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