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