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