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