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 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 priv->num_drop_pkts = 0;
163 #endif
164 priv->wpa_is_gtk_set = MFALSE;
165 #endif /* STA_SUPPORT */
166
167 #ifdef RW610
168 priv->tx_bf_cap = DEFAULT_11N_TX_BF_CAP;
169 #else
170 priv->tx_bf_cap = 0;
171 #endif
172 priv->wmm_required = MTRUE;
173 priv->wmm_enabled = MFALSE;
174 priv->wmm_qosinfo = 0;
175 priv->pmfcfg.mfpc = 0;
176 priv->pmfcfg.mfpr = 0;
177
178 #if CONFIG_11K
179 priv->enable_host_11k = (t_u8)MFALSE;
180 #endif
181 #if CONFIG_11K_OFFLOAD
182 priv->enable_11k = (t_u8)MFALSE;
183 #endif
184 #if CONFIG_11K
185 priv->neighbor_rep_token = (t_u8)1U;
186 priv->rrm_mgmt_bitmap_index = -1;
187 #endif
188 #if CONFIG_11V
189 priv->bss_trans_query_token = (t_u8)1U;
190 #endif
191 for (i = 0; i < MAX_NUM_TID; i++)
192 {
193 priv->addba_reject[i] = ADDBA_RSP_STATUS_ACCEPT;
194 }
195 priv->max_amsdu = 0;
196
197 priv->scan_block = MFALSE;
198
199 if (GET_BSS_ROLE(priv) == (unsigned)MLAN_BSS_ROLE_STA)
200 {
201 priv->port_ctrl_mode = MTRUE;
202 }
203 else
204 {
205 priv->port_ctrl_mode = MFALSE;
206 }
207 priv->port_open = MFALSE;
208 #if CONFIG_ROAMING
209 priv->roaming_enabled = MFALSE;
210 #endif
211 #if UAP_SUPPORT
212 priv->uap_bss_started = MFALSE;
213 priv->uap_host_based = MFALSE;
214 #endif
215
216 reset_ie_index();
217 #if CONFIG_WPA_SUPP
218 priv->default_scan_ies_len = 0;
219 priv->probe_req_index = -1;
220 #if CONFIG_WPA_SUPP_WPS
221 priv->wps.wps_mgmt_bitmap_index = -1;
222 #endif
223 #if CONFIG_WPA_SUPP_AP
224 priv->beacon_vendor_index = -1;
225 priv->beacon_index = 0;
226 priv->proberesp_index = 1;
227 priv->assocresp_index = 2;
228 priv->beacon_wps_index = 3;
229 #endif
230 #endif
231 #if CONFIG_TCP_ACK_ENH
232 priv->enable_tcp_ack_enh = MTRUE;
233 #endif
234
235 #if CONFIG_WPA_SUPP_DPP
236 priv->is_dpp_connect = MFALSE;
237 #endif
238
239 LEAVE();
240 return ret;
241 }
242
243 /**
244 * @brief This function initializes the adapter structure
245 * and sets default values to the members of adapter.
246 *
247 * @param pmadapter A pointer to mlan_adapter structure
248 *
249 * @return N/A
250 */
wlan_init_adapter(pmlan_adapter pmadapter)251 t_void wlan_init_adapter(pmlan_adapter pmadapter)
252 {
253 #ifdef WIFI_CALIB_CMD_SUPPORT
254 if (pmadapter->init_para.wifi_calib_mode == MLAN_INIT_PARA_DISABLED)
255 {
256 pmadapter->wifi_calib_mode = MFALSE;
257 }
258 else
259 {
260 pmadapter->wifi_calib_mode = pmadapter->init_para.wifi_calib_mode;
261 }
262 #endif
263 pmadapter->mp_rd_bitmap = 0;
264
265 /*
266 * wmsdk: fixme: Originally mp_wr_bitmap was set to 0. We have changed
267 * it only for legacy reason. Please check it and restore on high
268 * priority.
269 */
270 pmadapter->mp_wr_bitmap = 0;
271 #ifndef RW610
272 #if defined(SD8801)
273 pmadapter->curr_rd_port = 1;
274 pmadapter->curr_wr_port = 1;
275 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
276 pmadapter->curr_rd_port = 0;
277 pmadapter->curr_wr_port = 0;
278 #endif
279 pmadapter->mp_data_port_mask = DATA_PORT_MASK;
280 #endif
281 #ifdef STA_SUPPORT
282 /* Scan type */
283 pmadapter->scan_type = MLAN_SCAN_TYPE_ACTIVE;
284 /* Scan mode */
285 pmadapter->scan_mode = HostCmd_BSS_MODE_ANY;
286 /* Scan time */
287 pmadapter->specific_scan_time = MRVDRV_SPECIFIC_SCAN_CHAN_TIME;
288 pmadapter->active_scan_time = MRVDRV_ACTIVE_SCAN_CHAN_TIME;
289 pmadapter->passive_scan_time = MRVDRV_PASSIVE_SCAN_CHAN_TIME;
290
291 pmadapter->num_in_scan_table = 0;
292
293 pmadapter->ecsa_enable = MFALSE;
294
295 #if CONFIG_EXT_SCAN_SUPPORT
296 pmadapter->ext_scan = 1;
297 #endif
298 pmadapter->scan_probes = DEFAULT_PROBES;
299
300 #if CONFIG_SCAN_WITH_RSSIFILTER
301 pmadapter->rssi_threshold = 0;
302 #endif
303 pmadapter->multiple_dtim = MRVDRV_DEFAULT_MULTIPLE_DTIM;
304 pmadapter->local_listen_interval = 0; /* default value in firmware
305 will be used */
306 #endif /* STA_SUPPORT */
307
308 pmadapter->delay_to_ps = DELAY_TO_PS_DEFAULT;
309 pmadapter->enhanced_ps_mode = PS_MODE_AUTO;
310 pmadapter->bcn_miss_time_out = DEFAULT_BCN_MISS_TIMEOUT;
311
312 #if CONFIG_WMM_UAPSD
313 pmadapter->gen_null_pkt = MFALSE; /* Disable NULL Pkt generation-default */
314 pmadapter->pps_uapsd_mode = MFALSE; /* Disable pps/uapsd mode -default */
315 #endif
316 #if CONFIG_HOST_SLEEP
317 pmadapter->is_hs_configured = MFALSE;
318 pmadapter->mgmt_filter[0].action = 0; /* discard and not wakeup host */
319 pmadapter->mgmt_filter[0].type = 0xff; /* management frames */
320 pmadapter->mgmt_filter[0].frame_mask = 0x1400; /* Frame-Mask bits :
321 : Bit 0 - Association Request
322 : Bit 1 - Association Response
323 : Bit 2 - Re-Association Request
324 : Bit 3 - Re-Association Response
325 : Bit 4 - Probe Request
326 : Bit 5 - Probe Response
327 : Bit 8 - Beacon Frames
328 : Bit 10 - Disassociation
329 : Bit 11 - Authentication
330 : Bit 12 - Deauthentication
331 : Bit 13 - Action Frames
332 */
333 #endif
334 pmadapter->hw_dot_11n_dev_cap = 0;
335 pmadapter->hw_dev_mcs_support = 0;
336 pmadapter->usr_dot_11n_dev_cap_bg = 0;
337 pmadapter->usr_dot_11n_dev_cap_a = 0;
338 pmadapter->usr_dev_mcs_support = 0;
339 #ifdef STA_SUPPORT
340 pmadapter->chan_bandwidth = 0;
341 pmadapter->adhoc_11n_enabled = MFALSE;
342 #endif /* STA_SUPPORT */
343
344 pmadapter->hw_dot_11ac_dev_cap = 0;
345 pmadapter->hw_dot_11ac_mcs_support = 0;
346 pmadapter->usr_dot_11ac_opermode_bw = 0;
347 pmadapter->usr_dot_11ac_opermode_nss = 0;
348 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT
349 #if CONFIG_WIFI_CAPA
350 pmadapter->usr_dot_11n_enable = MTRUE;
351 #if CONFIG_11AC
352 pmadapter->usr_dot_11ac_enable = MTRUE;
353 #endif
354 #if CONFIG_11AX
355 pmadapter->usr_dot_11ax_enable = MTRUE;
356 #endif
357 #endif
358 #else
359 #if CONFIG_WIFI_CAPA
360 pmadapter->usr_dot_11n_enable = MFALSE;
361 #if CONFIG_11AC
362 pmadapter->usr_dot_11ac_enable = MFALSE;
363 #endif
364 #if CONFIG_11AX
365 pmadapter->usr_dot_11ax_enable = MFALSE;
366 #endif
367 #endif
368 #endif
369 /* Initialize 802.11d */
370 wlan_11d_init(pmadapter);
371 wlan_11h_init(pmadapter);
372
373 wlan_wmm_init(pmadapter);
374 wlan_init_wmm_param(pmadapter);
375 #if CONFIG_WMM_UAPSD
376 (void)__memset(pmadapter, &pmadapter->sleep_params, 0, sizeof(pmadapter->sleep_params));
377 (void)__memset(pmadapter, &pmadapter->sleep_period, 0, sizeof(pmadapter->sleep_period));
378
379 pmadapter->tx_lock_flag = MFALSE;
380 #endif /* CONFIG_WMM_UAPSD */
381 pmadapter->null_pkt_interval = 0;
382 pmadapter->fw_bands = 0U;
383 pmadapter->config_bands = 0U;
384 pmadapter->adhoc_start_band = 0U;
385 /* pmadapter->pscan_channels = MNULL; */
386 pmadapter->fw_release_number = 0;
387 pmadapter->fw_cap_info = 0;
388 (void)__memset(pmadapter, &pmadapter->region_channel, 0, sizeof(pmadapter->region_channel));
389 pmadapter->region_code = MRVDRV_DEFAULT_REGION_CODE;
390 (void)__memcpy(pmadapter, pmadapter->country_code, MRVDRV_DEFAULT_COUNTRY_CODE, COUNTRY_CODE_LEN);
391 pmadapter->adhoc_awake_period = 0;
392 pmadapter->ps_state = PS_STATE_AWAKE;
393 return;
394 }
395
396 /**
397 * @brief This function intializes the lock variables and
398 * the list heads.
399 *
400 * @param pmadapter A pointer to a mlan_adapter structure
401 *
402 * @return MLAN_STATUS_SUCCESS -- on success,
403 * otherwise MLAN_STATUS_FAILURE
404 *
405 */
wlan_init_lock_list(IN pmlan_adapter pmadapter)406 mlan_status wlan_init_lock_list(IN pmlan_adapter pmadapter)
407 {
408 mlan_status ret = MLAN_STATUS_SUCCESS;
409 pmlan_private priv = MNULL;
410 /* pmlan_callbacks pcb = &pmadapter->callbacks; */
411 t_u8 i = 0;
412 t_u8 j = 0;
413
414 ENTER();
415 for (i = 0; i < pmadapter->priv_num; i++)
416 {
417 if (pmadapter->priv[i] != NULL)
418 {
419 priv = pmadapter->priv[i];
420 for (j = 0; j < MAX_NUM_TID; ++j)
421 {
422 util_init_list_head((t_void *)pmadapter->pmoal_handle, &priv->wmm.tid_tbl_ptr[j].ra_list, MTRUE,
423 priv->adapter->callbacks.moal_init_lock);
424 }
425
426 #if CONFIG_WMM
427 /* wmm enhanced reuses 4 ac xmit queues */
428 for (j = 0; j < MAX_AC_QUEUES; ++j)
429 {
430 if (priv->adapter->callbacks.moal_init_semaphore(pmadapter->pmoal_handle, "ra_list_sem",
431 &priv->wmm.tid_tbl_ptr[j].ra_list.plock) !=
432 MLAN_STATUS_SUCCESS)
433 {
434 wifi_e("Create ra_list_sem failed");
435 ret = MLAN_STATUS_FAILURE;
436 goto done;
437 }
438 #if CONFIG_WMM_DEBUG
439 util_init_list_head((t_void *)pmadapter->pmoal_handle, &priv->wmm.hist_ra[j], MFALSE, MNULL);
440 #endif
441 }
442 #endif
443
444 ret = (mlan_status)OSA_MutexCreate((osa_mutex_handle_t)priv->tx_ba_stream_tbl_lock);
445 if (ret != MLAN_STATUS_SUCCESS)
446 {
447 wifi_e("Create Tx BA tbl sem failed");
448 ret = MLAN_STATUS_FAILURE;
449 goto done;
450 }
451
452 util_init_list_head((t_void *)pmadapter->pmoal_handle, &priv->tx_ba_stream_tbl_ptr, MTRUE,
453 pmadapter->callbacks.moal_init_lock);
454
455 ret = (mlan_status)OSA_SemaphoreCreateBinary((osa_semaphore_handle_t)priv->rx_reorder_tbl_lock);
456 if (ret != MLAN_STATUS_SUCCESS)
457 {
458 wifi_e("Create Rx Reorder tbl lock failed");
459 ret = MLAN_STATUS_FAILURE;
460 goto done;
461 }
462 OSA_SemaphorePost((osa_semaphore_handle_t)priv->rx_reorder_tbl_lock);
463 util_init_list_head((t_void *)pmadapter->pmoal_handle, &priv->rx_reorder_tbl_ptr, MTRUE,
464 pmadapter->callbacks.moal_init_lock);
465
466 util_scalar_init((t_void *)pmadapter->pmoal_handle, &priv->wmm.tx_pkts_queued, 0,
467 priv->wmm.ra_list_spinlock, pmadapter->callbacks.moal_init_lock);
468 util_scalar_init((t_void *)pmadapter->pmoal_handle, &priv->wmm.highest_queued_prio, HIGH_PRIO_TID,
469 priv->wmm.ra_list_spinlock, pmadapter->callbacks.moal_init_lock);
470 util_init_list_head((t_void *)pmadapter->pmoal_handle, &priv->sta_list, MTRUE,
471 pmadapter->callbacks.moal_init_lock);
472 }
473 }
474
475 done:
476 /* error: */
477 if (ret != MLAN_STATUS_SUCCESS)
478 {
479 for (i = 0; i < pmadapter->priv_num; i++)
480 {
481 priv = pmadapter->priv[i];
482 #if CONFIG_WMM
483 for (j = 0; j < MAX_AC_QUEUES; ++j)
484 {
485 if ((uint32_t *)(*(uint32_t *)priv->wmm.tid_tbl_ptr[j].ra_list.plock) != NULL)
486 priv->adapter->callbacks.moal_free_semaphore(
487 pmadapter->pmoal_handle, &priv->wmm.tid_tbl_ptr[j].ra_list.plock);
488 }
489 #endif
490 if ((uint32_t *)(*(uint32_t *)priv->tx_ba_stream_tbl_lock) != NULL)
491 OSA_MutexDestroy((osa_mutex_handle_t)priv->tx_ba_stream_tbl_lock);
492 if ((uint32_t *)(*(uint32_t *)priv->rx_reorder_tbl_lock) != NULL)
493 OSA_SemaphoreDestroy((osa_semaphore_handle_t)priv->rx_reorder_tbl_lock);
494 }
495 }
496 LEAVE();
497 return ret;
498 }
499
500 /**
501 * @brief This function initializes firmware
502 *
503 * @param pmadapter A pointer to mlan_adapter
504 *
505 * @return MLAN_STATUS_SUCCESS, MLAN_STATUS_PENDING or MLAN_STATUS_FAILURE
506 */
wlan_init_fw(IN pmlan_adapter pmadapter)507 mlan_status wlan_init_fw(IN pmlan_adapter pmadapter)
508 {
509 mlan_status ret = MLAN_STATUS_SUCCESS;
510 pmlan_private priv = MNULL;
511 t_u8 i = 0;
512
513 ENTER();
514
515 /* Initialize adapter structure */
516 wlan_init_adapter(pmadapter);
517
518 for (i = 0; i < pmadapter->priv_num; i++)
519 {
520 if (pmadapter->priv[i] != NULL)
521 {
522 priv = pmadapter->priv[i];
523
524 /* Initialize private structure */
525 if ((ret = wlan_init_priv(priv)) != MLAN_STATUS_SUCCESS)
526 {
527 ret = MLAN_STATUS_FAILURE;
528 goto done;
529 }
530 }
531 }
532 #ifdef WIFI_CALIB_CMD_SUPPORT
533 if (pmadapter->wifi_calib_mode != MTRUE)
534 {
535 #endif
536 /* Issue firmware initialize commands for first BSS, for other
537 interfaces it will be called after getting the last init command
538 response of previous interface */
539 done:
540 LEAVE();
541 return ret;
542 }
543
544 /**
545 * @brief This function frees the structure of adapter
546 *
547 * @param pmadapter A pointer to mlan_adapter structure
548 *
549 * @return N/A
550 */
551 t_void wlan_free_adapter(pmlan_adapter pmadapter)
552 {
553 ENTER();
554
555 if (!pmadapter)
556 {
557 PRINTM(MERROR, "The adapter is NULL\n");
558 LEAVE();
559 return;
560 }
561
562 LEAVE();
563 return;
564 }
565