Root/drivers/staging/csr/unifi_sme.c

1/*
2 * ***************************************************************************
3 * FILE: unifi_sme.c
4 *
5 * PURPOSE: SME related functions.
6 *
7 * Copyright (C) 2007-2009 by Cambridge Silicon Radio Ltd.
8 *
9 * Refer to LICENSE.txt included with this source code for details on
10 * the license terms.
11 *
12 * ***************************************************************************
13 */
14
15#include "unifi_priv.h"
16#include "csr_wifi_hip_unifi.h"
17#include "csr_wifi_hip_conversions.h"
18
19
20
21
22    int
23convert_sme_error(CsrResult error)
24{
25    switch (error) {
26        case CSR_RESULT_SUCCESS:
27            return 0;
28        case CSR_RESULT_FAILURE:
29        case CSR_WIFI_RESULT_NOT_FOUND:
30        case CSR_WIFI_RESULT_TIMED_OUT:
31        case CSR_WIFI_RESULT_CANCELLED:
32        case CSR_WIFI_RESULT_UNAVAILABLE:
33            return -EIO;
34        case CSR_WIFI_RESULT_NO_ROOM:
35            return -EBUSY;
36        case CSR_WIFI_RESULT_INVALID_PARAMETER:
37            return -EINVAL;
38        case CSR_WIFI_RESULT_UNSUPPORTED:
39            return -EOPNOTSUPP;
40        default:
41            return -EIO;
42    }
43}
44
45
46/*
47 * ---------------------------------------------------------------------------
48 * sme_log_event
49 *
50 * Callback function to be registered as the SME event callback.
51 * Copies the signal content into a new udi_log_t struct and adds
52 * it to the read queue for the SME client.
53 *
54 * Arguments:
55 * arg This is the value given to unifi_add_udi_hook, in
56 * this case a pointer to the client instance.
57 * signal Pointer to the received signal.
58 * signal_len Size of the signal structure in bytes.
59 * bulkdata Pointers to any associated bulk data.
60 * dir Direction of the signal. Zero means from host,
61 * non-zero means to host.
62 *
63 * Returns:
64 * None.
65 * ---------------------------------------------------------------------------
66 */
67    void
68sme_log_event(ul_client_t *pcli,
69        const u8 *signal, int signal_len,
70        const bulk_data_param_t *bulkdata,
71        int dir)
72{
73    unifi_priv_t *priv;
74    CSR_SIGNAL unpacked_signal;
75    CsrWifiSmeDataBlock mlmeCommand;
76    CsrWifiSmeDataBlock dataref1;
77    CsrWifiSmeDataBlock dataref2;
78    CsrResult result = CSR_RESULT_SUCCESS;
79    int r;
80
81    func_enter();
82    /* Just a sanity check */
83    if ((signal == NULL) || (signal_len <= 0)) {
84        func_exit();
85        return;
86    }
87
88    priv = uf_find_instance(pcli->instance);
89    if (!priv) {
90        unifi_error(priv, "sme_log_event: invalid priv\n");
91        func_exit();
92        return;
93    }
94
95    if (priv->smepriv == NULL) {
96        unifi_error(priv, "sme_log_event: invalid smepriv\n");
97        func_exit();
98        return;
99    }
100
101    unifi_trace(priv, UDBG3,
102            "sme_log_event: Process signal 0x%.4X\n",
103            CSR_GET_UINT16_FROM_LITTLE_ENDIAN(signal));
104
105
106    /* If the signal is known, then do any filtering required, otherwise it pass it to the SME. */
107    r = read_unpack_signal(signal, &unpacked_signal);
108    if (r == CSR_RESULT_SUCCESS) {
109        if ((unpacked_signal.SignalPrimitiveHeader.SignalId == CSR_DEBUG_STRING_INDICATION_ID) ||
110            (unpacked_signal.SignalPrimitiveHeader.SignalId == CSR_DEBUG_WORD16_INDICATION_ID))
111        {
112            func_exit();
113            return;
114        }
115        if (unpacked_signal.SignalPrimitiveHeader.SignalId == CSR_MA_PACKET_INDICATION_ID)
116        {
117            u16 frmCtrl;
118            u8 unicastPdu = TRUE;
119            u8 *macHdrLocation;
120            u8 *raddr = NULL, *taddr = NULL;
121            CsrWifiMacAddress peerMacAddress;
122            /* Check if we need to send CsrWifiRouterCtrlMicFailureInd*/
123            CSR_MA_PACKET_INDICATION *ind = &unpacked_signal.u.MaPacketIndication;
124
125            macHdrLocation = (u8 *) bulkdata->d[0].os_data_ptr;
126            /* Fetch the frame control value from mac header */
127            frmCtrl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(macHdrLocation);
128
129            /* Point to the addresses */
130            raddr = macHdrLocation + MAC_HEADER_ADDR1_OFFSET;
131            taddr = macHdrLocation + MAC_HEADER_ADDR2_OFFSET;
132
133            memcpy(peerMacAddress.a, taddr, ETH_ALEN);
134
135            if(ind->ReceptionStatus == CSR_MICHAEL_MIC_ERROR)
136            {
137                if (*raddr & 0x1)
138                    unicastPdu = FALSE;
139
140                CsrWifiRouterCtrlMicFailureIndSend (priv->CSR_WIFI_SME_IFACEQUEUE, 0,
141                        (ind->VirtualInterfaceIdentifier & 0xff),peerMacAddress,
142                        unicastPdu);
143                return;
144            }
145            else
146            {
147                if(ind->ReceptionStatus == CSR_RX_SUCCESS)
148                {
149                    u8 pmBit = (frmCtrl & 0x1000)?0x01:0x00;
150                    u16 interfaceTag = (ind->VirtualInterfaceIdentifier & 0xff);
151                    CsrWifiRouterCtrlStaInfo_t *srcStaInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,taddr,interfaceTag);
152                    if((srcStaInfo != NULL) && (uf_check_broadcast_bssid(priv, bulkdata)== FALSE))
153                    {
154                        uf_process_pm_bit_for_peer(priv,srcStaInfo,pmBit,interfaceTag);
155
156                        /* Update station last activity flag */
157                        srcStaInfo->activity_flag = TRUE;
158                    }
159                }
160            }
161        }
162
163        if (unpacked_signal.SignalPrimitiveHeader.SignalId == CSR_MA_PACKET_CONFIRM_ID)
164        {
165            CSR_MA_PACKET_CONFIRM *cfm = &unpacked_signal.u.MaPacketConfirm;
166            u16 interfaceTag = (cfm->VirtualInterfaceIdentifier & 0xff);
167            netInterface_priv_t *interfacePriv;
168            CSR_MA_PACKET_REQUEST *req;
169            CsrWifiMacAddress peerMacAddress;
170
171            if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
172            {
173                unifi_error(priv, "Bad MA_PACKET_CONFIRM interfaceTag %d\n", interfaceTag);
174                func_exit();
175                return;
176            }
177
178            unifi_trace(priv,UDBG1,"MA-PACKET Confirm (%x, %x)\n", cfm->HostTag, cfm->TransmissionStatus);
179
180            interfacePriv = priv->interfacePriv[interfaceTag];
181#ifdef CSR_SUPPORT_SME
182            if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
183                 interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
184
185                if(cfm->HostTag == interfacePriv->multicastPduHostTag){
186                    uf_process_ma_pkt_cfm_for_ap(priv ,interfaceTag, cfm);
187                }
188            }
189#endif
190
191            req = &interfacePriv->m4_signal.u.MaPacketRequest;
192
193            if(cfm->HostTag & 0x80000000)
194            {
195                if (cfm->TransmissionStatus != CSR_TX_SUCCESSFUL)
196                {
197                    result = CSR_RESULT_FAILURE;
198                }
199#ifdef CSR_SUPPORT_SME
200                memcpy(peerMacAddress.a, req->Ra.x, ETH_ALEN);
201                /* Check if this is a confirm for EAPOL M4 frame and we need to send transmistted ind*/
202                if (interfacePriv->m4_sent && (cfm->HostTag == interfacePriv->m4_hostTag))
203                {
204                    unifi_trace(priv, UDBG1, "%s: Sending M4 Transmit CFM\n", __FUNCTION__);
205                    CsrWifiRouterCtrlM4TransmittedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0,
206                            interfaceTag,
207                            peerMacAddress,
208                            result);
209                    interfacePriv->m4_sent = FALSE;
210                    interfacePriv->m4_hostTag = 0xffffffff;
211                }
212#endif
213                /* If EAPOL was requested via router APIs then send cfm else ignore*/
214                if((cfm->HostTag & 0x80000000) != CSR_WIFI_EAPOL_M4_HOST_TAG) {
215                    CsrWifiRouterMaPacketCfmSend((u16)signal[2],
216                        cfm->VirtualInterfaceIdentifier,
217                        result,
218                        (cfm->HostTag & 0x3fffffff), cfm->Rate);
219                } else {
220                    unifi_trace(priv, UDBG1, "%s: M4 received from netdevice\n", __FUNCTION__);
221                }
222                func_exit();
223                return;
224            }
225        }
226    }
227
228    mlmeCommand.length = signal_len;
229    mlmeCommand.data = (u8*)signal;
230
231    dataref1.length = bulkdata->d[0].data_length;
232    if (dataref1.length > 0) {
233        dataref1.data = (u8 *) bulkdata->d[0].os_data_ptr;
234    } else
235    {
236        dataref1.data = NULL;
237    }
238
239    dataref2.length = bulkdata->d[1].data_length;
240    if (dataref2.length > 0) {
241        dataref2.data = (u8 *) bulkdata->d[1].os_data_ptr;
242    } else
243    {
244        dataref2.data = NULL;
245    }
246
247    CsrWifiRouterCtrlHipIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, mlmeCommand.length, mlmeCommand.data,
248            dataref1.length, dataref1.data,
249            dataref2.length, dataref2.data);
250
251    func_exit();
252} /* sme_log_event() */
253
254
255/*
256 * ---------------------------------------------------------------------------
257 * uf_sme_port_state
258 *
259 * Return the state of the controlled port.
260 *
261 * Arguments:
262 * priv Pointer to device private context struct
263 * address Pointer to the destination for tx or sender for rx address
264 * queue Controlled or uncontrolled queue
265 *
266 * Returns:
267 * An unifi_ControlledPortAction value.
268 * ---------------------------------------------------------------------------
269 */
270CsrWifiRouterCtrlPortAction
271uf_sme_port_state(unifi_priv_t *priv, unsigned char *address, int queue, u16 interfaceTag)
272{
273    int i;
274    unifi_port_config_t *port;
275    netInterface_priv_t *interfacePriv;
276
277    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
278        unifi_error(priv, "uf_sme_port_state: bad interfaceTag\n");
279        return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
280    }
281
282    interfacePriv = priv->interfacePriv[interfaceTag];
283
284    if (queue == UF_CONTROLLED_PORT_Q) {
285        port = &interfacePriv->controlled_data_port;
286    } else {
287        port = &interfacePriv->uncontrolled_data_port;
288    }
289
290    if (!port->entries_in_use) {
291        unifi_trace(priv, UDBG5, "No port configurations, return Discard.\n");
292        return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
293    }
294
295    /* If the port configuration is common for all destinations, return it. */
296    if (port->overide_action == UF_DATA_PORT_OVERIDE) {
297        unifi_trace(priv, UDBG5, "Single port configuration (%d).\n",
298                port->port_cfg[0].port_action);
299        return port->port_cfg[0].port_action;
300    }
301
302    unifi_trace(priv, UDBG5, "Multiple (%d) port configurations.\n", port->entries_in_use);
303
304    /* If multiple configurations exist.. */
305    for (i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
306        /* .. go through the list and match the destination address. */
307        if (port->port_cfg[i].in_use &&
308            memcmp(address, port->port_cfg[i].mac_address.a, ETH_ALEN) == 0) {
309            /* Return the desired action. */
310            return port->port_cfg[i].port_action;
311        }
312    }
313
314    /* Could not find any information, return Open. */
315    unifi_trace(priv, UDBG5, "port configuration not found, return Open.\n");
316    return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN;
317} /* uf_sme_port_state() */
318
319/*
320 * ---------------------------------------------------------------------------
321 * uf_sme_port_config_handle
322 *
323 * Return the port config handle of the controlled/uncontrolled port.
324 *
325 * Arguments:
326 * priv Pointer to device private context struct
327 * address Pointer to the destination for tx or sender for rx address
328 * queue Controlled or uncontrolled queue
329 *
330 * Returns:
331 * An unifi_port_cfg_t* .
332 * ---------------------------------------------------------------------------
333 */
334unifi_port_cfg_t*
335uf_sme_port_config_handle(unifi_priv_t *priv, unsigned char *address, int queue, u16 interfaceTag)
336{
337    int i;
338    unifi_port_config_t *port;
339    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
340
341    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
342        unifi_error(priv, "uf_sme_port_config_handle: bad interfaceTag\n");
343        return NULL;
344    }
345
346    if (queue == UF_CONTROLLED_PORT_Q) {
347        port = &interfacePriv->controlled_data_port;
348    } else {
349        port = &interfacePriv->uncontrolled_data_port;
350    }
351
352    if (!port->entries_in_use) {
353        unifi_trace(priv, UDBG5, "No port configurations, return Discard.\n");
354        return NULL;
355    }
356
357    /* If the port configuration is common for all destinations, return it. */
358    if (port->overide_action == UF_DATA_PORT_OVERIDE) {
359        unifi_trace(priv, UDBG5, "Single port configuration (%d).\n",
360                port->port_cfg[0].port_action);
361        if (address) {
362            unifi_trace(priv, UDBG5, "addr[0] = %x, addr[1] = %x, addr[2] = %x, addr[3] = %x\n", address[0], address[1], address[2], address[3]);
363        }
364        return &port->port_cfg[0];
365    }
366
367    unifi_trace(priv, UDBG5, "Multiple port configurations.\n");
368
369    /* If multiple configurations exist.. */
370    for (i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
371        /* .. go through the list and match the destination address. */
372        if (port->port_cfg[i].in_use &&
373            memcmp(address, port->port_cfg[i].mac_address.a, ETH_ALEN) == 0) {
374            /* Return the desired action. */
375            return &port->port_cfg[i];
376        }
377    }
378
379    /* Could not find any information, return Open. */
380    unifi_trace(priv, UDBG5, "port configuration not found, returning NULL (debug).\n");
381    return NULL;
382} /* uf_sme_port_config_handle */
383
384void
385uf_multicast_list_wq(struct work_struct *work)
386{
387    unifi_priv_t *priv = container_of(work, unifi_priv_t,
388            multicast_list_task);
389    int i;
390    u16 interfaceTag = 0;
391    CsrWifiMacAddress* multicast_address_list = NULL;
392    int mc_count;
393    u8 *mc_list;
394    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
395
396    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
397        unifi_error(priv, "uf_multicast_list_wq: bad interfaceTag\n");
398        return;
399    }
400
401    unifi_trace(priv, UDBG5,
402            "uf_multicast_list_wq: list count = %d\n",
403            interfacePriv->mc_list_count);
404
405    /* Flush the current list */
406    CsrWifiRouterCtrlMulticastAddressIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, interfaceTag, CSR_WIFI_SME_LIST_ACTION_FLUSH, 0, NULL);
407
408    mc_count = interfacePriv->mc_list_count;
409    mc_list = interfacePriv->mc_list;
410    /*
411     * Allocate a new list, need to free it later
412     * in unifi_mgt_multicast_address_cfm().
413     */
414    multicast_address_list = kmalloc(mc_count * sizeof(CsrWifiMacAddress), GFP_KERNEL);
415
416    if (multicast_address_list == NULL) {
417        return;
418    }
419
420    for (i = 0; i < mc_count; i++) {
421        memcpy(multicast_address_list[i].a, mc_list, ETH_ALEN);
422        mc_list += ETH_ALEN;
423    }
424
425    if (priv->smepriv == NULL) {
426        kfree(multicast_address_list);
427        return;
428    }
429
430    CsrWifiRouterCtrlMulticastAddressIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,
431            interfaceTag,
432            CSR_WIFI_SME_LIST_ACTION_ADD,
433            mc_count, multicast_address_list);
434
435    /* The SME will take a copy of the addreses*/
436    kfree(multicast_address_list);
437}
438
439
440int unifi_cfg_power(unifi_priv_t *priv, unsigned char *arg)
441{
442    unifi_cfg_power_t cfg_power;
443    int rc;
444    int wol;
445
446    if (get_user(cfg_power, (unifi_cfg_power_t*)(((unifi_cfg_command_t*)arg) + 1))) {
447        unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n");
448        return -EFAULT;
449    }
450
451    switch (cfg_power) {
452        case UNIFI_CFG_POWER_OFF:
453            priv->wol_suspend = (enable_wol == UNIFI_WOL_OFF) ? FALSE : TRUE;
454            rc = sme_sys_suspend(priv);
455            if (rc) {
456                return rc;
457            }
458            break;
459        case UNIFI_CFG_POWER_ON:
460            wol = priv->wol_suspend;
461            rc = sme_sys_resume(priv);
462            if (rc) {
463                return rc;
464            }
465            if (wol) {
466                /* Kick the BH to ensure pending transfers are handled when
467                 * a suspend happened with card powered.
468                 */
469                unifi_send_signal(priv->card, NULL, 0, NULL);
470            }
471            break;
472        default:
473            unifi_error(priv, "WIFI POWER: Unknown value.\n");
474            return -EINVAL;
475    }
476
477    return 0;
478}
479
480
481int unifi_cfg_power_save(unifi_priv_t *priv, unsigned char *arg)
482{
483    unifi_cfg_powersave_t cfg_power_save;
484    CsrWifiSmePowerConfig powerConfig;
485    int rc;
486
487    if (get_user(cfg_power_save, (unifi_cfg_powersave_t*)(((unifi_cfg_command_t*)arg) + 1))) {
488        unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n");
489        return -EFAULT;
490    }
491
492    /* Get the coex info from the SME */
493    rc = sme_mgt_power_config_get(priv, &powerConfig);
494    if (rc) {
495        unifi_error(priv, "UNIFI_CFG: Get unifi_PowerConfigValue failed.\n");
496        return rc;
497    }
498
499    switch (cfg_power_save) {
500        case UNIFI_CFG_POWERSAVE_NONE:
501            powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW;
502            break;
503        case UNIFI_CFG_POWERSAVE_FAST:
504            powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_MED;
505            break;
506        case UNIFI_CFG_POWERSAVE_FULL:
507            powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH;
508            break;
509        case UNIFI_CFG_POWERSAVE_AUTO:
510            powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_AUTO;
511            break;
512        default:
513            unifi_error(priv, "POWERSAVE: Unknown value.\n");
514            return -EINVAL;
515    }
516
517    rc = sme_mgt_power_config_set(priv, &powerConfig);
518
519    if (rc) {
520        unifi_error(priv, "UNIFI_CFG: Set unifi_PowerConfigValue failed.\n");
521    }
522
523    return rc;
524}
525
526
527int unifi_cfg_power_supply(unifi_priv_t *priv, unsigned char *arg)
528{
529    unifi_cfg_powersupply_t cfg_power_supply;
530    CsrWifiSmeHostConfig hostConfig;
531    int rc;
532
533    if (get_user(cfg_power_supply, (unifi_cfg_powersupply_t*)(((unifi_cfg_command_t*)arg) + 1))) {
534        unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n");
535        return -EFAULT;
536    }
537
538    /* Get the coex info from the SME */
539    rc = sme_mgt_host_config_get(priv, &hostConfig);
540    if (rc) {
541        unifi_error(priv, "UNIFI_CFG: Get unifi_HostConfigValue failed.\n");
542        return rc;
543    }
544
545    switch (cfg_power_supply) {
546        case UNIFI_CFG_POWERSUPPLY_MAINS:
547            hostConfig.powerMode = CSR_WIFI_SME_HOST_POWER_MODE_ACTIVE;
548            break;
549        case UNIFI_CFG_POWERSUPPLY_BATTERIES:
550            hostConfig.powerMode = CSR_WIFI_SME_HOST_POWER_MODE_POWER_SAVE;
551            break;
552        default:
553            unifi_error(priv, "POWERSUPPLY: Unknown value.\n");
554            return -EINVAL;
555    }
556
557    rc = sme_mgt_host_config_set(priv, &hostConfig);
558    if (rc) {
559        unifi_error(priv, "UNIFI_CFG: Set unifi_HostConfigValue failed.\n");
560    }
561
562    return rc;
563}
564
565
566int unifi_cfg_packet_filters(unifi_priv_t *priv, unsigned char *arg)
567{
568    unsigned char *tclas_buffer;
569    unsigned int tclas_buffer_length;
570    tclas_t *dhcp_tclas;
571    int rc;
572
573    /* Free any TCLASs previously allocated */
574    if (priv->packet_filters.tclas_ies_length) {
575        kfree(priv->filter_tclas_ies);
576        priv->filter_tclas_ies = NULL;
577    }
578
579    tclas_buffer = ((unsigned char*)arg) + sizeof(unifi_cfg_command_t) + sizeof(unsigned int);
580    if (copy_from_user(&priv->packet_filters, (void*)tclas_buffer,
581                sizeof(uf_cfg_bcast_packet_filter_t))) {
582        unifi_error(priv, "UNIFI_CFG: Failed to get the filter struct\n");
583        return -EFAULT;
584    }
585
586    tclas_buffer_length = priv->packet_filters.tclas_ies_length;
587
588    /* Allocate TCLASs if necessary */
589    if (priv->packet_filters.dhcp_filter) {
590        priv->packet_filters.tclas_ies_length += sizeof(tclas_t);
591    }
592    if (priv->packet_filters.tclas_ies_length > 0) {
593        priv->filter_tclas_ies = kmalloc(priv->packet_filters.tclas_ies_length, GFP_KERNEL);
594        if (priv->filter_tclas_ies == NULL) {
595            return -ENOMEM;
596        }
597        if (tclas_buffer_length) {
598            tclas_buffer += sizeof(uf_cfg_bcast_packet_filter_t) - sizeof(unsigned char*);
599            if (copy_from_user(priv->filter_tclas_ies,
600                        tclas_buffer,
601                        tclas_buffer_length)) {
602                unifi_error(priv, "UNIFI_CFG: Failed to get the TCLAS buffer\n");
603                return -EFAULT;
604            }
605        }
606    }
607
608    if(priv->packet_filters.dhcp_filter)
609    {
610        /* Append the DHCP tclas IE */
611        dhcp_tclas = (tclas_t*)(priv->filter_tclas_ies + tclas_buffer_length);
612        memset(dhcp_tclas, 0, sizeof(tclas_t));
613        dhcp_tclas->element_id = 14;
614        dhcp_tclas->length = sizeof(tcpip_clsfr_t) + 1;
615        dhcp_tclas->user_priority = 0;
616        dhcp_tclas->tcp_ip_cls_fr.cls_fr_type = 1;
617        dhcp_tclas->tcp_ip_cls_fr.version = 4;
618        ((u8*)(&dhcp_tclas->tcp_ip_cls_fr.source_port))[0] = 0x00;
619        ((u8*)(&dhcp_tclas->tcp_ip_cls_fr.source_port))[1] = 0x44;
620        ((u8*)(&dhcp_tclas->tcp_ip_cls_fr.dest_port))[0] = 0x00;
621        ((u8*)(&dhcp_tclas->tcp_ip_cls_fr.dest_port))[1] = 0x43;
622        dhcp_tclas->tcp_ip_cls_fr.protocol = 0x11;
623        dhcp_tclas->tcp_ip_cls_fr.cls_fr_mask = 0x58; //bits: 3,4,6
624    }
625
626    rc = sme_mgt_packet_filter_set(priv);
627
628    return rc;
629}
630
631
632int unifi_cfg_wmm_qos_info(unifi_priv_t *priv, unsigned char *arg)
633{
634    u8 wmm_qos_info;
635    int rc = 0;
636
637    if (get_user(wmm_qos_info, (u8*)(((unifi_cfg_command_t*)arg) + 1))) {
638        unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n");
639        return -EFAULT;
640    }
641
642    /* Store the value in the connection info */
643    priv->connection_config.wmmQosInfo = wmm_qos_info;
644
645    return rc;
646}
647
648
649int unifi_cfg_wmm_addts(unifi_priv_t *priv, unsigned char *arg)
650{
651    u32 addts_tid;
652    u8 addts_ie_length;
653    u8 *addts_ie;
654    u8 *addts_params;
655    CsrWifiSmeDataBlock tspec;
656    CsrWifiSmeDataBlock tclas;
657    int rc;
658
659    addts_params = (u8*)(((unifi_cfg_command_t*)arg) + 1);
660    if (get_user(addts_tid, (u32*)addts_params)) {
661        unifi_error(priv, "unifi_cfg_wmm_addts: Failed to get the argument\n");
662        return -EFAULT;
663    }
664
665    addts_params += sizeof(u32);
666    if (get_user(addts_ie_length, (u8*)addts_params)) {
667        unifi_error(priv, "unifi_cfg_wmm_addts: Failed to get the argument\n");
668        return -EFAULT;
669    }
670
671    unifi_trace(priv, UDBG4, "addts: tid = 0x%x ie_length = %d\n",
672            addts_tid, addts_ie_length);
673
674    addts_ie = kmalloc(addts_ie_length, GFP_KERNEL);
675    if (addts_ie == NULL) {
676        unifi_error(priv,
677                "unifi_cfg_wmm_addts: Failed to malloc %d bytes for addts_ie buffer\n",
678                addts_ie_length);
679        return -ENOMEM;
680    }
681
682    addts_params += sizeof(u8);
683    rc = copy_from_user(addts_ie, addts_params, addts_ie_length);
684    if (rc) {
685        unifi_error(priv, "unifi_cfg_wmm_addts: Failed to get the addts buffer\n");
686        kfree(addts_ie);
687        return -EFAULT;
688    }
689
690    tspec.data = addts_ie;
691    tspec.length = addts_ie_length;
692    tclas.data = NULL;
693    tclas.length = 0;
694
695    rc = sme_mgt_tspec(priv, CSR_WIFI_SME_LIST_ACTION_ADD, addts_tid,
696            &tspec, &tclas);
697
698    kfree(addts_ie);
699    return rc;
700}
701
702
703int unifi_cfg_wmm_delts(unifi_priv_t *priv, unsigned char *arg)
704{
705    u32 delts_tid;
706    u8 *delts_params;
707    CsrWifiSmeDataBlock tspec;
708    CsrWifiSmeDataBlock tclas;
709    int rc;
710
711    delts_params = (u8*)(((unifi_cfg_command_t*)arg) + 1);
712    if (get_user(delts_tid, (u32*)delts_params)) {
713        unifi_error(priv, "unifi_cfg_wmm_delts: Failed to get the argument\n");
714        return -EFAULT;
715    }
716
717    unifi_trace(priv, UDBG4, "delts: tid = 0x%x\n", delts_tid);
718
719    tspec.data = tclas.data = NULL;
720    tspec.length = tclas.length = 0;
721
722    rc = sme_mgt_tspec(priv, CSR_WIFI_SME_LIST_ACTION_REMOVE, delts_tid,
723            &tspec, &tclas);
724
725    return rc;
726}
727
728int unifi_cfg_strict_draft_n(unifi_priv_t *priv, unsigned char *arg)
729{
730    u8 strict_draft_n;
731    u8 *strict_draft_n_params;
732    int rc;
733
734    CsrWifiSmeStaConfig staConfig;
735    CsrWifiSmeDeviceConfig deviceConfig;
736
737    strict_draft_n_params = (u8*)(((unifi_cfg_command_t*)arg) + 1);
738    if (get_user(strict_draft_n, (u8*)strict_draft_n_params)) {
739        unifi_error(priv, "unifi_cfg_strict_draft_n: Failed to get the argument\n");
740        return -EFAULT;
741    }
742
743    unifi_trace(priv, UDBG4, "strict_draft_n: = %s\n", ((strict_draft_n) ? "yes":"no"));
744
745    rc = sme_mgt_sme_config_get(priv, &staConfig, &deviceConfig);
746
747    if (rc) {
748        unifi_warning(priv, "unifi_cfg_strict_draft_n: Get unifi_SMEConfigValue failed.\n");
749        return -EFAULT;
750    }
751
752    deviceConfig.enableStrictDraftN = strict_draft_n;
753
754    rc = sme_mgt_sme_config_set(priv, &staConfig, &deviceConfig);
755    if (rc) {
756        unifi_warning(priv, "unifi_cfg_strict_draft_n: Set unifi_SMEConfigValue failed.\n");
757        rc = -EFAULT;
758    }
759
760    return rc;
761}
762
763
764int unifi_cfg_enable_okc(unifi_priv_t *priv, unsigned char *arg)
765{
766    u8 enable_okc;
767    u8 *enable_okc_params;
768    int rc;
769
770    CsrWifiSmeStaConfig staConfig;
771    CsrWifiSmeDeviceConfig deviceConfig;
772
773    enable_okc_params = (u8*)(((unifi_cfg_command_t*)arg) + 1);
774    if (get_user(enable_okc, (u8*)enable_okc_params)) {
775        unifi_error(priv, "unifi_cfg_enable_okc: Failed to get the argument\n");
776        return -EFAULT;
777    }
778
779    unifi_trace(priv, UDBG4, "enable_okc: = %s\n", ((enable_okc) ? "yes":"no"));
780
781    rc = sme_mgt_sme_config_get(priv, &staConfig, &deviceConfig);
782    if (rc) {
783        unifi_warning(priv, "unifi_cfg_enable_okc: Get unifi_SMEConfigValue failed.\n");
784        return -EFAULT;
785    }
786
787    staConfig.enableOpportunisticKeyCaching = enable_okc;
788
789    rc = sme_mgt_sme_config_set(priv, &staConfig, &deviceConfig);
790    if (rc) {
791        unifi_warning(priv, "unifi_cfg_enable_okc: Set unifi_SMEConfigValue failed.\n");
792        rc = -EFAULT;
793    }
794
795    return rc;
796}
797
798
799int unifi_cfg_get_info(unifi_priv_t *priv, unsigned char *arg)
800{
801    unifi_cfg_get_t get_cmd;
802    char inst_name[IFNAMSIZ];
803    int rc;
804
805    if (get_user(get_cmd, (unifi_cfg_get_t*)(((unifi_cfg_command_t*)arg) + 1))) {
806        unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n");
807        return -EFAULT;
808    }
809
810    switch (get_cmd) {
811        case UNIFI_CFG_GET_COEX:
812            {
813                CsrWifiSmeCoexInfo coexInfo;
814                /* Get the coex info from the SME */
815                rc = sme_mgt_coex_info_get(priv, &coexInfo);
816                if (rc) {
817                    unifi_error(priv, "UNIFI_CFG: Get unifi_CoexInfoValue failed.\n");
818                    return rc;
819                }
820
821                /* Copy the info to the out buffer */
822                if (copy_to_user((void*)arg,
823                            &coexInfo,
824                            sizeof(CsrWifiSmeCoexInfo))) {
825                    unifi_error(priv, "UNIFI_CFG: Failed to copy the coex info\n");
826                    return -EFAULT;
827                }
828                break;
829            }
830        case UNIFI_CFG_GET_POWER_MODE:
831            {
832                CsrWifiSmePowerConfig powerConfig;
833                rc = sme_mgt_power_config_get(priv, &powerConfig);
834                if (rc) {
835                    unifi_error(priv, "UNIFI_CFG: Get unifi_PowerConfigValue failed.\n");
836                    return rc;
837                }
838
839                /* Copy the info to the out buffer */
840                if (copy_to_user((void*)arg,
841                            &powerConfig.powerSaveLevel,
842                            sizeof(CsrWifiSmePowerSaveLevel))) {
843                    unifi_error(priv, "UNIFI_CFG: Failed to copy the power save info\n");
844                    return -EFAULT;
845                }
846                break;
847            }
848        case UNIFI_CFG_GET_POWER_SUPPLY:
849            {
850                CsrWifiSmeHostConfig hostConfig;
851                rc = sme_mgt_host_config_get(priv, &hostConfig);
852                if (rc) {
853                    unifi_error(priv, "UNIFI_CFG: Get unifi_HostConfigValue failed.\n");
854                    return rc;
855                }
856
857                /* Copy the info to the out buffer */
858                if (copy_to_user((void*)arg,
859                            &hostConfig.powerMode,
860                            sizeof(CsrWifiSmeHostPowerMode))) {
861                    unifi_error(priv, "UNIFI_CFG: Failed to copy the host power mode\n");
862                    return -EFAULT;
863                }
864                break;
865            }
866        case UNIFI_CFG_GET_VERSIONS:
867            break;
868        case UNIFI_CFG_GET_INSTANCE:
869            {
870                u16 InterfaceId=0;
871                uf_net_get_name(priv->netdev[InterfaceId], &inst_name[0], sizeof(inst_name));
872
873                /* Copy the info to the out buffer */
874                if (copy_to_user((void*)arg,
875                            &inst_name[0],
876                            sizeof(inst_name))) {
877                    unifi_error(priv, "UNIFI_CFG: Failed to copy the instance name\n");
878                    return -EFAULT;
879                }
880            }
881            break;
882
883        case UNIFI_CFG_GET_AP_CONFIG:
884            {
885#ifdef CSR_SUPPORT_WEXT_AP
886                uf_cfg_ap_config_t cfg_ap_config;
887                cfg_ap_config.channel = priv->ap_config.channel;
888                cfg_ap_config.beaconInterval = priv->ap_mac_config.beaconInterval;
889                cfg_ap_config.wmmEnabled = priv->ap_mac_config.wmmEnabled;
890                cfg_ap_config.dtimPeriod = priv->ap_mac_config.dtimPeriod;
891                cfg_ap_config.phySupportedBitmap = priv->ap_mac_config.phySupportedBitmap;
892                if (copy_to_user((void*)arg,
893                            &cfg_ap_config,
894                            sizeof(uf_cfg_ap_config_t))) {
895                    unifi_error(priv, "UNIFI_CFG: Failed to copy the AP configuration\n");
896                    return -EFAULT;
897                }
898#else
899                   return -EPERM;
900#endif
901            }
902            break;
903
904
905        default:
906            unifi_error(priv, "unifi_cfg_get_info: Unknown value.\n");
907            return -EINVAL;
908    }
909
910    return 0;
911}
912#ifdef CSR_SUPPORT_WEXT_AP
913int
914 uf_configure_supported_rates(u8 * supportedRates, u8 phySupportedBitmap)
915{
916    int i=0;
917    u8 b=FALSE, g = FALSE, n = FALSE;
918    b = phySupportedBitmap & CSR_WIFI_SME_AP_PHY_SUPPORT_B;
919    n = phySupportedBitmap & CSR_WIFI_SME_AP_PHY_SUPPORT_N;
920    g = phySupportedBitmap & CSR_WIFI_SME_AP_PHY_SUPPORT_G;
921    if(b || g) {
922        supportedRates[i++]=0x82;
923        supportedRates[i++]=0x84;
924        supportedRates[i++]=0x8b;
925        supportedRates[i++]=0x96;
926    } else if(n) {
927        /* For some strange reasons WiFi stack needs both b and g rates*/
928        supportedRates[i++]=0x02;
929        supportedRates[i++]=0x04;
930        supportedRates[i++]=0x0b;
931        supportedRates[i++]=0x16;
932        supportedRates[i++]=0x0c;
933        supportedRates[i++]=0x12;
934        supportedRates[i++]=0x18;
935    supportedRates[i++]=0x24;
936        supportedRates[i++]=0x30;
937        supportedRates[i++]=0x48;
938        supportedRates[i++]=0x60;
939        supportedRates[i++]=0x6c;
940    }
941    if(g) {
942        if(!b) {
943            supportedRates[i++]=0x8c;
944            supportedRates[i++]=0x98;
945            supportedRates[i++]=0xb0;
946        } else {
947            supportedRates[i++]=0x0c;
948            supportedRates[i++]=0x18;
949            supportedRates[i++]=0x30;
950        }
951        supportedRates[i++]=0x48;
952        supportedRates[i++]=0x12;
953        supportedRates[i++]=0x24;
954        supportedRates[i++]=0x60;
955        supportedRates[i++]=0x6c;
956    }
957    return i;
958}
959int unifi_cfg_set_ap_config(unifi_priv_t * priv,unsigned char* arg)
960{
961    uf_cfg_ap_config_t cfg_ap_config;
962    char *buffer;
963
964    buffer = ((unsigned char*)arg) + sizeof(unifi_cfg_command_t) + sizeof(unsigned int);
965    if (copy_from_user(&cfg_ap_config, (void*)buffer,
966                sizeof(uf_cfg_ap_config_t))) {
967        unifi_error(priv, "UNIFI_CFG: Failed to get the ap config struct\n");
968        return -EFAULT;
969    }
970    priv->ap_config.channel = cfg_ap_config.channel;
971    priv->ap_mac_config.dtimPeriod = cfg_ap_config.dtimPeriod;
972    priv->ap_mac_config.beaconInterval = cfg_ap_config.beaconInterval;
973    priv->group_sec_config.apGroupkeyTimeout = cfg_ap_config.groupkeyTimeout;
974    priv->group_sec_config.apStrictGtkRekey = cfg_ap_config.strictGtkRekeyEnabled;
975    priv->group_sec_config.apGmkTimeout = cfg_ap_config.gmkTimeout;
976    priv->group_sec_config.apResponseTimeout = cfg_ap_config.responseTimeout;
977    priv->group_sec_config.apRetransLimit = cfg_ap_config.retransLimit;
978
979    priv->ap_mac_config.shortSlotTimeEnabled = cfg_ap_config.shortSlotTimeEnabled;
980    priv->ap_mac_config.ctsProtectionType=cfg_ap_config.ctsProtectionType;
981
982    priv->ap_mac_config.wmmEnabled = cfg_ap_config.wmmEnabled;
983
984    priv->ap_mac_config.apHtParams.rxStbc=cfg_ap_config.rxStbc;
985    priv->ap_mac_config.apHtParams.rifsModeAllowed=cfg_ap_config.rifsModeAllowed;
986
987    priv->ap_mac_config.phySupportedBitmap = cfg_ap_config.phySupportedBitmap;
988    priv->ap_mac_config.maxListenInterval=cfg_ap_config.maxListenInterval;
989
990    priv->ap_mac_config.supportedRatesCount= uf_configure_supported_rates(priv->ap_mac_config.supportedRates,priv->ap_mac_config.phySupportedBitmap);
991
992    return 0;
993}
994
995#endif
996#ifdef CSR_SUPPORT_WEXT
997
998    void
999uf_sme_config_wq(struct work_struct *work)
1000{
1001    CsrWifiSmeStaConfig staConfig;
1002    CsrWifiSmeDeviceConfig deviceConfig;
1003    unifi_priv_t *priv = container_of(work, unifi_priv_t, sme_config_task);
1004
1005    /* Register to receive indications from the SME */
1006    CsrWifiSmeEventMaskSetReqSend(0,
1007            CSR_WIFI_SME_INDICATIONS_WIFIOFF | CSR_WIFI_SME_INDICATIONS_CONNECTIONQUALITY |
1008            CSR_WIFI_SME_INDICATIONS_MEDIASTATUS | CSR_WIFI_SME_INDICATIONS_MICFAILURE);
1009
1010    if (sme_mgt_sme_config_get(priv, &staConfig, &deviceConfig)) {
1011        unifi_warning(priv, "uf_sme_config_wq: Get unifi_SMEConfigValue failed.\n");
1012        return;
1013    }
1014
1015    if (priv->if_index == CSR_INDEX_5G) {
1016        staConfig.ifIndex = CSR_WIFI_SME_RADIO_IF_GHZ_5_0;
1017    } else {
1018        staConfig.ifIndex = CSR_WIFI_SME_RADIO_IF_GHZ_2_4;
1019    }
1020
1021    deviceConfig.trustLevel = (CsrWifiSme80211dTrustLevel)tl_80211d;
1022    if (sme_mgt_sme_config_set(priv, &staConfig, &deviceConfig)) {
1023        unifi_warning(priv,
1024                "SME config for 802.11d Trust Level and Radio Band failed.\n");
1025        return;
1026    }
1027
1028} /* uf_sme_config_wq() */
1029
1030#endif /* CSR_SUPPORT_WEXT */
1031
1032
1033/*
1034 * ---------------------------------------------------------------------------
1035 * uf_ta_ind_wq
1036 *
1037 * Deferred work queue function to send Traffic Analysis protocols
1038 * indications to the SME.
1039 * These are done in a deferred work queue for two reasons:
1040 * - the CsrWifiRouterCtrl...Send() functions are not safe for atomic context
1041 * - we want to load the main driver data path as lightly as possible
1042 *
1043 * The TA classifications already come from a workqueue.
1044 *
1045 * Arguments:
1046 * work Pointer to work queue item.
1047 *
1048 * Returns:
1049 * None.
1050 * ---------------------------------------------------------------------------
1051 */
1052    void
1053uf_ta_ind_wq(struct work_struct *work)
1054{
1055    struct ta_ind *ind = container_of(work, struct ta_ind, task);
1056    unifi_priv_t *priv = container_of(ind, unifi_priv_t, ta_ind_work);
1057    u16 interfaceTag = 0;
1058
1059
1060    CsrWifiRouterCtrlTrafficProtocolIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,
1061            interfaceTag,
1062            ind->packet_type,
1063            ind->direction,
1064            ind->src_addr);
1065    ind->in_use = 0;
1066
1067} /* uf_ta_ind_wq() */
1068
1069
1070/*
1071 * ---------------------------------------------------------------------------
1072 * uf_ta_sample_ind_wq
1073 *
1074 * Deferred work queue function to send Traffic Analysis sample
1075 * indications to the SME.
1076 * These are done in a deferred work queue for two reasons:
1077 * - the CsrWifiRouterCtrl...Send() functions are not safe for atomic context
1078 * - we want to load the main driver data path as lightly as possible
1079 *
1080 * The TA classifications already come from a workqueue.
1081 *
1082 * Arguments:
1083 * work Pointer to work queue item.
1084 *
1085 * Returns:
1086 * None.
1087 * ---------------------------------------------------------------------------
1088 */
1089    void
1090uf_ta_sample_ind_wq(struct work_struct *work)
1091{
1092    struct ta_sample_ind *ind = container_of(work, struct ta_sample_ind, task);
1093    unifi_priv_t *priv = container_of(ind, unifi_priv_t, ta_sample_ind_work);
1094    u16 interfaceTag = 0;
1095
1096     unifi_trace(priv, UDBG5, "rxtcp %d txtcp %d rxudp %d txudp %d prio %d\n",
1097        priv->rxTcpThroughput,
1098        priv->txTcpThroughput,
1099        priv->rxUdpThroughput,
1100        priv->txUdpThroughput,
1101        priv->bh_thread.prio);
1102
1103    if(priv->rxTcpThroughput > 1000)
1104    {
1105        if (bh_priority == -1 && priv->bh_thread.prio != 1)
1106        {
1107            struct sched_param param;
1108            priv->bh_thread.prio = 1;
1109            unifi_trace(priv, UDBG1, "%s new thread (RT) priority = %d\n",
1110                        priv->bh_thread.name, priv->bh_thread.prio);
1111            param.sched_priority = priv->bh_thread.prio;
1112            sched_setscheduler(priv->bh_thread.thread_task, SCHED_FIFO, &param);
1113        }
1114    } else
1115    {
1116        if (bh_priority == -1 && priv->bh_thread.prio != DEFAULT_PRIO)
1117        {
1118            struct sched_param param;
1119            param.sched_priority = 0;
1120            sched_setscheduler(priv->bh_thread.thread_task, SCHED_NORMAL, &param);
1121            priv->bh_thread.prio = DEFAULT_PRIO;
1122            unifi_trace(priv, UDBG1, "%s new thread priority = %d\n",
1123                        priv->bh_thread.name, priv->bh_thread.prio);
1124            set_user_nice(priv->bh_thread.thread_task, PRIO_TO_NICE(priv->bh_thread.prio));
1125        }
1126    }
1127
1128    CsrWifiRouterCtrlTrafficSampleIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, interfaceTag, ind->stats);
1129
1130    ind->in_use = 0;
1131
1132} /* uf_ta_sample_ind_wq() */
1133
1134
1135/*
1136 * ---------------------------------------------------------------------------
1137 * uf_send_m4_ready_wq
1138 *
1139 * Deferred work queue function to send M4 ReadyToSend inds to the SME.
1140 * These are done in a deferred work queue for two reasons:
1141 * - the CsrWifiRouterCtrl...Send() functions are not safe for atomic context
1142 * - we want to load the main driver data path as lightly as possible
1143 *
1144 * Arguments:
1145 * work Pointer to work queue item.
1146 *
1147 * Returns:
1148 * None.
1149 * ---------------------------------------------------------------------------
1150 */
1151void
1152uf_send_m4_ready_wq(struct work_struct *work)
1153{
1154    netInterface_priv_t *InterfacePriv = container_of(work, netInterface_priv_t, send_m4_ready_task);
1155    u16 iface = InterfacePriv->InterfaceTag;
1156    unifi_priv_t *priv = InterfacePriv->privPtr;
1157    CSR_MA_PACKET_REQUEST *req = &InterfacePriv->m4_signal.u.MaPacketRequest;
1158    CsrWifiMacAddress peer;
1159    unsigned long flags;
1160
1161    func_enter();
1162
1163    /* The peer address was stored in the signal */
1164    spin_lock_irqsave(&priv->m4_lock, flags);
1165    memcpy(peer.a, req->Ra.x, sizeof(peer.a));
1166    spin_unlock_irqrestore(&priv->m4_lock, flags);
1167
1168    /* Send a signal to SME */
1169    CsrWifiRouterCtrlM4ReadyToSendIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, iface, peer);
1170
1171    unifi_trace(priv, UDBG1, "M4ReadyToSendInd sent for peer %pMF\n",
1172        peer.a);
1173
1174    func_exit();
1175
1176} /* uf_send_m4_ready_wq() */
1177
1178#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
1179/*
1180 * ---------------------------------------------------------------------------
1181 * uf_send_pkt_to_encrypt
1182 *
1183 * Deferred work queue function to send the WAPI data pkts to SME when unicast KeyId = 1
1184 * These are done in a deferred work queue for two reasons:
1185 * - the CsrWifiRouterCtrl...Send() functions are not safe for atomic context
1186 * - we want to load the main driver data path as lightly as possible
1187 *
1188 * Arguments:
1189 * work Pointer to work queue item.
1190 *
1191 * Returns:
1192 * None.
1193 * ---------------------------------------------------------------------------
1194 */
1195void uf_send_pkt_to_encrypt(struct work_struct *work)
1196{
1197    netInterface_priv_t *interfacePriv = container_of(work, netInterface_priv_t, send_pkt_to_encrypt);
1198    u16 interfaceTag = interfacePriv->InterfaceTag;
1199    unifi_priv_t *priv = interfacePriv->privPtr;
1200
1201    u32 pktBulkDataLength;
1202    u8 *pktBulkData;
1203    unsigned long flags;
1204
1205    if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) {
1206
1207        func_enter();
1208
1209        pktBulkDataLength = interfacePriv->wapi_unicast_bulk_data.data_length;
1210
1211        if (pktBulkDataLength > 0) {
1212            pktBulkData = kmalloc(pktBulkDataLength, GFP_KERNEL);
1213            memset(pktBulkData, 0, pktBulkDataLength);
1214        } else {
1215            unifi_error(priv, "uf_send_pkt_to_encrypt() : invalid buffer\n");
1216            return;
1217        }
1218
1219        spin_lock_irqsave(&priv->wapi_lock, flags);
1220        /* Copy over the MA PKT REQ bulk data */
1221        memcpy(pktBulkData, (u8*)interfacePriv->wapi_unicast_bulk_data.os_data_ptr, pktBulkDataLength);
1222        /* Free any bulk data buffers allocated for the WAPI Data pkt */
1223        unifi_net_data_free(priv, &interfacePriv->wapi_unicast_bulk_data);
1224        interfacePriv->wapi_unicast_bulk_data.net_buf_length = 0;
1225        interfacePriv->wapi_unicast_bulk_data.data_length = 0;
1226        interfacePriv->wapi_unicast_bulk_data.os_data_ptr = interfacePriv->wapi_unicast_bulk_data.os_net_buf_ptr = NULL;
1227        spin_unlock_irqrestore(&priv->wapi_lock, flags);
1228
1229        CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, pktBulkDataLength, pktBulkData);
1230        unifi_trace(priv, UDBG1, "WapiUnicastTxEncryptInd sent to SME\n");
1231
1232        kfree(pktBulkData); /* Would have been copied over by the SME Handler */
1233
1234        func_exit();
1235    } else {
1236        unifi_warning(priv, "uf_send_pkt_to_encrypt() is NOT applicable for interface mode - %d\n",interfacePriv->interfaceMode);
1237    }
1238}/* uf_send_pkt_to_encrypt() */
1239#endif
1240

Archive Download this file



interactive