1 /** @file wifi-uap.c
2 *
3 * @brief This file provides UAP related APIs.
4 *
5 * Copyright 2008-2024 NXP
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 *
9 */
10
11 #include <mlan_api.h>
12
13 /* Additional WMSDK header files */
14 #include <wmerrno.h>
15 #include <osa.h>
16
17 #include <wifi.h>
18 #if defined(RW610)
19 #include "wifi-imu.h"
20 #else
21 #include "wifi-sdio.h"
22 #endif
23 #if CONFIG_WPA_SUPP_AP
24 #include "rtos_wpa_supp_if.h"
25 #endif
26 #include "wifi-internal.h"
27 #include "mlan_ieee.h"
28 #include <mlan_remap_mem_operations.h>
29
30 /* fixme: Some of the following options could be added to kconfig. While
31 adding the ranges in kconfig use the ones given as macros in
32 mlan_uap_cmdevent.c */
33 #ifdef RW610
34 #define UAP_BEACON_PERIOD 100U
35 #else
36 #define UAP_BEACON_PERIOD 200U
37 #endif
38 #define UAP_DTIM_PERIOD 1
39 #define MAX_RATES 14U
40
41 #if CONFIG_5GHz_SUPPORT
42 static uint8_t rates_5ghz[] = {0x8c, 0x98, 0xb0, 0x12, 0x24, 0x48, 0x60, 0x6c, 0x00};
43 #endif
44
45 static uint8_t rates_2ghz[] = {0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, 0x00};
46
47 static uint8_t rates_2ghz_b[] = {0x82, 0x84, 0x8b, 0x96, 0x00};
48
49 #if CONFIG_11AC
50 /**
51 * @brief initialize AP bss config
52 * @param pmpriv A pointer to mlan_private structure
53 * @param band BAND_5G/BAND_2GHZ
54 * @return 0 -- success, otherwise fail
55 */
wifi_check_11ac_capability(mlan_private * pmpriv,t_u8 band)56 static bool wifi_check_11ac_capability(mlan_private *pmpriv, t_u8 band)
57 {
58 mlan_adapter *pmadapter = pmpriv->adapter;
59 bool enable_11ac = MFALSE;
60
61 ENTER();
62 #if CONFIG_WIFI_CAPA
63 if (!pmadapter->usr_dot_11ac_enable)
64 {
65 return enable_11ac;
66 }
67 #endif
68 if ((band == BAND_CONFIG_5GHZ) && !(pmadapter->fw_bands & BAND_AAC))
69 {
70 PRINTM(MCMND, "FW don't support 5G AC\n");
71 LEAVE();
72 return enable_11ac;
73 }
74 if ((band == BAND_CONFIG_ACS_MODE || band == BAND_CONFIG_MANUAL) && !(pmadapter->fw_bands & BAND_GAC))
75 {
76 PRINTM(MCMND, "FW don't support 2G AC");
77 LEAVE();
78 return enable_11ac;
79 }
80 enable_11ac = MTRUE;
81
82 LEAVE();
83 return enable_11ac;
84 }
85
86 #define VHT_CAP_11AC_MASK 0x007fffff
87
88 /**
89 * @brief enable/disable 11AC
90 *
91 * @param pmpriv A pointer to mlan_private structure
92 * @param action MLAN_ACT_DISABLE or MLAN_ACT_ENABLE
93 * @param band band config
94 *
95 * @return 0--success, otherwise failure
96 */
wifi_uap_set_11ac_status(mlan_private * pmpriv,t_u8 action,t_u8 bandwidth,t_u8 channel)97 static int wifi_uap_set_11ac_status(mlan_private *pmpriv, t_u8 action, t_u8 bandwidth, t_u8 channel)
98 {
99 mlan_adapter *pmadapter = pmpriv->adapter;
100 int ret = 0;
101 mlan_ds_11ac_vht_cfg vht_cfg;
102
103 (void)memset(&vht_cfg, 0, sizeof(vht_cfg));
104
105 #if CONFIG_5GHz_SUPPORT
106 if (channel > MAX_CHANNELS_BG)
107 {
108 vht_cfg.band = BAND_SELECT_A;
109 }
110 else
111 {
112 vht_cfg.band = BAND_SELECT_BG;
113 }
114 #else
115 vht_cfg.band = BAND_SELECT_BG;
116 #endif
117 vht_cfg.txrx = MLAN_RADIO_TXRX;
118
119 vht_cfg.vht_cap_info = pmadapter->usr_dot_11ac_dev_cap_a;
120 if (action == MLAN_ACT_DISABLE)
121 {
122 vht_cfg.bwcfg = BW_FOLLOW_HTCAP;
123 vht_cfg.vht_cap_info &= ~VHT_CAP_11AC_MASK;
124 vht_cfg.vht_rx_mcs = vht_cfg.vht_tx_mcs = 0xffff;
125 vht_cfg.skip_usr_11ac_mcs_cfg = MTRUE;
126 }
127 else
128 {
129 if (BANDWIDTH_80MHZ == bandwidth)
130 {
131 vht_cfg.bwcfg = BW_FOLLOW_VHTCAP;
132 }
133 else
134 {
135 vht_cfg.bwcfg = BW_FOLLOW_HTCAP;
136 }
137
138 vht_cfg.vht_cap_info &= ~DEFALUT_11AC_CAP_BEAMFORMING_RESET_MASK;
139 #ifdef RW610
140 vht_cfg.vht_cap_info &= ~DEFALUT_11AC_CAP_SHORTGI_80MHZ_RESET_MASK;
141 #endif
142 vht_cfg.vht_tx_mcs = pmadapter->usr_dot_11ac_mcs_support >> 16;
143 vht_cfg.vht_rx_mcs = pmadapter->usr_dot_11ac_mcs_support & 0xffff;
144 vht_cfg.skip_usr_11ac_mcs_cfg = MTRUE;
145 }
146
147 if ((GET_VHTCAP_MAXMPDULEN(vht_cfg.vht_cap_info)) != 0U)
148 {
149 RESET_11ACMAXMPDULEN(vht_cfg.vht_cap_info);
150 }
151 else
152 {
153 /** Do Nothing */
154 }
155
156 wifi_d("Uap:11ac=%d vht_cap_info=0x%x, vht_tx_mcs=0x%x, vht_rx_mcs=0x%x\r\n", action, vht_cfg.vht_cap_info,
157 vht_cfg.vht_tx_mcs, vht_cfg.vht_rx_mcs);
158 ret = (int)wlan_11ac_ioctl_vhtcfg(pmpriv, (t_u8)MLAN_ACT_SET, &vht_cfg);
159 return ret;
160 }
161 #endif
162
163 #if CONFIG_11AX
164 /**
165 * @brief initialize AP bss config
166 * @param pmpriv A pointer to mlan_private structure
167 * @param band BAND_5G/BAND_2GHZ
168 * @return 0 -- success, otherwise fail
169 */
wifi_check_11ax_capability(mlan_private * pmpriv,t_u8 band)170 static t_u8 wifi_check_11ax_capability(mlan_private *pmpriv, t_u8 band)
171 {
172 mlan_adapter *pmadapter = pmpriv->adapter;
173 t_u8 enable_11ax = MFALSE;
174
175 ENTER();
176 #if CONFIG_WIFI_CAPA
177 if (!pmadapter->usr_dot_11ax_enable)
178 {
179 return enable_11ax;
180 }
181 #endif
182 if ((band == BAND_CONFIG_5GHZ) && !(pmadapter->fw_bands & BAND_AAX))
183 {
184 PRINTM(MCMND, "FW don't support 5G AX\n");
185 LEAVE();
186 return enable_11ax;
187 }
188 if ((band == BAND_CONFIG_ACS_MODE || band == BAND_CONFIG_MANUAL) && !(pmadapter->fw_bands & BAND_GAX))
189 {
190 PRINTM(MCMND, "FW don't support 2G AX\n");
191 LEAVE();
192 return enable_11ax;
193 }
194 enable_11ax = MTRUE;
195 PRINTM(MCMND, "enable_11ax=%d\n", enable_11ax);
196 LEAVE();
197 return enable_11ax;
198 }
199
200 /**
201 * @brief enable/disable 11AX
202 *
203 * @param pmpriv A pointer to mlan_private structure
204 * @param action MLAN_ACT_DISABLE or MLAN_ACT_ENABLE
205 * @param band band config
206 *
207 * @return 0--success, otherwise failure
208 */
wifi_uap_set_11ax_status(mlan_private * pmpriv,t_u8 action,t_u8 band,t_u8 bandwidth)209 int wifi_uap_set_11ax_status(mlan_private *pmpriv, t_u8 action, t_u8 band, t_u8 bandwidth)
210 {
211 mlan_adapter *pmadapter = pmpriv->adapter;
212 int ret = 0;
213 mlan_ds_11ax_he_cfg he_cfg;
214
215 ENTER();
216 if ((band == BAND_CONFIG_5GHZ && !(pmadapter->fw_bands & BAND_AAX)) ||
217 ((band == BAND_CONFIG_ACS_MODE || band == BAND_CONFIG_MANUAL) && !(pmadapter->fw_bands & BAND_GAX)))
218 {
219 PRINTM(MERROR, "fw doesn't support 11ax\n");
220 ret = -WM_FAIL;
221 goto done;
222 }
223 memset(&he_cfg, 0, sizeof(he_cfg));
224 if (band == BAND_CONFIG_5GHZ)
225 {
226 he_cfg.band = MBIT(1);
227 (void)memcpy((void *)&he_cfg.he_cap, (const void *)pmadapter->hw_he_cap, pmadapter->hw_hecap_len);
228 }
229 else if (band == BAND_CONFIG_ACS_MODE || band == BAND_CONFIG_MANUAL)
230 {
231 he_cfg.band = MBIT(0);
232 (void)memcpy((void *)&he_cfg.he_cap, (const void *)pmadapter->hw_2g_he_cap, pmadapter->hw_2g_hecap_len);
233 if (bandwidth == BANDWIDTH_20MHZ)
234 {
235 he_cfg.he_cap.he_phy_cap[0] &= ~(MBIT(1));
236 }
237 }
238 else
239 {
240 PRINTM(MERROR, "Invalid band!\n");
241 ret = -WM_E_INVAL;
242 goto done;
243 }
244
245 #ifdef RW610
246 he_cfg.he_cap.he_phy_cap[0] &= ~DEFAULT_11AX_CAP_40MHZIH2_4GHZBAND_RESET_MASK;
247 #endif
248
249 #if CONFIG_11AX_TWT
250 /* uap mode clear TWT request bit */
251 he_cfg.he_cap.he_mac_cap[0] &= ~HE_MAC_CAP_TWT_REQ_SUPPORT;
252 #endif
253
254 if (action == MLAN_ACT_DISABLE)
255 {
256 if (he_cfg.he_cap.len && (he_cfg.he_cap.ext_id == HE_CAPABILITY))
257 memset(he_cfg.he_cap.he_txrx_mcs_support, 0xff, sizeof(he_cfg.he_cap.he_txrx_mcs_support));
258 else
259 {
260 PRINTM(MCMND, "11ax already disabled\n");
261 goto done;
262 }
263 }
264 DBG_HEXDUMP(MCMD_D, "HE_CFG ", (t_u8 *)&he_cfg, sizeof(he_cfg));
265 ret = wlan_cmd_11ax_cfg(pmpriv, HostCmd_ACT_GEN_SET, &he_cfg);
266 done:
267 LEAVE();
268 return ret;
269 }
270 #endif /* CONFIG_11AX */
271
wifi_uap_clear_domain_info()272 void wifi_uap_clear_domain_info()
273 {
274 wifi_get_command_lock();
275 HostCmd_DS_COMMAND *cmd = wifi_get_command_buffer();
276 HostCmd_DS_802_11D_DOMAIN_INFO *domain_info = (HostCmd_DS_802_11D_DOMAIN_INFO *)((t_u8 *)cmd + S_DS_GEN);
277
278 (void)memset(cmd, 0x00, sizeof(HostCmd_DS_COMMAND));
279 cmd->seq_num = HostCmd_SET_SEQ_NO_BSS_INFO(0 /* seq_num */, 0 /* bss_num */, BSS_TYPE_UAP);
280 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11D_DOMAIN_INFO);
281 cmd->size = S_DS_GEN + sizeof(domain_info->action) + sizeof(MrvlIEtypesHeader_t);
282
283 domain_info->action = HostCmd_ACT_GEN_SET;
284 domain_info->domain.header.type = wlan_cpu_to_le16(TLV_TYPE_DOMAIN);
285
286 wifi_wait_for_cmdresp(NULL);
287 }
288
wifi_uap_prepare_and_send_cmd(mlan_private * pmpriv,t_u16 cmd_no,t_u16 cmd_action,t_u32 cmd_oid,t_void * pioctl_buf,t_void * pdata_buf,mlan_bss_type bss_type,void * priv)289 int wifi_uap_prepare_and_send_cmd(mlan_private *pmpriv,
290 t_u16 cmd_no,
291 t_u16 cmd_action,
292 t_u32 cmd_oid,
293 t_void *pioctl_buf,
294 t_void *pdata_buf,
295 mlan_bss_type bss_type,
296 void *priv)
297 {
298 (void)wifi_get_command_lock();
299 HostCmd_DS_COMMAND *cmd = wifi_get_command_buffer();
300
301 cmd->seq_num = HostCmd_SET_SEQ_NO_BSS_INFO(0U /* seq_num */, 0U /* bss_num */, (uint16_t)bss_type);
302 cmd->result = 0x0;
303
304 mlan_status rv = wlan_ops_uap_prepare_cmd(pmpriv, cmd_no, cmd_action, cmd_oid, pioctl_buf, pdata_buf, cmd);
305 if (rv != MLAN_STATUS_SUCCESS)
306 {
307 wifi_w("Failed to prepare cmd for uAP");
308 (void)wifi_put_command_lock();
309 return (int)rv;
310 }
311
312 (void)wifi_wait_for_cmdresp(priv);
313 return wm_wifi.cmd_resp_status;
314 }
315
316 /*
317 * Note: wlan_uap_domain_info() and wlan_uap_callback_domain_info() are the
318 * original function which handles this functionality. However, it does it
319 * through and IOCTL and its control flow will not work in our case. To
320 * elaborate, it first gets the channel number by sending a command to
321 * firmware. Then in the cmd resp handler to sends the domain info
322 * command. As per the current design of our driver we cannot send command
323 * from command resp handler. Hence, we have modified the control flow to
324 * suit our design.
325 *
326 * This Api is set as callback and called during uap start phase,
327 * getting region code by pmadapter.
328 * Then it sends 80211 domain info command to firmware
329 */
wifi_uap_downld_domain_params(int band)330 int wifi_uap_downld_domain_params(int band)
331 {
332 int rv;
333 mlan_private *priv_uap = mlan_adap->priv[1];
334 int region_code = mlan_adap->region_code;
335 const t_u8 *country_code = NULL;
336 t_u8 nr_sb;
337 wifi_sub_band_set_t *sub_band_list = NULL;
338
339 /* get band and sub band lists */
340 #if CONFIG_5GHz_SUPPORT
341 if (band == BAND_A)
342 {
343 sub_band_list = get_sub_band_from_region_code_5ghz(region_code, &nr_sb);
344 }
345 else
346 {
347 sub_band_list = get_sub_band_from_region_code(region_code, &nr_sb);
348 }
349 #else
350 sub_band_list = get_sub_band_from_region_code(region_code, &nr_sb);
351 #endif
352
353 /* get country code string from region code */
354 country_code = wlan_11d_code_2_region(mlan_adap, (t_u8)region_code);
355 if (country_code == NULL)
356 {
357 wuap_e("wifi_uap_downld_domain_params get country_code from region_code failed");
358 return -WM_FAIL;
359 }
360
361 /* restore domain info params for fw command */
362 wlan_11d_set_domain_info(priv_uap, band, country_code, nr_sb, (IEEEtypes_SubbandSet_t *)sub_band_list);
363
364 rv = wifi_uap_prepare_and_send_cmd(priv_uap, HostCmd_CMD_802_11D_DOMAIN_INFO, HostCmd_ACT_GEN_SET, 0, NULL, NULL,
365 MLAN_BSS_TYPE_UAP, NULL);
366 if (rv != 0)
367 {
368 wuap_w("Unable to send uap domain info");
369 return -WM_FAIL;
370 }
371
372 return WM_SUCCESS;
373 }
374
wifi_cmd_uap_config(char * ssid,t_u8 * mac_addr,enum wlan_security_type security,int key_mgmt,char * passphrase,char * password,t_u8 channel,wifi_scan_chan_list_t scan_chan_list,t_u8 pwe_derivation,t_u8 transition_disable,t_u16 beacon_period,t_u8 bandwidth,t_u8 dtim_period,t_u8 chan_sw_count,mlan_bss_type bss_type,bool mfpc,bool mfpr)375 static int wifi_cmd_uap_config(char *ssid,
376 t_u8 *mac_addr,
377 enum wlan_security_type security,
378 int key_mgmt,
379 char *passphrase,
380 char *password,
381 t_u8 channel,
382 wifi_scan_chan_list_t scan_chan_list,
383 t_u8 pwe_derivation,
384 t_u8 transition_disable,
385 t_u16 beacon_period,
386 t_u8 bandwidth,
387 t_u8 dtim_period,
388 t_u8 chan_sw_count,
389 mlan_bss_type bss_type,
390 bool mfpc,
391 bool mfpr)
392 {
393 t_u32 ssid_len = strlen(ssid);
394 uint8_t i;
395 const t_u8 wmm_oui[4] = {0x00, 0x50, 0xf2, 0x02};
396 #if (CONFIG_UAP_AMPDU_TX) || (CONFIG_UAP_AMPDU_RX)
397 int ret;
398 t_u8 supported_mcs_set[] = {0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
400 #endif
401 #if CONFIG_11AC
402 bool enable_11ac = MFALSE;
403 #endif
404 #if CONFIG_11AX
405 t_u8 enable_11ax = MFALSE;
406 #endif
407
408 if (!(security == WLAN_SECURITY_NONE || security == WLAN_SECURITY_WPA2 ||
409 security == WLAN_SECURITY_WPA_WPA2_MIXED || security == WLAN_SECURITY_WPA3_SAE ||
410 security == WLAN_SECURITY_WPA2_WPA3_SAE_MIXED
411 #if CONFIG_DRIVER_OWE
412 || security == WLAN_SECURITY_OWE_ONLY
413 #endif
414 ))
415 {
416 return -WM_E_INVAL;
417 }
418
419 #if !CONFIG_WPA_SUPP
420 int passphrase_len = (int)strlen(passphrase);
421 int password_len = (int)strlen(password);
422 #endif
423
424 mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[1];
425 wifi_uap_set_beacon_period(beacon_period);
426
427 /* fixme: check if this needs to go on heap */
428 mlan_ds_bss bss;
429 (void)memset(&bss, 0x00, sizeof(mlan_ds_bss));
430
431 bss.sub_command = MLAN_OID_UAP_BSS_CONFIG;
432
433 bss.param.bss_config.ssid.ssid_len = ssid_len;
434 (void)memcpy((void *)bss.param.bss_config.ssid.ssid, (const void *)ssid, ssid_len);
435
436 if (mac_addr != NULL)
437 {
438 (void)memcpy((void *)bss.param.bss_config.mac_addr, (const void *)mac_addr, MLAN_MAC_ADDR_LENGTH);
439 }
440
441 if (bss_type == MLAN_BSS_TYPE_UAP)
442 { /* Not required for WFD */
443 bss.param.bss_config.beacon_period = beacon_period;
444 bss.param.bss_config.dtim_period = dtim_period;
445 if (!wm_wifi.hidden_ssid)
446 bss.param.bss_config.bcast_ssid_ctl = 1;
447 else if (wm_wifi.hidden_ssid == 1)
448 bss.param.bss_config.bcast_ssid_ctl = 0;
449 else if (wm_wifi.hidden_ssid == 2)
450 bss.param.bss_config.bcast_ssid_ctl = 2;
451
452 if (chan_sw_count != 0U)
453 {
454 bss.param.bss_config.dtim_period = 1;
455 bss.param.bss_config.chan_sw_count = chan_sw_count;
456 }
457 }
458 /* Auto channel selection is not handled in 5GHz band, only
459 * manual channel selection is supported right now.
460 */
461 if (channel != 0U)
462 {
463 #if CONFIG_5GHz_SUPPORT
464 if (channel > MAX_CHANNELS_BG)
465 {
466 mlan_private *priv_sta = (mlan_private *)mlan_adap->priv[0];
467 if ((priv_sta->media_connected == MFALSE) && wlan_11h_radar_detect_required(pmpriv, channel))
468 {
469 wuap_e("Cannot start uAP on DFS channel %d", channel);
470 return -WM_E_INVAL;
471 }
472 #if CONFIG_UNII4_BAND_SUPPORT
473 /* TODO: Temporary work around until firmware fix is available */
474 if (channel == 173)
475 {
476 bss.param.bss_config.band_cfg = BAND_CONFIG_CH_173;
477 }
478 else
479 #endif
480 {
481 bss.param.bss_config.band_cfg = BAND_CONFIG_5GHZ;
482 }
483 (void)memcpy((void *)bss.param.bss_config.rates, (const void *)rates_5ghz, sizeof(rates_5ghz));
484 }
485 else
486 {
487 if (channel == 14)
488 {
489 (void)memcpy((void *)bss.param.bss_config.rates, (const void *)rates_2ghz_b, sizeof(rates_2ghz_b));
490 }
491 else
492 {
493 (void)memcpy((void *)bss.param.bss_config.rates, (const void *)rates_2ghz, sizeof(rates_2ghz));
494 }
495 bss.param.bss_config.band_cfg = BAND_CONFIG_MANUAL;
496 }
497 #else
498 if (channel == 14)
499 {
500 (void)memcpy((void *)bss.param.bss_config.rates, (const void *)rates_2ghz_b, sizeof(rates_2ghz_b));
501 }
502 else
503 {
504 (void)memcpy((void *)bss.param.bss_config.rates, (const void *)rates_2ghz, sizeof(rates_2ghz));
505 }
506 bss.param.bss_config.band_cfg = BAND_CONFIG_MANUAL;
507 #endif
508 bss.param.bss_config.channel = channel;
509 }
510 else
511 {
512 /* Auto channel selection from all channels*/
513 bss.param.bss_config.band_cfg = BAND_CONFIG_ACS_MODE;
514 bss.param.bss_config.channel = 0;
515
516 if (scan_chan_list.num_of_chan != 0U)
517 {
518 /* Specify channels if any for Auto channel selection */
519 bss.param.bss_config.num_of_chan = scan_chan_list.num_of_chan;
520 for (i = 0; i < scan_chan_list.num_of_chan; i++)
521 {
522 bss.param.bss_config.chan_list[i].chan_number = scan_chan_list.chan_number[i];
523 #if CONFIG_5GHz_SUPPORT
524 if (scan_chan_list.chan_number[i] > MAX_CHANNELS_BG)
525 {
526 bss.param.bss_config.chan_list[i].band_config_type = BAND_CONFIG_5GHZ;
527 (void)memcpy((void *)bss.param.bss_config.rates, (const void *)rates_5ghz, sizeof(rates_5ghz));
528 }
529 else
530 #endif
531 {
532 bss.param.bss_config.chan_list[i].band_config_type = 0x10;
533 (void)memcpy(bss.param.bss_config.rates, rates_2ghz, sizeof(rates_2ghz));
534 }
535 }
536 }
537 }
538
539 #if CONFIG_11AC
540 enable_11ac = wifi_check_11ac_capability(pmpriv, bss.param.bss_config.band_cfg);
541 #endif
542 #if CONFIG_11AX
543 enable_11ax = wifi_check_11ax_capability(pmpriv, bss.param.bss_config.band_cfg);
544 #endif
545 #if !CONFIG_WPA_SUPP
546 if (security == WLAN_SECURITY_NONE)
547 {
548 bss.param.bss_config.protocol = PROTOCOL_NO_SECURITY;
549 }
550
551 if (security == WLAN_SECURITY_WPA2 || security == WLAN_SECURITY_WPA_WPA2_MIXED ||
552 security == WLAN_SECURITY_WPA3_SAE || security == WLAN_SECURITY_WPA2_WPA3_SAE_MIXED
553 #if CONFIG_DRIVER_OWE
554 || security == WLAN_SECURITY_OWE_ONLY
555 #endif
556 )
557 {
558 bss.param.bss_config.wpa_cfg.pairwise_cipher_wpa2 = CIPHER_AES_CCMP;
559 bss.param.bss_config.wpa_cfg.group_cipher = CIPHER_AES_CCMP;
560 if (security == WLAN_SECURITY_WPA2)
561 {
562 bss.param.bss_config.protocol = PROTOCOL_WPA2;
563 if (key_mgmt & WLAN_KEY_MGMT_PSK)
564 {
565 bss.param.bss_config.key_mgmt = KEY_MGMT_PSK;
566 }
567 if (key_mgmt & WLAN_KEY_MGMT_PSK_SHA256)
568 {
569 bss.param.bss_config.key_mgmt |= KEY_MGMT_PSK_SHA256;
570 }
571 }
572 else if (security == WLAN_SECURITY_WPA_WPA2_MIXED)
573 {
574 bss.param.bss_config.protocol = PROTOCOL_WPA2_MIXED;
575 if (key_mgmt & WLAN_KEY_MGMT_PSK)
576 {
577 bss.param.bss_config.key_mgmt = KEY_MGMT_PSK;
578 }
579 if (key_mgmt & WLAN_KEY_MGMT_PSK_SHA256)
580 {
581 bss.param.bss_config.key_mgmt |= KEY_MGMT_PSK_SHA256;
582 }
583 bss.param.bss_config.wpa_cfg.pairwise_cipher_wpa = CIPHER_TKIP | CIPHER_AES_CCMP;
584 bss.param.bss_config.wpa_cfg.pairwise_cipher_wpa2 = CIPHER_TKIP | CIPHER_AES_CCMP;
585 bss.param.bss_config.wpa_cfg.group_cipher = CIPHER_TKIP;
586 }
587 else if (security == WLAN_SECURITY_WPA3_SAE)
588 {
589 bss.param.bss_config.protocol = PROTOCOL_WPA3_SAE;
590 if (key_mgmt & WLAN_KEY_MGMT_SAE)
591 {
592 bss.param.bss_config.key_mgmt = KEY_MGMT_SAE;
593 }
594 }
595 else if (security == WLAN_SECURITY_WPA2_WPA3_SAE_MIXED)
596 {
597 bss.param.bss_config.protocol = PROTOCOL_WPA2 | PROTOCOL_WPA3_SAE;
598 if (key_mgmt & WLAN_KEY_MGMT_PSK)
599 {
600 bss.param.bss_config.key_mgmt = KEY_MGMT_PSK;
601 }
602 if (key_mgmt & WLAN_KEY_MGMT_PSK_SHA256)
603 {
604 bss.param.bss_config.key_mgmt |= KEY_MGMT_PSK_SHA256;
605 }
606 if (key_mgmt & WLAN_KEY_MGMT_SAE)
607 {
608 bss.param.bss_config.key_mgmt |= KEY_MGMT_SAE;
609 }
610 }
611 #if CONFIG_DRIVER_OWE
612 else if (security == WLAN_SECURITY_OWE_ONLY)
613 {
614 bss.param.bss_config.protocol = PROTOCOL_OWE;
615 if (key_mgmt & WLAN_KEY_MGMT_OWE)
616 {
617 bss.param.bss_config.key_mgmt = KEY_MGMT_OWE;
618 }
619 }
620 #endif
621 else
622 { /* Do Nothing */
623 }
624 /***************************************
625 * Operation UINT16 Bits[15:2]: Reserved *
626 * Bit[1]: Authenticator *
627 * Bit[0]: KeyExchange *
628 ****************************************/
629 bss.param.bss_config.key_mgmt_operation = 0x00;
630
631 #if CONFIG_HOST_PMK
632 if ((security == WLAN_SECURITY_WPA2 || security == WLAN_SECURITY_WPA2_WPA3_SAE_MIXED) && passphrase_len < 64)
633 {
634 char pmk_bin[PMK_BIN_LEN] = {0};
635 char pmk_hex[PMK_HEX_LEN + 2] = {0};
636 bss.param.bss_config.wpa_cfg.length = PMK_HEX_LEN;
637 mrvl_generate_psk(ssid, strlen(ssid), passphrase, pmk_bin);
638 wm_bin2hex((uint8_t *)pmk_bin, pmk_hex, PMK_BIN_LEN, PMK_HEX_LEN + 2);
639 wuap_d("psk %s, pmk_hex %s", passphrase, pmk_hex);
640 (void)memcpy((void *)bss.param.bss_config.wpa_cfg.passphrase, (const void *)pmk_hex, PMK_HEX_LEN);
641 }
642 else
643 {
644 #endif
645 if (security == WLAN_SECURITY_WPA2 || security == WLAN_SECURITY_WPA_WPA2_MIXED ||
646 security == WLAN_SECURITY_WPA2_WPA3_SAE_MIXED)
647 {
648 /*app has converted pmk with psk*/
649 bss.param.bss_config.wpa_cfg.length = (t_u32)passphrase_len;
650 (void)memcpy((void *)bss.param.bss_config.wpa_cfg.passphrase, (const void *)passphrase,
651 (size_t)passphrase_len);
652 }
653 #if CONFIG_HOST_PMK
654 }
655 #endif
656 if (security == WLAN_SECURITY_WPA3_SAE || security == WLAN_SECURITY_WPA2_WPA3_SAE_MIXED)
657 {
658 bss.param.bss_config.auth_mode = MLAN_AUTH_MODE_AUTO;
659 bss.param.bss_config.pwe_derivation = pwe_derivation;
660 bss.param.bss_config.transition_disable = transition_disable;
661 bss.param.bss_config.wpa_cfg.password_length = (t_u32)password_len;
662 (void)memcpy((void *)bss.param.bss_config.wpa_cfg.password, (const void *)password, (size_t)password_len);
663 }
664 }
665 #endif
666 #if (CONFIG_UAP_AMPDU_TX) || (CONFIG_UAP_AMPDU_RX)
667 bss.param.bss_config.ht_cap_info = wm_wifi.ht_cap_info == 0 ? (t_u16)0x112c : wm_wifi.ht_cap_info;
668 wm_wifi.ht_tx_cfg = wm_wifi.ht_tx_cfg == 0 ? (t_u16)0x002c : wm_wifi.ht_tx_cfg;
669
670 if (bandwidth == BANDWIDTH_40MHZ
671 #if CONFIG_11AC
672 || bandwidth == BANDWIDTH_80MHZ
673 #endif
674 )
675 {
676 if (ISSUPP_CHANWIDTH40(mlan_adap->hw_dot_11n_dev_cap) != 0U)
677 {
678 bss.param.bss_config.ht_cap_info |= MBIT(1);
679 wm_wifi.ht_tx_cfg |= MBIT(1);
680 if (ISSUPP_SHORTGI40(mlan_adap->hw_dot_11n_dev_cap) != 0U)
681 {
682 bss.param.bss_config.ht_cap_info |= MBIT(6);
683 wm_wifi.ht_tx_cfg |= MBIT(6);
684 }
685 }
686 }
687 else if (bandwidth == BANDWIDTH_20MHZ)
688 {
689 wm_wifi.ht_tx_cfg &= ~MBIT(1);
690 wm_wifi.ht_tx_cfg &= ~MBIT(6);
691 bss.param.bss_config.ht_cap_info &= ~MBIT(12);
692 }
693 else
694 {
695 /*Do Nothing*/
696 }
697
698 if (ISSUPP_RXLDPC(mlan_adap->hw_dot_11n_dev_cap) != 0U)
699 {
700 SETHT_LDPCCODINGCAP(bss.param.bss_config.ht_cap_info);
701 SETHT_LDPCCODINGCAP(wm_wifi.ht_tx_cfg);
702 }
703 ret = wifi_uap_set_httxcfg_int(wm_wifi.ht_tx_cfg);
704 if (ret != WM_SUCCESS)
705 {
706 wuap_e("Cannot set uAP HT TX Cfg:%x", wm_wifi.ht_tx_cfg);
707 return -WM_E_INVAL;
708 }
709
710 if (!ISSUPP_TXSTBC(mlan_adap->hw_dot_11n_dev_cap))
711 bss.param.bss_config.ht_cap_info &= (~MBIT(7));
712 if (!ISSUPP_RXSTBC(mlan_adap->hw_dot_11n_dev_cap))
713 bss.param.bss_config.ht_cap_info &= (~(MBIT(8) | MBIT(9)));
714 if (!ISSUPP_CHANWIDTH40(mlan_adap->hw_dot_11n_dev_cap))
715 bss.param.bss_config.ht_cap_info &= (~MBIT(12));
716
717 #ifdef RW610
718 /* Set Tx Beam Forming Cap */
719 bss.param.bss_config.tx_bf_cap = mlan_adap->priv[1]->tx_bf_cap;
720 #endif
721
722 #if CONFIG_11AC
723 if (enable_11ac)
724 {
725 (void)wifi_uap_set_11ac_status(pmpriv, MLAN_ACT_ENABLE, bandwidth, channel);
726 }
727 else
728 {
729 (void)wifi_uap_set_11ac_status(pmpriv, MLAN_ACT_DISABLE, bandwidth, channel);
730 }
731 #endif
732 #if CONFIG_11AX
733 if (enable_11ax)
734 {
735 wifi_uap_set_11ax_status(pmpriv, MLAN_ACT_ENABLE, bss.param.bss_config.band_cfg, bandwidth);
736 }
737 else
738 {
739 wifi_uap_set_11ax_status(pmpriv, MLAN_ACT_DISABLE, bss.param.bss_config.band_cfg, bandwidth);
740 }
741 #endif
742 #ifdef RW610_SERIES
743 bss.param.bss_config.ampdu_param = 0x17;
744 #else
745 bss.param.bss_config.ampdu_param = 0x03;
746 #endif
747 (void)memcpy((void *)bss.param.bss_config.supported_mcs_set, (const void *)supported_mcs_set,
748 sizeof(bss.param.bss_config.supported_mcs_set));
749 #endif
750 /*
751 * Note that we are leaving htcap info set to zero by default. This
752 * will ensure that 11N is disabled.
753 */
754
755 memset(&bss.param.bss_config.wmm_para, 0x00, sizeof(wmm_parameter_t));
756
757 memcpy(&bss.param.bss_config.wmm_para.ouitype, wmm_oui, sizeof(wmm_oui));
758 #if CONFIG_WIFI_CAPA
759 if (pmpriv->adapter->usr_dot_11n_enable)
760 #endif
761 {
762 bss.param.bss_config.wmm_para.ouisubtype = 0x01;
763 bss.param.bss_config.wmm_para.version = 0x01;
764 bss.param.bss_config.wmm_para.reserved = 0x00;
765
766 memcpy(&bss.param.bss_config.wmm_para.ac_params, &mlan_adap->ac_params,
767 sizeof(wmm_ac_parameters_t) * MAX_AC_QUEUES);
768 for (i = 0; i < MAX_AC_QUEUES; i++)
769 {
770 bss.param.bss_config.wmm_para.ac_params[i].tx_op_limit =
771 wlan_cpu_to_le16(mlan_adap->ac_params[i].tx_op_limit);
772 }
773 }
774
775 mlan_ioctl_req ioctl_buf;
776 (void)memset(&ioctl_buf, 0x00, sizeof(mlan_ioctl_req));
777
778 ioctl_buf.req_id = (t_u32)MLAN_IOCTL_BSS;
779 /** Pointer to buffer */
780 ioctl_buf.pbuf = (t_u8 *)&bss;
781
782 return wifi_uap_prepare_and_send_cmd(pmpriv, HOST_CMD_APCMD_SYS_CONFIGURE, HostCmd_ACT_GEN_SET, 0, &ioctl_buf, NULL,
783 bss_type, NULL);
784 }
785
786 static wifi_uap_11d_apis_t wifi_uap_11d_apis = {
787 .wifi_uap_downld_domain_params_p = wifi_uap_downld_domain_params,
788 };
789
wifi_uap_enable_11d_support(void)790 int wifi_uap_enable_11d_support(void)
791 {
792 wuap_d("Enabling 11d support APIs");
793
794 wm_wifi.enable_11d_support = true;
795 wm_wifi.uap_support_11d_apis = &wifi_uap_11d_apis;
796 return WM_SUCCESS;
797 }
798
wifi_uap_ctrl_deauth(bool enable)799 int wifi_uap_ctrl_deauth(bool enable)
800 {
801 mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[1];
802 return wifi_uap_prepare_and_send_cmd(pmpriv, HostCmd_CMD_802_11_SNMP_MIB, HostCmd_ACT_GEN_SET, (t_u32)StopDeauth_i,
803 NULL, &enable, MLAN_BSS_TYPE_UAP, NULL);
804 }
805
wifi_uap_set_beacon_period(const t_u16 beacon_period)806 void wifi_uap_set_beacon_period(const t_u16 beacon_period)
807 {
808 wm_wifi.beacon_period = beacon_period;
809 }
810
wifi_uap_set_bandwidth(const t_u8 bandwidth)811 int wifi_uap_set_bandwidth(const t_u8 bandwidth)
812 {
813 if (bandwidth == BANDWIDTH_20MHZ || bandwidth == BANDWIDTH_40MHZ
814 #if CONFIG_11AC
815 || bandwidth == BANDWIDTH_80MHZ
816 #endif
817 )
818 {
819 #ifdef RW610
820 if (bandwidth != BANDWIDTH_20MHZ)
821 {
822 wuap_e("Error! RW610 only supports 20MHz");
823 return -WM_FAIL;
824 }
825 #endif
826 wm_wifi.bandwidth = bandwidth;
827 return WM_SUCCESS;
828 }
829 return (-WM_FAIL);
830 }
831
wifi_uap_get_bandwidth()832 t_u8 wifi_uap_get_bandwidth()
833 {
834 return wm_wifi.bandwidth;
835 }
836
wifi_uap_set_hidden_ssid(const t_u8 hidden_ssid)837 void wifi_uap_set_hidden_ssid(const t_u8 hidden_ssid)
838 {
839 wm_wifi.hidden_ssid = hidden_ssid;
840 }
841
wifi_uap_set_ecsa(void)842 void wifi_uap_set_ecsa(void)
843 {
844 #if defined(SD8801)
845 wm_wifi.chan_sw_count = 7;
846 #endif
847 }
848
wifi_uap_set_htcapinfo(const t_u16 ht_cap_info)849 void wifi_uap_set_htcapinfo(const t_u16 ht_cap_info)
850 {
851 wm_wifi.ht_cap_info = ht_cap_info;
852 }
853
wifi_uap_set_httxcfg(const t_u16 ht_tx_cfg)854 void wifi_uap_set_httxcfg(const t_u16 ht_tx_cfg)
855 {
856 wm_wifi.ht_tx_cfg = ht_tx_cfg;
857 }
858
859 #if CONFIG_WPA_SUPP
860 /**
861 * @brief Get second channel offset
862 *
863 * @param chan channel num
864 * @return second channel offset
865 */
wlan_get_second_channel_offset(mlan_private * priv,int chan)866 t_u8 wlan_get_second_channel_offset(mlan_private *priv, int chan)
867 {
868 t_u8 chan2Offset = SEC_CHAN_NONE;
869
870 /* Special Case: 20Mhz-only Channel */
871 #if CONFIG_UNII4_BAND_SUPPORT
872 if (priv->adapter->region_code != COUNTRY_CODE_US && chan == 165)
873 #else
874 if (chan == 165)
875 #endif
876 return chan2Offset;
877
878 switch (chan)
879 {
880 case 36:
881 case 44:
882 case 52:
883 case 60:
884 case 100:
885 case 108:
886 case 116:
887 case 124:
888 case 132:
889 case 140:
890 case 149:
891 case 157:
892 #if CONFIG_UNII4_BAND_SUPPORT
893 case 165:
894 case 173:
895 #endif
896 chan2Offset = SEC_CHAN_ABOVE;
897 break;
898 case 40:
899 case 48:
900 case 56:
901 case 64:
902 case 104:
903 case 112:
904 case 120:
905 case 128:
906 case 136:
907 case 144:
908 case 153:
909 case 161:
910 #if CONFIG_UNII4_BAND_SUPPORT
911 case 169:
912 case 177:
913 #endif
914 chan2Offset = SEC_CHAN_BELOW;
915 break;
916 }
917 return chan2Offset;
918 }
919
wifi_get_sec_channel_offset(unsigned int chan)920 t_u8 wifi_get_sec_channel_offset(unsigned int chan)
921 {
922 mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[1];
923 mlan_adapter *pmadapter = pmpriv->adapter;
924 t_u16 band;
925 t_u8 chan_offset;
926
927 #if CONFIG_5GHz_SUPPORT
928 if (chan > MAX_CHANNELS_BG)
929 {
930 band = BAND_AN;
931 }
932 else
933 {
934 band = BAND_GN;
935 }
936 #else
937 band = BAND_GN;
938 #endif
939
940 chan_offset = SEC_CHAN_ABOVE;
941
942 if (band & BAND_GN)
943 {
944 if ((chan == 1) || (chan == 2) || (chan == 3) || (chan == 4))
945 chan_offset = SEC_CHAN_ABOVE;
946 else if ((chan == 10) || (chan == 11) || (chan == 12) || (chan == 13))
947 chan_offset = SEC_CHAN_BELOW;
948 else if (chan == 14)
949 chan_offset = SEC_CHAN_NONE;
950
951 /* check if channel 12 is supported in the region */
952 if (!wlan_find_cfp_by_band_and_channel(pmadapter, band, 12))
953 if ((chan == 8) || (chan == 9))
954 chan_offset = SEC_CHAN_BELOW;
955 }
956 #if CONFIG_5GHz_SUPPORT
957 else if (band & BAND_AN)
958 chan_offset = wlan_get_second_channel_offset(pmpriv, chan);
959 #endif
960
961 return chan_offset;
962 }
963 #endif
964
965 #if CONFIG_WIFI_CAPA
wifi_uap_config_wifi_capa(uint8_t wlan_capa)966 void wifi_uap_config_wifi_capa(uint8_t wlan_capa)
967 {
968 if (wlan_capa & WIFI_SUPPORT_LEGACY)
969 {
970 if (wlan_capa & WIFI_SUPPORT_11N)
971 {
972 mlan_adap->usr_dot_11n_enable = MTRUE;
973 #if CONFIG_11AC
974 if (wlan_capa & WIFI_SUPPORT_11AC)
975 {
976 mlan_adap->usr_dot_11ac_enable = MTRUE;
977 #if CONFIG_11AX
978 if (wlan_capa & WIFI_SUPPORT_11AX)
979 {
980 mlan_adap->usr_dot_11ax_enable = MTRUE;
981 }
982 else
983 {
984 mlan_adap->usr_dot_11ax_enable = MFALSE;
985 }
986 #endif
987 }
988 else
989 #endif
990 {
991 #if CONFIG_11AC
992 mlan_adap->usr_dot_11ac_enable = MFALSE;
993 #endif
994 #if CONFIG_11AX
995 mlan_adap->usr_dot_11ax_enable = MFALSE;
996 #endif
997 }
998 }
999 else
1000 {
1001 mlan_adap->usr_dot_11n_enable = MFALSE;
1002 #if CONFIG_11AC
1003 mlan_adap->usr_dot_11ac_enable = MFALSE;
1004 #endif
1005 #if CONFIG_11AX
1006 mlan_adap->usr_dot_11ax_enable = MFALSE;
1007 #endif
1008 }
1009 }
1010 else
1011 {
1012 wuap_e("Invalid wifi capaibility setting\n");
1013 }
1014 return;
1015 }
1016 #endif
1017
wifi_uap_start(mlan_bss_type type,char * ssid,uint8_t * mac_addr,int security,int key_mgmt,char * passphrase,char * password,int channel,wifi_scan_chan_list_t scan_chan_list,uint8_t pwe_derivation,uint8_t transition_disable,bool mfpc,bool mfpr,uint8_t dtim)1018 int wifi_uap_start(mlan_bss_type type,
1019 char *ssid,
1020 uint8_t *mac_addr,
1021 int security,
1022 int key_mgmt,
1023 char *passphrase,
1024 char *password,
1025 int channel,
1026 wifi_scan_chan_list_t scan_chan_list,
1027 uint8_t pwe_derivation,
1028 uint8_t transition_disable,
1029 bool mfpc,
1030 #if CONFIG_WIFI_DTIM_PERIOD
1031 bool mfpr,
1032 uint8_t dtim
1033 #else
1034 bool mfpr
1035 #endif
1036 )
1037 {
1038 wuap_d("Configuring");
1039 #if CONFIG_11AC
1040 if ((BANDWIDTH_80MHZ == wm_wifi.bandwidth) && (channel <= MAX_CHANNELS_BG))
1041 {
1042 wuap_e(
1043 "Cannot start uAP if bandwidth is configured to 80MHz, "
1044 "while channel is selected automatically or set to less than %d.",
1045 MAX_CHANNELS_BG);
1046 return -WM_FAIL;
1047 }
1048 else
1049 {
1050 /** Do Nothing */
1051 }
1052 #endif
1053 if (channel == 14)
1054 {
1055 wm_wifi.bandwidth = BANDWIDTH_20MHZ;
1056 }
1057
1058 /* Configure SSID */
1059 int rv = wifi_cmd_uap_config(ssid, mac_addr, (enum wlan_security_type)security, key_mgmt, passphrase, password,
1060 (t_u8)channel, scan_chan_list, pwe_derivation, transition_disable,
1061 wm_wifi.beacon_period == 0U ? UAP_BEACON_PERIOD : wm_wifi.beacon_period,
1062 wm_wifi.bandwidth == 0U ? BANDWIDTH_40MHZ : wm_wifi.bandwidth,
1063 #if CONFIG_WIFI_DTIM_PERIOD
1064 dtim == 0 ? UAP_DTIM_PERIOD : dtim,
1065 #else
1066 UAP_DTIM_PERIOD,
1067 #endif
1068 wm_wifi.chan_sw_count, type, mfpc, mfpr);
1069
1070 if (rv != WM_SUCCESS)
1071 {
1072 wuap_e("config failed. Cannot start");
1073 return rv;
1074 }
1075
1076 if ((security == WLAN_SECURITY_WPA2 || security == WLAN_SECURITY_WPA_WPA2_MIXED ||
1077 security == WLAN_SECURITY_WPA3_SAE || security == WLAN_SECURITY_WPA2_WPA3_SAE_MIXED
1078 #if CONFIG_DRIVER_OWE
1079 || security == WLAN_SECURITY_OWE_ONLY
1080 #endif
1081 ))
1082 {
1083 (void)wifi_uap_pmf_getset(HostCmd_ACT_GEN_SET, (uint8_t *)&mfpc, (uint8_t *)&mfpr);
1084 }
1085
1086 mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[1];
1087
1088 if (wm_wifi.enable_11d_support && wm_wifi.uap_support_11d_apis)
1089 {
1090 wuap_d("Downloading domain params");
1091 wm_wifi.uap_support_11d_apis->wifi_uap_downld_domain_params_p(BAND_B);
1092 #if CONFIG_5GHz_SUPPORT
1093 wm_wifi.uap_support_11d_apis->wifi_uap_downld_domain_params_p(BAND_A);
1094 #endif
1095 }
1096
1097 wuap_d("Starting BSS");
1098 /* Start BSS */
1099 return wifi_uap_prepare_and_send_cmd(pmpriv, HOST_CMD_APCMD_BSS_START, HostCmd_ACT_GEN_SET, 0, NULL, NULL, type,
1100 NULL);
1101 }
1102
wifi_uap_bss_sta_list(wifi_sta_list_t ** list)1103 int wifi_uap_bss_sta_list(wifi_sta_list_t **list)
1104 {
1105 if (list == MNULL)
1106 {
1107 return -WM_E_INVAL;
1108 }
1109
1110 mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[1];
1111
1112 /* Start BSS */
1113 return wifi_uap_prepare_and_send_cmd(pmpriv, HOST_CMD_APCMD_STA_LIST, HostCmd_ACT_GEN_GET, 0, NULL, NULL,
1114 MLAN_BSS_TYPE_UAP, list);
1115
1116 /* *list must have been filled now if everything went well */
1117 }
1118
1119
wifi_sta_deauth(uint8_t * mac_addr,uint16_t reason_code)1120 int wifi_sta_deauth(uint8_t *mac_addr, uint16_t reason_code)
1121 {
1122 mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[1];
1123 mlan_deauth_param deauth;
1124
1125 if (mac_addr == MNULL)
1126 {
1127 return -WM_FAIL;
1128 }
1129
1130 (void)memcpy((void *)deauth.mac_addr, (const void *)mac_addr, MLAN_MAC_ADDR_LENGTH);
1131 deauth.reason_code = reason_code;
1132
1133 if (pmpriv->media_connected == MFALSE)
1134 {
1135 return -WM_FAIL;
1136 }
1137
1138 /* Start BSS */
1139 return wifi_uap_prepare_and_send_cmd(pmpriv, HOST_CMD_APCMD_STA_DEAUTH, HostCmd_ACT_GEN_SET, 0, NULL, &deauth,
1140 MLAN_BSS_TYPE_UAP, NULL);
1141 }
1142
wifi_uap_stop()1143 int wifi_uap_stop()
1144 {
1145 mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[1];
1146 int rv = 0;
1147
1148 /* Start BSS */
1149 rv = wifi_uap_prepare_and_send_cmd(pmpriv, HOST_CMD_APCMD_BSS_STOP, HostCmd_ACT_GEN_SET, 0, NULL, NULL,
1150 MLAN_BSS_TYPE_UAP, NULL);
1151 wifi_uap_clear_domain_info();
1152
1153 return rv;
1154 }
1155
1156 #if CONFIG_WPA_SUPP_AP
1157 #ifdef SD8801
wifi_uap_acs_config_set()1158 static int wifi_uap_acs_config_set()
1159 {
1160 uint8_t i = 0;
1161 uint32_t size = S_DS_GEN + sizeof(HostCmd_DS_ACS_CONFIG) - 1U;
1162 uint8_t active_chan_list[40];
1163 uint8_t active_num_chans = 0;
1164 MrvlIEtypes_ChanListParamSet_t *tlv_chan_list = NULL;
1165 HostCmd_DS_COMMAND *cmd;
1166
1167 wifi_get_active_channel_list(active_chan_list, &active_num_chans, 0);
1168
1169 (void)wifi_get_command_lock();
1170
1171 cmd = wifi_get_command_buffer();
1172
1173 memset(cmd, 0x00, size);
1174
1175 cmd->command = wlan_cpu_to_le16(HostCmd_MMH_ACS_CFG);
1176 HostCmd_DS_ACS_CONFIG *acs_cmd = (HostCmd_DS_ACS_CONFIG *)((uint32_t)cmd + S_DS_GEN);
1177 uint8_t *tlv = acs_cmd->tlv_buffer;
1178
1179 tlv_chan_list = (MrvlIEtypes_ChanListParamSet_t *)(void *)tlv;
1180
1181 memset(tlv_chan_list, 0x00, sizeof(MrvlIEtypesHeader_t) + active_num_chans * sizeof(ChanScanParamSet_t));
1182
1183 tlv_chan_list->header.type = TLV_TYPE_CHANLIST;
1184 tlv_chan_list->header.len = active_num_chans * sizeof(ChanScanParamSet_t);
1185
1186 for (i = 0; i < active_num_chans; i++)
1187 {
1188 tlv_chan_list->chan_scan_param[i].chan_number = active_chan_list[i];
1189 tlv_chan_list->chan_scan_param[i].min_scan_time = MRVDRV_ACTIVE_SCAN_CHAN_TIME;
1190 tlv_chan_list->chan_scan_param[i].max_scan_time = MRVDRV_ACTIVE_SCAN_CHAN_TIME;
1191 }
1192
1193 size += sizeof(tlv_chan_list->header) + tlv_chan_list->header.len;
1194
1195 cmd->size = (t_u16)size;
1196 cmd->seq_num = (0x01) << 12;
1197 cmd->result = 0x00;
1198
1199 (void)wifi_wait_for_cmdresp(NULL);
1200
1201 return WM_SUCCESS;
1202 }
1203 #endif
1204
wifi_uap_do_acs(const int * freq_list)1205 int wifi_uap_do_acs(const int *freq_list)
1206 {
1207 #ifndef SD8801
1208 mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[1];
1209 #endif
1210 MrvlIEtypes_channel_band_t *tlv_chan_band = MNULL;
1211 MrvlIEtypes_ChanListParamSet_t *tlv_chan_list = MNULL;
1212 ChanScanParamSet_t *pscan_chan = MNULL;
1213 t_u8 *tlv = MNULL;
1214 uint8_t active_chan_list[WIFI_MAX_CHANNEL_NUM];
1215 uint8_t active_num_chans = 0;
1216 t_u16 scan_chan_num = 0;
1217 t_u16 cmd_size;
1218 int i;
1219
1220 wifi_get_command_lock();
1221 HostCmd_DS_COMMAND *cmd = wifi_get_command_buffer();
1222 HostCmd_DS_SYS_CONFIG *sys_config = (HostCmd_DS_SYS_CONFIG *)&cmd->params.sys_config;
1223
1224 cmd->command = wlan_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
1225 cmd->seq_num = HostCmd_SET_SEQ_NO_BSS_INFO(0 /* seq_num */, 0 /* bss_num */, MLAN_BSS_TYPE_UAP);
1226 cmd->result = 0x00;
1227 sys_config->action = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
1228 cmd_size = sizeof(HostCmd_DS_SYS_CONFIG) - 1 + S_DS_GEN;
1229
1230 /* set band config tlv */
1231 tlv = (t_u8 *)sys_config->tlv_buffer;
1232 tlv_chan_band = (MrvlIEtypes_channel_band_t *)tlv;
1233 tlv_chan_band->header.type = wlan_cpu_to_le16(TLV_TYPE_UAP_CHAN_BAND_CONFIG);
1234 tlv_chan_band->header.len = wlan_cpu_to_le16(sizeof(t_u8) + sizeof(t_u8));
1235 tlv_chan_band->band_config = BAND_CONFIG_ACS_MODE;
1236 tlv_chan_band->channel = 0;
1237 cmd_size += sizeof(MrvlIEtypes_channel_band_t);
1238 tlv += sizeof(MrvlIEtypes_channel_band_t);
1239
1240 /* set scan channel list tlv */
1241 tlv_chan_list = (MrvlIEtypes_ChanListParamSet_t *)tlv;
1242 tlv_chan_list->header.type = wlan_cpu_to_le16(TLV_TYPE_CHANLIST);
1243 pscan_chan = tlv_chan_list->chan_scan_param;
1244
1245 /* fill in scan channel list */
1246 if (freq_list && freq_list[0] != 0)
1247 {
1248 /* use hostapd channel list */
1249 for (i = 0; i < WIFI_MAX_CHANNEL_NUM; i++)
1250 {
1251 if (freq_list[i] == 0)
1252 break;
1253
1254 (void)memset(pscan_chan, 0x00, sizeof(ChanScanParamSet_t));
1255 pscan_chan->chan_number = freq_to_chan(freq_list[i]);
1256 pscan_chan->radio_type = freq_list[i] >= 5180 ? BAND_5GHZ : BAND_2GHZ;
1257 pscan_chan++;
1258 }
1259 scan_chan_num = i;
1260 }
1261 else
1262 {
1263 /* create our own scan channel list on default 2.4G, as error protection */
1264 wifi_get_active_channel_list(active_chan_list, &active_num_chans, BAND_2GHZ);
1265 if (active_num_chans != 0 && active_num_chans < WIFI_MAX_CHANNEL_NUM)
1266 {
1267 for (i = 0; i < active_num_chans; i++)
1268 {
1269 (void)memset(pscan_chan, 0x00, sizeof(ChanScanParamSet_t));
1270 pscan_chan->chan_number = active_chan_list[i];
1271 pscan_chan->radio_type = BAND_2GHZ;
1272 pscan_chan++;
1273 }
1274 scan_chan_num = active_num_chans;
1275 }
1276 }
1277
1278 tlv_chan_list->header.len = wlan_cpu_to_le16(scan_chan_num * sizeof(ChanScanParamSet_t));
1279 cmd_size += sizeof(tlv_chan_list->header) + (scan_chan_num * sizeof(ChanScanParamSet_t));
1280 tlv += sizeof(tlv_chan_list->header) + (scan_chan_num * sizeof(ChanScanParamSet_t));
1281
1282 cmd->size = (t_u16)wlan_cpu_to_le16(cmd_size);
1283
1284 wifi_wait_for_cmdresp(NULL);
1285
1286 /* Start ACS SCAN */
1287 #ifdef SD8801
1288 return wifi_uap_acs_config_set();
1289 #else
1290 return wifi_uap_prepare_and_send_cmd(pmpriv, HostCMD_APCMD_ACS_SCAN, HostCmd_ACT_GEN_SET, 0, NULL, NULL,
1291 MLAN_BSS_TYPE_UAP, NULL);
1292 #endif
1293 }
1294 #endif
1295
1296 #if CONFIG_WIFI_UAP_WORKAROUND_STICKY_TIM
1297 /*
1298 * The following configuration was added because of a particular
1299 * bug on 8787 and 8782 firmware. The firmware bugzilla ID for the
1300 * bug is 39609. The bug causes the firmware to send packets to the
1301 * STA even after giving ACK for IEEE PS. The prov. mode scanning
1302 * coupled with this bug causes large scale packet losses and TCP
1303 * backoffs finally resulting in long load times for HTTP served
1304 * pages for prov. UI.
1305 */
1306
1307 /** TLV header length */
1308 #define TLVHEADER_LEN 4
1309
1310 #define MRVL_STICKY_TIM_CONFIG_TLV_ID (PROPRIETARY_TLV_BASE_ID + 0x96)
1311 /** TLV : Sticky TIM MAC address */
1312 #define MRVL_STICKY_TIM_STA_MAC_ADDR_TLV_ID (PROPRIETARY_TLV_BASE_ID + 0x97)
1313
1314 /** TLV buffer : sticky tim config */
1315 typedef PACK_START struct _tlvbuf_sticky_tim_config
1316 {
1317 /** Header */
1318 t_u16 tag;
1319 /** Length */
1320 t_u16 length;
1321 /** Enable */
1322 t_u16 enable;
1323 /** Duration */
1324 t_u16 duration;
1325 /** Sticky Bitmask */
1326 t_u16 sticky_bitmask;
1327 } PACK_END tlvbuf_sticky_tim_config;
1328
1329 /** TLV buffer : sticky tim sta mac address */
1330 typedef PACK_START struct _tlvbuf_sticky_tim_sta_mac_addr
1331 {
1332 /** Header */
1333 t_u16 tag;
1334 /** Length */
1335 t_u16 length;
1336 /** Control */
1337 t_u16 control;
1338 /** Station MAC address */
1339 t_u8 sta_mac_address[MLAN_MAC_ADDR_LENGTH];
1340 } PACK_END tlvbuf_sticky_tim_sta_mac_addr;
1341
1342 /*
1343 * This configures sticky TIM configuration for given MAC.
1344 *
1345 * Note that this is not present in mlan. So we have to add it here.
1346 */
wifi_uap_enable_sticky_bit(const uint8_t * mac_addr)1347 void wifi_uap_enable_sticky_bit(const uint8_t *mac_addr)
1348 {
1349 static bool global_sticky_enabled;
1350
1351 uint32_t size = S_DS_GEN + sizeof(HostCmd_DS_SYS_CONFIG) - 1;
1352
1353 wifi_get_command_lock();
1354 HostCmd_DS_COMMAND *cmd = wifi_get_command_buffer();
1355
1356 cmd->command = wlan_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
1357 HostCmd_DS_SYS_CONFIG *sys_config_cmd = (HostCmd_DS_SYS_CONFIG *)((uint32_t)cmd + S_DS_GEN);
1358 sys_config_cmd->action = HostCmd_ACT_GEN_SET;
1359 uint8_t *tlv = sys_config_cmd->tlv_buffer;
1360
1361 if (!global_sticky_enabled)
1362 {
1363 /*
1364 * This enables the global sticky TIM bit enable. This
1365 * needs to be done only once.
1366 */
1367 tlvbuf_sticky_tim_config *tlv_sticky_tim_cfg = (tlvbuf_sticky_tim_config *)tlv;
1368
1369 tlv_sticky_tim_cfg->tag = MRVL_STICKY_TIM_CONFIG_TLV_ID;
1370 tlv_sticky_tim_cfg->length = sizeof(tlvbuf_sticky_tim_config) - TLVHEADER_LEN;
1371 tlv_sticky_tim_cfg->enable = 1;
1372 /* Set it permanently */
1373 tlv_sticky_tim_cfg->duration = 0;
1374 /* MoreData bit and TIM bit is made sticky */
1375 tlv_sticky_tim_cfg->sticky_bitmask = (t_u16)0x3;
1376
1377 size += sizeof(MrvlIEtypesHeader_t) + tlv_sticky_tim_cfg->length;
1378 tlv += sizeof(MrvlIEtypesHeader_t) + tlv_sticky_tim_cfg->length;
1379
1380 global_sticky_enabled = true;
1381 }
1382
1383 tlvbuf_sticky_tim_sta_mac_addr *tim_cfg = (tlvbuf_sticky_tim_sta_mac_addr *)tlv;
1384
1385 tim_cfg->tag = MRVL_STICKY_TIM_STA_MAC_ADDR_TLV_ID;
1386 tim_cfg->length = sizeof(tlvbuf_sticky_tim_sta_mac_addr) - TLVHEADER_LEN;
1387 (void)memcpy((void *)tim_cfg->sta_mac_address, (const void *)mac_addr, MLAN_MAC_ADDR_LENGTH);
1388 tim_cfg->control = 1;
1389
1390 size += sizeof(MrvlIEtypesHeader_t) + tim_cfg->length;
1391
1392 cmd->size = size;
1393 cmd->seq_num = (0x01) << 12;
1394 cmd->result = 0x00;
1395
1396 wifi_wait_for_cmdresp(NULL);
1397 }
1398 #endif /* CONFIG_WIFI_UAP_WORKAROUND_STICKY_TIM */
1399
1400 /*
1401 * Note: This function handles only one (first) TLV from the response.
1402 */
wifi_uap_handle_cmd_resp(HostCmd_DS_COMMAND * resp)1403 void wifi_uap_handle_cmd_resp(HostCmd_DS_COMMAND *resp)
1404 {
1405 mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[1];
1406 HostCmd_DS_SYS_CONFIG *sys_config = (HostCmd_DS_SYS_CONFIG *)&resp->params.sys_config;
1407 uint8_t *tlv = sys_config->tlv_buffer;
1408 MrvlIEtypesHeader_t *header = (MrvlIEtypesHeader_t *)(void *)tlv;
1409 if (resp->result == 0U)
1410 {
1411 switch (header->type)
1412 {
1413 case TLV_TYPE_UAP_TX_POWER:
1414 {
1415 MrvlIEtypes_tx_power_t *tlv_tx_power = (MrvlIEtypes_tx_power_t *)(void *)tlv;
1416 if (sys_config->action == HostCmd_ACT_GEN_GET)
1417 {
1418 if (wm_wifi.cmd_resp_priv != NULL)
1419 {
1420 uint8_t *tx_power = (uint8_t *)wm_wifi.cmd_resp_priv;
1421 wm_wifi.cmd_resp_priv = NULL;
1422 *tx_power = tlv_tx_power->tx_power;
1423 }
1424 }
1425 wm_wifi.cmd_resp_status = WM_SUCCESS;
1426 }
1427 break;
1428 case TLV_TYPE_UAP_STA_AGEOUT_TIMER:
1429 {
1430 MrvlIEtypes_sta_ageout_t *tlv_sta_ageout_timer = (MrvlIEtypes_sta_ageout_t *)(void *)tlv;
1431 if (sys_config->action == HostCmd_ACT_GEN_GET)
1432 {
1433 if (wm_wifi.cmd_resp_priv != NULL)
1434 {
1435 uint32_t *sta_ageout_timer = (uint32_t *)wm_wifi.cmd_resp_priv;
1436 wm_wifi.cmd_resp_priv = NULL;
1437 *sta_ageout_timer = tlv_sta_ageout_timer->sta_ageout_timer;
1438 }
1439 }
1440 wm_wifi.cmd_resp_status = WM_SUCCESS;
1441 }
1442 break;
1443 case TLV_TYPE_UAP_PS_STA_AGEOUT_TIMER:
1444 {
1445 MrvlIEtypes_ps_sta_ageout_t *tlv_ps_sta_ageout_timer = (MrvlIEtypes_ps_sta_ageout_t *)(void *)tlv;
1446 if (sys_config->action == HostCmd_ACT_GEN_GET)
1447 {
1448 if (wm_wifi.cmd_resp_priv != NULL)
1449 {
1450 uint32_t *ps_sta_ageout_timer = (uint32_t *)wm_wifi.cmd_resp_priv;
1451 wm_wifi.cmd_resp_priv = NULL;
1452 *ps_sta_ageout_timer = tlv_ps_sta_ageout_timer->ps_sta_ageout_timer;
1453 }
1454 }
1455 wm_wifi.cmd_resp_status = WM_SUCCESS;
1456 }
1457 break;
1458 case TLV_TYPE_UAP_GRP_REKEY_TIME:
1459 {
1460 MrvlIEtypes_group_rekey_time_t *tlv_group_rekey_timer = (MrvlIEtypes_group_rekey_time_t *)(void *)tlv;
1461 if (sys_config->action == HostCmd_ACT_GEN_GET)
1462 {
1463 if (wm_wifi.cmd_resp_priv != NULL)
1464 {
1465 uint32_t *group_rekey_timer = (uint32_t *)wm_wifi.cmd_resp_priv;
1466 wm_wifi.cmd_resp_priv = NULL;
1467 *group_rekey_timer = tlv_group_rekey_timer->gk_rekey_time;
1468 }
1469 }
1470 wm_wifi.cmd_resp_status = WM_SUCCESS;
1471 }
1472 break;
1473 case TLV_TYPE_UAP_MCBC_DATA_RATE:
1474 {
1475 MrvlIEtypes_mcbc_rate_t *tlv_mcbc_rate = (MrvlIEtypes_mcbc_rate_t *)(void *)tlv;
1476 if (sys_config->action == HostCmd_ACT_GEN_GET)
1477 {
1478 if (wm_wifi.cmd_resp_priv != NULL)
1479 {
1480 uint16_t *mcbc_rate = (uint16_t *)wm_wifi.cmd_resp_priv;
1481 wm_wifi.cmd_resp_priv = NULL;
1482 *mcbc_rate = tlv_mcbc_rate->mcbc_data_rate;
1483 }
1484 }
1485 wm_wifi.cmd_resp_status = WM_SUCCESS;
1486 }
1487 break;
1488 case TLV_TYPE_RATES:
1489 {
1490 MrvlIEtypes_RatesParamSet_t *tlv_rates = (MrvlIEtypes_RatesParamSet_t *)(void *)tlv;
1491
1492 if (sys_config->action == HostCmd_ACT_GEN_GET)
1493 {
1494 if (wm_wifi.cmd_resp_priv != NULL)
1495 {
1496 char *rates = (char *)wm_wifi.cmd_resp_priv;
1497 wm_wifi.cmd_resp_priv = NULL;
1498 (void)memset((void *)rates, 0, MAX_RATES);
1499 (void)memcpy((void *)rates, (const void *)tlv_rates->rates,
1500 MIN(MAX_RATES, tlv_rates->header.len));
1501 }
1502 }
1503 wm_wifi.cmd_resp_status = WM_SUCCESS;
1504 }
1505 break;
1506 case TLV_TYPE_UAP_CHAN_BAND_CONFIG:
1507 {
1508 MrvlIEtypes_channel_band_t *tlv_cb = (MrvlIEtypes_channel_band_t *)(void *)tlv;
1509 pmpriv->uap_state_chan_cb.band_config = tlv_cb->band_config;
1510 pmpriv->uap_state_chan_cb.channel = tlv_cb->channel;
1511 if (wm_wifi.cmd_resp_priv != NULL)
1512 {
1513 t_u8 *channel = (t_u8 *)wm_wifi.cmd_resp_priv;
1514 wm_wifi.cmd_resp_priv = NULL;
1515 *channel = tlv_cb->channel;
1516 }
1517 wm_wifi.cmd_resp_status = WM_SUCCESS;
1518 }
1519 break;
1520 case TLV_TYPE_UAP_MAX_STA_CNT:
1521 {
1522 MrvlIEtypes_max_sta_count_t *tlv_sta_cnt = (MrvlIEtypes_max_sta_count_t *)(void *)tlv;
1523 pmpriv->uap_state_chan_cb.max_sta_count = tlv_sta_cnt->max_sta_count;
1524 pmpriv->uap_max_sta = tlv_sta_cnt->max_sta_count;
1525 if (wm_wifi.cmd_resp_priv != NULL)
1526 {
1527 int *sta_count = (int *)wm_wifi.cmd_resp_priv;
1528 wm_wifi.cmd_resp_priv = NULL;
1529 *sta_count = (int)tlv_sta_cnt->max_sta_count;
1530 }
1531 wm_wifi.cmd_resp_status = WM_SUCCESS;
1532 }
1533 break;
1534 default:
1535 wm_wifi.cmd_resp_status = WM_SUCCESS;
1536 break;
1537 }
1538 }
1539 else
1540 {
1541 wm_wifi.cmd_resp_status = -WM_FAIL;
1542 }
1543 }
1544
wifi_uap_rates_getset(uint8_t action,char * rates,uint8_t num_rates)1545 int wifi_uap_rates_getset(uint8_t action, char *rates, uint8_t num_rates)
1546 {
1547 uint8_t i = 0;
1548 uint32_t size = S_DS_GEN + sizeof(HostCmd_DS_SYS_CONFIG) - 1U;
1549
1550 (void)wifi_get_command_lock();
1551 HostCmd_DS_COMMAND *cmd = wifi_get_command_buffer();
1552
1553 cmd->command = wlan_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
1554 HostCmd_DS_SYS_CONFIG *sys_config_cmd = (HostCmd_DS_SYS_CONFIG *)((uint32_t)cmd + S_DS_GEN);
1555 uint8_t *tlv = sys_config_cmd->tlv_buffer;
1556
1557 MrvlIEtypes_RatesParamSet_t *tlv_rates = (MrvlIEtypes_RatesParamSet_t *)(void *)tlv;
1558
1559 if (action == HostCmd_ACT_GEN_GET)
1560 {
1561 sys_config_cmd->action = HostCmd_ACT_GEN_GET;
1562 }
1563 else
1564 {
1565 sys_config_cmd->action = HostCmd_ACT_GEN_SET;
1566 for (i = 0; i < num_rates; i++)
1567 {
1568 tlv_rates->rates[i] = (t_u8)rates[i];
1569 }
1570 }
1571
1572 tlv_rates->header.type = wlan_cpu_to_le16(TLV_TYPE_RATES);
1573 tlv_rates->header.len = wlan_cpu_to_le16(i);
1574
1575 size += sizeof(MrvlIEtypesHeader_t) + i;
1576 tlv += sizeof(MrvlIEtypesHeader_t) + i;
1577
1578 cmd->size = (t_u16)size;
1579 cmd->seq_num = (0x01) << 12;
1580 cmd->result = 0x00;
1581
1582 (void)wifi_wait_for_cmdresp(action == HostCmd_ACT_GEN_GET ? rates : NULL);
1583
1584 return wm_wifi.cmd_resp_status;
1585 }
1586
wifi_uap_mcbc_rate_getset(uint8_t action,uint16_t * mcbc_rate)1587 int wifi_uap_mcbc_rate_getset(uint8_t action, uint16_t *mcbc_rate)
1588 {
1589 uint32_t size = S_DS_GEN + sizeof(HostCmd_DS_SYS_CONFIG) - 1U;
1590
1591 (void)wifi_get_command_lock();
1592 HostCmd_DS_COMMAND *cmd = wifi_get_command_buffer();
1593
1594 cmd->command = wlan_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
1595 HostCmd_DS_SYS_CONFIG *sys_config_cmd = (HostCmd_DS_SYS_CONFIG *)((uint32_t)cmd + S_DS_GEN);
1596 uint8_t *tlv = sys_config_cmd->tlv_buffer;
1597
1598 MrvlIEtypes_mcbc_rate_t *tlv_mcbc_rate = (MrvlIEtypes_mcbc_rate_t *)(void *)tlv;
1599
1600 if (action == HostCmd_ACT_GEN_GET)
1601 {
1602 sys_config_cmd->action = HostCmd_ACT_GEN_GET;
1603 }
1604 else
1605 {
1606 sys_config_cmd->action = HostCmd_ACT_GEN_SET;
1607 tlv_mcbc_rate->mcbc_data_rate = *mcbc_rate;
1608 }
1609
1610 tlv_mcbc_rate->header.type = wlan_cpu_to_le16(TLV_TYPE_UAP_MCBC_DATA_RATE);
1611 tlv_mcbc_rate->header.len = wlan_cpu_to_le16(sizeof(t_u16));
1612
1613 size += sizeof(MrvlIEtypes_mcbc_rate_t);
1614 tlv += sizeof(MrvlIEtypes_mcbc_rate_t);
1615
1616 cmd->size = (t_u16)size;
1617 cmd->seq_num = (0x01) << 12;
1618 cmd->result = 0x00;
1619
1620 (void)wifi_wait_for_cmdresp(action == HostCmd_ACT_GEN_GET ? mcbc_rate : NULL);
1621
1622 return wm_wifi.cmd_resp_status;
1623 }
1624
wifi_uap_tx_power_getset(uint8_t action,uint8_t * tx_power_dbm)1625 int wifi_uap_tx_power_getset(uint8_t action, uint8_t *tx_power_dbm)
1626 {
1627 uint32_t size = S_DS_GEN + sizeof(HostCmd_DS_SYS_CONFIG) - 1U;
1628
1629 (void)wifi_get_command_lock();
1630 HostCmd_DS_COMMAND *cmd = wifi_get_command_buffer();
1631
1632 cmd->command = wlan_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
1633 HostCmd_DS_SYS_CONFIG *sys_config_cmd = (HostCmd_DS_SYS_CONFIG *)((uint32_t)cmd + S_DS_GEN);
1634 uint8_t *tlv = sys_config_cmd->tlv_buffer;
1635
1636 MrvlIEtypes_tx_power_t *tlv_tx_power = (MrvlIEtypes_tx_power_t *)(void *)tlv;
1637
1638 if (action == HostCmd_ACT_GEN_GET)
1639 {
1640 sys_config_cmd->action = HostCmd_ACT_GEN_GET;
1641 }
1642 else
1643 {
1644 sys_config_cmd->action = HostCmd_ACT_GEN_SET;
1645 tlv_tx_power->tx_power = *tx_power_dbm;
1646 }
1647 tlv_tx_power->header.type = wlan_cpu_to_le16(TLV_TYPE_UAP_TX_POWER);
1648 tlv_tx_power->header.len = wlan_cpu_to_le16(sizeof(t_u8));
1649
1650 size += sizeof(MrvlIEtypes_tx_power_t);
1651 tlv += sizeof(MrvlIEtypes_tx_power_t);
1652
1653 cmd->size = (uint16_t)size;
1654 cmd->seq_num = (0x01) << 12;
1655 cmd->result = 0x00;
1656
1657 (void)wifi_wait_for_cmdresp(action == HostCmd_ACT_GEN_GET ? tx_power_dbm : NULL);
1658
1659 return wm_wifi.cmd_resp_status;
1660 }
1661
wifi_uap_sta_ageout_timer_getset(uint8_t action,uint32_t * sta_ageout_timer)1662 int wifi_uap_sta_ageout_timer_getset(uint8_t action, uint32_t *sta_ageout_timer)
1663 {
1664 uint32_t size = S_DS_GEN + sizeof(HostCmd_DS_SYS_CONFIG) - 1U;
1665
1666 (void)wifi_get_command_lock();
1667 HostCmd_DS_COMMAND *cmd = wifi_get_command_buffer();
1668
1669 cmd->command = wlan_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
1670 HostCmd_DS_SYS_CONFIG *sys_config_cmd = (HostCmd_DS_SYS_CONFIG *)((uint32_t)cmd + S_DS_GEN);
1671 uint8_t *tlv = sys_config_cmd->tlv_buffer;
1672
1673 MrvlIEtypes_sta_ageout_t *tlv_sta_ageout_timer = (MrvlIEtypes_sta_ageout_t *)(void *)tlv;
1674
1675 if (action == HostCmd_ACT_GEN_GET)
1676 {
1677 sys_config_cmd->action = HostCmd_ACT_GEN_GET;
1678 }
1679 else
1680 {
1681 sys_config_cmd->action = HostCmd_ACT_GEN_SET;
1682 tlv_sta_ageout_timer->sta_ageout_timer = wlan_cpu_to_le32(*sta_ageout_timer);
1683 }
1684 tlv_sta_ageout_timer->header.type = wlan_cpu_to_le16(TLV_TYPE_UAP_STA_AGEOUT_TIMER);
1685 tlv_sta_ageout_timer->header.len = wlan_cpu_to_le16(sizeof(t_u32));
1686
1687 size += sizeof(MrvlIEtypes_sta_ageout_t);
1688 tlv += sizeof(MrvlIEtypes_sta_ageout_t);
1689
1690 cmd->size = (t_u16)size;
1691 cmd->seq_num = (0x01) << 12;
1692 cmd->result = 0x00;
1693
1694 (void)wifi_wait_for_cmdresp(action == HostCmd_ACT_GEN_GET ? sta_ageout_timer : NULL);
1695
1696 return wm_wifi.cmd_resp_status;
1697 }
1698
wifi_uap_ps_sta_ageout_timer_getset(uint8_t action,uint32_t * ps_sta_ageout_timer)1699 int wifi_uap_ps_sta_ageout_timer_getset(uint8_t action, uint32_t *ps_sta_ageout_timer)
1700 {
1701 uint32_t size = S_DS_GEN + sizeof(HostCmd_DS_SYS_CONFIG) - 1U;
1702
1703 (void)wifi_get_command_lock();
1704 HostCmd_DS_COMMAND *cmd = wifi_get_command_buffer();
1705
1706 cmd->command = wlan_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
1707 HostCmd_DS_SYS_CONFIG *sys_config_cmd = (HostCmd_DS_SYS_CONFIG *)((uint32_t)cmd + S_DS_GEN);
1708 uint8_t *tlv = sys_config_cmd->tlv_buffer;
1709
1710 MrvlIEtypes_ps_sta_ageout_t *tlv_ps_sta_ageout_timer = (MrvlIEtypes_ps_sta_ageout_t *)(void *)tlv;
1711
1712 if (action == HostCmd_ACT_GEN_GET)
1713 {
1714 sys_config_cmd->action = HostCmd_ACT_GEN_GET;
1715 }
1716 else
1717 {
1718 sys_config_cmd->action = HostCmd_ACT_GEN_SET;
1719 tlv_ps_sta_ageout_timer->ps_sta_ageout_timer = wlan_cpu_to_le32(*ps_sta_ageout_timer);
1720 }
1721 tlv_ps_sta_ageout_timer->header.type = wlan_cpu_to_le16(TLV_TYPE_UAP_PS_STA_AGEOUT_TIMER);
1722 tlv_ps_sta_ageout_timer->header.len = wlan_cpu_to_le16(sizeof(t_u32));
1723
1724 size += sizeof(MrvlIEtypes_ps_sta_ageout_t);
1725 tlv += sizeof(MrvlIEtypes_ps_sta_ageout_t);
1726
1727 cmd->size = (uint16_t)size;
1728 cmd->seq_num = (0x01) << 12;
1729 cmd->result = 0x00;
1730
1731 (void)wifi_wait_for_cmdresp(action == HostCmd_ACT_GEN_GET ? ps_sta_ageout_timer : NULL);
1732
1733 return wm_wifi.cmd_resp_status;
1734 }
1735
wifi_uap_group_rekey_timer_getset(uint8_t action,uint32_t * group_rekey_timer)1736 int wifi_uap_group_rekey_timer_getset(uint8_t action, uint32_t *group_rekey_timer)
1737 {
1738 uint32_t size = S_DS_GEN + sizeof(HostCmd_DS_SYS_CONFIG) - 1U;
1739
1740 (void)wifi_get_command_lock();
1741 HostCmd_DS_COMMAND *cmd = wifi_get_command_buffer();
1742
1743 cmd->command = wlan_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
1744 HostCmd_DS_SYS_CONFIG *sys_config_cmd = (HostCmd_DS_SYS_CONFIG *)((uint32_t)cmd + S_DS_GEN);
1745 uint8_t *tlv = sys_config_cmd->tlv_buffer;
1746
1747 MrvlIEtypes_group_rekey_time_t *tlv_group_rekey_timer = (MrvlIEtypes_group_rekey_time_t *)(void *)tlv;
1748
1749 if (action == HostCmd_ACT_GEN_GET)
1750 {
1751 sys_config_cmd->action = HostCmd_ACT_GEN_GET;
1752 }
1753 else
1754 {
1755 sys_config_cmd->action = HostCmd_ACT_GEN_SET;
1756 tlv_group_rekey_timer->gk_rekey_time = wlan_cpu_to_le32(*group_rekey_timer);
1757 }
1758 tlv_group_rekey_timer->header.type = wlan_cpu_to_le16(TLV_TYPE_UAP_GRP_REKEY_TIME);
1759 tlv_group_rekey_timer->header.len = wlan_cpu_to_le16(sizeof(t_u32));
1760
1761 size += sizeof(MrvlIEtypes_group_rekey_time_t);
1762 tlv += sizeof(MrvlIEtypes_group_rekey_time_t);
1763
1764 cmd->size = (t_u16)size;
1765 cmd->seq_num = (0x01) << 12;
1766 cmd->result = 0x00;
1767
1768 (void)wifi_wait_for_cmdresp(action == HostCmd_ACT_GEN_GET ? group_rekey_timer : NULL);
1769
1770 return wm_wifi.cmd_resp_status;
1771 }
1772
1773 /* Content reproduced from wlan_uap_get_channel() */
wifi_send_uap_get_channel_cmd(int * channel)1774 static int wifi_send_uap_get_channel_cmd(int *channel)
1775 {
1776 mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[1];
1777 t_u16 tlv_type = TLV_TYPE_UAP_CHAN_BAND_CONFIG;
1778
1779 int rv = wifi_uap_prepare_and_send_cmd(pmpriv, HOST_CMD_APCMD_SYS_CONFIGURE, HostCmd_ACT_GEN_GET, 0, MNULL,
1780 &tlv_type, MLAN_BSS_TYPE_UAP, channel);
1781 if (rv != WM_SUCCESS)
1782 {
1783 return rv;
1784 }
1785
1786 if (wm_wifi.cmd_resp_status != 0)
1787 {
1788 wifi_w("Unable to uap channel");
1789 return wm_wifi.cmd_resp_status;
1790 }
1791
1792 return rv;
1793 }
1794
1795 /* Content reproduced from wlan_uap_get_channel() */
wifi_send_uap_max_sta_num_cmd(uint8_t action,unsigned int * max_sta_num)1796 static int wifi_send_uap_max_sta_num_cmd(uint8_t action, unsigned int *max_sta_num)
1797 {
1798 mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[1];
1799 MrvlIEtypes_max_sta_count_t max_sta_count_tlv;
1800
1801 (void)memset(&max_sta_count_tlv, 0, sizeof(MrvlIEtypes_max_sta_count_t));
1802
1803 max_sta_count_tlv.header.type = TLV_TYPE_UAP_MAX_STA_CNT;
1804
1805 if (action == HostCmd_ACT_GEN_SET)
1806 {
1807 max_sta_count_tlv.header.len = (t_u16)sizeof(MrvlIEtypes_max_sta_count_t);
1808 max_sta_count_tlv.max_sta_count = (t_u16)*max_sta_num;
1809 }
1810
1811 int rv = wifi_uap_prepare_and_send_cmd(pmpriv, HOST_CMD_APCMD_SYS_CONFIGURE, action, 0, MNULL, &max_sta_count_tlv,
1812 MLAN_BSS_TYPE_UAP, max_sta_num);
1813 if (rv != WM_SUCCESS)
1814 {
1815 return rv;
1816 }
1817
1818 if (wm_wifi.cmd_resp_status != 0)
1819 {
1820 wifi_w("Unable to uap max_sta_num");
1821 return wm_wifi.cmd_resp_status;
1822 }
1823
1824 return rv;
1825 }
1826
wifi_get_uap_max_clients(unsigned int * max_sta_num)1827 int wifi_get_uap_max_clients(unsigned int *max_sta_num)
1828 {
1829 return wifi_send_uap_max_sta_num_cmd(HostCmd_ACT_GEN_GET, max_sta_num);
1830 }
1831
wifi_set_uap_max_clients(unsigned int * max_sta_num)1832 int wifi_set_uap_max_clients(unsigned int *max_sta_num)
1833 {
1834 return wifi_send_uap_max_sta_num_cmd(HostCmd_ACT_GEN_SET, max_sta_num);
1835 }
1836
1837 /*
1838 * Note: channel can be NULL. The side effects of this function also are of
1839 * interest to us as pmpriv->uap_state_chan_cb.band_config and
1840 * pmpriv->uap_state_chan_cb.channel are updated.
1841 */
wifi_get_uap_channel(int * channel)1842 int wifi_get_uap_channel(int *channel)
1843 {
1844 return wifi_send_uap_get_channel_cmd(channel);
1845 }
1846
wifi_uap_pmf_getset(uint8_t action,uint8_t * mfpc,uint8_t * mfpr)1847 int wifi_uap_pmf_getset(uint8_t action, uint8_t *mfpc, uint8_t *mfpr)
1848 {
1849 uint32_t size = S_DS_GEN + sizeof(HostCmd_DS_PMF_PARAMS);
1850 wifi_pmf_params_t wifi_pmf_params;
1851
1852 (void)wifi_get_command_lock();
1853 HostCmd_DS_COMMAND *cmd = wifi_get_command_buffer();
1854
1855 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_PMF_PARAMS);
1856 HostCmd_DS_PMF_PARAMS *sys_pmf_params = (HostCmd_DS_PMF_PARAMS *)((uint32_t)cmd + S_DS_GEN);
1857
1858 (void)memset(sys_pmf_params, 0x00, sizeof(HostCmd_DS_PMF_PARAMS));
1859
1860 if (action == HostCmd_ACT_GEN_GET)
1861 {
1862 sys_pmf_params->action = HostCmd_ACT_GEN_GET;
1863 }
1864 else
1865 {
1866 sys_pmf_params->action = HostCmd_ACT_GEN_SET;
1867 }
1868
1869 sys_pmf_params->params.mfpc = *mfpc;
1870 sys_pmf_params->params.mfpr = *mfpr;
1871
1872 cmd->size = (t_u16)size;
1873 cmd->seq_num = (0x01) << 12;
1874 cmd->result = 0x00;
1875
1876 (void)wifi_wait_for_cmdresp(action == HostCmd_ACT_GEN_GET ? &wifi_pmf_params : NULL);
1877
1878 if (action == HostCmd_ACT_GEN_GET)
1879 {
1880 *mfpc = wifi_pmf_params.mfpc;
1881 *mfpr = wifi_pmf_params.mfpr;
1882 }
1883
1884 return wm_wifi.cmd_resp_status;
1885 }
1886
1887 #if CONFIG_UAP_STA_MAC_ADDR_FILTER
wifi_set_sta_mac_filter(int filter_mode,int mac_count,unsigned char * mac_addr)1888 int wifi_set_sta_mac_filter(int filter_mode, int mac_count, unsigned char *mac_addr)
1889 {
1890 t_u8 *buffer = NULL;
1891 t_u16 cmd_len = 0;
1892 t_u16 buf_len = MRVDRV_SIZE_OF_CMD_BUFFER;
1893
1894 HostCmd_DS_GEN *cmd_buf = NULL;
1895 MrvlIEtypes_mac_filter_t *tlv = NULL;
1896 HostCmd_DS_SYS_CONFIG *sys_config = NULL;
1897
1898 /* Initialize the command length */
1899 if (filter_mode == 0)
1900 {
1901 cmd_len = sizeof(HostCmd_DS_GEN) + (sizeof(HostCmd_DS_SYS_CONFIG) - 1) +
1902 (sizeof(MrvlIEtypes_mac_filter_t) - 1) + (WLAN_MAX_STA_FILTER_NUM * MLAN_MAC_ADDR_LENGTH);
1903 }
1904 else
1905 {
1906 cmd_len = sizeof(HostCmd_DS_GEN) + (sizeof(HostCmd_DS_SYS_CONFIG) - 1) +
1907 (sizeof(MrvlIEtypes_mac_filter_t) - 1) + mac_count * MLAN_MAC_ADDR_LENGTH;
1908 }
1909
1910 /* Initialize the command buffer */
1911 buffer = (t_u8 *)OSA_MemoryAllocate(buf_len);
1912 if (!buffer)
1913 {
1914 wuap_e("ERR:Cannot allocate buffer for command!\r\n");
1915 return -WM_FAIL;
1916 }
1917
1918 memset(buffer, 0, buf_len);
1919
1920 /* Locate headers */
1921 cmd_buf = (HostCmd_DS_GEN *)buffer;
1922 sys_config = (HostCmd_DS_SYS_CONFIG *)(buffer + sizeof(HostCmd_DS_GEN));
1923 tlv = (MrvlIEtypes_mac_filter_t *)(buffer + sizeof(HostCmd_DS_GEN) + (sizeof(HostCmd_DS_SYS_CONFIG) - 1));
1924
1925 /* Fill the command buffer */
1926 cmd_buf->command = HOST_CMD_APCMD_SYS_CONFIGURE;
1927 cmd_buf->size = cmd_len;
1928 cmd_buf->seq_num = HostCmd_SET_SEQ_NO_BSS_INFO(0 /* seq_num */, 0 /* bss_num */, MLAN_BSS_TYPE_UAP);
1929 cmd_buf->result = 0;
1930
1931 sys_config->action = HostCmd_ACT_GEN_SET;
1932
1933 tlv->count = mac_count;
1934 tlv->filter_mode = filter_mode;
1935 tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_UAP_STA_MAC_ADDR_FILTER);
1936
1937 if (tlv->count)
1938 {
1939 tlv->header.len = tlv->count * MLAN_MAC_ADDR_LENGTH + 2;
1940 (void)memcpy(tlv->mac_address, mac_addr, mac_count * MLAN_MAC_ADDR_LENGTH);
1941 }
1942 else
1943 {
1944 tlv->header.len = WLAN_MAX_STA_FILTER_NUM * MLAN_MAC_ADDR_LENGTH + 2;
1945 }
1946
1947 if (is_uap_started())
1948 {
1949 wuap_e("down the uap before setting sta filter\n\r");
1950 OSA_MemoryFree(buffer);
1951 return -WM_FAIL;
1952 }
1953
1954 wifi_get_command_lock();
1955
1956 HostCmd_DS_COMMAND *cmd = wifi_get_command_buffer();
1957
1958 (void)memcpy((t_u8 *)cmd, cmd_buf, cmd_len);
1959
1960 wifi_wait_for_cmdresp(NULL);
1961
1962 OSA_MemoryFree(buffer);
1963
1964 return WM_SUCCESS;
1965 }
1966
1967 #endif
1968
1969 #if CONFIG_WPA_SUPP_AP
1970
wifi_uap_client_assoc(t_u8 * sta_addr,unsigned char is_11n_enabled)1971 void wifi_uap_client_assoc(t_u8 *sta_addr, unsigned char is_11n_enabled)
1972 {
1973 #if (CONFIG_UAP_AMPDU_TX) || (CONFIG_UAP_AMPDU_RX)
1974 wlan_request_ralist_lock(mlan_adap->priv[1]);
1975 /* Clear corresponding tx/rx table if necessary */
1976 if (wlan_11n_get_txbastream_tbl((mlan_private *)mlan_adap->priv[1], sta_addr))
1977 {
1978 wlan_11n_delete_txbastream_tbl_entry((mlan_private *)mlan_adap->priv[1], sta_addr);
1979 }
1980
1981 wlan_cleanup_reorder_tbl((mlan_private *)mlan_adap->priv[1], sta_addr);
1982 #if CONFIG_WMM
1983 wlan_ralist_del_enh(mlan_adap->priv[1], sta_addr);
1984 #endif
1985 /* txbastream table also is used as connected STAs data base */
1986 wlan_11n_create_txbastream_tbl((mlan_private *)mlan_adap->priv[1], sta_addr, BA_STREAM_NOT_SETUP);
1987 wlan_11n_update_txbastream_tbl_tx_thresh((mlan_private *)mlan_adap->priv[1], sta_addr, 3);
1988
1989 if (is_11n_enabled)
1990 {
1991 wlan_11n_update_txbastream_tbl_ampdu_supported((mlan_private *)mlan_adap->priv[1], sta_addr, MTRUE);
1992 }
1993
1994 wlan_release_ralist_lock(mlan_adap->priv[1]);
1995
1996 #endif /* CONFIG_UAP_AMPDU_TX || CONFIG_UAP_AMPDU_RX */
1997
1998 #if CONFIG_WMM
1999 wlan_ralist_add_enh(mlan_adap->priv[1], sta_addr);
2000 #endif
2001 }
2002
wifi_uap_client_deauth(t_u8 * sta_addr)2003 void wifi_uap_client_deauth(t_u8 *sta_addr)
2004 {
2005 #if (CONFIG_UAP_AMPDU_TX) || (CONFIG_UAP_AMPDU_RX)
2006 if ((mlan_private *)mlan_adap->priv[1]->is_11n_enabled)
2007 {
2008 wlan_cleanup_reorder_tbl((mlan_private *)mlan_adap->priv[1], sta_addr);
2009 wlan_request_ralist_lock((mlan_private *)mlan_adap->priv[1]);
2010 wlan_11n_delete_txbastream_tbl_entry((mlan_private *)mlan_adap->priv[1], sta_addr);
2011 wlan_release_ralist_lock((mlan_private *)mlan_adap->priv[1]);
2012 }
2013 #endif /* CONFIG_UAP_AMPDU_TX || CONFIG_UAP_AMPDU_RX */
2014
2015 #if CONFIG_WMM
2016 wlan_ralist_del_enh(mlan_adap->priv[1], sta_addr);
2017 #endif
2018 }
2019
2020 /**
2021 * @brief Verify RSN IE
2022 *
2023 * @param rsn_ie Pointer RSN IE
2024 * @param sys_config Pointer to mlan_uap_bss_param structure
2025 *
2026 * @return MTRUE/MFALSE
2027 */
wifi_check_rsn_ie(IEEEtypes_Rsn_t * rsn_ie,mlan_uap_bss_param * sys_config)2028 static t_u8 wifi_check_rsn_ie(IEEEtypes_Rsn_t *rsn_ie, mlan_uap_bss_param *sys_config)
2029 {
2030 int left = 0;
2031 int count = 0;
2032 int i = 0;
2033 wpa_suite_auth_key_mgmt_t *key_mgmt = NULL;
2034 left = rsn_ie->len + 2;
2035 if (left < (int)sizeof(IEEEtypes_Rsn_t))
2036 return MFALSE;
2037 sys_config->wpa_cfg.group_cipher = 0;
2038 sys_config->wpa_cfg.pairwise_cipher_wpa2 = 0;
2039 sys_config->key_mgmt = 0;
2040 /* check the group cipher */
2041 switch (rsn_ie->group_cipher.type)
2042 {
2043 case WPA_CIPHER_TKIP2:
2044 sys_config->wpa_cfg.group_cipher = CIPHER_TKIP;
2045 break;
2046 case WPA_CIPHER_AES_CCM:
2047 case WPA_CIPHER_AES_GCM:
2048 case WPA_CIPHER_AES_CCM_256:
2049 case WPA_CIPHER_AES_GCM_256:
2050 sys_config->wpa_cfg.group_cipher = CIPHER_AES_CCMP;
2051 break;
2052 default:
2053 break;
2054 }
2055 count = wlan_le16_to_cpu(rsn_ie->pairwise_cipher.count);
2056 for (i = 0; i < count; i++)
2057 {
2058 switch (rsn_ie->pairwise_cipher.list[i].type)
2059 {
2060 case WPA_CIPHER_TKIP2:
2061 sys_config->wpa_cfg.pairwise_cipher_wpa2 |= CIPHER_TKIP;
2062 break;
2063 case WPA_CIPHER_AES_CCM:
2064 case WPA_CIPHER_AES_GCM:
2065 case WPA_CIPHER_AES_CCM_256:
2066 case WPA_CIPHER_AES_GCM_256:
2067 sys_config->wpa_cfg.pairwise_cipher_wpa2 |= CIPHER_AES_CCMP;
2068 break;
2069 default:
2070 break;
2071 }
2072 }
2073 left -= sizeof(IEEEtypes_Rsn_t) + (count - 1) * sizeof(wpa_suite);
2074 if (left < (int)sizeof(wpa_suite_auth_key_mgmt_t))
2075 return MFALSE;
2076 key_mgmt = (wpa_suite_auth_key_mgmt_t *)((u8 *)rsn_ie + sizeof(IEEEtypes_Rsn_t) + (count - 1) * sizeof(wpa_suite));
2077 count = wlan_le16_to_cpu(key_mgmt->count);
2078 if (left < (int)(sizeof(wpa_suite_auth_key_mgmt_t) + (count - 1) * sizeof(wpa_suite)))
2079 return MFALSE;
2080 for (i = 0; i < count; i++)
2081 {
2082 switch (key_mgmt->list[i].type)
2083 {
2084 case RSN_AKM_8021X:
2085 case RSN_AKM_8021X_SHA256:
2086 case RSN_AKM_8021X_SUITEB:
2087 case RSN_AKM_8021X_SUITEB_192:
2088 #if CONFIG_11R
2089 case RSN_AKM_FT_8021X:
2090 case RSN_AKM_FT_8021X_SHA384:
2091 #endif
2092 sys_config->key_mgmt |= KEY_MGMT_EAP;
2093 break;
2094 case RSN_AKM_PSK:
2095 #if CONFIG_11R
2096 case RSN_AKM_FT_PSK:
2097 #endif
2098 sys_config->key_mgmt |= KEY_MGMT_PSK;
2099 break;
2100 case RSN_AKM_PSK_SHA256:
2101 sys_config->key_mgmt |= KEY_MGMT_PSK_SHA256;
2102 break;
2103 #ifdef UAP_HOST_MLME
2104 case RSN_AKM_SAE:
2105 #if CONFIG_11R
2106 case RSN_AKM_FT_SAE:
2107 #endif
2108 sys_config->key_mgmt |= KEY_MGMT_SAE;
2109 break;
2110 case RSN_AKM_OWE:
2111 #if CONFIG_DRIVER_OWE
2112 sys_config->key_mgmt |= KEY_MGMT_OWE;
2113 #endif
2114 break;
2115 #endif
2116 }
2117 }
2118 return MTRUE;
2119 }
2120
2121 /**
2122 * @brief Verify WPA IE`
2123 * @param wpa_ie Pointer WPA IE
2124 * @param sys_config Pointer to mlan_uap_bss_param structure
2125 *
2126 * @return MTRUE/MFALSE
2127 */
wifi_check_wpa_ie(IEEEtypes_Wpa_t * wpa_ie,mlan_uap_bss_param * sys_config)2128 static t_u8 wifi_check_wpa_ie(IEEEtypes_Wpa_t *wpa_ie, mlan_uap_bss_param *sys_config)
2129 {
2130 int left = 0;
2131 int count = 0;
2132 int i = 0;
2133 wpa_suite_auth_key_mgmt_t *key_mgmt = NULL;
2134 left = wpa_ie->len + 2;
2135 if (left < (int)sizeof(IEEEtypes_Wpa_t))
2136 return MFALSE;
2137 sys_config->wpa_cfg.group_cipher = 0;
2138 sys_config->wpa_cfg.pairwise_cipher_wpa = 0;
2139 switch (wpa_ie->group_cipher.type)
2140 {
2141 case WPA_CIPHER_TKIP2:
2142 sys_config->wpa_cfg.group_cipher = CIPHER_TKIP;
2143 break;
2144 case WPA_CIPHER_AES_CCM:
2145 sys_config->wpa_cfg.group_cipher = CIPHER_AES_CCMP;
2146 break;
2147 default:
2148 break;
2149 }
2150 count = wlan_le16_to_cpu(wpa_ie->pairwise_cipher.count);
2151 for (i = 0; i < count; i++)
2152 {
2153 switch (wpa_ie->pairwise_cipher.list[i].type)
2154 {
2155 case WPA_CIPHER_TKIP2:
2156 sys_config->wpa_cfg.pairwise_cipher_wpa |= CIPHER_TKIP;
2157 break;
2158 case WPA_CIPHER_AES_CCM:
2159 sys_config->wpa_cfg.pairwise_cipher_wpa |= CIPHER_AES_CCMP;
2160 break;
2161 default:
2162 break;
2163 }
2164 }
2165 left -= sizeof(IEEEtypes_Wpa_t) + (count - 1) * sizeof(wpa_suite);
2166 if (left < (int)sizeof(wpa_suite_auth_key_mgmt_t))
2167 return MFALSE;
2168 key_mgmt = (wpa_suite_auth_key_mgmt_t *)((u8 *)wpa_ie + sizeof(IEEEtypes_Wpa_t) + (count - 1) * sizeof(wpa_suite));
2169 count = wlan_le16_to_cpu(key_mgmt->count);
2170 if (left < (int)(sizeof(wpa_suite_auth_key_mgmt_t) + (count - 1) * sizeof(wpa_suite)))
2171 return MFALSE;
2172 for (i = 0; i < count; i++)
2173 {
2174 switch (key_mgmt->list[i].type)
2175 {
2176 case RSN_AKM_8021X:
2177 sys_config->key_mgmt = KEY_MGMT_EAP;
2178 break;
2179 case RSN_AKM_PSK:
2180 sys_config->key_mgmt = KEY_MGMT_PSK;
2181 break;
2182 }
2183 }
2184 return MTRUE;
2185 }
2186
2187 /**
2188 * @brief Find RSN/WPA IES
2189 *
2190 * @param ie Pointer IE buffer
2191 * @param sys_config Pointer to mlan_uap_bss_param structure
2192 * @return MTRUE/MFALSE
2193 */
wifi_find_wpa_ies(const t_u8 * ie,int len,mlan_uap_bss_param * sys_config)2194 static t_u8 wifi_find_wpa_ies(const t_u8 *ie, int len, mlan_uap_bss_param *sys_config)
2195 {
2196 int bytes_left = len;
2197 const t_u8 *pcurrent_ptr = ie;
2198 t_u16 total_ie_len;
2199 t_u8 element_len;
2200 t_u8 wpa2 = 0;
2201 t_u8 wpa = 0;
2202 t_u8 ret = MFALSE;
2203 IEEEtypes_ElementId_e element_id;
2204 IEEEtypes_VendorSpecific_t *pvendor_ie;
2205 const t_u8 wpa_oui[4] = {0x00, 0x50, 0xf2, 0x01};
2206 while (bytes_left >= 2)
2207 {
2208 element_id = (IEEEtypes_ElementId_e)(*((t_u8 *)pcurrent_ptr));
2209 element_len = *((t_u8 *)pcurrent_ptr + 1);
2210 total_ie_len = element_len + sizeof(IEEEtypes_Header_t);
2211 if (bytes_left < total_ie_len)
2212 {
2213 PRINTM(MERROR, "InterpretIE: Error in processing IE, bytes left < IE length\n");
2214 bytes_left = 0;
2215 continue;
2216 }
2217 switch (element_id)
2218 {
2219 case RSN_IE:
2220 wpa2 = wifi_check_rsn_ie((IEEEtypes_Rsn_t *)pcurrent_ptr, sys_config);
2221 break;
2222 case VENDOR_SPECIFIC_221:
2223 pvendor_ie = (IEEEtypes_VendorSpecific_t *)pcurrent_ptr;
2224 if (!memcmp(pvendor_ie->vend_hdr.oui, wpa_oui, sizeof(pvendor_ie->vend_hdr.oui)) &&
2225 (pvendor_ie->vend_hdr.oui_type == wpa_oui[3]))
2226 {
2227 wpa = wifi_check_wpa_ie((IEEEtypes_Wpa_t *)pcurrent_ptr, sys_config);
2228 }
2229 break;
2230 default:
2231 break;
2232 }
2233 pcurrent_ptr += element_len + 2;
2234 /* Need to account for IE ID and IE Len */
2235 bytes_left -= (element_len + 2);
2236 }
2237 if (wpa && wpa2)
2238 {
2239 sys_config->protocol = PROTOCOL_WPA | PROTOCOL_WPA2;
2240 ret = MTRUE;
2241 }
2242 else if (wpa2)
2243 {
2244 sys_config->protocol = PROTOCOL_WPA2;
2245 ret = MTRUE;
2246 }
2247 else if (wpa)
2248 {
2249 sys_config->protocol = PROTOCOL_WPA;
2250 ret = MTRUE;
2251 }
2252 return ret;
2253 }
2254
2255 /**
2256 * @brief Find and set WMM IES
2257 * @param priv Pointer to moal_private
2258 * @param ie Pointer IE buffer
2259 * @param sys_config Pointer to mlan_uap_bss_param structure
2260 *
2261 * @return N/A
2262 *
2263 **/
wifi_set_wmm_ies(mlan_private * priv,const t_u8 * ie,int len,mlan_uap_bss_param * sys_config)2264 static t_void wifi_set_wmm_ies(mlan_private *priv, const t_u8 *ie, int len, mlan_uap_bss_param *sys_config)
2265 {
2266 int bytes_left = len;
2267 const t_u8 *pcurrent_ptr = ie;
2268 t_u16 total_ie_len;
2269 t_u8 element_len;
2270 IEEEtypes_VendorSpecific_t *pvendor_ie;
2271 IEEEtypes_ElementId_e element_id;
2272 const t_u8 wmm_oui[4] = {0x00, 0x50, 0xf2, 0x02};
2273
2274 while (bytes_left >= 2)
2275 {
2276 element_id = (IEEEtypes_ElementId_e)(*((t_u8 *)pcurrent_ptr));
2277 element_len = *((t_u8 *)pcurrent_ptr + 1);
2278 total_ie_len = element_len + sizeof(IEEEtypes_Header_t);
2279 if (bytes_left < total_ie_len)
2280 {
2281 PRINTM(MERROR, "InterpretIE: Error in processing IE, bytes left < IE length\n");
2282 bytes_left = 0;
2283 continue;
2284 }
2285 switch (element_id)
2286 {
2287 case VENDOR_SPECIFIC_221:
2288 pvendor_ie = (IEEEtypes_VendorSpecific_t *)pcurrent_ptr;
2289 if (!memcmp(pvendor_ie->vend_hdr.oui, wmm_oui, sizeof(pvendor_ie->vend_hdr.oui)) &&
2290 pvendor_ie->vend_hdr.oui_type == wmm_oui[3])
2291 {
2292 if (total_ie_len == sizeof(IEEEtypes_WmmParameter_t))
2293 {
2294 #if CONFIG_WIFI_CAPA
2295 if (priv->adapter->usr_dot_11n_enable)
2296 #endif
2297 {
2298 /*
2299 * Only accept and copy the WMM IE if
2300 * it matches the size expected for the
2301 * WMM Parameter IE.
2302 */
2303 memcpy(&sys_config->wmm_para, pcurrent_ptr + sizeof(IEEEtypes_Header_t), element_len);
2304
2305 /** Disable U-APSD for now */
2306 sys_config->wmm_para.qos_info &= 0x7F;
2307
2308 /** set uap_host_based_config to true */
2309 sys_config->uap_host_based_config = MTRUE;
2310 }
2311 #if CONFIG_WIFI_CAPA
2312 else
2313 {
2314 memset(sys_config->wmm_para.ac_params, 0x00, sizeof(wmm_ac_parameters_t) * MAX_AC_QUEUES);
2315 }
2316 #endif
2317 }
2318 }
2319
2320 break;
2321 default:
2322 break;
2323 }
2324 pcurrent_ptr += element_len + 2;
2325 /* Need to account for IE ID and IE Len */
2326 bytes_left -= (element_len + 2);
2327 }
2328 }
2329
2330 /**
2331 * @brief Set/Get system configuration parameters
2332 *
2333 * @param priv A pointer to moal_private structure
2334 * @param action MLAN_ACT_SET or MLAN_ACT_GET
2335 * @param wait_option Wait option
2336 * @param sys_cfg A pointer to mlan_uap_bss_param structure
2337 *
2338 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
2339 */
wifi_set_get_sys_config(mlan_private * priv,t_u16 action,mlan_uap_bss_param * sys_cfg)2340 mlan_status wifi_set_get_sys_config(mlan_private *priv, t_u16 action, mlan_uap_bss_param *sys_cfg)
2341 {
2342 int ret;
2343 mlan_ds_bss bss;
2344 mlan_ioctl_req ioctl_buf;
2345
2346 ENTER();
2347
2348 (void)memset(&bss, 0x00, sizeof(mlan_ds_bss));
2349
2350 bss.sub_command = MLAN_OID_UAP_BSS_CONFIG;
2351
2352 if (action == MLAN_ACT_SET)
2353 memcpy(&bss.param.bss_config, sys_cfg, sizeof(mlan_uap_bss_param));
2354
2355 (void)memset(&ioctl_buf, 0x00, sizeof(mlan_ioctl_req));
2356
2357 ioctl_buf.req_id = (t_u32)MLAN_IOCTL_BSS;
2358 /** Pointer to buffer */
2359 ioctl_buf.pbuf = (t_u8 *)&bss;
2360
2361 ret = wifi_uap_prepare_and_send_cmd(priv, HOST_CMD_APCMD_SYS_CONFIGURE, HostCmd_ACT_GEN_SET, 0, &ioctl_buf, NULL,
2362 MLAN_BSS_TYPE_UAP, NULL);
2363 if (ret != WM_SUCCESS)
2364 {
2365 return MLAN_STATUS_FAILURE;
2366 }
2367
2368 return MLAN_STATUS_SUCCESS;
2369 }
2370
2371 #define IE_MASK_WPS 0x0001
2372 #define IE_MASK_P2P 0x0002
2373 #define IE_MASK_WFD 0x0004
2374 #define IE_MASK_VENDOR 0x0008
2375 #define IE_MASK_EXTCAP 0x0010
2376
2377 /**
2378 * @brief get specific ie
2379 *
2380 * @param ie Pointer to IEs
2381 * @param len Total length of ie
2382 * @param ie_out Pointer to out IE buf
2383 * @param ie_out_len Total length of ie_out
2384 * @param mask IE mask
2385 *
2386 * @return out IE length
2387 */
wifi_get_specific_ie(const t_u8 * ie,int len,t_u8 * ie_out,t_u32 ie_out_len,t_u16 mask)2388 static t_u16 wifi_get_specific_ie(const t_u8 *ie, int len, t_u8 *ie_out, t_u32 ie_out_len, t_u16 mask)
2389 {
2390 int left_len = len;
2391 const t_u8 *pos = ie;
2392 int length;
2393 t_u8 id = 0;
2394 t_u16 out_len = 0;
2395 IEEEtypes_VendorSpecific_t *pvendor_ie = NULL;
2396 const u8 wps_oui[4] = {0x00, 0x50, 0xf2, 0x04};
2397 const u8 p2p_oui[4] = {0x50, 0x6f, 0x9a, 0x09};
2398 const u8 wfd_oui[4] = {0x50, 0x6f, 0x9a, 0x0a};
2399 const t_u8 wmm_oui[4] = {0x00, 0x50, 0xf2, 0x02};
2400
2401 ENTER();
2402 while (left_len >= 2)
2403 {
2404 length = *(pos + 1);
2405 id = *pos;
2406 if ((length + 2) > left_len)
2407 break;
2408 if (id == VENDOR_SPECIFIC_221)
2409 {
2410 pvendor_ie = (IEEEtypes_VendorSpecific_t *)pos;
2411 if (!memcmp(pvendor_ie->vend_hdr.oui, wmm_oui, sizeof(pvendor_ie->vend_hdr.oui)) &&
2412 pvendor_ie->vend_hdr.oui_type == wmm_oui[3])
2413 {
2414 PRINTM(MIOCTL, "find WMM IE\n");
2415 }
2416 else if (!memcmp(pvendor_ie->vend_hdr.oui, p2p_oui, sizeof(pvendor_ie->vend_hdr.oui)) &&
2417 pvendor_ie->vend_hdr.oui_type == p2p_oui[3])
2418 {
2419 if (mask & IE_MASK_P2P)
2420 {
2421 /** only get first p2p ie here */
2422 __memcpy(NULL, ie_out + out_len, pos, length + 2);
2423 out_len += length + 2;
2424 break;
2425 }
2426 }
2427 else if (!memcmp(pvendor_ie->vend_hdr.oui, wps_oui, sizeof(pvendor_ie->vend_hdr.oui)) &&
2428 pvendor_ie->vend_hdr.oui_type == wps_oui[3])
2429 {
2430 if (mask & IE_MASK_WPS)
2431 {
2432 if ((out_len + length + 2) < (int)ie_out_len)
2433 {
2434 __memcpy(NULL, ie_out + out_len, pos, length + 2);
2435 out_len += length + 2;
2436 }
2437 else
2438 {
2439 PRINTM(MERROR, "get_specific_ie: IE too big, fail copy WPS IE\n");
2440 break;
2441 }
2442 }
2443 }
2444 else if (!memcmp(pvendor_ie->vend_hdr.oui, wfd_oui, sizeof(pvendor_ie->vend_hdr.oui)) &&
2445 pvendor_ie->vend_hdr.oui_type == wfd_oui[3])
2446 {
2447 if (mask & IE_MASK_WFD)
2448 {
2449 if ((out_len + length + 2) < (int)ie_out_len)
2450 {
2451 __memcpy(NULL, ie_out + out_len, pos, length + 2);
2452 out_len += length + 2;
2453 }
2454 else
2455 {
2456 PRINTM(MERROR, "get_specific_ie: IE too big, fail copy WFD IE\n");
2457 break;
2458 }
2459 }
2460 }
2461 else if (mask & IE_MASK_VENDOR)
2462 {
2463 if ((out_len + length + 2) < (int)ie_out_len)
2464 {
2465 __memcpy(NULL, ie_out + out_len, pos, length + 2);
2466 out_len += length + 2;
2467 }
2468 else
2469 {
2470 PRINTM(MERROR, "get_specific_ie:IE too big, fail copy VENDOR IE\n");
2471 break;
2472 }
2473 }
2474 }
2475 pos += (length + 2);
2476 left_len -= (length + 2);
2477 }
2478 LEAVE();
2479 return out_len;
2480 }
2481
2482 /**
2483 * @brief Find specific IE from IE buffer
2484 *
2485 * @param ie Pointer to IEs
2486 * @param len Total length of ie
2487 * @param spec_ie Pointer to specific IE buffer
2488 * @param spec_len Total length of specific IE
2489 *
2490 * @return out IE length
2491 */
wifi_find_ie(const t_u8 * ie,int len,const t_u8 * spec_ie,int spec_len)2492 static t_u8 wifi_find_ie(const t_u8 *ie, int len, const t_u8 *spec_ie, int spec_len)
2493 {
2494 int left_len = len;
2495 const t_u8 *pos = ie;
2496 int length;
2497
2498 while (left_len >= 2)
2499 {
2500 length = *(pos + 1);
2501 if ((length + 2) > left_len)
2502 break;
2503 if ((length + 2) == spec_len)
2504 {
2505 if (!memcmp(pos, spec_ie, spec_len))
2506 return MTRUE;
2507 }
2508 pos += (length + 2);
2509 left_len -= (length + 2);
2510 }
2511 return MFALSE;
2512 }
2513
2514 /**
2515 * @brief Filter specific IE in ie buf
2516 *
2517 * @param priv pointer to moal private structure
2518 * @param ie Pointer to IEs
2519 * @param len Total length of ie
2520 * @param ie_out Pointer to out IE buf
2521 * @param ie_out_len Total length of ie_out
2522 * @param wps_flag flag for wps/p2p
2523 * @param dup_ie Pointer to duplicate ie
2524 * @param dup_ie_len duplicate IE len
2525 *
2526 * @return out IE length
2527 */
wifi_filter_beacon_ies(mlan_private * priv,const t_u8 * ie,int len,t_u8 * ie_out,t_u32 ie_out_len,t_u16 wps_flag,const t_u8 * dup_ie,int dup_ie_len)2528 static t_u16 wifi_filter_beacon_ies(mlan_private *priv,
2529 const t_u8 *ie,
2530 int len,
2531 t_u8 *ie_out,
2532 t_u32 ie_out_len,
2533 t_u16 wps_flag,
2534 const t_u8 *dup_ie,
2535 int dup_ie_len)
2536 {
2537 int left_len = len;
2538 const t_u8 *pos = ie;
2539 int length;
2540 t_u8 id = 0;
2541 t_u16 out_len = 0;
2542 IEEEtypes_VendorSpecific_t *pvendor_ie = NULL;
2543 const u8 wps_oui[4] = {0x00, 0x50, 0xf2, 0x04};
2544 const u8 p2p_oui[4] = {0x50, 0x6f, 0x9a, 0x09};
2545 const u8 wfd_oui[4] = {0x50, 0x6f, 0x9a, 0x0a};
2546 const t_u8 wmm_oui[4] = {0x00, 0x50, 0xf2, 0x02};
2547 t_u8 find_p2p_ie = MFALSE;
2548 t_u8 enable_11d = MFALSE;
2549 #if CONFIG_11AX
2550 t_u8 ext_id = 0;
2551 #endif
2552 // int ie_len;
2553
2554 /* ERP_INFO/EXTENDED_SUPPORT_RATES/HT_CAPABILITY/HT_OPERATION/WMM
2555 * and WPS/P2P/WFD IE will be fileter out
2556 */
2557 while (left_len >= 2)
2558 {
2559 length = *(pos + 1);
2560 id = *pos;
2561 if ((length + 2) > left_len)
2562 break;
2563 if (dup_ie && dup_ie_len && wifi_find_ie(dup_ie, dup_ie_len, pos, length + 2))
2564 {
2565 wifi_d("skip duplicate IE");
2566 pos += (length + 2);
2567 left_len -= (length + 2);
2568 continue;
2569 }
2570 switch (id)
2571 {
2572 case COUNTRY_INFO:
2573 enable_11d = MTRUE;
2574 if ((out_len + length + 2) < (int)ie_out_len)
2575 {
2576 __memcpy(priv, ie_out + out_len, pos, length + 2);
2577 out_len += length + 2;
2578 }
2579 else
2580 {
2581 wifi_d("IE too big, fail copy COUNTRY INFO IE");
2582 }
2583 break;
2584 case HT_CAPABILITY:
2585 case HT_OPERATION:
2586 #if CONFIG_11AC
2587 case VHT_CAPABILITY:
2588 case VHT_OPERATION:
2589 #endif
2590 #ifdef UAP_HOST_MLME
2591 if ((out_len + length + 2) < (int)ie_out_len)
2592 {
2593 __memcpy(priv, ie_out + out_len, pos, length + 2);
2594 out_len += length + 2;
2595 }
2596 else
2597 {
2598 wifi_d("IE too big, fail copy COUNTRY INFO IE");
2599 }
2600 #endif
2601 break;
2602 case EXTENDED_SUPPORTED_RATES:
2603 case WLAN_EID_ERP_INFO:
2604 /* Fall Through */
2605 case REGULATORY_CLASS:
2606 /* Fall Through */
2607 case OVERLAPBSSSCANPARAM:
2608 #ifdef WAPI_AP
2609 /* Fall Through */
2610 case WAPI_IE:
2611 #endif
2612 break;
2613 #if CONFIG_11AX
2614 case EXTENSION:
2615 ext_id = *(pos + 2);
2616 #ifdef UAP_SUPPORT
2617 #if CONFIG_11AX
2618 if (ext_id == HE_CAPABILITY)
2619 {
2620 mlan_ds_11ax_he_cfg he_cfg;
2621 IEEEtypes_HECap_t *hecap_ie = NULL;
2622 (void)memset((void *)&he_cfg, 0, sizeof(mlan_ds_11ax_he_cfg));
2623
2624 if (priv->uap_channel <= 14)
2625 he_cfg.band = MBIT(0);
2626 else
2627 he_cfg.band = MBIT(1);
2628
2629 wifi_d("Retrieve 11ax cfg by channel=%d band=%d", priv->uap_channel, he_cfg.band);
2630
2631 if (0 == wlan_cmd_11ax_cfg(priv, HostCmd_ACT_GEN_GET, &he_cfg))
2632 {
2633 t_u16 he_cap_len;
2634 hecap_ie = (IEEEtypes_HECap_t *)&he_cfg.he_cap.len;
2635 he_cap_len = he_cfg.he_cap.len;
2636 hecap_ie->ieee_hdr.len = he_cap_len;
2637 hecap_ie->ieee_hdr.element_id = he_cfg.he_cap.id;
2638
2639 __memcpy(priv, ie_out + out_len, hecap_ie, hecap_ie->ieee_hdr.len + 2);
2640
2641 out_len += hecap_ie->ieee_hdr.len + 2;
2642 }
2643 else
2644 {
2645 wifi_d("Fail to get 11ax he_cap parameters");
2646 }
2647 }
2648 else
2649 #endif
2650 #endif
2651 {
2652 if ((out_len + length + 2) < (int)ie_out_len)
2653 {
2654 __memcpy(priv, ie_out + out_len, pos, length + 2);
2655 out_len += length + 2;
2656 }
2657 else
2658 {
2659 wifi_d("IE too big, fail copy EXTENSION IE");
2660 }
2661 }
2662 break;
2663 #endif
2664 case EXT_CAPABILITY:
2665 /* filter out EXTCAP */
2666 if (wps_flag & IE_MASK_EXTCAP)
2667 {
2668 #if 0
2669 ie_len = length + 2;
2670 if (MLAN_STATUS_SUCCESS !=
2671 wifi_set_get_gen_ie(priv, MLAN_ACT_SET,
2672 (t_u8 *)pos, &ie_len,
2673 MOAL_IOCTL_WAIT))
2674 PRINTM(MERROR,
2675 "Fail to set EXTCAP IE\n");
2676 #endif
2677 break;
2678 }
2679 if ((out_len + length + 2) < (int)ie_out_len)
2680 {
2681 __memcpy(priv, ie_out + out_len, pos, length + 2);
2682 out_len += length + 2;
2683 }
2684 else
2685 {
2686 wifi_d("IE too big, fail copy EXTCAP IE");
2687 }
2688 break;
2689 case VENDOR_SPECIFIC_221:
2690 /* filter out wmm ie */
2691 pvendor_ie = (IEEEtypes_VendorSpecific_t *)pos;
2692 if (!memcmp(pvendor_ie->vend_hdr.oui, wmm_oui, sizeof(pvendor_ie->vend_hdr.oui)) &&
2693 pvendor_ie->vend_hdr.oui_type == wmm_oui[3])
2694 {
2695 break;
2696 }
2697 /* filter out wps ie */
2698 else if (!memcmp(pvendor_ie->vend_hdr.oui, wps_oui, sizeof(pvendor_ie->vend_hdr.oui)) &&
2699 pvendor_ie->vend_hdr.oui_type == wps_oui[3])
2700 {
2701 if (wps_flag & IE_MASK_WPS)
2702 break;
2703 }
2704 /* filter out first p2p ie */
2705 else if (!memcmp(pvendor_ie->vend_hdr.oui, p2p_oui, sizeof(pvendor_ie->vend_hdr.oui)) &&
2706 pvendor_ie->vend_hdr.oui_type == p2p_oui[3])
2707 {
2708 if (!find_p2p_ie && (wps_flag & IE_MASK_P2P))
2709 {
2710 find_p2p_ie = MTRUE;
2711 break;
2712 }
2713 }
2714 /* filter out wfd ie */
2715 else if (!memcmp(pvendor_ie->vend_hdr.oui, wfd_oui, sizeof(pvendor_ie->vend_hdr.oui)) &&
2716 pvendor_ie->vend_hdr.oui_type == wfd_oui[3])
2717 {
2718 if (wps_flag & IE_MASK_WFD)
2719 break;
2720 }
2721 else if (wps_flag & IE_MASK_VENDOR)
2722 {
2723 // filter out vendor IE
2724 break;
2725 }
2726 if ((out_len + length + 2) < (int)ie_out_len)
2727 {
2728 __memcpy(priv, ie_out + out_len, pos, length + 2);
2729 out_len += length + 2;
2730 }
2731 else
2732 {
2733 wifi_d("IE too big, fail copy VENDOR_SPECIFIC_221 IE");
2734 }
2735 break;
2736 default:
2737 if ((out_len + length + 2) < (int)ie_out_len)
2738 {
2739 __memcpy(priv, ie_out + out_len, pos, length + 2);
2740 out_len += length + 2;
2741 }
2742 else
2743 {
2744 wifi_d("IE too big, fail copy %d IE", id);
2745 }
2746 break;
2747 }
2748
2749 pos += (length + 2);
2750 left_len -= (length + 2);
2751 }
2752
2753 #ifdef UAP_SUPPORT
2754 if (enable_11d && !priv->bss_started && !wlan_11d_is_enabled(priv))
2755 {
2756 wuap_d("Enable 11D support");
2757 wifi_enable_uap_11d_support();
2758 }
2759 #endif
2760 return out_len;
2761 }
2762
wifi_nxp_set_mgmt_ies(mlan_private * priv,char * tail_ies,unsigned short tail_ies_len,char * beacon_ies,unsigned short beacon_ies_len,char * proberesp_ies,unsigned short proberesp_ies_len,char * assocresp_ies,unsigned short assocresp_ies_len)2763 static int wifi_nxp_set_mgmt_ies(mlan_private *priv,
2764 char *tail_ies,
2765 unsigned short tail_ies_len,
2766 char *beacon_ies,
2767 unsigned short beacon_ies_len,
2768 char *proberesp_ies,
2769 unsigned short proberesp_ies_len,
2770 char *assocresp_ies,
2771 unsigned short assocresp_ies_len)
2772 {
2773 int ret = WM_SUCCESS;
2774 const t_u8 *ie = NULL;
2775 t_u8 ie_buffer[MAX_IE_SIZE];
2776 t_u16 ie_len, ie_length = 0;
2777 custom_ie *beacon_ies_data = NULL;
2778 custom_ie *beacon_wps_ies_data = NULL;
2779 custom_ie *proberesp_ies_data = NULL;
2780 custom_ie *assocresp_ies_data = NULL;
2781
2782 beacon_ies_data = (custom_ie *)OSA_MemoryAllocate(sizeof(custom_ie));
2783 beacon_wps_ies_data = (custom_ie *)OSA_MemoryAllocate(sizeof(custom_ie));
2784 proberesp_ies_data = (custom_ie *)OSA_MemoryAllocate(sizeof(custom_ie));
2785
2786 assocresp_ies_data = (custom_ie *)OSA_MemoryAllocate(sizeof(custom_ie));
2787
2788 if ((!beacon_ies_data) || (!beacon_wps_ies_data) || (!proberesp_ies_data) || (!assocresp_ies_data))
2789 {
2790 if (beacon_ies_data)
2791 {
2792 OSA_MemoryFree(beacon_ies_data);
2793 }
2794 if (beacon_wps_ies_data)
2795 {
2796 OSA_MemoryFree(beacon_wps_ies_data);
2797 }
2798 if (proberesp_ies_data)
2799 {
2800 OSA_MemoryFree(proberesp_ies_data);
2801 }
2802 if (assocresp_ies_data)
2803 {
2804 OSA_MemoryFree(assocresp_ies_data);
2805 }
2806 return -WM_FAIL;
2807 }
2808
2809 ie = (const t_u8 *)tail_ies;
2810 ie_len = tail_ies_len;
2811 ie_length = 0;
2812
2813 if ((ie != NULL) && (ie_len != 0U))
2814 {
2815 if (priv->beacon_vendor_index != -1)
2816 {
2817 ret = wifi_clear_mgmt_ie2(MLAN_BSS_TYPE_UAP, priv->beacon_vendor_index);
2818 if (ret != WM_SUCCESS)
2819 {
2820 wuap_e("Clear uAP vendor IE failed");
2821 ret = -WM_FAIL;
2822 goto done;
2823 }
2824 priv->beacon_vendor_index = -1;
2825 }
2826
2827 ie_length = wifi_get_specific_ie(ie, ie_len, ie_buffer, MAX_IE_SIZE, IE_MASK_VENDOR);
2828 #if CONFIG_WIFI_IO_DUMP
2829 PRINTF("VENDOR IE\r\n");
2830 dump_hex(ie_buffer, ie_length);
2831 #endif
2832
2833 if (ie_length)
2834 {
2835 priv->beacon_vendor_index =
2836 wifi_set_mgmt_ie2(MLAN_BSS_TYPE_UAP, MGMT_MASK_BEACON | MGMT_MASK_ASSOC_RESP | MGMT_MASK_PROBE_RESP,
2837 (void *)ie_buffer, ie_length);
2838
2839 if (priv->beacon_vendor_index == -1)
2840 {
2841 wuap_e("Set uAP vendor IE failed");
2842 ret = -WM_FAIL;
2843 goto done;
2844 }
2845 }
2846
2847 ie_length = wifi_filter_beacon_ies(priv, ie, ie_len, ie_buffer, MAX_IE_SIZE,
2848 IE_MASK_WPS | IE_MASK_WFD | IE_MASK_P2P | IE_MASK_VENDOR,
2849 (const t_u8 *)proberesp_ies, proberesp_ies_len);
2850 #if CONFIG_WIFI_IO_DUMP
2851 PRINTF("Beacon IE\r\n");
2852 dump_hex(ie_buffer, ie_length);
2853 #endif
2854 }
2855
2856 beacon_ies_data->ie_index = priv->beacon_index;
2857
2858 if (ie_length)
2859 {
2860 beacon_ies_data->mgmt_subtype_mask = MGMT_MASK_BEACON | MGMT_MASK_ASSOC_RESP | MGMT_MASK_PROBE_RESP;
2861 beacon_ies_data->ie_length = ie_length;
2862 memcpy(beacon_ies_data->ie_buffer, (void *)ie_buffer, ie_length);
2863 }
2864 else
2865 {
2866 beacon_ies_data->mgmt_subtype_mask = MGMT_MASK_CLEAR;
2867 }
2868
2869 ie = (const t_u8 *)beacon_ies;
2870 ie_len = beacon_ies_len;
2871 ie_length = 0;
2872
2873 if ((ie != NULL) && (ie_len != 0U))
2874 {
2875 ie_length = wifi_filter_beacon_ies(priv, ie, ie_len, ie_buffer, MAX_IE_SIZE, IE_MASK_VENDOR, NULL, 0);
2876 #if CONFIG_WIFI_IO_DUMP
2877 PRINTF("Beacon WPS IE\r\n");
2878 dump_hex(ie_buffer, ie_length);
2879 #endif
2880 }
2881
2882 beacon_wps_ies_data->ie_index = priv->beacon_wps_index;
2883 if (ie_length)
2884 {
2885 beacon_wps_ies_data->mgmt_subtype_mask = MGMT_MASK_BEACON;
2886 beacon_wps_ies_data->ie_length = ie_length;
2887 memcpy(beacon_wps_ies_data->ie_buffer, (void *)ie_buffer, ie_length);
2888 }
2889 else
2890 {
2891 beacon_wps_ies_data->mgmt_subtype_mask = MGMT_MASK_CLEAR;
2892 }
2893
2894 ie = (const t_u8 *)proberesp_ies;
2895 ie_len = proberesp_ies_len;
2896 ie_length = 0;
2897
2898 if ((ie != NULL) && (ie_len != 0U))
2899 {
2900 ie_length =
2901 wifi_filter_beacon_ies(priv, ie, ie_len, ie_buffer, MAX_IE_SIZE, IE_MASK_P2P | IE_MASK_VENDOR, NULL, 0);
2902 #if CONFIG_WIFI_IO_DUMP
2903 PRINTF("ProbeResp IE\r\n");
2904 dump_hex(ie_buffer, ie_length);
2905 #endif
2906 }
2907
2908 proberesp_ies_data->ie_index = priv->proberesp_index;
2909 if (ie_length)
2910 {
2911 proberesp_ies_data->mgmt_subtype_mask = MGMT_MASK_PROBE_RESP;
2912 proberesp_ies_data->ie_length = ie_length;
2913 memcpy(proberesp_ies_data->ie_buffer, (void *)ie_buffer, ie_length);
2914 }
2915 else
2916 {
2917 proberesp_ies_data->mgmt_subtype_mask = MGMT_MASK_CLEAR;
2918 }
2919
2920 ie = (const t_u8 *)assocresp_ies;
2921 ie_len = assocresp_ies_len;
2922 ie_length = 0;
2923
2924 if ((ie != NULL) && (ie_len != 0U))
2925 {
2926 #if CONFIG_WIFI_IO_DUMP
2927 PRINTF("AssocResp IE\r\n");
2928 dump_hex(ie, ie_len);
2929 #endif
2930 }
2931
2932 assocresp_ies_data->ie_index = priv->assocresp_index;
2933 if (ie_len)
2934 {
2935 assocresp_ies_data->mgmt_subtype_mask = MGMT_MASK_ASSOC_RESP;
2936 assocresp_ies_data->ie_length = ie_len;
2937 memcpy(assocresp_ies_data->ie_buffer, (void *)ie, ie_len);
2938 }
2939 else
2940 {
2941 assocresp_ies_data->mgmt_subtype_mask = MGMT_MASK_CLEAR;
2942 }
2943
2944 ret = wifi_set_custom_ie(beacon_ies_data, beacon_wps_ies_data, proberesp_ies_data, assocresp_ies_data);
2945 if (ret != WM_SUCCESS)
2946 {
2947 ret = -WM_FAIL;
2948 goto done;
2949 }
2950 ret = WM_SUCCESS;
2951 done:
2952 if (beacon_ies_data)
2953 {
2954 OSA_MemoryFree(beacon_ies_data);
2955 }
2956 if (beacon_wps_ies_data)
2957 {
2958 OSA_MemoryFree(beacon_wps_ies_data);
2959 }
2960 if (proberesp_ies_data)
2961 {
2962 OSA_MemoryFree(proberesp_ies_data);
2963 }
2964 if (assocresp_ies_data)
2965 {
2966 OSA_MemoryFree(assocresp_ies_data);
2967 }
2968
2969 return ret;
2970 }
2971
2972 #if CONFIG_5GHz_SUPPORT
2973 /**
2974 * @brief Get second channel offset
2975 *
2976 * @param priv A pointer to moal_private structure
2977 * @param chan channel num
2978 * @return second channel offset
2979 */
wifi_get_second_channel_offset(mlan_private * priv,int chan)2980 t_u8 wifi_get_second_channel_offset(mlan_private *priv, int chan)
2981 {
2982 t_u8 chan2Offset = SEC_CHAN_NONE;
2983
2984 #if CONFIG_UNII4_BAND_SUPPORT
2985 mlan_adapter *pmadapter = priv->adapter;
2986 if (pmadapter->region_code != COUNTRY_CODE_US && chan == 165)
2987 #else
2988 if (chan == 165)
2989 #endif
2990 return chan2Offset;
2991
2992 switch (chan)
2993 {
2994 case 36:
2995 case 44:
2996 case 52:
2997 case 60:
2998 case 100:
2999 case 108:
3000 case 116:
3001 case 124:
3002 case 132:
3003 #if CONFIG_11AC
3004 case 140:
3005 #endif
3006 case 149:
3007 case 157:
3008 #if CONFIG_UNII4_BAND_SUPPORT
3009 case 165:
3010 case 173:
3011 #endif
3012 chan2Offset = SEC_CHAN_ABOVE;
3013 break;
3014 case 40:
3015 case 48:
3016 case 56:
3017 case 64:
3018 case 104:
3019 case 112:
3020 case 120:
3021 case 128:
3022 case 136:
3023 #if CONFIG_11AC
3024 case 144:
3025 #endif
3026 case 153:
3027 case 161:
3028 #if CONFIG_UNII4_BAND_SUPPORT
3029 case 169:
3030 case 177:
3031 #endif
3032 chan2Offset = SEC_CHAN_BELOW;
3033 break;
3034 }
3035 return chan2Offset;
3036 }
3037 #endif
3038
3039 /**
3040 * @brief Look up specific IE in a buf
3041 *
3042 * @param ie Pointer to IEs
3043 * @param len Total length of ie
3044 * @param id Element id to lookup
3045 *
3046 * @return Pointer of the specific IE -- success, NULL -- fail
3047 */
wifi_parse_ie_tlv(const t_u8 * ie,int len,t_u8 id)3048 const t_u8 *wifi_parse_ie_tlv(const t_u8 *ie, int len, t_u8 id)
3049 {
3050 int left_len = len;
3051 const t_u8 *pos = ie;
3052 int length;
3053
3054 /* IE format:
3055 * | u8 | id |
3056 * | u8 | len |
3057 * | var | data |
3058 */
3059 while (left_len >= 2)
3060 {
3061 length = *(pos + 1);
3062 if ((*pos == id) && (length + 2) <= left_len)
3063 return pos;
3064 pos += (length + 2);
3065 left_len -= (length + 2);
3066 }
3067
3068 return NULL;
3069 }
3070
3071 /**
3072 * @brief Look up specific IE in Extension IE
3073 *
3074 * @param ie Pointer to IEs
3075 * @param len Total length of ie
3076 * @param ext_id Extended Element id to lookup
3077 *
3078 * @return Pointer of the specific Extended IE -- success, NULL
3079 * -- fail
3080 */
wifi_parse_ext_ie_tlv(const t_u8 * ie,int len,t_u8 ext_id)3081 const t_u8 *wifi_parse_ext_ie_tlv(const t_u8 *ie, int len, t_u8 ext_id)
3082 {
3083 int left_len = len;
3084 const t_u8 *pos = ie;
3085 int length;
3086
3087 /* Extension IE format:
3088 * | u8 | id |
3089 * | u8 | len |
3090 * | u8 | ext_id |
3091 * | var | data |
3092 */
3093 while (left_len >= 2)
3094 {
3095 length = *(pos + 1);
3096 if ((*pos == EXTENSION) && (length + 2) <= left_len)
3097 {
3098 if (*(pos + 2) == ext_id)
3099 return pos;
3100 }
3101 pos += (length + 2);
3102 left_len -= (length + 2);
3103 }
3104 return NULL;
3105 }
3106
3107 /**
3108 * @brief get ht_cap from beacon ie
3109 *
3110 * @param ie Pointer to IEs
3111 * @param len Total length of ie
3112 *
3113 * @return ht_cap
3114 */
wifi_get_htcap_info(const t_u8 * ie,int len)3115 static t_u16 wifi_get_htcap_info(const t_u8 *ie, int len)
3116 {
3117 t_u16 ht_cap_info = 0;
3118 IEEEtypes_HTCap_t *htcap_ie = NULL;
3119 htcap_ie = (IEEEtypes_HTCap_t *)wifi_parse_ie_tlv(ie, len, HT_CAPABILITY);
3120 if (htcap_ie)
3121 {
3122 /* hostap has converted ht_cap_info to little endian, here
3123 * conver to host endian */
3124 ht_cap_info = wlan_le16_to_cpu(htcap_ie->ht_cap.ht_cap_info);
3125 wifi_d("Get ht_cap from beacon ies: 0x%x\r\n", ht_cap_info);
3126 }
3127 return ht_cap_info;
3128 }
3129
3130 #if CONFIG_11AC
3131 /**
3132 * @brief get vht_cap from beacon ie
3133 *
3134 * @param ie Pointer to IEs
3135 * @param len Total length of ie
3136 *
3137 * @return Pointer to vht_cap ie
3138 */
wifi_get_vhtcap_info(const t_u8 * ie,int len)3139 static IEEEtypes_VHTCap_t *wifi_get_vhtcap_info(const t_u8 *ie, int len)
3140 {
3141 IEEEtypes_VHTCap_t *vhtcap_ie = NULL;
3142 vhtcap_ie = (IEEEtypes_VHTCap_t *)wifi_parse_ie_tlv(ie, len, VHT_CAPABILITY);
3143 if (vhtcap_ie)
3144 wifi_d("Get vht_cap from beacon ies: 0x%x\r\n", vhtcap_ie->vht_cap.vht_cap_info);
3145 return vhtcap_ie;
3146 }
3147
3148 /**
3149 * @brief get vht_oper from beacon ie
3150 *
3151 * @param ie Pointer to IEs
3152 * @param len Total length of ie
3153 *
3154 * @return Pointer to vht_opr ie
3155 */
wifi_get_vht_oprat_ie(const t_u8 * ie,int len)3156 static IEEEtypes_VHTOprat_t *wifi_get_vht_oprat_ie(const t_u8 *ie, int len)
3157 {
3158 IEEEtypes_VHTOprat_t *vht_oprat_ie = NULL;
3159 vht_oprat_ie = (IEEEtypes_VHTOprat_t *)wifi_parse_ie_tlv(ie, len, VHT_OPERATION);
3160 if (vht_oprat_ie)
3161 wifi_d("Get vht_oprat_ie from beacon ies: chan_width=%d\r\n", vht_oprat_ie->chan_width);
3162 return vht_oprat_ie;
3163 }
3164
3165 /**
3166 * @brief enable/disable 11AC
3167 *
3168 * @param priv A pointer to moal_private structure
3169 * @param action MLAN_ACT_DISABLE or MLAN_ACT_ENABLE
3170 * @param vht20_40 Enable VHT 20 MHz or 40 MHz band
3171 * @param vhtcap_ie A pointer to vht capability IE
3172 *
3173 * @return 0--success, otherwise failure
3174 */
wifi_uap_set_11ac_status2(mlan_private * priv,t_u8 action,t_u8 vht20_40,IEEEtypes_VHTCap_t * vhtcap_ie)3175 int wifi_uap_set_11ac_status2(mlan_private *priv, t_u8 action, t_u8 vht20_40, IEEEtypes_VHTCap_t *vhtcap_ie)
3176 {
3177 mlan_adapter *pmadapter = priv->adapter;
3178 mlan_ds_11ac_vht_cfg vht_cfg;
3179 int ret = 0;
3180
3181 ENTER();
3182
3183 (void)memset(&vht_cfg, 0, sizeof(vht_cfg));
3184
3185 #if CONFIG_5GHz_SUPPORT
3186 if (priv->uap_channel > MAX_CHANNELS_BG)
3187 {
3188 vht_cfg.band = BAND_SELECT_A;
3189 }
3190 else
3191 {
3192 vht_cfg.band = BAND_SELECT_BG;
3193 }
3194 #else
3195 vht_cfg.band = BAND_SELECT_BG;
3196 #endif
3197 vht_cfg.txrx = MLAN_RADIO_TXRX;
3198
3199 /*
3200 * p2p GO (negotiation or auto GO) cases, wpa_supplicant will download
3201 * invalid vht capability with value 0 in beacon parameters, so for p2p
3202 * GO case (vht_cap_info = 0), driver will use hardware 11ac vht
3203 * capability value instead of up layer value.
3204 */
3205 if (vhtcap_ie && vhtcap_ie->vht_cap.vht_cap_info != 0)
3206 {
3207 vht_cfg.vht_cap_info = wlan_le32_to_cpu(vhtcap_ie->vht_cap.vht_cap_info);
3208 /** todo mcs configuration */
3209 }
3210 else
3211 {
3212 #if CONFIG_5GHz_SUPPORT
3213 vht_cfg.vht_cap_info = pmadapter->usr_dot_11ac_dev_cap_a;
3214 #else
3215 vht_cfg.vht_cap_info = pmadapter->usr_dot_11ac_dev_cap_bg;
3216 #endif
3217 }
3218 if (action == MLAN_ACT_DISABLE)
3219 {
3220 vht_cfg.bwcfg = MFALSE;
3221 vht_cfg.vht_cap_info &= ~VHT_CAP_11AC_MASK;
3222 vht_cfg.vht_rx_mcs = vht_cfg.vht_tx_mcs = 0xffff;
3223 vht_cfg.skip_usr_11ac_mcs_cfg = MTRUE;
3224 }
3225 else
3226 {
3227 if (vht20_40)
3228 vht_cfg.bwcfg = MFALSE;
3229 else
3230 vht_cfg.bwcfg = MTRUE;
3231 vht_cfg.vht_cap_info &= ~DEFALUT_11AC_CAP_BEAMFORMING_RESET_MASK;
3232 vht_cfg.vht_tx_mcs = pmadapter->usr_dot_11ac_mcs_support >> 16;
3233 vht_cfg.vht_rx_mcs = pmadapter->usr_dot_11ac_mcs_support & 0xffff;
3234 vht_cfg.skip_usr_11ac_mcs_cfg = MTRUE;
3235 }
3236
3237 if ((GET_VHTCAP_MAXMPDULEN(vht_cfg.vht_cap_info)) != 0U)
3238 {
3239 RESET_11ACMAXMPDULEN(vht_cfg.vht_cap_info);
3240 }
3241 else
3242 {
3243 /** Do Nothing */
3244 }
3245
3246 wifi_d("Uap:11ac=%d vht_cap_info=0x%x, vht_tx_mcs=0x%x, vht_rx_mcs=0x%x\r\n", action, vht_cfg.vht_cap_info,
3247 vht_cfg.vht_tx_mcs, vht_cfg.vht_rx_mcs);
3248
3249 ret = (int)wlan_11ac_ioctl_vhtcfg(priv, (t_u8)MLAN_ACT_SET, &vht_cfg);
3250 return ret;
3251 }
3252 #endif
3253
3254 #if CONFIG_11AX
3255
3256 /**
3257 * @brief enable/disable 11AX
3258 *
3259 * @param pmpriv A pointer to mlan_private structure
3260 * @param action MLAN_ACT_DISABLE or MLAN_ACT_ENABLE
3261 * @param band band config
3262 *
3263 * @return 0--success, otherwise failure
3264 */
wifi_uap_set_11ax_status2(mlan_private * pmpriv,t_u8 action,t_u8 band,IEEEtypes_HECap_t * hecap_ie,t_u8 bandwidth)3265 int wifi_uap_set_11ax_status2(mlan_private *pmpriv, t_u8 action, t_u8 band, IEEEtypes_HECap_t *hecap_ie, t_u8 bandwidth)
3266 {
3267 mlan_adapter *pmadapter = pmpriv->adapter;
3268 int ret = 0;
3269 mlan_ds_11ax_he_cfg he_cfg;
3270
3271 ENTER();
3272 if ((band == BAND_CONFIG_5GHZ && !(pmadapter->fw_bands & BAND_AAX)) ||
3273 ((band == BAND_CONFIG_ACS_MODE || band == BAND_CONFIG_MANUAL) && !(pmadapter->fw_bands & BAND_GAX)))
3274 {
3275 PRINTM(MERROR, "fw doesn't support 11ax\n");
3276 ret = -WM_FAIL;
3277 goto done;
3278 }
3279 memset(&he_cfg, 0, sizeof(he_cfg));
3280 if (band == BAND_CONFIG_5GHZ)
3281 {
3282 he_cfg.band = MBIT(1);
3283 (void)memcpy((void *)&he_cfg.he_cap, (const void *)pmadapter->hw_he_cap, pmadapter->hw_hecap_len);
3284 }
3285 else if (band == BAND_CONFIG_ACS_MODE || band == BAND_CONFIG_MANUAL)
3286 {
3287 he_cfg.band = MBIT(0);
3288 (void)memcpy((void *)&he_cfg.he_cap, (const void *)pmadapter->hw_2g_he_cap, pmadapter->hw_2g_hecap_len);
3289 if (bandwidth == BANDWIDTH_20MHZ)
3290 {
3291 he_cfg.he_cap.he_phy_cap[0] &= ~(MBIT(1));
3292 }
3293 }
3294 else
3295 {
3296 PRINTM(MERROR, "Invalid band!\n");
3297 ret = -WM_E_INVAL;
3298 goto done;
3299 }
3300 #ifdef RW610
3301 he_cfg.he_cap.he_phy_cap[0] &= ~DEFAULT_11AX_CAP_40MHZIH2_4GHZBAND_RESET_MASK;
3302 #endif
3303 #if CONFIG_11AX_TWT
3304 /* uap mode clear TWT request bit */
3305 he_cfg.he_cap.he_mac_cap[0] &= ~HE_MAC_CAP_TWT_REQ_SUPPORT;
3306 #endif
3307 #if 0
3308 if (wlan_cmd_11ax_cfg(pmpriv, HostCmd_ACT_GEN_GET, &he_cfg))
3309 {
3310 PRINTM(MERROR, "Fail to get 11ax cfg!\n");
3311 ret = -WM_FAIL;
3312 goto done;
3313 }
3314 #endif
3315 if (hecap_ie)
3316 {
3317 DBG_HEXDUMP(MCMD_D, "hecap_ie", (t_u8 *)hecap_ie, hecap_ie->ieee_hdr.len + sizeof(IEEEtypes_Header_t));
3318 he_cfg.he_cap.id = hecap_ie->ieee_hdr.element_id;
3319 he_cfg.he_cap.len = hecap_ie->ieee_hdr.len;
3320 memcpy(&he_cfg.he_cap.ext_id, &hecap_ie->ext_id, he_cfg.he_cap.len);
3321 if ((band == BAND_2GHZ) && (bandwidth == BANDWIDTH_20MHZ))
3322 {
3323 he_cfg.he_cap.he_phy_cap[0] &= ~(MBIT(1));
3324 }
3325 }
3326
3327 if (action == MLAN_ACT_DISABLE)
3328 {
3329 if (he_cfg.he_cap.len && (he_cfg.he_cap.ext_id == HE_CAPABILITY))
3330 memset(he_cfg.he_cap.he_txrx_mcs_support, 0xff, sizeof(he_cfg.he_cap.he_txrx_mcs_support));
3331 else
3332 {
3333 PRINTM(MCMND, "11ax already disabled\n");
3334 goto done;
3335 }
3336 }
3337 DBG_HEXDUMP(MCMD_D, "HE_CFG ", (t_u8 *)&he_cfg, sizeof(he_cfg));
3338 ret = wlan_cmd_11ax_cfg(pmpriv, HostCmd_ACT_GEN_SET, &he_cfg);
3339 done:
3340 LEAVE();
3341 return ret;
3342 }
3343 #endif /* CONFIG_11AX */
3344
3345 #if CONFIG_5GHz_SUPPORT
wifi_set_uap_dfs_cac(mlan_private * priv,Band_Config_t * bandcfg,t_u8 ht_enabled)3346 static void wifi_set_uap_dfs_cac(mlan_private *priv, Band_Config_t *bandcfg, t_u8 ht_enabled)
3347 {
3348 if (priv->uap_channel > MAX_CHANNELS_BG)
3349 {
3350 mlan_private *priv_sta = (mlan_private *)mlan_adap->priv[0];
3351 if ((priv_sta->media_connected == MTRUE) && wlan_11h_radar_detect_required(priv, priv->uap_channel))
3352 {
3353 nxp_wifi_dfs_cac_info cacinfo;
3354 t_u8 center_chan = 0;
3355
3356 memset(&cacinfo, 0, sizeof(nxp_wifi_dfs_cac_info));
3357 cacinfo.center_freq = channel_to_frequency(priv->uap_channel, bandcfg->chanBand);
3358 cacinfo.ht_enabled = ht_enabled;
3359 cacinfo.ch_offset = bandcfg->chan2Offset;
3360 cacinfo.center_freq2 = 0;
3361
3362 switch (bandcfg->chanWidth)
3363 {
3364 case CHAN_BW_20MHZ:
3365 if (ht_enabled)
3366 cacinfo.ch_width = CHAN_BAND_WIDTH_20;
3367 else
3368 cacinfo.ch_width = CHAN_BAND_WIDTH_20_NOHT;
3369 cacinfo.center_freq1 = cacinfo.center_freq;
3370 break;
3371
3372 case CHAN_BW_40MHZ:
3373 cacinfo.ch_width = CHAN_BAND_WIDTH_40;
3374 if (bandcfg->chan2Offset == SEC_CHAN_ABOVE)
3375 cacinfo.center_freq1 = cacinfo.center_freq + 10;
3376 else if (bandcfg->chan2Offset == SEC_CHAN_BELOW)
3377 cacinfo.center_freq1 = cacinfo.center_freq - 10;
3378 break;
3379
3380 #if (CONFIG_11AC)
3381 case CHAN_BW_80MHZ:
3382 cacinfo.ch_width = CHAN_BAND_WIDTH_80;
3383 center_chan = wlan_get_center_freq_idx(priv, BAND_AAC, priv->uap_channel, CHANNEL_BW_80MHZ);
3384 cacinfo.center_freq1 = channel_to_frequency(center_chan, bandcfg->chanBand);
3385 break;
3386 #endif
3387
3388 default:
3389 break;
3390 }
3391
3392 /* STA has connected to EXT-AP on DFS channel, then uAP should support start network
3393 * on DFS channel. If DFS is offloaded to the driver, supplicant won't setup uAP until
3394 * the CAC is done by driver. When DFS master mode is not supported, driver needs to
3395 * send the EVENT_DFS_CAC_STARTED event to supplicant to set the cac_started flag, and
3396 * send EVENT_DFS_CAC_FINISHED event to supplicant to continue AP setup for DFS channel */
3397 if (wm_wifi.supp_if_callbk_fns->dfs_cac_started_callbk_fn)
3398 {
3399 wm_wifi.supp_if_callbk_fns->dfs_cac_started_callbk_fn(wm_wifi.hapd_if_priv, &cacinfo);
3400 }
3401 if (wm_wifi.supp_if_callbk_fns->dfs_cac_finished_callbk_fn)
3402 {
3403 wm_wifi.supp_if_callbk_fns->dfs_cac_finished_callbk_fn(wm_wifi.hapd_if_priv, &cacinfo);
3404 }
3405 }
3406 }
3407 }
3408 #endif
3409
wifi_nxp_beacon_config(nxp_wifi_ap_info_t * params)3410 int wifi_nxp_beacon_config(nxp_wifi_ap_info_t *params)
3411 {
3412 mlan_private *priv = (mlan_private *)mlan_adap->priv[1];
3413 mlan_private *remain_priv = NULL;
3414 // mlan_adapter *pmadapter = priv->adapter;
3415
3416 const t_u8 *ie = NULL;
3417 int ret = 0, ie_len;
3418 mlan_uap_bss_param *sys_config = NULL;
3419 // int i = 0;
3420 t_u8 rates_b[5] = {0x82, 0x84, 0x8b, 0x96, 0x00};
3421 t_u8 rates_bg[13] = {0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, 0x00};
3422 #if CONFIG_5GHz_SUPPORT
3423 t_u8 rates_a[9] = {0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c, 0x00};
3424 #endif
3425 t_u8 supported_mcs_set[] = {0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3426 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3427 t_u8 chan2Offset = SEC_CHAN_NONE;
3428 t_u8 enable_11n = MTRUE;
3429 t_u8 bandwidth = BANDWIDTH_40MHZ;
3430 t_u16 ht_cap = 0;
3431 #if CONFIG_11AC
3432 t_u8 enable_11ac = MFALSE;
3433 t_u8 vht20_40 = MFALSE;
3434 IEEEtypes_VHTCap_t *vhtcap_ie = NULL;
3435 IEEEtypes_VHTOprat_t *vhtopr_ie = NULL;
3436 #endif
3437 #if CONFIG_11AX
3438 IEEEtypes_HECap_t *hecap_ie = NULL;
3439 t_u8 enable_11ax = MFALSE;
3440 #endif
3441 Band_Config_t bandcfg;
3442 wifi_scan_chan_list_t scan_chan_list;
3443
3444 ENTER();
3445
3446 (void)bandwidth;
3447
3448 if (!params)
3449 {
3450 return -WM_FAIL;
3451 }
3452
3453 memset(&scan_chan_list, 0, sizeof(wifi_scan_chan_list_t));
3454
3455 ie = (const t_u8 *)params->tail_ie.ie;
3456 ie_len = params->tail_ie.ie_len;
3457 remain_priv = priv->adapter->priv[priv->adapter->remain_bss_index];
3458 if (wifi_is_remain_on_channel() && remain_priv)
3459 {
3460 wuap_d("Cancel Remain on Channel before Starting AP");
3461 wifi_remain_on_channel(false, 0, 0);
3462 }
3463
3464 if (params->beacon_set)
3465 {
3466 ret = wifi_nxp_set_mgmt_ies(priv, params->tail_ie.ie, params->tail_ie.ie_len, params->beacon_ies.ie,
3467 params->beacon_ies.ie_len, params->proberesp_ies.ie, params->proberesp_ies.ie_len,
3468 params->assocresp_ies.ie, params->assocresp_ies.ie_len);
3469 if (ret != WM_SUCCESS)
3470 {
3471 wuap_e("Set uAP mgmt ie failed");
3472 return -WM_FAIL;
3473 }
3474 }
3475 else
3476 {
3477 sys_config = OSA_MemoryAllocate(sizeof(mlan_uap_bss_param));
3478 if (!sys_config)
3479 {
3480 wuap_e("Fail to alloc memory for mlan_uap_bss_param");
3481 ret = -WM_FAIL;
3482 goto done;
3483 }
3484
3485 memset(&bandcfg, 0, sizeof(Band_Config_t));
3486
3487 if (priv->uap_max_sta)
3488 sys_config->max_sta_count = priv->uap_max_sta;
3489
3490 /* Setting the default values */
3491 sys_config->channel = params->chan.channel;
3492 priv->uap_channel = sys_config->channel;
3493 if (priv->uap_channel != 0U)
3494 {
3495 #if CONFIG_5GHz_SUPPORT
3496 if (priv->uap_channel > MAX_CHANNELS_BG)
3497 {
3498 mlan_private *priv_sta = (mlan_private *)mlan_adap->priv[0];
3499 if ((priv_sta->media_connected == MFALSE) && wlan_11h_radar_detect_required(priv, priv->uap_channel))
3500 {
3501 wuap_e("Cannot start uAP on DFS channel %d", priv->uap_channel);
3502 ret = -WM_FAIL;
3503 goto done;
3504 }
3505
3506 bandcfg.chanBand = BAND_5GHZ;
3507 }
3508 else
3509 {
3510 bandcfg.chanBand = BAND_2GHZ;
3511 }
3512 #else
3513 bandcfg.chanBand = BAND_2GHZ;
3514 #endif
3515 }
3516
3517 sys_config->preamble_type = 0;
3518 sys_config->mgmt_ie_passthru_mask = priv->mgmt_frame_passthru_mask;
3519 memcpy(sys_config->mac_addr, params->bssid, ETH_ALEN);
3520
3521 /* Set frag_threshold, rts_threshold, and retry limit */
3522 sys_config->frag_threshold = MLAN_FRAG_MAX_VALUE;
3523 sys_config->rts_threshold = MLAN_RTS_MAX_VALUE;
3524
3525 sys_config->pwe_derivation = params->sae_pwe;
3526
3527 if (params->beacon_int)
3528 sys_config->beacon_period = params->beacon_int;
3529
3530 if (params->dtim_period)
3531 sys_config->dtim_period = params->dtim_period;
3532
3533 if (sys_config->channel <= MAX_CHANNELS_BG)
3534 {
3535 if (sys_config->channel == 14)
3536 {
3537 memcpy(sys_config->rates, rates_b, sizeof(rates_b));
3538 }
3539 else
3540 {
3541 memcpy(sys_config->rates, rates_bg, sizeof(rates_bg));
3542 }
3543 }
3544 #if CONFIG_5GHz_SUPPORT
3545 else
3546 {
3547 memcpy(sys_config->rates, rates_a, sizeof(rates_a));
3548 }
3549 #endif
3550
3551 if (params->chan.ht_enabled != 1)
3552 {
3553 enable_11n = MFALSE;
3554 }
3555
3556 if (params->chan.sec_channel_offset == 1)
3557 {
3558 chan2Offset = SEC_CHAN_ABOVE;
3559 }
3560 else if (params->chan.sec_channel_offset == -1)
3561 {
3562 chan2Offset = SEC_CHAN_BELOW;
3563 }
3564
3565 if (params->chan.bandwidth == 20)
3566 {
3567 bandwidth = BANDWIDTH_20MHZ;
3568 bandcfg.chanWidth = CHAN_BW_20MHZ;
3569 }
3570 else if (params->chan.bandwidth == 40)
3571 {
3572 bandwidth = BANDWIDTH_40MHZ;
3573 bandcfg.chanWidth = CHAN_BW_40MHZ;
3574 }
3575 #if CONFIG_11AC
3576 else if (params->chan.bandwidth == 80)
3577 {
3578 bandwidth = BANDWIDTH_80MHZ;
3579 bandcfg.chanWidth = CHAN_BW_80MHZ;
3580 chan2Offset = wifi_get_second_channel_offset(priv, priv->uap_channel);
3581 }
3582 #endif
3583
3584 bandcfg.chan2Offset = chan2Offset;
3585 (void)memcpy((void *)&sys_config->band_cfg, (const void *)&bandcfg, sizeof(bandcfg));
3586
3587 #if CONFIG_11AC
3588 if (params->chan.vht_enabled == 1)
3589 {
3590 enable_11ac = wifi_check_11ac_capability(priv, bandcfg.chanBand);
3591 if (enable_11ac && ((bandwidth == BANDWIDTH_20MHZ) || (bandwidth == BANDWIDTH_40MHZ)))
3592 {
3593 vht20_40 = MTRUE;
3594 }
3595 }
3596 #endif
3597 #if CONFIG_11AX
3598 if (params->chan.he_enabled == 1)
3599 {
3600 enable_11ax = wifi_check_11ax_capability(priv, bandcfg.chanBand);
3601 }
3602 #endif
3603
3604 /* Disable GreenField by default */
3605 sys_config->ht_cap_info = 0x10c;
3606 if (enable_11n)
3607 sys_config->ht_cap_info |= 0x20;
3608 if (chan2Offset)
3609 {
3610 sys_config->ht_cap_info |= 0x1042;
3611 sys_config->ampdu_param = 3;
3612 }
3613
3614 if (enable_11n)
3615 {
3616 ht_cap = wifi_get_htcap_info(ie, ie_len);
3617 if (ht_cap)
3618 {
3619 if (bandcfg.chanBand == BAND_2GHZ)
3620 sys_config->ht_cap_info = (ht_cap & 0x13ff) | 0x0c;
3621 else
3622 sys_config->ht_cap_info = (ht_cap & 0x13ff) | 0x0c;
3623 }
3624 wifi_d(
3625 "11n=%d, ht_cap=0x%x, channel=%d, bandcfg:chanBand=0x%x chanWidth=0x%x chan2Offset=0x%x "
3626 "scanMode=0x%x\n",
3627 enable_11n, sys_config->ht_cap_info, priv->uap_channel, bandcfg.chanBand, bandcfg.chanWidth,
3628 bandcfg.chan2Offset, bandcfg.scanMode);
3629
3630 ret = wifi_uap_set_httxcfg_int(ht_cap);
3631 if (ret != WM_SUCCESS)
3632 {
3633 wuap_e("Cannot set uAP HT TX Cfg:%x", sys_config->ht_cap_info);
3634 ret = -WM_FAIL;
3635 goto done;
3636 }
3637
3638 sys_config->ampdu_param = 3;
3639
3640 /* Set MCS32 with 40MHz support */
3641 if ((bandcfg.chanWidth == CHAN_BW_40MHZ) || (bandcfg.chanWidth == CHAN_BW_80MHZ))
3642 SETHT_MCS32(supported_mcs_set);
3643
3644 (void)memcpy((void *)sys_config->supported_mcs_set, (const void *)supported_mcs_set,
3645 sizeof(sys_config->supported_mcs_set));
3646 }
3647
3648 if (!params->ssid.ssid_len)
3649 {
3650 ret = -WM_FAIL;
3651 goto done;
3652 }
3653 memcpy(sys_config->ssid.ssid, params->ssid.ssid, MIN(MLAN_MAX_SSID_LENGTH, params->ssid.ssid_len));
3654 sys_config->ssid.ssid_len = MIN(MLAN_MAX_SSID_LENGTH, params->ssid.ssid_len);
3655 /**
3656 * hidden_ssid=0: broadcast SSID in beacons.
3657 * hidden_ssid=1: send empty SSID (length=0) in beacon.
3658 * hidden_ssid=2: clear SSID (ACSII 0), but keep the original length
3659 */
3660 if (!params->hide_ssid)
3661 sys_config->bcast_ssid_ctl = 1;
3662 else if (params->hide_ssid == 1)
3663 sys_config->bcast_ssid_ctl = 0;
3664 else if (params->hide_ssid == 2)
3665 sys_config->bcast_ssid_ctl = 2;
3666
3667 sys_config->auth_mode = MLAN_AUTH_MODE_OPEN;
3668
3669 sys_config->protocol = PROTOCOL_NO_SECURITY;
3670 if ((params->wpa_version & WIFI_NXP_WPA_VERSION_1) && (params->wpa_version & WIFI_NXP_WPA_VERSION_2))
3671 sys_config->protocol = PROTOCOL_WPA | PROTOCOL_WPA2;
3672 else if (params->wpa_version & WIFI_NXP_WPA_VERSION_2)
3673 sys_config->protocol = PROTOCOL_WPA2;
3674 else if (params->wpa_version & WIFI_NXP_WPA_VERSION_1)
3675 sys_config->protocol = PROTOCOL_WPA;
3676
3677 if (params->key_mgmt_suites || (params->privacy && params->wpa_version))
3678 wifi_find_wpa_ies(ie, ie_len, sys_config);
3679
3680 /*find and set wmm ie*/
3681 wifi_set_wmm_ies(priv, ie, ie_len, sys_config);
3682
3683 #if CONFIG_11AC
3684 if (enable_11ac && enable_11n)
3685 {
3686 vhtcap_ie = wifi_get_vhtcap_info(ie, ie_len);
3687 vhtopr_ie = wifi_get_vht_oprat_ie(ie, ie_len);
3688 // Enable VHT80
3689 if (vhtopr_ie && vhtopr_ie->chan_width)
3690 vht20_40 = 0;
3691 wifi_uap_set_11ac_status2(priv, MLAN_ACT_ENABLE, vht20_40, vhtcap_ie);
3692 }
3693 else
3694 {
3695 wifi_uap_set_11ac_status2(priv, MLAN_ACT_DISABLE, vht20_40, NULL);
3696 }
3697 #endif
3698 #if CONFIG_11AX
3699 if (enable_11ax && enable_11n)
3700 {
3701 hecap_ie = (IEEEtypes_HECap_t *)wifi_parse_ext_ie_tlv(ie, ie_len, HE_CAPABILITY);
3702 wifi_uap_set_11ax_status2(priv, MLAN_ACT_ENABLE, bandcfg.chanBand, hecap_ie, bandwidth);
3703 }
3704 else
3705 wifi_uap_set_11ax_status2(priv, MLAN_ACT_DISABLE, bandcfg.chanBand, NULL, bandwidth);
3706 #endif
3707
3708 if (params->ap_max_inactivity)
3709 {
3710 sys_config->sta_ageout_timer = params->ap_max_inactivity * 10;
3711 sys_config->ps_sta_ageout_timer = params->ap_max_inactivity * 10;
3712 }
3713 PRINTM(MIOCTL, "inactivity_timeout=%d\n", params->ap_max_inactivity);
3714 PRINTM(MIOCTL, "sta_ageout_timer=%d ps_sta_ageout_timer=%d\n", sys_config->sta_ageout_timer,
3715 sys_config->ps_sta_ageout_timer);
3716
3717 if (MLAN_STATUS_SUCCESS != wifi_set_get_sys_config(priv, MLAN_ACT_SET, sys_config))
3718 {
3719 wuap_e("Set uAP sys config failed");
3720 ret = -WM_FAIL;
3721 goto done;
3722 }
3723
3724 ret = wifi_nxp_set_mgmt_ies(priv, params->tail_ie.ie, params->tail_ie.ie_len, params->beacon_ies.ie,
3725 params->beacon_ies.ie_len, params->proberesp_ies.ie, params->proberesp_ies.ie_len,
3726 params->assocresp_ies.ie, params->assocresp_ies.ie_len);
3727 if (ret != WM_SUCCESS)
3728 {
3729 wuap_e("Set uAP mgmt ie failed");
3730 ret = -WM_FAIL;
3731 goto done;
3732 }
3733
3734 if (wm_wifi.enable_11d_support && wm_wifi.uap_support_11d_apis)
3735 {
3736 wuap_d("Downloading domain params");
3737 wm_wifi.uap_support_11d_apis->wifi_uap_downld_domain_params_p(BAND_B);
3738 #if CONFIG_5GHz_SUPPORT
3739 wm_wifi.uap_support_11d_apis->wifi_uap_downld_domain_params_p(BAND_A);
3740 #endif
3741 }
3742
3743 #if CONFIG_5GHz_SUPPORT
3744 wifi_set_uap_dfs_cac(priv, &bandcfg, enable_11n);
3745 #endif
3746 priv->uap_host_based = MTRUE;
3747
3748 if (!params->beacon_set)
3749 {
3750 wuap_d("Starting BSS");
3751 /* Start BSS */
3752 if (MLAN_STATUS_SUCCESS != wifi_uap_prepare_and_send_cmd(priv, HOST_CMD_APCMD_BSS_START,
3753 HostCmd_ACT_GEN_SET, 0, NULL, NULL,
3754 MLAN_BSS_TYPE_UAP, NULL))
3755 {
3756 wuap_e("Start BSS failed");
3757 priv->uap_host_based = MFALSE;
3758 ret = -WM_FAIL;
3759 goto done;
3760 }
3761 wuap_d("wlan: AP started");
3762
3763 (void)wifi_set_rx_mgmt_indication(MLAN_BSS_TYPE_UAP, WIFI_MGMT_AUTH | MGMT_MASK_ASSOC_REQ |
3764 MGMT_MASK_REASSOC_REQ | WIFI_MGMT_DEAUTH |
3765 WIFI_MGMT_ACTION | WIFI_MGMT_DIASSOC);
3766 }
3767
3768 done:
3769 if (sys_config != NULL)
3770 {
3771 OSA_MemoryFree(sys_config);
3772 }
3773 }
3774
3775 LEAVE();
3776 return ret;
3777 }
3778
wifi_setup_ht_cap(t_u16 * ht_capab,t_u8 * pmcs_set,t_u8 * a_mpdu_params,t_u8 band)3779 int wifi_setup_ht_cap(t_u16 *ht_capab, t_u8 *pmcs_set, t_u8 *a_mpdu_params, t_u8 band)
3780 {
3781 mlan_private *priv = (mlan_private *)mlan_adap->priv[1];
3782 mlan_adapter *pmadapter = priv->adapter;
3783 t_u32 usr_dot_11n_dev_cap;
3784 int rx_mcs_supp;
3785 t_u8 mcs_set[NUM_MCS_FIELD];
3786
3787 ENTER();
3788
3789 *ht_capab = HT_CAP_INFO_DSSS_CCK40MHZ;
3790
3791 *a_mpdu_params = 3;
3792
3793 #if CONFIG_5GHz_SUPPORT
3794 if (band == BAND_5GHZ)
3795 {
3796 usr_dot_11n_dev_cap = pmadapter->usr_dot_11n_dev_cap_a;
3797 }
3798 else
3799 #endif
3800 {
3801 usr_dot_11n_dev_cap = pmadapter->usr_dot_11n_dev_cap_bg;
3802 }
3803
3804 if (ISSUPP_RXLDPC(usr_dot_11n_dev_cap))
3805 {
3806 *ht_capab |= HT_CAP_INFO_LDPC_CODING_CAP;
3807 }
3808 if (ISSUPP_CHANWIDTH40(usr_dot_11n_dev_cap))
3809 {
3810 *ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
3811 }
3812 else
3813 {
3814 *ht_capab &= ~(HT_CAP_INFO_DSSS_CCK40MHZ);
3815 }
3816 if ((usr_dot_11n_dev_cap >> 20) & 0x03) /* Delayed ACK supported */
3817 {
3818 *ht_capab |= HT_CAP_INFO_DELAYED_BA;
3819 }
3820 if (ISSUPP_GREENFIELD(usr_dot_11n_dev_cap))
3821 {
3822 *ht_capab |= HT_CAP_INFO_GREEN_FIELD;
3823 }
3824 if (ISSUPP_SHORTGI20(usr_dot_11n_dev_cap))
3825 {
3826 *ht_capab |= HT_CAP_INFO_SHORT_GI20MHZ;
3827 }
3828 if (ISSUPP_SHORTGI40(usr_dot_11n_dev_cap))
3829 {
3830 *ht_capab |= HT_CAP_INFO_SHORT_GI40MHZ;
3831 }
3832 if (ISSUPP_TXSTBC(usr_dot_11n_dev_cap))
3833 {
3834 *ht_capab |= HT_CAP_INFO_TX_STBC;
3835 }
3836 if (ISSUPP_RXSTBC(usr_dot_11n_dev_cap))
3837 {
3838 *ht_capab |= HT_CAP_INFO_RX_STBC_1;
3839 }
3840 if (ISSUPP_MIMOPS(usr_dot_11n_dev_cap))
3841 {
3842 *ht_capab |= HT_CAP_INFO_SMPS_STATIC;
3843 }
3844 else
3845 {
3846 *ht_capab |= HT_CAP_INFO_SMPS_DISABLED;
3847 }
3848 if (ISSUPP_MAXAMSDU(usr_dot_11n_dev_cap))
3849 {
3850 *ht_capab |= HT_CAP_INFO_MAX_AMSDU_SIZE;
3851 }
3852 if (ISENABLED_40MHZ_INTOLARENT(usr_dot_11n_dev_cap))
3853 {
3854 *ht_capab |= HT_CAP_INFO_40MHZ_INTOLERANT;
3855 }
3856
3857 rx_mcs_supp = GET_RXMCSSUPP(pmadapter->usr_dev_mcs_support);
3858 /* Set MCS for 1x1/2x2 */
3859 (void)__memset(pmadapter, (t_u8 *)mcs_set, 0xff, rx_mcs_supp);
3860 /* Clear all the other values */
3861 (void)__memset(pmadapter, (t_u8 *)&mcs_set[rx_mcs_supp], 0, NUM_MCS_FIELD - rx_mcs_supp);
3862 /* Set MCS32 with 40MHz support */
3863 if (ISSUPP_CHANWIDTH40(usr_dot_11n_dev_cap))
3864 SETHT_MCS32(mcs_set);
3865
3866 (void)__memcpy(pmadapter, pmcs_set, mcs_set, NUM_MCS_FIELD);
3867
3868 LEAVE();
3869
3870 return WM_SUCCESS;
3871 }
3872
wifi_get_default_ht_capab()3873 t_u16 wifi_get_default_ht_capab()
3874 {
3875 t_u16 ht_capab;
3876 t_u8 mcs_set[16];
3877 t_u8 a_mpdu_params;
3878
3879 wifi_setup_ht_cap(&ht_capab, &mcs_set[0], &a_mpdu_params, 0);
3880
3881 return ht_capab;
3882 }
3883
wifi_setup_channel_flag(void * channels,int num_chan,region_chan_t * region,t_u8 band)3884 static void wifi_setup_channel_flag(void *channels, int num_chan, region_chan_t *region, t_u8 band)
3885 {
3886 int i;
3887 int set_idx = 0;
3888 int get_idx = 0;
3889 const chan_freq_power_t *pchans_get = region->pcfp;
3890 struct wifi_nxp_event_channel *pchans_set = (struct wifi_nxp_event_channel *)channels;
3891
3892 for (i = 0; i < MAX(num_chan, region->num_cfp); i++)
3893 {
3894 if (set_idx >= num_chan)
3895 break;
3896
3897 if (get_idx >= region->num_cfp)
3898 {
3899 pchans_set[set_idx].wifi_nxp_flags |= WIFI_NXP_CHAN_FLAG_FREQUENCY_DISABLED;
3900
3901 set_idx++;
3902 }
3903 else
3904 {
3905 pchans_set[set_idx].center_frequency = pchans_get[get_idx].freq;
3906 pchans_set[set_idx].ch_valid = 1;
3907 pchans_set[set_idx].wifi_nxp_max_power = pchans_get[get_idx].max_tx_power;
3908 pchans_set[set_idx].wifi_nxp_flags &= (~WIFI_NXP_CHAN_FLAG_FREQUENCY_DISABLED);
3909
3910 if (band == BAND_2GHZ)
3911 {
3912 pchans_set[set_idx].wifi_nxp_flags |= WIFI_NXP_CHAN_FLAG_FREQUENCY_ATTR_NO_80MHZ;
3913 }
3914
3915 pchans_set[set_idx].wifi_nxp_flags |= WIFI_NXP_CHAN_FLAG_FREQUENCY_ATTR_NO_160MHZ;
3916
3917 /* set passive scan or radar detect flag */
3918 if (pchans_get[get_idx].passive_scan_or_radar_detect == MTRUE)
3919 {
3920 pchans_set[set_idx].wifi_nxp_flags |= WIFI_NXP_CHAN_FLAG_FREQUENCY_ATTR_RADAR;
3921 pchans_set[set_idx].wifi_nxp_flags |= WIFI_NXP_CHAN_DFS_VALID;
3922 }
3923
3924 set_idx++;
3925 get_idx++;
3926 }
3927 }
3928 }
3929
wifi_setup_channel_info(void * channels,int num_channels,t_u8 band)3930 void wifi_setup_channel_info(void *channels, int num_channels, t_u8 band)
3931 {
3932 mlan_adapter *pmadapter = (mlan_adapter *)mlan_adap;
3933 region_chan_t *region = NULL;
3934
3935 if (band == BAND_2GHZ)
3936 {
3937 if (pmadapter->region_channel[0].valid)
3938 region = &pmadapter->region_channel[0];
3939 else if (pmadapter->universal_channel[0].valid)
3940 region = &pmadapter->universal_channel[0];
3941 else
3942 return;
3943
3944 wifi_setup_channel_flag(channels, num_channels, region, band);
3945 }
3946 else if (band == BAND_5GHZ)
3947 {
3948 if (pmadapter->region_channel[1].valid)
3949 region = &pmadapter->region_channel[1];
3950 else if (pmadapter->universal_channel[1].valid)
3951 region = &pmadapter->universal_channel[1];
3952 else
3953 return;
3954
3955 wifi_setup_channel_flag(channels, num_channels, region, band);
3956 }
3957 else
3958 {
3959 wuap_e("wifi_setup_channel_info unsupported band %d", band);
3960 }
3961 }
3962
3963 #if CONFIG_11AC
wifi_setup_vht_cap(t_u32 * vht_capab,t_u8 * vht_mcs_set,t_u8 band)3964 int wifi_setup_vht_cap(t_u32 *vht_capab, t_u8 *vht_mcs_set, t_u8 band)
3965 {
3966 mlan_private *priv = (mlan_private *)mlan_adap->priv[1];
3967 mlan_adapter *pmadapter = priv->adapter;
3968 // t_u32 usr_dot_11ac_dev_cap;
3969 t_u16 vht_tx_mcs, vht_rx_mcs;
3970
3971 ENTER();
3972
3973 *vht_capab = pmadapter->usr_dot_11ac_dev_cap_a;
3974
3975 *vht_capab &= ~DEFALUT_11AC_CAP_BEAMFORMING_RESET_MASK;
3976 #ifdef RW610
3977 *vht_capab &= ~DEFALUT_11AC_CAP_SHORTGI_80MHZ_RESET_MASK;
3978 #endif
3979
3980 if ((GET_VHTCAP_MAXMPDULEN(*vht_capab)) != 0U)
3981 {
3982 RESET_11ACMAXMPDULEN(*vht_capab);
3983 }
3984 else
3985 {
3986 /** Do Nothing */
3987 }
3988
3989 vht_tx_mcs = pmadapter->usr_dot_11ac_mcs_support >> 16;
3990 vht_rx_mcs = pmadapter->usr_dot_11ac_mcs_support & 0xffff;
3991
3992 (void)__memcpy(pmadapter, &vht_mcs_set[0], &vht_rx_mcs, sizeof(t_u16));
3993
3994 (void)__memcpy(pmadapter, &vht_mcs_set[4], &vht_tx_mcs, sizeof(t_u16));
3995
3996 LEAVE();
3997
3998 return WM_SUCCESS;
3999 }
4000
wifi_get_default_vht_capab()4001 t_u32 wifi_get_default_vht_capab()
4002 {
4003 t_u32 vht_capab;
4004 t_u8 vht_mcs_set[8];
4005
4006 wifi_setup_vht_cap(&vht_capab, &vht_mcs_set[0], 0);
4007
4008 return vht_capab;
4009 }
4010 #endif
4011
4012 #if CONFIG_11AX
4013 /*
4014 ===============
4015 11AX CAP for uAP
4016 ===============
4017 Note: bits not mentioned below are set to 0.
4018
4019 5G
4020 ===
4021 HE MAC Cap:
4022 Bit0: 1 (+HTC HE Support)
4023 Bit25: 1 (OM Control Support. But uAP does not support
4024 Tx OM received from the STA, as it does not support UL OFDMA)
4025
4026 HE PHY Cap:
4027 Bit1-7: 0x2 (Supported Channel Width Set.
4028 Note it would be changed after 80+80 MHz is supported)
4029 Bit8-11: 0x3 (Punctured Preamble Rx.
4030 Note: it would be changed after 80+80 MHz is supported)
4031 Bit12: 0x0 (Device Class)
4032 Bit13: 0x1 (LDPC coding in Payload)
4033 Bit17: 0x1 (NDP with 4xHE-LTF+3.2usGI)
4034 Bit18: 0x1 (STBC Tx <= 80 MHz)
4035 Bit19: 0x1 (STBC Rx <= 80 MHz)
4036 Bit20: 0x1 (Doppler Tx)
4037 Bit21: 0x1 (Doppler Rx)
4038 Bit24-25: 0x1 (DCM Max Constellation Tx)
4039 Bit27-28: 0x1 (DCM Max Constellation Rx)
4040 Bit31: 0x1 (SU Beamformer)
4041 Bit32: 0x1 (SU BeamFormee)
4042 Bit34-36: 0x7 (Beamformee STS <= 80 MHz)
4043 Bit40-42: 0x1 (Number of Sounding Dimentions <= 80 MHz)
4044 Bit53: 0x1 (Partial Bandwidth Extended Range)
4045 Bit55: 0x1 (PPE Threshold Present.
4046 Note: PPE threshold may have some changes later)
4047 Bit58: 0x1 (HE SU PPDU and HE MU PPDU with 4xHE-LTF+0.8usGI)
4048 Bit59-61: 0x1 (Max Nc)
4049 Bit64: 0x1 (HE ER SU PPDU with 4xHE-LTF+0.8usGI)
4050 Bit75: 0x1 (Rx 1024-QAM Support < 242-tone RU)
4051 */
4052
4053 #define UAP_HE_MAC_CAP0_MASK 0x04
4054 #define UAP_HE_MAC_CAP1_MASK 0x00
4055 #define UAP_HE_MAC_CAP2_MASK 0x10
4056 #define UAP_HE_MAC_CAP3_MASK 0x02
4057 #define UAP_HE_MAC_CAP4_MASK 0x00
4058 #define UAP_HE_MAC_CAP5_MASK 0x00
4059 #define UAP_HE_PHY_CAP0_MASK 0x04
4060 #define UAP_HE_PHY_CAP1_MASK 0x23
4061 #define UAP_HE_PHY_CAP2_MASK 0x3E
4062 #define UAP_HE_PHY_CAP3_MASK 0x89
4063 #define UAP_HE_PHY_CAP4_MASK 0x1D
4064 #define UAP_HE_PHY_CAP5_MASK 0x01
4065 #define UAP_HE_PHY_CAP6_MASK 0xA0
4066 #define UAP_HE_PHY_CAP7_MASK 0x0C
4067 #define UAP_HE_PHY_CAP8_MASK 0x01
4068 #define UAP_HE_PHY_CAP9_MASK 0x08
4069 #define UAP_HE_PHY_CAP10_MASK 0x00
4070
4071 /*
4072 2G
4073 ===
4074 HE MAC Cap:
4075 Bit0: 1 (+HTC HE Support)
4076 Bit25: 1 (OM Control Support. Note: uAP does not support
4077 Tx OM received from the STA, as it does not support UL OFDMA)
4078
4079 HE PHY Cap:
4080 Bit1-7: 0x1 (Supported Channel Width Set)
4081 Bit8-11: 0x0 (Punctured Preamble Rx)
4082 Bit12: 0x0 (Device Class)
4083 Bit13: 0x1 (LDPC coding in Payload)
4084 Bit17: 0x1 (NDP with 4xLTF+3.2usGI)
4085 Bit18: 0x1 (STBC Tx <= 80 MHz)
4086 Bit19: 0x1 (STBC Rx <= 80 MHz)
4087 Bit20: 0x1 (Doppler Tx)
4088 Bit21: 0x1 (Doppler Rx)
4089 Bit24-25: 0x1 (DCM Max Constellation Tx)
4090 Bit27-28: 0x1 (DCM Max Constellation Rx)
4091 Bit31: 0x1 (SU Beamformer)
4092 Bit32: 0x1 (SU BeamFormee)
4093 Bit34-36: 0x7 (Beamformee STS <= 80 MHz)
4094 Bit40-42: 0x1 (Number of Sounding Dimentions <= 80 MHz)
4095 Bit53: 0x1 (Partial Bandwidth Extended Range)
4096 Bit55: 0x1 (PPE Threshold Present.
4097 Note: PPE threshold may have some changes later)
4098 Bit58: 0x1 (HE SU PPDU and HE MU PPDU with 4xHE-LTF+0.8usGI)
4099 Bit59-61: 0x1 (Max Nc)
4100 Bit64: 0x1 (HE ER SU PPDU with 4xHE-LTF+0.8usGI)
4101 Bit75: 0x1 (Rx 1024-QAM Support < 242-tone RU)
4102 */
4103 #define UAP_HE_2G_MAC_CAP0_MASK 0x04
4104 #define UAP_HE_2G_MAC_CAP1_MASK 0x00
4105 #define UAP_HE_2G_MAC_CAP2_MASK 0x10
4106 #define UAP_HE_2G_MAC_CAP3_MASK 0x02
4107 #define UAP_HE_2G_MAC_CAP4_MASK 0x00
4108 #define UAP_HE_2G_MAC_CAP5_MASK 0x00
4109 #define UAP_HE_2G_PHY_CAP0_MASK 0x02
4110 #define UAP_HE_2G_PHY_CAP1_MASK 0x20
4111 #define UAP_HE_2G_PHY_CAP2_MASK 0x3E
4112 #define UAP_HE_2G_PHY_CAP3_MASK 0x89
4113 #define UAP_HE_2G_PHY_CAP4_MASK 0x1D
4114 #define UAP_HE_2G_PHY_CAP5_MASK 0x01
4115 #define UAP_HE_2G_PHY_CAP6_MASK 0xA0
4116 #define UAP_HE_2G_PHY_CAP7_MASK 0x0C
4117 #define UAP_HE_2G_PHY_CAP8_MASK 0x01
4118 #define UAP_HE_2G_PHY_CAP9_MASK 0x08
4119 #define UAP_HE_2G_PHY_CAP10_MASK 0x00
4120
4121 /**
4122 * @brief update 11ax ie for AP mode *
4123 * @param band channel band
4124 * @hecap_ie a pointer to mlan_ds_11ax_he_capa
4125 *
4126 * @return 0--success, otherwise failure
4127 */
wifi_uap_update_11ax_ie(t_u8 band,mlan_ds_11ax_he_capa * hecap_ie)4128 static void wifi_uap_update_11ax_ie(t_u8 band, mlan_ds_11ax_he_capa *hecap_ie)
4129 {
4130 if (band == BAND_5GHZ
4131 #ifdef ENABLE_802_116E
4132 || band == BAND_6GHZ
4133 #endif
4134 )
4135 {
4136 hecap_ie->he_mac_cap[0] &= UAP_HE_MAC_CAP0_MASK;
4137 hecap_ie->he_mac_cap[1] &= UAP_HE_MAC_CAP1_MASK;
4138 hecap_ie->he_mac_cap[2] &= UAP_HE_MAC_CAP2_MASK;
4139 hecap_ie->he_mac_cap[3] &= UAP_HE_MAC_CAP3_MASK;
4140 hecap_ie->he_mac_cap[4] &= UAP_HE_MAC_CAP4_MASK;
4141 hecap_ie->he_mac_cap[5] &= UAP_HE_MAC_CAP5_MASK;
4142 hecap_ie->he_phy_cap[0] &= UAP_HE_PHY_CAP0_MASK;
4143 hecap_ie->he_phy_cap[1] &= UAP_HE_PHY_CAP1_MASK;
4144 hecap_ie->he_phy_cap[2] &= UAP_HE_PHY_CAP2_MASK;
4145 hecap_ie->he_phy_cap[3] &= UAP_HE_PHY_CAP3_MASK;
4146 hecap_ie->he_phy_cap[4] &= UAP_HE_PHY_CAP4_MASK;
4147 hecap_ie->he_phy_cap[5] &= UAP_HE_PHY_CAP5_MASK;
4148 hecap_ie->he_phy_cap[6] &= UAP_HE_PHY_CAP6_MASK;
4149 hecap_ie->he_phy_cap[7] &= UAP_HE_PHY_CAP7_MASK;
4150 hecap_ie->he_phy_cap[8] &= UAP_HE_PHY_CAP8_MASK;
4151 hecap_ie->he_phy_cap[9] &= UAP_HE_PHY_CAP9_MASK;
4152 hecap_ie->he_phy_cap[10] &= UAP_HE_PHY_CAP10_MASK;
4153 }
4154 else
4155 {
4156 hecap_ie->he_mac_cap[0] &= UAP_HE_2G_MAC_CAP0_MASK;
4157 hecap_ie->he_mac_cap[1] &= UAP_HE_2G_MAC_CAP1_MASK;
4158 hecap_ie->he_mac_cap[2] &= UAP_HE_2G_MAC_CAP2_MASK;
4159 hecap_ie->he_mac_cap[3] &= UAP_HE_2G_MAC_CAP3_MASK;
4160 hecap_ie->he_mac_cap[4] &= UAP_HE_2G_MAC_CAP4_MASK;
4161 hecap_ie->he_mac_cap[5] &= UAP_HE_2G_MAC_CAP5_MASK;
4162 hecap_ie->he_phy_cap[0] &= UAP_HE_2G_PHY_CAP0_MASK;
4163 hecap_ie->he_phy_cap[1] &= UAP_HE_2G_PHY_CAP1_MASK;
4164 hecap_ie->he_phy_cap[2] &= UAP_HE_2G_PHY_CAP2_MASK;
4165 hecap_ie->he_phy_cap[3] &= UAP_HE_2G_PHY_CAP3_MASK;
4166 hecap_ie->he_phy_cap[4] &= UAP_HE_2G_PHY_CAP4_MASK;
4167 hecap_ie->he_phy_cap[5] &= UAP_HE_2G_PHY_CAP5_MASK;
4168 hecap_ie->he_phy_cap[6] &= UAP_HE_2G_PHY_CAP6_MASK;
4169 hecap_ie->he_phy_cap[7] &= UAP_HE_2G_PHY_CAP7_MASK;
4170 hecap_ie->he_phy_cap[8] &= UAP_HE_2G_PHY_CAP8_MASK;
4171 hecap_ie->he_phy_cap[9] &= UAP_HE_2G_PHY_CAP9_MASK;
4172 hecap_ie->he_phy_cap[10] &= UAP_HE_2G_PHY_CAP10_MASK;
4173 }
4174 return;
4175 }
4176
4177 #if 1
4178 /**
4179 * @brief Sets up the CFG802.11 specific HE capability fields * with default
4180 * values
4181 *
4182 * @param priv A pointer to moal private structure
4183 * @param iftype_data A pointer to ieee80211_sband_iftype_data structure
4184 *
4185 * @return N/A
4186 */
wifi_setup_he_cap(nxp_wifi_he_capabilities * he_cap,t_u8 band)4187 int wifi_setup_he_cap(nxp_wifi_he_capabilities *he_cap, t_u8 band)
4188 {
4189 mlan_private *priv = (mlan_private *)mlan_adap->priv[1];
4190
4191 mlan_fw_info fw_info;
4192 t_u8 extra_mcs_size = 0;
4193 int ppe_threshold_len = 0;
4194 mlan_ds_11ax_he_capa *phe_cap = NULL;
4195 t_u8 hw_hecap_len = 0;
4196
4197 memset(&fw_info, 0, sizeof(mlan_fw_info));
4198
4199 wifi_request_get_fw_info(priv, &fw_info);
4200
4201 #if CONFIG_5GHz_SUPPORT
4202 if (band == BAND_5GHZ)
4203 {
4204 phe_cap = (mlan_ds_11ax_he_capa *)fw_info.hw_he_cap;
4205 hw_hecap_len = fw_info.hw_hecap_len;
4206 wifi_uap_update_11ax_ie(BAND_5GHZ, phe_cap);
4207 }
4208 else
4209 #endif
4210 #ifdef ENABLE_802_116E
4211 if (band == BAND_6GHZ)
4212 {
4213 phe_cap = (mlan_ds_11ax_he_capa *)fw_info.hw_he_cap;
4214 hw_hecap_len = fw_info.hw_hecap_len;
4215 wifi_uap_update_11ax_ie(BAND_6GHZ, phe_cap);
4216 }
4217 else
4218 #endif
4219 {
4220 phe_cap = (mlan_ds_11ax_he_capa *)fw_info.hw_2g_he_cap;
4221 hw_hecap_len = fw_info.hw_2g_hecap_len;
4222 wifi_uap_update_11ax_ie(BAND_2GHZ, phe_cap);
4223 }
4224
4225 if (!hw_hecap_len)
4226 return -WM_FAIL;
4227
4228 he_cap->he_supported = 1;
4229 (void)__memcpy(priv, he_cap->mac_cap, phe_cap->he_mac_cap, sizeof(phe_cap->he_mac_cap));
4230 (void)__memcpy(priv, he_cap->phy_cap, phe_cap->he_phy_cap, sizeof(phe_cap->he_phy_cap));
4231 memset(&he_cap->mcs, 0xff, WIFI_HE_MAX_MCS_CAPAB_SIZE);
4232 (void)__memcpy(priv, &he_cap->mcs, phe_cap->he_txrx_mcs_support, sizeof(phe_cap->he_txrx_mcs_support));
4233
4234 // Support 160Mhz
4235 if (phe_cap->he_phy_cap[0] & MBIT(3))
4236 extra_mcs_size += 4;
4237
4238 // Support 80+80
4239 if (phe_cap->he_phy_cap[0] & MBIT(4))
4240 extra_mcs_size += 4;
4241 if (extra_mcs_size)
4242 (void)__memcpy(priv, (t_u8 *)&he_cap->mcs + sizeof(phe_cap->he_txrx_mcs_support), phe_cap->val, extra_mcs_size);
4243
4244 #define HE_CAP_FIX_SIZE 22
4245 // Support PPE threshold
4246 ppe_threshold_len = phe_cap->len - HE_CAP_FIX_SIZE - extra_mcs_size;
4247 if (phe_cap->he_phy_cap[6] & MBIT(7) && ppe_threshold_len)
4248 {
4249 (void)__memcpy(priv, he_cap->ppet, &phe_cap->val[extra_mcs_size], ppe_threshold_len);
4250 }
4251 else
4252 {
4253 he_cap->phy_cap[6] &= ~MBIT(7);
4254 wifi_d("Clear PPE threshold 0x%x\r\n", he_cap->phy_cap[7]);
4255 }
4256 #ifdef ENABLE_802_116E
4257 if (band->band == BAND_6GHZ)
4258 iftype_data->he_6ghz_capa.capa = fw_info.hw_he_6g_cap;
4259 #endif
4260 LEAVE();
4261
4262 return WM_SUCCESS;
4263 }
4264 #else
4265 /**
4266 * @brief setup uap he_cap based on FW he_cap
4267 *
4268 * @param priv A pointer to moal private structure
4269 * @param wait_option wait_option
4270 *
4271 * @return N/A
4272 */
woal_cfg80211_setup_uap_he_cap(moal_private * priv,t_u8 wait_option)4273 void woal_cfg80211_setup_uap_he_cap(moal_private *priv, t_u8 wait_option)
4274 {
4275 mlan_ds_11ax_he_capa *phe_cap = NULL;
4276 mlan_ds_11ax_he_cfg he_cfg;
4277 t_u8 hw_hecap_len;
4278 mlan_fw_info fw_info;
4279 #ifdef UAP_SUPPORT
4280 int ret = 0;
4281 #endif
4282
4283 woal_request_get_fw_info(priv, MOAL_IOCTL_WAIT, &fw_info);
4284
4285 // Enable 2G 11AX on UAP
4286 if (fw_info.fw_bands & BAND_GAX)
4287 {
4288 memset(&he_cfg, 0, sizeof(he_cfg));
4289 phe_cap = (mlan_ds_11ax_he_capa *)fw_info.hw_2g_he_cap;
4290 hw_hecap_len = fw_info.hw_2g_hecap_len;
4291 if (hw_hecap_len)
4292 {
4293 woal_uap_update_11ax_ie(BAND_2GHZ, phe_cap);
4294 he_cfg.band = MBIT(0);
4295 moal_memcpy_ext(priv->phandle, &he_cfg.he_cap, phe_cap, hw_hecap_len, sizeof(mlan_ds_11ax_he_capa));
4296 DBG_HEXDUMP(MCMD_D, "2G HE_CFG ", (t_u8 *)&he_cfg, sizeof(he_cfg));
4297 #ifdef UAP_SUPPORT
4298 ret = woal_11ax_cfg(priv, MLAN_ACT_SET, &he_cfg, wait_option);
4299 if (ret)
4300 PRINTM(MERROR, "Fail to set 2G HE CAP\n");
4301 #endif
4302 }
4303 }
4304 #ifdef ENABLE_802_11A
4305 // Enable 5G 11AX on UAP
4306 if (fw_info.fw_bands & BAND_AAX)
4307 {
4308 memset(&he_cfg, 0, sizeof(he_cfg));
4309 phe_cap = (mlan_ds_11ax_he_capa *)fw_info.hw_he_cap;
4310 hw_hecap_len = fw_info.hw_hecap_len;
4311 if (hw_hecap_len)
4312 {
4313 woal_uap_update_11ax_ie(BAND_5GHZ, phe_cap);
4314 he_cfg.band = MBIT(1);
4315 moal_memcpy_ext(priv->phandle, &he_cfg.he_cap, phe_cap, hw_hecap_len, sizeof(mlan_ds_11ax_he_capa));
4316 DBG_HEXDUMP(MCMD_D, "5G HE_CFG ", (t_u8 *)&he_cfg, sizeof(he_cfg));
4317 #ifdef UAP_SUPPORT
4318 ret = woal_11ax_cfg(priv, MLAN_ACT_SET, &he_cfg, wait_option);
4319 if (ret)
4320 PRINTM(MERROR, "Fail to set 5G HE CAP\n");
4321 #endif
4322 }
4323 }
4324 #endif
4325 return;
4326 }
4327 #endif
4328 #endif
4329
4330 /**
4331 * @brief Set/Get sta information parameters
4332 *
4333 * @param priv A pointer to moal_private structure
4334 * @param action MLAN_ACT_SET or MLAN_ACT_GET
4335 * @param wait_option Wait option
4336 * @param sys_cfg A pointer to mlan_uap_bss_param structure
4337 *
4338 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
4339 */
wifi_uap_sta_info(mlan_private * priv,t_u16 action,mlan_ds_sta_info * sta_info)4340 static mlan_status wifi_uap_sta_info(mlan_private *priv, t_u16 action, mlan_ds_sta_info *sta_info)
4341 {
4342 int ret;
4343 mlan_ds_bss bss;
4344 mlan_ioctl_req ioctl_buf;
4345
4346 ENTER();
4347
4348 (void)memset(&bss, 0x00, sizeof(mlan_ds_bss));
4349
4350 bss.sub_command = MLAN_OID_UAP_ADD_STATION;
4351
4352 // if (action == HostCmd_ACT_ADD_STA)
4353 memcpy((void *)&bss.param.sta_info, (const void *)sta_info, sizeof(mlan_ds_sta_info) + (size_t)sta_info->tlv_len);
4354
4355 (void)memset(&ioctl_buf, 0x00, sizeof(mlan_ioctl_req));
4356
4357 ioctl_buf.req_id = (t_u32)MLAN_IOCTL_BSS;
4358 /** Pointer to buffer */
4359 ioctl_buf.pbuf = (t_u8 *)&bss;
4360
4361 ret = wifi_uap_prepare_and_send_cmd(priv, HostCmd_CMD_ADD_NEW_STATION, action, 0, &ioctl_buf, NULL,
4362 MLAN_BSS_TYPE_UAP, NULL);
4363 if (ret != WM_SUCCESS)
4364 {
4365 return MLAN_STATUS_FAILURE;
4366 }
4367
4368 return MLAN_STATUS_SUCCESS;
4369 }
4370
4371 /**
4372 * @brief uap remove sta
4373 *
4374 * @param priv A pointer to moal_private structure
4375 * @param addr A pointer to mac address
4376 *
4377 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
4378 */
wifi_uap_sta_remove(mlan_private * priv,const uint8_t * addr)4379 static mlan_status wifi_uap_sta_remove(mlan_private *priv, const uint8_t *addr)
4380 {
4381 int ret;
4382 mlan_deauth_param data_buf;
4383
4384 ENTER();
4385
4386 (void)memset(&data_buf, 0x00, sizeof(data_buf));
4387
4388 memcpy((void *)data_buf.mac_addr, (const void *)addr, sizeof(data_buf.mac_addr));
4389 data_buf.reason_code = WLAN_REASON_UNSPECIFIED;
4390
4391 ret = wifi_uap_prepare_and_send_cmd(priv, HOST_CMD_APCMD_STA_DEAUTH, 0, 0, NULL, &data_buf,
4392 MLAN_BSS_TYPE_UAP, NULL);
4393 if (ret != WM_SUCCESS)
4394 {
4395 return MLAN_STATUS_FAILURE;
4396 }
4397
4398 return MLAN_STATUS_SUCCESS;
4399 }
4400
wifi_nxp_sta_add(nxp_wifi_sta_info_t * params)4401 int wifi_nxp_sta_add(nxp_wifi_sta_info_t *params)
4402 {
4403 mlan_private *priv = (mlan_private *)mlan_adap->priv[1];
4404 int ret = 0;
4405 mlan_ds_sta_info *sta_info = NULL;
4406 t_u8 *pos;
4407 t_u8 qosinfo;
4408 MrvlIEtypes_Data_t *tlv;
4409 t_u32 req_len = 0;
4410 #if CONFIG_11AX
4411 MrvlExtIEtypes_Data_t *ext_tlv;
4412 #endif
4413
4414 ENTER();
4415
4416 if (!params)
4417 {
4418 ret = -WM_FAIL;
4419 goto done;
4420 }
4421
4422 req_len = sizeof(mlan_ds_sta_info);
4423 if (params->ext_capab_len)
4424 req_len += sizeof(MrvlIEtypesHeader_t) + params->ext_capab_len;
4425 if (params->supp_rates_len)
4426 req_len += sizeof(MrvlIEtypesHeader_t) + params->supp_rates_len;
4427 if (params->qosinfo)
4428 req_len += sizeof(MrvlIEtypesHeader_t) + sizeof(qosinfo);
4429 if (params->ht_capab_len)
4430 req_len += sizeof(MrvlIEtypesHeader_t) + sizeof(ieee80211_ht_capab_t);
4431 #if CONFIG_11AC
4432 if (params->vht_capab_len)
4433 req_len += sizeof(MrvlIEtypesHeader_t) + sizeof(ieee80211_vht_capab_t);
4434 #endif
4435
4436 #if CONFIG_11AX
4437 if (params->he_capab_len)
4438 req_len += sizeof(MrvlExtIEtypesHeader_t) + params->he_capab_len;
4439 #endif
4440
4441 sta_info = OSA_MemoryAllocate(req_len);
4442 if (!sta_info)
4443 {
4444 wuap_e("Fail to alloc memory for mlan_ds_sta_info");
4445 ret = -WM_FAIL;
4446 goto done;
4447 }
4448
4449 memset(sta_info, 0x00, req_len);
4450
4451 sta_info->listen_interval = params->listen_interval;
4452 sta_info->aid = params->aid;
4453 sta_info->cap_info = params->capability;
4454 sta_info->tlv_len = 0;
4455 sta_info->sta_flags = params->flags;
4456
4457 memcpy(sta_info->peer_mac, params->addr, MLAN_MAC_ADDR_LENGTH);
4458
4459 wuap_d("wlan: UAP/GO add peer station, address =" MACSTR "", MAC2STR(params->addr));
4460
4461 wuap_d("sta_flags=0x%x listen_interval=%d aid=%d cap_info=0x%x", params->flags, params->listen_interval,
4462 params->aid, params->capability);
4463
4464 pos = &sta_info->tlv[0];
4465 if (params->ext_capab_len)
4466 {
4467 tlv = (MrvlIEtypes_Data_t *)pos;
4468 tlv->header.type = EXT_CAPABILITY;
4469 tlv->header.len = params->ext_capab_len;
4470 memcpy(tlv->data, params->ext_capab, tlv->header.len);
4471 pos += sizeof(MrvlIEtypesHeader_t) + tlv->header.len;
4472 sta_info->tlv_len += sizeof(MrvlIEtypesHeader_t) + tlv->header.len;
4473 tlv = (MrvlIEtypes_Data_t *)pos;
4474 }
4475 if (params->supp_rates_len)
4476 {
4477 tlv = (MrvlIEtypes_Data_t *)pos;
4478 tlv->header.type = SUPPORTED_RATES;
4479 tlv->header.len = params->supp_rates_len;
4480 memcpy(tlv->data, params->supp_rates, tlv->header.len);
4481 pos += sizeof(MrvlIEtypesHeader_t) + tlv->header.len;
4482 sta_info->tlv_len += sizeof(MrvlIEtypesHeader_t) + tlv->header.len;
4483 tlv = (MrvlIEtypes_Data_t *)pos;
4484 }
4485 if (params->qosinfo)
4486 {
4487 tlv = (MrvlIEtypes_Data_t *)pos;
4488 tlv->header.type = QOS_INFO;
4489 tlv->header.len = sizeof(qosinfo);
4490 qosinfo = params->qosinfo;
4491 memcpy(tlv->data, &qosinfo, tlv->header.len);
4492 pos += sizeof(MrvlIEtypesHeader_t) + tlv->header.len;
4493 sta_info->tlv_len += sizeof(MrvlIEtypesHeader_t) + tlv->header.len;
4494 tlv = (MrvlIEtypes_Data_t *)pos;
4495 }
4496 if (params->ht_capab_len)
4497 {
4498 tlv = (MrvlIEtypes_Data_t *)pos;
4499 tlv->header.type = HT_CAPABILITY;
4500 tlv->header.len = sizeof(ieee80211_ht_capab_t);
4501 memcpy(tlv->data, ¶ms->ht_capab, tlv->header.len);
4502 pos += sizeof(MrvlIEtypesHeader_t) + tlv->header.len;
4503 sta_info->tlv_len += sizeof(MrvlIEtypesHeader_t) + tlv->header.len;
4504 tlv = (MrvlIEtypes_Data_t *)pos;
4505 }
4506 #if CONFIG_11AC
4507 if (params->vht_capab_len)
4508 {
4509 tlv = (MrvlIEtypes_Data_t *)pos;
4510 tlv->header.type = VHT_CAPABILITY;
4511 tlv->header.len = sizeof(ieee80211_vht_capab_t);
4512 memcpy(tlv->data, ¶ms->vht_capab, tlv->header.len);
4513 pos += sizeof(MrvlIEtypesHeader_t) + tlv->header.len;
4514 sta_info->tlv_len += sizeof(MrvlIEtypesHeader_t) + tlv->header.len;
4515 tlv = (MrvlIEtypes_Data_t *)pos;
4516 }
4517 #endif
4518 #if CONFIG_11AX
4519 if (params->he_capab_len)
4520 {
4521 ext_tlv = (MrvlExtIEtypes_Data_t *)pos;
4522 ext_tlv->header.type = EXTENSION;
4523 ext_tlv->header.len = params->he_capab_len + sizeof(u8);
4524 ext_tlv->header.ext_id = HE_CAPABILITY;
4525 memcpy(ext_tlv->data, (u8 *)¶ms->he_capab, params->he_capab_len);
4526 pos += sizeof(MrvlExtIEtypesHeader_t) + params->he_capab_len;
4527 sta_info->tlv_len += sizeof(MrvlExtIEtypesHeader_t) + params->he_capab_len;
4528 tlv = (MrvlIEtypes_Data_t *)pos;
4529 }
4530 #endif
4531
4532 if (MLAN_STATUS_SUCCESS != wifi_uap_sta_info(priv, HostCmd_ACT_ADD_STA, sta_info))
4533 {
4534 wuap_e("uAP add station failed");
4535 ret = -WM_FAIL;
4536 goto done;
4537 }
4538
4539 done:
4540 if (sta_info)
4541 OSA_MemoryFree(sta_info);
4542
4543 LEAVE();
4544 return ret;
4545 }
4546
wifi_nxp_sta_remove(const uint8_t * addr)4547 int wifi_nxp_sta_remove(const uint8_t *addr)
4548 {
4549 mlan_private *priv = (mlan_private *)mlan_adap->priv[1];
4550 int ret = 0;
4551 #if 0
4552 mlan_ds_sta_info *sta_info = NULL;
4553 #endif
4554 ENTER();
4555
4556 if (!addr)
4557 {
4558 ret = -WM_FAIL;
4559 goto done;
4560 }
4561
4562 if (MLAN_STATUS_SUCCESS != wifi_uap_sta_remove(priv, addr))
4563 {
4564 wuap_e("uAP remove station failed");
4565 ret = -WM_FAIL;
4566 goto done;
4567 }
4568
4569 #if 0
4570 sta_info = OSA_MemoryAllocate(sizeof(mlan_ds_sta_info));
4571 if (!sta_info)
4572 {
4573 wuap_e("Fail to alloc memory for mlan_ds_sta_info");
4574 ret = -WM_FAIL;
4575 goto done;
4576 }
4577
4578 memset(sta_info, 0x00, sizeof(mlan_ds_sta_info));
4579
4580 memcpy(sta_info->peer_mac, addr, MLAN_MAC_ADDR_LENGTH);
4581
4582 wuap_d("wlan: UAP/GO remove peer station, address =" MACSTR "", MAC2STR(addr));
4583
4584 if (MLAN_STATUS_SUCCESS != wifi_uap_sta_info(priv, HostCmd_ACT_REMOVE_STA, sta_info))
4585 {
4586 wuap_e("uAP remove station failed");
4587 ret = -WM_FAIL;
4588 goto done;
4589 }
4590 #endif
4591
4592 done:
4593 #if 0
4594 if (sta_info)
4595 OSA_MemoryFree(sta_info);
4596 #endif
4597
4598 LEAVE();
4599 return ret;
4600 }
4601
wifi_set_uap_rts(int rts_threshold)4602 int wifi_set_uap_rts(int rts_threshold)
4603 {
4604 mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[1];
4605 MrvlIEtypes_rts_threshold_t rts_threshold_tlv;
4606
4607 (void)memset(&rts_threshold_tlv, 0, sizeof(MrvlIEtypes_rts_threshold_t));
4608 rts_threshold_tlv.header.type = TLV_TYPE_UAP_RTS_THRESHOLD;
4609 rts_threshold_tlv.header.len = (t_u16)sizeof(MrvlIEtypes_rts_threshold_t);
4610 rts_threshold_tlv.rts_threshold = (t_u16)rts_threshold;
4611
4612 int rv = wifi_uap_prepare_and_send_cmd(pmpriv, HOST_CMD_APCMD_SYS_CONFIGURE, HostCmd_ACT_GEN_SET, 0, MNULL,
4613 &rts_threshold_tlv, MLAN_BSS_TYPE_UAP, NULL);
4614 if (rv != WM_SUCCESS)
4615 {
4616 return rv;
4617 }
4618
4619 if (wm_wifi.cmd_resp_status != 0)
4620 {
4621 wifi_w("Unable to set rts threshold");
4622 return wm_wifi.cmd_resp_status;
4623 }
4624
4625 return rv;
4626 }
4627
wifi_set_uap_frag(int frag_threshold)4628 int wifi_set_uap_frag(int frag_threshold)
4629 {
4630 mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[1];
4631 MrvlIEtypes_frag_threshold_t frag_threshold_tlv;
4632
4633 (void)memset(&frag_threshold_tlv, 0, sizeof(MrvlIEtypes_frag_threshold_t));
4634 frag_threshold_tlv.header.type = TLV_TYPE_UAP_RTS_THRESHOLD;
4635 frag_threshold_tlv.header.len = (t_u16)sizeof(MrvlIEtypes_frag_threshold_t);
4636 frag_threshold_tlv.frag_threshold = (t_u16)frag_threshold;
4637
4638 int rv = wifi_uap_prepare_and_send_cmd(pmpriv, HOST_CMD_APCMD_SYS_CONFIGURE, HostCmd_ACT_GEN_SET, 0, MNULL,
4639 &frag_threshold_tlv, MLAN_BSS_TYPE_UAP, NULL);
4640 if (rv != WM_SUCCESS)
4641 {
4642 return rv;
4643 }
4644
4645 if (wm_wifi.cmd_resp_status != 0)
4646 {
4647 wifi_w("Unable to set frag threshold");
4648 return wm_wifi.cmd_resp_status;
4649 }
4650
4651 return rv;
4652 }
4653
wifi_nxp_uap_disconnect(mlan_private * priv,t_u16 reason_code,t_u8 * mac)4654 void wifi_nxp_uap_disconnect(mlan_private *priv, t_u16 reason_code, t_u8 *mac)
4655 {
4656 wlan_mgmt_pkt *pmgmt_pkt_hdr = MNULL;
4657 nxp_wifi_event_mlme_t *mgmt_rx = &wm_wifi.mgmt_rx;
4658 t_u8 *pos = MNULL;
4659 t_u16 reason;
4660 t_u32 payload_len;
4661
4662 pmgmt_pkt_hdr = wifi_PrepDefaultMgtMsg(SUBTYPE_DEAUTH, (mlan_802_11_mac_addr *)(void *)priv->curr_addr,
4663 (mlan_802_11_mac_addr *)(void *)mac, (mlan_802_11_mac_addr *)(void *)priv->curr_addr, 100);
4664 if (pmgmt_pkt_hdr == MNULL)
4665 {
4666 wifi_e("No memory available for deauth");
4667 return;
4668 }
4669
4670 pos = (t_u8 *)pmgmt_pkt_hdr + sizeof(wlan_mgmt_pkt);
4671 reason = wlan_cpu_to_le16(reason_code);
4672 (void)memcpy(pos, &reason, sizeof(reason));
4673 payload_len = sizeof(reason) + sizeof(pmgmt_pkt_hdr->wlan_header);
4674
4675 if (payload_len <= (int)sizeof(mgmt_rx->frame.frame))
4676 {
4677 memset(mgmt_rx, 0, sizeof(nxp_wifi_event_mlme_t));
4678 mgmt_rx->frame.frame_len = payload_len;
4679 (void)memcpy((void *)mgmt_rx->frame.frame, (const void *)(&pmgmt_pkt_hdr->wlan_header), mgmt_rx->frame.frame_len);
4680 if (wm_wifi.supp_if_callbk_fns->mgmt_rx_callbk_fn)
4681 {
4682 wm_wifi.supp_if_callbk_fns->mgmt_rx_callbk_fn(wm_wifi.hapd_if_priv,
4683 mgmt_rx, mgmt_rx->frame.frame_len, -30);
4684 }
4685 }
4686 else
4687 {
4688 wifi_e("Insufficient frame buffer");
4689 }
4690
4691 #if !CONFIG_MEM_POOLS
4692 OSA_MemoryFree(pmgmt_pkt_hdr);
4693 #else
4694 OSA_MemoryPoolFree(buf_1536_MemoryPool, pmgmt_pkt_hdr);
4695 #endif
4696 }
4697
wifi_nxp_stop_ap()4698 int wifi_nxp_stop_ap()
4699 {
4700 mlan_private *priv = (mlan_private *)mlan_adap->priv[1];
4701 int ret = WM_SUCCESS;
4702
4703 if ((mlan_adap->in_reset == MTRUE) && (priv->media_connected == MFALSE))
4704 {
4705 return ret;
4706 }
4707
4708 (void)wifi_set_rx_mgmt_indication(MLAN_BSS_TYPE_UAP, 0);
4709
4710 if (priv->beacon_vendor_index != -1)
4711 {
4712 ret = wifi_clear_mgmt_ie2(MLAN_BSS_TYPE_UAP, priv->beacon_vendor_index);
4713 if (ret != WM_SUCCESS)
4714 {
4715 wuap_e("Clear uAP vendor IE failed");
4716 return -WM_FAIL;
4717 }
4718 priv->beacon_vendor_index = -1;
4719 }
4720
4721 ret = wifi_nxp_set_mgmt_ies(priv, NULL, 0, NULL, 0, NULL, 0, NULL, 0);
4722 if (ret != WM_SUCCESS)
4723 {
4724 wuap_e("Set uAP mgmt ie failed");
4725 ret = -WM_FAIL;
4726 goto done;
4727 }
4728
4729 wuap_d("Stopping BSS"); /* Stop BSS */
4730 if (MLAN_STATUS_SUCCESS != wifi_uap_prepare_and_send_cmd(priv, HOST_CMD_APCMD_BSS_STOP, HostCmd_ACT_GEN_SET, 0,
4731 NULL, NULL, MLAN_BSS_TYPE_UAP, NULL))
4732 {
4733 wuap_e("Stop BSS failed");
4734 return -WM_FAIL;
4735 }
4736 wifi_uap_clear_domain_info();
4737 priv->uap_host_based = MFALSE;
4738
4739 wuap_d("wlan: AP stopped");
4740
4741 done:
4742 LEAVE();
4743 return ret;
4744 }
4745
wifi_nxp_init_ap(nxp_wifi_ap_info_t * params)4746 int wifi_nxp_init_ap(nxp_wifi_ap_info_t *params)
4747 {
4748 int ret = 0;
4749 /* to do */
4750 return ret;
4751 }
4752
wifi_nxp_set_acl(nxp_wifi_acl_info_t * params)4753 int wifi_nxp_set_acl(nxp_wifi_acl_info_t *params)
4754 {
4755 mlan_private *priv = (mlan_private *)mlan_adap->priv[1];
4756 int ret = -WM_FAIL;
4757 mlan_uap_bss_param *sys_config = NULL;
4758 bool bss_started = MFALSE;
4759
4760 if (!params)
4761 {
4762 goto done;
4763 }
4764
4765 sys_config = OSA_MemoryAllocate(sizeof(mlan_uap_bss_param));
4766
4767 if (!sys_config)
4768 {
4769 wuap_e("Fail to alloc memory for mlan_uap_bss_param");
4770 goto done;
4771 }
4772
4773 memset(sys_config, 0x00, sizeof(mlan_uap_bss_param));
4774
4775 if (params->num_mac_acl <= MAX_MAC_FILTER_NUM)
4776 sys_config->filter.mac_count = params->num_mac_acl;
4777 else
4778 sys_config->filter.mac_count = MAX_MAC_FILTER_NUM;
4779
4780 if (params->acl_policy == 1U)
4781 sys_config->filter.filter_mode = MAC_FILTER_MODE_ALLOW_MAC;
4782 else if (params->acl_policy == 0U)
4783 sys_config->filter.filter_mode = MAC_FILTER_MODE_BLOCK_MAC;
4784 memcpy(sys_config->filter.mac_list, params->mac_acl, sys_config->filter.mac_count * sizeof(mlan_802_11_mac_addr));
4785
4786 if (priv->uap_host_based == MTRUE)
4787 {
4788 bss_started = MTRUE;
4789
4790 if (MLAN_STATUS_SUCCESS != wifi_uap_prepare_and_send_cmd(priv, HOST_CMD_APCMD_BSS_STOP, HostCmd_ACT_GEN_SET, 0,
4791 NULL, NULL, MLAN_BSS_TYPE_UAP, NULL))
4792 {
4793 wuap_e("Stop BSS failed");
4794 }
4795 }
4796
4797 if (MLAN_STATUS_SUCCESS == wifi_set_get_sys_config(priv, MLAN_ACT_SET, sys_config))
4798 {
4799 ret = WM_SUCCESS;
4800 }
4801
4802 if (bss_started)
4803 {
4804 if (MLAN_STATUS_SUCCESS != wifi_uap_prepare_and_send_cmd(priv, HOST_CMD_APCMD_BSS_START, HostCmd_ACT_GEN_SET, 0,
4805 NULL, NULL, MLAN_BSS_TYPE_UAP, NULL))
4806 {
4807 wuap_e("Start BSS failed");
4808 }
4809 }
4810
4811 done:
4812 if (sys_config)
4813 OSA_MemoryFree(sys_config);
4814
4815 LEAVE();
4816 return ret;
4817 }
4818
4819 #endif /* CONFIG_WPA_SUPP_AP */
4820