1 /** @file mlan_init.c
2  *
3  *  @brief  This file provides initialization for FW and HW
4  *
5  *  Copyright 2008-2024 NXP
6  *
7  *  SPDX-License-Identifier: BSD-3-Clause
8  *
9  */
10 
11 /********************************************************
12 Change log:
13     10/13/2008: initial version
14 ********************************************************/
15 
16 #include <mlan_api.h>
17 
18 /* Additional WMSDK header files */
19 #include <wmerrno.h>
20 #include <osa.h>
21 
22 /* Always keep this include at the end of all include files */
23 #include <mlan_remap_mem_operations.h>
24 /********************************************************
25         Global Variables
26 ********************************************************/
27 
28 #define BOARD_SDMMC_DATA_BUFFER_ALIGN_SIZE 32
29 
30 //_IOBUFS_ALIGNED(SDIO_DMA_ALIGNMENT)
31 #if defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
32 static t_u8 mp_regs_buffer[MAX_MP_REGS + DMA_ALIGNMENT];
33 #elif defined(SD8801)
34 SDK_ALIGN(uint8_t mp_regs_buffer[MAX_MP_REGS], BOARD_SDMMC_DATA_BUFFER_ALIGN_SIZE);
35 #endif
36 
37 /* We are allocating BSS list globally as we need heap for other purposes */
38 SDK_ALIGN(BSSDescriptor_t BSS_List[MRVDRV_MAX_BSSID_LIST], 32);
39 
40 #if CONFIG_SCAN_CHANNEL_GAP
41 
42 #if !CONFIG_5GHz_SUPPORT
43 static ChanStatistics_t Chan_Stats[14];
44 #else
45 static ChanStatistics_t Chan_Stats[48];
46 #endif
47 
48 #endif
49 
50 /********************************************************
51         Global Functions
52 ********************************************************/
53 
54 /**
55  *  @brief This function allocates buffer for the members of adapter
56  *  		structure like command buffer and BSSID list.
57  *
58  *  @param pmadapter A pointer to mlan_adapter structure
59  *
60  *  @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
61  */
wlan_allocate_adapter(pmlan_adapter pmadapter)62 mlan_status wlan_allocate_adapter(pmlan_adapter pmadapter)
63 {
64     (void)__memset(MNULL, &BSS_List, 0x00, sizeof(BSS_List));
65 
66     pmadapter->pscan_table = BSS_List;
67 #if CONFIG_SCAN_CHANNEL_GAP
68 
69 #if !CONFIG_5GHz_SUPPORT
70     pmadapter->num_in_chan_stats = 14;
71 #else
72     pmadapter->num_in_chan_stats = 48;
73 #endif
74     pmadapter->pchan_stats = Chan_Stats;
75 #endif
76 
77 #if defined(SD8801)
78     pmadapter->mp_regs = mp_regs_buffer;
79 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
80     pmadapter->mp_regs = (t_u8 *)ALIGN_ADDR(mp_regs_buffer, DMA_ALIGNMENT);
81 // mp_regs_buffer;
82 #endif
83 
84     return MLAN_STATUS_SUCCESS;
85 }
86 
wlan_clear_scan_bss(void)87 void wlan_clear_scan_bss(void)
88 {
89 #if CONFIG_WPA_SUPP
90     BSSDescriptor_t *bss_entry = NULL;
91     int i;
92 
93     for (i = 0; i < mlan_adap->num_in_scan_table; i++)
94     {
95         bss_entry = &mlan_adap->pscan_table[i];
96         if (bss_entry && bss_entry->ies != NULL)
97         {
98             OSA_MemoryFree(bss_entry->ies);
99         }
100     }
101 #endif
102     (void)__memset(MNULL, &BSS_List, 0x00, sizeof(BSS_List));
103 }
104 
105 /**
106  *  @brief This function initializes the private structure
107  *  		and sets default values to the members of mlan_private.
108  *
109  *  @param priv    A pointer to mlan_private structure
110  *
111  *  @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
112  */
wlan_init_priv(pmlan_private priv)113 mlan_status wlan_init_priv(pmlan_private priv)
114 {
115     t_u32 i;
116     /* pmlan_adapter pmadapter = priv->adapter; */
117     mlan_status ret = MLAN_STATUS_SUCCESS;
118 
119     ENTER();
120 
121     priv->media_connected = MFALSE;
122     (void)__memset(pmadapter, priv->curr_addr, 0xff, MLAN_MAC_ADDR_LENGTH);
123 
124 #ifdef STA_SUPPORT
125     priv->pkt_tx_ctrl = 0;
126     priv->bss_mode    = MLAN_BSS_MODE_INFRA;
127 
128     priv->data_rate         = 0; /* Initially indicate the rate as auto */
129     priv->data_rate_index   = (t_s8)-1;
130     priv->is_data_rate_auto = MTRUE;
131     priv->bcn_avg_factor    = DEFAULT_BCN_AVG_FACTOR;
132     priv->data_avg_factor   = DEFAULT_DATA_AVG_FACTOR;
133 
134     priv->sec_info.wep_status          = Wlan802_11WEPDisabled;
135     priv->sec_info.authentication_mode = MLAN_AUTH_MODE_AUTO;
136     priv->sec_info.encryption_mode     = MLAN_ENCRYPTION_MODE_NONE;
137     for (i = 0; i < sizeof(priv->wep_key) / sizeof(priv->wep_key[0]); i++)
138     {
139         (void)__memset(pmadapter, &priv->wep_key[i], 0, sizeof(mrvl_wep_key_t));
140     }
141     priv->wep_key_curr_index = 0;
142     priv->ewpa_query         = MFALSE;
143     priv->adhoc_aes_enabled  = MFALSE;
144     priv->curr_pkt_filter =
145 #if CONFIG_11AC
146         HostCmd_ACT_MAC_STATIC_DYNAMIC_BW_ENABLE |
147 #endif
148         HostCmd_ACT_MAC_RTS_CTS_ENABLE | HostCmd_ACT_MAC_RX_ON | HostCmd_ACT_MAC_TX_ON |
149         HostCmd_ACT_MAC_ETHERNETII_ENABLE;
150 
151 #if CONFIG_GTK_REKEY_OFFLOAD
152     (void)__memset(pmadapter, &priv->gtk_rekey, 0, sizeof(priv->gtk_rekey));
153 #endif
154     (void)__memset(pmadapter, &priv->curr_bss_params, 0, sizeof(priv->curr_bss_params));
155     priv->listen_interval = MLAN_DEFAULT_LISTEN_INTERVAL;
156     wlan_11d_priv_init(priv);
157     wlan_11h_priv_init(priv);
158 
159 #if defined(UAP_SUPPORT)
160     priv->uap_bss_started = MFALSE;
161     (void)__memset(pmadapter, &priv->uap_state_chan_cb, 0, sizeof(priv->uap_state_chan_cb));
162 #endif
163 #if defined(UAP_SUPPORT)
164     priv->num_drop_pkts = 0;
165 #endif
166     priv->wpa_is_gtk_set = MFALSE;
167 #endif /* STA_SUPPORT */
168 
169 #ifdef RW610
170     priv->tx_bf_cap = DEFAULT_11N_TX_BF_CAP;
171 #else
172     priv->tx_bf_cap = 0;
173 #endif
174     priv->wmm_required = MTRUE;
175     priv->wmm_enabled  = MFALSE;
176     priv->wmm_qosinfo  = 0;
177     priv->pmfcfg.mfpc = 0;
178     priv->pmfcfg.mfpr = 0;
179 
180 #if CONFIG_11K
181     priv->enable_host_11k = (t_u8)MFALSE;
182 #endif
183 #if CONFIG_11K_OFFLOAD
184     priv->enable_11k = (t_u8)MFALSE;
185 #endif
186 #if CONFIG_11K
187     priv->neighbor_rep_token    = (t_u8)1U;
188     priv->rrm_mgmt_bitmap_index = -1;
189 #endif
190 #if CONFIG_11V
191     priv->bss_trans_query_token = (t_u8)1U;
192 #endif
193     for (i = 0; i < MAX_NUM_TID; i++)
194     {
195         priv->addba_reject[i] = ADDBA_RSP_STATUS_ACCEPT;
196     }
197     priv->max_amsdu = 0;
198 
199     priv->scan_block = MFALSE;
200 
201     if (GET_BSS_ROLE(priv) == (unsigned)MLAN_BSS_ROLE_STA)
202     {
203         priv->port_ctrl_mode = MTRUE;
204     }
205     else
206     {
207         priv->port_ctrl_mode = MFALSE;
208     }
209     priv->port_open = MFALSE;
210 #if CONFIG_ROAMING
211     priv->roaming_enabled = MFALSE;
212 #endif
213 #ifdef UAP_SUPPORT
214     priv->uap_bss_started = MFALSE;
215     priv->uap_host_based  = MFALSE;
216 #endif
217 
218 #if CONFIG_WPA_SUPP
219     reset_ie_index();
220     priv->default_scan_ies_len = 0;
221     priv->probe_req_index      = -1;
222 #if CONFIG_WPA_SUPP_WPS
223     priv->wps.wps_mgmt_bitmap_index = -1;
224 #endif
225 #if CONFIG_WPA_SUPP_AP
226     priv->beacon_vendor_index = -1;
227     priv->beacon_index        = 0;
228     priv->proberesp_index     = 1;
229     priv->assocresp_index     = 2;
230     priv->beacon_wps_index    = 3;
231 #endif
232 #endif
233 #if CONFIG_TCP_ACK_ENH
234     priv->enable_tcp_ack_enh = MTRUE;
235 #endif
236 
237 #if CONFIG_WPA_SUPP_DPP
238     priv->is_dpp_connect = MFALSE;
239 #endif
240 
241     LEAVE();
242     return ret;
243 }
244 
245 /**
246  *  @brief This function initializes the adapter structure
247  *  		and sets default values to the members of adapter.
248  *
249  *  @param pmadapter	A pointer to mlan_adapter structure
250  *
251  *  @return		N/A
252  */
wlan_init_adapter(pmlan_adapter pmadapter)253 t_void wlan_init_adapter(pmlan_adapter pmadapter)
254 {
255 #ifdef WIFI_CALIB_CMD_SUPPORT
256     if (pmadapter->init_para.wifi_calib_mode == MLAN_INIT_PARA_DISABLED)
257     {
258         pmadapter->wifi_calib_mode = MFALSE;
259     }
260     else
261     {
262         pmadapter->wifi_calib_mode = pmadapter->init_para.wifi_calib_mode;
263     }
264 #endif
265     pmadapter->mp_rd_bitmap = 0;
266 
267     /*
268      * wmsdk: fixme: Originally mp_wr_bitmap was set to 0. We have changed
269      * it only for legacy reason. Please check it and restore on high
270      * priority.
271      */
272     pmadapter->mp_wr_bitmap = 0;
273 #ifndef RW610
274 #if defined(SD8801)
275     pmadapter->curr_rd_port = 1;
276     pmadapter->curr_wr_port = 1;
277 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
278     pmadapter->curr_rd_port      = 0;
279     pmadapter->curr_wr_port      = 0;
280 #endif
281     pmadapter->mp_data_port_mask = DATA_PORT_MASK;
282 #endif
283 #ifdef STA_SUPPORT
284     /* Scan type */
285     pmadapter->scan_type = MLAN_SCAN_TYPE_ACTIVE;
286     /* Scan mode */
287     pmadapter->scan_mode = HostCmd_BSS_MODE_ANY;
288     /* Scan time */
289     pmadapter->specific_scan_time = MRVDRV_SPECIFIC_SCAN_CHAN_TIME;
290     pmadapter->active_scan_time   = MRVDRV_ACTIVE_SCAN_CHAN_TIME;
291     pmadapter->passive_scan_time  = MRVDRV_PASSIVE_SCAN_CHAN_TIME;
292 
293     pmadapter->num_in_scan_table = 0;
294 
295     pmadapter->ecsa_enable = MFALSE;
296 
297 #if CONFIG_EXT_SCAN_SUPPORT
298     pmadapter->ext_scan = 1;
299 #endif
300     pmadapter->scan_probes = DEFAULT_PROBES;
301 
302 #if CONFIG_SCAN_WITH_RSSIFILTER
303     pmadapter->rssi_threshold = 0;
304 #endif
305     pmadapter->multiple_dtim         = MRVDRV_DEFAULT_MULTIPLE_DTIM;
306     pmadapter->local_listen_interval = 0; /* default value in firmware
307                                              will be used */
308 #endif                                    /* STA_SUPPORT */
309 
310     pmadapter->delay_to_ps       = DELAY_TO_PS_DEFAULT;
311     pmadapter->enhanced_ps_mode  = PS_MODE_AUTO;
312     pmadapter->bcn_miss_time_out = DEFAULT_BCN_MISS_TIMEOUT;
313 
314 #if CONFIG_WMM_UAPSD
315     pmadapter->gen_null_pkt   = MFALSE; /* Disable NULL Pkt generation-default */
316     pmadapter->pps_uapsd_mode = MFALSE; /* Disable pps/uapsd mode -default */
317 #endif
318 #if CONFIG_HOST_SLEEP
319     pmadapter->is_hs_configured          = MFALSE;
320     pmadapter->mgmt_filter[0].action     = 0;      /* discard and not wakeup host */
321     pmadapter->mgmt_filter[0].type       = 0xff;   /* management frames */
322     pmadapter->mgmt_filter[0].frame_mask = 0x1400; /* Frame-Mask bits :
323                                                       : Bit 0 - Association Request
324                                                       : Bit 1 - Association Response
325                                                       : Bit 2 - Re-Association Request
326                                                       : Bit 3 - Re-Association Response
327                                                       : Bit 4 - Probe Request
328                                                       : Bit 5 - Probe Response
329                                                       : Bit 8 - Beacon Frames
330                                                       : Bit 10 - Disassociation
331                                                       : Bit 11 - Authentication
332                                                       : Bit 12 - Deauthentication
333                                                       : Bit 13 - Action Frames
334                                                    */
335 #endif
336     pmadapter->hw_dot_11n_dev_cap     = 0;
337     pmadapter->hw_dev_mcs_support     = 0;
338     pmadapter->usr_dot_11n_dev_cap_bg = 0;
339     pmadapter->usr_dot_11n_dev_cap_a  = 0;
340     pmadapter->usr_dev_mcs_support    = 0;
341 #ifdef STA_SUPPORT
342     pmadapter->chan_bandwidth    = 0;
343     pmadapter->adhoc_11n_enabled = MFALSE;
344 #endif /* STA_SUPPORT */
345 
346     pmadapter->hw_dot_11ac_dev_cap       = 0;
347     pmadapter->hw_dot_11ac_mcs_support   = 0;
348     pmadapter->usr_dot_11ac_opermode_bw  = 0;
349     pmadapter->usr_dot_11ac_opermode_nss = 0;
350 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT
351 #if CONFIG_WIFI_CAPA
352     pmadapter->usr_dot_11n_enable = MTRUE;
353 #if CONFIG_11AC
354     pmadapter->usr_dot_11ac_enable = MTRUE;
355 #endif
356 #if CONFIG_11AX
357     pmadapter->usr_dot_11ax_enable = MTRUE;
358 #endif
359 #endif
360 #else
361 #if CONFIG_WIFI_CAPA
362     pmadapter->usr_dot_11n_enable = MFALSE;
363 #if CONFIG_11AC
364     pmadapter->usr_dot_11ac_enable = MFALSE;
365 #endif
366 #if CONFIG_11AX
367     pmadapter->usr_dot_11ax_enable = MFALSE;
368 #endif
369 #endif
370 #endif
371     /* Initialize 802.11d */
372     wlan_11d_init(pmadapter);
373     wlan_11h_init(pmadapter);
374 
375     wlan_wmm_init(pmadapter);
376     wlan_init_wmm_param(pmadapter);
377 #if CONFIG_WMM_UAPSD
378     (void)__memset(pmadapter, &pmadapter->sleep_params, 0, sizeof(pmadapter->sleep_params));
379     (void)__memset(pmadapter, &pmadapter->sleep_period, 0, sizeof(pmadapter->sleep_period));
380 
381     pmadapter->tx_lock_flag = MFALSE;
382 #endif /* CONFIG_WMM_UAPSD */
383     pmadapter->null_pkt_interval = 0;
384     pmadapter->fw_bands          = 0U;
385     pmadapter->config_bands      = 0U;
386     pmadapter->adhoc_start_band  = 0U;
387     /* pmadapter->pscan_channels = MNULL; */
388     pmadapter->fw_release_number = 0;
389     pmadapter->fw_cap_info       = 0;
390     (void)__memset(pmadapter, &pmadapter->region_channel, 0, sizeof(pmadapter->region_channel));
391     pmadapter->region_code = MRVDRV_DEFAULT_REGION_CODE;
392     (void)__memcpy(pmadapter, pmadapter->country_code, MRVDRV_DEFAULT_COUNTRY_CODE, COUNTRY_CODE_LEN);
393     pmadapter->adhoc_awake_period = 0;
394     pmadapter->ps_state           = PS_STATE_AWAKE;
395     return;
396 }
397 
398 /**
399  *  @brief This function intializes the lock variables and
400  *  the list heads.
401  *
402  *  @param pmadapter  A pointer to a mlan_adapter structure
403  *
404  *  @return           MLAN_STATUS_SUCCESS -- on success,
405  *                    otherwise MLAN_STATUS_FAILURE
406  *
407  */
wlan_init_lock_list(IN pmlan_adapter pmadapter)408 mlan_status wlan_init_lock_list(IN pmlan_adapter pmadapter)
409 {
410     mlan_status ret    = MLAN_STATUS_SUCCESS;
411     pmlan_private priv = MNULL;
412     /* pmlan_callbacks pcb = &pmadapter->callbacks; */
413     t_u8 i = 0;
414     t_u8 j = 0;
415 
416     ENTER();
417     for (i = 0; i < pmadapter->priv_num; i++)
418     {
419         if (pmadapter->priv[i] != NULL)
420         {
421             priv = pmadapter->priv[i];
422             for (j = 0; j < MAX_NUM_TID; ++j)
423             {
424                 util_init_list_head((t_void *)pmadapter->pmoal_handle, &priv->wmm.tid_tbl_ptr[j].ra_list, MTRUE,
425                                     priv->adapter->callbacks.moal_init_lock);
426             }
427 
428 #if CONFIG_WMM
429             /* wmm enhanced reuses 4 ac xmit queues */
430             for (j = 0; j < MAX_AC_QUEUES; ++j)
431             {
432                 if (priv->adapter->callbacks.moal_init_semaphore(pmadapter->pmoal_handle, "ra_list_sem",
433                                                                  &priv->wmm.tid_tbl_ptr[j].ra_list.plock) !=
434                     MLAN_STATUS_SUCCESS)
435                 {
436                     wifi_e("Create ra_list_sem failed");
437                     ret = MLAN_STATUS_FAILURE;
438                     goto done;
439                 }
440 #if CONFIG_WMM_DEBUG
441                 util_init_list_head((t_void *)pmadapter->pmoal_handle, &priv->wmm.hist_ra[j], MFALSE, MNULL);
442 #endif
443             }
444 #endif
445 
446             ret = (mlan_status)OSA_MutexCreate((osa_mutex_handle_t)priv->tx_ba_stream_tbl_lock);
447             if (ret != MLAN_STATUS_SUCCESS)
448             {
449                 wifi_e("Create Tx BA tbl sem failed");
450                 ret = MLAN_STATUS_FAILURE;
451                 goto done;
452             }
453 
454             util_init_list_head((t_void *)pmadapter->pmoal_handle, &priv->tx_ba_stream_tbl_ptr, MTRUE,
455                                 pmadapter->callbacks.moal_init_lock);
456 
457             ret = (mlan_status)OSA_SemaphoreCreateBinary((osa_semaphore_handle_t)priv->rx_reorder_tbl_lock);
458             if (ret != MLAN_STATUS_SUCCESS)
459             {
460                 wifi_e("Create Rx Reorder tbl lock failed");
461                 ret = MLAN_STATUS_FAILURE;
462                 goto done;
463             }
464             OSA_SemaphorePost((osa_semaphore_handle_t)priv->rx_reorder_tbl_lock);
465             util_init_list_head((t_void *)pmadapter->pmoal_handle, &priv->rx_reorder_tbl_ptr, MTRUE,
466                                 pmadapter->callbacks.moal_init_lock);
467 
468             util_scalar_init((t_void *)pmadapter->pmoal_handle, &priv->wmm.tx_pkts_queued, 0,
469                              priv->wmm.ra_list_spinlock, pmadapter->callbacks.moal_init_lock);
470             util_scalar_init((t_void *)pmadapter->pmoal_handle, &priv->wmm.highest_queued_prio, HIGH_PRIO_TID,
471                              priv->wmm.ra_list_spinlock, pmadapter->callbacks.moal_init_lock);
472             util_init_list_head((t_void *)pmadapter->pmoal_handle, &priv->sta_list, MTRUE,
473                                 pmadapter->callbacks.moal_init_lock);
474         }
475     }
476 
477 done:
478     /* error: */
479     if (ret != MLAN_STATUS_SUCCESS)
480     {
481         for (i = 0; i < pmadapter->priv_num; i++)
482         {
483             priv = pmadapter->priv[i];
484 #if CONFIG_WMM
485             for (j = 0; j < MAX_AC_QUEUES; ++j)
486             {
487                 if ((uint32_t *)(*(uint32_t *)priv->wmm.tid_tbl_ptr[j].ra_list.plock) != NULL)
488                     priv->adapter->callbacks.moal_free_semaphore(
489                         pmadapter->pmoal_handle, &priv->wmm.tid_tbl_ptr[j].ra_list.plock);
490             }
491 #endif
492             if ((uint32_t *)(*(uint32_t *)priv->tx_ba_stream_tbl_lock) != NULL)
493                 OSA_MutexDestroy((osa_mutex_handle_t)priv->tx_ba_stream_tbl_lock);
494             if ((uint32_t *)(*(uint32_t *)priv->rx_reorder_tbl_lock) != NULL)
495                 OSA_SemaphoreDestroy((osa_semaphore_handle_t)priv->rx_reorder_tbl_lock);
496         }
497     }
498     LEAVE();
499     return ret;
500 }
501 
502 /**
503  *  @brief  This function initializes firmware
504  *
505  *  @param pmadapter		A pointer to mlan_adapter
506  *
507  *  @return		MLAN_STATUS_SUCCESS, MLAN_STATUS_PENDING or MLAN_STATUS_FAILURE
508  */
wlan_init_fw(IN pmlan_adapter pmadapter)509 mlan_status wlan_init_fw(IN pmlan_adapter pmadapter)
510 {
511     mlan_status ret    = MLAN_STATUS_SUCCESS;
512     pmlan_private priv = MNULL;
513     t_u8 i             = 0;
514 
515     ENTER();
516 
517     /* Initialize adapter structure */
518     wlan_init_adapter(pmadapter);
519 
520     for (i = 0; i < pmadapter->priv_num; i++)
521     {
522         if (pmadapter->priv[i] != NULL)
523         {
524             priv = pmadapter->priv[i];
525 
526             /* Initialize private structure */
527             if ((ret = wlan_init_priv(priv)) != MLAN_STATUS_SUCCESS)
528             {
529                 ret = MLAN_STATUS_FAILURE;
530                 goto done;
531             }
532         }
533     }
534 #ifdef WIFI_CALIB_CMD_SUPPORT
535     if (pmadapter->wifi_calib_mode != MTRUE)
536     {
537 #endif
538         /* Issue firmware initialize commands for first BSS, for other
539            interfaces it will be called after getting the last init command
540            response of previous interface */
541 done:
542     LEAVE();
543     return ret;
544 }
545 
546 /**
547  *  @brief This function frees the structure of adapter
548  *
549  *  @param pmadapter      A pointer to mlan_adapter structure
550  *
551  *  @return             N/A
552  */
553 t_void wlan_free_adapter(pmlan_adapter pmadapter)
554 {
555     ENTER();
556 
557     if (!pmadapter)
558     {
559         PRINTM(MERROR, "The adapter is NULL\n");
560         LEAVE();
561         return;
562     }
563 
564     LEAVE();
565     return;
566 }
567