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 sema_init(&priv
->lock
, 1);
342 #endif /* USE_DRIVER_LOCK */
344 spin_lock_init(&priv
->send_signal_lock
);
346 spin_lock_init(&priv
->m4_lock
);
347 sema_init(&priv
->ba_mutex
, 1);
349 #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
350 spin_lock_init(&priv
->wapi_lock
);
353 #ifdef CSR_SUPPORT_SME
354 spin_lock_init(&priv
->staRecord_lock
);
355 spin_lock_init(&priv
->tx_q_lock
);
358 /* Create the Traffic Analysis workqueue */
359 priv
->unifi_workqueue
= create_singlethread_workqueue("unifi_workq");
360 if (priv
->unifi_workqueue
== NULL
) {
361 /* Deregister priv->netdev_client */
362 ul_deregister_client(priv
->netdev_client
);
363 free_netdev(priv
->netdev
[0]);
367 #ifdef CSR_SUPPORT_SME
368 /* Create the Multicast Addresses list work structure */
369 INIT_WORK(&priv
->multicast_list_task
, uf_multicast_list_wq
);
371 /* Create m4 buffering work structure */
372 INIT_WORK(&interfacePriv
->send_m4_ready_task
, uf_send_m4_ready_wq
);
374 #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
375 /* Create work structure to buffer the WAPI data packets to be sent to SME for encryption */
376 INIT_WORK(&interfacePriv
->send_pkt_to_encrypt
, uf_send_pkt_to_encrypt
);
382 priv
->amp_client
= NULL
;
383 priv
->coredump_mode
= 0;
384 priv
->ptest_mode
= 0;
385 priv
->wol_suspend
= FALSE
;
386 INIT_LIST_HEAD(&interfacePriv
->rx_uncontrolled_list
);
387 INIT_LIST_HEAD(&interfacePriv
->rx_controlled_list
);
388 sema_init(&priv
->rx_q_sem
, 1);
390 #ifdef CSR_SUPPORT_WEXT
391 interfacePriv
->netdev_callback_registered
= FALSE
;
392 interfacePriv
->wait_netdev_change
= FALSE
;
393 /* Register callback for netdevice state changes */
394 if ((rc
= register_netdevice_notifier(&uf_netdev_notifier
)) == 0) {
395 interfacePriv
->netdev_callback_registered
= TRUE
;
398 unifi_warning(priv
, "Failed to register netdevice notifier : %d %p\n", rc
, dev
);
400 #endif /* CSR_SUPPORT_WEXT */
402 #ifdef CSR_WIFI_SPLIT_PATCH
403 /* set it to some invalid value */
404 priv
->pending_mode_set
.common
.destination
= 0xaaaa;
408 } /* uf_alloc_netdevice() */
411 *---------------------------------------------------------------------------
412 * uf_alloc_netdevice_for_other_interfaces
414 * Allocate memory for the net_device and device private structs
415 * for this interface.
416 * Fill in the fields, but don't register the interface yet.
417 * We need to configure the UniFi first.
420 * interfaceTag Interface number.
421 * sdio_dev Pointer to SDIO context handle to use for all
423 * bus_id A small number indicating the SDIO card position on the
424 * bus. Typically this is the slot number, e.g. 0, 1 etc.
425 * Valid values are 0 to MAX_UNIFI_DEVS-1.
428 * Pointer to device private struct.
431 * The device private structure contains the interfaceTag and pointer to the unifi_priv
432 * structure created allocated by net_device od interface0.
433 * The net_device and device private structs are allocated together
434 * and should be freed by freeing the net_device pointer.
435 * ---------------------------------------------------------------------------
438 uf_alloc_netdevice_for_other_interfaces(unifi_priv_t
*priv
, u16 interfaceTag
)
440 struct net_device
*dev
;
441 netInterface_priv_t
*interfacePriv
;
444 * Allocate netdevice struct, assign name template and
445 * setup as an ethernet device.
446 * The net_device and private structs are zeroed. Ether_setup() then
447 * sets up ethernet handlers and values.
448 * The RedHat 9 redhat-config-network tool doesn't recognise wlan* devices,
449 * so use "eth*" (like other wireless extns drivers).
451 UF_ALLOC_NETDEV(dev
, sizeof(netInterface_priv_t
), "%d", ether_setup
, 1);
456 if (interfaceTag
>= CSR_WIFI_NUM_INTERFACES
) {
457 unifi_error(priv
, "uf_alloc_netdevice_for_other_interfaces bad interfaceTag\n");
461 /* Set up back pointer from priv to netdev */
462 interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
463 interfacePriv
->privPtr
= priv
;
464 interfacePriv
->InterfaceTag
= interfaceTag
;
465 priv
->netdev
[interfaceTag
] = dev
;
466 priv
->interfacePriv
[interfacePriv
->InterfaceTag
] = interfacePriv
;
468 /* reset the connected state for the interface */
469 interfacePriv
->connected
= UnifiConnectedUnknown
; /* -1 unknown, 0 no, 1 yes */
470 INIT_LIST_HEAD(&interfacePriv
->rx_uncontrolled_list
);
471 INIT_LIST_HEAD(&interfacePriv
->rx_controlled_list
);
473 /* Setup / override net_device fields */
474 dev
->netdev_ops
= &uf_netdev_ops
;
476 #ifdef CSR_SUPPORT_WEXT
477 dev
->wireless_handlers
= &unifi_iw_handler_def
;
478 #if IW_HANDLER_VERSION < 6
479 dev
->get_wireless_stats
= unifi_get_wireless_stats
;
480 #endif /* IW_HANDLER_VERSION */
481 #endif /* CSR_SUPPORT_WEXT */
483 } /* uf_alloc_netdevice() */
488 * ---------------------------------------------------------------------------
491 * Unregister the network device and free the memory allocated for it.
492 * NB This includes the memory for the priv struct.
495 * priv Device private pointer.
499 * ---------------------------------------------------------------------------
502 uf_free_netdevice(unifi_priv_t
*priv
)
509 unifi_trace(priv
, UDBG1
, "uf_free_netdevice\n");
516 * Free any buffers used for holding firmware
518 uf_release_firmware_files(priv
);
520 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
521 if (priv
->connection_config
.mlmeAssociateReqInformationElements
) {
522 kfree(priv
->connection_config
.mlmeAssociateReqInformationElements
);
524 priv
->connection_config
.mlmeAssociateReqInformationElements
= NULL
;
525 priv
->connection_config
.mlmeAssociateReqInformationElementsLength
= 0;
527 if (priv
->mib_data
.length
) {
528 vfree(priv
->mib_data
.data
);
530 priv
->mib_data
.data
= NULL
;
531 priv
->mib_data
.length
= 0;
533 #endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT*/
535 /* Free any bulkdata buffers allocated for M4 caching */
536 spin_lock_irqsave(&priv
->m4_lock
, flags
);
537 for (i
= 0; i
< CSR_WIFI_NUM_INTERFACES
; i
++) {
538 netInterface_priv_t
*interfacePriv
= priv
->interfacePriv
[i
];
539 if (interfacePriv
->m4_bulk_data
.data_length
> 0) {
540 unifi_trace(priv
, UDBG5
, "uf_free_netdevice: free M4 bulkdata %d\n", i
);
541 unifi_net_data_free(priv
, &interfacePriv
->m4_bulk_data
);
544 spin_unlock_irqrestore(&priv
->m4_lock
, flags
);
546 #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
547 /* Free any bulkdata buffers allocated for M4 caching */
548 spin_lock_irqsave(&priv
->wapi_lock
, flags
);
549 for (i
= 0; i
< CSR_WIFI_NUM_INTERFACES
; i
++) {
550 netInterface_priv_t
*interfacePriv
= priv
->interfacePriv
[i
];
551 if (interfacePriv
->wapi_unicast_bulk_data
.data_length
> 0) {
552 unifi_trace(priv
, UDBG5
, "uf_free_netdevice: free WAPI PKT bulk data %d\n", i
);
553 unifi_net_data_free(priv
, &interfacePriv
->wapi_unicast_bulk_data
);
556 spin_unlock_irqrestore(&priv
->wapi_lock
, flags
);
559 #ifdef CSR_SUPPORT_WEXT
560 /* Unregister callback for netdevice state changes */
561 unregister_netdevice_notifier(&uf_netdev_notifier
);
562 #endif /* CSR_SUPPORT_WEXT */
564 #ifdef CSR_SUPPORT_SME
565 /* Cancel work items and destroy the workqueue */
566 cancel_work_sync(&priv
->multicast_list_task
);
568 /* Destroy the workqueues. */
569 flush_workqueue(priv
->unifi_workqueue
);
570 destroy_workqueue(priv
->unifi_workqueue
);
572 /* Free up netdev in reverse order: priv is allocated with netdev[0].
573 * So, netdev[0] should be freed after all other netdevs are freed up
575 for (i
=CSR_WIFI_NUM_INTERFACES
-1; i
>=0; i
--) {
576 /*Free the netdev struct and priv, which are all one lump*/
577 if (priv
->netdev
[i
]) {
578 unifi_error(priv
, "uf_free_netdevice: netdev %d %p\n", i
, priv
->netdev
[i
]);
579 free_netdev(priv
->netdev
[i
]);
585 } /* uf_free_netdevice() */
589 * ---------------------------------------------------------------------------
592 * Called when userland does "ifconfig wlan0 up".
595 * dev Device pointer.
599 * ---------------------------------------------------------------------------
602 uf_net_open(struct net_device
*dev
)
604 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
605 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
609 /* If we haven't finished UniFi initialisation, we can't start */
610 if (priv
->init_progress
!= UNIFI_INIT_COMPLETED
) {
611 unifi_warning(priv
, "%s: unifi not ready, failing net_open\n", __FUNCTION__
);
615 #if (defined CSR_NATIVE_LINUX) && (defined UNIFI_SNIFF_ARPHRD) && defined(CSR_SUPPORT_WEXT)
617 * To sniff, the user must do "iwconfig mode monitor", which sets
618 * priv->wext_conf.mode to IW_MODE_MONITOR.
619 * Then he/she must do "ifconfig ethn up", which calls this fn.
620 * There is no point in starting the sniff with SNIFFJOIN until
623 if (priv
->wext_conf
.mode
== IW_MODE_MONITOR
) {
625 err
= uf_start_sniff(priv
);
629 netif_carrier_on(dev
);
633 #ifdef CSR_SUPPORT_WEXT
634 if (interfacePriv
->wait_netdev_change
) {
635 unifi_trace(priv
, UDBG1
, "%s: Waiting for NETDEV_CHANGE, assume connected\n",
637 interfacePriv
->connected
= UnifiConnected
;
638 interfacePriv
->wait_netdev_change
= FALSE
;
642 UF_NETIF_TX_START_ALL_QUEUES(dev
);
646 } /* uf_net_open() */
650 uf_net_stop(struct net_device
*dev
)
652 #if defined(CSR_NATIVE_LINUX) && defined(UNIFI_SNIFF_ARPHRD) && defined(CSR_SUPPORT_WEXT)
653 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
654 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
658 /* Stop sniffing if in Monitor mode */
659 if (priv
->wext_conf
.mode
== IW_MODE_MONITOR
) {
662 err
= unifi_reset_state(priv
, dev
->dev_addr
, 1);
672 UF_NETIF_TX_STOP_ALL_QUEUES(dev
);
676 } /* uf_net_stop() */
679 /* This is called after the WE handlers */
681 uf_net_ioctl(struct net_device
*dev
, struct ifreq
*rq
, int cmd
)
688 } /* uf_net_ioctl() */
692 static struct net_device_stats
*
693 uf_net_get_stats(struct net_device
*dev
)
695 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
697 return &interfacePriv
->stats
;
698 } /* uf_net_get_stats() */
700 static CSR_PRIORITY
uf_get_packet_priority(unifi_priv_t
*priv
, netInterface_priv_t
*interfacePriv
, struct sk_buff
*skb
, const int proto
)
702 CSR_PRIORITY priority
= CSR_CONTENTION
;
705 priority
= (CSR_PRIORITY
) (skb
->priority
>> 5);
707 if (priority
== CSR_QOS_UP0
) { /* 0 */
709 unifi_trace(priv
, UDBG5
, "uf_get_packet_priority: proto = 0x%.4X\n", proto
);
712 case 0x0800: /* IPv4 */
713 case 0x814C: /* SNMP */
714 case 0x880C: /* GSMP */
715 priority
= (CSR_PRIORITY
) (skb
->data
[1 + ETH_HLEN
] >> 5);
718 case 0x8100: /* VLAN */
719 priority
= (CSR_PRIORITY
) (skb
->data
[0 + ETH_HLEN
] >> 5);
722 case 0x86DD: /* IPv6 */
723 priority
= (CSR_PRIORITY
) ((skb
->data
[0 + ETH_HLEN
] & 0x0E) >> 1);
727 priority
= CSR_QOS_UP0
;
732 /* Check if we are allowed to transmit on this AC. Because of ACM we may have to downgrade to a lower
734 if (interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_STA
||
735 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI
) {
736 unifi_TrafficQueue queue
;
738 /* Keep trying lower priorities until we find a queue
739 * Priority to queue mapping is 1,2 - BK, 0,3 - BE, 4,5 - VI, 6,7 - VO */
740 queue
= unifi_frame_priority_to_queue(priority
);
742 while (queue
> UNIFI_TRAFFIC_Q_BK
&& !interfacePriv
->queueEnabled
[queue
]) {
744 priority
= unifi_get_default_downgrade_priority(queue
);
748 unifi_trace(priv
, UDBG5
, "Packet priority = %d\n", priority
);
757 * ---------------------------------------------------------------------------
758 * get_packet_priority
761 * priv private data area of functional driver
763 * ehdr ethernet header to fetch protocol
764 * interfacePriv For accessing station record database
769 * ---------------------------------------------------------------------------
772 get_packet_priority(unifi_priv_t
*priv
, struct sk_buff
*skb
, const struct ethhdr
*ehdr
, netInterface_priv_t
*interfacePriv
)
774 CSR_PRIORITY priority
= CSR_CONTENTION
;
775 const int proto
= ntohs(ehdr
->h_proto
);
777 u8 interfaceMode
= interfacePriv
->interfaceMode
;
781 /* Priority Mapping for all the Modes */
782 switch(interfaceMode
)
784 case CSR_WIFI_ROUTER_CTRL_MODE_STA
:
785 case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI
:
786 unifi_trace(priv
, UDBG4
, "mode is STA \n");
787 if ((priv
->sta_wmm_capabilities
& QOS_CAPABILITY_WMM_ENABLED
) == 1) {
788 priority
= uf_get_packet_priority(priv
, interfacePriv
, skb
, proto
);
790 priority
= CSR_CONTENTION
;
793 #ifdef CSR_SUPPORT_SME
794 case CSR_WIFI_ROUTER_CTRL_MODE_AP
:
795 case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
:
796 case CSR_WIFI_ROUTER_CTRL_MODE_IBSS
:
798 CsrWifiRouterCtrlStaInfo_t
* dstStaInfo
=
799 CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv
,ehdr
->h_dest
, interfacePriv
->InterfaceTag
);
800 unifi_trace(priv
, UDBG4
, "mode is AP \n");
801 if (!(ehdr
->h_dest
[0] & 0x01) && dstStaInfo
&& dstStaInfo
->wmmOrQosEnabled
) {
802 /* If packet is not Broadcast/multicast */
803 priority
= uf_get_packet_priority(priv
, interfacePriv
, skb
, proto
);
805 /* Since packet destination is not QSTA, set priority to CSR_CONTENTION */
806 unifi_trace(priv
, UDBG4
, "Destination is not QSTA or BroadCast/Multicast\n");
807 priority
= CSR_CONTENTION
;
813 unifi_trace(priv
, UDBG3
, " mode unknown in %s func, mode=%x\n", __FUNCTION__
, interfaceMode
);
815 unifi_trace(priv
, UDBG5
, "priority = %x\n", priority
);
822 * ---------------------------------------------------------------------------
823 * uf_net_select_queue
825 * Called by the kernel to select which queue to put the packet in
833 * ---------------------------------------------------------------------------
836 uf_net_select_queue(struct net_device
*dev
, struct sk_buff
*skb
)
838 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
839 unifi_priv_t
*priv
= (unifi_priv_t
*)interfacePriv
->privPtr
;
841 unifi_TrafficQueue queue
;
843 CSR_PRIORITY priority
;
847 memcpy(&ehdr
, skb
->data
, ETH_HLEN
);
848 proto
= ntohs(ehdr
.h_proto
);
850 /* 802.1x - apply controlled/uncontrolled port rules */
851 if ((proto
!= ETH_P_PAE
)
852 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
853 && (proto
!= ETH_P_WAI
)
857 priority
= get_packet_priority(priv
, skb
, &ehdr
, interfacePriv
);
858 queue
= unifi_frame_priority_to_queue(priority
);
861 queue
= UNIFI_TRAFFIC_Q_EAPOL
;
867 } /* uf_net_select_queue() */
870 skb_add_llc_snap(struct net_device
*dev
, struct sk_buff
*skb
, int proto
)
872 llc_snap_hdr_t
*snap
;
873 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
874 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
877 /* get the headroom available in skb */
878 headroom
= skb_headroom(skb
);
879 /* step 1: classify ether frame, DIX or 802.3? */
882 /* codes <= 1500 reserved for 802.3 lengths */
883 /* it's 802.3, pass ether payload unchanged, */
884 unifi_trace(priv
, UDBG3
, "802.3 len: %d\n", skb
->len
);
886 /* leave off any PAD octets. */
887 skb_trim(skb
, proto
);
888 } else if (proto
== ETH_P_8021Q
) {
890 /* Store the VLAN SNAP (should be 87-65). */
891 u16 vlan_snap
= *(u16
*)skb
->data
;
892 /* check for headroom availability before skb_push 14 = (4 + 10) */
894 unifi_trace(priv
, UDBG3
, "cant append vlan snap: debug\n");
897 /* Add AA-AA-03-00-00-00 */
898 snap
= (llc_snap_hdr_t
*)skb_push(skb
, 4);
899 snap
->dsap
= snap
->ssap
= 0xAA;
901 memcpy(snap
->oui
, oui_rfc1042
, P80211_OUI_LEN
);
903 /* Add AA-AA-03-00-00-00 */
904 snap
= (llc_snap_hdr_t
*)skb_push(skb
, 10);
905 snap
->dsap
= snap
->ssap
= 0xAA;
907 memcpy(snap
->oui
, oui_rfc1042
, P80211_OUI_LEN
);
909 /* Add the VLAN specific information */
910 snap
->protocol
= htons(proto
);
911 *(u16
*)(snap
+ 1) = vlan_snap
;
915 /* it's DIXII, time for some conversion */
916 unifi_trace(priv
, UDBG3
, "DIXII len: %d\n", skb
->len
);
918 /* check for headroom availability before skb_push */
919 if (headroom
< sizeof(llc_snap_hdr_t
)) {
920 unifi_trace(priv
, UDBG3
, "cant append snap: debug\n");
924 snap
= (llc_snap_hdr_t
*)skb_push(skb
, sizeof(llc_snap_hdr_t
));
925 snap
->dsap
= snap
->ssap
= 0xAA;
927 /* Use the appropriate OUI. */
928 if ((proto
== ETH_P_AARP
) || (proto
== ETH_P_IPX
)) {
929 memcpy(snap
->oui
, oui_8021h
, P80211_OUI_LEN
);
931 memcpy(snap
->oui
, oui_rfc1042
, P80211_OUI_LEN
);
933 snap
->protocol
= htons(proto
);
937 } /* skb_add_llc_snap() */
939 #ifdef CSR_SUPPORT_SME
941 _identify_sme_ma_pkt_ind(unifi_priv_t
*priv
,
942 const s8
*oui
, u16 protocol
,
943 const CSR_SIGNAL
*signal
,
944 bulk_data_param_t
*bulkdata
,
945 const unsigned char *daddr
,
946 const unsigned char *saddr
)
948 CSR_MA_PACKET_INDICATION
*pkt_ind
= (CSR_MA_PACKET_INDICATION
*)&signal
->u
.MaPacketIndication
;
952 unifi_trace(priv
, UDBG5
,
953 "_identify_sme_ma_pkt_ind -->\n");
954 for (i
= 0; i
< MAX_MA_UNIDATA_IND_FILTERS
; i
++) {
955 if (priv
->sme_unidata_ind_filters
[i
].in_use
) {
956 if (!memcmp(oui
, priv
->sme_unidata_ind_filters
[i
].oui
, 3) &&
957 (protocol
== priv
->sme_unidata_ind_filters
[i
].protocol
)) {
962 * Pass the packet to the SME, using unifi_sys_ma_unitdata_ind().
963 * The frame needs to be converted according to the encapsulation.
965 unifi_trace(priv
, UDBG1
,
966 "_identify_sme_ma_pkt_ind: handle=%d, encap=%d, proto=%x\n",
967 i
, priv
->sme_unidata_ind_filters
[i
].encapsulation
,
968 priv
->sme_unidata_ind_filters
[i
].protocol
);
969 if (priv
->sme_unidata_ind_filters
[i
].encapsulation
== CSR_WIFI_ROUTER_ENCAPSULATION_ETHERNET
) {
971 /* The translation is performed on skb... */
972 skb
= (struct sk_buff
*)bulkdata
->d
[0].os_net_buf_ptr
;
973 skb
->len
= bulkdata
->d
[0].data_length
;
975 unifi_trace(priv
, UDBG1
,
976 "_identify_sme_ma_pkt_ind: skb_80211_to_ether -->\n");
977 r
= skb_80211_to_ether(priv
, skb
, daddr
, saddr
,
979 unifi_trace(priv
, UDBG1
,
980 "_identify_sme_ma_pkt_ind: skb_80211_to_ether <--\n");
985 /* ... but we indicate buffer and length */
986 bulkdata
->d
[0].os_data_ptr
= skb
->data
;
987 bulkdata
->d
[0].data_length
= skb
->len
;
989 /* Add the MAC addresses before the SNAP */
990 bulkdata
->d
[0].os_data_ptr
-= 2*ETH_ALEN
;
991 bulkdata
->d
[0].data_length
+= 2*ETH_ALEN
;
992 memcpy((void*)bulkdata
->d
[0].os_data_ptr
, daddr
, ETH_ALEN
);
993 memcpy((void*)bulkdata
->d
[0].os_data_ptr
+ ETH_ALEN
, saddr
, ETH_ALEN
);
996 unifi_trace(priv
, UDBG1
,
997 "_identify_sme_ma_pkt_ind: unifi_sys_ma_pkt_ind -->\n");
998 CsrWifiRouterMaPacketIndSend(priv
->sme_unidata_ind_filters
[i
].appHandle
,
999 (pkt_ind
->VirtualInterfaceIdentifier
& 0xff),
1001 pkt_ind
->ReceptionStatus
,
1002 bulkdata
->d
[0].data_length
,
1003 (u8
*)bulkdata
->d
[0].os_data_ptr
,
1007 pkt_ind
->ReceivedRate
);
1010 unifi_trace(priv
, UDBG1
,
1011 "_identify_sme_ma_pkt_ind: unifi_sys_ma_pkt_ind <--\n");
1021 #endif /* CSR_SUPPORT_SME */
1024 * ---------------------------------------------------------------------------
1025 * skb_80211_to_ether
1027 * Make sure the received frame is in Ethernet (802.3) form.
1028 * De-encapsulates SNAP if necessary, adds a ethernet header.
1029 * The source buffer should not contain an 802.11 MAC header
1032 * payload Pointer to packet data received from UniFi.
1033 * payload_length Number of bytes of data received from UniFi.
1034 * daddr Destination MAC address.
1035 * saddr Source MAC address.
1038 * 0 on success, -1 if the packet is bad and should be dropped,
1039 * 1 if the packet was forwarded to the SME or AMP client.
1040 * ---------------------------------------------------------------------------
1043 skb_80211_to_ether(unifi_priv_t
*priv
, struct sk_buff
*skb
,
1044 const unsigned char *daddr
, const unsigned char *saddr
,
1045 const CSR_SIGNAL
*signal
,
1046 bulk_data_param_t
*bulkdata
)
1048 unsigned char *payload
;
1051 llc_snap_hdr_t
*snap
;
1053 #define UF_VLAN_LLC_HEADER_SIZE 18
1054 static const u8 vlan_inner_snap
[] = { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00 };
1055 #if defined(CSR_NATIVE_SOFTMAC) && defined(CSR_SUPPORT_SME)
1056 const CSR_MA_PACKET_INDICATION
*pkt_ind
= &signal
->u
.MaPacketIndication
;
1059 if(skb
== NULL
|| daddr
== NULL
|| saddr
== NULL
){
1060 unifi_error(priv
,"skb_80211_to_ether: PBC fail\n");
1064 payload
= skb
->data
;
1065 payload_length
= skb
->len
;
1067 snap
= (llc_snap_hdr_t
*)payload
;
1068 eth
= (struct ethhdr
*)payload
;
1070 /* get the skb headroom size */
1071 headroom
= skb_headroom(skb
);
1074 * Test for the various encodings
1076 if ((payload_length
>= sizeof(llc_snap_hdr_t
)) &&
1077 (snap
->dsap
== 0xAA) &&
1078 (snap
->ssap
== 0xAA) &&
1079 (snap
->ctrl
== 0x03) &&
1080 (snap
->oui
[0] == 0) &&
1081 (snap
->oui
[1] == 0) &&
1082 ((snap
->oui
[2] == 0) || (snap
->oui
[2] == 0xF8)))
1084 /* AppleTalk AARP (2) or IPX SNAP */
1085 if ((snap
->oui
[2] == 0) &&
1086 ((ntohs(snap
->protocol
) == ETH_P_AARP
) || (ntohs(snap
->protocol
) == ETH_P_IPX
)))
1090 unifi_trace(priv
, UDBG3
, "%s len: %d\n",
1091 (ntohs(snap
->protocol
) == ETH_P_AARP
) ? "ETH_P_AARP" : "ETH_P_IPX",
1094 /* check for headroom availability before skb_push */
1095 if (headroom
< (2 * ETH_ALEN
+ 2)) {
1096 unifi_warning(priv
, "headroom not available to skb_push ether header\n");
1100 /* Add 802.3 header and leave full payload */
1101 len
= htons(skb
->len
);
1102 memcpy(skb_push(skb
, 2), &len
, 2);
1103 memcpy(skb_push(skb
, ETH_ALEN
), saddr
, ETH_ALEN
);
1104 memcpy(skb_push(skb
, ETH_ALEN
), daddr
, ETH_ALEN
);
1108 /* VLAN-tagged IP */
1109 if ((snap
->oui
[2] == 0) && (ntohs(snap
->protocol
) == ETH_P_8021Q
))
1112 * The translation doesn't change the packet length, so is done in-place.
1114 * Example header (from Std 802.11-2007 Annex M):
1115 * AA-AA-03-00-00-00-81-00-87-65-AA-AA-03-00-00-00-08-06
1116 * -------SNAP-------p1-p1-ll-ll-------SNAP--------p2-p2
1117 * dd-dd-dd-dd-dd-dd-aa-aa-aa-aa-aa-aa-p1-p1-ll-ll-p2-p2
1118 * dd-dd-dd-dd-dd-dd-aa-aa-aa-aa-aa-aa-81-00-87-65-08-06
1122 if (payload_length
< UF_VLAN_LLC_HEADER_SIZE
) {
1123 unifi_warning(priv
, "VLAN SNAP header too short: %d bytes\n", payload_length
);
1127 if (memcmp(payload
+ 10, vlan_inner_snap
, 6)) {
1128 unifi_warning(priv
, "VLAN malformatted SNAP header.\n");
1132 unifi_trace(priv
, UDBG3
, "VLAN SNAP: %02x-%02x\n", payload
[8], payload
[9]);
1133 unifi_trace(priv
, UDBG3
, "VLAN len: %d\n", payload_length
);
1135 /* Create the 802.3 header */
1137 vlan_snap
= *((u16
*)(payload
+ 8));
1139 /* Create LLC header without byte-swapping */
1140 eth
->h_proto
= snap
->protocol
;
1142 memcpy(eth
->h_dest
, daddr
, ETH_ALEN
);
1143 memcpy(eth
->h_source
, saddr
, ETH_ALEN
);
1144 *(u16
*)(eth
+ 1) = vlan_snap
;
1148 /* it's a SNAP + RFC1042 frame */
1149 unifi_trace(priv
, UDBG3
, "SNAP+RFC1042 len: %d\n", payload_length
);
1151 /* chop SNAP+llc header from skb. */
1152 skb_pull(skb
, sizeof(llc_snap_hdr_t
));
1154 /* Since skb_pull called above to chop snap+llc, no need to check for headroom
1155 * availability before skb_push
1157 /* create 802.3 header at beginning of skb. */
1158 eth
= (struct ethhdr
*)skb_push(skb
, ETH_HLEN
);
1159 memcpy(eth
->h_dest
, daddr
, ETH_ALEN
);
1160 memcpy(eth
->h_source
, saddr
, ETH_ALEN
);
1161 /* Copy protocol field without byte-swapping */
1162 eth
->h_proto
= snap
->protocol
;
1166 /* check for headroom availability before skb_push */
1167 if (headroom
< (2 * ETH_ALEN
+ 2)) {
1168 unifi_warning(priv
, "headroom not available to skb_push ether header\n");
1171 /* Add 802.3 header and leave full payload */
1172 len
= htons(skb
->len
);
1173 memcpy(skb_push(skb
, 2), &len
, 2);
1174 memcpy(skb_push(skb
, ETH_ALEN
), saddr
, ETH_ALEN
);
1175 memcpy(skb_push(skb
, ETH_ALEN
), daddr
, ETH_ALEN
);
1181 } /* skb_80211_to_ether() */
1184 static CsrWifiRouterCtrlPortAction
verify_port(unifi_priv_t
*priv
, unsigned char *address
, int queue
, u16 interfaceTag
)
1186 #ifdef CSR_NATIVE_LINUX
1187 #ifdef CSR_SUPPORT_WEXT
1188 if (queue
== UF_CONTROLLED_PORT_Q
) {
1189 return priv
->wext_conf
.block_controlled_port
;
1191 return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN
;
1194 return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN
; /* default to open for softmac dev */
1197 return uf_sme_port_state(priv
, address
, queue
, interfaceTag
);
1202 * ---------------------------------------------------------------------------
1203 * prepare_and_add_macheader
1206 * These functions adds mac header for packet from netdev
1207 * to UniFi for transmission.
1208 * EAP protocol packets are also appended with Mac header &
1209 * sent using send_ma_pkt_request().
1212 * priv Pointer to device private context struct
1213 * skb Socket buffer containing data packet to transmit
1214 * newSkb Socket buffer containing data packet + Mac header if no sufficient headroom in skb
1215 * serviceClass to append QOS control header in Mac header
1216 * bulkdata if newSkb allocated then bulkdata updated to send to unifi
1217 * interfaceTag the interfaceID on which activity going on
1218 * daddr destination address
1219 * saddr source address
1220 * protection protection bit set in framce control of mac header
1223 * Zero on success or error code.
1224 * ---------------------------------------------------------------------------
1227 int prepare_and_add_macheader(unifi_priv_t
*priv
, struct sk_buff
*skb
, struct sk_buff
*newSkb
,
1228 CSR_PRIORITY priority
,
1229 bulk_data_param_t
*bulkdata
,
1237 u8 macHeaderLengthInBytes
= MAC_HEADER_SIZE
, *bufPtr
= NULL
;
1238 bulk_data_param_t data_ptrs
;
1239 CsrResult csrResult
;
1242 netInterface_priv_t
*interfacePriv
= priv
->interfacePriv
[interfaceTag
];
1244 u8 bQosNull
= false;
1247 unifi_error(priv
,"prepare_and_add_macheader: Invalid SKB reference\n");
1251 /* add a MAC header refer: 7.1.3.1 Frame Control field in P802.11REVmb.book */
1252 if (priority
!= CSR_CONTENTION
) {
1253 /* EAPOL packets don't go as QOS_DATA */
1254 if (priority
== CSR_MANAGEMENT
) {
1255 fc
|= cpu_to_le16(IEEE802_11_FC_TYPE_DATA
);
1257 /* Qos Control Field */
1258 macHeaderLengthInBytes
+= QOS_CONTROL_HEADER_SIZE
;
1262 fc
|= cpu_to_le16(IEEE802_11_FC_TYPE_QOS_DATA
);
1264 fc
|= cpu_to_le16(IEEE802_11_FC_TYPE_QOS_NULL
);
1270 fc
|= cpu_to_le16(IEEE802_11_FC_TYPE_NULL
);
1272 fc
|= cpu_to_le16(IEEE802_11_FC_TYPE_DATA
);
1276 switch (interfacePriv
->interfaceMode
)
1278 case CSR_WIFI_ROUTER_CTRL_MODE_STA
:
1279 case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI
:
1281 fc
|= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK
);
1283 case CSR_WIFI_ROUTER_CTRL_MODE_IBSS
:
1286 case CSR_WIFI_ROUTER_CTRL_MODE_AP
:
1287 case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
:
1289 fc
|= cpu_to_le16(IEEE802_11_FC_FROM_DS_MASK
);
1291 case CSR_WIFI_ROUTER_CTRL_MODE_AMP
:
1292 if (priority
== CSR_MANAGEMENT
) {
1295 fc
|= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK
);
1297 /* Data frames have to use WDS 4 address frames */
1299 fc
|= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK
| IEEE802_11_FC_FROM_DS_MASK
);
1300 macHeaderLengthInBytes
+= 6;
1304 unifi_warning(priv
, "prepare_and_add_macheader: Unknown mode %d\n",
1305 interfacePriv
->interfaceMode
);
1309 /* If Sta is QOS & HTC is supported then need to set 'order' bit */
1310 /* We don't support HT Control for now */
1313 fc
|= cpu_to_le16(IEEE802_11_FC_PROTECTED_MASK
);
1316 /* check the skb headroom before pushing mac header */
1317 headroom
= skb_headroom(skb
);
1319 if (headroom
< macHeaderLengthInBytes
) {
1320 unifi_trace(priv
, UDBG5
,
1321 "prepare_and_add_macheader: Allocate headroom extra %d bytes\n",
1322 macHeaderLengthInBytes
);
1324 csrResult
= unifi_net_data_malloc(priv
, &data_ptrs
.d
[0], skb
->len
+ macHeaderLengthInBytes
);
1326 if (csrResult
!= CSR_RESULT_SUCCESS
) {
1327 unifi_error(priv
, " failed to allocate request_data. in %s func\n", __FUNCTION__
);
1330 newSkb
= (struct sk_buff
*)(data_ptrs
.d
[0].os_net_buf_ptr
);
1331 newSkb
->len
= skb
->len
+ macHeaderLengthInBytes
;
1333 memcpy((void*)data_ptrs
.d
[0].os_data_ptr
+ macHeaderLengthInBytes
,
1334 skb
->data
, skb
->len
);
1336 bulkdata
->d
[0].os_data_ptr
= newSkb
->data
;
1337 bulkdata
->d
[0].os_net_buf_ptr
= (unsigned char*)newSkb
;
1338 bulkdata
->d
[0].data_length
= newSkb
->len
;
1340 bufPtr
= (u8
*)data_ptrs
.d
[0].os_data_ptr
;
1342 /* The old skb will not be used again */
1346 /* headroom has sufficient size, so will get proper pointer */
1347 bufPtr
= (u8
*)skb_push(skb
, macHeaderLengthInBytes
);
1348 bulkdata
->d
[0].os_data_ptr
= skb
->data
;
1349 bulkdata
->d
[0].os_net_buf_ptr
= (unsigned char*)skb
;
1350 bulkdata
->d
[0].data_length
= skb
->len
;
1353 /* Frame the actual MAC header */
1355 memset(bufPtr
, 0, macHeaderLengthInBytes
);
1357 /* copy frameControl field */
1358 memcpy(bufPtr
, &fc
, sizeof(fc
));
1359 bufPtr
+= sizeof(fc
);
1360 macHeaderLengthInBytes
-= sizeof(fc
);
1362 /* Duration/ID field which is 2 bytes */
1364 macHeaderLengthInBytes
-= 2;
1369 /* Its an Ad-Hoc no need to route it through AP */
1370 /* Address1: MAC address of the destination from eth header */
1371 memcpy(bufPtr
, daddr
, ETH_ALEN
);
1373 macHeaderLengthInBytes
-= ETH_ALEN
;
1375 /* Address2: MAC address of the source */
1376 memcpy(bufPtr
, saddr
, ETH_ALEN
);
1378 macHeaderLengthInBytes
-= ETH_ALEN
;
1380 /* Address3: the BSSID (locally generated in AdHoc (creators Bssid)) */
1381 memcpy(bufPtr
, &interfacePriv
->bssid
, ETH_ALEN
);
1383 macHeaderLengthInBytes
-= ETH_ALEN
;
1386 /* Address1: MAC address of the actual destination */
1387 memcpy(bufPtr
, daddr
, ETH_ALEN
);
1389 macHeaderLengthInBytes
-= ETH_ALEN
;
1390 /* Address2: The MAC address of the AP */
1391 memcpy(bufPtr
, &interfacePriv
->bssid
, ETH_ALEN
);
1393 macHeaderLengthInBytes
-= ETH_ALEN
;
1395 /* Address3: MAC address of the source from eth header */
1396 memcpy(bufPtr
, saddr
, ETH_ALEN
);
1398 macHeaderLengthInBytes
-= ETH_ALEN
;
1401 /* Address1: To AP is the MAC address of the AP to which its associated */
1402 memcpy(bufPtr
, &interfacePriv
->bssid
, ETH_ALEN
);
1404 macHeaderLengthInBytes
-= ETH_ALEN
;
1406 /* Address2: MAC address of the source from eth header */
1407 memcpy(bufPtr
, saddr
, ETH_ALEN
);
1409 macHeaderLengthInBytes
-= ETH_ALEN
;
1411 /* Address3: MAC address of the actual destination on the distribution system */
1412 memcpy(bufPtr
, daddr
, ETH_ALEN
);
1414 macHeaderLengthInBytes
-= ETH_ALEN
;
1417 memcpy(bufPtr
, &interfacePriv
->bssid
, ETH_ALEN
);
1419 macHeaderLengthInBytes
-= ETH_ALEN
;
1421 /* Address2: MAC address of the source from eth header */
1422 memcpy(bufPtr
, saddr
, ETH_ALEN
);
1424 macHeaderLengthInBytes
-= ETH_ALEN
;
1426 /* Address3: MAC address of the actual destination on the distribution system */
1427 memcpy(bufPtr
, daddr
, ETH_ALEN
);
1429 macHeaderLengthInBytes
-= ETH_ALEN
;
1432 unifi_error(priv
,"Unknown direction =%d : Not handled now\n",direction
);
1435 /* 2 bytes of frame control field, appended by firmware */
1437 macHeaderLengthInBytes
-= 2;
1439 if (3 == direction
) {
1440 /* Address4: MAC address of the source */
1441 memcpy(bufPtr
, saddr
, ETH_ALEN
);
1443 macHeaderLengthInBytes
-= ETH_ALEN
;
1446 /* IF Qos Data or Qos Null Data then set QosControl field */
1447 if ((priority
!= CSR_CONTENTION
) && (macHeaderLengthInBytes
>= QOS_CONTROL_HEADER_SIZE
)) {
1450 unifi_trace(priv
, UDBG1
, "data packets priority is more than 7, priority = %x\n", priority
);
1455 /*assigning address1
1456 * Address1 offset taken fromm bufPtr(currently bufPtr pointing to Qos contorl) variable in reverse direction
1457 * Address4 don't exit
1460 addressOne
= bufPtr
- ADDRESS_ONE_OFFSET
;
1462 if (addressOne
[0] & 0x1) {
1463 /* multicast/broadcast frames, no acknowledgement needed */
1466 /* non-AP mode only for now */
1467 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_STA
||
1468 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_IBSS
||
1469 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI
) {
1470 /* In case of STA and IBSS case eosp and txop limit is 0. */
1477 /* append Qos control field to mac header */
1479 /* txop limit is 0 */
1481 macHeaderLengthInBytes
-= QOS_CONTROL_HEADER_SIZE
;
1483 if (macHeaderLengthInBytes
) {
1484 unifi_warning(priv
, " Mac header not appended properly\n");
1491 * ---------------------------------------------------------------------------
1492 * send_ma_pkt_request
1494 * These functions send a data packet to UniFi for transmission.
1495 * EAP protocol packets are also sent as send_ma_pkt_request().
1498 * priv Pointer to device private context struct
1499 * skb Socket buffer containing data packet to transmit
1500 * ehdr Pointer to Ethernet header within skb.
1503 * Zero on success or error code.
1504 * ---------------------------------------------------------------------------
1508 send_ma_pkt_request(unifi_priv_t
*priv
, struct sk_buff
*skb
, const struct ethhdr
*ehdr
, CSR_PRIORITY priority
)
1512 u8 eapolStore
= FALSE
;
1513 struct sk_buff
*newSkb
= NULL
;
1514 bulk_data_param_t bulkdata
;
1515 const int proto
= ntohs(ehdr
->h_proto
);
1517 CsrWifiMacAddress peerAddress
;
1518 CSR_TRANSMISSION_CONTROL transmissionControl
= CSR_NO_CONFIRM_REQUIRED
;
1520 netInterface_priv_t
*interfacePriv
= NULL
;
1521 CSR_RATE TransmitRate
= (CSR_RATE
)0;
1523 unifi_trace(priv
, UDBG5
, "entering send_ma_pkt_request\n");
1525 /* Get the interface Tag by means of source Mac address */
1526 for (i
= 0; i
< CSR_WIFI_NUM_INTERFACES
; i
++) {
1527 if (!memcmp(priv
->netdev
[i
]->dev_addr
, ehdr
->h_source
, ETH_ALEN
)) {
1529 interfacePriv
= priv
->interfacePriv
[interfaceTag
];
1534 if (interfacePriv
== NULL
) {
1535 /* No match found - error */
1537 interfacePriv
= priv
->interfacePriv
[interfaceTag
];
1538 unifi_warning(priv
, "Mac address not matching ... debugging needed\n");
1539 interfacePriv
->stats
.tx_dropped
++;
1544 /* Add a SNAP header if necessary */
1545 if (skb_add_llc_snap(priv
->netdev
[interfaceTag
], skb
, proto
) != 0) {
1546 /* convert failed */
1547 unifi_error(priv
, "skb_add_llc_snap failed.\n");
1552 bulkdata
.d
[0].os_data_ptr
= skb
->data
;
1553 bulkdata
.d
[0].os_net_buf_ptr
= (unsigned char*)skb
;
1554 bulkdata
.d
[0].net_buf_length
= bulkdata
.d
[0].data_length
= skb
->len
;
1555 bulkdata
.d
[1].os_data_ptr
= NULL
;
1556 bulkdata
.d
[1].os_net_buf_ptr
= NULL
;
1557 bulkdata
.d
[1].net_buf_length
= bulkdata
.d
[1].data_length
= 0;
1559 #ifdef CSR_SUPPORT_SME
1560 /* Notify the TA module for the Tx frame for non AP/P2PGO mode*/
1561 if ((interfacePriv
->interfaceMode
!= CSR_WIFI_ROUTER_CTRL_MODE_AP
) &&
1562 (interfacePriv
->interfaceMode
!= CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
)) {
1563 unifi_ta_sample(priv
->card
, CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX
,
1564 &bulkdata
.d
[0], ehdr
->h_source
,
1565 priv
->netdev
[interfaceTag
]->dev_addr
,
1566 jiffies_to_msecs(jiffies
),
1567 0); /* rate is unknown on tx */
1569 #endif /* CSR_SUPPORT_SME */
1571 if ((proto
== ETH_P_PAE
)
1572 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1573 || (proto
== ETH_P_WAI
)
1577 /* check for m4 detection */
1578 if (0 == uf_verify_m4(priv
, bulkdata
.d
[0].os_data_ptr
, bulkdata
.d
[0].data_length
)) {
1583 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1584 if (proto
== ETH_P_WAI
)
1586 protection
= 0; /*WAI packets always sent unencrypted*/
1591 #ifdef CSR_SUPPORT_SME
1592 if ((protection
= uf_get_protection_bit_from_interfacemode(priv
, interfaceTag
, ehdr
->h_dest
)) < 0) {
1593 unifi_warning(priv
, "unicast address, but destination not in station record database\n");
1594 unifi_net_data_free(priv
, &bulkdata
.d
[0]);
1600 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1604 /* append Mac header for Eapol as well as data packet */
1605 if (prepare_and_add_macheader(priv
, skb
, newSkb
, priority
, &bulkdata
, interfaceTag
, ehdr
->h_dest
, ehdr
->h_source
, protection
)) {
1606 unifi_error(priv
, "failed to create MAC header\n");
1607 unifi_net_data_free(priv
, &bulkdata
.d
[0]);
1611 /* RA adrress must contain the immediate destination MAC address that is similiar to
1612 * the Address 1 field of 802.11 Mac header here 4 is: (sizeof(framecontrol) + sizeof (durationID))
1613 * which is address 1 field
1615 memcpy(peerAddress
.a
, ((u8
*) bulkdata
.d
[0].os_data_ptr
) + 4, ETH_ALEN
);
1617 unifi_trace(priv
, UDBG5
, "RA[0]=%x, RA[1]=%x, RA[2]=%x, RA[3]=%x, RA[4]=%x, RA[5]=%x\n",
1618 peerAddress
.a
[0],peerAddress
.a
[1], peerAddress
.a
[2], peerAddress
.a
[3],
1619 peerAddress
.a
[4],peerAddress
.a
[5]);
1622 if ((proto
== ETH_P_PAE
)
1623 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1624 || (proto
== ETH_P_WAI
)
1629 CSR_MA_PACKET_REQUEST
*req
= &signal
.u
.MaPacketRequest
;
1631 /* initialize signal to zero */
1632 memset(&signal
, 0, sizeof(CSR_SIGNAL
));
1634 /* Frame MA_PACKET request */
1635 signal
.SignalPrimitiveHeader
.SignalId
= CSR_MA_PACKET_REQUEST_ID
;
1636 signal
.SignalPrimitiveHeader
.ReceiverProcessId
= 0;
1637 signal
.SignalPrimitiveHeader
.SenderProcessId
= priv
->netdev_client
->sender_id
;
1639 transmissionControl
= req
->TransmissionControl
= 0;
1640 #ifdef CSR_SUPPORT_SME
1643 netInterface_priv_t
*netpriv
= (netInterface_priv_t
*)netdev_priv(priv
->netdev
[interfaceTag
]);
1645 /* Fill the MA-PACKET.req */
1647 req
->Priority
= priority
;
1648 unifi_trace(priv
, UDBG3
, "Tx Frame with Priority: %x\n", req
->Priority
);
1650 /* rate selected by firmware */
1651 req
->TransmitRate
= 0;
1652 req
->HostTag
= CSR_WIFI_EAPOL_M4_HOST_TAG
;
1653 /* RA address matching with address 1 of Mac header */
1654 memcpy(req
->Ra
.x
, ((u8
*) bulkdata
.d
[0].os_data_ptr
) + 4, ETH_ALEN
);
1656 spin_lock(&priv
->m4_lock
);
1657 /* Store the M4-PACKET.req for later */
1658 interfacePriv
->m4_signal
= signal
;
1659 interfacePriv
->m4_bulk_data
.net_buf_length
= bulkdata
.d
[0].net_buf_length
;
1660 interfacePriv
->m4_bulk_data
.data_length
= bulkdata
.d
[0].data_length
;
1661 interfacePriv
->m4_bulk_data
.os_data_ptr
= bulkdata
.d
[0].os_data_ptr
;
1662 interfacePriv
->m4_bulk_data
.os_net_buf_ptr
= bulkdata
.d
[0].os_net_buf_ptr
;
1663 spin_unlock(&priv
->m4_lock
);
1665 /* Signal the workqueue to call CsrWifiRouterCtrlM4ReadyToSendIndSend().
1666 * It cannot be called directly from the tx path because it
1667 * does a non-atomic kmalloc via the framework's CsrPmemAlloc().
1669 queue_work(priv
->unifi_workqueue
, &netpriv
->send_m4_ready_task
);
1674 }/*EAPOL or WAI packet*/
1676 #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
1677 if ((CSR_WIFI_ROUTER_CTRL_MODE_STA
== interfacePriv
->interfaceMode
) && \
1678 (priv
->wapi_unicast_filter
) && \
1679 (proto
!= ETH_P_PAE
) && \
1680 (proto
!= ETH_P_WAI
) && \
1684 CSR_MA_PACKET_REQUEST
*req
= &signal
.u
.MaPacketRequest
;
1685 netInterface_priv_t
*netpriv
= (netInterface_priv_t
*)netdev_priv(priv
->netdev
[interfaceTag
]);
1687 unifi_trace(priv
, UDBG4
, "send_ma_pkt_request() - WAPI unicast data packet when USKID = 1 \n");
1689 /* initialize signal to zero */
1690 memset(&signal
, 0, sizeof(CSR_SIGNAL
));
1691 /* Frame MA_PACKET request */
1692 signal
.SignalPrimitiveHeader
.SignalId
= CSR_MA_PACKET_REQUEST_ID
;
1693 signal
.SignalPrimitiveHeader
.ReceiverProcessId
= 0;
1694 signal
.SignalPrimitiveHeader
.SenderProcessId
= priv
->netdev_client
->sender_id
;
1696 /* Fill the MA-PACKET.req */
1697 req
->TransmissionControl
= 0;
1698 req
->Priority
= priority
;
1699 unifi_trace(priv
, UDBG3
, "Tx Frame with Priority: %x\n", req
->Priority
);
1700 req
->TransmitRate
= (CSR_RATE
) 0; /* rate selected by firmware */
1701 req
->HostTag
= 0xffffffff; /* Ask for a new HostTag */
1702 /* RA address matching with address 1 of Mac header */
1703 memcpy(req
->Ra
.x
, ((u8
*) bulkdata
.d
[0].os_data_ptr
) + 4, ETH_ALEN
);
1705 /* Store the M4-PACKET.req for later */
1706 spin_lock(&priv
->wapi_lock
);
1707 interfacePriv
->wapi_unicast_ma_pkt_sig
= signal
;
1708 interfacePriv
->wapi_unicast_bulk_data
.net_buf_length
= bulkdata
.d
[0].net_buf_length
;
1709 interfacePriv
->wapi_unicast_bulk_data
.data_length
= bulkdata
.d
[0].data_length
;
1710 interfacePriv
->wapi_unicast_bulk_data
.os_data_ptr
= bulkdata
.d
[0].os_data_ptr
;
1711 interfacePriv
->wapi_unicast_bulk_data
.os_net_buf_ptr
= bulkdata
.d
[0].os_net_buf_ptr
;
1712 spin_unlock(&priv
->wapi_lock
);
1714 /* Signal the workqueue to call CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend().
1715 * It cannot be called directly from the tx path because it
1716 * does a non-atomic kmalloc via the framework's CsrPmemAlloc().
1718 queue_work(priv
->unifi_workqueue
, &netpriv
->send_pkt_to_encrypt
);
1724 if(priv
->cmanrTestMode
)
1726 TransmitRate
= priv
->cmanrTestModeTransmitRate
;
1727 unifi_trace(priv
, UDBG2
, "send_ma_pkt_request: cmanrTestModeTransmitRate = %d TransmitRate=%d\n",
1728 priv
->cmanrTestModeTransmitRate
,
1733 /* Send UniFi msg */
1734 /* Here hostTag is been sent as 0xffffffff, its been appended properly while framing MA-Packet request in pdu_processing.c file */
1735 r
= uf_process_ma_packet_req(priv
,
1737 0xffffffff, /* Ask for a new HostTag */
1739 transmissionControl
,
1742 priv
->netdev_client
->sender_id
,
1746 unifi_trace(priv
, UDBG1
, "(HIP validation failure) r = %x\n", r
);
1747 unifi_net_data_free(priv
, &bulkdata
.d
[0]);
1751 unifi_trace(priv
, UDBG3
, "leaving send_ma_pkt_request, UNITDATA result code = %d\n", r
);
1754 } /* send_ma_pkt_request() */
1757 * ---------------------------------------------------------------------------
1760 * This function is called by the higher level stack to transmit an
1764 * skb Ethernet packet to send.
1765 * dev Pointer to the linux net device.
1768 * 0 on success (packet was consumed, not necessarily transmitted)
1769 * 1 if packet was requeued
1774 * The controlled port is handled in the qdisc dequeue handler.
1775 * ---------------------------------------------------------------------------
1778 uf_net_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
1780 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
1781 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
1785 static tx_signal_handler tx_handler
;
1786 CSR_PRIORITY priority
;
1787 CsrWifiRouterCtrlPortAction port_action
;
1791 unifi_trace(priv
, UDBG5
, "unifi_net_xmit: skb = %x\n", skb
);
1793 memcpy(&ehdr
, skb
->data
, ETH_HLEN
);
1794 proto
= ntohs(ehdr
.h_proto
);
1795 priority
= get_packet_priority(priv
, skb
, &ehdr
, interfacePriv
);
1797 /* All frames are sent as MA-PACKET.req (EAPOL also) */
1798 tx_handler
= send_ma_pkt_request
;
1800 /* 802.1x - apply controlled/uncontrolled port rules */
1801 if ((proto
!= ETH_P_PAE
)
1802 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1803 && (proto
!= ETH_P_WAI
)
1806 port
= UF_CONTROLLED_PORT_Q
;
1809 port
= UF_UNCONTROLLED_PORT_Q
;
1812 /* Uncontrolled port rules apply */
1813 port_action
= verify_port(priv
1814 , (((CSR_WIFI_ROUTER_CTRL_MODE_STA
== interfacePriv
->interfaceMode
)||(CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI
== interfacePriv
->interfaceMode
))? interfacePriv
->bssid
.a
: ehdr
.h_dest
)
1816 , interfacePriv
->InterfaceTag
);
1818 if (port_action
== CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN
) {
1819 unifi_trace(priv
, UDBG5
,
1820 "uf_net_xmit: %s controlled port open\n",
1822 /* Remove the ethernet header */
1823 skb_pull(skb
, ETH_HLEN
);
1824 result
= tx_handler(priv
, skb
, &ehdr
, priority
);
1827 /* Discard the packet if necessary */
1828 unifi_trace(priv
, UDBG2
,
1829 "uf_net_xmit: %s controlled port %s\n",
1830 port
? "" : "un", port_action
==CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK
? "blocked" : "closed");
1831 interfacePriv
->stats
.tx_dropped
++;
1835 return NETDEV_TX_OK
;
1838 if (result
== NETDEV_TX_OK
) {
1839 #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
1840 /* Don't update the tx stats when the pkt is to be sent for sw encryption*/
1841 if (!((CSR_WIFI_ROUTER_CTRL_MODE_STA
== interfacePriv
->interfaceMode
) &&
1842 (priv
->wapi_unicast_filter
== 1)))
1844 dev
->trans_start
= jiffies
;
1845 /* Should really count tx stats in the UNITDATA.status signal but
1846 * that doesn't have the length.
1848 interfacePriv
->stats
.tx_packets
++;
1849 /* count only the packet payload */
1850 interfacePriv
->stats
.tx_bytes
+= skb
->len
;
1854 dev
->trans_start
= jiffies
;
1857 * Should really count tx stats in the UNITDATA.status signal but
1858 * that doesn't have the length.
1860 interfacePriv
->stats
.tx_packets
++;
1861 /* count only the packet payload */
1862 interfacePriv
->stats
.tx_bytes
+= skb
->len
;
1864 } else if (result
< 0) {
1866 /* Failed to send: fh queue was full, and the skb was discarded.
1867 * Return OK to indicate that the buffer was consumed, to stop the
1868 * kernel re-transmitting the freed buffer.
1870 interfacePriv
->stats
.tx_dropped
++;
1871 unifi_trace(priv
, UDBG1
, "unifi_net_xmit: (Packet Drop), dropped count = %x\n", interfacePriv
->stats
.tx_dropped
);
1872 result
= NETDEV_TX_OK
;
1875 /* The skb will have been freed by send_XXX_request() */
1879 } /* uf_net_xmit() */
1882 * ---------------------------------------------------------------------------
1884 * unifi_restart_xmit
1886 * These functions are called from the UniFi core to control the flow
1887 * of packets from the upper layers.
1888 * unifi_pause_xmit() is called when the internal queue is full and
1889 * should take action to stop unifi_ma_unitdata() being called.
1890 * When the queue has drained, unifi_restart_xmit() will be called to
1891 * re-enable the flow of packets for transmission.
1894 * ospriv OS private context pointer.
1897 * unifi_pause_xmit() is called from interrupt context.
1898 * ---------------------------------------------------------------------------
1901 unifi_pause_xmit(void *ospriv
, unifi_TrafficQueue queue
)
1903 unifi_priv_t
*priv
= ospriv
;
1904 int i
; /* used as a loop counter */
1907 unifi_trace(priv
, UDBG2
, "Stopping queue %d\n", queue
);
1909 for(i
=0;i
<CSR_WIFI_NUM_INTERFACES
;i
++)
1911 if (netif_running(priv
->netdev
[i
]))
1913 netif_stop_subqueue(priv
->netdev
[i
], (u16
)queue
);
1917 #ifdef CSR_SUPPORT_SME
1919 routerStartBuffering(priv
,queue
);
1920 unifi_trace(priv
,UDBG2
,"Start buffering %d\n", queue
);
1922 routerStartBuffering(priv
,0);
1923 unifi_error(priv
, "Start buffering %d defaulting to 0\n", queue
);
1928 } /* unifi_pause_xmit() */
1931 unifi_restart_xmit(void *ospriv
, unifi_TrafficQueue queue
)
1933 unifi_priv_t
*priv
= ospriv
;
1934 int i
=0; /* used as a loop counter */
1937 unifi_trace(priv
, UDBG2
, "Waking queue %d\n", queue
);
1939 for(i
=0;i
<CSR_WIFI_NUM_INTERFACES
;i
++)
1941 if (netif_running(priv
->netdev
[i
]))
1943 netif_wake_subqueue(priv
->netdev
[i
], (u16
)queue
);
1947 #ifdef CSR_SUPPORT_SME
1949 routerStopBuffering(priv
,queue
);
1950 uf_send_buffered_frames(priv
,queue
);
1952 routerStopBuffering(priv
,0);
1953 uf_send_buffered_frames(priv
,0);
1957 } /* unifi_restart_xmit() */
1961 indicate_rx_skb(unifi_priv_t
*priv
, u16 ifTag
, u8
* dst_a
, u8
* src_a
, struct sk_buff
*skb
, CSR_SIGNAL
*signal
,
1962 bulk_data_param_t
*bulkdata
)
1965 struct net_device
*dev
;
1967 #ifdef CSR_SUPPORT_SME
1968 llc_snap_hdr_t
*snap
;
1970 snap
= (llc_snap_hdr_t
*)skb
->data
;
1972 sr
= _identify_sme_ma_pkt_ind(priv
,
1973 snap
->oui
, ntohs(snap
->protocol
),
1980 * Decapsulate any SNAP header and
1981 * prepend an ethernet header so that the skb manipulation and ARP
1984 r
= skb_80211_to_ether(priv
, skb
, dst_a
, src_a
,
1987 /* Drop the packet and return */
1988 priv
->interfacePriv
[ifTag
]->stats
.rx_errors
++;
1989 priv
->interfacePriv
[ifTag
]->stats
.rx_frame_errors
++;
1990 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
1991 unifi_notice(priv
, "indicate_rx_skb: Discard unknown frame.\n");
1996 /* Handle the case where packet is sent up through the subscription
1997 * API but should not be given to the network stack (AMP PAL case)
1998 * LLC header is different from WiFi and the packet has been subscribed for
2000 if (r
== 1 && sr
== 1) {
2001 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2002 unifi_trace(priv
, UDBG5
, "indicate_rx_skb: Data given to subscription"
2003 "API, not being given to kernel\n");
2008 dev
= priv
->netdev
[ifTag
];
2009 /* Now we look like a regular ethernet frame */
2010 /* Fill in SKB meta data */
2012 skb
->protocol
= eth_type_trans(skb
, dev
);
2013 skb
->ip_summed
= CHECKSUM_UNNECESSARY
;
2015 /* Test for an overlength frame */
2016 if (skb
->len
> (dev
->mtu
+ ETH_HLEN
)) {
2017 /* A bogus length ethfrm has been encap'd. */
2018 /* Is someone trying an oflow attack? */
2019 unifi_error(priv
, "%s: oversize frame (%d > %d)\n",
2021 skb
->len
, dev
->mtu
+ ETH_HLEN
);
2023 /* Drop the packet and return */
2024 priv
->interfacePriv
[ifTag
]->stats
.rx_errors
++;
2025 priv
->interfacePriv
[ifTag
]->stats
.rx_length_errors
++;
2026 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2032 if(priv
->cmanrTestMode
)
2034 const CSR_MA_PACKET_INDICATION
*pkt_ind
= &signal
->u
.MaPacketIndication
;
2035 priv
->cmanrTestModeTransmitRate
= pkt_ind
->ReceivedRate
;
2036 unifi_trace(priv
, UDBG2
, "indicate_rx_skb: cmanrTestModeTransmitRate=%d\n", priv
->cmanrTestModeTransmitRate
);
2039 /* Pass SKB up the stack */
2040 #ifdef CSR_WIFI_USE_NETIF_RX
2047 dev
->last_rx
= jiffies
;
2051 priv
->interfacePriv
[ifTag
]->stats
.rx_packets
++;
2052 priv
->interfacePriv
[ifTag
]->stats
.rx_bytes
+= bulkdata
->d
[0].data_length
;
2059 uf_process_rx_pending_queue(unifi_priv_t
*priv
, int queue
,
2060 CsrWifiMacAddress source_address
,
2061 int indicate
, u16 interfaceTag
)
2063 rx_buffered_packets_t
*rx_q_item
;
2064 struct list_head
*rx_list
;
2065 struct list_head
*n
;
2066 struct list_head
*l_h
;
2067 static const CsrWifiMacAddress broadcast_address
= {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
2068 netInterface_priv_t
*interfacePriv
= priv
->interfacePriv
[interfaceTag
];
2070 if (interfaceTag
>= CSR_WIFI_NUM_INTERFACES
) {
2071 unifi_error(priv
, "uf_process_rx_pending_queue bad interfaceTag\n");
2075 if (queue
== UF_CONTROLLED_PORT_Q
) {
2076 rx_list
= &interfacePriv
->rx_controlled_list
;
2078 rx_list
= &interfacePriv
->rx_uncontrolled_list
;
2081 down(&priv
->rx_q_sem
);
2082 list_for_each_safe(l_h
, n
, rx_list
) {
2083 rx_q_item
= list_entry(l_h
, rx_buffered_packets_t
, q
);
2085 /* Validate against the source address */
2086 if (memcmp(broadcast_address
.a
, source_address
.a
, ETH_ALEN
) &&
2087 memcmp(rx_q_item
->sa
.a
, source_address
.a
, ETH_ALEN
)) {
2089 unifi_trace(priv
, UDBG2
,
2090 "uf_process_rx_pending_queue: Skipping sa=%02X%02X%02X%02X%02X%02X skb=%p, bulkdata=%p\n",
2091 rx_q_item
->sa
.a
[0], rx_q_item
->sa
.a
[1],
2092 rx_q_item
->sa
.a
[2], rx_q_item
->sa
.a
[3],
2093 rx_q_item
->sa
.a
[4], rx_q_item
->sa
.a
[5],
2094 rx_q_item
->skb
, &rx_q_item
->bulkdata
.d
[0]);
2101 unifi_trace(priv
, UDBG2
,
2102 "uf_process_rx_pending_queue: Was Blocked skb=%p, bulkdata=%p\n",
2103 rx_q_item
->skb
, &rx_q_item
->bulkdata
);
2106 indicate_rx_skb(priv
, interfaceTag
, rx_q_item
->da
.a
, rx_q_item
->sa
.a
, rx_q_item
->skb
, &rx_q_item
->signal
, &rx_q_item
->bulkdata
);
2108 interfacePriv
->stats
.rx_dropped
++;
2109 unifi_net_data_free(priv
, &rx_q_item
->bulkdata
.d
[0]);
2112 /* It is our resposibility to free the Rx structure object. */
2115 up(&priv
->rx_q_sem
);
2119 * ---------------------------------------------------------------------------
2120 * uf_resume_data_plane
2122 * Is called when the (un)controlled port is set to open,
2123 * to notify the network stack to schedule for transmission
2124 * any packets queued in the qdisk while port was closed and
2125 * indicated to the stack any packets buffered in the Rx queues.
2128 * priv Pointer to device private struct
2131 * ---------------------------------------------------------------------------
2134 uf_resume_data_plane(unifi_priv_t
*priv
, int queue
,
2135 CsrWifiMacAddress peer_address
,
2138 #ifdef CSR_SUPPORT_WEXT
2139 netInterface_priv_t
*interfacePriv
= priv
->interfacePriv
[interfaceTag
];
2142 if (interfaceTag
>= CSR_WIFI_NUM_INTERFACES
) {
2143 unifi_error(priv
, "uf_resume_data_plane bad interfaceTag\n");
2147 unifi_trace(priv
, UDBG2
, "Resuming netif\n");
2150 * If we are waiting for the net device to enter the up state, don't
2151 * process the rx queue yet as it will be done by the callback when
2152 * the device is ready.
2154 #ifdef CSR_SUPPORT_WEXT
2155 if (!interfacePriv
->wait_netdev_change
)
2158 #ifdef CONFIG_NET_SCHED
2159 if (netif_running(priv
->netdev
[interfaceTag
])) {
2160 netif_tx_schedule_all(priv
->netdev
[interfaceTag
]);
2163 uf_process_rx_pending_queue(priv
, queue
, peer_address
, 1,interfaceTag
);
2165 } /* uf_resume_data_plane() */
2168 void uf_free_pending_rx_packets(unifi_priv_t
*priv
, int queue
, CsrWifiMacAddress peer_address
,u16 interfaceTag
)
2170 uf_process_rx_pending_queue(priv
, queue
, peer_address
, 0,interfaceTag
);
2172 } /* uf_free_pending_rx_packets() */
2176 * ---------------------------------------------------------------------------
2179 * Reformat a UniFi data received packet into a p80211 packet and
2180 * pass it up the protocol stack.
2187 * ---------------------------------------------------------------------------
2190 unifi_rx(unifi_priv_t
*priv
, CSR_SIGNAL
*signal
, bulk_data_param_t
*bulkdata
)
2193 bulk_data_desc_t
*pData
;
2194 const CSR_MA_PACKET_INDICATION
*pkt_ind
= &signal
->u
.MaPacketIndication
;
2195 struct sk_buff
*skb
;
2196 CsrWifiRouterCtrlPortAction port_action
;
2201 u8 da
[ETH_ALEN
], sa
[ETH_ALEN
];
2202 u8 toDs
, fromDs
, frameType
, macHeaderLengthInBytes
= MAC_HEADER_SIZE
;
2204 netInterface_priv_t
*interfacePriv
;
2209 interfaceTag
= (pkt_ind
->VirtualInterfaceIdentifier
& 0xff);
2210 interfacePriv
= priv
->interfacePriv
[interfaceTag
];
2212 /* Sanity check that the VIF refers to a sensible interface */
2213 if (interfaceTag
>= CSR_WIFI_NUM_INTERFACES
)
2215 unifi_error(priv
, "%s: MA-PACKET indication with bad interfaceTag %d\n", __FUNCTION__
, interfaceTag
);
2216 unifi_net_data_free(priv
,&bulkdata
->d
[0]);
2221 /* Sanity check that the VIF refers to an allocated netdev */
2222 if (!interfacePriv
->netdev_registered
)
2224 unifi_error(priv
, "%s: MA-PACKET indication with unallocated interfaceTag %d\n", __FUNCTION__
, interfaceTag
);
2225 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2230 if (bulkdata
->d
[0].data_length
== 0) {
2231 unifi_warning(priv
, "%s: MA-PACKET indication with zero bulk data\n", __FUNCTION__
);
2232 unifi_net_data_free(priv
,&bulkdata
->d
[0]);
2238 skb
= (struct sk_buff
*)bulkdata
->d
[0].os_net_buf_ptr
;
2239 skb
->len
= bulkdata
->d
[0].data_length
;
2241 /* Point to the addresses */
2242 toDs
= (skb
->data
[1] & 0x01) ? 1 : 0;
2243 fromDs
= (skb
->data
[1] & 0x02) ? 1 : 0;
2245 memcpy(da
,(skb
->data
+4+toDs
*12),ETH_ALEN
);/* Address1 or 3 */
2246 memcpy(sa
,(skb
->data
+10+fromDs
*(6+toDs
*8)),ETH_ALEN
); /* Address2, 3 or 4 */
2249 pData
= &bulkdata
->d
[0];
2250 frameControl
= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData
->os_data_ptr
);
2251 frameType
= ((frameControl
& 0x000C) >> 2);
2253 dataFrameType
=((frameControl
& 0x00f0) >> 4);
2254 unifi_trace(priv
, UDBG6
,
2255 "%s: Receive Data Frame Type %d \n", __FUNCTION__
,dataFrameType
);
2257 switch(dataFrameType
)
2261 /* If both are set then the Address4 exists (only for AP) */
2264 /* 6 is the size of Address4 field */
2265 macHeaderLengthInBytes
+= (QOS_CONTROL_HEADER_SIZE
+ 6);
2269 macHeaderLengthInBytes
+= QOS_CONTROL_HEADER_SIZE
;
2272 /* If order bit set then HT control field is the part of MAC header */
2273 if (frameControl
& FRAME_CONTROL_ORDER_BIT
)
2274 macHeaderLengthInBytes
+= HT_CONTROL_HEADER_SIZE
;
2278 macHeaderLengthInBytes
+= 6;
2281 /* Prepare the ethernet header from snap header of skb data */
2282 switch(dataFrameType
)
2286 /* This is for only queue info fetching, EAPOL wont come as
2287 * null data so the proto is initialized as zero
2293 llc_snap_hdr_t
*snap
;
2294 /* Fetch a snap header to find protocol (for IPV4/IPV6 packets
2295 * the snap header fetching offset is same)
2297 snap
= (llc_snap_hdr_t
*) (skb
->data
+ macHeaderLengthInBytes
);
2299 /* prepare the ethernet header from the snap header & addresses */
2300 ehdr
.h_proto
= snap
->protocol
;
2301 memcpy(ehdr
.h_dest
, da
, ETH_ALEN
);
2302 memcpy(ehdr
.h_source
, sa
, ETH_ALEN
);
2304 proto
= ntohs(ehdr
.h_proto
);
2306 unifi_trace(priv
, UDBG3
, "in unifi_rx protocol from snap header = 0x%x\n", proto
);
2308 if ((proto
!= ETH_P_PAE
)
2309 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
2310 && (proto
!= ETH_P_WAI
)
2313 queue
= UF_CONTROLLED_PORT_Q
;
2315 queue
= UF_UNCONTROLLED_PORT_Q
;
2318 port_action
= verify_port(priv
, (unsigned char*)sa
, queue
, interfaceTag
);
2319 unifi_trace(priv
, UDBG3
, "in unifi_rx port action is = 0x%x & queue = %x\n", port_action
, queue
);
2321 #ifdef CSR_SUPPORT_SME
2322 /* Notify the TA module for the Rx frame for non P2PGO and AP cases*/
2323 if((interfacePriv
->interfaceMode
!= CSR_WIFI_ROUTER_CTRL_MODE_AP
) &&
2324 (interfacePriv
->interfaceMode
!= CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
))
2326 /* Remove MAC header of length(macHeaderLengthInBytes) before sampling */
2327 skb_pull(skb
, macHeaderLengthInBytes
);
2328 pData
->os_data_ptr
= skb
->data
;
2329 pData
->data_length
-= macHeaderLengthInBytes
;
2331 if (pData
->data_length
) {
2332 unifi_ta_sample(priv
->card
, CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_RX
,
2334 sa
, priv
->netdev
[interfaceTag
]->dev_addr
,
2335 jiffies_to_msecs(jiffies
),
2336 pkt_ind
->ReceivedRate
);
2340 /* AP/P2PGO specific handling here */
2341 CsrWifiRouterCtrlStaInfo_t
* srcStaInfo
=
2342 CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv
,sa
,interfaceTag
);
2344 /* Defensive check only; Source address is already checked in
2345 process_ma_packet_ind and we should have a valid source address here */
2347 if(srcStaInfo
== NULL
) {
2348 CsrWifiMacAddress peerMacAddress
;
2349 /* Unknown data PDU */
2350 memcpy(peerMacAddress
.a
,sa
,ETH_ALEN
);
2351 unifi_trace(priv
, UDBG1
, "%s: Unexpected frame from peer = %x:%x:%x:%x:%x:%x\n", __FUNCTION__
,
2352 sa
[0], sa
[1],sa
[2], sa
[3], sa
[4],sa
[5]);
2353 CsrWifiRouterCtrlUnexpectedFrameIndSend(priv
->CSR_WIFI_SME_IFACEQUEUE
,0,interfaceTag
,peerMacAddress
);
2354 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2359 /* For AP GO mode, don't store the PDUs */
2360 if (port_action
!= CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN
) {
2361 /* Drop the packet and return */
2362 CsrWifiMacAddress peerMacAddress
;
2363 memcpy(peerMacAddress
.a
,sa
,ETH_ALEN
);
2364 unifi_trace(priv
, UDBG3
, "%s: Port is not open: unexpected frame from peer = %x:%x:%x:%x:%x:%x\n",
2365 __FUNCTION__
, sa
[0], sa
[1],sa
[2], sa
[3], sa
[4],sa
[5]);
2367 CsrWifiRouterCtrlUnexpectedFrameIndSend(priv
->CSR_WIFI_SME_IFACEQUEUE
,0,interfaceTag
,peerMacAddress
);
2368 interfacePriv
->stats
.rx_dropped
++;
2369 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2370 unifi_notice(priv
, "%s: Dropping packet, proto=0x%04x, %s port\n", __FUNCTION__
,
2371 proto
, queue
? "Controlled" : "Un-controlled");
2376 /* Qos NULL/Data NULL are freed here and not processed further */
2377 if((dataFrameType
== QOS_DATA_NULL
) || (dataFrameType
== DATA_NULL
)){
2378 unifi_trace(priv
, UDBG5
, "%s: Null Frame Received and Freed\n", __FUNCTION__
);
2379 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2384 /* Now we have done with MAC header so proceed with the real data part*/
2385 /* This function takes care of appropriate routing for AP/P2PGO case*/
2386 /* the function hadnles following things
2387 2. Routing the PDU to appropriate location
2388 3. Error case handling
2390 if(!(uf_ap_process_data_pdu(priv
, skb
, &ehdr
, srcStaInfo
,
2393 macHeaderLengthInBytes
)))
2398 unifi_trace(priv
, UDBG5
, "unifi_rx: no specific AP handling process as normal frame, MAC Header len %d\n",macHeaderLengthInBytes
);
2399 /* Remove the MAC header for subsequent conversion */
2400 skb_pull(skb
, macHeaderLengthInBytes
);
2401 pData
->os_data_ptr
= skb
->data
;
2402 pData
->data_length
-= macHeaderLengthInBytes
;
2403 pData
->os_net_buf_ptr
= (unsigned char*)skb
;
2404 pData
->net_buf_length
= skb
->len
;
2406 #endif /* CSR_SUPPORT_SME */
2409 /* Now that the MAC header is removed, null-data frames have zero length
2410 * and can be dropped
2412 if (pData
->data_length
== 0) {
2413 if (((frameControl
& 0x00f0) >> 4) != QOS_DATA_NULL
&&
2414 ((frameControl
& 0x00f0) >> 4) != DATA_NULL
) {
2415 unifi_trace(priv
, UDBG1
, "Zero length frame, but not null-data %04x\n", frameControl
);
2417 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2422 if (port_action
== CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD
) {
2423 /* Drop the packet and return */
2424 interfacePriv
->stats
.rx_dropped
++;
2425 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2426 unifi_notice(priv
, "%s: Dropping packet, proto=0x%04x, %s port\n",
2427 __FUNCTION__
, proto
, queue
? "controlled" : "uncontrolled");
2430 } else if ( (port_action
== CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK
) ||
2431 (interfacePriv
->connected
!= UnifiConnected
) ) {
2433 /* Buffer the packet into the Rx queues */
2434 rx_buffered_packets_t
*rx_q_item
;
2435 struct list_head
*rx_list
;
2437 rx_q_item
= (rx_buffered_packets_t
*)kmalloc(sizeof(rx_buffered_packets_t
),
2439 if (rx_q_item
== NULL
) {
2440 unifi_error(priv
, "%s: Failed to allocate %d bytes for rx packet record\n",
2441 __FUNCTION__
, sizeof(rx_buffered_packets_t
));
2442 interfacePriv
->stats
.rx_dropped
++;
2443 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2448 INIT_LIST_HEAD(&rx_q_item
->q
);
2449 rx_q_item
->bulkdata
= *bulkdata
;
2450 rx_q_item
->skb
= skb
;
2451 rx_q_item
->signal
= *signal
;
2452 memcpy(rx_q_item
->sa
.a
, sa
, ETH_ALEN
);
2453 memcpy(rx_q_item
->da
.a
, da
, ETH_ALEN
);
2454 unifi_trace(priv
, UDBG2
, "%s: Blocked skb=%p, bulkdata=%p\n",
2455 __FUNCTION__
, rx_q_item
->skb
, &rx_q_item
->bulkdata
);
2457 if (queue
== UF_CONTROLLED_PORT_Q
) {
2458 rx_list
= &interfacePriv
->rx_controlled_list
;
2460 rx_list
= &interfacePriv
->rx_uncontrolled_list
;
2463 /* Add to tail of packets queue */
2464 down(&priv
->rx_q_sem
);
2465 list_add_tail(&rx_q_item
->q
, rx_list
);
2466 up(&priv
->rx_q_sem
);
2473 indicate_rx_skb(priv
, interfaceTag
, da
, sa
, skb
, signal
, bulkdata
);
2479 static void process_ma_packet_cfm(unifi_priv_t
*priv
, CSR_SIGNAL
*signal
, bulk_data_param_t
*bulkdata
)
2482 const CSR_MA_PACKET_CONFIRM
*pkt_cfm
= &signal
->u
.MaPacketConfirm
;
2483 netInterface_priv_t
*interfacePriv
;
2486 interfaceTag
= (pkt_cfm
->VirtualInterfaceIdentifier
& 0xff);
2487 interfacePriv
= priv
->interfacePriv
[interfaceTag
];
2489 /* Sanity check that the VIF refers to a sensible interface */
2490 if (interfaceTag
>= CSR_WIFI_NUM_INTERFACES
)
2492 unifi_error(priv
, "%s: MA-PACKET confirm with bad interfaceTag %d\n", __FUNCTION__
, interfaceTag
);
2496 #ifdef CSR_SUPPORT_SME
2497 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
2498 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
2500 uf_process_ma_pkt_cfm_for_ap(priv
,interfaceTag
,pkt_cfm
);
2501 } else if (interfacePriv
->m4_sent
&& (pkt_cfm
->HostTag
== interfacePriv
->m4_hostTag
)) {
2502 /* Check if this is a confirm for EAPOL M4 frame and we need to send transmistted ind*/
2503 CsrResult result
= pkt_cfm
->TransmissionStatus
== CSR_TX_SUCCESSFUL
?CSR_RESULT_SUCCESS
:CSR_RESULT_FAILURE
;
2504 CsrWifiMacAddress peerMacAddress
;
2505 memcpy(peerMacAddress
.a
, interfacePriv
->m4_signal
.u
.MaPacketRequest
.Ra
.x
, ETH_ALEN
);
2507 unifi_trace(priv
, UDBG1
, "%s: Sending M4 Transmit CFM\n", __FUNCTION__
);
2508 CsrWifiRouterCtrlM4TransmittedIndSend(priv
->CSR_WIFI_SME_IFACEQUEUE
, 0,
2512 interfacePriv
->m4_sent
= FALSE
;
2513 interfacePriv
->m4_hostTag
= 0xffffffff;
2522 * ---------------------------------------------------------------------------
2525 * Reformat a UniFi data received packet into a p80211 packet and
2526 * pass it up the protocol stack.
2533 * ---------------------------------------------------------------------------
2535 static void process_ma_packet_ind(unifi_priv_t
*priv
, CSR_SIGNAL
*signal
, bulk_data_param_t
*bulkdata
)
2538 bulk_data_desc_t
*pData
;
2539 CSR_MA_PACKET_INDICATION
*pkt_ind
= (CSR_MA_PACKET_INDICATION
*)&signal
->u
.MaPacketIndication
;
2540 struct sk_buff
*skb
;
2542 netInterface_priv_t
*interfacePriv
;
2543 u8 da
[ETH_ALEN
], sa
[ETH_ALEN
];
2544 u8
*bssid
= NULL
, *ba_addr
= NULL
;
2545 u8 toDs
, fromDs
, frameType
;
2548 #ifdef CSR_SUPPORT_SME
2549 u8 dataFrameType
= 0;
2550 u8 powerSaveChanged
= FALSE
;
2552 CsrWifiRouterCtrlStaInfo_t
*srcStaInfo
= NULL
;
2559 interfaceTag
= (pkt_ind
->VirtualInterfaceIdentifier
& 0xff);
2560 interfacePriv
= priv
->interfacePriv
[interfaceTag
];
2563 /* Sanity check that the VIF refers to a sensible interface */
2564 if (interfaceTag
>= CSR_WIFI_NUM_INTERFACES
)
2566 unifi_error(priv
, "%s: MA-PACKET indication with bad interfaceTag %d\n", __FUNCTION__
, interfaceTag
);
2567 unifi_net_data_free(priv
,&bulkdata
->d
[0]);
2572 /* Sanity check that the VIF refers to an allocated netdev */
2573 if (!interfacePriv
->netdev_registered
)
2575 unifi_error(priv
, "%s: MA-PACKET indication with unallocated interfaceTag %d\n", __FUNCTION__
, interfaceTag
);
2576 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2581 if (bulkdata
->d
[0].data_length
== 0) {
2582 unifi_warning(priv
, "%s: MA-PACKET indication with zero bulk data\n", __FUNCTION__
);
2583 unifi_net_data_free(priv
,&bulkdata
->d
[0]);
2587 /* For monitor mode we need to pass this indication to the registered application
2588 handle this seperately*/
2589 /* MIC failure is already taken care of so no need to send the PDUs which are not successfully received in non-monitor mode*/
2590 if(pkt_ind
->ReceptionStatus
!= CSR_RX_SUCCESS
)
2592 unifi_warning(priv
, "%s: MA-PACKET indication with status = %d\n",__FUNCTION__
, pkt_ind
->ReceptionStatus
);
2593 unifi_net_data_free(priv
,&bulkdata
->d
[0]);
2599 skb
= (struct sk_buff
*)bulkdata
->d
[0].os_net_buf_ptr
;
2600 skb
->len
= bulkdata
->d
[0].data_length
;
2602 /* Point to the addresses */
2603 toDs
= (skb
->data
[1] & 0x01) ? 1 : 0;
2604 fromDs
= (skb
->data
[1] & 0x02) ? 1 : 0;
2606 memcpy(da
,(skb
->data
+4+toDs
*12),ETH_ALEN
);/* Address1 or 3 */
2607 memcpy(sa
,(skb
->data
+10+fromDs
*(6+toDs
*8)),ETH_ALEN
); /* Address2, 3 or 4 */
2609 /* Find the BSSID, which will be used to match the BA session */
2612 unifi_trace(priv
, UDBG6
, "4 address frame - don't try to find BSSID\n");
2617 bssid
= (u8
*) (skb
->data
+ 4 + 12 - (fromDs
* 6) - (toDs
* 12));
2620 pData
= &bulkdata
->d
[0];
2621 frameControl
= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData
->os_data_ptr
);
2622 frameType
= ((frameControl
& 0x000C) >> 2);
2624 unifi_trace(priv
, UDBG3
, "Rx Frame Type: %d sn: %d\n",frameType
,
2625 (le16_to_cpu(*((u16
*)(bulkdata
->d
[0].os_data_ptr
+ IEEE802_11_SEQUENCE_CONTROL_OFFSET
))) >> 4) & 0xfff);
2626 if(frameType
== IEEE802_11_FRAMETYPE_CONTROL
){
2627 #ifdef CSR_SUPPORT_SME
2628 unifi_trace(priv
, UDBG6
, "%s: Received Control Frame\n", __FUNCTION__
);
2630 if((frameControl
& 0x00f0) == 0x00A0){
2631 /* This is a PS-POLL request */
2632 u8 pmBit
= (frameControl
& 0x1000)?0x01:0x00;
2633 unifi_trace(priv
, UDBG6
, "%s: Received PS-POLL Frame\n", __FUNCTION__
);
2635 uf_process_ps_poll(priv
,sa
,da
,pmBit
,interfaceTag
);
2638 unifi_warning(priv
, "%s: Non PS-POLL control frame is received\n", __FUNCTION__
);
2641 unifi_net_data_free(priv
,&bulkdata
->d
[0]);
2645 if(frameType
!= IEEE802_11_FRAMETYPE_DATA
) {
2646 unifi_warning(priv
, "%s: Non control Non Data frame is received\n",__FUNCTION__
);
2647 unifi_net_data_free(priv
,&bulkdata
->d
[0]);
2652 #ifdef CSR_SUPPORT_SME
2653 if((interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
) ||
2654 (interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
)){
2656 srcStaInfo
= CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv
,sa
,interfaceTag
);
2658 if(srcStaInfo
== NULL
) {
2659 CsrWifiMacAddress peerMacAddress
;
2660 /* Unknown data PDU */
2661 memcpy(peerMacAddress
.a
,sa
,ETH_ALEN
);
2662 unifi_trace(priv
, UDBG1
, "%s: Unexpected frame from peer = %x:%x:%x:%x:%x:%x\n", __FUNCTION__
,
2663 sa
[0], sa
[1],sa
[2], sa
[3], sa
[4],sa
[5]);
2664 CsrWifiRouterCtrlUnexpectedFrameIndSend(priv
->CSR_WIFI_SME_IFACEQUEUE
,0,interfaceTag
,peerMacAddress
);
2665 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
2671 verify power management bit here so as to ensure host and unifi are always
2672 in sync with power management status of peer.
2674 If we do it later, it may so happen we have stored the frame in BA re-ordering
2675 buffer and hence host and unifi are out of sync for power management status
2678 pmBit
= (frameControl
& 0x1000)?0x01:0x00;
2679 powerSaveChanged
= uf_process_pm_bit_for_peer(priv
,srcStaInfo
,pmBit
,interfaceTag
);
2681 /* Update station last activity time */
2682 srcStaInfo
->activity_flag
= TRUE
;
2684 /* For Qos Frame if PM bit is toggled to indicate the change in power save state then it shall not be
2685 considered as Trigger Frame. Enter only if WMM STA and peer is in Power save */
2687 dataFrameType
= ((frameControl
& 0x00f0) >> 4);
2689 if((powerSaveChanged
== FALSE
)&&(srcStaInfo
->wmmOrQosEnabled
== TRUE
)&&
2690 (srcStaInfo
->currentPeerState
== CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE
)){
2692 if((dataFrameType
== QOS_DATA
) || (dataFrameType
== QOS_DATA_NULL
)){
2695 * QoS control field is offset from frame control by 2 (frame control)
2696 * + 2 (duration/ID) + 2 (sequence control) + 3*ETH_ALEN or 4*ETH_ALEN
2698 if((frameControl
& IEEE802_11_FC_TO_DS_MASK
) && (frameControl
& IEEE802_11_FC_FROM_DS_MASK
)){
2699 qosControl
= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData
->os_data_ptr
+ 30);
2702 qosControl
= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData
->os_data_ptr
+ 24);
2704 unifi_trace(priv
, UDBG5
, "%s: Check if U-APSD operations are triggered for qosControl: 0x%x\n",__FUNCTION__
,qosControl
);
2705 uf_process_wmm_deliver_ac_uapsd(priv
,srcStaInfo
,qosControl
,interfaceTag
);
2712 if( ((frameControl
& 0x00f0) >> 4) == QOS_DATA
) {
2713 u8
*qos_control_ptr
= (u8
*)bulkdata
->d
[0].os_data_ptr
+ (((frameControl
& IEEE802_11_FC_TO_DS_MASK
) && (frameControl
& IEEE802_11_FC_FROM_DS_MASK
))?30: 24);
2714 int tID
= *qos_control_ptr
& IEEE802_11_QC_TID_MASK
; /* using ls octet of qos control */
2715 ba_session_rx_struct
*ba_session
;
2716 u8 ba_session_idx
= 0;
2717 /* Get the BA originator address */
2718 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
2719 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
){
2725 down(&priv
->ba_mutex
);
2726 for (ba_session_idx
=0; ba_session_idx
< MAX_SUPPORTED_BA_SESSIONS_RX
; ba_session_idx
++){
2727 ba_session
= interfacePriv
->ba_session_rx
[ba_session_idx
];
2729 unifi_trace(priv
, UDBG6
, "found ba_session=0x%x ba_session_idx=%d", ba_session
, ba_session_idx
);
2730 if ((!memcmp(ba_session
->macAddress
.a
, ba_addr
, ETH_ALEN
)) && (ba_session
->tID
== tID
)){
2731 frame_desc_struct frame_desc
;
2732 frame_desc
.bulkdata
= *bulkdata
;
2733 frame_desc
.signal
= *signal
;
2734 frame_desc
.sn
= (le16_to_cpu(*((u16
*)(bulkdata
->d
[0].os_data_ptr
+ IEEE802_11_SEQUENCE_CONTROL_OFFSET
))) >> 4) & 0xfff;
2735 frame_desc
.active
= TRUE
;
2736 unifi_trace(priv
, UDBG6
, "%s: calling process_ba_frame (session=%d)\n", __FUNCTION__
, ba_session_idx
);
2737 process_ba_frame(priv
, interfacePriv
, ba_session
, &frame_desc
);
2738 up(&priv
->ba_mutex
);
2739 process_ba_complete(priv
, interfacePriv
);
2744 if (ba_session_idx
== MAX_SUPPORTED_BA_SESSIONS_RX
){
2745 up(&priv
->ba_mutex
);
2746 unifi_trace(priv
, UDBG6
, "%s: calling process_amsdu()", __FUNCTION__
);
2747 process_amsdu(priv
, signal
, bulkdata
);
2750 unifi_trace(priv
, UDBG6
, "calling unifi_rx()");
2751 unifi_rx(priv
, signal
, bulkdata
);
2754 /* check if the frames in reorder buffer has aged, the check
2755 * is done after receive processing so that if the missing frame
2756 * has arrived in this receive process, then it is handled cleanly.
2758 * And also this code here takes care that timeout check is made for all
2759 * the receive indications
2761 down(&priv
->ba_mutex
);
2762 for (i
=0; i
< MAX_SUPPORTED_BA_SESSIONS_RX
; i
++){
2763 ba_session_rx_struct
*ba_session
;
2764 ba_session
= interfacePriv
->ba_session_rx
[i
];
2766 check_ba_frame_age_timeout(priv
, interfacePriv
, ba_session
);
2769 up(&priv
->ba_mutex
);
2770 process_ba_complete(priv
, interfacePriv
);
2775 * ---------------------------------------------------------------------------
2776 * uf_set_multicast_list
2778 * This function is called by the higher level stack to set
2779 * a list of multicast rx addresses.
2782 * dev Network Device pointer.
2788 * ---------------------------------------------------------------------------
2792 uf_set_multicast_list(struct net_device
*dev
)
2794 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
2795 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
2797 #ifdef CSR_NATIVE_LINUX
2798 unifi_trace(priv
, UDBG3
, "uf_set_multicast_list unsupported\n");
2802 u8
*mc_list
= interfacePriv
->mc_list
;
2803 struct netdev_hw_addr
*mc_addr
;
2806 if (priv
->init_progress
!= UNIFI_INIT_COMPLETED
) {
2810 mc_addr_count
= netdev_mc_count(dev
);
2812 unifi_trace(priv
, UDBG3
,
2813 "uf_set_multicast_list (count=%d)\n", mc_addr_count
);
2816 /* Not enough space? */
2817 if (mc_addr_count
> UNIFI_MAX_MULTICAST_ADDRESSES
) {
2821 /* Store the list to be processed by the work item. */
2822 interfacePriv
->mc_list_count
= mc_addr_count
;
2823 netdev_hw_addr_list_for_each(mc_addr
, &dev
->mc
) {
2824 memcpy(mc_list
, mc_addr
->addr
, ETH_ALEN
);
2825 mc_list
+= ETH_ALEN
;
2828 /* Send a message to the workqueue */
2829 queue_work(priv
->unifi_workqueue
, &priv
->multicast_list_task
);
2832 } /* uf_set_multicast_list() */
2835 * ---------------------------------------------------------------------------
2836 * netdev_mlme_event_handler
2838 * Callback function to be used as the udi_event_callback when registering
2839 * as a netdev client.
2840 * To use it, a client specifies this function as the udi_event_callback
2841 * to ul_register_client(). The signal dispatcher in
2842 * unifi_receive_event() will call this function to deliver a signal.
2845 * pcli Pointer to the client instance.
2846 * signal Pointer to the received signal.
2847 * signal_len Size of the signal structure in bytes.
2848 * bulkdata Pointer to structure containing any associated bulk data.
2849 * dir Direction of the signal. Zero means from host,
2850 * non-zero means to host.
2854 * ---------------------------------------------------------------------------
2857 netdev_mlme_event_handler(ul_client_t
*pcli
, const u8
*sig_packed
, int sig_len
,
2858 const bulk_data_param_t
*bulkdata_o
, int dir
)
2861 unifi_priv_t
*priv
= uf_find_instance(pcli
->instance
);
2863 bulk_data_param_t bulkdata
;
2867 /* Just a sanity check */
2868 if (sig_packed
== NULL
) {
2873 * This copy is to silence a compiler warning about discarding the
2876 bulkdata
= *bulkdata_o
;
2878 /* Get the unpacked signal */
2879 r
= read_unpack_signal(sig_packed
, &signal
);
2882 * The CSR_MLME_CONNECTED_INDICATION_ID has a receiverID=0 so will
2883 * fall through this case. It is safe to ignore this signal.
2885 unifi_trace(priv
, UDBG1
,
2886 "Netdev - Received unknown signal 0x%.4X.\n",
2887 CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sig_packed
));
2891 id
= signal
.SignalPrimitiveHeader
.SignalId
;
2892 unifi_trace(priv
, UDBG3
, "Netdev - Process signal 0x%.4X\n", id
);
2895 * Take the appropriate action for the signal.
2898 case CSR_MA_PACKET_ERROR_INDICATION_ID
:
2899 process_ma_packet_error_ind(priv
, &signal
, &bulkdata
);
2901 case CSR_MA_PACKET_INDICATION_ID
:
2902 process_ma_packet_ind(priv
, &signal
, &bulkdata
);
2904 case CSR_MA_PACKET_CONFIRM_ID
:
2905 process_ma_packet_cfm(priv
, &signal
, &bulkdata
);
2907 #ifdef CSR_SUPPORT_SME
2908 case CSR_MLME_SET_TIM_CONFIRM_ID
:
2909 /* Handle TIM confirms from FW & set the station record's TIM state appropriately,
2910 * In case of failures, tries with max_retransmit limit
2912 uf_handle_tim_cfm(priv
, &signal
.u
.MlmeSetTimConfirm
, signal
.SignalPrimitiveHeader
.ReceiverProcessId
);
2915 case CSR_DEBUG_STRING_INDICATION_ID
:
2916 debug_string_indication(priv
, bulkdata
.d
[0].os_data_ptr
, bulkdata
.d
[0].data_length
);
2919 case CSR_DEBUG_WORD16_INDICATION_ID
:
2920 debug_word16_indication(priv
, &signal
);
2923 case CSR_DEBUG_GENERIC_CONFIRM_ID
:
2924 case CSR_DEBUG_GENERIC_INDICATION_ID
:
2925 debug_generic_indication(priv
, &signal
);
2932 } /* netdev_mlme_event_handler() */
2936 * ---------------------------------------------------------------------------
2939 * Retrieve the name (e.g. eth1) associated with this network device
2942 * dev Pointer to the network device.
2943 * name Buffer to write name
2944 * len Size of buffer in bytes
2950 * ---------------------------------------------------------------------------
2952 void uf_net_get_name(struct net_device
*dev
, char *name
, int len
)
2956 strlcpy(name
, dev
->name
, (len
> IFNAMSIZ
) ? IFNAMSIZ
: len
);
2959 } /* uf_net_get_name */
2961 #ifdef CSR_SUPPORT_WEXT
2964 * ---------------------------------------------------------------------------
2967 * Callback function to handle netdev state changes
2970 * notif Pointer to a notifier_block.
2971 * event Event prompting notification
2972 * ptr net_device pointer
2978 * The event handler is global, and may occur on non-UniFi netdevs.
2979 * ---------------------------------------------------------------------------
2982 uf_netdev_event(struct notifier_block
*notif
, unsigned long event
, void* ptr
) {
2983 struct net_device
*netdev
= ptr
;
2984 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(netdev
);
2985 unifi_priv_t
*priv
= NULL
;
2986 static const CsrWifiMacAddress broadcast_address
= {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
2988 /* Check that the event is for a UniFi netdev. If it's not, the netdev_priv
2989 * structure is not safe to use.
2991 if (uf_find_netdev_priv(interfacePriv
) == -1) {
2992 unifi_trace(NULL
, UDBG1
, "uf_netdev_event: ignore e=%d, ptr=%p, priv=%p %s\n",
2993 event
, ptr
, interfacePriv
, netdev
->name
);
2999 priv
= interfacePriv
->privPtr
;
3000 unifi_trace(priv
, UDBG1
, "NETDEV_CHANGE: %p %s %s waiting for it\n",
3003 interfacePriv
->wait_netdev_change
? "" : "not");
3005 if (interfacePriv
->wait_netdev_change
) {
3006 UF_NETIF_TX_WAKE_ALL_QUEUES(priv
->netdev
[interfacePriv
->InterfaceTag
]);
3007 interfacePriv
->connected
= UnifiConnected
;
3008 interfacePriv
->wait_netdev_change
= FALSE
;
3009 /* Note: passing the broadcast address here will allow anyone to attempt to join our adhoc network */
3010 uf_process_rx_pending_queue(priv
, UF_UNCONTROLLED_PORT_Q
, broadcast_address
, 1,interfacePriv
->InterfaceTag
);
3011 uf_process_rx_pending_queue(priv
, UF_CONTROLLED_PORT_Q
, broadcast_address
, 1,interfacePriv
->InterfaceTag
);
3021 static struct notifier_block uf_netdev_notifier
= {
3022 .notifier_call
= uf_netdev_event
,
3024 #endif /* CSR_SUPPORT_WEXT */
3028 process_amsdu(unifi_priv_t
*priv
, CSR_SIGNAL
*signal
, bulk_data_param_t
*bulkdata
)
3031 u32 length
= bulkdata
->d
[0].data_length
;
3032 u32 subframe_length
, subframe_body_length
, dot11_hdr_size
;
3034 bulk_data_param_t subframe_bulkdata
;
3035 u8
*dot11_hdr_ptr
= (u8
*)bulkdata
->d
[0].os_data_ptr
;
3036 CsrResult csrResult
;
3038 u8
*qos_control_ptr
;
3040 frameControl
= le16_to_cpu(*((u16
*)dot11_hdr_ptr
));
3041 qos_control_ptr
= dot11_hdr_ptr
+ (((frameControl
& IEEE802_11_FC_TO_DS_MASK
) && (frameControl
& IEEE802_11_FC_FROM_DS_MASK
))?30: 24);
3042 if(!(*qos_control_ptr
& IEEE802_11_QC_A_MSDU_PRESENT
)) {
3043 unifi_trace(priv
, UDBG6
, "%s: calling unifi_rx()", __FUNCTION__
);
3044 unifi_rx(priv
, signal
, bulkdata
);
3047 *qos_control_ptr
&= ~(IEEE802_11_QC_A_MSDU_PRESENT
);
3049 ptr
= qos_control_ptr
+ 2;
3050 offset
= dot11_hdr_size
= ptr
- dot11_hdr_ptr
;
3052 while(length
> (offset
+ sizeof(struct ethhdr
) + sizeof(llc_snap_hdr_t
))) {
3053 subframe_body_length
= ntohs(((struct ethhdr
*)ptr
)->h_proto
);
3054 if(subframe_body_length
> IEEE802_11_MAX_DATA_LEN
) {
3055 unifi_error(priv
, "%s: bad subframe_body_length = %d\n", __FUNCTION__
, subframe_body_length
);
3058 subframe_length
= sizeof(struct ethhdr
) + subframe_body_length
;
3059 memset(&subframe_bulkdata
, 0, sizeof(bulk_data_param_t
));
3061 csrResult
= unifi_net_data_malloc(priv
, &subframe_bulkdata
.d
[0], dot11_hdr_size
+ subframe_body_length
);
3063 if (csrResult
!= CSR_RESULT_SUCCESS
) {
3064 unifi_error(priv
, "%s: unifi_net_data_malloc failed\n", __FUNCTION__
);
3068 memcpy((u8
*)subframe_bulkdata
.d
[0].os_data_ptr
, dot11_hdr_ptr
, dot11_hdr_size
);
3071 /* When to DS=0 and from DS=0, address 3 will already have BSSID so no need to re-program */
3072 if ((frameControl
& IEEE802_11_FC_TO_DS_MASK
) && !(frameControl
& IEEE802_11_FC_FROM_DS_MASK
)){
3073 memcpy((u8
*)subframe_bulkdata
.d
[0].os_data_ptr
+ IEEE802_11_ADDR3_OFFSET
, ((struct ethhdr
*)ptr
)->h_dest
, ETH_ALEN
);
3075 else if (!(frameControl
& IEEE802_11_FC_TO_DS_MASK
) && (frameControl
& IEEE802_11_FC_FROM_DS_MASK
)){
3076 memcpy((u8
*)subframe_bulkdata
.d
[0].os_data_ptr
+ IEEE802_11_ADDR3_OFFSET
,
3077 ((struct ethhdr
*)ptr
)->h_source
,
3081 memcpy((u8
*)subframe_bulkdata
.d
[0].os_data_ptr
+ dot11_hdr_size
,
3082 ptr
+ sizeof(struct ethhdr
),
3083 subframe_body_length
);
3084 unifi_trace(priv
, UDBG6
, "%s: calling unifi_rx. length = %d subframe_length = %d\n", __FUNCTION__
, length
, subframe_length
);
3085 unifi_rx(priv
, signal
, &subframe_bulkdata
);
3087 subframe_length
= (subframe_length
+ 3)&(~0x3);
3088 ptr
+= subframe_length
;
3089 offset
+= subframe_length
;
3091 unifi_net_data_free(priv
, &bulkdata
->d
[0]);
3095 #define SN_TO_INDEX(__ba_session, __sn) (((__sn - __ba_session->start_sn) & 0xFFF) % __ba_session->wind_size)
3098 #define ADVANCE_EXPECTED_SN(__ba_session) \
3100 __ba_session->expected_sn++; \
3101 __ba_session->expected_sn &= 0xFFF; \
3104 #define FREE_BUFFER_SLOT(__ba_session, __index) \
3106 __ba_session->occupied_slots--; \
3107 __ba_session->buffer[__index].active = FALSE; \
3108 ADVANCE_EXPECTED_SN(__ba_session); \
3111 static void add_frame_to_ba_complete(unifi_priv_t
*priv
,
3112 netInterface_priv_t
*interfacePriv
,
3113 frame_desc_struct
*frame_desc
)
3115 interfacePriv
->ba_complete
[interfacePriv
->ba_complete_index
] = *frame_desc
;
3116 interfacePriv
->ba_complete_index
++;
3120 static void update_expected_sn(unifi_priv_t
*priv
,
3121 netInterface_priv_t
*interfacePriv
,
3122 ba_session_rx_struct
*ba_session
,
3128 gap
= (sn
- ba_session
->expected_sn
) & 0xFFF;
3129 unifi_trace(priv
, UDBG6
, "%s: proccess the frames up to new_expected_sn = %d gap = %d\n", __FUNCTION__
, sn
, gap
);
3130 for(j
= 0; j
< gap
&& j
< ba_session
->wind_size
; j
++) {
3131 i
= SN_TO_INDEX(ba_session
, ba_session
->expected_sn
);
3132 unifi_trace(priv
, UDBG6
, "%s: proccess the slot index = %d\n", __FUNCTION__
, i
);
3133 if(ba_session
->buffer
[i
].active
) {
3134 add_frame_to_ba_complete(priv
, interfacePriv
, &ba_session
->buffer
[i
]);
3135 unifi_trace(priv
, UDBG6
, "%s: proccess the frame at index = %d expected_sn = %d\n", __FUNCTION__
, i
, ba_session
->expected_sn
);
3136 FREE_BUFFER_SLOT(ba_session
, i
);
3138 unifi_trace(priv
, UDBG6
, "%s: empty slot at index = %d\n", __FUNCTION__
, i
);
3139 ADVANCE_EXPECTED_SN(ba_session
);
3142 ba_session
->expected_sn
= sn
;
3146 static void complete_ready_sequence(unifi_priv_t
*priv
,
3147 netInterface_priv_t
*interfacePriv
,
3148 ba_session_rx_struct
*ba_session
)
3152 i
= SN_TO_INDEX(ba_session
, ba_session
->expected_sn
);
3153 while (ba_session
->buffer
[i
].active
) {
3154 add_frame_to_ba_complete(priv
, interfacePriv
, &ba_session
->buffer
[i
]);
3155 unifi_trace(priv
, UDBG6
, "%s: completed stored frame(expected_sn=%d) at i = %d\n", __FUNCTION__
, ba_session
->expected_sn
, i
);
3156 FREE_BUFFER_SLOT(ba_session
, i
);
3157 i
= SN_TO_INDEX(ba_session
, ba_session
->expected_sn
);
3162 void scroll_ba_window(unifi_priv_t
*priv
,
3163 netInterface_priv_t
*interfacePriv
,
3164 ba_session_rx_struct
*ba_session
,
3167 if(((sn
- ba_session
->expected_sn
) & 0xFFF) <= 2048) {
3168 update_expected_sn(priv
, interfacePriv
, ba_session
, sn
);
3169 complete_ready_sequence(priv
, interfacePriv
, ba_session
);
3174 static int consume_frame_or_get_buffer_index(unifi_priv_t
*priv
,
3175 netInterface_priv_t
*interfacePriv
,
3176 ba_session_rx_struct
*ba_session
,
3178 frame_desc_struct
*frame_desc
) {
3182 if(((sn
- ba_session
->expected_sn
) & 0xFFF) <= 2048) {
3184 /* once we are in BA window, set the flag for BA trigger */
3185 if(!ba_session
->trigger_ba_after_ssn
){
3186 ba_session
->trigger_ba_after_ssn
= TRUE
;
3189 sn_temp
= ba_session
->expected_sn
+ ba_session
->wind_size
;
3190 unifi_trace(priv
, UDBG6
, "%s: new frame: sn=%d\n", __FUNCTION__
, sn
);
3191 if(!(((sn
- sn_temp
) & 0xFFF) > 2048)) {
3192 u16 new_expected_sn
;
3193 unifi_trace(priv
, UDBG6
, "%s: frame is out of window\n", __FUNCTION__
);
3194 sn_temp
= (sn
- ba_session
->wind_size
) & 0xFFF;
3195 new_expected_sn
= (sn_temp
+ 1) & 0xFFF;
3196 update_expected_sn(priv
, interfacePriv
, ba_session
, new_expected_sn
);
3199 if (sn
== ba_session
->expected_sn
) {
3200 unifi_trace(priv
, UDBG6
, "%s: sn = ba_session->expected_sn = %d\n", __FUNCTION__
, sn
);
3201 ADVANCE_EXPECTED_SN(ba_session
);
3202 add_frame_to_ba_complete(priv
, interfacePriv
, frame_desc
);
3204 i
= SN_TO_INDEX(ba_session
, sn
);
3205 unifi_trace(priv
, UDBG6
, "%s: sn(%d) != ba_session->expected_sn(%d), i = %d\n", __FUNCTION__
, sn
, ba_session
->expected_sn
, i
);
3206 if (ba_session
->buffer
[i
].active
) {
3207 unifi_trace(priv
, UDBG6
, "%s: free frame at i = %d\n", __FUNCTION__
, i
);
3209 unifi_net_data_free(priv
, &frame_desc
->bulkdata
.d
[0]);
3214 if(!ba_session
->trigger_ba_after_ssn
){
3215 unifi_trace(priv
, UDBG6
, "%s: frame before ssn, pass it up: sn=%d\n", __FUNCTION__
, sn
);
3216 add_frame_to_ba_complete(priv
, interfacePriv
, frame_desc
);
3218 unifi_trace(priv
, UDBG6
, "%s: old frame, drop: sn=%d, expected_sn=%d\n", __FUNCTION__
, sn
, ba_session
->expected_sn
);
3219 unifi_net_data_free(priv
, &frame_desc
->bulkdata
.d
[0]);
3227 static void process_ba_frame(unifi_priv_t
*priv
,
3228 netInterface_priv_t
*interfacePriv
,
3229 ba_session_rx_struct
*ba_session
,
3230 frame_desc_struct
*frame_desc
)
3233 u16 sn
= frame_desc
->sn
;
3235 if (ba_session
->timeout
) {
3236 mod_timer(&ba_session
->timer
, (jiffies
+ usecs_to_jiffies((ba_session
->timeout
) * 1024)));
3238 unifi_trace(priv
, UDBG6
, "%s: got frame(sn=%d)\n", __FUNCTION__
, sn
);
3240 i
= consume_frame_or_get_buffer_index(priv
, interfacePriv
, ba_session
, sn
, frame_desc
);
3242 unifi_trace(priv
, UDBG6
, "%s: store frame(sn=%d) at i = %d\n", __FUNCTION__
, sn
, i
);
3243 ba_session
->buffer
[i
] = *frame_desc
;
3244 ba_session
->buffer
[i
].recv_time
= CsrTimeGet(NULL
);
3245 ba_session
->occupied_slots
++;
3247 unifi_trace(priv
, UDBG6
, "%s: frame consumed - sn = %d\n", __FUNCTION__
, sn
);
3249 complete_ready_sequence(priv
, interfacePriv
, ba_session
);
3253 static void process_ba_complete(unifi_priv_t
*priv
, netInterface_priv_t
*interfacePriv
)
3255 frame_desc_struct
*frame_desc
;
3258 for(i
= 0; i
< interfacePriv
->ba_complete_index
; i
++) {
3259 frame_desc
= &interfacePriv
->ba_complete
[i
];
3260 unifi_trace(priv
, UDBG6
, "%s: calling process_amsdu()\n", __FUNCTION__
);
3261 process_amsdu(priv
, &frame_desc
->signal
, &frame_desc
->bulkdata
);
3263 interfacePriv
->ba_complete_index
= 0;
3268 /* Check if the frames in BA reoder buffer has aged and
3269 * if so release the frames to upper processes and move
3272 static void check_ba_frame_age_timeout( unifi_priv_t
*priv
,
3273 netInterface_priv_t
*interfacePriv
,
3274 ba_session_rx_struct
*ba_session
)
3281 /* gap is started at 1 because we have buffered frames and
3282 * hence a minimum gap of 1 exists
3286 now
= CsrTimeGet(NULL
);
3288 if (ba_session
->occupied_slots
)
3290 /* expected sequence has not arrived so start searching from next
3291 * sequence number until a frame is available and determine the gap.
3292 * Check if the frame available has timedout, if so advance the
3293 * expected sequence number and release the frames
3295 sn_temp
= (ba_session
->expected_sn
+ 1) & 0xFFF;
3297 for(j
= 0; j
< ba_session
->wind_size
; j
++)
3299 i
= SN_TO_INDEX(ba_session
, sn_temp
);
3301 if(ba_session
->buffer
[i
].active
)
3303 unifi_trace(priv
, UDBG6
, "check age at slot index = %d sn = %d recv_time = %u now = %u\n",
3305 ba_session
->buffer
[i
].sn
,
3306 ba_session
->buffer
[i
].recv_time
,
3309 if (ba_session
->buffer
[i
].recv_time
> now
)
3312 age
= CsrTimeAdd((CsrTime
)CsrTimeSub(CSR_SCHED_TIME_MAX
, ba_session
->buffer
[i
].recv_time
), now
);
3316 age
= (CsrTime
)CsrTimeSub(now
, ba_session
->buffer
[i
].recv_time
);
3319 if (age
>= CSR_WIFI_BA_MPDU_FRAME_AGE_TIMEOUT
)
3321 unifi_trace(priv
, UDBG2
, "release the frame at index = %d gap = %d expected_sn = %d sn = %d\n",
3324 ba_session
->expected_sn
,
3325 ba_session
->buffer
[i
].sn
);
3327 /* if it has timedout don't wait for missing frames, move the window */
3330 ADVANCE_EXPECTED_SN(ba_session
);
3332 add_frame_to_ba_complete(priv
, interfacePriv
, &ba_session
->buffer
[i
]);
3333 FREE_BUFFER_SLOT(ba_session
, i
);
3334 complete_ready_sequence(priv
, interfacePriv
, ba_session
);
3341 /* advance temp sequence number and frame gap */
3342 sn_temp
= (sn_temp
+ 1) & 0xFFF;
3350 static void process_ma_packet_error_ind(unifi_priv_t
*priv
, CSR_SIGNAL
*signal
, bulk_data_param_t
*bulkdata
)
3353 const CSR_MA_PACKET_ERROR_INDICATION
*pkt_err_ind
= &signal
->u
.MaPacketErrorIndication
;
3354 netInterface_priv_t
*interfacePriv
;
3355 ba_session_rx_struct
*ba_session
;
3356 u8 ba_session_idx
= 0;
3357 CSR_PRIORITY UserPriority
;
3358 CSR_SEQUENCE_NUMBER sn
;
3362 interfaceTag
= (pkt_err_ind
->VirtualInterfaceIdentifier
& 0xff);
3365 /* Sanity check that the VIF refers to a sensible interface */
3366 if (interfaceTag
>= CSR_WIFI_NUM_INTERFACES
)
3368 unifi_error(priv
, "%s: MaPacketErrorIndication indication with bad interfaceTag %d\n", __FUNCTION__
, interfaceTag
);
3373 interfacePriv
= priv
->interfacePriv
[interfaceTag
];
3374 UserPriority
= pkt_err_ind
->UserPriority
;
3375 if(UserPriority
> 15) {
3376 unifi_error(priv
, "%s: MaPacketErrorIndication indication with bad UserPriority=%d\n", __FUNCTION__
, UserPriority
);
3379 sn
= pkt_err_ind
->SequenceNumber
;
3381 down(&priv
->ba_mutex
);
3382 /* To find the right ba_session loop through the BA sessions, compare MAC address and tID */
3383 for (ba_session_idx
=0; ba_session_idx
< MAX_SUPPORTED_BA_SESSIONS_RX
; ba_session_idx
++){
3384 ba_session
= interfacePriv
->ba_session_rx
[ba_session_idx
];
3386 if ((!memcmp(ba_session
->macAddress
.a
, pkt_err_ind
->PeerQstaAddress
.x
, ETH_ALEN
)) && (ba_session
->tID
== UserPriority
)){
3387 if (ba_session
->timeout
) {
3388 mod_timer(&ba_session
->timer
, (jiffies
+ usecs_to_jiffies((ba_session
->timeout
) * 1024)));
3390 scroll_ba_window(priv
, interfacePriv
, ba_session
, sn
);
3396 up(&priv
->ba_mutex
);
3397 process_ba_complete(priv
, interfacePriv
);