net: pass info struct via netdevice notifier
[linux-2.6/btrfs-unstable.git] / drivers / staging / csr / netdev.c
blobd49cdf84a496d405568024bd39c2f21577cab68f
1 /*
2 * ---------------------------------------------------------------------------
3 * FILE: netdev.c
5 * PURPOSE:
6 * This file provides the upper edge interface to the linux netdevice
7 * and wireless extensions.
8 * It is part of the porting exercise.
10 * Copyright (C) 2005-2010 by Cambridge Silicon Radio Ltd.
12 * Refer to LICENSE.txt included with this source code for details on
13 * the license terms.
15 * ---------------------------------------------------------------------------
19 * Porting Notes:
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/vmalloc.h>
51 #include "csr_wifi_hip_unifi.h"
52 #include "csr_wifi_hip_conversions.h"
53 #include "unifi_priv.h"
54 #include <net/pkt_sched.h>
57 /* Wext handler is supported only if CSR_SUPPORT_WEXT is defined */
58 #ifdef CSR_SUPPORT_WEXT
59 extern struct iw_handler_def unifi_iw_handler_def;
60 #endif /* CSR_SUPPORT_WEXT */
61 static void check_ba_frame_age_timeout( unifi_priv_t *priv,
62 netInterface_priv_t *interfacePriv,
63 ba_session_rx_struct *ba_session);
64 static void process_ba_frame(unifi_priv_t *priv,
65 netInterface_priv_t *interfacePriv,
66 ba_session_rx_struct *ba_session,
67 frame_desc_struct *frame_desc);
68 static void process_ba_complete(unifi_priv_t *priv, netInterface_priv_t *interfacePriv);
69 static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata);
70 static void process_amsdu(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata);
71 static int uf_net_open(struct net_device *dev);
72 static int uf_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
73 static int uf_net_stop(struct net_device *dev);
74 static struct net_device_stats *uf_net_get_stats(struct net_device *dev);
75 static u16 uf_net_select_queue(struct net_device *dev, struct sk_buff *skb);
76 static netdev_tx_t uf_net_xmit(struct sk_buff *skb, struct net_device *dev);
77 static void uf_set_multicast_list(struct net_device *dev);
80 typedef int (*tx_signal_handler)(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr *ehdr, CSR_PRIORITY priority);
82 #ifdef CONFIG_NET_SCHED
84 * Queueing Discipline Interface
85 * Only used if kernel is configured with CONFIG_NET_SCHED
89 * The driver uses the qdisc interface to buffer and control all
90 * outgoing traffic. We create a root qdisc, register our qdisc operations
91 * and later we create two subsidiary pfifo queues for the uncontrolled
92 * and controlled ports.
94 * The network stack delivers all outgoing packets in our enqueue handler.
95 * There, we classify the packet and decide whether to store it or drop it
96 * (if the controlled port state is set to "discard").
97 * If the packet is enqueued, the network stack call our dequeue handler.
98 * There, we decide whether we can send the packet, delay it or drop it
99 * (the controlled port configuration might have changed meanwhile).
100 * If a packet is dequeued, then the network stack calls our hard_start_xmit
101 * handler where finally we send the packet.
103 * If the hard_start_xmit handler fails to send the packet, we return
104 * NETDEV_TX_BUSY and the network stack call our requeue handler where
105 * we put the packet back in the same queue in came from.
109 struct uf_sched_data
111 /* Traffic Classifier TBD */
112 struct tcf_proto *filter_list;
113 /* Our two queues */
114 struct Qdisc *queues[UNIFI_TRAFFIC_Q_MAX];
117 struct uf_tx_packet_data {
118 /* Queue the packet is stored in */
119 unifi_TrafficQueue queue;
120 /* QoS Priority determined when enqueing packet */
121 CSR_PRIORITY priority;
122 /* Debug */
123 unsigned long host_tag;
126 #endif /* CONFIG_NET_SCHED */
128 static const struct net_device_ops uf_netdev_ops =
130 .ndo_open = uf_net_open,
131 .ndo_stop = uf_net_stop,
132 .ndo_start_xmit = uf_net_xmit,
133 .ndo_do_ioctl = uf_net_ioctl,
134 .ndo_get_stats = uf_net_get_stats, /* called by /proc/net/dev */
135 .ndo_set_rx_mode = uf_set_multicast_list,
136 .ndo_select_queue = uf_net_select_queue,
139 static u8 oui_rfc1042[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
140 static u8 oui_8021h[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
143 /* Callback for event logging to blocking clients */
144 static void netdev_mlme_event_handler(ul_client_t *client,
145 const u8 *sig_packed, int sig_len,
146 const bulk_data_param_t *bulkdata,
147 int dir);
149 #ifdef CSR_SUPPORT_WEXT
150 /* Declare netdev_notifier block which will contain the state change
151 * handler callback function
153 static struct notifier_block uf_netdev_notifier;
154 #endif
157 * ---------------------------------------------------------------------------
158 * uf_alloc_netdevice
160 * Allocate memory for the net_device and device private structs
161 * for this interface.
162 * Fill in the fields, but don't register the interface yet.
163 * We need to configure the UniFi first.
165 * Arguments:
166 * sdio_dev Pointer to SDIO context handle to use for all
167 * SDIO ops.
168 * bus_id A small number indicating the SDIO card position on the
169 * bus. Typically this is the slot number, e.g. 0, 1 etc.
170 * Valid values are 0 to MAX_UNIFI_DEVS-1.
172 * Returns:
173 * Pointer to device private struct.
175 * Notes:
176 * The net_device and device private structs are allocated together
177 * and should be freed by freeing the net_device pointer.
178 * ---------------------------------------------------------------------------
180 unifi_priv_t *
181 uf_alloc_netdevice(CsrSdioFunction *sdio_dev, int bus_id)
183 struct net_device *dev;
184 unifi_priv_t *priv;
185 netInterface_priv_t *interfacePriv;
186 #ifdef CSR_SUPPORT_WEXT
187 int rc;
188 #endif
189 unsigned char i; /* loop index */
192 * Allocate netdevice struct, assign name template and
193 * setup as an ethernet device.
194 * The net_device and private structs are zeroed. Ether_setup() then
195 * sets up ethernet handlers and values.
196 * The RedHat 9 redhat-config-network tool doesn't recognise wlan* devices,
197 * so use "eth*" (like other wireless extns drivers).
199 dev = alloc_etherdev_mq(sizeof(unifi_priv_t) + sizeof(netInterface_priv_t), UNIFI_TRAFFIC_Q_MAX);
201 if (dev == NULL) {
202 return NULL;
205 /* Set up back pointer from priv to netdev */
206 interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
207 priv = (unifi_priv_t *)(interfacePriv + 1);
208 interfacePriv->privPtr = priv;
209 interfacePriv->InterfaceTag = 0;
212 /* Initialize all supported netdev interface to be NULL */
213 for(i=0; i<CSR_WIFI_NUM_INTERFACES; i++) {
214 priv->netdev[i] = NULL;
215 priv->interfacePriv[i] = NULL;
217 priv->netdev[0] = dev;
218 priv->interfacePriv[0] = interfacePriv;
220 /* Setup / override net_device fields */
221 dev->netdev_ops = &uf_netdev_ops;
223 #ifdef CSR_SUPPORT_WEXT
224 dev->wireless_handlers = &unifi_iw_handler_def;
225 #if IW_HANDLER_VERSION < 6
226 dev->get_wireless_stats = unifi_get_wireless_stats;
227 #endif /* IW_HANDLER_VERSION */
228 #endif /* CSR_SUPPORT_WEXT */
230 /* This gives us enough headroom to add the 802.11 header */
231 dev->needed_headroom = 32;
233 /* Use bus_id as instance number */
234 priv->instance = bus_id;
235 /* Store SDIO pointer to pass in the core */
236 priv->sdio = sdio_dev;
238 sdio_dev->driverData = (void*)priv;
239 /* Consider UniFi to be uninitialised */
240 priv->init_progress = UNIFI_INIT_NONE;
242 priv->prev_queue = 0;
245 * Initialise the clients structure array.
246 * We do not need protection around ul_init_clients() because
247 * the character device can not be used until uf_alloc_netdevice()
248 * returns and Unifi_instances[bus_id]=priv is set, since unifi_open()
249 * will return -ENODEV.
251 ul_init_clients(priv);
254 * Register a new ul client to send the multicast list signals.
255 * Note: priv->instance must be set before calling this.
257 priv->netdev_client = ul_register_client(priv,
259 netdev_mlme_event_handler);
260 if (priv->netdev_client == NULL) {
261 unifi_error(priv,
262 "Failed to register a unifi client for background netdev processing\n");
263 free_netdev(priv->netdev[0]);
264 return NULL;
266 unifi_trace(priv, UDBG2, "Netdev %p client (id:%d s:0x%X) is registered\n",
267 dev, priv->netdev_client->client_id, priv->netdev_client->sender_id);
269 priv->sta_wmm_capabilities = 0;
271 #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_SUPPORT_SME))
272 priv->wapi_multicast_filter = 0;
273 priv->wapi_unicast_filter = 0;
274 priv->wapi_unicast_queued_pkt_filter = 0;
275 #ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
276 priv->isWapiConnection = FALSE;
277 #endif
278 #endif
280 /* Enable all queues by default */
281 interfacePriv->queueEnabled[0] = 1;
282 interfacePriv->queueEnabled[1] = 1;
283 interfacePriv->queueEnabled[2] = 1;
284 interfacePriv->queueEnabled[3] = 1;
286 #ifdef CSR_SUPPORT_SME
287 priv->allPeerDozing = 0;
288 #endif
290 * Initialise the OS private struct.
293 * Instead of deciding in advance to use 11bg or 11a, we could do a more
294 * clever scan on both radios.
296 if (use_5g) {
297 priv->if_index = CSR_INDEX_5G;
298 unifi_info(priv, "Using the 802.11a radio\n");
299 } else {
300 priv->if_index = CSR_INDEX_2G4;
303 /* Initialise bh thread structure */
304 priv->bh_thread.thread_task = NULL;
305 priv->bh_thread.block_thread = 1;
306 init_waitqueue_head(&priv->bh_thread.wakeup_q);
307 priv->bh_thread.wakeup_flag = 0;
308 sprintf(priv->bh_thread.name, "uf_bh_thread");
310 /* reset the connected state for the interface */
311 interfacePriv->connected = UnifiConnectedUnknown; /* -1 unknown, 0 no, 1 yes */
313 #ifdef USE_DRIVER_LOCK
314 sema_init(&priv->lock, 1);
315 #endif /* USE_DRIVER_LOCK */
317 spin_lock_init(&priv->send_signal_lock);
319 spin_lock_init(&priv->m4_lock);
320 sema_init(&priv->ba_mutex, 1);
322 #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
323 spin_lock_init(&priv->wapi_lock);
324 #endif
326 #ifdef CSR_SUPPORT_SME
327 spin_lock_init(&priv->staRecord_lock);
328 spin_lock_init(&priv->tx_q_lock);
329 #endif
331 /* Create the Traffic Analysis workqueue */
332 priv->unifi_workqueue = create_singlethread_workqueue("unifi_workq");
333 if (priv->unifi_workqueue == NULL) {
334 /* Deregister priv->netdev_client */
335 ul_deregister_client(priv->netdev_client);
336 free_netdev(priv->netdev[0]);
337 return NULL;
340 #ifdef CSR_SUPPORT_SME
341 /* Create the Multicast Addresses list work structure */
342 INIT_WORK(&priv->multicast_list_task, uf_multicast_list_wq);
344 /* Create m4 buffering work structure */
345 INIT_WORK(&interfacePriv->send_m4_ready_task, uf_send_m4_ready_wq);
347 #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
348 /* Create work structure to buffer the WAPI data packets to be sent to SME for encryption */
349 INIT_WORK(&interfacePriv->send_pkt_to_encrypt, uf_send_pkt_to_encrypt);
350 #endif
351 #endif
353 priv->ref_count = 1;
355 priv->amp_client = NULL;
356 priv->coredump_mode = 0;
357 priv->ptest_mode = 0;
358 priv->wol_suspend = FALSE;
359 INIT_LIST_HEAD(&interfacePriv->rx_uncontrolled_list);
360 INIT_LIST_HEAD(&interfacePriv->rx_controlled_list);
361 sema_init(&priv->rx_q_sem, 1);
363 #ifdef CSR_SUPPORT_WEXT
364 interfacePriv->netdev_callback_registered = FALSE;
365 interfacePriv->wait_netdev_change = FALSE;
366 /* Register callback for netdevice state changes */
367 if ((rc = register_netdevice_notifier(&uf_netdev_notifier)) == 0) {
368 interfacePriv->netdev_callback_registered = TRUE;
370 else {
371 unifi_warning(priv, "Failed to register netdevice notifier : %d %p\n", rc, dev);
373 #endif /* CSR_SUPPORT_WEXT */
375 #ifdef CSR_WIFI_SPLIT_PATCH
376 /* set it to some invalid value */
377 priv->pending_mode_set.common.destination = 0xaaaa;
378 #endif
380 return priv;
381 } /* uf_alloc_netdevice() */
384 *---------------------------------------------------------------------------
385 * uf_alloc_netdevice_for_other_interfaces
387 * Allocate memory for the net_device and device private structs
388 * for this interface.
389 * Fill in the fields, but don't register the interface yet.
390 * We need to configure the UniFi first.
392 * Arguments:
393 * interfaceTag Interface number.
394 * sdio_dev Pointer to SDIO context handle to use for all
395 * SDIO ops.
396 * bus_id A small number indicating the SDIO card position on the
397 * bus. Typically this is the slot number, e.g. 0, 1 etc.
398 * Valid values are 0 to MAX_UNIFI_DEVS-1.
400 * Returns:
401 * Pointer to device private struct.
403 * Notes:
404 * The device private structure contains the interfaceTag and pointer to the unifi_priv
405 * structure created allocated by net_device od interface0.
406 * The net_device and device private structs are allocated together
407 * and should be freed by freeing the net_device pointer.
408 * ---------------------------------------------------------------------------
411 uf_alloc_netdevice_for_other_interfaces(unifi_priv_t *priv, u16 interfaceTag)
413 struct net_device *dev;
414 netInterface_priv_t *interfacePriv;
417 * Allocate netdevice struct, assign name template and
418 * setup as an ethernet device.
419 * The net_device and private structs are zeroed. Ether_setup() then
420 * sets up ethernet handlers and values.
421 * The RedHat 9 redhat-config-network tool doesn't recognise wlan* devices,
422 * so use "eth*" (like other wireless extns drivers).
424 dev = alloc_etherdev_mq(sizeof(netInterface_priv_t), 1);
425 if (dev == NULL) {
426 return FALSE;
429 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
430 unifi_error(priv, "uf_alloc_netdevice_for_other_interfaces bad interfaceTag\n");
431 return FALSE;
434 /* Set up back pointer from priv to netdev */
435 interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
436 interfacePriv->privPtr = priv;
437 interfacePriv->InterfaceTag = interfaceTag;
438 priv->netdev[interfaceTag] = dev;
439 priv->interfacePriv[interfacePriv->InterfaceTag] = interfacePriv;
441 /* reset the connected state for the interface */
442 interfacePriv->connected = UnifiConnectedUnknown; /* -1 unknown, 0 no, 1 yes */
443 INIT_LIST_HEAD(&interfacePriv->rx_uncontrolled_list);
444 INIT_LIST_HEAD(&interfacePriv->rx_controlled_list);
446 /* Setup / override net_device fields */
447 dev->netdev_ops = &uf_netdev_ops;
449 #ifdef CSR_SUPPORT_WEXT
450 dev->wireless_handlers = &unifi_iw_handler_def;
451 #if IW_HANDLER_VERSION < 6
452 dev->get_wireless_stats = unifi_get_wireless_stats;
453 #endif /* IW_HANDLER_VERSION */
454 #endif /* CSR_SUPPORT_WEXT */
455 return TRUE;
456 } /* uf_alloc_netdevice() */
461 * ---------------------------------------------------------------------------
462 * uf_free_netdevice
464 * Unregister the network device and free the memory allocated for it.
465 * NB This includes the memory for the priv struct.
467 * Arguments:
468 * priv Device private pointer.
470 * Returns:
471 * None.
472 * ---------------------------------------------------------------------------
475 uf_free_netdevice(unifi_priv_t *priv)
477 int i;
478 unsigned long flags;
480 unifi_trace(priv, UDBG1, "uf_free_netdevice\n");
482 if (!priv) {
483 return -EINVAL;
487 * Free any buffers used for holding firmware
489 uf_release_firmware_files(priv);
491 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
492 if (priv->connection_config.mlmeAssociateReqInformationElements) {
493 kfree(priv->connection_config.mlmeAssociateReqInformationElements);
495 priv->connection_config.mlmeAssociateReqInformationElements = NULL;
496 priv->connection_config.mlmeAssociateReqInformationElementsLength = 0;
498 if (priv->mib_data.length) {
499 vfree(priv->mib_data.data);
501 priv->mib_data.data = NULL;
502 priv->mib_data.length = 0;
504 #endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT*/
506 /* Free any bulkdata buffers allocated for M4 caching */
507 spin_lock_irqsave(&priv->m4_lock, flags);
508 for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
509 netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
510 if (interfacePriv->m4_bulk_data.data_length > 0) {
511 unifi_trace(priv, UDBG5, "uf_free_netdevice: free M4 bulkdata %d\n", i);
512 unifi_net_data_free(priv, &interfacePriv->m4_bulk_data);
515 spin_unlock_irqrestore(&priv->m4_lock, flags);
517 #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
518 /* Free any bulkdata buffers allocated for M4 caching */
519 spin_lock_irqsave(&priv->wapi_lock, flags);
520 for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
521 netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
522 if (interfacePriv->wapi_unicast_bulk_data.data_length > 0) {
523 unifi_trace(priv, UDBG5, "uf_free_netdevice: free WAPI PKT bulk data %d\n", i);
524 unifi_net_data_free(priv, &interfacePriv->wapi_unicast_bulk_data);
527 spin_unlock_irqrestore(&priv->wapi_lock, flags);
528 #endif
530 #ifdef CSR_SUPPORT_WEXT
531 /* Unregister callback for netdevice state changes */
532 unregister_netdevice_notifier(&uf_netdev_notifier);
533 #endif /* CSR_SUPPORT_WEXT */
535 #ifdef CSR_SUPPORT_SME
536 /* Cancel work items and destroy the workqueue */
537 cancel_work_sync(&priv->multicast_list_task);
538 #endif
539 /* Destroy the workqueues. */
540 flush_workqueue(priv->unifi_workqueue);
541 destroy_workqueue(priv->unifi_workqueue);
543 /* Free up netdev in reverse order: priv is allocated with netdev[0].
544 * So, netdev[0] should be freed after all other netdevs are freed up
546 for (i=CSR_WIFI_NUM_INTERFACES-1; i>=0; i--) {
547 /*Free the netdev struct and priv, which are all one lump*/
548 if (priv->netdev[i]) {
549 unifi_error(priv, "uf_free_netdevice: netdev %d %p\n", i, priv->netdev[i]);
550 free_netdev(priv->netdev[i]);
554 return 0;
555 } /* uf_free_netdevice() */
559 * ---------------------------------------------------------------------------
560 * uf_net_open
562 * Called when userland does "ifconfig wlan0 up".
564 * Arguments:
565 * dev Device pointer.
567 * Returns:
568 * None.
569 * ---------------------------------------------------------------------------
571 static int
572 uf_net_open(struct net_device *dev)
574 netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
575 unifi_priv_t *priv = interfacePriv->privPtr;
577 /* If we haven't finished UniFi initialisation, we can't start */
578 if (priv->init_progress != UNIFI_INIT_COMPLETED) {
579 unifi_warning(priv, "%s: unifi not ready, failing net_open\n", __FUNCTION__);
580 return -EINVAL;
583 #if (defined CSR_NATIVE_LINUX) && (defined UNIFI_SNIFF_ARPHRD) && defined(CSR_SUPPORT_WEXT)
585 * To sniff, the user must do "iwconfig mode monitor", which sets
586 * priv->wext_conf.mode to IW_MODE_MONITOR.
587 * Then he/she must do "ifconfig ethn up", which calls this fn.
588 * There is no point in starting the sniff with SNIFFJOIN until
589 * this point.
591 if (priv->wext_conf.mode == IW_MODE_MONITOR) {
592 int err;
593 err = uf_start_sniff(priv);
594 if (err) {
595 return err;
597 netif_carrier_on(dev);
599 #endif
601 #ifdef CSR_SUPPORT_WEXT
602 if (interfacePriv->wait_netdev_change) {
603 unifi_trace(priv, UDBG1, "%s: Waiting for NETDEV_CHANGE, assume connected\n",
604 __FUNCTION__);
605 interfacePriv->connected = UnifiConnected;
606 interfacePriv->wait_netdev_change = FALSE;
608 #endif
610 netif_tx_start_all_queues(dev);
612 return 0;
613 } /* uf_net_open() */
616 static int
617 uf_net_stop(struct net_device *dev)
619 #if defined(CSR_NATIVE_LINUX) && defined(UNIFI_SNIFF_ARPHRD) && defined(CSR_SUPPORT_WEXT)
620 netInterface_priv_t *interfacePriv = (netInterface_priv_t*)netdev_priv(dev);
621 unifi_priv_t *priv = interfacePriv->privPtr;
623 /* Stop sniffing if in Monitor mode */
624 if (priv->wext_conf.mode == IW_MODE_MONITOR) {
625 if (priv->card) {
626 int err;
627 err = unifi_reset_state(priv, dev->dev_addr, 1);
628 if (err) {
629 return err;
633 #endif
635 netif_tx_stop_all_queues(dev);
637 return 0;
638 } /* uf_net_stop() */
641 /* This is called after the WE handlers */
642 static int
643 uf_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
645 int rc;
647 rc = -EOPNOTSUPP;
649 return rc;
650 } /* uf_net_ioctl() */
654 static struct net_device_stats *
655 uf_net_get_stats(struct net_device *dev)
657 netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
659 return &interfacePriv->stats;
660 } /* uf_net_get_stats() */
662 static CSR_PRIORITY uf_get_packet_priority(unifi_priv_t *priv, netInterface_priv_t *interfacePriv, struct sk_buff *skb, const int proto)
664 CSR_PRIORITY priority = CSR_CONTENTION;
666 priority = (CSR_PRIORITY) (skb->priority >> 5);
668 if (priority == CSR_QOS_UP0) { /* 0 */
670 unifi_trace(priv, UDBG5, "uf_get_packet_priority: proto = 0x%.4X\n", proto);
672 switch (proto) {
673 case 0x0800: /* IPv4 */
674 case 0x814C: /* SNMP */
675 case 0x880C: /* GSMP */
676 priority = (CSR_PRIORITY) (skb->data[1 + ETH_HLEN] >> 5);
677 break;
679 case 0x8100: /* VLAN */
680 priority = (CSR_PRIORITY) (skb->data[0 + ETH_HLEN] >> 5);
681 break;
683 case 0x86DD: /* IPv6 */
684 priority = (CSR_PRIORITY) ((skb->data[0 + ETH_HLEN] & 0x0E) >> 1);
685 break;
687 default:
688 priority = CSR_QOS_UP0;
689 break;
693 /* Check if we are allowed to transmit on this AC. Because of ACM we may have to downgrade to a lower
694 * priority */
695 if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA ||
696 interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI) {
697 unifi_TrafficQueue queue;
699 /* Keep trying lower priorities until we find a queue
700 * Priority to queue mapping is 1,2 - BK, 0,3 - BE, 4,5 - VI, 6,7 - VO */
701 queue = unifi_frame_priority_to_queue(priority);
703 while (queue > UNIFI_TRAFFIC_Q_BK && !interfacePriv->queueEnabled[queue]) {
704 queue--;
705 priority = unifi_get_default_downgrade_priority(queue);
709 unifi_trace(priv, UDBG5, "Packet priority = %d\n", priority);
711 return priority;
717 * ---------------------------------------------------------------------------
718 * get_packet_priority
720 * Arguments:
721 * priv private data area of functional driver
722 * skb socket buffer
723 * ehdr ethernet header to fetch protocol
724 * interfacePriv For accessing station record database
727 * Returns:
728 * CSR_PRIORITY.
729 * ---------------------------------------------------------------------------
731 CSR_PRIORITY
732 get_packet_priority(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr *ehdr, netInterface_priv_t *interfacePriv)
734 CSR_PRIORITY priority = CSR_CONTENTION;
735 const int proto = ntohs(ehdr->h_proto);
737 u8 interfaceMode = interfacePriv->interfaceMode;
739 /* Priority Mapping for all the Modes */
740 switch(interfaceMode)
742 case CSR_WIFI_ROUTER_CTRL_MODE_STA:
743 case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
744 unifi_trace(priv, UDBG4, "mode is STA \n");
745 if ((priv->sta_wmm_capabilities & QOS_CAPABILITY_WMM_ENABLED) == 1) {
746 priority = uf_get_packet_priority(priv, interfacePriv, skb, proto);
747 } else {
748 priority = CSR_CONTENTION;
750 break;
751 #ifdef CSR_SUPPORT_SME
752 case CSR_WIFI_ROUTER_CTRL_MODE_AP:
753 case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
754 case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
756 CsrWifiRouterCtrlStaInfo_t * dstStaInfo =
757 CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,ehdr->h_dest, interfacePriv->InterfaceTag);
758 unifi_trace(priv, UDBG4, "mode is AP \n");
759 if (!(ehdr->h_dest[0] & 0x01) && dstStaInfo && dstStaInfo->wmmOrQosEnabled) {
760 /* If packet is not Broadcast/multicast */
761 priority = uf_get_packet_priority(priv, interfacePriv, skb, proto);
762 } else {
763 /* Since packet destination is not QSTA, set priority to CSR_CONTENTION */
764 unifi_trace(priv, UDBG4, "Destination is not QSTA or BroadCast/Multicast\n");
765 priority = CSR_CONTENTION;
768 break;
769 #endif
770 default:
771 unifi_trace(priv, UDBG3, " mode unknown in %s func, mode=%x\n", __FUNCTION__, interfaceMode);
773 unifi_trace(priv, UDBG5, "priority = %x\n", priority);
775 return priority;
779 * ---------------------------------------------------------------------------
780 * uf_net_select_queue
782 * Called by the kernel to select which queue to put the packet in
784 * Arguments:
785 * dev Device pointer
786 * skb Packet
788 * Returns:
789 * Queue index
790 * ---------------------------------------------------------------------------
792 static u16
793 uf_net_select_queue(struct net_device *dev, struct sk_buff *skb)
795 netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
796 unifi_priv_t *priv = (unifi_priv_t *)interfacePriv->privPtr;
797 struct ethhdr ehdr;
798 unifi_TrafficQueue queue;
799 int proto;
800 CSR_PRIORITY priority;
802 memcpy(&ehdr, skb->data, ETH_HLEN);
803 proto = ntohs(ehdr.h_proto);
805 /* 802.1x - apply controlled/uncontrolled port rules */
806 if ((proto != ETH_P_PAE)
807 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
808 && (proto != ETH_P_WAI)
809 #endif
811 /* queues 0 - 3 */
812 priority = get_packet_priority(priv, skb, &ehdr, interfacePriv);
813 queue = unifi_frame_priority_to_queue(priority);
814 } else {
815 /* queue 4 */
816 queue = UNIFI_TRAFFIC_Q_EAPOL;
820 return (u16)queue;
821 } /* uf_net_select_queue() */
824 skb_add_llc_snap(struct net_device *dev, struct sk_buff *skb, int proto)
826 llc_snap_hdr_t *snap;
827 netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
828 unifi_priv_t *priv = interfacePriv->privPtr;
829 int headroom;
831 /* get the headroom available in skb */
832 headroom = skb_headroom(skb);
833 /* step 1: classify ether frame, DIX or 802.3? */
835 if (proto < 0x600) {
836 /* codes <= 1500 reserved for 802.3 lengths */
837 /* it's 802.3, pass ether payload unchanged, */
838 unifi_trace(priv, UDBG3, "802.3 len: %d\n", skb->len);
840 /* leave off any PAD octets. */
841 skb_trim(skb, proto);
842 } else if (proto == ETH_P_8021Q) {
844 /* Store the VLAN SNAP (should be 87-65). */
845 u16 vlan_snap = *(u16*)skb->data;
846 /* check for headroom availability before skb_push 14 = (4 + 10) */
847 if (headroom < 14) {
848 unifi_trace(priv, UDBG3, "cant append vlan snap: debug\n");
849 return -1;
851 /* Add AA-AA-03-00-00-00 */
852 snap = (llc_snap_hdr_t *)skb_push(skb, 4);
853 snap->dsap = snap->ssap = 0xAA;
854 snap->ctrl = 0x03;
855 memcpy(snap->oui, oui_rfc1042, P80211_OUI_LEN);
857 /* Add AA-AA-03-00-00-00 */
858 snap = (llc_snap_hdr_t *)skb_push(skb, 10);
859 snap->dsap = snap->ssap = 0xAA;
860 snap->ctrl = 0x03;
861 memcpy(snap->oui, oui_rfc1042, P80211_OUI_LEN);
863 /* Add the VLAN specific information */
864 snap->protocol = htons(proto);
865 *(u16*)(snap + 1) = vlan_snap;
867 } else
869 /* it's DIXII, time for some conversion */
870 unifi_trace(priv, UDBG3, "DIXII len: %d\n", skb->len);
872 /* check for headroom availability before skb_push */
873 if (headroom < sizeof(llc_snap_hdr_t)) {
874 unifi_trace(priv, UDBG3, "cant append snap: debug\n");
875 return -1;
877 /* tack on SNAP */
878 snap = (llc_snap_hdr_t *)skb_push(skb, sizeof(llc_snap_hdr_t));
879 snap->dsap = snap->ssap = 0xAA;
880 snap->ctrl = 0x03;
881 /* Use the appropriate OUI. */
882 if ((proto == ETH_P_AARP) || (proto == ETH_P_IPX)) {
883 memcpy(snap->oui, oui_8021h, P80211_OUI_LEN);
884 } else {
885 memcpy(snap->oui, oui_rfc1042, P80211_OUI_LEN);
887 snap->protocol = htons(proto);
890 return 0;
891 } /* skb_add_llc_snap() */
893 #ifdef CSR_SUPPORT_SME
894 static int
895 _identify_sme_ma_pkt_ind(unifi_priv_t *priv,
896 const s8 *oui, u16 protocol,
897 const CSR_SIGNAL *signal,
898 bulk_data_param_t *bulkdata,
899 const unsigned char *daddr,
900 const unsigned char *saddr)
902 CSR_MA_PACKET_INDICATION *pkt_ind = (CSR_MA_PACKET_INDICATION*)&signal->u.MaPacketIndication;
903 int r;
904 u8 i;
906 unifi_trace(priv, UDBG5,
907 "_identify_sme_ma_pkt_ind -->\n");
908 for (i = 0; i < MAX_MA_UNIDATA_IND_FILTERS; i++) {
909 if (priv->sme_unidata_ind_filters[i].in_use) {
910 if (!memcmp(oui, priv->sme_unidata_ind_filters[i].oui, 3) &&
911 (protocol == priv->sme_unidata_ind_filters[i].protocol)) {
913 /* Send to client */
914 if (priv->sme_cli) {
916 * Pass the packet to the SME, using unifi_sys_ma_unitdata_ind().
917 * The frame needs to be converted according to the encapsulation.
919 unifi_trace(priv, UDBG1,
920 "_identify_sme_ma_pkt_ind: handle=%d, encap=%d, proto=%x\n",
921 i, priv->sme_unidata_ind_filters[i].encapsulation,
922 priv->sme_unidata_ind_filters[i].protocol);
923 if (priv->sme_unidata_ind_filters[i].encapsulation == CSR_WIFI_ROUTER_ENCAPSULATION_ETHERNET) {
924 struct sk_buff *skb;
925 /* The translation is performed on skb... */
926 skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
927 skb->len = bulkdata->d[0].data_length;
929 unifi_trace(priv, UDBG1,
930 "_identify_sme_ma_pkt_ind: skb_80211_to_ether -->\n");
931 r = skb_80211_to_ether(priv, skb, daddr, saddr,
932 signal, bulkdata);
933 unifi_trace(priv, UDBG1,
934 "_identify_sme_ma_pkt_ind: skb_80211_to_ether <--\n");
935 if (r) {
936 return -EINVAL;
939 /* ... but we indicate buffer and length */
940 bulkdata->d[0].os_data_ptr = skb->data;
941 bulkdata->d[0].data_length = skb->len;
942 } else {
943 /* Add the MAC addresses before the SNAP */
944 bulkdata->d[0].os_data_ptr -= 2*ETH_ALEN;
945 bulkdata->d[0].data_length += 2*ETH_ALEN;
946 memcpy((void*)bulkdata->d[0].os_data_ptr, daddr, ETH_ALEN);
947 memcpy((void*)bulkdata->d[0].os_data_ptr + ETH_ALEN, saddr, ETH_ALEN);
950 unifi_trace(priv, UDBG1,
951 "_identify_sme_ma_pkt_ind: unifi_sys_ma_pkt_ind -->\n");
952 CsrWifiRouterMaPacketIndSend(priv->sme_unidata_ind_filters[i].appHandle,
953 (pkt_ind->VirtualInterfaceIdentifier & 0xff),
955 pkt_ind->ReceptionStatus,
956 bulkdata->d[0].data_length,
957 (u8*)bulkdata->d[0].os_data_ptr,
958 NULL,
959 pkt_ind->Rssi,
960 pkt_ind->Snr,
961 pkt_ind->ReceivedRate);
964 unifi_trace(priv, UDBG1,
965 "_identify_sme_ma_pkt_ind: unifi_sys_ma_pkt_ind <--\n");
968 return 1;
973 return -1;
975 #endif /* CSR_SUPPORT_SME */
978 * ---------------------------------------------------------------------------
979 * skb_80211_to_ether
981 * Make sure the received frame is in Ethernet (802.3) form.
982 * De-encapsulates SNAP if necessary, adds a ethernet header.
983 * The source buffer should not contain an 802.11 MAC header
985 * Arguments:
986 * payload Pointer to packet data received from UniFi.
987 * payload_length Number of bytes of data received from UniFi.
988 * daddr Destination MAC address.
989 * saddr Source MAC address.
991 * Returns:
992 * 0 on success, -1 if the packet is bad and should be dropped,
993 * 1 if the packet was forwarded to the SME or AMP client.
994 * ---------------------------------------------------------------------------
997 skb_80211_to_ether(unifi_priv_t *priv, struct sk_buff *skb,
998 const unsigned char *daddr, const unsigned char *saddr,
999 const CSR_SIGNAL *signal,
1000 bulk_data_param_t *bulkdata)
1002 unsigned char *payload;
1003 int payload_length;
1004 struct ethhdr *eth;
1005 llc_snap_hdr_t *snap;
1006 int headroom;
1007 #define UF_VLAN_LLC_HEADER_SIZE 18
1008 static const u8 vlan_inner_snap[] = { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00 };
1009 #if defined(CSR_NATIVE_SOFTMAC) && defined(CSR_SUPPORT_SME)
1010 const CSR_MA_PACKET_INDICATION *pkt_ind = &signal->u.MaPacketIndication;
1011 #endif
1013 if(skb== NULL || daddr == NULL || saddr == NULL){
1014 unifi_error(priv,"skb_80211_to_ether: PBC fail\n");
1015 return 1;
1018 payload = skb->data;
1019 payload_length = skb->len;
1021 snap = (llc_snap_hdr_t *)payload;
1022 eth = (struct ethhdr *)payload;
1024 /* get the skb headroom size */
1025 headroom = skb_headroom(skb);
1028 * Test for the various encodings
1030 if ((payload_length >= sizeof(llc_snap_hdr_t)) &&
1031 (snap->dsap == 0xAA) &&
1032 (snap->ssap == 0xAA) &&
1033 (snap->ctrl == 0x03) &&
1034 (snap->oui[0] == 0) &&
1035 (snap->oui[1] == 0) &&
1036 ((snap->oui[2] == 0) || (snap->oui[2] == 0xF8)))
1038 /* AppleTalk AARP (2) or IPX SNAP */
1039 if ((snap->oui[2] == 0) &&
1040 ((ntohs(snap->protocol) == ETH_P_AARP) || (ntohs(snap->protocol) == ETH_P_IPX)))
1042 u16 len;
1044 unifi_trace(priv, UDBG3, "%s len: %d\n",
1045 (ntohs(snap->protocol) == ETH_P_AARP) ? "ETH_P_AARP" : "ETH_P_IPX",
1046 payload_length);
1048 /* check for headroom availability before skb_push */
1049 if (headroom < (2 * ETH_ALEN + 2)) {
1050 unifi_warning(priv, "headroom not available to skb_push ether header\n");
1051 return -1;
1054 /* Add 802.3 header and leave full payload */
1055 len = htons(skb->len);
1056 memcpy(skb_push(skb, 2), &len, 2);
1057 memcpy(skb_push(skb, ETH_ALEN), saddr, ETH_ALEN);
1058 memcpy(skb_push(skb, ETH_ALEN), daddr, ETH_ALEN);
1060 return 0;
1062 /* VLAN-tagged IP */
1063 if ((snap->oui[2] == 0) && (ntohs(snap->protocol) == ETH_P_8021Q))
1066 * The translation doesn't change the packet length, so is done in-place.
1068 * Example header (from Std 802.11-2007 Annex M):
1069 * AA-AA-03-00-00-00-81-00-87-65-AA-AA-03-00-00-00-08-06
1070 * -------SNAP-------p1-p1-ll-ll-------SNAP--------p2-p2
1071 * dd-dd-dd-dd-dd-dd-aa-aa-aa-aa-aa-aa-p1-p1-ll-ll-p2-p2
1072 * dd-dd-dd-dd-dd-dd-aa-aa-aa-aa-aa-aa-81-00-87-65-08-06
1074 u16 vlan_snap;
1076 if (payload_length < UF_VLAN_LLC_HEADER_SIZE) {
1077 unifi_warning(priv, "VLAN SNAP header too short: %d bytes\n", payload_length);
1078 return -1;
1081 if (memcmp(payload + 10, vlan_inner_snap, 6)) {
1082 unifi_warning(priv, "VLAN malformatted SNAP header.\n");
1083 return -1;
1086 unifi_trace(priv, UDBG3, "VLAN SNAP: %02x-%02x\n", payload[8], payload[9]);
1087 unifi_trace(priv, UDBG3, "VLAN len: %d\n", payload_length);
1089 /* Create the 802.3 header */
1091 vlan_snap = *((u16*)(payload + 8));
1093 /* Create LLC header without byte-swapping */
1094 eth->h_proto = snap->protocol;
1096 memcpy(eth->h_dest, daddr, ETH_ALEN);
1097 memcpy(eth->h_source, saddr, ETH_ALEN);
1098 *(u16*)(eth + 1) = vlan_snap;
1099 return 0;
1102 /* it's a SNAP + RFC1042 frame */
1103 unifi_trace(priv, UDBG3, "SNAP+RFC1042 len: %d\n", payload_length);
1105 /* chop SNAP+llc header from skb. */
1106 skb_pull(skb, sizeof(llc_snap_hdr_t));
1108 /* Since skb_pull called above to chop snap+llc, no need to check for headroom
1109 * availability before skb_push
1111 /* create 802.3 header at beginning of skb. */
1112 eth = (struct ethhdr *)skb_push(skb, ETH_HLEN);
1113 memcpy(eth->h_dest, daddr, ETH_ALEN);
1114 memcpy(eth->h_source, saddr, ETH_ALEN);
1115 /* Copy protocol field without byte-swapping */
1116 eth->h_proto = snap->protocol;
1117 } else {
1118 u16 len;
1120 /* check for headroom availability before skb_push */
1121 if (headroom < (2 * ETH_ALEN + 2)) {
1122 unifi_warning(priv, "headroom not available to skb_push ether header\n");
1123 return -1;
1125 /* Add 802.3 header and leave full payload */
1126 len = htons(skb->len);
1127 memcpy(skb_push(skb, 2), &len, 2);
1128 memcpy(skb_push(skb, ETH_ALEN), saddr, ETH_ALEN);
1129 memcpy(skb_push(skb, ETH_ALEN), daddr, ETH_ALEN);
1131 return 1;
1134 return 0;
1135 } /* skb_80211_to_ether() */
1138 static CsrWifiRouterCtrlPortAction verify_port(unifi_priv_t *priv, unsigned char *address, int queue, u16 interfaceTag)
1140 #ifdef CSR_NATIVE_LINUX
1141 #ifdef CSR_SUPPORT_WEXT
1142 if (queue == UF_CONTROLLED_PORT_Q) {
1143 return priv->wext_conf.block_controlled_port;
1144 } else {
1145 return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN;
1147 #else
1148 return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN; /* default to open for softmac dev */
1149 #endif
1150 #else
1151 return uf_sme_port_state(priv, address, queue, interfaceTag);
1152 #endif
1156 * ---------------------------------------------------------------------------
1157 * prepare_and_add_macheader
1160 * These functions adds mac header for packet from netdev
1161 * to UniFi for transmission.
1162 * EAP protocol packets are also appended with Mac header &
1163 * sent using send_ma_pkt_request().
1165 * Arguments:
1166 * priv Pointer to device private context struct
1167 * skb Socket buffer containing data packet to transmit
1168 * newSkb Socket buffer containing data packet + Mac header if no sufficient headroom in skb
1169 * serviceClass to append QOS control header in Mac header
1170 * bulkdata if newSkb allocated then bulkdata updated to send to unifi
1171 * interfaceTag the interfaceID on which activity going on
1172 * daddr destination address
1173 * saddr source address
1174 * protection protection bit set in framce control of mac header
1176 * Returns:
1177 * Zero on success or error code.
1178 * ---------------------------------------------------------------------------
1181 int prepare_and_add_macheader(unifi_priv_t *priv, struct sk_buff *skb, struct sk_buff *newSkb,
1182 CSR_PRIORITY priority,
1183 bulk_data_param_t *bulkdata,
1184 u16 interfaceTag,
1185 const u8 *daddr,
1186 const u8 *saddr,
1187 u8 protection)
1189 u16 fc = 0;
1190 u8 qc = 0;
1191 u8 macHeaderLengthInBytes = MAC_HEADER_SIZE, *bufPtr = NULL;
1192 bulk_data_param_t data_ptrs;
1193 CsrResult csrResult;
1194 int headroom =0;
1195 u8 direction = 0;
1196 netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
1197 u8 *addressOne;
1198 u8 bQosNull = false;
1200 if (skb == NULL) {
1201 unifi_error(priv,"prepare_and_add_macheader: Invalid SKB reference\n");
1202 return -1;
1205 /* add a MAC header refer: 7.1.3.1 Frame Control field in P802.11REVmb.book */
1206 if (priority != CSR_CONTENTION) {
1207 /* EAPOL packets don't go as QOS_DATA */
1208 if (priority == CSR_MANAGEMENT) {
1209 fc |= cpu_to_le16(IEEE802_11_FC_TYPE_DATA);
1210 } else {
1211 /* Qos Control Field */
1212 macHeaderLengthInBytes += QOS_CONTROL_HEADER_SIZE;
1214 if (skb->len) {
1216 fc |= cpu_to_le16(IEEE802_11_FC_TYPE_QOS_DATA);
1217 } else {
1218 fc |= cpu_to_le16(IEEE802_11_FC_TYPE_QOS_NULL);
1219 bQosNull = true;
1222 } else {
1223 if(skb->len == 0) {
1224 fc |= cpu_to_le16(IEEE802_11_FC_TYPE_NULL);
1225 } else {
1226 fc |= cpu_to_le16(IEEE802_11_FC_TYPE_DATA);
1230 switch (interfacePriv->interfaceMode)
1232 case CSR_WIFI_ROUTER_CTRL_MODE_STA:
1233 case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
1234 direction = 2;
1235 fc |= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK);
1236 break;
1237 case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
1238 direction = 0;
1239 break;
1240 case CSR_WIFI_ROUTER_CTRL_MODE_AP:
1241 case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
1242 direction = 1;
1243 fc |= cpu_to_le16(IEEE802_11_FC_FROM_DS_MASK);
1244 break;
1245 case CSR_WIFI_ROUTER_CTRL_MODE_AMP:
1246 if (priority == CSR_MANAGEMENT ) {
1248 direction = 2;
1249 fc |= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK);
1250 } else {
1251 /* Data frames have to use WDS 4 address frames */
1252 direction = 3;
1253 fc |= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK | IEEE802_11_FC_FROM_DS_MASK);
1254 macHeaderLengthInBytes += 6;
1256 break;
1257 default:
1258 unifi_warning(priv, "prepare_and_add_macheader: Unknown mode %d\n",
1259 interfacePriv->interfaceMode);
1263 /* If Sta is QOS & HTC is supported then need to set 'order' bit */
1264 /* We don't support HT Control for now */
1266 if(protection) {
1267 fc |= cpu_to_le16(IEEE802_11_FC_PROTECTED_MASK);
1270 /* check the skb headroom before pushing mac header */
1271 headroom = skb_headroom(skb);
1273 if (headroom < macHeaderLengthInBytes) {
1274 unifi_trace(priv, UDBG5,
1275 "prepare_and_add_macheader: Allocate headroom extra %d bytes\n",
1276 macHeaderLengthInBytes);
1278 csrResult = unifi_net_data_malloc(priv, &data_ptrs.d[0], skb->len + macHeaderLengthInBytes);
1280 if (csrResult != CSR_RESULT_SUCCESS) {
1281 unifi_error(priv, " failed to allocate request_data. in %s func\n", __FUNCTION__);
1282 return -1;
1284 newSkb = (struct sk_buff *)(data_ptrs.d[0].os_net_buf_ptr);
1285 newSkb->len = skb->len + macHeaderLengthInBytes;
1287 memcpy((void*)data_ptrs.d[0].os_data_ptr + macHeaderLengthInBytes,
1288 skb->data, skb->len);
1290 bulkdata->d[0].os_data_ptr = newSkb->data;
1291 bulkdata->d[0].os_net_buf_ptr = (unsigned char*)newSkb;
1292 bulkdata->d[0].data_length = newSkb->len;
1294 bufPtr = (u8*)data_ptrs.d[0].os_data_ptr;
1296 /* The old skb will not be used again */
1297 kfree_skb(skb);
1298 } else {
1300 /* headroom has sufficient size, so will get proper pointer */
1301 bufPtr = (u8*)skb_push(skb, macHeaderLengthInBytes);
1302 bulkdata->d[0].os_data_ptr = skb->data;
1303 bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skb;
1304 bulkdata->d[0].data_length = skb->len;
1307 /* Frame the actual MAC header */
1309 memset(bufPtr, 0, macHeaderLengthInBytes);
1311 /* copy frameControl field */
1312 memcpy(bufPtr, &fc, sizeof(fc));
1313 bufPtr += sizeof(fc);
1314 macHeaderLengthInBytes -= sizeof(fc);
1316 /* Duration/ID field which is 2 bytes */
1317 bufPtr += 2;
1318 macHeaderLengthInBytes -= 2;
1320 switch(direction)
1322 case 0:
1323 /* Its an Ad-Hoc no need to route it through AP */
1324 /* Address1: MAC address of the destination from eth header */
1325 memcpy(bufPtr, daddr, ETH_ALEN);
1326 bufPtr += ETH_ALEN;
1327 macHeaderLengthInBytes -= ETH_ALEN;
1329 /* Address2: MAC address of the source */
1330 memcpy(bufPtr, saddr, ETH_ALEN);
1331 bufPtr += ETH_ALEN;
1332 macHeaderLengthInBytes -= ETH_ALEN;
1334 /* Address3: the BSSID (locally generated in AdHoc (creators Bssid)) */
1335 memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN);
1336 bufPtr += ETH_ALEN;
1337 macHeaderLengthInBytes -= ETH_ALEN;
1338 break;
1339 case 1:
1340 /* Address1: MAC address of the actual destination */
1341 memcpy(bufPtr, daddr, ETH_ALEN);
1342 bufPtr += ETH_ALEN;
1343 macHeaderLengthInBytes -= ETH_ALEN;
1344 /* Address2: The MAC address of the AP */
1345 memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN);
1346 bufPtr += ETH_ALEN;
1347 macHeaderLengthInBytes -= ETH_ALEN;
1349 /* Address3: MAC address of the source from eth header */
1350 memcpy(bufPtr, saddr, ETH_ALEN);
1351 bufPtr += ETH_ALEN;
1352 macHeaderLengthInBytes -= ETH_ALEN;
1353 break;
1354 case 2:
1355 /* Address1: To AP is the MAC address of the AP to which its associated */
1356 memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN);
1357 bufPtr += ETH_ALEN;
1358 macHeaderLengthInBytes -= ETH_ALEN;
1360 /* Address2: MAC address of the source from eth header */
1361 memcpy(bufPtr, saddr, ETH_ALEN);
1362 bufPtr += ETH_ALEN;
1363 macHeaderLengthInBytes -= ETH_ALEN;
1365 /* Address3: MAC address of the actual destination on the distribution system */
1366 memcpy(bufPtr, daddr, ETH_ALEN);
1367 bufPtr += ETH_ALEN;
1368 macHeaderLengthInBytes -= ETH_ALEN;
1369 break;
1370 case 3:
1371 memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN);
1372 bufPtr += ETH_ALEN;
1373 macHeaderLengthInBytes -= ETH_ALEN;
1375 /* Address2: MAC address of the source from eth header */
1376 memcpy(bufPtr, saddr, ETH_ALEN);
1377 bufPtr += ETH_ALEN;
1378 macHeaderLengthInBytes -= ETH_ALEN;
1380 /* Address3: MAC address of the actual destination on the distribution system */
1381 memcpy(bufPtr, daddr, ETH_ALEN);
1382 bufPtr += ETH_ALEN;
1383 macHeaderLengthInBytes -= ETH_ALEN;
1384 break;
1385 default:
1386 unifi_error(priv,"Unknown direction =%d : Not handled now\n",direction);
1387 return -1;
1389 /* 2 bytes of frame control field, appended by firmware */
1390 bufPtr += 2;
1391 macHeaderLengthInBytes -= 2;
1393 if (3 == direction) {
1394 /* Address4: MAC address of the source */
1395 memcpy(bufPtr, saddr, ETH_ALEN);
1396 bufPtr += ETH_ALEN;
1397 macHeaderLengthInBytes -= ETH_ALEN;
1400 /* IF Qos Data or Qos Null Data then set QosControl field */
1401 if ((priority != CSR_CONTENTION) && (macHeaderLengthInBytes >= QOS_CONTROL_HEADER_SIZE)) {
1403 if (priority > 7) {
1404 unifi_trace(priv, UDBG1, "data packets priority is more than 7, priority = %x\n", priority);
1405 qc |= 7;
1406 } else {
1407 qc |= priority;
1409 /*assigning address1
1410 * Address1 offset taken fromm bufPtr(currently bufPtr pointing to Qos contorl) variable in reverse direction
1411 * Address4 don't exit
1414 addressOne = bufPtr- ADDRESS_ONE_OFFSET;
1416 if (addressOne[0] & 0x1) {
1417 /* multicast/broadcast frames, no acknowledgement needed */
1418 qc |= 1 << 5;
1420 /* non-AP mode only for now */
1421 if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA ||
1422 interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS ||
1423 interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI) {
1424 /* In case of STA and IBSS case eosp and txop limit is 0. */
1425 } else {
1426 if(bQosNull) {
1427 qc |= 1 << 4;
1431 /* append Qos control field to mac header */
1432 bufPtr[0] = qc;
1433 /* txop limit is 0 */
1434 bufPtr[1] = 0;
1435 macHeaderLengthInBytes -= QOS_CONTROL_HEADER_SIZE;
1437 if (macHeaderLengthInBytes) {
1438 unifi_warning(priv, " Mac header not appended properly\n");
1439 return -1;
1441 return 0;
1445 * ---------------------------------------------------------------------------
1446 * send_ma_pkt_request
1448 * These functions send a data packet to UniFi for transmission.
1449 * EAP protocol packets are also sent as send_ma_pkt_request().
1451 * Arguments:
1452 * priv Pointer to device private context struct
1453 * skb Socket buffer containing data packet to transmit
1454 * ehdr Pointer to Ethernet header within skb.
1456 * Returns:
1457 * Zero on success or error code.
1458 * ---------------------------------------------------------------------------
1461 static int
1462 send_ma_pkt_request(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr *ehdr, CSR_PRIORITY priority)
1464 int r;
1465 u16 i;
1466 u8 eapolStore = FALSE;
1467 struct sk_buff *newSkb = NULL;
1468 bulk_data_param_t bulkdata;
1469 const int proto = ntohs(ehdr->h_proto);
1470 u16 interfaceTag;
1471 CsrWifiMacAddress peerAddress;
1472 CSR_TRANSMISSION_CONTROL transmissionControl = CSR_NO_CONFIRM_REQUIRED;
1473 s8 protection;
1474 netInterface_priv_t *interfacePriv = NULL;
1475 CSR_RATE TransmitRate = (CSR_RATE)0;
1477 unifi_trace(priv, UDBG5, "entering send_ma_pkt_request\n");
1479 /* Get the interface Tag by means of source Mac address */
1480 for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
1481 if (!memcmp(priv->netdev[i]->dev_addr, ehdr->h_source, ETH_ALEN)) {
1482 interfaceTag = i;
1483 interfacePriv = priv->interfacePriv[interfaceTag];
1484 break;
1488 if (interfacePriv == NULL) {
1489 /* No match found - error */
1490 interfaceTag = 0;
1491 interfacePriv = priv->interfacePriv[interfaceTag];
1492 unifi_warning(priv, "Mac address not matching ... debugging needed\n");
1493 interfacePriv->stats.tx_dropped++;
1494 kfree_skb(skb);
1495 return -1;
1498 /* Add a SNAP header if necessary */
1499 if (skb_add_llc_snap(priv->netdev[interfaceTag], skb, proto) != 0) {
1500 /* convert failed */
1501 unifi_error(priv, "skb_add_llc_snap failed.\n");
1502 kfree_skb(skb);
1503 return -1;
1506 bulkdata.d[0].os_data_ptr = skb->data;
1507 bulkdata.d[0].os_net_buf_ptr = (unsigned char*)skb;
1508 bulkdata.d[0].net_buf_length = bulkdata.d[0].data_length = skb->len;
1509 bulkdata.d[1].os_data_ptr = NULL;
1510 bulkdata.d[1].os_net_buf_ptr = NULL;
1511 bulkdata.d[1].net_buf_length = bulkdata.d[1].data_length = 0;
1513 #ifdef CSR_SUPPORT_SME
1514 /* Notify the TA module for the Tx frame for non AP/P2PGO mode*/
1515 if ((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_AP) &&
1516 (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_P2PGO)) {
1517 unifi_ta_sample(priv->card, CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX,
1518 &bulkdata.d[0], ehdr->h_source,
1519 priv->netdev[interfaceTag]->dev_addr,
1520 jiffies_to_msecs(jiffies),
1521 0); /* rate is unknown on tx */
1523 #endif /* CSR_SUPPORT_SME */
1525 if ((proto == ETH_P_PAE)
1526 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1527 || (proto == ETH_P_WAI)
1528 #endif
1531 /* check for m4 detection */
1532 if (0 == uf_verify_m4(priv, bulkdata.d[0].os_data_ptr, bulkdata.d[0].data_length)) {
1533 eapolStore = TRUE;
1537 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1538 if (proto == ETH_P_WAI)
1540 protection = 0; /*WAI packets always sent unencrypted*/
1542 else
1544 #endif
1545 #ifdef CSR_SUPPORT_SME
1546 if ((protection = uf_get_protection_bit_from_interfacemode(priv, interfaceTag, ehdr->h_dest)) < 0) {
1547 unifi_warning(priv, "unicast address, but destination not in station record database\n");
1548 unifi_net_data_free(priv, &bulkdata.d[0]);
1549 return -1;
1551 #else
1552 protection = 0;
1553 #endif
1554 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1556 #endif
1558 /* append Mac header for Eapol as well as data packet */
1559 if (prepare_and_add_macheader(priv, skb, newSkb, priority, &bulkdata, interfaceTag, ehdr->h_dest, ehdr->h_source, protection)) {
1560 unifi_error(priv, "failed to create MAC header\n");
1561 unifi_net_data_free(priv, &bulkdata.d[0]);
1562 return -1;
1565 /* RA address must contain the immediate destination MAC address that is similar to
1566 * the Address 1 field of 802.11 Mac header here 4 is: (sizeof(framecontrol) + sizeof (durationID))
1567 * which is address 1 field
1569 memcpy(peerAddress.a, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
1571 unifi_trace(priv, UDBG5, "RA[0]=%x, RA[1]=%x, RA[2]=%x, RA[3]=%x, RA[4]=%x, RA[5]=%x\n",
1572 peerAddress.a[0],peerAddress.a[1], peerAddress.a[2], peerAddress.a[3],
1573 peerAddress.a[4],peerAddress.a[5]);
1576 if ((proto == ETH_P_PAE)
1577 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1578 || (proto == ETH_P_WAI)
1579 #endif
1582 CSR_SIGNAL signal;
1583 CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest;
1585 /* initialize signal to zero */
1586 memset(&signal, 0, sizeof(CSR_SIGNAL));
1588 /* Frame MA_PACKET request */
1589 signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID;
1590 signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
1591 signal.SignalPrimitiveHeader.SenderProcessId = priv->netdev_client->sender_id;
1593 transmissionControl = req->TransmissionControl = 0;
1594 #ifdef CSR_SUPPORT_SME
1595 if (eapolStore)
1597 netInterface_priv_t *netpriv = (netInterface_priv_t *)netdev_priv(priv->netdev[interfaceTag]);
1599 /* Fill the MA-PACKET.req */
1601 req->Priority = priority;
1602 unifi_trace(priv, UDBG3, "Tx Frame with Priority: %x\n", req->Priority);
1604 /* rate selected by firmware */
1605 req->TransmitRate = 0;
1606 req->HostTag = CSR_WIFI_EAPOL_M4_HOST_TAG;
1607 /* RA address matching with address 1 of Mac header */
1608 memcpy(req->Ra.x, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
1610 spin_lock(&priv->m4_lock);
1611 /* Store the M4-PACKET.req for later */
1612 interfacePriv->m4_signal = signal;
1613 interfacePriv->m4_bulk_data.net_buf_length = bulkdata.d[0].net_buf_length;
1614 interfacePriv->m4_bulk_data.data_length = bulkdata.d[0].data_length;
1615 interfacePriv->m4_bulk_data.os_data_ptr = bulkdata.d[0].os_data_ptr;
1616 interfacePriv->m4_bulk_data.os_net_buf_ptr = bulkdata.d[0].os_net_buf_ptr;
1617 spin_unlock(&priv->m4_lock);
1619 /* Signal the workqueue to call CsrWifiRouterCtrlM4ReadyToSendIndSend().
1620 * It cannot be called directly from the tx path because it
1621 * does a non-atomic kmalloc via the framework's CsrPmemAlloc().
1623 queue_work(priv->unifi_workqueue, &netpriv->send_m4_ready_task);
1625 return 0;
1627 #endif
1628 }/*EAPOL or WAI packet*/
1630 #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
1631 if ((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) && \
1632 (priv->wapi_unicast_filter) && \
1633 (proto != ETH_P_PAE) && \
1634 (proto != ETH_P_WAI) && \
1635 (skb->len > 0))
1637 CSR_SIGNAL signal;
1638 CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest;
1639 netInterface_priv_t *netpriv = (netInterface_priv_t *)netdev_priv(priv->netdev[interfaceTag]);
1641 unifi_trace(priv, UDBG4, "send_ma_pkt_request() - WAPI unicast data packet when USKID = 1 \n");
1643 /* initialize signal to zero */
1644 memset(&signal, 0, sizeof(CSR_SIGNAL));
1645 /* Frame MA_PACKET request */
1646 signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID;
1647 signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
1648 signal.SignalPrimitiveHeader.SenderProcessId = priv->netdev_client->sender_id;
1650 /* Fill the MA-PACKET.req */
1651 req->TransmissionControl = 0;
1652 req->Priority = priority;
1653 unifi_trace(priv, UDBG3, "Tx Frame with Priority: %x\n", req->Priority);
1654 req->TransmitRate = (CSR_RATE) 0; /* rate selected by firmware */
1655 req->HostTag = 0xffffffff; /* Ask for a new HostTag */
1656 /* RA address matching with address 1 of Mac header */
1657 memcpy(req->Ra.x, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
1659 /* Store the M4-PACKET.req for later */
1660 spin_lock(&priv->wapi_lock);
1661 interfacePriv->wapi_unicast_ma_pkt_sig = signal;
1662 interfacePriv->wapi_unicast_bulk_data.net_buf_length = bulkdata.d[0].net_buf_length;
1663 interfacePriv->wapi_unicast_bulk_data.data_length = bulkdata.d[0].data_length;
1664 interfacePriv->wapi_unicast_bulk_data.os_data_ptr = bulkdata.d[0].os_data_ptr;
1665 interfacePriv->wapi_unicast_bulk_data.os_net_buf_ptr = bulkdata.d[0].os_net_buf_ptr;
1666 spin_unlock(&priv->wapi_lock);
1668 /* Signal the workqueue to call CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend().
1669 * It cannot be called directly from the tx path because it
1670 * does a non-atomic kmalloc via the framework's CsrPmemAlloc().
1672 queue_work(priv->unifi_workqueue, &netpriv->send_pkt_to_encrypt);
1674 return 0;
1676 #endif
1678 if(priv->cmanrTestMode)
1680 TransmitRate = priv->cmanrTestModeTransmitRate;
1681 unifi_trace(priv, UDBG2, "send_ma_pkt_request: cmanrTestModeTransmitRate = %d TransmitRate=%d\n",
1682 priv->cmanrTestModeTransmitRate,
1683 TransmitRate
1687 /* Send UniFi msg */
1688 /* Here hostTag is been sent as 0xffffffff, its been appended properly while framing MA-Packet request in pdu_processing.c file */
1689 r = uf_process_ma_packet_req(priv,
1690 peerAddress.a,
1691 0xffffffff, /* Ask for a new HostTag */
1692 interfaceTag,
1693 transmissionControl,
1694 TransmitRate,
1695 priority,
1696 priv->netdev_client->sender_id,
1697 &bulkdata);
1699 if (r) {
1700 unifi_trace(priv, UDBG1, "(HIP validation failure) r = %x\n", r);
1701 unifi_net_data_free(priv, &bulkdata.d[0]);
1702 return -1;
1705 unifi_trace(priv, UDBG3, "leaving send_ma_pkt_request, UNITDATA result code = %d\n", r);
1707 return r;
1708 } /* send_ma_pkt_request() */
1711 * ---------------------------------------------------------------------------
1712 * uf_net_xmit
1714 * This function is called by the higher level stack to transmit an
1715 * ethernet packet.
1717 * Arguments:
1718 * skb Ethernet packet to send.
1719 * dev Pointer to the linux net device.
1721 * Returns:
1722 * 0 on success (packet was consumed, not necessarily transmitted)
1723 * 1 if packet was requeued
1724 * -1 on error
1727 * Notes:
1728 * The controlled port is handled in the qdisc dequeue handler.
1729 * ---------------------------------------------------------------------------
1731 static netdev_tx_t
1732 uf_net_xmit(struct sk_buff *skb, struct net_device *dev)
1734 netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
1735 unifi_priv_t *priv = interfacePriv->privPtr;
1736 struct ethhdr ehdr;
1737 int proto, port;
1738 int result;
1739 static tx_signal_handler tx_handler;
1740 CSR_PRIORITY priority;
1741 CsrWifiRouterCtrlPortAction port_action;
1743 unifi_trace(priv, UDBG5, "unifi_net_xmit: skb = %x\n", skb);
1745 memcpy(&ehdr, skb->data, ETH_HLEN);
1746 proto = ntohs(ehdr.h_proto);
1747 priority = get_packet_priority(priv, skb, &ehdr, interfacePriv);
1749 /* All frames are sent as MA-PACKET.req (EAPOL also) */
1750 tx_handler = send_ma_pkt_request;
1752 /* 802.1x - apply controlled/uncontrolled port rules */
1753 if ((proto != ETH_P_PAE)
1754 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1755 && (proto != ETH_P_WAI)
1756 #endif
1758 port = UF_CONTROLLED_PORT_Q;
1759 } else {
1760 /* queue 4 */
1761 port = UF_UNCONTROLLED_PORT_Q;
1764 /* Uncontrolled port rules apply */
1765 port_action = verify_port(priv
1766 , (((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode)||(CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI== interfacePriv->interfaceMode))? interfacePriv->bssid.a: ehdr.h_dest)
1767 , port
1768 , interfacePriv->InterfaceTag);
1770 if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
1771 unifi_trace(priv, UDBG5,
1772 "uf_net_xmit: %s controlled port open\n",
1773 port ? "" : "un");
1774 /* Remove the ethernet header */
1775 skb_pull(skb, ETH_HLEN);
1776 result = tx_handler(priv, skb, &ehdr, priority);
1777 } else {
1779 /* Discard the packet if necessary */
1780 unifi_trace(priv, UDBG2,
1781 "uf_net_xmit: %s controlled port %s\n",
1782 port ? "" : "un", port_action==CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK ? "blocked" : "closed");
1783 interfacePriv->stats.tx_dropped++;
1784 kfree_skb(skb);
1786 return NETDEV_TX_OK;
1789 if (result == NETDEV_TX_OK) {
1790 #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
1791 /* Don't update the tx stats when the pkt is to be sent for sw encryption*/
1792 if (!((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) &&
1793 (priv->wapi_unicast_filter == 1)))
1795 dev->trans_start = jiffies;
1796 /* Should really count tx stats in the UNITDATA.status signal but
1797 * that doesn't have the length.
1799 interfacePriv->stats.tx_packets++;
1800 /* count only the packet payload */
1801 interfacePriv->stats.tx_bytes += skb->len;
1804 #else
1805 dev->trans_start = jiffies;
1808 * Should really count tx stats in the UNITDATA.status signal but
1809 * that doesn't have the length.
1811 interfacePriv->stats.tx_packets++;
1812 /* count only the packet payload */
1813 interfacePriv->stats.tx_bytes += skb->len;
1814 #endif
1815 } else if (result < 0) {
1817 /* Failed to send: fh queue was full, and the skb was discarded.
1818 * Return OK to indicate that the buffer was consumed, to stop the
1819 * kernel re-transmitting the freed buffer.
1821 interfacePriv->stats.tx_dropped++;
1822 unifi_trace(priv, UDBG1, "unifi_net_xmit: (Packet Drop), dropped count = %x\n", interfacePriv->stats.tx_dropped);
1823 result = NETDEV_TX_OK;
1826 /* The skb will have been freed by send_XXX_request() */
1828 return result;
1829 } /* uf_net_xmit() */
1832 * ---------------------------------------------------------------------------
1833 * unifi_pause_xmit
1834 * unifi_restart_xmit
1836 * These functions are called from the UniFi core to control the flow
1837 * of packets from the upper layers.
1838 * unifi_pause_xmit() is called when the internal queue is full and
1839 * should take action to stop unifi_ma_unitdata() being called.
1840 * When the queue has drained, unifi_restart_xmit() will be called to
1841 * re-enable the flow of packets for transmission.
1843 * Arguments:
1844 * ospriv OS private context pointer.
1846 * Returns:
1847 * unifi_pause_xmit() is called from interrupt context.
1848 * ---------------------------------------------------------------------------
1850 void
1851 unifi_pause_xmit(void *ospriv, unifi_TrafficQueue queue)
1853 unifi_priv_t *priv = ospriv;
1854 int i; /* used as a loop counter */
1856 unifi_trace(priv, UDBG2, "Stopping queue %d\n", queue);
1858 for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++)
1860 if (netif_running(priv->netdev[i]))
1862 netif_stop_subqueue(priv->netdev[i], (u16)queue);
1866 #ifdef CSR_SUPPORT_SME
1867 if(queue<=3) {
1868 routerStartBuffering(priv,queue);
1869 unifi_trace(priv,UDBG2,"Start buffering %d\n", queue);
1870 } else {
1871 routerStartBuffering(priv,0);
1872 unifi_error(priv, "Start buffering %d defaulting to 0\n", queue);
1874 #endif
1876 } /* unifi_pause_xmit() */
1878 void
1879 unifi_restart_xmit(void *ospriv, unifi_TrafficQueue queue)
1881 unifi_priv_t *priv = ospriv;
1882 int i=0; /* used as a loop counter */
1884 unifi_trace(priv, UDBG2, "Waking queue %d\n", queue);
1886 for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++)
1888 if (netif_running(priv->netdev[i]))
1890 netif_wake_subqueue(priv->netdev[i], (u16)queue);
1894 #ifdef CSR_SUPPORT_SME
1895 if(queue <=3) {
1896 routerStopBuffering(priv,queue);
1897 uf_send_buffered_frames(priv,queue);
1898 } else {
1899 routerStopBuffering(priv,0);
1900 uf_send_buffered_frames(priv,0);
1902 #endif
1903 } /* unifi_restart_xmit() */
1906 static void
1907 indicate_rx_skb(unifi_priv_t *priv, u16 ifTag, u8* dst_a, u8* src_a, struct sk_buff *skb, CSR_SIGNAL *signal,
1908 bulk_data_param_t *bulkdata)
1910 int r, sr = 0;
1911 struct net_device *dev;
1913 #ifdef CSR_SUPPORT_SME
1914 llc_snap_hdr_t *snap;
1916 snap = (llc_snap_hdr_t *)skb->data;
1918 sr = _identify_sme_ma_pkt_ind(priv,
1919 snap->oui, ntohs(snap->protocol),
1920 signal,
1921 bulkdata,
1922 dst_a, src_a );
1923 #endif
1926 * Decapsulate any SNAP header and
1927 * prepend an ethernet header so that the skb manipulation and ARP
1928 * stuff works.
1930 r = skb_80211_to_ether(priv, skb, dst_a, src_a,
1931 signal, bulkdata);
1932 if (r == -1) {
1933 /* Drop the packet and return */
1934 priv->interfacePriv[ifTag]->stats.rx_errors++;
1935 priv->interfacePriv[ifTag]->stats.rx_frame_errors++;
1936 unifi_net_data_free(priv, &bulkdata->d[0]);
1937 unifi_notice(priv, "indicate_rx_skb: Discard unknown frame.\n");
1938 return;
1941 /* Handle the case where packet is sent up through the subscription
1942 * API but should not be given to the network stack (AMP PAL case)
1943 * LLC header is different from WiFi and the packet has been subscribed for
1945 if (r == 1 && sr == 1) {
1946 unifi_net_data_free(priv, &bulkdata->d[0]);
1947 unifi_trace(priv, UDBG5, "indicate_rx_skb: Data given to subscription"
1948 "API, not being given to kernel\n");
1949 return;
1952 dev = priv->netdev[ifTag];
1953 /* Now we look like a regular ethernet frame */
1954 /* Fill in SKB meta data */
1955 skb->dev = dev;
1956 skb->protocol = eth_type_trans(skb, dev);
1957 skb->ip_summed = CHECKSUM_UNNECESSARY;
1959 /* Test for an overlength frame */
1960 if (skb->len > (dev->mtu + ETH_HLEN)) {
1961 /* A bogus length ethfrm has been encap'd. */
1962 /* Is someone trying an oflow attack? */
1963 unifi_error(priv, "%s: oversize frame (%d > %d)\n",
1964 dev->name,
1965 skb->len, dev->mtu + ETH_HLEN);
1967 /* Drop the packet and return */
1968 priv->interfacePriv[ifTag]->stats.rx_errors++;
1969 priv->interfacePriv[ifTag]->stats.rx_length_errors++;
1970 unifi_net_data_free(priv, &bulkdata->d[0]);
1971 return;
1975 if(priv->cmanrTestMode)
1977 const CSR_MA_PACKET_INDICATION *pkt_ind = &signal->u.MaPacketIndication;
1978 priv->cmanrTestModeTransmitRate = pkt_ind->ReceivedRate;
1979 unifi_trace(priv, UDBG2, "indicate_rx_skb: cmanrTestModeTransmitRate=%d\n", priv->cmanrTestModeTransmitRate);
1982 /* Pass SKB up the stack */
1983 #ifdef CSR_WIFI_USE_NETIF_RX
1984 netif_rx(skb);
1985 #else
1986 netif_rx_ni(skb);
1987 #endif
1989 if (dev != NULL) {
1990 dev->last_rx = jiffies;
1993 /* Bump rx stats */
1994 priv->interfacePriv[ifTag]->stats.rx_packets++;
1995 priv->interfacePriv[ifTag]->stats.rx_bytes += bulkdata->d[0].data_length;
1997 return;
2000 void
2001 uf_process_rx_pending_queue(unifi_priv_t *priv, int queue,
2002 CsrWifiMacAddress source_address,
2003 int indicate, u16 interfaceTag)
2005 rx_buffered_packets_t *rx_q_item;
2006 struct list_head *rx_list;
2007 struct list_head *n;
2008 struct list_head *l_h;
2009 static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
2010 netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
2012 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2013 unifi_error(priv, "uf_process_rx_pending_queue bad interfaceTag\n");
2014 return;
2017 if (queue == UF_CONTROLLED_PORT_Q) {
2018 rx_list = &interfacePriv->rx_controlled_list;
2019 } else {
2020 rx_list = &interfacePriv->rx_uncontrolled_list;
2023 down(&priv->rx_q_sem);
2024 list_for_each_safe(l_h, n, rx_list) {
2025 rx_q_item = list_entry(l_h, rx_buffered_packets_t, q);
2027 /* Validate against the source address */
2028 if (memcmp(broadcast_address.a, source_address.a, ETH_ALEN) &&
2029 memcmp(rx_q_item->sa.a, source_address.a, ETH_ALEN)) {
2031 unifi_trace(priv, UDBG2,
2032 "uf_process_rx_pending_queue: Skipping sa=%02X%02X%02X%02X%02X%02X skb=%p, bulkdata=%p\n",
2033 rx_q_item->sa.a[0], rx_q_item->sa.a[1],
2034 rx_q_item->sa.a[2], rx_q_item->sa.a[3],
2035 rx_q_item->sa.a[4], rx_q_item->sa.a[5],
2036 rx_q_item->skb, &rx_q_item->bulkdata.d[0]);
2037 continue;
2040 list_del(l_h);
2043 unifi_trace(priv, UDBG2,
2044 "uf_process_rx_pending_queue: Was Blocked skb=%p, bulkdata=%p\n",
2045 rx_q_item->skb, &rx_q_item->bulkdata);
2047 if (indicate) {
2048 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);
2049 } else {
2050 interfacePriv->stats.rx_dropped++;
2051 unifi_net_data_free(priv, &rx_q_item->bulkdata.d[0]);
2054 /* It is our resposibility to free the Rx structure object. */
2055 kfree(rx_q_item);
2057 up(&priv->rx_q_sem);
2061 * ---------------------------------------------------------------------------
2062 * uf_resume_data_plane
2064 * Is called when the (un)controlled port is set to open,
2065 * to notify the network stack to schedule for transmission
2066 * any packets queued in the qdisk while port was closed and
2067 * indicated to the stack any packets buffered in the Rx queues.
2069 * Arguments:
2070 * priv Pointer to device private struct
2072 * Returns:
2073 * ---------------------------------------------------------------------------
2075 void
2076 uf_resume_data_plane(unifi_priv_t *priv, int queue,
2077 CsrWifiMacAddress peer_address,
2078 u16 interfaceTag)
2080 #ifdef CSR_SUPPORT_WEXT
2081 netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
2082 #endif
2084 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2085 unifi_error(priv, "uf_resume_data_plane bad interfaceTag\n");
2086 return;
2089 unifi_trace(priv, UDBG2, "Resuming netif\n");
2092 * If we are waiting for the net device to enter the up state, don't
2093 * process the rx queue yet as it will be done by the callback when
2094 * the device is ready.
2096 #ifdef CSR_SUPPORT_WEXT
2097 if (!interfacePriv->wait_netdev_change)
2098 #endif
2100 #ifdef CONFIG_NET_SCHED
2101 if (netif_running(priv->netdev[interfaceTag])) {
2102 netif_tx_schedule_all(priv->netdev[interfaceTag]);
2104 #endif
2105 uf_process_rx_pending_queue(priv, queue, peer_address, 1,interfaceTag);
2107 } /* uf_resume_data_plane() */
2110 void uf_free_pending_rx_packets(unifi_priv_t *priv, int queue, CsrWifiMacAddress peer_address,u16 interfaceTag)
2112 uf_process_rx_pending_queue(priv, queue, peer_address, 0,interfaceTag);
2114 } /* uf_free_pending_rx_packets() */
2118 * ---------------------------------------------------------------------------
2119 * unifi_rx
2121 * Reformat a UniFi data received packet into a p80211 packet and
2122 * pass it up the protocol stack.
2124 * Arguments:
2125 * None.
2127 * Returns:
2128 * None.
2129 * ---------------------------------------------------------------------------
2131 static void
2132 unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
2134 u16 interfaceTag;
2135 bulk_data_desc_t *pData;
2136 const CSR_MA_PACKET_INDICATION *pkt_ind = &signal->u.MaPacketIndication;
2137 struct sk_buff *skb;
2138 CsrWifiRouterCtrlPortAction port_action;
2139 u8 dataFrameType;
2140 int proto;
2141 int queue;
2143 u8 da[ETH_ALEN], sa[ETH_ALEN];
2144 u8 toDs, fromDs, frameType, macHeaderLengthInBytes = MAC_HEADER_SIZE;
2145 u16 frameControl;
2146 netInterface_priv_t *interfacePriv;
2147 struct ethhdr ehdr;
2149 interfaceTag = (pkt_ind->VirtualInterfaceIdentifier & 0xff);
2150 interfacePriv = priv->interfacePriv[interfaceTag];
2152 /* Sanity check that the VIF refers to a sensible interface */
2153 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
2155 unifi_error(priv, "%s: MA-PACKET indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
2156 unifi_net_data_free(priv,&bulkdata->d[0]);
2157 return;
2160 /* Sanity check that the VIF refers to an allocated netdev */
2161 if (!interfacePriv->netdev_registered)
2163 unifi_error(priv, "%s: MA-PACKET indication with unallocated interfaceTag %d\n", __FUNCTION__, interfaceTag);
2164 unifi_net_data_free(priv, &bulkdata->d[0]);
2165 return;
2168 if (bulkdata->d[0].data_length == 0) {
2169 unifi_warning(priv, "%s: MA-PACKET indication with zero bulk data\n", __FUNCTION__);
2170 unifi_net_data_free(priv,&bulkdata->d[0]);
2171 return;
2175 skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
2176 skb->len = bulkdata->d[0].data_length;
2178 /* Point to the addresses */
2179 toDs = (skb->data[1] & 0x01) ? 1 : 0;
2180 fromDs = (skb->data[1] & 0x02) ? 1 : 0;
2182 memcpy(da,(skb->data+4+toDs*12),ETH_ALEN);/* Address1 or 3 */
2183 memcpy(sa,(skb->data+10+fromDs*(6+toDs*8)),ETH_ALEN); /* Address2, 3 or 4 */
2186 pData = &bulkdata->d[0];
2187 frameControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr);
2188 frameType = ((frameControl & 0x000C) >> 2);
2190 dataFrameType =((frameControl & 0x00f0) >> 4);
2191 unifi_trace(priv, UDBG6,
2192 "%s: Receive Data Frame Type %d \n", __FUNCTION__,dataFrameType);
2194 switch(dataFrameType)
2196 case QOS_DATA:
2197 case QOS_DATA_NULL:
2198 /* If both are set then the Address4 exists (only for AP) */
2199 if (fromDs && toDs)
2201 /* 6 is the size of Address4 field */
2202 macHeaderLengthInBytes += (QOS_CONTROL_HEADER_SIZE + 6);
2204 else
2206 macHeaderLengthInBytes += QOS_CONTROL_HEADER_SIZE;
2209 /* If order bit set then HT control field is the part of MAC header */
2210 if (frameControl & FRAME_CONTROL_ORDER_BIT)
2211 macHeaderLengthInBytes += HT_CONTROL_HEADER_SIZE;
2212 break;
2213 default:
2214 if (fromDs && toDs)
2215 macHeaderLengthInBytes += 6;
2218 /* Prepare the ethernet header from snap header of skb data */
2219 switch(dataFrameType)
2221 case DATA_NULL:
2222 case QOS_DATA_NULL:
2223 /* This is for only queue info fetching, EAPOL wont come as
2224 * null data so the proto is initialized as zero
2226 proto = 0x0;
2227 break;
2228 default:
2230 llc_snap_hdr_t *snap;
2231 /* Fetch a snap header to find protocol (for IPV4/IPV6 packets
2232 * the snap header fetching offset is same)
2234 snap = (llc_snap_hdr_t *) (skb->data + macHeaderLengthInBytes);
2236 /* prepare the ethernet header from the snap header & addresses */
2237 ehdr.h_proto = snap->protocol;
2238 memcpy(ehdr.h_dest, da, ETH_ALEN);
2239 memcpy(ehdr.h_source, sa, ETH_ALEN);
2241 proto = ntohs(ehdr.h_proto);
2243 unifi_trace(priv, UDBG3, "in unifi_rx protocol from snap header = 0x%x\n", proto);
2245 if ((proto != ETH_P_PAE)
2246 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
2247 && (proto != ETH_P_WAI)
2248 #endif
2250 queue = UF_CONTROLLED_PORT_Q;
2251 } else {
2252 queue = UF_UNCONTROLLED_PORT_Q;
2255 port_action = verify_port(priv, (unsigned char*)sa, queue, interfaceTag);
2256 unifi_trace(priv, UDBG3, "in unifi_rx port action is = 0x%x & queue = %x\n", port_action, queue);
2258 #ifdef CSR_SUPPORT_SME
2259 /* Notify the TA module for the Rx frame for non P2PGO and AP cases*/
2260 if((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_AP) &&
2261 (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_P2PGO))
2263 /* Remove MAC header of length(macHeaderLengthInBytes) before sampling */
2264 skb_pull(skb, macHeaderLengthInBytes);
2265 pData->os_data_ptr = skb->data;
2266 pData->data_length -= macHeaderLengthInBytes;
2268 if (pData->data_length) {
2269 unifi_ta_sample(priv->card, CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_RX,
2270 &bulkdata->d[0],
2271 sa, priv->netdev[interfaceTag]->dev_addr,
2272 jiffies_to_msecs(jiffies),
2273 pkt_ind->ReceivedRate);
2275 } else {
2277 /* AP/P2PGO specific handling here */
2278 CsrWifiRouterCtrlStaInfo_t * srcStaInfo =
2279 CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,sa,interfaceTag);
2281 /* Defensive check only; Source address is already checked in
2282 process_ma_packet_ind and we should have a valid source address here */
2284 if(srcStaInfo == NULL) {
2285 CsrWifiMacAddress peerMacAddress;
2286 /* Unknown data PDU */
2287 memcpy(peerMacAddress.a,sa,ETH_ALEN);
2288 unifi_trace(priv, UDBG1, "%s: Unexpected frame from peer = %x:%x:%x:%x:%x:%x\n", __FUNCTION__,
2289 sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]);
2290 CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress);
2291 unifi_net_data_free(priv, &bulkdata->d[0]);
2292 return;
2295 /* For AP GO mode, don't store the PDUs */
2296 if (port_action != CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
2297 /* Drop the packet and return */
2298 CsrWifiMacAddress peerMacAddress;
2299 memcpy(peerMacAddress.a,sa,ETH_ALEN);
2300 unifi_trace(priv, UDBG3, "%s: Port is not open: unexpected frame from peer = %x:%x:%x:%x:%x:%x\n",
2301 __FUNCTION__, sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]);
2303 CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress);
2304 interfacePriv->stats.rx_dropped++;
2305 unifi_net_data_free(priv, &bulkdata->d[0]);
2306 unifi_notice(priv, "%s: Dropping packet, proto=0x%04x, %s port\n", __FUNCTION__,
2307 proto, queue ? "Controlled" : "Un-controlled");
2308 return;
2311 /* Qos NULL/Data NULL are freed here and not processed further */
2312 if((dataFrameType == QOS_DATA_NULL) || (dataFrameType == DATA_NULL)){
2313 unifi_trace(priv, UDBG5, "%s: Null Frame Received and Freed\n", __FUNCTION__);
2314 unifi_net_data_free(priv, &bulkdata->d[0]);
2315 return;
2318 /* Now we have done with MAC header so proceed with the real data part*/
2319 /* This function takes care of appropriate routing for AP/P2PGO case*/
2320 /* the function hadnles following things
2321 2. Routing the PDU to appropriate location
2322 3. Error case handling
2324 if(!(uf_ap_process_data_pdu(priv, skb, &ehdr, srcStaInfo,
2325 signal,
2326 bulkdata,
2327 macHeaderLengthInBytes)))
2329 return;
2331 unifi_trace(priv, UDBG5, "unifi_rx: no specific AP handling process as normal frame, MAC Header len %d\n",macHeaderLengthInBytes);
2332 /* Remove the MAC header for subsequent conversion */
2333 skb_pull(skb, macHeaderLengthInBytes);
2334 pData->os_data_ptr = skb->data;
2335 pData->data_length -= macHeaderLengthInBytes;
2336 pData->os_net_buf_ptr = (unsigned char*)skb;
2337 pData->net_buf_length = skb->len;
2339 #endif /* CSR_SUPPORT_SME */
2342 /* Now that the MAC header is removed, null-data frames have zero length
2343 * and can be dropped
2345 if (pData->data_length == 0) {
2346 if (((frameControl & 0x00f0) >> 4) != QOS_DATA_NULL &&
2347 ((frameControl & 0x00f0) >> 4) != DATA_NULL) {
2348 unifi_trace(priv, UDBG1, "Zero length frame, but not null-data %04x\n", frameControl);
2350 unifi_net_data_free(priv, &bulkdata->d[0]);
2351 return;
2354 if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) {
2355 /* Drop the packet and return */
2356 interfacePriv->stats.rx_dropped++;
2357 unifi_net_data_free(priv, &bulkdata->d[0]);
2358 unifi_notice(priv, "%s: Dropping packet, proto=0x%04x, %s port\n",
2359 __FUNCTION__, proto, queue ? "controlled" : "uncontrolled");
2360 return;
2361 } else if ( (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK) ||
2362 (interfacePriv->connected != UnifiConnected) ) {
2364 /* Buffer the packet into the Rx queues */
2365 rx_buffered_packets_t *rx_q_item;
2366 struct list_head *rx_list;
2368 rx_q_item = kmalloc(sizeof(rx_buffered_packets_t),
2369 GFP_KERNEL);
2370 if (rx_q_item == NULL) {
2371 unifi_error(priv, "%s: Failed to allocate %d bytes for rx packet record\n",
2372 __FUNCTION__, sizeof(rx_buffered_packets_t));
2373 interfacePriv->stats.rx_dropped++;
2374 unifi_net_data_free(priv, &bulkdata->d[0]);
2375 return;
2378 INIT_LIST_HEAD(&rx_q_item->q);
2379 rx_q_item->bulkdata = *bulkdata;
2380 rx_q_item->skb = skb;
2381 rx_q_item->signal = *signal;
2382 memcpy(rx_q_item->sa.a, sa, ETH_ALEN);
2383 memcpy(rx_q_item->da.a, da, ETH_ALEN);
2384 unifi_trace(priv, UDBG2, "%s: Blocked skb=%p, bulkdata=%p\n",
2385 __FUNCTION__, rx_q_item->skb, &rx_q_item->bulkdata);
2387 if (queue == UF_CONTROLLED_PORT_Q) {
2388 rx_list = &interfacePriv->rx_controlled_list;
2389 } else {
2390 rx_list = &interfacePriv->rx_uncontrolled_list;
2393 /* Add to tail of packets queue */
2394 down(&priv->rx_q_sem);
2395 list_add_tail(&rx_q_item->q, rx_list);
2396 up(&priv->rx_q_sem);
2398 return;
2402 indicate_rx_skb(priv, interfaceTag, da, sa, skb, signal, bulkdata);
2404 } /* unifi_rx() */
2406 static void process_ma_packet_cfm(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
2408 u16 interfaceTag;
2409 const CSR_MA_PACKET_CONFIRM *pkt_cfm = &signal->u.MaPacketConfirm;
2410 netInterface_priv_t *interfacePriv;
2412 interfaceTag = (pkt_cfm->VirtualInterfaceIdentifier & 0xff);
2413 interfacePriv = priv->interfacePriv[interfaceTag];
2415 /* Sanity check that the VIF refers to a sensible interface */
2416 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
2418 unifi_error(priv, "%s: MA-PACKET confirm with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
2419 return;
2421 #ifdef CSR_SUPPORT_SME
2422 if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
2423 interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
2425 uf_process_ma_pkt_cfm_for_ap(priv,interfaceTag,pkt_cfm);
2426 } else if (interfacePriv->m4_sent && (pkt_cfm->HostTag == interfacePriv->m4_hostTag)) {
2427 /* Check if this is a confirm for EAPOL M4 frame and we need to send transmistted ind*/
2428 CsrResult result = pkt_cfm->TransmissionStatus == CSR_TX_SUCCESSFUL?CSR_RESULT_SUCCESS:CSR_RESULT_FAILURE;
2429 CsrWifiMacAddress peerMacAddress;
2430 memcpy(peerMacAddress.a, interfacePriv->m4_signal.u.MaPacketRequest.Ra.x, ETH_ALEN);
2432 unifi_trace(priv, UDBG1, "%s: Sending M4 Transmit CFM\n", __FUNCTION__);
2433 CsrWifiRouterCtrlM4TransmittedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0,
2434 interfaceTag,
2435 peerMacAddress,
2436 result);
2437 interfacePriv->m4_sent = FALSE;
2438 interfacePriv->m4_hostTag = 0xffffffff;
2440 #endif
2441 return;
2446 * ---------------------------------------------------------------------------
2447 * unifi_rx
2449 * Reformat a UniFi data received packet into a p80211 packet and
2450 * pass it up the protocol stack.
2452 * Arguments:
2453 * None.
2455 * Returns:
2456 * None.
2457 * ---------------------------------------------------------------------------
2459 static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
2461 u16 interfaceTag;
2462 bulk_data_desc_t *pData;
2463 CSR_MA_PACKET_INDICATION *pkt_ind = (CSR_MA_PACKET_INDICATION*)&signal->u.MaPacketIndication;
2464 struct sk_buff *skb;
2465 u16 frameControl;
2466 netInterface_priv_t *interfacePriv;
2467 u8 da[ETH_ALEN], sa[ETH_ALEN];
2468 u8 *bssid = NULL, *ba_addr = NULL;
2469 u8 toDs, fromDs, frameType;
2470 u8 i =0;
2472 #ifdef CSR_SUPPORT_SME
2473 u8 dataFrameType = 0;
2474 u8 powerSaveChanged = FALSE;
2475 u8 pmBit = 0;
2476 CsrWifiRouterCtrlStaInfo_t *srcStaInfo = NULL;
2477 u16 qosControl;
2479 #endif
2481 interfaceTag = (pkt_ind->VirtualInterfaceIdentifier & 0xff);
2482 interfacePriv = priv->interfacePriv[interfaceTag];
2485 /* Sanity check that the VIF refers to a sensible interface */
2486 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
2488 unifi_error(priv, "%s: MA-PACKET indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
2489 unifi_net_data_free(priv,&bulkdata->d[0]);
2490 return;
2493 /* Sanity check that the VIF refers to an allocated netdev */
2494 if (!interfacePriv->netdev_registered)
2496 unifi_error(priv, "%s: MA-PACKET indication with unallocated interfaceTag %d\n", __FUNCTION__, interfaceTag);
2497 unifi_net_data_free(priv, &bulkdata->d[0]);
2498 return;
2501 if (bulkdata->d[0].data_length == 0) {
2502 unifi_warning(priv, "%s: MA-PACKET indication with zero bulk data\n", __FUNCTION__);
2503 unifi_net_data_free(priv,&bulkdata->d[0]);
2504 return;
2506 /* For monitor mode we need to pass this indication to the registered application
2507 handle this separately*/
2508 /* MIC failure is already taken care of so no need to send the PDUs which are not successfully received in non-monitor mode*/
2509 if(pkt_ind->ReceptionStatus != CSR_RX_SUCCESS)
2511 unifi_warning(priv, "%s: MA-PACKET indication with status = %d\n",__FUNCTION__, pkt_ind->ReceptionStatus);
2512 unifi_net_data_free(priv,&bulkdata->d[0]);
2513 return;
2517 skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
2518 skb->len = bulkdata->d[0].data_length;
2520 /* Point to the addresses */
2521 toDs = (skb->data[1] & 0x01) ? 1 : 0;
2522 fromDs = (skb->data[1] & 0x02) ? 1 : 0;
2524 memcpy(da,(skb->data+4+toDs*12),ETH_ALEN);/* Address1 or 3 */
2525 memcpy(sa,(skb->data+10+fromDs*(6+toDs*8)),ETH_ALEN); /* Address2, 3 or 4 */
2527 /* Find the BSSID, which will be used to match the BA session */
2528 if (toDs && fromDs)
2530 unifi_trace(priv, UDBG6, "4 address frame - don't try to find BSSID\n");
2531 bssid = NULL;
2533 else
2535 bssid = (u8 *) (skb->data + 4 + 12 - (fromDs * 6) - (toDs * 12));
2538 pData = &bulkdata->d[0];
2539 frameControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr);
2540 frameType = ((frameControl & 0x000C) >> 2);
2542 unifi_trace(priv, UDBG3, "Rx Frame Type: %d sn: %d\n",frameType,
2543 (le16_to_cpu(*((u16*)(bulkdata->d[0].os_data_ptr + IEEE802_11_SEQUENCE_CONTROL_OFFSET))) >> 4) & 0xfff);
2544 if(frameType == IEEE802_11_FRAMETYPE_CONTROL){
2545 #ifdef CSR_SUPPORT_SME
2546 unifi_trace(priv, UDBG6, "%s: Received Control Frame\n", __FUNCTION__);
2548 if((frameControl & 0x00f0) == 0x00A0){
2549 /* This is a PS-POLL request */
2550 u8 pmBit = (frameControl & 0x1000)?0x01:0x00;
2551 unifi_trace(priv, UDBG6, "%s: Received PS-POLL Frame\n", __FUNCTION__);
2553 uf_process_ps_poll(priv,sa,da,pmBit,interfaceTag);
2555 else {
2556 unifi_warning(priv, "%s: Non PS-POLL control frame is received\n", __FUNCTION__);
2558 #endif
2559 unifi_net_data_free(priv,&bulkdata->d[0]);
2560 return;
2562 if(frameType != IEEE802_11_FRAMETYPE_DATA) {
2563 unifi_warning(priv, "%s: Non control Non Data frame is received\n",__FUNCTION__);
2564 unifi_net_data_free(priv,&bulkdata->d[0]);
2565 return;
2568 #ifdef CSR_SUPPORT_SME
2569 if((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP) ||
2570 (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO)){
2572 srcStaInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,sa,interfaceTag);
2574 if(srcStaInfo == NULL) {
2575 CsrWifiMacAddress peerMacAddress;
2576 /* Unknown data PDU */
2577 memcpy(peerMacAddress.a,sa,ETH_ALEN);
2578 unifi_trace(priv, UDBG1, "%s: Unexpected frame from peer = %x:%x:%x:%x:%x:%x\n", __FUNCTION__,
2579 sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]);
2580 CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress);
2581 unifi_net_data_free(priv, &bulkdata->d[0]);
2582 return;
2586 verify power management bit here so as to ensure host and unifi are always
2587 in sync with power management status of peer.
2589 If we do it later, it may so happen we have stored the frame in BA re-ordering
2590 buffer and hence host and unifi are out of sync for power management status
2593 pmBit = (frameControl & 0x1000)?0x01:0x00;
2594 powerSaveChanged = uf_process_pm_bit_for_peer(priv,srcStaInfo,pmBit,interfaceTag);
2596 /* Update station last activity time */
2597 srcStaInfo->activity_flag = TRUE;
2599 /* For Qos Frame if PM bit is toggled to indicate the change in power save state then it shall not be
2600 considered as Trigger Frame. Enter only if WMM STA and peer is in Power save */
2602 dataFrameType = ((frameControl & 0x00f0) >> 4);
2604 if((powerSaveChanged == FALSE)&&(srcStaInfo->wmmOrQosEnabled == TRUE)&&
2605 (srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)){
2607 if((dataFrameType == QOS_DATA) || (dataFrameType == QOS_DATA_NULL)){
2610 * QoS control field is offset from frame control by 2 (frame control)
2611 * + 2 (duration/ID) + 2 (sequence control) + 3*ETH_ALEN or 4*ETH_ALEN
2613 if((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)){
2614 qosControl= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr + 30);
2616 else{
2617 qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr + 24);
2619 unifi_trace(priv, UDBG5, "%s: Check if U-APSD operations are triggered for qosControl: 0x%x\n",__FUNCTION__,qosControl);
2620 uf_process_wmm_deliver_ac_uapsd(priv,srcStaInfo,qosControl,interfaceTag);
2625 #endif
2627 if( ((frameControl & 0x00f0) >> 4) == QOS_DATA) {
2628 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);
2629 int tID = *qos_control_ptr & IEEE802_11_QC_TID_MASK; /* using ls octet of qos control */
2630 ba_session_rx_struct *ba_session;
2631 u8 ba_session_idx = 0;
2632 /* Get the BA originator address */
2633 if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
2634 interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO){
2635 ba_addr = sa;
2636 }else{
2637 ba_addr = bssid;
2640 down(&priv->ba_mutex);
2641 for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
2642 ba_session = interfacePriv->ba_session_rx[ba_session_idx];
2643 if (ba_session){
2644 unifi_trace(priv, UDBG6, "found ba_session=0x%x ba_session_idx=%d", ba_session, ba_session_idx);
2645 if ((!memcmp(ba_session->macAddress.a, ba_addr, ETH_ALEN)) && (ba_session->tID == tID)){
2646 frame_desc_struct frame_desc;
2647 frame_desc.bulkdata = *bulkdata;
2648 frame_desc.signal = *signal;
2649 frame_desc.sn = (le16_to_cpu(*((u16*)(bulkdata->d[0].os_data_ptr + IEEE802_11_SEQUENCE_CONTROL_OFFSET))) >> 4) & 0xfff;
2650 frame_desc.active = TRUE;
2651 unifi_trace(priv, UDBG6, "%s: calling process_ba_frame (session=%d)\n", __FUNCTION__, ba_session_idx);
2652 process_ba_frame(priv, interfacePriv, ba_session, &frame_desc);
2653 up(&priv->ba_mutex);
2654 process_ba_complete(priv, interfacePriv);
2655 break;
2659 if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX){
2660 up(&priv->ba_mutex);
2661 unifi_trace(priv, UDBG6, "%s: calling process_amsdu()", __FUNCTION__);
2662 process_amsdu(priv, signal, bulkdata);
2664 } else {
2665 unifi_trace(priv, UDBG6, "calling unifi_rx()");
2666 unifi_rx(priv, signal, bulkdata);
2669 /* check if the frames in reorder buffer has aged, the check
2670 * is done after receive processing so that if the missing frame
2671 * has arrived in this receive process, then it is handled cleanly.
2673 * And also this code here takes care that timeout check is made for all
2674 * the receive indications
2676 down(&priv->ba_mutex);
2677 for (i=0; i < MAX_SUPPORTED_BA_SESSIONS_RX; i++){
2678 ba_session_rx_struct *ba_session;
2679 ba_session = interfacePriv->ba_session_rx[i];
2680 if (ba_session){
2681 check_ba_frame_age_timeout(priv, interfacePriv, ba_session);
2684 up(&priv->ba_mutex);
2685 process_ba_complete(priv, interfacePriv);
2689 * ---------------------------------------------------------------------------
2690 * uf_set_multicast_list
2692 * This function is called by the higher level stack to set
2693 * a list of multicast rx addresses.
2695 * Arguments:
2696 * dev Network Device pointer.
2698 * Returns:
2699 * None.
2701 * Notes:
2702 * ---------------------------------------------------------------------------
2705 static void
2706 uf_set_multicast_list(struct net_device *dev)
2708 netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
2709 unifi_priv_t *priv = interfacePriv->privPtr;
2711 #ifdef CSR_NATIVE_LINUX
2712 unifi_trace(priv, UDBG3, "uf_set_multicast_list unsupported\n");
2713 return;
2714 #else
2716 u8 *mc_list = interfacePriv->mc_list;
2717 struct netdev_hw_addr *mc_addr;
2718 int mc_addr_count;
2720 if (priv->init_progress != UNIFI_INIT_COMPLETED) {
2721 return;
2724 mc_addr_count = netdev_mc_count(dev);
2726 unifi_trace(priv, UDBG3,
2727 "uf_set_multicast_list (count=%d)\n", mc_addr_count);
2730 /* Not enough space? */
2731 if (mc_addr_count > UNIFI_MAX_MULTICAST_ADDRESSES) {
2732 return;
2735 /* Store the list to be processed by the work item. */
2736 interfacePriv->mc_list_count = mc_addr_count;
2737 netdev_hw_addr_list_for_each(mc_addr, &dev->mc) {
2738 memcpy(mc_list, mc_addr->addr, ETH_ALEN);
2739 mc_list += ETH_ALEN;
2742 /* Send a message to the workqueue */
2743 queue_work(priv->unifi_workqueue, &priv->multicast_list_task);
2744 #endif
2746 } /* uf_set_multicast_list() */
2749 * ---------------------------------------------------------------------------
2750 * netdev_mlme_event_handler
2752 * Callback function to be used as the udi_event_callback when registering
2753 * as a netdev client.
2754 * To use it, a client specifies this function as the udi_event_callback
2755 * to ul_register_client(). The signal dispatcher in
2756 * unifi_receive_event() will call this function to deliver a signal.
2758 * Arguments:
2759 * pcli Pointer to the client instance.
2760 * signal Pointer to the received signal.
2761 * signal_len Size of the signal structure in bytes.
2762 * bulkdata Pointer to structure containing any associated bulk data.
2763 * dir Direction of the signal. Zero means from host,
2764 * non-zero means to host.
2766 * Returns:
2767 * None.
2768 * ---------------------------------------------------------------------------
2770 static void
2771 netdev_mlme_event_handler(ul_client_t *pcli, const u8 *sig_packed, int sig_len,
2772 const bulk_data_param_t *bulkdata_o, int dir)
2774 CSR_SIGNAL signal;
2775 unifi_priv_t *priv = uf_find_instance(pcli->instance);
2776 int id, r;
2777 bulk_data_param_t bulkdata;
2779 /* Just a sanity check */
2780 if (sig_packed == NULL) {
2781 return;
2785 * This copy is to silence a compiler warning about discarding the
2786 * const qualifier.
2788 bulkdata = *bulkdata_o;
2790 /* Get the unpacked signal */
2791 r = read_unpack_signal(sig_packed, &signal);
2792 if (r) {
2794 * The CSR_MLME_CONNECTED_INDICATION_ID has a receiverID=0 so will
2795 * fall through this case. It is safe to ignore this signal.
2797 unifi_trace(priv, UDBG1,
2798 "Netdev - Received unknown signal 0x%.4X.\n",
2799 CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sig_packed));
2800 return;
2803 id = signal.SignalPrimitiveHeader.SignalId;
2804 unifi_trace(priv, UDBG3, "Netdev - Process signal 0x%.4X\n", id);
2807 * Take the appropriate action for the signal.
2809 switch (id) {
2810 case CSR_MA_PACKET_ERROR_INDICATION_ID:
2811 process_ma_packet_error_ind(priv, &signal, &bulkdata);
2812 break;
2813 case CSR_MA_PACKET_INDICATION_ID:
2814 process_ma_packet_ind(priv, &signal, &bulkdata);
2815 break;
2816 case CSR_MA_PACKET_CONFIRM_ID:
2817 process_ma_packet_cfm(priv, &signal, &bulkdata);
2818 break;
2819 #ifdef CSR_SUPPORT_SME
2820 case CSR_MLME_SET_TIM_CONFIRM_ID:
2821 /* Handle TIM confirms from FW & set the station record's TIM state appropriately,
2822 * In case of failures, tries with max_retransmit limit
2824 uf_handle_tim_cfm(priv, &signal.u.MlmeSetTimConfirm, signal.SignalPrimitiveHeader.ReceiverProcessId);
2825 break;
2826 #endif
2827 case CSR_DEBUG_STRING_INDICATION_ID:
2828 debug_string_indication(priv, bulkdata.d[0].os_data_ptr, bulkdata.d[0].data_length);
2829 break;
2831 case CSR_DEBUG_WORD16_INDICATION_ID:
2832 debug_word16_indication(priv, &signal);
2833 break;
2835 case CSR_DEBUG_GENERIC_CONFIRM_ID:
2836 case CSR_DEBUG_GENERIC_INDICATION_ID:
2837 debug_generic_indication(priv, &signal);
2838 break;
2839 default:
2840 break;
2843 } /* netdev_mlme_event_handler() */
2847 * ---------------------------------------------------------------------------
2848 * uf_net_get_name
2850 * Retrieve the name (e.g. eth1) associated with this network device
2852 * Arguments:
2853 * dev Pointer to the network device.
2854 * name Buffer to write name
2855 * len Size of buffer in bytes
2857 * Returns:
2858 * None
2860 * Notes:
2861 * ---------------------------------------------------------------------------
2863 void uf_net_get_name(struct net_device *dev, char *name, int len)
2865 *name = '\0';
2866 if (dev) {
2867 strlcpy(name, dev->name, (len > IFNAMSIZ) ? IFNAMSIZ : len);
2870 } /* uf_net_get_name */
2872 #ifdef CSR_SUPPORT_WEXT
2875 * ---------------------------------------------------------------------------
2876 * uf_netdev_event
2878 * Callback function to handle netdev state changes
2880 * Arguments:
2881 * notif Pointer to a notifier_block.
2882 * event Event prompting notification
2883 * ptr net_device pointer
2885 * Returns:
2886 * None
2888 * Notes:
2889 * The event handler is global, and may occur on non-UniFi netdevs.
2890 * ---------------------------------------------------------------------------
2892 static int
2893 uf_netdev_event(struct notifier_block *notif, unsigned long event, void* ptr) {
2894 struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
2895 netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(netdev);
2896 unifi_priv_t *priv = NULL;
2897 static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
2899 /* Check that the event is for a UniFi netdev. If it's not, the netdev_priv
2900 * structure is not safe to use.
2902 if (uf_find_netdev_priv(interfacePriv) == -1) {
2903 unifi_trace(NULL, UDBG1, "uf_netdev_event: ignore e=%d, ptr=%p, priv=%p %s\n",
2904 event, ptr, interfacePriv, netdev->name);
2905 return 0;
2908 switch(event) {
2909 case NETDEV_CHANGE:
2910 priv = interfacePriv->privPtr;
2911 unifi_trace(priv, UDBG1, "NETDEV_CHANGE: %p %s %s waiting for it\n",
2912 ptr,
2913 netdev->name,
2914 interfacePriv->wait_netdev_change ? "" : "not");
2916 if (interfacePriv->wait_netdev_change) {
2917 netif_tx_wake_all_queues(priv->netdev[interfacePriv->InterfaceTag]);
2918 interfacePriv->connected = UnifiConnected;
2919 interfacePriv->wait_netdev_change = FALSE;
2920 /* Note: passing the broadcast address here will allow anyone to attempt to join our adhoc network */
2921 uf_process_rx_pending_queue(priv, UF_UNCONTROLLED_PORT_Q, broadcast_address, 1,interfacePriv->InterfaceTag);
2922 uf_process_rx_pending_queue(priv, UF_CONTROLLED_PORT_Q, broadcast_address, 1,interfacePriv->InterfaceTag);
2924 break;
2926 default:
2927 break;
2929 return 0;
2932 static struct notifier_block uf_netdev_notifier = {
2933 .notifier_call = uf_netdev_event,
2935 #endif /* CSR_SUPPORT_WEXT */
2938 static void
2939 process_amsdu(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
2941 u32 offset;
2942 u32 length = bulkdata->d[0].data_length;
2943 u32 subframe_length, subframe_body_length, dot11_hdr_size;
2944 u8 *ptr;
2945 bulk_data_param_t subframe_bulkdata;
2946 u8 *dot11_hdr_ptr = (u8*)bulkdata->d[0].os_data_ptr;
2947 CsrResult csrResult;
2948 u16 frameControl;
2949 u8 *qos_control_ptr;
2951 frameControl = le16_to_cpu(*((u16*)dot11_hdr_ptr));
2952 qos_control_ptr = dot11_hdr_ptr + (((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK))?30: 24);
2953 if(!(*qos_control_ptr & IEEE802_11_QC_A_MSDU_PRESENT)) {
2954 unifi_trace(priv, UDBG6, "%s: calling unifi_rx()", __FUNCTION__);
2955 unifi_rx(priv, signal, bulkdata);
2956 return;
2958 *qos_control_ptr &= ~(IEEE802_11_QC_A_MSDU_PRESENT);
2960 ptr = qos_control_ptr + 2;
2961 offset = dot11_hdr_size = ptr - dot11_hdr_ptr;
2963 while(length > (offset + sizeof(struct ethhdr) + sizeof(llc_snap_hdr_t))) {
2964 subframe_body_length = ntohs(((struct ethhdr*)ptr)->h_proto);
2965 if(subframe_body_length > IEEE802_11_MAX_DATA_LEN) {
2966 unifi_error(priv, "%s: bad subframe_body_length = %d\n", __FUNCTION__, subframe_body_length);
2967 break;
2969 subframe_length = sizeof(struct ethhdr) + subframe_body_length;
2970 memset(&subframe_bulkdata, 0, sizeof(bulk_data_param_t));
2972 csrResult = unifi_net_data_malloc(priv, &subframe_bulkdata.d[0], dot11_hdr_size + subframe_body_length);
2974 if (csrResult != CSR_RESULT_SUCCESS) {
2975 unifi_error(priv, "%s: unifi_net_data_malloc failed\n", __FUNCTION__);
2976 break;
2979 memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr, dot11_hdr_ptr, dot11_hdr_size);
2982 /* When to DS=0 and from DS=0, address 3 will already have BSSID so no need to re-program */
2983 if ((frameControl & IEEE802_11_FC_TO_DS_MASK) && !(frameControl & IEEE802_11_FC_FROM_DS_MASK)){
2984 memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr + IEEE802_11_ADDR3_OFFSET, ((struct ethhdr*)ptr)->h_dest, ETH_ALEN);
2986 else if (!(frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)){
2987 memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr + IEEE802_11_ADDR3_OFFSET,
2988 ((struct ethhdr*)ptr)->h_source,
2989 ETH_ALEN);
2992 memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr + dot11_hdr_size,
2993 ptr + sizeof(struct ethhdr),
2994 subframe_body_length);
2995 unifi_trace(priv, UDBG6, "%s: calling unifi_rx. length = %d subframe_length = %d\n", __FUNCTION__, length, subframe_length);
2996 unifi_rx(priv, signal, &subframe_bulkdata);
2998 subframe_length = (subframe_length + 3)&(~0x3);
2999 ptr += subframe_length;
3000 offset += subframe_length;
3002 unifi_net_data_free(priv, &bulkdata->d[0]);
3006 #define SN_TO_INDEX(__ba_session, __sn) (((__sn - __ba_session->start_sn) & 0xFFF) % __ba_session->wind_size)
3009 #define ADVANCE_EXPECTED_SN(__ba_session) \
3011 __ba_session->expected_sn++; \
3012 __ba_session->expected_sn &= 0xFFF; \
3015 #define FREE_BUFFER_SLOT(__ba_session, __index) \
3017 __ba_session->occupied_slots--; \
3018 __ba_session->buffer[__index].active = FALSE; \
3019 ADVANCE_EXPECTED_SN(__ba_session); \
3022 static void add_frame_to_ba_complete(unifi_priv_t *priv,
3023 netInterface_priv_t *interfacePriv,
3024 frame_desc_struct *frame_desc)
3026 interfacePriv->ba_complete[interfacePriv->ba_complete_index] = *frame_desc;
3027 interfacePriv->ba_complete_index++;
3031 static void update_expected_sn(unifi_priv_t *priv,
3032 netInterface_priv_t *interfacePriv,
3033 ba_session_rx_struct *ba_session,
3034 u16 sn)
3036 int i, j;
3037 u16 gap;
3039 gap = (sn - ba_session->expected_sn) & 0xFFF;
3040 unifi_trace(priv, UDBG6, "%s: process the frames up to new_expected_sn = %d gap = %d\n", __FUNCTION__, sn, gap);
3041 for(j = 0; j < gap && j < ba_session->wind_size; j++) {
3042 i = SN_TO_INDEX(ba_session, ba_session->expected_sn);
3043 unifi_trace(priv, UDBG6, "%s: process the slot index = %d\n", __FUNCTION__, i);
3044 if(ba_session->buffer[i].active) {
3045 add_frame_to_ba_complete(priv, interfacePriv, &ba_session->buffer[i]);
3046 unifi_trace(priv, UDBG6, "%s: process the frame at index = %d expected_sn = %d\n", __FUNCTION__, i, ba_session->expected_sn);
3047 FREE_BUFFER_SLOT(ba_session, i);
3048 } else {
3049 unifi_trace(priv, UDBG6, "%s: empty slot at index = %d\n", __FUNCTION__, i);
3050 ADVANCE_EXPECTED_SN(ba_session);
3053 ba_session->expected_sn = sn;
3057 static void complete_ready_sequence(unifi_priv_t *priv,
3058 netInterface_priv_t *interfacePriv,
3059 ba_session_rx_struct *ba_session)
3061 int i;
3063 i = SN_TO_INDEX(ba_session, ba_session->expected_sn);
3064 while (ba_session->buffer[i].active) {
3065 add_frame_to_ba_complete(priv, interfacePriv, &ba_session->buffer[i]);
3066 unifi_trace(priv, UDBG6, "%s: completed stored frame(expected_sn=%d) at i = %d\n", __FUNCTION__, ba_session->expected_sn, i);
3067 FREE_BUFFER_SLOT(ba_session, i);
3068 i = SN_TO_INDEX(ba_session, ba_session->expected_sn);
3073 void scroll_ba_window(unifi_priv_t *priv,
3074 netInterface_priv_t *interfacePriv,
3075 ba_session_rx_struct *ba_session,
3076 u16 sn)
3078 if(((sn - ba_session->expected_sn) & 0xFFF) <= 2048) {
3079 update_expected_sn(priv, interfacePriv, ba_session, sn);
3080 complete_ready_sequence(priv, interfacePriv, ba_session);
3085 static int consume_frame_or_get_buffer_index(unifi_priv_t *priv,
3086 netInterface_priv_t *interfacePriv,
3087 ba_session_rx_struct *ba_session,
3088 u16 sn,
3089 frame_desc_struct *frame_desc) {
3090 int i;
3091 u16 sn_temp;
3093 if(((sn - ba_session->expected_sn) & 0xFFF) <= 2048) {
3095 /* once we are in BA window, set the flag for BA trigger */
3096 if(!ba_session->trigger_ba_after_ssn){
3097 ba_session->trigger_ba_after_ssn = TRUE;
3100 sn_temp = ba_session->expected_sn + ba_session->wind_size;
3101 unifi_trace(priv, UDBG6, "%s: new frame: sn=%d\n", __FUNCTION__, sn);
3102 if(!(((sn - sn_temp) & 0xFFF) > 2048)) {
3103 u16 new_expected_sn;
3104 unifi_trace(priv, UDBG6, "%s: frame is out of window\n", __FUNCTION__);
3105 sn_temp = (sn - ba_session->wind_size) & 0xFFF;
3106 new_expected_sn = (sn_temp + 1) & 0xFFF;
3107 update_expected_sn(priv, interfacePriv, ba_session, new_expected_sn);
3109 i = -1;
3110 if (sn == ba_session->expected_sn) {
3111 unifi_trace(priv, UDBG6, "%s: sn = ba_session->expected_sn = %d\n", __FUNCTION__, sn);
3112 ADVANCE_EXPECTED_SN(ba_session);
3113 add_frame_to_ba_complete(priv, interfacePriv, frame_desc);
3114 } else {
3115 i = SN_TO_INDEX(ba_session, sn);
3116 unifi_trace(priv, UDBG6, "%s: sn(%d) != ba_session->expected_sn(%d), i = %d\n", __FUNCTION__, sn, ba_session->expected_sn, i);
3117 if (ba_session->buffer[i].active) {
3118 unifi_trace(priv, UDBG6, "%s: free frame at i = %d\n", __FUNCTION__, i);
3119 i = -1;
3120 unifi_net_data_free(priv, &frame_desc->bulkdata.d[0]);
3123 } else {
3124 i = -1;
3125 if(!ba_session->trigger_ba_after_ssn){
3126 unifi_trace(priv, UDBG6, "%s: frame before ssn, pass it up: sn=%d\n", __FUNCTION__, sn);
3127 add_frame_to_ba_complete(priv, interfacePriv, frame_desc);
3128 }else{
3129 unifi_trace(priv, UDBG6, "%s: old frame, drop: sn=%d, expected_sn=%d\n", __FUNCTION__, sn, ba_session->expected_sn);
3130 unifi_net_data_free(priv, &frame_desc->bulkdata.d[0]);
3133 return i;
3138 static void process_ba_frame(unifi_priv_t *priv,
3139 netInterface_priv_t *interfacePriv,
3140 ba_session_rx_struct *ba_session,
3141 frame_desc_struct *frame_desc)
3143 int i;
3144 u16 sn = frame_desc->sn;
3146 if (ba_session->timeout) {
3147 mod_timer(&ba_session->timer, (jiffies + usecs_to_jiffies((ba_session->timeout) * 1024)));
3149 unifi_trace(priv, UDBG6, "%s: got frame(sn=%d)\n", __FUNCTION__, sn);
3151 i = consume_frame_or_get_buffer_index(priv, interfacePriv, ba_session, sn, frame_desc);
3152 if(i >= 0) {
3153 unifi_trace(priv, UDBG6, "%s: store frame(sn=%d) at i = %d\n", __FUNCTION__, sn, i);
3154 ba_session->buffer[i] = *frame_desc;
3155 ba_session->buffer[i].recv_time = CsrTimeGet(NULL);
3156 ba_session->occupied_slots++;
3157 } else {
3158 unifi_trace(priv, UDBG6, "%s: frame consumed - sn = %d\n", __FUNCTION__, sn);
3160 complete_ready_sequence(priv, interfacePriv, ba_session);
3164 static void process_ba_complete(unifi_priv_t *priv, netInterface_priv_t *interfacePriv)
3166 frame_desc_struct *frame_desc;
3167 u8 i;
3169 for(i = 0; i < interfacePriv->ba_complete_index; i++) {
3170 frame_desc = &interfacePriv->ba_complete[i];
3171 unifi_trace(priv, UDBG6, "%s: calling process_amsdu()\n", __FUNCTION__);
3172 process_amsdu(priv, &frame_desc->signal, &frame_desc->bulkdata);
3174 interfacePriv->ba_complete_index = 0;
3179 /* Check if the frames in BA reoder buffer has aged and
3180 * if so release the frames to upper processes and move
3181 * the window
3183 static void check_ba_frame_age_timeout( unifi_priv_t *priv,
3184 netInterface_priv_t *interfacePriv,
3185 ba_session_rx_struct *ba_session)
3187 u32 now;
3188 u32 age;
3189 u8 i, j;
3190 u16 sn_temp;
3192 /* gap is started at 1 because we have buffered frames and
3193 * hence a minimum gap of 1 exists
3195 u8 gap=1;
3197 now = CsrTimeGet(NULL);
3199 if (ba_session->occupied_slots)
3201 /* expected sequence has not arrived so start searching from next
3202 * sequence number until a frame is available and determine the gap.
3203 * Check if the frame available has timedout, if so advance the
3204 * expected sequence number and release the frames
3206 sn_temp = (ba_session->expected_sn + 1) & 0xFFF;
3208 for(j = 0; j < ba_session->wind_size; j++)
3210 i = SN_TO_INDEX(ba_session, sn_temp);
3212 if(ba_session->buffer[i].active)
3214 unifi_trace(priv, UDBG6, "check age at slot index = %d sn = %d recv_time = %u now = %u\n",
3216 ba_session->buffer[i].sn,
3217 ba_session->buffer[i].recv_time,
3218 now);
3220 if (ba_session->buffer[i].recv_time > now)
3222 /* timer wrap */
3223 age = CsrTimeAdd((u32)CsrTimeSub(CSR_SCHED_TIME_MAX, ba_session->buffer[i].recv_time), now);
3225 else
3227 age = (u32)CsrTimeSub(now, ba_session->buffer[i].recv_time);
3230 if (age >= CSR_WIFI_BA_MPDU_FRAME_AGE_TIMEOUT)
3232 unifi_trace(priv, UDBG2, "release the frame at index = %d gap = %d expected_sn = %d sn = %d\n",
3234 gap,
3235 ba_session->expected_sn,
3236 ba_session->buffer[i].sn);
3238 /* if it has timedout don't wait for missing frames, move the window */
3239 while (gap--)
3241 ADVANCE_EXPECTED_SN(ba_session);
3243 add_frame_to_ba_complete(priv, interfacePriv, &ba_session->buffer[i]);
3244 FREE_BUFFER_SLOT(ba_session, i);
3245 complete_ready_sequence(priv, interfacePriv, ba_session);
3247 break;
3250 else
3252 /* advance temp sequence number and frame gap */
3253 sn_temp = (sn_temp + 1) & 0xFFF;
3254 gap++;
3261 static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
3263 u16 interfaceTag;
3264 const CSR_MA_PACKET_ERROR_INDICATION *pkt_err_ind = &signal->u.MaPacketErrorIndication;
3265 netInterface_priv_t *interfacePriv;
3266 ba_session_rx_struct *ba_session;
3267 u8 ba_session_idx = 0;
3268 CSR_PRIORITY UserPriority;
3269 CSR_SEQUENCE_NUMBER sn;
3271 interfaceTag = (pkt_err_ind->VirtualInterfaceIdentifier & 0xff);
3274 /* Sanity check that the VIF refers to a sensible interface */
3275 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
3277 unifi_error(priv, "%s: MaPacketErrorIndication indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
3278 return;
3281 interfacePriv = priv->interfacePriv[interfaceTag];
3282 UserPriority = pkt_err_ind->UserPriority;
3283 if(UserPriority > 15) {
3284 unifi_error(priv, "%s: MaPacketErrorIndication indication with bad UserPriority=%d\n", __FUNCTION__, UserPriority);
3286 sn = pkt_err_ind->SequenceNumber;
3288 down(&priv->ba_mutex);
3289 /* To find the right ba_session loop through the BA sessions, compare MAC address and tID */
3290 for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
3291 ba_session = interfacePriv->ba_session_rx[ba_session_idx];
3292 if (ba_session){
3293 if ((!memcmp(ba_session->macAddress.a, pkt_err_ind->PeerQstaAddress.x, ETH_ALEN)) && (ba_session->tID == UserPriority)){
3294 if (ba_session->timeout) {
3295 mod_timer(&ba_session->timer, (jiffies + usecs_to_jiffies((ba_session->timeout) * 1024)));
3297 scroll_ba_window(priv, interfacePriv, ba_session, sn);
3298 break;
3303 up(&priv->ba_mutex);
3304 process_ba_complete(priv, interfacePriv);