1 /** @file mlan_sta_cmdresp.c
2 *
3 * @brief This file provides the handling of command
4 *
5 * Copyright 2008-2024 NXP
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 *
9 */
10
11 /******************************************************
12 Change log:
13 10/21/2008: initial version
14 ******************************************************/
15
16 #include <mlan_api.h>
17
18 /* Additional WMSDK header files */
19 #include <wmerrno.h>
20 #include <osa.h>
21
22 /* Always keep this include at the end of all include files */
23 #include <mlan_remap_mem_operations.h>
24
25 /********************************************************
26 Local Variables
27 ********************************************************/
28
29 /********************************************************
30 Global Variables
31 ********************************************************/
32
33 /********************************************************
34 Local Functions
35 ********************************************************/
36 #if CONFIG_RF_TEST_MODE
37
38 /**
39 * @brief This function prepares command resp of MFG Continuous Tx
40 *
41 * @param pmpriv A pointer to mlan_private structure
42 * @param resp A pointer to HostCmd_DS_COMMAND
43 * @param pioctl_buf A pointer to mlan_ioctl_req structure
44 *
45 * @return MLAN_STATUS_SUCCESS
46 */
wlan_ret_mfg_tx_cont(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)47 static mlan_status wlan_ret_mfg_tx_cont(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf)
48 {
49 mlan_ds_misc_cfg *misc = MNULL;
50 HostCmd_DS_MFG_CMD_TX_CONT *mcmd = (HostCmd_DS_MFG_CMD_TX_CONT *)&resp->params.mfg_tx_cont;
51 mlan_ds_mfg_cmd_tx_cont *cfg = MNULL;
52
53 ENTER();
54 if (!pioctl_buf)
55 {
56 LEAVE();
57 return MLAN_STATUS_FAILURE;
58 }
59 misc = (mlan_ds_misc_cfg *)pioctl_buf;
60 cfg = (mlan_ds_mfg_cmd_tx_cont *)&misc->param.mfg_tx_cont;
61
62 cfg->error = wlan_le32_to_cpu(mcmd->error);
63 cfg->enable_tx = wlan_le32_to_cpu(mcmd->enable_tx);
64 cfg->cw_mode = wlan_le32_to_cpu(mcmd->cw_mode);
65 cfg->payload_pattern = wlan_le32_to_cpu(mcmd->payload_pattern);
66 cfg->cs_mode = wlan_le32_to_cpu(mcmd->cs_mode);
67 cfg->act_sub_ch = wlan_le32_to_cpu(mcmd->act_sub_ch);
68 cfg->tx_rate = wlan_le32_to_cpu(mcmd->tx_rate);
69
70 LEAVE();
71 return MLAN_STATUS_SUCCESS;
72 }
73
74 /**
75 * @brief This function prepares command resp of MFG Tx frame
76 *
77 * @param pmpriv A pointer to mlan_private structure
78 * @param resp A pointer to HostCmd_DS_COMMAND
79 * @param pioctl_buf A pointer to mlan_ioctl_req structure
80 *
81 * @return MLAN_STATUS_SUCCESS
82 */
wlan_ret_mfg_tx_frame(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)83 static mlan_status wlan_ret_mfg_tx_frame(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf)
84 {
85 mlan_ds_misc_cfg *misc = MNULL;
86 HostCmd_DS_MFG_CMD_TX_FRAME2 *mcmd = (HostCmd_DS_MFG_CMD_TX_FRAME2 *)&resp->params.mfg_tx_frame2;
87 mlan_ds_mfg_cmd_tx_frame2 *cfg = MNULL;
88
89 ENTER();
90 if (!pioctl_buf)
91 {
92 LEAVE();
93 return MLAN_STATUS_FAILURE;
94 }
95 misc = (mlan_ds_misc_cfg *)pioctl_buf;
96 cfg = (mlan_ds_mfg_cmd_tx_frame2 *)&misc->param.mfg_tx_frame2;
97
98 cfg->error = wlan_le32_to_cpu(mcmd->error);
99 cfg->enable = wlan_le32_to_cpu(mcmd->enable);
100 cfg->data_rate = wlan_le32_to_cpu(mcmd->data_rate);
101 cfg->frame_pattern = wlan_le32_to_cpu(mcmd->frame_pattern);
102 cfg->frame_length = wlan_le32_to_cpu(mcmd->frame_length);
103 cfg->adjust_burst_sifs = wlan_le16_to_cpu(mcmd->adjust_burst_sifs);
104 cfg->burst_sifs_in_us = wlan_le32_to_cpu(mcmd->burst_sifs_in_us);
105 cfg->short_preamble = wlan_le32_to_cpu(mcmd->short_preamble);
106 cfg->act_sub_ch = wlan_le32_to_cpu(mcmd->act_sub_ch);
107 cfg->short_gi = wlan_le32_to_cpu(mcmd->short_gi);
108 cfg->tx_bf = wlan_le32_to_cpu(mcmd->tx_bf);
109 cfg->gf_mode = wlan_le32_to_cpu(mcmd->gf_mode);
110 cfg->stbc = wlan_le32_to_cpu(mcmd->stbc);
111 memcpy(cfg->bssid, mcmd->bssid, sizeof(cfg->bssid));
112
113 LEAVE();
114 return MLAN_STATUS_SUCCESS;
115 }
116
117 /**
118 * @brief This function prepares command resp of MFG HE TB Tx
119 *
120 * @param pmpriv A pointer to mlan_private structure
121 * @param resp A pointer to HostCmd_DS_COMMAND
122 * @param pioctl_buf A pointer to mlan_ioctl_req structure
123 *
124 * @return MLAN_STATUS_SUCCESS
125 */
126
wlan_ret_mfg_he_tb_tx(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)127 static mlan_status wlan_ret_mfg_he_tb_tx(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf)
128 {
129 mlan_ds_misc_cfg *misc = MNULL;
130 HostCmd_DS_MFG_CMD_HE_TBTX_T *mcmd = (HostCmd_DS_MFG_CMD_HE_TBTX_T *)&resp->params.mfg_he_power;
131 mlan_ds_mfg_Cmd_HE_TBTx_t *cfg = MNULL;
132
133 ENTER();
134 if (!pioctl_buf)
135 {
136 LEAVE();
137 return MLAN_STATUS_FAILURE;
138 }
139 misc = (mlan_ds_misc_cfg *)pioctl_buf;
140 cfg = (mlan_ds_mfg_Cmd_HE_TBTx_t *)&misc->param.mfg_he_power;
141
142 cfg->enable = wlan_le16_to_cpu(mcmd->enable);
143 cfg->qnum = wlan_le16_to_cpu(mcmd->qnum);
144 cfg->aid = wlan_le16_to_cpu(mcmd->aid);
145 cfg->axq_mu_timer = wlan_le16_to_cpu(mcmd->axq_mu_timer);
146 cfg->tx_power = wlan_le16_to_cpu(mcmd->tx_power);
147
148 LEAVE();
149 return MLAN_STATUS_SUCCESS;
150 }
151
152 /**
153 * @brief This function prepares command resp of MFG OTP MAC add
154 *
155 * @param pmpriv A pointer to mlan_private structure
156 * @param resp A pointer to HostCmd_DS_COMMAND
157 * @param pioctl_buf A pointer to mlan_ioctl_req structure
158 *
159 * @return MLAN_STATUS_SUCCESS
160 */
161
wlan_ret_mfg_otp_mac_add(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)162 static mlan_status wlan_ret_mfg_otp_mac_add(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf)
163 {
164 mlan_ds_misc_cfg *misc = MNULL;
165 HostCmd_DS_MFG_CMD_OTP_MAC_ADD_T *mcmd = (HostCmd_DS_MFG_CMD_OTP_MAC_ADD_T *)&resp->params.mfg_otp_mac_addr_rd_wr;
166 mlan_ds_mfg_cmd_otp_mac_addr_rd_wr_t *cfg = MNULL;
167
168 ENTER();
169 if (!pioctl_buf)
170 {
171 LEAVE();
172 return MLAN_STATUS_FAILURE;
173 }
174 misc = (mlan_ds_misc_cfg *)pioctl_buf;
175 cfg = (mlan_ds_mfg_cmd_otp_mac_addr_rd_wr_t *)&misc->param.mfg_otp_mac_addr_rd_wr;
176
177 memcpy(cfg->mac_addr, mcmd->mac_addr, MLAN_MAC_ADDR_LENGTH);
178
179 LEAVE();
180 return MLAN_STATUS_SUCCESS;
181 }
182
183 /**
184 * @brief This function prepares command resp of MFG OTP cal data
185 *
186 * @param pmpriv A pointer to mlan_private structure
187 * @param resp A pointer to HostCmd_DS_COMMAND
188 * @param pioctl_buf A pointer to mlan_ioctl_req structure
189 *
190 * @return MLAN_STATUS_SUCCESS
191 */
192
wlan_ret_mfg_otp_cal_data(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)193 static mlan_status wlan_ret_mfg_otp_cal_data(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf)
194 {
195 mlan_ds_misc_cfg *misc = MNULL;
196 HostCmd_DS_MFG_CMD_OTP_CAL_DATA_T *mcmd = (HostCmd_DS_MFG_CMD_OTP_CAL_DATA_T *)&resp->params.mfg_otp_cal_data_rd_wr;
197 mlan_ds_mfg_cmd_otp_cal_data_rd_wr_t *cfg = MNULL;
198
199 ENTER();
200 if (!pioctl_buf)
201 {
202 LEAVE();
203 return MLAN_STATUS_FAILURE;
204 }
205 misc = (mlan_ds_misc_cfg *)pioctl_buf;
206 cfg = (mlan_ds_mfg_cmd_otp_cal_data_rd_wr_t *)&misc->param.mfg_otp_cal_data_rd_wr;
207
208 cfg->cal_data_status = mcmd->cal_data_status;
209 cfg->cal_data_len = mcmd->cal_data_len;
210 memcpy(cfg->cal_data, mcmd->cal_data, mcmd->cal_data_len);
211
212 LEAVE();
213 return MLAN_STATUS_SUCCESS;
214 }
215
216 /**
217 * @brief This function prepares command resp of MFG config Trigger frame
218 *
219 * @param pmpriv A pointer to mlan_private structure
220 * @param resp A pointer to HostCmd_DS_COMMAND
221 * @param pioctl_buf A pointer to mlan_ioctl_req structure
222 *
223 * @return MLAN_STATUS_SUCCESS
224 */
wlan_ret_mfg_config_trigger_frame(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)225 static mlan_status wlan_ret_mfg_config_trigger_frame(pmlan_private pmpriv,
226 HostCmd_DS_COMMAND *resp,
227 mlan_ioctl_req *pioctl_buf)
228 {
229 mlan_ds_misc_cfg *misc = MNULL;
230 HostCmd_MFG_CMD_IEEETYPES_CTLBASICTRIGHDR_T *mcmd =
231 (HostCmd_MFG_CMD_IEEETYPES_CTLBASICTRIGHDR_T *)&resp->params.mfg_tx_trigger_config;
232 mfg_Cmd_IEEEtypes_CtlBasicTrigHdr_t *cfg = MNULL;
233
234 ENTER();
235 if (!pioctl_buf)
236 {
237 LEAVE();
238 return MLAN_STATUS_FAILURE;
239 }
240 misc = (mlan_ds_misc_cfg *)pioctl_buf;
241 cfg = (mfg_Cmd_IEEEtypes_CtlBasicTrigHdr_t *)&misc->param.mfg_tx_trigger_config;
242
243 cfg->enable_tx = wlan_le32_to_cpu(mcmd->enable_tx);
244 cfg->standalone_hetb = wlan_le32_to_cpu(mcmd->standalone_hetb);
245 cfg->frmCtl.type = wlan_le16_to_cpu(mcmd->frmCtl.type);
246 cfg->frmCtl.sub_type = wlan_le16_to_cpu(mcmd->frmCtl.sub_type);
247 cfg->duration = wlan_le16_to_cpu(mcmd->duration);
248
249 cfg->trig_common_field = wlan_le64_to_cpu(mcmd->trig_common_field);
250
251 cfg->trig_user_info_field = wlan_le64_to_cpu(mcmd->trig_user_info_field);
252
253 // memcpy_ext(pmpriv->adapter, &cfg->trig_user_info_field, &mcmd->trig_user_info_field,
254 // sizeof(mcmd->trig_user_info_field), sizeof(cfg->trig_user_info_field));
255
256 cfg->basic_trig_user_info = wlan_le16_to_cpu(mcmd->basic_trig_user_info);
257
258 LEAVE();
259 return MLAN_STATUS_SUCCESS;
260 }
261
262 /**
263 * @brief This function prepares command resp of MFG Cmd
264 *
265 * @param pmpriv A pointer to mlan_private structure
266 * @param resp A pointer to HostCmd_DS_COMMAND
267 * @param pioctl_buf A pointer to mlan_ioctl_req structure
268 *
269 * @return MLAN_STATUS_SUCCESS
270 */
wlan_ret_mfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,void * pioctl_buf)271 mlan_status wlan_ret_mfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, void *pioctl_buf)
272 {
273 HostCmd_DS_MFG_CMD_GENERIC_CFG *mcmd = (HostCmd_DS_MFG_CMD_GENERIC_CFG *)&resp->params.mfg_generic_cfg;
274 mlan_ds_misc_cfg *misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf;
275 mlan_ds_mfg_cmd_generic_cfg *cfg = MNULL;
276 mlan_status ret = MLAN_STATUS_SUCCESS;
277
278 ENTER();
279 if (!pioctl_buf)
280 {
281 LEAVE();
282 return MLAN_STATUS_FAILURE;
283 }
284 switch (wlan_le32_to_cpu(mcmd->mfg_cmd))
285 {
286 case MFG_CMD_TX_CONT:
287 ret = wlan_ret_mfg_tx_cont(pmpriv, resp, pioctl_buf);
288 goto cmd_mfg_done;
289 case MFG_CMD_TX_FRAME:
290 ret = wlan_ret_mfg_tx_frame(pmpriv, resp, pioctl_buf);
291 goto cmd_mfg_done;
292 case MFG_CMD_CONFIG_MAC_HE_TB_TX:
293 ret = wlan_ret_mfg_he_tb_tx(pmpriv, resp, pioctl_buf);
294 goto cmd_mfg_done;
295 case MFG_CMD_CONFIG_TRIGGER_FRAME:
296 ret = wlan_ret_mfg_config_trigger_frame(pmpriv, resp, pioctl_buf);
297 goto cmd_mfg_done;
298 case MFG_CMD_OTP_MAC_ADD:
299 ret = wlan_ret_mfg_otp_mac_add(pmpriv, resp, pioctl_buf);
300 goto cmd_mfg_done;
301 case MFG_CMD_OTP_CAL_DATA:
302 ret = wlan_ret_mfg_otp_cal_data(pmpriv, resp, pioctl_buf);
303 goto cmd_mfg_done;
304 case MFG_CMD_SET_TEST_MODE:
305 case MFG_CMD_UNSET_TEST_MODE:
306 case MFG_CMD_TX_ANT:
307 case MFG_CMD_RX_ANT:
308 case MFG_CMD_RF_CHAN:
309 case MFG_CMD_CLR_RX_ERR:
310 case MFG_CMD_RF_BAND_AG:
311 case MFG_CMD_RF_CHANNELBW:
312 case MFG_CMD_RADIO_MODE_CFG:
313 case MFG_CMD_RFPWR:
314 break;
315 default:
316 ret = MLAN_STATUS_FAILURE;
317 goto cmd_mfg_done;
318 }
319 cfg = (mlan_ds_mfg_cmd_generic_cfg *)&(misc_cfg->param);
320
321 cfg->error = wlan_le32_to_cpu(mcmd->error);
322 cfg->data1 = wlan_le32_to_cpu(mcmd->data1);
323 cfg->data2 = wlan_le32_to_cpu(mcmd->data2);
324 cfg->data3 = wlan_le32_to_cpu(mcmd->data3);
325 cmd_mfg_done:
326 LEAVE();
327 return ret;
328 }
329 #endif
330
331 /**
332 * @brief This function handles the command response of snmp_mib
333 *
334 * @param pmpriv A pointer to mlan_private structure
335 * @param resp A pointer to HostCmd_DS_COMMAND
336 * @param pioctl_buf A pointer to mlan_ioctl_req structure
337 *
338 * @return MLAN_STATUS_SUCCESS
339 */
wlan_ret_802_11_snmp_mib(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * resp,IN mlan_ioctl_req * pioctl_buf)340 static mlan_status wlan_ret_802_11_snmp_mib(IN pmlan_private pmpriv,
341 IN HostCmd_DS_COMMAND *resp,
342 IN mlan_ioctl_req *pioctl_buf)
343 {
344 HostCmd_DS_802_11_SNMP_MIB *psmib = &resp->params.smib;
345 t_u16 oid = wlan_le16_to_cpu(psmib->oid);
346 t_u16 query_type = wlan_le16_to_cpu(psmib->query_type);
347 t_u32 ul_temp;
348
349 mlan_ds_snmp_mib *mib = MNULL;
350
351 ENTER();
352
353 if (pioctl_buf != MNULL)
354 {
355 mib = (mlan_ds_snmp_mib *)(void *)pioctl_buf->pbuf;
356 }
357
358 /* wmsdk */
359 PRINTM(MINFO, "SNMP_RESP: value of the oid = 0x%x, query_type=0x%x\n", oid, query_type);
360 PRINTM(MINFO, "SNMP_RESP: Buf size = 0x%x\n", wlan_le16_to_cpu(psmib->buf_size));
361
362 if (query_type == HostCmd_ACT_GEN_GET)
363 {
364 /* wmsdk: GET is not used. Disable */
365 switch (oid)
366 {
367 case DtimPeriod_i:
368 ul_temp = psmib->value[0];
369 PRINTM(MINFO, "SNMP_RESP: DTIM Period =%u\n", ul_temp);
370 if (mib != MNULL)
371 {
372 mib->param.dtim_period = ul_temp;
373 }
374 break;
375 #if CONFIG_WIFI_FRAG_THRESHOLD
376 case FragThresh_i:
377 ul_temp = wlan_le16_to_cpu(*((t_u16 *)(psmib->value)));
378 PRINTM(MINFO, "SNMP_RESP: FragThsd =%u\n", ul_temp);
379 if (mib)
380 {
381 mib->param.frag_threshold = ul_temp;
382 }
383 break;
384 #endif
385 #if CONFIG_WIFI_RTS_THRESHOLD
386 case RtsThresh_i:
387 ul_temp = wlan_le16_to_cpu(*((t_u16 *)(psmib->value)));
388 PRINTM(MINFO, "SNMP_RESP: RTSThsd =%u\n", ul_temp);
389 if (mib)
390 {
391 mib->param.rts_threshold = ul_temp;
392 }
393 break;
394 #endif
395 default:
396 PRINTM(MINFO, "Unexpected snmp_mib oid\n");
397 break;
398 }
399 }
400 else
401 { /* (query_type == HostCmd_ACT_GEN_SET) */
402 /* Update state for 11d */
403 if (oid == Dot11D_i)
404 {
405 ul_temp = wlan_le16_to_cpu(*((t_u16 *)(void *)(psmib->value)));
406 /* Set 11d state to private */
407 pmpriv->state_11d.enable_11d = (state_11d_t)ul_temp;
408 /* Set user enable flag if called from ioctl */
409 if (pioctl_buf != NULL)
410 {
411 pmpriv->state_11d.user_enable_11d = (state_11d_t)ul_temp;
412 }
413 }
414 /* Update state for 11h */
415 if (oid == Dot11H_i)
416 {
417 ul_temp = wlan_le16_to_cpu(*((t_u16 *)(void *)(psmib->value)));
418 /* Set 11h state to priv */
419 pmpriv->intf_state_11h.is_11h_active = (ul_temp & ENABLE_11H_MASK) ? MTRUE : MFALSE;
420 /* Set radar_det state to adapter */
421 pmpriv->adapter->state_11h.is_master_radar_det_active = (ul_temp & MASTER_RADAR_DET_MASK) ? MTRUE : MFALSE;
422 pmpriv->adapter->state_11h.is_slave_radar_det_active = (ul_temp & SLAVE_RADAR_DET_MASK) ? MTRUE : MFALSE;
423 }
424 }
425
426 if (pioctl_buf != NULL)
427 {
428 /* Indicate ioctl complete */
429 pioctl_buf->data_read_written = sizeof(mlan_ds_snmp_mib);
430 }
431
432 LEAVE();
433 return MLAN_STATUS_SUCCESS;
434 }
435
436 /**
437 * @brief This function handles the command response of get_log
438 *
439 * @param pmpriv A pointer to mlan_private structure
440 * @param resp A pointer to HostCmd_DS_COMMAND
441 * @param pioctl_buf A pointer to mlan_ioctl_req structure
442 *
443 * @return MLAN_STATUS_SUCCESS
444 */
wlan_ret_get_log(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * resp,IN mlan_ioctl_req * pioctl_buf)445 static mlan_status wlan_ret_get_log(IN pmlan_private pmpriv, IN HostCmd_DS_COMMAND *resp, IN mlan_ioctl_req *pioctl_buf)
446 {
447 HostCmd_DS_802_11_GET_LOG *pget_log = (HostCmd_DS_802_11_GET_LOG *)&resp->params.get_log;
448 mlan_ds_get_info *pget_info = MNULL;
449
450 ENTER();
451 if (pioctl_buf != NULL)
452 {
453 pget_info = (mlan_ds_get_info *)(void *)pioctl_buf->pbuf;
454 pget_info->param.stats.mcast_tx_frame = wlan_le32_to_cpu(pget_log->mcast_tx_frame);
455 pget_info->param.stats.failed = wlan_le32_to_cpu(pget_log->failed);
456 pget_info->param.stats.retry = wlan_le32_to_cpu(pget_log->retry);
457 pget_info->param.stats.multi_retry = wlan_le32_to_cpu(pget_log->multiretry);
458 pget_info->param.stats.frame_dup = wlan_le32_to_cpu(pget_log->frame_dup);
459 pget_info->param.stats.rts_success = wlan_le32_to_cpu(pget_log->rts_success);
460 pget_info->param.stats.rts_failure = wlan_le32_to_cpu(pget_log->rts_failure);
461 pget_info->param.stats.ack_failure = wlan_le32_to_cpu(pget_log->ack_failure);
462 pget_info->param.stats.rx_frag = wlan_le32_to_cpu(pget_log->rx_frag);
463 pget_info->param.stats.mcast_rx_frame = wlan_le32_to_cpu(pget_log->mcast_rx_frame);
464 pget_info->param.stats.fcs_error = wlan_le32_to_cpu(pget_log->fcs_error);
465 pget_info->param.stats.tx_frame = wlan_le32_to_cpu(pget_log->tx_frame);
466 pget_info->param.stats.wep_icv_error[0] = wlan_le32_to_cpu(pget_log->wep_icv_err_cnt[0]);
467 pget_info->param.stats.wep_icv_error[1] = wlan_le32_to_cpu(pget_log->wep_icv_err_cnt[1]);
468 pget_info->param.stats.wep_icv_error[2] = wlan_le32_to_cpu(pget_log->wep_icv_err_cnt[2]);
469 pget_info->param.stats.wep_icv_error[3] = wlan_le32_to_cpu(pget_log->wep_icv_err_cnt[3]);
470 /* Indicate ioctl complete */
471 pioctl_buf->data_read_written = sizeof(mlan_ds_get_info);
472 }
473 LEAVE();
474 return MLAN_STATUS_SUCCESS;
475 }
476
477 /**
478 * @brief Get power level and rate index
479 *
480 * @param pmpriv A pointer to mlan_private structure
481 * @param pdata_buf Pointer to the data buffer
482 *
483 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
484 */
wlan_get_power_level(pmlan_private pmpriv,void * pdata_buf)485 static mlan_status wlan_get_power_level(pmlan_private pmpriv, void *pdata_buf)
486 {
487 int length = -1, max_power = -1, min_power = -1;
488 MrvlTypes_Power_Group_t *ppg_tlv = MNULL;
489 Power_Group_t *pg = MNULL;
490
491 ENTER();
492
493 if (pdata_buf != NULL)
494 {
495 ppg_tlv = (MrvlTypes_Power_Group_t *)(void *)((t_u8 *)pdata_buf + sizeof(HostCmd_DS_TXPWR_CFG));
496 pg = (Power_Group_t *)(void *)((t_u8 *)ppg_tlv + sizeof(MrvlTypes_Power_Group_t));
497 length = (int)ppg_tlv->length;
498 if (length > 0)
499 {
500 max_power = (int)pg->power_max;
501 min_power = (int)pg->power_min;
502 length -= (int)sizeof(Power_Group_t);
503 }
504 while (length > 0)
505 {
506 pg++;
507 if (max_power < pg->power_max)
508 {
509 max_power = (int)pg->power_max;
510 }
511 if (min_power > pg->power_min)
512 {
513 min_power = (int)pg->power_min;
514 }
515 length -= (int)sizeof(Power_Group_t);
516 }
517 if (ppg_tlv->length > 0U)
518 {
519 pmpriv->min_tx_power_level = (t_u8)min_power;
520 pmpriv->max_tx_power_level = (t_u8)max_power;
521 }
522 }
523 else
524 {
525 LEAVE();
526 return MLAN_STATUS_FAILURE;
527 }
528
529 LEAVE();
530 return MLAN_STATUS_SUCCESS;
531 }
532 /**
533 * @brief This function handles the command response of tx_power_cfg
534 *
535 * @param pmpriv A pointer to mlan_private structure
536 * @param resp A pointer to HostCmd_DS_COMMAND
537 * @param pioctl_buf A pointer to mlan_ioctl_req structure
538 *
539 * @return MLAN_STATUS_SUCCESS
540 */
wlan_ret_tx_power_cfg(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * resp,IN mlan_ioctl_req * pioctl_buf)541 static mlan_status wlan_ret_tx_power_cfg(IN pmlan_private pmpriv,
542 IN HostCmd_DS_COMMAND *resp,
543 IN mlan_ioctl_req *pioctl_buf)
544 {
545 HostCmd_DS_TXPWR_CFG *ptxp_cfg = &resp->params.txp_cfg;
546 MrvlTypes_Power_Group_t *ppg_tlv = MNULL;
547 Power_Group_t *pg = MNULL;
548 t_u16 action = wlan_le16_to_cpu(ptxp_cfg->action);
549 mlan_ds_power_cfg *power = MNULL;
550 t_u32 data[5];
551 bool invalid_hostcmd = MFALSE;
552
553 ENTER();
554
555 ppg_tlv = (MrvlTypes_Power_Group_t *)(void *)((t_u8 *)&resp->params + sizeof(HostCmd_DS_TXPWR_CFG));
556 pg = (Power_Group_t *)(void *)((t_u8 *)ppg_tlv + sizeof(MrvlTypes_Power_Group_t));
557
558 switch (action)
559 {
560 case HostCmd_ACT_GEN_GET:
561 ppg_tlv->length = wlan_le16_to_cpu(ppg_tlv->length);
562 if (pmpriv->adapter->hw_status == WlanHardwareStatusInitializing)
563 {
564 // coverity[overrun-buffer-val:SUPPRESS]
565 (void)wlan_get_power_level(pmpriv, ptxp_cfg);
566 }
567 pmpriv->tx_power_level = (t_u16)pg->power_min;
568 PRINTM(MMSG, "The Sta tx power level: %d\r\n", pmpriv->tx_power_level);
569 break;
570
571 case HostCmd_ACT_GEN_SET:
572 if (wlan_le32_to_cpu(ptxp_cfg->mode) != 0U)
573 {
574 if (pg->power_max == pg->power_min)
575 {
576 pmpriv->tx_power_level = (t_u16)pg->power_min;
577 }
578 }
579 break;
580 default:
581 PRINTM(MERROR, "CMD_RESP: unknown command action %d\n", action);
582 invalid_hostcmd = MTRUE;
583 break;
584 }
585 if (invalid_hostcmd == MTRUE)
586 {
587 LEAVE();
588 return MLAN_STATUS_SUCCESS;
589 }
590
591 PRINTM(MINFO, "Current TxPower Level = %d,Max Power=%d, Min Power=%d\n", pmpriv->tx_power_level,
592 pmpriv->max_tx_power_level, pmpriv->min_tx_power_level);
593
594 if (pioctl_buf != MNULL)
595 {
596 power = (mlan_ds_power_cfg *)(void *)pioctl_buf->pbuf;
597 if (action == HostCmd_ACT_GEN_GET)
598 {
599 if (power->sub_command == MLAN_OID_POWER_CFG)
600 {
601 pioctl_buf->data_read_written = sizeof(mlan_power_cfg_t) + MLAN_SUB_COMMAND_SIZE;
602 power->param.power_cfg.power_level = pmpriv->tx_power_level;
603 if (wlan_le32_to_cpu(ptxp_cfg->mode) != 0U)
604 {
605 power->param.power_cfg.is_power_auto = MFALSE;
606 }
607 else
608 {
609 power->param.power_cfg.is_power_auto = MTRUE;
610 }
611 }
612 else
613 {
614 power->param.power_ext.len = 0;
615 while (ppg_tlv->length != 0U)
616 {
617 data[0] = pg->first_rate_code;
618 data[1] = pg->last_rate_code;
619 if (pg->modulation_class == MOD_CLASS_OFDM)
620 {
621 data[0] += MLAN_RATE_INDEX_OFDM0;
622 data[1] += MLAN_RATE_INDEX_OFDM0;
623 }
624 else if (pg->modulation_class == MOD_CLASS_HT)
625 {
626 data[0] += MLAN_RATE_INDEX_MCS0;
627 data[1] += MLAN_RATE_INDEX_MCS0;
628 if (pg->ht_bandwidth == HT_BW_40)
629 {
630 data[0] |= TX_RATE_HT_BW40_BIT;
631 data[1] |= TX_RATE_HT_BW40_BIT;
632 }
633 }
634 else
635 {
636 /* Do Nothing */
637 }
638 data[2] = (t_u32)pg->power_min;
639 data[3] = (t_u32)pg->power_max;
640 data[4] = (t_u32)pg->power_step;
641 (void)__memcpy(pmpriv->adapter,
642 (t_u8 *)(&power->param.power_ext.power_data[power->param.power_ext.len]),
643 (t_u8 *)data, sizeof(data));
644 power->param.power_ext.len += 5U;
645 pg++;
646 ppg_tlv->length -= (t_u16)sizeof(Power_Group_t);
647 }
648 pioctl_buf->data_read_written = sizeof(mlan_power_cfg_ext) + MLAN_SUB_COMMAND_SIZE;
649 }
650 }
651 }
652
653 LEAVE();
654 return MLAN_STATUS_SUCCESS;
655 }
656
657 #if CONFIG_WMM_UAPSD
658 /**
659 * @brief This function handles the command response of sleep_period
660 *
661 * @param pmpriv A pointer to mlan_private structure
662 * @param resp A pointer to HostCmd_DS_COMMAND
663 * @param pioctl_buf A pointer to mlan_ioctl_req structure
664 * @return MLAN_STATUS_SUCCESS
665 */
wlan_ret_802_11_sleep_period(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * resp,IN mlan_ioctl_req * pioctl_buf)666 static mlan_status wlan_ret_802_11_sleep_period(IN pmlan_private pmpriv,
667 IN HostCmd_DS_COMMAND *resp,
668 IN mlan_ioctl_req *pioctl_buf)
669 {
670 HostCmd_DS_802_11_SLEEP_PERIOD *pcmd_sleep_pd = &resp->params.sleep_pd;
671 mlan_ds_pm_cfg *pm_cfg = MNULL;
672 t_u16 sleep_pd = 0;
673
674 ENTER();
675
676 sleep_pd = wlan_le16_to_cpu(pcmd_sleep_pd->sleep_pd);
677 if (pioctl_buf)
678 {
679 pm_cfg = (mlan_ds_pm_cfg *)pioctl_buf->pbuf;
680 pm_cfg->param.sleep_period = (t_u32)sleep_pd;
681 pioctl_buf->data_read_written = sizeof(pm_cfg->param.sleep_period) + MLAN_SUB_COMMAND_SIZE;
682 }
683 pmpriv->adapter->sleep_period.period = sleep_pd;
684
685 pmpriv->adapter->pps_uapsd_mode = MFALSE;
686 pmpriv->adapter->tx_lock_flag = MFALSE;
687 if ((pmpriv->adapter->sleep_period.period != 0) &&
688 (pmpriv->adapter->sleep_period.period != SLEEP_PERIOD_RESERVED_FF))
689 {
690 pmpriv->adapter->gen_null_pkt = MTRUE;
691 }
692 else
693 {
694 pmpriv->adapter->gen_null_pkt = MFALSE;
695 }
696
697 LEAVE();
698 return MLAN_STATUS_SUCCESS;
699 }
700 #endif
701
702 /**
703 * @brief This function handles the command response of deauthenticate
704 *
705 * @param pmpriv A pointer to mlan_private structure
706 * @param resp A pointer to HostCmd_DS_COMMAND
707 * @param pioctl_buf A pointer to mlan_ioctl_req structure
708 *
709 * @return MLAN_STATUS_SUCCESS
710 */
wlan_ret_802_11_deauthenticate(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * resp,IN mlan_ioctl_req * pioctl_buf)711 mlan_status wlan_ret_802_11_deauthenticate(IN pmlan_private pmpriv,
712 IN HostCmd_DS_COMMAND *resp,
713 IN mlan_ioctl_req *pioctl_buf)
714 {
715 ENTER();
716 wlan_reset_connect_state(pmpriv, MTRUE);
717
718 LEAVE();
719 return MLAN_STATUS_SUCCESS;
720 }
721
722 /**
723 * @brief This function handles the command response of rf_channel
724 *
725 * @param pmpriv A pointer to mlan_private structure
726 * @param resp A pointer to HostCmd_DS_COMMAND
727 * @param pioctl_buf A pointer to mlan_ioctl_req structure
728 *
729 * @return MLAN_STATUS_SUCCESS
730 */
wlan_ret_802_11_rf_channel(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * resp,IN mlan_ioctl_req * pioctl_buf)731 static mlan_status wlan_ret_802_11_rf_channel(IN pmlan_private pmpriv,
732 IN HostCmd_DS_COMMAND *resp,
733 IN mlan_ioctl_req *pioctl_buf)
734 {
735 ENTER();
736 /* fixme: enable this part when needed */
737 LEAVE();
738 return MLAN_STATUS_SUCCESS;
739 }
740
741 #if CONFIG_11K_OFFLOAD
742 /**
743 * @brief This function handles the command response of offload feature
744 *
745 * @param priv A pointer to mlan_private structure
746 * @param resp A pointer to HostCmd_DS_COMMAND
747 *
748 * @return MLAN_STATUS_SUCCESS
749 */
wlan_ret_offload_feature_ctrl(mlan_private * priv,HostCmd_DS_COMMAND * resp)750 static mlan_status wlan_ret_offload_feature_ctrl(mlan_private *priv, HostCmd_DS_COMMAND *resp)
751 {
752 mlan_status ret = MLAN_STATUS_SUCCESS;
753 HostCmd_OFFLOAD_FEATURE_CTRL *fctrl = &resp->params.fctrl;
754 ENTER();
755
756 PRINTM(MINFO, "offload feature ctrl set successful \n");
757 if (fctrl->featureSelect == 0)
758 {
759 PRINTM(MCMND, "11k: Neighbor Report %s \n", fctrl->control.std.dot11k_nbor_support ? "enabled" : "disabled");
760 PRINTM(MCMND, "11k: Traffic Stream Measurement %s \n", fctrl->control.std.dot11k_tsm ? "enabled" : "disabled");
761 PRINTM(MCMND, "11k: Link Measurement %s \n", fctrl->control.std.dot11k_lm ? "enabled" : "disabled");
762 PRINTM(MCMND, "11k: Beacon Report %s \n", fctrl->control.std.dot11k_rm ? "enabled" : "disabled");
763 PRINTM(MCMND, "11v: BSS Transition %s \n", fctrl->control.std.dot11v_bss_trans ? "enabled" : "disabled");
764
765 priv->enable_11k = fctrl->control.std.dot11k_nbor_support | fctrl->control.std.dot11k_tsm |
766 fctrl->control.std.dot11k_lm | fctrl->control.std.dot11k_rm;
767 if (priv->enable_11k)
768 {
769 priv->ext_cap.BSS_Transition = 1U;
770 }
771 else
772 {
773 priv->ext_cap.BSS_Transition = 0U;
774 }
775 PRINTM(MMSG, "11K %s \n", priv->enable_11k ? "enable" : "disable");
776 }
777
778 LEAVE();
779 return ret;
780 }
781 #endif
782
783 #if (CONFIG_SUBSCRIBE_EVENT_SUPPORT)
784 /**
785 * @brief This function handles the command response of
786 * subscribe event
787 *
788 * @param pmpriv A pointer to mlan_private structure
789 * @param resp A pointer to HostCmd_DS_COMMAND
790 * @param pioctl_buf A pointer to command buffer
791 *
792 * @return MLAN_STATUS_SUCCESS
793 */
wlan_ret_subscribe_event(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * resp,IN mlan_ioctl_req * sub_evt)794 static mlan_status wlan_ret_subscribe_event(IN pmlan_private pmpriv,
795 IN HostCmd_DS_COMMAND *resp,
796 IN mlan_ioctl_req *sub_evt)
797 {
798 ENTER();
799 if (sub_evt && wlan_parse_getdata(resp, (mlan_ds_subscribe_evt *)sub_evt) != WM_SUCCESS)
800 {
801 wevt_w("get subscribe event fail\n");
802 return MLAN_STATUS_FAILURE;
803 }
804 LEAVE();
805
806 return MLAN_STATUS_SUCCESS;
807 }
808 #endif
809
810 /********************************************************
811 Global Functions
812 ********************************************************/
813 /**
814 * @brief This function handles the station command response
815 *
816 * @param priv A pointer to mlan_private structure
817 * @param cmdresp_no cmd no
818 * @param pcmd_buf cmdresp buf
819 * @param pioctl A pointer to ioctl buf
820 *
821 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
822 */
wlan_ops_sta_process_cmdresp(IN t_void * priv,IN t_u16 cmdresp_no,IN t_void * pcmd_buf,IN t_void * pioctl)823 mlan_status wlan_ops_sta_process_cmdresp(IN t_void *priv, IN t_u16 cmdresp_no, IN t_void *pcmd_buf, IN t_void *pioctl)
824 {
825 mlan_status ret = MLAN_STATUS_SUCCESS;
826 mlan_private *pmpriv = (mlan_private *)priv;
827 HostCmd_DS_COMMAND *resp = (HostCmd_DS_COMMAND *)pcmd_buf;
828 mlan_ioctl_req *pioctl_buf = (mlan_ioctl_req *)pioctl;
829 /* mlan_adapter *pmadapter = pmpriv->adapter; */
830 /* int ctr; */
831
832 ENTER();
833
834 /* Command successful, handle response */
835 switch (cmdresp_no)
836 {
837 case HostCmd_CMD_GET_HW_SPEC:
838 ret = wlan_ret_get_hw_spec(pmpriv, resp, pioctl_buf);
839 break;
840 case HostCmd_CMD_TXPWR_CFG:
841 ret = wlan_ret_tx_power_cfg(pmpriv, resp, pioctl_buf);
842 break;
843 case HostCmd_CMD_TX_RATE_CFG:
844 ret = wlan_ret_tx_rate_cfg(pmpriv, resp, pioctl_buf);
845 break;
846 #if !CONFIG_EXT_SCAN_SUPPORT
847 case HostCmd_CMD_802_11_SCAN:
848 ret = wlan_ret_802_11_scan(pmpriv, resp, pioctl_buf);
849 pioctl_buf = MNULL;
850 /* pmadapter->curr_cmd->pioctl_buf = MNULL; */
851 break;
852 #else
853 case HostCmd_CMD_802_11_SCAN_EXT:
854 ret = wlan_ret_802_11_scan_ext(pmpriv, resp, pioctl_buf);
855 pioctl_buf = MNULL;
856 break;
857 #endif /* CONFIG_EXT_SCAN_SUPPORT */
858 #if CONFIG_WMM_UAPSD
859 case HostCmd_CMD_802_11_SLEEP_PERIOD:
860 ret = wlan_ret_802_11_sleep_period(pmpriv, resp, pioctl_buf);
861 break;
862 #endif
863 case HostCmd_CMD_802_11_ASSOCIATE:
864 ret = wlan_ret_802_11_associate(pmpriv, resp, pioctl_buf);
865 break;
866 case HostCmd_CMD_802_11_GET_LOG:
867 ret = wlan_ret_get_log(pmpriv, resp, pioctl_buf);
868 break;
869 case HostCmd_CMD_802_11_SNMP_MIB:
870 ret = wlan_ret_802_11_snmp_mib(pmpriv, resp, pioctl_buf);
871 break;
872 case HostCmd_CMD_802_11_TX_RATE_QUERY:
873 ret = wlan_ret_802_11_tx_rate_query(pmpriv, resp, pioctl_buf);
874 break;
875 case HostCmd_CMD_802_11_RF_CHANNEL:
876 ret = wlan_ret_802_11_rf_channel(pmpriv, resp, pioctl_buf);
877 break;
878 #if CONFIG_WMM
879 case HostCmd_CMD_WMM_PARAM_CONFIG:
880 ret = wlan_ret_wmm_param_config(pmpriv, resp, pioctl_buf);
881 break;
882 #endif
883 #if CONFIG_SUBSCRIBE_EVENT_SUPPORT
884 case HostCmd_CMD_802_11_SUBSCRIBE_EVENT:
885 ret = wlan_ret_subscribe_event(pmpriv, resp, pioctl_buf);
886 break;
887 #endif
888 #if (CONFIG_BG_SCAN)
889 case HostCmd_CMD_802_11_BG_SCAN_QUERY:
890 ret = wlan_ret_802_11_scan(pmpriv, resp, pioctl_buf);
891 PRINTM(MINFO, "CMD_RESP: BG_SCAN result is ready!\n");
892 break;
893 #endif
894 #if CONFIG_RF_TEST_MODE
895 case HostCmd_CMD_MFG_COMMAND:
896 ret = wlan_ret_mfg(pmpriv, resp, pioctl_buf);
897 break;
898 #endif
899 #ifdef OTP_CHANINFO
900 case HostCmd_CMD_CHAN_REGION_CFG:
901 ret = wlan_ret_chan_region_cfg(pmpriv, resp, pioctl_buf);
902 break;
903 #endif
904 case HostCmd_CMD_BOOT_SLEEP:
905 ret = wlan_ret_boot_sleep(pmpriv, resp, pioctl_buf);
906 break;
907 #if CONFIG_11AX
908 case HostCmd_CMD_11AX_CMD:
909 ret = wlan_ret_11ax_cmd(pmpriv, resp, pioctl_buf);
910 break;
911 #endif
912 #if CONFIG_WIFI_CLOCKSYNC
913 case HostCmd_GPIO_TSF_LATCH_PARAM_CONFIG:
914 ret = wlan_ret_gpio_tsf_latch(pmpriv, resp, pioctl_buf);
915 break;
916 #endif /* CONFIG_WIFI_CLOCKSYNC */
917 #if CONFIG_11K_OFFLOAD
918 case HostCmd_CMD_OFFLOAD_FEATURE_CONTROL:
919 ret = wlan_ret_offload_feature_ctrl(pmpriv, resp);
920 break;
921 #endif /* CONFIG_11K_OFFLOAD*/
922 #if CONFIG_MULTI_CHAN
923 case HostCmd_CMD_MULTI_CHAN_CONFIG:
924 ret = wlan_ret_multi_chan_cfg(pmpriv, resp, pioctl_buf);
925 break;
926 case HostCmd_CMD_MULTI_CHAN_POLICY:
927 ret = wlan_ret_multi_chan_policy(pmpriv, resp, pioctl_buf);
928 break;
929 case HostCmd_CMD_DRCS_CONFIG:
930 ret = wlan_ret_drcs_cfg(pmpriv, resp, pioctl_buf);
931 break;
932 #endif
933 #if CONFIG_1AS
934 case HostCmd_CMD_HOST_CLOCK_CFG:
935 ret = wlan_ret_host_clock_cfg(pmpriv, resp, pioctl_buf);
936 break;
937 #endif
938 #if (CONFIG_WIFI_IND_RESET) && (CONFIG_WIFI_IND_DNLD)
939 case HostCmd_CMD_INDEPENDENT_RESET_CFG:
940 ret = wlan_ret_ind_rst_cfg(pmpriv, resp, pioctl_buf);
941 break;
942 #endif
943 default:
944 PRINTM(MERROR, "CMD_RESP: Unknown command response %#x\n", resp->command);
945 break;
946 }
947
948 LEAVE();
949 return ret;
950 }
951