]> Pileus Git - ~andy/linux/blob - drivers/staging/csr/sme_sys.c
Merge branch 'writeback-for-next' of git://git.kernel.org/pub/scm/linux/kernel/git...
[~andy/linux] / drivers / staging / csr / sme_sys.c
1 /*
2  * ---------------------------------------------------------------------------
3  * FILE:     sme_sys.c
4  *
5  * PURPOSE:
6  *      Driver specific implementation of the SME SYS SAP.
7  *      It is part of the porting exercise.
8  *
9  * Copyright (C) 2008-2011 by Cambridge Silicon Radio Ltd.
10  *
11  * Refer to LICENSE.txt included with this source code for details on
12  * the license terms.
13  *
14  * ---------------------------------------------------------------------------
15  */
16
17 #include <linux/version.h>
18 #include "csr_wifi_hip_unifiversion.h"
19 #include "unifi_priv.h"
20 #include "csr_wifi_hip_conversions.h"
21 #ifdef CSR_SUPPORT_WEXT_AP
22 #include "csr_wifi_sme_sef.h"
23 #endif
24
25 /*
26  * This file implements the SME SYS API and contains the following functions:
27  * CsrWifiRouterCtrlMediaStatusReqHandler()
28  * CsrWifiRouterCtrlHipReqHandler()
29  * CsrWifiRouterCtrlPortConfigureReqHandler()
30  * CsrWifiRouterCtrlWifiOnReqHandler()
31  * CsrWifiRouterCtrlWifiOffReqHandler()
32  * CsrWifiRouterCtrlSuspendResHandler()
33  * CsrWifiRouterCtrlResumeResHandler()
34  * CsrWifiRouterCtrlQosControlReqHandler()
35  * CsrWifiRouterCtrlConfigurePowerModeReqHandler()
36  * CsrWifiRouterCtrlWifiOnResHandler()
37  * CsrWifiRouterCtrlWifiOffRspHandler()
38  * CsrWifiRouterCtrlMulticastAddressResHandler()
39  * CsrWifiRouterCtrlTrafficConfigReqHandler()
40  * CsrWifiRouterCtrlTrafficClassificationReqHandler()
41  * CsrWifiRouterCtrlTclasAddReqHandler()
42  * CsrWifiRouterCtrlTclasDelReqHandler()
43  * CsrWifiRouterCtrlSetModeReqHandler()
44  * CsrWifiRouterCtrlWapiMulticastFilterReqHandler()
45  * CsrWifiRouterCtrlWapiUnicastFilterReqHandler()
46  * CsrWifiRouterCtrlWapiUnicastTxPktReqHandler()
47  * CsrWifiRouterCtrlWapiRxPktReqHandler()
48  * CsrWifiRouterCtrlWapiFilterReqHandler()
49  */
50
51 #ifdef CSR_SUPPORT_SME
52 static void check_inactivity_timer_expire_func(unsigned long data);
53 void uf_send_disconnected_ind_wq(struct work_struct *work);
54 #endif
55
56 void send_auto_ma_packet_confirm(unifi_priv_t *priv,
57                                  netInterface_priv_t *interfacePriv,
58                                  struct list_head *buffered_frames_list)
59 {
60     tx_buffered_packets_t *buffered_frame_item = NULL;
61     struct list_head *listHead;
62     struct list_head *placeHolder;
63     int client_id;
64
65     CSR_SIGNAL unpacked_signal;
66     u8 sigbuf[UNIFI_PACKED_SIGBUF_SIZE];
67     u16 packed_siglen;
68
69
70     list_for_each_safe(listHead, placeHolder, buffered_frames_list)
71     {
72         buffered_frame_item = list_entry(listHead, tx_buffered_packets_t, q);
73
74         if(!buffered_frame_item) {
75             unifi_error(priv, "Entry should exist, otherwise it is a (BUG)\n");
76             continue;
77         }
78
79         if ((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_NONE) &&
80             (priv->wifi_on_state == wifi_on_done))
81         {
82
83             unifi_warning(priv, "Send MA_PACKET_CONFIRM to SenderProcessId = %x for (HostTag = %x TransmissionControl = %x)\n",
84                                  (buffered_frame_item->leSenderProcessId),
85                                  buffered_frame_item->hostTag,
86                                  buffered_frame_item->transmissionControl);
87
88             client_id = buffered_frame_item->leSenderProcessId & 0xFF00;
89
90             if (client_id == priv->sme_cli->sender_id)
91             {
92                 /* construct a MA-PACKET.confirm message for SME */
93                 memset(&unpacked_signal, 0, sizeof(unpacked_signal));
94                 unpacked_signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_CONFIRM_ID;
95                 unpacked_signal.SignalPrimitiveHeader.ReceiverProcessId = buffered_frame_item->leSenderProcessId;
96                 unpacked_signal.SignalPrimitiveHeader.SenderProcessId = CSR_WIFI_ROUTER_IFACEQUEUE;
97
98                 unpacked_signal.u.MaPacketConfirm.VirtualInterfaceIdentifier = uf_get_vif_identifier(interfacePriv->interfaceMode,
99                                                                                                      interfacePriv->InterfaceTag);
100                 unpacked_signal.u.MaPacketConfirm.TransmissionStatus = CSR_RESULT_FAILURE;
101                 unpacked_signal.u.MaPacketConfirm.RetryCount = 0;
102                 unpacked_signal.u.MaPacketConfirm.Rate = buffered_frame_item->rate;
103                 unpacked_signal.u.MaPacketConfirm.HostTag = buffered_frame_item->hostTag;
104
105                 write_pack(&unpacked_signal, sigbuf, &packed_siglen);
106                 unifi_warning(priv, "MA_PACKET_CONFIRM for SME (0x%x, 0x%x, 0x%x, 0x%x)\n",
107                                          unpacked_signal.SignalPrimitiveHeader.ReceiverProcessId,
108                                          unpacked_signal.SignalPrimitiveHeader.SenderProcessId,
109                                          unpacked_signal.u.MaPacketConfirm.VirtualInterfaceIdentifier,
110                                          unpacked_signal.u.MaPacketConfirm.HostTag);
111
112                 CsrWifiRouterCtrlHipIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,
113                                             packed_siglen,
114                                             (u8 *)sigbuf,
115                                             0, NULL,
116                                             0, NULL);
117             }
118             else if((buffered_frame_item->hostTag & 0x80000000))
119             {
120                 /* construct a MA-PACKET.confirm message for NME */
121                 unifi_warning(priv, "MA_PACKET_CONFIRM for NME (0x%x, 0x%x, 0x%x, 0x%x)\n",
122                                     buffered_frame_item->leSenderProcessId,
123                                     buffered_frame_item->interfaceTag,
124                                     buffered_frame_item->transmissionControl,
125                                     (buffered_frame_item->hostTag & 0x3FFFFFFF));
126
127                 CsrWifiRouterMaPacketCfmSend((buffered_frame_item->leSenderProcessId & 0xFF),
128                                             buffered_frame_item->interfaceTag,
129                                             CSR_RESULT_FAILURE,
130                                             (buffered_frame_item->hostTag & 0x3FFFFFFF),
131                                             buffered_frame_item->rate);
132
133             }
134             else
135             {
136                 unifi_warning(priv, "Buffered packet dropped without sending a confirm\n");
137             }
138
139         }
140
141         list_del(listHead);
142         kfree(buffered_frame_item);
143         buffered_frame_item = NULL;
144     }
145 }
146
147 void CsrWifiRouterCtrlMediaStatusReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
148 {
149     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
150     CsrWifiRouterCtrlMediaStatusReq* req = (CsrWifiRouterCtrlMediaStatusReq*)msg;
151     netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
152     unsigned long flags;
153
154     if (priv->smepriv == NULL) {
155         unifi_error(priv, "CsrWifiRouterCtrlMediaStatusReqHandler: invalid smepriv\n");
156         return;
157     }
158     if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
159         unifi_error(priv, "CsrWifiRouterCtrlMediaStatusReqHandler: invalid interfaceTag\n");
160         return;
161     }
162     unifi_trace(priv, UDBG3, "CsrWifiRouterCtrlMediaStatusReqHandler: Mode = %d req->mediaStatus = %d\n",interfacePriv->interfaceMode,req->mediaStatus);
163     if (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_AMP) {
164         bulk_data_desc_t bulk_data;
165
166         bulk_data.data_length = 0;
167
168         spin_lock_irqsave(&priv->m4_lock, flags);
169         if (interfacePriv->m4_bulk_data.data_length > 0) {
170             bulk_data = interfacePriv->m4_bulk_data;
171             interfacePriv->m4_bulk_data.net_buf_length = 0;
172             interfacePriv->m4_bulk_data.data_length = 0;
173             interfacePriv->m4_bulk_data.os_data_ptr = interfacePriv->m4_bulk_data.os_net_buf_ptr = NULL;
174         }
175         spin_unlock_irqrestore(&priv->m4_lock, flags);
176
177         if (bulk_data.data_length != 0) {
178             unifi_trace(priv, UDBG5, "CsrWifiRouterCtrlMediaStatusReqHandler: free M4\n");
179             unifi_net_data_free(priv, &bulk_data);
180         }
181
182         if ((req->mediaStatus == CSR_WIFI_SME_MEDIA_STATUS_CONNECTED) &&
183             (interfacePriv->connected != UnifiConnected)) {
184
185             switch(interfacePriv->interfaceMode){
186                 case CSR_WIFI_ROUTER_CTRL_MODE_AP:
187                 case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
188                     interfacePriv->connected = UnifiConnected;
189                     netif_carrier_on(priv->netdev[req->interfaceTag]);
190 #ifdef CSR_SUPPORT_WEXT
191                     wext_send_started_event(priv);
192 #endif
193                     unifi_trace(priv, UDBG1,
194                                 "CsrWifiRouterCtrlMediaStatusReqHandler: AP/P2PGO setting netif_carrier_on\n");
195                     netif_tx_wake_all_queues(priv->netdev[req->interfaceTag]);
196                     break;
197
198                 default:
199 #ifdef CSR_SUPPORT_WEXT
200                 /* In the WEXT builds (sme and native), the userspace is not ready
201                  * to process any EAPOL or WAPI packets, until it has been informed
202                  * of the NETDEV_CHANGE.
203                  */
204                 if (interfacePriv->netdev_callback_registered && (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI)) {
205                     interfacePriv->wait_netdev_change = TRUE;
206                     unifi_trace(priv, UDBG1,
207                                 "CsrWifiRouterCtrlMediaStatusReqHandler: waiting for NETDEV_CHANGE\n");
208                     /*
209                      * Carrier can go to on, only after wait_netdev_change is set to TRUE.
210                      * Otherwise there can be a race in uf_netdev_event().
211                      */
212                     netif_carrier_on(priv->netdev[req->interfaceTag]);
213                     unifi_trace(priv, UDBG1,
214                                 "CsrWifiRouterCtrlMediaStatusReqHandler: STA/P2PCLI setting netif_carrier_on\n");
215                 }
216                 else
217 #endif
218                 {
219                     /* In the NME build, the userspace does not wait for the NETDEV_CHANGE
220                      * so it is ready to process all the EAPOL or WAPI packets.
221                      * At this point, we enable all the Tx queues, and we indicate any packets
222                      * that are queued (and the respective port is opened).
223                      */
224                     static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
225                     interfacePriv->connected = UnifiConnected;
226                     unifi_trace(priv, UDBG1,
227                                 "CsrWifiRouterMediaStatusReqHandler: UnifiConnected && netif_carrier_on\n");
228                     netif_carrier_on(priv->netdev[req->interfaceTag]);
229                     netif_tx_wake_all_queues(priv->netdev[req->interfaceTag]);
230                     uf_process_rx_pending_queue(priv, UF_UNCONTROLLED_PORT_Q, broadcast_address, 1, interfacePriv->InterfaceTag);
231                     uf_process_rx_pending_queue(priv, UF_CONTROLLED_PORT_Q, broadcast_address, 1, interfacePriv->InterfaceTag);
232                 }
233                 break;
234             }
235         }
236
237         if (req->mediaStatus == CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED) {
238 #ifdef CSR_SUPPORT_WEXT
239             unifi_trace(priv, UDBG1,
240                         "CsrWifiRouterMediaStatusReqHandler: cancel waiting for NETDEV_CHANGE\n");
241             interfacePriv->wait_netdev_change = FALSE;
242 #endif
243             unifi_trace(priv, UDBG1,
244                         "CsrWifiRouterMediaStatusReqHandler: setting netif_carrier_off\n");
245             netif_carrier_off(priv->netdev[req->interfaceTag]);
246 #ifdef CSR_SUPPORT_WEXT
247             switch(interfacePriv->interfaceMode){
248                 case CSR_WIFI_ROUTER_CTRL_MODE_AP:
249                 case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
250                      wext_send_started_event(priv);
251                      break;
252                 default:
253                      break;
254             }
255 #endif
256             interfacePriv->connected = UnifiNotConnected;
257         }
258     } else {
259         /* For AMP, just update the L2 connected flag */
260         if (req->mediaStatus == CSR_WIFI_SME_MEDIA_STATUS_CONNECTED) {
261             unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlMediaStatusReqHandler: AMP connected\n");
262             interfacePriv->connected = UnifiConnected;
263         } else {
264             unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlMediaStatusReqHandler: AMP disconnected\n");
265             interfacePriv->connected = UnifiNotConnected;
266         }
267     }
268 }
269
270
271 void CsrWifiRouterCtrlHipReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
272 {
273     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
274     CsrWifiRouterCtrlHipReq* hipreq = (CsrWifiRouterCtrlHipReq*)msg;
275     bulk_data_param_t bulkdata;
276     u8 *signal_ptr;
277     int signal_length;
278     int r=0;
279     void *dest;
280     CsrResult csrResult;
281     CSR_SIGNAL *signal;
282     u16 interfaceTag = 0;
283     CSR_MA_PACKET_REQUEST *req;
284     netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
285
286     if (priv == NULL) {
287         return;
288     }
289     if (priv->smepriv == NULL) {
290         unifi_error(priv, "CsrWifiRouterCtrlHipReqHandler: invalid smepriv\n");
291         return;
292     }
293     if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
294         unifi_error(priv, "CsrWifiRouterCtrlHipReqHandler: invalid interfaceTag\n");
295         return;
296     }
297
298     /* Initialize bulkdata to avoid os_net_buf is garbage */
299     memset(&bulkdata, 0, sizeof(bulk_data_param_t));
300
301     signal = (CSR_SIGNAL *)hipreq->mlmeCommand;
302
303     unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlHipReqHandler: 0x04%X ---->\n",
304                 *((u16*)hipreq->mlmeCommand));
305
306     /* Construct the signal. */
307     signal_ptr = (u8*)hipreq->mlmeCommand;
308     signal_length = hipreq->mlmeCommandLength;
309
310     /*
311      * The MSB of the sender ID needs to be set to the client ID.
312      * The LSB is controlled by the SME.
313      */
314     signal_ptr[5] = (priv->sme_cli->sender_id >> 8) & 0xff;
315
316     /* Allocate buffers for the bulk data. */
317     if (hipreq->dataRef1Length) {
318         csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], hipreq->dataRef1Length);
319         if (csrResult == CSR_RESULT_SUCCESS) {
320             dest = (void*)bulkdata.d[0].os_data_ptr;
321             memcpy(dest, hipreq->dataRef1, hipreq->dataRef1Length);
322             bulkdata.d[0].data_length = hipreq->dataRef1Length;
323         } else {
324             unifi_warning(priv, "signal not sent down, allocation failed in CsrWifiRouterCtrlHipReqHandler\n");
325             return;
326         }
327     } else {
328         bulkdata.d[0].os_data_ptr = NULL;
329         bulkdata.d[0].data_length = 0;
330     }
331     if (hipreq->dataRef2Length) {
332         csrResult = unifi_net_data_malloc(priv, &bulkdata.d[1], hipreq->dataRef2Length);
333         if (csrResult == CSR_RESULT_SUCCESS) {
334             dest = (void*)bulkdata.d[1].os_data_ptr;
335             memcpy(dest, hipreq->dataRef2, hipreq->dataRef2Length);
336             bulkdata.d[1].data_length = hipreq->dataRef2Length;
337         } else {
338             if (bulkdata.d[0].data_length)
339             {
340                 unifi_net_data_free(priv, &bulkdata.d[0]);
341             }
342             unifi_warning(priv, "signal not sent down, allocation failed in CsrWifiRouterCtrlHipReqHandler\n");
343             return;
344         }
345     } else {
346         bulkdata.d[1].os_data_ptr = NULL;
347         bulkdata.d[1].data_length = 0;
348     }
349
350     unifi_trace(priv, UDBG3, "SME SEND: Signal 0x%.4X \n",
351                 *((u16*)signal_ptr));
352     if (signal->SignalPrimitiveHeader.SignalId == CSR_MA_PACKET_REQUEST_ID)
353     {
354         CSR_SIGNAL unpacked_signal;
355         read_unpack_signal((u8 *) signal, &unpacked_signal);
356         req = &unpacked_signal.u.MaPacketRequest;
357         interfaceTag = req->VirtualInterfaceIdentifier & 0xff;
358         switch(interfacePriv->interfaceMode)
359         {
360             case CSR_WIFI_ROUTER_CTRL_MODE_NONE:
361                 unifi_error(priv, "CsrWifiRouterCtrlHipReqHandler: invalid mode: NONE \n");
362                 break;
363             default:
364                 unifi_trace(priv, UDBG5, "mode is %x\n", interfacePriv->interfaceMode);
365         }
366         /* While sending ensure that first 2 bits b31 and b30 are 00. These are used for local routing*/
367         r = uf_process_ma_packet_req(priv, req->Ra.x, (req->HostTag & 0x3FFFFFFF), interfaceTag,
368                                      req->TransmissionControl, req->TransmitRate,
369                                      req->Priority, signal->SignalPrimitiveHeader.SenderProcessId,
370                                      &bulkdata);
371         if (r)
372         {
373             if (bulkdata.d[0].data_length)
374             {
375                 unifi_net_data_free(priv, &bulkdata.d[0]);
376             }
377             if (bulkdata.d[1].data_length)
378             {
379                 unifi_net_data_free(priv, &bulkdata.d[1]);
380             }
381         }
382     } else {
383         /* ul_send_signal_raw frees the bulk data if it fails */
384         r = ul_send_signal_raw(priv, signal_ptr, signal_length, &bulkdata);
385     }
386
387     if (r) {
388         unifi_error(priv,
389                     "CsrWifiRouterCtrlHipReqHandler: Failed to send signal (0x%.4X - %u)\n",
390                     *((u16*)signal_ptr), r);
391         CsrWifiRouterCtrlWifiOffIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,CSR_WIFI_SME_CONTROL_INDICATION_ERROR);
392     }
393
394     unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlHipReqHandler: <----\n");
395 }
396
397 #ifdef CSR_WIFI_SEND_GRATUITOUS_ARP
398 static void
399 uf_send_gratuitous_arp(unifi_priv_t *priv, u16 interfaceTag)
400 {
401     netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
402     CSR_PRIORITY priority;
403     CSR_SIGNAL signal;
404     bulk_data_param_t bulkdata;
405     CsrResult csrResult;
406     struct sk_buff *skb, *newSkb = NULL;
407     s8 protection;
408     int r;
409     static const u8 arp_req[36] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00,
410                                          0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01,
411                                          0x00, 0x02, 0x5f, 0x20, 0x2f, 0x02,
412                                          0xc0, 0xa8, 0x00, 0x02,
413                                          0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
414                                          0xc0, 0xa8, 0x00, 0x02};
415
416     func_enter();
417
418     csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], sizeof(arp_req));
419     if (csrResult != CSR_RESULT_SUCCESS)
420     {
421         unifi_error(priv, "Failed to allocate bulk data in CsrWifiSmeRoamCompleteIndHandler()\n");
422         return;
423     }
424     skb = (struct sk_buff *)(bulkdata.d[0].os_net_buf_ptr);
425     skb->len = bulkdata.d[0].data_length;
426
427     memcpy(skb->data, arp_req, sizeof(arp_req));
428     /* add MAC and IP address */
429     memcpy(skb->data + 16, priv->netdev[interfaceTag]->dev_addr, ETH_ALEN);
430     skb->data[22] = (priv->sta_ip_address      ) & 0xFF;
431     skb->data[23] = (priv->sta_ip_address >>  8) & 0xFF;
432     skb->data[24] = (priv->sta_ip_address >> 16) & 0xFF;
433     skb->data[25] = (priv->sta_ip_address >> 24) & 0xFF;
434     skb->data[32] = (priv->sta_ip_address      ) & 0xFF;
435     skb->data[33] = (priv->sta_ip_address >>  8) & 0xFF;
436     skb->data[34] = (priv->sta_ip_address >> 16) & 0xFF;
437     skb->data[35] = (priv->sta_ip_address >> 24) & 0xFF;
438
439     bulkdata.d[1].os_data_ptr = NULL;
440     bulkdata.d[1].os_net_buf_ptr = NULL;
441     bulkdata.d[1].net_buf_length = bulkdata.d[1].data_length = 0;
442
443     if ((protection = uf_get_protection_bit_from_interfacemode(priv, interfaceTag, &arp_req[26])) < 0)
444     {
445         unifi_error(priv, "CsrWifiSmeRoamCompleteIndHandler: Failed to determine protection mode\n");
446         unifi_net_data_free(priv, &bulkdata.d[0]);
447         return;
448     }
449
450     if ((priv->sta_wmm_capabilities & QOS_CAPABILITY_WMM_ENABLED) == 1)
451     {
452         priority = CSR_QOS_UP0;
453     }
454     else
455     {
456         priority = CSR_CONTENTION;
457     }
458
459     if (prepare_and_add_macheader(priv, skb, newSkb, priority, &bulkdata,
460                                   interfaceTag, &arp_req[26],
461                                   priv->netdev[interfaceTag]->dev_addr, protection))
462     {
463         unifi_error(priv, "CsrWifiSmeRoamCompleteIndHandler: failed to create MAC header\n");
464         unifi_net_data_free(priv, &bulkdata.d[0]);
465         return;
466     }
467     bulkdata.d[0].os_data_ptr = skb->data;
468     bulkdata.d[0].os_net_buf_ptr = skb;
469     bulkdata.d[0].data_length = skb->len;
470
471     unifi_frame_ma_packet_req(priv, priority, 0, 0xffffffff, interfaceTag,
472                               CSR_NO_CONFIRM_REQUIRED, priv->netdev_client->sender_id,
473                               interfacePriv->bssid.a, &signal);
474
475     r = ul_send_signal_unpacked(priv, &signal, &bulkdata);
476     if (r)
477     {
478         unifi_error(priv, "CsrWifiSmeRoamCompleteIndHandler: failed to send QOS data null packet result: %d\n",r);
479         unifi_net_data_free(priv, &bulkdata.d[0]);
480         return;
481     }
482
483     func_exit();
484
485 }
486 #endif /* CSR_WIFI_SEND_GRATUITOUS_ARP */
487
488 /*
489  * ---------------------------------------------------------------------------
490  * configure_data_port
491  *
492  *      Store the new controlled port configuration.
493  *
494  * Arguments:
495  *      priv            Pointer to device private context struct
496  *      port_cfg        Pointer to the port configuration
497  *
498  * Returns:
499  *      An unifi_ControlledPortAction value.
500  * ---------------------------------------------------------------------------
501  */
502 static int
503 configure_data_port(unifi_priv_t *priv,
504         CsrWifiRouterCtrlPortAction port_action,
505         const CsrWifiMacAddress *macAddress,
506         const int queue,
507         u16 interfaceTag)
508 {
509     const u8 broadcast_mac_address[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
510     unifi_port_config_t *port;
511     netInterface_priv_t *interfacePriv;
512     int i;
513     const char* controlled_string; /* cosmetic "controlled"/"uncontrolled" for trace */
514
515     if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
516         unifi_error(priv, "configure_data_port: bad interfaceTag\n");
517         return -EFAULT;
518     }
519
520     interfacePriv = priv->interfacePriv[interfaceTag];
521
522     if (queue == UF_CONTROLLED_PORT_Q) {
523         port = &interfacePriv->controlled_data_port;
524         controlled_string = "controlled";
525     } else {
526         port = &interfacePriv->uncontrolled_data_port;
527         controlled_string = "uncontrolled";
528     }
529
530         unifi_trace(priv, UDBG2,
531                 "port config request %pM %s with port_action %d.\n",
532                 macAddress->a, controlled_string, port_action);
533
534     /* If the new configuration has the broadcast MAC address or if we are in infrastructure mode then clear the list first and set port overide mode */
535     if ((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode ||
536         interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI) ||
537         !memcmp(macAddress->a, broadcast_mac_address, ETH_ALEN)) {
538
539         port->port_cfg[0].port_action = port_action;
540         port->port_cfg[0].mac_address = *macAddress;
541         port->port_cfg[0].in_use = TRUE;
542         port->entries_in_use = 1;
543         port->overide_action = UF_DATA_PORT_OVERIDE;
544
545         unifi_trace(priv, UDBG2, "%s port override on\n",
546                     (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled");
547
548         /* Discard the remaining entries in the port config table */
549         for (i = 1; i < UNIFI_MAX_CONNECTIONS; i++) {
550             port->port_cfg[i].in_use = FALSE;
551         }
552
553         if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
554             unifi_trace(priv, UDBG1, "%s port broadcast set to open.\n",
555                         (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled");
556
557             /*
558              * Ask stack to schedule for transmission any packets queued
559              * while controlled port was not open.
560              * Use netif_schedule() instead of netif_wake_queue() because
561              * transmission should be already enabled at this point. If it
562              * is not, probably the interface is down and should remain as is.
563              */
564             uf_resume_data_plane(priv, queue, *macAddress, interfaceTag);
565
566 #ifdef CSR_WIFI_SEND_GRATUITOUS_ARP
567             if ((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) &&
568                 (queue == UF_CONTROLLED_PORT_Q) && (priv->sta_ip_address != 0xFFFFFFFF))
569             {
570                 uf_send_gratuitous_arp(priv, interfaceTag);
571             }
572 #endif
573         } else {
574             unifi_trace(priv, UDBG1, "%s port broadcast set to %s.\n",
575                         (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled",
576                         (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) ? "discard": "closed");
577
578             /* If port is closed, discard all the pending Rx packets */
579             if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) {
580                 uf_free_pending_rx_packets(priv, queue, *macAddress,interfaceTag);
581             }
582         }
583     } else {
584         /* store the new configuration, either in the entry with matching mac address (if already present),
585          * otherwise in a new entry
586          */
587
588         int found_entry_flag;
589         int first_free_slot = -1;
590
591         /* If leaving override mode, free the port entry used for override */
592         if (port->overide_action == UF_DATA_PORT_OVERIDE) {
593             port->port_cfg[0].in_use = FALSE;
594             port->entries_in_use = 0;
595             port->overide_action = UF_DATA_PORT_NOT_OVERIDE;
596
597             unifi_trace(priv, UDBG2, "%s port override off\n",
598                         (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled");
599         }
600
601         found_entry_flag = 0;
602         for (i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
603             if (port->port_cfg[i].in_use) {
604                 if (!memcmp(&port->port_cfg[i].mac_address.a, macAddress->a, ETH_ALEN)) {
605                     /* We've seen this address before, reconfigure it */
606                     port->port_cfg[i].port_action = port_action;
607                     found_entry_flag = 1;
608                     break;
609                 }
610             } else if (first_free_slot == -1) {
611                 /* Remember the first free slot on the way past so it can be claimed
612                  * if this turns out to be a new MAC address (to save walking the list again).
613                  */
614                 first_free_slot = i;
615             }
616         }
617
618         /* At this point we found an existing entry and have updated it, or need to
619          * add a new entry. If all slots are allocated, give up and return an error.
620          */
621         if (!found_entry_flag) {
622             if (first_free_slot == -1) {
623                 unifi_error(priv, "no free slot found in port config array (%d used)\n", port->entries_in_use);
624                 return -EFAULT;
625             } else {
626                 port->entries_in_use++;
627             }
628
629             unifi_trace(priv, UDBG3, "port config index assigned in config_data_port = %d\n", first_free_slot);
630             port->port_cfg[first_free_slot].in_use = TRUE;
631             port->port_cfg[first_free_slot].port_action = port_action;
632             port->port_cfg[first_free_slot].mac_address = *macAddress;
633         }
634
635         if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
636             /*
637              * Ask stack to schedule for transmission any packets queued
638              * while controlled port was not open.
639              * Use netif_schedule() instead of netif_wake_queue() because
640              * transmission should be already enabled at this point. If it
641              * is not, probably the interface is down and should remain as is.
642              */
643             uf_resume_data_plane(priv, queue, *macAddress, interfaceTag);
644         }
645
646         /*
647          * If port is closed, discard all the pending Rx packets
648          * coming from the peer station.
649          */
650         if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) {
651             uf_free_pending_rx_packets(priv, queue, *macAddress,interfaceTag);
652         }
653
654         unifi_trace(priv, UDBG2,
655                 "port config %pM with port_action %d.\n",
656                 macAddress->a, port_action);
657     }
658     return 0;
659 } /* configure_data_port() */
660
661
662 void CsrWifiRouterCtrlPortConfigureReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
663 {
664     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
665     CsrWifiRouterCtrlPortConfigureReq* req = (CsrWifiRouterCtrlPortConfigureReq*)msg;
666     netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
667
668     unifi_trace(priv, UDBG3, "entering CsrWifiRouterCtrlPortConfigureReqHandler\n");
669     if (priv->smepriv == NULL) {
670         unifi_error(priv, "CsrWifiRouterCtrlPortConfigureReqHandler: invalid smepriv\n");
671         return;
672     }
673
674     /* To update the protection status of the peer/station */
675     switch(interfacePriv->interfaceMode)
676     {
677         case CSR_WIFI_ROUTER_CTRL_MODE_STA:
678             case CSR_WIFI_ROUTER_CTRL_MODE_AMP:
679         case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
680         case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
681             /* Since for Unifi as a station, the station record not maintained & interfaceID is
682              * only needed to update the peer protection status
683              */
684             interfacePriv->protect = req->setProtection;
685             break;
686         case CSR_WIFI_ROUTER_CTRL_MODE_AP:
687         case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
688             {
689                 u8 i;
690                 CsrWifiRouterCtrlStaInfo_t *staRecord;
691                 /* Ifscontrolled port is open means, The peer has been added to station record
692                  * so that the protection corresponding to the peer is valid in this req
693                  */
694                 if (req->controlledPortAction == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
695                     for(i =0; i < UNIFI_MAX_CONNECTIONS; i++) {
696                         staRecord = (CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]);
697                         if (staRecord) {
698                                 /* Find the matching station record & set the protection type */
699                                 if (!memcmp(req->macAddress.a, staRecord->peerMacAddress.a, ETH_ALEN)) {
700                                         staRecord->protection = req->setProtection;
701                                         break;
702                                 }
703                         }
704                     }
705                 }
706             }
707             break;
708         default:
709             unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlPortConfigureReqHandler(0x%.4X) Uncaught mode %d\n",
710                         msg->source, interfacePriv->interfaceMode);
711     }
712
713     configure_data_port(priv, req->uncontrolledPortAction, (const CsrWifiMacAddress *)&req->macAddress,
714                         UF_UNCONTROLLED_PORT_Q, req->interfaceTag);
715     configure_data_port(priv, req->controlledPortAction, (const CsrWifiMacAddress *)&req->macAddress,
716                         UF_CONTROLLED_PORT_Q, req->interfaceTag);
717
718     CsrWifiRouterCtrlPortConfigureCfmSend(msg->source,req->clientData,req->interfaceTag,
719                                       CSR_RESULT_SUCCESS, req->macAddress);
720     unifi_trace(priv, UDBG3, "leaving CsrWifiRouterCtrlPortConfigureReqHandler\n");
721 }
722
723
724 void CsrWifiRouterCtrlWifiOnReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
725 {
726     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
727     CsrWifiRouterCtrlVersions versions;
728     CsrWifiRouterCtrlWifiOnReq* req = (CsrWifiRouterCtrlWifiOnReq*)msg;
729     int r,i;
730     CsrResult csrResult;
731
732     if (priv == NULL) {
733         return;
734     }
735     if( priv->wol_suspend ) {
736         unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: Don't reset mode\n");
737     } else {
738 #ifdef ANDROID_BUILD
739         /* Take the wakelock while Wi-Fi On is in progress */
740         unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: take wake lock\n");
741         wake_lock(&unifi_sdio_wake_lock);
742 #endif
743         for (i=0; i<CSR_WIFI_NUM_INTERFACES; i++) {
744             unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: Setting interface %d to NONE\n", i );
745
746             priv->interfacePriv[i]->interfaceMode = 0;
747         }
748     }
749     unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler(0x%.4X) req->dataLength=%d req->data=0x%x\n", msg->source, req->dataLength, req->data);
750
751     if(req->dataLength==3 && req->data && req->data[0]==0 && req->data[1]==1 && req->data[2]==1)
752     {
753         priv->cmanrTestMode = TRUE;
754         unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: cmanrTestMode=%d\n", priv->cmanrTestMode);
755     }
756     else
757     {
758         priv->cmanrTestMode = FALSE;
759     }
760
761     /*
762      * The request to initialise UniFi might come while UniFi is running.
763      * We need to block all I/O activity until the reset completes, otherwise
764      * an SDIO error might occur resulting an indication to the SME which
765      * makes it think that the initialisation has failed.
766      */
767     priv->bh_thread.block_thread = 1;
768
769     /* Update the wifi_on state */
770     priv->wifi_on_state = wifi_on_in_progress;
771
772     /* If UniFi was unpowered, acquire the firmware for download to chip */
773     if (!priv->wol_suspend) {
774         r = uf_request_firmware_files(priv, UNIFI_FW_STA);
775         if (r) {
776             unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to get f/w\n");
777             CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE);
778             return;
779         }
780     } else {
781         unifi_trace(priv, UDBG1, "Don't need firmware\n");
782     }
783
784     /* Power on UniFi (which may not necessarily have been off) */
785     CsrSdioClaim(priv->sdio);
786     csrResult = CsrSdioPowerOn(priv->sdio);
787     CsrSdioRelease(priv->sdio);
788     if (csrResult != CSR_RESULT_SUCCESS && csrResult != CSR_SDIO_RESULT_NOT_RESET) {
789         unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to power on UniFi\n");
790         CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE);
791         return;
792     }
793
794     /* If CsrSdioPowerOn() returns CSR_RESULT_SUCCESS, it means that we need to initialise UniFi */
795     if (csrResult == CSR_RESULT_SUCCESS && !priv->wol_suspend) {
796         /* Initialise UniFi hardware */
797         r = uf_init_hw(priv);
798         if (r) {
799             unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to initialise h/w, error %d\n", r);
800             CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE);
801             return;
802         }
803     } else {
804         unifi_trace(priv, UDBG1, "UniFi already initialised\n");
805     }
806
807     /* Completed handling of wake up from suspend with UniFi powered */
808     priv->wol_suspend = FALSE;
809
810     /* Re-enable the I/O thread */
811     priv->bh_thread.block_thread = 0;
812
813     /*
814      * Start the I/O thread. The thread might be already running.
815      * This fine, just carry on with the request.
816      */
817     r = uf_init_bh(priv);
818     if (r) {
819         CsrSdioClaim(priv->sdio);
820         CsrSdioPowerOff(priv->sdio);
821         CsrSdioRelease(priv->sdio);
822         CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE);
823         return;
824     }
825
826     /* Get the version information from the core */
827     unifi_card_info(priv->card, &priv->card_info);
828
829     /* Set the sme queue id */
830     priv->CSR_WIFI_SME_IFACEQUEUE = msg->source;
831     CSR_WIFI_SME_IFACEQUEUE = msg->source;
832
833
834     /* Copy to the unifiio_card_info structure. */
835     versions.chipId = priv->card_info.chip_id;
836     versions.chipVersion = priv->card_info.chip_version;
837     versions.firmwareBuild = priv->card_info.fw_build;
838     versions.firmwareHip = priv->card_info.fw_hip_version;
839     versions.routerBuild = (char*)CSR_WIFI_VERSION;
840     versions.routerHip = (UNIFI_HIP_MAJOR_VERSION << 8) | UNIFI_HIP_MINOR_VERSION;
841
842     CsrWifiRouterCtrlWifiOnIndSend(msg->source, 0, CSR_RESULT_SUCCESS, versions);
843
844     /* Update the wifi_on state */
845     priv->wifi_on_state = wifi_on_done;
846 }
847
848
849 /*
850  * wifi_off:
851  *      Common code for CsrWifiRouterCtrlWifiOffReqHandler() and
852  *      CsrWifiRouterCtrlWifiOffRspHandler().
853  */
854 static void
855 wifi_off(unifi_priv_t *priv)
856 {
857     int power_off;
858     int priv_instance;
859     int i;
860     CsrResult csrResult;
861
862
863     /* Already off? */
864     if (priv->wifi_on_state == wifi_on_unspecified) {
865         unifi_trace(priv, UDBG1, "wifi_off already\n");
866         return;
867     }
868
869     unifi_trace(priv, UDBG1, "wifi_off\n");
870
871     /* Destroy the Traffic Analysis Module */
872     cancel_work_sync(&priv->ta_ind_work.task);
873     cancel_work_sync(&priv->ta_sample_ind_work.task);
874 #ifdef CSR_SUPPORT_WEXT
875     cancel_work_sync(&priv->sme_config_task);
876     wext_send_disassoc_event(priv);
877 #endif
878
879     /* Cancel pending M4 stuff */
880     for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
881         if (priv->netdev[i]) {
882             netInterface_priv_t *netpriv = (netInterface_priv_t *) netdev_priv(priv->netdev[i]);
883             cancel_work_sync(&netpriv->send_m4_ready_task);
884         }
885     }
886     flush_workqueue(priv->unifi_workqueue);
887
888     /* fw_init parameter can prevent power off UniFi, for debugging */
889     priv_instance = uf_find_priv(priv);
890     if (priv_instance == -1) {
891         unifi_warning(priv,
892                 "CsrWifiRouterCtrlStopReqHandler: Unknown priv instance, will power off card.\n");
893         power_off = 1;
894     } else {
895         power_off = (fw_init[priv_instance] > 0) ? 0 : 1;
896     }
897
898     /* Production test mode requires power to the chip, too */
899     if (priv->ptest_mode) {
900         power_off = 0;
901     }
902
903     /* Stop the bh_thread */
904     uf_stop_thread(priv, &priv->bh_thread);
905
906     /* Read the f/w panic codes, if any. Protect against second wifi_off() call,
907      * which may happen if SME requests a wifi_off and closes the char device */
908     if (priv->init_progress != UNIFI_INIT_NONE) {
909         CsrSdioClaim(priv->sdio);
910         unifi_capture_panic(priv->card);
911         CsrSdioRelease(priv->sdio);
912     }
913
914     /* Unregister the interrupt handler */
915     if (csr_sdio_linux_remove_irq(priv->sdio)) {
916         unifi_notice(priv,
917                 "csr_sdio_linux_remove_irq failed to talk to card.\n");
918     }
919
920     if (power_off) {
921         unifi_trace(priv, UDBG2,
922                     "Force low power and try to power off\n");
923         /* Put UniFi to deep sleep, in case we can not power it off */
924         CsrSdioClaim(priv->sdio);
925         csrResult = unifi_force_low_power_mode(priv->card);
926         CsrSdioRelease(priv->sdio);
927
928         CsrSdioPowerOff(priv->sdio);
929     }
930
931     /* Consider UniFi to be uninitialised */
932     priv->init_progress = UNIFI_INIT_NONE;
933     priv->wifi_on_state = wifi_on_unspecified;
934
935
936 } /* wifi_off() */
937
938
939 void CsrWifiRouterCtrlWifiOffReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
940 {
941     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
942     CsrWifiRouterCtrlWifiOffReq* req = (CsrWifiRouterCtrlWifiOffReq*)msg;
943     int i = 0;
944
945     if (priv == NULL) {
946         return;
947     }
948
949     unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOffReqHandler(0x%.4X)\n", msg->source);
950
951     /* Stop the network traffic on all interfaces before freeing the core. */
952     for (i=0; i<CSR_WIFI_NUM_INTERFACES; i++) {
953         netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
954         if (interfacePriv->netdev_registered == 1) {
955             netif_carrier_off(priv->netdev[i]);
956             netif_tx_stop_all_queues(priv->netdev[i]);
957             interfacePriv->connected = UnifiConnectedUnknown;
958         }
959         interfacePriv->interfaceMode = 0;
960
961         /* Enable all queues by default */
962         interfacePriv->queueEnabled[0] = 1;
963         interfacePriv->queueEnabled[1] = 1;
964         interfacePriv->queueEnabled[2] = 1;
965         interfacePriv->queueEnabled[3] = 1;
966     }
967     wifi_off(priv);
968
969     CsrWifiRouterCtrlWifiOffCfmSend(msg->source,req->clientData);
970
971     /* If this is called in response to closing the character device, the
972      * caller must use uf_sme_cancel_request() to terminate any pending SME
973      * blocking request or there will be a delay while the operation times out.
974      */
975 }
976
977
978 void CsrWifiRouterCtrlQosControlReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
979 {
980     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
981     CsrWifiRouterCtrlQosControlReq* req = (CsrWifiRouterCtrlQosControlReq*)msg;
982     netInterface_priv_t *interfacePriv;
983
984     if (priv->smepriv == NULL) {
985         unifi_error(priv, "CsrWifiRouterCtrlQosControlReqHandler: invalid smepriv\n");
986         return;
987     }
988
989     unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlQosControlReqHandler:scontrol = %d", req->control);
990
991     if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
992         unifi_error(priv, "CsrWifiRouterCtrlQosControlReqHandler: interfaceID >= CSR_WIFI_NUM_INTERFACES.\n");
993         return;
994     }
995     interfacePriv = priv->interfacePriv[req->interfaceTag];
996
997     if (req->control == CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_WMM_ON) {
998         priv->sta_wmm_capabilities |= QOS_CAPABILITY_WMM_ENABLED;
999         unifi_trace(priv, UDBG1, "WMM enabled\n");
1000
1001         unifi_trace(priv, UDBG1, "Queue Config %x\n", req->queueConfig);
1002
1003         interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_BK] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_BK_ENABLE)?1:0;
1004         interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_BE] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_BE_ENABLE)?1:0;
1005         interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_VI] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_VI_ENABLE)?1:0;
1006         interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_VO] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_VO_ENABLE)?1:0;
1007
1008     } else {
1009         priv->sta_wmm_capabilities = 0;
1010         unifi_trace(priv, UDBG1, "WMM disabled\n");
1011     }
1012 }
1013
1014
1015 void CsrWifiRouterCtrlTclasAddReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1016 {
1017     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1018     CsrWifiRouterCtrlTclasAddReq* req = (CsrWifiRouterCtrlTclasAddReq*)msg;
1019
1020     if (priv == NULL) {
1021         unifi_error(priv, "CsrWifiRouterCtrlTclasAddReqHandler: invalid smepriv\n");
1022         return;
1023     }
1024
1025     CsrWifiRouterCtrlTclasAddCfmSend(msg->source, req->clientData, req->interfaceTag , CSR_RESULT_SUCCESS);
1026 }
1027
1028 void CsrWifiRouterCtrlTclasDelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1029 {
1030     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1031     CsrWifiRouterCtrlTclasDelReq* req = (CsrWifiRouterCtrlTclasDelReq*)msg;
1032
1033     if (priv == NULL) {
1034         unifi_error(priv, "CsrWifiRouterCtrlTclasDelReqHandler: invalid smepriv\n");
1035         return;
1036     }
1037
1038     CsrWifiRouterCtrlTclasDelCfmSend(msg->source, req->clientData, req->interfaceTag, CSR_RESULT_SUCCESS);
1039 }
1040
1041
1042 void CsrWifiRouterCtrlConfigurePowerModeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1043 {
1044     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1045     CsrWifiRouterCtrlConfigurePowerModeReq* req = (CsrWifiRouterCtrlConfigurePowerModeReq*)msg;
1046     enum unifi_low_power_mode pm;
1047     CsrResult csrResult;
1048
1049     if (priv->smepriv == NULL) {
1050         unifi_error(priv, "CsrWifiRouterCtrlConfigurePowerModeReqHandler: invalid smepriv\n");
1051         return;
1052     }
1053
1054     if (req->mode == CSR_WIFI_ROUTER_CTRL_LOW_POWER_MODE_DISABLED) {
1055         pm = UNIFI_LOW_POWER_DISABLED;
1056     } else {
1057         pm = UNIFI_LOW_POWER_ENABLED;
1058     }
1059
1060     unifi_trace(priv, UDBG2,
1061                 "CsrWifiRouterCtrlConfigurePowerModeReqHandler (mode=%d, wake=%d)\n",
1062                 req->mode, req->wakeHost);
1063     csrResult = unifi_configure_low_power_mode(priv->card, pm,
1064                                                (req->wakeHost ? UNIFI_PERIODIC_WAKE_HOST_ENABLED : UNIFI_PERIODIC_WAKE_HOST_DISABLED));
1065 }
1066
1067
1068 void CsrWifiRouterCtrlWifiOnResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1069 {
1070     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1071     CsrWifiRouterCtrlWifiOnRes* res = (CsrWifiRouterCtrlWifiOnRes*)msg;
1072
1073     if (priv == NULL) {
1074         unifi_error(NULL, "CsrWifiRouterCtrlWifiOnResHandler: Invalid ospriv.\n");
1075         return;
1076     }
1077
1078     unifi_trace(priv, UDBG1,
1079                 "CsrWifiRouterCtrlWifiOnResHandler: status %d (patch %u)\n", res->status, res->smeVersions.firmwarePatch);
1080
1081     if (res->smeVersions.firmwarePatch != 0) {
1082         unifi_info(priv, "Firmware patch %d\n", res->smeVersions.firmwarePatch);
1083     }
1084
1085     if (res->numInterfaceAddress > CSR_WIFI_NUM_INTERFACES) {
1086         unifi_error(priv, "WifiOnResHandler bad numInterfaceAddress %d\n", res->numInterfaceAddress);
1087         return;
1088     }
1089
1090     /* UniFi is now initialised, complete the init. */
1091     if (res->status == CSR_RESULT_SUCCESS)
1092     {
1093         int i; /* used as a loop counter */
1094         u32 intmode = CSR_WIFI_INTMODE_DEFAULT;
1095 #ifdef CSR_WIFI_SPLIT_PATCH
1096         u8 switching_ap_fw = FALSE;
1097 #endif
1098         /* Register the UniFi device with the OS network manager */
1099         unifi_trace(priv, UDBG3, "Card Init Completed Successfully\n");
1100
1101         /* Store the MAC address in the netdev */
1102         for(i=0;i<res->numInterfaceAddress;i++)
1103         {
1104             memcpy(priv->netdev[i]->dev_addr, res->stationMacAddress[i].a, ETH_ALEN);
1105         }
1106
1107         /* Copy version structure into the private versions field */
1108         priv->sme_versions = res->smeVersions;
1109
1110         unifi_trace(priv, UDBG2, "network interfaces count = %d\n",
1111                     res->numInterfaceAddress);
1112
1113         /* Register the netdevs for each interface. */
1114         for(i=0;i<res->numInterfaceAddress;i++)
1115         {
1116             netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
1117             if(!interfacePriv->netdev_registered)
1118             {
1119                 int r;
1120                 unifi_trace(priv, UDBG3, "registering net device %d\n", i);
1121                 r = uf_register_netdev(priv, i);
1122                 if (r)
1123                 {
1124                     /* unregister the net_device that are registered in the previous iterations */
1125                     uf_unregister_netdev(priv);
1126                     unifi_error(priv, "Failed to register the network device.\n");
1127                     CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_FAILURE);
1128                     return;
1129                 }
1130             }
1131 #ifdef CSR_WIFI_SPLIT_PATCH
1132             else
1133             {
1134                 /* If a netdev is already registered, we have received this WifiOnRes
1135                  * in response to switching AP/STA firmware in a ModeSetReq.
1136                  * Rememeber this in order to send a ModeSetCfm once
1137                  */
1138                 switching_ap_fw = TRUE;
1139             }
1140 #endif
1141         }
1142         priv->totalInterfaceCount = res->numInterfaceAddress;
1143
1144         /* If the MIB has selected f/w scheduled interrupt mode, apply it now
1145          * but let module param override.
1146          */
1147         if (run_bh_once != -1) {
1148             intmode = (u32)run_bh_once;
1149         } else if (res->scheduledInterrupt) {
1150             intmode = CSR_WIFI_INTMODE_RUN_BH_ONCE;
1151         }
1152         unifi_set_interrupt_mode(priv->card, intmode);
1153
1154         priv->init_progress = UNIFI_INIT_COMPLETED;
1155
1156         /* Acknowledge the CsrWifiRouterCtrlWifiOnReq now */
1157         CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_SUCCESS);
1158
1159 #ifdef CSR_WIFI_SPLIT_PATCH
1160         if (switching_ap_fw && (priv->pending_mode_set.common.destination != 0xaaaa)) {
1161             unifi_info(priv, "Completed firmware reload with %s patch\n",
1162                 CSR_WIFI_HIP_IS_AP_FW(priv->interfacePriv[0]->interfaceMode) ? "AP" : "STA");
1163
1164             /* Confirm the ModeSetReq that requested the AP/STA patch switch */
1165             CsrWifiRouterCtrlModeSetCfmSend(priv->pending_mode_set.common.source,
1166                                             priv->pending_mode_set.clientData,
1167                                             priv->pending_mode_set.interfaceTag,
1168                                             priv->pending_mode_set.mode,
1169                                             CSR_RESULT_SUCCESS);
1170             priv->pending_mode_set.common.destination = 0xaaaa;
1171         }
1172 #endif
1173         unifi_info(priv, "UniFi ready\n");
1174
1175 #ifdef ANDROID_BUILD
1176         /* Release the wakelock */
1177         unifi_trace(priv, UDBG1, "ready: release wake lock\n");
1178         wake_unlock(&unifi_sdio_wake_lock);
1179 #endif
1180         /* Firmware initialisation is complete, so let the SDIO bus
1181          * clock be raised when convienent to the core.
1182          */
1183         unifi_request_max_sdio_clock(priv->card);
1184
1185 #ifdef CSR_SUPPORT_WEXT
1186         /* Notify the Android wpa_supplicant that we are ready */
1187         wext_send_started_event(priv);
1188
1189         queue_work(priv->unifi_workqueue, &priv->sme_config_task);
1190 #endif
1191
1192     } else {
1193         /* Acknowledge the CsrWifiRouterCtrlWifiOnReq now */
1194         CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_FAILURE);
1195     }
1196 }
1197
1198
1199 void CsrWifiRouterCtrlWifiOffResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1200 {
1201 }
1202
1203
1204 void CsrWifiRouterCtrlMulticastAddressResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1205 {
1206 }
1207
1208
1209 void CsrWifiRouterMaPacketSubscribeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1210 {
1211     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1212     CsrWifiRouterMaPacketSubscribeReq* req = (CsrWifiRouterMaPacketSubscribeReq*)msg;
1213     u8 i;
1214     CsrResult result;
1215
1216     if (priv == NULL) {
1217         unifi_error(priv, "CsrWifiRouterMaPacketSubscribeReqHandler: invalid priv\n");
1218         return;
1219     }
1220
1221     /* Look for an unused filter */
1222
1223     result = CSR_WIFI_RESULT_NO_ROOM;
1224     for (i = 0; i < MAX_MA_UNIDATA_IND_FILTERS; i++) {
1225
1226         if (!priv->sme_unidata_ind_filters[i].in_use) {
1227
1228             priv->sme_unidata_ind_filters[i].in_use = 1;
1229             priv->sme_unidata_ind_filters[i].appHandle = msg->source;
1230             priv->sme_unidata_ind_filters[i].encapsulation = req->encapsulation;
1231             priv->sme_unidata_ind_filters[i].protocol = req->protocol;
1232
1233             priv->sme_unidata_ind_filters[i].oui[2] = (u8)  (req->oui        & 0xFF);
1234             priv->sme_unidata_ind_filters[i].oui[1] = (u8) ((req->oui >>  8) & 0xFF);
1235             priv->sme_unidata_ind_filters[i].oui[0] = (u8) ((req->oui >> 16) & 0xFF);
1236
1237             result = CSR_RESULT_SUCCESS;
1238             break;
1239         }
1240     }
1241
1242     unifi_trace(priv, UDBG1,
1243                 "subscribe_req: encap=%d, handle=%d, result=%d\n",
1244                 req->encapsulation, i, result);
1245     CsrWifiRouterMaPacketSubscribeCfmSend(msg->source,req->interfaceTag, i, result, 0);
1246 }
1247
1248
1249 void CsrWifiRouterMaPacketUnsubscribeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1250 {
1251     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1252     CsrWifiRouterMaPacketUnsubscribeReq* req = (CsrWifiRouterMaPacketUnsubscribeReq*)msg;
1253     CsrResult result;
1254
1255     if (priv == NULL) {
1256         unifi_error(priv, "CsrWifiRouterMaPacketUnsubscribeReqHandler: invalid priv\n");
1257         return;
1258     }
1259
1260     result = CSR_WIFI_RESULT_NOT_FOUND;
1261
1262     if (req->subscriptionHandle < MAX_MA_UNIDATA_IND_FILTERS) {
1263         if (priv->sme_unidata_ind_filters[req->subscriptionHandle].in_use) {
1264             priv->sme_unidata_ind_filters[req->subscriptionHandle].in_use = 0;
1265             result = CSR_RESULT_SUCCESS;
1266         } else {
1267             result = CSR_WIFI_RESULT_NOT_FOUND;
1268         }
1269     }
1270
1271     unifi_trace(priv, UDBG1,
1272                 "unsubscribe_req: handle=%d, result=%d\n",
1273                 req->subscriptionHandle, result);
1274     CsrWifiRouterMaPacketUnsubscribeCfmSend(msg->source,req->interfaceTag, result);
1275 }
1276
1277
1278 void CsrWifiRouterCtrlCapabilitiesReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1279 {
1280     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1281     CsrWifiRouterCtrlCapabilitiesReq* req = (CsrWifiRouterCtrlCapabilitiesReq*)msg;
1282
1283     if (priv == NULL) {
1284         unifi_error(priv, "CsrWifiRouterCtrlCapabilitiesReqHandler: invalid priv\n");
1285         return;
1286     }
1287
1288     CsrWifiRouterCtrlCapabilitiesCfmSend(msg->source,req->clientData,
1289             UNIFI_SOFT_COMMAND_Q_LENGTH - 1,
1290             UNIFI_SOFT_TRAFFIC_Q_LENGTH - 1);
1291 }
1292
1293
1294 void CsrWifiRouterCtrlSuspendResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1295 {
1296     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1297     CsrWifiRouterCtrlSuspendRes* res = (CsrWifiRouterCtrlSuspendRes*)msg;
1298
1299     if (priv == NULL) {
1300         unifi_error(priv, "CsrWifiRouterCtrlSuspendResHandler: invalid priv\n");
1301         return;
1302     }
1303
1304     sme_complete_request(priv, res->status);
1305 }
1306
1307
1308 void CsrWifiRouterCtrlResumeResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1309 {
1310     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1311     CsrWifiRouterCtrlResumeRes* res = (CsrWifiRouterCtrlResumeRes*)msg;
1312
1313     if (priv == NULL) {
1314         unifi_error(priv, "CsrWifiRouterCtrlResumeResHandler: invalid priv\n");
1315         return;
1316     }
1317
1318     sme_complete_request(priv, res->status);
1319 }
1320
1321
1322 void CsrWifiRouterCtrlTrafficConfigReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1323 {
1324     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1325     CsrWifiRouterCtrlTrafficConfigReq* req = (CsrWifiRouterCtrlTrafficConfigReq*)msg;
1326     CsrResult csrResult;
1327
1328     if (priv == NULL) {
1329         unifi_error(priv, "CsrWifiRouterCtrlTrafficConfigReqHandler: invalid smepriv\n");
1330         return;
1331     }
1332     if (req->trafficConfigType == CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_FILTER)
1333     {
1334         req->config.packetFilter |= CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM;
1335     }
1336     csrResult = unifi_ta_configure(priv->card, req->trafficConfigType, (const CsrWifiRouterCtrlTrafficConfig *)&req->config);
1337 }
1338
1339 void CsrWifiRouterCtrlTrafficClassificationReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1340 {
1341     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1342     CsrWifiRouterCtrlTrafficClassificationReq* req = (CsrWifiRouterCtrlTrafficClassificationReq*)msg;
1343
1344     if (priv == NULL) {
1345         unifi_error(priv, "CsrWifiRouterCtrlTrafficClassificationReqHandler: invalid smepriv\n");
1346         return;
1347     }
1348
1349     unifi_ta_classification(priv->card, req->trafficType, req->period);
1350 }
1351
1352 static int
1353 _sys_packet_req(unifi_priv_t *priv, const CSR_SIGNAL *signal,
1354         u8 subscriptionHandle,
1355         u16 frameLength, u8 *frame,
1356         int proto)
1357 {
1358     int r;
1359     const sme_ma_unidata_ind_filter_t *subs;
1360     bulk_data_param_t bulkdata;
1361     CSR_MA_PACKET_REQUEST req = signal->u.MaPacketRequest;
1362     struct sk_buff *skb, *newSkb = NULL;
1363     CsrWifiMacAddress peerMacAddress;
1364     CsrResult csrResult;
1365     u16 interfaceTag = req.VirtualInterfaceIdentifier & 0xff;
1366     u8 eapolStore = FALSE;
1367     s8 protection = 0;
1368     netInterface_priv_t *interfacePriv;
1369     unsigned long flags;
1370
1371     if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
1372         unifi_error(priv, "_sys_packet_req: interfaceID >= CSR_WIFI_NUM_INTERFACES.\n");
1373         return -EINVAL;
1374     }
1375     interfacePriv = priv->interfacePriv[interfaceTag];
1376     if (!priv->sme_unidata_ind_filters[subscriptionHandle].in_use) {
1377         unifi_error(priv, "_sys_packet_req: unknown subscription.\n");
1378         return -EINVAL;
1379     }
1380
1381     subs = &priv->sme_unidata_ind_filters[subscriptionHandle];
1382     unifi_trace(priv, UDBG1,
1383                 "_sys_packet_req: handle=%d, subs=%p, encap=%d\n",
1384                 subscriptionHandle, subs, subs->encapsulation);
1385
1386     csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], frameLength);
1387     if (csrResult != CSR_RESULT_SUCCESS) {
1388         unifi_error(priv, "_sys_packet_req: failed to allocate bulkdata.\n");
1389         return (int)CsrHipResultToStatus(csrResult);
1390     }
1391
1392     /* get the peer Mac address */
1393     memcpy(&peerMacAddress, frame, ETH_ALEN);
1394
1395     /* Determine if we need to add encapsulation header */
1396     if (subs->encapsulation == CSR_WIFI_ROUTER_ENCAPSULATION_ETHERNET) {
1397         memcpy((void*)bulkdata.d[0].os_data_ptr, frame, frameLength);
1398
1399         /* The translation is performed on the skb */
1400         skb = (struct sk_buff*)bulkdata.d[0].os_net_buf_ptr;
1401
1402         unifi_trace(priv, UDBG1,
1403                     "_sys_packet_req: skb_add_llc_snap -->\n");
1404         r = skb_add_llc_snap(priv->netdev[interfaceTag], skb, proto);
1405         unifi_trace(priv, UDBG1,
1406                     "_sys_packet_req: skb_add_llc_snap <--\n");
1407         if (r) {
1408             unifi_error(priv,
1409                         "_sys_packet_req: failed to translate eth frame.\n");
1410             unifi_net_data_free(priv,&bulkdata.d[0]);
1411             return r;
1412         }
1413
1414         bulkdata.d[0].data_length = skb->len;
1415     } else {
1416         /* Crop the MAC addresses from the packet */
1417         memcpy((void*)bulkdata.d[0].os_data_ptr, frame + 2*ETH_ALEN, frameLength - 2*ETH_ALEN);
1418         bulkdata.d[0].data_length = frameLength - 2*ETH_ALEN;
1419         skb = (struct sk_buff*)bulkdata.d[0].os_net_buf_ptr;
1420         skb->len = bulkdata.d[0].data_length;
1421
1422     }
1423
1424     bulkdata.d[1].os_data_ptr = NULL;
1425     bulkdata.d[1].os_net_buf_ptr = NULL;
1426     bulkdata.d[1].data_length = 0;
1427
1428     /* check for m4 detection */
1429     if (0 == uf_verify_m4(priv, bulkdata.d[0].os_data_ptr, bulkdata.d[0].data_length)) {
1430         eapolStore = TRUE;
1431     }
1432
1433 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1434     if (proto == ETH_P_WAI)
1435      {
1436         protection = 0; /*WAI packets always sent unencrypted*/
1437      }
1438    else
1439      {
1440 #endif
1441
1442 #ifdef CSR_SUPPORT_SME
1443     if ((protection = uf_get_protection_bit_from_interfacemode(priv, interfaceTag, peerMacAddress.a)) < 0) {
1444         unifi_error(priv, "unicast address, but destination not in station record database\n");
1445         unifi_net_data_free(priv,&bulkdata.d[0]);
1446         return -1;
1447     }
1448 #else
1449     protection = 0;
1450 #endif
1451
1452 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1453     }
1454 #endif
1455
1456     /* add Mac header */
1457     if (prepare_and_add_macheader(priv, skb, newSkb, req.Priority, &bulkdata, interfaceTag, frame, frame + ETH_ALEN, protection)) {
1458         unifi_error(priv, "failed to create MAC header\n");
1459         unifi_net_data_free(priv,&bulkdata.d[0]);
1460         return -1;
1461     }
1462
1463     if (eapolStore) {
1464         spin_lock_irqsave(&priv->m4_lock, flags);
1465         /* Store the EAPOL M4 packet for later */
1466         interfacePriv->m4_signal = *signal;
1467         interfacePriv->m4_bulk_data.net_buf_length = bulkdata.d[0].net_buf_length;
1468         interfacePriv->m4_bulk_data.data_length = bulkdata.d[0].data_length;
1469         interfacePriv->m4_bulk_data.os_data_ptr = bulkdata.d[0].os_data_ptr;
1470         interfacePriv->m4_bulk_data.os_net_buf_ptr = bulkdata.d[0].os_net_buf_ptr;
1471         spin_unlock_irqrestore(&priv->m4_lock, flags);
1472         /* Send a signal to SME */
1473         unifi_trace(priv, UDBG1, "_sys_packet_req: Sending CsrWifiRouterCtrlM4ReadyToSendInd\n");
1474         CsrWifiRouterCtrlM4ReadyToSendIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, peerMacAddress);
1475         return 0;
1476     }
1477
1478     /* Send the signal to UniFi */
1479       /* Set the B31 to 1 for local routing*/
1480     r= uf_process_ma_packet_req(priv,  peerMacAddress.a, (req.HostTag | 0x80000000), interfaceTag, 0,
1481                                 (CSR_RATE)0, req.Priority, signal->SignalPrimitiveHeader.SenderProcessId, &bulkdata);
1482     if (r) {
1483         unifi_error(priv,
1484                     "_sys_packet_req: failed to send signal.\n");
1485         unifi_net_data_free(priv,&bulkdata.d[0]);
1486         return r;
1487     }
1488     /* The final CsrWifiRouterMaPacketCfmSend() will called when the actual MA-PACKET.cfm is received from the chip */
1489
1490     return 0;
1491 }
1492
1493 void CsrWifiRouterMaPacketReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1494 {
1495     int r;
1496     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1497     CsrWifiRouterMaPacketReq* mareq = (CsrWifiRouterMaPacketReq*)msg;
1498     llc_snap_hdr_t *snap;
1499     u16 snap_protocol;
1500     CSR_SIGNAL signal;
1501     CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest;
1502     CsrWifiRouterCtrlPortAction controlPortaction;
1503     u8 *daddr, *saddr;
1504     u16 interfaceTag = mareq->interfaceTag & 0x00ff;
1505     int queue;
1506     netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
1507
1508     if (!mareq->frame || !priv || !priv->smepriv)
1509     {
1510         unifi_error(priv, "CsrWifiRouterMaPacketReqHandler: invalid frame/priv/priv->smepriv\n");
1511         return;
1512     }
1513
1514     if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
1515         unifi_error(priv, "CsrWifiRouterMaPacketReqHandler: interfaceID >= CSR_WIFI_NUM_INTERFACES.\n");
1516         return;
1517     }
1518     /* get a pointer to dest & source Mac address */
1519     daddr = mareq->frame;
1520     saddr = (mareq->frame + ETH_ALEN);
1521     /* point to the proper position of frame, since frame has MAC header */
1522     snap = (llc_snap_hdr_t *) (mareq->frame + 2 * ETH_ALEN);
1523     snap_protocol = ntohs(snap->protocol);
1524     if((snap_protocol == ETH_P_PAE)
1525 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1526        || (snap_protocol == ETH_P_WAI)
1527 #endif
1528     )
1529     {
1530         queue = UF_UNCONTROLLED_PORT_Q;
1531     }
1532     else
1533     {
1534         queue = UF_CONTROLLED_PORT_Q;
1535     }
1536
1537     /* Controlled port restrictions apply to the packets */
1538     controlPortaction = uf_sme_port_state(priv, daddr, queue, interfaceTag);
1539     if (controlPortaction != CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN)
1540     {
1541         unifi_warning(priv, "CsrWifiRouterMaPacketReqHandler: (%s)controlled port is closed.\n", (queue == UF_CONTROLLED_PORT_Q)?"":"un");
1542         if(mareq->cfmRequested)
1543         {
1544             CsrWifiRouterMaPacketCfmSend(msg->source,
1545                                      interfaceTag,
1546                                      CSR_RESULT_FAILURE,
1547                                      mareq->hostTag, 0);
1548         }
1549         return;
1550     }
1551
1552     signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID;
1553     /* Store the appHandle in the LSB of the SenderId. */
1554     CSR_COPY_UINT16_TO_LITTLE_ENDIAN(((priv->sme_cli->sender_id & 0xff00) | (unsigned int)msg->source),
1555                                      (u8*)&signal.SignalPrimitiveHeader.SenderProcessId);
1556     signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
1557
1558     /* Fill in the MA-PACKET.req signal */
1559     memcpy(req->Ra.x, daddr, ETH_ALEN);
1560     req->Priority = mareq->priority;
1561     req->TransmitRate = 0; /* Let firmware select the rate*/
1562     req->VirtualInterfaceIdentifier = uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag);
1563     req->HostTag = mareq->hostTag;
1564
1565     if(mareq->cfmRequested)
1566         req->TransmissionControl = 0;
1567     else
1568         req->TransmissionControl = CSR_NO_CONFIRM_REQUIRED;
1569
1570     r = _sys_packet_req(priv, &signal, mareq->subscriptionHandle,
1571             mareq->frameLength, mareq->frame, snap_protocol);
1572
1573     if (r && mareq->cfmRequested)
1574     {
1575         CsrWifiRouterMaPacketCfmSend(msg->source,interfaceTag,
1576                                      CSR_RESULT_FAILURE,
1577                                      mareq->hostTag, 0);
1578     }
1579     return;
1580 }
1581
1582 void CsrWifiRouterMaPacketCancelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1583 {
1584 }
1585
1586 void CsrWifiRouterCtrlM4TransmitReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1587 {
1588     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1589     CsrWifiRouterCtrlM4TransmitReq* req = (CsrWifiRouterCtrlM4TransmitReq*)msg;
1590     int r;
1591     bulk_data_param_t bulkdata;
1592     netInterface_priv_t *interfacePriv;
1593     CSR_SIGNAL m4_signal;
1594     unsigned long flags;
1595
1596     if (priv == NULL) {
1597         unifi_error(priv, "CsrWifiRouterCtrlM4TransmitReqHandler: invalid smepriv\n");
1598         return;
1599     }
1600     if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
1601         unifi_error(priv, "M4TransmitReqHandler: interfaceTag >= CSR_WIFI_NUM_INTERFACES\n");
1602         return;
1603     }
1604
1605     interfacePriv = priv->interfacePriv[req->interfaceTag];
1606     spin_lock_irqsave(&priv->m4_lock, flags);
1607     if (interfacePriv->m4_bulk_data.data_length == 0) {
1608         spin_unlock_irqrestore(&priv->m4_lock, flags);
1609         unifi_error(priv, "CsrWifiRouterCtrlM4TransmitReqHandler: invalid buffer\n");
1610         return;
1611     }
1612
1613     memcpy(&bulkdata.d[0], &interfacePriv->m4_bulk_data, sizeof(bulk_data_desc_t));
1614
1615     interfacePriv->m4_bulk_data.net_buf_length = 0;
1616     interfacePriv->m4_bulk_data.data_length = 0;
1617     interfacePriv->m4_bulk_data.os_data_ptr = interfacePriv->m4_bulk_data.os_net_buf_ptr = NULL;
1618     m4_signal = interfacePriv->m4_signal;
1619     spin_unlock_irqrestore(&priv->m4_lock, flags);
1620
1621     bulkdata.d[1].os_data_ptr = NULL;
1622     bulkdata.d[1].data_length = 0;
1623
1624     interfacePriv->m4_sent = TRUE;
1625     m4_signal.u.MaPacketRequest.HostTag |= 0x80000000;
1626     /* Store the hostTag for later varification */
1627     interfacePriv->m4_hostTag = m4_signal.u.MaPacketRequest.HostTag;
1628     r = ul_send_signal_unpacked(priv, &m4_signal, &bulkdata);
1629     unifi_trace(priv, UDBG1,
1630                 "CsrWifiRouterCtrlM4TransmitReqHandler: sent\n");
1631     if (r) {
1632         unifi_error(priv,
1633                     "CsrWifiRouterCtrlM4TransmitReqHandler: failed to send signal.\n");
1634         unifi_net_data_free(priv, &bulkdata.d[0]);
1635     }
1636 }
1637
1638 /* reset the station records when the mode is set as CSR_WIFI_ROUTER_CTRL_MODE_NONE */
1639 static void CsrWifiRouterCtrlResetStationRecordList(unifi_priv_t *priv, u16 interfaceTag)
1640 {
1641     u8 i,j;
1642     CsrWifiRouterCtrlStaInfo_t *staInfo=NULL;
1643     netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
1644     unsigned long lock_flags;
1645
1646     /* create a list for sending confirms of un-delivered packets */
1647     struct list_head send_cfm_list;
1648
1649     if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
1650         unifi_error(priv, "CsrWifiRouterCtrlResetStationRecordList: bad interfaceTag\n");
1651         return;
1652     }
1653
1654     INIT_LIST_HEAD(&send_cfm_list);
1655
1656     /* Reset the station record to NULL if mode is NONE */
1657     for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
1658         if ((staInfo=interfacePriv->staInfo[i]) != NULL) {
1659             uf_prepare_send_cfm_list_for_queued_pkts(priv,
1660                                                  &send_cfm_list,
1661                                                  &(staInfo->mgtFrames));
1662             uf_flush_list(priv,&(staInfo->mgtFrames));
1663             for(j=0;j<MAX_ACCESS_CATOGORY;j++){
1664                 uf_prepare_send_cfm_list_for_queued_pkts(priv,
1665                                                      &send_cfm_list,
1666                                                      &(staInfo->dataPdu[j]));
1667                 uf_flush_list(priv,&(staInfo->dataPdu[j]));
1668             }
1669
1670             spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
1671             /* Removing station record information from port config array */
1672             memset(staInfo->peerControlledPort, 0, sizeof(unifi_port_cfg_t));
1673             staInfo->peerControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
1674             staInfo->peerControlledPort->in_use = FALSE;
1675             interfacePriv->controlled_data_port.entries_in_use--;
1676
1677             memset(staInfo->peerUnControlledPort, 0, sizeof(unifi_port_cfg_t));
1678             staInfo->peerUnControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
1679             staInfo->peerUnControlledPort->in_use = FALSE;
1680             interfacePriv->uncontrolled_data_port.entries_in_use--;
1681
1682             kfree(interfacePriv->staInfo[i]);
1683             interfacePriv->staInfo[i] = NULL;
1684             spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
1685         }
1686     }
1687     /* after the critical region process the list of frames that requested cfm
1688      * and send cfm to requestor one by one
1689      */
1690     send_auto_ma_packet_confirm(priv, interfacePriv, &send_cfm_list);
1691
1692 #ifdef CSR_SUPPORT_SME
1693     /* Interface Independent, no of packet queued, incase of mode is None or AP set to 0 */
1694     switch(interfacePriv->interfaceMode)
1695     {
1696         case CSR_WIFI_ROUTER_CTRL_MODE_AP:
1697         case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
1698         case CSR_WIFI_ROUTER_CTRL_MODE_NONE:
1699             if (priv->noOfPktQueuedInDriver) {
1700                 unifi_warning(priv, "After reset the noOfPktQueuedInDriver = %x\n", priv->noOfPktQueuedInDriver);
1701                 spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
1702                 priv->noOfPktQueuedInDriver = 0;
1703                 spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
1704             }
1705             break;
1706         case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
1707             break;
1708         default:
1709             unifi_error(priv, "interfacemode is not correct in CsrWifiRouterCtrlResetStationRecordList: debug\n");
1710     }
1711 #endif
1712
1713     if (((interfacePriv->controlled_data_port.entries_in_use != 0) || (interfacePriv->uncontrolled_data_port.entries_in_use != 0))
1714             && (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_NONE)) {
1715         /* Print in case if the value of entries goes to -ve/+ve (apart from 0)
1716          * we expect the entries should be zero here if mode is set as NONE
1717          */
1718         unifi_trace(priv, UDBG3, "In %s controlled port entries = %d, uncontrolled port entries = %d\n",
1719                    __FUNCTION__, interfacePriv->controlled_data_port.entries_in_use,
1720                    interfacePriv->uncontrolled_data_port.entries_in_use);
1721     }
1722 }
1723
1724 void CsrWifiRouterCtrlInterfaceReset(unifi_priv_t *priv, u16 interfaceTag)
1725 {
1726     netInterface_priv_t *interfacePriv;
1727
1728     /* create a list for sending confirms of un-delivered packets */
1729     struct list_head send_cfm_list;
1730
1731     if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
1732         unifi_error(priv, "CsrWifiRouterCtrlInterfaceReset: bad interfaceTag\n");
1733         return;
1734     }
1735
1736     interfacePriv = priv->interfacePriv[interfaceTag];
1737
1738     INIT_LIST_HEAD(&send_cfm_list);
1739
1740     /* Enable all queues by default */
1741     interfacePriv->queueEnabled[0] = 1;
1742     interfacePriv->queueEnabled[1] = 1;
1743     interfacePriv->queueEnabled[2] = 1;
1744     interfacePriv->queueEnabled[3] = 1;
1745
1746     uf_prepare_send_cfm_list_for_queued_pkts(priv,
1747                                              &send_cfm_list,
1748                                              &(interfacePriv->genericMgtFrames));
1749     uf_flush_list(priv,&(interfacePriv->genericMgtFrames));
1750
1751     uf_prepare_send_cfm_list_for_queued_pkts(priv,
1752                                              &send_cfm_list,
1753                                              &(interfacePriv->genericMulticastOrBroadCastMgtFrames));
1754     uf_flush_list(priv,&(interfacePriv->genericMulticastOrBroadCastMgtFrames));
1755
1756     uf_prepare_send_cfm_list_for_queued_pkts(priv,
1757                                              &send_cfm_list,
1758                                              &(interfacePriv->genericMulticastOrBroadCastFrames));
1759
1760     uf_flush_list(priv,&(interfacePriv->genericMulticastOrBroadCastFrames));
1761
1762     /*  process the list of frames that requested cfm
1763     and send cfm to requestor one by one */
1764     send_auto_ma_packet_confirm(priv, interfacePriv, &send_cfm_list);
1765
1766     /* Reset the station record to NULL if mode is tried to set as NONE */
1767     switch(interfacePriv->interfaceMode)
1768     {
1769         case CSR_WIFI_ROUTER_CTRL_MODE_STA:
1770         case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
1771         case CSR_WIFI_ROUTER_CTRL_MODE_MONITOR:
1772         case CSR_WIFI_ROUTER_CTRL_MODE_AMP:
1773             /* station records not available in these modes */
1774             break;
1775         default:
1776             CsrWifiRouterCtrlResetStationRecordList(priv,interfaceTag);
1777     }
1778
1779     interfacePriv->num_stations_joined = 0;
1780     interfacePriv->sta_activity_check_enabled = FALSE;
1781 }
1782
1783
1784 void CsrWifiRouterCtrlModeSetReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1785 {
1786     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1787     CsrWifiRouterCtrlModeSetReq* req = (CsrWifiRouterCtrlModeSetReq*)msg;
1788
1789     if (priv == NULL)
1790     {
1791         unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: invalid smepriv\n");
1792         return;
1793     }
1794
1795     if (req->interfaceTag < CSR_WIFI_NUM_INTERFACES)
1796     {
1797         netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
1798 #ifdef CSR_WIFI_SPLIT_PATCH
1799         u8 old_mode = interfacePriv->interfaceMode;
1800 #endif
1801         unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlModeSetReqHandler: interfacePriv->interfaceMode = %d\n",
1802                 interfacePriv->interfaceMode);
1803
1804         interfacePriv->interfaceMode = req->mode;
1805
1806 #ifdef CSR_WIFI_SPLIT_PATCH
1807         /* Detect a change in mode that requires a switch to/from the AP firmware patch.
1808          * This should only happen when transitioning in/out of AP modes.
1809          */
1810         if (CSR_WIFI_HIP_IS_AP_FW(req->mode) != CSR_WIFI_HIP_IS_AP_FW(old_mode))
1811         {
1812             CsrWifiRouterCtrlVersions versions;
1813             int r;
1814
1815 #ifdef ANDROID_BUILD
1816             /* Take the wakelock while switching patch */
1817             unifi_trace(priv, UDBG1, "patch switch: take wake lock\n");
1818             wake_lock(&unifi_sdio_wake_lock);
1819 #endif
1820             unifi_info(priv, "Resetting UniFi with %s patch\n", CSR_WIFI_HIP_IS_AP_FW(req->mode) ? "AP" : "STA");
1821
1822             r = uf_request_firmware_files(priv, UNIFI_FW_STA);
1823             if (r) {
1824                 unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: Failed to get f/w\n");
1825                 CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
1826                                                 req->mode, CSR_RESULT_FAILURE);
1827                 return;
1828             }
1829
1830             /* Block the I/O thread */
1831             priv->bh_thread.block_thread = 1;
1832
1833             /* Reset and download the new patch */
1834             r = uf_init_hw(priv);
1835             if (r) {
1836                 unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to initialise h/w, error %d\n", r);
1837                 CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
1838                                                 req->mode, CSR_RESULT_FAILURE);
1839                 return;
1840             }
1841
1842             /* Re-enable the I/O thread */
1843             priv->bh_thread.block_thread = 0;
1844
1845             /* Get the version information from the core */
1846             unifi_card_info(priv->card, &priv->card_info);
1847
1848             /* Copy to the unifiio_card_info structure. */
1849             versions.chipId = priv->card_info.chip_id;
1850             versions.chipVersion = priv->card_info.chip_version;
1851             versions.firmwareBuild = priv->card_info.fw_build;
1852             versions.firmwareHip = priv->card_info.fw_hip_version;
1853             versions.routerBuild = (char*)CSR_WIFI_VERSION;
1854             versions.routerHip = (UNIFI_HIP_MAJOR_VERSION << 8) | UNIFI_HIP_MINOR_VERSION;
1855
1856             /* Now that new firmware is running, send a WifiOnInd to the NME. This will
1857              * cause it to retransfer the MIB.
1858              */
1859             CsrWifiRouterCtrlWifiOnIndSend(msg->source, 0, CSR_RESULT_SUCCESS, versions);
1860
1861             /* Store the request so we know where to send the ModeSetCfm */
1862             priv->pending_mode_set = *req;
1863         }
1864         else
1865 #endif
1866         {
1867             /* No patch switch, confirm straightaway */
1868             CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
1869                                             req->mode, CSR_RESULT_SUCCESS);
1870         }
1871
1872         interfacePriv->bssid = req->bssid;
1873         /* For modes other than AP/P2PGO, set below member FALSE */
1874         interfacePriv->intraBssEnabled = FALSE;
1875         /* Initialise the variable bcTimSet with a value
1876          * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
1877          */
1878         interfacePriv->bcTimSet = 0xFF;
1879         interfacePriv->bcTimSetReqPendingFlag = FALSE;
1880         /* Initialise the variable bcTimSetReqQueued with a value
1881          * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
1882          */
1883         interfacePriv->bcTimSetReqQueued =0xFF;
1884         CsrWifiRouterCtrlInterfaceReset(priv,req->interfaceTag);
1885
1886         if(req->mode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
1887            req->mode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
1888             interfacePriv->protect = req->protection;
1889             interfacePriv->dtimActive=FALSE;
1890             interfacePriv->multicastPduHostTag = 0xffffffff;
1891             /* For AP/P2PGO mode SME sending intraBssDistEnabled
1892              * i.e. for AP: intraBssDistEnabled = TRUE, for P2PGO
1893              * intraBssDistEnabled = TRUE/FALSE on requirement
1894              */
1895             interfacePriv->intraBssEnabled = req->intraBssDistEnabled;
1896             unifi_trace(priv, UDBG3, "CsrWifiRouterCtrlModeSetReqHandler: IntraBssDisEnabled = %d\n",
1897                         req->intraBssDistEnabled);
1898         } else if (req->mode == CSR_WIFI_ROUTER_CTRL_MODE_NONE) {
1899               netif_carrier_off(priv->netdev[req->interfaceTag]);
1900               interfacePriv->connected = UnifiConnectedUnknown;
1901         }
1902     }
1903     else {
1904         unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: invalid interfaceTag :%d\n",req->interfaceTag);
1905     }
1906 }
1907
1908 void CsrWifiRouterMaPacketResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1909 {
1910 }
1911
1912 /* delete the station record from the station record data base */
1913 static int peer_delete_record(unifi_priv_t *priv, CsrWifiRouterCtrlPeerDelReq *req)
1914 {
1915     u8 j;
1916     CsrWifiRouterCtrlStaInfo_t *staInfo = NULL;
1917     unifi_port_config_t *controlledPort;
1918     unifi_port_config_t *unControlledPort;
1919     netInterface_priv_t *interfacePriv;
1920
1921     u8 ba_session_idx = 0;
1922     ba_session_rx_struct *ba_session_rx = NULL;
1923     ba_session_tx_struct *ba_session_tx = NULL;
1924
1925     /* create a list for sending confirms of un-delivered packets */
1926     struct list_head send_cfm_list;
1927
1928     unsigned long lock_flags;
1929
1930     if ((req->peerRecordHandle >= UNIFI_MAX_CONNECTIONS) || (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES)) {
1931         unifi_error(priv, "handle/interfaceTag is not proper, handle = %d, interfaceTag = %d\n", req->peerRecordHandle, req->interfaceTag);
1932         return CSR_RESULT_FAILURE;
1933     }
1934
1935     INIT_LIST_HEAD(&send_cfm_list);
1936
1937     interfacePriv = priv->interfacePriv[req->interfaceTag];
1938     /* remove the station record & make it NULL */
1939     if ((staInfo=interfacePriv->staInfo[req->peerRecordHandle])!=NULL) {
1940
1941         uf_prepare_send_cfm_list_for_queued_pkts(priv,
1942                                                  &send_cfm_list,
1943                                                  &(staInfo->mgtFrames));
1944
1945         uf_flush_list(priv,&(staInfo->mgtFrames));
1946         for(j=0;j<MAX_ACCESS_CATOGORY;j++){
1947             uf_prepare_send_cfm_list_for_queued_pkts(priv,
1948                                                      &send_cfm_list,
1949                                                      &(staInfo->dataPdu[j]));
1950             uf_flush_list(priv,&(staInfo->dataPdu[j]));
1951         }
1952
1953         spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
1954         /* clear the port configure array info, for the corresponding peer entry */
1955         controlledPort = &interfacePriv->controlled_data_port;
1956         unControlledPort = &interfacePriv->uncontrolled_data_port;
1957
1958         unifi_trace(priv, UDBG1, "peer_delete_record: Peer found handle = %d, port in use: cont(%d), unCont(%d)\n",
1959                     req->peerRecordHandle, controlledPort->entries_in_use, unControlledPort->entries_in_use);
1960
1961         memset(staInfo->peerControlledPort, 0, sizeof(unifi_port_cfg_t));
1962         staInfo->peerControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
1963         staInfo->peerControlledPort->in_use = FALSE;
1964         if (controlledPort->entries_in_use) {
1965             controlledPort->entries_in_use--;
1966         } else {
1967             unifi_warning(priv, "number of controlled port entries is zero, trying to decrement: debug\n");
1968         }
1969
1970         memset(staInfo->peerUnControlledPort, 0, sizeof(unifi_port_cfg_t));
1971         staInfo->peerUnControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
1972         staInfo->peerUnControlledPort->in_use = FALSE;
1973         if (unControlledPort->entries_in_use) {
1974             unControlledPort->entries_in_use--;
1975         } else {
1976             unifi_warning(priv, "number of uncontrolled port entries is zero, trying to decrement: debug\n");
1977         }
1978
1979         spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
1980         /* update the TIM with zero */
1981         if (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_IBSS &&
1982                 staInfo->timSet == CSR_WIFI_TIM_SET) {
1983             unifi_trace(priv, UDBG3, "peer is deleted so TIM updated to 0, in firmware\n");
1984             update_tim(priv,staInfo->aid,0,req->interfaceTag, req->peerRecordHandle);
1985         }
1986
1987
1988         /* Stop BA session if it is active, for this peer address all BA sessions
1989         (per tID per role) are closed */
1990
1991         down(&priv->ba_mutex);
1992         for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
1993             ba_session_rx = priv->interfacePriv[req->interfaceTag]->ba_session_rx[ba_session_idx];
1994             if(ba_session_rx) {
1995                 if(!memcmp(ba_session_rx->macAddress.a, staInfo->peerMacAddress.a, ETH_ALEN)){
1996                     blockack_session_stop(priv,
1997                                         req->interfaceTag,
1998                                         CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT,
1999                                         ba_session_rx->tID,
2000                                         ba_session_rx->macAddress);
2001                 }
2002             }
2003         }
2004
2005         for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){
2006             ba_session_tx = priv->interfacePriv[req->interfaceTag]->ba_session_tx[ba_session_idx];
2007             if(ba_session_tx) {
2008                 if(!memcmp(ba_session_tx->macAddress.a, staInfo->peerMacAddress.a, ETH_ALEN)){
2009                     blockack_session_stop(priv,
2010                                         req->interfaceTag,
2011                                         CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR,
2012                                         ba_session_tx->tID,
2013                                         ba_session_tx->macAddress);
2014                 }
2015             }
2016         }
2017
2018         up(&priv->ba_mutex);
2019
2020 #ifdef CSR_SUPPORT_SME
2021         unifi_trace(priv, UDBG1, "Canceling work queue for STA with AID: %d\n", staInfo->aid);
2022         cancel_work_sync(&staInfo->send_disconnected_ind_task);
2023 #endif
2024
2025         spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2026 #ifdef CSR_SUPPORT_SME
2027         interfacePriv->num_stations_joined--;
2028
2029         staInfo->nullDataHostTag = INVALID_HOST_TAG;
2030
2031         if ((interfacePriv->sta_activity_check_enabled) &&
2032             (interfacePriv->num_stations_joined < STA_INACTIVE_DETECTION_TRIGGER_THRESHOLD))
2033         {
2034             unifi_trace(priv, UDBG1, "STOPPING the Inactivity Timer (num of stations = %d)\n", interfacePriv->num_stations_joined);
2035             interfacePriv->sta_activity_check_enabled = FALSE;
2036             del_timer_sync(&interfacePriv->sta_activity_check_timer);
2037         }
2038 #endif
2039
2040         /* Free the station record for corresponding peer */
2041         kfree(interfacePriv->staInfo[req->peerRecordHandle]);
2042         interfacePriv->staInfo[req->peerRecordHandle] = NULL;
2043         spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2044
2045         /* after the critical region process the list of frames that requested cfm
2046         and send cfm to requestor one by one */
2047         send_auto_ma_packet_confirm(priv, interfacePriv, &send_cfm_list);
2048
2049
2050     }
2051     else
2052     {
2053         unifi_trace(priv, UDBG3, " peer not found: Delete request Peer handle[%d]\n", req->peerRecordHandle);
2054     }
2055
2056     return CSR_RESULT_SUCCESS;
2057 }
2058
2059 void CsrWifiRouterCtrlPeerDelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2060 {
2061     CsrWifiRouterCtrlPeerDelReq* req = (CsrWifiRouterCtrlPeerDelReq*)msg;
2062     CsrResult status = CSR_RESULT_SUCCESS;
2063     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2064     netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
2065
2066     unifi_trace(priv, UDBG2, "entering CsrWifiRouterCtrlPeerDelReqHandler \n");
2067     if (priv == NULL)
2068     {
2069         unifi_error(priv, "CsrWifiRouterCtrlPeerDelReqHandler: invalid smepriv\n");
2070         return;
2071     }
2072
2073     if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES)
2074     {
2075         unifi_error(priv, "CsrWifiRouterCtrlPeerDelReqHandler: bad interfaceTag\n");
2076         return;
2077     }
2078
2079     switch(interfacePriv->interfaceMode)
2080     {
2081         case CSR_WIFI_ROUTER_CTRL_MODE_AP:
2082         case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
2083         case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
2084             /* remove the station from station record data base */
2085             status = peer_delete_record(priv, req);
2086             break;
2087         case CSR_WIFI_ROUTER_CTRL_MODE_STA:
2088         case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
2089         default:
2090             /* No station record to maintain in these modes */
2091             break;
2092     }
2093
2094     CsrWifiRouterCtrlPeerDelCfmSend(msg->source,req->clientData,req->interfaceTag,status);
2095     unifi_trace(priv, UDBG2, "leaving CsrWifiRouterCtrlPeerDelReqHandler \n");
2096 }
2097
2098 /* Add the new station to the station record data base */
2099 static int peer_add_new_record(unifi_priv_t *priv,CsrWifiRouterCtrlPeerAddReq *req,u32 *handle)
2100 {
2101     u8 i, powerModeTemp = 0;
2102     u8 freeSlotFound = FALSE;
2103     CsrWifiRouterCtrlStaInfo_t *newRecord = NULL;
2104     netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
2105     CsrTime currentTime, currentTimeHi;
2106     unsigned long lock_flags;
2107
2108     if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2109         unifi_error(priv, "peer_add_new_record: bad interfaceTag\n");
2110         return CSR_RESULT_FAILURE;
2111     }
2112
2113     currentTime = CsrTimeGet(&currentTimeHi);
2114
2115     for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
2116         if(interfacePriv->staInfo[i] == NULL) {
2117             /* Slot is empty, so can be used for station record */
2118             freeSlotFound = TRUE;
2119             *handle = i;
2120
2121             /* Allocate for the new station record , to avoid race condition would happen between ADD_PEER &
2122              * DEL_PEER the allocation made atomic memory rather than kernel memory
2123              */
2124             newRecord = kmalloc(sizeof(CsrWifiRouterCtrlStaInfo_t), GFP_ATOMIC);
2125             if (!newRecord) {
2126                 unifi_error(priv, "failed to allocate the %d bytes of mem for station record\n",
2127                             sizeof(CsrWifiRouterCtrlStaInfo_t));
2128                 return CSR_RESULT_FAILURE;
2129             }
2130
2131             unifi_trace(priv, UDBG1, "peer_add_new_record: handle = %d AID = %d addr = %x:%x:%x:%x:%x:%x LI=%u\n",
2132                         *handle, req->associationId, req->peerMacAddress.a[0], req->peerMacAddress.a[1], req->peerMacAddress.a[2],
2133                         req->peerMacAddress.a[3], req->peerMacAddress.a[4], req->peerMacAddress.a[5],
2134                         req->staInfo.listenIntervalInTus);
2135
2136             /* disable the preemption until station record updated */
2137             spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2138
2139             interfacePriv->staInfo[i] = newRecord;
2140             /* Initialize the record*/
2141             memset(newRecord,0,sizeof(CsrWifiRouterCtrlStaInfo_t));
2142             /* update the station record */
2143             memcpy(newRecord->peerMacAddress.a, req->peerMacAddress.a, ETH_ALEN);
2144             newRecord->wmmOrQosEnabled = req->staInfo.wmmOrQosEnabled;
2145
2146             /* maxSpLength is bit map in qosInfo field, so converting accordingly */
2147             newRecord->maxSpLength = req->staInfo.maxSpLength * 2;
2148
2149             /*Max SP 0 mean any number of packets. since we buffer only 512
2150             packets we are hard coding this to zero for the moment */
2151
2152             if(newRecord->maxSpLength == 0)
2153                 newRecord->maxSpLength=512;
2154
2155             newRecord->assignedHandle = i;
2156
2157              /* copy power save mode of all access catagory (Trigger/Delivery/both enabled/disabled) */
2158             powerModeTemp = (u8) ((req->staInfo.powersaveMode >> 4) & 0xff);
2159
2160             if(!(req->staInfo.powersaveMode & 0x0001))
2161                 newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BK]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
2162             else
2163                newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BK]= powerModeTemp & 0x03;
2164
2165             if(!(req->staInfo.powersaveMode & 0x0002))
2166                 newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BE]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
2167             else
2168                newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BE]= ((powerModeTemp & 0x0C)>> 2);
2169
2170             if(!(req->staInfo.powersaveMode & 0x0004))
2171                 newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VI]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
2172             else
2173                newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VI]= ((powerModeTemp & 0x30)>> 4);
2174
2175             if(!(req->staInfo.powersaveMode & 0x0008))
2176                 newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
2177             else
2178                newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]= ((powerModeTemp & 0xC0)>> 6);
2179
2180             {
2181                 u8 k;
2182                 for(k=0; k< MAX_ACCESS_CATOGORY ;k++)
2183                     unifi_trace(priv, UDBG2, "peer_add_new_record: WMM : %d ,AC %d, powersaveMode %x \n",
2184                             req->staInfo.wmmOrQosEnabled,k,newRecord->powersaveMode[k]);
2185             }
2186
2187             unifi_trace(priv, UDBG3, "newRecord->wmmOrQosEnabled : %d , MAX SP : %d\n",
2188                     newRecord->wmmOrQosEnabled,newRecord->maxSpLength);
2189
2190             /* Initialize the mgtFrames & data Pdu list */
2191             {
2192                 u8 j;
2193                 INIT_LIST_HEAD(&newRecord->mgtFrames);
2194                 for(j = 0; j < MAX_ACCESS_CATOGORY; j++) {
2195                     INIT_LIST_HEAD(&newRecord->dataPdu[j]);
2196                 }
2197             }
2198
2199             newRecord->lastActivity = currentTime;
2200             newRecord->activity_flag = TRUE;
2201
2202             /* enable the preemption as station record updated */
2203             spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2204
2205             /* First time port actions are set for the peer with below information */
2206             configure_data_port(priv, CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN, &newRecord->peerMacAddress,
2207                                 UF_UNCONTROLLED_PORT_Q, req->interfaceTag);
2208
2209             if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS) {
2210                 configure_data_port(priv, CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN, &newRecord->peerMacAddress,
2211                                     UF_CONTROLLED_PORT_Q, req->interfaceTag);
2212             } else {
2213                 configure_data_port(priv, CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD, &newRecord->peerMacAddress,
2214                                     UF_CONTROLLED_PORT_Q, req->interfaceTag);
2215             }
2216
2217
2218             spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2219             /* Port status must be already set before calling the Add Peer request */
2220             newRecord->peerControlledPort = uf_sme_port_config_handle(priv, newRecord->peerMacAddress.a,
2221                                                                       UF_CONTROLLED_PORT_Q, req->interfaceTag);
2222             newRecord->peerUnControlledPort = uf_sme_port_config_handle(priv, newRecord->peerMacAddress.a,
2223                                                                         UF_UNCONTROLLED_PORT_Q, req->interfaceTag);
2224
2225             if (!newRecord->peerControlledPort || !newRecord->peerUnControlledPort) {
2226                 /* enable the preemption as station record failed to update */
2227                 unifi_warning(priv, "Un/ControlledPort record not found in port configuration array index = %d\n", i);
2228                 kfree(interfacePriv->staInfo[i]);
2229                 interfacePriv->staInfo[i] = NULL;
2230                 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2231                 return CSR_RESULT_FAILURE;
2232             }
2233
2234             newRecord->currentPeerState = CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE;
2235
2236             /* changes done during block ack handling */
2237             newRecord->txSuspend = FALSE;
2238
2239             /*U-APSD related data structure*/
2240             newRecord->timRequestPendingFlag = FALSE;
2241
2242             /* Initialise the variable updateTimReqQueued with a value
2243              * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
2244              */
2245             newRecord->updateTimReqQueued = 0xFF;
2246             newRecord->timSet = CSR_WIFI_TIM_RESET;
2247             newRecord->uapsdActive = FALSE;
2248             newRecord->noOfSpFramesSent =0;
2249             newRecord->triggerFramePriority = CSR_QOS_UP0;
2250
2251             /* The protection bit is updated once the port opens for corresponding peer in
2252              * routerPortConfigure request */
2253
2254             /* update the association ID */
2255             newRecord->aid = req->associationId;
2256
2257 #ifdef CSR_SUPPORT_SME
2258             interfacePriv->num_stations_joined++;
2259             newRecord->interfacePriv = interfacePriv;
2260             newRecord->listenIntervalInTus = req->staInfo.listenIntervalInTus;
2261             newRecord->nullDataHostTag = INVALID_HOST_TAG;
2262
2263             INIT_WORK(&newRecord->send_disconnected_ind_task, uf_send_disconnected_ind_wq);
2264
2265             if(!(interfacePriv->sta_activity_check_enabled) &&
2266                (interfacePriv->num_stations_joined >= STA_INACTIVE_DETECTION_TRIGGER_THRESHOLD)){
2267                 unifi_trace(priv, UDBG1,
2268                             "peer_add_new_record: STARTING the Inactivity Timer (num of stations = %d)",
2269                             interfacePriv->num_stations_joined);
2270
2271                 interfacePriv->sta_activity_check_enabled = TRUE;
2272                 interfacePriv->sta_activity_check_timer.function = check_inactivity_timer_expire_func;
2273                 interfacePriv->sta_activity_check_timer.data = (unsigned long)interfacePriv;
2274
2275                 init_timer(&interfacePriv->sta_activity_check_timer);
2276                 mod_timer(&interfacePriv->sta_activity_check_timer,
2277                           (jiffies + usecs_to_jiffies(STA_INACTIVE_DETECTION_TIMER_INTERVAL * 1000 * 1000)));
2278
2279             }
2280 #endif
2281             spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2282             break;
2283         }
2284     }
2285
2286     if(!freeSlotFound) {
2287         unifi_error(priv, "Limited connectivity, Free slot not found for station record addition\n");
2288         return CSR_RESULT_FAILURE;
2289     }
2290     return CSR_RESULT_SUCCESS;
2291 }
2292
2293 #ifdef CSR_SUPPORT_SME
2294 static void check_inactivity_timer_expire_func(unsigned long data)
2295 {
2296     struct unifi_priv *priv;
2297     CsrWifiRouterCtrlStaInfo_t *sta_record = NULL;
2298     u8 i = 0;
2299     CsrTime now;
2300     CsrTime inactive_time;
2301     netInterface_priv_t *interfacePriv = (netInterface_priv_t *) data;
2302
2303     if (!interfacePriv)
2304     {
2305         return;
2306     }
2307
2308     priv = interfacePriv->privPtr;
2309
2310     if (interfacePriv->InterfaceTag >= CSR_WIFI_NUM_INTERFACES)
2311     {
2312         unifi_error(priv, "check_inactivity_timer_expire_func: Invalid interfaceTag\n");
2313         return;
2314     }
2315
2316     /* RUN Algorithm to check inactivity for each connected station */
2317     now = CsrTimeGet(NULL);
2318
2319     for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
2320         if(interfacePriv->staInfo[i] != NULL) {
2321             sta_record = interfacePriv->staInfo[i];
2322
2323             if (sta_record->activity_flag == TRUE){
2324                 sta_record->activity_flag = FALSE;
2325                 sta_record->lastActivity = now;
2326                 continue;
2327             }
2328
2329             if (sta_record->lastActivity > now)
2330             {
2331                 /* simple timer wrap (for 1 wrap) */
2332                 inactive_time = CsrTimeAdd((CsrTime)CsrTimeSub(CSR_SCHED_TIME_MAX, sta_record->lastActivity), now);
2333             }
2334             else
2335             {
2336                 inactive_time = (CsrTime)CsrTimeSub(now, sta_record->lastActivity);
2337             }
2338
2339             if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL)
2340             {
2341                 unifi_trace(priv, UDBG1, "STA is Inactive - AID = %d inactive_time = %d\n",
2342                                         sta_record->aid,
2343                                         inactive_time);
2344
2345                 /* station is in-active, if it is in active mode send a null frame
2346                  * and the station should acknowledge the null frame, if acknowledgement
2347                  * is not received throw out the station.
2348                  * If the station is in Power Save, update TIM for the station so
2349                  * that it wakes up and register some activity through PS-Poll or
2350                  * trigger frame.
2351                  */
2352                  if (sta_record->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)
2353                  {
2354                     unifi_trace(priv, UDBG1, "STA power save state - Active, send a NULL frame to check if it is ALIVE\n");
2355                     uf_send_nulldata ( priv,
2356                                        sta_record->interfacePriv->InterfaceTag,
2357                                        sta_record->peerMacAddress.a,
2358                                        CSR_CONTENTION,
2359                                        sta_record);
2360                  }
2361                  else if (sta_record->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
2362                  {
2363                     if((sta_record->timSet == CSR_WIFI_TIM_SET) ||
2364                        (sta_record->timSet == CSR_WIFI_TIM_SETTING))
2365                     {
2366                         unifi_trace(priv, UDBG1, "STA power save state - PS, TIM is already SET\n");
2367
2368                         /* If TIM is set and we do not have any activity for
2369                          * more than 3 listen intervals then send a disconnected
2370                          * indication to SME, to delete the station from station
2371                          * record list.
2372                          * The inactivity is already more than STA_INACTIVE_TIMEOUT_VAL
2373                          * and this check ensures if the listen interval is a larger
2374                          * value than STA_INACTIVE_TIMEOUT_VAL.
2375                          */
2376                          if (inactive_time > (3 * (sta_record->listenIntervalInTus * 1024)))
2377                          {
2378                             unifi_trace(priv, UDBG1, "STA is inactive for more than 3 listen intervals\n");
2379                             queue_work( priv->unifi_workqueue,
2380                                         &sta_record->send_disconnected_ind_task);
2381                          }
2382
2383                     }
2384                     else
2385                     {
2386                         unifi_trace(priv, UDBG1, "STA power save state - PS, update TIM to see if it is ALIVE\n");
2387                         update_tim(priv,
2388                                    sta_record->aid,
2389                                    CSR_WIFI_TIM_SET,
2390                                    interfacePriv->InterfaceTag,
2391                                    sta_record->assignedHandle);
2392                     }
2393                  }
2394             }
2395         }
2396     }
2397
2398     /* re-run the timer interrupt */
2399     mod_timer(&interfacePriv->sta_activity_check_timer,
2400               (jiffies + usecs_to_jiffies(STA_INACTIVE_DETECTION_TIMER_INTERVAL * 1000 * 1000)));
2401
2402 }
2403
2404
2405 void uf_send_disconnected_ind_wq(struct work_struct *work)
2406 {
2407
2408     CsrWifiRouterCtrlStaInfo_t *staInfo = container_of(work, CsrWifiRouterCtrlStaInfo_t, send_disconnected_ind_task);
2409     unifi_priv_t *priv;
2410     u16 interfaceTag;
2411     struct list_head send_cfm_list;
2412     u8 j;
2413
2414     func_enter();
2415
2416     if(!staInfo) {
2417         return;
2418     }
2419
2420     if(!staInfo->interfacePriv) {
2421         return;
2422     }
2423
2424     priv = staInfo->interfacePriv->privPtr;
2425     interfaceTag =  staInfo->interfacePriv->InterfaceTag;
2426
2427     if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2428         unifi_error(priv, "uf_send_disconnected_ind_wq: invalid interfaceTag\n");
2429         return;
2430     }
2431
2432     /* The SME/NME may be waiting for confirmation for requested frames to this station.
2433      * So loop through buffered frames for this station and if confirmation is
2434      * requested, send auto confirmation with failure status. Also flush the frames so
2435      * that these are not processed again in PEER_DEL_REQ handler.
2436      */
2437     INIT_LIST_HEAD(&send_cfm_list);
2438
2439     uf_prepare_send_cfm_list_for_queued_pkts(priv,
2440                                              &send_cfm_list,
2441                                              &(staInfo->mgtFrames));
2442
2443     uf_flush_list(priv, &(staInfo->mgtFrames));
2444
2445     for(j = 0; j < MAX_ACCESS_CATOGORY; j++){
2446         uf_prepare_send_cfm_list_for_queued_pkts(priv,
2447                                                  &send_cfm_list,
2448                                                  &(staInfo->dataPdu[j]));
2449
2450         uf_flush_list(priv,&(staInfo->dataPdu[j]));
2451     }
2452
2453     send_auto_ma_packet_confirm(priv, staInfo->interfacePriv, &send_cfm_list);
2454
2455     unifi_warning(priv, "uf_send_disconnected_ind_wq: Router Disconnected IND Peer (%x-%x-%x-%x-%x-%x)\n",
2456                 staInfo->peerMacAddress.a[0],
2457                 staInfo->peerMacAddress.a[1],
2458                 staInfo->peerMacAddress.a[2],
2459                 staInfo->peerMacAddress.a[3],
2460                 staInfo->peerMacAddress.a[4],
2461                 staInfo->peerMacAddress.a[5]);
2462
2463     CsrWifiRouterCtrlConnectedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,
2464                                       0,
2465                                       staInfo->interfacePriv->InterfaceTag,
2466                                       staInfo->peerMacAddress,
2467                                       CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED);
2468
2469
2470     return;
2471 }
2472
2473
2474 #endif
2475 void CsrWifiRouterCtrlPeerAddReqHandler(void* drvpriv,CsrWifiFsmEvent* msg)
2476 {
2477     CsrWifiRouterCtrlPeerAddReq* req = (CsrWifiRouterCtrlPeerAddReq*)msg;
2478     CsrResult status = CSR_RESULT_SUCCESS;
2479     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2480     u32 handle = 0;
2481     netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
2482
2483     unifi_trace(priv, UDBG2, "entering CsrWifiRouterCtrlPeerAddReqHandler \n");
2484     if (priv == NULL)
2485     {
2486         unifi_error(priv, "CsrWifiRouterCtrlPeerAddReqHandler: invalid smepriv\n");
2487         return;
2488     }
2489
2490     if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES)
2491     {
2492         unifi_error(priv, "CsrWifiRouterCtrlPeerAddReqHandler: bad interfaceTag\n");
2493         return;
2494     }
2495
2496     switch(interfacePriv->interfaceMode)
2497     {
2498         case CSR_WIFI_ROUTER_CTRL_MODE_AP:
2499         case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
2500         case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
2501             /* Add station record */
2502             status = peer_add_new_record(priv,req,&handle);
2503             break;
2504         case CSR_WIFI_ROUTER_CTRL_MODE_STA:
2505         case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
2506         default:
2507             /* No station record to maintain in these modes */
2508             break;
2509     }
2510
2511     CsrWifiRouterCtrlPeerAddCfmSend(msg->source,req->clientData,req->interfaceTag,req->peerMacAddress,handle,status);
2512     unifi_trace(priv, UDBG2, "leaving CsrWifiRouterCtrlPeerAddReqHandler \n");
2513 }
2514
2515 void CsrWifiRouterCtrlPeerUpdateReqHandler(void* drvpriv,CsrWifiFsmEvent* msg)
2516 {
2517     CsrWifiRouterCtrlPeerUpdateReq* req = (CsrWifiRouterCtrlPeerUpdateReq*)msg;
2518     CsrResult status = CSR_RESULT_SUCCESS;
2519     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2520
2521     unifi_trace(priv, UDBG2, "entering CsrWifiRouterCtrlPeerUpdateReqHandler \n");
2522     if (priv == NULL)
2523     {
2524         unifi_error(priv, "CsrWifiRouterCtrlPeerUpdateReqHandler: invalid smepriv\n");
2525         return;
2526     }
2527
2528     CsrWifiRouterCtrlPeerUpdateCfmSend(msg->source,req->clientData,req->interfaceTag,status);
2529     unifi_trace(priv, UDBG2, "leaving CsrWifiRouterCtrlPeerUpdateReqHandler \n");
2530 }
2531
2532
2533  void CsrWifiRouterCtrlRawSdioDeinitialiseReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2534 {
2535     /* This will never be called as it is intercepted in the Userspace */
2536 }
2537
2538 void CsrWifiRouterCtrlRawSdioInitialiseReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2539 {
2540     /* This will never be called as it is intercepted in the Userspace */
2541 }
2542
2543 void
2544 uf_send_ba_err_wq(struct work_struct *work)
2545 {
2546     ba_session_rx_struct *ba_session = container_of(work, ba_session_rx_struct, send_ba_err_task);
2547     unifi_priv_t *priv;
2548
2549     if(!ba_session) {
2550         return;
2551     }
2552
2553     if(!ba_session->interfacePriv) {
2554         return;
2555     }
2556
2557     priv = ba_session->interfacePriv->privPtr;
2558
2559     if (ba_session->interfacePriv->InterfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2560         unifi_error(priv, "%s: invalid interfaceTag\n", __FUNCTION__);
2561         return;
2562     }
2563
2564     unifi_warning(priv, "%s: Calling CsrWifiRouterCtrlBlockAckErrorIndSend(%d, %d, %d, %d, %x:%x:%x:%x:%x:%x, %d)\n",
2565                     __FUNCTION__,
2566                     priv->CSR_WIFI_SME_IFACEQUEUE,
2567                     0,
2568                     ba_session->interfacePriv->InterfaceTag,
2569                     ba_session->tID,
2570                     ba_session->macAddress.a[0],
2571                     ba_session->macAddress.a[1],
2572                     ba_session->macAddress.a[2],
2573                     ba_session->macAddress.a[3],
2574                     ba_session->macAddress.a[4],
2575                     ba_session->macAddress.a[5],
2576                     CSR_RESULT_SUCCESS
2577                  );
2578     CsrWifiRouterCtrlBlockAckErrorIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,
2579                     0,
2580                     ba_session->interfacePriv->InterfaceTag,
2581                     ba_session->tID,
2582                     ba_session->macAddress,
2583                     CSR_RESULT_SUCCESS);
2584 }
2585
2586
2587 static void ba_session_terminate_timer_func(unsigned long data)
2588 {
2589     ba_session_rx_struct *ba_session = (ba_session_rx_struct*)data;
2590     struct unifi_priv *priv;
2591
2592     if(!ba_session) {
2593         return;
2594     }
2595
2596     if(!ba_session->interfacePriv) {
2597         return;
2598     }
2599
2600     priv = ba_session->interfacePriv->privPtr;
2601
2602     if (ba_session->interfacePriv->InterfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2603         unifi_error(priv, "%s: invalid interfaceTag\n", __FUNCTION__);
2604         return;
2605     }
2606
2607     queue_work(priv->unifi_workqueue, &ba_session->send_ba_err_task);
2608 }
2609
2610
2611 u8 blockack_session_stop(unifi_priv_t *priv,
2612                                      u16 interfaceTag,
2613                                      CsrWifiRouterCtrlBlockAckRole role,
2614                                      u16 tID,
2615                                      CsrWifiMacAddress macAddress)
2616 {
2617     netInterface_priv_t *interfacePriv;
2618     ba_session_rx_struct *ba_session_rx = NULL;
2619     ba_session_tx_struct *ba_session_tx = NULL;
2620     u8 ba_session_idx = 0;
2621     int i;
2622
2623     if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2624         unifi_error(priv, "%s: bad interfaceTag = %d\n", __FUNCTION__, interfaceTag);
2625         return FALSE;
2626     }
2627
2628     interfacePriv = priv->interfacePriv[interfaceTag];
2629
2630     if(!interfacePriv) {
2631         unifi_error(priv, "%s: bad interfacePriv\n", __FUNCTION__);
2632         return FALSE;
2633     }
2634
2635     if(tID > 15) {
2636         unifi_error(priv, "%s: bad tID = %d\n", __FUNCTION__, tID);
2637         return FALSE;
2638     }
2639
2640     if((role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR) &&
2641         (role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT)) {
2642         unifi_error(priv, "%s: bad role = %d\n", __FUNCTION__, role);
2643         return FALSE;
2644         }
2645
2646         unifi_warning(priv,
2647                 "%s: stopping ba_session for peer = %pM role = %d tID = %d\n",
2648                 __func__, macAddress.a, role, tID);
2649
2650     /* find out the appropriate ba session (/station /tid /role) for which stop is requested */
2651     if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT){
2652         for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
2653
2654             ba_session_rx = interfacePriv->ba_session_rx[ba_session_idx];
2655
2656             if(ba_session_rx){
2657                 if ((!memcmp(ba_session_rx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_rx->tID == tID)){
2658                     break;
2659                 }
2660             }
2661         }
2662
2663         if (!ba_session_rx || (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX)) {
2664             unifi_error(priv, "%s: bad ba_session for Rx [tID=%d]\n", __FUNCTION__, tID);
2665             return FALSE;
2666         }
2667
2668
2669         if(ba_session_rx->timeout) {
2670             del_timer_sync(&ba_session_rx->timer);
2671         }
2672         cancel_work_sync(&ba_session_rx->send_ba_err_task);
2673         for (i = 0; i < ba_session_rx->wind_size; i++) {
2674             if(ba_session_rx->buffer[i].active) {
2675                 frame_desc_struct *frame_desc = &ba_session_rx->buffer[i];
2676                 unifi_net_data_free(priv, &frame_desc->bulkdata.d[0]);
2677             }
2678         }
2679         kfree(ba_session_rx->buffer);
2680
2681         interfacePriv->ba_session_rx[ba_session_idx] = NULL;
2682         kfree(ba_session_rx);
2683     }else if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR){
2684         for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){
2685         ba_session_tx = interfacePriv->ba_session_tx[ba_session_idx];
2686             if(ba_session_tx){
2687                 if ((!memcmp(ba_session_tx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_tx->tID == tID)){
2688                     break;
2689                 }
2690             }
2691         }
2692
2693         if (!ba_session_tx || (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_TX)) {
2694             unifi_error(priv, "%s: bad ba_session for Tx [tID=%d]\n", __FUNCTION__, tID);
2695             return FALSE;
2696         }
2697         interfacePriv->ba_session_tx[ba_session_idx] = NULL;
2698         kfree(ba_session_tx);
2699
2700     }
2701
2702     return TRUE;
2703 }
2704
2705
2706 void CsrWifiRouterCtrlBlockAckDisableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2707 {
2708     CsrWifiRouterCtrlBlockAckDisableReq* req = (CsrWifiRouterCtrlBlockAckDisableReq*)msg;
2709     u8 r;
2710     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2711
2712     unifi_trace(priv, UDBG6, "%s: in ok\n", __FUNCTION__);
2713
2714     down(&priv->ba_mutex);
2715     r = blockack_session_stop(priv,
2716                               req->interfaceTag,
2717                               req->role,
2718                               req->trafficStreamID,
2719                               req->macAddress);
2720     up(&priv->ba_mutex);
2721
2722     CsrWifiRouterCtrlBlockAckDisableCfmSend(msg->source,
2723                                             req->clientData,
2724                                             req->interfaceTag,
2725                                             r?CSR_RESULT_SUCCESS:CSR_RESULT_FAILURE);
2726
2727     unifi_trace(priv, UDBG6, "%s: out ok\n", __FUNCTION__);
2728 }
2729
2730
2731 u8 blockack_session_start(unifi_priv_t *priv,
2732                                u16 interfaceTag,
2733                                u16 tID,
2734                                u16 timeout,
2735                                CsrWifiRouterCtrlBlockAckRole role,
2736                                u16 wind_size,
2737                                u16 start_sn,
2738                                CsrWifiMacAddress macAddress
2739                               )
2740 {
2741     netInterface_priv_t *interfacePriv;
2742     ba_session_rx_struct *ba_session_rx = NULL;
2743     ba_session_tx_struct *ba_session_tx = NULL;
2744     u8 ba_session_idx = 0;
2745
2746
2747     if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2748         unifi_error(priv, "%s: bad interfaceTag = %d\n", __FUNCTION__, interfaceTag);
2749         return FALSE;
2750     }
2751
2752     interfacePriv = priv->interfacePriv[interfaceTag];
2753
2754     if(!interfacePriv) {
2755         unifi_error(priv, "%s: bad interfacePriv\n", __FUNCTION__);
2756         return FALSE;
2757     }
2758
2759     if(tID > 15)
2760     {
2761         unifi_error(priv, "%s: bad tID=%d\n", __FUNCTION__, tID);
2762         return FALSE;
2763     }
2764
2765     if(wind_size > MAX_BA_WIND_SIZE) {
2766         unifi_error(priv, "%s: bad wind_size = %d\n", __FUNCTION__, wind_size);
2767         return FALSE;
2768     }
2769
2770     if(role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR &&
2771        role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT) {
2772         unifi_error(priv, "%s: bad role = %d\n", __FUNCTION__, role);
2773         return FALSE;
2774     }
2775
2776         unifi_warning(priv,
2777                 "%s: ba session with peer= (%pM)\n", __func__,
2778                 macAddress.a);
2779
2780     unifi_warning(priv, "%s: ba session for tID=%d timeout=%d role=%d wind_size=%d start_sn=%d\n", __FUNCTION__,
2781                   tID,
2782                   timeout,
2783                   role,
2784                   wind_size,
2785                   start_sn);
2786
2787     /* Check if BA session exists for per station, per TID, per role or not.
2788     if BA session exists update parameters and if it does not exist
2789     create a new BA session */
2790     if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR){
2791         for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){
2792             ba_session_tx = interfacePriv->ba_session_tx[ba_session_idx];
2793             if (ba_session_tx) {
2794                 if ((!memcmp(ba_session_tx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_tx->tID == tID)){
2795                     unifi_warning(priv, "%s: ba_session for Tx already exists\n", __FUNCTION__);
2796                     return TRUE;
2797                 }
2798             }
2799         }
2800
2801         /* we have to create new ba_session_tx struct */
2802          ba_session_tx = NULL;
2803
2804         /* loop through until an empty BA session slot is there and save the session there */
2805         for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX ; ba_session_idx++){
2806             if (!(interfacePriv->ba_session_tx[ba_session_idx])){
2807                 break;
2808             }
2809         }
2810         if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_TX){
2811             unifi_error(priv, "%s: All ba_session used for Tx, NO free session available\n", __FUNCTION__);
2812             return FALSE;
2813         }
2814
2815         /* create and populate the new BA session structure */
2816         ba_session_tx = kzalloc(sizeof(ba_session_tx_struct), GFP_KERNEL);
2817         if (!ba_session_tx) {
2818             unifi_error(priv, "%s: kmalloc failed for ba_session_tx\n", __FUNCTION__);
2819             return FALSE;
2820         }
2821
2822         ba_session_tx->interfacePriv = interfacePriv;
2823         ba_session_tx->tID = tID;
2824         ba_session_tx->macAddress = macAddress;
2825
2826         interfacePriv->ba_session_tx[ba_session_idx] = ba_session_tx;
2827
2828     } else if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT){
2829
2830         for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
2831             ba_session_rx = interfacePriv->ba_session_rx[ba_session_idx];
2832             if (ba_session_rx) {
2833                 if ((!memcmp(ba_session_rx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_rx->tID == tID)){
2834                     unifi_warning(priv, "%s: ba_session for Rx[tID = %d] already exists\n", __FUNCTION__, tID);
2835
2836                     if(ba_session_rx->wind_size == wind_size &&
2837                         ba_session_rx->timeout == timeout &&
2838                         ba_session_rx->expected_sn == start_sn) {
2839                         return TRUE;
2840                     }
2841
2842                     if(ba_session_rx->timeout) {
2843                         del_timer_sync(&ba_session_rx->timer);
2844                         ba_session_rx->timeout = 0;
2845                     }
2846
2847                     if(ba_session_rx->wind_size != wind_size) {
2848                         blockack_session_stop(priv, interfaceTag, role, tID, macAddress);
2849                     } else {
2850                         if (timeout) {
2851                             ba_session_rx->timeout = timeout;
2852                             ba_session_rx->timer.function = ba_session_terminate_timer_func;
2853                             ba_session_rx->timer.data = (unsigned long)ba_session_rx;
2854                             init_timer(&ba_session_rx->timer);
2855                             mod_timer(&ba_session_rx->timer, (jiffies + usecs_to_jiffies((ba_session_rx->timeout) * 1024)));
2856                         }
2857                         /*
2858                          * The starting sequence number shall remain same if the BA
2859                          * enable request is issued to update BA parameters only. If
2860                          * it is not same, then we scroll our window to the new starting
2861                          * sequence number. This could happen if the DELBA frame from
2862                          * originator is lost and then we receive ADDBA frame with new SSN.
2863                         */
2864                         if(ba_session_rx->start_sn != start_sn) {
2865                             scroll_ba_window(priv, interfacePriv, ba_session_rx, start_sn);
2866                         }
2867                         return TRUE;
2868                     }
2869                 }
2870             }
2871         }
2872
2873         /* we could have a valid BA session pointer here or un-initialized
2874         ba session pointer. but in any case we have to create a new session.
2875         so re-initialize the ba_session pointer */
2876         ba_session_rx = NULL;
2877
2878         /* loop through until an empty BA session slot is there and save the session there */
2879         for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX ; ba_session_idx++){
2880             if (!(interfacePriv->ba_session_rx[ba_session_idx])){
2881                 break;
2882             }
2883         }
2884         if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX){
2885             unifi_error(priv, "%s: All ba_session used for Rx, NO free session available\n", __FUNCTION__);
2886             return FALSE;
2887         }
2888
2889         /* It is observed that with some devices there is a race between
2890          * EAPOL exchanges and BA session establishment. This results in
2891          * some EAPOL authentication packets getting stuck in BA reorder
2892          * buffer and hence the conection cannot be established. To avoid
2893          * this we check here if the EAPOL authentication is complete and
2894          * if so then only allow the BA session to establish.
2895          *
2896          * It is verified that the peers normally re-establish
2897          * the BA session after the initial rejection.
2898          */
2899         if (CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN != uf_sme_port_state(priv, macAddress.a, UF_CONTROLLED_PORT_Q, interfacePriv->InterfaceTag))
2900         {
2901             unifi_warning(priv, "blockack_session_start: Controlled port not opened, Reject BA request\n");
2902             return FALSE;
2903         }
2904
2905         ba_session_rx = kzalloc(sizeof(ba_session_rx_struct), GFP_KERNEL);
2906         if (!ba_session_rx) {
2907             unifi_error(priv, "%s: kmalloc failed for ba_session_rx\n", __FUNCTION__);
2908             return FALSE;
2909         }
2910
2911         ba_session_rx->wind_size = wind_size;
2912         ba_session_rx->start_sn = ba_session_rx->expected_sn = start_sn;
2913         ba_session_rx->trigger_ba_after_ssn = FALSE;
2914
2915         ba_session_rx->buffer = kzalloc(ba_session_rx->wind_size*sizeof(frame_desc_struct), GFP_KERNEL);
2916         if (!ba_session_rx->buffer) {
2917             kfree(ba_session_rx);
2918             unifi_error(priv, "%s: kmalloc failed for buffer\n", __FUNCTION__);
2919             return FALSE;
2920         }
2921
2922         INIT_WORK(&ba_session_rx->send_ba_err_task, uf_send_ba_err_wq);
2923         if (timeout) {
2924             ba_session_rx->timeout = timeout;
2925             ba_session_rx->timer.function = ba_session_terminate_timer_func;
2926             ba_session_rx->timer.data = (unsigned long)ba_session_rx;
2927             init_timer(&ba_session_rx->timer);
2928             mod_timer(&ba_session_rx->timer, (jiffies + usecs_to_jiffies((ba_session_rx->timeout) * 1024)));
2929         }
2930
2931         ba_session_rx->interfacePriv = interfacePriv;
2932         ba_session_rx->tID = tID;
2933         ba_session_rx->macAddress = macAddress;
2934
2935         interfacePriv->ba_session_rx[ba_session_idx] = ba_session_rx;
2936     }
2937     return TRUE;
2938 }
2939
2940 void CsrWifiRouterCtrlBlockAckEnableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2941 {
2942     CsrWifiRouterCtrlBlockAckEnableReq* req = (CsrWifiRouterCtrlBlockAckEnableReq*)msg;
2943     u8 r;
2944     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2945
2946     unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
2947     down(&priv->ba_mutex);
2948     r = blockack_session_start(priv,
2949                                req->interfaceTag,
2950                                req->trafficStreamID,
2951                                req->timeout,
2952                                req->role,
2953                                req->bufferSize,
2954                                req->ssn,
2955                                req->macAddress
2956                               );
2957     up(&priv->ba_mutex);
2958
2959     CsrWifiRouterCtrlBlockAckEnableCfmSend(msg->source,
2960                                            req->clientData,
2961                                            req->interfaceTag,
2962                                            r?CSR_RESULT_SUCCESS:CSR_RESULT_FAILURE);
2963     unifi_trace(priv, UDBG6, "<<%s: r=%d\n", __FUNCTION__, r);
2964
2965 }
2966
2967 void CsrWifiRouterCtrlWapiMulticastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2968 {
2969 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
2970
2971     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2972     CsrWifiRouterCtrlWapiMulticastFilterReq* req = (CsrWifiRouterCtrlWapiMulticastFilterReq*)msg;
2973     netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
2974
2975     if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
2976
2977         unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
2978
2979         unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiMulticastFilterReq: req->status = %d\n", req->status);
2980
2981         /* status 1 - Filter on
2982         * status 0 - Filter off */
2983         priv->wapi_multicast_filter = req->status;
2984
2985         unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
2986     } else {
2987
2988         unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
2989
2990     }
2991 #elif defined(UNIFI_DEBUG)
2992     /*WAPI Disabled*/
2993     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2994     unifi_error(priv,"CsrWifiRouterCtrlWapiMulticastFilterReqHandler: called when WAPI isn't enabled\n");
2995 #endif
2996 }
2997
2998 void CsrWifiRouterCtrlWapiUnicastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2999 {
3000 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
3001
3002     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3003     CsrWifiRouterCtrlWapiUnicastFilterReq* req = (CsrWifiRouterCtrlWapiUnicastFilterReq*)msg;
3004     netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
3005
3006     if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
3007
3008         unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
3009
3010         unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastFilterReq: req->status= %d\n", req->status);
3011
3012         if ((priv->wapi_unicast_filter == 1) && (req->status == 0)) {
3013             /* When we have successfully re-associated and obtained a new unicast key with keyid = 0 */
3014             priv->wapi_unicast_queued_pkt_filter = 1;
3015         }
3016
3017         /* status 1 - Filter ON
3018          * status 0 - Filter OFF */
3019         priv->wapi_unicast_filter = req->status;
3020
3021         unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
3022     } else {
3023
3024          unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
3025
3026     }
3027 #elif defined(UNIFI_DEBUG)
3028     /*WAPI Disabled*/
3029     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3030     unifi_error(priv,"CsrWifiRouterCtrlWapiUnicastFilterReqHandler: called when WAPI isn't enabled\n");
3031 #endif
3032 }
3033
3034 void CsrWifiRouterCtrlWapiRxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
3035 {
3036 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
3037
3038     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3039     CsrWifiRouterCtrlWapiRxPktReq* req =  (CsrWifiRouterCtrlWapiRxPktReq*)msg;
3040     int client_id, receiver_id;
3041     bulk_data_param_t bulkdata;
3042     CsrResult res;
3043     ul_client_t *client;
3044     CSR_SIGNAL signal;
3045     CSR_MA_PACKET_INDICATION *pkt_ind;
3046     netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
3047
3048     if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
3049
3050         unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
3051
3052         if (priv == NULL) {
3053             unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq : invalid priv\n",__FUNCTION__);
3054             return;
3055         }
3056
3057         if (priv->smepriv == NULL) {
3058              unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq : invalid sme priv\n",__FUNCTION__);
3059              return;
3060         }
3061
3062         if (req->dataLength == 0 || req->data == NULL) {
3063              unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq: invalid request\n",__FUNCTION__);
3064              return;
3065         }
3066
3067         res = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength);
3068         if (res != CSR_RESULT_SUCCESS) {
3069              unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq: Could not allocate net data\n",__FUNCTION__);
3070              return;
3071         }
3072
3073         /* This function is expected to be called only when the MIC has been verified by SME to be correct
3074          * So reset the reception status to rx_success */
3075         res = read_unpack_signal(req->signal, &signal);
3076         if (res) {
3077                   unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: Received unknown or corrupted signal.\n");
3078                   return;
3079         }
3080         pkt_ind = (CSR_MA_PACKET_INDICATION*) (&((&signal)->u).MaPacketIndication);
3081         if (pkt_ind->ReceptionStatus != CSR_MICHAEL_MIC_ERROR) {
3082                   unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: Unknown signal with reception status = %d\n",pkt_ind->ReceptionStatus);
3083                   return;
3084         } else {
3085                   unifi_trace(priv, UDBG4,"CsrWifiRouterCtrlWapiRxPktReqHandler: MIC verified , RX_SUCCESS \n",__FUNCTION__);
3086                   pkt_ind->ReceptionStatus = CSR_RX_SUCCESS;
3087                   write_pack(&signal, req->signal, &(req->signalLength));
3088         }
3089
3090         memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength);
3091
3092         receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((req->signal) + sizeof(s16)) & 0xFFF0;
3093         client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT;
3094
3095         client = &priv->ul_clients[client_id];
3096
3097         if (client && client->event_hook) {
3098               unifi_trace(priv, UDBG3,
3099                           "CsrWifiRouterCtrlWapiRxPktReq: "
3100                           "Sending signal to client %d, (s:0x%X, r:0x%X) - Signal 0x%X \n",
3101                           client->client_id, client->sender_id, receiver_id,
3102                           CSR_GET_UINT16_FROM_LITTLE_ENDIAN(req->signal));
3103
3104               client->event_hook(client, req->signal, req->signalLength, &bulkdata, UDI_TO_HOST);
3105         } else {
3106               unifi_trace(priv, UDBG4, "No client to give the packet to\n");
3107               unifi_net_data_free(priv, &bulkdata.d[0]);
3108         }
3109
3110         unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
3111     } else {
3112         unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
3113     }
3114 #elif defined(UNIFI_DEBUG)
3115     /*WAPI Disabled*/
3116     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3117     unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: called when WAPI isn't enabled\n");
3118 #endif
3119 }
3120
3121 void CsrWifiRouterCtrlWapiUnicastTxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
3122 {
3123 #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
3124
3125         unifi_priv_t *priv = (unifi_priv_t*) drvpriv;
3126     CsrWifiRouterCtrlWapiUnicastTxPktReq *req   = (CsrWifiRouterCtrlWapiUnicastTxPktReq*) msg;
3127     netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
3128     bulk_data_param_t bulkdata;
3129     u8 macHeaderLengthInBytes = MAC_HEADER_SIZE;
3130     /*KeyID, Reserved, PN, MIC*/
3131     u8 appendedCryptoFields = 1 + 1 + 16 + 16;
3132     CsrResult result;
3133     /* Retrieve the MA PACKET REQ fields from the Signal retained from send_ma_pkt_request() */
3134     CSR_MA_PACKET_REQUEST *storedSignalMAPktReq = &interfacePriv->wapi_unicast_ma_pkt_sig.u.MaPacketRequest;
3135
3136     if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
3137
3138         unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
3139
3140         if (priv == NULL) {
3141             unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler : invalid priv\n",__FUNCTION__);
3142             return;
3143         }
3144         if (priv->smepriv == NULL) {
3145             unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler : invalid sme priv\n",__FUNCTION__);
3146             return;
3147         }
3148         if (req->data == NULL) {
3149             unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: invalid request\n",__FUNCTION__);
3150             return;
3151         } else {
3152             /* If it is QoS data (type = data subtype = QoS), frame header contains QoS control field */
3153             if ((req->data[0] & 0x88) == 0x88) {
3154                 macHeaderLengthInBytes  = macHeaderLengthInBytes + QOS_CONTROL_HEADER_SIZE;
3155             }
3156         }
3157         if ( !(req->dataLength>(macHeaderLengthInBytes+appendedCryptoFields)) ) {
3158             unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: invalid dataLength\n",__FUNCTION__);
3159             return;
3160         }
3161
3162             /* Encrypted DATA Packet contained in (req->data)
3163          * -------------------------------------------------------------------
3164          * |MAC Header|  KeyId   | Reserved |    PN    | xxDataxx | xxMICxxx |
3165          * -------------------------------------------------------------------
3166          *                                             (<-----Encrypted----->)
3167          * -------------------------------------------------------------------
3168          * |24/26(QoS)|    1     |    1     |    16    |    x     |    16    |
3169          * -------------------------------------------------------------------
3170          */
3171         result = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength);
3172         if (result != CSR_RESULT_SUCCESS) {
3173              unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: Could not allocate net data\n",__FUNCTION__);
3174              return;
3175         }
3176         memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength);
3177         bulkdata.d[0].data_length = req->dataLength;
3178         bulkdata.d[1].os_data_ptr = NULL;
3179         bulkdata.d[1].data_length = 0;
3180
3181         /* Send UniFi msg */
3182         /* Here hostTag is been sent as 0xffffffff, its been appended properly while framing MA-Packet request in pdu_processing.c file */
3183         result = uf_process_ma_packet_req(priv,
3184                                           storedSignalMAPktReq->Ra.x,
3185                                           storedSignalMAPktReq->HostTag,/* Ask for a new HostTag */
3186                                           req->interfaceTag,
3187                                           storedSignalMAPktReq->TransmissionControl,
3188                                           storedSignalMAPktReq->TransmitRate,
3189                                           storedSignalMAPktReq->Priority, /* Retained value */
3190                                           interfacePriv->wapi_unicast_ma_pkt_sig.SignalPrimitiveHeader.SenderProcessId, /*FIXME AP: VALIDATE ???*/
3191                                           &bulkdata);
3192
3193         if (result == NETDEV_TX_OK) {
3194              (priv->netdev[req->interfaceTag])->trans_start = jiffies;
3195              /* Should really count tx stats in the UNITDATA.status signal but
3196               * that doesn't have the length.
3197               */
3198              interfacePriv->stats.tx_packets++;
3199
3200              /* count only the packet payload */
3201              interfacePriv->stats.tx_bytes += req->dataLength - macHeaderLengthInBytes - appendedCryptoFields;
3202              unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: (Packet Sent), sent count = %x\n", interfacePriv->stats.tx_packets);
3203         } else {
3204              /* Failed to send: fh queue was full, and the skb was discarded*/
3205              unifi_trace(priv, UDBG1, "(HIP validation failure) Result = %d\n", result);
3206              unifi_net_data_free(priv, &bulkdata.d[0]);
3207
3208              interfacePriv->stats.tx_dropped++;
3209              unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: (Packet Drop), dropped count = %x\n", interfacePriv->stats.tx_dropped);
3210         }
3211
3212         unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
3213
3214     } else {
3215
3216         unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
3217
3218     }
3219 #elif defined(UNIFI_DEBUG)
3220     /*WAPI Disabled*/
3221     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3222     unifi_error(priv,"CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: called when WAPI SW ENCRYPTION isn't enabled\n");
3223 #endif
3224 }
3225
3226 void CsrWifiRouterCtrlWapiFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
3227 {
3228 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
3229
3230 #ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
3231     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3232     CsrWifiRouterCtrlWapiFilterReq* req = (CsrWifiRouterCtrlWapiFilterReq*)msg;
3233     netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
3234
3235     if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
3236
3237         unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
3238
3239         unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiFilterReq: req->isWapiConnected [0/1] = %d \n",req->isWapiConnected);
3240
3241         priv->isWapiConnection = req->isWapiConnected;
3242
3243         unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
3244     } else {
3245
3246         unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
3247
3248     }
3249 #endif
3250
3251 #elif defined(UNIFI_DEBUG)
3252     /*WAPI Disabled*/
3253     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3254     unifi_error(priv,"CsrWifiRouterCtrlWapiFilterReq: called when WAPI isn't enabled\n");
3255 #endif
3256 }