xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/nxp/mlan/mlan_uap_cmdevent.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /** @file mlan_uap_cmdevent.c
2  *
3  *  @brief This file contains the handling of AP mode command and event
4  *
5  *
6  *  Copyright 2009-2022 NXP
7  *
8  *  This software file (the File) is distributed by NXP
9  *  under the terms of the GNU General Public License Version 2, June 1991
10  *  (the License).  You may use, redistribute and/or modify the File in
11  *  accordance with the terms and conditions of the License, a copy of which
12  *  is available by writing to the Free Software Foundation, Inc.,
13  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
14  *  worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
15  *
16  *  THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
17  *  IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
18  *  ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
19  *  this warranty disclaimer.
20  *
21  */
22 
23 /********************************************************
24 Change log:
25     02/05/2009: initial version
26 ********************************************************/
27 
28 #include "mlan.h"
29 #include "mlan_util.h"
30 #include "mlan_fw.h"
31 #ifdef STA_SUPPORT
32 #include "mlan_join.h"
33 #endif
34 #include "mlan_main.h"
35 #include "mlan_uap.h"
36 #ifdef SDIO
37 #include "mlan_sdio.h"
38 #endif /* SDIO */
39 #include "mlan_11n.h"
40 #include "mlan_11h.h"
41 #include "mlan_11ac.h"
42 #include "mlan_11ax.h"
43 #ifdef DRV_EMBEDDED_AUTHENTICATOR
44 #include "authenticator_api.h"
45 #endif
46 #ifdef PCIE
47 #include "mlan_pcie.h"
48 #endif /* PCIE */
49 /********************************************************
50 			Local Functions
51 ********************************************************/
52 
53 /**
54  *  @brief This function prepares command of BAND_STEERING_CFG
55  *
56  *  @param pmpriv       A pointer to mlan_private structure
57  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
58  *  @param cmd_action
59  *  @param pdata_buf    A pointer to data buffer
60  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
61  */
wlan_cmd_set_get_band_steering_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)62 static mlan_status wlan_cmd_set_get_band_steering_cfg(pmlan_private pmpriv,
63 						      HostCmd_DS_COMMAND *cmd,
64 						      t_u16 cmd_action,
65 						      t_void *pdata_buf)
66 {
67 	mlan_ds_band_steer_cfg *pband_steer_cfg =
68 		(mlan_ds_band_steer_cfg *)pdata_buf;
69 	ENTER();
70 
71 	cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_BAND_STEERING);
72 	cmd->size =
73 		wlan_cpu_to_le16(sizeof(HostCmd_DS_BAND_STEERING) + S_DS_GEN);
74 	cmd->params.band_steer_info.state = pband_steer_cfg->state;
75 	cmd->params.band_steer_info.block_2g_prb_req =
76 		pband_steer_cfg->block_2g_prb_req;
77 	cmd->params.band_steer_info.max_btm_req_allowed =
78 		pband_steer_cfg->max_btm_req_allowed;
79 	cmd->params.band_steer_info.action = cmd_action;
80 
81 	LEAVE();
82 	return MLAN_STATUS_SUCCESS;
83 }
84 
85 /**
86  *  @brief This function handle response of HostCmd_CMD_802_11_BAND_STEERING
87  *
88  *  @param pmpriv       A pointer to mlan_private structure
89  *  @param resp         Pointer to command response buffer
90  *
91  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
92  */
93 static mlan_status
wlan_ret_set_get_band_steering_cfg(mlan_private * pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)94 wlan_ret_set_get_band_steering_cfg(mlan_private *pmpriv,
95 				   HostCmd_DS_COMMAND *resp,
96 				   mlan_ioctl_req *pioctl_buf)
97 {
98 	mlan_status ret = MLAN_STATUS_SUCCESS;
99 	HostCmd_DS_BAND_STEERING *pband_steer_info =
100 		&resp->params.band_steer_info;
101 	mlan_ds_misc_cfg *pband_steer;
102 
103 	ENTER();
104 
105 	pband_steer = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
106 
107 	pband_steer->param.band_steer_cfg.action = pband_steer_info->action;
108 	pband_steer->param.band_steer_cfg.state = pband_steer_info->state;
109 	pband_steer->param.band_steer_cfg.block_2g_prb_req =
110 		pband_steer_info->block_2g_prb_req;
111 	pband_steer->param.band_steer_cfg.max_btm_req_allowed =
112 		pband_steer_info->max_btm_req_allowed;
113 
114 	LEAVE();
115 	return ret;
116 }
117 
118 /**
119  *  @brief This function prepares command of BEACON_STUCK_CFG
120  *
121  *  @param pmpriv       A pointer to mlan_private structure
122  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
123  *  @param cmd_action
124  *  @param pdata_buf    A pointer to data buffer
125  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
126  */
wlan_cmd_set_get_beacon_stuck_cfg(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_u16 cmd_action,IN t_void * pdata_buf)127 static mlan_status wlan_cmd_set_get_beacon_stuck_cfg(IN pmlan_private pmpriv,
128 						     IN HostCmd_DS_COMMAND *cmd,
129 						     IN t_u16 cmd_action,
130 						     IN t_void *pdata_buf)
131 {
132 	HostCmd_DS_BEACON_STUCK_CFG *pbeacon_stuck_param_cfg =
133 		(HostCmd_DS_BEACON_STUCK_CFG *)(pdata_buf + sizeof(t_u32));
134 
135 	ENTER();
136 
137 	cmd->command = wlan_cpu_to_le16(HostCmd_CMD_UAP_BEACON_STUCK_CFG);
138 	cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_BEACON_STUCK_CFG) +
139 				     S_DS_GEN);
140 	cmd->params.beacon_stuck_cfg.beacon_stuck_detect_count =
141 		pbeacon_stuck_param_cfg->beacon_stuck_detect_count;
142 	cmd->params.beacon_stuck_cfg.recovery_confirm_count =
143 		pbeacon_stuck_param_cfg->recovery_confirm_count;
144 	cmd->params.beacon_stuck_cfg.action = cmd_action;
145 
146 	LEAVE();
147 	return MLAN_STATUS_SUCCESS;
148 }
149 
150 /**
151  *  @brief This function handle response of HostCmd_CMD_UAP_BEACON_STUCK_CFG
152  *
153  *  @param pmpriv       A pointer to mlan_private structure
154  *  @param resp         Pointer to command response buffer
155  *
156  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
157  */
wlan_ret_set_get_beacon_stuck_cfg(mlan_private * pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)158 static mlan_status wlan_ret_set_get_beacon_stuck_cfg(mlan_private *pmpriv,
159 						     HostCmd_DS_COMMAND *resp,
160 						     mlan_ioctl_req *pioctl_buf)
161 {
162 	mlan_status ret = MLAN_STATUS_SUCCESS;
163 	HostCmd_DS_BEACON_STUCK_CFG *pbeacon_stuck_param_cfg =
164 		&resp->params.beacon_stuck_cfg;
165 	mlan_ds_misc_cfg *pbeacon_stuck;
166 
167 	ENTER();
168 
169 	pbeacon_stuck = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
170 
171 	pbeacon_stuck->param.beacon_stuck_cfg.action =
172 		pbeacon_stuck_param_cfg->action;
173 	pbeacon_stuck->param.beacon_stuck_cfg.beacon_stuck_detect_count =
174 		pbeacon_stuck_param_cfg->beacon_stuck_detect_count;
175 	pbeacon_stuck->param.beacon_stuck_cfg.recovery_confirm_count =
176 		pbeacon_stuck_param_cfg->recovery_confirm_count;
177 
178 	LEAVE();
179 	return ret;
180 }
181 
182 /**
183  *  @brief This function handles the command response error
184  *
185  *  @param pmpriv       A pointer to mlan_private structure
186  *  @param resp         A pointer to HostCmd_DS_COMMAND
187  *  @param pioctl_buf   A pointer to command buffer
188  *
189  *  @return             N/A
190  */
uap_process_cmdresp_error(mlan_private * pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)191 static mlan_status uap_process_cmdresp_error(mlan_private *pmpriv,
192 					     HostCmd_DS_COMMAND *resp,
193 					     mlan_ioctl_req *pioctl_buf)
194 {
195 	mlan_adapter *pmadapter = pmpriv->adapter;
196 #if defined(USB)
197 	t_u8 i;
198 #endif
199 	mlan_status ret = MLAN_STATUS_FAILURE;
200 
201 	ENTER();
202 	if (resp->command != HostCmd_CMD_WMM_PARAM_CONFIG &&
203 	    resp->command != HostCmd_CMD_CHAN_REGION_CFG)
204 		PRINTM(MERROR, "CMD_RESP: cmd %#x error, result=%#x\n",
205 		       resp->command, resp->result);
206 	if (pioctl_buf)
207 		pioctl_buf->status_code = resp->result;
208 	/*
209 	 * Handling errors here
210 	 */
211 	switch (resp->command) {
212 #ifdef SDIO
213 	case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG:
214 		pmadapter->pcard_sd->sdio_rx_aggr_enable = MFALSE;
215 		PRINTM(MMSG, "FW don't support SDIO single port rx aggr\n");
216 		break;
217 #endif
218 
219 	case HOST_CMD_APCMD_SYS_CONFIGURE: {
220 		HostCmd_DS_SYS_CONFIG *sys_config =
221 			(HostCmd_DS_SYS_CONFIG *)&resp->params.sys_config;
222 		t_u16 resp_len = 0, travel_len = 0, index;
223 		mlan_ds_misc_custom_ie *cust_ie = MNULL;
224 		mlan_ds_misc_cfg *misc = MNULL;
225 		custom_ie *cptr;
226 
227 		if (!pioctl_buf || (pioctl_buf->req_id != MLAN_IOCTL_MISC_CFG))
228 			break;
229 		misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
230 		if ((pioctl_buf->action == MLAN_ACT_SET) &&
231 		    (misc->sub_command == MLAN_OID_MISC_CUSTOM_IE)) {
232 			cust_ie = (mlan_ds_misc_custom_ie *)
233 					  sys_config->tlv_buffer;
234 			if (cust_ie) {
235 				cust_ie->type = wlan_le16_to_cpu(cust_ie->type);
236 				resp_len = cust_ie->len =
237 					wlan_le16_to_cpu(cust_ie->len);
238 				travel_len = 0;
239 				/* conversion for index, mask, len */
240 				if (resp_len == sizeof(t_u16))
241 					cust_ie->ie_data_list[0].ie_index =
242 						wlan_cpu_to_le16(
243 							cust_ie->ie_data_list[0]
244 								.ie_index);
245 
246 				while (resp_len > sizeof(t_u16)) {
247 					cptr = (custom_ie
248 							*)(((t_u8 *)cust_ie
249 								    ->ie_data_list) +
250 							   travel_len);
251 					index = cptr->ie_index =
252 						wlan_le16_to_cpu(
253 							cptr->ie_index);
254 					cptr->mgmt_subtype_mask =
255 						wlan_le16_to_cpu(
256 							cptr->mgmt_subtype_mask);
257 					cptr->ie_length = wlan_le16_to_cpu(
258 						cptr->ie_length);
259 					travel_len += cptr->ie_length +
260 						      sizeof(custom_ie) -
261 						      MAX_IE_SIZE;
262 					resp_len -= cptr->ie_length +
263 						    sizeof(custom_ie) -
264 						    MAX_IE_SIZE;
265 					if ((pmpriv->mgmt_ie[index]
266 						     .mgmt_subtype_mask ==
267 					     cptr->mgmt_subtype_mask) &&
268 					    (pmpriv->mgmt_ie[index].ie_length ==
269 					     cptr->ie_length) &&
270 					    !memcmp(pmpriv->adapter,
271 						    pmpriv->mgmt_ie[index]
272 							    .ie_buffer,
273 						    cptr->ie_buffer,
274 						    cptr->ie_length)) {
275 						PRINTM(MERROR,
276 						       "set custom ie fail, remove ie index :%d\n",
277 						       index);
278 						memset(pmadapter,
279 						       &pmpriv->mgmt_ie[index],
280 						       0, sizeof(custom_ie));
281 					}
282 				}
283 			}
284 		}
285 	} break;
286 	case HostCmd_CMD_PACKET_AGGR_CTRL:
287 #ifdef USB
288 		if (IS_USB(pmadapter->card_type)) {
289 			for (i = 0; i < MAX_USB_TX_PORT_NUM; i++)
290 				pmadapter->pcard_usb->usb_tx_aggr[i]
291 					.aggr_ctrl.enable = MFALSE;
292 			pmadapter->pcard_usb->usb_rx_deaggr.aggr_ctrl.enable =
293 				MFALSE;
294 		}
295 #endif
296 		break;
297 	case HostCmd_CMD_CHAN_REGION_CFG:
298 		ret = MLAN_STATUS_SUCCESS;
299 		PRINTM(MCMND, "FW don't support chan region cfg command!\n");
300 		break;
301 #if defined(DRV_EMBEDDED_AUTHENTICATOR)
302 	case HostCmd_CMD_CRYPTO:
303 		PRINTM(MCMND, "crypto cmd result=0x%x!\n", resp->result);
304 		ret = wlan_ret_crypto(pmpriv, resp, pioctl_buf);
305 		break;
306 #endif
307 	default:
308 		break;
309 	}
310 
311 	wlan_request_cmd_lock(pmadapter);
312 	wlan_insert_cmd_to_free_q(pmadapter, pmadapter->curr_cmd);
313 	pmadapter->curr_cmd = MNULL;
314 	wlan_release_cmd_lock(pmadapter);
315 
316 	LEAVE();
317 	return ret;
318 }
319 
320 /**
321  *  @brief This function will return the pointer to station entry in station
322  * list table which matches the give mac address
323  *
324  *  @param priv    A pointer to mlan_private
325  *
326  *  @return	   A pointer to structure sta_node
327  */
wlan_notify_station_deauth(mlan_private * priv)328 static void wlan_notify_station_deauth(mlan_private *priv)
329 {
330 	sta_node *sta_ptr;
331 	t_u8 event_buf[100];
332 	mlan_event *pevent = (mlan_event *)event_buf;
333 	t_u8 *pbuf;
334 
335 	ENTER();
336 	sta_ptr = (sta_node *)util_peek_list(
337 		priv->adapter->pmoal_handle, &priv->sta_list,
338 		priv->adapter->callbacks.moal_spin_lock,
339 		priv->adapter->callbacks.moal_spin_unlock);
340 	if (!sta_ptr) {
341 		LEAVE();
342 		return;
343 	}
344 	while (sta_ptr != (sta_node *)&priv->sta_list) {
345 		memset(priv->adapter, event_buf, 0, sizeof(event_buf));
346 		pevent->bss_index = priv->bss_index;
347 		pevent->event_id = MLAN_EVENT_ID_UAP_FW_STA_DISCONNECT;
348 		pevent->event_len = MLAN_MAC_ADDR_LENGTH + 2;
349 		pbuf = (t_u8 *)pevent->event_buf;
350 		/* reason field set to 0, Unspecified */
351 		memcpy_ext(priv->adapter, pbuf + 2, sta_ptr->mac_addr,
352 			   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
353 		wlan_recv_event(priv, pevent->event_id, pevent);
354 		sta_ptr = sta_ptr->pnext;
355 	}
356 	LEAVE();
357 	return;
358 }
359 
360 /**
361  * @brief This function prepares command of hs_cfg.
362  *
363  * @param pmpriv       A pointer to mlan_private structure
364  * @param cmd          A pointer to HostCmd_DS_COMMAND structure
365  * @param cmd_action   The action: GET or SET
366  * @param pdata_buf    A pointer to data buffer
367  *
368  * @return             MLAN_STATUS_SUCCESS
369  */
wlan_uap_cmd_802_11_hs_cfg(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,hs_config_param * pdata_buf)370 static mlan_status wlan_uap_cmd_802_11_hs_cfg(pmlan_private pmpriv,
371 					      HostCmd_DS_COMMAND *cmd,
372 					      t_u16 cmd_action,
373 					      hs_config_param *pdata_buf)
374 {
375 	pmlan_adapter pmadapter = pmpriv->adapter;
376 	HostCmd_DS_802_11_HS_CFG_ENH *phs_cfg =
377 		(HostCmd_DS_802_11_HS_CFG_ENH *)&(cmd->params.opt_hs_cfg);
378 	t_u8 *tlv = (t_u8 *)phs_cfg + sizeof(HostCmd_DS_802_11_HS_CFG_ENH);
379 	MrvlIEtypes_HsWakeHoldoff_t *holdoff_tlv = MNULL;
380 	MrvlIEtypes_HS_Antmode_t *antmode_tlv = MNULL;
381 	MrvlIEtypes_WakeupSourceGPIO_t *gpio_tlv = MNULL;
382 	MrvlIEtypes_MgmtFrameFilter_t *mgmt_filter_tlv = MNULL;
383 	MrvlIEtypes_WakeupExtend_t *ext_tlv = MNULL;
384 
385 	ENTER();
386 	cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH);
387 	cmd->size = wlan_cpu_to_le16(S_DS_GEN +
388 				     sizeof(HostCmd_DS_802_11_HS_CFG_ENH));
389 
390 	if (pdata_buf == MNULL) {
391 		phs_cfg->action = wlan_cpu_to_le16(HS_ACTIVATE);
392 		phs_cfg->params.hs_activate.resp_ctrl =
393 			wlan_cpu_to_le16(RESP_NEEDED);
394 	} else {
395 		phs_cfg->action = wlan_cpu_to_le16(HS_CONFIGURE);
396 		phs_cfg->params.hs_config.conditions =
397 			wlan_cpu_to_le32(pdata_buf->conditions);
398 		phs_cfg->params.hs_config.gpio = pdata_buf->gpio;
399 		phs_cfg->params.hs_config.gap = pdata_buf->gap;
400 		if (pmpriv->adapter->min_wake_holdoff) {
401 			cmd->size = wlan_cpu_to_le16(
402 				S_DS_GEN +
403 				sizeof(HostCmd_DS_802_11_HS_CFG_ENH) +
404 				sizeof(MrvlIEtypes_HsWakeHoldoff_t));
405 			holdoff_tlv = (MrvlIEtypes_HsWakeHoldoff_t *)tlv;
406 			holdoff_tlv->header.type =
407 				wlan_cpu_to_le16(TLV_TYPE_HS_WAKE_HOLDOFF);
408 			holdoff_tlv->header.len = wlan_cpu_to_le16(
409 				sizeof(MrvlIEtypes_HsWakeHoldoff_t) -
410 				sizeof(MrvlIEtypesHeader_t));
411 			holdoff_tlv->min_wake_holdoff = wlan_cpu_to_le16(
412 				pmpriv->adapter->min_wake_holdoff);
413 			tlv += sizeof(MrvlIEtypes_HsWakeHoldoff_t);
414 		}
415 		PRINTM(MCMND,
416 		       "HS_CFG_CMD: condition:0x%x gpio:0x%x gap:0x%x holdoff=%d\n",
417 		       phs_cfg->params.hs_config.conditions,
418 		       phs_cfg->params.hs_config.gpio,
419 		       phs_cfg->params.hs_config.gap,
420 		       pmpriv->adapter->min_wake_holdoff);
421 
422 		if (pmadapter->param_type_ind == 1) {
423 			cmd->size += sizeof(MrvlIEtypes_WakeupSourceGPIO_t);
424 			gpio_tlv = (MrvlIEtypes_WakeupSourceGPIO_t *)tlv;
425 			gpio_tlv->header.type = wlan_cpu_to_le16(
426 				TLV_TYPE_HS_WAKEUP_SOURCE_GPIO);
427 			gpio_tlv->header.len = wlan_cpu_to_le16(
428 				sizeof(MrvlIEtypes_WakeupSourceGPIO_t) -
429 				sizeof(MrvlIEtypesHeader_t));
430 			gpio_tlv->ind_gpio = (t_u8)pmadapter->ind_gpio;
431 			gpio_tlv->level = (t_u8)pmadapter->level;
432 			tlv += sizeof(MrvlIEtypes_WakeupSourceGPIO_t);
433 		}
434 		if (pmadapter->param_type_ext == 2) {
435 			cmd->size += sizeof(MrvlIEtypes_WakeupExtend_t);
436 			ext_tlv = (MrvlIEtypes_WakeupExtend_t *)tlv;
437 			ext_tlv->header.type =
438 				wlan_cpu_to_le16(TLV_TYPE_WAKEUP_EXTEND);
439 			ext_tlv->header.len = wlan_cpu_to_le16(
440 				sizeof(MrvlIEtypes_WakeupExtend_t) -
441 				sizeof(MrvlIEtypesHeader_t));
442 			ext_tlv->event_force_ignore =
443 				wlan_cpu_to_le32(pmadapter->event_force_ignore);
444 			ext_tlv->event_use_ext_gap =
445 				wlan_cpu_to_le32(pmadapter->event_use_ext_gap);
446 			ext_tlv->ext_gap = pmadapter->ext_gap;
447 			ext_tlv->gpio_wave = pmadapter->gpio_wave;
448 			tlv += sizeof(MrvlIEtypes_WakeupExtend_t);
449 		}
450 		if (pmadapter->mgmt_filter[0].type) {
451 			int i = 0;
452 			mgmt_frame_filter mgmt_filter[MAX_MGMT_FRAME_FILTER];
453 			memset(pmadapter, mgmt_filter, 0,
454 			       MAX_MGMT_FRAME_FILTER *
455 				       sizeof(mgmt_frame_filter));
456 			mgmt_filter_tlv = (MrvlIEtypes_MgmtFrameFilter_t *)tlv;
457 			mgmt_filter_tlv->header.type =
458 				wlan_cpu_to_le16(TLV_TYPE_MGMT_FRAME_WAKEUP);
459 			tlv += sizeof(MrvlIEtypesHeader_t);
460 			while (i < MAX_MGMT_FRAME_FILTER &&
461 			       pmadapter->mgmt_filter[i].type) {
462 				mgmt_filter[i].action =
463 					(t_u8)pmadapter->mgmt_filter[i].action;
464 				mgmt_filter[i].type =
465 					(t_u8)pmadapter->mgmt_filter[i].type;
466 				mgmt_filter[i].frame_mask = wlan_cpu_to_le32(
467 					pmadapter->mgmt_filter[i].frame_mask);
468 				i++;
469 			}
470 			memcpy_ext(pmadapter, (t_u8 *)mgmt_filter_tlv->filter,
471 				   (t_u8 *)mgmt_filter,
472 				   i * sizeof(mgmt_frame_filter),
473 				   sizeof(mgmt_filter_tlv->filter));
474 			tlv += i * sizeof(mgmt_frame_filter);
475 			mgmt_filter_tlv->header.len =
476 				wlan_cpu_to_le16(i * sizeof(mgmt_frame_filter));
477 			cmd->size += i * sizeof(mgmt_frame_filter) +
478 				     sizeof(MrvlIEtypesHeader_t);
479 		}
480 		if (pmadapter->hs_mimo_switch) {
481 			cmd->size += sizeof(MrvlIEtypes_HS_Antmode_t);
482 			antmode_tlv = (MrvlIEtypes_HS_Antmode_t *)tlv;
483 			antmode_tlv->header.type =
484 				wlan_cpu_to_le16(TLV_TYPE_HS_ANTMODE);
485 			antmode_tlv->header.len = wlan_cpu_to_le16(
486 				sizeof(MrvlIEtypes_HS_Antmode_t) -
487 				sizeof(MrvlIEtypesHeader_t));
488 			antmode_tlv->txpath_antmode = ANTMODE_FW_DECISION;
489 			antmode_tlv->rxpath_antmode = ANTMODE_FW_DECISION;
490 			tlv += sizeof(MrvlIEtypes_HS_Antmode_t);
491 			PRINTM(MCMND,
492 			       "hs_mimo_switch=%d, txpath_antmode=%d, rxpath_antmode=%d\n",
493 			       pmadapter->hs_mimo_switch,
494 			       antmode_tlv->txpath_antmode,
495 			       antmode_tlv->rxpath_antmode);
496 		}
497 	}
498 	LEAVE();
499 	return MLAN_STATUS_SUCCESS;
500 }
501 
502 /**
503  *  @brief This function prepares command of Tx data pause
504  *
505  *  @param pmpriv		A pointer to mlan_private structure
506  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
507  *  @param cmd_action   the action: GET or SET
508  *  @param pdata_buf    A pointer to data buffer
509  *  @return         MLAN_STATUS_SUCCESS
510  */
wlan_uap_cmd_txdatapause(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)511 static mlan_status wlan_uap_cmd_txdatapause(pmlan_private pmpriv,
512 					    HostCmd_DS_COMMAND *cmd,
513 					    t_u16 cmd_action, t_void *pdata_buf)
514 {
515 	HostCmd_DS_CMD_TX_DATA_PAUSE *pause_cmd =
516 		(HostCmd_DS_CMD_TX_DATA_PAUSE *)&cmd->params.tx_data_pause;
517 	mlan_ds_misc_tx_datapause *data_pause =
518 		(mlan_ds_misc_tx_datapause *)pdata_buf;
519 
520 	ENTER();
521 
522 	cmd->command = wlan_cpu_to_le16(HostCmd_CMD_CFG_TX_DATA_PAUSE);
523 	cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_CMD_TX_DATA_PAUSE) +
524 				     S_DS_GEN);
525 	pause_cmd->action = wlan_cpu_to_le16(cmd_action);
526 
527 	if (cmd_action == HostCmd_ACT_GEN_SET) {
528 		pause_cmd->enable_tx_pause = (t_u8)data_pause->tx_pause;
529 		pause_cmd->pause_tx_count = (t_u8)data_pause->tx_buf_cnt;
530 	}
531 
532 	LEAVE();
533 	return MLAN_STATUS_SUCCESS;
534 }
535 
536 /**
537  *  @brief This function handles the command response of Tx data pause
538  *
539  *  @param pmpriv       A pointer to mlan_private structure
540  *  @param resp         A pointer to HostCmd_DS_COMMAND
541  *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
542  *
543  *  @return             MLAN_STATUS_SUCCESS
544  */
wlan_uap_ret_txdatapause(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)545 static mlan_status wlan_uap_ret_txdatapause(pmlan_private pmpriv,
546 					    HostCmd_DS_COMMAND *resp,
547 					    mlan_ioctl_req *pioctl_buf)
548 {
549 	HostCmd_DS_CMD_TX_DATA_PAUSE *pause_cmd =
550 		(HostCmd_DS_CMD_TX_DATA_PAUSE *)&resp->params.tx_data_pause;
551 	mlan_ds_misc_cfg *misc_cfg = MNULL;
552 
553 	ENTER();
554 
555 	if (pioctl_buf) {
556 		misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
557 		misc_cfg->param.tx_datapause.tx_pause =
558 			pause_cmd->enable_tx_pause;
559 		misc_cfg->param.tx_datapause.tx_buf_cnt =
560 			pause_cmd->pause_tx_count;
561 	}
562 	LEAVE();
563 	return MLAN_STATUS_SUCCESS;
564 }
565 
566 /**
567  *  @brief This function will process tx pause event
568  *
569  *  @param priv    A pointer to mlan_private
570  *  @param pevent  A pointer to event buf
571  *
572  *  @return	       N/A
573  */
wlan_process_tx_pause_event(pmlan_private priv,pmlan_buffer pevent)574 static void wlan_process_tx_pause_event(pmlan_private priv, pmlan_buffer pevent)
575 {
576 	t_u16 tlv_type, tlv_len;
577 	int tlv_buf_left = pevent->data_len - sizeof(t_u32);
578 	MrvlIEtypesHeader_t *tlv =
579 		(MrvlIEtypesHeader_t *)(pevent->pbuf + pevent->data_offset +
580 					sizeof(t_u32));
581 	MrvlIEtypes_tx_pause_t *tx_pause_tlv;
582 	sta_node *sta_ptr = MNULL;
583 	t_u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
584 	t_u32 total_pkts_queued;
585 	t_u16 tx_pkts_queued = 0;
586 	;
587 
588 	ENTER();
589 
590 	total_pkts_queued =
591 		util_scalar_read(priv->adapter->pmoal_handle,
592 				 &priv->wmm.tx_pkts_queued, MNULL, MNULL);
593 	while (tlv_buf_left >= (int)sizeof(MrvlIEtypesHeader_t)) {
594 		tlv_type = wlan_le16_to_cpu(tlv->type);
595 		tlv_len = wlan_le16_to_cpu(tlv->len);
596 		if ((sizeof(MrvlIEtypesHeader_t) + tlv_len) >
597 		    (unsigned int)tlv_buf_left) {
598 			PRINTM(MERROR, "wrong tlv: tlvLen=%d, tlvBufLeft=%d\n",
599 			       tlv_len, tlv_buf_left);
600 			break;
601 		}
602 		if (tlv_type == TLV_TYPE_TX_PAUSE) {
603 			tx_pause_tlv = (MrvlIEtypes_tx_pause_t *)tlv;
604 
605 			if (!memcmp(priv->adapter, bc_mac,
606 				    tx_pause_tlv->peermac,
607 				    MLAN_MAC_ADDR_LENGTH))
608 				tx_pkts_queued = wlan_update_ralist_tx_pause(
609 					priv, tx_pause_tlv->peermac,
610 					tx_pause_tlv->tx_pause);
611 			else if (!memcmp(priv->adapter, priv->curr_addr,
612 					 tx_pause_tlv->peermac,
613 					 MLAN_MAC_ADDR_LENGTH)) {
614 				if (tx_pause_tlv->tx_pause)
615 					priv->tx_pause = MTRUE;
616 				else
617 					priv->tx_pause = MFALSE;
618 			} else {
619 				sta_ptr = wlan_get_station_entry(
620 					priv, tx_pause_tlv->peermac);
621 				if (sta_ptr) {
622 					if (sta_ptr->tx_pause !=
623 					    tx_pause_tlv->tx_pause) {
624 						sta_ptr->tx_pause =
625 							tx_pause_tlv->tx_pause;
626 						tx_pkts_queued =
627 							wlan_update_ralist_tx_pause(
628 								priv,
629 								tx_pause_tlv
630 									->peermac,
631 								tx_pause_tlv
632 									->tx_pause);
633 					}
634 				}
635 			}
636 			if (!tx_pause_tlv->tx_pause)
637 				total_pkts_queued += tx_pkts_queued;
638 			PRINTM(MCMND,
639 			       "TxPause: " MACSTR
640 			       " pause=%d, pkts=%d  pending=%d total=%d\n",
641 			       MAC2STR(tx_pause_tlv->peermac),
642 			       tx_pause_tlv->tx_pause, tx_pause_tlv->pkt_cnt,
643 			       tx_pkts_queued, total_pkts_queued);
644 		}
645 		tlv_buf_left -= (sizeof(MrvlIEtypesHeader_t) + tlv_len);
646 		tlv = (MrvlIEtypesHeader_t *)((t_u8 *)tlv + tlv_len +
647 					      sizeof(MrvlIEtypesHeader_t));
648 	}
649 
650 	LEAVE();
651 	return;
652 }
653 
654 /**
655  *  @brief This function prepares command for config uap settings
656  *
657  *  @param pmpriv       A pointer to mlan_private structure
658  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
659  *  @param cmd_action   the action: GET or SET
660  *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
661  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
662  */
wlan_uap_cmd_ap_config(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,pmlan_ioctl_req pioctl_buf)663 static mlan_status wlan_uap_cmd_ap_config(pmlan_private pmpriv,
664 					  HostCmd_DS_COMMAND *cmd,
665 					  t_u16 cmd_action,
666 					  pmlan_ioctl_req pioctl_buf)
667 {
668 	mlan_ds_bss *bss = MNULL;
669 	HostCmd_DS_SYS_CONFIG *sys_config =
670 		(HostCmd_DS_SYS_CONFIG *)&cmd->params.sys_config;
671 	t_u8 *tlv = MNULL;
672 	MrvlIEtypes_MacAddr_t *tlv_mac = MNULL;
673 	MrvlIEtypes_SsIdParamSet_t *tlv_ssid = MNULL;
674 	MrvlIEtypes_beacon_period_t *tlv_beacon_period = MNULL;
675 	MrvlIEtypes_dtim_period_t *tlv_dtim_period = MNULL;
676 	MrvlIEtypes_RatesParamSet_t *tlv_rates = MNULL;
677 	MrvlIEtypes_tx_rate_t *tlv_txrate = MNULL;
678 	MrvlIEtypes_mcbc_rate_t *tlv_mcbc_rate = MNULL;
679 	MrvlIEtypes_tx_power_t *tlv_tx_power = MNULL;
680 	MrvlIEtypes_bcast_ssid_t *tlv_bcast_ssid = MNULL;
681 	MrvlIEtypes_antenna_mode_t *tlv_antenna = MNULL;
682 	MrvlIEtypes_pkt_forward_t *tlv_pkt_forward = MNULL;
683 	MrvlIEtypes_max_sta_count_t *tlv_sta_count = MNULL;
684 	MrvlIEtypes_sta_ageout_t *tlv_sta_ageout = MNULL;
685 	MrvlIEtypes_ps_sta_ageout_t *tlv_ps_sta_ageout = MNULL;
686 	MrvlIEtypes_rts_threshold_t *tlv_rts_threshold = MNULL;
687 	MrvlIEtypes_frag_threshold_t *tlv_frag_threshold = MNULL;
688 	MrvlIEtypes_retry_limit_t *tlv_retry_limit = MNULL;
689 	MrvlIEtypes_eapol_pwk_hsk_timeout_t *tlv_pairwise_timeout = MNULL;
690 	MrvlIEtypes_eapol_pwk_hsk_retries_t *tlv_pairwise_retries = MNULL;
691 	MrvlIEtypes_eapol_gwk_hsk_timeout_t *tlv_groupwise_timeout = MNULL;
692 	MrvlIEtypes_eapol_gwk_hsk_retries_t *tlv_groupwise_retries = MNULL;
693 	MrvlIEtypes_mgmt_ie_passthru_t *tlv_mgmt_ie_passthru = MNULL;
694 	MrvlIEtypes_2040_coex_enable_t *tlv_2040_coex_enable = MNULL;
695 	MrvlIEtypes_mac_filter_t *tlv_mac_filter = MNULL;
696 	MrvlIEtypes_channel_band_t *tlv_chan_band = MNULL;
697 	MrvlIEtypes_ChanListParamSet_t *tlv_chan_list = MNULL;
698 	ChanScanParamSet_t *pscan_chan = MNULL;
699 	MrvlIEtypes_auth_type_t *tlv_auth_type = MNULL;
700 	MrvlIEtypes_encrypt_protocol_t *tlv_encrypt_protocol = MNULL;
701 	MrvlIEtypes_akmp_t *tlv_akmp = MNULL;
702 	MrvlIEtypes_pwk_cipher_t *tlv_pwk_cipher = MNULL;
703 	MrvlIEtypes_gwk_cipher_t *tlv_gwk_cipher = MNULL;
704 	MrvlIEtypes_rsn_replay_prot_t *tlv_rsn_prot = MNULL;
705 	MrvlIEtypes_passphrase_t *tlv_passphrase = MNULL;
706 	MrvlIEtypes_group_rekey_time_t *tlv_rekey_time = MNULL;
707 	MrvlIEtypes_wep_key_t *tlv_wep_key = MNULL;
708 	MrvlIETypes_HTCap_t *tlv_htcap = MNULL;
709 	MrvlIEtypes_wmm_parameter_t *tlv_wmm_parameter = MNULL;
710 	MrvlIEtypes_preamble_t *tlv_preamble = MNULL;
711 
712 	t_u32 cmd_size = 0;
713 	t_u8 zero_mac[] = {0, 0, 0, 0, 0, 0};
714 	t_u16 i;
715 	t_u16 ac;
716 #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) ||                \
717 	defined(PCIE9097) || defined(SD9097) || defined(USB9097) ||            \
718 	defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X)
719 	int rx_mcs_supp = 0;
720 #endif
721 
722 	ENTER();
723 	if (pioctl_buf == MNULL) {
724 		LEAVE();
725 		return MLAN_STATUS_FAILURE;
726 	}
727 
728 	bss = (mlan_ds_bss *)pioctl_buf->pbuf;
729 
730 	cmd->command = wlan_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
731 	sys_config->action = wlan_cpu_to_le16(cmd_action);
732 	cmd_size = sizeof(HostCmd_DS_SYS_CONFIG) - 1 + S_DS_GEN;
733 
734 	tlv = (t_u8 *)sys_config->tlv_buffer;
735 	if (memcmp(pmpriv->adapter, zero_mac, &bss->param.bss_config.mac_addr,
736 		   MLAN_MAC_ADDR_LENGTH)) {
737 		tlv_mac = (MrvlIEtypes_MacAddr_t *)tlv;
738 		tlv_mac->header.type =
739 			wlan_cpu_to_le16(TLV_TYPE_UAP_MAC_ADDRESS);
740 		tlv_mac->header.len = wlan_cpu_to_le16(MLAN_MAC_ADDR_LENGTH);
741 		memcpy_ext(pmpriv->adapter, tlv_mac->mac,
742 			   &bss->param.bss_config.mac_addr,
743 			   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
744 		cmd_size += sizeof(MrvlIEtypes_MacAddr_t);
745 		tlv += sizeof(MrvlIEtypes_MacAddr_t);
746 	}
747 
748 	if (bss->param.bss_config.bandcfg.scanMode == SCAN_MODE_ACS) {
749 		/* ACS is not allowed when DFS repeater mode is on */
750 		if (pmpriv->adapter->dfs_repeater) {
751 			PRINTM(MERROR, "ACS is not allowed when"
752 				       "DFS repeater mode is on.\n");
753 			return MLAN_STATUS_FAILURE;
754 		}
755 	}
756 
757 	if (bss->param.bss_config.ssid.ssid_len) {
758 		tlv_ssid = (MrvlIEtypes_SsIdParamSet_t *)tlv;
759 		tlv_ssid->header.type = wlan_cpu_to_le16(TLV_TYPE_SSID);
760 		tlv_ssid->header.len = wlan_cpu_to_le16(
761 			(t_u16)bss->param.bss_config.ssid.ssid_len);
762 		memcpy_ext(pmpriv->adapter, tlv_ssid->ssid,
763 			   bss->param.bss_config.ssid.ssid,
764 			   bss->param.bss_config.ssid.ssid_len,
765 			   MLAN_MAX_SSID_LENGTH);
766 		cmd_size += sizeof(MrvlIEtypesHeader_t) +
767 			    bss->param.bss_config.ssid.ssid_len;
768 		tlv += sizeof(MrvlIEtypesHeader_t) +
769 		       bss->param.bss_config.ssid.ssid_len;
770 	}
771 
772 	if ((bss->param.bss_config.beacon_period >= MIN_BEACON_PERIOD) &&
773 	    (bss->param.bss_config.beacon_period <= MAX_BEACON_PERIOD)) {
774 		tlv_beacon_period = (MrvlIEtypes_beacon_period_t *)tlv;
775 		tlv_beacon_period->header.type =
776 			wlan_cpu_to_le16(TLV_TYPE_UAP_BEACON_PERIOD);
777 		tlv_beacon_period->header.len = wlan_cpu_to_le16(sizeof(t_u16));
778 		tlv_beacon_period->beacon_period =
779 			wlan_cpu_to_le16(bss->param.bss_config.beacon_period);
780 		cmd_size += sizeof(MrvlIEtypes_beacon_period_t);
781 		tlv += sizeof(MrvlIEtypes_beacon_period_t);
782 	}
783 
784 	if ((bss->param.bss_config.dtim_period >= MIN_DTIM_PERIOD) &&
785 	    (bss->param.bss_config.dtim_period <= MAX_DTIM_PERIOD)) {
786 		tlv_dtim_period = (MrvlIEtypes_dtim_period_t *)tlv;
787 		tlv_dtim_period->header.type =
788 			wlan_cpu_to_le16(TLV_TYPE_UAP_DTIM_PERIOD);
789 		tlv_dtim_period->header.len = wlan_cpu_to_le16(sizeof(t_u8));
790 		tlv_dtim_period->dtim_period =
791 			bss->param.bss_config.dtim_period;
792 		cmd_size += sizeof(MrvlIEtypes_dtim_period_t);
793 		tlv += sizeof(MrvlIEtypes_dtim_period_t);
794 	}
795 
796 	if (bss->param.bss_config.rates[0]) {
797 		tlv_rates = (MrvlIEtypes_RatesParamSet_t *)tlv;
798 		tlv_rates->header.type = wlan_cpu_to_le16(TLV_TYPE_RATES);
799 		for (i = 0;
800 		     i < MAX_DATA_RATES && bss->param.bss_config.rates[i];
801 		     i++) {
802 			tlv_rates->rates[i] = bss->param.bss_config.rates[i];
803 		}
804 		tlv_rates->header.len = wlan_cpu_to_le16(i);
805 		cmd_size += sizeof(MrvlIEtypesHeader_t) + i;
806 		tlv += sizeof(MrvlIEtypesHeader_t) + i;
807 	}
808 
809 	if (bss->param.bss_config.tx_data_rate <= DATA_RATE_54M) {
810 		tlv_txrate = (MrvlIEtypes_tx_rate_t *)tlv;
811 		tlv_txrate->header.type =
812 			wlan_cpu_to_le16(TLV_TYPE_UAP_TX_DATA_RATE);
813 		tlv_txrate->header.len = wlan_cpu_to_le16(sizeof(t_u16));
814 		tlv_txrate->tx_data_rate =
815 			wlan_cpu_to_le16(bss->param.bss_config.tx_data_rate);
816 		cmd_size += sizeof(MrvlIEtypes_tx_rate_t);
817 		tlv += sizeof(MrvlIEtypes_tx_rate_t);
818 	}
819 
820 	if (bss->param.bss_config.tx_beacon_rate <= DATA_RATE_54M) {
821 		tlv_txrate = (MrvlIEtypes_tx_rate_t *)tlv;
822 		tlv_txrate->header.type =
823 			wlan_cpu_to_le16(TLV_TYPE_UAP_TX_BEACON_RATE);
824 		tlv_txrate->header.len = wlan_cpu_to_le16(sizeof(t_u16));
825 		tlv_txrate->tx_data_rate =
826 			wlan_cpu_to_le16(bss->param.bss_config.tx_beacon_rate);
827 		cmd_size += sizeof(MrvlIEtypes_tx_rate_t);
828 		tlv += sizeof(MrvlIEtypes_tx_rate_t);
829 	}
830 
831 	if (bss->param.bss_config.mcbc_data_rate <= DATA_RATE_54M) {
832 		tlv_mcbc_rate = (MrvlIEtypes_mcbc_rate_t *)tlv;
833 		tlv_mcbc_rate->header.type =
834 			wlan_cpu_to_le16(TLV_TYPE_UAP_MCBC_DATA_RATE);
835 		tlv_mcbc_rate->header.len = wlan_cpu_to_le16(sizeof(t_u16));
836 		tlv_mcbc_rate->mcbc_data_rate =
837 			wlan_cpu_to_le16(bss->param.bss_config.mcbc_data_rate);
838 		cmd_size += sizeof(MrvlIEtypes_mcbc_rate_t);
839 		tlv += sizeof(MrvlIEtypes_mcbc_rate_t);
840 	}
841 
842 	if (bss->param.bss_config.tx_power_level <= MAX_TX_POWER) {
843 		tlv_tx_power = (MrvlIEtypes_tx_power_t *)tlv;
844 		tlv_tx_power->header.type =
845 			wlan_cpu_to_le16(TLV_TYPE_UAP_TX_POWER);
846 		tlv_tx_power->header.len = wlan_cpu_to_le16(sizeof(t_u8));
847 		tlv_tx_power->tx_power = bss->param.bss_config.tx_power_level;
848 		cmd_size += sizeof(MrvlIEtypes_tx_power_t);
849 		tlv += sizeof(MrvlIEtypes_tx_power_t);
850 	}
851 
852 	if (bss->param.bss_config.bcast_ssid_ctl <= MAX_BCAST_SSID_CTL) {
853 		tlv_bcast_ssid = (MrvlIEtypes_bcast_ssid_t *)tlv;
854 		tlv_bcast_ssid->header.type =
855 			wlan_cpu_to_le16(TLV_TYPE_UAP_BCAST_SSID_CTL);
856 		tlv_bcast_ssid->header.len = wlan_cpu_to_le16(sizeof(t_u8));
857 		tlv_bcast_ssid->bcast_ssid_ctl =
858 			bss->param.bss_config.bcast_ssid_ctl;
859 		cmd_size += sizeof(MrvlIEtypes_bcast_ssid_t);
860 		tlv += sizeof(MrvlIEtypes_bcast_ssid_t);
861 	}
862 
863 	if ((bss->param.bss_config.tx_antenna == ANTENNA_MODE_A) ||
864 	    (bss->param.bss_config.tx_antenna == ANTENNA_MODE_B)) {
865 		tlv_antenna = (MrvlIEtypes_antenna_mode_t *)tlv;
866 		tlv_antenna->header.type =
867 			wlan_cpu_to_le16(TLV_TYPE_UAP_ANTENNA_CTL);
868 		tlv_antenna->header.len =
869 			wlan_cpu_to_le16(sizeof(t_u8) + sizeof(t_u8));
870 		tlv_antenna->which_antenna = TX_ANTENNA;
871 		tlv_antenna->antenna_mode = bss->param.bss_config.tx_antenna;
872 		cmd_size += sizeof(MrvlIEtypes_antenna_mode_t);
873 		tlv += sizeof(MrvlIEtypes_antenna_mode_t);
874 	}
875 
876 	if ((bss->param.bss_config.rx_antenna == ANTENNA_MODE_A) ||
877 	    (bss->param.bss_config.rx_antenna == ANTENNA_MODE_B)) {
878 		tlv_antenna = (MrvlIEtypes_antenna_mode_t *)tlv;
879 		tlv_antenna->header.type =
880 			wlan_cpu_to_le16(TLV_TYPE_UAP_ANTENNA_CTL);
881 		tlv_antenna->header.len =
882 			wlan_cpu_to_le16(sizeof(t_u8) + sizeof(t_u8));
883 		tlv_antenna->which_antenna = RX_ANTENNA;
884 		tlv_antenna->antenna_mode = bss->param.bss_config.rx_antenna;
885 		cmd_size += sizeof(MrvlIEtypes_antenna_mode_t);
886 		tlv += sizeof(MrvlIEtypes_antenna_mode_t);
887 	}
888 
889 	if (bss->param.bss_config.pkt_forward_ctl <= MAX_PKT_FWD_CTRL) {
890 		tlv_pkt_forward = (MrvlIEtypes_pkt_forward_t *)tlv;
891 		tlv_pkt_forward->header.type =
892 			wlan_cpu_to_le16(TLV_TYPE_UAP_PKT_FWD_CTL);
893 		tlv_pkt_forward->header.len = wlan_cpu_to_le16(sizeof(t_u8));
894 		tlv_pkt_forward->pkt_forward_ctl =
895 			bss->param.bss_config.pkt_forward_ctl;
896 		cmd_size += sizeof(MrvlIEtypes_pkt_forward_t);
897 		tlv += sizeof(MrvlIEtypes_pkt_forward_t);
898 	}
899 
900 	if (bss->param.bss_config.max_sta_count <= MAX_STA_COUNT) {
901 		tlv_sta_count = (MrvlIEtypes_max_sta_count_t *)tlv;
902 		tlv_sta_count->header.type =
903 			wlan_cpu_to_le16(TLV_TYPE_UAP_MAX_STA_CNT);
904 		tlv_sta_count->header.len = wlan_cpu_to_le16(sizeof(t_u16));
905 		tlv_sta_count->max_sta_count =
906 			wlan_cpu_to_le16(bss->param.bss_config.max_sta_count);
907 		cmd_size += sizeof(MrvlIEtypes_max_sta_count_t);
908 		tlv += sizeof(MrvlIEtypes_max_sta_count_t);
909 	}
910 
911 	if (((bss->param.bss_config.sta_ageout_timer >= MIN_STAGE_OUT_TIME) &&
912 	     (bss->param.bss_config.sta_ageout_timer <= MAX_STAGE_OUT_TIME)) ||
913 	    (bss->param.bss_config.sta_ageout_timer == 0)) {
914 		tlv_sta_ageout = (MrvlIEtypes_sta_ageout_t *)tlv;
915 		tlv_sta_ageout->header.type =
916 			wlan_cpu_to_le16(TLV_TYPE_UAP_STA_AGEOUT_TIMER);
917 		tlv_sta_ageout->header.len = wlan_cpu_to_le16(sizeof(t_u32));
918 		tlv_sta_ageout->sta_ageout_timer = wlan_cpu_to_le32(
919 			bss->param.bss_config.sta_ageout_timer);
920 		cmd_size += sizeof(MrvlIEtypes_sta_ageout_t);
921 		tlv += sizeof(MrvlIEtypes_sta_ageout_t);
922 	}
923 
924 	if (((bss->param.bss_config.ps_sta_ageout_timer >= MIN_STAGE_OUT_TIME) &&
925 	     (bss->param.bss_config.ps_sta_ageout_timer <=
926 	      MAX_STAGE_OUT_TIME)) ||
927 	    (bss->param.bss_config.ps_sta_ageout_timer == 0)) {
928 		tlv_ps_sta_ageout = (MrvlIEtypes_ps_sta_ageout_t *)tlv;
929 		tlv_ps_sta_ageout->header.type =
930 			wlan_cpu_to_le16(TLV_TYPE_UAP_PS_STA_AGEOUT_TIMER);
931 		tlv_ps_sta_ageout->header.len = wlan_cpu_to_le16(sizeof(t_u32));
932 		tlv_ps_sta_ageout->ps_sta_ageout_timer = wlan_cpu_to_le32(
933 			bss->param.bss_config.ps_sta_ageout_timer);
934 		cmd_size += sizeof(MrvlIEtypes_ps_sta_ageout_t);
935 		tlv += sizeof(MrvlIEtypes_ps_sta_ageout_t);
936 	}
937 	if (bss->param.bss_config.rts_threshold <= MAX_RTS_THRESHOLD) {
938 		tlv_rts_threshold = (MrvlIEtypes_rts_threshold_t *)tlv;
939 		tlv_rts_threshold->header.type =
940 			wlan_cpu_to_le16(TLV_TYPE_UAP_RTS_THRESHOLD);
941 		tlv_rts_threshold->header.len = wlan_cpu_to_le16(sizeof(t_u16));
942 		tlv_rts_threshold->rts_threshold =
943 			wlan_cpu_to_le16(bss->param.bss_config.rts_threshold);
944 		cmd_size += sizeof(MrvlIEtypes_rts_threshold_t);
945 		tlv += sizeof(MrvlIEtypes_rts_threshold_t);
946 	}
947 
948 	if ((bss->param.bss_config.frag_threshold >= MIN_FRAG_THRESHOLD) &&
949 	    (bss->param.bss_config.frag_threshold <= MAX_FRAG_THRESHOLD)) {
950 		tlv_frag_threshold = (MrvlIEtypes_frag_threshold_t *)tlv;
951 		tlv_frag_threshold->header.type =
952 			wlan_cpu_to_le16(TLV_TYPE_UAP_FRAG_THRESHOLD);
953 		tlv_frag_threshold->header.len =
954 			wlan_cpu_to_le16(sizeof(t_u16));
955 		tlv_frag_threshold->frag_threshold =
956 			wlan_cpu_to_le16(bss->param.bss_config.frag_threshold);
957 		cmd_size += sizeof(MrvlIEtypes_frag_threshold_t);
958 		tlv += sizeof(MrvlIEtypes_frag_threshold_t);
959 	}
960 
961 	if (bss->param.bss_config.retry_limit <= MAX_RETRY_LIMIT) {
962 		tlv_retry_limit = (MrvlIEtypes_retry_limit_t *)tlv;
963 		tlv_retry_limit->header.type =
964 			wlan_cpu_to_le16(TLV_TYPE_UAP_RETRY_LIMIT);
965 		tlv_retry_limit->header.len = wlan_cpu_to_le16(sizeof(t_u8));
966 		tlv_retry_limit->retry_limit =
967 			(t_u8)bss->param.bss_config.retry_limit;
968 		cmd_size += sizeof(MrvlIEtypes_retry_limit_t);
969 		tlv += sizeof(MrvlIEtypes_retry_limit_t);
970 	}
971 
972 #ifdef DRV_EMBEDDED_AUTHENTICATOR
973 	if (IS_FW_SUPPORT_AUTHENTICATOR(pmpriv->adapter)) {
974 #endif
975 		if (bss->param.bss_config.pairwise_update_timeout <
976 		    (MAX_VALID_DWORD)) {
977 			tlv_pairwise_timeout =
978 				(MrvlIEtypes_eapol_pwk_hsk_timeout_t *)tlv;
979 			tlv_pairwise_timeout->header.type = wlan_cpu_to_le16(
980 				TLV_TYPE_UAP_EAPOL_PWK_HSK_TIMEOUT);
981 			tlv_pairwise_timeout->header.len =
982 				wlan_cpu_to_le16(sizeof(t_u32));
983 			tlv_pairwise_timeout
984 				->pairwise_update_timeout = wlan_cpu_to_le32(
985 				bss->param.bss_config.pairwise_update_timeout);
986 			cmd_size += sizeof(MrvlIEtypes_eapol_pwk_hsk_timeout_t);
987 			tlv += sizeof(MrvlIEtypes_eapol_pwk_hsk_timeout_t);
988 		}
989 
990 		if (bss->param.bss_config.pwk_retries < (MAX_VALID_DWORD)) {
991 			tlv_pairwise_retries =
992 				(MrvlIEtypes_eapol_pwk_hsk_retries_t *)tlv;
993 			tlv_pairwise_retries->header.type = wlan_cpu_to_le16(
994 				TLV_TYPE_UAP_EAPOL_PWK_HSK_RETRIES);
995 			tlv_pairwise_retries->header.len =
996 				wlan_cpu_to_le16(sizeof(t_u32));
997 			tlv_pairwise_retries->pwk_retries = wlan_cpu_to_le32(
998 				bss->param.bss_config.pwk_retries);
999 			cmd_size += sizeof(MrvlIEtypes_eapol_pwk_hsk_retries_t);
1000 			tlv += sizeof(MrvlIEtypes_eapol_pwk_hsk_retries_t);
1001 		}
1002 
1003 		if (bss->param.bss_config.groupwise_update_timeout <
1004 		    (MAX_VALID_DWORD)) {
1005 			tlv_groupwise_timeout =
1006 				(MrvlIEtypes_eapol_gwk_hsk_timeout_t *)tlv;
1007 			tlv_groupwise_timeout->header.type = wlan_cpu_to_le16(
1008 				TLV_TYPE_UAP_EAPOL_GWK_HSK_TIMEOUT);
1009 			tlv_groupwise_timeout->header.len =
1010 				wlan_cpu_to_le16(sizeof(t_u32));
1011 			tlv_groupwise_timeout
1012 				->groupwise_update_timeout = wlan_cpu_to_le32(
1013 				bss->param.bss_config.groupwise_update_timeout);
1014 			cmd_size += sizeof(MrvlIEtypes_eapol_gwk_hsk_timeout_t);
1015 			tlv += sizeof(MrvlIEtypes_eapol_gwk_hsk_timeout_t);
1016 		}
1017 
1018 		if (bss->param.bss_config.gwk_retries < (MAX_VALID_DWORD)) {
1019 			tlv_groupwise_retries =
1020 				(MrvlIEtypes_eapol_gwk_hsk_retries_t *)tlv;
1021 			tlv_groupwise_retries->header.type = wlan_cpu_to_le16(
1022 				TLV_TYPE_UAP_EAPOL_GWK_HSK_RETRIES);
1023 			tlv_groupwise_retries->header.len =
1024 				wlan_cpu_to_le16(sizeof(t_u32));
1025 			tlv_groupwise_retries->gwk_retries = wlan_cpu_to_le32(
1026 				bss->param.bss_config.gwk_retries);
1027 			cmd_size += sizeof(MrvlIEtypes_eapol_gwk_hsk_retries_t);
1028 			tlv += sizeof(MrvlIEtypes_eapol_gwk_hsk_retries_t);
1029 		}
1030 #ifdef DRV_EMBEDDED_AUTHENTICATOR
1031 	}
1032 #endif
1033 	if ((bss->param.bss_config.filter.filter_mode <=
1034 	     MAC_FILTER_MODE_BLOCK_MAC) &&
1035 	    (bss->param.bss_config.filter.mac_count <= MAX_MAC_FILTER_NUM)) {
1036 		tlv_mac_filter = (MrvlIEtypes_mac_filter_t *)tlv;
1037 		tlv_mac_filter->header.type =
1038 			wlan_cpu_to_le16(TLV_TYPE_UAP_STA_MAC_ADDR_FILTER);
1039 		tlv_mac_filter->header.len = wlan_cpu_to_le16(
1040 			2 + MLAN_MAC_ADDR_LENGTH *
1041 				    bss->param.bss_config.filter.mac_count);
1042 		tlv_mac_filter->count =
1043 			(t_u8)bss->param.bss_config.filter.mac_count;
1044 		tlv_mac_filter->filter_mode =
1045 			(t_u8)bss->param.bss_config.filter.filter_mode;
1046 		memcpy_ext(pmpriv->adapter, tlv_mac_filter->mac_address,
1047 			   (t_u8 *)bss->param.bss_config.filter.mac_list,
1048 			   MLAN_MAC_ADDR_LENGTH *
1049 				   bss->param.bss_config.filter.mac_count,
1050 			   MLAN_MAC_ADDR_LENGTH * MAX_MAC_FILTER_NUM);
1051 		cmd_size += sizeof(MrvlIEtypesHeader_t) + 2 +
1052 			    MLAN_MAC_ADDR_LENGTH *
1053 				    bss->param.bss_config.filter.mac_count;
1054 		tlv += sizeof(MrvlIEtypesHeader_t) + 2 +
1055 		       MLAN_MAC_ADDR_LENGTH *
1056 			       bss->param.bss_config.filter.mac_count;
1057 	}
1058 
1059 	if (((bss->param.bss_config.bandcfg.scanMode == SCAN_MODE_MANUAL) &&
1060 	     (bss->param.bss_config.channel > 0) &&
1061 	     (bss->param.bss_config.channel <= MLAN_MAX_CHANNEL)) ||
1062 	    (bss->param.bss_config.bandcfg.scanMode == SCAN_MODE_ACS)) {
1063 		tlv_chan_band = (MrvlIEtypes_channel_band_t *)tlv;
1064 		tlv_chan_band->header.type =
1065 			wlan_cpu_to_le16(TLV_TYPE_UAP_CHAN_BAND_CONFIG);
1066 		tlv_chan_band->header.len =
1067 			wlan_cpu_to_le16(sizeof(t_u8) + sizeof(t_u8));
1068 		tlv_chan_band->bandcfg = bss->param.bss_config.bandcfg;
1069 		tlv_chan_band->channel = bss->param.bss_config.channel;
1070 		cmd_size += sizeof(MrvlIEtypes_channel_band_t);
1071 		tlv += sizeof(MrvlIEtypes_channel_band_t);
1072 	}
1073 
1074 	if ((bss->param.bss_config.num_of_chan) &&
1075 	    (bss->param.bss_config.num_of_chan <= MLAN_MAX_CHANNEL)) {
1076 		tlv_chan_list = (MrvlIEtypes_ChanListParamSet_t *)tlv;
1077 		tlv_chan_list->header.type =
1078 			wlan_cpu_to_le16(TLV_TYPE_CHANLIST);
1079 		tlv_chan_list->header.len = wlan_cpu_to_le16(
1080 			(t_u16)(sizeof(ChanScanParamSet_t) *
1081 				bss->param.bss_config.num_of_chan));
1082 		pscan_chan = tlv_chan_list->chan_scan_param;
1083 		for (i = 0; i < bss->param.bss_config.num_of_chan; i++) {
1084 			pscan_chan->chan_number =
1085 				bss->param.bss_config.chan_list[i].chan_number;
1086 			pscan_chan->bandcfg =
1087 				bss->param.bss_config.chan_list[i].bandcfg;
1088 			pscan_chan++;
1089 		}
1090 		cmd_size += sizeof(tlv_chan_list->header) +
1091 			    (sizeof(ChanScanParamSet_t) *
1092 			     bss->param.bss_config.num_of_chan);
1093 		tlv += sizeof(tlv_chan_list->header) +
1094 		       (sizeof(ChanScanParamSet_t) *
1095 			bss->param.bss_config.num_of_chan);
1096 	}
1097 
1098 	if ((bss->param.bss_config.auth_mode <= MLAN_AUTH_MODE_SHARED) ||
1099 	    (bss->param.bss_config.auth_mode == MLAN_AUTH_MODE_AUTO)) {
1100 		tlv_auth_type = (MrvlIEtypes_auth_type_t *)tlv;
1101 		tlv_auth_type->header.type =
1102 			wlan_cpu_to_le16(TLV_TYPE_AUTH_TYPE);
1103 		tlv_auth_type->header.len =
1104 			wlan_cpu_to_le16(sizeof(MrvlIEtypes_auth_type_t) -
1105 					 sizeof(MrvlIEtypesHeader_t));
1106 		tlv_auth_type->auth_type =
1107 			(t_u8)bss->param.bss_config.auth_mode;
1108 		cmd_size += sizeof(MrvlIEtypes_auth_type_t);
1109 		tlv += sizeof(MrvlIEtypes_auth_type_t);
1110 	}
1111 
1112 	if (bss->param.bss_config.protocol) {
1113 		tlv_encrypt_protocol = (MrvlIEtypes_encrypt_protocol_t *)tlv;
1114 		tlv_encrypt_protocol->header.type =
1115 			wlan_cpu_to_le16(TLV_TYPE_UAP_ENCRYPT_PROTOCOL);
1116 		tlv_encrypt_protocol->header.len =
1117 			wlan_cpu_to_le16(sizeof(t_u16));
1118 		tlv_encrypt_protocol->protocol =
1119 			wlan_cpu_to_le16(bss->param.bss_config.protocol);
1120 		cmd_size += sizeof(MrvlIEtypes_encrypt_protocol_t);
1121 		tlv += sizeof(MrvlIEtypes_encrypt_protocol_t);
1122 	}
1123 
1124 	if ((bss->param.bss_config.protocol & PROTOCOL_WPA) ||
1125 	    (bss->param.bss_config.protocol & PROTOCOL_WPA2) ||
1126 	    (bss->param.bss_config.protocol & PROTOCOL_EAP)) {
1127 		tlv_akmp = (MrvlIEtypes_akmp_t *)tlv;
1128 		tlv_akmp->header.type = wlan_cpu_to_le16(TLV_TYPE_UAP_AKMP);
1129 		tlv_akmp->key_mgmt =
1130 			wlan_cpu_to_le16(bss->param.bss_config.key_mgmt);
1131 		tlv_akmp->header.len = sizeof(t_u16);
1132 		tlv_akmp->key_mgmt_operation = wlan_cpu_to_le16(
1133 			bss->param.bss_config.key_mgmt_operation);
1134 		tlv_akmp->header.len += sizeof(t_u16);
1135 		tlv_akmp->header.len = wlan_cpu_to_le16(tlv_akmp->header.len);
1136 		cmd_size += sizeof(MrvlIEtypes_akmp_t);
1137 		tlv += sizeof(MrvlIEtypes_akmp_t);
1138 
1139 		if (bss->param.bss_config.wpa_cfg.pairwise_cipher_wpa &
1140 		    VALID_CIPHER_BITMAP) {
1141 			tlv_pwk_cipher = (MrvlIEtypes_pwk_cipher_t *)tlv;
1142 			tlv_pwk_cipher->header.type =
1143 				wlan_cpu_to_le16(TLV_TYPE_PWK_CIPHER);
1144 			tlv_pwk_cipher->header.len = wlan_cpu_to_le16(
1145 				sizeof(t_u16) + sizeof(t_u8) + sizeof(t_u8));
1146 			tlv_pwk_cipher->protocol =
1147 				wlan_cpu_to_le16(PROTOCOL_WPA);
1148 			tlv_pwk_cipher->pairwise_cipher =
1149 				bss->param.bss_config.wpa_cfg
1150 					.pairwise_cipher_wpa;
1151 			cmd_size += sizeof(MrvlIEtypes_pwk_cipher_t);
1152 			tlv += sizeof(MrvlIEtypes_pwk_cipher_t);
1153 		}
1154 
1155 		if (bss->param.bss_config.wpa_cfg.pairwise_cipher_wpa2 &
1156 		    VALID_CIPHER_BITMAP) {
1157 			tlv_pwk_cipher = (MrvlIEtypes_pwk_cipher_t *)tlv;
1158 			tlv_pwk_cipher->header.type =
1159 				wlan_cpu_to_le16(TLV_TYPE_PWK_CIPHER);
1160 			tlv_pwk_cipher->header.len = wlan_cpu_to_le16(
1161 				sizeof(t_u16) + sizeof(t_u8) + sizeof(t_u8));
1162 			tlv_pwk_cipher->protocol =
1163 				wlan_cpu_to_le16(PROTOCOL_WPA2);
1164 			tlv_pwk_cipher->pairwise_cipher =
1165 				bss->param.bss_config.wpa_cfg
1166 					.pairwise_cipher_wpa2;
1167 			cmd_size += sizeof(MrvlIEtypes_pwk_cipher_t);
1168 			tlv += sizeof(MrvlIEtypes_pwk_cipher_t);
1169 		}
1170 
1171 		if (bss->param.bss_config.wpa_cfg.group_cipher &
1172 		    VALID_CIPHER_BITMAP) {
1173 			tlv_gwk_cipher = (MrvlIEtypes_gwk_cipher_t *)tlv;
1174 			tlv_gwk_cipher->header.type =
1175 				wlan_cpu_to_le16(TLV_TYPE_GWK_CIPHER);
1176 			tlv_gwk_cipher->header.len =
1177 				wlan_cpu_to_le16(sizeof(t_u8) + sizeof(t_u8));
1178 			tlv_gwk_cipher->group_cipher =
1179 				bss->param.bss_config.wpa_cfg.group_cipher;
1180 			cmd_size += sizeof(MrvlIEtypes_gwk_cipher_t);
1181 			tlv += sizeof(MrvlIEtypes_gwk_cipher_t);
1182 		}
1183 
1184 		if (bss->param.bss_config.wpa_cfg.rsn_protection <= MTRUE) {
1185 			tlv_rsn_prot = (MrvlIEtypes_rsn_replay_prot_t *)tlv;
1186 			tlv_rsn_prot->header.type = wlan_cpu_to_le16(
1187 				TLV_TYPE_UAP_RSN_REPLAY_PROTECT);
1188 			tlv_rsn_prot->header.len =
1189 				wlan_cpu_to_le16(sizeof(t_u8));
1190 			tlv_rsn_prot->rsn_replay_prot =
1191 				bss->param.bss_config.wpa_cfg.rsn_protection;
1192 			cmd_size += sizeof(MrvlIEtypes_rsn_replay_prot_t);
1193 			tlv += sizeof(MrvlIEtypes_rsn_replay_prot_t);
1194 		}
1195 
1196 #ifdef DRV_EMBEDDED_AUTHENTICATOR
1197 		if (IS_FW_SUPPORT_AUTHENTICATOR(pmpriv->adapter)) {
1198 #endif
1199 			if (bss->param.bss_config.wpa_cfg.length) {
1200 				tlv_passphrase =
1201 					(MrvlIEtypes_passphrase_t *)tlv;
1202 				tlv_passphrase->header.type = wlan_cpu_to_le16(
1203 					TLV_TYPE_UAP_WPA_PASSPHRASE);
1204 				tlv_passphrase->header
1205 					.len = (t_u16)wlan_cpu_to_le16(
1206 					bss->param.bss_config.wpa_cfg.length);
1207 				memcpy_ext(
1208 					pmpriv->adapter,
1209 					tlv_passphrase->passphrase,
1210 					bss->param.bss_config.wpa_cfg.passphrase,
1211 					bss->param.bss_config.wpa_cfg.length,
1212 					bss->param.bss_config.wpa_cfg.length);
1213 				cmd_size +=
1214 					sizeof(MrvlIEtypesHeader_t) +
1215 					bss->param.bss_config.wpa_cfg.length;
1216 				tlv += sizeof(MrvlIEtypesHeader_t) +
1217 				       bss->param.bss_config.wpa_cfg.length;
1218 			}
1219 
1220 			if (bss->param.bss_config.wpa_cfg.gk_rekey_time <
1221 			    MAX_GRP_TIMER) {
1222 				tlv_rekey_time =
1223 					(MrvlIEtypes_group_rekey_time_t *)tlv;
1224 				tlv_rekey_time->header.type = wlan_cpu_to_le16(
1225 					TLV_TYPE_UAP_GRP_REKEY_TIME);
1226 				tlv_rekey_time->header.len =
1227 					wlan_cpu_to_le16(sizeof(t_u32));
1228 				tlv_rekey_time->gk_rekey_time =
1229 					wlan_cpu_to_le32(
1230 						bss->param.bss_config.wpa_cfg
1231 							.gk_rekey_time);
1232 				cmd_size +=
1233 					sizeof(MrvlIEtypes_group_rekey_time_t);
1234 				tlv += sizeof(MrvlIEtypes_group_rekey_time_t);
1235 			}
1236 #ifdef DRV_EMBEDDED_AUTHENTICATOR
1237 		}
1238 #endif
1239 	} else {
1240 		if ((bss->param.bss_config.wep_cfg.key0.length) &&
1241 		    ((bss->param.bss_config.wep_cfg.key0.length == 5) ||
1242 		     (bss->param.bss_config.wep_cfg.key0.length == 10) ||
1243 		     (bss->param.bss_config.wep_cfg.key0.length == 13) ||
1244 		     (bss->param.bss_config.wep_cfg.key0.length == 26))) {
1245 			tlv_wep_key = (MrvlIEtypes_wep_key_t *)tlv;
1246 			tlv_wep_key->header.type =
1247 				wlan_cpu_to_le16(TLV_TYPE_UAP_WEP_KEY);
1248 			tlv_wep_key->header.len = wlan_cpu_to_le16(
1249 				2 + bss->param.bss_config.wep_cfg.key0.length);
1250 			tlv_wep_key->key_index =
1251 				bss->param.bss_config.wep_cfg.key0.key_index;
1252 			tlv_wep_key->is_default =
1253 				bss->param.bss_config.wep_cfg.key0.is_default;
1254 			memcpy_ext(pmpriv->adapter, tlv_wep_key->key,
1255 				   bss->param.bss_config.wep_cfg.key0.key,
1256 				   bss->param.bss_config.wep_cfg.key0.length,
1257 				   bss->param.bss_config.wep_cfg.key0.length);
1258 			cmd_size += sizeof(MrvlIEtypesHeader_t) + 2 +
1259 				    bss->param.bss_config.wep_cfg.key0.length;
1260 			tlv += sizeof(MrvlIEtypesHeader_t) + 2 +
1261 			       bss->param.bss_config.wep_cfg.key0.length;
1262 		}
1263 
1264 		if ((bss->param.bss_config.wep_cfg.key1.length) &&
1265 		    ((bss->param.bss_config.wep_cfg.key1.length == 5) ||
1266 		     (bss->param.bss_config.wep_cfg.key1.length == 10) ||
1267 		     (bss->param.bss_config.wep_cfg.key1.length == 13) ||
1268 		     (bss->param.bss_config.wep_cfg.key1.length == 26))) {
1269 			tlv_wep_key = (MrvlIEtypes_wep_key_t *)tlv;
1270 			tlv_wep_key->header.type =
1271 				wlan_cpu_to_le16(TLV_TYPE_UAP_WEP_KEY);
1272 			tlv_wep_key->header.len = wlan_cpu_to_le16(
1273 				2 + bss->param.bss_config.wep_cfg.key1.length);
1274 			tlv_wep_key->key_index =
1275 				bss->param.bss_config.wep_cfg.key1.key_index;
1276 			tlv_wep_key->is_default =
1277 				bss->param.bss_config.wep_cfg.key1.is_default;
1278 			memcpy_ext(pmpriv->adapter, tlv_wep_key->key,
1279 				   bss->param.bss_config.wep_cfg.key1.key,
1280 				   bss->param.bss_config.wep_cfg.key1.length,
1281 				   bss->param.bss_config.wep_cfg.key1.length);
1282 			cmd_size += sizeof(MrvlIEtypesHeader_t) + 2 +
1283 				    bss->param.bss_config.wep_cfg.key1.length;
1284 			tlv += sizeof(MrvlIEtypesHeader_t) + 2 +
1285 			       bss->param.bss_config.wep_cfg.key1.length;
1286 		}
1287 
1288 		if ((bss->param.bss_config.wep_cfg.key2.length) &&
1289 		    ((bss->param.bss_config.wep_cfg.key2.length == 5) ||
1290 		     (bss->param.bss_config.wep_cfg.key2.length == 10) ||
1291 		     (bss->param.bss_config.wep_cfg.key2.length == 13) ||
1292 		     (bss->param.bss_config.wep_cfg.key2.length == 26))) {
1293 			tlv_wep_key = (MrvlIEtypes_wep_key_t *)tlv;
1294 			tlv_wep_key->header.type =
1295 				wlan_cpu_to_le16(TLV_TYPE_UAP_WEP_KEY);
1296 			tlv_wep_key->header.len = wlan_cpu_to_le16(
1297 				2 + bss->param.bss_config.wep_cfg.key2.length);
1298 			tlv_wep_key->key_index =
1299 				bss->param.bss_config.wep_cfg.key2.key_index;
1300 			tlv_wep_key->is_default =
1301 				bss->param.bss_config.wep_cfg.key2.is_default;
1302 			memcpy_ext(pmpriv->adapter, tlv_wep_key->key,
1303 				   bss->param.bss_config.wep_cfg.key2.key,
1304 				   bss->param.bss_config.wep_cfg.key2.length,
1305 				   bss->param.bss_config.wep_cfg.key2.length);
1306 			cmd_size += sizeof(MrvlIEtypesHeader_t) + 2 +
1307 				    bss->param.bss_config.wep_cfg.key2.length;
1308 			tlv += sizeof(MrvlIEtypesHeader_t) + 2 +
1309 			       bss->param.bss_config.wep_cfg.key2.length;
1310 		}
1311 
1312 		if ((bss->param.bss_config.wep_cfg.key3.length) &&
1313 		    ((bss->param.bss_config.wep_cfg.key3.length == 5) ||
1314 		     (bss->param.bss_config.wep_cfg.key3.length == 10) ||
1315 		     (bss->param.bss_config.wep_cfg.key3.length == 13) ||
1316 		     (bss->param.bss_config.wep_cfg.key3.length == 26))) {
1317 			tlv_wep_key = (MrvlIEtypes_wep_key_t *)tlv;
1318 			tlv_wep_key->header.type =
1319 				wlan_cpu_to_le16(TLV_TYPE_UAP_WEP_KEY);
1320 			tlv_wep_key->header.len = wlan_cpu_to_le16(
1321 				2 + bss->param.bss_config.wep_cfg.key3.length);
1322 			tlv_wep_key->key_index =
1323 				bss->param.bss_config.wep_cfg.key3.key_index;
1324 			tlv_wep_key->is_default =
1325 				bss->param.bss_config.wep_cfg.key3.is_default;
1326 			memcpy_ext(pmpriv->adapter, tlv_wep_key->key,
1327 				   bss->param.bss_config.wep_cfg.key3.key,
1328 				   bss->param.bss_config.wep_cfg.key3.length,
1329 				   bss->param.bss_config.wep_cfg.key3.length);
1330 			cmd_size += sizeof(MrvlIEtypesHeader_t) + 2 +
1331 				    bss->param.bss_config.wep_cfg.key3.length;
1332 			tlv += sizeof(MrvlIEtypesHeader_t) + 2 +
1333 			       bss->param.bss_config.wep_cfg.key3.length;
1334 		}
1335 	}
1336 	if (bss->param.bss_config.ht_cap_info) {
1337 		tlv_htcap = (MrvlIETypes_HTCap_t *)tlv;
1338 		tlv_htcap->header.type = wlan_cpu_to_le16(HT_CAPABILITY);
1339 		tlv_htcap->header.len = wlan_cpu_to_le16(sizeof(HTCap_t));
1340 		tlv_htcap->ht_cap.ht_cap_info =
1341 			wlan_cpu_to_le16(bss->param.bss_config.ht_cap_info);
1342 		tlv_htcap->ht_cap.ampdu_param =
1343 			bss->param.bss_config.ampdu_param;
1344 		memcpy_ext(pmpriv->adapter, tlv_htcap->ht_cap.supported_mcs_set,
1345 			   bss->param.bss_config.supported_mcs_set, 16,
1346 			   sizeof(tlv_htcap->ht_cap.supported_mcs_set));
1347 #if defined(PCIE9098) || defined(SD9098) || defined(USB9098) ||                \
1348 	defined(PCIE9097) || defined(SD9097) || defined(USB9097) ||            \
1349 	defined(SDNW62X) || defined(PCIENW62X) || defined(USBNW62X)
1350 		if (IS_CARD9098(pmpriv->adapter->card_type) ||
1351 		    IS_CARDNW62X(pmpriv->adapter->card_type) ||
1352 		    IS_CARD9097(pmpriv->adapter->card_type)) {
1353 			if (bss->param.bss_config.supported_mcs_set[0]) {
1354 				if (bss->param.bss_config.bandcfg.chanBand ==
1355 				    BAND_5GHZ)
1356 					rx_mcs_supp = GET_RXMCSSUPP(
1357 						pmpriv->adapter->user_htstream >>
1358 						8);
1359 				else
1360 					rx_mcs_supp = GET_RXMCSSUPP(
1361 						pmpriv->adapter->user_htstream);
1362 
1363 				if (rx_mcs_supp == 0x1) {
1364 					tlv_htcap->ht_cap.supported_mcs_set[0] =
1365 						0xFF;
1366 					tlv_htcap->ht_cap.supported_mcs_set[1] =
1367 						0;
1368 				} else if (rx_mcs_supp == 0x2) {
1369 					tlv_htcap->ht_cap.supported_mcs_set[0] =
1370 						0xFF;
1371 					tlv_htcap->ht_cap.supported_mcs_set[1] =
1372 						0xFF;
1373 				}
1374 			}
1375 		}
1376 #endif
1377 		tlv_htcap->ht_cap.ht_ext_cap =
1378 			wlan_cpu_to_le16(bss->param.bss_config.ht_ext_cap);
1379 		tlv_htcap->ht_cap.tx_bf_cap =
1380 			wlan_cpu_to_le32(bss->param.bss_config.tx_bf_cap);
1381 		tlv_htcap->ht_cap.asel = bss->param.bss_config.asel;
1382 		cmd_size += sizeof(MrvlIETypes_HTCap_t);
1383 		tlv += sizeof(MrvlIETypes_HTCap_t);
1384 	}
1385 	if (bss->param.bss_config.mgmt_ie_passthru_mask < (MAX_VALID_DWORD)) {
1386 		tlv_mgmt_ie_passthru = (MrvlIEtypes_mgmt_ie_passthru_t *)tlv;
1387 		tlv_mgmt_ie_passthru->header.type =
1388 			wlan_cpu_to_le16(TLV_TYPE_UAP_MGMT_IE_PASSTHRU_MASK);
1389 		tlv_mgmt_ie_passthru->header.len =
1390 			wlan_cpu_to_le16(sizeof(t_u32));
1391 		/* keep copy in private data */
1392 		pmpriv->mgmt_frame_passthru_mask =
1393 			bss->param.bss_config.mgmt_ie_passthru_mask;
1394 		tlv_mgmt_ie_passthru->mgmt_ie_mask = wlan_cpu_to_le32(
1395 			bss->param.bss_config.mgmt_ie_passthru_mask);
1396 		cmd_size += sizeof(MrvlIEtypes_mgmt_ie_passthru_t);
1397 		tlv += sizeof(MrvlIEtypes_mgmt_ie_passthru_t);
1398 	}
1399 	if ((bss->param.bss_config.enable_2040coex == 0) ||
1400 	    (bss->param.bss_config.enable_2040coex == 1)) {
1401 		tlv_2040_coex_enable = (MrvlIEtypes_2040_coex_enable_t *)tlv;
1402 		tlv_2040_coex_enable->header.type =
1403 			wlan_cpu_to_le16(TLV_TYPE_2040_BSS_COEX_CONTROL);
1404 		tlv_2040_coex_enable->header.len =
1405 			wlan_cpu_to_le16(sizeof(t_u8));
1406 		tlv_2040_coex_enable->enable_2040coex =
1407 			bss->param.bss_config.enable_2040coex;
1408 		cmd_size += sizeof(MrvlIEtypes_2040_coex_enable_t);
1409 		tlv += sizeof(MrvlIEtypes_2040_coex_enable_t);
1410 	}
1411 	if ((bss->param.bss_config.uap_host_based_config == MTRUE) ||
1412 	    (bss->param.bss_config.wmm_para.qos_info & 0x80 ||
1413 	     bss->param.bss_config.wmm_para.qos_info == 0x00)) {
1414 		tlv_wmm_parameter = (MrvlIEtypes_wmm_parameter_t *)tlv;
1415 		tlv_wmm_parameter->header.type =
1416 			wlan_cpu_to_le16(TLV_TYPE_VENDOR_SPECIFIC_IE);
1417 		tlv_wmm_parameter->header.len = wlan_cpu_to_le16(
1418 			sizeof(bss->param.bss_config.wmm_para));
1419 		memcpy_ext(pmpriv->adapter, tlv_wmm_parameter->wmm_para.ouitype,
1420 			   bss->param.bss_config.wmm_para.ouitype,
1421 			   sizeof(tlv_wmm_parameter->wmm_para.ouitype),
1422 			   sizeof(tlv_wmm_parameter->wmm_para.ouitype));
1423 		tlv_wmm_parameter->wmm_para.ouisubtype =
1424 			bss->param.bss_config.wmm_para.ouisubtype;
1425 		tlv_wmm_parameter->wmm_para.version =
1426 			bss->param.bss_config.wmm_para.version;
1427 		tlv_wmm_parameter->wmm_para.qos_info =
1428 			bss->param.bss_config.wmm_para.qos_info;
1429 		for (ac = 0; ac < 4; ac++) {
1430 			tlv_wmm_parameter->wmm_para.ac_params[ac]
1431 				.aci_aifsn.aifsn =
1432 				bss->param.bss_config.wmm_para.ac_params[ac]
1433 					.aci_aifsn.aifsn;
1434 			tlv_wmm_parameter->wmm_para.ac_params[ac].aci_aifsn.aci =
1435 				bss->param.bss_config.wmm_para.ac_params[ac]
1436 					.aci_aifsn.aci;
1437 			tlv_wmm_parameter->wmm_para.ac_params[ac].ecw.ecw_max =
1438 				bss->param.bss_config.wmm_para.ac_params[ac]
1439 					.ecw.ecw_max;
1440 			tlv_wmm_parameter->wmm_para.ac_params[ac].ecw.ecw_min =
1441 				bss->param.bss_config.wmm_para.ac_params[ac]
1442 					.ecw.ecw_min;
1443 			tlv_wmm_parameter->wmm_para.ac_params[ac].tx_op_limit =
1444 				wlan_cpu_to_le16(bss->param.bss_config.wmm_para
1445 							 .ac_params[ac]
1446 							 .tx_op_limit);
1447 		}
1448 		cmd_size += sizeof(MrvlIEtypes_wmm_parameter_t);
1449 		tlv += sizeof(MrvlIEtypes_wmm_parameter_t);
1450 	}
1451 #ifdef DRV_EMBEDDED_AUTHENTICATOR
1452 	if (!IS_FW_SUPPORT_AUTHENTICATOR(pmpriv->adapter))
1453 		AuthenticatorBssConfig(pmpriv->psapriv,
1454 				       (t_u8 *)&bss->param.bss_config, 0, 0, 0);
1455 #endif
1456 	if (pmpriv->adapter->pcard_info->v17_fw_api &&
1457 	    bss->param.bss_config.preamble_type) {
1458 		tlv_preamble = (MrvlIEtypes_preamble_t *)tlv;
1459 		tlv_preamble->header.type =
1460 			wlan_cpu_to_le16(TLV_TYPE_UAP_PREAMBLE_CTL);
1461 		tlv_preamble->header.len =
1462 			wlan_cpu_to_le16(sizeof(MrvlIEtypes_preamble_t) -
1463 					 sizeof(MrvlIEtypesHeader_t));
1464 		tlv_preamble->preamble_type =
1465 			wlan_cpu_to_le16(bss->param.bss_config.preamble_type);
1466 
1467 		cmd_size += sizeof(MrvlIEtypes_preamble_t);
1468 		tlv += sizeof(MrvlIEtypes_preamble_t);
1469 	}
1470 	cmd->size = (t_u16)wlan_cpu_to_le16(cmd_size);
1471 	PRINTM(MCMND, "AP config: cmd_size=%d\n", cmd_size);
1472 	LEAVE();
1473 	return MLAN_STATUS_SUCCESS;
1474 }
1475 
1476 /**
1477  *  @brief This function prepares command of sys_config
1478  *
1479  *  @param pmpriv       A pointer to mlan_private structure
1480  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
1481  *  @param cmd_action   the action: GET or SET
1482  *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
1483  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1484  */
wlan_uap_cmd_sys_configure(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,pmlan_ioctl_req pioctl_buf,t_void * pdata_buf)1485 static mlan_status wlan_uap_cmd_sys_configure(pmlan_private pmpriv,
1486 					      HostCmd_DS_COMMAND *cmd,
1487 					      t_u16 cmd_action,
1488 					      pmlan_ioctl_req pioctl_buf,
1489 					      t_void *pdata_buf)
1490 {
1491 	mlan_ds_bss *bss = MNULL;
1492 	HostCmd_DS_SYS_CONFIG *sys_config =
1493 		(HostCmd_DS_SYS_CONFIG *)&cmd->params.sys_config;
1494 	MrvlIEtypes_MacAddr_t *mac_tlv = MNULL;
1495 	MrvlIEtypes_channel_band_t *pdat_tlv_cb = MNULL;
1496 	MrvlIEtypes_beacon_period_t *bcn_pd_tlv = MNULL,
1497 				    *pdat_tlv_bcnpd = MNULL;
1498 	MrvlIEtypes_dtim_period_t *dtim_pd_tlv = MNULL,
1499 				  *pdat_tlv_dtimpd = MNULL;
1500 	MrvlIEtypes_wmm_parameter_t *tlv_wmm_parameter = MNULL;
1501 	MrvlIEtypes_ChanListParamSet_t *tlv_chan_list = MNULL;
1502 	ChanScanParamSet_t *pscan_chan = MNULL;
1503 	MrvlIEtypes_channel_band_t *chan_band_tlv = MNULL;
1504 	MrvlIEtypes_chan_bw_oper_t *poper_class_tlv = MNULL;
1505 	t_u8 length = 0;
1506 	t_u8 curr_oper_class = 1;
1507 	t_u8 *oper_class_ie = (t_u8 *)sys_config->tlv_buffer;
1508 	t_u16 i = 0;
1509 	t_u8 ac = 0;
1510 	mlan_ds_misc_custom_ie *cust_ie = MNULL;
1511 	mlan_ds_misc_cfg *misc = MNULL;
1512 	MrvlIEtypesHeader_t *ie_header =
1513 		(MrvlIEtypesHeader_t *)sys_config->tlv_buffer;
1514 	MrvlIEtypesHeader_t *pdata_header = (MrvlIEtypesHeader_t *)pdata_buf;
1515 	t_u8 *ie = (t_u8 *)sys_config->tlv_buffer + sizeof(MrvlIEtypesHeader_t);
1516 	t_u16 req_len = 0, travel_len = 0;
1517 	custom_ie *cptr = MNULL;
1518 	mlan_status ret = MLAN_STATUS_SUCCESS;
1519 	MrvlIEtypes_wacp_mode_t *tlv_wacp_mode = MNULL;
1520 	MrvlIEtypes_action_chan_switch_t *tlv_chan_switch = MNULL;
1521 	IEEEtypes_ChanSwitchAnn_t *csa_ie = MNULL;
1522 	IEEEtypes_ExtChanSwitchAnn_t *ecsa_ie = MNULL;
1523 
1524 	ENTER();
1525 
1526 	cmd->command = wlan_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
1527 	sys_config->action = wlan_cpu_to_le16(cmd_action);
1528 	cmd->size =
1529 		wlan_cpu_to_le16(sizeof(HostCmd_DS_SYS_CONFIG) - 1 + S_DS_GEN);
1530 	if (pioctl_buf == MNULL) {
1531 		if (pdata_buf) {
1532 			switch (pdata_header->type) {
1533 			case TLV_TYPE_UAP_CHAN_BAND_CONFIG:
1534 				pdat_tlv_cb =
1535 					(MrvlIEtypes_channel_band_t *)pdata_buf;
1536 				chan_band_tlv = (MrvlIEtypes_channel_band_t *)
1537 							sys_config->tlv_buffer;
1538 				cmd->size = wlan_cpu_to_le16(
1539 					sizeof(HostCmd_DS_SYS_CONFIG) - 1 +
1540 					S_DS_GEN +
1541 					sizeof(MrvlIEtypes_channel_band_t));
1542 				chan_band_tlv->header.type = wlan_cpu_to_le16(
1543 					TLV_TYPE_UAP_CHAN_BAND_CONFIG);
1544 				chan_band_tlv->header.len = wlan_cpu_to_le16(
1545 					sizeof(MrvlIEtypes_channel_band_t) -
1546 					sizeof(MrvlIEtypesHeader_t));
1547 				if (cmd_action) {
1548 					chan_band_tlv->bandcfg =
1549 						pdat_tlv_cb->bandcfg;
1550 					chan_band_tlv->channel =
1551 						pdat_tlv_cb->channel;
1552 				}
1553 				ret = MLAN_STATUS_SUCCESS;
1554 				break;
1555 			case TLV_TYPE_UAP_BEACON_PERIOD:
1556 				pdat_tlv_bcnpd = (MrvlIEtypes_beacon_period_t *)
1557 					pdata_buf;
1558 				bcn_pd_tlv = (MrvlIEtypes_beacon_period_t *)
1559 						     sys_config->tlv_buffer;
1560 				cmd->size = sizeof(HostCmd_DS_SYS_CONFIG) - 1 +
1561 					    S_DS_GEN +
1562 					    sizeof(MrvlIEtypes_beacon_period_t);
1563 				bcn_pd_tlv->header.type = wlan_cpu_to_le16(
1564 					TLV_TYPE_UAP_BEACON_PERIOD);
1565 				bcn_pd_tlv->header.len = wlan_cpu_to_le16(
1566 					sizeof(MrvlIEtypes_beacon_period_t) -
1567 					sizeof(MrvlIEtypesHeader_t));
1568 				if (cmd_action) {
1569 					bcn_pd_tlv->beacon_period =
1570 						wlan_cpu_to_le16(
1571 							pdat_tlv_bcnpd
1572 								->beacon_period);
1573 				}
1574 				/* Add TLV_UAP_DTIM_PERIOD if it follws in
1575 				 * pdata_buf */
1576 				pdat_tlv_dtimpd =
1577 					(MrvlIEtypes_dtim_period_t
1578 						 *)(((t_u8 *)pdata_buf) +
1579 						    sizeof(MrvlIEtypes_beacon_period_t));
1580 				if (TLV_TYPE_UAP_DTIM_PERIOD ==
1581 				    pdat_tlv_dtimpd->header.type) {
1582 					dtim_pd_tlv =
1583 						(MrvlIEtypes_dtim_period_t
1584 							 *)(sys_config
1585 								    ->tlv_buffer +
1586 							    sizeof(MrvlIEtypes_beacon_period_t));
1587 					cmd->size += sizeof(
1588 						MrvlIEtypes_dtim_period_t);
1589 					dtim_pd_tlv->header
1590 						.type = wlan_cpu_to_le16(
1591 						TLV_TYPE_UAP_DTIM_PERIOD);
1592 					dtim_pd_tlv->header
1593 						.len = wlan_cpu_to_le16(
1594 						sizeof(MrvlIEtypes_dtim_period_t) -
1595 						sizeof(MrvlIEtypesHeader_t));
1596 					if (cmd_action) {
1597 						dtim_pd_tlv->dtim_period =
1598 							pdat_tlv_dtimpd
1599 								->dtim_period;
1600 					}
1601 				}
1602 				/* Finalize cmd size */
1603 				cmd->size = wlan_cpu_to_le16(cmd->size);
1604 				ret = MLAN_STATUS_SUCCESS;
1605 				break;
1606 			case TLV_TYPE_MGMT_IE:
1607 				cust_ie = (mlan_ds_misc_custom_ie *)pdata_buf;
1608 				cmd->size = wlan_cpu_to_le16(
1609 					sizeof(HostCmd_DS_SYS_CONFIG) - 1 +
1610 					S_DS_GEN + sizeof(MrvlIEtypesHeader_t) +
1611 					cust_ie->len);
1612 				ie_header->type =
1613 					wlan_cpu_to_le16(TLV_TYPE_MGMT_IE);
1614 				ie_header->len = wlan_cpu_to_le16(cust_ie->len);
1615 
1616 				if (ie) {
1617 					req_len = cust_ie->len;
1618 					travel_len = 0;
1619 					/* conversion for index, mask, len */
1620 					if (req_len == sizeof(t_u16))
1621 						cust_ie->ie_data_list[0]
1622 							.ie_index = wlan_cpu_to_le16(
1623 							cust_ie->ie_data_list[0]
1624 								.ie_index);
1625 					while (req_len > sizeof(t_u16)) {
1626 						cptr = (custom_ie
1627 								*)(((t_u8 *)&cust_ie
1628 									    ->ie_data_list) +
1629 								   travel_len);
1630 						travel_len +=
1631 							cptr->ie_length +
1632 							sizeof(custom_ie) -
1633 							MAX_IE_SIZE;
1634 						req_len -= cptr->ie_length +
1635 							   sizeof(custom_ie) -
1636 							   MAX_IE_SIZE;
1637 						cptr->ie_index =
1638 							wlan_cpu_to_le16(
1639 								cptr->ie_index);
1640 						cptr->mgmt_subtype_mask = wlan_cpu_to_le16(
1641 							cptr->mgmt_subtype_mask);
1642 						cptr->ie_length =
1643 							wlan_cpu_to_le16(
1644 								cptr->ie_length);
1645 					}
1646 					memcpy_ext(pmpriv->adapter, ie,
1647 						   cust_ie->ie_data_list,
1648 						   cust_ie->len, cust_ie->len);
1649 				}
1650 				break;
1651 			case REGULATORY_CLASS:
1652 				poper_class_tlv =
1653 					(MrvlIEtypes_chan_bw_oper_t *)pdata_buf;
1654 				ret = wlan_get_curr_oper_class(
1655 					pmpriv,
1656 					poper_class_tlv->ds_chan_bw_oper.channel,
1657 					poper_class_tlv->ds_chan_bw_oper
1658 						.bandwidth,
1659 					&curr_oper_class);
1660 				if (ret != MLAN_STATUS_SUCCESS) {
1661 					PRINTM(MERROR,
1662 					       "Can not get current oper class! bandwidth = %d, channel = %d\n",
1663 					       poper_class_tlv->ds_chan_bw_oper
1664 						       .bandwidth,
1665 					       poper_class_tlv->ds_chan_bw_oper
1666 						       .channel);
1667 				}
1668 
1669 				if (cmd_action == HostCmd_ACT_GEN_SET)
1670 					length =
1671 						wlan_add_supported_oper_class_ie(
1672 							pmpriv, &oper_class_ie,
1673 							curr_oper_class);
1674 				cmd->size = wlan_cpu_to_le16(
1675 					sizeof(HostCmd_DS_SYS_CONFIG) - 1 +
1676 					S_DS_GEN + length);
1677 				break;
1678 			case TLV_TYPE_UAP_MAX_STA_CNT_PER_CHIP:
1679 				memcpy_ext(
1680 					pmpriv->adapter, sys_config->tlv_buffer,
1681 					pdata_buf,
1682 					sizeof(MrvlIEtypes_uap_max_sta_cnt_t),
1683 					sizeof(MrvlIEtypes_uap_max_sta_cnt_t));
1684 				cmd->size = wlan_cpu_to_le16(
1685 					sizeof(HostCmd_DS_SYS_CONFIG) - 1 +
1686 					S_DS_GEN +
1687 					sizeof(MrvlIEtypes_uap_max_sta_cnt_t));
1688 				break;
1689 			default:
1690 				PRINTM(MERROR,
1691 				       "Wrong data, or missing TLV_TYPE 0x%04x handler.\n",
1692 				       *(t_u16 *)pdata_buf);
1693 				break;
1694 			}
1695 			goto done;
1696 		} else {
1697 			mac_tlv =
1698 				(MrvlIEtypes_MacAddr_t *)sys_config->tlv_buffer;
1699 			cmd->size = wlan_cpu_to_le16(
1700 				sizeof(HostCmd_DS_SYS_CONFIG) - 1 + S_DS_GEN +
1701 				sizeof(MrvlIEtypes_MacAddr_t));
1702 			mac_tlv->header.type =
1703 				wlan_cpu_to_le16(TLV_TYPE_UAP_MAC_ADDRESS);
1704 			mac_tlv->header.len =
1705 				wlan_cpu_to_le16(MLAN_MAC_ADDR_LENGTH);
1706 			ret = MLAN_STATUS_SUCCESS;
1707 			goto done;
1708 		}
1709 	}
1710 	if (pioctl_buf->req_id == MLAN_IOCTL_BSS) {
1711 		bss = (mlan_ds_bss *)pioctl_buf->pbuf;
1712 		if (bss->sub_command == MLAN_OID_BSS_MAC_ADDR) {
1713 			mac_tlv =
1714 				(MrvlIEtypes_MacAddr_t *)sys_config->tlv_buffer;
1715 			cmd->size = wlan_cpu_to_le16(
1716 				sizeof(HostCmd_DS_SYS_CONFIG) - 1 + S_DS_GEN +
1717 				sizeof(MrvlIEtypes_MacAddr_t));
1718 			mac_tlv->header.type =
1719 				wlan_cpu_to_le16(TLV_TYPE_UAP_MAC_ADDRESS);
1720 			mac_tlv->header.len =
1721 				wlan_cpu_to_le16(MLAN_MAC_ADDR_LENGTH);
1722 			if (cmd_action == HostCmd_ACT_GEN_SET)
1723 				memcpy_ext(pmpriv->adapter, mac_tlv->mac,
1724 					   &bss->param.mac_addr,
1725 					   MLAN_MAC_ADDR_LENGTH,
1726 					   MLAN_MAC_ADDR_LENGTH);
1727 		} else if (bss->sub_command == MLAN_OID_UAP_CFG_WMM_PARAM) {
1728 			tlv_wmm_parameter = (MrvlIEtypes_wmm_parameter_t *)
1729 						    sys_config->tlv_buffer;
1730 			cmd->size = wlan_cpu_to_le16(
1731 				sizeof(HostCmd_DS_SYS_CONFIG) - 1 + S_DS_GEN +
1732 				sizeof(MrvlIEtypes_wmm_parameter_t));
1733 			tlv_wmm_parameter->header.type =
1734 				wlan_cpu_to_le16(TLV_TYPE_AP_WMM_PARAM);
1735 			tlv_wmm_parameter->header.len = wlan_cpu_to_le16(
1736 				sizeof(bss->param.ap_wmm_para));
1737 			if (cmd_action == HostCmd_ACT_GEN_SET) {
1738 				for (ac = 0; ac < 4; ac++) {
1739 					tlv_wmm_parameter->wmm_para
1740 						.ac_params[ac]
1741 						.aci_aifsn.aifsn =
1742 						bss->param.ap_wmm_para
1743 							.ac_params[ac]
1744 							.aci_aifsn.aifsn;
1745 					tlv_wmm_parameter->wmm_para
1746 						.ac_params[ac]
1747 						.aci_aifsn.aci =
1748 						bss->param.ap_wmm_para
1749 							.ac_params[ac]
1750 							.aci_aifsn.aci;
1751 					tlv_wmm_parameter->wmm_para
1752 						.ac_params[ac]
1753 						.ecw.ecw_max =
1754 						bss->param.ap_wmm_para
1755 							.ac_params[ac]
1756 							.ecw.ecw_max;
1757 					tlv_wmm_parameter->wmm_para
1758 						.ac_params[ac]
1759 						.ecw.ecw_min =
1760 						bss->param.ap_wmm_para
1761 							.ac_params[ac]
1762 							.ecw.ecw_min;
1763 					tlv_wmm_parameter->wmm_para
1764 						.ac_params[ac]
1765 						.tx_op_limit = wlan_cpu_to_le16(
1766 						bss->param.ap_wmm_para
1767 							.ac_params[ac]
1768 							.tx_op_limit);
1769 				}
1770 			}
1771 		} else if (bss->sub_command == MLAN_OID_UAP_SCAN_CHANNELS) {
1772 			tlv_chan_list = (MrvlIEtypes_ChanListParamSet_t *)
1773 						sys_config->tlv_buffer;
1774 			tlv_chan_list->header.type =
1775 				wlan_cpu_to_le16(TLV_TYPE_CHANLIST);
1776 			if (bss->param.ap_scan_channels.num_of_chan &&
1777 			    bss->param.ap_scan_channels.num_of_chan <=
1778 				    MLAN_MAX_CHANNEL) {
1779 				cmd->size = wlan_cpu_to_le16(
1780 					sizeof(HostCmd_DS_SYS_CONFIG) - 1 +
1781 					S_DS_GEN +
1782 					sizeof(tlv_chan_list->header) +
1783 					sizeof(ChanScanParamSet_t) *
1784 						bss->param.ap_scan_channels
1785 							.num_of_chan);
1786 				tlv_chan_list->header.len = wlan_cpu_to_le16(
1787 					(t_u16)(sizeof(ChanScanParamSet_t) *
1788 						bss->param.ap_scan_channels
1789 							.num_of_chan));
1790 				pscan_chan = tlv_chan_list->chan_scan_param;
1791 				for (i = 0;
1792 				     i <
1793 				     bss->param.ap_scan_channels.num_of_chan;
1794 				     i++) {
1795 					pscan_chan->chan_number =
1796 						bss->param.ap_scan_channels
1797 							.chan_list[i]
1798 							.chan_number;
1799 					pscan_chan->bandcfg =
1800 						bss->param.ap_scan_channels
1801 							.chan_list[i]
1802 							.bandcfg;
1803 					pscan_chan++;
1804 				}
1805 				PRINTM(MCMND,
1806 				       "Set AP scan channel list =  %d\n",
1807 				       bss->param.ap_scan_channels.num_of_chan);
1808 			} else {
1809 				tlv_chan_list->header.len = wlan_cpu_to_le16(
1810 					(t_u16)(sizeof(ChanScanParamSet_t) *
1811 						MLAN_MAX_CHANNEL));
1812 				cmd->size = wlan_cpu_to_le16(
1813 					sizeof(HostCmd_DS_SYS_CONFIG) - 1 +
1814 					S_DS_GEN +
1815 					sizeof(MrvlIEtypes_ChanListParamSet_t) +
1816 					sizeof(ChanScanParamSet_t) *
1817 						MLAN_MAX_CHANNEL);
1818 			}
1819 		} else if (bss->sub_command == MLAN_OID_UAP_CHANNEL) {
1820 			chan_band_tlv = (MrvlIEtypes_channel_band_t *)
1821 						sys_config->tlv_buffer;
1822 			cmd->size = wlan_cpu_to_le16(
1823 				sizeof(HostCmd_DS_SYS_CONFIG) - 1 + S_DS_GEN +
1824 				sizeof(MrvlIEtypes_channel_band_t));
1825 			chan_band_tlv->header.type =
1826 				wlan_cpu_to_le16(TLV_TYPE_UAP_CHAN_BAND_CONFIG);
1827 			chan_band_tlv->header.len = wlan_cpu_to_le16(
1828 				sizeof(MrvlIEtypes_channel_band_t) -
1829 				sizeof(MrvlIEtypesHeader_t));
1830 			if (cmd_action == HostCmd_ACT_GEN_SET) {
1831 				chan_band_tlv->bandcfg =
1832 					bss->param.ap_channel.bandcfg;
1833 				chan_band_tlv->channel =
1834 					bss->param.ap_channel.channel;
1835 				PRINTM(MCMND,
1836 				       "Set AP channel, band=%d, channel=%d\n",
1837 				       bss->param.ap_channel.bandcfg,
1838 				       bss->param.ap_channel.channel);
1839 			}
1840 		} else if (bss->sub_command == MLAN_OID_ACTION_CHAN_SWITCH) {
1841 			cmd->size = sizeof(HostCmd_DS_SYS_CONFIG) - 1 +
1842 				    S_DS_GEN +
1843 				    sizeof(MrvlIEtypes_action_chan_switch_t);
1844 			tlv_chan_switch = (MrvlIEtypes_action_chan_switch_t *)
1845 						  sys_config->tlv_buffer;
1846 			tlv_chan_switch->header.type = wlan_cpu_to_le16(
1847 				MRVL_ACTION_CHAN_SWITCH_ANNOUNCE);
1848 			// mode reserve for future use
1849 			tlv_chan_switch->mode = 0;
1850 			tlv_chan_switch->num_pkt =
1851 				bss->param.chanswitch.chan_switch_count;
1852 			if (bss->param.chanswitch.new_oper_class) {
1853 				tlv_chan_switch->header.len = wlan_cpu_to_le16(
1854 					sizeof(MrvlIEtypes_action_chan_switch_t) -
1855 					sizeof(MrvlIEtypesHeader_t) +
1856 					sizeof(IEEEtypes_ExtChanSwitchAnn_t));
1857 				ecsa_ie = (IEEEtypes_ExtChanSwitchAnn_t *)
1858 						  tlv_chan_switch->ie_buf;
1859 				ecsa_ie->element_id = EXTEND_CHANNEL_SWITCH_ANN;
1860 				ecsa_ie->len =
1861 					sizeof(IEEEtypes_ExtChanSwitchAnn_t) -
1862 					sizeof(IEEEtypes_Header_t);
1863 				ecsa_ie->chan_switch_mode =
1864 					bss->param.chanswitch.chan_switch_mode;
1865 				ecsa_ie->chan_switch_count = 0;
1866 				ecsa_ie->new_channel_num =
1867 					bss->param.chanswitch.new_channel_num;
1868 				ecsa_ie->new_oper_class =
1869 					bss->param.chanswitch.new_oper_class;
1870 				cmd->size +=
1871 					sizeof(IEEEtypes_ExtChanSwitchAnn_t);
1872 			} else {
1873 				tlv_chan_switch->header.len = wlan_cpu_to_le16(
1874 					sizeof(MrvlIEtypes_action_chan_switch_t) -
1875 					sizeof(MrvlIEtypesHeader_t) +
1876 					sizeof(IEEEtypes_ChanSwitchAnn_t));
1877 				csa_ie = (IEEEtypes_ChanSwitchAnn_t *)
1878 						 tlv_chan_switch->ie_buf;
1879 				csa_ie->element_id = CHANNEL_SWITCH_ANN;
1880 				csa_ie->len =
1881 					sizeof(IEEEtypes_ChanSwitchAnn_t) -
1882 					sizeof(IEEEtypes_Header_t);
1883 				csa_ie->chan_switch_mode =
1884 					bss->param.chanswitch.chan_switch_mode;
1885 				csa_ie->chan_switch_count = 0;
1886 				csa_ie->new_channel_num =
1887 					bss->param.chanswitch.new_channel_num;
1888 				cmd->size += sizeof(IEEEtypes_ChanSwitchAnn_t);
1889 			}
1890 			cmd->size = wlan_cpu_to_le16(cmd->size);
1891 		} else if ((bss->sub_command == MLAN_OID_UAP_BSS_CONFIG) &&
1892 			   (cmd_action == HostCmd_ACT_GEN_SET)) {
1893 			ret = wlan_uap_cmd_ap_config(pmpriv, cmd, cmd_action,
1894 						     pioctl_buf);
1895 			goto done;
1896 		}
1897 	} else if (pioctl_buf->req_id == MLAN_IOCTL_MISC_CFG) {
1898 		misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
1899 		if ((misc->sub_command == MLAN_OID_MISC_GEN_IE) &&
1900 		    (misc->param.gen_ie.type == MLAN_IE_TYPE_GEN_IE)) {
1901 			cmd->size = wlan_cpu_to_le16(
1902 				sizeof(HostCmd_DS_SYS_CONFIG) - 1 + S_DS_GEN +
1903 				sizeof(MrvlIEtypesHeader_t) +
1904 				misc->param.gen_ie.len);
1905 			ie_header->type = wlan_cpu_to_le16(TLV_TYPE_WAPI_IE);
1906 			ie_header->len =
1907 				wlan_cpu_to_le16(misc->param.gen_ie.len);
1908 			if (cmd_action == HostCmd_ACT_GEN_SET)
1909 				memcpy_ext(pmpriv->adapter, ie,
1910 					   misc->param.gen_ie.ie_data,
1911 					   misc->param.gen_ie.len,
1912 					   misc->param.gen_ie.len);
1913 		}
1914 		if ((misc->sub_command == MLAN_OID_MISC_CUSTOM_IE) &&
1915 		    (misc->param.cust_ie.type == TLV_TYPE_MGMT_IE)) {
1916 			cmd->size = wlan_cpu_to_le16(
1917 				sizeof(HostCmd_DS_SYS_CONFIG) - 1 + S_DS_GEN +
1918 				sizeof(MrvlIEtypesHeader_t) +
1919 				misc->param.cust_ie.len);
1920 			ie_header->type = wlan_cpu_to_le16(TLV_TYPE_MGMT_IE);
1921 			ie_header->len =
1922 				wlan_cpu_to_le16(misc->param.cust_ie.len);
1923 
1924 			if (ie) {
1925 				req_len = misc->param.cust_ie.len;
1926 				travel_len = 0;
1927 				/* conversion for index, mask, len */
1928 				if (req_len == sizeof(t_u16))
1929 					misc->param.cust_ie.ie_data_list[0]
1930 						.ie_index = wlan_cpu_to_le16(
1931 						misc->param.cust_ie
1932 							.ie_data_list[0]
1933 							.ie_index);
1934 				while (req_len > sizeof(t_u16)) {
1935 					cptr = (custom_ie
1936 							*)(((t_u8 *)&misc->param
1937 								    .cust_ie
1938 								    .ie_data_list) +
1939 							   travel_len);
1940 					travel_len += cptr->ie_length +
1941 						      sizeof(custom_ie) -
1942 						      MAX_IE_SIZE;
1943 					req_len -= cptr->ie_length +
1944 						   sizeof(custom_ie) -
1945 						   MAX_IE_SIZE;
1946 					cptr->ie_index = wlan_cpu_to_le16(
1947 						cptr->ie_index);
1948 					cptr->mgmt_subtype_mask =
1949 						wlan_cpu_to_le16(
1950 							cptr->mgmt_subtype_mask);
1951 					cptr->ie_length = wlan_cpu_to_le16(
1952 						cptr->ie_length);
1953 				}
1954 				if (misc->param.cust_ie.len)
1955 					memcpy_ext(
1956 						pmpriv->adapter, ie,
1957 						misc->param.cust_ie.ie_data_list,
1958 						misc->param.cust_ie.len,
1959 						misc->param.cust_ie.len);
1960 			}
1961 		}
1962 		if (misc->sub_command == MLAN_OID_MISC_WACP_MODE) {
1963 			tlv_wacp_mode = (MrvlIEtypes_wacp_mode_t *)
1964 						sys_config->tlv_buffer;
1965 			tlv_wacp_mode->header.type =
1966 				wlan_cpu_to_le16(TLV_TYPE_UAP_WACP_MODE);
1967 			tlv_wacp_mode->header.len =
1968 				wlan_cpu_to_le16(sizeof(t_u8));
1969 			if (cmd_action == HostCmd_ACT_GEN_SET) {
1970 				tlv_wacp_mode->wacp_mode =
1971 					misc->param.wacp_mode;
1972 			}
1973 			cmd->size = wlan_cpu_to_le16(
1974 				sizeof(HostCmd_DS_SYS_CONFIG) - 1 + S_DS_GEN +
1975 				sizeof(MrvlIEtypes_wacp_mode_t));
1976 		}
1977 	}
1978 done:
1979 	LEAVE();
1980 	return ret;
1981 }
1982 
1983 /**
1984  *  @brief This function handles command resp for get uap settings
1985  *
1986  *  @param pmpriv       A pointer to mlan_private structure
1987  *  @param resp         A pointer to HostCmd_DS_COMMAND
1988  *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
1989  *
1990  *  @return             MLAN_STATUS_SUCCESS
1991  */
wlan_uap_ret_cmd_ap_config(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)1992 static mlan_status wlan_uap_ret_cmd_ap_config(pmlan_private pmpriv,
1993 					      HostCmd_DS_COMMAND *resp,
1994 					      mlan_ioctl_req *pioctl_buf)
1995 {
1996 	HostCmd_DS_SYS_CONFIG *sys_config =
1997 		(HostCmd_DS_SYS_CONFIG *)&resp->params.sys_config;
1998 	mlan_ds_bss *bss = MNULL;
1999 	MrvlIEtypesHeader_t *tlv = MNULL;
2000 	t_u16 tlv_buf_left = 0;
2001 	t_u16 tlv_type = 0;
2002 	t_u16 tlv_len = 0;
2003 	MrvlIEtypes_MacAddr_t *tlv_mac = MNULL;
2004 	MrvlIEtypes_SsIdParamSet_t *tlv_ssid = MNULL;
2005 	MrvlIEtypes_beacon_period_t *tlv_beacon_period = MNULL;
2006 	MrvlIEtypes_dtim_period_t *tlv_dtim_period = MNULL;
2007 	MrvlIEtypes_RatesParamSet_t *tlv_rates = MNULL;
2008 	MrvlIEtypes_tx_rate_t *tlv_txrate = MNULL;
2009 	MrvlIEtypes_mcbc_rate_t *tlv_mcbc_rate = MNULL;
2010 	MrvlIEtypes_tx_power_t *tlv_tx_power = MNULL;
2011 	MrvlIEtypes_bcast_ssid_t *tlv_bcast_ssid = MNULL;
2012 	MrvlIEtypes_antenna_mode_t *tlv_antenna = MNULL;
2013 	MrvlIEtypes_pkt_forward_t *tlv_pkt_forward = MNULL;
2014 	MrvlIEtypes_max_sta_count_t *tlv_sta_count = MNULL;
2015 	MrvlIEtypes_sta_ageout_t *tlv_sta_ageout = MNULL;
2016 	MrvlIEtypes_ps_sta_ageout_t *tlv_ps_sta_ageout = MNULL;
2017 	MrvlIEtypes_rts_threshold_t *tlv_rts_threshold = MNULL;
2018 	MrvlIEtypes_frag_threshold_t *tlv_frag_threshold = MNULL;
2019 	MrvlIEtypes_retry_limit_t *tlv_retry_limit = MNULL;
2020 	MrvlIEtypes_eapol_pwk_hsk_timeout_t *tlv_pairwise_timeout = MNULL;
2021 	MrvlIEtypes_eapol_pwk_hsk_retries_t *tlv_pairwise_retries = MNULL;
2022 	MrvlIEtypes_eapol_gwk_hsk_timeout_t *tlv_groupwise_timeout = MNULL;
2023 	MrvlIEtypes_eapol_gwk_hsk_retries_t *tlv_groupwise_retries = MNULL;
2024 	MrvlIEtypes_mgmt_ie_passthru_t *tlv_mgmt_ie_passthru = MNULL;
2025 	MrvlIEtypes_2040_coex_enable_t *tlv_2040_coex_enable = MNULL;
2026 	MrvlIEtypes_mac_filter_t *tlv_mac_filter = MNULL;
2027 	MrvlIEtypes_channel_band_t *tlv_chan_band = MNULL;
2028 	MrvlIEtypes_ChanListParamSet_t *tlv_chan_list = MNULL;
2029 	ChanScanParamSet_t *pscan_chan = MNULL;
2030 	MrvlIEtypes_auth_type_t *tlv_auth_type = MNULL;
2031 	MrvlIEtypes_encrypt_protocol_t *tlv_encrypt_protocol = MNULL;
2032 	MrvlIEtypes_akmp_t *tlv_akmp = MNULL;
2033 	MrvlIEtypes_pwk_cipher_t *tlv_pwk_cipher = MNULL;
2034 	MrvlIEtypes_gwk_cipher_t *tlv_gwk_cipher = MNULL;
2035 	MrvlIEtypes_rsn_replay_prot_t *tlv_rsn_prot = MNULL;
2036 	MrvlIEtypes_passphrase_t *tlv_passphrase = MNULL;
2037 #ifdef WIFI_DIRECT_SUPPORT
2038 	MrvlIEtypes_psk_t *tlv_psk = MNULL;
2039 #endif /* WIFI_DIRECT_SUPPORT */
2040 	MrvlIEtypes_group_rekey_time_t *tlv_rekey_time = MNULL;
2041 	MrvlIEtypes_wep_key_t *tlv_wep_key = MNULL;
2042 	MrvlIEtypes_preamble_t *tlv_preamble = MNULL;
2043 	MrvlIEtypes_bss_status_t *tlv_bss_status = MNULL;
2044 	MrvlIETypes_HTCap_t *tlv_htcap = MNULL;
2045 	MrvlIEtypes_wmm_parameter_t *tlv_wmm_parameter = MNULL;
2046 
2047 	wep_key *pkey = MNULL;
2048 	t_u16 i;
2049 	t_u16 ac;
2050 
2051 	ENTER();
2052 
2053 	bss = (mlan_ds_bss *)pioctl_buf->pbuf;
2054 	tlv = (MrvlIEtypesHeader_t *)sys_config->tlv_buffer;
2055 	tlv_buf_left =
2056 		resp->size - (sizeof(HostCmd_DS_SYS_CONFIG) - 1 + S_DS_GEN);
2057 
2058 	while (tlv_buf_left >= sizeof(MrvlIEtypesHeader_t)) {
2059 		tlv_type = wlan_le16_to_cpu(tlv->type);
2060 		tlv_len = wlan_le16_to_cpu(tlv->len);
2061 
2062 		if (tlv_buf_left < (tlv_len + sizeof(MrvlIEtypesHeader_t))) {
2063 			PRINTM(MERROR,
2064 			       "Error processing uAP sys config TLVs, bytes left < TLV length\n");
2065 			break;
2066 		}
2067 
2068 		switch (tlv_type) {
2069 		case TLV_TYPE_UAP_MAC_ADDRESS:
2070 			tlv_mac = (MrvlIEtypes_MacAddr_t *)tlv;
2071 			memcpy_ext(pmpriv->adapter,
2072 				   &bss->param.bss_config.mac_addr,
2073 				   tlv_mac->mac, MLAN_MAC_ADDR_LENGTH,
2074 				   MLAN_MAC_ADDR_LENGTH);
2075 			break;
2076 		case TLV_TYPE_SSID:
2077 			tlv_ssid = (MrvlIEtypes_SsIdParamSet_t *)tlv;
2078 			bss->param.bss_config.ssid.ssid_len =
2079 				MIN(MLAN_MAX_SSID_LENGTH, tlv_len);
2080 			memcpy_ext(pmpriv->adapter,
2081 				   bss->param.bss_config.ssid.ssid,
2082 				   tlv_ssid->ssid, tlv_len,
2083 				   MLAN_MAX_SSID_LENGTH);
2084 			break;
2085 		case TLV_TYPE_UAP_BEACON_PERIOD:
2086 			tlv_beacon_period = (MrvlIEtypes_beacon_period_t *)tlv;
2087 			bss->param.bss_config.beacon_period = wlan_le16_to_cpu(
2088 				tlv_beacon_period->beacon_period);
2089 			pmpriv->uap_state_chan_cb.beacon_period =
2090 				wlan_le16_to_cpu(
2091 					tlv_beacon_period->beacon_period);
2092 			break;
2093 		case TLV_TYPE_UAP_DTIM_PERIOD:
2094 			tlv_dtim_period = (MrvlIEtypes_dtim_period_t *)tlv;
2095 			bss->param.bss_config.dtim_period =
2096 				tlv_dtim_period->dtim_period;
2097 			pmpriv->uap_state_chan_cb.dtim_period =
2098 				tlv_dtim_period->dtim_period;
2099 			break;
2100 		case TLV_TYPE_RATES:
2101 			tlv_rates = (MrvlIEtypes_RatesParamSet_t *)tlv;
2102 			memcpy_ext(pmpriv->adapter, bss->param.bss_config.rates,
2103 				   tlv_rates->rates, tlv_len, MAX_DATA_RATES);
2104 			break;
2105 		case TLV_TYPE_UAP_TX_DATA_RATE:
2106 			tlv_txrate = (MrvlIEtypes_tx_rate_t *)tlv;
2107 			bss->param.bss_config.tx_data_rate =
2108 				wlan_le16_to_cpu(tlv_txrate->tx_data_rate);
2109 			break;
2110 		case TLV_TYPE_UAP_TX_BEACON_RATE:
2111 			tlv_txrate = (MrvlIEtypes_tx_rate_t *)tlv;
2112 			bss->param.bss_config.tx_beacon_rate =
2113 				wlan_le16_to_cpu(tlv_txrate->tx_data_rate);
2114 			break;
2115 		case TLV_TYPE_UAP_MCBC_DATA_RATE:
2116 			tlv_mcbc_rate = (MrvlIEtypes_mcbc_rate_t *)tlv;
2117 			bss->param.bss_config.mcbc_data_rate =
2118 				wlan_le16_to_cpu(tlv_mcbc_rate->mcbc_data_rate);
2119 			break;
2120 		case TLV_TYPE_UAP_TX_POWER:
2121 			tlv_tx_power = (MrvlIEtypes_tx_power_t *)tlv;
2122 			bss->param.bss_config.tx_power_level =
2123 				tlv_tx_power->tx_power;
2124 			break;
2125 		case TLV_TYPE_UAP_BCAST_SSID_CTL:
2126 			tlv_bcast_ssid = (MrvlIEtypes_bcast_ssid_t *)tlv;
2127 			bss->param.bss_config.bcast_ssid_ctl =
2128 				tlv_bcast_ssid->bcast_ssid_ctl;
2129 			break;
2130 		case TLV_TYPE_UAP_ANTENNA_CTL:
2131 			tlv_antenna = (MrvlIEtypes_antenna_mode_t *)tlv;
2132 			if (tlv_antenna->which_antenna == TX_ANTENNA)
2133 				bss->param.bss_config.tx_antenna =
2134 					tlv_antenna->antenna_mode;
2135 			else if (tlv_antenna->which_antenna == RX_ANTENNA)
2136 				bss->param.bss_config.rx_antenna =
2137 					tlv_antenna->antenna_mode;
2138 			break;
2139 		case TLV_TYPE_UAP_PKT_FWD_CTL:
2140 			tlv_pkt_forward = (MrvlIEtypes_pkt_forward_t *)tlv;
2141 			bss->param.bss_config.pkt_forward_ctl =
2142 				tlv_pkt_forward->pkt_forward_ctl;
2143 			break;
2144 		case TLV_TYPE_UAP_MAX_STA_CNT:
2145 			tlv_sta_count = (MrvlIEtypes_max_sta_count_t *)tlv;
2146 			bss->param.bss_config.max_sta_count =
2147 				wlan_le16_to_cpu(tlv_sta_count->max_sta_count);
2148 			break;
2149 		case TLV_TYPE_UAP_STA_AGEOUT_TIMER:
2150 			tlv_sta_ageout = (MrvlIEtypes_sta_ageout_t *)tlv;
2151 			bss->param.bss_config.sta_ageout_timer =
2152 				wlan_le32_to_cpu(
2153 					tlv_sta_ageout->sta_ageout_timer);
2154 			break;
2155 		case TLV_TYPE_UAP_PS_STA_AGEOUT_TIMER:
2156 			tlv_ps_sta_ageout = (MrvlIEtypes_ps_sta_ageout_t *)tlv;
2157 			bss->param.bss_config.ps_sta_ageout_timer =
2158 				wlan_le32_to_cpu(
2159 					tlv_ps_sta_ageout->ps_sta_ageout_timer);
2160 			break;
2161 		case TLV_TYPE_UAP_RTS_THRESHOLD:
2162 			tlv_rts_threshold = (MrvlIEtypes_rts_threshold_t *)tlv;
2163 			bss->param.bss_config.rts_threshold = wlan_le16_to_cpu(
2164 				tlv_rts_threshold->rts_threshold);
2165 			break;
2166 		case TLV_TYPE_UAP_FRAG_THRESHOLD:
2167 			tlv_frag_threshold =
2168 				(MrvlIEtypes_frag_threshold_t *)tlv;
2169 			bss->param.bss_config.frag_threshold = wlan_le16_to_cpu(
2170 				tlv_frag_threshold->frag_threshold);
2171 			break;
2172 		case TLV_TYPE_UAP_RETRY_LIMIT:
2173 			tlv_retry_limit = (MrvlIEtypes_retry_limit_t *)tlv;
2174 			bss->param.bss_config.retry_limit =
2175 				tlv_retry_limit->retry_limit;
2176 			break;
2177 		case TLV_TYPE_UAP_EAPOL_PWK_HSK_TIMEOUT:
2178 			tlv_pairwise_timeout =
2179 				(MrvlIEtypes_eapol_pwk_hsk_timeout_t *)tlv;
2180 			bss->param.bss_config
2181 				.pairwise_update_timeout = wlan_le32_to_cpu(
2182 				tlv_pairwise_timeout->pairwise_update_timeout);
2183 			break;
2184 		case TLV_TYPE_UAP_EAPOL_PWK_HSK_RETRIES:
2185 			tlv_pairwise_retries =
2186 				(MrvlIEtypes_eapol_pwk_hsk_retries_t *)tlv;
2187 			bss->param.bss_config.pwk_retries = wlan_le32_to_cpu(
2188 				tlv_pairwise_retries->pwk_retries);
2189 			break;
2190 		case TLV_TYPE_UAP_EAPOL_GWK_HSK_TIMEOUT:
2191 			tlv_groupwise_timeout =
2192 				(MrvlIEtypes_eapol_gwk_hsk_timeout_t *)tlv;
2193 			bss->param.bss_config.groupwise_update_timeout =
2194 				wlan_le32_to_cpu(
2195 					tlv_groupwise_timeout
2196 						->groupwise_update_timeout);
2197 			break;
2198 		case TLV_TYPE_UAP_EAPOL_GWK_HSK_RETRIES:
2199 			tlv_groupwise_retries =
2200 				(MrvlIEtypes_eapol_gwk_hsk_retries_t *)tlv;
2201 			bss->param.bss_config.gwk_retries = wlan_le32_to_cpu(
2202 				tlv_groupwise_retries->gwk_retries);
2203 			break;
2204 		case TLV_TYPE_UAP_MGMT_IE_PASSTHRU_MASK:
2205 			tlv_mgmt_ie_passthru =
2206 				(MrvlIEtypes_mgmt_ie_passthru_t *)tlv;
2207 			bss->param.bss_config.mgmt_ie_passthru_mask =
2208 				wlan_le32_to_cpu(
2209 					tlv_mgmt_ie_passthru->mgmt_ie_mask);
2210 			break;
2211 		case TLV_TYPE_2040_BSS_COEX_CONTROL:
2212 			tlv_2040_coex_enable =
2213 				(MrvlIEtypes_2040_coex_enable_t *)tlv;
2214 			bss->param.bss_config.enable_2040coex =
2215 				tlv_2040_coex_enable->enable_2040coex;
2216 			break;
2217 		case TLV_TYPE_UAP_STA_MAC_ADDR_FILTER:
2218 			tlv_mac_filter = (MrvlIEtypes_mac_filter_t *)tlv;
2219 			bss->param.bss_config.filter.mac_count =
2220 				MIN(MAX_MAC_FILTER_NUM, tlv_mac_filter->count);
2221 			bss->param.bss_config.filter.filter_mode =
2222 				tlv_mac_filter->filter_mode;
2223 			memcpy_ext(
2224 				pmpriv->adapter,
2225 				(t_u8 *)bss->param.bss_config.filter.mac_list,
2226 				tlv_mac_filter->mac_address,
2227 				MLAN_MAC_ADDR_LENGTH *
2228 					bss->param.bss_config.filter.mac_count,
2229 				sizeof(bss->param.bss_config.filter.mac_list));
2230 			break;
2231 		case TLV_TYPE_UAP_CHAN_BAND_CONFIG:
2232 			tlv_chan_band = (MrvlIEtypes_channel_band_t *)tlv;
2233 			bss->param.bss_config.bandcfg = tlv_chan_band->bandcfg;
2234 			bss->param.bss_config.channel = tlv_chan_band->channel;
2235 			pmpriv->uap_channel = tlv_chan_band->channel;
2236 			pmpriv->uap_bandwidth =
2237 				tlv_chan_band->bandcfg.chanWidth;
2238 			pmpriv->uap_state_chan_cb.bandcfg =
2239 				tlv_chan_band->bandcfg;
2240 			pmpriv->uap_state_chan_cb.channel =
2241 				tlv_chan_band->channel;
2242 			break;
2243 		case TLV_TYPE_CHANLIST:
2244 			tlv_chan_list = (MrvlIEtypes_ChanListParamSet_t *)tlv;
2245 			bss->param.bss_config.num_of_chan =
2246 				tlv_len / sizeof(ChanScanParamSet_t);
2247 			pscan_chan = tlv_chan_list->chan_scan_param;
2248 			for (i = 0; i < bss->param.bss_config.num_of_chan;
2249 			     i++) {
2250 				bss->param.bss_config.chan_list[i].chan_number =
2251 					pscan_chan->chan_number;
2252 				bss->param.bss_config.chan_list[i].bandcfg =
2253 					pscan_chan->bandcfg;
2254 				pscan_chan++;
2255 			}
2256 			break;
2257 		case TLV_TYPE_AUTH_TYPE:
2258 			tlv_auth_type = (MrvlIEtypes_auth_type_t *)tlv;
2259 			bss->param.bss_config.auth_mode =
2260 				tlv_auth_type->auth_type;
2261 			if (tlv_len == (sizeof(MrvlIEtypes_auth_type_t) -
2262 					sizeof(MrvlIEtypesHeader_t))) {
2263 				bss->param.bss_config.pwe_derivation =
2264 					tlv_auth_type->PWE_derivation;
2265 				bss->param.bss_config.transition_disable =
2266 					tlv_auth_type->transition_disable;
2267 			}
2268 			break;
2269 		case TLV_TYPE_UAP_ENCRYPT_PROTOCOL:
2270 			tlv_encrypt_protocol =
2271 				(MrvlIEtypes_encrypt_protocol_t *)tlv;
2272 			bss->param.bss_config.protocol = wlan_le16_to_cpu(
2273 				tlv_encrypt_protocol->protocol);
2274 			break;
2275 		case TLV_TYPE_UAP_AKMP:
2276 			tlv_akmp = (MrvlIEtypes_akmp_t *)tlv;
2277 			bss->param.bss_config.key_mgmt =
2278 				wlan_le16_to_cpu(tlv_akmp->key_mgmt);
2279 			if (tlv_len > sizeof(t_u16))
2280 				bss->param.bss_config.key_mgmt_operation =
2281 					wlan_le16_to_cpu(
2282 						tlv_akmp->key_mgmt_operation);
2283 			break;
2284 		case TLV_TYPE_PWK_CIPHER:
2285 			tlv_pwk_cipher = (MrvlIEtypes_pwk_cipher_t *)tlv;
2286 			if (wlan_le16_to_cpu(tlv_pwk_cipher->protocol) &
2287 			    PROTOCOL_WPA)
2288 				bss->param.bss_config.wpa_cfg
2289 					.pairwise_cipher_wpa =
2290 					tlv_pwk_cipher->pairwise_cipher;
2291 			if (wlan_le16_to_cpu(tlv_pwk_cipher->protocol) &
2292 			    PROTOCOL_WPA2)
2293 				bss->param.bss_config.wpa_cfg
2294 					.pairwise_cipher_wpa2 =
2295 					tlv_pwk_cipher->pairwise_cipher;
2296 			if (wlan_le16_to_cpu(tlv_pwk_cipher->protocol) &
2297 			    PROTOCOL_WPA3_SAE)
2298 				bss->param.bss_config.wpa_cfg
2299 					.pairwise_cipher_wpa2 =
2300 					tlv_pwk_cipher->pairwise_cipher;
2301 			break;
2302 		case TLV_TYPE_GWK_CIPHER:
2303 			tlv_gwk_cipher = (MrvlIEtypes_gwk_cipher_t *)tlv;
2304 			bss->param.bss_config.wpa_cfg.group_cipher =
2305 				tlv_gwk_cipher->group_cipher;
2306 			break;
2307 		case TLV_TYPE_UAP_RSN_REPLAY_PROTECT:
2308 			tlv_rsn_prot = (MrvlIEtypes_rsn_replay_prot_t *)tlv;
2309 			bss->param.bss_config.wpa_cfg.rsn_protection =
2310 				tlv_rsn_prot->rsn_replay_prot;
2311 			break;
2312 		case TLV_TYPE_UAP_WPA_PASSPHRASE:
2313 			tlv_passphrase = (MrvlIEtypes_passphrase_t *)tlv;
2314 			bss->param.bss_config.wpa_cfg.length =
2315 				MIN(MLAN_PMK_HEXSTR_LENGTH, tlv_len);
2316 			memcpy_ext(pmpriv->adapter,
2317 				   bss->param.bss_config.wpa_cfg.passphrase,
2318 				   tlv_passphrase->passphrase,
2319 				   bss->param.bss_config.wpa_cfg.length,
2320 				   sizeof(bss->param.bss_config.wpa_cfg
2321 						  .passphrase));
2322 			break;
2323 #ifdef WIFI_DIRECT_SUPPORT
2324 		case TLV_TYPE_UAP_PSK:
2325 			tlv_psk = (MrvlIEtypes_psk_t *)tlv;
2326 			memcpy_ext(pmpriv->adapter, bss->param.bss_config.psk,
2327 				   tlv_psk->psk, tlv_len, MLAN_MAX_KEY_LENGTH);
2328 			break;
2329 #endif /* WIFI_DIRECT_SUPPORT */
2330 		case TLV_TYPE_UAP_GRP_REKEY_TIME:
2331 			tlv_rekey_time = (MrvlIEtypes_group_rekey_time_t *)tlv;
2332 			bss->param.bss_config.wpa_cfg.gk_rekey_time =
2333 				wlan_le32_to_cpu(tlv_rekey_time->gk_rekey_time);
2334 			break;
2335 		case TLV_TYPE_UAP_WEP_KEY:
2336 			tlv_wep_key = (MrvlIEtypes_wep_key_t *)tlv;
2337 			pkey = MNULL;
2338 			if (tlv_wep_key->key_index == 0)
2339 				pkey = &bss->param.bss_config.wep_cfg.key0;
2340 			else if (tlv_wep_key->key_index == 1)
2341 				pkey = &bss->param.bss_config.wep_cfg.key1;
2342 			else if (tlv_wep_key->key_index == 2)
2343 				pkey = &bss->param.bss_config.wep_cfg.key2;
2344 			else if (tlv_wep_key->key_index == 3)
2345 				pkey = &bss->param.bss_config.wep_cfg.key3;
2346 			if (pkey) {
2347 				pkey->key_index = tlv_wep_key->key_index;
2348 				pkey->is_default = tlv_wep_key->is_default;
2349 				pkey->length =
2350 					MIN(MAX_WEP_KEY_SIZE, (tlv_len - 2));
2351 				memcpy_ext(pmpriv->adapter, pkey->key,
2352 					   tlv_wep_key->key, pkey->length,
2353 					   pkey->length);
2354 			}
2355 			break;
2356 		case TLV_TYPE_UAP_PREAMBLE_CTL:
2357 			tlv_preamble = (MrvlIEtypes_preamble_t *)tlv;
2358 			bss->param.bss_config.preamble_type =
2359 				tlv_preamble->preamble_type;
2360 			break;
2361 		case TLV_TYPE_BSS_STATUS:
2362 			tlv_bss_status = (MrvlIEtypes_bss_status_t *)tlv;
2363 			bss->param.bss_config.bss_status =
2364 				wlan_le16_to_cpu(tlv_bss_status->bss_status);
2365 			pmpriv->uap_bss_started =
2366 				(bss->param.bss_config.bss_status) ? MTRUE :
2367 								     MFALSE;
2368 			break;
2369 		case TLV_TYPE_HT_CAPABILITY:
2370 			tlv_htcap = (MrvlIETypes_HTCap_t *)tlv;
2371 			bss->param.bss_config.ht_cap_info =
2372 				wlan_le16_to_cpu(tlv_htcap->ht_cap.ht_cap_info);
2373 			bss->param.bss_config.ampdu_param =
2374 				tlv_htcap->ht_cap.ampdu_param;
2375 			memcpy_ext(
2376 				pmpriv->adapter,
2377 				bss->param.bss_config.supported_mcs_set,
2378 				tlv_htcap->ht_cap.supported_mcs_set, 16,
2379 				sizeof(bss->param.bss_config.supported_mcs_set));
2380 			bss->param.bss_config.ht_ext_cap =
2381 				wlan_le16_to_cpu(tlv_htcap->ht_cap.ht_ext_cap);
2382 			bss->param.bss_config.tx_bf_cap =
2383 				wlan_le32_to_cpu(tlv_htcap->ht_cap.tx_bf_cap);
2384 			bss->param.bss_config.asel = tlv_htcap->ht_cap.asel;
2385 			break;
2386 		case TLV_TYPE_VENDOR_SPECIFIC_IE:
2387 			tlv_wmm_parameter = (MrvlIEtypes_wmm_parameter_t *)tlv;
2388 			bss->param.bss_config.wmm_para.qos_info =
2389 				tlv_wmm_parameter->wmm_para.qos_info;
2390 			for (ac = 0; ac < 4; ac++) {
2391 				bss->param.bss_config.wmm_para.ac_params[ac]
2392 					.aci_aifsn.aifsn =
2393 					tlv_wmm_parameter->wmm_para
2394 						.ac_params[ac]
2395 						.aci_aifsn.aifsn;
2396 				bss->param.bss_config.wmm_para.ac_params[ac]
2397 					.aci_aifsn.aci =
2398 					tlv_wmm_parameter->wmm_para
2399 						.ac_params[ac]
2400 						.aci_aifsn.aci;
2401 				bss->param.bss_config.wmm_para.ac_params[ac]
2402 					.ecw.ecw_max =
2403 					tlv_wmm_parameter->wmm_para
2404 						.ac_params[ac]
2405 						.ecw.ecw_max;
2406 				bss->param.bss_config.wmm_para.ac_params[ac]
2407 					.ecw.ecw_min =
2408 					tlv_wmm_parameter->wmm_para
2409 						.ac_params[ac]
2410 						.ecw.ecw_min;
2411 				bss->param.bss_config.wmm_para.ac_params[ac]
2412 					.tx_op_limit = wlan_le16_to_cpu(
2413 					tlv_wmm_parameter->wmm_para
2414 						.ac_params[ac]
2415 						.tx_op_limit);
2416 			}
2417 			break;
2418 		}
2419 
2420 		tlv_buf_left -= tlv_len + sizeof(MrvlIEtypesHeader_t);
2421 		tlv = (MrvlIEtypesHeader_t *)((t_u8 *)tlv + tlv_len +
2422 					      sizeof(MrvlIEtypesHeader_t));
2423 	}
2424 #ifdef DRV_EMBEDDED_AUTHENTICATOR
2425 	if (!IS_FW_SUPPORT_AUTHENTICATOR(pmpriv->adapter))
2426 		AuthenticatorBssConfig(pmpriv->psapriv,
2427 				       (t_u8 *)&bss->param.bss_config, 0, 0, 1);
2428 #endif
2429 	LEAVE();
2430 	return MLAN_STATUS_SUCCESS;
2431 }
2432 
2433 /**
2434  *  @brief This function handles the command response of sys_reset
2435  *         Clear various private state variables used by DFS.
2436  *
2437  *  @param pmpriv       A pointer to mlan_private structure
2438  *  @param resp         A pointer to HostCmd_DS_COMMAND
2439  *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
2440  *
2441  *  @return             MLAN_STATUS_SUCCESS
2442  */
wlan_uap_ret_sys_reset(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)2443 static mlan_status wlan_uap_ret_sys_reset(pmlan_private pmpriv,
2444 					  HostCmd_DS_COMMAND *resp,
2445 					  mlan_ioctl_req *pioctl_buf)
2446 {
2447 	ENTER();
2448 
2449 	memset(pmpriv->adapter, &(pmpriv->uap_state_chan_cb.bandcfg), 0,
2450 	       sizeof(pmpriv->uap_state_chan_cb.bandcfg));
2451 	pmpriv->uap_state_chan_cb.channel = 0;
2452 	pmpriv->uap_state_chan_cb.beacon_period = 0;
2453 	pmpriv->uap_state_chan_cb.dtim_period = 0;
2454 
2455 	/* assume default 11d/11h states are off, should check with FW */
2456 	/* currently don't clear domain_info... global, could be from STA */
2457 	wlan_11d_priv_init(pmpriv);
2458 	wlan_11h_priv_init(pmpriv);
2459 
2460 	LEAVE();
2461 	return MLAN_STATUS_SUCCESS;
2462 }
2463 
2464 /**
2465  *  @brief This function handles the command response of sys_config
2466  *
2467  *  @param pmpriv       A pointer to mlan_private structure
2468  *  @param resp         A pointer to HostCmd_DS_COMMAND
2469  *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
2470  *
2471  *  @return             MLAN_STATUS_SUCCESS
2472  */
wlan_uap_ret_sys_config(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)2473 static mlan_status wlan_uap_ret_sys_config(pmlan_private pmpriv,
2474 					   HostCmd_DS_COMMAND *resp,
2475 					   mlan_ioctl_req *pioctl_buf)
2476 {
2477 	int resp_len = 0, travel_len = 0;
2478 	t_u32 i = 0;
2479 	custom_ie *cptr;
2480 	HostCmd_DS_SYS_CONFIG *sys_config =
2481 		(HostCmd_DS_SYS_CONFIG *)&resp->params.sys_config;
2482 	mlan_ds_bss *bss = MNULL;
2483 	mlan_ds_misc_cfg *misc = MNULL;
2484 	MrvlIEtypes_MacAddr_t *tlv =
2485 		(MrvlIEtypes_MacAddr_t *)sys_config->tlv_buffer;
2486 	mlan_ds_misc_custom_ie *cust_ie = MNULL;
2487 	tlvbuf_max_mgmt_ie *max_mgmt_ie = MNULL;
2488 	MrvlIEtypes_wmm_parameter_t *tlv_wmm_parameter =
2489 		(MrvlIEtypes_wmm_parameter_t *)sys_config->tlv_buffer;
2490 	MrvlIEtypes_ChanListParamSet_t *tlv_chan_list =
2491 		(MrvlIEtypes_ChanListParamSet_t *)sys_config->tlv_buffer;
2492 	MrvlIEtypes_channel_band_t *chan_band_tlv =
2493 		(MrvlIEtypes_channel_band_t *)sys_config->tlv_buffer;
2494 	ChanScanParamSet_t *pscan_chan = MNULL;
2495 	t_u8 ac = 0;
2496 	MrvlIEtypes_channel_band_t *tlv_cb = MNULL;
2497 	MrvlIEtypes_beacon_period_t *tlv_bcnpd = MNULL;
2498 	MrvlIEtypes_dtim_period_t *tlv_dtimpd = MNULL;
2499 	MrvlIEtypes_uap_max_sta_cnt_t *tlv_uap_max_sta = MNULL;
2500 
2501 	ENTER();
2502 	sys_config->action = wlan_le16_to_cpu(sys_config->action);
2503 
2504 	if (pioctl_buf) {
2505 		if (pioctl_buf->req_id == MLAN_IOCTL_BSS) {
2506 			bss = (mlan_ds_bss *)pioctl_buf->pbuf;
2507 			if (bss->sub_command == MLAN_OID_BSS_MAC_ADDR) {
2508 				if (TLV_TYPE_UAP_MAC_ADDRESS ==
2509 				    wlan_le16_to_cpu(tlv->header.type)) {
2510 					memcpy_ext(pmpriv->adapter,
2511 						   &bss->param.mac_addr,
2512 						   tlv->mac,
2513 						   MLAN_MAC_ADDR_LENGTH,
2514 						   MLAN_MAC_ADDR_LENGTH);
2515 				}
2516 			} else if (bss->sub_command ==
2517 				   MLAN_OID_UAP_CFG_WMM_PARAM) {
2518 				if (TLV_TYPE_AP_WMM_PARAM ==
2519 				    wlan_le16_to_cpu(
2520 					    tlv_wmm_parameter->header.type)) {
2521 					if (wlan_le16_to_cpu(
2522 						    tlv_wmm_parameter->header
2523 							    .len) <
2524 					    sizeof(bss->param.ap_wmm_para)) {
2525 						PRINTM(MCMND,
2526 						       "FW don't support AP WMM PARAM\n");
2527 					} else {
2528 						bss->param.ap_wmm_para.reserved =
2529 							MLAN_STATUS_COMPLETE;
2530 						for (ac = 0; ac < 4; ac++) {
2531 							bss->param.ap_wmm_para
2532 								.ac_params[ac]
2533 								.aci_aifsn
2534 								.aifsn =
2535 								tlv_wmm_parameter
2536 									->wmm_para
2537 									.ac_params
2538 										[ac]
2539 									.aci_aifsn
2540 									.aifsn;
2541 							bss->param.ap_wmm_para
2542 								.ac_params[ac]
2543 								.aci_aifsn.aci =
2544 								tlv_wmm_parameter
2545 									->wmm_para
2546 									.ac_params
2547 										[ac]
2548 									.aci_aifsn
2549 									.aci;
2550 							bss->param.ap_wmm_para
2551 								.ac_params[ac]
2552 								.ecw.ecw_max =
2553 								tlv_wmm_parameter
2554 									->wmm_para
2555 									.ac_params
2556 										[ac]
2557 									.ecw
2558 									.ecw_max;
2559 							bss->param.ap_wmm_para
2560 								.ac_params[ac]
2561 								.ecw.ecw_min =
2562 								tlv_wmm_parameter
2563 									->wmm_para
2564 									.ac_params
2565 										[ac]
2566 									.ecw
2567 									.ecw_min;
2568 							bss->param.ap_wmm_para
2569 								.ac_params[ac]
2570 								.tx_op_limit = wlan_le16_to_cpu(
2571 								tlv_wmm_parameter
2572 									->wmm_para
2573 									.ac_params
2574 										[ac]
2575 									.tx_op_limit);
2576 							PRINTM(MCMND,
2577 							       "ac=%d, aifsn=%d, aci=%d, ecw_max=%d, ecw_min=%d, tx_op=%d\n",
2578 							       ac,
2579 							       bss->param
2580 								       .ap_wmm_para
2581 								       .ac_params
2582 									       [ac]
2583 								       .aci_aifsn
2584 								       .aifsn,
2585 							       bss->param
2586 								       .ap_wmm_para
2587 								       .ac_params
2588 									       [ac]
2589 								       .aci_aifsn
2590 								       .aci,
2591 							       bss->param
2592 								       .ap_wmm_para
2593 								       .ac_params
2594 									       [ac]
2595 								       .ecw
2596 								       .ecw_max,
2597 							       bss->param
2598 								       .ap_wmm_para
2599 								       .ac_params
2600 									       [ac]
2601 								       .ecw
2602 								       .ecw_min,
2603 							       bss->param
2604 								       .ap_wmm_para
2605 								       .ac_params
2606 									       [ac]
2607 								       .tx_op_limit);
2608 						}
2609 					}
2610 				}
2611 			} else if (bss->sub_command ==
2612 				   MLAN_OID_UAP_SCAN_CHANNELS) {
2613 				if (TLV_TYPE_CHANLIST ==
2614 				    wlan_le16_to_cpu(
2615 					    tlv_chan_list->header.type)) {
2616 					pscan_chan =
2617 						tlv_chan_list->chan_scan_param;
2618 					bss->param.ap_scan_channels.num_of_chan =
2619 						0;
2620 					for (i = 0;
2621 					     i <
2622 					     (int)wlan_le16_to_cpu(
2623 						     tlv_chan_list->header.len) /
2624 						     sizeof(ChanScanParamSet_t);
2625 					     i++) {
2626 						if (bss->param.ap_scan_channels
2627 							    .remove_nop_channel &&
2628 						    wlan_11h_is_channel_under_nop(
2629 							    pmpriv->adapter,
2630 							    pscan_chan
2631 								    ->chan_number)) {
2632 							bss->param
2633 								.ap_scan_channels
2634 								.num_remvoed_channel++;
2635 							PRINTM(MCMND,
2636 							       "Remove nop channel=%d\n",
2637 							       pscan_chan
2638 								       ->chan_number);
2639 							pscan_chan++;
2640 							continue;
2641 						}
2642 						bss->param.ap_scan_channels
2643 							.chan_list
2644 								[bss->param
2645 									 .ap_scan_channels
2646 									 .num_of_chan]
2647 							.chan_number =
2648 							pscan_chan->chan_number;
2649 						bss->param.ap_scan_channels
2650 							.chan_list
2651 								[bss->param
2652 									 .ap_scan_channels
2653 									 .num_of_chan]
2654 							.bandcfg =
2655 							pscan_chan->bandcfg;
2656 						bss->param.ap_scan_channels
2657 							.num_of_chan++;
2658 						pscan_chan++;
2659 					}
2660 					PRINTM(MCMND,
2661 					       "AP scan channel list=%d\n",
2662 					       bss->param.ap_scan_channels
2663 						       .num_of_chan);
2664 				}
2665 			} else if (bss->sub_command == MLAN_OID_UAP_CHANNEL) {
2666 				if (TLV_TYPE_UAP_CHAN_BAND_CONFIG ==
2667 				    wlan_le16_to_cpu(
2668 					    chan_band_tlv->header.type)) {
2669 					bss->param.ap_channel.bandcfg =
2670 						chan_band_tlv->bandcfg;
2671 					bss->param.ap_channel.channel =
2672 						chan_band_tlv->channel;
2673 					bss->param.ap_channel.is_11n_enabled =
2674 						pmpriv->is_11n_enabled;
2675 					pmpriv->uap_channel =
2676 						chan_band_tlv->channel;
2677 					pmpriv->uap_bandwidth =
2678 						chan_band_tlv->bandcfg.chanWidth;
2679 					pmpriv->uap_state_chan_cb.bandcfg =
2680 						chan_band_tlv->bandcfg;
2681 					pmpriv->uap_state_chan_cb.channel =
2682 						chan_band_tlv->channel;
2683 					bss->param.ap_channel.is_dfs_chan =
2684 						wlan_11h_radar_detect_required(
2685 							pmpriv,
2686 							bss->param.ap_channel
2687 								.channel);
2688 					if (chan_band_tlv->bandcfg.chanWidth ==
2689 					    CHAN_BW_80MHZ)
2690 						bss->param.ap_channel
2691 							.center_chan =
2692 							wlan_get_center_freq_idx(
2693 								pmpriv,
2694 								BAND_AAC,
2695 								chan_band_tlv
2696 									->channel,
2697 								CHANNEL_BW_80MHZ);
2698 					PRINTM(MCMND,
2699 					       "AP channel, band=0x%x, channel=%d, is_11n_enabled=%d center_chan=%d\n",
2700 					       bss->param.ap_channel.bandcfg,
2701 					       bss->param.ap_channel.channel,
2702 					       bss->param.ap_channel
2703 						       .is_11n_enabled,
2704 					       bss->param.ap_channel
2705 						       .center_chan);
2706 				}
2707 			} else if ((bss->sub_command ==
2708 				    MLAN_OID_UAP_BSS_CONFIG) &&
2709 				   (pioctl_buf->action == MLAN_ACT_GET)) {
2710 				wlan_uap_ret_cmd_ap_config(pmpriv, resp,
2711 							   pioctl_buf);
2712 			}
2713 		}
2714 		if (pioctl_buf->req_id == MLAN_IOCTL_MISC_CFG) {
2715 			misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
2716 			cust_ie = (mlan_ds_misc_custom_ie *)
2717 					  sys_config->tlv_buffer;
2718 			if ((pioctl_buf->action == MLAN_ACT_GET ||
2719 			     pioctl_buf->action == MLAN_ACT_SET) &&
2720 			    (misc->sub_command == MLAN_OID_MISC_CUSTOM_IE)) {
2721 				cust_ie->type = wlan_le16_to_cpu(cust_ie->type);
2722 				resp_len = cust_ie->len =
2723 					wlan_le16_to_cpu(cust_ie->len);
2724 				travel_len = 0;
2725 				/* conversion for index, mask, len */
2726 				if (resp_len == sizeof(t_u16))
2727 					cust_ie->ie_data_list[0].ie_index =
2728 						wlan_cpu_to_le16(
2729 							cust_ie->ie_data_list[0]
2730 								.ie_index);
2731 
2732 				while (resp_len > (int)sizeof(t_u16)) {
2733 					cptr = (custom_ie
2734 							*)(((t_u8 *)cust_ie
2735 								    ->ie_data_list) +
2736 							   travel_len);
2737 					cptr->ie_index = wlan_le16_to_cpu(
2738 						cptr->ie_index);
2739 					cptr->mgmt_subtype_mask =
2740 						wlan_le16_to_cpu(
2741 							cptr->mgmt_subtype_mask);
2742 					cptr->ie_length = wlan_le16_to_cpu(
2743 						cptr->ie_length);
2744 					travel_len += cptr->ie_length +
2745 						      sizeof(custom_ie) -
2746 						      MAX_IE_SIZE;
2747 					resp_len -= cptr->ie_length +
2748 						    sizeof(custom_ie) -
2749 						    MAX_IE_SIZE;
2750 				}
2751 				memcpy_ext(pmpriv->adapter,
2752 					   &misc->param.cust_ie, cust_ie,
2753 					   cust_ie->len +
2754 						   sizeof(MrvlIEtypesHeader_t),
2755 					   sizeof(mlan_ds_misc_custom_ie) -
2756 						   sizeof(tlvbuf_max_mgmt_ie));
2757 				max_mgmt_ie =
2758 					(tlvbuf_max_mgmt_ie
2759 						 *)(sys_config->tlv_buffer +
2760 						    cust_ie->len +
2761 						    sizeof(MrvlIEtypesHeader_t));
2762 				if (max_mgmt_ie) {
2763 					max_mgmt_ie->type = wlan_le16_to_cpu(
2764 						max_mgmt_ie->type);
2765 					if (max_mgmt_ie->type ==
2766 					    TLV_TYPE_MAX_MGMT_IE) {
2767 						max_mgmt_ie->len =
2768 							wlan_le16_to_cpu(
2769 								max_mgmt_ie
2770 									->len);
2771 						max_mgmt_ie->count =
2772 							wlan_le16_to_cpu(
2773 								max_mgmt_ie
2774 									->count);
2775 						for (i = 0;
2776 						     i < max_mgmt_ie->count;
2777 						     i++) {
2778 							max_mgmt_ie->info[i]
2779 								.buf_size = wlan_le16_to_cpu(
2780 								max_mgmt_ie
2781 									->info[i]
2782 									.buf_size);
2783 							max_mgmt_ie->info[i]
2784 								.buf_count = wlan_le16_to_cpu(
2785 								max_mgmt_ie
2786 									->info[i]
2787 									.buf_count);
2788 						}
2789 						/* Append max_mgmt_ie TLV after
2790 						 * custom_ie */
2791 						memcpy_ext(
2792 							pmpriv->adapter,
2793 							(t_u8 *)&misc->param
2794 									.cust_ie +
2795 								(cust_ie->len +
2796 								 sizeof(MrvlIEtypesHeader_t)),
2797 							max_mgmt_ie,
2798 							max_mgmt_ie->len +
2799 								sizeof(MrvlIEtypesHeader_t),
2800 							sizeof(tlvbuf_max_mgmt_ie));
2801 					}
2802 				}
2803 			}
2804 		}
2805 	} else { /* no ioctl: driver generated get/set */
2806 		switch (wlan_le16_to_cpu(tlv->header.type)) {
2807 		case TLV_TYPE_UAP_MAC_ADDRESS:
2808 			if (sys_config->action == HostCmd_ACT_GEN_SET) {
2809 				memcpy_ext(pmpriv->adapter, pmpriv->curr_addr,
2810 					   tlv->mac, MLAN_MAC_ADDR_LENGTH,
2811 					   MLAN_MAC_ADDR_LENGTH);
2812 			}
2813 			break;
2814 		case TLV_TYPE_UAP_MAX_STA_CNT_PER_CHIP:
2815 			tlv_uap_max_sta = (MrvlIEtypes_uap_max_sta_cnt_t *)tlv;
2816 			pmpriv->adapter->max_sta_conn =
2817 				wlan_le16_to_cpu(tlv_uap_max_sta->uap_max_sta);
2818 			PRINTM(MCMND, "Uap max_sta per chip=%d\n",
2819 			       wlan_le16_to_cpu(tlv_uap_max_sta->uap_max_sta));
2820 			break;
2821 		case TLV_TYPE_UAP_CHAN_BAND_CONFIG:
2822 			tlv_cb = (MrvlIEtypes_channel_band_t *)tlv;
2823 			pmpriv->uap_state_chan_cb.bandcfg = tlv_cb->bandcfg;
2824 			pmpriv->uap_state_chan_cb.channel = tlv_cb->channel;
2825 			/* call callback waiting for channel info */
2826 			if (pmpriv->uap_state_chan_cb.get_chan_callback)
2827 				pmpriv->uap_state_chan_cb.get_chan_callback(
2828 					pmpriv);
2829 			break;
2830 		case TLV_TYPE_UAP_BEACON_PERIOD:
2831 			tlv_bcnpd = (MrvlIEtypes_beacon_period_t *)tlv;
2832 			pmpriv->uap_state_chan_cb.beacon_period =
2833 				wlan_le16_to_cpu(tlv_bcnpd->beacon_period);
2834 			/* copy dtim_period as well if it follows */
2835 			tlv_dtimpd =
2836 				(MrvlIEtypes_dtim_period_t
2837 					 *)(((t_u8 *)tlv) +
2838 					    sizeof(MrvlIEtypes_beacon_period_t));
2839 			if (TLV_TYPE_UAP_DTIM_PERIOD ==
2840 			    wlan_le16_to_cpu(tlv_dtimpd->header.type))
2841 				pmpriv->uap_state_chan_cb.dtim_period =
2842 					tlv_dtimpd->dtim_period;
2843 			/* call callback waiting for beacon/dtim info */
2844 			if (pmpriv->uap_state_chan_cb.get_chan_callback)
2845 				pmpriv->uap_state_chan_cb.get_chan_callback(
2846 					pmpriv);
2847 			break;
2848 		case TLV_TYPE_MGMT_IE:
2849 			if ((pmpriv->adapter->state_rdh.stage ==
2850 			     RDH_SET_CUSTOM_IE) ||
2851 			    (pmpriv->adapter->state_rdh.stage ==
2852 			     RDH_REM_CUSTOM_IE)) {
2853 				if (!pmpriv->adapter->ecsa_enable)
2854 					wlan_11h_radar_detected_callback(
2855 						(t_void *)pmpriv);
2856 			}
2857 			break;
2858 		}
2859 	}
2860 	LEAVE();
2861 	return MLAN_STATUS_SUCCESS;
2862 }
2863 
2864 /**
2865  *  @brief This function prepares command of snmp_mib
2866  *
2867  *  @param pmpriv       A pointer to mlan_private structure
2868  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
2869  *  @param cmd_action   the action: GET or SET
2870  *  @param cmd_oid      Cmd oid: treated as sub command
2871  *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
2872  *  @param pdata_buf    A pointer to information buffer
2873  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
2874  */
wlan_uap_cmd_snmp_mib(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_u32 cmd_oid,pmlan_ioctl_req pioctl_buf,t_void * pdata_buf)2875 static mlan_status wlan_uap_cmd_snmp_mib(pmlan_private pmpriv,
2876 					 HostCmd_DS_COMMAND *cmd,
2877 					 t_u16 cmd_action, t_u32 cmd_oid,
2878 					 pmlan_ioctl_req pioctl_buf,
2879 					 t_void *pdata_buf)
2880 {
2881 	HostCmd_DS_802_11_SNMP_MIB *psnmp_mib = &cmd->params.smib;
2882 	HostCmd_DS_UAP_802_11_SNMP_MIB *puap_snmp_mib = &cmd->params.uap_smib;
2883 
2884 	mlan_status ret = MLAN_STATUS_SUCCESS;
2885 	t_u8 *psnmp_oid = MNULL;
2886 	t_u32 ul_temp;
2887 	t_u8 i;
2888 
2889 	t_u8 snmp_oids[] = {
2890 		tkip_mic_failures,
2891 		ccmp_decrypt_errors,
2892 		wep_undecryptable_count,
2893 		wep_icv_error_count,
2894 		decrypt_failure_count,
2895 		dot11_mcast_tx_count,
2896 		dot11_failed_count,
2897 		dot11_retry_count,
2898 		dot11_multi_retry_count,
2899 		dot11_frame_dup_count,
2900 		dot11_rts_success_count,
2901 		dot11_rts_failure_count,
2902 		dot11_ack_failure_count,
2903 		dot11_rx_fragment_count,
2904 		dot11_mcast_rx_frame_count,
2905 		dot11_fcs_error_count,
2906 		dot11_tx_frame_count,
2907 		dot11_rsna_tkip_cm_invoked,
2908 		dot11_rsna_4way_hshk_failures,
2909 	};
2910 
2911 	ENTER();
2912 
2913 	if (cmd_action == HostCmd_ACT_GEN_GET) {
2914 		cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
2915 		psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_GET);
2916 		if (cmd_oid == StopDeauth_i) {
2917 			psnmp_mib->oid = wlan_cpu_to_le16((t_u16)StopDeauth_i);
2918 			psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u8));
2919 			cmd->size = wlan_cpu_to_le16(
2920 				sizeof(HostCmd_DS_802_11_SNMP_MIB) + S_DS_GEN);
2921 		} else {
2922 			cmd->size = wlan_cpu_to_le16(
2923 				sizeof(t_u16) + S_DS_GEN +
2924 				sizeof(snmp_oids) *
2925 					sizeof(MrvlIEtypes_snmp_oid_t));
2926 			psnmp_oid = (t_u8 *)&puap_snmp_mib->snmp_data;
2927 			for (i = 0; i < sizeof(snmp_oids); i++) {
2928 				/* SNMP OID header type */
2929 				*(t_u16 *)psnmp_oid =
2930 					wlan_cpu_to_le16(snmp_oids[i]);
2931 				psnmp_oid += sizeof(t_u16);
2932 				/* SNMP OID header length */
2933 				*(t_u16 *)psnmp_oid =
2934 					wlan_cpu_to_le16(sizeof(t_u32));
2935 				psnmp_oid += sizeof(t_u16) + sizeof(t_u32);
2936 			}
2937 		}
2938 	} else { /* cmd_action == ACT_SET */
2939 		cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
2940 		cmd->size = sizeof(HostCmd_DS_802_11_SNMP_MIB) - 1 + S_DS_GEN;
2941 		psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
2942 
2943 		switch (cmd_oid) {
2944 		case Dot11D_i:
2945 		case Dot11H_i:
2946 			psnmp_mib->oid = wlan_cpu_to_le16((t_u16)cmd_oid);
2947 			psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
2948 			ul_temp = *(t_u32 *)pdata_buf;
2949 			*((t_u16 *)(psnmp_mib->value)) =
2950 				wlan_cpu_to_le16((t_u16)ul_temp);
2951 			cmd->size += sizeof(t_u16);
2952 			break;
2953 		case ECSAEnable_i:
2954 			psnmp_mib->oid = wlan_cpu_to_le16((t_u16)cmd_oid);
2955 			psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u8));
2956 			psnmp_mib->value[0] = *((t_u8 *)pdata_buf);
2957 			cmd->size += sizeof(t_u8);
2958 			break;
2959 		case StopDeauth_i:
2960 			psnmp_mib->oid = wlan_cpu_to_le16((t_u16)cmd_oid);
2961 			psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u8));
2962 			psnmp_mib->value[0] = *((t_u8 *)pdata_buf);
2963 			cmd->size += sizeof(t_u8);
2964 			break;
2965 		case Dot11H_fakeRadar:
2966 			psnmp_mib->oid = wlan_cpu_to_le16((t_u16)cmd_oid);
2967 			psnmp_mib->buf_size = 0;
2968 			break;
2969 		case ChanTrackParam_i:
2970 			psnmp_mib->oid = wlan_cpu_to_le16((t_u16)cmd_oid);
2971 			psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u8));
2972 			psnmp_mib->value[0] = *((t_u8 *)pdata_buf);
2973 			cmd->size += sizeof(t_u8);
2974 			break;
2975 		default:
2976 			PRINTM(MERROR, "Unsupported OID.\n");
2977 			ret = MLAN_STATUS_FAILURE;
2978 			break;
2979 		}
2980 		cmd->size = wlan_cpu_to_le16(cmd->size);
2981 	}
2982 
2983 	LEAVE();
2984 	return ret;
2985 }
2986 
2987 /**
2988  *  @brief This function prepares command of get_log.
2989  *
2990  *  @param pmpriv       A pointer to mlan_private structure
2991  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
2992  *
2993  *  @return             MLAN_STATUS_SUCCESS
2994  */
wlan_uap_cmd_802_11_get_log(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd)2995 static mlan_status wlan_uap_cmd_802_11_get_log(pmlan_private pmpriv,
2996 					       HostCmd_DS_COMMAND *cmd)
2997 {
2998 	ENTER();
2999 	cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_GET_LOG);
3000 	cmd->size =
3001 		wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_GET_LOG) + S_DS_GEN);
3002 	LEAVE();
3003 	return MLAN_STATUS_SUCCESS;
3004 }
3005 
3006 /**
3007  *  @brief This function prepares command of bss_start.
3008  *
3009  *  @param pmpriv       A pointer to mlan_private structure
3010  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
3011  *
3012  *  @return             MLAN_STATUS_SUCCESS
3013  */
wlan_uap_cmd_bss_start(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd)3014 static mlan_status wlan_uap_cmd_bss_start(pmlan_private pmpriv,
3015 					  HostCmd_DS_COMMAND *cmd)
3016 {
3017 	MrvlIEtypes_HostMlme_t *tlv;
3018 
3019 	ENTER();
3020 	cmd->command = wlan_cpu_to_le16(HOST_CMD_APCMD_BSS_START);
3021 	cmd->size = S_DS_GEN;
3022 	if (pmpriv->uap_host_based & UAP_FLAG_HOST_MLME) {
3023 		tlv = (MrvlIEtypes_HostMlme_t *)((t_u8 *)cmd + cmd->size);
3024 		tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_HOST_MLME);
3025 		tlv->header.len = wlan_cpu_to_le16(sizeof(tlv->host_mlme));
3026 		tlv->host_mlme = MTRUE;
3027 		cmd->size += sizeof(MrvlIEtypes_HostMlme_t);
3028 	}
3029 	cmd->size = wlan_cpu_to_le16(cmd->size);
3030 	LEAVE();
3031 	return MLAN_STATUS_SUCCESS;
3032 }
3033 
3034 /**
3035  *  @brief This function handles the command response of snmp_mib
3036  *
3037  *  @param pmpriv       A pointer to mlan_private structure
3038  *  @param resp         A pointer to HostCmd_DS_COMMAND
3039  *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
3040  *
3041  *  @return             MLAN_STATUS_SUCCESS
3042  */
wlan_uap_ret_snmp_mib(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)3043 static mlan_status wlan_uap_ret_snmp_mib(pmlan_private pmpriv,
3044 					 HostCmd_DS_COMMAND *resp,
3045 					 mlan_ioctl_req *pioctl_buf)
3046 {
3047 	pmlan_adapter pmadapter = pmpriv->adapter;
3048 	HostCmd_DS_802_11_SNMP_MIB *psnmp_mib =
3049 		(HostCmd_DS_802_11_SNMP_MIB *)&resp->params.smib;
3050 	mlan_ds_get_info *info;
3051 	mlan_ds_snmp_mib *mib = MNULL;
3052 	t_u16 oid = wlan_le16_to_cpu(psnmp_mib->oid);
3053 	t_u8 *psnmp_oid = MNULL;
3054 	t_u32 data;
3055 	t_u16 tlv_buf_left = 0;
3056 	t_u16 tlv_type = 0;
3057 	t_u16 query_type = wlan_le16_to_cpu(psnmp_mib->query_type);
3058 
3059 	ENTER();
3060 	if (query_type == HostCmd_ACT_GEN_GET) {
3061 		if (!pioctl_buf) {
3062 			LEAVE();
3063 			return MLAN_STATUS_SUCCESS;
3064 		}
3065 		if (oid == StopDeauth_i) {
3066 			mib = (mlan_ds_snmp_mib *)pioctl_buf->pbuf;
3067 			if (mib)
3068 				mib->param.deauthctrl = psnmp_mib->value[0];
3069 			LEAVE();
3070 			return MLAN_STATUS_SUCCESS;
3071 		}
3072 		info = (mlan_ds_get_info *)pioctl_buf->pbuf;
3073 		tlv_buf_left = resp->size - (sizeof(t_u16) + S_DS_GEN);
3074 		psnmp_oid = (t_u8 *)&psnmp_mib->oid;
3075 		while (tlv_buf_left >= sizeof(MrvlIEtypes_snmp_oid_t)) {
3076 			tlv_type = wlan_le16_to_cpu(*(t_u16 *)psnmp_oid);
3077 			psnmp_oid += sizeof(t_u16) + sizeof(t_u16);
3078 			memcpy_ext(pmadapter, &data, psnmp_oid, sizeof(t_u32),
3079 				   sizeof(t_u32));
3080 			switch (tlv_type) {
3081 			case tkip_mic_failures:
3082 				info->param.ustats.tkip_mic_failures =
3083 					wlan_le32_to_cpu(data);
3084 				break;
3085 			case ccmp_decrypt_errors:
3086 				info->param.ustats.ccmp_decrypt_errors =
3087 					wlan_le32_to_cpu(data);
3088 				break;
3089 			case wep_undecryptable_count:
3090 				info->param.ustats.wep_undecryptable_count =
3091 					wlan_le32_to_cpu(data);
3092 				break;
3093 			case wep_icv_error_count:
3094 				info->param.ustats.wep_icv_error_count =
3095 					wlan_le32_to_cpu(data);
3096 				break;
3097 			case decrypt_failure_count:
3098 				info->param.ustats.decrypt_failure_count =
3099 					wlan_le32_to_cpu(data);
3100 				break;
3101 			case dot11_mcast_tx_count:
3102 				info->param.ustats.mcast_tx_count =
3103 					wlan_le32_to_cpu(data);
3104 				break;
3105 			case dot11_failed_count:
3106 				info->param.ustats.failed_count =
3107 					wlan_le32_to_cpu(data);
3108 				break;
3109 			case dot11_retry_count:
3110 				info->param.ustats.retry_count =
3111 					wlan_le32_to_cpu(data);
3112 				break;
3113 			case dot11_multi_retry_count:
3114 				info->param.ustats.multi_retry_count =
3115 					wlan_le32_to_cpu(data);
3116 				break;
3117 			case dot11_frame_dup_count:
3118 				info->param.ustats.frame_dup_count =
3119 					wlan_le32_to_cpu(data);
3120 				break;
3121 			case dot11_rts_success_count:
3122 				info->param.ustats.rts_success_count =
3123 					wlan_le32_to_cpu(data);
3124 				break;
3125 			case dot11_rts_failure_count:
3126 				info->param.ustats.rts_failure_count =
3127 					wlan_le32_to_cpu(data);
3128 				break;
3129 			case dot11_ack_failure_count:
3130 				info->param.ustats.ack_failure_count =
3131 					wlan_le32_to_cpu(data);
3132 				break;
3133 			case dot11_rx_fragment_count:
3134 				info->param.ustats.rx_fragment_count =
3135 					wlan_le32_to_cpu(data);
3136 				break;
3137 			case dot11_mcast_rx_frame_count:
3138 				info->param.ustats.mcast_rx_frame_count =
3139 					wlan_le32_to_cpu(data);
3140 				break;
3141 			case dot11_fcs_error_count:
3142 				info->param.ustats.fcs_error_count =
3143 					wlan_le32_to_cpu(data);
3144 				break;
3145 			case dot11_tx_frame_count:
3146 				info->param.ustats.tx_frame_count =
3147 					wlan_le32_to_cpu(data);
3148 				break;
3149 			case dot11_rsna_tkip_cm_invoked:
3150 				info->param.ustats.rsna_tkip_cm_invoked =
3151 					wlan_le32_to_cpu(data);
3152 				break;
3153 			case dot11_rsna_4way_hshk_failures:
3154 				info->param.ustats.rsna_4way_hshk_failures =
3155 					wlan_le32_to_cpu(data);
3156 				break;
3157 			}
3158 			tlv_buf_left -= sizeof(MrvlIEtypes_snmp_oid_t);
3159 			psnmp_oid += sizeof(t_u32);
3160 		}
3161 	} else { /* ACT_SET */
3162 		switch (wlan_le16_to_cpu(psnmp_mib->oid)) {
3163 		case Dot11D_i:
3164 			data = wlan_le16_to_cpu(*((t_u16 *)(psnmp_mib->value)));
3165 			/* Set 11d state to private */
3166 			pmpriv->state_11d.enable_11d = data;
3167 			/* Set user enable flag if called from ioctl */
3168 			if (pioctl_buf)
3169 				pmpriv->state_11d.user_enable_11d = data;
3170 			break;
3171 		case Dot11H_i:
3172 			data = wlan_le16_to_cpu(*((t_u16 *)(psnmp_mib->value)));
3173 			PRINTM(MCMND, "wlan: uap Dot11H_i=%d\n", data);
3174 			/* Set 11h state to priv */
3175 			pmpriv->intf_state_11h.is_11h_active =
3176 				(data & ENABLE_11H_MASK);
3177 			/* Set radar_det state to adapter */
3178 			pmpriv->adapter->state_11h.is_master_radar_det_active =
3179 				(data & MASTER_RADAR_DET_MASK) ? MTRUE : MFALSE;
3180 			pmpriv->adapter->state_11h.is_slave_radar_det_active =
3181 				(data & SLAVE_RADAR_DET_MASK) ? MTRUE : MFALSE;
3182 			break;
3183 		}
3184 	}
3185 
3186 	LEAVE();
3187 	return MLAN_STATUS_SUCCESS;
3188 }
3189 
3190 /**
3191  *  @brief This function handles the command response of get_log
3192  *
3193  *  @param pmpriv       A pointer to mlan_private structure
3194  *  @param resp         A pointer to HostCmd_DS_COMMAND
3195  *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
3196  *
3197  *  @return             MLAN_STATUS_SUCCESS
3198  */
wlan_uap_ret_get_log(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)3199 static mlan_status wlan_uap_ret_get_log(pmlan_private pmpriv,
3200 					HostCmd_DS_COMMAND *resp,
3201 					mlan_ioctl_req *pioctl_buf)
3202 {
3203 	HostCmd_DS_802_11_GET_LOG *pget_log =
3204 		(HostCmd_DS_802_11_GET_LOG *)&resp->params.get_log;
3205 	mlan_ds_get_info *pget_info = MNULL;
3206 	int i = 0;
3207 
3208 	ENTER();
3209 
3210 	if (pioctl_buf) {
3211 		pget_info = (mlan_ds_get_info *)pioctl_buf->pbuf;
3212 		pget_info->param.stats.mcast_tx_frame =
3213 			wlan_le32_to_cpu(pget_log->mcast_tx_frame);
3214 		pget_info->param.stats.failed =
3215 			wlan_le32_to_cpu(pget_log->failed);
3216 		pget_info->param.stats.retry =
3217 			wlan_le32_to_cpu(pget_log->retry);
3218 		pget_info->param.stats.multi_retry =
3219 			wlan_le32_to_cpu(pget_log->multiretry);
3220 		pget_info->param.stats.frame_dup =
3221 			wlan_le32_to_cpu(pget_log->frame_dup);
3222 		pget_info->param.stats.rts_success =
3223 			wlan_le32_to_cpu(pget_log->rts_success);
3224 		pget_info->param.stats.rts_failure =
3225 			wlan_le32_to_cpu(pget_log->rts_failure);
3226 		pget_info->param.stats.ack_failure =
3227 			wlan_le32_to_cpu(pget_log->ack_failure);
3228 		pget_info->param.stats.rx_frag =
3229 			wlan_le32_to_cpu(pget_log->rx_frag);
3230 		pget_info->param.stats.mcast_rx_frame =
3231 			wlan_le32_to_cpu(pget_log->mcast_rx_frame);
3232 		pget_info->param.stats.fcs_error =
3233 			wlan_le32_to_cpu(pget_log->fcs_error);
3234 		pget_info->param.stats.tx_frame =
3235 			wlan_le32_to_cpu(pget_log->tx_frame);
3236 		pget_info->param.stats.wep_icv_error[0] =
3237 			wlan_le32_to_cpu(pget_log->wep_icv_err_cnt[0]);
3238 		pget_info->param.stats.wep_icv_error[1] =
3239 			wlan_le32_to_cpu(pget_log->wep_icv_err_cnt[1]);
3240 		pget_info->param.stats.wep_icv_error[2] =
3241 			wlan_le32_to_cpu(pget_log->wep_icv_err_cnt[2]);
3242 		pget_info->param.stats.wep_icv_error[3] =
3243 			wlan_le32_to_cpu(pget_log->wep_icv_err_cnt[3]);
3244 		pget_info->param.stats.bcn_rcv_cnt =
3245 			wlan_le32_to_cpu(pget_log->bcn_rcv_cnt);
3246 		pget_info->param.stats.bcn_miss_cnt =
3247 			wlan_le32_to_cpu(pget_log->bcn_miss_cnt);
3248 		pget_info->param.stats.amsdu_rx_cnt = pmpriv->amsdu_rx_cnt;
3249 		pget_info->param.stats.msdu_in_rx_amsdu_cnt =
3250 			pmpriv->msdu_in_rx_amsdu_cnt;
3251 		pget_info->param.stats.amsdu_tx_cnt = pmpriv->amsdu_tx_cnt;
3252 		pget_info->param.stats.msdu_in_tx_amsdu_cnt =
3253 			pmpriv->msdu_in_tx_amsdu_cnt;
3254 		pget_info->param.stats.rx_stuck_issue_cnt[0] =
3255 			wlan_le32_to_cpu(pget_log->rx_stuck_issue_cnt[0]);
3256 		pget_info->param.stats.rx_stuck_issue_cnt[1] =
3257 			wlan_le32_to_cpu(pget_log->rx_stuck_issue_cnt[1]);
3258 		pget_info->param.stats.rx_stuck_recovery_cnt =
3259 			wlan_le32_to_cpu(pget_log->rx_stuck_recovery_cnt);
3260 		pget_info->param.stats.rx_stuck_tsf[0] =
3261 			wlan_le64_to_cpu(pget_log->rx_stuck_tsf[0]);
3262 		pget_info->param.stats.rx_stuck_tsf[1] =
3263 			wlan_le64_to_cpu(pget_log->rx_stuck_tsf[1]);
3264 		pget_info->param.stats.tx_watchdog_recovery_cnt =
3265 			wlan_le32_to_cpu(pget_log->tx_watchdog_recovery_cnt);
3266 		pget_info->param.stats.tx_watchdog_tsf[0] =
3267 			wlan_le64_to_cpu(pget_log->tx_watchdog_tsf[0]);
3268 		pget_info->param.stats.tx_watchdog_tsf[1] =
3269 			wlan_le64_to_cpu(pget_log->tx_watchdog_tsf[1]);
3270 		pget_info->param.stats.channel_switch_ann_sent =
3271 			wlan_le32_to_cpu(pget_log->channel_switch_ann_sent);
3272 		pget_info->param.stats.channel_switch_state =
3273 			wlan_le32_to_cpu(pget_log->channel_switch_state);
3274 		pget_info->param.stats.reg_class =
3275 			wlan_le32_to_cpu(pget_log->reg_class);
3276 		pget_info->param.stats.channel_number =
3277 			wlan_le32_to_cpu(pget_log->channel_number);
3278 		pget_info->param.stats.channel_switch_mode =
3279 			wlan_le32_to_cpu(pget_log->channel_switch_mode);
3280 		pget_info->param.stats.rx_reset_mac_recovery_cnt =
3281 			wlan_le32_to_cpu(pget_log->rx_reset_mac_recovery_cnt);
3282 		pget_info->param.stats.rx_Isr2_NotDone_Cnt =
3283 			wlan_le32_to_cpu(pget_log->rx_Isr2_NotDone_Cnt);
3284 		pget_info->param.stats.gdma_abort_cnt =
3285 			wlan_le32_to_cpu(pget_log->gdma_abort_cnt);
3286 		pget_info->param.stats.g_reset_rx_mac_cnt =
3287 			wlan_le32_to_cpu(pget_log->g_reset_rx_mac_cnt);
3288 		// Ownership error counters
3289 		pget_info->param.stats.dwCtlErrCnt =
3290 			wlan_le32_to_cpu(pget_log->dwCtlErrCnt);
3291 		pget_info->param.stats.dwBcnErrCnt =
3292 			wlan_le32_to_cpu(pget_log->dwBcnErrCnt);
3293 		pget_info->param.stats.dwMgtErrCnt =
3294 			wlan_le32_to_cpu(pget_log->dwMgtErrCnt);
3295 		pget_info->param.stats.dwDatErrCnt =
3296 			wlan_le32_to_cpu(pget_log->dwDatErrCnt);
3297 		pget_info->param.stats.bigtk_mmeGoodCnt =
3298 			wlan_le32_to_cpu(pget_log->bigtk_mmeGoodCnt);
3299 		pget_info->param.stats.bigtk_replayErrCnt =
3300 			wlan_le32_to_cpu(pget_log->bigtk_replayErrCnt);
3301 		pget_info->param.stats.bigtk_micErrCnt =
3302 			wlan_le32_to_cpu(pget_log->bigtk_micErrCnt);
3303 		pget_info->param.stats.bigtk_mmeNotFoundCnt =
3304 			wlan_le32_to_cpu(pget_log->bigtk_mmeNotFoundCnt);
3305 
3306 		if (pmpriv->adapter->getlog_enable) {
3307 			pget_info->param.stats.tx_frag_cnt =
3308 				wlan_le32_to_cpu(pget_log->tx_frag_cnt);
3309 			for (i = 0; i < 8; i++) {
3310 				pget_info->param.stats.qos_tx_frag_cnt[i] =
3311 					wlan_le32_to_cpu(
3312 						pget_log->qos_tx_frag_cnt[i]);
3313 				pget_info->param.stats.qos_failed_cnt[i] =
3314 					wlan_le32_to_cpu(
3315 						pget_log->qos_failed_cnt[i]);
3316 				pget_info->param.stats.qos_retry_cnt[i] =
3317 					wlan_le32_to_cpu(
3318 						pget_log->qos_retry_cnt[i]);
3319 				pget_info->param.stats.qos_multi_retry_cnt[i] =
3320 					wlan_le32_to_cpu(
3321 						pget_log->qos_multi_retry_cnt[i]);
3322 				pget_info->param.stats.qos_frm_dup_cnt[i] =
3323 					wlan_le32_to_cpu(
3324 						pget_log->qos_frm_dup_cnt[i]);
3325 				pget_info->param.stats.qos_rts_suc_cnt[i] =
3326 					wlan_le32_to_cpu(
3327 						pget_log->qos_rts_suc_cnt[i]);
3328 				pget_info->param.stats.qos_rts_failure_cnt[i] =
3329 					wlan_le32_to_cpu(
3330 						pget_log->qos_rts_failure_cnt[i]);
3331 				pget_info->param.stats.qos_ack_failure_cnt[i] =
3332 					wlan_le32_to_cpu(
3333 						pget_log->qos_ack_failure_cnt[i]);
3334 				pget_info->param.stats.qos_rx_frag_cnt[i] =
3335 					wlan_le32_to_cpu(
3336 						pget_log->qos_rx_frag_cnt[i]);
3337 				pget_info->param.stats.qos_tx_frm_cnt[i] =
3338 					wlan_le32_to_cpu(
3339 						pget_log->qos_tx_frm_cnt[i]);
3340 				pget_info->param.stats.qos_discarded_frm_cnt
3341 					[i] = wlan_le32_to_cpu(
3342 					pget_log->qos_discarded_frm_cnt[i]);
3343 				pget_info->param.stats.qos_mpdus_rx_cnt[i] =
3344 					wlan_le32_to_cpu(
3345 						pget_log->qos_mpdus_rx_cnt[i]);
3346 				pget_info->param.stats.qos_retries_rx_cnt[i] =
3347 					wlan_le32_to_cpu(
3348 						pget_log->qos_retries_rx_cnt[i]);
3349 			}
3350 			pget_info->param.stats.mgmt_ccmp_replays =
3351 				wlan_le32_to_cpu(pget_log->mgmt_ccmp_replays);
3352 			pget_info->param.stats.tx_amsdu_cnt =
3353 				wlan_le32_to_cpu(pget_log->tx_amsdu_cnt);
3354 			pget_info->param.stats.failed_amsdu_cnt =
3355 				wlan_le32_to_cpu(pget_log->failed_amsdu_cnt);
3356 			pget_info->param.stats.retry_amsdu_cnt =
3357 				wlan_le32_to_cpu(pget_log->retry_amsdu_cnt);
3358 			pget_info->param.stats.multi_retry_amsdu_cnt =
3359 				wlan_le32_to_cpu(
3360 					pget_log->multi_retry_amsdu_cnt);
3361 			pget_info->param.stats.tx_octets_in_amsdu_cnt =
3362 				wlan_le64_to_cpu(
3363 					pget_log->tx_octets_in_amsdu_cnt);
3364 			pget_info->param.stats.amsdu_ack_failure_cnt =
3365 				wlan_le32_to_cpu(
3366 					pget_log->amsdu_ack_failure_cnt);
3367 			pget_info->param.stats.rx_amsdu_cnt =
3368 				wlan_le32_to_cpu(pget_log->rx_amsdu_cnt);
3369 			pget_info->param.stats.rx_octets_in_amsdu_cnt =
3370 				wlan_le64_to_cpu(
3371 					pget_log->rx_octets_in_amsdu_cnt);
3372 			pget_info->param.stats.tx_ampdu_cnt =
3373 				wlan_le32_to_cpu(pget_log->tx_ampdu_cnt);
3374 			pget_info->param.stats.tx_mpdus_in_ampdu_cnt =
3375 				wlan_le32_to_cpu(
3376 					pget_log->tx_mpdus_in_ampdu_cnt);
3377 			pget_info->param.stats.tx_octets_in_ampdu_cnt =
3378 				wlan_le64_to_cpu(
3379 					pget_log->tx_octets_in_ampdu_cnt);
3380 			pget_info->param.stats.ampdu_rx_cnt =
3381 				wlan_le32_to_cpu(pget_log->ampdu_rx_cnt);
3382 			pget_info->param.stats.mpdu_in_rx_ampdu_cnt =
3383 				wlan_le32_to_cpu(
3384 					pget_log->mpdu_in_rx_ampdu_cnt);
3385 			pget_info->param.stats.rx_octets_in_ampdu_cnt =
3386 				wlan_le64_to_cpu(
3387 					pget_log->rx_octets_in_ampdu_cnt);
3388 			pget_info->param.stats.ampdu_delimiter_crc_error_cnt =
3389 				wlan_le32_to_cpu(
3390 					pget_log->ampdu_delimiter_crc_error_cnt);
3391 
3392 			/* Indicate ioctl complete */
3393 			pioctl_buf->data_read_written =
3394 				sizeof(mlan_ds_get_info);
3395 		} else
3396 			pioctl_buf->data_read_written =
3397 				sizeof(mlan_ds_get_stats_org) +
3398 				sizeof(pget_info->sub_command);
3399 	}
3400 	LEAVE();
3401 	return MLAN_STATUS_SUCCESS;
3402 }
3403 
3404 /**
3405  *  @brief This function prepares command of deauth station
3406  *
3407  *  @param pmpriv       A pointer to mlan_private structure
3408  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
3409  *  @param pdata_buf    A pointer to data buffer
3410  *  @return         MLAN_STATUS_SUCCESS
3411  */
wlan_uap_cmd_sta_deauth(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_void * pdata_buf)3412 static mlan_status wlan_uap_cmd_sta_deauth(pmlan_private pmpriv,
3413 					   HostCmd_DS_COMMAND *cmd,
3414 					   t_void *pdata_buf)
3415 {
3416 	HostCmd_DS_STA_DEAUTH *pcmd_sta_deauth =
3417 		(HostCmd_DS_STA_DEAUTH *)&cmd->params.sta_deauth;
3418 	mlan_deauth_param *deauth = (mlan_deauth_param *)pdata_buf;
3419 
3420 	ENTER();
3421 	cmd->command = wlan_cpu_to_le16(HOST_CMD_APCMD_STA_DEAUTH);
3422 	cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_STA_DEAUTH));
3423 	memcpy_ext(pmpriv->adapter, pcmd_sta_deauth->mac, deauth->mac_addr,
3424 		   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
3425 	pcmd_sta_deauth->reason = wlan_cpu_to_le16(deauth->reason_code);
3426 	LEAVE();
3427 	return MLAN_STATUS_SUCCESS;
3428 }
3429 
3430 /**
3431  *  @brief This function prepares command of report mic_err
3432  *
3433  *  @param pmpriv       A pointer to mlan_private structure
3434  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
3435  *  @param pdata_buf    A pointer to data buffer
3436  *  @return         MLAN_STATUS_SUCCESS
3437  */
wlan_uap_cmd_report_mic(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_void * pdata_buf)3438 static mlan_status wlan_uap_cmd_report_mic(pmlan_private pmpriv,
3439 					   HostCmd_DS_COMMAND *cmd,
3440 					   t_void *pdata_buf)
3441 {
3442 	HostCmd_DS_REPORT_MIC *pcmd_report_mic =
3443 		(HostCmd_DS_REPORT_MIC *)&cmd->params.report_mic;
3444 
3445 	ENTER();
3446 	cmd->command = wlan_cpu_to_le16(HOST_CMD_APCMD_REPORT_MIC);
3447 	cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_REPORT_MIC));
3448 	memcpy_ext(pmpriv->adapter, pcmd_report_mic->mac, pdata_buf,
3449 		   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
3450 	LEAVE();
3451 	return MLAN_STATUS_SUCCESS;
3452 }
3453 
3454 /**
3455  *  @brief This function prepares command of key material
3456  *
3457  *  @param pmpriv       A pointer to mlan_private structure
3458  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
3459  *  @param cmd_action   The action: GET or SET
3460  *  @param cmd_oid      OID: ENABLE or DISABLE
3461  *  @param pdata_buf    A pointer to data buffer
3462  *  @return             MLAN_STATUS_SUCCESS
3463  */
wlan_uap_cmd_key_material(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_u16 cmd_oid,t_void * pdata_buf)3464 static mlan_status wlan_uap_cmd_key_material(pmlan_private pmpriv,
3465 					     HostCmd_DS_COMMAND *cmd,
3466 					     t_u16 cmd_action, t_u16 cmd_oid,
3467 					     t_void *pdata_buf)
3468 {
3469 	HostCmd_DS_802_11_KEY_MATERIAL *pkey_material =
3470 		&cmd->params.key_material;
3471 	mlan_ds_encrypt_key *pkey = (mlan_ds_encrypt_key *)pdata_buf;
3472 	mlan_status ret = MLAN_STATUS_SUCCESS;
3473 	sta_node *sta_ptr = MNULL;
3474 
3475 	ENTER();
3476 	if (!pkey) {
3477 		ret = MLAN_STATUS_FAILURE;
3478 		goto done;
3479 	}
3480 	cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL);
3481 	pkey_material->action = wlan_cpu_to_le16(cmd_action);
3482 	if (cmd_action == HostCmd_ACT_GEN_GET) {
3483 		cmd->size = wlan_cpu_to_le16(sizeof(pkey_material->action) +
3484 					     S_DS_GEN);
3485 		goto done;
3486 	}
3487 	memset(pmpriv->adapter, &pkey_material->key_param_set, 0,
3488 	       sizeof(MrvlIEtype_KeyParamSetV2_t));
3489 	if (pkey->key_flags & KEY_FLAG_REMOVE_KEY) {
3490 		pkey_material->action =
3491 			wlan_cpu_to_le16(HostCmd_ACT_GEN_REMOVE);
3492 		pkey_material->key_param_set.type =
3493 			wlan_cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
3494 		pkey_material->key_param_set.length =
3495 			wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN);
3496 		pkey_material->key_param_set.key_idx =
3497 			pkey->key_index & KEY_INDEX_MASK;
3498 		pkey_material->key_param_set.key_info = wlan_cpu_to_le16(
3499 			KEY_INFO_MCAST_KEY | KEY_INFO_UCAST_KEY);
3500 		memcpy_ext(pmpriv->adapter,
3501 			   pkey_material->key_param_set.mac_addr,
3502 			   pkey->mac_addr, MLAN_MAC_ADDR_LENGTH,
3503 			   MLAN_MAC_ADDR_LENGTH);
3504 		cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) +
3505 					     S_DS_GEN + KEY_PARAMS_FIXED_LEN +
3506 					     sizeof(pkey_material->action));
3507 		PRINTM(MCMND, "Remove Key\n");
3508 		goto done;
3509 	}
3510 	pkey_material->action = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
3511 	pkey_material->key_param_set.key_idx = pkey->key_index & KEY_INDEX_MASK;
3512 	pkey_material->key_param_set.type =
3513 		wlan_cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
3514 	pkey_material->key_param_set.key_info = KEY_INFO_ENABLE_KEY;
3515 	memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.mac_addr,
3516 		   pkey->mac_addr, MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
3517 	if (pkey->key_len <= MAX_WEP_KEY_SIZE) {
3518 		pkey_material->key_param_set.length = wlan_cpu_to_le16(
3519 			KEY_PARAMS_FIXED_LEN + sizeof(wep_param_t));
3520 		pkey_material->key_param_set.key_type = KEY_TYPE_ID_WEP;
3521 		pkey_material->key_param_set.key_info |=
3522 			KEY_INFO_MCAST_KEY | KEY_INFO_UCAST_KEY;
3523 		if (pkey_material->key_param_set.key_idx ==
3524 		    (pmpriv->wep_key_curr_index & KEY_INDEX_MASK))
3525 			pkey_material->key_param_set.key_info |=
3526 				KEY_INFO_DEFAULT_KEY;
3527 		pkey_material->key_param_set.key_info =
3528 			wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
3529 		pkey_material->key_param_set.key_params.wep.key_len =
3530 			wlan_cpu_to_le16(pkey->key_len);
3531 		memcpy_ext(pmpriv->adapter,
3532 			   pkey_material->key_param_set.key_params.wep.key,
3533 			   pkey->key_material, pkey->key_len, MAX_WEP_KEY_SIZE);
3534 		cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) +
3535 					     S_DS_GEN + KEY_PARAMS_FIXED_LEN +
3536 					     sizeof(wep_param_t) +
3537 					     sizeof(pkey_material->action));
3538 		PRINTM(MCMND, "Set WEP Key\n");
3539 		goto done;
3540 	}
3541 	if (pkey->key_flags & KEY_FLAG_GROUP_KEY)
3542 		pkey_material->key_param_set.key_info |= KEY_INFO_MCAST_KEY;
3543 	else
3544 		pkey_material->key_param_set.key_info |= KEY_INFO_UCAST_KEY;
3545 	if (pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK)
3546 		pkey_material->key_param_set.key_info |= KEY_INFO_CMAC_AES_KEY;
3547 	if (pkey->key_flags & KEY_FLAG_SET_TX_KEY)
3548 		pkey_material->key_param_set.key_info |=
3549 			KEY_INFO_TX_KEY | KEY_INFO_RX_KEY;
3550 	else
3551 		pkey_material->key_param_set.key_info |= KEY_INFO_TX_KEY;
3552 	if (pkey->is_wapi_key) {
3553 		pkey_material->key_param_set.key_type = KEY_TYPE_ID_WAPI;
3554 		memcpy_ext(pmpriv->adapter,
3555 			   pkey_material->key_param_set.key_params.wapi.pn,
3556 			   pkey->pn, PN_SIZE, PN_SIZE);
3557 		pkey_material->key_param_set.key_params.wapi.key_len =
3558 			wlan_cpu_to_le16(MIN(WAPI_KEY_SIZE, pkey->key_len));
3559 		memcpy_ext(pmpriv->adapter,
3560 			   pkey_material->key_param_set.key_params.wapi.key,
3561 			   pkey->key_material, pkey->key_len, WAPI_KEY_SIZE);
3562 		if (!pmpriv->sec_info.wapi_key_on)
3563 			pkey_material->key_param_set.key_info |=
3564 				KEY_INFO_DEFAULT_KEY;
3565 		if (pkey->key_flags & KEY_FLAG_GROUP_KEY) {
3566 			pmpriv->sec_info.wapi_key_on = MTRUE;
3567 		} else {
3568 			/* WAPI pairwise key: unicast */
3569 			sta_ptr =
3570 				wlan_add_station_entry(pmpriv, pkey->mac_addr);
3571 			if (sta_ptr) {
3572 				PRINTM(MCMND, "station: wapi_key_on\n");
3573 				sta_ptr->wapi_key_on = MTRUE;
3574 			}
3575 		}
3576 		pkey_material->key_param_set.key_info =
3577 			wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
3578 		pkey_material->key_param_set.length = wlan_cpu_to_le16(
3579 			KEY_PARAMS_FIXED_LEN + sizeof(wapi_param));
3580 		cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) +
3581 					     S_DS_GEN + KEY_PARAMS_FIXED_LEN +
3582 					     sizeof(wapi_param) +
3583 					     sizeof(pkey_material->action));
3584 		PRINTM(MCMND, "Set WAPI Key\n");
3585 		goto done;
3586 	}
3587 	pkey_material->key_param_set.key_info |= KEY_INFO_DEFAULT_KEY;
3588 	pkey_material->key_param_set.key_info =
3589 		wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
3590 	if (pkey->key_len == WPA_AES_KEY_LEN &&
3591 	    !(pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK)) {
3592 		if (pkey->key_flags &
3593 		    (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
3594 			memcpy_ext(
3595 				pmpriv->adapter,
3596 				pkey_material->key_param_set.key_params.aes.pn,
3597 				pkey->pn, SEQ_MAX_SIZE, WPA_PN_SIZE);
3598 		pkey_material->key_param_set.key_type = KEY_TYPE_ID_AES;
3599 		pkey_material->key_param_set.key_params.aes.key_len =
3600 			wlan_cpu_to_le16(pkey->key_len);
3601 		memcpy_ext(pmpriv->adapter,
3602 			   pkey_material->key_param_set.key_params.aes.key,
3603 			   pkey->key_material, pkey->key_len, WPA_AES_KEY_LEN);
3604 		pkey_material->key_param_set.length = wlan_cpu_to_le16(
3605 			KEY_PARAMS_FIXED_LEN + sizeof(aes_param));
3606 		cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) +
3607 					     S_DS_GEN + KEY_PARAMS_FIXED_LEN +
3608 					     sizeof(aes_param) +
3609 					     sizeof(pkey_material->action));
3610 		PRINTM(MCMND, "Set AES Key\n");
3611 		goto done;
3612 	}
3613 	if (pkey->key_len == WPA_IGTK_KEY_LEN &&
3614 	    (pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK)) {
3615 		if (pkey->key_flags &
3616 		    (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
3617 			memcpy_ext(pmpriv->adapter,
3618 				   pkey_material->key_param_set.key_params
3619 					   .cmac_aes.ipn,
3620 				   pkey->pn, SEQ_MAX_SIZE, IGTK_PN_SIZE);
3621 		pkey_material->key_param_set.key_info &=
3622 			~(wlan_cpu_to_le16(KEY_INFO_MCAST_KEY));
3623 		pkey_material->key_param_set.key_info |=
3624 			wlan_cpu_to_le16(KEY_INFO_AES_MCAST_IGTK);
3625 		if (pkey->key_flags & KEY_FLAG_GMAC_128)
3626 			pkey_material->key_param_set.key_type =
3627 				KEY_TYPE_ID_BIP_GMAC_128;
3628 		else
3629 			pkey_material->key_param_set.key_type =
3630 				KEY_TYPE_ID_AES_CMAC;
3631 		pkey_material->key_param_set.key_params.cmac_aes.key_len =
3632 			wlan_cpu_to_le16(pkey->key_len);
3633 		memcpy_ext(pmpriv->adapter,
3634 			   pkey_material->key_param_set.key_params.cmac_aes.key,
3635 			   pkey->key_material, pkey->key_len, CMAC_AES_KEY_LEN);
3636 		pkey_material->key_param_set.length = wlan_cpu_to_le16(
3637 			KEY_PARAMS_FIXED_LEN + sizeof(cmac_aes_param));
3638 		cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) +
3639 					     S_DS_GEN + KEY_PARAMS_FIXED_LEN +
3640 					     sizeof(cmac_aes_param) +
3641 					     sizeof(pkey_material->action));
3642 		if (pkey->key_flags & KEY_FLAG_GMAC_128)
3643 			PRINTM(MCMND, "Set AES 128 GMAC Key\n");
3644 		else
3645 			PRINTM(MCMND, "Set CMAC AES Key\n");
3646 		goto done;
3647 	}
3648 	if (pkey->key_len == WPA_IGTK_256_KEY_LEN &&
3649 	    (pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK)) {
3650 		if (pkey->key_flags &
3651 		    (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
3652 			memcpy_ext(pmpriv->adapter,
3653 				   pkey_material->key_param_set.key_params
3654 					   .cmac_aes.ipn,
3655 				   pkey->pn, SEQ_MAX_SIZE, IGTK_PN_SIZE);
3656 		pkey_material->key_param_set.key_info &=
3657 			~(wlan_cpu_to_le16(KEY_INFO_MCAST_KEY));
3658 		pkey_material->key_param_set.key_info |=
3659 			wlan_cpu_to_le16(KEY_INFO_AES_MCAST_IGTK);
3660 		pkey_material->key_param_set.key_type =
3661 			KEY_TYPE_ID_BIP_GMAC_256;
3662 		pkey_material->key_param_set.key_params.cmac_aes.key_len =
3663 			wlan_cpu_to_le16(pkey->key_len);
3664 		memcpy_ext(pmpriv->adapter,
3665 			   pkey_material->key_param_set.key_params.cmac_aes.key,
3666 			   pkey->key_material, pkey->key_len,
3667 			   WPA_IGTK_256_KEY_LEN);
3668 		pkey_material->key_param_set.length = wlan_cpu_to_le16(
3669 			KEY_PARAMS_FIXED_LEN + sizeof(gmac_aes_256_param));
3670 		cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) +
3671 					     S_DS_GEN + KEY_PARAMS_FIXED_LEN +
3672 					     sizeof(gmac_aes_256_param) +
3673 					     sizeof(pkey_material->action));
3674 		PRINTM(MCMND, "Set AES 256 GMAC Key\n");
3675 		goto done;
3676 	}
3677 	if (pkey->key_len == WPA_TKIP_KEY_LEN) {
3678 		if (pkey->key_flags &
3679 		    (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
3680 			memcpy_ext(
3681 				pmpriv->adapter,
3682 				pkey_material->key_param_set.key_params.tkip.pn,
3683 				pkey->pn, SEQ_MAX_SIZE, WPA_PN_SIZE);
3684 		pkey_material->key_param_set.key_type = KEY_TYPE_ID_TKIP;
3685 		pkey_material->key_param_set.key_params.tkip.key_len =
3686 			wlan_cpu_to_le16(pkey->key_len);
3687 		memcpy_ext(pmpriv->adapter,
3688 			   pkey_material->key_param_set.key_params.tkip.key,
3689 			   pkey->key_material, pkey->key_len, WPA_TKIP_KEY_LEN);
3690 		pkey_material->key_param_set.length = wlan_cpu_to_le16(
3691 			KEY_PARAMS_FIXED_LEN + sizeof(tkip_param));
3692 		cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) +
3693 					     S_DS_GEN + KEY_PARAMS_FIXED_LEN +
3694 					     sizeof(tkip_param) +
3695 					     sizeof(pkey_material->action));
3696 		PRINTM(MCMND, "Set TKIP Key\n");
3697 	}
3698 done:
3699 	LEAVE();
3700 	return ret;
3701 }
3702 
3703 /**
3704  *  @brief This function handles the command response of sta_list
3705  *
3706  *  @param pmpriv       A pointer to mlan_private structure
3707  *  @param resp         A pointer to HostCmd_DS_COMMAND
3708  *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
3709  *
3710  *  @return             MLAN_STATUS_SUCCESS
3711  */
wlan_uap_ret_sta_list(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)3712 static mlan_status wlan_uap_ret_sta_list(pmlan_private pmpriv,
3713 					 HostCmd_DS_COMMAND *resp,
3714 					 mlan_ioctl_req *pioctl_buf)
3715 {
3716 	HostCmd_DS_STA_LIST *sta_list =
3717 		(HostCmd_DS_STA_LIST *)&resp->params.sta_list;
3718 	mlan_ds_get_info *info;
3719 	MrvlIEtypes_sta_info_t *tlv = MNULL;
3720 	t_u8 i = 0;
3721 	sta_node *sta_ptr;
3722 	t_u8 tlv_len = 0;
3723 	t_u8 *buf = MNULL;
3724 	t_u8 *ie_buf = MNULL;
3725 
3726 	ENTER();
3727 	if (pioctl_buf) {
3728 		info = (mlan_ds_get_info *)pioctl_buf->pbuf;
3729 		info->param.sta_list.sta_count =
3730 			wlan_le16_to_cpu(sta_list->sta_count);
3731 		buf = sta_list->tlv_buf;
3732 		tlv = (MrvlIEtypes_sta_info_t *)buf;
3733 		info->param.sta_list.sta_count =
3734 			MIN(info->param.sta_list.sta_count, MAX_NUM_CLIENTS);
3735 		ie_buf = (t_u8 *)&info->param.sta_list.info[0];
3736 		ie_buf +=
3737 			sizeof(sta_info_data) * info->param.sta_list.sta_count;
3738 		pioctl_buf->data_read_written =
3739 			sizeof(mlan_ds_sta_list) -
3740 			sizeof(sta_info_data) * MAX_NUM_CLIENTS;
3741 		for (i = 0; i < info->param.sta_list.sta_count; i++) {
3742 			tlv_len = wlan_le16_to_cpu(tlv->header.len);
3743 			memcpy_ext(pmpriv->adapter,
3744 				   info->param.sta_list.info[i].mac_address,
3745 				   tlv->mac_address, MLAN_MAC_ADDR_LENGTH,
3746 				   MLAN_MAC_ADDR_LENGTH);
3747 			info->param.sta_list.info[i].ie_len =
3748 				tlv_len + sizeof(MrvlIEtypesHeader_t) -
3749 				sizeof(MrvlIEtypes_sta_info_t);
3750 			if (info->param.sta_list.info[i].ie_len) {
3751 				memcpy_ext(pmpriv->adapter, ie_buf, tlv->ie_buf,
3752 					   info->param.sta_list.info[i].ie_len,
3753 					   info->param.sta_list.info[i].ie_len);
3754 				ie_buf += info->param.sta_list.info[i].ie_len;
3755 			}
3756 			info->param.sta_list.info[i].power_mgmt_status =
3757 				tlv->power_mgmt_status;
3758 			info->param.sta_list.info[i].rssi = tlv->rssi;
3759 			sta_ptr = wlan_get_station_entry(pmpriv,
3760 							 tlv->mac_address);
3761 			if (sta_ptr) {
3762 				info->param.sta_list.info[i].bandmode =
3763 					sta_ptr->bandmode;
3764 				memcpy_ext(
3765 					pmpriv->adapter,
3766 					&(info->param.sta_list.info[i].stats),
3767 					&(sta_ptr->stats), sizeof(sta_stats),
3768 					sizeof(sta_stats));
3769 			} else
3770 				info->param.sta_list.info[i].bandmode = 0xFF;
3771 			pioctl_buf->data_read_written +=
3772 				sizeof(sta_info_data) +
3773 				info->param.sta_list.info[i].ie_len;
3774 			buf += sizeof(MrvlIEtypes_sta_info_t) +
3775 			       info->param.sta_list.info[i].ie_len;
3776 			tlv = (MrvlIEtypes_sta_info_t *)buf;
3777 		}
3778 		PRINTM(MCMND, "Total sta_list size=%d\n",
3779 		       pioctl_buf->data_read_written);
3780 	}
3781 
3782 	LEAVE();
3783 	return MLAN_STATUS_SUCCESS;
3784 }
3785 
3786 /** Fixed size of bss start event */
3787 #define BSS_START_EVENT_FIX_SIZE 12
3788 
3789 /**
3790  *  @brief This function will search for the specific ie
3791  *
3792  *  @param priv    A pointer to mlan_private
3793  *  @param pevent  A pointer to event buf
3794  *
3795  *  @return	       N/A
3796  */
wlan_check_uap_capability(pmlan_private priv,pmlan_buffer pevent)3797 static void wlan_check_uap_capability(pmlan_private priv, pmlan_buffer pevent)
3798 {
3799 	t_u16 tlv_type, tlv_len;
3800 	int tlv_buf_left = pevent->data_len - BSS_START_EVENT_FIX_SIZE;
3801 	MrvlIEtypesHeader_t *tlv =
3802 		(MrvlIEtypesHeader_t *)(pevent->pbuf + pevent->data_offset +
3803 					BSS_START_EVENT_FIX_SIZE);
3804 
3805 	const t_u8 wmm_oui[4] = {0x00, 0x50, 0xf2, 0x02};
3806 	IEEEtypes_WmmParameter_t wmm_param_ie;
3807 	MrvlIEtypes_channel_band_t *pchan_info;
3808 	t_u8 event_buf[100];
3809 	mlan_event *event = (mlan_event *)event_buf;
3810 	chan_band_info *pchan_band_info = (chan_band_info *)event->event_buf;
3811 	MrvlIEtypes_He_cap_t *pext_tlv = MNULL;
3812 
3813 	ENTER();
3814 	priv->wmm_enabled = MFALSE;
3815 	priv->pkt_fwd = MFALSE;
3816 	priv->is_11n_enabled = MFALSE;
3817 	priv->is_11ac_enabled = MFALSE;
3818 	priv->is_11ax_enabled = MFALSE;
3819 
3820 	while (tlv_buf_left >= (int)sizeof(MrvlIEtypesHeader_t)) {
3821 		tlv_type = wlan_le16_to_cpu(tlv->type);
3822 		tlv_len = wlan_le16_to_cpu(tlv->len);
3823 		if ((sizeof(MrvlIEtypesHeader_t) + tlv_len) >
3824 		    (unsigned int)tlv_buf_left) {
3825 			PRINTM(MERROR, "wrong tlv: tlvLen=%d, tlvBufLeft=%d\n",
3826 			       tlv_len, tlv_buf_left);
3827 			break;
3828 		}
3829 		if (tlv_type == HT_CAPABILITY) {
3830 			DBG_HEXDUMP(MCMD_D, "HT_CAP tlv", tlv,
3831 				    tlv_len + sizeof(MrvlIEtypesHeader_t));
3832 			priv->is_11n_enabled = MTRUE;
3833 		}
3834 		if (tlv_type == VHT_CAPABILITY) {
3835 			DBG_HEXDUMP(MCMD_D, "VHT_CAP tlv", tlv,
3836 				    tlv_len + sizeof(MrvlIEtypesHeader_t));
3837 			priv->is_11ac_enabled = MTRUE;
3838 		}
3839 		if (tlv_type == EXTENSION) {
3840 			pext_tlv = (MrvlIEtypes_He_cap_t *)tlv;
3841 			if (pext_tlv->ext_id == HE_CAPABILITY) {
3842 				DBG_HEXDUMP(
3843 					MCMD_D, "HE_CAP tlv", tlv,
3844 					tlv_len + sizeof(MrvlIEtypesHeader_t));
3845 				priv->is_11ax_enabled = MTRUE;
3846 			}
3847 		}
3848 
3849 		if (tlv_type == VENDOR_SPECIFIC_221) {
3850 			if (!memcmp(priv->adapter,
3851 				    (t_u8 *)tlv + sizeof(MrvlIEtypesHeader_t),
3852 				    wmm_oui, sizeof(wmm_oui))) {
3853 				DBG_HEXDUMP(
3854 					MCMD_D, "wmm ie tlv", tlv,
3855 					tlv_len + sizeof(MrvlIEtypesHeader_t));
3856 				priv->wmm_enabled = MFALSE;
3857 				wlan_wmm_setup_ac_downgrade(priv);
3858 				priv->wmm_enabled = MTRUE;
3859 				memcpy_ext(priv->adapter, &wmm_param_ie,
3860 					   ((t_u8 *)tlv + 2),
3861 					   sizeof(IEEEtypes_WmmParameter_t),
3862 					   sizeof(IEEEtypes_WmmParameter_t));
3863 				wmm_param_ie.vend_hdr.len = (t_u8)tlv_len;
3864 				wmm_param_ie.vend_hdr.element_id = WMM_IE;
3865 				wlan_wmm_setup_queue_priorities(priv,
3866 								&wmm_param_ie);
3867 			}
3868 		}
3869 		if (tlv_type == TLV_TYPE_UAP_PKT_FWD_CTL) {
3870 			DBG_HEXDUMP(MCMD_D, "pkt_fwd tlv", tlv,
3871 				    tlv_len + sizeof(MrvlIEtypesHeader_t));
3872 			priv->pkt_fwd =
3873 				*((t_u8 *)tlv + sizeof(MrvlIEtypesHeader_t));
3874 			PRINTM(MCMND, "pkt_fwd FW: 0x%x\n", priv->pkt_fwd);
3875 			if (priv->pkt_fwd & PKT_FWD_FW_BIT)
3876 				priv->pkt_fwd = MFALSE;
3877 			else
3878 				priv->pkt_fwd |= PKT_FWD_ENABLE_BIT;
3879 			PRINTM(MCMND, "pkt_fwd DRV: 0x%x\n", priv->pkt_fwd);
3880 		}
3881 		if (tlv_type == TLV_TYPE_UAP_CHAN_BAND_CONFIG) {
3882 			DBG_HEXDUMP(MCMD_D, "chan_band_config tlv", tlv,
3883 				    tlv_len + sizeof(MrvlIEtypesHeader_t));
3884 			pchan_info = (MrvlIEtypes_channel_band_t *)tlv;
3885 			priv->uap_channel = pchan_info->channel;
3886 			priv->uap_bandwidth = pchan_info->bandcfg.chanWidth;
3887 			priv->uap_state_chan_cb.channel = pchan_info->channel;
3888 			priv->uap_state_chan_cb.bandcfg = pchan_info->bandcfg;
3889 			PRINTM(MCMND, "uap_channel FW: 0x%x bw=%d\n",
3890 			       priv->uap_channel, priv->uap_bandwidth);
3891 			event->bss_index = priv->bss_index;
3892 			event->event_id = MLAN_EVENT_ID_DRV_UAP_CHAN_INFO;
3893 			event->event_len = sizeof(chan_band_info);
3894 			memcpy_ext(priv->adapter,
3895 				   (t_u8 *)&pchan_band_info->bandcfg,
3896 				   (t_u8 *)&pchan_info->bandcfg, tlv_len,
3897 				   tlv_len);
3898 			if (pchan_band_info->bandcfg.chanWidth == CHAN_BW_80MHZ)
3899 				pchan_band_info->center_chan =
3900 					wlan_get_center_freq_idx(
3901 						priv, BAND_AAC,
3902 						pchan_info->channel,
3903 						CHANNEL_BW_80MHZ);
3904 			if (priv->adapter->ecsa_enable) {
3905 				int ret;
3906 				t_u8 bandwidth = BW_20MHZ;
3907 
3908 				MrvlIEtypes_chan_bw_oper_t chan_bw_oper;
3909 				chan_bw_oper.header.type = REGULATORY_CLASS;
3910 				chan_bw_oper.header.len =
3911 					sizeof(MrvlIEtypes_chan_bw_oper_t);
3912 				chan_bw_oper.ds_chan_bw_oper.channel =
3913 					pchan_info->channel;
3914 
3915 				if (pchan_band_info->bandcfg.chanWidth ==
3916 				    CHAN_BW_40MHZ)
3917 					bandwidth = BW_40MHZ;
3918 				else if (pchan_band_info->bandcfg.chanWidth ==
3919 					 CHAN_BW_80MHZ)
3920 					bandwidth = BW_80MHZ;
3921 				chan_bw_oper.ds_chan_bw_oper.bandwidth =
3922 					bandwidth;
3923 
3924 				ret = wlan_prepare_cmd(
3925 					priv, HOST_CMD_APCMD_SYS_CONFIGURE,
3926 					HostCmd_ACT_GEN_SET, 0, MNULL,
3927 					&chan_bw_oper);
3928 				if (ret != MLAN_STATUS_SUCCESS &&
3929 				    ret != MLAN_STATUS_PENDING) {
3930 					PRINTM(MERROR,
3931 					       "%s(): Could not set supported operating class IE for priv=%p [priv_bss_idx=%d]!\n",
3932 					       __func__, priv, priv->bss_index);
3933 				}
3934 			}
3935 		}
3936 
3937 		tlv_buf_left -= (sizeof(MrvlIEtypesHeader_t) + tlv_len);
3938 		tlv = (MrvlIEtypesHeader_t *)((t_u8 *)tlv + tlv_len +
3939 					      sizeof(MrvlIEtypesHeader_t));
3940 	}
3941 	if (priv->wmm_enabled == MFALSE) {
3942 		/* Since WMM is not enabled, setup the queues with the defaults
3943 		 */
3944 		wlan_wmm_setup_queues(priv);
3945 	}
3946 	if (event->event_id == MLAN_EVENT_ID_DRV_UAP_CHAN_INFO) {
3947 		pchan_band_info->is_11n_enabled = priv->is_11n_enabled;
3948 		wlan_recv_event(priv, MLAN_EVENT_ID_DRV_UAP_CHAN_INFO, event);
3949 	}
3950 
3951 	LEAVE();
3952 }
3953 
3954 /**
3955  *  @brief This function will update WAPI PN in statation assoc event
3956  *
3957  *  @param priv    A pointer to mlan_private
3958  *  @param pevent  A pointer to event buf
3959  *
3960  *  @return	       MFALSE
3961  */
wlan_update_wapi_info_tlv(pmlan_private priv,pmlan_buffer pevent)3962 static t_u32 wlan_update_wapi_info_tlv(pmlan_private priv, pmlan_buffer pevent)
3963 {
3964 	t_u32 ret = MFALSE;
3965 	t_u16 tlv_type, tlv_len;
3966 	t_u32 tx_pn[4];
3967 	t_u32 i = 0;
3968 	int tlv_buf_left = pevent->data_len - ASSOC_EVENT_FIX_SIZE;
3969 	MrvlIEtypesHeader_t *tlv =
3970 		(MrvlIEtypesHeader_t *)(pevent->pbuf + pevent->data_offset +
3971 					ASSOC_EVENT_FIX_SIZE);
3972 	MrvlIEtypes_wapi_info_t *wapi_tlv = MNULL;
3973 
3974 	ENTER();
3975 	while (tlv_buf_left >= (int)sizeof(MrvlIEtypesHeader_t)) {
3976 		tlv_type = wlan_le16_to_cpu(tlv->type);
3977 		tlv_len = wlan_le16_to_cpu(tlv->len);
3978 		if ((sizeof(MrvlIEtypesHeader_t) + tlv_len) >
3979 		    (unsigned int)tlv_buf_left) {
3980 			PRINTM(MERROR, "wrong tlv: tlvLen=%d, tlvBufLeft=%d\n",
3981 			       tlv_len, tlv_buf_left);
3982 			break;
3983 		}
3984 		if (tlv_type == TLV_TYPE_AP_WAPI_INFO) {
3985 			wapi_tlv = (MrvlIEtypes_wapi_info_t *)tlv;
3986 			DBG_HEXDUMP(MCMD_D, "Fw:multicast_PN",
3987 				    wapi_tlv->multicast_PN, PN_SIZE);
3988 			memcpy_ext(priv->adapter, (t_u8 *)tx_pn,
3989 				   wapi_tlv->multicast_PN, PN_SIZE,
3990 				   sizeof(tx_pn));
3991 			for (i = 0; i < 4; i++)
3992 				tx_pn[i] = mlan_ntohl(tx_pn[i]);
3993 			memcpy_ext(priv->adapter, wapi_tlv->multicast_PN,
3994 				   (t_u8 *)tx_pn, PN_SIZE,
3995 				   sizeof(wapi_tlv->multicast_PN));
3996 			DBG_HEXDUMP(MCMD_D, "Host:multicast_PN",
3997 				    wapi_tlv->multicast_PN, PN_SIZE);
3998 			break;
3999 		}
4000 		tlv_buf_left -= (sizeof(MrvlIEtypesHeader_t) + tlv_len);
4001 		tlv = (MrvlIEtypesHeader_t *)((t_u8 *)tlv + tlv_len +
4002 					      sizeof(MrvlIEtypesHeader_t));
4003 	}
4004 	LEAVE();
4005 
4006 	return ret;
4007 }
4008 
4009 /**
4010  *  @brief This function send sta_assoc_event to moal
4011  *          payload with sta mac address and assoc ie.
4012  *
4013  *  @param priv    A pointer to mlan_private
4014  *  @param pevent  A pointer to mlan_event buffer
4015  *  @param pbuf    A pointer to mlan_buffer which has event content.
4016  *
4017  *  @return	       MFALSE
4018  */
wlan_process_sta_assoc_event(pmlan_private priv,mlan_event * pevent,pmlan_buffer pmbuf)4019 static t_u32 wlan_process_sta_assoc_event(pmlan_private priv,
4020 					  mlan_event *pevent,
4021 					  pmlan_buffer pmbuf)
4022 {
4023 	t_u32 ret = MFALSE;
4024 	t_u16 tlv_type, tlv_len;
4025 	t_u16 frame_control, frame_sub_type = 0;
4026 	t_u8 *assoc_req_ie = MNULL;
4027 	t_u8 ie_len = 0, assoc_ie_len = 0;
4028 	int tlv_buf_left = pmbuf->data_len - ASSOC_EVENT_FIX_SIZE;
4029 	MrvlIEtypesHeader_t *tlv =
4030 		(MrvlIEtypesHeader_t *)(pmbuf->pbuf + pmbuf->data_offset +
4031 					ASSOC_EVENT_FIX_SIZE);
4032 	MrvlIETypes_MgmtFrameSet_t *mgmt_tlv = MNULL;
4033 
4034 	ENTER();
4035 	pevent->event_id = MLAN_EVENT_ID_UAP_FW_STA_CONNECT;
4036 	pevent->bss_index = priv->bss_index;
4037 	pevent->event_len = MLAN_MAC_ADDR_LENGTH;
4038 	memcpy_ext(priv->adapter, pevent->event_buf,
4039 		   pmbuf->pbuf + pmbuf->data_offset + 6, pevent->event_len,
4040 		   pevent->event_len);
4041 	while (tlv_buf_left >= (int)sizeof(MrvlIEtypesHeader_t)) {
4042 		tlv_type = wlan_le16_to_cpu(tlv->type);
4043 		tlv_len = wlan_le16_to_cpu(tlv->len);
4044 		if ((sizeof(MrvlIEtypesHeader_t) + tlv_len) >
4045 		    (unsigned int)tlv_buf_left) {
4046 			PRINTM(MERROR, "wrong tlv: tlvLen=%d, tlvBufLeft=%d\n",
4047 			       tlv_len, tlv_buf_left);
4048 			break;
4049 		}
4050 		if (tlv_type == TLV_TYPE_MGMT_FRAME) {
4051 			mgmt_tlv = (MrvlIETypes_MgmtFrameSet_t *)tlv;
4052 			memcpy_ext(priv->adapter, &frame_control,
4053 				   (t_u8 *)&(mgmt_tlv->frame_control),
4054 				   sizeof(frame_control),
4055 				   sizeof(frame_control));
4056 			frame_sub_type = IEEE80211_GET_FC_MGMT_FRAME_SUBTYPE(
4057 				frame_control);
4058 			if ((mgmt_tlv->frame_control.type == 0) &&
4059 			    ((frame_sub_type == SUBTYPE_ASSOC_REQUEST) ||
4060 			     (frame_sub_type == SUBTYPE_REASSOC_REQUEST))) {
4061 				if (frame_sub_type == SUBTYPE_ASSOC_REQUEST)
4062 					assoc_ie_len =
4063 						sizeof(IEEEtypes_AssocRqst_t);
4064 				else if (frame_sub_type ==
4065 					 SUBTYPE_REASSOC_REQUEST)
4066 					assoc_ie_len =
4067 						sizeof(IEEEtypes_ReAssocRqst_t);
4068 
4069 				ie_len = tlv_len -
4070 					 sizeof(IEEEtypes_FrameCtl_t) -
4071 					 assoc_ie_len;
4072 				assoc_req_ie =
4073 					(t_u8 *)tlv +
4074 					sizeof(MrvlIETypes_MgmtFrameSet_t) +
4075 					assoc_ie_len;
4076 				memcpy_ext(priv->adapter,
4077 					   pevent->event_buf +
4078 						   pevent->event_len,
4079 					   assoc_req_ie, ie_len, ie_len);
4080 				pevent->event_len += ie_len;
4081 				break;
4082 			}
4083 		}
4084 		tlv_buf_left -= (sizeof(MrvlIEtypesHeader_t) + tlv_len);
4085 		tlv = (MrvlIEtypesHeader_t *)((t_u8 *)tlv + tlv_len +
4086 					      sizeof(MrvlIEtypesHeader_t));
4087 	}
4088 	PRINTM(MEVENT, "STA assoc event len=%d\n", pevent->event_len);
4089 	DBG_HEXDUMP(MCMD_D, "STA assoc event", pevent->event_buf,
4090 		    pevent->event_len);
4091 	wlan_recv_event(priv, pevent->event_id, pevent);
4092 	LEAVE();
4093 	return ret;
4094 }
4095 
4096 /**
4097  *  @brief This function handles repsonse of acs_scan.
4098  *
4099  *  @param pmpriv       A pointer to mlan_private structure
4100  *  @param pcmd         A pointer to HostCmd_DS_COMMAND structure
4101  *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
4102  *
4103  *  @return             MLAN_STATUS_SUCCESS
4104  */
wlan_ret_cmd_uap_acs_scan(pmlan_private pmpriv,const HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)4105 static mlan_status wlan_ret_cmd_uap_acs_scan(pmlan_private pmpriv,
4106 					     const HostCmd_DS_COMMAND *resp,
4107 					     mlan_ioctl_req *pioctl_buf)
4108 {
4109 	HostCMD_DS_APCMD_ACS_SCAN *acs_scan =
4110 		(HostCMD_DS_APCMD_ACS_SCAN *)&resp->params.acs_scan;
4111 	mlan_ds_bss *bss = MNULL;
4112 
4113 	ENTER();
4114 	PRINTM(MCMND, "ACS scan done: bandcfg=%x, channel=%d\n",
4115 	       acs_scan->bandcfg, acs_scan->chan);
4116 	if (pioctl_buf) {
4117 		bss = (mlan_ds_bss *)pioctl_buf->pbuf;
4118 		bss->param.ap_acs_scan.chan = acs_scan->chan;
4119 		bss->param.ap_acs_scan.bandcfg = acs_scan->bandcfg;
4120 		pioctl_buf->data_read_written = sizeof(mlan_ds_bss);
4121 	}
4122 
4123 	LEAVE();
4124 	return MLAN_STATUS_SUCCESS;
4125 }
4126 
4127 /**
4128  *  @brief This function prepares command of uap operation control
4129  *
4130  *  @param pmpriv		A pointer to mlan_private structure
4131  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
4132  *  @param cmd_action   the action: GET or SET
4133  *  @param pdata_buf    A pointer to data buffer
4134  *  @return         MLAN_STATUS_SUCCESS
4135  */
wlan_uap_cmd_oper_ctrl(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)4136 static mlan_status wlan_uap_cmd_oper_ctrl(pmlan_private pmpriv,
4137 					  HostCmd_DS_COMMAND *cmd,
4138 					  t_u16 cmd_action, t_void *pdata_buf)
4139 {
4140 	HostCmd_DS_UAP_OPER_CTRL *poper_ctl =
4141 		(HostCmd_DS_UAP_OPER_CTRL *)&cmd->params.uap_oper_ctrl;
4142 	mlan_ds_bss *bss = (mlan_ds_bss *)pdata_buf;
4143 	mlan_uap_oper_ctrl *uap_oper_ctrl = &bss->param.ap_oper_ctrl;
4144 	Band_Config_t *bandcfg = MNULL;
4145 
4146 	ENTER();
4147 
4148 	cmd->command = wlan_cpu_to_le16(HOST_CMD_APCMD_OPER_CTRL);
4149 	cmd->size =
4150 		wlan_cpu_to_le16(sizeof(HostCmd_DS_UAP_OPER_CTRL) + S_DS_GEN);
4151 	poper_ctl->action = wlan_cpu_to_le16(cmd_action);
4152 
4153 	if (cmd_action == HostCmd_ACT_GEN_SET) {
4154 		poper_ctl->ctrl = wlan_cpu_to_le16(uap_oper_ctrl->ctrl_value);
4155 		if (uap_oper_ctrl->ctrl_value == 2) {
4156 			poper_ctl->chan_opt =
4157 				wlan_cpu_to_le16(uap_oper_ctrl->chan_opt);
4158 			if (uap_oper_ctrl->chan_opt == 3) {
4159 				poper_ctl->channel_band.header.type =
4160 					wlan_cpu_to_le16(
4161 						TLV_TYPE_UAP_CHAN_BAND_CONFIG);
4162 				poper_ctl->channel_band.header
4163 					.len = wlan_cpu_to_le16(
4164 					sizeof(MrvlIEtypes_channel_band_t) -
4165 					sizeof(MrvlIEtypesHeader_t));
4166 				bandcfg = &poper_ctl->channel_band.bandcfg;
4167 				if (uap_oper_ctrl->channel > 14)
4168 					bandcfg->chanBand = BAND_5GHZ;
4169 				bandcfg->chanWidth = uap_oper_ctrl->band_cfg;
4170 				if (bandcfg->chanWidth)
4171 					bandcfg->chan2Offset =
4172 						wlan_get_second_channel_offset(
4173 							pmpriv,
4174 							uap_oper_ctrl->channel);
4175 				bandcfg->scanMode = SCAN_MODE_MANUAL;
4176 				poper_ctl->channel_band.channel =
4177 					uap_oper_ctrl->channel;
4178 			}
4179 		}
4180 	}
4181 
4182 	LEAVE();
4183 	return MLAN_STATUS_SUCCESS;
4184 }
4185 
4186 /**
4187  *  @brief This function handles the command response of uap operation control
4188  *
4189  *  @param pmpriv       A pointer to mlan_private structure
4190  *  @param resp         A pointer to HostCmd_DS_COMMAND
4191  *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
4192  *
4193  *  @return             MLAN_STATUS_SUCCESS
4194  */
wlan_uap_ret_oper_ctrl(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)4195 static mlan_status wlan_uap_ret_oper_ctrl(pmlan_private pmpriv,
4196 					  HostCmd_DS_COMMAND *resp,
4197 					  mlan_ioctl_req *pioctl_buf)
4198 {
4199 	HostCmd_DS_UAP_OPER_CTRL *poper_ctl =
4200 		(HostCmd_DS_UAP_OPER_CTRL *)&resp->params.uap_oper_ctrl;
4201 	mlan_ds_bss *bss = MNULL;
4202 	mlan_uap_oper_ctrl *uap_oper_ctrl = MNULL;
4203 	Band_Config_t *bandcfg = MNULL;
4204 
4205 	ENTER();
4206 
4207 	if (pioctl_buf && pioctl_buf->action == MLAN_ACT_GET) {
4208 		bss = (mlan_ds_bss *)pioctl_buf->pbuf;
4209 		uap_oper_ctrl = (mlan_uap_oper_ctrl *)&bss->param.ap_oper_ctrl;
4210 		uap_oper_ctrl->ctrl_value = wlan_le16_to_cpu(poper_ctl->ctrl);
4211 		uap_oper_ctrl->chan_opt = wlan_le16_to_cpu(poper_ctl->chan_opt);
4212 		uap_oper_ctrl->channel = poper_ctl->channel_band.channel;
4213 		bandcfg = &poper_ctl->channel_band.bandcfg;
4214 		uap_oper_ctrl->band_cfg = bandcfg->chanWidth;
4215 	}
4216 
4217 	LEAVE();
4218 	return MLAN_STATUS_SUCCESS;
4219 }
4220 
4221 /**
4222  *  @brief	Check 11B support Rates
4223  *
4224  *
4225  *  @param pmadapter	Private mlan adapter structure
4226  *
4227  *  @return MTRUE/MFALSE
4228  *
4229  */
4230 static t_u8
wlan_check_11B_support_rates(MrvlIEtypes_RatesParamSet_t * prates_tlv)4231 wlan_check_11B_support_rates(MrvlIEtypes_RatesParamSet_t *prates_tlv)
4232 {
4233 	int i;
4234 	t_u8 rate;
4235 	t_u8 ret = MTRUE;
4236 	for (i = 0; i < prates_tlv->header.len; i++) {
4237 		rate = prates_tlv->rates[i] & 0x7f;
4238 		if ((rate != 0x02) && (rate != 0x04) && (rate != 0x0b) &&
4239 		    (rate != 0x16)) {
4240 			ret = MFALSE;
4241 			break;
4242 		}
4243 	}
4244 	return ret;
4245 }
4246 
4247 /**
4248  *  @brief This function prepares command of sys_config
4249  *
4250  *  @param pmpriv       A pointer to mlan_private structure
4251  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
4252  *  @param cmd_action   cmd action
4253  *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
4254  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
4255  */
wlan_uap_cmd_add_station(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,pmlan_ioctl_req pioctl_buf)4256 static mlan_status wlan_uap_cmd_add_station(pmlan_private pmpriv,
4257 					    HostCmd_DS_COMMAND *cmd,
4258 					    t_u16 cmd_action,
4259 					    pmlan_ioctl_req pioctl_buf)
4260 {
4261 	mlan_ds_bss *bss = MNULL;
4262 	HostCmd_DS_ADD_STATION *new_sta =
4263 		(HostCmd_DS_ADD_STATION *)&cmd->params.sta_info;
4264 	sta_node *sta_ptr = MNULL;
4265 	t_u16 tlv_buf_left;
4266 	t_u8 *pos = MNULL;
4267 	t_u8 *tlv_buf = MNULL;
4268 	t_u16 travel_len = 0;
4269 	MrvlIEtypesHeader_t *tlv;
4270 	t_u16 tlv_len = 0;
4271 	t_u8 b_only = MFALSE;
4272 	mlan_adapter *pmadapter = pmpriv->adapter;
4273 	MrvlIETypes_HTCap_t *phtcap;
4274 	MrvlIETypes_VHTCap_t *pvhtcap;
4275 	MrvlIEtypes_Extension_t *pext_tlv = MNULL;
4276 	MrvlIEtypes_StaFlag_t *pstaflag;
4277 	int i;
4278 
4279 	ENTER();
4280 
4281 	if (!pioctl_buf) {
4282 		LEAVE();
4283 		return MLAN_STATUS_FAILURE;
4284 	}
4285 	bss = (mlan_ds_bss *)pioctl_buf->pbuf;
4286 	cmd->command = wlan_cpu_to_le16(HostCmd_CMD_ADD_NEW_STATION);
4287 	new_sta->action = wlan_cpu_to_le16(cmd_action);
4288 	cmd->size = sizeof(HostCmd_DS_ADD_STATION) + S_DS_GEN;
4289 	if (cmd_action == HostCmd_ACT_ADD_STA) {
4290 		sta_ptr = wlan_get_station_entry(pmpriv,
4291 						 bss->param.sta_info.peer_mac);
4292 		if (!sta_ptr)
4293 			sta_ptr = wlan_add_station_entry(
4294 				pmpriv, bss->param.sta_info.peer_mac);
4295 	} else {
4296 		sta_ptr = wlan_add_station_entry(pmpriv,
4297 						 bss->param.sta_info.peer_mac);
4298 	}
4299 	if (!sta_ptr) {
4300 		LEAVE();
4301 		return MLAN_STATUS_FAILURE;
4302 	}
4303 	memcpy_ext(pmadapter, new_sta->peer_mac, bss->param.sta_info.peer_mac,
4304 		   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
4305 	if (cmd_action != HostCmd_ACT_ADD_STA)
4306 		goto done;
4307 	new_sta->aid = wlan_cpu_to_le16(bss->param.sta_info.aid);
4308 	new_sta->listen_interval =
4309 		wlan_cpu_to_le32(bss->param.sta_info.listen_interval);
4310 	if (bss->param.sta_info.cap_info)
4311 		new_sta->cap_info =
4312 			wlan_cpu_to_le16(bss->param.sta_info.cap_info);
4313 	else
4314 		new_sta->cap_info = wlan_cpu_to_le16(sta_ptr->capability);
4315 	tlv_buf_left = bss->param.sta_info.tlv_len;
4316 	pos = new_sta->tlv;
4317 	tlv_buf = bss->param.sta_info.tlv;
4318 	tlv = (MrvlIEtypesHeader_t *)tlv_buf;
4319 	if (bss->param.sta_info.sta_flags & STA_FLAG_WME) {
4320 		PRINTM(MCMND, "STA flags supports wmm \n");
4321 		sta_ptr->is_wmm_enabled = MTRUE;
4322 	}
4323 	// append sta_flag_flags.
4324 	pstaflag = (MrvlIEtypes_StaFlag_t *)pos;
4325 	pstaflag->header.type = wlan_cpu_to_le16(TLV_TYPE_UAP_STA_FLAGS);
4326 	pstaflag->header.len = wlan_cpu_to_le16(sizeof(t_u32));
4327 	pstaflag->sta_flags = wlan_cpu_to_le32(bss->param.sta_info.sta_flags);
4328 	pos += sizeof(MrvlIEtypes_StaFlag_t);
4329 	cmd->size += sizeof(MrvlIEtypes_StaFlag_t);
4330 
4331 	while (tlv_buf_left >= sizeof(MrvlIEtypesHeader_t)) {
4332 		if (tlv_buf_left < (sizeof(MrvlIEtypesHeader_t) + tlv->len))
4333 			break;
4334 		switch (tlv->type) {
4335 		case EXT_CAPABILITY:
4336 			break;
4337 		case SUPPORTED_RATES:
4338 			b_only = wlan_check_11B_support_rates(
4339 				(MrvlIEtypes_RatesParamSet_t *)tlv);
4340 			break;
4341 		case QOS_INFO:
4342 			PRINTM(MCMND, "STA supports wmm\n");
4343 			sta_ptr->is_wmm_enabled = MTRUE;
4344 			break;
4345 		case HT_CAPABILITY:
4346 			PRINTM(MCMND, "STA supports 11n\n");
4347 			sta_ptr->is_11n_enabled = MTRUE;
4348 			phtcap = (MrvlIETypes_HTCap_t *)tlv;
4349 			if (sta_ptr->HTcap.ieee_hdr.element_id ==
4350 			    HT_CAPABILITY) {
4351 				if (GETHT_40MHZ_INTOLARANT(
4352 					    sta_ptr->HTcap.ht_cap.ht_cap_info)) {
4353 					PRINTM(MCMND,
4354 					       "SETHT_40MHZ_INTOLARANT\n");
4355 					SETHT_40MHZ_INTOLARANT(
4356 						phtcap->ht_cap.ht_cap_info);
4357 				}
4358 			}
4359 			if (GETHT_MAXAMSDU(phtcap->ht_cap.ht_cap_info))
4360 				sta_ptr->max_amsdu = MLAN_TX_DATA_BUF_SIZE_8K;
4361 			else
4362 				sta_ptr->max_amsdu = MLAN_TX_DATA_BUF_SIZE_4K;
4363 			break;
4364 		case VHT_CAPABILITY:
4365 			PRINTM(MCMND, "STA supports 11ac\n");
4366 			sta_ptr->is_11ac_enabled = MTRUE;
4367 			pvhtcap = (MrvlIETypes_VHTCap_t *)tlv;
4368 			if (GET_VHTCAP_MAXMPDULEN(
4369 				    pvhtcap->vht_cap.vht_cap_info) == 2)
4370 				sta_ptr->max_amsdu = MLAN_TX_DATA_BUF_SIZE_12K;
4371 			else if (GET_VHTCAP_MAXMPDULEN(
4372 					 pvhtcap->vht_cap.vht_cap_info) == 1)
4373 				sta_ptr->max_amsdu = MLAN_TX_DATA_BUF_SIZE_8K;
4374 			else
4375 				sta_ptr->max_amsdu = MLAN_TX_DATA_BUF_SIZE_4K;
4376 			break;
4377 		case OPER_MODE_NTF:
4378 			break;
4379 		case EXTENSION:
4380 			pext_tlv = (MrvlIEtypes_Extension_t *)tlv;
4381 			if (pext_tlv->ext_id == HE_CAPABILITY) {
4382 				sta_ptr->is_11ax_enabled = MTRUE;
4383 				PRINTM(MCMND, "STA supports 11ax\n");
4384 			} else {
4385 				pext_tlv = MNULL;
4386 			}
4387 			break;
4388 		default:
4389 			break;
4390 		}
4391 		tlv_len = tlv->len;
4392 		tlv->type = wlan_cpu_to_le16(tlv->type);
4393 		tlv->len = wlan_cpu_to_le16(tlv->len);
4394 		memcpy_ext(pmadapter, pos, (t_u8 *)tlv,
4395 			   sizeof(MrvlIEtypesHeader_t) + tlv_len,
4396 			   sizeof(MrvlIEtypesHeader_t) + tlv_len);
4397 		pos += sizeof(MrvlIEtypesHeader_t) + tlv_len;
4398 		tlv_buf += sizeof(MrvlIEtypesHeader_t) + tlv_len;
4399 		tlv = (MrvlIEtypesHeader_t *)tlv_buf;
4400 		travel_len += sizeof(MrvlIEtypesHeader_t) + tlv_len;
4401 		tlv_buf_left -= sizeof(MrvlIEtypesHeader_t) + tlv_len;
4402 	}
4403 	if (sta_ptr->is_11ax_enabled) {
4404 		if (pext_tlv == MNULL) {
4405 			tlv = (MrvlIEtypesHeader_t *)pos;
4406 			tlv->type = wlan_cpu_to_le16(EXTENSION);
4407 			tlv->len = wlan_cpu_to_le16(
4408 				MIN(sta_ptr->he_cap.ieee_hdr.len,
4409 				    sizeof(IEEEtypes_HECap_t) -
4410 					    sizeof(IEEEtypes_Header_t)));
4411 
4412 			pos += sizeof(MrvlIEtypesHeader_t);
4413 			memcpy_ext(pmadapter, pos,
4414 				   (t_u8 *)&sta_ptr->he_cap.ext_id, tlv->len,
4415 				   tlv->len);
4416 			travel_len += sizeof(MrvlIEtypesHeader_t) + tlv->len;
4417 		}
4418 	}
4419 
4420 	if (sta_ptr->is_11n_enabled) {
4421 		if (pmpriv->uap_channel <= 14)
4422 			sta_ptr->bandmode = BAND_GN;
4423 		else
4424 			sta_ptr->bandmode = BAND_AN;
4425 	} else if (!b_only) {
4426 		if (pmpriv->uap_channel <= 14)
4427 			sta_ptr->bandmode = BAND_G;
4428 		else
4429 			sta_ptr->bandmode = BAND_A;
4430 	} else
4431 		sta_ptr->bandmode = BAND_B;
4432 	if (sta_ptr->is_11ac_enabled) {
4433 		if (pmpriv->uap_channel <= 14)
4434 			sta_ptr->bandmode = BAND_GAC;
4435 		else
4436 			sta_ptr->bandmode = BAND_AAC;
4437 	}
4438 	if (sta_ptr->is_11ax_enabled) {
4439 		if (pmpriv->uap_channel <= 14)
4440 			sta_ptr->bandmode = BAND_GAX;
4441 		else
4442 			sta_ptr->bandmode = BAND_AAX;
4443 	}
4444 
4445 	for (i = 0; i < MAX_NUM_TID; i++) {
4446 		if (sta_ptr->is_11n_enabled || sta_ptr->is_11ax_enabled)
4447 			sta_ptr->ampdu_sta[i] =
4448 				pmpriv->aggr_prio_tbl[i].ampdu_user;
4449 		else
4450 			sta_ptr->ampdu_sta[i] = BA_STREAM_NOT_ALLOWED;
4451 	}
4452 	memset(pmadapter, sta_ptr->rx_seq, 0xff, sizeof(sta_ptr->rx_seq));
4453 done:
4454 	cmd->size += travel_len;
4455 	cmd->size = wlan_cpu_to_le16(cmd->size);
4456 	LEAVE();
4457 	return MLAN_STATUS_SUCCESS;
4458 }
4459 
4460 /**
4461  *  @brief This function prepares command of per peer stats
4462  *
4463  *  @param pmpriv        A pointer to mlan_private structure
4464  *  @param cmd           A pointer to HostCmd_DS_COMMAND structure
4465  *  @param cmd_action    the action: GET or SET
4466  *  @param pdata_buf     A pointer to data buffer
4467  *  @return              MLAN_STATUS_SUCCESS
4468  */
wlan_cmd_stats(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_void * pdata_buf)4469 static mlan_status wlan_cmd_stats(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
4470 				  t_u16 cmd_action, t_void *pdata_buf)
4471 {
4472 	HostCmd_DS_STATS *stats_cmd = (HostCmd_DS_STATS *)&cmd->params.stats;
4473 	Stats_Cfg_Params_TLV_t *cfg_param = MNULL;
4474 	mlan_ds_stats *stats = (mlan_ds_stats *)pdata_buf;
4475 	Stats_Cfg_Params_TLV_t *stats_param = MNULL;
4476 
4477 	ENTER();
4478 	cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_STATS);
4479 	cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_STATS) + S_DS_GEN);
4480 	if (cmd_action) {
4481 		cmd->size =
4482 			wlan_cpu_to_le16(sizeof(HostCmd_DS_STATS) + S_DS_GEN +
4483 					 sizeof(Stats_Cfg_Params_TLV_t) - 1);
4484 		stats_cmd->action = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
4485 
4486 		stats_param = (Stats_Cfg_Params_TLV_t *)stats->tlv_buf;
4487 		if (stats_param->tlvHeader.type ==
4488 		    NXP_802_11_PER_PEER_STATS_CFG_TLV_ID) {
4489 			cfg_param =
4490 				(Stats_Cfg_Params_TLV_t *)stats_cmd->tlv_buffer;
4491 			*cfg_param = *stats_param;
4492 		}
4493 	} else {
4494 		cmd->size =
4495 			wlan_cpu_to_le16(sizeof(HostCmd_DS_STATS) + S_DS_GEN);
4496 		stats_cmd->action = wlan_cpu_to_le16(HostCmd_ACT_GEN_GET);
4497 	}
4498 	LEAVE();
4499 	return MLAN_STATUS_SUCCESS;
4500 }
4501 
4502 /**
4503  *  @brief This function handles the command response of stats
4504  *
4505  *  @param pmpriv       A pointer to mlan_private structure
4506  *  @param resp         A pointer to HostCmd_DS_COMMAND
4507  *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
4508  *
4509  *  @return             MLAN_STATUS_SUCCESS
4510  */
wlan_ret_stats(pmlan_private pmpriv,HostCmd_DS_COMMAND * resp,mlan_ioctl_req * pioctl_buf)4511 static mlan_status wlan_ret_stats(pmlan_private pmpriv,
4512 				  HostCmd_DS_COMMAND *resp,
4513 				  mlan_ioctl_req *pioctl_buf)
4514 {
4515 	HostCmd_DS_STATS *cfg_cmd = (HostCmd_DS_STATS *)&resp->params.stats;
4516 	mlan_ds_misc_cfg *misc_cfg = MNULL;
4517 	t_u8 *pBuf = (t_u8 *)&cfg_cmd->tlv_buffer;
4518 	int len = resp->size;
4519 
4520 	ENTER();
4521 	if (pioctl_buf) {
4522 		misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
4523 		len -= (S_DS_GEN + sizeof(t_u16));
4524 		memcpy_ext(pmpriv->adapter,
4525 			   (t_u8 *)&misc_cfg->param.stats.tlv_buf, pBuf, len,
4526 			   len);
4527 		misc_cfg->param.stats.tlv_len = len;
4528 		pioctl_buf->buf_len = sizeof(mlan_ds_stats) + len - 1;
4529 	}
4530 
4531 	LEAVE();
4532 	return MLAN_STATUS_SUCCESS;
4533 }
4534 
4535 /********************************************************
4536 			Global Functions
4537 ********************************************************/
4538 /**
4539  *  @brief This function prepare the command before sending to firmware.
4540  *
4541  *  @param priv       A pointer to mlan_private structure
4542  *  @param cmd_no       Command number
4543  *  @param cmd_action   Command action: GET or SET
4544  *  @param cmd_oid      Cmd oid: treated as sub command
4545  *  @param pioctl_buf   A pointer to MLAN IOCTL Request buffer
4546  *  @param pdata_buf    A pointer to information buffer
4547  *  @param pcmd_buf      A pointer to cmd buf
4548  *
4549  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
4550  */
wlan_ops_uap_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)4551 mlan_status wlan_ops_uap_prepare_cmd(t_void *priv, t_u16 cmd_no,
4552 				     t_u16 cmd_action, t_u32 cmd_oid,
4553 				     t_void *pioctl_buf, t_void *pdata_buf,
4554 				     t_void *pcmd_buf)
4555 {
4556 	HostCmd_DS_COMMAND *cmd_ptr = (HostCmd_DS_COMMAND *)pcmd_buf;
4557 	mlan_private *pmpriv = (mlan_private *)priv;
4558 	mlan_status ret = MLAN_STATUS_SUCCESS;
4559 	pmlan_ioctl_req pioctl_req = (mlan_ioctl_req *)pioctl_buf;
4560 
4561 	ENTER();
4562 
4563 	/* Prepare command */
4564 	switch (cmd_no) {
4565 	case HostCMD_APCMD_ACS_SCAN:
4566 	case HostCmd_CMD_SOFT_RESET:
4567 	case HOST_CMD_APCMD_BSS_STOP:
4568 	case HOST_CMD_APCMD_SYS_INFO:
4569 	case HOST_CMD_APCMD_SYS_RESET:
4570 	case HOST_CMD_APCMD_STA_LIST:
4571 		cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
4572 		cmd_ptr->size = wlan_cpu_to_le16(S_DS_GEN);
4573 		break;
4574 	case HOST_CMD_APCMD_BSS_START:
4575 		ret = wlan_uap_cmd_bss_start(pmpriv, cmd_ptr);
4576 #ifdef DRV_EMBEDDED_AUTHENTICATOR
4577 		if (IsAuthenticatorEnabled(pmpriv->psapriv))
4578 			AuthenticatorBssConfig(pmpriv->psapriv, MNULL, 1, 0, 0);
4579 #endif
4580 		break;
4581 	case HOST_CMD_APCMD_SYS_CONFIGURE:
4582 		ret = wlan_uap_cmd_sys_configure(pmpriv, cmd_ptr, cmd_action,
4583 						 (pmlan_ioctl_req)pioctl_buf,
4584 						 pdata_buf);
4585 		break;
4586 	case HostCmd_CMD_802_11_PS_MODE_ENH:
4587 		ret = wlan_cmd_enh_power_mode(pmpriv, cmd_ptr, cmd_action,
4588 					      (t_u16)cmd_oid, pdata_buf);
4589 		break;
4590 #if defined(SDIO)
4591 	case HostCmd_CMD_SDIO_GPIO_INT_CONFIG:
4592 		ret = wlan_cmd_sdio_gpio_int(pmpriv, cmd_ptr, cmd_action,
4593 					     pdata_buf);
4594 		break;
4595 #endif
4596 	case HostCmd_CMD_FUNC_INIT:
4597 		if (pmpriv->adapter->hw_status == WlanHardwareStatusReset)
4598 			pmpriv->adapter->hw_status =
4599 				WlanHardwareStatusInitializing;
4600 		cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
4601 		cmd_ptr->size = wlan_cpu_to_le16(S_DS_GEN);
4602 		break;
4603 	case HostCmd_CMD_FUNC_SHUTDOWN:
4604 		pmpriv->adapter->hw_status = WlanHardwareStatusReset;
4605 		cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
4606 		cmd_ptr->size = wlan_cpu_to_le16(S_DS_GEN);
4607 		break;
4608 	case HostCmd_CMD_CFG_DATA:
4609 		ret = wlan_cmd_cfg_data(pmpriv, cmd_ptr, cmd_action, cmd_oid,
4610 					pdata_buf);
4611 		break;
4612 	case HostCmd_CMD_MAC_CONTROL:
4613 		ret = wlan_cmd_mac_control(pmpriv, cmd_ptr, cmd_action,
4614 					   pdata_buf);
4615 		break;
4616 	case HostCmd_CMD_802_11_SNMP_MIB:
4617 		ret = wlan_uap_cmd_snmp_mib(pmpriv, cmd_ptr, cmd_action,
4618 					    cmd_oid,
4619 					    (pmlan_ioctl_req)pioctl_buf,
4620 					    pdata_buf);
4621 		break;
4622 	case HostCmd_CMD_802_11_GET_LOG:
4623 		ret = wlan_uap_cmd_802_11_get_log(pmpriv, cmd_ptr);
4624 		break;
4625 	case HostCmd_CMD_802_11D_DOMAIN_INFO:
4626 		ret = wlan_cmd_802_11d_domain_info(pmpriv, cmd_ptr, cmd_action);
4627 		break;
4628 	case HostCmd_CMD_CHAN_REPORT_REQUEST:
4629 		ret = wlan_11h_cmd_process(pmpriv, cmd_ptr, pdata_buf);
4630 		break;
4631 	case HOST_CMD_APCMD_STA_DEAUTH:
4632 		ret = wlan_uap_cmd_sta_deauth(pmpriv, cmd_ptr, pdata_buf);
4633 		break;
4634 	case HOST_CMD_APCMD_REPORT_MIC:
4635 		ret = wlan_uap_cmd_report_mic(pmpriv, cmd_ptr, pdata_buf);
4636 		break;
4637 	case HostCmd_CMD_802_11_KEY_MATERIAL:
4638 		ret = wlan_uap_cmd_key_material(pmpriv, cmd_ptr, cmd_action,
4639 						cmd_oid, pdata_buf);
4640 		break;
4641 	case HostCmd_CMD_GET_HW_SPEC:
4642 		ret = wlan_cmd_get_hw_spec(pmpriv, cmd_ptr);
4643 		break;
4644 #ifdef SDIO
4645 	case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG:
4646 		ret = wlan_cmd_sdio_rx_aggr_cfg(cmd_ptr, cmd_action, pdata_buf);
4647 		break;
4648 #endif
4649 	case HostCmd_CMD_802_11_HS_CFG_ENH:
4650 		ret = wlan_uap_cmd_802_11_hs_cfg(pmpriv, cmd_ptr, cmd_action,
4651 						 (hs_config_param *)pdata_buf);
4652 		break;
4653 	case HostCmd_CMD_HS_WAKEUP_REASON:
4654 		ret = wlan_cmd_hs_wakeup_reason(pmpriv, cmd_ptr, pdata_buf);
4655 		break;
4656 	case HostCmd_CMD_802_11_ROBUSTCOEX:
4657 		ret = wlan_cmd_robustcoex(pmpriv, cmd_ptr, cmd_action,
4658 					  (t_u16 *)pdata_buf);
4659 		break;
4660 	case HostCmd_CMD_DMCS_CONFIG:
4661 		ret = wlan_cmd_dmcs_config(pmpriv, cmd_ptr, cmd_action,
4662 					   pdata_buf);
4663 		break;
4664 	case HostCmd_CMD_RECONFIGURE_TX_BUFF:
4665 		ret = wlan_cmd_recfg_tx_buf(pmpriv, cmd_ptr, cmd_action,
4666 					    pdata_buf);
4667 		break;
4668 	case HostCmd_CMD_AMSDU_AGGR_CTRL:
4669 		ret = wlan_cmd_amsdu_aggr_ctrl(pmpriv, cmd_ptr, cmd_action,
4670 					       pdata_buf);
4671 		break;
4672 	case HostCmd_CMD_11N_CFG:
4673 		ret = wlan_cmd_11n_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
4674 		break;
4675 	case HostCmd_CMD_11N_ADDBA_REQ:
4676 		ret = wlan_cmd_11n_addba_req(pmpriv, cmd_ptr, pdata_buf);
4677 		break;
4678 	case HostCmd_CMD_11N_DELBA:
4679 		ret = wlan_cmd_11n_delba(pmpriv, cmd_ptr, pdata_buf);
4680 		break;
4681 	case HostCmd_CMD_11N_ADDBA_RSP:
4682 		ret = wlan_cmd_11n_addba_rspgen(pmpriv, cmd_ptr, pdata_buf);
4683 		break;
4684 	case HostCmd_CMD_REJECT_ADDBA_REQ:
4685 		ret = wlan_cmd_reject_addba_req(pmpriv, cmd_ptr, cmd_action,
4686 						pdata_buf);
4687 		break;
4688 	case HostCmd_CMD_TX_BF_CFG:
4689 		ret = wlan_cmd_tx_bf_cfg(pmpriv, cmd_ptr, cmd_action,
4690 					 pdata_buf);
4691 		break;
4692 #if defined(WIFI_DIRECT_SUPPORT)
4693 	case HostCmd_CMD_SET_BSS_MODE:
4694 		cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
4695 		if (pdata_buf)
4696 			cmd_ptr->params.bss_mode.con_type = *(t_u8 *)pdata_buf;
4697 		else
4698 			cmd_ptr->params.bss_mode.con_type =
4699 				BSS_MODE_WIFIDIRECT_GO;
4700 		cmd_ptr->size = wlan_cpu_to_le16(
4701 			sizeof(HostCmd_DS_SET_BSS_MODE) + S_DS_GEN);
4702 		ret = MLAN_STATUS_SUCCESS;
4703 		break;
4704 #endif
4705 	case HostCmd_CMD_VERSION_EXT:
4706 		cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
4707 		cmd_ptr->params.verext.version_str_sel =
4708 			(t_u8)(*((t_u32 *)pdata_buf));
4709 		cmd_ptr->size = wlan_cpu_to_le16(
4710 			sizeof(HostCmd_DS_VERSION_EXT) + S_DS_GEN);
4711 		ret = MLAN_STATUS_SUCCESS;
4712 		break;
4713 	case HostCmd_CMD_RX_MGMT_IND:
4714 		cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
4715 		cmd_ptr->params.rx_mgmt_ind.action =
4716 			wlan_cpu_to_le16(cmd_action);
4717 		cmd_ptr->params.rx_mgmt_ind.mgmt_subtype_mask =
4718 			(t_u32)(*((t_u32 *)pdata_buf));
4719 		cmd_ptr->size = wlan_cpu_to_le16(
4720 			sizeof(HostCmd_DS_RX_MGMT_IND) + S_DS_GEN);
4721 		break;
4722 	case HostCmd_CMD_CFG_TX_DATA_PAUSE:
4723 		ret = wlan_uap_cmd_txdatapause(pmpriv, cmd_ptr, cmd_action,
4724 					       pdata_buf);
4725 		break;
4726 	case HostCmd_CMD_802_11_RADIO_CONTROL:
4727 		ret = wlan_cmd_802_11_radio_control(pmpriv, cmd_ptr, cmd_action,
4728 						    pdata_buf);
4729 		break;
4730 	case HostCmd_CMD_TX_RATE_CFG:
4731 		ret = wlan_cmd_tx_rate_cfg(pmpriv, cmd_ptr, cmd_action,
4732 					   pdata_buf, pioctl_buf);
4733 		break;
4734 	case HostCmd_CMD_802_11_TX_RATE_QUERY:
4735 		cmd_ptr->command =
4736 			wlan_cpu_to_le16(HostCmd_CMD_802_11_TX_RATE_QUERY);
4737 		cmd_ptr->size = wlan_cpu_to_le16(sizeof(HostCmd_TX_RATE_QUERY) +
4738 						 S_DS_GEN);
4739 		pmpriv->tx_rate = 0;
4740 		ret = MLAN_STATUS_SUCCESS;
4741 		break;
4742 	case HostCmd_CMD_802_11_REMAIN_ON_CHANNEL:
4743 		ret = wlan_cmd_remain_on_channel(pmpriv, cmd_ptr, cmd_action,
4744 						 pdata_buf);
4745 		break;
4746 #ifdef WIFI_DIRECT_SUPPORT
4747 	case HOST_CMD_WIFI_DIRECT_MODE_CONFIG:
4748 		ret = wlan_cmd_wifi_direct_mode(pmpriv, cmd_ptr, cmd_action,
4749 						pdata_buf);
4750 		break;
4751 	case HOST_CMD_P2P_PARAMS_CONFIG:
4752 		ret = wlan_cmd_p2p_params_config(pmpriv, cmd_ptr, cmd_action,
4753 						 pdata_buf);
4754 		break;
4755 #endif
4756 	case HOST_CMD_GPIO_TSF_LATCH_PARAM_CONFIG:
4757 		ret = wlan_cmd_gpio_tsf_latch(pmpriv, cmd_ptr, cmd_action,
4758 					      pioctl_buf, pdata_buf);
4759 		break;
4760 	case HostCmd_CMD_802_11_RF_ANTENNA:
4761 		ret = wlan_cmd_802_11_rf_antenna(pmpriv, cmd_ptr, cmd_action,
4762 						 pdata_buf);
4763 		break;
4764 	case HostCmd_CMD_802_11_MIMO_SWITCH:
4765 		ret = wlan_cmd_802_11_mimo_switch(pmpriv, cmd_ptr, pdata_buf);
4766 		break;
4767 	case HostCmd_CMD_11AC_CFG:
4768 		ret = wlan_cmd_11ac_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
4769 		break;
4770 	case HostCmd_CMD_DYN_BW:
4771 		ret = wlan_cmd_config_dyn_bw(pmpriv, cmd_ptr, cmd_action,
4772 					     pdata_buf);
4773 		break;
4774 	case HostCmd_CMD_MAC_REG_ACCESS:
4775 	case HostCmd_CMD_BBP_REG_ACCESS:
4776 	case HostCmd_CMD_RF_REG_ACCESS:
4777 	case HostCmd_CMD_CAU_REG_ACCESS:
4778 	case HostCmd_CMD_TARGET_ACCESS:
4779 	case HostCmd_CMD_802_11_EEPROM_ACCESS:
4780 	case HostCmd_CMD_BCA_REG_ACCESS:
4781 	case HostCmd_CMD_REG_ACCESS:
4782 		ret = wlan_cmd_reg_access(pmpriv, cmd_ptr, cmd_action,
4783 					  pdata_buf);
4784 		break;
4785 	case HostCmd_CMD_MEM_ACCESS:
4786 		ret = wlan_cmd_mem_access(cmd_ptr, cmd_action, pdata_buf);
4787 		break;
4788 	case HostCmd_CMD_WMM_QUEUE_CONFIG:
4789 		ret = wlan_cmd_wmm_queue_config(pmpriv, cmd_ptr, pdata_buf);
4790 		break;
4791 #ifdef RX_PACKET_COALESCE
4792 	case HostCmd_CMD_RX_PKT_COALESCE_CFG:
4793 		ret = wlan_cmd_rx_pkt_coalesce_cfg(pmpriv, cmd_ptr, cmd_action,
4794 						   pdata_buf);
4795 		break;
4796 #endif
4797 	case HOST_CMD_APCMD_OPER_CTRL:
4798 		ret = wlan_uap_cmd_oper_ctrl(pmpriv, cmd_ptr, cmd_action,
4799 					     pdata_buf);
4800 		break;
4801 
4802 	case HostCmd_CMD_INDEPENDENT_RESET_CFG:
4803 		ret = wlan_cmd_ind_rst_cfg(cmd_ptr, cmd_action, pdata_buf);
4804 		break;
4805 	case HostCmd_CMD_GET_TSF:
4806 		ret = wlan_cmd_get_tsf(pmpriv, cmd_ptr, cmd_action);
4807 		break;
4808 
4809 	case HostCmd_CMD_802_11_PS_INACTIVITY_TIMEOUT:
4810 		ret = wlan_cmd_ps_inactivity_timeout(pmpriv, cmd_ptr,
4811 						     cmd_action, pdata_buf);
4812 		break;
4813 
4814 	case HostCmd_CMD_CHAN_REGION_CFG:
4815 		cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
4816 		cmd_ptr->size = wlan_cpu_to_le16(
4817 			sizeof(HostCmd_DS_CHAN_REGION_CFG) + S_DS_GEN);
4818 		cmd_ptr->params.reg_cfg.action = wlan_cpu_to_le16(cmd_action);
4819 		break;
4820 	case HostCmd_CMD_802_11_NET_MONITOR:
4821 		ret = wlan_cmd_net_monitor(pmpriv, cmd_ptr, cmd_action,
4822 					   pdata_buf);
4823 		break;
4824 	case HostCmd_CMD_PACKET_AGGR_CTRL:
4825 		ret = wlan_cmd_packet_aggr_ctrl(pmpriv, cmd_ptr, cmd_action,
4826 						pdata_buf);
4827 		break;
4828 #if defined(PCIE)
4829 #if defined(PCIE8997) || defined(PCIE8897)
4830 	case HostCmd_CMD_PCIE_HOST_BUF_DETAILS:
4831 		ret = wlan_cmd_pcie_host_buf_cfg(pmpriv, cmd_ptr, cmd_action,
4832 						 pdata_buf);
4833 		break;
4834 #endif
4835 #endif
4836 	case HOST_CMD_TX_RX_PKT_STATS:
4837 		ret = wlan_cmd_tx_rx_pkt_stats(pmpriv, cmd_ptr,
4838 					       (pmlan_ioctl_req)pioctl_buf,
4839 					       pdata_buf);
4840 		break;
4841 	case HostCmd_CMD_FW_DUMP_EVENT:
4842 		ret = wlan_cmd_fw_dump_event(pmpriv, cmd_ptr, cmd_action,
4843 					     pdata_buf);
4844 		break;
4845 	case HostCmd_CMD_802_11_LINK_STATS:
4846 		ret = wlan_cmd_802_11_link_statistic(pmpriv, cmd_ptr,
4847 						     cmd_action, pioctl_buf);
4848 		break;
4849 	case HostCmd_CMD_ADD_NEW_STATION:
4850 		ret = wlan_uap_cmd_add_station(pmpriv, cmd_ptr, cmd_action,
4851 					       (pmlan_ioctl_req)pioctl_buf);
4852 		break;
4853 	case HostCmd_CMD_BOOT_SLEEP:
4854 		ret = wlan_cmd_boot_sleep(pmpriv, cmd_ptr, cmd_action,
4855 					  pdata_buf);
4856 		break;
4857 #if defined(DRV_EMBEDDED_AUTHENTICATOR)
4858 	case HostCmd_CMD_CRYPTO:
4859 		ret = wlan_cmd_crypto(pmpriv, cmd_ptr, cmd_action, pdata_buf);
4860 		break;
4861 #endif
4862 	case HostCmd_CMD_11AX_CFG:
4863 		ret = wlan_cmd_11ax_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
4864 		break;
4865 	case HostCmd_CMD_11AX_CMD:
4866 		ret = wlan_cmd_11ax_cmd(pmpriv, cmd_ptr, cmd_action, pdata_buf);
4867 		break;
4868 	case HostCmd_CMD_RANGE_EXT:
4869 		ret = wlan_cmd_range_ext(pmpriv, cmd_ptr, cmd_action,
4870 					 pdata_buf);
4871 		break;
4872 	case HostCmd_CMD_RX_ABORT_CFG:
4873 		ret = wlan_cmd_rxabortcfg(pmpriv, cmd_ptr, cmd_action,
4874 					  pdata_buf);
4875 		break;
4876 	case HostCmd_CMD_RX_ABORT_CFG_EXT:
4877 		ret = wlan_cmd_rxabortcfg_ext(pmpriv, cmd_ptr, cmd_action,
4878 					      pdata_buf);
4879 		break;
4880 	case HostCmd_CMD_TX_AMPDU_PROT_MODE:
4881 		ret = wlan_cmd_tx_ampdu_prot_mode(pmpriv, cmd_ptr, cmd_action,
4882 						  pdata_buf);
4883 		break;
4884 	case HostCmd_CMD_DOT11MC_UNASSOC_FTM_CFG:
4885 		ret = wlan_cmd_dot11mc_unassoc_ftm_cfg(pmpriv, cmd_ptr,
4886 						       cmd_action, pdata_buf);
4887 		break;
4888 	case HostCmd_CMD_RATE_ADAPT_CFG:
4889 		ret = wlan_cmd_rate_adapt_cfg(pmpriv, cmd_ptr, cmd_action,
4890 					      pdata_buf);
4891 		break;
4892 	case HostCmd_CMD_CCK_DESENSE_CFG:
4893 		ret = wlan_cmd_cck_desense_cfg(pmpriv, cmd_ptr, cmd_action,
4894 					       pdata_buf);
4895 		break;
4896 	case HostCmd_CHANNEL_TRPC_CONFIG:
4897 		ret = wlan_cmd_get_chan_trpc_config(pmpriv, cmd_ptr, cmd_action,
4898 						    pdata_buf);
4899 		break;
4900 	case HostCmd_CMD_LOW_POWER_MODE_CFG:
4901 		ret = wlan_cmd_set_get_low_power_mode_cfg(
4902 			pmpriv, cmd_ptr, cmd_action, pdata_buf);
4903 		break;
4904 	case HostCmd_CMD_802_11_BAND_STEERING:
4905 		ret = wlan_cmd_set_get_band_steering_cfg(pmpriv, cmd_ptr,
4906 							 cmd_action, pdata_buf);
4907 		break;
4908 	case HostCmd_CMD_UAP_BEACON_STUCK_CFG:
4909 		ret = wlan_cmd_set_get_beacon_stuck_cfg(pmpriv, cmd_ptr,
4910 							cmd_action, pdata_buf);
4911 		break;
4912 	case HostCmd_CMD_HAL_PHY_CFG:
4913 		ret = wlan_cmd_hal_phy_cfg(pmpriv, cmd_ptr, cmd_action,
4914 					   pdata_buf);
4915 		break;
4916 	case HostCmd_CMD_MC_AGGR_CFG:
4917 		ret = wlan_cmd_mc_aggr_cfg(pmpriv, cmd_ptr, cmd_action,
4918 					   pdata_buf);
4919 		break;
4920 	case HostCmd_CMD_802_11_STATS:
4921 		ret = wlan_cmd_stats(pmpriv, cmd_ptr, cmd_action, pdata_buf);
4922 		break;
4923 	case HostCmd_CMD_GET_CH_LOAD:
4924 		ret = wlan_cmd_get_ch_load(pmpriv, cmd_ptr, cmd_action,
4925 					   pdata_buf);
4926 		break;
4927 	case HostCmd_DS_GET_SENSOR_TEMP:
4928 		wlan_cmd_get_sensor_temp(pmpriv, cmd_ptr, cmd_action);
4929 		break;
4930 	default:
4931 		PRINTM(MERROR, "PREP_CMD: unknown command- %#x\n", cmd_no);
4932 		if (pioctl_req)
4933 			pioctl_req->status_code = MLAN_ERROR_CMD_INVALID;
4934 		ret = MLAN_STATUS_FAILURE;
4935 		break;
4936 	}
4937 	LEAVE();
4938 	return ret;
4939 }
4940 
4941 /**
4942  *  @brief This function handles the AP mode command response
4943  *
4944  *  @param priv             A pointer to mlan_private structure
4945  *  @param cmdresp_no       cmd no
4946  *  @param pcmd_buf         cmdresp buf
4947  *  @param pioctl           A pointer to ioctl buf
4948  *
4949  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
4950  */
wlan_ops_uap_process_cmdresp(t_void * priv,t_u16 cmdresp_no,t_void * pcmd_buf,t_void * pioctl)4951 mlan_status wlan_ops_uap_process_cmdresp(t_void *priv, t_u16 cmdresp_no,
4952 					 t_void *pcmd_buf, t_void *pioctl)
4953 {
4954 	mlan_status ret = MLAN_STATUS_SUCCESS;
4955 	mlan_private *pmpriv = (mlan_private *)priv;
4956 	HostCmd_DS_COMMAND *resp = (HostCmd_DS_COMMAND *)pcmd_buf;
4957 	mlan_ioctl_req *pioctl_buf = (mlan_ioctl_req *)pioctl;
4958 	mlan_adapter *pmadapter = pmpriv->adapter;
4959 #ifdef SDIO
4960 	int ctr;
4961 #endif
4962 	wlan_dfs_device_state_t *pstate_dfs =
4963 		(wlan_dfs_device_state_t *)&pmpriv->adapter->state_dfs;
4964 	t_u32 sec, usec;
4965 	ENTER();
4966 
4967 	/* If the command is not successful, cleanup and return failure */
4968 	if (resp->result != HostCmd_RESULT_OK) {
4969 		ret = uap_process_cmdresp_error(pmpriv, resp, pioctl_buf);
4970 		LEAVE();
4971 		return ret;
4972 	}
4973 
4974 	/* Command successful, handle response */
4975 	switch (cmdresp_no) {
4976 	case HOST_CMD_APCMD_BSS_STOP:
4977 		pmpriv->uap_bss_started = MFALSE;
4978 		/* Timestamp update is required because bss_start after skip_cac
4979 		 * enabled should not select non-current channel just because
4980 		 * timestamp got expired
4981 		 */
4982 		if (!pmpriv->intf_state_11h.is_11h_host &&
4983 		    !pstate_dfs->dfs_check_pending &&
4984 		    pstate_dfs->dfs_check_channel) {
4985 			pmpriv->adapter->callbacks.moal_get_system_time(
4986 				pmpriv->adapter->pmoal_handle, &sec, &usec);
4987 			pstate_dfs->dfs_report_time_sec = sec;
4988 		}
4989 		wlan_reset_all_chan_dfs_state(priv, BAND_A, DFS_USABLE);
4990 		if (pmpriv->intf_state_11h.is_11h_host)
4991 			pmpriv->intf_state_11h.tx_disabled = MFALSE;
4992 		else {
4993 			if (pmpriv->adapter->ecsa_enable)
4994 				wlan_11h_remove_custom_ie(pmpriv->adapter,
4995 							  pmpriv);
4996 			wlan_11h_check_update_radar_det_state(pmpriv);
4997 		}
4998 
4999 		if (pmpriv->adapter->state_rdh.stage == RDH_STOP_INTFS)
5000 			wlan_11h_radar_detected_callback((t_void *)pmpriv);
5001 		wlan_coex_ampdu_rxwinsize(pmadapter);
5002 #ifdef DRV_EMBEDDED_AUTHENTICATOR
5003 		if (IsAuthenticatorEnabled(pmpriv->psapriv)) {
5004 			AuthenticatorBssConfig(pmpriv->psapriv, MNULL, 0, 1, 0);
5005 			AuthenticatorkeyClear(pmpriv->psapriv);
5006 		}
5007 #endif
5008 		pmpriv->uap_host_based = 0;
5009 		break;
5010 	case HOST_CMD_APCMD_BSS_START:
5011 		if (!pmpriv->intf_state_11h.is_11h_host &&
5012 		    pmpriv->adapter->state_rdh.stage == RDH_RESTART_INTFS)
5013 			wlan_11h_radar_detected_callback((t_void *)pmpriv);
5014 		/* Stop pps_uapsd_mode once bss_start */
5015 		pmpriv->adapter->tx_lock_flag = MFALSE;
5016 		pmpriv->adapter->pps_uapsd_mode = MFALSE;
5017 		pmpriv->adapter->delay_null_pkt = MFALSE;
5018 		/* Clear AMSDU statistics*/
5019 		pmpriv->amsdu_rx_cnt = 0;
5020 		pmpriv->amsdu_tx_cnt = 0;
5021 		pmpriv->msdu_in_rx_amsdu_cnt = 0;
5022 		pmpriv->msdu_in_tx_amsdu_cnt = 0;
5023 		break;
5024 	case HOST_CMD_APCMD_SYS_RESET:
5025 		pmpriv->uap_bss_started = MFALSE;
5026 		pmpriv->uap_host_based = 0;
5027 #ifdef DRV_EMBEDDED_AUTHENTICATOR
5028 		AuthenitcatorInitBssConfig(pmpriv->psapriv);
5029 #endif
5030 		ret = wlan_uap_ret_sys_reset(pmpriv, resp, pioctl_buf);
5031 		wlan_11h_check_update_radar_det_state(pmpriv);
5032 		wlan_coex_ampdu_rxwinsize(pmadapter);
5033 		break;
5034 	case HOST_CMD_APCMD_SYS_INFO:
5035 		break;
5036 	case HOST_CMD_APCMD_SYS_CONFIGURE:
5037 		ret = wlan_uap_ret_sys_config(pmpriv, resp, pioctl_buf);
5038 		break;
5039 	case HostCmd_CMD_802_11_PS_MODE_ENH:
5040 		ret = wlan_ret_enh_power_mode(pmpriv, resp, pioctl_buf);
5041 		break;
5042 #if defined(SDIO)
5043 	case HostCmd_CMD_SDIO_GPIO_INT_CONFIG:
5044 		break;
5045 #endif
5046 	case HostCmd_CMD_FUNC_INIT:
5047 	case HostCmd_CMD_FUNC_SHUTDOWN:
5048 		break;
5049 	case HostCmd_CMD_802_11_SNMP_MIB:
5050 		ret = wlan_uap_ret_snmp_mib(pmpriv, resp, pioctl_buf);
5051 		break;
5052 	case HostCmd_CMD_802_11_GET_LOG:
5053 		ret = wlan_uap_ret_get_log(pmpriv, resp, pioctl_buf);
5054 		break;
5055 	case HostCmd_CMD_802_11D_DOMAIN_INFO:
5056 		ret = wlan_ret_802_11d_domain_info(pmpriv, resp);
5057 		break;
5058 	case HostCmd_CMD_CHAN_REPORT_REQUEST:
5059 		ret = wlan_11h_cmdresp_process(pmpriv, resp);
5060 		break;
5061 	case HOST_CMD_APCMD_STA_DEAUTH:
5062 		break;
5063 	case HOST_CMD_APCMD_REPORT_MIC:
5064 		break;
5065 	case HostCmd_CMD_802_11_KEY_MATERIAL:
5066 		break;
5067 	case HOST_CMD_APCMD_STA_LIST:
5068 		ret = wlan_uap_ret_sta_list(pmpriv, resp, pioctl_buf);
5069 		break;
5070 	case HostCmd_CMD_GET_HW_SPEC:
5071 		ret = wlan_ret_get_hw_spec(pmpriv, resp, pioctl_buf);
5072 		break;
5073 #ifdef SDIO
5074 	case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG:
5075 		ret = wlan_ret_sdio_rx_aggr_cfg(pmpriv, resp);
5076 		break;
5077 #endif
5078 	case HostCmd_CMD_CFG_DATA:
5079 		ret = wlan_ret_cfg_data(pmpriv, resp, pioctl_buf);
5080 		break;
5081 	case HostCmd_CMD_MAC_CONTROL:
5082 		ret = wlan_ret_mac_control(pmpriv, resp, pioctl_buf);
5083 		break;
5084 	case HostCmd_CMD_802_11_HS_CFG_ENH:
5085 		ret = wlan_ret_802_11_hs_cfg(pmpriv, resp, pioctl_buf);
5086 		break;
5087 	case HostCmd_CMD_HS_WAKEUP_REASON:
5088 		ret = wlan_ret_hs_wakeup_reason(pmpriv, resp, pioctl_buf);
5089 		break;
5090 	case HostCmd_CMD_802_11_ROBUSTCOEX:
5091 		break;
5092 	case HostCmd_CMD_DMCS_CONFIG:
5093 		ret = wlan_ret_dmcs_config(pmpriv, resp, pioctl_buf);
5094 		break;
5095 	case HostCmd_CMD_11N_ADDBA_REQ:
5096 		ret = wlan_ret_11n_addba_req(pmpriv, resp);
5097 		break;
5098 	case HostCmd_CMD_11N_DELBA:
5099 		ret = wlan_ret_11n_delba(pmpriv, resp);
5100 		break;
5101 	case HostCmd_CMD_11N_ADDBA_RSP:
5102 		ret = wlan_ret_11n_addba_resp(pmpriv, resp);
5103 		break;
5104 	case HostCmd_CMD_SET_BSS_MODE:
5105 		break;
5106 	case HostCmd_CMD_802_11_NET_MONITOR:
5107 		ret = wlan_ret_net_monitor(pmpriv, resp, pioctl_buf);
5108 		break;
5109 	case HostCmd_CMD_RECONFIGURE_TX_BUFF:
5110 		wlan_set_tx_pause_flag(pmpriv, MFALSE);
5111 
5112 		pmadapter->tx_buf_size =
5113 			(t_u16)wlan_le16_to_cpu(resp->params.tx_buf.buff_size);
5114 #ifdef SDIO
5115 		if (IS_SD(pmadapter->card_type)) {
5116 			pmadapter->tx_buf_size = (pmadapter->tx_buf_size /
5117 						  MLAN_SDIO_BLOCK_SIZE) *
5118 						 MLAN_SDIO_BLOCK_SIZE;
5119 			pmadapter->pcard_sd->mp_end_port = wlan_le16_to_cpu(
5120 				resp->params.tx_buf.mp_end_port);
5121 			pmadapter->pcard_sd->mp_data_port_mask =
5122 				pmadapter->pcard_sd->reg->data_port_mask;
5123 
5124 			for (ctr = 1;
5125 			     ctr <= pmadapter->pcard_sd->max_ports -
5126 					    pmadapter->pcard_sd->mp_end_port;
5127 			     ctr++) {
5128 				pmadapter->pcard_sd->mp_data_port_mask &=
5129 					~(1 << (pmadapter->pcard_sd->max_ports -
5130 						ctr));
5131 			}
5132 
5133 			pmadapter->pcard_sd->curr_wr_port =
5134 				pmadapter->pcard_sd->reg->start_wr_port;
5135 			pmadapter->pcard_sd->mpa_tx.pkt_aggr_limit =
5136 				MIN(pmadapter->pcard_sd->mp_aggr_pkt_limit,
5137 				    (pmadapter->pcard_sd->mp_end_port >> 1));
5138 			PRINTM(MCMND, "end port %d, data port mask %x\n",
5139 			       wlan_le16_to_cpu(
5140 				       resp->params.tx_buf.mp_end_port),
5141 			       pmadapter->pcard_sd->mp_data_port_mask);
5142 		}
5143 #endif
5144 		pmadapter->curr_tx_buf_size = pmadapter->tx_buf_size;
5145 		PRINTM(MCMND, "max_tx_buf_size=%d, tx_buf_size=%d\n",
5146 		       pmadapter->max_tx_buf_size, pmadapter->tx_buf_size);
5147 		break;
5148 	case HostCmd_CMD_AMSDU_AGGR_CTRL:
5149 		ret = wlan_ret_amsdu_aggr_ctrl(pmpriv, resp, pioctl_buf);
5150 		break;
5151 	case HostCmd_CMD_11N_CFG:
5152 		ret = wlan_ret_11n_cfg(pmpriv, resp, pioctl_buf);
5153 		break;
5154 	case HostCmd_CMD_REJECT_ADDBA_REQ:
5155 		ret = wlan_ret_reject_addba_req(pmpriv, resp, pioctl_buf);
5156 		break;
5157 	case HostCmd_CMD_TX_BF_CFG:
5158 		ret = wlan_ret_tx_bf_cfg(pmpriv, resp, pioctl_buf);
5159 		break;
5160 	case HostCmd_CMD_VERSION_EXT:
5161 		ret = wlan_ret_ver_ext(pmpriv, resp, pioctl_buf);
5162 		break;
5163 	case HostCmd_CMD_RX_MGMT_IND:
5164 		ret = wlan_ret_rx_mgmt_ind(pmpriv, resp, pioctl_buf);
5165 		break;
5166 	case HostCmd_CMD_CFG_TX_DATA_PAUSE:
5167 		ret = wlan_uap_ret_txdatapause(pmpriv, resp, pioctl_buf);
5168 		break;
5169 	case HostCmd_CMD_802_11_RADIO_CONTROL:
5170 		ret = wlan_ret_802_11_radio_control(pmpriv, resp, pioctl_buf);
5171 		break;
5172 	case HostCmd_CMD_TX_RATE_CFG:
5173 		ret = wlan_ret_tx_rate_cfg(pmpriv, resp, pioctl_buf);
5174 		break;
5175 	case HostCmd_CMD_802_11_TX_RATE_QUERY:
5176 		ret = wlan_ret_802_11_tx_rate_query(pmpriv, resp, pioctl_buf);
5177 		break;
5178 	case HostCmd_CMD_802_11_REMAIN_ON_CHANNEL:
5179 		ret = wlan_ret_remain_on_channel(pmpriv, resp, pioctl_buf);
5180 		break;
5181 #ifdef WIFI_DIRECT_SUPPORT
5182 	case HOST_CMD_WIFI_DIRECT_MODE_CONFIG:
5183 		ret = wlan_ret_wifi_direct_mode(pmpriv, resp, pioctl_buf);
5184 		break;
5185 	case HOST_CMD_P2P_PARAMS_CONFIG:
5186 		ret = wlan_ret_p2p_params_config(pmpriv, resp, pioctl_buf);
5187 		break;
5188 #endif
5189 	case HOST_CMD_GPIO_TSF_LATCH_PARAM_CONFIG:
5190 		ret = wlan_ret_gpio_tsf_latch(pmpriv, resp, pioctl_buf);
5191 		break;
5192 	case HostCmd_CMD_802_11_RF_ANTENNA:
5193 		ret = wlan_ret_802_11_rf_antenna(pmpriv, resp, pioctl_buf);
5194 		break;
5195 	case HostCmd_CMD_802_11_MIMO_SWITCH:
5196 		break;
5197 	case HostCmd_CMD_11AC_CFG:
5198 		ret = wlan_ret_11ac_cfg(pmpriv, resp, pioctl_buf);
5199 		break;
5200 	case HostCmd_CMD_DYN_BW:
5201 		ret = wlan_ret_dyn_bw(pmpriv, resp, pioctl_buf);
5202 		break;
5203 	case HostCmd_CMD_MAC_REG_ACCESS:
5204 	case HostCmd_CMD_BBP_REG_ACCESS:
5205 	case HostCmd_CMD_RF_REG_ACCESS:
5206 	case HostCmd_CMD_CAU_REG_ACCESS:
5207 	case HostCmd_CMD_TARGET_ACCESS:
5208 	case HostCmd_CMD_802_11_EEPROM_ACCESS:
5209 	case HostCmd_CMD_BCA_REG_ACCESS:
5210 	case HostCmd_CMD_REG_ACCESS:
5211 		ret = wlan_ret_reg_access(pmpriv->adapter, cmdresp_no, resp,
5212 					  pioctl_buf);
5213 		break;
5214 	case HostCmd_CMD_MEM_ACCESS:
5215 		ret = wlan_ret_mem_access(pmpriv, resp, pioctl_buf);
5216 		break;
5217 	case HostCmd_CMD_WMM_QUEUE_CONFIG:
5218 		ret = wlan_ret_wmm_queue_config(pmpriv, resp, pioctl_buf);
5219 		break;
5220 #ifdef RX_PACKET_COALESCE
5221 	case HostCmd_CMD_RX_PKT_COALESCE_CFG:
5222 		ret = wlan_ret_rx_pkt_coalesce_cfg(pmpriv, resp, pioctl_buf);
5223 		break;
5224 #endif
5225 	case HostCMD_APCMD_ACS_SCAN:
5226 		ret = wlan_ret_cmd_uap_acs_scan(pmpriv, resp, pioctl_buf);
5227 		break;
5228 	case HOST_CMD_APCMD_OPER_CTRL:
5229 		ret = wlan_uap_ret_oper_ctrl(pmpriv, resp, pioctl_buf);
5230 		break;
5231 	case HostCmd_CMD_INDEPENDENT_RESET_CFG:
5232 		ret = wlan_ret_ind_rst_cfg(pmpriv, resp, pioctl_buf);
5233 		break;
5234 	case HostCmd_CMD_802_11_PS_INACTIVITY_TIMEOUT:
5235 		break;
5236 	case HostCmd_CMD_GET_TSF:
5237 		ret = wlan_ret_get_tsf(pmpriv, resp, pioctl_buf);
5238 		break;
5239 
5240 	case HostCmd_CMD_CHAN_REGION_CFG:
5241 		ret = wlan_ret_chan_region_cfg(pmpriv, resp, pioctl_buf);
5242 		break;
5243 	case HostCmd_CMD_PACKET_AGGR_CTRL:
5244 		ret = wlan_ret_packet_aggr_ctrl(pmpriv, resp, pioctl_buf);
5245 		break;
5246 #if defined(PCIE)
5247 #if defined(PCIE8997) || defined(PCIE8897)
5248 	case HostCmd_CMD_PCIE_HOST_BUF_DETAILS:
5249 		PRINTM(MINFO, "PCIE host buffer configuration successful.\n");
5250 		break;
5251 #endif
5252 #endif
5253 	case HOST_CMD_TX_RX_PKT_STATS:
5254 		ret = wlan_ret_tx_rx_pkt_stats(pmpriv, resp, pioctl_buf);
5255 		break;
5256 	case HostCmd_CMD_802_11_LINK_STATS:
5257 		ret = wlan_ret_get_link_statistic(pmpriv, resp, pioctl_buf);
5258 		break;
5259 	case HostCmd_CMD_BOOT_SLEEP:
5260 		ret = wlan_ret_boot_sleep(pmpriv, resp, pioctl_buf);
5261 		break;
5262 	case HostCmd_CMD_ADD_NEW_STATION:
5263 		break;
5264 #if defined(DRV_EMBEDDED_AUTHENTICATOR)
5265 	case HostCmd_CMD_CRYPTO:
5266 		ret = wlan_ret_crypto(pmpriv, resp, pioctl_buf);
5267 		break;
5268 #endif
5269 	case HostCmd_CMD_11AX_CFG:
5270 		ret = wlan_ret_11ax_cfg(pmpriv, resp, pioctl_buf);
5271 		break;
5272 	case HostCmd_CMD_11AX_CMD:
5273 		ret = wlan_ret_11ax_cmd(pmpriv, resp, pioctl_buf);
5274 		break;
5275 	case HostCmd_CMD_RANGE_EXT:
5276 		ret = wlan_ret_range_ext(pmpriv, resp, pioctl_buf);
5277 		break;
5278 	case HostCmd_CMD_RX_ABORT_CFG:
5279 		ret = wlan_ret_rxabortcfg(pmpriv, resp, pioctl_buf);
5280 		break;
5281 	case HostCmd_CMD_RX_ABORT_CFG_EXT:
5282 		ret = wlan_ret_rxabortcfg_ext(pmpriv, resp, pioctl_buf);
5283 		break;
5284 	case HostCmd_CMD_TX_AMPDU_PROT_MODE:
5285 		ret = wlan_ret_tx_ampdu_prot_mode(pmpriv, resp, pioctl_buf);
5286 		break;
5287 	case HostCmd_CMD_DOT11MC_UNASSOC_FTM_CFG:
5288 		ret = wlan_ret_dot11mc_unassoc_ftm_cfg(pmpriv, resp,
5289 						       pioctl_buf);
5290 		break;
5291 	case HostCmd_CMD_HAL_PHY_CFG:
5292 		ret = wlan_ret_hal_phy_cfg(pmpriv, resp, pioctl_buf);
5293 		break;
5294 	case HostCmd_CMD_RATE_ADAPT_CFG:
5295 		ret = wlan_ret_rate_adapt_cfg(pmpriv, resp, pioctl_buf);
5296 		break;
5297 	case HostCmd_CMD_CCK_DESENSE_CFG:
5298 		ret = wlan_ret_cck_desense_cfg(pmpriv, resp, pioctl_buf);
5299 		break;
5300 	case HostCmd_CHANNEL_TRPC_CONFIG:
5301 		ret = wlan_ret_get_chan_trpc_config(pmpriv, resp, pioctl_buf);
5302 		break;
5303 	case HostCmd_CMD_LOW_POWER_MODE_CFG:
5304 		ret = wlan_ret_set_get_low_power_mode_cfg(pmpriv, resp,
5305 							  pioctl_buf);
5306 		break;
5307 	case HostCmd_CMD_802_11_BAND_STEERING:
5308 		ret = wlan_ret_set_get_band_steering_cfg(pmpriv, resp,
5309 							 pioctl_buf);
5310 		break;
5311 	case HostCmd_CMD_UAP_BEACON_STUCK_CFG:
5312 		ret = wlan_ret_set_get_beacon_stuck_cfg(pmpriv, resp,
5313 							pioctl_buf);
5314 		break;
5315 	case HostCmd_CMD_MC_AGGR_CFG:
5316 		ret = wlan_ret_mc_aggr_cfg(pmpriv, resp, pioctl_buf);
5317 		break;
5318 	case HostCmd_CMD_802_11_STATS:
5319 		ret = wlan_ret_stats(pmpriv, resp, pioctl_buf);
5320 		break;
5321 	case HostCmd_CMD_GET_CH_LOAD:
5322 		ret = wlan_ret_ch_load(pmpriv, resp, pioctl_buf);
5323 		break;
5324 	case HostCmd_DS_GET_SENSOR_TEMP:
5325 		ret = wlan_ret_get_sensor_temp(pmpriv, resp, pioctl_buf);
5326 		break;
5327 	default:
5328 		PRINTM(MERROR, "CMD_RESP: Unknown command response %#x\n",
5329 		       resp->command);
5330 		if (pioctl_buf)
5331 			pioctl_buf->status_code = MLAN_ERROR_CMD_RESP_FAIL;
5332 		break;
5333 	}
5334 	LEAVE();
5335 	return ret;
5336 }
5337 
5338 /**
5339  *  @brief This function handles events generated by firmware
5340  *
5341  *  @param priv		A pointer to mlan_private structure
5342  *
5343  *  @return		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
5344  */
wlan_ops_uap_process_event(t_void * priv)5345 mlan_status wlan_ops_uap_process_event(t_void *priv)
5346 {
5347 	pmlan_private pmpriv = (pmlan_private)priv;
5348 	pmlan_adapter pmadapter = pmpriv->adapter;
5349 	pmlan_callbacks pcb = &pmadapter->callbacks;
5350 	mlan_status ret = MLAN_STATUS_SUCCESS;
5351 	t_u32 eventcause = pmadapter->event_cause;
5352 	pmlan_buffer pmbuf = pmadapter->pmlan_buffer_event;
5353 	t_u8 *event_buf = MNULL;
5354 	mlan_event *pevent = MNULL;
5355 	t_u8 sta_addr[MLAN_MAC_ADDR_LENGTH];
5356 	sta_node *sta_ptr = MNULL;
5357 	t_u8 i = 0;
5358 	t_u8 channel = 0;
5359 	t_u8 bandwidth = 0;
5360 	MrvlIEtypes_channel_band_t *pchan_info = MNULL;
5361 	chan_band_info *pchan_band_info = MNULL;
5362 	event_exceed_max_p2p_conn *event_excd_p2p = MNULL;
5363 	t_u16 enable;
5364 
5365 	ENTER();
5366 
5367 	if (!pmbuf) {
5368 		LEAVE();
5369 		return MLAN_STATUS_FAILURE;
5370 	}
5371 	/* Event length check */
5372 	if (pmbuf && (pmbuf->data_len - sizeof(eventcause)) > MAX_EVENT_SIZE) {
5373 		pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID;
5374 		LEAVE();
5375 		return MLAN_STATUS_FAILURE;
5376 	}
5377 
5378 	/* Allocate memory for event buffer */
5379 	ret = pcb->moal_malloc(pmadapter->pmoal_handle,
5380 			       MAX_EVENT_SIZE + sizeof(mlan_event),
5381 			       MLAN_MEM_DEF, &event_buf);
5382 	if ((ret != MLAN_STATUS_SUCCESS) || !event_buf) {
5383 		PRINTM(MERROR, "Could not allocate buffer for event buf\n");
5384 		if (pmbuf)
5385 			pmbuf->status_code = MLAN_ERROR_NO_MEM;
5386 		goto done;
5387 	}
5388 	pevent = (pmlan_event)event_buf;
5389 	memset(pmadapter, &pevent->event_id, 0, sizeof(pevent->event_id));
5390 
5391 	if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE &&
5392 	    pmbuf->data_len > sizeof(eventcause))
5393 		DBG_HEXDUMP(MEVT_D, "EVENT", pmbuf->pbuf + pmbuf->data_offset,
5394 			    pmbuf->data_len);
5395 
5396 	switch (eventcause) {
5397 	case EVENT_MICRO_AP_BSS_START:
5398 		PRINTM(MEVENT, "EVENT: MICRO_AP_BSS_START\n");
5399 		pmpriv->uap_bss_started = MTRUE;
5400 		pmpriv->is_data_rate_auto = MTRUE;
5401 		memcpy_ext(pmadapter, pmpriv->curr_addr,
5402 			   pmadapter->event_body + 2, MLAN_MAC_ADDR_LENGTH,
5403 			   MLAN_MAC_ADDR_LENGTH);
5404 		pevent->event_id = MLAN_EVENT_ID_UAP_FW_BSS_START;
5405 		wlan_check_uap_capability(pmpriv, pmbuf);
5406 		wlan_coex_ampdu_rxwinsize(pmadapter);
5407 #ifdef DRV_EMBEDDED_AUTHENTICATOR
5408 		if (IsAuthenticatorEnabled(pmpriv->psapriv)) {
5409 			pmadapter->authenticator_priv = pmpriv;
5410 			wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_DEFER_RX_WORK,
5411 					MNULL);
5412 		}
5413 #endif
5414 		if (wlan_11h_radar_detect_required(pmpriv, pmpriv->uap_channel))
5415 			wlan_11h_update_dfs_master_state_by_uap(pmpriv);
5416 		break;
5417 	case EVENT_MICRO_AP_BSS_ACTIVE:
5418 		PRINTM(MEVENT, "EVENT: MICRO_AP_BSS_ACTIVE\n");
5419 		pmpriv->media_connected = MTRUE;
5420 		pmpriv->port_open = MTRUE;
5421 		pevent->event_id = MLAN_EVENT_ID_UAP_FW_BSS_ACTIVE;
5422 		break;
5423 	case EVENT_MICRO_AP_BSS_IDLE:
5424 		PRINTM(MEVENT, "EVENT: MICRO_AP_BSS_IDLE\n");
5425 		pevent->event_id = MLAN_EVENT_ID_UAP_FW_BSS_IDLE;
5426 		pmpriv->media_connected = MFALSE;
5427 		wlan_clean_txrx(pmpriv);
5428 		wlan_notify_station_deauth(pmpriv);
5429 		wlan_delete_station_list(pmpriv);
5430 		pmpriv->port_open = MFALSE;
5431 		pmpriv->amsdu_disable = MFALSE;
5432 		pmpriv->tx_pause = MFALSE;
5433 		break;
5434 	case EVENT_MICRO_AP_MIC_COUNTERMEASURES:
5435 		PRINTM(MEVENT, "EVENT: MICRO_AP_MIC_COUNTERMEASURES\n");
5436 		pevent->event_id = MLAN_EVENT_ID_UAP_FW_MIC_COUNTERMEASURES;
5437 		break;
5438 	case EVENT_PS_AWAKE:
5439 		PRINTM(MINFO, "EVENT: AWAKE\n");
5440 		PRINTM_NETINTF(MEVENT, pmpriv);
5441 		PRINTM(MEVENT, "||");
5442 		/* Handle unexpected PS AWAKE event */
5443 		if (pmadapter->ps_state == PS_STATE_SLEEP_CFM)
5444 			break;
5445 		pmadapter->pm_wakeup_card_req = MFALSE;
5446 		pmadapter->pm_wakeup_fw_try = MFALSE;
5447 		pmadapter->ps_state = PS_STATE_AWAKE;
5448 
5449 		break;
5450 	case EVENT_PS_SLEEP:
5451 		PRINTM(MINFO, "EVENT: SLEEP\n");
5452 		PRINTM_NETINTF(MEVENT, pmpriv);
5453 		PRINTM(MEVENT, "__");
5454 		/* Handle unexpected PS SLEEP event */
5455 		if (pmadapter->ps_state == PS_STATE_SLEEP_CFM)
5456 			break;
5457 		pmadapter->ps_state = PS_STATE_PRE_SLEEP;
5458 		wlan_check_ps_cond(pmadapter);
5459 		break;
5460 	case EVENT_MICRO_AP_STA_ASSOC:
5461 		wlan_process_sta_assoc_event(pmpriv, pevent, pmbuf);
5462 		memcpy_ext(pmadapter, sta_addr, pmadapter->event_body + 2,
5463 			   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
5464 		sta_ptr = wlan_add_station_entry(pmpriv, sta_addr);
5465 		PRINTM_NETINTF(MMSG, pmpriv);
5466 		PRINTM(MMSG, "wlan: EVENT: MICRO_AP_STA_ASSOC " MACSTR "\n",
5467 		       MAC2STR(sta_addr));
5468 		if (!sta_ptr)
5469 			break;
5470 		wlan_check_sta_capability(pmpriv, pmbuf, sta_ptr);
5471 		if (pmpriv->is_11n_enabled || pmpriv->is_11ax_enabled
5472 #ifdef DRV_EMBEDDED_AUTHENTICATOR
5473 		    || IsAuthenticatorEnabled(pmpriv->psapriv)
5474 #endif
5475 		) {
5476 			for (i = 0; i < MAX_NUM_TID; i++) {
5477 				if (sta_ptr->is_11n_enabled ||
5478 				    sta_ptr->is_11ax_enabled)
5479 					sta_ptr->ampdu_sta[i] =
5480 						pmpriv->aggr_prio_tbl[i]
5481 							.ampdu_user;
5482 				else
5483 					sta_ptr->ampdu_sta[i] =
5484 						BA_STREAM_NOT_ALLOWED;
5485 			}
5486 			memset(pmadapter, sta_ptr->rx_seq, 0xff,
5487 			       sizeof(sta_ptr->rx_seq));
5488 		}
5489 		if (pmpriv->sec_info.wapi_enabled)
5490 			wlan_update_wapi_info_tlv(pmpriv, pmbuf);
5491 #ifdef DRV_EMBEDDED_AUTHENTICATOR
5492 		/**enter authenticator*/
5493 		if (IsAuthenticatorEnabled(pmpriv->psapriv))
5494 			AuthenticatorSendEapolPacket(
5495 				pmpriv->psapriv, sta_ptr->cm_connectioninfo);
5496 #endif
5497 		pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU;
5498 		break;
5499 	case EVENT_MICRO_AP_STA_DEAUTH:
5500 		pevent->event_id = MLAN_EVENT_ID_UAP_FW_STA_DISCONNECT;
5501 		pevent->bss_index = pmpriv->bss_index;
5502 		pevent->event_len = pmbuf->data_len - 4;
5503 		/* skip event length field */
5504 		memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
5505 			   pmbuf->pbuf + pmbuf->data_offset + 4,
5506 			   pevent->event_len, pevent->event_len);
5507 		wlan_recv_event(pmpriv, pevent->event_id, pevent);
5508 		memcpy_ext(pmadapter, sta_addr, pmadapter->event_body + 2,
5509 			   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
5510 		sta_ptr = wlan_get_station_entry(pmpriv, sta_addr);
5511 		PRINTM_NETINTF(MMSG, pmpriv);
5512 		PRINTM(MMSG, "wlan: EVENT: MICRO_AP_STA_DEAUTH " MACSTR "\n",
5513 		       MAC2STR(sta_addr));
5514 		if (pmpriv->is_11n_enabled || pmpriv->is_11ax_enabled) {
5515 			wlan_cleanup_reorder_tbl(pmpriv, sta_addr);
5516 			wlan_11n_cleanup_txbastream_tbl(pmpriv, sta_addr);
5517 		}
5518 		wlan_wmm_delete_peer_ralist(pmpriv, sta_addr);
5519 		wlan_delete_station_entry(pmpriv, sta_addr);
5520 		pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU;
5521 		break;
5522 	case EVENT_HS_ACT_REQ:
5523 		PRINTM(MEVENT, "EVENT: HS_ACT_REQ\n");
5524 		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_HS_CFG_ENH, 0,
5525 				       0, MNULL, MNULL);
5526 		break;
5527 	case EVENT_ADDBA:
5528 		PRINTM(MEVENT, "EVENT: ADDBA Request\n");
5529 		if (pmpriv->media_connected == MTRUE)
5530 			ret = wlan_prepare_cmd(pmpriv,
5531 					       HostCmd_CMD_11N_ADDBA_RSP,
5532 					       HostCmd_ACT_GEN_SET, 0, MNULL,
5533 					       pmadapter->event_body);
5534 		else
5535 			PRINTM(MERROR,
5536 			       "Ignore ADDBA Request event in BSS idle state\n");
5537 		break;
5538 	case EVENT_DELBA:
5539 		PRINTM(MEVENT, "EVENT: DELBA Request\n");
5540 		if (pmpriv->media_connected == MTRUE)
5541 			wlan_11n_delete_bastream(pmpriv, pmadapter->event_body);
5542 		else
5543 			PRINTM(MERROR,
5544 			       "Ignore DELBA Request event in BSS idle state\n");
5545 		break;
5546 	case EVENT_BA_STREAM_TIMEOUT:
5547 		PRINTM(MEVENT, "EVENT:  BA Stream timeout\n");
5548 		if (pmpriv->media_connected == MTRUE)
5549 			wlan_11n_ba_stream_timeout(
5550 				pmpriv, (HostCmd_DS_11N_BATIMEOUT *)
5551 						pmadapter->event_body);
5552 		else
5553 			PRINTM(MERROR,
5554 			       "Ignore BA Stream timeout event in BSS idle state\n");
5555 		break;
5556 	case EVENT_RXBA_SYNC:
5557 		PRINTM(MEVENT, "EVENT:  RXBA_SYNC\n");
5558 		wlan_11n_rxba_sync_event(pmpriv, pmadapter->event_body,
5559 					 pmbuf->data_len - sizeof(eventcause));
5560 		break;
5561 	case EVENT_AMSDU_AGGR_CTRL:
5562 		PRINTM(MEVENT, "EVENT:  AMSDU_AGGR_CTRL %d\n",
5563 		       *(t_u16 *)pmadapter->event_body);
5564 		pmadapter->tx_buf_size =
5565 			MIN(pmadapter->curr_tx_buf_size,
5566 			    wlan_le16_to_cpu(*(t_u16 *)pmadapter->event_body));
5567 		if (pmbuf->data_len == sizeof(eventcause) + sizeof(t_u32)) {
5568 			enable = wlan_le16_to_cpu(
5569 				*(t_u16 *)(pmadapter->event_body +
5570 					   sizeof(t_u16)));
5571 			if (enable)
5572 				pmpriv->amsdu_disable = MFALSE;
5573 			else
5574 				pmpriv->amsdu_disable = MTRUE;
5575 			PRINTM(MEVENT, "amsdu_disable=%d\n",
5576 			       pmpriv->amsdu_disable);
5577 		}
5578 		PRINTM(MEVENT, "tx_buf_size %d\n", pmadapter->tx_buf_size);
5579 		break;
5580 	case EVENT_TX_DATA_PAUSE:
5581 		PRINTM(MEVENT, "EVENT: TX_DATA_PAUSE\n");
5582 		wlan_process_tx_pause_event(priv, pmbuf);
5583 		break;
5584 	case EVENT_RADAR_DETECTED:
5585 		PRINTM_NETINTF(MEVENT, pmpriv);
5586 		PRINTM(MEVENT, "EVENT: Radar Detected\n");
5587 		if (pmpriv->adapter->dfs_test_params.cac_restart &&
5588 		    pmpriv->adapter->state_dfs.dfs_check_pending) {
5589 			wlan_11h_cancel_radar_detect(pmpriv);
5590 			wlan_11h_issue_radar_detect(
5591 				pmpriv, MNULL,
5592 				pmpriv->adapter->dfs_test_params.chan,
5593 				pmpriv->adapter->dfs_test_params.bandcfg);
5594 			pevent->event_id = 0;
5595 			break;
5596 		}
5597 		/* Send as passthru first, this event can cause other events */
5598 		memset(pmadapter, event_buf, 0x00, MAX_EVENT_SIZE);
5599 		pevent->bss_index = pmpriv->bss_index;
5600 		pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU;
5601 		pevent->event_len = pmbuf->data_len;
5602 		memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
5603 			   pmbuf->pbuf + pmbuf->data_offset, pevent->event_len,
5604 			   pevent->event_len);
5605 		wlan_recv_event(pmpriv, pevent->event_id, pevent);
5606 		pevent->event_id = 0; /* clear to avoid resending at end of fcn
5607 				       */
5608 
5609 		/* Print event data */
5610 		pevent->event_id = MLAN_EVENT_ID_FW_RADAR_DETECTED;
5611 		pevent->event_len = pmbuf->data_len - sizeof(eventcause);
5612 		memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
5613 			   pmbuf->pbuf + pmbuf->data_offset +
5614 				   sizeof(eventcause),
5615 			   pevent->event_len, pevent->event_len);
5616 		wlan_11h_print_event_radar_detected(pmpriv, pevent, &channel,
5617 						    &bandwidth);
5618 		*((t_u8 *)pevent->event_buf) = channel;
5619 		*((t_u8 *)pevent->event_buf + 1) = bandwidth;
5620 		if (pmpriv->bss_type == MLAN_BSS_TYPE_DFS) {
5621 			wlan_recv_event(priv, MLAN_EVENT_ID_FW_RADAR_DETECTED,
5622 					pevent);
5623 			pevent->event_id = 0; /* clear to avoid
5624 						 resending at end of fcn
5625 					       */
5626 			break;
5627 		}
5628 		if (!pmpriv->intf_state_11h.is_11h_host) {
5629 			if (pmadapter->state_rdh.stage == RDH_OFF) {
5630 				pmadapter->state_rdh.stage = RDH_CHK_INTFS;
5631 				wlan_11h_radar_detected_handling(pmadapter,
5632 								 pmpriv);
5633 				wlan_recv_event(priv,
5634 						MLAN_EVENT_ID_FW_RADAR_DETECTED,
5635 						pevent);
5636 			} else {
5637 				PRINTM(MEVENT,
5638 				       "Ignore Event Radar Detected - handling"
5639 				       " already in progress.\n");
5640 			}
5641 		} else {
5642 			if (pmpriv->adapter->dfs_test_params
5643 				    .no_channel_change_on_radar ||
5644 			    pmpriv->adapter->dfs_test_params
5645 				    .fixed_new_channel_on_radar) {
5646 				if (pmadapter->state_rdh.stage == RDH_OFF) {
5647 					pmadapter->state_rdh.stage =
5648 						RDH_CHK_INTFS;
5649 					wlan_11h_radar_detected_handling(
5650 						pmadapter, pmpriv);
5651 				} else
5652 					PRINTM(MEVENT,
5653 					       "Ignore Event Radar Detected - handling already in progress.\n");
5654 			} else {
5655 				pmpriv->intf_state_11h.tx_disabled = MTRUE;
5656 				wlan_recv_event(priv,
5657 						MLAN_EVENT_ID_FW_RADAR_DETECTED,
5658 						pevent);
5659 			}
5660 		}
5661 
5662 		pevent->event_id = 0; /* clear to avoid resending at end of fcn
5663 				       */
5664 		break;
5665 	case EVENT_CHANNEL_REPORT_RDY:
5666 		PRINTM_NETINTF(MEVENT, pmpriv);
5667 		PRINTM(MEVENT, "EVENT: Channel Report Ready\n");
5668 		pmpriv->adapter->dfs_test_params.cac_restart = MFALSE;
5669 		memset(pmadapter, event_buf, 0x00, MAX_EVENT_SIZE);
5670 		/* Setup event buffer */
5671 		pevent->bss_index = pmpriv->bss_index;
5672 		pevent->event_id = MLAN_EVENT_ID_FW_CHANNEL_REPORT_RDY;
5673 		pevent->event_len = pmbuf->data_len - sizeof(eventcause);
5674 		/* Copy event data */
5675 		memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
5676 			   pmbuf->pbuf + pmbuf->data_offset +
5677 				   sizeof(eventcause),
5678 			   pevent->event_len, pevent->event_len);
5679 		/* Handle / pass event data, and free buffer */
5680 		ret = wlan_11h_handle_event_chanrpt_ready(pmpriv, pevent,
5681 							  &channel, &bandwidth);
5682 		if (pmpriv->bss_type == MLAN_BSS_TYPE_DFS) {
5683 			*((t_u8 *)pevent->event_buf) =
5684 				pmpriv->adapter->state_dfs.dfs_radar_found;
5685 			*((t_u8 *)pevent->event_buf + 1) = channel;
5686 			*((t_u8 *)pevent->event_buf + 2) = bandwidth;
5687 			wlan_recv_event(pmpriv,
5688 					MLAN_EVENT_ID_FW_CHANNEL_REPORT_RDY,
5689 					pevent);
5690 			pevent->event_id = 0; /* clear to avoid resending at end
5691 						 of fcn */
5692 			break;
5693 		}
5694 		if (pmpriv->intf_state_11h.is_11h_host) {
5695 			*((t_u8 *)pevent->event_buf) =
5696 				pmpriv->adapter->state_dfs.dfs_radar_found;
5697 			*((t_u8 *)pevent->event_buf + 1) = channel;
5698 			*((t_u8 *)pevent->event_buf + 2) = bandwidth;
5699 
5700 			wlan_recv_event(pmpriv,
5701 					MLAN_EVENT_ID_FW_CHANNEL_REPORT_RDY,
5702 					pevent);
5703 		} else {
5704 			/* Send up this Event to unblock MOAL waitqueue */
5705 			wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_MEAS_REPORT,
5706 					MNULL);
5707 		}
5708 		pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU;
5709 		break;
5710 	case EVENT_CHANNEL_SWITCH:
5711 		pchan_info =
5712 			(MrvlIEtypes_channel_band_t *)(pmadapter->event_body);
5713 		channel = pchan_info->channel;
5714 		PRINTM_NETINTF(MEVENT, pmpriv);
5715 		PRINTM(MEVENT, "EVENT: CHANNEL_SWITCH new channel %d\n",
5716 		       channel);
5717 		pmpriv->uap_channel = channel;
5718 		pmpriv->uap_bandwidth = pchan_info->bandcfg.chanWidth;
5719 		pmpriv->uap_state_chan_cb.channel = pchan_info->channel;
5720 		pmpriv->uap_state_chan_cb.bandcfg = pchan_info->bandcfg;
5721 		if (wlan_11h_radar_detect_required(pmpriv, pchan_info->channel))
5722 			wlan_11h_update_dfs_master_state_by_uap(pmpriv);
5723 		if ((pmpriv->adapter->state_rdh.stage != RDH_OFF &&
5724 		     !pmpriv->intf_state_11h.is_11h_host) ||
5725 		    pmpriv->adapter->dfs_test_params.no_channel_change_on_radar ||
5726 		    pmpriv->adapter->dfs_test_params.fixed_new_channel_on_radar) {
5727 			/* Handle embedded DFS */
5728 			if (pmpriv->adapter->state_rdh.stage ==
5729 			    RDH_SET_CUSTOM_IE) {
5730 				pmadapter->state_rdh.stage =
5731 					RDH_RESTART_TRAFFIC;
5732 				wlan_11h_radar_detected_handling(pmadapter,
5733 								 pmpriv);
5734 			}
5735 
5736 		} else {
5737 			/* Handle Host-based DFS and non-DFS(normal uap) case */
5738 			pmpriv->intf_state_11h.tx_disabled = MFALSE;
5739 		}
5740 		if (pmpriv->uap_host_based) {
5741 			memset(pmadapter, event_buf, 0x00, MAX_EVENT_SIZE);
5742 			/* Setup event buffer */
5743 			pevent->bss_index = pmpriv->bss_index;
5744 			pevent->event_id =
5745 				MLAN_EVENT_ID_FW_CHAN_SWITCH_COMPLETE;
5746 			pevent->event_len = sizeof(chan_band_info);
5747 			pchan_band_info = (chan_band_info *)pevent->event_buf;
5748 			/* Copy event data */
5749 			memcpy_ext(pmadapter, (t_u8 *)&pchan_band_info->bandcfg,
5750 				   (t_u8 *)&pchan_info->bandcfg,
5751 				   sizeof(pchan_info->bandcfg),
5752 				   sizeof(pchan_info->bandcfg));
5753 			pchan_band_info->channel = pchan_info->channel;
5754 			if (pchan_band_info->bandcfg.chanWidth == CHAN_BW_80MHZ)
5755 				pchan_band_info->center_chan =
5756 					wlan_get_center_freq_idx(
5757 						priv, BAND_AAC,
5758 						pchan_info->channel,
5759 						CHANNEL_BW_80MHZ);
5760 			pchan_band_info->is_11n_enabled =
5761 				pmpriv->is_11n_enabled;
5762 			wlan_recv_event(pmpriv,
5763 					MLAN_EVENT_ID_FW_CHAN_SWITCH_COMPLETE,
5764 					pevent);
5765 			pevent->event_id = 0;
5766 		}
5767 		break;
5768 	case EVENT_REMAIN_ON_CHANNEL_EXPIRED:
5769 		PRINTM_NETINTF(MEVENT, pmpriv);
5770 		PRINTM(MEVENT, "EVENT: REMAIN_ON_CHANNEL_EXPIRED reason=%d\n",
5771 		       *(t_u16 *)pmadapter->event_body);
5772 		wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_FLUSH_RX_WORK, MNULL);
5773 		pevent->event_id = MLAN_EVENT_ID_FW_REMAIN_ON_CHAN_EXPIRED;
5774 		break;
5775 
5776 	case EVENT_FW_DEBUG_INFO:
5777 		memset(pmadapter, event_buf, 0x00, MAX_EVENT_SIZE);
5778 		pevent->bss_index = pmpriv->bss_index;
5779 		pevent->event_id = MLAN_EVENT_ID_FW_DEBUG_INFO;
5780 		pevent->event_len = pmbuf->data_len - sizeof(eventcause);
5781 		memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
5782 			   pmbuf->pbuf + pmbuf->data_offset +
5783 				   sizeof(eventcause),
5784 			   pevent->event_len, pevent->event_len);
5785 		PRINTM(MEVENT, "EVENT: FW Debug Info %s\n",
5786 		       (t_u8 *)pevent->event_buf);
5787 		wlan_recv_event(pmpriv, pevent->event_id, pevent);
5788 		pevent->event_id = 0; /* clear to avoid resending at end of fcn
5789 				       */
5790 		break;
5791 	case EVENT_TX_STATUS_REPORT:
5792 		PRINTM(MINFO, "EVENT: TX_STATUS\n");
5793 		pevent->event_id = MLAN_EVENT_ID_FW_TX_STATUS;
5794 		break;
5795 	case EVENT_BT_COEX_WLAN_PARA_CHANGE:
5796 		PRINTM(MEVENT, "EVENT: BT coex wlan param update\n");
5797 		wlan_bt_coex_wlan_param_update_event(pmpriv, pmbuf);
5798 		break;
5799 	case EVENT_EXCEED_MAX_P2P_CONN:
5800 		event_excd_p2p =
5801 			(event_exceed_max_p2p_conn *)(pmbuf->pbuf +
5802 						      pmbuf->data_offset);
5803 		PRINTM(MEVENT, "EVENT: EXCEED MAX P2P CONNECTION\n");
5804 		PRINTM(MEVENT, "REQUEST P2P MAC: " MACSTR "\n",
5805 		       MAC2STR(event_excd_p2p->peer_mac_addr));
5806 		pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU;
5807 		break;
5808 	case EVENT_VDLL_IND:
5809 		wlan_process_vdll_event(pmpriv, pmbuf);
5810 		break;
5811 	case EVENT_CSI:
5812 		PRINTM(MEVENT, "EVENT: EVENT_CSI on UAP\n");
5813 		wlan_process_csi_event(pmpriv);
5814 		break;
5815 
5816 	case EVENT_FW_HANG_REPORT:
5817 		if (pmbuf->data_len < (sizeof(eventcause) + sizeof(t_u16))) {
5818 			PRINTM(MEVENT,
5819 			       "EVENT: EVENT_FW_HANG_REPORT skip for len too short: %d\n",
5820 			       pmbuf->data_len);
5821 			break;
5822 		}
5823 		PRINTM(MEVENT, "EVENT: EVENT_FW_HANG_REPORT reasoncode=%d\n",
5824 		       wlan_le16_to_cpu(*(t_u16 *)(pmbuf->pbuf +
5825 						   pmbuf->data_offset +
5826 						   sizeof(eventcause))));
5827 		pmadapter->fw_hang_report = MTRUE;
5828 		wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_DBG_DUMP, MNULL);
5829 		break;
5830 	case EVENT_WATCHDOG_TMOUT:
5831 		PRINTM(MEVENT, "EVENT: EVENT_WATCHDOG_TMOUT reasoncode=%d\n",
5832 		       wlan_le16_to_cpu(*(t_u16 *)(pmbuf->pbuf +
5833 						   pmbuf->data_offset +
5834 						   sizeof(eventcause))));
5835 		pevent->event_id = MLAN_EVENT_ID_DRV_WIFI_STATUS;
5836 		pevent->event_len = sizeof(pevent->event_id) + sizeof(t_u16);
5837 		memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
5838 			   pmbuf->pbuf + pmbuf->data_offset +
5839 				   sizeof(eventcause),
5840 			   sizeof(t_u16), sizeof(t_u16));
5841 		break;
5842 	case CHAN_LOAD_EVENT: {
5843 		t_u8 *ptr = MNULL;
5844 		HostCmd_DS_GET_CH_LOAD *cfg_cmd = MNULL;
5845 		ptr = (t_u8 *)(pmbuf->pbuf + pmbuf->data_offset);
5846 		ptr += 4; /* actual data buffer start */
5847 		cfg_cmd = (HostCmd_DS_GET_CH_LOAD *)ptr;
5848 		pmpriv->ch_load_param = wlan_le16_to_cpu(cfg_cmd->ch_load);
5849 		pmpriv->noise = wlan_le16_to_cpu(cfg_cmd->noise);
5850 		pmpriv->rx_quality = wlan_le16_to_cpu(cfg_cmd->rx_quality);
5851 		break;
5852 	}
5853 	case EVENT_FW_DUMP_INFO:
5854 		PRINTM(MINFO, "EVENT: Dump FW info\n");
5855 		pevent->event_id = MLAN_EVENT_ID_FW_DUMP_INFO;
5856 		break;
5857 	default:
5858 		pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU;
5859 		break;
5860 	}
5861 
5862 	if (pevent->event_id) {
5863 		pevent->bss_index = pmpriv->bss_index;
5864 		pevent->event_len = pmbuf->data_len;
5865 		memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
5866 			   pmbuf->pbuf + pmbuf->data_offset, pevent->event_len,
5867 			   pevent->event_len);
5868 		wlan_recv_event(pmpriv, pevent->event_id, pevent);
5869 	}
5870 done:
5871 	if (event_buf)
5872 		pcb->moal_mfree(pmadapter->pmoal_handle, event_buf);
5873 	LEAVE();
5874 	return ret;
5875 }
5876 
5877 /**
5878  *  @brief  This function issues commands to set uap max sta number
5879  *
5880  *  @param priv         A pointer to mlan_private structure
5881  *  @param uap_max_sta  Max station number uAP can supported (per chip)
5882  *
5883  *  @return   MLAN_STATUS_SUCCESS or MLAN_STATUS_PENDING or MLAN_STATUS_FAILURE
5884  */
wlan_uap_set_uap_max_sta(pmlan_private pmpriv,t_u8 uap_max_sta)5885 static mlan_status wlan_uap_set_uap_max_sta(pmlan_private pmpriv,
5886 					    t_u8 uap_max_sta)
5887 {
5888 	MrvlIEtypes_uap_max_sta_cnt_t tlv_uap_max_sta;
5889 	mlan_status ret = MLAN_STATUS_SUCCESS;
5890 
5891 	ENTER();
5892 	memset(pmpriv->adapter, &tlv_uap_max_sta, 0, sizeof(tlv_uap_max_sta));
5893 	tlv_uap_max_sta.header.type =
5894 		wlan_cpu_to_le16(TLV_TYPE_UAP_MAX_STA_CNT_PER_CHIP);
5895 	tlv_uap_max_sta.header.len = wlan_cpu_to_le16(sizeof(t_u16));
5896 	tlv_uap_max_sta.uap_max_sta = wlan_cpu_to_le16(uap_max_sta);
5897 	ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_SYS_CONFIGURE,
5898 			       HostCmd_ACT_GEN_SET, 0, MNULL, &tlv_uap_max_sta);
5899 	LEAVE();
5900 	return ret;
5901 }
5902 
5903 /**
5904  *  @brief  This function issues commands to initialize firmware
5905  *
5906  *  @param priv         A pointer to mlan_private structure
5907  *  @param first_bss    flag for first BSS
5908  *
5909  *  @return   MLAN_STATUS_SUCCESS or MLAN_STATUS_PENDING or MLAN_STATUS_FAILURE
5910  */
wlan_ops_uap_init_cmd(t_void * priv,t_u8 first_bss)5911 mlan_status wlan_ops_uap_init_cmd(t_void *priv, t_u8 first_bss)
5912 {
5913 	mlan_status ret = MLAN_STATUS_SUCCESS;
5914 	pmlan_private pmpriv = (pmlan_private)priv;
5915 	t_u16 last_cmd = 0;
5916 
5917 	ENTER();
5918 	if (!pmpriv) {
5919 		LEAVE();
5920 		return MLAN_STATUS_FAILURE;
5921 	}
5922 
5923 	if (first_bss) {
5924 		if (wlan_adapter_init_cmd(pmpriv->adapter) ==
5925 		    MLAN_STATUS_FAILURE) {
5926 			ret = MLAN_STATUS_FAILURE;
5927 			goto done;
5928 		}
5929 	}
5930 	if (pmpriv->adapter->init_para.uap_max_sta &&
5931 	    (pmpriv->adapter->init_para.uap_max_sta <= MAX_STA_COUNT))
5932 		wlan_uap_set_uap_max_sta(
5933 			pmpriv, pmpriv->adapter->init_para.uap_max_sta);
5934 
5935 	ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_SYS_CONFIGURE,
5936 			       HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
5937 	if (ret) {
5938 		ret = MLAN_STATUS_FAILURE;
5939 		goto done;
5940 	}
5941 	last_cmd = HOST_CMD_APCMD_SYS_CONFIGURE;
5942 	/** set last_init_cmd */
5943 	if (last_cmd) {
5944 		pmpriv->adapter->last_init_cmd = last_cmd;
5945 		ret = MLAN_STATUS_PENDING;
5946 	}
5947 done:
5948 	LEAVE();
5949 	return ret;
5950 }
5951