2 * ---------------------------------------------------------------------------
6 * This file provides the upper edge interface to the linux netdevice
7 * and wireless extensions.
8 * It is part of the porting exercise.
10 * Copyright (C) 2005-2010 by Cambridge Silicon Radio Ltd.
12 * Refer to LICENSE.txt included with this source code for details on
15 * ---------------------------------------------------------------------------
20 * This file implements the data plane of the UniFi linux driver.
22 * All the Tx packets are passed to the HIP core lib, using the
23 * unifi_send_signal() API. For EAPOL packets use the MLME-EAPOL.req
24 * signal, for all other use the MLME-UNITDATA.req. The unifi_send_signal()
25 * expects the wire-formatted (packed) signal. For convenience, in the OS
26 * layer we only use the native (unpacked) signal structures. The HIP core lib
27 * provides the write_pack() helper function to convert to the packed signal.
28 * The packet is stored in the bulk data of the signal. We do not need to
29 * allocate new memory to store the packet, because unifi_net_data_malloc()
30 * is implemented to return a skb, which is the format of packet in Linux.
31 * The HIP core lib frees the bulk data buffers, so we do not need to do
32 * this in the OS layer.
34 * All the Rx packets are MLME-UNITDATA.ind signals, passed by the HIP core lib
35 * in unifi_receive_event(). We do not need to allocate an skb and copy the
36 * received packet because the HIP core lib has stored in memory allocated by
37 * unifi_net_data_malloc(). Also, we can perform the 802.11 to Ethernet
38 * translation in-place because we allocate the extra memory allocated in
39 * unifi_net_data_malloc().
41 * If possible, the porting exercise should appropriately implement
42 * unifi_net_data_malloc() and unifi_net_data_free() to save copies between
43 * network and driver buffers.
46 #include <linux/types.h>
47 #include <linux/etherdevice.h>
48 #include <linux/mutex.h>
49 #include <linux/semaphore.h>
50 #include <linux/version.h>
51 #include <linux/vmalloc.h>
52 #include "csr_wifi_hip_unifi.h"
53 #include "csr_wifi_hip_conversions.h"
54 #include "unifi_priv.h"
55 #include <net/pkt_sched.h>
58 /* ALLOW_Q_PAUSE: Pre 2.6.28 kernels do not support multiple driver queues (required for QoS).
59 * In order to support QoS in these kernels, multiple queues are implemented in the driver. But since
60 * there is only a single queue in the kernel (leading to multiple queues in the driver) there is no possibility
61 * of stopping a particular queue in the kernel. Stopping the single kernel queue leads to undesirable starvation
62 * of driver queues. One of the proposals is to not stop the kernel queue but to prevent dequeuing from the
63 * 'stopped' driver queue. Allow q pause is an experimental implementation of this scheme for pre 2.6.28 kernels.
64 * When NOT defined, queues are paused locally in the driver and packets are dequeued for transmission only from the
65 * unpaused queues. When Allow q pause is defined the kernel queue is stopped whenever any driver queue is paused.
70 #define UF_ALLOC_NETDEV(_dev, _size, _name, _setup, _num_of_queues) \
72 static char name[8]; \
73 sprintf(name, "%s%s", UNIFI_NET_NAME, _name); \
74 _dev = alloc_netdev_mq(_size, name, _setup, _num_of_queues); \
77 #define UF_ALLOC_NETDEV(_dev, _size, _name, _setup, _num_of_queues) \
79 _dev = alloc_etherdev_mq(_size, _num_of_queues); \
81 #endif /* UNIFI_NET_NAME */
84 /* Wext handler is suported only if CSR_SUPPORT_WEXT is defined */
85 #ifdef CSR_SUPPORT_WEXT
86 extern struct iw_handler_def unifi_iw_handler_def
;
87 #endif /* CSR_SUPPORT_WEXT */
88 static void check_ba_frame_age_timeout( unifi_priv_t
*priv
,
89 netInterface_priv_t
*interfacePriv
,
90 ba_session_rx_struct
*ba_session
);
91 static void process_ba_frame(unifi_priv_t
*priv
,
92 netInterface_priv_t
*interfacePriv
,
93 ba_session_rx_struct
*ba_session
,
94 frame_desc_struct
*frame_desc
);
95 static void process_ba_complete(unifi_priv_t
*priv
, netInterface_priv_t
*interfacePriv
);
96 static void process_ma_packet_error_ind(unifi_priv_t
*priv
, CSR_SIGNAL
*signal
, bulk_data_param_t
*bulkdata
);
97 static void process_amsdu(unifi_priv_t
*priv
, CSR_SIGNAL
*signal
, bulk_data_param_t
*bulkdata
);
98 static int uf_net_open(struct net_device
*dev
);
99 static int uf_net_ioctl(struct net_device
*dev
, struct ifreq
*rq
, int cmd
);
100 static int uf_net_stop(struct net_device
*dev
);
101 static struct net_device_stats
*uf_net_get_stats(struct net_device
*dev
);
102 static u16
uf_net_select_queue(struct net_device
*dev
, struct sk_buff
*skb
);
103 static netdev_tx_t
uf_net_xmit(struct sk_buff
*skb
, struct net_device
*dev
);
104 static void uf_set_multicast_list(struct net_device
*dev
);
107 typedef int (*tx_signal_handler
)(unifi_priv_t
*priv
, struct sk_buff
*skb
, const struct ethhdr
*ehdr
, CSR_PRIORITY priority
);
109 #ifdef CONFIG_NET_SCHED
111 * Queueing Discipline Interface
112 * Only used if kernel is configured with CONFIG_NET_SCHED
116 * The driver uses the qdisc interface to buffer and control all
117 * outgoing traffic. We create a root qdisc, register our qdisc operations
118 * and later we create two subsiduary pfifo queues for the uncontrolled
119 * and controlled ports.
121 * The network stack delivers all outgoing packets in our enqueue handler.
122 * There, we classify the packet and decide whether to store it or drop it
123 * (if the controlled port state is set to "discard").
124 * If the packet is enqueued, the network stack call our dequeue handler.
125 * There, we decide whether we can send the packet, delay it or drop it
126 * (the controlled port configuration might have changed meanwhile).
127 * If a packet is dequeued, then the network stack calls our hard_start_xmit
128 * handler where finally we send the packet.
130 * If the hard_start_xmit handler fails to send the packet, we return
131 * NETDEV_TX_BUSY and the network stack call our requeue handler where
132 * we put the packet back in the same queue in came from.
138 /* Traffic Classifier TBD */
139 struct tcf_proto
*filter_list
;
141 struct Qdisc
*queues
[UNIFI_TRAFFIC_Q_MAX
];
144 struct uf_tx_packet_data
{
145 /* Queue the packet is stored in */
146 unifi_TrafficQueue queue
;
147 /* QoS Priority determined when enqueing packet */
148 CSR_PRIORITY priority
;
150 unsigned long host_tag
;
153 #endif /* CONFIG_NET_SCHED */
155 static const struct net_device_ops uf_netdev_ops
=
157 .ndo_open
= uf_net_open
,
158 .ndo_stop
= uf_net_stop
,
159 .ndo_start_xmit
= uf_net_xmit
,
160 .ndo_do_ioctl
= uf_net_ioctl
,
161 .ndo_get_stats
= uf_net_get_stats
, /* called by /proc/net/dev */
162 .ndo_set_rx_mode
= uf_set_multicast_list
,
163 .ndo_select_queue
= uf_net_select_queue
,
166 static u8 oui_rfc1042
[P80211_OUI_LEN
] = { 0x00, 0x00, 0x00 };
167 static u8 oui_8021h
[P80211_OUI_LEN
] = { 0x00, 0x00, 0xf8 };
170 /* Callback for event logging to blocking clients */
171 static void netdev_mlme_event_handler(ul_client_t
*client
,
172 const u8
*sig_packed
, int sig_len
,
173 const bulk_data_param_t
*bulkdata
,
176 #ifdef CSR_SUPPORT_WEXT
177 /* Declare netdev_notifier block which will contain the state change
178 * handler callback function
180 static struct notifier_block uf_netdev_notifier
;
184 * ---------------------------------------------------------------------------
187 * Allocate memory for the net_device and device private structs
188 * for this interface.
189 * Fill in the fields, but don't register the interface yet.
190 * We need to configure the UniFi first.
193 * sdio_dev Pointer to SDIO context handle to use for all
195 * bus_id A small number indicating the SDIO card position on the
196 * bus. Typically this is the slot number, e.g. 0, 1 etc.
197 * Valid values are 0 to MAX_UNIFI_DEVS-1.
200 * Pointer to device private struct.
203 * The net_device and device private structs are allocated together
204 * and should be freed by freeing the net_device pointer.
205 * ---------------------------------------------------------------------------
208 uf_alloc_netdevice(CsrSdioFunction
*sdio_dev
, int bus_id
)
210 struct net_device
*dev
;
212 netInterface_priv_t
*interfacePriv
;
213 #ifdef CSR_SUPPORT_WEXT
216 unsigned char i
; /* loop index */
219 * Allocate netdevice struct, assign name template and
220 * setup as an ethernet device.
221 * The net_device and private structs are zeroed. Ether_setup() then
222 * sets up ethernet handlers and values.
223 * The RedHat 9 redhat-config-network tool doesn't recognise wlan* devices,
224 * so use "eth*" (like other wireless extns drivers).
226 UF_ALLOC_NETDEV(dev
, sizeof(unifi_priv_t
)+sizeof(netInterface_priv_t
), "%d", ether_setup
, UNIFI_TRAFFIC_Q_MAX
);
232 /* Set up back pointer from priv to netdev */
233 interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
234 priv
= (unifi_priv_t
*)(interfacePriv
+ 1);
235 interfacePriv
->privPtr
= priv
;
236 interfacePriv
->InterfaceTag
= 0;
239 /* Initialize all supported netdev interface to be NULL */
240 for(i
=0; i
<CSR_WIFI_NUM_INTERFACES
; i
++) {
241 priv
->netdev
[i
] = NULL
;
242 priv
->interfacePriv
[i
] = NULL
;
244 priv
->netdev
[0] = dev
;
245 priv
->interfacePriv
[0] = interfacePriv
;
247 /* Setup / override net_device fields */
248 dev
->netdev_ops
= &uf_netdev_ops
;
250 #ifdef CSR_SUPPORT_WEXT
251 dev
->wireless_handlers
= &unifi_iw_handler_def
;
252 #if IW_HANDLER_VERSION < 6
253 dev
->get_wireless_stats
= unifi_get_wireless_stats
;
254 #endif /* IW_HANDLER_VERSION */
255 #endif /* CSR_SUPPORT_WEXT */
257 /* This gives us enough headroom to add the 802.11 header */
258 dev
->needed_headroom
= 32;
260 /* Use bus_id as instance number */
261 priv
->instance
= bus_id
;
262 /* Store SDIO pointer to pass in the core */
263 priv
->sdio
= sdio_dev
;
265 sdio_dev
->driverData
= (void*)priv
;
266 /* Consider UniFi to be uninitialised */
267 priv
->init_progress
= UNIFI_INIT_NONE
;
269 priv
->prev_queue
= 0;
272 * Initialise the clients structure array.
273 * We do not need protection around ul_init_clients() because
274 * the character device can not be used until uf_alloc_netdevice()
275 * returns and Unifi_instances[bus_id]=priv is set, since unifi_open()
276 * will return -ENODEV.
278 ul_init_clients(priv
);
281 * Register a new ul client to send the multicast list signals.
282 * Note: priv->instance must be set before calling this.
284 priv
->netdev_client
= ul_register_client(priv
,
286 netdev_mlme_event_handler
);
287 if (priv
->netdev_client
== NULL
) {
289 "Failed to register a unifi client for background netdev processing\n");
290 free_netdev(priv
->netdev
[0]);
293 unifi_trace(priv
, UDBG2
, "Netdev %p client (id:%d s:0x%X) is registered\n",
294 dev
, priv
->netdev_client
->client_id
, priv
->netdev_client
->sender_id
);
296 priv
->sta_wmm_capabilities
= 0;
298 #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_SUPPORT_SME))
299 priv
->wapi_multicast_filter
= 0;
300 priv
->wapi_unicast_filter
= 0;
301 priv
->wapi_unicast_queued_pkt_filter
= 0;
302 #ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
303 priv
->isWapiConnection
= FALSE
;
307 /* Enable all queues by default */
308 interfacePriv
->queueEnabled
[0] = 1;
309 interfacePriv
->queueEnabled
[1] = 1;
310 interfacePriv
->queueEnabled
[2] = 1;
311 interfacePriv
->queueEnabled
[3] = 1;
313 #ifdef CSR_SUPPORT_SME
314 priv
->allPeerDozing
= 0;
317 * Initialise the OS private struct.
320 * Instead of deciding in advance to use 11bg or 11a, we could do a more
321 * clever scan on both radios.
324 priv
->if_index
= CSR_INDEX_5G
;
325 unifi_info(priv
, "Using the 802.11a radio\n");
327 priv
->if_index
= CSR_INDEX_2G4
;
330 /* Initialise bh thread structure */
331 priv
->bh_thread
.thread_task
= NULL
;
332 priv
->bh_thread
.block_thread
= 1;
333 init_waitqueue_head(&priv
->bh_thread
.wakeup_q
);
334 priv
->bh_thread
.wakeup_flag
= 0;
335 sprintf(priv
->bh_thread
.name
, "uf_bh_thread");
337 /* reset the connected state for the interface */
338 interfacePriv
->connected
= UnifiConnectedUnknown
; /* -1 unknown, 0 no, 1 yes */
340 #ifdef USE_DRIVER_LOCK
341 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
342 sema_init(&priv
->lock
, 1);
344 init_MUTEX(&priv
->lock
);
346 #endif /* USE_DRIVER_LOCK */
348 spin_lock_init(&priv
->send_signal_lock
);
350 spin_lock_init(&priv
->m4_lock
);
351 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
352 sema_init(&priv
->ba_mutex
, 1);
354 init_MUTEX(&priv
->ba_mutex
);
357 #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
358 spin_lock_init(&priv
->wapi_lock
);
361 #ifdef CSR_SUPPORT_SME
362 spin_lock_init(&priv
->staRecord_lock
);
363 spin_lock_init(&priv
->tx_q_lock
);
366 /* Create the Traffic Analysis workqueue */
367 priv
->unifi_workqueue
= create_singlethread_workqueue("unifi_workq");
368 if (priv
->unifi_workqueue
== NULL
) {
369 /* Deregister priv->netdev_client */
370 ul_deregister_client(priv
->netdev_client
);
371 free_netdev(priv
->netdev
[0]);
375 #ifdef CSR_SUPPORT_SME
376 /* Create the Multicast Addresses list work structure */
377 INIT_WORK(&priv
->multicast_list_task
, uf_multicast_list_wq
);
379 /* Create m4 buffering work structure */
380 INIT_WORK(&interfacePriv
->send_m4_ready_task
, uf_send_m4_ready_wq
);
382 #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
383 /* Create work structure to buffer the WAPI data packets to be sent to SME for encryption */
384 INIT_WORK(&interfacePriv
->send_pkt_to_encrypt
, uf_send_pkt_to_encrypt
);
390 priv
->amp_client
= NULL
;
391 priv
->coredump_mode
= 0;
392 priv
->ptest_mode
= 0;
393 priv
->wol_suspend
= FALSE
;
394 INIT_LIST_HEAD(&interfacePriv
->rx_uncontrolled_list
);
395 INIT_LIST_HEAD(&interfacePriv
->rx_controlled_list
);
396 sema_init(&priv
->rx_q_sem
, 1);
398 #ifdef CSR_SUPPORT_WEXT
399 interfacePriv
->netdev_callback_registered
= FALSE
;
400 interfacePriv
->wait_netdev_change
= FALSE
;
401 /* Register callback for netdevice state changes */
402 if ((rc
= register_netdevice_notifier(&uf_netdev_notifier
)) == 0) {
403 interfacePriv
->netdev_callback_registered
= TRUE
;
406 unifi_warning(priv
, "Failed to register netdevice notifier : %d %p\n", rc
, dev
);
408 #endif /* CSR_SUPPORT_WEXT */
410 #ifdef CSR_WIFI_SPLIT_PATCH
411 /* set it to some invalid value */
412 priv
->pending_mode_set
.common
.destination
= 0xaaaa;
416 } /* uf_alloc_netdevice() */
419 *---------------------------------------------------------------------------
420 * uf_alloc_netdevice_for_other_interfaces
422 * Allocate memory for the net_device and device private structs
423 * for this interface.
424 * Fill in the fields, but don't register the interface yet.
425 * We need to configure the UniFi first.
428 * interfaceTag Interface number.
429 * sdio_dev Pointer to SDIO context handle to use for all
431 * bus_id A small number indicating the SDIO card position on the
432 * bus. Typically this is the slot number, e.g. 0, 1 etc.
433 * Valid values are 0 to MAX_UNIFI_DEVS-1.
436 * Pointer to device private struct.
439 * The device private structure contains the interfaceTag and pointer to the unifi_priv
440 * structure created allocated by net_device od interface0.
441 * The net_device and device private structs are allocated together
442 * and should be freed by freeing the net_device pointer.
443 * ---------------------------------------------------------------------------
446 uf_alloc_netdevice_for_other_interfaces(unifi_priv_t
*priv
, u16 interfaceTag
)
448 struct net_device
*dev
;
449 netInterface_priv_t
*interfacePriv
;
452 * Allocate netdevice struct, assign name template and
453 * setup as an ethernet device.
454 * The net_device and private structs are zeroed. Ether_setup() then
455 * sets up ethernet handlers and values.
456 * The RedHat 9 redhat-config-network tool doesn't recognise wlan* devices,
457 * so use "eth*" (like other wireless extns drivers).
459 UF_ALLOC_NETDEV(dev
, sizeof(netInterface_priv_t
), "%d", ether_setup
, 1);
464 if (interfaceTag
>= CSR_WIFI_NUM_INTERFACES
) {
465 unifi_error(priv
, "uf_alloc_netdevice_for_other_interfaces bad interfaceTag\n");
469 /* Set up back pointer from priv to netdev */
470 interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
471 interfacePriv
->privPtr
= priv
;
472 interfacePriv
->InterfaceTag
= interfaceTag
;
473 priv
->netdev
[interfaceTag
] = dev
;
474 priv
->interfacePriv
[interfacePriv
->InterfaceTag
] = interfacePriv
;
476 /* reset the connected state for the interface */
477 interfacePriv
->connected
= UnifiConnectedUnknown
; /* -1 unknown, 0 no, 1 yes */
478 INIT_LIST_HEAD(&interfacePriv
->rx_uncontrolled_list
);
479 INIT_LIST_HEAD(&interfacePriv
->rx_controlled_list
);
481 /* Setup / override net_device fields */
482 dev
->netdev_ops
= &uf_netdev_ops
;
484 #ifdef CSR_SUPPORT_WEXT
485 dev
->wireless_handlers
= &unifi_iw_handler_def
;
486 #if IW_HANDLER_VERSION < 6
487 dev
->get_wireless_stats
= unifi_get_wireless_stats
;
488 #endif /* IW_HANDLER_VERSION */
489 #endif /* CSR_SUPPORT_WEXT */
491 } /* uf_alloc_netdevice() */
496 * ---------------------------------------------------------------------------
499 * Unregister the network device and free the memory allocated for it.
500 * NB This includes the memory for the priv struct.
503 * priv Device private pointer.
507 * ---------------------------------------------------------------------------
510 uf_free_netdevice(unifi_priv_t
*priv
)
517 unifi_trace(priv
, UDBG1
, "uf_free_netdevice\n");
524 * Free any buffers used for holding firmware
526 uf_release_firmware_files(priv
);
528 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
529 if (priv
->connection_config
.mlmeAssociateReqInformationElements
) {
530 kfree(priv
->connection_config
.mlmeAssociateReqInformationElements
);
532 priv
->connection_config
.mlmeAssociateReqInformationElements
= NULL
;
533 priv
->connection_config
.mlmeAssociateReqInformationElementsLength
= 0;
535 if (priv
->mib_data
.length
) {
536 vfree(priv
->mib_data
.data
);
538 priv
->mib_data
.data
= NULL
;
539 priv
->mib_data
.length
= 0;
541 #endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT*/
543 /* Free any bulkdata buffers allocated for M4 caching */
544 spin_lock_irqsave(&priv
->m4_lock
, flags
);
545 for (i
= 0; i
< CSR_WIFI_NUM_INTERFACES
; i
++) {
546 netInterface_priv_t
*interfacePriv
= priv
->interfacePriv
[i
];
547 if (interfacePriv
->m4_bulk_data
.data_length
> 0) {
548 unifi_trace(priv
, UDBG5
, "uf_free_netdevice: free M4 bulkdata %d\n", i
);
549 unifi_net_data_free(priv
, &interfacePriv
->m4_bulk_data
);
552 spin_unlock_irqrestore(&priv
->m4_lock
, flags
);
554 #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
555 /* Free any bulkdata buffers allocated for M4 caching */
556 spin_lock_irqsave(&priv
->wapi_lock
, flags
);
557 for (i
= 0; i
< CSR_WIFI_NUM_INTERFACES
; i
++) {
558 netInterface_priv_t
*interfacePriv
= priv
->interfacePriv
[i
];
559 if (interfacePriv
->wapi_unicast_bulk_data
.data_length
> 0) {
560 unifi_trace(priv
, UDBG5
, "uf_free_netdevice: free WAPI PKT bulk data %d\n", i
);
561 unifi_net_data_free(priv
, &interfacePriv
->wapi_unicast_bulk_data
);
564 spin_unlock_irqrestore(&priv
->wapi_lock
, flags
);
567 #ifdef CSR_SUPPORT_WEXT
568 /* Unregister callback for netdevice state changes */
569 unregister_netdevice_notifier(&uf_netdev_notifier
);
570 #endif /* CSR_SUPPORT_WEXT */
572 #ifdef CSR_SUPPORT_SME
573 /* Cancel work items and destroy the workqueue */
574 cancel_work_sync(&priv
->multicast_list_task
);
576 /* Destroy the workqueues. */
577 flush_workqueue(priv
->unifi_workqueue
);
578 destroy_workqueue(priv
->unifi_workqueue
);
580 /* Free up netdev in reverse order: priv is allocated with netdev[0].
581 * So, netdev[0] should be freed after all other netdevs are freed up
583 for (i
=CSR_WIFI_NUM_INTERFACES
-1; i
>=0; i
--) {
584 /*Free the netdev struct and priv, which are all one lump*/
585 if (priv
->netdev
[i
]) {
586 unifi_error(priv
, "uf_free_netdevice: netdev %d %p\n", i
, priv
->netdev
[i
]);
587 free_netdev(priv
->netdev
[i
]);
593 } /* uf_free_netdevice() */
597 * ---------------------------------------------------------------------------
600 * Called when userland does "ifconfig wlan0 up".
603 * dev Device pointer.
607 * ---------------------------------------------------------------------------
610 uf_net_open(struct net_device
*dev
)
612 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
613 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
617 /* If we haven't finished UniFi initialisation, we can't start */
618 if (priv
->init_progress
!= UNIFI_INIT_COMPLETED
) {
619 unifi_warning(priv
, "%s: unifi not ready, failing net_open\n", __FUNCTION__
);
623 #if (defined CSR_NATIVE_LINUX) && (defined UNIFI_SNIFF_ARPHRD) && defined(CSR_SUPPORT_WEXT)
625 * To sniff, the user must do "iwconfig mode monitor", which sets
626 * priv->wext_conf.mode to IW_MODE_MONITOR.
627 * Then he/she must do "ifconfig ethn up", which calls this fn.
628 * There is no point in starting the sniff with SNIFFJOIN until
631 if (priv
->wext_conf
.mode
== IW_MODE_MONITOR
) {
633 err
= uf_start_sniff(priv
);
637 netif_carrier_on(dev
);
641 #ifdef CSR_SUPPORT_WEXT
642 if (interfacePriv
->wait_netdev_change
) {
643 unifi_trace(priv
, UDBG1
, "%s: Waiting for NETDEV_CHANGE, assume connected\n",
645 interfacePriv
->connected
= UnifiConnected
;
646 interfacePriv
->wait_netdev_change
= FALSE
;
650 UF_NETIF_TX_START_ALL_QUEUES(dev
);
654 } /* uf_net_open() */
658 uf_net_stop(struct net_device
*dev
)
660 #if defined(CSR_NATIVE_LINUX) && defined(UNIFI_SNIFF_ARPHRD) && defined(CSR_SUPPORT_WEXT)
661 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
662 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
666 /* Stop sniffing if in Monitor mode */
667 if (priv
->wext_conf
.mode
== IW_MODE_MONITOR
) {
670 err
= unifi_reset_state(priv
, dev
->dev_addr
, 1);
680 UF_NETIF_TX_STOP_ALL_QUEUES(dev
);
684 } /* uf_net_stop() */
687 /* This is called after the WE handlers */
689 uf_net_ioctl(struct net_device
*dev
, struct ifreq
*rq
, int cmd
)
696 } /* uf_net_ioctl() */
700 static struct net_device_stats
*
701 uf_net_get_stats(struct net_device
*dev
)
703 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
705 return &interfacePriv
->stats
;
706 } /* uf_net_get_stats() */
708 static CSR_PRIORITY
uf_get_packet_priority(unifi_priv_t
*priv
, netInterface_priv_t
*interfacePriv
, struct sk_buff
*skb
, const int proto
)
710 CSR_PRIORITY priority
= CSR_CONTENTION
;
713 priority
= (CSR_PRIORITY
) (skb
->priority
>> 5);
715 if (priority
== CSR_QOS_UP0
) { /* 0 */
717 unifi_trace(priv
, UDBG5
, "uf_get_packet_priority: proto = 0x%.4X\n", proto
);
720 case 0x0800: /* IPv4 */
721 case 0x814C: /* SNMP */
722 case 0x880C: /* GSMP */
723 priority
= (CSR_PRIORITY
) (skb
->data
[1 + ETH_HLEN
] >> 5);
726 case 0x8100: /* VLAN */
727 priority
= (CSR_PRIORITY
) (skb
->data
[0 + ETH_HLEN
] >> 5);
730 case 0x86DD: /* IPv6 */
731 priority
= (CSR_PRIORITY
) ((skb
->data
[0 + ETH_HLEN
] & 0x0E) >> 1);
735 priority
= CSR_QOS_UP0
;
740 /* Check if we are allowed to transmit on this AC. Because of ACM we may have to downgrade to a lower
742 if (interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_STA
||
743 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI
) {
744 unifi_TrafficQueue queue
;
746 /* Keep trying lower priorities until we find a queue
747 * Priority to queue mapping is 1,2 - BK, 0,3 - BE, 4,5 - VI, 6,7 - VO */
748 queue
= unifi_frame_priority_to_queue(priority
);
750 while (queue
> UNIFI_TRAFFIC_Q_BK
&& !interfacePriv
->queueEnabled
[queue
]) {
752 priority
= unifi_get_default_downgrade_priority(queue
);
756 unifi_trace(priv
, UDBG5
, "Packet priority = %d\n", priority
);
765 * ---------------------------------------------------------------------------
766 * get_packet_priority
769 * priv private data area of functional driver
771 * ehdr ethernet header to fetch protocol
772 * interfacePriv For accessing station record database
777 * ---------------------------------------------------------------------------
780 get_packet_priority(unifi_priv_t
*priv
, struct sk_buff
*skb
, const struct ethhdr
*ehdr
, netInterface_priv_t
*interfacePriv
)
782 CSR_PRIORITY priority
= CSR_CONTENTION
;
783 const int proto
= ntohs(ehdr
->h_proto
);
785 u8 interfaceMode
= interfacePriv
->interfaceMode
;
789 /* Priority Mapping for all the Modes */
790 switch(interfaceMode
)
792 case CSR_WIFI_ROUTER_CTRL_MODE_STA
:
793 case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI
:
794 unifi_trace(priv
, UDBG4
, "mode is STA \n");
795 if ((priv
->sta_wmm_capabilities
& QOS_CAPABILITY_WMM_ENABLED
) == 1) {
796 priority
= uf_get_packet_priority(priv
, interfacePriv
, skb
, proto
);
798 priority
= CSR_CONTENTION
;
801 #ifdef CSR_SUPPORT_SME
802 case CSR_WIFI_ROUTER_CTRL_MODE_AP
:
803 case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
:
804 case CSR_WIFI_ROUTER_CTRL_MODE_IBSS
:
806 CsrWifiRouterCtrlStaInfo_t
* dstStaInfo
=
807 CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv
,ehdr
->h_dest
, interfacePriv
->InterfaceTag
);
808 unifi_trace(priv
, UDBG4
, "mode is AP \n");
809 if (!(ehdr
->h_dest
[0] & 0x01) && dstStaInfo
&& dstStaInfo
->wmmOrQosEnabled
) {
810 /* If packet is not Broadcast/multicast */
811 priority
= uf_get_packet_priority(priv
, interfacePriv
, skb
, proto
);
813 /* Since packet destination is not QSTA, set priority to CSR_CONTENTION */
814 unifi_trace(priv
, UDBG4
, "Destination is not QSTA or BroadCast/Multicast\n");
815 priority
= CSR_CONTENTION
;
821 unifi_trace(priv
, UDBG3
, " mode unknown in %s func, mode=%x\n", __FUNCTION__
, interfaceMode
);
823 unifi_trace(priv
, UDBG5
, "priority = %x\n", priority
);
830 * ---------------------------------------------------------------------------
831 * uf_net_select_queue
833 * Called by the kernel to select which queue to put the packet in
841 * ---------------------------------------------------------------------------
844 uf_net_select_queue(struct net_device
*dev
, struct sk_buff
*skb
)
846 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
847 unifi_priv_t
*priv
= (unifi_priv_t
*)interfacePriv
->privPtr
;
849 unifi_TrafficQueue queue
;
851 CSR_PRIORITY priority
;
855 memcpy(&ehdr
, skb
->data
, ETH_HLEN
);
856 proto
= ntohs(ehdr
.h_proto
);
858 /* 802.1x - apply controlled/uncontrolled port rules */
859 if ((proto
!= ETH_P_PAE
)
860 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
861 && (proto
!= ETH_P_WAI
)
865 priority
= get_packet_priority(priv
, skb
, &ehdr
, interfacePriv
);
866 queue
= unifi_frame_priority_to_queue(priority
);
869 queue
= UNIFI_TRAFFIC_Q_EAPOL
;
875 } /* uf_net_select_queue() */
878 skb_add_llc_snap(struct net_device
*dev
, struct sk_buff
*skb
, int proto
)
880 llc_snap_hdr_t
*snap
;
881 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
882 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
885 /* get the headroom available in skb */
886 headroom
= skb_headroom(skb
);
887 /* step 1: classify ether frame, DIX or 802.3? */
890 /* codes <= 1500 reserved for 802.3 lengths */
891 /* it's 802.3, pass ether payload unchanged, */
892 unifi_trace(priv
, UDBG3
, "802.3 len: %d\n", skb
->len
);
894 /* leave off any PAD octets. */
895 skb_trim(skb
, proto
);
896 } else if (proto
== ETH_P_8021Q
) {
898 /* Store the VLAN SNAP (should be 87-65). */
899 u16 vlan_snap
= *(u16
*)skb
->data
;
900 /* check for headroom availability before skb_push 14 = (4 + 10) */
902 unifi_trace(priv
, UDBG3
, "cant append vlan snap: debug\n");
905 /* Add AA-AA-03-00-00-00 */
906 snap
= (llc_snap_hdr_t
*)skb_push(skb
, 4);
907 snap
->dsap
= snap
->ssap
= 0xAA;
909 memcpy(snap
->oui
, oui_rfc1042
, P80211_OUI_LEN
);
911 /* Add AA-AA-03-00-00-00 */
912 snap
= (llc_snap_hdr_t
*)skb_push(skb
, 10);
913 snap
->dsap
= snap
->ssap
= 0xAA;
915 memcpy(snap
->oui
, oui_rfc1042
, P80211_OUI_LEN
);
917 /* Add the VLAN specific information */
918 snap
->protocol
= htons(proto
);
919 *(u16
*)(snap
+ 1) = vlan_snap
;
923 /* it's DIXII, time for some conversion */
924 unifi_trace(priv
, UDBG3
, "DIXII len: %d\n", skb
->len
);
926 /* check for headroom availability before skb_push */
927 if (headroom
< sizeof(llc_snap_hdr_t
)) {
928 unifi_trace(priv
, UDBG3
, "cant append snap: debug\n");
932 snap
= (llc_snap_hdr_t
*)skb_push(skb
, sizeof(llc_snap_hdr_t
));
933 snap
->dsap
= snap
->ssap
= 0xAA;
935 /* Use the appropriate OUI. */
936 if ((proto
== ETH_P_AARP
) || (proto
== ETH_P_IPX
)) {
937 memcpy(snap
->oui
, oui_8021h
, P80211_OUI_LEN
);
939 memcpy(snap
->oui
, oui_rfc1042
, P80211_OUI_LEN
);
941 snap
->protocol
= htons(proto
);
945 } /* skb_add_llc_snap() */
947 #ifdef CSR_SUPPORT_SME
949 _identify_sme_ma_pkt_ind(unifi_priv_t
*priv
,
950 const s8
*oui
, u16 protocol
,
951 const CSR_SIGNAL
*signal
,
952 bulk_data_param_t
*bulkdata
,
953 const unsigned char *daddr
,
954 const unsigned char *saddr
)
956 CSR_MA_PACKET_INDICATION
*pkt_ind
= (CSR_MA_PACKET_INDICATION
*)&signal
->u
.MaPacketIndication
;
960 unifi_trace(priv
, UDBG5
,
961 "_identify_sme_ma_pkt_ind -->\n");
962 for (i
= 0; i
< MAX_MA_UNIDATA_IND_FILTERS
; i
++) {
963 if (priv
->sme_unidata_ind_filters
[i
].in_use
) {
964 if (!memcmp(oui
, priv
->sme_unidata_ind_filters
[i
].oui
, 3) &&
965 (protocol
== priv
->sme_unidata_ind_filters
[i
].protocol
)) {
970 * Pass the packet to the SME, using unifi_sys_ma_unitdata_ind().
971 * The frame needs to be converted according to the encapsulation.
973 unifi_trace(priv
, UDBG1
,
974 "_identify_sme_ma_pkt_ind: handle=%d, encap=%d, proto=%x\n",
975 i
, priv
->sme_unidata_ind_filters
[i
].encapsulation
,
976 priv
->sme_unidata_ind_filters
[i
].protocol
);
977 if (priv
->sme_unidata_ind_filters
[i
].encapsulation
== CSR_WIFI_ROUTER_ENCAPSULATION_ETHERNET
) {
979 /* The translation is performed on skb... */
980 skb
= (struct sk_buff
*)bulkdata
->d
[0].os_net_buf_ptr
;
981 skb
->len
= bulkdata
->d
[0].data_length
;
983 unifi_trace(priv
, UDBG1
,
984 "_identify_sme_ma_pkt_ind: skb_80211_to_ether -->\n");
985 r
= skb_80211_to_ether(priv
, skb
, daddr
, saddr
,
987 unifi_trace(priv
, UDBG1
,
988 "_identify_sme_ma_pkt_ind: skb_80211_to_ether <--\n");
993 /* ... but we indicate buffer and length */
994 bulkdata
->d
[0].os_data_ptr
= skb
->data
;
995 bulkdata
->d
[0].data_length
= skb
->len
;
997 /* Add the MAC addresses before the SNAP */
998 bulkdata
->d
[0].os_data_ptr
-= 2*ETH_ALEN
;
999 bulkdata
->d
[0].data_length
+= 2*ETH_ALEN
;
1000 memcpy((void*)bulkdata
->d
[0].os_data_ptr
, daddr
, ETH_ALEN
);
1001 memcpy((void*)bulkdata
->d
[0].os_data_ptr
+ ETH_ALEN
, saddr
, ETH_ALEN
);
1004 unifi_trace(priv
, UDBG1
,
1005 "_identify_sme_ma_pkt_ind: unifi_sys_ma_pkt_ind -->\n");
1006 CsrWifiRouterMaPacketIndSend(priv
->sme_unidata_ind_filters
[i
].appHandle
,
1007 (pkt_ind
->VirtualInterfaceIdentifier
& 0xff),
1009 pkt_ind
->ReceptionStatus
,
1010 bulkdata
->d
[0].data_length
,
1011 (u8
*)bulkdata
->d
[0].os_data_ptr
,
1015 pkt_ind
->ReceivedRate
);
1018 unifi_trace(priv
, UDBG1
,
1019 "_identify_sme_ma_pkt_ind: unifi_sys_ma_pkt_ind <--\n");
1029 #endif /* CSR_SUPPORT_SME */
1032 * ---------------------------------------------------------------------------
1033 * skb_80211_to_ether
1035 * Make sure the received frame is in Ethernet (802.3) form.
1036 * De-encapsulates SNAP if necessary, adds a ethernet header.
1037 * The source buffer should not contain an 802.11 MAC header
1040 * payload Pointer to packet data received from UniFi.
1041 * payload_length Number of bytes of data received from UniFi.
1042 * daddr Destination MAC address.
1043 * saddr Source MAC address.
1046 * 0 on success, -1 if the packet is bad and should be dropped,
1047 * 1 if the packet was forwarded to the SME or AMP client.
1048 * ---------------------------------------------------------------------------
1051 skb_80211_to_ether(unifi_priv_t
*priv
, struct sk_buff
*skb
,
1052 const unsigned char *daddr
, const unsigned char *saddr
,
1053 const CSR_SIGNAL
*signal
,
1054 bulk_data_param_t
*bulkdata
)
1056 unsigned char *payload
;
1059 llc_snap_hdr_t
*snap
;
1061 #define UF_VLAN_LLC_HEADER_SIZE 18
1062 static const u8 vlan_inner_snap
[] = { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00 };
1063 #if defined(CSR_NATIVE_SOFTMAC) && defined(CSR_SUPPORT_SME)
1064 const CSR_MA_PACKET_INDICATION
*pkt_ind
= &signal
->u
.MaPacketIndication
;
1067 if(skb
== NULL
|| daddr
== NULL
|| saddr
== NULL
){
1068 unifi_error(priv
,"skb_80211_to_ether: PBC fail\n");
1072 payload
= skb
->data
;
1073 payload_length
= skb
->len
;
1075 snap
= (llc_snap_hdr_t
*)payload
;
1076 eth
= (struct ethhdr
*)payload
;
1078 /* get the skb headroom size */
1079 headroom
= skb_headroom(skb
);
1082 * Test for the various encodings
1084 if ((payload_length
>= sizeof(llc_snap_hdr_t
)) &&
1085 (snap
->dsap
== 0xAA) &&
1086 (snap
->ssap
== 0xAA) &&
1087 (snap
->ctrl
== 0x03) &&
1088 (snap
->oui
[0] == 0) &&
1089 (snap
->oui
[1] == 0) &&
1090 ((snap
->oui
[2] == 0) || (snap
->oui
[2] == 0xF8)))
1092 /* AppleTalk AARP (2) or IPX SNAP */
1093 if ((snap
->oui
[2] == 0) &&
1094 ((ntohs(snap
->protocol
) == ETH_P_AARP
) || (ntohs(snap
->protocol
) == ETH_P_IPX
)))
1098 unifi_trace(priv
, UDBG3
, "%s len: %d\n",
1099 (ntohs(snap
->protocol
) == ETH_P_AARP
) ? "ETH_P_AARP" : "ETH_P_IPX",
1102 /* check for headroom availability before skb_push */
1103 if (headroom
< (2 * ETH_ALEN
+ 2)) {
1104 unifi_warning(priv
, "headroom not available to skb_push ether header\n");
1108 /* Add 802.3 header and leave full payload */
1109 len
= htons(skb
->len
);
1110 memcpy(skb_push(skb
, 2), &len
, 2);
1111 memcpy(skb_push(skb
, ETH_ALEN
), saddr
, ETH_ALEN
);
1112 memcpy(skb_push(skb
, ETH_ALEN
), daddr
, ETH_ALEN
);
1116 /* VLAN-tagged IP */
1117 if ((snap
->oui
[2] == 0) && (ntohs(snap
->protocol
) == ETH_P_8021Q
))
1120 * The translation doesn't change the packet length, so is done in-place.
1122 * Example header (from Std 802.11-2007 Annex M):
1123 * AA-AA-03-00-00-00-81-00-87-65-AA-AA-03-00-00-00-08-06
1124 * -------SNAP-------p1-p1-ll-ll-------SNAP--------p2-p2
1125 * dd-dd-dd-dd-dd-dd-aa-aa-aa-aa-aa-aa-p1-p1-ll-ll-p2-p2
1126 * dd-dd-dd-dd-dd-dd-aa-aa-aa-aa-aa-aa-81-00-87-65-08-06
1130 if (payload_length
< UF_VLAN_LLC_HEADER_SIZE
) {
1131 unifi_warning(priv
, "VLAN SNAP header too short: %d bytes\n", payload_length
);
1135 if (memcmp(payload
+ 10, vlan_inner_snap
, 6)) {
1136 unifi_warning(priv
, "VLAN malformatted SNAP header.\n");
1140 unifi_trace(priv
, UDBG3
, "VLAN SNAP: %02x-%02x\n", payload
[8], payload
[9]);
1141 unifi_trace(priv
, UDBG3
, "VLAN len: %d\n", payload_length
);
1143 /* Create the 802.3 header */
1145 vlan_snap
= *((u16
*)(payload
+ 8));
1147 /* Create LLC header without byte-swapping */
1148 eth
->h_proto
= snap
->protocol
;
1150 memcpy(eth
->h_dest
, daddr
, ETH_ALEN
);
1151 memcpy(eth
->h_source
, saddr
, ETH_ALEN
);
1152 *(u16
*)(eth
+ 1) = vlan_snap
;
1156 /* it's a SNAP + RFC1042 frame */
1157 unifi_trace(priv
, UDBG3
, "SNAP+RFC1042 len: %d\n", payload_length
);
1159 /* chop SNAP+llc header from skb. */
1160 skb_pull(skb
, sizeof(llc_snap_hdr_t
));
1162 /* Since skb_pull called above to chop snap+llc, no need to check for headroom
1163 * availability before skb_push
1165 /* create 802.3 header at beginning of skb. */
1166 eth
= (struct ethhdr
*)skb_push(skb
, ETH_HLEN
);
1167 memcpy(eth
->h_dest
, daddr
, ETH_ALEN
);
1168 memcpy(eth
->h_source
, saddr
, ETH_ALEN
);
1169 /* Copy protocol field without byte-swapping */
1170 eth
->h_proto
= snap
->protocol
;
1174 /* check for headroom availability before skb_push */
1175 if (headroom
< (2 * ETH_ALEN
+ 2)) {
1176 unifi_warning(priv
, "headroom not available to skb_push ether header\n");
1179 /* Add 802.3 header and leave full payload */
1180 len
= htons(skb
->len
);
1181 memcpy(skb_push(skb
, 2), &len
, 2);
1182 memcpy(skb_push(skb
, ETH_ALEN
), saddr
, ETH_ALEN
);
1183 memcpy(skb_push(skb
, ETH_ALEN
), daddr
, ETH_ALEN
);
1189 } /* skb_80211_to_ether() */
1192 static CsrWifiRouterCtrlPortAction
verify_port(unifi_priv_t
*priv
, unsigned char *address
, int queue
, u16 interfaceTag
)
1194 #ifdef CSR_NATIVE_LINUX
1195 #ifdef CSR_SUPPORT_WEXT
1196 if (queue
== UF_CONTROLLED_PORT_Q
) {
1197 return priv
->wext_conf
.block_controlled_port
;
1199 return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN
;
1202 return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN
; /* default to open for softmac dev */
1205 return uf_sme_port_state(priv
, address
, queue
, interfaceTag
);
1210 * ---------------------------------------------------------------------------
1211 * prepare_and_add_macheader
1214 * These functions adds mac header for packet from netdev
1215 * to UniFi for transmission.
1216 * EAP protocol packets are also appended with Mac header &
1217 * sent using send_ma_pkt_request().
1220 * priv Pointer to device private context struct
1221 * skb Socket buffer containing data packet to transmit
1222 * newSkb Socket buffer containing data packet + Mac header if no sufficient headroom in skb
1223 * serviceClass to append QOS control header in Mac header
1224 * bulkdata if newSkb allocated then bulkdata updated to send to unifi
1225 * interfaceTag the interfaceID on which activity going on
1226 * daddr destination address
1227 * saddr source address
1228 * protection protection bit set in framce control of mac header
1231 * Zero on success or error code.
1232 * ---------------------------------------------------------------------------
1235 int prepare_and_add_macheader(unifi_priv_t
*priv
, struct sk_buff
*skb
, struct sk_buff
*newSkb
,
1236 CSR_PRIORITY priority
,
1237 bulk_data_param_t
*bulkdata
,
1245 u8 macHeaderLengthInBytes
= MAC_HEADER_SIZE
, *bufPtr
= NULL
;
1246 bulk_data_param_t data_ptrs
;
1247 CsrResult csrResult
;
1250 netInterface_priv_t
*interfacePriv
= priv
->interfacePriv
[interfaceTag
];
1252 u8 bQosNull
= false;
1255 unifi_error(priv
,"prepare_and_add_macheader: Invalid SKB reference\n");
1259 /* add a MAC header refer: 7.1.3.1 Frame Control field in P802.11REVmb.book */
1260 if (priority
!= CSR_CONTENTION
) {
1261 /* EAPOL packets don't go as QOS_DATA */
1262 if (priority
== CSR_MANAGEMENT
) {
1263 fc
|= cpu_to_le16(IEEE802_11_FC_TYPE_DATA
);
1265 /* Qos Control Field */
1266 macHeaderLengthInBytes
+= QOS_CONTROL_HEADER_SIZE
;
1270 fc
|= cpu_to_le16(IEEE802_11_FC_TYPE_QOS_DATA
);
1272 fc
|= cpu_to_le16(IEEE802_11_FC_TYPE_QOS_NULL
);
1278 fc
|= cpu_to_le16(IEEE802_11_FC_TYPE_NULL
);
1280 fc
|= cpu_to_le16(IEEE802_11_FC_TYPE_DATA
);
1284 switch (interfacePriv
->interfaceMode
)
1286 case CSR_WIFI_ROUTER_CTRL_MODE_STA
:
1287 case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI
:
1289 fc
|= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK
);
1291 case CSR_WIFI_ROUTER_CTRL_MODE_IBSS
:
1294 case CSR_WIFI_ROUTER_CTRL_MODE_AP
:
1295 case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
:
1297 fc
|= cpu_to_le16(IEEE802_11_FC_FROM_DS_MASK
);
1299 case CSR_WIFI_ROUTER_CTRL_MODE_AMP
:
1300 if (priority
== CSR_MANAGEMENT
) {
1303 fc
|= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK
);
1305 /* Data frames have to use WDS 4 address frames */
1307 fc
|= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK
| IEEE802_11_FC_FROM_DS_MASK
);
1308 macHeaderLengthInBytes
+= 6;
1312 unifi_warning(priv
, "prepare_and_add_macheader: Unknown mode %d\n",
1313 interfacePriv
->interfaceMode
);
1317 /* If Sta is QOS & HTC is supported then need to set 'order' bit */
1318 /* We don't support HT Control for now */
1321 fc
|= cpu_to_le16(IEEE802_11_FC_PROTECTED_MASK
);
1324 /* check the skb headroom before pushing mac header */
1325 headroom
= skb_headroom(skb
);
1327 if (headroom
< macHeaderLengthInBytes
) {
1328 unifi_trace(priv
, UDBG5
,
1329 "prepare_and_add_macheader: Allocate headroom extra %d bytes\n",
1330 macHeaderLengthInBytes
);
1332 csrResult
= unifi_net_data_malloc(priv
, &data_ptrs
.d
[0], skb
->len
+ macHeaderLengthInBytes
);
1334 if (csrResult
!= CSR_RESULT_SUCCESS
) {
1335 unifi_error(priv
, " failed to allocate request_data. in %s func\n", __FUNCTION__
);
1338 newSkb
= (struct sk_buff
*)(data_ptrs
.d
[0].os_net_buf_ptr
);
1339 newSkb
->len
= skb
->len
+ macHeaderLengthInBytes
;
1341 memcpy((void*)data_ptrs
.d
[0].os_data_ptr
+ macHeaderLengthInBytes
,
1342 skb
->data
, skb
->len
);
1344 bulkdata
->d
[0].os_data_ptr
= newSkb
->data
;
1345 bulkdata
->d
[0].os_net_buf_ptr
= (unsigned char*)newSkb
;
1346 bulkdata
->d
[0].data_length
= newSkb
->len
;
1348 bufPtr
= (u8
*)data_ptrs
.d
[0].os_data_ptr
;
1350 /* The old skb will not be used again */
1354 /* headroom has sufficient size, so will get proper pointer */
1355 bufPtr
= (u8
*)skb_push(skb
, macHeaderLengthInBytes
);
1356 bulkdata
->d
[0].os_data_ptr
= skb
->data
;
1357 bulkdata
->d
[0].os_net_buf_ptr
= (unsigned char*)skb
;
1358 bulkdata
->d
[0].data_length
= skb
->len
;
1361 /* Frame the actual MAC header */
1363 memset(bufPtr
, 0, macHeaderLengthInBytes
);
1365 /* copy frameControl field */
1366 memcpy(bufPtr
, &fc
, sizeof(fc
));
1367 bufPtr
+= sizeof(fc
);
1368 macHeaderLengthInBytes
-= sizeof(fc
);
1370 /* Duration/ID field which is 2 bytes */
1372 macHeaderLengthInBytes
-= 2;
1377 /* Its an Ad-Hoc no need to route it through AP */
1378 /* Address1: MAC address of the destination from eth header */
1379 memcpy(bufPtr
, daddr
, ETH_ALEN
);
1381 macHeaderLengthInBytes
-= ETH_ALEN
;
1383 /* Address2: MAC address of the source */
1384 memcpy(bufPtr
, saddr
, ETH_ALEN
);
1386 macHeaderLengthInBytes
-= ETH_ALEN
;
1388 /* Address3: the BSSID (locally generated in AdHoc (creators Bssid)) */
1389 memcpy(bufPtr
, &interfacePriv
->bssid
, ETH_ALEN
);
1391 macHeaderLengthInBytes
-= ETH_ALEN
;
1394 /* Address1: MAC address of the actual destination */
1395 memcpy(bufPtr
, daddr
, ETH_ALEN
);
1397 macHeaderLengthInBytes
-= ETH_ALEN
;
1398 /* Address2: The MAC address of the AP */
1399 memcpy(bufPtr
, &interfacePriv
->bssid
, ETH_ALEN
);
1401 macHeaderLengthInBytes
-= ETH_ALEN
;
1403 /* Address3: MAC address of the source from eth header */
1404 memcpy(bufPtr
, saddr
, ETH_ALEN
);
1406 macHeaderLengthInBytes
-= ETH_ALEN
;
1409 /* Address1: To AP is the MAC address of the AP to which its associated */
1410 memcpy(bufPtr
, &interfacePriv
->bssid
, ETH_ALEN
);
1412 macHeaderLengthInBytes
-= ETH_ALEN
;
1414 /* Address2: MAC address of the source from eth header */
1415 memcpy(bufPtr
, saddr
, ETH_ALEN
);
1417 macHeaderLengthInBytes
-= ETH_ALEN
;
1419 /* Address3: MAC address of the actual destination on the distribution system */
1420 memcpy(bufPtr
, daddr
, ETH_ALEN
);
1422 macHeaderLengthInBytes
-= ETH_ALEN
;
1425 memcpy(bufPtr
, &interfacePriv
->bssid
, ETH_ALEN
);
1427 macHeaderLengthInBytes
-= ETH_ALEN
;
1429 /* Address2: MAC address of the source from eth header */
1430 memcpy(bufPtr
, saddr
, ETH_ALEN
);
1432 macHeaderLengthInBytes
-= ETH_ALEN
;
1434 /* Address3: MAC address of the actual destination on the distribution system */
1435 memcpy(bufPtr
, daddr
, ETH_ALEN
);
1437 macHeaderLengthInBytes
-= ETH_ALEN
;
1440 unifi_error(priv
,"Unknown direction =%d : Not handled now\n",direction
);
1443 /* 2 bytes of frame control field, appended by firmware */
1445 macHeaderLengthInBytes
-= 2;
1447 if (3 == direction
) {
1448 /* Address4: MAC address of the source */
1449 memcpy(bufPtr
, saddr
, ETH_ALEN
);
1451 macHeaderLengthInBytes
-= ETH_ALEN
;
1454 /* IF Qos Data or Qos Null Data then set QosControl field */
1455 if ((priority
!= CSR_CONTENTION
) && (macHeaderLengthInBytes
>= QOS_CONTROL_HEADER_SIZE
)) {
1458 unifi_trace(priv
, UDBG1
, "data packets priority is more than 7, priority = %x\n", priority
);
1463 /*assigning address1
1464 * Address1 offset taken fromm bufPtr(currently bufPtr pointing to Qos contorl) variable in reverse direction
1465 * Address4 don't exit
1468 addressOne
= bufPtr
- ADDRESS_ONE_OFFSET
;
1470 if (addressOne
[0] & 0x1) {
1471 /* multicast/broadcast frames, no acknowledgement needed */
1474 /* non-AP mode only for now */
1475 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_STA
||
1476 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_IBSS
||
1477 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI
) {
1478 /* In case of STA and IBSS case eosp and txop limit is 0. */
1485 /* append Qos control field to mac header */
1487 /* txop limit is 0 */
1489 macHeaderLengthInBytes
-= QOS_CONTROL_HEADER_SIZE
;
1491 if (macHeaderLengthInBytes
) {
1492 unifi_warning(priv
, " Mac header not appended properly\n");
1499 * ---------------------------------------------------------------------------
1500 * send_ma_pkt_request
1502 * These functions send a data packet to UniFi for transmission.
1503 * EAP protocol packets are also sent as send_ma_pkt_request().
1506 * priv Pointer to device private context struct
1507 * skb Socket buffer containing data packet to transmit
1508 * ehdr Pointer to Ethernet header within skb.
1511 * Zero on success or error code.
1512 * ---------------------------------------------------------------------------
1516 send_ma_pkt_request(unifi_priv_t
*priv
, struct sk_buff
*skb
, const struct ethhdr
*ehdr
, CSR_PRIORITY priority
)
1520 u8 eapolStore
= FALSE
;
1521 struct sk_buff
*newSkb
= NULL
;
1522 bulk_data_param_t bulkdata
;
1523 const int proto
= ntohs(ehdr
->h_proto
);
1525 CsrWifiMacAddress peerAddress
;
1526 CSR_TRANSMISSION_CONTROL transmissionControl
= CSR_NO_CONFIRM_REQUIRED
;
1528 netInterface_priv_t
*interfacePriv
= NULL
;
1529 CSR_RATE TransmitRate
= (CSR_RATE
)0;
1531 unifi_trace(priv
, UDBG5
, "entering send_ma_pkt_request\n");
1533 /* Get the interface Tag by means of source Mac address */
1534 for (i
= 0; i
< CSR_WIFI_NUM_INTERFACES
; i
++) {
1535 if (!memcmp(priv
->netdev
[i
]->dev_addr
, ehdr
->h_source
, ETH_ALEN
)) {
1537 interfacePriv
= priv
->interfacePriv
[interfaceTag
];
1542 if (interfacePriv
== NULL
) {
1543 /* No match found - error */
1545 interfacePriv
= priv
->interfacePriv
[interfaceTag
];
1546 unifi_warning(priv
, "Mac address not matching ... debugging needed\n");
1547 interfacePriv
->stats
.tx_dropped
++;
1552 /* Add a SNAP header if necessary */
1553 if (skb_add_llc_snap(priv
->netdev
[interfaceTag
], skb
, proto
) != 0) {
1554 /* convert failed */
1555 unifi_error(priv
, "skb_add_llc_snap failed.\n");
1560 bulkdata
.d
[0].os_data_ptr
= skb
->data
;
1561 bulkdata
.d
[0].os_net_buf_ptr
= (unsigned char*)skb
;
1562 bulkdata
.d
[0].net_buf_length
= bulkdata
.d
[0].data_length
= skb
->len
;
1563 bulkdata
.d
[1].os_data_ptr
= NULL
;
1564 bulkdata
.d
[1].os_net_buf_ptr
= NULL
;
1565 bulkdata
.d
[1].net_buf_length
= bulkdata
.d
[1].data_length
= 0;
1567 #ifdef CSR_SUPPORT_SME
1568 /* Notify the TA module for the Tx frame for non AP/P2PGO mode*/
1569 if ((interfacePriv
->interfaceMode
!= CSR_WIFI_ROUTER_CTRL_MODE_AP
) &&
1570 (interfacePriv
->interfaceMode
!= CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
)) {
1571 unifi_ta_sample(priv
->card
, CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX
,
1572 &bulkdata
.d
[0], ehdr
->h_source
,
1573 priv
->netdev
[interfaceTag
]->dev_addr
,
1574 jiffies_to_msecs(jiffies
),
1575 0); /* rate is unknown on tx */
1577 #endif /* CSR_SUPPORT_SME */
1579 if ((proto
== ETH_P_PAE
)
1580 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1581 || (proto
== ETH_P_WAI
)
1585 /* check for m4 detection */
1586 if (0 == uf_verify_m4(priv
, bulkdata
.d
[0].os_data_ptr
, bulkdata
.d
[0].data_length
)) {
1591 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1592 if (proto
== ETH_P_WAI
)
1594 protection
= 0; /*WAI packets always sent unencrypted*/
1599 #ifdef CSR_SUPPORT_SME
1600 if ((protection
= uf_get_protection_bit_from_interfacemode(priv
, interfaceTag
, ehdr
->h_dest
)) < 0) {
1601 unifi_warning(priv
, "unicast address, but destination not in station record database\n");
1602 unifi_net_data_free(priv
, &bulkdata
.d
[0]);
1608 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1612 /* append Mac header for Eapol as well as data packet */
1613 if (prepare_and_add_macheader(priv
, skb
, newSkb
, priority
, &bulkdata
, interfaceTag
, ehdr
->h_dest
, ehdr
->h_source
, protection
)) {
1614 unifi_error(priv
, "failed to create MAC header\n");
1615 unifi_net_data_free(priv
, &bulkdata
.d
[0]);
1619 /* RA adrress must contain the immediate destination MAC address that is similiar to
1620 * the Address 1 field of 802.11 Mac header here 4 is: (sizeof(framecontrol) + sizeof (durationID))
1621 * which is address 1 field
1623 memcpy(peerAddress
.a
, ((u8
*) bulkdata
.d
[0].os_data_ptr
) + 4, ETH_ALEN
);
1625 unifi_trace(priv
, UDBG5
, "RA[0]=%x, RA[1]=%x, RA[2]=%x, RA[3]=%x, RA[4]=%x, RA[5]=%x\n",
1626 peerAddress
.a
[0],peerAddress
.a
[1], peerAddress
.a
[2], peerAddress
.a
[3],
1627 peerAddress
.a
[4],peerAddress
.a
[5]);
1630 if ((proto
== ETH_P_PAE
)
1631 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1632 || (proto
== ETH_P_WAI
)
1637 CSR_MA_PACKET_REQUEST
*req
= &signal
.u
.MaPacketRequest
;
1639 /* initialize signal to zero */
1640 memset(&signal
, 0, sizeof(CSR_SIGNAL
));
1642 /* Frame MA_PACKET request */
1643 signal
.SignalPrimitiveHeader
.SignalId
= CSR_MA_PACKET_REQUEST_ID
;
1644 signal
.SignalPrimitiveHeader
.ReceiverProcessId
= 0;
1645 signal
.SignalPrimitiveHeader
.SenderProcessId
= priv
->netdev_client
->sender_id
;
1647 transmissionControl
= req
->TransmissionControl
= 0;
1648 #ifdef CSR_SUPPORT_SME
1651 netInterface_priv_t
*netpriv
= (netInterface_priv_t
*)netdev_priv(priv
->netdev
[interfaceTag
]);
1653 /* Fill the MA-PACKET.req */
1655 req
->Priority
= priority
;
1656 unifi_trace(priv
, UDBG3
, "Tx Frame with Priority: %x\n", req
->Priority
);
1658 /* rate selected by firmware */
1659 req
->TransmitRate
= 0;
1660 req
->HostTag
= CSR_WIFI_EAPOL_M4_HOST_TAG
;
1661 /* RA address matching with address 1 of Mac header */
1662 memcpy(req
->Ra
.x
, ((u8
*) bulkdata
.d
[0].os_data_ptr
) + 4, ETH_ALEN
);
1664 spin_lock(&priv
->m4_lock
);
1665 /* Store the M4-PACKET.req for later */
1666 interfacePriv
->m4_signal
= signal
;
1667 interfacePriv
->m4_bulk_data
.net_buf_length
= bulkdata
.d
[0].net_buf_length
;
1668 interfacePriv
->m4_bulk_data
.data_length
= bulkdata
.d
[0].data_length
;
1669 interfacePriv
->m4_bulk_data
.os_data_ptr
= bulkdata
.d
[0].os_data_ptr
;
1670 interfacePriv
->m4_bulk_data
.os_net_buf_ptr
= bulkdata
.d
[0].os_net_buf_ptr
;
1671 spin_unlock(&priv
->m4_lock
);
1673 /* Signal the workqueue to call CsrWifiRouterCtrlM4ReadyToSendIndSend().
1674 * It cannot be called directly from the tx path because it
1675 * does a non-atomic kmalloc via the framework's CsrPmemAlloc().
1677 queue_work(priv
->unifi_workqueue
, &netpriv
->send_m4_ready_task
);
1682 }/*EAPOL or WAI packet*/
1684 #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
1685 if ((CSR_WIFI_ROUTER_CTRL_MODE_STA
== interfacePriv
->interfaceMode
) && \
1686 (priv
->wapi_unicast_filter
) && \
1687 (proto
!= ETH_P_PAE
) && \
1688 (proto
!= ETH_P_WAI
) && \
1692 CSR_MA_PACKET_REQUEST
*req
= &signal
.u
.MaPacketRequest
;
1693 netInterface_priv_t
*netpriv
= (netInterface_priv_t
*)netdev_priv(priv
->netdev
[interfaceTag
]);
1695 unifi_trace(priv
, UDBG4
, "send_ma_pkt_request() - WAPI unicast data packet when USKID = 1 \n");
1697 /* initialize signal to zero */
1698 memset(&signal
, 0, sizeof(CSR_SIGNAL
));
1699 /* Frame MA_PACKET request */
1700 signal
.SignalPrimitiveHeader
.SignalId
= CSR_MA_PACKET_REQUEST_ID
;
1701 signal
.SignalPrimitiveHeader
.ReceiverProcessId
= 0;
1702 signal
.SignalPrimitiveHeader
.SenderProcessId
= priv
->netdev_client
->sender_id
;
1704 /* Fill the MA-PACKET.req */
1705 req
->TransmissionControl
= 0;
1706 req
->Priority
= priority
;
1707 unifi_trace(priv
, UDBG3
, "Tx Frame with Priority: %x\n", req
->Priority
);
1708 req
->TransmitRate
= (CSR_RATE
) 0; /* rate selected by firmware */
1709 req
->HostTag
= 0xffffffff; /* Ask for a new HostTag */
1710 /* RA address matching with address 1 of Mac header */
1711 memcpy(req
->Ra
.x
, ((u8
*) bulkdata
.d
[0].os_data_ptr
) + 4, ETH_ALEN
);
1713 /* Store the M4-PACKET.req for later */
1714 spin_lock(&priv
->wapi_lock
);
1715 interfacePriv
->wapi_unicast_ma_pkt_sig
= signal
;
1716 interfacePriv
->wapi_unicast_bulk_data
.net_buf_length
= bulkdata
.d
[0].net_buf_length
;
1717 interfacePriv
->wapi_unicast_bulk_data
.data_length
= bulkdata
.d
[0].data_length
;
1718 interfacePriv
->wapi_unicast_bulk_data
.os_data_ptr
= bulkdata
.d
[0].os_data_ptr
;
1719 interfacePriv
->wapi_unicast_bulk_data
.os_net_buf_ptr
= bulkdata
.d
[0].os_net_buf_ptr
;
1720 spin_unlock(&priv
->wapi_lock
);
1722 /* Signal the workqueue to call CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend().
1723 * It cannot be called directly from the tx path because it
1724 * does a non-atomic kmalloc via the framework's CsrPmemAlloc().
1726 queue_work(priv
->unifi_workqueue
, &netpriv
->send_pkt_to_encrypt
);
1732 if(priv
->cmanrTestMode
)
1734 TransmitRate
= priv
->cmanrTestModeTransmitRate
;
1735 unifi_trace(priv
, UDBG2
, "send_ma_pkt_request: cmanrTestModeTransmitRate = %d TransmitRate=%d\n",
1736 priv
->cmanrTestModeTransmitRate
,
1741 /* Send UniFi msg */
1742 /* Here hostTag is been sent as 0xffffffff, its been appended properly while framing MA-Packet request in pdu_processing.c file */
1743 r
= uf_process_ma_packet_req(priv
,
1745 0xffffffff, /* Ask for a new HostTag */
1747 transmissionControl
,
1750 priv
->netdev_client
->sender_id
,
1754 unifi_trace(priv
, UDBG1
, "(HIP validation failure) r = %x\n", r
);
1755 unifi_net_data_free(priv
, &bulkdata
.d
[0]);
1759 unifi_trace(priv
, UDBG3
, "leaving send_ma_pkt_request, UNITDATA result code = %d\n", r
);
1762 } /* send_ma_pkt_request() */
1765 * ---------------------------------------------------------------------------
1768 * This function is called by the higher level stack to transmit an
1772 * skb Ethernet packet to send.
1773 * dev Pointer to the linux net device.
1776 * 0 on success (packet was consumed, not necessarily transmitted)
1777 * 1 if packet was requeued
1782 * The controlled port is handled in the qdisc dequeue handler.
1783 * ---------------------------------------------------------------------------
1786 uf_net_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
1788 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
1789 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
1793 static tx_signal_handler tx_handler
;
1794 CSR_PRIORITY priority
;
1795 CsrWifiRouterCtrlPortAction port_action
;
1799 unifi_trace(priv
, UDBG5
, "unifi_net_xmit: skb = %x\n", skb
);
1801 memcpy(&ehdr
, skb
->data
, ETH_HLEN
);
1802 proto
= ntohs(ehdr
.h_proto
);
1803 priority
= get_packet_priority(priv
, skb
, &ehdr
, interfacePriv
);
1805 /* All frames are sent as MA-PACKET.req (EAPOL also) */
1806 tx_handler
= send_ma_pkt_request
;
1808 /* 802.1x - apply controlled/uncontrolled port rules */
1809 if ((proto
!= ETH_P_PAE
)
1810 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1811 && (proto
!= ETH_P_WAI
)
1814 port
= UF_CONTROLLED_PORT_Q
;
1817 port
= UF_UNCONTROLLED_PORT_Q
;
1820 /* Uncontrolled port rules apply */
1821 port_action
= verify_port(priv
1822 , (((CSR_WIFI_ROUTER_CTRL_MODE_STA
== interfacePriv
->interfaceMode
)||(CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI
== interfacePriv
->interfaceMode
))? interfacePriv
->bssid
.a
: ehdr
.h_dest
)
1824 , interfacePriv
->InterfaceTag
);
1826 if (port_action
== CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN
) {
1827 unifi_trace(priv
, UDBG5
,
1828 "uf_net_xmit: %s controlled port open\n",
1830 /* Remove the ethernet header */
1831 skb_pull(skb
, ETH_HLEN
);
1832 result
= tx_handler(priv
, skb
, &ehdr
, priority
);
1835 /* Discard the packet if necessary */
1836 unifi_trace(priv
, UDBG2
,
1837 "uf_net_xmit: %s controlled port %s\n",
1838 port
? "" : "un", port_action
==CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK
? "blocked" : "closed");
1839 interfacePriv
->stats
.tx_dropped
++;
1843 return NETDEV_TX_OK
;
1846 if (result
== NETDEV_TX_OK
) {
1847 #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
1848 /* Don't update the tx stats when the pkt is to be sent for sw encryption*/
1849 if (!((CSR_WIFI_ROUTER_CTRL_MODE_STA
== interfacePriv
->interfaceMode
) &&
1850 (priv
->wapi_unicast_filter
== 1)))
1852 dev
->trans_start
= jiffies
;
1853 /* Should really count tx stats in the UNITDATA.status signal but
1854 * that doesn't have the length.
1856 interfacePriv
->stats
.tx_packets
++;
1857 /* count only the packet payload */
1858 interfacePriv
->stats
.tx_bytes
+= skb
->len
;
1862 dev
->trans_start
= jiffies
;
1865 * Should really count tx stats in the UNITDATA.status signal but
1866 * that doesn't have the length.
1868 interfacePriv
->stats
.tx_packets
++;
1869 /* count only the packet payload */
1870 interfacePriv
->stats
.tx_bytes
+= skb
->len
;
1872 } else if (result
< 0) {
1874 /* Failed to send: fh queue was full, and the skb was discarded.
1875 * Return OK to indicate that the buffer was consumed, to stop the
1876 * kernel re-transmitting the freed buffer.
1878 interfacePriv
->stats
.tx_dropped
++;
1879 unifi_trace(priv
, UDBG1
, "unifi_net_xmit: (Packet Drop), dropped count = %x\n", interfacePriv
->stats
.tx_dropped
);
1880 result
= NETDEV_TX_OK
;
1883 /* The skb will have been freed by send_XXX_request() */
1887 } /* uf_net_xmit() */
1890 * ---------------------------------------------------------------------------
1892 * unifi_restart_xmit
1894 * These functions are called from the UniFi core to control the flow
1895 * of packets from the upper layers.
1896 * unifi_pause_xmit() is called when the internal queue is full and
1897 * should take action to stop unifi_ma_unitdata() being called.
1898 * When the queue has drained, unifi_restart_xmit() will be called to
1899 * re-enable the flow of packets for transmission.
1902 * ospriv OS private context pointer.
1905 * unifi_pause_xmit() is called from interrupt context.
1906 * ---------------------------------------------------------------------------
1909 unifi_pause_xmit(void *ospriv
, unifi_TrafficQueue queue
)
1911 unifi_priv_t
*priv
= ospriv
;
1912 int i
; /* used as a loop counter */
1915 unifi_trace(priv
, UDBG2
, "Stopping queue %d\n", queue
);
1917 for(i
=0;i
<CSR_WIFI_NUM_INTERFACES
;i
++)
1919 if (netif_running(priv
->netdev
[i
]))
1921 netif_stop_subqueue(priv
->netdev
[i
], (u16
)queue
);
1925 #ifdef CSR_SUPPORT_SME
1927 routerStartBuffering(priv
,queue
);
1928 unifi_trace(priv
,UDBG2
,"Start buffering %d\n", queue
);
1930 routerStartBuffering(priv
,0);
1931 unifi_error(priv
, "Start buffering %d defaulting to 0\n", queue
);
1936 } /* unifi_pause_xmit() */
1939 unifi_restart_xmit(void *ospriv
, unifi_TrafficQueue queue
)
1941 unifi_priv_t
*priv
= ospriv
;
1942 int i
=0; /* used as a loop counter */
1945 unifi_trace(priv
, UDBG2
, "Waking queue %d\n", queue
);
1947 for(i
=0;i
<CSR_WIFI_NUM_INTERFACES
;i
++)
1949 if (netif_running(priv
->netdev
[i
]))
1951 netif_wake_subqueue(priv
->netdev
[i
], (u16
)queue
);
1955 #ifdef CSR_SUPPORT_SME
1957 routerStopBuffering(priv
,queue
);
1958 uf_send_buffered_frames(priv
,queue
);
1960 routerStopBuffering(priv
,0);
1961 uf_send_buffered_frames(priv
,0);
1965 } /* unifi_restart_xmit() */
1969 indicate_rx_skb(unifi_priv_t
*priv
, u16 ifTag
, u8
* dst_a
, u8
* src_a
, struct sk_buff
*skb
, CSR_SIGNAL
*signal
,
1970 bulk_data_param_t
*bulkdata
)
1973 struct net_device
*dev
;
1975 #ifdef CSR_SUPPORT_SME
1976 llc_snap_hdr_t
*snap
;
1978 snap
= (llc_snap_hdr_t
*)skb
->data
;
1980 sr
= _identify_sme_ma_pkt_ind(priv
,
1981 snap
->oui
, ntohs(snap
->protocol
),
1988 * Decapsulate any SNAP header and
1989 * prepend an ethernet header so that the skb manipulation and ARP
1992 r
= skb_80211_to_ether(priv
, skb
, dst_a
, src_a
,
1995 /* Drop the packet and return */
1996 priv
->interfacePriv
[ifTag
]->stats
.rx_errors
++;
1997 priv
->interfacePriv
[ifTag
]->stats
.rx_frame_errors
++;
1998 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
1999 unifi_notice(priv
, "indicate_rx_skb: Discard unknown frame.\n");
2004 /* Handle the case where packet is sent up through the subscription
2005 * API but should not be given to the network stack (AMP PAL case)
2006 * LLC header is different from WiFi and the packet has been subscribed for
2008 if (r
== 1 && sr
== 1) {
2009 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2010 unifi_trace(priv
, UDBG5
, "indicate_rx_skb: Data given to subscription"
2011 "API, not being given to kernel\n");
2016 dev
= priv
->netdev
[ifTag
];
2017 /* Now we look like a regular ethernet frame */
2018 /* Fill in SKB meta data */
2020 skb
->protocol
= eth_type_trans(skb
, dev
);
2021 skb
->ip_summed
= CHECKSUM_UNNECESSARY
;
2023 /* Test for an overlength frame */
2024 if (skb
->len
> (dev
->mtu
+ ETH_HLEN
)) {
2025 /* A bogus length ethfrm has been encap'd. */
2026 /* Is someone trying an oflow attack? */
2027 unifi_error(priv
, "%s: oversize frame (%d > %d)\n",
2029 skb
->len
, dev
->mtu
+ ETH_HLEN
);
2031 /* Drop the packet and return */
2032 priv
->interfacePriv
[ifTag
]->stats
.rx_errors
++;
2033 priv
->interfacePriv
[ifTag
]->stats
.rx_length_errors
++;
2034 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2040 if(priv
->cmanrTestMode
)
2042 const CSR_MA_PACKET_INDICATION
*pkt_ind
= &signal
->u
.MaPacketIndication
;
2043 priv
->cmanrTestModeTransmitRate
= pkt_ind
->ReceivedRate
;
2044 unifi_trace(priv
, UDBG2
, "indicate_rx_skb: cmanrTestModeTransmitRate=%d\n", priv
->cmanrTestModeTransmitRate
);
2047 /* Pass SKB up the stack */
2048 #ifdef CSR_WIFI_USE_NETIF_RX
2055 dev
->last_rx
= jiffies
;
2059 priv
->interfacePriv
[ifTag
]->stats
.rx_packets
++;
2060 priv
->interfacePriv
[ifTag
]->stats
.rx_bytes
+= bulkdata
->d
[0].data_length
;
2067 uf_process_rx_pending_queue(unifi_priv_t
*priv
, int queue
,
2068 CsrWifiMacAddress source_address
,
2069 int indicate
, u16 interfaceTag
)
2071 rx_buffered_packets_t
*rx_q_item
;
2072 struct list_head
*rx_list
;
2073 struct list_head
*n
;
2074 struct list_head
*l_h
;
2075 static const CsrWifiMacAddress broadcast_address
= {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
2076 netInterface_priv_t
*interfacePriv
= priv
->interfacePriv
[interfaceTag
];
2078 if (interfaceTag
>= CSR_WIFI_NUM_INTERFACES
) {
2079 unifi_error(priv
, "uf_process_rx_pending_queue bad interfaceTag\n");
2083 if (queue
== UF_CONTROLLED_PORT_Q
) {
2084 rx_list
= &interfacePriv
->rx_controlled_list
;
2086 rx_list
= &interfacePriv
->rx_uncontrolled_list
;
2089 down(&priv
->rx_q_sem
);
2090 list_for_each_safe(l_h
, n
, rx_list
) {
2091 rx_q_item
= list_entry(l_h
, rx_buffered_packets_t
, q
);
2093 /* Validate against the source address */
2094 if (memcmp(broadcast_address
.a
, source_address
.a
, ETH_ALEN
) &&
2095 memcmp(rx_q_item
->sa
.a
, source_address
.a
, ETH_ALEN
)) {
2097 unifi_trace(priv
, UDBG2
,
2098 "uf_process_rx_pending_queue: Skipping sa=%02X%02X%02X%02X%02X%02X skb=%p, bulkdata=%p\n",
2099 rx_q_item
->sa
.a
[0], rx_q_item
->sa
.a
[1],
2100 rx_q_item
->sa
.a
[2], rx_q_item
->sa
.a
[3],
2101 rx_q_item
->sa
.a
[4], rx_q_item
->sa
.a
[5],
2102 rx_q_item
->skb
, &rx_q_item
->bulkdata
.d
[0]);
2109 unifi_trace(priv
, UDBG2
,
2110 "uf_process_rx_pending_queue: Was Blocked skb=%p, bulkdata=%p\n",
2111 rx_q_item
->skb
, &rx_q_item
->bulkdata
);
2114 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
);
2116 interfacePriv
->stats
.rx_dropped
++;
2117 unifi_net_data_free(priv
, &rx_q_item
->bulkdata
.d
[0]);
2120 /* It is our resposibility to free the Rx structure object. */
2123 up(&priv
->rx_q_sem
);
2127 * ---------------------------------------------------------------------------
2128 * uf_resume_data_plane
2130 * Is called when the (un)controlled port is set to open,
2131 * to notify the network stack to schedule for transmission
2132 * any packets queued in the qdisk while port was closed and
2133 * indicated to the stack any packets buffered in the Rx queues.
2136 * priv Pointer to device private struct
2139 * ---------------------------------------------------------------------------
2142 uf_resume_data_plane(unifi_priv_t
*priv
, int queue
,
2143 CsrWifiMacAddress peer_address
,
2146 #ifdef CSR_SUPPORT_WEXT
2147 netInterface_priv_t
*interfacePriv
= priv
->interfacePriv
[interfaceTag
];
2150 if (interfaceTag
>= CSR_WIFI_NUM_INTERFACES
) {
2151 unifi_error(priv
, "uf_resume_data_plane bad interfaceTag\n");
2155 unifi_trace(priv
, UDBG2
, "Resuming netif\n");
2158 * If we are waiting for the net device to enter the up state, don't
2159 * process the rx queue yet as it will be done by the callback when
2160 * the device is ready.
2162 #ifdef CSR_SUPPORT_WEXT
2163 if (!interfacePriv
->wait_netdev_change
)
2166 #ifdef CONFIG_NET_SCHED
2167 if (netif_running(priv
->netdev
[interfaceTag
])) {
2168 netif_tx_schedule_all(priv
->netdev
[interfaceTag
]);
2171 uf_process_rx_pending_queue(priv
, queue
, peer_address
, 1,interfaceTag
);
2173 } /* uf_resume_data_plane() */
2176 void uf_free_pending_rx_packets(unifi_priv_t
*priv
, int queue
, CsrWifiMacAddress peer_address
,u16 interfaceTag
)
2178 uf_process_rx_pending_queue(priv
, queue
, peer_address
, 0,interfaceTag
);
2180 } /* uf_free_pending_rx_packets() */
2184 * ---------------------------------------------------------------------------
2187 * Reformat a UniFi data received packet into a p80211 packet and
2188 * pass it up the protocol stack.
2195 * ---------------------------------------------------------------------------
2198 unifi_rx(unifi_priv_t
*priv
, CSR_SIGNAL
*signal
, bulk_data_param_t
*bulkdata
)
2201 bulk_data_desc_t
*pData
;
2202 const CSR_MA_PACKET_INDICATION
*pkt_ind
= &signal
->u
.MaPacketIndication
;
2203 struct sk_buff
*skb
;
2204 CsrWifiRouterCtrlPortAction port_action
;
2209 u8 da
[ETH_ALEN
], sa
[ETH_ALEN
];
2210 u8 toDs
, fromDs
, frameType
, macHeaderLengthInBytes
= MAC_HEADER_SIZE
;
2212 netInterface_priv_t
*interfacePriv
;
2217 interfaceTag
= (pkt_ind
->VirtualInterfaceIdentifier
& 0xff);
2218 interfacePriv
= priv
->interfacePriv
[interfaceTag
];
2220 /* Sanity check that the VIF refers to a sensible interface */
2221 if (interfaceTag
>= CSR_WIFI_NUM_INTERFACES
)
2223 unifi_error(priv
, "%s: MA-PACKET indication with bad interfaceTag %d\n", __FUNCTION__
, interfaceTag
);
2224 unifi_net_data_free(priv
,&bulkdata
->d
[0]);
2229 /* Sanity check that the VIF refers to an allocated netdev */
2230 if (!interfacePriv
->netdev_registered
)
2232 unifi_error(priv
, "%s: MA-PACKET indication with unallocated interfaceTag %d\n", __FUNCTION__
, interfaceTag
);
2233 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2238 if (bulkdata
->d
[0].data_length
== 0) {
2239 unifi_warning(priv
, "%s: MA-PACKET indication with zero bulk data\n", __FUNCTION__
);
2240 unifi_net_data_free(priv
,&bulkdata
->d
[0]);
2246 skb
= (struct sk_buff
*)bulkdata
->d
[0].os_net_buf_ptr
;
2247 skb
->len
= bulkdata
->d
[0].data_length
;
2249 /* Point to the addresses */
2250 toDs
= (skb
->data
[1] & 0x01) ? 1 : 0;
2251 fromDs
= (skb
->data
[1] & 0x02) ? 1 : 0;
2253 memcpy(da
,(skb
->data
+4+toDs
*12),ETH_ALEN
);/* Address1 or 3 */
2254 memcpy(sa
,(skb
->data
+10+fromDs
*(6+toDs
*8)),ETH_ALEN
); /* Address2, 3 or 4 */
2257 pData
= &bulkdata
->d
[0];
2258 frameControl
= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData
->os_data_ptr
);
2259 frameType
= ((frameControl
& 0x000C) >> 2);
2261 dataFrameType
=((frameControl
& 0x00f0) >> 4);
2262 unifi_trace(priv
, UDBG6
,
2263 "%s: Receive Data Frame Type %d \n", __FUNCTION__
,dataFrameType
);
2265 switch(dataFrameType
)
2269 /* If both are set then the Address4 exists (only for AP) */
2272 /* 6 is the size of Address4 field */
2273 macHeaderLengthInBytes
+= (QOS_CONTROL_HEADER_SIZE
+ 6);
2277 macHeaderLengthInBytes
+= QOS_CONTROL_HEADER_SIZE
;
2280 /* If order bit set then HT control field is the part of MAC header */
2281 if (frameControl
& FRAME_CONTROL_ORDER_BIT
)
2282 macHeaderLengthInBytes
+= HT_CONTROL_HEADER_SIZE
;
2286 macHeaderLengthInBytes
+= 6;
2289 /* Prepare the ethernet header from snap header of skb data */
2290 switch(dataFrameType
)
2294 /* This is for only queue info fetching, EAPOL wont come as
2295 * null data so the proto is initialized as zero
2301 llc_snap_hdr_t
*snap
;
2302 /* Fetch a snap header to find protocol (for IPV4/IPV6 packets
2303 * the snap header fetching offset is same)
2305 snap
= (llc_snap_hdr_t
*) (skb
->data
+ macHeaderLengthInBytes
);
2307 /* prepare the ethernet header from the snap header & addresses */
2308 ehdr
.h_proto
= snap
->protocol
;
2309 memcpy(ehdr
.h_dest
, da
, ETH_ALEN
);
2310 memcpy(ehdr
.h_source
, sa
, ETH_ALEN
);
2312 proto
= ntohs(ehdr
.h_proto
);
2314 unifi_trace(priv
, UDBG3
, "in unifi_rx protocol from snap header = 0x%x\n", proto
);
2316 if ((proto
!= ETH_P_PAE
)
2317 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
2318 && (proto
!= ETH_P_WAI
)
2321 queue
= UF_CONTROLLED_PORT_Q
;
2323 queue
= UF_UNCONTROLLED_PORT_Q
;
2326 port_action
= verify_port(priv
, (unsigned char*)sa
, queue
, interfaceTag
);
2327 unifi_trace(priv
, UDBG3
, "in unifi_rx port action is = 0x%x & queue = %x\n", port_action
, queue
);
2329 #ifdef CSR_SUPPORT_SME
2330 /* Notify the TA module for the Rx frame for non P2PGO and AP cases*/
2331 if((interfacePriv
->interfaceMode
!= CSR_WIFI_ROUTER_CTRL_MODE_AP
) &&
2332 (interfacePriv
->interfaceMode
!= CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
))
2334 /* Remove MAC header of length(macHeaderLengthInBytes) before sampling */
2335 skb_pull(skb
, macHeaderLengthInBytes
);
2336 pData
->os_data_ptr
= skb
->data
;
2337 pData
->data_length
-= macHeaderLengthInBytes
;
2339 if (pData
->data_length
) {
2340 unifi_ta_sample(priv
->card
, CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_RX
,
2342 sa
, priv
->netdev
[interfaceTag
]->dev_addr
,
2343 jiffies_to_msecs(jiffies
),
2344 pkt_ind
->ReceivedRate
);
2348 /* AP/P2PGO specific handling here */
2349 CsrWifiRouterCtrlStaInfo_t
* srcStaInfo
=
2350 CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv
,sa
,interfaceTag
);
2352 /* Defensive check only; Source address is already checked in
2353 process_ma_packet_ind and we should have a valid source address here */
2355 if(srcStaInfo
== NULL
) {
2356 CsrWifiMacAddress peerMacAddress
;
2357 /* Unknown data PDU */
2358 memcpy(peerMacAddress
.a
,sa
,ETH_ALEN
);
2359 unifi_trace(priv
, UDBG1
, "%s: Unexpected frame from peer = %x:%x:%x:%x:%x:%x\n", __FUNCTION__
,
2360 sa
[0], sa
[1],sa
[2], sa
[3], sa
[4],sa
[5]);
2361 CsrWifiRouterCtrlUnexpectedFrameIndSend(priv
->CSR_WIFI_SME_IFACEQUEUE
,0,interfaceTag
,peerMacAddress
);
2362 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2367 /* For AP GO mode, don't store the PDUs */
2368 if (port_action
!= CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN
) {
2369 /* Drop the packet and return */
2370 CsrWifiMacAddress peerMacAddress
;
2371 memcpy(peerMacAddress
.a
,sa
,ETH_ALEN
);
2372 unifi_trace(priv
, UDBG3
, "%s: Port is not open: unexpected frame from peer = %x:%x:%x:%x:%x:%x\n",
2373 __FUNCTION__
, sa
[0], sa
[1],sa
[2], sa
[3], sa
[4],sa
[5]);
2375 CsrWifiRouterCtrlUnexpectedFrameIndSend(priv
->CSR_WIFI_SME_IFACEQUEUE
,0,interfaceTag
,peerMacAddress
);
2376 interfacePriv
->stats
.rx_dropped
++;
2377 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2378 unifi_notice(priv
, "%s: Dropping packet, proto=0x%04x, %s port\n", __FUNCTION__
,
2379 proto
, queue
? "Controlled" : "Un-controlled");
2384 /* Qos NULL/Data NULL are freed here and not processed further */
2385 if((dataFrameType
== QOS_DATA_NULL
) || (dataFrameType
== DATA_NULL
)){
2386 unifi_trace(priv
, UDBG5
, "%s: Null Frame Received and Freed\n", __FUNCTION__
);
2387 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2392 /* Now we have done with MAC header so proceed with the real data part*/
2393 /* This function takes care of appropriate routing for AP/P2PGO case*/
2394 /* the function hadnles following things
2395 2. Routing the PDU to appropriate location
2396 3. Error case handling
2398 if(!(uf_ap_process_data_pdu(priv
, skb
, &ehdr
, srcStaInfo
,
2401 macHeaderLengthInBytes
)))
2406 unifi_trace(priv
, UDBG5
, "unifi_rx: no specific AP handling process as normal frame, MAC Header len %d\n",macHeaderLengthInBytes
);
2407 /* Remove the MAC header for subsequent conversion */
2408 skb_pull(skb
, macHeaderLengthInBytes
);
2409 pData
->os_data_ptr
= skb
->data
;
2410 pData
->data_length
-= macHeaderLengthInBytes
;
2411 pData
->os_net_buf_ptr
= (unsigned char*)skb
;
2412 pData
->net_buf_length
= skb
->len
;
2414 #endif /* CSR_SUPPORT_SME */
2417 /* Now that the MAC header is removed, null-data frames have zero length
2418 * and can be dropped
2420 if (pData
->data_length
== 0) {
2421 if (((frameControl
& 0x00f0) >> 4) != QOS_DATA_NULL
&&
2422 ((frameControl
& 0x00f0) >> 4) != DATA_NULL
) {
2423 unifi_trace(priv
, UDBG1
, "Zero length frame, but not null-data %04x\n", frameControl
);
2425 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2430 if (port_action
== CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD
) {
2431 /* Drop the packet and return */
2432 interfacePriv
->stats
.rx_dropped
++;
2433 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2434 unifi_notice(priv
, "%s: Dropping packet, proto=0x%04x, %s port\n",
2435 __FUNCTION__
, proto
, queue
? "controlled" : "uncontrolled");
2438 } else if ( (port_action
== CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK
) ||
2439 (interfacePriv
->connected
!= UnifiConnected
) ) {
2441 /* Buffer the packet into the Rx queues */
2442 rx_buffered_packets_t
*rx_q_item
;
2443 struct list_head
*rx_list
;
2445 rx_q_item
= (rx_buffered_packets_t
*)kmalloc(sizeof(rx_buffered_packets_t
),
2447 if (rx_q_item
== NULL
) {
2448 unifi_error(priv
, "%s: Failed to allocate %d bytes for rx packet record\n",
2449 __FUNCTION__
, sizeof(rx_buffered_packets_t
));
2450 interfacePriv
->stats
.rx_dropped
++;
2451 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2456 INIT_LIST_HEAD(&rx_q_item
->q
);
2457 rx_q_item
->bulkdata
= *bulkdata
;
2458 rx_q_item
->skb
= skb
;
2459 rx_q_item
->signal
= *signal
;
2460 memcpy(rx_q_item
->sa
.a
, sa
, ETH_ALEN
);
2461 memcpy(rx_q_item
->da
.a
, da
, ETH_ALEN
);
2462 unifi_trace(priv
, UDBG2
, "%s: Blocked skb=%p, bulkdata=%p\n",
2463 __FUNCTION__
, rx_q_item
->skb
, &rx_q_item
->bulkdata
);
2465 if (queue
== UF_CONTROLLED_PORT_Q
) {
2466 rx_list
= &interfacePriv
->rx_controlled_list
;
2468 rx_list
= &interfacePriv
->rx_uncontrolled_list
;
2471 /* Add to tail of packets queue */
2472 down(&priv
->rx_q_sem
);
2473 list_add_tail(&rx_q_item
->q
, rx_list
);
2474 up(&priv
->rx_q_sem
);
2481 indicate_rx_skb(priv
, interfaceTag
, da
, sa
, skb
, signal
, bulkdata
);
2487 static void process_ma_packet_cfm(unifi_priv_t
*priv
, CSR_SIGNAL
*signal
, bulk_data_param_t
*bulkdata
)
2490 const CSR_MA_PACKET_CONFIRM
*pkt_cfm
= &signal
->u
.MaPacketConfirm
;
2491 netInterface_priv_t
*interfacePriv
;
2494 interfaceTag
= (pkt_cfm
->VirtualInterfaceIdentifier
& 0xff);
2495 interfacePriv
= priv
->interfacePriv
[interfaceTag
];
2497 /* Sanity check that the VIF refers to a sensible interface */
2498 if (interfaceTag
>= CSR_WIFI_NUM_INTERFACES
)
2500 unifi_error(priv
, "%s: MA-PACKET confirm with bad interfaceTag %d\n", __FUNCTION__
, interfaceTag
);
2504 #ifdef CSR_SUPPORT_SME
2505 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
2506 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
2508 uf_process_ma_pkt_cfm_for_ap(priv
,interfaceTag
,pkt_cfm
);
2509 } else if (interfacePriv
->m4_sent
&& (pkt_cfm
->HostTag
== interfacePriv
->m4_hostTag
)) {
2510 /* Check if this is a confirm for EAPOL M4 frame and we need to send transmistted ind*/
2511 CsrResult result
= pkt_cfm
->TransmissionStatus
== CSR_TX_SUCCESSFUL
?CSR_RESULT_SUCCESS
:CSR_RESULT_FAILURE
;
2512 CsrWifiMacAddress peerMacAddress
;
2513 memcpy(peerMacAddress
.a
, interfacePriv
->m4_signal
.u
.MaPacketRequest
.Ra
.x
, ETH_ALEN
);
2515 unifi_trace(priv
, UDBG1
, "%s: Sending M4 Transmit CFM\n", __FUNCTION__
);
2516 CsrWifiRouterCtrlM4TransmittedIndSend(priv
->CSR_WIFI_SME_IFACEQUEUE
, 0,
2520 interfacePriv
->m4_sent
= FALSE
;
2521 interfacePriv
->m4_hostTag
= 0xffffffff;
2530 * ---------------------------------------------------------------------------
2533 * Reformat a UniFi data received packet into a p80211 packet and
2534 * pass it up the protocol stack.
2541 * ---------------------------------------------------------------------------
2543 static void process_ma_packet_ind(unifi_priv_t
*priv
, CSR_SIGNAL
*signal
, bulk_data_param_t
*bulkdata
)
2546 bulk_data_desc_t
*pData
;
2547 CSR_MA_PACKET_INDICATION
*pkt_ind
= (CSR_MA_PACKET_INDICATION
*)&signal
->u
.MaPacketIndication
;
2548 struct sk_buff
*skb
;
2550 netInterface_priv_t
*interfacePriv
;
2551 u8 da
[ETH_ALEN
], sa
[ETH_ALEN
];
2552 u8
*bssid
= NULL
, *ba_addr
= NULL
;
2553 u8 toDs
, fromDs
, frameType
;
2556 #ifdef CSR_SUPPORT_SME
2557 u8 dataFrameType
= 0;
2558 u8 powerSaveChanged
= FALSE
;
2560 CsrWifiRouterCtrlStaInfo_t
*srcStaInfo
= NULL
;
2567 interfaceTag
= (pkt_ind
->VirtualInterfaceIdentifier
& 0xff);
2568 interfacePriv
= priv
->interfacePriv
[interfaceTag
];
2571 /* Sanity check that the VIF refers to a sensible interface */
2572 if (interfaceTag
>= CSR_WIFI_NUM_INTERFACES
)
2574 unifi_error(priv
, "%s: MA-PACKET indication with bad interfaceTag %d\n", __FUNCTION__
, interfaceTag
);
2575 unifi_net_data_free(priv
,&bulkdata
->d
[0]);
2580 /* Sanity check that the VIF refers to an allocated netdev */
2581 if (!interfacePriv
->netdev_registered
)
2583 unifi_error(priv
, "%s: MA-PACKET indication with unallocated interfaceTag %d\n", __FUNCTION__
, interfaceTag
);
2584 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2589 if (bulkdata
->d
[0].data_length
== 0) {
2590 unifi_warning(priv
, "%s: MA-PACKET indication with zero bulk data\n", __FUNCTION__
);
2591 unifi_net_data_free(priv
,&bulkdata
->d
[0]);
2595 /* For monitor mode we need to pass this indication to the registered application
2596 handle this seperately*/
2597 /* MIC failure is already taken care of so no need to send the PDUs which are not successfully received in non-monitor mode*/
2598 if(pkt_ind
->ReceptionStatus
!= CSR_RX_SUCCESS
)
2600 unifi_warning(priv
, "%s: MA-PACKET indication with status = %d\n",__FUNCTION__
, pkt_ind
->ReceptionStatus
);
2601 unifi_net_data_free(priv
,&bulkdata
->d
[0]);
2607 skb
= (struct sk_buff
*)bulkdata
->d
[0].os_net_buf_ptr
;
2608 skb
->len
= bulkdata
->d
[0].data_length
;
2610 /* Point to the addresses */
2611 toDs
= (skb
->data
[1] & 0x01) ? 1 : 0;
2612 fromDs
= (skb
->data
[1] & 0x02) ? 1 : 0;
2614 memcpy(da
,(skb
->data
+4+toDs
*12),ETH_ALEN
);/* Address1 or 3 */
2615 memcpy(sa
,(skb
->data
+10+fromDs
*(6+toDs
*8)),ETH_ALEN
); /* Address2, 3 or 4 */
2617 /* Find the BSSID, which will be used to match the BA session */
2620 unifi_trace(priv
, UDBG6
, "4 address frame - don't try to find BSSID\n");
2625 bssid
= (u8
*) (skb
->data
+ 4 + 12 - (fromDs
* 6) - (toDs
* 12));
2628 pData
= &bulkdata
->d
[0];
2629 frameControl
= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData
->os_data_ptr
);
2630 frameType
= ((frameControl
& 0x000C) >> 2);
2632 unifi_trace(priv
, UDBG3
, "Rx Frame Type: %d sn: %d\n",frameType
,
2633 (le16_to_cpu(*((u16
*)(bulkdata
->d
[0].os_data_ptr
+ IEEE802_11_SEQUENCE_CONTROL_OFFSET
))) >> 4) & 0xfff);
2634 if(frameType
== IEEE802_11_FRAMETYPE_CONTROL
){
2635 #ifdef CSR_SUPPORT_SME
2636 unifi_trace(priv
, UDBG6
, "%s: Received Control Frame\n", __FUNCTION__
);
2638 if((frameControl
& 0x00f0) == 0x00A0){
2639 /* This is a PS-POLL request */
2640 u8 pmBit
= (frameControl
& 0x1000)?0x01:0x00;
2641 unifi_trace(priv
, UDBG6
, "%s: Received PS-POLL Frame\n", __FUNCTION__
);
2643 uf_process_ps_poll(priv
,sa
,da
,pmBit
,interfaceTag
);
2646 unifi_warning(priv
, "%s: Non PS-POLL control frame is received\n", __FUNCTION__
);
2649 unifi_net_data_free(priv
,&bulkdata
->d
[0]);
2653 if(frameType
!= IEEE802_11_FRAMETYPE_DATA
) {
2654 unifi_warning(priv
, "%s: Non control Non Data frame is received\n",__FUNCTION__
);
2655 unifi_net_data_free(priv
,&bulkdata
->d
[0]);
2660 #ifdef CSR_SUPPORT_SME
2661 if((interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
) ||
2662 (interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
)){
2664 srcStaInfo
= CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv
,sa
,interfaceTag
);
2666 if(srcStaInfo
== NULL
) {
2667 CsrWifiMacAddress peerMacAddress
;
2668 /* Unknown data PDU */
2669 memcpy(peerMacAddress
.a
,sa
,ETH_ALEN
);
2670 unifi_trace(priv
, UDBG1
, "%s: Unexpected frame from peer = %x:%x:%x:%x:%x:%x\n", __FUNCTION__
,
2671 sa
[0], sa
[1],sa
[2], sa
[3], sa
[4],sa
[5]);
2672 CsrWifiRouterCtrlUnexpectedFrameIndSend(priv
->CSR_WIFI_SME_IFACEQUEUE
,0,interfaceTag
,peerMacAddress
);
2673 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2679 verify power management bit here so as to ensure host and unifi are always
2680 in sync with power management status of peer.
2682 If we do it later, it may so happen we have stored the frame in BA re-ordering
2683 buffer and hence host and unifi are out of sync for power management status
2686 pmBit
= (frameControl
& 0x1000)?0x01:0x00;
2687 powerSaveChanged
= uf_process_pm_bit_for_peer(priv
,srcStaInfo
,pmBit
,interfaceTag
);
2689 /* Update station last activity time */
2690 srcStaInfo
->activity_flag
= TRUE
;
2692 /* For Qos Frame if PM bit is toggled to indicate the change in power save state then it shall not be
2693 considered as Trigger Frame. Enter only if WMM STA and peer is in Power save */
2695 dataFrameType
= ((frameControl
& 0x00f0) >> 4);
2697 if((powerSaveChanged
== FALSE
)&&(srcStaInfo
->wmmOrQosEnabled
== TRUE
)&&
2698 (srcStaInfo
->currentPeerState
== CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE
)){
2700 if((dataFrameType
== QOS_DATA
) || (dataFrameType
== QOS_DATA_NULL
)){
2703 * QoS control field is offset from frame control by 2 (frame control)
2704 * + 2 (duration/ID) + 2 (sequence control) + 3*ETH_ALEN or 4*ETH_ALEN
2706 if((frameControl
& IEEE802_11_FC_TO_DS_MASK
) && (frameControl
& IEEE802_11_FC_FROM_DS_MASK
)){
2707 qosControl
= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData
->os_data_ptr
+ 30);
2710 qosControl
= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData
->os_data_ptr
+ 24);
2712 unifi_trace(priv
, UDBG5
, "%s: Check if U-APSD operations are triggered for qosControl: 0x%x\n",__FUNCTION__
,qosControl
);
2713 uf_process_wmm_deliver_ac_uapsd(priv
,srcStaInfo
,qosControl
,interfaceTag
);
2720 if( ((frameControl
& 0x00f0) >> 4) == QOS_DATA
) {
2721 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);
2722 int tID
= *qos_control_ptr
& IEEE802_11_QC_TID_MASK
; /* using ls octet of qos control */
2723 ba_session_rx_struct
*ba_session
;
2724 u8 ba_session_idx
= 0;
2725 /* Get the BA originator address */
2726 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
2727 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
){
2733 down(&priv
->ba_mutex
);
2734 for (ba_session_idx
=0; ba_session_idx
< MAX_SUPPORTED_BA_SESSIONS_RX
; ba_session_idx
++){
2735 ba_session
= interfacePriv
->ba_session_rx
[ba_session_idx
];
2737 unifi_trace(priv
, UDBG6
, "found ba_session=0x%x ba_session_idx=%d", ba_session
, ba_session_idx
);
2738 if ((!memcmp(ba_session
->macAddress
.a
, ba_addr
, ETH_ALEN
)) && (ba_session
->tID
== tID
)){
2739 frame_desc_struct frame_desc
;
2740 frame_desc
.bulkdata
= *bulkdata
;
2741 frame_desc
.signal
= *signal
;
2742 frame_desc
.sn
= (le16_to_cpu(*((u16
*)(bulkdata
->d
[0].os_data_ptr
+ IEEE802_11_SEQUENCE_CONTROL_OFFSET
))) >> 4) & 0xfff;
2743 frame_desc
.active
= TRUE
;
2744 unifi_trace(priv
, UDBG6
, "%s: calling process_ba_frame (session=%d)\n", __FUNCTION__
, ba_session_idx
);
2745 process_ba_frame(priv
, interfacePriv
, ba_session
, &frame_desc
);
2746 up(&priv
->ba_mutex
);
2747 process_ba_complete(priv
, interfacePriv
);
2752 if (ba_session_idx
== MAX_SUPPORTED_BA_SESSIONS_RX
){
2753 up(&priv
->ba_mutex
);
2754 unifi_trace(priv
, UDBG6
, "%s: calling process_amsdu()", __FUNCTION__
);
2755 process_amsdu(priv
, signal
, bulkdata
);
2758 unifi_trace(priv
, UDBG6
, "calling unifi_rx()");
2759 unifi_rx(priv
, signal
, bulkdata
);
2762 /* check if the frames in reorder buffer has aged, the check
2763 * is done after receive processing so that if the missing frame
2764 * has arrived in this receive process, then it is handled cleanly.
2766 * And also this code here takes care that timeout check is made for all
2767 * the receive indications
2769 down(&priv
->ba_mutex
);
2770 for (i
=0; i
< MAX_SUPPORTED_BA_SESSIONS_RX
; i
++){
2771 ba_session_rx_struct
*ba_session
;
2772 ba_session
= interfacePriv
->ba_session_rx
[i
];
2774 check_ba_frame_age_timeout(priv
, interfacePriv
, ba_session
);
2777 up(&priv
->ba_mutex
);
2778 process_ba_complete(priv
, interfacePriv
);
2783 * ---------------------------------------------------------------------------
2784 * uf_set_multicast_list
2786 * This function is called by the higher level stack to set
2787 * a list of multicast rx addresses.
2790 * dev Network Device pointer.
2796 * ---------------------------------------------------------------------------
2800 uf_set_multicast_list(struct net_device
*dev
)
2802 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
2803 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
2805 #ifdef CSR_NATIVE_LINUX
2806 unifi_trace(priv
, UDBG3
, "uf_set_multicast_list unsupported\n");
2810 u8
*mc_list
= interfacePriv
->mc_list
;
2811 struct netdev_hw_addr
*mc_addr
;
2814 if (priv
->init_progress
!= UNIFI_INIT_COMPLETED
) {
2818 mc_addr_count
= netdev_mc_count(dev
);
2820 unifi_trace(priv
, UDBG3
,
2821 "uf_set_multicast_list (count=%d)\n", mc_addr_count
);
2824 /* Not enough space? */
2825 if (mc_addr_count
> UNIFI_MAX_MULTICAST_ADDRESSES
) {
2829 /* Store the list to be processed by the work item. */
2830 interfacePriv
->mc_list_count
= mc_addr_count
;
2831 netdev_hw_addr_list_for_each(mc_addr
, &dev
->mc
) {
2832 memcpy(mc_list
, mc_addr
->addr
, ETH_ALEN
);
2833 mc_list
+= ETH_ALEN
;
2836 /* Send a message to the workqueue */
2837 queue_work(priv
->unifi_workqueue
, &priv
->multicast_list_task
);
2840 } /* uf_set_multicast_list() */
2843 * ---------------------------------------------------------------------------
2844 * netdev_mlme_event_handler
2846 * Callback function to be used as the udi_event_callback when registering
2847 * as a netdev client.
2848 * To use it, a client specifies this function as the udi_event_callback
2849 * to ul_register_client(). The signal dispatcher in
2850 * unifi_receive_event() will call this function to deliver a signal.
2853 * pcli Pointer to the client instance.
2854 * signal Pointer to the received signal.
2855 * signal_len Size of the signal structure in bytes.
2856 * bulkdata Pointer to structure containing any associated bulk data.
2857 * dir Direction of the signal. Zero means from host,
2858 * non-zero means to host.
2862 * ---------------------------------------------------------------------------
2865 netdev_mlme_event_handler(ul_client_t
*pcli
, const u8
*sig_packed
, int sig_len
,
2866 const bulk_data_param_t
*bulkdata_o
, int dir
)
2869 unifi_priv_t
*priv
= uf_find_instance(pcli
->instance
);
2871 bulk_data_param_t bulkdata
;
2875 /* Just a sanity check */
2876 if (sig_packed
== NULL
) {
2881 * This copy is to silence a compiler warning about discarding the
2884 bulkdata
= *bulkdata_o
;
2886 /* Get the unpacked signal */
2887 r
= read_unpack_signal(sig_packed
, &signal
);
2890 * The CSR_MLME_CONNECTED_INDICATION_ID has a receiverID=0 so will
2891 * fall through this case. It is safe to ignore this signal.
2893 unifi_trace(priv
, UDBG1
,
2894 "Netdev - Received unknown signal 0x%.4X.\n",
2895 CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sig_packed
));
2899 id
= signal
.SignalPrimitiveHeader
.SignalId
;
2900 unifi_trace(priv
, UDBG3
, "Netdev - Process signal 0x%.4X\n", id
);
2903 * Take the appropriate action for the signal.
2906 case CSR_MA_PACKET_ERROR_INDICATION_ID
:
2907 process_ma_packet_error_ind(priv
, &signal
, &bulkdata
);
2909 case CSR_MA_PACKET_INDICATION_ID
:
2910 process_ma_packet_ind(priv
, &signal
, &bulkdata
);
2912 case CSR_MA_PACKET_CONFIRM_ID
:
2913 process_ma_packet_cfm(priv
, &signal
, &bulkdata
);
2915 #ifdef CSR_SUPPORT_SME
2916 case CSR_MLME_SET_TIM_CONFIRM_ID
:
2917 /* Handle TIM confirms from FW & set the station record's TIM state appropriately,
2918 * In case of failures, tries with max_retransmit limit
2920 uf_handle_tim_cfm(priv
, &signal
.u
.MlmeSetTimConfirm
, signal
.SignalPrimitiveHeader
.ReceiverProcessId
);
2923 case CSR_DEBUG_STRING_INDICATION_ID
:
2924 debug_string_indication(priv
, bulkdata
.d
[0].os_data_ptr
, bulkdata
.d
[0].data_length
);
2927 case CSR_DEBUG_WORD16_INDICATION_ID
:
2928 debug_word16_indication(priv
, &signal
);
2931 case CSR_DEBUG_GENERIC_CONFIRM_ID
:
2932 case CSR_DEBUG_GENERIC_INDICATION_ID
:
2933 debug_generic_indication(priv
, &signal
);
2940 } /* netdev_mlme_event_handler() */
2944 * ---------------------------------------------------------------------------
2947 * Retrieve the name (e.g. eth1) associated with this network device
2950 * dev Pointer to the network device.
2951 * name Buffer to write name
2952 * len Size of buffer in bytes
2958 * ---------------------------------------------------------------------------
2960 void uf_net_get_name(struct net_device
*dev
, char *name
, int len
)
2964 strlcpy(name
, dev
->name
, (len
> IFNAMSIZ
) ? IFNAMSIZ
: len
);
2967 } /* uf_net_get_name */
2969 #ifdef CSR_SUPPORT_WEXT
2972 * ---------------------------------------------------------------------------
2975 * Callback function to handle netdev state changes
2978 * notif Pointer to a notifier_block.
2979 * event Event prompting notification
2980 * ptr net_device pointer
2986 * The event handler is global, and may occur on non-UniFi netdevs.
2987 * ---------------------------------------------------------------------------
2990 uf_netdev_event(struct notifier_block
*notif
, unsigned long event
, void* ptr
) {
2991 struct net_device
*netdev
= ptr
;
2992 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(netdev
);
2993 unifi_priv_t
*priv
= NULL
;
2994 static const CsrWifiMacAddress broadcast_address
= {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
2996 /* Check that the event is for a UniFi netdev. If it's not, the netdev_priv
2997 * structure is not safe to use.
2999 if (uf_find_netdev_priv(interfacePriv
) == -1) {
3000 unifi_trace(NULL
, UDBG1
, "uf_netdev_event: ignore e=%d, ptr=%p, priv=%p %s\n",
3001 event
, ptr
, interfacePriv
, netdev
->name
);
3007 priv
= interfacePriv
->privPtr
;
3008 unifi_trace(priv
, UDBG1
, "NETDEV_CHANGE: %p %s %s waiting for it\n",
3011 interfacePriv
->wait_netdev_change
? "" : "not");
3013 if (interfacePriv
->wait_netdev_change
) {
3014 UF_NETIF_TX_WAKE_ALL_QUEUES(priv
->netdev
[interfacePriv
->InterfaceTag
]);
3015 interfacePriv
->connected
= UnifiConnected
;
3016 interfacePriv
->wait_netdev_change
= FALSE
;
3017 /* Note: passing the broadcast address here will allow anyone to attempt to join our adhoc network */
3018 uf_process_rx_pending_queue(priv
, UF_UNCONTROLLED_PORT_Q
, broadcast_address
, 1,interfacePriv
->InterfaceTag
);
3019 uf_process_rx_pending_queue(priv
, UF_CONTROLLED_PORT_Q
, broadcast_address
, 1,interfacePriv
->InterfaceTag
);
3029 static struct notifier_block uf_netdev_notifier
= {
3030 .notifier_call
= uf_netdev_event
,
3032 #endif /* CSR_SUPPORT_WEXT */
3036 process_amsdu(unifi_priv_t
*priv
, CSR_SIGNAL
*signal
, bulk_data_param_t
*bulkdata
)
3039 u32 length
= bulkdata
->d
[0].data_length
;
3040 u32 subframe_length
, subframe_body_length
, dot11_hdr_size
;
3042 bulk_data_param_t subframe_bulkdata
;
3043 u8
*dot11_hdr_ptr
= (u8
*)bulkdata
->d
[0].os_data_ptr
;
3044 CsrResult csrResult
;
3046 u8
*qos_control_ptr
;
3048 frameControl
= le16_to_cpu(*((u16
*)dot11_hdr_ptr
));
3049 qos_control_ptr
= dot11_hdr_ptr
+ (((frameControl
& IEEE802_11_FC_TO_DS_MASK
) && (frameControl
& IEEE802_11_FC_FROM_DS_MASK
))?30: 24);
3050 if(!(*qos_control_ptr
& IEEE802_11_QC_A_MSDU_PRESENT
)) {
3051 unifi_trace(priv
, UDBG6
, "%s: calling unifi_rx()", __FUNCTION__
);
3052 unifi_rx(priv
, signal
, bulkdata
);
3055 *qos_control_ptr
&= ~(IEEE802_11_QC_A_MSDU_PRESENT
);
3057 ptr
= qos_control_ptr
+ 2;
3058 offset
= dot11_hdr_size
= ptr
- dot11_hdr_ptr
;
3060 while(length
> (offset
+ sizeof(struct ethhdr
) + sizeof(llc_snap_hdr_t
))) {
3061 subframe_body_length
= ntohs(((struct ethhdr
*)ptr
)->h_proto
);
3062 if(subframe_body_length
> IEEE802_11_MAX_DATA_LEN
) {
3063 unifi_error(priv
, "%s: bad subframe_body_length = %d\n", __FUNCTION__
, subframe_body_length
);
3066 subframe_length
= sizeof(struct ethhdr
) + subframe_body_length
;
3067 memset(&subframe_bulkdata
, 0, sizeof(bulk_data_param_t
));
3069 csrResult
= unifi_net_data_malloc(priv
, &subframe_bulkdata
.d
[0], dot11_hdr_size
+ subframe_body_length
);
3071 if (csrResult
!= CSR_RESULT_SUCCESS
) {
3072 unifi_error(priv
, "%s: unifi_net_data_malloc failed\n", __FUNCTION__
);
3076 memcpy((u8
*)subframe_bulkdata
.d
[0].os_data_ptr
, dot11_hdr_ptr
, dot11_hdr_size
);
3079 /* When to DS=0 and from DS=0, address 3 will already have BSSID so no need to re-program */
3080 if ((frameControl
& IEEE802_11_FC_TO_DS_MASK
) && !(frameControl
& IEEE802_11_FC_FROM_DS_MASK
)){
3081 memcpy((u8
*)subframe_bulkdata
.d
[0].os_data_ptr
+ IEEE802_11_ADDR3_OFFSET
, ((struct ethhdr
*)ptr
)->h_dest
, ETH_ALEN
);
3083 else if (!(frameControl
& IEEE802_11_FC_TO_DS_MASK
) && (frameControl
& IEEE802_11_FC_FROM_DS_MASK
)){
3084 memcpy((u8
*)subframe_bulkdata
.d
[0].os_data_ptr
+ IEEE802_11_ADDR3_OFFSET
,
3085 ((struct ethhdr
*)ptr
)->h_source
,
3089 memcpy((u8
*)subframe_bulkdata
.d
[0].os_data_ptr
+ dot11_hdr_size
,
3090 ptr
+ sizeof(struct ethhdr
),
3091 subframe_body_length
);
3092 unifi_trace(priv
, UDBG6
, "%s: calling unifi_rx. length = %d subframe_length = %d\n", __FUNCTION__
, length
, subframe_length
);
3093 unifi_rx(priv
, signal
, &subframe_bulkdata
);
3095 subframe_length
= (subframe_length
+ 3)&(~0x3);
3096 ptr
+= subframe_length
;
3097 offset
+= subframe_length
;
3099 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
3103 #define SN_TO_INDEX(__ba_session, __sn) (((__sn - __ba_session->start_sn) & 0xFFF) % __ba_session->wind_size)
3106 #define ADVANCE_EXPECTED_SN(__ba_session) \
3108 __ba_session->expected_sn++; \
3109 __ba_session->expected_sn &= 0xFFF; \
3112 #define FREE_BUFFER_SLOT(__ba_session, __index) \
3114 __ba_session->occupied_slots--; \
3115 __ba_session->buffer[__index].active = FALSE; \
3116 ADVANCE_EXPECTED_SN(__ba_session); \
3119 static void add_frame_to_ba_complete(unifi_priv_t
*priv
,
3120 netInterface_priv_t
*interfacePriv
,
3121 frame_desc_struct
*frame_desc
)
3123 interfacePriv
->ba_complete
[interfacePriv
->ba_complete_index
] = *frame_desc
;
3124 interfacePriv
->ba_complete_index
++;
3128 static void update_expected_sn(unifi_priv_t
*priv
,
3129 netInterface_priv_t
*interfacePriv
,
3130 ba_session_rx_struct
*ba_session
,
3136 gap
= (sn
- ba_session
->expected_sn
) & 0xFFF;
3137 unifi_trace(priv
, UDBG6
, "%s: proccess the frames up to new_expected_sn = %d gap = %d\n", __FUNCTION__
, sn
, gap
);
3138 for(j
= 0; j
< gap
&& j
< ba_session
->wind_size
; j
++) {
3139 i
= SN_TO_INDEX(ba_session
, ba_session
->expected_sn
);
3140 unifi_trace(priv
, UDBG6
, "%s: proccess the slot index = %d\n", __FUNCTION__
, i
);
3141 if(ba_session
->buffer
[i
].active
) {
3142 add_frame_to_ba_complete(priv
, interfacePriv
, &ba_session
->buffer
[i
]);
3143 unifi_trace(priv
, UDBG6
, "%s: proccess the frame at index = %d expected_sn = %d\n", __FUNCTION__
, i
, ba_session
->expected_sn
);
3144 FREE_BUFFER_SLOT(ba_session
, i
);
3146 unifi_trace(priv
, UDBG6
, "%s: empty slot at index = %d\n", __FUNCTION__
, i
);
3147 ADVANCE_EXPECTED_SN(ba_session
);
3150 ba_session
->expected_sn
= sn
;
3154 static void complete_ready_sequence(unifi_priv_t
*priv
,
3155 netInterface_priv_t
*interfacePriv
,
3156 ba_session_rx_struct
*ba_session
)
3160 i
= SN_TO_INDEX(ba_session
, ba_session
->expected_sn
);
3161 while (ba_session
->buffer
[i
].active
) {
3162 add_frame_to_ba_complete(priv
, interfacePriv
, &ba_session
->buffer
[i
]);
3163 unifi_trace(priv
, UDBG6
, "%s: completed stored frame(expected_sn=%d) at i = %d\n", __FUNCTION__
, ba_session
->expected_sn
, i
);
3164 FREE_BUFFER_SLOT(ba_session
, i
);
3165 i
= SN_TO_INDEX(ba_session
, ba_session
->expected_sn
);
3170 void scroll_ba_window(unifi_priv_t
*priv
,
3171 netInterface_priv_t
*interfacePriv
,
3172 ba_session_rx_struct
*ba_session
,
3175 if(((sn
- ba_session
->expected_sn
) & 0xFFF) <= 2048) {
3176 update_expected_sn(priv
, interfacePriv
, ba_session
, sn
);
3177 complete_ready_sequence(priv
, interfacePriv
, ba_session
);
3182 static int consume_frame_or_get_buffer_index(unifi_priv_t
*priv
,
3183 netInterface_priv_t
*interfacePriv
,
3184 ba_session_rx_struct
*ba_session
,
3186 frame_desc_struct
*frame_desc
) {
3190 if(((sn
- ba_session
->expected_sn
) & 0xFFF) <= 2048) {
3192 /* once we are in BA window, set the flag for BA trigger */
3193 if(!ba_session
->trigger_ba_after_ssn
){
3194 ba_session
->trigger_ba_after_ssn
= TRUE
;
3197 sn_temp
= ba_session
->expected_sn
+ ba_session
->wind_size
;
3198 unifi_trace(priv
, UDBG6
, "%s: new frame: sn=%d\n", __FUNCTION__
, sn
);
3199 if(!(((sn
- sn_temp
) & 0xFFF) > 2048)) {
3200 u16 new_expected_sn
;
3201 unifi_trace(priv
, UDBG6
, "%s: frame is out of window\n", __FUNCTION__
);
3202 sn_temp
= (sn
- ba_session
->wind_size
) & 0xFFF;
3203 new_expected_sn
= (sn_temp
+ 1) & 0xFFF;
3204 update_expected_sn(priv
, interfacePriv
, ba_session
, new_expected_sn
);
3207 if (sn
== ba_session
->expected_sn
) {
3208 unifi_trace(priv
, UDBG6
, "%s: sn = ba_session->expected_sn = %d\n", __FUNCTION__
, sn
);
3209 ADVANCE_EXPECTED_SN(ba_session
);
3210 add_frame_to_ba_complete(priv
, interfacePriv
, frame_desc
);
3212 i
= SN_TO_INDEX(ba_session
, sn
);
3213 unifi_trace(priv
, UDBG6
, "%s: sn(%d) != ba_session->expected_sn(%d), i = %d\n", __FUNCTION__
, sn
, ba_session
->expected_sn
, i
);
3214 if (ba_session
->buffer
[i
].active
) {
3215 unifi_trace(priv
, UDBG6
, "%s: free frame at i = %d\n", __FUNCTION__
, i
);
3217 unifi_net_data_free(priv
, &frame_desc
->bulkdata
.d
[0]);
3222 if(!ba_session
->trigger_ba_after_ssn
){
3223 unifi_trace(priv
, UDBG6
, "%s: frame before ssn, pass it up: sn=%d\n", __FUNCTION__
, sn
);
3224 add_frame_to_ba_complete(priv
, interfacePriv
, frame_desc
);
3226 unifi_trace(priv
, UDBG6
, "%s: old frame, drop: sn=%d, expected_sn=%d\n", __FUNCTION__
, sn
, ba_session
->expected_sn
);
3227 unifi_net_data_free(priv
, &frame_desc
->bulkdata
.d
[0]);
3235 static void process_ba_frame(unifi_priv_t
*priv
,
3236 netInterface_priv_t
*interfacePriv
,
3237 ba_session_rx_struct
*ba_session
,
3238 frame_desc_struct
*frame_desc
)
3241 u16 sn
= frame_desc
->sn
;
3243 if (ba_session
->timeout
) {
3244 mod_timer(&ba_session
->timer
, (jiffies
+ usecs_to_jiffies((ba_session
->timeout
) * 1024)));
3246 unifi_trace(priv
, UDBG6
, "%s: got frame(sn=%d)\n", __FUNCTION__
, sn
);
3248 i
= consume_frame_or_get_buffer_index(priv
, interfacePriv
, ba_session
, sn
, frame_desc
);
3250 unifi_trace(priv
, UDBG6
, "%s: store frame(sn=%d) at i = %d\n", __FUNCTION__
, sn
, i
);
3251 ba_session
->buffer
[i
] = *frame_desc
;
3252 ba_session
->buffer
[i
].recv_time
= CsrTimeGet(NULL
);
3253 ba_session
->occupied_slots
++;
3255 unifi_trace(priv
, UDBG6
, "%s: frame consumed - sn = %d\n", __FUNCTION__
, sn
);
3257 complete_ready_sequence(priv
, interfacePriv
, ba_session
);
3261 static void process_ba_complete(unifi_priv_t
*priv
, netInterface_priv_t
*interfacePriv
)
3263 frame_desc_struct
*frame_desc
;
3266 for(i
= 0; i
< interfacePriv
->ba_complete_index
; i
++) {
3267 frame_desc
= &interfacePriv
->ba_complete
[i
];
3268 unifi_trace(priv
, UDBG6
, "%s: calling process_amsdu()\n", __FUNCTION__
);
3269 process_amsdu(priv
, &frame_desc
->signal
, &frame_desc
->bulkdata
);
3271 interfacePriv
->ba_complete_index
= 0;
3276 /* Check if the frames in BA reoder buffer has aged and
3277 * if so release the frames to upper processes and move
3280 static void check_ba_frame_age_timeout( unifi_priv_t
*priv
,
3281 netInterface_priv_t
*interfacePriv
,
3282 ba_session_rx_struct
*ba_session
)
3289 /* gap is started at 1 because we have buffered frames and
3290 * hence a minimum gap of 1 exists
3294 now
= CsrTimeGet(NULL
);
3296 if (ba_session
->occupied_slots
)
3298 /* expected sequence has not arrived so start searching from next
3299 * sequence number until a frame is available and determine the gap.
3300 * Check if the frame available has timedout, if so advance the
3301 * expected sequence number and release the frames
3303 sn_temp
= (ba_session
->expected_sn
+ 1) & 0xFFF;
3305 for(j
= 0; j
< ba_session
->wind_size
; j
++)
3307 i
= SN_TO_INDEX(ba_session
, sn_temp
);
3309 if(ba_session
->buffer
[i
].active
)
3311 unifi_trace(priv
, UDBG6
, "check age at slot index = %d sn = %d recv_time = %u now = %u\n",
3313 ba_session
->buffer
[i
].sn
,
3314 ba_session
->buffer
[i
].recv_time
,
3317 if (ba_session
->buffer
[i
].recv_time
> now
)
3320 age
= CsrTimeAdd((CsrTime
)CsrTimeSub(CSR_SCHED_TIME_MAX
, ba_session
->buffer
[i
].recv_time
), now
);
3324 age
= (CsrTime
)CsrTimeSub(now
, ba_session
->buffer
[i
].recv_time
);
3327 if (age
>= CSR_WIFI_BA_MPDU_FRAME_AGE_TIMEOUT
)
3329 unifi_trace(priv
, UDBG2
, "release the frame at index = %d gap = %d expected_sn = %d sn = %d\n",
3332 ba_session
->expected_sn
,
3333 ba_session
->buffer
[i
].sn
);
3335 /* if it has timedout don't wait for missing frames, move the window */
3338 ADVANCE_EXPECTED_SN(ba_session
);
3340 add_frame_to_ba_complete(priv
, interfacePriv
, &ba_session
->buffer
[i
]);
3341 FREE_BUFFER_SLOT(ba_session
, i
);
3342 complete_ready_sequence(priv
, interfacePriv
, ba_session
);
3349 /* advance temp sequence number and frame gap */
3350 sn_temp
= (sn_temp
+ 1) & 0xFFF;
3358 static void process_ma_packet_error_ind(unifi_priv_t
*priv
, CSR_SIGNAL
*signal
, bulk_data_param_t
*bulkdata
)
3361 const CSR_MA_PACKET_ERROR_INDICATION
*pkt_err_ind
= &signal
->u
.MaPacketErrorIndication
;
3362 netInterface_priv_t
*interfacePriv
;
3363 ba_session_rx_struct
*ba_session
;
3364 u8 ba_session_idx
= 0;
3365 CSR_PRIORITY UserPriority
;
3366 CSR_SEQUENCE_NUMBER sn
;
3370 interfaceTag
= (pkt_err_ind
->VirtualInterfaceIdentifier
& 0xff);
3373 /* Sanity check that the VIF refers to a sensible interface */
3374 if (interfaceTag
>= CSR_WIFI_NUM_INTERFACES
)
3376 unifi_error(priv
, "%s: MaPacketErrorIndication indication with bad interfaceTag %d\n", __FUNCTION__
, interfaceTag
);
3381 interfacePriv
= priv
->interfacePriv
[interfaceTag
];
3382 UserPriority
= pkt_err_ind
->UserPriority
;
3383 if(UserPriority
> 15) {
3384 unifi_error(priv
, "%s: MaPacketErrorIndication indication with bad UserPriority=%d\n", __FUNCTION__
, UserPriority
);
3387 sn
= pkt_err_ind
->SequenceNumber
;
3389 down(&priv
->ba_mutex
);
3390 /* To find the right ba_session loop through the BA sessions, compare MAC address and tID */
3391 for (ba_session_idx
=0; ba_session_idx
< MAX_SUPPORTED_BA_SESSIONS_RX
; ba_session_idx
++){
3392 ba_session
= interfacePriv
->ba_session_rx
[ba_session_idx
];
3394 if ((!memcmp(ba_session
->macAddress
.a
, pkt_err_ind
->PeerQstaAddress
.x
, ETH_ALEN
)) && (ba_session
->tID
== UserPriority
)){
3395 if (ba_session
->timeout
) {
3396 mod_timer(&ba_session
->timer
, (jiffies
+ usecs_to_jiffies((ba_session
->timeout
) * 1024)));
3398 scroll_ba_window(priv
, interfacePriv
, ba_session
, sn
);
3404 up(&priv
->ba_mutex
);
3405 process_ba_complete(priv
, interfacePriv
);