1 /** @file mlan_cmdevt.c
2 *
3 * @brief This file provides the handling of CMD/EVENT in MLAN
4 *
5 * Copyright 2008-2024 NXP
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 *
9 */
10
11 /*************************************************************
12 Change Log:
13 05/12/2009: initial version
14 ************************************************************/
15 #include <mlan_api.h>
16
17 /* Additional WMSDK header files */
18 #include <wmerrno.h>
19 #include <osa.h>
20
21 /* Always keep this include at the end of all include files */
22 #include <mlan_remap_mem_operations.h>
23
24 /********************************************************
25 Local Variables
26 ********************************************************/
27
28 /*******************************************************
29 Global Variables
30 ********************************************************/
31
32 /********************************************************
33 Local Functions
34 ********************************************************/
35
36 /**
37 * @brief This function prepare the command before sending to firmware.
38 *
39 * @param pmpriv A pointer to mlan_private structure
40 * @param cmd_no Command number
41 * @param cmd_action Command action: GET or SET
42 * @param cmd_oid Cmd oid: treated as sub command
43 * @param pioctl_buf A pointer to MLAN IOCTL Request buffer
44 * @param pdata_buf A pointer to information buffer
45 *
46 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
47 */
wlan_prepare_cmd(IN mlan_private * pmpriv,IN t_u16 cmd_no,IN t_u16 cmd_action,IN t_u32 cmd_oid,IN t_void * pioctl_buf,IN t_void * pdata_buf)48 mlan_status wlan_prepare_cmd(IN mlan_private *pmpriv,
49 IN t_u16 cmd_no,
50 IN t_u16 cmd_action,
51 IN t_u32 cmd_oid,
52 IN t_void *pioctl_buf,
53 IN t_void *pdata_buf)
54 {
55 /* Note: We send only one command at a time and do not need the linked
56 list based implementation used here. So we will call our own
57 implementation here.
58 */
59
60 return wifi_prepare_and_send_cmd(pmpriv, cmd_no, cmd_action, cmd_oid, pioctl_buf, pdata_buf, pmpriv->bss_type,
61 NULL);
62 }
63
64 #if CONFIG_11AX
65 /**
66 * @brief Fetch bitmap rate index
67 *
68 * @param rate_scope A pointer to MrvlRateScope_t
69 *
70 * @return bitmap rate index
71 */
wlan_get_bitmap_index(MrvlRateScope_t * rate_scope)72 static t_u16 wlan_get_bitmap_index(MrvlRateScope_t *rate_scope)
73 {
74 t_u16 index = 0;
75 if (rate_scope != MNULL)
76 {
77 index += NELEMENTS(rate_scope->ht_mcs_rate_bitmap);
78 index += NELEMENTS(rate_scope->vht_mcs_rate_bitmap);
79 }
80 return index;
81 }
82 #endif
83
84 /**
85 * @brief This function prepares command of power mode
86 *
87 * @param pmpriv A pointer to mlan_private structure
88 * @param cmd A pointer to HostCmd_DS_COMMAND structure
89 * @param cmd_action the action: GET or SET
90 * @param ps_bitmap PS bitmap
91 * @param pdata_buf A pointer to data buffer
92 * @return MLAN_STATUS_SUCCESS
93 */
wlan_cmd_enh_power_mode(pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN ENH_PS_MODES cmd_action,IN t_u16 ps_bitmap,IN t_void * pdata_buf)94 mlan_status wlan_cmd_enh_power_mode(pmlan_private pmpriv,
95 IN HostCmd_DS_COMMAND *cmd,
96 IN ENH_PS_MODES cmd_action,
97 IN t_u16 ps_bitmap,
98 IN t_void *pdata_buf)
99 {
100 HostCmd_DS_802_11_PS_MODE_ENH *psmode_enh = &cmd->params.psmode_enh;
101 t_u8 *tlv = MNULL;
102 t_u16 cmd_size = 0;
103
104 ENTER();
105
106 PRINTM(MCMND, "PS Command: action = 0x%x, bitmap = 0x%x\n", cmd_action, ps_bitmap);
107
108 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
109 if (cmd_action == DIS_AUTO_PS)
110 {
111 psmode_enh->action = (ENH_PS_MODES)(wlan_cpu_to_le16(DIS_AUTO_PS));
112 psmode_enh->params.ps_bitmap = wlan_cpu_to_le16(ps_bitmap);
113 cmd->size = wlan_cpu_to_le16(S_DS_GEN + AUTO_PS_FIX_SIZE);
114 }
115 #if (CONFIG_WNM_PS)
116 else if (cmd_action == DIS_WNM_PS)
117 {
118 psmode_enh->action = (ENH_PS_MODES)(wlan_cpu_to_le16(DIS_WNM_PS));
119 psmode_enh->params.ps_bitmap = wlan_cpu_to_le16(ps_bitmap);
120 cmd->size = wlan_cpu_to_le16(S_DS_GEN + AUTO_PS_FIX_SIZE);
121 }
122 #endif
123 else if (cmd_action == GET_PS)
124 {
125 psmode_enh->action = (ENH_PS_MODES)(wlan_cpu_to_le16(GET_PS));
126 psmode_enh->params.ps_bitmap = wlan_cpu_to_le16(ps_bitmap);
127 cmd->size = wlan_cpu_to_le16(S_DS_GEN + AUTO_PS_FIX_SIZE);
128 }
129 else if (cmd_action == EXT_PS_PARAM)
130 {
131 psmode_enh->action = wlan_cpu_to_le16(EXT_PS_PARAM);
132 psmode_enh->params.ext_param.reserved = 0;
133 cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(t_u16) + sizeof(ext_ps_param));
134 psmode_enh->params.ext_param.param.header.type = wlan_cpu_to_le16(TLV_TYPE_PS_EXT_PARAM);
135 psmode_enh->params.ext_param.param.header.len = sizeof(t_u32);
136 psmode_enh->params.ext_param.param.mode = wlan_cpu_to_le32(*((t_u32 *)pdata_buf));
137 }
138 else if (cmd_action == EN_AUTO_PS)
139 {
140 psmode_enh->action = (ENH_PS_MODES)(wlan_cpu_to_le16(EN_AUTO_PS));
141 psmode_enh->params.auto_ps.ps_bitmap = wlan_cpu_to_le16(ps_bitmap);
142 cmd_size = S_DS_GEN + AUTO_PS_FIX_SIZE;
143 tlv = (t_u8 *)cmd + cmd_size;
144 if ((ps_bitmap & BITMAP_STA_PS) != 0U)
145 {
146 pmlan_adapter pmadapter = pmpriv->adapter;
147 MrvlIEtypes_ps_param_t *ps_tlv = (MrvlIEtypes_ps_param_t *)(void *)tlv;
148 ps_param *ps_mode = (ps_param *)&ps_tlv->param;
149 ps_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_PS_PARAM);
150 ps_tlv->header.len = wlan_cpu_to_le16(sizeof(MrvlIEtypes_ps_param_t) - sizeof(MrvlIEtypesHeader_t));
151 cmd_size += (t_u16)sizeof(MrvlIEtypes_ps_param_t);
152 tlv += (t_u8)sizeof(MrvlIEtypes_ps_param_t);
153 ps_mode->null_pkt_interval = wlan_cpu_to_le16(pmadapter->null_pkt_interval);
154 ps_mode->multiple_dtims = wlan_cpu_to_le16(pmadapter->multiple_dtim);
155 ps_mode->bcn_miss_timeout = wlan_cpu_to_le16(pmadapter->bcn_miss_time_out);
156 ps_mode->local_listen_interval = wlan_cpu_to_le16(pmadapter->local_listen_interval);
157 ps_mode->adhoc_wake_period = wlan_cpu_to_le16(pmadapter->adhoc_awake_period);
158 ps_mode->delay_to_ps = wlan_cpu_to_le16(pmadapter->delay_to_ps);
159 ps_mode->mode = wlan_cpu_to_le16(pmadapter->enhanced_ps_mode);
160 }
161
162 if ((ps_bitmap & BITMAP_AUTO_DS) != 0U)
163 {
164 MrvlIEtypes_auto_ds_param_t *auto_ps_tlv = (MrvlIEtypes_auto_ds_param_t *)(void *)tlv;
165 auto_ds_param *auto_ds = (auto_ds_param *)&auto_ps_tlv->param;
166 t_u16 idletime = 0;
167 auto_ps_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_AUTO_DS_PARAM);
168 auto_ps_tlv->header.len =
169 wlan_cpu_to_le16(sizeof(MrvlIEtypes_auto_ds_param_t) - sizeof(MrvlIEtypesHeader_t));
170 cmd_size += (t_u16)sizeof(MrvlIEtypes_auto_ds_param_t);
171 tlv += (t_u8)sizeof(MrvlIEtypes_auto_ds_param_t);
172 if (pdata_buf != NULL)
173 {
174 idletime = ((mlan_ds_auto_ds *)pdata_buf)->idletime;
175 }
176 auto_ds->deep_sleep_timeout = wlan_cpu_to_le16(idletime);
177 }
178
179 #if UAP_SUPPORT
180 if ((pdata_buf != MNULL) && (ps_bitmap & (BITMAP_UAP_INACT_PS | BITMAP_UAP_DTIM_PS)))
181 {
182 mlan_ds_ps_mgmt *ps_mgmt = (mlan_ds_ps_mgmt *)pdata_buf;
183 MrvlIEtypes_sleep_param_t *sleep_tlv = MNULL;
184 MrvlIEtypes_inact_sleep_param_t *inact_tlv = MNULL;
185 if ((ps_mgmt->flags & PS_FLAG_SLEEP_PARAM) != 0U)
186 {
187 sleep_tlv = (MrvlIEtypes_sleep_param_t *)(void *)tlv;
188 sleep_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_AP_SLEEP_PARAM);
189 sleep_tlv->header.len =
190 wlan_cpu_to_le16(sizeof(MrvlIEtypes_sleep_param_t) - sizeof(MrvlIEtypesHeader_t));
191 sleep_tlv->ctrl_bitmap = wlan_cpu_to_le32(ps_mgmt->sleep_param.ctrl_bitmap);
192 sleep_tlv->min_sleep = wlan_cpu_to_le32(ps_mgmt->sleep_param.min_sleep);
193 sleep_tlv->max_sleep = wlan_cpu_to_le32(ps_mgmt->sleep_param.max_sleep);
194 cmd_size += (t_u16)sizeof(MrvlIEtypes_sleep_param_t);
195 tlv += (t_u8)sizeof(MrvlIEtypes_sleep_param_t);
196 }
197 if ((ps_mgmt->flags & PS_FLAG_INACT_SLEEP_PARAM) != 0U)
198 {
199 inact_tlv = (MrvlIEtypes_inact_sleep_param_t *)(void *)tlv;
200 inact_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_AP_INACT_SLEEP_PARAM);
201 inact_tlv->header.len =
202 wlan_cpu_to_le16(sizeof(MrvlIEtypes_inact_sleep_param_t) - sizeof(MrvlIEtypesHeader_t));
203 inact_tlv->inactivity_to = wlan_cpu_to_le32(ps_mgmt->inact_param.inactivity_to);
204 inact_tlv->min_awake = wlan_cpu_to_le32(ps_mgmt->inact_param.min_awake);
205 inact_tlv->max_awake = wlan_cpu_to_le32(ps_mgmt->inact_param.max_awake);
206 cmd_size += (t_u16)sizeof(MrvlIEtypes_inact_sleep_param_t);
207 tlv += (t_u8)sizeof(MrvlIEtypes_inact_sleep_param_t);
208 }
209 }
210 #endif
211 cmd->size = wlan_cpu_to_le16(cmd_size);
212 }
213 #if (CONFIG_WNM_PS)
214 else if (cmd_action == EN_WNM_PS)
215 {
216 psmode_enh->action = wlan_cpu_to_le16(EN_WNM_PS);
217 psmode_enh->params.auto_ps.ps_bitmap = wlan_cpu_to_le16(ps_bitmap);
218 cmd_size = S_DS_GEN + AUTO_PS_FIX_SIZE;
219 tlv = (t_u8 *)cmd + cmd_size;
220 if ((ps_bitmap & BITMAP_STA_PS) != 0)
221 {
222 if (pdata_buf != NULL)
223 {
224 pmlan_adapter pmadapter = pmpriv->adapter;
225 MrvlIEtypes_wnm_ps_param_t *wnm_ps_tlv = (MrvlIEtypes_wnm_ps_param_t *)tlv;
226 wnm_ps_param *wnm_ps = (wnm_ps_param *)&wnm_ps_tlv->param;
227 t_u16 internal = 0;
228 wnm_ps_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_WNM_PARAM);
229 wnm_ps_tlv->header.len =
230 wlan_cpu_to_le16(sizeof(MrvlIEtypes_wnm_ps_param_t) - sizeof(MrvlIEtypesHeader_t));
231 cmd_size += sizeof(MrvlIEtypes_wnm_ps_param_t);
232 tlv += sizeof(MrvlIEtypes_wnm_ps_param_t);
233 internal = *(t_u32 *)pdata_buf;
234 wnm_ps->action = 0;
235 wnm_ps->null_pkt_interval = wlan_cpu_to_le16(pmadapter->null_pkt_interval);
236 wnm_ps->bcn_miss_timeout = wlan_cpu_to_le16(pmadapter->bcn_miss_time_out);
237 wnm_ps->local_listen_interval = wlan_cpu_to_le16(pmadapter->local_listen_interval);
238 wnm_ps->ps_mode = wlan_cpu_to_le16(pmadapter->enhanced_ps_mode);
239 wnm_ps->delay_to_ps = DELAY_TO_PS_WNM;
240 wnm_ps->wnm_sleep_interval = wlan_cpu_to_le16(internal);
241 }
242 }
243 cmd->size = wlan_cpu_to_le16(cmd_size);
244 }
245 #endif
246 else
247 { /* Do Nothing */
248 }
249
250 LEAVE();
251 return MLAN_STATUS_SUCCESS;
252 }
253
254 #ifdef SD8801
wlan_ret_802_11_tx_rate_query(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * resp,IN void * pioctl)255 mlan_status wlan_ret_802_11_tx_rate_query(IN pmlan_private pmpriv, IN HostCmd_DS_COMMAND *resp, IN void *pioctl)
256 {
257 mlan_adapter *pmadapter = pmpriv->adapter;
258 wifi_ds_rate *rate = MNULL;
259 ENTER();
260
261 pmpriv->tx_rate = resp->params.tx_rate.tx_rate;
262 #if CONFIG_11N
263 pmpriv->tx_htinfo = resp->params.tx_rate.ht_info;
264 #endif
265 if (!pmpriv->is_data_rate_auto)
266 {
267 #if CONFIG_11N
268 pmpriv->data_rate = wlan_index_to_data_rate(pmadapter, pmpriv->tx_rate, pmpriv->tx_htinfo);
269 #else
270 pmpriv->data_rate = wlan_index_to_data_rate(pmadapter, pmpriv->tx_rate, 0);
271 #endif
272 }
273
274 if (pioctl)
275 {
276 rate = (wifi_ds_rate *)pioctl;
277 if (rate->sub_command == WIFI_DS_RATE_CFG)
278 {
279 #if 0
280 if(rate->param.rate_cfg.rate_type == MLAN_RATE_INDEX) {
281 #endif
282 #if CONFIG_11N
283 if (pmpriv->tx_htinfo & MBIT(0))
284 rate->param.rate_cfg.rate = pmpriv->tx_rate + MLAN_RATE_INDEX_MCS0;
285 else
286 #endif
287 /* For HostCmd_CMD_802_11_TX_RATE_QUERY, there is a hole in rate table
288 * between HR/DSSS and OFDM rates, so minus 1 for OFDM rate index */
289 rate->param.rate_cfg.rate =
290 (pmpriv->tx_rate > MLAN_RATE_INDEX_OFDM0) ? pmpriv->tx_rate - 1 : pmpriv->tx_rate;
291 #if 0
292 }
293 else {
294 #if CONFIG_11N
295 rate->param.rate_cfg.rate = wlan_index_to_data_rate(pmadapter, pmpriv->tx_rate,
296 pmpriv->tx_htinfo);
297 #else
298 rate->param.rate_cfg.rate = wlan_index_to_data_rate(pmadapter, pmpriv->tx_rate, 0);
299 #endif
300 }
301 #endif
302 }
303 else if (rate->sub_command == WIFI_DS_GET_DATA_RATE)
304 {
305 #if CONFIG_11N
306 if (pmpriv->tx_htinfo & MBIT(0))
307 {
308 rate->param.data_rate.tx_data_rate = pmpriv->tx_rate + MLAN_RATE_INDEX_MCS0;
309 if (pmpriv->tx_htinfo & MBIT(1))
310 rate->param.data_rate.tx_bw = MLAN_HT_BW40;
311 else
312 rate->param.data_rate.tx_bw = MLAN_HT_BW20;
313 if (pmpriv->tx_htinfo & MBIT(2))
314 rate->param.data_rate.tx_gi = MLAN_HT_SGI;
315 else
316 rate->param.data_rate.tx_gi = MLAN_HT_LGI;
317 }
318 else
319 #endif
320 /* For HostCmd_CMD_802_11_TX_RATE_QUERY, there is a hole in rate table
321 between HR/DSSS and OFDM rates, so minus 1 for OFDM rate index */
322 rate->param.data_rate.tx_data_rate =
323 (pmpriv->tx_rate > MLAN_RATE_INDEX_OFDM0) ? pmpriv->tx_rate - 1 : pmpriv->tx_rate;
324 #if CONFIG_11N
325 if (pmpriv->rxpd_htinfo & MBIT(0))
326 {
327 rate->param.data_rate.rx_data_rate = pmpriv->rxpd_rate + MLAN_RATE_INDEX_MCS0;
328 if (pmpriv->rxpd_htinfo & MBIT(1))
329 rate->param.data_rate.rx_bw = MLAN_HT_BW40;
330 else
331 rate->param.data_rate.rx_bw = MLAN_HT_BW20;
332 if (pmpriv->rxpd_htinfo & MBIT(2))
333 rate->param.data_rate.rx_gi = MLAN_HT_SGI;
334 else
335 rate->param.data_rate.rx_gi = MLAN_HT_LGI;
336 }
337 else
338 #endif
339 /* For rate index in RxPD, there is a hole in rate table
340 between HR/DSSS and OFDM rates, so minus 1 for OFDM rate index */
341 rate->param.data_rate.rx_data_rate =
342 (pmpriv->rxpd_rate > MLAN_RATE_INDEX_OFDM0) ? pmpriv->rxpd_rate - 1 : pmpriv->rxpd_rate;
343 }
344 }
345 LEAVE();
346 return MLAN_STATUS_SUCCESS;
347 }
348 #else
349 /**
350 * @brief This function handles the command response of tx rate query
351 *
352 * @param pmpriv A pointer to mlan_private structure
353 * @param resp A pointer to HostCmd_DS_COMMAND
354 * @param pioctl_buf A pointer to mlan_ioctl_req structure
355 *
356 * @return MLAN_STATUS_SUCCESS
357 */
wlan_ret_802_11_tx_rate_query(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * resp,IN void * pioctl)358 mlan_status wlan_ret_802_11_tx_rate_query(IN pmlan_private pmpriv, IN HostCmd_DS_COMMAND *resp, IN void *pioctl)
359 {
360 mlan_adapter *pmadapter = pmpriv->adapter;
361 wifi_ds_rate *rate = MNULL;
362 ENTER();
363
364 pmpriv->tx_rate = resp->params.tx_rate.tx_rate;
365 pmpriv->tx_rate_info = resp->params.tx_rate.tx_rate_info;
366
367 #if CONFIG_11AX
368 if ((mlan_rate_format)(pmpriv->tx_rate_info & 0x3U) == MLAN_RATE_FORMAT_HE)
369 pmpriv->ext_tx_rate_info = resp->params.tx_rate.ext_tx_rate_info;
370 #endif
371
372 if (!pmpriv->is_data_rate_auto)
373 {
374 pmpriv->data_rate = wlan_index_to_data_rate(pmadapter, pmpriv->tx_rate, pmpriv->tx_rate_info
375 #if CONFIG_11AX
376 ,
377 pmpriv->ext_tx_rate_info
378 #endif
379 );
380 }
381
382 if (pioctl != NULL)
383 {
384 rate = (wifi_ds_rate *)pioctl;
385 if (rate->sub_command == WIFI_DS_RATE_CFG)
386 {
387 #if 0
388 if(rate->param.rate_cfg.rate_type == MLAN_RATE_INDEX) {
389 #endif
390 #if CONFIG_11AC
391 if ((mlan_rate_format)(pmpriv->tx_rate_info & 0x3U) == MLAN_RATE_FORMAT_VHT
392 #if CONFIG_11AX
393 || ((mlan_rate_format)(pmpriv->tx_rate_info & 0x3U) == MLAN_RATE_FORMAT_HE)
394 #endif
395 )
396 {
397 /* VHT rate */
398 rate->param.rate_cfg.rate = (t_u32)((pmpriv->tx_rate) & 0xF);
399 }
400 else
401 #endif
402 #if CONFIG_11N
403 if ((mlan_rate_format)(pmpriv->tx_rate_info & 0x3U) == MLAN_RATE_FORMAT_HT)
404 {
405 /* HT rate */
406 rate->param.rate_cfg.rate = pmpriv->tx_rate + MLAN_RATE_INDEX_MCS0;
407 }
408 else
409 #endif
410 {
411 /* LG rate */
412 /* For HostCmd_CMD_802_11_TX_RATE_QUERY,
413 * there is a hole (0x4) in rate table
414 * between HR/DSSS and OFDM rates,
415 * so minus 1 for OFDM rate index */
416 rate->param.rate_cfg.rate =
417 (pmpriv->tx_rate > MLAN_RATE_INDEX_OFDM0) ? pmpriv->tx_rate - 1U : pmpriv->tx_rate;
418 }
419 #if 0
420 }
421 else {
422 /* rate_type = MLAN_RATE_VALUE */
423 rate->param.rate_cfg.rate = wlan_index_to_data_rate(pmadapter,
424 pmpriv->tx_rate,
425 pmpriv->tx_rate_info);
426 }
427 #endif
428 }
429 else if (rate->sub_command == WIFI_DS_GET_DATA_RATE)
430 {
431 /* Tx rate info */
432 #if CONFIG_11AC
433 if ((mlan_rate_format)(pmpriv->tx_rate_info & 0x3U) == MLAN_RATE_FORMAT_VHT
434 #if CONFIG_11AX
435 || (mlan_rate_format)(pmpriv->tx_rate_info & 0x3U) == MLAN_RATE_FORMAT_HE
436 #endif
437 )
438 {
439 /* VHT/HE rate */
440 rate->param.data_rate.tx_rate_format = (mlan_rate_format)(pmpriv->tx_rate_info & 0x3U);
441 rate->param.data_rate.tx_bw = (t_u32)((pmpriv->tx_rate_info & 0xC) >> 2);
442
443 #if CONFIG_11AX
444 if ((mlan_rate_format)(pmpriv->tx_rate_info & 0x3U) == MLAN_RATE_FORMAT_HE)
445 rate->param.data_rate.tx_gi =
446 (pmpriv->tx_rate_info & 0x10) >> 4 | (pmpriv->tx_rate_info & 0x80) >> 6;
447 else
448 #endif
449 rate->param.data_rate.tx_gi = (t_u32)((pmpriv->tx_rate_info & 0x10) >> 4);
450 rate->param.data_rate.tx_nss = ((pmpriv->tx_rate) >> 4) & 0x03;
451 rate->param.data_rate.tx_mcs_index = (t_u32)((pmpriv->tx_rate) & 0xF);
452 rate->param.data_rate.tx_data_rate =
453 wlan_index_to_data_rate(pmadapter, pmpriv->tx_rate, pmpriv->tx_rate_info
454 #if CONFIG_11AX
455 ,
456 pmpriv->ext_tx_rate_info
457 #endif
458 );
459 }
460 else
461 #endif
462 #if CONFIG_11N
463 if ((mlan_rate_format)(pmpriv->tx_rate_info & 0x3U) == MLAN_RATE_FORMAT_HT)
464 {
465 /* HT rate */
466 rate->param.data_rate.tx_rate_format = MLAN_RATE_FORMAT_HT;
467 rate->param.data_rate.tx_bw = (pmpriv->tx_rate_info & 0xCU) >> 2U;
468 rate->param.data_rate.tx_gi = (pmpriv->tx_rate_info & 0x10U) >> 4U;
469 rate->param.data_rate.tx_mcs_index = pmpriv->tx_rate;
470 rate->param.data_rate.tx_data_rate =
471 wlan_index_to_data_rate(pmadapter, pmpriv->tx_rate, pmpriv->tx_rate_info
472 #if CONFIG_11AX
473 ,
474 pmpriv->ext_tx_rate_info
475 #endif
476 );
477 }
478 else
479 #endif
480 {
481 /* LG rate */
482 rate->param.data_rate.tx_rate_format = MLAN_RATE_FORMAT_LG;
483 /* For HostCmd_CMD_802_11_TX_RATE_QUERY,
484 * there is a hole in rate table
485 * between HR/DSSS and OFDM rates,
486 * so minus 1 for OFDM rate index */
487 rate->param.data_rate.tx_data_rate =
488 (pmpriv->tx_rate > MLAN_RATE_INDEX_OFDM0) ? pmpriv->tx_rate - 1U : pmpriv->tx_rate;
489 }
490
491 /* Rx rate info */
492 #if CONFIG_11AC
493 if ((mlan_rate_format)(pmpriv->rxpd_rate_info & 0x3U) == MLAN_RATE_FORMAT_VHT
494 #if CONFIG_11AX
495 || (pmpriv->rxpd_rate_info & 0x3) == MLAN_RATE_FORMAT_HE
496 #endif
497 )
498 {
499 /* VHT/HE rate */
500 rate->param.data_rate.rx_rate_format = (mlan_rate_format)(pmpriv->rxpd_rate_info & 0x3);
501 rate->param.data_rate.rx_bw = (t_u32)((pmpriv->rxpd_rate_info & 0xC) >> 2);
502
503 #if CONFIG_11AX
504 if ((pmpriv->rxpd_rate_info & 0x3) == MLAN_RATE_FORMAT_HE)
505 rate->param.data_rate.rx_gi =
506 (pmpriv->rxpd_rate_info & 0x10) >> 4 | (pmpriv->rxpd_rate_info & 0x80) >> 6;
507 else
508 #endif
509 rate->param.data_rate.rx_gi = (t_u32)((pmpriv->rxpd_rate_info & 0x10) >> 4);
510 rate->param.data_rate.rx_nss = ((pmpriv->rxpd_rate) >> 4) & 0x3;
511 rate->param.data_rate.rx_mcs_index = (t_u32)((pmpriv->rxpd_rate) & 0xF);
512 rate->param.data_rate.rx_data_rate =
513 wlan_index_to_data_rate(pmadapter, pmpriv->rxpd_rate, pmpriv->rxpd_rate_info
514 #if CONFIG_11AX
515 ,
516 pmpriv->ext_tx_rate_info
517 #endif
518 );
519 }
520 else
521 #endif
522 #if CONFIG_11N
523 if ((pmpriv->rxpd_rate_info & 0x3) == MLAN_RATE_FORMAT_HT)
524 {
525 /* HT rate */
526 rate->param.data_rate.rx_rate_format = MLAN_RATE_FORMAT_HT;
527 rate->param.data_rate.rx_bw = (pmpriv->rxpd_rate_info & 0xCU) >> 2U;
528 rate->param.data_rate.rx_gi = (pmpriv->rxpd_rate_info & 0x10U) >> 4U;
529 rate->param.data_rate.rx_mcs_index = pmpriv->rxpd_rate;
530 rate->param.data_rate.rx_data_rate =
531 wlan_index_to_data_rate(pmadapter, pmpriv->rxpd_rate, pmpriv->rxpd_rate_info
532 #if CONFIG_11AX
533 ,
534 pmpriv->ext_tx_rate_info
535 #endif
536 );
537 }
538 else
539 #endif
540 {
541 /* LG rate */
542 rate->param.data_rate.rx_rate_format = MLAN_RATE_FORMAT_LG;
543 /* For rate index in RxPD,
544 * there is a hole in rate table
545 * between HR/DSSS and OFDM rates,
546 * so minus 1 for OFDM rate index */
547 rate->param.data_rate.rx_data_rate =
548 (t_u32)((pmpriv->rxpd_rate > MLAN_RATE_INDEX_OFDM0) ? pmpriv->rxpd_rate - 1 : pmpriv->rxpd_rate);
549 }
550 }
551 else
552 { /* Do Nothing */
553 }
554 }
555 LEAVE();
556 return MLAN_STATUS_SUCCESS;
557 }
558 #endif
559
560 /**
561 * @brief This function prepares command of tx_rate_cfg.
562 *
563 * @param pmpriv A pointer to mlan_private structure
564 * @param cmd A pointer to HostCmd_DS_COMMAND structure
565 * @param cmd_action The action: GET or SET
566 * @param pdata_buf A pointer to data buffer
567 *
568 * @return MLAN_STATUS_SUCCESS
569 */
wlan_cmd_tx_rate_cfg(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_u16 cmd_action,IN t_void * pdata_buf,IN mlan_ioctl_req * pioctl_buf)570 mlan_status wlan_cmd_tx_rate_cfg(IN pmlan_private pmpriv,
571 IN HostCmd_DS_COMMAND *cmd,
572 IN t_u16 cmd_action,
573 IN t_void *pdata_buf,
574 IN mlan_ioctl_req *pioctl_buf)
575 {
576 HostCmd_DS_TX_RATE_CFG *rate_cfg = (HostCmd_DS_TX_RATE_CFG *)&cmd->params.tx_rate_cfg;
577 MrvlRateScope_t *rate_scope;
578 MrvlRateDropPattern_t *rate_drop;
579 MrvlIETypes_rate_setting_t *rate_setting_tlv;
580 mlan_ds_rate *ds_rate = MNULL;
581 t_u16 *pbitmap_rates = (t_u16 *)pdata_buf;
582
583 t_u32 i;
584
585 ENTER();
586
587 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_TX_RATE_CFG);
588
589 rate_cfg->action = wlan_cpu_to_le16(cmd_action);
590 rate_cfg->cfg_index = 0;
591
592 rate_scope = (MrvlRateScope_t *)(void *)((t_u8 *)rate_cfg + sizeof(HostCmd_DS_TX_RATE_CFG));
593 // coverity[overrun-local:SUPPRESS]
594 rate_scope->type = wlan_cpu_to_le16(TLV_TYPE_RATE_SCOPE);
595 rate_scope->length = wlan_cpu_to_le16(sizeof(MrvlRateScope_t) - sizeof(MrvlIEtypesHeader_t));
596 if (pbitmap_rates != MNULL)
597 {
598 rate_scope->hr_dsss_rate_bitmap = wlan_cpu_to_le16(pbitmap_rates[0]);
599 rate_scope->ofdm_rate_bitmap = wlan_cpu_to_le16(pbitmap_rates[1]);
600 for (i = 0; i < NELEMENTS(rate_scope->ht_mcs_rate_bitmap); i++)
601 {
602 rate_scope->ht_mcs_rate_bitmap[i] = wlan_cpu_to_le16(pbitmap_rates[2U + i]);
603 }
604 #if CONFIG_11AC
605 for (i = 0; i < NELEMENTS(rate_scope->vht_mcs_rate_bitmap); i++)
606 {
607 rate_scope->vht_mcs_rate_bitmap[i] =
608 wlan_cpu_to_le16(pbitmap_rates[2U + NELEMENTS(rate_scope->ht_mcs_rate_bitmap) + i]);
609 }
610 #endif
611 #if CONFIG_11AX
612 if (IS_FW_SUPPORT_11AX(pmpriv->adapter))
613 {
614 for (i = 0; i < NELEMENTS(rate_scope->he_mcs_rate_bitmap); i++)
615 rate_scope->he_mcs_rate_bitmap[i] =
616 wlan_cpu_to_le16(pbitmap_rates[2U + wlan_get_bitmap_index(rate_scope) + i]);
617 }
618 else
619 {
620 rate_scope->length = wlan_cpu_to_le16(sizeof(MrvlRateScope_t) - sizeof(rate_scope->he_mcs_rate_bitmap) -
621 sizeof(MrvlIEtypesHeader_t));
622 }
623 #endif
624 }
625 else
626 {
627 rate_scope->hr_dsss_rate_bitmap = wlan_cpu_to_le16(pmpriv->bitmap_rates[0]);
628 rate_scope->ofdm_rate_bitmap = wlan_cpu_to_le16(pmpriv->bitmap_rates[1]);
629 for (i = 0; i < NELEMENTS(rate_scope->ht_mcs_rate_bitmap); i++)
630 {
631 rate_scope->ht_mcs_rate_bitmap[i] = wlan_cpu_to_le16(pmpriv->bitmap_rates[2U + i]);
632 }
633 #if CONFIG_11AC
634 for (i = 0; i < NELEMENTS(rate_scope->vht_mcs_rate_bitmap); i++)
635 {
636 rate_scope->vht_mcs_rate_bitmap[i] =
637 wlan_cpu_to_le16(pmpriv->bitmap_rates[2U + NELEMENTS(rate_scope->ht_mcs_rate_bitmap) + i]);
638 }
639 #endif
640 #if CONFIG_11AX
641 if (IS_FW_SUPPORT_11AX(pmpriv->adapter))
642 {
643 for (i = 0; i < NELEMENTS(rate_scope->he_mcs_rate_bitmap); i++)
644 rate_scope->he_mcs_rate_bitmap[i] =
645 wlan_cpu_to_le16(pmpriv->bitmap_rates[2U + wlan_get_bitmap_index(rate_scope) + i]);
646 }
647 else
648 {
649 rate_scope->length = wlan_cpu_to_le16(sizeof(MrvlRateScope_t) - sizeof(rate_scope->he_mcs_rate_bitmap) -
650 sizeof(MrvlIEtypesHeader_t));
651 }
652 #endif
653 }
654
655 rate_drop = (MrvlRateDropPattern_t *)(void *)((t_u8 *)rate_scope + sizeof(MrvlRateScope_t));
656 rate_drop->type = wlan_cpu_to_le16(TLV_TYPE_RATE_DROP_PATTERN);
657 rate_drop->length = wlan_cpu_to_le16(sizeof(rate_drop->rate_drop_mode));
658 rate_drop->rate_drop_mode = 0;
659
660 cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_TX_RATE_CFG) + sizeof(MrvlRateScope_t) +
661 sizeof(MrvlRateDropPattern_t));
662
663 if (pioctl_buf)
664 {
665 ds_rate = (mlan_ds_rate *)pioctl_buf->pbuf;
666 rate_setting_tlv = (MrvlIETypes_rate_setting_t *)((t_u8 *)rate_drop + sizeof(MrvlRateDropPattern_t));
667 rate_setting_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_TX_RATE_CFG);
668 rate_setting_tlv->header.len = wlan_cpu_to_le16(sizeof(rate_setting_tlv->rate_setting));
669 rate_setting_tlv->rate_setting = wlan_cpu_to_le16(ds_rate->param.rate_cfg.rate_setting);
670 PRINTM(MCMND, "he rate setting = %d\n", rate_setting_tlv->rate_setting);
671 cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_TX_RATE_CFG) + sizeof(MrvlRateScope_t) +
672 sizeof(MrvlRateDropPattern_t) + sizeof(MrvlIETypes_rate_setting_t));
673 }
674
675 LEAVE();
676 return MLAN_STATUS_SUCCESS;
677 }
678
679 /**
680 * @brief This function handles the command response of tx_rate_cfg
681 *
682 * @param pmpriv A pointer to mlan_private structure
683 * @param resp A pointer to HostCmd_DS_COMMAND
684 * @param pioctl_buf A pointer to mlan_ioctl_req structure
685 *
686 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
687 */
wlan_ret_tx_rate_cfg(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * resp,IN void * pioctl)688 mlan_status wlan_ret_tx_rate_cfg(IN pmlan_private pmpriv, IN HostCmd_DS_COMMAND *resp, IN void *pioctl)
689 {
690 mlan_adapter *pmadapter = pmpriv->adapter;
691 wifi_ds_rate *ds_rate = MNULL;
692 HostCmd_DS_TX_RATE_CFG *prate_cfg = MNULL;
693 MrvlRateScope_t *prate_scope;
694 MrvlIEtypesHeader_t *head = MNULL;
695 t_u16 tlv;
696 t_u16 tlv_buf_len = 0;
697 t_u8 *tlv_buf;
698 t_u32 i;
699 t_s32 index;
700 mlan_status ret = MLAN_STATUS_SUCCESS;
701 MrvlIETypes_rate_setting_t *rate_setting_tlv = MNULL;
702 t_u16 rate_setting = 0xffff;
703
704 ENTER();
705
706 if (resp == MNULL)
707 {
708 LEAVE();
709 return MLAN_STATUS_FAILURE;
710 }
711 prate_cfg = (HostCmd_DS_TX_RATE_CFG *)&(resp->params.tx_rate_cfg);
712
713 tlv_buf = (t_u8 *)((t_u8 *)prate_cfg) + sizeof(HostCmd_DS_TX_RATE_CFG);
714 if (tlv_buf != NULL)
715 {
716 tlv_buf_len = resp->size - (sizeof(HostCmd_DS_TX_RATE_CFG) + S_DS_GEN);
717 tlv_buf_len = wlan_le16_to_cpu(tlv_buf_len);
718 }
719
720 while (tlv_buf_len > 0U)
721 {
722 // coverity[overrun-local:SUPPRESS]
723 tlv = (t_u16)(*tlv_buf);
724 tlv = tlv | (*(tlv_buf + 1) << 8);
725
726 switch (tlv)
727 {
728 case TLV_TYPE_RATE_SCOPE:
729 prate_scope = (MrvlRateScope_t *)(void *)tlv_buf;
730 pmpriv->bitmap_rates[0] = wlan_le16_to_cpu(prate_scope->hr_dsss_rate_bitmap);
731 pmpriv->bitmap_rates[1] = wlan_le16_to_cpu(prate_scope->ofdm_rate_bitmap);
732 for (i = 0; i < sizeof(prate_scope->ht_mcs_rate_bitmap) / sizeof(t_u16); i++)
733 {
734 pmpriv->bitmap_rates[2U + i] = wlan_le16_to_cpu(prate_scope->ht_mcs_rate_bitmap[i]);
735 }
736 #if CONFIG_11AC
737 for (i = 0; i < NELEMENTS(prate_scope->vht_mcs_rate_bitmap); i++)
738 {
739 pmpriv->bitmap_rates[2 + sizeof(prate_scope->ht_mcs_rate_bitmap) / sizeof(t_u16) + i] =
740 wlan_le16_to_cpu(prate_scope->vht_mcs_rate_bitmap[i]);
741 }
742
743 #endif
744 #if CONFIG_11AX
745 if (IS_FW_SUPPORT_11AX(pmadapter))
746 {
747 for (i = 0; i < NELEMENTS(prate_scope->he_mcs_rate_bitmap); i++)
748 {
749 pmpriv->bitmap_rates[2 + sizeof(prate_scope->ht_mcs_rate_bitmap) / sizeof(t_u16) +
750 sizeof(prate_scope->vht_mcs_rate_bitmap) / sizeof(t_u16) + i] =
751 wlan_le16_to_cpu(prate_scope->he_mcs_rate_bitmap[i]);
752 }
753 }
754 #endif
755 break;
756 case TLV_TYPE_TX_RATE_CFG:
757 rate_setting_tlv = (MrvlIETypes_rate_setting_t *)tlv_buf;
758 rate_setting = rate_setting_tlv->rate_setting;
759 break;
760 /* Add RATE_DROP tlv here */
761 default:
762 PRINTM(MINFO, "Unexpected TLV for rate cfg \n");
763 break;
764 }
765
766 head = (MrvlIEtypesHeader_t *)(void *)tlv_buf;
767 head->len = wlan_le16_to_cpu(head->len);
768 tlv_buf += head->len + sizeof(MrvlIEtypesHeader_t);
769 tlv_buf_len -= (head->len + sizeof(MrvlIEtypesHeader_t));
770 }
771
772 pmpriv->is_data_rate_auto = wlan_is_rate_auto(pmpriv);
773
774 if (pmpriv->is_data_rate_auto != 0U)
775 {
776 pmpriv->data_rate = 0;
777 PRINTM(MINFO, "Rate is Auto\r\n");
778 }
779
780 if (pioctl != NULL)
781 {
782 ds_rate = (wifi_ds_rate *)pioctl;
783 if (ds_rate == MNULL)
784 {
785 PRINTM(MERROR, "Request buffer not found!\n");
786 LEAVE();
787 return MLAN_STATUS_FAILURE;
788 }
789 if (pmpriv->is_data_rate_auto != 0U)
790 {
791 // ds_rate->param.rate_cfg.is_rate_auto = MTRUE;
792 ds_rate->param.rate_cfg.rate_format = MLAN_RATE_FORMAT_AUTO;
793 }
794 else
795 {
796 /* check the LG rate */
797 index = wlan_get_rate_index(pmadapter, &pmpriv->bitmap_rates[0], 4);
798 if (index != -1)
799 {
800 if ((index >= MLAN_RATE_BITMAP_OFDM0) && (index <= MLAN_RATE_BITMAP_OFDM7))
801 {
802 index -= (MLAN_RATE_BITMAP_OFDM0 - MLAN_RATE_INDEX_OFDM0);
803 }
804
805 ds_rate->param.rate_cfg.rate_format = MLAN_RATE_FORMAT_LG;
806 ds_rate->param.rate_cfg.rate = (t_u32)index;
807 }
808 /* check the HT rate */
809 index = wlan_get_rate_index(pmadapter, &pmpriv->bitmap_rates[2], 16);
810 if (index != -1)
811 {
812 ds_rate->param.rate_cfg.rate_format = MLAN_RATE_FORMAT_HT;
813 ds_rate->param.rate_cfg.rate = (t_u32)index;
814 }
815
816 #if CONFIG_11AC
817 /* check the VHT rate */
818 index = wlan_get_rate_index(pmadapter, &pmpriv->bitmap_rates[10], 16);
819
820 if (index != -1)
821 {
822 ds_rate->param.rate_cfg.rate_format = MLAN_RATE_FORMAT_VHT;
823 ds_rate->param.rate_cfg.rate = (t_u32)(index % 16);
824 ds_rate->param.rate_cfg.nss = (t_u32)(index / 16);
825 ds_rate->param.rate_cfg.nss += MLAN_RATE_NSS1;
826 }
827 #endif
828 #if CONFIG_11AX
829 /* check the HE rate */
830 if (IS_FW_SUPPORT_11AX(pmadapter))
831 {
832 index = wlan_get_rate_index(pmadapter, &pmpriv->bitmap_rates[18], 16);
833 if (index != -1)
834 {
835 ds_rate->param.rate_cfg.rate_format = MLAN_RATE_FORMAT_HE;
836 ds_rate->param.rate_cfg.rate = index % 16;
837 ds_rate->param.rate_cfg.nss = index / 16;
838 ds_rate->param.rate_cfg.nss += MLAN_RATE_NSS1;
839 }
840 }
841 #endif
842 ds_rate->param.rate_cfg.rate_setting = rate_setting;
843 PRINTM(MINFO, "Rate index is %d\n", ds_rate->param.rate_cfg.rate);
844
845 ds_rate->param.rate_cfg.rate_index = ds_rate->param.rate_cfg.rate;
846 }
847 }
848
849 LEAVE();
850 return ret;
851 }
852
853 /**
854 * @brief This function prepares command of get_hw_spec.
855 *
856 * @param pmpriv A pointer to mlan_private structure
857 * @param pcmd A pointer to HostCmd_DS_COMMAND structure
858 *
859 * @return MLAN_STATUS_SUCCESS
860 */
wlan_cmd_get_hw_spec(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * pcmd)861 mlan_status wlan_cmd_get_hw_spec(IN pmlan_private pmpriv, IN HostCmd_DS_COMMAND *pcmd)
862 {
863 HostCmd_DS_GET_HW_SPEC *hw_spec = &pcmd->params.hw_spec;
864
865 ENTER();
866
867 pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_GET_HW_SPEC);
868 pcmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_GET_HW_SPEC) + S_DS_GEN);
869 (void)__memcpy(pmpriv->adapter, hw_spec->permanent_addr, pmpriv->curr_addr, MLAN_MAC_ADDR_LENGTH);
870
871 LEAVE();
872 return MLAN_STATUS_SUCCESS;
873 }
874
875 /**
876 * @brief This function prepares command of HostCmd_CMD_GET_TSF
877 *
878 * @param pmpriv A pointer to mlan_private structure
879 * @param cmd A pointer to HostCmd_DS_COMMAND structure
880 * @param cmd_action The action: GET
881 * @return MLAN_STATUS_SUCCESS
882 */
wlan_cmd_get_tsf(pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_u16 cmd_action)883 mlan_status wlan_cmd_get_tsf(pmlan_private pmpriv, IN HostCmd_DS_COMMAND *cmd, IN t_u16 cmd_action)
884 {
885 ENTER();
886
887 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_GET_TSF);
888 cmd->size = wlan_cpu_to_le16((sizeof(HostCmd_DS_TSF)) + S_DS_GEN);
889
890 LEAVE();
891 return MLAN_STATUS_SUCCESS;
892 }
893
894 #if (CONFIG_WIFI_TX_PER_TRACK) || (CONFIG_TX_RX_HISTOGRAM)
895 /**
896 * @brief This function prepares command of txrx_histogram and tx_pert, distinguish by cmd_action.
897 *
898 * @param pmpriv A pointer to mlan_private structure
899 * @param cmd A pointer to HostCmd_DS_COMMAND structure
900 * @param cmd_action The action: GET or SET
901 * @param pdata_buf A pointer to data buffer
902 *
903 * @return MLAN_STATUS_SUCCESS
904 */
wlan_cmd_txrx_pkt_stats(pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_u16 cmd_action,IN t_void * pdata_buf)905 mlan_status wlan_cmd_txrx_pkt_stats(pmlan_private pmpriv,
906 IN HostCmd_DS_COMMAND *cmd,
907 IN t_u16 cmd_action,
908 IN t_void *pdata_buf)
909 {
910 #if CONFIG_WIFI_TX_PER_TRACK
911 if (cmd_action == HostCmd_ACT_SET_TX_PER_TRACKING)
912 {
913 wlan_cmd_tx_pert(pmpriv, cmd, cmd_action, pdata_buf);
914 }
915 #endif
916 #if CONFIG_TX_RX_HISTOGRAM
917 if (cmd_action != HostCmd_ACT_SET_TX_PER_TRACKING)
918 {
919 wlan_cmd_txrx_histogram(pmpriv, cmd, pdata_buf);
920 }
921 #endif
922 return MLAN_STATUS_SUCCESS;
923 }
924 #endif
925
926 #if CONFIG_WIFI_TX_PER_TRACK
927 /**
928 * @brief This function prepares command of tx_pert.
929 *
930 * @param pmpriv A pointer to mlan_private structure
931 * @param cmd A pointer to HostCmd_DS_COMMAND structure
932 * @param cmd_action The action: GET or SET
933 * @param pdata_buf A pointer to data buffer
934 *
935 * @return MLAN_STATUS_SUCCESS
936 */
wlan_cmd_tx_pert(pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_u16 cmd_action,IN t_void * pdata_buf)937 mlan_status wlan_cmd_tx_pert(pmlan_private pmpriv,
938 IN HostCmd_DS_COMMAND *cmd,
939 IN t_u16 cmd_action,
940 IN t_void *pdata_buf)
941 {
942 HostCmd_DS_TX_RX_PKT_STATS *pkt_stats = &cmd->params.pkt_stats;
943 MrvlTxPerTrackInfo_t *tx_pert = NULL;
944 tx_pert_info *cfg = (tx_pert_info *)pdata_buf;
945
946 ENTER();
947 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_TX_RX_PKT_STATS);
948 pkt_stats->action = wlan_cpu_to_le16(cmd_action);
949 pkt_stats->enable = cfg->tx_pert_check;
950 if (cmd_action == HostCmd_ACT_SET_TX_PER_TRACKING)
951 {
952 tx_pert = (MrvlTxPerTrackInfo_t *)((t_u8 *)pkt_stats + sizeof(HostCmd_DS_TX_RX_PKT_STATS));
953 // coverity[overrun-local:SUPPRESS]
954 tx_pert->type = wlan_cpu_to_le16(TLV_TYPE_TX_PER_TRACK);
955 tx_pert->length = wlan_cpu_to_le16(sizeof(MrvlTxPerTrackInfo_t) - sizeof(MrvlIEtypesHeader_t));
956 tx_pert->tx_stat_check_period = cfg->tx_pert_check_peroid;
957 tx_pert->tx_stat_check_ratio = cfg->tx_pert_check_ratio;
958 tx_pert->tx_stat_check_num = wlan_cpu_to_le16(cfg->tx_pert_check_num);
959 }
960 cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_TX_RX_PKT_STATS) + sizeof(MrvlTxPerTrackInfo_t));
961
962 LEAVE();
963 return MLAN_STATUS_SUCCESS;
964 }
965 #endif
966
967 #if CONFIG_TX_RX_HISTOGRAM
968 /**
969 * @brief This function prepares command of txrx_histogram.
970 *
971 * @param pmpriv A pointer to mlan_private structure
972 * @param cmd A pointer to HostCmd_DS_COMMAND structure
973 * @param cmd_action The action: GET or SET
974 * @param pdata_buf A pointer to data buffer
975 *
976 * @return MLAN_STATUS_SUCCESS
977 */
wlan_cmd_txrx_histogram(pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_void * pdata_buf)978 mlan_status wlan_cmd_txrx_histogram(pmlan_private pmpriv, IN HostCmd_DS_COMMAND *cmd, IN t_void *pdata_buf)
979 {
980 HostCmd_DS_TX_RX_HISTOGRAM *histogram = &cmd->params.histogram;
981 txrx_histogram_info *cfg = (txrx_histogram_info *)pdata_buf;
982
983 ENTER();
984 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_TX_RX_PKT_STATS);
985 histogram->action = cfg->action;
986 histogram->enable = cfg->enable;
987 cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_TX_RX_HISTOGRAM));
988
989 LEAVE();
990 return MLAN_STATUS_SUCCESS;
991 }
992 #endif
993
994 /** * @brief This function gets the no 5G status
995 *
996 * @param pmpriv A pointer to mlan_private structure
997 * @param resp A pointer to HostCmd_DS_COMMAND
998 *
999 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1000 */
wlan_get_no_5G_status(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp)1001 static mlan_status wlan_get_no_5G_status(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp)
1002 {
1003 mlan_adapter *pmadapter = pmpriv->adapter;
1004 t_u16 left_len;
1005 t_u16 tlv_type = 0;
1006 t_u16 tlv_len = 0;
1007 MrvlIEtypesHeader_t *tlv = MNULL;
1008 MrvlIEtypes_fw_cap_info_t *fw_cap_tlv = MNULL;
1009
1010 left_len = resp->size - sizeof(HostCmd_DS_GET_HW_SPEC) - S_DS_GEN;
1011 tlv = (MrvlIEtypesHeader_t *)((t_u8 *)resp + S_DS_GEN + sizeof(HostCmd_DS_GET_HW_SPEC));
1012 while (left_len > sizeof(MrvlIEtypesHeader_t))
1013 {
1014 tlv_type = wlan_le16_to_cpu(tlv->type);
1015 tlv_len = wlan_le16_to_cpu(tlv->len);
1016 if (tlv_type == TLV_TYPE_FW_CAP_INFO)
1017 {
1018 fw_cap_tlv = (MrvlIEtypes_fw_cap_info_t *)tlv;
1019 pmadapter->fw_cap_ext = wlan_le32_to_cpu(fw_cap_tlv->fw_cap_ext);
1020 break;
1021 }
1022 left_len -= (sizeof(MrvlIEtypesHeader_t) + tlv_len);
1023 tlv = (MrvlIEtypesHeader_t *)((t_u8 *)tlv + tlv_len + sizeof(MrvlIEtypesHeader_t));
1024 }
1025
1026 return MLAN_STATUS_SUCCESS;
1027 }
1028
1029 /**
1030 * @brief This function handles the command response of get_hw_spec
1031 *
1032 * @param pmpriv A pointer to mlan_private structure
1033 * @param resp A pointer to HostCmd_DS_COMMAND
1034 * @param pioctl_buf A pointer to command buffer
1035 *
1036 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1037 */
wlan_ret_get_hw_spec(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * resp,IN t_void * pioctl_buf)1038 mlan_status wlan_ret_get_hw_spec(IN pmlan_private pmpriv, IN HostCmd_DS_COMMAND *resp, IN t_void *pioctl_buf)
1039 {
1040 HostCmd_DS_GET_HW_SPEC *hw_spec = &resp->params.hw_spec;
1041 mlan_adapter *pmadapter = pmpriv->adapter;
1042 mlan_status ret = MLAN_STATUS_SUCCESS;
1043 t_u32 i;
1044 pmlan_ioctl_req pioctl_req = (mlan_ioctl_req *)pioctl_buf;
1045 t_u16 left_len;
1046 t_u16 tlv_type = 0;
1047 t_u16 tlv_len = 0;
1048 MrvlIEtypesHeader_t *tlv = MNULL;
1049 #if CONFIG_11AX
1050 MrvlIEtypes_Extension_t *ext_tlv = MNULL;
1051 #ifdef RW610
1052 int he_tlv_idx = 0;
1053 #endif
1054 #endif
1055 MrvlIEtypes_fw_cap_info_t *fw_cap_tlv = MNULL;
1056 ENTER();
1057
1058 pmadapter->fw_cap_info = wlan_le32_to_cpu(hw_spec->fw_cap_info);
1059 /* Get no 5G status to check whether need to disable 5G */
1060 wlan_get_no_5G_status(pmpriv, resp);
1061 #ifdef STA_SUPPORT
1062 if ((IS_SUPPORT_MULTI_BANDS(pmadapter)) != 0U)
1063 {
1064 pmadapter->fw_bands = (t_u16)GET_FW_DEFAULT_BANDS(pmadapter);
1065 if (ISSUPP_NO5G(pmadapter->fw_cap_ext))
1066 {
1067 pmadapter->fw_bands &= ~(BAND_A | BAND_AN | BAND_AAC);
1068 }
1069 #if !CONFIG_5GHz_SUPPORT
1070 /* fixme: Re-check if this is the correct way to disable 5 GHz. */
1071 pmadapter->fw_bands &= ~(BAND_A | BAND_AN | BAND_AAC);
1072 #endif /* CONFIG_5GHz_SUPPORT */
1073 }
1074 else
1075 {
1076 pmadapter->fw_bands = BAND_B;
1077 }
1078
1079 pmadapter->config_bands = pmadapter->fw_bands;
1080 for (i = 0; i < pmadapter->priv_num; i++)
1081 {
1082 if (pmadapter->priv[i] != MNULL)
1083 {
1084 pmadapter->priv[i]->config_bands = pmadapter->fw_bands;
1085 }
1086 }
1087
1088 if ((pmadapter->fw_bands & BAND_A) != 0U)
1089 {
1090 if ((pmadapter->fw_bands & BAND_GN) != 0U)
1091 {
1092 pmadapter->config_bands |= BAND_AN;
1093 for (i = 0; i < pmadapter->priv_num; i++)
1094 {
1095 if (pmadapter->priv[i] != MNULL)
1096 {
1097 pmadapter->priv[i]->config_bands |= BAND_AN;
1098 }
1099 }
1100
1101 pmadapter->fw_bands |= BAND_AN;
1102 }
1103 if ((pmadapter->fw_bands & BAND_AAC) != 0U)
1104 {
1105 pmadapter->config_bands |= BAND_AAC;
1106 for (i = 0; i < pmadapter->priv_num; i++)
1107 {
1108 if (pmadapter->priv[i] != MNULL)
1109 {
1110 pmadapter->priv[i]->config_bands |= BAND_AAC;
1111 }
1112 }
1113 }
1114 if ((pmadapter->fw_bands & BAND_AN) != 0U)
1115 {
1116 pmadapter->adhoc_start_band = (BAND_A | BAND_AN);
1117 pmadapter->adhoc_11n_enabled = MTRUE;
1118 }
1119 else
1120 {
1121 pmadapter->adhoc_start_band = BAND_A;
1122 }
1123 pmpriv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL_A;
1124 }
1125 else if ((pmadapter->fw_bands & BAND_GN) != 0U)
1126 {
1127 pmadapter->adhoc_start_band = (BAND_G | BAND_B | BAND_GN);
1128 pmpriv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
1129 pmadapter->adhoc_11n_enabled = MTRUE;
1130 }
1131 else if ((pmadapter->fw_bands & BAND_G) != 0U)
1132 {
1133 pmadapter->adhoc_start_band = (BAND_G | BAND_B);
1134 pmpriv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
1135 }
1136 else if ((pmadapter->fw_bands & BAND_B) != 0U)
1137 {
1138 pmadapter->adhoc_start_band = BAND_B;
1139 pmpriv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
1140 }
1141 else
1142 {
1143 /* Do nothing */
1144 }
1145 #endif /* STA_SUPPORT */
1146
1147 pmadapter->fw_release_number = hw_spec->fw_release_number;
1148 pmadapter->number_of_antenna = wlan_le16_to_cpu(hw_spec->number_of_antenna);
1149
1150 PRINTM(MINFO, "GET_HW_SPEC: fw_release_number- 0x%X\n", wlan_le32_to_cpu(pmadapter->fw_release_number));
1151 PRINTM(MINFO, "GET_HW_SPEC: Permanent addr- %2x:%2x:%2x:%2x:%2x:%2x\n", hw_spec->permanent_addr[0],
1152 hw_spec->permanent_addr[1], hw_spec->permanent_addr[2], hw_spec->permanent_addr[3],
1153 hw_spec->permanent_addr[4], hw_spec->permanent_addr[5]);
1154 PRINTM(MINFO, "GET_HW_SPEC: hw_if_version=0x%X version=0x%X\n", wlan_le16_to_cpu(hw_spec->hw_if_version),
1155 wlan_le16_to_cpu(hw_spec->version));
1156
1157 if (pmpriv->curr_addr[0] == 0xffU)
1158 {
1159 (void)__memmove(pmadapter, pmpriv->curr_addr, hw_spec->permanent_addr, MLAN_MAC_ADDR_LENGTH);
1160 #if CONFIG_P2P
1161 (void)__memmove(pmadapter, pmpriv->curr_p2p_addr, hw_spec->permanent_addr, MLAN_MAC_ADDR_LENGTH);
1162 pmpriv->curr_p2p_addr[0] |= (0x01 << 1);
1163 #endif
1164 }
1165
1166 pmadapter->hw_dot_11n_dev_cap = wlan_le32_to_cpu(hw_spec->dot_11n_dev_cap);
1167 pmadapter->usr_dot_11n_dev_cap_bg = pmadapter->hw_dot_11n_dev_cap & DEFAULT_11N_CAP_MASK_BG;
1168 pmadapter->usr_dot_11n_dev_cap_a = pmadapter->hw_dot_11n_dev_cap & DEFAULT_11N_CAP_MASK_A;
1169 pmadapter->usr_dev_mcs_support = pmadapter->hw_dev_mcs_support = hw_spec->dev_mcs_support;
1170 pmadapter->hw_mpdu_density = GET_MPDU_DENSITY(hw_spec->hw_dev_cap);
1171 PRINTM(MCMND, "GET_HW_SPEC: hw_mpdu_density=%d dev_mcs_support=0x%x\n", pmadapter->hw_mpdu_density,
1172 hw_spec->dev_mcs_support);
1173
1174 wlan_show_dot11ndevcap(pmadapter, pmadapter->hw_dot_11n_dev_cap);
1175 wlan_show_devmcssupport(pmadapter, pmadapter->hw_dev_mcs_support);
1176
1177 pmadapter->hw_dot_11ac_dev_cap = wlan_le32_to_cpu(hw_spec->Dot11acDevCap);
1178 pmadapter->hw_dot_11ac_mcs_support = wlan_le32_to_cpu(hw_spec->Dot11acMcsSupport);
1179
1180 pmadapter->usr_dot_11ac_mcs_support = pmadapter->hw_dot_11ac_mcs_support;
1181
1182 pmadapter->usr_dot_11ac_dev_cap_bg = pmadapter->hw_dot_11ac_dev_cap & ~DEFALUT_11AC_CAP_BEAMFORMING_RESET_MASK;
1183 #if CONFIG_5GHz_SUPPORT
1184 pmadapter->usr_dot_11ac_dev_cap_a = pmadapter->hw_dot_11ac_dev_cap & ~DEFALUT_11AC_CAP_BEAMFORMING_RESET_MASK;
1185 #endif
1186 pmadapter->usr_dot_11ac_bw = BW_FOLLOW_VHTCAP;
1187
1188 pmadapter->mp_end_port = wlan_le16_to_cpu(hw_spec->mp_end_port);
1189
1190 #ifndef RW610
1191 for (i = 1; i <= (unsigned)(MAX_PORT - pmadapter->mp_end_port); i++)
1192 {
1193 pmadapter->mp_data_port_mask &= ~(1U << (MAX_PORT - i));
1194 }
1195 #endif
1196
1197 #ifdef OTP_CHANINFO
1198 if ((pmadapter->otp_region != MNULL) && (pmadapter->otp_region->force_reg == 0U))
1199 {
1200 #endif
1201
1202 /* Set the region code to WWSM by default */
1203 pmadapter->region_code = hw_spec->region_code;
1204 for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++)
1205 {
1206 /* Use the region code to search for the index */
1207 if (pmadapter->region_code == region_code_index[i])
1208 {
1209 break;
1210 }
1211 }
1212 /* If it's unidentified region code, use the default */
1213 if (i >= MRVDRV_MAX_REGION_CODE)
1214 {
1215 pmadapter->region_code = MRVDRV_DEFAULT_REGION_CODE;
1216 PRINTM(MWARN, "unidentified region code, use the default (0x%02x)\n", MRVDRV_DEFAULT_REGION_CODE);
1217 }
1218
1219 /* Back up hw_region_code in case it is overwritten by the supplicant process*/
1220 pmadapter->hw_region_code = pmadapter->region_code;
1221
1222 /* Synchronize CFP code with region code */
1223 pmadapter->cfp_code_bg = (t_u8)pmadapter->region_code;
1224 pmadapter->cfp_code_a = (t_u8)pmadapter->region_code;
1225 /* Set country code */
1226 (void)__memcpy(pmadapter, pmadapter->country_code,
1227 wlan_11d_code_2_region(pmadapter, (t_u8)pmadapter->region_code), COUNTRY_CODE_LEN - 1);
1228 #ifdef OTP_CHANINFO
1229 }
1230 #endif
1231 if (wlan_set_regiontable(pmpriv, (t_u8)pmadapter->region_code, pmadapter->fw_bands) != MLAN_STATUS_SUCCESS)
1232 {
1233 if (pioctl_req != MNULL)
1234 {
1235 pioctl_req->status_code = MLAN_ERROR_CMD_SCAN_FAIL;
1236 }
1237 ret = MLAN_STATUS_FAILURE;
1238 goto done;
1239 }
1240 #ifdef STA_SUPPORT
1241 if (wlan_11d_set_universaltable(pmpriv, pmadapter->fw_bands) != MLAN_STATUS_SUCCESS)
1242 {
1243 if (pioctl_req != MNULL)
1244 {
1245 pioctl_req->status_code = MLAN_ERROR_CMD_SCAN_FAIL;
1246 }
1247 ret = MLAN_STATUS_FAILURE;
1248 goto done;
1249 }
1250 #endif /* STA_SUPPORT */
1251 left_len = resp->size - (t_u16)sizeof(HostCmd_DS_GET_HW_SPEC) - (t_u16)S_DS_GEN;
1252 tlv = (MrvlIEtypesHeader_t *)(void *)((t_u8 *)(&resp->params) + sizeof(HostCmd_DS_GET_HW_SPEC));
1253 while (left_len > sizeof(MrvlIEtypesHeader_t))
1254 {
1255 tlv_type = wlan_le16_to_cpu(tlv->type);
1256 tlv_len = wlan_le16_to_cpu(tlv->len);
1257 switch (tlv_type)
1258 {
1259 #if CONFIG_11AX
1260 case TLV_TYPE_EXTENSION_ID:
1261 ext_tlv = (MrvlIEtypes_Extension_t *)tlv;
1262 if (ext_tlv->ext_id == HE_CAPABILITY)
1263 {
1264 ext_tlv->type = tlv_type;
1265 ext_tlv->len = tlv_len;
1266 #ifndef RW610
1267 wlan_update_11ax_cap(pmadapter, (MrvlIEtypes_Extension_t *)ext_tlv);
1268 #else
1269 if ((he_tlv_idx == AX_2G_TLV_INDEX) || !ISSUPP_NO5G(pmadapter->fw_cap_ext))
1270 {
1271 wlan_update_11ax_cap(pmadapter, (MrvlIEtypes_Extension_t *)ext_tlv, he_tlv_idx);
1272 he_tlv_idx++;
1273 }
1274 #endif
1275 }
1276 break;
1277 #endif
1278 case TLV_TYPE_FW_CAP_INFO:
1279 fw_cap_tlv = (MrvlIEtypes_fw_cap_info_t *)(void *)tlv;
1280 pmadapter->fw_cap_info = wlan_le32_to_cpu(fw_cap_tlv->fw_cap_info);
1281 pmadapter->fw_cap_ext = wlan_le32_to_cpu(fw_cap_tlv->fw_cap_ext);
1282 PRINTM(MCMND, "fw_cap_info=0x%x fw_cap_ext=0x%x\n", pmadapter->fw_cap_info, pmadapter->fw_cap_ext);
1283 break;
1284 default:
1285 PRINTM(MINFO, "Unexpected TLV hw spec \n");
1286 break;
1287 }
1288 left_len -= (t_u16)(sizeof(MrvlIEtypesHeader_t) + tlv_len);
1289 tlv = (MrvlIEtypesHeader_t *)(void *)((t_u8 *)tlv + tlv_len + sizeof(MrvlIEtypesHeader_t));
1290 }
1291
1292 #if defined(SD8987) || defined(SD9177)
1293 pmadapter->cmd_tx_data = IS_FW_SUPPORT_CMD_TX_DATA(pmadapter) ? 0x01 : 0x00;
1294 #endif
1295
1296 done:
1297 LEAVE();
1298 return ret;
1299 }
1300
1301 /**
1302 * @brief This function prepares command of remain_on_channel.
1303 *
1304 * @param pmpriv A pointer to mlan_private structure
1305 * @param cmd A pointer to HostCmd_DS_COMMAND structure
1306 * @param cmd_action The action: GET or SET
1307 * @param pdata_buf A pointer to data buffer
1308 *
1309 * @return MLAN_STATUS_SUCCESS
1310 */
wlan_cmd_remain_on_channel(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_u16 cmd_action,IN t_void * pdata_buf)1311 mlan_status wlan_cmd_remain_on_channel(IN pmlan_private pmpriv,
1312 IN HostCmd_DS_COMMAND *cmd,
1313 IN t_u16 cmd_action,
1314 IN t_void *pdata_buf)
1315 {
1316 HostCmd_DS_REMAIN_ON_CHANNEL *remain_channel = &cmd->params.remain_on_chan;
1317 mlan_ds_remain_chan *cfg = (mlan_ds_remain_chan *)pdata_buf;
1318 ENTER();
1319 cmd->size = wlan_cpu_to_le16((sizeof(HostCmd_DS_REMAIN_ON_CHANNEL)) + S_DS_GEN);
1320 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_REMAIN_ON_CHANNEL);
1321 remain_channel->action = cmd_action;
1322 if (cmd_action == HostCmd_ACT_GEN_SET)
1323 {
1324 if (cfg->remove != 0U)
1325 {
1326 remain_channel->action = HostCmd_ACT_GEN_REMOVE;
1327 }
1328 else
1329 {
1330 remain_channel->status = 0;
1331 remain_channel->reserved = 0;
1332 remain_channel->bandcfg = cfg->bandcfg;
1333 remain_channel->channel = cfg->channel;
1334 remain_channel->remain_period = wlan_cpu_to_le32(cfg->remain_period);
1335 }
1336 }
1337 remain_channel->action = wlan_cpu_to_le16(remain_channel->action);
1338
1339 LEAVE();
1340 return MLAN_STATUS_SUCCESS;
1341 }
1342
1343 #ifdef OTP_CHANINFO
1344 /**
1345 * @brief This function handles the command response of chan_region_cfg
1346 *
1347 * @param pmpriv A pointer to mlan_private structure
1348 * @param resp A pointer to HostCmd_DS_COMMAND
1349 * @param pioctl_buf A pointer to command buffer
1350 *
1351 * @return MLAN_STATUS_SUCCESS
1352 */
wlan_ret_chan_region_cfg(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * resp,IN mlan_ioctl_req * pioctl_buf)1353 mlan_status wlan_ret_chan_region_cfg(IN pmlan_private pmpriv,
1354 IN HostCmd_DS_COMMAND *resp,
1355 IN mlan_ioctl_req *pioctl_buf)
1356 {
1357 mlan_adapter *pmadapter = pmpriv->adapter;
1358 t_u16 action;
1359 HostCmd_DS_CHAN_REGION_CFG *reg = MNULL;
1360 t_u8 *tlv_buf = MNULL;
1361 t_u16 tlv_buf_left;
1362 mlan_ds_misc_cfg *misc_cfg = MNULL;
1363 mlan_ds_misc_chnrgpwr_cfg *cfg = MNULL;
1364 mlan_status ret = MLAN_STATUS_SUCCESS;
1365
1366 ENTER();
1367
1368 reg = (HostCmd_DS_CHAN_REGION_CFG *)(void *)&resp->params;
1369 if (reg == MNULL)
1370 {
1371 ret = MLAN_STATUS_FAILURE;
1372 goto done;
1373 }
1374
1375 action = wlan_le16_to_cpu(reg->action);
1376 if (action != HostCmd_ACT_GEN_GET)
1377 {
1378 ret = MLAN_STATUS_FAILURE;
1379 goto done;
1380 }
1381
1382 tlv_buf = (t_u8 *)reg + sizeof(*reg);
1383 tlv_buf_left = (t_u16)(wlan_le16_to_cpu(resp->size) - S_DS_GEN - sizeof(*reg));
1384
1385 /* Add FW cfp tables and region info */
1386 wlan_add_fw_cfp_tables(pmpriv, tlv_buf, tlv_buf_left);
1387
1388 if (pioctl_buf == MNULL)
1389 {
1390 goto done;
1391 }
1392
1393 if (pioctl_buf->pbuf == MNULL)
1394 {
1395 ret = MLAN_STATUS_FAILURE;
1396 goto done;
1397 }
1398
1399 misc_cfg = (mlan_ds_misc_cfg *)(void *)pioctl_buf->pbuf;
1400
1401 if (misc_cfg->sub_command == MLAN_OID_MISC_GET_REGIONPWR_CFG)
1402 {
1403 cfg = (mlan_ds_misc_chnrgpwr_cfg *)&(misc_cfg->param.rgchnpwr_cfg);
1404 cfg->length = wlan_le16_to_cpu(resp->size);
1405 (void)__memcpy(pmpriv->adapter, cfg->chnrgpwr_buf, (t_u8 *)resp, cfg->length);
1406 }
1407 else
1408 {
1409 (void)__memset(pmpriv->adapter, &misc_cfg->param.custom_reg_domain, 0, sizeof(mlan_ds_custom_reg_domain));
1410 if (pmadapter->otp_region != MNULL)
1411 {
1412 (void)__memcpy(pmpriv->adapter, &misc_cfg->param.custom_reg_domain.region, pmadapter->otp_region,
1413 sizeof(otp_region_info_t));
1414 }
1415 if (pmadapter->cfp_otp_bg != MNULL)
1416 {
1417 misc_cfg->param.custom_reg_domain.num_bg_chan = pmadapter->tx_power_table_bg_rows;
1418 (void)__memcpy(pmpriv->adapter, (t_u8 *)misc_cfg->param.custom_reg_domain.cfp_tbl,
1419 (t_u8 *)pmadapter->cfp_otp_bg,
1420 pmadapter->tx_power_table_bg_rows * sizeof(chan_freq_power_t));
1421 }
1422 #if CONFIG_5GHz_SUPPORT
1423 if (pmadapter->cfp_otp_a != MNULL)
1424 {
1425 misc_cfg->param.custom_reg_domain.num_a_chan = pmadapter->tx_power_table_a_rows;
1426 (void)__memcpy(pmpriv->adapter,
1427 (t_u8 *)misc_cfg->param.custom_reg_domain.cfp_tbl +
1428 pmadapter->tx_power_table_bg_rows * sizeof(chan_freq_power_t),
1429 (t_u8 *)pmadapter->cfp_otp_a, pmadapter->tx_power_table_a_rows * sizeof(chan_freq_power_t));
1430 }
1431 #endif
1432 }
1433 done:
1434 LEAVE();
1435 return ret;
1436 }
1437 #endif
1438
1439 #if CONFIG_COMPRESS_TX_PWTBL
wlan_cmd_region_power_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)1440 mlan_status wlan_cmd_region_power_cfg(pmlan_private pmpriv,
1441 HostCmd_DS_COMMAND *cmd,
1442 t_u16 cmd_action,
1443 t_void *pdata_buf)
1444 {
1445 t_u16 buf_len;
1446
1447 ENTER();
1448
1449 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_REGION_POWER_CFG);
1450 if (cmd_action == HostCmd_ACT_GEN_SET)
1451 {
1452 buf_len = cmd->size - S_DS_GEN;
1453 __memcpy(pmpriv->adapter, (t_u8 *)cmd + S_DS_GEN, pdata_buf, buf_len);
1454 }
1455
1456 LEAVE();
1457 return MLAN_STATUS_SUCCESS;
1458 }
1459 #endif
1460
1461 #if CONFIG_RX_ABORT_CFG
1462 /**
1463 * @brief This function sends rx abort cfg command to firmware.
1464 *
1465 * @param pmpriv A pointer to mlan_private structure
1466 * @param cmd Hostcmd ID
1467 * @param cmd_action Command action
1468 * @param pdata_buf A void pointer to information buffer
1469 * @return N/A
1470 */
wlan_cmd_rx_abort_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)1471 mlan_status wlan_cmd_rx_abort_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, t_u16 cmd_action, t_void *pdata_buf)
1472 {
1473 HostCmd_DS_RX_ABORT_CFG *rx_abort_cfg = &cmd->params.rx_abort_cfg;
1474 (void)memset(cmd, 0x00, sizeof(HostCmd_DS_COMMAND));
1475 rx_abort_cfg_t *cfg = (rx_abort_cfg_t *)pdata_buf;
1476
1477 ENTER();
1478
1479 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_RX_ABORT_CFG);
1480 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_RX_ABORT_CFG) + S_DS_GEN);
1481 rx_abort_cfg->action = wlan_cpu_to_le16(cmd_action);
1482
1483 if (rx_abort_cfg->action == HostCmd_ACT_GEN_SET)
1484 {
1485 rx_abort_cfg->enable = cfg->enable;
1486 rx_abort_cfg->rssi_threshold = (t_s8)cfg->rssi_threshold;
1487 }
1488
1489 LEAVE();
1490 return MLAN_STATUS_SUCCESS;
1491 }
1492 #endif
1493
1494 #if CONFIG_RX_ABORT_CFG_EXT
1495 /**
1496 * @brief This function sends rx abort cfg ext command to firmware.
1497 *
1498 * @param pmpriv A pointer to mlan_private structure
1499 * @param cmd Hostcmd ID
1500 * @param cmd_action Command action
1501 * @param pdata_buf A void pointer to information buffer
1502 * @return N/A
1503 */
wlan_cmd_rx_abort_cfg_ext(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)1504 mlan_status wlan_cmd_rx_abort_cfg_ext(pmlan_private pmpriv,
1505 HostCmd_DS_COMMAND *cmd,
1506 t_u16 cmd_action,
1507 t_void *pdata_buf)
1508 {
1509 HostCmd_DS_RX_ABORT_CFG_EXT *rx_abort_cfg_ext = (HostCmd_DS_RX_ABORT_CFG_EXT *)&cmd->params.rx_abort_cfg_ext;
1510 rx_abort_cfg_ext_t *cfg = (rx_abort_cfg_ext_t *)pdata_buf;
1511
1512 ENTER();
1513
1514 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_RX_ABORT_CFG_EXT);
1515 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_RX_ABORT_CFG_EXT) + S_DS_GEN);
1516 rx_abort_cfg_ext->action = wlan_cpu_to_le16(cmd_action);
1517
1518 if (rx_abort_cfg_ext->action == HostCmd_ACT_GEN_SET)
1519 {
1520 rx_abort_cfg_ext->enable = cfg->enable;
1521 rx_abort_cfg_ext->rssi_margin = (t_s8)cfg->rssi_margin;
1522 rx_abort_cfg_ext->ceil_rssi_threshold = (t_s8)cfg->ceil_rssi_threshold;
1523 rx_abort_cfg_ext->floor_rssi_threshold = (t_s8)cfg->floor_rssi_threshold;
1524 }
1525
1526 LEAVE();
1527 return MLAN_STATUS_SUCCESS;
1528 }
1529 #endif
1530
1531 #if CONFIG_CCK_DESENSE_CFG
1532 /**
1533 * @brief This function sends cck desense cfg command to firmware.
1534 *
1535 * @param pmpriv A pointer to mlan_private structure
1536 * @param cmd Hostcmd ID
1537 * @param cmd_action Command action
1538 * @param pdata_buf A void pointer to information buffer
1539 * @return N/A
1540 */
wlan_cmd_cck_desense_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)1541 mlan_status wlan_cmd_cck_desense_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, t_u16 cmd_action, t_void *pdata_buf)
1542 {
1543 HostCmd_DS_CCK_DESENSE_CFG *cfg_cmd = (HostCmd_DS_CCK_DESENSE_CFG *)&cmd->params.cck_desense_cfg;
1544 cck_desense_cfg_t *cfg = (cck_desense_cfg_t *)pdata_buf;
1545
1546 ENTER();
1547
1548 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_CCK_DESENSE_CFG);
1549 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_CCK_DESENSE_CFG) + S_DS_GEN);
1550 cfg_cmd->action = wlan_cpu_to_le16(cmd_action);
1551
1552 if (cmd_action == HostCmd_ACT_GEN_SET)
1553 {
1554 cfg_cmd->mode = wlan_cpu_to_le16(cfg->mode);
1555 cfg_cmd->margin = (t_s8)cfg->margin;
1556 cfg_cmd->ceil_thresh = (t_s8)cfg->ceil_thresh;
1557 cfg_cmd->num_on_intervals = (t_u8)cfg->num_on_intervals;
1558 cfg_cmd->num_off_intervals = (t_u8)cfg->num_off_intervals;
1559 }
1560
1561 LEAVE();
1562 return MLAN_STATUS_SUCCESS;
1563 }
1564 #endif
1565
1566 #if CONFIG_WIFI_CLOCKSYNC
1567 /**
1568 * @brief This function prepares command of GPIO TSF LATCH.
1569 *
1570 * @param pmpriv A pointer to mlan_private structure
1571 * @param cmd A pointer to HostCmd_DS_COMMAND structure
1572 * @param cmd_action The action: GET or SET
1573 * @param pioctl_buf A pointer to mlan_ioctl_req buf
1574 * @param pdata_buf A pointer to data buffer
1575 *
1576 * @return MLAN_STATUS_SUCCESS
1577 */
wlan_cmd_gpio_tsf_latch(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,mlan_ioctl_req * pioctl_buf,t_void * pdata_buf)1578 mlan_status wlan_cmd_gpio_tsf_latch(
1579 pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, t_u16 cmd_action, mlan_ioctl_req *pioctl_buf, t_void *pdata_buf)
1580 {
1581 HostCmd_DS_GPIO_TSF_LATCH_PARAM_CONFIG *gpio_tsf_config = &cmd->params.gpio_tsf_latch;
1582 mlan_ds_gpio_tsf_latch *cfg = (mlan_ds_gpio_tsf_latch *)pdata_buf;
1583 mlan_ds_misc_cfg *misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
1584
1585 mlan_ds_tsf_info *tsf_info = (mlan_ds_tsf_info *)pdata_buf;
1586 MrvlIEtypes_GPIO_TSF_LATCH_CONFIG *gpio_tsf_latch_config = MNULL;
1587 MrvlIEtypes_GPIO_TSF_LATCH_REPORT *gpio_tsf_latch_report = MNULL;
1588 t_u8 *tlv = MNULL;
1589 ENTER();
1590
1591 cmd->size = sizeof(HostCmd_DS_GPIO_TSF_LATCH_PARAM_CONFIG) + S_DS_GEN;
1592 cmd->command = wlan_cpu_to_le16(HostCmd_GPIO_TSF_LATCH_PARAM_CONFIG);
1593 gpio_tsf_config->action = wlan_cpu_to_le16(cmd_action);
1594 if (cmd_action == HostCmd_ACT_GEN_SET)
1595 {
1596 tlv = (t_u8 *)gpio_tsf_config->tlv_buf;
1597 if (misc_cfg->sub_command == (t_u32)MLAN_OID_MISC_GPIO_TSF_LATCH)
1598 {
1599 gpio_tsf_latch_config = (MrvlIEtypes_GPIO_TSF_LATCH_CONFIG *)tlv;
1600 gpio_tsf_latch_config->header.type = wlan_cpu_to_le16(TLV_TYPE_GPIO_TSF_LATCH_CONFIG);
1601 gpio_tsf_latch_config->header.len =
1602 wlan_cpu_to_le16(sizeof(MrvlIEtypes_GPIO_TSF_LATCH_CONFIG) - sizeof(MrvlIEtypesHeader_t));
1603 gpio_tsf_latch_config->clock_sync_mode = cfg->clock_sync_mode;
1604 gpio_tsf_latch_config->clock_sync_Role = cfg->clock_sync_Role;
1605 gpio_tsf_latch_config->clock_sync_gpio_pin_number = cfg->clock_sync_gpio_pin_number;
1606 gpio_tsf_latch_config->clock_sync_gpio_level_toggle = cfg->clock_sync_gpio_level_toggle;
1607 gpio_tsf_latch_config->clock_sync_gpio_pulse_width = wlan_cpu_to_le16(cfg->clock_sync_gpio_pulse_width);
1608 cmd->size += sizeof(MrvlIEtypes_GPIO_TSF_LATCH_CONFIG);
1609 tlv += sizeof(MrvlIEtypes_GPIO_TSF_LATCH_CONFIG);
1610 PRINTM(
1611 MCMND,
1612 "Set GPIO TSF latch config: \r\nMode=%d Role=%d, \r\nGPIO Pin Number=%d, \r\nGPIO level/toggle=%d GPIO "
1613 "pulse "
1614 "width=%d\n\r",
1615 cfg->clock_sync_mode, cfg->clock_sync_Role, cfg->clock_sync_gpio_pin_number,
1616 cfg->clock_sync_gpio_level_toggle, (int)cfg->clock_sync_gpio_pulse_width);
1617 }
1618 }
1619 else if (cmd_action == HostCmd_ACT_GEN_GET)
1620 {
1621 tlv = (t_u8 *)gpio_tsf_config->tlv_buf;
1622 if (misc_cfg->sub_command == (t_u32)MLAN_OID_MISC_GPIO_TSF_LATCH)
1623 {
1624 gpio_tsf_latch_config = (MrvlIEtypes_GPIO_TSF_LATCH_CONFIG *)tlv;
1625 gpio_tsf_latch_config->header.type = wlan_cpu_to_le16(TLV_TYPE_GPIO_TSF_LATCH_CONFIG);
1626 gpio_tsf_latch_config->header.len =
1627 wlan_cpu_to_le16(sizeof(MrvlIEtypes_GPIO_TSF_LATCH_CONFIG) - sizeof(MrvlIEtypesHeader_t));
1628 cmd->size += sizeof(MrvlIEtypes_GPIO_TSF_LATCH_CONFIG);
1629 tlv += sizeof(MrvlIEtypes_GPIO_TSF_LATCH_CONFIG);
1630 }
1631
1632 if (misc_cfg->sub_command == (t_u32)MLAN_OID_MISC_GET_TSF_INFO)
1633 {
1634 gpio_tsf_latch_report = (MrvlIEtypes_GPIO_TSF_LATCH_REPORT *)tlv;
1635 (void)memset(gpio_tsf_latch_report, 0, sizeof(MrvlIEtypes_GPIO_TSF_LATCH_REPORT));
1636 gpio_tsf_latch_report->header.type = wlan_cpu_to_le16(TLV_TYPE_GPIO_TSF_LATCH_REPORT);
1637 gpio_tsf_latch_report->header.len =
1638 wlan_cpu_to_le16(sizeof(MrvlIEtypes_GPIO_TSF_LATCH_REPORT) - sizeof(MrvlIEtypesHeader_t));
1639 gpio_tsf_latch_report->tsf_format = wlan_cpu_to_le16(tsf_info->tsf_format);
1640 PRINTM(MCMND, "Get TSF info: format=%d\n\r", tsf_info->tsf_format);
1641 cmd->size += sizeof(MrvlIEtypes_GPIO_TSF_LATCH_REPORT);
1642 }
1643 }
1644 cmd->size = wlan_cpu_to_le16(cmd->size);
1645 LEAVE();
1646 return MLAN_STATUS_SUCCESS;
1647 }
1648
1649 /**
1650 * @brief This function handles the command response of GPIO TSF Latch
1651 *
1652 * @param pmpriv A pointer to mlan_private structure
1653 * @param resp A pointer to HostCmd_DS_COMMAND
1654 * @param pioctl_buf A pointer to mlan_ioctl_req structure
1655 *
1656 * @return MLAN_STATUS_SUCCESS
1657 */
wlan_ret_gpio_tsf_latch(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)1658 mlan_status wlan_ret_gpio_tsf_latch(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf)
1659 {
1660 HostCmd_DS_GPIO_TSF_LATCH_PARAM_CONFIG *gpio_tsf_config = &resp->params.gpio_tsf_latch;
1661 mlan_ds_misc_cfg *cfg = MNULL;
1662 MrvlIEtypes_GPIO_TSF_LATCH_CONFIG *gpio_tsf_latch_config = MNULL;
1663 MrvlIEtypes_GPIO_TSF_LATCH_REPORT *gpio_tsf_latch_report = MNULL;
1664 MrvlIEtypesHeader_t *tlv = MNULL;
1665 t_u16 tlv_buf_left = 0;
1666 t_u16 tlv_type = 0;
1667 t_u16 tlv_len = 0;
1668
1669 ENTER();
1670 if (wlan_le16_to_cpu(gpio_tsf_config->action) == HostCmd_ACT_GEN_GET)
1671 {
1672 if (pioctl_buf)
1673 {
1674 cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
1675 tlv = (MrvlIEtypesHeader_t *)(gpio_tsf_config->tlv_buf);
1676 tlv_buf_left = resp->size - (sizeof(HostCmd_DS_GPIO_TSF_LATCH_PARAM_CONFIG) + S_DS_GEN);
1677 while (tlv_buf_left >= sizeof(MrvlIEtypesHeader_t))
1678 {
1679 tlv_type = wlan_le16_to_cpu(tlv->type);
1680 tlv_len = wlan_le16_to_cpu(tlv->len);
1681 if (tlv_buf_left < (tlv_len + sizeof(MrvlIEtypesHeader_t)))
1682 {
1683 PRINTM(MCMND, "Error processing gpio tsf latch config TLVs, bytes left < TLV length\n");
1684 break;
1685 }
1686 switch (tlv_type)
1687 {
1688 case TLV_TYPE_GPIO_TSF_LATCH_CONFIG:
1689 if (cfg->sub_command == (t_u32)MLAN_OID_MISC_GPIO_TSF_LATCH)
1690 {
1691 gpio_tsf_latch_config = (MrvlIEtypes_GPIO_TSF_LATCH_CONFIG *)tlv;
1692 cfg->param.gpio_tsf_latch_config.clock_sync_mode = gpio_tsf_latch_config->clock_sync_mode;
1693 cfg->param.gpio_tsf_latch_config.clock_sync_Role = gpio_tsf_latch_config->clock_sync_Role;
1694 cfg->param.gpio_tsf_latch_config.clock_sync_gpio_pin_number =
1695 gpio_tsf_latch_config->clock_sync_gpio_pin_number;
1696 cfg->param.gpio_tsf_latch_config.clock_sync_gpio_level_toggle =
1697 gpio_tsf_latch_config->clock_sync_gpio_level_toggle;
1698 cfg->param.gpio_tsf_latch_config.clock_sync_gpio_pulse_width =
1699 wlan_le16_to_cpu(gpio_tsf_latch_config->clock_sync_gpio_pulse_width);
1700 PRINTM(
1701 MCMND,
1702 "Get GPIO TSF latch config: Mode=%d Role=%d, GPIO Pin Number=%d, GPIO level/toggle=%d "
1703 "GPIO pulse width=%d\n\r",
1704 cfg->param.gpio_tsf_latch_config.clock_sync_mode,
1705 cfg->param.gpio_tsf_latch_config.clock_sync_Role,
1706 cfg->param.gpio_tsf_latch_config.clock_sync_gpio_pin_number,
1707 cfg->param.gpio_tsf_latch_config.clock_sync_gpio_level_toggle,
1708 (int)cfg->param.gpio_tsf_latch_config.clock_sync_gpio_pulse_width);
1709 }
1710 break;
1711 case TLV_TYPE_GPIO_TSF_LATCH_REPORT:
1712 if (cfg->sub_command == (t_u32)MLAN_OID_MISC_GET_TSF_INFO)
1713 {
1714 gpio_tsf_latch_report = (MrvlIEtypes_GPIO_TSF_LATCH_REPORT *)tlv;
1715 cfg->param.tsf_info.tsf_format = wlan_le16_to_cpu(gpio_tsf_latch_report->tsf_format);
1716 cfg->param.tsf_info.tsf_info = wlan_le16_to_cpu(gpio_tsf_latch_report->tsf_info);
1717 cfg->param.tsf_info.tsf = wlan_le64_to_cpu(gpio_tsf_latch_report->tsf);
1718 cfg->param.tsf_info.tsf_offset = wlan_le16_to_cpu(gpio_tsf_latch_report->tsf_offset);
1719 PRINTM(MCMND, "Get GPIO TSF latch report : format=%d\n info=%d tsf=%llu offset=%d\r\n",
1720 cfg->param.tsf_info.tsf_format, cfg->param.tsf_info.tsf_info,
1721 cfg->param.tsf_info.tsf, cfg->param.tsf_info.tsf_offset);
1722 }
1723 break;
1724 default:
1725 wifi_d("gpio tsf latch: Unknown tlv type");
1726 break;
1727 }
1728 tlv_buf_left -= tlv_len + sizeof(MrvlIEtypesHeader_t);
1729 tlv = (MrvlIEtypesHeader_t *)((t_u8 *)tlv + tlv_len + sizeof(MrvlIEtypesHeader_t));
1730 }
1731 if (cfg->sub_command == (t_u32)MLAN_OID_MISC_GPIO_TSF_LATCH)
1732 pioctl_buf->data_read_written = sizeof(mlan_ds_gpio_tsf_latch);
1733 else if (cfg->sub_command == (t_u32)MLAN_OID_MISC_GET_TSF_INFO)
1734 pioctl_buf->data_read_written = sizeof(mlan_ds_tsf_info);
1735 }
1736 }
1737 LEAVE();
1738 return MLAN_STATUS_SUCCESS;
1739 }
1740 #endif /* CONFIG_WIFI_CLOCKSYNC */
1741
1742 #if CONFIG_MULTI_CHAN
1743 /**
1744 * @brief This function prepares the command MULTI_CHAN_CFG
1745 *
1746 * @param pmpriv A pointer to mlan_private structure
1747 * @param cmd A pointer to HostCmd_DS_COMMAND structure
1748 * @param cmd_action Command action: GET or SET
1749 * @param pdata_buf A pointer to new setting buf
1750 *
1751 * @return MLAN_STATUS_SUCCESS
1752 */
wlan_cmd_multi_chan_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)1753 mlan_status wlan_cmd_multi_chan_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, t_u16 cmd_action, t_void *pdata_buf)
1754 {
1755 mlan_ds_multi_chan_cfg *multi_chan_cfg = (mlan_ds_multi_chan_cfg *)pdata_buf;
1756 HostCmd_DS_MULTI_CHAN_CFG *pmchan_cfg = (HostCmd_DS_MULTI_CHAN_CFG *)&cmd->params.multi_chan_cfg;
1757
1758 ENTER();
1759
1760 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MULTI_CHAN_CONFIG);
1761 pmchan_cfg->action = wlan_cpu_to_le16(cmd_action);
1762
1763 if (cmd_action == HostCmd_ACT_GEN_SET)
1764 {
1765 pmchan_cfg->buffer_weight = multi_chan_cfg->buffer_weight;
1766 pmchan_cfg->channel_time = wlan_cpu_to_le32(multi_chan_cfg->channel_time);
1767 PRINTM(MCMND, "Set multi-channel: buffer_weight=%d channel_time=%d\n", multi_chan_cfg->buffer_weight,
1768 multi_chan_cfg->channel_time);
1769 cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_MULTI_CHAN_CFG));
1770 }
1771 else
1772 {
1773 cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(cmd_action));
1774 }
1775
1776 LEAVE();
1777 return MLAN_STATUS_SUCCESS;
1778 }
1779
1780 /**
1781 * @brief This function handles the command response of MULTI_CHAN_CFG
1782 *
1783 * @param pmpriv A pointer to mlan_private structure
1784 * @param resp A pointer to HostCmd_DS_COMMAND
1785 * @param pioctl_buf A pointer to mlan_ioctl_req structure
1786 *
1787 * @return MLAN_STATUS_SUCCESS
1788 */
wlan_ret_multi_chan_cfg(pmlan_private pmpriv,const HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)1789 mlan_status wlan_ret_multi_chan_cfg(pmlan_private pmpriv, const HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf)
1790 {
1791 mlan_ds_misc_cfg *pcfg = MNULL;
1792 const HostCmd_DS_MULTI_CHAN_CFG *presp_cfg = &resp->params.multi_chan_cfg;
1793
1794 ENTER();
1795
1796 if (pioctl_buf)
1797 {
1798 pcfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
1799 pcfg->param.multi_chan_cfg.channel_time = wlan_le32_to_cpu(presp_cfg->channel_time);
1800 pcfg->param.multi_chan_cfg.buffer_weight = presp_cfg->buffer_weight;
1801 pcfg->param.multi_chan_cfg.tlv_len = resp->size - (sizeof(HostCmd_DS_GEN) + sizeof(HostCmd_DS_MULTI_CHAN_CFG));
1802 PRINTM(MCMND, "Get multi-channel: buffer_weight=%d channel_time=%d tlv_len=%d\n",
1803 pcfg->param.multi_chan_cfg.buffer_weight, pcfg->param.multi_chan_cfg.channel_time,
1804 pcfg->param.multi_chan_cfg.tlv_len);
1805 __memcpy(pmpriv->adapter, pcfg->param.multi_chan_cfg.tlv_buf, presp_cfg->tlv_buf,
1806 pcfg->param.multi_chan_cfg.tlv_len);
1807 pioctl_buf->buf_len = sizeof(mlan_ds_multi_chan_cfg) + pcfg->param.multi_chan_cfg.tlv_len;
1808 }
1809
1810 LEAVE();
1811 return MLAN_STATUS_SUCCESS;
1812 }
1813
1814 /**
1815 * @brief This function prepares the command MULTI_CHAN_POLICY
1816 *
1817 * @param pmpriv A pointer to mlan_private structure
1818 * @param cmd A pointer to HostCmd_DS_COMMAND structure
1819 * @param cmd_action Command action: GET or SET
1820 * @param pdata_buf A pointer to new setting buf
1821 *
1822 * @return MLAN_STATUS_SUCCESS
1823 */
wlan_cmd_multi_chan_policy(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)1824 mlan_status wlan_cmd_multi_chan_policy(pmlan_private pmpriv,
1825 HostCmd_DS_COMMAND *cmd,
1826 t_u16 cmd_action,
1827 t_void *pdata_buf)
1828 {
1829 t_u16 policy = 0;
1830 HostCmd_DS_MULTI_CHAN_POLICY *pmulti_chan_policy = (HostCmd_DS_MULTI_CHAN_POLICY *)&cmd->params.multi_chan_policy;
1831
1832 ENTER();
1833
1834 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MULTI_CHAN_POLICY);
1835 pmulti_chan_policy->action = wlan_cpu_to_le16(cmd_action);
1836 cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_MULTI_CHAN_POLICY));
1837 if (cmd_action == HostCmd_ACT_GEN_SET)
1838 {
1839 policy = *((t_u16 *)pdata_buf);
1840 pmulti_chan_policy->policy = wlan_cpu_to_le16(policy);
1841 PRINTM(MCMND, "Set multi-channel policy: %d\n", policy);
1842 }
1843 LEAVE();
1844 return MLAN_STATUS_SUCCESS;
1845 }
1846
1847 /**
1848 * @brief This function handles the command response of MULTI_CHAN_POLICY
1849 *
1850 * @param pmpriv A pointer to mlan_private structure
1851 * @param resp A pointer to HostCmd_DS_COMMAND
1852 * @param pioctl_buf A pointer to mlan_ioctl_req structure
1853 *
1854 * @return MLAN_STATUS_SUCCESS
1855 */
wlan_ret_multi_chan_policy(pmlan_private pmpriv,const HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)1856 mlan_status wlan_ret_multi_chan_policy(pmlan_private pmpriv, const HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf)
1857 {
1858 mlan_ds_misc_cfg *pcfg = MNULL;
1859 const HostCmd_DS_MULTI_CHAN_POLICY *presp_cfg = &resp->params.multi_chan_policy;
1860
1861 ENTER();
1862
1863 if (pioctl_buf)
1864 {
1865 pcfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
1866 pcfg->param.multi_chan_policy = wlan_le16_to_cpu(presp_cfg->policy);
1867
1868 if (pioctl_buf->action == HostCmd_ACT_GEN_SET)
1869 {
1870 if (pcfg->param.multi_chan_policy)
1871 pmpriv->adapter->mc_policy = MTRUE;
1872 else
1873 pmpriv->adapter->mc_policy = MFALSE;
1874 }
1875 }
1876
1877 LEAVE();
1878 return MLAN_STATUS_SUCCESS;
1879 }
1880
1881 /**
1882 * @brief This function prepares the command DRCD_CFG
1883 *
1884 * @param pmpriv A pointer to mlan_private structure
1885 * @param cmd A pointer to HostCmd_DS_COMMAND structure
1886 * @param cmd_action Command action: GET or SET
1887 * @param pdata_buf A pointer to new setting buf
1888 *
1889 * @return MLAN_STATUS_SUCCESS
1890 */
wlan_cmd_drcs_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)1891 mlan_status wlan_cmd_drcs_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, t_u16 cmd_action, t_void *pdata_buf)
1892 {
1893 mlan_ds_drcs_cfg *drcs_cfg = (mlan_ds_drcs_cfg *)pdata_buf;
1894 HostCmd_DS_DRCS_CFG *pdrcs_cfg = (HostCmd_DS_DRCS_CFG *)&cmd->params.drcs_cfg;
1895 MrvlTypes_DrcsTimeSlice_t *channel_time_slicing = &pdrcs_cfg->time_slicing;
1896
1897 ENTER();
1898
1899 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_DRCS_CONFIG);
1900 pdrcs_cfg->action = wlan_cpu_to_le16(cmd_action);
1901
1902 if (cmd_action == HostCmd_ACT_GEN_SET)
1903 {
1904 channel_time_slicing->header.type = wlan_cpu_to_le16(MRVL_DRCS_TIME_SLICE_TLV_ID);
1905 channel_time_slicing->header.len =
1906 wlan_cpu_to_le16(sizeof(MrvlTypes_DrcsTimeSlice_t) - sizeof(MrvlIEtypesHeader_t));
1907 channel_time_slicing->chan_idx = wlan_cpu_to_le16(drcs_cfg->chan_idx);
1908 channel_time_slicing->chantime = drcs_cfg->chantime;
1909 channel_time_slicing->switchtime = drcs_cfg->switchtime;
1910 channel_time_slicing->undozetime = drcs_cfg->undozetime;
1911 channel_time_slicing->mode = drcs_cfg->mode;
1912 PRINTM(MCMND, "Set multi-channel: chan_idx=%d chantime=%d switchtime=%d undozetime=%d mode=%d\n",
1913 channel_time_slicing->chan_idx, channel_time_slicing->chantime, channel_time_slicing->switchtime,
1914 channel_time_slicing->undozetime, channel_time_slicing->mode);
1915 cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_DRCS_CFG));
1916 /* Set two channels different parameters */
1917 if (0x3 != channel_time_slicing->chan_idx)
1918 {
1919 drcs_cfg++;
1920 channel_time_slicing = pdrcs_cfg->drcs_buf;
1921 channel_time_slicing->header.type = wlan_cpu_to_le16(MRVL_DRCS_TIME_SLICE_TLV_ID);
1922 channel_time_slicing->header.len =
1923 wlan_cpu_to_le16(sizeof(MrvlTypes_DrcsTimeSlice_t) - sizeof(MrvlIEtypesHeader_t));
1924 channel_time_slicing->chan_idx = wlan_cpu_to_le16(drcs_cfg->chan_idx);
1925 channel_time_slicing->chantime = drcs_cfg->chantime;
1926 channel_time_slicing->switchtime = drcs_cfg->switchtime;
1927 channel_time_slicing->undozetime = drcs_cfg->undozetime;
1928 channel_time_slicing->mode = drcs_cfg->mode;
1929 PRINTM(MCMND, "Set multi-channel: chan_idx=%d chantime=%d switchtime=%d undozetime=%d mode=%d\n",
1930 channel_time_slicing->chan_idx, channel_time_slicing->chantime, channel_time_slicing->switchtime,
1931 channel_time_slicing->undozetime, channel_time_slicing->mode);
1932 cmd->size += wlan_cpu_to_le16(sizeof(MrvlTypes_DrcsTimeSlice_t));
1933 }
1934 }
1935 else
1936 {
1937 cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(cmd_action));
1938 }
1939
1940 LEAVE();
1941 return MLAN_STATUS_SUCCESS;
1942 }
1943
1944 /**
1945 * @brief This function handles the command response of DRCS_CFG
1946 *
1947 * @param pmpriv A pointer to mlan_private structure
1948 * @param resp A pointer to HostCmd_DS_COMMAND
1949 * @param pioctl_buf A pointer to mlan_ioctl_req structure
1950 *
1951 * @return MLAN_STATUS_SUCCESS
1952 */
wlan_ret_drcs_cfg(pmlan_private pmpriv,const HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)1953 mlan_status wlan_ret_drcs_cfg(pmlan_private pmpriv, const HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf)
1954 {
1955 mlan_ds_misc_cfg *pcfg = MNULL;
1956 const HostCmd_DS_DRCS_CFG *presp_cfg = &resp->params.drcs_cfg;
1957 const MrvlTypes_DrcsTimeSlice_t *channel_time_slicing = &presp_cfg->time_slicing;
1958 const MrvlTypes_DrcsTimeSlice_t *channel_time_slicing1 = MNULL;
1959 mlan_ds_drcs_cfg *drcs_cfg1 = MNULL;
1960
1961 ENTER();
1962
1963 if (pioctl_buf)
1964 {
1965 pcfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
1966 if (wlan_le16_to_cpu(channel_time_slicing->header.type) != MRVL_DRCS_TIME_SLICE_TLV_ID ||
1967 wlan_le16_to_cpu(channel_time_slicing->header.len) !=
1968 sizeof(MrvlTypes_DrcsTimeSlice_t) - sizeof(MrvlIEtypesHeader_t))
1969 {
1970 LEAVE();
1971 return MLAN_STATUS_FAILURE;
1972 }
1973 pcfg->param.drcs_cfg[0].chan_idx = wlan_le16_to_cpu(channel_time_slicing->chan_idx);
1974 pcfg->param.drcs_cfg[0].chantime = channel_time_slicing->chantime;
1975 pcfg->param.drcs_cfg[0].switchtime = channel_time_slicing->switchtime;
1976 pcfg->param.drcs_cfg[0].undozetime = channel_time_slicing->undozetime;
1977 pcfg->param.drcs_cfg[0].mode = channel_time_slicing->mode;
1978 PRINTM(MCMND, "multi-channel: chan_idx=%d chantime=%d switchtime=%d undozetime=%d mode=%d\n",
1979 pcfg->param.drcs_cfg[0].chan_idx, channel_time_slicing->chantime, channel_time_slicing->switchtime,
1980 channel_time_slicing->undozetime, channel_time_slicing->mode);
1981 pioctl_buf->buf_len = sizeof(mlan_ds_drcs_cfg);
1982 /*Channel for chan_idx 1 and 2 have different parameters*/
1983 if (0x3 != pcfg->param.drcs_cfg[0].chan_idx)
1984 {
1985 channel_time_slicing1 = presp_cfg->drcs_buf;
1986 if (wlan_le16_to_cpu(channel_time_slicing1->header.type) != MRVL_DRCS_TIME_SLICE_TLV_ID ||
1987 wlan_le16_to_cpu(channel_time_slicing1->header.len) !=
1988 sizeof(MrvlTypes_DrcsTimeSlice_t) - sizeof(MrvlIEtypesHeader_t))
1989 {
1990 LEAVE();
1991 return MLAN_STATUS_FAILURE;
1992 }
1993 drcs_cfg1 = (mlan_ds_drcs_cfg *)&pcfg->param.drcs_cfg[1];
1994 drcs_cfg1->chan_idx = wlan_le16_to_cpu(channel_time_slicing1->chan_idx);
1995 drcs_cfg1->chantime = channel_time_slicing1->chantime;
1996 drcs_cfg1->switchtime = channel_time_slicing1->switchtime;
1997 drcs_cfg1->undozetime = channel_time_slicing1->undozetime;
1998 drcs_cfg1->mode = channel_time_slicing1->mode;
1999 PRINTM(MCMND, "multi-channel: chan_idx=%d chantime=%d switchtime=%d undozetime=%d mode=%d\n",
2000 drcs_cfg1->chan_idx, drcs_cfg1->chantime, drcs_cfg1->switchtime, drcs_cfg1->undozetime,
2001 drcs_cfg1->mode);
2002 pioctl_buf->buf_len += sizeof(mlan_ds_drcs_cfg);
2003 }
2004 }
2005
2006 LEAVE();
2007 return MLAN_STATUS_SUCCESS;
2008 }
2009 #endif
2010
2011 #if CONFIG_1AS
2012 /**
2013 * @brief This function prepares command of sending host_clock_cfg.
2014 *
2015 * @param cmd A pointer to HostCmd_DS_COMMAND structure
2016 * @param cmd_action the action: GET or SET
2017 * @param pdata_buf A pointer to data buffer
2018 * @return MLAN_STATUS_SUCCESS
2019 */
wlan_cmd_host_clock_cfg(HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)2020 mlan_status wlan_cmd_host_clock_cfg(HostCmd_DS_COMMAND *cmd, t_u16 cmd_action, t_void *pdata_buf)
2021 {
2022 mlan_ds_host_clock *hostclk = (mlan_ds_host_clock *)pdata_buf;
2023 HostCmd_DS_HOST_CLOCK_CFG *host_clock = (HostCmd_DS_HOST_CLOCK_CFG *)&cmd->params.host_clock_cfg;
2024
2025 ENTER();
2026
2027 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_HOST_CLOCK_CFG);
2028 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_HOST_CLOCK_CFG) + S_DS_GEN);
2029
2030 host_clock->action = wlan_cpu_to_le16(cmd_action);
2031 host_clock->time = wlan_cpu_to_le64(hostclk->time);
2032
2033 LEAVE();
2034 return MLAN_STATUS_SUCCESS;
2035 }
2036
2037 /**
2038 * @brief This function handles the command response of host_clock_cfg
2039 *
2040 * @param pmpriv A pointer to mlan_private structure
2041 * @param resp A pointer to HostCmd_DS_COMMAND
2042 * @param pioctl_buf A pointer to command buffer
2043 *
2044 * @return MLAN_STATUS_SUCCESS
2045 */
wlan_ret_host_clock_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)2046 mlan_status wlan_ret_host_clock_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf)
2047 {
2048 mlan_ds_misc_cfg *cfg = MNULL;
2049 mlan_ds_host_clock *hostclk = MNULL;
2050 HostCmd_DS_HOST_CLOCK_CFG *host_clock = (HostCmd_DS_HOST_CLOCK_CFG *)&resp->params.host_clock_cfg;
2051 // mlan_adapter *pmadapter = pmpriv->adapter;
2052 // pmlan_callbacks pcb = &pmadapter->callbacks;
2053 // t_u64 cmd_rtt;
2054
2055 ENTER();
2056
2057 if (pioctl_buf)
2058 {
2059 cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
2060 hostclk = &cfg->param.host_clock;
2061
2062 hostclk->time = wlan_le64_to_cpu(host_clock->time);
2063 // cmd_rtt = pcb->moal_do_div(pmadapter->d2 - pmadapter->d1, 2);
2064 // PRINTM(MINFO, "HW time: %ld, Host Time: %ld, RTT: %ld\n",
2065 // host_clock->hw_time, hostclk->time, cmd_rtt);
2066 hostclk->fw_time = wlan_le64_to_cpu(host_clock->hw_time) /*- cmd_rtt*/; // Not adjusting
2067 // cmd_rtt gave
2068 // better results
2069 // with 802.1as
2070 hostclk->host_bbu_clk_delta = hostclk->time - hostclk->fw_time;
2071 // pmadapter->host_bbu_clk_delta = hostclk->host_bbu_clk_delta;
2072
2073 /* Indicate ioctl complete */
2074 // pioctl_buf->data_read_written =
2075 // sizeof(mlan_ds_misc_cfg) + MLAN_SUB_COMMAND_SIZE;
2076 }
2077
2078 LEAVE();
2079 return MLAN_STATUS_SUCCESS;
2080 }
2081 #endif
2082
2083 #if CONFIG_FW_VDLL
2084
2085 extern const unsigned char wlan_fw_bin[];
2086 extern unsigned int wlan_fw_bin_len;
2087
2088 /**
2089 * @brief This function download the vdll block.
2090 *
2091 * @param pmadapter A pointer to mlan_adapter structure
2092 * @param block A pointer to VDLL block
2093 * @param block_len The VDLL block length
2094 *
2095 * @return MLAN_STATUS_SUCCESS
2096 */
wlan_download_vdll_block(mlan_adapter * pmadapter,t_u8 * block,t_u16 block_len)2097 mlan_status wlan_download_vdll_block(mlan_adapter *pmadapter, t_u8 *block, t_u16 block_len)
2098 {
2099 mlan_status status = MLAN_STATUS_FAILURE;
2100 int ret = -WM_FAIL;
2101 pvdll_dnld_ctrl ctrl = &pmadapter->vdll_ctrl;
2102 t_u16 msg_len = block_len + sizeof(HostCmd_DS_GEN);
2103 HostCmd_DS_GEN *cmd_hdr;
2104
2105 ENTER();
2106
2107 if ((msg_len > WIFI_FW_CMDBUF_SIZE) || (ctrl == NULL))
2108 {
2109 wevt_d("VDLL block mem greater than cmd buf/vdll struct not inited");
2110 goto done;
2111 }
2112
2113 cmd_hdr = (HostCmd_DS_GEN *)ctrl->cmd_buf;
2114
2115 cmd_hdr->command = wlan_cpu_to_le16(HostCmd_CMD_VDLL);
2116 cmd_hdr->seq_num = wlan_cpu_to_le16(0xFF00);
2117 cmd_hdr->size = wlan_cpu_to_le16(msg_len);
2118
2119 (void)__memcpy(pmadapter, ctrl->cmd_buf + sizeof(HostCmd_DS_GEN), block, block_len);
2120
2121 #if CONFIG_FW_VDLL_DEBUG
2122 wevt_d("DNLD_VDLL : block_len=%d", block_len);
2123 #endif
2124
2125 ret = wifi_wait_for_vdllcmdresp(NULL);
2126
2127 if (ret == -WM_FAIL)
2128 {
2129 wevt_d("DNLD_VDLL: Host to Card Failed");
2130 }
2131 else
2132 {
2133 status = MLAN_STATUS_SUCCESS;
2134 }
2135
2136 done:
2137 LEAVE();
2138 return status;
2139 }
2140
2141 /**
2142 * @brief The function Get the VDLL image from moal
2143 *
2144 * @param pmadapter A pointer to mlan_adapter structure
2145 * @param offset offset
2146 *
2147 * @return MLAN_STATUS_SUCCESS
2148 *
2149 */
wlan_get_vdll_image(pmlan_adapter pmadapter,t_u32 vdll_len)2150 static mlan_status wlan_get_vdll_image(pmlan_adapter pmadapter, t_u32 vdll_len)
2151 {
2152 /*Since f/w is already in .h in RT so we will use the offsets directly*/
2153
2154 vdll_dnld_ctrl *ctrl = &pmadapter->vdll_ctrl;
2155 ENTER();
2156 if (ctrl != NULL)
2157 {
2158 ctrl->vdll_mem = (t_u8 *)(pmadapter->fw_start_addr + (wlan_fw_bin_len - vdll_len));
2159 ctrl->vdll_len = vdll_len;
2160 ctrl->cmd_buf = (t_u8 *)wifi_get_vdllcommand_buffer();
2161 }
2162 LEAVE();
2163 return MLAN_STATUS_SUCCESS;
2164 }
2165
2166 /**
2167 * @brief This function handle the multi_chan info event
2168 *
2169 * @param pmpriv A pointer to mlan_private structure
2170 * @param pevent A pointer to event buffer
2171 *
2172 * @return MLAN_STATUS_SUCCESS
2173 */
wlan_process_vdll_event(pmlan_private pmpriv,t_u8 * pevent)2174 mlan_status wlan_process_vdll_event(pmlan_private pmpriv, t_u8 *pevent)
2175 {
2176 mlan_status status = MLAN_STATUS_SUCCESS;
2177 vdll_ind *ind = MNULL;
2178 t_u32 offset = 0;
2179 t_u16 block_len = 0;
2180 mlan_adapter *pmadapter = pmpriv->adapter;
2181 vdll_dnld_ctrl *ctrl = &pmadapter->vdll_ctrl;
2182
2183 ENTER();
2184 ind = (vdll_ind *)(pevent + sizeof(mlan_event_id));
2185
2186 switch (wlan_le16_to_cpu(ind->type))
2187 {
2188 case VDLL_IND_TYPE_REQ:
2189 offset = wlan_le32_to_cpu(ind->offset);
2190 block_len = wlan_le16_to_cpu(ind->block_len);
2191 #if CONFIG_FW_VDLL_DEBUG
2192 wevt_d("VDLL_IND: type=%d offset = 0x%x, len = %d, vdll_len=0x%x", wlan_le16_to_cpu(ind->type), offset,
2193 block_len, ctrl->vdll_len);
2194 #endif
2195 if (offset <= ctrl->vdll_len)
2196 {
2197 block_len = MIN(block_len, ctrl->vdll_len - offset);
2198 status = wlan_download_vdll_block(pmadapter, ctrl->vdll_mem + offset, block_len);
2199 if (status)
2200 {
2201 wevt_d("Fail to download VDLL block");
2202 }
2203 if (pmadapter->vdll_in_progress == MFALSE)
2204 {
2205 (void)pmadapter->callbacks.moal_start_timer(pmadapter->pmoal_handle, pmadapter->vdll_timer, MFALSE,
2206 2000);
2207 pmadapter->vdll_in_progress = MTRUE;
2208 }
2209 else
2210 {
2211 (void)pmadapter->callbacks.moal_reset_timer(pmadapter->pmoal_handle, pmadapter->vdll_timer);
2212 }
2213 }
2214 else
2215 {
2216 wevt_d("Invalid VDLL req: offset=0x%x, len=%d, vdll_len=0x%x", offset, block_len, ctrl->vdll_len);
2217 }
2218 break;
2219
2220 case VDLL_IND_TYPE_OFFSET:
2221 offset = wlan_le32_to_cpu(ind->offset);
2222 #if CONFIG_FW_VDLL_DEBUG
2223 wevt_d("VDLL_IND (OFFSET): vdll_len=0x%x", offset);
2224 #endif
2225 wlan_get_vdll_image(pmadapter, offset);
2226 break;
2227 case VDLL_IND_TYPE_ERR_SIG:
2228 wevt_d("VDLL_IND (SIG ERR).");
2229 break;
2230 case VDLL_IND_TYPE_ERR_ID:
2231 wevt_d("VDLL_IND (ID ERR).");
2232 break;
2233 #if defined(SD9177)
2234 case VDLL_IND_TYPE_ERR_SECURE:
2235 wevt_d("VDLL_IND (SECURE ERR).");
2236 break;
2237 case VDLL_IND_TYPE_COMPLETE:
2238 wevt_d("VDLL_IND (ID COMPLETE).");
2239 break;
2240 #elif defined(SD8978) || defined(SD8987) || defined(SD8997)
2241 case VDLL_IND_TYPE_INTF_RESET:
2242 wevt_d("VDLLV2_IND (INTF RESET).");
2243 sd_wifi_reset_ports();
2244 break;
2245 #endif
2246 default:
2247 wevt_d("unknown vdll ind type=%d", ind->type);
2248 break;
2249 }
2250 LEAVE();
2251 return status;
2252 }
2253 #endif /* CONFIG_FW_VDLL */
2254
2255 #if (CONFIG_WIFI_IND_RESET) && (CONFIG_WIFI_IND_DNLD)
2256 /**
2257 * @brief This function prepares command of independent reset.
2258 *
2259 * @param cmd A pointer to HostCmd_DS_COMMAND structure
2260 * @param cmd_action the action: GET or SET
2261 * @param pdata_buf A pointer to data buffer
2262 * @return MLAN_STATUS_SUCCESS
2263 */
wlan_cmd_ind_rst_cfg(HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)2264 mlan_status wlan_cmd_ind_rst_cfg(HostCmd_DS_COMMAND *cmd, t_u16 cmd_action, t_void *pdata_buf)
2265 {
2266 mlan_ds_ind_rst_cfg *pdata_ind_rst = (mlan_ds_ind_rst_cfg *)pdata_buf;
2267 HostCmd_DS_INDEPENDENT_RESET_CFG *ind_rst_cfg = (HostCmd_DS_INDEPENDENT_RESET_CFG *)&cmd->params.ind_rst_cfg;
2268
2269 ENTER();
2270
2271 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_INDEPENDENT_RESET_CFG);
2272 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_INDEPENDENT_RESET_CFG) + S_DS_GEN);
2273
2274 ind_rst_cfg->action = wlan_cpu_to_le16(cmd_action);
2275 if (cmd_action == HostCmd_ACT_GEN_SET)
2276 {
2277 ind_rst_cfg->ir_mode = pdata_ind_rst->ir_mode;
2278 ind_rst_cfg->gpio_pin = pdata_ind_rst->gpio_pin;
2279 }
2280
2281 LEAVE();
2282 return MLAN_STATUS_SUCCESS;
2283 }
2284 /**
2285 * @brief This function handles the command response of independent reset
2286 *
2287 * @param pmpriv A pointer to mlan_private structure
2288 * @param resp A pointer to HostCmd_DS_COMMAND
2289 * @param pioctl_buf A pointer to command buffer
2290 *
2291 * @return MLAN_STATUS_SUCCESS
2292 */
wlan_ret_ind_rst_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)2293 mlan_status wlan_ret_ind_rst_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf)
2294 {
2295 mlan_ds_misc_cfg *misc = MNULL;
2296 const HostCmd_DS_INDEPENDENT_RESET_CFG *ind_rst_cfg = (HostCmd_DS_INDEPENDENT_RESET_CFG *)&resp->params.ind_rst_cfg;
2297
2298 ENTER();
2299
2300 if (pioctl_buf)
2301 {
2302 misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
2303
2304 if (wlan_le16_to_cpu(ind_rst_cfg->action) == HostCmd_ACT_GEN_GET)
2305 {
2306 misc->param.ind_rst_cfg.ir_mode = ind_rst_cfg->ir_mode;
2307 misc->param.ind_rst_cfg.gpio_pin = ind_rst_cfg->gpio_pin;
2308 }
2309 }
2310
2311 LEAVE();
2312 return MLAN_STATUS_SUCCESS;
2313 }
2314 #endif
2315
2316 /**
2317 * @brief This function sends boot sleep configure command to firmware.
2318 *
2319 * @param pmpriv A pointer to mlan_private structure
2320 * @param cmd Hostcmd ID
2321 * @param cmd_action Command action
2322 * @param pdata_buf A void pointer to information buffer
2323 * @return MLAN_STATUS_SUCCESS/ MLAN_STATUS_FAILURE
2324 */
wlan_cmd_boot_sleep(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)2325 mlan_status wlan_cmd_boot_sleep(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, t_u16 cmd_action, t_void *pdata_buf)
2326 {
2327 HostCmd_DS_BOOT_SLEEP *boot_sleep = MNULL;
2328 t_u16 enable = *(t_u16 *)pdata_buf;
2329
2330 ENTER();
2331
2332 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_BOOT_SLEEP);
2333 boot_sleep = &cmd->params.boot_sleep;
2334 boot_sleep->action = wlan_cpu_to_le16(cmd_action);
2335 boot_sleep->enable = wlan_cpu_to_le16(enable);
2336
2337 cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_BOOT_SLEEP));
2338
2339 LEAVE();
2340 return MLAN_STATUS_SUCCESS;
2341 }
2342
2343 /**
2344 * @brief This function handles the command response of boot sleep cfg
2345 *
2346 * @param pmpriv A pointer to mlan_private structure
2347 * @param resp A pointer to HostCmd_DS_COMMAND
2348 * @param pioctl_buf A pointer to mlan_ioctl_req structure
2349 *
2350 * @return MLAN_STATUS_SUCCESS
2351 */
wlan_ret_boot_sleep(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)2352 mlan_status wlan_ret_boot_sleep(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf)
2353 {
2354 HostCmd_DS_BOOT_SLEEP *boot_sleep = &resp->params.boot_sleep;
2355 mlan_ds_misc_cfg *cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
2356
2357 ENTER();
2358
2359 cfg->param.boot_sleep = wlan_le16_to_cpu(boot_sleep->enable);
2360 PRINTM(MCMND, "boot sleep cfg status %u", cfg->param.boot_sleep);
2361 LEAVE();
2362 return MLAN_STATUS_SUCCESS;
2363 }
2364
2365 /**
2366 * @brief This function prepares command of hs wakeup reason.
2367 *
2368 * @param pmpriv A pointer to mlan_private structure
2369 * @param cmd A pointer to HostCmd_DS_COMMAND structure
2370 * @param pdata_buf A pointer to data buffer
2371 * @return MLAN_STATUS_SUCCESS
2372 */
wlan_cmd_hs_wakeup_reason(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_void * pdata_buf)2373 mlan_status wlan_cmd_hs_wakeup_reason(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, t_void *pdata_buf)
2374 {
2375 ENTER();
2376
2377 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_HS_WAKEUP_REASON);
2378 cmd->size = wlan_cpu_to_le16((sizeof(HostCmd_DS_HS_WAKEUP_REASON)) + S_DS_GEN);
2379
2380 LEAVE();
2381 return MLAN_STATUS_SUCCESS;
2382 }
2383
2384 /**
2385 * @brief This function handles the command response of
2386 * hs wakeup reason
2387 *
2388 * @param pmpriv A pointer to mlan_private structure
2389 * @param resp A pointer to HostCmd_DS_COMMAND
2390 * @param pioctl_buf A pointer to command buffer
2391 *
2392 * @return MLAN_STATUS_SUCCESS
2393 */
wlan_ret_hs_wakeup_reason(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)2394 mlan_status wlan_ret_hs_wakeup_reason(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf)
2395 {
2396 HostCmd_DS_HS_WAKEUP_REASON *hs_wakeup_reason = (HostCmd_DS_HS_WAKEUP_REASON *)&resp->params.hs_wakeup_reason;
2397 mlan_ds_pm_cfg *pm_cfg = MNULL;
2398
2399 ENTER();
2400
2401 pm_cfg = (mlan_ds_pm_cfg *)pioctl_buf->pbuf;
2402 pm_cfg->param.wakeup_reason.hs_wakeup_reason = wlan_le16_to_cpu(hs_wakeup_reason->wakeup_reason);
2403 pioctl_buf->data_read_written = sizeof(mlan_ds_pm_cfg);
2404
2405 LEAVE();
2406 return MLAN_STATUS_SUCCESS;
2407 }
2408
2409 /**
2410 * @brief This function prepares command of TX_FRAME
2411 *
2412 * @param pmpriv A pointer to mlan_private structure
2413 * @param cmd A pointer to HostCmd_DS_COMMAND structure
2414 * @param cmd_action the action: GET or SET
2415 * @param pdata_buf A pointer to data buffer
2416 * @return MLAN_STATUS_SUCCESS
2417 */
wlan_cmd_tx_frame(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)2418 mlan_status wlan_cmd_tx_frame(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, t_u16 cmd_action, t_void *pdata_buf)
2419 {
2420 t_u16 cmd_size = 0;
2421 HostCmd_DS_80211_TX_FRAME *tx_frame_cmd = &cmd->params.tx_frame;
2422 mlan_ds_misc_tx_frame *tx_frame = (mlan_ds_misc_tx_frame *)pdata_buf;
2423 TxPD *plocal_tx_pd = (TxPD *)tx_frame_cmd->buffer;
2424 t_u32 pkt_type = 0;
2425 t_u32 tx_control = 0;
2426 t_u8 *pdata = tx_frame->tx_buf;
2427 t_u16 data_len = tx_frame->data_len;
2428
2429 ENTER();
2430 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_TX_FRAME);
2431 cmd_size = sizeof(HostCmd_DS_80211_TX_FRAME) + S_DS_GEN;
2432 tx_frame_cmd->action = 0;
2433 tx_frame_cmd->status = 0;
2434 (void)__memcpy(pmpriv->adapter, &tx_frame_cmd->band_config, (t_u8 *)&tx_frame->bandcfg, sizeof(t_u8));
2435 tx_frame_cmd->channel = tx_frame->channel;
2436
2437 if (tx_frame->buf_type == MLAN_BUF_TYPE_RAW_DATA)
2438 {
2439 (void)__memcpy(pmpriv->adapter, &pkt_type, tx_frame->tx_buf, sizeof(pkt_type));
2440 (void)__memcpy(pmpriv->adapter, &tx_control, tx_frame->tx_buf + sizeof(pkt_type), sizeof(tx_control));
2441 data_len -= sizeof(pkt_type) + sizeof(tx_control);
2442 pdata += sizeof(pkt_type) + sizeof(tx_control);
2443 }
2444 (void)__memcpy(pmpriv->adapter, tx_frame_cmd->buffer + sizeof(TxPD), pdata, data_len);
2445
2446 (void)__memset(pmpriv->adapter, plocal_tx_pd, 0, sizeof(TxPD));
2447 plocal_tx_pd->bss_num = GET_BSS_NUM(pmpriv);
2448 plocal_tx_pd->bss_type = pmpriv->bss_type;
2449 plocal_tx_pd->tx_pkt_length = (t_u16)data_len;
2450 plocal_tx_pd->priority = (t_u8)tx_frame->priority;
2451 plocal_tx_pd->tx_pkt_offset = sizeof(TxPD);
2452 plocal_tx_pd->pkt_delay_2ms = 0xff;
2453
2454 if (tx_frame->buf_type == MLAN_BUF_TYPE_RAW_DATA)
2455 {
2456 plocal_tx_pd->tx_pkt_type = (t_u16)pkt_type;
2457 plocal_tx_pd->tx_control = tx_control;
2458 }
2459
2460 if (tx_frame->flags & MLAN_BUF_FLAG_TX_STATUS)
2461 {
2462 #ifdef TXPD_RXPD_V3
2463 plocal_tx_pd->tx_control_1 |= tx_frame->tx_seq_num << 8;
2464 #else
2465 plocal_tx_pd->tx_token_id = (t_u8)tx_frame->tx_seq_num;
2466 #endif
2467 plocal_tx_pd->flags |= MRVDRV_TxPD_FLAGS_TX_PACKET_STATUS;
2468 }
2469
2470 endian_convert_TxPD(plocal_tx_pd);
2471 cmd_size += sizeof(TxPD) + data_len;
2472 cmd->size = wlan_cpu_to_le16(cmd_size);
2473
2474 LEAVE();
2475 return MLAN_STATUS_SUCCESS;
2476 }
2477