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