]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/csr/sme_sys.c
9c3aa7494604fd59fda0623178843173df049e76
[karo-tx-linux.git] / 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 "csr_wifi_hip_unifiversion.h"
18 #include "unifi_priv.h"
19 #include "csr_wifi_hip_conversions.h"
20 #ifdef CSR_SUPPORT_WEXT_AP
21 #include "csr_wifi_sme_sef.h"
22 #endif
23
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     CsrUint8 sigbuf[UNIFI_PACKED_SIGBUF_SIZE];
67     CsrUint16 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                                             (CsrUint8 *)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                     UF_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                     UF_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     CsrUint16 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                 *((CsrUint16*)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                 *((CsrUint16*)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                     *((CsrUint16*)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, CsrUint16 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     CsrInt8 protection;
408     int r;
409     static const CsrUint8 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         CsrUint16 interfaceTag)
508 {
509     const CsrUint8 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                 CsrUint8 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 = (CsrCharString*)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 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
873     cancel_work_sync(&priv->ta_ind_work.task);
874     cancel_work_sync(&priv->ta_sample_ind_work.task);
875 #ifdef CSR_SUPPORT_WEXT
876     cancel_work_sync(&priv->sme_config_task);
877     wext_send_disassoc_event(priv);
878 #endif
879
880     /* Cancel pending M4 stuff */
881     for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
882         if (priv->netdev[i]) {
883             netInterface_priv_t *netpriv = (netInterface_priv_t *) netdev_priv(priv->netdev[i]);
884             cancel_work_sync(&netpriv->send_m4_ready_task);
885         }
886     }
887 #endif
888     flush_workqueue(priv->unifi_workqueue);
889
890     /* fw_init parameter can prevent power off UniFi, for debugging */
891     priv_instance = uf_find_priv(priv);
892     if (priv_instance == -1) {
893         unifi_warning(priv,
894                 "CsrWifiRouterCtrlStopReqHandler: Unknown priv instance, will power off card.\n");
895         power_off = 1;
896     } else {
897         power_off = (fw_init[priv_instance] > 0) ? 0 : 1;
898     }
899
900     /* Production test mode requires power to the chip, too */
901     if (priv->ptest_mode) {
902         power_off = 0;
903     }
904
905     /* Stop the bh_thread */
906     uf_stop_thread(priv, &priv->bh_thread);
907
908     /* Read the f/w panic codes, if any. Protect against second wifi_off() call,
909      * which may happen if SME requests a wifi_off and closes the char device */
910     if (priv->init_progress != UNIFI_INIT_NONE) {
911         CsrSdioClaim(priv->sdio);
912         unifi_capture_panic(priv->card);
913         CsrSdioRelease(priv->sdio);
914     }
915
916     /* Unregister the interrupt handler */
917     if (csr_sdio_linux_remove_irq(priv->sdio)) {
918         unifi_notice(priv,
919                 "csr_sdio_linux_remove_irq failed to talk to card.\n");
920     }
921
922     if (power_off) {
923         unifi_trace(priv, UDBG2,
924                     "Force low power and try to power off\n");
925         /* Put UniFi to deep sleep, in case we can not power it off */
926         CsrSdioClaim(priv->sdio);
927         csrResult = unifi_force_low_power_mode(priv->card);
928         CsrSdioRelease(priv->sdio);
929
930         CsrSdioPowerOff(priv->sdio);
931     }
932
933     /* Consider UniFi to be uninitialised */
934     priv->init_progress = UNIFI_INIT_NONE;
935     priv->wifi_on_state = wifi_on_unspecified;
936
937
938 } /* wifi_off() */
939
940
941 void CsrWifiRouterCtrlWifiOffReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
942 {
943     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
944     CsrWifiRouterCtrlWifiOffReq* req = (CsrWifiRouterCtrlWifiOffReq*)msg;
945     int i = 0;
946
947     if (priv == NULL) {
948         return;
949     }
950
951     unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOffReqHandler(0x%.4X)\n", msg->source);
952
953     /* Stop the network traffic on all interfaces before freeing the core. */
954     for (i=0; i<CSR_WIFI_NUM_INTERFACES; i++) {
955         netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
956         if (interfacePriv->netdev_registered == 1) {
957             netif_carrier_off(priv->netdev[i]);
958             UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev[i]);
959             interfacePriv->connected = UnifiConnectedUnknown;
960         }
961         interfacePriv->interfaceMode = 0;
962
963         /* Enable all queues by default */
964         interfacePriv->queueEnabled[0] = 1;
965         interfacePriv->queueEnabled[1] = 1;
966         interfacePriv->queueEnabled[2] = 1;
967         interfacePriv->queueEnabled[3] = 1;
968     }
969     wifi_off(priv);
970
971     CsrWifiRouterCtrlWifiOffCfmSend(msg->source,req->clientData);
972
973     /* If this is called in response to closing the character device, the
974      * caller must use uf_sme_cancel_request() to terminate any pending SME
975      * blocking request or there will be a delay while the operation times out.
976      */
977 }
978
979
980 void CsrWifiRouterCtrlQosControlReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
981 {
982     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
983     CsrWifiRouterCtrlQosControlReq* req = (CsrWifiRouterCtrlQosControlReq*)msg;
984     netInterface_priv_t *interfacePriv;
985
986     if (priv->smepriv == NULL) {
987         unifi_error(priv, "CsrWifiRouterCtrlQosControlReqHandler: invalid smepriv\n");
988         return;
989     }
990
991     unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlQosControlReqHandler:scontrol = %d", req->control);
992
993     if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
994         unifi_error(priv, "CsrWifiRouterCtrlQosControlReqHandler: interfaceID >= CSR_WIFI_NUM_INTERFACES.\n");
995         return;
996     }
997     interfacePriv = priv->interfacePriv[req->interfaceTag];
998
999     if (req->control == CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_WMM_ON) {
1000         priv->sta_wmm_capabilities |= QOS_CAPABILITY_WMM_ENABLED;
1001         unifi_trace(priv, UDBG1, "WMM enabled\n");
1002
1003         unifi_trace(priv, UDBG1, "Queue Config %x\n", req->queueConfig);
1004
1005         interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_BK] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_BK_ENABLE)?1:0;
1006         interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_BE] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_BE_ENABLE)?1:0;
1007         interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_VI] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_VI_ENABLE)?1:0;
1008         interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_VO] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_VO_ENABLE)?1:0;
1009
1010     } else {
1011         priv->sta_wmm_capabilities = 0;
1012         unifi_trace(priv, UDBG1, "WMM disabled\n");
1013     }
1014 }
1015
1016
1017 void CsrWifiRouterCtrlTclasAddReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1018 {
1019     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1020     CsrWifiRouterCtrlTclasAddReq* req = (CsrWifiRouterCtrlTclasAddReq*)msg;
1021
1022     if (priv == NULL) {
1023         unifi_error(priv, "CsrWifiRouterCtrlTclasAddReqHandler: invalid smepriv\n");
1024         return;
1025     }
1026
1027     CsrWifiRouterCtrlTclasAddCfmSend(msg->source, req->clientData, req->interfaceTag , CSR_RESULT_SUCCESS);
1028 }
1029
1030 void CsrWifiRouterCtrlTclasDelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1031 {
1032     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1033     CsrWifiRouterCtrlTclasDelReq* req = (CsrWifiRouterCtrlTclasDelReq*)msg;
1034
1035     if (priv == NULL) {
1036         unifi_error(priv, "CsrWifiRouterCtrlTclasDelReqHandler: invalid smepriv\n");
1037         return;
1038     }
1039
1040     CsrWifiRouterCtrlTclasDelCfmSend(msg->source, req->clientData, req->interfaceTag, CSR_RESULT_SUCCESS);
1041 }
1042
1043
1044 void CsrWifiRouterCtrlConfigurePowerModeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1045 {
1046     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1047     CsrWifiRouterCtrlConfigurePowerModeReq* req = (CsrWifiRouterCtrlConfigurePowerModeReq*)msg;
1048     enum unifi_low_power_mode pm;
1049     CsrResult csrResult;
1050
1051     if (priv->smepriv == NULL) {
1052         unifi_error(priv, "CsrWifiRouterCtrlConfigurePowerModeReqHandler: invalid smepriv\n");
1053         return;
1054     }
1055
1056     if (req->mode == CSR_WIFI_ROUTER_CTRL_LOW_POWER_MODE_DISABLED) {
1057         pm = UNIFI_LOW_POWER_DISABLED;
1058     } else {
1059         pm = UNIFI_LOW_POWER_ENABLED;
1060     }
1061
1062     unifi_trace(priv, UDBG2,
1063                 "CsrWifiRouterCtrlConfigurePowerModeReqHandler (mode=%d, wake=%d)\n",
1064                 req->mode, req->wakeHost);
1065     csrResult = unifi_configure_low_power_mode(priv->card, pm,
1066                                                (req->wakeHost ? UNIFI_PERIODIC_WAKE_HOST_ENABLED : UNIFI_PERIODIC_WAKE_HOST_DISABLED));
1067 }
1068
1069
1070 void CsrWifiRouterCtrlWifiOnResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1071 {
1072     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1073     CsrWifiRouterCtrlWifiOnRes* res = (CsrWifiRouterCtrlWifiOnRes*)msg;
1074
1075     if (priv == NULL) {
1076         unifi_error(NULL, "CsrWifiRouterCtrlWifiOnResHandler: Invalid ospriv.\n");
1077         return;
1078     }
1079
1080     unifi_trace(priv, UDBG1,
1081                 "CsrWifiRouterCtrlWifiOnResHandler: status %d (patch %u)\n", res->status, res->smeVersions.firmwarePatch);
1082
1083     if (res->smeVersions.firmwarePatch != 0) {
1084         unifi_info(priv, "Firmware patch %d\n", res->smeVersions.firmwarePatch);
1085     }
1086
1087     if (res->numInterfaceAddress > CSR_WIFI_NUM_INTERFACES) {
1088         unifi_error(priv, "WifiOnResHandler bad numInterfaceAddress %d\n", res->numInterfaceAddress);
1089         return;
1090     }
1091
1092     /* UniFi is now initialised, complete the init. */
1093     if (res->status == CSR_RESULT_SUCCESS)
1094     {
1095         int i; /* used as a loop counter */
1096         CsrUint32 intmode = CSR_WIFI_INTMODE_DEFAULT;
1097 #ifdef CSR_WIFI_SPLIT_PATCH
1098         CsrBool switching_ap_fw = FALSE;
1099 #endif
1100         /* Register the UniFi device with the OS network manager */
1101         unifi_trace(priv, UDBG3, "Card Init Completed Successfully\n");
1102
1103         /* Store the MAC address in the netdev */
1104         for(i=0;i<res->numInterfaceAddress;i++)
1105         {
1106             memcpy(priv->netdev[i]->dev_addr, res->stationMacAddress[i].a, ETH_ALEN);
1107         }
1108
1109         /* Copy version structure into the private versions field */
1110         priv->sme_versions = res->smeVersions;
1111
1112         unifi_trace(priv, UDBG2, "network interfaces count = %d\n",
1113                     res->numInterfaceAddress);
1114
1115         /* Register the netdevs for each interface. */
1116         for(i=0;i<res->numInterfaceAddress;i++)
1117         {
1118             netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
1119             if(!interfacePriv->netdev_registered)
1120             {
1121                 int r;
1122                 unifi_trace(priv, UDBG3, "registering net device %d\n", i);
1123                 r = uf_register_netdev(priv, i);
1124                 if (r)
1125                 {
1126                     /* unregister the net_device that are registered in the previous iterations */
1127                     uf_unregister_netdev(priv);
1128                     unifi_error(priv, "Failed to register the network device.\n");
1129                     CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_FAILURE);
1130                     return;
1131                 }
1132             }
1133 #ifdef CSR_WIFI_SPLIT_PATCH
1134             else
1135             {
1136                 /* If a netdev is already registered, we have received this WifiOnRes
1137                  * in response to switching AP/STA firmware in a ModeSetReq.
1138                  * Rememeber this in order to send a ModeSetCfm once
1139                  */
1140                 switching_ap_fw = TRUE;
1141             }
1142 #endif
1143         }
1144         priv->totalInterfaceCount = res->numInterfaceAddress;
1145
1146         /* If the MIB has selected f/w scheduled interrupt mode, apply it now
1147          * but let module param override.
1148          */
1149         if (run_bh_once != -1) {
1150             intmode = (CsrUint32)run_bh_once;
1151         } else if (res->scheduledInterrupt) {
1152             intmode = CSR_WIFI_INTMODE_RUN_BH_ONCE;
1153         }
1154         unifi_set_interrupt_mode(priv->card, intmode);
1155
1156         priv->init_progress = UNIFI_INIT_COMPLETED;
1157
1158         /* Acknowledge the CsrWifiRouterCtrlWifiOnReq now */
1159         CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_SUCCESS);
1160
1161 #ifdef CSR_WIFI_SPLIT_PATCH
1162         if (switching_ap_fw && (priv->pending_mode_set.common.destination != 0xaaaa)) {
1163             unifi_info(priv, "Completed firmware reload with %s patch\n",
1164                 CSR_WIFI_HIP_IS_AP_FW(priv->interfacePriv[0]->interfaceMode) ? "AP" : "STA");
1165
1166             /* Confirm the ModeSetReq that requested the AP/STA patch switch */
1167             CsrWifiRouterCtrlModeSetCfmSend(priv->pending_mode_set.common.source,
1168                                             priv->pending_mode_set.clientData,
1169                                             priv->pending_mode_set.interfaceTag,
1170                                             priv->pending_mode_set.mode,
1171                                             CSR_RESULT_SUCCESS);
1172             priv->pending_mode_set.common.destination = 0xaaaa;
1173         }
1174 #endif
1175         unifi_info(priv, "UniFi ready\n");
1176
1177 #ifdef ANDROID_BUILD
1178         /* Release the wakelock */
1179         unifi_trace(priv, UDBG1, "ready: release wake lock\n");
1180         wake_unlock(&unifi_sdio_wake_lock);
1181 #endif
1182         /* Firmware initialisation is complete, so let the SDIO bus
1183          * clock be raised when convienent to the core.
1184          */
1185         unifi_request_max_sdio_clock(priv->card);
1186
1187 #ifdef CSR_SUPPORT_WEXT
1188         /* Notify the Android wpa_supplicant that we are ready */
1189         wext_send_started_event(priv);
1190
1191         queue_work(priv->unifi_workqueue, &priv->sme_config_task);
1192 #endif
1193
1194     } else {
1195         /* Acknowledge the CsrWifiRouterCtrlWifiOnReq now */
1196         CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_FAILURE);
1197     }
1198 }
1199
1200
1201 void CsrWifiRouterCtrlWifiOffResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1202 {
1203 }
1204
1205
1206 void CsrWifiRouterCtrlMulticastAddressResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1207 {
1208 }
1209
1210
1211 void CsrWifiRouterMaPacketSubscribeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1212 {
1213     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1214     CsrWifiRouterMaPacketSubscribeReq* req = (CsrWifiRouterMaPacketSubscribeReq*)msg;
1215     CsrUint8 i;
1216     CsrResult result;
1217
1218     if (priv == NULL) {
1219         unifi_error(priv, "CsrWifiRouterMaPacketSubscribeReqHandler: invalid priv\n");
1220         return;
1221     }
1222
1223     /* Look for an unused filter */
1224
1225     result = CSR_WIFI_RESULT_NO_ROOM;
1226     for (i = 0; i < MAX_MA_UNIDATA_IND_FILTERS; i++) {
1227
1228         if (!priv->sme_unidata_ind_filters[i].in_use) {
1229
1230             priv->sme_unidata_ind_filters[i].in_use = 1;
1231             priv->sme_unidata_ind_filters[i].appHandle = msg->source;
1232             priv->sme_unidata_ind_filters[i].encapsulation = req->encapsulation;
1233             priv->sme_unidata_ind_filters[i].protocol = req->protocol;
1234
1235             priv->sme_unidata_ind_filters[i].oui[2] = (CsrUint8)  (req->oui        & 0xFF);
1236             priv->sme_unidata_ind_filters[i].oui[1] = (CsrUint8) ((req->oui >>  8) & 0xFF);
1237             priv->sme_unidata_ind_filters[i].oui[0] = (CsrUint8) ((req->oui >> 16) & 0xFF);
1238
1239             result = CSR_RESULT_SUCCESS;
1240             break;
1241         }
1242     }
1243
1244     unifi_trace(priv, UDBG1,
1245                 "subscribe_req: encap=%d, handle=%d, result=%d\n",
1246                 req->encapsulation, i, result);
1247     CsrWifiRouterMaPacketSubscribeCfmSend(msg->source,req->interfaceTag, i, result, 0);
1248 }
1249
1250
1251 void CsrWifiRouterMaPacketUnsubscribeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1252 {
1253     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1254     CsrWifiRouterMaPacketUnsubscribeReq* req = (CsrWifiRouterMaPacketUnsubscribeReq*)msg;
1255     CsrResult result;
1256
1257     if (priv == NULL) {
1258         unifi_error(priv, "CsrWifiRouterMaPacketUnsubscribeReqHandler: invalid priv\n");
1259         return;
1260     }
1261
1262     result = CSR_WIFI_RESULT_NOT_FOUND;
1263
1264     if (req->subscriptionHandle < MAX_MA_UNIDATA_IND_FILTERS) {
1265         if (priv->sme_unidata_ind_filters[req->subscriptionHandle].in_use) {
1266             priv->sme_unidata_ind_filters[req->subscriptionHandle].in_use = 0;
1267             result = CSR_RESULT_SUCCESS;
1268         } else {
1269             result = CSR_WIFI_RESULT_NOT_FOUND;
1270         }
1271     }
1272
1273     unifi_trace(priv, UDBG1,
1274                 "unsubscribe_req: handle=%d, result=%d\n",
1275                 req->subscriptionHandle, result);
1276     CsrWifiRouterMaPacketUnsubscribeCfmSend(msg->source,req->interfaceTag, result);
1277 }
1278
1279
1280 void CsrWifiRouterCtrlCapabilitiesReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1281 {
1282     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1283     CsrWifiRouterCtrlCapabilitiesReq* req = (CsrWifiRouterCtrlCapabilitiesReq*)msg;
1284
1285     if (priv == NULL) {
1286         unifi_error(priv, "CsrWifiRouterCtrlCapabilitiesReqHandler: invalid priv\n");
1287         return;
1288     }
1289
1290     CsrWifiRouterCtrlCapabilitiesCfmSend(msg->source,req->clientData,
1291             UNIFI_SOFT_COMMAND_Q_LENGTH - 1,
1292             UNIFI_SOFT_TRAFFIC_Q_LENGTH - 1);
1293 }
1294
1295
1296 void CsrWifiRouterCtrlSuspendResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1297 {
1298     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1299     CsrWifiRouterCtrlSuspendRes* res = (CsrWifiRouterCtrlSuspendRes*)msg;
1300
1301     if (priv == NULL) {
1302         unifi_error(priv, "CsrWifiRouterCtrlSuspendResHandler: invalid priv\n");
1303         return;
1304     }
1305
1306     sme_complete_request(priv, res->status);
1307 }
1308
1309
1310 void CsrWifiRouterCtrlResumeResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1311 {
1312     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1313     CsrWifiRouterCtrlResumeRes* res = (CsrWifiRouterCtrlResumeRes*)msg;
1314
1315     if (priv == NULL) {
1316         unifi_error(priv, "CsrWifiRouterCtrlResumeResHandler: invalid priv\n");
1317         return;
1318     }
1319
1320     sme_complete_request(priv, res->status);
1321 }
1322
1323
1324 void CsrWifiRouterCtrlTrafficConfigReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1325 {
1326     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1327     CsrWifiRouterCtrlTrafficConfigReq* req = (CsrWifiRouterCtrlTrafficConfigReq*)msg;
1328     CsrResult csrResult;
1329
1330     if (priv == NULL) {
1331         unifi_error(priv, "CsrWifiRouterCtrlTrafficConfigReqHandler: invalid smepriv\n");
1332         return;
1333     }
1334     if (req->trafficConfigType == CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_FILTER)
1335     {
1336         req->config.packetFilter |= CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM;
1337     }
1338     csrResult = unifi_ta_configure(priv->card, req->trafficConfigType, (const CsrWifiRouterCtrlTrafficConfig *)&req->config);
1339 }
1340
1341 void CsrWifiRouterCtrlTrafficClassificationReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1342 {
1343     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1344     CsrWifiRouterCtrlTrafficClassificationReq* req = (CsrWifiRouterCtrlTrafficClassificationReq*)msg;
1345
1346     if (priv == NULL) {
1347         unifi_error(priv, "CsrWifiRouterCtrlTrafficClassificationReqHandler: invalid smepriv\n");
1348         return;
1349     }
1350
1351     unifi_ta_classification(priv->card, req->trafficType, req->period);
1352 }
1353
1354 static int
1355 _sys_packet_req(unifi_priv_t *priv, const CSR_SIGNAL *signal,
1356         CsrUint8 subscriptionHandle,
1357         CsrUint16 frameLength, CsrUint8 *frame,
1358         int proto)
1359 {
1360     int r;
1361     const sme_ma_unidata_ind_filter_t *subs;
1362     bulk_data_param_t bulkdata;
1363     CSR_MA_PACKET_REQUEST req = signal->u.MaPacketRequest;
1364     struct sk_buff *skb, *newSkb = NULL;
1365     CsrWifiMacAddress peerMacAddress;
1366     CsrResult csrResult;
1367     CsrUint16 interfaceTag = req.VirtualInterfaceIdentifier & 0xff;
1368     CsrBool eapolStore = FALSE;
1369     CsrInt8 protection = 0;
1370     netInterface_priv_t *interfacePriv;
1371     unsigned long flags;
1372
1373     if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
1374         unifi_error(priv, "_sys_packet_req: interfaceID >= CSR_WIFI_NUM_INTERFACES.\n");
1375         return -EINVAL;
1376     }
1377     interfacePriv = priv->interfacePriv[interfaceTag];
1378     if (!priv->sme_unidata_ind_filters[subscriptionHandle].in_use) {
1379         unifi_error(priv, "_sys_packet_req: unknown subscription.\n");
1380         return -EINVAL;
1381     }
1382
1383     subs = &priv->sme_unidata_ind_filters[subscriptionHandle];
1384     unifi_trace(priv, UDBG1,
1385                 "_sys_packet_req: handle=%d, subs=%p, encap=%d\n",
1386                 subscriptionHandle, subs, subs->encapsulation);
1387
1388     csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], frameLength);
1389     if (csrResult != CSR_RESULT_SUCCESS) {
1390         unifi_error(priv, "_sys_packet_req: failed to allocate bulkdata.\n");
1391         return (int)CsrHipResultToStatus(csrResult);
1392     }
1393
1394     /* get the peer Mac address */
1395     memcpy(&peerMacAddress, frame, ETH_ALEN);
1396
1397     /* Determine if we need to add encapsulation header */
1398     if (subs->encapsulation == CSR_WIFI_ROUTER_ENCAPSULATION_ETHERNET) {
1399         memcpy((void*)bulkdata.d[0].os_data_ptr, frame, frameLength);
1400
1401         /* The translation is performed on the skb */
1402         skb = (struct sk_buff*)bulkdata.d[0].os_net_buf_ptr;
1403
1404         unifi_trace(priv, UDBG1,
1405                     "_sys_packet_req: skb_add_llc_snap -->\n");
1406         r = skb_add_llc_snap(priv->netdev[interfaceTag], skb, proto);
1407         unifi_trace(priv, UDBG1,
1408                     "_sys_packet_req: skb_add_llc_snap <--\n");
1409         if (r) {
1410             unifi_error(priv,
1411                         "_sys_packet_req: failed to translate eth frame.\n");
1412             unifi_net_data_free(priv,&bulkdata.d[0]);
1413             return r;
1414         }
1415
1416         bulkdata.d[0].data_length = skb->len;
1417     } else {
1418         /* Crop the MAC addresses from the packet */
1419         memcpy((void*)bulkdata.d[0].os_data_ptr, frame + 2*ETH_ALEN, frameLength - 2*ETH_ALEN);
1420         bulkdata.d[0].data_length = frameLength - 2*ETH_ALEN;
1421         skb = (struct sk_buff*)bulkdata.d[0].os_net_buf_ptr;
1422         skb->len = bulkdata.d[0].data_length;
1423
1424     }
1425
1426     bulkdata.d[1].os_data_ptr = NULL;
1427     bulkdata.d[1].os_net_buf_ptr = NULL;
1428     bulkdata.d[1].data_length = 0;
1429
1430     /* check for m4 detection */
1431     if (0 == uf_verify_m4(priv, bulkdata.d[0].os_data_ptr, bulkdata.d[0].data_length)) {
1432         eapolStore = TRUE;
1433     }
1434
1435 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1436     if (proto == ETH_P_WAI)
1437      {
1438         protection = 0; /*WAI packets always sent unencrypted*/
1439      }
1440    else
1441      {
1442 #endif
1443
1444 #ifdef CSR_SUPPORT_SME
1445     if ((protection = uf_get_protection_bit_from_interfacemode(priv, interfaceTag, peerMacAddress.a)) < 0) {
1446         unifi_error(priv, "unicast address, but destination not in station record database\n");
1447         unifi_net_data_free(priv,&bulkdata.d[0]);
1448         return -1;
1449     }
1450 #else
1451     protection = 0;
1452 #endif
1453
1454 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1455     }
1456 #endif
1457
1458     /* add Mac header */
1459     if (prepare_and_add_macheader(priv, skb, newSkb, req.Priority, &bulkdata, interfaceTag, frame, frame + ETH_ALEN, protection)) {
1460         unifi_error(priv, "failed to create MAC header\n");
1461         unifi_net_data_free(priv,&bulkdata.d[0]);
1462         return -1;
1463     }
1464
1465     if (eapolStore) {
1466         spin_lock_irqsave(&priv->m4_lock, flags);
1467         /* Store the EAPOL M4 packet for later */
1468         interfacePriv->m4_signal = *signal;
1469         interfacePriv->m4_bulk_data.net_buf_length = bulkdata.d[0].net_buf_length;
1470         interfacePriv->m4_bulk_data.data_length = bulkdata.d[0].data_length;
1471         interfacePriv->m4_bulk_data.os_data_ptr = bulkdata.d[0].os_data_ptr;
1472         interfacePriv->m4_bulk_data.os_net_buf_ptr = bulkdata.d[0].os_net_buf_ptr;
1473         spin_unlock_irqrestore(&priv->m4_lock, flags);
1474         /* Send a signal to SME */
1475         unifi_trace(priv, UDBG1, "_sys_packet_req: Sending CsrWifiRouterCtrlM4ReadyToSendInd\n");
1476         CsrWifiRouterCtrlM4ReadyToSendIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, peerMacAddress);
1477         return 0;
1478     }
1479
1480     /* Send the signal to UniFi */
1481       /* Set the B31 to 1 for local routing*/
1482     r= uf_process_ma_packet_req(priv,  peerMacAddress.a, (req.HostTag | 0x80000000), interfaceTag, 0,
1483                                 (CSR_RATE)0, req.Priority, signal->SignalPrimitiveHeader.SenderProcessId, &bulkdata);
1484     if (r) {
1485         unifi_error(priv,
1486                     "_sys_packet_req: failed to send signal.\n");
1487         unifi_net_data_free(priv,&bulkdata.d[0]);
1488         return r;
1489     }
1490     /* The final CsrWifiRouterMaPacketCfmSend() will called when the actual MA-PACKET.cfm is received from the chip */
1491
1492     return 0;
1493 }
1494
1495 void CsrWifiRouterMaPacketReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1496 {
1497     int r;
1498     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1499     CsrWifiRouterMaPacketReq* mareq = (CsrWifiRouterMaPacketReq*)msg;
1500     llc_snap_hdr_t *snap;
1501     CsrUint16 snap_protocol;
1502     CSR_SIGNAL signal;
1503     CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest;
1504     CsrWifiRouterCtrlPortAction controlPortaction;
1505     CsrUint8 *daddr, *saddr;
1506     CsrUint16 interfaceTag = mareq->interfaceTag & 0x00ff;
1507     int queue;
1508     netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
1509
1510     if (!mareq->frame || !priv || !priv->smepriv)
1511     {
1512         unifi_error(priv, "CsrWifiRouterMaPacketReqHandler: invalid frame/priv/priv->smepriv\n");
1513         return;
1514     }
1515
1516     if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
1517         unifi_error(priv, "CsrWifiRouterMaPacketReqHandler: interfaceID >= CSR_WIFI_NUM_INTERFACES.\n");
1518         return;
1519     }
1520     /* get a pointer to dest & source Mac address */
1521     daddr = mareq->frame;
1522     saddr = (mareq->frame + ETH_ALEN);
1523     /* point to the proper position of frame, since frame has MAC header */
1524     snap = (llc_snap_hdr_t *) (mareq->frame + 2 * ETH_ALEN);
1525     snap_protocol = ntohs(snap->protocol);
1526     if((snap_protocol == ETH_P_PAE)
1527 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1528        || (snap_protocol == ETH_P_WAI)
1529 #endif
1530     )
1531     {
1532         queue = UF_UNCONTROLLED_PORT_Q;
1533     }
1534     else
1535     {
1536         queue = UF_CONTROLLED_PORT_Q;
1537     }
1538
1539     /* Controlled port restrictions apply to the packets */
1540     controlPortaction = uf_sme_port_state(priv, daddr, queue, interfaceTag);
1541     if (controlPortaction != CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN)
1542     {
1543         unifi_warning(priv, "CsrWifiRouterMaPacketReqHandler: (%s)controlled port is closed.\n", (queue == UF_CONTROLLED_PORT_Q)?"":"un");
1544         if(mareq->cfmRequested)
1545         {
1546             CsrWifiRouterMaPacketCfmSend(msg->source,
1547                                      interfaceTag,
1548                                      CSR_RESULT_FAILURE,
1549                                      mareq->hostTag, 0);
1550         }
1551         return;
1552     }
1553
1554     signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID;
1555     /* Store the appHandle in the LSB of the SenderId. */
1556     CSR_COPY_UINT16_TO_LITTLE_ENDIAN(((priv->sme_cli->sender_id & 0xff00) | (unsigned int)msg->source),
1557                                      (u8*)&signal.SignalPrimitiveHeader.SenderProcessId);
1558     signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
1559
1560     /* Fill in the MA-PACKET.req signal */
1561     memcpy(req->Ra.x, daddr, ETH_ALEN);
1562     req->Priority = mareq->priority;
1563     req->TransmitRate = 0; /* Let firmware select the rate*/
1564     req->VirtualInterfaceIdentifier = uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag);
1565     req->HostTag = mareq->hostTag;
1566
1567     if(mareq->cfmRequested)
1568         req->TransmissionControl = 0;
1569     else
1570         req->TransmissionControl = CSR_NO_CONFIRM_REQUIRED;
1571
1572     r = _sys_packet_req(priv, &signal, mareq->subscriptionHandle,
1573             mareq->frameLength, mareq->frame, snap_protocol);
1574
1575 #define MAX_RETRY 2
1576     if (r && mareq->cfmRequested)
1577     {
1578         CsrWifiRouterMaPacketCfmSend(msg->source,interfaceTag,
1579                                      CSR_RESULT_FAILURE,
1580                                      mareq->hostTag, 0);
1581     }
1582     return;
1583 }
1584
1585 void CsrWifiRouterMaPacketCancelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1586 {
1587 }
1588
1589 void CsrWifiRouterCtrlM4TransmitReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1590 {
1591     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1592     CsrWifiRouterCtrlM4TransmitReq* req = (CsrWifiRouterCtrlM4TransmitReq*)msg;
1593     int r;
1594     bulk_data_param_t bulkdata;
1595     netInterface_priv_t *interfacePriv;
1596     CSR_SIGNAL m4_signal;
1597     unsigned long flags;
1598
1599     if (priv == NULL) {
1600         unifi_error(priv, "CsrWifiRouterCtrlM4TransmitReqHandler: invalid smepriv\n");
1601         return;
1602     }
1603     if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
1604         unifi_error(priv, "M4TransmitReqHandler: interfaceTag >= CSR_WIFI_NUM_INTERFACES\n");
1605         return;
1606     }
1607
1608     interfacePriv = priv->interfacePriv[req->interfaceTag];
1609     spin_lock_irqsave(&priv->m4_lock, flags);
1610     if (interfacePriv->m4_bulk_data.data_length == 0) {
1611         spin_unlock_irqrestore(&priv->m4_lock, flags);
1612         unifi_error(priv, "CsrWifiRouterCtrlM4TransmitReqHandler: invalid buffer\n");
1613         return;
1614     }
1615
1616     memcpy(&bulkdata.d[0], &interfacePriv->m4_bulk_data, sizeof(bulk_data_desc_t));
1617
1618     interfacePriv->m4_bulk_data.net_buf_length = 0;
1619     interfacePriv->m4_bulk_data.data_length = 0;
1620     interfacePriv->m4_bulk_data.os_data_ptr = interfacePriv->m4_bulk_data.os_net_buf_ptr = NULL;
1621     m4_signal = interfacePriv->m4_signal;
1622     spin_unlock_irqrestore(&priv->m4_lock, flags);
1623
1624     bulkdata.d[1].os_data_ptr = NULL;
1625     bulkdata.d[1].data_length = 0;
1626
1627     interfacePriv->m4_sent = TRUE;
1628     m4_signal.u.MaPacketRequest.HostTag |= 0x80000000;
1629     /* Store the hostTag for later varification */
1630     interfacePriv->m4_hostTag = m4_signal.u.MaPacketRequest.HostTag;
1631     r = ul_send_signal_unpacked(priv, &m4_signal, &bulkdata);
1632     unifi_trace(priv, UDBG1,
1633                 "CsrWifiRouterCtrlM4TransmitReqHandler: sent\n");
1634     if (r) {
1635         unifi_error(priv,
1636                     "CsrWifiRouterCtrlM4TransmitReqHandler: failed to send signal.\n");
1637         unifi_net_data_free(priv, &bulkdata.d[0]);
1638     }
1639 }
1640
1641 /* reset the station records when the mode is set as CSR_WIFI_ROUTER_CTRL_MODE_NONE */
1642 static void CsrWifiRouterCtrlResetStationRecordList(unifi_priv_t *priv, CsrUint16 interfaceTag)
1643 {
1644     CsrUint8 i,j;
1645     CsrWifiRouterCtrlStaInfo_t *staInfo=NULL;
1646     netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
1647     unsigned long lock_flags;
1648
1649     /* create a list for sending confirms of un-delivered packets */
1650     struct list_head send_cfm_list;
1651
1652     if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
1653         unifi_error(priv, "CsrWifiRouterCtrlResetStationRecordList: bad interfaceTag\n");
1654         return;
1655     }
1656
1657     INIT_LIST_HEAD(&send_cfm_list);
1658
1659     /* Reset the station record to NULL if mode is NONE */
1660     for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
1661         if ((staInfo=interfacePriv->staInfo[i]) != NULL) {
1662             uf_prepare_send_cfm_list_for_queued_pkts(priv,
1663                                                  &send_cfm_list,
1664                                                  &(staInfo->mgtFrames));
1665             uf_flush_list(priv,&(staInfo->mgtFrames));
1666             for(j=0;j<MAX_ACCESS_CATOGORY;j++){
1667                 uf_prepare_send_cfm_list_for_queued_pkts(priv,
1668                                                      &send_cfm_list,
1669                                                      &(staInfo->dataPdu[j]));
1670                 uf_flush_list(priv,&(staInfo->dataPdu[j]));
1671             }
1672
1673             spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
1674             /* Removing station record information from port config array */
1675             memset(staInfo->peerControlledPort, 0, sizeof(unifi_port_cfg_t));
1676             staInfo->peerControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
1677             staInfo->peerControlledPort->in_use = FALSE;
1678             interfacePriv->controlled_data_port.entries_in_use--;
1679
1680             memset(staInfo->peerUnControlledPort, 0, sizeof(unifi_port_cfg_t));
1681             staInfo->peerUnControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
1682             staInfo->peerUnControlledPort->in_use = FALSE;
1683             interfacePriv->uncontrolled_data_port.entries_in_use--;
1684
1685             kfree(interfacePriv->staInfo[i]);
1686             interfacePriv->staInfo[i] = NULL;
1687             spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
1688         }
1689     }
1690     /* after the critical region process the list of frames that requested cfm
1691      * and send cfm to requestor one by one
1692      */
1693     send_auto_ma_packet_confirm(priv, interfacePriv, &send_cfm_list);
1694
1695 #ifdef CSR_SUPPORT_SME
1696     /* Interface Independent, no of packet queued, incase of mode is None or AP set to 0 */
1697     switch(interfacePriv->interfaceMode)
1698     {
1699         case CSR_WIFI_ROUTER_CTRL_MODE_AP:
1700         case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
1701         case CSR_WIFI_ROUTER_CTRL_MODE_NONE:
1702             if (priv->noOfPktQueuedInDriver) {
1703                 unifi_warning(priv, "After reset the noOfPktQueuedInDriver = %x\n", priv->noOfPktQueuedInDriver);
1704                 spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
1705                 priv->noOfPktQueuedInDriver = 0;
1706                 spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
1707             }
1708             break;
1709         case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
1710             break;
1711         default:
1712             unifi_error(priv, "interfacemode is not correct in CsrWifiRouterCtrlResetStationRecordList: debug\n");
1713     }
1714 #endif
1715
1716     if (((interfacePriv->controlled_data_port.entries_in_use != 0) || (interfacePriv->uncontrolled_data_port.entries_in_use != 0))
1717             && (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_NONE)) {
1718         /* Print in case if the value of entries goes to -ve/+ve (apart from 0)
1719          * we expect the entries should be zero here if mode is set as NONE
1720          */
1721         unifi_trace(priv, UDBG3, "In %s controlled port entries = %d, uncontrolled port entries = %d\n",
1722                    __FUNCTION__, interfacePriv->controlled_data_port.entries_in_use,
1723                    interfacePriv->uncontrolled_data_port.entries_in_use);
1724     }
1725 }
1726
1727 void CsrWifiRouterCtrlInterfaceReset(unifi_priv_t *priv, CsrUint16 interfaceTag)
1728 {
1729     netInterface_priv_t *interfacePriv;
1730
1731     /* create a list for sending confirms of un-delivered packets */
1732     struct list_head send_cfm_list;
1733
1734     if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
1735         unifi_error(priv, "CsrWifiRouterCtrlInterfaceReset: bad interfaceTag\n");
1736         return;
1737     }
1738
1739     interfacePriv = priv->interfacePriv[interfaceTag];
1740
1741     INIT_LIST_HEAD(&send_cfm_list);
1742
1743     /* Enable all queues by default */
1744     interfacePriv->queueEnabled[0] = 1;
1745     interfacePriv->queueEnabled[1] = 1;
1746     interfacePriv->queueEnabled[2] = 1;
1747     interfacePriv->queueEnabled[3] = 1;
1748
1749     uf_prepare_send_cfm_list_for_queued_pkts(priv,
1750                                              &send_cfm_list,
1751                                              &(interfacePriv->genericMgtFrames));
1752     uf_flush_list(priv,&(interfacePriv->genericMgtFrames));
1753
1754     uf_prepare_send_cfm_list_for_queued_pkts(priv,
1755                                              &send_cfm_list,
1756                                              &(interfacePriv->genericMulticastOrBroadCastMgtFrames));
1757     uf_flush_list(priv,&(interfacePriv->genericMulticastOrBroadCastMgtFrames));
1758
1759     uf_prepare_send_cfm_list_for_queued_pkts(priv,
1760                                              &send_cfm_list,
1761                                              &(interfacePriv->genericMulticastOrBroadCastFrames));
1762
1763     uf_flush_list(priv,&(interfacePriv->genericMulticastOrBroadCastFrames));
1764
1765     /*  process the list of frames that requested cfm
1766     and send cfm to requestor one by one */
1767     send_auto_ma_packet_confirm(priv, interfacePriv, &send_cfm_list);
1768
1769     /* Reset the station record to NULL if mode is tried to set as NONE */
1770     switch(interfacePriv->interfaceMode)
1771     {
1772         case CSR_WIFI_ROUTER_CTRL_MODE_STA:
1773         case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
1774         case CSR_WIFI_ROUTER_CTRL_MODE_MONITOR:
1775         case CSR_WIFI_ROUTER_CTRL_MODE_AMP:
1776             /* station records not available in these modes */
1777             break;
1778         default:
1779             CsrWifiRouterCtrlResetStationRecordList(priv,interfaceTag);
1780     }
1781
1782     interfacePriv->num_stations_joined = 0;
1783     interfacePriv->sta_activity_check_enabled = FALSE;
1784 }
1785
1786
1787 void CsrWifiRouterCtrlModeSetReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1788 {
1789     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1790     CsrWifiRouterCtrlModeSetReq* req = (CsrWifiRouterCtrlModeSetReq*)msg;
1791
1792     if (priv == NULL)
1793     {
1794         unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: invalid smepriv\n");
1795         return;
1796     }
1797
1798     if (req->interfaceTag < CSR_WIFI_NUM_INTERFACES)
1799     {
1800         netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
1801 #ifdef CSR_WIFI_SPLIT_PATCH
1802         CsrUint8 old_mode = interfacePriv->interfaceMode;
1803 #endif
1804         unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlModeSetReqHandler: interfacePriv->interfaceMode = %d\n",
1805                 interfacePriv->interfaceMode);
1806
1807         interfacePriv->interfaceMode = req->mode;
1808
1809 #ifdef CSR_WIFI_SPLIT_PATCH
1810         /* Detect a change in mode that requires a switch to/from the AP firmware patch.
1811          * This should only happen when transitioning in/out of AP modes.
1812          */
1813         if (CSR_WIFI_HIP_IS_AP_FW(req->mode) != CSR_WIFI_HIP_IS_AP_FW(old_mode))
1814         {
1815             CsrWifiRouterCtrlVersions versions;
1816             int r;
1817
1818 #ifdef ANDROID_BUILD
1819             /* Take the wakelock while switching patch */
1820             unifi_trace(priv, UDBG1, "patch switch: take wake lock\n");
1821             wake_lock(&unifi_sdio_wake_lock);
1822 #endif
1823             unifi_info(priv, "Resetting UniFi with %s patch\n", CSR_WIFI_HIP_IS_AP_FW(req->mode) ? "AP" : "STA");
1824
1825             r = uf_request_firmware_files(priv, UNIFI_FW_STA);
1826             if (r) {
1827                 unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: Failed to get f/w\n");
1828                 CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
1829                                                 req->mode, CSR_RESULT_FAILURE);
1830                 return;
1831             }
1832
1833             /* Block the I/O thread */
1834             priv->bh_thread.block_thread = 1;
1835
1836             /* Reset and download the new patch */
1837             r = uf_init_hw(priv);
1838             if (r) {
1839                 unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to initialise h/w, error %d\n", r);
1840                 CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
1841                                                 req->mode, CSR_RESULT_FAILURE);
1842                 return;
1843             }
1844
1845             /* Re-enable the I/O thread */
1846             priv->bh_thread.block_thread = 0;
1847
1848             /* Get the version information from the core */
1849             unifi_card_info(priv->card, &priv->card_info);
1850
1851             /* Copy to the unifiio_card_info structure. */
1852             versions.chipId = priv->card_info.chip_id;
1853             versions.chipVersion = priv->card_info.chip_version;
1854             versions.firmwareBuild = priv->card_info.fw_build;
1855             versions.firmwareHip = priv->card_info.fw_hip_version;
1856             versions.routerBuild = (CsrCharString*)CSR_WIFI_VERSION;
1857             versions.routerHip = (UNIFI_HIP_MAJOR_VERSION << 8) | UNIFI_HIP_MINOR_VERSION;
1858
1859             /* Now that new firmware is running, send a WifiOnInd to the NME. This will
1860              * cause it to retransfer the MIB.
1861              */
1862             CsrWifiRouterCtrlWifiOnIndSend(msg->source, 0, CSR_RESULT_SUCCESS, versions);
1863
1864             /* Store the request so we know where to send the ModeSetCfm */
1865             priv->pending_mode_set = *req;
1866         }
1867         else
1868 #endif
1869         {
1870             /* No patch switch, confirm straightaway */
1871             CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
1872                                             req->mode, CSR_RESULT_SUCCESS);
1873         }
1874
1875         interfacePriv->bssid = req->bssid;
1876         /* For modes other than AP/P2PGO, set below member FALSE */
1877         interfacePriv->intraBssEnabled = FALSE;
1878         /* Initialise the variable bcTimSet with a value
1879          * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
1880          */
1881         interfacePriv->bcTimSet = 0xFF;
1882         interfacePriv->bcTimSetReqPendingFlag = FALSE;
1883         /* Initialise the variable bcTimSetReqQueued with a value
1884          * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
1885          */
1886         interfacePriv->bcTimSetReqQueued =0xFF;
1887         CsrWifiRouterCtrlInterfaceReset(priv,req->interfaceTag);
1888
1889         if(req->mode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
1890            req->mode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
1891             interfacePriv->protect = req->protection;
1892             interfacePriv->dtimActive=FALSE;
1893             interfacePriv->multicastPduHostTag = 0xffffffff;
1894             /* For AP/P2PGO mode SME sending intraBssDistEnabled
1895              * i.e. for AP: intraBssDistEnabled = TRUE, for P2PGO
1896              * intraBssDistEnabled = TRUE/FALSE on requirement
1897              */
1898             interfacePriv->intraBssEnabled = req->intraBssDistEnabled;
1899             unifi_trace(priv, UDBG3, "CsrWifiRouterCtrlModeSetReqHandler: IntraBssDisEnabled = %d\n",
1900                         req->intraBssDistEnabled);
1901         } else if (req->mode == CSR_WIFI_ROUTER_CTRL_MODE_NONE) {
1902               netif_carrier_off(priv->netdev[req->interfaceTag]);
1903               interfacePriv->connected = UnifiConnectedUnknown;
1904         }
1905     }
1906     else {
1907         unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: invalid interfaceTag :%d\n",req->interfaceTag);
1908     }
1909 }
1910
1911 void CsrWifiRouterMaPacketResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1912 {
1913 }
1914
1915 /* delete the station record from the station record data base */
1916 static int peer_delete_record(unifi_priv_t *priv, CsrWifiRouterCtrlPeerDelReq *req)
1917 {
1918     CsrUint8 j;
1919     CsrWifiRouterCtrlStaInfo_t *staInfo = NULL;
1920     unifi_port_config_t *controlledPort;
1921     unifi_port_config_t *unControlledPort;
1922     netInterface_priv_t *interfacePriv;
1923
1924     CsrUint8 ba_session_idx = 0;
1925     ba_session_rx_struct *ba_session_rx = NULL;
1926     ba_session_tx_struct *ba_session_tx = NULL;
1927
1928     /* create a list for sending confirms of un-delivered packets */
1929     struct list_head send_cfm_list;
1930
1931     unsigned long lock_flags;
1932
1933     if ((req->peerRecordHandle >= UNIFI_MAX_CONNECTIONS) || (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES)) {
1934         unifi_error(priv, "handle/interfaceTag is not proper, handle = %d, interfaceTag = %d\n", req->peerRecordHandle, req->interfaceTag);
1935         return CSR_RESULT_FAILURE;
1936     }
1937
1938     INIT_LIST_HEAD(&send_cfm_list);
1939
1940     interfacePriv = priv->interfacePriv[req->interfaceTag];
1941     /* remove the station record & make it NULL */
1942     if ((staInfo=interfacePriv->staInfo[req->peerRecordHandle])!=NULL) {
1943
1944         uf_prepare_send_cfm_list_for_queued_pkts(priv,
1945                                                  &send_cfm_list,
1946                                                  &(staInfo->mgtFrames));
1947
1948         uf_flush_list(priv,&(staInfo->mgtFrames));
1949         for(j=0;j<MAX_ACCESS_CATOGORY;j++){
1950             uf_prepare_send_cfm_list_for_queued_pkts(priv,
1951                                                      &send_cfm_list,
1952                                                      &(staInfo->dataPdu[j]));
1953             uf_flush_list(priv,&(staInfo->dataPdu[j]));
1954         }
1955
1956         spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
1957         /* clear the port configure array info, for the corresponding peer entry */
1958         controlledPort = &interfacePriv->controlled_data_port;
1959         unControlledPort = &interfacePriv->uncontrolled_data_port;
1960
1961         unifi_trace(priv, UDBG1, "peer_delete_record: Peer found handle = %d, port in use: cont(%d), unCont(%d)\n",
1962                     req->peerRecordHandle, controlledPort->entries_in_use, unControlledPort->entries_in_use);
1963
1964         memset(staInfo->peerControlledPort, 0, sizeof(unifi_port_cfg_t));
1965         staInfo->peerControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
1966         staInfo->peerControlledPort->in_use = FALSE;
1967         if (controlledPort->entries_in_use) {
1968             controlledPort->entries_in_use--;
1969         } else {
1970             unifi_warning(priv, "number of controlled port entries is zero, trying to decrement: debug\n");
1971         }
1972
1973         memset(staInfo->peerUnControlledPort, 0, sizeof(unifi_port_cfg_t));
1974         staInfo->peerUnControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
1975         staInfo->peerUnControlledPort->in_use = FALSE;
1976         if (unControlledPort->entries_in_use) {
1977             unControlledPort->entries_in_use--;
1978         } else {
1979             unifi_warning(priv, "number of uncontrolled port entries is zero, trying to decrement: debug\n");
1980         }
1981
1982         spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
1983         /* update the TIM with zero */
1984         if (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_IBSS &&
1985                 staInfo->timSet == CSR_WIFI_TIM_SET) {
1986             unifi_trace(priv, UDBG3, "peer is deleted so TIM updated to 0, in firmware\n");
1987             update_tim(priv,staInfo->aid,0,req->interfaceTag, req->peerRecordHandle);
1988         }
1989
1990
1991         /* Stop BA session if it is active, for this peer address all BA sessions
1992         (per tID per role) are closed */
1993
1994         down(&priv->ba_mutex);
1995         for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
1996             ba_session_rx = priv->interfacePriv[req->interfaceTag]->ba_session_rx[ba_session_idx];
1997             if(ba_session_rx) {
1998                 if(!memcmp(ba_session_rx->macAddress.a, staInfo->peerMacAddress.a, ETH_ALEN)){
1999                     blockack_session_stop(priv,
2000                                         req->interfaceTag,
2001                                         CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT,
2002                                         ba_session_rx->tID,
2003                                         ba_session_rx->macAddress);
2004                 }
2005             }
2006         }
2007
2008         for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){
2009             ba_session_tx = priv->interfacePriv[req->interfaceTag]->ba_session_tx[ba_session_idx];
2010             if(ba_session_tx) {
2011                 if(!memcmp(ba_session_tx->macAddress.a, staInfo->peerMacAddress.a, ETH_ALEN)){
2012                     blockack_session_stop(priv,
2013                                         req->interfaceTag,
2014                                         CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR,
2015                                         ba_session_tx->tID,
2016                                         ba_session_tx->macAddress);
2017                 }
2018             }
2019         }
2020
2021         up(&priv->ba_mutex);
2022
2023 #ifdef CSR_SUPPORT_SME
2024         unifi_trace(priv, UDBG1, "Canceling work queue for STA with AID: %d\n", staInfo->aid);
2025         cancel_work_sync(&staInfo->send_disconnected_ind_task);
2026 #endif
2027
2028         spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2029 #ifdef CSR_SUPPORT_SME
2030         interfacePriv->num_stations_joined--;
2031
2032         staInfo->nullDataHostTag = INVALID_HOST_TAG;
2033
2034         if ((interfacePriv->sta_activity_check_enabled) &&
2035             (interfacePriv->num_stations_joined < STA_INACTIVE_DETECTION_TRIGGER_THRESHOLD))
2036         {
2037             unifi_trace(priv, UDBG1, "STOPPING the Inactivity Timer (num of stations = %d)\n", interfacePriv->num_stations_joined);
2038             interfacePriv->sta_activity_check_enabled = FALSE;
2039             del_timer_sync(&interfacePriv->sta_activity_check_timer);
2040         }
2041 #endif
2042
2043         /* Free the station record for corresponding peer */
2044         kfree(interfacePriv->staInfo[req->peerRecordHandle]);
2045         interfacePriv->staInfo[req->peerRecordHandle] = NULL;
2046         spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2047
2048         /* after the critical region process the list of frames that requested cfm
2049         and send cfm to requestor one by one */
2050         send_auto_ma_packet_confirm(priv, interfacePriv, &send_cfm_list);
2051
2052
2053     }
2054     else
2055     {
2056         unifi_trace(priv, UDBG3, " peer not found: Delete request Peer handle[%d]\n", req->peerRecordHandle);
2057     }
2058
2059     return CSR_RESULT_SUCCESS;
2060 }
2061
2062 void CsrWifiRouterCtrlPeerDelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2063 {
2064     CsrWifiRouterCtrlPeerDelReq* req = (CsrWifiRouterCtrlPeerDelReq*)msg;
2065     CsrResult status = CSR_RESULT_SUCCESS;
2066     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2067     netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
2068
2069     unifi_trace(priv, UDBG2, "entering CsrWifiRouterCtrlPeerDelReqHandler \n");
2070     if (priv == NULL)
2071     {
2072         unifi_error(priv, "CsrWifiRouterCtrlPeerDelReqHandler: invalid smepriv\n");
2073         return;
2074     }
2075
2076     if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES)
2077     {
2078         unifi_error(priv, "CsrWifiRouterCtrlPeerDelReqHandler: bad interfaceTag\n");
2079         return;
2080     }
2081
2082     switch(interfacePriv->interfaceMode)
2083     {
2084         case CSR_WIFI_ROUTER_CTRL_MODE_AP:
2085         case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
2086         case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
2087             /* remove the station from station record data base */
2088             status = peer_delete_record(priv, req);
2089             break;
2090         case CSR_WIFI_ROUTER_CTRL_MODE_STA:
2091         case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
2092         default:
2093             /* No station record to maintain in these modes */
2094             break;
2095     }
2096
2097     CsrWifiRouterCtrlPeerDelCfmSend(msg->source,req->clientData,req->interfaceTag,status);
2098     unifi_trace(priv, UDBG2, "leaving CsrWifiRouterCtrlPeerDelReqHandler \n");
2099 }
2100
2101 /* Add the new station to the station record data base */
2102 static int peer_add_new_record(unifi_priv_t *priv,CsrWifiRouterCtrlPeerAddReq *req,CsrUint32 *handle)
2103 {
2104     CsrUint8 i, powerModeTemp = 0;
2105     CsrBool freeSlotFound = FALSE;
2106     CsrWifiRouterCtrlStaInfo_t *newRecord = NULL;
2107     netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
2108     CsrTime currentTime, currentTimeHi;
2109     unsigned long lock_flags;
2110
2111     if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2112         unifi_error(priv, "peer_add_new_record: bad interfaceTag\n");
2113         return CSR_RESULT_FAILURE;
2114     }
2115
2116     currentTime = CsrTimeGet(&currentTimeHi);
2117
2118     for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
2119         if(interfacePriv->staInfo[i] == NULL) {
2120             /* Slot is empty, so can be used for station record */
2121             freeSlotFound = TRUE;
2122             *handle = i;
2123
2124             /* Allocate for the new station record , to avoid race condition would happen between ADD_PEER &
2125              * DEL_PEER the allocation made atomic memory rather than kernel memory
2126              */
2127             newRecord = (CsrWifiRouterCtrlStaInfo_t *) kmalloc(sizeof(CsrWifiRouterCtrlStaInfo_t), GFP_ATOMIC);
2128             if (!newRecord) {
2129                 unifi_error(priv, "failed to allocate the %d bytes of mem for station record\n",
2130                             sizeof(CsrWifiRouterCtrlStaInfo_t));
2131                 return CSR_RESULT_FAILURE;
2132             }
2133
2134             unifi_trace(priv, UDBG1, "peer_add_new_record: handle = %d AID = %d addr = %x:%x:%x:%x:%x:%x LI=%u\n",
2135                         *handle, req->associationId, req->peerMacAddress.a[0], req->peerMacAddress.a[1], req->peerMacAddress.a[2],
2136                         req->peerMacAddress.a[3], req->peerMacAddress.a[4], req->peerMacAddress.a[5],
2137                         req->staInfo.listenIntervalInTus);
2138
2139             /* disable the preemption until station record updated */
2140             spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2141
2142             interfacePriv->staInfo[i] = newRecord;
2143             /* Initialize the record*/
2144             memset(newRecord,0,sizeof(CsrWifiRouterCtrlStaInfo_t));
2145             /* update the station record */
2146             memcpy(newRecord->peerMacAddress.a, req->peerMacAddress.a, ETH_ALEN);
2147             newRecord->wmmOrQosEnabled = req->staInfo.wmmOrQosEnabled;
2148
2149             /* maxSpLength is bit map in qosInfo field, so converting accordingly */
2150             newRecord->maxSpLength = req->staInfo.maxSpLength * 2;
2151
2152             /*Max SP 0 mean any number of packets. since we buffer only 512
2153             packets we are hard coding this to zero for the moment */
2154
2155             if(newRecord->maxSpLength == 0)
2156                 newRecord->maxSpLength=512;
2157
2158             newRecord->assignedHandle = i;
2159
2160              /* copy power save mode of all access catagory (Trigger/Delivery/both enabled/disabled) */
2161             powerModeTemp = (CsrUint8) ((req->staInfo.powersaveMode >> 4) & 0xff);
2162
2163             if(!(req->staInfo.powersaveMode & 0x0001))
2164                 newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BK]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
2165             else
2166                newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BK]= powerModeTemp & 0x03;
2167
2168             if(!(req->staInfo.powersaveMode & 0x0002))
2169                 newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BE]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
2170             else
2171                newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BE]= ((powerModeTemp & 0x0C)>> 2);
2172
2173             if(!(req->staInfo.powersaveMode & 0x0004))
2174                 newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VI]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
2175             else
2176                newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VI]= ((powerModeTemp & 0x30)>> 4);
2177
2178             if(!(req->staInfo.powersaveMode & 0x0008))
2179                 newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
2180             else
2181                newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]= ((powerModeTemp & 0xC0)>> 6);
2182
2183             {
2184                 CsrUint8 k;
2185                 for(k=0; k< MAX_ACCESS_CATOGORY ;k++)
2186                     unifi_trace(priv, UDBG2, "peer_add_new_record: WMM : %d ,AC %d, powersaveMode %x \n",
2187                             req->staInfo.wmmOrQosEnabled,k,newRecord->powersaveMode[k]);
2188             }
2189
2190             unifi_trace(priv, UDBG3, "newRecord->wmmOrQosEnabled : %d , MAX SP : %d\n",
2191                     newRecord->wmmOrQosEnabled,newRecord->maxSpLength);
2192
2193             /* Initialize the mgtFrames & data Pdu list */
2194             {
2195                 CsrUint8 j;
2196                 INIT_LIST_HEAD(&newRecord->mgtFrames);
2197                 for(j = 0; j < MAX_ACCESS_CATOGORY; j++) {
2198                     INIT_LIST_HEAD(&newRecord->dataPdu[j]);
2199                 }
2200             }
2201
2202             newRecord->lastActivity = currentTime;
2203             newRecord->activity_flag = TRUE;
2204
2205             /* enable the preemption as station record updated */
2206             spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2207
2208             /* First time port actions are set for the peer with below information */
2209             configure_data_port(priv, CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN, &newRecord->peerMacAddress,
2210                                 UF_UNCONTROLLED_PORT_Q, req->interfaceTag);
2211
2212             if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS) {
2213                 configure_data_port(priv, CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN, &newRecord->peerMacAddress,
2214                                     UF_CONTROLLED_PORT_Q, req->interfaceTag);
2215             } else {
2216                 configure_data_port(priv, CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD, &newRecord->peerMacAddress,
2217                                     UF_CONTROLLED_PORT_Q, req->interfaceTag);
2218             }
2219
2220
2221             spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2222             /* Port status must be already set before calling the Add Peer request */
2223             newRecord->peerControlledPort = uf_sme_port_config_handle(priv, newRecord->peerMacAddress.a,
2224                                                                       UF_CONTROLLED_PORT_Q, req->interfaceTag);
2225             newRecord->peerUnControlledPort = uf_sme_port_config_handle(priv, newRecord->peerMacAddress.a,
2226                                                                         UF_UNCONTROLLED_PORT_Q, req->interfaceTag);
2227
2228             if (!newRecord->peerControlledPort || !newRecord->peerUnControlledPort) {
2229                 /* enable the preemption as station record failed to update */
2230                 unifi_warning(priv, "Un/ControlledPort record not found in port configuration array index = %d\n", i);
2231                 kfree(interfacePriv->staInfo[i]);
2232                 interfacePriv->staInfo[i] = NULL;
2233                 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2234                 return CSR_RESULT_FAILURE;
2235             }
2236
2237             newRecord->currentPeerState = CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE;
2238
2239             /* changes done during block ack handling */
2240             newRecord->txSuspend = FALSE;
2241
2242             /*U-APSD related data structure*/
2243             newRecord->timRequestPendingFlag = FALSE;
2244
2245             /* Initialise the variable updateTimReqQueued with a value
2246              * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
2247              */
2248             newRecord->updateTimReqQueued = 0xFF;
2249             newRecord->timSet = CSR_WIFI_TIM_RESET;
2250             newRecord->uapsdActive = FALSE;
2251             newRecord->noOfSpFramesSent =0;
2252             newRecord->triggerFramePriority = CSR_QOS_UP0;
2253
2254             /* The protection bit is updated once the port opens for corresponding peer in
2255              * routerPortConfigure request */
2256
2257             /* update the association ID */
2258             newRecord->aid = req->associationId;
2259
2260 #ifdef CSR_SUPPORT_SME
2261             interfacePriv->num_stations_joined++;
2262             newRecord->interfacePriv = interfacePriv;
2263             newRecord->listenIntervalInTus = req->staInfo.listenIntervalInTus;
2264             newRecord->nullDataHostTag = INVALID_HOST_TAG;
2265
2266             INIT_WORK(&newRecord->send_disconnected_ind_task, uf_send_disconnected_ind_wq);
2267
2268             if(!(interfacePriv->sta_activity_check_enabled) &&
2269                (interfacePriv->num_stations_joined >= STA_INACTIVE_DETECTION_TRIGGER_THRESHOLD)){
2270                 unifi_trace(priv, UDBG1,
2271                             "peer_add_new_record: STARTING the Inactivity Timer (num of stations = %d)",
2272                             interfacePriv->num_stations_joined);
2273
2274                 interfacePriv->sta_activity_check_enabled = TRUE;
2275                 interfacePriv->sta_activity_check_timer.function = check_inactivity_timer_expire_func;
2276                 interfacePriv->sta_activity_check_timer.data = (unsigned long)interfacePriv;
2277
2278                 init_timer(&interfacePriv->sta_activity_check_timer);
2279                 mod_timer(&interfacePriv->sta_activity_check_timer,
2280                           (jiffies + usecs_to_jiffies(STA_INACTIVE_DETECTION_TIMER_INTERVAL * 1000 * 1000)));
2281
2282             }
2283 #endif
2284             spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2285             break;
2286         }
2287     }
2288
2289     if(!freeSlotFound) {
2290         unifi_error(priv, "Limited connectivity, Free slot not found for station record addition\n");
2291         return CSR_RESULT_FAILURE;
2292     }
2293     return CSR_RESULT_SUCCESS;
2294 }
2295
2296 #ifdef CSR_SUPPORT_SME
2297 static void check_inactivity_timer_expire_func(unsigned long data)
2298 {
2299     struct unifi_priv *priv;
2300     CsrWifiRouterCtrlStaInfo_t *sta_record = NULL;
2301     CsrUint8 i = 0;
2302     CsrTime now;
2303     CsrTime inactive_time;
2304     netInterface_priv_t *interfacePriv = (netInterface_priv_t *) data;
2305
2306     if (!interfacePriv)
2307     {
2308         return;
2309     }
2310
2311     priv = interfacePriv->privPtr;
2312
2313     if (interfacePriv->InterfaceTag >= CSR_WIFI_NUM_INTERFACES)
2314     {
2315         unifi_error(priv, "check_inactivity_timer_expire_func: Invalid interfaceTag\n");
2316         return;
2317     }
2318
2319     /* RUN Algorithm to check inactivity for each connected station */
2320     now = CsrTimeGet(NULL);
2321
2322     for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
2323         if(interfacePriv->staInfo[i] != NULL) {
2324             sta_record = interfacePriv->staInfo[i];
2325
2326             if (sta_record->activity_flag == TRUE){
2327                 sta_record->activity_flag = FALSE;
2328                 sta_record->lastActivity = now;
2329                 continue;
2330             }
2331
2332             if (sta_record->lastActivity > now)
2333             {
2334                 /* simple timer wrap (for 1 wrap) */
2335                 inactive_time = CsrTimeAdd((CsrTime)CsrTimeSub(CSR_SCHED_TIME_MAX, sta_record->lastActivity), now);
2336             }
2337             else
2338             {
2339                 inactive_time = (CsrTime)CsrTimeSub(now, sta_record->lastActivity);
2340             }
2341
2342             if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL)
2343             {
2344                 unifi_trace(priv, UDBG1, "STA is Inactive - AID = %d inactive_time = %d\n",
2345                                         sta_record->aid,
2346                                         inactive_time);
2347
2348                 /* station is in-active, if it is in active mode send a null frame
2349                  * and the station should acknowledge the null frame, if acknowledgement
2350                  * is not received throw out the station.
2351                  * If the station is in Power Save, update TIM for the station so
2352                  * that it wakes up and register some activity through PS-Poll or
2353                  * trigger frame.
2354                  */
2355                  if (sta_record->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)
2356                  {
2357                     unifi_trace(priv, UDBG1, "STA power save state - Active, send a NULL frame to check if it is ALIVE\n");
2358                     uf_send_nulldata ( priv,
2359                                        sta_record->interfacePriv->InterfaceTag,
2360                                        sta_record->peerMacAddress.a,
2361                                        CSR_CONTENTION,
2362                                        sta_record);
2363                  }
2364                  else if (sta_record->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
2365                  {
2366                     if((sta_record->timSet == CSR_WIFI_TIM_SET) ||
2367                        (sta_record->timSet == CSR_WIFI_TIM_SETTING))
2368                     {
2369                         unifi_trace(priv, UDBG1, "STA power save state - PS, TIM is already SET\n");
2370
2371                         /* If TIM is set and we do not have any activity for
2372                          * more than 3 listen intervals then send a disconnected
2373                          * indication to SME, to delete the station from station
2374                          * record list.
2375                          * The inactivity is already more than STA_INACTIVE_TIMEOUT_VAL
2376                          * and this check ensures if the listen interval is a larger
2377                          * value than STA_INACTIVE_TIMEOUT_VAL.
2378                          */
2379                          if (inactive_time > (3 * (sta_record->listenIntervalInTus * 1024)))
2380                          {
2381                             unifi_trace(priv, UDBG1, "STA is inactive for more than 3 listen intervals\n");
2382                             queue_work( priv->unifi_workqueue,
2383                                         &sta_record->send_disconnected_ind_task);
2384                          }
2385
2386                     }
2387                     else
2388                     {
2389                         unifi_trace(priv, UDBG1, "STA power save state - PS, update TIM to see if it is ALIVE\n");
2390                         update_tim(priv,
2391                                    sta_record->aid,
2392                                    CSR_WIFI_TIM_SET,
2393                                    interfacePriv->InterfaceTag,
2394                                    sta_record->assignedHandle);
2395                     }
2396                  }
2397             }
2398         }
2399     }
2400
2401     /* re-run the timer interrupt */
2402     mod_timer(&interfacePriv->sta_activity_check_timer,
2403               (jiffies + usecs_to_jiffies(STA_INACTIVE_DETECTION_TIMER_INTERVAL * 1000 * 1000)));
2404
2405 }
2406
2407
2408 void uf_send_disconnected_ind_wq(struct work_struct *work)
2409 {
2410
2411     CsrWifiRouterCtrlStaInfo_t *staInfo = container_of(work, CsrWifiRouterCtrlStaInfo_t, send_disconnected_ind_task);
2412     unifi_priv_t *priv;
2413     CsrUint16 interfaceTag;
2414     struct list_head send_cfm_list;
2415     CsrUint8 j;
2416
2417     func_enter();
2418
2419     if(!staInfo) {
2420         return;
2421     }
2422
2423     if(!staInfo->interfacePriv) {
2424         return;
2425     }
2426
2427     priv = staInfo->interfacePriv->privPtr;
2428     interfaceTag =  staInfo->interfacePriv->InterfaceTag;
2429
2430     if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2431         unifi_error(priv, "uf_send_disconnected_ind_wq: invalid interfaceTag\n");
2432         return;
2433     }
2434
2435     /* The SME/NME may be waiting for confirmation for requested frames to this station.
2436      * So loop through buffered frames for this station and if confirmation is
2437      * requested, send auto confirmation with failure status. Also flush the frames so
2438      * that these are not processed again in PEER_DEL_REQ handler.
2439      */
2440     INIT_LIST_HEAD(&send_cfm_list);
2441
2442     uf_prepare_send_cfm_list_for_queued_pkts(priv,
2443                                              &send_cfm_list,
2444                                              &(staInfo->mgtFrames));
2445
2446     uf_flush_list(priv, &(staInfo->mgtFrames));
2447
2448     for(j = 0; j < MAX_ACCESS_CATOGORY; j++){
2449         uf_prepare_send_cfm_list_for_queued_pkts(priv,
2450                                                  &send_cfm_list,
2451                                                  &(staInfo->dataPdu[j]));
2452
2453         uf_flush_list(priv,&(staInfo->dataPdu[j]));
2454     }
2455
2456     send_auto_ma_packet_confirm(priv, staInfo->interfacePriv, &send_cfm_list);
2457
2458     unifi_warning(priv, "uf_send_disconnected_ind_wq: Router Disconnected IND Peer (%x-%x-%x-%x-%x-%x)\n",
2459                 staInfo->peerMacAddress.a[0],
2460                 staInfo->peerMacAddress.a[1],
2461                 staInfo->peerMacAddress.a[2],
2462                 staInfo->peerMacAddress.a[3],
2463                 staInfo->peerMacAddress.a[4],
2464                 staInfo->peerMacAddress.a[5]);
2465
2466     CsrWifiRouterCtrlConnectedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,
2467                                       0,
2468                                       staInfo->interfacePriv->InterfaceTag,
2469                                       staInfo->peerMacAddress,
2470                                       CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED);
2471
2472
2473     return;
2474 }
2475
2476
2477 #endif
2478 void CsrWifiRouterCtrlPeerAddReqHandler(void* drvpriv,CsrWifiFsmEvent* msg)
2479 {
2480     CsrWifiRouterCtrlPeerAddReq* req = (CsrWifiRouterCtrlPeerAddReq*)msg;
2481     CsrResult status = CSR_RESULT_SUCCESS;
2482     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2483     CsrUint32 handle = 0;
2484     netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
2485
2486     unifi_trace(priv, UDBG2, "entering CsrWifiRouterCtrlPeerAddReqHandler \n");
2487     if (priv == NULL)
2488     {
2489         unifi_error(priv, "CsrWifiRouterCtrlPeerAddReqHandler: invalid smepriv\n");
2490         return;
2491     }
2492
2493     if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES)
2494     {
2495         unifi_error(priv, "CsrWifiRouterCtrlPeerAddReqHandler: bad interfaceTag\n");
2496         return;
2497     }
2498
2499     switch(interfacePriv->interfaceMode)
2500     {
2501         case CSR_WIFI_ROUTER_CTRL_MODE_AP:
2502         case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
2503         case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
2504             /* Add station record */
2505             status = peer_add_new_record(priv,req,&handle);
2506             break;
2507         case CSR_WIFI_ROUTER_CTRL_MODE_STA:
2508         case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
2509         default:
2510             /* No station record to maintain in these modes */
2511             break;
2512     }
2513
2514     CsrWifiRouterCtrlPeerAddCfmSend(msg->source,req->clientData,req->interfaceTag,req->peerMacAddress,handle,status);
2515     unifi_trace(priv, UDBG2, "leaving CsrWifiRouterCtrlPeerAddReqHandler \n");
2516 }
2517
2518 void CsrWifiRouterCtrlPeerUpdateReqHandler(void* drvpriv,CsrWifiFsmEvent* msg)
2519 {
2520     CsrWifiRouterCtrlPeerUpdateReq* req = (CsrWifiRouterCtrlPeerUpdateReq*)msg;
2521     CsrResult status = CSR_RESULT_SUCCESS;
2522     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2523
2524     unifi_trace(priv, UDBG2, "entering CsrWifiRouterCtrlPeerUpdateReqHandler \n");
2525     if (priv == NULL)
2526     {
2527         unifi_error(priv, "CsrWifiRouterCtrlPeerUpdateReqHandler: invalid smepriv\n");
2528         return;
2529     }
2530
2531     CsrWifiRouterCtrlPeerUpdateCfmSend(msg->source,req->clientData,req->interfaceTag,status);
2532     unifi_trace(priv, UDBG2, "leaving CsrWifiRouterCtrlPeerUpdateReqHandler \n");
2533 }
2534
2535
2536  void CsrWifiRouterCtrlRawSdioDeinitialiseReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2537 {
2538     /* This will never be called as it is intercepted in the Userspace */
2539 }
2540
2541 void CsrWifiRouterCtrlRawSdioInitialiseReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2542 {
2543     /* This will never be called as it is intercepted in the Userspace */
2544 }
2545
2546 void
2547 uf_send_ba_err_wq(struct work_struct *work)
2548 {
2549     ba_session_rx_struct *ba_session = container_of(work, ba_session_rx_struct, send_ba_err_task);
2550     unifi_priv_t *priv;
2551
2552     if(!ba_session) {
2553         return;
2554     }
2555
2556     if(!ba_session->interfacePriv) {
2557         return;
2558     }
2559
2560     priv = ba_session->interfacePriv->privPtr;
2561
2562     if (ba_session->interfacePriv->InterfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2563         unifi_error(priv, "%s: invalid interfaceTag\n", __FUNCTION__);
2564         return;
2565     }
2566
2567     unifi_warning(priv, "%s: Calling CsrWifiRouterCtrlBlockAckErrorIndSend(%d, %d, %d, %d, %x:%x:%x:%x:%x:%x, %d)\n",
2568                     __FUNCTION__,
2569                     priv->CSR_WIFI_SME_IFACEQUEUE,
2570                     0,
2571                     ba_session->interfacePriv->InterfaceTag,
2572                     ba_session->tID,
2573                     ba_session->macAddress.a[0],
2574                     ba_session->macAddress.a[1],
2575                     ba_session->macAddress.a[2],
2576                     ba_session->macAddress.a[3],
2577                     ba_session->macAddress.a[4],
2578                     ba_session->macAddress.a[5],
2579                     CSR_RESULT_SUCCESS
2580                  );
2581     CsrWifiRouterCtrlBlockAckErrorIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,
2582                     0,
2583                     ba_session->interfacePriv->InterfaceTag,
2584                     ba_session->tID,
2585                     ba_session->macAddress,
2586                     CSR_RESULT_SUCCESS);
2587 }
2588
2589
2590 static void ba_session_terminate_timer_func(unsigned long data)
2591 {
2592     ba_session_rx_struct *ba_session = (ba_session_rx_struct*)data;
2593     struct unifi_priv *priv;
2594
2595     if(!ba_session) {
2596         return;
2597     }
2598
2599     if(!ba_session->interfacePriv) {
2600         return;
2601     }
2602
2603     priv = ba_session->interfacePriv->privPtr;
2604
2605     if (ba_session->interfacePriv->InterfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2606         unifi_error(priv, "%s: invalid interfaceTag\n", __FUNCTION__);
2607         return;
2608     }
2609
2610     queue_work(priv->unifi_workqueue, &ba_session->send_ba_err_task);
2611 }
2612
2613
2614 CsrBool blockack_session_stop(unifi_priv_t *priv,
2615                                      CsrUint16 interfaceTag,
2616                                      CsrWifiRouterCtrlBlockAckRole role,
2617                                      CsrUint16 tID,
2618                                      CsrWifiMacAddress macAddress)
2619 {
2620     netInterface_priv_t *interfacePriv;
2621     ba_session_rx_struct *ba_session_rx = NULL;
2622     ba_session_tx_struct *ba_session_tx = NULL;
2623     CsrUint8 ba_session_idx = 0;
2624     int i;
2625
2626     if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2627         unifi_error(priv, "%s: bad interfaceTag = %d\n", __FUNCTION__, interfaceTag);
2628         return FALSE;
2629     }
2630
2631     interfacePriv = priv->interfacePriv[interfaceTag];
2632
2633     if(!interfacePriv) {
2634         unifi_error(priv, "%s: bad interfacePriv\n", __FUNCTION__);
2635         return FALSE;
2636     }
2637
2638     if(tID > 15) {
2639         unifi_error(priv, "%s: bad tID = %d\n", __FUNCTION__, tID);
2640         return FALSE;
2641     }
2642
2643     if((role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR) &&
2644         (role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT)) {
2645         unifi_error(priv, "%s: bad role = %d\n", __FUNCTION__, role);
2646         return FALSE;
2647         }
2648
2649         unifi_warning(priv,
2650                 "%s: stopping ba_session for peer = %pM role = %d tID = %d\n",
2651                 __func__, macAddress.a, role, tID);
2652
2653     /* find out the appropriate ba session (/station /tid /role) for which stop is requested */
2654     if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT){
2655         for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
2656
2657             ba_session_rx = interfacePriv->ba_session_rx[ba_session_idx];
2658
2659             if(ba_session_rx){
2660                 if ((!memcmp(ba_session_rx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_rx->tID == tID)){
2661                     break;
2662                 }
2663             }
2664         }
2665
2666         if (!ba_session_rx || (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX)) {
2667             unifi_error(priv, "%s: bad ba_session for Rx [tID=%d]\n", __FUNCTION__, tID);
2668             return FALSE;
2669         }
2670
2671
2672         if(ba_session_rx->timeout) {
2673             del_timer_sync(&ba_session_rx->timer);
2674         }
2675         cancel_work_sync(&ba_session_rx->send_ba_err_task);
2676         for (i = 0; i < ba_session_rx->wind_size; i++) {
2677             if(ba_session_rx->buffer[i].active) {
2678                 frame_desc_struct *frame_desc = &ba_session_rx->buffer[i];
2679                 unifi_net_data_free(priv, &frame_desc->bulkdata.d[0]);
2680             }
2681         }
2682         kfree(ba_session_rx->buffer);
2683
2684         interfacePriv->ba_session_rx[ba_session_idx] = NULL;
2685         kfree(ba_session_rx);
2686     }else if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR){
2687         for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){
2688         ba_session_tx = interfacePriv->ba_session_tx[ba_session_idx];
2689             if(ba_session_tx){
2690                 if ((!memcmp(ba_session_tx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_tx->tID == tID)){
2691                     break;
2692                 }
2693             }
2694         }
2695
2696         if (!ba_session_tx || (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_TX)) {
2697             unifi_error(priv, "%s: bad ba_session for Tx [tID=%d]\n", __FUNCTION__, tID);
2698             return FALSE;
2699         }
2700         interfacePriv->ba_session_tx[ba_session_idx] = NULL;
2701         kfree(ba_session_tx);
2702
2703     }
2704
2705     return TRUE;
2706 }
2707
2708
2709 void CsrWifiRouterCtrlBlockAckDisableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2710 {
2711     CsrWifiRouterCtrlBlockAckDisableReq* req = (CsrWifiRouterCtrlBlockAckDisableReq*)msg;
2712     CsrBool r;
2713     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2714
2715     unifi_trace(priv, UDBG6, "%s: in ok\n", __FUNCTION__);
2716
2717     down(&priv->ba_mutex);
2718     r = blockack_session_stop(priv,
2719                               req->interfaceTag,
2720                               req->role,
2721                               req->trafficStreamID,
2722                               req->macAddress);
2723     up(&priv->ba_mutex);
2724
2725     CsrWifiRouterCtrlBlockAckDisableCfmSend(msg->source,
2726                                             req->clientData,
2727                                             req->interfaceTag,
2728                                             r?CSR_RESULT_SUCCESS:CSR_RESULT_FAILURE);
2729
2730     unifi_trace(priv, UDBG6, "%s: out ok\n", __FUNCTION__);
2731 }
2732
2733
2734 CsrBool blockack_session_start(unifi_priv_t *priv,
2735                                CsrUint16 interfaceTag,
2736                                CsrUint16 tID,
2737                                CsrUint16 timeout,
2738                                CsrWifiRouterCtrlBlockAckRole role,
2739                                CsrUint16 wind_size,
2740                                CsrUint16 start_sn,
2741                                CsrWifiMacAddress macAddress
2742                               )
2743 {
2744     netInterface_priv_t *interfacePriv;
2745     ba_session_rx_struct *ba_session_rx = NULL;
2746     ba_session_tx_struct *ba_session_tx = NULL;
2747     CsrUint8 ba_session_idx = 0;
2748
2749
2750     if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2751         unifi_error(priv, "%s: bad interfaceTag = %d\n", __FUNCTION__, interfaceTag);
2752         return FALSE;
2753     }
2754
2755     interfacePriv = priv->interfacePriv[interfaceTag];
2756
2757     if(!interfacePriv) {
2758         unifi_error(priv, "%s: bad interfacePriv\n", __FUNCTION__);
2759         return FALSE;
2760     }
2761
2762     if(tID > 15)
2763     {
2764         unifi_error(priv, "%s: bad tID=%d\n", __FUNCTION__, tID);
2765         return FALSE;
2766     }
2767
2768     if(wind_size > MAX_BA_WIND_SIZE) {
2769         unifi_error(priv, "%s: bad wind_size = %d\n", __FUNCTION__, wind_size);
2770         return FALSE;
2771     }
2772
2773     if(role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR &&
2774        role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT) {
2775         unifi_error(priv, "%s: bad role = %d\n", __FUNCTION__, role);
2776         return FALSE;
2777     }
2778
2779         unifi_warning(priv,
2780                 "%s: ba session with peer= (%pM)\n", __func__,
2781                 macAddress.a);
2782
2783     unifi_warning(priv, "%s: ba session for tID=%d timeout=%d role=%d wind_size=%d start_sn=%d\n", __FUNCTION__,
2784                   tID,
2785                   timeout,
2786                   role,
2787                   wind_size,
2788                   start_sn);
2789
2790     /* Check if BA session exists for per station, per TID, per role or not.
2791     if BA session exists update parameters and if it does not exist
2792     create a new BA session */
2793     if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR){
2794         for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){
2795             ba_session_tx = interfacePriv->ba_session_tx[ba_session_idx];
2796             if (ba_session_tx) {
2797                 if ((!memcmp(ba_session_tx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_tx->tID == tID)){
2798                     unifi_warning(priv, "%s: ba_session for Tx already exists\n", __FUNCTION__);
2799                     return TRUE;
2800                 }
2801             }
2802         }
2803
2804         /* we have to create new ba_session_tx struct */
2805          ba_session_tx = NULL;
2806
2807         /* loop through until an empty BA session slot is there and save the session there */
2808         for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX ; ba_session_idx++){
2809             if (!(interfacePriv->ba_session_tx[ba_session_idx])){
2810                 break;
2811             }
2812         }
2813         if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_TX){
2814             unifi_error(priv, "%s: All ba_session used for Tx, NO free session available\n", __FUNCTION__);
2815             return FALSE;
2816         }
2817
2818         /* create and populate the new BA session structure */
2819         ba_session_tx = kmalloc(sizeof(ba_session_tx_struct), GFP_KERNEL);
2820         if (!ba_session_tx) {
2821             unifi_error(priv, "%s: kmalloc failed for ba_session_tx\n", __FUNCTION__);
2822             return FALSE;
2823         }
2824         memset(ba_session_tx, 0, sizeof(ba_session_tx_struct));
2825
2826         ba_session_tx->interfacePriv = interfacePriv;
2827         ba_session_tx->tID = tID;
2828         ba_session_tx->macAddress = macAddress;
2829
2830         interfacePriv->ba_session_tx[ba_session_idx] = ba_session_tx;
2831
2832     } else if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT){
2833
2834         for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
2835             ba_session_rx = interfacePriv->ba_session_rx[ba_session_idx];
2836             if (ba_session_rx) {
2837                 if ((!memcmp(ba_session_rx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_rx->tID == tID)){
2838                     unifi_warning(priv, "%s: ba_session for Rx[tID = %d] already exists\n", __FUNCTION__, tID);
2839
2840                     if(ba_session_rx->wind_size == wind_size &&
2841                         ba_session_rx->timeout == timeout &&
2842                         ba_session_rx->expected_sn == start_sn) {
2843                         return TRUE;
2844                     }
2845
2846                     if(ba_session_rx->timeout) {
2847                         del_timer_sync(&ba_session_rx->timer);
2848                         ba_session_rx->timeout = 0;
2849                     }
2850
2851                     if(ba_session_rx->wind_size != wind_size) {
2852                         blockack_session_stop(priv, interfaceTag, role, tID, macAddress);
2853                     } else {
2854                         if (timeout) {
2855                             ba_session_rx->timeout = timeout;
2856                             ba_session_rx->timer.function = ba_session_terminate_timer_func;
2857                             ba_session_rx->timer.data = (unsigned long)ba_session_rx;
2858                             init_timer(&ba_session_rx->timer);
2859                             mod_timer(&ba_session_rx->timer, (jiffies + usecs_to_jiffies((ba_session_rx->timeout) * 1024)));
2860                         }
2861                         /*
2862                          * The starting sequence number shall remain same if the BA
2863                          * enable request is issued to update BA parameters only. If
2864                          * it is not same, then we scroll our window to the new starting
2865                          * sequence number. This could happen if the DELBA frame from
2866                          * originator is lost and then we receive ADDBA frame with new SSN.
2867                         */
2868                         if(ba_session_rx->start_sn != start_sn) {
2869                             scroll_ba_window(priv, interfacePriv, ba_session_rx, start_sn);
2870                         }
2871                         return TRUE;
2872                     }
2873                 }
2874             }
2875         }
2876
2877         /* we could have a valid BA session pointer here or un-initialized
2878         ba session pointer. but in any case we have to create a new session.
2879         so re-initialize the ba_session pointer */
2880         ba_session_rx = NULL;
2881
2882         /* loop through until an empty BA session slot is there and save the session there */
2883         for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX ; ba_session_idx++){
2884             if (!(interfacePriv->ba_session_rx[ba_session_idx])){
2885                 break;
2886             }
2887         }
2888         if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX){
2889             unifi_error(priv, "%s: All ba_session used for Rx, NO free session available\n", __FUNCTION__);
2890             return FALSE;
2891         }
2892
2893         /* It is observed that with some devices there is a race between
2894          * EAPOL exchanges and BA session establishment. This results in
2895          * some EAPOL authentication packets getting stuck in BA reorder
2896          * buffer and hence the conection cannot be established. To avoid
2897          * this we check here if the EAPOL authentication is complete and
2898          * if so then only allow the BA session to establish.
2899          *
2900          * It is verified that the peers normally re-establish
2901          * the BA session after the initial rejection.
2902          */
2903         if (CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN != uf_sme_port_state(priv, macAddress.a, UF_CONTROLLED_PORT_Q, interfacePriv->InterfaceTag))
2904         {
2905             unifi_warning(priv, "blockack_session_start: Controlled port not opened, Reject BA request\n");
2906             return FALSE;
2907         }
2908
2909         ba_session_rx = kmalloc(sizeof(ba_session_rx_struct), GFP_KERNEL);
2910         if (!ba_session_rx) {
2911             unifi_error(priv, "%s: kmalloc failed for ba_session_rx\n", __FUNCTION__);
2912             return FALSE;
2913         }
2914         memset(ba_session_rx, 0, sizeof(ba_session_rx_struct));
2915
2916         ba_session_rx->wind_size = wind_size;
2917         ba_session_rx->start_sn = ba_session_rx->expected_sn = start_sn;
2918         ba_session_rx->trigger_ba_after_ssn = FALSE;
2919
2920         ba_session_rx->buffer = kmalloc(ba_session_rx->wind_size*sizeof(frame_desc_struct), GFP_KERNEL);
2921         if (!ba_session_rx->buffer) {
2922             kfree(ba_session_rx);
2923             unifi_error(priv, "%s: kmalloc failed for buffer\n", __FUNCTION__);
2924             return FALSE;
2925         }
2926
2927         memset(ba_session_rx->buffer, 0, ba_session_rx->wind_size*sizeof(frame_desc_struct));
2928
2929         INIT_WORK(&ba_session_rx->send_ba_err_task, uf_send_ba_err_wq);
2930         if (timeout) {
2931             ba_session_rx->timeout = timeout;
2932             ba_session_rx->timer.function = ba_session_terminate_timer_func;
2933             ba_session_rx->timer.data = (unsigned long)ba_session_rx;
2934             init_timer(&ba_session_rx->timer);
2935             mod_timer(&ba_session_rx->timer, (jiffies + usecs_to_jiffies((ba_session_rx->timeout) * 1024)));
2936         }
2937
2938         ba_session_rx->interfacePriv = interfacePriv;
2939         ba_session_rx->tID = tID;
2940         ba_session_rx->macAddress = macAddress;
2941
2942         interfacePriv->ba_session_rx[ba_session_idx] = ba_session_rx;
2943     }
2944     return TRUE;
2945 }
2946
2947 void CsrWifiRouterCtrlBlockAckEnableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2948 {
2949     CsrWifiRouterCtrlBlockAckEnableReq* req = (CsrWifiRouterCtrlBlockAckEnableReq*)msg;
2950     CsrBool r;
2951     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2952
2953     unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
2954     down(&priv->ba_mutex);
2955     r = blockack_session_start(priv,
2956                                req->interfaceTag,
2957                                req->trafficStreamID,
2958                                req->timeout,
2959                                req->role,
2960                                req->bufferSize,
2961                                req->ssn,
2962                                req->macAddress
2963                               );
2964     up(&priv->ba_mutex);
2965
2966     CsrWifiRouterCtrlBlockAckEnableCfmSend(msg->source,
2967                                            req->clientData,
2968                                            req->interfaceTag,
2969                                            r?CSR_RESULT_SUCCESS:CSR_RESULT_FAILURE);
2970     unifi_trace(priv, UDBG6, "<<%s: r=%d\n", __FUNCTION__, r);
2971
2972 }
2973
2974 void CsrWifiRouterCtrlWapiMulticastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2975 {
2976 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
2977
2978     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2979     CsrWifiRouterCtrlWapiMulticastFilterReq* req = (CsrWifiRouterCtrlWapiMulticastFilterReq*)msg;
2980     netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
2981
2982     if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
2983
2984         unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
2985
2986         unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiMulticastFilterReq: req->status = %d\n", req->status);
2987
2988         /* status 1 - Filter on
2989         * status 0 - Filter off */
2990         priv->wapi_multicast_filter = req->status;
2991
2992         unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
2993     } else {
2994
2995         unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
2996
2997     }
2998 #elif defined(UNIFI_DEBUG)
2999     /*WAPI Disabled*/
3000     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3001     unifi_error(priv,"CsrWifiRouterCtrlWapiMulticastFilterReqHandler: called when WAPI isn't enabled\n");
3002 #endif
3003 }
3004
3005 void CsrWifiRouterCtrlWapiUnicastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
3006 {
3007 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
3008
3009     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3010     CsrWifiRouterCtrlWapiUnicastFilterReq* req = (CsrWifiRouterCtrlWapiUnicastFilterReq*)msg;
3011     netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
3012
3013     if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
3014
3015         unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
3016
3017         unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastFilterReq: req->status= %d\n", req->status);
3018
3019         if ((priv->wapi_unicast_filter == 1) && (req->status == 0)) {
3020             /* When we have successfully re-associated and obtained a new unicast key with keyid = 0 */
3021             priv->wapi_unicast_queued_pkt_filter = 1;
3022         }
3023
3024         /* status 1 - Filter ON
3025          * status 0 - Filter OFF */
3026         priv->wapi_unicast_filter = req->status;
3027
3028         unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
3029     } else {
3030
3031          unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
3032
3033     }
3034 #elif defined(UNIFI_DEBUG)
3035     /*WAPI Disabled*/
3036     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3037     unifi_error(priv,"CsrWifiRouterCtrlWapiUnicastFilterReqHandler: called when WAPI isn't enabled\n");
3038 #endif
3039 }
3040
3041 void CsrWifiRouterCtrlWapiRxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
3042 {
3043 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
3044
3045     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3046     CsrWifiRouterCtrlWapiRxPktReq* req =  (CsrWifiRouterCtrlWapiRxPktReq*)msg;
3047     int client_id, receiver_id;
3048     bulk_data_param_t bulkdata;
3049     CsrResult res;
3050     ul_client_t *client;
3051     CSR_SIGNAL signal;
3052     CSR_MA_PACKET_INDICATION *pkt_ind;
3053     netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
3054
3055     if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
3056
3057         unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
3058
3059         if (priv == NULL) {
3060             unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq : invalid priv\n",__FUNCTION__);
3061             return;
3062         }
3063
3064         if (priv->smepriv == NULL) {
3065              unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq : invalid sme priv\n",__FUNCTION__);
3066              return;
3067         }
3068
3069         if (req->dataLength == 0 || req->data == NULL) {
3070              unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq: invalid request\n",__FUNCTION__);
3071              return;
3072         }
3073
3074         res = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength);
3075         if (res != CSR_RESULT_SUCCESS) {
3076              unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq: Could not allocate net data\n",__FUNCTION__);
3077              return;
3078         }
3079
3080         /* This function is expected to be called only when the MIC has been verified by SME to be correct
3081          * So reset the reception status to rx_success */
3082         res = read_unpack_signal(req->signal, &signal);
3083         if (res) {
3084                   unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: Received unknown or corrupted signal.\n");
3085                   return;
3086         }
3087         pkt_ind = (CSR_MA_PACKET_INDICATION*) (&((&signal)->u).MaPacketIndication);
3088         if (pkt_ind->ReceptionStatus != CSR_MICHAEL_MIC_ERROR) {
3089                   unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: Unknown signal with reception status = %d\n",pkt_ind->ReceptionStatus);
3090                   return;
3091         } else {
3092                   unifi_trace(priv, UDBG4,"CsrWifiRouterCtrlWapiRxPktReqHandler: MIC verified , RX_SUCCESS \n",__FUNCTION__);
3093                   pkt_ind->ReceptionStatus = CSR_RX_SUCCESS;
3094                   write_pack(&signal, req->signal, &(req->signalLength));
3095         }
3096
3097         memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength);
3098
3099         receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((req->signal) + sizeof(CsrInt16)) & 0xFFF0;
3100         client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT;
3101
3102         client = &priv->ul_clients[client_id];
3103
3104         if (client && client->event_hook) {
3105               unifi_trace(priv, UDBG3,
3106                           "CsrWifiRouterCtrlWapiRxPktReq: "
3107                           "Sending signal to client %d, (s:0x%X, r:0x%X) - Signal 0x%X \n",
3108                           client->client_id, client->sender_id, receiver_id,
3109                           CSR_GET_UINT16_FROM_LITTLE_ENDIAN(req->signal));
3110
3111               client->event_hook(client, req->signal, req->signalLength, &bulkdata, UDI_TO_HOST);
3112         } else {
3113               unifi_trace(priv, UDBG4, "No client to give the packet to\n");
3114               unifi_net_data_free(priv, &bulkdata.d[0]);
3115         }
3116
3117         unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
3118     } else {
3119         unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
3120     }
3121 #elif defined(UNIFI_DEBUG)
3122     /*WAPI Disabled*/
3123     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3124     unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: called when WAPI isn't enabled\n");
3125 #endif
3126 }
3127
3128 void CsrWifiRouterCtrlWapiUnicastTxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
3129 {
3130 #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
3131
3132         unifi_priv_t *priv = (unifi_priv_t*) drvpriv;
3133     CsrWifiRouterCtrlWapiUnicastTxPktReq *req   = (CsrWifiRouterCtrlWapiUnicastTxPktReq*) msg;
3134     netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
3135     bulk_data_param_t bulkdata;
3136     CsrUint8 macHeaderLengthInBytes = MAC_HEADER_SIZE;
3137     /*KeyID, Reserved, PN, MIC*/
3138     CsrUint8 appendedCryptoFields = 1 + 1 + 16 + 16;
3139     CsrResult result;
3140     /* Retrieve the MA PACKET REQ fields from the Signal retained from send_ma_pkt_request() */
3141     CSR_MA_PACKET_REQUEST *storedSignalMAPktReq = &interfacePriv->wapi_unicast_ma_pkt_sig.u.MaPacketRequest;
3142
3143     if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
3144
3145         unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
3146
3147         if (priv == NULL) {
3148             unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler : invalid priv\n",__FUNCTION__);
3149             return;
3150         }
3151         if (priv->smepriv == NULL) {
3152             unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler : invalid sme priv\n",__FUNCTION__);
3153             return;
3154         }
3155         if (req->data == NULL) {
3156             unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: invalid request\n",__FUNCTION__);
3157             return;
3158         } else {
3159             /* If it is QoS data (type = data subtype = QoS), frame header contains QoS control field */
3160             if ((req->data[0] & 0x88) == 0x88) {
3161                 macHeaderLengthInBytes  = macHeaderLengthInBytes + QOS_CONTROL_HEADER_SIZE;
3162             }
3163         }
3164         if ( !(req->dataLength>(macHeaderLengthInBytes+appendedCryptoFields)) ) {
3165             unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: invalid dataLength\n",__FUNCTION__);
3166             return;
3167         }
3168
3169             /* Encrypted DATA Packet contained in (req->data)
3170          * -------------------------------------------------------------------
3171          * |MAC Header|  KeyId   | Reserved |    PN    | xxDataxx | xxMICxxx |
3172          * -------------------------------------------------------------------
3173          *                                             (<-----Encrypted----->)
3174          * -------------------------------------------------------------------
3175          * |24/26(QoS)|    1     |    1     |    16    |    x     |    16    |
3176          * -------------------------------------------------------------------
3177          */
3178         result = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength);
3179         if (result != CSR_RESULT_SUCCESS) {
3180              unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: Could not allocate net data\n",__FUNCTION__);
3181              return;
3182         }
3183         memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength);
3184         bulkdata.d[0].data_length = req->dataLength;
3185         bulkdata.d[1].os_data_ptr = NULL;
3186         bulkdata.d[1].data_length = 0;
3187
3188         /* Send UniFi msg */
3189         /* Here hostTag is been sent as 0xffffffff, its been appended properly while framing MA-Packet request in pdu_processing.c file */
3190         result = uf_process_ma_packet_req(priv,
3191                                           storedSignalMAPktReq->Ra.x,
3192                                           storedSignalMAPktReq->HostTag,/* Ask for a new HostTag */
3193                                           req->interfaceTag,
3194                                           storedSignalMAPktReq->TransmissionControl,
3195                                           storedSignalMAPktReq->TransmitRate,
3196                                           storedSignalMAPktReq->Priority, /* Retained value */
3197                                           interfacePriv->wapi_unicast_ma_pkt_sig.SignalPrimitiveHeader.SenderProcessId, /*FIXME AP: VALIDATE ???*/
3198                                           &bulkdata);
3199
3200         if (result == NETDEV_TX_OK) {
3201              (priv->netdev[req->interfaceTag])->trans_start = jiffies;
3202              /* Should really count tx stats in the UNITDATA.status signal but
3203               * that doesn't have the length.
3204               */
3205              interfacePriv->stats.tx_packets++;
3206
3207              /* count only the packet payload */
3208              interfacePriv->stats.tx_bytes += req->dataLength - macHeaderLengthInBytes - appendedCryptoFields;
3209              unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: (Packet Sent), sent count = %x\n", interfacePriv->stats.tx_packets);
3210         } else {
3211              /* Failed to send: fh queue was full, and the skb was discarded*/
3212              unifi_trace(priv, UDBG1, "(HIP validation failure) Result = %d\n", result);
3213              unifi_net_data_free(priv, &bulkdata.d[0]);
3214
3215              interfacePriv->stats.tx_dropped++;
3216              unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: (Packet Drop), dropped count = %x\n", interfacePriv->stats.tx_dropped);
3217         }
3218
3219         unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
3220
3221     } else {
3222
3223         unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
3224
3225     }
3226 #elif defined(UNIFI_DEBUG)
3227     /*WAPI Disabled*/
3228     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3229     unifi_error(priv,"CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: called when WAPI SW ENCRYPTION isn't enabled\n");
3230 #endif
3231 }
3232
3233 void CsrWifiRouterCtrlWapiFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
3234 {
3235 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
3236
3237 #ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
3238     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3239     CsrWifiRouterCtrlWapiFilterReq* req = (CsrWifiRouterCtrlWapiFilterReq*)msg;
3240     netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
3241
3242     if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
3243
3244         unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
3245
3246         unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiFilterReq: req->isWapiConnected [0/1] = %d \n",req->isWapiConnected);
3247
3248         priv->isWapiConnection = req->isWapiConnected;
3249
3250         unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
3251     } else {
3252
3253         unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
3254
3255     }
3256 #endif
3257
3258 #elif defined(UNIFI_DEBUG)
3259     /*WAPI Disabled*/
3260     unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3261     unifi_error(priv,"CsrWifiRouterCtrlWapiFilterReq: called when WAPI isn't enabled\n");
3262 #endif
3263 }