1 /**
2 * @file mlan_misc.c
3 *
4 * @brief This file include miscellaneous functions for MLAN module
5 *
6 *
7 * Copyright 2009-2022 NXP
8 *
9 * This software file (the File) is distributed by NXP
10 * under the terms of the GNU General Public License Version 2, June 1991
11 * (the License). You may use, redistribute and/or modify the File in
12 * accordance with the terms and conditions of the License, a copy of which
13 * is available by writing to the Free Software Foundation, Inc.,
14 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
15 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
16 *
17 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
19 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
20 * this warranty disclaimer.
21 *
22 */
23
24 /*************************************************************
25 Change Log:
26 05/11/2009: initial version
27 ************************************************************/
28 #include "mlan.h"
29 #ifdef STA_SUPPORT
30 #include "mlan_join.h"
31 #endif /* STA_SUPPORT */
32 #include "mlan_util.h"
33 #include "mlan_fw.h"
34 #include "mlan_main.h"
35 #include "mlan_wmm.h"
36 #include "mlan_11n.h"
37 #include "mlan_11ac.h"
38 #include "mlan_11ax.h"
39 #ifdef UAP_SUPPORT
40 #include "mlan_uap.h"
41 #endif
42 #ifdef DRV_EMBEDDED_AUTHENTICATOR
43 #include "authenticator_api.h"
44 #endif
45 /********************************************************
46 Local Variables
47 ********************************************************/
48
49 /********************************************************
50 Global Variables
51 ********************************************************/
52
53 /********************************************************
54 Local Functions
55 ********************************************************/
56 #if defined(PCIE) || defined(SDIO)
57 /**
58 * @brief Check pending irq
59 *
60 * @param pmadapter A pointer to mlan_adapter structure
61 *
62 * @return MTRUE/MFALSE;
63 */
wlan_pending_interrupt(pmlan_adapter pmadapter)64 static t_u8 wlan_pending_interrupt(pmlan_adapter pmadapter)
65 {
66 if (!IS_USB(pmadapter->card_type) && pmadapter->ireg)
67 return MTRUE;
68 return MFALSE;
69 }
70 #endif
71
72 /** Custom IE auto index and mask */
73 #define MLAN_CUSTOM_IE_AUTO_IDX_MASK 0xffff
74 /** Custom IE mask for delete operation */
75 #define MLAN_CUSTOM_IE_DELETE_MASK 0
76 /** Custom IE mask for create new index */
77 #define MLAN_CUSTOM_IE_NEW_MASK 0x8000
78 /** Custom IE header size */
79 #define MLAN_CUSTOM_IE_HDR_SIZE (sizeof(custom_ie) - MAX_IE_SIZE)
80
81 /**
82 * @brief Check if current custom IE index is used on other interfaces.
83 *
84 * @param pmpriv A pointer to mlan_private structure
85 * @param idx index to check for in use
86 *
87 * @return MLAN_STATUS_SUCCESS --unused, otherwise used.
88 */
wlan_is_custom_ie_index_unused(pmlan_private pmpriv,t_u16 idx)89 static mlan_status wlan_is_custom_ie_index_unused(pmlan_private pmpriv,
90 t_u16 idx)
91 {
92 t_u8 i = 0;
93 pmlan_adapter pmadapter = pmpriv->adapter;
94 pmlan_private priv;
95 ENTER();
96
97 for (i = 0; i < pmadapter->priv_num; i++) {
98 priv = pmadapter->priv[i];
99 /* Check for other interfaces only */
100 if (priv && priv->bss_index != pmpriv->bss_index) {
101 if (priv->mgmt_ie[idx].mgmt_subtype_mask &&
102 priv->mgmt_ie[idx].ie_length) {
103 /* used entry found */
104 LEAVE();
105 return MLAN_STATUS_FAILURE;
106 }
107 }
108 }
109 LEAVE();
110 return MLAN_STATUS_SUCCESS;
111 }
112
113 /**
114 * @brief Get the custom IE index
115 *
116 * @param pmpriv A pointer to mlan_private structure
117 * @param pioctl_req A pointer to ioctl request buffer
118 * @param mask mask value for which the index to be returned
119 * @param ie_data a pointer to custom_ie structure
120 * @param idx will hold the computed index
121 *
122 * @return MLAN_STATUS_SUCCESS --success, otherwise fail
123 */
wlan_custom_ioctl_get_autoidx(pmlan_private pmpriv,pmlan_ioctl_req pioctl_req,t_u16 mask,custom_ie * ie_data,t_u16 * idx)124 static mlan_status wlan_custom_ioctl_get_autoidx(pmlan_private pmpriv,
125 pmlan_ioctl_req pioctl_req,
126 t_u16 mask, custom_ie *ie_data,
127 t_u16 *idx)
128 {
129 t_u16 index = 0, insert = MFALSE;
130 mlan_status ret = MLAN_STATUS_SUCCESS;
131
132 ENTER();
133 /* Determine the index where the IE needs to be inserted */
134 while (!insert) {
135 while (index < MIN(pmpriv->adapter->max_mgmt_ie_index,
136 MAX_MGMT_IE_INDEX)) {
137 if (pmpriv->mgmt_ie[index].mgmt_subtype_mask ==
138 MLAN_CUSTOM_IE_AUTO_IDX_MASK) {
139 index++;
140 continue;
141 }
142 if (pmpriv->mgmt_ie[index].mgmt_subtype_mask == mask) {
143 /* Duplicate IE should be avoided */
144 if (pmpriv->mgmt_ie[index].ie_length) {
145 if (!memcmp(pmpriv->adapter,
146 pmpriv->mgmt_ie[index]
147 .ie_buffer,
148 ie_data->ie_buffer,
149 pmpriv->mgmt_ie[index]
150 .ie_length)) {
151 PRINTM(MINFO,
152 "IE with the same mask exists at index %d mask=0x%x\n",
153 index, mask);
154 *idx = MLAN_CUSTOM_IE_AUTO_IDX_MASK;
155 goto done;
156 }
157 }
158 /* Check if enough space is available */
159 if (pmpriv->mgmt_ie[index].ie_length +
160 ie_data->ie_length >
161 MAX_IE_SIZE) {
162 index++;
163 continue;
164 }
165 insert = MTRUE;
166 break;
167 }
168 index++;
169 }
170 if (!insert) {
171 for (index = 0;
172 index < MIN(pmpriv->adapter->max_mgmt_ie_index,
173 MAX_MGMT_IE_INDEX);
174 index++) {
175 if (pmpriv->mgmt_ie[index].ie_length == 0) {
176 /*
177 * Check if this index is in use
178 * by other interface If yes,
179 * move ahead to next index
180 */
181 if (MLAN_STATUS_SUCCESS ==
182 wlan_is_custom_ie_index_unused(
183 pmpriv, index)) {
184 insert = MTRUE;
185 break;
186 } else {
187 PRINTM(MINFO,
188 "Skipping IE index %d in use.\n",
189 index);
190 }
191 }
192 }
193 }
194 if (index == pmpriv->adapter->max_mgmt_ie_index && !insert) {
195 PRINTM(MERROR, "Failed to Set the IE buffer\n");
196 if (pioctl_req)
197 pioctl_req->status_code = MLAN_ERROR_IOCTL_FAIL;
198 ret = MLAN_STATUS_FAILURE;
199 goto done;
200 }
201 }
202
203 *idx = index;
204 done:
205 LEAVE();
206 return ret;
207 }
208
209 /**
210 * @brief Delete custom IE
211 *
212 * @param pmpriv A pointer to mlan_private structure
213 * @param pioctl_req A pointer to ioctl request buffer
214 * @param ie_data a pointer to custom_ie structure
215 * @param idx index supplied
216 *
217 * @return MLAN_STATUS_SUCCESS --success, otherwise fail
218 */
219
wlan_custom_ioctl_auto_delete(pmlan_private pmpriv,pmlan_ioctl_req pioctl_req,custom_ie * ie_data,t_u16 idx)220 static mlan_status wlan_custom_ioctl_auto_delete(pmlan_private pmpriv,
221 pmlan_ioctl_req pioctl_req,
222 custom_ie *ie_data, t_u16 idx)
223 {
224 mlan_status ret = MLAN_STATUS_SUCCESS;
225 pmlan_adapter pmadapter = pmpriv->adapter;
226 t_u16 index = 0, insert = MFALSE, del_len;
227 t_u8 del_ie[MAX_IE_SIZE], ie[MAX_IE_SIZE];
228 t_s32 cnt, tmp_len = 0;
229 t_u8 *tmp_ie;
230
231 ENTER();
232 memset(pmpriv->adapter, del_ie, 0, MAX_IE_SIZE);
233 memcpy_ext(pmpriv->adapter, del_ie, ie_data->ie_buffer,
234 ie_data->ie_length, MAX_IE_SIZE);
235 del_len = MIN(MAX_IE_SIZE - 1, ie_data->ie_length);
236
237 if (MLAN_CUSTOM_IE_AUTO_IDX_MASK == idx)
238 ie_data->ie_index = 0;
239
240 for (index = 0;
241 index < MIN(pmadapter->max_mgmt_ie_index, MAX_MGMT_IE_INDEX);
242 index++) {
243 if (MLAN_CUSTOM_IE_AUTO_IDX_MASK != idx &&
244 idx < MAX_MGMT_IE_INDEX)
245 index = idx;
246 tmp_ie = pmpriv->mgmt_ie[index].ie_buffer;
247 tmp_len = pmpriv->mgmt_ie[index].ie_length;
248 cnt = 0;
249 while (tmp_len) {
250 if (!memcmp(pmpriv->adapter, tmp_ie, del_ie, del_len)) {
251 memcpy_ext(pmpriv->adapter, ie,
252 pmpriv->mgmt_ie[index].ie_buffer,
253 cnt, MAX_IE_SIZE);
254 if (pmpriv->mgmt_ie[index].ie_length >
255 (cnt + del_len))
256 memcpy_ext(
257 pmpriv->adapter, &ie[cnt],
258 &pmpriv->mgmt_ie[index].ie_buffer
259 [MIN((MAX_IE_SIZE - 1),
260 (cnt + del_len))],
261 (pmpriv->mgmt_ie[index]
262 .ie_length -
263 (cnt + del_len)),
264 MAX_IE_SIZE - cnt);
265 memset(pmpriv->adapter,
266 &pmpriv->mgmt_ie[index].ie_buffer, 0,
267 sizeof(pmpriv->mgmt_ie[index].ie_buffer));
268 memcpy_ext(pmpriv->adapter,
269 &pmpriv->mgmt_ie[index].ie_buffer,
270 ie,
271 pmpriv->mgmt_ie[index].ie_length -
272 del_len,
273 MAX_IE_SIZE);
274 pmpriv->mgmt_ie[index].ie_length -= del_len;
275 if (MLAN_CUSTOM_IE_AUTO_IDX_MASK == idx)
276 /* set a bit to indicate caller about
277 * update */
278 ie_data->ie_index |=
279 (((t_u16)1) << index);
280 insert = MTRUE;
281 tmp_ie = pmpriv->mgmt_ie[index].ie_buffer;
282 tmp_len = pmpriv->mgmt_ie[index].ie_length;
283 cnt = 0;
284 continue;
285 }
286 tmp_ie++;
287 tmp_len--;
288 cnt++;
289 }
290 if (MLAN_CUSTOM_IE_AUTO_IDX_MASK != idx)
291 break;
292 }
293 if (index == pmadapter->max_mgmt_ie_index && !insert) {
294 PRINTM(MERROR, "Failed to Clear IE buffer\n");
295 if (pioctl_req)
296 pioctl_req->status_code = MLAN_ERROR_IOCTL_FAIL;
297 ret = MLAN_STATUS_FAILURE;
298 }
299 LEAVE();
300 return ret;
301 }
302
303 /********************************************************
304 Global Functions
305 ********************************************************/
306
307 /**
308 * @brief send host cmd
309 *
310 * @param pmadapter A pointer to mlan_adapter structure
311 * @param pioctl_req A pointer to ioctl request buffer
312 *
313 * @return MLAN_STATUS_PENDING --success, otherwise fail
314 */
wlan_misc_ioctl_host_cmd(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)315 mlan_status wlan_misc_ioctl_host_cmd(pmlan_adapter pmadapter,
316 pmlan_ioctl_req pioctl_req)
317 {
318 mlan_status ret = MLAN_STATUS_SUCCESS;
319 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
320 mlan_ds_misc_cfg *misc = MNULL;
321
322 ENTER();
323
324 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
325
326 /* Send request to firmware */
327 ret = wlan_prepare_cmd(pmpriv, 0, 0, 0, (t_void *)pioctl_req,
328 (t_void *)&misc->param.hostcmd);
329 if (ret == MLAN_STATUS_SUCCESS)
330 ret = MLAN_STATUS_PENDING;
331
332 LEAVE();
333 return ret;
334 }
335
336 /**
337 * @brief Send function init/shutdown command to firmware
338 *
339 * @param pmadapter A pointer to mlan_adapter structure
340 * @param pioctl_req A pointer to ioctl request buffer
341 *
342 * @return MLAN_STATUS_PENDING --success, otherwise fail
343 */
wlan_misc_ioctl_init_shutdown(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)344 mlan_status wlan_misc_ioctl_init_shutdown(pmlan_adapter pmadapter,
345 pmlan_ioctl_req pioctl_req)
346 {
347 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
348 mlan_status ret = MLAN_STATUS_SUCCESS;
349 mlan_ds_misc_cfg *misc_cfg = MNULL;
350 t_u16 cmd;
351
352 ENTER();
353
354 misc_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
355 if (misc_cfg->param.func_init_shutdown == MLAN_FUNC_INIT)
356 cmd = HostCmd_CMD_FUNC_INIT;
357 else if (misc_cfg->param.func_init_shutdown == MLAN_FUNC_SHUTDOWN)
358 cmd = HostCmd_CMD_FUNC_SHUTDOWN;
359 else {
360 PRINTM(MERROR, "Unsupported parameter\n");
361 pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
362 ret = MLAN_STATUS_FAILURE;
363 goto exit;
364 }
365
366 /* Send command to firmware */
367 ret = wlan_prepare_cmd(pmpriv, cmd, HostCmd_ACT_GEN_SET, 0,
368 (t_void *)pioctl_req, MNULL);
369
370 if (ret == MLAN_STATUS_SUCCESS)
371 ret = MLAN_STATUS_PENDING;
372
373 exit:
374 LEAVE();
375 return ret;
376 }
377
378 /**
379 * @brief Get debug information
380 *
381 * @param pmadapter A pointer to mlan_adapter structure
382 * @param pioctl_req A pointer to ioctl request buffer
383 *
384 * @return MLAN_STATUS_SUCCESS --success
385 */
wlan_get_info_debug_info(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)386 mlan_status wlan_get_info_debug_info(pmlan_adapter pmadapter,
387 pmlan_ioctl_req pioctl_req)
388 {
389 pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
390 mlan_status ret = MLAN_STATUS_SUCCESS;
391 mlan_ds_get_info *info;
392 mlan_debug_info *debug_info = MNULL;
393 t_u32 i;
394 t_u8 *ptid;
395
396 ENTER();
397
398 info = (mlan_ds_get_info *)pioctl_req->pbuf;
399 debug_info = (mlan_debug_info *)info->param.debug_info;
400
401 if (pioctl_req->action == MLAN_ACT_GET) {
402 ptid = ac_to_tid[WMM_AC_BK];
403 debug_info->wmm_ac_bk = pmpriv->wmm.packets_out[ptid[0]] +
404 pmpriv->wmm.packets_out[ptid[1]];
405 ptid = ac_to_tid[WMM_AC_BE];
406 debug_info->wmm_ac_be = pmpriv->wmm.packets_out[ptid[0]] +
407 pmpriv->wmm.packets_out[ptid[1]];
408 ptid = ac_to_tid[WMM_AC_VI];
409 debug_info->wmm_ac_vi = pmpriv->wmm.packets_out[ptid[0]] +
410 pmpriv->wmm.packets_out[ptid[1]];
411 ptid = ac_to_tid[WMM_AC_VO];
412 debug_info->wmm_ac_vo = pmpriv->wmm.packets_out[ptid[0]] +
413 pmpriv->wmm.packets_out[ptid[1]];
414 debug_info->max_tx_buf_size = (t_u32)pmadapter->max_tx_buf_size;
415 debug_info->tx_buf_size = (t_u32)pmadapter->tx_buf_size;
416 debug_info->curr_tx_buf_size =
417 (t_u32)pmadapter->curr_tx_buf_size;
418 debug_info->rx_tbl_num =
419 wlan_get_rxreorder_tbl(pmpriv, debug_info->rx_tbl);
420 debug_info->tx_tbl_num =
421 wlan_get_txbastream_tbl(pmpriv, debug_info->tx_tbl);
422 debug_info->ralist_num =
423 wlan_get_ralist_info(pmpriv, debug_info->ralist);
424 debug_info->tdls_peer_num =
425 wlan_get_tdls_list(pmpriv, debug_info->tdls_peer_list);
426 debug_info->ps_mode = pmadapter->ps_mode;
427 debug_info->ps_state = pmadapter->ps_state;
428 #ifdef STA_SUPPORT
429 debug_info->is_deep_sleep = pmadapter->is_deep_sleep;
430 #endif /* STA_SUPPORT */
431 debug_info->pm_wakeup_card_req = pmadapter->pm_wakeup_card_req;
432 debug_info->pm_wakeup_fw_try = pmadapter->pm_wakeup_fw_try;
433 debug_info->pm_wakeup_in_secs = pmadapter->pm_wakeup_in_secs;
434 debug_info->pm_wakeup_timeout = pmadapter->pm_wakeup_timeout;
435 debug_info->is_hs_configured = pmadapter->is_hs_configured;
436 debug_info->hs_activated = pmadapter->hs_activated;
437 debug_info->pps_uapsd_mode = pmadapter->pps_uapsd_mode;
438 debug_info->sleep_pd = pmadapter->sleep_period.period;
439 debug_info->qos_cfg = pmpriv->wmm_qosinfo;
440 debug_info->tx_lock_flag = pmadapter->tx_lock_flag;
441 debug_info->port_open = pmpriv->port_open;
442 debug_info->bypass_pkt_count = pmadapter->bypass_pkt_count;
443 debug_info->scan_processing = pmadapter->scan_processing;
444 debug_info->scan_state = pmadapter->scan_state;
445 debug_info->mlan_processing = pmadapter->mlan_processing;
446 debug_info->main_lock_flag = pmadapter->main_lock_flag;
447 debug_info->main_process_cnt = pmadapter->main_process_cnt;
448 debug_info->delay_task_flag = pmadapter->delay_task_flag;
449 debug_info->num_cmd_host_to_card_failure =
450 pmadapter->dbg.num_cmd_host_to_card_failure;
451 debug_info->num_cmd_sleep_cfm_host_to_card_failure =
452 pmadapter->dbg.num_cmd_sleep_cfm_host_to_card_failure;
453 debug_info->num_tx_host_to_card_failure =
454 pmadapter->dbg.num_tx_host_to_card_failure;
455 debug_info->num_alloc_buffer_failure =
456 pmadapter->dbg.num_alloc_buffer_failure;
457 debug_info->num_pkt_dropped = pmadapter->dbg.num_pkt_dropped;
458
459 debug_info->num_event_deauth = pmadapter->dbg.num_event_deauth;
460 debug_info->num_event_disassoc =
461 pmadapter->dbg.num_event_disassoc;
462 debug_info->num_event_link_lost =
463 pmadapter->dbg.num_event_link_lost;
464 debug_info->num_cmd_deauth = pmadapter->dbg.num_cmd_deauth;
465 debug_info->num_cmd_assoc_success =
466 pmadapter->dbg.num_cmd_assoc_success;
467 debug_info->num_cmd_assoc_failure =
468 pmadapter->dbg.num_cmd_assoc_failure;
469 debug_info->num_cmd_timeout = pmadapter->num_cmd_timeout;
470 debug_info->timeout_cmd_id = pmadapter->dbg.timeout_cmd_id;
471 debug_info->timeout_cmd_act = pmadapter->dbg.timeout_cmd_act;
472 memcpy_ext(pmadapter, debug_info->last_cmd_id,
473 pmadapter->dbg.last_cmd_id,
474 sizeof(pmadapter->dbg.last_cmd_id),
475 sizeof(debug_info->last_cmd_id));
476 memcpy_ext(pmadapter, debug_info->last_cmd_act,
477 pmadapter->dbg.last_cmd_act,
478 sizeof(pmadapter->dbg.last_cmd_act),
479 sizeof(debug_info->last_cmd_act));
480 debug_info->last_cmd_index = pmadapter->dbg.last_cmd_index;
481 memcpy_ext(pmadapter, debug_info->last_cmd_resp_id,
482 pmadapter->dbg.last_cmd_resp_id,
483 sizeof(pmadapter->dbg.last_cmd_resp_id),
484 sizeof(debug_info->last_cmd_resp_id));
485 debug_info->last_cmd_resp_index =
486 pmadapter->dbg.last_cmd_resp_index;
487 memcpy_ext(pmadapter, debug_info->last_event,
488 pmadapter->dbg.last_event,
489 sizeof(pmadapter->dbg.last_event),
490 sizeof(debug_info->last_event));
491 debug_info->last_event_index = pmadapter->dbg.last_event_index;
492 debug_info->num_no_cmd_node = pmadapter->dbg.num_no_cmd_node;
493 debug_info->pending_cmd =
494 (pmadapter->curr_cmd) ?
495 pmadapter->dbg.last_cmd_id
496 [pmadapter->dbg.last_cmd_index] :
497 0;
498 debug_info->dnld_cmd_in_secs = pmadapter->dnld_cmd_in_secs;
499 #ifdef SDIO
500 if (IS_SD(pmadapter->card_type)) {
501 debug_info->num_cmdevt_card_to_host_failure =
502 pmadapter->dbg.num_cmdevt_card_to_host_failure;
503 debug_info->num_rx_card_to_host_failure =
504 pmadapter->dbg.num_rx_card_to_host_failure;
505 debug_info->num_int_read_failure =
506 pmadapter->dbg.num_int_read_failure;
507 debug_info->last_int_status =
508 pmadapter->dbg.last_int_status;
509 debug_info->mp_rd_bitmap =
510 pmadapter->pcard_sd->mp_rd_bitmap;
511 debug_info->mp_wr_bitmap =
512 pmadapter->pcard_sd->mp_wr_bitmap;
513 debug_info->curr_rd_port =
514 pmadapter->pcard_sd->curr_rd_port;
515 debug_info->curr_wr_port =
516 pmadapter->pcard_sd->curr_wr_port;
517 debug_info->mp_invalid_update =
518 pmadapter->pcard_sd->mp_invalid_update;
519 debug_info->num_of_irq =
520 pmadapter->pcard_sd->num_of_irq;
521 memcpy_ext(pmadapter, debug_info->mp_update,
522 pmadapter->pcard_sd->mp_update,
523 sizeof(pmadapter->pcard_sd->mp_update),
524 sizeof(debug_info->mp_update));
525 memcpy_ext(pmadapter, debug_info->mpa_tx_count,
526 pmadapter->pcard_sd->mpa_tx_count,
527 sizeof(pmadapter->pcard_sd->mpa_tx_count),
528 sizeof(debug_info->mpa_tx_count));
529 debug_info->mpa_sent_last_pkt =
530 pmadapter->pcard_sd->mpa_sent_last_pkt;
531 debug_info->mpa_sent_no_ports =
532 pmadapter->pcard_sd->mpa_sent_no_ports;
533 debug_info->last_recv_wr_bitmap =
534 pmadapter->pcard_sd->last_recv_wr_bitmap;
535 debug_info->last_recv_rd_bitmap =
536 pmadapter->pcard_sd->last_recv_rd_bitmap;
537 debug_info->mp_data_port_mask =
538 pmadapter->pcard_sd->mp_data_port_mask;
539 debug_info->last_mp_index =
540 pmadapter->pcard_sd->last_mp_index;
541 memcpy_ext(
542 pmadapter, debug_info->last_mp_wr_bitmap,
543 pmadapter->pcard_sd->last_mp_wr_bitmap,
544 sizeof(pmadapter->pcard_sd->last_mp_wr_bitmap),
545 sizeof(debug_info->last_mp_wr_bitmap));
546 memcpy_ext(
547 pmadapter, debug_info->last_mp_wr_ports,
548 pmadapter->pcard_sd->last_mp_wr_ports,
549 sizeof(pmadapter->pcard_sd->last_mp_wr_ports),
550 sizeof(debug_info->last_mp_wr_ports));
551 memcpy_ext(pmadapter, debug_info->last_mp_wr_len,
552 pmadapter->pcard_sd->last_mp_wr_len,
553 sizeof(pmadapter->pcard_sd->last_mp_wr_len),
554 sizeof(debug_info->last_mp_wr_len));
555 memcpy_ext(pmadapter, debug_info->last_mp_wr_info,
556 pmadapter->pcard_sd->last_mp_wr_info,
557 sizeof(pmadapter->pcard_sd->last_mp_wr_info),
558 sizeof(debug_info->last_mp_wr_info));
559 memcpy_ext(
560 pmadapter, debug_info->last_curr_wr_port,
561 pmadapter->pcard_sd->last_curr_wr_port,
562 sizeof(pmadapter->pcard_sd->last_curr_wr_port),
563 sizeof(debug_info->last_curr_wr_port));
564 debug_info->mpa_buf = pmadapter->pcard_sd->mpa_buf;
565 debug_info->mpa_buf_size =
566 pmadapter->pcard_sd->mpa_buf_size;
567 debug_info->sdio_rx_aggr =
568 pmadapter->pcard_sd->sdio_rx_aggr_enable;
569 memcpy_ext(pmadapter, debug_info->mpa_rx_count,
570 pmadapter->pcard_sd->mpa_rx_count,
571 sizeof(pmadapter->pcard_sd->mpa_rx_count),
572 sizeof(debug_info->mpa_rx_count));
573 debug_info->mp_aggr_pkt_limit =
574 pmadapter->pcard_sd->mp_aggr_pkt_limit;
575 }
576 #endif
577 #ifdef PCIE
578 if (IS_PCIE(pmadapter->card_type)) {
579 debug_info->txbd_rdptr =
580 pmadapter->pcard_pcie->txbd_rdptr;
581 debug_info->txbd_wrptr =
582 pmadapter->pcard_pcie->txbd_wrptr;
583 debug_info->rxbd_rdptr =
584 pmadapter->pcard_pcie->rxbd_rdptr;
585 debug_info->rxbd_wrptr =
586 pmadapter->pcard_pcie->rxbd_wrptr;
587 debug_info->eventbd_rdptr =
588 pmadapter->pcard_pcie->evtbd_rdptr;
589 debug_info->eventbd_wrptr =
590 pmadapter->pcard_pcie->evtbd_wrptr;
591 debug_info->txbd_ring_vbase =
592 pmadapter->pcard_pcie->txbd_ring_vbase;
593 debug_info->txbd_ring_size =
594 pmadapter->pcard_pcie->txbd_ring_size;
595 debug_info->rxbd_ring_vbase =
596 pmadapter->pcard_pcie->rxbd_ring_vbase;
597 debug_info->rxbd_ring_size =
598 pmadapter->pcard_pcie->rxbd_ring_size;
599 debug_info->evtbd_ring_vbase =
600 pmadapter->pcard_pcie->evtbd_ring_vbase;
601 debug_info->evtbd_ring_size =
602 pmadapter->pcard_pcie->evtbd_ring_size;
603 debug_info->txrx_bd_size =
604 pmadapter->pcard_pcie->txrx_bd_size;
605 }
606 #endif
607 debug_info->data_sent = pmadapter->data_sent;
608 debug_info->data_sent_cnt = pmadapter->data_sent_cnt;
609 debug_info->cmd_sent = pmadapter->cmd_sent;
610 debug_info->cmd_resp_received = pmadapter->cmd_resp_received;
611 debug_info->tx_pkts_queued =
612 util_scalar_read(pmadapter->pmoal_handle,
613 &pmpriv->wmm.tx_pkts_queued, MNULL,
614 MNULL);
615 #ifdef UAP_SUPPORT
616 debug_info->num_bridge_pkts =
617 util_scalar_read(pmadapter->pmoal_handle,
618 &pmadapter->pending_bridge_pkts,
619 pmadapter->callbacks.moal_spin_lock,
620 pmadapter->callbacks.moal_spin_unlock);
621 debug_info->num_drop_pkts = pmpriv->num_drop_pkts;
622 #endif
623 debug_info->fw_hang_report = pmadapter->fw_hang_report;
624 debug_info->mlan_processing = pmadapter->mlan_processing;
625 debug_info->mlan_rx_processing = pmadapter->mlan_rx_processing;
626 debug_info->rx_pkts_queued = pmadapter->rx_pkts_queued;
627 debug_info->mlan_adapter = pmadapter;
628 debug_info->mlan_adapter_size = sizeof(mlan_adapter);
629 debug_info->mlan_priv_num = pmadapter->priv_num;
630 for (i = 0; i < pmadapter->priv_num; i++) {
631 debug_info->mlan_priv[i] = pmadapter->priv[i];
632 debug_info->mlan_priv_size[i] = sizeof(mlan_private);
633 }
634 }
635
636 pioctl_req->data_read_written =
637 sizeof(mlan_debug_info) + MLAN_SUB_COMMAND_SIZE;
638
639 LEAVE();
640 return ret;
641 }
642
643 /**
644 * @brief Set/Get the MAC control configuration.
645 *
646 * @param pmadapter A pointer to mlan_adapter structure
647 * @param pioctl_req A pointer to ioctl request buffer
648 *
649 * @return MLAN_STATUS_PENDING -- success, otherwise fail
650 */
wlan_misc_ioctl_mac_control(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)651 mlan_status wlan_misc_ioctl_mac_control(pmlan_adapter pmadapter,
652 pmlan_ioctl_req pioctl_req)
653 {
654 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
655 mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
656 mlan_status ret = MLAN_STATUS_SUCCESS;
657 t_u16 cmd_action = 0;
658
659 ENTER();
660
661 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
662
663 if (pioctl_req->action == MLAN_ACT_GET) {
664 misc->param.mac_ctrl = pmpriv->curr_pkt_filter;
665 } else {
666 pmpriv->curr_pkt_filter = misc->param.mac_ctrl;
667 cmd_action = HostCmd_ACT_GEN_SET;
668
669 /* Send command to firmware */
670 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MAC_CONTROL,
671 cmd_action, 0, (t_void *)pioctl_req,
672 &misc->param.mac_ctrl);
673
674 if (ret == MLAN_STATUS_SUCCESS)
675 ret = MLAN_STATUS_PENDING;
676 }
677
678 LEAVE();
679 return ret;
680 }
681
682 /**
683 * @brief This timer function handles wakeup card timeout.
684 *
685 * @param function_context A pointer to function_context
686 * @return N/A
687 */
wlan_wakeup_card_timeout_func(void * function_context)688 t_void wlan_wakeup_card_timeout_func(void *function_context)
689 {
690 pmlan_adapter pmadapter = (pmlan_adapter)function_context;
691 mlan_private *pmpriv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);
692
693 ENTER();
694
695 PRINTM(MERROR, "%s: ps_state=%d\n", __FUNCTION__, pmadapter->ps_state);
696 if (pmadapter->ps_state != PS_STATE_AWAKE) {
697 PRINTM_NETINTF(MERROR, pmpriv);
698 PRINTM(MERROR, "Wakeup card timeout!\n");
699 pmadapter->pm_wakeup_timeout++;
700 wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_DBG_DUMP, MNULL);
701 }
702 pmadapter->wakeup_fw_timer_is_set = MFALSE;
703
704 LEAVE();
705 }
706
707 /**
708 * @brief Set/Get HS configuration
709 *
710 * @param pmadapter A pointer to mlan_adapter structure
711 * @param pioctl_req A pointer to ioctl request buffer
712 *
713 * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
714 * otherwise fail
715 */
wlan_pm_ioctl_hscfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)716 mlan_status wlan_pm_ioctl_hscfg(pmlan_adapter pmadapter,
717 pmlan_ioctl_req pioctl_req)
718 {
719 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
720 mlan_ds_pm_cfg *pm = MNULL;
721 mlan_status status = MLAN_STATUS_SUCCESS;
722 t_u32 prev_cond = 0;
723
724 ENTER();
725
726 pm = (mlan_ds_pm_cfg *)pioctl_req->pbuf;
727
728 switch (pioctl_req->action) {
729 case MLAN_ACT_SET:
730 #ifdef STA_SUPPORT
731 if (pmadapter->pps_uapsd_mode) {
732 PRINTM(MINFO,
733 "Host Sleep IOCTL is blocked in UAPSD/PPS mode\n");
734 pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
735 status = MLAN_STATUS_FAILURE;
736 break;
737 }
738 #endif /* STA_SUPPORT */
739 if (pm->param.hs_cfg.is_invoke_hostcmd == MTRUE) {
740 if (pm->param.hs_cfg.conditions ==
741 HOST_SLEEP_CFG_CANCEL) {
742 if (pmadapter->is_hs_configured == MFALSE) {
743 /* Already cancelled */
744 break;
745 }
746 /* Save previous condition */
747 prev_cond = pmadapter->hs_cfg.conditions;
748 pmadapter->hs_cfg.conditions =
749 pm->param.hs_cfg.conditions;
750 } else if (pmadapter->hs_cfg.conditions ==
751 HOST_SLEEP_CFG_CANCEL) {
752 /* Return failure if no parameters for HS enable
753 */
754 pioctl_req->status_code =
755 MLAN_ERROR_INVALID_PARAMETER;
756 status = MLAN_STATUS_FAILURE;
757 break;
758 }
759 status = wlan_prepare_cmd(
760 pmpriv, HostCmd_CMD_802_11_HS_CFG_ENH,
761 HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
762 (t_void *)(&pmadapter->hs_cfg));
763 if (status == MLAN_STATUS_SUCCESS)
764 status = MLAN_STATUS_PENDING;
765 if (pm->param.hs_cfg.conditions ==
766 HOST_SLEEP_CFG_CANCEL) {
767 /* Restore previous condition */
768 pmadapter->hs_cfg.conditions = prev_cond;
769 }
770 } else {
771 pmadapter->hs_cfg.conditions =
772 pm->param.hs_cfg.conditions;
773 pmadapter->hs_cfg.gpio = (t_u8)pm->param.hs_cfg.gpio;
774 pmadapter->hs_cfg.gap = (t_u8)pm->param.hs_cfg.gap;
775 pmadapter->param_type_ind =
776 (t_u8)pm->param.hs_cfg.param_type_ind;
777 pmadapter->ind_gpio = (t_u8)pm->param.hs_cfg.ind_gpio;
778 pmadapter->level = (t_u8)pm->param.hs_cfg.level;
779 pmadapter->param_type_ext =
780 (t_u8)pm->param.hs_cfg.param_type_ext;
781 pmadapter->event_force_ignore =
782 pm->param.hs_cfg.event_force_ignore;
783 pmadapter->event_use_ext_gap =
784 pm->param.hs_cfg.event_use_ext_gap;
785 pmadapter->ext_gap = pm->param.hs_cfg.ext_gap;
786 pmadapter->gpio_wave = pm->param.hs_cfg.gpio_wave;
787 pmadapter->hs_wake_interval =
788 pm->param.hs_cfg.hs_wake_interval;
789 pmadapter->min_wake_holdoff =
790 pm->param.hs_cfg.min_wake_holdoff;
791 }
792 break;
793 case MLAN_ACT_GET:
794 pm->param.hs_cfg.conditions = pmadapter->hs_cfg.conditions;
795 pm->param.hs_cfg.gpio = pmadapter->hs_cfg.gpio;
796 pm->param.hs_cfg.gap = pmadapter->hs_cfg.gap;
797 pm->param.hs_cfg.param_type_ind = pmadapter->param_type_ind;
798 pm->param.hs_cfg.ind_gpio = pmadapter->ind_gpio;
799 pm->param.hs_cfg.level = pmadapter->level;
800 pm->param.hs_cfg.param_type_ext = pmadapter->param_type_ext;
801 pm->param.hs_cfg.event_force_ignore =
802 pmadapter->event_force_ignore;
803 pm->param.hs_cfg.event_use_ext_gap =
804 pmadapter->event_use_ext_gap;
805 pm->param.hs_cfg.ext_gap = pmadapter->ext_gap;
806 pm->param.hs_cfg.gpio_wave = pmadapter->gpio_wave;
807 pm->param.hs_cfg.hs_wake_interval = pmadapter->hs_wake_interval;
808 pm->param.hs_cfg.min_wake_holdoff = pmadapter->min_wake_holdoff;
809 break;
810 default:
811 pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
812 status = MLAN_STATUS_FAILURE;
813 break;
814 }
815
816 LEAVE();
817 return status;
818 }
819
820 /**
821 * @brief Set Robustcoex gpiocfg
822 *
823 * @param pmadapter A pointer to mlan_adapter structure
824 * @param pioctl_req A pointer to ioctl request buffer
825 *
826 * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
827 * otherwise fail
828 */
wlan_misc_robustcoex(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)829 mlan_status wlan_misc_robustcoex(pmlan_adapter pmadapter,
830 pmlan_ioctl_req pioctl_req)
831 {
832 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
833 mlan_status ret = MLAN_STATUS_SUCCESS;
834 t_u16 cmd_action;
835 mlan_ds_misc_cfg *robust_coex_cfg =
836 (mlan_ds_misc_cfg *)pioctl_req->pbuf;
837
838 ENTER();
839
840 if (pioctl_req->action == MLAN_ACT_SET)
841 cmd_action = HostCmd_ACT_GEN_SET;
842 else
843 cmd_action = HostCmd_ACT_GEN_GET;
844
845 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_ROBUSTCOEX,
846 cmd_action, 0, (t_void *)pioctl_req,
847 &robust_coex_cfg->param.robustcoexparams);
848
849 if (ret == MLAN_STATUS_SUCCESS)
850 ret = MLAN_STATUS_PENDING;
851 LEAVE();
852 return ret;
853 }
854
855 /**
856 * @brief Set/get DMCS config
857 *
858 * @param pmadapter A pointer to mlan_adapter structure
859 * @param pioctl_req A pointer to ioctl request buffer
860 *
861 * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success, otherwise fail
862 */
wlan_misc_dmcs_config(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)863 mlan_status wlan_misc_dmcs_config(pmlan_adapter pmadapter,
864 pmlan_ioctl_req pioctl_req)
865 {
866 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
867 mlan_status ret = MLAN_STATUS_SUCCESS;
868 t_u16 cmd_action;
869 mlan_ds_misc_cfg *dmcs_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
870
871 ENTER();
872
873 if (pioctl_req->action == MLAN_ACT_SET)
874 cmd_action = HostCmd_ACT_GEN_SET;
875 else
876 cmd_action = HostCmd_ACT_GEN_GET;
877
878 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_DMCS_CONFIG, cmd_action, 0,
879 (t_void *)pioctl_req,
880 &dmcs_cfg->param.dmcs_policy);
881
882 if (ret == MLAN_STATUS_SUCCESS)
883 ret = MLAN_STATUS_PENDING;
884 LEAVE();
885 return ret;
886 }
887
888 #if defined(PCIE)
889 /**
890 * @brief Enable SSU support
891 *
892 * @param pmadapter A pointer to mlan_adapter structure
893 * @param pioctl_req A pointer to ioctl request buffer
894 *
895 * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
896 * otherwise fail
897 */
wlan_misc_ssu(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)898 mlan_status wlan_misc_ssu(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
899 {
900 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
901 mlan_status ret = MLAN_STATUS_SUCCESS;
902 t_u16 cmd_action = HostCmd_ACT_GEN_GET;
903 mlan_ds_misc_cfg *ssu_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
904
905 ENTER();
906
907 if (pioctl_req->action == MLAN_ACT_SET)
908 cmd_action = HostCmd_ACT_GEN_SET;
909 else if (pioctl_req->action == MLAN_ACT_DEFAULT)
910 cmd_action = HostCmd_ACT_GEN_SET_DEFAULT;
911 else if (pioctl_req->action == MLAN_ACT_GET)
912 cmd_action = HostCmd_ACT_GEN_GET;
913
914 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_SSU, cmd_action, 0,
915 (t_void *)pioctl_req,
916 &ssu_cfg->param.ssu_params);
917
918 if (ret == MLAN_STATUS_SUCCESS)
919 ret = MLAN_STATUS_PENDING;
920 LEAVE();
921 return ret;
922 }
923 #endif
924
925 /**
926 * @brief Set the hal/phy cfg params.
927 *
928 * @param pmadapter A pointer to mlan_adapter structure
929 * @param pioctl_req A pointer to ioctl request buffer
930 *
931 * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
932 * otherwise fail
933 */
wlan_misc_hal_phy_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)934 mlan_status wlan_misc_hal_phy_cfg(pmlan_adapter pmadapter,
935 pmlan_ioctl_req pioctl_req)
936 {
937 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
938 mlan_status ret = MLAN_STATUS_SUCCESS;
939 mlan_ds_misc_cfg *hal_phy_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
940 t_u16 cmd_act;
941
942 ENTER();
943
944 cmd_act = HostCmd_ACT_GEN_SET;
945 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_HAL_PHY_CFG, cmd_act, 0,
946 (t_void *)pioctl_req,
947 &hal_phy_cfg->param.hal_phy_cfg_params);
948
949 if (ret == MLAN_STATUS_SUCCESS)
950 ret = MLAN_STATUS_PENDING;
951
952 LEAVE();
953 return ret;
954 }
955
956 /**
957 * @brief Enable/disable CSI support
958 *
959 * @param pmadapter A pointer to mlan_adapter structure
960 * @param pioctl_req A pointer to ioctl request buffer
961 *
962 * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
963 * otherwise fail
964 */
wlan_misc_csi(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)965 mlan_status wlan_misc_csi(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
966 {
967 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
968 mlan_status ret = MLAN_STATUS_SUCCESS;
969 mlan_ds_misc_cfg *csi_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
970 t_u16 cmd_act;
971
972 ENTER();
973
974 if (csi_cfg->param.csi_params.csi_enable == 1) {
975 if (pmadapter->csi_enabled) {
976 PRINTM(MERROR,
977 "Enable CSI: CSI was already enabled.\n");
978 ret = MLAN_STATUS_FAILURE;
979 goto done;
980 }
981 cmd_act = CSI_CMD_ENABLE;
982 } else {
983 if (!pmadapter->csi_enabled) {
984 PRINTM(MERROR,
985 "Disable CSI: CSI was already disabled.\n");
986 ret = MLAN_STATUS_FAILURE;
987 goto done;
988 }
989 cmd_act = CSI_CMD_DISABLE;
990 }
991
992 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_CSI, cmd_act, 0,
993 (t_void *)pioctl_req,
994 &csi_cfg->param.csi_params);
995
996 if (ret == MLAN_STATUS_SUCCESS)
997 ret = MLAN_STATUS_PENDING;
998
999 done:
1000 LEAVE();
1001 return ret;
1002 }
1003
1004 /**
1005 * @brief This function allocates a mlan_buffer.
1006 *
1007 * @param pmadapter Pointer to mlan_adapter
1008 * @param data_len Data length
1009 * @param head_room head_room reserved in mlan_buffer
1010 * @param malloc_flag flag to user moal_malloc
1011 * @return mlan_buffer pointer or MNULL
1012 */
wlan_alloc_mlan_buffer(mlan_adapter * pmadapter,t_u32 data_len,t_u32 head_room,t_u32 malloc_flag)1013 pmlan_buffer wlan_alloc_mlan_buffer(mlan_adapter *pmadapter, t_u32 data_len,
1014 t_u32 head_room, t_u32 malloc_flag)
1015 {
1016 mlan_status ret = MLAN_STATUS_SUCCESS;
1017 pmlan_buffer pmbuf = MNULL;
1018 t_u32 buf_size = 0;
1019 t_u8 *tmp_buf = MNULL;
1020 pmlan_callbacks pcb = &pmadapter->callbacks;
1021 t_u32 mem_flags = MLAN_MEM_DEF | MLAN_MEM_DMA;
1022
1023 ENTER();
1024
1025 #ifdef SDIO
1026 /* make sure that the data length is at least SDIO block size */
1027 if (IS_SD(pmadapter->card_type))
1028 data_len = (data_len + MLAN_SDIO_BLOCK_SIZE - 1) /
1029 MLAN_SDIO_BLOCK_SIZE * MLAN_SDIO_BLOCK_SIZE;
1030 #endif
1031
1032 /* head_room is not implemented for malloc mlan buffer */
1033 if (malloc_flag & MOAL_MALLOC_BUFFER) {
1034 buf_size = sizeof(mlan_buffer) + data_len + DMA_ALIGNMENT;
1035 if (malloc_flag & MOAL_MEM_FLAG_ATOMIC)
1036 mem_flags |= MLAN_MEM_FLAG_ATOMIC;
1037 ret = pcb->moal_malloc(pmadapter->pmoal_handle, buf_size,
1038 mem_flags, (t_u8 **)&pmbuf);
1039 if ((ret != MLAN_STATUS_SUCCESS) || !pmbuf) {
1040 pmbuf = MNULL;
1041 goto exit;
1042 }
1043 memset(pmadapter, pmbuf, 0, sizeof(mlan_buffer));
1044
1045 pmbuf->pdesc = MNULL;
1046 /* Align address */
1047 pmbuf->pbuf = (t_u8 *)ALIGN_ADDR(
1048 (t_u8 *)pmbuf + sizeof(mlan_buffer), DMA_ALIGNMENT);
1049 pmbuf->data_offset = 0;
1050 pmbuf->data_len = data_len;
1051 pmbuf->flags |= MLAN_BUF_FLAG_MALLOC_BUF;
1052 } else if (malloc_flag & MOAL_ALLOC_MLAN_BUFFER) {
1053 /* use moal_alloc_mlan_buffer, head_room supported */
1054 ret = pcb->moal_alloc_mlan_buffer(
1055 pmadapter->pmoal_handle,
1056 data_len + DMA_ALIGNMENT + head_room, &pmbuf);
1057 if ((ret != MLAN_STATUS_SUCCESS) || !pmbuf) {
1058 PRINTM(MERROR, "Failed to allocate 'mlan_buffer'\n");
1059 goto exit;
1060 }
1061 pmbuf->data_offset = head_room;
1062 tmp_buf = (t_u8 *)ALIGN_ADDR(pmbuf->pbuf + pmbuf->data_offset,
1063 DMA_ALIGNMENT);
1064 pmbuf->data_offset +=
1065 (t_u32)(tmp_buf - (pmbuf->pbuf + pmbuf->data_offset));
1066 pmbuf->data_len = data_len;
1067 pmbuf->flags = 0;
1068 }
1069
1070 exit:
1071 LEAVE();
1072 return pmbuf;
1073 }
1074
1075 /**
1076 * @brief This function frees a mlan_buffer.
1077 *
1078 * @param pmadapter Pointer to mlan_adapter
1079 * @param pmbuf Pointer to mlan_buffer
1080 *
1081 * @return N/A
1082 */
wlan_free_mlan_buffer(mlan_adapter * pmadapter,pmlan_buffer pmbuf)1083 t_void wlan_free_mlan_buffer(mlan_adapter *pmadapter, pmlan_buffer pmbuf)
1084 {
1085 pmlan_callbacks pcb = &pmadapter->callbacks;
1086 ENTER();
1087
1088 if (pcb && pmbuf) {
1089 if (pmbuf->flags & MLAN_BUF_FLAG_BRIDGE_BUF)
1090 util_scalar_decrement(
1091 pmadapter->pmoal_handle,
1092 &pmadapter->pending_bridge_pkts,
1093 pmadapter->callbacks.moal_spin_lock,
1094 pmadapter->callbacks.moal_spin_unlock);
1095 if (pmbuf->flags & MLAN_BUF_FLAG_MALLOC_BUF)
1096 pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)pmbuf);
1097 else
1098 pcb->moal_free_mlan_buffer(pmadapter->pmoal_handle,
1099 pmbuf);
1100 }
1101
1102 LEAVE();
1103 return;
1104 }
1105
1106 /**
1107 * @brief Delay function implementation
1108 *
1109 * @param pmadapter A pointer to mlan_adapter structure
1110 * @param delay Delay value
1111 * @param u Units of delay (sec, msec or usec)
1112 *
1113 * @return N/A
1114 */
wlan_delay_func(mlan_adapter * pmadapter,t_u32 delay,t_delay_unit u)1115 t_void wlan_delay_func(mlan_adapter *pmadapter, t_u32 delay, t_delay_unit u)
1116 {
1117 t_u32 now_tv_sec, now_tv_usec;
1118 t_u32 upto_tv_sec, upto_tv_usec;
1119 pmlan_callbacks pcb = &pmadapter->callbacks;
1120
1121 ENTER();
1122
1123 if (pcb->moal_udelay) {
1124 if (u == SEC)
1125 delay *= 1000000;
1126 else if (u == MSEC)
1127 delay *= 1000;
1128 pcb->moal_udelay(pmadapter->pmoal_handle, delay);
1129 } else {
1130 pcb->moal_get_system_time(pmadapter->pmoal_handle, &upto_tv_sec,
1131 &upto_tv_usec);
1132
1133 switch (u) {
1134 case SEC:
1135 upto_tv_sec += delay;
1136 break;
1137 case MSEC:
1138 delay *= 1000;
1139 /* fall through */
1140 case USEC:
1141 upto_tv_sec += (delay / 1000000);
1142 upto_tv_usec += (delay % 1000000);
1143 break;
1144 }
1145
1146 do {
1147 pcb->moal_get_system_time(pmadapter->pmoal_handle,
1148 &now_tv_sec, &now_tv_usec);
1149 if (now_tv_sec > upto_tv_sec) {
1150 LEAVE();
1151 return;
1152 }
1153
1154 if ((now_tv_sec == upto_tv_sec) &&
1155 (now_tv_usec >= upto_tv_usec)) {
1156 LEAVE();
1157 return;
1158 }
1159 } while (MTRUE);
1160 }
1161
1162 LEAVE();
1163 return;
1164 }
1165
1166 /**
1167 * @brief BSS remove
1168 *
1169 * @param pmadapter A pointer to mlan_adapter structure
1170 * @param pioctl_req A pointer to ioctl request buffer
1171 *
1172 * @return MLAN_STATUS_PENDING --success, MLAN_STATUS_FAILURE
1173 */
wlan_bss_ioctl_bss_remove(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)1174 mlan_status wlan_bss_ioctl_bss_remove(pmlan_adapter pmadapter,
1175 pmlan_ioctl_req pioctl_req)
1176 {
1177 ENTER();
1178 wlan_cancel_bss_pending_cmd(pmadapter, pioctl_req->bss_index);
1179 LEAVE();
1180 return MLAN_STATUS_SUCCESS;
1181 }
1182
1183 #if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
1184 /**
1185 * @brief Set/Get BSS role
1186 *
1187 * @param pmadapter A pointer to mlan_adapter structure
1188 * @param pioctl_req A pointer to ioctl request buffer
1189 *
1190 * @return MLAN_STATUS_PENDING --success, MLAN_STATUS_FAILURE
1191 */
wlan_bss_ioctl_bss_role(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)1192 mlan_status wlan_bss_ioctl_bss_role(pmlan_adapter pmadapter,
1193 pmlan_ioctl_req pioctl_req)
1194 {
1195 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
1196 mlan_ds_bss *bss = MNULL;
1197 mlan_status ret = MLAN_STATUS_SUCCESS;
1198 HostCmd_DS_VERSION_EXT dummy;
1199 #ifdef USB
1200 pmlan_callbacks pcb = &pmadapter->callbacks;
1201 pmlan_buffer pmbuf;
1202 #endif
1203 #if defined(WIFI_DIRECT_SUPPORT)
1204 t_u8 bss_mode;
1205 #endif
1206 t_u8 i, global_band = 0;
1207 int j;
1208
1209 ENTER();
1210
1211 bss = (mlan_ds_bss *)pioctl_req->pbuf;
1212 if (pioctl_req->action == MLAN_ACT_GET) {
1213 bss->param.bss_role = GET_BSS_ROLE(pmpriv);
1214 } else {
1215 if (GET_BSS_ROLE(pmpriv) == bss->param.bss_role) {
1216 PRINTM(MIOCTL, "BSS ie already in the desired role!\n");
1217 goto done;
1218 }
1219 mlan_block_rx_process(pmadapter, MTRUE);
1220 /** Switch BSS role */
1221 wlan_free_priv(pmpriv);
1222
1223 #ifdef USB
1224 if (IS_USB(pmadapter->card_type)) {
1225 while ((pmbuf = (pmlan_buffer)util_dequeue_list(
1226 pmadapter->pmoal_handle,
1227 &pmadapter->rx_data_queue,
1228 pcb->moal_spin_lock,
1229 pcb->moal_spin_unlock))) {
1230 pcb->moal_recv_complete(pmadapter->pmoal_handle,
1231 pmbuf,
1232 pmadapter->rx_data_ep,
1233 MLAN_STATUS_FAILURE);
1234 }
1235 }
1236 #endif
1237 pmpriv->bss_role = bss->param.bss_role;
1238 if (pmpriv->bss_type == MLAN_BSS_TYPE_UAP)
1239 pmpriv->bss_type = MLAN_BSS_TYPE_STA;
1240 else if (pmpriv->bss_type == MLAN_BSS_TYPE_STA)
1241 pmpriv->bss_type = MLAN_BSS_TYPE_UAP;
1242 /* Initialize private structures */
1243 wlan_init_priv(pmpriv);
1244 /* restore mac address */
1245 memcpy_ext(pmpriv->adapter, pmpriv->curr_addr,
1246 pmpriv->adapter->permanent_addr,
1247 MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
1248 mlan_block_rx_process(pmadapter, MFALSE);
1249 /* Initialize function table */
1250 for (j = 0; mlan_ops[j]; j++) {
1251 if (mlan_ops[j]->bss_role == GET_BSS_ROLE(pmpriv)) {
1252 memcpy_ext(pmadapter, &pmpriv->ops, mlan_ops[j],
1253 sizeof(mlan_operations),
1254 sizeof(mlan_operations));
1255 }
1256 }
1257
1258 for (i = 0; i < pmadapter->priv_num; i++) {
1259 if (pmadapter->priv[i] &&
1260 GET_BSS_ROLE(pmadapter->priv[i]) ==
1261 MLAN_BSS_ROLE_STA)
1262 global_band |= pmadapter->priv[i]->config_bands;
1263 }
1264
1265 if (global_band != pmadapter->config_bands) {
1266 if (wlan_set_regiontable(
1267 pmpriv, (t_u8)pmadapter->region_code,
1268 global_band |
1269 pmadapter->adhoc_start_band)) {
1270 pioctl_req->status_code = MLAN_ERROR_IOCTL_FAIL;
1271 LEAVE();
1272 return MLAN_STATUS_FAILURE;
1273 }
1274
1275 if (wlan_11d_set_universaltable(
1276 pmpriv,
1277 global_band |
1278 pmadapter->adhoc_start_band)) {
1279 pioctl_req->status_code = MLAN_ERROR_IOCTL_FAIL;
1280 LEAVE();
1281 return MLAN_STATUS_FAILURE;
1282 }
1283 pmadapter->config_bands = global_band;
1284 }
1285
1286 /* Issue commands to initialize firmware */
1287 #if defined(WIFI_DIRECT_SUPPORT)
1288 if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_STA)
1289 bss_mode = BSS_MODE_WIFIDIRECT_CLIENT;
1290 else
1291 bss_mode = BSS_MODE_WIFIDIRECT_GO;
1292 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_SET_BSS_MODE,
1293 HostCmd_ACT_GEN_SET, 0, MNULL,
1294 &bss_mode);
1295 if (ret)
1296 goto done;
1297 #endif
1298 ret = pmpriv->ops.init_cmd(pmpriv, MFALSE);
1299 if (ret == MLAN_STATUS_FAILURE)
1300 goto done;
1301
1302 /* Issue dummy Get command to complete the ioctl */
1303 memset(pmadapter, &dummy, 0, sizeof(HostCmd_DS_VERSION_EXT));
1304 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_VERSION_EXT,
1305 HostCmd_ACT_GEN_GET, 0,
1306 (t_void *)pioctl_req, (t_void *)&dummy);
1307 if (ret == MLAN_STATUS_SUCCESS)
1308 ret = MLAN_STATUS_PENDING;
1309 }
1310
1311 done:
1312 LEAVE();
1313 return ret;
1314 }
1315 #endif
1316
1317 /**
1318 * @brief Set the custom IE
1319 *
1320 * @param pmadapter A pointer to mlan_adapter structure
1321 * @param pioctl_req A pointer to ioctl request buffer
1322 * @param send_ioctl Flag to indicate if ioctl should be sent with cmd
1323 * (MTRUE if from moal/user, MFALSE if internal)
1324 *
1325 * @return MLAN_STATUS_PENDING --success, otherwise fail
1326 */
wlan_misc_ioctl_custom_ie_list(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req,t_bool send_ioctl)1327 mlan_status wlan_misc_ioctl_custom_ie_list(pmlan_adapter pmadapter,
1328 pmlan_ioctl_req pioctl_req,
1329 t_bool send_ioctl)
1330 {
1331 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
1332 mlan_status ret = MLAN_STATUS_SUCCESS;
1333 mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
1334 custom_ie *ie_data = MNULL;
1335 t_u16 cmd_action = 0, index, mask, i, len, app_data_len;
1336 t_s32 ioctl_len;
1337 t_u8 *tmp_ie;
1338
1339 ENTER();
1340
1341 if ((misc->param.cust_ie.len == 0) ||
1342 (misc->param.cust_ie.len == sizeof(t_u16))) {
1343 pioctl_req->action = MLAN_ACT_GET;
1344 /* Get the IE */
1345 cmd_action = HostCmd_ACT_GEN_GET;
1346 } else {
1347 /* ioctl_len : ioctl length from application, start with
1348 * misc->param.cust_ie.len and reach upto 0 */
1349 ioctl_len = misc->param.cust_ie.len;
1350
1351 /* app_data_len : length from application, start with 0
1352 * and reach upto ioctl_len */
1353 app_data_len = sizeof(MrvlIEtypesHeader_t);
1354 misc->param.cust_ie.len = 0;
1355
1356 while (ioctl_len > 0) {
1357 ie_data = (custom_ie *)(((t_u8 *)&misc->param.cust_ie) +
1358 app_data_len);
1359 ioctl_len -=
1360 (ie_data->ie_length + MLAN_CUSTOM_IE_HDR_SIZE);
1361 app_data_len +=
1362 (ie_data->ie_length + MLAN_CUSTOM_IE_HDR_SIZE);
1363
1364 index = ie_data->ie_index;
1365 mask = ie_data->mgmt_subtype_mask;
1366
1367 /* Need to be Autohandled */
1368 if (MLAN_CUSTOM_IE_AUTO_IDX_MASK == index) {
1369 /* Automatic Deletion */
1370 if (mask == MLAN_CUSTOM_IE_DELETE_MASK) {
1371 ret = wlan_custom_ioctl_auto_delete(
1372 pmpriv, pioctl_req, ie_data,
1373 index);
1374 /* if IE to delete is not found, return
1375 * error */
1376 if (ret == MLAN_STATUS_FAILURE)
1377 goto done;
1378 index = ie_data->ie_index;
1379 memset(pmadapter, ie_data, 0,
1380 sizeof(custom_ie) *
1381 MAX_MGMT_IE_INDEX_TO_FW);
1382 len = 0;
1383 for (i = 0;
1384 i < pmadapter->max_mgmt_ie_index;
1385 i++) {
1386 /* Check if index is updated
1387 * before sending to FW */
1388 if (index & ((t_u16)1) << i) {
1389 memcpy_ext(
1390 pmadapter,
1391 (t_u8 *)ie_data +
1392 len,
1393 &i,
1394 sizeof(ie_data->ie_index),
1395 sizeof(ie_data->ie_index));
1396 len += sizeof(
1397 ie_data->ie_index);
1398 memcpy_ext(
1399 pmadapter,
1400 (t_u8 *)ie_data +
1401 len,
1402 &pmpriv->mgmt_ie[i]
1403 .mgmt_subtype_mask,
1404 sizeof(ie_data->mgmt_subtype_mask),
1405 sizeof(ie_data->mgmt_subtype_mask));
1406 len += sizeof(
1407 ie_data->mgmt_subtype_mask);
1408 memcpy_ext(
1409 pmadapter,
1410 (t_u8 *)ie_data +
1411 len,
1412 &pmpriv->mgmt_ie[i]
1413 .ie_length,
1414 sizeof(ie_data->ie_length),
1415 sizeof(ie_data->ie_length));
1416 len += sizeof(
1417 ie_data->ie_length);
1418 if (pmpriv->mgmt_ie[i]
1419 .ie_length) {
1420 memcpy_ext(
1421 pmadapter,
1422 (t_u8 *)ie_data +
1423 len,
1424 &pmpriv->mgmt_ie[i]
1425 .ie_buffer,
1426 pmpriv->mgmt_ie[i]
1427 .ie_length,
1428 pmpriv->mgmt_ie[i]
1429 .ie_length);
1430 len += pmpriv->mgmt_ie[i]
1431 .ie_length;
1432 }
1433 }
1434 }
1435 misc->param.cust_ie.len += len;
1436 pioctl_req->action = MLAN_ACT_SET;
1437 cmd_action = HostCmd_ACT_GEN_SET;
1438 } else { /* Automatic Addition */
1439 if (MLAN_STATUS_FAILURE ==
1440 wlan_custom_ioctl_get_autoidx(
1441 pmpriv, pioctl_req, mask,
1442 ie_data, &index)) {
1443 PRINTM(MERROR,
1444 "Failed to Set the IE buffer\n");
1445 ret = MLAN_STATUS_FAILURE;
1446 goto done;
1447 }
1448 mask &= ~MLAN_CUSTOM_IE_NEW_MASK;
1449 if (MLAN_CUSTOM_IE_AUTO_IDX_MASK ==
1450 index ||
1451 index >= MAX_MGMT_IE_INDEX) {
1452 ret = MLAN_STATUS_SUCCESS;
1453 goto done;
1454 }
1455 tmp_ie = (t_u8 *)&pmpriv->mgmt_ie[index]
1456 .ie_buffer;
1457 memcpy_ext(
1458 pmadapter,
1459 tmp_ie + pmpriv->mgmt_ie[index]
1460 .ie_length,
1461 &ie_data->ie_buffer,
1462 ie_data->ie_length,
1463 ie_data->ie_length);
1464 pmpriv->mgmt_ie[index].ie_length +=
1465 ie_data->ie_length;
1466 pmpriv->mgmt_ie[index].ie_index = index;
1467 pmpriv->mgmt_ie[index]
1468 .mgmt_subtype_mask = mask;
1469
1470 pioctl_req->action = MLAN_ACT_SET;
1471 cmd_action = HostCmd_ACT_GEN_SET;
1472 ie_data->ie_index = index;
1473 ie_data->ie_length =
1474 pmpriv->mgmt_ie[index].ie_length;
1475 memcpy_ext(
1476 pmadapter, &ie_data->ie_buffer,
1477 &pmpriv->mgmt_ie[index]
1478 .ie_buffer,
1479 pmpriv->mgmt_ie[index].ie_length,
1480 MAX_IE_SIZE);
1481 misc->param.cust_ie.len +=
1482 pmpriv->mgmt_ie[index]
1483 .ie_length +
1484 MLAN_CUSTOM_IE_HDR_SIZE;
1485 }
1486 } else {
1487 if (index >= pmadapter->max_mgmt_ie_index ||
1488 index >= MAX_MGMT_IE_INDEX) {
1489 PRINTM(MERROR,
1490 "Invalid custom IE index %d\n",
1491 index);
1492 ret = MLAN_STATUS_FAILURE;
1493 goto done;
1494 }
1495 /* Set/Clear the IE and save it */
1496 if (ie_data->mgmt_subtype_mask ==
1497 MLAN_CUSTOM_IE_DELETE_MASK &&
1498 ie_data->ie_length) {
1499 PRINTM(MINFO, "Clear the IE buffer\n");
1500 ret = wlan_custom_ioctl_auto_delete(
1501 pmpriv, pioctl_req, ie_data,
1502 index);
1503 /* if IE to delete is not found, return
1504 * error */
1505 if (ret == MLAN_STATUS_FAILURE)
1506 goto done;
1507 memset(pmadapter, ie_data, 0,
1508 sizeof(custom_ie) *
1509 MAX_MGMT_IE_INDEX_TO_FW);
1510 memcpy_ext(
1511 pmadapter, (t_u8 *)ie_data,
1512 &pmpriv->mgmt_ie[index],
1513 pmpriv->mgmt_ie[index].ie_length +
1514 MLAN_CUSTOM_IE_HDR_SIZE,
1515 pmpriv->mgmt_ie[index].ie_length +
1516 MLAN_CUSTOM_IE_HDR_SIZE);
1517 } else {
1518 /*
1519 * Check if this index is being used on
1520 * any other interfaces. If yes, then
1521 * the request needs to be rejected.
1522 */
1523 ret = wlan_is_custom_ie_index_unused(
1524 pmpriv, index);
1525 if (ret == MLAN_STATUS_FAILURE) {
1526 PRINTM(MERROR,
1527 "IE index is used by other interface.\n");
1528 PRINTM(MERROR,
1529 "Set or delete on index %d is not allowed.\n",
1530 index);
1531 pioctl_req->status_code =
1532 MLAN_ERROR_IOCTL_FAIL;
1533 goto done;
1534 }
1535 PRINTM(MINFO, "Set the IE buffer\n");
1536 if (ie_data->mgmt_subtype_mask ==
1537 MLAN_CUSTOM_IE_DELETE_MASK)
1538 ie_data->ie_length = 0;
1539 else {
1540 if ((pmpriv->mgmt_ie[index]
1541 .mgmt_subtype_mask ==
1542 ie_data->mgmt_subtype_mask) &&
1543 (pmpriv->mgmt_ie[index]
1544 .ie_length ==
1545 ie_data->ie_length) &&
1546 !memcmp(pmpriv->adapter,
1547 pmpriv->mgmt_ie[index]
1548 .ie_buffer,
1549 ie_data->ie_buffer,
1550 ie_data->ie_length)) {
1551 PRINTM(MIOCTL,
1552 "same custom ie already configured!\n");
1553 if (ioctl_len <= 0 &&
1554 misc->param.cust_ie
1555 .len ==
1556 0) {
1557 goto done;
1558 } else {
1559 /* remove
1560 * matching IE
1561 * from app
1562 * buffer */
1563 app_data_len -=
1564 ie_data->ie_length +
1565 MLAN_CUSTOM_IE_HDR_SIZE;
1566 memmove(pmadapter,
1567 (t_u8 *)ie_data,
1568 ie_data->ie_buffer +
1569 ie_data->ie_length,
1570 ioctl_len);
1571 continue;
1572 }
1573 }
1574 }
1575 memset(pmadapter,
1576 &pmpriv->mgmt_ie[index], 0,
1577 sizeof(custom_ie));
1578 memcpy_ext(pmadapter,
1579 &pmpriv->mgmt_ie[index],
1580 ie_data, sizeof(custom_ie),
1581 sizeof(custom_ie));
1582 }
1583
1584 misc->param.cust_ie.len +=
1585 pmpriv->mgmt_ie[index].ie_length +
1586 MLAN_CUSTOM_IE_HDR_SIZE;
1587 pioctl_req->action = MLAN_ACT_SET;
1588 cmd_action = HostCmd_ACT_GEN_SET;
1589 }
1590 }
1591 }
1592
1593 /* Send command to firmware */
1594 if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_STA) {
1595 ret = wlan_prepare_cmd(
1596 pmpriv, HostCmd_CMD_MGMT_IE_LIST, cmd_action, 0,
1597 (send_ioctl) ? (t_void *)pioctl_req : MNULL,
1598 &misc->param.cust_ie);
1599 }
1600 #ifdef UAP_SUPPORT
1601 else if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_UAP) {
1602 ret = wlan_prepare_cmd(
1603 pmpriv, HOST_CMD_APCMD_SYS_CONFIGURE, cmd_action, 0,
1604 (send_ioctl) ? (t_void *)pioctl_req : MNULL,
1605 (send_ioctl) ? MNULL : &misc->param.cust_ie);
1606 }
1607 #endif
1608 if (ret == MLAN_STATUS_SUCCESS)
1609 ret = MLAN_STATUS_PENDING;
1610 done:
1611 LEAVE();
1612 return ret;
1613 }
1614
1615 /**
1616 * @brief Read/write adapter register
1617 *
1618 * @param pmadapter A pointer to mlan_adapter structure
1619 * @param pioctl_req A pointer to ioctl request buffer
1620 *
1621 * @return MLAN_STATUS_PENDING --success, otherwise fail
1622 */
wlan_reg_mem_ioctl_reg_rw(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)1623 mlan_status wlan_reg_mem_ioctl_reg_rw(pmlan_adapter pmadapter,
1624 pmlan_ioctl_req pioctl_req)
1625 {
1626 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
1627 mlan_ds_reg_mem *reg_mem = MNULL;
1628 mlan_status ret = MLAN_STATUS_SUCCESS;
1629 t_u16 cmd_action = 0, cmd_no;
1630
1631 ENTER();
1632
1633 reg_mem = (mlan_ds_reg_mem *)pioctl_req->pbuf;
1634 if (pioctl_req->action == MLAN_ACT_GET)
1635 cmd_action = HostCmd_ACT_GEN_GET;
1636 else
1637 cmd_action = HostCmd_ACT_GEN_SET;
1638
1639 switch (reg_mem->param.reg_rw.type) {
1640 case MLAN_REG_MAC:
1641 #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \
1642 defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \
1643 defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097)
1644 case MLAN_REG_MAC2:
1645 #endif
1646 cmd_no = HostCmd_CMD_MAC_REG_ACCESS;
1647 break;
1648 case MLAN_REG_BBP:
1649 #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \
1650 defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \
1651 defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097)
1652 case MLAN_REG_BBP2:
1653 #endif
1654 cmd_no = HostCmd_CMD_BBP_REG_ACCESS;
1655 break;
1656 case MLAN_REG_RF:
1657 #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \
1658 defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \
1659 defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097)
1660 case MLAN_REG_RF2:
1661 #endif
1662 cmd_no = HostCmd_CMD_RF_REG_ACCESS;
1663 break;
1664 case MLAN_REG_CAU:
1665 cmd_no = HostCmd_CMD_CAU_REG_ACCESS;
1666 break;
1667 case MLAN_REG_PSU:
1668 cmd_no = HostCmd_CMD_TARGET_ACCESS;
1669 break;
1670 case MLAN_REG_BCA:
1671 #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \
1672 defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \
1673 defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097)
1674 case MLAN_REG_BCA2:
1675 #endif
1676 cmd_no = HostCmd_CMD_BCA_REG_ACCESS;
1677 break;
1678 #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \
1679 defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \
1680 defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097) || \
1681 defined(SD9177)
1682 case MLAN_REG_CIU:
1683 cmd_no = HostCmd_CMD_REG_ACCESS;
1684 break;
1685 #endif
1686 default:
1687 pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
1688 ret = MLAN_STATUS_FAILURE;
1689 goto exit;
1690 }
1691
1692 /* Send request to firmware */
1693 ret = wlan_prepare_cmd(pmpriv, cmd_no, cmd_action, 0,
1694 (t_void *)pioctl_req,
1695 (t_void *)®_mem->param.reg_rw);
1696
1697 if (ret == MLAN_STATUS_SUCCESS)
1698 ret = MLAN_STATUS_PENDING;
1699
1700 exit:
1701 LEAVE();
1702 return ret;
1703 }
1704
1705 /**
1706 * @brief Read the EEPROM contents of the card
1707 *
1708 * @param pmadapter A pointer to mlan_adapter structure
1709 * @param pioctl_req A pointer to ioctl request buffer
1710 *
1711 * @return MLAN_STATUS_PENDING --success, otherwise fail
1712 */
wlan_reg_mem_ioctl_read_eeprom(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)1713 mlan_status wlan_reg_mem_ioctl_read_eeprom(pmlan_adapter pmadapter,
1714 pmlan_ioctl_req pioctl_req)
1715 {
1716 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
1717 mlan_ds_reg_mem *reg_mem = MNULL;
1718 mlan_status ret = MLAN_STATUS_SUCCESS;
1719 t_u16 cmd_action = 0;
1720
1721 ENTER();
1722
1723 reg_mem = (mlan_ds_reg_mem *)pioctl_req->pbuf;
1724 if (pioctl_req->action == MLAN_ACT_GET)
1725 cmd_action = HostCmd_ACT_GEN_GET;
1726
1727 /* Send request to firmware */
1728 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_EEPROM_ACCESS,
1729 cmd_action, 0, (t_void *)pioctl_req,
1730 (t_void *)®_mem->param.rd_eeprom);
1731
1732 if (ret == MLAN_STATUS_SUCCESS)
1733 ret = MLAN_STATUS_PENDING;
1734
1735 LEAVE();
1736 return ret;
1737 }
1738
1739 /**
1740 * @brief Read/write memory of device
1741 *
1742 * @param pmadapter A pointer to mlan_adapter structure
1743 * @param pioctl_req A pointer to ioctl request buffer
1744 *
1745 * @return MLAN_STATUS_PENDING --success, otherwise fail
1746 */
wlan_reg_mem_ioctl_mem_rw(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)1747 mlan_status wlan_reg_mem_ioctl_mem_rw(pmlan_adapter pmadapter,
1748 pmlan_ioctl_req pioctl_req)
1749 {
1750 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
1751 mlan_ds_reg_mem *reg_mem = MNULL;
1752 mlan_status ret = MLAN_STATUS_SUCCESS;
1753 t_u16 cmd_action = 0;
1754
1755 ENTER();
1756
1757 reg_mem = (mlan_ds_reg_mem *)pioctl_req->pbuf;
1758 if (pioctl_req->action == MLAN_ACT_GET)
1759 cmd_action = HostCmd_ACT_GEN_GET;
1760 else
1761 cmd_action = HostCmd_ACT_GEN_SET;
1762
1763 /* Send request to firmware */
1764 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MEM_ACCESS, cmd_action, 0,
1765 (t_void *)pioctl_req,
1766 (t_void *)®_mem->param.mem_rw);
1767
1768 if (ret == MLAN_STATUS_SUCCESS)
1769 ret = MLAN_STATUS_PENDING;
1770
1771 LEAVE();
1772 return ret;
1773 }
1774
1775 /**
1776 * @brief This function will check if station list is empty
1777 *
1778 * @param priv A pointer to mlan_private
1779 *
1780 * @return MFALSE/MTRUE
1781 */
wlan_is_station_list_empty(mlan_private * priv)1782 t_u8 wlan_is_station_list_empty(mlan_private *priv)
1783 {
1784 ENTER();
1785 if (!(util_peek_list(priv->adapter->pmoal_handle, &priv->sta_list,
1786 priv->adapter->callbacks.moal_spin_lock,
1787 priv->adapter->callbacks.moal_spin_unlock))) {
1788 LEAVE();
1789 return MTRUE;
1790 }
1791 LEAVE();
1792 return MFALSE;
1793 }
1794
1795 /**
1796 * @brief This function will return the pointer to station entry in station
1797 * list table which matches the give mac address
1798 *
1799 * @param priv A pointer to mlan_private
1800 * @param mac mac address to find in station list table
1801 *
1802 * @return A pointer to structure sta_node
1803 */
wlan_get_station_entry(mlan_private * priv,t_u8 * mac)1804 sta_node *wlan_get_station_entry(mlan_private *priv, t_u8 *mac)
1805 {
1806 sta_node *sta_ptr;
1807
1808 ENTER();
1809
1810 if (!mac) {
1811 LEAVE();
1812 return MNULL;
1813 }
1814 sta_ptr = (sta_node *)util_peek_list(priv->adapter->pmoal_handle,
1815 &priv->sta_list, MNULL, MNULL);
1816
1817 while (sta_ptr && (sta_ptr != (sta_node *)&priv->sta_list)) {
1818 if (!memcmp(priv->adapter, sta_ptr->mac_addr, mac,
1819 MLAN_MAC_ADDR_LENGTH)) {
1820 LEAVE();
1821 return sta_ptr;
1822 }
1823 sta_ptr = sta_ptr->pnext;
1824 }
1825 LEAVE();
1826 return MNULL;
1827 }
1828
1829 /**
1830 * @brief This function will add a pointer to station entry in station list
1831 * table with the give mac address, if it does not exist already
1832 *
1833 * @param priv A pointer to mlan_private
1834 * @param mac mac address to find in station list table
1835 *
1836 * @return A pointer to structure sta_node
1837 */
wlan_add_station_entry(mlan_private * priv,t_u8 * mac)1838 sta_node *wlan_add_station_entry(mlan_private *priv, t_u8 *mac)
1839 {
1840 sta_node *sta_ptr = MNULL;
1841
1842 ENTER();
1843
1844 sta_ptr = wlan_get_station_entry(priv, mac);
1845 if (sta_ptr)
1846 goto done;
1847 if (priv->adapter->callbacks.moal_malloc(priv->adapter->pmoal_handle,
1848 sizeof(sta_node), MLAN_MEM_DEF,
1849 (t_u8 **)&sta_ptr)) {
1850 PRINTM(MERROR, "Failed to allocate memory for station node\n");
1851 LEAVE();
1852 return MNULL;
1853 }
1854 memset(priv->adapter, sta_ptr, 0, sizeof(sta_node));
1855 memcpy_ext(priv->adapter, sta_ptr->mac_addr, mac, MLAN_MAC_ADDR_LENGTH,
1856 MLAN_MAC_ADDR_LENGTH);
1857 util_enqueue_list_tail(priv->adapter->pmoal_handle, &priv->sta_list,
1858 (pmlan_linked_list)sta_ptr,
1859 priv->adapter->callbacks.moal_spin_lock,
1860 priv->adapter->callbacks.moal_spin_unlock);
1861 #ifdef DRV_EMBEDDED_AUTHENTICATOR
1862 if ((GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) &&
1863 IsAuthenticatorEnabled(priv->psapriv))
1864 authenticator_init_client(priv->psapriv,
1865 &sta_ptr->cm_connectioninfo, mac);
1866 #endif
1867 done:
1868 LEAVE();
1869 return sta_ptr;
1870 }
1871
1872 /**
1873 * @brief This function will delete a station entry from station list
1874 *
1875 *
1876 * @param priv A pointer to mlan_private
1877 * @param mac station's mac address
1878 *
1879 * @return N/A
1880 */
wlan_delete_station_entry(mlan_private * priv,t_u8 * mac)1881 t_void wlan_delete_station_entry(mlan_private *priv, t_u8 *mac)
1882 {
1883 sta_node *sta_ptr = MNULL;
1884 ENTER();
1885 sta_ptr = wlan_get_station_entry(priv, mac);
1886 if (sta_ptr) {
1887 #ifdef DRV_EMBEDDED_AUTHENTICATOR
1888 if ((GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) &&
1889 IsAuthenticatorEnabled(priv->psapriv))
1890 authenticator_free_client(priv->psapriv,
1891 sta_ptr->cm_connectioninfo);
1892 #endif
1893 util_unlink_list(priv->adapter->pmoal_handle, &priv->sta_list,
1894 (pmlan_linked_list)sta_ptr,
1895 priv->adapter->callbacks.moal_spin_lock,
1896 priv->adapter->callbacks.moal_spin_unlock);
1897 priv->adapter->callbacks.moal_mfree(priv->adapter->pmoal_handle,
1898 (t_u8 *)sta_ptr);
1899 }
1900
1901 LEAVE();
1902 return;
1903 }
1904
1905 /**
1906 * @brief Clean up wapi station list
1907 *
1908 * @param priv Pointer to the mlan_private driver data struct
1909 *
1910 * @return N/A
1911 */
wlan_delete_station_list(pmlan_private priv)1912 t_void wlan_delete_station_list(pmlan_private priv)
1913 {
1914 sta_node *sta_ptr;
1915
1916 ENTER();
1917 while ((sta_ptr = (sta_node *)util_dequeue_list(
1918 priv->adapter->pmoal_handle, &priv->sta_list,
1919 priv->adapter->callbacks.moal_spin_lock,
1920 priv->adapter->callbacks.moal_spin_unlock))) {
1921 #ifdef DRV_EMBEDDED_AUTHENTICATOR
1922 if ((GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) &&
1923 IsAuthenticatorEnabled(priv->psapriv))
1924 authenticator_free_client(priv->psapriv,
1925 sta_ptr->cm_connectioninfo);
1926 #endif
1927 priv->adapter->callbacks.moal_mfree(priv->adapter->pmoal_handle,
1928 (t_u8 *)sta_ptr);
1929 }
1930 LEAVE();
1931 return;
1932 }
1933
1934 /**
1935 * @brief Get tdls peer list
1936 *
1937 * @param priv A pointer to mlan_private structure
1938 * @param buf A pointer to tdls_peer_info buf
1939 * @return number of tdls peer
1940 */
wlan_get_tdls_list(mlan_private * priv,tdls_peer_info * buf)1941 int wlan_get_tdls_list(mlan_private *priv, tdls_peer_info *buf)
1942 {
1943 tdls_peer_info *peer_info = buf;
1944 sta_node *sta_ptr = MNULL;
1945 int count = 0;
1946 IEEEtypes_Header_t *ieee_hdr;
1947 ENTER();
1948 if (priv->bss_type != MLAN_BSS_TYPE_STA) {
1949 LEAVE();
1950 return count;
1951 }
1952 sta_ptr = (sta_node *)util_peek_list(
1953 priv->adapter->pmoal_handle, &priv->sta_list,
1954 priv->adapter->callbacks.moal_spin_lock,
1955 priv->adapter->callbacks.moal_spin_unlock);
1956 if (!sta_ptr) {
1957 LEAVE();
1958 return count;
1959 }
1960 while (sta_ptr != (sta_node *)&priv->sta_list) {
1961 if (sta_ptr->status == TDLS_SETUP_COMPLETE) {
1962 peer_info->snr = sta_ptr->snr;
1963 peer_info->nf = sta_ptr->nf;
1964 memcpy_ext(priv->adapter, peer_info->mac_addr,
1965 sta_ptr->mac_addr, MLAN_MAC_ADDR_LENGTH,
1966 MLAN_MAC_ADDR_LENGTH);
1967 memcpy_ext(priv->adapter, peer_info->ht_cap,
1968 &sta_ptr->HTcap, sizeof(IEEEtypes_HTCap_t),
1969 sizeof(peer_info->ht_cap));
1970 memcpy_ext(priv->adapter, peer_info->ext_cap,
1971 &sta_ptr->ExtCap, sizeof(IEEEtypes_ExtCap_t),
1972 sizeof(peer_info->ext_cap));
1973 memcpy_ext(priv->adapter, peer_info->vht_cap,
1974 &sta_ptr->vht_cap,
1975 sizeof(IEEEtypes_VHTCap_t),
1976 sizeof(peer_info->vht_cap));
1977 ieee_hdr = (IEEEtypes_Header_t *)peer_info->he_cap;
1978 memcpy_ext(priv->adapter, peer_info->he_cap,
1979 &sta_ptr->he_cap,
1980 sizeof(IEEEtypes_Header_t) + ieee_hdr->len,
1981 sizeof(peer_info->he_cap));
1982 peer_info++;
1983 count++;
1984 }
1985 sta_ptr = sta_ptr->pnext;
1986 if (count >= MLAN_MAX_TDLS_PEER_SUPPORTED)
1987 break;
1988 }
1989 LEAVE();
1990 return count;
1991 }
1992
1993 /**
1994 * @brief Set the TDLS configuration to FW.
1995 *
1996 * @param pmadapter A pointer to mlan_adapter structure
1997 * @param pioctl_req A pointer to ioctl request buffer
1998 *
1999 * @return MLAN_STATUS_PENDING --success, otherwise fail
2000 */
wlan_misc_ioctl_tdls_config(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)2001 mlan_status wlan_misc_ioctl_tdls_config(pmlan_adapter pmadapter,
2002 pmlan_ioctl_req pioctl_req)
2003 {
2004 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
2005 mlan_status ret = MLAN_STATUS_SUCCESS;
2006 mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
2007 tdls_all_config *tdls_all_cfg =
2008 (tdls_all_config *)misc->param.tdls_config.tdls_data;
2009 t_u8 event_buf[100];
2010 mlan_event *pevent = (mlan_event *)event_buf;
2011 tdls_tear_down_event *tdls_evt =
2012 (tdls_tear_down_event *)pevent->event_buf;
2013 sta_node *sta_ptr = MNULL;
2014 MrvlIEtypes_Data_t *pMrvlTlv = MNULL;
2015 t_u8 *pos = MNULL;
2016 t_u16 remain_len = 0;
2017
2018 ENTER();
2019
2020 if (misc->param.tdls_config.tdls_action == WLAN_TDLS_TEAR_DOWN_REQ) {
2021 sta_ptr = wlan_get_station_entry(
2022 pmpriv, tdls_all_cfg->u.tdls_tear_down.peer_mac_addr);
2023 if (sta_ptr && sta_ptr->external_tdls) {
2024 pevent->bss_index = pmpriv->bss_index;
2025 pevent->event_id = MLAN_EVENT_ID_DRV_TDLS_TEARDOWN_REQ;
2026 pevent->event_len = sizeof(tdls_tear_down_event);
2027 memcpy_ext(pmpriv->adapter,
2028 (t_u8 *)tdls_evt->peer_mac_addr,
2029 tdls_all_cfg->u.tdls_tear_down.peer_mac_addr,
2030 MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
2031 tdls_evt->reason_code =
2032 tdls_all_cfg->u.tdls_tear_down.reason_code;
2033 wlan_recv_event(pmpriv,
2034 MLAN_EVENT_ID_DRV_TDLS_TEARDOWN_REQ,
2035 pevent);
2036 LEAVE();
2037 return ret;
2038 }
2039 }
2040 if (misc->param.tdls_config.tdls_action == WLAN_HOST_TDLS_CONFIG) {
2041 pmpriv->host_tdls_uapsd_support =
2042 tdls_all_cfg->u.host_tdls_cfg.uapsd_support;
2043 pmpriv->host_tdls_cs_support =
2044 tdls_all_cfg->u.host_tdls_cfg.cs_support;
2045 pos = tdls_all_cfg->u.host_tdls_cfg.tlv_buffer;
2046 remain_len = tdls_all_cfg->u.host_tdls_cfg.tlv_len;
2047 while (remain_len > sizeof(MrvlIEtypesHeader_t)) {
2048 remain_len -= sizeof(MrvlIEtypesHeader_t);
2049 pMrvlTlv = (MrvlIEtypes_Data_t *)pos;
2050 switch (pMrvlTlv->header.type) {
2051 case SUPPORTED_CHANNELS:
2052 pmpriv->chan_supp_len = (t_u8)MIN(
2053 pMrvlTlv->header.len, MAX_IE_SIZE);
2054 memset(pmadapter, pmpriv->chan_supp, 0,
2055 sizeof(pmpriv->chan_supp));
2056 memcpy_ext(pmadapter, pmpriv->chan_supp,
2057 pMrvlTlv->data, pMrvlTlv->header.len,
2058 MAX_IE_SIZE);
2059 DBG_HEXDUMP(MCMD_D, "TDLS supported channel",
2060 pmpriv->chan_supp,
2061 pmpriv->chan_supp_len);
2062 break;
2063 case REGULATORY_CLASS:
2064 pmpriv->supp_regulatory_class_len = (t_u8)MIN(
2065 pMrvlTlv->header.len, MAX_IE_SIZE);
2066 memset(pmadapter, pmpriv->supp_regulatory_class,
2067 0,
2068 sizeof(pmpriv->supp_regulatory_class));
2069 memcpy_ext(pmadapter,
2070 pmpriv->supp_regulatory_class,
2071 pMrvlTlv->data, pMrvlTlv->header.len,
2072 MAX_IE_SIZE);
2073 DBG_HEXDUMP(MCMD_D,
2074 "TDLS supported regulatory class",
2075 pmpriv->supp_regulatory_class,
2076 pmpriv->supp_regulatory_class_len);
2077 break;
2078 default:
2079 break;
2080 }
2081 remain_len -= pMrvlTlv->header.len;
2082 pos += sizeof(MrvlIEtypesHeader_t) +
2083 pMrvlTlv->header.len;
2084 }
2085 LEAVE();
2086 return ret;
2087 }
2088 pioctl_req->action = MLAN_ACT_SET;
2089
2090 /* Send command to firmware */
2091 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG,
2092 HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
2093 &misc->param.tdls_config);
2094
2095 if (ret == MLAN_STATUS_SUCCESS)
2096 ret = MLAN_STATUS_PENDING;
2097 LEAVE();
2098 return ret;
2099 }
2100
2101 /**
2102 * @brief enable tdls config for cs and uapsd.
2103 *
2104 * @param pmpriv A pointer to mlan_private structure
2105 * @param enable MTRUE/MFALSE
2106 *
2107 * @return
2108 */
wlan_tdls_config(pmlan_private pmpriv,t_u8 enable)2109 t_void wlan_tdls_config(pmlan_private pmpriv, t_u8 enable)
2110 {
2111 mlan_adapter *pmadapter = pmpriv->adapter;
2112 mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks;
2113 mlan_ds_misc_tdls_config *tdls_config = MNULL;
2114 tdls_all_config *tdls_all_cfg = MNULL;
2115 mlan_status ret = MLAN_STATUS_SUCCESS;
2116
2117 ENTER();
2118
2119 ret = pcb->moal_malloc(pmadapter->pmoal_handle,
2120 sizeof(mlan_ds_misc_tdls_config), MLAN_MEM_DEF,
2121 (t_u8 **)&tdls_config);
2122 if (ret != MLAN_STATUS_SUCCESS || !tdls_config) {
2123 PRINTM(MERROR, "Memory allocation for tdls_config failed!\n");
2124 LEAVE();
2125 return;
2126 }
2127 memset(pmadapter, (t_u8 *)tdls_config, 0,
2128 sizeof(mlan_ds_misc_tdls_config));
2129 tdls_all_cfg = (tdls_all_config *)tdls_config->tdls_data;
2130 tdls_all_cfg->u.tdls_config.enable = enable;
2131 tdls_config->tdls_action = WLAN_TDLS_CONFIG;
2132 /* Send command to firmware */
2133 wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG, HostCmd_ACT_GEN_SET,
2134 0, MNULL, tdls_config);
2135 PRINTM(MCMND, "tdls_config: enable=%d\n", enable);
2136
2137 if (tdls_config)
2138 pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)tdls_config);
2139
2140 LEAVE();
2141 }
2142
2143 /**
2144 * @brief set tdls channel switch parameters.
2145 *
2146 * @param pmpriv A pointer to mlan_private structure
2147 *
2148 * @return
2149 */
wlan_tdls_cs_param_config(pmlan_private pmpriv)2150 static t_void wlan_tdls_cs_param_config(pmlan_private pmpriv)
2151 {
2152 mlan_adapter *pmadapter = pmpriv->adapter;
2153 mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks;
2154 mlan_ds_misc_tdls_config *tdls_config = MNULL;
2155 tdls_all_config *tdls_all_cfg = MNULL;
2156 mlan_status ret = MLAN_STATUS_SUCCESS;
2157
2158 ENTER();
2159
2160 ret = pcb->moal_malloc(pmadapter->pmoal_handle,
2161 sizeof(mlan_ds_misc_tdls_config), MLAN_MEM_DEF,
2162 (t_u8 **)&tdls_config);
2163 if (ret != MLAN_STATUS_SUCCESS || !tdls_config) {
2164 PRINTM(MERROR, "Memory allocation for tdls_config failed!\n");
2165 LEAVE();
2166 return;
2167 }
2168 memset(pmadapter, (t_u8 *)tdls_config, 0,
2169 sizeof(mlan_ds_misc_tdls_config));
2170
2171 tdls_all_cfg = (tdls_all_config *)tdls_config->tdls_data;
2172 tdls_config->tdls_action = WLAN_TDLS_CS_PARAMS;
2173 tdls_all_cfg->u.tdls_cs_params.unit_time = 2;
2174 tdls_all_cfg->u.tdls_cs_params.threshold_otherlink = 10;
2175 tdls_all_cfg->u.tdls_cs_params.threshold_directlink = 0;
2176
2177 /* Send command to firmware */
2178 wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG, HostCmd_ACT_GEN_SET,
2179 0, MNULL, tdls_config);
2180
2181 if (tdls_config)
2182 pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)tdls_config);
2183
2184 LEAVE();
2185 }
2186
2187 /**
2188 * @brief start tdls channel switch
2189 *
2190 * @param pmpriv A pointer to mlan_private structure
2191 * @param peer_mac_addr A pointer to peer mac address
2192 * @param pioctl_buf A pointer to ioctl request buffer
2193 *
2194 * @return
2195 */
wlan_tdls_cs_start(pmlan_private pmpriv,t_u8 * peer_mac_addr,pmlan_ioctl_req pioctl_buf)2196 static t_void wlan_tdls_cs_start(pmlan_private pmpriv, t_u8 *peer_mac_addr,
2197 pmlan_ioctl_req pioctl_buf)
2198 {
2199 mlan_adapter *pmadapter = pmpriv->adapter;
2200 mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks;
2201 mlan_ds_misc_tdls_config *tdls_config = MNULL;
2202 tdls_all_config *tdls_all_cfg = MNULL;
2203 mlan_ds_misc_cfg *misc = MNULL;
2204 mlan_status ret = MLAN_STATUS_SUCCESS;
2205
2206 ENTER();
2207
2208 ret = pcb->moal_malloc(pmadapter->pmoal_handle,
2209 sizeof(mlan_ds_misc_tdls_config), MLAN_MEM_DEF,
2210 (t_u8 **)&tdls_config);
2211 if (ret != MLAN_STATUS_SUCCESS || !tdls_config) {
2212 PRINTM(MERROR, "Memory allocation for tdls_config failed!\n");
2213 LEAVE();
2214 return;
2215 }
2216 memset(pmadapter, (t_u8 *)tdls_config, 0,
2217 sizeof(mlan_ds_misc_tdls_config));
2218
2219 if (pioctl_buf) {
2220 misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
2221 memcpy_ext(pmpriv->adapter, tdls_config,
2222 &misc->param.tdls_config,
2223 sizeof(mlan_ds_misc_tdls_config),
2224 sizeof(mlan_ds_misc_tdls_config));
2225 tdls_all_cfg = (tdls_all_config *)tdls_config->tdls_data;
2226 if (tdls_all_cfg->u.tdls_chan_switch.primary_channel > 14) {
2227 tdls_all_cfg->u.tdls_chan_switch
2228 .secondary_channel_offset =
2229 wlan_get_second_channel_offset(
2230 pmpriv, tdls_all_cfg->u.tdls_chan_switch
2231 .primary_channel);
2232 }
2233 PRINTM(MCMND, "Start TDLS CS: channel=%d\n",
2234 tdls_all_cfg->u.tdls_chan_switch.primary_channel);
2235 } else {
2236 tdls_all_cfg = (tdls_all_config *)tdls_config->tdls_data;
2237 tdls_config->tdls_action = WLAN_TDLS_INIT_CHAN_SWITCH;
2238 memcpy_ext(pmpriv->adapter,
2239 tdls_all_cfg->u.tdls_chan_switch.peer_mac_addr,
2240 peer_mac_addr, MLAN_MAC_ADDR_LENGTH,
2241 MLAN_MAC_ADDR_LENGTH);
2242 tdls_all_cfg->u.tdls_chan_switch.primary_channel =
2243 pmpriv->tdls_cs_channel;
2244 if (pmpriv->tdls_cs_channel > 14) {
2245 tdls_all_cfg->u.tdls_chan_switch.band = BAND_5GHZ;
2246 tdls_all_cfg->u.tdls_chan_switch
2247 .secondary_channel_offset =
2248 wlan_get_second_channel_offset(
2249 pmpriv, pmpriv->tdls_cs_channel);
2250 } else {
2251 tdls_all_cfg->u.tdls_chan_switch.band = BAND_2GHZ;
2252 }
2253 PRINTM(MCMND, "Start TDLS CS: channel=%d\n",
2254 pmpriv->tdls_cs_channel);
2255 }
2256 tdls_all_cfg->u.tdls_chan_switch.switch_time = 10;
2257 tdls_all_cfg->u.tdls_chan_switch.switch_timeout = 16;
2258 tdls_all_cfg->u.tdls_chan_switch.regulatory_class = 12;
2259 tdls_all_cfg->u.tdls_chan_switch.periodicity = 1;
2260
2261 /* Send command to firmware */
2262 wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG, HostCmd_ACT_GEN_SET,
2263 0, MNULL, tdls_config);
2264
2265 if (tdls_config)
2266 pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)tdls_config);
2267
2268 LEAVE();
2269 }
2270
2271 #if 0
2272 /**
2273 * @brief stop tdls channel switch
2274 *
2275 * @param pmpriv A pointer to mlan_private structure
2276 * @param peer_mac_addr A pointer to peer mac address
2277 * @param pioctl_buf A pointer to command buffer
2278 * @return
2279 */
2280 static t_void wlan_tdls_cs_stop(pmlan_private pmpriv, t_u8 *peer_mac_addr)
2281 {
2282 mlan_adapter *pmadapter = pmpriv->adapter;
2283 mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks;
2284 mlan_ds_misc_tdls_config *tdls_config = MNULL;
2285 tdls_all_config *tdls_all_cfg = MNULL;
2286 mlan_status ret = MLAN_STATUS_SUCCESS;
2287
2288 ENTER();
2289
2290 ret = pcb->moal_malloc(pmadapter->pmoal_handle,
2291 sizeof(mlan_ds_misc_tdls_config), MLAN_MEM_DEF,
2292 (t_u8 **)&tdls_config);
2293 if (ret != MLAN_STATUS_SUCCESS || !tdls_config) {
2294 PRINTM(MERROR, "Memory allocation for tdls_config failed!\n");
2295 LEAVE();
2296 return;
2297 }
2298 memset(pmadapter, (t_u8 *)tdls_config, 0,
2299 sizeof(mlan_ds_misc_tdls_config));
2300
2301 tdls_all_cfg = (tdls_all_config *)tdls_config->tdls_data;
2302 tdls_config->tdls_action = WLAN_TDLS_STOP_CHAN_SWITCH;
2303
2304 memcpy_ext(pmpriv->adapter,
2305 tdls_all_cfg->u.tdls_stop_chan_switch.peer_mac_addr,
2306 peer_mac_addr, MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
2307 PRINTM(MCMND, "Stop TDLS CS\n");
2308 /* Send command to firmware */
2309 wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG, HostCmd_ACT_GEN_SET,
2310 0, MNULL, tdls_config);
2311
2312 if (tdls_config)
2313 pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)tdls_config);
2314
2315 LEAVE();
2316 }
2317 #endif
2318
2319 /**
2320 * @brief Set/Get the TDLS off channel.
2321 *
2322 * @param pmadapter A pointer to mlan_adapter structure
2323 * @param pioctl_req A pointer to ioctl request buffer
2324 *
2325 * @return MLAN_STATUS_PENDING --success, otherwise fail
2326 */
wlan_misc_ioctl_tdls_cs_channel(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)2327 mlan_status wlan_misc_ioctl_tdls_cs_channel(pmlan_adapter pmadapter,
2328 pmlan_ioctl_req pioctl_req)
2329 {
2330 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
2331 mlan_status ret = MLAN_STATUS_SUCCESS;
2332 mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
2333
2334 ENTER();
2335
2336 if (MLAN_ACT_GET == pioctl_req->action)
2337 misc->param.tdls_cs_channel = pmpriv->tdls_cs_channel;
2338 else if (MLAN_ACT_SET == pioctl_req->action) {
2339 pmpriv->tdls_cs_channel = misc->param.tdls_cs_channel;
2340 }
2341 LEAVE();
2342 return ret;
2343 }
2344 /**
2345 * @brief Set/Get the TDLS idle time.
2346 *
2347 * @param pmadapter A pointer to mlan_adapter structure
2348 * @param pioctl_req A pointer to ioctl request buffer
2349 *
2350 * @return MLAN_STATUS_PENDING --success, otherwise fail
2351 */
wlan_misc_ioctl_tdls_idle_time(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)2352 mlan_status wlan_misc_ioctl_tdls_idle_time(pmlan_adapter pmadapter,
2353 pmlan_ioctl_req pioctl_req)
2354 {
2355 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
2356 mlan_status ret = MLAN_STATUS_SUCCESS;
2357 mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
2358
2359 ENTER();
2360
2361 if (MLAN_ACT_GET == pioctl_req->action) {
2362 misc->param.tdls_idle_time = pmpriv->tdls_idle_time;
2363 } else if (MLAN_ACT_SET == pioctl_req->action) {
2364 pmpriv->tdls_idle_time = misc->param.tdls_idle_time;
2365 }
2366 LEAVE();
2367 return ret;
2368 }
2369
2370 /**
2371 * @brief Set the TDLS operation to FW.
2372 *
2373 * @param pmadapter A pointer to mlan_adapter structure
2374 * @param pioctl_req A pointer to ioctl request buffer
2375 *
2376 * @return MLAN_STATUS_PENDING --success, otherwise fail
2377 */
wlan_misc_ioctl_tdls_oper(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)2378 mlan_status wlan_misc_ioctl_tdls_oper(pmlan_adapter pmadapter,
2379 pmlan_ioctl_req pioctl_req)
2380 {
2381 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
2382 mlan_status ret = MLAN_STATUS_SUCCESS;
2383 mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
2384 mlan_ds_misc_tdls_oper *ptdls_oper = &misc->param.tdls_oper;
2385 t_u8 event_buf[100];
2386 mlan_event *ptdls_event = (mlan_event *)event_buf;
2387 tdls_tear_down_event *tdls_evt =
2388 (tdls_tear_down_event *)ptdls_event->event_buf;
2389 sta_node *sta_ptr = MNULL;
2390 t_u8 i = 0;
2391
2392 ENTER();
2393 sta_ptr = wlan_get_station_entry(pmpriv, ptdls_oper->peer_mac);
2394 switch (ptdls_oper->tdls_action) {
2395 case WLAN_TDLS_ENABLE_LINK:
2396 if (sta_ptr && (sta_ptr->status != TDLS_SETUP_FAILURE)) {
2397 PRINTM(MMSG, "TDLS: Enable link " MACSTR " success\n",
2398 MAC2STR(ptdls_oper->peer_mac));
2399 sta_ptr->status = TDLS_SETUP_COMPLETE;
2400 pmadapter->tdls_status = TDLS_IN_BASE_CHANNEL;
2401 if (!pmpriv->txaggrctrl)
2402 wlan_11n_send_delba_to_peer(
2403 pmpriv,
2404 pmpriv->curr_bss_params.bss_descriptor
2405 .mac_address);
2406 if (sta_ptr->HTcap.ieee_hdr.element_id ==
2407 HT_CAPABILITY) {
2408 sta_ptr->is_11n_enabled = MTRUE;
2409 if (GETHT_MAXAMSDU(
2410 sta_ptr->HTcap.ht_cap.ht_cap_info))
2411 sta_ptr->max_amsdu =
2412 MLAN_TX_DATA_BUF_SIZE_8K;
2413 else
2414 sta_ptr->max_amsdu =
2415 MLAN_TX_DATA_BUF_SIZE_4K;
2416 for (i = 0; i < MAX_NUM_TID; i++) {
2417 if (sta_ptr->is_11n_enabled ||
2418 sta_ptr->is_11ax_enabled)
2419 sta_ptr->ampdu_sta[i] =
2420 pmpriv->aggr_prio_tbl[i]
2421 .ampdu_user;
2422 else
2423 sta_ptr->ampdu_sta[i] =
2424 BA_STREAM_NOT_ALLOWED;
2425 }
2426 memset(pmpriv->adapter, sta_ptr->rx_seq, 0xff,
2427 sizeof(sta_ptr->rx_seq));
2428 }
2429 wlan_restore_tdls_packets(pmpriv, ptdls_oper->peer_mac,
2430 TDLS_SETUP_COMPLETE);
2431 if (ISSUPP_EXTCAP_TDLS_CHAN_SWITCH(
2432 sta_ptr->ExtCap.ext_cap)) {
2433 wlan_tdls_config(pmpriv, MTRUE);
2434 wlan_tdls_cs_param_config(pmpriv);
2435 /**tdls cs start*/
2436 if (pmpriv->tdls_cs_channel &&
2437 pmpriv->tdls_cs_channel !=
2438 pmpriv->curr_bss_params
2439 .bss_descriptor.channel)
2440 wlan_tdls_cs_start(pmpriv,
2441 ptdls_oper->peer_mac,
2442 MNULL);
2443 }
2444 } else {
2445 PRINTM(MMSG, "TDLS: Enable link " MACSTR " fail\n",
2446 MAC2STR(ptdls_oper->peer_mac));
2447 /*for supplicant 2.0, we need send event to request
2448 *teardown, *for latest supplicant, we only need return
2449 *fail, and supplicant will send teardown packet and
2450 *disable tdls link*/
2451 if (sta_ptr) {
2452 ptdls_event->bss_index = pmpriv->bss_index;
2453 ptdls_event->event_id =
2454 MLAN_EVENT_ID_DRV_TDLS_TEARDOWN_REQ;
2455 ptdls_event->event_len =
2456 sizeof(tdls_tear_down_event);
2457 memcpy_ext(pmpriv->adapter,
2458 (t_u8 *)tdls_evt->peer_mac_addr,
2459 ptdls_oper->peer_mac,
2460 MLAN_MAC_ADDR_LENGTH,
2461 MLAN_MAC_ADDR_LENGTH);
2462 tdls_evt->reason_code =
2463 MLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED;
2464 wlan_recv_event(
2465 pmpriv,
2466 MLAN_EVENT_ID_DRV_TDLS_TEARDOWN_REQ,
2467 ptdls_event);
2468 wlan_restore_tdls_packets(pmpriv,
2469 ptdls_oper->peer_mac,
2470 TDLS_TEAR_DOWN);
2471 if (sta_ptr->is_11n_enabled ||
2472 sta_ptr->is_11ax_enabled) {
2473 wlan_cleanup_reorder_tbl(
2474 pmpriv, ptdls_oper->peer_mac);
2475 wlan_11n_cleanup_txbastream_tbl(
2476 pmpriv, ptdls_oper->peer_mac);
2477 }
2478 wlan_delete_station_entry(pmpriv,
2479 ptdls_oper->peer_mac);
2480 if (MTRUE == wlan_is_station_list_empty(pmpriv))
2481 pmadapter->tdls_status = TDLS_NOT_SETUP;
2482 else
2483 pmadapter->tdls_status =
2484 TDLS_IN_BASE_CHANNEL;
2485 }
2486 ret = MLAN_STATUS_FAILURE;
2487 }
2488 wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_DEFER_HANDLING,
2489 MNULL);
2490 break;
2491 case WLAN_TDLS_DISABLE_LINK:
2492 /* Send command to firmware to delete tdls link*/
2493 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_OPERATION,
2494 HostCmd_ACT_GEN_SET, 0,
2495 (t_void *)pioctl_req, ptdls_oper);
2496 if (ret == MLAN_STATUS_SUCCESS)
2497 ret = MLAN_STATUS_PENDING;
2498 break;
2499 case WLAN_TDLS_CREATE_LINK:
2500 PRINTM(MIOCTL, "CREATE TDLS LINK\n");
2501 if (sta_ptr && sta_ptr->status == TDLS_SETUP_INPROGRESS) {
2502 PRINTM(MIOCTL, "We already create the link\n");
2503 break;
2504 }
2505 if (!sta_ptr)
2506 sta_ptr = wlan_add_station_entry(
2507 pmpriv, misc->param.tdls_oper.peer_mac);
2508 if (sta_ptr) {
2509 sta_ptr->status = TDLS_SETUP_INPROGRESS;
2510 sta_ptr->external_tdls = MTRUE;
2511 wlan_hold_tdls_packets(pmpriv,
2512 misc->param.tdls_oper.peer_mac);
2513 }
2514 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_OPERATION,
2515 HostCmd_ACT_GEN_SET, 0,
2516 (t_void *)pioctl_req, ptdls_oper);
2517 if (ret == MLAN_STATUS_SUCCESS)
2518 ret = MLAN_STATUS_PENDING;
2519 break;
2520 case WLAN_TDLS_CONFIG_LINK:
2521 if (!sta_ptr || sta_ptr->status == TDLS_SETUP_FAILURE) {
2522 PRINTM(MERROR, "Can not CONFIG TDLS Link\n");
2523 ret = MLAN_STATUS_FAILURE;
2524 break;
2525 }
2526 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_OPERATION,
2527 HostCmd_ACT_GEN_SET, 0,
2528 (t_void *)pioctl_req, ptdls_oper);
2529 if (ret == MLAN_STATUS_SUCCESS)
2530 ret = MLAN_STATUS_PENDING;
2531 break;
2532 case WLAN_TDLS_INIT_CHAN_SWITCH:
2533 if (sta_ptr &&
2534 ISSUPP_EXTCAP_TDLS_CHAN_SWITCH(sta_ptr->ExtCap.ext_cap)) {
2535 wlan_tdls_config(pmpriv, MTRUE);
2536 wlan_tdls_cs_param_config(pmpriv);
2537 /**tdls cs start*/
2538 wlan_tdls_cs_start(pmpriv, ptdls_oper->peer_mac,
2539 pioctl_req);
2540 }
2541 wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_DEFER_HANDLING,
2542 MNULL);
2543 break;
2544 default:
2545 break;
2546 }
2547 LEAVE();
2548 return ret;
2549 }
2550
2551 /**
2552 * @brief Get AP's ext capability
2553 *
2554 * @param pmpriv A pointer to mlan_adapter structure
2555 * @param ext_cap A pointer to ExtCap_t structure
2556 *
2557 * @return MLAN_STATUS_PENDING --success, otherwise fail
2558 */
wlan_get_ap_ext_cap(mlan_private * pmpriv,ExtCap_t * ext_cap)2559 static void wlan_get_ap_ext_cap(mlan_private *pmpriv, ExtCap_t *ext_cap)
2560 {
2561 pmlan_adapter pmadapter = pmpriv->adapter;
2562 BSSDescriptor_t *pbss_desc;
2563 pbss_desc = &pmpriv->curr_bss_params.bss_descriptor;
2564 memset(pmadapter, ext_cap, 0, sizeof(ExtCap_t));
2565 if (pbss_desc->pext_cap) {
2566 memcpy_ext(pmadapter, (t_u8 *)ext_cap,
2567 (t_u8 *)pbss_desc->pext_cap +
2568 sizeof(IEEEtypes_Header_t),
2569 pbss_desc->pext_cap->ieee_hdr.len, sizeof(ExtCap_t));
2570 }
2571 return;
2572 }
2573
2574 /**
2575 * @brief Set the TDLS operation to FW.
2576 *
2577 * @param pmadapter A pointer to mlan_adapter structure
2578 * @param pioctl_req A pointer to ioctl request buffer
2579 *
2580 * @return MLAN_STATUS_PENDING --success, otherwise fail
2581 */
wlan_misc_ioctl_tdls_get_ies(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)2582 mlan_status wlan_misc_ioctl_tdls_get_ies(pmlan_adapter pmadapter,
2583 pmlan_ioctl_req pioctl_req)
2584 {
2585 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
2586 mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
2587 mlan_ds_misc_tdls_ies *tdls_ies = &misc->param.tdls_ies;
2588 mlan_status ret = MLAN_STATUS_SUCCESS;
2589 BSSDescriptor_t *pbss_desc;
2590 t_u32 usr_dot_11n_dev_cap;
2591 IEEEtypes_ExtCap_t *ext_cap = MNULL;
2592 ExtCap_t ap_ext_cap;
2593 IEEEtypes_HTCap_t *ht_cap = MNULL;
2594 IEEEtypes_HTInfo_t *ht_info = MNULL;
2595 IEEEtypes_VHTCap_t *vht_cap = MNULL;
2596 IEEEtypes_VHTOprat_t *vht_oprat = MNULL;
2597 IEEEtypes_AssocRsp_t *passoc_rsp = MNULL;
2598 IEEEtypes_AID_t *aid_info = MNULL;
2599 IEEEtypes_HECap_t *he_cap = MNULL;
2600 IEEEtypes_HeOp_t *he_op = MNULL;
2601 t_u8 supp_chan[] = {1, 11};
2602 t_u8 regulatory_class[] = {1, /**current class*/
2603 1, 2, 3, 4, 12, 22, 23, 24,
2604 25, 27, 28, 29, 30, 32, 33}; /**list
2605 regulatory
2606 class*/
2607 IEEEtypes_Generic_t *pSupp_chan = MNULL, *pRegulatory_class = MNULL;
2608 sta_node *sta_ptr = MNULL;
2609 ENTER();
2610
2611 /* We don't need peer information for TDLS setup */
2612 if (!(tdls_ies->flags & TDLS_IE_FLAGS_SETUP))
2613 sta_ptr = wlan_get_station_entry(pmpriv, tdls_ies->peer_mac);
2614 pbss_desc = &pmpriv->curr_bss_params.bss_descriptor;
2615 wlan_get_ap_ext_cap(pmpriv, &ap_ext_cap);
2616 if (pbss_desc->bss_band & BAND_A)
2617 usr_dot_11n_dev_cap = pmpriv->usr_dot_11n_dev_cap_a;
2618 else
2619 usr_dot_11n_dev_cap = pmpriv->usr_dot_11n_dev_cap_bg;
2620
2621 /** fill the extcap */
2622 if (tdls_ies->flags & TDLS_IE_FLAGS_EXTCAP) {
2623 ext_cap = (IEEEtypes_ExtCap_t *)tdls_ies->ext_cap;
2624 ext_cap->ieee_hdr.element_id = EXT_CAPABILITY;
2625 ext_cap->ieee_hdr.len = sizeof(ExtCap_t);
2626 SET_EXTCAP_TDLS(ext_cap->ext_cap);
2627 RESET_EXTCAP_TDLS_UAPSD(ext_cap->ext_cap);
2628 RESET_EXTCAP_TDLS_CHAN_SWITCH(ext_cap->ext_cap);
2629
2630 if (pmpriv->host_tdls_uapsd_support) {
2631 /* uapsd in tdls confirm frame*/
2632 if (tdls_ies->flags & TDLS_IE_FLAGS_HTINFO) {
2633 if (sta_ptr && ISSUPP_EXTCAP_TDLS_UAPSD(
2634 sta_ptr->ExtCap.ext_cap))
2635 SET_EXTCAP_TDLS_UAPSD(ext_cap->ext_cap);
2636 } else {
2637 SET_EXTCAP_TDLS_UAPSD(ext_cap->ext_cap);
2638 }
2639 }
2640 /* channel switch support */
2641 if (pmpriv->host_tdls_cs_support &&
2642 !IS_EXTCAP_TDLS_CHLSWITCHPROHIB(ap_ext_cap)) {
2643 /* channel switch in tdls confirm frame*/
2644 if (tdls_ies->flags & TDLS_IE_FLAGS_HTINFO) {
2645 if (sta_ptr && ISSUPP_EXTCAP_TDLS_CHAN_SWITCH(
2646 sta_ptr->ExtCap.ext_cap))
2647 SET_EXTCAP_TDLS_CHAN_SWITCH(
2648 ext_cap->ext_cap);
2649 } else {
2650 SET_EXTCAP_TDLS_CHAN_SWITCH(ext_cap->ext_cap);
2651 }
2652 }
2653
2654 RESET_EXTCAP_TDLS_WIDER_BANDWIDTH(ext_cap->ext_cap);
2655 if ((pmadapter->fw_bands & BAND_AAC) &&
2656 (MFALSE == wlan_is_ap_in_11ac_mode(pmpriv)))
2657 SET_EXTCAP_TDLS_WIDER_BANDWIDTH(ext_cap->ext_cap);
2658 /* if peer does not support wider bandwidth, don't set wider
2659 * bandwidth*/
2660 if (sta_ptr && sta_ptr->rate_len &&
2661 !ISSUPP_EXTCAP_TDLS_WIDER_BANDWIDTH(
2662 sta_ptr->ExtCap.ext_cap))
2663 RESET_EXTCAP_TDLS_WIDER_BANDWIDTH(ext_cap->ext_cap);
2664 DBG_HEXDUMP(MCMD_D, "TDLS extcap", tdls_ies->ext_cap,
2665 sizeof(IEEEtypes_ExtCap_t));
2666 }
2667
2668 /** default qos info is 0xf, compare with peer device qos info for tdls
2669 * confirm */
2670 if (tdls_ies->flags & TDLS_IE_FLAGS_QOS_INFO) {
2671 if (sta_ptr && sta_ptr->rate_len)
2672 tdls_ies->QosInfo = sta_ptr->qos_info & 0xf;
2673 PRINTM(MCMND, "TDLS Qos info=0x%x\n", tdls_ies->QosInfo);
2674 }
2675
2676 /** fill the htcap based on hwspec */
2677 if (tdls_ies->flags & TDLS_IE_FLAGS_HTCAP) {
2678 ht_cap = (IEEEtypes_HTCap_t *)tdls_ies->ht_cap;
2679 memset(pmadapter, ht_cap, 0, sizeof(IEEEtypes_HTCap_t));
2680 if ((sta_ptr && !ISSUPP_EXTCAP_TDLS_CHAN_SWITCH(
2681 sta_ptr->ExtCap.ext_cap)) ||
2682 IS_EXTCAP_TDLS_CHLSWITCHPROHIB(ap_ext_cap))
2683 wlan_fill_ht_cap_ie(pmpriv, ht_cap,
2684 pbss_desc->bss_band);
2685 else if (pmpriv->host_tdls_cs_support &&
2686 (pmadapter->fw_bands & BAND_A))
2687 wlan_fill_ht_cap_ie(pmpriv, ht_cap, BAND_A);
2688 else
2689 wlan_fill_ht_cap_ie(pmpriv, ht_cap,
2690 pbss_desc->bss_band);
2691 DBG_HEXDUMP(MCMD_D, "TDLS htcap", tdls_ies->ht_cap,
2692 sizeof(IEEEtypes_HTCap_t));
2693 }
2694 /** if peer did not support 11AC, do not add vht related ie */
2695 if (sta_ptr && sta_ptr->rate_len &&
2696 (sta_ptr->vht_cap.ieee_hdr.element_id != VHT_CAPABILITY))
2697 tdls_ies->flags &=
2698 ~(TDLS_IE_FLAGS_VHTCAP | TDLS_IE_FLAGS_VHTOPRAT |
2699 TDLS_IE_FLAGS_AID);
2700 /** fill the vhtcap based on hwspec */
2701 if (tdls_ies->flags & TDLS_IE_FLAGS_VHTCAP) {
2702 vht_cap = (IEEEtypes_VHTCap_t *)tdls_ies->vht_cap;
2703 memset(pmadapter, vht_cap, 0, sizeof(IEEEtypes_VHTCap_t));
2704 wlan_fill_vht_cap_ie(pmpriv, vht_cap, pbss_desc->bss_band);
2705 if (ht_cap)
2706 SETHT_SUPPCHANWIDTH(ht_cap->ht_cap.ht_cap_info);
2707 DBG_HEXDUMP(MCMD_D, "TDLS VHT Cap IE", tdls_ies->vht_cap,
2708 sizeof(IEEEtypes_VHTCap_t));
2709 }
2710 /** fill the vhtoperation based on hwspec */
2711 if (tdls_ies->flags & TDLS_IE_FLAGS_VHTOPRAT) {
2712 vht_oprat = (IEEEtypes_VHTOprat_t *)tdls_ies->vht_oprat;
2713 memset(pmadapter, vht_oprat, 0, sizeof(IEEEtypes_VHTOprat_t));
2714 if (sta_ptr &&
2715 (sta_ptr->vht_cap.ieee_hdr.element_id == VHT_CAPABILITY) &&
2716 (pbss_desc->bss_band & BAND_A)) {
2717 wlan_fill_tdls_vht_oprat_ie(pmpriv, vht_oprat, sta_ptr);
2718 }
2719 if (sta_ptr)
2720 memcpy_ext(pmadapter, &sta_ptr->vht_oprat,
2721 tdls_ies->vht_oprat,
2722 sizeof(IEEEtypes_VHTOprat_t),
2723 sizeof(IEEEtypes_VHTOprat_t));
2724 DBG_HEXDUMP(MCMD_D, "TDLS VHT Operation IE",
2725 tdls_ies->vht_oprat, sizeof(IEEEtypes_VHTOprat_t));
2726 }
2727 /** fill the AID info */
2728 if (tdls_ies->flags & TDLS_IE_FLAGS_AID) {
2729 if (pmpriv->curr_bss_params.host_mlme)
2730 passoc_rsp = (IEEEtypes_AssocRsp_t
2731 *)(pmpriv->assoc_rsp_buf +
2732 sizeof(IEEEtypes_MgmtHdr_t));
2733 else
2734 passoc_rsp =
2735 (IEEEtypes_AssocRsp_t *)pmpriv->assoc_rsp_buf;
2736 aid_info = (IEEEtypes_AID_t *)tdls_ies->aid_info;
2737 memset(pmadapter, aid_info, 0, sizeof(IEEEtypes_AID_t));
2738 aid_info->ieee_hdr.element_id = AID_INFO;
2739 aid_info->ieee_hdr.len = sizeof(t_u16);
2740 aid_info->AID = wlan_le16_to_cpu(passoc_rsp->a_id);
2741 PRINTM(MCMND, "TDLS AID=0x%x\n", aid_info->AID);
2742 }
2743 /** fill the hecap based on hwspec */
2744 if (tdls_ies->flags & TDLS_IE_FLAGS_HECAP) {
2745 he_cap = (IEEEtypes_HECap_t *)tdls_ies->he_cap;
2746 memset(pmadapter, he_cap, 0, sizeof(IEEEtypes_HECap_t));
2747 wlan_fill_he_cap_ie(pmpriv, he_cap, pbss_desc->bss_band);
2748 DBG_HEXDUMP(MCMD_D, "TDLS HE Cap IE", tdls_ies->he_cap,
2749 sizeof(IEEEtypes_Header_t) + he_cap->ieee_hdr.len);
2750 }
2751
2752 if (tdls_ies->flags & TDLS_IE_FLAGS_HEOP) {
2753 he_op = (IEEEtypes_HeOp_t *)tdls_ies->he_op;
2754 memset(pmadapter, he_op, 0, sizeof(IEEEtypes_HeOp_t));
2755 wlan_fill_he_op_ie(pmpriv, he_op);
2756 }
2757 if (sta_ptr) {
2758 memcpy_ext(pmadapter, &sta_ptr->he_op, tdls_ies->he_op,
2759 sizeof(IEEEtypes_HeOp_t), sizeof(IEEEtypes_HeOp_t));
2760 DBG_HEXDUMP(MCMD_D, "TDLS HE Operation IE", tdls_ies->he_op,
2761 sizeof(IEEEtypes_HeOp_t));
2762 }
2763 /** fill the htinfo */
2764 if (tdls_ies->flags & TDLS_IE_FLAGS_HTINFO) {
2765 ht_info = (IEEEtypes_HTInfo_t *)tdls_ies->ht_info;
2766 pbss_desc = &pmpriv->curr_bss_params.bss_descriptor;
2767 ht_info->ieee_hdr.element_id = HT_OPERATION;
2768 ht_info->ieee_hdr.len = sizeof(HTInfo_t);
2769 ht_info->ht_info.pri_chan = pbss_desc->channel;
2770 /* follow AP's channel bandwidth */
2771 if (ISSUPP_CHANWIDTH40(usr_dot_11n_dev_cap) &&
2772 pbss_desc->pht_info &&
2773 ISALLOWED_CHANWIDTH40(
2774 pbss_desc->pht_info->ht_info.field2)) {
2775 ht_info->ht_info.field2 =
2776 pbss_desc->pht_info->ht_info.field2;
2777 } else {
2778 ht_info->ht_info.field2 =
2779 wlan_get_second_channel_offset(
2780 pmpriv, pbss_desc->channel);
2781 }
2782 if (vht_oprat &&
2783 vht_oprat->ieee_hdr.element_id == VHT_OPERATION) {
2784 ht_info->ht_info.field2 =
2785 wlan_get_second_channel_offset(
2786 pmpriv, pbss_desc->channel);
2787 ht_info->ht_info.field2 |= MBIT(2);
2788 }
2789 if (sta_ptr)
2790 memcpy_ext(pmadapter, &sta_ptr->HTInfo,
2791 tdls_ies->ht_info,
2792 sizeof(IEEEtypes_HTInfo_t),
2793 sizeof(IEEEtypes_HTInfo_t));
2794 DBG_HEXDUMP(MCMD_D, "TDLS htinfo", tdls_ies->ht_info,
2795 sizeof(IEEEtypes_HTInfo_t));
2796 }
2797
2798 /** supported channels andl regulatory IE*/
2799 if (pmpriv->host_tdls_cs_support &&
2800 (tdls_ies->flags & TDLS_IE_FLAGS_SUPP_CS_IE) &&
2801 !IS_EXTCAP_TDLS_CHLSWITCHPROHIB(ap_ext_cap)) {
2802 /** supported channels IE*/
2803 pSupp_chan = (IEEEtypes_Generic_t *)tdls_ies->supp_chan;
2804 pSupp_chan->ieee_hdr.element_id = SUPPORTED_CHANNELS;
2805 if (pmpriv->chan_supp_len) {
2806 pSupp_chan->ieee_hdr.len = pmpriv->chan_supp_len;
2807 memcpy_ext(pmadapter, pSupp_chan->data,
2808 pmpriv->chan_supp, pmpriv->chan_supp_len,
2809 sizeof(pSupp_chan->data));
2810 } else {
2811 pSupp_chan->ieee_hdr.len = sizeof(supp_chan);
2812 memcpy_ext(pmadapter, pSupp_chan->data, supp_chan,
2813 sizeof(supp_chan), sizeof(pSupp_chan->data));
2814 }
2815 DBG_HEXDUMP(
2816 MCMD_D, "TDLS supported channel", tdls_ies->supp_chan,
2817 pSupp_chan->ieee_hdr.len + sizeof(IEEEtypes_Header_t));
2818
2819 /**fill supported Regulatory Class IE*/
2820 pRegulatory_class =
2821 (IEEEtypes_Generic_t *)tdls_ies->regulatory_class;
2822 pRegulatory_class->ieee_hdr.element_id = REGULATORY_CLASS;
2823 if (pmpriv->supp_regulatory_class_len) {
2824 pRegulatory_class->ieee_hdr.len =
2825 pmpriv->supp_regulatory_class_len;
2826 memcpy_ext(pmadapter, pRegulatory_class->data,
2827 pmpriv->supp_regulatory_class,
2828 pmpriv->supp_regulatory_class_len,
2829 sizeof(pRegulatory_class->data));
2830 } else {
2831 pRegulatory_class->ieee_hdr.len =
2832 sizeof(regulatory_class);
2833 memcpy_ext(pmadapter, pRegulatory_class->data,
2834 regulatory_class, sizeof(regulatory_class),
2835 sizeof(pRegulatory_class->data));
2836 }
2837 DBG_HEXDUMP(MCMD_D, "TDLS supported regulatory class",
2838 tdls_ies->regulatory_class,
2839 pRegulatory_class->ieee_hdr.len +
2840 sizeof(IEEEtypes_Header_t));
2841 }
2842 LEAVE();
2843 return ret;
2844 }
2845
2846 /**
2847 * @brief Set mimo switch configuration
2848 *
2849 * @param pmadapter A pointer to mlan_adapter structure
2850 * @param pioctl_req A pointer to ioctl request buffer
2851 *
2852 * @return MLAN_STATUS_PENDING --success, otherwise fail
2853 */
wlan_radio_ioctl_mimo_switch_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)2854 mlan_status wlan_radio_ioctl_mimo_switch_cfg(pmlan_adapter pmadapter,
2855 pmlan_ioctl_req pioctl_req)
2856 {
2857 pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
2858 mlan_ds_radio_cfg *radio_cfg = (mlan_ds_radio_cfg *)pioctl_req->pbuf;
2859 mlan_status ret = MLAN_STATUS_SUCCESS;
2860
2861 ENTER();
2862
2863 /* Send request to firmware */
2864 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_MIMO_SWITCH, 0, 0,
2865 (t_void *)pioctl_req,
2866 &(radio_cfg->param.mimo_switch_cfg));
2867
2868 if (ret == MLAN_STATUS_SUCCESS)
2869 ret = MLAN_STATUS_PENDING;
2870
2871 LEAVE();
2872 return ret;
2873 }
2874
2875 /**
2876 * @brief Get extended version information
2877 *
2878 * @param pmadapter A pointer to mlan_adapter structure
2879 * @param pioctl_req A pointer to ioctl request buffer
2880 *
2881 * @return MLAN_STATUS_PENDING --success, otherwise fail
2882 */
wlan_get_info_ver_ext(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)2883 mlan_status wlan_get_info_ver_ext(pmlan_adapter pmadapter,
2884 pmlan_ioctl_req pioctl_req)
2885 {
2886 pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
2887 mlan_ds_get_info *pinfo = (mlan_ds_get_info *)pioctl_req->pbuf;
2888 mlan_status ret = MLAN_STATUS_SUCCESS;
2889
2890 ENTER();
2891
2892 /* Send request to firmware */
2893 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_VERSION_EXT,
2894 HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
2895 &pinfo->param.ver_ext.version_str_sel);
2896
2897 if (ret == MLAN_STATUS_SUCCESS)
2898 ret = MLAN_STATUS_PENDING;
2899
2900 LEAVE();
2901 return ret;
2902 }
2903
2904 /**
2905 * @brief Set/Get link layer statistics
2906 *
2907 * @param pmadapter A pointer to mlan_adapter structure
2908 * @param pioctl_req A pointer to ioctl request buffer
2909 *
2910 * @return MLAN_STATUS_PENDING --success, otherwise fail
2911 */
wlan_ioctl_link_statistic(mlan_private * pmpriv,pmlan_ioctl_req pioctl_req)2912 mlan_status wlan_ioctl_link_statistic(mlan_private *pmpriv,
2913 pmlan_ioctl_req pioctl_req)
2914 {
2915 mlan_status ret = MLAN_STATUS_SUCCESS;
2916 t_u16 cmd_action = 0;
2917
2918 ENTER();
2919
2920 /* Check buffer length of MLAN IOCTL */
2921 if (pioctl_req->buf_len < sizeof(mlan_ds_get_stats)) {
2922 PRINTM(MWARN,
2923 "MLAN IOCTL information buffer length is too short.\n");
2924 pioctl_req->data_read_written = 0;
2925 pioctl_req->buf_len_needed = sizeof(mlan_ds_get_stats);
2926 pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
2927 ret = MLAN_STATUS_RESOURCE;
2928 goto exit;
2929 }
2930
2931 switch (pioctl_req->action) {
2932 case MLAN_ACT_GET:
2933 cmd_action = HostCmd_ACT_GEN_GET;
2934 break;
2935 case MLAN_ACT_SET:
2936 cmd_action = HostCmd_ACT_GEN_SET;
2937 break;
2938 case MLAN_ACT_CLEAR:
2939 cmd_action = HostCmd_ACT_GEN_REMOVE;
2940 break;
2941 default:
2942 ret = MLAN_STATUS_FAILURE;
2943 goto exit;
2944 }
2945
2946 /* Send request to firmware */
2947 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_LINK_STATS,
2948 cmd_action, 0, (t_void *)pioctl_req, MNULL);
2949
2950 if (ret == MLAN_STATUS_SUCCESS)
2951 ret = MLAN_STATUS_PENDING;
2952
2953 exit:
2954 LEAVE();
2955 return ret;
2956 }
2957
2958 /**
2959 * @brief Get TX/RX histogram statistic
2960 *
2961 * @param pmadapter A pointer to mlan_adapter structure
2962 * @param pioctl_req A pointer to ioctl request buffer
2963 *
2964 * @return MLAN_STATUS_PENDING --success, otherwise fail
2965 */
wlan_get_tx_rx_histogram(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)2966 mlan_status wlan_get_tx_rx_histogram(pmlan_adapter pmadapter,
2967 pmlan_ioctl_req pioctl_req)
2968 {
2969 pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
2970 mlan_ds_misc_cfg *pmisc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
2971 mlan_status ret = MLAN_STATUS_SUCCESS;
2972
2973 ENTER();
2974
2975 /* Send request to firmware */
2976 ret = wlan_prepare_cmd(pmpriv, HOST_CMD_TX_RX_PKT_STATS,
2977 HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
2978 &(pmisc->param.tx_rx_histogram));
2979
2980 if (ret == MLAN_STATUS_SUCCESS)
2981 ret = MLAN_STATUS_PENDING;
2982
2983 LEAVE();
2984 return ret;
2985 }
2986
2987 #ifdef DEBUG_LEVEL1
2988 /**
2989 * @brief Set driver debug bit masks in order to enhance performance
2990 *
2991 * @param pmadapter A pointer to mlan_adapter structure
2992 * @param pioctl_req A pointer to ioctl request buffer
2993 *
2994 * @return MLAN_STATUS_PENDING --success, otherwise fail
2995 */
wlan_set_drvdbg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)2996 mlan_status wlan_set_drvdbg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
2997 {
2998 mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
2999 mlan_status ret = MLAN_STATUS_SUCCESS;
3000
3001 ENTER();
3002
3003 /* Set driver debug bit masks */
3004 mlan_drvdbg = misc->param.drvdbg;
3005
3006 LEAVE();
3007 return ret;
3008 }
3009 #endif
3010
3011 /**
3012 * @brief Rx mgmt frame forward register
3013 *
3014 * @param pmadapter A pointer to mlan_adapter structure
3015 * @param pioctl_req A pointer to ioctl request buffer
3016 *
3017 * @return MLAN_STATUS_PENDING --success, otherwise fail
3018 */
wlan_reg_rx_mgmt_ind(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)3019 mlan_status wlan_reg_rx_mgmt_ind(pmlan_adapter pmadapter,
3020 pmlan_ioctl_req pioctl_req)
3021 {
3022 pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
3023 mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
3024 mlan_status ret = MLAN_STATUS_SUCCESS;
3025
3026 ENTER();
3027
3028 /* Set passthru mask for mgmt frame */
3029 pmpriv->mgmt_frame_passthru_mask = misc->param.mgmt_subtype_mask;
3030
3031 /* Send request to firmware */
3032 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_RX_MGMT_IND,
3033 pioctl_req->action, 0, (t_void *)pioctl_req,
3034 &misc->param.mgmt_subtype_mask);
3035
3036 if (ret == MLAN_STATUS_SUCCESS)
3037 ret = MLAN_STATUS_PENDING;
3038
3039 LEAVE();
3040 return ret;
3041 }
3042
3043 /**
3044 * @brief This function processes the 802.11 mgmt Frame
3045 *
3046 * @param priv A pointer to mlan_private
3047 *
3048 * @param payload A pointer to the received buffer
3049 * @param payload_len Length of the received buffer
3050 * @param prx_pd A pointer to RxPD
3051 *
3052 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
3053 */
wlan_process_802dot11_mgmt_pkt(mlan_private * priv,t_u8 * payload,t_u32 payload_len,RxPD * prx_pd)3054 mlan_status wlan_process_802dot11_mgmt_pkt(mlan_private *priv, t_u8 *payload,
3055 t_u32 payload_len, RxPD *prx_pd)
3056 {
3057 pmlan_adapter pmadapter = priv->adapter;
3058 pmlan_callbacks pcb = &pmadapter->callbacks;
3059 mlan_status ret = MLAN_STATUS_SUCCESS;
3060 wlan_802_11_header *pieee_pkt_hdr = MNULL;
3061 t_u16 sub_type = 0;
3062 t_u8 *event_buf = MNULL;
3063 mlan_event *pevent = MNULL;
3064 t_u8 unicast = 0;
3065 t_u8 broadcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3066 IEEE80211_MGMT *mgmt = MNULL;
3067 t_u8 category = 0;
3068 t_u8 action_code = 0;
3069 #ifdef UAP_SUPPORT
3070 sta_node *sta_ptr = MNULL;
3071 MrvlIETypes_MgmtFrameSet_t *tlv;
3072 pmlan_buffer pmbuf;
3073 #endif
3074
3075 ENTER();
3076 if (payload_len > (MAX_EVENT_SIZE - sizeof(mlan_event))) {
3077 PRINTM(MERROR, "Dropping large mgmt frame,len =%d\n",
3078 payload_len);
3079 LEAVE();
3080 return ret;
3081 }
3082 /* Check packet type-subtype and compare with mgmt_passthru_mask
3083 * If event is needed to host, just eventify it */
3084 pieee_pkt_hdr = (wlan_802_11_header *)payload;
3085 sub_type = IEEE80211_GET_FC_MGMT_FRAME_SUBTYPE(pieee_pkt_hdr->frm_ctl);
3086 if (((1 << sub_type) & priv->mgmt_frame_passthru_mask) == 0) {
3087 PRINTM(MINFO, "Dropping mgmt frame for subtype %d snr=%d.\n",
3088 sub_type, prx_pd->snr);
3089 LEAVE();
3090 return ret;
3091 }
3092 switch (sub_type) {
3093 case SUBTYPE_ASSOC_REQUEST:
3094 case SUBTYPE_REASSOC_REQUEST:
3095 #ifdef UAP_SUPPORT
3096 if (priv->uap_host_based & UAP_FLAG_HOST_MLME) {
3097 PRINTM_NETINTF(MMSG, priv);
3098 if (!memcmp(pmadapter, pieee_pkt_hdr->addr3,
3099 priv->curr_addr, MLAN_MAC_ADDR_LENGTH)) {
3100 PRINTM(MMSG,
3101 "wlan: HostMlme MICRO_AP_STA_ASSOC " MACSTR
3102 "\n",
3103 MAC2STR(pieee_pkt_hdr->addr2));
3104 mgmt = (IEEE80211_MGMT *)payload;
3105 sta_ptr = wlan_add_station_entry(
3106 priv, pieee_pkt_hdr->addr2);
3107 if (sta_ptr) {
3108 sta_ptr->capability = wlan_le16_to_cpu(
3109 mgmt->u.assoc_req.capab_info);
3110 pmbuf = wlan_alloc_mlan_buffer(
3111 pmadapter, payload_len, 0,
3112 MOAL_MALLOC_BUFFER);
3113 if (pmbuf) {
3114 PRINTM(MCMND,
3115 "check sta capability\n");
3116 pmbuf->data_len =
3117 ASSOC_EVENT_FIX_SIZE;
3118 tlv = (MrvlIETypes_MgmtFrameSet_t
3119 *)(pmbuf->pbuf +
3120 pmbuf->data_offset +
3121 pmbuf->data_len);
3122 tlv->type = wlan_cpu_to_le16(
3123 TLV_TYPE_MGMT_FRAME);
3124 tlv->len = sizeof(
3125 IEEEtypes_FrameCtl_t);
3126 memcpy_ext(
3127 pmadapter,
3128 (t_u8 *)&tlv
3129 ->frame_control,
3130 &pieee_pkt_hdr->frm_ctl,
3131 sizeof(IEEEtypes_FrameCtl_t),
3132 sizeof(IEEEtypes_FrameCtl_t));
3133 pmbuf->data_len += sizeof(
3134 MrvlIETypes_MgmtFrameSet_t);
3135 memcpy_ext(
3136 pmadapter,
3137 pmbuf->pbuf +
3138 pmbuf->data_offset +
3139 pmbuf->data_len,
3140 payload +
3141 sizeof(wlan_802_11_header),
3142 payload_len -
3143 sizeof(wlan_802_11_header),
3144 payload_len -
3145 sizeof(wlan_802_11_header));
3146 pmbuf->data_len +=
3147 payload_len -
3148 sizeof(wlan_802_11_header);
3149 tlv->len +=
3150 payload_len -
3151 sizeof(wlan_802_11_header);
3152 tlv->len = wlan_cpu_to_le16(
3153 tlv->len);
3154 DBG_HEXDUMP(
3155 MCMD_D, "assoc_req",
3156 pmbuf->pbuf +
3157 pmbuf->data_offset,
3158 pmbuf->data_len);
3159 wlan_check_sta_capability(
3160 priv, pmbuf, sta_ptr);
3161 wlan_free_mlan_buffer(pmadapter,
3162 pmbuf);
3163 }
3164 }
3165 } else {
3166 PRINTM(MMSG,
3167 "wlan: Drop MICRO_AP_STA_ASSOC " MACSTR
3168 " from unknown BSSID " MACSTR "\n",
3169 MAC2STR(pieee_pkt_hdr->addr2),
3170 MAC2STR(pieee_pkt_hdr->addr3));
3171 }
3172 }
3173 unicast = MTRUE;
3174 break;
3175 #endif
3176 case SUBTYPE_AUTH:
3177 unicast = MTRUE;
3178 PRINTM_NETINTF(MMSG, priv);
3179 PRINTM(MMSG, "wlan: HostMlme Auth received from " MACSTR "\n",
3180 MAC2STR(pieee_pkt_hdr->addr2));
3181 break;
3182 case SUBTYPE_PROBE_RESP:
3183 unicast = MTRUE;
3184 break;
3185 case SUBTYPE_DISASSOC:
3186 case SUBTYPE_DEAUTH:
3187 if (memcmp(pmadapter, pieee_pkt_hdr->addr1, broadcast,
3188 MLAN_MAC_ADDR_LENGTH))
3189 unicast = MTRUE;
3190 #ifdef UAP_SUPPORT
3191 if (priv->uap_host_based & UAP_FLAG_HOST_MLME) {
3192 if (!memcmp(pmadapter, pieee_pkt_hdr->addr3,
3193 priv->curr_addr, MLAN_MAC_ADDR_LENGTH)) {
3194 PRINTM_NETINTF(MMSG, priv);
3195 PRINTM(MMSG,
3196 "wlan: HostMlme Deauth Receive from " MACSTR
3197 "\n",
3198 MAC2STR(pieee_pkt_hdr->addr2));
3199 }
3200 }
3201 #endif
3202 if (priv->bss_role == MLAN_BSS_ROLE_STA) {
3203 if (priv->curr_bss_params.host_mlme) {
3204 if (memcmp(pmadapter, pieee_pkt_hdr->addr3,
3205 (t_u8 *)priv->curr_bss_params
3206 .bss_descriptor.mac_address,
3207 MLAN_MAC_ADDR_LENGTH)) {
3208 PRINTM(MCMND,
3209 "Dropping Deauth frame from other bssid: type=%d " MACSTR
3210 "\n",
3211 sub_type,
3212 MAC2STR(pieee_pkt_hdr->addr3));
3213 LEAVE();
3214 return ret;
3215 }
3216 PRINTM_NETINTF(MMSG, priv);
3217 PRINTM(MMSG,
3218 "wlan: HostMlme Disconnected: sub_type=%d\n",
3219 sub_type);
3220 pmadapter->pending_disconnect_priv = priv;
3221 wlan_recv_event(
3222 priv, MLAN_EVENT_ID_DRV_DEFER_HANDLING,
3223 MNULL);
3224 }
3225 }
3226 break;
3227 case SUBTYPE_ACTION:
3228 category = *(payload + sizeof(wlan_802_11_header));
3229 action_code = *(payload + sizeof(wlan_802_11_header) + 1);
3230 if (category == IEEE_MGMT_ACTION_CATEGORY_BLOCK_ACK) {
3231 PRINTM(MINFO,
3232 "Drop BLOCK ACK action frame: action_code=%d\n",
3233 action_code);
3234 LEAVE();
3235 return ret;
3236 }
3237 if ((category == IEEE_MGMT_ACTION_CATEGORY_PUBLIC) &&
3238 (action_code == BSS_20_40_COEX)) {
3239 PRINTM(MINFO,
3240 "Drop 20/40 BSS Coexistence Management frame\n");
3241 LEAVE();
3242 return ret;
3243 }
3244 if ((category == CATEGORY_PUBLIC) &&
3245 (action_code == TDLS_DISCOVERY_RESPONSE)) {
3246 pcb->moal_updata_peer_signal(pmadapter->pmoal_handle,
3247 priv->bss_index,
3248 pieee_pkt_hdr->addr2,
3249 prx_pd->snr, prx_pd->nf);
3250 PRINTM(MINFO,
3251 "Rx: TDLS discovery response, nf=%d, snr=%d\n",
3252 prx_pd->nf, prx_pd->snr);
3253 }
3254 if (memcmp(pmadapter, pieee_pkt_hdr->addr1, broadcast,
3255 MLAN_MAC_ADDR_LENGTH))
3256 unicast = MTRUE;
3257 break;
3258 default:
3259 break;
3260 }
3261 if (unicast == MTRUE) {
3262 if (memcmp(pmadapter, pieee_pkt_hdr->addr1, priv->curr_addr,
3263 MLAN_MAC_ADDR_LENGTH)) {
3264 PRINTM(MINFO,
3265 "Dropping mgmt frame for others: type=%d " MACSTR
3266 "\n",
3267 sub_type, MAC2STR(pieee_pkt_hdr->addr1));
3268 LEAVE();
3269 return ret;
3270 }
3271 }
3272 /* Allocate memory for event buffer */
3273 ret = pcb->moal_malloc(pmadapter->pmoal_handle, MAX_EVENT_SIZE,
3274 MLAN_MEM_DEF, &event_buf);
3275 if ((ret != MLAN_STATUS_SUCCESS) || !event_buf) {
3276 PRINTM(MERROR, "Could not allocate buffer for event buf\n");
3277 LEAVE();
3278 return MLAN_STATUS_FAILURE;
3279 }
3280 pevent = (pmlan_event)event_buf;
3281 pevent->bss_index = priv->bss_index;
3282 mgmt = (IEEE80211_MGMT *)payload;
3283 if (!priv->curr_bss_params.host_mlme && sub_type == SUBTYPE_ACTION &&
3284 mgmt->u.ft_resp.category == FT_CATEGORY &&
3285 mgmt->u.ft_resp.action == FT_ACTION_RESPONSE &&
3286 mgmt->u.ft_resp.status_code == 0) {
3287 PRINTM(MCMND, "FT Action response received\n");
3288 #define FT_ACTION_HEAD_LEN (24 + 6 + 16)
3289 pevent->event_id = MLAN_EVENT_ID_DRV_FT_RESPONSE;
3290 pevent->event_len =
3291 payload_len + MLAN_MAC_ADDR_LENGTH - FT_ACTION_HEAD_LEN;
3292 memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
3293 &mgmt->u.ft_resp.target_ap_addr,
3294 MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
3295 memcpy_ext(pmadapter,
3296 (t_u8 *)(pevent->event_buf + MLAN_MAC_ADDR_LENGTH),
3297 payload + FT_ACTION_HEAD_LEN,
3298 payload_len - FT_ACTION_HEAD_LEN,
3299 pevent->event_len - MLAN_MAC_ADDR_LENGTH);
3300 } else if (!priv->curr_bss_params.host_mlme &&
3301 sub_type == SUBTYPE_AUTH &&
3302 mgmt->u.auth.auth_alg == MLAN_AUTH_MODE_FT &&
3303 mgmt->u.auth.auth_transaction == 2 &&
3304 mgmt->u.auth.status_code == 0) {
3305 PRINTM(MCMND, "FT auth response received \n");
3306 #define AUTH_PACKET_LEN (24 + 6 + 6)
3307 pevent->event_id = MLAN_EVENT_ID_DRV_FT_RESPONSE;
3308 pevent->event_len =
3309 payload_len + MLAN_MAC_ADDR_LENGTH - AUTH_PACKET_LEN;
3310 memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf, mgmt->sa,
3311 MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
3312 memcpy_ext(pmadapter,
3313 (t_u8 *)(pevent->event_buf + MLAN_MAC_ADDR_LENGTH),
3314 payload + AUTH_PACKET_LEN,
3315 payload_len - AUTH_PACKET_LEN,
3316 pevent->event_len - MLAN_MAC_ADDR_LENGTH);
3317 } else {
3318 pevent->event_id = MLAN_EVENT_ID_DRV_MGMT_FRAME;
3319 pevent->event_len = payload_len + sizeof(pevent->event_id);
3320 memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
3321 (t_u8 *)&pevent->event_id, sizeof(pevent->event_id),
3322 pevent->event_len);
3323 memcpy_ext(
3324 pmadapter,
3325 (t_u8 *)(pevent->event_buf + sizeof(pevent->event_id)),
3326 payload, payload_len, payload_len);
3327 }
3328 wlan_recv_event(priv, pevent->event_id, pevent);
3329 if (event_buf)
3330 pcb->moal_mfree(pmadapter->pmoal_handle, event_buf);
3331 LEAVE();
3332 return MLAN_STATUS_SUCCESS;
3333 }
3334
3335 #ifdef STA_SUPPORT
3336 /**
3337 * @brief Extended capabilities configuration
3338 *
3339 * @param pmadapter A pointer to mlan_adapter structure
3340 * @param pioctl_req A pointer to ioctl request buffer
3341 *
3342 * @return MLAN_STATUS_PENDING --success, otherwise fail
3343 */
wlan_misc_ext_capa_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)3344 mlan_status wlan_misc_ext_capa_cfg(pmlan_adapter pmadapter,
3345 pmlan_ioctl_req pioctl_req)
3346 {
3347 pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
3348 mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
3349 mlan_status ret = MLAN_STATUS_SUCCESS;
3350
3351 ENTER();
3352
3353 if (MLAN_ACT_GET == pioctl_req->action)
3354 memcpy_ext(pmpriv->adapter, &misc->param.ext_cap,
3355 &pmpriv->def_ext_cap, sizeof(misc->param.ext_cap),
3356 sizeof(misc->param.ext_cap));
3357 else if (MLAN_ACT_SET == pioctl_req->action) {
3358 memcpy_ext(pmpriv->adapter, &pmpriv->ext_cap,
3359 &misc->param.ext_cap, sizeof(misc->param.ext_cap),
3360 sizeof(pmpriv->ext_cap));
3361 /* Save default Extended Capability */
3362 memcpy_ext(pmpriv->adapter, &pmpriv->def_ext_cap,
3363 &pmpriv->ext_cap, sizeof(pmpriv->ext_cap),
3364 sizeof(pmpriv->def_ext_cap));
3365 if (pmpriv->config_bands & BAND_AAC)
3366 SET_EXTCAP_OPERMODENTF(pmpriv->ext_cap);
3367 }
3368
3369 LEAVE();
3370 return ret;
3371 }
3372
3373 /**
3374 * @brief Check whether Extended Capabilities IE support
3375 *
3376 * @param pmpriv A pointer to mlan_private structure
3377 *
3378 * @return MTRUE or MFALSE;
3379 */
wlan_is_ext_capa_support(mlan_private * pmpriv)3380 t_u32 wlan_is_ext_capa_support(mlan_private *pmpriv)
3381 {
3382 ENTER();
3383
3384 if (ISSUPP_EXTCAP_TDLS(pmpriv->ext_cap) ||
3385 ISSUPP_EXTCAP_INTERWORKING(pmpriv->ext_cap) ||
3386 ISSUPP_EXTCAP_BSS_TRANSITION(pmpriv->ext_cap) ||
3387 ISSUPP_EXTCAP_QOS_MAP(pmpriv->ext_cap) ||
3388 ISSUPP_EXTCAP_OPERMODENTF(pmpriv->ext_cap)) {
3389 LEAVE();
3390 return MTRUE;
3391 } else {
3392 LEAVE();
3393 return MFALSE;
3394 }
3395 }
3396 #endif
3397
3398 /**
3399 * @brief Set hotspot enable/disable
3400 *
3401 * @param pmadapter A pointer to mlan_adapter structure
3402 * @param pioctl_req A pointer to ioctl request buffer
3403 *
3404 * @return MLAN_STATUS_PENDING --success, otherwise fail
3405 */
wlan_misc_hotspot_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)3406 mlan_status wlan_misc_hotspot_cfg(pmlan_adapter pmadapter,
3407 pmlan_ioctl_req pioctl_req)
3408 {
3409 pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
3410 mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
3411 mlan_status ret = MLAN_STATUS_SUCCESS;
3412
3413 ENTER();
3414
3415 if (MLAN_ACT_GET == pioctl_req->action)
3416 misc->param.hotspot_cfg = pmpriv->hotspot_cfg;
3417 else if (MLAN_ACT_SET == pioctl_req->action)
3418 pmpriv->hotspot_cfg = misc->param.hotspot_cfg;
3419
3420 LEAVE();
3421 return ret;
3422 }
3423
3424 #ifdef STA_SUPPORT
3425 /**
3426 * @brief Add Extended Capabilities IE
3427 *
3428 * @param pmpriv A pointer to mlan_private structure
3429 * @param pbss_desc A pointer to BSSDescriptor_t structure
3430 * @param pptlv_out A pointer to TLV to fill in
3431 *
3432 * @return N/A
3433 */
wlan_add_ext_capa_info_ie(mlan_private * pmpriv,BSSDescriptor_t * pbss_desc,t_u8 ** pptlv_out)3434 void wlan_add_ext_capa_info_ie(mlan_private *pmpriv, BSSDescriptor_t *pbss_desc,
3435 t_u8 **pptlv_out)
3436 {
3437 MrvlIETypes_ExtCap_t *pext_cap = MNULL;
3438
3439 ENTER();
3440
3441 pext_cap = (MrvlIETypes_ExtCap_t *)*pptlv_out;
3442 memset(pmpriv->adapter, pext_cap, 0, sizeof(MrvlIETypes_ExtCap_t));
3443 pext_cap->header.type = wlan_cpu_to_le16(EXT_CAPABILITY);
3444 pext_cap->header.len = wlan_cpu_to_le16(sizeof(ExtCap_t));
3445 if (pmpriv->adapter->ecsa_enable)
3446 SET_EXTCAP_EXT_CHANNEL_SWITCH(pmpriv->ext_cap);
3447 else
3448 RESET_EXTCAP_EXT_CHANNEL_SWITCH(pmpriv->ext_cap);
3449 if (pbss_desc && pbss_desc->multi_bssid_ap)
3450 SET_EXTCAP_MULTI_BSSID(pmpriv->ext_cap);
3451 if (wlan_check_11ax_twt_supported(pmpriv, pbss_desc))
3452 SET_EXTCAP_TWT_REQ(pmpriv->ext_cap);
3453 memcpy_ext(pmpriv->adapter, &pext_cap->ext_cap, &pmpriv->ext_cap,
3454 sizeof(pmpriv->ext_cap), sizeof(pext_cap->ext_cap));
3455 *pptlv_out += sizeof(MrvlIETypes_ExtCap_t);
3456
3457 LEAVE();
3458 }
3459 #endif
3460
3461 /**
3462 * @brief Get OTP user data
3463 *
3464 * @param pmadapter A pointer to mlan_adapter structure
3465 * @param pioctl_req A pointer to ioctl request buffer
3466 *
3467 * @return MLAN_STATUS_PENDING --success, otherwise fail
3468 */
wlan_misc_otp_user_data(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)3469 mlan_status wlan_misc_otp_user_data(pmlan_adapter pmadapter,
3470 pmlan_ioctl_req pioctl_req)
3471 {
3472 pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
3473 mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
3474 mlan_status ret = MLAN_STATUS_FAILURE;
3475
3476 ENTER();
3477
3478 if (misc->param.otp_user_data.user_data_length >
3479 MAX_OTP_USER_DATA_LEN) {
3480 PRINTM(MERROR, "Invalid OTP user data length\n");
3481 pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
3482 LEAVE();
3483 return ret;
3484 }
3485
3486 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_OTP_READ_USER_DATA,
3487 HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
3488 &misc->param.otp_user_data);
3489
3490 if (ret == MLAN_STATUS_SUCCESS)
3491 ret = MLAN_STATUS_PENDING;
3492
3493 LEAVE();
3494 return ret;
3495 }
3496
3497 #ifdef UAP_SUPPORT
3498 /**
3499 * @brief Check 11B support Rates
3500 *
3501 *
3502 * @param pmadapter Private mlan adapter structure
3503 *
3504 * @return MTRUE/MFALSE
3505 *
3506 */
wlan_check_ie_11b_support_rates(pIEEEtypes_Generic_t prates)3507 static t_u8 wlan_check_ie_11b_support_rates(pIEEEtypes_Generic_t prates)
3508 {
3509 int i;
3510 t_u8 rate;
3511 t_u8 ret = MTRUE;
3512 for (i = 0; i < prates->ieee_hdr.len; i++) {
3513 rate = prates->data[i] & 0x7f;
3514 if ((rate != 0x02) && (rate != 0x04) && (rate != 0x0b) &&
3515 (rate != 0x16)) {
3516 ret = MFALSE;
3517 break;
3518 }
3519 }
3520 return ret;
3521 }
3522 #endif
3523
3524 /**
3525 * @brief This function will search for the specific ie
3526 *
3527 * @param priv A pointer to mlan_private
3528 * @param pevent A pointer to event buf
3529 * @param sta_ptr A pointer to sta_node
3530 *
3531 * @return N/A
3532 */
wlan_check_sta_capability(pmlan_private priv,pmlan_buffer pevent,sta_node * sta_ptr)3533 void wlan_check_sta_capability(pmlan_private priv, pmlan_buffer pevent,
3534 sta_node *sta_ptr)
3535 {
3536 t_u16 tlv_type, tlv_len;
3537 t_u16 frame_control, frame_sub_type = 0;
3538 t_u8 *assoc_req_ie = MNULL;
3539 t_u8 ie_len = 0, assoc_ie_len = 0;
3540 IEEEtypes_HTCap_t *pht_cap = MNULL;
3541 IEEEtypes_VHTCap_t *pvht_cap = MNULL;
3542 IEEEtypes_Extension_t *phe_cap = MNULL;
3543 #ifdef UAP_SUPPORT
3544 t_u8 *rate = MNULL;
3545 t_u8 b_only = MFALSE;
3546 #endif
3547
3548 int tlv_buf_left = pevent->data_len - ASSOC_EVENT_FIX_SIZE;
3549 MrvlIEtypesHeader_t *tlv =
3550 (MrvlIEtypesHeader_t *)(pevent->pbuf + pevent->data_offset +
3551 ASSOC_EVENT_FIX_SIZE);
3552 MrvlIETypes_MgmtFrameSet_t *mgmt_tlv = MNULL;
3553
3554 ENTER();
3555 while (tlv_buf_left >= (int)sizeof(MrvlIEtypesHeader_t)) {
3556 tlv_type = wlan_le16_to_cpu(tlv->type);
3557 tlv_len = wlan_le16_to_cpu(tlv->len);
3558 if ((sizeof(MrvlIEtypesHeader_t) + tlv_len) >
3559 (unsigned int)tlv_buf_left) {
3560 PRINTM(MERROR, "wrong tlv: tlvLen=%d, tlvBufLeft=%d\n",
3561 tlv_len, tlv_buf_left);
3562 break;
3563 }
3564 if (tlv_type == TLV_TYPE_MGMT_FRAME) {
3565 mgmt_tlv = (MrvlIETypes_MgmtFrameSet_t *)tlv;
3566 memcpy_ext(priv->adapter, &frame_control,
3567 (t_u8 *)&(mgmt_tlv->frame_control),
3568 sizeof(frame_control),
3569 sizeof(frame_control));
3570 frame_sub_type = IEEE80211_GET_FC_MGMT_FRAME_SUBTYPE(
3571 frame_control);
3572 if ((mgmt_tlv->frame_control.type == 0) &&
3573 ((frame_sub_type == SUBTYPE_BEACON)
3574 #ifdef UAP_SUPPORT
3575 || (frame_sub_type == SUBTYPE_ASSOC_REQUEST) ||
3576 (frame_sub_type == SUBTYPE_REASSOC_REQUEST)
3577 #endif
3578 )) {
3579 if (frame_sub_type == SUBTYPE_BEACON)
3580 assoc_ie_len =
3581 sizeof(IEEEtypes_Beacon_t);
3582 #ifdef UAP_SUPPORT
3583 else if (frame_sub_type ==
3584 SUBTYPE_ASSOC_REQUEST)
3585 assoc_ie_len =
3586 sizeof(IEEEtypes_AssocRqst_t);
3587 else if (frame_sub_type ==
3588 SUBTYPE_REASSOC_REQUEST)
3589 assoc_ie_len =
3590 sizeof(IEEEtypes_ReAssocRqst_t);
3591 #endif
3592 ie_len = tlv_len -
3593 sizeof(IEEEtypes_FrameCtl_t) -
3594 assoc_ie_len;
3595 assoc_req_ie =
3596 (t_u8 *)tlv +
3597 sizeof(MrvlIETypes_MgmtFrameSet_t) +
3598 assoc_ie_len;
3599 sta_ptr->is_wmm_enabled =
3600 wlan_is_wmm_ie_present(priv->adapter,
3601 assoc_req_ie,
3602 ie_len);
3603 PRINTM(MCMND, "STA: is_wmm_enabled=%d\n",
3604 sta_ptr->is_wmm_enabled);
3605 pht_cap = (IEEEtypes_HTCap_t *)
3606 wlan_get_specific_ie(priv, assoc_req_ie,
3607 ie_len,
3608 HT_CAPABILITY, 0);
3609 if (pht_cap) {
3610 PRINTM(MCMND, "STA supports 11n\n");
3611 sta_ptr->is_11n_enabled = MTRUE;
3612 memcpy_ext(priv->adapter,
3613 (t_u8 *)&sta_ptr->HTcap,
3614 pht_cap,
3615 sizeof(IEEEtypes_HTCap_t),
3616 sizeof(IEEEtypes_HTCap_t));
3617 if (GETHT_MAXAMSDU(wlan_le16_to_cpu(
3618 pht_cap->ht_cap
3619 .ht_cap_info)))
3620 sta_ptr->max_amsdu =
3621 MLAN_TX_DATA_BUF_SIZE_8K;
3622 else
3623 sta_ptr->max_amsdu =
3624 MLAN_TX_DATA_BUF_SIZE_4K;
3625 } else {
3626 PRINTM(MCMND,
3627 "STA doesn't support 11n\n");
3628 }
3629 pvht_cap = (IEEEtypes_VHTCap_t *)
3630 wlan_get_specific_ie(priv, assoc_req_ie,
3631 ie_len,
3632 VHT_CAPABILITY, 0);
3633 if (pvht_cap &&
3634 (priv->is_11ac_enabled == MTRUE)) {
3635 PRINTM(MCMND, "STA supports 11ac\n");
3636 sta_ptr->is_11ac_enabled = MTRUE;
3637 if (GET_VHTCAP_MAXMPDULEN(wlan_le32_to_cpu(
3638 pvht_cap->vht_cap
3639 .vht_cap_info)) ==
3640 2)
3641 sta_ptr->max_amsdu =
3642 MLAN_TX_DATA_BUF_SIZE_12K;
3643 else if (GET_VHTCAP_MAXMPDULEN(wlan_le32_to_cpu(
3644 pvht_cap->vht_cap
3645 .vht_cap_info)) ==
3646 1)
3647 sta_ptr->max_amsdu =
3648 MLAN_TX_DATA_BUF_SIZE_8K;
3649 else
3650 sta_ptr->max_amsdu =
3651 MLAN_TX_DATA_BUF_SIZE_4K;
3652 } else {
3653 PRINTM(MCMND,
3654 "STA doesn't support 11ac\n");
3655 }
3656 phe_cap = (IEEEtypes_Extension_t *)
3657 wlan_get_specific_ie(priv, assoc_req_ie,
3658 ie_len, EXTENSION,
3659 HE_CAPABILITY);
3660 if (phe_cap &&
3661 (priv->is_11ax_enabled == MTRUE)) {
3662 PRINTM(MCMND, "STA supports 11ax\n");
3663 sta_ptr->is_11ax_enabled = MTRUE;
3664 memcpy_ext(
3665 priv->adapter,
3666 (t_u8 *)&sta_ptr->he_cap,
3667 phe_cap,
3668 phe_cap->ieee_hdr.len +
3669 sizeof(IEEEtypes_Header_t),
3670 sizeof(IEEEtypes_HECap_t));
3671 sta_ptr->he_cap.ieee_hdr.len = MIN(
3672 phe_cap->ieee_hdr.len,
3673 sizeof(IEEEtypes_HECap_t) -
3674 sizeof(IEEEtypes_Header_t));
3675 } else {
3676 PRINTM(MCMND,
3677 "STA doesn't support 11ax\n");
3678 }
3679 #ifdef UAP_SUPPORT
3680 /* Note: iphone6 does not have ERP_INFO */
3681 rate = wlan_get_specific_ie(priv, assoc_req_ie,
3682 ie_len,
3683 SUPPORTED_RATES, 0);
3684 if (rate)
3685 b_only = wlan_check_ie_11b_support_rates(
3686 (pIEEEtypes_Generic_t)rate);
3687 if (sta_ptr->is_11ax_enabled) {
3688 if (priv->uap_channel <= 14)
3689 sta_ptr->bandmode = BAND_GAX;
3690 else
3691 sta_ptr->bandmode = BAND_AAX;
3692 } else if (sta_ptr->is_11ac_enabled) {
3693 if (priv->uap_channel <= 14)
3694 sta_ptr->bandmode = BAND_GAC;
3695 else
3696 sta_ptr->bandmode = BAND_AAC;
3697 } else if (sta_ptr->is_11n_enabled) {
3698 if (priv->uap_channel <= 14)
3699 sta_ptr->bandmode = BAND_GN;
3700 else
3701 sta_ptr->bandmode = BAND_AN;
3702 } else if (priv->uap_channel <= 14) {
3703 if (b_only)
3704 sta_ptr->bandmode = BAND_B;
3705 else
3706 sta_ptr->bandmode = BAND_G;
3707 } else
3708 sta_ptr->bandmode = BAND_A;
3709 #endif
3710 #ifdef DRV_EMBEDDED_AUTHENTICATOR
3711 if (IsAuthenticatorEnabled(priv->psapriv))
3712 authenticator_get_sta_security_info(
3713 priv->psapriv,
3714 sta_ptr->cm_connectioninfo,
3715 assoc_req_ie, ie_len);
3716 #endif
3717 break;
3718 }
3719 }
3720 tlv_buf_left -= (sizeof(MrvlIEtypesHeader_t) + tlv_len);
3721 tlv = (MrvlIEtypesHeader_t *)((t_u8 *)tlv + tlv_len +
3722 sizeof(MrvlIEtypesHeader_t));
3723 }
3724 LEAVE();
3725
3726 return;
3727 }
3728
3729 /**
3730 * @brief check if WMM ie present.
3731 *
3732 * @param pmadapter A pointer to mlan_adapter structure
3733 * @param pbuf A pointer to IE buffer
3734 * @param buf_len IE buffer len
3735 *
3736 * @return MTRUE/MFALSE
3737 */
wlan_is_wmm_ie_present(pmlan_adapter pmadapter,t_u8 * pbuf,t_u16 buf_len)3738 t_u8 wlan_is_wmm_ie_present(pmlan_adapter pmadapter, t_u8 *pbuf, t_u16 buf_len)
3739 {
3740 t_u16 bytes_left = buf_len;
3741 IEEEtypes_ElementId_e element_id;
3742 t_u8 *pcurrent_ptr = pbuf;
3743 t_u8 element_len;
3744 t_u16 total_ie_len;
3745 IEEEtypes_VendorSpecific_t *pvendor_ie;
3746 const t_u8 wmm_oui[4] = {0x00, 0x50, 0xf2, 0x02};
3747 t_u8 find_wmm_ie = MFALSE;
3748
3749 ENTER();
3750
3751 /* Process variable IE */
3752 while (bytes_left >= 2) {
3753 element_id = (IEEEtypes_ElementId_e)(*((t_u8 *)pcurrent_ptr));
3754 element_len = *((t_u8 *)pcurrent_ptr + 1);
3755 total_ie_len = element_len + sizeof(IEEEtypes_Header_t);
3756
3757 if (bytes_left < total_ie_len) {
3758 PRINTM(MERROR, "InterpretIE: Error in processing IE, "
3759 "bytes left < IE length\n");
3760 bytes_left = 0;
3761 continue;
3762 }
3763 switch (element_id) {
3764 case VENDOR_SPECIFIC_221:
3765 pvendor_ie = (IEEEtypes_VendorSpecific_t *)pcurrent_ptr;
3766 if (!memcmp(pmadapter, pvendor_ie->vend_hdr.oui,
3767 wmm_oui, sizeof(wmm_oui))) {
3768 find_wmm_ie = MTRUE;
3769 PRINTM(MINFO, "find WMM IE\n");
3770 }
3771 break;
3772 default:
3773 break;
3774 }
3775 pcurrent_ptr += element_len + 2;
3776 /* Need to account for IE ID and IE Len */
3777 bytes_left -= (element_len + 2);
3778 if (find_wmm_ie)
3779 break;
3780 }
3781
3782 LEAVE();
3783 return find_wmm_ie;
3784 }
3785
3786 /**
3787 * @brief This function will search for the specific ie
3788 *
3789 *
3790 * @param priv A pointer to mlan_private
3791 * @param ie_buf A pointer to ie_buf
3792 * @param ie_len total ie length
3793 * @param id ie's id
3794 * @param ext_id ie's extension id
3795 *
3796 * @return ie's poiner or MNULL
3797 */
wlan_get_specific_ie(pmlan_private priv,t_u8 * ie_buf,t_u8 ie_len,IEEEtypes_ElementId_e id,t_u8 ext_id)3798 t_u8 *wlan_get_specific_ie(pmlan_private priv, t_u8 *ie_buf, t_u8 ie_len,
3799 IEEEtypes_ElementId_e id, t_u8 ext_id)
3800 {
3801 t_u32 bytes_left = ie_len;
3802 t_u8 *pcurrent_ptr = ie_buf;
3803 t_u16 total_ie_len;
3804 t_u8 *ie_ptr = MNULL;
3805 IEEEtypes_ElementId_e element_id;
3806 t_u8 element_len;
3807 t_u8 element_eid;
3808
3809 ENTER();
3810
3811 DBG_HEXDUMP(MDAT_D, "ie", ie_buf, ie_len);
3812 while (bytes_left >= 2) {
3813 element_id = (IEEEtypes_ElementId_e)(*((t_u8 *)pcurrent_ptr));
3814 element_len = *((t_u8 *)pcurrent_ptr + 1);
3815 element_eid = *((t_u8 *)pcurrent_ptr + 2);
3816 total_ie_len = element_len + sizeof(IEEEtypes_Header_t);
3817 if (bytes_left < total_ie_len) {
3818 PRINTM(MERROR, "InterpretIE: Error in processing IE, "
3819 "bytes left < IE length\n");
3820 break;
3821 }
3822 if ((!ext_id && element_id == id) ||
3823 (id == EXTENSION && element_id == id &&
3824 ext_id == element_eid)) {
3825 PRINTM(MCMND, "Find IE: id=%d ext_id=%d\n", id, ext_id);
3826 DBG_HEXDUMP(MCMD_D, "IE", pcurrent_ptr, total_ie_len);
3827 ie_ptr = pcurrent_ptr;
3828 break;
3829 }
3830 pcurrent_ptr += element_len + 2;
3831 /* Need to account for IE ID and IE Len */
3832 bytes_left -= (element_len + 2);
3833 }
3834
3835 LEAVE();
3836
3837 return ie_ptr;
3838 }
3839
3840 /**
3841 * @brief Get pm info
3842 *
3843 * @param pmadapter A pointer to mlan_adapter structure
3844 * @param pioctl_req A pointer to ioctl request buffer
3845 *
3846 * @return MLAN_STATUS_SUCCESS --success
3847 */
wlan_get_pm_info(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)3848 mlan_status wlan_get_pm_info(pmlan_adapter pmadapter,
3849 pmlan_ioctl_req pioctl_req)
3850 {
3851 mlan_status ret = MLAN_STATUS_SUCCESS;
3852 mlan_ds_pm_cfg *pm_cfg = MNULL;
3853
3854 ENTER();
3855
3856 pm_cfg = (mlan_ds_pm_cfg *)pioctl_req->pbuf;
3857 pm_cfg->param.ps_info.is_suspend_allowed = MTRUE;
3858 wlan_request_cmd_lock(pmadapter);
3859 if (util_peek_list(pmadapter->pmoal_handle, &pmadapter->cmd_pending_q,
3860 MNULL, MNULL) ||
3861 pmadapter->curr_cmd || !wlan_bypass_tx_list_empty(pmadapter) ||
3862 !wlan_wmm_lists_empty(pmadapter)
3863 #if defined(SDIO) || defined(PCIE)
3864 || wlan_pending_interrupt(pmadapter)
3865 #endif
3866 ) {
3867 pm_cfg->param.ps_info.is_suspend_allowed = MFALSE;
3868 #if defined(SDIO) || defined(PCIE)
3869 PRINTM(MIOCTL,
3870 "PM: cmd_pending_q=%p,curr_cmd=%p,wmm_list_empty=%d, by_pass=%d irq_pending=%d\n",
3871 util_peek_list(pmadapter->pmoal_handle,
3872 &pmadapter->cmd_pending_q, MNULL, MNULL),
3873 pmadapter->curr_cmd, wlan_wmm_lists_empty(pmadapter),
3874 wlan_bypass_tx_list_empty(pmadapter),
3875 wlan_pending_interrupt(pmadapter));
3876 #else
3877 PRINTM(MIOCTL,
3878 "PM: cmd_pending_q=%p,curr_cmd=%p,wmm_list_empty=%d, by_pass=%d\n",
3879 util_peek_list(pmadapter->pmoal_handle,
3880 &pmadapter->cmd_pending_q, MNULL, MNULL),
3881 pmadapter->curr_cmd, wlan_wmm_lists_empty(pmadapter),
3882 wlan_bypass_tx_list_empty(pmadapter));
3883 #endif
3884 }
3885 wlan_release_cmd_lock(pmadapter);
3886 LEAVE();
3887 return ret;
3888 }
3889
3890 /**
3891 * @brief Get hs wakeup reason
3892 *
3893 * @param pmadapter A pointer to mlan_adapter structure
3894 * @param pioctl_req A pointer to ioctl request buffer
3895 *
3896 * @return MLAN_STATUS_SUCCESS --success
3897 */
wlan_get_hs_wakeup_reason(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)3898 mlan_status wlan_get_hs_wakeup_reason(pmlan_adapter pmadapter,
3899 pmlan_ioctl_req pioctl_req)
3900 {
3901 pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
3902 pmlan_ds_pm_cfg pm_cfg = MNULL;
3903 mlan_status ret = MLAN_STATUS_FAILURE;
3904
3905 ENTER();
3906
3907 pm_cfg = (mlan_ds_pm_cfg *)pioctl_req->pbuf;
3908
3909 /* Send command to firmware */
3910 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_HS_WAKEUP_REASON,
3911 HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
3912 &pm_cfg->param.wakeup_reason);
3913
3914 if (ret == MLAN_STATUS_SUCCESS)
3915 ret = MLAN_STATUS_PENDING;
3916
3917 LEAVE();
3918 return ret;
3919 }
3920
3921 /**
3922 * @brief Set/Get radio status
3923 *
3924 * @param pmadapter A pointer to mlan_adapter structure
3925 * @param pioctl_req A pointer to ioctl request buffer
3926 *
3927 * @return MLAN_STATUS_SUCCESS --success, otherwise fail
3928 */
wlan_radio_ioctl_radio_ctl(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)3929 mlan_status wlan_radio_ioctl_radio_ctl(pmlan_adapter pmadapter,
3930 pmlan_ioctl_req pioctl_req)
3931 {
3932 mlan_status ret = MLAN_STATUS_SUCCESS;
3933 mlan_ds_radio_cfg *radio_cfg = MNULL;
3934 t_u16 cmd_action = 0;
3935 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
3936
3937 ENTER();
3938
3939 radio_cfg = (mlan_ds_radio_cfg *)pioctl_req->pbuf;
3940 if (pioctl_req->action == MLAN_ACT_SET) {
3941 if (pmadapter->radio_on == radio_cfg->param.radio_on_off) {
3942 ret = MLAN_STATUS_SUCCESS;
3943 goto exit;
3944 } else {
3945 if (pmpriv->media_connected == MTRUE) {
3946 ret = MLAN_STATUS_FAILURE;
3947 goto exit;
3948 }
3949 cmd_action = HostCmd_ACT_GEN_SET;
3950 }
3951 } else
3952 cmd_action = HostCmd_ACT_GEN_GET;
3953
3954 /* Send request to firmware */
3955 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_RADIO_CONTROL,
3956 cmd_action, 0, (t_void *)pioctl_req,
3957 &radio_cfg->param.radio_on_off);
3958
3959 if (ret == MLAN_STATUS_SUCCESS)
3960 ret = MLAN_STATUS_PENDING;
3961
3962 exit:
3963 LEAVE();
3964 return ret;
3965 }
3966
3967 /**
3968 * @brief Set/Get antenna configuration
3969 *
3970 * @param pmadapter A pointer to mlan_adapter structure
3971 * @param pioctl_req A pointer to ioctl request buffer
3972 *
3973 * @return MLAN_STATUS_PENDING --success, otherwise fail
3974 */
wlan_radio_ioctl_ant_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)3975 mlan_status wlan_radio_ioctl_ant_cfg(pmlan_adapter pmadapter,
3976 pmlan_ioctl_req pioctl_req)
3977 {
3978 mlan_status ret = MLAN_STATUS_SUCCESS;
3979 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
3980 mlan_ds_radio_cfg *radio_cfg = MNULL;
3981 t_u16 cmd_action = 0;
3982 mlan_ds_ant_cfg *ant_cfg = MNULL;
3983 mlan_ds_ant_cfg_1x1 *ant_cfg_1x1 = MNULL;
3984
3985 ENTER();
3986
3987 radio_cfg = (mlan_ds_radio_cfg *)pioctl_req->pbuf;
3988 if (IS_STREAM_2X2(pmadapter->feature_control))
3989 ant_cfg = &radio_cfg->param.ant_cfg;
3990
3991 if (pioctl_req->action == MLAN_ACT_SET) {
3992 /* User input validation */
3993 if (IS_STREAM_2X2(pmadapter->feature_control)) {
3994 #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \
3995 defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \
3996 defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X)
3997 if (IS_CARD9098(pmadapter->card_type) ||
3998 IS_CARD9097(pmadapter->card_type) ||
3999 IS_CARDNW62X(pmadapter->card_type)) {
4000 ant_cfg->tx_antenna &= 0x0303;
4001 ant_cfg->rx_antenna &= 0x0303;
4002 /** 2G antcfg TX */
4003 if (ant_cfg->tx_antenna & 0x00FF) {
4004 pmadapter->user_htstream &= ~0xF0;
4005 pmadapter->user_htstream |=
4006 (bitcount(ant_cfg->tx_antenna &
4007 0x00FF)
4008 << 4);
4009 }
4010 /* 5G antcfg tx */
4011 if (ant_cfg->tx_antenna & 0xFF00) {
4012 pmadapter->user_htstream &= ~0xF000;
4013 pmadapter->user_htstream |=
4014 (bitcount(ant_cfg->tx_antenna &
4015 0xFF00)
4016 << 12);
4017 }
4018 /* 2G antcfg RX */
4019 if (ant_cfg->rx_antenna & 0x00FF) {
4020 pmadapter->user_htstream &= ~0xF;
4021 pmadapter->user_htstream |= bitcount(
4022 ant_cfg->rx_antenna & 0x00FF);
4023 }
4024 /* 5G antcfg RX */
4025 if (ant_cfg->rx_antenna & 0xFF00) {
4026 pmadapter->user_htstream &= ~0xF00;
4027 pmadapter->user_htstream |=
4028 (bitcount(ant_cfg->rx_antenna &
4029 0xFF00)
4030 << 8);
4031 }
4032 PRINTM(MCMND,
4033 "user_htstream=0x%x, tx_antenna=0x%x >rx_antenna=0x%x\n",
4034 pmadapter->user_htstream,
4035 ant_cfg->tx_antenna,
4036 ant_cfg->rx_antenna);
4037 } else {
4038 #endif
4039
4040 ant_cfg->tx_antenna &= 0x0003;
4041 ant_cfg->rx_antenna &= 0x0003;
4042 #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \
4043 defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \
4044 defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X)
4045 }
4046 #endif
4047 if (!ant_cfg->tx_antenna ||
4048 bitcount(ant_cfg->tx_antenna & 0x00FF) >
4049 pmadapter->number_of_antenna ||
4050 bitcount(ant_cfg->tx_antenna & 0xFF00) >
4051 pmadapter->number_of_antenna) {
4052 PRINTM(MERROR,
4053 "Invalid TX antenna setting: 0x%x\n",
4054 ant_cfg->tx_antenna);
4055 pioctl_req->status_code =
4056 MLAN_ERROR_INVALID_PARAMETER;
4057 ret = MLAN_STATUS_FAILURE;
4058 goto exit;
4059 }
4060 if (ant_cfg->rx_antenna) {
4061 if (bitcount(ant_cfg->rx_antenna & 0x00FF) >
4062 pmadapter->number_of_antenna ||
4063 bitcount(ant_cfg->rx_antenna & 0xFF00) >
4064 pmadapter->number_of_antenna) {
4065 PRINTM(MERROR,
4066 "Invalid RX antenna setting: 0x%x\n",
4067 ant_cfg->rx_antenna);
4068 pioctl_req->status_code =
4069 MLAN_ERROR_INVALID_PARAMETER;
4070 ret = MLAN_STATUS_FAILURE;
4071 goto exit;
4072 }
4073 } else
4074 ant_cfg->rx_antenna = ant_cfg->tx_antenna;
4075 } else if (!radio_cfg->param.ant_cfg_1x1.antenna ||
4076 ((radio_cfg->param.ant_cfg_1x1.antenna !=
4077 RF_ANTENNA_AUTO) &&
4078 (radio_cfg->param.ant_cfg_1x1.antenna & 0xFFFC))) {
4079 PRINTM(MERROR, "Invalid antenna setting\n");
4080 pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
4081 ret = MLAN_STATUS_FAILURE;
4082 goto exit;
4083 }
4084 cmd_action = HostCmd_ACT_GEN_SET;
4085 } else
4086 cmd_action = HostCmd_ACT_GEN_GET;
4087
4088 /* Cast it to t_u16, antenna mode for command
4089 * HostCmd_CMD_802_11_RF_ANTENNA requires 2 bytes */
4090 if (!IS_STREAM_2X2(pmadapter->feature_control))
4091 ant_cfg_1x1 = &radio_cfg->param.ant_cfg_1x1;
4092
4093 /* Send request to firmware */
4094 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_RF_ANTENNA,
4095 cmd_action, 0, (t_void *)pioctl_req,
4096 (IS_STREAM_2X2(pmadapter->feature_control)) ?
4097 (t_void *)ant_cfg :
4098 (t_void *)ant_cfg_1x1);
4099
4100 if (ret == MLAN_STATUS_SUCCESS)
4101 ret = MLAN_STATUS_PENDING;
4102
4103 exit:
4104 LEAVE();
4105 return ret;
4106 }
4107
4108 /**
4109 * @brief Get rate bitmap
4110 *
4111 * @param pmadapter A pointer to mlan_adapter structure
4112 * @param pioctl_req A pointer to ioctl request buffer
4113 *
4114 * @return MLAN_STATUS_PENDING --success, otherwise fail
4115 */
wlan_rate_ioctl_get_rate_bitmap(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)4116 static mlan_status wlan_rate_ioctl_get_rate_bitmap(pmlan_adapter pmadapter,
4117 pmlan_ioctl_req pioctl_req)
4118 {
4119 mlan_status ret = MLAN_STATUS_SUCCESS;
4120 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
4121
4122 ENTER();
4123
4124 /* Send request to firmware */
4125 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG,
4126 HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
4127 MNULL);
4128 if (ret == MLAN_STATUS_SUCCESS)
4129 ret = MLAN_STATUS_PENDING;
4130
4131 LEAVE();
4132 return ret;
4133 }
4134
4135 /**
4136 * @brief Set rate bitmap
4137 *
4138 * @param pmadapter A pointer to mlan_adapter structure
4139 * @param pioctl_req A pointer to ioctl request buffer
4140 *
4141 * @return MLAN_STATUS_PENDING --success, otherwise fail
4142 */
wlan_rate_ioctl_set_rate_bitmap(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)4143 static mlan_status wlan_rate_ioctl_set_rate_bitmap(pmlan_adapter pmadapter,
4144 pmlan_ioctl_req pioctl_req)
4145 {
4146 mlan_ds_rate *ds_rate = MNULL;
4147 mlan_status ret = MLAN_STATUS_FAILURE;
4148 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
4149 t_u16 *bitmap_rates = MNULL;
4150
4151 ENTER();
4152
4153 ds_rate = (mlan_ds_rate *)pioctl_req->pbuf;
4154 bitmap_rates = ds_rate->param.rate_cfg.bitmap_rates;
4155
4156 PRINTM(MINFO,
4157 "RateBitmap=%04x%04x%04x%04x%04x%04x%04x%04x"
4158 "%04x%04x%04x%04x%04x%04x%04x%04x%04x%04x, "
4159 "IsRateAuto=%d, DataRate=%d\n",
4160 bitmap_rates[17], bitmap_rates[16], bitmap_rates[15],
4161 bitmap_rates[14], bitmap_rates[13], bitmap_rates[12],
4162 bitmap_rates[11], bitmap_rates[10], bitmap_rates[9],
4163 bitmap_rates[8], bitmap_rates[7], bitmap_rates[6],
4164 bitmap_rates[5], bitmap_rates[4], bitmap_rates[3],
4165 bitmap_rates[2], bitmap_rates[1], bitmap_rates[0],
4166 pmpriv->is_data_rate_auto, pmpriv->data_rate);
4167
4168 /* Send request to firmware */
4169 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG,
4170 HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
4171 (t_void *)bitmap_rates);
4172 if (ret == MLAN_STATUS_SUCCESS)
4173 ret = MLAN_STATUS_PENDING;
4174
4175 LEAVE();
4176 return ret;
4177 }
4178
4179 /**
4180 * @brief Get rate value
4181 *
4182 * @param pmadapter A pointer to mlan_adapter structure
4183 * @param pioctl_req A pointer to ioctl request buffer
4184 *
4185 * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
4186 * otherwise fail
4187 */
wlan_rate_ioctl_get_rate_value(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)4188 static mlan_status wlan_rate_ioctl_get_rate_value(pmlan_adapter pmadapter,
4189 pmlan_ioctl_req pioctl_req)
4190 {
4191 mlan_ds_rate *rate = MNULL;
4192 mlan_status ret = MLAN_STATUS_SUCCESS;
4193 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
4194
4195 ENTER();
4196
4197 rate = (mlan_ds_rate *)pioctl_req->pbuf;
4198 rate->param.rate_cfg.is_rate_auto = pmpriv->is_data_rate_auto;
4199 pioctl_req->data_read_written =
4200 sizeof(mlan_rate_cfg_t) + MLAN_SUB_COMMAND_SIZE;
4201
4202 /* If not connected, set rate to the lowest in each band */
4203 if (pmpriv->media_connected != MTRUE) {
4204 if (pmpriv->config_bands & (BAND_B | BAND_G)) {
4205 /* Return the lowest supported rate for BG band */
4206 rate->param.rate_cfg.rate = SupportedRates_BG[0] & 0x7f;
4207 } else if (pmpriv->config_bands & (BAND_A | BAND_B)) {
4208 /* Return the lowest supported rate for A band */
4209 rate->param.rate_cfg.rate = SupportedRates_BG[0] & 0x7f;
4210 } else if (pmpriv->config_bands & BAND_A) {
4211 /* Return the lowest supported rate for A band */
4212 rate->param.rate_cfg.rate = SupportedRates_A[0] & 0x7f;
4213 } else if (pmpriv->config_bands & BAND_G) {
4214 /* Return the lowest supported rate for G band */
4215 rate->param.rate_cfg.rate = SupportedRates_G[0] & 0x7f;
4216 } else if (pmpriv->config_bands & BAND_B) {
4217 /* Return the lowest supported rate for B band */
4218 rate->param.rate_cfg.rate = SupportedRates_B[0] & 0x7f;
4219 } else if (pmpriv->config_bands & BAND_GN) {
4220 /* Return the lowest supported rate for N band */
4221 rate->param.rate_cfg.rate = SupportedRates_N[0] & 0x7f;
4222 } else {
4223 PRINTM(MMSG, "Invalid Band 0x%x\n",
4224 pmpriv->config_bands);
4225 }
4226
4227 } else {
4228 /* Send request to firmware */
4229 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_TX_RATE_QUERY,
4230 HostCmd_ACT_GEN_GET, 0,
4231 (t_void *)pioctl_req, MNULL);
4232 if (ret == MLAN_STATUS_SUCCESS)
4233 ret = MLAN_STATUS_PENDING;
4234 }
4235
4236 LEAVE();
4237 return ret;
4238 }
4239
4240 /**
4241 * @brief Set rate value
4242 *
4243 * @param pmadapter A pointer to mlan_adapter structure
4244 * @param pioctl_req A pointer to ioctl request buffer
4245 *
4246 * @return MLAN_STATUS_PENDING --success, otherwise fail
4247 */
wlan_rate_ioctl_set_rate_value(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)4248 static mlan_status wlan_rate_ioctl_set_rate_value(pmlan_adapter pmadapter,
4249 pmlan_ioctl_req pioctl_req)
4250 {
4251 mlan_ds_rate *ds_rate = MNULL;
4252 WLAN_802_11_RATES rates;
4253 t_u8 *rate = MNULL;
4254 int rate_index = 0;
4255 t_u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
4256 t_u32 i = 0;
4257 mlan_status ret = MLAN_STATUS_SUCCESS;
4258 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
4259
4260 ENTER();
4261
4262 ds_rate = (mlan_ds_rate *)pioctl_req->pbuf;
4263
4264 if (ds_rate->param.rate_cfg.is_rate_auto) {
4265 memset(pmadapter, bitmap_rates, 0, sizeof(bitmap_rates));
4266 /* Support all HR/DSSS rates */
4267 bitmap_rates[0] = 0x000F;
4268 /* Support all OFDM rates */
4269 bitmap_rates[1] = 0x00FF;
4270 /* Rates talbe [0] HR/DSSS,[1] OFDM,[2..9] HT,[10..17] VHT */
4271 /* Support all HT-MCSs rate */
4272 for (i = 0; i < NELEMENTS(pmpriv->bitmap_rates) - 3 - 8; i++)
4273 bitmap_rates[i + 2] = 0xFFFF;
4274 bitmap_rates[9] = 0x3FFF;
4275 /* Support all VHT-MCSs rate */
4276 for (i = 0; i < NELEMENTS(pmpriv->bitmap_rates) - 10; i++)
4277 bitmap_rates[i + 10] = 0x03FF; /* 10 Bits valid */
4278 } else {
4279 memset(pmadapter, rates, 0, sizeof(rates));
4280 wlan_get_active_data_rates(pmpriv, pmpriv->bss_mode,
4281 (pmpriv->bss_mode ==
4282 MLAN_BSS_MODE_INFRA) ?
4283 pmpriv->config_bands :
4284 pmadapter->adhoc_start_band,
4285 rates);
4286 rate = rates;
4287 for (i = 0; (rate[i] && i < WLAN_SUPPORTED_RATES); i++) {
4288 PRINTM(MINFO, "Rate=0x%X Wanted=0x%X\n", rate[i],
4289 ds_rate->param.rate_cfg.rate);
4290 if ((rate[i] & 0x7f) ==
4291 (ds_rate->param.rate_cfg.rate & 0x7f))
4292 break;
4293 }
4294 if ((i < WLAN_SUPPORTED_RATES && !rate[i]) ||
4295 (i == WLAN_SUPPORTED_RATES)) {
4296 PRINTM(MERROR,
4297 "The fixed data rate 0x%X is out "
4298 "of range\n",
4299 ds_rate->param.rate_cfg.rate);
4300 pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
4301 ret = MLAN_STATUS_FAILURE;
4302 goto exit;
4303 }
4304 memset(pmadapter, bitmap_rates, 0, sizeof(bitmap_rates));
4305 rate_index = wlan_data_rate_to_index(
4306 pmadapter, ds_rate->param.rate_cfg.rate);
4307 /* Only allow b/g rates to be set */
4308 if (rate_index >= MLAN_RATE_INDEX_HRDSSS0 &&
4309 rate_index <= MLAN_RATE_INDEX_HRDSSS3)
4310 bitmap_rates[0] = 1 << rate_index;
4311 else {
4312 rate_index -= 1; /* There is a 0x00 in the table */
4313 if (rate_index >= MLAN_RATE_INDEX_OFDM0 &&
4314 rate_index <= MLAN_RATE_INDEX_OFDM7)
4315 bitmap_rates[1] = 1 << (rate_index -
4316 MLAN_RATE_INDEX_OFDM0);
4317 }
4318 }
4319
4320 /* Send request to firmware */
4321 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG,
4322 HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
4323 bitmap_rates);
4324 if (ret == MLAN_STATUS_SUCCESS)
4325 ret = MLAN_STATUS_PENDING;
4326
4327 exit:
4328 LEAVE();
4329 return ret;
4330 }
4331
4332 /**
4333 * @brief Get rate index
4334 *
4335 * @param pmadapter A pointer to mlan_adapter structure
4336 * @param pioctl_req A pointer to ioctl request buffer
4337 *
4338 * @return MLAN_STATUS_PENDING --success, otherwise fail
4339 */
wlan_rate_ioctl_get_rate_index(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)4340 static mlan_status wlan_rate_ioctl_get_rate_index(pmlan_adapter pmadapter,
4341 pmlan_ioctl_req pioctl_req)
4342 {
4343 mlan_status ret = MLAN_STATUS_SUCCESS;
4344 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
4345
4346 ENTER();
4347
4348 /* Send request to firmware */
4349 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG,
4350 HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
4351 MNULL);
4352 if (ret == MLAN_STATUS_SUCCESS)
4353 ret = MLAN_STATUS_PENDING;
4354
4355 LEAVE();
4356 return ret;
4357 }
4358
4359 /**
4360 * @brief Set rate index
4361 *
4362 * @param pmadapter A pointer to mlan_adapter structure
4363 * @param pioctl_req A pointer to ioctl request buffer
4364 *
4365 * @return MLAN_STATUS_PENDING --success, otherwise fail
4366 */
wlan_rate_ioctl_set_rate_index(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)4367 static mlan_status wlan_rate_ioctl_set_rate_index(pmlan_adapter pmadapter,
4368 pmlan_ioctl_req pioctl_req)
4369 {
4370 t_u32 rate_index;
4371 t_u32 rate_format;
4372 t_u32 nss;
4373 t_u32 i;
4374 mlan_ds_rate *ds_rate = MNULL;
4375 mlan_status ret = MLAN_STATUS_FAILURE;
4376 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
4377 t_u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
4378 int tx_mcs_supp = GET_TXMCSSUPP(pmpriv->usr_dev_mcs_support);
4379
4380 ENTER();
4381
4382 ds_rate = (mlan_ds_rate *)pioctl_req->pbuf;
4383 rate_format = ds_rate->param.rate_cfg.rate_format;
4384 nss = ds_rate->param.rate_cfg.nss;
4385 rate_index = ds_rate->param.rate_cfg.rate;
4386
4387 if (ds_rate->param.rate_cfg.is_rate_auto) {
4388 memset(pmadapter, bitmap_rates, 0, sizeof(bitmap_rates));
4389 /* Rates talbe [0]: HR/DSSS;[1]: OFDM; [2..9] HT; */
4390 /* Support all HR/DSSS rates */
4391 bitmap_rates[0] = 0x000F;
4392 /* Support all OFDM rates */
4393 bitmap_rates[1] = 0x00FF;
4394 /* Support all HT-MCSs rate */
4395 for (i = 2; i < 9; i++)
4396 bitmap_rates[i] = 0xFFFF;
4397 bitmap_rates[9] = 0x3FFF;
4398 /* [10..17] VHT */
4399 /* Support all VHT-MCSs rate for NSS 1 and 2 */
4400 for (i = 10; i < 12; i++)
4401 bitmap_rates[i] = 0x03FF; /* 10 Bits valid */
4402 /* Set to 0 as default value for all other NSSs */
4403 for (i = 12; i < 17; i++)
4404 bitmap_rates[i] = 0x0;
4405 /* [18..25] HE */
4406 /* Support all HE-MCSs rate for NSS1 and 2 */
4407 for (i = 18; i < 20; i++)
4408 bitmap_rates[i] = 0x0FFF;
4409 for (i = 20; i < NELEMENTS(bitmap_rates); i++)
4410 bitmap_rates[i] = 0x0;
4411 } else {
4412 PRINTM(MINFO, "Rate index is %d\n", rate_index);
4413 if ((rate_format == MLAN_RATE_FORMAT_HT) &&
4414 (rate_index > MLAN_RATE_INDEX_MCS7 &&
4415 rate_index <= MLAN_RATE_INDEX_MCS15) &&
4416 (tx_mcs_supp < 2)) {
4417 PRINTM(MERROR,
4418 "HW don't support 2x2, rate_index=%d hw_mcs_supp=0x%x\n",
4419 rate_index, pmpriv->usr_dev_mcs_support);
4420 pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
4421 LEAVE();
4422 return MLAN_STATUS_FAILURE;
4423 }
4424 memset(pmadapter, bitmap_rates, 0, sizeof(bitmap_rates));
4425 if (rate_format == MLAN_RATE_FORMAT_LG) {
4426 /* Bitmap of HR/DSSS rates */
4427 if (rate_index <= MLAN_RATE_INDEX_HRDSSS3) {
4428 bitmap_rates[0] = 1 << rate_index;
4429 ret = MLAN_STATUS_SUCCESS;
4430 /* Bitmap of OFDM rates */
4431 } else if ((rate_index >= MLAN_RATE_INDEX_OFDM0) &&
4432 (rate_index <= MLAN_RATE_INDEX_OFDM7)) {
4433 bitmap_rates[1] = 1 << (rate_index -
4434 MLAN_RATE_INDEX_OFDM0);
4435 ret = MLAN_STATUS_SUCCESS;
4436 }
4437 } else if (rate_format == MLAN_RATE_FORMAT_HT) {
4438 if (rate_index <= MLAN_RATE_INDEX_MCS32) {
4439 bitmap_rates[2 + (rate_index / 16)] =
4440 1 << (rate_index % 16);
4441 ret = MLAN_STATUS_SUCCESS;
4442 }
4443 }
4444 if (rate_format == MLAN_RATE_FORMAT_VHT) {
4445 if ((rate_index <= MLAN_RATE_INDEX_MCS9) &&
4446 (MLAN_RATE_NSS1 <= nss) &&
4447 (nss <= MLAN_RATE_NSS2)) {
4448 bitmap_rates[10 + nss - MLAN_RATE_NSS1] =
4449 (1 << rate_index);
4450 ret = MLAN_STATUS_SUCCESS;
4451 }
4452 }
4453 if (rate_format == MLAN_RATE_FORMAT_HE) {
4454 if (IS_FW_SUPPORT_11AX(pmadapter)) {
4455 if ((rate_index <= MLAN_RATE_INDEX_MCS11) &&
4456 (MLAN_RATE_NSS1 <= nss) &&
4457 (nss <= MLAN_RATE_NSS2)) {
4458 bitmap_rates[18 + nss - MLAN_RATE_NSS1] =
4459 (1 << rate_index);
4460 ret = MLAN_STATUS_SUCCESS;
4461 }
4462 } else {
4463 PRINTM(MERROR,
4464 "Error! Fw doesn't support 11AX\n");
4465 LEAVE();
4466 return MLAN_STATUS_FAILURE;
4467 }
4468 }
4469
4470 if (ret == MLAN_STATUS_FAILURE) {
4471 PRINTM(MERROR, "Invalid MCS index=%d. \n", rate_index);
4472 pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
4473 LEAVE();
4474 return MLAN_STATUS_FAILURE;
4475 }
4476 }
4477
4478 PRINTM(MINFO,
4479 "RateBitmap=%04x%04x%04x%04x%04x%04x%04x%04x"
4480 "%04x%04x%04x%04x%04x%04x%04x%04x%04x%04x, "
4481 "IsRateAuto=%d, DataRate=%d\n",
4482 bitmap_rates[17], bitmap_rates[16], bitmap_rates[15],
4483 bitmap_rates[14], bitmap_rates[13], bitmap_rates[12],
4484 bitmap_rates[11], bitmap_rates[10], bitmap_rates[9],
4485 bitmap_rates[8], bitmap_rates[7], bitmap_rates[6],
4486 bitmap_rates[5], bitmap_rates[4], bitmap_rates[3],
4487 bitmap_rates[2], bitmap_rates[1], bitmap_rates[0],
4488 pmpriv->is_data_rate_auto, pmpriv->data_rate);
4489
4490 /* Send request to firmware */
4491 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG,
4492 HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
4493 (t_void *)bitmap_rates);
4494 if (ret == MLAN_STATUS_SUCCESS)
4495 ret = MLAN_STATUS_PENDING;
4496
4497 LEAVE();
4498 return ret;
4499 }
4500
4501 /**
4502 * @brief Rate configuration command handler
4503 *
4504 * @param pmadapter A pointer to mlan_adapter structure
4505 * @param pioctl_req A pointer to ioctl request buffer
4506 *
4507 * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
4508 * otherwise fail
4509 */
wlan_rate_ioctl_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)4510 mlan_status wlan_rate_ioctl_cfg(pmlan_adapter pmadapter,
4511 pmlan_ioctl_req pioctl_req)
4512 {
4513 mlan_ds_rate *rate = MNULL;
4514 mlan_status status = MLAN_STATUS_SUCCESS;
4515
4516 ENTER();
4517
4518 rate = (mlan_ds_rate *)pioctl_req->pbuf;
4519 if (rate->param.rate_cfg.rate_type == MLAN_RATE_BITMAP) {
4520 if (pioctl_req->action == MLAN_ACT_GET)
4521 status = wlan_rate_ioctl_get_rate_bitmap(pmadapter,
4522 pioctl_req);
4523 else
4524 status = wlan_rate_ioctl_set_rate_bitmap(pmadapter,
4525 pioctl_req);
4526 } else if (rate->param.rate_cfg.rate_type == MLAN_RATE_VALUE) {
4527 if (pioctl_req->action == MLAN_ACT_GET)
4528 status = wlan_rate_ioctl_get_rate_value(pmadapter,
4529 pioctl_req);
4530 else
4531 status = wlan_rate_ioctl_set_rate_value(pmadapter,
4532 pioctl_req);
4533 } else {
4534 if (pioctl_req->action == MLAN_ACT_GET)
4535 status = wlan_rate_ioctl_get_rate_index(pmadapter,
4536 pioctl_req);
4537 else
4538 status = wlan_rate_ioctl_set_rate_index(pmadapter,
4539 pioctl_req);
4540 }
4541
4542 LEAVE();
4543 return status;
4544 }
4545
4546 /**
4547 * @brief Get data rates
4548 *
4549 * @param pmadapter A pointer to mlan_adapter structure
4550 * @param pioctl_req A pointer to ioctl request buffer
4551 *
4552 * @return MLAN_STATUS_PENDING --success, otherwise fail
4553 */
wlan_rate_ioctl_get_data_rate(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)4554 mlan_status wlan_rate_ioctl_get_data_rate(pmlan_adapter pmadapter,
4555 pmlan_ioctl_req pioctl_req)
4556 {
4557 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
4558 mlan_status ret = MLAN_STATUS_SUCCESS;
4559
4560 ENTER();
4561
4562 if (pioctl_req->action != MLAN_ACT_GET) {
4563 ret = MLAN_STATUS_FAILURE;
4564 goto exit;
4565 }
4566
4567 /* Send request to firmware */
4568 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_TX_RATE_QUERY,
4569 HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
4570 MNULL);
4571 if (ret == MLAN_STATUS_SUCCESS)
4572 ret = MLAN_STATUS_PENDING;
4573
4574 exit:
4575 LEAVE();
4576 return ret;
4577 }
4578
4579 /**
4580 * @brief Set/Get remain on channel setting
4581 *
4582 * @param pmadapter A pointer to mlan_adapter structure
4583 * @param pioctl_req A pointer to ioctl request buffer
4584 *
4585 * @return MLAN_STATUS_SUCCESS --success, otherwise fail
4586 */
wlan_radio_ioctl_remain_chan_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)4587 mlan_status wlan_radio_ioctl_remain_chan_cfg(pmlan_adapter pmadapter,
4588 pmlan_ioctl_req pioctl_req)
4589 {
4590 mlan_status ret = MLAN_STATUS_SUCCESS;
4591 mlan_ds_radio_cfg *radio_cfg = MNULL;
4592 t_u16 cmd_action = 0;
4593 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
4594
4595 ENTER();
4596
4597 radio_cfg = (mlan_ds_radio_cfg *)pioctl_req->pbuf;
4598 if (pioctl_req->action == MLAN_ACT_SET)
4599 cmd_action = HostCmd_ACT_GEN_SET;
4600 else
4601 cmd_action = HostCmd_ACT_GEN_GET;
4602
4603 /* Send request to firmware */
4604 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_REMAIN_ON_CHANNEL,
4605 cmd_action, 0, (t_void *)pioctl_req,
4606 &radio_cfg->param.remain_chan);
4607
4608 if (ret == MLAN_STATUS_SUCCESS)
4609 ret = MLAN_STATUS_PENDING;
4610
4611 LEAVE();
4612 return ret;
4613 }
4614
4615 #ifdef WIFI_DIRECT_SUPPORT
4616 /**
4617 * @brief Set/Get wifi_direct_mode
4618 *
4619 * @param pmadapter A pointer to mlan_adapter structure
4620 * @param pioctl_req A pointer to ioctl request buffer
4621 *
4622 * @return MLAN_STATUS_SUCCESS --success, otherwise fail
4623 */
wlan_bss_ioctl_wifi_direct_mode(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)4624 mlan_status wlan_bss_ioctl_wifi_direct_mode(pmlan_adapter pmadapter,
4625 pmlan_ioctl_req pioctl_req)
4626 {
4627 mlan_status ret = MLAN_STATUS_SUCCESS;
4628 mlan_ds_bss *bss = MNULL;
4629
4630 t_u16 cmd_action = 0;
4631 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
4632
4633 ENTER();
4634
4635 bss = (mlan_ds_bss *)pioctl_req->pbuf;
4636
4637 if (pioctl_req->action == MLAN_ACT_SET)
4638 cmd_action = HostCmd_ACT_GEN_SET;
4639 else
4640 cmd_action = HostCmd_ACT_GEN_GET;
4641
4642 /* Send request to firmware */
4643 ret = wlan_prepare_cmd(pmpriv, HOST_CMD_WIFI_DIRECT_MODE_CONFIG,
4644 cmd_action, 0, (t_void *)pioctl_req,
4645 &bss->param.wfd_mode);
4646
4647 if (ret == MLAN_STATUS_SUCCESS)
4648 ret = MLAN_STATUS_PENDING;
4649
4650 LEAVE();
4651 return ret;
4652 }
4653
4654 /**
4655 * @brief Set/Get p2p config
4656 *
4657 * @param pmadapter A pointer to mlan_adapter structure
4658 * @param pioctl_req A pointer to ioctl request buffer
4659 *
4660 * @return MLAN_STATUS_SUCCESS --success, otherwise fail
4661 */
wlan_misc_p2p_config(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)4662 mlan_status wlan_misc_p2p_config(pmlan_adapter pmadapter,
4663 pmlan_ioctl_req pioctl_req)
4664 {
4665 mlan_status ret = MLAN_STATUS_SUCCESS;
4666 mlan_ds_misc_cfg *misc_cfg = MNULL;
4667 t_u16 cmd_action = 0;
4668 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
4669
4670 ENTER();
4671
4672 misc_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
4673 if (pioctl_req->action == MLAN_ACT_SET)
4674 cmd_action = HostCmd_ACT_GEN_SET;
4675 else
4676 cmd_action = HostCmd_ACT_GEN_GET;
4677
4678 /* Send request to firmware */
4679 ret = wlan_prepare_cmd(pmpriv, HOST_CMD_P2P_PARAMS_CONFIG, cmd_action,
4680 0, (t_void *)pioctl_req,
4681 &misc_cfg->param.p2p_config);
4682
4683 if (ret == MLAN_STATUS_SUCCESS)
4684 ret = MLAN_STATUS_PENDING;
4685
4686 LEAVE();
4687 return ret;
4688 }
4689 #endif
4690
4691 /**
4692 * @brief Set/Get GPIO TSF Latch config
4693 *
4694 * @param pmadapter A pointer to mlan_adapter structure
4695 * @param pioctl_req A pointer to ioctl request buffer
4696 *
4697 * @return MLAN_STATUS_SUCCESS --success, otherwise fail
4698 */
wlan_misc_gpio_tsf_latch_config(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)4699 mlan_status wlan_misc_gpio_tsf_latch_config(pmlan_adapter pmadapter,
4700 pmlan_ioctl_req pioctl_req)
4701 {
4702 mlan_status ret = MLAN_STATUS_SUCCESS;
4703 mlan_ds_misc_cfg *misc_cfg = MNULL;
4704 t_u16 cmd_action = 0;
4705 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
4706
4707 ENTER();
4708
4709 misc_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
4710 if (pioctl_req->action == MLAN_ACT_SET)
4711 cmd_action = HostCmd_ACT_GEN_SET;
4712 else
4713 cmd_action = HostCmd_ACT_GEN_GET;
4714
4715 /* Send request to firmware */
4716 ret = wlan_prepare_cmd(pmpriv, HOST_CMD_GPIO_TSF_LATCH_PARAM_CONFIG,
4717 cmd_action, 0, (t_void *)pioctl_req,
4718 &misc_cfg->param.gpio_tsf_latch_config);
4719
4720 if (ret == MLAN_STATUS_SUCCESS)
4721 ret = MLAN_STATUS_PENDING;
4722
4723 LEAVE();
4724 return ret;
4725 }
4726
4727 /**
4728 * @brief Get TSF info
4729 *
4730 * @param pmadapter A pointer to mlan_adapter structure
4731 * @param pioctl_req A pointer to ioctl request buffer
4732 *
4733 * @return MLAN_STATUS_SUCCESS --success, otherwise fail
4734 */
wlan_misc_get_tsf_info(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)4735 mlan_status wlan_misc_get_tsf_info(pmlan_adapter pmadapter,
4736 pmlan_ioctl_req pioctl_req)
4737 {
4738 mlan_status ret = MLAN_STATUS_SUCCESS;
4739 mlan_ds_misc_cfg *misc_cfg = MNULL;
4740 t_u16 cmd_action = 0;
4741 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
4742
4743 ENTER();
4744
4745 misc_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
4746 cmd_action = HostCmd_ACT_GEN_GET;
4747
4748 /* Send request to firmware */
4749 ret = wlan_prepare_cmd(pmpriv, HOST_CMD_GPIO_TSF_LATCH_PARAM_CONFIG,
4750 cmd_action, 0, (t_void *)pioctl_req,
4751 &misc_cfg->param.tsf_info);
4752
4753 if (ret == MLAN_STATUS_SUCCESS)
4754 ret = MLAN_STATUS_PENDING;
4755
4756 LEAVE();
4757 return ret;
4758 }
4759
4760 /**
4761 * @brief Set coalesce config
4762 *
4763 * @param pmadapter A pointer to mlan_adapter structure
4764 * @param pioctl_req A pointer to ioctl request buffer
4765 *
4766 * @return MLAN_STATUS_SUCCESS --success, otherwise fail
4767 */
wlan_misc_ioctl_coalesce_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)4768 mlan_status wlan_misc_ioctl_coalesce_cfg(pmlan_adapter pmadapter,
4769 pmlan_ioctl_req pioctl_req)
4770 {
4771 mlan_status ret = MLAN_STATUS_SUCCESS;
4772 mlan_ds_misc_cfg *misc_cfg = MNULL;
4773 t_u16 cmd_action = 0;
4774 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
4775
4776 ENTER();
4777
4778 misc_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
4779 if (pioctl_req->action == MLAN_ACT_SET)
4780 cmd_action = HostCmd_ACT_GEN_SET;
4781 else
4782 cmd_action = HostCmd_ACT_GEN_GET;
4783
4784 /* Send request to firmware */
4785 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_COALESCE_CFG, cmd_action, 0,
4786 (t_void *)pioctl_req,
4787 &misc_cfg->param.coalesce_cfg);
4788
4789 if (ret == MLAN_STATUS_SUCCESS)
4790 ret = MLAN_STATUS_PENDING;
4791
4792 LEAVE();
4793 return ret;
4794 }
4795
4796 /**
4797 * @brief Get/Set USB packet aggregation parameters
4798 *
4799 * @param pmadapter A pointer to mlan_adapter structure
4800 * @param pioctl_req A pointer to ioctl request buffer
4801 *
4802 * @return MLAN_STATUS_PENDING --success, otherwise fail
4803 */
wlan_misc_ioctl_aggr_ctrl(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)4804 mlan_status wlan_misc_ioctl_aggr_ctrl(pmlan_adapter pmadapter,
4805 pmlan_ioctl_req pioctl_req)
4806 {
4807 mlan_status ret = MLAN_STATUS_SUCCESS;
4808 mlan_ds_misc_cfg *misc = MNULL;
4809 t_u16 cmd_action = 0;
4810 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
4811
4812 ENTER();
4813
4814 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
4815 if (pioctl_req->action == MLAN_ACT_SET)
4816 cmd_action = HostCmd_ACT_GEN_SET;
4817 else
4818 cmd_action = HostCmd_ACT_GEN_GET;
4819
4820 /* Send request to firmware */
4821 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_PACKET_AGGR_CTRL, cmd_action,
4822 0, (t_void *)pioctl_req,
4823 &misc->param.aggr_params);
4824
4825 if (ret == MLAN_STATUS_SUCCESS) {
4826 ret = MLAN_STATUS_PENDING;
4827 }
4828
4829 LEAVE();
4830 return ret;
4831 }
4832
4833 #ifdef USB
4834 /**
4835 * @brief Get/Set USB packet aggregation parameters
4836 *
4837 * @param pmadapter A pointer to mlan_adapter structure
4838 * @param pioctl_req A pointer to ioctl request buffer
4839 *
4840 * @return MLAN_STATUS_PENDING --success, otherwise fail
4841 */
wlan_misc_ioctl_usb_aggr_ctrl(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)4842 mlan_status wlan_misc_ioctl_usb_aggr_ctrl(pmlan_adapter pmadapter,
4843 pmlan_ioctl_req pioctl_req)
4844 {
4845 mlan_status ret = MLAN_STATUS_SUCCESS;
4846 mlan_ds_misc_cfg *misc = MNULL;
4847 t_u16 cmd_action = 0;
4848 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
4849
4850 ENTER();
4851
4852 if (pmadapter->pcard_usb->fw_usb_aggr == MFALSE) {
4853 PRINTM(MERROR, "USB aggregation not supported by FW\n");
4854 pioctl_req->status_code = MLAN_ERROR_CMD_INVALID;
4855 LEAVE();
4856 return MLAN_STATUS_FAILURE;
4857 }
4858
4859 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
4860 if (pioctl_req->action == MLAN_ACT_SET)
4861 cmd_action = HostCmd_ACT_GEN_SET;
4862 else
4863 cmd_action = HostCmd_ACT_GEN_GET;
4864
4865 /* Send request to firmware */
4866 ret = wlan_prepare_cmd(pmpriv,
4867 HostCmd_CMD_PACKET_AGGR_OVER_HOST_INTERFACE,
4868 cmd_action, 0, (t_void *)pioctl_req,
4869 &misc->param.usb_aggr_params);
4870
4871 if (ret == MLAN_STATUS_SUCCESS) {
4872 ret = MLAN_STATUS_PENDING;
4873 }
4874
4875 LEAVE();
4876 return ret;
4877 }
4878 #endif
4879
4880 /**
4881 * @brief Get/Set Tx control configuration
4882 *
4883 * @param pmadapter A pointer to mlan_adapter structure
4884 * @param pioctl_req A pointer to ioctl request buffer
4885 *
4886 * @return MLAN_STATUS_SUCCESS
4887 */
wlan_misc_ioctl_txcontrol(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)4888 mlan_status wlan_misc_ioctl_txcontrol(pmlan_adapter pmadapter,
4889 pmlan_ioctl_req pioctl_req)
4890 {
4891 mlan_status ret = MLAN_STATUS_SUCCESS;
4892 mlan_ds_misc_cfg *misc = MNULL;
4893 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
4894
4895 ENTER();
4896
4897 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
4898 if (pioctl_req->action == MLAN_ACT_SET)
4899 pmpriv->pkt_tx_ctrl = misc->param.tx_control;
4900 else
4901 misc->param.tx_control = pmpriv->pkt_tx_ctrl;
4902
4903 LEAVE();
4904 return ret;
4905 }
4906
4907 #ifdef RX_PACKET_COALESCE
4908 /**
4909 * @brief Get/Set RX packet coalescing configuration
4910 *
4911 * @param pmadapter A pointer to mlan_adapter structure
4912 * @param pioctl_req A pointer to ioctl request buffer
4913 *
4914 * @return MLAN_STATUS_SUCCESS
4915 */
wlan_misc_ioctl_rx_pkt_coalesce_config(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)4916 mlan_status wlan_misc_ioctl_rx_pkt_coalesce_config(pmlan_adapter pmadapter,
4917 pmlan_ioctl_req pioctl_req)
4918 {
4919 mlan_status ret = MLAN_STATUS_SUCCESS;
4920 mlan_ds_misc_cfg *misc = MNULL;
4921 t_u16 cmd_action = 0;
4922 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
4923
4924 ENTER();
4925
4926 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
4927
4928 if (pioctl_req->action == MLAN_ACT_SET)
4929 cmd_action = HostCmd_ACT_GEN_SET;
4930 else
4931 cmd_action = HostCmd_ACT_GEN_GET;
4932
4933 /* Send request to firmware */
4934 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_RX_PKT_COALESCE_CFG,
4935 cmd_action, 0, (t_void *)pioctl_req,
4936 &misc->param.rx_coalesce);
4937
4938 if (ret == MLAN_STATUS_SUCCESS)
4939 ret = MLAN_STATUS_PENDING;
4940
4941 LEAVE();
4942 return ret;
4943 }
4944 #endif
4945
4946 /**
4947 * @brief Is any uAP started or STA connected?
4948 *
4949 * @param pmadapter A pointer to mlan_adapter structure
4950 *
4951 * @return MTRUE/MFALSE
4952 */
wlan_check_interface_active(mlan_adapter * pmadapter)4953 t_bool wlan_check_interface_active(mlan_adapter *pmadapter)
4954 {
4955 t_bool ret = MFALSE;
4956 pmlan_private pmpriv;
4957 int i;
4958
4959 if (pmadapter == MNULL)
4960 return MFALSE;
4961
4962 for (i = 0; i < pmadapter->priv_num; i++) {
4963 pmpriv = pmadapter->priv[i];
4964 if (pmpriv) {
4965 #ifdef UAP_SUPPORT
4966 if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_UAP)
4967 ret = pmpriv->uap_bss_started;
4968 else
4969 #endif
4970 if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_STA)
4971 ret = pmpriv->media_connected;
4972 }
4973 if (ret)
4974 return MTRUE;
4975 }
4976
4977 return MFALSE;
4978 }
4979
4980 /**
4981 * @brief Get/Set DFS REPEATER mode
4982 *
4983 * @param pmadapter A pointer to mlan_adapter structure
4984 * @param pioctl_req A pointer to ioctl request buffer
4985 *
4986 * @return MLAN_STATUS_SUCCESS
4987 */
wlan_misc_ioctl_dfs_repeater_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)4988 mlan_status wlan_misc_ioctl_dfs_repeater_cfg(pmlan_adapter pmadapter,
4989 pmlan_ioctl_req pioctl_req)
4990 {
4991 mlan_status ret = MLAN_STATUS_SUCCESS;
4992 mlan_ds_misc_cfg *misc = MNULL;
4993 t_u16 cmd_action = 0;
4994 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
4995
4996 ENTER();
4997
4998 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
4999
5000 if (pioctl_req->action == MLAN_ACT_SET) {
5001 /* Make sure no interface is active
5002 * before setting the dfs repeater mode
5003 */
5004 if (wlan_check_interface_active(pmadapter)) {
5005 PRINTM(MMSG, "DFS-Repeater active priv found,"
5006 " skip enabling the mode.\n");
5007 ret = MLAN_STATUS_FAILURE;
5008 goto done;
5009 }
5010
5011 cmd_action = HostCmd_ACT_GEN_SET;
5012 } else {
5013 cmd_action = HostCmd_ACT_GEN_GET;
5014 }
5015
5016 /* Send request to firmware */
5017 ret = wlan_prepare_cmd(pmpriv, HostCmd_DFS_REPEATER_MODE, cmd_action, 0,
5018 (t_void *)pioctl_req, &misc->param.dfs_repeater);
5019
5020 done:
5021 if (ret == MLAN_STATUS_SUCCESS)
5022 ret = MLAN_STATUS_PENDING;
5023
5024 LEAVE();
5025 return ret;
5026 }
5027
5028 /**
5029 * @brief Set/Get Low Power Mode
5030 *
5031 * @param pmadapter A pointer to mlan_adapter structure
5032 * @param pioctl_req A pointer to ioctl request buffer
5033 *
5034 * @return MLAN_STATUS_SUCCESS
5035 */
wlan_misc_ioctl_low_pwr_mode(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)5036 mlan_status wlan_misc_ioctl_low_pwr_mode(pmlan_adapter pmadapter,
5037 pmlan_ioctl_req pioctl_req)
5038 {
5039 mlan_status ret = MLAN_STATUS_SUCCESS;
5040 mlan_ds_misc_cfg *misc = MNULL;
5041 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
5042
5043 ENTER();
5044
5045 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
5046
5047 /* Send request to firmware */
5048 ret = wlan_prepare_cmd(pmpriv, HostCMD_CONFIG_LOW_POWER_MODE,
5049 HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
5050 &misc->param.low_pwr_mode);
5051
5052 if (ret == MLAN_STATUS_SUCCESS)
5053 ret = MLAN_STATUS_PENDING;
5054
5055 LEAVE();
5056 return ret;
5057 }
5058
5059 /**
5060 * @brief Configure PMIC in Firmware
5061 *
5062 * @param pmadapter A pointer to mlan_adapter structure
5063 * @param pioctl_req A pointer to ioctl request buffer
5064 *
5065 * @return MLAN_STATUS_SUCCESS
5066 */
wlan_misc_ioctl_pmic_configure(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)5067 mlan_status wlan_misc_ioctl_pmic_configure(pmlan_adapter pmadapter,
5068 pmlan_ioctl_req pioctl_req)
5069 {
5070 mlan_status ret = MLAN_STATUS_SUCCESS;
5071 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
5072
5073 ENTER();
5074
5075 /* Send request to firmware */
5076 ret = wlan_prepare_cmd(pmpriv, HOST_CMD_PMIC_CONFIGURE,
5077 HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
5078 MNULL);
5079
5080 if (ret == MLAN_STATUS_SUCCESS)
5081 ret = MLAN_STATUS_PENDING;
5082
5083 LEAVE();
5084 return ret;
5085 }
5086
5087 /* @brief Set/Get CW Mode Level control
5088 *
5089 * @param pmadapter A pointer to mlan_adapter structure
5090 * @param pioctl_req A pointer to ioctl request buffer
5091 *
5092 * @return MLAN_STATUS_SUCCESS
5093 */
wlan_misc_ioctl_cwmode_ctrl(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)5094 mlan_status wlan_misc_ioctl_cwmode_ctrl(pmlan_adapter pmadapter,
5095 pmlan_ioctl_req pioctl_req)
5096 {
5097 mlan_status ret = MLAN_STATUS_SUCCESS;
5098 mlan_ds_misc_cfg *misc = MNULL;
5099 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
5100 t_u16 cmd_action = 0;
5101
5102 ENTER();
5103
5104 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
5105
5106 if (pioctl_req->action == MLAN_ACT_SET)
5107 cmd_action = HostCmd_ACT_GEN_SET;
5108 else
5109 cmd_action = HostCmd_ACT_GEN_GET;
5110
5111 /* Send request to firmware */
5112 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_CW_MODE_CTRL, cmd_action, 0,
5113 (t_void *)pioctl_req, &misc->param.cwmode);
5114
5115 if (ret == MLAN_STATUS_SUCCESS)
5116 ret = MLAN_STATUS_PENDING;
5117
5118 LEAVE();
5119 return ret;
5120 }
5121
5122 /**
5123 * @brief push value to stack
5124 *
5125 * @param pmadapter A pointer to mlan_adapter structure
5126 * @param s A pointer to mef_stack
5127 * @param len Length of value
5128 * @param val A pointer to value
5129 *
5130 * @return MLAN_STATUS_SUCCESS or FAIL
5131 */
push_n(pmlan_adapter pmadapter,mef_stack * s,t_u8 len,t_u8 * val)5132 inline mlan_status push_n(pmlan_adapter pmadapter, mef_stack *s, t_u8 len,
5133 t_u8 *val)
5134 {
5135 if ((s->sp + len) <= MAX_NUM_STACK_BYTES) {
5136 memcpy_ext(pmadapter, s->byte + s->sp, val, len,
5137 MAX_NUM_STACK_BYTES - s->sp);
5138 s->sp += len;
5139 return MLAN_STATUS_SUCCESS;
5140 } else {
5141 PRINTM(MERROR, "Stack is full\n");
5142 return MLAN_STATUS_FAILURE;
5143 }
5144 }
5145
5146 /**
5147 * @brief push value to stack accoring to operand type
5148 *
5149 * @param pmadapter A pointer to mlan_adapter structure
5150 * @param s A pointer to mef_stack
5151 * @param op A pointer to mef_op
5152 *
5153 * @return MLAN_STATUS_SUCCESS or FAIL
5154 */
mef_push(pmlan_adapter pmadapter,mef_stack * s,mef_op * op)5155 inline mlan_status mef_push(pmlan_adapter pmadapter, mef_stack *s, mef_op *op)
5156 {
5157 mlan_status ret = MLAN_STATUS_SUCCESS;
5158 t_u8 nbytes;
5159 switch (op->operand_type) {
5160 case OPERAND_DNUM:
5161 ret = push_n(pmadapter, s, 4, op->val);
5162 if (ret == MLAN_STATUS_SUCCESS)
5163 ret = push_n(pmadapter, s, 1, &op->operand_type);
5164 else
5165 ret = MLAN_STATUS_FAILURE;
5166 break;
5167 case OPERAND_BYTE_SEQ:
5168 nbytes = op->val[0];
5169 if (MLAN_STATUS_SUCCESS ==
5170 push_n(pmadapter, s, nbytes, op->val + 1) &&
5171 MLAN_STATUS_SUCCESS == push_n(pmadapter, s, 1, op->val) &&
5172 MLAN_STATUS_SUCCESS ==
5173 push_n(pmadapter, s, 1, &op->operand_type))
5174 ret = MLAN_STATUS_SUCCESS;
5175 else
5176 ret = MLAN_STATUS_FAILURE;
5177 break;
5178 default:
5179 ret = push_n(pmadapter, s, 1, &op->operand_type);
5180 break;
5181 }
5182 return ret;
5183 }
5184
5185 /**
5186 * @brief push dnum filter to stack
5187 *
5188 * @param pmadapter A pointer to mlan_adapter structure
5189 * @param s A pointer to mef_stack
5190 * @param filter A pointer to filter item
5191 *
5192 * @return MLAN_STATUS_SUCCESS or FAIL
5193 */
push_filter_dnum_eq(pmlan_adapter pmadapter,mef_stack * s,mef_filter_t * filter)5194 static mlan_status push_filter_dnum_eq(pmlan_adapter pmadapter, mef_stack *s,
5195 mef_filter_t *filter)
5196 {
5197 mlan_status ret = MLAN_STATUS_SUCCESS;
5198 t_u32 dnum;
5199 mef_op op;
5200
5201 ENTER();
5202
5203 if (!filter) {
5204 ret = MLAN_STATUS_FAILURE;
5205 goto done;
5206 }
5207 if (filter->fill_flag != (FILLING_TYPE | FILLING_PATTERN |
5208 FILLING_OFFSET | FILLING_NUM_BYTES)) {
5209 PRINTM(MERROR, "Filter item fill error\n");
5210 ret = MLAN_STATUS_FAILURE;
5211 goto done;
5212 }
5213
5214 /* Format of decimal num:
5215 * | 5 bytes | 5 bytes | 5 bytes | 1 byte | |
5216 * pattern | offset | num of bytes | type (TYPE_DNUM_EQ) |
5217 */
5218
5219 /* push pattern */
5220 memset(pmadapter, &op, 0, sizeof(op));
5221 op.operand_type = OPERAND_DNUM;
5222 dnum = filter->pattern;
5223 memcpy_ext(pmadapter, op.val, &dnum, sizeof(dnum), sizeof(op.val));
5224 ret = mef_push(pmadapter, s, &op);
5225 if (ret != MLAN_STATUS_SUCCESS)
5226 goto done;
5227
5228 /* push offset */
5229 memset(pmadapter, &op, 0, sizeof(op));
5230 op.operand_type = OPERAND_DNUM;
5231 dnum = filter->offset;
5232 memcpy_ext(pmadapter, op.val, &dnum, sizeof(dnum), sizeof(op.val));
5233 ret = mef_push(pmadapter, s, &op);
5234 if (ret != MLAN_STATUS_SUCCESS)
5235 goto done;
5236
5237 /* push num of bytes */
5238 memset(pmadapter, &op, 0, sizeof(op));
5239 op.operand_type = OPERAND_DNUM;
5240 dnum = filter->num_bytes;
5241 memcpy_ext(pmadapter, op.val, &dnum, sizeof(dnum), sizeof(op.val));
5242 ret = mef_push(pmadapter, s, &op);
5243 if (ret != MLAN_STATUS_SUCCESS)
5244 goto done;
5245
5246 /* push type */
5247 memset(pmadapter, &op, 0, sizeof(op));
5248 op.operand_type = TYPE_DNUM_EQ;
5249 ret = mef_push(pmadapter, s, &op);
5250
5251 done:
5252 LEAVE();
5253 return ret;
5254 }
5255
5256 /**
5257 * @brief push byte_eq filter to stack
5258 *
5259 * @param pmadapter A pointer to mlan_adapter structure
5260 * @param s A pointer to mef_stack
5261 * @param filter A pointer to filter item
5262 *
5263 * @return MLAN_STATUS_SUCCESS or FAIL
5264 */
push_filter_byte_eq(pmlan_adapter pmadapter,mef_stack * s,mef_filter_t * filter)5265 static mlan_status push_filter_byte_eq(pmlan_adapter pmadapter, mef_stack *s,
5266 mef_filter_t *filter)
5267 {
5268 mlan_status ret = MLAN_STATUS_SUCCESS;
5269 t_u32 dnum;
5270 mef_op op;
5271
5272 ENTER();
5273
5274 if (!filter) {
5275 ret = MLAN_STATUS_FAILURE;
5276 goto done;
5277 }
5278 if (filter->fill_flag != (FILLING_TYPE | FILLING_REPEAT |
5279 FILLING_BYTE_SEQ | FILLING_OFFSET)) {
5280 PRINTM(MERROR, "Filter item fill error\n");
5281 ret = MLAN_STATUS_FAILURE;
5282 goto done;
5283 }
5284
5285 /* Format of decimal num:
5286 * | 5 bytes | val | 5 bytes | 1 byte | |
5287 * repeat | bytes seq | offset | type (TYPE_BYTE_EQ) |
5288 */
5289
5290 /* push repeat */
5291 memset(pmadapter, &op, 0, sizeof(op));
5292 op.operand_type = OPERAND_DNUM;
5293 dnum = filter->repeat;
5294 memcpy_ext(pmadapter, op.val, &dnum, sizeof(dnum), sizeof(op.val));
5295 ret = mef_push(pmadapter, s, &op);
5296 if (ret != MLAN_STATUS_SUCCESS)
5297 goto done;
5298
5299 /* push bytes seq */
5300 memset(pmadapter, &op, 0, sizeof(op));
5301 op.operand_type = OPERAND_BYTE_SEQ;
5302 op.val[0] = filter->num_byte_seq;
5303 memcpy_ext(pmadapter, &op.val[1], filter->byte_seq,
5304 filter->num_byte_seq, MAX_NUM_BYTE_SEQ);
5305 ret = mef_push(pmadapter, s, &op);
5306 if (ret != MLAN_STATUS_SUCCESS)
5307 goto done;
5308
5309 /* push offset */
5310 memset(pmadapter, &op, 0, sizeof(op));
5311 op.operand_type = OPERAND_DNUM;
5312 dnum = filter->offset;
5313 memcpy_ext(pmadapter, op.val, &dnum, sizeof(dnum), sizeof(op.val));
5314 ret = mef_push(pmadapter, s, &op);
5315 if (ret != MLAN_STATUS_SUCCESS)
5316 goto done;
5317
5318 /* push type */
5319 memset(pmadapter, &op, 0, sizeof(op));
5320 op.operand_type = TYPE_BYTE_EQ;
5321 ret = mef_push(pmadapter, s, &op);
5322
5323 done:
5324 LEAVE();
5325 return ret;
5326 }
5327
5328 /**
5329 * @brief push bite_eq filter to stack
5330 *
5331 * @param pmadapter A pointer to mlan_adapter structure
5332 * @param s A pointer to mef_stack
5333 * @param filter A pointer to filter item
5334 *
5335 * @return MLAN_STATUS_SUCCESS or FAIL
5336 */
push_filter_bit_eq(pmlan_adapter pmadapter,mef_stack * s,mef_filter_t * filter)5337 static mlan_status push_filter_bit_eq(pmlan_adapter pmadapter, mef_stack *s,
5338 mef_filter_t *filter)
5339 {
5340 mlan_status ret = MLAN_STATUS_SUCCESS;
5341 t_u32 dnum;
5342 mef_op op;
5343
5344 ENTER();
5345
5346 if (!filter) {
5347 ret = MLAN_STATUS_FAILURE;
5348 goto done;
5349 }
5350 if (filter->fill_flag != (FILLING_TYPE | FILLING_REPEAT |
5351 FILLING_BYTE_SEQ | FILLING_OFFSET)) {
5352 PRINTM(MERROR, "Filter item fill error\n");
5353 ret = MLAN_STATUS_FAILURE;
5354 goto done;
5355 }
5356
5357 /* Format of decimal num:
5358 * | val | 5 bytes | val | 1 byte | |
5359 * bytes seq | offset | mask seq | type (TYPE_BIT_EQ) |
5360 */
5361
5362 /* push bytes seq */
5363 memset(pmadapter, &op, 0, sizeof(op));
5364 op.operand_type = OPERAND_BYTE_SEQ;
5365 op.val[0] = filter->num_byte_seq;
5366 memcpy_ext(pmadapter, &op.val[1], filter->byte_seq,
5367 filter->num_byte_seq, MAX_NUM_BYTE_SEQ);
5368 ret = mef_push(pmadapter, s, &op);
5369 if (ret != MLAN_STATUS_SUCCESS)
5370 goto done;
5371
5372 /* push offset */
5373 memset(pmadapter, &op, 0, sizeof(op));
5374 op.operand_type = OPERAND_DNUM;
5375 dnum = filter->offset;
5376 memcpy_ext(pmadapter, op.val, &dnum, sizeof(dnum), sizeof(op.val));
5377 ret = mef_push(pmadapter, s, &op);
5378 if (ret != MLAN_STATUS_SUCCESS)
5379 goto done;
5380
5381 /* push mask seq */
5382 memset(pmadapter, &op, 0, sizeof(op));
5383 op.operand_type = OPERAND_BYTE_SEQ;
5384 op.val[0] = filter->num_mask_seq;
5385 memcpy_ext(pmadapter, &op.val[1], filter->mask_seq,
5386 filter->num_mask_seq, MAX_NUM_BYTE_SEQ);
5387 ret = mef_push(pmadapter, s, &op);
5388 if (ret != MLAN_STATUS_SUCCESS)
5389 goto done;
5390
5391 /* push type */
5392 memset(pmadapter, &op, 0, sizeof(op));
5393 op.operand_type = TYPE_BIT_EQ;
5394 ret = mef_push(pmadapter, s, &op);
5395
5396 done:
5397 LEAVE();
5398 return ret;
5399 }
5400
5401 /**
5402 * @brief push filter to stack
5403 *
5404 * @param pmadapter A pointer to mlan_adapter structure
5405 * @param s A pointer to mef_stack
5406 * @param filter A pointer to filter item
5407 *
5408 * @return MLAN_STATUS_SUCCESS or FAIL
5409 */
wlan_push_filter(pmlan_adapter pmadapter,mef_stack * s,mef_filter_t * filter)5410 static mlan_status wlan_push_filter(pmlan_adapter pmadapter, mef_stack *s,
5411 mef_filter_t *filter)
5412 {
5413 mlan_status ret = MLAN_STATUS_SUCCESS;
5414
5415 switch (filter->type) {
5416 case TYPE_DNUM_EQ:
5417 ret = push_filter_dnum_eq(pmadapter, s, filter);
5418 break;
5419 case TYPE_BYTE_EQ:
5420 ret = push_filter_byte_eq(pmadapter, s, filter);
5421 break;
5422 case TYPE_BIT_EQ:
5423 ret = push_filter_bit_eq(pmadapter, s, filter);
5424 break;
5425 default:
5426 PRINTM(MERROR, "Invalid filter type\n");
5427 ret = MLAN_STATUS_FAILURE;
5428 break;
5429 }
5430 return ret;
5431 }
5432
5433 /**
5434 * @brief generate mef data
5435 *
5436 * @param pmadapter A pointer to mlan_adapter structure
5437 * @param s A pointer to mef_stack
5438 * @param entry A pointer to mef_entry_t
5439 *
5440 * @return MLAN_STATUS_SUCCESS or FAIL
5441 */
wlan_generate_mef_filter_stack(pmlan_adapter pmadapter,mef_stack * s,mef_entry_t * entry)5442 static mlan_status wlan_generate_mef_filter_stack(pmlan_adapter pmadapter,
5443 mef_stack *s,
5444 mef_entry_t *entry)
5445 {
5446 mlan_status ret = MLAN_STATUS_SUCCESS;
5447 mef_op op;
5448 int i;
5449
5450 ENTER();
5451
5452 for (i = 0; i < entry->filter_num; i++) {
5453 ret = wlan_push_filter(pmadapter, s, &entry->filter_item[i]);
5454 if (ret != MLAN_STATUS_SUCCESS) {
5455 PRINTM(MERROR, "push filter to stack error\n");
5456 goto done;
5457 }
5458 if (i != 0) {
5459 memset(pmadapter, &op, 0, sizeof(op));
5460 op.operand_type = entry->rpn[i];
5461 ret = mef_push(pmadapter, s, &op);
5462 if (ret != MLAN_STATUS_SUCCESS) {
5463 PRINTM(MERROR, "push filter rpn error\n");
5464 goto done;
5465 }
5466 }
5467 }
5468 done:
5469 LEAVE();
5470 return ret;
5471 }
5472
5473 /**
5474 * @brief Set the mef entries to firmware
5475 *
5476 * @param pmpriv A pointer to mlan_private structure
5477 * @param pmadapter A pointer to mlan_adapter structure
5478 * @param pmef A pointer to mef_cfg structure
5479 *
5480 * @return MLAN_STATUS_SUCCESS or FAIL
5481 */
wlan_set_mef_entry(mlan_private * pmpriv,pmlan_adapter pmadapter,mef_cfg_data * pmef)5482 mlan_status wlan_set_mef_entry(mlan_private *pmpriv, pmlan_adapter pmadapter,
5483 mef_cfg_data *pmef)
5484 {
5485 mlan_status ret = MLAN_STATUS_SUCCESS;
5486 mlan_ds_misc_cmd *hostcmd;
5487 HostCmd_DS_GEN *hostcmd_hdr;
5488 HostCmd_DS_MEF_CFG *mef_hdr;
5489 mef_entry_header *entry_hdr;
5490 mef_stack *stack;
5491 mef_entry_t *pentry;
5492 t_u8 *buf;
5493 t_u32 i, buf_len;
5494 pmlan_callbacks pcb;
5495
5496 ENTER();
5497
5498 if (pmef->entry_num > MAX_NUM_ENTRIES) {
5499 PRINTM(MERROR, "Too many entries\n");
5500 ret = MLAN_STATUS_FAILURE;
5501 goto done;
5502 }
5503 pcb = &pmadapter->callbacks;
5504 ret = pcb->moal_malloc(pmadapter->pmoal_handle,
5505 sizeof(mlan_ds_misc_cmd), MLAN_MEM_DEF,
5506 (t_u8 **)&hostcmd);
5507 if (ret != MLAN_STATUS_SUCCESS || hostcmd == MNULL) {
5508 PRINTM(MERROR, "Failed to allocate cmd data buffer\n");
5509 ret = MLAN_STATUS_FAILURE;
5510 goto err_handle;
5511 }
5512
5513 /** Fill the cmd header data*/
5514 memset(pmadapter, hostcmd, 0, sizeof(mlan_ds_misc_cmd));
5515 buf = hostcmd->cmd;
5516 hostcmd_hdr = (HostCmd_DS_GEN *)buf;
5517 hostcmd_hdr->command = wlan_cpu_to_le16(HostCmd_CMD_MEF_CFG);
5518 buf_len = S_DS_GEN;
5519
5520 /** Fill HostCmd_DS_MEF_CFG*/
5521 mef_hdr = (HostCmd_DS_MEF_CFG *)(buf + buf_len);
5522 mef_hdr->criteria = wlan_cpu_to_le32(pmef->criteria);
5523 mef_hdr->nentries = wlan_cpu_to_le16(pmef->entry_num);
5524 buf_len += sizeof(HostCmd_DS_MEF_CFG);
5525
5526 /** generate mef entry data*/
5527 for (i = 0, pentry = pmef->pentry; i < pmef->entry_num; i++, pentry++) {
5528 /** Fill entry header data*/
5529 entry_hdr = (mef_entry_header *)(buf + buf_len);
5530 entry_hdr->mode = pentry->mode;
5531 entry_hdr->action = pentry->action;
5532 buf_len += sizeof(mef_entry_header);
5533
5534 /** Fill Stack data*/
5535 stack = (mef_stack *)(buf + buf_len);
5536 ret = wlan_generate_mef_filter_stack(pmadapter, stack, pentry);
5537 if (ret != MLAN_STATUS_SUCCESS) {
5538 PRINTM(MERROR, "Generate mef data error\n");
5539 goto err_handle;
5540 }
5541 buf_len += (stack->sp + sizeof(stack->sp));
5542 }
5543 hostcmd_hdr->size = wlan_cpu_to_le16(buf_len);
5544 hostcmd->len = wlan_cpu_to_le32(buf_len);
5545
5546 DBG_HEXDUMP(MCMD_D, "MEF DATA", (t_u8 *)hostcmd, buf_len + 4);
5547
5548 /** Send command to firmware*/
5549 ret = wlan_prepare_cmd(pmpriv, 0, 0, 0, (t_void *)MNULL,
5550 (t_void *)hostcmd);
5551
5552 err_handle:
5553 if (hostcmd)
5554 pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)hostcmd);
5555 done:
5556 LEAVE();
5557 return ret;
5558 }
5559
5560 /*
5561 * @brief generate Host_CMD_MEF_CFG cmd data to firmware
5562 *
5563 * @param pmpriv A pointer to mlan_private structure
5564 * @param pmadapter A pointer to mlan_adapter structure
5565 *
5566 * @return MLAN_STATUS_SUCCESS or FAIL
5567 */
wlan_process_mef_cfg_cmd(mlan_private * pmpriv,pmlan_adapter pmadapter)5568 mlan_status wlan_process_mef_cfg_cmd(mlan_private *pmpriv,
5569 pmlan_adapter pmadapter)
5570 {
5571 mlan_status ret = MLAN_STATUS_SUCCESS;
5572 pmlan_callbacks pcb;
5573 mef_cfg_data mef;
5574 mef_entry_t *pentry = MNULL;
5575 mef_entry *pmef;
5576 t_u16 entry_num = 0;
5577
5578 ENTER();
5579
5580 pcb = &pmadapter->callbacks;
5581 memset(pmadapter, &mef, 0, sizeof(mef_cfg_data));
5582
5583 /** check how many entries in adapter*/
5584 pmef = &pmadapter->entry_cfg;
5585 entry_num += pmef->enable_autoarp_entry;
5586 entry_num += pmef->num_wowlan_entry;
5587 entry_num += pmef->num_ipv6_ns_offload;
5588 if (!entry_num && !pmef->clear_mef_entry) {
5589 PRINTM(MIOCTL, "No filter entries\n");
5590 goto done;
5591 }
5592 if (entry_num) {
5593 ret = pcb->moal_malloc(pmadapter->pmoal_handle,
5594 sizeof(mef_entry_t) * entry_num,
5595 MLAN_MEM_DEF, (t_u8 **)&mef.pentry);
5596 if (ret != MLAN_STATUS_SUCCESS || mef.pentry == MNULL) {
5597 PRINTM(MERROR, "Failed to allocate cmd data buffer\n");
5598 ret = MLAN_STATUS_FAILURE;
5599 goto err_handle;
5600 }
5601 }
5602
5603 /** Fill mef_cfg structure*/
5604 mef.criteria = pmef->criteria;
5605 mef.entry_num = entry_num;
5606 memset(pmadapter, mef.pentry, 0, sizeof(mef_entry_t) * entry_num);
5607 pentry = mef.pentry;
5608 /** Fill mef_entry_t structure*/
5609 /** Copy Auto arp response entry*/
5610 if (pmef->enable_autoarp_entry) {
5611 memcpy_ext(pmadapter, pentry, &pmef->entry[5],
5612 sizeof(mef_entry_t), sizeof(mef_entry_t));
5613 pentry += pmef->enable_autoarp_entry;
5614 }
5615 /** Copy wowlan entry*/
5616 if (pmef->num_wowlan_entry) {
5617 memcpy_ext(pmadapter, pentry, &pmef->entry[6],
5618 sizeof(mef_entry_t), sizeof(mef_entry_t));
5619 pentry += pmef->num_wowlan_entry;
5620 }
5621 /** Copy IPv6 NS message offload entry */
5622 if (pmef->num_ipv6_ns_offload)
5623 memcpy_ext(pmadapter, pentry, &pmef->entry[7],
5624 sizeof(mef_entry_t), sizeof(mef_entry_t));
5625
5626 /** Set Entries to firmware*/
5627 ret = wlan_set_mef_entry(pmpriv, pmadapter, &mef);
5628 if (ret != MLAN_STATUS_SUCCESS)
5629 PRINTM(MERROR, "Set MEF entries error\n");
5630
5631 err_handle:
5632 if (mef.pentry)
5633 pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)mef.pentry);
5634 done:
5635 LEAVE();
5636 return ret;
5637 }
5638
5639 /* @brief Get/Set NV-FLT-CONFIG parameters
5640 *
5641 * @param pmadapter A pointer to mlan_adapter structure
5642 * @param pioctl_req A pointer to ioctl request buffer
5643 *
5644 * @return MLAN_STATUS_SUCCESS
5645 */
wlan_misc_ioctl_mef_flt_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)5646 mlan_status wlan_misc_ioctl_mef_flt_cfg(pmlan_adapter pmadapter,
5647 pmlan_ioctl_req pioctl_req)
5648 {
5649 mlan_status ret = MLAN_STATUS_SUCCESS;
5650 mlan_ds_misc_cfg *misc_cfg = MNULL;
5651 mlan_ds_misc_mef_flt_cfg *mef_cfg = MNULL;
5652 mef_entry *pmef = MNULL;
5653
5654 ENTER();
5655
5656 misc_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
5657 mef_cfg = &misc_cfg->param.mef_flt_cfg;
5658 pmef = &pmadapter->entry_cfg;
5659 switch (pioctl_req->action) {
5660 case MLAN_ACT_SET:
5661 if (mef_cfg->mef_act_type == MEF_ACT_WOWLAN) {
5662 pmef->num_wowlan_entry = 1;
5663 pmef->criteria |= mef_cfg->criteria;
5664 memcpy_ext(pmadapter, &pmef->entry[6],
5665 &mef_cfg->mef_entry, sizeof(mef_entry_t),
5666 sizeof(mef_entry_t));
5667 }
5668 if (mef_cfg->mef_act_type == MEF_ACT_IPV6_NS) {
5669 pmef->num_ipv6_ns_offload = 1;
5670 pmef->criteria |= mef_cfg->criteria;
5671 memcpy_ext(pmadapter, &pmef->entry[7],
5672 &mef_cfg->mef_entry, sizeof(mef_entry_t),
5673 sizeof(mef_entry_t));
5674 }
5675 /** Set AUTO ARP Entry to adapter*/
5676 if (mef_cfg->mef_act_type == MEF_ACT_AUTOARP) {
5677 if (mef_cfg->op_code & MLAN_IPADDR_OP_AUTO_ARP_RESP) {
5678 pmef->enable_autoarp_entry = 1;
5679 pmef->criteria |= mef_cfg->criteria;
5680 memcpy_ext(pmadapter, &pmef->entry[5],
5681 &mef_cfg->mef_entry,
5682 sizeof(mef_entry_t),
5683 sizeof(mef_entry_t));
5684 if (MLAN_STATUS_SUCCESS !=
5685 wlan_process_mef_cfg_cmd(
5686 pmadapter
5687 ->priv[pioctl_req->bss_index],
5688 pmadapter))
5689 PRINTM(MERROR,
5690 "Set MEF Entries Error\n");
5691 } else if (!(mef_cfg->op_code &
5692 MLAN_IPADDR_OP_IP_REMOVE)) {
5693 pmef->enable_autoarp_entry = 0;
5694 pmef->num_wowlan_entry = 0;
5695 pmef->num_ipv6_ns_offload = 0;
5696 pmef->clear_mef_entry = 1;
5697 memset(pmadapter, &pmef->entry[5], 0,
5698 sizeof(mef_entry_t));
5699 memset(pmadapter, &pmef->entry[6], 0,
5700 sizeof(mef_entry_t));
5701 memset(pmadapter, &pmef->entry[7], 0,
5702 sizeof(mef_entry_t));
5703 if (MLAN_STATUS_SUCCESS !=
5704 wlan_process_mef_cfg_cmd(
5705 pmadapter
5706 ->priv[pioctl_req->bss_index],
5707 pmadapter))
5708 PRINTM(MERROR,
5709 "Clear MEF Entries Error\n");
5710 }
5711 }
5712 break;
5713 case MLAN_ACT_GET:
5714 if (mef_cfg->mef_act_type == MEF_ACT_WOWLAN)
5715 memcpy_ext(pmadapter, &mef_cfg->mef_entry,
5716 &pmef->entry[6], sizeof(mef_entry_t),
5717 sizeof(mef_entry_t));
5718 break;
5719 default:
5720 pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
5721 ret = MLAN_STATUS_FAILURE;
5722 break;
5723 }
5724
5725 LEAVE();
5726 return ret;
5727 }
5728
5729 /**
5730 * @brief Set/Get WPA passphrase for esupplicant
5731 *
5732 * @param pmadapter A pointer to mlan_adapter structure
5733 * @param pioctl_req A pointer to ioctl request buffer
5734 *
5735 * @return MLAN_STATUS_PENDING --success, otherwise fail
5736 */
wlan_sec_ioctl_passphrase(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)5737 mlan_status wlan_sec_ioctl_passphrase(pmlan_adapter pmadapter,
5738 pmlan_ioctl_req pioctl_req)
5739 {
5740 mlan_status ret = MLAN_STATUS_SUCCESS;
5741 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
5742 mlan_ds_sec_cfg *sec = MNULL;
5743 t_u16 cmd_action = 0;
5744 #ifdef STA_SUPPORT
5745 BSSDescriptor_t *pbss_desc;
5746 int i = 0;
5747 #endif
5748 ENTER();
5749
5750 sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
5751 #ifdef DRV_EMBEDDED_SUPPLICANT
5752 if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_STA &&
5753 !IS_FW_SUPPORT_SUPPLICANT(pmpriv->adapter)) {
5754 if (sec->param.passphrase.psk_type == MLAN_PSK_QUERY)
5755 SupplicantQueryPassphrase(
5756 pmpriv->psapriv,
5757 (void *)&sec->param.passphrase);
5758 else if (sec->param.passphrase.psk_type == MLAN_PSK_CLEAR)
5759 SupplicantClearPMK(pmpriv->psapriv,
5760 (void *)&sec->param.passphrase);
5761 else
5762 SupplicantSetPassphrase(pmpriv->psapriv,
5763 (void *)&sec->param.passphrase);
5764
5765 LEAVE();
5766 return ret;
5767 }
5768 #endif
5769
5770 if (!IS_FW_SUPPORT_SUPPLICANT(pmpriv->adapter)) {
5771 LEAVE();
5772 return ret;
5773 }
5774
5775 if (pioctl_req->action == MLAN_ACT_SET) {
5776 if (sec->param.passphrase.psk_type == MLAN_PSK_CLEAR)
5777 cmd_action = HostCmd_ACT_GEN_REMOVE;
5778 else
5779 cmd_action = HostCmd_ACT_GEN_SET;
5780 } else if (pioctl_req->action == MLAN_ACT_CLEAR) {
5781 cmd_action = HostCmd_ACT_GEN_REMOVE;
5782 } else {
5783 if (sec->param.passphrase.psk_type == MLAN_PSK_QUERY) {
5784 #ifdef STA_SUPPORT
5785 if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_STA &&
5786 sec->param.passphrase.ssid.ssid_len == 0) {
5787 i = wlan_find_bssid_in_list(
5788 pmpriv,
5789 (t_u8 *)&sec->param.passphrase.bssid,
5790 MLAN_BSS_MODE_AUTO);
5791 if (i >= 0) {
5792 pbss_desc = &pmadapter->pscan_table[i];
5793 memcpy_ext(pmadapter,
5794 &sec->param.passphrase.ssid,
5795 &pbss_desc->ssid,
5796 sizeof(mlan_802_11_ssid),
5797 sizeof(mlan_802_11_ssid));
5798 memset(pmadapter,
5799 &sec->param.passphrase.bssid, 0,
5800 MLAN_MAC_ADDR_LENGTH);
5801 PRINTM(MINFO,
5802 "PSK_QUERY: found ssid=%s\n",
5803 sec->param.passphrase.ssid.ssid);
5804 }
5805 } else
5806 #endif
5807 memset(pmadapter, &sec->param.passphrase.bssid,
5808 0, MLAN_MAC_ADDR_LENGTH);
5809 }
5810 cmd_action = HostCmd_ACT_GEN_GET;
5811 }
5812
5813 /* Send request to firmware */
5814 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_SUPPLICANT_PMK, cmd_action,
5815 0, (t_void *)pioctl_req, (t_void *)sec);
5816 if (ret == MLAN_STATUS_SUCCESS)
5817 ret = MLAN_STATUS_PENDING;
5818
5819 LEAVE();
5820 return ret;
5821 }
5822
5823 /**
5824 * @brief Set per packet Txctl and Rxinfo configuration
5825 *
5826 * @param pmadapter A pointer to mlan_adapter structure
5827 * @param pioctl_req A pointer to ioctl request buffer
5828 *
5829 * @return MLAN_STATUS_SUCCESS --success, otherwise fail
5830 */
wlan_misc_per_pkt_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)5831 mlan_status wlan_misc_per_pkt_cfg(pmlan_adapter pmadapter,
5832 pmlan_ioctl_req pioctl_req)
5833 {
5834 mlan_status ret = MLAN_STATUS_SUCCESS;
5835 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
5836 mlan_ds_misc_cfg *misc = MNULL;
5837
5838 ENTER();
5839
5840 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
5841 pmpriv->rx_pkt_info = MFALSE;
5842 if (misc->param.txrx_pkt_ctrl & RX_PKT_INFO)
5843 pmpriv->rx_pkt_info = MTRUE;
5844
5845 LEAVE();
5846 return ret;
5847 }
5848
5849 /**
5850 * @brief Set/Get region code
5851 *
5852 * @param pmadapter A pointer to mlan_adapter structure
5853 * @param pioctl_req A pointer to ioctl request buffer
5854 *
5855 * @return MLAN_STATUS_SUCCESS --success, otherwise fail
5856 */
wlan_misc_ioctl_region(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)5857 mlan_status wlan_misc_ioctl_region(pmlan_adapter pmadapter,
5858 pmlan_ioctl_req pioctl_req)
5859 {
5860 mlan_status ret = MLAN_STATUS_SUCCESS;
5861 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
5862 mlan_ds_misc_cfg *misc = MNULL;
5863 int i;
5864
5865 ENTER();
5866
5867 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
5868 if (pioctl_req->action == MLAN_ACT_GET) {
5869 misc->param.region_code = pmadapter->region_code;
5870 } else {
5871 if (pmadapter->otp_region && pmadapter->otp_region->force_reg) {
5872 PRINTM(MERROR,
5873 "ForceRegionRule is set in the on-chip OTP"
5874 " memory\n");
5875 LEAVE();
5876 return MLAN_STATUS_FAILURE;
5877 }
5878 for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
5879 /* Use the region code to search for the index */
5880 if (misc->param.region_code == region_code_index[i]) {
5881 pmadapter->region_code =
5882 (t_u16)misc->param.region_code;
5883 break;
5884 }
5885 }
5886 /* It's unidentified region code */
5887 if (i >= MRVDRV_MAX_REGION_CODE) {
5888 PRINTM(MERROR, "Region Code not identified\n");
5889 pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
5890 LEAVE();
5891 return MLAN_STATUS_FAILURE;
5892 }
5893 pmadapter->cfp_code_bg = misc->param.region_code;
5894 pmadapter->cfp_code_a = misc->param.region_code;
5895 if (wlan_set_regiontable(pmpriv, (t_u8)pmadapter->region_code,
5896 pmadapter->config_bands |
5897 pmadapter->adhoc_start_band)) {
5898 pioctl_req->status_code = MLAN_ERROR_IOCTL_FAIL;
5899 ret = MLAN_STATUS_FAILURE;
5900 }
5901 }
5902 pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
5903
5904 LEAVE();
5905 return ret;
5906 }
5907
5908 /**
5909 * @brief Configure GPIO independent reset
5910 *
5911 * @param pmadapter A pointer to mlan_adapter structure
5912 * @param pioctl_req A pointer to ioctl request buffer
5913 *
5914 * @return MLAN_STATUS_PENDING --success, otherwise fail
5915 */
wlan_misc_ioctl_ind_rst_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)5916 mlan_status wlan_misc_ioctl_ind_rst_cfg(pmlan_adapter pmadapter,
5917 pmlan_ioctl_req pioctl_req)
5918 {
5919 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
5920 mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
5921 mlan_status ret = MLAN_STATUS_SUCCESS;
5922 t_u16 cmd_action = 0;
5923
5924 ENTER();
5925
5926 if (pioctl_req->action == MLAN_ACT_GET)
5927 cmd_action = HostCmd_ACT_GEN_GET;
5928 else
5929 cmd_action = HostCmd_ACT_GEN_SET;
5930
5931 /* Send request to firmware */
5932 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_INDEPENDENT_RESET_CFG,
5933 cmd_action, 0, (t_void *)pioctl_req,
5934 (t_void *)&misc->param.ind_rst_cfg);
5935
5936 if (ret == MLAN_STATUS_SUCCESS)
5937 ret = MLAN_STATUS_PENDING;
5938
5939 LEAVE();
5940 return ret;
5941 }
5942
5943 /**
5944 * @brief Get timestamp from firmware
5945 *
5946 * @param pmadapter A pointer to mlan_adapter structure
5947 * @param pioctl_req A pointer to ioctl request buffer
5948 *
5949 * @return MLAN_STATUS_PENDING --success, otherwise fail
5950 */
wlan_misc_ioctl_get_tsf(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)5951 mlan_status wlan_misc_ioctl_get_tsf(pmlan_adapter pmadapter,
5952 pmlan_ioctl_req pioctl_req)
5953 {
5954 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
5955 mlan_status ret = MLAN_STATUS_SUCCESS;
5956 t_u16 cmd_action = 0;
5957
5958 ENTER();
5959
5960 if (pioctl_req->action == MLAN_ACT_GET)
5961 cmd_action = HostCmd_ACT_GEN_GET;
5962 else {
5963 PRINTM(MERROR, "No support set tsf!");
5964 return MLAN_STATUS_FAILURE;
5965 }
5966
5967 /* Send request to firmware */
5968 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_GET_TSF, cmd_action, 0,
5969 (t_void *)pioctl_req, MNULL);
5970
5971 if (ret == MLAN_STATUS_SUCCESS)
5972 ret = MLAN_STATUS_PENDING;
5973
5974 LEAVE();
5975 return ret;
5976 }
5977
5978 /**
5979 * @brief Create custom regulatory cfg
5980 *
5981 * @param pmadapter A pointer to mlan_adapter structure
5982 * @param pioctl_req A pointer to ioctl request buffer
5983 *
5984 * @return MLAN_STATUS_PENDING --success, otherwise fail
5985 */
wlan_misc_chan_reg_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)5986 mlan_status wlan_misc_chan_reg_cfg(pmlan_adapter pmadapter,
5987 pmlan_ioctl_req pioctl_req)
5988 {
5989 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
5990 mlan_status ret = MLAN_STATUS_SUCCESS;
5991 t_u16 cmd_action = 0;
5992
5993 ENTER();
5994
5995 if (pioctl_req->action == MLAN_ACT_GET)
5996 cmd_action = HostCmd_ACT_GEN_GET;
5997 else {
5998 PRINTM(MERROR, "No support set channel region cfg!");
5999 return MLAN_STATUS_FAILURE;
6000 }
6001
6002 /* Send request to firmware */
6003 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_CHAN_REGION_CFG, cmd_action,
6004 0, (t_void *)pioctl_req, MNULL);
6005
6006 if (ret == MLAN_STATUS_SUCCESS)
6007 ret = MLAN_STATUS_PENDING;
6008
6009 LEAVE();
6010 return ret;
6011 }
6012
6013 /**
6014 * @brief Check operating class validation
6015 *
6016 * @param pmadapter A pointer to mlan_adapter structure
6017 * @param pioctl_req Pointer to the IOCTL request buffer
6018 *
6019 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
6020 */
wlan_misc_ioctl_operclass_validation(pmlan_adapter pmadapter,mlan_ioctl_req * pioctl_req)6021 mlan_status wlan_misc_ioctl_operclass_validation(pmlan_adapter pmadapter,
6022 mlan_ioctl_req *pioctl_req)
6023 {
6024 pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
6025 mlan_ds_misc_cfg *misc = MNULL;
6026 t_u8 channel, oper_class;
6027 mlan_status ret = MLAN_STATUS_SUCCESS;
6028
6029 ENTER();
6030
6031 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
6032 channel = misc->param.bw_chan_oper.channel;
6033 oper_class = misc->param.bw_chan_oper.oper_class;
6034 if (pioctl_req->action == MLAN_ACT_GET) {
6035 ret = wlan_check_operclass_validation(pmpriv, channel,
6036 oper_class);
6037 } else {
6038 PRINTM(MERROR, "Unsupported cmd_action\n");
6039 LEAVE();
6040 return MLAN_STATUS_FAILURE;
6041 }
6042
6043 LEAVE();
6044 return ret;
6045 }
6046
6047 /**
6048 * @brief Get Region channel power setting
6049 *
6050 * @param pmadapter A pointer to mlan_adapter structure
6051 * @param pioctl_req A pointer to ioctl request buffer
6052 *
6053 * @return MLAN_STATUS_PENDING --success, otherwise fail
6054 */
wlan_get_rgchnpwr_cfg(pmlan_adapter pmadapter,mlan_ioctl_req * pioctl_req)6055 mlan_status wlan_get_rgchnpwr_cfg(pmlan_adapter pmadapter,
6056 mlan_ioctl_req *pioctl_req)
6057 {
6058 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
6059 mlan_status ret = MLAN_STATUS_SUCCESS;
6060 t_u16 cmd_action = 0;
6061
6062 ENTER();
6063
6064 cmd_action = HostCmd_ACT_GEN_GET;
6065
6066 /* Send request to firmware */
6067 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_CHAN_REGION_CFG, cmd_action,
6068 0, (t_void *)pioctl_req, MNULL);
6069
6070 if (ret == MLAN_STATUS_SUCCESS)
6071 ret = MLAN_STATUS_PENDING;
6072
6073 LEAVE();
6074 return ret;
6075 }
6076
6077 /**
6078 * @brief Get/Set mc_aggr_cfg
6079 *
6080 * @param pmadapter A pointer to mlan_adapter structure
6081 * @param pioctl_req A pointer to ioctl request buffer
6082 *
6083 * @return MLAN_STATUS_PENDING --success, otherwise fail
6084 */
wlan_misc_ioctl_mc_aggr_cfg(pmlan_adapter pmadapter,mlan_ioctl_req * pioctl_req)6085 mlan_status wlan_misc_ioctl_mc_aggr_cfg(pmlan_adapter pmadapter,
6086 mlan_ioctl_req *pioctl_req)
6087 {
6088 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
6089 mlan_status ret = MLAN_STATUS_SUCCESS;
6090 t_u16 cmd_action = 0;
6091 mlan_ds_misc_cfg *misc = MNULL;
6092
6093 ENTER();
6094
6095 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
6096 cmd_action = pioctl_req->action;
6097
6098 /* Send request to firmware */
6099 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MC_AGGR_CFG, cmd_action, 0,
6100 (t_void *)pioctl_req,
6101 (t_void *)&misc->param.mc_aggr_cfg);
6102
6103 if (ret == MLAN_STATUS_SUCCESS)
6104 ret = MLAN_STATUS_PENDING;
6105
6106 LEAVE();
6107 return ret;
6108 }
6109 /**
6110 * @brief get channel load results
6111 *
6112 * @param pmadapter A pointer to mlan_adapter structure
6113 * @param pioctl_req A pointer to ioctl request buffer
6114 *
6115 * @return MLAN_STATUS_PENDING --success, otherwise fail
6116 */
wlan_misc_ioctl_ch_load_results(pmlan_adapter pmadapter,mlan_ioctl_req * pioctl_req)6117 mlan_status wlan_misc_ioctl_ch_load_results(pmlan_adapter pmadapter,
6118 mlan_ioctl_req *pioctl_req)
6119 {
6120 mlan_private *pmpriv = MNULL;
6121 mlan_status ret = MLAN_STATUS_SUCCESS;
6122 t_u16 cmd_action = 0;
6123 mlan_ds_misc_cfg *misc = MNULL;
6124
6125 ENTER();
6126 if (pioctl_req == MNULL)
6127 return MLAN_STATUS_FAILURE;
6128 pmpriv = pmadapter->priv[pioctl_req->bss_index];
6129 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
6130 cmd_action = pioctl_req->action;
6131
6132 /* Send request to firmware */
6133 if (pmpriv->ch_load_param == 255) {
6134 return MLAN_STATUS_FAILURE;
6135 } else {
6136 misc->param.ch_load.ch_load_param = pmpriv->ch_load_param;
6137 misc->param.ch_load.noise = pmpriv->noise;
6138 misc->param.ch_load.rx_quality = pmpriv->rx_quality;
6139 }
6140
6141 LEAVE();
6142 return ret;
6143 }
6144
6145 /**
6146 * @brief get channel load
6147 *
6148 * @param pmadapter A pointer to mlan_adapter structure
6149 * @param pioctl_req A pointer to ioctl request buffer
6150 *
6151 * @return MLAN_STATUS_PENDING --success, otherwise fail
6152 */
wlan_misc_ioctl_ch_load(pmlan_adapter pmadapter,mlan_ioctl_req * pioctl_req)6153 mlan_status wlan_misc_ioctl_ch_load(pmlan_adapter pmadapter,
6154 mlan_ioctl_req *pioctl_req)
6155 {
6156 mlan_private *pmpriv = MNULL;
6157 mlan_status ret = MLAN_STATUS_SUCCESS;
6158 t_u16 cmd_action = 0;
6159 mlan_ds_misc_cfg *misc = MNULL;
6160
6161 ENTER();
6162 if (pioctl_req == MNULL)
6163 return MLAN_STATUS_FAILURE;
6164 pmpriv = pmadapter->priv[pioctl_req->bss_index];
6165 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
6166 cmd_action = pioctl_req->action;
6167
6168 /* Send request to firmware */
6169 pmpriv->ch_load_param = 255; /* Default value for identifying
6170 update/non-updated value*/
6171 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_GET_CH_LOAD, cmd_action, 0,
6172 (t_void *)pioctl_req,
6173 (t_void *)&misc->param.ch_load);
6174
6175 if (ret == MLAN_STATUS_SUCCESS)
6176 ret = MLAN_STATUS_PENDING;
6177
6178 LEAVE();
6179 return ret;
6180 }
6181
6182 /**
6183 * @brief Get CHAN_TPRC setting
6184 *
6185 * @param pmadapter A pointer to mlan_adapter structure
6186 * @param pioctl_req A pointer to ioctl request buffer
6187 *
6188 * @return MLAN_STATUS_PENDING --success, otherwise fail
6189 */
wlan_get_chan_trpc_cfg(pmlan_adapter pmadapter,mlan_ioctl_req * pioctl_req)6190 mlan_status wlan_get_chan_trpc_cfg(pmlan_adapter pmadapter,
6191 mlan_ioctl_req *pioctl_req)
6192 {
6193 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
6194 mlan_status ret = MLAN_STATUS_SUCCESS;
6195 t_u16 cmd_action = 0;
6196 mlan_ds_misc_cfg *misc = MNULL;
6197
6198 ENTER();
6199
6200 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
6201 cmd_action = HostCmd_ACT_GEN_GET;
6202
6203 /* Send request to firmware */
6204 ret = wlan_prepare_cmd(pmpriv, HostCmd_CHANNEL_TRPC_CONFIG, cmd_action,
6205 0, (t_void *)pioctl_req,
6206 (t_void *)&misc->param.trpc_cfg);
6207
6208 if (ret == MLAN_STATUS_SUCCESS)
6209 ret = MLAN_STATUS_PENDING;
6210
6211 LEAVE();
6212 return ret;
6213 }
6214
6215 /**
6216 * @brief Get non-global operating class
6217 *
6218 * @param pmadapter A pointer to mlan_adapter structure
6219 * @param pioctl_req Pointer to the IOCTL request buffer
6220 *
6221 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
6222 */
wlan_misc_ioctl_oper_class(pmlan_adapter pmadapter,mlan_ioctl_req * pioctl_req)6223 mlan_status wlan_misc_ioctl_oper_class(pmlan_adapter pmadapter,
6224 mlan_ioctl_req *pioctl_req)
6225 {
6226 pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
6227 mlan_ds_misc_cfg *misc = MNULL;
6228 t_u8 channel, bandwidth, oper_class = 0;
6229 mlan_status ret = MLAN_STATUS_SUCCESS;
6230
6231 ENTER();
6232
6233 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
6234 channel = misc->param.bw_chan_oper.channel;
6235 switch (misc->param.bw_chan_oper.bandwidth) {
6236 case 20:
6237 bandwidth = BW_20MHZ;
6238 break;
6239 case 40:
6240 bandwidth = BW_40MHZ;
6241 break;
6242 case 80:
6243 bandwidth = BW_80MHZ;
6244 break;
6245 default:
6246 bandwidth = BW_20MHZ;
6247 break;
6248 }
6249
6250 if (pioctl_req->action == MLAN_ACT_GET) {
6251 ret = wlan_get_curr_oper_class(pmpriv, channel, bandwidth,
6252 &oper_class);
6253 misc->param.bw_chan_oper.oper_class = oper_class;
6254 } else {
6255 PRINTM(MERROR, "Unsupported cmd_action\n");
6256 LEAVE();
6257 return MLAN_STATUS_FAILURE;
6258 }
6259
6260 LEAVE();
6261 return ret;
6262 }
6263
6264 /**
6265 * @brief config dynamic bandwidth
6266 *
6267 * @param pmadapter A pointer to mlan_adapter structure
6268 * @param pioctl_req Pointer to the IOCTL request buffer
6269 *
6270 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
6271 */
wlan_misc_ioctl_fw_dump_event(pmlan_adapter pmadapter,mlan_ioctl_req * pioctl_req)6272 mlan_status wlan_misc_ioctl_fw_dump_event(pmlan_adapter pmadapter,
6273 mlan_ioctl_req *pioctl_req)
6274 {
6275 pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
6276 t_u16 cmd_action = 0;
6277 mlan_status ret = MLAN_STATUS_SUCCESS;
6278
6279 ENTER();
6280
6281 if (pioctl_req->action == MLAN_ACT_SET)
6282 cmd_action = HostCmd_ACT_GEN_SET;
6283 else if (pioctl_req->action == MLAN_ACT_GET)
6284 cmd_action = HostCmd_ACT_GEN_GET;
6285 else {
6286 PRINTM(MERROR, "Unsupported cmd_action\n");
6287 LEAVE();
6288 return MLAN_STATUS_FAILURE;
6289 }
6290
6291 /* Send request to firmware */
6292 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_FW_DUMP_EVENT, cmd_action, 0,
6293 (t_void *)pioctl_req, MNULL);
6294
6295 if (ret == MLAN_STATUS_SUCCESS)
6296 ret = MLAN_STATUS_PENDING;
6297
6298 LEAVE();
6299 return ret;
6300 }
6301
6302 /**
6303 * @brief Set/Get the network monitor configuration.
6304 *
6305 * @param pmadapter A pointer to mlan_adapter structure
6306 * @param pioctl_req A pointer to ioctl request buffer
6307 *
6308 * @return MLAN_STATUS_PENDING --success, otherwise fail
6309 */
wlan_misc_ioctl_net_monitor(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)6310 mlan_status wlan_misc_ioctl_net_monitor(pmlan_adapter pmadapter,
6311 pmlan_ioctl_req pioctl_req)
6312 {
6313 mlan_private *pmpriv;
6314 mlan_ds_misc_cfg *misc;
6315 mlan_status ret = MLAN_STATUS_SUCCESS;
6316 t_u16 cmd_action = 0;
6317
6318 ENTER();
6319
6320 if (!pioctl_req) {
6321 LEAVE();
6322 return MLAN_STATUS_FAILURE;
6323 }
6324 pmpriv = pmadapter->priv[pioctl_req->bss_index];
6325
6326 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
6327
6328 if (misc->param.net_mon.enable_net_mon == CHANNEL_SPEC_SNIFFER_MODE) {
6329 /* Net monitor IOCTL not allowed in connected state */
6330 if (pmpriv->media_connected == MTRUE) {
6331 PRINTM(MERROR,
6332 "IOCTL not allowed in connected state\n");
6333 pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
6334 LEAVE();
6335 return MLAN_STATUS_FAILURE;
6336 }
6337 }
6338
6339 if (pioctl_req->action == MLAN_ACT_SET)
6340 cmd_action = HostCmd_ACT_GEN_SET;
6341 else
6342 cmd_action = HostCmd_ACT_GEN_GET;
6343
6344 /* Send command to firmware */
6345 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_NET_MONITOR,
6346 cmd_action, 0, (t_void *)pioctl_req,
6347 &misc->param.net_mon);
6348
6349 if (ret == MLAN_STATUS_SUCCESS)
6350 ret = MLAN_STATUS_PENDING;
6351
6352 LEAVE();
6353 return ret;
6354 }
6355
6356 /**
6357 * @brief config boot sleep
6358 *
6359 * @param pmadapter A pointer to mlan_adapter structure
6360 * @param pioctl_req Pointer to the IOCTL request buffer
6361 *
6362 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
6363 */
wlan_misc_bootsleep(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)6364 mlan_status wlan_misc_bootsleep(pmlan_adapter pmadapter,
6365 pmlan_ioctl_req pioctl_req)
6366 {
6367 pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
6368 mlan_ds_misc_cfg *misc = MNULL;
6369 t_u16 cmd_action = 0;
6370 mlan_status ret = MLAN_STATUS_SUCCESS;
6371
6372 ENTER();
6373
6374 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
6375
6376 if (pioctl_req->action == MLAN_ACT_SET)
6377 cmd_action = HostCmd_ACT_GEN_SET;
6378 else if (pioctl_req->action == MLAN_ACT_GET)
6379 cmd_action = HostCmd_ACT_GEN_GET;
6380 else {
6381 PRINTM(MERROR, "Unsupported cmd_action 0x%x\n",
6382 pioctl_req->action);
6383 LEAVE();
6384 return MLAN_STATUS_FAILURE;
6385 }
6386
6387 /* Send request to firmware */
6388 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_BOOT_SLEEP, cmd_action, 0,
6389 (t_void *)pioctl_req, &misc->param.boot_sleep);
6390
6391 if (ret == MLAN_STATUS_SUCCESS)
6392 ret = MLAN_STATUS_PENDING;
6393
6394 LEAVE();
6395 return ret;
6396 }
6397
6398 /**
6399 * @brief Set/Get Infra/Ad-hoc band configuration
6400 *
6401 * @param pmadapter A pointer to mlan_adapter structure
6402 * @param pioctl_req A pointer to ioctl request buffer
6403 *
6404 * @return MLAN_STATUS_SUCCESS --success, otherwise fail
6405 */
wlan_radio_ioctl_band_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)6406 mlan_status wlan_radio_ioctl_band_cfg(pmlan_adapter pmadapter,
6407 pmlan_ioctl_req pioctl_req)
6408 {
6409 t_u32 i, global_band = 0;
6410 t_u32 infra_band = 0;
6411 t_u32 adhoc_band = 0;
6412 t_u32 adhoc_channel = 0;
6413 mlan_ds_radio_cfg *radio_cfg = MNULL;
6414 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
6415
6416 ENTER();
6417
6418 radio_cfg = (mlan_ds_radio_cfg *)pioctl_req->pbuf;
6419 if (pioctl_req->action == MLAN_ACT_SET) {
6420 infra_band = radio_cfg->param.band_cfg.config_bands;
6421 adhoc_band = radio_cfg->param.band_cfg.adhoc_start_band;
6422 adhoc_channel = radio_cfg->param.band_cfg.adhoc_channel;
6423
6424 /* SET Infra band */
6425 if ((infra_band | pmadapter->fw_bands) & ~pmadapter->fw_bands) {
6426 pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
6427 LEAVE();
6428 return MLAN_STATUS_FAILURE;
6429 }
6430
6431 /* SET Ad-hoc Band */
6432 if ((adhoc_band | pmadapter->fw_bands) & ~pmadapter->fw_bands) {
6433 pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
6434 LEAVE();
6435 return MLAN_STATUS_FAILURE;
6436 }
6437 if (!adhoc_band)
6438 adhoc_band = pmadapter->adhoc_start_band;
6439
6440 for (i = 0; i < pmadapter->priv_num; i++) {
6441 if (pmadapter->priv[i] &&
6442 pmadapter->priv[i] != pmpriv &&
6443 GET_BSS_ROLE(pmadapter->priv[i]) ==
6444 MLAN_BSS_ROLE_STA)
6445 global_band |=
6446 (t_u32)pmadapter->priv[i]->config_bands;
6447 }
6448 global_band |= infra_band;
6449
6450 if (wlan_set_regiontable(pmpriv, (t_u8)pmadapter->region_code,
6451 global_band | adhoc_band)) {
6452 pioctl_req->status_code = MLAN_ERROR_IOCTL_FAIL;
6453 LEAVE();
6454 return MLAN_STATUS_FAILURE;
6455 }
6456 #ifdef STA_SUPPORT
6457 if (wlan_11d_set_universaltable(pmpriv,
6458 global_band | adhoc_band)) {
6459 pioctl_req->status_code = MLAN_ERROR_IOCTL_FAIL;
6460 LEAVE();
6461 return MLAN_STATUS_FAILURE;
6462 }
6463 #endif
6464 pmpriv->config_bands = infra_band;
6465 pmadapter->config_bands = global_band;
6466
6467 pmadapter->adhoc_start_band = adhoc_band;
6468 pmpriv->intf_state_11h.adhoc_auto_sel_chan = MFALSE;
6469
6470 #ifdef STA_SUPPORT
6471 /*
6472 * If no adhoc_channel is supplied verify if the existing
6473 * adhoc channel compiles with new adhoc_band
6474 */
6475 if (!adhoc_channel) {
6476 if (!wlan_find_cfp_by_band_and_channel(
6477 pmadapter, pmadapter->adhoc_start_band,
6478 pmpriv->adhoc_channel)) {
6479 /* Pass back the default channel */
6480 radio_cfg->param.band_cfg.adhoc_channel =
6481 DEFAULT_AD_HOC_CHANNEL;
6482 if ((pmadapter->adhoc_start_band & BAND_A)) {
6483 radio_cfg->param.band_cfg.adhoc_channel =
6484 DEFAULT_AD_HOC_CHANNEL_A;
6485 }
6486 }
6487 } else {
6488 /* Return error if adhoc_band and adhoc_channel
6489 * combination is invalid
6490 */
6491 if (!wlan_find_cfp_by_band_and_channel(
6492 pmadapter, pmadapter->adhoc_start_band,
6493 (t_u16)adhoc_channel)) {
6494 pioctl_req->status_code =
6495 MLAN_ERROR_INVALID_PARAMETER;
6496 LEAVE();
6497 return MLAN_STATUS_FAILURE;
6498 }
6499 pmpriv->adhoc_channel = (t_u8)adhoc_channel;
6500 }
6501
6502 #endif
6503
6504 } else {
6505 /* Infra Bands */
6506 radio_cfg->param.band_cfg.config_bands = pmpriv->config_bands;
6507 /* Adhoc Band */
6508 radio_cfg->param.band_cfg.adhoc_start_band =
6509 pmadapter->adhoc_start_band;
6510 /* Adhoc Channel */
6511 radio_cfg->param.band_cfg.adhoc_channel = pmpriv->adhoc_channel;
6512 /* FW support Bands */
6513 radio_cfg->param.band_cfg.fw_bands = pmadapter->fw_bands;
6514 PRINTM(MINFO, "Global config band = %d\n",
6515 pmadapter->config_bands);
6516 #ifdef STA_SUPPORT
6517 #endif
6518 }
6519
6520 LEAVE();
6521 return MLAN_STATUS_SUCCESS;
6522 }
6523
6524 /**
6525 * @brief Rx Abort Cfg
6526 *
6527 * @param pmadapter A pointer to mlan_adapter structure
6528 * @param pioctl_req A pointer to ioctl request buffer
6529 *
6530 * @return MLAN_STATUS_PENDING --success, otherwise fail
6531 */
wlan_misc_ioctl_rxabortcfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)6532 mlan_status wlan_misc_ioctl_rxabortcfg(pmlan_adapter pmadapter,
6533 pmlan_ioctl_req pioctl_req)
6534 {
6535 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
6536 mlan_ds_misc_cfg *pmisc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
6537 mlan_status ret = MLAN_STATUS_SUCCESS;
6538 t_u16 cmd_action = 0;
6539
6540 ENTER();
6541
6542 if (pioctl_req->action == MLAN_ACT_SET)
6543 cmd_action = HostCmd_ACT_GEN_SET;
6544 else
6545 cmd_action = HostCmd_ACT_GEN_GET;
6546 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_RX_ABORT_CFG, cmd_action, 0,
6547 (t_void *)pioctl_req,
6548 &(pmisc->param.rx_abort_cfg));
6549 if (ret == MLAN_STATUS_SUCCESS)
6550 ret = MLAN_STATUS_PENDING;
6551
6552 LEAVE();
6553 return ret;
6554 }
6555 /**
6556 * @brief Rx Abort Cfg ext
6557 *
6558 * @param pmadapter A pointer to mlan_adapter structure
6559 * @param pioctl_req A pointer to ioctl request buffer
6560 *
6561 * @return MLAN_STATUS_PENDING --success, otherwise fail
6562 */
wlan_misc_ioctl_rxabortcfg_ext(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)6563 mlan_status wlan_misc_ioctl_rxabortcfg_ext(pmlan_adapter pmadapter,
6564 pmlan_ioctl_req pioctl_req)
6565 {
6566 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
6567 mlan_ds_misc_cfg *pmisc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
6568 mlan_status ret = MLAN_STATUS_SUCCESS;
6569 t_u16 cmd_action = 0;
6570
6571 ENTER();
6572
6573 if (pioctl_req->action == MLAN_ACT_SET)
6574 cmd_action = HostCmd_ACT_GEN_SET;
6575 else
6576 cmd_action = HostCmd_ACT_GEN_GET;
6577 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_RX_ABORT_CFG_EXT, cmd_action,
6578 0, (t_void *)pioctl_req,
6579 &(pmisc->param.rx_abort_cfg_ext));
6580 if (ret == MLAN_STATUS_SUCCESS)
6581 ret = MLAN_STATUS_PENDING;
6582
6583 LEAVE();
6584 return ret;
6585 }
6586
6587 /**
6588 * @brief Dot11mc unassociated FTM CFG
6589 *
6590 * @param pmadapter A pointer to mlan_adapter structure
6591 * @param pioctl_req A pointer to ioctl request buffer
6592 *
6593 * @return MLAN_STATUS_PENDING --success, otherwise fail
6594 */
wlan_misc_ioctl_dot11mc_unassoc_ftm_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)6595 mlan_status wlan_misc_ioctl_dot11mc_unassoc_ftm_cfg(pmlan_adapter pmadapter,
6596 pmlan_ioctl_req pioctl_req)
6597 {
6598 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
6599 mlan_ds_misc_cfg *pmisc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
6600 mlan_status ret = MLAN_STATUS_SUCCESS;
6601 t_u16 cmd_action = 0;
6602
6603 ENTER();
6604
6605 if (pioctl_req->action == MLAN_ACT_SET)
6606 cmd_action = HostCmd_ACT_GEN_SET;
6607 else
6608 cmd_action = HostCmd_ACT_GEN_GET;
6609 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_DOT11MC_UNASSOC_FTM_CFG,
6610 cmd_action, 0, (t_void *)pioctl_req,
6611 &(pmisc->param.dot11mc_unassoc_ftm_cfg));
6612 if (ret == MLAN_STATUS_SUCCESS)
6613 ret = MLAN_STATUS_PENDING;
6614
6615 LEAVE();
6616 return ret;
6617 }
6618
6619 /**
6620 * @brief Tx ampdu protection mode
6621 *
6622 * @param pmadapter A pointer to mlan_adapter structure
6623 * @param pioctl_req A pointer to ioctl request buffer
6624 *
6625 * @return MLAN_STATUS_PENDING --success, otherwise fail
6626 */
wlan_misc_ioctl_tx_ampdu_prot_mode(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)6627 mlan_status wlan_misc_ioctl_tx_ampdu_prot_mode(pmlan_adapter pmadapter,
6628 pmlan_ioctl_req pioctl_req)
6629 {
6630 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
6631 mlan_ds_misc_cfg *pmisc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
6632 mlan_status ret = MLAN_STATUS_SUCCESS;
6633 t_u16 cmd_action = 0;
6634
6635 ENTER();
6636
6637 if (pioctl_req->action == MLAN_ACT_SET)
6638 cmd_action = HostCmd_ACT_GEN_SET;
6639 else
6640 cmd_action = HostCmd_ACT_GEN_GET;
6641 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_AMPDU_PROT_MODE,
6642 cmd_action, 0, (t_void *)pioctl_req,
6643 &(pmisc->param.tx_ampdu_prot_mode));
6644 if (ret == MLAN_STATUS_SUCCESS)
6645 ret = MLAN_STATUS_PENDING;
6646
6647 LEAVE();
6648 return ret;
6649 }
6650
6651 /**
6652 * @brief Rate adapt config
6653 *
6654 * @param pmadapter A pointer to mlan_adapter structure
6655 * @param pioctl_req A pointer to ioctl request buffer
6656 *
6657 * @return MLAN_STATUS_PENDING --success, otherwise fail
6658 */
wlan_misc_ioctl_rate_adapt_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)6659 mlan_status wlan_misc_ioctl_rate_adapt_cfg(pmlan_adapter pmadapter,
6660 pmlan_ioctl_req pioctl_req)
6661 {
6662 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
6663 mlan_ds_misc_cfg *pmisc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
6664 mlan_status ret = MLAN_STATUS_SUCCESS;
6665 t_u16 cmd_action = 0;
6666
6667 ENTER();
6668
6669 if (pioctl_req->action == MLAN_ACT_SET)
6670 cmd_action = HostCmd_ACT_GEN_SET;
6671 else
6672 cmd_action = HostCmd_ACT_GEN_GET;
6673 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_RATE_ADAPT_CFG, cmd_action,
6674 0, (t_void *)pioctl_req,
6675 &(pmisc->param.rate_adapt_cfg));
6676 if (ret == MLAN_STATUS_SUCCESS)
6677 ret = MLAN_STATUS_PENDING;
6678
6679 LEAVE();
6680 return ret;
6681 }
6682
6683 /**
6684 * @brief CCK Desense config
6685 *
6686 * @param pmadapter A pointer to mlan_adapter structure
6687 * @param pioctl_req A pointer to ioctl request buffer
6688 *
6689 * @return MLAN_STATUS_PENDING --success, otherwise fail
6690 */
wlan_misc_ioctl_cck_desense_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)6691 mlan_status wlan_misc_ioctl_cck_desense_cfg(pmlan_adapter pmadapter,
6692 pmlan_ioctl_req pioctl_req)
6693 {
6694 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
6695 mlan_ds_misc_cfg *pmisc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
6696 mlan_status ret = MLAN_STATUS_SUCCESS;
6697 t_u16 cmd_action = 0;
6698
6699 ENTER();
6700
6701 if (pioctl_req->action == MLAN_ACT_SET)
6702 cmd_action = HostCmd_ACT_GEN_SET;
6703 else
6704 cmd_action = HostCmd_ACT_GEN_GET;
6705 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_CCK_DESENSE_CFG, cmd_action,
6706 0, (t_void *)pioctl_req,
6707 &(pmisc->param.cck_desense_cfg));
6708 if (ret == MLAN_STATUS_SUCCESS)
6709 ret = MLAN_STATUS_PENDING;
6710
6711 LEAVE();
6712 return ret;
6713 }
6714
6715 /**
6716 * @brief config dynamic bandwidth
6717 *
6718 * @param pmadapter A pointer to mlan_adapter structure
6719 * @param pioctl_req Pointer to the IOCTL request buffer
6720 *
6721 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
6722 */
wlan_misc_ioctl_dyn_bw(pmlan_adapter pmadapter,mlan_ioctl_req * pioctl_req)6723 mlan_status wlan_misc_ioctl_dyn_bw(pmlan_adapter pmadapter,
6724 mlan_ioctl_req *pioctl_req)
6725 {
6726 pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
6727 mlan_ds_misc_cfg *misc = MNULL;
6728 t_u16 cmd_action = 0;
6729 mlan_status ret = MLAN_STATUS_SUCCESS;
6730
6731 ENTER();
6732
6733 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
6734
6735 if (pioctl_req->action == MLAN_ACT_SET)
6736 cmd_action = HostCmd_ACT_GEN_SET;
6737 else if (pioctl_req->action == MLAN_ACT_GET)
6738 cmd_action = HostCmd_ACT_GEN_GET;
6739 else {
6740 PRINTM(MERROR, "Unsupported cmd_action\n");
6741 LEAVE();
6742 return MLAN_STATUS_FAILURE;
6743 }
6744
6745 /* Send request to firmware */
6746 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_DYN_BW, cmd_action, 0,
6747 (t_void *)pioctl_req, &misc->param.dyn_bw);
6748
6749 if (ret == MLAN_STATUS_SUCCESS)
6750 ret = MLAN_STATUS_PENDING;
6751
6752 LEAVE();
6753 return ret;
6754 }
6755
6756 /**
6757 * @brief Set/Get low power mode configuration parameter
6758 *
6759 * @param pmadapter A pointer to mlan_adapter structure
6760 * @param pioctl_req A pointer to ioctl request buffer
6761 *
6762 * @return MLAN_STATUS_SUCCESS --success
6763 */
wlan_power_ioctl_set_get_lpm(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)6764 mlan_status wlan_power_ioctl_set_get_lpm(pmlan_adapter pmadapter,
6765 pmlan_ioctl_req pioctl_req)
6766 {
6767 mlan_status ret = MLAN_STATUS_SUCCESS;
6768 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
6769 mlan_ds_power_cfg *pm_cfg = MNULL;
6770 t_u16 cmd_action = 0, lpm = 0;
6771
6772 ENTER();
6773
6774 pm_cfg = (mlan_ds_power_cfg *)pioctl_req->pbuf;
6775 cmd_action = HostCmd_ACT_GEN_GET;
6776 if (pioctl_req->action == MLAN_ACT_SET) {
6777 cmd_action = HostCmd_ACT_GEN_SET;
6778 lpm = pm_cfg->param.lpm;
6779 }
6780
6781 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_LOW_POWER_MODE_CFG,
6782 cmd_action, 0, (t_void *)pioctl_req, &lpm);
6783
6784 if (ret == MLAN_STATUS_SUCCESS)
6785 ret = MLAN_STATUS_PENDING;
6786
6787 LEAVE();
6788 return ret;
6789 }
6790
6791 /**
6792 * @brief RF Test Mode config
6793 *
6794 * @param pmadapter A pointer to mlan_adapter structure
6795 * @param pioctl_req A pointer to ioctl request buffer
6796 *
6797 * @return MLAN_STATUS_PENDING --success, otherwise fail
6798 */
wlan_misc_ioctl_rf_test_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)6799 mlan_status wlan_misc_ioctl_rf_test_cfg(pmlan_adapter pmadapter,
6800 pmlan_ioctl_req pioctl_req)
6801 {
6802 mlan_private *pmpriv = MNULL;
6803 mlan_ds_misc_cfg *pmisc = MNULL;
6804 mlan_status ret = MLAN_STATUS_FAILURE;
6805 t_u16 cmd_action = 0;
6806
6807 ENTER();
6808
6809 if (!pioctl_req)
6810 goto done;
6811
6812 pmpriv = pmadapter->priv[pioctl_req->bss_index];
6813 pmisc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
6814
6815 switch (pmisc->sub_command) {
6816 case MLAN_OID_MISC_RF_TEST_GENERIC:
6817 if (pioctl_req->action == MLAN_ACT_SET)
6818 cmd_action = HostCmd_ACT_GEN_SET;
6819 else
6820 cmd_action = HostCmd_ACT_GEN_GET;
6821 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MFG_COMMAND,
6822 cmd_action, 0, (t_void *)pioctl_req,
6823 &(pmisc->param.mfg_generic_cfg));
6824 break;
6825 case MLAN_OID_MISC_RF_TEST_TX_CONT:
6826 if (pioctl_req->action == MLAN_ACT_SET)
6827 cmd_action = HostCmd_ACT_GEN_SET;
6828 else {
6829 PRINTM(MERROR, "Unsupported cmd_action\n");
6830 ret = MLAN_STATUS_FAILURE;
6831 goto done;
6832 }
6833 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MFG_COMMAND,
6834 cmd_action, 0, (t_void *)pioctl_req,
6835 &(pmisc->param.mfg_tx_cont));
6836 break;
6837 case MLAN_OID_MISC_RF_TEST_TX_FRAME:
6838 if (pioctl_req->action == MLAN_ACT_SET)
6839 cmd_action = HostCmd_ACT_GEN_SET;
6840 else {
6841 PRINTM(MERROR, "Unsupported cmd_action\n");
6842 ret = MLAN_STATUS_FAILURE;
6843 goto done;
6844 }
6845 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MFG_COMMAND,
6846 cmd_action, 0, (t_void *)pioctl_req,
6847 &(pmisc->param.mfg_tx_frame2));
6848 break;
6849 case MLAN_OID_MISC_RF_TEST_HE_POWER:
6850 if (pioctl_req->action == MLAN_ACT_SET)
6851 cmd_action = HostCmd_ACT_GEN_SET;
6852 else {
6853 PRINTM(MERROR, "Unsupported cmd_action\n");
6854 ret = MLAN_STATUS_FAILURE;
6855 goto done;
6856 }
6857 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MFG_COMMAND,
6858 cmd_action, 0, (t_void *)pioctl_req,
6859 &(pmisc->param.mfg_he_power));
6860 break;
6861 }
6862
6863 if (ret == MLAN_STATUS_SUCCESS)
6864 ret = MLAN_STATUS_PENDING;
6865 done:
6866 LEAVE();
6867 return ret;
6868 }
6869
6870 /**
6871 * @brief Range ext mode config
6872 *
6873 * @param pmadapter A pointer to mlan_adapter structure
6874 * @param pioctl_req A pointer to ioctl request buffer
6875 *
6876 * @return MLAN_STATUS_PENDING --success, otherwise fail
6877 */
wlan_misc_ioctl_range_ext(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)6878 mlan_status wlan_misc_ioctl_range_ext(pmlan_adapter pmadapter,
6879 pmlan_ioctl_req pioctl_req)
6880 {
6881 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
6882 mlan_ds_misc_cfg *pmisc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
6883 mlan_status ret = MLAN_STATUS_SUCCESS;
6884 t_u16 cmd_action = 0;
6885
6886 ENTER();
6887
6888 if (pioctl_req->action == MLAN_ACT_SET)
6889 cmd_action = HostCmd_ACT_GEN_SET;
6890 else
6891 cmd_action = HostCmd_ACT_GEN_GET;
6892 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_RANGE_EXT, cmd_action, 0,
6893 (t_void *)pioctl_req,
6894 &(pmisc->param.range_ext_mode));
6895 if (ret == MLAN_STATUS_SUCCESS)
6896 ret = MLAN_STATUS_PENDING;
6897
6898 LEAVE();
6899 return ret;
6900 }
6901
6902 #ifdef UAP_SUPPORT
6903 /**
6904 * @brief set wacp mode
6905 *
6906 * @param pmadapter A pointer to mlan_adapter structure
6907 * @param pioctl_req A pointer to ioctl request buffer
6908 *
6909 * @return MLAN_STATUS_PENDING --success, otherwise fail
6910 */
wlan_misc_ioctl_wacp_mode(IN pmlan_adapter pmadapter,IN pmlan_ioctl_req pioctl_req)6911 mlan_status wlan_misc_ioctl_wacp_mode(IN pmlan_adapter pmadapter,
6912 IN pmlan_ioctl_req pioctl_req)
6913 {
6914 mlan_status ret = MLAN_STATUS_SUCCESS;
6915 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
6916 mlan_ds_misc_cfg *misc = MNULL;
6917 t_u16 cmd_action;
6918
6919 ENTER();
6920
6921 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
6922
6923 if (pioctl_req->action == MLAN_ACT_SET)
6924 cmd_action = HostCmd_ACT_GEN_SET;
6925 else
6926 cmd_action = HostCmd_ACT_GEN_GET;
6927
6928 ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_SYS_CONFIGURE, cmd_action,
6929 0, (t_void *)pioctl_req,
6930 (t_void *)&misc->param.wacp_mode);
6931
6932 if (ret == MLAN_STATUS_SUCCESS)
6933 ret = MLAN_STATUS_PENDING;
6934
6935 LEAVE();
6936 return ret;
6937 }
6938 #endif
6939
wlan_misc_ioctl_get_sensor_temp(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)6940 mlan_status wlan_misc_ioctl_get_sensor_temp(pmlan_adapter pmadapter,
6941 pmlan_ioctl_req pioctl_req)
6942 {
6943 mlan_status ret = MLAN_STATUS_SUCCESS;
6944 t_u16 cmd_action = 0;
6945 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
6946
6947 ENTER();
6948
6949 if (pioctl_req->action == MLAN_ACT_GET)
6950 cmd_action = HostCmd_ACT_GEN_GET;
6951 else {
6952 PRINTM(MERROR, " Sensor temp only support get operation \n");
6953 LEAVE();
6954 return MLAN_STATUS_FAILURE;
6955 }
6956
6957 /* Send request to firmware */
6958 ret = wlan_prepare_cmd(pmpriv, HostCmd_DS_GET_SENSOR_TEMP, cmd_action,
6959 0, (t_void *)pioctl_req, MNULL);
6960
6961 if (ret == MLAN_STATUS_SUCCESS)
6962 ret = MLAN_STATUS_PENDING;
6963
6964 LEAVE();
6965 return ret;
6966 }
6967