1 /** @file mlan_sta_cmd.c
2 *
3 * @brief This file contains the handling of command.
4 * it prepares command and sends it to firmware when
5 * it is ready.
6 *
7 *
8 * Copyright 2008-2022 NXP
9 *
10 * This software file (the File) is distributed by NXP
11 * under the terms of the GNU General Public License Version 2, June 1991
12 * (the License). You may use, redistribute and/or modify the File in
13 * accordance with the terms and conditions of the License, a copy of which
14 * is available by writing to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
16 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
17 *
18 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
20 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
21 * this warranty disclaimer.
22 *
23 */
24
25 /******************************************************
26 * Change log:
27 * 10/21/2008: initial version
28 ******************************************************/
29
30 #include "mlan.h"
31 #include "mlan_join.h"
32 #include "mlan_util.h"
33 #include "mlan_fw.h"
34 #include "mlan_main.h"
35 #include "mlan_wmm.h"
36 #include "mlan_11n.h"
37 #include "mlan_11ac.h"
38 #include "mlan_11ax.h"
39 #include "mlan_11h.h"
40 #ifdef SDIO
41 #include "mlan_sdio.h"
42 #endif /* SDIO */
43 #include "mlan_meas.h"
44 #ifdef PCIE
45 #include "mlan_pcie.h"
46 #endif /* PCIE */
47
48 /********************************************************
49 * Local Variables
50 ********************************************************/
51
52 /********************************************************
53 * Global Variables
54 ********************************************************/
55
56 /********************************************************
57 * Local Functions
58 ********************************************************/
59
60 /**
61 * @brief This function prepares command of RSSI info.
62 *
63 * @param pmpriv A pointer to mlan_private structure
64 * @param pcmd A pointer to HostCmd_DS_COMMAND structure
65 * @param cmd_action Command action
66 *
67 * @return MLAN_STATUS_SUCCESS
68 */
wlan_cmd_802_11_rssi_info(pmlan_private pmpriv,HostCmd_DS_COMMAND * pcmd,t_u16 cmd_action)69 static mlan_status wlan_cmd_802_11_rssi_info(pmlan_private pmpriv,
70 HostCmd_DS_COMMAND *pcmd,
71 t_u16 cmd_action)
72 {
73 ENTER();
74
75 pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_RSSI_INFO);
76 pcmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_RSSI_INFO) +
77 S_DS_GEN);
78 pcmd->params.rssi_info.action = wlan_cpu_to_le16(cmd_action);
79 pcmd->params.rssi_info.ndata =
80 wlan_cpu_to_le16(pmpriv->data_avg_factor);
81 pcmd->params.rssi_info.nbcn = wlan_cpu_to_le16(pmpriv->bcn_avg_factor);
82
83 /* Reset SNR/NF/RSSI values in private structure */
84 pmpriv->data_rssi_last = 0;
85 pmpriv->data_nf_last = 0;
86 pmpriv->data_rssi_avg = 0;
87 pmpriv->data_nf_avg = 0;
88 pmpriv->bcn_rssi_last = 0;
89 pmpriv->bcn_nf_last = 0;
90 pmpriv->bcn_rssi_avg = 0;
91 pmpriv->bcn_nf_avg = 0;
92
93 LEAVE();
94 return MLAN_STATUS_SUCCESS;
95 }
96
97 /**
98 * @brief This function prepares command of RSSI info.
99 *
100 * @param pmpriv A pointer to mlan_private structure
101 * @param pcmd A pointer to HostCmd_DS_COMMAND structure
102 * @param cmd_action Command action
103 *
104 * @return MLAN_STATUS_SUCCESS
105 */
wlan_cmd_802_11_rssi_info_ext(pmlan_private pmpriv,HostCmd_DS_COMMAND * pcmd,t_u16 cmd_action,t_void * pdata_buf)106 static mlan_status wlan_cmd_802_11_rssi_info_ext(pmlan_private pmpriv,
107 HostCmd_DS_COMMAND *pcmd,
108 t_u16 cmd_action,
109 t_void *pdata_buf)
110 {
111 HostCmd_DS_802_11_RSSI_INFO_EXT *rssi_info_ext_cmd =
112 &pcmd->params.rssi_info_ext;
113 mlan_ds_get_info *info = (mlan_ds_get_info *)pdata_buf;
114 MrvlIEtypes_RSSI_EXT_t *signal_info_tlv = MNULL;
115 t_u8 *pos = MNULL;
116
117 ENTER();
118
119 pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_RSSI_INFO_EXT);
120 pcmd->size = sizeof(HostCmd_DS_802_11_RSSI_INFO_EXT) + S_DS_GEN;
121 rssi_info_ext_cmd->action = wlan_cpu_to_le16(cmd_action);
122 rssi_info_ext_cmd->ndata = 0;
123 rssi_info_ext_cmd->nbcn = 0;
124
125 if (info->param.path_id) {
126 pos = (t_u8 *)rssi_info_ext_cmd->tlv_buf;
127 signal_info_tlv = (MrvlIEtypes_RSSI_EXT_t *)pos;
128 signal_info_tlv->header.len =
129 wlan_cpu_to_le16(sizeof(MrvlIEtypes_RSSI_EXT_t) -
130 sizeof(MrvlIEtypesHeader_t));
131 signal_info_tlv->header.type =
132 wlan_cpu_to_le16(TLV_TYPE_RSSI_INFO);
133 signal_info_tlv->path_id =
134 wlan_cpu_to_le16(info->param.path_id);
135 pcmd->size += sizeof(MrvlIEtypes_RSSI_EXT_t);
136 }
137 pcmd->size = wlan_cpu_to_le16(pcmd->size);
138 LEAVE();
139 return MLAN_STATUS_SUCCESS;
140 }
141
142 /**
143 * @brief This function prepares command of snmp_mib.
144 *
145 * @param pmpriv A pointer to mlan_private structure
146 * @param cmd A pointer to HostCmd_DS_COMMAND structure
147 * @param cmd_action The action: GET or SET
148 * @param cmd_oid OID: ENABLE or DISABLE
149 * @param pdata_buf A pointer to command information buffer
150 *
151 * @return MLAN_STATUS_SUCCESS
152 */
wlan_cmd_802_11_snmp_mib(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_u32 cmd_oid,t_void * pdata_buf)153 static mlan_status wlan_cmd_802_11_snmp_mib(pmlan_private pmpriv,
154 HostCmd_DS_COMMAND *cmd,
155 t_u16 cmd_action, t_u32 cmd_oid,
156 t_void *pdata_buf)
157 {
158 HostCmd_DS_802_11_SNMP_MIB *psnmp_mib = &cmd->params.smib;
159 t_u32 ul_temp;
160
161 ENTER();
162 PRINTM(MINFO, "SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
163 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
164 cmd->size = sizeof(HostCmd_DS_802_11_SNMP_MIB) - 1 + S_DS_GEN;
165
166 if (cmd_action == HostCmd_ACT_GEN_GET) {
167 psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_GET);
168 psnmp_mib->buf_size = wlan_cpu_to_le16(MAX_SNMP_BUF_SIZE);
169 cmd->size += MAX_SNMP_BUF_SIZE;
170 }
171
172 switch (cmd_oid) {
173 case DtimPeriod_i:
174 psnmp_mib->oid = wlan_cpu_to_le16((t_u16)DtimPeriod_i);
175 if (cmd_action == HostCmd_ACT_GEN_SET) {
176 psnmp_mib->query_type =
177 wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
178 psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u8));
179 ul_temp = *((t_u32 *)pdata_buf);
180 psnmp_mib->value[0] = (t_u8)ul_temp;
181 cmd->size += sizeof(t_u8);
182 }
183 break;
184 case FragThresh_i:
185 psnmp_mib->oid = wlan_cpu_to_le16((t_u16)FragThresh_i);
186 if (cmd_action == HostCmd_ACT_GEN_SET) {
187 psnmp_mib->query_type =
188 wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
189 psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
190 ul_temp = *((t_u32 *)pdata_buf);
191 *((t_u16 *)(psnmp_mib->value)) =
192 wlan_cpu_to_le16((t_u16)ul_temp);
193 cmd->size += sizeof(t_u16);
194 }
195 break;
196 case RtsThresh_i:
197 psnmp_mib->oid = wlan_cpu_to_le16((t_u16)RtsThresh_i);
198 if (cmd_action == HostCmd_ACT_GEN_SET) {
199 psnmp_mib->query_type =
200 wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
201 psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
202 ul_temp = *((t_u32 *)pdata_buf);
203 *(t_u16 *)(psnmp_mib->value) =
204 wlan_cpu_to_le16((t_u16)ul_temp);
205 cmd->size += sizeof(t_u16);
206 }
207 break;
208
209 case ShortRetryLim_i:
210 psnmp_mib->oid = wlan_cpu_to_le16((t_u16)ShortRetryLim_i);
211 if (cmd_action == HostCmd_ACT_GEN_SET) {
212 psnmp_mib->query_type =
213 wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
214 psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
215 ul_temp = (*(t_u32 *)pdata_buf);
216 *((t_u16 *)(psnmp_mib->value)) =
217 wlan_cpu_to_le16((t_u16)ul_temp);
218 cmd->size += sizeof(t_u16);
219 }
220 break;
221 case Dot11D_i:
222 psnmp_mib->oid = wlan_cpu_to_le16((t_u16)Dot11D_i);
223 if (cmd_action == HostCmd_ACT_GEN_SET) {
224 psnmp_mib->query_type =
225 wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
226 psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
227 ul_temp = *(t_u32 *)pdata_buf;
228 *((t_u16 *)(psnmp_mib->value)) =
229 wlan_cpu_to_le16((t_u16)ul_temp);
230 cmd->size += sizeof(t_u16);
231 }
232 break;
233 case Dot11H_i:
234 psnmp_mib->oid = wlan_cpu_to_le16((t_u16)Dot11H_i);
235 if (cmd_action == HostCmd_ACT_GEN_SET) {
236 psnmp_mib->query_type =
237 wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
238 psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
239 ul_temp = *(t_u32 *)pdata_buf;
240 *((t_u16 *)(psnmp_mib->value)) =
241 wlan_cpu_to_le16((t_u16)ul_temp);
242 cmd->size += sizeof(t_u16);
243 }
244 break;
245 case WwsMode_i:
246 psnmp_mib->oid = wlan_cpu_to_le16((t_u16)WwsMode_i);
247 if (cmd_action == HostCmd_ACT_GEN_SET) {
248 psnmp_mib->query_type =
249 wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
250 psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
251 ul_temp = *((t_u32 *)pdata_buf);
252 *((t_u16 *)(psnmp_mib->value)) =
253 wlan_cpu_to_le16((t_u16)ul_temp);
254 cmd->size += sizeof(t_u16);
255 }
256 break;
257 case Thermal_i:
258 psnmp_mib->oid = wlan_cpu_to_le16((t_u16)Thermal_i);
259 break;
260 case NullPktPeriod_i:
261 /** keep alive null data pkt interval in full power mode */
262 psnmp_mib->oid = wlan_cpu_to_le16((t_u16)NullPktPeriod_i);
263 if (cmd_action == HostCmd_ACT_GEN_SET) {
264 psnmp_mib->query_type =
265 wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
266 psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u32));
267 ul_temp = *((t_u32 *)pdata_buf);
268 ul_temp = wlan_cpu_to_le32(ul_temp);
269 memcpy_ext(pmpriv->adapter, psnmp_mib->value, &ul_temp,
270 sizeof(t_u32), sizeof(t_u32));
271 cmd->size += sizeof(t_u32);
272 }
273 break;
274 case ECSAEnable_i:
275 psnmp_mib->oid = wlan_cpu_to_le16((t_u16)ECSAEnable_i);
276 if (cmd_action == HostCmd_ACT_GEN_SET) {
277 psnmp_mib->query_type =
278 wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
279 psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u8));
280 psnmp_mib->value[0] = *((t_u8 *)pdata_buf);
281 cmd->size += sizeof(t_u8);
282 }
283 break;
284 case SignalextEnable_i:
285 psnmp_mib->oid = wlan_cpu_to_le16((t_u16)SignalextEnable_i);
286 if (cmd_action == HostCmd_ACT_GEN_SET) {
287 psnmp_mib->query_type =
288 wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
289 psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u8));
290 psnmp_mib->value[0] = *(t_u8 *)pdata_buf;
291 cmd->size += sizeof(t_u8);
292 }
293 break;
294 case ChanTrackParam_i:
295 psnmp_mib->oid = wlan_cpu_to_le16((t_u16)ChanTrackParam_i);
296 if (cmd_action == HostCmd_ACT_GEN_SET) {
297 psnmp_mib->query_type =
298 wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
299 psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u8));
300 psnmp_mib->value[0] = *(t_u8 *)pdata_buf;
301 cmd->size += sizeof(t_u8);
302 }
303 break;
304 default:
305 break;
306 }
307 cmd->size = wlan_cpu_to_le16(cmd->size);
308 PRINTM(MINFO,
309 "SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x, Value=0x%x\n",
310 cmd_action, cmd_oid, wlan_le16_to_cpu(psnmp_mib->buf_size),
311 wlan_le16_to_cpu(*(t_u16 *)psnmp_mib->value));
312 LEAVE();
313 return MLAN_STATUS_SUCCESS;
314 }
315
316 /**
317 * @brief This function prepares command of get_log.
318 *
319 * @param pmpriv A pointer to mlan_private structure
320 * @param cmd A pointer to HostCmd_DS_COMMAND structure
321 *
322 * @return MLAN_STATUS_SUCCESS
323 */
wlan_cmd_802_11_get_log(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd)324 static mlan_status wlan_cmd_802_11_get_log(pmlan_private pmpriv,
325 HostCmd_DS_COMMAND *cmd)
326 {
327 ENTER();
328 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_GET_LOG);
329 cmd->size =
330 wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_GET_LOG) + S_DS_GEN);
331 LEAVE();
332 return MLAN_STATUS_SUCCESS;
333 }
334
335 /**
336 * @brief This function prepares command of MFG Continuous Tx cmd.
337 *
338 * @param pmpriv A pointer to mlan_private structure
339 * @param cmd A pointer to HostCmd_DS_COMMAND structure
340 * @param action The action: GET or SET
341 * @param pdata_buf A pointer to data buffer
342 *
343 * @return MLAN_STATUS_SUCCESS
344 */
wlan_cmd_mfg_tx_cont(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 action,t_void * pdata_buf)345 static mlan_status wlan_cmd_mfg_tx_cont(pmlan_private pmpriv,
346 HostCmd_DS_COMMAND *cmd, t_u16 action,
347 t_void *pdata_buf)
348 {
349 struct mfg_cmd_tx_cont *mcmd =
350 (struct mfg_cmd_tx_cont *)&cmd->params.mfg_tx_cont;
351 struct mfg_cmd_tx_cont *cfg = (struct mfg_cmd_tx_cont *)pdata_buf;
352
353 ENTER();
354 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MFG_COMMAND);
355 cmd->size = wlan_cpu_to_le16(sizeof(struct mfg_cmd_tx_cont) + S_DS_GEN);
356
357 mcmd->mfg_cmd = wlan_cpu_to_le32(cfg->mfg_cmd);
358 mcmd->action = wlan_cpu_to_le16(action);
359 if (action == HostCmd_ACT_GEN_SET) {
360 mcmd->enable_tx = wlan_cpu_to_le32(cfg->enable_tx);
361 mcmd->cw_mode = wlan_cpu_to_le32(cfg->cw_mode);
362 mcmd->payload_pattern = wlan_cpu_to_le32(cfg->payload_pattern);
363 mcmd->cs_mode = wlan_cpu_to_le32(cfg->cs_mode);
364 mcmd->act_sub_ch = wlan_cpu_to_le32(cfg->act_sub_ch);
365 mcmd->tx_rate = wlan_cpu_to_le32(cfg->tx_rate);
366 }
367
368 LEAVE();
369 return MLAN_STATUS_SUCCESS;
370 }
371
372 /**
373 * @brief This function prepares command of MFG Tx frame.
374 *
375 * @param pmpriv A pointer to mlan_private structure
376 * @param cmd A pointer to HostCmd_DS_COMMAND structure
377 * @param action The action: GET or SET
378 * @param pdata_buf A pointer to data buffer
379 *
380 * @return MLAN_STATUS_SUCCESS
381 */
wlan_cmd_mfg_tx_frame(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 action,t_void * pdata_buf)382 static mlan_status wlan_cmd_mfg_tx_frame(pmlan_private pmpriv,
383 HostCmd_DS_COMMAND *cmd, t_u16 action,
384 t_void *pdata_buf)
385 {
386 struct mfg_cmd_tx_frame2 *mcmd =
387 (struct mfg_cmd_tx_frame2 *)&cmd->params.mfg_tx_frame2;
388 struct mfg_cmd_tx_frame2 *cfg = (struct mfg_cmd_tx_frame2 *)pdata_buf;
389
390 ENTER();
391 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MFG_COMMAND);
392 cmd->size =
393 wlan_cpu_to_le16(sizeof(struct mfg_cmd_tx_frame2) + S_DS_GEN);
394
395 mcmd->mfg_cmd = wlan_cpu_to_le32(cfg->mfg_cmd);
396 mcmd->action = wlan_cpu_to_le16(action);
397 if (action == HostCmd_ACT_GEN_SET) {
398 mcmd->enable = wlan_cpu_to_le32(cfg->enable);
399 mcmd->data_rate = wlan_cpu_to_le32(cfg->data_rate);
400 mcmd->frame_pattern = wlan_cpu_to_le32(cfg->frame_pattern);
401 mcmd->frame_length = wlan_cpu_to_le32(cfg->frame_length);
402 mcmd->adjust_burst_sifs =
403 wlan_cpu_to_le16(cfg->adjust_burst_sifs);
404 mcmd->burst_sifs_in_us =
405 wlan_cpu_to_le32(cfg->burst_sifs_in_us);
406 mcmd->short_preamble = wlan_cpu_to_le32(cfg->short_preamble);
407 mcmd->act_sub_ch = wlan_cpu_to_le32(cfg->act_sub_ch);
408 mcmd->short_gi = wlan_cpu_to_le32(cfg->short_gi);
409 mcmd->tx_bf = wlan_cpu_to_le32(cfg->tx_bf);
410 mcmd->gf_mode = wlan_cpu_to_le32(cfg->gf_mode);
411 mcmd->stbc = wlan_cpu_to_le32(cfg->stbc);
412 mcmd->NumPkt = wlan_cpu_to_le32(cfg->NumPkt);
413 mcmd->MaxPE = wlan_cpu_to_le32(cfg->MaxPE);
414 mcmd->BeamChange = wlan_cpu_to_le32(cfg->BeamChange);
415 mcmd->Dcm = wlan_cpu_to_le32(cfg->Dcm);
416 mcmd->Doppler = wlan_cpu_to_le32(cfg->Doppler);
417 mcmd->MidP = wlan_cpu_to_le32(cfg->MidP);
418 mcmd->QNum = wlan_cpu_to_le32(cfg->QNum);
419 memcpy_ext(pmpriv->adapter, mcmd->bssid, cfg->bssid,
420 MLAN_MAC_ADDR_LENGTH, sizeof(mcmd->bssid));
421 }
422
423 LEAVE();
424 return MLAN_STATUS_SUCCESS;
425 }
426
427 /**
428 * @brief This function prepares command of MFG HE TB Tx.
429 *
430 * @param pmpriv A pointer to mlan_private structure
431 * @param cmd A pointer to HostCmd_DS_COMMAND structure
432 * @param action The action: GET or SET
433 * @param pdata_buf A pointer to data buffer
434 *
435 * @return MLAN_STATUS_SUCCESS
436 */
437
wlan_cmd_mfg_he_tb_tx(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 action,t_void * pdata_buf)438 mlan_status wlan_cmd_mfg_he_tb_tx(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
439 t_u16 action, t_void *pdata_buf)
440 {
441 struct mfg_Cmd_HE_TBTx_t *mcmd =
442 (struct mfg_Cmd_HE_TBTx_t *)&cmd->params.mfg_he_power;
443 struct mfg_Cmd_HE_TBTx_t *cfg = (struct mfg_Cmd_HE_TBTx_t *)pdata_buf;
444 ENTER();
445 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MFG_COMMAND);
446 cmd->size =
447 wlan_cpu_to_le16(sizeof(struct mfg_Cmd_HE_TBTx_t) + S_DS_GEN);
448
449 mcmd->mfg_cmd = wlan_cpu_to_le32(cfg->mfg_cmd);
450 mcmd->action = wlan_cpu_to_le16(action);
451 if (action == HostCmd_ACT_GEN_SET) {
452 mcmd->enable = wlan_cpu_to_le16(cfg->enable);
453 mcmd->qnum = wlan_cpu_to_le16(cfg->qnum);
454 mcmd->aid = wlan_cpu_to_le16(cfg->aid);
455 mcmd->axq_mu_timer = wlan_cpu_to_le16(cfg->axq_mu_timer);
456 mcmd->tx_power = wlan_cpu_to_le16(cfg->tx_power);
457 }
458
459 LEAVE();
460 return MLAN_STATUS_SUCCESS;
461 }
462
463 /**
464 * @brief This function prepares command of MFG cmd.
465 *
466 * @param pmpriv A pointer to mlan_private structure
467 * @param cmd A pointer to HostCmd_DS_COMMAND structure
468 * @param action The action: GET or SET
469 * @param pdata_buf A pointer to data buffer
470 *
471 * @return MLAN_STATUS_SUCCESS
472 */
wlan_cmd_mfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 action,t_void * pdata_buf)473 mlan_status wlan_cmd_mfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
474 t_u16 action, t_void *pdata_buf)
475 {
476 struct mfg_cmd_generic_cfg *mcmd =
477 (struct mfg_cmd_generic_cfg *)&cmd->params.mfg_generic_cfg;
478 struct mfg_cmd_generic_cfg *cfg =
479 (struct mfg_cmd_generic_cfg *)pdata_buf;
480 mlan_status ret = MLAN_STATUS_SUCCESS;
481
482 ENTER();
483
484 if (!mcmd || !cfg) {
485 ret = MLAN_STATUS_FAILURE;
486 goto cmd_mfg_done;
487 }
488 switch (cfg->mfg_cmd) {
489 case MFG_CMD_TX_CONT:
490 ret = wlan_cmd_mfg_tx_cont(pmpriv, cmd, action, pdata_buf);
491 goto cmd_mfg_done;
492 case MFG_CMD_TX_FRAME:
493 ret = wlan_cmd_mfg_tx_frame(pmpriv, cmd, action, pdata_buf);
494 goto cmd_mfg_done;
495 case MFG_CMD_CONFIG_MAC_HE_TB_TX:
496 ret = wlan_cmd_mfg_he_tb_tx(pmpriv, cmd, action, pdata_buf);
497 goto cmd_mfg_done;
498 case MFG_CMD_SET_TEST_MODE:
499 case MFG_CMD_UNSET_TEST_MODE:
500 case MFG_CMD_TX_ANT:
501 case MFG_CMD_RX_ANT:
502 case MFG_CMD_RF_CHAN:
503 case MFG_CMD_CLR_RX_ERR:
504 case MFG_CMD_RF_BAND_AG:
505 case MFG_CMD_RF_CHANNELBW:
506 case MFG_CMD_RADIO_MODE_CFG:
507 case MFG_CMD_RFPWR:
508 break;
509 default:
510 ret = MLAN_STATUS_FAILURE;
511 goto cmd_mfg_done;
512 }
513 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MFG_COMMAND);
514 cmd->size =
515 wlan_cpu_to_le16(sizeof(struct mfg_cmd_generic_cfg) + S_DS_GEN);
516
517 mcmd->mfg_cmd = wlan_cpu_to_le32(cfg->mfg_cmd);
518 mcmd->action = wlan_cpu_to_le16(action);
519 if (action == HostCmd_ACT_GEN_SET) {
520 mcmd->data1 = wlan_cpu_to_le32(cfg->data1);
521 mcmd->data2 = wlan_cpu_to_le32(cfg->data2);
522 mcmd->data3 = wlan_cpu_to_le32(cfg->data3);
523 }
524 cmd_mfg_done:
525 LEAVE();
526 return ret;
527 }
528
529 /**
530 * @brief This function prepares command of tx_power_cfg.
531 *
532 * @param pmpriv A pointer to mlan_private structure
533 * @param cmd A pointer to HostCmd_DS_COMMAND structure
534 * @param cmd_action The action: GET or SET
535 * @param pdata_buf A pointer to data buffer
536 *
537 * @return MLAN_STATUS_SUCCESS
538 */
wlan_cmd_tx_power_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)539 static mlan_status wlan_cmd_tx_power_cfg(pmlan_private pmpriv,
540 HostCmd_DS_COMMAND *cmd,
541 t_u16 cmd_action, t_void *pdata_buf)
542 {
543 MrvlTypes_Power_Group_t *ppg_tlv = MNULL;
544 HostCmd_DS_TXPWR_CFG *ptxp = MNULL;
545 HostCmd_DS_TXPWR_CFG *ptxp_cfg = &cmd->params.txp_cfg;
546
547 ENTER();
548
549 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_TXPWR_CFG);
550 cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_TXPWR_CFG));
551 switch (cmd_action) {
552 case HostCmd_ACT_GEN_SET:
553 ptxp = (HostCmd_DS_TXPWR_CFG *)pdata_buf;
554 if (ptxp->mode) {
555 ppg_tlv = (MrvlTypes_Power_Group_t
556 *)((t_u8 *)pdata_buf +
557 sizeof(HostCmd_DS_TXPWR_CFG));
558 memmove(pmpriv->adapter, ptxp_cfg, pdata_buf,
559 sizeof(HostCmd_DS_TXPWR_CFG) +
560 sizeof(MrvlTypes_Power_Group_t) +
561 ppg_tlv->length);
562
563 ppg_tlv = (MrvlTypes_Power_Group_t
564 *)((t_u8 *)ptxp_cfg +
565 sizeof(HostCmd_DS_TXPWR_CFG));
566 cmd->size += wlan_cpu_to_le16(
567 sizeof(MrvlTypes_Power_Group_t) +
568 ppg_tlv->length);
569 ppg_tlv->type = wlan_cpu_to_le16(ppg_tlv->type);
570 ppg_tlv->length = wlan_cpu_to_le16(ppg_tlv->length);
571 } else {
572 memmove(pmpriv->adapter, ptxp_cfg, pdata_buf,
573 sizeof(HostCmd_DS_TXPWR_CFG));
574 }
575 ptxp_cfg->action = wlan_cpu_to_le16(cmd_action);
576 ptxp_cfg->cfg_index = wlan_cpu_to_le16(ptxp_cfg->cfg_index);
577 ptxp_cfg->mode = wlan_cpu_to_le32(ptxp_cfg->mode);
578 break;
579 case HostCmd_ACT_GEN_GET:
580 ptxp_cfg->action = wlan_cpu_to_le16(cmd_action);
581 break;
582 }
583
584 LEAVE();
585 return MLAN_STATUS_SUCCESS;
586 }
587
588 /**
589 * @brief This function prepares command of rf_tx_power.
590 *
591 * @param pmpriv A pointer to wlan_private structure
592 * @param cmd A pointer to HostCmd_DS_COMMAND structure
593 * @param cmd_action the action: GET or SET
594 * @param pdata_buf A pointer to data buffer
595 * @return MLAN_STATUS_SUCCESS
596 */
wlan_cmd_802_11_rf_tx_power(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)597 static mlan_status wlan_cmd_802_11_rf_tx_power(pmlan_private pmpriv,
598 HostCmd_DS_COMMAND *cmd,
599 t_u16 cmd_action,
600 t_void *pdata_buf)
601 {
602 HostCmd_DS_802_11_RF_TX_POWER *prtp = &cmd->params.txp;
603
604 ENTER();
605
606 cmd->size = wlan_cpu_to_le16((sizeof(HostCmd_DS_802_11_RF_TX_POWER)) +
607 S_DS_GEN);
608 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_RF_TX_POWER);
609 prtp->action = cmd_action;
610
611 PRINTM(MINFO, "RF_TX_POWER_CMD: Size:%d Cmd:0x%x Act:%d\n", cmd->size,
612 cmd->command, prtp->action);
613
614 switch (cmd_action) {
615 case HostCmd_ACT_GEN_GET:
616 prtp->action = wlan_cpu_to_le16(HostCmd_ACT_GEN_GET);
617 prtp->current_level = 0;
618 break;
619
620 case HostCmd_ACT_GEN_SET:
621 prtp->action = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
622 prtp->current_level = wlan_cpu_to_le16(*((t_s16 *)pdata_buf));
623 break;
624 }
625 LEAVE();
626 return MLAN_STATUS_SUCCESS;
627 }
628
629 #ifdef WIFI_DIRECT_SUPPORT
630 /**
631 * @brief Check if any p2p interface is conencted
632 *
633 * @param pmadapter A pointer to mlan_adapter structure
634 *
635 * @return MTRUE/MFALSE;
636 */
wlan_is_p2p_connected(pmlan_adapter pmadapter)637 static t_u8 wlan_is_p2p_connected(pmlan_adapter pmadapter)
638 {
639 int j;
640 pmlan_private priv;
641
642 ENTER();
643 for (j = 0; j < pmadapter->priv_num; ++j) {
644 priv = pmadapter->priv[j];
645 if (priv) {
646 if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT) {
647 if ((priv->bss_role == MLAN_BSS_ROLE_STA) &&
648 (priv->media_connected == MTRUE)) {
649 LEAVE();
650 return MTRUE;
651 }
652 if ((priv->bss_role == MLAN_BSS_ROLE_UAP) &&
653 (priv->uap_bss_started == MTRUE)) {
654 LEAVE();
655 return MTRUE;
656 }
657 }
658 }
659 }
660 LEAVE();
661 return MFALSE;
662 }
663 #endif
664
665 /**
666 * @brief This function prepares command of hs_cfg.
667 *
668 * @param pmpriv A pointer to mlan_private structure
669 * @param cmd A pointer to HostCmd_DS_COMMAND structure
670 * @param cmd_action The action: GET or SET
671 * @param pdata_buf A pointer to data buffer
672 *
673 * @return MLAN_STATUS_SUCCESS
674 */
wlan_cmd_802_11_hs_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,hs_config_param * pdata_buf)675 static mlan_status wlan_cmd_802_11_hs_cfg(pmlan_private pmpriv,
676 HostCmd_DS_COMMAND *cmd,
677 t_u16 cmd_action,
678 hs_config_param *pdata_buf)
679 {
680 pmlan_adapter pmadapter = pmpriv->adapter;
681 HostCmd_DS_802_11_HS_CFG_ENH *phs_cfg = &cmd->params.opt_hs_cfg;
682 t_u16 hs_activate = MFALSE;
683 t_u8 *tlv = (t_u8 *)phs_cfg + sizeof(HostCmd_DS_802_11_HS_CFG_ENH);
684 MrvlIEtypes_HsWakeHoldoff_t *holdoff_tlv = MNULL;
685 MrvlIEtypes_PsParamsInHs_t *psparam_tlv = MNULL;
686 MrvlIEtypes_WakeupSourceGPIO_t *gpio_tlv = MNULL;
687 MrvlIEtypes_MgmtFrameFilter_t *mgmt_filter_tlv = MNULL;
688 MrvlIEtypes_WakeupExtend_t *ext_tlv = MNULL;
689 MrvlIEtypes_HS_Antmode_t *antmode_tlv = MNULL;
690
691 ENTER();
692
693 if (pdata_buf == MNULL) {
694 /* New Activate command */
695 hs_activate = MTRUE;
696 }
697 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH);
698
699 if (!hs_activate && (pdata_buf->conditions != HOST_SLEEP_CFG_CANCEL) &&
700 ((pmadapter->arp_filter_size > 0) &&
701 (pmadapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) {
702 PRINTM(MINFO, "Attach %d bytes ArpFilter to HSCfg cmd\n",
703 pmadapter->arp_filter_size);
704 memcpy_ext(pmpriv->adapter,
705 ((t_u8 *)phs_cfg) +
706 sizeof(HostCmd_DS_802_11_HS_CFG_ENH),
707 pmadapter->arp_filter, pmadapter->arp_filter_size,
708 pmadapter->arp_filter_size);
709 cmd->size = pmadapter->arp_filter_size +
710 sizeof(HostCmd_DS_802_11_HS_CFG_ENH) + S_DS_GEN;
711 tlv = (t_u8 *)phs_cfg + sizeof(HostCmd_DS_802_11_HS_CFG_ENH) +
712 pmadapter->arp_filter_size;
713 } else
714 cmd->size = S_DS_GEN + sizeof(HostCmd_DS_802_11_HS_CFG_ENH);
715
716 if (hs_activate) {
717 cmd->size = wlan_cpu_to_le16(cmd->size);
718 phs_cfg->action = wlan_cpu_to_le16(HS_ACTIVATE);
719 phs_cfg->params.hs_activate.resp_ctrl =
720 wlan_cpu_to_le16(RESP_NEEDED);
721 } else {
722 phs_cfg->action = wlan_cpu_to_le16(HS_CONFIGURE);
723 #ifdef WIFI_DIRECT_SUPPORT
724 if (wlan_is_p2p_connected(pmadapter))
725 phs_cfg->params.hs_config.conditions = wlan_cpu_to_le32(
726 pdata_buf->conditions |
727 HOST_SLEEP_COND_MULTICAST_DATA);
728 else
729 #endif
730 phs_cfg->params.hs_config.conditions =
731 wlan_cpu_to_le32(pdata_buf->conditions);
732 phs_cfg->params.hs_config.gpio = pdata_buf->gpio;
733 phs_cfg->params.hs_config.gap = pdata_buf->gap;
734 if (pmadapter->min_wake_holdoff) {
735 cmd->size += sizeof(MrvlIEtypes_HsWakeHoldoff_t);
736 holdoff_tlv = (MrvlIEtypes_HsWakeHoldoff_t *)tlv;
737 holdoff_tlv->header.type =
738 wlan_cpu_to_le16(TLV_TYPE_HS_WAKE_HOLDOFF);
739 holdoff_tlv->header.len = wlan_cpu_to_le16(
740 sizeof(MrvlIEtypes_HsWakeHoldoff_t) -
741 sizeof(MrvlIEtypesHeader_t));
742 holdoff_tlv->min_wake_holdoff =
743 wlan_cpu_to_le16(pmadapter->min_wake_holdoff);
744 tlv += sizeof(MrvlIEtypes_HsWakeHoldoff_t);
745 PRINTM(MCMND, "min_wake_holdoff=%d\n",
746 pmadapter->min_wake_holdoff);
747 }
748 if (pmadapter->hs_wake_interval && pmpriv->media_connected &&
749 (pmpriv->bss_type == MLAN_BSS_TYPE_STA)) {
750 cmd->size += sizeof(MrvlIEtypes_PsParamsInHs_t);
751 psparam_tlv = (MrvlIEtypes_PsParamsInHs_t *)tlv;
752 psparam_tlv->header.type =
753 wlan_cpu_to_le16(TLV_TYPE_PS_PARAMS_IN_HS);
754 psparam_tlv->header.len = wlan_cpu_to_le16(
755 sizeof(MrvlIEtypes_PsParamsInHs_t) -
756 sizeof(MrvlIEtypesHeader_t));
757 psparam_tlv->hs_wake_interval =
758 wlan_cpu_to_le32(pmadapter->hs_wake_interval);
759 psparam_tlv->hs_inactivity_timeout = wlan_cpu_to_le32(
760 pmadapter->hs_inactivity_timeout);
761 tlv += sizeof(MrvlIEtypes_PsParamsInHs_t);
762 PRINTM(MCMND, "hs_wake_interval=%d\n",
763 pmadapter->hs_wake_interval);
764 PRINTM(MCMND, "hs_inactivity_timeout=%d\n",
765 pmadapter->hs_inactivity_timeout);
766 }
767 if (pmadapter->param_type_ind == 1) {
768 cmd->size += sizeof(MrvlIEtypes_WakeupSourceGPIO_t);
769 gpio_tlv = (MrvlIEtypes_WakeupSourceGPIO_t *)tlv;
770 gpio_tlv->header.type = wlan_cpu_to_le16(
771 TLV_TYPE_HS_WAKEUP_SOURCE_GPIO);
772 gpio_tlv->header.len = wlan_cpu_to_le16(
773 sizeof(MrvlIEtypes_WakeupSourceGPIO_t) -
774 sizeof(MrvlIEtypesHeader_t));
775 gpio_tlv->ind_gpio = (t_u8)pmadapter->ind_gpio;
776 gpio_tlv->level = (t_u8)pmadapter->level;
777 tlv += sizeof(MrvlIEtypes_WakeupSourceGPIO_t);
778 }
779 if (pmadapter->param_type_ext == 2) {
780 cmd->size += sizeof(MrvlIEtypes_WakeupExtend_t);
781 ext_tlv = (MrvlIEtypes_WakeupExtend_t *)tlv;
782 ext_tlv->header.type =
783 wlan_cpu_to_le16(TLV_TYPE_WAKEUP_EXTEND);
784 ext_tlv->header.len = wlan_cpu_to_le16(
785 sizeof(MrvlIEtypes_WakeupExtend_t) -
786 sizeof(MrvlIEtypesHeader_t));
787 ext_tlv->event_force_ignore =
788 wlan_cpu_to_le32(pmadapter->event_force_ignore);
789 ext_tlv->event_use_ext_gap =
790 wlan_cpu_to_le32(pmadapter->event_use_ext_gap);
791 ext_tlv->ext_gap = pmadapter->ext_gap;
792 ext_tlv->gpio_wave = pmadapter->gpio_wave;
793 tlv += sizeof(MrvlIEtypes_WakeupExtend_t);
794 }
795 if (pmadapter->mgmt_filter[0].type) {
796 int i = 0;
797 mgmt_frame_filter mgmt_filter[MAX_MGMT_FRAME_FILTER];
798
799 memset(pmadapter, mgmt_filter, 0,
800 MAX_MGMT_FRAME_FILTER *
801 sizeof(mgmt_frame_filter));
802 mgmt_filter_tlv = (MrvlIEtypes_MgmtFrameFilter_t *)tlv;
803 mgmt_filter_tlv->header.type =
804 wlan_cpu_to_le16(TLV_TYPE_MGMT_FRAME_WAKEUP);
805 tlv += sizeof(MrvlIEtypesHeader_t);
806 while (i < MAX_MGMT_FRAME_FILTER &&
807 pmadapter->mgmt_filter[i].type) {
808 mgmt_filter[i].action =
809 (t_u8)pmadapter->mgmt_filter[i].action;
810 mgmt_filter[i].type =
811 (t_u8)pmadapter->mgmt_filter[i].type;
812 mgmt_filter[i].frame_mask = wlan_cpu_to_le32(
813 pmadapter->mgmt_filter[i].frame_mask);
814 i++;
815 }
816 memcpy_ext(pmadapter, (t_u8 *)mgmt_filter_tlv->filter,
817 (t_u8 *)mgmt_filter,
818 i * sizeof(mgmt_frame_filter),
819 sizeof(mgmt_filter_tlv->filter));
820 tlv += i * sizeof(mgmt_frame_filter);
821 mgmt_filter_tlv->header.len =
822 wlan_cpu_to_le16(i * sizeof(mgmt_frame_filter));
823 cmd->size += i * sizeof(mgmt_frame_filter) +
824 sizeof(MrvlIEtypesHeader_t);
825 }
826 if (pmadapter->hs_mimo_switch) {
827 cmd->size += sizeof(MrvlIEtypes_HS_Antmode_t);
828 antmode_tlv = (MrvlIEtypes_HS_Antmode_t *)tlv;
829 antmode_tlv->header.type =
830 wlan_cpu_to_le16(TLV_TYPE_HS_ANTMODE);
831 antmode_tlv->header.len = wlan_cpu_to_le16(
832 sizeof(MrvlIEtypes_HS_Antmode_t) -
833 sizeof(MrvlIEtypesHeader_t));
834 antmode_tlv->txpath_antmode = ANTMODE_FW_DECISION;
835 antmode_tlv->rxpath_antmode = ANTMODE_FW_DECISION;
836 tlv += sizeof(MrvlIEtypes_HS_Antmode_t);
837 PRINTM(MCMND, "hs_mimo_switch=%d\n",
838 pmadapter->hs_mimo_switch);
839 PRINTM(MCMND, "txpath_antmode=%d, rxpath_antmode=%d\n",
840 antmode_tlv->txpath_antmode,
841 antmode_tlv->rxpath_antmode);
842 }
843 cmd->size = wlan_cpu_to_le16(cmd->size);
844 PRINTM(MCMND, "HS_CFG_CMD: condition:0x%x gpio:0x%x\n",
845 phs_cfg->params.hs_config.conditions,
846 phs_cfg->params.hs_config.gpio);
847 PRINTM(MCMND, "HS_CFG_CMD: gap:0x%x holdoff=%d\n",
848 phs_cfg->params.hs_config.gap,
849 pmadapter->min_wake_holdoff);
850 PRINTM(MCMND,
851 "HS_CFG_CMD: wake_interval=%d inactivity_timeout=%d\n",
852 pmadapter->hs_wake_interval,
853 pmadapter->hs_inactivity_timeout);
854 }
855
856 LEAVE();
857 return MLAN_STATUS_SUCCESS;
858 }
859
860 /**
861 * @brief This function prepares command of sleep_period.
862 *
863 * @param pmpriv A pointer to mlan_private structure
864 * @param cmd A pointer to HostCmd_DS_COMMAND structure
865 * @param cmd_action The action: GET or SET
866 * @param pdata_buf A pointer to data buffer
867 *
868 * @return MLAN_STATUS_SUCCESS
869 */
wlan_cmd_802_11_sleep_period(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_u16 * pdata_buf)870 static mlan_status wlan_cmd_802_11_sleep_period(pmlan_private pmpriv,
871 HostCmd_DS_COMMAND *cmd,
872 t_u16 cmd_action,
873 t_u16 *pdata_buf)
874 {
875 HostCmd_DS_802_11_SLEEP_PERIOD *pcmd_sleep_pd = &cmd->params.sleep_pd;
876
877 ENTER();
878
879 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_SLEEP_PERIOD);
880 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_SLEEP_PERIOD) +
881 S_DS_GEN);
882 if (cmd_action == HostCmd_ACT_GEN_SET)
883 pcmd_sleep_pd->sleep_pd = wlan_cpu_to_le16(*(t_u16 *)pdata_buf);
884
885 pcmd_sleep_pd->action = wlan_cpu_to_le16(cmd_action);
886
887 LEAVE();
888 return MLAN_STATUS_SUCCESS;
889 }
890
891 /**
892 * @brief This function prepares command of sleep_params.
893 *
894 * @param pmpriv A pointer to mlan_private structure
895 * @param cmd A pointer to HostCmd_DS_COMMAND structure
896 * @param cmd_action The action: GET or SET
897 * @param pdata_buf A pointer to data buffer
898 *
899 * @return MLAN_STATUS_SUCCESS
900 */
wlan_cmd_802_11_sleep_params(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_u16 * pdata_buf)901 static mlan_status wlan_cmd_802_11_sleep_params(pmlan_private pmpriv,
902 HostCmd_DS_COMMAND *cmd,
903 t_u16 cmd_action,
904 t_u16 *pdata_buf)
905 {
906 HostCmd_DS_802_11_SLEEP_PARAMS *pcmd_sp = &cmd->params.sleep_param;
907 mlan_ds_sleep_params *psp = (mlan_ds_sleep_params *)pdata_buf;
908
909 ENTER();
910
911 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_SLEEP_PARAMS);
912 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_SLEEP_PARAMS) +
913 S_DS_GEN);
914 if (cmd_action == HostCmd_ACT_GEN_SET) {
915 pcmd_sp->reserved = (t_u16)psp->reserved;
916 pcmd_sp->error = (t_u16)psp->error;
917 pcmd_sp->offset = (t_u16)psp->offset;
918 pcmd_sp->stable_time = (t_u16)psp->stable_time;
919 pcmd_sp->cal_control = (t_u8)psp->cal_control;
920 pcmd_sp->external_sleep_clk = (t_u8)psp->ext_sleep_clk;
921
922 pcmd_sp->reserved = wlan_cpu_to_le16(pcmd_sp->reserved);
923 pcmd_sp->error = wlan_cpu_to_le16(pcmd_sp->error);
924 pcmd_sp->offset = wlan_cpu_to_le16(pcmd_sp->offset);
925 pcmd_sp->stable_time = wlan_cpu_to_le16(pcmd_sp->stable_time);
926 }
927 pcmd_sp->action = wlan_cpu_to_le16(cmd_action);
928
929 LEAVE();
930 return MLAN_STATUS_SUCCESS;
931 }
932
933 /**
934 * @brief This function prepares command of mac_multicast_adr.
935 *
936 * @param pmpriv A pointer to mlan_private structure
937 * @param cmd A pointer to HostCmd_DS_COMMAND structure
938 * @param cmd_action The action: GET or SET
939 * @param pdata_buf A pointer to data buffer
940 *
941 * @return MLAN_STATUS_SUCCESS
942 */
wlan_cmd_mac_multicast_adr(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)943 static mlan_status wlan_cmd_mac_multicast_adr(pmlan_private pmpriv,
944 HostCmd_DS_COMMAND *cmd,
945 t_u16 cmd_action,
946 t_void *pdata_buf)
947 {
948 mlan_multicast_list *pmcast_list = (mlan_multicast_list *)pdata_buf;
949 HostCmd_DS_MAC_MULTICAST_ADR *pmc_addr = &cmd->params.mc_addr;
950
951 ENTER();
952 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_MAC_MULTICAST_ADR) +
953 S_DS_GEN);
954 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MAC_MULTICAST_ADR);
955
956 pmc_addr->action = wlan_cpu_to_le16(cmd_action);
957 pmc_addr->num_of_adrs =
958 wlan_cpu_to_le16((t_u16)pmcast_list->num_multicast_addr);
959 memcpy_ext(pmpriv->adapter, pmc_addr->mac_list, pmcast_list->mac_list,
960 pmcast_list->num_multicast_addr * MLAN_MAC_ADDR_LENGTH,
961 sizeof(pmc_addr->mac_list));
962
963 LEAVE();
964 return MLAN_STATUS_SUCCESS;
965 }
966
967 /**
968 * @brief This function prepares command of deauthenticate/disassociate.
969 *
970 * @param pmpriv A pointer to mlan_private structure
971 * @param cmd_no Command number
972 * @param cmd A pointer to HostCmd_DS_COMMAND structure
973 * @param pdata_buf A pointer to data buffer
974 *
975 * @return MLAN_STATUS_SUCCESS
976 */
wlan_cmd_802_11_deauthenticate(pmlan_private pmpriv,t_u16 cmd_no,HostCmd_DS_COMMAND * cmd,t_void * pdata_buf)977 static mlan_status wlan_cmd_802_11_deauthenticate(pmlan_private pmpriv,
978 t_u16 cmd_no,
979 HostCmd_DS_COMMAND *cmd,
980 t_void *pdata_buf)
981 {
982 HostCmd_DS_802_11_DEAUTHENTICATE *pdeauth = &cmd->params.deauth;
983
984 ENTER();
985
986 cmd->command = wlan_cpu_to_le16(cmd_no);
987 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_DEAUTHENTICATE) +
988 S_DS_GEN);
989
990 /* Set AP MAC address */
991 memcpy_ext(pmpriv->adapter, pdeauth, (t_u8 *)pdata_buf,
992 sizeof(*pdeauth), sizeof(*pdeauth));
993 if (cmd_no == HostCmd_CMD_802_11_DEAUTHENTICATE)
994 PRINTM(MCMND, "Deauth: " MACSTR "\n",
995 MAC2STR(pdeauth->mac_addr));
996 else
997 PRINTM(MCMND, "Disassociate: " MACSTR "\n",
998 MAC2STR(pdeauth->mac_addr));
999
1000 if (pmpriv->adapter->state_11h.recvd_chanswann_event) {
1001 /** Reason code 36 = Requested from peer station as it is leaving the BSS */
1002 #define REASON_CODE_PEER_STA_LEAVING 36
1003 pdeauth->reason_code =
1004 wlan_cpu_to_le16(REASON_CODE_PEER_STA_LEAVING);
1005 } else {
1006 pdeauth->reason_code = wlan_cpu_to_le16(pdeauth->reason_code);
1007 }
1008
1009 LEAVE();
1010 return MLAN_STATUS_SUCCESS;
1011 }
1012
1013 /**
1014 * @brief This function prepares command of ad_hoc_stop.
1015 *
1016 * @param pmpriv A pointer to mlan_private structure
1017 * @param cmd A pointer to HostCmd_DS_COMMAND structure
1018 *
1019 * @return MLAN_STATUS_SUCCESS
1020 */
wlan_cmd_802_11_ad_hoc_stop(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd)1021 static mlan_status wlan_cmd_802_11_ad_hoc_stop(pmlan_private pmpriv,
1022 HostCmd_DS_COMMAND *cmd)
1023 {
1024 ENTER();
1025
1026 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_STOP);
1027 cmd->size = wlan_cpu_to_le16(S_DS_GEN);
1028
1029 if (wlan_11h_is_active(pmpriv))
1030 wlan_11h_activate(pmpriv, MNULL, MFALSE);
1031
1032 LEAVE();
1033 return MLAN_STATUS_SUCCESS;
1034 }
1035
1036 /**
1037 * @brief This function prepares command of key_material.
1038 *
1039 * @param pmpriv A pointer to mlan_private structure
1040 * @param cmd A pointer to HostCmd_DS_COMMAND structure
1041 * @param cmd_action The action: GET or SET
1042 * @param cmd_oid OID: ENABLE or DISABLE
1043 * @param pdata_buf A pointer to data buffer
1044 *
1045 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1046 */
wlan_cmd_802_11_key_material(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_u32 cmd_oid,t_void * pdata_buf)1047 static mlan_status wlan_cmd_802_11_key_material(pmlan_private pmpriv,
1048 HostCmd_DS_COMMAND *cmd,
1049 t_u16 cmd_action, t_u32 cmd_oid,
1050 t_void *pdata_buf)
1051 {
1052 HostCmd_DS_802_11_KEY_MATERIAL *pkey_material =
1053 &cmd->params.key_material;
1054 mlan_ds_encrypt_key *pkey = (mlan_ds_encrypt_key *)pdata_buf;
1055 mlan_status ret = MLAN_STATUS_SUCCESS;
1056
1057 ENTER();
1058 if (!pkey) {
1059 ret = MLAN_STATUS_FAILURE;
1060 goto done;
1061 }
1062 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL);
1063 pkey_material->action = wlan_cpu_to_le16(cmd_action);
1064 if (cmd_action == HostCmd_ACT_GEN_GET) {
1065 PRINTM(MCMND, "GET Key\n");
1066 pkey_material->key_param_set.key_idx =
1067 pkey->key_index & KEY_INDEX_MASK;
1068 pkey_material->key_param_set.type =
1069 wlan_cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
1070 pkey_material->key_param_set.length =
1071 wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN);
1072 memcpy_ext(pmpriv->adapter,
1073 pkey_material->key_param_set.mac_addr,
1074 pkey->mac_addr, MLAN_MAC_ADDR_LENGTH,
1075 MLAN_MAC_ADDR_LENGTH);
1076 if (pkey->key_flags & KEY_FLAG_GROUP_KEY)
1077 pkey_material->key_param_set.key_info |=
1078 KEY_INFO_MCAST_KEY;
1079 else
1080 pkey_material->key_param_set.key_info |=
1081 KEY_INFO_UCAST_KEY;
1082 if (pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK)
1083 pkey_material->key_param_set.key_info =
1084 KEY_INFO_CMAC_AES_KEY;
1085 pkey_material->key_param_set.key_info =
1086 wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
1087 cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) +
1088 S_DS_GEN + KEY_PARAMS_FIXED_LEN +
1089 sizeof(pkey_material->action));
1090 goto done;
1091 }
1092 memset(pmpriv->adapter, &pkey_material->key_param_set, 0,
1093 sizeof(MrvlIEtype_KeyParamSetV2_t));
1094 if (pkey->key_flags & KEY_FLAG_REMOVE_KEY) {
1095 pkey_material->action =
1096 wlan_cpu_to_le16(HostCmd_ACT_GEN_REMOVE);
1097 pkey_material->key_param_set.type =
1098 wlan_cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
1099 pkey_material->key_param_set.length =
1100 wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN);
1101 pkey_material->key_param_set.key_idx =
1102 pkey->key_index & KEY_INDEX_MASK;
1103 pkey_material->key_param_set.key_info = wlan_cpu_to_le16(
1104 KEY_INFO_MCAST_KEY | KEY_INFO_UCAST_KEY);
1105 memcpy_ext(pmpriv->adapter,
1106 pkey_material->key_param_set.mac_addr,
1107 pkey->mac_addr, MLAN_MAC_ADDR_LENGTH,
1108 MLAN_MAC_ADDR_LENGTH);
1109 cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) +
1110 S_DS_GEN + KEY_PARAMS_FIXED_LEN +
1111 sizeof(pkey_material->action));
1112 PRINTM(MCMND, "Remove Key\n");
1113 goto done;
1114 }
1115 pkey_material->action = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
1116 pkey_material->key_param_set.key_idx = pkey->key_index & KEY_INDEX_MASK;
1117 pkey_material->key_param_set.type =
1118 wlan_cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
1119 pkey_material->key_param_set.key_info = KEY_INFO_ENABLE_KEY;
1120 memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.mac_addr,
1121 pkey->mac_addr, MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
1122 if (pkey->key_len <= MAX_WEP_KEY_SIZE) {
1123 pkey_material->key_param_set.length = wlan_cpu_to_le16(
1124 KEY_PARAMS_FIXED_LEN + sizeof(wep_param_t));
1125 pkey_material->key_param_set.key_type = KEY_TYPE_ID_WEP;
1126 if (pkey->is_current_wep_key) {
1127 pkey_material->key_param_set.key_info |=
1128 KEY_INFO_MCAST_KEY | KEY_INFO_UCAST_KEY;
1129 if (pkey_material->key_param_set.key_idx ==
1130 (pmpriv->wep_key_curr_index & KEY_INDEX_MASK))
1131 pkey_material->key_param_set.key_info |=
1132 KEY_INFO_DEFAULT_KEY;
1133 } else {
1134 if (pkey->key_flags & KEY_FLAG_GROUP_KEY)
1135 pkey_material->key_param_set.key_info |=
1136 KEY_INFO_MCAST_KEY;
1137 else
1138 pkey_material->key_param_set.key_info |=
1139 KEY_INFO_UCAST_KEY;
1140 }
1141 pkey_material->key_param_set.key_info =
1142 wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
1143 pkey_material->key_param_set.key_params.wep.key_len =
1144 wlan_cpu_to_le16(pkey->key_len);
1145 memcpy_ext(pmpriv->adapter,
1146 pkey_material->key_param_set.key_params.wep.key,
1147 pkey->key_material, pkey->key_len, MAX_WEP_KEY_SIZE);
1148 cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) +
1149 S_DS_GEN + KEY_PARAMS_FIXED_LEN +
1150 sizeof(wep_param_t) +
1151 sizeof(pkey_material->action));
1152 PRINTM(MCMND, "Set WEP Key\n");
1153 goto done;
1154 }
1155 if (pkey->key_flags & KEY_FLAG_GROUP_KEY)
1156 pkey_material->key_param_set.key_info |= KEY_INFO_MCAST_KEY;
1157 else
1158 pkey_material->key_param_set.key_info |= KEY_INFO_UCAST_KEY;
1159 if (pkey->key_flags & KEY_FLAG_SET_TX_KEY)
1160 pkey_material->key_param_set.key_info |=
1161 KEY_INFO_TX_KEY | KEY_INFO_RX_KEY;
1162 else
1163 pkey_material->key_param_set.key_info |= KEY_INFO_RX_KEY;
1164 if (pkey->is_wapi_key) {
1165 pkey_material->key_param_set.key_type = KEY_TYPE_ID_WAPI;
1166 memcpy_ext(pmpriv->adapter,
1167 pkey_material->key_param_set.key_params.wapi.pn,
1168 pkey->pn, PN_SIZE, PN_SIZE);
1169 pkey_material->key_param_set.key_params.wapi.key_len =
1170 wlan_cpu_to_le16(pkey->key_len);
1171 memcpy_ext(pmpriv->adapter,
1172 pkey_material->key_param_set.key_params.wapi.key,
1173 pkey->key_material, pkey->key_len, WAPI_KEY_SIZE);
1174 if (!pmpriv->sec_info.wapi_key_on)
1175 pkey_material->key_param_set.key_info |=
1176 KEY_INFO_DEFAULT_KEY;
1177 if (pkey->key_flags & KEY_FLAG_GROUP_KEY)
1178 pmpriv->sec_info.wapi_key_on = MTRUE;
1179 pkey_material->key_param_set.key_info =
1180 wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
1181 pkey_material->key_param_set.length = wlan_cpu_to_le16(
1182 KEY_PARAMS_FIXED_LEN + sizeof(wapi_param));
1183 cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) +
1184 S_DS_GEN + KEY_PARAMS_FIXED_LEN +
1185 sizeof(wapi_param) +
1186 sizeof(pkey_material->action));
1187 PRINTM(MCMND, "Set WAPI Key\n");
1188 goto done;
1189 }
1190 if (pmpriv->bss_mode == MLAN_BSS_MODE_INFRA) {
1191 /* Enable default key for WPA/WPA2 */
1192 if (!pmpriv->wpa_is_gtk_set)
1193 pkey_material->key_param_set.key_info |=
1194 KEY_INFO_DEFAULT_KEY;
1195 } else {
1196 pkey_material->key_param_set.key_info |= KEY_INFO_DEFAULT_KEY;
1197 /* Enable unicast bit for WPA-NONE/ADHOC_AES */
1198 if ((!pmpriv->sec_info.wpa2_enabled) &&
1199 (pkey->key_flags & KEY_FLAG_SET_TX_KEY))
1200 pkey_material->key_param_set.key_info |=
1201 KEY_INFO_UCAST_KEY;
1202 }
1203 pkey_material->key_param_set.key_info =
1204 wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
1205 if (pkey->key_flags & KEY_FLAG_GCMP ||
1206 pkey->key_flags & KEY_FLAG_GCMP_256) {
1207 if (pkey->key_flags &
1208 (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID)) {
1209 memcpy_ext(
1210 pmpriv->adapter,
1211 pkey_material->key_param_set.key_params.gcmp.pn,
1212 pkey->pn, SEQ_MAX_SIZE, WPA_PN_SIZE);
1213 }
1214 if (pkey->key_flags & KEY_FLAG_GCMP)
1215 pkey_material->key_param_set.key_type =
1216 KEY_TYPE_ID_GCMP;
1217 else
1218 pkey_material->key_param_set.key_type =
1219 KEY_TYPE_ID_GCMP_256;
1220 pkey_material->key_param_set.key_params.gcmp.key_len =
1221 wlan_cpu_to_le16(pkey->key_len);
1222 memcpy_ext(pmpriv->adapter,
1223 pkey_material->key_param_set.key_params.gcmp.key,
1224 pkey->key_material, pkey->key_len, WPA_GCMP_KEY_LEN);
1225 pkey_material->key_param_set.length = wlan_cpu_to_le16(
1226 KEY_PARAMS_FIXED_LEN + sizeof(gcmp_param));
1227 cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) +
1228 S_DS_GEN + KEY_PARAMS_FIXED_LEN +
1229 sizeof(gcmp_param) +
1230 sizeof(pkey_material->action));
1231
1232 goto done;
1233 }
1234 if (pkey->key_flags & KEY_FLAG_CCMP_256) {
1235 if (pkey->key_flags &
1236 (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID)) {
1237 memcpy_ext(pmpriv->adapter,
1238 pkey_material->key_param_set.key_params
1239 .ccmp256.pn,
1240 pkey->pn, SEQ_MAX_SIZE, WPA_PN_SIZE);
1241 }
1242 pkey_material->key_param_set.key_type = KEY_TYPE_ID_CCMP_256;
1243 pkey_material->key_param_set.key_params.ccmp256.key_len =
1244 wlan_cpu_to_le16(pkey->key_len);
1245 memcpy_ext(pmpriv->adapter,
1246 pkey_material->key_param_set.key_params.ccmp256.key,
1247 pkey->key_material, pkey->key_len,
1248 WPA_CCMP_256_KEY_LEN);
1249 pkey_material->key_param_set.length = wlan_cpu_to_le16(
1250 KEY_PARAMS_FIXED_LEN + sizeof(ccmp_256_param));
1251 cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) +
1252 S_DS_GEN + KEY_PARAMS_FIXED_LEN +
1253 sizeof(ccmp_256_param) +
1254 sizeof(pkey_material->action));
1255
1256 goto done;
1257 }
1258 if (pkey->key_len == WPA_AES_KEY_LEN &&
1259 !(pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK)) {
1260 if (pkey->key_flags &
1261 (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
1262 memcpy_ext(
1263 pmpriv->adapter,
1264 pkey_material->key_param_set.key_params.aes.pn,
1265 pkey->pn, SEQ_MAX_SIZE, WPA_PN_SIZE);
1266 pkey_material->key_param_set.key_type = KEY_TYPE_ID_AES;
1267 pkey_material->key_param_set.key_params.aes.key_len =
1268 wlan_cpu_to_le16(pkey->key_len);
1269 memcpy_ext(pmpriv->adapter,
1270 pkey_material->key_param_set.key_params.aes.key,
1271 pkey->key_material, pkey->key_len, WPA_AES_KEY_LEN);
1272 pkey_material->key_param_set.length = wlan_cpu_to_le16(
1273 KEY_PARAMS_FIXED_LEN + sizeof(aes_param));
1274 cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) +
1275 S_DS_GEN + KEY_PARAMS_FIXED_LEN +
1276 sizeof(aes_param) +
1277 sizeof(pkey_material->action));
1278 PRINTM(MCMND, "Set AES Key\n");
1279 goto done;
1280 }
1281 if (pkey->key_len == WPA_IGTK_KEY_LEN &&
1282 (pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK)) {
1283 if (pkey->key_flags &
1284 (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
1285 memcpy_ext(pmpriv->adapter,
1286 pkey_material->key_param_set.key_params
1287 .cmac_aes.ipn,
1288 pkey->pn, SEQ_MAX_SIZE, IGTK_PN_SIZE);
1289 pkey_material->key_param_set.key_info &=
1290 ~(wlan_cpu_to_le16(KEY_INFO_MCAST_KEY));
1291 pkey_material->key_param_set.key_info |=
1292 wlan_cpu_to_le16(KEY_INFO_AES_MCAST_IGTK);
1293 if (pkey->key_flags & KEY_FLAG_GMAC_128)
1294 pkey_material->key_param_set.key_type =
1295 KEY_TYPE_ID_BIP_GMAC_128;
1296 else
1297 pkey_material->key_param_set.key_type =
1298 KEY_TYPE_ID_AES_CMAC;
1299 pkey_material->key_param_set.key_params.cmac_aes.key_len =
1300 wlan_cpu_to_le16(pkey->key_len);
1301 memcpy_ext(pmpriv->adapter,
1302 pkey_material->key_param_set.key_params.cmac_aes.key,
1303 pkey->key_material, pkey->key_len, CMAC_AES_KEY_LEN);
1304 pkey_material->key_param_set.length = wlan_cpu_to_le16(
1305 KEY_PARAMS_FIXED_LEN + sizeof(cmac_aes_param));
1306 cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) +
1307 S_DS_GEN + KEY_PARAMS_FIXED_LEN +
1308 sizeof(cmac_aes_param) +
1309 sizeof(pkey_material->action));
1310 if (pkey->key_flags & KEY_FLAG_GMAC_128)
1311 PRINTM(MCMND, "Set AES 128 GMAC Key\n");
1312 else
1313 PRINTM(MCMND, "Set CMAC AES Key\n");
1314 goto done;
1315 }
1316 if (pkey->key_len == WPA_IGTK_256_KEY_LEN &&
1317 (pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK)) {
1318 if (pkey->key_flags &
1319 (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
1320 memcpy_ext(pmpriv->adapter,
1321 pkey_material->key_param_set.key_params
1322 .cmac_aes.ipn,
1323 pkey->pn, SEQ_MAX_SIZE, IGTK_PN_SIZE);
1324 pkey_material->key_param_set.key_info &=
1325 ~(wlan_cpu_to_le16(KEY_INFO_MCAST_KEY));
1326 pkey_material->key_param_set.key_info |=
1327 wlan_cpu_to_le16(KEY_INFO_AES_MCAST_IGTK);
1328 pkey_material->key_param_set.key_type =
1329 KEY_TYPE_ID_BIP_GMAC_256;
1330 pkey_material->key_param_set.key_params.cmac_aes.key_len =
1331 wlan_cpu_to_le16(pkey->key_len);
1332 memcpy_ext(pmpriv->adapter,
1333 pkey_material->key_param_set.key_params.cmac_aes.key,
1334 pkey->key_material, pkey->key_len,
1335 WPA_IGTK_256_KEY_LEN);
1336 pkey_material->key_param_set.length = wlan_cpu_to_le16(
1337 KEY_PARAMS_FIXED_LEN + sizeof(gmac_aes_256_param));
1338 cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) +
1339 S_DS_GEN + KEY_PARAMS_FIXED_LEN +
1340 sizeof(gmac_aes_256_param) +
1341 sizeof(pkey_material->action));
1342 PRINTM(MCMND, "Set AES 256 GMAC Key\n");
1343 goto done;
1344 }
1345 if (pkey->key_len == WPA_TKIP_KEY_LEN) {
1346 if (pkey->key_flags &
1347 (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
1348 memcpy_ext(
1349 pmpriv->adapter,
1350 pkey_material->key_param_set.key_params.tkip.pn,
1351 pkey->pn, SEQ_MAX_SIZE, WPA_PN_SIZE);
1352 pkey_material->key_param_set.key_type = KEY_TYPE_ID_TKIP;
1353 pkey_material->key_param_set.key_params.tkip.key_len =
1354 wlan_cpu_to_le16(pkey->key_len);
1355 memcpy_ext(pmpriv->adapter,
1356 pkey_material->key_param_set.key_params.tkip.key,
1357 pkey->key_material, pkey->key_len, WPA_TKIP_KEY_LEN);
1358 pkey_material->key_param_set.length = wlan_cpu_to_le16(
1359 KEY_PARAMS_FIXED_LEN + sizeof(tkip_param));
1360 cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) +
1361 S_DS_GEN + KEY_PARAMS_FIXED_LEN +
1362 sizeof(tkip_param) +
1363 sizeof(pkey_material->action));
1364 PRINTM(MCMND, "Set TKIP Key\n");
1365 }
1366 done:
1367 LEAVE();
1368 return ret;
1369 }
1370
1371 /**
1372 * @brief This function prepares command of gtk rekey offload
1373 *
1374 * @param pmpriv A pointer to mlan_private structure
1375 * @param cmd A pointer to HostCmd_DS_COMMAND structure
1376 * @param cmd_action The action: GET or SET
1377 * @param cmd_oid OID: ENABLE or DISABLE
1378 * @param pdata_buf A pointer to data buffer
1379 *
1380 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1381 */
wlan_cmd_gtk_rekey_offload(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_u32 cmd_oid,t_void * pdata_buf)1382 static mlan_status wlan_cmd_gtk_rekey_offload(pmlan_private pmpriv,
1383 HostCmd_DS_COMMAND *cmd,
1384 t_u16 cmd_action, t_u32 cmd_oid,
1385 t_void *pdata_buf)
1386 {
1387 HostCmd_DS_GTK_REKEY_PARAMS *rekey = &cmd->params.gtk_rekey;
1388 mlan_ds_misc_gtk_rekey_data *data =
1389 (mlan_ds_misc_gtk_rekey_data *)pdata_buf;
1390 t_u64 rekey_ctr;
1391
1392 ENTER();
1393 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG);
1394 cmd->size = wlan_cpu_to_le16(sizeof(*rekey) + S_DS_GEN);
1395
1396 rekey->action = wlan_cpu_to_le16(cmd_action);
1397 if (cmd_action == HostCmd_ACT_GEN_SET) {
1398 memcpy_ext(pmpriv->adapter, rekey->kek, data->kek, MLAN_KEK_LEN,
1399 MLAN_KEK_LEN);
1400 memcpy_ext(pmpriv->adapter, rekey->kck, data->kck, MLAN_KCK_LEN,
1401 MLAN_KCK_LEN);
1402 rekey_ctr = wlan_le64_to_cpu(
1403 swap_byte_64(*(t_u64 *)data->replay_ctr));
1404 rekey->replay_ctr_low = wlan_cpu_to_le32((t_u32)rekey_ctr);
1405 rekey->replay_ctr_high =
1406 wlan_cpu_to_le32((t_u64)rekey_ctr >> 32);
1407 }
1408
1409 LEAVE();
1410 return MLAN_STATUS_SUCCESS;
1411 }
1412
1413 /**
1414 * @brief This function send eapol pkt to FW
1415 *
1416 * @param pmpriv A pointer to mlan_private structure
1417 * @param cmd A pointer to HostCmd_DS_COMMAND structure
1418 * @param cmd_action the action: GET or SET
1419 * @param pdata_buf A pointer to data buffer
1420 *
1421 * @return MLAN_STATUS_SUCCESS
1422 */
wlan_cmd_eapol_pkt(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)1423 static mlan_status wlan_cmd_eapol_pkt(pmlan_private pmpriv,
1424 HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
1425 t_void *pdata_buf)
1426 {
1427 HostCmd_DS_EAPOL_PKT *eapol_pkt = &cmd->params.eapol_pkt;
1428 mlan_buffer *pmbuf = (mlan_buffer *)pdata_buf;
1429
1430 ENTER();
1431 eapol_pkt->action = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
1432 cmd->size = sizeof(HostCmd_DS_EAPOL_PKT) + S_DS_GEN;
1433 cmd->command = wlan_cpu_to_le16(cmd->command);
1434
1435 eapol_pkt->tlv_eapol.header.type = wlan_cpu_to_le16(TLV_TYPE_EAPOL_PKT);
1436 eapol_pkt->tlv_eapol.header.len = wlan_cpu_to_le16(pmbuf->data_len);
1437 memcpy_ext(pmpriv->adapter, eapol_pkt->tlv_eapol.pkt_buf,
1438 pmbuf->pbuf + pmbuf->data_offset, pmbuf->data_len,
1439 pmbuf->data_len);
1440 cmd->size += pmbuf->data_len;
1441 cmd->size = wlan_cpu_to_le16(cmd->size);
1442
1443 LEAVE();
1444 return MLAN_STATUS_SUCCESS;
1445 }
1446
1447 /**
1448 * @brief Handle the supplicant profile command
1449 *
1450 * @param pmpriv A pointer to mlan_private structure
1451 * @param cmd A pointer to HostCmd_DS_COMMAND structure
1452 * @param cmd_action The action: GET or SET
1453 *
1454 * @return MLAN_STATUS_SUCCESS
1455 */
wlan_cmd_802_11_supplicant_profile(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)1456 static mlan_status wlan_cmd_802_11_supplicant_profile(pmlan_private pmpriv,
1457 HostCmd_DS_COMMAND *cmd,
1458 t_u16 cmd_action,
1459 t_void *pdata_buf)
1460 {
1461 HostCmd_DS_802_11_SUPPLICANT_PROFILE *sup_profile =
1462 (HostCmd_DS_802_11_SUPPLICANT_PROFILE *)&(
1463 cmd->params.esupplicant_profile);
1464 MrvlIEtypes_EncrProto_t *encr_proto_tlv = MNULL;
1465 MrvlIEtypes_Cipher_t *pcipher_tlv = MNULL;
1466 t_u8 *ptlv_buffer = (t_u8 *)sup_profile->tlv_buf;
1467 mlan_ds_esupp_mode *esupp = MNULL;
1468
1469 ENTER();
1470
1471 cmd->size = wlan_cpu_to_le16(
1472 sizeof(HostCmd_DS_802_11_SUPPLICANT_PROFILE) + S_DS_GEN - 1);
1473 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_SUPPLICANT_PROFILE);
1474 sup_profile->action = wlan_cpu_to_le16(cmd_action);
1475 if ((cmd_action == HostCmd_ACT_GEN_SET) && pdata_buf) {
1476 esupp = (mlan_ds_esupp_mode *)pdata_buf;
1477 if (esupp->rsn_mode) {
1478 encr_proto_tlv = (MrvlIEtypes_EncrProto_t *)ptlv_buffer;
1479 encr_proto_tlv->header.type =
1480 wlan_cpu_to_le16(TLV_TYPE_ENCRYPTION_PROTO);
1481 encr_proto_tlv->header.len =
1482 (t_u16)sizeof(encr_proto_tlv->rsn_mode);
1483 encr_proto_tlv->rsn_mode =
1484 wlan_cpu_to_le16(esupp->rsn_mode);
1485 ptlv_buffer += (encr_proto_tlv->header.len +
1486 sizeof(MrvlIEtypesHeader_t));
1487 cmd->size += (encr_proto_tlv->header.len +
1488 sizeof(MrvlIEtypesHeader_t));
1489 encr_proto_tlv->header.len =
1490 wlan_cpu_to_le16(encr_proto_tlv->header.len);
1491 }
1492 if (esupp->act_paircipher || esupp->act_groupcipher) {
1493 pcipher_tlv = (MrvlIEtypes_Cipher_t *)ptlv_buffer;
1494 pcipher_tlv->header.type =
1495 wlan_cpu_to_le16(TLV_TYPE_CIPHER);
1496 pcipher_tlv->header.len =
1497 (t_u16)(sizeof(pcipher_tlv->pair_cipher) +
1498 sizeof(pcipher_tlv->group_cipher));
1499 if (esupp->act_paircipher) {
1500 pcipher_tlv->pair_cipher =
1501 esupp->act_paircipher & 0xff;
1502 }
1503 if (esupp->act_groupcipher) {
1504 pcipher_tlv->group_cipher =
1505 esupp->act_groupcipher & 0xff;
1506 }
1507 ptlv_buffer += (pcipher_tlv->header.len +
1508 sizeof(MrvlIEtypesHeader_t));
1509 cmd->size += (pcipher_tlv->header.len +
1510 sizeof(MrvlIEtypesHeader_t));
1511 pcipher_tlv->header.len =
1512 wlan_cpu_to_le16(pcipher_tlv->header.len);
1513 }
1514 }
1515 cmd->size = wlan_cpu_to_le16(cmd->size);
1516 LEAVE();
1517 return MLAN_STATUS_SUCCESS;
1518 }
1519
1520 /**
1521 * @brief This function prepares command of rf_channel.
1522 *
1523 * @param pmpriv A pointer to mlan_private structure
1524 * @param cmd A pointer to HostCmd_DS_COMMAND structure
1525 * @param cmd_action The action: GET or SET
1526 * @param pdata_buf A pointer to data buffer
1527 *
1528 * @return MLAN_STATUS_SUCCESS
1529 */
wlan_cmd_802_11_rf_channel(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)1530 static mlan_status wlan_cmd_802_11_rf_channel(pmlan_private pmpriv,
1531 HostCmd_DS_COMMAND *cmd,
1532 t_u16 cmd_action,
1533 t_void *pdata_buf)
1534 {
1535 HostCmd_DS_802_11_RF_CHANNEL *prf_chan = &cmd->params.rf_channel;
1536
1537 ENTER();
1538
1539 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_RF_CHANNEL);
1540 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_RF_CHANNEL) +
1541 S_DS_GEN);
1542
1543 if (cmd_action == HostCmd_ACT_GEN_SET) {
1544 if ((pmpriv->adapter->adhoc_start_band & BAND_A))
1545 prf_chan->rf_type.bandcfg.chanBand = BAND_5GHZ;
1546 prf_chan->rf_type.bandcfg.chanWidth =
1547 pmpriv->adapter->chan_bandwidth;
1548 prf_chan->current_channel =
1549 wlan_cpu_to_le16(*((t_u16 *)pdata_buf));
1550 }
1551 prf_chan->action = wlan_cpu_to_le16(cmd_action);
1552 LEAVE();
1553 return MLAN_STATUS_SUCCESS;
1554 }
1555
1556 /**
1557 * @brief This function prepares command of ibss_coalescing_status.
1558 *
1559 * @param pmpriv A pointer to mlan_private structure
1560 * @param cmd A pointer to HostCmd_DS_COMMAND structure
1561 * @param cmd_action The action: GET or SET
1562 * @param pdata_buf A pointer to data buffer or MNULL
1563 *
1564 * @return MLAN_STATUS_SUCCESS
1565 */
wlan_cmd_ibss_coalescing_status(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)1566 static mlan_status wlan_cmd_ibss_coalescing_status(pmlan_private pmpriv,
1567 HostCmd_DS_COMMAND *cmd,
1568 t_u16 cmd_action,
1569 t_void *pdata_buf)
1570 {
1571 HostCmd_DS_802_11_IBSS_STATUS *pibss_coal =
1572 &(cmd->params.ibss_coalescing);
1573 t_u16 enable = 0;
1574
1575 ENTER();
1576
1577 cmd->command =
1578 wlan_cpu_to_le16(HostCmd_CMD_802_11_IBSS_COALESCING_STATUS);
1579 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_IBSS_STATUS) +
1580 S_DS_GEN);
1581 cmd->result = 0;
1582 pibss_coal->action = wlan_cpu_to_le16(cmd_action);
1583
1584 switch (cmd_action) {
1585 case HostCmd_ACT_GEN_SET:
1586 if (pdata_buf != MNULL)
1587 enable = *(t_u16 *)pdata_buf;
1588 pibss_coal->enable = wlan_cpu_to_le16(enable);
1589 break;
1590
1591 /* In other case.. Nothing to do */
1592 case HostCmd_ACT_GEN_GET:
1593 default:
1594 break;
1595 }
1596
1597 LEAVE();
1598 return MLAN_STATUS_SUCCESS;
1599 }
1600
1601 /**
1602 * @brief This function prepares command of mgmt IE list.
1603 *
1604 * @param pmpriv A pointer to mlan_private structure
1605 * @param cmd A pointer to HostCmd_DS_COMMAND structure
1606 * @param cmd_action The action: GET or SET
1607 * @param pdata_buf A pointer to data buffer
1608 *
1609 * @return MLAN_STATUS_SUCCESS
1610 */
wlan_cmd_mgmt_ie_list(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)1611 static mlan_status wlan_cmd_mgmt_ie_list(pmlan_private pmpriv,
1612 HostCmd_DS_COMMAND *cmd,
1613 t_u16 cmd_action, t_void *pdata_buf)
1614 {
1615 t_u16 req_len = 0, travel_len = 0;
1616 custom_ie *cptr = MNULL;
1617 mlan_ds_misc_custom_ie *cust_ie = MNULL;
1618 HostCmd_DS_MGMT_IE_LIST_CFG *pmgmt_ie_list =
1619 &(cmd->params.mgmt_ie_list);
1620
1621 ENTER();
1622
1623 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MGMT_IE_LIST);
1624 cmd->size = sizeof(HostCmd_DS_MGMT_IE_LIST_CFG) + S_DS_GEN;
1625 cmd->result = 0;
1626 pmgmt_ie_list->action = wlan_cpu_to_le16(cmd_action);
1627
1628 cust_ie = (mlan_ds_misc_custom_ie *)pdata_buf;
1629 pmgmt_ie_list->ds_mgmt_ie.type = wlan_cpu_to_le16(cust_ie->type);
1630 pmgmt_ie_list->ds_mgmt_ie.len = wlan_cpu_to_le16(cust_ie->len);
1631
1632 req_len = cust_ie->len;
1633 if (req_len > sizeof(cust_ie->ie_data_list)) {
1634 PRINTM(MERROR, "Invalid cust_ie->len=%d\n", req_len);
1635 LEAVE();
1636 return MLAN_STATUS_FAILURE;
1637 }
1638 travel_len = 0;
1639 /* conversion for index, mask, len */
1640 if (req_len == sizeof(t_u16))
1641 cust_ie->ie_data_list[0].ie_index =
1642 wlan_cpu_to_le16(cust_ie->ie_data_list[0].ie_index);
1643
1644 while (req_len > sizeof(t_u16)) {
1645 cptr = (custom_ie *)(((t_u8 *)cust_ie->ie_data_list) +
1646 travel_len);
1647 travel_len += cptr->ie_length + sizeof(custom_ie) - MAX_IE_SIZE;
1648 req_len -= cptr->ie_length + sizeof(custom_ie) - MAX_IE_SIZE;
1649 cptr->ie_index = wlan_cpu_to_le16(cptr->ie_index);
1650 cptr->mgmt_subtype_mask =
1651 wlan_cpu_to_le16(cptr->mgmt_subtype_mask);
1652 cptr->ie_length = wlan_cpu_to_le16(cptr->ie_length);
1653 }
1654 if (cust_ie->len)
1655 memcpy_ext(pmpriv->adapter,
1656 pmgmt_ie_list->ds_mgmt_ie.ie_data_list,
1657 cust_ie->ie_data_list, cust_ie->len,
1658 sizeof(pmgmt_ie_list->ds_mgmt_ie.ie_data_list));
1659
1660 cmd->size -= (MAX_MGMT_IE_INDEX_TO_FW * sizeof(custom_ie)) +
1661 sizeof(tlvbuf_max_mgmt_ie);
1662 cmd->size += cust_ie->len;
1663 cmd->size = wlan_cpu_to_le16(cmd->size);
1664
1665 LEAVE();
1666 return MLAN_STATUS_SUCCESS;
1667 }
1668
1669 /**
1670 * @brief This function prepares command of TDLS configuration.
1671 *
1672 * @param pmpriv A pointer to mlan_private structure
1673 * @param cmd A pointer to HostCmd_DS_COMMAND structure
1674 * @param cmd_action The action: GET or SET
1675 * @param pdata_buf A pointer to data buffer
1676 *
1677 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1678 */
wlan_cmd_tdls_config(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)1679 static mlan_status wlan_cmd_tdls_config(pmlan_private pmpriv,
1680 HostCmd_DS_COMMAND *cmd,
1681 t_u16 cmd_action, t_void *pdata_buf)
1682 {
1683 t_u16 travel_len = 0;
1684 mlan_ds_misc_tdls_config *tdls_config = MNULL;
1685 tdls_all_config *tdls_all_cfg = MNULL;
1686 HostCmd_DS_TDLS_CONFIG *ptdls_config_data =
1687 &(cmd->params.tdls_config_data);
1688 t_u8 zero_mac[] = {0, 0, 0, 0, 0, 0};
1689
1690 ENTER();
1691
1692 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_TDLS_CONFIG);
1693 cmd->size = sizeof(HostCmd_DS_TDLS_CONFIG) + S_DS_GEN;
1694 cmd->result = 0;
1695
1696 tdls_config = (mlan_ds_misc_tdls_config *)pdata_buf;
1697 ptdls_config_data->tdls_info.tdls_action =
1698 wlan_cpu_to_le16(tdls_config->tdls_action);
1699
1700 tdls_all_cfg = (tdls_all_config *)tdls_config->tdls_data;
1701
1702 switch (tdls_config->tdls_action) {
1703 case WLAN_TDLS_CONFIG:
1704 travel_len = sizeof(tdls_all_cfg->u.tdls_config);
1705 tdls_all_cfg->u.tdls_config.enable =
1706 wlan_cpu_to_le16(tdls_all_cfg->u.tdls_config.enable);
1707 memcpy_ext(pmpriv->adapter,
1708 ptdls_config_data->tdls_info.tdls_data,
1709 &tdls_all_cfg->u.tdls_setup, travel_len,
1710 MAX_TDLS_DATA_LEN);
1711 break;
1712
1713 case WLAN_TDLS_SET_INFO:
1714 travel_len = tdls_all_cfg->u.tdls_set.tlv_length;
1715 if ((travel_len + sizeof(t_u16)) > MAX_TDLS_DATA_LEN) {
1716 PRINTM(MERROR, "TDLS configuration overflow\n");
1717 LEAVE();
1718 return MLAN_STATUS_FAILURE;
1719 }
1720 memcpy_ext(pmpriv->adapter,
1721 ptdls_config_data->tdls_info.tdls_data,
1722 (t_u8 *)&tdls_all_cfg->u.tdls_set.cap_info,
1723 sizeof(t_u16), sizeof(t_u16));
1724 memcpy_ext(pmpriv->adapter,
1725 (t_u8 *)ptdls_config_data->tdls_info.tdls_data +
1726 sizeof(t_u16),
1727 &tdls_all_cfg->u.tdls_set.tlv_buffer, travel_len,
1728 MAX_TDLS_DATA_LEN - sizeof(t_u16));
1729 travel_len += sizeof(t_u16);
1730 break;
1731 case WLAN_TDLS_DISCOVERY_REQ:
1732 travel_len = MLAN_MAC_ADDR_LENGTH;
1733 memcpy_ext(pmpriv->adapter,
1734 ptdls_config_data->tdls_info.tdls_data,
1735 tdls_all_cfg->u.tdls_discovery.peer_mac_addr,
1736 travel_len, MAX_TDLS_DATA_LEN);
1737 break;
1738
1739 case WLAN_TDLS_SETUP_REQ:
1740 travel_len = sizeof(tdls_all_cfg->u.tdls_setup);
1741 tdls_all_cfg->u.tdls_setup.setup_timeout = wlan_cpu_to_le32(
1742 tdls_all_cfg->u.tdls_setup.setup_timeout);
1743 tdls_all_cfg->u.tdls_setup.key_lifetime = wlan_cpu_to_le32(
1744 tdls_all_cfg->u.tdls_setup.key_lifetime);
1745 memcpy_ext(pmpriv->adapter,
1746 ptdls_config_data->tdls_info.tdls_data,
1747 &tdls_all_cfg->u.tdls_setup, travel_len,
1748 MAX_TDLS_DATA_LEN);
1749 break;
1750
1751 case WLAN_TDLS_TEAR_DOWN_REQ:
1752 travel_len = sizeof(tdls_all_cfg->u.tdls_tear_down);
1753 tdls_all_cfg->u.tdls_tear_down.reason_code = wlan_cpu_to_le16(
1754 tdls_all_cfg->u.tdls_tear_down.reason_code);
1755 memcpy_ext(pmpriv->adapter,
1756 ptdls_config_data->tdls_info.tdls_data,
1757 &tdls_all_cfg->u.tdls_tear_down, travel_len,
1758 MAX_TDLS_DATA_LEN);
1759 break;
1760 case WLAN_TDLS_STOP_CHAN_SWITCH:
1761 travel_len = MLAN_MAC_ADDR_LENGTH;
1762 memcpy_ext(pmpriv->adapter,
1763 ptdls_config_data->tdls_info.tdls_data,
1764 tdls_all_cfg->u.tdls_stop_chan_switch.peer_mac_addr,
1765 travel_len, MAX_TDLS_DATA_LEN);
1766 break;
1767 case WLAN_TDLS_INIT_CHAN_SWITCH:
1768 travel_len = sizeof(tdls_all_cfg->u.tdls_chan_switch);
1769 tdls_all_cfg->u.tdls_chan_switch.switch_time = wlan_cpu_to_le16(
1770 tdls_all_cfg->u.tdls_chan_switch.switch_time);
1771 tdls_all_cfg->u.tdls_chan_switch.switch_timeout =
1772 wlan_cpu_to_le16(
1773 tdls_all_cfg->u.tdls_chan_switch.switch_timeout);
1774 memcpy_ext(pmpriv->adapter,
1775 ptdls_config_data->tdls_info.tdls_data,
1776 &tdls_all_cfg->u.tdls_chan_switch, travel_len,
1777 MAX_TDLS_DATA_LEN);
1778 break;
1779 case WLAN_TDLS_CS_PARAMS:
1780 travel_len = sizeof(tdls_all_cfg->u.tdls_cs_params);
1781 memcpy_ext(pmpriv->adapter,
1782 ptdls_config_data->tdls_info.tdls_data,
1783 &tdls_all_cfg->u.tdls_cs_params, travel_len,
1784 MAX_TDLS_DATA_LEN);
1785 break;
1786 case WLAN_TDLS_CS_DISABLE:
1787 travel_len = sizeof(tdls_all_cfg->u.tdls_disable_cs);
1788 tdls_all_cfg->u.tdls_disable_cs.data =
1789 wlan_cpu_to_le16(tdls_all_cfg->u.tdls_disable_cs.data);
1790 memcpy_ext(pmpriv->adapter,
1791 ptdls_config_data->tdls_info.tdls_data,
1792 &tdls_all_cfg->u.tdls_disable_cs, travel_len,
1793 MAX_TDLS_DATA_LEN);
1794 break;
1795 case WLAN_TDLS_POWER_MODE:
1796 travel_len = sizeof(tdls_all_cfg->u.tdls_power_mode);
1797 tdls_all_cfg->u.tdls_power_mode.power_mode = wlan_cpu_to_le16(
1798 tdls_all_cfg->u.tdls_power_mode.power_mode);
1799 memcpy_ext(pmpriv->adapter,
1800 ptdls_config_data->tdls_info.tdls_data,
1801 &tdls_all_cfg->u.tdls_power_mode, travel_len,
1802 MAX_TDLS_DATA_LEN);
1803 break;
1804
1805 case WLAN_TDLS_LINK_STATUS:
1806 travel_len = 0;
1807 if (memcmp(pmpriv->adapter,
1808 tdls_all_cfg->u.tdls_link_status_req.peer_mac_addr,
1809 zero_mac, sizeof(zero_mac))) {
1810 travel_len =
1811 sizeof(tdls_all_cfg->u.tdls_link_status_req);
1812 memcpy_ext(pmpriv->adapter,
1813 ptdls_config_data->tdls_info.tdls_data,
1814 tdls_all_cfg->u.tdls_link_status_req
1815 .peer_mac_addr,
1816 travel_len, MAX_TDLS_DATA_LEN);
1817 }
1818 break;
1819
1820 case WLAN_TDLS_DEBUG_ALLOW_WEAK_SECURITY:
1821 case WLAN_TDLS_DEBUG_SETUP_SAME_LINK:
1822 case WLAN_TDLS_DEBUG_FAIL_SETUP_CONFIRM:
1823 case WLAN_TDLS_DEBUG_WRONG_BSS:
1824 case WLAN_TDLS_DEBUG_SETUP_PROHIBITED:
1825 case WLAN_TDLS_DEBUG_HIGHER_LOWER_MAC:
1826 case WLAN_TDLS_DEBUG_IGNORE_KEY_EXPIRY:
1827 case WLAN_TDLS_DEBUG_STOP_RX:
1828 case WLAN_TDLS_DEBUG_CS_RET_IM:
1829 travel_len = sizeof(tdls_all_cfg->u.tdls_debug_data);
1830 tdls_all_cfg->u.tdls_debug_data.debug_data = wlan_cpu_to_le16(
1831 tdls_all_cfg->u.tdls_debug_data.debug_data);
1832 memcpy_ext(pmpriv->adapter,
1833 ptdls_config_data->tdls_info.tdls_data,
1834 &tdls_all_cfg->u.tdls_debug_data, travel_len,
1835 MAX_TDLS_DATA_LEN);
1836 break;
1837
1838 default:
1839 LEAVE();
1840 return MLAN_STATUS_FAILURE;
1841 }
1842
1843 cmd->size += travel_len;
1844 cmd->size -= MAX_TDLS_DATA_LEN;
1845 cmd->size = wlan_cpu_to_le16(cmd->size);
1846
1847 LEAVE();
1848 return MLAN_STATUS_SUCCESS;
1849 }
1850
1851 /**
1852 * @brief This function prepares command of TDLS create/config/delete
1853 *
1854 * @param pmpriv A pointer to mlan_private structure
1855 * @param cmd A pointer to HostCmd_DS_COMMAND structure
1856 * @param cmd_action The action: GET or SET
1857 * @param pdata_buf A pointer to data buffer
1858 *
1859 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1860 */
wlan_cmd_tdls_oper(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)1861 static mlan_status wlan_cmd_tdls_oper(pmlan_private pmpriv,
1862 HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
1863 t_void *pdata_buf)
1864 {
1865 t_u16 travel_len = 0;
1866 mlan_ds_misc_tdls_oper *tdls_oper = MNULL;
1867 HostCmd_DS_TDLS_OPER *ptdls_oper = &(cmd->params.tdls_oper_data);
1868 sta_node *sta_ptr;
1869 t_u8 *pos;
1870 MrvlIEtypes_RatesParamSet_t *Rate_tlv = MNULL;
1871 MrvlIETypes_HTCap_t *HTcap_tlv = MNULL;
1872 MrvlIETypes_HTInfo_t *HTInfo_tlv = MNULL;
1873 MrvlIETypes_2040BSSCo_t *BSSCo = MNULL;
1874 MrvlIETypes_ExtCap_t *ExCap = MNULL;
1875 MrvlIEtypes_RsnParamSet_t *Rsn_ie = MNULL;
1876 MrvlIETypes_qosinfo_t *qos_info = MNULL;
1877 MrvlIETypes_LinkIDElement_t *LinkID = MNULL;
1878 BSSDescriptor_t *pbss_desc = &pmpriv->curr_bss_params.bss_descriptor;
1879 MrvlIETypes_VHTCap_t *VHTcap_tlv = MNULL;
1880 MrvlIETypes_VHTOprat_t *VHTOper_tlv = MNULL;
1881 MrvlIETypes_AID_t *AidInfo = MNULL;
1882 MrvlIEtypes_Extension_t *hecap_tlv = MNULL;
1883 MrvlIEtypes_He_Op_t *heop_tlv = MNULL;
1884 MrvlIEtypes_TDLS_Idle_Timeout_t *TdlsIdleTimeout = MNULL;
1885
1886 ENTER();
1887
1888 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_TDLS_OPERATION);
1889 cmd->size = sizeof(HostCmd_DS_TDLS_OPER) + S_DS_GEN;
1890 cmd->result = 0;
1891
1892 tdls_oper = (mlan_ds_misc_tdls_oper *)pdata_buf;
1893 ptdls_oper->reason = 0;
1894 memcpy_ext(pmpriv->adapter, ptdls_oper->peer_mac, tdls_oper->peer_mac,
1895 MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
1896 sta_ptr = wlan_get_station_entry(pmpriv, tdls_oper->peer_mac);
1897 pos = (t_u8 *)ptdls_oper + sizeof(HostCmd_DS_TDLS_OPER);
1898 switch (tdls_oper->tdls_action) {
1899 case WLAN_TDLS_CREATE_LINK:
1900 if (sta_ptr)
1901 sta_ptr->status = TDLS_SETUP_INPROGRESS;
1902 ptdls_oper->tdls_action = wlan_cpu_to_le16(TDLS_CREATE);
1903 break;
1904 case WLAN_TDLS_CONFIG_LINK:
1905 if (sta_ptr) {
1906 ptdls_oper->tdls_action = wlan_cpu_to_le16(TDLS_CONFIG);
1907 /*capability*/
1908 *(t_u16 *)pos = wlan_cpu_to_le16(sta_ptr->capability);
1909 travel_len += sizeof(sta_ptr->capability);
1910
1911 /*supported rate*/
1912 Rate_tlv = (MrvlIEtypes_RatesParamSet_t *)(pos +
1913 travel_len);
1914 Rate_tlv->header.type =
1915 wlan_cpu_to_le16(TLV_TYPE_RATES);
1916 Rate_tlv->header.len =
1917 wlan_cpu_to_le16(sta_ptr->rate_len);
1918 memcpy_ext(pmpriv->adapter,
1919 pos + travel_len +
1920 sizeof(MrvlIEtypesHeader_t),
1921 sta_ptr->support_rate, sta_ptr->rate_len,
1922 sta_ptr->rate_len);
1923 travel_len +=
1924 sizeof(MrvlIEtypesHeader_t) + sta_ptr->rate_len;
1925
1926 /*Extended capability */
1927 if (sta_ptr->ExtCap.ieee_hdr.element_id ==
1928 EXT_CAPABILITY) {
1929 ExCap = (MrvlIETypes_ExtCap_t *)(pos +
1930 travel_len);
1931 ExCap->header.type =
1932 wlan_cpu_to_le16(TLV_TYPE_EXTCAP);
1933 ExCap->header.len = wlan_cpu_to_le16(
1934 sta_ptr->ExtCap.ieee_hdr.len);
1935 memcpy_ext(pmpriv->adapter, &ExCap->ext_cap,
1936 &sta_ptr->ExtCap.ext_cap,
1937 sta_ptr->ExtCap.ieee_hdr.len,
1938 sta_ptr->ExtCap.ieee_hdr.len);
1939 travel_len += sta_ptr->ExtCap.ieee_hdr.len +
1940 sizeof(MrvlIEtypesHeader_t);
1941 }
1942 if (ExCap) {
1943 if (pmpriv->host_tdls_uapsd_support &&
1944 ISSUPP_EXTCAP_TDLS_UAPSD(ExCap->ext_cap)) {
1945 /* qos_info */
1946 qos_info =
1947 (MrvlIETypes_qosinfo_t
1948 *)(pos + travel_len);
1949 qos_info->header.type =
1950 wlan_cpu_to_le16(QOS_INFO);
1951 qos_info->header.len =
1952 wlan_cpu_to_le16(sizeof(t_u8));
1953 qos_info->qos_info = sta_ptr->qos_info;
1954 travel_len +=
1955 sizeof(MrvlIETypes_qosinfo_t);
1956 } else {
1957 RESET_EXTCAP_TDLS_UAPSD(ExCap->ext_cap);
1958 }
1959
1960 if (!(pmpriv->host_tdls_cs_support &&
1961 ISSUPP_EXTCAP_TDLS_CHAN_SWITCH(
1962 ExCap->ext_cap)))
1963 RESET_EXTCAP_TDLS_CHAN_SWITCH(
1964 ExCap->ext_cap);
1965 }
1966
1967 /*RSN ie*/
1968 if (sta_ptr->rsn_ie.ieee_hdr.element_id == RSN_IE) {
1969 Rsn_ie = (MrvlIEtypes_RsnParamSet_t
1970 *)(pos + travel_len);
1971 Rsn_ie->header.type = wlan_cpu_to_le16(
1972 sta_ptr->rsn_ie.ieee_hdr.element_id);
1973 Rsn_ie->header.len = wlan_cpu_to_le16(
1974 sta_ptr->rsn_ie.ieee_hdr.len);
1975 memcpy_ext(pmpriv->adapter, Rsn_ie->rsn_ie,
1976 sta_ptr->rsn_ie.data,
1977 sta_ptr->rsn_ie.ieee_hdr.len,
1978 sta_ptr->rsn_ie.ieee_hdr.len);
1979 travel_len += sta_ptr->rsn_ie.ieee_hdr.len +
1980 sizeof(MrvlIEtypesHeader_t);
1981 }
1982 /*Link ID*/
1983 if (sta_ptr->link_ie.element_id == LINK_ID) {
1984 LinkID = (MrvlIETypes_LinkIDElement_t
1985 *)(pos + travel_len);
1986 LinkID->header.type = wlan_cpu_to_le16(LINK_ID);
1987 LinkID->header.len =
1988 wlan_cpu_to_le16(sta_ptr->link_ie.len);
1989 memcpy_ext(pmpriv->adapter, &LinkID->bssid,
1990 &sta_ptr->link_ie.bssid,
1991 sta_ptr->link_ie.len,
1992 sizeof(LinkID->bssid));
1993 travel_len += sta_ptr->link_ie.len +
1994 sizeof(MrvlIEtypesHeader_t);
1995 }
1996 /*HT capability*/
1997 if (sta_ptr->HTcap.ieee_hdr.element_id ==
1998 HT_CAPABILITY) {
1999 HTcap_tlv = (MrvlIETypes_HTCap_t *)(pos +
2000 travel_len);
2001 HTcap_tlv->header.type =
2002 wlan_cpu_to_le16(TLV_TYPE_HT_CAP);
2003 HTcap_tlv->header.len = wlan_cpu_to_le16(
2004 sta_ptr->HTcap.ieee_hdr.len);
2005 memcpy_ext(pmpriv->adapter, &HTcap_tlv->ht_cap,
2006 &sta_ptr->HTcap.ht_cap,
2007 sta_ptr->HTcap.ieee_hdr.len,
2008 sizeof(HTcap_tlv->ht_cap));
2009 travel_len += sta_ptr->HTcap.ieee_hdr.len +
2010 sizeof(MrvlIEtypesHeader_t);
2011 }
2012 if (HTcap_tlv) {
2013 if (pmpriv->host_tdls_cs_support &&
2014 (pmpriv->adapter->fw_bands & BAND_A))
2015 wlan_fill_ht_cap_tlv(pmpriv, HTcap_tlv,
2016 BAND_A, MFALSE);
2017 else
2018 wlan_fill_ht_cap_tlv(
2019 pmpriv, HTcap_tlv,
2020 pbss_desc->bss_band, MFALSE);
2021 DBG_HEXDUMP(MCMD_D, "FW htcap",
2022 (t_u8 *)HTcap_tlv,
2023 sizeof(MrvlIETypes_HTCap_t));
2024 }
2025
2026 /*HT info*/
2027 if (sta_ptr->HTInfo.ieee_hdr.element_id ==
2028 HT_OPERATION) {
2029 HTInfo_tlv =
2030 (MrvlIETypes_HTInfo_t *)(pos +
2031 travel_len);
2032 HTInfo_tlv->header.type =
2033 wlan_cpu_to_le16(TLV_TYPE_HT_INFO);
2034 HTInfo_tlv->header.len = wlan_cpu_to_le16(
2035 sta_ptr->HTInfo.ieee_hdr.len);
2036 memcpy_ext(pmpriv->adapter,
2037 &HTInfo_tlv->ht_info,
2038 &sta_ptr->HTInfo.ht_info,
2039 sta_ptr->HTInfo.ieee_hdr.len,
2040 sizeof(HTInfo_tlv->ht_info));
2041 travel_len += sta_ptr->HTInfo.ieee_hdr.len +
2042 sizeof(MrvlIEtypesHeader_t);
2043 DBG_HEXDUMP(MCMD_D, "HT Info",
2044 (t_u8 *)HTInfo_tlv,
2045 sizeof(MrvlIETypes_HTInfo_t));
2046 }
2047 /*20/40 BSS co-exist*/
2048 if (sta_ptr->BSSCO_20_40.ieee_hdr.element_id ==
2049 BSSCO_2040) {
2050 BSSCo = (MrvlIETypes_2040BSSCo_t *)(pos +
2051 travel_len);
2052 BSSCo->header.type = wlan_cpu_to_le16(
2053 TLV_TYPE_2040BSS_COEXISTENCE);
2054 BSSCo->header.len = wlan_cpu_to_le16(
2055 sta_ptr->BSSCO_20_40.ieee_hdr.len);
2056 memcpy_ext(pmpriv->adapter, &BSSCo->bss_co_2040,
2057 &sta_ptr->BSSCO_20_40.bss_co_2040,
2058 sta_ptr->BSSCO_20_40.ieee_hdr.len,
2059 sizeof(BSSCo->bss_co_2040));
2060 travel_len +=
2061 sta_ptr->BSSCO_20_40.ieee_hdr.len +
2062 sizeof(MrvlIEtypesHeader_t);
2063 }
2064 /* Check if we need enable the 11AC */
2065 if (sta_ptr && sta_ptr->vht_oprat.ieee_hdr.element_id ==
2066 VHT_OPERATION) {
2067 /** AID */
2068 if (sta_ptr->aid_info.ieee_hdr.element_id ==
2069 AID_INFO) {
2070 AidInfo = (MrvlIETypes_AID_t
2071 *)(pos + travel_len);
2072 AidInfo->header.type =
2073 wlan_cpu_to_le16(AID_INFO);
2074 AidInfo->header.len = wlan_cpu_to_le16(
2075 sta_ptr->aid_info.ieee_hdr.len);
2076 AidInfo->AID = wlan_cpu_to_le16(
2077 sta_ptr->aid_info.AID);
2078 travel_len += sizeof(MrvlIETypes_AID_t);
2079 }
2080 /* Vht capability */
2081 if (sta_ptr->vht_cap.ieee_hdr.element_id ==
2082 VHT_CAPABILITY) {
2083 VHTcap_tlv =
2084 (MrvlIETypes_VHTCap_t
2085 *)(pos + travel_len);
2086 VHTcap_tlv->header.type =
2087 wlan_cpu_to_le16(
2088 VHT_CAPABILITY);
2089 VHTcap_tlv->header
2090 .len = wlan_cpu_to_le16(
2091 sta_ptr->vht_cap.ieee_hdr.len);
2092 memcpy_ext(
2093 pmpriv->adapter,
2094 &VHTcap_tlv->vht_cap,
2095 &sta_ptr->vht_cap.vht_cap,
2096 sta_ptr->vht_cap.ieee_hdr.len,
2097 sizeof(VHTcap_tlv->vht_cap));
2098 travel_len +=
2099 sta_ptr->vht_cap.ieee_hdr.len +
2100 sizeof(MrvlIEtypesHeader_t);
2101 }
2102 if (VHTcap_tlv) {
2103 wlan_fill_vht_cap_tlv(
2104 pmpriv, VHTcap_tlv,
2105 pbss_desc->bss_band, MTRUE,
2106 MTRUE);
2107 DBG_HEXDUMP(
2108 MCMD_D,
2109 "TDLS Config Link: VHT Capability",
2110 (t_u8 *)VHTcap_tlv,
2111 sizeof(MrvlIETypes_VHTCap_t));
2112 }
2113
2114 /*Vht operation*/
2115 VHTOper_tlv =
2116 (MrvlIETypes_VHTOprat_t *)(pos +
2117 travel_len);
2118 VHTOper_tlv->header.type =
2119 wlan_cpu_to_le16(VHT_OPERATION);
2120 VHTOper_tlv->header.len = wlan_cpu_to_le16(
2121 sta_ptr->vht_oprat.ieee_hdr.len);
2122 memcpy_ext(pmpriv->adapter,
2123 &VHTOper_tlv->chan_width,
2124 &sta_ptr->vht_oprat.chan_width,
2125 sta_ptr->vht_oprat.ieee_hdr.len,
2126 (sizeof(MrvlIETypes_VHTOprat_t) -
2127 sizeof(MrvlIEtypesHeader_t)));
2128 VHTOper_tlv->basic_MCS_map = wlan_cpu_to_le16(
2129 VHTOper_tlv->basic_MCS_map);
2130 travel_len += sta_ptr->vht_oprat.ieee_hdr.len +
2131 sizeof(MrvlIEtypesHeader_t);
2132 DBG_HEXDUMP(MCMD_D,
2133 "TDLS Config Link: VHT operation",
2134 (t_u8 *)VHTOper_tlv,
2135 sizeof(MrvlIETypes_VHTOprat_t));
2136 }
2137 /* Check if we need enable the 11AX */
2138 if (sta_ptr &&
2139 (sta_ptr->he_op.ieee_hdr.element_id == EXTENSION) &&
2140 (sta_ptr->he_op.ext_id == HE_OPERATION)) {
2141 /* HE Capability */
2142 hecap_tlv =
2143 (MrvlIEtypes_Extension_t *)(pos +
2144 travel_len);
2145 /* fill the peer HE CAP IE */
2146 memcpy_ext(pmpriv->adapter, &hecap_tlv->ext_id,
2147 &sta_ptr->tdls_he_cap.ext_id,
2148 sta_ptr->tdls_he_cap.ieee_hdr.len,
2149 sizeof(MrvlIEtypes_He_cap_t) -
2150 sizeof(MrvlIEtypesHeader_t));
2151 hecap_tlv->type =
2152 wlan_cpu_to_le16(TLV_TYPE_EXTENSION_ID);
2153 hecap_tlv->len = MIN(
2154 sta_ptr->tdls_he_cap.ieee_hdr.len,
2155 sizeof(MrvlIEtypes_He_cap_t) -
2156 sizeof(MrvlIEtypesHeader_t));
2157 hecap_tlv->len =
2158 wlan_cpu_to_le16(hecap_tlv->len);
2159 #if 0
2160 wlan_fill_he_cap_tlv(pmpriv,
2161 pmpriv->config_bands,
2162 hecap_tlv, MFALSE);
2163 #endif
2164
2165 travel_len += wlan_le16_to_cpu(hecap_tlv->len) +
2166 sizeof(MrvlIEtypesHeader_t);
2167
2168 DBG_HEXDUMP(
2169 MCMD_D,
2170 "TDLS Config Link: HE Capability",
2171 (t_u8 *)hecap_tlv,
2172 wlan_le16_to_cpu(hecap_tlv->len) +
2173 sizeof(MrvlIEtypesHeader_t));
2174
2175 /* HE Operation */
2176 heop_tlv = (MrvlIEtypes_He_Op_t *)(pos +
2177 travel_len);
2178 heop_tlv->header.type =
2179 wlan_cpu_to_le16(EXTENSION);
2180 heop_tlv->header.len = wlan_cpu_to_le16(
2181 sta_ptr->he_op.ieee_hdr.len);
2182 memcpy_ext(pmpriv->adapter, &heop_tlv->ext_id,
2183 &sta_ptr->he_op.ext_id,
2184 sta_ptr->he_op.ieee_hdr.len,
2185 sizeof(MrvlIEtypes_He_Op_t) -
2186 sizeof(MrvlIEtypesHeader_t));
2187 heop_tlv->he_op_param1 = wlan_cpu_to_le16(
2188 heop_tlv->he_op_param1);
2189 heop_tlv->basic_he_mcs_nss = wlan_cpu_to_le16(
2190 heop_tlv->basic_he_mcs_nss);
2191 travel_len +=
2192 wlan_le16_to_cpu(heop_tlv->header.len) +
2193 sizeof(MrvlIEtypesHeader_t);
2194 DBG_HEXDUMP(
2195 MCMD_D,
2196 "TDLS Config Link: HE Operation",
2197 (t_u8 *)heop_tlv,
2198 wlan_le16_to_cpu(heop_tlv->header.len) +
2199 sizeof(MrvlIEtypesHeader_t));
2200 }
2201
2202 TdlsIdleTimeout =
2203 (MrvlIEtypes_TDLS_Idle_Timeout_t *)(pos +
2204 travel_len);
2205 TdlsIdleTimeout->header.type =
2206 wlan_cpu_to_le16(TLV_TYPE_TDLS_IDLE_TIMEOUT);
2207 TdlsIdleTimeout->header.len =
2208 sizeof(TdlsIdleTimeout->value);
2209 TdlsIdleTimeout->header.len =
2210 wlan_cpu_to_le16(TdlsIdleTimeout->header.len);
2211 TdlsIdleTimeout->value =
2212 wlan_cpu_to_le16(pmpriv->tdls_idle_time);
2213 travel_len += sizeof(MrvlIEtypes_TDLS_Idle_Timeout_t);
2214 }
2215 break;
2216 case WLAN_TDLS_DISABLE_LINK:
2217 ptdls_oper->tdls_action = wlan_cpu_to_le16(TDLS_DELETE);
2218 break;
2219 default:
2220 break;
2221 }
2222 cmd->size += travel_len;
2223 cmd->size = wlan_cpu_to_le16(cmd->size);
2224
2225 LEAVE();
2226 return MLAN_STATUS_SUCCESS;
2227 }
2228
2229 /**
2230 * @brief This function prepares system clock cfg command
2231 *
2232 * @param pmpriv A pointer to mlan_private structure
2233 * @param cmd A pointer to HostCmd_DS_COMMAND structure
2234 * @param cmd_action The action: GET or SET
2235 * @param pdata_buf A pointer to data buffer
2236 * @return MLAN_STATUS_SUCCESS
2237 */
wlan_cmd_sysclock_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)2238 static mlan_status wlan_cmd_sysclock_cfg(pmlan_private pmpriv,
2239 HostCmd_DS_COMMAND *cmd,
2240 t_u16 cmd_action, t_void *pdata_buf)
2241 {
2242 HostCmd_DS_ECL_SYSTEM_CLOCK_CONFIG *cfg = &cmd->params.sys_clock_cfg;
2243 mlan_ds_misc_sys_clock *clk_cfg = (mlan_ds_misc_sys_clock *)pdata_buf;
2244 int i = 0;
2245
2246 ENTER();
2247
2248 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_ECL_SYSTEM_CLOCK_CONFIG);
2249 cmd->size = wlan_cpu_to_le16(
2250 sizeof(HostCmd_DS_ECL_SYSTEM_CLOCK_CONFIG) + S_DS_GEN);
2251
2252 cfg->action = wlan_cpu_to_le16(cmd_action);
2253 cfg->cur_sys_clk = wlan_cpu_to_le16(clk_cfg->cur_sys_clk);
2254 cfg->sys_clk_type = wlan_cpu_to_le16(clk_cfg->sys_clk_type);
2255 cfg->sys_clk_len =
2256 wlan_cpu_to_le16(clk_cfg->sys_clk_num) * sizeof(t_u16);
2257 for (i = 0; i < clk_cfg->sys_clk_num; i++)
2258 cfg->sys_clk[i] = wlan_cpu_to_le16(clk_cfg->sys_clk[i]);
2259
2260 LEAVE();
2261 return MLAN_STATUS_SUCCESS;
2262 }
2263
2264 /**
2265 * @brief This function prepares command of subscribe event.
2266 *
2267 * @param pmpriv A pointer to mlan_private structure
2268 * @param cmd A pointer to HostCmd_DS_COMMAND structure
2269 * @param cmd_action the action: GET or SET
2270 * @param pdata_buf A pointer to data buffer
2271 * @return MLAN_STATUS_SUCCESS
2272 */
wlan_cmd_subscribe_event(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)2273 static mlan_status wlan_cmd_subscribe_event(pmlan_private pmpriv,
2274 HostCmd_DS_COMMAND *cmd,
2275 t_u16 cmd_action, t_void *pdata_buf)
2276 {
2277 mlan_ds_subscribe_evt *sub_evt = (mlan_ds_subscribe_evt *)pdata_buf;
2278 HostCmd_DS_SUBSCRIBE_EVENT *evt =
2279 (HostCmd_DS_SUBSCRIBE_EVENT *)&cmd->params.subscribe_event;
2280 t_u16 cmd_size = 0;
2281 t_u8 *tlv = MNULL;
2282 MrvlIEtypes_BeaconLowRssiThreshold_t *rssi_low = MNULL;
2283 MrvlIEtypes_BeaconLowSnrThreshold_t *snr_low = MNULL;
2284 MrvlIEtypes_FailureCount_t *fail_count = MNULL;
2285 MrvlIEtypes_BeaconsMissed_t *beacon_missed = MNULL;
2286 MrvlIEtypes_BeaconHighRssiThreshold_t *rssi_high = MNULL;
2287 MrvlIEtypes_BeaconHighSnrThreshold_t *snr_high = MNULL;
2288 MrvlIEtypes_DataLowRssiThreshold_t *data_rssi_low = MNULL;
2289 MrvlIEtypes_DataLowSnrThreshold_t *data_snr_low = MNULL;
2290 MrvlIEtypes_DataHighRssiThreshold_t *data_rssi_high = MNULL;
2291 MrvlIEtypes_DataHighSnrThreshold_t *data_snr_high = MNULL;
2292 MrvlIEtypes_LinkQualityThreshold_t *link_quality = MNULL;
2293 MrvlIETypes_PreBeaconMissed_t *pre_bcn_missed = MNULL;
2294
2295 ENTER();
2296
2297 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_SUBSCRIBE_EVENT);
2298 evt->action = wlan_cpu_to_le16(cmd_action);
2299 cmd_size = sizeof(HostCmd_DS_SUBSCRIBE_EVENT) + S_DS_GEN;
2300 if (cmd_action == HostCmd_ACT_GEN_GET)
2301 goto done;
2302 evt->action = wlan_cpu_to_le16(sub_evt->evt_action);
2303 evt->event_bitmap = wlan_cpu_to_le16(sub_evt->evt_bitmap);
2304 tlv = (t_u8 *)cmd + cmd_size;
2305 if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_RSSI_LOW) {
2306 rssi_low = (MrvlIEtypes_BeaconLowRssiThreshold_t *)tlv;
2307 rssi_low->header.type = wlan_cpu_to_le16(TLV_TYPE_RSSI_LOW);
2308 rssi_low->header.len = wlan_cpu_to_le16(
2309 sizeof(MrvlIEtypes_BeaconLowRssiThreshold_t) -
2310 sizeof(MrvlIEtypesHeader_t));
2311 rssi_low->value = sub_evt->low_rssi;
2312 rssi_low->frequency = sub_evt->low_rssi_freq;
2313 tlv += sizeof(MrvlIEtypes_BeaconLowRssiThreshold_t);
2314 cmd_size += sizeof(MrvlIEtypes_BeaconLowRssiThreshold_t);
2315 }
2316 if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_SNR_LOW) {
2317 snr_low = (MrvlIEtypes_BeaconLowSnrThreshold_t *)tlv;
2318 snr_low->header.type = wlan_cpu_to_le16(TLV_TYPE_SNR_LOW);
2319 snr_low->header.len = wlan_cpu_to_le16(
2320 sizeof(MrvlIEtypes_BeaconLowSnrThreshold_t) -
2321 sizeof(MrvlIEtypesHeader_t));
2322 snr_low->value = sub_evt->low_snr;
2323 snr_low->frequency = sub_evt->low_snr_freq;
2324 tlv += sizeof(MrvlIEtypes_BeaconLowSnrThreshold_t);
2325 cmd_size += sizeof(MrvlIEtypes_BeaconLowSnrThreshold_t);
2326 }
2327 if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_MAX_FAIL) {
2328 fail_count = (MrvlIEtypes_FailureCount_t *)tlv;
2329 fail_count->header.type = wlan_cpu_to_le16(TLV_TYPE_FAILCOUNT);
2330 fail_count->header.len =
2331 wlan_cpu_to_le16(sizeof(MrvlIEtypes_FailureCount_t) -
2332 sizeof(MrvlIEtypesHeader_t));
2333 fail_count->value = sub_evt->failure_count;
2334 fail_count->frequency = sub_evt->failure_count_freq;
2335 tlv += sizeof(MrvlIEtypes_FailureCount_t);
2336 cmd_size += sizeof(MrvlIEtypes_FailureCount_t);
2337 }
2338 if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_BEACON_MISSED) {
2339 beacon_missed = (MrvlIEtypes_BeaconsMissed_t *)tlv;
2340 beacon_missed->header.type = wlan_cpu_to_le16(TLV_TYPE_BCNMISS);
2341 beacon_missed->header.len =
2342 wlan_cpu_to_le16(sizeof(MrvlIEtypes_BeaconsMissed_t) -
2343 sizeof(MrvlIEtypesHeader_t));
2344 beacon_missed->value = sub_evt->beacon_miss;
2345 beacon_missed->frequency = sub_evt->beacon_miss_freq;
2346 tlv += sizeof(MrvlIEtypes_BeaconsMissed_t);
2347 cmd_size += sizeof(MrvlIEtypes_BeaconsMissed_t);
2348 }
2349 if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_RSSI_HIGH) {
2350 rssi_high = (MrvlIEtypes_BeaconHighRssiThreshold_t *)tlv;
2351 rssi_high->header.type = wlan_cpu_to_le16(TLV_TYPE_RSSI_HIGH);
2352 rssi_high->header.len = wlan_cpu_to_le16(
2353 sizeof(MrvlIEtypes_BeaconHighRssiThreshold_t) -
2354 sizeof(MrvlIEtypesHeader_t));
2355 rssi_high->value = sub_evt->high_rssi;
2356 rssi_high->frequency = sub_evt->high_rssi_freq;
2357 tlv += sizeof(MrvlIEtypes_BeaconHighRssiThreshold_t);
2358 cmd_size += sizeof(MrvlIEtypes_BeaconHighRssiThreshold_t);
2359 }
2360 if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_SNR_HIGH) {
2361 snr_high = (MrvlIEtypes_BeaconHighSnrThreshold_t *)tlv;
2362 snr_high->header.type = wlan_cpu_to_le16(TLV_TYPE_SNR_HIGH);
2363 snr_high->header.len = wlan_cpu_to_le16(
2364 sizeof(MrvlIEtypes_BeaconHighSnrThreshold_t) -
2365 sizeof(MrvlIEtypesHeader_t));
2366 snr_high->value = sub_evt->high_snr;
2367 snr_high->frequency = sub_evt->high_snr_freq;
2368 tlv += sizeof(MrvlIEtypes_BeaconHighSnrThreshold_t);
2369 cmd_size += sizeof(MrvlIEtypes_BeaconHighSnrThreshold_t);
2370 }
2371 if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_DATA_RSSI_LOW) {
2372 data_rssi_low = (MrvlIEtypes_DataLowRssiThreshold_t *)tlv;
2373 data_rssi_low->header.type =
2374 wlan_cpu_to_le16(TLV_TYPE_RSSI_LOW_DATA);
2375 data_rssi_low->header.len = wlan_cpu_to_le16(
2376 sizeof(MrvlIEtypes_DataLowRssiThreshold_t) -
2377 sizeof(MrvlIEtypesHeader_t));
2378 data_rssi_low->value = sub_evt->data_low_rssi;
2379 data_rssi_low->frequency = sub_evt->data_low_rssi_freq;
2380 tlv += sizeof(MrvlIEtypes_DataLowRssiThreshold_t);
2381 cmd_size += sizeof(MrvlIEtypes_DataLowRssiThreshold_t);
2382 }
2383 if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_DATA_SNR_LOW) {
2384 data_snr_low = (MrvlIEtypes_DataLowSnrThreshold_t *)tlv;
2385 data_snr_low->header.type =
2386 wlan_cpu_to_le16(TLV_TYPE_SNR_LOW_DATA);
2387 data_snr_low->header.len = wlan_cpu_to_le16(
2388 sizeof(MrvlIEtypes_DataLowSnrThreshold_t) -
2389 sizeof(MrvlIEtypesHeader_t));
2390 data_snr_low->value = sub_evt->data_low_snr;
2391 data_snr_low->frequency = sub_evt->data_low_snr_freq;
2392 tlv += sizeof(MrvlIEtypes_DataLowSnrThreshold_t);
2393 cmd_size += sizeof(MrvlIEtypes_DataLowSnrThreshold_t);
2394 }
2395 if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_DATA_RSSI_HIGH) {
2396 data_rssi_high = (MrvlIEtypes_DataHighRssiThreshold_t *)tlv;
2397 data_rssi_high->header.type =
2398 wlan_cpu_to_le16(TLV_TYPE_RSSI_HIGH_DATA);
2399 data_rssi_high->header.len = wlan_cpu_to_le16(
2400 sizeof(MrvlIEtypes_DataHighRssiThreshold_t) -
2401 sizeof(MrvlIEtypesHeader_t));
2402 data_rssi_high->value = sub_evt->data_high_rssi;
2403 data_rssi_high->frequency = sub_evt->data_high_rssi_freq;
2404 tlv += sizeof(MrvlIEtypes_DataHighRssiThreshold_t);
2405 cmd_size += sizeof(MrvlIEtypes_DataHighRssiThreshold_t);
2406 }
2407 if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_DATA_SNR_HIGH) {
2408 data_snr_high = (MrvlIEtypes_DataHighSnrThreshold_t *)tlv;
2409 data_snr_high->header.type =
2410 wlan_cpu_to_le16(TLV_TYPE_SNR_HIGH_DATA);
2411 data_snr_high->header.len = wlan_cpu_to_le16(
2412 sizeof(MrvlIEtypes_DataHighSnrThreshold_t) -
2413 sizeof(MrvlIEtypesHeader_t));
2414 data_snr_high->value = sub_evt->data_high_snr;
2415 data_snr_high->frequency = sub_evt->data_high_snr_freq;
2416 tlv += sizeof(MrvlIEtypes_DataHighSnrThreshold_t);
2417 cmd_size += sizeof(MrvlIEtypes_DataHighSnrThreshold_t);
2418 }
2419 if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_LINK_QUALITY) {
2420 link_quality = (MrvlIEtypes_LinkQualityThreshold_t *)tlv;
2421 link_quality->header.type =
2422 wlan_cpu_to_le16(TLV_TYPE_LINK_QUALITY);
2423 link_quality->header.len = wlan_cpu_to_le16(
2424 sizeof(MrvlIEtypes_LinkQualityThreshold_t) -
2425 sizeof(MrvlIEtypesHeader_t));
2426 link_quality->link_snr = wlan_cpu_to_le16(sub_evt->link_snr);
2427 link_quality->link_snr_freq =
2428 wlan_cpu_to_le16(sub_evt->link_snr_freq);
2429 link_quality->link_rate = wlan_cpu_to_le16(sub_evt->link_rate);
2430 link_quality->link_rate_freq =
2431 wlan_cpu_to_le16(sub_evt->link_rate_freq);
2432 link_quality->link_tx_latency =
2433 wlan_cpu_to_le16(sub_evt->link_tx_latency);
2434 link_quality->link_tx_lantency_freq =
2435 wlan_cpu_to_le16(sub_evt->link_tx_lantency_freq);
2436 tlv += sizeof(MrvlIEtypes_LinkQualityThreshold_t);
2437 cmd_size += sizeof(MrvlIEtypes_LinkQualityThreshold_t);
2438 }
2439 if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_PRE_BEACON_LOST) {
2440 pre_bcn_missed = (MrvlIETypes_PreBeaconMissed_t *)tlv;
2441 pre_bcn_missed->header.type =
2442 wlan_cpu_to_le16(TLV_TYPE_PRE_BCNMISS);
2443 pre_bcn_missed->header.len =
2444 wlan_cpu_to_le16(sizeof(MrvlIETypes_PreBeaconMissed_t) -
2445 sizeof(MrvlIEtypesHeader_t));
2446 pre_bcn_missed->value = sub_evt->pre_beacon_miss;
2447 pre_bcn_missed->frequency = 0;
2448 tlv += sizeof(MrvlIETypes_PreBeaconMissed_t);
2449 cmd_size += sizeof(MrvlIETypes_PreBeaconMissed_t);
2450 }
2451 done:
2452 cmd->size = wlan_cpu_to_le16(cmd_size);
2453 LEAVE();
2454 return MLAN_STATUS_SUCCESS;
2455 }
2456
2457 /**
2458 * @brief This function prepares command of OTP user data.
2459 *
2460 * @param pmpriv A pointer to mlan_private structure
2461 * @param cmd A pointer to HostCmd_DS_COMMAND structure
2462 * @param cmd_action the action: GET or SET
2463 * @param pdata_buf A pointer to data buffer
2464 * @return MLAN_STATUS_SUCCESS
2465 */
wlan_cmd_otp_user_data(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)2466 static mlan_status wlan_cmd_otp_user_data(pmlan_private pmpriv,
2467 HostCmd_DS_COMMAND *cmd,
2468 t_u16 cmd_action, t_void *pdata_buf)
2469 {
2470 mlan_ds_misc_otp_user_data *user_data =
2471 (mlan_ds_misc_otp_user_data *)pdata_buf;
2472 HostCmd_DS_OTP_USER_DATA *cmd_user_data =
2473 (HostCmd_DS_OTP_USER_DATA *)&cmd->params.otp_user_data;
2474 t_u16 cmd_size = 0;
2475
2476 ENTER();
2477
2478 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_OTP_READ_USER_DATA);
2479 cmd_size = sizeof(HostCmd_DS_OTP_USER_DATA) + S_DS_GEN - 1;
2480
2481 cmd_user_data->action = wlan_cpu_to_le16(cmd_action);
2482 cmd_user_data->reserved = 0;
2483 cmd_user_data->user_data_length =
2484 wlan_cpu_to_le16(user_data->user_data_length);
2485 cmd_size += user_data->user_data_length;
2486 cmd->size = wlan_cpu_to_le16(cmd_size);
2487
2488 LEAVE();
2489 return MLAN_STATUS_SUCCESS;
2490 }
2491
2492 /**
2493 * @brief This function prepares command of fw auto re-connect.
2494 *
2495 * @param pmpriv A pointer to mlan_private structure
2496 * @param cmd A pointer to HostCmd_DS_COMMAND structure
2497 * @param cmd_action the action: GET or SET
2498 * @param pdata_buf A pointer to data buffer
2499 * @return MLAN_STATUS_SUCCESS
2500 */
wlan_cmd_fw_auto_reconnect(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)2501 static mlan_status wlan_cmd_fw_auto_reconnect(pmlan_private pmpriv,
2502 HostCmd_DS_COMMAND *cmd,
2503 t_u16 cmd_action,
2504 t_void *pdata_buf)
2505 {
2506 HostCmd_DS_FW_AUTO_RECONNECT *fw_auto_reconnect =
2507 &cmd->params.fw_auto_reconnect_cmd;
2508 mlan_ds_fw_reconnect *fw_auto_reconn =
2509 (mlan_ds_fw_reconnect *)pdata_buf;
2510
2511 ENTER();
2512
2513 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_FW_AUTO_RECONNECT);
2514 cmd->size = wlan_cpu_to_le16((sizeof(HostCmd_DS_FW_AUTO_RECONNECT)) +
2515 S_DS_GEN);
2516
2517 fw_auto_reconnect->action = wlan_cpu_to_le16(cmd_action);
2518
2519 if (cmd_action == HostCmd_ACT_GEN_SET) {
2520 fw_auto_reconnect->reconnect_counter =
2521 fw_auto_reconn->fw_reconn_counter;
2522 fw_auto_reconnect->reconnect_interval =
2523 fw_auto_reconn->fw_reconn_interval;
2524 fw_auto_reconnect->flags =
2525 wlan_cpu_to_le16(fw_auto_reconn->fw_reconn_flags);
2526 }
2527
2528 LEAVE();
2529 return MLAN_STATUS_SUCCESS;
2530 }
2531
2532 #ifdef USB
2533 /**
2534 * @brief This function prepares command of packet aggragation
2535 *
2536 * @param pmpriv A pointer to mlan_private structure
2537 * @param cmd A pointer to HostCmd_DS_COMMAND structure
2538 * @param cmd_action the action: GET or SET
2539 * @param pdata_buf A pointer to data buffer
2540 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
2541 */
2542 static mlan_status
wlan_cmd_packet_aggr_over_host_interface(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)2543 wlan_cmd_packet_aggr_over_host_interface(pmlan_private pmpriv,
2544 HostCmd_DS_COMMAND *cmd,
2545 t_u16 cmd_action, t_void *pdata_buf)
2546 {
2547 HostCmd_DS_PACKET_AGGR_OVER_HOST_INTERFACE *packet_aggr =
2548 &cmd->params.packet_aggr;
2549 MrvlIETypes_USBAggrParam_t *usb_aggr_param_tlv = MNULL;
2550 mlan_ds_misc_usb_aggr_ctrl *usb_aggr_ctrl =
2551 (mlan_ds_misc_usb_aggr_ctrl *)pdata_buf;
2552 t_u8 *ptlv_buffer = (t_u8 *)packet_aggr->tlv_buf;
2553 pmlan_adapter pmadapter = pmpriv->adapter;
2554
2555 ENTER();
2556
2557 usb_aggr_param_tlv = (MrvlIETypes_USBAggrParam_t *)ptlv_buffer;
2558
2559 cmd->command =
2560 wlan_cpu_to_le16(HostCmd_CMD_PACKET_AGGR_OVER_HOST_INTERFACE);
2561 packet_aggr->action = wlan_cpu_to_le16(cmd_action);
2562 memset(pmadapter, usb_aggr_param_tlv, 0,
2563 MRVL_USB_AGGR_PARAM_TLV_LEN + sizeof(MrvlIEtypesHeader_t));
2564 usb_aggr_param_tlv->header.type =
2565 wlan_cpu_to_le16(MRVL_USB_AGGR_PARAM_TLV_ID);
2566 usb_aggr_param_tlv->header.len =
2567 wlan_cpu_to_le16(MRVL_USB_AGGR_PARAM_TLV_LEN);
2568 cmd->size = wlan_cpu_to_le16(
2569 sizeof(HostCmd_DS_PACKET_AGGR_OVER_HOST_INTERFACE) + S_DS_GEN +
2570 MRVL_USB_AGGR_PARAM_TLV_LEN + sizeof(MrvlIEtypesHeader_t) - 1);
2571
2572 if (pmadapter->data_sent || (!wlan_bypass_tx_list_empty(pmadapter)) ||
2573 (!wlan_wmm_lists_empty(pmadapter))) {
2574 /* Make sure this is not issued during traffic */
2575 PRINTM(MERROR,
2576 "USB aggregation parameters cannot be accessed during traffic.\n");
2577 LEAVE();
2578 return MLAN_STATUS_FAILURE;
2579 }
2580
2581 if (cmd_action == HostCmd_ACT_GEN_SET) {
2582 usb_aggr_param_tlv->enable = 0;
2583 if (usb_aggr_ctrl->tx_aggr_ctrl.enable)
2584 usb_aggr_param_tlv->enable |= MBIT(1);
2585 usb_aggr_param_tlv->tx_aggr_align = wlan_cpu_to_le16(
2586 usb_aggr_ctrl->tx_aggr_ctrl.aggr_align);
2587 if (usb_aggr_ctrl->rx_deaggr_ctrl.enable)
2588 usb_aggr_param_tlv->enable |= MBIT(0);
2589 usb_aggr_param_tlv->rx_aggr_mode = wlan_cpu_to_le16(
2590 usb_aggr_ctrl->rx_deaggr_ctrl.aggr_mode);
2591 usb_aggr_param_tlv->rx_aggr_align = wlan_cpu_to_le16(
2592 usb_aggr_ctrl->rx_deaggr_ctrl.aggr_align);
2593 usb_aggr_param_tlv->rx_aggr_max = wlan_cpu_to_le16(
2594 usb_aggr_ctrl->rx_deaggr_ctrl.aggr_max);
2595 usb_aggr_param_tlv->rx_aggr_tmo = wlan_cpu_to_le16(
2596 usb_aggr_ctrl->rx_deaggr_ctrl.aggr_tmo);
2597 usb_aggr_param_tlv->enable =
2598 wlan_cpu_to_le16(usb_aggr_param_tlv->enable);
2599 }
2600
2601 LEAVE();
2602 return MLAN_STATUS_SUCCESS;
2603 }
2604 #endif
2605
2606 /**
2607 * @brief This function prepares inactivity timeout command
2608 *
2609 * @param cmd A pointer to HostCmd_DS_COMMAND structure
2610 * @param cmd_action the action: GET or SET
2611 * @param pdata_buf A pointer to data buffer
2612 * @return MLAN_STATUS_SUCCESS
2613 */
wlan_cmd_inactivity_timeout(HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)2614 static mlan_status wlan_cmd_inactivity_timeout(HostCmd_DS_COMMAND *cmd,
2615 t_u16 cmd_action,
2616 t_void *pdata_buf)
2617 {
2618 pmlan_ds_inactivity_to inac_to;
2619 HostCmd_DS_INACTIVITY_TIMEOUT_EXT *cmd_inac_to =
2620 &cmd->params.inactivity_to;
2621
2622 ENTER();
2623
2624 inac_to = (mlan_ds_inactivity_to *)pdata_buf;
2625
2626 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_INACTIVITY_TIMEOUT_EXT) +
2627 S_DS_GEN);
2628 cmd->command = wlan_cpu_to_le16(cmd->command);
2629 cmd_inac_to->action = wlan_cpu_to_le16(cmd_action);
2630 if (cmd_action == HostCmd_ACT_GEN_SET) {
2631 cmd_inac_to->timeout_unit =
2632 wlan_cpu_to_le16((t_u16)inac_to->timeout_unit);
2633 cmd_inac_to->unicast_timeout =
2634 wlan_cpu_to_le16((t_u16)inac_to->unicast_timeout);
2635 cmd_inac_to->mcast_timeout =
2636 wlan_cpu_to_le16((t_u16)inac_to->mcast_timeout);
2637 cmd_inac_to->ps_entry_timeout =
2638 wlan_cpu_to_le16((t_u16)inac_to->ps_entry_timeout);
2639 }
2640
2641 LEAVE();
2642 return MLAN_STATUS_SUCCESS;
2643 }
2644
2645 /**
2646 * @brief This function prepares network monitor command
2647 *
2648 * @param pmpriv A pointer to mlan_private structure
2649 * @param cmd A pointer to HostCmd_DS_COMMAND structure
2650 * @param cmd_action the action: GET or SET
2651 * @param pdata_buf A pointer to data buffer
2652 * @return MLAN_STATUS_SUCCESS
2653 */
wlan_cmd_net_monitor(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)2654 mlan_status wlan_cmd_net_monitor(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
2655 t_u16 cmd_action, t_void *pdata_buf)
2656 {
2657 mlan_ds_misc_net_monitor *net_mon;
2658 HostCmd_DS_802_11_NET_MONITOR *cmd_net_mon = &cmd->params.net_mon;
2659 ChanBandParamSet_t *pchan_band = MNULL;
2660 t_u8 sec_chan_offset = 0;
2661 t_u32 bw_offset = 0;
2662
2663 ENTER();
2664
2665 net_mon = (mlan_ds_misc_net_monitor *)pdata_buf;
2666
2667 cmd->size = wlan_cpu_to_le16(S_DS_GEN +
2668 sizeof(HostCmd_DS_802_11_NET_MONITOR));
2669 cmd->command = wlan_cpu_to_le16(cmd->command);
2670 cmd_net_mon->action = wlan_cpu_to_le16(cmd_action);
2671 if (cmd_action == HostCmd_ACT_GEN_SET) {
2672 cmd_net_mon->enable_net_mon =
2673 wlan_cpu_to_le16((t_u16)net_mon->enable_net_mon);
2674 if (net_mon->enable_net_mon) {
2675 pchan_band =
2676 &cmd_net_mon->monitor_chan.chan_band_param[0];
2677 cmd_net_mon->filter_flag =
2678 wlan_cpu_to_le16((t_u16)net_mon->filter_flag);
2679 cmd_net_mon->monitor_chan.header.type =
2680 wlan_cpu_to_le16(TLV_TYPE_CHANNELBANDLIST);
2681 cmd_net_mon->monitor_chan.header.len =
2682 wlan_cpu_to_le16(sizeof(ChanBandParamSet_t));
2683 pchan_band->chan_number = (t_u8)net_mon->channel;
2684 pchan_band->bandcfg.chanBand =
2685 wlan_band_to_radio_type((t_u16)net_mon->band);
2686
2687 if (net_mon->band & BAND_GN ||
2688 net_mon->band & BAND_AN ||
2689 net_mon->band & BAND_GAC ||
2690 net_mon->band & BAND_AAC) {
2691 bw_offset = net_mon->chan_bandwidth;
2692 if (bw_offset == CHANNEL_BW_40MHZ_ABOVE) {
2693 pchan_band->bandcfg.chan2Offset =
2694 SEC_CHAN_ABOVE;
2695 pchan_band->bandcfg.chanWidth =
2696 CHAN_BW_40MHZ;
2697 } else if (bw_offset ==
2698 CHANNEL_BW_40MHZ_BELOW) {
2699 pchan_band->bandcfg.chan2Offset =
2700 SEC_CHAN_BELOW;
2701 pchan_band->bandcfg.chanWidth =
2702 CHAN_BW_40MHZ;
2703 } else if (bw_offset == CHANNEL_BW_80MHZ) {
2704 sec_chan_offset =
2705 wlan_get_second_channel_offset(
2706 pmpriv,
2707 net_mon->channel);
2708 if (sec_chan_offset == SEC_CHAN_ABOVE)
2709 pchan_band->bandcfg.chan2Offset =
2710 SEC_CHAN_ABOVE;
2711 else if (sec_chan_offset ==
2712 SEC_CHAN_BELOW)
2713 pchan_band->bandcfg.chan2Offset =
2714 SEC_CHAN_BELOW;
2715 pchan_band->bandcfg.chanWidth =
2716 CHAN_BW_80MHZ;
2717 }
2718 }
2719 }
2720 }
2721
2722 LEAVE();
2723 return MLAN_STATUS_SUCCESS;
2724 }
2725
2726 /**
2727 * @brief This function prepares Low Power Mode
2728 *
2729 * @param pmpriv A pointer to mlan_private structure
2730 * @param cmd A pointer to HostCmd_DS_COMMAND structure
2731 * @param cmd_action the action: GET or SET
2732 * @param pdata_buf A pointer to data buffer
2733 *
2734 * @return MLAN_STATUS_SUCCESS
2735 */
wlan_cmd_low_pwr_mode(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_void * pdata_buf)2736 static mlan_status wlan_cmd_low_pwr_mode(pmlan_private pmpriv,
2737 HostCmd_DS_COMMAND *cmd,
2738 t_void *pdata_buf)
2739 {
2740 HostCmd_CONFIG_LOW_PWR_MODE *cmd_lpm_cfg =
2741 &cmd->params.low_pwr_mode_cfg;
2742 t_u8 *enable;
2743
2744 ENTER();
2745
2746 cmd->size = S_DS_GEN + sizeof(HostCmd_CONFIG_LOW_PWR_MODE);
2747
2748 enable = (t_u8 *)pdata_buf;
2749 cmd->size = wlan_cpu_to_le16(cmd->size);
2750 cmd->command = wlan_cpu_to_le16(cmd->command);
2751 cmd_lpm_cfg->enable = *enable;
2752
2753 LEAVE();
2754 return MLAN_STATUS_SUCCESS;
2755 }
2756
2757 /**
2758 * @brief This function prepares DFS repeater mode configuration
2759 *
2760 * @param pmpriv A pointer to mlan_private structure
2761 * @param cmd A pointer to HostCmd_DS_COMMAND structure
2762 * @param cmd_action the action: GET or SET
2763 * @param pdata_buf A pointer to data buffer
2764 *
2765 * @return MLAN_STATUS_SUCCESS
2766 */
wlan_cmd_dfs_repeater_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)2767 static mlan_status wlan_cmd_dfs_repeater_cfg(pmlan_private pmpriv,
2768 HostCmd_DS_COMMAND *cmd,
2769 t_u16 cmd_action,
2770 t_void *pdata_buf)
2771 {
2772 mlan_ds_misc_dfs_repeater *dfs_repeater = MNULL;
2773 HostCmd_DS_DFS_REPEATER_MODE *cmd_dfs_repeater =
2774 &cmd->params.dfs_repeater;
2775
2776 ENTER();
2777
2778 cmd->size = S_DS_GEN + sizeof(HostCmd_DS_DFS_REPEATER_MODE);
2779
2780 dfs_repeater = (mlan_ds_misc_dfs_repeater *)pdata_buf;
2781 cmd->size = wlan_cpu_to_le16(cmd->size);
2782 cmd->command = wlan_cpu_to_le16(cmd->command);
2783 cmd_dfs_repeater->action = wlan_cpu_to_le16(cmd_action);
2784
2785 if (cmd_action == HostCmd_ACT_GEN_SET)
2786 cmd_dfs_repeater->mode = wlan_cpu_to_le16(dfs_repeater->mode);
2787
2788 LEAVE();
2789 return MLAN_STATUS_SUCCESS;
2790 }
2791
2792 /**
2793 * @brief This function prepares command of coalesce_config.
2794 *
2795 * @param pmpriv A pointer to mlan_private structure
2796 * @param cmd A pointer to HostCmd_DS_COMMAND structure
2797 * @param cmd_action The action: GET or SET
2798 * @param pdata_buf A pointer to data buffer
2799 *
2800 * @return MLAN_STATUS_SUCCESS
2801 */
wlan_cmd_coalesce_config(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)2802 static mlan_status wlan_cmd_coalesce_config(pmlan_private pmpriv,
2803 HostCmd_DS_COMMAND *cmd,
2804 t_u16 cmd_action, t_void *pdata_buf)
2805 {
2806 HostCmd_DS_COALESCE_CONFIG *coalesce_config =
2807 &cmd->params.coalesce_config;
2808 mlan_ds_coalesce_cfg *cfg = (mlan_ds_coalesce_cfg *)pdata_buf;
2809 t_u16 cnt, idx, length;
2810 struct coalesce_filt_field_param *param;
2811 struct coalesce_receive_filt_rule *rule;
2812
2813 ENTER();
2814
2815 cmd->size = (sizeof(HostCmd_DS_COALESCE_CONFIG) -
2816 sizeof(struct coalesce_receive_filt_rule)) +
2817 S_DS_GEN;
2818 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_COALESCE_CFG);
2819 coalesce_config->action = wlan_cpu_to_le16(cmd_action);
2820 coalesce_config->num_of_rules = wlan_cpu_to_le16(cfg->num_of_rules);
2821 if (cmd_action == HostCmd_ACT_GEN_SET) {
2822 rule = coalesce_config->rule;
2823 for (cnt = 0; cnt < cfg->num_of_rules; cnt++) {
2824 rule->header.type =
2825 wlan_cpu_to_le16(TLV_TYPE_COALESCE_RULE);
2826 rule->max_coalescing_delay = wlan_cpu_to_le16(
2827 cfg->rule[cnt].max_coalescing_delay);
2828 rule->pkt_type = cfg->rule[cnt].pkt_type;
2829 rule->num_of_fields = cfg->rule[cnt].num_of_fields;
2830
2831 length = 0;
2832
2833 param = rule->params;
2834 for (idx = 0; idx < cfg->rule[cnt].num_of_fields;
2835 idx++) {
2836 param->operation =
2837 cfg->rule[cnt].params[idx].operation;
2838 param->operand_len =
2839 cfg->rule[cnt].params[idx].operand_len;
2840 param->offset = wlan_cpu_to_le16(
2841 cfg->rule[cnt].params[idx].offset);
2842 memcpy_ext(pmpriv->adapter,
2843 param->operand_byte_stream,
2844 cfg->rule[cnt]
2845 .params[idx]
2846 .operand_byte_stream,
2847 param->operand_len,
2848 sizeof(param->operand_byte_stream));
2849
2850 length += sizeof(
2851 struct coalesce_filt_field_param);
2852
2853 param++;
2854 }
2855
2856 /* Total rule length is sizeof
2857 * max_coalescing_delay(t_u16), num_of_fields(t_u8),
2858 * pkt_type(t_u8) and total length of the all params
2859 */
2860 rule->header.len =
2861 wlan_cpu_to_le16(length + sizeof(t_u16) +
2862 sizeof(t_u8) + sizeof(t_u8));
2863
2864 /* Add the rule length to the command size*/
2865 cmd->size += wlan_le16_to_cpu(rule->header.len) +
2866 sizeof(MrvlIEtypesHeader_t);
2867
2868 rule = (void *)((t_u8 *)rule->params + length);
2869 }
2870 }
2871 cmd->size = wlan_cpu_to_le16(cmd->size);
2872 LEAVE();
2873 return MLAN_STATUS_SUCCESS;
2874 }
2875
2876 /********************************************************
2877 * Global Functions
2878 ********************************************************/
2879
2880 /**
2881 * @brief This function prepares command of arb cfg
2882 *
2883 * @param pmpriv A pointer to mlan_private structure
2884 * @param cmd A pointer to HostCmd_DS_COMMAND structure
2885 * @param cmd_action the action: GET or SET
2886 * @param pdata_buf A pointer to data buffer
2887 * @return MLAN_STATUS_SUCCESS
2888 */
wlan_cmd_arb_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)2889 mlan_status wlan_cmd_arb_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
2890 t_u16 cmd_action, t_void *pdata_buf)
2891 {
2892 HostCmd_DS_CMD_ARB_CONFIG *cfg_cmd =
2893 (HostCmd_DS_CMD_ARB_CONFIG *)&cmd->params.arb_cfg;
2894 mlan_ds_misc_arb_cfg *misc_cfg = (mlan_ds_misc_arb_cfg *)pdata_buf;
2895
2896 ENTER();
2897
2898 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_ARB_CONFIG);
2899 cmd->size =
2900 wlan_cpu_to_le16(sizeof(HostCmd_DS_CMD_ARB_CONFIG) + S_DS_GEN);
2901 cfg_cmd->action = wlan_cpu_to_le16(cmd_action);
2902
2903 if (cmd_action == HostCmd_ACT_GEN_SET) {
2904 cfg_cmd->arb_mode = wlan_cpu_to_le32(misc_cfg->arb_mode);
2905 if (misc_cfg->arb_mode == 3) {
2906 #define DEF_ARB_TX_WIN 4
2907 #define DEF_ARB_TIMEOUT 0
2908 pmpriv->add_ba_param.timeout = DEF_ARB_TIMEOUT;
2909 pmpriv->add_ba_param.tx_win_size = DEF_ARB_TX_WIN;
2910 } else {
2911 pmpriv->add_ba_param.timeout =
2912 MLAN_DEFAULT_BLOCK_ACK_TIMEOUT;
2913 pmpriv->add_ba_param.tx_win_size =
2914 MLAN_STA_AMPDU_DEF_TXWINSIZE;
2915 }
2916 }
2917
2918 LEAVE();
2919 return MLAN_STATUS_SUCCESS;
2920 }
2921
2922 /**
2923 * @brief This function set ipv6 ra offload configuration.
2924 *
2925 * @param pmpriv A pointer to mlan_private structure
2926 * @param pcmd A pointer to HostCmd_DS_COMMAND structure
2927 * @param cmd_action Command action
2928 * @param pdata_buf A pointer to information buffer
2929 * @return N/A
2930 */
2931
wlan_cmd_ipv6_ra_offload(mlan_private * pmpriv,HostCmd_DS_COMMAND * pcmd,t_u16 cmd_action,void * pdata_buf)2932 mlan_status wlan_cmd_ipv6_ra_offload(mlan_private *pmpriv,
2933 HostCmd_DS_COMMAND *pcmd, t_u16 cmd_action,
2934 void *pdata_buf)
2935 {
2936 HostCmd_DS_IPV6_RA_OFFLOAD *ipv6_ra_cfg = &pcmd->params.ipv6_ra_offload;
2937 mlan_ds_misc_ipv6_ra_offload *ipv6_ra_offload =
2938 (mlan_ds_misc_ipv6_ra_offload *)pdata_buf;
2939 MrvlIEtypesHeader_t *ie = &ipv6_ra_cfg->ipv6_addr_param.Header;
2940
2941 ENTER();
2942
2943 pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_IPV6_RA_OFFLOAD_CFG);
2944 ipv6_ra_cfg->action = wlan_cpu_to_le16(cmd_action);
2945 if (cmd_action == HostCmd_ACT_GEN_SET) {
2946 ipv6_ra_cfg->enable = ipv6_ra_offload->enable;
2947 ie->type = wlan_cpu_to_le16(TLV_TYPE_IPV6_RA_OFFLOAD);
2948 ie->len = wlan_cpu_to_le16(16);
2949 memcpy_ext(pmpriv->adapter,
2950 ipv6_ra_cfg->ipv6_addr_param.ipv6_addr,
2951 ipv6_ra_offload->ipv6_addr, 16,
2952 sizeof(ipv6_ra_cfg->ipv6_addr_param.ipv6_addr));
2953 pcmd->size = wlan_cpu_to_le16(
2954 S_DS_GEN + sizeof(HostCmd_DS_IPV6_RA_OFFLOAD));
2955 } else if (cmd_action == HostCmd_ACT_GEN_GET)
2956 pcmd->size = wlan_cpu_to_le16(S_DS_GEN +
2957 sizeof(ipv6_ra_cfg->action));
2958
2959 LEAVE();
2960 return MLAN_STATUS_SUCCESS;
2961 }
2962
2963 /**
2964 * @brief This function sends get sta band channel command to firmware.
2965 *
2966 * @param priv A pointer to mlan_private structure
2967 * @param cmd Hostcmd ID
2968 * @return N/A
2969 */
wlan_cmd_sta_config(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,mlan_ioctl_req * pioctl_buf,t_void * pdata_buf)2970 static mlan_status wlan_cmd_sta_config(pmlan_private pmpriv,
2971 HostCmd_DS_COMMAND *cmd,
2972 t_u16 cmd_action,
2973 mlan_ioctl_req *pioctl_buf,
2974 t_void *pdata_buf)
2975 {
2976 mlan_ds_bss *bss = MNULL;
2977 HostCmd_DS_STA_CONFIGURE *sta_cfg_cmd = &cmd->params.sta_cfg;
2978 MrvlIEtypes_channel_band_t *tlv_band_channel = MNULL;
2979 mlan_status ret = MLAN_STATUS_FAILURE;
2980
2981 ENTER();
2982 if (!pioctl_buf)
2983 return ret;
2984
2985 if (pioctl_buf->req_id == MLAN_IOCTL_BSS) {
2986 bss = (mlan_ds_bss *)pioctl_buf->pbuf;
2987 if ((bss->sub_command == MLAN_OID_BSS_CHAN_INFO) &&
2988 (cmd_action == HostCmd_ACT_GEN_GET)) {
2989 cmd->command =
2990 wlan_cpu_to_le16(HostCmd_CMD_STA_CONFIGURE);
2991 cmd->size = wlan_cpu_to_le16(
2992 S_DS_GEN + sizeof(HostCmd_DS_STA_CONFIGURE) +
2993 sizeof(*tlv_band_channel));
2994 sta_cfg_cmd->action = wlan_cpu_to_le16(cmd_action);
2995 tlv_band_channel = (MrvlIEtypes_channel_band_t *)
2996 sta_cfg_cmd->tlv_buffer;
2997 memset(pmpriv->adapter, tlv_band_channel, 0x00,
2998 sizeof(*tlv_band_channel));
2999 tlv_band_channel->header.type =
3000 wlan_cpu_to_le16(TLV_TYPE_CHANNELBANDLIST);
3001 tlv_band_channel->header.len = wlan_cpu_to_le16(
3002 sizeof(MrvlIEtypes_channel_band_t) -
3003 sizeof(MrvlIEtypesHeader_t));
3004 ret = MLAN_STATUS_SUCCESS;
3005 }
3006 }
3007
3008 LEAVE();
3009 return ret;
3010 }
3011
3012 /**
3013 * @brief This function prepare the config tlvs of roam offload.
3014 *
3015 * @param priv A pointer to mlan_private structure
3016 * @param tlv_no TLV type
3017 * @param value Pointer to mlan_ds_misc_roam_offload structure
3018 * @param pointer Value of trigger_condition
3019 * @param size Pointer to the buffer of HostCmd_DS_ROAM_OFFLOAD
3020 * @return N/A
3021 */
mlan_prepare_roam_offload_tlv(pmlan_private pmpriv,t_u32 type,mlan_ds_misc_roam_offload * roam,t_u8 trigger_condition,t_u8 * pos)3022 static t_u16 mlan_prepare_roam_offload_tlv(pmlan_private pmpriv, t_u32 type,
3023 mlan_ds_misc_roam_offload *roam,
3024 t_u8 trigger_condition, t_u8 *pos)
3025 {
3026 MrvlIEtypes_fw_roam_enable_t *enable_tlv = MNULL;
3027 MrvlIEtypes_fw_roam_trigger_condition_t *trigger_condition_tlv = MNULL;
3028 MrvlIEtypes_Bssid_t *bssid_tlv = MNULL;
3029 MrvlIEtypes_SsIdParamSet_t *ssid_tlv = MNULL;
3030 MrvlIEtypes_fw_roam_retry_count_t *retry_count_tlv = MNULL;
3031 MrvlIEtypes_para_rssi_t *rssi_para_tlv = MNULL;
3032 MrvlIEtypes_fw_roam_bgscan_setting_t *bgscan_set_tlv = MNULL;
3033 MrvlIEtypes_roam_blacklist_t *blacklist_tlv = MNULL;
3034 MrvlIEtypes_ees_param_set_t *ees_param_tlv = MNULL;
3035 MrvlIEtypes_band_rssi_t *band_rssi_tlv = MNULL;
3036 MrvlIEtypes_beacon_miss_threshold_t *bcn_miss_threshold_tlv = MNULL;
3037 MrvlIEtypes_pre_beacon_miss_threshold_t *pre_bcn_miss_threshold_tlv =
3038 MNULL;
3039 MrvlIEtypes_RepeatCount_t *tlv_repeat = MNULL;
3040 t_u8 zero_mac[MLAN_MAC_ADDR_LENGTH] = {0}, *begin;
3041 int i = 0;
3042
3043 ENTER();
3044
3045 begin = pos;
3046 if (type & FW_ROAM_ENABLE) {
3047 enable_tlv = (MrvlIEtypes_fw_roam_enable_t *)pos;
3048 enable_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_ROAM);
3049 enable_tlv->header.len =
3050 wlan_cpu_to_le16(sizeof(MrvlIEtypes_fw_roam_enable_t) -
3051 sizeof(MrvlIEtypesHeader_t));
3052 if (roam->enable <= ROAM_OFFLOAD_WITHOUT_APLIST)
3053 enable_tlv->roam_enable = roam->enable;
3054 else
3055 enable_tlv->roam_enable = ROAM_OFFLOAD_WITHOUT_APLIST;
3056 pos += sizeof(MrvlIEtypes_fw_roam_enable_t);
3057 }
3058 if (type & FW_ROAM_TRIGGER_COND) {
3059 trigger_condition_tlv =
3060 (MrvlIEtypes_fw_roam_trigger_condition_t *)pos;
3061 trigger_condition_tlv->header.type =
3062 wlan_cpu_to_le16(TLV_TYPE_ROM_TRIGGER);
3063 trigger_condition_tlv->header.len = wlan_cpu_to_le16(
3064 sizeof(trigger_condition_tlv->trigger_condition));
3065 trigger_condition_tlv->trigger_condition =
3066 wlan_cpu_to_le16(trigger_condition);
3067 pos += sizeof(trigger_condition_tlv->header) +
3068 sizeof(trigger_condition_tlv->trigger_condition);
3069 }
3070 if (type & FW_ROAM_BSSID) {
3071 bssid_tlv = (MrvlIEtypes_Bssid_t *)pos;
3072 bssid_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_BSSID);
3073 bssid_tlv->header.len =
3074 wlan_cpu_to_le16(sizeof(bssid_tlv->bssid));
3075 if (memcmp(pmpriv->adapter, roam->bssid_reconnect, zero_mac,
3076 sizeof(zero_mac)) != 0)
3077 memcpy_ext(pmpriv->adapter, bssid_tlv->bssid,
3078 roam->bssid_reconnect,
3079 sizeof(bssid_tlv->bssid),
3080 sizeof(bssid_tlv->bssid));
3081 else {
3082 if (roam->config_mode == ROAM_OFFLOAD_SUSPEND_CFG)
3083 memcpy_ext(pmpriv->adapter, bssid_tlv->bssid,
3084 pmpriv->curr_bss_params
3085 .bss_descriptor.mac_address,
3086 sizeof(bssid_tlv->bssid),
3087 sizeof(bssid_tlv->bssid));
3088 else if (roam->config_mode == ROAM_OFFLOAD_RESUME_CFG)
3089 memcpy_ext(pmpriv->adapter, bssid_tlv->bssid,
3090 zero_mac, sizeof(bssid_tlv->bssid),
3091 sizeof(bssid_tlv->bssid));
3092 }
3093 pos += sizeof(bssid_tlv->header) + sizeof(bssid_tlv->bssid);
3094 }
3095 if (type & FW_ROAM_SSID) {
3096 for (i = 0; i < roam->ssid_list.ssid_num; i++) {
3097 ssid_tlv = (MrvlIEtypes_SsIdParamSet_t *)pos;
3098 ssid_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_SSID);
3099 memcpy_ext(pmpriv->adapter, ssid_tlv->ssid,
3100 roam->ssid_list.ssids[i].ssid,
3101 roam->ssid_list.ssids[i].ssid_len,
3102 roam->ssid_list.ssids[i].ssid_len);
3103 pos += sizeof(ssid_tlv->header) +
3104 wlan_strlen(ssid_tlv->ssid);
3105 ssid_tlv->header.len =
3106 wlan_cpu_to_le16(wlan_strlen(ssid_tlv->ssid));
3107 }
3108 if (!roam->ssid_list.ssid_num) {
3109 ssid_tlv = (MrvlIEtypes_SsIdParamSet_t *)pos;
3110 ssid_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_SSID);
3111 memcpy_ext(
3112 pmpriv->adapter, ssid_tlv->ssid,
3113 pmpriv->curr_bss_params.bss_descriptor.ssid.ssid,
3114 pmpriv->curr_bss_params.bss_descriptor.ssid
3115 .ssid_len,
3116 pmpriv->curr_bss_params.bss_descriptor.ssid
3117 .ssid_len);
3118 ssid_tlv->header.len =
3119 wlan_cpu_to_le16(wlan_strlen(ssid_tlv->ssid));
3120 pos += sizeof(ssid_tlv->header) + ssid_tlv->header.len;
3121 }
3122 }
3123 if (type & FW_ROAM_RETRY_COUNT) {
3124 retry_count_tlv = (MrvlIEtypes_fw_roam_retry_count_t *)pos;
3125 retry_count_tlv->header.type =
3126 wlan_cpu_to_le16(TLV_TYPE_ROM_RETRY_COUNT);
3127 retry_count_tlv->header.len =
3128 wlan_cpu_to_le16(sizeof(retry_count_tlv->retry_count));
3129 if (roam->retry_count)
3130 retry_count_tlv->retry_count =
3131 wlan_cpu_to_le16(roam->retry_count);
3132 else
3133 retry_count_tlv->retry_count =
3134 wlan_cpu_to_le16(RETRY_UNLIMITED_TIME);
3135 pos += sizeof(retry_count_tlv->header) +
3136 sizeof(retry_count_tlv->retry_count);
3137 }
3138 if (type & FW_ROAM_RSSI_PARA) {
3139 rssi_para_tlv = (MrvlIEtypes_para_rssi_t *)pos;
3140 rssi_para_tlv->header.type =
3141 wlan_cpu_to_le16(TLV_TYPE_ROM_PARA_RSSI);
3142 rssi_para_tlv->header.len =
3143 wlan_cpu_to_le16(sizeof(rssi_para_tlv->max_rssi) +
3144 sizeof(rssi_para_tlv->min_rssi) +
3145 sizeof(rssi_para_tlv->step_rssi));
3146 rssi_para_tlv->max_rssi = roam->para_rssi.max_rssi;
3147 rssi_para_tlv->min_rssi = roam->para_rssi.min_rssi;
3148 rssi_para_tlv->step_rssi = roam->para_rssi.step_rssi;
3149 pos += sizeof(rssi_para_tlv->header) +
3150 sizeof(rssi_para_tlv->max_rssi) +
3151 sizeof(rssi_para_tlv->min_rssi) +
3152 sizeof(rssi_para_tlv->step_rssi);
3153 }
3154 if (type & FW_ROAM_BAND_RSSI) {
3155 band_rssi_tlv = (MrvlIEtypes_band_rssi_t *)pos;
3156 band_rssi_tlv->header.type =
3157 wlan_cpu_to_le16(TLV_TYPE_BAND_RSSI);
3158 band_rssi_tlv->header.len =
3159 wlan_cpu_to_le16(sizeof(MrvlIEtypes_band_rssi_t) -
3160 sizeof(MrvlIEtypesHeader_t));
3161 band_rssi_tlv->band_rssi.band_preferred =
3162 roam->band_rssi.band_preferred;
3163 band_rssi_tlv->band_rssi.rssi_hysteresis =
3164 roam->band_rssi.rssi_hysteresis;
3165 pos += sizeof(MrvlIEtypes_band_rssi_t);
3166 }
3167
3168 if (type & FW_ROAM_BGSCAN_PARAM) {
3169 bgscan_set_tlv = (MrvlIEtypes_fw_roam_bgscan_setting_t *)pos;
3170 bgscan_set_tlv->header.type =
3171 wlan_cpu_to_le16(TLV_TYPE_ROM_BGSCAN);
3172 bgscan_set_tlv->header.len = wlan_cpu_to_le16(
3173 sizeof(MrvlIEtypes_fw_roam_bgscan_setting_t) -
3174 sizeof(MrvlIEtypesHeader_t));
3175 bgscan_set_tlv->bss_type = roam->bgscan_cfg.bss_type;
3176 bgscan_set_tlv->channels_perscan =
3177 roam->bgscan_cfg.channels_per_scan;
3178 bgscan_set_tlv->scan_interval =
3179 wlan_cpu_to_le32(roam->bgscan_cfg.scan_interval);
3180 bgscan_set_tlv->report_condition =
3181 wlan_cpu_to_le32(roam->bgscan_cfg.bg_rpt_condition);
3182 pos += sizeof(MrvlIEtypes_fw_roam_bgscan_setting_t);
3183 }
3184
3185 if (type & FW_ROAM_EES_PARAM) {
3186 ees_param_tlv = (MrvlIEtypes_ees_param_set_t *)pos;
3187 ees_param_tlv->header.type =
3188 wlan_cpu_to_le16(TLV_TYPE_ENERGYEFFICIENTSCAN);
3189 ees_param_tlv->header.len =
3190 wlan_cpu_to_le16(sizeof(MrvlIEtypes_ees_param_set_t) -
3191 sizeof(MrvlIEtypesHeader_t));
3192 ees_param_tlv->ees_cfg.ees_mode =
3193 wlan_cpu_to_le16(roam->ees_cfg.ees_mode);
3194 ees_param_tlv->ees_cfg.ees_rpt_condition =
3195 wlan_cpu_to_le16(roam->ees_cfg.ees_rpt_condition);
3196 ees_param_tlv->ees_cfg.high_scan_period =
3197 wlan_cpu_to_le16(roam->ees_cfg.high_scan_period);
3198 ees_param_tlv->ees_cfg.high_scan_count =
3199 wlan_cpu_to_le16(roam->ees_cfg.high_scan_count);
3200 ees_param_tlv->ees_cfg.mid_scan_period =
3201 wlan_cpu_to_le16(roam->ees_cfg.mid_scan_period);
3202 ees_param_tlv->ees_cfg.mid_scan_count =
3203 wlan_cpu_to_le16(roam->ees_cfg.mid_scan_count);
3204 ees_param_tlv->ees_cfg.low_scan_period =
3205 wlan_cpu_to_le16(roam->ees_cfg.low_scan_period);
3206 ees_param_tlv->ees_cfg.low_scan_count =
3207 wlan_cpu_to_le16(roam->ees_cfg.low_scan_count);
3208 pos += sizeof(MrvlIEtypes_ees_param_set_t);
3209 }
3210
3211 if (type & FW_ROAM_BCN_MISS_THRESHOLD) {
3212 bcn_miss_threshold_tlv =
3213 (MrvlIEtypes_beacon_miss_threshold_t *)pos;
3214 bcn_miss_threshold_tlv->header.type =
3215 wlan_cpu_to_le16(TLV_TYPE_BCNMISS);
3216 bcn_miss_threshold_tlv->header.len = wlan_cpu_to_le16(
3217 sizeof(MrvlIEtypes_beacon_miss_threshold_t) -
3218 sizeof(MrvlIEtypesHeader_t));
3219 bcn_miss_threshold_tlv->bcn_miss_threshold =
3220 roam->bcn_miss_threshold;
3221 pos += sizeof(MrvlIEtypes_beacon_miss_threshold_t);
3222 }
3223
3224 if (type & FW_ROAM_PRE_BCN_MISS_THRESHOLD) {
3225 pre_bcn_miss_threshold_tlv =
3226 (MrvlIEtypes_pre_beacon_miss_threshold_t *)pos;
3227 pre_bcn_miss_threshold_tlv->header.type =
3228 wlan_cpu_to_le16(TLV_TYPE_PRE_BCNMISS);
3229 pre_bcn_miss_threshold_tlv->header.len = wlan_cpu_to_le16(
3230 sizeof(MrvlIEtypes_pre_beacon_miss_threshold_t) -
3231 sizeof(MrvlIEtypesHeader_t));
3232 pre_bcn_miss_threshold_tlv->pre_bcn_miss_threshold =
3233 roam->pre_bcn_miss_threshold;
3234 pos += sizeof(MrvlIEtypes_pre_beacon_miss_threshold_t);
3235 }
3236
3237 if (type & FW_ROAM_BLACKLIST) {
3238 blacklist_tlv = (MrvlIEtypes_roam_blacklist_t *)pos;
3239 blacklist_tlv->header.type =
3240 wlan_cpu_to_le16(TLV_TYPE_BLACKLIST_BSSID);
3241 blacklist_tlv->header.len =
3242 roam->black_list.ap_num * MLAN_MAC_ADDR_LENGTH +
3243 sizeof(roam->black_list.ap_num);
3244 memcpy_ext(pmpriv->adapter, (t_u8 *)&blacklist_tlv->blacklist,
3245 (t_u8 *)&roam->black_list, blacklist_tlv->header.len,
3246 sizeof(blacklist_tlv->blacklist));
3247 pos += sizeof(MrvlIEtypesHeader_t) + blacklist_tlv->header.len;
3248 blacklist_tlv->header.len =
3249 wlan_cpu_to_le16(blacklist_tlv->header.len);
3250 }
3251
3252 if (type & FW_ROAM_REPEAT_CNT) {
3253 tlv_repeat = (MrvlIEtypes_RepeatCount_t *)pos;
3254 tlv_repeat->header.type =
3255 wlan_cpu_to_le16(TLV_TYPE_REPEAT_COUNT);
3256 tlv_repeat->header.len =
3257 wlan_cpu_to_le16(sizeof(MrvlIEtypes_RepeatCount_t) -
3258 sizeof(MrvlIEtypesHeader_t));
3259 tlv_repeat->repeat_count = wlan_cpu_to_le16(roam->repeat_count);
3260 pos += sizeof(MrvlIEtypes_RepeatCount_t);
3261 }
3262 LEAVE();
3263 return (pos - begin);
3264 }
3265 /**
3266 * @brief This function sends enable/disable roam offload command to firmware.
3267 *
3268 * @param pmpriv A pointer to mlan_private structure
3269 * @param pcmd Hostcmd ID
3270 * @param cmd_action Command action
3271 * @return N/A
3272 */
wlan_cmd_roam_offload(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)3273 static mlan_status wlan_cmd_roam_offload(pmlan_private pmpriv,
3274 HostCmd_DS_COMMAND *cmd,
3275 t_u16 cmd_action, t_void *pdata_buf)
3276 {
3277 HostCmd_DS_ROAM_OFFLOAD *roam_cmd = &cmd->params.roam_offload;
3278 MrvlIEtypes_roam_aplist_t *aplist = MNULL;
3279 t_u8 *pos = (t_u8 *)roam_cmd + sizeof(roam_cmd->action);
3280 mlan_ds_misc_roam_offload *roam = MNULL;
3281 t_u8 zero_mac[MLAN_MAC_ADDR_LENGTH] = {0};
3282 t_u32 type = 0;
3283 t_u8 trigger_condition = 0;
3284
3285 ENTER();
3286
3287 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_ROAM_OFFLOAD);
3288 cmd->size = S_DS_GEN + sizeof(HostCmd_DS_ROAM_OFFLOAD);
3289 roam_cmd->action = wlan_cpu_to_le16(cmd_action);
3290
3291 roam = (mlan_ds_misc_roam_offload *)pdata_buf;
3292
3293 if (roam->config_mode) {
3294 switch (roam->config_mode) {
3295 case ROAM_OFFLOAD_ENABLE:
3296 type |= FW_ROAM_ENABLE;
3297 if (roam->enable && roam->enable != AUTO_RECONNECT) {
3298 type |= FW_ROAM_TRIGGER_COND;
3299 trigger_condition |= RSSI_LOW_TRIGGER |
3300 PRE_BEACON_LOST_TRIGGER;
3301 }
3302 break;
3303 case ROAM_OFFLOAD_SUSPEND_CFG:
3304 type |= FW_ROAM_TRIGGER_COND | FW_ROAM_RETRY_COUNT;
3305 if (roam->enable == AUTO_RECONNECT) {
3306 type |= FW_ROAM_BSSID | FW_ROAM_SSID;
3307 trigger_condition = LINK_LOST_TRIGGER |
3308 DEAUTH_WITH_EXT_AP_TRIGGER;
3309 } else
3310 trigger_condition = LINK_LOST_TRIGGER |
3311 DEAUTH_WITH_EXT_AP_TRIGGER |
3312 RSSI_LOW_TRIGGER |
3313 PRE_BEACON_LOST_TRIGGER;
3314
3315 if (roam->enable == ROAM_OFFLOAD_WITH_BSSID)
3316 type |= FW_ROAM_BSSID;
3317 if (roam->enable == ROAM_OFFLOAD_WITH_SSID)
3318 type |= FW_ROAM_SSID;
3319 break;
3320 case ROAM_OFFLOAD_RESUME_CFG:
3321 type |= FW_ROAM_TRIGGER_COND;
3322 if (roam->enable == AUTO_RECONNECT)
3323 trigger_condition = NO_TRIGGER;
3324 else
3325 trigger_condition = RSSI_LOW_TRIGGER |
3326 PRE_BEACON_LOST_TRIGGER;
3327 if (roam->enable == ROAM_OFFLOAD_WITH_BSSID ||
3328 roam->enable == AUTO_RECONNECT)
3329 type |= FW_ROAM_BSSID;
3330 break;
3331 case ROAM_OFFLOAD_PARAM_CFG:
3332 if (roam->enable && roam->enable != AUTO_RECONNECT) {
3333 if (roam->retry_count != 0)
3334 type |= FW_ROAM_RETRY_COUNT;
3335 if (roam->ssid_list.ssid_num)
3336 type |= FW_ROAM_SSID;
3337 if (roam->para_rssi.set_flag)
3338 type |= FW_ROAM_RSSI_PARA;
3339 if (memcmp(pmpriv->adapter,
3340 roam->bssid_reconnect, zero_mac,
3341 sizeof(zero_mac)) != 0)
3342 type |= FW_ROAM_BSSID;
3343 if (roam->band_rssi_flag)
3344 type |= FW_ROAM_BAND_RSSI;
3345 if (roam->bgscan_set_flag)
3346 type |= FW_ROAM_BGSCAN_PARAM;
3347 if (roam->ees_param_set_flag)
3348 type |= FW_ROAM_EES_PARAM;
3349 if (roam->bcn_miss_threshold)
3350 type |= FW_ROAM_BCN_MISS_THRESHOLD;
3351 if (roam->pre_bcn_miss_threshold)
3352 type |= FW_ROAM_PRE_BCN_MISS_THRESHOLD;
3353 if (roam->black_list.ap_num)
3354 type |= FW_ROAM_BLACKLIST;
3355 if (roam->trigger_condition != 0xff) {
3356 type |= FW_ROAM_TRIGGER_COND;
3357 trigger_condition =
3358 roam->trigger_condition;
3359 }
3360 if (roam->repeat_count)
3361 type |= FW_ROAM_REPEAT_CNT;
3362 }
3363 break;
3364 }
3365 cmd->size += mlan_prepare_roam_offload_tlv(
3366 pmpriv, type, roam, trigger_condition, pos);
3367 }
3368 if (roam->aplist.ap_num) {
3369 aplist = (MrvlIEtypes_roam_aplist_t *)pos;
3370 aplist->header.type = wlan_cpu_to_le16(TLV_TYPE_APLIST);
3371 aplist->header.len = roam->aplist.ap_num * MLAN_MAC_ADDR_LENGTH;
3372 memcpy_ext(pmpriv->adapter, aplist->ap_mac, roam->aplist.ap_mac,
3373 roam->aplist.ap_num * MLAN_MAC_ADDR_LENGTH,
3374 roam->aplist.ap_num * MLAN_MAC_ADDR_LENGTH);
3375 pos += sizeof(aplist->header) + aplist->header.len;
3376 cmd->size += sizeof(aplist->header) + aplist->header.len;
3377 aplist->header.len = wlan_cpu_to_le16(aplist->header.len);
3378 }
3379 cmd->size = wlan_cpu_to_le16(cmd->size);
3380
3381 LEAVE();
3382 return MLAN_STATUS_SUCCESS;
3383 }
3384
3385 /**
3386 * @brief This function sends set and get auto tx command to firmware.
3387 *
3388 * @param pmpriv A pointer to mlan_private structure
3389 * @param pcmd Hostcmd ID
3390 * @param cmd_action Command action
3391 * @param cmd_oid Cmd oid: treated as sub command
3392 * @param pdata_buf A void pointer to information buffer
3393 * @return N/A
3394 */
wlan_cmd_auto_tx(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_u32 cmd_oid,t_void * pdata_buf)3395 static mlan_status wlan_cmd_auto_tx(pmlan_private pmpriv,
3396 HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
3397 t_u32 cmd_oid, t_void *pdata_buf)
3398 {
3399 HostCmd_DS_AUTO_TX *auto_tx_cmd = &cmd->params.auto_tx;
3400 t_u8 *pos = (t_u8 *)auto_tx_cmd->tlv_buffer;
3401 t_u16 len = 0;
3402 MrvlIEtypes_Cloud_Keep_Alive_t *keep_alive_tlv = MNULL;
3403 MrvlIEtypes_Keep_Alive_Ctrl_t *ctrl_tlv = MNULL;
3404 MrvlIEtypes_Keep_Alive_Pkt_t *pkt_tlv = MNULL;
3405 mlan_ds_misc_keep_alive *misc_keep_alive = MNULL;
3406 t_u8 eth_ip[] = {0x08, 0x00};
3407
3408 ENTER();
3409
3410 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_AUTO_TX);
3411 cmd->size = S_DS_GEN + sizeof(HostCmd_DS_AUTO_TX);
3412 auto_tx_cmd->action = wlan_cpu_to_le16(cmd_action);
3413
3414 switch (cmd_oid) {
3415 case OID_CLOUD_KEEP_ALIVE:
3416 misc_keep_alive = (mlan_ds_misc_keep_alive *)pdata_buf;
3417 keep_alive_tlv = (MrvlIEtypes_Cloud_Keep_Alive_t *)pos;
3418
3419 keep_alive_tlv->header.type =
3420 wlan_cpu_to_le16(TLV_TYPE_CLOUD_KEEP_ALIVE);
3421 keep_alive_tlv->keep_alive_id = misc_keep_alive->mkeep_alive_id;
3422 keep_alive_tlv->enable = misc_keep_alive->enable;
3423 len = len + sizeof(keep_alive_tlv->keep_alive_id) +
3424 sizeof(keep_alive_tlv->enable);
3425 pos = pos + len + sizeof(MrvlIEtypesHeader_t);
3426 if (cmd_action == HostCmd_ACT_GEN_SET) {
3427 if (misc_keep_alive->enable) {
3428 ctrl_tlv = (MrvlIEtypes_Keep_Alive_Ctrl_t *)pos;
3429 ctrl_tlv->header.type = wlan_cpu_to_le16(
3430 TLV_TYPE_KEEP_ALIVE_CTRL);
3431 ctrl_tlv->header.len = wlan_cpu_to_le16(
3432 sizeof(MrvlIEtypes_Keep_Alive_Ctrl_t) -
3433 sizeof(MrvlIEtypesHeader_t));
3434 ctrl_tlv->snd_interval = wlan_cpu_to_le32(
3435 misc_keep_alive->send_interval);
3436 ctrl_tlv->retry_interval = wlan_cpu_to_le16(
3437 misc_keep_alive->retry_interval);
3438 ctrl_tlv->retry_count = wlan_cpu_to_le16(
3439 misc_keep_alive->retry_count);
3440 len = len +
3441 sizeof(MrvlIEtypes_Keep_Alive_Ctrl_t);
3442
3443 pos = pos +
3444 sizeof(MrvlIEtypes_Keep_Alive_Ctrl_t);
3445 pkt_tlv = (MrvlIEtypes_Keep_Alive_Pkt_t *)pos;
3446 pkt_tlv->header.type = wlan_cpu_to_le16(
3447 TLV_TYPE_KEEP_ALIVE_PKT);
3448 memcpy_ext(pmpriv->adapter,
3449 pkt_tlv->eth_header.dest_addr,
3450 misc_keep_alive->dst_mac,
3451 MLAN_MAC_ADDR_LENGTH,
3452 MLAN_MAC_ADDR_LENGTH);
3453 memcpy_ext(pmpriv->adapter,
3454 pkt_tlv->eth_header.src_addr,
3455 misc_keep_alive->src_mac,
3456 MLAN_MAC_ADDR_LENGTH,
3457 MLAN_MAC_ADDR_LENGTH);
3458 memcpy_ext(
3459 pmpriv->adapter,
3460 (t_u8 *)&pkt_tlv->eth_header.h803_len,
3461 eth_ip, sizeof(t_u16), sizeof(t_u16));
3462 if (misc_keep_alive->ether_type)
3463 pkt_tlv->eth_header
3464 .h803_len = mlan_htons(
3465 misc_keep_alive->ether_type);
3466 else
3467 memcpy_ext(pmpriv->adapter,
3468 (t_u8 *)&pkt_tlv->eth_header
3469 .h803_len,
3470 eth_ip, sizeof(t_u16),
3471 sizeof(t_u16));
3472 memcpy_ext(pmpriv->adapter,
3473 (t_u8 *)&pkt_tlv->ip_packet,
3474 misc_keep_alive->packet,
3475 misc_keep_alive->pkt_len,
3476 MKEEP_ALIVE_IP_PKT_MAX);
3477 pkt_tlv->header.len = wlan_cpu_to_le16(
3478 sizeof(Eth803Hdr_t) +
3479 misc_keep_alive->pkt_len);
3480 len = len + sizeof(MrvlIEtypesHeader_t) +
3481 sizeof(Eth803Hdr_t) +
3482 misc_keep_alive->pkt_len;
3483 } else {
3484 pkt_tlv = (MrvlIEtypes_Keep_Alive_Pkt_t *)pos;
3485 pkt_tlv->header.type = wlan_cpu_to_le16(
3486 TLV_TYPE_KEEP_ALIVE_PKT);
3487 pkt_tlv->header.len = 0;
3488 len = len + sizeof(MrvlIEtypesHeader_t);
3489 }
3490 }
3491 if (cmd_action == HostCmd_ACT_GEN_RESET) {
3492 pkt_tlv = (MrvlIEtypes_Keep_Alive_Pkt_t *)pos;
3493 pkt_tlv->header.type =
3494 wlan_cpu_to_le16(TLV_TYPE_KEEP_ALIVE_PKT);
3495 pkt_tlv->header.len = 0;
3496 len = len + sizeof(MrvlIEtypesHeader_t);
3497 }
3498 keep_alive_tlv->header.len = wlan_cpu_to_le16(len);
3499
3500 cmd->size = cmd->size + len + sizeof(MrvlIEtypesHeader_t);
3501 cmd->size = wlan_cpu_to_le16(cmd->size);
3502 break;
3503 default:
3504 break;
3505 }
3506
3507 LEAVE();
3508 return MLAN_STATUS_SUCCESS;
3509 }
3510
3511 /**
3512 * @brief This function check if the command is supported by firmware
3513 *
3514 * @param priv A pointer to mlan_private structure
3515 * @param cmd_no Command number
3516 *
3517 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
3518 */
wlan_is_cmd_allowed(mlan_private * priv,t_u16 cmd_no)3519 static mlan_status wlan_is_cmd_allowed(mlan_private *priv, t_u16 cmd_no)
3520 {
3521 mlan_status ret = MLAN_STATUS_SUCCESS;
3522
3523 ENTER();
3524 if (priv->adapter->pcard_info->v16_fw_api) {
3525 if (!IS_FW_SUPPORT_ADHOC(priv->adapter)) {
3526 switch (cmd_no) {
3527 case HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON:
3528 case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS:
3529 case HostCmd_CMD_802_11_AD_HOC_START:
3530 case HostCmd_CMD_802_11_AD_HOC_JOIN:
3531 case HostCmd_CMD_802_11_AD_HOC_STOP:
3532 ret = MLAN_STATUS_FAILURE;
3533 break;
3534 default:
3535 break;
3536 }
3537 }
3538 }
3539 LEAVE();
3540 return ret;
3541 }
3542
3543 /**
3544 * @brief This function enable/disable CSI support.
3545 *
3546 * @param pmpriv A pointer to mlan_private structure
3547 * @param cmd A pointer to HostCmd_DS_COMMAND structure
3548 * @param cmd_action The action: GET or SET
3549 * @param pdata_buf A pointer to data buffer
3550 *
3551 * @return MLAN_STATUS_SUCCESS
3552 */
wlan_cmd_csi(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_u16 * pdata_buf)3553 static mlan_status wlan_cmd_csi(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
3554 t_u16 cmd_action, t_u16 *pdata_buf)
3555 {
3556 HostCmd_DS_CSI_CFG *csi_cfg_cmd = &cmd->params.csi_params;
3557 mlan_ds_csi_params *csi_params = MNULL;
3558
3559 ENTER();
3560
3561 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_CSI);
3562 cmd->size = sizeof(HostCmd_DS_CSI_CFG) + S_DS_GEN;
3563 csi_cfg_cmd->action = wlan_cpu_to_le16(cmd_action);
3564 switch (cmd_action) {
3565 case CSI_CMD_ENABLE:
3566 csi_params = (mlan_ds_csi_params *)pdata_buf;
3567 csi_cfg_cmd->head_id = wlan_cpu_to_le32(csi_params->head_id);
3568 csi_cfg_cmd->tail_id = wlan_cpu_to_le32(csi_params->tail_id);
3569 csi_cfg_cmd->chip_id = csi_params->chip_id;
3570 csi_cfg_cmd->csi_filter_cnt = csi_params->csi_filter_cnt;
3571 if (csi_cfg_cmd->csi_filter_cnt > CSI_FILTER_MAX)
3572 csi_cfg_cmd->csi_filter_cnt = CSI_FILTER_MAX;
3573 memcpy_ext(pmpriv->adapter, (t_u8 *)csi_cfg_cmd->csi_filter,
3574 (t_u8 *)csi_params->csi_filter,
3575 sizeof(mlan_csi_filter_t) *
3576 csi_cfg_cmd->csi_filter_cnt,
3577 sizeof(csi_cfg_cmd->csi_filter));
3578 DBG_HEXDUMP(MCMD_D, "Enable CSI", csi_cfg_cmd,
3579 sizeof(HostCmd_DS_CSI_CFG));
3580 break;
3581 case CSI_CMD_DISABLE:
3582 DBG_HEXDUMP(MCMD_D, "Disable CSI", csi_cfg_cmd,
3583 sizeof(HostCmd_DS_CSI_CFG));
3584 default:
3585 break;
3586 }
3587 cmd->size = wlan_cpu_to_le16(cmd->size);
3588 LEAVE();
3589 return MLAN_STATUS_SUCCESS;
3590 }
3591
3592 /**
3593 * @brief This function prepare the command before sending to firmware.
3594 *
3595 * @param priv A pointer to mlan_private structure
3596 * @param cmd_no Command number
3597 * @param cmd_action Command action: GET or SET
3598 * @param cmd_oid Cmd oid: treated as sub command
3599 * @param pioctl_buf A pointer to MLAN IOCTL Request buffer
3600 * @param pdata_buf A pointer to information buffer
3601 * @param pcmd_buf A pointer to cmd buf
3602 *
3603 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
3604 */
wlan_ops_sta_prepare_cmd(t_void * priv,t_u16 cmd_no,t_u16 cmd_action,t_u32 cmd_oid,t_void * pioctl_buf,t_void * pdata_buf,t_void * pcmd_buf)3605 mlan_status wlan_ops_sta_prepare_cmd(t_void *priv, t_u16 cmd_no,
3606 t_u16 cmd_action, t_u32 cmd_oid,
3607 t_void *pioctl_buf, t_void *pdata_buf,
3608 t_void *pcmd_buf)
3609 {
3610 HostCmd_DS_COMMAND *cmd_ptr = (HostCmd_DS_COMMAND *)pcmd_buf;
3611 mlan_private *pmpriv = (mlan_private *)priv;
3612 mlan_status ret = MLAN_STATUS_SUCCESS;
3613
3614 ENTER();
3615
3616 if (wlan_is_cmd_allowed(pmpriv, cmd_no)) {
3617 PRINTM(MERROR, "FW don't support the command 0x%x\n", cmd_no);
3618 return MLAN_STATUS_FAILURE;
3619 }
3620 /* Prepare command */
3621 switch (cmd_no) {
3622 case HostCmd_CMD_GET_HW_SPEC:
3623 ret = wlan_cmd_get_hw_spec(pmpriv, cmd_ptr);
3624 break;
3625 #ifdef SDIO
3626 case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG:
3627 ret = wlan_cmd_sdio_rx_aggr_cfg(cmd_ptr, cmd_action, pdata_buf);
3628 break;
3629 #endif
3630 case HostCmd_CMD_CFG_DATA:
3631 ret = wlan_cmd_cfg_data(pmpriv, cmd_ptr, cmd_action, cmd_oid,
3632 pdata_buf);
3633 break;
3634 case HostCmd_CMD_MAC_CONTROL:
3635 ret = wlan_cmd_mac_control(pmpriv, cmd_ptr, cmd_action,
3636 pdata_buf);
3637 break;
3638 case HostCmd_CMD_802_11_MAC_ADDRESS:
3639 ret = wlan_cmd_802_11_mac_address(pmpriv, cmd_ptr, cmd_action);
3640 break;
3641 case HostCmd_CMD_MAC_MULTICAST_ADR:
3642 ret = wlan_cmd_mac_multicast_adr(pmpriv, cmd_ptr, cmd_action,
3643 pdata_buf);
3644 break;
3645 case HostCmd_CMD_TX_RATE_CFG:
3646 ret = wlan_cmd_tx_rate_cfg(pmpriv, cmd_ptr, cmd_action,
3647 pdata_buf, pioctl_buf);
3648 break;
3649 case HostCmd_CMD_802_11_RF_ANTENNA:
3650 ret = wlan_cmd_802_11_rf_antenna(pmpriv, cmd_ptr, cmd_action,
3651 pdata_buf);
3652 break;
3653 case HostCmd_CMD_CW_MODE_CTRL:
3654 ret = wlan_cmd_cw_mode_ctrl(pmpriv, cmd_ptr, cmd_action,
3655 pdata_buf);
3656 break;
3657 case HostCmd_CMD_TXPWR_CFG:
3658 ret = wlan_cmd_tx_power_cfg(pmpriv, cmd_ptr, cmd_action,
3659 pdata_buf);
3660 break;
3661 case HostCmd_CMD_802_11_RF_TX_POWER:
3662 ret = wlan_cmd_802_11_rf_tx_power(pmpriv, cmd_ptr, cmd_action,
3663 pdata_buf);
3664 break;
3665 case HostCmd_CMD_802_11_PS_MODE_ENH:
3666 ret = wlan_cmd_enh_power_mode(pmpriv, cmd_ptr, cmd_action,
3667 (t_u16)cmd_oid, pdata_buf);
3668 break;
3669 case HostCmd_CMD_802_11_HS_CFG_ENH:
3670 ret = wlan_cmd_802_11_hs_cfg(pmpriv, cmd_ptr, cmd_action,
3671 (hs_config_param *)pdata_buf);
3672 break;
3673 case HostCmd_CMD_802_11_ROBUSTCOEX:
3674 ret = wlan_cmd_robustcoex(pmpriv, cmd_ptr, cmd_action,
3675 pdata_buf);
3676 break;
3677 case HostCmd_CMD_DMCS_CONFIG:
3678 ret = wlan_cmd_dmcs_config(pmpriv, cmd_ptr, cmd_action,
3679 pdata_buf);
3680 break;
3681 #if defined(PCIE)
3682 case HostCmd_CMD_SSU:
3683 ret = wlan_cmd_ssu(pmpriv, cmd_ptr, cmd_action, pdata_buf);
3684 break;
3685 #endif
3686 case HostCmd_CMD_CSI:
3687 ret = wlan_cmd_csi(pmpriv, cmd_ptr, cmd_action, pdata_buf);
3688 break;
3689 case HostCmd_CMD_HAL_PHY_CFG:
3690 ret = wlan_cmd_hal_phy_cfg(pmpriv, cmd_ptr, cmd_action,
3691 pdata_buf);
3692 break;
3693 case HostCmd_CMD_IPS_CONFIG:
3694 ret = wlan_cmd_ips_config(pmpriv, cmd_ptr, cmd_action,
3695 pdata_buf);
3696 break;
3697 case HOST_CMD_PMIC_CONFIGURE:
3698 cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
3699 cmd_ptr->size = wlan_cpu_to_le16(S_DS_GEN);
3700 break;
3701 case HostCmd_CMD_802_11_SLEEP_PERIOD:
3702 ret = wlan_cmd_802_11_sleep_period(pmpriv, cmd_ptr, cmd_action,
3703 (t_u16 *)pdata_buf);
3704 break;
3705 case HostCmd_CMD_802_11_SLEEP_PARAMS:
3706 ret = wlan_cmd_802_11_sleep_params(pmpriv, cmd_ptr, cmd_action,
3707 (t_u16 *)pdata_buf);
3708 break;
3709 case HostCmd_CMD_802_11_SCAN:
3710 ret = wlan_cmd_802_11_scan(pmpriv, cmd_ptr, pdata_buf);
3711 break;
3712 case HostCmd_CMD_802_11_BG_SCAN_CONFIG:
3713 ret = wlan_cmd_bgscan_config(pmpriv, cmd_ptr, pdata_buf);
3714 break;
3715 case HostCmd_CMD_802_11_BG_SCAN_QUERY:
3716 ret = wlan_cmd_802_11_bg_scan_query(pmpriv, cmd_ptr, pdata_buf);
3717 break;
3718 case HostCmd_CMD_802_11_ASSOCIATE:
3719 ret = wlan_cmd_802_11_associate(pmpriv, cmd_ptr, pdata_buf);
3720 break;
3721 case HostCmd_CMD_802_11_DEAUTHENTICATE:
3722 case HostCmd_CMD_802_11_DISASSOCIATE:
3723 ret = wlan_cmd_802_11_deauthenticate(pmpriv, cmd_no, cmd_ptr,
3724 pdata_buf);
3725 break;
3726 case HostCmd_CMD_802_11_AD_HOC_START:
3727 ret = wlan_cmd_802_11_ad_hoc_start(pmpriv, cmd_ptr, pdata_buf);
3728 break;
3729 case HostCmd_CMD_802_11_AD_HOC_JOIN:
3730 ret = wlan_cmd_802_11_ad_hoc_join(pmpriv, cmd_ptr, pdata_buf);
3731 break;
3732 case HostCmd_CMD_802_11_AD_HOC_STOP:
3733 ret = wlan_cmd_802_11_ad_hoc_stop(pmpriv, cmd_ptr);
3734 break;
3735 case HostCmd_CMD_802_11_GET_LOG:
3736 ret = wlan_cmd_802_11_get_log(pmpriv, cmd_ptr);
3737 break;
3738 case HostCmd_CMD_802_11_LINK_STATS:
3739 ret = wlan_cmd_802_11_link_statistic(pmpriv, cmd_ptr,
3740 cmd_action, pioctl_buf);
3741 break;
3742 case HostCmd_CMD_RSSI_INFO:
3743 ret = wlan_cmd_802_11_rssi_info(pmpriv, cmd_ptr, cmd_action);
3744 break;
3745 case HostCmd_CMD_RSSI_INFO_EXT:
3746 ret = wlan_cmd_802_11_rssi_info_ext(pmpriv, cmd_ptr, cmd_action,
3747 pdata_buf);
3748 break;
3749 case HostCmd_CMD_802_11_SNMP_MIB:
3750 ret = wlan_cmd_802_11_snmp_mib(pmpriv, cmd_ptr, cmd_action,
3751 cmd_oid, pdata_buf);
3752 break;
3753 case HostCmd_CMD_802_11_RADIO_CONTROL:
3754 ret = wlan_cmd_802_11_radio_control(pmpriv, cmd_ptr, cmd_action,
3755 pdata_buf);
3756 break;
3757 case HostCmd_CMD_802_11_TX_RATE_QUERY:
3758 cmd_ptr->command =
3759 wlan_cpu_to_le16(HostCmd_CMD_802_11_TX_RATE_QUERY);
3760 cmd_ptr->size = wlan_cpu_to_le16(sizeof(HostCmd_TX_RATE_QUERY) +
3761 S_DS_GEN);
3762 pmpriv->tx_rate = 0;
3763 ret = MLAN_STATUS_SUCCESS;
3764 break;
3765 case HostCmd_CMD_VERSION_EXT:
3766 cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
3767 cmd_ptr->params.verext.version_str_sel =
3768 (t_u8)(*((t_u32 *)pdata_buf));
3769 cmd_ptr->size = wlan_cpu_to_le16(
3770 sizeof(HostCmd_DS_VERSION_EXT) + S_DS_GEN);
3771 ret = MLAN_STATUS_SUCCESS;
3772 break;
3773 case HostCmd_CMD_RX_MGMT_IND:
3774 cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
3775 cmd_ptr->params.rx_mgmt_ind.action =
3776 wlan_cpu_to_le16(cmd_action);
3777 cmd_ptr->params.rx_mgmt_ind.mgmt_subtype_mask =
3778 wlan_cpu_to_le32((t_u32)(*((t_u32 *)pdata_buf)));
3779 cmd_ptr->size = wlan_cpu_to_le16(
3780 sizeof(HostCmd_DS_RX_MGMT_IND) + S_DS_GEN);
3781 break;
3782 case HostCmd_CMD_802_11_RF_CHANNEL:
3783 ret = wlan_cmd_802_11_rf_channel(pmpriv, cmd_ptr, cmd_action,
3784 pdata_buf);
3785 break;
3786 case HostCmd_CMD_FUNC_INIT:
3787 if (pmpriv->adapter->hw_status == WlanHardwareStatusReset)
3788 pmpriv->adapter->hw_status =
3789 WlanHardwareStatusInitializing;
3790 cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
3791 cmd_ptr->size = wlan_cpu_to_le16(S_DS_GEN);
3792 break;
3793 case HostCmd_CMD_FUNC_SHUTDOWN:
3794 pmpriv->adapter->hw_status = WlanHardwareStatusReset;
3795 cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
3796 cmd_ptr->size = wlan_cpu_to_le16(S_DS_GEN);
3797 break;
3798 case HostCmd_CMD_SOFT_RESET:
3799 cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
3800 cmd_ptr->size = wlan_cpu_to_le16(S_DS_GEN);
3801 break;
3802 case HostCmd_CMD_11N_ADDBA_REQ:
3803 ret = wlan_cmd_11n_addba_req(pmpriv, cmd_ptr, pdata_buf);
3804 break;
3805 case HostCmd_CMD_11N_DELBA:
3806 ret = wlan_cmd_11n_delba(pmpriv, cmd_ptr, pdata_buf);
3807 break;
3808 case HostCmd_CMD_11N_ADDBA_RSP:
3809 ret = wlan_cmd_11n_addba_rspgen(pmpriv, cmd_ptr, pdata_buf);
3810 break;
3811 case HostCmd_CMD_802_11_KEY_MATERIAL:
3812 ret = wlan_cmd_802_11_key_material(pmpriv, cmd_ptr, cmd_action,
3813 cmd_oid, pdata_buf);
3814 break;
3815 case HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG:
3816 ret = wlan_cmd_gtk_rekey_offload(pmpriv, cmd_ptr, cmd_action,
3817 cmd_oid, pdata_buf);
3818 break;
3819
3820 case HostCmd_CMD_SUPPLICANT_PMK:
3821 ret = wlan_cmd_802_11_supplicant_pmk(pmpriv, cmd_ptr,
3822 cmd_action, pdata_buf);
3823 break;
3824 case HostCmd_CMD_802_11_EAPOL_PKT:
3825 ret = wlan_cmd_eapol_pkt(pmpriv, cmd_ptr, cmd_action,
3826 pdata_buf);
3827 break;
3828 case HostCmd_CMD_SUPPLICANT_PROFILE:
3829 ret = wlan_cmd_802_11_supplicant_profile(pmpriv, cmd_ptr,
3830 cmd_action, pdata_buf);
3831 break;
3832
3833 case HostCmd_CMD_802_11D_DOMAIN_INFO:
3834 ret = wlan_cmd_802_11d_domain_info(pmpriv, cmd_ptr, cmd_action);
3835 break;
3836 case HostCmd_CMD_802_11_TPC_ADAPT_REQ:
3837 case HostCmd_CMD_802_11_TPC_INFO:
3838 case HostCmd_CMD_802_11_CHAN_SW_ANN:
3839 case HostCmd_CMD_CHAN_REPORT_REQUEST:
3840 ret = wlan_11h_cmd_process(pmpriv, cmd_ptr, pdata_buf);
3841 break;
3842 case HostCmd_CMD_RECONFIGURE_TX_BUFF:
3843 ret = wlan_cmd_recfg_tx_buf(pmpriv, cmd_ptr, cmd_action,
3844 pdata_buf);
3845 break;
3846 case HostCmd_CMD_AMSDU_AGGR_CTRL:
3847 ret = wlan_cmd_amsdu_aggr_ctrl(pmpriv, cmd_ptr, cmd_action,
3848 pdata_buf);
3849 break;
3850 case HostCmd_CMD_11N_CFG:
3851 ret = wlan_cmd_11n_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
3852 break;
3853 case HostCmd_CMD_11AC_CFG:
3854 ret = wlan_cmd_11ac_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
3855 break;
3856 #if 0
3857 case HostCmd_CMD_RECONFIGURE_TX_BUFF:
3858 ret = wlan_cmd_recfg_tx_buf(pmpriv, cmd_ptr, cmd_action,
3859 pdata_buf);
3860 break;
3861 #endif
3862 case HostCmd_CMD_TX_BF_CFG:
3863 ret = wlan_cmd_tx_bf_cfg(pmpriv, cmd_ptr, cmd_action,
3864 pdata_buf);
3865 break;
3866 case HostCmd_CMD_WMM_GET_STATUS:
3867 PRINTM(MINFO, "WMM: WMM_GET_STATUS cmd sent\n");
3868 cmd_ptr->command = wlan_cpu_to_le16(HostCmd_CMD_WMM_GET_STATUS);
3869 cmd_ptr->size = wlan_cpu_to_le16(
3870 sizeof(HostCmd_DS_WMM_GET_STATUS) + S_DS_GEN);
3871 ret = MLAN_STATUS_SUCCESS;
3872 break;
3873 case HostCmd_CMD_WMM_ADDTS_REQ:
3874 ret = wlan_cmd_wmm_addts_req(pmpriv, cmd_ptr, pdata_buf);
3875 break;
3876 case HostCmd_CMD_WMM_DELTS_REQ:
3877 ret = wlan_cmd_wmm_delts_req(pmpriv, cmd_ptr, pdata_buf);
3878 break;
3879 case HostCmd_CMD_WMM_QUEUE_CONFIG:
3880 ret = wlan_cmd_wmm_queue_config(pmpriv, cmd_ptr, pdata_buf);
3881 break;
3882 case HostCmd_CMD_WMM_QUEUE_STATS:
3883 ret = wlan_cmd_wmm_queue_stats(pmpriv, cmd_ptr, pdata_buf);
3884 break;
3885 case HostCmd_CMD_WMM_TS_STATUS:
3886 ret = wlan_cmd_wmm_ts_status(pmpriv, cmd_ptr, pdata_buf);
3887 break;
3888 case HostCmd_CMD_WMM_PARAM_CONFIG:
3889 ret = wlan_cmd_wmm_param_config(pmpriv, cmd_ptr, cmd_action,
3890 pdata_buf);
3891 break;
3892 case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS:
3893 ret = wlan_cmd_ibss_coalescing_status(pmpriv, cmd_ptr,
3894 cmd_action, pdata_buf);
3895 break;
3896 case HostCmd_CMD_MGMT_IE_LIST:
3897 ret = wlan_cmd_mgmt_ie_list(pmpriv, cmd_ptr, cmd_action,
3898 pdata_buf);
3899 break;
3900 case HostCmd_CMD_TDLS_CONFIG:
3901 ret = wlan_cmd_tdls_config(pmpriv, cmd_ptr, cmd_action,
3902 pdata_buf);
3903 break;
3904 case HostCmd_CMD_TDLS_OPERATION:
3905 ret = wlan_cmd_tdls_oper(pmpriv, cmd_ptr, cmd_action,
3906 pdata_buf);
3907 break;
3908 case HostCmd_CMD_802_11_SCAN_EXT:
3909 ret = wlan_cmd_802_11_scan_ext(pmpriv, cmd_ptr, pdata_buf);
3910 break;
3911 case HostCmd_CMD_ECL_SYSTEM_CLOCK_CONFIG:
3912 ret = wlan_cmd_sysclock_cfg(pmpriv, cmd_ptr, cmd_action,
3913 pdata_buf);
3914 break;
3915 case HostCmd_CMD_MAC_REG_ACCESS:
3916 case HostCmd_CMD_BBP_REG_ACCESS:
3917 case HostCmd_CMD_RF_REG_ACCESS:
3918 case HostCmd_CMD_CAU_REG_ACCESS:
3919 case HostCmd_CMD_TARGET_ACCESS:
3920 case HostCmd_CMD_802_11_EEPROM_ACCESS:
3921 case HostCmd_CMD_BCA_REG_ACCESS:
3922 case HostCmd_CMD_REG_ACCESS:
3923 ret = wlan_cmd_reg_access(pmpriv, cmd_ptr, cmd_action,
3924 pdata_buf);
3925 break;
3926 case HostCmd_CMD_MEM_ACCESS:
3927 ret = wlan_cmd_mem_access(cmd_ptr, cmd_action, pdata_buf);
3928 break;
3929 case HostCmd_CMD_INACTIVITY_TIMEOUT_EXT:
3930 ret = wlan_cmd_inactivity_timeout(cmd_ptr, cmd_action,
3931 pdata_buf);
3932 break;
3933 case HostCmd_CMD_GET_TSF:
3934 ret = wlan_cmd_get_tsf(pmpriv, cmd_ptr, cmd_action);
3935 break;
3936 #if defined(SDIO)
3937 case HostCmd_CMD_SDIO_GPIO_INT_CONFIG:
3938 ret = wlan_cmd_sdio_gpio_int(pmpriv, cmd_ptr, cmd_action,
3939 pdata_buf);
3940 break;
3941 #endif
3942 case HostCmd_CMD_SET_BSS_MODE:
3943 cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
3944 #ifdef WIFI_DIRECT_SUPPORT
3945 if (pdata_buf) {
3946 cmd_ptr->params.bss_mode.con_type = *(t_u8 *)pdata_buf;
3947 } else
3948 #endif
3949 if (pmpriv->bss_mode == MLAN_BSS_MODE_IBSS)
3950 cmd_ptr->params.bss_mode.con_type =
3951 CONNECTION_TYPE_ADHOC;
3952 else if (pmpriv->bss_mode == MLAN_BSS_MODE_INFRA)
3953 cmd_ptr->params.bss_mode.con_type =
3954 CONNECTION_TYPE_INFRA;
3955 cmd_ptr->size = wlan_cpu_to_le16(
3956 sizeof(HostCmd_DS_SET_BSS_MODE) + S_DS_GEN);
3957 ret = MLAN_STATUS_SUCCESS;
3958 break;
3959 case HostCmd_CMD_802_11_NET_MONITOR:
3960 ret = wlan_cmd_net_monitor(pmpriv, cmd_ptr, cmd_action,
3961 pdata_buf);
3962 break;
3963 case HostCmd_CMD_MEASUREMENT_REQUEST:
3964 case HostCmd_CMD_MEASUREMENT_REPORT:
3965 ret = wlan_meas_cmd_process(pmpriv, cmd_ptr, pdata_buf);
3966 break;
3967 #if defined(PCIE)
3968 #if defined(PCIE8997) || defined(PCIE8897)
3969 case HostCmd_CMD_PCIE_HOST_BUF_DETAILS:
3970 ret = wlan_cmd_pcie_host_buf_cfg(pmpriv, cmd_ptr, cmd_action,
3971 pdata_buf);
3972 break;
3973 #endif
3974 #endif
3975 case HostCmd_CMD_802_11_REMAIN_ON_CHANNEL:
3976 ret = wlan_cmd_remain_on_channel(pmpriv, cmd_ptr, cmd_action,
3977 pdata_buf);
3978 break;
3979 #ifdef WIFI_DIRECT_SUPPORT
3980 case HOST_CMD_WIFI_DIRECT_MODE_CONFIG:
3981 ret = wlan_cmd_wifi_direct_mode(pmpriv, cmd_ptr, cmd_action,
3982 pdata_buf);
3983 break;
3984 #endif
3985 case HostCmd_CMD_802_11_SUBSCRIBE_EVENT:
3986 ret = wlan_cmd_subscribe_event(pmpriv, cmd_ptr, cmd_action,
3987 pdata_buf);
3988 break;
3989 case HostCmd_CMD_OTP_READ_USER_DATA:
3990 ret = wlan_cmd_otp_user_data(pmpriv, cmd_ptr, cmd_action,
3991 pdata_buf);
3992 break;
3993 case HostCmd_CMD_FW_AUTO_RECONNECT:
3994 ret = wlan_cmd_fw_auto_reconnect(pmpriv, cmd_ptr, cmd_action,
3995 pdata_buf);
3996 break;
3997 case HostCmd_CMD_HS_WAKEUP_REASON:
3998 ret = wlan_cmd_hs_wakeup_reason(pmpriv, cmd_ptr, pdata_buf);
3999 break;
4000 case HostCmd_CMD_REJECT_ADDBA_REQ:
4001 ret = wlan_cmd_reject_addba_req(pmpriv, cmd_ptr, cmd_action,
4002 pdata_buf);
4003 break;
4004 case HostCmd_CMD_PACKET_AGGR_CTRL:
4005 ret = wlan_cmd_packet_aggr_ctrl(pmpriv, cmd_ptr, cmd_action,
4006 pdata_buf);
4007 break;
4008 #ifdef USB
4009 case HostCmd_CMD_PACKET_AGGR_OVER_HOST_INTERFACE:
4010 ret = wlan_cmd_packet_aggr_over_host_interface(
4011 pmpriv, cmd_ptr, cmd_action, pdata_buf);
4012 break;
4013 #endif
4014 #ifdef RX_PACKET_COALESCE
4015 case HostCmd_CMD_RX_PKT_COALESCE_CFG:
4016 ret = wlan_cmd_rx_pkt_coalesce_cfg(pmpriv, cmd_ptr, cmd_action,
4017 pdata_buf);
4018 break;
4019 #endif
4020 case HostCMD_CONFIG_LOW_POWER_MODE:
4021 ret = wlan_cmd_low_pwr_mode(pmpriv, cmd_ptr, pdata_buf);
4022 break;
4023 case HostCmd_DFS_REPEATER_MODE:
4024 ret = wlan_cmd_dfs_repeater_cfg(pmpriv, cmd_ptr, cmd_action,
4025 pdata_buf);
4026 break;
4027 case HostCmd_CMD_COALESCE_CFG:
4028 ret = wlan_cmd_coalesce_config(pmpriv, cmd_ptr, cmd_action,
4029 pdata_buf);
4030 break;
4031 case HostCmd_DS_GET_SENSOR_TEMP:
4032 ret = wlan_cmd_get_sensor_temp(pmpriv, cmd_ptr, cmd_action);
4033 break;
4034 case HostCmd_CMD_802_11_MIMO_SWITCH:
4035 ret = wlan_cmd_802_11_mimo_switch(pmpriv, cmd_ptr, pdata_buf);
4036 break;
4037 case HostCmd_CMD_IPV6_RA_OFFLOAD_CFG:
4038 ret = wlan_cmd_ipv6_ra_offload(pmpriv, cmd_ptr, cmd_action,
4039 pdata_buf);
4040 break;
4041 case HostCmd_CMD_STA_CONFIGURE:
4042 ret = wlan_cmd_sta_config(pmpriv, cmd_ptr, cmd_action,
4043 pioctl_buf, pdata_buf);
4044 break;
4045
4046 case HostCmd_CMD_INDEPENDENT_RESET_CFG:
4047 ret = wlan_cmd_ind_rst_cfg(cmd_ptr, cmd_action, pdata_buf);
4048 break;
4049
4050 case HostCmd_CMD_ROAM_OFFLOAD:
4051 ret = wlan_cmd_roam_offload(pmpriv, cmd_ptr, cmd_action,
4052 pdata_buf);
4053 break;
4054
4055 case HostCmd_CMD_802_11_PS_INACTIVITY_TIMEOUT:
4056 ret = wlan_cmd_ps_inactivity_timeout(pmpriv, cmd_ptr,
4057 cmd_action, pdata_buf);
4058 break;
4059 case HostCmd_CMD_CHAN_REGION_CFG:
4060 cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
4061 cmd_ptr->size = wlan_cpu_to_le16(
4062 sizeof(HostCmd_DS_CHAN_REGION_CFG) + S_DS_GEN);
4063 cmd_ptr->params.reg_cfg.action = wlan_cpu_to_le16(cmd_action);
4064 break;
4065 case HostCmd_CMD_AUTO_TX:
4066 ret = wlan_cmd_auto_tx(pmpriv, cmd_ptr, cmd_action, cmd_oid,
4067 pdata_buf);
4068 break;
4069 case HOST_CMD_TX_RX_PKT_STATS:
4070 ret = wlan_cmd_tx_rx_pkt_stats(pmpriv, cmd_ptr,
4071 (pmlan_ioctl_req)pioctl_buf,
4072 pdata_buf);
4073 break;
4074 case HostCmd_CMD_DYN_BW:
4075 ret = wlan_cmd_config_dyn_bw(pmpriv, cmd_ptr, cmd_action,
4076 pdata_buf);
4077 break;
4078 case HostCmd_CMD_BOOT_SLEEP:
4079 ret = wlan_cmd_boot_sleep(pmpriv, cmd_ptr, cmd_action,
4080 pdata_buf);
4081 break;
4082 case HostCmd_CMD_FW_DUMP_EVENT:
4083 ret = wlan_cmd_fw_dump_event(pmpriv, cmd_ptr, cmd_action,
4084 pdata_buf);
4085 break;
4086 #if defined(DRV_EMBEDDED_SUPPLICANT)
4087 case HostCmd_CMD_CRYPTO:
4088 ret = wlan_cmd_crypto(pmpriv, cmd_ptr, cmd_action, pdata_buf);
4089 break;
4090 #endif
4091 case HostCmd_CMD_11AX_CFG:
4092 ret = wlan_cmd_11ax_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
4093 break;
4094 case HostCmd_CMD_11AX_CMD:
4095 ret = wlan_cmd_11ax_cmd(pmpriv, cmd_ptr, cmd_action, pdata_buf);
4096 break;
4097 case HostCmd_CMD_RANGE_EXT:
4098 ret = wlan_cmd_range_ext(pmpriv, cmd_ptr, cmd_action,
4099 pdata_buf);
4100 break;
4101 case HostCmd_CMD_TWT_CFG:
4102 ret = wlan_cmd_twt_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
4103 break;
4104 case HOST_CMD_GPIO_TSF_LATCH_PARAM_CONFIG:
4105 ret = wlan_cmd_gpio_tsf_latch(pmpriv, cmd_ptr, cmd_action,
4106 pioctl_buf, pdata_buf);
4107 break;
4108 case HostCmd_CMD_RX_ABORT_CFG:
4109 ret = wlan_cmd_rxabortcfg(pmpriv, cmd_ptr, cmd_action,
4110 pdata_buf);
4111 break;
4112 case HostCmd_CMD_RX_ABORT_CFG_EXT:
4113 ret = wlan_cmd_rxabortcfg_ext(pmpriv, cmd_ptr, cmd_action,
4114 pdata_buf);
4115 break;
4116 case HostCmd_CMD_ARB_CONFIG:
4117 ret = wlan_cmd_arb_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
4118 break;
4119 case HostCmd_CMD_TX_AMPDU_PROT_MODE:
4120 ret = wlan_cmd_tx_ampdu_prot_mode(pmpriv, cmd_ptr, cmd_action,
4121 pdata_buf);
4122 break;
4123 case HostCmd_CMD_DOT11MC_UNASSOC_FTM_CFG:
4124 ret = wlan_cmd_dot11mc_unassoc_ftm_cfg(pmpriv, cmd_ptr,
4125 cmd_action, pdata_buf);
4126 break;
4127 case HostCmd_CMD_RATE_ADAPT_CFG:
4128 ret = wlan_cmd_rate_adapt_cfg(pmpriv, cmd_ptr, cmd_action,
4129 pdata_buf);
4130 break;
4131 case HostCmd_CMD_CCK_DESENSE_CFG:
4132 ret = wlan_cmd_cck_desense_cfg(pmpriv, cmd_ptr, cmd_action,
4133 pdata_buf);
4134 break;
4135 case HostCmd_CHANNEL_TRPC_CONFIG:
4136 ret = wlan_cmd_get_chan_trpc_config(pmpriv, cmd_ptr, cmd_action,
4137 pdata_buf);
4138 break;
4139 case HostCmd_CMD_LOW_POWER_MODE_CFG:
4140 ret = wlan_cmd_set_get_low_power_mode_cfg(
4141 pmpriv, cmd_ptr, cmd_action, pdata_buf);
4142 break;
4143 case HostCmd_CMD_MFG_COMMAND:
4144 ret = wlan_cmd_mfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
4145 break;
4146 case HostCmd_CMD_MC_AGGR_CFG:
4147 ret = wlan_cmd_mc_aggr_cfg(pmpriv, cmd_ptr, cmd_action,
4148 pdata_buf);
4149 break;
4150 case HostCmd_CMD_GET_CH_LOAD:
4151 ret = wlan_cmd_get_ch_load(pmpriv, cmd_ptr, cmd_action,
4152 pdata_buf);
4153 break;
4154 default:
4155 PRINTM(MERROR, "PREP_CMD: unknown command- %#x\n", cmd_no);
4156 ret = MLAN_STATUS_FAILURE;
4157 break;
4158 }
4159
4160 LEAVE();
4161 return ret;
4162 }
4163
4164 /**
4165 * @brief This function issues commands to initialize firmware
4166 *
4167 * @param priv A pointer to mlan_private structure
4168 * @param first_bss flag for first BSS
4169 *
4170 * @return MLAN_STATUS_PENDING or MLAN_STATUS_FAILURE
4171 */
wlan_ops_sta_init_cmd(t_void * priv,t_u8 first_bss)4172 mlan_status wlan_ops_sta_init_cmd(t_void *priv, t_u8 first_bss)
4173 {
4174 pmlan_private pmpriv = (pmlan_private)priv;
4175 mlan_status ret = MLAN_STATUS_SUCCESS;
4176 mlan_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl;
4177
4178 ENTER();
4179
4180 if (!pmpriv) {
4181 LEAVE();
4182 return MLAN_STATUS_FAILURE;
4183 }
4184
4185 if (first_bss == MTRUE) {
4186 ret = wlan_adapter_init_cmd(pmpriv->adapter);
4187 if (ret == MLAN_STATUS_FAILURE)
4188 goto done;
4189 }
4190
4191 /* get tx rate */
4192 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG,
4193 HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
4194 if (ret) {
4195 ret = MLAN_STATUS_FAILURE;
4196 goto done;
4197 }
4198 pmpriv->data_rate = 0;
4199
4200 /* get tx power */
4201 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_RF_TX_POWER,
4202 HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
4203 if (ret) {
4204 ret = MLAN_STATUS_FAILURE;
4205 goto done;
4206 }
4207
4208 memset(pmpriv->adapter, &amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl));
4209 amsdu_aggr_ctrl.enable = MLAN_ACT_ENABLE;
4210 /* Send request to firmware */
4211 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_AMSDU_AGGR_CTRL,
4212 HostCmd_ACT_GEN_SET, 0, MNULL,
4213 (t_void *)&amsdu_aggr_ctrl);
4214 if (ret) {
4215 ret = MLAN_STATUS_FAILURE;
4216 goto done;
4217 }
4218 /* MAC Control must be the last command in init_fw */
4219 /* set MAC Control */
4220 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MAC_CONTROL,
4221 HostCmd_ACT_GEN_SET, 0, MNULL,
4222 &pmpriv->curr_pkt_filter);
4223 if (ret) {
4224 ret = MLAN_STATUS_FAILURE;
4225 goto done;
4226 }
4227 /** set last_init_cmd */
4228 pmpriv->adapter->last_init_cmd = HostCmd_CMD_MAC_CONTROL;
4229
4230 if (first_bss == MFALSE) {
4231 /* Get MAC address */
4232 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_MAC_ADDRESS,
4233 HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
4234 if (ret) {
4235 ret = MLAN_STATUS_FAILURE;
4236 goto done;
4237 }
4238 pmpriv->adapter->last_init_cmd = HostCmd_CMD_802_11_MAC_ADDRESS;
4239 }
4240
4241 ret = MLAN_STATUS_PENDING;
4242 done:
4243 LEAVE();
4244 return ret;
4245 }
4246