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