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