staging/csr: fix coding style problems in handle_bh_error
[deliverable/linux.git] / drivers / staging / csr / netdev.c
CommitLineData
635d2b00
GKH
1/*
2 * ---------------------------------------------------------------------------
3 * FILE: netdev.c
4 *
5 * PURPOSE:
6 * This file provides the upper edge interface to the linux netdevice
7 * and wireless extensions.
8 * It is part of the porting exercise.
9 *
10 * Copyright (C) 2005-2010 by Cambridge Silicon Radio Ltd.
11 *
12 * Refer to LICENSE.txt included with this source code for details on
13 * the license terms.
14 *
15 * ---------------------------------------------------------------------------
16 */
17
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
635d2b00
GKH
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
95edd09e 400#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_SUPPORT_SME))
635d2b00
GKH
401 priv->wapi_multicast_filter = 0;
402 priv->wapi_unicast_filter = 0;
403 priv->wapi_unicast_queued_pkt_filter = 0;
95edd09e
GKH
404#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
405 priv->isWapiConnection = FALSE;
406#endif
407#endif
635d2b00
GKH
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);
95edd09e
GKH
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
635d2b00
GKH
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);
95edd09e
GKH
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
635d2b00
GKH
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
95edd09e
GKH
520#ifdef CSR_WIFI_SPLIT_PATCH
521 /* set it to some invalid value */
522 priv->pending_mode_set.common.destination = 0xaaaa;
523#endif
524
635d2b00
GKH
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 */
5379b13d 555u8
8c87f69a 556uf_alloc_netdevice_for_other_interfaces(unifi_priv_t *priv, u16 interfaceTag)
635d2b00
GKH
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
95edd09e
GKH
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
635d2b00
GKH
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
7e6f5794 916 u8 interfaceMode = interfacePriv->interfaceMode;
635d2b00
GKH
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,
8c87f69a 1083 const s8 *oui, u16 protocol,
635d2b00
GKH
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;
7e6f5794 1091 u8 i;
635d2b00
GKH
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,
7e6f5794 1144 (u8*)bulkdata->d[0].os_data_ptr,
635d2b00
GKH
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
8c87f69a 1325static CsrWifiRouterCtrlPortAction verify_port(unifi_priv_t *priv, unsigned char *address, int queue, u16 interfaceTag)
635d2b00
GKH
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,
8c87f69a 1371 u16 interfaceTag,
7e6f5794
GKH
1372 const u8 *daddr,
1373 const u8 *saddr,
5379b13d 1374 u8 protection)
635d2b00 1375{
8c87f69a 1376 u16 fc = 0;
7e6f5794
GKH
1377 u8 qc = 0;
1378 u8 macHeaderLengthInBytes = MAC_HEADER_SIZE, *bufPtr = NULL;
635d2b00
GKH
1379 bulk_data_param_t data_ptrs;
1380 CsrResult csrResult;
1381 int headroom =0;
7e6f5794 1382 u8 direction = 0;
635d2b00 1383 netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
7e6f5794 1384 u8 *addressOne;
5379b13d 1385 u8 bQosNull = false;
635d2b00
GKH
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
7e6f5794 1481 bufPtr = (u8*)data_ptrs.d[0].os_data_ptr;
635d2b00
GKH
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 */
7e6f5794 1488 bufPtr = (u8*)skb_push(skb, macHeaderLengthInBytes);
635d2b00
GKH
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
95edd09e 1590 if (priority > 7) {
635d2b00
GKH
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;
8c87f69a 1652 u16 i;
5379b13d 1653 u8 eapolStore = FALSE;
635d2b00
GKH
1654 struct sk_buff *newSkb = NULL;
1655 bulk_data_param_t bulkdata;
1656 const int proto = ntohs(ehdr->h_proto);
8c87f69a 1657 u16 interfaceTag;
635d2b00
GKH
1658 CsrWifiMacAddress peerAddress;
1659 CSR_TRANSMISSION_CONTROL transmissionControl = CSR_NO_CONFIRM_REQUIRED;
163eb0d8 1660 s8 protection;
635d2b00 1661 netInterface_priv_t *interfacePriv = NULL;
95edd09e 1662 CSR_RATE TransmitRate = (CSR_RATE)0;
635d2b00
GKH
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 */
7e6f5794 1756 memcpy(peerAddress.a, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
635d2b00
GKH
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 */
7e6f5794 1795 memcpy(req->Ra.x, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
635d2b00
GKH
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
95edd09e
GKH
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 */
7e6f5794 1844 memcpy(req->Ra.x, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
95edd09e
GKH
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 );
635d2b00
GKH
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,
95edd09e 1881 TransmitRate,
635d2b00
GKH
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) {
95edd09e
GKH
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;
635d2b00 2004
95edd09e
GKH
2005 }
2006#else
2007 dev->trans_start = jiffies;
635d2b00
GKH
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;
95edd09e 2016#endif
635d2b00
GKH
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
8c87f69a 2153indicate_rx_skb(unifi_priv_t *priv, u16 ifTag, u8* dst_a, u8* src_a, struct sk_buff *skb, CSR_SIGNAL *signal,
635d2b00
GKH
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
95edd09e
GKH
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
635d2b00
GKH
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,
8c87f69a 2253 int indicate, u16 interfaceTag)
635d2b00
GKH
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,
8c87f69a 2328 u16 interfaceTag)
635d2b00
GKH
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
8c87f69a 2366void uf_free_pending_rx_packets(unifi_priv_t *priv, int queue, CsrWifiMacAddress peer_address,u16 interfaceTag)
635d2b00
GKH
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{
8c87f69a 2390 u16 interfaceTag;
635d2b00
GKH
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;
7e6f5794 2395 u8 dataFrameType;
635d2b00
GKH
2396 int proto;
2397 int queue;
2398
7e6f5794
GKH
2399 u8 da[ETH_ALEN], sa[ETH_ALEN];
2400 u8 toDs, fromDs, frameType, macHeaderLengthInBytes = MAC_HEADER_SIZE;
8c87f69a 2401 u16 frameControl;
635d2b00
GKH
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{
8c87f69a 2679 u16 interfaceTag;
635d2b00
GKH
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{
8c87f69a 2735 u16 interfaceTag;
635d2b00
GKH
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;
8c87f69a 2739 u16 frameControl;
635d2b00 2740 netInterface_priv_t *interfacePriv;
7e6f5794
GKH
2741 u8 da[ETH_ALEN], sa[ETH_ALEN];
2742 u8 *bssid = NULL, *ba_addr = NULL;
2743 u8 toDs, fromDs, frameType;
2744 u8 i =0;
635d2b00
GKH
2745
2746#ifdef CSR_SUPPORT_SME
7e6f5794 2747 u8 dataFrameType = 0;
5379b13d 2748 u8 powerSaveChanged = FALSE;
7e6f5794 2749 u8 pmBit = 0;
635d2b00 2750 CsrWifiRouterCtrlStaInfo_t *srcStaInfo = NULL;
8c87f69a 2751 u16 qosControl;
635d2b00
GKH
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 {
7e6f5794 2815 bssid = (u8 *) (skb->data + 4 + 12 - (fromDs * 6) - (toDs * 12));
635d2b00
GKH
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,
8c87f69a 2823 (le16_to_cpu(*((u16*)(bulkdata->d[0].os_data_ptr + IEEE802_11_SEQUENCE_CONTROL_OFFSET))) >> 4) & 0xfff);
635d2b00
GKH
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 */
7e6f5794 2830 u8 pmBit = (frameControl & 0x1000)?0x01:0x00;
635d2b00
GKH
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 /*
95edd09e
GKH
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 */
635d2b00
GKH
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 }
95edd09e
GKH
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);
635d2b00
GKH
2904 }
2905 }
2906 }
2907
2908#endif
2909
2910 if( ((frameControl & 0x00f0) >> 4) == QOS_DATA) {
7e6f5794 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);
635d2b00
GKH
2912 int tID = *qos_control_ptr & IEEE802_11_QC_TID_MASK; /* using ls octet of qos control */
2913 ba_session_rx_struct *ba_session;
7e6f5794 2914 u8 ba_session_idx = 0;
635d2b00
GKH
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
95edd09e 2923 down(&priv->ba_mutex);
635d2b00
GKH
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;
8c87f69a 2932 frame_desc.sn = (le16_to_cpu(*((u16*)(bulkdata->d[0].os_data_ptr + IEEE802_11_SEQUENCE_CONTROL_OFFSET))) >> 4) & 0xfff;
635d2b00
GKH
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);
95edd09e 2936 up(&priv->ba_mutex);
635d2b00
GKH
2937 process_ba_complete(priv, interfacePriv);
2938 break;
2939 }
2940 }
2941 }
2942 if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX){
95edd09e 2943 up(&priv->ba_mutex);
635d2b00
GKH
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 */
95edd09e 2959 down(&priv->ba_mutex);
635d2b00
GKH
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 }
95edd09e 2967 up(&priv->ba_mutex);
635d2b00 2968 process_ba_complete(priv, interfacePriv);
635d2b00
GKH
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{
26a6b2e1
GKH
3622 u32 offset;
3623 u32 length = bulkdata->d[0].data_length;
3624 u32 subframe_length, subframe_body_length, dot11_hdr_size;
7e6f5794 3625 u8 *ptr;
635d2b00 3626 bulk_data_param_t subframe_bulkdata;
7e6f5794 3627 u8 *dot11_hdr_ptr = (u8*)bulkdata->d[0].os_data_ptr;
635d2b00 3628 CsrResult csrResult;
8c87f69a 3629 u16 frameControl;
7e6f5794 3630 u8 *qos_control_ptr;
635d2b00 3631
8c87f69a 3632 frameControl = le16_to_cpu(*((u16*)dot11_hdr_ptr));
635d2b00
GKH
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
7e6f5794 3660 memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr, dot11_hdr_ptr, dot11_hdr_size);
635d2b00
GKH
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)){
7e6f5794 3665 memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr + IEEE802_11_ADDR3_OFFSET, ((struct ethhdr*)ptr)->h_dest, ETH_ALEN);
635d2b00
GKH
3666 }
3667 else if (!(frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)){
7e6f5794 3668 memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr + IEEE802_11_ADDR3_OFFSET,
635d2b00
GKH
3669 ((struct ethhdr*)ptr)->h_source,
3670 ETH_ALEN);
3671 }
3672
7e6f5794 3673 memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr + dot11_hdr_size,
635d2b00
GKH
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,
8c87f69a 3715 u16 sn)
635d2b00
GKH
3716{
3717 int i, j;
8c87f69a 3718 u16 gap;
635d2b00
GKH
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,
8c87f69a 3757 u16 sn)
635d2b00
GKH
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,
8c87f69a 3769 u16 sn,
635d2b00
GKH
3770 frame_desc_struct *frame_desc) {
3771 int i;
8c87f69a 3772 u16 sn_temp;
635d2b00
GKH
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)) {
8c87f69a 3784 u16 new_expected_sn;
635d2b00
GKH
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;
8c87f69a 3825 u16 sn = frame_desc->sn;
635d2b00
GKH
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;
7e6f5794 3848 u8 i;
635d2b00
GKH
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;
7e6f5794 3870 u8 i, j;
8c87f69a 3871 u16 sn_temp;
635d2b00
GKH
3872
3873 /* gap is started at 1 because we have buffered frames and
3874 * hence a minimum gap of 1 exists
3875 */
7e6f5794 3876 u8 gap=1;
635d2b00
GKH
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{
8c87f69a 3944 u16 interfaceTag;
635d2b00
GKH
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;
7e6f5794 3948 u8 ba_session_idx = 0;
635d2b00
GKH
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
95edd09e 3973 down(&priv->ba_mutex);
635d2b00
GKH
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
95edd09e 3988 up(&priv->ba_mutex);
635d2b00
GKH
3989 process_ba_complete(priv, interfacePriv);
3990 func_exit();
3991}
3992
3993
This page took 0.398731 seconds and 5 git commands to generate.