staging: csr: netdev.c: Clean up KERNEL_VERSION checks: 2.6.37
[deliverable/linux.git] / drivers / staging / csr / netdev.c
CommitLineData
635d2b00
GKH
1/*
2 * ---------------------------------------------------------------------------
3 * FILE: netdev.c
4 *
5 * PURPOSE:
6 * This file provides the upper edge interface to the linux netdevice
7 * and wireless extensions.
8 * It is part of the porting exercise.
9 *
10 * Copyright (C) 2005-2010 by Cambridge Silicon Radio Ltd.
11 *
12 * Refer to LICENSE.txt included with this source code for details on
13 * the license terms.
14 *
15 * ---------------------------------------------------------------------------
16 */
17
635d2b00
GKH
18/*
19 * Porting Notes:
20 * This file implements the data plane of the UniFi linux driver.
21 *
22 * All the Tx packets are passed to the HIP core lib, using the
23 * unifi_send_signal() API. For EAPOL packets use the MLME-EAPOL.req
24 * signal, for all other use the MLME-UNITDATA.req. The unifi_send_signal()
25 * expects the wire-formatted (packed) signal. For convenience, in the OS
26 * layer we only use the native (unpacked) signal structures. The HIP core lib
27 * provides the write_pack() helper function to convert to the packed signal.
28 * The packet is stored in the bulk data of the signal. We do not need to
29 * allocate new memory to store the packet, because unifi_net_data_malloc()
30 * is implemented to return a skb, which is the format of packet in Linux.
31 * The HIP core lib frees the bulk data buffers, so we do not need to do
32 * this in the OS layer.
33 *
34 * All the Rx packets are MLME-UNITDATA.ind signals, passed by the HIP core lib
35 * in unifi_receive_event(). We do not need to allocate an skb and copy the
36 * received packet because the HIP core lib has stored in memory allocated by
37 * unifi_net_data_malloc(). Also, we can perform the 802.11 to Ethernet
38 * translation in-place because we allocate the extra memory allocated in
39 * unifi_net_data_malloc().
40 *
41 * If possible, the porting exercise should appropriately implement
42 * unifi_net_data_malloc() and unifi_net_data_free() to save copies between
43 * network and driver buffers.
44 */
45
46#include <linux/types.h>
47#include <linux/etherdevice.h>
48#include <linux/mutex.h>
49#include <linux/semaphore.h>
3d4e9e57 50#include <linux/version.h>
635d2b00
GKH
51#include <linux/vmalloc.h>
52#include "csr_wifi_hip_unifi.h"
53#include "csr_wifi_hip_conversions.h"
54#include "unifi_priv.h"
635d2b00
GKH
55#include <net/pkt_sched.h>
56
57
58/* ALLOW_Q_PAUSE: Pre 2.6.28 kernels do not support multiple driver queues (required for QoS).
59 * In order to support QoS in these kernels, multiple queues are implemented in the driver. But since
60 * there is only a single queue in the kernel (leading to multiple queues in the driver) there is no possibility
61 * of stopping a particular queue in the kernel. Stopping the single kernel queue leads to undesirable starvation
62 * of driver queues. One of the proposals is to not stop the kernel queue but to prevent dequeuing from the
63 * 'stopped' driver queue. Allow q pause is an experimental implementation of this scheme for pre 2.6.28 kernels.
64 * When NOT defined, queues are paused locally in the driver and packets are dequeued for transmission only from the
65 * unpaused queues. When Allow q pause is defined the kernel queue is stopped whenever any driver queue is paused.
66 */
67#define ALLOW_Q_PAUSE
68
635d2b00
GKH
69#ifdef UNIFI_NET_NAME
70#define UF_ALLOC_NETDEV(_dev, _size, _name, _setup, _num_of_queues) \
71 do { \
72 static char name[8]; \
73 sprintf(name, "%s%s", UNIFI_NET_NAME, _name); \
74 _dev = alloc_netdev_mq(_size, name, _setup, _num_of_queues); \
75 } while (0);
76#else
77#define UF_ALLOC_NETDEV(_dev, _size, _name, _setup, _num_of_queues) \
78 do { \
79 _dev = alloc_etherdev_mq(_size, _num_of_queues); \
80 } while (0);
81#endif /* UNIFI_NET_NAME */
635d2b00
GKH
82
83
84/* Wext handler is suported only if CSR_SUPPORT_WEXT is defined */
85#ifdef CSR_SUPPORT_WEXT
86extern struct iw_handler_def unifi_iw_handler_def;
87#endif /* CSR_SUPPORT_WEXT */
88static void check_ba_frame_age_timeout( unifi_priv_t *priv,
89 netInterface_priv_t *interfacePriv,
90 ba_session_rx_struct *ba_session);
91static void process_ba_frame(unifi_priv_t *priv,
92 netInterface_priv_t *interfacePriv,
93 ba_session_rx_struct *ba_session,
94 frame_desc_struct *frame_desc);
95static void process_ba_complete(unifi_priv_t *priv, netInterface_priv_t *interfacePriv);
96static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata);
97static void process_amsdu(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata);
98static int uf_net_open(struct net_device *dev);
99static int uf_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
100static int uf_net_stop(struct net_device *dev);
101static struct net_device_stats *uf_net_get_stats(struct net_device *dev);
635d2b00 102static u16 uf_net_select_queue(struct net_device *dev, struct sk_buff *skb);
635d2b00 103static netdev_tx_t uf_net_xmit(struct sk_buff *skb, struct net_device *dev);
635d2b00
GKH
104static void uf_set_multicast_list(struct net_device *dev);
105
106
107typedef int (*tx_signal_handler)(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr *ehdr, CSR_PRIORITY priority);
108
109#ifdef CONFIG_NET_SCHED
110/*
111 * Queueing Discipline Interface
112 * Only used if kernel is configured with CONFIG_NET_SCHED
113 */
114
115/*
116 * The driver uses the qdisc interface to buffer and control all
117 * outgoing traffic. We create a root qdisc, register our qdisc operations
118 * and later we create two subsiduary pfifo queues for the uncontrolled
119 * and controlled ports.
120 *
121 * The network stack delivers all outgoing packets in our enqueue handler.
122 * There, we classify the packet and decide whether to store it or drop it
123 * (if the controlled port state is set to "discard").
124 * If the packet is enqueued, the network stack call our dequeue handler.
125 * There, we decide whether we can send the packet, delay it or drop it
126 * (the controlled port configuration might have changed meanwhile).
127 * If a packet is dequeued, then the network stack calls our hard_start_xmit
128 * handler where finally we send the packet.
129 *
130 * If the hard_start_xmit handler fails to send the packet, we return
131 * NETDEV_TX_BUSY and the network stack call our requeue handler where
132 * we put the packet back in the same queue in came from.
133 *
134 */
135
136struct uf_sched_data
137{
138 /* Traffic Classifier TBD */
139 struct tcf_proto *filter_list;
140 /* Our two queues */
141 struct Qdisc *queues[UNIFI_TRAFFIC_Q_MAX];
142};
143
144struct uf_tx_packet_data {
145 /* Queue the packet is stored in */
146 unifi_TrafficQueue queue;
147 /* QoS Priority determined when enqueing packet */
148 CSR_PRIORITY priority;
149 /* Debug */
150 unsigned long host_tag;
151};
152
635d2b00
GKH
153#endif /* CONFIG_NET_SCHED */
154
635d2b00
GKH
155static const struct net_device_ops uf_netdev_ops =
156{
157 .ndo_open = uf_net_open,
158 .ndo_stop = uf_net_stop,
159 .ndo_start_xmit = uf_net_xmit,
160 .ndo_do_ioctl = uf_net_ioctl,
161 .ndo_get_stats = uf_net_get_stats, /* called by /proc/net/dev */
162 .ndo_set_rx_mode = uf_set_multicast_list,
163 .ndo_select_queue = uf_net_select_queue,
164};
635d2b00
GKH
165
166static u8 oui_rfc1042[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
167static u8 oui_8021h[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
168
169
170/* Callback for event logging to blocking clients */
171static void netdev_mlme_event_handler(ul_client_t *client,
172 const u8 *sig_packed, int sig_len,
173 const bulk_data_param_t *bulkdata,
174 int dir);
175
176#ifdef CSR_SUPPORT_WEXT
177/* Declare netdev_notifier block which will contain the state change
178 * handler callback function
179 */
180static struct notifier_block uf_netdev_notifier;
181#endif
182
183/*
184 * ---------------------------------------------------------------------------
185 * uf_alloc_netdevice
186 *
187 * Allocate memory for the net_device and device private structs
188 * for this interface.
189 * Fill in the fields, but don't register the interface yet.
190 * We need to configure the UniFi first.
191 *
192 * Arguments:
193 * sdio_dev Pointer to SDIO context handle to use for all
194 * SDIO ops.
195 * bus_id A small number indicating the SDIO card position on the
196 * bus. Typically this is the slot number, e.g. 0, 1 etc.
197 * Valid values are 0 to MAX_UNIFI_DEVS-1.
198 *
199 * Returns:
200 * Pointer to device private struct.
201 *
202 * Notes:
203 * The net_device and device private structs are allocated together
204 * and should be freed by freeing the net_device pointer.
205 * ---------------------------------------------------------------------------
206 */
207unifi_priv_t *
208uf_alloc_netdevice(CsrSdioFunction *sdio_dev, int bus_id)
209{
210 struct net_device *dev;
211 unifi_priv_t *priv;
212 netInterface_priv_t *interfacePriv;
213#ifdef CSR_SUPPORT_WEXT
214 int rc;
215#endif
216 unsigned char i; /* loop index */
217
218 /*
219 * Allocate netdevice struct, assign name template and
220 * setup as an ethernet device.
221 * The net_device and private structs are zeroed. Ether_setup() then
222 * sets up ethernet handlers and values.
223 * The RedHat 9 redhat-config-network tool doesn't recognise wlan* devices,
224 * so use "eth*" (like other wireless extns drivers).
225 */
226 UF_ALLOC_NETDEV(dev, sizeof(unifi_priv_t)+sizeof(netInterface_priv_t), "%d", ether_setup, UNIFI_TRAFFIC_Q_MAX);
227
228 if (dev == NULL) {
229 return NULL;
230 }
231
232 /* Set up back pointer from priv to netdev */
233 interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
234 priv = (unifi_priv_t *)(interfacePriv + 1);
235 interfacePriv->privPtr = priv;
236 interfacePriv->InterfaceTag = 0;
237
238
239 /* Initialize all supported netdev interface to be NULL */
240 for(i=0; i<CSR_WIFI_NUM_INTERFACES; i++) {
241 priv->netdev[i] = NULL;
242 priv->interfacePriv[i] = NULL;
243 }
244 priv->netdev[0] = dev;
245 priv->interfacePriv[0] = interfacePriv;
246
247 /* Setup / override net_device fields */
635d2b00 248 dev->netdev_ops = &uf_netdev_ops;
635d2b00
GKH
249
250#ifdef CSR_SUPPORT_WEXT
251 dev->wireless_handlers = &unifi_iw_handler_def;
252#if IW_HANDLER_VERSION < 6
253 dev->get_wireless_stats = unifi_get_wireless_stats;
254#endif /* IW_HANDLER_VERSION */
255#endif /* CSR_SUPPORT_WEXT */
256
257 /* This gives us enough headroom to add the 802.11 header */
258 dev->needed_headroom = 32;
259
260 /* Use bus_id as instance number */
261 priv->instance = bus_id;
262 /* Store SDIO pointer to pass in the core */
263 priv->sdio = sdio_dev;
264
265 sdio_dev->driverData = (void*)priv;
266 /* Consider UniFi to be uninitialised */
267 priv->init_progress = UNIFI_INIT_NONE;
268
269 priv->prev_queue = 0;
270
271 /*
272 * Initialise the clients structure array.
273 * We do not need protection around ul_init_clients() because
274 * the character device can not be used until uf_alloc_netdevice()
275 * returns and Unifi_instances[bus_id]=priv is set, since unifi_open()
276 * will return -ENODEV.
277 */
278 ul_init_clients(priv);
279
280 /*
281 * Register a new ul client to send the multicast list signals.
282 * Note: priv->instance must be set before calling this.
283 */
284 priv->netdev_client = ul_register_client(priv,
285 0,
286 netdev_mlme_event_handler);
287 if (priv->netdev_client == NULL) {
288 unifi_error(priv,
289 "Failed to register a unifi client for background netdev processing\n");
290 free_netdev(priv->netdev[0]);
291 return NULL;
292 }
293 unifi_trace(priv, UDBG2, "Netdev %p client (id:%d s:0x%X) is registered\n",
294 dev, priv->netdev_client->client_id, priv->netdev_client->sender_id);
295
296 priv->sta_wmm_capabilities = 0;
297
95edd09e 298#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_SUPPORT_SME))
635d2b00
GKH
299 priv->wapi_multicast_filter = 0;
300 priv->wapi_unicast_filter = 0;
301 priv->wapi_unicast_queued_pkt_filter = 0;
95edd09e
GKH
302#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
303 priv->isWapiConnection = FALSE;
304#endif
305#endif
635d2b00
GKH
306
307 /* Enable all queues by default */
308 interfacePriv->queueEnabled[0] = 1;
309 interfacePriv->queueEnabled[1] = 1;
310 interfacePriv->queueEnabled[2] = 1;
311 interfacePriv->queueEnabled[3] = 1;
312
313#ifdef CSR_SUPPORT_SME
314 priv->allPeerDozing = 0;
315#endif
316 /*
317 * Initialise the OS private struct.
318 */
319 /*
320 * Instead of deciding in advance to use 11bg or 11a, we could do a more
321 * clever scan on both radios.
322 */
323 if (use_5g) {
324 priv->if_index = CSR_INDEX_5G;
325 unifi_info(priv, "Using the 802.11a radio\n");
326 } else {
327 priv->if_index = CSR_INDEX_2G4;
328 }
329
330 /* Initialise bh thread structure */
331 priv->bh_thread.thread_task = NULL;
332 priv->bh_thread.block_thread = 1;
333 init_waitqueue_head(&priv->bh_thread.wakeup_q);
334 priv->bh_thread.wakeup_flag = 0;
335 sprintf(priv->bh_thread.name, "uf_bh_thread");
336
337 /* reset the connected state for the interface */
338 interfacePriv->connected = UnifiConnectedUnknown; /* -1 unknown, 0 no, 1 yes */
339
340#ifdef USE_DRIVER_LOCK
635d2b00 341 sema_init(&priv->lock, 1);
635d2b00
GKH
342#endif /* USE_DRIVER_LOCK */
343
344 spin_lock_init(&priv->send_signal_lock);
345
346 spin_lock_init(&priv->m4_lock);
95edd09e 347 sema_init(&priv->ba_mutex, 1);
95edd09e
GKH
348
349#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
350 spin_lock_init(&priv->wapi_lock);
351#endif
635d2b00
GKH
352
353#ifdef CSR_SUPPORT_SME
354 spin_lock_init(&priv->staRecord_lock);
355 spin_lock_init(&priv->tx_q_lock);
356#endif
357
358 /* Create the Traffic Analysis workqueue */
359 priv->unifi_workqueue = create_singlethread_workqueue("unifi_workq");
360 if (priv->unifi_workqueue == NULL) {
361 /* Deregister priv->netdev_client */
362 ul_deregister_client(priv->netdev_client);
363 free_netdev(priv->netdev[0]);
364 return NULL;
365 }
366
367#ifdef CSR_SUPPORT_SME
368 /* Create the Multicast Addresses list work structure */
369 INIT_WORK(&priv->multicast_list_task, uf_multicast_list_wq);
370
371 /* Create m4 buffering work structure */
372 INIT_WORK(&interfacePriv->send_m4_ready_task, uf_send_m4_ready_wq);
95edd09e
GKH
373
374#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
375 /* Create work structure to buffer the WAPI data packets to be sent to SME for encryption */
376 INIT_WORK(&interfacePriv->send_pkt_to_encrypt, uf_send_pkt_to_encrypt);
377#endif
635d2b00
GKH
378#endif
379
635d2b00
GKH
380 priv->ref_count = 1;
381
635d2b00
GKH
382 priv->amp_client = NULL;
383 priv->coredump_mode = 0;
384 priv->ptest_mode = 0;
385 priv->wol_suspend = FALSE;
386 INIT_LIST_HEAD(&interfacePriv->rx_uncontrolled_list);
387 INIT_LIST_HEAD(&interfacePriv->rx_controlled_list);
388 sema_init(&priv->rx_q_sem, 1);
389
390#ifdef CSR_SUPPORT_WEXT
391 interfacePriv->netdev_callback_registered = FALSE;
392 interfacePriv->wait_netdev_change = FALSE;
393 /* Register callback for netdevice state changes */
394 if ((rc = register_netdevice_notifier(&uf_netdev_notifier)) == 0) {
395 interfacePriv->netdev_callback_registered = TRUE;
396 }
397 else {
398 unifi_warning(priv, "Failed to register netdevice notifier : %d %p\n", rc, dev);
399 }
400#endif /* CSR_SUPPORT_WEXT */
401
95edd09e
GKH
402#ifdef CSR_WIFI_SPLIT_PATCH
403 /* set it to some invalid value */
404 priv->pending_mode_set.common.destination = 0xaaaa;
405#endif
406
635d2b00
GKH
407 return priv;
408} /* uf_alloc_netdevice() */
409
410/*
411 *---------------------------------------------------------------------------
412 * uf_alloc_netdevice_for_other_interfaces
413 *
414 * Allocate memory for the net_device and device private structs
415 * for this interface.
416 * Fill in the fields, but don't register the interface yet.
417 * We need to configure the UniFi first.
418 *
419 * Arguments:
420 * interfaceTag Interface number.
421 * sdio_dev Pointer to SDIO context handle to use for all
422 * SDIO ops.
423 * bus_id A small number indicating the SDIO card position on the
424 * bus. Typically this is the slot number, e.g. 0, 1 etc.
425 * Valid values are 0 to MAX_UNIFI_DEVS-1.
426 *
427 * Returns:
428 * Pointer to device private struct.
429 *
430 * Notes:
431 * The device private structure contains the interfaceTag and pointer to the unifi_priv
432 * structure created allocated by net_device od interface0.
433 * The net_device and device private structs are allocated together
434 * and should be freed by freeing the net_device pointer.
435 * ---------------------------------------------------------------------------
436 */
5379b13d 437u8
8c87f69a 438uf_alloc_netdevice_for_other_interfaces(unifi_priv_t *priv, u16 interfaceTag)
635d2b00
GKH
439{
440 struct net_device *dev;
441 netInterface_priv_t *interfacePriv;
442
443 /*
444 * Allocate netdevice struct, assign name template and
445 * setup as an ethernet device.
446 * The net_device and private structs are zeroed. Ether_setup() then
447 * sets up ethernet handlers and values.
448 * The RedHat 9 redhat-config-network tool doesn't recognise wlan* devices,
449 * so use "eth*" (like other wireless extns drivers).
450 */
451 UF_ALLOC_NETDEV(dev, sizeof(netInterface_priv_t), "%d", ether_setup, 1);
452 if (dev == NULL) {
453 return FALSE;
454 }
455
456 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
457 unifi_error(priv, "uf_alloc_netdevice_for_other_interfaces bad interfaceTag\n");
458 return FALSE;
459 }
460
461 /* Set up back pointer from priv to netdev */
462 interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
463 interfacePriv->privPtr = priv;
464 interfacePriv->InterfaceTag = interfaceTag;
465 priv->netdev[interfaceTag] = dev;
466 priv->interfacePriv[interfacePriv->InterfaceTag] = interfacePriv;
467
468 /* reset the connected state for the interface */
469 interfacePriv->connected = UnifiConnectedUnknown; /* -1 unknown, 0 no, 1 yes */
470 INIT_LIST_HEAD(&interfacePriv->rx_uncontrolled_list);
471 INIT_LIST_HEAD(&interfacePriv->rx_controlled_list);
472
473 /* Setup / override net_device fields */
635d2b00 474 dev->netdev_ops = &uf_netdev_ops;
635d2b00
GKH
475
476#ifdef CSR_SUPPORT_WEXT
477 dev->wireless_handlers = &unifi_iw_handler_def;
478#if IW_HANDLER_VERSION < 6
479 dev->get_wireless_stats = unifi_get_wireless_stats;
480#endif /* IW_HANDLER_VERSION */
481#endif /* CSR_SUPPORT_WEXT */
482 return TRUE;
483} /* uf_alloc_netdevice() */
484
485
486
487/*
488 * ---------------------------------------------------------------------------
489 * uf_free_netdevice
490 *
491 * Unregister the network device and free the memory allocated for it.
492 * NB This includes the memory for the priv struct.
493 *
494 * Arguments:
495 * priv Device private pointer.
496 *
497 * Returns:
498 * None.
499 * ---------------------------------------------------------------------------
500 */
501int
502uf_free_netdevice(unifi_priv_t *priv)
503{
504 int i;
505 unsigned long flags;
506
507 func_enter();
508
509 unifi_trace(priv, UDBG1, "uf_free_netdevice\n");
510
511 if (!priv) {
512 return -EINVAL;
513 }
514
515 /*
516 * Free any buffers used for holding firmware
517 */
518 uf_release_firmware_files(priv);
519
520#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
521 if (priv->connection_config.mlmeAssociateReqInformationElements) {
522 kfree(priv->connection_config.mlmeAssociateReqInformationElements);
523 }
524 priv->connection_config.mlmeAssociateReqInformationElements = NULL;
525 priv->connection_config.mlmeAssociateReqInformationElementsLength = 0;
526
527 if (priv->mib_data.length) {
528 vfree(priv->mib_data.data);
529 }
530 priv->mib_data.data = NULL;
531 priv->mib_data.length = 0;
532
533#endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT*/
534
535 /* Free any bulkdata buffers allocated for M4 caching */
536 spin_lock_irqsave(&priv->m4_lock, flags);
537 for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
538 netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
539 if (interfacePriv->m4_bulk_data.data_length > 0) {
540 unifi_trace(priv, UDBG5, "uf_free_netdevice: free M4 bulkdata %d\n", i);
541 unifi_net_data_free(priv, &interfacePriv->m4_bulk_data);
542 }
543 }
544 spin_unlock_irqrestore(&priv->m4_lock, flags);
545
95edd09e
GKH
546#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
547 /* Free any bulkdata buffers allocated for M4 caching */
548 spin_lock_irqsave(&priv->wapi_lock, flags);
549 for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
550 netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
551 if (interfacePriv->wapi_unicast_bulk_data.data_length > 0) {
552 unifi_trace(priv, UDBG5, "uf_free_netdevice: free WAPI PKT bulk data %d\n", i);
553 unifi_net_data_free(priv, &interfacePriv->wapi_unicast_bulk_data);
554 }
555 }
556 spin_unlock_irqrestore(&priv->wapi_lock, flags);
557#endif
558
635d2b00
GKH
559#ifdef CSR_SUPPORT_WEXT
560 /* Unregister callback for netdevice state changes */
561 unregister_netdevice_notifier(&uf_netdev_notifier);
562#endif /* CSR_SUPPORT_WEXT */
563
564#ifdef CSR_SUPPORT_SME
565 /* Cancel work items and destroy the workqueue */
635d2b00
GKH
566 cancel_work_sync(&priv->multicast_list_task);
567#endif
635d2b00
GKH
568/* Destroy the workqueues. */
569 flush_workqueue(priv->unifi_workqueue);
570 destroy_workqueue(priv->unifi_workqueue);
571
572 /* Free up netdev in reverse order: priv is allocated with netdev[0].
573 * So, netdev[0] should be freed after all other netdevs are freed up
574 */
575 for (i=CSR_WIFI_NUM_INTERFACES-1; i>=0; i--) {
576 /*Free the netdev struct and priv, which are all one lump*/
577 if (priv->netdev[i]) {
578 unifi_error(priv, "uf_free_netdevice: netdev %d %p\n", i, priv->netdev[i]);
579 free_netdev(priv->netdev[i]);
580 }
581 }
582
583 func_exit();
584 return 0;
585} /* uf_free_netdevice() */
586
587
588/*
589 * ---------------------------------------------------------------------------
590 * uf_net_open
591 *
592 * Called when userland does "ifconfig wlan0 up".
593 *
594 * Arguments:
595 * dev Device pointer.
596 *
597 * Returns:
598 * None.
599 * ---------------------------------------------------------------------------
600 */
601static int
602uf_net_open(struct net_device *dev)
603{
604 netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
605 unifi_priv_t *priv = interfacePriv->privPtr;
606
607 func_enter();
608
609 /* If we haven't finished UniFi initialisation, we can't start */
610 if (priv->init_progress != UNIFI_INIT_COMPLETED) {
611 unifi_warning(priv, "%s: unifi not ready, failing net_open\n", __FUNCTION__);
612 return -EINVAL;
613 }
614
615#if (defined CSR_NATIVE_LINUX) && (defined UNIFI_SNIFF_ARPHRD) && defined(CSR_SUPPORT_WEXT)
616 /*
617 * To sniff, the user must do "iwconfig mode monitor", which sets
618 * priv->wext_conf.mode to IW_MODE_MONITOR.
619 * Then he/she must do "ifconfig ethn up", which calls this fn.
620 * There is no point in starting the sniff with SNIFFJOIN until
621 * this point.
622 */
623 if (priv->wext_conf.mode == IW_MODE_MONITOR) {
624 int err;
625 err = uf_start_sniff(priv);
626 if (err) {
627 return err;
628 }
629 netif_carrier_on(dev);
630 }
631#endif
632
633#ifdef CSR_SUPPORT_WEXT
634 if (interfacePriv->wait_netdev_change) {
635 unifi_trace(priv, UDBG1, "%s: Waiting for NETDEV_CHANGE, assume connected\n",
636 __FUNCTION__);
637 interfacePriv->connected = UnifiConnected;
638 interfacePriv->wait_netdev_change = FALSE;
639 }
640#endif
641
642 UF_NETIF_TX_START_ALL_QUEUES(dev);
643
644 func_exit();
645 return 0;
646} /* uf_net_open() */
647
648
649static int
650uf_net_stop(struct net_device *dev)
651{
652#if defined(CSR_NATIVE_LINUX) && defined(UNIFI_SNIFF_ARPHRD) && defined(CSR_SUPPORT_WEXT)
653 netInterface_priv_t *interfacePriv = (netInterface_priv_t*)netdev_priv(dev);
654 unifi_priv_t *priv = interfacePriv->privPtr;
655
656 func_enter();
657
658 /* Stop sniffing if in Monitor mode */
659 if (priv->wext_conf.mode == IW_MODE_MONITOR) {
660 if (priv->card) {
661 int err;
662 err = unifi_reset_state(priv, dev->dev_addr, 1);
663 if (err) {
664 return err;
665 }
666 }
667 }
668#else
669 func_enter();
670#endif
671
672 UF_NETIF_TX_STOP_ALL_QUEUES(dev);
673
674 func_exit();
675 return 0;
676} /* uf_net_stop() */
677
678
679/* This is called after the WE handlers */
680static int
681uf_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
682{
683 int rc;
684
685 rc = -EOPNOTSUPP;
686
687 return rc;
688} /* uf_net_ioctl() */
689
690
691
692static struct net_device_stats *
693uf_net_get_stats(struct net_device *dev)
694{
695 netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
696
697 return &interfacePriv->stats;
698} /* uf_net_get_stats() */
699
700static CSR_PRIORITY uf_get_packet_priority(unifi_priv_t *priv, netInterface_priv_t *interfacePriv, struct sk_buff *skb, const int proto)
701{
702 CSR_PRIORITY priority = CSR_CONTENTION;
703
704 func_enter();
705 priority = (CSR_PRIORITY) (skb->priority >> 5);
706
707 if (priority == CSR_QOS_UP0) { /* 0 */
708
709 unifi_trace(priv, UDBG5, "uf_get_packet_priority: proto = 0x%.4X\n", proto);
710
711 switch (proto) {
712 case 0x0800: /* IPv4 */
713 case 0x814C: /* SNMP */
714 case 0x880C: /* GSMP */
715 priority = (CSR_PRIORITY) (skb->data[1 + ETH_HLEN] >> 5);
716 break;
717
718 case 0x8100: /* VLAN */
719 priority = (CSR_PRIORITY) (skb->data[0 + ETH_HLEN] >> 5);
720 break;
721
722 case 0x86DD: /* IPv6 */
723 priority = (CSR_PRIORITY) ((skb->data[0 + ETH_HLEN] & 0x0E) >> 1);
724 break;
725
726 default:
727 priority = CSR_QOS_UP0;
728 break;
729 }
730 }
731
732 /* Check if we are allowed to transmit on this AC. Because of ACM we may have to downgrade to a lower
733 * priority */
734 if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA ||
735 interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI) {
736 unifi_TrafficQueue queue;
737
738 /* Keep trying lower priorities until we find a queue
739 * Priority to queue mapping is 1,2 - BK, 0,3 - BE, 4,5 - VI, 6,7 - VO */
740 queue = unifi_frame_priority_to_queue(priority);
741
742 while (queue > UNIFI_TRAFFIC_Q_BK && !interfacePriv->queueEnabled[queue]) {
743 queue--;
744 priority = unifi_get_default_downgrade_priority(queue);
745 }
746 }
747
748 unifi_trace(priv, UDBG5, "Packet priority = %d\n", priority);
749
750 func_exit();
751 return priority;
752}
753
754/*
755 */
756/*
757 * ---------------------------------------------------------------------------
758 * get_packet_priority
759 *
760 * Arguments:
761 * priv private data area of functional driver
762 * skb socket buffer
763 * ehdr ethernet header to fetch protocol
764 * interfacePriv For accessing station record database
765 *
766 *
767 * Returns:
768 * CSR_PRIORITY.
769 * ---------------------------------------------------------------------------
770 */
771CSR_PRIORITY
772get_packet_priority(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr *ehdr, netInterface_priv_t *interfacePriv)
773{
774 CSR_PRIORITY priority = CSR_CONTENTION;
775 const int proto = ntohs(ehdr->h_proto);
776
7e6f5794 777 u8 interfaceMode = interfacePriv->interfaceMode;
635d2b00
GKH
778
779 func_enter();
780
781 /* Priority Mapping for all the Modes */
782 switch(interfaceMode)
783 {
784 case CSR_WIFI_ROUTER_CTRL_MODE_STA:
785 case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
786 unifi_trace(priv, UDBG4, "mode is STA \n");
787 if ((priv->sta_wmm_capabilities & QOS_CAPABILITY_WMM_ENABLED) == 1) {
788 priority = uf_get_packet_priority(priv, interfacePriv, skb, proto);
789 } else {
790 priority = CSR_CONTENTION;
791 }
792 break;
793#ifdef CSR_SUPPORT_SME
794 case CSR_WIFI_ROUTER_CTRL_MODE_AP:
795 case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
796 case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
797 {
798 CsrWifiRouterCtrlStaInfo_t * dstStaInfo =
799 CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,ehdr->h_dest, interfacePriv->InterfaceTag);
800 unifi_trace(priv, UDBG4, "mode is AP \n");
801 if (!(ehdr->h_dest[0] & 0x01) && dstStaInfo && dstStaInfo->wmmOrQosEnabled) {
802 /* If packet is not Broadcast/multicast */
803 priority = uf_get_packet_priority(priv, interfacePriv, skb, proto);
804 } else {
805 /* Since packet destination is not QSTA, set priority to CSR_CONTENTION */
806 unifi_trace(priv, UDBG4, "Destination is not QSTA or BroadCast/Multicast\n");
807 priority = CSR_CONTENTION;
808 }
809 }
810 break;
811#endif
812 default:
813 unifi_trace(priv, UDBG3, " mode unknown in %s func, mode=%x\n", __FUNCTION__, interfaceMode);
814 }
815 unifi_trace(priv, UDBG5, "priority = %x\n", priority);
816
817 func_exit();
818 return priority;
819}
820
635d2b00
GKH
821/*
822 * ---------------------------------------------------------------------------
823 * uf_net_select_queue
824 *
825 * Called by the kernel to select which queue to put the packet in
826 *
827 * Arguments:
828 * dev Device pointer
829 * skb Packet
830 *
831 * Returns:
832 * Queue index
833 * ---------------------------------------------------------------------------
834 */
835static u16
836uf_net_select_queue(struct net_device *dev, struct sk_buff *skb)
837{
838 netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
839 unifi_priv_t *priv = (unifi_priv_t *)interfacePriv->privPtr;
840 struct ethhdr ehdr;
841 unifi_TrafficQueue queue;
842 int proto;
843 CSR_PRIORITY priority;
844
845 func_enter();
846
847 memcpy(&ehdr, skb->data, ETH_HLEN);
848 proto = ntohs(ehdr.h_proto);
849
850 /* 802.1x - apply controlled/uncontrolled port rules */
851 if ((proto != ETH_P_PAE)
852#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
853 && (proto != ETH_P_WAI)
854#endif
855 ) {
856 /* queues 0 - 3 */
857 priority = get_packet_priority(priv, skb, &ehdr, interfacePriv);
858 queue = unifi_frame_priority_to_queue(priority);
859 } else {
860 /* queue 4 */
861 queue = UNIFI_TRAFFIC_Q_EAPOL;
862 }
863
864
865 func_exit();
866 return (u16)queue;
867} /* uf_net_select_queue() */
635d2b00
GKH
868
869int
870skb_add_llc_snap(struct net_device *dev, struct sk_buff *skb, int proto)
871{
872 llc_snap_hdr_t *snap;
873 netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
874 unifi_priv_t *priv = interfacePriv->privPtr;
875 int headroom;
876
877 /* get the headroom available in skb */
878 headroom = skb_headroom(skb);
879 /* step 1: classify ether frame, DIX or 802.3? */
880
881 if (proto < 0x600) {
882 /* codes <= 1500 reserved for 802.3 lengths */
883 /* it's 802.3, pass ether payload unchanged, */
884 unifi_trace(priv, UDBG3, "802.3 len: %d\n", skb->len);
885
886 /* leave off any PAD octets. */
887 skb_trim(skb, proto);
888 } else if (proto == ETH_P_8021Q) {
889
890 /* Store the VLAN SNAP (should be 87-65). */
891 u16 vlan_snap = *(u16*)skb->data;
892 /* check for headroom availability before skb_push 14 = (4 + 10) */
893 if (headroom < 14) {
894 unifi_trace(priv, UDBG3, "cant append vlan snap: debug\n");
895 return -1;
896 }
897 /* Add AA-AA-03-00-00-00 */
898 snap = (llc_snap_hdr_t *)skb_push(skb, 4);
899 snap->dsap = snap->ssap = 0xAA;
900 snap->ctrl = 0x03;
901 memcpy(snap->oui, oui_rfc1042, P80211_OUI_LEN);
902
903 /* Add AA-AA-03-00-00-00 */
904 snap = (llc_snap_hdr_t *)skb_push(skb, 10);
905 snap->dsap = snap->ssap = 0xAA;
906 snap->ctrl = 0x03;
907 memcpy(snap->oui, oui_rfc1042, P80211_OUI_LEN);
908
909 /* Add the VLAN specific information */
910 snap->protocol = htons(proto);
911 *(u16*)(snap + 1) = vlan_snap;
912
913 } else
914 {
915 /* it's DIXII, time for some conversion */
916 unifi_trace(priv, UDBG3, "DIXII len: %d\n", skb->len);
917
918 /* check for headroom availability before skb_push */
919 if (headroom < sizeof(llc_snap_hdr_t)) {
920 unifi_trace(priv, UDBG3, "cant append snap: debug\n");
921 return -1;
922 }
923 /* tack on SNAP */
924 snap = (llc_snap_hdr_t *)skb_push(skb, sizeof(llc_snap_hdr_t));
925 snap->dsap = snap->ssap = 0xAA;
926 snap->ctrl = 0x03;
927 /* Use the appropriate OUI. */
928 if ((proto == ETH_P_AARP) || (proto == ETH_P_IPX)) {
929 memcpy(snap->oui, oui_8021h, P80211_OUI_LEN);
930 } else {
931 memcpy(snap->oui, oui_rfc1042, P80211_OUI_LEN);
932 }
933 snap->protocol = htons(proto);
934 }
935
936 return 0;
937} /* skb_add_llc_snap() */
938
939#ifdef CSR_SUPPORT_SME
940static int
941_identify_sme_ma_pkt_ind(unifi_priv_t *priv,
8c87f69a 942 const s8 *oui, u16 protocol,
635d2b00
GKH
943 const CSR_SIGNAL *signal,
944 bulk_data_param_t *bulkdata,
945 const unsigned char *daddr,
946 const unsigned char *saddr)
947{
948 CSR_MA_PACKET_INDICATION *pkt_ind = (CSR_MA_PACKET_INDICATION*)&signal->u.MaPacketIndication;
949 int r;
7e6f5794 950 u8 i;
635d2b00
GKH
951
952 unifi_trace(priv, UDBG5,
953 "_identify_sme_ma_pkt_ind -->\n");
954 for (i = 0; i < MAX_MA_UNIDATA_IND_FILTERS; i++) {
955 if (priv->sme_unidata_ind_filters[i].in_use) {
956 if (!memcmp(oui, priv->sme_unidata_ind_filters[i].oui, 3) &&
957 (protocol == priv->sme_unidata_ind_filters[i].protocol)) {
958
959 /* Send to client */
960 if (priv->sme_cli) {
961 /*
962 * Pass the packet to the SME, using unifi_sys_ma_unitdata_ind().
963 * The frame needs to be converted according to the encapsulation.
964 */
965 unifi_trace(priv, UDBG1,
966 "_identify_sme_ma_pkt_ind: handle=%d, encap=%d, proto=%x\n",
967 i, priv->sme_unidata_ind_filters[i].encapsulation,
968 priv->sme_unidata_ind_filters[i].protocol);
969 if (priv->sme_unidata_ind_filters[i].encapsulation == CSR_WIFI_ROUTER_ENCAPSULATION_ETHERNET) {
970 struct sk_buff *skb;
971 /* The translation is performed on skb... */
972 skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
973 skb->len = bulkdata->d[0].data_length;
974
975 unifi_trace(priv, UDBG1,
976 "_identify_sme_ma_pkt_ind: skb_80211_to_ether -->\n");
977 r = skb_80211_to_ether(priv, skb, daddr, saddr,
978 signal, bulkdata);
979 unifi_trace(priv, UDBG1,
980 "_identify_sme_ma_pkt_ind: skb_80211_to_ether <--\n");
981 if (r) {
982 return -EINVAL;
983 }
984
985 /* ... but we indicate buffer and length */
986 bulkdata->d[0].os_data_ptr = skb->data;
987 bulkdata->d[0].data_length = skb->len;
988 } else {
989 /* Add the MAC addresses before the SNAP */
990 bulkdata->d[0].os_data_ptr -= 2*ETH_ALEN;
991 bulkdata->d[0].data_length += 2*ETH_ALEN;
992 memcpy((void*)bulkdata->d[0].os_data_ptr, daddr, ETH_ALEN);
993 memcpy((void*)bulkdata->d[0].os_data_ptr + ETH_ALEN, saddr, ETH_ALEN);
994 }
995
996 unifi_trace(priv, UDBG1,
997 "_identify_sme_ma_pkt_ind: unifi_sys_ma_pkt_ind -->\n");
998 CsrWifiRouterMaPacketIndSend(priv->sme_unidata_ind_filters[i].appHandle,
999 (pkt_ind->VirtualInterfaceIdentifier & 0xff),
1000 i,
1001 pkt_ind->ReceptionStatus,
1002 bulkdata->d[0].data_length,
7e6f5794 1003 (u8*)bulkdata->d[0].os_data_ptr,
635d2b00
GKH
1004 NULL,
1005 pkt_ind->Rssi,
1006 pkt_ind->Snr,
1007 pkt_ind->ReceivedRate);
1008
1009
1010 unifi_trace(priv, UDBG1,
1011 "_identify_sme_ma_pkt_ind: unifi_sys_ma_pkt_ind <--\n");
1012 }
1013
1014 return 1;
1015 }
1016 }
1017 }
1018
1019 return -1;
1020}
1021#endif /* CSR_SUPPORT_SME */
1022
1023/*
1024 * ---------------------------------------------------------------------------
1025 * skb_80211_to_ether
1026 *
1027 * Make sure the received frame is in Ethernet (802.3) form.
1028 * De-encapsulates SNAP if necessary, adds a ethernet header.
1029 * The source buffer should not contain an 802.11 MAC header
1030 *
1031 * Arguments:
1032 * payload Pointer to packet data received from UniFi.
1033 * payload_length Number of bytes of data received from UniFi.
1034 * daddr Destination MAC address.
1035 * saddr Source MAC address.
1036 *
1037 * Returns:
1038 * 0 on success, -1 if the packet is bad and should be dropped,
1039 * 1 if the packet was forwarded to the SME or AMP client.
1040 * ---------------------------------------------------------------------------
1041 */
1042int
1043skb_80211_to_ether(unifi_priv_t *priv, struct sk_buff *skb,
1044 const unsigned char *daddr, const unsigned char *saddr,
1045 const CSR_SIGNAL *signal,
1046 bulk_data_param_t *bulkdata)
1047{
1048 unsigned char *payload;
1049 int payload_length;
1050 struct ethhdr *eth;
1051 llc_snap_hdr_t *snap;
1052 int headroom;
1053#define UF_VLAN_LLC_HEADER_SIZE 18
1054 static const u8 vlan_inner_snap[] = { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00 };
1055#if defined(CSR_NATIVE_SOFTMAC) && defined(CSR_SUPPORT_SME)
1056 const CSR_MA_PACKET_INDICATION *pkt_ind = &signal->u.MaPacketIndication;
1057#endif
1058
1059 if(skb== NULL || daddr == NULL || saddr == NULL){
1060 unifi_error(priv,"skb_80211_to_ether: PBC fail\n");
1061 return 1;
1062 }
1063
1064 payload = skb->data;
1065 payload_length = skb->len;
1066
1067 snap = (llc_snap_hdr_t *)payload;
1068 eth = (struct ethhdr *)payload;
1069
1070 /* get the skb headroom size */
1071 headroom = skb_headroom(skb);
1072
1073 /*
1074 * Test for the various encodings
1075 */
1076 if ((payload_length >= sizeof(llc_snap_hdr_t)) &&
1077 (snap->dsap == 0xAA) &&
1078 (snap->ssap == 0xAA) &&
1079 (snap->ctrl == 0x03) &&
1080 (snap->oui[0] == 0) &&
1081 (snap->oui[1] == 0) &&
1082 ((snap->oui[2] == 0) || (snap->oui[2] == 0xF8)))
1083 {
1084 /* AppleTalk AARP (2) or IPX SNAP */
1085 if ((snap->oui[2] == 0) &&
1086 ((ntohs(snap->protocol) == ETH_P_AARP) || (ntohs(snap->protocol) == ETH_P_IPX)))
1087 {
1088 u16 len;
1089
1090 unifi_trace(priv, UDBG3, "%s len: %d\n",
1091 (ntohs(snap->protocol) == ETH_P_AARP) ? "ETH_P_AARP" : "ETH_P_IPX",
1092 payload_length);
1093
1094 /* check for headroom availability before skb_push */
1095 if (headroom < (2 * ETH_ALEN + 2)) {
1096 unifi_warning(priv, "headroom not available to skb_push ether header\n");
1097 return -1;
1098 }
1099
1100 /* Add 802.3 header and leave full payload */
1101 len = htons(skb->len);
1102 memcpy(skb_push(skb, 2), &len, 2);
1103 memcpy(skb_push(skb, ETH_ALEN), saddr, ETH_ALEN);
1104 memcpy(skb_push(skb, ETH_ALEN), daddr, ETH_ALEN);
1105
1106 return 0;
1107 }
1108 /* VLAN-tagged IP */
1109 if ((snap->oui[2] == 0) && (ntohs(snap->protocol) == ETH_P_8021Q))
1110 {
1111 /*
1112 * The translation doesn't change the packet length, so is done in-place.
1113 *
1114 * Example header (from Std 802.11-2007 Annex M):
1115 * AA-AA-03-00-00-00-81-00-87-65-AA-AA-03-00-00-00-08-06
1116 * -------SNAP-------p1-p1-ll-ll-------SNAP--------p2-p2
1117 * dd-dd-dd-dd-dd-dd-aa-aa-aa-aa-aa-aa-p1-p1-ll-ll-p2-p2
1118 * dd-dd-dd-dd-dd-dd-aa-aa-aa-aa-aa-aa-81-00-87-65-08-06
1119 */
1120 u16 vlan_snap;
1121
1122 if (payload_length < UF_VLAN_LLC_HEADER_SIZE) {
1123 unifi_warning(priv, "VLAN SNAP header too short: %d bytes\n", payload_length);
1124 return -1;
1125 }
1126
1127 if (memcmp(payload + 10, vlan_inner_snap, 6)) {
1128 unifi_warning(priv, "VLAN malformatted SNAP header.\n");
1129 return -1;
1130 }
1131
1132 unifi_trace(priv, UDBG3, "VLAN SNAP: %02x-%02x\n", payload[8], payload[9]);
1133 unifi_trace(priv, UDBG3, "VLAN len: %d\n", payload_length);
1134
1135 /* Create the 802.3 header */
1136
1137 vlan_snap = *((u16*)(payload + 8));
1138
1139 /* Create LLC header without byte-swapping */
1140 eth->h_proto = snap->protocol;
1141
1142 memcpy(eth->h_dest, daddr, ETH_ALEN);
1143 memcpy(eth->h_source, saddr, ETH_ALEN);
1144 *(u16*)(eth + 1) = vlan_snap;
1145 return 0;
1146 }
1147
1148 /* it's a SNAP + RFC1042 frame */
1149 unifi_trace(priv, UDBG3, "SNAP+RFC1042 len: %d\n", payload_length);
1150
1151 /* chop SNAP+llc header from skb. */
1152 skb_pull(skb, sizeof(llc_snap_hdr_t));
1153
1154 /* Since skb_pull called above to chop snap+llc, no need to check for headroom
1155 * availability before skb_push
1156 */
1157 /* create 802.3 header at beginning of skb. */
1158 eth = (struct ethhdr *)skb_push(skb, ETH_HLEN);
1159 memcpy(eth->h_dest, daddr, ETH_ALEN);
1160 memcpy(eth->h_source, saddr, ETH_ALEN);
1161 /* Copy protocol field without byte-swapping */
1162 eth->h_proto = snap->protocol;
1163 } else {
1164 u16 len;
1165
1166 /* check for headroom availability before skb_push */
1167 if (headroom < (2 * ETH_ALEN + 2)) {
1168 unifi_warning(priv, "headroom not available to skb_push ether header\n");
1169 return -1;
1170 }
1171 /* Add 802.3 header and leave full payload */
1172 len = htons(skb->len);
1173 memcpy(skb_push(skb, 2), &len, 2);
1174 memcpy(skb_push(skb, ETH_ALEN), saddr, ETH_ALEN);
1175 memcpy(skb_push(skb, ETH_ALEN), daddr, ETH_ALEN);
1176
1177 return 1;
1178 }
1179
1180 return 0;
1181} /* skb_80211_to_ether() */
1182
1183
8c87f69a 1184static CsrWifiRouterCtrlPortAction verify_port(unifi_priv_t *priv, unsigned char *address, int queue, u16 interfaceTag)
635d2b00
GKH
1185{
1186#ifdef CSR_NATIVE_LINUX
1187#ifdef CSR_SUPPORT_WEXT
1188 if (queue == UF_CONTROLLED_PORT_Q) {
1189 return priv->wext_conf.block_controlled_port;
1190 } else {
1191 return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN;
1192 }
1193#else
1194 return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN; /* default to open for softmac dev */
1195#endif
1196#else
1197 return uf_sme_port_state(priv, address, queue, interfaceTag);
1198#endif
1199}
1200
1201/*
1202 * ---------------------------------------------------------------------------
1203 * prepare_and_add_macheader
1204 *
1205 *
1206 * These functions adds mac header for packet from netdev
1207 * to UniFi for transmission.
1208 * EAP protocol packets are also appended with Mac header &
1209 * sent using send_ma_pkt_request().
1210 *
1211 * Arguments:
1212 * priv Pointer to device private context struct
1213 * skb Socket buffer containing data packet to transmit
1214 * newSkb Socket buffer containing data packet + Mac header if no sufficient headroom in skb
1215 * serviceClass to append QOS control header in Mac header
1216 * bulkdata if newSkb allocated then bulkdata updated to send to unifi
1217 * interfaceTag the interfaceID on which activity going on
1218 * daddr destination address
1219 * saddr source address
1220 * protection protection bit set in framce control of mac header
1221 *
1222 * Returns:
1223 * Zero on success or error code.
1224 * ---------------------------------------------------------------------------
1225 */
1226
1227int prepare_and_add_macheader(unifi_priv_t *priv, struct sk_buff *skb, struct sk_buff *newSkb,
1228 CSR_PRIORITY priority,
1229 bulk_data_param_t *bulkdata,
8c87f69a 1230 u16 interfaceTag,
7e6f5794
GKH
1231 const u8 *daddr,
1232 const u8 *saddr,
5379b13d 1233 u8 protection)
635d2b00 1234{
8c87f69a 1235 u16 fc = 0;
7e6f5794
GKH
1236 u8 qc = 0;
1237 u8 macHeaderLengthInBytes = MAC_HEADER_SIZE, *bufPtr = NULL;
635d2b00
GKH
1238 bulk_data_param_t data_ptrs;
1239 CsrResult csrResult;
1240 int headroom =0;
7e6f5794 1241 u8 direction = 0;
635d2b00 1242 netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
7e6f5794 1243 u8 *addressOne;
5379b13d 1244 u8 bQosNull = false;
635d2b00
GKH
1245
1246 if (skb == NULL) {
1247 unifi_error(priv,"prepare_and_add_macheader: Invalid SKB reference\n");
1248 return -1;
1249 }
1250
1251 /* add a MAC header refer: 7.1.3.1 Frame Control field in P802.11REVmb.book */
1252 if (priority != CSR_CONTENTION) {
1253 /* EAPOL packets don't go as QOS_DATA */
1254 if (priority == CSR_MANAGEMENT) {
1255 fc |= cpu_to_le16(IEEE802_11_FC_TYPE_DATA);
1256 } else {
1257 /* Qos Control Field */
1258 macHeaderLengthInBytes += QOS_CONTROL_HEADER_SIZE;
1259
1260 if (skb->len) {
1261
1262 fc |= cpu_to_le16(IEEE802_11_FC_TYPE_QOS_DATA);
1263 } else {
1264 fc |= cpu_to_le16(IEEE802_11_FC_TYPE_QOS_NULL);
1265 bQosNull = true;
1266 }
1267 }
1268 } else {
1269 if(skb->len == 0) {
1270 fc |= cpu_to_le16(IEEE802_11_FC_TYPE_NULL);
1271 } else {
1272 fc |= cpu_to_le16(IEEE802_11_FC_TYPE_DATA);
1273 }
1274 }
1275
1276 switch (interfacePriv->interfaceMode)
1277 {
1278 case CSR_WIFI_ROUTER_CTRL_MODE_STA:
1279 case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
1280 direction = 2;
1281 fc |= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK);
1282 break;
1283 case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
1284 direction = 0;
1285 break;
1286 case CSR_WIFI_ROUTER_CTRL_MODE_AP:
1287 case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
1288 direction = 1;
1289 fc |= cpu_to_le16(IEEE802_11_FC_FROM_DS_MASK);
1290 break;
1291 case CSR_WIFI_ROUTER_CTRL_MODE_AMP:
1292 if (priority == CSR_MANAGEMENT ) {
1293
1294 direction = 2;
1295 fc |= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK);
1296 } else {
1297 /* Data frames have to use WDS 4 address frames */
1298 direction = 3;
1299 fc |= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK | IEEE802_11_FC_FROM_DS_MASK);
1300 macHeaderLengthInBytes += 6;
1301 }
1302 break;
1303 default:
1304 unifi_warning(priv, "prepare_and_add_macheader: Unknown mode %d\n",
1305 interfacePriv->interfaceMode);
1306 }
1307
1308
1309 /* If Sta is QOS & HTC is supported then need to set 'order' bit */
1310 /* We don't support HT Control for now */
1311
1312 if(protection) {
1313 fc |= cpu_to_le16(IEEE802_11_FC_PROTECTED_MASK);
1314 }
1315
1316 /* check the skb headroom before pushing mac header */
1317 headroom = skb_headroom(skb);
1318
1319 if (headroom < macHeaderLengthInBytes) {
1320 unifi_trace(priv, UDBG5,
1321 "prepare_and_add_macheader: Allocate headroom extra %d bytes\n",
1322 macHeaderLengthInBytes);
1323
1324 csrResult = unifi_net_data_malloc(priv, &data_ptrs.d[0], skb->len + macHeaderLengthInBytes);
1325
1326 if (csrResult != CSR_RESULT_SUCCESS) {
1327 unifi_error(priv, " failed to allocate request_data. in %s func\n", __FUNCTION__);
1328 return -1;
1329 }
1330 newSkb = (struct sk_buff *)(data_ptrs.d[0].os_net_buf_ptr);
1331 newSkb->len = skb->len + macHeaderLengthInBytes;
1332
1333 memcpy((void*)data_ptrs.d[0].os_data_ptr + macHeaderLengthInBytes,
1334 skb->data, skb->len);
1335
1336 bulkdata->d[0].os_data_ptr = newSkb->data;
1337 bulkdata->d[0].os_net_buf_ptr = (unsigned char*)newSkb;
1338 bulkdata->d[0].data_length = newSkb->len;
1339
7e6f5794 1340 bufPtr = (u8*)data_ptrs.d[0].os_data_ptr;
635d2b00
GKH
1341
1342 /* The old skb will not be used again */
1343 kfree_skb(skb);
1344 } else {
1345
1346 /* headroom has sufficient size, so will get proper pointer */
7e6f5794 1347 bufPtr = (u8*)skb_push(skb, macHeaderLengthInBytes);
635d2b00
GKH
1348 bulkdata->d[0].os_data_ptr = skb->data;
1349 bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skb;
1350 bulkdata->d[0].data_length = skb->len;
1351 }
1352
1353 /* Frame the actual MAC header */
1354
1355 memset(bufPtr, 0, macHeaderLengthInBytes);
1356
1357 /* copy frameControl field */
1358 memcpy(bufPtr, &fc, sizeof(fc));
1359 bufPtr += sizeof(fc);
1360 macHeaderLengthInBytes -= sizeof(fc);
1361
1362 /* Duration/ID field which is 2 bytes */
1363 bufPtr += 2;
1364 macHeaderLengthInBytes -= 2;
1365
1366 switch(direction)
1367 {
1368 case 0:
1369 /* Its an Ad-Hoc no need to route it through AP */
1370 /* Address1: MAC address of the destination from eth header */
1371 memcpy(bufPtr, daddr, ETH_ALEN);
1372 bufPtr += ETH_ALEN;
1373 macHeaderLengthInBytes -= ETH_ALEN;
1374
1375 /* Address2: MAC address of the source */
1376 memcpy(bufPtr, saddr, ETH_ALEN);
1377 bufPtr += ETH_ALEN;
1378 macHeaderLengthInBytes -= ETH_ALEN;
1379
1380 /* Address3: the BSSID (locally generated in AdHoc (creators Bssid)) */
1381 memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN);
1382 bufPtr += ETH_ALEN;
1383 macHeaderLengthInBytes -= ETH_ALEN;
1384 break;
1385 case 1:
1386 /* Address1: MAC address of the actual destination */
1387 memcpy(bufPtr, daddr, ETH_ALEN);
1388 bufPtr += ETH_ALEN;
1389 macHeaderLengthInBytes -= ETH_ALEN;
1390 /* Address2: The MAC address of the AP */
1391 memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN);
1392 bufPtr += ETH_ALEN;
1393 macHeaderLengthInBytes -= ETH_ALEN;
1394
1395 /* Address3: MAC address of the source from eth header */
1396 memcpy(bufPtr, saddr, ETH_ALEN);
1397 bufPtr += ETH_ALEN;
1398 macHeaderLengthInBytes -= ETH_ALEN;
1399 break;
1400 case 2:
1401 /* Address1: To AP is the MAC address of the AP to which its associated */
1402 memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN);
1403 bufPtr += ETH_ALEN;
1404 macHeaderLengthInBytes -= ETH_ALEN;
1405
1406 /* Address2: MAC address of the source from eth header */
1407 memcpy(bufPtr, saddr, ETH_ALEN);
1408 bufPtr += ETH_ALEN;
1409 macHeaderLengthInBytes -= ETH_ALEN;
1410
1411 /* Address3: MAC address of the actual destination on the distribution system */
1412 memcpy(bufPtr, daddr, ETH_ALEN);
1413 bufPtr += ETH_ALEN;
1414 macHeaderLengthInBytes -= ETH_ALEN;
1415 break;
1416 case 3:
1417 memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN);
1418 bufPtr += ETH_ALEN;
1419 macHeaderLengthInBytes -= ETH_ALEN;
1420
1421 /* Address2: MAC address of the source from eth header */
1422 memcpy(bufPtr, saddr, ETH_ALEN);
1423 bufPtr += ETH_ALEN;
1424 macHeaderLengthInBytes -= ETH_ALEN;
1425
1426 /* Address3: MAC address of the actual destination on the distribution system */
1427 memcpy(bufPtr, daddr, ETH_ALEN);
1428 bufPtr += ETH_ALEN;
1429 macHeaderLengthInBytes -= ETH_ALEN;
1430 break;
1431 default:
1432 unifi_error(priv,"Unknown direction =%d : Not handled now\n",direction);
1433 return -1;
1434 }
1435 /* 2 bytes of frame control field, appended by firmware */
1436 bufPtr += 2;
1437 macHeaderLengthInBytes -= 2;
1438
1439 if (3 == direction) {
1440 /* Address4: MAC address of the source */
1441 memcpy(bufPtr, saddr, ETH_ALEN);
1442 bufPtr += ETH_ALEN;
1443 macHeaderLengthInBytes -= ETH_ALEN;
1444 }
1445
1446 /* IF Qos Data or Qos Null Data then set QosControl field */
1447 if ((priority != CSR_CONTENTION) && (macHeaderLengthInBytes >= QOS_CONTROL_HEADER_SIZE)) {
1448
95edd09e 1449 if (priority > 7) {
635d2b00
GKH
1450 unifi_trace(priv, UDBG1, "data packets priority is more than 7, priority = %x\n", priority);
1451 qc |= 7;
1452 } else {
1453 qc |= priority;
1454 }
1455 /*assigning address1
1456 * Address1 offset taken fromm bufPtr(currently bufPtr pointing to Qos contorl) variable in reverse direction
1457 * Address4 don't exit
1458 */
1459
1460 addressOne = bufPtr- ADDRESS_ONE_OFFSET;
1461
1462 if (addressOne[0] & 0x1) {
1463 /* multicast/broadcast frames, no acknowledgement needed */
1464 qc |= 1 << 5;
1465 }
1466 /* non-AP mode only for now */
1467 if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA ||
1468 interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS ||
1469 interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI) {
1470 /* In case of STA and IBSS case eosp and txop limit is 0. */
1471 } else {
1472 if(bQosNull) {
1473 qc |= 1 << 4;
1474 }
1475 }
1476
1477 /* append Qos control field to mac header */
1478 bufPtr[0] = qc;
1479 /* txop limit is 0 */
1480 bufPtr[1] = 0;
1481 macHeaderLengthInBytes -= QOS_CONTROL_HEADER_SIZE;
1482 }
1483 if (macHeaderLengthInBytes) {
1484 unifi_warning(priv, " Mac header not appended properly\n");
1485 return -1;
1486 }
1487 return 0;
1488}
1489
1490/*
1491 * ---------------------------------------------------------------------------
1492 * send_ma_pkt_request
1493 *
1494 * These functions send a data packet to UniFi for transmission.
1495 * EAP protocol packets are also sent as send_ma_pkt_request().
1496 *
1497 * Arguments:
1498 * priv Pointer to device private context struct
1499 * skb Socket buffer containing data packet to transmit
1500 * ehdr Pointer to Ethernet header within skb.
1501 *
1502 * Returns:
1503 * Zero on success or error code.
1504 * ---------------------------------------------------------------------------
1505 */
1506
1507static int
1508send_ma_pkt_request(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr *ehdr, CSR_PRIORITY priority)
1509{
1510 int r;
8c87f69a 1511 u16 i;
5379b13d 1512 u8 eapolStore = FALSE;
635d2b00
GKH
1513 struct sk_buff *newSkb = NULL;
1514 bulk_data_param_t bulkdata;
1515 const int proto = ntohs(ehdr->h_proto);
8c87f69a 1516 u16 interfaceTag;
635d2b00
GKH
1517 CsrWifiMacAddress peerAddress;
1518 CSR_TRANSMISSION_CONTROL transmissionControl = CSR_NO_CONFIRM_REQUIRED;
163eb0d8 1519 s8 protection;
635d2b00 1520 netInterface_priv_t *interfacePriv = NULL;
95edd09e 1521 CSR_RATE TransmitRate = (CSR_RATE)0;
635d2b00
GKH
1522
1523 unifi_trace(priv, UDBG5, "entering send_ma_pkt_request\n");
1524
1525 /* Get the interface Tag by means of source Mac address */
1526 for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
1527 if (!memcmp(priv->netdev[i]->dev_addr, ehdr->h_source, ETH_ALEN)) {
1528 interfaceTag = i;
1529 interfacePriv = priv->interfacePriv[interfaceTag];
1530 break;
1531 }
1532 }
1533
1534 if (interfacePriv == NULL) {
1535 /* No match found - error */
1536 interfaceTag = 0;
1537 interfacePriv = priv->interfacePriv[interfaceTag];
1538 unifi_warning(priv, "Mac address not matching ... debugging needed\n");
1539 interfacePriv->stats.tx_dropped++;
1540 kfree_skb(skb);
1541 return -1;
1542 }
1543
1544 /* Add a SNAP header if necessary */
1545 if (skb_add_llc_snap(priv->netdev[interfaceTag], skb, proto) != 0) {
1546 /* convert failed */
1547 unifi_error(priv, "skb_add_llc_snap failed.\n");
1548 kfree_skb(skb);
1549 return -1;
1550 }
1551
1552 bulkdata.d[0].os_data_ptr = skb->data;
1553 bulkdata.d[0].os_net_buf_ptr = (unsigned char*)skb;
1554 bulkdata.d[0].net_buf_length = bulkdata.d[0].data_length = skb->len;
1555 bulkdata.d[1].os_data_ptr = NULL;
1556 bulkdata.d[1].os_net_buf_ptr = NULL;
1557 bulkdata.d[1].net_buf_length = bulkdata.d[1].data_length = 0;
1558
1559#ifdef CSR_SUPPORT_SME
1560 /* Notify the TA module for the Tx frame for non AP/P2PGO mode*/
1561 if ((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_AP) &&
1562 (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_P2PGO)) {
1563 unifi_ta_sample(priv->card, CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX,
1564 &bulkdata.d[0], ehdr->h_source,
1565 priv->netdev[interfaceTag]->dev_addr,
1566 jiffies_to_msecs(jiffies),
1567 0); /* rate is unknown on tx */
1568 }
1569#endif /* CSR_SUPPORT_SME */
1570
1571 if ((proto == ETH_P_PAE)
1572#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1573 || (proto == ETH_P_WAI)
1574#endif
1575 )
1576 {
1577 /* check for m4 detection */
1578 if (0 == uf_verify_m4(priv, bulkdata.d[0].os_data_ptr, bulkdata.d[0].data_length)) {
1579 eapolStore = TRUE;
1580 }
1581 }
1582
1583#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1584 if (proto == ETH_P_WAI)
1585 {
1586 protection = 0; /*WAI packets always sent unencrypted*/
1587 }
1588 else
1589 {
1590#endif
1591#ifdef CSR_SUPPORT_SME
1592 if ((protection = uf_get_protection_bit_from_interfacemode(priv, interfaceTag, ehdr->h_dest)) < 0) {
1593 unifi_warning(priv, "unicast address, but destination not in station record database\n");
1594 unifi_net_data_free(priv, &bulkdata.d[0]);
1595 return -1;
1596 }
1597#else
1598 protection = 0;
1599#endif
1600#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1601 }
1602#endif
1603
1604 /* append Mac header for Eapol as well as data packet */
1605 if (prepare_and_add_macheader(priv, skb, newSkb, priority, &bulkdata, interfaceTag, ehdr->h_dest, ehdr->h_source, protection)) {
1606 unifi_error(priv, "failed to create MAC header\n");
1607 unifi_net_data_free(priv, &bulkdata.d[0]);
1608 return -1;
1609 }
1610
1611 /* RA adrress must contain the immediate destination MAC address that is similiar to
1612 * the Address 1 field of 802.11 Mac header here 4 is: (sizeof(framecontrol) + sizeof (durationID))
1613 * which is address 1 field
1614 */
7e6f5794 1615 memcpy(peerAddress.a, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
635d2b00
GKH
1616
1617 unifi_trace(priv, UDBG5, "RA[0]=%x, RA[1]=%x, RA[2]=%x, RA[3]=%x, RA[4]=%x, RA[5]=%x\n",
1618 peerAddress.a[0],peerAddress.a[1], peerAddress.a[2], peerAddress.a[3],
1619 peerAddress.a[4],peerAddress.a[5]);
1620
1621
1622 if ((proto == ETH_P_PAE)
1623#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1624 || (proto == ETH_P_WAI)
1625#endif
1626 )
1627 {
1628 CSR_SIGNAL signal;
1629 CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest;
1630
1631 /* initialize signal to zero */
1632 memset(&signal, 0, sizeof(CSR_SIGNAL));
1633
1634 /* Frame MA_PACKET request */
1635 signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID;
1636 signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
1637 signal.SignalPrimitiveHeader.SenderProcessId = priv->netdev_client->sender_id;
1638
1639 transmissionControl = req->TransmissionControl = 0;
1640#ifdef CSR_SUPPORT_SME
1641 if (eapolStore)
1642 {
1643 netInterface_priv_t *netpriv = (netInterface_priv_t *)netdev_priv(priv->netdev[interfaceTag]);
1644
1645 /* Fill the MA-PACKET.req */
1646
1647 req->Priority = priority;
1648 unifi_trace(priv, UDBG3, "Tx Frame with Priority: %x\n", req->Priority);
1649
1650 /* rate selected by firmware */
1651 req->TransmitRate = 0;
1652 req->HostTag = CSR_WIFI_EAPOL_M4_HOST_TAG;
1653 /* RA address matching with address 1 of Mac header */
7e6f5794 1654 memcpy(req->Ra.x, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
635d2b00
GKH
1655
1656 spin_lock(&priv->m4_lock);
1657 /* Store the M4-PACKET.req for later */
1658 interfacePriv->m4_signal = signal;
1659 interfacePriv->m4_bulk_data.net_buf_length = bulkdata.d[0].net_buf_length;
1660 interfacePriv->m4_bulk_data.data_length = bulkdata.d[0].data_length;
1661 interfacePriv->m4_bulk_data.os_data_ptr = bulkdata.d[0].os_data_ptr;
1662 interfacePriv->m4_bulk_data.os_net_buf_ptr = bulkdata.d[0].os_net_buf_ptr;
1663 spin_unlock(&priv->m4_lock);
1664
1665 /* Signal the workqueue to call CsrWifiRouterCtrlM4ReadyToSendIndSend().
1666 * It cannot be called directly from the tx path because it
1667 * does a non-atomic kmalloc via the framework's CsrPmemAlloc().
1668 */
1669 queue_work(priv->unifi_workqueue, &netpriv->send_m4_ready_task);
1670
1671 return 0;
1672 }
1673#endif
95edd09e
GKH
1674 }/*EAPOL or WAI packet*/
1675
1676#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
1677 if ((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) && \
1678 (priv->wapi_unicast_filter) && \
1679 (proto != ETH_P_PAE) && \
1680 (proto != ETH_P_WAI) && \
1681 (skb->len > 0))
1682 {
1683 CSR_SIGNAL signal;
1684 CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest;
1685 netInterface_priv_t *netpriv = (netInterface_priv_t *)netdev_priv(priv->netdev[interfaceTag]);
1686
1687 unifi_trace(priv, UDBG4, "send_ma_pkt_request() - WAPI unicast data packet when USKID = 1 \n");
1688
1689 /* initialize signal to zero */
1690 memset(&signal, 0, sizeof(CSR_SIGNAL));
1691 /* Frame MA_PACKET request */
1692 signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID;
1693 signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
1694 signal.SignalPrimitiveHeader.SenderProcessId = priv->netdev_client->sender_id;
1695
1696 /* Fill the MA-PACKET.req */
1697 req->TransmissionControl = 0;
1698 req->Priority = priority;
1699 unifi_trace(priv, UDBG3, "Tx Frame with Priority: %x\n", req->Priority);
1700 req->TransmitRate = (CSR_RATE) 0; /* rate selected by firmware */
1701 req->HostTag = 0xffffffff; /* Ask for a new HostTag */
1702 /* RA address matching with address 1 of Mac header */
7e6f5794 1703 memcpy(req->Ra.x, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
95edd09e
GKH
1704
1705 /* Store the M4-PACKET.req for later */
1706 spin_lock(&priv->wapi_lock);
1707 interfacePriv->wapi_unicast_ma_pkt_sig = signal;
1708 interfacePriv->wapi_unicast_bulk_data.net_buf_length = bulkdata.d[0].net_buf_length;
1709 interfacePriv->wapi_unicast_bulk_data.data_length = bulkdata.d[0].data_length;
1710 interfacePriv->wapi_unicast_bulk_data.os_data_ptr = bulkdata.d[0].os_data_ptr;
1711 interfacePriv->wapi_unicast_bulk_data.os_net_buf_ptr = bulkdata.d[0].os_net_buf_ptr;
1712 spin_unlock(&priv->wapi_lock);
1713
1714 /* Signal the workqueue to call CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend().
1715 * It cannot be called directly from the tx path because it
1716 * does a non-atomic kmalloc via the framework's CsrPmemAlloc().
1717 */
1718 queue_work(priv->unifi_workqueue, &netpriv->send_pkt_to_encrypt);
1719
1720 return 0;
1721 }
1722#endif
1723
1724 if(priv->cmanrTestMode)
1725 {
1726 TransmitRate = priv->cmanrTestModeTransmitRate;
1727 unifi_trace(priv, UDBG2, "send_ma_pkt_request: cmanrTestModeTransmitRate = %d TransmitRate=%d\n",
1728 priv->cmanrTestModeTransmitRate,
1729 TransmitRate
1730 );
635d2b00
GKH
1731 }
1732
1733 /* Send UniFi msg */
1734 /* Here hostTag is been sent as 0xffffffff, its been appended properly while framing MA-Packet request in pdu_processing.c file */
1735 r = uf_process_ma_packet_req(priv,
1736 peerAddress.a,
1737 0xffffffff, /* Ask for a new HostTag */
1738 interfaceTag,
1739 transmissionControl,
95edd09e 1740 TransmitRate,
635d2b00
GKH
1741 priority,
1742 priv->netdev_client->sender_id,
1743 &bulkdata);
1744
1745 if (r) {
1746 unifi_trace(priv, UDBG1, "(HIP validation failure) r = %x\n", r);
1747 unifi_net_data_free(priv, &bulkdata.d[0]);
1748 return -1;
1749 }
1750
1751 unifi_trace(priv, UDBG3, "leaving send_ma_pkt_request, UNITDATA result code = %d\n", r);
1752
1753 return r;
1754} /* send_ma_pkt_request() */
1755
1756/*
1757 * ---------------------------------------------------------------------------
1758 * uf_net_xmit
1759 *
1760 * This function is called by the higher level stack to transmit an
1761 * ethernet packet.
1762 *
1763 * Arguments:
1764 * skb Ethernet packet to send.
1765 * dev Pointer to the linux net device.
1766 *
1767 * Returns:
1768 * 0 on success (packet was consumed, not necessarily transmitted)
1769 * 1 if packet was requeued
1770 * -1 on error
1771 *
1772 *
1773 * Notes:
1774 * The controlled port is handled in the qdisc dequeue handler.
1775 * ---------------------------------------------------------------------------
1776 */
635d2b00 1777static netdev_tx_t
635d2b00
GKH
1778uf_net_xmit(struct sk_buff *skb, struct net_device *dev)
1779{
1780 netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
1781 unifi_priv_t *priv = interfacePriv->privPtr;
1782 struct ethhdr ehdr;
1783 int proto, port;
1784 int result;
1785 static tx_signal_handler tx_handler;
1786 CSR_PRIORITY priority;
635d2b00 1787 CsrWifiRouterCtrlPortAction port_action;
635d2b00
GKH
1788
1789 func_enter();
1790
1791 unifi_trace(priv, UDBG5, "unifi_net_xmit: skb = %x\n", skb);
1792
1793 memcpy(&ehdr, skb->data, ETH_HLEN);
1794 proto = ntohs(ehdr.h_proto);
1795 priority = get_packet_priority(priv, skb, &ehdr, interfacePriv);
1796
1797 /* All frames are sent as MA-PACKET.req (EAPOL also) */
1798 tx_handler = send_ma_pkt_request;
1799
1800 /* 802.1x - apply controlled/uncontrolled port rules */
1801 if ((proto != ETH_P_PAE)
1802#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1803 && (proto != ETH_P_WAI)
1804#endif
1805 ) {
1806 port = UF_CONTROLLED_PORT_Q;
1807 } else {
1808 /* queue 4 */
1809 port = UF_UNCONTROLLED_PORT_Q;
1810 }
1811
635d2b00
GKH
1812 /* Uncontrolled port rules apply */
1813 port_action = verify_port(priv
1814 , (((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode)||(CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI== interfacePriv->interfaceMode))? interfacePriv->bssid.a: ehdr.h_dest)
1815 , port
1816 , interfacePriv->InterfaceTag);
1817
1818 if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
1819 unifi_trace(priv, UDBG5,
1820 "uf_net_xmit: %s controlled port open\n",
1821 port ? "" : "un");
1822 /* Remove the ethernet header */
1823 skb_pull(skb, ETH_HLEN);
1824 result = tx_handler(priv, skb, &ehdr, priority);
1825 } else {
1826
1827 /* Discard the packet if necessary */
1828 unifi_trace(priv, UDBG2,
1829 "uf_net_xmit: %s controlled port %s\n",
1830 port ? "" : "un", port_action==CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK ? "blocked" : "closed");
1831 interfacePriv->stats.tx_dropped++;
1832 kfree_skb(skb);
1833
1834 func_exit();
1835 return NETDEV_TX_OK;
1836 }
635d2b00
GKH
1837
1838 if (result == NETDEV_TX_OK) {
95edd09e
GKH
1839#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
1840 /* Don't update the tx stats when the pkt is to be sent for sw encryption*/
1841 if (!((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) &&
1842 (priv->wapi_unicast_filter == 1)))
1843 {
1844 dev->trans_start = jiffies;
1845 /* Should really count tx stats in the UNITDATA.status signal but
1846 * that doesn't have the length.
1847 */
1848 interfacePriv->stats.tx_packets++;
1849 /* count only the packet payload */
1850 interfacePriv->stats.tx_bytes += skb->len;
635d2b00 1851
95edd09e
GKH
1852 }
1853#else
1854 dev->trans_start = jiffies;
635d2b00
GKH
1855
1856 /*
1857 * Should really count tx stats in the UNITDATA.status signal but
1858 * that doesn't have the length.
1859 */
1860 interfacePriv->stats.tx_packets++;
1861 /* count only the packet payload */
1862 interfacePriv->stats.tx_bytes += skb->len;
95edd09e 1863#endif
635d2b00
GKH
1864 } else if (result < 0) {
1865
1866 /* Failed to send: fh queue was full, and the skb was discarded.
1867 * Return OK to indicate that the buffer was consumed, to stop the
1868 * kernel re-transmitting the freed buffer.
1869 */
1870 interfacePriv->stats.tx_dropped++;
1871 unifi_trace(priv, UDBG1, "unifi_net_xmit: (Packet Drop), dropped count = %x\n", interfacePriv->stats.tx_dropped);
1872 result = NETDEV_TX_OK;
1873 }
1874
1875 /* The skb will have been freed by send_XXX_request() */
1876
1877 func_exit();
1878 return result;
1879} /* uf_net_xmit() */
1880
1881/*
1882 * ---------------------------------------------------------------------------
1883 * unifi_pause_xmit
1884 * unifi_restart_xmit
1885 *
1886 * These functions are called from the UniFi core to control the flow
1887 * of packets from the upper layers.
1888 * unifi_pause_xmit() is called when the internal queue is full and
1889 * should take action to stop unifi_ma_unitdata() being called.
1890 * When the queue has drained, unifi_restart_xmit() will be called to
1891 * re-enable the flow of packets for transmission.
1892 *
1893 * Arguments:
1894 * ospriv OS private context pointer.
1895 *
1896 * Returns:
1897 * unifi_pause_xmit() is called from interrupt context.
1898 * ---------------------------------------------------------------------------
1899 */
1900void
1901unifi_pause_xmit(void *ospriv, unifi_TrafficQueue queue)
1902{
1903 unifi_priv_t *priv = ospriv;
1904 int i; /* used as a loop counter */
1905
1906 func_enter();
1907 unifi_trace(priv, UDBG2, "Stopping queue %d\n", queue);
1908
635d2b00
GKH
1909 for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++)
1910 {
1911 if (netif_running(priv->netdev[i]))
1912 {
1913 netif_stop_subqueue(priv->netdev[i], (u16)queue);
1914 }
1915 }
635d2b00
GKH
1916
1917#ifdef CSR_SUPPORT_SME
1918 if(queue<=3) {
1919 routerStartBuffering(priv,queue);
1920 unifi_trace(priv,UDBG2,"Start buffering %d\n", queue);
1921 } else {
1922 routerStartBuffering(priv,0);
1923 unifi_error(priv, "Start buffering %d defaulting to 0\n", queue);
1924 }
1925#endif
1926 func_exit();
1927
1928} /* unifi_pause_xmit() */
1929
1930void
1931unifi_restart_xmit(void *ospriv, unifi_TrafficQueue queue)
1932{
1933 unifi_priv_t *priv = ospriv;
1934 int i=0; /* used as a loop counter */
1935
1936 func_enter();
1937 unifi_trace(priv, UDBG2, "Waking queue %d\n", queue);
1938
635d2b00
GKH
1939 for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++)
1940 {
1941 if (netif_running(priv->netdev[i]))
1942 {
1943 netif_wake_subqueue(priv->netdev[i], (u16)queue);
1944 }
1945 }
635d2b00
GKH
1946
1947#ifdef CSR_SUPPORT_SME
1948 if(queue <=3) {
1949 routerStopBuffering(priv,queue);
1950 uf_send_buffered_frames(priv,queue);
1951 } else {
1952 routerStopBuffering(priv,0);
1953 uf_send_buffered_frames(priv,0);
1954 }
1955#endif
1956 func_exit();
1957} /* unifi_restart_xmit() */
1958
1959
1960static void
8c87f69a 1961indicate_rx_skb(unifi_priv_t *priv, u16 ifTag, u8* dst_a, u8* src_a, struct sk_buff *skb, CSR_SIGNAL *signal,
635d2b00
GKH
1962 bulk_data_param_t *bulkdata)
1963{
1964 int r, sr = 0;
1965 struct net_device *dev;
1966
1967#ifdef CSR_SUPPORT_SME
1968 llc_snap_hdr_t *snap;
1969
1970 snap = (llc_snap_hdr_t *)skb->data;
1971
1972 sr = _identify_sme_ma_pkt_ind(priv,
1973 snap->oui, ntohs(snap->protocol),
1974 signal,
1975 bulkdata,
1976 dst_a, src_a );
1977#endif
1978
1979 /*
1980 * Decapsulate any SNAP header and
1981 * prepend an ethernet header so that the skb manipulation and ARP
1982 * stuff works.
1983 */
1984 r = skb_80211_to_ether(priv, skb, dst_a, src_a,
1985 signal, bulkdata);
1986 if (r == -1) {
1987 /* Drop the packet and return */
1988 priv->interfacePriv[ifTag]->stats.rx_errors++;
1989 priv->interfacePriv[ifTag]->stats.rx_frame_errors++;
1990 unifi_net_data_free(priv, &bulkdata->d[0]);
1991 unifi_notice(priv, "indicate_rx_skb: Discard unknown frame.\n");
1992 func_exit();
1993 return;
1994 }
1995
1996 /* Handle the case where packet is sent up through the subscription
1997 * API but should not be given to the network stack (AMP PAL case)
1998 * LLC header is different from WiFi and the packet has been subscribed for
1999 */
2000 if (r == 1 && sr == 1) {
2001 unifi_net_data_free(priv, &bulkdata->d[0]);
2002 unifi_trace(priv, UDBG5, "indicate_rx_skb: Data given to subscription"
2003 "API, not being given to kernel\n");
2004 func_exit();
2005 return;
2006 }
2007
2008 dev = priv->netdev[ifTag];
2009 /* Now we look like a regular ethernet frame */
2010 /* Fill in SKB meta data */
2011 skb->dev = dev;
2012 skb->protocol = eth_type_trans(skb, dev);
2013 skb->ip_summed = CHECKSUM_UNNECESSARY;
2014
2015 /* Test for an overlength frame */
2016 if (skb->len > (dev->mtu + ETH_HLEN)) {
2017 /* A bogus length ethfrm has been encap'd. */
2018 /* Is someone trying an oflow attack? */
2019 unifi_error(priv, "%s: oversize frame (%d > %d)\n",
2020 dev->name,
2021 skb->len, dev->mtu + ETH_HLEN);
2022
2023 /* Drop the packet and return */
2024 priv->interfacePriv[ifTag]->stats.rx_errors++;
2025 priv->interfacePriv[ifTag]->stats.rx_length_errors++;
2026 unifi_net_data_free(priv, &bulkdata->d[0]);
2027 func_exit();
2028 return;
2029 }
2030
2031
95edd09e
GKH
2032 if(priv->cmanrTestMode)
2033 {
2034 const CSR_MA_PACKET_INDICATION *pkt_ind = &signal->u.MaPacketIndication;
2035 priv->cmanrTestModeTransmitRate = pkt_ind->ReceivedRate;
2036 unifi_trace(priv, UDBG2, "indicate_rx_skb: cmanrTestModeTransmitRate=%d\n", priv->cmanrTestModeTransmitRate);
2037 }
2038
635d2b00
GKH
2039 /* Pass SKB up the stack */
2040#ifdef CSR_WIFI_USE_NETIF_RX
2041 netif_rx(skb);
2042#else
2043 netif_rx_ni(skb);
2044#endif
2045
2046 if (dev != NULL) {
2047 dev->last_rx = jiffies;
2048 }
2049
2050 /* Bump rx stats */
2051 priv->interfacePriv[ifTag]->stats.rx_packets++;
2052 priv->interfacePriv[ifTag]->stats.rx_bytes += bulkdata->d[0].data_length;
2053
2054 func_exit();
2055 return;
2056}
2057
2058void
2059uf_process_rx_pending_queue(unifi_priv_t *priv, int queue,
2060 CsrWifiMacAddress source_address,
8c87f69a 2061 int indicate, u16 interfaceTag)
635d2b00
GKH
2062{
2063 rx_buffered_packets_t *rx_q_item;
2064 struct list_head *rx_list;
2065 struct list_head *n;
2066 struct list_head *l_h;
2067 static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
2068 netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
2069
2070 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2071 unifi_error(priv, "uf_process_rx_pending_queue bad interfaceTag\n");
2072 return;
2073 }
2074
2075 if (queue == UF_CONTROLLED_PORT_Q) {
2076 rx_list = &interfacePriv->rx_controlled_list;
2077 } else {
2078 rx_list = &interfacePriv->rx_uncontrolled_list;
2079 }
2080
2081 down(&priv->rx_q_sem);
2082 list_for_each_safe(l_h, n, rx_list) {
2083 rx_q_item = list_entry(l_h, rx_buffered_packets_t, q);
2084
2085 /* Validate against the source address */
2086 if (memcmp(broadcast_address.a, source_address.a, ETH_ALEN) &&
2087 memcmp(rx_q_item->sa.a, source_address.a, ETH_ALEN)) {
2088
2089 unifi_trace(priv, UDBG2,
2090 "uf_process_rx_pending_queue: Skipping sa=%02X%02X%02X%02X%02X%02X skb=%p, bulkdata=%p\n",
2091 rx_q_item->sa.a[0], rx_q_item->sa.a[1],
2092 rx_q_item->sa.a[2], rx_q_item->sa.a[3],
2093 rx_q_item->sa.a[4], rx_q_item->sa.a[5],
2094 rx_q_item->skb, &rx_q_item->bulkdata.d[0]);
2095 continue;
2096 }
2097
2098 list_del(l_h);
2099
2100
2101 unifi_trace(priv, UDBG2,
2102 "uf_process_rx_pending_queue: Was Blocked skb=%p, bulkdata=%p\n",
2103 rx_q_item->skb, &rx_q_item->bulkdata);
2104
2105 if (indicate) {
2106 indicate_rx_skb(priv, interfaceTag, rx_q_item->da.a, rx_q_item->sa.a, rx_q_item->skb, &rx_q_item->signal, &rx_q_item->bulkdata);
2107 } else {
2108 interfacePriv->stats.rx_dropped++;
2109 unifi_net_data_free(priv, &rx_q_item->bulkdata.d[0]);
2110 }
2111
2112 /* It is our resposibility to free the Rx structure object. */
2113 kfree(rx_q_item);
2114 }
2115 up(&priv->rx_q_sem);
2116}
2117
2118/*
2119 * ---------------------------------------------------------------------------
2120 * uf_resume_data_plane
2121 *
2122 * Is called when the (un)controlled port is set to open,
2123 * to notify the network stack to schedule for transmission
2124 * any packets queued in the qdisk while port was closed and
2125 * indicated to the stack any packets buffered in the Rx queues.
2126 *
2127 * Arguments:
2128 * priv Pointer to device private struct
2129 *
2130 * Returns:
2131 * ---------------------------------------------------------------------------
2132 */
2133void
2134uf_resume_data_plane(unifi_priv_t *priv, int queue,
2135 CsrWifiMacAddress peer_address,
8c87f69a 2136 u16 interfaceTag)
635d2b00
GKH
2137{
2138#ifdef CSR_SUPPORT_WEXT
2139 netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
2140#endif
2141
2142 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2143 unifi_error(priv, "uf_resume_data_plane bad interfaceTag\n");
2144 return;
2145 }
2146
2147 unifi_trace(priv, UDBG2, "Resuming netif\n");
2148
2149 /*
2150 * If we are waiting for the net device to enter the up state, don't
2151 * process the rx queue yet as it will be done by the callback when
2152 * the device is ready.
2153 */
2154#ifdef CSR_SUPPORT_WEXT
2155 if (!interfacePriv->wait_netdev_change)
2156#endif
2157 {
2158#ifdef CONFIG_NET_SCHED
2159 if (netif_running(priv->netdev[interfaceTag])) {
635d2b00 2160 netif_tx_schedule_all(priv->netdev[interfaceTag]);
635d2b00
GKH
2161 }
2162#endif
2163 uf_process_rx_pending_queue(priv, queue, peer_address, 1,interfaceTag);
2164 }
2165} /* uf_resume_data_plane() */
2166
2167
8c87f69a 2168void uf_free_pending_rx_packets(unifi_priv_t *priv, int queue, CsrWifiMacAddress peer_address,u16 interfaceTag)
635d2b00
GKH
2169{
2170 uf_process_rx_pending_queue(priv, queue, peer_address, 0,interfaceTag);
2171
2172} /* uf_free_pending_rx_packets() */
2173
2174
2175/*
2176 * ---------------------------------------------------------------------------
2177 * unifi_rx
2178 *
2179 * Reformat a UniFi data received packet into a p80211 packet and
2180 * pass it up the protocol stack.
2181 *
2182 * Arguments:
2183 * None.
2184 *
2185 * Returns:
2186 * None.
2187 * ---------------------------------------------------------------------------
2188 */
2189static void
2190unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
2191{
8c87f69a 2192 u16 interfaceTag;
635d2b00
GKH
2193 bulk_data_desc_t *pData;
2194 const CSR_MA_PACKET_INDICATION *pkt_ind = &signal->u.MaPacketIndication;
2195 struct sk_buff *skb;
2196 CsrWifiRouterCtrlPortAction port_action;
7e6f5794 2197 u8 dataFrameType;
635d2b00
GKH
2198 int proto;
2199 int queue;
2200
7e6f5794
GKH
2201 u8 da[ETH_ALEN], sa[ETH_ALEN];
2202 u8 toDs, fromDs, frameType, macHeaderLengthInBytes = MAC_HEADER_SIZE;
8c87f69a 2203 u16 frameControl;
635d2b00
GKH
2204 netInterface_priv_t *interfacePriv;
2205 struct ethhdr ehdr;
2206
2207 func_enter();
2208
2209 interfaceTag = (pkt_ind->VirtualInterfaceIdentifier & 0xff);
2210 interfacePriv = priv->interfacePriv[interfaceTag];
2211
2212 /* Sanity check that the VIF refers to a sensible interface */
2213 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
2214 {
2215 unifi_error(priv, "%s: MA-PACKET indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
2216 unifi_net_data_free(priv,&bulkdata->d[0]);
2217 func_exit();
2218 return;
2219 }
2220
2221 /* Sanity check that the VIF refers to an allocated netdev */
2222 if (!interfacePriv->netdev_registered)
2223 {
2224 unifi_error(priv, "%s: MA-PACKET indication with unallocated interfaceTag %d\n", __FUNCTION__, interfaceTag);
2225 unifi_net_data_free(priv, &bulkdata->d[0]);
2226 func_exit();
2227 return;
2228 }
2229
2230 if (bulkdata->d[0].data_length == 0) {
2231 unifi_warning(priv, "%s: MA-PACKET indication with zero bulk data\n", __FUNCTION__);
2232 unifi_net_data_free(priv,&bulkdata->d[0]);
2233 func_exit();
2234 return;
2235 }
2236
2237
2238 skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
2239 skb->len = bulkdata->d[0].data_length;
2240
2241 /* Point to the addresses */
2242 toDs = (skb->data[1] & 0x01) ? 1 : 0;
2243 fromDs = (skb->data[1] & 0x02) ? 1 : 0;
2244
2245 memcpy(da,(skb->data+4+toDs*12),ETH_ALEN);/* Address1 or 3 */
2246 memcpy(sa,(skb->data+10+fromDs*(6+toDs*8)),ETH_ALEN); /* Address2, 3 or 4 */
2247
2248
2249 pData = &bulkdata->d[0];
2250 frameControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr);
2251 frameType = ((frameControl & 0x000C) >> 2);
2252
2253 dataFrameType =((frameControl & 0x00f0) >> 4);
2254 unifi_trace(priv, UDBG6,
2255 "%s: Receive Data Frame Type %d \n", __FUNCTION__,dataFrameType);
2256
2257 switch(dataFrameType)
2258 {
2259 case QOS_DATA:
2260 case QOS_DATA_NULL:
2261 /* If both are set then the Address4 exists (only for AP) */
2262 if (fromDs && toDs)
2263 {
2264 /* 6 is the size of Address4 field */
2265 macHeaderLengthInBytes += (QOS_CONTROL_HEADER_SIZE + 6);
2266 }
2267 else
2268 {
2269 macHeaderLengthInBytes += QOS_CONTROL_HEADER_SIZE;
2270 }
2271
2272 /* If order bit set then HT control field is the part of MAC header */
2273 if (frameControl & FRAME_CONTROL_ORDER_BIT)
2274 macHeaderLengthInBytes += HT_CONTROL_HEADER_SIZE;
2275 break;
2276 default:
2277 if (fromDs && toDs)
2278 macHeaderLengthInBytes += 6;
2279 }
2280
2281 /* Prepare the ethernet header from snap header of skb data */
2282 switch(dataFrameType)
2283 {
2284 case DATA_NULL:
2285 case QOS_DATA_NULL:
2286 /* This is for only queue info fetching, EAPOL wont come as
2287 * null data so the proto is initialized as zero
2288 */
2289 proto = 0x0;
2290 break;
2291 default:
2292 {
2293 llc_snap_hdr_t *snap;
2294 /* Fetch a snap header to find protocol (for IPV4/IPV6 packets
2295 * the snap header fetching offset is same)
2296 */
2297 snap = (llc_snap_hdr_t *) (skb->data + macHeaderLengthInBytes);
2298
2299 /* prepare the ethernet header from the snap header & addresses */
2300 ehdr.h_proto = snap->protocol;
2301 memcpy(ehdr.h_dest, da, ETH_ALEN);
2302 memcpy(ehdr.h_source, sa, ETH_ALEN);
2303 }
2304 proto = ntohs(ehdr.h_proto);
2305 }
2306 unifi_trace(priv, UDBG3, "in unifi_rx protocol from snap header = 0x%x\n", proto);
2307
2308 if ((proto != ETH_P_PAE)
2309#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
2310 && (proto != ETH_P_WAI)
2311#endif
2312 ) {
2313 queue = UF_CONTROLLED_PORT_Q;
2314 } else {
2315 queue = UF_UNCONTROLLED_PORT_Q;
2316 }
2317
2318 port_action = verify_port(priv, (unsigned char*)sa, queue, interfaceTag);
2319 unifi_trace(priv, UDBG3, "in unifi_rx port action is = 0x%x & queue = %x\n", port_action, queue);
2320
2321#ifdef CSR_SUPPORT_SME
2322 /* Notify the TA module for the Rx frame for non P2PGO and AP cases*/
2323 if((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_AP) &&
2324 (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_P2PGO))
2325 {
2326 /* Remove MAC header of length(macHeaderLengthInBytes) before sampling */
2327 skb_pull(skb, macHeaderLengthInBytes);
2328 pData->os_data_ptr = skb->data;
2329 pData->data_length -= macHeaderLengthInBytes;
2330
2331 if (pData->data_length) {
2332 unifi_ta_sample(priv->card, CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_RX,
2333 &bulkdata->d[0],
2334 sa, priv->netdev[interfaceTag]->dev_addr,
2335 jiffies_to_msecs(jiffies),
2336 pkt_ind->ReceivedRate);
2337 }
2338 } else {
2339
2340 /* AP/P2PGO specific handling here */
2341 CsrWifiRouterCtrlStaInfo_t * srcStaInfo =
2342 CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,sa,interfaceTag);
2343
2344 /* Defensive check only; Source address is already checked in
2345 process_ma_packet_ind and we should have a valid source address here */
2346
2347 if(srcStaInfo == NULL) {
2348 CsrWifiMacAddress peerMacAddress;
2349 /* Unknown data PDU */
2350 memcpy(peerMacAddress.a,sa,ETH_ALEN);
2351 unifi_trace(priv, UDBG1, "%s: Unexpected frame from peer = %x:%x:%x:%x:%x:%x\n", __FUNCTION__,
2352 sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]);
2353 CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress);
2354 unifi_net_data_free(priv, &bulkdata->d[0]);
2355 func_exit();
2356 return;
2357 }
2358
2359 /* For AP GO mode, don't store the PDUs */
2360 if (port_action != CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
2361 /* Drop the packet and return */
2362 CsrWifiMacAddress peerMacAddress;
2363 memcpy(peerMacAddress.a,sa,ETH_ALEN);
2364 unifi_trace(priv, UDBG3, "%s: Port is not open: unexpected frame from peer = %x:%x:%x:%x:%x:%x\n",
2365 __FUNCTION__, sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]);
2366
2367 CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress);
2368 interfacePriv->stats.rx_dropped++;
2369 unifi_net_data_free(priv, &bulkdata->d[0]);
2370 unifi_notice(priv, "%s: Dropping packet, proto=0x%04x, %s port\n", __FUNCTION__,
2371 proto, queue ? "Controlled" : "Un-controlled");
2372 func_exit();
2373 return;
2374 }
2375
2376 /* Qos NULL/Data NULL are freed here and not processed further */
2377 if((dataFrameType == QOS_DATA_NULL) || (dataFrameType == DATA_NULL)){
2378 unifi_trace(priv, UDBG5, "%s: Null Frame Received and Freed\n", __FUNCTION__);
2379 unifi_net_data_free(priv, &bulkdata->d[0]);
2380 func_exit();
2381 return;
2382 }
2383
2384 /* Now we have done with MAC header so proceed with the real data part*/
2385 /* This function takes care of appropriate routing for AP/P2PGO case*/
2386 /* the function hadnles following things
2387 2. Routing the PDU to appropriate location
2388 3. Error case handling
2389 */
2390 if(!(uf_ap_process_data_pdu(priv, skb, &ehdr, srcStaInfo,
2391 signal,
2392 bulkdata,
2393 macHeaderLengthInBytes)))
2394 {
2395 func_exit();
2396 return;
2397 }
2398 unifi_trace(priv, UDBG5, "unifi_rx: no specific AP handling process as normal frame, MAC Header len %d\n",macHeaderLengthInBytes);
2399 /* Remove the MAC header for subsequent conversion */
2400 skb_pull(skb, macHeaderLengthInBytes);
2401 pData->os_data_ptr = skb->data;
2402 pData->data_length -= macHeaderLengthInBytes;
2403 pData->os_net_buf_ptr = (unsigned char*)skb;
2404 pData->net_buf_length = skb->len;
2405 }
2406#endif /* CSR_SUPPORT_SME */
2407
2408
2409 /* Now that the MAC header is removed, null-data frames have zero length
2410 * and can be dropped
2411 */
2412 if (pData->data_length == 0) {
2413 if (((frameControl & 0x00f0) >> 4) != QOS_DATA_NULL &&
2414 ((frameControl & 0x00f0) >> 4) != DATA_NULL) {
2415 unifi_trace(priv, UDBG1, "Zero length frame, but not null-data %04x\n", frameControl);
2416 }
2417 unifi_net_data_free(priv, &bulkdata->d[0]);
2418 func_exit();
2419 return;
2420 }
2421
2422 if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) {
2423 /* Drop the packet and return */
2424 interfacePriv->stats.rx_dropped++;
2425 unifi_net_data_free(priv, &bulkdata->d[0]);
2426 unifi_notice(priv, "%s: Dropping packet, proto=0x%04x, %s port\n",
2427 __FUNCTION__, proto, queue ? "controlled" : "uncontrolled");
2428 func_exit();
2429 return;
2430 } else if ( (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK) ||
2431 (interfacePriv->connected != UnifiConnected) ) {
2432
2433 /* Buffer the packet into the Rx queues */
2434 rx_buffered_packets_t *rx_q_item;
2435 struct list_head *rx_list;
2436
2437 rx_q_item = (rx_buffered_packets_t *)kmalloc(sizeof(rx_buffered_packets_t),
2438 GFP_KERNEL);
2439 if (rx_q_item == NULL) {
2440 unifi_error(priv, "%s: Failed to allocate %d bytes for rx packet record\n",
2441 __FUNCTION__, sizeof(rx_buffered_packets_t));
2442 interfacePriv->stats.rx_dropped++;
2443 unifi_net_data_free(priv, &bulkdata->d[0]);
2444 func_exit();
2445 return;
2446 }
2447
2448 INIT_LIST_HEAD(&rx_q_item->q);
2449 rx_q_item->bulkdata = *bulkdata;
2450 rx_q_item->skb = skb;
2451 rx_q_item->signal = *signal;
2452 memcpy(rx_q_item->sa.a, sa, ETH_ALEN);
2453 memcpy(rx_q_item->da.a, da, ETH_ALEN);
2454 unifi_trace(priv, UDBG2, "%s: Blocked skb=%p, bulkdata=%p\n",
2455 __FUNCTION__, rx_q_item->skb, &rx_q_item->bulkdata);
2456
2457 if (queue == UF_CONTROLLED_PORT_Q) {
2458 rx_list = &interfacePriv->rx_controlled_list;
2459 } else {
2460 rx_list = &interfacePriv->rx_uncontrolled_list;
2461 }
2462
2463 /* Add to tail of packets queue */
2464 down(&priv->rx_q_sem);
2465 list_add_tail(&rx_q_item->q, rx_list);
2466 up(&priv->rx_q_sem);
2467
2468 func_exit();
2469 return;
2470
2471 }
2472
2473 indicate_rx_skb(priv, interfaceTag, da, sa, skb, signal, bulkdata);
2474
2475 func_exit();
2476
2477} /* unifi_rx() */
2478
2479static void process_ma_packet_cfm(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
2480{
8c87f69a 2481 u16 interfaceTag;
635d2b00
GKH
2482 const CSR_MA_PACKET_CONFIRM *pkt_cfm = &signal->u.MaPacketConfirm;
2483 netInterface_priv_t *interfacePriv;
2484
2485 func_enter();
2486 interfaceTag = (pkt_cfm->VirtualInterfaceIdentifier & 0xff);
2487 interfacePriv = priv->interfacePriv[interfaceTag];
2488
2489 /* Sanity check that the VIF refers to a sensible interface */
2490 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
2491 {
2492 unifi_error(priv, "%s: MA-PACKET confirm with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
2493 func_exit();
2494 return;
2495 }
2496#ifdef CSR_SUPPORT_SME
2497 if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
2498 interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
2499
2500 uf_process_ma_pkt_cfm_for_ap(priv,interfaceTag,pkt_cfm);
2501 } else if (interfacePriv->m4_sent && (pkt_cfm->HostTag == interfacePriv->m4_hostTag)) {
2502 /* Check if this is a confirm for EAPOL M4 frame and we need to send transmistted ind*/
2503 CsrResult result = pkt_cfm->TransmissionStatus == CSR_TX_SUCCESSFUL?CSR_RESULT_SUCCESS:CSR_RESULT_FAILURE;
2504 CsrWifiMacAddress peerMacAddress;
2505 memcpy(peerMacAddress.a, interfacePriv->m4_signal.u.MaPacketRequest.Ra.x, ETH_ALEN);
2506
2507 unifi_trace(priv, UDBG1, "%s: Sending M4 Transmit CFM\n", __FUNCTION__);
2508 CsrWifiRouterCtrlM4TransmittedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0,
2509 interfaceTag,
2510 peerMacAddress,
2511 result);
2512 interfacePriv->m4_sent = FALSE;
2513 interfacePriv->m4_hostTag = 0xffffffff;
2514 }
2515#endif
2516 func_exit();
2517 return;
2518}
2519
2520
2521/*
2522 * ---------------------------------------------------------------------------
2523 * unifi_rx
2524 *
2525 * Reformat a UniFi data received packet into a p80211 packet and
2526 * pass it up the protocol stack.
2527 *
2528 * Arguments:
2529 * None.
2530 *
2531 * Returns:
2532 * None.
2533 * ---------------------------------------------------------------------------
2534 */
2535static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
2536{
8c87f69a 2537 u16 interfaceTag;
635d2b00
GKH
2538 bulk_data_desc_t *pData;
2539 CSR_MA_PACKET_INDICATION *pkt_ind = (CSR_MA_PACKET_INDICATION*)&signal->u.MaPacketIndication;
2540 struct sk_buff *skb;
8c87f69a 2541 u16 frameControl;
635d2b00 2542 netInterface_priv_t *interfacePriv;
7e6f5794
GKH
2543 u8 da[ETH_ALEN], sa[ETH_ALEN];
2544 u8 *bssid = NULL, *ba_addr = NULL;
2545 u8 toDs, fromDs, frameType;
2546 u8 i =0;
635d2b00
GKH
2547
2548#ifdef CSR_SUPPORT_SME
7e6f5794 2549 u8 dataFrameType = 0;
5379b13d 2550 u8 powerSaveChanged = FALSE;
7e6f5794 2551 u8 pmBit = 0;
635d2b00 2552 CsrWifiRouterCtrlStaInfo_t *srcStaInfo = NULL;
8c87f69a 2553 u16 qosControl;
635d2b00
GKH
2554
2555#endif
2556
2557 func_enter();
2558
2559 interfaceTag = (pkt_ind->VirtualInterfaceIdentifier & 0xff);
2560 interfacePriv = priv->interfacePriv[interfaceTag];
2561
2562
2563 /* Sanity check that the VIF refers to a sensible interface */
2564 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
2565 {
2566 unifi_error(priv, "%s: MA-PACKET indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
2567 unifi_net_data_free(priv,&bulkdata->d[0]);
2568 func_exit();
2569 return;
2570 }
2571
2572 /* Sanity check that the VIF refers to an allocated netdev */
2573 if (!interfacePriv->netdev_registered)
2574 {
2575 unifi_error(priv, "%s: MA-PACKET indication with unallocated interfaceTag %d\n", __FUNCTION__, interfaceTag);
2576 unifi_net_data_free(priv, &bulkdata->d[0]);
2577 func_exit();
2578 return;
2579 }
2580
2581 if (bulkdata->d[0].data_length == 0) {
2582 unifi_warning(priv, "%s: MA-PACKET indication with zero bulk data\n", __FUNCTION__);
2583 unifi_net_data_free(priv,&bulkdata->d[0]);
2584 func_exit();
2585 return;
2586 }
2587 /* For monitor mode we need to pass this indication to the registered application
2588 handle this seperately*/
2589 /* MIC failure is already taken care of so no need to send the PDUs which are not successfully received in non-monitor mode*/
2590 if(pkt_ind->ReceptionStatus != CSR_RX_SUCCESS)
2591 {
2592 unifi_warning(priv, "%s: MA-PACKET indication with status = %d\n",__FUNCTION__, pkt_ind->ReceptionStatus);
2593 unifi_net_data_free(priv,&bulkdata->d[0]);
2594 func_exit();
2595 return;
2596 }
2597
2598
2599 skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
2600 skb->len = bulkdata->d[0].data_length;
2601
2602 /* Point to the addresses */
2603 toDs = (skb->data[1] & 0x01) ? 1 : 0;
2604 fromDs = (skb->data[1] & 0x02) ? 1 : 0;
2605
2606 memcpy(da,(skb->data+4+toDs*12),ETH_ALEN);/* Address1 or 3 */
2607 memcpy(sa,(skb->data+10+fromDs*(6+toDs*8)),ETH_ALEN); /* Address2, 3 or 4 */
2608
2609 /* Find the BSSID, which will be used to match the BA session */
2610 if (toDs && fromDs)
2611 {
2612 unifi_trace(priv, UDBG6, "4 address frame - don't try to find BSSID\n");
2613 bssid = NULL;
2614 }
2615 else
2616 {
7e6f5794 2617 bssid = (u8 *) (skb->data + 4 + 12 - (fromDs * 6) - (toDs * 12));
635d2b00
GKH
2618 }
2619
2620 pData = &bulkdata->d[0];
2621 frameControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr);
2622 frameType = ((frameControl & 0x000C) >> 2);
2623
2624 unifi_trace(priv, UDBG3, "Rx Frame Type: %d sn: %d\n",frameType,
8c87f69a 2625 (le16_to_cpu(*((u16*)(bulkdata->d[0].os_data_ptr + IEEE802_11_SEQUENCE_CONTROL_OFFSET))) >> 4) & 0xfff);
635d2b00
GKH
2626 if(frameType == IEEE802_11_FRAMETYPE_CONTROL){
2627#ifdef CSR_SUPPORT_SME
2628 unifi_trace(priv, UDBG6, "%s: Received Control Frame\n", __FUNCTION__);
2629
2630 if((frameControl & 0x00f0) == 0x00A0){
2631 /* This is a PS-POLL request */
7e6f5794 2632 u8 pmBit = (frameControl & 0x1000)?0x01:0x00;
635d2b00
GKH
2633 unifi_trace(priv, UDBG6, "%s: Received PS-POLL Frame\n", __FUNCTION__);
2634
2635 uf_process_ps_poll(priv,sa,da,pmBit,interfaceTag);
2636 }
2637 else {
2638 unifi_warning(priv, "%s: Non PS-POLL control frame is received\n", __FUNCTION__);
2639 }
2640#endif
2641 unifi_net_data_free(priv,&bulkdata->d[0]);
2642 func_exit();
2643 return;
2644 }
2645 if(frameType != IEEE802_11_FRAMETYPE_DATA) {
2646 unifi_warning(priv, "%s: Non control Non Data frame is received\n",__FUNCTION__);
2647 unifi_net_data_free(priv,&bulkdata->d[0]);
2648 func_exit();
2649 return;
2650 }
2651
2652#ifdef CSR_SUPPORT_SME
2653 if((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP) ||
2654 (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO)){
2655
2656 srcStaInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,sa,interfaceTag);
2657
2658 if(srcStaInfo == NULL) {
2659 CsrWifiMacAddress peerMacAddress;
2660 /* Unknown data PDU */
2661 memcpy(peerMacAddress.a,sa,ETH_ALEN);
2662 unifi_trace(priv, UDBG1, "%s: Unexpected frame from peer = %x:%x:%x:%x:%x:%x\n", __FUNCTION__,
2663 sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]);
2664 CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress);
2665 unifi_net_data_free(priv, &bulkdata->d[0]);
2666 func_exit();
2667 return;
2668 }
2669
2670 /*
2671 verify power management bit here so as to ensure host and unifi are always
2672 in sync with power management status of peer.
2673
2674 If we do it later, it may so happen we have stored the frame in BA re-ordering
2675 buffer and hence host and unifi are out of sync for power management status
2676 */
2677
2678 pmBit = (frameControl & 0x1000)?0x01:0x00;
2679 powerSaveChanged = uf_process_pm_bit_for_peer(priv,srcStaInfo,pmBit,interfaceTag);
2680
2681 /* Update station last activity time */
2682 srcStaInfo->activity_flag = TRUE;
2683
2684 /* For Qos Frame if PM bit is toggled to indicate the change in power save state then it shall not be
2685 considered as Trigger Frame. Enter only if WMM STA and peer is in Power save */
2686
2687 dataFrameType = ((frameControl & 0x00f0) >> 4);
2688
2689 if((powerSaveChanged == FALSE)&&(srcStaInfo->wmmOrQosEnabled == TRUE)&&
2690 (srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)){
2691
2692 if((dataFrameType == QOS_DATA) || (dataFrameType == QOS_DATA_NULL)){
2693
2694 /*
95edd09e
GKH
2695 * QoS control field is offset from frame control by 2 (frame control)
2696 * + 2 (duration/ID) + 2 (sequence control) + 3*ETH_ALEN or 4*ETH_ALEN
2697 */
635d2b00
GKH
2698 if((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)){
2699 qosControl= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr + 30);
2700 }
2701 else{
2702 qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr + 24);
2703 }
95edd09e
GKH
2704 unifi_trace(priv, UDBG5, "%s: Check if U-APSD operations are triggered for qosControl: 0x%x\n",__FUNCTION__,qosControl);
2705 uf_process_wmm_deliver_ac_uapsd(priv,srcStaInfo,qosControl,interfaceTag);
635d2b00
GKH
2706 }
2707 }
2708 }
2709
2710#endif
2711
2712 if( ((frameControl & 0x00f0) >> 4) == QOS_DATA) {
7e6f5794 2713 u8 *qos_control_ptr = (u8*)bulkdata->d[0].os_data_ptr + (((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK))?30: 24);
635d2b00
GKH
2714 int tID = *qos_control_ptr & IEEE802_11_QC_TID_MASK; /* using ls octet of qos control */
2715 ba_session_rx_struct *ba_session;
7e6f5794 2716 u8 ba_session_idx = 0;
635d2b00
GKH
2717 /* Get the BA originator address */
2718 if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
2719 interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO){
2720 ba_addr = sa;
2721 }else{
2722 ba_addr = bssid;
2723 }
2724
95edd09e 2725 down(&priv->ba_mutex);
635d2b00
GKH
2726 for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
2727 ba_session = interfacePriv->ba_session_rx[ba_session_idx];
2728 if (ba_session){
2729 unifi_trace(priv, UDBG6, "found ba_session=0x%x ba_session_idx=%d", ba_session, ba_session_idx);
2730 if ((!memcmp(ba_session->macAddress.a, ba_addr, ETH_ALEN)) && (ba_session->tID == tID)){
2731 frame_desc_struct frame_desc;
2732 frame_desc.bulkdata = *bulkdata;
2733 frame_desc.signal = *signal;
8c87f69a 2734 frame_desc.sn = (le16_to_cpu(*((u16*)(bulkdata->d[0].os_data_ptr + IEEE802_11_SEQUENCE_CONTROL_OFFSET))) >> 4) & 0xfff;
635d2b00
GKH
2735 frame_desc.active = TRUE;
2736 unifi_trace(priv, UDBG6, "%s: calling process_ba_frame (session=%d)\n", __FUNCTION__, ba_session_idx);
2737 process_ba_frame(priv, interfacePriv, ba_session, &frame_desc);
95edd09e 2738 up(&priv->ba_mutex);
635d2b00
GKH
2739 process_ba_complete(priv, interfacePriv);
2740 break;
2741 }
2742 }
2743 }
2744 if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX){
95edd09e 2745 up(&priv->ba_mutex);
635d2b00
GKH
2746 unifi_trace(priv, UDBG6, "%s: calling process_amsdu()", __FUNCTION__);
2747 process_amsdu(priv, signal, bulkdata);
2748 }
2749 } else {
2750 unifi_trace(priv, UDBG6, "calling unifi_rx()");
2751 unifi_rx(priv, signal, bulkdata);
2752 }
2753
2754 /* check if the frames in reorder buffer has aged, the check
2755 * is done after receive processing so that if the missing frame
2756 * has arrived in this receive process, then it is handled cleanly.
2757 *
2758 * And also this code here takes care that timeout check is made for all
2759 * the receive indications
2760 */
95edd09e 2761 down(&priv->ba_mutex);
635d2b00
GKH
2762 for (i=0; i < MAX_SUPPORTED_BA_SESSIONS_RX; i++){
2763 ba_session_rx_struct *ba_session;
2764 ba_session = interfacePriv->ba_session_rx[i];
2765 if (ba_session){
2766 check_ba_frame_age_timeout(priv, interfacePriv, ba_session);
2767 }
2768 }
95edd09e 2769 up(&priv->ba_mutex);
635d2b00 2770 process_ba_complete(priv, interfacePriv);
635d2b00
GKH
2771
2772 func_exit();
2773}
2774/*
2775 * ---------------------------------------------------------------------------
2776 * uf_set_multicast_list
2777 *
2778 * This function is called by the higher level stack to set
2779 * a list of multicast rx addresses.
2780 *
2781 * Arguments:
2782 * dev Network Device pointer.
2783 *
2784 * Returns:
2785 * None.
2786 *
2787 * Notes:
2788 * ---------------------------------------------------------------------------
2789 */
2790
2791static void
2792uf_set_multicast_list(struct net_device *dev)
2793{
2794 netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
2795 unifi_priv_t *priv = interfacePriv->privPtr;
2796
2797#ifdef CSR_NATIVE_LINUX
2798 unifi_trace(priv, UDBG3, "uf_set_multicast_list unsupported\n");
2799 return;
2800#else
2801
2802 u8 *mc_list = interfacePriv->mc_list;
635d2b00
GKH
2803 struct netdev_hw_addr *mc_addr;
2804 int mc_addr_count;
635d2b00
GKH
2805
2806 if (priv->init_progress != UNIFI_INIT_COMPLETED) {
2807 return;
2808 }
2809
635d2b00
GKH
2810 mc_addr_count = netdev_mc_count(dev);
2811
2812 unifi_trace(priv, UDBG3,
2813 "uf_set_multicast_list (count=%d)\n", mc_addr_count);
2814
2815
2816 /* Not enough space? */
2817 if (mc_addr_count > UNIFI_MAX_MULTICAST_ADDRESSES) {
2818 return;
2819 }
2820
2821 /* Store the list to be processed by the work item. */
2822 interfacePriv->mc_list_count = mc_addr_count;
2823 netdev_hw_addr_list_for_each(mc_addr, &dev->mc) {
2824 memcpy(mc_list, mc_addr->addr, ETH_ALEN);
2825 mc_list += ETH_ALEN;
2826 }
2827
635d2b00
GKH
2828 /* Send a message to the workqueue */
2829 queue_work(priv->unifi_workqueue, &priv->multicast_list_task);
2830#endif
2831
2832} /* uf_set_multicast_list() */
2833
2834/*
2835 * ---------------------------------------------------------------------------
2836 * netdev_mlme_event_handler
2837 *
2838 * Callback function to be used as the udi_event_callback when registering
2839 * as a netdev client.
2840 * To use it, a client specifies this function as the udi_event_callback
2841 * to ul_register_client(). The signal dispatcher in
2842 * unifi_receive_event() will call this function to deliver a signal.
2843 *
2844 * Arguments:
2845 * pcli Pointer to the client instance.
2846 * signal Pointer to the received signal.
2847 * signal_len Size of the signal structure in bytes.
2848 * bulkdata Pointer to structure containing any associated bulk data.
2849 * dir Direction of the signal. Zero means from host,
2850 * non-zero means to host.
2851 *
2852 * Returns:
2853 * None.
2854 * ---------------------------------------------------------------------------
2855 */
2856static void
2857netdev_mlme_event_handler(ul_client_t *pcli, const u8 *sig_packed, int sig_len,
2858 const bulk_data_param_t *bulkdata_o, int dir)
2859{
2860 CSR_SIGNAL signal;
2861 unifi_priv_t *priv = uf_find_instance(pcli->instance);
2862 int id, r;
2863 bulk_data_param_t bulkdata;
2864
2865 func_enter();
2866
2867 /* Just a sanity check */
2868 if (sig_packed == NULL) {
2869 return;
2870 }
2871
2872 /*
2873 * This copy is to silence a compiler warning about discarding the
2874 * const qualifier.
2875 */
2876 bulkdata = *bulkdata_o;
2877
2878 /* Get the unpacked signal */
2879 r = read_unpack_signal(sig_packed, &signal);
2880 if (r) {
2881 /*
2882 * The CSR_MLME_CONNECTED_INDICATION_ID has a receiverID=0 so will
2883 * fall through this case. It is safe to ignore this signal.
2884 */
2885 unifi_trace(priv, UDBG1,
2886 "Netdev - Received unknown signal 0x%.4X.\n",
2887 CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sig_packed));
2888 return;
2889 }
2890
2891 id = signal.SignalPrimitiveHeader.SignalId;
2892 unifi_trace(priv, UDBG3, "Netdev - Process signal 0x%.4X\n", id);
2893
2894 /*
2895 * Take the appropriate action for the signal.
2896 */
2897 switch (id) {
2898 case CSR_MA_PACKET_ERROR_INDICATION_ID:
2899 process_ma_packet_error_ind(priv, &signal, &bulkdata);
2900 break;
2901 case CSR_MA_PACKET_INDICATION_ID:
2902 process_ma_packet_ind(priv, &signal, &bulkdata);
2903 break;
2904 case CSR_MA_PACKET_CONFIRM_ID:
2905 process_ma_packet_cfm(priv, &signal, &bulkdata);
2906 break;
2907#ifdef CSR_SUPPORT_SME
2908 case CSR_MLME_SET_TIM_CONFIRM_ID:
2909 /* Handle TIM confirms from FW & set the station record's TIM state appropriately,
2910 * In case of failures, tries with max_retransmit limit
2911 */
2912 uf_handle_tim_cfm(priv, &signal.u.MlmeSetTimConfirm, signal.SignalPrimitiveHeader.ReceiverProcessId);
2913 break;
2914#endif
2915 case CSR_DEBUG_STRING_INDICATION_ID:
2916 debug_string_indication(priv, bulkdata.d[0].os_data_ptr, bulkdata.d[0].data_length);
2917 break;
2918
2919 case CSR_DEBUG_WORD16_INDICATION_ID:
2920 debug_word16_indication(priv, &signal);
2921 break;
2922
2923 case CSR_DEBUG_GENERIC_CONFIRM_ID:
2924 case CSR_DEBUG_GENERIC_INDICATION_ID:
2925 debug_generic_indication(priv, &signal);
2926 break;
2927 default:
2928 break;
2929 }
2930
2931 func_exit();
2932} /* netdev_mlme_event_handler() */
2933
2934
2935/*
2936 * ---------------------------------------------------------------------------
2937 * uf_net_get_name
2938 *
2939 * Retrieve the name (e.g. eth1) associated with this network device
2940 *
2941 * Arguments:
2942 * dev Pointer to the network device.
2943 * name Buffer to write name
2944 * len Size of buffer in bytes
2945 *
2946 * Returns:
2947 * None
2948 *
2949 * Notes:
2950 * ---------------------------------------------------------------------------
2951 */
2952void uf_net_get_name(struct net_device *dev, char *name, int len)
2953{
2954 *name = '\0';
2955 if (dev) {
2956 strlcpy(name, dev->name, (len > IFNAMSIZ) ? IFNAMSIZ : len);
2957 }
2958
2959} /* uf_net_get_name */
2960
635d2b00
GKH
2961#ifdef CSR_SUPPORT_WEXT
2962
2963/*
2964 * ---------------------------------------------------------------------------
2965 * uf_netdev_event
2966 *
2967 * Callback function to handle netdev state changes
2968 *
2969 * Arguments:
2970 * notif Pointer to a notifier_block.
2971 * event Event prompting notification
2972 * ptr net_device pointer
2973 *
2974 * Returns:
2975 * None
2976 *
2977 * Notes:
2978 * The event handler is global, and may occur on non-UniFi netdevs.
2979 * ---------------------------------------------------------------------------
2980 */
2981static int
2982uf_netdev_event(struct notifier_block *notif, unsigned long event, void* ptr) {
2983 struct net_device *netdev = ptr;
2984 netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(netdev);
2985 unifi_priv_t *priv = NULL;
2986 static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
2987
2988 /* Check that the event is for a UniFi netdev. If it's not, the netdev_priv
2989 * structure is not safe to use.
2990 */
2991 if (uf_find_netdev_priv(interfacePriv) == -1) {
2992 unifi_trace(NULL, UDBG1, "uf_netdev_event: ignore e=%d, ptr=%p, priv=%p %s\n",
2993 event, ptr, interfacePriv, netdev->name);
2994 return 0;
2995 }
2996
2997 switch(event) {
2998 case NETDEV_CHANGE:
2999 priv = interfacePriv->privPtr;
3000 unifi_trace(priv, UDBG1, "NETDEV_CHANGE: %p %s %s waiting for it\n",
3001 ptr,
3002 netdev->name,
3003 interfacePriv->wait_netdev_change ? "" : "not");
3004
3005 if (interfacePriv->wait_netdev_change) {
3006 UF_NETIF_TX_WAKE_ALL_QUEUES(priv->netdev[interfacePriv->InterfaceTag]);
3007 interfacePriv->connected = UnifiConnected;
3008 interfacePriv->wait_netdev_change = FALSE;
3009 /* Note: passing the broadcast address here will allow anyone to attempt to join our adhoc network */
3010 uf_process_rx_pending_queue(priv, UF_UNCONTROLLED_PORT_Q, broadcast_address, 1,interfacePriv->InterfaceTag);
3011 uf_process_rx_pending_queue(priv, UF_CONTROLLED_PORT_Q, broadcast_address, 1,interfacePriv->InterfaceTag);
3012 }
3013 break;
3014
3015 default:
3016 break;
3017 }
3018 return 0;
3019}
3020
3021static struct notifier_block uf_netdev_notifier = {
3022 .notifier_call = uf_netdev_event,
3023};
3024#endif /* CSR_SUPPORT_WEXT */
3025
3026
3027static void
3028 process_amsdu(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
3029{
26a6b2e1
GKH
3030 u32 offset;
3031 u32 length = bulkdata->d[0].data_length;
3032 u32 subframe_length, subframe_body_length, dot11_hdr_size;
7e6f5794 3033 u8 *ptr;
635d2b00 3034 bulk_data_param_t subframe_bulkdata;
7e6f5794 3035 u8 *dot11_hdr_ptr = (u8*)bulkdata->d[0].os_data_ptr;
635d2b00 3036 CsrResult csrResult;
8c87f69a 3037 u16 frameControl;
7e6f5794 3038 u8 *qos_control_ptr;
635d2b00 3039
8c87f69a 3040 frameControl = le16_to_cpu(*((u16*)dot11_hdr_ptr));
635d2b00
GKH
3041 qos_control_ptr = dot11_hdr_ptr + (((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK))?30: 24);
3042 if(!(*qos_control_ptr & IEEE802_11_QC_A_MSDU_PRESENT)) {
3043 unifi_trace(priv, UDBG6, "%s: calling unifi_rx()", __FUNCTION__);
3044 unifi_rx(priv, signal, bulkdata);
3045 return;
3046 }
3047 *qos_control_ptr &= ~(IEEE802_11_QC_A_MSDU_PRESENT);
3048
3049 ptr = qos_control_ptr + 2;
3050 offset = dot11_hdr_size = ptr - dot11_hdr_ptr;
3051
3052 while(length > (offset + sizeof(struct ethhdr) + sizeof(llc_snap_hdr_t))) {
3053 subframe_body_length = ntohs(((struct ethhdr*)ptr)->h_proto);
3054 if(subframe_body_length > IEEE802_11_MAX_DATA_LEN) {
3055 unifi_error(priv, "%s: bad subframe_body_length = %d\n", __FUNCTION__, subframe_body_length);
3056 break;
3057 }
3058 subframe_length = sizeof(struct ethhdr) + subframe_body_length;
3059 memset(&subframe_bulkdata, 0, sizeof(bulk_data_param_t));
3060
3061 csrResult = unifi_net_data_malloc(priv, &subframe_bulkdata.d[0], dot11_hdr_size + subframe_body_length);
3062
3063 if (csrResult != CSR_RESULT_SUCCESS) {
3064 unifi_error(priv, "%s: unifi_net_data_malloc failed\n", __FUNCTION__);
3065 break;
3066 }
3067
7e6f5794 3068 memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr, dot11_hdr_ptr, dot11_hdr_size);
635d2b00
GKH
3069
3070
3071 /* When to DS=0 and from DS=0, address 3 will already have BSSID so no need to re-program */
3072 if ((frameControl & IEEE802_11_FC_TO_DS_MASK) && !(frameControl & IEEE802_11_FC_FROM_DS_MASK)){
7e6f5794 3073 memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr + IEEE802_11_ADDR3_OFFSET, ((struct ethhdr*)ptr)->h_dest, ETH_ALEN);
635d2b00
GKH
3074 }
3075 else if (!(frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)){
7e6f5794 3076 memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr + IEEE802_11_ADDR3_OFFSET,
635d2b00
GKH
3077 ((struct ethhdr*)ptr)->h_source,
3078 ETH_ALEN);
3079 }
3080
7e6f5794 3081 memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr + dot11_hdr_size,
635d2b00
GKH
3082 ptr + sizeof(struct ethhdr),
3083 subframe_body_length);
3084 unifi_trace(priv, UDBG6, "%s: calling unifi_rx. length = %d subframe_length = %d\n", __FUNCTION__, length, subframe_length);
3085 unifi_rx(priv, signal, &subframe_bulkdata);
3086
3087 subframe_length = (subframe_length + 3)&(~0x3);
3088 ptr += subframe_length;
3089 offset += subframe_length;
3090 }
3091 unifi_net_data_free(priv, &bulkdata->d[0]);
3092}
3093
3094
3095#define SN_TO_INDEX(__ba_session, __sn) (((__sn - __ba_session->start_sn) & 0xFFF) % __ba_session->wind_size)
3096
3097
3098#define ADVANCE_EXPECTED_SN(__ba_session) \
3099{ \
3100 __ba_session->expected_sn++; \
3101 __ba_session->expected_sn &= 0xFFF; \
3102}
3103
3104#define FREE_BUFFER_SLOT(__ba_session, __index) \
3105{ \
3106 __ba_session->occupied_slots--; \
3107 __ba_session->buffer[__index].active = FALSE; \
3108 ADVANCE_EXPECTED_SN(__ba_session); \
3109}
3110
3111static void add_frame_to_ba_complete(unifi_priv_t *priv,
3112 netInterface_priv_t *interfacePriv,
3113 frame_desc_struct *frame_desc)
3114{
3115 interfacePriv->ba_complete[interfacePriv->ba_complete_index] = *frame_desc;
3116 interfacePriv->ba_complete_index++;
3117}
3118
3119
3120static void update_expected_sn(unifi_priv_t *priv,
3121 netInterface_priv_t *interfacePriv,
3122 ba_session_rx_struct *ba_session,
8c87f69a 3123 u16 sn)
635d2b00
GKH
3124{
3125 int i, j;
8c87f69a 3126 u16 gap;
635d2b00
GKH
3127
3128 gap = (sn - ba_session->expected_sn) & 0xFFF;
3129 unifi_trace(priv, UDBG6, "%s: proccess the frames up to new_expected_sn = %d gap = %d\n", __FUNCTION__, sn, gap);
3130 for(j = 0; j < gap && j < ba_session->wind_size; j++) {
3131 i = SN_TO_INDEX(ba_session, ba_session->expected_sn);
3132 unifi_trace(priv, UDBG6, "%s: proccess the slot index = %d\n", __FUNCTION__, i);
3133 if(ba_session->buffer[i].active) {
3134 add_frame_to_ba_complete(priv, interfacePriv, &ba_session->buffer[i]);
3135 unifi_trace(priv, UDBG6, "%s: proccess the frame at index = %d expected_sn = %d\n", __FUNCTION__, i, ba_session->expected_sn);
3136 FREE_BUFFER_SLOT(ba_session, i);
3137 } else {
3138 unifi_trace(priv, UDBG6, "%s: empty slot at index = %d\n", __FUNCTION__, i);
3139 ADVANCE_EXPECTED_SN(ba_session);
3140 }
3141 }
3142 ba_session->expected_sn = sn;
3143}
3144
3145
3146static void complete_ready_sequence(unifi_priv_t *priv,
3147 netInterface_priv_t *interfacePriv,
3148 ba_session_rx_struct *ba_session)
3149{
3150 int i;
3151
3152 i = SN_TO_INDEX(ba_session, ba_session->expected_sn);
3153 while (ba_session->buffer[i].active) {
3154 add_frame_to_ba_complete(priv, interfacePriv, &ba_session->buffer[i]);
3155 unifi_trace(priv, UDBG6, "%s: completed stored frame(expected_sn=%d) at i = %d\n", __FUNCTION__, ba_session->expected_sn, i);
3156 FREE_BUFFER_SLOT(ba_session, i);
3157 i = SN_TO_INDEX(ba_session, ba_session->expected_sn);
3158 }
3159}
3160
3161
3162void scroll_ba_window(unifi_priv_t *priv,
3163 netInterface_priv_t *interfacePriv,
3164 ba_session_rx_struct *ba_session,
8c87f69a 3165 u16 sn)
635d2b00
GKH
3166{
3167 if(((sn - ba_session->expected_sn) & 0xFFF) <= 2048) {
3168 update_expected_sn(priv, interfacePriv, ba_session, sn);
3169 complete_ready_sequence(priv, interfacePriv, ba_session);
3170 }
3171}
3172
3173
3174static int consume_frame_or_get_buffer_index(unifi_priv_t *priv,
3175 netInterface_priv_t *interfacePriv,
3176 ba_session_rx_struct *ba_session,
8c87f69a 3177 u16 sn,
635d2b00
GKH
3178 frame_desc_struct *frame_desc) {
3179 int i;
8c87f69a 3180 u16 sn_temp;
635d2b00
GKH
3181
3182 if(((sn - ba_session->expected_sn) & 0xFFF) <= 2048) {
3183
3184 /* once we are in BA window, set the flag for BA trigger */
3185 if(!ba_session->trigger_ba_after_ssn){
3186 ba_session->trigger_ba_after_ssn = TRUE;
3187 }
3188
3189 sn_temp = ba_session->expected_sn + ba_session->wind_size;
3190 unifi_trace(priv, UDBG6, "%s: new frame: sn=%d\n", __FUNCTION__, sn);
3191 if(!(((sn - sn_temp) & 0xFFF) > 2048)) {
8c87f69a 3192 u16 new_expected_sn;
635d2b00
GKH
3193 unifi_trace(priv, UDBG6, "%s: frame is out of window\n", __FUNCTION__);
3194 sn_temp = (sn - ba_session->wind_size) & 0xFFF;
3195 new_expected_sn = (sn_temp + 1) & 0xFFF;
3196 update_expected_sn(priv, interfacePriv, ba_session, new_expected_sn);
3197 }
3198 i = -1;
3199 if (sn == ba_session->expected_sn) {
3200 unifi_trace(priv, UDBG6, "%s: sn = ba_session->expected_sn = %d\n", __FUNCTION__, sn);
3201 ADVANCE_EXPECTED_SN(ba_session);
3202 add_frame_to_ba_complete(priv, interfacePriv, frame_desc);
3203 } else {
3204 i = SN_TO_INDEX(ba_session, sn);
3205 unifi_trace(priv, UDBG6, "%s: sn(%d) != ba_session->expected_sn(%d), i = %d\n", __FUNCTION__, sn, ba_session->expected_sn, i);
3206 if (ba_session->buffer[i].active) {
3207 unifi_trace(priv, UDBG6, "%s: free frame at i = %d\n", __FUNCTION__, i);
3208 i = -1;
3209 unifi_net_data_free(priv, &frame_desc->bulkdata.d[0]);
3210 }
3211 }
3212 } else {
3213 i = -1;
3214 if(!ba_session->trigger_ba_after_ssn){
3215 unifi_trace(priv, UDBG6, "%s: frame before ssn, pass it up: sn=%d\n", __FUNCTION__, sn);
3216 add_frame_to_ba_complete(priv, interfacePriv, frame_desc);
3217 }else{
3218 unifi_trace(priv, UDBG6, "%s: old frame, drop: sn=%d, expected_sn=%d\n", __FUNCTION__, sn, ba_session->expected_sn);
3219 unifi_net_data_free(priv, &frame_desc->bulkdata.d[0]);
3220 }
3221 }
3222 return i;
3223}
3224
3225
3226
3227static void process_ba_frame(unifi_priv_t *priv,
3228 netInterface_priv_t *interfacePriv,
3229 ba_session_rx_struct *ba_session,
3230 frame_desc_struct *frame_desc)
3231{
3232 int i;
8c87f69a 3233 u16 sn = frame_desc->sn;
635d2b00
GKH
3234
3235 if (ba_session->timeout) {
3236 mod_timer(&ba_session->timer, (jiffies + usecs_to_jiffies((ba_session->timeout) * 1024)));
3237 }
3238 unifi_trace(priv, UDBG6, "%s: got frame(sn=%d)\n", __FUNCTION__, sn);
3239
3240 i = consume_frame_or_get_buffer_index(priv, interfacePriv, ba_session, sn, frame_desc);
3241 if(i >= 0) {
3242 unifi_trace(priv, UDBG6, "%s: store frame(sn=%d) at i = %d\n", __FUNCTION__, sn, i);
3243 ba_session->buffer[i] = *frame_desc;
3244 ba_session->buffer[i].recv_time = CsrTimeGet(NULL);
3245 ba_session->occupied_slots++;
3246 } else {
3247 unifi_trace(priv, UDBG6, "%s: frame consumed - sn = %d\n", __FUNCTION__, sn);
3248 }
3249 complete_ready_sequence(priv, interfacePriv, ba_session);
3250}
3251
3252
3253static void process_ba_complete(unifi_priv_t *priv, netInterface_priv_t *interfacePriv)
3254{
3255 frame_desc_struct *frame_desc;
7e6f5794 3256 u8 i;
635d2b00
GKH
3257
3258 for(i = 0; i < interfacePriv->ba_complete_index; i++) {
3259 frame_desc = &interfacePriv->ba_complete[i];
3260 unifi_trace(priv, UDBG6, "%s: calling process_amsdu()\n", __FUNCTION__);
3261 process_amsdu(priv, &frame_desc->signal, &frame_desc->bulkdata);
3262 }
3263 interfacePriv->ba_complete_index = 0;
3264
3265}
3266
3267
3268/* Check if the frames in BA reoder buffer has aged and
3269 * if so release the frames to upper processes and move
3270 * the window
3271 */
3272static void check_ba_frame_age_timeout( unifi_priv_t *priv,
3273 netInterface_priv_t *interfacePriv,
3274 ba_session_rx_struct *ba_session)
3275{
3276 CsrTime now;
3277 CsrTime age;
7e6f5794 3278 u8 i, j;
8c87f69a 3279 u16 sn_temp;
635d2b00
GKH
3280
3281 /* gap is started at 1 because we have buffered frames and
3282 * hence a minimum gap of 1 exists
3283 */
7e6f5794 3284 u8 gap=1;
635d2b00
GKH
3285
3286 now = CsrTimeGet(NULL);
3287
3288 if (ba_session->occupied_slots)
3289 {
3290 /* expected sequence has not arrived so start searching from next
3291 * sequence number until a frame is available and determine the gap.
3292 * Check if the frame available has timedout, if so advance the
3293 * expected sequence number and release the frames
3294 */
3295 sn_temp = (ba_session->expected_sn + 1) & 0xFFF;
3296
3297 for(j = 0; j < ba_session->wind_size; j++)
3298 {
3299 i = SN_TO_INDEX(ba_session, sn_temp);
3300
3301 if(ba_session->buffer[i].active)
3302 {
3303 unifi_trace(priv, UDBG6, "check age at slot index = %d sn = %d recv_time = %u now = %u\n",
3304 i,
3305 ba_session->buffer[i].sn,
3306 ba_session->buffer[i].recv_time,
3307 now);
3308
3309 if (ba_session->buffer[i].recv_time > now)
3310 {
3311 /* timer wrap */
3312 age = CsrTimeAdd((CsrTime)CsrTimeSub(CSR_SCHED_TIME_MAX, ba_session->buffer[i].recv_time), now);
3313 }
3314 else
3315 {
3316 age = (CsrTime)CsrTimeSub(now, ba_session->buffer[i].recv_time);
3317 }
3318
3319 if (age >= CSR_WIFI_BA_MPDU_FRAME_AGE_TIMEOUT)
3320 {
3321 unifi_trace(priv, UDBG2, "release the frame at index = %d gap = %d expected_sn = %d sn = %d\n",
3322 i,
3323 gap,
3324 ba_session->expected_sn,
3325 ba_session->buffer[i].sn);
3326
3327 /* if it has timedout don't wait for missing frames, move the window */
3328 while (gap--)
3329 {
3330 ADVANCE_EXPECTED_SN(ba_session);
3331 }
3332 add_frame_to_ba_complete(priv, interfacePriv, &ba_session->buffer[i]);
3333 FREE_BUFFER_SLOT(ba_session, i);
3334 complete_ready_sequence(priv, interfacePriv, ba_session);
3335 }
3336 break;
3337
3338 }
3339 else
3340 {
3341 /* advance temp sequence number and frame gap */
3342 sn_temp = (sn_temp + 1) & 0xFFF;
3343 gap++;
3344 }
3345 }
3346 }
3347}
3348
3349
3350static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
3351{
8c87f69a 3352 u16 interfaceTag;
635d2b00
GKH
3353 const CSR_MA_PACKET_ERROR_INDICATION *pkt_err_ind = &signal->u.MaPacketErrorIndication;
3354 netInterface_priv_t *interfacePriv;
3355 ba_session_rx_struct *ba_session;
7e6f5794 3356 u8 ba_session_idx = 0;
635d2b00
GKH
3357 CSR_PRIORITY UserPriority;
3358 CSR_SEQUENCE_NUMBER sn;
3359
3360 func_enter();
3361
3362 interfaceTag = (pkt_err_ind->VirtualInterfaceIdentifier & 0xff);
3363
3364
3365 /* Sanity check that the VIF refers to a sensible interface */
3366 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
3367 {
3368 unifi_error(priv, "%s: MaPacketErrorIndication indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
3369 func_exit();
3370 return;
3371 }
3372
3373 interfacePriv = priv->interfacePriv[interfaceTag];
3374 UserPriority = pkt_err_ind->UserPriority;
3375 if(UserPriority > 15) {
3376 unifi_error(priv, "%s: MaPacketErrorIndication indication with bad UserPriority=%d\n", __FUNCTION__, UserPriority);
3377 func_exit();
3378 }
3379 sn = pkt_err_ind->SequenceNumber;
3380
95edd09e 3381 down(&priv->ba_mutex);
635d2b00
GKH
3382 /* To find the right ba_session loop through the BA sessions, compare MAC address and tID */
3383 for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
3384 ba_session = interfacePriv->ba_session_rx[ba_session_idx];
3385 if (ba_session){
3386 if ((!memcmp(ba_session->macAddress.a, pkt_err_ind->PeerQstaAddress.x, ETH_ALEN)) && (ba_session->tID == UserPriority)){
3387 if (ba_session->timeout) {
3388 mod_timer(&ba_session->timer, (jiffies + usecs_to_jiffies((ba_session->timeout) * 1024)));
3389 }
3390 scroll_ba_window(priv, interfacePriv, ba_session, sn);
3391 break;
3392 }
3393 }
3394 }
3395
95edd09e 3396 up(&priv->ba_mutex);
635d2b00
GKH
3397 process_ba_complete(priv, interfacePriv);
3398 func_exit();
3399}
3400
3401
This page took 0.34211 seconds and 5 git commands to generate.