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