Root/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
52static void check_inactivity_timer_expire_func(unsigned long data);
53void uf_send_disconnected_ind_wq(struct work_struct *work);
54#endif
55
56void 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
147void 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
271void 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
398static void
399uf_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 */
502static int
503configure_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
662void 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
724void 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 */
854static void
855wifi_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
941void 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
980void 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
1017void 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
1030void 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
1044void 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
1070void 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
1201void CsrWifiRouterCtrlWifiOffResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1202{
1203}
1204
1205
1206void CsrWifiRouterCtrlMulticastAddressResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1207{
1208}
1209
1210
1211void 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
1251void 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
1280void 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
1296void 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
1310void 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
1324void 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
1341void 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
1354static 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
1495void 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
1584void CsrWifiRouterMaPacketCancelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1585{
1586}
1587
1588void 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 */
1641static 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
1726void 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
1786void 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
1910void CsrWifiRouterMaPacketResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1911{
1912}
1913
1914/* delete the station record from the station record data base */
1915static 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
2061void 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 */
2101static 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
2296static 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
2407void 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
2477void 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
2517void 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
2540void CsrWifiRouterCtrlRawSdioInitialiseReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2541{
2542    /* This will never be called as it is intercepted in the Userspace */
2543}
2544
2545void
2546uf_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
2589static 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
2613u8 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
2708void 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
2733u8 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
2946void 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
2973void 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
3004void 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
3040void 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
3127void 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
3232void 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}
3263

Archive Download this file



interactive