1 /** @file mlan_uap_cmdevent.c
2  *
3  *  @brief  This file provides the handling of AP mode command and event
4  *
5  *  Copyright 2008-2024 NXP
6  *
7  *  SPDX-License-Identifier: BSD-3-Clause
8  *
9  */
10 
11 /********************************************************
12 Change log:
13     02/05/2009: initial version
14 ********************************************************/
15 
16 #include <mlan_api.h>
17 
18 /* Additional WMSDK header files */
19 #include <wmerrno.h>
20 #include <osa.h>
21 
22 /* Always keep this include at the end of all include files */
23 #include <mlan_remap_mem_operations.h>
24 
25 /**
26  *  @brief This function prepares command for config uap settings
27  *
28  *  @param pmpriv		A pointer to mlan_private structure
29  *  @param cmd	   		A pointer to HostCmd_DS_COMMAND structure
30  *  @param cmd_action   the action: GET or SET
31  *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
32  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
33  */
wlan_uap_cmd_ap_config(pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_u16 cmd_action,IN pmlan_ioctl_req pioctl_buf)34 static mlan_status wlan_uap_cmd_ap_config(pmlan_private pmpriv,
35                                           IN HostCmd_DS_COMMAND *cmd,
36                                           IN t_u16 cmd_action,
37                                           IN pmlan_ioctl_req pioctl_buf)
38 {
39     mlan_ds_bss *bss                               = MNULL;
40     HostCmd_DS_SYS_CONFIG *sys_config              = (HostCmd_DS_SYS_CONFIG *)&cmd->params.sys_config;
41     t_u8 *tlv                                      = MNULL;
42     MrvlIEtypes_MacAddr_t *tlv_mac                 = MNULL;
43     MrvlIEtypes_SsIdParamSet_t *tlv_ssid           = MNULL;
44     MrvlIEtypes_beacon_period_t *tlv_beacon_period = MNULL;
45     MrvlIEtypes_ecsa_config_t *tlv_ecsa_config     = MNULL;
46     MrvlIEtypes_dtim_period_t *tlv_dtim_period     = MNULL;
47     MrvlIEtypes_RatesParamSet_t *tlv_rates         = MNULL;
48     MrvlIEtypes_bcast_ssid_t *tlv_bcast_ssid = MNULL;
49     MrvlIEtypes_auth_type_t *tlv_auth_type               = MNULL;
50     MrvlIEtypes_channel_band_t *tlv_chan_band            = MNULL;
51     MrvlIEtypes_ChanListParamSet_t *tlv_chan_list        = MNULL;
52     ChanScanParamSet_t *pscan_chan                       = MNULL;
53     MrvlIEtypes_encrypt_protocol_t *tlv_encrypt_protocol = MNULL;
54     MrvlIEtypes_akmp_t *tlv_akmp                         = MNULL;
55     MrvlIEtypes_pwk_cipher_t *tlv_pwk_cipher             = MNULL;
56     MrvlIEtypes_gwk_cipher_t *tlv_gwk_cipher             = MNULL;
57     MrvlIEtypes_passphrase_t *tlv_passphrase = MNULL;
58     MrvlIEtypes_password_t *tlv_password     = MNULL;
59     MrvlIEtypes_wmm_parameter_t *tlv_wmm_parameter = MNULL;
60 #if (CONFIG_UAP_AMPDU_TX) || (CONFIG_UAP_AMPDU_RX)
61     MrvlIETypes_HTCap_t *tlv_htcap = MNULL;
62 #endif
63     t_u32 cmd_size  = 0;
64     t_u8 zero_mac[] = {0, 0, 0, 0, 0, 0};
65     t_u16 i;
66     t_u16 ac;
67 
68     ENTER();
69     if (pioctl_buf == MNULL)
70     {
71         LEAVE();
72         return MLAN_STATUS_FAILURE;
73     }
74 
75     bss = (mlan_ds_bss *)(void *)pioctl_buf->pbuf;
76 
77     cmd->command       = wlan_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
78     sys_config->action = wlan_cpu_to_le16(cmd_action);
79     cmd_size           = sizeof(HostCmd_DS_SYS_CONFIG) - 1U + S_DS_GEN;
80 
81     tlv = (t_u8 *)sys_config->tlv_buffer;
82     if (__memcmp(pmpriv->adapter, zero_mac, &bss->param.bss_config.mac_addr, MLAN_MAC_ADDR_LENGTH) != 0)
83     {
84         tlv_mac              = (MrvlIEtypes_MacAddr_t *)(void *)tlv;
85         tlv_mac->header.type = wlan_cpu_to_le16(TLV_TYPE_UAP_MAC_ADDRESS);
86         tlv_mac->header.len  = wlan_cpu_to_le16(MLAN_MAC_ADDR_LENGTH);
87         (void)__memcpy(pmpriv->adapter, tlv_mac->mac, &bss->param.bss_config.mac_addr, MLAN_MAC_ADDR_LENGTH);
88         cmd_size += sizeof(MrvlIEtypes_MacAddr_t);
89         tlv += sizeof(MrvlIEtypes_MacAddr_t);
90     }
91 
92     if (bss->param.bss_config.ssid.ssid_len != 0U)
93     {
94         tlv_ssid              = (MrvlIEtypes_SsIdParamSet_t *)(void *)tlv;
95         tlv_ssid->header.type = wlan_cpu_to_le16(TLV_TYPE_SSID);
96         tlv_ssid->header.len  = wlan_cpu_to_le16((t_u16)bss->param.bss_config.ssid.ssid_len);
97         (void)__memcpy(pmpriv->adapter, tlv_ssid->ssid, bss->param.bss_config.ssid.ssid,
98                        bss->param.bss_config.ssid.ssid_len);
99         cmd_size += sizeof(MrvlIEtypesHeader_t) + bss->param.bss_config.ssid.ssid_len;
100         tlv += sizeof(MrvlIEtypesHeader_t) + bss->param.bss_config.ssid.ssid_len;
101     }
102 
103     if ((bss->param.bss_config.beacon_period >= MIN_BEACON_PERIOD) &&
104         (bss->param.bss_config.beacon_period <= MAX_BEACON_PERIOD))
105     {
106         tlv_beacon_period                = (MrvlIEtypes_beacon_period_t *)(void *)tlv;
107         tlv_beacon_period->header.type   = wlan_cpu_to_le16(TLV_TYPE_UAP_BEACON_PERIOD);
108         tlv_beacon_period->header.len    = wlan_cpu_to_le16(sizeof(t_u16));
109         tlv_beacon_period->beacon_period = wlan_cpu_to_le16(bss->param.bss_config.beacon_period);
110         cmd_size += sizeof(MrvlIEtypes_beacon_period_t);
111         tlv += sizeof(MrvlIEtypes_beacon_period_t);
112     }
113 
114     if ((bss->param.bss_config.chan_sw_count >= MIN_CHSW_COUNT) &&
115         (bss->param.bss_config.chan_sw_count <= MAX_CHSW_COUNT))
116     {
117         tlv_ecsa_config                     = (MrvlIEtypes_ecsa_config_t *)(void *)tlv;
118         tlv_ecsa_config->header.type        = wlan_cpu_to_le16(TLV_TYPE_UAP_ECSA_CONFIG);
119         tlv_ecsa_config->header.len         = wlan_cpu_to_le16(sizeof(t_u16) + sizeof(t_u8) + sizeof(t_u8));
120         tlv_ecsa_config->enable             = 1;
121         tlv_ecsa_config->ChannelSwitchMode  = 0;
122         tlv_ecsa_config->ChannelSwitchCount = bss->param.bss_config.chan_sw_count;
123         cmd_size += sizeof(MrvlIEtypes_ecsa_config_t);
124         tlv += sizeof(MrvlIEtypes_ecsa_config_t);
125     }
126 
127     if ((bss->param.bss_config.dtim_period >= MIN_DTIM_PERIOD) &&
128         (bss->param.bss_config.dtim_period <= MAX_DTIM_PERIOD))
129     {
130         tlv_dtim_period              = (MrvlIEtypes_dtim_period_t *)(void *)tlv;
131         tlv_dtim_period->header.type = wlan_cpu_to_le16(TLV_TYPE_UAP_DTIM_PERIOD);
132         tlv_dtim_period->header.len  = wlan_cpu_to_le16(sizeof(t_u8));
133         tlv_dtim_period->dtim_period = bss->param.bss_config.dtim_period;
134         cmd_size += sizeof(MrvlIEtypes_dtim_period_t);
135         tlv += sizeof(MrvlIEtypes_dtim_period_t);
136     }
137 
138     if (bss->param.bss_config.rates[0] != 0U)
139     {
140         tlv_rates              = (MrvlIEtypes_RatesParamSet_t *)(void *)tlv;
141         tlv_rates->header.type = wlan_cpu_to_le16(TLV_TYPE_RATES);
142         for (i = 0; i < MAX_DATA_RATES && bss->param.bss_config.rates[i]; i++)
143         {
144             tlv_rates->rates[i] = bss->param.bss_config.rates[i];
145         }
146         tlv_rates->header.len = wlan_cpu_to_le16(i);
147         cmd_size += sizeof(MrvlIEtypesHeader_t) + i;
148         tlv += sizeof(MrvlIEtypesHeader_t) + i;
149     }
150 
151     if (bss->param.bss_config.bcast_ssid_ctl <= MAX_BCAST_SSID_CTL)
152     {
153         tlv_bcast_ssid                 = (MrvlIEtypes_bcast_ssid_t *)(void *)tlv;
154         tlv_bcast_ssid->header.type    = wlan_cpu_to_le16(TLV_TYPE_UAP_BCAST_SSID_CTL);
155         tlv_bcast_ssid->header.len     = wlan_cpu_to_le16(sizeof(t_u8));
156         tlv_bcast_ssid->bcast_ssid_ctl = bss->param.bss_config.bcast_ssid_ctl;
157         cmd_size += sizeof(MrvlIEtypes_bcast_ssid_t);
158         tlv += sizeof(MrvlIEtypes_bcast_ssid_t);
159     }
160 
161     if ((((bss->param.bss_config.band_cfg & BAND_CONFIG_ACS_MODE) == BAND_CONFIG_MANUAL) &&
162          (bss->param.bss_config.channel > 0U) && (bss->param.bss_config.channel <= MLAN_MAX_CHANNEL)) ||
163         (bss->param.bss_config.band_cfg & BAND_CONFIG_ACS_MODE))
164     {
165         tlv_chan_band              = (MrvlIEtypes_channel_band_t *)(void *)tlv;
166         tlv_chan_band->header.type = wlan_cpu_to_le16(TLV_TYPE_UAP_CHAN_BAND_CONFIG);
167         tlv_chan_band->header.len  = wlan_cpu_to_le16(sizeof(t_u8) + sizeof(t_u8));
168         tlv_chan_band->band_config = bss->param.bss_config.band_cfg;
169         tlv_chan_band->channel     = bss->param.bss_config.channel;
170         cmd_size += sizeof(MrvlIEtypes_channel_band_t);
171         tlv += sizeof(MrvlIEtypes_channel_band_t);
172     }
173 
174     if ((bss->param.bss_config.num_of_chan) && (bss->param.bss_config.num_of_chan <= MLAN_MAX_CHANNEL))
175     {
176         tlv_chan_list              = (MrvlIEtypes_ChanListParamSet_t *)(void *)tlv;
177         tlv_chan_list->header.type = wlan_cpu_to_le16(TLV_TYPE_CHANLIST);
178         tlv_chan_list->header.len =
179             wlan_cpu_to_le16((t_u16)(sizeof(ChanScanParamSet_t) * bss->param.bss_config.num_of_chan));
180         pscan_chan = tlv_chan_list->chan_scan_param;
181         for (i = 0; i < bss->param.bss_config.num_of_chan; i++)
182         {
183             (void)__memset(pmpriv->adapter, pscan_chan, 0x00, sizeof(ChanScanParamSet_t));
184             pscan_chan->chan_number = bss->param.bss_config.chan_list[i].chan_number;
185             pscan_chan->radio_type  = bss->param.bss_config.chan_list[i].band_config_type;
186             pscan_chan++;
187         }
188         cmd_size += sizeof(tlv_chan_list->header) + (sizeof(ChanScanParamSet_t) * bss->param.bss_config.num_of_chan);
189         tlv += sizeof(tlv_chan_list->header) + (sizeof(ChanScanParamSet_t) * bss->param.bss_config.num_of_chan);
190     }
191 
192     if ((bss->param.bss_config.auth_mode <= MLAN_AUTH_MODE_SHARED) ||
193         (bss->param.bss_config.auth_mode == MLAN_AUTH_MODE_AUTO))
194     {
195         tlv_auth_type                 = (MrvlIEtypes_auth_type_t *)tlv;
196         tlv_auth_type->header.type    = wlan_cpu_to_le16(TLV_TYPE_AUTH_TYPE);
197         tlv_auth_type->header.len     = wlan_cpu_to_le16(sizeof(MrvlIEtypes_auth_type_t) - sizeof(MrvlIEtypesHeader_t));
198         tlv_auth_type->auth_type      = (t_u8)bss->param.bss_config.auth_mode;
199         tlv_auth_type->PWE_derivation = (t_u8)bss->param.bss_config.pwe_derivation;
200         tlv_auth_type->transition_disable = (t_u8)bss->param.bss_config.transition_disable;
201         cmd_size += sizeof(MrvlIEtypes_auth_type_t);
202         tlv += sizeof(MrvlIEtypes_auth_type_t);
203     }
204 
205     if (bss->param.bss_config.protocol != 0U)
206     {
207         tlv_encrypt_protocol              = (MrvlIEtypes_encrypt_protocol_t *)(void *)tlv;
208         tlv_encrypt_protocol->header.type = wlan_cpu_to_le16(TLV_TYPE_UAP_ENCRYPT_PROTOCOL);
209         tlv_encrypt_protocol->header.len  = wlan_cpu_to_le16(sizeof(t_u16));
210         tlv_encrypt_protocol->protocol    = wlan_cpu_to_le16(bss->param.bss_config.protocol);
211         cmd_size += sizeof(MrvlIEtypes_encrypt_protocol_t);
212         tlv += sizeof(MrvlIEtypes_encrypt_protocol_t);
213     }
214 
215     if ((bss->param.bss_config.protocol & PROTOCOL_WPA) || (bss->param.bss_config.protocol & PROTOCOL_WPA2) ||
216         (bss->param.bss_config.protocol & PROTOCOL_WPA3_SAE) ||
217 #if CONFIG_DRIVER_OWE
218         (bss->param.bss_config.protocol & PROTOCOL_OWE) ||
219 #endif
220         (bss->param.bss_config.protocol & PROTOCOL_EAP))
221     {
222         tlv_akmp                     = (MrvlIEtypes_akmp_t *)(void *)tlv;
223         tlv_akmp->header.type        = wlan_cpu_to_le16(TLV_TYPE_UAP_AKMP);
224         tlv_akmp->key_mgmt           = wlan_cpu_to_le16(bss->param.bss_config.key_mgmt);
225         tlv_akmp->header.len         = (t_u16)sizeof(t_u16);
226         tlv_akmp->key_mgmt_operation = wlan_cpu_to_le16(bss->param.bss_config.key_mgmt_operation);
227         tlv_akmp->header.len += (t_u16)sizeof(t_u16);
228         tlv_akmp->header.len = wlan_cpu_to_le16(tlv_akmp->header.len);
229         cmd_size += sizeof(MrvlIEtypes_akmp_t);
230         tlv += sizeof(MrvlIEtypes_akmp_t);
231 
232         if ((bss->param.bss_config.wpa_cfg.pairwise_cipher_wpa & VALID_CIPHER_BITMAP) != 0U)
233         {
234             tlv_pwk_cipher                  = (MrvlIEtypes_pwk_cipher_t *)(void *)tlv;
235             tlv_pwk_cipher->header.type     = wlan_cpu_to_le16(TLV_TYPE_PWK_CIPHER);
236             tlv_pwk_cipher->header.len      = wlan_cpu_to_le16(sizeof(t_u16) + sizeof(t_u8) + sizeof(t_u8));
237             tlv_pwk_cipher->protocol        = wlan_cpu_to_le16(PROTOCOL_WPA);
238             tlv_pwk_cipher->pairwise_cipher = bss->param.bss_config.wpa_cfg.pairwise_cipher_wpa;
239             cmd_size += sizeof(MrvlIEtypes_pwk_cipher_t);
240             tlv += sizeof(MrvlIEtypes_pwk_cipher_t);
241         }
242 
243         if ((bss->param.bss_config.wpa_cfg.pairwise_cipher_wpa2 & VALID_CIPHER_BITMAP) != 0U)
244         {
245             tlv_pwk_cipher              = (MrvlIEtypes_pwk_cipher_t *)(void *)tlv;
246             tlv_pwk_cipher->header.type = wlan_cpu_to_le16(TLV_TYPE_PWK_CIPHER);
247             tlv_pwk_cipher->header.len  = wlan_cpu_to_le16(sizeof(t_u16) + sizeof(t_u8) + sizeof(t_u8));
248             if ((bss->param.bss_config.protocol & PROTOCOL_WPA3_SAE) != 0U)
249             {
250                 tlv_pwk_cipher->protocol = wlan_cpu_to_le16(PROTOCOL_WPA3_SAE);
251             }
252             else
253             {
254                 tlv_pwk_cipher->protocol = wlan_cpu_to_le16(PROTOCOL_WPA2);
255             }
256             tlv_pwk_cipher->pairwise_cipher = bss->param.bss_config.wpa_cfg.pairwise_cipher_wpa2;
257             cmd_size += sizeof(MrvlIEtypes_pwk_cipher_t);
258             tlv += sizeof(MrvlIEtypes_pwk_cipher_t);
259         }
260 
261         if ((bss->param.bss_config.wpa_cfg.group_cipher & VALID_CIPHER_BITMAP) != 0U)
262         {
263             tlv_gwk_cipher               = (MrvlIEtypes_gwk_cipher_t *)(void *)tlv;
264             tlv_gwk_cipher->header.type  = wlan_cpu_to_le16(TLV_TYPE_GWK_CIPHER);
265             tlv_gwk_cipher->header.len   = wlan_cpu_to_le16(sizeof(t_u8) + sizeof(t_u8));
266             tlv_gwk_cipher->group_cipher = bss->param.bss_config.wpa_cfg.group_cipher;
267             cmd_size += sizeof(MrvlIEtypes_gwk_cipher_t);
268             tlv += sizeof(MrvlIEtypes_gwk_cipher_t);
269         }
270 
271         if (bss->param.bss_config.wpa_cfg.length != 0U)
272         {
273             tlv_passphrase              = (MrvlIEtypes_passphrase_t *)(void *)tlv;
274             tlv_passphrase->header.type = wlan_cpu_to_le16(TLV_TYPE_UAP_WPA_PASSPHRASE);
275             tlv_passphrase->header.len  = (t_u16)wlan_cpu_to_le16(bss->param.bss_config.wpa_cfg.length);
276             (void)__memcpy(pmpriv->adapter, tlv_passphrase->passphrase, bss->param.bss_config.wpa_cfg.passphrase,
277                            bss->param.bss_config.wpa_cfg.length);
278             cmd_size += sizeof(MrvlIEtypesHeader_t) + bss->param.bss_config.wpa_cfg.length;
279             tlv += sizeof(MrvlIEtypesHeader_t) + bss->param.bss_config.wpa_cfg.length;
280         }
281 
282         if (bss->param.bss_config.wpa_cfg.password_length != 0U)
283         {
284             tlv_password              = (MrvlIEtypes_password_t *)(void *)tlv;
285             tlv_password->header.type = wlan_cpu_to_le16(TLV_TYPE_UAP_WPA3_SAE_PASSWORD);
286             tlv_password->header.len  = (t_u16)wlan_cpu_to_le16(bss->param.bss_config.wpa_cfg.password_length);
287             (void)__memcpy(pmpriv->adapter, tlv_password->password, bss->param.bss_config.wpa_cfg.password,
288                            bss->param.bss_config.wpa_cfg.password_length);
289             cmd_size += sizeof(MrvlIEtypesHeader_t) + bss->param.bss_config.wpa_cfg.password_length;
290             tlv += sizeof(MrvlIEtypesHeader_t) + bss->param.bss_config.wpa_cfg.password_length;
291         }
292     }
293 
294 #if (CONFIG_UAP_AMPDU_TX) || (CONFIG_UAP_AMPDU_RX)
295     if ((bss->param.bss_config.ht_cap_info) != 0U)
296     {
297         /* wmsdk: All the values received will be zero by default. */
298         tlv_htcap                     = (MrvlIETypes_HTCap_t *)(void *)tlv;
299         tlv_htcap->header.type        = wlan_cpu_to_le16(HT_CAPABILITY);
300         tlv_htcap->header.len         = wlan_cpu_to_le16(sizeof(HTCap_t));
301         tlv_htcap->ht_cap.ht_cap_info = wlan_cpu_to_le16(bss->param.bss_config.ht_cap_info);
302         tlv_htcap->ht_cap.ampdu_param = bss->param.bss_config.ampdu_param;
303         (void)__memcpy(pmpriv->adapter, tlv_htcap->ht_cap.supported_mcs_set, bss->param.bss_config.supported_mcs_set,
304                        16);
305 #if CONFIG_WIFI_CAPA
306         /* Disable 802.11n */
307         if (!pmpriv->adapter->usr_dot_11n_enable)
308         {
309             tlv_htcap->ht_cap.supported_mcs_set[0] = 0;
310             tlv_htcap->ht_cap.supported_mcs_set[4] = 0;
311 #ifdef STREAM_2X2
312             tlv_htcap->ht_cap.supported_mcs_set[1] = 0;
313 #endif
314         }
315 #endif
316         tlv_htcap->ht_cap.ht_ext_cap = wlan_cpu_to_le16(bss->param.bss_config.ht_ext_cap);
317         tlv_htcap->ht_cap.tx_bf_cap  = wlan_cpu_to_le32(bss->param.bss_config.tx_bf_cap);
318         tlv_htcap->ht_cap.asel       = bss->param.bss_config.asel;
319         cmd_size += sizeof(MrvlIETypes_HTCap_t);
320         tlv += sizeof(MrvlIETypes_HTCap_t);
321     }
322 #endif
323 
324     if ((bss->param.bss_config.uap_host_based_config == MTRUE) ||
325         (bss->param.bss_config.wmm_para.qos_info & 0x80 || bss->param.bss_config.wmm_para.qos_info == 0x00))
326     {
327         tlv_wmm_parameter              = (MrvlIEtypes_wmm_parameter_t *)tlv;
328         (void)__memset(pmpriv->adapter, tlv_wmm_parameter, 0x00, sizeof(MrvlIEtypes_wmm_parameter_t));
329         tlv_wmm_parameter->header.type = wlan_cpu_to_le16(TLV_TYPE_VENDOR_SPECIFIC_IE);
330         tlv_wmm_parameter->header.len  = wlan_cpu_to_le16(sizeof(bss->param.bss_config.wmm_para));
331         (void)__memcpy(pmpriv->adapter, tlv_wmm_parameter->wmm_para.ouitype, bss->param.bss_config.wmm_para.ouitype,
332                        sizeof(tlv_wmm_parameter->wmm_para.ouitype));
333         tlv_wmm_parameter->wmm_para.ouisubtype = bss->param.bss_config.wmm_para.ouisubtype;
334         tlv_wmm_parameter->wmm_para.version    = bss->param.bss_config.wmm_para.version;
335         tlv_wmm_parameter->wmm_para.qos_info   = bss->param.bss_config.wmm_para.qos_info;
336         tlv_wmm_parameter->wmm_para.reserved   = 0x00;
337         for (ac = 0; ac < 4; ac++)
338         {
339             tlv_wmm_parameter->wmm_para.ac_params[ac].aci_aifsn.aifsn =
340                 bss->param.bss_config.wmm_para.ac_params[ac].aci_aifsn.aifsn;
341             tlv_wmm_parameter->wmm_para.ac_params[ac].aci_aifsn.acm =
342                 bss->param.bss_config.wmm_para.ac_params[ac].aci_aifsn.acm;
343             tlv_wmm_parameter->wmm_para.ac_params[ac].aci_aifsn.aci =
344                 bss->param.bss_config.wmm_para.ac_params[ac].aci_aifsn.aci;
345             tlv_wmm_parameter->wmm_para.ac_params[ac].ecw.ecw_max =
346                 bss->param.bss_config.wmm_para.ac_params[ac].ecw.ecw_max;
347             tlv_wmm_parameter->wmm_para.ac_params[ac].ecw.ecw_min =
348                 bss->param.bss_config.wmm_para.ac_params[ac].ecw.ecw_min;
349             tlv_wmm_parameter->wmm_para.ac_params[ac].tx_op_limit =
350                 wlan_cpu_to_le16(bss->param.bss_config.wmm_para.ac_params[ac].tx_op_limit);
351         }
352         cmd_size += sizeof(MrvlIEtypes_wmm_parameter_t);
353         tlv += sizeof(MrvlIEtypes_wmm_parameter_t);
354     }
355 
356     cmd->size = (t_u16)wlan_cpu_to_le16(cmd_size);
357     PRINTM(MCMND, "AP config: cmd_size=%d\n", cmd_size);
358 #if CONFIG_WIFI_EXTRA_DEBUG
359     PRINTF("wlan_uap_cmd_ap_config : cmd\r\n");
360     dump_hex(cmd, cmd->size);
361 #endif
362     LEAVE();
363     return MLAN_STATUS_SUCCESS;
364 }
365 
366 /**
367  *  @brief This function prepares command of sys_config
368  *
369  *  @param pmpriv		A pointer to mlan_private structure
370  *  @param cmd	   		A pointer to HostCmd_DS_COMMAND structure
371  *  @param cmd_action   the action: GET or SET
372  *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
373  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
374  */
wlan_uap_cmd_sys_configure(pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_u16 cmd_action,IN pmlan_ioctl_req pioctl_buf,IN t_void * pdata_buf)375 static mlan_status wlan_uap_cmd_sys_configure(pmlan_private pmpriv,
376                                               IN HostCmd_DS_COMMAND *cmd,
377                                               IN t_u16 cmd_action,
378                                               IN pmlan_ioctl_req pioctl_buf,
379                                               IN t_void *pdata_buf)
380 {
381     mlan_ds_bss *bss                          = MNULL;
382     HostCmd_DS_SYS_CONFIG *sys_config         = (HostCmd_DS_SYS_CONFIG *)&cmd->params.sys_config;
383     MrvlIEtypes_channel_band_t *chan_band_tlv = MNULL, *pdat_tlv_cb = MNULL;
384     MrvlIEtypes_max_sta_count_t *max_sta_cnt_tlv = MNULL, *pdat_tlv_ccb = MNULL;
385     mlan_ds_misc_custom_ie *cust_ie = MNULL;
386     MrvlIEtypesHeader_t *ie_header  = (MrvlIEtypesHeader_t *)sys_config->tlv_buffer;
387     t_u8 *ie                        = (t_u8 *)sys_config->tlv_buffer + sizeof(MrvlIEtypesHeader_t);
388     t_u16 req_len = 0, travel_len = 0;
389     custom_ie *cptr = MNULL;
390 
391 #if CONFIG_ECSA
392     MrvlIEtypes_action_chan_switch_t *tlv_chan_switch = MNULL;
393     IEEEtypes_ChanSwitchAnn_t *csa_ie                 = MNULL;
394     IEEEtypes_ExtChanSwitchAnn_t *ecsa_ie             = MNULL;
395 #endif
396 
397     mlan_status ret = MLAN_STATUS_SUCCESS;
398 
399     ENTER();
400 
401     cmd->command       = wlan_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
402     sys_config->action = wlan_cpu_to_le16(cmd_action);
403     cmd->size          = wlan_cpu_to_le16(sizeof(HostCmd_DS_SYS_CONFIG) - 1U + S_DS_GEN);
404     if (pioctl_buf == MNULL)
405     {
406         if (pdata_buf != NULL)
407         {
408             switch (*(t_u16 *)pdata_buf)
409             {
410                 case TLV_TYPE_UAP_CHAN_BAND_CONFIG:
411                     pdat_tlv_cb                = (MrvlIEtypes_channel_band_t *)pdata_buf;
412                     chan_band_tlv              = (MrvlIEtypes_channel_band_t *)(void *)sys_config->tlv_buffer;
413                     cmd->size                  = wlan_cpu_to_le16(sizeof(HostCmd_DS_SYS_CONFIG) - 1U + S_DS_GEN +
414                                                                   sizeof(MrvlIEtypes_channel_band_t));
415                     chan_band_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_UAP_CHAN_BAND_CONFIG);
416                     chan_band_tlv->header.len =
417                         wlan_cpu_to_le16(sizeof(MrvlIEtypes_channel_band_t) - sizeof(MrvlIEtypesHeader_t));
418                     if (cmd_action != 0U)
419                     {
420                         chan_band_tlv->band_config = pdat_tlv_cb->band_config;
421                         chan_band_tlv->channel     = pdat_tlv_cb->channel;
422                     }
423                     ret = MLAN_STATUS_SUCCESS;
424                     break;
425                 case TLV_TYPE_UAP_MAX_STA_CNT:
426                     pdat_tlv_ccb                 = (MrvlIEtypes_max_sta_count_t *)pdata_buf;
427                     max_sta_cnt_tlv              = (MrvlIEtypes_max_sta_count_t *)(void *)sys_config->tlv_buffer;
428                     cmd->size                    = wlan_cpu_to_le16(sizeof(HostCmd_DS_SYS_CONFIG) - 1U + S_DS_GEN +
429                                                                     sizeof(MrvlIEtypes_max_sta_count_t));
430                     max_sta_cnt_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_UAP_MAX_STA_CNT);
431 
432                     if (cmd_action != 0U)
433                     {
434                         max_sta_cnt_tlv->header.len =
435                             wlan_cpu_to_le16(sizeof(MrvlIEtypes_max_sta_count_t) - sizeof(MrvlIEtypesHeader_t));
436                         max_sta_cnt_tlv->max_sta_count = pdat_tlv_ccb->max_sta_count;
437                     }
438                     else
439                     {
440                         max_sta_cnt_tlv->header.len    = 0;
441                         max_sta_cnt_tlv->max_sta_count = 0;
442                     }
443                     ret = MLAN_STATUS_SUCCESS;
444                     break;
445                 case TLV_TYPE_MGMT_IE:
446                     cust_ie         = (mlan_ds_misc_custom_ie *)pdata_buf;
447                     cmd->size       = wlan_cpu_to_le16(sizeof(HostCmd_DS_SYS_CONFIG) - 1 + S_DS_GEN +
448                                                        sizeof(MrvlIEtypesHeader_t) + cust_ie->len);
449                     ie_header->type = wlan_cpu_to_le16(TLV_TYPE_MGMT_IE);
450                     ie_header->len  = wlan_cpu_to_le16(cust_ie->len);
451 
452                     if (ie)
453                     {
454                         req_len    = cust_ie->len;
455                         travel_len = 0;
456                         /* conversion for index, mask, len */
457                         if (req_len == sizeof(t_u16))
458                             cust_ie->ie_data_list[0].ie_index = wlan_cpu_to_le16(cust_ie->ie_data_list[0].ie_index);
459                         while (req_len > sizeof(t_u16))
460                         {
461                             cptr = (custom_ie *)(((t_u8 *)&cust_ie->ie_data_list) + travel_len);
462                             travel_len += cptr->ie_length + sizeof(custom_ie) - MAX_IE_SIZE;
463                             req_len -= cptr->ie_length + sizeof(custom_ie) - MAX_IE_SIZE;
464                             cptr->ie_index          = wlan_cpu_to_le16(cptr->ie_index);
465                             cptr->mgmt_subtype_mask = wlan_cpu_to_le16(cptr->mgmt_subtype_mask);
466                             cptr->ie_length         = wlan_cpu_to_le16(cptr->ie_length);
467                         }
468                         (void)__memcpy(pmpriv->adapter, ie, cust_ie->ie_data_list, cust_ie->len);
469                     }
470                     break;
471                 default:
472                     PRINTM(MERROR, "Wrong data, or missing TLV_TYPE 0x%04x handler.\n", *(t_u16 *)pdata_buf);
473                     break;
474             }
475             goto done;
476         }
477     }
478 
479     if (pioctl_buf->req_id == (t_u32)MLAN_IOCTL_BSS)
480     {
481         bss = (mlan_ds_bss *)(void *)pioctl_buf->pbuf;
482         if ((bss->sub_command == MLAN_OID_UAP_BSS_CONFIG) && (cmd_action == HostCmd_ACT_GEN_SET))
483         {
484             ret = wlan_uap_cmd_ap_config(pmpriv, cmd, cmd_action, pioctl_buf);
485             goto done;
486         }
487 #if CONFIG_ECSA
488         else if (bss->sub_command == MLAN_OID_ACTION_CHAN_SWITCH)
489         {
490             cmd->size       = sizeof(HostCmd_DS_SYS_CONFIG) - 1 + S_DS_GEN + sizeof(MrvlIEtypes_action_chan_switch_t);
491             tlv_chan_switch = (MrvlIEtypes_action_chan_switch_t *)sys_config->tlv_buffer;
492             tlv_chan_switch->header.type = wlan_cpu_to_le16(MRVL_ACTION_CHAN_SWITCH_ANNOUNCE);
493             // mode reserve for future use
494             tlv_chan_switch->mode = 0;
495             if (bss->param.chanswitch.new_oper_class)
496             {
497                 tlv_chan_switch->header.len =
498                     wlan_cpu_to_le16(sizeof(MrvlIEtypes_action_chan_switch_t) - sizeof(MrvlIEtypesHeader_t) +
499                                      sizeof(IEEEtypes_ExtChanSwitchAnn_t));
500                 ecsa_ie                    = (IEEEtypes_ExtChanSwitchAnn_t *)tlv_chan_switch->ie_buf;
501                 ecsa_ie->element_id        = EXTEND_CHANNEL_SWITCH_ANN;
502                 ecsa_ie->len               = sizeof(IEEEtypes_ExtChanSwitchAnn_t) - sizeof(IEEEtypes_Header_t);
503                 ecsa_ie->chan_switch_mode  = bss->param.chanswitch.chan_switch_mode;
504                 ecsa_ie->chan_switch_count = bss->param.chanswitch.chan_switch_count;
505                 ecsa_ie->new_channel_num   = bss->param.chanswitch.new_channel_num;
506                 ecsa_ie->new_oper_class    = bss->param.chanswitch.new_oper_class;
507                 cmd->size += sizeof(IEEEtypes_ExtChanSwitchAnn_t);
508             }
509             else
510             {
511                 tlv_chan_switch->header.len =
512                     wlan_cpu_to_le16(sizeof(MrvlIEtypes_action_chan_switch_t) - sizeof(MrvlIEtypesHeader_t) +
513                                      sizeof(IEEEtypes_ChanSwitchAnn_t));
514                 csa_ie                    = (IEEEtypes_ChanSwitchAnn_t *)tlv_chan_switch->ie_buf;
515                 csa_ie->element_id        = CHANNEL_SWITCH_ANN;
516                 csa_ie->len               = sizeof(IEEEtypes_ChanSwitchAnn_t) - sizeof(IEEEtypes_Header_t);
517                 csa_ie->chan_switch_mode  = bss->param.chanswitch.chan_switch_mode;
518                 csa_ie->chan_switch_count = bss->param.chanswitch.chan_switch_count;
519                 csa_ie->new_channel_num   = bss->param.chanswitch.new_channel_num;
520                 cmd->size += sizeof(IEEEtypes_ChanSwitchAnn_t);
521             }
522             cmd->size = wlan_cpu_to_le16(cmd->size);
523         }
524 #endif
525         else
526         { /* Do Nothing */
527         }
528     }
529     else
530     {
531         goto done;
532     }
533 done:
534     LEAVE();
535     return ret;
536 }
537 
538 /**
539  *  @brief This function prepares command of snmp_mib
540  *
541  *  @param pmpriv		A pointer to mlan_private structure
542  *  @param cmd	   		A pointer to HostCmd_DS_COMMAND structure
543  *  @param cmd_action   the action: GET or SET
544  *  @param cmd_oid      Cmd oid: treated as sub command
545  *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
546  *  @param pdata_buf    A pointer to information buffer
547  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
548  */
wlan_uap_cmd_snmp_mib(pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_u16 cmd_action,IN t_u32 cmd_oid,IN pmlan_ioctl_req pioctl_buf,IN t_void * pdata_buf)549 static mlan_status wlan_uap_cmd_snmp_mib(pmlan_private pmpriv,
550                                          IN HostCmd_DS_COMMAND *cmd,
551                                          IN t_u16 cmd_action,
552                                          IN t_u32 cmd_oid,
553                                          IN pmlan_ioctl_req pioctl_buf,
554                                          IN t_void *pdata_buf)
555 {
556     HostCmd_DS_802_11_SNMP_MIB *psnmp_mib = &cmd->params.smib;
557     mlan_status ret                       = MLAN_STATUS_SUCCESS;
558     t_u8 *psnmp_oid                       = MNULL;
559 #if (CONFIG_WIFI_FRAG_THRESHOLD) || (CONFIG_WIFI_RTS_THRESHOLD)
560     t_u32 ul_temp;
561 #endif
562     t_u8 i;
563 
564     t_u8 snmp_oids[] = {
565         (t_u8)tkip_mic_failures,
566         (t_u8)ccmp_decrypt_errors,
567         (t_u8)wep_undecryptable_count,
568         (t_u8)wep_icv_error_count,
569         (t_u8)decrypt_failure_count,
570         (t_u8)dot11_mcast_tx_count,
571         (t_u8)dot11_failed_count,
572         (t_u8)dot11_retry_count,
573         (t_u8)dot11_multi_retry_count,
574         (t_u8)dot11_frame_dup_count,
575         (t_u8)dot11_rts_success_count,
576         (t_u8)dot11_rts_failure_count,
577         (t_u8)dot11_ack_failure_count,
578         (t_u8)dot11_rx_fragment_count,
579         (t_u8)dot11_mcast_rx_frame_count,
580         (t_u8)dot11_fcs_error_count,
581         (t_u8)dot11_tx_frame_count,
582         (t_u8)dot11_rsna_tkip_cm_invoked,
583         (t_u8)dot11_rsna_4way_hshk_failures,
584     };
585 
586     ENTER();
587 
588     if (cmd_action == HostCmd_ACT_GEN_GET)
589     {
590         cmd->command          = wlan_cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
591         psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_GET);
592         if (cmd_oid == (t_u32)StopDeauth_i)
593         {
594             psnmp_mib->oid      = wlan_cpu_to_le16((t_u16)StopDeauth_i);
595             psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u8));
596             cmd->size           = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_SNMP_MIB) + S_DS_GEN);
597         }
598         else
599         {
600             cmd->size = wlan_cpu_to_le16(sizeof(t_u16) + S_DS_GEN + sizeof(snmp_oids) * sizeof(MrvlIEtypes_snmp_oid_t));
601             psnmp_oid = (t_u8 *)&psnmp_mib->oid;
602             for (i = 0; i < sizeof(snmp_oids); i++)
603             {
604                 /* SNMP OID header type */
605                 // coverity[overrun-local:SUPPRESS]
606                 *(t_u16 *)(void *)psnmp_oid = wlan_cpu_to_le16(snmp_oids[i]);
607                 psnmp_oid += sizeof(t_u16);
608                 /* SNMP OID header length */
609                 *(t_u16 *)(void *)psnmp_oid = wlan_cpu_to_le16(sizeof(t_u32));
610                 psnmp_oid += sizeof(t_u16) + sizeof(t_u32);
611             }
612         }
613     }
614     else
615     { /* cmd_action == ACT_SET */
616         cmd->command          = wlan_cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
617         cmd->size             = sizeof(HostCmd_DS_802_11_SNMP_MIB) - 1U + S_DS_GEN;
618         psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
619 
620         switch (cmd_oid)
621         {
622             case Dot11D_i:
623             case Dot11H_i:
624                 psnmp_mib->oid      = wlan_cpu_to_le16((t_u16)cmd_oid);
625                 psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
626                 // ul_temp = *(t_u32 *) pdata_buf;
627                 //*((t_u16 *) (psnmp_mib->value)) = wlan_cpu_to_le16((t_u16) ul_temp);
628                 cmd->size += (t_u16)sizeof(t_u16);
629                 break;
630             case StopDeauth_i:
631                 psnmp_mib->oid      = wlan_cpu_to_le16((t_u16)cmd_oid);
632                 psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u8));
633                 psnmp_mib->value[0] = *((t_u8 *)pdata_buf);
634                 cmd->size += (t_u16)sizeof(t_u8);
635                 break;
636 #if CONFIG_WIFI_FRAG_THRESHOLD
637             case FragThresh_i:
638                 psnmp_mib->oid                 = wlan_cpu_to_le16((t_u16)FragThresh_i);
639                 psnmp_mib->buf_size            = wlan_cpu_to_le16(sizeof(t_u16));
640                 ul_temp                        = *((t_u32 *)pdata_buf);
641                 *((t_u16 *)(psnmp_mib->value)) = wlan_cpu_to_le16((t_u16)ul_temp);
642                 cmd->size += sizeof(t_u16);
643                 break;
644 #endif
645 #if CONFIG_WIFI_RTS_THRESHOLD
646             case RtsThresh_i:
647                 psnmp_mib->oid                 = wlan_cpu_to_le16((t_u16)RtsThresh_i);
648                 psnmp_mib->buf_size            = wlan_cpu_to_le16(sizeof(t_u16));
649                 ul_temp                        = *((t_u32 *)pdata_buf);
650                 *((t_u16 *)(psnmp_mib->value)) = wlan_cpu_to_le16((t_u16)ul_temp);
651                 cmd->size += sizeof(t_u16);
652                 break;
653 #endif
654             default:
655                 PRINTM(MERROR, "Unsupported OID.\n");
656                 ret = MLAN_STATUS_FAILURE;
657                 break;
658         }
659         cmd->size = wlan_cpu_to_le16(cmd->size);
660     }
661 
662     LEAVE();
663     return ret;
664 }
665 
666 /**
667  *  @brief This function prepares command of deauth station
668  *
669  *  @param pmpriv		A pointer to mlan_private structure
670  *  @param cmd	   		A pointer to HostCmd_DS_COMMAND structure
671  *  @param pdata_buf    A pointer to data buffer
672  *  @return         MLAN_STATUS_SUCCESS
673  */
wlan_uap_cmd_sta_deauth(pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_void * pdata_buf)674 static mlan_status wlan_uap_cmd_sta_deauth(pmlan_private pmpriv, IN HostCmd_DS_COMMAND *cmd, IN t_void *pdata_buf)
675 {
676     HostCmd_DS_STA_DEAUTH *pcmd_sta_deauth = (HostCmd_DS_STA_DEAUTH *)&cmd->params.sta_deauth;
677     mlan_deauth_param *deauth              = (mlan_deauth_param *)pdata_buf;
678 
679     ENTER();
680     cmd->command = wlan_cpu_to_le16(HOST_CMD_APCMD_STA_DEAUTH);
681     cmd->size    = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_STA_DEAUTH));
682     (void)__memcpy(pmpriv->adapter, pcmd_sta_deauth->mac, deauth->mac_addr, MLAN_MAC_ADDR_LENGTH);
683     pcmd_sta_deauth->reason = wlan_cpu_to_le16(deauth->reason_code);
684     LEAVE();
685     return MLAN_STATUS_SUCCESS;
686 }
687 
688 #if defined(WAPI_AP) || defined(HOST_AUTHENTICATOR) || (CONFIG_WPA_SUPP_AP)
689 /**
690  *  @brief This function prepares command of key material
691  *
692  *  @param pmpriv       A pointer to mlan_private structure
693  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
694  *  @param cmd_action   The action: GET or SET
695  *  @param cmd_oid      OID: ENABLE or DISABLE
696  *  @param pdata_buf    A pointer to data buffer
697  *  @return             MLAN_STATUS_SUCCESS
698  */
wlan_uap_cmd_key_material(pmlan_private pmpriv,HostCmd_DS_COMMAND * cmd,t_u16 cmd_action,t_u16 cmd_oid,t_void * pdata_buf)699 static mlan_status wlan_uap_cmd_key_material(
700     pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, t_u16 cmd_action, t_u16 cmd_oid, t_void *pdata_buf)
701 {
702     HostCmd_DS_802_11_KEY_MATERIAL *pkey_material = &cmd->params.key_material;
703     mlan_ds_encrypt_key *pkey                     = (mlan_ds_encrypt_key *)pdata_buf;
704     mlan_status ret                               = MLAN_STATUS_SUCCESS;
705 #ifdef WAPI_AP
706     sta_node *sta_ptr = MNULL;
707 #endif
708 
709     ENTER();
710     if (!pkey)
711     {
712         ret = MLAN_STATUS_FAILURE;
713         goto done;
714     }
715     cmd->command          = wlan_cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL);
716     pkey_material->action = wlan_cpu_to_le16(cmd_action);
717     if (cmd_action == HostCmd_ACT_GEN_GET)
718     {
719         cmd->size = wlan_cpu_to_le16(sizeof(pkey_material->action) + S_DS_GEN);
720         goto done;
721     }
722     memset(&pkey_material->key_param_set, 0, sizeof(MrvlIEtype_KeyParamSetV2_t));
723     if (pkey->key_flags & KEY_FLAG_REMOVE_KEY)
724     {
725         pkey_material->action                 = wlan_cpu_to_le16(HostCmd_ACT_GEN_REMOVE);
726         pkey_material->key_param_set.type     = wlan_cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
727         pkey_material->key_param_set.length   = wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN);
728         pkey_material->key_param_set.key_idx  = pkey->key_index & KEY_INDEX_MASK;
729         pkey_material->key_param_set.key_info = wlan_cpu_to_le16(KEY_INFO_MCAST_KEY | KEY_INFO_UCAST_KEY);
730         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.mac_addr, pkey->mac_addr, MLAN_MAC_ADDR_LENGTH,
731                    MLAN_MAC_ADDR_LENGTH);
732         cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN + KEY_PARAMS_FIXED_LEN +
733                                      sizeof(pkey_material->action));
734         wifi_d("Remove Key");
735         goto done;
736     }
737     pkey_material->action                 = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
738     pkey_material->key_param_set.key_idx  = pkey->key_index & KEY_INDEX_MASK;
739     pkey_material->key_param_set.type     = wlan_cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
740     pkey_material->key_param_set.key_info = KEY_INFO_ENABLE_KEY;
741     memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.mac_addr, pkey->mac_addr, MLAN_MAC_ADDR_LENGTH,
742                MLAN_MAC_ADDR_LENGTH);
743     if (pkey->key_len <= MAX_WEP_KEY_SIZE)
744     {
745         pkey_material->key_param_set.length   = wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(wep_param_t));
746         pkey_material->key_param_set.key_type = KEY_TYPE_ID_WEP;
747         pkey_material->key_param_set.key_info |= KEY_INFO_MCAST_KEY | KEY_INFO_UCAST_KEY;
748         if (pkey_material->key_param_set.key_idx == (pmpriv->wep_key_curr_index & KEY_INDEX_MASK))
749             pkey_material->key_param_set.key_info |= KEY_INFO_DEFAULT_KEY;
750         pkey_material->key_param_set.key_info               = wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
751         pkey_material->key_param_set.key_params.wep.key_len = wlan_cpu_to_le16(pkey->key_len);
752         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.wep.key, pkey->key_material, pkey->key_len,
753                    MAX_WEP_KEY_SIZE);
754         cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN + KEY_PARAMS_FIXED_LEN +
755                                      sizeof(wep_param_t) + sizeof(pkey_material->action));
756         wifi_d("Set WEP Key");
757         goto done;
758     }
759     if (pkey->key_flags & KEY_FLAG_GROUP_KEY)
760         pkey_material->key_param_set.key_info |= KEY_INFO_MCAST_KEY;
761     else
762         pkey_material->key_param_set.key_info |= KEY_INFO_UCAST_KEY;
763 #ifdef ENABLE_802_11W
764     if (pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK)
765         pkey_material->key_param_set.key_info |= KEY_INFO_CMAC_AES_KEY;
766 #endif
767     if (pkey->key_flags & KEY_FLAG_SET_TX_KEY)
768         pkey_material->key_param_set.key_info |= KEY_INFO_TX_KEY | KEY_INFO_RX_KEY;
769     else
770         pkey_material->key_param_set.key_info |= KEY_INFO_TX_KEY;
771 #ifdef WAPI_AP
772     if (pkey->is_wapi_key)
773     {
774         pkey_material->key_param_set.key_type = KEY_TYPE_ID_WAPI;
775         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.wapi.pn, pkey->pn, PN_SIZE, PN_SIZE);
776         pkey_material->key_param_set.key_params.wapi.key_len = wlan_cpu_to_le16(MIN(WAPI_KEY_SIZE, pkey->key_len));
777         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.wapi.key, pkey->key_material, pkey->key_len,
778                    WAPI_KEY_SIZE);
779         if (!pmpriv->sec_info.wapi_key_on)
780             pkey_material->key_param_set.key_info |= KEY_INFO_DEFAULT_KEY;
781         if (pkey->key_flags & KEY_FLAG_GROUP_KEY)
782         {
783             pmpriv->sec_info.wapi_key_on = MTRUE;
784         }
785         else
786         {
787             /* WAPI pairwise key: unicast */
788             sta_ptr = wlan_add_station_entry(pmpriv, pkey->mac_addr);
789             if (sta_ptr)
790             {
791                 wifi_d("station: wapi_key_on");
792                 sta_ptr->wapi_key_on = MTRUE;
793             }
794         }
795         pkey_material->key_param_set.key_info = wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
796         pkey_material->key_param_set.length   = wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(wapi_param));
797         cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN + KEY_PARAMS_FIXED_LEN +
798                                      sizeof(wapi_param) + sizeof(pkey_material->action));
799         wifi_d("Set WAPI Key");
800         goto done;
801     }
802 #endif
803     pkey_material->key_param_set.key_info |= KEY_INFO_DEFAULT_KEY;
804     pkey_material->key_param_set.key_info = wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
805     if (pkey->key_flags & KEY_FLAG_GCMP || pkey->key_flags & KEY_FLAG_GCMP_256)
806     {
807         if (pkey->key_flags & (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
808         {
809             memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.gcmp.pn, pkey->pn, SEQ_MAX_SIZE,
810                        WPA_PN_SIZE);
811         }
812         if (pkey->key_flags & KEY_FLAG_GCMP)
813             pkey_material->key_param_set.key_type = KEY_TYPE_ID_GCMP;
814         else
815             pkey_material->key_param_set.key_type = KEY_TYPE_ID_GCMP_256;
816         pkey_material->key_param_set.key_params.gcmp.key_len = wlan_cpu_to_le16(pkey->key_len);
817         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.gcmp.key, pkey->key_material, pkey->key_len,
818                    WPA_GCMP_KEY_LEN);
819         pkey_material->key_param_set.length = wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(gcmp_param));
820         cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN + KEY_PARAMS_FIXED_LEN +
821                                      sizeof(gcmp_param) + sizeof(pkey_material->action));
822         PRINTM(MCMND, "Set GCMP Key\n");
823         goto done;
824     }
825     if (pkey->key_flags & KEY_FLAG_CCMP_256)
826     {
827         if (pkey->key_flags & (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
828         {
829             memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.ccmp256.pn, pkey->pn, SEQ_MAX_SIZE,
830                        WPA_PN_SIZE);
831         }
832         pkey_material->key_param_set.key_type                   = KEY_TYPE_ID_CCMP_256;
833         pkey_material->key_param_set.key_params.ccmp256.key_len = wlan_cpu_to_le16(pkey->key_len);
834         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.ccmp256.key, pkey->key_material,
835                    pkey->key_len, WPA_CCMP_256_KEY_LEN);
836         pkey_material->key_param_set.length = wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(ccmp_256_param));
837         cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN + KEY_PARAMS_FIXED_LEN +
838                                      sizeof(ccmp_256_param) + sizeof(pkey_material->action));
839         PRINTM(MCMND, "Set CCMP256 Key\n");
840         goto done;
841     }
842 #ifdef ENABLE_802_11W
843     if (pkey->key_len == WPA_AES_KEY_LEN && !(pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK))
844     {
845 #else
846     if (pkey->key_len == WPA_AES_KEY_LEN)
847     {
848 #endif
849         if (pkey->key_flags & (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
850             memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.aes.pn, pkey->pn, SEQ_MAX_SIZE,
851                        WPA_PN_SIZE);
852         pkey_material->key_param_set.key_type               = KEY_TYPE_ID_AES;
853         pkey_material->key_param_set.key_params.aes.key_len = wlan_cpu_to_le16(pkey->key_len);
854         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.aes.key, pkey->key_material, pkey->key_len,
855                    WPA_AES_KEY_LEN);
856         pkey_material->key_param_set.length = wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(aes_param));
857         cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN + KEY_PARAMS_FIXED_LEN + sizeof(aes_param) +
858                                      sizeof(pkey_material->action));
859         wifi_d("Set AES Key");
860         goto done;
861     }
862 #ifdef ENABLE_802_11W
863     if (pkey->key_len == WPA_IGTK_KEY_LEN && (pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK))
864     {
865         if (pkey->key_flags & (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
866             memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.cmac_aes.ipn, pkey->pn, SEQ_MAX_SIZE,
867                        IGTK_PN_SIZE);
868         pkey_material->key_param_set.key_info &= ~(wlan_cpu_to_le16(KEY_INFO_MCAST_KEY));
869         pkey_material->key_param_set.key_info |= wlan_cpu_to_le16(KEY_INFO_AES_MCAST_IGTK);
870         if (pkey->key_flags & KEY_FLAG_GMAC_128)
871             pkey_material->key_param_set.key_type = KEY_TYPE_ID_BIP_GMAC_128;
872         else
873             pkey_material->key_param_set.key_type = KEY_TYPE_ID_AES_CMAC;
874         pkey_material->key_param_set.key_params.cmac_aes.key_len = wlan_cpu_to_le16(pkey->key_len);
875         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.cmac_aes.key, pkey->key_material,
876                    pkey->key_len, CMAC_AES_KEY_LEN);
877         pkey_material->key_param_set.length = wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(cmac_aes_param));
878         cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN + KEY_PARAMS_FIXED_LEN +
879                                      sizeof(cmac_aes_param) + sizeof(pkey_material->action));
880         if (pkey->key_flags & KEY_FLAG_GMAC_128)
881             PRINTM(MCMND, "Set AES 128 GMAC Key\n");
882         else
883             PRINTM(MCMND, "Set CMAC AES Key\n");
884         goto done;
885     }
886     if (pkey->key_len == WPA_IGTK_256_KEY_LEN && (pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK))
887     {
888         if (pkey->key_flags & (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
889             memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.gmac_aes.ipn, pkey->pn, SEQ_MAX_SIZE,
890                        IGTK_PN_SIZE);
891         pkey_material->key_param_set.key_info &= ~(wlan_cpu_to_le16(KEY_INFO_MCAST_KEY));
892         pkey_material->key_param_set.key_info |= wlan_cpu_to_le16(KEY_INFO_AES_MCAST_IGTK);
893         pkey_material->key_param_set.key_type                    = KEY_TYPE_ID_BIP_GMAC_256;
894         pkey_material->key_param_set.key_params.gmac_aes.key_len = wlan_cpu_to_le16(pkey->key_len);
895         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.gmac_aes.key, pkey->key_material,
896                    pkey->key_len, WPA_IGTK_256_KEY_LEN);
897         pkey_material->key_param_set.length = wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(gmac_aes_256_param));
898         cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN + KEY_PARAMS_FIXED_LEN +
899                                      sizeof(gmac_aes_256_param) + sizeof(pkey_material->action));
900         PRINTM(MCMND, "Set AES 256 GMAC Key\n");
901         goto done;
902     }
903 #endif
904     if (pkey->key_len == WPA_TKIP_KEY_LEN)
905     {
906         if (pkey->key_flags & (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
907             memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.tkip.pn, pkey->pn, SEQ_MAX_SIZE,
908                        WPA_PN_SIZE);
909         pkey_material->key_param_set.key_type                = KEY_TYPE_ID_TKIP;
910         pkey_material->key_param_set.key_params.tkip.key_len = wlan_cpu_to_le16(pkey->key_len);
911         memcpy_ext(pmpriv->adapter, pkey_material->key_param_set.key_params.tkip.key, pkey->key_material, pkey->key_len,
912                    WPA_TKIP_KEY_LEN);
913         pkey_material->key_param_set.length = wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(tkip_param));
914         cmd->size = wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN + KEY_PARAMS_FIXED_LEN +
915                                      sizeof(tkip_param) + sizeof(pkey_material->action));
916         PRINTM(MCMND, "Set TKIP Key\n");
917     }
918 done:
919     LEAVE();
920     return ret;
921 }
922 
923 #endif /* WAPI_AP || HOST_AUTHENTICATOR || CONFIG_WPA_SUPP_AP */
924 
925 /**
926  *  @brief This function will search for the specific ie
927  *
928  *
929  *  @param priv    A pointer to mlan_private
930  *  @param pevent  A pointer to event buf
931  *  @param sta_ptr A pointer to sta_node
932  *
933  *  @return	       N/A
934  */
935 void wlan_check_sta_capability(pmlan_private priv, pmlan_buffer pevent, sta_node *sta_ptr)
936 {
937     t_u16 tlv_type, tlv_len;
938     t_u16 frame_control, frame_sub_type = 0;
939     t_u8 *assoc_req_ie = MNULL;
940     t_u8 ie_len = 0, assoc_ie_len = 0;
941     IEEEtypes_HTCap_t *pht_cap = MNULL;
942     int tlv_buf_left           = pevent->data_len - ASSOC_EVENT_FIX_SIZE;
943     MrvlIEtypesHeader_t *tlv   = (MrvlIEtypesHeader_t *)(pevent->pbuf + pevent->data_offset + ASSOC_EVENT_FIX_SIZE);
944     MrvlIETypes_MgmtFrameSet_t *mgmt_tlv = MNULL;
945 
946     ENTER();
947     while (tlv_buf_left >= (int)sizeof(MrvlIEtypesHeader_t))
948     {
949         tlv_type = wlan_le16_to_cpu(tlv->type);
950         tlv_len  = wlan_le16_to_cpu(tlv->len);
951         if ((sizeof(MrvlIEtypesHeader_t) + tlv_len) > (unsigned int)tlv_buf_left)
952         {
953             wifi_d("wrong tlv: tlvLen=%d, tlvBufLeft=%d", tlv_len, tlv_buf_left);
954             break;
955         }
956         if (tlv_type == TLV_TYPE_UAP_MGMT_FRAME)
957         {
958             mgmt_tlv = (MrvlIETypes_MgmtFrameSet_t *)tlv;
959             (void)__memcpy(priv->adapter, &frame_control, (t_u8 *)&(mgmt_tlv->frame_control), sizeof(frame_control));
960             frame_sub_type = IEEE80211_GET_FC_MGMT_FRAME_SUBTYPE(frame_control);
961             if ((mgmt_tlv->frame_control.type == 0) &&
962                 ((frame_sub_type == SUBTYPE_ASSOC_REQUEST) || (frame_sub_type == SUBTYPE_REASSOC_REQUEST)))
963             {
964                 if (frame_sub_type == SUBTYPE_ASSOC_REQUEST)
965                     assoc_ie_len = sizeof(IEEEtypes_AssocRqst_t);
966                 else if (frame_sub_type == SUBTYPE_REASSOC_REQUEST)
967                     assoc_ie_len = sizeof(IEEEtypes_ReAssocRqst_t);
968 
969                 ie_len       = tlv_len - sizeof(IEEEtypes_FrameCtl_t) - assoc_ie_len;
970                 assoc_req_ie = (t_u8 *)tlv + sizeof(MrvlIETypes_MgmtFrameSet_t) + assoc_ie_len;
971                 pht_cap      = (IEEEtypes_HTCap_t *)wlan_get_specific_ie(priv, assoc_req_ie, ie_len, HT_CAPABILITY, 0);
972                 if (pht_cap)
973                 {
974                     wifi_d("STA supports 11n");
975                     sta_ptr->is_11n_enabled = MTRUE;
976                     if (GETHT_MAXAMSDU(pht_cap->ht_cap.ht_cap_info))
977                         sta_ptr->max_amsdu = MLAN_TX_DATA_BUF_SIZE_8K;
978                     else
979                         sta_ptr->max_amsdu = MLAN_TX_DATA_BUF_SIZE_4K;
980                 }
981                 else
982                 {
983                     wifi_d("STA doesn't support 11n");
984                 }
985                 break;
986             }
987         }
988         tlv_buf_left -= (sizeof(MrvlIEtypesHeader_t) + tlv_len);
989         tlv = (MrvlIEtypesHeader_t *)((t_u8 *)tlv + tlv_len + sizeof(MrvlIEtypesHeader_t));
990     }
991     LEAVE();
992 
993     return;
994 }
995 
996 #if UAP_HOST_MLME
997 /**
998  *  @brief	Check 11B support Rates
999  *
1000  *
1001  *  @param pmadapter	Private mlan adapter structure
1002  *
1003  *  @return MTRUE/MFALSE
1004  *
1005  */
1006 static t_u8 wlan_check_11B_support_rates(MrvlIEtypes_RatesParamSet_t *prates_tlv)
1007 {
1008     int i;
1009     t_u8 rate;
1010     t_u8 ret = MTRUE;
1011     for (i = 0; i < prates_tlv->header.len; i++)
1012     {
1013         rate = prates_tlv->rates[i] & 0x7f;
1014         if ((rate != 0x02) && (rate != 0x04) && (rate != 0x0b) && (rate != 0x16))
1015         {
1016             ret = MFALSE;
1017             break;
1018         }
1019     }
1020     return ret;
1021 }
1022 
1023 /**
1024  *  @brief This function prepares command of sys_config
1025  *
1026  *  @param pmpriv       A pointer to mlan_private structure
1027  *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
1028  *  @param cmd_action   cmd action
1029  *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
1030  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1031  */
1032 static mlan_status wlan_uap_cmd_add_station(pmlan_private pmpriv,
1033                                             HostCmd_DS_COMMAND *cmd,
1034                                             t_u16 cmd_action,
1035                                             pmlan_ioctl_req pioctl_buf)
1036 {
1037     mlan_ds_bss *bss                = MNULL;
1038     HostCmd_DS_ADD_STATION *new_sta = (HostCmd_DS_ADD_STATION *)&cmd->params.sta_info;
1039     sta_node *sta_ptr               = MNULL;
1040     t_u16 tlv_buf_left;
1041     t_u8 *pos        = MNULL;
1042     t_u8 *tlv_buf    = MNULL;
1043     t_u16 travel_len = 0;
1044     MrvlIEtypesHeader_t *tlv;
1045     t_u16 tlv_len = 0;
1046     t_u8 b_only   = MFALSE;
1047     MrvlIETypes_HTCap_t *phtcap;
1048 #if CONFIG_11AC
1049     MrvlIETypes_VHTCap_t *pvhtcap;
1050 #endif
1051 #if CONFIG_11AX
1052     MrvlIEtypes_Extension_t *pext_tlv = MNULL;
1053 #endif
1054     MrvlIEtypes_StaFlag_t *pstaflag;
1055     int i;
1056 
1057     ENTER();
1058 
1059     if (!pioctl_buf)
1060     {
1061         LEAVE();
1062         return MLAN_STATUS_FAILURE;
1063     }
1064     (void)__memset(pmpriv->adapter, new_sta, 0x00, sizeof(HostCmd_DS_ADD_STATION));
1065     bss = (mlan_ds_bss *)pioctl_buf->pbuf;
1066 
1067     cmd->command    = wlan_cpu_to_le16(HostCmd_CMD_ADD_NEW_STATION);
1068     new_sta->action = wlan_cpu_to_le16(cmd_action);
1069     cmd->size       = sizeof(HostCmd_DS_ADD_STATION) + S_DS_GEN;
1070     if (cmd_action == HostCmd_ACT_ADD_STA)
1071     {
1072         sta_ptr = wlan_get_station_entry(pmpriv, bss->param.sta_info.peer_mac);
1073         if (!sta_ptr)
1074             sta_ptr = wlan_add_station_entry(pmpriv, bss->param.sta_info.peer_mac);
1075     }
1076     else
1077     {
1078         sta_ptr = wlan_add_station_entry(pmpriv, bss->param.sta_info.peer_mac);
1079     }
1080     if (!sta_ptr)
1081     {
1082         LEAVE();
1083         return MLAN_STATUS_FAILURE;
1084     }
1085 #ifdef EASYMESH
1086     /* Save station aid for multi-ap */
1087     sta_ptr->aid = bss->param.sta_info.aid;
1088 #endif
1089     (void)__memcpy(NULL, new_sta->peer_mac, bss->param.sta_info.peer_mac, MLAN_MAC_ADDR_LENGTH);
1090     if (cmd_action != HostCmd_ACT_ADD_STA)
1091         goto done;
1092     new_sta->aid             = wlan_cpu_to_le16(bss->param.sta_info.aid);
1093     new_sta->listen_interval = wlan_cpu_to_le32(bss->param.sta_info.listen_interval);
1094     if (bss->param.sta_info.cap_info)
1095         new_sta->cap_info = wlan_cpu_to_le16(bss->param.sta_info.cap_info);
1096     else
1097         new_sta->cap_info = wlan_cpu_to_le16(sta_ptr->capability);
1098     tlv_buf_left = bss->param.sta_info.tlv_len;
1099     pos          = new_sta->tlv;
1100     tlv_buf      = bss->param.sta_info.tlv;
1101     tlv          = (MrvlIEtypesHeader_t *)tlv_buf;
1102     if (bss->param.sta_info.sta_flags & STA_FLAG_WME)
1103     {
1104         wifi_d("STA flags supports wmm");
1105         sta_ptr->is_wmm_enabled = MTRUE;
1106     }
1107     // append sta_flag_flags.
1108     pstaflag              = (MrvlIEtypes_StaFlag_t *)pos;
1109     pstaflag->header.type = wlan_cpu_to_le16(TLV_TYPE_UAP_STA_FLAGS);
1110     pstaflag->header.len  = wlan_cpu_to_le16(sizeof(t_u32));
1111     pstaflag->sta_flags   = wlan_cpu_to_le32(bss->param.sta_info.sta_flags);
1112     pos += sizeof(MrvlIEtypes_StaFlag_t);
1113     cmd->size += sizeof(MrvlIEtypes_StaFlag_t);
1114 
1115     while (tlv_buf_left >= sizeof(MrvlIEtypesHeader_t))
1116     {
1117         if (tlv_buf_left < (sizeof(MrvlIEtypesHeader_t) + tlv->len))
1118             break;
1119         switch (tlv->type)
1120         {
1121             case EXT_CAPABILITY:
1122                 break;
1123             case SUPPORTED_RATES:
1124                 b_only = wlan_check_11B_support_rates((MrvlIEtypes_RatesParamSet_t *)tlv);
1125                 break;
1126             case QOS_INFO:
1127                 wifi_d("STA supports wmm");
1128                 sta_ptr->is_wmm_enabled = MTRUE;
1129                 break;
1130             case HT_CAPABILITY:
1131                 wifi_d("STA supports 11n");
1132                 sta_ptr->is_11n_enabled = MTRUE;
1133                 phtcap                  = (MrvlIETypes_HTCap_t *)tlv;
1134                 if (sta_ptr->HTcap.ieee_hdr.element_id == HT_CAPABILITY)
1135                 {
1136                     if (GETHT_40MHZ_INTOLARANT(sta_ptr->HTcap.ht_cap.ht_cap_info))
1137                     {
1138                         wifi_d("SETHT_40MHZ_INTOLARANT");
1139                         SETHT_40MHZ_INTOLARANT(phtcap->ht_cap.ht_cap_info);
1140                     }
1141                 }
1142                 if (GETHT_MAXAMSDU(phtcap->ht_cap.ht_cap_info))
1143                     sta_ptr->max_amsdu = MLAN_TX_DATA_BUF_SIZE_8K;
1144                 else
1145                     sta_ptr->max_amsdu = MLAN_TX_DATA_BUF_SIZE_4K;
1146                 break;
1147 #if CONFIG_11AC
1148             case VHT_CAPABILITY:
1149                 wifi_d("STA supports 11ac");
1150                 sta_ptr->is_11ac_enabled = MTRUE;
1151                 pvhtcap                  = (MrvlIETypes_VHTCap_t *)tlv;
1152                 if (GET_VHTCAP_MAXMPDULEN(pvhtcap->vht_cap.vht_cap_info) == 2)
1153                     sta_ptr->max_amsdu = MLAN_TX_DATA_BUF_SIZE_12K;
1154                 else if (GET_VHTCAP_MAXMPDULEN(pvhtcap->vht_cap.vht_cap_info) == 1)
1155                     sta_ptr->max_amsdu = MLAN_TX_DATA_BUF_SIZE_8K;
1156                 else
1157                     sta_ptr->max_amsdu = MLAN_TX_DATA_BUF_SIZE_4K;
1158                 break;
1159             case OPER_MODE_NTF:
1160                 break;
1161 #endif
1162 #if CONFIG_11AX
1163             case EXTENSION:
1164                 pext_tlv = (MrvlIEtypes_Extension_t *)tlv;
1165                 if (pext_tlv->ext_id == HE_CAPABILITY)
1166                 {
1167                     sta_ptr->is_11ax_enabled = MTRUE;
1168                     wifi_d("STA supports 11ax");
1169                 }
1170 #ifdef ENABLE_802_116E
1171                 else if (pext_tlv->ext_id == HE_6G_CAPABILITY)
1172                 {
1173                     MrvlIEtypes_He_6g_cap_t *phe_6g_cap = MNULL;
1174                     phe_6g_cap                          = (MrvlIEtypes_He_6g_cap_t *)tlv;
1175                     if (GET_6G_BAND_CAP_MAXMPDULEN(phe_6g_cap->capa) == 2)
1176                         pmpriv->max_amsdu = MLAN_TX_DATA_BUF_SIZE_12K;
1177                     else if (GET_6G_BAND_CAP_MAXMPDULEN(phe_6g_cap->capa) == 1)
1178                         pmpriv->max_amsdu = MLAN_TX_DATA_BUF_SIZE_8K;
1179                     else
1180                         pmpriv->max_amsdu = MLAN_TX_DATA_BUF_SIZE_4K;
1181                 }
1182 #endif
1183                 else
1184                 {
1185                     pext_tlv = MNULL;
1186                 }
1187                 break;
1188 #endif
1189             default:
1190                 break;
1191         }
1192         tlv->type = wlan_cpu_to_le16(tlv->type);
1193         tlv->len  = wlan_cpu_to_le16(tlv->len);
1194         tlv_len   = tlv->len;
1195         (void)__memcpy(NULL, pos, (t_u8 *)tlv, sizeof(MrvlIEtypesHeader_t) + tlv_len);
1196         pos += sizeof(MrvlIEtypesHeader_t) + tlv_len;
1197         tlv_buf += sizeof(MrvlIEtypesHeader_t) + tlv_len;
1198         tlv = (MrvlIEtypesHeader_t *)tlv_buf;
1199         travel_len += sizeof(MrvlIEtypesHeader_t) + tlv_len;
1200         tlv_buf_left -= sizeof(MrvlIEtypesHeader_t) + tlv_len;
1201     }
1202 #if CONFIG_11AX
1203     if (sta_ptr->is_11ax_enabled)
1204     {
1205         if (pext_tlv == MNULL)
1206         {
1207             tlv       = (MrvlIEtypesHeader_t *)pos;
1208             tlv->type = wlan_cpu_to_le16(EXTENSION);
1209             tlv->len  = wlan_cpu_to_le16(
1210                 MIN(sta_ptr->he_cap.ieee_hdr.len, sizeof(IEEEtypes_HECap_t) - sizeof(IEEEtypes_Header_t)));
1211 
1212             pos += sizeof(MrvlIEtypesHeader_t);
1213             (void)__memcpy(NULL, pos, (t_u8 *)&sta_ptr->he_cap.ext_id, tlv->len);
1214             travel_len += sizeof(MrvlIEtypesHeader_t) + tlv->len;
1215         }
1216     }
1217 #endif
1218 
1219     if (sta_ptr->is_11n_enabled)
1220     {
1221         if (pmpriv->uap_channel <= 14)
1222             sta_ptr->bandmode = BAND_GN;
1223 #if CONFIG_5GHz_SUPPORT
1224         else
1225             sta_ptr->bandmode = BAND_AN;
1226 #endif
1227     }
1228     else if (!b_only)
1229     {
1230         if (pmpriv->uap_channel <= 14)
1231             sta_ptr->bandmode = BAND_G;
1232 #if CONFIG_5GHz_SUPPORT
1233         else
1234             sta_ptr->bandmode = BAND_A;
1235 #endif
1236     }
1237     else
1238         sta_ptr->bandmode = BAND_B;
1239 #if CONFIG_11AC
1240     if (sta_ptr->is_11ac_enabled)
1241     {
1242         if (pmpriv->uap_channel <= 14)
1243             sta_ptr->bandmode = BAND_GAC;
1244         else
1245             sta_ptr->bandmode = BAND_AAC;
1246     }
1247 #endif
1248 #if CONFIG_11AX
1249     if (sta_ptr->is_11ax_enabled)
1250     {
1251         if (pmpriv->uap_channel <= 14)
1252             sta_ptr->bandmode = BAND_GAX;
1253         else
1254             sta_ptr->bandmode = BAND_AAX;
1255     }
1256 #endif
1257 
1258     for (i = 0; i < MAX_NUM_TID; i++)
1259     {
1260         if (sta_ptr->is_11n_enabled
1261 #if CONFIG_11AX
1262             || sta_ptr->is_11ax_enabled
1263 #endif
1264         )
1265             sta_ptr->ampdu_sta[i] = pmpriv->aggr_prio_tbl[i].ampdu_user;
1266         else
1267             sta_ptr->ampdu_sta[i] = BA_STREAM_NOT_ALLOWED;
1268     }
1269     (void)__memset(pmpriv->adapter, sta_ptr->rx_seq, 0xff, sizeof(sta_ptr->rx_seq));
1270 done:
1271     cmd->size += travel_len;
1272     cmd->size = wlan_cpu_to_le16(cmd->size);
1273     LEAVE();
1274     return MLAN_STATUS_SUCCESS;
1275 }
1276 #endif
1277 
1278 /**
1279  *  @brief This function prepares command of bss_start.
1280  *
1281  * @param pmpriv       A pointer to mlan_private structure
1282  * @param cmd          A pointer to HostCmd_DS_COMMAND structure
1283  *
1284  * @return             MLAN_STATUS_SUCCESS
1285  **/
1286 static mlan_status wlan_uap_cmd_bss_start(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd)
1287 {
1288 #if UAP_HOST_MLME
1289     MrvlIEtypes_HostMlme_t *tlv;
1290 #endif
1291     ENTER();
1292     cmd->command = wlan_cpu_to_le16(HOST_CMD_APCMD_BSS_START);
1293     cmd->size    = S_DS_GEN;
1294 #if UAP_HOST_MLME
1295     if (pmpriv->uap_host_based)
1296     {
1297         tlv              = (MrvlIEtypes_HostMlme_t *)((t_u8 *)cmd + cmd->size);
1298         tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_HOST_MLME);
1299         tlv->header.len  = wlan_cpu_to_le16(sizeof(tlv->host_mlme));
1300         tlv->host_mlme   = MTRUE;
1301         cmd->size += sizeof(MrvlIEtypes_HostMlme_t);
1302     }
1303 #endif
1304     cmd->size = wlan_cpu_to_le16(cmd->size);
1305     LEAVE();
1306     return MLAN_STATUS_SUCCESS;
1307 }
1308 
1309 /********************************************************
1310     Global Functions
1311 ********************************************************/
1312 /**
1313  *  @brief This function prepare the command before sending to firmware.
1314  *
1315  *  @param priv       A pointer to mlan_private structure
1316  *  @param cmd_no       Command number
1317  *  @param cmd_action   Command action: GET or SET
1318  *  @param cmd_oid      Cmd oid: treated as sub command
1319  *  @param pioctl_buf   A pointer to MLAN IOCTL Request buffer
1320  *  @param pdata_buf    A pointer to information buffer
1321  *  @param pcmd_buf      A pointer to cmd buf
1322  *
1323  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1324  */
1325 mlan_status wlan_ops_uap_prepare_cmd(IN t_void *priv,
1326                                      IN t_u16 cmd_no,
1327                                      IN t_u16 cmd_action,
1328                                      IN t_u32 cmd_oid,
1329                                      IN t_void *pioctl_buf,
1330                                      IN t_void *pdata_buf,
1331                                      IN t_void *pcmd_buf)
1332 {
1333     HostCmd_DS_COMMAND *cmd_ptr = (HostCmd_DS_COMMAND *)pcmd_buf;
1334     mlan_private *pmpriv        = (mlan_private *)priv;
1335     mlan_status ret             = MLAN_STATUS_SUCCESS;
1336     pmlan_ioctl_req pioctl_req  = (mlan_ioctl_req *)pioctl_buf;
1337 
1338     ENTER();
1339 
1340     /* Prepare command */
1341     switch (cmd_no)
1342     {
1343         case HostCMD_APCMD_ACS_SCAN:
1344         case HostCmd_CMD_SOFT_RESET:
1345         case HOST_CMD_APCMD_BSS_STOP:
1346         case HOST_CMD_APCMD_SYS_INFO:
1347         case HOST_CMD_APCMD_SYS_RESET:
1348         case HOST_CMD_APCMD_STA_LIST:
1349             cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
1350             cmd_ptr->size    = wlan_cpu_to_le16(S_DS_GEN);
1351             break;
1352         case HOST_CMD_APCMD_BSS_START:
1353             ret = wlan_uap_cmd_bss_start(pmpriv, cmd_ptr);
1354             break;
1355         case HOST_CMD_APCMD_SYS_CONFIGURE:
1356             ret = wlan_uap_cmd_sys_configure(pmpriv, cmd_ptr, cmd_action, (pmlan_ioctl_req)pioctl_buf, pdata_buf);
1357             break;
1358         case HostCmd_CMD_802_11_SNMP_MIB:
1359             ret = wlan_uap_cmd_snmp_mib(pmpriv, cmd_ptr, cmd_action, cmd_oid, (pmlan_ioctl_req)pioctl_buf, pdata_buf);
1360             break;
1361         case HostCmd_CMD_802_11D_DOMAIN_INFO:
1362             if (pmpriv->support_11d_APIs != NULL)
1363             {
1364                 ret = pmpriv->support_11d_APIs->wlan_cmd_802_11d_domain_info_p(pmpriv, cmd_ptr, cmd_action);
1365             }
1366             break;
1367         case HOST_CMD_APCMD_STA_DEAUTH:
1368             ret = wlan_uap_cmd_sta_deauth(pmpriv, cmd_ptr, pdata_buf);
1369             break;
1370 #if defined(WAPI_AP) || defined(HOST_AUTHENTICATOR) || (CONFIG_WPA_SUPP_AP)
1371         case HostCmd_CMD_802_11_KEY_MATERIAL:
1372             ret = wlan_uap_cmd_key_material(pmpriv, cmd_ptr, cmd_action, cmd_oid, pdata_buf);
1373             break;
1374 #endif
1375         case HostCmd_CMD_11N_CFG:
1376             ret = wlan_cmd_11n_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
1377             break;
1378         case HostCmd_CMD_11N_ADDBA_REQ:
1379             ret = wlan_cmd_11n_addba_req(pmpriv, cmd_ptr, pdata_buf);
1380             break;
1381         case HostCmd_CMD_11N_DELBA:
1382             ret = wlan_cmd_11n_delba(pmpriv, cmd_ptr, pdata_buf);
1383             break;
1384 #if UAP_HOST_MLME
1385         case HostCmd_CMD_ADD_NEW_STATION:
1386             ret = wlan_uap_cmd_add_station(pmpriv, cmd_ptr, cmd_action, (pmlan_ioctl_req)pioctl_buf);
1387             break;
1388 #endif
1389         case HostCmd_CMD_TX_RATE_CFG:
1390             ret = wlan_cmd_tx_rate_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf, (pmlan_ioctl_req)pioctl_buf);
1391             break;
1392         case HostCmd_CMD_802_11_TX_RATE_QUERY:
1393             cmd_ptr->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_TX_RATE_QUERY);
1394             cmd_ptr->size    = wlan_cpu_to_le16(sizeof(HostCmd_TX_RATE_QUERY) + S_DS_GEN);
1395             pmpriv->tx_rate  = 0;
1396             ret              = MLAN_STATUS_SUCCESS;
1397             break;
1398         case HostCmd_CMD_11AC_CFG:
1399             ret = wlan_cmd_11ac_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
1400             break;
1401 #if CONFIG_WIFI_CLOCKSYNC
1402         case HostCmd_GPIO_TSF_LATCH_PARAM_CONFIG:
1403             ret = wlan_cmd_gpio_tsf_latch(pmpriv, cmd_ptr, cmd_action, pioctl_buf, pdata_buf);
1404             break;
1405 #endif
1406 #if CONFIG_11AX
1407         case HostCmd_CMD_11AX_CMD:
1408             ret = (mlan_status)wlan_cmd_11ax_cmd(pmpriv, cmd_ptr, cmd_action, pdata_buf);
1409             break;
1410         case HostCmd_CMD_11AX_CFG:
1411             ret = (mlan_status)wlan_cmd_11ax_cfg(pmpriv, cmd_action, pdata_buf);
1412             break;
1413 #if CONFIG_11AX_TWT
1414         case HostCmd_CMD_TWT_CFG:
1415             ret = wlan_cmd_twt_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
1416             break;
1417 #endif /* CONFIG_11AX_TWT */
1418 #endif /* CONFIG_11AX */
1419         default:
1420             PRINTM(MERROR, "PREP_CMD: unknown command- %#x\n", cmd_no);
1421             if (pioctl_req != NULL)
1422             {
1423                 pioctl_req->status_code = MLAN_ERROR_CMD_INVALID;
1424             }
1425             ret = MLAN_STATUS_FAILURE;
1426             break;
1427     }
1428     LEAVE();
1429     return ret;
1430 }
1431