1 /** @file mlan_sta_cmd.c
2  *
3  *  @brief This file provides the handling of command. It prepares command and sends it to firmware when it is ready
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 mlan_status wlan_cmd_auto_reconnect(IN HostCmd_DS_COMMAND *cmd, IN t_u16 cmd_action, IN t_void *pdata_buf);
26 mlan_status wlan_cmd_mem_access(IN HostCmd_DS_COMMAND *cmd, IN t_u16 cmd_action, IN t_void *pdata_buf);
27 mlan_status wlan_cmd_reg_access(IN HostCmd_DS_COMMAND *cmd, IN t_u16 cmd_action, IN t_void *pdata_buf);
28 mlan_status wlan_cmd_802_11_deauthenticate(IN pmlan_private pmpriv, IN HostCmd_DS_COMMAND *cmd, IN t_void *pdata_buf);
29 
30 /********************************************************
31                 Local Variables
32 ********************************************************/
33 
34 /********************************************************
35                 Global Variables
36 ********************************************************/
37 
38 /********************************************************
39                 Local Functions
40 ********************************************************/
41 #if CONFIG_RF_TEST_MODE
42 /**
43  *  @brief This function prepares command of MFG Continuous Tx cmd.
44  *
45  *  @param pmpriv       A pointer to mlan_private structure
46  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
47  *  @param action       The action: GET or SET
48  *  @param pdata_buf    A pointer to data buffer
49  *
50  *  @return             MLAN_STATUS_SUCCESS
51  */
wlan_cmd_mfg_tx_cont(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 action,t_void * pdata_buf)52 static mlan_status wlan_cmd_mfg_tx_cont(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, t_u16 action, t_void *pdata_buf)
53 {
54     HostCmd_DS_MFG_CMD_TX_CONT *mcmd = (HostCmd_DS_MFG_CMD_TX_CONT *)&cmd->params.mfg_tx_cont;
55     mlan_ds_mfg_cmd_tx_cont *cfg     = (mlan_ds_mfg_cmd_tx_cont *)pdata_buf;
56 
57     ENTER();
58 
59     (void)__memset(pmpriv->adapter, mcmd, 0x00, sizeof(HostCmd_DS_MFG_CMD_TX_CONT));
60 
61     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MFG_COMMAND);
62     cmd->size    = wlan_cpu_to_le16(sizeof(HostCmd_DS_MFG_CMD_TX_CONT) + S_DS_GEN);
63 
64     mcmd->mfg_cmd = wlan_cpu_to_le32(cfg->mfg_cmd);
65     mcmd->action  = wlan_cpu_to_le16(action);
66     if (action == HostCmd_ACT_GEN_SET)
67     {
68         mcmd->enable_tx       = wlan_cpu_to_le32(cfg->enable_tx);
69         mcmd->cw_mode         = wlan_cpu_to_le32(cfg->cw_mode);
70         mcmd->payload_pattern = wlan_cpu_to_le32(cfg->payload_pattern);
71         mcmd->cs_mode         = wlan_cpu_to_le32(cfg->cs_mode);
72         mcmd->act_sub_ch      = wlan_cpu_to_le32(cfg->act_sub_ch);
73         mcmd->tx_rate         = wlan_cpu_to_le32(cfg->tx_rate);
74     }
75 
76     LEAVE();
77     return MLAN_STATUS_SUCCESS;
78 }
79 
80 /**
81  *  @brief This function prepares command of MFG Tx frame.
82  *
83  *  @param pmpriv       A pointer to mlan_private structure
84  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
85  *  @param action       The action: GET or SET
86  *  @param pdata_buf    A pointer to data buffer
87  *
88  *  @return             MLAN_STATUS_SUCCESS
89  */
wlan_cmd_mfg_tx_frame(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 action,t_void * pdata_buf)90 static mlan_status wlan_cmd_mfg_tx_frame(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, t_u16 action, t_void *pdata_buf)
91 {
92     HostCmd_DS_MFG_CMD_TX_FRAME2 *mcmd = (HostCmd_DS_MFG_CMD_TX_FRAME2 *)&cmd->params.mfg_tx_frame2;
93     mlan_ds_mfg_cmd_tx_frame2 *cfg     = (mlan_ds_mfg_cmd_tx_frame2 *)pdata_buf;
94 
95     ENTER();
96 
97     (void)__memset(pmpriv->adapter, mcmd, 0x00, sizeof(HostCmd_DS_MFG_CMD_TX_FRAME2));
98 
99     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MFG_COMMAND);
100     cmd->size    = wlan_cpu_to_le16(sizeof(HostCmd_DS_MFG_CMD_TX_FRAME2) + S_DS_GEN);
101 
102     mcmd->mfg_cmd = wlan_cpu_to_le32(cfg->mfg_cmd);
103     mcmd->action  = wlan_cpu_to_le16(action);
104     if (action == HostCmd_ACT_GEN_SET)
105     {
106         mcmd->enable            = wlan_cpu_to_le32(cfg->enable);
107         mcmd->data_rate         = wlan_cpu_to_le32(cfg->data_rate);
108         mcmd->frame_pattern     = wlan_cpu_to_le32(cfg->frame_pattern);
109         mcmd->frame_length      = wlan_cpu_to_le32(cfg->frame_length);
110         mcmd->adjust_burst_sifs = wlan_cpu_to_le16(cfg->adjust_burst_sifs);
111         mcmd->burst_sifs_in_us  = wlan_cpu_to_le32(cfg->burst_sifs_in_us);
112         mcmd->short_preamble    = wlan_cpu_to_le32(cfg->short_preamble);
113         mcmd->act_sub_ch        = wlan_cpu_to_le32(cfg->act_sub_ch);
114         mcmd->short_gi          = wlan_cpu_to_le32(cfg->short_gi);
115         mcmd->tx_bf             = wlan_cpu_to_le32(cfg->tx_bf);
116         mcmd->gf_mode           = wlan_cpu_to_le32(cfg->gf_mode);
117         mcmd->stbc              = wlan_cpu_to_le32(cfg->stbc);
118         (void)__memcpy(pmpriv->adapter, mcmd->bssid, cfg->bssid, MLAN_MAC_ADDR_LENGTH);
119     }
120 
121     LEAVE();
122     return MLAN_STATUS_SUCCESS;
123 }
124 
125 /**
126  *  @brief This function prepares command of MFG HE TB Tx.
127  *
128  *  @param pmpriv       A pointer to mlan_private structure
129  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
130  *  @param action       The action: GET or SET
131  *  @param pdata_buf    A pointer to data buffer
132  *
133  *  @return             MLAN_STATUS_SUCCESS
134  */
135 
wlan_cmd_mfg_he_tb_tx(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 action,t_void * pdata_buf)136 static mlan_status wlan_cmd_mfg_he_tb_tx(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, t_u16 action, t_void *pdata_buf)
137 {
138     HostCmd_DS_MFG_CMD_HE_TBTX_T *mcmd = (HostCmd_DS_MFG_CMD_HE_TBTX_T *)&cmd->params.mfg_he_power;
139     mlan_ds_mfg_Cmd_HE_TBTx_t *cfg     = (mlan_ds_mfg_Cmd_HE_TBTx_t *)pdata_buf;
140     ENTER();
141     (void)__memset(pmpriv->adapter, mcmd, 0x00, sizeof(HostCmd_DS_MFG_CMD_HE_TBTX_T));
142     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MFG_COMMAND);
143     cmd->size    = wlan_cpu_to_le16(sizeof(HostCmd_DS_MFG_CMD_HE_TBTX_T) + S_DS_GEN);
144 
145     mcmd->mfg_cmd = wlan_cpu_to_le32(cfg->mfg_cmd);
146     mcmd->action  = wlan_cpu_to_le16(action);
147     if (action == HostCmd_ACT_GEN_SET)
148     {
149         mcmd->enable       = wlan_cpu_to_le16(cfg->enable);
150         mcmd->qnum         = wlan_cpu_to_le16(cfg->qnum);
151         mcmd->aid          = wlan_cpu_to_le16(cfg->aid);
152         mcmd->axq_mu_timer = wlan_cpu_to_le16(cfg->axq_mu_timer);
153         mcmd->tx_power     = wlan_cpu_to_le16(cfg->tx_power);
154     }
155 
156     LEAVE();
157     return MLAN_STATUS_SUCCESS;
158 }
159 
160 /**
161  *  @brief This function prepares command of MFG OTP MAC add.
162  *
163  *  @param pmpriv       A pointer to mlan_private structure
164  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
165  *  @param action       The action: GET or SET
166  *  @param pdata_buf    A pointer to data buffer
167  *
168  *  @return             MLAN_STATUS_SUCCESS
169  */
170 
wlan_cmd_mfg_otp_mac_add(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 action,t_void * pdata_buf)171 static mlan_status wlan_cmd_mfg_otp_mac_add(pmlan_private pmpriv,
172                                             HostCmd_DS_COMMAND *cmd,
173                                             t_u16 action,
174                                             t_void *pdata_buf)
175 {
176     HostCmd_DS_MFG_CMD_OTP_MAC_ADD_T *mcmd    = (HostCmd_DS_MFG_CMD_OTP_MAC_ADD_T *)&cmd->params.mfg_otp_mac_addr_rd_wr;
177     mlan_ds_mfg_cmd_otp_mac_addr_rd_wr_t *cfg = (mlan_ds_mfg_cmd_otp_mac_addr_rd_wr_t *)pdata_buf;
178     ENTER();
179     (void)__memset(pmpriv->adapter, mcmd, 0x00, sizeof(HostCmd_DS_MFG_CMD_OTP_MAC_ADD_T));
180     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MFG_COMMAND);
181     cmd->size    = wlan_cpu_to_le16(sizeof(HostCmd_DS_MFG_CMD_OTP_MAC_ADD_T) + S_DS_GEN);
182 
183     mcmd->mfg_cmd = wlan_cpu_to_le32(cfg->mfg_cmd);
184     mcmd->action  = wlan_cpu_to_le16(action);
185     if (action == HostCmd_ACT_GEN_SET)
186     {
187         (void)__memcpy(pmpriv->adapter, mcmd->mac_addr, cfg->mac_addr, MLAN_MAC_ADDR_LENGTH);
188     }
189 
190     LEAVE();
191     return MLAN_STATUS_SUCCESS;
192 }
193 
194 /**
195  *  @brief This function prepares command of MFG OTP cal data.
196  *
197  *  @param pmpriv       A pointer to mlan_private structure
198  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
199  *  @param action       The action: GET or SET
200  *  @param pdata_buf    A pointer to data buffer
201  *
202  *  @return             MLAN_STATUS_SUCCESS
203  */
204 
wlan_cmd_mfg_otp_cal_data(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 action,t_void * pdata_buf)205 static mlan_status wlan_cmd_mfg_otp_cal_data(pmlan_private pmpriv,
206                                              HostCmd_DS_COMMAND *cmd,
207                                              t_u16 action,
208                                              t_void *pdata_buf)
209 {
210     HostCmd_DS_MFG_CMD_OTP_CAL_DATA_T *mcmd = (HostCmd_DS_MFG_CMD_OTP_CAL_DATA_T *)&cmd->params.mfg_otp_cal_data_rd_wr;
211     mlan_ds_mfg_cmd_otp_cal_data_rd_wr_t *cfg = (mlan_ds_mfg_cmd_otp_cal_data_rd_wr_t *)pdata_buf;
212     ENTER();
213     (void)__memset(pmpriv->adapter, mcmd, 0x00, sizeof(HostCmd_DS_MFG_CMD_OTP_CAL_DATA_T));
214     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MFG_COMMAND);
215     cmd->size    = wlan_cpu_to_le16(sizeof(HostCmd_DS_MFG_CMD_OTP_CAL_DATA_T) + S_DS_GEN);
216 
217     mcmd->mfg_cmd         = wlan_cpu_to_le32(cfg->mfg_cmd);
218     mcmd->action          = wlan_cpu_to_le16(action);
219     mcmd->cal_data_status = wlan_cpu_to_le16(cfg->cal_data_status);
220     mcmd->cal_data_len    = wlan_cpu_to_le16(cfg->cal_data_len);
221     if (action == HostCmd_ACT_GEN_SET)
222     {
223         (void)__memcpy(pmpriv->adapter, mcmd->cal_data, cfg->cal_data, cfg->cal_data_len);
224     }
225 
226     LEAVE();
227     return MLAN_STATUS_SUCCESS;
228 }
229 
230 /**
231  *  @brief This function prepares command of MFG config trigger frame.
232  *
233  *  @param pmpriv       A pointer to mlan_private structure
234  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
235  *  @param action       The action: GET or SET
236  *  @param pdata_buf    A pointer to data buffer
237  *
238  *  @return             MLAN_STATUS_SUCCESS
239  */
wlan_cmd_mfg_config_trigger_frame(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 action,t_void * pdata_buf)240 static mlan_status wlan_cmd_mfg_config_trigger_frame(pmlan_private pmpriv,
241                                                      HostCmd_DS_COMMAND *cmd,
242                                                      t_u16 action,
243                                                      t_void *pdata_buf)
244 {
245     HostCmd_MFG_CMD_IEEETYPES_CTLBASICTRIGHDR_T *mcmd =
246         (HostCmd_MFG_CMD_IEEETYPES_CTLBASICTRIGHDR_T *)&cmd->params.mfg_tx_trigger_config;
247     mfg_Cmd_IEEEtypes_CtlBasicTrigHdr_t *cfg = (mfg_Cmd_IEEEtypes_CtlBasicTrigHdr_t *)pdata_buf;
248 
249     ENTER();
250     (void)__memset(pmpriv->adapter, mcmd, 0x00, sizeof(HostCmd_MFG_CMD_IEEETYPES_CTLBASICTRIGHDR_T));
251     cmd->command  = wlan_cpu_to_le16(HostCmd_CMD_MFG_COMMAND);
252     cmd->size     = wlan_cpu_to_le16(sizeof(HostCmd_MFG_CMD_IEEETYPES_CTLBASICTRIGHDR_T) + S_DS_GEN);
253     mcmd->mfg_cmd = wlan_cpu_to_le32(cfg->mfg_cmd);
254     mcmd->action  = wlan_cpu_to_le16(action);
255     if (action == HostCmd_ACT_GEN_SET)
256     {
257         mcmd->enable_tx       = wlan_cpu_to_le32(cfg->enable_tx);
258         mcmd->standalone_hetb = wlan_cpu_to_le32(cfg->standalone_hetb);
259         mcmd->frmCtl.type     = wlan_cpu_to_le16(cfg->frmCtl.type);
260         mcmd->frmCtl.sub_type = wlan_cpu_to_le16(cfg->frmCtl.sub_type);
261         mcmd->duration        = wlan_cpu_to_le16(cfg->duration);
262 
263         mcmd->trig_common_field    = wlan_cpu_to_le64(cfg->trig_common_field);
264         mcmd->trig_user_info_field = wlan_cpu_to_le64(cfg->trig_user_info_field);
265         mcmd->basic_trig_user_info = wlan_cpu_to_le16(cfg->basic_trig_user_info);
266     }
267     LEAVE();
268     return MLAN_STATUS_SUCCESS;
269 }
270 
271 /**
272  *  @brief This function prepares command of MFG cmd.
273  *
274  *  @param pmpriv       A pointer to mlan_private structure
275  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
276  *  @param action       The action: GET or SET
277  *  @param pdata_buf    A pointer to data buffer
278  *
279  *  @return             MLAN_STATUS_SUCCESS
280  */
wlan_cmd_mfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 action,t_void * pdata_buf)281 static mlan_status wlan_cmd_mfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, t_u16 action, t_void *pdata_buf)
282 {
283     HostCmd_DS_MFG_CMD_GENERIC_CFG *mcmd = (HostCmd_DS_MFG_CMD_GENERIC_CFG *)&cmd->params.mfg_generic_cfg;
284     mlan_ds_mfg_cmd_generic_cfg *cfg     = (mlan_ds_mfg_cmd_generic_cfg *)pdata_buf;
285     mlan_status ret                      = MLAN_STATUS_SUCCESS;
286 
287     ENTER();
288 
289     if (!mcmd || !cfg)
290     {
291         ret = MLAN_STATUS_FAILURE;
292         goto cmd_mfg_done;
293     }
294 
295     (void)__memset(pmpriv->adapter, mcmd, 0x00, sizeof(HostCmd_DS_MFG_CMD_GENERIC_CFG));
296 
297     switch (cfg->mfg_cmd)
298     {
299         case MFG_CMD_TX_FRAME:
300             ret = wlan_cmd_mfg_tx_frame(pmpriv, cmd, action, pdata_buf);
301             goto cmd_mfg_done;
302         case MFG_CMD_TX_CONT:
303             ret = wlan_cmd_mfg_tx_cont(pmpriv, cmd, action, pdata_buf);
304             goto cmd_mfg_done;
305         case MFG_CMD_CONFIG_MAC_HE_TB_TX:
306             ret = wlan_cmd_mfg_he_tb_tx(pmpriv, cmd, action, pdata_buf);
307             goto cmd_mfg_done;
308         case MFG_CMD_CONFIG_TRIGGER_FRAME:
309             ret = wlan_cmd_mfg_config_trigger_frame(pmpriv, cmd, action, pdata_buf);
310             goto cmd_mfg_done;
311         case MFG_CMD_OTP_MAC_ADD:
312             ret = wlan_cmd_mfg_otp_mac_add(pmpriv, cmd, action, pdata_buf);
313             goto cmd_mfg_done;
314         case MFG_CMD_OTP_CAL_DATA:
315             ret = wlan_cmd_mfg_otp_cal_data(pmpriv, cmd, action, pdata_buf);
316             goto cmd_mfg_done;
317         case MFG_CMD_SET_TEST_MODE:
318         case MFG_CMD_UNSET_TEST_MODE:
319         case MFG_CMD_TX_ANT:
320         case MFG_CMD_RX_ANT:
321         case MFG_CMD_RF_CHAN:
322         case MFG_CMD_CLR_RX_ERR:
323         case MFG_CMD_RF_BAND_AG:
324         case MFG_CMD_RF_CHANNELBW:
325         case MFG_CMD_RFPWR:
326         case MFG_CMD_RADIO_MODE_CFG:
327             break;
328         default:
329             ret = MLAN_STATUS_FAILURE;
330             goto cmd_mfg_done;
331     }
332     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MFG_COMMAND);
333     cmd->size    = wlan_cpu_to_le16(sizeof(HostCmd_DS_MFG_CMD_GENERIC_CFG) + S_DS_GEN);
334 
335     mcmd->mfg_cmd = wlan_cpu_to_le32(cfg->mfg_cmd);
336     mcmd->action  = wlan_cpu_to_le16(action);
337     if (action == HostCmd_ACT_GEN_SET)
338     {
339         mcmd->data1 = wlan_cpu_to_le32(cfg->data1);
340         mcmd->data2 = wlan_cpu_to_le32(cfg->data2);
341         mcmd->data3 = wlan_cpu_to_le32(cfg->data3);
342     }
343 cmd_mfg_done:
344     LEAVE();
345     return ret;
346 }
347 #endif
348 
349 /**
350  *  @brief This function prepares command of RSSI info.
351  *
352  *  @param pmpriv       A pointer to mlan_private structure
353  *  @param pcmd         A pointer to HostCmd_DS_COMMAND structure
354  *  @param cmd_action   Command action
355  *
356  *  @return             MLAN_STATUS_SUCCESS
357  */
wlan_cmd_802_11_rssi_info(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * pcmd,IN t_u16 cmd_action)358 static mlan_status wlan_cmd_802_11_rssi_info(IN pmlan_private pmpriv, IN HostCmd_DS_COMMAND *pcmd, IN t_u16 cmd_action)
359 {
360     ENTER();
361 
362     pcmd->command                 = wlan_cpu_to_le16(HostCmd_CMD_RSSI_INFO);
363     pcmd->size                    = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_RSSI_INFO) + S_DS_GEN);
364     pcmd->params.rssi_info.action = wlan_cpu_to_le16(cmd_action);
365     pcmd->params.rssi_info.ndata  = wlan_cpu_to_le16(pmpriv->data_avg_factor);
366     pcmd->params.rssi_info.nbcn   = wlan_cpu_to_le16(pmpriv->bcn_avg_factor);
367 
368     /* Reset SNR/NF/RSSI values in private structure */
369     pmpriv->data_rssi_last = 0;
370     pmpriv->data_nf_last   = 0;
371     pmpriv->data_rssi_avg  = 0;
372     pmpriv->data_nf_avg    = 0;
373     pmpriv->bcn_rssi_last  = 0;
374     pmpriv->bcn_nf_last    = 0;
375     pmpriv->bcn_rssi_avg   = 0;
376     pmpriv->bcn_nf_avg     = 0;
377 
378     LEAVE();
379     return MLAN_STATUS_SUCCESS;
380 }
381 
382 /**
383  *  @brief This function prepares command of mac_control.
384  *
385  *  @param pmpriv       A pointer to mlan_private structure
386  *  @param pcmd         A pointer to HostCmd_DS_COMMAND structure
387  *  @param cmd_action   Command action
388  *  @param pdata_buf    A pointer to command information buffer
389  *
390  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
391  */
wlan_cmd_mac_control(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * pcmd,IN t_u16 cmd_action,IN t_void * pdata_buf)392 static mlan_status wlan_cmd_mac_control(IN pmlan_private pmpriv,
393                                         IN HostCmd_DS_COMMAND *pcmd,
394                                         IN t_u16 cmd_action,
395                                         IN t_void *pdata_buf)
396 {
397     HostCmd_DS_MAC_CONTROL *pmac = &pcmd->params.mac_ctrl;
398     t_u16 action                 = *((t_u16 *)pdata_buf);
399 
400     ENTER();
401 
402     if (cmd_action != HostCmd_ACT_GEN_SET)
403     {
404         PRINTM(MERROR, "wlan_cmd_mac_control(): support SET only.\n");
405         LEAVE();
406         return MLAN_STATUS_FAILURE;
407     }
408 
409     pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_MAC_CONTROL);
410     pcmd->size    = wlan_cpu_to_le16(sizeof(HostCmd_DS_MAC_CONTROL) + S_DS_GEN);
411     pmac->action  = wlan_cpu_to_le16(action);
412 
413     LEAVE();
414     return MLAN_STATUS_SUCCESS;
415 }
416 
417 /**
418  *  @brief This function prepares command of snmp_mib.
419  *
420  *  @param pmpriv       A pointer to mlan_private structure
421  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
422  *  @param cmd_action   The action: GET or SET
423  *  @param cmd_oid      OID: ENABLE or DISABLE
424  *  @param pdata_buf    A pointer to command information buffer
425  *
426  *  @return             MLAN_STATUS_SUCCESS
427  */
wlan_cmd_802_11_snmp_mib(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_u16 cmd_action,IN t_u32 cmd_oid,IN t_void * pdata_buf)428 static mlan_status wlan_cmd_802_11_snmp_mib(
429     IN pmlan_private pmpriv, IN HostCmd_DS_COMMAND *cmd, IN t_u16 cmd_action, IN t_u32 cmd_oid, IN t_void *pdata_buf)
430 {
431     HostCmd_DS_802_11_SNMP_MIB *psnmp_mib = &cmd->params.smib;
432     t_u32 ul_temp;
433 
434     ENTER();
435     PRINTM(MINFO, "SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
436     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
437     cmd->size    = sizeof(HostCmd_DS_802_11_SNMP_MIB) - 1U + S_DS_GEN;
438 
439     if (cmd_action == HostCmd_ACT_GEN_GET)
440     {
441         psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_GET);
442         psnmp_mib->buf_size   = wlan_cpu_to_le16(MAX_SNMP_BUF_SIZE);
443         cmd->size += MAX_SNMP_BUF_SIZE;
444     }
445 
446     switch (cmd_oid)
447     {
448 #if CONFIG_WIFI_FRAG_THRESHOLD
449         case FragThresh_i:
450             psnmp_mib->oid = wlan_cpu_to_le16((t_u16)FragThresh_i);
451             if (cmd_action == HostCmd_ACT_GEN_SET)
452             {
453                 psnmp_mib->query_type          = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
454                 psnmp_mib->buf_size            = wlan_cpu_to_le16(sizeof(t_u16));
455                 ul_temp                        = *((t_u32 *)pdata_buf);
456                 *((t_u16 *)(psnmp_mib->value)) = wlan_cpu_to_le16((t_u16)ul_temp);
457                 cmd->size += sizeof(t_u16);
458             }
459             break;
460 #endif
461 #if CONFIG_WIFI_RTS_THRESHOLD
462         case RtsThresh_i:
463             psnmp_mib->oid = wlan_cpu_to_le16((t_u16)RtsThresh_i);
464             if (cmd_action == HostCmd_ACT_GEN_SET)
465             {
466                 psnmp_mib->query_type        = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
467                 psnmp_mib->buf_size          = wlan_cpu_to_le16(sizeof(t_u16));
468                 ul_temp                      = *((t_u32 *)pdata_buf);
469                 *(t_u16 *)(psnmp_mib->value) = wlan_cpu_to_le16((t_u16)ul_temp);
470                 cmd->size += sizeof(t_u16);
471             }
472             break;
473 #endif
474         case Dot11D_i:
475             psnmp_mib->oid = wlan_cpu_to_le16((t_u16)Dot11D_i);
476             if (cmd_action == HostCmd_ACT_GEN_SET)
477             {
478                 psnmp_mib->query_type                  = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
479                 psnmp_mib->buf_size                    = wlan_cpu_to_le16(sizeof(t_u16));
480                 ul_temp                                = *(t_u32 *)pdata_buf;
481                 *((t_u16 *)(void *)(psnmp_mib->value)) = wlan_cpu_to_le16((t_u16)ul_temp);
482                 cmd->size += (t_u16)sizeof(t_u16);
483             }
484             break;
485         case Dot11H_i:
486             psnmp_mib->oid = wlan_cpu_to_le16((t_u16)Dot11H_i);
487             if (cmd_action == HostCmd_ACT_GEN_SET)
488             {
489                 psnmp_mib->query_type                  = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
490                 psnmp_mib->buf_size                    = wlan_cpu_to_le16(sizeof(t_u16));
491                 ul_temp                                = *(t_u32 *)pdata_buf;
492                 *((t_u16 *)(void *)(psnmp_mib->value)) = wlan_cpu_to_le16((t_u16)ul_temp);
493                 cmd->size += (t_u16)sizeof(t_u16);
494             }
495             break;
496         case ECSAEnable_i:
497             psnmp_mib->oid = wlan_cpu_to_le16((t_u16)ECSAEnable_i);
498             if (cmd_action == HostCmd_ACT_GEN_SET)
499             {
500                 psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
501                 psnmp_mib->buf_size   = wlan_cpu_to_le16(sizeof(t_u8));
502                 psnmp_mib->value[0]   = *((t_u8 *)pdata_buf);
503                 cmd->size += (t_u16)sizeof(t_u8);
504             }
505             break;
506         default:
507             PRINTM(MINFO, "Unexpected SNMP MIB INDEX \n");
508             break;
509     }
510     cmd->size = wlan_cpu_to_le16(cmd->size);
511     PRINTM(MINFO, "SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x, Value=0x%x\n", cmd_action, cmd_oid,
512            wlan_le16_to_cpu(psnmp_mib->buf_size), wlan_le16_to_cpu(*(t_u16 *)psnmp_mib->value));
513     LEAVE();
514     return MLAN_STATUS_SUCCESS;
515 }
516 
517 /**
518  *  @brief This function prepares command of get_log.
519  *
520  *  @param pmpriv       A pointer to mlan_private structure
521  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
522  *
523  *  @return             MLAN_STATUS_SUCCESS
524  */
wlan_cmd_802_11_get_log(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd)525 static mlan_status wlan_cmd_802_11_get_log(IN pmlan_private pmpriv, IN HostCmd_DS_COMMAND *cmd)
526 {
527     ENTER();
528     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_GET_LOG);
529     cmd->size    = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_GET_LOG) + S_DS_GEN);
530     LEAVE();
531     return MLAN_STATUS_SUCCESS;
532 }
533 
534 /**
535  *  @brief This function prepares command of tx_power_cfg.
536  *
537  *  @param pmpriv      A pointer to mlan_private structure
538  *  @param cmd         A pointer to HostCmd_DS_COMMAND structure
539  *  @param cmd_action  The action: GET or SET
540  *  @param pdata_buf   A pointer to data buffer
541  *
542  *  @return            MLAN_STATUS_SUCCESS
543  */
wlan_cmd_tx_power_cfg(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_u16 cmd_action,IN t_void * pdata_buf)544 static mlan_status wlan_cmd_tx_power_cfg(IN pmlan_private pmpriv,
545                                          IN HostCmd_DS_COMMAND *cmd,
546                                          IN t_u16 cmd_action,
547                                          IN t_void *pdata_buf)
548 {
549     MrvlTypes_Power_Group_t *ppg_tlv = MNULL;
550     HostCmd_DS_TXPWR_CFG *ptxp       = MNULL;
551     HostCmd_DS_TXPWR_CFG *ptxp_cfg   = &cmd->params.txp_cfg;
552 
553     ENTER();
554 
555     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_TXPWR_CFG);
556     cmd->size    = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_TXPWR_CFG));
557     switch (cmd_action)
558     {
559         case HostCmd_ACT_GEN_SET:
560             ptxp = (HostCmd_DS_TXPWR_CFG *)pdata_buf;
561             if (ptxp->mode != 0U)
562             {
563                 ppg_tlv = (MrvlTypes_Power_Group_t *)(void *)((t_u8 *)pdata_buf + sizeof(HostCmd_DS_TXPWR_CFG));
564                 (void)__memmove(
565                     pmpriv->adapter, ptxp_cfg, pdata_buf,
566                     sizeof(HostCmd_DS_TXPWR_CFG) + sizeof(MrvlTypes_Power_Group_t) + (t_u32)ppg_tlv->length);
567 
568                 ppg_tlv = (MrvlTypes_Power_Group_t *)(void *)((t_u8 *)&cmd->params + sizeof(HostCmd_DS_TXPWR_CFG));
569                 cmd->size += (t_u16)(wlan_cpu_to_le16(sizeof(MrvlTypes_Power_Group_t) + ppg_tlv->length));
570                 ppg_tlv->type   = wlan_cpu_to_le16(ppg_tlv->type);
571                 ppg_tlv->length = wlan_cpu_to_le16(ppg_tlv->length);
572             }
573             else
574             {
575                 (void)__memmove(pmpriv->adapter, ptxp_cfg, pdata_buf, sizeof(HostCmd_DS_TXPWR_CFG));
576             }
577             ptxp_cfg->action    = wlan_cpu_to_le16(cmd_action);
578             ptxp_cfg->cfg_index = wlan_cpu_to_le16(ptxp_cfg->cfg_index);
579             ptxp_cfg->mode      = wlan_cpu_to_le32(ptxp_cfg->mode);
580             break;
581         case HostCmd_ACT_GEN_GET:
582             ptxp_cfg->action = wlan_cpu_to_le16(cmd_action);
583             break;
584         default:
585             PRINTM(MINFO, "Unexpected Host Cmd tx_power_cfg\n");
586             break;
587     }
588 
589     LEAVE();
590     return MLAN_STATUS_SUCCESS;
591 }
592 
593 /**
594  *  @brief This function prepares command of rf_tx_power.
595  *
596  *  @param pmpriv     A pointer to wlan_private structure
597  *  @param cmd        A pointer to HostCmd_DS_COMMAND structure
598  *  @param cmd_action the action: GET or SET
599  *  @param pdata_buf  A pointer to data buffer
600  *  @return           MLAN_STATUS_SUCCESS
601  */
wlan_cmd_802_11_rf_tx_power(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_u16 cmd_action,IN t_void * pdata_buf)602 static mlan_status wlan_cmd_802_11_rf_tx_power(IN pmlan_private pmpriv,
603                                                IN HostCmd_DS_COMMAND *cmd,
604                                                IN t_u16 cmd_action,
605                                                IN t_void *pdata_buf)
606 {
607     HostCmd_DS_802_11_RF_TX_POWER *prtp = &cmd->params.txp;
608 
609     ENTER();
610 
611     cmd->size    = wlan_cpu_to_le16((sizeof(HostCmd_DS_802_11_RF_TX_POWER)) + S_DS_GEN);
612     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_RF_TX_POWER);
613     prtp->action = cmd_action;
614 
615     PRINTM(MINFO, "RF_TX_POWER_CMD: Size:%d Cmd:0x%x Act:%d\n", cmd->size, cmd->command, prtp->action);
616 
617     switch (cmd_action)
618     {
619         case HostCmd_ACT_GEN_GET:
620             prtp->action        = wlan_cpu_to_le16(HostCmd_ACT_GEN_GET);
621             prtp->current_level = 0;
622             break;
623 
624         case HostCmd_ACT_GEN_SET:
625             prtp->action        = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
626             prtp->current_level = wlan_cpu_to_le16(*((t_u16 *)pdata_buf));
627             break;
628         default:
629             PRINTM(MINFO, "Unexpected Host Cmd rf_tx_power \n");
630             break;
631     }
632     LEAVE();
633     return MLAN_STATUS_SUCCESS;
634 }
635 
636 /**
637  * @brief This function prepares command of hs_cfg.
638  *
639  * @param pmpriv       A pointer to mlan_private structure
640  * @param cmd          A pointer to HostCmd_DS_COMMAND structure
641  * @param cmd_action   The action: GET or SET
642  * @param pdata_buf    A pointer to data buffer
643  *
644  * @return             MLAN_STATUS_SUCCESS
645  */
wlan_cmd_802_11_hs_cfg(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_u16 cmd_action,IN hs_config_param * pdata_buf)646 static mlan_status wlan_cmd_802_11_hs_cfg(IN pmlan_private pmpriv,
647                                           IN HostCmd_DS_COMMAND *cmd,
648                                           IN t_u16 cmd_action,
649                                           IN hs_config_param *pdata_buf)
650 {
651     HostCmd_DS_802_11_HS_CFG_ENH *phs_cfg = &cmd->params.opt_hs_cfg;
652     t_u16 hs_activate                     = MFALSE;
653 
654     ENTER();
655     if (pdata_buf == MNULL)
656     {
657         /* New Activate command */
658         hs_activate = MTRUE;
659     }
660     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH);
661     cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_802_11_HS_CFG_ENH));
662 
663     if (hs_activate != 0U)
664     {
665         phs_cfg->action                       = wlan_cpu_to_le16(HS_ACTIVATE);
666         phs_cfg->params.hs_activate.resp_ctrl = wlan_cpu_to_le16(RESP_NEEDED);
667     }
668     else
669     {
670         phs_cfg->action                      = wlan_cpu_to_le16(HS_CONFIGURE);
671         phs_cfg->params.hs_config.conditions = wlan_cpu_to_le32(pdata_buf->conditions);
672         phs_cfg->params.hs_config.gpio       = pdata_buf->gpio;
673         phs_cfg->params.hs_config.gap        = pdata_buf->gap;
674         PRINTM(MCMND, "HS_CFG_CMD: condition:0x%x gpio:0x%x gap:0x%x\n", phs_cfg->params.hs_config.conditions,
675                phs_cfg->params.hs_config.gpio, phs_cfg->params.hs_config.gap);
676     }
677 
678     LEAVE();
679     return MLAN_STATUS_SUCCESS;
680 }
681 
682 /**
683  *  @brief This function prepares command of mac_address.
684  *
685  *  @param pmpriv       A pointer to mlan_private structure
686  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
687  *  @param cmd_action   The action: GET or SET
688  *
689  *  @return             MLAN_STATUS_SUCCESS
690  */
wlan_cmd_802_11_mac_address(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_u16 cmd_action,t_void * pdata_buf)691 static mlan_status wlan_cmd_802_11_mac_address(IN pmlan_private pmpriv,
692                                                IN HostCmd_DS_COMMAND *cmd,
693                                                IN t_u16 cmd_action,
694                                                t_void *pdata_buf)
695 {
696     ENTER();
697     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_MAC_ADDRESS);
698     cmd->size    = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_MAC_ADDRESS) + S_DS_GEN);
699     cmd->result  = 0;
700 
701     cmd->params.mac_addr.action = wlan_cpu_to_le16(cmd_action);
702 
703     if (cmd_action == HostCmd_ACT_GEN_SET)
704     {
705         (void)__memcpy(pmpriv->adapter, cmd->params.mac_addr.mac_addr, pdata_buf, MLAN_MAC_ADDR_LENGTH);
706         // HEXDUMP("SET_CMD: MAC ADDRESS-", priv->CurrentAddr, 6);
707     }
708     LEAVE();
709     return MLAN_STATUS_SUCCESS;
710 }
711 
712 #if CONFIG_WMM_UAPSD
713 /**
714  * @brief This function prepares command of sleep_period.
715  *
716  * @param pmpriv       A pointer to mlan_private structure
717  * @param cmd          A pointer to HostCmd_DS_COMMAND structure
718  * @param cmd_action   The action: GET or SET
719  * @param pdata_buf    A pointer to data buffer
720  *
721  * @return             MLAN_STATUS_SUCCESS
722  */
wlan_cmd_802_11_sleep_period(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_u16 cmd_action,IN t_u16 * pdata_buf)723 static mlan_status wlan_cmd_802_11_sleep_period(IN pmlan_private pmpriv,
724                                                 IN HostCmd_DS_COMMAND *cmd,
725                                                 IN t_u16 cmd_action,
726                                                 IN t_u16 *pdata_buf)
727 {
728     HostCmd_DS_802_11_SLEEP_PERIOD *pcmd_sleep_pd = &cmd->params.sleep_pd;
729 
730     ENTER();
731 
732     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_SLEEP_PERIOD);
733     cmd->size    = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_SLEEP_PERIOD) + S_DS_GEN);
734     if (cmd_action == HostCmd_ACT_GEN_SET)
735     {
736         pcmd_sleep_pd->sleep_pd = wlan_cpu_to_le16(*(t_u16 *)pdata_buf);
737     }
738     pcmd_sleep_pd->action = wlan_cpu_to_le16(cmd_action);
739 
740     LEAVE();
741     return MLAN_STATUS_SUCCESS;
742 }
743 #endif
744 
745 /**
746  *  @brief This function prepares command of mac_multicast_adr.
747  *
748  *  @param pmpriv       A pointer to mlan_private structure
749  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
750  *  @param cmd_action   The action: GET or SET
751  *  @param pdata_buf    A pointer to data buffer
752  *
753  *  @return             MLAN_STATUS_SUCCESS
754  */
wlan_cmd_mac_multicast_adr(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_u16 cmd_action,IN t_void * pdata_buf)755 static mlan_status wlan_cmd_mac_multicast_adr(IN pmlan_private pmpriv,
756                                               IN HostCmd_DS_COMMAND *cmd,
757                                               IN t_u16 cmd_action,
758                                               IN t_void *pdata_buf)
759 {
760     mlan_multicast_list *pmcast_list       = (mlan_multicast_list *)pdata_buf;
761     HostCmd_DS_MAC_MULTICAST_ADR *pmc_addr = &cmd->params.mc_addr;
762 
763     ENTER();
764     cmd->size    = wlan_cpu_to_le16(sizeof(HostCmd_DS_MAC_MULTICAST_ADR) + S_DS_GEN);
765     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MAC_MULTICAST_ADR);
766 
767     pmc_addr->action      = wlan_cpu_to_le16(cmd_action);
768     pmc_addr->num_of_adrs = wlan_cpu_to_le16((t_u16)pmcast_list->num_multicast_addr);
769     (void)__memcpy(pmpriv->adapter, pmc_addr->mac_list, pmcast_list->mac_list,
770                    pmcast_list->num_multicast_addr * MLAN_MAC_ADDR_LENGTH);
771 
772     LEAVE();
773     return MLAN_STATUS_SUCCESS;
774 }
775 
776 /**
777  *  @brief This function prepares command of deauthenticate.
778  *
779  * @param pmpriv       A pointer to mlan_private structure
780  * @param cmd          A pointer to HostCmd_DS_COMMAND structure
781  * @param pdata_buf    A pointer to data buffer
782  *
783  * @return             MLAN_STATUS_SUCCESS
784  */
wlan_cmd_802_11_deauthenticate(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_void * pdata_buf)785 /* static */ mlan_status wlan_cmd_802_11_deauthenticate(IN pmlan_private pmpriv,
786                                                         IN HostCmd_DS_COMMAND *cmd,
787                                                         IN t_void *pdata_buf)
788 {
789     HostCmd_DS_802_11_DEAUTHENTICATE *pdeauth = &cmd->params.deauth;
790 
791     ENTER();
792 
793     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_DEAUTHENTICATE);
794     cmd->size    = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_DEAUTHENTICATE) + S_DS_GEN);
795 
796     /* Set AP MAC address */
797     (void)__memcpy(pmpriv->adapter, pdeauth->mac_addr, (t_u8 *)pdata_buf, MLAN_MAC_ADDR_LENGTH);
798 
799     PRINTM(MCMND, "Deauth: %02x:%02x:%02x:%02x:%02x:%02x\n", pdeauth->mac_addr[0], pdeauth->mac_addr[1],
800            pdeauth->mac_addr[2], pdeauth->mac_addr[3], pdeauth->mac_addr[4], pdeauth->mac_addr[5]);
801 
802     if (pmpriv->adapter->state_11h.recvd_chanswann_event)
803     {
804 /** Reason code 36 = Requested from peer station as it is leaving the BSS */
805 #define REASON_CODE_PEER_STA_LEAVING 36
806         pdeauth->reason_code = wlan_cpu_to_le16(REASON_CODE_PEER_STA_LEAVING);
807     }
808     else
809     {
810 /** Reason code 3 = Station is leaving */
811 #define REASON_CODE_STA_LEAVING 3
812         pdeauth->reason_code = wlan_cpu_to_le16(REASON_CODE_STA_LEAVING);
813     }
814 
815     LEAVE();
816     return MLAN_STATUS_SUCCESS;
817 }
818 
819 /**
820  *  @brief This function prepares command of key_material.
821  *
822  *  @param pmpriv       A pointer to mlan_private structure
823  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
824  *  @param cmd_action   The action: GET or SET
825  *  @param cmd_oid      OID: ENABLE or DISABLE
826  *  @param pdata_buf    A pointer to data buffer
827  *
828  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
829  */
wlan_cmd_802_11_key_material(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_u32 cmd_oid,t_void * pdata_buf)830 static mlan_status wlan_cmd_802_11_key_material(
831     pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, t_u16 cmd_action, t_u32 cmd_oid, t_void *pdata_buf)
832 {
833     HostCmd_DS_802_11_KEY_MATERIAL *pkey_material = &cmd->params.key_material;
834     mlan_ds_encrypt_key *pkey                     = (mlan_ds_encrypt_key *)pdata_buf;
835     mlan_status ret                               = MLAN_STATUS_SUCCESS;
836 
837     ENTER();
838     if (!pkey)
839     {
840         ret = MLAN_STATUS_FAILURE;
841         goto done;
842     }
843     cmd->command          = wlan_cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL);
844     pkey_material->action = wlan_cpu_to_le16(cmd_action);
845     if (cmd_action == HostCmd_ACT_GEN_GET)
846     {
847         wifi_d("GET Key");
848         pkey_material->key_param_set.key_idx = pkey->key_index & KEY_INDEX_MASK;
849         pkey_material->key_param_set.type    = wlan_cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
850         pkey_material->key_param_set.length  = wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN);
851         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.mac_addr, pkey->mac_addr, MLAN_MAC_ADDR_LENGTH,
852                    MLAN_MAC_ADDR_LENGTH);
853         if (pkey->key_flags & KEY_FLAG_GROUP_KEY)
854             pkey_material->key_param_set.key_info |= KEY_INFO_MCAST_KEY;
855         else
856             pkey_material->key_param_set.key_info |= KEY_INFO_UCAST_KEY;
857 #ifdef ENABLE_802_11W
858         if (pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK)
859             pkey_material->key_param_set.key_info = KEY_INFO_CMAC_AES_KEY;
860 #endif
861         pkey_material->key_param_set.key_info = wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
862         cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN + KEY_PARAMS_FIXED_LEN +
863                                      sizeof(pkey_material->action));
864         goto done;
865     }
866     (void)__memset(pmpriv->adapter, &pkey_material->key_param_set, 0, sizeof(MrvlIEtype_KeyParamSetV2_t));
867     if (pkey->key_flags & KEY_FLAG_REMOVE_KEY)
868     {
869         pkey_material->action                = wlan_cpu_to_le16(HostCmd_ACT_GEN_REMOVE);
870         pkey_material->key_param_set.type    = wlan_cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
871         pkey_material->key_param_set.length  = wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN);
872         pkey_material->key_param_set.key_idx = pkey->key_index & KEY_INDEX_MASK;
873         pkey_material->key_param_set.key_info =
874             wlan_cpu_to_le16(KEY_INFO_MCAST_KEY | KEY_INFO_UCAST_KEY | KEY_INFO_CMAC_AES_KEY);
875         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.mac_addr, pkey->mac_addr, MLAN_MAC_ADDR_LENGTH,
876                    MLAN_MAC_ADDR_LENGTH);
877         cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN + KEY_PARAMS_FIXED_LEN +
878                                      sizeof(pkey_material->action));
879         wifi_d("Remove Key");
880         goto done;
881     }
882     pkey_material->action                 = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
883     pkey_material->key_param_set.key_idx  = pkey->key_index & KEY_INDEX_MASK;
884     pkey_material->key_param_set.type     = wlan_cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
885     pkey_material->key_param_set.key_info = KEY_INFO_ENABLE_KEY;
886     memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.mac_addr, pkey->mac_addr, MLAN_MAC_ADDR_LENGTH,
887                MLAN_MAC_ADDR_LENGTH);
888     if (pkey->key_len <= MAX_WEP_KEY_SIZE)
889     {
890         pkey_material->key_param_set.length   = wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(wep_param_t));
891         pkey_material->key_param_set.key_type = KEY_TYPE_ID_WEP;
892         if (pkey->is_current_wep_key)
893         {
894             pkey_material->key_param_set.key_info |= KEY_INFO_MCAST_KEY | KEY_INFO_UCAST_KEY;
895             if (pkey_material->key_param_set.key_idx == (pmpriv->wep_key_curr_index & KEY_INDEX_MASK))
896                 pkey_material->key_param_set.key_info |= KEY_INFO_DEFAULT_KEY;
897         }
898         else
899         {
900             if (pkey->key_flags & KEY_FLAG_GROUP_KEY)
901                 pkey_material->key_param_set.key_info |= KEY_INFO_MCAST_KEY;
902             else
903                 pkey_material->key_param_set.key_info |= KEY_INFO_UCAST_KEY;
904         }
905         pkey_material->key_param_set.key_info               = wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
906         pkey_material->key_param_set.key_params.wep.key_len = wlan_cpu_to_le16(pkey->key_len);
907         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.wep.key, pkey->key_material, pkey->key_len,
908                    MAX_WEP_KEY_SIZE);
909         cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN + KEY_PARAMS_FIXED_LEN +
910                                      sizeof(wep_param_t) + sizeof(pkey_material->action));
911         wifi_d("Set WEP Key");
912         goto done;
913     }
914     if (pkey->key_flags & KEY_FLAG_GROUP_KEY)
915         pkey_material->key_param_set.key_info |= KEY_INFO_MCAST_KEY;
916     else
917         pkey_material->key_param_set.key_info |= KEY_INFO_UCAST_KEY;
918     if (pkey->key_flags & KEY_FLAG_SET_TX_KEY)
919         pkey_material->key_param_set.key_info |= KEY_INFO_TX_KEY | KEY_INFO_RX_KEY;
920     else
921         pkey_material->key_param_set.key_info |= KEY_INFO_RX_KEY;
922 #if defined(WAPI)
923     if (pkey->is_wapi_key)
924     {
925         pkey_material->key_param_set.key_type = KEY_TYPE_ID_WAPI;
926         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.wapi.pn, pkey->pn, PN_SIZE, PN_SIZE);
927         pkey_material->key_param_set.key_params.wapi.key_len = wlan_cpu_to_le16(pkey->key_len);
928         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.wapi.key, pkey->key_material, pkey->key_len,
929                    WAPI_KEY_SIZE);
930         if (!pmpriv->sec_info.wapi_key_on)
931             pkey_material->key_param_set.key_info |= KEY_INFO_DEFAULT_KEY;
932         if (pkey->key_flags & KEY_FLAG_GROUP_KEY)
933             pmpriv->sec_info.wapi_key_on = MTRUE;
934         pkey_material->key_param_set.key_info = wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
935         pkey_material->key_param_set.length   = wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(wapi_param));
936         cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN + KEY_PARAMS_FIXED_LEN +
937                                      sizeof(wapi_param) + sizeof(pkey_material->action));
938         wifi_d("Set WAPI Key");
939         goto done;
940     }
941 #endif
942     if (pmpriv->bss_mode == MLAN_BSS_MODE_INFRA)
943     {
944         /* Enable default key for WPA/WPA2 */
945         if (!pmpriv->wpa_is_gtk_set)
946             pkey_material->key_param_set.key_info |= KEY_INFO_DEFAULT_KEY;
947     }
948     else
949     {
950         pkey_material->key_param_set.key_info |= KEY_INFO_DEFAULT_KEY;
951         /* Enable unicast bit for WPA-NONE/ADHOC_AES */
952         if ((!pmpriv->sec_info.wpa2_enabled) && (pkey->key_flags & KEY_FLAG_SET_TX_KEY))
953             pkey_material->key_param_set.key_info |= KEY_INFO_UCAST_KEY;
954     }
955     pkey_material->key_param_set.key_info = wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
956 #ifdef ENABLE_GCMP_SUPPORT
957     if (pkey->key_flags & KEY_FLAG_GCMP || pkey->key_flags & KEY_FLAG_GCMP_256)
958     {
959         if (pkey->key_flags & (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
960         {
961             memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.gcmp.pn, pkey->pn, SEQ_MAX_SIZE,
962                        WPA_PN_SIZE);
963         }
964         if (pkey->key_flags & KEY_FLAG_GCMP)
965             pkey_material->key_param_set.key_type = KEY_TYPE_ID_GCMP;
966         else
967             pkey_material->key_param_set.key_type = KEY_TYPE_ID_GCMP_256;
968         pkey_material->key_param_set.key_params.gcmp.key_len = wlan_cpu_to_le16(pkey->key_len);
969         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.gcmp.key, pkey->key_material, pkey->key_len,
970                    WPA_GCMP_KEY_LEN);
971         pkey_material->key_param_set.length = wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(gcmp_param));
972         cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN + KEY_PARAMS_FIXED_LEN +
973                                      sizeof(gcmp_param) + sizeof(pkey_material->action));
974         wifi_d("Set GCMP Key");
975         goto done;
976     }
977 #endif
978     if (pkey->key_flags & KEY_FLAG_CCMP_256)
979     {
980         if (pkey->key_flags & (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
981         {
982             memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.ccmp256.pn, pkey->pn, SEQ_MAX_SIZE,
983                        WPA_PN_SIZE);
984         }
985         pkey_material->key_param_set.key_type                   = KEY_TYPE_ID_CCMP_256;
986         pkey_material->key_param_set.key_params.ccmp256.key_len = wlan_cpu_to_le16(pkey->key_len);
987         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.ccmp256.key, pkey->key_material,
988                    pkey->key_len, WPA_CCMP_256_KEY_LEN);
989         pkey_material->key_param_set.length = wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(ccmp_256_param));
990         cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN + KEY_PARAMS_FIXED_LEN +
991                                      sizeof(ccmp_256_param) + sizeof(pkey_material->action));
992         wifi_d("Set CCMP256 Key");
993         goto done;
994     }
995 #ifdef ENABLE_802_11W
996     if (pkey->key_len == WPA_AES_KEY_LEN && !(pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK))
997     {
998 #else
999     if (pkey->key_len == WPA_AES_KEY_LEN)
1000     {
1001 #endif
1002         if (pkey->key_flags & (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
1003             memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.aes.pn, pkey->pn, SEQ_MAX_SIZE,
1004                        WPA_PN_SIZE);
1005         pkey_material->key_param_set.key_type               = KEY_TYPE_ID_AES;
1006         pkey_material->key_param_set.key_params.aes.key_len = wlan_cpu_to_le16(pkey->key_len);
1007         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.aes.key, pkey->key_material, pkey->key_len,
1008                    WPA_AES_KEY_LEN);
1009         pkey_material->key_param_set.length = wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(aes_param));
1010         cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN + KEY_PARAMS_FIXED_LEN + sizeof(aes_param) +
1011                                      sizeof(pkey_material->action));
1012         wifi_d("Set AES Key");
1013         goto done;
1014     }
1015 #ifdef ENABLE_802_11W
1016     if (pkey->key_len == WPA_IGTK_KEY_LEN && (pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK))
1017     {
1018         if (pkey->key_flags & (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
1019             memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.cmac_aes.ipn, pkey->pn, SEQ_MAX_SIZE,
1020                        IGTK_PN_SIZE);
1021         pkey_material->key_param_set.key_info &= ~(wlan_cpu_to_le16(KEY_INFO_MCAST_KEY));
1022         pkey_material->key_param_set.key_info |= wlan_cpu_to_le16(KEY_INFO_AES_MCAST_IGTK);
1023         if (pkey->key_flags & KEY_FLAG_GMAC_128)
1024             pkey_material->key_param_set.key_type = KEY_TYPE_ID_BIP_GMAC_128;
1025         else
1026             pkey_material->key_param_set.key_type = KEY_TYPE_ID_AES_CMAC;
1027         pkey_material->key_param_set.key_params.cmac_aes.key_len = wlan_cpu_to_le16(pkey->key_len);
1028         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.cmac_aes.key, pkey->key_material,
1029                    pkey->key_len, CMAC_AES_KEY_LEN);
1030         pkey_material->key_param_set.length = wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(cmac_aes_param));
1031         cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN + KEY_PARAMS_FIXED_LEN +
1032                                      sizeof(cmac_aes_param) + sizeof(pkey_material->action));
1033         if (pkey->key_flags & KEY_FLAG_GMAC_128)
1034             wifi_d("Set AES 128 GMAC Key");
1035         else
1036             wifi_d("Set CMAC AES Key");
1037         goto done;
1038     }
1039     if (pkey->key_len == WPA_IGTK_256_KEY_LEN && (pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK))
1040     {
1041         if (pkey->key_flags & (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
1042             (void)__memcpy(pmpriv->adapter, pkey_material->key_param_set.key_params.gmac_aes.ipn, pkey->pn,
1043                            SEQ_MAX_SIZE);
1044         pkey_material->key_param_set.key_info &= ~(wlan_cpu_to_le16(KEY_INFO_MCAST_KEY));
1045         pkey_material->key_param_set.key_info |= wlan_cpu_to_le16(KEY_INFO_AES_MCAST_IGTK);
1046         pkey_material->key_param_set.key_type                    = KEY_TYPE_ID_BIP_GMAC_256;
1047         pkey_material->key_param_set.key_params.gmac_aes.key_len = wlan_cpu_to_le16(pkey->key_len);
1048         (void)__memcpy(pmpriv->adapter, pkey_material->key_param_set.key_params.gmac_aes.key, pkey->key_material,
1049                        pkey->key_len);
1050         pkey_material->key_param_set.length = wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(gmac_aes_256_param));
1051         cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN + KEY_PARAMS_FIXED_LEN +
1052                                      sizeof(gmac_aes_256_param) + sizeof(pkey_material->action));
1053         wifi_d("Set AES 256 GMAC Key");
1054         goto done;
1055     }
1056 #endif
1057     if (pkey->key_len == WPA_TKIP_KEY_LEN)
1058     {
1059         if (pkey->key_flags & (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
1060             memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.tkip.pn, pkey->pn, SEQ_MAX_SIZE,
1061                        WPA_PN_SIZE);
1062         pkey_material->key_param_set.key_type                = KEY_TYPE_ID_TKIP;
1063         pkey_material->key_param_set.key_params.tkip.key_len = wlan_cpu_to_le16(pkey->key_len);
1064         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.tkip.key, pkey->key_material, pkey->key_len,
1065                    WPA_TKIP_KEY_LEN);
1066         pkey_material->key_param_set.length = wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(tkip_param));
1067         cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN + KEY_PARAMS_FIXED_LEN +
1068                                      sizeof(tkip_param) + sizeof(pkey_material->action));
1069         wifi_d("Set TKIP Key");
1070     }
1071 done:
1072     LEAVE();
1073     return ret;
1074 }
1075 
1076 #if CONFIG_GTK_REKEY_OFFLOAD
1077 /**
1078  *  @brief This function prepares command of gtk rekey offload
1079  *
1080  *  @param pmpriv       A pointer to mlan_private structure
1081  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
1082  *  @param cmd_action   The action: GET or SET
1083  *  @param cmd_oid      OID: ENABLE or DISABLE
1084  *  @param pdata_buf    A pointer to data buffer
1085  *
1086  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1087  */
1088 static mlan_status wlan_cmd_gtk_rekey_offload(
1089     pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, t_u16 cmd_action, t_u32 cmd_oid, t_void *pdata_buf)
1090 {
1091     HostCmd_DS_GTK_REKEY_PARAMS *rekey = &cmd->params.gtk_rekey;
1092     mlan_ds_misc_gtk_rekey_data *data  = (mlan_ds_misc_gtk_rekey_data *)pdata_buf;
1093     t_u64 rekey_ctr;
1094 
1095     ENTER();
1096     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_CONFIG_GTK_REKEY_OFFLOAD_CFG);
1097     cmd->size    = wlan_cpu_to_le16(sizeof(*rekey) + S_DS_GEN);
1098 
1099     rekey->action = wlan_cpu_to_le16(cmd_action);
1100     if (cmd_action == HostCmd_ACT_GEN_SET)
1101     {
1102         memcpy_ext(pmpriv->adapter, rekey->kek, data->kek, MLAN_KEK_LEN, MLAN_KEK_LEN);
1103         memcpy_ext(pmpriv->adapter, rekey->kck, data->kck, MLAN_KCK_LEN, MLAN_KCK_LEN);
1104         rekey_ctr              = wlan_le64_to_cpu(swap_byte_64(*(t_u64 *)data->replay_ctr));
1105         rekey->replay_ctr_low  = wlan_cpu_to_le32((t_u32)rekey_ctr);
1106         rekey->replay_ctr_high = wlan_cpu_to_le32((t_u64)rekey_ctr >> 32);
1107     }
1108 
1109     LEAVE();
1110     return MLAN_STATUS_SUCCESS;
1111 }
1112 #endif
1113 
1114 /**
1115  *  @brief This function prepares command of supplicant pmk
1116  *
1117  *  @param pmpriv       A pointer to mlan_private structure
1118  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
1119  *  @param cmd_action   The action: GET or SET
1120  *  @param pdata_buf    A pointer to data buffer
1121  *
1122  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1123  */
1124 static mlan_status wlan_cmd_802_11_supplicant_pmk(IN pmlan_private pmpriv,
1125                                                   IN HostCmd_DS_COMMAND *cmd,
1126                                                   IN t_u16 cmd_action,
1127                                                   IN t_void *pdata_buf)
1128 {
1129     MrvlIEtypes_PMK_t *ppmk_tlv                        = MNULL;
1130     MrvlIEtypes_Passphrase_t *ppassphrase_tlv          = MNULL;
1131     MrvlIEtypes_Password_t *ppassword_tlv              = MNULL;
1132     MrvlIEtypes_SsIdParamSet_t *pssid_tlv              = MNULL;
1133     MrvlIEtypes_Bssid_t *pbssid_tlv                    = MNULL;
1134     HostCmd_DS_802_11_SUPPLICANT_PMK *pesupplicant_psk = &cmd->params.esupplicant_psk;
1135     t_u8 *ptlv_buffer                                  = (t_u8 *)pesupplicant_psk->tlv_buffer;
1136     mlan_ds_passphrase *psk                            = (mlan_ds_passphrase *)pdata_buf;
1137     t_u8 zero_mac[]                                    = {0, 0, 0, 0, 0, 0};
1138 
1139     ENTER();
1140     /*
1141      * Parse the rest of the buf here
1142      *      1)  <ssid="valid ssid"> - This will get the passphrase, AKMP
1143      *          for specified ssid, if none specified then it will get all.
1144      *          Eg: iwpriv <mlanX> passphrase 0:ssid=nxp
1145      *      2)  <psk="psk">:<passphrase="passphare">:<bssid="00:50:43:ef:23:f3">
1146      *          <ssid="valid ssid"> - passphrase and psk cannot be provided to
1147      *          the same SSID, Takes one SSID at a time, If ssid= is present
1148      *          the it should contain a passphrase or psk. If no arguments are
1149      *          provided then AKMP=802.1x, and passphrase should be provided
1150      *          after association.
1151      *          End of each parameter should be followed by a ':'(except for the
1152      *          last parameter) as the delimiter. If ':' has to be used in
1153      *          an SSID then a '/' should be preceded to ':' as a escape.
1154      *          Eg:iwpriv <mlanX> passphrase
1155      *                    "1:ssid=mrvl AP:psk=abcdefgh:bssid=00:50:43:ef:23:f3"
1156      *          iwpriv <mlanX> passphrase
1157      *                 "1:ssid=mrvl/: AP:psk=abcdefgd:bssid=00:50:43:ef:23:f3"
1158      *          iwpriv <mlanX> passphrase "1:ssid=mrvlAP:psk=abcdefgd"
1159      *      3)  <ssid="valid ssid"> - This will clear the passphrase
1160      *          for specified ssid, if none specified then it will clear all.
1161      *          Eg: iwpriv <mlanX> passphrase 2:ssid=nxp
1162      */
1163 
1164     /* -1 is for t_u8 TlvBuffer[1] as this should not be included */
1165     cmd->size = sizeof(HostCmd_DS_802_11_SUPPLICANT_PMK) + S_DS_GEN - 1U;
1166     if (psk->ssid.ssid_len != 0U)
1167     {
1168         pssid_tlv              = (MrvlIEtypes_SsIdParamSet_t *)(void *)ptlv_buffer;
1169         pssid_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_SSID);
1170         pssid_tlv->header.len  = (t_u16)MIN(MLAN_MAX_SSID_LENGTH, psk->ssid.ssid_len);
1171         (void)__memcpy(pmpriv->adapter, (char *)pssid_tlv->ssid, psk->ssid.ssid,
1172                        MIN(MLAN_MAX_SSID_LENGTH, psk->ssid.ssid_len));
1173         ptlv_buffer += (pssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
1174         cmd->size += (t_u16)(pssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
1175         pssid_tlv->header.len = wlan_cpu_to_le16(pssid_tlv->header.len);
1176     }
1177     if (__memcmp(pmpriv->adapter, (t_u8 *)&psk->bssid, zero_mac, sizeof(zero_mac)) != 0)
1178     {
1179         pbssid_tlv              = (MrvlIEtypes_Bssid_t *)(void *)ptlv_buffer;
1180         pbssid_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_BSSID);
1181         pbssid_tlv->header.len  = MLAN_MAC_ADDR_LENGTH;
1182         (void)__memcpy(pmpriv->adapter, pbssid_tlv->bssid, (t_u8 *)&psk->bssid, MLAN_MAC_ADDR_LENGTH);
1183         ptlv_buffer += (pbssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
1184         cmd->size += (t_u16)(pbssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
1185         pbssid_tlv->header.len = wlan_cpu_to_le16(pbssid_tlv->header.len);
1186     }
1187     if (psk->psk_type == MLAN_PSK_PASSPHRASE)
1188     {
1189         ppassphrase_tlv              = (MrvlIEtypes_Passphrase_t *)(void *)ptlv_buffer;
1190         ppassphrase_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_PASSPHRASE);
1191         ppassphrase_tlv->header.len  = (t_u16)MIN(MLAN_MAX_PASSPHRASE_LENGTH, psk->psk.passphrase.passphrase_len);
1192         (void)__memcpy(pmpriv->adapter, ppassphrase_tlv->passphrase, psk->psk.passphrase.passphrase,
1193                        MIN(MLAN_MAX_PASSPHRASE_LENGTH, psk->psk.passphrase.passphrase_len));
1194         ptlv_buffer += (ppassphrase_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
1195         cmd->size += (t_u16)(ppassphrase_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
1196         ppassphrase_tlv->header.len = wlan_cpu_to_le16(ppassphrase_tlv->header.len);
1197     }
1198     if (psk->psk_type == MLAN_PSK_PASSWORD)
1199     {
1200         ppassword_tlv              = (MrvlIEtypes_Password_t *)(void *)ptlv_buffer;
1201         ppassword_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_WPA3_SAE_PASSWORD);
1202         ppassword_tlv->header.len  = (t_u16)MIN(MLAN_MAX_PASSWORD_LENGTH, psk->password.password_len);
1203         (void)__memcpy(pmpriv->adapter, ppassword_tlv->password, psk->password.password,
1204                        MIN(MLAN_MAX_PASSWORD_LENGTH, psk->password.password_len));
1205         ptlv_buffer += (ppassword_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
1206         cmd->size += (t_u16)(ppassword_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
1207         ppassword_tlv->header.len = wlan_cpu_to_le16(ppassword_tlv->header.len);
1208     }
1209     if (psk->psk_type == MLAN_PSK_PMK)
1210     {
1211         ppmk_tlv              = (MrvlIEtypes_PMK_t *)(void *)ptlv_buffer;
1212         ppmk_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_PMK);
1213         ppmk_tlv->header.len  = MLAN_MAX_KEY_LENGTH;
1214         (void)__memcpy(pmpriv->adapter, ppmk_tlv->pmk, psk->psk.pmk.pmk, MLAN_MAX_KEY_LENGTH);
1215         ptlv_buffer += (ppmk_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
1216         cmd->size += (t_u16)(ppmk_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
1217         ppmk_tlv->header.len = wlan_cpu_to_le16(ppmk_tlv->header.len);
1218     }
1219     if ((cmd_action == HostCmd_ACT_GEN_SET) &&
1220         (((pssid_tlv != MNULL) || (pbssid_tlv != MNULL)) &&
1221          ((ppmk_tlv == MNULL) && (ppassphrase_tlv == MNULL) && (ppassword_tlv == MNULL))))
1222     {
1223         PRINTM(MERROR, "Invalid case,ssid/bssid present without pmk or passphrase or password\n");
1224         LEAVE();
1225         return MLAN_STATUS_FAILURE;
1226     }
1227 #if CONFIG_RSN_REPLAY_DETECTION
1228     if ((cmd_action == HostCmd_ACT_GEN_SET) || (cmd_action == HostCmd_ACT_GEN_REMOVE))
1229     {
1230         wlan_reset_pn_on_rekey(pmpriv, psk->bssid);
1231     }
1232 #endif
1233     cmd->command                   = wlan_cpu_to_le16(HostCmd_CMD_SUPPLICANT_PMK);
1234     pesupplicant_psk->action       = wlan_cpu_to_le16(cmd_action);
1235     pesupplicant_psk->cache_result = 0;
1236     cmd->size                      = wlan_cpu_to_le16(cmd->size);
1237     LEAVE();
1238     return MLAN_STATUS_SUCCESS;
1239 }
1240 
1241 /**
1242  *  @brief This function prepares command of rf_channel.
1243  *
1244  *  @param pmpriv       A pointer to mlan_private structure
1245  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
1246  *  @param cmd_action   The action: GET or SET
1247  *  @param pdata_buf    A pointer to data buffer
1248  *
1249  *  @return             MLAN_STATUS_SUCCESS
1250  */
1251 static mlan_status wlan_cmd_802_11_rf_channel(IN pmlan_private pmpriv,
1252                                               IN HostCmd_DS_COMMAND *cmd,
1253                                               IN t_u16 cmd_action,
1254                                               IN t_void *pdata_buf)
1255 {
1256     HostCmd_DS_802_11_RF_CHANNEL *prf_chan = &cmd->params.rf_channel;
1257 
1258     ENTER();
1259 
1260     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_RF_CHANNEL);
1261     cmd->size    = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_RF_CHANNEL) + S_DS_GEN);
1262 
1263     if (cmd_action == HostCmd_ACT_GEN_SET)
1264     {
1265         if ((pmpriv->adapter->adhoc_start_band & BAND_A) || (pmpriv->adapter->adhoc_start_band & BAND_AN))
1266         {
1267             prf_chan->rf_type = HostCmd_SCAN_RADIO_TYPE_A;
1268         }
1269         SET_SECONDARYCHAN(prf_chan->rf_type, pmpriv->adapter->chan_bandwidth);
1270         prf_chan->rf_type         = wlan_cpu_to_le16(prf_chan->rf_type);
1271         prf_chan->current_channel = wlan_cpu_to_le16(*((t_u16 *)pdata_buf));
1272     }
1273     prf_chan->action = wlan_cpu_to_le16(cmd_action);
1274     LEAVE();
1275     return MLAN_STATUS_SUCCESS;
1276 }
1277 
1278 /**
1279  *  @brief This function prepares command of mgmt IE list.
1280  *
1281  *  @param pmpriv       A pointer to mlan_private structure
1282  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
1283  *  @param cmd_action   The action: GET or SET
1284  *  @param pdata_buf	A pointer to data buffer
1285  *
1286  *  @return             MLAN_STATUS_SUCCESS
1287  */
1288 static mlan_status wlan_cmd_mgmt_ie_list(IN pmlan_private pmpriv,
1289                                          IN HostCmd_DS_COMMAND *cmd,
1290                                          IN t_u16 cmd_action,
1291                                          IN t_void *pdata_buf)
1292 {
1293     t_u16 req_len = 0, travel_len = 0;
1294     custom_ie *cptr                            = MNULL;
1295     mlan_ds_misc_custom_ie *cust_ie            = MNULL;
1296     HostCmd_DS_MGMT_IE_LIST_CFG *pmgmt_ie_list = &(cmd->params.mgmt_ie_list);
1297 
1298     ENTER();
1299 
1300     cmd->command          = wlan_cpu_to_le16(HostCmd_CMD_MGMT_IE_LIST);
1301     cmd->size             = sizeof(HostCmd_DS_MGMT_IE_LIST_CFG) + S_DS_GEN;
1302     cmd->result           = 0;
1303     pmgmt_ie_list->action = wlan_cpu_to_le16(cmd_action);
1304 
1305     cust_ie                        = (mlan_ds_misc_custom_ie *)pdata_buf;
1306     pmgmt_ie_list->ds_mgmt_ie.type = wlan_cpu_to_le16(cust_ie->type);
1307     pmgmt_ie_list->ds_mgmt_ie.len  = wlan_cpu_to_le16(cust_ie->len);
1308 
1309     if ((pmgmt_ie_list != MNULL) && (cust_ie != MNULL))
1310     {
1311         req_len    = cust_ie->len;
1312         travel_len = 0;
1313         /* conversion for index, mask, len */
1314         if (req_len == sizeof(t_u16))
1315         {
1316             cust_ie->ie_data_list[0].ie_index = wlan_cpu_to_le16(cust_ie->ie_data_list[0].ie_index);
1317         }
1318 
1319         while (req_len > sizeof(t_u16))
1320         {
1321             cptr = (custom_ie *)(void *)(((t_u8 *)cust_ie->ie_data_list) + travel_len);
1322             travel_len += (t_u16)(cptr->ie_length + sizeof(custom_ie) - MAX_IE_SIZE);
1323             req_len -= (t_u16)(cptr->ie_length + sizeof(custom_ie) - MAX_IE_SIZE);
1324             cptr->ie_index          = wlan_cpu_to_le16(cptr->ie_index);
1325             cptr->mgmt_subtype_mask = wlan_cpu_to_le16(cptr->mgmt_subtype_mask);
1326             cptr->ie_length         = wlan_cpu_to_le16(cptr->ie_length);
1327         }
1328         if (cust_ie->len != 0U)
1329         {
1330             (void)__memcpy(pmpriv->adapter, pmgmt_ie_list->ds_mgmt_ie.ie_data_list, cust_ie->ie_data_list,
1331                            cust_ie->len);
1332         }
1333     }
1334 
1335     cmd->size -= (MAX_MGMT_IE_INDEX_TO_FW * sizeof(custom_ie)) + sizeof(tlvbuf_max_mgmt_ie);
1336     cmd->size += cust_ie->len;
1337     cmd->size = wlan_cpu_to_le16(cmd->size);
1338 
1339     LEAVE();
1340     return MLAN_STATUS_SUCCESS;
1341 }
1342 
1343 /**
1344 *  @brief This function prepares command of reg_access.
1345 *
1346 *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
1347 *  @param cmd_action   the action: GET or SET
1348 *  @param pdata_buf    A pointer to data buffer
1349 *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1350 */
1351 /* static */ mlan_status wlan_cmd_reg_access(IN HostCmd_DS_COMMAND *cmd, IN t_u16 cmd_action, IN t_void *pdata_buf)
1352 {
1353     mlan_ds_reg_rw *reg_rw;
1354     bool invalid_hostcmd = MFALSE;
1355 
1356     ENTER();
1357 
1358     reg_rw = (mlan_ds_reg_rw *)pdata_buf;
1359     switch (cmd->command)
1360     {
1361         case HostCmd_CMD_MAC_REG_ACCESS:
1362         {
1363             HostCmd_DS_MAC_REG_ACCESS *mac_reg;
1364             cmd->size       = wlan_cpu_to_le16(sizeof(HostCmd_DS_MAC_REG_ACCESS) + S_DS_GEN);
1365             mac_reg         = (HostCmd_DS_MAC_REG_ACCESS *)&cmd->params.mac_reg;
1366             mac_reg->action = wlan_cpu_to_le16(cmd_action);
1367             mac_reg->offset = wlan_cpu_to_le16((t_u16)reg_rw->offset);
1368             mac_reg->value  = wlan_cpu_to_le32(reg_rw->value);
1369             break;
1370         }
1371         case HostCmd_CMD_BBP_REG_ACCESS:
1372         {
1373             HostCmd_DS_BBP_REG_ACCESS *bbp_reg;
1374             cmd->size       = wlan_cpu_to_le16(sizeof(HostCmd_DS_BBP_REG_ACCESS) + S_DS_GEN);
1375             bbp_reg         = (HostCmd_DS_BBP_REG_ACCESS *)&cmd->params.bbp_reg;
1376             bbp_reg->action = wlan_cpu_to_le16(cmd_action);
1377             bbp_reg->offset = wlan_cpu_to_le16((t_u16)reg_rw->offset);
1378             bbp_reg->value  = (t_u8)reg_rw->value;
1379             break;
1380         }
1381         case HostCmd_CMD_RF_REG_ACCESS:
1382         {
1383             HostCmd_DS_RF_REG_ACCESS *rf_reg;
1384             cmd->size      = wlan_cpu_to_le16(sizeof(HostCmd_DS_RF_REG_ACCESS) + S_DS_GEN);
1385             rf_reg         = (HostCmd_DS_RF_REG_ACCESS *)&cmd->params.rf_reg;
1386             rf_reg->action = wlan_cpu_to_le16(cmd_action);
1387             rf_reg->offset = wlan_cpu_to_le16((t_u16)reg_rw->offset);
1388             rf_reg->value  = (t_u8)reg_rw->value;
1389             break;
1390         }
1391         case HostCmd_CMD_CAU_REG_ACCESS:
1392         {
1393             HostCmd_DS_RF_REG_ACCESS *cau_reg;
1394             cmd->size       = wlan_cpu_to_le16(sizeof(HostCmd_DS_RF_REG_ACCESS) + S_DS_GEN);
1395             cau_reg         = (HostCmd_DS_RF_REG_ACCESS *)&cmd->params.rf_reg;
1396             cau_reg->action = wlan_cpu_to_le16(cmd_action);
1397             cau_reg->offset = wlan_cpu_to_le16((t_u16)reg_rw->offset);
1398             cau_reg->value  = (t_u8)reg_rw->value;
1399             break;
1400         }
1401         case HostCmd_CMD_802_11_EEPROM_ACCESS:
1402         {
1403             mlan_ds_read_eeprom *rd_eeprom              = (mlan_ds_read_eeprom *)pdata_buf;
1404             HostCmd_DS_802_11_EEPROM_ACCESS *cmd_eeprom = (HostCmd_DS_802_11_EEPROM_ACCESS *)&cmd->params.eeprom;
1405             cmd->size              = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_EEPROM_ACCESS) + S_DS_GEN);
1406             cmd_eeprom->action     = wlan_cpu_to_le16(cmd_action);
1407             cmd_eeprom->offset     = wlan_cpu_to_le16(rd_eeprom->offset);
1408             cmd_eeprom->byte_count = wlan_cpu_to_le16(rd_eeprom->byte_count);
1409             cmd_eeprom->value      = 0;
1410             break;
1411         }
1412         default:
1413             invalid_hostcmd = MTRUE;
1414             break;
1415     }
1416     if (invalid_hostcmd == MTRUE)
1417     {
1418         LEAVE();
1419         return MLAN_STATUS_FAILURE;
1420     }
1421     cmd->command = wlan_cpu_to_le16(cmd->command);
1422 
1423     LEAVE();
1424     return MLAN_STATUS_SUCCESS;
1425 }
1426 
1427 /**
1428  *  @brief This function prepares command of mem_access.
1429  *
1430  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
1431  *  @param cmd_action   the action: GET or SET
1432  *  @param pdata_buf    A pointer to data buffer
1433  *  @return             MLAN_STATUS_SUCCESS
1434  */
1435 mlan_status wlan_cmd_mem_access(IN HostCmd_DS_COMMAND *cmd, IN t_u16 cmd_action, IN t_void *pdata_buf)
1436 {
1437     mlan_ds_mem_rw *mem_rw            = (mlan_ds_mem_rw *)pdata_buf;
1438     HostCmd_DS_MEM_ACCESS *mem_access = (HostCmd_DS_MEM_ACCESS *)&cmd->params.mem;
1439 
1440     ENTER();
1441 
1442     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MEM_ACCESS);
1443     cmd->size    = wlan_cpu_to_le16(sizeof(HostCmd_DS_MEM_ACCESS) + S_DS_GEN);
1444 
1445     mem_access->action = wlan_cpu_to_le16(cmd_action);
1446     mem_access->addr   = wlan_cpu_to_le32(mem_rw->addr);
1447     mem_access->value  = wlan_cpu_to_le32(mem_rw->value);
1448 
1449     LEAVE();
1450     return MLAN_STATUS_SUCCESS;
1451 }
1452 
1453 /**
1454  *  @brief This function prepares command of auto_reconnect
1455  *
1456  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
1457  *  @param cmd_action   the action: GET or SET
1458  *  @param pdata_buf    A pointer to data buffer
1459  *  @return             MLAN_STATUS_SUCCESS
1460  */
1461 mlan_status wlan_cmd_auto_reconnect(IN HostCmd_DS_COMMAND *cmd, IN t_u16 cmd_action, IN t_void *pdata_buf)
1462 {
1463     mlan_ds_auto_reconnect *auto_reconnect = (mlan_ds_auto_reconnect *)pdata_buf;
1464     HostCmd_DS_AUTO_RECONNECT *auto_reconn = (HostCmd_DS_AUTO_RECONNECT *)&cmd->params.auto_reconnect;
1465 
1466     ENTER();
1467 
1468     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_AUTO_RECONNECT);
1469     cmd->size    = wlan_cpu_to_le16(sizeof(HostCmd_DS_AUTO_RECONNECT) + S_DS_GEN);
1470 
1471     auto_reconn->action             = wlan_cpu_to_le16(cmd_action);
1472     auto_reconn->reconnect_counter  = auto_reconnect->reconnect_counter;
1473     auto_reconn->reconnect_interval = auto_reconnect->reconnect_interval;
1474     auto_reconn->flags              = wlan_cpu_to_le16(auto_reconnect->flags);
1475 
1476     LEAVE();
1477     return MLAN_STATUS_SUCCESS;
1478 }
1479 
1480 /**
1481  *  @brief This function prepares command of rx management indication
1482  *
1483  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
1484  *  @param cmd_action   the action: GET or SET
1485  *  @param pdata_buf    A pointer to data buffer
1486  *  @return             MLAN_STATUS_SUCCESS
1487  */
1488 mlan_status wlan_cmd_rx_mgmt_indication(IN pmlan_private pmpriv,
1489                                         IN HostCmd_DS_COMMAND *cmd,
1490                                         IN t_u16 cmd_action,
1491                                         IN t_void *pdata_buf)
1492 {
1493     mlan_ds_rx_mgmt_indication *rx_mgmt_indication = (mlan_ds_rx_mgmt_indication *)pdata_buf;
1494     HostCmd_DS_RX_MGMT_IND *rx_mgmt                = (HostCmd_DS_RX_MGMT_IND *)&cmd->params.rx_mgmt_ind;
1495 
1496     ENTER();
1497 
1498     /* Set passthru mask for mgmt frame */
1499     pmpriv->mgmt_frame_passthru_mask = rx_mgmt_indication->mgmt_subtype_mask;
1500 
1501     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_RX_MGMT_IND);
1502     cmd->size    = wlan_cpu_to_le16(sizeof(HostCmd_DS_RX_MGMT_IND) + S_DS_GEN);
1503 
1504     rx_mgmt->action            = wlan_cpu_to_le16(cmd_action);
1505     rx_mgmt->mgmt_subtype_mask = wlan_cpu_to_le32(rx_mgmt_indication->mgmt_subtype_mask);
1506 
1507     rx_mgmt->data_subtype_mask = 0;
1508 
1509     LEAVE();
1510     return MLAN_STATUS_SUCCESS;
1511 }
1512 
1513 #if CONFIG_11K_OFFLOAD
1514 /**
1515  *  @brief This function sends get nlist.
1516  *
1517  *  @param pmpriv       A pointer to mlan_private structure
1518  *  @param pcmd         Hostcmd ID
1519  *  @param cmd_action   Command action
1520  *  @param pdata_buf    A pointer to information buffer
1521  *  @return             N/A
1522  */
1523 static mlan_status wlan_cmd_offload_feature_ctrl(mlan_private *pmpriv,
1524                                                  HostCmd_DS_COMMAND *pcmd,
1525                                                  t_u16 cmd_action,
1526                                                  void *pdata_buf)
1527 {
1528     HostCmd_OFFLOAD_FEATURE_CTRL *pfctrl = &pcmd->params.fctrl;
1529     mlan_status ret                      = MLAN_STATUS_SUCCESS;
1530 
1531     ENTER();
1532 
1533     pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_OFFLOAD_FEATURE_CONTROL);
1534     (void)__memcpy(pmpriv->adapter, pfctrl, pdata_buf, sizeof(HostCmd_OFFLOAD_FEATURE_CTRL));
1535     pcmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_OFFLOAD_FEATURE_CTRL));
1536 
1537     LEAVE();
1538     return ret;
1539 }
1540 
1541 /**
1542  *  @brief This function sends 11k neighbor report request.
1543  *
1544  *  @param pmpriv       A pointer to mlan_private structure
1545  *  @param pcmd         Hostcmd ID
1546  *  @return             N/A
1547  */
1548 mlan_status wlan_cmd_11k_neighbor_req(mlan_private *pmpriv, HostCmd_DS_COMMAND *pcmd)
1549 {
1550     HostCmd_OFFLOAD_FEATURE_CTRL *pfctrl = &pcmd->params.fctrl;
1551     mlan_status ret                      = MLAN_STATUS_SUCCESS;
1552 
1553     ENTER();
1554     /* FW 11k/11mc recommend use 0x00fd instead of 0x0231 command */
1555     /* FW: FEATURE_TEST_ACTION_SELECT */
1556     pfctrl->featureSelect = 3;
1557     /* FW: host_OffloadFeatureTestAction_t.generate_neighbor_req */
1558     pfctrl->control.empty = 2;
1559     pcmd->command         = wlan_cpu_to_le16(HostCmd_CMD_OFFLOAD_FEATURE_CONTROL);
1560     pcmd->size            = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_OFFLOAD_FEATURE_CTRL) - 1);
1561 
1562     LEAVE();
1563     return ret;
1564 }
1565 #endif
1566 
1567 #if CONFIG_WLAN_BRIDGE
1568 /**
1569  *  @brief This function prepares command of bridge mode
1570  *
1571  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
1572  *  @param cmd_action   the action: GET or SET
1573  *  @param pdata_buf    A pointer to data buffer
1574  *  @return             MLAN_STATUS_SUCCESS
1575  */
1576 mlan_status wlan_cmd_bridge_mode(IN HostCmd_DS_COMMAND *cmd, IN t_u16 cmd_action, IN t_void *pdata_buf)
1577 {
1578     mlan_bridge_mode *bridge_mode = (mlan_bridge_mode *)pdata_buf;
1579     HostCmd_BRIDGE_MODE *bg_mode  = (HostCmd_BRIDGE_MODE *)&cmd->params.bridge_mode;
1580 
1581     ENTER();
1582 
1583     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_BRIDGE_MODE);
1584     cmd->size    = wlan_cpu_to_le16(sizeof(HostCmd_BRIDGE_MODE) + S_DS_GEN);
1585 
1586     bg_mode->action = wlan_cpu_to_le16(cmd_action);
1587     bg_mode->enable = wlan_cpu_to_le32(bridge_mode->enable);
1588     LEAVE();
1589     return MLAN_STATUS_SUCCESS;
1590 }
1591 #endif
1592 
1593 #if (CONFIG_SUBSCRIBE_EVENT_SUPPORT) || (CONFIG_ROAMING)
1594 int wlan_parse_getdata(HostCmd_DS_COMMAND *resp, mlan_ds_subscribe_evt *sub_evt)
1595 {
1596     if (!resp || !sub_evt)
1597         return WM_E_INVAL;
1598     HostCmd_DS_SUBSCRIBE_EVENT *evt                     = &resp->params.subscribe_event;
1599     int tyhdsize                                        = sizeof(MrvlIEtypesHeader_t);
1600     t_u8 *tlv0                                          = (t_u8 *)resp + sizeof(HostCmd_DS_SUBSCRIBE_EVENT) + S_DS_GEN;
1601     t_u8 *tlv                                           = tlv0;
1602     MrvlIEtypes_BeaconLowRssiThreshold_t *rssi_low      = MNULL;
1603     MrvlIEtypes_BeaconLowSnrThreshold_t *snr_low        = MNULL;
1604     MrvlIEtypes_FailureCount_t *fail_count              = MNULL;
1605     MrvlIEtypes_BeaconsMissed_t *beacon_missed          = MNULL;
1606     MrvlIEtypes_BeaconHighRssiThreshold_t *rssi_high    = MNULL;
1607     MrvlIEtypes_BeaconHighSnrThreshold_t *snr_high      = MNULL;
1608     MrvlIEtypes_DataLowRssiThreshold_t *data_rssi_low   = MNULL;
1609     MrvlIEtypes_DataLowSnrThreshold_t *data_snr_low     = MNULL;
1610     MrvlIEtypes_DataHighRssiThreshold_t *data_rssi_high = MNULL;
1611     MrvlIEtypes_DataHighSnrThreshold_t *data_snr_high   = MNULL;
1612     MrvlIEtypes_LinkQualityThreshold_t *link_quality    = MNULL;
1613     MrvlIETypes_PreBeaconMissed_t *pre_bcn_missed       = MNULL;
1614 
1615     sub_evt->evt_action = wlan_le16_to_cpu(evt->action);
1616     sub_evt->evt_bitmap = wlan_le16_to_cpu(evt->event_bitmap);
1617     /*rssi_low*/
1618     if ((tlv - tlv0) > resp->size)
1619         return WM_E_IO;
1620     rssi_low               = (MrvlIEtypes_BeaconLowRssiThreshold_t *)tlv;
1621     sub_evt->low_rssi      = rssi_low->value;
1622     sub_evt->low_rssi_freq = rssi_low->frequency;
1623     tlv += rssi_low->header.len + tyhdsize;
1624 
1625     /*snr_low*/
1626     if ((tlv - tlv0) > resp->size)
1627         return WM_E_IO;
1628     snr_low               = (MrvlIEtypes_BeaconLowSnrThreshold_t *)tlv;
1629     sub_evt->low_snr      = snr_low->value;
1630     sub_evt->low_snr_freq = snr_low->frequency;
1631     tlv += sizeof(MrvlIEtypes_BeaconLowSnrThreshold_t);
1632 
1633     /*max fail*/
1634     if ((tlv - tlv0) > resp->size)
1635         return WM_E_IO;
1636     fail_count                  = (MrvlIEtypes_FailureCount_t *)tlv;
1637     sub_evt->failure_count      = fail_count->value;
1638     sub_evt->failure_count_freq = fail_count->frequency;
1639     tlv += sizeof(MrvlIEtypes_FailureCount_t);
1640 
1641     /*beacon miss*/
1642     if ((tlv - tlv0) > resp->size)
1643         return WM_E_IO;
1644     beacon_missed             = (MrvlIEtypes_BeaconsMissed_t *)tlv;
1645     sub_evt->beacon_miss      = beacon_missed->value;
1646     sub_evt->beacon_miss_freq = beacon_missed->frequency;
1647     tlv += sizeof(MrvlIEtypes_BeaconsMissed_t);
1648 
1649     /*rssi high*/
1650     if ((tlv - tlv0) > resp->size)
1651         return WM_E_IO;
1652     rssi_high               = (MrvlIEtypes_BeaconHighRssiThreshold_t *)tlv;
1653     sub_evt->high_rssi      = rssi_high->value;
1654     sub_evt->high_rssi_freq = rssi_high->frequency;
1655     tlv += sizeof(MrvlIEtypes_BeaconHighRssiThreshold_t);
1656 
1657     /*snr high*/
1658     if ((tlv - tlv0) > resp->size)
1659         return WM_E_IO;
1660     snr_high               = (MrvlIEtypes_BeaconHighSnrThreshold_t *)tlv;
1661     sub_evt->high_snr      = snr_high->value;
1662     sub_evt->high_snr_freq = snr_high->frequency;
1663     tlv += sizeof(MrvlIEtypes_BeaconHighSnrThreshold_t);
1664 
1665     /*data rssi low*/
1666     if ((tlv - tlv0) > resp->size)
1667         return WM_E_IO;
1668     data_rssi_low               = (MrvlIEtypes_DataLowRssiThreshold_t *)tlv;
1669     sub_evt->data_low_rssi      = data_rssi_low->value;
1670     sub_evt->data_low_rssi_freq = data_rssi_low->frequency;
1671     tlv += sizeof(MrvlIEtypes_DataLowRssiThreshold_t);
1672 
1673     /*data snr low*/
1674     if ((tlv - tlv0) > resp->size)
1675         return WM_E_IO;
1676     data_snr_low               = (MrvlIEtypes_DataLowSnrThreshold_t *)tlv;
1677     sub_evt->data_low_snr      = data_snr_low->value;
1678     sub_evt->data_low_snr_freq = data_snr_low->frequency;
1679     tlv += sizeof(MrvlIEtypes_DataLowSnrThreshold_t);
1680 
1681     /*data rssi high*/
1682     if ((tlv - tlv0) > resp->size)
1683         return WM_E_IO;
1684     data_rssi_high               = (MrvlIEtypes_DataHighRssiThreshold_t *)tlv;
1685     sub_evt->data_high_rssi      = data_rssi_high->value;
1686     sub_evt->data_high_rssi_freq = data_rssi_high->frequency;
1687     tlv += sizeof(MrvlIEtypes_DataHighRssiThreshold_t);
1688 
1689     /*data snr high*/
1690     if ((tlv - tlv0) > resp->size)
1691         return WM_E_IO;
1692     data_snr_high               = (MrvlIEtypes_DataHighSnrThreshold_t *)tlv;
1693     sub_evt->data_high_snr      = data_snr_high->value;
1694     sub_evt->data_high_snr_freq = data_snr_high->frequency;
1695     tlv += sizeof(MrvlIEtypes_DataHighSnrThreshold_t);
1696 
1697     /*link quality*/
1698     if ((tlv - tlv0) > resp->size)
1699         return WM_E_IO;
1700     link_quality                   = (MrvlIEtypes_LinkQualityThreshold_t *)tlv;
1701     sub_evt->link_snr              = wlan_le16_to_cpu(link_quality->link_snr);
1702     sub_evt->link_snr_freq         = wlan_le16_to_cpu(link_quality->link_snr_freq);
1703     sub_evt->link_rate             = wlan_le16_to_cpu(link_quality->link_rate);
1704     sub_evt->link_rate_freq        = wlan_le16_to_cpu(link_quality->link_rate_freq);
1705     sub_evt->link_tx_latency       = wlan_le16_to_cpu(link_quality->link_tx_latency);
1706     sub_evt->link_tx_lantency_freq = wlan_le16_to_cpu(link_quality->link_tx_lantency_freq);
1707     tlv += link_quality->header.len + tyhdsize;
1708 
1709     /*pre beacon lost*/
1710     if ((tlv - tlv0) > resp->size)
1711         return WM_E_IO;
1712     pre_bcn_missed           = (MrvlIETypes_PreBeaconMissed_t *)tlv;
1713     sub_evt->pre_beacon_miss = pre_bcn_missed->value;
1714     tlv += tyhdsize + pre_bcn_missed->header.len;
1715 
1716     return WM_SUCCESS;
1717 }
1718 #endif
1719 
1720 /**
1721  *  @brief This function prepares command of subscribe event.
1722  *
1723  *  @param pmpriv    	A pointer to mlan_private structure
1724  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
1725  *  @param cmd_action   the action: GET or SET
1726  *  @param pdata_buf    A pointer to data buffer
1727  *  @return             MLAN_STATUS_SUCCESS
1728  */
1729 mlan_status wlan_cmd_subscribe_event(IN pmlan_private pmpriv,
1730                                      IN HostCmd_DS_COMMAND *cmd,
1731                                      IN t_u16 cmd_action,
1732                                      IN t_void *pdata_buf)
1733 {
1734     mlan_ds_subscribe_evt *sub_evt                      = (mlan_ds_subscribe_evt *)pdata_buf;
1735     HostCmd_DS_SUBSCRIBE_EVENT *evt                     = (HostCmd_DS_SUBSCRIBE_EVENT *)&cmd->params.subscribe_event;
1736     t_u16 cmd_size                                      = 0;
1737     t_u8 *tlv                                           = MNULL;
1738     MrvlIEtypes_BeaconLowRssiThreshold_t *rssi_low      = MNULL;
1739     MrvlIEtypes_BeaconLowSnrThreshold_t *snr_low        = MNULL;
1740     MrvlIEtypes_FailureCount_t *fail_count              = MNULL;
1741     MrvlIEtypes_BeaconsMissed_t *beacon_missed          = MNULL;
1742     MrvlIEtypes_BeaconHighRssiThreshold_t *rssi_high    = MNULL;
1743     MrvlIEtypes_BeaconHighSnrThreshold_t *snr_high      = MNULL;
1744     MrvlIEtypes_DataLowRssiThreshold_t *data_rssi_low   = MNULL;
1745     MrvlIEtypes_DataLowSnrThreshold_t *data_snr_low     = MNULL;
1746     MrvlIEtypes_DataHighRssiThreshold_t *data_rssi_high = MNULL;
1747     MrvlIEtypes_DataHighSnrThreshold_t *data_snr_high   = MNULL;
1748     MrvlIEtypes_LinkQualityThreshold_t *link_quality    = MNULL;
1749     MrvlIETypes_PreBeaconMissed_t *pre_bcn_missed       = MNULL;
1750 
1751     ENTER();
1752 
1753     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_SUBSCRIBE_EVENT);
1754     evt->action  = wlan_cpu_to_le16(cmd_action);
1755     cmd_size     = sizeof(HostCmd_DS_SUBSCRIBE_EVENT) + S_DS_GEN;
1756     if (cmd_action == HostCmd_ACT_GEN_GET)
1757         goto done;
1758     if (sub_evt->evt_action == SUBSCRIBE_EVT_ACT_BITWISE_CLR)
1759     {
1760         evt->action       = wlan_cpu_to_le16(SUBSCRIBE_EVT_ACT_BITWISE_CLR);
1761         evt->event_bitmap = wlan_cpu_to_le16(sub_evt->evt_bitmap);
1762         goto done;
1763     }
1764 
1765 #define HostCmd_ACT_BITWISE_SET 0x02
1766     evt->action       = wlan_cpu_to_le16(HostCmd_ACT_BITWISE_SET);
1767     evt->event_bitmap = wlan_cpu_to_le16(sub_evt->evt_bitmap);
1768     tlv               = (t_u8 *)cmd + cmd_size;
1769     if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_RSSI_LOW)
1770     {
1771         rssi_low              = (MrvlIEtypes_BeaconLowRssiThreshold_t *)tlv;
1772         rssi_low->header.type = wlan_cpu_to_le16(TLV_TYPE_RSSI_LOW);
1773         rssi_low->header.len =
1774             wlan_cpu_to_le16(sizeof(MrvlIEtypes_BeaconLowRssiThreshold_t) - sizeof(MrvlIEtypesHeader_t));
1775         rssi_low->value     = sub_evt->low_rssi;
1776         rssi_low->frequency = sub_evt->low_rssi_freq;
1777         tlv += sizeof(MrvlIEtypes_BeaconLowRssiThreshold_t);
1778         cmd_size += sizeof(MrvlIEtypes_BeaconLowRssiThreshold_t);
1779     }
1780     if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_SNR_LOW)
1781     {
1782         snr_low              = (MrvlIEtypes_BeaconLowSnrThreshold_t *)tlv;
1783         snr_low->header.type = wlan_cpu_to_le16(TLV_TYPE_SNR_LOW);
1784         snr_low->header.len =
1785             wlan_cpu_to_le16(sizeof(MrvlIEtypes_BeaconLowSnrThreshold_t) - sizeof(MrvlIEtypesHeader_t));
1786         snr_low->value     = sub_evt->low_snr;
1787         snr_low->frequency = sub_evt->low_snr_freq;
1788         tlv += sizeof(MrvlIEtypes_BeaconLowSnrThreshold_t);
1789         cmd_size += sizeof(MrvlIEtypes_BeaconLowSnrThreshold_t);
1790     }
1791     if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_MAX_FAIL)
1792     {
1793         fail_count              = (MrvlIEtypes_FailureCount_t *)tlv;
1794         fail_count->header.type = wlan_cpu_to_le16(TLV_TYPE_FAILCOUNT);
1795         fail_count->header.len  = wlan_cpu_to_le16(sizeof(MrvlIEtypes_FailureCount_t) - sizeof(MrvlIEtypesHeader_t));
1796         fail_count->value       = sub_evt->failure_count;
1797         fail_count->frequency   = sub_evt->failure_count_freq;
1798         tlv += sizeof(MrvlIEtypes_FailureCount_t);
1799         cmd_size += sizeof(MrvlIEtypes_FailureCount_t);
1800     }
1801     if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_BEACON_MISSED)
1802     {
1803         beacon_missed              = (MrvlIEtypes_BeaconsMissed_t *)tlv;
1804         beacon_missed->header.type = wlan_cpu_to_le16(TLV_TYPE_BCNMISS);
1805         beacon_missed->header.len = wlan_cpu_to_le16(sizeof(MrvlIEtypes_BeaconsMissed_t) - sizeof(MrvlIEtypesHeader_t));
1806         beacon_missed->value      = sub_evt->beacon_miss;
1807         beacon_missed->frequency  = sub_evt->beacon_miss_freq;
1808         tlv += sizeof(MrvlIEtypes_BeaconsMissed_t);
1809         cmd_size += sizeof(MrvlIEtypes_BeaconsMissed_t);
1810     }
1811     if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_RSSI_HIGH)
1812     {
1813         rssi_high              = (MrvlIEtypes_BeaconHighRssiThreshold_t *)tlv;
1814         rssi_high->header.type = wlan_cpu_to_le16(TLV_TYPE_RSSI_HIGH);
1815         rssi_high->header.len =
1816             wlan_cpu_to_le16(sizeof(MrvlIEtypes_BeaconHighRssiThreshold_t) - sizeof(MrvlIEtypesHeader_t));
1817         rssi_high->value     = sub_evt->high_rssi;
1818         rssi_high->frequency = sub_evt->high_rssi_freq;
1819         tlv += sizeof(MrvlIEtypes_BeaconHighRssiThreshold_t);
1820         cmd_size += sizeof(MrvlIEtypes_BeaconHighRssiThreshold_t);
1821     }
1822     if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_SNR_HIGH)
1823     {
1824         snr_high              = (MrvlIEtypes_BeaconHighSnrThreshold_t *)tlv;
1825         snr_high->header.type = wlan_cpu_to_le16(TLV_TYPE_SNR_HIGH);
1826         snr_high->header.len =
1827             wlan_cpu_to_le16(sizeof(MrvlIEtypes_BeaconHighSnrThreshold_t) - sizeof(MrvlIEtypesHeader_t));
1828         snr_high->value     = sub_evt->high_snr;
1829         snr_high->frequency = sub_evt->high_snr_freq;
1830         tlv += sizeof(MrvlIEtypes_BeaconHighSnrThreshold_t);
1831         cmd_size += sizeof(MrvlIEtypes_BeaconHighSnrThreshold_t);
1832     }
1833     if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_DATA_RSSI_LOW)
1834     {
1835         data_rssi_low              = (MrvlIEtypes_DataLowRssiThreshold_t *)tlv;
1836         data_rssi_low->header.type = wlan_cpu_to_le16(TLV_TYPE_RSSI_LOW_DATA);
1837         data_rssi_low->header.len =
1838             wlan_cpu_to_le16(sizeof(MrvlIEtypes_DataLowRssiThreshold_t) - sizeof(MrvlIEtypesHeader_t));
1839         data_rssi_low->value     = sub_evt->data_low_rssi;
1840         data_rssi_low->frequency = sub_evt->data_low_rssi_freq;
1841         tlv += sizeof(MrvlIEtypes_DataLowRssiThreshold_t);
1842         cmd_size += sizeof(MrvlIEtypes_DataLowRssiThreshold_t);
1843     }
1844     if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_DATA_SNR_LOW)
1845     {
1846         data_snr_low              = (MrvlIEtypes_DataLowSnrThreshold_t *)tlv;
1847         data_snr_low->header.type = wlan_cpu_to_le16(TLV_TYPE_SNR_LOW_DATA);
1848         data_snr_low->header.len =
1849             wlan_cpu_to_le16(sizeof(MrvlIEtypes_DataLowSnrThreshold_t) - sizeof(MrvlIEtypesHeader_t));
1850         data_snr_low->value     = sub_evt->data_low_snr;
1851         data_snr_low->frequency = sub_evt->data_low_snr_freq;
1852         tlv += sizeof(MrvlIEtypes_DataLowSnrThreshold_t);
1853         cmd_size += sizeof(MrvlIEtypes_DataLowSnrThreshold_t);
1854     }
1855     if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_DATA_RSSI_HIGH)
1856     {
1857         data_rssi_high              = (MrvlIEtypes_DataHighRssiThreshold_t *)tlv;
1858         data_rssi_high->header.type = wlan_cpu_to_le16(TLV_TYPE_RSSI_HIGH_DATA);
1859         data_rssi_high->header.len =
1860             wlan_cpu_to_le16(sizeof(MrvlIEtypes_DataHighRssiThreshold_t) - sizeof(MrvlIEtypesHeader_t));
1861         data_rssi_high->value     = sub_evt->data_high_rssi;
1862         data_rssi_high->frequency = sub_evt->data_high_rssi_freq;
1863         tlv += sizeof(MrvlIEtypes_DataHighRssiThreshold_t);
1864         cmd_size += sizeof(MrvlIEtypes_DataHighRssiThreshold_t);
1865     }
1866     if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_DATA_SNR_HIGH)
1867     {
1868         data_snr_high              = (MrvlIEtypes_DataHighSnrThreshold_t *)tlv;
1869         data_snr_high->header.type = wlan_cpu_to_le16(TLV_TYPE_SNR_HIGH_DATA);
1870         data_snr_high->header.len =
1871             wlan_cpu_to_le16(sizeof(MrvlIEtypes_DataHighSnrThreshold_t) - sizeof(MrvlIEtypesHeader_t));
1872         data_snr_high->value     = sub_evt->data_high_snr;
1873         data_snr_high->frequency = sub_evt->data_high_snr_freq;
1874         tlv += sizeof(MrvlIEtypes_DataHighSnrThreshold_t);
1875         cmd_size += sizeof(MrvlIEtypes_DataHighSnrThreshold_t);
1876     }
1877     if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_LINK_QUALITY)
1878     {
1879         link_quality              = (MrvlIEtypes_LinkQualityThreshold_t *)tlv;
1880         link_quality->header.type = wlan_cpu_to_le16(TLV_TYPE_LINK_QUALITY);
1881         link_quality->header.len =
1882             wlan_cpu_to_le16(sizeof(MrvlIEtypes_LinkQualityThreshold_t) - sizeof(MrvlIEtypesHeader_t));
1883         link_quality->link_snr              = wlan_cpu_to_le16(sub_evt->link_snr);
1884         link_quality->link_snr_freq         = wlan_cpu_to_le16(sub_evt->link_snr_freq);
1885         link_quality->link_rate             = wlan_cpu_to_le16(sub_evt->link_rate);
1886         link_quality->link_rate_freq        = wlan_cpu_to_le16(sub_evt->link_rate_freq);
1887         link_quality->link_tx_latency       = wlan_cpu_to_le16(sub_evt->link_tx_latency);
1888         link_quality->link_tx_lantency_freq = wlan_cpu_to_le16(sub_evt->link_tx_lantency_freq);
1889         tlv += sizeof(MrvlIEtypes_LinkQualityThreshold_t);
1890         cmd_size += sizeof(MrvlIEtypes_LinkQualityThreshold_t);
1891     }
1892     if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_PRE_BEACON_LOST)
1893     {
1894         pre_bcn_missed              = (MrvlIETypes_PreBeaconMissed_t *)tlv;
1895         pre_bcn_missed->header.type = wlan_cpu_to_le16(TLV_TYPE_PRE_BCNMISS);
1896         pre_bcn_missed->header.len =
1897             wlan_cpu_to_le16(sizeof(MrvlIETypes_PreBeaconMissed_t) - sizeof(MrvlIEtypesHeader_t));
1898         pre_bcn_missed->value     = sub_evt->pre_beacon_miss;
1899         pre_bcn_missed->frequency = 0;
1900         tlv += sizeof(MrvlIETypes_PreBeaconMissed_t);
1901         cmd_size += sizeof(MrvlIETypes_PreBeaconMissed_t);
1902     }
1903 done:
1904     cmd->size = wlan_cpu_to_le16(cmd_size);
1905     LEAVE();
1906     return MLAN_STATUS_SUCCESS;
1907 }
1908 
1909 /**
1910  *  @brief This function prepares command of OTP user data.
1911  *
1912  *  @param pmpriv    	A pointer to mlan_private structure
1913  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
1914  *  @param cmd_action   the action: GET or SET
1915  *  @param pdata_buf    A pointer to data buffer
1916  *  @return             MLAN_STATUS_SUCCESS
1917  */
1918 static mlan_status wlan_cmd_otp_user_data(IN pmlan_private pmpriv,
1919                                           IN HostCmd_DS_COMMAND *cmd,
1920                                           IN t_u16 cmd_action,
1921                                           IN t_void *pdata_buf)
1922 {
1923     mlan_ds_misc_otp_user_data *user_data   = (mlan_ds_misc_otp_user_data *)pdata_buf;
1924     HostCmd_DS_OTP_USER_DATA *cmd_user_data = (HostCmd_DS_OTP_USER_DATA *)&cmd->params.otp_user_data;
1925     t_u16 cmd_size                          = 0;
1926 
1927     ENTER();
1928 
1929     cmd->command = wlan_cpu_to_le16(HostCmd_CMD_OTP_READ_USER_DATA);
1930     cmd_size     = sizeof(HostCmd_DS_OTP_USER_DATA) + S_DS_GEN - 1U;
1931 
1932     cmd_user_data->action           = wlan_cpu_to_le16(cmd_action);
1933     cmd_user_data->reserved         = 0;
1934     cmd_user_data->user_data_length = wlan_cpu_to_le16(user_data->user_data_length);
1935     /* wmsdk: below change is added in order to count user_data_length size
1936      * for SET/Write operation only, in case GET/Read it is not required
1937      * (SDIO cmd size remains same).
1938      */
1939     if (cmd_action == HostCmd_ACT_GEN_SET)
1940     {
1941         cmd_size += user_data->user_data_length;
1942     }
1943     cmd->size = wlan_cpu_to_le16(cmd_size);
1944 
1945     LEAVE();
1946     return MLAN_STATUS_SUCCESS;
1947 }
1948 
1949 #if CONFIG_TX_AMPDU_PROT_MODE
1950 /**
1951  *  @brief This function handles the command response of Tx ampdu prot mode
1952  *
1953  *  @param pmpriv       A pointer to mlan_private structure
1954  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
1955  *  @param cmd_action   The action: GET or SET
1956  *  @param pdata_buf    A pointer to command information buffer
1957  *
1958  *  @return             MLAN_STATUS_SUCCESS
1959  */
1960 static mlan_status wlan_cmd_tx_ampdu_prot_mode(IN pmlan_private pmpriv,
1961                                                IN HostCmd_DS_COMMAND *cmd,
1962                                                IN t_u16 cmd_action,
1963                                                IN t_void *pdata_buf)
1964 {
1965     HostCmd_DS_CMD_TX_AMPDU_PROT_MODE *prot_mode = &cmd->params.tx_ampdu_prot_mode;
1966     tx_ampdu_prot_mode_para *para                = (tx_ampdu_prot_mode_para *)pdata_buf;
1967 
1968     ENTER();
1969 
1970     cmd->command      = wlan_cpu_to_le16(HostCmd_CMD_TX_AMPDU_PROT_MODE);
1971     cmd->size         = wlan_cpu_to_le16(sizeof(HostCmd_DS_CMD_TX_AMPDU_PROT_MODE) + S_DS_GEN);
1972     prot_mode->action = wlan_cpu_to_le16(cmd_action);
1973 
1974     if (cmd_action == HostCmd_ACT_GEN_SET)
1975     {
1976         prot_mode->mode = wlan_cpu_to_le16(para->mode);
1977     }
1978 
1979     LEAVE();
1980     return MLAN_STATUS_SUCCESS;
1981 }
1982 #endif
1983 
1984 #if CONFIG_CSI
1985 /**
1986  * @brief This function enable/disable CSI support.
1987  *
1988  * @param pmpriv       A pointer to mlan_private structure
1989  * @param cmd          A pointer to HostCmd_DS_COMMAND structure
1990  * @param cmd_action   The action: GET or SET
1991  * @param pdata_buf    A pointer to data buffer
1992  *
1993  * @return             MLAN_STATUS_SUCCESS
1994  */
1995 static mlan_status wlan_cmd_csi(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, t_u16 cmd_action, t_u16 *pdata_buf)
1996 {
1997     HostCmd_DS_CSI_CFG *csi_cfg_cmd      = &cmd->params.csi_params;
1998     wifi_csi_config_params_t *csi_params = MNULL;
1999 
2000     ENTER();
2001 
2002     cmd->command        = wlan_cpu_to_le16(HostCmd_CMD_CSI);
2003     cmd->size           = sizeof(HostCmd_DS_CSI_CFG) + S_DS_GEN;
2004     csi_cfg_cmd->action = wlan_cpu_to_le16(cmd_action);
2005     switch (cmd_action)
2006     {
2007         case CSI_CMD_ENABLE:
2008             csi_params                  = (wifi_csi_config_params_t *)pdata_buf;
2009             csi_cfg_cmd->head_id        = wlan_cpu_to_le32(csi_params->head_id);
2010             csi_cfg_cmd->tail_id        = wlan_cpu_to_le32(csi_params->tail_id);
2011             csi_cfg_cmd->chip_id        = csi_params->chip_id;
2012             csi_cfg_cmd->csi_filter_cnt = csi_params->csi_filter_cnt;
2013 
2014             csi_cfg_cmd->channel_bandconfig.header.type        = wlan_cpu_to_le16(TLV_TYPE_CSI_MONITOR_CFG);
2015             csi_cfg_cmd->channel_bandconfig.header.len         = 4;
2016             csi_cfg_cmd->channel_bandconfig.bandconfig         = csi_params->band_config;
2017             csi_cfg_cmd->channel_bandconfig.channel            = csi_params->channel;
2018             csi_cfg_cmd->channel_bandconfig.csi_monitor_enable = csi_params->csi_monitor_enable;
2019             csi_cfg_cmd->channel_bandconfig.ra4us              = csi_params->ra4us;
2020 
2021             if (csi_cfg_cmd->csi_filter_cnt > CSI_FILTER_MAX)
2022                 csi_cfg_cmd->csi_filter_cnt = CSI_FILTER_MAX;
2023             memcpy((t_u8 *)csi_cfg_cmd->csi_filter, (t_u8 *)csi_params->csi_filter,
2024                    sizeof(wifi_csi_filter_t) * csi_cfg_cmd->csi_filter_cnt);
2025 
2026             DBG_HEXDUMP(MCMD_D, "Enable CSI", csi_cfg_cmd, sizeof(HostCmd_DS_CSI_CFG));
2027             break;
2028         case CSI_CMD_DISABLE:
2029             DBG_HEXDUMP(MCMD_D, "Disable CSI", csi_cfg_cmd, sizeof(HostCmd_DS_CSI_CFG));
2030         default:
2031             break;
2032     }
2033     cmd->size = wlan_cpu_to_le16(cmd->size);
2034     LEAVE();
2035     return MLAN_STATUS_SUCCESS;
2036 }
2037 #endif
2038 
2039 /********************************************************
2040                 Global Functions
2041 ********************************************************/
2042 
2043 /**
2044  *  @brief This function prepare the command before sending to firmware.
2045  *
2046  *  @param priv       A pointer to mlan_private structure
2047  *  @param cmd_no       Command number
2048  *  @param cmd_action   Command action: GET or SET
2049  *  @param cmd_oid      Cmd oid: treated as sub command
2050  *  @param pioctl_buf   A pointer to MLAN IOCTL Request buffer
2051  *  @param pdata_buf    A pointer to information buffer
2052  *  @param pcmd_buf      A pointer to cmd buf
2053  *
2054  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
2055  */
2056 mlan_status wlan_ops_sta_prepare_cmd(IN t_void *priv,
2057                                      IN t_u16 cmd_no,
2058                                      IN t_u16 cmd_action,
2059                                      IN t_u32 cmd_oid,
2060                                      IN t_void *pioctl_buf,
2061                                      IN t_void *pdata_buf,
2062                                      IN t_void *pcmd_buf)
2063 {
2064     HostCmd_DS_COMMAND *cmd_ptr = (HostCmd_DS_COMMAND *)pcmd_buf;
2065     mlan_private *pmpriv        = (mlan_private *)priv;
2066     mlan_status ret             = MLAN_STATUS_SUCCESS;
2067 
2068     ENTER();
2069 
2070     /* Prepare command */
2071     switch (cmd_no)
2072     {
2073         case HostCmd_CMD_MAC_CONTROL:
2074             ret = wlan_cmd_mac_control(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2075             break;
2076         case HostCmd_CMD_802_11_MAC_ADDRESS:
2077             ret = wlan_cmd_802_11_mac_address(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2078             break;
2079         case HostCmd_CMD_MAC_MULTICAST_ADR:
2080             ret = wlan_cmd_mac_multicast_adr(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2081             break;
2082         case HostCmd_CMD_TX_RATE_CFG:
2083             ret = wlan_cmd_tx_rate_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf, pioctl_buf);
2084             break;
2085         case HostCmd_CMD_802_11_RF_ANTENNA:
2086             ret = wlan_cmd_802_11_rf_antenna(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2087             break;
2088 #if CONFIG_NET_MONITOR
2089         case HostCmd_CMD_802_11_NET_MONITOR:
2090             ret = wlan_cmd_802_11_net_monitor(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2091             break;
2092 #endif
2093         case HostCmd_CMD_TXPWR_CFG:
2094             ret = wlan_cmd_tx_power_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2095             break;
2096         case HostCmd_CMD_802_11_RF_TX_POWER:
2097             ret = wlan_cmd_802_11_rf_tx_power(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2098             break;
2099         case HostCmd_CMD_802_11_HS_CFG_ENH:
2100             ret = wlan_cmd_802_11_hs_cfg(pmpriv, cmd_ptr, cmd_action, (hs_config_param *)pdata_buf);
2101             break;
2102 #if CONFIG_WMM_UAPSD
2103         case HostCmd_CMD_802_11_SLEEP_PERIOD:
2104             ret = wlan_cmd_802_11_sleep_period(pmpriv, cmd_ptr, cmd_action, (t_u16 *)pdata_buf);
2105             break;
2106 #endif
2107 #if !CONFIG_EXT_SCAN_SUPPORT
2108         case HostCmd_CMD_802_11_SCAN:
2109             ret = wlan_cmd_802_11_scan(pmpriv, cmd_ptr, pdata_buf);
2110             break;
2111 #endif
2112 #if CONFIG_BG_SCAN
2113         case HostCmd_CMD_802_11_BG_SCAN_CONFIG:
2114             ret = wlan_cmd_bgscan_config(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2115             break;
2116         case HostCmd_CMD_802_11_BG_SCAN_QUERY:
2117             ret = wlan_cmd_802_11_bg_scan_query(pmpriv, cmd_ptr, cmd_action);
2118             break;
2119 #endif
2120         case HostCmd_CMD_802_11_ASSOCIATE:
2121             ret = wlan_cmd_802_11_associate(pmpriv, cmd_ptr, pdata_buf);
2122             break;
2123         case HostCmd_CMD_802_11_GET_LOG:
2124             ret = wlan_cmd_802_11_get_log(pmpriv, cmd_ptr);
2125             break;
2126         case HostCmd_CMD_RSSI_INFO:
2127             ret = wlan_cmd_802_11_rssi_info(pmpriv, cmd_ptr, cmd_action);
2128             break;
2129         case HostCmd_CMD_802_11_SNMP_MIB:
2130             ret = wlan_cmd_802_11_snmp_mib(pmpriv, cmd_ptr, cmd_action, cmd_oid, pdata_buf);
2131             break;
2132         case HostCmd_CMD_802_11_TX_RATE_QUERY:
2133             cmd_ptr->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_TX_RATE_QUERY);
2134             cmd_ptr->size    = wlan_cpu_to_le16(sizeof(HostCmd_TX_RATE_QUERY) + S_DS_GEN);
2135             pmpriv->tx_rate  = 0;
2136             ret              = MLAN_STATUS_SUCCESS;
2137             break;
2138         case HostCmd_CMD_TBTT_OFFSET:
2139             cmd_ptr->command                   = wlan_cpu_to_le16(HostCmd_CMD_TBTT_OFFSET);
2140             cmd_ptr->size                      = wlan_cpu_to_le16(S_DS_GEN + sizeof(t_u16));
2141             cmd_ptr->params.tbtt_offset.action = HostCmd_ACT_GEN_GET;
2142             ret                                = MLAN_STATUS_SUCCESS;
2143             break;
2144         case HostCmd_CMD_VERSION_EXT:
2145             (void)__memset(pmpriv->adapter, cmd_ptr, 0x00, sizeof(HostCmd_DS_COMMAND));
2146             cmd_ptr->command                       = wlan_cpu_to_le16(cmd_no);
2147             cmd_ptr->params.verext.version_str_sel = *(t_u8 *)pdata_buf;
2148             cmd_ptr->size                          = wlan_cpu_to_le16(sizeof(HostCmd_DS_VERSION_EXT) + S_DS_GEN);
2149             ret                                    = MLAN_STATUS_SUCCESS;
2150             break;
2151         case HostCmd_CMD_802_11_RF_CHANNEL:
2152             ret = wlan_cmd_802_11_rf_channel(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2153             break;
2154         case HostCmd_CMD_11N_ADDBA_REQ:
2155             ret = wlan_cmd_11n_addba_req(pmpriv, cmd_ptr, pdata_buf);
2156             break;
2157         case HostCmd_CMD_11N_DELBA:
2158             ret = wlan_cmd_11n_delba(pmpriv, cmd_ptr, pdata_buf);
2159             break;
2160         case HostCmd_CMD_11N_ADDBA_RSP:
2161             ret = wlan_cmd_11n_addba_rspgen(pmpriv, cmd_ptr, pdata_buf);
2162             break;
2163 #ifdef WPA
2164         case HostCmd_CMD_802_11_KEY_MATERIAL:
2165             ret = wlan_cmd_802_11_key_material(pmpriv, cmd_ptr, cmd_action, cmd_oid, pdata_buf);
2166             break;
2167 #endif /* End of WPA */
2168 #if CONFIG_GTK_REKEY_OFFLOAD
2169         case HostCmd_CMD_CONFIG_GTK_REKEY_OFFLOAD_CFG:
2170             ret = wlan_cmd_gtk_rekey_offload(pmpriv, cmd_ptr, cmd_action, cmd_oid, pdata_buf);
2171             break;
2172 #endif
2173         case HostCmd_CMD_SUPPLICANT_PMK:
2174             ret = wlan_cmd_802_11_supplicant_pmk(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2175             break;
2176         case HostCmd_CMD_802_11D_DOMAIN_INFO:
2177             if (pmpriv->support_11d_APIs != MNULL)
2178             {
2179                 ret = pmpriv->support_11d_APIs->wlan_cmd_802_11d_domain_info_p(pmpriv, cmd_ptr, cmd_action);
2180             }
2181             break;
2182         case HostCmd_CMD_11N_CFG:
2183             ret = wlan_cmd_11n_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2184             break;
2185         case HostCmd_CMD_11AC_CFG:
2186             ret = wlan_cmd_11ac_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2187             break;
2188 #if CONFIG_WMM
2189         case HostCmd_CMD_WMM_PARAM_CONFIG:
2190             ret = wlan_cmd_wmm_param_config(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2191             break;
2192 #endif
2193         case HostCmd_CMD_MGMT_IE_LIST:
2194             ret = wlan_cmd_mgmt_ie_list(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2195             break;
2196 #if CONFIG_EXT_SCAN_SUPPORT
2197         case HostCmd_CMD_802_11_SCAN_EXT:
2198             ret = wlan_cmd_802_11_scan_ext(pmpriv, cmd_ptr, pdata_buf);
2199             break;
2200 #endif
2201         case HostCmd_CMD_802_11_REMAIN_ON_CHANNEL:
2202             ret = wlan_cmd_remain_on_channel(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2203             break;
2204         case HostCmd_CMD_802_11_SUBSCRIBE_EVENT:
2205             ret = wlan_cmd_subscribe_event(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2206             break;
2207         case HostCmd_CMD_OTP_READ_USER_DATA:
2208             ret = wlan_cmd_otp_user_data(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2209             break;
2210         case HostCmd_CMD_HS_WAKEUP_REASON:
2211             ret = wlan_cmd_hs_wakeup_reason(pmpriv, cmd_ptr, pdata_buf);
2212             break;
2213         case HostCmd_CMD_GET_TSF:
2214             ret = wlan_cmd_get_tsf(pmpriv, cmd_ptr, cmd_action);
2215             break;
2216 #if CONFIG_WIFI_CLOCKSYNC
2217         case HostCmd_GPIO_TSF_LATCH_PARAM_CONFIG:
2218             ret = wlan_cmd_gpio_tsf_latch(pmpriv, cmd_ptr, cmd_action, pioctl_buf, pdata_buf);
2219             break;
2220 #endif /* CONFIG_WIFI_CLOCKSYNC */
2221 #if (CONFIG_WIFI_TX_PER_TRACK) || (CONFIG_TX_RX_HISTOGRAM)
2222         case HostCmd_CMD_TX_RX_PKT_STATS:
2223             ret = wlan_cmd_txrx_pkt_stats(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2224             break;
2225 #endif
2226 #if CONFIG_RF_TEST_MODE
2227         case HostCmd_CMD_MFG_COMMAND:
2228             ret = wlan_cmd_mfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2229             break;
2230 #endif
2231         case HostCmd_CMD_BOOT_SLEEP:
2232             ret = wlan_cmd_boot_sleep(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2233             break;
2234 #if CONFIG_11AX
2235         case HostCmd_CMD_11AX_CMD:
2236             ret = (mlan_status)wlan_cmd_11ax_cmd(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2237             break;
2238         case HostCmd_CMD_11AX_CFG:
2239             ret = (mlan_status)wlan_cmd_11ax_cfg(pmpriv, cmd_action, pdata_buf);
2240             break;
2241 #if CONFIG_11AX_TWT
2242         case HostCmd_CMD_TWT_CFG:
2243             ret = wlan_cmd_twt_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2244             break;
2245 #endif /* CONFIG_11AX_TWT */
2246 #endif /* CONFIG_11AX */
2247 #if CONFIG_11K_OFFLOAD
2248         case HostCmd_CMD_OFFLOAD_FEATURE_CONTROL:
2249             ret = wlan_cmd_offload_feature_ctrl(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2250             break;
2251 #endif /* CONFIG_11K_OFFLOAD */
2252 #if CONFIG_MULTI_CHAN
2253         case HostCmd_CMD_MULTI_CHAN_CONFIG:
2254             ret = wlan_cmd_multi_chan_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2255             break;
2256         case HostCmd_CMD_MULTI_CHAN_POLICY:
2257             ret = wlan_cmd_multi_chan_policy(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2258             break;
2259         case HostCmd_CMD_DRCS_CONFIG:
2260             ret = wlan_cmd_drcs_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2261             break;
2262 #endif
2263 #if CONFIG_COMPRESS_TX_PWTBL
2264         case HostCmd_CMD_REGION_POWER_CFG:
2265             ret = wlan_cmd_region_power_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2266             break;
2267 #endif
2268 #if CONFIG_1AS
2269         case HostCmd_CMD_HOST_CLOCK_CFG:
2270             ret = wlan_cmd_host_clock_cfg(cmd_ptr, cmd_action, pdata_buf);
2271             break;
2272 #endif
2273 #if CONFIG_TX_AMPDU_PROT_MODE
2274         case HostCmd_CMD_TX_AMPDU_PROT_MODE:
2275             ret = wlan_cmd_tx_ampdu_prot_mode(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2276             break;
2277 #endif
2278 #if CONFIG_CSI
2279         case HostCmd_CMD_CSI:
2280             ret = wlan_cmd_csi(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2281             break;
2282 #endif
2283 #if CONFIG_RX_ABORT_CFG
2284         case HostCmd_CMD_RX_ABORT_CFG:
2285             ret = wlan_cmd_rx_abort_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2286             break;
2287 #endif
2288 #if CONFIG_RX_ABORT_CFG_EXT
2289         case HostCmd_CMD_RX_ABORT_CFG_EXT:
2290             ret = wlan_cmd_rx_abort_cfg_ext(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2291             break;
2292 #endif
2293 #if CONFIG_CCK_DESENSE_CFG
2294         case HostCmd_CMD_CCK_DESENSE_CFG:
2295             ret = wlan_cmd_cck_desense_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2296             break;
2297 #endif
2298 #if (CONFIG_WIFI_IND_RESET) && (CONFIG_WIFI_IND_DNLD)
2299         case HostCmd_CMD_INDEPENDENT_RESET_CFG:
2300             ret = wlan_cmd_ind_rst_cfg(cmd_ptr, cmd_action, pdata_buf);
2301             break;
2302 #endif
2303         case HostCmd_CMD_802_11_TX_FRAME:
2304             ret = wlan_cmd_tx_frame(pmpriv, cmd_ptr, cmd_action, pdata_buf);
2305             break;
2306         default:
2307             PRINTM(MERROR, "PREP_CMD: unknown command- %#x\n", cmd_no);
2308             ret = MLAN_STATUS_FAILURE;
2309             break;
2310     }
2311 
2312     LEAVE();
2313     return ret;
2314 }
2315