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

Archive Download this file



interactive