xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/nxp/mlan/mlan_sta_cmd.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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