1 /**
2 * @file mlan_cmdevt.c
3 *
4 * @brief This file contains the handling of CMD/EVENT in MLAN
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/12/2009: initial version
27 ************************************************************/
28 #include "mlan.h"
29 #ifdef STA_SUPPORT
30 #include "mlan_join.h"
31 #endif
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 #include "mlan_11h.h"
40 #ifdef SDIO
41 #include "mlan_sdio.h"
42 #endif /* SDIO */
43 #ifdef PCIE
44 #include "mlan_pcie.h"
45 #endif /* PCIE */
46 #include "mlan_init.h"
47
48 /********************************************************
49 Local Variables
50 ********************************************************/
51
52 /*******************************************************
53 Global Variables
54 ********************************************************/
55
56 /********************************************************
57 Local Functions
58 ********************************************************/
59 #ifdef STA_SUPPORT
60 /**
61 * @brief This function check if the command was cancel scan command
62 *
63 * @param pcmd A pointer to HostCmd_DS_COMMAND structure
64 * @return N/A
65 */
wlan_is_cancel_scan_cmd(HostCmd_DS_COMMAND * pcmd)66 static t_u8 wlan_is_cancel_scan_cmd(HostCmd_DS_COMMAND *pcmd)
67 {
68 HostCmd_DS_802_11_SCAN_EXT *pext_scan_cmd = &pcmd->params.ext_scan;
69 if (pext_scan_cmd->ext_scan_type == EXT_SCAN_CANCEL)
70 return MTRUE;
71 else
72 return MFALSE;
73 }
74 /**
75 * @brief This function inserts scan command node to scan_pending_q.
76 *
77 * @param pmpriv A pointer to mlan_private structure
78 * @param pcmd_node A pointer to cmd_ctrl_node structure
79 * @return N/A
80 */
wlan_queue_scan_cmd(mlan_private * pmpriv,cmd_ctrl_node * pcmd_node)81 static t_void wlan_queue_scan_cmd(mlan_private *pmpriv,
82 cmd_ctrl_node *pcmd_node)
83 {
84 mlan_adapter *pmadapter = pmpriv->adapter;
85
86 ENTER();
87
88 if (pcmd_node == MNULL)
89 goto done;
90 pcmd_node->cmd_flag |= CMD_F_SCAN;
91
92 util_enqueue_list_tail(pmadapter->pmoal_handle,
93 &pmadapter->scan_pending_q,
94 (pmlan_linked_list)pcmd_node, MNULL, MNULL);
95
96 done:
97 LEAVE();
98 }
99
100 /**
101 * @brief This function check if cmd allowed to send to firmware
102 * during scan
103 *
104 * @param cmd_id cmd id
105 *
106 * @return MTRUE/MFALSE
107 */
wlan_is_cmd_allowed_during_scan(t_u16 cmd_id)108 static t_u8 wlan_is_cmd_allowed_during_scan(t_u16 cmd_id)
109 {
110 t_u8 ret = MTRUE;
111 ENTER();
112 switch (cmd_id) {
113 case HostCmd_CMD_FUNC_INIT:
114 case HostCmd_CMD_CFG_DATA:
115 case HostCmd_CMD_REGION_POWER_CFG:
116 case HostCmd_CHANNEL_TRPC_CONFIG:
117 case HostCmd_CMD_FUNC_SHUTDOWN:
118 case HostCmd_CMD_802_11_ASSOCIATE:
119 case HostCmd_CMD_802_11_DEAUTHENTICATE:
120 case HostCmd_CMD_802_11_DISASSOCIATE:
121 case HostCmd_CMD_802_11_AD_HOC_START:
122 case HostCmd_CMD_802_11_AD_HOC_JOIN:
123 case HostCmd_CMD_802_11_AD_HOC_STOP:
124 case HostCmd_CMD_11N_ADDBA_REQ:
125 case HostCmd_CMD_11N_ADDBA_RSP:
126 case HostCmd_CMD_11N_DELBA:
127 case HostCmd_CMD_802_11_REMAIN_ON_CHANNEL:
128 case HostCmd_CMD_TDLS_CONFIG:
129 case HostCmd_CMD_TDLS_OPERATION:
130 case HostCmd_CMD_SOFT_RESET:
131 #ifdef UAP_SUPPORT
132 case HOST_CMD_APCMD_SYS_RESET:
133 case HOST_CMD_APCMD_BSS_START:
134 case HOST_CMD_APCMD_BSS_STOP:
135 case HOST_CMD_APCMD_STA_DEAUTH:
136 #endif
137 case HostCmd_CMD_802_11_BG_SCAN_CONFIG:
138 case HostCMD_APCMD_ACS_SCAN:
139 ret = MFALSE;
140 break;
141 default:
142 break;
143 }
144 LEAVE();
145 return ret;
146 }
147
148 /**
149 * @brief This function move the cmd from ext_cmd_pending_q to
150 * cmd_pending_q
151 *
152 * @param cmd_id cmd id
153 *
154 * @return MTRUE/MFALSE
155 */
wlan_move_cmd_to_cmd_pending_q(pmlan_adapter pmadapter)156 t_void wlan_move_cmd_to_cmd_pending_q(pmlan_adapter pmadapter)
157 {
158 cmd_ctrl_node *pcmd_node = MNULL;
159
160 ENTER();
161
162 wlan_request_cmd_lock(pmadapter);
163 while ((pcmd_node = (cmd_ctrl_node *)util_peek_list(
164 pmadapter->pmoal_handle, &pmadapter->ext_cmd_pending_q,
165 MNULL, MNULL))) {
166 util_unlink_list(pmadapter->pmoal_handle,
167 &pmadapter->ext_cmd_pending_q,
168 (pmlan_linked_list)pcmd_node, MNULL, MNULL);
169 wlan_insert_cmd_to_pending_q(pmadapter, pcmd_node, MTRUE);
170 }
171 wlan_release_cmd_lock(pmadapter);
172 LEAVE();
173 }
174
175 /**
176 * @brief This function inserts scan command node to scan_cmd_pending_q.
177 *
178 * @param pmpriv A pointer to mlan_private structure
179 * @param pcmd_node A pointer to cmd_ctrl_node structure
180 * @return N/A
181 */
wlan_queue_cmd_to_ext_cmd_pending_queue(mlan_private * pmpriv,cmd_ctrl_node * pcmd_node)182 static t_void wlan_queue_cmd_to_ext_cmd_pending_queue(mlan_private *pmpriv,
183 cmd_ctrl_node *pcmd_node)
184 {
185 mlan_adapter *pmadapter = pmpriv->adapter;
186
187 ENTER();
188
189 if (pcmd_node == MNULL)
190 goto done;
191
192 util_enqueue_list_tail(pmadapter->pmoal_handle,
193 &pmadapter->ext_cmd_pending_q,
194 (pmlan_linked_list)pcmd_node, MNULL, MNULL);
195
196 done:
197 LEAVE();
198 }
199
200 /**
201 * @brief Internal function used to flush the scan cmd pending queue
202 *
203 * @param pmadapter A pointer to mlan_adapter structure
204 *
205 * @return N/A
206 */
wlan_flush_ext_cmd_pending_queue(pmlan_adapter pmadapter)207 t_void wlan_flush_ext_cmd_pending_queue(pmlan_adapter pmadapter)
208 {
209 cmd_ctrl_node *pcmd_node = MNULL;
210 HostCmd_DS_COMMAND *pcmd = MNULL;
211 mlan_ioctl_req *pioctl_buf = MNULL;
212 pmlan_callbacks pcb = &pmadapter->callbacks;
213 ENTER();
214
215 wlan_request_cmd_lock(pmadapter);
216 while ((pcmd_node = (cmd_ctrl_node *)util_peek_list(
217 pmadapter->pmoal_handle, &pmadapter->ext_cmd_pending_q,
218 MNULL, MNULL))) {
219 util_unlink_list(pmadapter->pmoal_handle,
220 &pmadapter->ext_cmd_pending_q,
221 (pmlan_linked_list)pcmd_node, MNULL, MNULL);
222 pcmd = (HostCmd_DS_COMMAND *)(pcmd_node->cmdbuf->pbuf +
223 pcmd_node->cmdbuf->data_offset);
224 PRINTM(MCMND, "flush ext_cmd_pending_queue: cmd 0x%02x\n",
225 wlan_le16_to_cpu(pcmd->command));
226 if (pcmd_node->pioctl_buf) {
227 pioctl_buf = (mlan_ioctl_req *)pcmd_node->pioctl_buf;
228 pcmd_node->pioctl_buf = MNULL;
229 pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL;
230 pcb->moal_ioctl_complete(pmadapter->pmoal_handle,
231 pioctl_buf,
232 MLAN_STATUS_FAILURE);
233 }
234 wlan_insert_cmd_to_free_q(pmadapter, pcmd_node);
235 }
236 wlan_release_cmd_lock(pmadapter);
237 LEAVE();
238 }
239
240 /**
241 * @brief This function inserts command node to scan_pending_q or
242 * cmd_pending_q
243 *
244 * @param pmpriv A pointer to mlan_private structure
245 * @param pcmd_node A pointer to cmd_ctrl_node structure
246 * @return N/A
247 */
248
wlan_queue_cmd(mlan_private * pmpriv,cmd_ctrl_node * pcmd_node,t_u16 cmd_no)249 static t_void wlan_queue_cmd(mlan_private *pmpriv, cmd_ctrl_node *pcmd_node,
250 t_u16 cmd_no)
251 {
252 ENTER();
253 if (pmpriv->adapter->scan_processing &&
254 pmpriv->adapter->ext_scan_type == EXT_SCAN_ENHANCE) {
255 if (MFALSE == wlan_is_cmd_allowed_during_scan(cmd_no)) {
256 PRINTM(MCMND, "QUEUE_CMD: cmd=0x%x ext_cmd_pending_q\n",
257 cmd_no);
258 wlan_queue_cmd_to_ext_cmd_pending_queue(pmpriv,
259 pcmd_node);
260 return;
261 }
262 }
263 wlan_insert_cmd_to_pending_q(pmpriv->adapter, pcmd_node, MTRUE);
264 LEAVE();
265 }
266
267 /**
268 * @brief Internal function used to flush the scan pending queue
269 *
270 * @param pmadapter A pointer to mlan_adapter structure
271 *
272 * @return N/A
273 */
wlan_check_scan_queue(pmlan_adapter pmadapter)274 static void wlan_check_scan_queue(pmlan_adapter pmadapter)
275 {
276 cmd_ctrl_node *pcmd_node = MNULL;
277 t_u16 num = 0;
278
279 pcmd_node = (cmd_ctrl_node *)util_peek_list(pmadapter->pmoal_handle,
280 &pmadapter->scan_pending_q,
281 MNULL, MNULL);
282 if (!pcmd_node) {
283 PRINTM(MERROR, "No pending scan command\n");
284 return;
285 }
286 while (pcmd_node != (cmd_ctrl_node *)&pmadapter->scan_pending_q) {
287 num++;
288 pcmd_node = pcmd_node->pnext;
289 }
290 PRINTM(MERROR, "num_pending_scan=%d\n", num);
291 }
292 #endif
293
294 /**
295 * @brief This function will dump the pending commands id
296 *
297 * @param pmadapter A pointer to mlan_adapter
298 *
299 * @return N/A
300 */
wlan_dump_pending_commands(pmlan_adapter pmadapter)301 static void wlan_dump_pending_commands(pmlan_adapter pmadapter)
302 {
303 cmd_ctrl_node *pcmd_node = MNULL;
304 HostCmd_DS_COMMAND *pcmd;
305
306 ENTER();
307 wlan_request_cmd_lock(pmadapter);
308 pcmd_node = (cmd_ctrl_node *)util_peek_list(pmadapter->pmoal_handle,
309 &pmadapter->cmd_pending_q,
310 MNULL, MNULL);
311 if (!pcmd_node) {
312 wlan_release_cmd_lock(pmadapter);
313 LEAVE();
314 return;
315 }
316 while (pcmd_node != (cmd_ctrl_node *)&pmadapter->cmd_pending_q) {
317 pcmd = (HostCmd_DS_COMMAND *)(pcmd_node->cmdbuf->pbuf +
318 pcmd_node->cmdbuf->data_offset);
319 PRINTM(MERROR, "pending command id: 0x%x ioctl_buf=%p\n",
320 wlan_le16_to_cpu(pcmd->command), pcmd_node->pioctl_buf);
321 pcmd_node = pcmd_node->pnext;
322 }
323 #ifdef STA_SUPPORT
324 wlan_check_scan_queue(pmadapter);
325 #endif
326 wlan_release_cmd_lock(pmadapter);
327 LEAVE();
328 return;
329 }
330
331 #define REASON_CODE_NO_CMD_NODE 1
332 #define REASON_CODE_CMD_TIMEOUT 2
333 #define REASON_CODE_CMD_TO_CARD_FAILURE 3
334 #define REASON_CODE_EXT_SCAN_TIMEOUT 4
335 /**
336 * @brief This function dump debug info
337 *
338 * @return N/A
339 */
wlan_dump_info(mlan_adapter * pmadapter,t_u8 reason)340 static t_void wlan_dump_info(mlan_adapter *pmadapter, t_u8 reason)
341 {
342 cmd_ctrl_node *pcmd_node = MNULL;
343 #ifdef DEBUG_LEVEL1
344 t_u32 sec = 0, usec = 0;
345 #endif
346 t_u16 i;
347 #ifdef SDIO
348 t_u8 j;
349 t_u8 mp_aggr_pkt_limit;
350 #endif
351 t_u16 cmd_id, cmd_act;
352 mlan_private *pmpriv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);
353
354 ENTER();
355
356 PRINTM(MERROR, "------------Dump info-----------\n", reason);
357 switch (reason) {
358 case REASON_CODE_NO_CMD_NODE:
359 pmadapter->dbg.num_no_cmd_node++;
360 PRINTM(MERROR, "No Free command node\n");
361 break;
362 case REASON_CODE_CMD_TIMEOUT:
363 PRINTM(MERROR, "Commmand Timeout\n");
364 break;
365 case REASON_CODE_CMD_TO_CARD_FAILURE:
366 PRINTM(MERROR, "Command to card failure\n");
367 break;
368 case REASON_CODE_EXT_SCAN_TIMEOUT:
369 PRINTM(MERROR, "EXT_SCAN_STATUS event Timeout\n");
370 break;
371 default:
372 break;
373 }
374 if ((reason == REASON_CODE_NO_CMD_NODE) &&
375 (pmadapter->dbg.num_no_cmd_node > 1)) {
376 if (pmadapter->dbg.num_no_cmd_node >= 5) {
377 if (pmpriv)
378 wlan_recv_event(pmpriv,
379 MLAN_EVENT_ID_DRV_DBG_DUMP,
380 MNULL);
381 }
382 LEAVE();
383 return;
384 }
385 wlan_dump_pending_commands(pmadapter);
386 if (reason != REASON_CODE_CMD_TIMEOUT) {
387 if (!pmadapter->curr_cmd) {
388 PRINTM(MERROR, "CurCmd Empty\n");
389 } else {
390 pcmd_node = pmadapter->curr_cmd;
391 cmd_id = pmadapter->dbg.last_cmd_id
392 [pmadapter->dbg.last_cmd_index];
393 cmd_act = pmadapter->dbg.last_cmd_act
394 [pmadapter->dbg.last_cmd_index];
395 PRINTM_GET_SYS_TIME(MERROR, &sec, &usec);
396 PRINTM(MERROR,
397 "Current cmd id (%lu.%06lu) = 0x%x, act = 0x%x\n",
398 sec, usec, cmd_id, cmd_act);
399 #if defined(SDIO) || defined(PCIE)
400 if (!IS_USB(pmadapter->card_type) &&
401 pcmd_node->cmdbuf) {
402 t_u8 *pcmd_buf;
403 pcmd_buf = pcmd_node->cmdbuf->pbuf +
404 pcmd_node->cmdbuf->data_offset +
405 pmadapter->ops.intf_header_len;
406 for (i = 0; i < 16; i++)
407 PRINTM(MERROR, "%02x ", *pcmd_buf++);
408 PRINTM(MERROR, "\n");
409 }
410 #endif
411 pmpriv = pcmd_node->priv;
412 if (pmpriv)
413 PRINTM(MERROR, "BSS type = %d BSS role= %d\n",
414 pmpriv->bss_type, pmpriv->bss_role);
415 }
416 }
417 PRINTM(MERROR, "mlan_processing =%d\n", pmadapter->mlan_processing);
418 PRINTM(MERROR, "main_lock_flag =%d\n", pmadapter->main_lock_flag);
419 PRINTM(MERROR, "main_process_cnt =%d\n", pmadapter->main_process_cnt);
420 PRINTM(MERROR, "delay_task_flag =%d\n", pmadapter->delay_task_flag);
421 PRINTM(MERROR, "mlan_rx_processing =%d\n",
422 pmadapter->mlan_rx_processing);
423 PRINTM(MERROR, "rx_pkts_queued=%d\n", pmadapter->rx_pkts_queued);
424 PRINTM(MERROR, "more_task_flag = %d\n", pmadapter->more_task_flag);
425 PRINTM(MERROR, "num_cmd_timeout = %d\n", pmadapter->num_cmd_timeout);
426 PRINTM(MERROR, "last_cmd_index = %d\n", pmadapter->dbg.last_cmd_index);
427 PRINTM(MERROR, "last_cmd_id = ");
428 for (i = 0; i < DBG_CMD_NUM; i++)
429 PRINTM(MERROR, "0x%x ", pmadapter->dbg.last_cmd_id[i]);
430 PRINTM(MERROR, "\n");
431 PRINTM(MERROR, "last_cmd_act = ");
432 for (i = 0; i < DBG_CMD_NUM; i++)
433 PRINTM(MERROR, "0x%x ", pmadapter->dbg.last_cmd_act[i]);
434 PRINTM(MERROR, "\n");
435 PRINTM(MERROR, "last_cmd_resp_index = %d\n",
436 pmadapter->dbg.last_cmd_resp_index);
437 PRINTM(MERROR, "last_cmd_resp_id = ");
438 for (i = 0; i < DBG_CMD_NUM; i++)
439 PRINTM(MERROR, "0x%x ", pmadapter->dbg.last_cmd_resp_id[i]);
440 PRINTM(MERROR, "\n");
441 PRINTM(MERROR, "last_event_index = %d\n",
442 pmadapter->dbg.last_event_index);
443 PRINTM(MERROR, "last_event = ");
444 for (i = 0; i < DBG_CMD_NUM; i++)
445 PRINTM(MERROR, "0x%x ", pmadapter->dbg.last_event[i]);
446 PRINTM(MERROR, "\n");
447
448 PRINTM(MERROR, "num_data_h2c_failure = %d\n",
449 pmadapter->dbg.num_tx_host_to_card_failure);
450 PRINTM(MERROR, "num_cmd_h2c_failure = %d\n",
451 pmadapter->dbg.num_cmd_host_to_card_failure);
452 #ifdef SDIO
453 if (IS_SD(pmadapter->card_type)) {
454 PRINTM(MERROR, "num_data_c2h_failure = %d\n",
455 pmadapter->dbg.num_rx_card_to_host_failure);
456 PRINTM(MERROR, "num_cmdevt_c2h_failure = %d\n",
457 pmadapter->dbg.num_cmdevt_card_to_host_failure);
458 PRINTM(MERROR, "num_int_read_failure = %d\n",
459 pmadapter->dbg.num_int_read_failure);
460 PRINTM(MERROR, "last_int_status = %d\n",
461 pmadapter->dbg.last_int_status);
462 }
463 #endif
464 PRINTM(MERROR, "num_alloc_buffer_failure = %d\n",
465 pmadapter->dbg.num_alloc_buffer_failure);
466 PRINTM(MERROR, "num_pkt_dropped = %d\n",
467 pmadapter->dbg.num_pkt_dropped);
468 PRINTM(MERROR, "num_no_cmd_node = %d\n",
469 pmadapter->dbg.num_no_cmd_node);
470 PRINTM(MERROR, "num_event_deauth = %d\n",
471 pmadapter->dbg.num_event_deauth);
472 PRINTM(MERROR, "num_event_disassoc = %d\n",
473 pmadapter->dbg.num_event_disassoc);
474 PRINTM(MERROR, "num_event_link_lost = %d\n",
475 pmadapter->dbg.num_event_link_lost);
476 PRINTM(MERROR, "num_cmd_deauth = %d\n", pmadapter->dbg.num_cmd_deauth);
477 PRINTM(MERROR, "num_cmd_assoc_success = %d\n",
478 pmadapter->dbg.num_cmd_assoc_success);
479 PRINTM(MERROR, "num_cmd_assoc_failure = %d\n",
480 pmadapter->dbg.num_cmd_assoc_failure);
481 PRINTM(MERROR, "num_cons_assoc_failure = %d\n",
482 pmadapter->dbg.num_cons_assoc_failure);
483 PRINTM(MERROR, "cmd_resp_received=%d\n", pmadapter->cmd_resp_received);
484 PRINTM(MERROR, "event_received=%d\n", pmadapter->event_received);
485
486 PRINTM(MERROR, "max_tx_buf_size=%d\n", pmadapter->max_tx_buf_size);
487 PRINTM(MERROR, "tx_buf_size=%d\n", pmadapter->tx_buf_size);
488 PRINTM(MERROR, "curr_tx_buf_size=%d\n", pmadapter->curr_tx_buf_size);
489
490 PRINTM(MERROR, "data_sent=%d cmd_sent=%d\n", pmadapter->data_sent,
491 pmadapter->cmd_sent);
492
493 PRINTM(MERROR, "ps_mode=%d ps_state=%d\n", pmadapter->ps_mode,
494 pmadapter->ps_state);
495 PRINTM(MERROR, "wakeup_dev_req=%d wakeup_tries=%d wakeup_timeout=%d\n",
496 pmadapter->pm_wakeup_card_req, pmadapter->pm_wakeup_fw_try,
497 pmadapter->pm_wakeup_timeout);
498 PRINTM(MERROR, "hs_configured=%d hs_activated=%d\n",
499 pmadapter->is_hs_configured, pmadapter->hs_activated);
500 PRINTM(MERROR, "pps_uapsd_mode=%d sleep_pd=%d\n",
501 pmadapter->pps_uapsd_mode, pmadapter->sleep_period.period);
502 PRINTM(MERROR, "tx_lock_flag = %d\n", pmadapter->tx_lock_flag);
503 PRINTM(MERROR, "scan_processing = %d\n", pmadapter->scan_processing);
504 PRINTM(MERROR, "scan_state = 0x%x\n", pmadapter->scan_state);
505 PRINTM(MERROR, "bypass_pkt_count=%d\n", pmadapter->bypass_pkt_count);
506 #ifdef SDIO
507 if (IS_SD(pmadapter->card_type)) {
508 mp_aggr_pkt_limit = pmadapter->pcard_sd->mp_aggr_pkt_limit;
509 PRINTM(MERROR, "mp_rd_bitmap=0x%x curr_rd_port=0x%x\n",
510 pmadapter->pcard_sd->mp_rd_bitmap,
511 pmadapter->pcard_sd->curr_rd_port);
512 PRINTM(MERROR, "mp_wr_bitmap=0x%x curr_wr_port=0x%x\n",
513 pmadapter->pcard_sd->mp_wr_bitmap,
514 pmadapter->pcard_sd->curr_wr_port);
515 PRINTM(MMSG, "mp_data_port_mask = 0x%x\n",
516 pmadapter->pcard_sd->mp_data_port_mask);
517
518 PRINTM(MERROR,
519 "last_recv_rd_bitmap=0x%x mp_invalid_update=%d\n",
520 pmadapter->pcard_sd->last_recv_rd_bitmap,
521 pmadapter->pcard_sd->mp_invalid_update);
522 PRINTM(MERROR, "last_recv_wr_bitmap=0x%x last_mp_index=%d\n",
523 pmadapter->pcard_sd->last_recv_wr_bitmap,
524 pmadapter->pcard_sd->last_mp_index);
525 for (i = 0; i < SDIO_MP_DBG_NUM; i++) {
526 PRINTM(MERROR,
527 "mp_wr_bitmap: 0x%x mp_wr_ports=0x%x len=%d curr_wr_port=0x%x\n",
528 pmadapter->pcard_sd->last_mp_wr_bitmap[i],
529 pmadapter->pcard_sd->last_mp_wr_ports[i],
530 pmadapter->pcard_sd->last_mp_wr_len[i],
531 pmadapter->pcard_sd->last_curr_wr_port[i]);
532 for (j = 0; j < mp_aggr_pkt_limit; j++) {
533 PRINTM(MERROR, "0x%02x ",
534 pmadapter->pcard_sd->last_mp_wr_info
535 [i * mp_aggr_pkt_limit + j]);
536 }
537 PRINTM(MERROR, "\n");
538 }
539 }
540 #endif
541 #ifdef PCIE
542 if (IS_PCIE(pmadapter->card_type)) {
543 PRINTM(MERROR, "txbd_rdptr=0x%x txbd_wrptr=0x%x\n",
544 pmadapter->pcard_pcie->txbd_rdptr,
545 pmadapter->pcard_pcie->txbd_wrptr);
546 PRINTM(MERROR, "rxbd_rdptr=0x%x rxbd_wrptr=0x%x\n",
547 pmadapter->pcard_pcie->rxbd_rdptr,
548 pmadapter->pcard_pcie->rxbd_wrptr);
549 PRINTM(MERROR, "evtbd_rdptr=0x%x evt_wrptr=0x%x\n",
550 pmadapter->pcard_pcie->evtbd_rdptr,
551 pmadapter->pcard_pcie->evtbd_wrptr);
552 PRINTM(MERROR, "last_wr_index:%d\n",
553 pmadapter->pcard_pcie->txbd_wrptr &
554 (pmadapter->pcard_pcie->txrx_bd_size - 1));
555 PRINTM(MERROR, " txrx_bd_size = %d\n",
556 pmadapter->pcard_pcie->txrx_bd_size);
557 PRINTM(MERROR, "Tx pkt size:\n");
558 for (i = 0; i < pmadapter->pcard_pcie->txrx_bd_size; i++) {
559 PRINTM(MERROR, "%04d ",
560 pmadapter->pcard_pcie->last_tx_pkt_size[i]);
561 if (((i + 1) % 16) == 0)
562 PRINTM(MERROR, "\n");
563 }
564 }
565 #endif
566 for (i = 0; i < pmadapter->priv_num; ++i) {
567 if (pmadapter->priv[i])
568 wlan_dump_ralist(pmadapter->priv[i]);
569 }
570 if (reason != REASON_CODE_CMD_TIMEOUT) {
571 if ((pmadapter->dbg.num_no_cmd_node >= 5) ||
572 (pmadapter->pm_wakeup_card_req &&
573 pmadapter->pm_wakeup_fw_try) ||
574 (reason == REASON_CODE_EXT_SCAN_TIMEOUT)) {
575 if (pmpriv)
576 wlan_recv_event(pmpriv,
577 MLAN_EVENT_ID_DRV_DBG_DUMP,
578 MNULL);
579 else {
580 pmpriv = wlan_get_priv(pmadapter,
581 MLAN_BSS_ROLE_ANY);
582 if (pmpriv)
583 wlan_recv_event(
584 pmpriv,
585 MLAN_EVENT_ID_DRV_DBG_DUMP,
586 MNULL);
587 }
588 }
589 }
590 PRINTM(MERROR, "-------- Dump info End---------\n", reason);
591 LEAVE();
592 return;
593 }
594
595 /**
596 * @brief This function convert a given character to hex
597 *
598 * @param chr Character to be converted
599 *
600 * @return The converted hex if chr is a valid hex, else 0
601 */
wlan_hexval(t_u8 chr)602 static t_u32 wlan_hexval(t_u8 chr)
603 {
604 if (chr >= '0' && chr <= '9')
605 return chr - '0';
606 if (chr >= 'A' && chr <= 'F')
607 return chr - 'A' + 10;
608 if (chr >= 'a' && chr <= 'f')
609 return chr - 'a' + 10;
610
611 return 0;
612 }
613
614 /**
615 * @brief This function convert a given string to hex
616 *
617 * @param a A pointer to string to be converted
618 *
619 * @return The converted hex value if param a is a valid hex, else
620 * 0
621 */
wlan_atox(t_u8 * a)622 static int wlan_atox(t_u8 *a)
623 {
624 int i = 0;
625
626 ENTER();
627
628 while (wlan_isxdigit(*a))
629 i = i * 16 + wlan_hexval(*a++);
630
631 LEAVE();
632 return i;
633 }
634
635 /**
636 * @brief This function parse cal data from ASCII to hex
637 *
638 * @param src A pointer to source data
639 * @param len Source data length
640 * @param dst A pointer to a buf to store the parsed data
641 *
642 * @return The parsed hex data length
643 */
wlan_parse_cal_cfg(t_u8 * src,t_size len,t_u8 * dst)644 static t_u32 wlan_parse_cal_cfg(t_u8 *src, t_size len, t_u8 *dst)
645 {
646 t_u8 *ptr;
647 t_u8 *dptr;
648
649 ENTER();
650 ptr = src;
651 dptr = dst;
652
653 while (ptr - src < len) {
654 if (*ptr && (wlan_isspace(*ptr) || *ptr == '\t')) {
655 ptr++;
656 continue;
657 }
658
659 if (wlan_isxdigit(*ptr)) {
660 *dptr++ = wlan_atox(ptr);
661 ptr += 2;
662 } else {
663 ptr++;
664 }
665 }
666 LEAVE();
667 return dptr - dst;
668 }
669
670 /**
671 * @brief This function finds first occurrence of a char in a string
672 *
673 * @param s A pointer to the string to be searched
674 * @param c The character to search for
675 *
676 * @return Location of the first occurrence of the char
677 * if found, else NULL
678 */
wlan_strchr(t_u8 * s,int c)679 static t_u8 *wlan_strchr(t_u8 *s, int c)
680 {
681 t_u8 *pos = s;
682 while (*pos != '\0') {
683 if (*pos == (t_u8)c)
684 return pos;
685 pos++;
686 }
687 return MNULL;
688 }
689
690 #define CFG_TYPE_HOSTCMD 0
691 #define CFG_TYPE_DPDFILE 1
692
693 /**
694 * @brief WOAL parse ASCII format raw data to hex format
695 *
696 * @param pmpriv MOAL handle
697 * @param cfg_type Conf file type
698 * @param data Source data
699 * @param size data length
700 * @return MLAN_STATUS_SUCCESS--success, otherwise--fail
701 */
wlan_process_hostcmd_cfg(pmlan_private pmpriv,t_u16 cfg_type,t_u8 * data,t_size size)702 static t_u32 wlan_process_hostcmd_cfg(pmlan_private pmpriv, t_u16 cfg_type,
703 t_u8 *data, t_size size)
704 {
705 mlan_status ret = MLAN_STATUS_SUCCESS;
706 t_u8 *pos = data;
707 t_u8 *intf_s, *intf_e;
708 t_u8 *buf = MNULL;
709 t_u8 *ptr = MNULL;
710 t_u32 cmd_len = 0;
711 t_u8 start_raw = MFALSE;
712 mlan_ds_misc_cmd *hostcmd;
713 HostCmd_DS_GEN *pcmd = MNULL;
714 HostCmd_DS_802_11_CFG_DATA *pcfg_cmd = MNULL;
715 mlan_adapter *pmadapter = MNULL;
716 mlan_callbacks *pcb = MNULL;
717 t_u8 hostcmd_flag = MFALSE;
718
719 ENTER();
720 if (!pmpriv) {
721 PRINTM(MERROR, "pmpriv is NULL\n");
722 LEAVE();
723 return MLAN_STATUS_FAILURE;
724 }
725 pmadapter = pmpriv->adapter;
726 pcb = (mlan_callbacks *)&pmadapter->callbacks;
727 ret = pcb->moal_malloc(pmadapter->pmoal_handle,
728 sizeof(mlan_ds_misc_cmd), MLAN_MEM_DEF,
729 (t_u8 **)&hostcmd);
730 if (ret || !hostcmd) {
731 PRINTM(MERROR, "Could not allocate buffer space!\n");
732 LEAVE();
733 return ret;
734 }
735 buf = hostcmd->cmd;
736 ptr = buf;
737 while ((pos - data) < size) {
738 while (*pos == ' ' || *pos == '\t')
739 pos++;
740 if (*pos == '#') { /* Line comment */
741 while (*pos != '\n')
742 pos++;
743 pos++;
744 }
745 if ((*pos == '\r' && *(pos + 1) == '\n') || *pos == '\n' ||
746 *pos == '\0') {
747 pos++;
748 continue; /* Needn't process this line */
749 }
750
751 if (*pos == '}') {
752 if (cfg_type == CFG_TYPE_DPDFILE && pcmd) {
753 /* Fill command head for DPD RAW data conf */
754 hostcmd->len = ptr - buf;
755 pcmd->command =
756 wlan_cpu_to_le16(HostCmd_CMD_CFG_DATA);
757 pcmd->size = wlan_cpu_to_le16(hostcmd->len);
758 pcfg_cmd = (HostCmd_DS_802_11_CFG_DATA
759 *)((t_u8 *)pcmd + S_DS_GEN);
760 pcfg_cmd->action =
761 wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
762 pcfg_cmd->type = wlan_cpu_to_le16(OID_TYPE_DPD);
763 pcfg_cmd->data_len = wlan_cpu_to_le16(
764 hostcmd->len - S_DS_GEN -
765 sizeof(HostCmd_DS_802_11_CFG_DATA));
766 pcmd = MNULL;
767 pcfg_cmd = MNULL;
768 } else {
769 /* For hostcmd data conf */
770 cmd_len = *((t_u16 *)(buf + sizeof(t_u16)));
771 hostcmd->len = cmd_len;
772 }
773 ret = wlan_prepare_cmd(pmpriv, 0, 0, 0, MNULL,
774 (t_void *)hostcmd);
775 memset(pmadapter, buf, 0, MRVDRV_SIZE_OF_CMD_BUFFER);
776 ptr = buf;
777 start_raw = MFALSE;
778 pos++;
779 continue;
780 }
781
782 if (start_raw == MFALSE) {
783 intf_s = wlan_strchr(pos, '=');
784 if (intf_s) {
785 if (*(intf_s + 1) == '=')
786 hostcmd_flag = MTRUE;
787 intf_e = wlan_strchr(intf_s, '{');
788 } else
789 intf_e = MNULL;
790
791 if (intf_s && intf_e) {
792 start_raw = MTRUE;
793 pos = intf_e + 1;
794 /* Reserve command head for DPD RAW data conf */
795 if (cfg_type == CFG_TYPE_DPDFILE &&
796 !hostcmd_flag) {
797 pcmd = (HostCmd_DS_GEN *)ptr;
798 ptr += S_DS_GEN +
799 sizeof(HostCmd_DS_802_11_CFG_DATA);
800 }
801 continue;
802 }
803 }
804
805 if (start_raw) {
806 /* Raw data block exists */
807 while (*pos != '\n') {
808 if ((*pos <= 'f' && *pos >= 'a') ||
809 (*pos <= 'F' && *pos >= 'A') ||
810 (*pos <= '9' && *pos >= '0')) {
811 *ptr++ = wlan_atox(pos);
812 pos += 2;
813 } else
814 pos++;
815 }
816 }
817 }
818 pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)hostcmd);
819 LEAVE();
820 return ret;
821 }
822
823 /**
824 * @brief This function initializes the command node.
825 *
826 * @param pmpriv A pointer to mlan_private structure
827 * @param pcmd_node A pointer to cmd_ctrl_node structure
828 * @param cmd_no cmd id
829 * @param pioctl_buf A pointer to MLAN IOCTL Request buffer
830 * @param pdata_buf A pointer to information buffer
831 *
832 * @return N/A
833 */
wlan_init_cmd_node(pmlan_private pmpriv,cmd_ctrl_node * pcmd_node,t_u32 cmd_no,t_void * pioctl_buf,t_void * pdata_buf)834 static void wlan_init_cmd_node(pmlan_private pmpriv, cmd_ctrl_node *pcmd_node,
835 t_u32 cmd_no, t_void *pioctl_buf,
836 t_void *pdata_buf)
837 {
838 mlan_adapter *pmadapter = pmpriv->adapter;
839
840 ENTER();
841
842 if (pcmd_node == MNULL) {
843 LEAVE();
844 return;
845 }
846 pcmd_node->priv = pmpriv;
847 pcmd_node->cmd_no = cmd_no;
848 pcmd_node->pioctl_buf = pioctl_buf;
849 pcmd_node->pdata_buf = pdata_buf;
850
851 #ifdef USB
852 if (IS_USB(pmadapter->card_type)) {
853 pcmd_node->cmdbuf =
854 wlan_alloc_mlan_buffer(pmadapter,
855 MRVDRV_SIZE_OF_CMD_BUFFER, 0,
856 MOAL_MALLOC_BUFFER);
857 if (!pcmd_node->cmdbuf) {
858 PRINTM(MERROR, "Failed to allocate cmd_buffer\n");
859 LEAVE();
860 return;
861 }
862 }
863 #endif /* USB */
864 #if defined(SDIO) || defined(PCIE)
865 if (!IS_USB(pmadapter->card_type))
866 pcmd_node->cmdbuf = pcmd_node->pmbuf;
867 #endif
868
869 /* Make sure head_ptr for cmd buf is Align */
870 pcmd_node->cmdbuf->data_offset = 0;
871 memset(pmadapter, pcmd_node->cmdbuf->pbuf, 0,
872 MRVDRV_SIZE_OF_CMD_BUFFER);
873
874 /* Prepare mlan_buffer for command sending */
875 pcmd_node->cmdbuf->buf_type = MLAN_BUF_TYPE_CMD;
876 #ifdef USB
877 if (IS_USB(pmadapter->card_type))
878 pcmd_node->cmdbuf->data_offset += MLAN_TYPE_LEN;
879 #endif
880 #if defined(SDIO) || defined(PCIE)
881 if (!IS_USB(pmadapter->card_type))
882 pcmd_node->cmdbuf->data_offset +=
883 pmadapter->ops.intf_header_len;
884 #endif
885
886 LEAVE();
887 }
888
889 /**
890 * @brief This function gets a free command node if available in
891 * command free queue.
892 *
893 * @param pmadapter A pointer to mlan_adapter structure
894 *
895 * @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or MNULL
896 */
wlan_get_cmd_node(mlan_adapter * pmadapter)897 static cmd_ctrl_node *wlan_get_cmd_node(mlan_adapter *pmadapter)
898 {
899 cmd_ctrl_node *pcmd_node;
900
901 ENTER();
902
903 if (pmadapter == MNULL) {
904 LEAVE();
905 return MNULL;
906 }
907 wlan_request_cmd_lock(pmadapter);
908 if (util_peek_list(pmadapter->pmoal_handle, &pmadapter->cmd_free_q,
909 MNULL, MNULL)) {
910 pcmd_node = (cmd_ctrl_node *)util_dequeue_list(
911 pmadapter->pmoal_handle, &pmadapter->cmd_free_q, MNULL,
912 MNULL);
913 } else {
914 PRINTM(MERROR,
915 "GET_CMD_NODE: cmd_ctrl_node is not available\n");
916 pcmd_node = MNULL;
917 }
918 wlan_release_cmd_lock(pmadapter);
919 LEAVE();
920 return pcmd_node;
921 }
922
923 /**
924 * @brief This function cleans command node.
925 *
926 * @param pmadapter A pointer to mlan_adapter structure
927 * @param pcmd_node A pointer to cmd_ctrl_node structure
928 *
929 * @return N/A
930 */
wlan_clean_cmd_node(pmlan_adapter pmadapter,cmd_ctrl_node * pcmd_node)931 static t_void wlan_clean_cmd_node(pmlan_adapter pmadapter,
932 cmd_ctrl_node *pcmd_node)
933 {
934 ENTER();
935
936 if (pcmd_node == MNULL) {
937 LEAVE();
938 return;
939 }
940 pcmd_node->cmd_no = 0;
941 pcmd_node->cmd_flag = 0;
942 pcmd_node->pioctl_buf = MNULL;
943 pcmd_node->pdata_buf = MNULL;
944
945 #ifdef USB
946 if (IS_USB(pmadapter->card_type) && pcmd_node->cmdbuf) {
947 wlan_free_mlan_buffer(pmadapter, pcmd_node->cmdbuf);
948 pcmd_node->cmdbuf = MNULL;
949 }
950 #endif
951
952 if (pcmd_node->respbuf) {
953 pmadapter->ops.cmdrsp_complete(pmadapter, pcmd_node->respbuf,
954 MLAN_STATUS_SUCCESS);
955 pcmd_node->respbuf = MNULL;
956 }
957
958 LEAVE();
959 return;
960 }
961
962 #ifdef STA_SUPPORT
963 /**
964 * @brief This function will return the pointer to the first entry in
965 * pending cmd which is scan command
966 *
967 * @param pmadapter A pointer to mlan_adapter
968 *
969 * @return A pointer to first entry match pioctl_req
970 */
wlan_get_pending_scan_cmd(pmlan_adapter pmadapter)971 static cmd_ctrl_node *wlan_get_pending_scan_cmd(pmlan_adapter pmadapter)
972 {
973 cmd_ctrl_node *pcmd_node = MNULL;
974
975 ENTER();
976
977 pcmd_node = (cmd_ctrl_node *)util_peek_list(pmadapter->pmoal_handle,
978 &pmadapter->cmd_pending_q,
979 MNULL, MNULL);
980 if (!pcmd_node) {
981 LEAVE();
982 return MNULL;
983 }
984 while (pcmd_node != (cmd_ctrl_node *)&pmadapter->cmd_pending_q) {
985 if (pcmd_node->cmd_flag & CMD_F_SCAN) {
986 LEAVE();
987 return pcmd_node;
988 }
989 pcmd_node = pcmd_node->pnext;
990 }
991 LEAVE();
992 return MNULL;
993 }
994 #endif
995
996 /**
997 * @brief This function will return the pointer to the first entry in
998 * pending cmd which matches the given pioctl_req
999 *
1000 * @param pmadapter A pointer to mlan_adapter
1001 * @param pioctl_req A pointer to mlan_ioctl_req buf
1002 *
1003 * @return A pointer to first entry match pioctl_req
1004 */
wlan_get_pending_ioctl_cmd(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)1005 static cmd_ctrl_node *wlan_get_pending_ioctl_cmd(pmlan_adapter pmadapter,
1006 pmlan_ioctl_req pioctl_req)
1007 {
1008 cmd_ctrl_node *pcmd_node = MNULL;
1009
1010 ENTER();
1011
1012 pcmd_node = (cmd_ctrl_node *)util_peek_list(pmadapter->pmoal_handle,
1013 &pmadapter->cmd_pending_q,
1014 MNULL, MNULL);
1015 if (!pcmd_node) {
1016 LEAVE();
1017 return MNULL;
1018 }
1019 while (pcmd_node != (cmd_ctrl_node *)&pmadapter->cmd_pending_q) {
1020 if (pcmd_node->pioctl_buf &&
1021 (pcmd_node->pioctl_buf == pioctl_req)) {
1022 LEAVE();
1023 return pcmd_node;
1024 }
1025 pcmd_node = pcmd_node->pnext;
1026 }
1027 LEAVE();
1028 return MNULL;
1029 }
1030
1031 /**
1032 * @brief This function will return the pointer to the first entry in
1033 * pending cmd which matches the given bss_index
1034 *
1035 * @param pmadapter A pointer to mlan_adapter
1036 * @param bss_index bss_index
1037 *
1038 * @return A pointer to first entry match pioctl_req
1039 */
wlan_get_bss_pending_ioctl_cmd(pmlan_adapter pmadapter,t_u32 bss_index)1040 static cmd_ctrl_node *wlan_get_bss_pending_ioctl_cmd(pmlan_adapter pmadapter,
1041 t_u32 bss_index)
1042 {
1043 cmd_ctrl_node *pcmd_node = MNULL;
1044 mlan_ioctl_req *pioctl_buf = MNULL;
1045 ENTER();
1046
1047 pcmd_node = (cmd_ctrl_node *)util_peek_list(pmadapter->pmoal_handle,
1048 &pmadapter->cmd_pending_q,
1049 MNULL, MNULL);
1050 if (!pcmd_node) {
1051 LEAVE();
1052 return MNULL;
1053 }
1054 while (pcmd_node != (cmd_ctrl_node *)&pmadapter->cmd_pending_q) {
1055 if (pcmd_node->pioctl_buf) {
1056 pioctl_buf = (mlan_ioctl_req *)pcmd_node->pioctl_buf;
1057 if (pioctl_buf->bss_index == bss_index) {
1058 LEAVE();
1059 return pcmd_node;
1060 }
1061 }
1062 pcmd_node = pcmd_node->pnext;
1063 }
1064 LEAVE();
1065 return MNULL;
1066 }
1067
1068 /**
1069 * @brief This function handles the command response of host_cmd
1070 *
1071 * @param pmpriv A pointer to mlan_private structure
1072 * @param resp A pointer to HostCmd_DS_COMMAND
1073 * @param pioctl_buf A pointer to mlan_ioctl_req structure
1074 *
1075 * @return MLAN_STATUS_SUCCESS
1076 */
wlan_ret_host_cmd(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)1077 static mlan_status wlan_ret_host_cmd(pmlan_private pmpriv,
1078 HostCmd_DS_COMMAND *resp,
1079 mlan_ioctl_req *pioctl_buf)
1080 {
1081 mlan_ds_misc_cfg *misc;
1082 t_u16 size = wlan_le16_to_cpu(resp->size);
1083
1084 ENTER();
1085
1086 PRINTM(MINFO, "host command response size = %d\n", size);
1087 size = MIN(size, MRVDRV_SIZE_OF_CMD_BUFFER);
1088 if (pioctl_buf) {
1089 misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
1090 misc->param.hostcmd.len = size;
1091 memcpy_ext(pmpriv->adapter, misc->param.hostcmd.cmd,
1092 (void *)resp, size, MRVDRV_SIZE_OF_CMD_BUFFER);
1093 }
1094
1095 LEAVE();
1096 return MLAN_STATUS_SUCCESS;
1097 }
1098
1099 /**
1100 * @brief This function sends host command to firmware.
1101 *
1102 * @param pmpriv A pointer to mlan_private structure
1103 * @param cmd A pointer to HostCmd_DS_COMMAND structure
1104 * @param pdata_buf A pointer to data buffer
1105 * @param cmd_no A pointer to cmd_no
1106 * @return MLAN_STATUS_SUCCESS
1107 */
wlan_cmd_host_cmd(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_void * pdata_buf,t_u16 * cmd_no)1108 static mlan_status wlan_cmd_host_cmd(pmlan_private pmpriv,
1109 HostCmd_DS_COMMAND *cmd, t_void *pdata_buf,
1110 t_u16 *cmd_no)
1111 {
1112 mlan_ds_misc_cmd *pcmd_ptr = (mlan_ds_misc_cmd *)pdata_buf;
1113
1114 ENTER();
1115
1116 /* Copy the HOST command to command buffer */
1117 memcpy_ext(pmpriv->adapter, (void *)cmd, pcmd_ptr->cmd, pcmd_ptr->len,
1118 MRVDRV_SIZE_OF_CMD_BUFFER);
1119 *cmd_no = wlan_le16_to_cpu(cmd->command);
1120 PRINTM(MCMND, "Prepare Host command: 0x%x size = %d\n", *cmd_no,
1121 pcmd_ptr->len);
1122 LEAVE();
1123 return MLAN_STATUS_SUCCESS;
1124 }
1125
1126 /**
1127 * @brief This function get the cmd timeout value
1128 *
1129 * @param cmd_id cmd id
1130 *
1131 * @return timeout value for this command
1132 */
wlan_get_cmd_timeout(t_u16 cmd_id)1133 static t_u32 wlan_get_cmd_timeout(t_u16 cmd_id)
1134 {
1135 t_u32 timeout;
1136 ENTER();
1137 switch (cmd_id) {
1138 case HostCmd_CMD_802_11_SCAN:
1139 case HostCmd_CMD_802_11_SCAN_EXT:
1140 timeout = MRVDRV_TIMER_10S * 2;
1141 break;
1142 case HostCmd_CMD_FUNC_INIT:
1143 case HostCmd_CMD_FUNC_SHUTDOWN:
1144 case HostCmd_CMD_802_11_ASSOCIATE:
1145 case HostCmd_CMD_802_11_DEAUTHENTICATE:
1146 case HostCmd_CMD_802_11_DISASSOCIATE:
1147 case HostCmd_CMD_802_11_AD_HOC_START:
1148 case HostCmd_CMD_802_11_AD_HOC_JOIN:
1149 case HostCmd_CMD_802_11_AD_HOC_STOP:
1150 case HostCmd_CMD_11N_ADDBA_REQ:
1151 case HostCmd_CMD_11N_ADDBA_RSP:
1152 case HostCmd_CMD_11N_DELBA:
1153 case HostCmd_CMD_802_11_REMAIN_ON_CHANNEL:
1154 case HostCmd_CMD_TDLS_CONFIG:
1155 case HostCmd_CMD_TDLS_OPERATION:
1156 case HostCmd_CMD_SUPPLICANT_PMK:
1157 case HostCmd_CMD_SUPPLICANT_PROFILE:
1158 case HostCmd_CMD_SOFT_RESET:
1159 #ifdef UAP_SUPPORT
1160 case HOST_CMD_APCMD_SYS_RESET:
1161 case HOST_CMD_APCMD_BSS_START:
1162 case HOST_CMD_APCMD_BSS_STOP:
1163 case HOST_CMD_APCMD_STA_DEAUTH:
1164 #endif
1165 case HostCMD_APCMD_ACS_SCAN:
1166 timeout = MRVDRV_TIMER_5S;
1167 break;
1168 default:
1169 #ifdef IMX_SUPPORT
1170 /*
1171 * During the roaming test and the 5AP connection test, cmd
1172 * timeout are observed for commands like 0x5e, 0x16, 0xd1.
1173 * Observed that response has come just after default timeout of
1174 * 2 seconds for these commands. This random timeout is not
1175 * observed when the default timeout is increased to 5 seconds
1176 * (As an work around, Increase the default timeout to 5
1177 * seconds. Need to further debug exact reason for delay in cmd
1178 * responses)
1179 *
1180 */
1181 timeout = MRVDRV_TIMER_1S * 5;
1182 #else
1183 timeout = MRVDRV_TIMER_1S * 5;
1184 #endif
1185 break;
1186 }
1187 LEAVE();
1188 return timeout;
1189 }
1190
1191 /**
1192 * @brief This function downloads a command to firmware.
1193 *
1194 * @param pmpriv A pointer to mlan_private structure
1195 * @param pcmd_node A pointer to cmd_ctrl_node structure
1196 *
1197 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1198 */
wlan_dnld_cmd_to_fw(mlan_private * pmpriv,cmd_ctrl_node * pcmd_node)1199 static mlan_status wlan_dnld_cmd_to_fw(mlan_private *pmpriv,
1200 cmd_ctrl_node *pcmd_node)
1201 {
1202 mlan_adapter *pmadapter = pmpriv->adapter;
1203 mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks;
1204 mlan_status ret = MLAN_STATUS_SUCCESS;
1205 HostCmd_DS_COMMAND *pcmd;
1206 mlan_ioctl_req *pioctl_buf = MNULL;
1207 t_u16 cmd_code;
1208 t_u16 cmd_size;
1209 t_u32 age_ts_usec;
1210 #ifdef USB
1211 t_u32 tmp;
1212 #endif
1213 #ifdef DEBUG_LEVEL1
1214 t_u32 sec = 0, usec = 0;
1215 #endif
1216 t_u32 timeout = 0;
1217
1218 ENTER();
1219
1220 if (pcmd_node)
1221 if (pcmd_node->pioctl_buf != MNULL)
1222 pioctl_buf = (mlan_ioctl_req *)pcmd_node->pioctl_buf;
1223 if (!pmadapter || !pcmd_node) {
1224 if (pioctl_buf)
1225 pioctl_buf->status_code = MLAN_ERROR_CMD_DNLD_FAIL;
1226 ret = MLAN_STATUS_FAILURE;
1227 goto done;
1228 }
1229
1230 pcmd = (HostCmd_DS_COMMAND *)(pcmd_node->cmdbuf->pbuf +
1231 pcmd_node->cmdbuf->data_offset);
1232
1233 /* Sanity test */
1234 if (pcmd == MNULL || pcmd->size == 0) {
1235 PRINTM(MERROR,
1236 "DNLD_CMD: pcmd is null or command size is zero, "
1237 "Not sending\n");
1238 if (pioctl_buf)
1239 pioctl_buf->status_code = MLAN_ERROR_CMD_DNLD_FAIL;
1240 wlan_request_cmd_lock(pmadapter);
1241 wlan_insert_cmd_to_free_q(pmadapter, pcmd_node);
1242 wlan_release_cmd_lock(pmadapter);
1243 ret = MLAN_STATUS_FAILURE;
1244 goto done;
1245 }
1246
1247 /* Set command sequence number */
1248 pmadapter->seq_num++;
1249 pcmd->seq_num = wlan_cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO(
1250 pmadapter->seq_num, pcmd_node->priv->bss_num,
1251 pcmd_node->priv->bss_type));
1252 cmd_code = wlan_le16_to_cpu(pcmd->command);
1253 pcmd_node->cmd_no = cmd_code;
1254 timeout = wlan_get_cmd_timeout(cmd_code);
1255 cmd_size = wlan_le16_to_cpu(pcmd->size);
1256
1257 pcmd_node->cmdbuf->data_len = cmd_size;
1258
1259 wlan_request_cmd_lock(pmadapter);
1260 pmadapter->curr_cmd = pcmd_node;
1261 wlan_release_cmd_lock(pmadapter);
1262
1263 /* Save the last command id and action to debug log */
1264 pmadapter->dbg.last_cmd_index =
1265 (pmadapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM;
1266 pmadapter->dbg.last_cmd_id[pmadapter->dbg.last_cmd_index] = cmd_code;
1267 pmadapter->dbg.last_cmd_act[pmadapter->dbg.last_cmd_index] =
1268 wlan_le16_to_cpu(*(t_u16 *)((t_u8 *)pcmd + S_DS_GEN));
1269 pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle,
1270 &pmadapter->dnld_cmd_in_secs,
1271 &age_ts_usec);
1272
1273 #ifdef USB
1274 if (IS_USB(pmadapter->card_type)) {
1275 /* Add extra header for USB */
1276 if (pcmd_node->cmdbuf->data_offset < MLAN_TYPE_LEN) {
1277 PRINTM(MERROR,
1278 "DNLD_CMD: data_offset is too small=%d\n",
1279 pcmd_node->cmdbuf->data_offset);
1280 if (pioctl_buf)
1281 pioctl_buf->status_code =
1282 MLAN_ERROR_CMD_DNLD_FAIL;
1283
1284 wlan_request_cmd_lock(pmadapter);
1285 wlan_insert_cmd_to_free_q(pmadapter, pcmd_node);
1286 pmadapter->curr_cmd = MNULL;
1287 wlan_release_cmd_lock(pmadapter);
1288 if (pmadapter->dbg.last_cmd_index)
1289 pmadapter->dbg.last_cmd_index--;
1290 else
1291 pmadapter->dbg.last_cmd_index = DBG_CMD_NUM - 1;
1292 ret = MLAN_STATUS_FAILURE;
1293 goto done;
1294 }
1295 tmp = wlan_cpu_to_le32(MLAN_USB_TYPE_CMD);
1296 memcpy_ext(pmadapter, (t_u8 *)pcmd - MLAN_TYPE_LEN,
1297 (t_u8 *)&tmp, MLAN_TYPE_LEN, MLAN_TYPE_LEN);
1298 pcmd_node->cmdbuf->data_offset -= MLAN_TYPE_LEN;
1299 pcmd_node->cmdbuf->data_len += MLAN_TYPE_LEN;
1300 }
1301 #endif
1302
1303 if (pcmd->command == HostCmd_CMD_802_11_SCAN_EXT)
1304 pmadapter->scan_state |= wlan_get_ext_scan_state(pcmd);
1305
1306 PRINTM_GET_SYS_TIME(MCMND, &sec, &usec);
1307 PRINTM_NETINTF(MCMND, pmpriv);
1308 PRINTM(MCMND,
1309 "DNLD_CMD (%lu.%06lu): 0x%x, act 0x%x, len %d, seqno 0x%x timeout %d\n",
1310 sec, usec, cmd_code,
1311 wlan_le16_to_cpu(*(t_u16 *)((t_u8 *)pcmd + S_DS_GEN)), cmd_size,
1312 wlan_le16_to_cpu(pcmd->seq_num), timeout);
1313 DBG_HEXDUMP(MCMD_D, "DNLD_CMD", (t_u8 *)pcmd, cmd_size);
1314
1315 #if defined(SDIO) || defined(PCIE)
1316 if (!IS_USB(pmadapter->card_type)) {
1317 pcmd_node->cmdbuf->data_offset -=
1318 pmadapter->ops.intf_header_len;
1319 pcmd_node->cmdbuf->data_len += pmadapter->ops.intf_header_len;
1320 }
1321 #endif
1322
1323 /* Send the command to lower layer */
1324 ret = pmadapter->ops.host_to_card(pmpriv, MLAN_TYPE_CMD,
1325 pcmd_node->cmdbuf, MNULL);
1326
1327 #ifdef USB
1328 if (IS_USB(pmadapter->card_type) && (ret == MLAN_STATUS_PENDING))
1329 pcmd_node->cmdbuf = MNULL;
1330 #endif
1331
1332 if (ret == MLAN_STATUS_FAILURE) {
1333 PRINTM(MERROR, "DNLD_CMD: Host to Card Failed\n");
1334 if (pcmd_node->pioctl_buf) {
1335 pioctl_buf = (mlan_ioctl_req *)pcmd_node->pioctl_buf;
1336 pioctl_buf->status_code = MLAN_ERROR_CMD_DNLD_FAIL;
1337 }
1338
1339 wlan_request_cmd_lock(pmadapter);
1340 wlan_insert_cmd_to_free_q(pmadapter, pmadapter->curr_cmd);
1341 pmadapter->curr_cmd = MNULL;
1342 wlan_release_cmd_lock(pmadapter);
1343 if (pmadapter->dbg.last_cmd_index)
1344 pmadapter->dbg.last_cmd_index--;
1345 else
1346 pmadapter->dbg.last_cmd_index = DBG_CMD_NUM - 1;
1347
1348 pmadapter->dbg.num_cmd_host_to_card_failure++;
1349 wlan_dump_info(pmadapter, REASON_CODE_CMD_TO_CARD_FAILURE);
1350 ret = MLAN_STATUS_FAILURE;
1351 goto done;
1352 }
1353
1354 /* Clear BSS_NO_BITS from HostCmd */
1355 cmd_code &= HostCmd_CMD_ID_MASK;
1356
1357 /* For the command who has no command response, we should return here */
1358 if (cmd_code == HostCmd_CMD_FW_DUMP_EVENT ||
1359 cmd_code == HostCmd_CMD_SOFT_RESET) {
1360 if (pcmd_node->pioctl_buf) {
1361 PRINTM(MMSG,
1362 "CMD(0x%x) has no cmd resp: free curr_cmd and do ioctl_complete\n",
1363 cmd_code);
1364 pioctl_buf = (mlan_ioctl_req *)pcmd_node->pioctl_buf;
1365 wlan_request_cmd_lock(pmadapter);
1366 wlan_insert_cmd_to_free_q(pmadapter,
1367 pmadapter->curr_cmd);
1368 pmadapter->curr_cmd = MNULL;
1369 wlan_release_cmd_lock(pmadapter);
1370 }
1371 goto done;
1372 }
1373
1374 /* Setup the timer after transmit command */
1375 pcb->moal_start_timer(pmadapter->pmoal_handle,
1376 pmadapter->pmlan_cmd_timer, MFALSE, timeout);
1377
1378 pmadapter->cmd_timer_is_set = MTRUE;
1379
1380 ret = MLAN_STATUS_SUCCESS;
1381
1382 done:
1383 LEAVE();
1384 return ret;
1385 }
1386
1387 /**
1388 * @brief This function sends sleep confirm command to firmware.
1389 *
1390 * @param pmadapter A pointer to mlan_adapter structure
1391 *
1392 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1393 */
wlan_dnld_sleep_confirm_cmd(mlan_adapter * pmadapter)1394 static mlan_status wlan_dnld_sleep_confirm_cmd(mlan_adapter *pmadapter)
1395 {
1396 mlan_status ret = MLAN_STATUS_SUCCESS;
1397 static t_u32 i;
1398 #if defined(SDIO) || defined(PCIE)
1399 t_u16 cmd_len = 0;
1400 #endif
1401 opt_sleep_confirm_buffer *sleep_cfm_buf =
1402 (opt_sleep_confirm_buffer *)(pmadapter->psleep_cfm->pbuf +
1403 pmadapter->psleep_cfm->data_offset);
1404 mlan_buffer *pmbuf = MNULL;
1405 mlan_private *pmpriv = MNULL;
1406
1407 ENTER();
1408
1409 pmpriv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);
1410 if (!pmpriv) {
1411 LEAVE();
1412 return MLAN_STATUS_FAILURE;
1413 }
1414 #if defined(SDIO) || defined(PCIE)
1415 if (!IS_USB(pmadapter->card_type)) {
1416 cmd_len = sizeof(OPT_Confirm_Sleep);
1417 pmbuf = pmadapter->psleep_cfm;
1418 }
1419 #endif
1420 pmadapter->seq_num++;
1421 sleep_cfm_buf->ps_cfm_sleep.seq_num =
1422 wlan_cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO(
1423 pmadapter->seq_num, pmpriv->bss_num, pmpriv->bss_type));
1424 DBG_HEXDUMP(MCMD_D, "SLEEP_CFM", &sleep_cfm_buf->ps_cfm_sleep,
1425 sizeof(OPT_Confirm_Sleep));
1426
1427 /* Send sleep confirm command to firmware */
1428 #ifdef USB
1429 if (IS_USB(pmadapter->card_type)) {
1430 pmbuf = wlan_alloc_mlan_buffer(pmadapter,
1431 sizeof(opt_sleep_confirm_buffer),
1432 0, MOAL_MALLOC_BUFFER);
1433
1434 if (!pmbuf) {
1435 PRINTM(MERROR,
1436 "Failed to allocate sleep confirm buffers\n");
1437 LEAVE();
1438 return MLAN_STATUS_FAILURE;
1439 }
1440 pmbuf->buf_type = MLAN_BUF_TYPE_CMD;
1441 pmbuf->data_len = pmadapter->psleep_cfm->data_len;
1442 memcpy_ext(pmadapter, pmbuf->pbuf + pmbuf->data_offset,
1443 pmadapter->psleep_cfm->pbuf +
1444 pmadapter->psleep_cfm->data_offset,
1445 pmadapter->psleep_cfm->data_len, pmbuf->data_len);
1446 }
1447 #endif /* USB */
1448
1449 #if defined(SDIO) || defined(PCIE)
1450 if (!IS_USB(pmadapter->card_type))
1451 pmadapter->psleep_cfm->data_len =
1452 cmd_len + pmadapter->ops.intf_header_len;
1453 #endif
1454
1455 if (pmbuf)
1456 ret = pmadapter->ops.host_to_card(pmpriv, MLAN_TYPE_CMD, pmbuf,
1457 MNULL);
1458
1459 #ifdef USB
1460 if (IS_USB(pmadapter->card_type) && (ret != MLAN_STATUS_PENDING))
1461 wlan_free_mlan_buffer(pmadapter, pmbuf);
1462 #endif
1463 if (ret == MLAN_STATUS_FAILURE) {
1464 PRINTM(MERROR, "SLEEP_CFM: failed\n");
1465 pmadapter->dbg.num_cmd_sleep_cfm_host_to_card_failure++;
1466 goto done;
1467 } else {
1468 if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_UAP)
1469 pmadapter->ps_state = PS_STATE_SLEEP_CFM;
1470 #ifdef STA_SUPPORT
1471 if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_STA) {
1472 if (!sleep_cfm_buf->ps_cfm_sleep.sleep_cfm.resp_ctrl) {
1473 /* Response is not needed for sleep confirm
1474 * command */
1475 pmadapter->ps_state = PS_STATE_SLEEP;
1476 } else {
1477 pmadapter->ps_state = PS_STATE_SLEEP_CFM;
1478 }
1479
1480 if (!sleep_cfm_buf->ps_cfm_sleep.sleep_cfm.resp_ctrl &&
1481 (pmadapter->is_hs_configured &&
1482 !pmadapter->sleep_period.period)) {
1483 pmadapter->pm_wakeup_card_req = MTRUE;
1484 wlan_host_sleep_activated_event(
1485 wlan_get_priv(pmadapter,
1486 MLAN_BSS_ROLE_STA),
1487 MTRUE);
1488 }
1489 }
1490 #endif /* STA_SUPPORT */
1491
1492 PRINTM_NETINTF(MEVENT, pmpriv);
1493 #define NUM_SC_PER_LINE 16
1494 if (++i % NUM_SC_PER_LINE == 0)
1495 PRINTM(MEVENT, "+\n");
1496 else
1497 PRINTM(MEVENT, "+");
1498 }
1499
1500 done:
1501 LEAVE();
1502 return ret;
1503 }
1504
1505 /**
1506 * @brief Fetch bitmap rate index
1507 *
1508 * @param rate_scope A pointer to MrvlRateScope_t
1509 *
1510 * @return bitmap rate index
1511 */
wlan_get_bitmap_index(MrvlRateScope_t * rate_scope)1512 static t_u16 wlan_get_bitmap_index(MrvlRateScope_t *rate_scope)
1513 {
1514 t_u16 index = 0;
1515
1516 if (rate_scope != MNULL) {
1517 index += NELEMENTS(rate_scope->ht_mcs_rate_bitmap);
1518 index += NELEMENTS(rate_scope->vht_mcs_rate_bitmap);
1519 }
1520
1521 return index;
1522 }
1523
1524 /********************************************************
1525 Global Functions
1526 ********************************************************/
1527
1528 /**
1529 * @brief Event handler
1530 *
1531 * @param priv A pointer to mlan_private structure
1532 * @param event_id Event ID
1533 * @param pmevent Event buffer
1534 *
1535 * @return MLAN_STATUS_SUCCESS
1536 */
wlan_recv_event(pmlan_private priv,mlan_event_id event_id,t_void * pmevent)1537 mlan_status wlan_recv_event(pmlan_private priv, mlan_event_id event_id,
1538 t_void *pmevent)
1539 {
1540 pmlan_callbacks pcb = MNULL;
1541
1542 ENTER();
1543
1544 if (!priv) {
1545 LEAVE();
1546 return MLAN_STATUS_FAILURE;
1547 }
1548 pcb = &priv->adapter->callbacks;
1549
1550 if (pmevent)
1551 /* The caller has provided the event. */
1552 pcb->moal_recv_event(priv->adapter->pmoal_handle,
1553 (pmlan_event)pmevent);
1554 else {
1555 mlan_event mevent;
1556
1557 memset(priv->adapter, &mevent, 0, sizeof(mlan_event));
1558 mevent.bss_index = priv->bss_index;
1559 mevent.event_id = event_id;
1560 mevent.event_len = 0;
1561
1562 pcb->moal_recv_event(priv->adapter->pmoal_handle, &mevent);
1563 }
1564
1565 LEAVE();
1566 return MLAN_STATUS_SUCCESS;
1567 }
1568
1569 /**
1570 * @brief This function allocates the command buffer and links
1571 * it to command free queue.
1572 *
1573 * @param pmadapter A pointer to mlan_adapter structure
1574 *
1575 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1576 */
wlan_alloc_cmd_buffer(mlan_adapter * pmadapter)1577 mlan_status wlan_alloc_cmd_buffer(mlan_adapter *pmadapter)
1578 {
1579 mlan_status ret = MLAN_STATUS_SUCCESS;
1580 mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks;
1581 cmd_ctrl_node *pcmd_array = MNULL;
1582 t_u32 buf_size;
1583 t_u32 i;
1584
1585 ENTER();
1586
1587 /* Allocate and initialize cmd_ctrl_node */
1588 buf_size = sizeof(cmd_ctrl_node) * MRVDRV_NUM_OF_CMD_BUFFER;
1589 ret = pcb->moal_malloc(pmadapter->pmoal_handle, buf_size,
1590 MLAN_MEM_DEF | MLAN_MEM_DMA,
1591 (t_u8 **)&pcmd_array);
1592 if (ret != MLAN_STATUS_SUCCESS || !pcmd_array) {
1593 PRINTM(MERROR,
1594 "ALLOC_CMD_BUF: Failed to allocate pcmd_array\n");
1595 ret = MLAN_STATUS_FAILURE;
1596 goto done;
1597 }
1598
1599 pmadapter->cmd_pool = pcmd_array;
1600 memset(pmadapter, pmadapter->cmd_pool, 0, buf_size);
1601
1602 #if defined(PCIE) || defined(SDIO)
1603 if (!IS_USB(pmadapter->card_type)) {
1604 /* Allocate and initialize command buffers */
1605 for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
1606 pcmd_array[i].pmbuf = wlan_alloc_mlan_buffer(
1607 pmadapter, MRVDRV_SIZE_OF_CMD_BUFFER, 0,
1608 MOAL_MALLOC_BUFFER);
1609 if (!pcmd_array[i].pmbuf) {
1610 PRINTM(MERROR,
1611 "ALLOC_CMD_BUF: Failed to allocate command buffer\n");
1612 ret = MLAN_STATUS_FAILURE;
1613 goto done;
1614 }
1615 }
1616 }
1617 #endif
1618 wlan_request_cmd_lock(pmadapter);
1619 for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++)
1620 wlan_insert_cmd_to_free_q(pmadapter, &pcmd_array[i]);
1621 wlan_release_cmd_lock(pmadapter);
1622 ret = MLAN_STATUS_SUCCESS;
1623 done:
1624 LEAVE();
1625 return ret;
1626 }
1627
1628 /**
1629 * @brief This function frees the command buffer.
1630 *
1631 * @param pmadapter A pointer to mlan_adapter structure
1632 *
1633 * @return MLAN_STATUS_SUCCESS
1634 */
wlan_free_cmd_buffer(mlan_adapter * pmadapter)1635 mlan_status wlan_free_cmd_buffer(mlan_adapter *pmadapter)
1636 {
1637 mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks;
1638 cmd_ctrl_node *pcmd_array;
1639 t_u32 i;
1640
1641 ENTER();
1642
1643 /* Need to check if cmd pool is allocated or not */
1644 if (pmadapter->cmd_pool == MNULL) {
1645 PRINTM(MINFO, "FREE_CMD_BUF: cmd_pool is Null\n");
1646 goto done;
1647 }
1648
1649 pcmd_array = pmadapter->cmd_pool;
1650
1651 /* Release shared memory buffers */
1652 for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
1653 #ifdef USB
1654 if (IS_USB(pmadapter->card_type) && pcmd_array[i].cmdbuf) {
1655 PRINTM(MINFO, "Free all the USB command buffer.\n");
1656 wlan_free_mlan_buffer(pmadapter, pcmd_array[i].cmdbuf);
1657 pcmd_array[i].cmdbuf = MNULL;
1658 }
1659 #endif
1660 #if defined(SDIO) || defined(PCIE)
1661 if (!IS_USB(pmadapter->card_type) && pcmd_array[i].pmbuf) {
1662 PRINTM(MINFO, "Free all the command buffer.\n");
1663 wlan_free_mlan_buffer(pmadapter, pcmd_array[i].pmbuf);
1664 pcmd_array[i].pmbuf = MNULL;
1665 }
1666 #endif
1667 if (pcmd_array[i].respbuf) {
1668 #ifdef USB
1669 if (IS_USB(pmadapter->card_type))
1670 pmadapter->callbacks.moal_recv_complete(
1671 pmadapter->pmoal_handle,
1672 pcmd_array[i].respbuf,
1673 pmadapter->rx_cmd_ep,
1674 MLAN_STATUS_SUCCESS);
1675 #endif
1676 #if defined(SDIO) || defined(PCIE)
1677 if (!IS_USB(pmadapter->card_type))
1678 wlan_free_mlan_buffer(pmadapter,
1679 pcmd_array[i].respbuf);
1680 #endif
1681 pcmd_array[i].respbuf = MNULL;
1682 }
1683 }
1684 /* Release cmd_ctrl_node */
1685 if (pmadapter->cmd_pool) {
1686 PRINTM(MINFO, "Free command pool.\n");
1687 pcb->moal_mfree(pmadapter->pmoal_handle,
1688 (t_u8 *)pmadapter->cmd_pool);
1689 pmadapter->cmd_pool = MNULL;
1690 }
1691
1692 done:
1693 LEAVE();
1694 return MLAN_STATUS_SUCCESS;
1695 }
1696
1697 /**
1698 * @brief This function handles events generated by firmware
1699 *
1700 * @param pmadapter A pointer to mlan_adapter structure
1701 *
1702 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1703 */
wlan_process_event(pmlan_adapter pmadapter)1704 mlan_status wlan_process_event(pmlan_adapter pmadapter)
1705 {
1706 mlan_status ret = MLAN_STATUS_SUCCESS;
1707 pmlan_private priv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);
1708 pmlan_buffer pmbuf = pmadapter->pmlan_buffer_event;
1709 t_u32 eventcause = pmadapter->event_cause;
1710 #ifdef DEBUG_LEVEL1
1711 t_u32 in_ts_sec = 0, in_ts_usec = 0;
1712 #endif
1713 ENTER();
1714
1715 /* Save the last event to debug log */
1716 pmadapter->dbg.last_event_index =
1717 (pmadapter->dbg.last_event_index + 1) % DBG_CMD_NUM;
1718 pmadapter->dbg.last_event[pmadapter->dbg.last_event_index] =
1719 (t_u16)eventcause;
1720
1721 if ((eventcause & EVENT_ID_MASK) == EVENT_RADAR_DETECTED) {
1722 priv = wlan_get_priv_by_id(pmadapter,
1723 EVENT_GET_BSS_NUM(eventcause),
1724 EVENT_GET_BSS_TYPE(eventcause));
1725 if (priv && priv->bss_type != MLAN_BSS_TYPE_DFS) {
1726 if (wlan_11h_dfs_event_preprocessing(pmadapter) ==
1727 MLAN_STATUS_SUCCESS) {
1728 memcpy_ext(pmadapter, (t_u8 *)&eventcause,
1729 pmbuf->pbuf + pmbuf->data_offset,
1730 sizeof(eventcause),
1731 sizeof(eventcause));
1732 } else {
1733 priv = wlan_get_priv_by_id(
1734 pmadapter,
1735 EVENT_GET_BSS_NUM(eventcause),
1736 EVENT_GET_BSS_TYPE(eventcause));
1737 if (priv)
1738 PRINTM_NETINTF(MEVENT, priv);
1739 PRINTM(MERROR,
1740 "Error processing DFS Event: 0x%x\n",
1741 eventcause);
1742 goto done;
1743 }
1744 }
1745 }
1746 /* Get BSS number and corresponding priv */
1747 priv = wlan_get_priv_by_id(pmadapter, EVENT_GET_BSS_NUM(eventcause),
1748 EVENT_GET_BSS_TYPE(eventcause));
1749 if (!priv)
1750 priv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);
1751 if (!priv) {
1752 ret = MLAN_STATUS_FAILURE;
1753 goto done;
1754 }
1755
1756 /* Clear BSS_NO_BITS from event */
1757 eventcause &= EVENT_ID_MASK;
1758 pmadapter->event_cause = eventcause;
1759
1760 if (pmbuf) {
1761 pmbuf->bss_index = priv->bss_index;
1762 memcpy_ext(pmadapter, pmbuf->pbuf + pmbuf->data_offset,
1763 (t_u8 *)&eventcause, sizeof(eventcause),
1764 sizeof(eventcause));
1765 }
1766
1767 if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE &&
1768 eventcause != EVENT_FW_DUMP_INFO) {
1769 PRINTM_GET_SYS_TIME(MEVENT, &in_ts_sec, &in_ts_usec);
1770 PRINTM_NETINTF(MEVENT, priv);
1771 PRINTM(MEVENT, "%lu.%06lu : Event: 0x%x\n", in_ts_sec,
1772 in_ts_usec, eventcause);
1773 }
1774
1775 ret = priv->ops.process_event(priv);
1776 done:
1777 pmadapter->event_cause = 0;
1778 pmadapter->pmlan_buffer_event = MNULL;
1779 if (pmbuf)
1780 pmadapter->ops.event_complete(pmadapter, pmbuf,
1781 MLAN_STATUS_SUCCESS);
1782
1783 LEAVE();
1784 return ret;
1785 }
1786
1787 /**
1788 * @brief This function requests a lock on command queue.
1789 *
1790 * @param pmadapter A pointer to mlan_adapter structure
1791 *
1792 * @return N/A
1793 */
wlan_request_cmd_lock(mlan_adapter * pmadapter)1794 t_void wlan_request_cmd_lock(mlan_adapter *pmadapter)
1795 {
1796 mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks;
1797
1798 ENTER();
1799
1800 /* Call MOAL spin lock callback function */
1801 pcb->moal_spin_lock(pmadapter->pmoal_handle, pmadapter->pmlan_cmd_lock);
1802
1803 LEAVE();
1804 return;
1805 }
1806
1807 /**
1808 * @brief This function releases a lock on command queue.
1809 *
1810 * @param pmadapter A pointer to mlan_adapter structure
1811 *
1812 * @return N/A
1813 */
wlan_release_cmd_lock(mlan_adapter * pmadapter)1814 t_void wlan_release_cmd_lock(mlan_adapter *pmadapter)
1815 {
1816 mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks;
1817
1818 ENTER();
1819
1820 /* Call MOAL spin unlock callback function */
1821 pcb->moal_spin_unlock(pmadapter->pmoal_handle,
1822 pmadapter->pmlan_cmd_lock);
1823
1824 LEAVE();
1825 return;
1826 }
1827
1828 /**
1829 * @brief This function prepare the command before sending to firmware.
1830 *
1831 * @param pmpriv A pointer to mlan_private structure
1832 * @param cmd_no Command number
1833 * @param cmd_action Command action: GET or SET
1834 * @param cmd_oid Cmd oid: treated as sub command
1835 * @param pioctl_buf A pointer to MLAN IOCTL Request buffer
1836 * @param pdata_buf A pointer to information buffer
1837 *
1838 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1839 */
wlan_prepare_cmd(mlan_private * pmpriv,t_u16 cmd_no,t_u16 cmd_action,t_u32 cmd_oid,t_void * pioctl_buf,t_void * pdata_buf)1840 mlan_status wlan_prepare_cmd(mlan_private *pmpriv, t_u16 cmd_no,
1841 t_u16 cmd_action, t_u32 cmd_oid,
1842 t_void *pioctl_buf, t_void *pdata_buf)
1843 {
1844 mlan_status ret = MLAN_STATUS_SUCCESS;
1845 mlan_adapter *pmadapter = MNULL;
1846 cmd_ctrl_node *pcmd_node = MNULL;
1847 HostCmd_DS_COMMAND *cmd_ptr = MNULL;
1848 pmlan_ioctl_req pioctl_req = (mlan_ioctl_req *)pioctl_buf;
1849
1850 ENTER();
1851
1852 if (!pmpriv) {
1853 LEAVE();
1854 return MLAN_STATUS_FAILURE;
1855 }
1856 pmadapter = pmpriv->adapter;
1857
1858 /* Sanity test */
1859 if (!pmadapter || pmadapter->surprise_removed) {
1860 PRINTM(MERROR, "PREP_CMD: Card is Removed\n");
1861 if (pioctl_req)
1862 pioctl_req->status_code = MLAN_ERROR_FW_NOT_READY;
1863 ret = MLAN_STATUS_FAILURE;
1864 goto done;
1865 }
1866
1867 if (pmadapter->hw_status == WlanHardwareStatusReset) {
1868 if ((cmd_no != HostCmd_CMD_FUNC_INIT)
1869 #ifdef PCIE
1870 && (cmd_no != HostCmd_CMD_PCIE_HOST_BUF_DETAILS)
1871 #endif
1872 ) {
1873 PRINTM(MERROR, "PREP_CMD: FW is in reset state\n");
1874 if (pioctl_req)
1875 pioctl_req->status_code =
1876 MLAN_ERROR_FW_NOT_READY;
1877 ret = MLAN_STATUS_FAILURE;
1878 goto done;
1879 }
1880 }
1881
1882 /* Get a new command node */
1883 pcmd_node = wlan_get_cmd_node(pmadapter);
1884
1885 if (pcmd_node == MNULL) {
1886 PRINTM(MERROR, "PREP_CMD: No free cmd node\n");
1887 wlan_dump_info(pmadapter, REASON_CODE_NO_CMD_NODE);
1888 if (pioctl_req)
1889 pioctl_req->status_code = MLAN_ERROR_NO_MEM;
1890 ret = MLAN_STATUS_FAILURE;
1891 goto done;
1892 }
1893 /** reset num no cmd node */
1894 pmadapter->dbg.num_no_cmd_node = 0;
1895
1896 /* Initialize the command node */
1897 wlan_init_cmd_node(pmpriv, pcmd_node, cmd_no, pioctl_buf, pdata_buf);
1898
1899 if (pcmd_node->cmdbuf == MNULL) {
1900 PRINTM(MERROR, "PREP_CMD: No free cmd buf\n");
1901 if (pioctl_req)
1902 pioctl_req->status_code = MLAN_ERROR_NO_MEM;
1903 ret = MLAN_STATUS_FAILURE;
1904 goto done;
1905 }
1906
1907 cmd_ptr = (HostCmd_DS_COMMAND *)(pcmd_node->cmdbuf->pbuf +
1908 pcmd_node->cmdbuf->data_offset);
1909 cmd_ptr->command = cmd_no;
1910 cmd_ptr->result = 0;
1911
1912 /* Prepare command */
1913 if (cmd_no)
1914 ret = pmpriv->ops.prepare_cmd(pmpriv, cmd_no, cmd_action,
1915 cmd_oid, pioctl_buf, pdata_buf,
1916 cmd_ptr);
1917 else {
1918 ret = wlan_cmd_host_cmd(pmpriv, cmd_ptr, pdata_buf, &cmd_no);
1919 pcmd_node->cmd_flag |= CMD_F_HOSTCMD;
1920 }
1921
1922 /* Return error, since the command preparation failed */
1923 if (ret != MLAN_STATUS_SUCCESS) {
1924 PRINTM(MERROR, "PREP_CMD: Command 0x%x preparation failed\n",
1925 cmd_no);
1926 pcmd_node->pioctl_buf = MNULL;
1927 if (pioctl_req)
1928 pioctl_req->status_code = MLAN_ERROR_CMD_DNLD_FAIL;
1929 wlan_request_cmd_lock(pmadapter);
1930 wlan_insert_cmd_to_free_q(pmadapter, pcmd_node);
1931 wlan_release_cmd_lock(pmadapter);
1932 ret = MLAN_STATUS_FAILURE;
1933 goto done;
1934 }
1935
1936 wlan_request_cmd_lock(pmadapter);
1937 /* Send command */
1938 #ifdef STA_SUPPORT
1939 if (cmd_no == HostCmd_CMD_802_11_SCAN ||
1940 cmd_no == HostCmd_CMD_802_11_SCAN_EXT) {
1941 if (cmd_no == HostCmd_CMD_802_11_SCAN_EXT &&
1942 pmadapter->ext_scan && pmadapter->ext_scan_enh &&
1943 pmadapter->ext_scan_type == EXT_SCAN_ENHANCE &&
1944 wlan_is_cancel_scan_cmd(cmd_ptr)) {
1945 wlan_insert_cmd_to_pending_q(pmadapter, pcmd_node,
1946 MFALSE);
1947 } else
1948
1949 wlan_queue_scan_cmd(pmpriv, pcmd_node);
1950 } else {
1951 #endif
1952 if ((cmd_no == HostCmd_CMD_802_11_HS_CFG_ENH) &&
1953 (cmd_action == HostCmd_ACT_GEN_SET) &&
1954 (pmadapter->hs_cfg.conditions == HOST_SLEEP_CFG_CANCEL))
1955 wlan_insert_cmd_to_pending_q(pmadapter, pcmd_node,
1956 MFALSE);
1957 else
1958 wlan_queue_cmd(pmpriv, pcmd_node, cmd_no);
1959 #ifdef STA_SUPPORT
1960 }
1961 #endif
1962 wlan_release_cmd_lock(pmadapter);
1963 done:
1964 LEAVE();
1965 return ret;
1966 }
1967
1968 /**
1969 * @brief This function inserts command node to cmd_free_q
1970 * after cleaning it.
1971 *
1972 * @param pmadapter A pointer to mlan_adapter structure
1973 * @param pcmd_node A pointer to cmd_ctrl_node structure
1974 *
1975 * @return N/A
1976 */
wlan_insert_cmd_to_free_q(mlan_adapter * pmadapter,cmd_ctrl_node * pcmd_node)1977 t_void wlan_insert_cmd_to_free_q(mlan_adapter *pmadapter,
1978 cmd_ctrl_node *pcmd_node)
1979 {
1980 mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks;
1981 mlan_ioctl_req *pioctl_req = MNULL;
1982 ENTER();
1983
1984 if (pcmd_node == MNULL)
1985 goto done;
1986 if (pcmd_node->pioctl_buf) {
1987 pioctl_req = (mlan_ioctl_req *)pcmd_node->pioctl_buf;
1988 if (pioctl_req->status_code != MLAN_ERROR_NO_ERROR)
1989 pcb->moal_ioctl_complete(pmadapter->pmoal_handle,
1990 pioctl_req,
1991 MLAN_STATUS_FAILURE);
1992 else
1993 pcb->moal_ioctl_complete(pmadapter->pmoal_handle,
1994 pioctl_req,
1995 MLAN_STATUS_SUCCESS);
1996 }
1997 /* Clean the node */
1998 wlan_clean_cmd_node(pmadapter, pcmd_node);
1999
2000 /* Insert node into cmd_free_q */
2001 util_enqueue_list_tail(pmadapter->pmoal_handle, &pmadapter->cmd_free_q,
2002 (pmlan_linked_list)pcmd_node, MNULL, MNULL);
2003 done:
2004 LEAVE();
2005 }
2006
2007 /**
2008 * @brief This function queues the command to cmd list.
2009 *
2010 * @param pmadapter A pointer to mlan_adapter structure
2011 * @param pcmd_node A pointer to cmd_ctrl_node structure
2012 * @param add_tail Specify if the cmd needs to be queued in the header or
2013 * tail
2014 *
2015 * @return N/A
2016 */
wlan_insert_cmd_to_pending_q(mlan_adapter * pmadapter,cmd_ctrl_node * pcmd_node,t_u32 add_tail)2017 t_void wlan_insert_cmd_to_pending_q(mlan_adapter *pmadapter,
2018 cmd_ctrl_node *pcmd_node, t_u32 add_tail)
2019 {
2020 HostCmd_DS_COMMAND *pcmd = MNULL;
2021 t_u16 command;
2022
2023 ENTER();
2024
2025 if (pcmd_node == MNULL) {
2026 PRINTM(MERROR, "QUEUE_CMD: pcmd_node is MNULL\n");
2027 goto done;
2028 }
2029
2030 pcmd = (HostCmd_DS_COMMAND *)(pcmd_node->cmdbuf->pbuf +
2031 pcmd_node->cmdbuf->data_offset);
2032
2033 command = wlan_le16_to_cpu(pcmd->command);
2034
2035 /* Exit_PS command needs to be queued in the header always. */
2036 if (command == HostCmd_CMD_802_11_PS_MODE_ENH) {
2037 HostCmd_DS_802_11_PS_MODE_ENH *pm = &pcmd->params.psmode_enh;
2038 if (wlan_le16_to_cpu(pm->action) == DIS_AUTO_PS) {
2039 if (pmadapter->ps_state != PS_STATE_AWAKE)
2040 add_tail = MFALSE;
2041 }
2042 }
2043
2044 if (add_tail) {
2045 util_enqueue_list_tail(pmadapter->pmoal_handle,
2046 &pmadapter->cmd_pending_q,
2047 (pmlan_linked_list)pcmd_node, MNULL,
2048 MNULL);
2049 } else {
2050 util_enqueue_list_head(pmadapter->pmoal_handle,
2051 &pmadapter->cmd_pending_q,
2052 (pmlan_linked_list)pcmd_node, MNULL,
2053 MNULL);
2054 }
2055
2056 PRINTM_NETINTF(MCMND, pcmd_node->priv);
2057 PRINTM(MCMND, "QUEUE_CMD: cmd=0x%x is queued\n", command);
2058
2059 done:
2060 LEAVE();
2061 return;
2062 }
2063
2064 /**
2065 * @brief This function executes next command in command
2066 * pending queue. It will put firmware back to PS mode
2067 * if applicable.
2068 *
2069 * @param pmadapter A pointer to mlan_adapter structure
2070 *
2071 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
2072 */
wlan_exec_next_cmd(mlan_adapter * pmadapter)2073 mlan_status wlan_exec_next_cmd(mlan_adapter *pmadapter)
2074 {
2075 mlan_private *priv = MNULL;
2076 cmd_ctrl_node *pcmd_node = MNULL;
2077 mlan_status ret = MLAN_STATUS_SUCCESS;
2078 HostCmd_DS_COMMAND *pcmd;
2079
2080 ENTER();
2081
2082 /* Sanity test */
2083 if (pmadapter == MNULL) {
2084 PRINTM(MERROR, "EXEC_NEXT_CMD: pmadapter is MNULL\n");
2085 ret = MLAN_STATUS_FAILURE;
2086 goto done;
2087 }
2088 /* Check if already in processing */
2089 if (pmadapter->curr_cmd) {
2090 PRINTM(MERROR,
2091 "EXEC_NEXT_CMD: there is command in processing!\n");
2092 ret = MLAN_STATUS_FAILURE;
2093 goto done;
2094 }
2095
2096 wlan_request_cmd_lock(pmadapter);
2097 /* Check if any command is pending */
2098 pcmd_node = (cmd_ctrl_node *)util_peek_list(pmadapter->pmoal_handle,
2099 &pmadapter->cmd_pending_q,
2100 MNULL, MNULL);
2101
2102 if (pcmd_node) {
2103 pcmd = (HostCmd_DS_COMMAND *)(pcmd_node->cmdbuf->pbuf +
2104 pcmd_node->cmdbuf->data_offset);
2105 priv = pcmd_node->priv;
2106
2107 if (pmadapter->ps_state != PS_STATE_AWAKE) {
2108 PRINTM(MERROR,
2109 "Cannot send command in sleep state, this should not happen\n");
2110 wlan_release_cmd_lock(pmadapter);
2111 goto done;
2112 }
2113
2114 util_unlink_list(pmadapter->pmoal_handle,
2115 &pmadapter->cmd_pending_q,
2116 (pmlan_linked_list)pcmd_node, MNULL, MNULL);
2117 wlan_release_cmd_lock(pmadapter);
2118 ret = wlan_dnld_cmd_to_fw(priv, pcmd_node);
2119 priv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);
2120 /* Any command sent to the firmware when host is in sleep mode,
2121 * should de-configure host sleep */
2122 /* We should skip the host sleep configuration command itself
2123 * though */
2124 if (priv && (pcmd->command !=
2125 wlan_cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH))) {
2126 if (pmadapter->hs_activated == MTRUE) {
2127 pmadapter->is_hs_configured = MFALSE;
2128 wlan_host_sleep_activated_event(priv, MFALSE);
2129 }
2130 }
2131 goto done;
2132 } else {
2133 wlan_release_cmd_lock(pmadapter);
2134 }
2135 ret = MLAN_STATUS_SUCCESS;
2136 done:
2137 LEAVE();
2138 return ret;
2139 }
2140
2141 /**
2142 * @brief This function handles the command response
2143 *
2144 * @param pmadapter A pointer to mlan_adapter structure
2145 *
2146 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
2147 */
wlan_process_cmdresp(mlan_adapter * pmadapter)2148 mlan_status wlan_process_cmdresp(mlan_adapter *pmadapter)
2149 {
2150 HostCmd_DS_COMMAND *resp = MNULL;
2151 mlan_private *pmpriv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);
2152 mlan_private *pmpriv_next = MNULL;
2153 mlan_status ret = MLAN_STATUS_SUCCESS;
2154 t_u16 orig_cmdresp_no;
2155 t_u16 cmdresp_no;
2156 t_u16 cmdresp_result;
2157 mlan_ioctl_req *pioctl_buf = MNULL;
2158 mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks;
2159 #ifdef DEBUG_LEVEL1
2160 t_u32 sec = 0, usec = 0;
2161 #endif
2162 t_u32 i;
2163
2164 ENTER();
2165
2166 if (pmadapter->curr_cmd)
2167 if (pmadapter->curr_cmd->pioctl_buf != MNULL) {
2168 pioctl_buf = (mlan_ioctl_req *)
2169 pmadapter->curr_cmd->pioctl_buf;
2170 }
2171
2172 if (!pmadapter->curr_cmd || !pmadapter->curr_cmd->respbuf) {
2173 resp = (HostCmd_DS_COMMAND *)pmadapter->upld_buf;
2174 resp->command = wlan_le16_to_cpu(resp->command);
2175 PRINTM(MERROR, "CMD_RESP: No curr_cmd, 0x%x\n", resp->command);
2176 if (pioctl_buf)
2177 pioctl_buf->status_code = MLAN_ERROR_CMD_RESP_FAIL;
2178 ret = MLAN_STATUS_FAILURE;
2179 goto done;
2180 }
2181
2182 DBG_HEXDUMP(MCMD_D, "CMD_RESP",
2183 pmadapter->curr_cmd->respbuf->pbuf +
2184 pmadapter->curr_cmd->respbuf->data_offset,
2185 pmadapter->curr_cmd->respbuf->data_len);
2186
2187 resp = (HostCmd_DS_COMMAND *)(pmadapter->curr_cmd->respbuf->pbuf +
2188 pmadapter->curr_cmd->respbuf->data_offset);
2189 orig_cmdresp_no = wlan_le16_to_cpu(resp->command);
2190 cmdresp_no = (orig_cmdresp_no & HostCmd_CMD_ID_MASK);
2191 if (pmadapter->curr_cmd->cmd_no != cmdresp_no) {
2192 PRINTM(MERROR, "cmdresp error: cmd=0x%x cmd_resp=0x%x\n",
2193 pmadapter->curr_cmd->cmd_no, cmdresp_no);
2194 ret = MLAN_STATUS_FAILURE;
2195 goto done;
2196 }
2197 pmadapter->dnld_cmd_in_secs = 0;
2198 /* Now we got response from FW, cancel the command timer */
2199 if (pmadapter->cmd_timer_is_set) {
2200 /* Cancel command timeout timer */
2201 pcb->moal_stop_timer(pmadapter->pmoal_handle,
2202 pmadapter->pmlan_cmd_timer);
2203 /* Cancel command timeout timer */
2204 pmadapter->cmd_timer_is_set = MFALSE;
2205 }
2206 pmadapter->num_cmd_timeout = 0;
2207 wlan_request_cmd_lock(pmadapter);
2208 if (pmadapter->curr_cmd->cmd_flag & CMD_F_CANCELED) {
2209 cmd_ctrl_node *free_cmd = pmadapter->curr_cmd;
2210 pmadapter->curr_cmd = MNULL;
2211 PRINTM(MCMND, "CMD_RESP: 0x%x been canceled!\n",
2212 wlan_le16_to_cpu(resp->command));
2213 if (pioctl_buf)
2214 pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL;
2215 wlan_insert_cmd_to_free_q(pmadapter, free_cmd);
2216 wlan_release_cmd_lock(pmadapter);
2217 ret = MLAN_STATUS_FAILURE;
2218 goto done;
2219 } else {
2220 wlan_release_cmd_lock(pmadapter);
2221 }
2222 if (pmadapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) {
2223 /* Copy original response back to response buffer */
2224 if (pmpriv)
2225 wlan_ret_host_cmd(pmpriv, resp, pioctl_buf);
2226 }
2227 resp->size = wlan_le16_to_cpu(resp->size);
2228 resp->seq_num = wlan_le16_to_cpu(resp->seq_num);
2229 resp->result = wlan_le16_to_cpu(resp->result);
2230
2231 /* Get BSS number and corresponding priv */
2232 pmpriv = wlan_get_priv_by_id(pmadapter,
2233 HostCmd_GET_BSS_NO(resp->seq_num),
2234 HostCmd_GET_BSS_TYPE(resp->seq_num));
2235 if (!pmpriv)
2236 pmpriv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);
2237 /* Clear RET_BIT from HostCmd */
2238 resp->command = (orig_cmdresp_no & HostCmd_CMD_ID_MASK);
2239 if (!pmpriv) {
2240 ret = MLAN_STATUS_FAILURE;
2241 goto done;
2242 }
2243 cmdresp_no = resp->command;
2244
2245 cmdresp_result = resp->result;
2246
2247 /* Save the last command response to debug log */
2248 pmadapter->dbg.last_cmd_resp_index =
2249 (pmadapter->dbg.last_cmd_resp_index + 1) % DBG_CMD_NUM;
2250 pmadapter->dbg.last_cmd_resp_id[pmadapter->dbg.last_cmd_resp_index] =
2251 orig_cmdresp_no;
2252
2253 PRINTM_GET_SYS_TIME(MCMND, &sec, &usec);
2254 PRINTM_NETINTF(MCMND, pmadapter->curr_cmd->priv);
2255 PRINTM(MCMND,
2256 "CMD_RESP (%lu.%06lu): 0x%x, result %d, len %d, seqno 0x%x\n",
2257 sec, usec, orig_cmdresp_no, cmdresp_result, resp->size,
2258 resp->seq_num);
2259
2260 if (!(orig_cmdresp_no & HostCmd_RET_BIT)) {
2261 PRINTM(MERROR, "CMD_RESP: Invalid response to command!\n");
2262 if (pioctl_buf)
2263 pioctl_buf->status_code = MLAN_ERROR_FW_CMDRESP;
2264 wlan_request_cmd_lock(pmadapter);
2265 wlan_insert_cmd_to_free_q(pmadapter, pmadapter->curr_cmd);
2266 pmadapter->curr_cmd = MNULL;
2267 wlan_release_cmd_lock(pmadapter);
2268 ret = MLAN_STATUS_FAILURE;
2269 goto done;
2270 }
2271
2272 if (pmadapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) {
2273 pmadapter->curr_cmd->cmd_flag &= ~CMD_F_HOSTCMD;
2274 if ((cmdresp_result == HostCmd_RESULT_OK) &&
2275 (cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH))
2276 ret = wlan_ret_802_11_hs_cfg(pmpriv, resp, pioctl_buf);
2277 } else {
2278 /* handle response */
2279 ret = pmpriv->ops.process_cmdresp(pmpriv, cmdresp_no, resp,
2280 pioctl_buf);
2281 }
2282
2283 /* Check init command response */
2284 if (pmadapter->hw_status == WlanHardwareStatusInitializing ||
2285 pmadapter->hw_status == WlanHardwareStatusGetHwSpec) {
2286 if (ret == MLAN_STATUS_FAILURE) {
2287 #if 0
2288 //ignore command error for WARM RESET
2289 if (pmadapter->pwarm_reset_ioctl_req) {
2290 /* warm reset failure */
2291 pmadapter->pwarm_reset_ioctl_req->status_code =
2292 MLAN_ERROR_CMD_RESP_FAIL;
2293 pcb->moal_ioctl_complete(
2294 pmadapter->pmoal_handle,
2295 pmadapter->pwarm_reset_ioctl_req,
2296 MLAN_STATUS_FAILURE);
2297 pmadapter->pwarm_reset_ioctl_req = MNULL;
2298 goto done;
2299 }
2300 #endif
2301 PRINTM(MERROR,
2302 "cmd 0x%02x failed during initialization\n",
2303 cmdresp_no);
2304 wlan_init_fw_complete(pmadapter);
2305 goto done;
2306 }
2307 #ifdef STA_SUPPORT
2308 #ifdef PCIE
2309 /* init adma write pointer */
2310 if (IS_PCIE(pmadapter->card_type) &&
2311 cmdresp_no == HostCmd_CMD_FUNC_SHUTDOWN &&
2312 pmadapter->pwarm_reset_ioctl_req) {
2313 #if defined(PCIE9098) || defined(PCIE9097) || defined(PCIENW62X)
2314 if (pmadapter->pcard_pcie->reg->use_adma)
2315 #endif
2316 wlan_pcie_init_fw(pmadapter);
2317 }
2318 #endif
2319 #endif
2320 }
2321
2322 wlan_request_cmd_lock(pmadapter);
2323 if (pmadapter->curr_cmd) {
2324 cmd_ctrl_node *free_cmd = pmadapter->curr_cmd;
2325 pioctl_buf = (mlan_ioctl_req *)pmadapter->curr_cmd->pioctl_buf;
2326 pmadapter->curr_cmd = MNULL;
2327 if (pioctl_buf && (ret == MLAN_STATUS_SUCCESS))
2328 pioctl_buf->status_code = MLAN_ERROR_NO_ERROR;
2329 else if (pioctl_buf && (ret == MLAN_STATUS_FAILURE) &&
2330 !pioctl_buf->status_code)
2331 pioctl_buf->status_code = MLAN_ERROR_CMD_RESP_FAIL;
2332
2333 /* Clean up and put current command back to cmd_free_q */
2334 wlan_insert_cmd_to_free_q(pmadapter, free_cmd);
2335 }
2336 wlan_release_cmd_lock(pmadapter);
2337
2338 if ((pmadapter->hw_status == WlanHardwareStatusInitializing) &&
2339 (pmadapter->last_init_cmd == cmdresp_no)) {
2340 i = pmpriv->bss_index + 1;
2341 while (i < pmadapter->priv_num &&
2342 (!(pmpriv_next = pmadapter->priv[i]) ||
2343 pmpriv_next->bss_virtual ||
2344 pmpriv_next->bss_type == MLAN_BSS_TYPE_DFS))
2345 i++;
2346 if (!pmpriv_next || i >= pmadapter->priv_num) {
2347 #ifdef STA_SUPPORT
2348 if (pmadapter->pwarm_reset_ioctl_req) {
2349 for (i = 0; i < pmadapter->priv_num; i++) {
2350 if (pmadapter->priv[i]->curr_addr[0] ==
2351 0xff)
2352 memmove(pmadapter,
2353 pmadapter->priv[i]
2354 ->curr_addr,
2355 pmadapter->permanent_addr,
2356 MLAN_MAC_ADDR_LENGTH);
2357 }
2358 /* warm reset complete */
2359 PRINTM(MMSG, "wlan: warm reset complete\n");
2360 pmadapter->hw_status = WlanHardwareStatusReady;
2361 pcb->moal_ioctl_complete(
2362 pmadapter->pmoal_handle,
2363 pmadapter->pwarm_reset_ioctl_req,
2364 MLAN_STATUS_SUCCESS);
2365 pmadapter->pwarm_reset_ioctl_req = MNULL;
2366 goto done;
2367 }
2368 #endif
2369 pmadapter->hw_status = WlanHardwareStatusInitdone;
2370 } else {
2371 /* Issue init commands for the next interface */
2372 ret = pmpriv_next->ops.init_cmd(pmpriv_next, MFALSE);
2373 }
2374 } else if ((pmadapter->hw_status == WlanHardwareStatusGetHwSpec) &&
2375 (HostCmd_CMD_GET_HW_SPEC == cmdresp_no)) {
2376 pmadapter->hw_status = WlanHardwareStatusGetHwSpecdone;
2377 }
2378 done:
2379 LEAVE();
2380 return ret;
2381 }
2382
2383 /**
2384 * @brief This function handles the timeout of command sending.
2385 * It will re-send the same command again.
2386 *
2387 * @param function_context A pointer to function_context
2388 * @return N/A
2389 */
wlan_cmd_timeout_func(t_void * function_context)2390 t_void wlan_cmd_timeout_func(t_void *function_context)
2391 {
2392 mlan_adapter *pmadapter = (mlan_adapter *)function_context;
2393 cmd_ctrl_node *pcmd_node = MNULL;
2394 mlan_ioctl_req *pioctl_buf = MNULL;
2395 #ifdef DEBUG_LEVEL1
2396 t_u32 sec = 0, usec = 0;
2397 #endif
2398 #if defined(SDIO) || defined(PCIE)
2399 t_u8 i;
2400 #endif
2401 mlan_private *pmpriv = MNULL;
2402
2403 ENTER();
2404
2405 pmadapter->cmd_timer_is_set = MFALSE;
2406 if (!pmadapter->curr_cmd) {
2407 if (pmadapter->ext_scan && pmadapter->ext_scan_enh &&
2408 pmadapter->scan_processing) {
2409 PRINTM(MMSG, "Ext scan enh timeout\n");
2410 pmadapter->ext_scan_timeout = MTRUE;
2411 wlan_dump_info(pmadapter, REASON_CODE_EXT_SCAN_TIMEOUT);
2412 goto exit;
2413 }
2414 PRINTM(MWARN, "CurCmd Empty\n");
2415 goto exit;
2416 }
2417 pmadapter->num_cmd_timeout++;
2418 pcmd_node = pmadapter->curr_cmd;
2419 if (pcmd_node->pioctl_buf != MNULL) {
2420 pioctl_buf = (mlan_ioctl_req *)pcmd_node->pioctl_buf;
2421 pioctl_buf->status_code = MLAN_ERROR_CMD_TIMEOUT;
2422 }
2423
2424 pmadapter->dbg.timeout_cmd_id =
2425 pmadapter->dbg.last_cmd_id[pmadapter->dbg.last_cmd_index];
2426 pmadapter->dbg.timeout_cmd_act =
2427 pmadapter->dbg.last_cmd_act[pmadapter->dbg.last_cmd_index];
2428 PRINTM_GET_SYS_TIME(MERROR, &sec, &usec);
2429 PRINTM(MERROR, "Timeout cmd id (%lu.%06lu) = 0x%x, act = 0x%x\n", sec,
2430 usec, pmadapter->dbg.timeout_cmd_id,
2431 pmadapter->dbg.timeout_cmd_act);
2432 #if defined(SDIO) || defined(PCIE)
2433 if (!IS_USB(pmadapter->card_type) && pcmd_node->cmdbuf) {
2434 t_u8 *pcmd_buf;
2435 pcmd_buf = pcmd_node->cmdbuf->pbuf +
2436 pcmd_node->cmdbuf->data_offset +
2437 pmadapter->ops.intf_header_len;
2438 for (i = 0; i < 16; i++)
2439 PRINTM(MERROR, "%02x ", *pcmd_buf++);
2440 PRINTM(MERROR, "\n");
2441 }
2442 #endif
2443 #ifdef PCIE
2444 if (IS_PCIE(pmadapter->card_type))
2445 pmadapter->ops.debug_dump(pmadapter);
2446 #endif
2447 pmpriv = pcmd_node->priv;
2448 if (pmpriv)
2449 PRINTM(MERROR, "BSS type = %d BSS role= %d\n", pmpriv->bss_type,
2450 pmpriv->bss_role);
2451 wlan_dump_info(pmadapter, REASON_CODE_CMD_TIMEOUT);
2452
2453 if (pmadapter->hw_status == WlanHardwareStatusInitializing ||
2454 pmadapter->hw_status == WlanHardwareStatusGetHwSpec)
2455 wlan_init_fw_complete(pmadapter);
2456 else {
2457 /* Signal MOAL to perform extra handling for debugging */
2458 if (pmpriv) {
2459 wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_DBG_DUMP,
2460 MNULL);
2461 } else {
2462 wlan_recv_event(wlan_get_priv(pmadapter,
2463 MLAN_BSS_ROLE_ANY),
2464 MLAN_EVENT_ID_DRV_DBG_DUMP, MNULL);
2465 }
2466 }
2467
2468 exit:
2469 LEAVE();
2470 return;
2471 }
2472
2473 #ifdef STA_SUPPORT
2474 /**
2475 * @brief Internal function used to flush the scan pending queue
2476 *
2477 * @param pmadapter A pointer to mlan_adapter structure
2478 *
2479 * @return N/A
2480 */
wlan_flush_scan_queue(pmlan_adapter pmadapter)2481 t_void wlan_flush_scan_queue(pmlan_adapter pmadapter)
2482 {
2483 cmd_ctrl_node *pcmd_node = MNULL;
2484 mlan_ioctl_req *pioctl_buf = MNULL;
2485 HostCmd_DS_COMMAND *pcmd = MNULL;
2486 t_u16 cmd_no = 0;
2487 pmlan_callbacks pcb = &pmadapter->callbacks;
2488 ENTER();
2489
2490 wlan_request_cmd_lock(pmadapter);
2491 while ((pcmd_node = (cmd_ctrl_node *)util_peek_list(
2492 pmadapter->pmoal_handle, &pmadapter->scan_pending_q,
2493 MNULL, MNULL))) {
2494 util_unlink_list(pmadapter->pmoal_handle,
2495 &pmadapter->scan_pending_q,
2496 (pmlan_linked_list)pcmd_node, MNULL, MNULL);
2497 pcmd = (HostCmd_DS_COMMAND *)(pcmd_node->cmdbuf->pbuf +
2498 pcmd_node->cmdbuf->data_offset);
2499 cmd_no = wlan_le16_to_cpu(pcmd->command);
2500 PRINTM(MCMND, "flush scan queue: cmd 0x%02x\n", cmd_no);
2501 if (pcmd_node->pioctl_buf &&
2502 cmd_no != HostCmd_CMD_802_11_SCAN &&
2503 cmd_no != HostCmd_CMD_802_11_SCAN_EXT) {
2504 pioctl_buf = (mlan_ioctl_req *)pcmd_node->pioctl_buf;
2505 pcmd_node->pioctl_buf = MNULL;
2506 pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL;
2507 pcb->moal_ioctl_complete(pmadapter->pmoal_handle,
2508 pioctl_buf,
2509 MLAN_STATUS_FAILURE);
2510 }
2511 wlan_insert_cmd_to_free_q(pmadapter, pcmd_node);
2512 }
2513
2514 pmadapter->scan_processing = MFALSE;
2515 wlan_release_cmd_lock(pmadapter);
2516
2517 LEAVE();
2518 }
2519
2520 /**
2521 * @brief Cancel pending SCAN ioctl cmd.
2522 *
2523 * @param pmadapter A pointer to mlan_adapter
2524 * @param pioctl_req A pointer to pmlan_ioctl_req
2525 *
2526 * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING
2527 */
wlan_cancel_pending_scan_cmd(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)2528 mlan_status wlan_cancel_pending_scan_cmd(pmlan_adapter pmadapter,
2529 pmlan_ioctl_req pioctl_req)
2530 {
2531 pmlan_callbacks pcb = &pmadapter->callbacks;
2532 cmd_ctrl_node *pcmd_node = MNULL;
2533 mlan_ioctl_req *pioctl_buf = MNULL;
2534 pmlan_private priv = MNULL;
2535 mlan_status status = MLAN_STATUS_SUCCESS;
2536 ENTER();
2537
2538 PRINTM(MIOCTL, "Cancel scan command\n");
2539 wlan_request_cmd_lock(pmadapter);
2540 /* IOCTL will be completed, avoid calling IOCTL complete again from
2541 * EVENT/CMDRESP */
2542 if (pmadapter->pscan_ioctl_req) {
2543 pioctl_buf = pmadapter->pscan_ioctl_req;
2544 priv = pmadapter->priv[pioctl_buf->bss_index];
2545 pmadapter->pscan_ioctl_req = MNULL;
2546 pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL;
2547 pcb->moal_ioctl_complete(pmadapter->pmoal_handle, pioctl_buf,
2548 MLAN_STATUS_FAILURE);
2549 }
2550
2551 if (pmadapter->curr_cmd && pmadapter->curr_cmd->pioctl_buf) {
2552 pioctl_buf = (mlan_ioctl_req *)pmadapter->curr_cmd->pioctl_buf;
2553 if (pioctl_buf->req_id == MLAN_IOCTL_SCAN) {
2554 PRINTM(MIOCTL, "wlan_cancel_scan: current command\n");
2555 pcmd_node = pmadapter->curr_cmd;
2556 pcmd_node->pioctl_buf = MNULL;
2557 pcmd_node->cmd_flag |= CMD_F_CANCELED;
2558 pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL;
2559 pcb->moal_ioctl_complete(pmadapter->pmoal_handle,
2560 pioctl_buf,
2561 MLAN_STATUS_FAILURE);
2562 }
2563 }
2564 while ((pcmd_node = wlan_get_pending_scan_cmd(pmadapter)) != MNULL) {
2565 PRINTM(MIOCTL,
2566 "wlan_cancel_scan: find scan command in cmd_pending_q\n");
2567 util_unlink_list(pmadapter->pmoal_handle,
2568 &pmadapter->cmd_pending_q,
2569 (pmlan_linked_list)pcmd_node, MNULL, MNULL);
2570 wlan_insert_cmd_to_free_q(pmadapter, pcmd_node);
2571 }
2572 wlan_release_cmd_lock(pmadapter);
2573 if (pmadapter->scan_processing &&
2574 pmadapter->ext_scan_type == EXT_SCAN_ENHANCE) {
2575 if (priv) {
2576 if (MLAN_STATUS_SUCCESS ==
2577 wlan_prepare_cmd(priv, HostCmd_CMD_802_11_SCAN_EXT,
2578 HostCmd_ACT_GEN_SET, 0, pioctl_req,
2579 MNULL)) {
2580 wlan_recv_event(
2581 priv, MLAN_EVENT_ID_DRV_DEFER_HANDLING,
2582 MNULL);
2583 status = MLAN_STATUS_PENDING;
2584 }
2585 }
2586 }
2587 /* Cancel all pending scan command */
2588 wlan_flush_scan_queue(pmadapter);
2589 LEAVE();
2590 return status;
2591 }
2592 #endif
2593
2594 /**
2595 * @brief Cancel all pending cmd.
2596 *
2597 * @param pmadapter A pointer to mlan_adapter
2598 * @param flag MTRUE/MFALSE
2599 *
2600 * @return N/A
2601 */
wlan_cancel_all_pending_cmd(pmlan_adapter pmadapter,t_u8 flag)2602 t_void wlan_cancel_all_pending_cmd(pmlan_adapter pmadapter, t_u8 flag)
2603 {
2604 cmd_ctrl_node *pcmd_node = MNULL;
2605 pmlan_callbacks pcb = &pmadapter->callbacks;
2606 mlan_ioctl_req *pioctl_buf = MNULL;
2607 #ifdef STA_SUPPORT
2608 pmlan_private priv = MNULL;
2609 #endif
2610 ENTER();
2611 /* Cancel current cmd */
2612 wlan_request_cmd_lock(pmadapter);
2613 #ifdef STA_SUPPORT
2614 /* IOCTL will be completed, avoid calling IOCTL complete again from
2615 * EVENT/CMDRESP */
2616 if (pmadapter->pscan_ioctl_req) {
2617 pioctl_buf = pmadapter->pscan_ioctl_req;
2618 priv = pmadapter->priv[pioctl_buf->bss_index];
2619 pmadapter->pscan_ioctl_req = MNULL;
2620 pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL;
2621 pcb->moal_ioctl_complete(pmadapter->pmoal_handle, pioctl_buf,
2622 MLAN_STATUS_FAILURE);
2623 }
2624 #endif
2625 if (pmadapter->curr_cmd) {
2626 pcmd_node = pmadapter->curr_cmd;
2627 if (pcmd_node->pioctl_buf) {
2628 pioctl_buf = (mlan_ioctl_req *)pcmd_node->pioctl_buf;
2629 pcmd_node->pioctl_buf = MNULL;
2630 pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL;
2631 pcb->moal_ioctl_complete(pmadapter->pmoal_handle,
2632 pioctl_buf,
2633 MLAN_STATUS_FAILURE);
2634 }
2635 if (flag) {
2636 pmadapter->curr_cmd = MNULL;
2637 wlan_insert_cmd_to_free_q(pmadapter, pcmd_node);
2638 }
2639 }
2640
2641 /* Cancel all pending command */
2642 while ((pcmd_node = (cmd_ctrl_node *)util_peek_list(
2643 pmadapter->pmoal_handle, &pmadapter->cmd_pending_q,
2644 MNULL, MNULL))) {
2645 util_unlink_list(pmadapter->pmoal_handle,
2646 &pmadapter->cmd_pending_q,
2647 (pmlan_linked_list)pcmd_node, MNULL, MNULL);
2648 if (pcmd_node->pioctl_buf) {
2649 pioctl_buf = (mlan_ioctl_req *)pcmd_node->pioctl_buf;
2650 pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL;
2651 pcb->moal_ioctl_complete(pmadapter->pmoal_handle,
2652 pioctl_buf,
2653 MLAN_STATUS_FAILURE);
2654 pcmd_node->pioctl_buf = MNULL;
2655 }
2656 wlan_insert_cmd_to_free_q(pmadapter, pcmd_node);
2657 }
2658 wlan_release_cmd_lock(pmadapter);
2659 /* Cancel all pending scan command */
2660 wlan_flush_scan_queue(pmadapter);
2661 /* Cancel all pending command in scan_cmd_pending_q command */
2662 wlan_flush_ext_cmd_pending_queue(pmadapter);
2663 LEAVE();
2664 }
2665
2666 /**
2667 * @brief Cancel specific bss's pending ioctl cmd.
2668 *
2669 * @param pmadapter A pointer to mlan_adapter
2670 * @param bss_index BSS index
2671 *
2672 * @return N/A
2673 */
wlan_cancel_bss_pending_cmd(pmlan_adapter pmadapter,t_u32 bss_index)2674 t_void wlan_cancel_bss_pending_cmd(pmlan_adapter pmadapter, t_u32 bss_index)
2675 {
2676 pmlan_callbacks pcb = &pmadapter->callbacks;
2677 cmd_ctrl_node *pcmd_node = MNULL;
2678 mlan_ioctl_req *pioctl_buf = MNULL;
2679 #ifdef STA_SUPPORT
2680 t_u8 flash_scan = MFALSE;
2681 #endif
2682 #ifdef STA_SUPPORT
2683 pmlan_private priv = MNULL;
2684 #endif
2685 ENTER();
2686
2687 PRINTM(MIOCTL, "MOAL Cancel BSS IOCTL: bss_index=%d\n", (int)bss_index);
2688 wlan_request_cmd_lock(pmadapter);
2689 #ifdef STA_SUPPORT
2690 if (pmadapter->pscan_ioctl_req &&
2691 (pmadapter->pscan_ioctl_req->bss_index == bss_index)) {
2692 /* IOCTL will be completed, avoid calling IOCTL complete again
2693 * from EVENT/CMDRESP */
2694 flash_scan = MTRUE;
2695 pioctl_buf = pmadapter->pscan_ioctl_req;
2696 priv = pmadapter->priv[pioctl_buf->bss_index];
2697 pmadapter->pscan_ioctl_req = MNULL;
2698 pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL;
2699 pcb->moal_ioctl_complete(pmadapter->pmoal_handle, pioctl_buf,
2700 MLAN_STATUS_FAILURE);
2701 }
2702 #endif
2703 if (pmadapter->curr_cmd && pmadapter->curr_cmd->pioctl_buf) {
2704 pioctl_buf = (mlan_ioctl_req *)pmadapter->curr_cmd->pioctl_buf;
2705 if (pioctl_buf->bss_index == bss_index) {
2706 pcmd_node = pmadapter->curr_cmd;
2707 pcmd_node->pioctl_buf = MNULL;
2708 pcmd_node->cmd_flag |= CMD_F_CANCELED;
2709 #ifdef STA_SUPPORT
2710 if (pioctl_buf->req_id == MLAN_IOCTL_SCAN)
2711 flash_scan = MTRUE;
2712 #endif
2713 pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL;
2714 pcb->moal_ioctl_complete(pmadapter->pmoal_handle,
2715 pioctl_buf,
2716 MLAN_STATUS_FAILURE);
2717 }
2718 }
2719 while ((pcmd_node = wlan_get_bss_pending_ioctl_cmd(
2720 pmadapter, bss_index)) != MNULL) {
2721 util_unlink_list(pmadapter->pmoal_handle,
2722 &pmadapter->cmd_pending_q,
2723 (pmlan_linked_list)pcmd_node, MNULL, MNULL);
2724 pioctl_buf = (mlan_ioctl_req *)pcmd_node->pioctl_buf;
2725 pcmd_node->pioctl_buf = MNULL;
2726 #ifdef STA_SUPPORT
2727 if (pioctl_buf->req_id == MLAN_IOCTL_SCAN)
2728 flash_scan = MTRUE;
2729 #endif
2730 pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL;
2731 pcb->moal_ioctl_complete(pmadapter->pmoal_handle, pioctl_buf,
2732 MLAN_STATUS_FAILURE);
2733 wlan_insert_cmd_to_free_q(pmadapter, pcmd_node);
2734 }
2735 wlan_release_cmd_lock(pmadapter);
2736 #ifdef STA_SUPPORT
2737 if (flash_scan) {
2738 if (pmadapter->scan_processing &&
2739 pmadapter->ext_scan_type == EXT_SCAN_ENHANCE) {
2740 if (priv) {
2741 if (MLAN_STATUS_FAILURE ==
2742 wlan_prepare_cmd(
2743 priv, HostCmd_CMD_802_11_SCAN_EXT,
2744 HostCmd_ACT_GEN_SET, 0, MNULL,
2745 MNULL))
2746 PRINTM(MERROR,
2747 "failed to prepare command");
2748 wlan_recv_event(
2749 priv, MLAN_EVENT_ID_DRV_DEFER_HANDLING,
2750 MNULL);
2751 }
2752 }
2753 /* Cancel all pending scan command */
2754 wlan_flush_scan_queue(pmadapter);
2755 }
2756 #endif
2757 LEAVE();
2758 return;
2759 }
2760
2761 /**
2762 * @brief Cancel pending ioctl cmd.
2763 *
2764 * @param pmadapter A pointer to mlan_adapter
2765 * @param pioctl_req A pointer to mlan_ioctl_req buf
2766 *
2767 * @return N/A
2768 */
wlan_cancel_pending_ioctl(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)2769 t_void wlan_cancel_pending_ioctl(pmlan_adapter pmadapter,
2770 pmlan_ioctl_req pioctl_req)
2771 {
2772 pmlan_callbacks pcb = &pmadapter->callbacks;
2773 cmd_ctrl_node *pcmd_node = MNULL;
2774 t_u8 find = MFALSE;
2775 #ifdef STA_SUPPORT
2776 pmlan_private priv = MNULL;
2777 #endif
2778
2779 ENTER();
2780
2781 PRINTM(MIOCTL, "MOAL Cancel IOCTL: 0x%x sub_id=0x%x action=%d\n",
2782 pioctl_req->req_id, *((t_u32 *)pioctl_req->pbuf),
2783 (int)pioctl_req->action);
2784
2785 wlan_request_cmd_lock(pmadapter);
2786 #ifdef STA_SUPPORT
2787 /* IOCTL will be completed, avoid calling IOCTL complete again from
2788 * EVENT/CMDRESP */
2789 if (pmadapter->pscan_ioctl_req == pioctl_req) {
2790 priv = pmadapter->priv[pioctl_req->bss_index];
2791 pmadapter->pscan_ioctl_req = MNULL;
2792 find = MTRUE;
2793 }
2794 #endif
2795 if ((pmadapter->curr_cmd) &&
2796 (pmadapter->curr_cmd->pioctl_buf == pioctl_req)) {
2797 pcmd_node = pmadapter->curr_cmd;
2798 pcmd_node->pioctl_buf = MNULL;
2799 pcmd_node->cmd_flag |= CMD_F_CANCELED;
2800 find = MTRUE;
2801 }
2802
2803 while ((pcmd_node = wlan_get_pending_ioctl_cmd(pmadapter,
2804 pioctl_req)) != MNULL) {
2805 util_unlink_list(pmadapter->pmoal_handle,
2806 &pmadapter->cmd_pending_q,
2807 (pmlan_linked_list)pcmd_node, MNULL, MNULL);
2808 pcmd_node->pioctl_buf = MNULL;
2809 find = MTRUE;
2810 wlan_insert_cmd_to_free_q(pmadapter, pcmd_node);
2811 }
2812 wlan_release_cmd_lock(pmadapter);
2813 #ifdef STA_SUPPORT
2814 if (pioctl_req->req_id == MLAN_IOCTL_SCAN) {
2815 if (pmadapter->scan_processing &&
2816 pmadapter->ext_scan_type == EXT_SCAN_ENHANCE) {
2817 if (priv) {
2818 if (MLAN_STATUS_FAILURE ==
2819 wlan_prepare_cmd(
2820 priv, HostCmd_CMD_802_11_SCAN_EXT,
2821 HostCmd_ACT_GEN_SET, 0, MNULL,
2822 MNULL))
2823 PRINTM(MERROR,
2824 "Failed to prepare command");
2825 wlan_recv_event(
2826 priv, MLAN_EVENT_ID_DRV_DEFER_HANDLING,
2827 MNULL);
2828 }
2829 }
2830 /* Cancel all pending scan command */
2831 wlan_flush_scan_queue(pmadapter);
2832 }
2833 #endif
2834 if (find) {
2835 pioctl_req->status_code = MLAN_ERROR_CMD_CANCEL;
2836 pcb->moal_ioctl_complete(pmadapter->pmoal_handle, pioctl_req,
2837 MLAN_STATUS_FAILURE);
2838 }
2839
2840 LEAVE();
2841 return;
2842 }
2843
2844 /**
2845 * @brief This function convert mlan_wifi_rate to wifi_rate.
2846 *
2847 * @param pmpriv A pointer to mlan_private structure
2848 * @param pmlan_rate A pointer to mlan_wifi_rate structure
2849 * @param prate A pointer to wifi_rate
2850 *
2851 * @return N/A
2852 */
wlan_fill_hal_wifi_rate(pmlan_private pmpriv,mlan_wifi_rate * pmlan_rate,wifi_rate * prate)2853 t_void wlan_fill_hal_wifi_rate(pmlan_private pmpriv, mlan_wifi_rate *pmlan_rate,
2854 wifi_rate *prate)
2855 {
2856 t_u8 index = 0;
2857 t_u8 rate_info = 0;
2858
2859 ENTER();
2860
2861 prate->preamble = pmlan_rate->preamble;
2862 prate->nss = pmlan_rate->nss;
2863 prate->bw = pmlan_rate->bw;
2864 prate->rateMcsIdx = pmlan_rate->rateMcsIdx;
2865 prate->reserved = 0;
2866 prate->bitrate = wlan_le32_to_cpu(pmlan_rate->bitrate);
2867
2868 if (!prate->bitrate) {
2869 index = prate->rateMcsIdx;
2870 index |= prate->nss << 4;
2871 if (prate->preamble == WIFI_PREAMBLE_HT)
2872 rate_info = MLAN_RATE_FORMAT_HT;
2873 else if (prate->preamble == WIFI_PREAMBLE_VHT)
2874 rate_info = MLAN_RATE_FORMAT_VHT;
2875 else
2876 rate_info = MLAN_RATE_FORMAT_LG;
2877 rate_info |= prate->bw << 2;
2878 PRINTM(MCMND, "index=0x%x rate_info=0x%x\n", index, rate_info);
2879 /** For rateMcsIdx, OFDM/CCK rate code would be as per ieee std
2880 * in the units of 0.5mbps. HT/VHT it would be mcs index */
2881 /** For bitrate, in 100kbps */
2882 if (rate_info == MLAN_RATE_FORMAT_LG)
2883 prate->bitrate = prate->rateMcsIdx * 5;
2884 else
2885 prate->bitrate =
2886 wlan_index_to_data_rate(pmpriv->adapter, index,
2887 rate_info, 0) *
2888 5;
2889 PRINTM(MCMND, "bitrate(in 100kbps)=%d\n", prate->bitrate);
2890 }
2891
2892 LEAVE();
2893 }
2894
2895 /**
2896 * @brief Handle the version_ext resp
2897 *
2898 * @param pmpriv A pointer to mlan_private structure
2899 * @param resp A pointer to HostCmd_DS_COMMAND
2900 * @param pioctl_buf A pointer to mlan_ioctl_req structure
2901 *
2902 * @return MLAN_STATUS_SUCCESS
2903 */
wlan_ret_ver_ext(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)2904 mlan_status wlan_ret_ver_ext(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
2905 mlan_ioctl_req *pioctl_buf)
2906 {
2907 HostCmd_DS_VERSION_EXT *ver_ext = &resp->params.verext;
2908 mlan_ds_get_info *info;
2909 ENTER();
2910 if (pioctl_buf) {
2911 info = (mlan_ds_get_info *)pioctl_buf->pbuf;
2912 info->param.ver_ext.version_str_sel = ver_ext->version_str_sel;
2913 memcpy_ext(pmpriv->adapter, info->param.ver_ext.version_str,
2914 ver_ext->version_str, sizeof(char) * 128,
2915 sizeof(char) * MLAN_MAX_VER_STR_LEN);
2916 }
2917 LEAVE();
2918 return MLAN_STATUS_SUCCESS;
2919 }
2920
2921 /**
2922 * @brief Handle the rx mgmt forward registration resp
2923 *
2924 * @param pmpriv A pointer to mlan_private structure
2925 * @param resp A pointer to HostCmd_DS_COMMAND
2926 * @param pioctl_buf A pointer to mlan_ioctl_req structure
2927 *
2928 * @return MLAN_STATUS_SUCCESS
2929 */
wlan_ret_rx_mgmt_ind(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)2930 mlan_status wlan_ret_rx_mgmt_ind(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
2931 mlan_ioctl_req *pioctl_buf)
2932 {
2933 mlan_ds_misc_cfg *misc = MNULL;
2934 ENTER();
2935
2936 if (pioctl_buf) {
2937 misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
2938 misc->param.mgmt_subtype_mask = wlan_le32_to_cpu(
2939 resp->params.rx_mgmt_ind.mgmt_subtype_mask);
2940 }
2941
2942 LEAVE();
2943 return MLAN_STATUS_SUCCESS;
2944 }
2945
2946 /**
2947 * @brief This function checks conditions and prepares to
2948 * send sleep confirm command to firmware if OK.
2949 *
2950 * @param pmadapter A pointer to mlan_adapter structure
2951 *
2952 * @return N/A
2953 */
wlan_check_ps_cond(mlan_adapter * pmadapter)2954 t_void wlan_check_ps_cond(mlan_adapter *pmadapter)
2955 {
2956 ENTER();
2957
2958 if (!pmadapter->cmd_sent && !pmadapter->curr_cmd &&
2959 !pmadapter->keep_wakeup && !wlan_is_tx_pending(pmadapter) &&
2960 !IS_CARD_RX_RCVD(pmadapter)) {
2961 wlan_dnld_sleep_confirm_cmd(pmadapter);
2962 } else {
2963 PRINTM(MCMND, "Delay Sleep Confirm (%s%s%s%s)\n",
2964 (pmadapter->cmd_sent) ? "D" : "",
2965 (pmadapter->curr_cmd) ? "C" : "",
2966 (wlan_is_tx_pending(pmadapter)) ? "T" : "",
2967 (IS_CARD_RX_RCVD(pmadapter)) ? "R" : "");
2968 }
2969
2970 LEAVE();
2971 }
2972
2973 /**
2974 * @brief This function sends the HS_ACTIVATED event to the application
2975 *
2976 * @param priv A pointer to mlan_private structure
2977 * @param activated MTRUE if activated, MFALSE if de-activated
2978 *
2979 * @return N/A
2980 */
wlan_host_sleep_activated_event(pmlan_private priv,t_u8 activated)2981 t_void wlan_host_sleep_activated_event(pmlan_private priv, t_u8 activated)
2982 {
2983 ENTER();
2984
2985 if (!priv) {
2986 LEAVE();
2987 return;
2988 }
2989
2990 if (activated) {
2991 if (priv->adapter->is_hs_configured) {
2992 priv->adapter->hs_activated = MTRUE;
2993 wlan_update_rxreorder_tbl(priv->adapter, MTRUE);
2994 PRINTM(MEVENT, "hs_activated\n");
2995 wlan_recv_event(priv, MLAN_EVENT_ID_DRV_HS_ACTIVATED,
2996 MNULL);
2997 } else
2998 PRINTM(MWARN, "hs_activated: HS not configured !!!\n");
2999 } else {
3000 PRINTM(MEVENT, "hs_deactived\n");
3001 priv->adapter->hs_activated = MFALSE;
3002 wlan_recv_event(priv, MLAN_EVENT_ID_DRV_HS_DEACTIVATED, MNULL);
3003 }
3004
3005 LEAVE();
3006 return;
3007 }
3008
3009 /**
3010 * @brief This function sends the HS_WAKEUP event to the application
3011 *
3012 * @param priv A pointer to mlan_private structure
3013 *
3014 * @return N/A
3015 */
wlan_host_sleep_wakeup_event(pmlan_private priv)3016 t_void wlan_host_sleep_wakeup_event(pmlan_private priv)
3017 {
3018 ENTER();
3019
3020 if (priv->adapter->is_hs_configured)
3021 wlan_recv_event(priv, MLAN_EVENT_ID_FW_HS_WAKEUP, MNULL);
3022 else
3023 PRINTM(MWARN, "hs_wakeup: Host Sleep not configured !!!\n");
3024
3025 LEAVE();
3026 }
3027
3028 /**
3029 * @brief This function handles the command response of hs_cfg
3030 *
3031 * @param pmpriv A pointer to mlan_private structure
3032 * @param resp A pointer to HostCmd_DS_COMMAND
3033 * @param pioctl_buf A pointer to mlan_ioctl_req structure
3034 *
3035 * @return MLAN_STATUS_SUCCESS
3036 */
wlan_ret_802_11_hs_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)3037 mlan_status wlan_ret_802_11_hs_cfg(pmlan_private pmpriv,
3038 HostCmd_DS_COMMAND *resp,
3039 mlan_ioctl_req *pioctl_buf)
3040 {
3041 pmlan_adapter pmadapter = pmpriv->adapter;
3042 HostCmd_DS_802_11_HS_CFG_ENH *phs_cfg = &resp->params.opt_hs_cfg;
3043
3044 ENTER();
3045
3046 phs_cfg->params.hs_config.conditions =
3047 wlan_le32_to_cpu(phs_cfg->params.hs_config.conditions);
3048 phs_cfg->action = wlan_le16_to_cpu(phs_cfg->action);
3049 PRINTM(MCMND,
3050 "CMD_RESP: HS_CFG cmd reply result=%#x,"
3051 " action=0x%x conditions=0x%x gpio=0x%x gap=0x%x\n",
3052 resp->result, phs_cfg->action,
3053 phs_cfg->params.hs_config.conditions,
3054 phs_cfg->params.hs_config.gpio, phs_cfg->params.hs_config.gap);
3055 if ((phs_cfg->action == HS_ACTIVATE &&
3056 !pmadapter->pcard_info->supp_ps_handshake) ||
3057 pmadapter->pcard_info->supp_ps_handshake) {
3058 /* clean up curr_cmd to allow suspend */
3059 if (pioctl_buf)
3060 pioctl_buf->status_code = MLAN_ERROR_NO_ERROR;
3061 /* Clean up and put current command back to cmd_free_q */
3062 wlan_request_cmd_lock(pmadapter);
3063 wlan_insert_cmd_to_free_q(pmadapter, pmadapter->curr_cmd);
3064 pmadapter->curr_cmd = MNULL;
3065 wlan_release_cmd_lock(pmadapter);
3066 if (!pmadapter->pcard_info->supp_ps_handshake) {
3067 wlan_host_sleep_activated_event(pmpriv, MTRUE);
3068 goto done;
3069 }
3070 }
3071 if (phs_cfg->params.hs_config.conditions != HOST_SLEEP_CFG_CANCEL) {
3072 pmadapter->is_hs_configured = MTRUE;
3073 if (pmadapter->pcard_info->supp_ps_handshake)
3074 wlan_host_sleep_activated_event(pmpriv, MTRUE);
3075 } else {
3076 pmadapter->is_hs_configured = MFALSE;
3077 if (pmadapter->hs_activated)
3078 wlan_host_sleep_activated_event(pmpriv, MFALSE);
3079 }
3080
3081 done:
3082 LEAVE();
3083 return MLAN_STATUS_SUCCESS;
3084 }
3085
3086 /**
3087 * @brief Perform hs related activities on receiving the power up interrupt
3088 *
3089 * @param pmadapter A pointer to the adapter structure
3090 * @return N/A
3091 */
wlan_process_hs_config(pmlan_adapter pmadapter)3092 t_void wlan_process_hs_config(pmlan_adapter pmadapter)
3093 {
3094 ENTER();
3095 PRINTM(MINFO, "Recevie interrupt/data in HS mode\n");
3096 if (pmadapter->hs_cfg.gap == HOST_SLEEP_CFG_GAP_FF)
3097 pmadapter->ops.wakeup_card(pmadapter, MTRUE);
3098 LEAVE();
3099 return;
3100 }
3101
3102 /**
3103 * @brief Check sleep confirm command response and set the state to ASLEEP
3104 *
3105 * @param pmadapter A pointer to the adapter structure
3106 * @param pbuf A pointer to the command response buffer
3107 * @param upld_len Command response buffer length
3108 * @return N/A
3109 */
wlan_process_sleep_confirm_resp(pmlan_adapter pmadapter,t_u8 * pbuf,t_u32 upld_len)3110 void wlan_process_sleep_confirm_resp(pmlan_adapter pmadapter, t_u8 *pbuf,
3111 t_u32 upld_len)
3112 {
3113 HostCmd_DS_COMMAND *cmd;
3114 pmlan_private pmpriv;
3115
3116 ENTER();
3117
3118 if (!upld_len) {
3119 PRINTM(MERROR, "Command size is 0\n");
3120 LEAVE();
3121 return;
3122 }
3123 cmd = (HostCmd_DS_COMMAND *)pbuf;
3124 cmd->result = wlan_le16_to_cpu(cmd->result);
3125 cmd->command = wlan_le16_to_cpu(cmd->command);
3126 cmd->seq_num = wlan_le16_to_cpu(cmd->seq_num);
3127
3128 pmpriv =
3129 wlan_get_priv_by_id(pmadapter, HostCmd_GET_BSS_NO(cmd->seq_num),
3130 HostCmd_GET_BSS_TYPE(cmd->seq_num));
3131 /* Update sequence number */
3132 cmd->seq_num = HostCmd_GET_SEQ_NO(cmd->seq_num);
3133 /* Clear RET_BIT from HostCmd */
3134 cmd->command &= HostCmd_CMD_ID_MASK;
3135 if (!pmpriv)
3136 pmpriv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);
3137 if (cmd->command != HostCmd_CMD_802_11_PS_MODE_ENH) {
3138 PRINTM(MERROR,
3139 "Received unexpected response for command %x, result = %x\n",
3140 cmd->command, cmd->result);
3141 LEAVE();
3142 return;
3143 }
3144 PRINTM_NETINTF(MEVENT, pmpriv);
3145 PRINTM(MEVENT, "#\n");
3146 if (cmd->result != MLAN_STATUS_SUCCESS) {
3147 PRINTM(MERROR, "Sleep confirm command failed\n");
3148 pmadapter->pm_wakeup_card_req = MFALSE;
3149 pmadapter->ps_state = PS_STATE_AWAKE;
3150 LEAVE();
3151 return;
3152 }
3153 pmadapter->pm_wakeup_card_req = MTRUE;
3154
3155 if (pmadapter->is_hs_configured) {
3156 wlan_host_sleep_activated_event(
3157 wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY), MTRUE);
3158 }
3159 pmadapter->ps_state = PS_STATE_SLEEP;
3160 LEAVE();
3161 }
3162
3163 /**
3164 * @brief This function prepares command of power mode
3165 *
3166 * @param pmpriv A pointer to mlan_private structure
3167 * @param cmd A pointer to HostCmd_DS_COMMAND structure
3168 * @param cmd_action the action: GET or SET
3169 * @param ps_bitmap PS bitmap
3170 * @param pdata_buf A pointer to data buffer
3171 * @return MLAN_STATUS_SUCCESS
3172 */
wlan_cmd_enh_power_mode(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_u16 ps_bitmap,t_void * pdata_buf)3173 mlan_status wlan_cmd_enh_power_mode(pmlan_private pmpriv,
3174 HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
3175 t_u16 ps_bitmap, t_void *pdata_buf)
3176 {
3177 HostCmd_DS_802_11_PS_MODE_ENH *psmode_enh = &cmd->params.psmode_enh;
3178 t_u8 *tlv = MNULL;
3179 t_u16 cmd_size = 0;
3180
3181 ENTER();
3182
3183 PRINTM(MCMND, "PS Command: action = 0x%x, bitmap = 0x%x\n", cmd_action,
3184 ps_bitmap);
3185
3186 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
3187 if (cmd_action == DIS_AUTO_PS) {
3188 psmode_enh->action = wlan_cpu_to_le16(DIS_AUTO_PS);
3189 psmode_enh->params.ps_bitmap = wlan_cpu_to_le16(ps_bitmap);
3190 cmd->size = wlan_cpu_to_le16(S_DS_GEN + AUTO_PS_FIX_SIZE);
3191 } else if (cmd_action == GET_PS) {
3192 psmode_enh->action = wlan_cpu_to_le16(GET_PS);
3193 psmode_enh->params.ps_bitmap = wlan_cpu_to_le16(ps_bitmap);
3194 cmd->size = wlan_cpu_to_le16(S_DS_GEN + AUTO_PS_FIX_SIZE);
3195 } else if (cmd_action == EN_AUTO_PS) {
3196 psmode_enh->action = wlan_cpu_to_le16(EN_AUTO_PS);
3197 psmode_enh->params.auto_ps.ps_bitmap =
3198 wlan_cpu_to_le16(ps_bitmap);
3199 cmd_size = S_DS_GEN + AUTO_PS_FIX_SIZE;
3200 tlv = (t_u8 *)cmd + cmd_size;
3201 if (ps_bitmap & BITMAP_STA_PS) {
3202 pmlan_adapter pmadapter = pmpriv->adapter;
3203 MrvlIEtypes_ps_param_t *ps_tlv =
3204 (MrvlIEtypes_ps_param_t *)tlv;
3205 ps_param *ps_mode = &ps_tlv->param;
3206 ps_tlv->header.type =
3207 wlan_cpu_to_le16(TLV_TYPE_PS_PARAM);
3208 ps_tlv->header.len = wlan_cpu_to_le16(
3209 sizeof(MrvlIEtypes_ps_param_t) -
3210 sizeof(MrvlIEtypesHeader_t));
3211 cmd_size += sizeof(MrvlIEtypes_ps_param_t);
3212 tlv += sizeof(MrvlIEtypes_ps_param_t);
3213 ps_mode->null_pkt_interval =
3214 wlan_cpu_to_le16(pmadapter->null_pkt_interval);
3215 ps_mode->multiple_dtims =
3216 wlan_cpu_to_le16(pmadapter->multiple_dtim);
3217 ps_mode->bcn_miss_timeout =
3218 wlan_cpu_to_le16(pmadapter->bcn_miss_time_out);
3219 ps_mode->local_listen_interval = wlan_cpu_to_le16(
3220 pmadapter->local_listen_interval);
3221 ps_mode->delay_to_ps =
3222 wlan_cpu_to_le16(pmadapter->delay_to_ps);
3223 ps_mode->mode =
3224 wlan_cpu_to_le16(pmadapter->enhanced_ps_mode);
3225 }
3226 if (ps_bitmap & BITMAP_BCN_TMO) {
3227 MrvlIEtypes_bcn_timeout_t *bcn_tmo_tlv =
3228 (MrvlIEtypes_bcn_timeout_t *)tlv;
3229 mlan_ds_bcn_timeout *bcn_tmo =
3230 (mlan_ds_bcn_timeout *)pdata_buf;
3231 bcn_tmo_tlv->header.type =
3232 wlan_cpu_to_le16(TLV_TYPE_BCN_TIMEOUT);
3233 bcn_tmo_tlv->header.len = wlan_cpu_to_le16(
3234 sizeof(MrvlIEtypes_bcn_timeout_t) -
3235 sizeof(MrvlIEtypesHeader_t));
3236 bcn_tmo_tlv->bcn_miss_tmo_window =
3237 wlan_cpu_to_le16(bcn_tmo->bcn_miss_tmo_window);
3238 bcn_tmo_tlv->bcn_miss_tmo_period =
3239 wlan_cpu_to_le16(bcn_tmo->bcn_miss_tmo_period);
3240 bcn_tmo_tlv->bcn_rq_tmo_window =
3241 wlan_cpu_to_le16(bcn_tmo->bcn_rq_tmo_window);
3242 bcn_tmo_tlv->bcn_rq_tmo_period =
3243 wlan_cpu_to_le16(bcn_tmo->bcn_rq_tmo_period);
3244 cmd_size += sizeof(MrvlIEtypes_bcn_timeout_t);
3245 tlv += sizeof(MrvlIEtypes_bcn_timeout_t);
3246
3247 psmode_enh->params.auto_ps.ps_bitmap = wlan_cpu_to_le16(
3248 (ps_bitmap & (~BITMAP_BCN_TMO)) |
3249 BITMAP_STA_PS);
3250 }
3251 if (ps_bitmap & BITMAP_AUTO_DS) {
3252 MrvlIEtypes_auto_ds_param_t *auto_ps_tlv =
3253 (MrvlIEtypes_auto_ds_param_t *)tlv;
3254 auto_ds_param *auto_ds = &auto_ps_tlv->param;
3255 t_u16 idletime = 0;
3256 auto_ps_tlv->header.type =
3257 wlan_cpu_to_le16(TLV_TYPE_AUTO_DS_PARAM);
3258 auto_ps_tlv->header.len = wlan_cpu_to_le16(
3259 sizeof(MrvlIEtypes_auto_ds_param_t) -
3260 sizeof(MrvlIEtypesHeader_t));
3261 cmd_size += sizeof(MrvlIEtypes_auto_ds_param_t);
3262 tlv += sizeof(MrvlIEtypes_auto_ds_param_t);
3263 if (pdata_buf)
3264 idletime =
3265 ((mlan_ds_auto_ds *)pdata_buf)->idletime;
3266 auto_ds->deep_sleep_timeout =
3267 wlan_cpu_to_le16(idletime);
3268 }
3269 #if defined(UAP_SUPPORT)
3270 if (pdata_buf &&
3271 (ps_bitmap & (BITMAP_UAP_INACT_PS | BITMAP_UAP_DTIM_PS))) {
3272 mlan_ds_ps_mgmt *ps_mgmt = (mlan_ds_ps_mgmt *)pdata_buf;
3273 MrvlIEtypes_sleep_param_t *sleep_tlv = MNULL;
3274 MrvlIEtypes_inact_sleep_param_t *inact_tlv = MNULL;
3275 if (ps_mgmt->flags & PS_FLAG_SLEEP_PARAM) {
3276 sleep_tlv = (MrvlIEtypes_sleep_param_t *)tlv;
3277 sleep_tlv->header.type = wlan_cpu_to_le16(
3278 TLV_TYPE_AP_SLEEP_PARAM);
3279 sleep_tlv->header.len = wlan_cpu_to_le16(
3280 sizeof(MrvlIEtypes_sleep_param_t) -
3281 sizeof(MrvlIEtypesHeader_t));
3282 sleep_tlv->ctrl_bitmap = wlan_cpu_to_le32(
3283 ps_mgmt->sleep_param.ctrl_bitmap);
3284 sleep_tlv->min_sleep = wlan_cpu_to_le32(
3285 ps_mgmt->sleep_param.min_sleep);
3286 sleep_tlv->max_sleep = wlan_cpu_to_le32(
3287 ps_mgmt->sleep_param.max_sleep);
3288 cmd_size += sizeof(MrvlIEtypes_sleep_param_t);
3289 tlv += sizeof(MrvlIEtypes_sleep_param_t);
3290 }
3291 if (ps_mgmt->flags & PS_FLAG_INACT_SLEEP_PARAM) {
3292 inact_tlv =
3293 (MrvlIEtypes_inact_sleep_param_t *)tlv;
3294 inact_tlv->header.type = wlan_cpu_to_le16(
3295 TLV_TYPE_AP_INACT_SLEEP_PARAM);
3296 inact_tlv->header.len = wlan_cpu_to_le16(
3297 sizeof(MrvlIEtypes_inact_sleep_param_t) -
3298 sizeof(MrvlIEtypesHeader_t));
3299 inact_tlv->inactivity_to = wlan_cpu_to_le32(
3300 ps_mgmt->inact_param.inactivity_to);
3301 inact_tlv->min_awake = wlan_cpu_to_le32(
3302 ps_mgmt->inact_param.min_awake);
3303 inact_tlv->max_awake = wlan_cpu_to_le32(
3304 ps_mgmt->inact_param.max_awake);
3305 cmd_size +=
3306 sizeof(MrvlIEtypes_inact_sleep_param_t);
3307 tlv += sizeof(MrvlIEtypes_inact_sleep_param_t);
3308 }
3309 }
3310 #endif
3311 cmd->size = wlan_cpu_to_le16(cmd_size);
3312 }
3313
3314 LEAVE();
3315 return MLAN_STATUS_SUCCESS;
3316 }
3317
3318 /**
3319 * @brief This function handles the command response of ps_mode_enh
3320 *
3321 * @param pmpriv A pointer to mlan_private structure
3322 * @param resp A pointer to HostCmd_DS_COMMAND
3323 * @param pioctl_buf A pointer to mlan_ioctl_req structure
3324 *
3325 * @return MLAN_STATUS_SUCCESS
3326 */
wlan_ret_enh_power_mode(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)3327 mlan_status wlan_ret_enh_power_mode(pmlan_private pmpriv,
3328 HostCmd_DS_COMMAND *resp,
3329 mlan_ioctl_req *pioctl_buf)
3330 {
3331 pmlan_adapter pmadapter = pmpriv->adapter;
3332 MrvlIEtypesHeader_t *mrvl_tlv = MNULL;
3333 MrvlIEtypes_auto_ds_param_t *auto_ds_tlv = MNULL;
3334 HostCmd_DS_802_11_PS_MODE_ENH *ps_mode = &resp->params.psmode_enh;
3335
3336 ENTER();
3337
3338 ps_mode->action = wlan_le16_to_cpu(ps_mode->action);
3339 PRINTM(MINFO, "CMD_RESP: PS_MODE cmd reply result=%#x action=0x%X\n",
3340 resp->result, ps_mode->action);
3341 if (ps_mode->action == EN_AUTO_PS) {
3342 ps_mode->params.auto_ps.ps_bitmap =
3343 wlan_le16_to_cpu(ps_mode->params.auto_ps.ps_bitmap);
3344 if (ps_mode->params.auto_ps.ps_bitmap & BITMAP_AUTO_DS) {
3345 PRINTM(MCMND, "Enabled auto deep sleep\n");
3346 pmpriv->adapter->is_deep_sleep = MTRUE;
3347 mrvl_tlv = (MrvlIEtypesHeader_t *)((t_u8 *)ps_mode +
3348 AUTO_PS_FIX_SIZE);
3349 while (wlan_le16_to_cpu(mrvl_tlv->type) !=
3350 TLV_TYPE_AUTO_DS_PARAM) {
3351 mrvl_tlv =
3352 (MrvlIEtypesHeader_t
3353 *)((t_u8 *)mrvl_tlv +
3354 wlan_le16_to_cpu(
3355 mrvl_tlv->len) +
3356 sizeof(MrvlIEtypesHeader_t));
3357 }
3358 auto_ds_tlv = (MrvlIEtypes_auto_ds_param_t *)mrvl_tlv;
3359 pmpriv->adapter->idle_time = wlan_le16_to_cpu(
3360 auto_ds_tlv->param.deep_sleep_timeout);
3361 }
3362 if (ps_mode->params.auto_ps.ps_bitmap & BITMAP_STA_PS) {
3363 PRINTM(MCMND, "Enabled STA power save\n");
3364 if (pmadapter->sleep_period.period) {
3365 PRINTM(MCMND,
3366 "Setting uapsd/pps mode to TRUE\n");
3367 }
3368 }
3369 #if defined(UAP_SUPPORT)
3370 if (ps_mode->params.auto_ps.ps_bitmap &
3371 (BITMAP_UAP_INACT_PS | BITMAP_UAP_DTIM_PS)) {
3372 pmadapter->ps_mode = Wlan802_11PowerModePSP;
3373 PRINTM(MCMND, "Enabled uAP power save\n");
3374 }
3375 #endif
3376 } else if (ps_mode->action == DIS_AUTO_PS) {
3377 ps_mode->params.ps_bitmap =
3378 wlan_cpu_to_le16(ps_mode->params.ps_bitmap);
3379 if (ps_mode->params.ps_bitmap & BITMAP_AUTO_DS) {
3380 pmpriv->adapter->is_deep_sleep = MFALSE;
3381 PRINTM(MCMND, "Disabled auto deep sleep\n");
3382 }
3383 if (ps_mode->params.ps_bitmap & BITMAP_STA_PS) {
3384 PRINTM(MCMND, "Disabled STA power save\n");
3385 if (pmadapter->sleep_period.period) {
3386 pmadapter->delay_null_pkt = MFALSE;
3387 pmadapter->tx_lock_flag = MFALSE;
3388 pmadapter->pps_uapsd_mode = MFALSE;
3389 }
3390 }
3391 #if defined(UAP_SUPPORT)
3392 if (ps_mode->params.ps_bitmap &
3393 (BITMAP_UAP_INACT_PS | BITMAP_UAP_DTIM_PS)) {
3394 pmadapter->ps_mode = Wlan802_11PowerModeCAM;
3395 PRINTM(MCMND, "Disabled uAP power save\n");
3396 }
3397 #endif
3398 } else if (ps_mode->action == GET_PS) {
3399 ps_mode->params.ps_bitmap =
3400 wlan_le16_to_cpu(ps_mode->params.ps_bitmap);
3401 if (ps_mode->params.auto_ps.ps_bitmap &
3402 (BITMAP_STA_PS | BITMAP_UAP_INACT_PS | BITMAP_UAP_DTIM_PS))
3403 pmadapter->ps_mode = Wlan802_11PowerModePSP;
3404 else
3405 pmadapter->ps_mode = Wlan802_11PowerModeCAM;
3406 PRINTM(MCMND, "ps_bitmap=0x%x\n", ps_mode->params.ps_bitmap);
3407 if (pioctl_buf) {
3408 mlan_ds_pm_cfg *pm_cfg =
3409 (mlan_ds_pm_cfg *)pioctl_buf->pbuf;
3410 if (pm_cfg->sub_command == MLAN_OID_PM_CFG_IEEE_PS) {
3411 if (ps_mode->params.auto_ps.ps_bitmap &
3412 BITMAP_STA_PS)
3413 pm_cfg->param.ps_mode = 1;
3414 else
3415 pm_cfg->param.ps_mode = 0;
3416 }
3417 #if defined(UAP_SUPPORT)
3418 if (pm_cfg->sub_command == MLAN_OID_PM_CFG_PS_MODE) {
3419 MrvlIEtypes_sleep_param_t *sleep_tlv = MNULL;
3420 MrvlIEtypes_inact_sleep_param_t *inact_tlv =
3421 MNULL;
3422 MrvlIEtypesHeader_t *tlv = MNULL;
3423 t_u16 tlv_type = 0;
3424 t_u16 tlv_len = 0;
3425 t_u16 tlv_buf_left = 0;
3426 pm_cfg->param.ps_mgmt.flags = PS_FLAG_PS_MODE;
3427 if (ps_mode->params.ps_bitmap &
3428 BITMAP_UAP_INACT_PS)
3429 pm_cfg->param.ps_mgmt.ps_mode =
3430 PS_MODE_INACTIVITY;
3431 else if (ps_mode->params.ps_bitmap &
3432 BITMAP_UAP_DTIM_PS)
3433 pm_cfg->param.ps_mgmt.ps_mode =
3434 PS_MODE_PERIODIC_DTIM;
3435 else
3436 pm_cfg->param.ps_mgmt.ps_mode =
3437 PS_MODE_DISABLE;
3438 tlv_buf_left = resp->size -
3439 (S_DS_GEN + AUTO_PS_FIX_SIZE);
3440 tlv = (MrvlIEtypesHeader_t *)((t_u8 *)ps_mode +
3441 AUTO_PS_FIX_SIZE);
3442 while (tlv_buf_left >=
3443 sizeof(MrvlIEtypesHeader_t)) {
3444 tlv_type = wlan_le16_to_cpu(tlv->type);
3445 tlv_len = wlan_le16_to_cpu(tlv->len);
3446 switch (tlv_type) {
3447 case TLV_TYPE_AP_SLEEP_PARAM:
3448 sleep_tlv =
3449 (MrvlIEtypes_sleep_param_t
3450 *)tlv;
3451 pm_cfg->param.ps_mgmt.flags |=
3452 PS_FLAG_SLEEP_PARAM;
3453 pm_cfg->param.ps_mgmt
3454 .sleep_param
3455 .ctrl_bitmap = wlan_le32_to_cpu(
3456 sleep_tlv->ctrl_bitmap);
3457 pm_cfg->param.ps_mgmt
3458 .sleep_param
3459 .min_sleep = wlan_le32_to_cpu(
3460 sleep_tlv->min_sleep);
3461 pm_cfg->param.ps_mgmt
3462 .sleep_param
3463 .max_sleep = wlan_le32_to_cpu(
3464 sleep_tlv->max_sleep);
3465 break;
3466 case TLV_TYPE_AP_INACT_SLEEP_PARAM:
3467 inact_tlv =
3468 (MrvlIEtypes_inact_sleep_param_t
3469 *)tlv;
3470 pm_cfg->param.ps_mgmt.flags |=
3471 PS_FLAG_INACT_SLEEP_PARAM;
3472 pm_cfg->param.ps_mgmt
3473 .inact_param
3474 .inactivity_to = wlan_le32_to_cpu(
3475 inact_tlv->inactivity_to);
3476 pm_cfg->param.ps_mgmt
3477 .inact_param
3478 .min_awake = wlan_le32_to_cpu(
3479 inact_tlv->min_awake);
3480 pm_cfg->param.ps_mgmt
3481 .inact_param
3482 .max_awake = wlan_le32_to_cpu(
3483 inact_tlv->max_awake);
3484 break;
3485 }
3486 tlv_buf_left -=
3487 tlv_len +
3488 sizeof(MrvlIEtypesHeader_t);
3489 tlv = (MrvlIEtypesHeader_t
3490 *)((t_u8 *)tlv +
3491 tlv_len +
3492 sizeof(MrvlIEtypesHeader_t));
3493 }
3494 }
3495 #endif
3496 }
3497 }
3498
3499 LEAVE();
3500 return MLAN_STATUS_SUCCESS;
3501 }
3502
3503 /**
3504 * @brief This function handles the command response of tx rate query
3505 *
3506 * @param pmpriv A pointer to mlan_private structure
3507 * @param resp A pointer to HostCmd_DS_COMMAND
3508 * @param pioctl_buf A pointer to mlan_ioctl_req structure
3509 *
3510 * @return MLAN_STATUS_SUCCESS
3511 */
wlan_ret_802_11_tx_rate_query(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)3512 mlan_status wlan_ret_802_11_tx_rate_query(pmlan_private pmpriv,
3513 HostCmd_DS_COMMAND *resp,
3514 mlan_ioctl_req *pioctl_buf)
3515 {
3516 mlan_adapter *pmadapter = pmpriv->adapter;
3517 mlan_ds_rate *rate = MNULL;
3518 ENTER();
3519
3520 pmpriv->tx_rate = resp->params.tx_rate.tx_rate;
3521 pmpriv->tx_rate_info = resp->params.tx_rate.tx_rate_info;
3522 if (pmpriv->adapter->pcard_info->v14_fw_api) {
3523 pmpriv->tx_rate_info = wlan_convert_v14_tx_rate_info(
3524 pmpriv, pmpriv->tx_rate_info);
3525 PRINTM(MINFO,
3526 "%s: v14_fw_api=%d tx_rate=%d tx_rate_info=0x%x->0x%x\n",
3527 __func__, pmpriv->adapter->pcard_info->v14_fw_api,
3528 pmpriv->tx_rate, resp->params.tx_rate.tx_rate_info,
3529 pmpriv->tx_rate_info);
3530 }
3531 if ((pmpriv->tx_rate_info & 0x3) == MLAN_RATE_FORMAT_HE)
3532 pmpriv->ext_tx_rate_info =
3533 resp->params.tx_rate.ext_tx_rate_info;
3534 else
3535 pmpriv->ext_tx_rate_info = 0;
3536
3537 if (!pmpriv->is_data_rate_auto) {
3538 pmpriv->data_rate =
3539 wlan_index_to_data_rate(pmadapter, pmpriv->tx_rate,
3540 pmpriv->tx_rate_info,
3541 pmpriv->ext_tx_rate_info);
3542 }
3543
3544 if (pioctl_buf) {
3545 rate = (mlan_ds_rate *)pioctl_buf->pbuf;
3546 if (rate->sub_command == MLAN_OID_RATE_CFG) {
3547 if (rate->param.rate_cfg.rate_type == MLAN_RATE_INDEX) {
3548 if ((pmpriv->tx_rate_info & 0x3) ==
3549 MLAN_RATE_FORMAT_VHT ||
3550 ((pmpriv->tx_rate_info & 0x3) ==
3551 MLAN_RATE_FORMAT_HE))
3552
3553 /* VHT rate */
3554 rate->param.rate_cfg.rate =
3555 (pmpriv->tx_rate) & 0xF;
3556 else if ((pmpriv->tx_rate_info & 0x3) ==
3557 MLAN_RATE_FORMAT_HT)
3558 /* HT rate */
3559 rate->param.rate_cfg.rate =
3560 pmpriv->tx_rate +
3561 MLAN_RATE_INDEX_MCS0;
3562 else
3563 /* LG rate */
3564 /* For HostCmd_CMD_802_11_TX_RATE_QUERY,
3565 * there is a hole (0x4) in rate table
3566 * between HR/DSSS and OFDM rates,
3567 * so minus 1 for OFDM rate index */
3568 rate->param.rate_cfg.rate =
3569 (pmpriv->tx_rate >
3570 MLAN_RATE_INDEX_OFDM0) ?
3571 pmpriv->tx_rate - 1 :
3572 pmpriv->tx_rate;
3573 } else {
3574 /* rate_type = MLAN_RATE_VALUE */
3575 rate->param.rate_cfg.rate =
3576 wlan_index_to_data_rate(
3577 pmadapter, pmpriv->tx_rate,
3578 pmpriv->tx_rate_info,
3579 pmpriv->ext_tx_rate_info);
3580 }
3581 } else if (rate->sub_command == MLAN_OID_GET_DATA_RATE) {
3582 /* Tx rate info */
3583 if ((pmpriv->tx_rate_info & 0x3) ==
3584 MLAN_RATE_FORMAT_VHT ||
3585 (pmpriv->tx_rate_info & 0x3) ==
3586 MLAN_RATE_FORMAT_HE) {
3587 /* AX/VHT rate */
3588 rate->param.data_rate.tx_rate_format =
3589 pmpriv->tx_rate_info & 0x3;
3590 rate->param.data_rate.tx_ht_bw =
3591 (pmpriv->tx_rate_info & 0xC) >> 2;
3592 if ((pmpriv->tx_rate_info & 0x3) ==
3593 MLAN_RATE_FORMAT_HE)
3594 rate->param.data_rate.tx_ht_gi =
3595 (pmpriv->tx_rate_info & 0x10) >>
3596 4 |
3597 (pmpriv->tx_rate_info & 0x80) >>
3598 6;
3599 else
3600 rate->param.data_rate.tx_ht_gi =
3601 (pmpriv->tx_rate_info & 0x10) >>
3602 4;
3603 rate->param.data_rate.tx_nss =
3604 ((pmpriv->tx_rate) >> 4) & 0x03;
3605 rate->param.data_rate.tx_mcs_index =
3606 (pmpriv->tx_rate) & 0xF;
3607 if ((pmpriv->tx_rate_info & 0x3) ==
3608 MLAN_RATE_FORMAT_VHT ||
3609 (pmpriv->tx_rate_info & 0x3) ==
3610 MLAN_RATE_FORMAT_HE)
3611 rate->param.data_rate.tx_data_rate =
3612 wlan_index_to_data_rate(
3613 pmadapter,
3614 pmpriv->tx_rate,
3615 pmpriv->tx_rate_info,
3616 pmpriv->ext_tx_rate_info);
3617 } else if ((pmpriv->tx_rate_info & 0x3) ==
3618 MLAN_RATE_FORMAT_HT) {
3619 /* HT rate */
3620 rate->param.data_rate.tx_rate_format =
3621 MLAN_RATE_FORMAT_HT;
3622 rate->param.data_rate.tx_ht_bw =
3623 (pmpriv->tx_rate_info & 0xC) >> 2;
3624
3625 rate->param.data_rate.tx_ht_gi =
3626 (pmpriv->tx_rate_info & 0x10) >> 4;
3627 rate->param.data_rate.tx_mcs_index =
3628 pmpriv->tx_rate;
3629 rate->param.data_rate.tx_data_rate =
3630 wlan_index_to_data_rate(
3631 pmadapter, pmpriv->tx_rate,
3632 pmpriv->tx_rate_info,
3633 pmpriv->ext_tx_rate_info);
3634 } else {
3635 /* LG rate */
3636 rate->param.data_rate.tx_rate_format =
3637 MLAN_RATE_FORMAT_LG;
3638 /* For HostCmd_CMD_802_11_TX_RATE_QUERY,
3639 * there is a hole in rate table
3640 * between HR/DSSS and OFDM rates,
3641 * so minus 1 for OFDM rate index */
3642 rate->param.data_rate.tx_data_rate =
3643 (pmpriv->tx_rate >
3644 MLAN_RATE_INDEX_OFDM0) ?
3645 pmpriv->tx_rate - 1 :
3646 pmpriv->tx_rate;
3647 }
3648
3649 /* Rx rate info */
3650 if ((pmpriv->rxpd_rate_info & 0x3) ==
3651 MLAN_RATE_FORMAT_VHT ||
3652 (pmpriv->rxpd_rate_info & 0x3) ==
3653 MLAN_RATE_FORMAT_HE) {
3654 /* VHT rate */
3655 rate->param.data_rate.rx_rate_format =
3656 pmpriv->rxpd_rate_info & 0x3;
3657 rate->param.data_rate.rx_ht_bw =
3658 (pmpriv->rxpd_rate_info & 0xC) >> 2;
3659 if ((pmpriv->rxpd_rate_info & 0x3) ==
3660 MLAN_RATE_FORMAT_HE)
3661 rate->param.data_rate.rx_ht_gi =
3662 (pmpriv->rxpd_rate_info &
3663 0x10) >>
3664 4 |
3665 (pmpriv->rxpd_rate_info &
3666 0x80) >>
3667 6;
3668 else
3669 rate->param.data_rate.rx_ht_gi =
3670 (pmpriv->rxpd_rate_info &
3671 0x10) >>
3672 4;
3673 rate->param.data_rate.rx_nss =
3674 ((pmpriv->rxpd_rate) >> 4) & 0x3;
3675 rate->param.data_rate.rx_mcs_index =
3676 (pmpriv->rxpd_rate) & 0xF;
3677 if ((pmpriv->rxpd_rate_info & 0x3) ==
3678 MLAN_RATE_FORMAT_VHT ||
3679 (pmpriv->rxpd_rate_info & 0x3) ==
3680 MLAN_RATE_FORMAT_HE)
3681 rate->param.data_rate.rx_data_rate =
3682 wlan_index_to_data_rate(
3683 pmadapter,
3684 pmpriv->rxpd_rate,
3685 pmpriv->rxpd_rate_info,
3686 pmpriv->rxpd_rx_info);
3687 } else if ((pmpriv->rxpd_rate_info & 0x3) ==
3688 MLAN_RATE_FORMAT_HT) {
3689 /* HT rate */
3690 rate->param.data_rate.rx_rate_format =
3691 MLAN_RATE_FORMAT_HT;
3692 rate->param.data_rate.rx_ht_bw =
3693 (pmpriv->rxpd_rate_info & 0xC) >> 2;
3694 rate->param.data_rate.rx_ht_gi =
3695 (pmpriv->rxpd_rate_info & 0x10) >> 4;
3696 rate->param.data_rate.rx_mcs_index =
3697 pmpriv->rxpd_rate;
3698 rate->param.data_rate.rx_data_rate =
3699 wlan_index_to_data_rate(
3700 pmadapter, pmpriv->rxpd_rate,
3701 pmpriv->rxpd_rate_info, 0);
3702 } else {
3703 /* LG rate */
3704 rate->param.data_rate.rx_rate_format =
3705 MLAN_RATE_FORMAT_LG;
3706 /* For rate index in RxPD,
3707 * there is a hole in rate table
3708 * between HR/DSSS and OFDM rates,
3709 * so minus 1 for OFDM rate index */
3710 rate->param.data_rate.rx_data_rate =
3711 (pmpriv->rxpd_rate >
3712 MLAN_RATE_INDEX_OFDM0) ?
3713 pmpriv->rxpd_rate - 1 :
3714 pmpriv->rxpd_rate;
3715 }
3716 }
3717 pioctl_buf->data_read_written =
3718 sizeof(mlan_data_rate) + MLAN_SUB_COMMAND_SIZE;
3719 }
3720 LEAVE();
3721 return MLAN_STATUS_SUCCESS;
3722 }
3723
3724 /**
3725 * @brief This function prepares command of robustcoex.
3726 *
3727 * @param pmpriv A pointer to mlan_private structure
3728 * @param cmd A pointer to HostCmd_DS_COMMAND structure
3729 * @param cmd_action The action: GET or SET
3730 * @param pdata_buf A pointer to data buffer
3731 *
3732 * @return MLAN_STATUS_SUCCESS
3733 */
wlan_cmd_robustcoex(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_u16 * pdata_buf)3734 mlan_status wlan_cmd_robustcoex(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
3735 t_u16 cmd_action, t_u16 *pdata_buf)
3736 {
3737 HostCmd_DS_802_11_ROBUSTCOEX *rbstcx = &cmd->params.robustcoexparams;
3738 mlan_ds_misc_robustcoex_params *robustcoex_params = MNULL;
3739 MrvlIEtypes_RobustcoexSourceGPIO_t *tlv =
3740 (MrvlIEtypes_RobustcoexSourceGPIO_t *)(rbstcx->tlv_buf);
3741
3742 ENTER();
3743
3744 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_ROBUSTCOEX);
3745 cmd->size = sizeof(HostCmd_DS_802_11_ROBUSTCOEX) + S_DS_GEN;
3746 rbstcx->action = wlan_cpu_to_le16(cmd_action);
3747 switch (cmd_action) {
3748 case HostCmd_ACT_GEN_SET:
3749 robustcoex_params = (mlan_ds_misc_robustcoex_params *)pdata_buf;
3750 if (robustcoex_params->method == ROBUSTCOEX_GPIO_CFG) {
3751 cmd->size += sizeof(MrvlIEtypes_RobustcoexSourceGPIO_t);
3752 tlv->header.type =
3753 wlan_cpu_to_le16(TLV_TYPE_ROBUSTCOEX);
3754 tlv->header.len = wlan_cpu_to_le16(
3755 sizeof(MrvlIEtypes_RobustcoexSourceGPIO_t) -
3756 sizeof(MrvlIEtypesHeader_t));
3757 tlv->enable = (t_u8)robustcoex_params->enable;
3758 tlv->gpio_num = (t_u8)robustcoex_params->gpio_num;
3759 tlv->gpio_polarity =
3760 (t_u8)robustcoex_params->gpio_polarity;
3761 }
3762 break;
3763 case HostCmd_ACT_GEN_GET:
3764 default:
3765 break;
3766 }
3767 cmd->size = wlan_cpu_to_le16(cmd->size);
3768 LEAVE();
3769 return MLAN_STATUS_SUCCESS;
3770 }
3771
3772 #if defined(PCIE)
3773 /**
3774 * @brief This function enables SSU support.
3775 *
3776 * @param pmpriv A pointer to mlan_private structure
3777 * @param cmd A pointer to HostCmd_DS_COMMAND structure
3778 * @param cmd_action The action: GET or SET
3779 * @param pdata_buf A pointer to data buffer
3780 *
3781 * @return MLAN_STATUS_SUCCESS
3782 */
wlan_cmd_ssu(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_u16 * pdata_buf)3783 mlan_status wlan_cmd_ssu(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
3784 t_u16 cmd_action, t_u16 *pdata_buf)
3785 {
3786 HostCmd_DS_SSU_CFG *ssu_cfg_cmd = &cmd->params.ssu_params;
3787 mlan_ds_ssu_params *ssu_params = MNULL;
3788 mlan_status ret = MLAN_STATUS_SUCCESS;
3789 mlan_adapter *pmadapter = pmpriv->adapter;
3790
3791 ENTER();
3792
3793 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_SSU);
3794 cmd->size = sizeof(HostCmd_DS_SSU_CFG) + S_DS_GEN;
3795 ssu_cfg_cmd->action = wlan_cpu_to_le16(cmd_action);
3796 switch (cmd_action) {
3797 case HostCmd_ACT_GEN_SET:
3798 case HostCmd_ACT_GEN_SET_DEFAULT:
3799 ssu_params = (mlan_ds_ssu_params *)pdata_buf;
3800 ssu_cfg_cmd->nskip = wlan_cpu_to_le32(ssu_params->nskip);
3801 ssu_cfg_cmd->nsel = wlan_cpu_to_le32(ssu_params->nsel);
3802 ssu_cfg_cmd->adcdownsample =
3803 wlan_cpu_to_le32(ssu_params->adcdownsample);
3804 ssu_cfg_cmd->mask_adc_pkt =
3805 wlan_cpu_to_le32(ssu_params->mask_adc_pkt);
3806 ssu_cfg_cmd->out_16bits =
3807 wlan_cpu_to_le32(ssu_params->out_16bits);
3808 ssu_cfg_cmd->spec_pwr_enable =
3809 wlan_cpu_to_le32(ssu_params->spec_pwr_enable);
3810 ssu_cfg_cmd->rate_deduction =
3811 wlan_cpu_to_le32(ssu_params->rate_deduction);
3812 ssu_cfg_cmd->n_pkt_avg =
3813 wlan_cpu_to_le32(ssu_params->n_pkt_avg);
3814 /* Initialize PCIE ring buffer */
3815 ret = wlan_alloc_ssu_pcie_buf(pmadapter);
3816 if (MLAN_STATUS_SUCCESS != ret) {
3817 PRINTM(MERROR,
3818 "Failed to allocate PCIE host buffers for SSU\n");
3819 LEAVE();
3820 return MLAN_STATUS_FAILURE;
3821 }
3822 ssu_cfg_cmd->buffer_base_addr[0] =
3823 wlan_cpu_to_le32((t_u32)pmadapter->ssu_buf->buf_pa);
3824 ssu_cfg_cmd->buffer_base_addr[1] = wlan_cpu_to_le32(
3825 (t_u32)((t_u64)(pmadapter->ssu_buf->buf_pa >> 32)));
3826 ssu_cfg_cmd->buffer_pool_size =
3827 wlan_cpu_to_le32(MLAN_SSU_BUF_SIZE);
3828 break;
3829 case HostCmd_ACT_GEN_GET:
3830 default:
3831 break;
3832 }
3833 cmd->size = wlan_cpu_to_le16(cmd->size);
3834 LEAVE();
3835 return MLAN_STATUS_SUCCESS;
3836 }
3837 #endif
3838
3839 /**
3840 * @brief This function prepares command of dmcs config.
3841 *
3842 * @param pmpriv A pointer to mlan_private structure
3843 * @param cmd A pointer to HostCmd_DS_COMMAND structure
3844 * @param cmd_action The action: GET or SET
3845 * @param pdata_buf A pointer to data buffer
3846 *
3847 * @return MLAN_STATUS_SUCCESS
3848 */
wlan_cmd_dmcs_config(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)3849 mlan_status wlan_cmd_dmcs_config(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
3850 t_u16 cmd_action, t_void *pdata_buf)
3851 {
3852 HostCmd_DS_DMCS_CFG *dmcs = &cmd->params.dmcs;
3853 mlan_ds_misc_mapping_policy *dmcs_params = MNULL;
3854 t_u8 *mapping_policy = (t_u8 *)dmcs->tlv_buf;
3855
3856 ENTER();
3857
3858 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_DMCS_CONFIG);
3859 cmd->size = sizeof(HostCmd_DS_DMCS_CFG) + S_DS_GEN;
3860 dmcs->action = wlan_cpu_to_le16(cmd_action);
3861 dmcs_params = (mlan_ds_misc_mapping_policy *)pdata_buf;
3862 dmcs->subcmd = wlan_cpu_to_le16(dmcs_params->subcmd);
3863 switch (dmcs->subcmd) {
3864 case 0:
3865 cmd->size += sizeof(t_u8);
3866 *mapping_policy = dmcs_params->mapping_policy;
3867 break;
3868 case 1:
3869 default:
3870 break;
3871 }
3872 cmd->size = wlan_cpu_to_le16(cmd->size);
3873 LEAVE();
3874 return MLAN_STATUS_SUCCESS;
3875 }
3876
3877 /**
3878 * @brief This function handles the command response of dmcs config
3879 *
3880 * @param pmpriv A pointer to mlan_private structure
3881 * @param resp A pointer to HostCmd_DS_COMMAND
3882 * @param pioctl_buf A pointer to mlan_ioctl_req structure
3883 *
3884 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
3885 */
wlan_ret_dmcs_config(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)3886 mlan_status wlan_ret_dmcs_config(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
3887 mlan_ioctl_req *pioctl_buf)
3888 {
3889 mlan_status ret = MLAN_STATUS_SUCCESS;
3890 HostCmd_DS_DMCS_CFG *dmcs = &resp->params.dmcs;
3891 MrvlIEtypes_DmcsStatus_t *dmcs_status;
3892 mlan_ds_misc_cfg *cfg = MNULL;
3893 t_u16 tlv_buf_left = 0;
3894 t_u16 tlv_type = 0, tlv_len = 0;
3895 MrvlIEtypesHeader_t *tlv = MNULL;
3896 int i = 0;
3897
3898 ENTER();
3899 if (pioctl_buf) {
3900 cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
3901 tlv = (MrvlIEtypesHeader_t *)((t_u8 *)dmcs +
3902 sizeof(HostCmd_DS_DMCS_CFG));
3903 tlv_buf_left =
3904 resp->size - (sizeof(HostCmd_DS_DMCS_CFG) + S_DS_GEN);
3905 while (tlv_buf_left > sizeof(MrvlIEtypesHeader_t)) {
3906 tlv_type = wlan_le16_to_cpu(tlv->type);
3907 tlv_len = wlan_le16_to_cpu(tlv->len);
3908 if (tlv_buf_left <
3909 (tlv_len + sizeof(MrvlIEtypesHeader_t))) {
3910 PRINTM(MERROR,
3911 "Error while processing DMCS status tlv, bytes_left < TLV len\n");
3912 ret = MLAN_STATUS_FAILURE;
3913 break;
3914 }
3915 switch (tlv_type) {
3916 case TLV_TYPE_DMCS_STATUS:
3917 dmcs_status = (MrvlIEtypes_DmcsStatus_t *)tlv;
3918 cfg->param.dmcs_status.mapping_policy =
3919 dmcs_status->mapping_policy;
3920 memset(pmpriv->adapter,
3921 &cfg->param.dmcs_status.radio_status, 0,
3922 sizeof(dmcsStatus_t));
3923 for (i = 0; i < MAX_NUM_MAC; i++) {
3924 memcpy_ext(
3925 pmpriv->adapter,
3926 &cfg->param.dmcs_status
3927 .radio_status[i],
3928 &dmcs_status->radio_status[i],
3929 sizeof(dmcsStatus_t),
3930 sizeof(dmcsStatus_t));
3931 }
3932 break;
3933 default:
3934 break;
3935 }
3936 tlv_buf_left -= tlv_len + sizeof(MrvlIEtypesHeader_t);
3937 tlv = (MrvlIEtypesHeader_t
3938 *)((t_u8 *)tlv + tlv_len +
3939 sizeof(MrvlIEtypesHeader_t));
3940 }
3941 pioctl_buf->data_read_written =
3942 sizeof(mlan_ds_misc_dmcs_status);
3943 }
3944 LEAVE();
3945 return ret;
3946 }
3947
3948 /**
3949 * @brief This function prepares command of tx_rate_cfg.
3950 *
3951 * @param pmpriv A pointer to mlan_private structure
3952 * @param cmd A pointer to HostCmd_DS_COMMAND structure
3953 * @param cmd_action The action: GET or SET
3954 * @param pdata_buf A pointer to data buffer
3955 * @param pioctl_buf A pointer to ioctl buffer
3956 *
3957 * @return MLAN_STATUS_SUCCESS
3958 */
wlan_cmd_tx_rate_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf,mlan_ioctl_req * pioctl_buf)3959 mlan_status wlan_cmd_tx_rate_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
3960 t_u16 cmd_action, t_void *pdata_buf,
3961 mlan_ioctl_req *pioctl_buf)
3962 {
3963 HostCmd_DS_TX_RATE_CFG *rate_cfg =
3964 (HostCmd_DS_TX_RATE_CFG *)&(cmd->params.tx_rate_cfg);
3965 MrvlRateScope_t *rate_scope;
3966 MrvlRateDropPattern_t *rate_drop;
3967 MrvlIETypes_rate_setting_t *rate_setting_tlv;
3968 mlan_ds_rate *ds_rate = MNULL;
3969 t_u16 *pbitmap_rates = (t_u16 *)pdata_buf;
3970
3971 t_u32 i;
3972
3973 ENTER();
3974
3975 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_TX_RATE_CFG);
3976
3977 rate_cfg->action = wlan_cpu_to_le16(cmd_action);
3978 rate_cfg->cfg_index = 0;
3979
3980 rate_scope = (MrvlRateScope_t *)rate_cfg->tlv_buf;
3981 rate_scope->type = wlan_cpu_to_le16(TLV_TYPE_RATE_SCOPE);
3982 rate_scope->length = wlan_cpu_to_le16(sizeof(MrvlRateScope_t) -
3983 sizeof(MrvlIEtypesHeader_t));
3984 if (pbitmap_rates != MNULL) {
3985 rate_scope->hr_dsss_rate_bitmap =
3986 wlan_cpu_to_le16(pbitmap_rates[0]);
3987 rate_scope->ofdm_rate_bitmap =
3988 wlan_cpu_to_le16(pbitmap_rates[1]);
3989 for (i = 0; i < NELEMENTS(rate_scope->ht_mcs_rate_bitmap); i++)
3990 rate_scope->ht_mcs_rate_bitmap[i] =
3991 wlan_cpu_to_le16(pbitmap_rates[2 + i]);
3992 for (i = 0; i < NELEMENTS(rate_scope->vht_mcs_rate_bitmap); i++)
3993 rate_scope->vht_mcs_rate_bitmap[i] = wlan_cpu_to_le16(
3994 pbitmap_rates
3995 [2 +
3996 NELEMENTS(
3997 rate_scope->ht_mcs_rate_bitmap) +
3998 i]);
3999 if (IS_FW_SUPPORT_11AX(pmpriv->adapter)) {
4000 for (i = 0;
4001 i < NELEMENTS(rate_scope->he_mcs_rate_bitmap); i++)
4002 rate_scope->he_mcs_rate_bitmap
4003 [i] = wlan_cpu_to_le16(
4004 pbitmap_rates[2 +
4005 wlan_get_bitmap_index(
4006 rate_scope) +
4007 i]);
4008 } else {
4009 rate_scope->length = wlan_cpu_to_le16(
4010 sizeof(MrvlRateScope_t) -
4011 sizeof(rate_scope->he_mcs_rate_bitmap) -
4012 sizeof(MrvlIEtypesHeader_t));
4013 }
4014 } else {
4015 rate_scope->hr_dsss_rate_bitmap =
4016 wlan_cpu_to_le16(pmpriv->bitmap_rates[0]);
4017 rate_scope->ofdm_rate_bitmap =
4018 wlan_cpu_to_le16(pmpriv->bitmap_rates[1]);
4019 for (i = 0; i < NELEMENTS(rate_scope->ht_mcs_rate_bitmap); i++)
4020 rate_scope->ht_mcs_rate_bitmap[i] =
4021 wlan_cpu_to_le16(pmpriv->bitmap_rates[2 + i]);
4022 for (i = 0; i < NELEMENTS(rate_scope->vht_mcs_rate_bitmap); i++)
4023 rate_scope->vht_mcs_rate_bitmap[i] = wlan_cpu_to_le16(
4024 pmpriv->bitmap_rates
4025 [2 +
4026 NELEMENTS(
4027 rate_scope->ht_mcs_rate_bitmap) +
4028 i]);
4029 if (IS_FW_SUPPORT_11AX(pmpriv->adapter)) {
4030 for (i = 0;
4031 i < NELEMENTS(rate_scope->vht_mcs_rate_bitmap);
4032 i++)
4033 rate_scope->he_mcs_rate_bitmap[i] =
4034 wlan_cpu_to_le16(
4035 pmpriv->bitmap_rates
4036 [2 +
4037 wlan_get_bitmap_index(
4038 rate_scope) +
4039 i]);
4040 } else {
4041 rate_scope->length = wlan_cpu_to_le16(
4042 sizeof(MrvlRateScope_t) -
4043 sizeof(rate_scope->he_mcs_rate_bitmap) -
4044 sizeof(MrvlIEtypesHeader_t));
4045 }
4046 }
4047
4048 rate_drop =
4049 (MrvlRateDropPattern_t *)((t_u8 *)rate_scope +
4050 wlan_le16_to_cpu(rate_scope->length) +
4051 sizeof(MrvlIEtypesHeader_t));
4052 rate_drop->type = wlan_cpu_to_le16(TLV_TYPE_RATE_DROP_PATTERN);
4053 rate_drop->length = wlan_cpu_to_le16(sizeof(rate_drop->rate_drop_mode));
4054 rate_drop->rate_drop_mode = 0;
4055
4056 cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_TX_RATE_CFG) +
4057 wlan_le16_to_cpu(rate_scope->length) +
4058 sizeof(MrvlIEtypesHeader_t) +
4059 sizeof(MrvlRateDropPattern_t));
4060 if (pioctl_buf && pmpriv->adapter->pcard_info->v17_fw_api) {
4061 ds_rate = (mlan_ds_rate *)pioctl_buf->pbuf;
4062 rate_setting_tlv = (MrvlIETypes_rate_setting_t
4063 *)((t_u8 *)rate_drop +
4064 sizeof(MrvlRateDropPattern_t));
4065 rate_setting_tlv->header.type =
4066 wlan_cpu_to_le16(TLV_TYPE_TX_RATE_CFG);
4067 rate_setting_tlv->header.len = wlan_cpu_to_le16(
4068 sizeof(rate_setting_tlv->rate_setting));
4069 rate_setting_tlv->rate_setting =
4070 wlan_cpu_to_le16(ds_rate->param.rate_cfg.rate_setting);
4071 PRINTM(MCMND, "he rate setting = %d\n",
4072 rate_setting_tlv->rate_setting);
4073 cmd->size = wlan_cpu_to_le16(
4074 S_DS_GEN + sizeof(HostCmd_DS_TX_RATE_CFG) +
4075 wlan_le16_to_cpu(rate_scope->length) +
4076 sizeof(MrvlIEtypesHeader_t) +
4077 sizeof(MrvlRateDropPattern_t) +
4078 sizeof(MrvlIETypes_rate_setting_t));
4079 }
4080 LEAVE();
4081 return MLAN_STATUS_SUCCESS;
4082 }
4083
4084 /**
4085 * @brief This function handles the command response of tx_rate_cfg
4086 *
4087 * @param pmpriv A pointer to mlan_private structure
4088 * @param resp A pointer to HostCmd_DS_COMMAND
4089 * @param pioctl_buf A pointer to mlan_ioctl_req structure
4090 *
4091 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
4092 */
wlan_ret_tx_rate_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)4093 mlan_status wlan_ret_tx_rate_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
4094 mlan_ioctl_req *pioctl_buf)
4095 {
4096 mlan_adapter *pmadapter = pmpriv->adapter;
4097 mlan_ds_rate *ds_rate = MNULL;
4098 HostCmd_DS_TX_RATE_CFG *prate_cfg = MNULL;
4099 MrvlRateScope_t *prate_scope;
4100 MrvlIEtypesHeader_t *head = MNULL;
4101 t_u16 tlv, tlv_buf_len = 0;
4102 t_u8 *tlv_buf;
4103 t_u32 i;
4104 t_s32 index;
4105 mlan_status ret = MLAN_STATUS_SUCCESS;
4106 MrvlIETypes_rate_setting_t *rate_setting_tlv = MNULL;
4107 t_u16 rate_setting = 0xffff;
4108
4109 ENTER();
4110
4111 if (resp == MNULL) {
4112 LEAVE();
4113 return MLAN_STATUS_FAILURE;
4114 }
4115 prate_cfg = (HostCmd_DS_TX_RATE_CFG *)&(resp->params.tx_rate_cfg);
4116
4117 tlv_buf = (t_u8 *)prate_cfg->tlv_buf;
4118 tlv_buf_len = resp->size - (sizeof(HostCmd_DS_TX_RATE_CFG) + S_DS_GEN);
4119
4120 while (tlv_buf && tlv_buf_len > 0) {
4121 tlv = (*tlv_buf);
4122 tlv = tlv | (*(tlv_buf + 1) << 8);
4123
4124 switch (tlv) {
4125 case TLV_TYPE_RATE_SCOPE:
4126 prate_scope = (MrvlRateScope_t *)tlv_buf;
4127 pmpriv->bitmap_rates[0] = wlan_le16_to_cpu(
4128 prate_scope->hr_dsss_rate_bitmap);
4129 pmpriv->bitmap_rates[1] =
4130 wlan_le16_to_cpu(prate_scope->ofdm_rate_bitmap);
4131 for (i = 0;
4132 i < NELEMENTS(prate_scope->ht_mcs_rate_bitmap);
4133 i++)
4134 pmpriv->bitmap_rates[2 + i] = wlan_le16_to_cpu(
4135 prate_scope->ht_mcs_rate_bitmap[i]);
4136 for (i = 0;
4137 i < NELEMENTS(prate_scope->vht_mcs_rate_bitmap);
4138 i++)
4139 pmpriv->bitmap_rates
4140 [2 +
4141 sizeof(prate_scope->ht_mcs_rate_bitmap) /
4142 sizeof(t_u16) +
4143 i] =
4144 wlan_le16_to_cpu(
4145 prate_scope
4146 ->vht_mcs_rate_bitmap[i]);
4147 if (IS_FW_SUPPORT_11AX(pmadapter)) {
4148 for (i = 0;
4149 i <
4150 NELEMENTS(prate_scope->he_mcs_rate_bitmap);
4151 i++)
4152 pmpriv->bitmap_rates
4153 [2 +
4154 sizeof(prate_scope
4155 ->ht_mcs_rate_bitmap) /
4156 sizeof(t_u16) +
4157 sizeof(prate_scope
4158 ->vht_mcs_rate_bitmap) /
4159 sizeof(t_u16) +
4160 i] =
4161 wlan_le16_to_cpu(
4162 prate_scope
4163 ->he_mcs_rate_bitmap
4164 [i]);
4165 }
4166 break;
4167 case TLV_TYPE_TX_RATE_CFG:
4168 rate_setting_tlv =
4169 (MrvlIETypes_rate_setting_t *)tlv_buf;
4170 rate_setting = rate_setting_tlv->rate_setting;
4171 break;
4172 /* Add RATE_DROP tlv here */
4173 }
4174
4175 head = (MrvlIEtypesHeader_t *)tlv_buf;
4176 head->len = wlan_le16_to_cpu(head->len);
4177 tlv_buf += head->len + sizeof(MrvlIEtypesHeader_t);
4178 tlv_buf_len -= (head->len + sizeof(MrvlIEtypesHeader_t));
4179 }
4180
4181 pmpriv->is_data_rate_auto = wlan_is_rate_auto(pmpriv);
4182
4183 if (pmpriv->is_data_rate_auto) {
4184 pmpriv->data_rate = 0;
4185 } else {
4186 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_TX_RATE_QUERY,
4187 HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
4188 }
4189
4190 if (pioctl_buf) {
4191 ds_rate = (mlan_ds_rate *)pioctl_buf->pbuf;
4192 if (ds_rate == MNULL) {
4193 PRINTM(MERROR, "Request buffer not found!\n");
4194 LEAVE();
4195 return MLAN_STATUS_FAILURE;
4196 }
4197 if (pmpriv->is_data_rate_auto) {
4198 ds_rate->param.rate_cfg.is_rate_auto = MTRUE;
4199 ds_rate->param.rate_cfg.rate_format =
4200 MLAN_RATE_FORMAT_AUTO;
4201 } else {
4202 ds_rate->param.rate_cfg.is_rate_auto = MFALSE;
4203 /* check the LG rate */
4204 index = wlan_get_rate_index(
4205 pmadapter, &pmpriv->bitmap_rates[0], 4);
4206 if (index != -1) {
4207 if ((index >= MLAN_RATE_BITMAP_OFDM0) &&
4208 (index <= MLAN_RATE_BITMAP_OFDM7))
4209 index -= (MLAN_RATE_BITMAP_OFDM0 -
4210 MLAN_RATE_INDEX_OFDM0);
4211 ds_rate->param.rate_cfg.rate_format =
4212 MLAN_RATE_FORMAT_LG;
4213 ds_rate->param.rate_cfg.rate = index;
4214 }
4215 /* check the HT rate */
4216 index = wlan_get_rate_index(
4217 pmadapter, &pmpriv->bitmap_rates[2], 16);
4218 if (index != -1) {
4219 ds_rate->param.rate_cfg.rate_format =
4220 MLAN_RATE_FORMAT_HT;
4221 ds_rate->param.rate_cfg.rate = index;
4222 }
4223 /* check the VHT rate */
4224 index = wlan_get_rate_index(
4225 pmadapter, &pmpriv->bitmap_rates[10], 16);
4226 if (index != -1) {
4227 ds_rate->param.rate_cfg.rate_format =
4228 MLAN_RATE_FORMAT_VHT;
4229 ds_rate->param.rate_cfg.rate = index % 16;
4230 ds_rate->param.rate_cfg.nss = index / 16;
4231 ds_rate->param.rate_cfg.nss += MLAN_RATE_NSS1;
4232 }
4233 /* check the HE rate */
4234 if (IS_FW_SUPPORT_11AX(pmadapter)) {
4235 index = wlan_get_rate_index(
4236 pmadapter, &pmpriv->bitmap_rates[18],
4237 16);
4238 if (index != -1) {
4239 ds_rate->param.rate_cfg.rate_format =
4240 MLAN_RATE_FORMAT_HE;
4241 ds_rate->param.rate_cfg.rate =
4242 index % 16;
4243 ds_rate->param.rate_cfg.nss =
4244 index / 16;
4245 ds_rate->param.rate_cfg.nss +=
4246 MLAN_RATE_NSS1;
4247 }
4248 }
4249 ds_rate->param.rate_cfg.rate_setting = rate_setting;
4250 PRINTM(MINFO, "Rate index is %d\n",
4251 ds_rate->param.rate_cfg.rate);
4252 }
4253 for (i = 0; i < MAX_BITMAP_RATES_SIZE; i++) {
4254 ds_rate->param.rate_cfg.bitmap_rates[i] =
4255 pmpriv->bitmap_rates[i];
4256 }
4257 }
4258
4259 LEAVE();
4260 return ret;
4261 }
4262
4263 /**
4264 * @brief This function issues adapter specific commands
4265 * to initialize firmware
4266 *
4267 * @param pmadapter A pointer to mlan_adapter structure
4268 *
4269 * @return MLAN_STATUS_PENDING or MLAN_STATUS_FAILURE
4270 */
wlan_adapter_get_hw_spec(pmlan_adapter pmadapter)4271 mlan_status wlan_adapter_get_hw_spec(pmlan_adapter pmadapter)
4272 {
4273 mlan_status ret = MLAN_STATUS_SUCCESS;
4274 pmlan_private priv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);
4275
4276 ENTER();
4277 #if defined(SDIO)
4278 /*
4279 * This should be issued in the very first to config
4280 * SDIO_GPIO interrupt mode.
4281 */
4282 if (IS_SD(pmadapter->card_type) &&
4283 (wlan_set_sdio_gpio_int(priv) != MLAN_STATUS_SUCCESS)) {
4284 ret = MLAN_STATUS_FAILURE;
4285 goto done;
4286 }
4287 #endif
4288
4289 #ifdef PCIE
4290 if (IS_PCIE(pmadapter->card_type) &&
4291 (MLAN_STATUS_SUCCESS != wlan_set_pcie_buf_config(priv))) {
4292 ret = MLAN_STATUS_FAILURE;
4293 goto done;
4294 }
4295 #endif
4296
4297 ret = wlan_prepare_cmd(priv, HostCmd_CMD_FUNC_INIT, HostCmd_ACT_GEN_SET,
4298 0, MNULL, MNULL);
4299 if (ret) {
4300 ret = MLAN_STATUS_FAILURE;
4301 goto done;
4302 }
4303 /** DPD data dnld cmd prepare */
4304 if ((pmadapter->pdpd_data) && (pmadapter->dpd_data_len > 0)) {
4305 ret = wlan_process_hostcmd_cfg(priv, CFG_TYPE_DPDFILE,
4306 pmadapter->pdpd_data,
4307 pmadapter->dpd_data_len);
4308 if (ret) {
4309 ret = MLAN_STATUS_FAILURE;
4310 goto done;
4311 }
4312 pmadapter->pdpd_data = MNULL;
4313 pmadapter->dpd_data_len = 0;
4314 }
4315 if ((pmadapter->ptxpwr_data) && (pmadapter->txpwr_data_len > 0)) {
4316 ret = wlan_process_hostcmd_cfg(priv, CFG_TYPE_HOSTCMD,
4317 pmadapter->ptxpwr_data,
4318 pmadapter->txpwr_data_len);
4319 if (ret) {
4320 ret = MLAN_STATUS_FAILURE;
4321 goto done;
4322 }
4323 pmadapter->ptxpwr_data = MNULL;
4324 pmadapter->txpwr_data_len = 0;
4325 }
4326 if (!pmadapter->pdpd_data &&
4327 (pmadapter->dpd_data_len == UNKNOW_DPD_LENGTH)) {
4328 ret = wlan_prepare_cmd(priv, HostCmd_CMD_CFG_DATA,
4329 HostCmd_ACT_GEN_GET, OID_TYPE_DPD, MNULL,
4330 MNULL);
4331 if (ret) {
4332 ret = MLAN_STATUS_FAILURE;
4333 goto done;
4334 }
4335 }
4336 /** Cal data dnld cmd prepare */
4337 if ((pmadapter->pcal_data) && (pmadapter->cal_data_len > 0)) {
4338 ret = wlan_prepare_cmd(priv, HostCmd_CMD_CFG_DATA,
4339 HostCmd_ACT_GEN_SET, OID_TYPE_CAL, MNULL,
4340 MNULL);
4341 if (ret) {
4342 ret = MLAN_STATUS_FAILURE;
4343 goto done;
4344 }
4345 pmadapter->pcal_data = MNULL;
4346 pmadapter->cal_data_len = 0;
4347 }
4348 /* Get FW region and cfp tables */
4349 ret = wlan_prepare_cmd(priv, HostCmd_CMD_CHAN_REGION_CFG,
4350 HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
4351 if (ret) {
4352 ret = MLAN_STATUS_FAILURE;
4353 goto done;
4354 }
4355 /*
4356 * Get HW spec
4357 */
4358 ret = wlan_prepare_cmd(priv, HostCmd_CMD_GET_HW_SPEC,
4359 HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
4360 if (ret) {
4361 ret = MLAN_STATUS_FAILURE;
4362 goto done;
4363 }
4364 ret = MLAN_STATUS_PENDING;
4365 done:
4366 LEAVE();
4367 return ret;
4368 }
4369
4370 /**
4371 * @brief This function issues adapter specific commands
4372 * to initialize firmware
4373 *
4374 * @param pmadapter A pointer to mlan_adapter structure
4375 *
4376 * @return MLAN_STATUS_PENDING or MLAN_STATUS_FAILURE
4377 */
wlan_adapter_init_cmd(pmlan_adapter pmadapter)4378 mlan_status wlan_adapter_init_cmd(pmlan_adapter pmadapter)
4379 {
4380 mlan_status ret = MLAN_STATUS_SUCCESS;
4381 pmlan_private pmpriv = MNULL;
4382 #ifdef STA_SUPPORT
4383 pmlan_private pmpriv_sta = MNULL;
4384 #endif
4385 ENTER();
4386
4387 pmpriv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);
4388 #ifdef STA_SUPPORT
4389 pmpriv_sta = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_STA);
4390 #endif
4391
4392 #ifdef SDIO
4393 if (IS_SD(pmadapter->card_type)) {
4394 }
4395 #endif
4396
4397 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_RECONFIGURE_TX_BUFF,
4398 HostCmd_ACT_GEN_SET, 0, MNULL,
4399 &pmadapter->max_tx_buf_size);
4400 if (ret) {
4401 ret = MLAN_STATUS_FAILURE;
4402 goto done;
4403 }
4404
4405 #if defined(STA_SUPPORT)
4406 if (pmpriv_sta &&
4407 (pmpriv_sta->state_11d.user_enable_11d == ENABLE_11D)) {
4408 /* Send command to FW to enable 11d */
4409 ret = wlan_prepare_cmd(pmpriv_sta, HostCmd_CMD_802_11_SNMP_MIB,
4410 HostCmd_ACT_GEN_SET, Dot11D_i, MNULL,
4411 &pmpriv_sta->state_11d.user_enable_11d);
4412 if (ret) {
4413 ret = MLAN_STATUS_FAILURE;
4414 goto done;
4415 }
4416 }
4417 #endif
4418
4419 #ifdef STA_SUPPORT
4420 if (pmpriv_sta && (pmadapter->ps_mode == Wlan802_11PowerModePSP)) {
4421 ret = wlan_prepare_cmd(pmpriv_sta,
4422 HostCmd_CMD_802_11_PS_MODE_ENH,
4423 EN_AUTO_PS, BITMAP_STA_PS, MNULL, MNULL);
4424 if (ret) {
4425 ret = MLAN_STATUS_FAILURE;
4426 goto done;
4427 }
4428 }
4429 #endif
4430
4431 if (pmadapter->init_auto_ds) {
4432 mlan_ds_auto_ds auto_ds;
4433 /* Enable auto deep sleep */
4434 auto_ds.idletime = pmadapter->idle_time;
4435 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_PS_MODE_ENH,
4436 EN_AUTO_PS, BITMAP_AUTO_DS, MNULL,
4437 &auto_ds);
4438 if (ret) {
4439 ret = MLAN_STATUS_FAILURE;
4440 goto done;
4441 }
4442 }
4443
4444 #define DEF_AUTO_NULL_PKT_PERIOD 30
4445 if (pmpriv_sta) {
4446 t_u32 value = DEF_AUTO_NULL_PKT_PERIOD;
4447 ret = wlan_prepare_cmd(pmpriv_sta, HostCmd_CMD_802_11_SNMP_MIB,
4448 HostCmd_ACT_GEN_SET, NullPktPeriod_i,
4449 MNULL, &value);
4450 if (ret) {
4451 ret = MLAN_STATUS_FAILURE;
4452 goto done;
4453 }
4454 }
4455 if (pmadapter->init_para.indrstcfg != 0xffffffff) {
4456 mlan_ds_ind_rst_cfg ind_rst_cfg;
4457 ind_rst_cfg.ir_mode = pmadapter->init_para.indrstcfg & 0xff;
4458 ind_rst_cfg.gpio_pin =
4459 (pmadapter->init_para.indrstcfg & 0xff00) >> 8;
4460 ret = wlan_prepare_cmd(pmpriv,
4461 HostCmd_CMD_INDEPENDENT_RESET_CFG,
4462 HostCmd_ACT_GEN_SET, 0, MNULL,
4463 (t_void *)&ind_rst_cfg);
4464 if (ret) {
4465 ret = MLAN_STATUS_FAILURE;
4466 goto done;
4467 }
4468 }
4469
4470 if (pmadapter->inact_tmo) {
4471 ret = wlan_prepare_cmd(pmpriv,
4472 HostCmd_CMD_802_11_PS_INACTIVITY_TIMEOUT,
4473 HostCmd_ACT_GEN_SET, 0, MNULL,
4474 &pmadapter->inact_tmo);
4475 if (ret) {
4476 ret = MLAN_STATUS_FAILURE;
4477 goto done;
4478 }
4479 }
4480 /* Send request to firmware */
4481 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_RF_ANTENNA,
4482 HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
4483 if (ret) {
4484 ret = MLAN_STATUS_FAILURE;
4485 goto done;
4486 }
4487 ret = MLAN_STATUS_PENDING;
4488 done:
4489 LEAVE();
4490 return ret;
4491 }
4492
4493 #ifdef RX_PACKET_COALESCE
wlan_cmd_rx_pkt_coalesce_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)4494 mlan_status wlan_cmd_rx_pkt_coalesce_cfg(pmlan_private pmpriv,
4495 HostCmd_DS_COMMAND *cmd,
4496 t_u16 cmd_action, t_void *pdata_buf)
4497 {
4498 mlan_ds_misc_rx_packet_coalesce *rx_pkt_cfg =
4499 (mlan_ds_misc_rx_packet_coalesce *)pdata_buf;
4500 HostCmd_DS_RX_PKT_COAL_CFG *prx_coal_cfg =
4501 (HostCmd_DS_RX_PKT_COAL_CFG *)&cmd->params.rx_pkt_coal_cfg;
4502
4503 ENTER();
4504
4505 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_RX_PKT_COALESCE_CFG);
4506 prx_coal_cfg->action = wlan_cpu_to_le16(cmd_action);
4507
4508 if (cmd_action == HostCmd_ACT_GEN_SET) {
4509 prx_coal_cfg->packet_threshold =
4510 wlan_cpu_to_le32(rx_pkt_cfg->packet_threshold);
4511 prx_coal_cfg->delay = wlan_cpu_to_le16(rx_pkt_cfg->delay);
4512 PRINTM(MCMND,
4513 "Set RX coal config: packet threshold=%d delay=%d\n",
4514 rx_pkt_cfg->packet_threshold, rx_pkt_cfg->delay);
4515 cmd->size = wlan_cpu_to_le16(
4516 S_DS_GEN + sizeof(HostCmd_DS_RX_PKT_COAL_CFG));
4517 } else {
4518 cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(cmd_action));
4519 }
4520
4521 LEAVE();
4522 return MLAN_STATUS_SUCCESS;
4523 }
4524
4525 /**
4526 * @brief This function handles the command response of RX_PACKET_COAL_CFG
4527 *
4528 * @param pmpriv A pointer to mlan_private structure
4529 * @param resp A pointer to HostCmd_DS_COMMAND
4530 * @param pioctl_buf A pointer to mlan_ioctl_req structure
4531 *
4532 * @return MLAN_STATUS_SUCCESS
4533 */
wlan_ret_rx_pkt_coalesce_cfg(pmlan_private pmpriv,const HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)4534 mlan_status wlan_ret_rx_pkt_coalesce_cfg(pmlan_private pmpriv,
4535 const HostCmd_DS_COMMAND *resp,
4536 mlan_ioctl_req *pioctl_buf)
4537 {
4538 mlan_ds_misc_cfg *pcfg = MNULL;
4539 const HostCmd_DS_RX_PKT_COAL_CFG *presp_cfg =
4540 &resp->params.rx_pkt_coal_cfg;
4541
4542 ENTER();
4543
4544 if (pioctl_buf) {
4545 pcfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
4546 pcfg->param.rx_coalesce.packet_threshold =
4547 wlan_le32_to_cpu(presp_cfg->packet_threshold);
4548 pcfg->param.rx_coalesce.delay =
4549 wlan_le16_to_cpu(presp_cfg->delay);
4550 PRINTM(MCMND,
4551 "Get rx pkt coalesce info: packet threshold=%d delay=%d\n",
4552 pcfg->param.rx_coalesce.packet_threshold,
4553 pcfg->param.rx_coalesce.delay);
4554 pioctl_buf->buf_len = sizeof(mlan_ds_misc_rx_packet_coalesce);
4555 }
4556
4557 LEAVE();
4558 return MLAN_STATUS_SUCCESS;
4559 }
4560
4561 #endif
4562
4563 /**
4564 * @brief This function download the vdll block.
4565 *
4566 * @param pmadapter A pointer to mlan_adapter structure
4567 * @param block A pointer to VDLL block
4568 * @param block_len The VDLL block length
4569 *
4570 * @return MLAN_STATUS_SUCCESS
4571 */
wlan_download_vdll_block(mlan_adapter * pmadapter,t_u8 * block,t_u16 block_len)4572 mlan_status wlan_download_vdll_block(mlan_adapter *pmadapter, t_u8 *block,
4573 t_u16 block_len)
4574 {
4575 mlan_status status = MLAN_STATUS_FAILURE;
4576 mlan_status ret = MLAN_STATUS_PENDING;
4577 #if defined(SDIO) || defined(PCIE)
4578 pvdll_dnld_ctrl ctrl = &pmadapter->vdll_ctrl;
4579 #endif
4580 mlan_buffer *pmbuf = MNULL;
4581 mlan_private *pmpriv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);
4582 HostCmd_DS_GEN *cmd_hdr = MNULL;
4583 t_u16 msg_len = block_len + sizeof(HostCmd_DS_GEN);
4584 #ifdef USB
4585 t_u32 tmp;
4586 #endif
4587 ENTER();
4588 #if defined(SDIO) || defined(PCIE)
4589 if (!IS_USB(pmadapter->card_type)) {
4590 pmbuf = ctrl->cmd_buf;
4591 if (pmbuf)
4592 pmbuf->data_offset += pmadapter->ops.intf_header_len;
4593 }
4594 #endif
4595 #ifdef USB
4596 if (IS_USB(pmadapter->card_type)) {
4597 pmbuf = wlan_alloc_mlan_buffer(pmadapter,
4598 MRVDRV_SIZE_OF_CMD_BUFFER, 0,
4599 MOAL_MALLOC_BUFFER);
4600 if (pmbuf) {
4601 tmp = wlan_cpu_to_le32(MLAN_USB_TYPE_VDLL);
4602 memcpy_ext(pmadapter,
4603 (t_u8 *)(pmbuf->pbuf + pmbuf->data_offset),
4604 (t_u8 *)&tmp, MLAN_TYPE_LEN, MLAN_TYPE_LEN);
4605 pmbuf->data_offset += MLAN_TYPE_LEN;
4606 }
4607 }
4608 #endif
4609 if (!pmbuf) {
4610 PRINTM(MERROR, "dnld vdll: Fail to alloc vdll buf");
4611 goto done;
4612 }
4613 cmd_hdr = (HostCmd_DS_GEN *)(pmbuf->pbuf + pmbuf->data_offset);
4614 cmd_hdr->command = wlan_cpu_to_le16(HostCmd_CMD_VDLL);
4615 cmd_hdr->seq_num = wlan_cpu_to_le16(0xFF00);
4616 cmd_hdr->size = wlan_cpu_to_le16(msg_len);
4617
4618 pmadapter->callbacks.moal_memcpy_ext(pmadapter->pmoal_handle,
4619 pmbuf->pbuf + pmbuf->data_offset +
4620 sizeof(HostCmd_DS_GEN),
4621 block, block_len, block_len);
4622
4623 pmbuf->data_len = msg_len;
4624
4625 #if defined(SDIO) || defined(PCIE)
4626 if (!IS_USB(pmadapter->card_type)) {
4627 pmbuf->data_offset -= pmadapter->ops.intf_header_len;
4628 pmbuf->data_len += pmadapter->ops.intf_header_len;
4629 }
4630 #endif
4631 #ifdef USB
4632 if (IS_USB(pmadapter->card_type)) {
4633 pmbuf->data_offset -= MLAN_TYPE_LEN;
4634 pmbuf->data_len += MLAN_TYPE_LEN;
4635 }
4636 #endif
4637 PRINTM_NETINTF(MCMND, pmpriv);
4638 PRINTM(MCMND, "DNLD_VDLL : block_len=%d\n", block_len);
4639
4640 ret = pmadapter->ops.host_to_card(pmpriv, MLAN_TYPE_VDLL, pmbuf, MNULL);
4641
4642 if (ret == MLAN_STATUS_FAILURE)
4643 PRINTM(MERROR, "DNLD_VDLL: Host to Card Failed\n");
4644 else
4645 status = MLAN_STATUS_SUCCESS;
4646
4647 done:
4648 if ((ret == MLAN_STATUS_FAILURE) || (ret == MLAN_STATUS_SUCCESS)) {
4649 #ifdef USB
4650 if (IS_USB(pmadapter->card_type))
4651 wlan_free_mlan_buffer(pmadapter, pmbuf);
4652 #endif
4653 }
4654 LEAVE();
4655 return status;
4656 }
4657
4658 /**
4659 * @brief The function Get the VDLL image from moal
4660 *
4661 * @param pmadapter A pointer to mlan_adapter structure
4662 * @param offset offset
4663 *
4664 * @return MLAN_STATUS_SUCCESS
4665 *
4666 */
wlan_get_vdll_image(pmlan_adapter pmadapter,t_u32 vdll_len)4667 static mlan_status wlan_get_vdll_image(pmlan_adapter pmadapter, t_u32 vdll_len)
4668 {
4669 mlan_status status = MLAN_STATUS_SUCCESS;
4670 vdll_dnld_ctrl *ctrl = &pmadapter->vdll_ctrl;
4671 pmlan_callbacks pcb = &pmadapter->callbacks;
4672
4673 ENTER();
4674
4675 if (ctrl->vdll_mem) {
4676 PRINTM(MCMND, "VDLL mem is not empty: %p len=%d\n",
4677 ctrl->vdll_mem, ctrl->vdll_len);
4678 goto done;
4679 }
4680 if (pcb->moal_vmalloc && pcb->moal_vfree)
4681 status = pcb->moal_vmalloc(pmadapter->pmoal_handle, vdll_len,
4682 (t_u8 **)&ctrl->vdll_mem);
4683 else
4684 status = pcb->moal_malloc(pmadapter->pmoal_handle, vdll_len,
4685 MLAN_MEM_DEF,
4686 (t_u8 **)&ctrl->vdll_mem);
4687
4688 if (status != MLAN_STATUS_SUCCESS) {
4689 PRINTM(MERROR, "VDLL: Fail to alloc vdll memory");
4690 goto done;
4691 }
4692
4693 if (MLAN_STATUS_SUCCESS !=
4694 pcb->moal_get_vdll_data(pmadapter->pmoal_handle, vdll_len,
4695 ctrl->vdll_mem)) {
4696 PRINTM(MERROR, "VDLL: firmware image not available\n");
4697 status = MLAN_STATUS_FAILURE;
4698 if (pcb->moal_vmalloc && pcb->moal_vfree)
4699 pcb->moal_vfree(pmadapter->pmoal_handle,
4700 (t_u8 *)ctrl->vdll_mem);
4701 else
4702 pcb->moal_mfree(pmadapter->pmoal_handle,
4703 (t_u8 *)ctrl->vdll_mem);
4704 ctrl->vdll_mem = MNULL;
4705 ctrl->vdll_len = 0;
4706 goto done;
4707 }
4708 /*allocate a memory to store all VDLL images*/
4709 ctrl->vdll_len = vdll_len;
4710 PRINTM(MMSG, "VDLL image: len=%d\n", ctrl->vdll_len);
4711 done:
4712 LEAVE();
4713 return status;
4714 }
4715
4716 /**
4717 * @brief This function handle the multi_chan info event
4718 *
4719 * @param pmpriv A pointer to mlan_private structure
4720 * @param pevent A pointer to event buffer
4721 *
4722 * @return MLAN_STATUS_SUCCESS
4723 */
wlan_process_vdll_event(pmlan_private pmpriv,pmlan_buffer pevent)4724 mlan_status wlan_process_vdll_event(pmlan_private pmpriv, pmlan_buffer pevent)
4725 {
4726 mlan_status status = MLAN_STATUS_SUCCESS;
4727 vdll_ind *ind = MNULL;
4728 t_u32 offset = 0;
4729 t_u16 block_len = 0;
4730 mlan_adapter *pmadapter = pmpriv->adapter;
4731 vdll_dnld_ctrl *ctrl = &pmadapter->vdll_ctrl;
4732
4733 ENTER();
4734 ind = (vdll_ind *)(pevent->pbuf + pevent->data_offset +
4735 sizeof(mlan_event_id));
4736 switch (wlan_le16_to_cpu(ind->type)) {
4737 case VDLL_IND_TYPE_REQ:
4738 offset = wlan_le32_to_cpu(ind->offset);
4739 block_len = wlan_le16_to_cpu(ind->block_len);
4740 PRINTM(MEVENT, "VDLL_IND: type=%d offset = 0x%x, len = %d\n",
4741 wlan_le16_to_cpu(ind->type), offset, block_len);
4742 if (offset <= ctrl->vdll_len) {
4743 block_len = MIN(block_len, ctrl->vdll_len - offset);
4744 if (!pmadapter->cmd_sent) {
4745 status = wlan_download_vdll_block(
4746 pmadapter, ctrl->vdll_mem + offset,
4747 block_len);
4748 if (status)
4749 PRINTM(MERROR,
4750 "Fail to download VDLL block\n");
4751 } else {
4752 PRINTM(MCMND,
4753 "cmd_sent=1, delay download VDLL block\n");
4754 ctrl->pending_block_len = block_len;
4755 ctrl->pending_block = ctrl->vdll_mem + offset;
4756 }
4757 } else {
4758 PRINTM(MERROR,
4759 "Invalid VDLL req: offset=0x%x, len=%d, vdll_len=%d\n",
4760 offset, block_len, ctrl->vdll_len);
4761 }
4762 break;
4763
4764 case VDLL_IND_TYPE_OFFSET:
4765 offset = wlan_le32_to_cpu(ind->offset);
4766 PRINTM(MEVENT, "VDLL_IND (OFFSET): offset=0x%x\n", offset);
4767 wlan_get_vdll_image(pmadapter, offset);
4768 break;
4769 case VDLL_IND_TYPE_ERR_SIG:
4770 PRINTM(MERROR, "VDLL_IND (SIG ERR).\n");
4771 break;
4772 case VDLL_IND_TYPE_ERR_ID:
4773 PRINTM(MERROR, "VDLL_IND (ID ERR).\n");
4774 break;
4775 default:
4776 PRINTM(MERROR, "unknow vdll ind type=%d\n", ind->type);
4777 break;
4778 }
4779 LEAVE();
4780 return status;
4781 }
4782
4783 /**
4784 * @brief This function handle the csi event
4785 *
4786 * @param pmpriv A pointer to mlan_private structure
4787 *
4788 * @return MLAN_STATUS_SUCCESS
4789 */
wlan_process_csi_event(pmlan_private pmpriv)4790 mlan_status wlan_process_csi_event(pmlan_private pmpriv)
4791 {
4792 pmlan_adapter pmadapter = pmpriv->adapter;
4793 mlan_status status;
4794 t_u32 eventcause = pmadapter->event_cause;
4795 t_u8 *evt_buf = MNULL;
4796 pmlan_buffer pmbuf = pmadapter->pmlan_buffer_event;
4797 pmlan_callbacks pcb = &pmadapter->callbacks;
4798 pmlan_event pevent;
4799
4800 ENTER();
4801
4802 /* Allocate memory for event buffer */
4803 status = pcb->moal_malloc(pmadapter->pmoal_handle, MAX_EVENT_SIZE,
4804 MLAN_MEM_DEF, &evt_buf);
4805 if ((status == MLAN_STATUS_SUCCESS) && evt_buf) {
4806 t_u16 csi_sig;
4807 pcsi_record_ds csi_record = (pcsi_record_ds)(
4808 pmbuf->pbuf + pmbuf->data_offset + sizeof(eventcause));
4809 /* Check CSI signature */
4810 csi_sig = csi_record->CSI_Sign;
4811 if (csi_sig != CSI_SIGNATURE) {
4812 PRINTM(MERROR,
4813 "Wrong CSI signature 0x%04x. Should be 0x%04x",
4814 csi_sig, CSI_SIGNATURE);
4815 status = MLAN_STATUS_FAILURE;
4816 } else {
4817 /* Send event to moal */
4818 pevent = (pmlan_event)evt_buf;
4819 pevent->bss_index = pmpriv->bss_index;
4820 pevent->event_id = MLAN_EVENT_ID_CSI;
4821 /* Event length is the CSI record length in byte */
4822 pevent->event_len = csi_record->Len * 4;
4823 if (pevent->event_len >
4824 pmbuf->data_len - sizeof(eventcause))
4825 pevent->event_len =
4826 pmbuf->data_len - sizeof(eventcause);
4827 memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
4828 csi_record, pevent->event_len,
4829 pevent->event_len);
4830 wlan_recv_event(pmpriv, pevent->event_id, pevent);
4831 }
4832 pcb->moal_mfree(pmadapter->pmoal_handle, evt_buf);
4833 }
4834
4835 LEAVE();
4836 return status;
4837 }
4838
4839 /**
4840 * @brief This function prepares command of get_hw_spec.
4841 *
4842 * @param pmpriv A pointer to mlan_private structure
4843 * @param pcmd A pointer to HostCmd_DS_COMMAND structure
4844 *
4845 * @return MLAN_STATUS_SUCCESS
4846 */
wlan_cmd_get_hw_spec(pmlan_private pmpriv,HostCmd_DS_COMMAND * pcmd)4847 mlan_status wlan_cmd_get_hw_spec(pmlan_private pmpriv, HostCmd_DS_COMMAND *pcmd)
4848 {
4849 HostCmd_DS_GET_HW_SPEC *hw_spec = &pcmd->params.hw_spec;
4850
4851 ENTER();
4852
4853 pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_GET_HW_SPEC);
4854 pcmd->size =
4855 wlan_cpu_to_le16(sizeof(HostCmd_DS_GET_HW_SPEC) + S_DS_GEN);
4856 memcpy_ext(pmpriv->adapter, hw_spec->permanent_addr, pmpriv->curr_addr,
4857 MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
4858
4859 LEAVE();
4860 return MLAN_STATUS_SUCCESS;
4861 }
4862
4863 #ifdef SDIO
4864 /**
4865 * @brief This function prepares command of sdio rx aggr command.
4866 *
4867 * @param pcmd A pointer to HostCmd_DS_COMMAND structure
4868 * @param cmd_action Command action: GET or SET
4869 * @param pdata_buf A pointer to new setting buf
4870
4871 * @return MLAN_STATUS_SUCCESS
4872 */
wlan_cmd_sdio_rx_aggr_cfg(HostCmd_DS_COMMAND * pcmd,t_u16 cmd_action,t_void * pdata_buf)4873 mlan_status wlan_cmd_sdio_rx_aggr_cfg(HostCmd_DS_COMMAND *pcmd,
4874 t_u16 cmd_action, t_void *pdata_buf)
4875 {
4876 HostCmd_DS_SDIO_SP_RX_AGGR_CFG *cfg = &pcmd->params.sdio_rx_aggr;
4877
4878 pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_SDIO_SP_RX_AGGR_CFG);
4879 pcmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_SDIO_SP_RX_AGGR_CFG) +
4880 S_DS_GEN);
4881 cfg->action = cmd_action;
4882 if (cmd_action == HostCmd_ACT_GEN_SET)
4883 cfg->enable = *(t_u8 *)pdata_buf;
4884 return MLAN_STATUS_SUCCESS;
4885 }
4886
4887 /**
4888 * @brief This function handles the command response of sdio rx aggr command
4889 *
4890 * @param pmpriv A pointer to mlan_private structure
4891 * @param resp A pointer to HostCmd_DS_COMMAND
4892 *
4893 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
4894 */
wlan_ret_sdio_rx_aggr_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp)4895 mlan_status wlan_ret_sdio_rx_aggr_cfg(pmlan_private pmpriv,
4896 HostCmd_DS_COMMAND *resp)
4897 {
4898 mlan_adapter *pmadapter = pmpriv->adapter;
4899 HostCmd_DS_SDIO_SP_RX_AGGR_CFG *cfg = &resp->params.sdio_rx_aggr;
4900
4901 pmadapter->pcard_sd->sdio_rx_aggr_enable = cfg->enable;
4902 pmadapter->pcard_sd->sdio_rx_block_size =
4903 wlan_le16_to_cpu(cfg->sdio_block_size);
4904 PRINTM(MMSG, "SDIO rx aggr: %d block_size=%d\n", cfg->enable,
4905 pmadapter->pcard_sd->sdio_rx_block_size);
4906 if (!pmadapter->pcard_sd->sdio_rx_block_size)
4907 pmadapter->pcard_sd->sdio_rx_aggr_enable = MFALSE;
4908 if (pmadapter->pcard_sd->sdio_rx_aggr_enable) {
4909 pmadapter->pcard_sd->max_sp_rx_size = SDIO_CMD53_MAX_SIZE;
4910 wlan_re_alloc_sdio_rx_mpa_buffer(pmadapter);
4911 }
4912 return MLAN_STATUS_SUCCESS;
4913 }
4914 #endif
4915
4916 /**
4917 * @brief This function prepares command of set_cfg_data.
4918 *
4919 * @param pmpriv A pointer to mlan_private strcture
4920 * @param pcmd A pointer to HostCmd_DS_COMMAND structure
4921 * @param cmd_action Command action: GET or SET
4922 * @param pdata_buf A pointer to cal_data buf
4923 *
4924 * @return MLAN_STATUS_SUCCESS
4925 */
wlan_cmd_cfg_data(pmlan_private pmpriv,HostCmd_DS_COMMAND * pcmd,t_u16 cmd_action,t_u32 cmd_oid,t_void * pdata_buf)4926 mlan_status wlan_cmd_cfg_data(pmlan_private pmpriv, HostCmd_DS_COMMAND *pcmd,
4927 t_u16 cmd_action, t_u32 cmd_oid,
4928 t_void *pdata_buf)
4929 {
4930 mlan_status ret = MLAN_STATUS_SUCCESS;
4931 HostCmd_DS_802_11_CFG_DATA *pcfg_data = &(pcmd->params.cfg_data);
4932 pmlan_adapter pmadapter = pmpriv->adapter;
4933 t_u32 len = 0;
4934 t_u32 data_offset;
4935 t_u8 *temp_pcmd = (t_u8 *)pcmd;
4936
4937 ENTER();
4938
4939 data_offset = S_DS_GEN + sizeof(HostCmd_DS_802_11_CFG_DATA);
4940
4941 if ((cmd_oid == OID_TYPE_CAL) && (pmadapter->pcal_data) &&
4942 (pmadapter->cal_data_len > 0)) {
4943 len = wlan_parse_cal_cfg((t_u8 *)pmadapter->pcal_data,
4944 pmadapter->cal_data_len,
4945 (t_u8 *)(temp_pcmd + data_offset));
4946 }
4947
4948 pcfg_data->action = cmd_action;
4949 pcfg_data->type = cmd_oid;
4950 pcfg_data->data_len = len;
4951
4952 pcmd->command = HostCmd_CMD_CFG_DATA;
4953 pcmd->size = pcfg_data->data_len + data_offset;
4954
4955 pcmd->command = wlan_cpu_to_le16(pcmd->command);
4956 pcmd->size = wlan_cpu_to_le16(pcmd->size);
4957
4958 pcfg_data->action = wlan_cpu_to_le16(pcfg_data->action);
4959 pcfg_data->type = wlan_cpu_to_le16(pcfg_data->type);
4960 pcfg_data->data_len = wlan_cpu_to_le16(pcfg_data->data_len);
4961
4962 LEAVE();
4963 return ret;
4964 }
4965
4966 /**
4967 * @brief This function handles the command response of set_cfg_data
4968 *
4969 * @param pmpriv A pointer to mlan_private structure
4970 * @param resp A pointer to HostCmd_DS_COMMAND
4971 * @param pioctl_buf A pointer to A pointer to mlan_ioctl_req
4972 *
4973 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
4974 */
wlan_ret_cfg_data(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * resp,IN t_void * pioctl_buf)4975 mlan_status wlan_ret_cfg_data(IN pmlan_private pmpriv,
4976 IN HostCmd_DS_COMMAND *resp,
4977 IN t_void *pioctl_buf)
4978 {
4979 mlan_status ret = MLAN_STATUS_SUCCESS;
4980 t_u8 event_buf[100];
4981 mlan_cmdresp_event *pevent = (mlan_cmdresp_event *)event_buf;
4982 mlan_adapter *pmadapter = pmpriv->adapter;
4983 HostCmd_DS_802_11_CFG_DATA *pcfg_data = &resp->params.cfg_data;
4984 t_u16 action;
4985 t_u16 type;
4986
4987 ENTER();
4988
4989 if (resp->result != HostCmd_RESULT_OK) {
4990 PRINTM(MERROR, "CFG data cmd resp failed\n");
4991 ret = MLAN_STATUS_FAILURE;
4992 }
4993
4994 if (!pmadapter->pdpd_data &&
4995 (pmadapter->dpd_data_len == UNKNOW_DPD_LENGTH) &&
4996 pmadapter->hw_status == WlanHardwareStatusGetHwSpec) {
4997 action = wlan_le16_to_cpu(pcfg_data->action);
4998 type = wlan_le16_to_cpu(pcfg_data->type);
4999 if (action == HostCmd_ACT_GEN_GET && (type == OID_TYPE_DPD)) {
5000 pcfg_data->action =
5001 wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
5002 pevent->bss_index = pmpriv->bss_index;
5003 pevent->event_id = MLAN_EVENT_ID_STORE_HOST_CMD_RESP;
5004 pevent->resp = (t_u8 *)resp;
5005 pevent->event_len = wlan_le16_to_cpu(resp->size);
5006 wlan_recv_event(pmpriv,
5007 MLAN_EVENT_ID_STORE_HOST_CMD_RESP,
5008 (mlan_event *)pevent);
5009 }
5010 }
5011
5012 LEAVE();
5013 return ret;
5014 }
5015
5016 /**
5017 * @brief This function prepares command of mac_control.
5018 *
5019 * @param pmpriv A pointer to mlan_private structure
5020 * @param pcmd A pointer to HostCmd_DS_COMMAND structure
5021 * @param cmd_action Command action
5022 * @param pdata_buf A pointer to command information buffer
5023 *
5024 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
5025 */
wlan_cmd_mac_control(pmlan_private pmpriv,HostCmd_DS_COMMAND * pcmd,t_u16 cmd_action,t_void * pdata_buf)5026 mlan_status wlan_cmd_mac_control(pmlan_private pmpriv, HostCmd_DS_COMMAND *pcmd,
5027 t_u16 cmd_action, t_void *pdata_buf)
5028 {
5029 HostCmd_DS_MAC_CONTROL *pmac = &pcmd->params.mac_ctrl;
5030 t_u32 action = *((t_u32 *)pdata_buf);
5031
5032 ENTER();
5033
5034 if (cmd_action != HostCmd_ACT_GEN_SET) {
5035 PRINTM(MERROR, "wlan_cmd_mac_control(): support SET only.\n");
5036 LEAVE();
5037 return MLAN_STATUS_FAILURE;
5038 }
5039
5040 pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_MAC_CONTROL);
5041 pcmd->size =
5042 wlan_cpu_to_le16(sizeof(HostCmd_DS_MAC_CONTROL) + S_DS_GEN);
5043 pmac->action = wlan_cpu_to_le32(action);
5044
5045 LEAVE();
5046 return MLAN_STATUS_SUCCESS;
5047 }
5048
5049 /**
5050 * @brief This function handles the command response of mac_control
5051 *
5052 * @param pmpriv A pointer to mlan_private structure
5053 * @param resp A pointer to HostCmd_DS_COMMAND
5054 * @param pioctl_buf A pointer to mlan_ioctl_req structure
5055 *
5056 * @return MLAN_STATUS_SUCCESS
5057 */
wlan_ret_mac_control(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)5058 mlan_status wlan_ret_mac_control(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
5059 mlan_ioctl_req *pioctl_buf)
5060 {
5061 ENTER();
5062 LEAVE();
5063 return MLAN_STATUS_SUCCESS;
5064 }
5065
5066 /**
5067 * @brief This function handles the command response of get_hw_spec
5068 *
5069 * @param pmpriv A pointer to mlan_private structure
5070 * @param resp A pointer to HostCmd_DS_COMMAND
5071 * @param pioctl_buf A pointer to command buffer
5072 *
5073 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
5074 */
wlan_ret_get_hw_spec(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,t_void * pioctl_buf)5075 mlan_status wlan_ret_get_hw_spec(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
5076 t_void *pioctl_buf)
5077 {
5078 HostCmd_DS_GET_HW_SPEC *hw_spec = &resp->params.hw_spec;
5079 mlan_adapter *pmadapter = pmpriv->adapter;
5080 mlan_status ret = MLAN_STATUS_SUCCESS;
5081 t_u32 i;
5082 t_u16 left_len;
5083 t_u16 tlv_type = 0;
5084 t_u16 tlv_len = 0;
5085 MrvlIEtypes_fw_ver_info_t *api_rev = MNULL;
5086 t_u16 api_id = 0;
5087 MrvlIEtypesHeader_t *tlv = MNULL;
5088 pmlan_ioctl_req pioctl_req = (mlan_ioctl_req *)pioctl_buf;
5089 MrvlIEtypes_Max_Conn_t *tlv_max_conn = MNULL;
5090 MrvlIEtypes_Extension_t *ext_tlv = MNULL;
5091 MrvlIEtypes_fw_cap_info_t *fw_cap_tlv = MNULL;
5092
5093 MrvlIEtypes_Secure_Boot_Uuid_t *sb_uuid_tlv = MNULL;
5094
5095 ENTER();
5096
5097 pmadapter->fw_cap_info = wlan_le32_to_cpu(hw_spec->fw_cap_info);
5098 pmadapter->fw_cap_info &= pmadapter->init_para.dev_cap_mask;
5099
5100 PRINTM(MMSG, "fw_cap_info=0x%x, dev_cap_mask=0x%x\n",
5101 wlan_le32_to_cpu(hw_spec->fw_cap_info),
5102 pmadapter->init_para.dev_cap_mask);
5103 #ifdef STA_SUPPORT
5104 if (IS_SUPPORT_MULTI_BANDS(pmadapter))
5105 pmadapter->fw_bands = (t_u8)GET_FW_DEFAULT_BANDS(pmadapter);
5106 else
5107 pmadapter->fw_bands = BAND_B;
5108
5109 if ((pmadapter->fw_bands & BAND_A) && (pmadapter->fw_bands & BAND_GN))
5110 pmadapter->fw_bands |= BAND_AN;
5111 if (!(pmadapter->fw_bands & BAND_G) && (pmadapter->fw_bands & BAND_GN))
5112 pmadapter->fw_bands &= ~BAND_GN;
5113
5114 pmadapter->config_bands = pmadapter->fw_bands;
5115 for (i = 0; i < pmadapter->priv_num; i++) {
5116 if (pmadapter->priv[i])
5117 pmadapter->priv[i]->config_bands = pmadapter->fw_bands;
5118 }
5119
5120 if (pmadapter->fw_bands & BAND_A) {
5121 if (pmadapter->fw_bands & BAND_AN) {
5122 pmadapter->config_bands |= BAND_AN;
5123 for (i = 0; i < pmadapter->priv_num; i++) {
5124 if (pmadapter->priv[i])
5125 pmadapter->priv[i]->config_bands |=
5126 BAND_AN;
5127 }
5128 }
5129 if (pmadapter->fw_bands & BAND_AAC) {
5130 pmadapter->config_bands |= BAND_AAC;
5131 for (i = 0; i < pmadapter->priv_num; i++) {
5132 if (pmadapter->priv[i])
5133 pmadapter->priv[i]->config_bands |=
5134 BAND_AAC;
5135 }
5136 }
5137 if (pmadapter->fw_bands & BAND_GAC) {
5138 pmadapter->config_bands |= BAND_GAC;
5139 for (i = 0; i < pmadapter->priv_num; i++) {
5140 if (pmadapter->priv[i])
5141 pmadapter->priv[i]->config_bands |=
5142 BAND_GAC;
5143 }
5144 }
5145 pmadapter->adhoc_start_band = BAND_A;
5146 pmpriv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL_A;
5147 } else if (pmadapter->fw_bands & BAND_G) {
5148 pmadapter->adhoc_start_band = BAND_G | BAND_B;
5149 pmpriv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
5150 } else if (pmadapter->fw_bands & BAND_B) {
5151 pmadapter->adhoc_start_band = BAND_B;
5152 pmpriv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
5153 }
5154 #endif /* STA_SUPPORT */
5155
5156 pmadapter->fw_release_number =
5157 wlan_le32_to_cpu(hw_spec->fw_release_number);
5158 pmadapter->number_of_antenna =
5159 wlan_le16_to_cpu(hw_spec->number_of_antenna) & 0x00ff;
5160 pmadapter->antinfo =
5161 (wlan_le16_to_cpu(hw_spec->number_of_antenna) & 0xff00) >> 8;
5162 PRINTM(MCMND, "num_ant=%d, antinfo=0x%x\n",
5163 pmadapter->number_of_antenna, pmadapter->antinfo);
5164
5165 PRINTM(MINFO, "GET_HW_SPEC: fw_release_number- 0x%X\n",
5166 pmadapter->fw_release_number);
5167 PRINTM(MINFO, "GET_HW_SPEC: Permanent addr- " MACSTR "\n",
5168 MAC2STR(hw_spec->permanent_addr));
5169 PRINTM(MINFO, "GET_HW_SPEC: hw_if_version=0x%X version=0x%X\n",
5170 wlan_le16_to_cpu(hw_spec->hw_if_version),
5171 wlan_le16_to_cpu(hw_spec->version));
5172
5173 if (pmpriv->curr_addr[0] == 0xff)
5174 memmove(pmadapter, pmpriv->curr_addr, hw_spec->permanent_addr,
5175 MLAN_MAC_ADDR_LENGTH);
5176 memmove(pmadapter, pmadapter->permanent_addr, hw_spec->permanent_addr,
5177 MLAN_MAC_ADDR_LENGTH);
5178 pmadapter->hw_dot_11n_dev_cap =
5179 wlan_le32_to_cpu(hw_spec->dot_11n_dev_cap);
5180 pmadapter->hw_dev_mcs_support = hw_spec->dev_mcs_support;
5181 for (i = 0; i < pmadapter->priv_num; i++) {
5182 if (pmadapter->priv[i])
5183 wlan_update_11n_cap(pmadapter->priv[i]);
5184 }
5185
5186 wlan_show_dot11ndevcap(pmadapter, pmadapter->hw_dot_11n_dev_cap);
5187 wlan_show_devmcssupport(pmadapter, pmadapter->hw_dev_mcs_support);
5188 #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \
5189 defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \
5190 defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X)
5191 pmadapter->user_htstream = pmadapter->hw_dev_mcs_support;
5192 /** separate stream config for 2.4G and 5G, will be changed according to
5193 * antenna cfg*/
5194 if (pmadapter->fw_bands & BAND_A)
5195 pmadapter->user_htstream |= (pmadapter->user_htstream << 8);
5196 PRINTM(MCMND, "user_htstream=0x%x\n", pmadapter->user_htstream);
5197 #endif
5198
5199 if (ISSUPP_BEAMFORMING(pmadapter->hw_dot_11n_dev_cap)) {
5200 PRINTM(MCMND, "Enable Beamforming\n");
5201 for (i = 0; i < pmadapter->priv_num; i++) {
5202 if (pmadapter->priv[i])
5203 pmadapter->priv[i]->tx_bf_cap =
5204 pmadapter->pcard_info
5205 ->default_11n_tx_bf_cap;
5206 }
5207 }
5208 pmadapter->hw_dot_11ac_dev_cap =
5209 wlan_le32_to_cpu(hw_spec->Dot11acDevCap);
5210 pmadapter->hw_dot_11ac_mcs_support =
5211 wlan_le32_to_cpu(hw_spec->Dot11acMcsSupport);
5212 for (i = 0; i < pmadapter->priv_num; i++) {
5213 if (pmadapter->priv[i])
5214 wlan_update_11ac_cap(pmadapter->priv[i]);
5215 }
5216 wlan_show_dot11acdevcap(pmadapter, pmadapter->hw_dot_11ac_dev_cap);
5217 wlan_show_dot11acmcssupport(pmadapter,
5218 pmadapter->hw_dot_11ac_mcs_support);
5219
5220 #ifdef SDIO
5221 if (IS_SD(pmadapter->card_type)) {
5222 pmadapter->pcard_sd->mp_end_port =
5223 wlan_le16_to_cpu(hw_spec->mp_end_port);
5224
5225 for (i = 1; i <= (unsigned)(pmadapter->pcard_sd->max_ports -
5226 pmadapter->pcard_sd->mp_end_port);
5227 i++)
5228 pmadapter->pcard_sd->mp_data_port_mask &=
5229 ~(1 << (pmadapter->pcard_sd->max_ports - i));
5230 }
5231 #endif
5232
5233 pmadapter->max_mgmt_ie_index =
5234 wlan_le16_to_cpu(hw_spec->mgmt_buf_count);
5235 PRINTM(MCMND, "GET_HW_SPEC: mgmt IE count=%d\n",
5236 pmadapter->max_mgmt_ie_index);
5237 if (!pmadapter->max_mgmt_ie_index ||
5238 pmadapter->max_mgmt_ie_index > MAX_MGMT_IE_INDEX)
5239 pmadapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX;
5240
5241 pmadapter->region_code = wlan_le16_to_cpu(hw_spec->region_code);
5242 for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
5243 /* Use the region code to search for the index */
5244 if (pmadapter->region_code == region_code_index[i])
5245 break;
5246 }
5247 /* If it's unidentified region code, use the default */
5248 if (i >= MRVDRV_MAX_REGION_CODE) {
5249 pmadapter->region_code = MRVDRV_DEFAULT_REGION_CODE;
5250 PRINTM(MWARN,
5251 "unidentified region code, use the default (0x%02x)\n",
5252 MRVDRV_DEFAULT_REGION_CODE);
5253 }
5254 /* Synchronize CFP code with region code */
5255 pmadapter->cfp_code_bg = pmadapter->region_code;
5256 pmadapter->cfp_code_a = pmadapter->region_code;
5257
5258 if (pmadapter->fw_cap_info & ENHANCE_EXT_SCAN_ENABLE)
5259 pmadapter->ext_scan_enh = MTRUE;
5260
5261 #ifdef SDIO
5262 if (IS_SD(pmadapter->card_type)) {
5263 if ((pmadapter->fw_cap_info & SDIO_SP_RX_AGGR_ENABLE) &&
5264 pmadapter->pcard_sd->sdio_rx_aggr_enable) {
5265 t_u8 sdio_sp_rx_aggr = MTRUE;
5266 ret = wlan_prepare_cmd(pmpriv,
5267 HostCmd_CMD_SDIO_SP_RX_AGGR_CFG,
5268 HostCmd_ACT_GEN_SET, 0, MNULL,
5269 &sdio_sp_rx_aggr);
5270 if (ret) {
5271 ret = MLAN_STATUS_FAILURE;
5272 goto done;
5273 }
5274 } else {
5275 pmadapter->pcard_sd->sdio_rx_aggr_enable = MFALSE;
5276 PRINTM(MCMND, "FW: SDIO rx aggr disabled 0x%x\n",
5277 pmadapter->fw_cap_info);
5278 }
5279 }
5280 #endif
5281
5282 if (wlan_set_regiontable(pmpriv, (t_u8)pmadapter->region_code,
5283 pmadapter->fw_bands)) {
5284 if (pioctl_req)
5285 pioctl_req->status_code = MLAN_ERROR_CMD_SCAN_FAIL;
5286 ret = MLAN_STATUS_FAILURE;
5287 goto done;
5288 }
5289 #ifdef STA_SUPPORT
5290 if (wlan_11d_set_universaltable(pmpriv, pmadapter->fw_bands)) {
5291 if (pioctl_req)
5292 pioctl_req->status_code = MLAN_ERROR_CMD_SCAN_FAIL;
5293 ret = MLAN_STATUS_FAILURE;
5294 goto done;
5295 }
5296 #endif /* STA_SUPPORT */
5297 if (pmadapter->fw_cap_info & FW_CAPINFO_ECSA) {
5298 t_u8 ecsa_enable = MTRUE;
5299 pmadapter->ecsa_enable = MTRUE;
5300 PRINTM(MCMND, "pmadapter->ecsa_enable=%d\n",
5301 pmadapter->ecsa_enable);
5302 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_SNMP_MIB,
5303 HostCmd_ACT_GEN_SET, ECSAEnable_i, MNULL,
5304 &ecsa_enable);
5305 if (ret) {
5306 ret = MLAN_STATUS_FAILURE;
5307 goto done;
5308 }
5309 }
5310 if (pmadapter->fw_cap_info & FW_CAPINFO_GET_LOG) {
5311 pmadapter->getlog_enable = MTRUE;
5312 PRINTM(MCMND, "pmadapter->getlog_enable=%d\n",
5313 pmadapter->getlog_enable);
5314 }
5315
5316 left_len = resp->size - sizeof(HostCmd_DS_GET_HW_SPEC) - S_DS_GEN;
5317 tlv = (MrvlIEtypesHeader_t *)((t_u8 *)hw_spec +
5318 sizeof(HostCmd_DS_GET_HW_SPEC));
5319 while (left_len > sizeof(MrvlIEtypesHeader_t)) {
5320 tlv_type = wlan_le16_to_cpu(tlv->type);
5321 tlv_len = wlan_le16_to_cpu(tlv->len);
5322 switch (tlv_type) {
5323 case TLV_TYPE_FW_VER_INFO:
5324 api_rev = (MrvlIEtypes_fw_ver_info_t *)tlv;
5325 api_id = wlan_le16_to_cpu(api_rev->api_id);
5326 switch (api_id) {
5327 case FW_API_VER_ID:
5328 pmadapter->fw_ver = api_rev->major_ver;
5329 pmadapter->fw_min_ver = api_rev->minor_ver;
5330 PRINTM(MCMND, "fw ver=%d.%d\n",
5331 api_rev->major_ver, api_rev->minor_ver);
5332 break;
5333 case UAP_FW_API_VER_ID:
5334 pmadapter->uap_fw_ver = api_rev->major_ver;
5335 PRINTM(MCMND, "uap fw ver=%d.%d\n",
5336 api_rev->major_ver, api_rev->minor_ver);
5337 break;
5338 case CHANRPT_API_VER_ID:
5339 pmadapter->chanrpt_param_bandcfg =
5340 api_rev->minor_ver;
5341 PRINTM(MCMND, "chanrpt api ver=%d.%d\n",
5342 api_rev->major_ver, api_rev->minor_ver);
5343 break;
5344 case FW_HOTFIX_VER_ID:
5345 pmadapter->fw_hotfix_ver = api_rev->major_ver;
5346 PRINTM(MCMND, "fw hotfix ver=%d\n",
5347 api_rev->major_ver);
5348 break;
5349 default:
5350 break;
5351 }
5352 break;
5353 case TLV_TYPE_MAX_CONN:
5354 tlv_max_conn = (MrvlIEtypes_Max_Conn_t *)tlv;
5355 PRINTM(MMSG, "max_p2p_conn = %d, max_sta_conn = %d\n",
5356 tlv_max_conn->max_p2p_conn,
5357 tlv_max_conn->max_sta_conn);
5358 if (tlv_max_conn->max_p2p_conn &&
5359 tlv_max_conn->max_sta_conn)
5360 pmadapter->max_sta_conn =
5361 MIN(tlv_max_conn->max_sta_conn,
5362 tlv_max_conn->max_p2p_conn);
5363 else if (tlv_max_conn->max_sta_conn)
5364 pmadapter->max_sta_conn =
5365 tlv_max_conn->max_sta_conn;
5366 else if (tlv_max_conn->max_p2p_conn)
5367 pmadapter->max_sta_conn =
5368 tlv_max_conn->max_p2p_conn;
5369 else
5370 pmadapter->max_sta_conn = 0;
5371 break;
5372 case TLV_TYPE_EXTENSION_ID:
5373 ext_tlv = (MrvlIEtypes_Extension_t *)tlv;
5374 if (ext_tlv->ext_id == HE_CAPABILITY) {
5375 ext_tlv->type = tlv_type;
5376 ext_tlv->len = tlv_len;
5377 wlan_update_11ax_cap(
5378 pmadapter,
5379 (MrvlIEtypes_Extension_t *)ext_tlv);
5380 }
5381 break;
5382 case TLV_TYPE_FW_CAP_INFO:
5383 fw_cap_tlv = (MrvlIEtypes_fw_cap_info_t *)tlv;
5384 pmadapter->fw_cap_info =
5385 wlan_le32_to_cpu(fw_cap_tlv->fw_cap_info);
5386 pmadapter->fw_cap_ext =
5387 wlan_le32_to_cpu(fw_cap_tlv->fw_cap_ext);
5388 PRINTM(MCMND, "fw_cap_info=0x%x fw_cap_ext=0x%x\n",
5389 pmadapter->fw_cap_info, pmadapter->fw_cap_ext);
5390 break;
5391 case TLV_TYPE_SECURE_BOOT_UUID:
5392 sb_uuid_tlv = (MrvlIEtypes_Secure_Boot_Uuid_t *)tlv;
5393 pmadapter->uuid_lo = sb_uuid_tlv->uuid_lo;
5394 pmadapter->uuid_hi = sb_uuid_tlv->uuid_hi;
5395 PRINTM(MMSG, "uuid: %016llx%016llx\n",
5396 pmadapter->uuid_lo, pmadapter->uuid_hi);
5397 break;
5398 default:
5399 break;
5400 }
5401 left_len -= (sizeof(MrvlIEtypesHeader_t) + tlv_len);
5402 tlv = (MrvlIEtypesHeader_t *)((t_u8 *)tlv + tlv_len +
5403 sizeof(MrvlIEtypesHeader_t));
5404 }
5405 done:
5406 LEAVE();
5407 return ret;
5408 }
5409
5410 /**
5411 * @brief This function prepares command of radio_control.
5412 *
5413 * @param pmpriv A pointer to mlan_private structure
5414 * @param cmd A pointer to HostCmd_DS_COMMAND structure
5415 * @param cmd_action The action: GET or SET
5416 * @param pdata_buf A pointer to data buffer
5417 *
5418 * @return MLAN_STATUS_SUCCESS
5419 */
wlan_cmd_802_11_radio_control(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)5420 mlan_status wlan_cmd_802_11_radio_control(pmlan_private pmpriv,
5421 HostCmd_DS_COMMAND *cmd,
5422 t_u16 cmd_action, t_void *pdata_buf)
5423 {
5424 HostCmd_DS_802_11_RADIO_CONTROL *pradio_control = &cmd->params.radio;
5425 t_u32 radio_ctl;
5426 ENTER();
5427 cmd->size = wlan_cpu_to_le16((sizeof(HostCmd_DS_802_11_RADIO_CONTROL)) +
5428 S_DS_GEN);
5429 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_RADIO_CONTROL);
5430 pradio_control->action = wlan_cpu_to_le16(cmd_action);
5431 memcpy_ext(pmpriv->adapter, &radio_ctl, pdata_buf, sizeof(t_u32),
5432 sizeof(radio_ctl));
5433 pradio_control->control = wlan_cpu_to_le16((t_u16)radio_ctl);
5434 LEAVE();
5435 return MLAN_STATUS_SUCCESS;
5436 }
5437
5438 /**
5439 * @brief This function handles the command response of radio_control
5440 *
5441 * @param pmpriv A pointer to mlan_private structure
5442 * @param resp A pointer to HostCmd_DS_COMMAND
5443 * @param pioctl_buf A pointer to mlan_ioctl_req structure
5444 *
5445 * @return MLAN_STATUS_SUCCESS
5446 */
wlan_ret_802_11_radio_control(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)5447 mlan_status wlan_ret_802_11_radio_control(pmlan_private pmpriv,
5448 HostCmd_DS_COMMAND *resp,
5449 mlan_ioctl_req *pioctl_buf)
5450 {
5451 HostCmd_DS_802_11_RADIO_CONTROL *pradio_ctrl =
5452 (HostCmd_DS_802_11_RADIO_CONTROL *)&resp->params.radio;
5453 mlan_ds_radio_cfg *radio_cfg = MNULL;
5454 mlan_adapter *pmadapter = pmpriv->adapter;
5455
5456 ENTER();
5457 pmadapter->radio_on = wlan_le16_to_cpu(pradio_ctrl->control);
5458 if (pioctl_buf) {
5459 radio_cfg = (mlan_ds_radio_cfg *)pioctl_buf->pbuf;
5460 radio_cfg->param.radio_on_off = (t_u32)pmadapter->radio_on;
5461 pioctl_buf->data_read_written = sizeof(mlan_ds_radio_cfg);
5462 }
5463 LEAVE();
5464 return MLAN_STATUS_SUCCESS;
5465 }
5466
5467 /**
5468 * @brief This function prepares command of remain_on_channel.
5469 *
5470 * @param pmpriv A pointer to mlan_private structure
5471 * @param cmd A pointer to HostCmd_DS_COMMAND structure
5472 * @param cmd_action The action: GET or SET
5473 * @param pdata_buf A pointer to data buffer
5474 *
5475 * @return MLAN_STATUS_SUCCESS
5476 */
wlan_cmd_remain_on_channel(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)5477 mlan_status wlan_cmd_remain_on_channel(pmlan_private pmpriv,
5478 HostCmd_DS_COMMAND *cmd,
5479 t_u16 cmd_action, t_void *pdata_buf)
5480 {
5481 HostCmd_DS_REMAIN_ON_CHANNEL *remain_channel =
5482 &cmd->params.remain_on_chan;
5483 mlan_ds_remain_chan *cfg = (mlan_ds_remain_chan *)pdata_buf;
5484 ENTER();
5485 cmd->size = wlan_cpu_to_le16((sizeof(HostCmd_DS_REMAIN_ON_CHANNEL)) +
5486 S_DS_GEN);
5487 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_REMAIN_ON_CHANNEL);
5488 remain_channel->action = cmd_action;
5489 if (cmd_action == HostCmd_ACT_GEN_SET) {
5490 if (cfg->remove) {
5491 remain_channel->action = HostCmd_ACT_GEN_REMOVE;
5492 } else {
5493 remain_channel->bandcfg = cfg->bandcfg;
5494 remain_channel->channel = cfg->channel;
5495 remain_channel->remain_period =
5496 wlan_cpu_to_le32(cfg->remain_period);
5497 }
5498 }
5499 remain_channel->action = wlan_cpu_to_le16(remain_channel->action);
5500
5501 LEAVE();
5502 return MLAN_STATUS_SUCCESS;
5503 }
5504
5505 /**
5506 * @brief This function handles the command response of remain_on_channel
5507 *
5508 * @param pmpriv A pointer to mlan_private structure
5509 * @param resp A pointer to HostCmd_DS_COMMAND
5510 * @param pioctl_buf A pointer to mlan_ioctl_req structure
5511 *
5512 * @return MLAN_STATUS_SUCCESS
5513 */
wlan_ret_remain_on_channel(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)5514 mlan_status wlan_ret_remain_on_channel(pmlan_private pmpriv,
5515 HostCmd_DS_COMMAND *resp,
5516 mlan_ioctl_req *pioctl_buf)
5517 {
5518 HostCmd_DS_REMAIN_ON_CHANNEL *remain_channel =
5519 &resp->params.remain_on_chan;
5520 mlan_ds_radio_cfg *radio_cfg = MNULL;
5521
5522 ENTER();
5523 if (pioctl_buf) {
5524 radio_cfg = (mlan_ds_radio_cfg *)pioctl_buf->pbuf;
5525 radio_cfg->param.remain_chan.status = remain_channel->status;
5526 radio_cfg->param.remain_chan.bandcfg = remain_channel->bandcfg;
5527 radio_cfg->param.remain_chan.channel = remain_channel->channel;
5528 radio_cfg->param.remain_chan.remain_period =
5529 wlan_le32_to_cpu(remain_channel->remain_period);
5530 pioctl_buf->data_read_written = sizeof(mlan_ds_radio_cfg);
5531 }
5532 LEAVE();
5533 return MLAN_STATUS_SUCCESS;
5534 }
5535
5536 #ifdef WIFI_DIRECT_SUPPORT
5537 /**
5538 * @brief This function prepares command of wifi direct mode.
5539 *
5540 * @param pmpriv A pointer to mlan_private structure
5541 * @param cmd A pointer to HostCmd_DS_COMMAND structure
5542 * @param cmd_action The action: GET or SET
5543 * @param pdata_buf A pointer to data buffer
5544 *
5545 * @return MLAN_STATUS_SUCCESS
5546 */
wlan_cmd_wifi_direct_mode(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)5547 mlan_status wlan_cmd_wifi_direct_mode(pmlan_private pmpriv,
5548 HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
5549 t_void *pdata_buf)
5550 {
5551 HostCmd_DS_WIFI_DIRECT_MODE *wfd_mode = &cmd->params.wifi_direct_mode;
5552 t_u16 mode = *((t_u16 *)pdata_buf);
5553 ENTER();
5554 cmd->size = wlan_cpu_to_le16((sizeof(HostCmd_DS_WIFI_DIRECT_MODE)) +
5555 S_DS_GEN);
5556 cmd->command = wlan_cpu_to_le16(HOST_CMD_WIFI_DIRECT_MODE_CONFIG);
5557 wfd_mode->action = wlan_cpu_to_le16(cmd_action);
5558 if (cmd_action == HostCmd_ACT_GEN_SET)
5559 wfd_mode->mode = wlan_cpu_to_le16(mode);
5560
5561 LEAVE();
5562 return MLAN_STATUS_SUCCESS;
5563 }
5564
5565 /**
5566 * @brief This function handles the command response of wifi direct mode
5567 *
5568 * @param pmpriv A pointer to mlan_private structure
5569 * @param resp A pointer to HostCmd_DS_COMMAND
5570 * @param pioctl_buf A pointer to mlan_ioctl_req structure
5571 *
5572 * @return MLAN_STATUS_SUCCESS
5573 */
wlan_ret_wifi_direct_mode(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)5574 mlan_status wlan_ret_wifi_direct_mode(pmlan_private pmpriv,
5575 HostCmd_DS_COMMAND *resp,
5576 mlan_ioctl_req *pioctl_buf)
5577 {
5578 HostCmd_DS_WIFI_DIRECT_MODE *wfd_mode = &resp->params.wifi_direct_mode;
5579 mlan_ds_bss *bss = MNULL;
5580
5581 ENTER();
5582 if (pioctl_buf) {
5583 bss = (mlan_ds_bss *)pioctl_buf->pbuf;
5584 bss->param.wfd_mode = wlan_le16_to_cpu(wfd_mode->mode);
5585 pioctl_buf->data_read_written = sizeof(mlan_ds_bss);
5586 }
5587 LEAVE();
5588 return MLAN_STATUS_SUCCESS;
5589 }
5590
5591 /**
5592 * @brief This function prepares command of p2p_params_config.
5593 *
5594 * @param pmpriv A pointer to mlan_private structure
5595 * @param cmd A pointer to HostCmd_DS_COMMAND structure
5596 * @param cmd_action The action: GET or SET
5597 * @param pdata_buf A pointer to data buffer
5598 *
5599 * @return MLAN_STATUS_SUCCESS
5600 */
wlan_cmd_p2p_params_config(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)5601 mlan_status wlan_cmd_p2p_params_config(pmlan_private pmpriv,
5602 HostCmd_DS_COMMAND *cmd,
5603 t_u16 cmd_action, t_void *pdata_buf)
5604 {
5605 HostCmd_DS_WIFI_DIRECT_PARAM_CONFIG *p2p_config =
5606 &cmd->params.p2p_params_config;
5607 mlan_ds_wifi_direct_config *cfg =
5608 (mlan_ds_wifi_direct_config *)pdata_buf;
5609 MrvlIEtypes_NoA_setting_t *pnoa_tlv = MNULL;
5610 MrvlIEtypes_OPP_PS_setting_t *popp_ps_tlv = MNULL;
5611 t_u8 *tlv = MNULL;
5612 ENTER();
5613
5614 cmd->size = sizeof(HostCmd_DS_WIFI_DIRECT_PARAM_CONFIG) + S_DS_GEN;
5615 cmd->command = wlan_cpu_to_le16(HOST_CMD_P2P_PARAMS_CONFIG);
5616 p2p_config->action = wlan_cpu_to_le16(cmd_action);
5617 if (cmd_action == HostCmd_ACT_GEN_SET) {
5618 tlv = (t_u8 *)p2p_config->tlv_buf;
5619 if (cfg->flags & WIFI_DIRECT_NOA) {
5620 pnoa_tlv = (MrvlIEtypes_NoA_setting_t *)tlv;
5621 pnoa_tlv->header.type =
5622 wlan_cpu_to_le16(TLV_TYPE_WIFI_DIRECT_NOA);
5623 pnoa_tlv->header.len = wlan_cpu_to_le16(
5624 sizeof(MrvlIEtypes_NoA_setting_t) -
5625 sizeof(MrvlIEtypesHeader_t));
5626 pnoa_tlv->enable = cfg->noa_enable;
5627 pnoa_tlv->index = wlan_cpu_to_le16(cfg->index);
5628 pnoa_tlv->noa_count = cfg->noa_count;
5629 pnoa_tlv->noa_duration =
5630 wlan_cpu_to_le32(cfg->noa_duration);
5631 pnoa_tlv->noa_interval =
5632 wlan_cpu_to_le32(cfg->noa_interval);
5633 cmd->size += sizeof(MrvlIEtypes_NoA_setting_t);
5634 tlv += sizeof(MrvlIEtypes_NoA_setting_t);
5635 PRINTM(MCMND,
5636 "Set NOA: enable=%d index=%d, count=%d, duration=%d interval=%d\n",
5637 cfg->noa_enable, cfg->index, cfg->noa_count,
5638 (int)cfg->noa_duration, (int)cfg->noa_interval);
5639 }
5640 if (cfg->flags & WIFI_DIRECT_OPP_PS) {
5641 popp_ps_tlv = (MrvlIEtypes_OPP_PS_setting_t *)tlv;
5642 popp_ps_tlv->header.type =
5643 wlan_cpu_to_le16(TLV_TYPE_WIFI_DIRECT_OPP_PS);
5644 popp_ps_tlv->header.len = wlan_cpu_to_le16(
5645 sizeof(MrvlIEtypes_OPP_PS_setting_t) -
5646 sizeof(MrvlIEtypesHeader_t));
5647
5648 popp_ps_tlv->enable = cfg->ct_window;
5649 popp_ps_tlv->enable |= cfg->opp_ps_enable << 7;
5650 cmd->size += sizeof(MrvlIEtypes_OPP_PS_setting_t);
5651 PRINTM(MCMND, "Set OPP_PS: enable=%d ct_win=%d\n",
5652 cfg->opp_ps_enable, cfg->ct_window);
5653 }
5654 } else if (cmd_action == HostCmd_ACT_GEN_GET) {
5655 tlv = (t_u8 *)p2p_config->tlv_buf;
5656 if (cfg->flags & WIFI_DIRECT_NOA) {
5657 pnoa_tlv = (MrvlIEtypes_NoA_setting_t *)tlv;
5658 pnoa_tlv->header.type =
5659 wlan_cpu_to_le16(TLV_TYPE_WIFI_DIRECT_NOA);
5660 pnoa_tlv->header.len = wlan_cpu_to_le16(
5661 sizeof(MrvlIEtypes_NoA_setting_t) -
5662 sizeof(MrvlIEtypesHeader_t));
5663 cmd->size += sizeof(MrvlIEtypes_NoA_setting_t);
5664 tlv += sizeof(MrvlIEtypes_NoA_setting_t);
5665 }
5666
5667 if (cfg->flags & WIFI_DIRECT_OPP_PS) {
5668 popp_ps_tlv = (MrvlIEtypes_OPP_PS_setting_t *)tlv;
5669 popp_ps_tlv->header.type =
5670 wlan_cpu_to_le16(TLV_TYPE_WIFI_DIRECT_OPP_PS);
5671 popp_ps_tlv->header.len = wlan_cpu_to_le16(
5672 sizeof(MrvlIEtypes_OPP_PS_setting_t) -
5673 sizeof(MrvlIEtypesHeader_t));
5674 cmd->size += sizeof(MrvlIEtypes_OPP_PS_setting_t);
5675 }
5676 }
5677 cmd->size = wlan_cpu_to_le16(cmd->size);
5678 LEAVE();
5679 return MLAN_STATUS_SUCCESS;
5680 }
5681
5682 /**
5683 * @brief This function handles the command response of p2p_params_config
5684 *
5685 * @param pmpriv A pointer to mlan_private structure
5686 * @param resp A pointer to HostCmd_DS_COMMAND
5687 * @param pioctl_buf A pointer to mlan_ioctl_req structure
5688 *
5689 * @return MLAN_STATUS_SUCCESS
5690 */
wlan_ret_p2p_params_config(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)5691 mlan_status wlan_ret_p2p_params_config(pmlan_private pmpriv,
5692 HostCmd_DS_COMMAND *resp,
5693 mlan_ioctl_req *pioctl_buf)
5694 {
5695 HostCmd_DS_WIFI_DIRECT_PARAM_CONFIG *p2p_config =
5696 &resp->params.p2p_params_config;
5697 mlan_ds_misc_cfg *cfg = MNULL;
5698 MrvlIEtypes_NoA_setting_t *pnoa_tlv = MNULL;
5699 MrvlIEtypes_OPP_PS_setting_t *popp_ps_tlv = MNULL;
5700 MrvlIEtypesHeader_t *tlv = MNULL;
5701 t_u16 tlv_buf_left = 0;
5702 t_u16 tlv_type = 0;
5703 t_u16 tlv_len = 0;
5704
5705 ENTER();
5706 if (wlan_le16_to_cpu(p2p_config->action) == HostCmd_ACT_GEN_GET) {
5707 if (pioctl_buf) {
5708 cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
5709 tlv = (MrvlIEtypesHeader_t *)(p2p_config->tlv_buf);
5710 tlv_buf_left =
5711 resp->size -
5712 (sizeof(HostCmd_DS_WIFI_DIRECT_PARAM_CONFIG) +
5713 S_DS_GEN);
5714 while (tlv_buf_left >= sizeof(MrvlIEtypesHeader_t)) {
5715 tlv_type = wlan_le16_to_cpu(tlv->type);
5716 tlv_len = wlan_le16_to_cpu(tlv->len);
5717 if (tlv_buf_left <
5718 (tlv_len + sizeof(MrvlIEtypesHeader_t))) {
5719 PRINTM(MERROR,
5720 "Error processing p2p param config TLVs, bytes left < TLV length\n");
5721 break;
5722 }
5723 switch (tlv_type) {
5724 case TLV_TYPE_WIFI_DIRECT_NOA:
5725 pnoa_tlv = (MrvlIEtypes_NoA_setting_t *)
5726 tlv;
5727 cfg->param.p2p_config.flags |=
5728 WIFI_DIRECT_NOA;
5729 cfg->param.p2p_config.noa_enable =
5730 pnoa_tlv->enable;
5731 cfg->param.p2p_config.index =
5732 wlan_le16_to_cpu(
5733 pnoa_tlv->index);
5734 cfg->param.p2p_config.noa_count =
5735 pnoa_tlv->noa_count;
5736 cfg->param.p2p_config.noa_duration =
5737 wlan_le32_to_cpu(
5738 pnoa_tlv->noa_duration);
5739 cfg->param.p2p_config.noa_interval =
5740 wlan_le32_to_cpu(
5741 pnoa_tlv->noa_interval);
5742 PRINTM(MCMND,
5743 "Get NOA: enable=%d index=%d, count=%d, duration=%d interval=%d\n",
5744 cfg->param.p2p_config.noa_enable,
5745 cfg->param.p2p_config.index,
5746 cfg->param.p2p_config.noa_count,
5747 (int)cfg->param.p2p_config
5748 .noa_duration,
5749 (int)cfg->param.p2p_config
5750 .noa_interval);
5751 break;
5752 case TLV_TYPE_WIFI_DIRECT_OPP_PS:
5753 popp_ps_tlv =
5754 (MrvlIEtypes_OPP_PS_setting_t *)
5755 tlv;
5756 cfg->param.p2p_config.flags |=
5757 WIFI_DIRECT_OPP_PS;
5758 cfg->param.p2p_config.opp_ps_enable =
5759 (popp_ps_tlv->enable & 0x80) >>
5760 7;
5761 cfg->param.p2p_config.ct_window =
5762 popp_ps_tlv->enable & 0x7f;
5763 PRINTM(MCMND,
5764 "Get OPP_PS: enable=%d ct_win=%d\n",
5765 cfg->param.p2p_config
5766 .opp_ps_enable,
5767 cfg->param.p2p_config.ct_window);
5768 break;
5769 default:
5770 break;
5771 }
5772 tlv_buf_left -=
5773 tlv_len + sizeof(MrvlIEtypesHeader_t);
5774 tlv = (MrvlIEtypesHeader_t
5775 *)((t_u8 *)tlv + tlv_len +
5776 sizeof(MrvlIEtypesHeader_t));
5777 }
5778 pioctl_buf->data_read_written =
5779 sizeof(mlan_ds_wifi_direct_config);
5780 }
5781 }
5782 LEAVE();
5783 return MLAN_STATUS_SUCCESS;
5784 }
5785 #endif
5786
5787 /**
5788 * @brief This function prepares command of GPIO TSF LATCH.
5789 *
5790 * @param pmpriv A pointer to mlan_private structure
5791 * @param cmd A pointer to HostCmd_DS_COMMAND structure
5792 * @param cmd_action The action: GET or SET
5793 * @param pioctl_buf A pointer to mlan_ioctl_req buf
5794 * @param pdata_buf A pointer to data buffer
5795 *
5796 * @return MLAN_STATUS_SUCCESS
5797 */
wlan_cmd_gpio_tsf_latch(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,mlan_ioctl_req * pioctl_buf,t_void * pdata_buf)5798 mlan_status wlan_cmd_gpio_tsf_latch(pmlan_private pmpriv,
5799 HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
5800 mlan_ioctl_req *pioctl_buf,
5801 t_void *pdata_buf)
5802 {
5803 HostCmd_DS_GPIO_TSF_LATCH_PARAM_CONFIG *gpio_tsf_config =
5804 &cmd->params.gpio_tsf_latch;
5805 mlan_ds_gpio_tsf_latch *cfg = (mlan_ds_gpio_tsf_latch *)pdata_buf;
5806 mlan_ds_misc_cfg *misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
5807
5808 mlan_ds_tsf_info *tsf_info = (mlan_ds_tsf_info *)pdata_buf;
5809 MrvlIEtypes_GPIO_TSF_LATCH_CONFIG *gpio_tsf_latch_config = MNULL;
5810 MrvlIEtypes_GPIO_TSF_LATCH_REPORT *gpio_tsf_latch_report = MNULL;
5811 t_u8 *tlv = MNULL;
5812 ENTER();
5813
5814 cmd->size = sizeof(HostCmd_DS_GPIO_TSF_LATCH_PARAM_CONFIG) + S_DS_GEN;
5815 cmd->command = wlan_cpu_to_le16(HOST_CMD_GPIO_TSF_LATCH_PARAM_CONFIG);
5816 gpio_tsf_config->action = wlan_cpu_to_le16(cmd_action);
5817 if (cmd_action == HostCmd_ACT_GEN_SET) {
5818 tlv = (t_u8 *)gpio_tsf_config->tlv_buf;
5819 if (misc_cfg->sub_command == MLAN_OID_MISC_GPIO_TSF_LATCH) {
5820 gpio_tsf_latch_config =
5821 (MrvlIEtypes_GPIO_TSF_LATCH_CONFIG *)tlv;
5822 gpio_tsf_latch_config->header.type = wlan_cpu_to_le16(
5823 TLV_TYPE_GPIO_TSF_LATCH_CONFIG);
5824 gpio_tsf_latch_config->header.len = wlan_cpu_to_le16(
5825 sizeof(MrvlIEtypes_GPIO_TSF_LATCH_CONFIG) -
5826 sizeof(MrvlIEtypesHeader_t));
5827 gpio_tsf_latch_config->clock_sync_mode =
5828 cfg->clock_sync_mode;
5829 gpio_tsf_latch_config->clock_sync_Role =
5830 cfg->clock_sync_Role;
5831 gpio_tsf_latch_config->clock_sync_gpio_pin_number =
5832 cfg->clock_sync_gpio_pin_number;
5833 gpio_tsf_latch_config->clock_sync_gpio_level_toggle =
5834 cfg->clock_sync_gpio_level_toggle;
5835 gpio_tsf_latch_config->clock_sync_gpio_pulse_width =
5836 wlan_cpu_to_le16(
5837 cfg->clock_sync_gpio_pulse_width);
5838 cmd->size += sizeof(MrvlIEtypes_GPIO_TSF_LATCH_CONFIG);
5839 tlv += sizeof(MrvlIEtypes_GPIO_TSF_LATCH_CONFIG);
5840 PRINTM(MCMND,
5841 "Set GPIO TSF latch config: Mode=%d Role=%d, GPIO Pin Number=%d, GPIO level/toggle=%d GPIO pulse width=%d\n",
5842 cfg->clock_sync_mode, cfg->clock_sync_Role,
5843 cfg->clock_sync_gpio_pin_number,
5844 cfg->clock_sync_gpio_level_toggle,
5845 (int)cfg->clock_sync_gpio_pulse_width);
5846 }
5847 } else if (cmd_action == HostCmd_ACT_GEN_GET) {
5848 tlv = (t_u8 *)gpio_tsf_config->tlv_buf;
5849 if (misc_cfg->sub_command == MLAN_OID_MISC_GPIO_TSF_LATCH) {
5850 gpio_tsf_latch_config =
5851 (MrvlIEtypes_GPIO_TSF_LATCH_CONFIG *)tlv;
5852 gpio_tsf_latch_config->header.type = wlan_cpu_to_le16(
5853 TLV_TYPE_GPIO_TSF_LATCH_CONFIG);
5854 gpio_tsf_latch_config->header.len = wlan_cpu_to_le16(
5855 sizeof(MrvlIEtypes_GPIO_TSF_LATCH_CONFIG) -
5856 sizeof(MrvlIEtypesHeader_t));
5857 cmd->size += sizeof(MrvlIEtypes_GPIO_TSF_LATCH_CONFIG);
5858 tlv += sizeof(MrvlIEtypes_GPIO_TSF_LATCH_CONFIG);
5859 }
5860
5861 if (misc_cfg->sub_command == MLAN_OID_MISC_GET_TSF_INFO) {
5862 gpio_tsf_latch_report =
5863 (MrvlIEtypes_GPIO_TSF_LATCH_REPORT *)tlv;
5864 gpio_tsf_latch_report->header.type = wlan_cpu_to_le16(
5865 TLV_TYPE_GPIO_TSF_LATCH_REPORT);
5866 gpio_tsf_latch_report->header.len = wlan_cpu_to_le16(
5867 sizeof(MrvlIEtypes_GPIO_TSF_LATCH_REPORT) -
5868 sizeof(MrvlIEtypesHeader_t));
5869 gpio_tsf_latch_report->tsf_format =
5870 wlan_cpu_to_le16(tsf_info->tsf_format);
5871 PRINTM(MCMND, "Get TSF info: format=%d\n",
5872 tsf_info->tsf_format);
5873 cmd->size += sizeof(MrvlIEtypes_GPIO_TSF_LATCH_REPORT);
5874 }
5875 }
5876 cmd->size = wlan_cpu_to_le16(cmd->size);
5877 LEAVE();
5878 return MLAN_STATUS_SUCCESS;
5879 }
5880
5881 /**
5882 * @brief This function handles the command response of GPIO TSF Latch
5883 *
5884 * @param pmpriv A pointer to mlan_private structure
5885 * @param resp A pointer to HostCmd_DS_COMMAND
5886 * @param pioctl_buf A pointer to mlan_ioctl_req structure
5887 *
5888 * @return MLAN_STATUS_SUCCESS
5889 */
wlan_ret_gpio_tsf_latch(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)5890 mlan_status wlan_ret_gpio_tsf_latch(pmlan_private pmpriv,
5891 HostCmd_DS_COMMAND *resp,
5892 mlan_ioctl_req *pioctl_buf)
5893 {
5894 HostCmd_DS_GPIO_TSF_LATCH_PARAM_CONFIG *gpio_tsf_config =
5895 &resp->params.gpio_tsf_latch;
5896 mlan_ds_misc_cfg *cfg = MNULL;
5897 MrvlIEtypes_GPIO_TSF_LATCH_CONFIG *gpio_tsf_latch_config = MNULL;
5898 MrvlIEtypes_GPIO_TSF_LATCH_REPORT *gpio_tsf_latch_report = MNULL;
5899 MrvlIEtypesHeader_t *tlv = MNULL;
5900 t_u16 tlv_buf_left = 0;
5901 t_u16 tlv_type = 0;
5902 t_u16 tlv_len = 0;
5903
5904 ENTER();
5905 if (wlan_le16_to_cpu(gpio_tsf_config->action) == HostCmd_ACT_GEN_GET) {
5906 if (pioctl_buf) {
5907 cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
5908 tlv = (MrvlIEtypesHeader_t *)(gpio_tsf_config->tlv_buf);
5909 tlv_buf_left =
5910 resp->size -
5911 (sizeof(HostCmd_DS_GPIO_TSF_LATCH_PARAM_CONFIG) +
5912 S_DS_GEN);
5913 while (tlv_buf_left >= sizeof(MrvlIEtypesHeader_t)) {
5914 tlv_type = wlan_le16_to_cpu(tlv->type);
5915 tlv_len = wlan_le16_to_cpu(tlv->len);
5916 if (tlv_buf_left <
5917 (tlv_len + sizeof(MrvlIEtypesHeader_t))) {
5918 PRINTM(MERROR,
5919 "Error processing gpio tsf latch config TLVs, bytes left < TLV length\n");
5920 break;
5921 }
5922 switch (tlv_type) {
5923 case TLV_TYPE_GPIO_TSF_LATCH_CONFIG:
5924 if (cfg->sub_command ==
5925 MLAN_OID_MISC_GPIO_TSF_LATCH) {
5926 gpio_tsf_latch_config =
5927 (MrvlIEtypes_GPIO_TSF_LATCH_CONFIG
5928 *)tlv;
5929 cfg->param.gpio_tsf_latch_config
5930 .clock_sync_mode =
5931 gpio_tsf_latch_config
5932 ->clock_sync_mode;
5933 cfg->param.gpio_tsf_latch_config
5934 .clock_sync_Role =
5935 gpio_tsf_latch_config
5936 ->clock_sync_Role;
5937 cfg->param.gpio_tsf_latch_config
5938 .clock_sync_gpio_pin_number =
5939 gpio_tsf_latch_config
5940 ->clock_sync_gpio_pin_number;
5941 cfg->param.gpio_tsf_latch_config
5942 .clock_sync_gpio_level_toggle =
5943 gpio_tsf_latch_config
5944 ->clock_sync_gpio_level_toggle;
5945 cfg->param.gpio_tsf_latch_config
5946 .clock_sync_gpio_pulse_width =
5947 wlan_le16_to_cpu(
5948 gpio_tsf_latch_config
5949 ->clock_sync_gpio_pulse_width);
5950 PRINTM(MCMND,
5951 "Get GPIO TSF latch config: Mode=%d Role=%d, GPIO Pin Number=%d, GPIO level/toggle=%d GPIO pulse width=%d\n",
5952 cfg->param
5953 .gpio_tsf_latch_config
5954 .clock_sync_mode,
5955 cfg->param
5956 .gpio_tsf_latch_config
5957 .clock_sync_Role,
5958 cfg->param
5959 .gpio_tsf_latch_config
5960 .clock_sync_gpio_pin_number,
5961 cfg->param
5962 .gpio_tsf_latch_config
5963 .clock_sync_gpio_level_toggle,
5964 (int)cfg->param
5965 .gpio_tsf_latch_config
5966 .clock_sync_gpio_pulse_width);
5967 }
5968 break;
5969 case TLV_TYPE_GPIO_TSF_LATCH_REPORT:
5970 if (cfg->sub_command ==
5971 MLAN_OID_MISC_GET_TSF_INFO) {
5972 gpio_tsf_latch_report =
5973 (MrvlIEtypes_GPIO_TSF_LATCH_REPORT
5974 *)tlv;
5975 cfg->param.tsf_info
5976 .tsf_format = wlan_le16_to_cpu(
5977 gpio_tsf_latch_report
5978 ->tsf_format);
5979 cfg->param.tsf_info
5980 .tsf_info = wlan_le16_to_cpu(
5981 gpio_tsf_latch_report
5982 ->tsf_info);
5983 cfg->param.tsf_info
5984 .tsf = wlan_le64_to_cpu(
5985 gpio_tsf_latch_report
5986 ->tsf);
5987 cfg->param.tsf_info
5988 .tsf_offset = wlan_le16_to_cpu(
5989 gpio_tsf_latch_report
5990 ->tsf_offset);
5991 PRINTM(MCMND,
5992 "Get GPIO TSF latch report : format=%d\n info=%d tsf=%llu offset=%d",
5993 cfg->param.tsf_info
5994 .tsf_format,
5995 cfg->param.tsf_info
5996 .tsf_info,
5997 cfg->param.tsf_info.tsf,
5998 cfg->param.tsf_info
5999 .tsf_offset);
6000 }
6001 break;
6002 default:
6003 break;
6004 }
6005 tlv_buf_left -=
6006 tlv_len + sizeof(MrvlIEtypesHeader_t);
6007 tlv = (MrvlIEtypesHeader_t
6008 *)((t_u8 *)tlv + tlv_len +
6009 sizeof(MrvlIEtypesHeader_t));
6010 }
6011 if (cfg->sub_command == MLAN_OID_MISC_GPIO_TSF_LATCH)
6012 pioctl_buf->data_read_written =
6013 sizeof(mlan_ds_gpio_tsf_latch);
6014 else if (cfg->sub_command == MLAN_OID_MISC_GET_TSF_INFO)
6015 pioctl_buf->data_read_written =
6016 sizeof(mlan_ds_tsf_info);
6017 }
6018 }
6019 LEAVE();
6020 return MLAN_STATUS_SUCCESS;
6021 }
6022
6023 /**
6024 * @brief This function prepares command of mimo switch configuration.
6025 *
6026 * @param pmpriv A pointer to mlan_private structure
6027 * @param cmd A pointer to HostCmd_DS_COMMAND structure
6028 * @param pdata_buf A pointer to data buffer
6029 * @return MLAN_STATUS_SUCCESS
6030 */
wlan_cmd_802_11_mimo_switch(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_void * pdata_buf)6031 mlan_status wlan_cmd_802_11_mimo_switch(pmlan_private pmpriv,
6032 HostCmd_DS_COMMAND *cmd,
6033 t_void *pdata_buf)
6034 {
6035 HostCmd_DS_MIMO_SWITCH *mimo_switch_cmd = &cmd->params.mimo_switch;
6036 mlan_ds_mimo_switch *pmimo_switch = (mlan_ds_mimo_switch *)pdata_buf;
6037
6038 ENTER();
6039
6040 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_MIMO_SWITCH);
6041 cmd->size =
6042 wlan_cpu_to_le16((sizeof(HostCmd_DS_MIMO_SWITCH)) + S_DS_GEN);
6043 mimo_switch_cmd->txpath_antmode = pmimo_switch->txpath_antmode;
6044 mimo_switch_cmd->rxpath_antmode = pmimo_switch->rxpath_antmode;
6045
6046 LEAVE();
6047 return MLAN_STATUS_SUCCESS;
6048 }
6049
6050 /**
6051 * @brief This function prepares command of hs wakeup reason.
6052 *
6053 * @param pmpriv A pointer to mlan_private structure
6054 * @param cmd A pointer to HostCmd_DS_COMMAND structure
6055 * @param pdata_buf A pointer to data buffer
6056 * @return MLAN_STATUS_SUCCESS
6057 */
wlan_cmd_hs_wakeup_reason(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_void * pdata_buf)6058 mlan_status wlan_cmd_hs_wakeup_reason(pmlan_private pmpriv,
6059 HostCmd_DS_COMMAND *cmd,
6060 t_void *pdata_buf)
6061 {
6062 ENTER();
6063
6064 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_HS_WAKEUP_REASON);
6065 cmd->size = wlan_cpu_to_le16((sizeof(HostCmd_DS_HS_WAKEUP_REASON)) +
6066 S_DS_GEN);
6067
6068 LEAVE();
6069 return MLAN_STATUS_SUCCESS;
6070 }
6071
6072 /**
6073 * @brief This function handles the command response of
6074 * hs wakeup reason
6075 *
6076 * @param pmpriv A pointer to mlan_private structure
6077 * @param resp A pointer to HostCmd_DS_COMMAND
6078 * @param pioctl_buf A pointer to command buffer
6079 *
6080 * @return MLAN_STATUS_SUCCESS
6081 */
wlan_ret_hs_wakeup_reason(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)6082 mlan_status wlan_ret_hs_wakeup_reason(pmlan_private pmpriv,
6083 HostCmd_DS_COMMAND *resp,
6084 mlan_ioctl_req *pioctl_buf)
6085 {
6086 HostCmd_DS_HS_WAKEUP_REASON *hs_wakeup_reason =
6087 (HostCmd_DS_HS_WAKEUP_REASON *)&resp->params.hs_wakeup_reason;
6088 mlan_ds_pm_cfg *pm_cfg = MNULL;
6089
6090 ENTER();
6091
6092 pm_cfg = (mlan_ds_pm_cfg *)pioctl_buf->pbuf;
6093 pm_cfg->param.wakeup_reason.hs_wakeup_reason =
6094 wlan_le16_to_cpu(hs_wakeup_reason->wakeup_reason);
6095 pioctl_buf->data_read_written = sizeof(mlan_ds_pm_cfg);
6096
6097 LEAVE();
6098 return MLAN_STATUS_SUCCESS;
6099 }
6100
6101 /**
6102 * @brief This function prepares command of tx_rx_pkt_stats
6103 *
6104 * @param pmpriv A pointer to mlan_private structure
6105 * @param cmd A pointer to HostCmd_DS_COMMAND structure
6106 * @param pioctl_buf A pointer to mlan_ioctl_req structure
6107 * @param pdata_buf A pointer to information buffer
6108 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
6109 */
wlan_cmd_tx_rx_pkt_stats(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,pmlan_ioctl_req pioctl_buf,t_void * pdata_buf)6110 mlan_status wlan_cmd_tx_rx_pkt_stats(pmlan_private pmpriv,
6111 HostCmd_DS_COMMAND *cmd,
6112 pmlan_ioctl_req pioctl_buf,
6113 t_void *pdata_buf)
6114 {
6115 HostCmd_DS_TX_RX_HISTOGRAM *ptx_rx_histogram =
6116 &cmd->params.tx_rx_histogram;
6117 mlan_ds_misc_tx_rx_histogram *ptx_rx_pkt_stats =
6118 (mlan_ds_misc_tx_rx_histogram *)pdata_buf;
6119 mlan_status ret = MLAN_STATUS_SUCCESS;
6120
6121 ENTER();
6122
6123 if (!ptx_rx_pkt_stats) {
6124 ret = MLAN_STATUS_FAILURE;
6125 goto done;
6126 }
6127 cmd->command = wlan_cpu_to_le16(HOST_CMD_TX_RX_PKT_STATS);
6128 cmd->size =
6129 wlan_cpu_to_le16(sizeof(HostCmd_DS_TX_RX_HISTOGRAM) + S_DS_GEN);
6130
6131 ptx_rx_histogram->enable = ptx_rx_pkt_stats->enable;
6132 ptx_rx_histogram->action = wlan_cpu_to_le16(ptx_rx_pkt_stats->action);
6133 done:
6134 LEAVE();
6135 return ret;
6136 }
6137 /**
6138 * @brief This function handles the command response of tx_rx_pkt_stats
6139 *
6140 * @param pmpriv A pointer to mlan_private structure
6141 * @param resp A pointer to HostCmd_DS_COMMAND
6142 * @param pioctl_buf A pointer to mlan_ioctl_req structure
6143 *
6144 * @return MLAN_STATUS_SUCCESS
6145 */
wlan_ret_tx_rx_pkt_stats(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)6146 mlan_status wlan_ret_tx_rx_pkt_stats(pmlan_private pmpriv,
6147 HostCmd_DS_COMMAND *resp,
6148 mlan_ioctl_req *pioctl_buf)
6149 {
6150 HostCmd_DS_TX_RX_HISTOGRAM *ptx_rx_histogram =
6151 &resp->params.tx_rx_histogram;
6152 mlan_ds_misc_cfg *info;
6153 t_u16 cmdsize = wlan_le16_to_cpu(resp->size), length;
6154 t_u32 *pos, count = 0;
6155
6156 ENTER();
6157
6158 if (pioctl_buf) {
6159 ptx_rx_histogram->action =
6160 wlan_le16_to_cpu(ptx_rx_histogram->action);
6161 info = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
6162 length =
6163 cmdsize - S_DS_GEN - sizeof(HostCmd_DS_TX_RX_HISTOGRAM);
6164 if (length > 0) {
6165 info->param.tx_rx_histogram.size = length;
6166 memcpy_ext(pmpriv->adapter,
6167 info->param.tx_rx_histogram.value,
6168 (t_u8 *)ptx_rx_histogram +
6169 sizeof(HostCmd_DS_TX_RX_HISTOGRAM),
6170 length, info->param.tx_rx_histogram.size);
6171 pos = (t_u32 *)info->param.tx_rx_histogram.value;
6172 while (length - 4 * count) {
6173 *pos = wlan_le32_to_cpu(*pos);
6174 pos += 4;
6175 count++;
6176 }
6177 }
6178 }
6179
6180 LEAVE();
6181 return MLAN_STATUS_SUCCESS;
6182 }
6183
6184 /*
6185 * @brief This function prepares command of cwmode control.
6186 *
6187 * @param pmpriv A pointer to mlan_private structure
6188 * @param cmd A pointer to HostCmd_DS_COMMAND structure
6189 * @param cmd_action The action: GET or SET
6190 * @param pdata_buf A pointer to data buffer
6191 *
6192 * @return MLAN_STATUS_SUCCESS
6193 */
wlan_cmd_cw_mode_ctrl(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)6194 mlan_status wlan_cmd_cw_mode_ctrl(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
6195 t_u16 cmd_action, t_void *pdata_buf)
6196 {
6197 HostCmd_DS_CW_MODE_CTRL *cwmode_ctrl = &cmd->params.cwmode;
6198 mlan_ds_cw_mode_ctrl *cw_mode = (mlan_ds_cw_mode_ctrl *)pdata_buf;
6199 ENTER();
6200 cmd->size =
6201 wlan_cpu_to_le16((sizeof(HostCmd_DS_CW_MODE_CTRL)) + S_DS_GEN);
6202 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_CW_MODE_CTRL);
6203 cwmode_ctrl->action = wlan_cpu_to_le16(cmd_action);
6204
6205 if (cmd_action == HostCmd_ACT_GEN_SET) {
6206 cwmode_ctrl->mode = cw_mode->mode;
6207 cwmode_ctrl->channel = cw_mode->channel;
6208 cwmode_ctrl->chanInfo = cw_mode->chanInfo;
6209 cwmode_ctrl->txPower = wlan_cpu_to_le16(cw_mode->txPower);
6210 cwmode_ctrl->rateInfo = wlan_cpu_to_le32(cw_mode->rateInfo);
6211 cwmode_ctrl->pktLength = wlan_cpu_to_le16(cw_mode->pktLength);
6212 }
6213 LEAVE();
6214 return MLAN_STATUS_SUCCESS;
6215 }
6216
6217 /*
6218 * @brief This function handles the command response of cwmode_ctrl
6219 *
6220 * @param pmpriv A pointer to mlan_private structure
6221 * @param resp A pointer to HostCmd_DS_COMMAND
6222 * @param pioctl_buf A pointer to mlan_ioctl_req structure
6223 *
6224 * @return MLAN_STATUS_SUCCESS
6225 */
wlan_ret_cw_mode_ctrl(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)6226 mlan_status wlan_ret_cw_mode_ctrl(pmlan_private pmpriv,
6227 HostCmd_DS_COMMAND *resp,
6228 mlan_ioctl_req *pioctl_buf)
6229 {
6230 HostCmd_DS_CW_MODE_CTRL *cwmode_resp = &resp->params.cwmode;
6231 mlan_ds_misc_cfg *misc = MNULL;
6232
6233 ENTER();
6234 if (pioctl_buf) {
6235 misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
6236 misc->param.cwmode.mode = cwmode_resp->mode;
6237 misc->param.cwmode.channel = cwmode_resp->channel;
6238 misc->param.cwmode.chanInfo = cwmode_resp->chanInfo;
6239 misc->param.cwmode.txPower =
6240 wlan_le16_to_cpu(cwmode_resp->txPower);
6241 misc->param.cwmode.rateInfo =
6242 wlan_le32_to_cpu(cwmode_resp->rateInfo);
6243 ;
6244 misc->param.cwmode.pktLength =
6245 wlan_le16_to_cpu(cwmode_resp->pktLength);
6246 ;
6247 pioctl_buf->data_read_written = sizeof(mlan_ds_misc_cfg);
6248 }
6249 LEAVE();
6250 return MLAN_STATUS_SUCCESS;
6251 }
6252
6253 /**
6254 * @brief This function prepares command of rf_antenna.
6255 *
6256 * @param pmpriv A pointer to mlan_private structure
6257 * @param cmd A pointer to HostCmd_DS_COMMAND structure
6258 * @param cmd_action The action: GET or SET
6259 * @param pdata_buf A pointer to data buffer
6260 *
6261 * @return MLAN_STATUS_SUCCESS
6262 */
wlan_cmd_802_11_rf_antenna(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)6263 mlan_status wlan_cmd_802_11_rf_antenna(pmlan_private pmpriv,
6264 HostCmd_DS_COMMAND *cmd,
6265 t_u16 cmd_action, t_void *pdata_buf)
6266 {
6267 HostCmd_DS_802_11_RF_ANTENNA *pantenna = &cmd->params.antenna;
6268 mlan_ds_ant_cfg *ant_cfg = (mlan_ds_ant_cfg *)pdata_buf;
6269 typedef struct _HostCmd_DS_802_11_RF_ANTENNA_1X1 {
6270 /** Action */
6271 t_u16 action;
6272 /** Antenna or 0xffff (diversity) */
6273 t_u16 antenna_mode;
6274 /** Evaluate time */
6275 t_u16 evaluate_time;
6276 /** Current antenna */
6277 t_u16 current_antenna;
6278 } HostCmd_DS_802_11_RF_ANTENNA_1X1;
6279 HostCmd_DS_802_11_RF_ANTENNA_1X1 *pantenna_1x1 =
6280 (HostCmd_DS_802_11_RF_ANTENNA_1X1 *)&cmd->params.antenna;
6281 mlan_ds_ant_cfg_1x1 *ant_cfg_1x1 = (mlan_ds_ant_cfg_1x1 *)pdata_buf;
6282
6283 ENTER();
6284 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_RF_ANTENNA);
6285 if (!IS_STREAM_2X2(pmpriv->adapter->feature_control))
6286 cmd->size = wlan_cpu_to_le16(
6287 sizeof(HostCmd_DS_802_11_RF_ANTENNA_1X1) + S_DS_GEN);
6288 else
6289 cmd->size = wlan_cpu_to_le16(
6290 sizeof(HostCmd_DS_802_11_RF_ANTENNA) + S_DS_GEN);
6291
6292 if (cmd_action == HostCmd_ACT_GEN_SET) {
6293 if (IS_STREAM_2X2(pmpriv->adapter->feature_control)) {
6294 pantenna->action_tx =
6295 wlan_cpu_to_le16(HostCmd_ACT_SET_TX);
6296 pantenna->tx_antenna_mode =
6297 wlan_cpu_to_le16((t_u16)ant_cfg->tx_antenna);
6298 pantenna->action_rx =
6299 wlan_cpu_to_le16(HostCmd_ACT_SET_RX);
6300 pantenna->rx_antenna_mode =
6301 wlan_cpu_to_le16((t_u16)ant_cfg->rx_antenna);
6302 } else {
6303 pantenna_1x1->action =
6304 wlan_cpu_to_le16(HostCmd_ACT_SET_BOTH);
6305 pantenna_1x1->antenna_mode =
6306 wlan_cpu_to_le16((t_u16)ant_cfg_1x1->antenna);
6307 pantenna_1x1->evaluate_time = wlan_cpu_to_le16(
6308 (t_u16)ant_cfg_1x1->evaluate_time);
6309 }
6310 } else {
6311 if (IS_STREAM_2X2(pmpriv->adapter->feature_control)) {
6312 pantenna->action_tx =
6313 wlan_cpu_to_le16(HostCmd_ACT_GET_TX);
6314 pantenna->action_rx =
6315 wlan_cpu_to_le16(HostCmd_ACT_GET_RX);
6316 } else {
6317 pantenna_1x1->action =
6318 wlan_cpu_to_le16(HostCmd_ACT_GET_BOTH);
6319 }
6320 }
6321 LEAVE();
6322 return MLAN_STATUS_SUCCESS;
6323 }
6324
6325 /**
6326 * @brief This function handles the command response of rf_antenna
6327 *
6328 * @param pmpriv A pointer to mlan_private structure
6329 * @param resp A pointer to HostCmd_DS_COMMAND
6330 * @param pioctl_buf A pointer to mlan_ioctl_req structure
6331 *
6332 * @return MLAN_STATUS_SUCCESS
6333 */
wlan_ret_802_11_rf_antenna(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)6334 mlan_status wlan_ret_802_11_rf_antenna(pmlan_private pmpriv,
6335 HostCmd_DS_COMMAND *resp,
6336 mlan_ioctl_req *pioctl_buf)
6337 {
6338 HostCmd_DS_802_11_RF_ANTENNA *pantenna = &resp->params.antenna;
6339 t_u16 tx_ant_mode = wlan_le16_to_cpu(pantenna->tx_antenna_mode);
6340 t_u16 rx_ant_mode = wlan_le16_to_cpu(pantenna->rx_antenna_mode);
6341 #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \
6342 defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \
6343 defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X)
6344 mlan_adapter *pmadapter = pmpriv->adapter;
6345 #endif
6346 typedef struct _HostCmd_DS_802_11_RF_ANTENNA_1X1 {
6347 /** Action */
6348 t_u16 action;
6349 /** Antenna or 0xffff (diversity) */
6350 t_u16 antenna_mode;
6351 /** Evaluate time */
6352 t_u16 evaluate_time;
6353 /** Current antenna */
6354 t_u16 current_antenna;
6355 } HostCmd_DS_802_11_RF_ANTENNA_1X1;
6356 HostCmd_DS_802_11_RF_ANTENNA_1X1 *pantenna_1x1 =
6357 (HostCmd_DS_802_11_RF_ANTENNA_1X1 *)&resp->params.antenna;
6358 t_u16 ant_mode = wlan_le16_to_cpu(pantenna_1x1->antenna_mode);
6359 t_u16 evaluate_time = wlan_le16_to_cpu(pantenna_1x1->evaluate_time);
6360 t_u16 current_antenna = wlan_le16_to_cpu(pantenna_1x1->current_antenna);
6361 mlan_ds_radio_cfg *radio = MNULL;
6362
6363 ENTER();
6364
6365 if (IS_STREAM_2X2(pmpriv->adapter->feature_control)) {
6366 PRINTM(MCMND,
6367 "RF_ANT_RESP: Tx action = 0x%x, Tx Mode = 0x%04x"
6368 " Rx action = 0x%x, Rx Mode = 0x%04x\n",
6369 wlan_le16_to_cpu(pantenna->action_tx), tx_ant_mode,
6370 wlan_le16_to_cpu(pantenna->action_rx), rx_ant_mode);
6371 #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \
6372 defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \
6373 defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X)
6374 if (IS_CARD9098(pmadapter->card_type) ||
6375 IS_CARDNW62X(pmadapter->card_type) ||
6376 IS_CARD9097(pmadapter->card_type)) {
6377 tx_ant_mode &= 0x0303;
6378 rx_ant_mode &= 0x0303;
6379 /** 2G antcfg TX */
6380 if (tx_ant_mode & 0x00FF) {
6381 pmadapter->user_htstream &= ~0xF0;
6382 pmadapter->user_htstream |=
6383 (bitcount(tx_ant_mode & 0x00FF) << 4);
6384 }
6385 /* 5G antcfg tx */
6386 if (tx_ant_mode & 0xFF00) {
6387 pmadapter->user_htstream &= ~0xF000;
6388 pmadapter->user_htstream |=
6389 (bitcount(tx_ant_mode & 0xFF00) << 12);
6390 }
6391 /* 2G antcfg RX */
6392 if (rx_ant_mode & 0x00FF) {
6393 pmadapter->user_htstream &= ~0xF;
6394 pmadapter->user_htstream |=
6395 bitcount(rx_ant_mode & 0x00FF);
6396 }
6397 /* 5G antcfg RX */
6398 if (rx_ant_mode & 0xFF00) {
6399 pmadapter->user_htstream &= ~0xF00;
6400 pmadapter->user_htstream |=
6401 (bitcount(rx_ant_mode & 0xFF00) << 8);
6402 }
6403 PRINTM(MCMND,
6404 "user_htstream=0x%x, tx_antenna=0x%x rx_antenna=0x%x\n",
6405 pmadapter->user_htstream, tx_ant_mode,
6406 rx_ant_mode);
6407 }
6408 #endif
6409 } else
6410 PRINTM(MINFO,
6411 "RF_ANT_RESP: action = 0x%x, Mode = 0x%04x, Evaluate time = %d, Current antenna = %d\n",
6412 wlan_le16_to_cpu(pantenna_1x1->action), ant_mode,
6413 evaluate_time, current_antenna);
6414
6415 if (pioctl_buf) {
6416 radio = (mlan_ds_radio_cfg *)pioctl_buf->pbuf;
6417 if (IS_STREAM_2X2(pmpriv->adapter->feature_control)) {
6418 radio->param.ant_cfg.tx_antenna = tx_ant_mode;
6419 radio->param.ant_cfg.rx_antenna = rx_ant_mode;
6420 } else {
6421 radio->param.ant_cfg_1x1.antenna = ant_mode;
6422 radio->param.ant_cfg_1x1.evaluate_time = evaluate_time;
6423 radio->param.ant_cfg_1x1.current_antenna =
6424 current_antenna;
6425 }
6426 }
6427
6428 LEAVE();
6429 return MLAN_STATUS_SUCCESS;
6430 }
6431
6432 /**
6433 * @brief This function prepares command of reg_access.
6434 *
6435 * @param priv A pointer to mlan_priv register.
6436 * @param cmd A pointer to HostCmd_DS_COMMAND structure
6437 * @param cmd_action the action: GET or SET
6438 * @param pdata_buf A pointer to data buffer
6439 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
6440 */
wlan_cmd_reg_access(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)6441 mlan_status wlan_cmd_reg_access(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
6442 t_u16 cmd_action, t_void *pdata_buf)
6443 {
6444 mlan_ds_reg_rw *reg_rw;
6445 #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \
6446 defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \
6447 defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097)
6448 MrvlIEtypes_Reg_type_t *tlv;
6449 mlan_adapter *pmadapter = pmpriv->adapter;
6450 #endif
6451
6452 ENTER();
6453
6454 reg_rw = (mlan_ds_reg_rw *)pdata_buf;
6455 switch (cmd->command) {
6456 case HostCmd_CMD_MAC_REG_ACCESS: {
6457 HostCmd_DS_MAC_REG_ACCESS *mac_reg;
6458 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_MAC_REG_ACCESS) +
6459 S_DS_GEN);
6460 mac_reg = (HostCmd_DS_MAC_REG_ACCESS *)&cmd->params.mac_reg;
6461 mac_reg->action = wlan_cpu_to_le16(cmd_action);
6462 mac_reg->offset = wlan_cpu_to_le16((t_u16)reg_rw->offset);
6463 mac_reg->value = wlan_cpu_to_le32(reg_rw->value);
6464 #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \
6465 defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \
6466 defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097)
6467 if ((reg_rw->type == MLAN_REG_MAC2) &&
6468 (IS_CARD9098(pmadapter->card_type) ||
6469 IS_CARDNW62X(pmadapter->card_type) ||
6470 IS_CARD9097(pmadapter->card_type))) {
6471 tlv = (MrvlIEtypes_Reg_type_t
6472 *)((t_u8 *)cmd +
6473 sizeof(HostCmd_DS_MAC_REG_ACCESS) +
6474 S_DS_GEN);
6475 tlv->header.type =
6476 wlan_cpu_to_le16(TLV_TYPE_REG_ACCESS_CTRL);
6477 tlv->header.len = wlan_cpu_to_le16(sizeof(t_u8));
6478 tlv->type = MLAN_REG_MAC2;
6479 cmd->size = wlan_cpu_to_le16(
6480 sizeof(HostCmd_DS_MAC_REG_ACCESS) + S_DS_GEN +
6481 sizeof(MrvlIEtypes_Reg_type_t));
6482 }
6483 #endif
6484 break;
6485 }
6486 case HostCmd_CMD_REG_ACCESS: {
6487 HostCmd_DS_REG_ACCESS *reg;
6488 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_REG_ACCESS) +
6489 S_DS_GEN);
6490 reg = (HostCmd_DS_REG_ACCESS *)&cmd->params.reg;
6491 reg->action = wlan_cpu_to_le16(cmd_action);
6492 reg->reg_type = wlan_cpu_to_le16((t_u16)reg_rw->type);
6493 reg->offset = wlan_cpu_to_le16((t_u16)reg_rw->offset);
6494 reg->value = wlan_cpu_to_le32(reg_rw->value);
6495 break;
6496 }
6497 case HostCmd_CMD_BBP_REG_ACCESS: {
6498 HostCmd_DS_BBP_REG_ACCESS *bbp_reg;
6499 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_BBP_REG_ACCESS) +
6500 S_DS_GEN);
6501 bbp_reg = (HostCmd_DS_BBP_REG_ACCESS *)&cmd->params.bbp_reg;
6502 bbp_reg->action = wlan_cpu_to_le16(cmd_action);
6503 bbp_reg->offset = wlan_cpu_to_le16((t_u16)reg_rw->offset);
6504 bbp_reg->value = (t_u8)reg_rw->value;
6505 #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \
6506 defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \
6507 defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097)
6508 if ((reg_rw->type == MLAN_REG_BBP2) &&
6509 (IS_CARD9098(pmadapter->card_type) ||
6510 IS_CARDNW62X(pmadapter->card_type) ||
6511 IS_CARD9097(pmadapter->card_type))) {
6512 tlv = (MrvlIEtypes_Reg_type_t
6513 *)((t_u8 *)cmd +
6514 sizeof(HostCmd_DS_BBP_REG_ACCESS) +
6515 S_DS_GEN);
6516 tlv->header.type =
6517 wlan_cpu_to_le16(TLV_TYPE_REG_ACCESS_CTRL);
6518 tlv->header.len = wlan_cpu_to_le16(sizeof(t_u8));
6519 tlv->type = MLAN_REG_BBP2;
6520 cmd->size = wlan_cpu_to_le16(
6521 sizeof(HostCmd_DS_BBP_REG_ACCESS) + S_DS_GEN +
6522 sizeof(MrvlIEtypes_Reg_type_t));
6523 }
6524 #endif
6525 break;
6526 }
6527 case HostCmd_CMD_RF_REG_ACCESS: {
6528 HostCmd_DS_RF_REG_ACCESS *rf_reg;
6529 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_RF_REG_ACCESS) +
6530 S_DS_GEN);
6531 rf_reg = (HostCmd_DS_RF_REG_ACCESS *)&cmd->params.rf_reg;
6532 rf_reg->action = wlan_cpu_to_le16(cmd_action);
6533 rf_reg->offset = wlan_cpu_to_le16((t_u16)reg_rw->offset);
6534 rf_reg->value = (t_u8)reg_rw->value;
6535 #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \
6536 defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \
6537 defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097)
6538 if ((reg_rw->type == MLAN_REG_RF2) &&
6539 (IS_CARD9098(pmadapter->card_type) ||
6540 IS_CARDNW62X(pmadapter->card_type) ||
6541 IS_CARD9097(pmadapter->card_type))) {
6542 tlv = (MrvlIEtypes_Reg_type_t
6543 *)((t_u8 *)cmd +
6544 sizeof(HostCmd_DS_RF_REG_ACCESS) +
6545 S_DS_GEN);
6546 tlv->header.type =
6547 wlan_cpu_to_le16(TLV_TYPE_REG_ACCESS_CTRL);
6548 tlv->header.len = wlan_cpu_to_le16(sizeof(t_u8));
6549 tlv->type = MLAN_REG_RF2;
6550 cmd->size = wlan_cpu_to_le16(
6551 sizeof(HostCmd_DS_RF_REG_ACCESS) + S_DS_GEN +
6552 sizeof(MrvlIEtypes_Reg_type_t));
6553 }
6554 #endif
6555 break;
6556 }
6557 case HostCmd_CMD_CAU_REG_ACCESS: {
6558 HostCmd_DS_RF_REG_ACCESS *cau_reg;
6559 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_RF_REG_ACCESS) +
6560 S_DS_GEN);
6561 cau_reg = (HostCmd_DS_RF_REG_ACCESS *)&cmd->params.rf_reg;
6562 cau_reg->action = wlan_cpu_to_le16(cmd_action);
6563 cau_reg->offset = wlan_cpu_to_le16((t_u16)reg_rw->offset);
6564 cau_reg->value = (t_u8)reg_rw->value;
6565 break;
6566 }
6567 case HostCmd_CMD_TARGET_ACCESS: {
6568 HostCmd_DS_TARGET_ACCESS *target;
6569 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_TARGET_ACCESS) +
6570 S_DS_GEN);
6571 target = (HostCmd_DS_TARGET_ACCESS *)&cmd->params.target;
6572 target->action = wlan_cpu_to_le16(cmd_action);
6573 target->csu_target = wlan_cpu_to_le16(MLAN_CSU_TARGET_PSU);
6574 target->address = wlan_cpu_to_le16((t_u16)reg_rw->offset);
6575 target->data = (t_u8)reg_rw->value;
6576 break;
6577 }
6578 case HostCmd_CMD_802_11_EEPROM_ACCESS: {
6579 mlan_ds_read_eeprom *rd_eeprom =
6580 (mlan_ds_read_eeprom *)pdata_buf;
6581 HostCmd_DS_802_11_EEPROM_ACCESS *cmd_eeprom =
6582 (HostCmd_DS_802_11_EEPROM_ACCESS *)&cmd->params.eeprom;
6583 cmd->size = wlan_cpu_to_le16(
6584 sizeof(HostCmd_DS_802_11_EEPROM_ACCESS) + S_DS_GEN);
6585 cmd_eeprom->action = wlan_cpu_to_le16(cmd_action);
6586 cmd_eeprom->offset = wlan_cpu_to_le16(rd_eeprom->offset);
6587 cmd_eeprom->byte_count =
6588 wlan_cpu_to_le16(rd_eeprom->byte_count);
6589 cmd_eeprom->value = 0;
6590 break;
6591 }
6592 case HostCmd_CMD_BCA_REG_ACCESS: {
6593 HostCmd_DS_BCA_REG_ACCESS *bca_reg;
6594 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_BCA_REG_ACCESS) +
6595 S_DS_GEN);
6596 bca_reg = (HostCmd_DS_BCA_REG_ACCESS *)&cmd->params.bca_reg;
6597 bca_reg->action = wlan_cpu_to_le16(cmd_action);
6598 bca_reg->offset = wlan_cpu_to_le16((t_u16)reg_rw->offset);
6599 bca_reg->value = wlan_cpu_to_le32(reg_rw->value);
6600 #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \
6601 defined(PCIE9097) || defined(USB9097) || defined(SDNW62X) || \
6602 defined(PCIENW62X) || defined(USBNW62X) || defined(SD9097)
6603 if ((reg_rw->type == MLAN_REG_BCA2) &&
6604 (IS_CARD9098(pmadapter->card_type) ||
6605 IS_CARDNW62X(pmadapter->card_type) ||
6606 IS_CARD9097(pmadapter->card_type))) {
6607 tlv = (MrvlIEtypes_Reg_type_t
6608 *)((t_u8 *)cmd +
6609 sizeof(HostCmd_DS_BCA_REG_ACCESS) +
6610 S_DS_GEN);
6611 tlv->header.type =
6612 wlan_cpu_to_le16(TLV_TYPE_REG_ACCESS_CTRL);
6613 tlv->header.len = wlan_cpu_to_le16(sizeof(t_u8));
6614 tlv->type = MLAN_REG_BCA2;
6615 cmd->size = wlan_cpu_to_le16(
6616 sizeof(HostCmd_DS_BCA_REG_ACCESS) + S_DS_GEN +
6617 sizeof(MrvlIEtypes_Reg_type_t));
6618 }
6619 #endif
6620 break;
6621 }
6622 default:
6623 LEAVE();
6624 return MLAN_STATUS_FAILURE;
6625 }
6626 cmd->command = wlan_cpu_to_le16(cmd->command);
6627
6628 LEAVE();
6629 return MLAN_STATUS_SUCCESS;
6630 }
6631
6632 /**
6633 * @brief This function handles the command response of reg_access
6634 *
6635 * @param pmadapter A pointer to mlan_adapter structure
6636 * @param type The type of reg access (MAC, BBP or RF)
6637 * @param resp A pointer to HostCmd_DS_COMMAND
6638 * @param pioctl_buf A pointer to command buffer
6639 *
6640 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
6641 */
wlan_ret_reg_access(mlan_adapter * pmadapter,t_u16 type,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)6642 mlan_status wlan_ret_reg_access(mlan_adapter *pmadapter, t_u16 type,
6643 HostCmd_DS_COMMAND *resp,
6644 mlan_ioctl_req *pioctl_buf)
6645 {
6646 mlan_ds_reg_mem *reg_mem = MNULL;
6647 mlan_ds_reg_rw *reg_rw = MNULL;
6648
6649 ENTER();
6650
6651 if (pioctl_buf) {
6652 reg_mem = (mlan_ds_reg_mem *)pioctl_buf->pbuf;
6653 reg_rw = ®_mem->param.reg_rw;
6654 switch (type) {
6655 case HostCmd_CMD_MAC_REG_ACCESS: {
6656 HostCmd_DS_MAC_REG_ACCESS *reg;
6657 reg = (HostCmd_DS_MAC_REG_ACCESS *)&resp->params.mac_reg;
6658 reg_rw->offset = (t_u32)wlan_le16_to_cpu(reg->offset);
6659 reg_rw->value = wlan_le32_to_cpu(reg->value);
6660 break;
6661 }
6662 case HostCmd_CMD_REG_ACCESS: {
6663 HostCmd_DS_REG_ACCESS *reg;
6664 reg = (HostCmd_DS_REG_ACCESS *)&resp->params.reg;
6665 reg_rw->offset = (t_u32)wlan_le16_to_cpu(reg->offset);
6666 reg_rw->value = wlan_le32_to_cpu(reg->value);
6667 break;
6668 }
6669 case HostCmd_CMD_BBP_REG_ACCESS: {
6670 HostCmd_DS_BBP_REG_ACCESS *reg;
6671 reg = (HostCmd_DS_BBP_REG_ACCESS *)&resp->params.bbp_reg;
6672 reg_rw->offset = (t_u32)wlan_le16_to_cpu(reg->offset);
6673 reg_rw->value = (t_u32)reg->value;
6674 break;
6675 }
6676
6677 case HostCmd_CMD_RF_REG_ACCESS: {
6678 HostCmd_DS_RF_REG_ACCESS *reg;
6679 reg = (HostCmd_DS_RF_REG_ACCESS *)&resp->params.rf_reg;
6680 reg_rw->offset = (t_u32)wlan_le16_to_cpu(reg->offset);
6681 reg_rw->value = (t_u32)reg->value;
6682 break;
6683 }
6684 case HostCmd_CMD_CAU_REG_ACCESS: {
6685 HostCmd_DS_RF_REG_ACCESS *reg;
6686 reg = (HostCmd_DS_RF_REG_ACCESS *)&resp->params.rf_reg;
6687 reg_rw->offset = (t_u32)wlan_le16_to_cpu(reg->offset);
6688 reg_rw->value = (t_u32)reg->value;
6689 break;
6690 }
6691 case HostCmd_CMD_TARGET_ACCESS: {
6692 HostCmd_DS_TARGET_ACCESS *reg;
6693 reg = (HostCmd_DS_TARGET_ACCESS *)&resp->params.target;
6694 reg_rw->offset = (t_u32)wlan_le16_to_cpu(reg->address);
6695 reg_rw->value = (t_u32)reg->data;
6696 break;
6697 }
6698 case HostCmd_CMD_802_11_EEPROM_ACCESS: {
6699 mlan_ds_read_eeprom *eeprom = ®_mem->param.rd_eeprom;
6700 HostCmd_DS_802_11_EEPROM_ACCESS *cmd_eeprom =
6701 (HostCmd_DS_802_11_EEPROM_ACCESS *)&resp->params
6702 .eeprom;
6703 cmd_eeprom->byte_count =
6704 wlan_le16_to_cpu(cmd_eeprom->byte_count);
6705 PRINTM(MINFO, "EEPROM read len=%x\n",
6706 cmd_eeprom->byte_count);
6707 if (eeprom->byte_count < cmd_eeprom->byte_count) {
6708 eeprom->byte_count = 0;
6709 PRINTM(MINFO,
6710 "EEPROM read return length is too big\n");
6711 pioctl_buf->status_code =
6712 MLAN_ERROR_CMD_RESP_FAIL;
6713 LEAVE();
6714 return MLAN_STATUS_FAILURE;
6715 }
6716 eeprom->offset = wlan_le16_to_cpu(cmd_eeprom->offset);
6717 eeprom->byte_count = cmd_eeprom->byte_count;
6718 if (eeprom->byte_count > 0) {
6719 memcpy_ext(pmadapter, &eeprom->value,
6720 &cmd_eeprom->value,
6721 eeprom->byte_count, MAX_EEPROM_DATA);
6722 HEXDUMP("EEPROM", (char *)&eeprom->value,
6723 MIN(MAX_EEPROM_DATA,
6724 eeprom->byte_count));
6725 }
6726 break;
6727 }
6728 case HostCmd_CMD_BCA_REG_ACCESS: {
6729 HostCmd_DS_BCA_REG_ACCESS *reg;
6730 reg = (HostCmd_DS_BCA_REG_ACCESS *)&resp->params.bca_reg;
6731 reg_rw->offset = (t_u32)wlan_le16_to_cpu(reg->offset);
6732 reg_rw->value = wlan_le32_to_cpu(reg->value);
6733 break;
6734 }
6735 default:
6736 pioctl_buf->status_code = MLAN_ERROR_CMD_RESP_FAIL;
6737 LEAVE();
6738 return MLAN_STATUS_FAILURE;
6739 }
6740 }
6741
6742 LEAVE();
6743 return MLAN_STATUS_SUCCESS;
6744 }
6745
6746 /**
6747 * @brief This function prepares command of mem_access.
6748 *
6749 * @param cmd A pointer to HostCmd_DS_COMMAND structure
6750 * @param cmd_action the action: GET or SET
6751 * @param pdata_buf A pointer to data buffer
6752 * @return MLAN_STATUS_SUCCESS
6753 */
wlan_cmd_mem_access(HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)6754 mlan_status wlan_cmd_mem_access(HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
6755 t_void *pdata_buf)
6756 {
6757 mlan_ds_mem_rw *mem_rw = (mlan_ds_mem_rw *)pdata_buf;
6758 HostCmd_DS_MEM_ACCESS *mem_access =
6759 (HostCmd_DS_MEM_ACCESS *)&cmd->params.mem;
6760
6761 ENTER();
6762
6763 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MEM_ACCESS);
6764 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_MEM_ACCESS) + S_DS_GEN);
6765
6766 mem_access->action = wlan_cpu_to_le16(cmd_action);
6767 mem_access->addr = wlan_cpu_to_le32(mem_rw->addr);
6768 mem_access->value = wlan_cpu_to_le32(mem_rw->value);
6769
6770 LEAVE();
6771 return MLAN_STATUS_SUCCESS;
6772 }
6773
6774 /**
6775 * @brief This function handles the command response of mem_access
6776 *
6777 * @param pmpriv A pointer to mlan_private structure
6778 * @param resp A pointer to HostCmd_DS_COMMAND
6779 * @param pioctl_buf A pointer to command buffer
6780 *
6781 * @return MLAN_STATUS_SUCCESS
6782 */
wlan_ret_mem_access(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)6783 mlan_status wlan_ret_mem_access(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
6784 mlan_ioctl_req *pioctl_buf)
6785 {
6786 mlan_ds_reg_mem *reg_mem = MNULL;
6787 mlan_ds_mem_rw *mem_rw = MNULL;
6788 HostCmd_DS_MEM_ACCESS *mem = (HostCmd_DS_MEM_ACCESS *)&resp->params.mem;
6789
6790 ENTER();
6791
6792 if (pioctl_buf) {
6793 reg_mem = (mlan_ds_reg_mem *)pioctl_buf->pbuf;
6794 mem_rw = ®_mem->param.mem_rw;
6795
6796 mem_rw->addr = wlan_le32_to_cpu(mem->addr);
6797 mem_rw->value = wlan_le32_to_cpu(mem->value);
6798 }
6799
6800 LEAVE();
6801 return MLAN_STATUS_SUCCESS;
6802 }
6803
6804 /**
6805 *
6806 * @brief This function handles coex events generated by firmware
6807 *
6808 * @param priv A pointer to mlan_private structure
6809 * @param pevent A pointer to event buf
6810 *
6811 * @return N/A
6812 */
wlan_bt_coex_wlan_param_update_event(pmlan_private priv,pmlan_buffer pevent)6813 void wlan_bt_coex_wlan_param_update_event(pmlan_private priv,
6814 pmlan_buffer pevent)
6815 {
6816 pmlan_adapter pmadapter = priv->adapter;
6817 MrvlIEtypesHeader_t *tlv = MNULL;
6818 MrvlIETypes_BtCoexAggrWinSize_t *pCoexWinsize = MNULL;
6819 MrvlIEtypes_BtCoexScanTime_t *pScantlv = MNULL;
6820 t_s32 len = pevent->data_len - sizeof(t_u32);
6821 t_u8 *pCurrent_ptr = pevent->pbuf + pevent->data_offset + sizeof(t_u32);
6822 t_u16 tlv_type, tlv_len;
6823
6824 ENTER();
6825
6826 while (len >= (t_s32)sizeof(MrvlIEtypesHeader_t)) {
6827 tlv = (MrvlIEtypesHeader_t *)pCurrent_ptr;
6828 tlv_len = wlan_le16_to_cpu(tlv->len);
6829 tlv_type = wlan_le16_to_cpu(tlv->type);
6830 if ((tlv_len + (t_s32)sizeof(MrvlIEtypesHeader_t)) > len)
6831 break;
6832 switch (tlv_type) {
6833 case TLV_BTCOEX_WL_AGGR_WINSIZE:
6834 pCoexWinsize = (MrvlIETypes_BtCoexAggrWinSize_t *)tlv;
6835 pmadapter->coex_win_size = pCoexWinsize->coex_win_size;
6836 pmadapter->coex_tx_win_size = pCoexWinsize->tx_win_size;
6837 pmadapter->coex_rx_win_size = pCoexWinsize->rx_win_size;
6838 wlan_coex_ampdu_rxwinsize(pmadapter);
6839 wlan_update_ampdu_txwinsize(pmadapter);
6840 break;
6841 case TLV_BTCOEX_WL_SCANTIME:
6842 pScantlv = (MrvlIEtypes_BtCoexScanTime_t *)tlv;
6843 pmadapter->coex_scan = pScantlv->coex_scan;
6844 pmadapter->coex_min_scan_time =
6845 wlan_le16_to_cpu(pScantlv->min_scan_time);
6846 pmadapter->coex_max_scan_time =
6847 wlan_le16_to_cpu(pScantlv->max_scan_time);
6848 break;
6849 default:
6850 break;
6851 }
6852 len -= tlv_len + sizeof(MrvlIEtypesHeader_t);
6853 pCurrent_ptr += tlv_len + sizeof(MrvlIEtypesHeader_t);
6854 }
6855 PRINTM(MEVENT,
6856 "coex_scan=%d min_scan=%d coex_win=%d, tx_win=%d rx_win=%d\n",
6857 pmadapter->coex_scan, pmadapter->coex_min_scan_time,
6858 pmadapter->coex_win_size, pmadapter->coex_tx_win_size,
6859 pmadapter->coex_rx_win_size);
6860
6861 LEAVE();
6862 }
6863
6864 /**
6865 * @brief This function prepares command of supplicant pmk
6866 *
6867 * @param pmpriv A pointer to mlan_private structure
6868 * @param cmd A pointer to HostCmd_DS_COMMAND structure
6869 * @param cmd_action The action: GET or SET
6870 * @param pdata_buf A pointer to data buffer
6871 *
6872 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
6873 */
wlan_cmd_802_11_supplicant_pmk(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)6874 mlan_status wlan_cmd_802_11_supplicant_pmk(pmlan_private pmpriv,
6875 HostCmd_DS_COMMAND *cmd,
6876 t_u16 cmd_action, t_void *pdata_buf)
6877 {
6878 MrvlIEtypes_PMK_t *ppmk_tlv = MNULL;
6879 MrvlIEtypes_Passphrase_t *ppassphrase_tlv = MNULL;
6880 MrvlIEtypes_SAE_Password_t *psae_password_tlv = MNULL;
6881 MrvlIEtypes_SsIdParamSet_t *pssid_tlv = MNULL;
6882 MrvlIEtypes_Bssid_t *pbssid_tlv = MNULL;
6883 HostCmd_DS_802_11_SUPPLICANT_PMK *pesupplicant_psk =
6884 &cmd->params.esupplicant_psk;
6885 t_u8 *ptlv_buffer = (t_u8 *)pesupplicant_psk->tlv_buffer;
6886 mlan_ds_sec_cfg *sec = (mlan_ds_sec_cfg *)pdata_buf;
6887 mlan_ds_passphrase *psk = MNULL;
6888 t_u8 zero_mac[] = {0, 0, 0, 0, 0, 0};
6889 t_u8 ssid_flag = 0, bssid_flag = 0, pmk_flag = 0, passphrase_flag = 0;
6890 t_u8 sae_password_flag = 0;
6891 t_u8 zero[MLAN_MAX_KEY_LENGTH] = {0};
6892 MrvlIEtypes_fw_roam_enable_t *proam_tlv = MNULL;
6893 MrvlIEtypes_keyParams_t *key_tlv = MNULL;
6894 int length = 0;
6895 t_u8 userset_passphrase = 0;
6896
6897 ENTER();
6898 if (sec->multi_passphrase)
6899 psk = (mlan_ds_passphrase *)&sec->param
6900 .roam_passphrase[userset_passphrase];
6901 else
6902 psk = (mlan_ds_passphrase *)&sec->param.passphrase;
6903 if (cmd_action == HostCmd_ACT_GEN_REMOVE) {
6904 cmd->size =
6905 sizeof(HostCmd_DS_802_11_SUPPLICANT_PMK) + S_DS_GEN - 1;
6906 proam_tlv = (MrvlIEtypes_fw_roam_enable_t *)ptlv_buffer;
6907 proam_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_ROAM);
6908 proam_tlv->header.len = sizeof(MrvlIEtypes_fw_roam_enable_t) -
6909 sizeof(MrvlIEtypesHeader_t);
6910 proam_tlv->roam_enable = MTRUE;
6911 ptlv_buffer +=
6912 (proam_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
6913 cmd->size +=
6914 (proam_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
6915 proam_tlv->header.len = wlan_cpu_to_le16(proam_tlv->header.len);
6916
6917 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_SUPPLICANT_PMK);
6918 pesupplicant_psk->action = wlan_cpu_to_le16(cmd_action);
6919 pesupplicant_psk->cache_result = 0;
6920 cmd->size = wlan_cpu_to_le16(cmd->size);
6921 LEAVE();
6922 return MLAN_STATUS_SUCCESS;
6923 }
6924
6925 // Parse the rest of the buf here
6926 // 1) <ssid="valid ssid"> - This will get the passphrase, AKMP
6927 // for specified ssid, if none specified then it will get all.
6928 // Eg: iwpriv <mlanX> passphrase 0:ssid=nxp
6929 // 2) <psk="psk">:<passphrase="passphare">:<bssid="00:50:43:ef:23:f3">
6930 // <ssid="valid ssid"> - passphrase and psk cannot be provided to
6931 // the same SSID, Takes one SSID at a time, If ssid= is present
6932 // the it should contain a passphrase or psk. If no arguments are
6933 // provided then AKMP=802.1x, and passphrase should be provided
6934 // after association.
6935 // End of each parameter should be followed by a ':'(except for the
6936 // last parameter) as the delimiter. If ':' has to be used in
6937 // an SSID then a '/' should be preceded to ':' as a escape.
6938 // Eg:iwpriv <mlanX> passphrase
6939 // "1:ssid=mrvl AP:psk=abcdefgh:bssid=00:50:43:ef:23:f3"
6940 // iwpriv <mlanX> passphrase
6941 // "1:ssid=nxp/: AP:psk=abcdefgd:bssid=00:50:43:ef:23:f3"
6942 // iwpriv <mlanX> passphrase "1:ssid=mrvlAP:psk=abcdefgd"
6943 // 3) <ssid="valid ssid"> - This will clear the passphrase
6944 // for specified ssid, if none specified then it will clear all.
6945 // Eg: iwpriv <mlanX> passphrase 2:ssid=nxp
6946 //
6947 //
6948 // -1 is for t_u8 TlvBuffer[1] as this should not be included */
6949 cmd->size = sizeof(HostCmd_DS_802_11_SUPPLICANT_PMK) + S_DS_GEN - 1;
6950 if (psk && memcmp(pmpriv->adapter, (t_u8 *)&psk->bssid, zero_mac,
6951 sizeof(zero_mac))) {
6952 pbssid_tlv = (MrvlIEtypes_Bssid_t *)ptlv_buffer;
6953 pbssid_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_BSSID);
6954 pbssid_tlv->header.len = MLAN_MAC_ADDR_LENGTH;
6955 memcpy_ext(pmpriv->adapter, pbssid_tlv->bssid,
6956 (t_u8 *)&psk->bssid, MLAN_MAC_ADDR_LENGTH,
6957 MLAN_MAC_ADDR_LENGTH);
6958 ptlv_buffer +=
6959 (pbssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
6960 cmd->size +=
6961 (pbssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
6962 pbssid_tlv->header.len =
6963 wlan_cpu_to_le16(pbssid_tlv->header.len);
6964 bssid_flag = 1;
6965 }
6966 if (psk && (psk->psk_type == MLAN_PSK_PMK)) {
6967 ppmk_tlv = (MrvlIEtypes_PMK_t *)ptlv_buffer;
6968 ppmk_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_PMK);
6969 ppmk_tlv->header.len = MLAN_MAX_KEY_LENGTH;
6970 memcpy_ext(pmpriv->adapter, ppmk_tlv->pmk, psk->psk.pmk.pmk,
6971 MLAN_MAX_KEY_LENGTH, MLAN_MAX_KEY_LENGTH);
6972 ptlv_buffer +=
6973 (ppmk_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
6974 cmd->size +=
6975 (ppmk_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
6976 ppmk_tlv->header.len = wlan_cpu_to_le16(ppmk_tlv->header.len);
6977 pmk_flag = 1;
6978 if (memcmp(pmpriv->adapter, psk->psk.pmk.pmk_r0, zero,
6979 MLAN_MAX_KEY_LENGTH)) {
6980 ppmk_tlv = (MrvlIEtypes_PMK_t *)ptlv_buffer;
6981 ppmk_tlv->header.type =
6982 wlan_cpu_to_le16(TLV_TYPE_PMK_R0);
6983 ppmk_tlv->header.len = MLAN_MAX_KEY_LENGTH;
6984 memcpy_ext(pmpriv->adapter, ppmk_tlv->pmk,
6985 psk->psk.pmk.pmk_r0, MLAN_MAX_KEY_LENGTH,
6986 MLAN_MAX_KEY_LENGTH);
6987 ptlv_buffer += (ppmk_tlv->header.len +
6988 sizeof(MrvlIEtypesHeader_t));
6989 cmd->size += (ppmk_tlv->header.len +
6990 sizeof(MrvlIEtypesHeader_t));
6991 ppmk_tlv->header.len =
6992 wlan_cpu_to_le16(ppmk_tlv->header.len);
6993 }
6994 if (memcmp(pmpriv->adapter, psk->psk.pmk.pmk_r0_name, zero,
6995 MLAN_MAX_PMKR0_NAME_LENGTH)) {
6996 ppmk_tlv = (MrvlIEtypes_PMK_t *)ptlv_buffer;
6997 ppmk_tlv->header.type =
6998 wlan_cpu_to_le16(TLV_TYPE_PMK_R0_NAME);
6999 ppmk_tlv->header.len = MLAN_MAX_PMKR0_NAME_LENGTH;
7000 memcpy_ext(pmpriv->adapter, ppmk_tlv->pmk,
7001 psk->psk.pmk.pmk_r0_name,
7002 MLAN_MAX_PMKR0_NAME_LENGTH,
7003 MLAN_MAX_PMKR0_NAME_LENGTH);
7004 ptlv_buffer += (ppmk_tlv->header.len +
7005 sizeof(MrvlIEtypesHeader_t));
7006 cmd->size += (ppmk_tlv->header.len +
7007 sizeof(MrvlIEtypesHeader_t));
7008 ppmk_tlv->header.len =
7009 wlan_cpu_to_le16(ppmk_tlv->header.len);
7010 }
7011 }
7012 if (pmpriv->adapter->fw_roaming &&
7013 (pmpriv->adapter->userset_passphrase ||
7014 (psk && psk->psk_type == MLAN_PSK_PMK))) {
7015 proam_tlv = (MrvlIEtypes_fw_roam_enable_t *)ptlv_buffer;
7016 proam_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_ROAM);
7017 proam_tlv->header.len = sizeof(MrvlIEtypes_fw_roam_enable_t) -
7018 sizeof(MrvlIEtypesHeader_t);
7019 proam_tlv->roam_enable = MTRUE;
7020 proam_tlv->userset_passphrase =
7021 pmpriv->adapter->userset_passphrase;
7022 ptlv_buffer +=
7023 (proam_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
7024 cmd->size +=
7025 (proam_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
7026 proam_tlv->header.len = wlan_cpu_to_le16(proam_tlv->header.len);
7027 }
7028 do {
7029 if (pmpriv->adapter->userset_passphrase &&
7030 sec->multi_passphrase) {
7031 key_tlv = (MrvlIEtypes_keyParams_t *)ptlv_buffer;
7032 key_tlv->header.type = wlan_cpu_to_le16(
7033 TLV_TYPE_ROAM_OFFLOAD_USER_SET_PMK);
7034 ptlv_buffer += sizeof(MrvlIEtypesHeader_t);
7035 cmd->size += sizeof(MrvlIEtypesHeader_t);
7036 length = cmd->size;
7037 }
7038 if (psk->ssid.ssid_len) {
7039 pssid_tlv = (MrvlIEtypes_SsIdParamSet_t *)ptlv_buffer;
7040 pssid_tlv->header.type =
7041 wlan_cpu_to_le16(TLV_TYPE_SSID);
7042 pssid_tlv->header.len = (t_u16)MIN(MLAN_MAX_SSID_LENGTH,
7043 psk->ssid.ssid_len);
7044 memcpy_ext(pmpriv->adapter, (t_u8 *)pssid_tlv->ssid,
7045 (t_u8 *)psk->ssid.ssid, psk->ssid.ssid_len,
7046 MLAN_MAX_SSID_LENGTH);
7047 ptlv_buffer += (pssid_tlv->header.len +
7048 sizeof(MrvlIEtypesHeader_t));
7049 cmd->size += (pssid_tlv->header.len +
7050 sizeof(MrvlIEtypesHeader_t));
7051 pssid_tlv->header.len =
7052 wlan_cpu_to_le16(pssid_tlv->header.len);
7053 ssid_flag = 1;
7054 }
7055 if (psk->psk_type == MLAN_PSK_PASSPHRASE) {
7056 ppassphrase_tlv =
7057 (MrvlIEtypes_Passphrase_t *)ptlv_buffer;
7058 ppassphrase_tlv->header.type =
7059 wlan_cpu_to_le16(TLV_TYPE_PASSPHRASE);
7060 ppassphrase_tlv->header.len =
7061 (t_u16)MIN(MLAN_MAX_PASSPHRASE_LENGTH,
7062 psk->psk.passphrase.passphrase_len);
7063 memcpy_ext(pmpriv->adapter, ppassphrase_tlv->passphrase,
7064 psk->psk.passphrase.passphrase,
7065 psk->psk.passphrase.passphrase_len,
7066 MLAN_MAX_PASSPHRASE_LENGTH);
7067 ptlv_buffer += (ppassphrase_tlv->header.len +
7068 sizeof(MrvlIEtypesHeader_t));
7069 cmd->size += (ppassphrase_tlv->header.len +
7070 sizeof(MrvlIEtypesHeader_t));
7071 ppassphrase_tlv->header.len =
7072 wlan_cpu_to_le16(ppassphrase_tlv->header.len);
7073 passphrase_flag = 1;
7074 }
7075 if (psk->psk_type == MLAN_PSK_SAE_PASSWORD) {
7076 psae_password_tlv =
7077 (MrvlIEtypes_SAE_Password_t *)ptlv_buffer;
7078 psae_password_tlv->header.type =
7079 wlan_cpu_to_le16(TLV_TYPE_SAE_PASSWORD);
7080 psae_password_tlv->header.len = (t_u16)MIN(
7081 MLAN_MAX_SAE_PASSWORD_LENGTH,
7082 psk->psk.sae_password.sae_password_len);
7083 memcpy_ext(pmpriv->adapter,
7084 psae_password_tlv->sae_password,
7085 psk->psk.sae_password.sae_password,
7086 psk->psk.sae_password.sae_password_len,
7087 MLAN_MAX_SAE_PASSWORD_LENGTH);
7088 ptlv_buffer += (psae_password_tlv->header.len +
7089 sizeof(MrvlIEtypesHeader_t));
7090 cmd->size += (psae_password_tlv->header.len +
7091 sizeof(MrvlIEtypesHeader_t));
7092 psae_password_tlv->header.len =
7093 wlan_cpu_to_le16(psae_password_tlv->header.len);
7094 sae_password_flag = 1;
7095 }
7096 if (key_tlv)
7097 key_tlv->header.len =
7098 wlan_cpu_to_le16(cmd->size - length);
7099 userset_passphrase++;
7100 psk = (mlan_ds_passphrase *)&sec->param
7101 .roam_passphrase[userset_passphrase];
7102 } while (psk && sec->multi_passphrase &&
7103 userset_passphrase < pmpriv->adapter->userset_passphrase);
7104 pmpriv->adapter->userset_passphrase = 0;
7105 if ((cmd_action == HostCmd_ACT_GEN_SET) &&
7106 ((ssid_flag || bssid_flag) && (!pmk_flag && !passphrase_flag) &&
7107 (!pmk_flag && !sae_password_flag))) {
7108 PRINTM(MERROR,
7109 "Invalid case,ssid/bssid present without pmk, passphrase or sae password\n");
7110 LEAVE();
7111 return MLAN_STATUS_FAILURE;
7112 }
7113 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_SUPPLICANT_PMK);
7114 pesupplicant_psk->action = wlan_cpu_to_le16(cmd_action);
7115 pesupplicant_psk->cache_result = 0;
7116 cmd->size = wlan_cpu_to_le16(cmd->size);
7117 LEAVE();
7118 return MLAN_STATUS_SUCCESS;
7119 }
7120
7121 /**
7122 * @brief Handle the supplicant pmk response
7123 *
7124 * @param pmpriv A pointer to mlan_private structure
7125 * @param resp A pointer to HostCmd_DS_COMMAND
7126 * @param pioctl_buf A pointer to mlan_ioctl_req structure
7127 *
7128 * @return MLAN_STATUS_SUCCESS MLAN_STATUS_FAILURE
7129 */
wlan_ret_802_11_supplicant_pmk(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)7130 mlan_status wlan_ret_802_11_supplicant_pmk(pmlan_private pmpriv,
7131 HostCmd_DS_COMMAND *resp,
7132 mlan_ioctl_req *pioctl_buf)
7133 {
7134 HostCmd_DS_802_11_SUPPLICANT_PMK *supplicant_pmk_resp =
7135 &resp->params.esupplicant_psk;
7136 mlan_ds_sec_cfg *sec_buf = MNULL;
7137 mlan_ds_sec_cfg *sec = MNULL;
7138 mlan_adapter *pmadapter = pmpriv->adapter;
7139 pmlan_callbacks pcb = &pmadapter->callbacks;
7140 MrvlIEtypes_PMK_t *ppmk_tlv = MNULL;
7141 MrvlIEtypes_Passphrase_t *passphrase_tlv = MNULL;
7142 MrvlIEtypes_SAE_Password_t *psae_password_tlv = MNULL;
7143 MrvlIEtypes_SsIdParamSet_t *pssid_tlv = MNULL;
7144 MrvlIEtypes_Bssid_t *pbssid_tlv = MNULL;
7145 t_u8 *tlv_buf = (t_u8 *)supplicant_pmk_resp->tlv_buffer;
7146 t_u16 action = wlan_le16_to_cpu(supplicant_pmk_resp->action);
7147 int tlv_buf_len = 0;
7148 t_u16 tlv;
7149 mlan_status ret = MLAN_STATUS_SUCCESS;
7150
7151 ENTER();
7152 tlv_buf_len = resp->size -
7153 (sizeof(HostCmd_DS_802_11_SUPPLICANT_PMK) + S_DS_GEN - 1);
7154
7155 if (pioctl_buf) {
7156 if (((mlan_ds_bss *)pioctl_buf->pbuf)->sub_command ==
7157 MLAN_OID_BSS_FIND_BSS) {
7158 ret = pcb->moal_malloc(pmadapter->pmoal_handle,
7159 sizeof(mlan_ds_sec_cfg),
7160 MLAN_MEM_DEF, (t_u8 **)&sec_buf);
7161 if (ret || !sec_buf) {
7162 PRINTM(MERROR, "Could not allocate sec_buf!\n");
7163 LEAVE();
7164 return ret;
7165 }
7166 sec = sec_buf;
7167 } else {
7168 sec = (mlan_ds_sec_cfg *)pioctl_buf->pbuf;
7169 }
7170 if (action == HostCmd_ACT_GEN_GET) {
7171 while (tlv_buf_len > 0) {
7172 tlv = (*tlv_buf) | (*(tlv_buf + 1) << 8);
7173 if ((tlv != TLV_TYPE_SSID) &&
7174 (tlv != TLV_TYPE_BSSID) &&
7175 (tlv != TLV_TYPE_PASSPHRASE) &&
7176 (tlv != TLV_TYPE_PMK) &&
7177 (tlv != TLV_TYPE_SAE_PASSWORD))
7178 break;
7179 switch (tlv) {
7180 case TLV_TYPE_SSID:
7181 pssid_tlv =
7182 (MrvlIEtypes_SsIdParamSet_t *)
7183 tlv_buf;
7184 pssid_tlv->header.len =
7185 wlan_le16_to_cpu(
7186 pssid_tlv->header.len);
7187 memcpy_ext(
7188 pmpriv->adapter,
7189 sec->param.passphrase.ssid.ssid,
7190 pssid_tlv->ssid,
7191 pssid_tlv->header.len,
7192 MLAN_MAX_SSID_LENGTH);
7193 sec->param.passphrase.ssid.ssid_len =
7194 MIN(MLAN_MAX_SSID_LENGTH,
7195 pssid_tlv->header.len);
7196 tlv_buf += pssid_tlv->header.len +
7197 sizeof(MrvlIEtypesHeader_t);
7198 tlv_buf_len -=
7199 (pssid_tlv->header.len +
7200 sizeof(MrvlIEtypesHeader_t));
7201 break;
7202 case TLV_TYPE_BSSID:
7203 pbssid_tlv =
7204 (MrvlIEtypes_Bssid_t *)tlv_buf;
7205 pbssid_tlv->header.len =
7206 wlan_le16_to_cpu(
7207 pbssid_tlv->header.len);
7208 memcpy_ext(pmpriv->adapter,
7209 &sec->param.passphrase.bssid,
7210 pbssid_tlv->bssid,
7211 MLAN_MAC_ADDR_LENGTH,
7212 MLAN_MAC_ADDR_LENGTH);
7213 tlv_buf += pbssid_tlv->header.len +
7214 sizeof(MrvlIEtypesHeader_t);
7215 tlv_buf_len -=
7216 (pbssid_tlv->header.len +
7217 sizeof(MrvlIEtypesHeader_t));
7218 break;
7219 case TLV_TYPE_PASSPHRASE:
7220 passphrase_tlv =
7221 (MrvlIEtypes_Passphrase_t *)
7222 tlv_buf;
7223 passphrase_tlv->header
7224 .len = wlan_le16_to_cpu(
7225 passphrase_tlv->header.len);
7226 sec->param.passphrase.psk_type =
7227 MLAN_PSK_PASSPHRASE;
7228 sec->param.passphrase.psk.passphrase
7229 .passphrase_len =
7230 passphrase_tlv->header.len;
7231 memcpy_ext(
7232 pmpriv->adapter,
7233 sec->param.passphrase.psk
7234 .passphrase.passphrase,
7235 passphrase_tlv->passphrase,
7236 passphrase_tlv->header.len,
7237 MLAN_MAX_PASSPHRASE_LENGTH);
7238 tlv_buf += passphrase_tlv->header.len +
7239 sizeof(MrvlIEtypesHeader_t);
7240 tlv_buf_len -=
7241 (passphrase_tlv->header.len +
7242 sizeof(MrvlIEtypesHeader_t));
7243 break;
7244 case TLV_TYPE_SAE_PASSWORD:
7245 psae_password_tlv =
7246 (MrvlIEtypes_SAE_Password_t *)
7247 tlv_buf;
7248 psae_password_tlv->header
7249 .len = wlan_le16_to_cpu(
7250 psae_password_tlv->header.len);
7251 sec->param.passphrase.psk_type =
7252 MLAN_PSK_SAE_PASSWORD;
7253 sec->param.passphrase.psk.sae_password
7254 .sae_password_len =
7255 psae_password_tlv->header.len;
7256 memcpy_ext(
7257 pmpriv->adapter,
7258 sec->param.passphrase.psk
7259 .sae_password
7260 .sae_password,
7261 psae_password_tlv->sae_password,
7262 psae_password_tlv->header.len,
7263 MLAN_MAX_SAE_PASSWORD_LENGTH);
7264 tlv_buf +=
7265 psae_password_tlv->header.len +
7266 sizeof(MrvlIEtypesHeader_t);
7267 tlv_buf_len -=
7268 (psae_password_tlv->header.len +
7269 sizeof(MrvlIEtypesHeader_t));
7270 break;
7271 case TLV_TYPE_PMK:
7272 ppmk_tlv = (MrvlIEtypes_PMK_t *)tlv_buf;
7273 ppmk_tlv->header.len = wlan_le16_to_cpu(
7274 ppmk_tlv->header.len);
7275 sec->param.passphrase.psk_type =
7276 MLAN_PSK_PMK;
7277 memcpy_ext(pmpriv->adapter,
7278 sec->param.passphrase.psk.pmk
7279 .pmk,
7280 ppmk_tlv->pmk,
7281 ppmk_tlv->header.len,
7282 MLAN_MAX_KEY_LENGTH);
7283 tlv_buf += ppmk_tlv->header.len +
7284 sizeof(MrvlIEtypesHeader_t);
7285 tlv_buf_len -=
7286 (ppmk_tlv->header.len +
7287 sizeof(MrvlIEtypesHeader_t));
7288 break;
7289 }
7290 }
7291 #ifdef STA_SUPPORT
7292 if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_STA &&
7293 ((mlan_ds_bss *)pioctl_buf->pbuf)->sub_command ==
7294 MLAN_OID_BSS_FIND_BSS) {
7295 wlan_set_ewpa_mode(pmpriv,
7296 &sec->param.passphrase);
7297 ret = wlan_find_bss(pmpriv, pioctl_buf);
7298 }
7299 #endif
7300
7301 } else if (action == HostCmd_ACT_GEN_SET) {
7302 PRINTM(MINFO, "Esupp PMK set: enable ewpa query\n");
7303 pmpriv->ewpa_query = MTRUE;
7304 }
7305 if (sec_buf)
7306 pcb->moal_mfree(pmadapter->pmoal_handle,
7307 (t_u8 *)sec_buf);
7308 }
7309
7310 LEAVE();
7311 return ret;
7312 }
7313
7314 /**
7315 * @brief This function prepares command of independent reset.
7316 *
7317 * @param cmd A pointer to HostCmd_DS_COMMAND structure
7318 * @param cmd_action the action: GET or SET
7319 * @param pdata_buf A pointer to data buffer
7320 * @return MLAN_STATUS_SUCCESS
7321 */
wlan_cmd_ind_rst_cfg(HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)7322 mlan_status wlan_cmd_ind_rst_cfg(HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
7323 t_void *pdata_buf)
7324 {
7325 mlan_ds_ind_rst_cfg *pdata_ind_rst = (mlan_ds_ind_rst_cfg *)pdata_buf;
7326 HostCmd_DS_INDEPENDENT_RESET_CFG *ind_rst_cfg =
7327 (HostCmd_DS_INDEPENDENT_RESET_CFG *)&cmd->params.ind_rst_cfg;
7328
7329 ENTER();
7330
7331 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_INDEPENDENT_RESET_CFG);
7332 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_INDEPENDENT_RESET_CFG) +
7333 S_DS_GEN);
7334
7335 ind_rst_cfg->action = wlan_cpu_to_le16(cmd_action);
7336 if (cmd_action == HostCmd_ACT_GEN_SET) {
7337 ind_rst_cfg->ir_mode = pdata_ind_rst->ir_mode;
7338 ind_rst_cfg->gpio_pin = pdata_ind_rst->gpio_pin;
7339 }
7340
7341 LEAVE();
7342 return MLAN_STATUS_SUCCESS;
7343 }
7344
7345 /**
7346 * @brief This function handles the command response of independent reset
7347 *
7348 * @param pmpriv A pointer to mlan_private structure
7349 * @param resp A pointer to HostCmd_DS_COMMAND
7350 * @param pioctl_buf A pointer to command buffer
7351 *
7352 * @return MLAN_STATUS_SUCCESS
7353 */
wlan_ret_ind_rst_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)7354 mlan_status wlan_ret_ind_rst_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
7355 mlan_ioctl_req *pioctl_buf)
7356 {
7357 mlan_ds_misc_cfg *misc = MNULL;
7358 const HostCmd_DS_INDEPENDENT_RESET_CFG *ind_rst_cfg =
7359 (HostCmd_DS_INDEPENDENT_RESET_CFG *)&resp->params.ind_rst_cfg;
7360
7361 ENTER();
7362
7363 if (pioctl_buf) {
7364 misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
7365
7366 if (wlan_le16_to_cpu(ind_rst_cfg->action) ==
7367 HostCmd_ACT_GEN_GET) {
7368 misc->param.ind_rst_cfg.ir_mode = ind_rst_cfg->ir_mode;
7369 misc->param.ind_rst_cfg.gpio_pin =
7370 ind_rst_cfg->gpio_pin;
7371 }
7372 }
7373
7374 LEAVE();
7375 return MLAN_STATUS_SUCCESS;
7376 }
7377
7378 /**
7379 * @brief This function prepares command of ps inactivity timeout.
7380 *
7381 * @param pmpriv A pointer to mlan_private structure
7382 * @param cmd A pointer to HostCmd_DS_COMMAND structure
7383 * @param cmd_action the action: GET or SET
7384 * @param pdata_buf A pointer to data buffer
7385 * @return MLAN_STATUS_SUCCESS
7386 */
wlan_cmd_ps_inactivity_timeout(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)7387 mlan_status wlan_cmd_ps_inactivity_timeout(pmlan_private pmpriv,
7388 HostCmd_DS_COMMAND *cmd,
7389 t_u16 cmd_action, t_void *pdata_buf)
7390 {
7391 t_u16 timeout = *((t_u16 *)pdata_buf);
7392 HostCmd_DS_802_11_PS_INACTIVITY_TIMEOUT *ps_inact_tmo =
7393 (HostCmd_DS_802_11_PS_INACTIVITY_TIMEOUT *)&cmd->params
7394 .ps_inact_tmo;
7395
7396 ENTER();
7397
7398 cmd->command =
7399 wlan_cpu_to_le16(HostCmd_CMD_802_11_PS_INACTIVITY_TIMEOUT);
7400 cmd->size = wlan_cpu_to_le16(
7401 sizeof(HostCmd_DS_802_11_PS_INACTIVITY_TIMEOUT) + S_DS_GEN);
7402
7403 ps_inact_tmo->action = wlan_cpu_to_le16(cmd_action);
7404 if (cmd_action == HostCmd_ACT_GEN_SET)
7405 ps_inact_tmo->inact_tmo = wlan_cpu_to_le16(timeout);
7406
7407 LEAVE();
7408 return MLAN_STATUS_SUCCESS;
7409 }
7410
7411 /**
7412 * @brief This function prepares command of HostCmd_CMD_GET_TSF
7413 *
7414 * @param pmpriv A pointer to mlan_private structure
7415 * @param cmd A pointer to HostCmd_DS_COMMAND structure
7416 * @param cmd_action The action: GET
7417 * @return MLAN_STATUS_SUCCESS
7418 */
wlan_cmd_get_tsf(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action)7419 mlan_status wlan_cmd_get_tsf(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
7420 t_u16 cmd_action)
7421 {
7422 ENTER();
7423
7424 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_GET_TSF);
7425 cmd->size = wlan_cpu_to_le16((sizeof(HostCmd_DS_TSF)) + S_DS_GEN);
7426
7427 LEAVE();
7428 return MLAN_STATUS_SUCCESS;
7429 }
7430
7431 /**
7432 * @brief This function handles the command response of HostCmd_CMD_GET_TSF
7433 *
7434 * @param pmpriv A pointer to mlan_private structure
7435 * @param resp A pointer to HostCmd_DS_COMMAND
7436 * @param pioctl_buf A pointer to mlan_ioctl_req structure
7437 *
7438 * @return MLAN_STATUS_SUCCESS
7439 */
wlan_ret_get_tsf(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)7440 mlan_status wlan_ret_get_tsf(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
7441 mlan_ioctl_req *pioctl_buf)
7442 {
7443 mlan_ds_misc_cfg *misc_cfg = MNULL;
7444 HostCmd_DS_TSF *tsf_pointer = (HostCmd_DS_TSF *)&resp->params.tsf;
7445
7446 ENTER();
7447 if (pioctl_buf) {
7448 misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
7449 misc_cfg->param.misc_tsf = wlan_le64_to_cpu(tsf_pointer->tsf);
7450 }
7451
7452 LEAVE();
7453 return MLAN_STATUS_SUCCESS;
7454 }
7455
7456 /**
7457 * @brief This function handles the command response of chan_region_cfg
7458 *
7459 * @param pmpriv A pointer to mlan_private structure
7460 * @param resp A pointer to HostCmd_DS_COMMAND
7461 * @param pioctl_buf A pointer to command buffer
7462 *
7463 * @return MLAN_STATUS_SUCCESS
7464 */
wlan_ret_chan_region_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)7465 mlan_status wlan_ret_chan_region_cfg(pmlan_private pmpriv,
7466 HostCmd_DS_COMMAND *resp,
7467 mlan_ioctl_req *pioctl_buf)
7468 {
7469 mlan_adapter *pmadapter = pmpriv->adapter;
7470 t_u16 action;
7471 HostCmd_DS_CHAN_REGION_CFG *reg = MNULL;
7472 t_u8 *tlv_buf = MNULL;
7473 t_u16 tlv_buf_left;
7474 mlan_ds_misc_cfg *misc_cfg = MNULL;
7475 mlan_ds_misc_chnrgpwr_cfg *cfg = MNULL;
7476 mlan_status ret = MLAN_STATUS_SUCCESS;
7477
7478 ENTER();
7479
7480 reg = (HostCmd_DS_CHAN_REGION_CFG *)&resp->params.reg_cfg;
7481 if (!reg) {
7482 ret = MLAN_STATUS_FAILURE;
7483 goto done;
7484 }
7485
7486 action = wlan_le16_to_cpu(reg->action);
7487 if (action != HostCmd_ACT_GEN_GET) {
7488 ret = MLAN_STATUS_FAILURE;
7489 goto done;
7490 }
7491
7492 tlv_buf = (t_u8 *)reg + sizeof(*reg);
7493 tlv_buf_left = wlan_le16_to_cpu(resp->size) - S_DS_GEN - sizeof(*reg);
7494
7495 /* Add FW cfp tables and region info */
7496 wlan_add_fw_cfp_tables(pmpriv, tlv_buf, tlv_buf_left);
7497 if (pmadapter->otp_region) {
7498 wlan_set_regiontable(pmpriv, (t_u8)pmadapter->region_code,
7499 pmadapter->fw_bands);
7500 }
7501 if (!pioctl_buf)
7502 goto done;
7503
7504 if (!pioctl_buf->pbuf) {
7505 ret = MLAN_STATUS_FAILURE;
7506 goto done;
7507 }
7508
7509 misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
7510
7511 if (misc_cfg->sub_command == MLAN_OID_MISC_GET_REGIONPWR_CFG) {
7512 cfg = (mlan_ds_misc_chnrgpwr_cfg *)&(
7513 misc_cfg->param.rgchnpwr_cfg);
7514 cfg->length = wlan_le16_to_cpu(resp->size);
7515 memcpy_ext(pmpriv->adapter, cfg->chnrgpwr_buf, (t_u8 *)resp,
7516 cfg->length, sizeof(cfg->chnrgpwr_buf));
7517 } else {
7518 memset(pmpriv->adapter, &misc_cfg->param.custom_reg_domain, 0,
7519 sizeof(mlan_ds_custom_reg_domain));
7520 if (pmadapter->otp_region)
7521 memcpy_ext(pmpriv->adapter,
7522 &misc_cfg->param.custom_reg_domain.region,
7523 pmadapter->otp_region,
7524 sizeof(otp_region_info_t),
7525 sizeof(otp_region_info_t));
7526 if (pmadapter->cfp_otp_bg) {
7527 misc_cfg->param.custom_reg_domain.num_bg_chan =
7528 pmadapter->tx_power_table_bg_rows;
7529 memcpy_ext(pmpriv->adapter,
7530 (t_u8 *)misc_cfg->param.custom_reg_domain
7531 .cfp_tbl,
7532 (t_u8 *)pmadapter->cfp_otp_bg,
7533 pmadapter->tx_power_table_bg_rows *
7534 sizeof(chan_freq_power_t),
7535 pmadapter->tx_power_table_bg_rows *
7536 sizeof(chan_freq_power_t));
7537 }
7538 if (pmadapter->cfp_otp_a) {
7539 misc_cfg->param.custom_reg_domain.num_a_chan =
7540 pmadapter->tx_power_table_a_rows;
7541 memcpy_ext(pmpriv->adapter,
7542 (t_u8 *)misc_cfg->param.custom_reg_domain
7543 .cfp_tbl +
7544 pmadapter->tx_power_table_bg_rows *
7545 sizeof(chan_freq_power_t),
7546 (t_u8 *)pmadapter->cfp_otp_a,
7547 pmadapter->tx_power_table_a_rows *
7548 sizeof(chan_freq_power_t),
7549 pmadapter->tx_power_table_a_rows *
7550 sizeof(chan_freq_power_t));
7551 }
7552 }
7553 done:
7554 LEAVE();
7555 return ret;
7556 }
7557
7558 /**
7559 * @brief This function prepares command of packet aggragation
7560 *
7561 * @param pmpriv A pointer to mlan_private structure
7562 * @param cmd A pointer to HostCmd_DS_COMMAND structure
7563 * @param cmd_action the action: GET or SET
7564 * @param pdata_buf A pointer to data buffer
7565 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
7566 */
wlan_cmd_packet_aggr_ctrl(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)7567 mlan_status wlan_cmd_packet_aggr_ctrl(pmlan_private pmpriv,
7568 HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
7569 t_void *pdata_buf)
7570 {
7571 HostCmd_DS_PACKET_AGGR_CTRL *aggr_ctrl = &cmd->params.aggr_ctrl;
7572 mlan_ds_misc_aggr_ctrl *aggr = (mlan_ds_misc_aggr_ctrl *)pdata_buf;
7573
7574 ENTER();
7575
7576 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_PACKET_AGGR_CTRL);
7577 aggr_ctrl->action = wlan_cpu_to_le16(cmd_action);
7578 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_PACKET_AGGR_CTRL) +
7579 S_DS_GEN);
7580 aggr_ctrl->aggr_enable = 0;
7581
7582 if (aggr->tx.enable)
7583 aggr_ctrl->aggr_enable |= MBIT(0);
7584 aggr_ctrl->aggr_enable = wlan_cpu_to_le16(aggr_ctrl->aggr_enable);
7585
7586 LEAVE();
7587 return MLAN_STATUS_SUCCESS;
7588 }
7589
7590 /**
7591 * @brief This function handles the command response of
7592 * packet aggregation
7593 *
7594 * @param pmpriv A pointer to mlan_private structure
7595 * @param resp A pointer to HostCmd_DS_COMMAND
7596 * @param pioctl_buf A pointer to command buffer
7597 *
7598 * @return MLAN_STATUS_SUCCESS
7599 */
wlan_ret_packet_aggr_ctrl(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)7600 mlan_status wlan_ret_packet_aggr_ctrl(pmlan_private pmpriv,
7601 HostCmd_DS_COMMAND *resp,
7602 mlan_ioctl_req *pioctl_buf)
7603 {
7604 mlan_ds_misc_cfg *misc = MNULL;
7605 HostCmd_DS_PACKET_AGGR_CTRL *aggr_ctrl = &resp->params.aggr_ctrl;
7606 mlan_ds_misc_aggr_ctrl *aggr = MNULL;
7607 #if defined(USB)
7608 mlan_adapter *pmadapter = pmpriv->adapter;
7609 t_u8 i;
7610 t_u8 change = 0;
7611 usb_tx_aggr_params *pusb_tx_aggr = MNULL;
7612 #endif
7613
7614 ENTER();
7615
7616 aggr_ctrl->aggr_enable = wlan_le16_to_cpu(aggr_ctrl->aggr_enable);
7617 aggr_ctrl->tx_aggr_max_size =
7618 wlan_le16_to_cpu(aggr_ctrl->tx_aggr_max_size);
7619 aggr_ctrl->tx_aggr_max_num =
7620 wlan_le16_to_cpu(aggr_ctrl->tx_aggr_max_num);
7621 aggr_ctrl->tx_aggr_align = wlan_le16_to_cpu(aggr_ctrl->tx_aggr_align);
7622 PRINTM(MCMND, "enable=0x%x, tx_size=%d, tx_num=%d, tx_align=%d\n",
7623 aggr_ctrl->aggr_enable, aggr_ctrl->tx_aggr_max_size,
7624 aggr_ctrl->tx_aggr_max_num, aggr_ctrl->tx_aggr_align);
7625 #if defined(USB)
7626 if (IS_USB(pmadapter->card_type)) {
7627 if (aggr_ctrl->aggr_enable & MBIT(0)) {
7628 if (!pmadapter->pcard_usb->usb_tx_aggr[0]
7629 .aggr_ctrl.enable) {
7630 pmadapter->pcard_usb->usb_tx_aggr[0]
7631 .aggr_ctrl.enable = MTRUE;
7632 change = MTRUE;
7633 }
7634
7635 } else {
7636 if (pmadapter->pcard_usb->usb_tx_aggr[0]
7637 .aggr_ctrl.enable) {
7638 pmadapter->pcard_usb->usb_tx_aggr[0]
7639 .aggr_ctrl.enable = MFALSE;
7640 change = MTRUE;
7641 }
7642 }
7643 pmadapter->pcard_usb->usb_tx_aggr[0].aggr_ctrl.aggr_mode =
7644 MLAN_USB_AGGR_MODE_LEN_V2;
7645 pmadapter->pcard_usb->usb_tx_aggr[0].aggr_ctrl.aggr_align =
7646 aggr_ctrl->tx_aggr_align;
7647 pmadapter->pcard_usb->usb_tx_aggr[0].aggr_ctrl.aggr_max =
7648 aggr_ctrl->tx_aggr_max_size;
7649 pmadapter->pcard_usb->usb_tx_aggr[0].aggr_ctrl.aggr_tmo =
7650 MLAN_USB_TX_AGGR_TIMEOUT_MSEC * 1000;
7651 if (change) {
7652 wlan_reset_usb_tx_aggr(pmadapter);
7653 for (i = 0; i < pmadapter->priv_num; ++i) {
7654 if (pmadapter->priv[i]) {
7655 pusb_tx_aggr =
7656 wlan_get_usb_tx_aggr_params(
7657 pmadapter,
7658 pmadapter->priv[i]
7659 ->port);
7660 if (pusb_tx_aggr &&
7661 pusb_tx_aggr->aggr_ctrl.aggr_mode ==
7662 MLAN_USB_AGGR_MODE_LEN_V2)
7663 pmadapter->priv[i]->intf_hr_len =
7664 MLAN_USB_TX_AGGR_HEADER;
7665 else
7666 pmadapter->priv[i]->intf_hr_len =
7667 USB_INTF_HEADER_LEN;
7668 }
7669 }
7670 }
7671 }
7672 #endif
7673 if (pioctl_buf) {
7674 misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
7675 aggr = (mlan_ds_misc_aggr_ctrl *)&(misc->param.aggr_params);
7676 if (aggr_ctrl->aggr_enable & MBIT(0))
7677 aggr->tx.enable = MTRUE;
7678 else
7679 aggr->tx.enable = MFALSE;
7680 aggr->tx.aggr_align = aggr_ctrl->tx_aggr_align;
7681 aggr->tx.aggr_max_size = aggr_ctrl->tx_aggr_max_size;
7682 aggr->tx.aggr_max_num = aggr_ctrl->tx_aggr_max_num;
7683 #if defined(USB)
7684 if (IS_USB(pmadapter->card_type))
7685 aggr->tx.aggr_tmo = pmadapter->pcard_usb->usb_tx_aggr[0]
7686 .aggr_ctrl.aggr_tmo;
7687 #endif
7688 }
7689 LEAVE();
7690 return MLAN_STATUS_SUCCESS;
7691 }
7692
7693 /**
7694 * @brief This function sends fw dump event command to firmware.
7695 *
7696 * @param pmpriv A pointer to mlan_private structure
7697 * @param cmd Hostcmd ID
7698 * @param cmd_action Command action
7699 * @param pdata_buf A void pointer to information buffer
7700 * @return N/A
7701 */
wlan_cmd_fw_dump_event(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)7702 mlan_status wlan_cmd_fw_dump_event(pmlan_private pmpriv,
7703 HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
7704 t_void *pdata_buf)
7705 {
7706 ENTER();
7707
7708 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_FW_DUMP_EVENT);
7709 cmd->size = S_DS_GEN;
7710 cmd->size = wlan_cpu_to_le16(cmd->size);
7711
7712 LEAVE();
7713 return MLAN_STATUS_SUCCESS;
7714 }
7715
7716 /**
7717 * @brief This function prepares command of get link layer statistics.
7718 *
7719 * @param pmpriv A pointer to mlan_private structure
7720 * @param cmd A pointer to HostCmd_DS_COMMAND structure
7721 * @param cmd_action the action: GET or SET
7722 * @param pdata_buf A pointer to data buffer
7723 *
7724 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
7725 *
7726 */
wlan_cmd_802_11_link_statistic(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,mlan_ioctl_req * pioctl_buf)7727 mlan_status wlan_cmd_802_11_link_statistic(pmlan_private pmpriv,
7728 HostCmd_DS_COMMAND *cmd,
7729 t_u16 cmd_action,
7730 mlan_ioctl_req *pioctl_buf)
7731 {
7732 mlan_ds_get_info *info = (mlan_ds_get_info *)(pioctl_buf->pbuf);
7733 HostCmd_DS_802_11_LINK_STATISTIC *ll_stat =
7734 &cmd->params.get_link_statistic;
7735 wifi_link_layer_params *ll_params = MNULL;
7736
7737 ENTER();
7738
7739 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_LINK_STATS);
7740 cmd->size = wlan_cpu_to_le16(S_DS_GEN +
7741 sizeof(HostCmd_DS_802_11_LINK_STATISTIC));
7742 ll_stat->action = wlan_cpu_to_le16(cmd_action);
7743
7744 switch (cmd_action) {
7745 case HostCmd_ACT_GEN_SET:
7746 ll_params =
7747 (wifi_link_layer_params *)info->param.link_statistic;
7748 ll_stat->mpdu_size_threshold =
7749 wlan_cpu_to_le32(ll_params->mpdu_size_threshold);
7750 ll_stat->aggressive_statistics_gathering = wlan_cpu_to_le32(
7751 ll_params->aggressive_statistics_gathering);
7752 break;
7753 case HostCmd_ACT_GEN_GET:
7754 /** ll_stat->stat_type = wlan_cpu_to_le16(stat_type); */
7755 break;
7756 default:
7757 break;
7758 }
7759
7760 LEAVE();
7761 return MLAN_STATUS_SUCCESS;
7762 }
7763
7764 /**
7765 * @brief This function fill link layer statistic from firmware
7766 *
7767 * @param priv A pointer to
7768 * mlan_private structure
7769 * @param link_statistic_ioctl_buf, A pointer to fill ioctl buffer
7770 * @param resp A pointer to
7771 * HostCmd_DS_COMMAND
7772 *
7773 * @return MLAN_STATUS_SUCCESS
7774 */
wlan_fill_link_statistic(mlan_private * priv,char * link_statistic_ioctl_buf,HostCmd_DS_COMMAND * resp)7775 static void wlan_fill_link_statistic(mlan_private *priv,
7776 char *link_statistic_ioctl_buf,
7777 HostCmd_DS_COMMAND *resp)
7778 {
7779 char *link_statistic = link_statistic_ioctl_buf;
7780 wifi_radio_stat *radio_stat = MNULL;
7781 wifi_iface_stat *iface_stat = MNULL;
7782 mlan_wifi_iface_stat *fw_ifaceStat = MNULL;
7783 mlan_wifi_radio_stat *fw_radioStat = MNULL;
7784 t_u32 num_radio = 0;
7785 int i = 0, chan_idx = 0, peerIdx = 0, rate_idx = 0;
7786 t_u16 left_len = 0, tlv_type = 0, tlv_len = 0;
7787 MrvlIEtypesHeader_t *tlv = MNULL;
7788 HostCmd_DS_802_11_LINK_STATISTIC *plink_stat =
7789 (HostCmd_DS_802_11_LINK_STATISTIC *)&resp->params
7790 .get_link_statistic;
7791
7792 /* TLV parse */
7793 if (resp->size > (sizeof(HostCmd_DS_802_11_LINK_STATISTIC) - S_DS_GEN))
7794 left_len = resp->size -
7795 sizeof(HostCmd_DS_802_11_LINK_STATISTIC) - S_DS_GEN;
7796
7797 tlv = (MrvlIEtypesHeader_t *)(plink_stat->value);
7798 DBG_HEXDUMP(MDAT_D, "tlv:", (void *)tlv, 1024);
7799 while (left_len > sizeof(MrvlIEtypesHeader_t)) {
7800 tlv_type = wlan_le16_to_cpu(tlv->type);
7801 tlv_len = wlan_le16_to_cpu(tlv->len);
7802 switch (tlv_type) {
7803 case TLV_TYPE_LL_STAT_IFACE:
7804 fw_ifaceStat = (mlan_wifi_iface_stat
7805 *)((t_u8 *)tlv +
7806 sizeof(MrvlIEtypesHeader_t));
7807 break;
7808 case TLV_TYPE_LL_STAT_RADIO:
7809 fw_radioStat = (mlan_wifi_radio_stat
7810 *)((t_u8 *)tlv +
7811 sizeof(MrvlIEtypesHeader_t));
7812 num_radio = MAX_RADIO;
7813 break;
7814 default:
7815 break;
7816 }
7817 left_len -= (sizeof(MrvlIEtypesHeader_t) + tlv_len);
7818 tlv = (MrvlIEtypesHeader_t *)((t_u8 *)tlv + tlv_len +
7819 sizeof(MrvlIEtypesHeader_t));
7820 }
7821
7822 if (!fw_ifaceStat || !fw_radioStat) {
7823 PRINTM(MERROR, "!fw_ifaceStat || !fw_radioStat\n");
7824 return;
7825 }
7826
7827 *((t_u32 *)link_statistic) = num_radio;
7828 link_statistic += sizeof(num_radio);
7829
7830 /* Fill radio stats array*/
7831 for (i = 0; i < num_radio; i++) {
7832 radio_stat = (wifi_radio_stat *)link_statistic;
7833 link_statistic += sizeof(wifi_radio_stat);
7834
7835 radio_stat->radio = wlan_le32_to_cpu(fw_radioStat[i].radio);
7836
7837 radio_stat->on_time = wlan_le32_to_cpu(fw_radioStat[i].on_time);
7838 radio_stat->tx_time = wlan_le32_to_cpu(fw_radioStat[i].tx_time);
7839 radio_stat->reserved0 =
7840 wlan_le32_to_cpu(fw_radioStat[i].reserved0);
7841 radio_stat->rx_time = wlan_le32_to_cpu(fw_radioStat[i].rx_time);
7842 radio_stat->on_time_scan =
7843 wlan_le32_to_cpu(fw_radioStat[i].on_time_scan);
7844 radio_stat->on_time_nbd =
7845 wlan_le32_to_cpu(fw_radioStat[i].on_time_nbd);
7846 radio_stat->on_time_gscan =
7847 wlan_le32_to_cpu(fw_radioStat[i].on_time_gscan);
7848 radio_stat->on_time_roam_scan =
7849 wlan_le32_to_cpu(fw_radioStat[i].on_time_roam_scan);
7850 radio_stat->on_time_pno_scan =
7851 wlan_le32_to_cpu(fw_radioStat[i].on_time_pno_scan);
7852 radio_stat->on_time_hs20 =
7853 wlan_le32_to_cpu(fw_radioStat[i].on_time_hs20);
7854
7855 radio_stat->num_channels =
7856 wlan_le32_to_cpu(fw_radioStat[i].num_channels);
7857 for (chan_idx = 0; chan_idx < radio_stat->num_channels;
7858 chan_idx++) {
7859 if (radio_stat->num_channels > MAX_NUM_CHAN) {
7860 radio_stat->num_channels =
7861 wlan_le32_to_cpu(MAX_NUM_CHAN);
7862 PRINTM(MERROR,
7863 "%s : radio_stat->num_channels=%d\n",
7864 __func__, radio_stat->num_channels);
7865 break;
7866 }
7867 radio_stat->channels[chan_idx].channel.width =
7868 wlan_le32_to_cpu(fw_radioStat[i]
7869 .channels[chan_idx]
7870 .channel.width);
7871 radio_stat->channels[chan_idx].channel.center_freq =
7872 wlan_le32_to_cpu(fw_radioStat[i]
7873 .channels[chan_idx]
7874 .channel.center_freq);
7875 radio_stat->channels[chan_idx].channel.center_freq0 =
7876 wlan_le32_to_cpu(fw_radioStat[i]
7877 .channels[chan_idx]
7878 .channel.center_freq0);
7879 radio_stat->channels[chan_idx].channel.center_freq1 =
7880 wlan_le32_to_cpu(fw_radioStat[i]
7881 .channels[chan_idx]
7882 .channel.center_freq1);
7883
7884 radio_stat->channels[chan_idx]
7885 .on_time = wlan_le32_to_cpu(
7886 fw_radioStat[i].channels[chan_idx].on_time);
7887 radio_stat->channels[chan_idx].cca_busy_time =
7888 wlan_le32_to_cpu(fw_radioStat[i]
7889 .channels[chan_idx]
7890 .cca_busy_time);
7891 }
7892 }
7893
7894 /* Fill iface stats*/
7895 iface_stat = (wifi_iface_stat *)link_statistic;
7896
7897 /* get wifi_interface_link_layer_info in driver, not in firmware */
7898 if (priv->bss_role == MLAN_BSS_ROLE_STA) {
7899 iface_stat->info.mode = MLAN_INTERFACE_STA;
7900 if (priv->media_connected)
7901 iface_stat->info.state = MLAN_ASSOCIATING;
7902 else
7903 iface_stat->info.state = MLAN_DISCONNECTED;
7904 iface_stat->info.roaming = MLAN_ROAMING_IDLE;
7905 iface_stat->info.capabilities = MLAN_CAPABILITY_QOS;
7906 memcpy_ext(priv->adapter, iface_stat->info.ssid,
7907 priv->curr_bss_params.bss_descriptor.ssid.ssid,
7908 MLAN_MAX_SSID_LENGTH, MLAN_MAX_SSID_LENGTH);
7909 memcpy_ext(priv->adapter, iface_stat->info.bssid,
7910 priv->curr_bss_params.bss_descriptor.mac_address,
7911 MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
7912 } else {
7913 iface_stat->info.mode = MLAN_INTERFACE_SOFTAP;
7914 iface_stat->info.capabilities = MLAN_CAPABILITY_QOS;
7915 }
7916 memcpy_ext(priv->adapter, iface_stat->info.mac_addr, priv->curr_addr,
7917 MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
7918 memcpy_ext(priv->adapter, iface_stat->info.ap_country_str,
7919 priv->adapter->country_code, COUNTRY_CODE_LEN,
7920 COUNTRY_CODE_LEN);
7921 memcpy_ext(priv->adapter, iface_stat->info.country_str,
7922 priv->adapter->country_code, COUNTRY_CODE_LEN,
7923 COUNTRY_CODE_LEN);
7924
7925 iface_stat->beacon_rx = wlan_le32_to_cpu(fw_ifaceStat->beacon_rx);
7926 iface_stat->average_tsf_offset =
7927 wlan_le64_to_cpu(fw_ifaceStat->average_tsf_offset);
7928 iface_stat->leaky_ap_detected =
7929 wlan_le32_to_cpu(fw_ifaceStat->leaky_ap_detected);
7930 iface_stat->leaky_ap_avg_num_frames_leaked =
7931 wlan_le32_to_cpu(fw_ifaceStat->leaky_ap_avg_num_frames_leaked);
7932 iface_stat->leaky_ap_guard_time =
7933 wlan_le32_to_cpu(fw_ifaceStat->leaky_ap_guard_time);
7934
7935 /* Value of iface_stat should be Reaccumulate by each peer */
7936 iface_stat->mgmt_rx = wlan_le32_to_cpu(fw_ifaceStat->mgmt_rx);
7937 iface_stat->mgmt_action_rx =
7938 wlan_le32_to_cpu(fw_ifaceStat->mgmt_action_rx);
7939 iface_stat->mgmt_action_tx =
7940 wlan_le32_to_cpu(fw_ifaceStat->mgmt_action_tx);
7941
7942 iface_stat->rssi_mgmt = wlan_le32_to_cpu(fw_ifaceStat->rssi_mgmt);
7943 iface_stat->rssi_data = wlan_le32_to_cpu(fw_ifaceStat->rssi_data);
7944 iface_stat->rssi_ack = wlan_le32_to_cpu(fw_ifaceStat->rssi_ack);
7945
7946 for (i = WMM_AC_BK; i <= WMM_AC_VO; i++) {
7947 iface_stat->ac[i].ac = i;
7948 iface_stat->ac[i].tx_mpdu =
7949 wlan_le32_to_cpu(fw_ifaceStat->ac[i].tx_mpdu);
7950 iface_stat->ac[i].rx_mpdu =
7951 wlan_le32_to_cpu(fw_ifaceStat->ac[i].rx_mpdu);
7952 iface_stat->ac[i].tx_mcast =
7953 wlan_le32_to_cpu(fw_ifaceStat->ac[i].tx_mcast);
7954 iface_stat->ac[i].rx_mcast =
7955 wlan_le32_to_cpu(fw_ifaceStat->ac[i].rx_mcast);
7956 iface_stat->ac[i].rx_ampdu =
7957 wlan_le32_to_cpu(fw_ifaceStat->ac[i].rx_ampdu);
7958 iface_stat->ac[i].tx_ampdu =
7959 wlan_le32_to_cpu(fw_ifaceStat->ac[i].tx_ampdu);
7960 iface_stat->ac[i].mpdu_lost =
7961 wlan_le32_to_cpu(fw_ifaceStat->ac[i].mpdu_lost);
7962 iface_stat->ac[i].retries =
7963 wlan_le32_to_cpu(fw_ifaceStat->ac[i].retries);
7964 iface_stat->ac[i].retries_short =
7965 wlan_le32_to_cpu(fw_ifaceStat->ac[i].retries_short);
7966 iface_stat->ac[i].retries_long =
7967 wlan_le32_to_cpu(fw_ifaceStat->ac[i].retries_long);
7968 iface_stat->ac[i].contention_time_min = wlan_le32_to_cpu(
7969 fw_ifaceStat->ac[i].contention_time_min);
7970 iface_stat->ac[i].contention_time_max = wlan_le32_to_cpu(
7971 fw_ifaceStat->ac[i].contention_time_max);
7972 iface_stat->ac[i].contention_time_avg = wlan_le32_to_cpu(
7973 fw_ifaceStat->ac[i].contention_time_avg);
7974 iface_stat->ac[i].contention_num_samples = wlan_le32_to_cpu(
7975 fw_ifaceStat->ac[i].contention_num_samples);
7976 }
7977
7978 /* LL_STAT V3: STA-solution: support maxium 1 peers for AP*/
7979 iface_stat->num_peers = wlan_le32_to_cpu(fw_ifaceStat->num_peers);
7980 for (peerIdx = 0; peerIdx < iface_stat->num_peers; peerIdx++) {
7981 iface_stat->peer_info[peerIdx].type =
7982 fw_ifaceStat->peer_info[peerIdx].type;
7983 memcpy_ext(priv->adapter,
7984 iface_stat->peer_info[peerIdx].peer_mac_address,
7985 fw_ifaceStat->peer_info[peerIdx].peer_mac_address,
7986 MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
7987 iface_stat->peer_info[peerIdx].capabilities = wlan_le32_to_cpu(
7988 fw_ifaceStat->peer_info[peerIdx].capabilities);
7989 iface_stat->peer_info[peerIdx].num_rate = wlan_le32_to_cpu(
7990 fw_ifaceStat->peer_info[peerIdx].num_rate);
7991
7992 PRINTM(MINFO,
7993 "bitrate tx_mpdu rx_mpdu mpdu_lost retries retries_short retries_long\n");
7994 for (rate_idx = 0;
7995 rate_idx < iface_stat->peer_info[peerIdx].num_rate;
7996 rate_idx++) {
7997 wlan_fill_hal_wifi_rate(priv,
7998 &fw_ifaceStat
7999 ->peer_info[peerIdx]
8000 .rate_stats[rate_idx]
8001 .rate,
8002 &iface_stat->peer_info[peerIdx]
8003 .rate_stats[rate_idx]
8004 .rate);
8005
8006 iface_stat->peer_info[peerIdx]
8007 .rate_stats[rate_idx]
8008 .tx_mpdu = wlan_le32_to_cpu(
8009 fw_ifaceStat->peer_info[peerIdx]
8010 .rate_stats[rate_idx]
8011 .tx_mpdu);
8012 iface_stat->peer_info[peerIdx]
8013 .rate_stats[rate_idx]
8014 .rx_mpdu = wlan_le32_to_cpu(
8015 fw_ifaceStat->peer_info[peerIdx]
8016 .rate_stats[rate_idx]
8017 .rx_mpdu);
8018 iface_stat->peer_info[peerIdx]
8019 .rate_stats[rate_idx]
8020 .mpdu_lost = wlan_le32_to_cpu(
8021 fw_ifaceStat->peer_info[peerIdx]
8022 .rate_stats[rate_idx]
8023 .mpdu_lost);
8024 iface_stat->peer_info[peerIdx]
8025 .rate_stats[rate_idx]
8026 .retries = wlan_le32_to_cpu(
8027 fw_ifaceStat->peer_info[peerIdx]
8028 .rate_stats[rate_idx]
8029 .retries);
8030 iface_stat->peer_info[peerIdx]
8031 .rate_stats[rate_idx]
8032 .retries_short = wlan_le32_to_cpu(
8033 fw_ifaceStat->peer_info[peerIdx]
8034 .rate_stats[rate_idx]
8035 .retries_short);
8036 iface_stat->peer_info[peerIdx]
8037 .rate_stats[rate_idx]
8038 .retries_long = wlan_le32_to_cpu(
8039 fw_ifaceStat->peer_info[peerIdx]
8040 .rate_stats[rate_idx]
8041 .retries_long);
8042 PRINTM(MDAT_D,
8043 "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
8044 iface_stat->peer_info[peerIdx]
8045 .rate_stats[rate_idx]
8046 .rate.bitrate,
8047 iface_stat->peer_info[peerIdx]
8048 .rate_stats[rate_idx]
8049 .tx_mpdu,
8050 iface_stat->peer_info[peerIdx]
8051 .rate_stats[rate_idx]
8052 .rx_mpdu,
8053 iface_stat->peer_info[peerIdx]
8054 .rate_stats[rate_idx]
8055 .mpdu_lost,
8056 iface_stat->peer_info[peerIdx]
8057 .rate_stats[rate_idx]
8058 .retries,
8059 iface_stat->peer_info[peerIdx]
8060 .rate_stats[rate_idx]
8061 .retries_short,
8062 iface_stat->peer_info[peerIdx]
8063 .rate_stats[rate_idx]
8064 .retries_long);
8065 }
8066 }
8067 }
8068
8069 /**
8070 * @brief This function handles the command response of get_link_statistic
8071 *
8072 * @param pmpriv A pointer to mlan_private structure
8073 * @param resp A pointer to HostCmd_DS_COMMAND
8074 * @param pioctl_buf A pointer to mlan_ioctl_req structure
8075 *
8076 * @return MLAN_STATUS_SUCCESS
8077 */
wlan_ret_get_link_statistic(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)8078 mlan_status wlan_ret_get_link_statistic(pmlan_private pmpriv,
8079 HostCmd_DS_COMMAND *resp,
8080 mlan_ioctl_req *pioctl_buf)
8081 {
8082 mlan_ds_get_info *info;
8083 t_u8 *link_statistic = MNULL;
8084 t_u16 action = wlan_le16_to_cpu(resp->params.get_link_statistic.action);
8085
8086 ENTER();
8087
8088 if (pioctl_buf) {
8089 info = (mlan_ds_get_info *)pioctl_buf->pbuf;
8090 link_statistic = info->param.link_statistic;
8091
8092 switch (action) {
8093 case HostCmd_ACT_GEN_GET:
8094 wlan_fill_link_statistic(pmpriv, link_statistic, resp);
8095 break;
8096 case HostCmd_ACT_GEN_SET:
8097 case HostCmd_ACT_GEN_REMOVE:
8098 /* nothing to do */
8099 break;
8100 default:
8101 break;
8102 }
8103 /* Indicate ioctl complete */
8104 pioctl_buf->data_read_written =
8105 BUF_MAXLEN + MLAN_SUB_COMMAND_SIZE;
8106 }
8107
8108 LEAVE();
8109 return MLAN_STATUS_SUCCESS;
8110 }
8111
8112 /**
8113 * @brief This function sends boot sleep configure command to firmware.
8114 *
8115 * @param pmpriv A pointer to mlan_private structure
8116 * @param cmd Hostcmd ID
8117 * @param cmd_action Command action
8118 * @param pdata_buf A void pointer to information buffer
8119 * @return MLAN_STATUS_SUCCESS/ MLAN_STATUS_FAILURE
8120 */
wlan_cmd_boot_sleep(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)8121 mlan_status wlan_cmd_boot_sleep(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
8122 t_u16 cmd_action, t_void *pdata_buf)
8123 {
8124 HostCmd_DS_BOOT_SLEEP *boot_sleep = MNULL;
8125 t_u16 enable = *(t_u16 *)pdata_buf;
8126
8127 ENTER();
8128
8129 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_BOOT_SLEEP);
8130 boot_sleep = &cmd->params.boot_sleep;
8131 boot_sleep->action = wlan_cpu_to_le16(cmd_action);
8132 boot_sleep->enable = wlan_cpu_to_le16(enable);
8133
8134 cmd->size = S_DS_GEN + sizeof(HostCmd_DS_BOOT_SLEEP);
8135
8136 LEAVE();
8137 return MLAN_STATUS_SUCCESS;
8138 }
8139
8140 /**
8141 * @brief This function handles the command response of boot sleep cfg
8142 *
8143 * @param pmpriv A pointer to mlan_private structure
8144 * @param resp A pointer to HostCmd_DS_COMMAND
8145 * @param pioctl_buf A pointer to mlan_ioctl_req structure
8146 *
8147 * @return MLAN_STATUS_SUCCESS
8148 */
wlan_ret_boot_sleep(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)8149 mlan_status wlan_ret_boot_sleep(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
8150 mlan_ioctl_req *pioctl_buf)
8151 {
8152 HostCmd_DS_BOOT_SLEEP *boot_sleep = &resp->params.boot_sleep;
8153 mlan_ds_misc_cfg *cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
8154
8155 ENTER();
8156
8157 cfg->param.boot_sleep = wlan_le16_to_cpu(boot_sleep->enable);
8158 PRINTM(MCMND, "boot sleep cfg status %u", cfg->param.boot_sleep);
8159
8160 LEAVE();
8161 return MLAN_STATUS_SUCCESS;
8162 }
8163
8164 #if defined(DRV_EMBEDDED_AUTHENTICATOR) || defined(DRV_EMBEDDED_SUPPLICANT)
8165
8166 /**
8167 * @brief This function handles send crypto command
8168 *
8169 * @param pmpriv A pointer to mlan_private structure
8170 * @param cmd Hostcmd ID
8171 * @param cmd_action Command action
8172 * @param pdata_buf A void pointer to information buffer
8173 *
8174 * @return MLAN_STATUS_SUCCESS
8175 */
wlan_cmd_crypto(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_u16 * pdata_buf)8176 mlan_status wlan_cmd_crypto(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
8177 t_u16 cmd_action, t_u16 *pdata_buf)
8178 {
8179 HostCmd_DS_CRYPTO *cry_cmd = &cmd->params.crypto_cmd;
8180 mlan_ds_sup_cfg *cfg = (mlan_ds_sup_cfg *)pdata_buf;
8181 #if defined(DRV_EMBEDDED_AUTHENTICATOR) || defined(DRV_EMBEDDED_SUPPLICANT)
8182 subcmd_prf_hmac_sha1_t *prf_hmac_sha1 = MNULL;
8183 subcmd_hmac_sha1_t *hmac_sha1 = MNULL;
8184 subcmd_hmac_sha256_t *hmac_sha256 = MNULL;
8185 subcmd_sha256_t *sha256 = MNULL;
8186 subcmd_rijndael_t *rijndael = MNULL;
8187 subcmd_rc4_t *rc4 = MNULL;
8188 subcmd_md5_t *md5 = MNULL;
8189 subcmd_mrvl_f_t *mrvl_f = MNULL;
8190 subcmd_sha256_kdf_t *sha256_kdf = MNULL;
8191 t_u8 *ptlv = MNULL;
8192 t_u8 tlv_bitmap = 0;
8193 t_u32 i = 0;
8194 #endif
8195 ENTER();
8196
8197 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_CRYPTO);
8198 cmd->size = S_DS_GEN + sizeof(HostCmd_DS_CRYPTO);
8199 cry_cmd->action = wlan_cpu_to_le16(cmd_action);
8200 cry_cmd->subCmdCode = cfg->sub_command;
8201 switch (cfg->sub_command) {
8202 #if defined(DRV_EMBEDDED_AUTHENTICATOR) || defined(DRV_EMBEDDED_SUPPLICANT)
8203 case HostCmd_CMD_CRYPTO_SUBCMD_PRF_HMAC_SHA1:
8204 tlv_bitmap = BIT_TLV_TYPE_CRYPTO_KEY |
8205 BIT_TLV_TYPE_CRYPTO_KEY_PREFIX |
8206 BIT_TLV_TYPE_CRYPTO_KEY_DATA_BLK;
8207 /* set subcmd start */
8208 prf_hmac_sha1 = (subcmd_prf_hmac_sha1_t *)cry_cmd->subCmd;
8209 prf_hmac_sha1->output_len = cfg->output_len;
8210 /* set tlv start */
8211 ptlv = prf_hmac_sha1->tlv;
8212 cmd->size += sizeof(subcmd_prf_hmac_sha1_t);
8213 break;
8214 case HostCmd_CMD_CRYPTO_SUBCMD_HMAC_SHA1:
8215 tlv_bitmap = BIT_TLV_TYPE_CRYPTO_KEY |
8216 BIT_TLV_TYPE_CRYPTO_KEY_DATA_BLK;
8217 /* set subcmd start */
8218 hmac_sha1 = (subcmd_hmac_sha1_t *)cry_cmd->subCmd;
8219 hmac_sha1->output_len = cfg->output_len;
8220 hmac_sha1->data_blks_nr = cfg->data_blks_nr;
8221 /* set tlv start */
8222 ptlv = hmac_sha1->tlv;
8223 cmd->size += sizeof(subcmd_hmac_sha1_t);
8224 break;
8225 case HostCmd_CMD_CRYPTO_SUBCMD_HMAC_SHA256:
8226 tlv_bitmap = BIT_TLV_TYPE_CRYPTO_KEY |
8227 BIT_TLV_TYPE_CRYPTO_KEY_DATA_BLK;
8228 /* set subcmd start */
8229 hmac_sha256 = (subcmd_hmac_sha256_t *)cry_cmd->subCmd;
8230 hmac_sha256->output_len = cfg->output_len;
8231 hmac_sha256->data_blks_nr = cfg->data_blks_nr;
8232 /* set tlv start */
8233 ptlv = hmac_sha256->tlv;
8234 cmd->size += sizeof(subcmd_hmac_sha256_t);
8235 break;
8236 case HostCmd_CMD_CRYPTO_SUBCMD_SHA256:
8237 tlv_bitmap = BIT_TLV_TYPE_CRYPTO_KEY_DATA_BLK;
8238 /* set subcmd start */
8239 sha256 = (subcmd_sha256_t *)cry_cmd->subCmd;
8240 sha256->output_len = cfg->output_len;
8241 sha256->data_blks_nr = cfg->data_blks_nr;
8242 /* set tlv start */
8243 ptlv = sha256->tlv;
8244 cmd->size += sizeof(subcmd_sha256_t);
8245 break;
8246 case HostCmd_CMD_CRYPTO_SUBCMD_RIJNDAEL:
8247 tlv_bitmap = BIT_TLV_TYPE_CRYPTO_KEY |
8248 BIT_TLV_TYPE_CRYPTO_KEY_DATA_BLK;
8249 /* set subcmd start */
8250 rijndael = (subcmd_rijndael_t *)cry_cmd->subCmd;
8251 rijndael->sub_action_code = cfg->sub_action_code;
8252 rijndael->output_len = cfg->output_len;
8253 /* set tlv start */
8254 ptlv = rijndael->tlv;
8255 cmd->size += sizeof(subcmd_rijndael_t);
8256 break;
8257 case HostCmd_CMD_CRYPTO_SUBCMD_RC4:
8258 tlv_bitmap = BIT_TLV_TYPE_CRYPTO_KEY |
8259 BIT_TLV_TYPE_CRYPTO_KEY_IV |
8260 BIT_TLV_TYPE_CRYPTO_KEY_DATA_BLK;
8261 /* set subcmd start */
8262 rc4 = (subcmd_rc4_t *)cry_cmd->subCmd;
8263 rc4->skip_bytes = cfg->skip_bytes;
8264 rc4->output_len = cfg->output_len;
8265 /* set tlv start */
8266 ptlv = rc4->tlv;
8267 cmd->size += sizeof(subcmd_rc4_t);
8268 break;
8269 case HostCmd_CMD_CRYPTO_SUBCMD_MD5:
8270 tlv_bitmap = BIT_TLV_TYPE_CRYPTO_KEY |
8271 BIT_TLV_TYPE_CRYPTO_KEY_DATA_BLK;
8272 /* set subcmd start */
8273 md5 = (subcmd_md5_t *)cry_cmd->subCmd;
8274 md5->output_len = cfg->output_len;
8275 /* set tlv start */
8276 ptlv = md5->tlv;
8277 cmd->size += sizeof(subcmd_md5_t);
8278 break;
8279 case HostCmd_CMD_CRYPTO_SUBCMD_MRVL_F:
8280 tlv_bitmap = BIT_TLV_TYPE_CRYPTO_KEY |
8281 BIT_TLV_TYPE_CRYPTO_KEY_DATA_BLK;
8282 /* set subcmd start */
8283 mrvl_f = (subcmd_mrvl_f_t *)cry_cmd->subCmd;
8284 mrvl_f->iterations = cfg->iteration;
8285 mrvl_f->count = cfg->count;
8286 mrvl_f->output_len = cfg->output_len;
8287 /* set tlv start */
8288 ptlv = mrvl_f->tlv;
8289 cmd->size += sizeof(subcmd_mrvl_f_t);
8290 break;
8291 case HostCmd_CMD_CRYPTO_SUBCMD_SHA256_KDF:
8292 tlv_bitmap = BIT_TLV_TYPE_CRYPTO_KEY |
8293 BIT_TLV_TYPE_CRYPTO_KEY_PREFIX |
8294 BIT_TLV_TYPE_CRYPTO_KEY_DATA_BLK;
8295 /* set subcmd start */
8296 sha256_kdf = (subcmd_sha256_kdf_t *)cry_cmd->subCmd;
8297 sha256_kdf->output_len = cfg->output_len;
8298 /* set tlv start */
8299 ptlv = sha256_kdf->tlv;
8300 cmd->size += sizeof(subcmd_sha256_kdf_t);
8301 break;
8302 #endif
8303 default:
8304 break;
8305 }
8306 #if defined(DRV_EMBEDDED_AUTHENTICATOR) || defined(DRV_EMBEDDED_SUPPLICANT)
8307 /* add tlv */
8308 if (tlv_bitmap & BIT_TLV_TYPE_CRYPTO_KEY) {
8309 ((MrvlIEParamSet_t *)ptlv)->Type =
8310 wlan_cpu_to_le16(TLV_TYPE_CRYPTO_KEY);
8311 ((MrvlIEParamSet_t *)ptlv)->Length =
8312 wlan_cpu_to_le16(cfg->key_len);
8313 memcpy_ext(pmpriv->adapter,
8314 (t_u8 *)ptlv + sizeof(MrvlIEParamSet_t), cfg->key,
8315 cfg->key_len, cfg->key_len);
8316 cmd->size += cfg->key_len + sizeof(MrvlIEParamSet_t);
8317 ptlv += cfg->key_len + sizeof(MrvlIEParamSet_t);
8318 }
8319
8320 if (tlv_bitmap & BIT_TLV_TYPE_CRYPTO_KEY_PREFIX) {
8321 ((MrvlIEParamSet_t *)ptlv)->Type =
8322 wlan_cpu_to_le16(TLV_TYPE_CRYPTO_KEY_PREFIX);
8323 ((MrvlIEParamSet_t *)ptlv)->Length =
8324 wlan_cpu_to_le16(cfg->key_prefix_len);
8325 memcpy_ext(pmpriv->adapter, ptlv + sizeof(MrvlIEParamSet_t),
8326 cfg->key_prefix, cfg->key_prefix_len,
8327 cfg->key_prefix_len);
8328 cmd->size += cfg->key_prefix_len + sizeof(MrvlIEParamSet_t);
8329 ptlv += cfg->key_prefix_len + sizeof(MrvlIEParamSet_t);
8330 }
8331
8332 if (tlv_bitmap & BIT_TLV_TYPE_CRYPTO_KEY_IV) {
8333 ((MrvlIEParamSet_t *)ptlv)->Type =
8334 wlan_cpu_to_le16(TLV_TYPE_CRYPTO_KEY_IV);
8335 ((MrvlIEParamSet_t *)ptlv)->Length =
8336 wlan_cpu_to_le16(cfg->key_iv_len);
8337 memcpy_ext(pmpriv->adapter, ptlv + sizeof(MrvlIEParamSet_t),
8338 cfg->key_iv, cfg->key_iv_len, cfg->key_iv_len);
8339 cmd->size += cfg->key_iv_len + sizeof(MrvlIEParamSet_t);
8340 ptlv += cfg->key_iv_len + sizeof(MrvlIEParamSet_t);
8341 }
8342
8343 if (tlv_bitmap & BIT_TLV_TYPE_CRYPTO_KEY_DATA_BLK) {
8344 t_u16 data_blk_len = 0;
8345 t_u8 *pdata_blk = MNULL;
8346 for (i = 0; i < cfg->data_blks_nr; i++) {
8347 data_blk_len = *(cfg->key_data_blk_len + i);
8348 pdata_blk = *(cfg->key_data_blk + i);
8349 ((MrvlIEParamSet_t *)ptlv)->Type =
8350 wlan_cpu_to_le16(TLV_TYPE_CRYPTO_KEY_DATA_BLK);
8351 ((MrvlIEParamSet_t *)ptlv)->Length =
8352 wlan_cpu_to_le16(data_blk_len);
8353 memcpy_ext(pmpriv->adapter,
8354 ptlv + sizeof(MrvlIEParamSet_t), pdata_blk,
8355 data_blk_len, data_blk_len);
8356 cmd->size += data_blk_len + sizeof(MrvlIEParamSet_t);
8357 ptlv += data_blk_len + sizeof(MrvlIEParamSet_t);
8358 }
8359 }
8360 #endif
8361 HEXDUMP("HostCmd_DS_COMMAND wlan_cmd_crypto", cmd, cmd->size);
8362
8363 cmd->size = wlan_cpu_to_le16(cmd->size);
8364 LEAVE();
8365 return MLAN_STATUS_SUCCESS;
8366 }
8367
8368 /**
8369 * @brief This function handles the command response of crypto command
8370 *
8371 * @param pmpriv A pointer to mlan_private structure
8372 * @param resp A pointer to HostCmd_DS_COMMAND
8373 * @param pioctl_buf A pointer to mlan_ioctl_req structure
8374 *
8375 * @return MLAN_STATUS_SUCCESS
8376 */
wlan_ret_crypto(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)8377 mlan_status wlan_ret_crypto(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
8378 mlan_ioctl_req *pioctl_buf)
8379 {
8380 HostCmd_DS_CRYPTO *crypto_cmd = &resp->params.crypto_cmd;
8381 #if defined(DRV_EMBEDDED_AUTHENTICATOR) || defined(DRV_EMBEDDED_SUPPLICANT)
8382 mlan_adapter *pmadapter = pmpriv->adapter;
8383 mlan_callbacks *pcb = (pmlan_callbacks)&pmadapter->callbacks;
8384 mlan_ds_sup_cfg *cfg = (mlan_ds_sup_cfg *)pioctl_buf->pbuf;
8385 #endif
8386
8387 ENTER();
8388 #if defined(DRV_EMBEDDED_AUTHENTICATOR) || defined(DRV_EMBEDDED_SUPPLICANT)
8389 if (!cfg) {
8390 PRINTM(MERROR, "wlan_ret_crypto cfg is null \n");
8391 goto done;
8392 }
8393 if (resp->result == HostCmd_RESULT_OK) {
8394 /* copy the result */
8395 memcpy_ext(pmpriv->adapter, cfg->output,
8396 (t_u8 *)crypto_cmd + sizeof(HostCmd_DS_CRYPTO) +
8397 sizeof(cfg->output_len),
8398 cfg->output_len, cfg->output_len);
8399 }
8400
8401 /* Prevent the ioctl from completing when the cmd is freed */
8402 if (cfg->call_back) {
8403 pmadapter->curr_cmd->pioctl_buf = MNULL;
8404 /* trigger wait q */
8405 pcb->moal_notify_hostcmd_complete(pmadapter->pmoal_handle,
8406 pmpriv->bss_index);
8407 }
8408 #endif
8409 done:
8410 LEAVE();
8411 return MLAN_STATUS_SUCCESS;
8412 }
8413 #endif
8414
8415 /**
8416 * @brief This function prepares command of mac_address.
8417 *
8418 * @param pmpriv A pointer to mlan_private structure
8419 * @param cmd A pointer to HostCmd_DS_COMMAND structure
8420 * @param cmd_action The action: GET or SET
8421 *
8422 * @return MLAN_STATUS_SUCCESS
8423 */
wlan_cmd_802_11_mac_address(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action)8424 mlan_status wlan_cmd_802_11_mac_address(pmlan_private pmpriv,
8425 HostCmd_DS_COMMAND *cmd,
8426 t_u16 cmd_action)
8427 {
8428 ENTER();
8429 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_MAC_ADDRESS);
8430 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_MAC_ADDRESS) +
8431 S_DS_GEN);
8432 cmd->result = 0;
8433
8434 cmd->params.mac_addr.action = wlan_cpu_to_le16(cmd_action);
8435
8436 if (cmd_action == HostCmd_ACT_GEN_SET) {
8437 memcpy_ext(pmpriv->adapter, cmd->params.mac_addr.mac_addr,
8438 pmpriv->curr_addr, MLAN_MAC_ADDR_LENGTH,
8439 MLAN_MAC_ADDR_LENGTH);
8440 /* HEXDUMP("SET_CMD: MAC ADDRESS-", priv->CurrentAddr, 6); */
8441 }
8442 LEAVE();
8443 return MLAN_STATUS_SUCCESS;
8444 }
8445
8446 /**
8447 * @brief This function handles the command response of mac_address
8448 *
8449 * @param pmpriv A pointer to mlan_private structure
8450 * @param resp A pointer to HostCmd_DS_COMMAND
8451 * @param pioctl_buf A pointer to mlan_ioctl_req structure
8452 *
8453 * @return MLAN_STATUS_SUCCESS
8454 */
wlan_ret_802_11_mac_address(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)8455 mlan_status wlan_ret_802_11_mac_address(pmlan_private pmpriv,
8456 HostCmd_DS_COMMAND *resp,
8457 mlan_ioctl_req *pioctl_buf)
8458 {
8459 HostCmd_DS_802_11_MAC_ADDRESS *pmac_addr = &resp->params.mac_addr;
8460 mlan_ds_bss *bss = MNULL;
8461
8462 ENTER();
8463
8464 memcpy_ext(pmpriv->adapter, pmpriv->curr_addr, pmac_addr->mac_addr,
8465 MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
8466
8467 PRINTM(MINFO, "MAC address: " MACSTR "\n", MAC2STR(pmpriv->curr_addr));
8468 if (pioctl_buf) {
8469 bss = (mlan_ds_bss *)pioctl_buf->pbuf;
8470 memcpy_ext(pmpriv->adapter, &bss->param.mac_addr,
8471 pmpriv->curr_addr, MLAN_MAC_ADDR_LENGTH,
8472 MLAN_MAC_ADDR_LENGTH);
8473 pioctl_buf->data_read_written =
8474 MLAN_MAC_ADDR_LENGTH + MLAN_SUB_COMMAND_SIZE;
8475 }
8476 LEAVE();
8477 return MLAN_STATUS_SUCCESS;
8478 }
8479
8480 /**
8481 * @brief This function prepares command of Rx abort cfg
8482 *
8483 * @param pmpriv A pointer to mlan_private structure
8484 * @param cmd A pointer to HostCmd_DS_COMMAND structure
8485 * @param cmd_action the action: GET or SET
8486 * @param pdata_buf A pointer to data buffer
8487 * @return MLAN_STATUS_SUCCESS
8488 */
wlan_cmd_rxabortcfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)8489 mlan_status wlan_cmd_rxabortcfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
8490 t_u16 cmd_action, t_void *pdata_buf)
8491 {
8492 HostCmd_DS_CMD_RX_ABORT_CFG *cfg_cmd =
8493 (HostCmd_DS_CMD_RX_ABORT_CFG *)&cmd->params.rx_abort_cfg;
8494 mlan_ds_misc_rx_abort_cfg *cfg = (mlan_ds_misc_rx_abort_cfg *)pdata_buf;
8495
8496 ENTER();
8497
8498 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_RX_ABORT_CFG);
8499 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_CMD_RX_ABORT_CFG) +
8500 S_DS_GEN);
8501 cfg_cmd->action = wlan_cpu_to_le16(cmd_action);
8502
8503 if (cmd_action == HostCmd_ACT_GEN_SET) {
8504 cfg_cmd->enable = (t_u8)cfg->enable;
8505 cfg_cmd->rssi_threshold = (t_s8)cfg->rssi_threshold;
8506 }
8507
8508 LEAVE();
8509 return MLAN_STATUS_SUCCESS;
8510 }
8511
8512 /**
8513 * @brief This function handles the command response of Rx Abort Cfg
8514 *
8515 * @param pmpriv A pointer to mlan_private structure
8516 * @param resp A pointer to HostCmd_DS_COMMAND
8517 * @param pioctl_buf A pointer to mlan_ioctl_req structure
8518 *
8519 * @return MLAN_STATUS_SUCCESS
8520 */
wlan_ret_rxabortcfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)8521 mlan_status wlan_ret_rxabortcfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
8522 mlan_ioctl_req *pioctl_buf)
8523 {
8524 HostCmd_DS_CMD_RX_ABORT_CFG *cfg_cmd =
8525 (HostCmd_DS_CMD_RX_ABORT_CFG *)&resp->params.rx_abort_cfg;
8526 mlan_ds_misc_cfg *misc_cfg = MNULL;
8527
8528 ENTER();
8529
8530 if (pioctl_buf) {
8531 misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
8532 misc_cfg->param.rx_abort_cfg.enable = (t_u8)cfg_cmd->enable;
8533 misc_cfg->param.rx_abort_cfg.rssi_threshold =
8534 (t_s8)cfg_cmd->rssi_threshold;
8535 }
8536 LEAVE();
8537 return MLAN_STATUS_SUCCESS;
8538 }
8539
8540 /**
8541 * @brief This function prepares command of Rx abort cfg ext
8542 *
8543 * @param pmpriv A pointer to mlan_private structure
8544 * @param cmd A pointer to HostCmd_DS_COMMAND structure
8545 * @param cmd_action the action: GET or SET
8546 * @param pdata_buf A pointer to data buffer
8547 * @return MLAN_STATUS_SUCCESS
8548 */
wlan_cmd_rxabortcfg_ext(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)8549 mlan_status wlan_cmd_rxabortcfg_ext(pmlan_private pmpriv,
8550 HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
8551 t_void *pdata_buf)
8552 {
8553 HostCmd_DS_CMD_RX_ABORT_CFG_EXT *cfg_cmd =
8554 (HostCmd_DS_CMD_RX_ABORT_CFG_EXT *)&cmd->params.rx_abort_cfg_ext;
8555 mlan_ds_misc_rx_abort_cfg_ext *cfg =
8556 (mlan_ds_misc_rx_abort_cfg_ext *)pdata_buf;
8557
8558 ENTER();
8559
8560 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_RX_ABORT_CFG_EXT);
8561 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_CMD_RX_ABORT_CFG_EXT) +
8562 S_DS_GEN);
8563 cfg_cmd->action = wlan_cpu_to_le16(cmd_action);
8564
8565 if (cmd_action == HostCmd_ACT_GEN_SET) {
8566 cfg_cmd->enable = (t_u8)cfg->enable;
8567 cfg_cmd->rssi_margin = (t_s8)cfg->rssi_margin;
8568 cfg_cmd->ceil_rssi_threshold = (t_s8)cfg->ceil_rssi_threshold;
8569 }
8570
8571 LEAVE();
8572 return MLAN_STATUS_SUCCESS;
8573 }
8574
8575 /**
8576 * @brief This function handles the command response of Rx Abort Cfg ext
8577 *
8578 * @param pmpriv A pointer to mlan_private structure
8579 * @param resp A pointer to HostCmd_DS_COMMAND
8580 * @param pioctl_buf A pointer to mlan_ioctl_req structure
8581 *
8582 * @return MLAN_STATUS_SUCCESS
8583 */
wlan_ret_rxabortcfg_ext(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)8584 mlan_status wlan_ret_rxabortcfg_ext(pmlan_private pmpriv,
8585 HostCmd_DS_COMMAND *resp,
8586 mlan_ioctl_req *pioctl_buf)
8587 {
8588 HostCmd_DS_CMD_RX_ABORT_CFG_EXT *cfg_cmd =
8589 (HostCmd_DS_CMD_RX_ABORT_CFG_EXT *)&resp->params
8590 .rx_abort_cfg_ext;
8591 mlan_ds_misc_cfg *misc_cfg = MNULL;
8592
8593 ENTER();
8594
8595 if (pioctl_buf) {
8596 misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
8597 misc_cfg->param.rx_abort_cfg_ext.enable = cfg_cmd->enable;
8598 misc_cfg->param.rx_abort_cfg_ext.rssi_margin =
8599 cfg_cmd->rssi_margin;
8600 misc_cfg->param.rx_abort_cfg_ext.ceil_rssi_threshold =
8601 cfg_cmd->ceil_rssi_threshold;
8602 }
8603 LEAVE();
8604 return MLAN_STATUS_SUCCESS;
8605 }
8606
8607 /**
8608 * @brief This function sets the hal/phy cfg params
8609 *
8610 * @param pmpriv A pointer to mlan_private structure
8611 * @param cmd A pointer to HostCmd_DS_COMMAND structure
8612 * @param cmd_action The action: GET or SET
8613 * @param pdata_buf A pointer to data buffer
8614 *
8615 * @return MLAN_STATUS_SUCCESS
8616 */
wlan_cmd_hal_phy_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_u16 * pdata_buf)8617 mlan_status wlan_cmd_hal_phy_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
8618 t_u16 cmd_action, t_u16 *pdata_buf)
8619 {
8620 HostCmd_DS_HAL_PHY_CFG *hal_phy_cfg_cmd =
8621 &cmd->params.hal_phy_cfg_params;
8622 mlan_ds_hal_phy_cfg_params *hal_phy_cfg_params = MNULL;
8623
8624 ENTER();
8625
8626 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_HAL_PHY_CFG);
8627 cmd->size = sizeof(HostCmd_DS_HAL_PHY_CFG) + S_DS_GEN;
8628 hal_phy_cfg_cmd->action = wlan_cpu_to_le16(cmd_action);
8629 hal_phy_cfg_params = (mlan_ds_hal_phy_cfg_params *)pdata_buf;
8630 hal_phy_cfg_cmd->dot11b_psd_mask_cfg =
8631 hal_phy_cfg_params->dot11b_psd_mask_cfg;
8632 cmd->size = wlan_cpu_to_le16(cmd->size);
8633 LEAVE();
8634 return MLAN_STATUS_SUCCESS;
8635 }
8636
8637 /**
8638 * @brief This function handles the command response of hal_phy_cfg
8639 *
8640 * @param pmpriv A pointer to mlan_private structure
8641 * @param resp A pointer to HostCmd_DS_COMMAND
8642 * @param pioctl_buf A pointer to mlan_ioctl_req structure
8643 *
8644 * @return MLAN_STATUS_SUCCESS
8645 */
wlan_ret_hal_phy_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)8646 mlan_status wlan_ret_hal_phy_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
8647 mlan_ioctl_req *pioctl_buf)
8648 {
8649 HostCmd_DS_HAL_PHY_CFG *cfg_cmd =
8650 (HostCmd_DS_HAL_PHY_CFG *)&resp->params.hal_phy_cfg_params;
8651 mlan_ds_misc_cfg *misc_cfg = MNULL;
8652
8653 ENTER();
8654
8655 if (pioctl_buf) {
8656 misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
8657 misc_cfg->param.hal_phy_cfg_params.dot11b_psd_mask_cfg =
8658 cfg_cmd->dot11b_psd_mask_cfg;
8659 }
8660 LEAVE();
8661 return MLAN_STATUS_SUCCESS;
8662 }
8663
wlan_cmd_ips_config(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)8664 mlan_status wlan_cmd_ips_config(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
8665 t_u16 cmd_action, t_void *pdata_buf)
8666 {
8667 HostCmd_DS_IPS_CONFIG *ips_cfg = MNULL;
8668 t_u32 enable = *(t_u32 *)pdata_buf;
8669
8670 ENTER();
8671 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_IPS_CONFIG);
8672 ips_cfg = &cmd->params.ips_cfg;
8673 ips_cfg->enable = wlan_cpu_to_le32(enable);
8674 cmd->size = S_DS_GEN + sizeof(HostCmd_DS_IPS_CONFIG);
8675 LEAVE();
8676 return MLAN_STATUS_SUCCESS;
8677 }
8678
wlan_ret_ips_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)8679 mlan_status wlan_ret_ips_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
8680 mlan_ioctl_req *pioctl_buf)
8681 {
8682 ENTER();
8683 LEAVE();
8684 return MLAN_STATUS_SUCCESS;
8685 }
8686
8687 /**
8688 * @brief This function prepares command of Dot11mc unassoc ftm cfg
8689 *
8690 * @param pmpriv A pointer to mlan_private structure
8691 * @param cmd A pointer to HostCmd_DS_COMMAND structure
8692 * @param cmd_action the action: GET or SET
8693 * @param pdata_buf A pointer to data buffer
8694 * @return MLAN_STATUS_SUCCESS
8695 */
wlan_cmd_dot11mc_unassoc_ftm_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)8696 mlan_status wlan_cmd_dot11mc_unassoc_ftm_cfg(pmlan_private pmpriv,
8697 HostCmd_DS_COMMAND *cmd,
8698 t_u16 cmd_action,
8699 t_void *pdata_buf)
8700 {
8701 HostCmd_DS_CMD_DOT11MC_UNASSOC_FTM_CFG *cfg_cmd =
8702 (HostCmd_DS_CMD_DOT11MC_UNASSOC_FTM_CFG *)&cmd->params
8703 .dot11mc_unassoc_ftm_cfg;
8704 mlan_ds_misc_dot11mc_unassoc_ftm_cfg *cfg =
8705 (mlan_ds_misc_dot11mc_unassoc_ftm_cfg *)pdata_buf;
8706
8707 ENTER();
8708
8709 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_DOT11MC_UNASSOC_FTM_CFG);
8710 cmd->size = wlan_cpu_to_le16(
8711 sizeof(HostCmd_DS_CMD_DOT11MC_UNASSOC_FTM_CFG) + S_DS_GEN);
8712 cfg_cmd->action = wlan_cpu_to_le16(cmd_action);
8713
8714 if (cmd_action == HostCmd_ACT_GEN_SET) {
8715 cfg_cmd->state = wlan_cpu_to_le16(cfg->state);
8716 }
8717
8718 LEAVE();
8719 return MLAN_STATUS_SUCCESS;
8720 }
8721
8722 /**
8723 * @brief This function handles the command response of Dot11mc unassoc ftm cfg
8724 *
8725 * @param pmpriv A pointer to mlan_private structure
8726 * @param resp A pointer to HostCmd_DS_COMMAND
8727 * @param pioctl_buf A pointer to mlan_ioctl_req structure
8728 *
8729 * @return MLAN_STATUS_SUCCESS
8730 */
wlan_ret_dot11mc_unassoc_ftm_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)8731 mlan_status wlan_ret_dot11mc_unassoc_ftm_cfg(pmlan_private pmpriv,
8732 HostCmd_DS_COMMAND *resp,
8733 mlan_ioctl_req *pioctl_buf)
8734 {
8735 HostCmd_DS_CMD_DOT11MC_UNASSOC_FTM_CFG *cfg_cmd =
8736 (HostCmd_DS_CMD_DOT11MC_UNASSOC_FTM_CFG *)&resp->params
8737 .dot11mc_unassoc_ftm_cfg;
8738 mlan_ds_misc_cfg *misc_cfg = MNULL;
8739
8740 ENTER();
8741
8742 if (pioctl_buf) {
8743 misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
8744 misc_cfg->param.dot11mc_unassoc_ftm_cfg.state =
8745 wlan_le16_to_cpu(cfg_cmd->state);
8746 }
8747 LEAVE();
8748 return MLAN_STATUS_SUCCESS;
8749 }
8750
8751 /**
8752 * @brief This function prepares command of Tx ampdu prot mode
8753 *
8754 * @param pmpriv A pointer to mlan_private structure
8755 * @param cmd A pointer to HostCmd_DS_COMMAND structure
8756 * @param cmd_action the action: GET or SET
8757 * @param pdata_buf A pointer to data buffer
8758 * @return MLAN_STATUS_SUCCESS
8759 */
wlan_cmd_tx_ampdu_prot_mode(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)8760 mlan_status wlan_cmd_tx_ampdu_prot_mode(pmlan_private pmpriv,
8761 HostCmd_DS_COMMAND *cmd,
8762 t_u16 cmd_action, t_void *pdata_buf)
8763 {
8764 HostCmd_DS_CMD_TX_AMPDU_PROT_MODE *cfg_cmd =
8765 (HostCmd_DS_CMD_TX_AMPDU_PROT_MODE *)&cmd->params
8766 .tx_ampdu_prot_mode;
8767 mlan_ds_misc_tx_ampdu_prot_mode *cfg =
8768 (mlan_ds_misc_tx_ampdu_prot_mode *)pdata_buf;
8769
8770 ENTER();
8771
8772 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_TX_AMPDU_PROT_MODE);
8773 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_CMD_TX_AMPDU_PROT_MODE) +
8774 S_DS_GEN);
8775 cfg_cmd->action = wlan_cpu_to_le16(cmd_action);
8776
8777 if (cmd_action == HostCmd_ACT_GEN_SET) {
8778 cfg_cmd->mode = wlan_cpu_to_le16(cfg->mode);
8779 }
8780
8781 LEAVE();
8782 return MLAN_STATUS_SUCCESS;
8783 }
8784
8785 /**
8786 * @brief This function handles the command response of Tx ampdu prot mode
8787 *
8788 * @param pmpriv A pointer to mlan_private structure
8789 * @param resp A pointer to HostCmd_DS_COMMAND
8790 * @param pioctl_buf A pointer to mlan_ioctl_req structure
8791 *
8792 * @return MLAN_STATUS_SUCCESS
8793 */
wlan_ret_tx_ampdu_prot_mode(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)8794 mlan_status wlan_ret_tx_ampdu_prot_mode(pmlan_private pmpriv,
8795 HostCmd_DS_COMMAND *resp,
8796 mlan_ioctl_req *pioctl_buf)
8797 {
8798 HostCmd_DS_CMD_TX_AMPDU_PROT_MODE *cfg_cmd =
8799 (HostCmd_DS_CMD_TX_AMPDU_PROT_MODE *)&resp->params
8800 .tx_ampdu_prot_mode;
8801 mlan_ds_misc_cfg *misc_cfg = MNULL;
8802
8803 ENTER();
8804
8805 if (pioctl_buf) {
8806 misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
8807 misc_cfg->param.tx_ampdu_prot_mode.mode =
8808 wlan_le16_to_cpu(cfg_cmd->mode);
8809 }
8810 LEAVE();
8811 return MLAN_STATUS_SUCCESS;
8812 }
8813
8814 /**
8815 * @brief This function prepares command of Rate Adapt cfg
8816 *
8817 * @param pmpriv A pointer to mlan_private structure
8818 * @param cmd A pointer to HostCmd_DS_COMMAND structure
8819 * @param cmd_action the action: GET or SET
8820 * @param pdata_buf A pointer to data buffer
8821 * @return MLAN_STATUS_SUCCESS
8822 */
wlan_cmd_rate_adapt_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)8823 mlan_status wlan_cmd_rate_adapt_cfg(pmlan_private pmpriv,
8824 HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
8825 t_void *pdata_buf)
8826 {
8827 HostCmd_DS_CMD_RATE_ADAPT_CFG *cfg_cmd =
8828 (HostCmd_DS_CMD_RATE_ADAPT_CFG *)&cmd->params.rate_adapt_cfg;
8829 mlan_ds_misc_rate_adapt_cfg *cfg =
8830 (mlan_ds_misc_rate_adapt_cfg *)pdata_buf;
8831
8832 ENTER();
8833
8834 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_RATE_ADAPT_CFG);
8835 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_CMD_RATE_ADAPT_CFG) +
8836 S_DS_GEN);
8837 cfg_cmd->action = wlan_cpu_to_le16(cmd_action);
8838
8839 if (cmd_action == HostCmd_ACT_GEN_SET) {
8840 cfg_cmd->sr_rateadapt = (t_u8)cfg->sr_rateadapt;
8841 cfg_cmd->ra_low_thresh = (t_u8)cfg->ra_low_thresh;
8842 cfg_cmd->ra_high_thresh = (t_u8)cfg->ra_high_thresh;
8843 cfg_cmd->ra_interval = wlan_cpu_to_le16(cfg->ra_interval);
8844 }
8845
8846 LEAVE();
8847 return MLAN_STATUS_SUCCESS;
8848 }
8849
8850 /**
8851 * @brief This function handles the command response of Rate Adapt Cfg
8852 *
8853 * @param pmpriv A pointer to mlan_private structure
8854 * @param resp A pointer to HostCmd_DS_COMMAND
8855 * @param pioctl_buf A pointer to mlan_ioctl_req structure
8856 *
8857 * @return MLAN_STATUS_SUCCESS
8858 */
wlan_ret_rate_adapt_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)8859 mlan_status wlan_ret_rate_adapt_cfg(pmlan_private pmpriv,
8860 HostCmd_DS_COMMAND *resp,
8861 mlan_ioctl_req *pioctl_buf)
8862 {
8863 HostCmd_DS_CMD_RATE_ADAPT_CFG *cfg_cmd =
8864 (HostCmd_DS_CMD_RATE_ADAPT_CFG *)&resp->params.rate_adapt_cfg;
8865 mlan_ds_misc_cfg *misc_cfg = MNULL;
8866
8867 ENTER();
8868
8869 if (pioctl_buf) {
8870 misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
8871 misc_cfg->param.rate_adapt_cfg.sr_rateadapt =
8872 (t_u8)cfg_cmd->sr_rateadapt;
8873 misc_cfg->param.rate_adapt_cfg.ra_low_thresh =
8874 (t_u8)cfg_cmd->ra_low_thresh;
8875 misc_cfg->param.rate_adapt_cfg.ra_high_thresh =
8876 (t_u8)cfg_cmd->ra_high_thresh;
8877 misc_cfg->param.rate_adapt_cfg.ra_interval =
8878 wlan_le16_to_cpu(cfg_cmd->ra_interval);
8879 }
8880 LEAVE();
8881 return MLAN_STATUS_SUCCESS;
8882 }
8883
8884 /**
8885 * @brief This function prepares command of CCK Desense cfg
8886 *
8887 * @param pmpriv A pointer to mlan_private structure
8888 * @param cmd A pointer to HostCmd_DS_COMMAND structure
8889 * @param cmd_action the action: GET or SET
8890 * @param pdata_buf A pointer to data buffer
8891 * @return MLAN_STATUS_SUCCESS
8892 */
wlan_cmd_cck_desense_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)8893 mlan_status wlan_cmd_cck_desense_cfg(pmlan_private pmpriv,
8894 HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
8895 t_void *pdata_buf)
8896 {
8897 HostCmd_DS_CMD_CCK_DESENSE_CFG *cfg_cmd =
8898 (HostCmd_DS_CMD_CCK_DESENSE_CFG *)&cmd->params.cck_desense_cfg;
8899 mlan_ds_misc_cck_desense_cfg *cfg =
8900 (mlan_ds_misc_cck_desense_cfg *)pdata_buf;
8901
8902 ENTER();
8903
8904 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_CCK_DESENSE_CFG);
8905 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_CMD_CCK_DESENSE_CFG) +
8906 S_DS_GEN);
8907 cfg_cmd->action = wlan_cpu_to_le16(cmd_action);
8908
8909 if (cmd_action == HostCmd_ACT_GEN_SET) {
8910 cfg_cmd->mode = wlan_cpu_to_le16(cfg->mode);
8911 cfg_cmd->margin = (t_s8)cfg->margin;
8912 cfg_cmd->ceil_thresh = (t_s8)cfg->ceil_thresh;
8913 cfg_cmd->num_on_intervals = (t_u8)cfg->num_on_intervals;
8914 cfg_cmd->num_off_intervals = (t_u8)cfg->num_off_intervals;
8915 }
8916
8917 LEAVE();
8918 return MLAN_STATUS_SUCCESS;
8919 }
8920
8921 /**
8922 * @brief This function handles the command response of CCK Desense Cfg
8923 *
8924 * @param pmpriv A pointer to mlan_private structure
8925 * @param resp A pointer to HostCmd_DS_COMMAND
8926 * @param pioctl_buf A pointer to mlan_ioctl_req structure
8927 *
8928 * @return MLAN_STATUS_SUCCESS
8929 */
wlan_ret_cck_desense_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)8930 mlan_status wlan_ret_cck_desense_cfg(pmlan_private pmpriv,
8931 HostCmd_DS_COMMAND *resp,
8932 mlan_ioctl_req *pioctl_buf)
8933 {
8934 HostCmd_DS_CMD_CCK_DESENSE_CFG *cfg_cmd =
8935 (HostCmd_DS_CMD_CCK_DESENSE_CFG *)&resp->params.cck_desense_cfg;
8936 mlan_ds_misc_cfg *misc_cfg = MNULL;
8937
8938 ENTER();
8939
8940 if (pioctl_buf) {
8941 misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
8942 misc_cfg->param.cck_desense_cfg.mode =
8943 wlan_le16_to_cpu(cfg_cmd->mode);
8944 misc_cfg->param.cck_desense_cfg.margin = (t_s8)cfg_cmd->margin;
8945 misc_cfg->param.cck_desense_cfg.ceil_thresh =
8946 (t_s8)cfg_cmd->ceil_thresh;
8947 misc_cfg->param.cck_desense_cfg.num_on_intervals =
8948 (t_u8)cfg_cmd->num_on_intervals;
8949 misc_cfg->param.cck_desense_cfg.num_off_intervals =
8950 (t_u8)cfg_cmd->num_off_intervals;
8951 }
8952 LEAVE();
8953 return MLAN_STATUS_SUCCESS;
8954 }
8955
8956 /**
8957 * @brief This function sends dynamic bandwidth command to firmware.
8958 *
8959 * @param pmpriv A pointer to mlan_private structure
8960 * @param cmd Hostcmd ID
8961 * @param cmd_action Command action
8962 * @param pdata_buf A void pointer to information buffer
8963 * @return N/A
8964 */
wlan_cmd_config_dyn_bw(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)8965 mlan_status wlan_cmd_config_dyn_bw(pmlan_private pmpriv,
8966 HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
8967 t_void *pdata_buf)
8968 {
8969 HostCmd_DS_DYN_BW *dyn_bw_cmd = &cmd->params.dyn_bw;
8970
8971 ENTER();
8972
8973 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_DYN_BW);
8974 cmd->size = S_DS_GEN + sizeof(HostCmd_DS_DYN_BW);
8975 dyn_bw_cmd->action = wlan_cpu_to_le16(cmd_action);
8976 dyn_bw_cmd->dyn_bw = wlan_cpu_to_le16(*(t_u16 *)pdata_buf);
8977 cmd->size = wlan_cpu_to_le16(cmd->size);
8978
8979 LEAVE();
8980 return MLAN_STATUS_SUCCESS;
8981 }
8982
8983 /**
8984 * @brief This function handles the command response of dyn_bw
8985 *
8986 * @param pmpriv A pointer to mlan_private structure
8987 * @param resp A pointer to HostCmd_DS_COMMAND
8988 * @param pioctl_buf A pointer to mlan_ioctl_req structure
8989 *
8990 * @return MLAN_STATUS_SUCCESS
8991 */
wlan_ret_dyn_bw(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)8992 mlan_status wlan_ret_dyn_bw(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
8993 mlan_ioctl_req *pioctl_buf)
8994 {
8995 mlan_ds_misc_cfg *cfg = MNULL;
8996 HostCmd_DS_DYN_BW *dyn_bw = &resp->params.dyn_bw;
8997
8998 ENTER();
8999 if (pioctl_buf &&
9000 (wlan_le16_to_cpu(dyn_bw->action) == HostCmd_ACT_GEN_GET)) {
9001 cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
9002 cfg->param.dyn_bw = wlan_le16_to_cpu(dyn_bw->dyn_bw);
9003 PRINTM(MCMND, "Get dynamic bandwidth 0x%x\n",
9004 cfg->param.dyn_bw);
9005 }
9006 LEAVE();
9007 return MLAN_STATUS_SUCCESS;
9008 }
9009
9010 /**
9011 * @brief This function prepares command of CHAN_TRPC_CONFIG
9012 *
9013 * @param pmpriv A pointer to mlan_private structure
9014 * @param cmd A pointer to HostCmd_DS_COMMAND structure
9015 * @param cmd_action the action: GET or SET
9016 * @param pdata_buf A pointer to data buffer
9017 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
9018 */
wlan_cmd_get_chan_trpc_config(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)9019 mlan_status wlan_cmd_get_chan_trpc_config(pmlan_private pmpriv,
9020 HostCmd_DS_COMMAND *cmd,
9021 t_u16 cmd_action, t_void *pdata_buf)
9022 {
9023 HostCmd_DS_CHANNEL_TRPC_CONFIG *trpc_cfg = &cmd->params.ch_trpc_config;
9024 mlan_ds_misc_chan_trpc_cfg *cfg =
9025 (mlan_ds_misc_chan_trpc_cfg *)pdata_buf;
9026
9027 ENTER();
9028
9029 cmd->command = wlan_cpu_to_le16(HostCmd_CHANNEL_TRPC_CONFIG);
9030 trpc_cfg->action = wlan_cpu_to_le16(cmd_action);
9031 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_CHANNEL_TRPC_CONFIG) +
9032 S_DS_GEN);
9033 trpc_cfg->sub_band = wlan_cpu_to_le16(cfg->sub_band);
9034 LEAVE();
9035 return MLAN_STATUS_SUCCESS;
9036 }
9037 /**
9038 * @brief This function prepares command of LOW_POWER_MODE_CFG
9039 *
9040 * @param pmpriv A pointer to mlan_private structure
9041 * @param cmd A pointer to HostCmd_DS_COMMAND structure
9042 * @param cmd_action the action: GET or SET
9043 * @param pdata_buf A pointer to data buffer
9044 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
9045 */
wlan_cmd_set_get_low_power_mode_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)9046 mlan_status wlan_cmd_set_get_low_power_mode_cfg(pmlan_private pmpriv,
9047 HostCmd_DS_COMMAND *cmd,
9048 t_u16 cmd_action,
9049 t_void *pdata_buf)
9050 {
9051 HostCmd_DS_LOW_POWER_MODE_CFG *lpm_cfg = &cmd->params.lpm_cfg;
9052 t_u16 lpm = *(t_u16 *)pdata_buf;
9053
9054 ENTER();
9055
9056 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_LOW_POWER_MODE_CFG);
9057 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_LOW_POWER_MODE_CFG) +
9058 S_DS_GEN);
9059 lpm_cfg->action = wlan_cpu_to_le16(cmd_action);
9060
9061 if (cmd_action == HostCmd_ACT_GEN_SET)
9062 lpm_cfg->lpm = wlan_cpu_to_le16(lpm);
9063
9064 LEAVE();
9065 return MLAN_STATUS_SUCCESS;
9066 }
9067
9068 /**
9069 * @brief This function handles the command response of low power mode
9070 *
9071 * @param pmpriv A pointer to mlan_private structure
9072 * @param resp A pointer to HostCmd_DS_COMMAND
9073 * @param pioctl_buf A pointer to command buffer
9074 *
9075 * @return MLAN_STATUS_SUCCESS
9076
9077 */
wlan_ret_set_get_low_power_mode_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)9078 mlan_status wlan_ret_set_get_low_power_mode_cfg(pmlan_private pmpriv,
9079 HostCmd_DS_COMMAND *resp,
9080 mlan_ioctl_req *pioctl_buf)
9081 {
9082 mlan_ds_power_cfg *cfg = MNULL;
9083 HostCmd_DS_LOW_POWER_MODE_CFG *lpm_cfg = &resp->params.lpm_cfg;
9084
9085 ENTER();
9086
9087 if (pioctl_buf &&
9088 (wlan_le16_to_cpu(lpm_cfg->action) == HostCmd_ACT_GEN_GET)) {
9089 cfg = (mlan_ds_power_cfg *)pioctl_buf->pbuf;
9090 cfg->param.lpm = wlan_le16_to_cpu(lpm_cfg->lpm);
9091 PRINTM(MCMND, "Get low power mode %d\n", cfg->param.lpm);
9092 }
9093
9094 LEAVE();
9095 return MLAN_STATUS_SUCCESS;
9096 }
9097 /**
9098 * @brief This function handles the command response of
9099 * packet aggregation
9100 *
9101 * @param pmpriv A pointer to mlan_private structure
9102 * @param resp A pointer to HostCmd_DS_COMMAND
9103 * @param pioctl_buf A pointer to command buffer
9104 *
9105 * @return MLAN_STATUS_SUCCESS
9106 */
wlan_ret_get_chan_trpc_config(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)9107 mlan_status wlan_ret_get_chan_trpc_config(pmlan_private pmpriv,
9108 HostCmd_DS_COMMAND *resp,
9109 mlan_ioctl_req *pioctl_buf)
9110 {
9111 mlan_ds_misc_cfg *misc = MNULL;
9112 HostCmd_DS_CHANNEL_TRPC_CONFIG *trpc_cfg = &resp->params.ch_trpc_config;
9113 mlan_ds_misc_chan_trpc_cfg *cfg = MNULL;
9114 mlan_adapter *pmadapter = pmpriv->adapter;
9115
9116 ENTER();
9117 if (pioctl_buf) {
9118 misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
9119 cfg = (mlan_ds_misc_chan_trpc_cfg *)&(misc->param.trpc_cfg);
9120 cfg->sub_band = wlan_le16_to_cpu(trpc_cfg->sub_band);
9121 cfg->length = wlan_le16_to_cpu(resp->size);
9122 memcpy_ext(pmadapter, cfg->trpc_buf, (t_u8 *)resp, cfg->length,
9123 sizeof(cfg->trpc_buf));
9124 }
9125 LEAVE();
9126 return MLAN_STATUS_SUCCESS;
9127 }
9128
9129 /**
9130 * @brief This function prepares command of mc_aggr_cfg
9131 *
9132 * @param pmpriv A pointer to mlan_private structure
9133 * @param cmd A pointer to HostCmd_DS_COMMAND structure
9134 * @param cmd_action the action: GET or SET
9135 * @param pdata_buf A pointer to data buffer
9136 * @return MLAN_STATUS_SUCCESS
9137 */
wlan_cmd_mc_aggr_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)9138 mlan_status wlan_cmd_mc_aggr_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
9139 t_u16 cmd_action, t_void *pdata_buf)
9140 {
9141 HostCmd_DS_MC_AGGR_CFG *cfg_cmd =
9142 (HostCmd_DS_MC_AGGR_CFG *)&cmd->params.mc_aggr_cfg;
9143 mlan_ds_mc_aggr_cfg *cfg = (mlan_ds_mc_aggr_cfg *)pdata_buf;
9144
9145 ENTER();
9146
9147 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MC_AGGR_CFG);
9148 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_MC_AGGR_CFG) + S_DS_GEN);
9149 cfg_cmd->action = wlan_cpu_to_le16(cmd_action);
9150
9151 cfg_cmd->enable_bitmap = (t_u8)cfg->enable_bitmap;
9152 cfg_cmd->mask_bitmap = (t_u8)cfg->mask_bitmap;
9153 cfg_cmd->cts2self_offset = wlan_cpu_to_le16(cfg->cts2self_offset);
9154 LEAVE();
9155 return MLAN_STATUS_SUCCESS;
9156 }
9157
9158 /**
9159 * @brief This function handles the command response of mc_aggr_cfg
9160 *
9161 * @param pmpriv A pointer to mlan_private structure
9162 * @param resp A pointer to HostCmd_DS_COMMAND
9163 * @param pioctl_buf A pointer to mlan_ioctl_req structure
9164 *
9165 * @return MLAN_STATUS_SUCCESS
9166 */
wlan_ret_mc_aggr_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)9167 mlan_status wlan_ret_mc_aggr_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
9168 mlan_ioctl_req *pioctl_buf)
9169 {
9170 HostCmd_DS_MC_AGGR_CFG *cfg_cmd =
9171 (HostCmd_DS_MC_AGGR_CFG *)&resp->params.mc_aggr_cfg;
9172 mlan_ds_misc_cfg *misc_cfg = MNULL;
9173
9174 ENTER();
9175
9176 if (pioctl_buf) {
9177 misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
9178 misc_cfg->param.mc_aggr_cfg.enable_bitmap =
9179 (t_u8)cfg_cmd->enable_bitmap;
9180 misc_cfg->param.mc_aggr_cfg.mask_bitmap =
9181 (t_u8)cfg_cmd->mask_bitmap;
9182 misc_cfg->param.mc_aggr_cfg.cts2self_offset =
9183 (t_u8)cfg_cmd->cts2self_offset;
9184 }
9185 LEAVE();
9186 return MLAN_STATUS_SUCCESS;
9187 }
9188
9189 /**
9190 * @brief This function prepares command of ch_load
9191 *
9192 * @param pmpriv A pointer to mlan_private structure
9193 * @param cmd A pointer to HostCmd_DS_COMMAND structure
9194 * @param cmd_action the action: GET or SET
9195 * @param pdata_buf A pointer to data buffer
9196 * @return MLAN_STATUS_SUCCESS
9197 */
wlan_cmd_get_ch_load(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)9198 mlan_status wlan_cmd_get_ch_load(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
9199 t_u16 cmd_action, t_void *pdata_buf)
9200 {
9201 HostCmd_DS_GET_CH_LOAD *cfg_cmd =
9202 (HostCmd_DS_GET_CH_LOAD *)&cmd->params.ch_load;
9203 mlan_ds_ch_load *cfg = (mlan_ds_ch_load *)pdata_buf;
9204
9205 ENTER();
9206
9207 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_GET_CH_LOAD);
9208 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_GET_CH_LOAD) + S_DS_GEN);
9209 cfg_cmd->action = wlan_cpu_to_le16(cmd_action);
9210 cfg_cmd->ch_load = wlan_cpu_to_le16(cfg->ch_load_param);
9211 cfg_cmd->noise = wlan_cpu_to_le16(cfg->noise);
9212 cfg_cmd->rx_quality = wlan_cpu_to_le16(cfg->rx_quality);
9213 cfg_cmd->duration = wlan_cpu_to_le16(cfg->duration);
9214 LEAVE();
9215 return MLAN_STATUS_SUCCESS;
9216 }
9217
9218 /**
9219 * @brief This function handles the command response of ch_load
9220 *
9221 * @param pmpriv A pointer to mlan_private structure
9222 * @param resp A pointer to HostCmd_DS_COMMAND
9223 * @param pioctl_buf A pointer to mlan_ioctl_req structure
9224 *
9225 * @return MLAN_STATUS_SUCCESS
9226 */
wlan_ret_ch_load(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)9227 mlan_status wlan_ret_ch_load(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
9228 mlan_ioctl_req *pioctl_buf)
9229 {
9230 ENTER();
9231 LEAVE();
9232 return MLAN_STATUS_SUCCESS;
9233 }
9234
9235 /**
9236 * @brief This function prepares command of RANGE_EXT
9237 *
9238 * @param pmpriv A pointer to mlan_private structure
9239 * @param cmd A pointer to HostCmd_DS_COMMAND structure
9240 * @param cmd_action the action: GET or SET
9241 * @param pdata_buf A pointer to data buffer
9242 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
9243 */
wlan_cmd_range_ext(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)9244 mlan_status wlan_cmd_range_ext(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
9245 t_u16 cmd_action, t_void *pdata_buf)
9246 {
9247 HostCmd_DS_RANGE_EXT *range_ext = &cmd->params.range_ext;
9248 t_u8 mode = *(t_u8 *)pdata_buf;
9249
9250 ENTER();
9251
9252 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_RANGE_EXT);
9253 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_RANGE_EXT) + S_DS_GEN);
9254 range_ext->action = wlan_cpu_to_le16(cmd_action);
9255
9256 if (cmd_action == HostCmd_ACT_GEN_SET)
9257 range_ext->mode = mode;
9258
9259 LEAVE();
9260 return MLAN_STATUS_SUCCESS;
9261 }
9262
9263 /**
9264 * @brief This function handles the command response of RANGE_EXT
9265 *
9266 * @param pmpriv A pointer to mlan_private structure
9267 * @param resp A pointer to HostCmd_DS_COMMAND
9268 * @param pioctl_buf A pointer to command buffer
9269 *
9270 * @return MLAN_STATUS_SUCCESS
9271 */
wlan_ret_range_ext(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)9272 mlan_status wlan_ret_range_ext(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
9273 mlan_ioctl_req *pioctl_buf)
9274 {
9275 mlan_ds_misc_cfg *misc_cfg = MNULL;
9276 HostCmd_DS_RANGE_EXT *range_ext = &resp->params.range_ext;
9277
9278 ENTER();
9279
9280 if (pioctl_buf &&
9281 (wlan_le16_to_cpu(range_ext->action) == HostCmd_ACT_GEN_GET)) {
9282 misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
9283 misc_cfg->param.range_ext_mode = range_ext->mode;
9284 PRINTM(MCMND, "Get range ext mode %d\n",
9285 misc_cfg->param.range_ext_mode);
9286 }
9287
9288 LEAVE();
9289 return MLAN_STATUS_SUCCESS;
9290 }
9291
9292 /**
9293 * @brief This function prepares command of get_sensor_temp
9294 *
9295 * @param pmpriv A pointer to mlan_private structure
9296 * @param cmd A pointer to HostCmd_DS_COMMAND structure
9297 * @param cmd_action the action: GET or SET
9298 * @param pdata_buf A pointer to data buffer
9299 * @return MLAN_STATUS_SUCCESS
9300 */
wlan_cmd_get_sensor_temp(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action)9301 mlan_status wlan_cmd_get_sensor_temp(pmlan_private pmpriv,
9302 HostCmd_DS_COMMAND *cmd, t_u16 cmd_action)
9303 {
9304 ENTER();
9305
9306 if (cmd_action != HostCmd_ACT_GEN_GET) {
9307 PRINTM(MERROR, "wlan_cmd_get_sensor_temp: support GET only.\n");
9308 LEAVE();
9309 return MLAN_STATUS_FAILURE;
9310 }
9311
9312 cmd->command = wlan_cpu_to_le16(HostCmd_DS_GET_SENSOR_TEMP);
9313 cmd->size = wlan_cpu_to_le16(S_DS_GEN + 4);
9314
9315 LEAVE();
9316 return MLAN_STATUS_SUCCESS;
9317 }
9318 /**
9319 * @brief This function handles the command response of get_sensor_temp
9320 *
9321 * @param pmpriv A pointer to mlan_private structure
9322 * @param resp A pointer to HostCmd_DS_COMMAND
9323 * @param pioctl_buf A pointer to mlan_ioctl_req structure
9324 *
9325 * @return MLAN_STATUS_SUCCESS
9326 */
wlan_ret_get_sensor_temp(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)9327 mlan_status wlan_ret_get_sensor_temp(pmlan_private pmpriv,
9328 HostCmd_DS_COMMAND *resp,
9329 mlan_ioctl_req *pioctl_buf)
9330 {
9331 mlan_ds_misc_cfg *pcfg = MNULL;
9332 const HostCmd_DS_SENSOR_TEMP *pSensorT = &resp->params.temp_sensor;
9333
9334 ENTER();
9335
9336 if (pioctl_buf) {
9337 pcfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
9338 pcfg->param.sensor_temp.temperature =
9339 wlan_le32_to_cpu(pSensorT->temperature);
9340 PRINTM(MCMND, "get SOC temperature %u C \n",
9341 pSensorT->temperature);
9342 }
9343
9344 LEAVE();
9345 return MLAN_STATUS_SUCCESS;
9346 }
9347