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