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