1 /*
2 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <esp_event.h>
8 #include <esp_wifi.h>
9 #include "esp_log.h"
10 #include "esp_private/wifi.h"
11 #include "esp_pm.h"
12 #include "esp_sleep.h"
13 #include "esp_private/pm_impl.h"
14 #include "soc/rtc.h"
15 #include "esp_wpa.h"
16 #include "esp_netif.h"
17 #include "tcpip_adapter_compatible/tcpip_adapter_compat.h"
18 #include "driver/adc2_wifi_private.h"
19 #include "esp_coexist_internal.h"
20 #include "esp_phy_init.h"
21 #include "phy.h"
22
23 #if (CONFIG_ESP32_WIFI_RX_BA_WIN > CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM)
24 #error "WiFi configuration check: WARNING, WIFI_RX_BA_WIN should not be larger than WIFI_DYNAMIC_RX_BUFFER_NUM!"
25 #endif
26
27 #if (CONFIG_ESP32_WIFI_RX_BA_WIN > (CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM << 1))
28 #error "WiFi configuration check: WARNING, WIFI_RX_BA_WIN should not be larger than double of the WIFI_STATIC_RX_BUFFER_NUM!"
29 #endif
30
31 ESP_EVENT_DEFINE_BASE(WIFI_EVENT);
32
33 extern uint8_t esp_wifi_get_user_init_flag_internal(void);
34 #ifdef CONFIG_PM_ENABLE
35 static esp_pm_lock_handle_t s_wifi_modem_sleep_lock;
36 #endif
37
38 /* Set additional WiFi features and capabilities */
39 uint64_t g_wifi_feature_caps =
40 #if CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE
41 CONFIG_FEATURE_WPA3_SAE_BIT |
42 #endif
43 #if (CONFIG_ESP32_SPIRAM_SUPPORT || CONFIG_ESP32S2_SPIRAM_SUPPORT || CONFIG_ESP32S3_SPIRAM_SUPPORT)
44 CONFIG_FEATURE_CACHE_TX_BUF_BIT |
45 #endif
46 #if CONFIG_ESP_WIFI_FTM_INITIATOR_SUPPORT
47 CONFIG_FEATURE_FTM_INITIATOR_BIT |
48 #endif
49 #if CONFIG_ESP_WIFI_FTM_RESPONDER_SUPPORT
50 CONFIG_FEATURE_FTM_RESPONDER_BIT |
51 #endif
52 0;
53
54
55 static const char* TAG = "wifi_init";
56
s_set_default_wifi_log_level(void)57 static void __attribute__((constructor)) s_set_default_wifi_log_level(void)
58 {
59 /* WiFi libraries aren't compiled to know CONFIG_LOG_DEFAULT_LEVEL,
60 so set it at runtime startup. Done here not in esp_wifi_init() to allow
61 the user to set the level again before esp_wifi_init() is called.
62 */
63 esp_log_level_set("wifi", CONFIG_LOG_DEFAULT_LEVEL);
64 esp_log_level_set("mesh", CONFIG_LOG_DEFAULT_LEVEL);
65 esp_log_level_set("smartconfig", CONFIG_LOG_DEFAULT_LEVEL);
66 esp_log_level_set("ESPNOW", CONFIG_LOG_DEFAULT_LEVEL);
67 }
68
esp_wifi_set_log_level(void)69 static void esp_wifi_set_log_level(void)
70 {
71 wifi_log_level_t wifi_log_level = WIFI_LOG_INFO;
72 /* set WiFi log level */
73 #if CONFIG_LOG_MAXIMUM_LEVEL == 0
74 wifi_log_level = WIFI_LOG_NONE;
75 #elif CONFIG_LOG_MAXIMUM_LEVEL == 1
76 wifi_log_level = WIFI_LOG_ERROR;
77 #elif CONFIG_LOG_MAXIMUM_LEVEL == 2
78 wifi_log_level = WIFI_LOG_WARNING;
79 #elif CONFIG_LOG_MAXIMUM_LEVEL == 3
80 wifi_log_level = WIFI_LOG_INFO;
81 #elif CONFIG_LOG_MAXIMUM_LEVEL == 4
82 wifi_log_level = WIFI_LOG_DEBUG;
83 #elif CONFIG_LOG_MAXIMUM_LEVEL == 5
84 wifi_log_level = WIFI_LOG_VERBOSE;
85 #endif
86 esp_wifi_internal_set_log_level(wifi_log_level);
87 }
88
esp_wifi_deinit(void)89 esp_err_t esp_wifi_deinit(void)
90 {
91 esp_err_t err = ESP_OK;
92
93 if (esp_wifi_get_user_init_flag_internal()) {
94 ESP_LOGE(TAG, "Wi-Fi not stop");
95 return ESP_ERR_WIFI_NOT_STOPPED;
96 }
97
98 if (esp_wifi_internal_reg_rxcb(WIFI_IF_STA, NULL) != ESP_OK ||
99 esp_wifi_internal_reg_rxcb(WIFI_IF_AP, NULL) != ESP_OK) {
100 ESP_LOGW(TAG, "Failed to unregister Rx callbacks");
101 }
102
103 esp_supplicant_deinit();
104 err = esp_wifi_deinit_internal();
105 if (err != ESP_OK) {
106 ESP_LOGE(TAG, "Failed to deinit Wi-Fi driver (0x%x)", err);
107 return err;
108 }
109
110 #if CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER
111 tcpip_adapter_clear_default_wifi_handlers();
112 #endif
113 #if CONFIG_ESP_WIFI_SLP_IRAM_OPT
114 esp_pm_unregister_light_sleep_default_params_config_callback();
115 #endif
116 #if CONFIG_FREERTOS_USE_TICKLESS_IDLE
117 #if SOC_WIFI_HW_TSF
118 esp_pm_unregister_skip_light_sleep_callback(esp_wifi_internal_is_tsf_active);
119 esp_pm_unregister_inform_out_light_sleep_overhead_callback(esp_wifi_internal_update_light_sleep_wake_ahead_time);
120 esp_sleep_disable_wifi_wakeup();
121 #endif
122 #endif
123 #if CONFIG_MAC_BB_PD
124 esp_unregister_mac_bb_pd_callback(pm_mac_sleep);
125 esp_unregister_mac_bb_pu_callback(pm_mac_wakeup);
126 #endif
127 #if CONFIG_IDF_TARGET_ESP32C3
128 phy_init_flag();
129 #endif
130 esp_wifi_power_domain_off();
131 return err;
132 }
133
esp_wifi_config_info(void)134 static void esp_wifi_config_info(void)
135 {
136 #ifdef CONFIG_ESP32_WIFI_RX_BA_WIN
137 ESP_LOGI(TAG, "rx ba win: %d", CONFIG_ESP32_WIFI_RX_BA_WIN);
138 #endif
139
140 #ifdef CONFIG_ESP_NETIF_TCPIP_LWIP
141 ESP_LOGI(TAG, "tcpip mbox: %d", CONFIG_LWIP_TCPIP_RECVMBOX_SIZE);
142 ESP_LOGI(TAG, "udp mbox: %d", CONFIG_LWIP_UDP_RECVMBOX_SIZE);
143 ESP_LOGI(TAG, "tcp mbox: %d", CONFIG_LWIP_TCP_RECVMBOX_SIZE);
144 ESP_LOGI(TAG, "tcp tx win: %d", CONFIG_LWIP_TCP_SND_BUF_DEFAULT);
145 ESP_LOGI(TAG, "tcp rx win: %d", CONFIG_LWIP_TCP_WND_DEFAULT);
146 ESP_LOGI(TAG, "tcp mss: %d", CONFIG_LWIP_TCP_MSS);
147
148 #ifdef CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP
149 ESP_LOGI(TAG, "WiFi/LWIP prefer SPIRAM");
150 #endif
151
152 #ifdef CONFIG_ESP32_WIFI_IRAM_OPT
153 ESP_LOGI(TAG, "WiFi IRAM OP enabled");
154 #endif
155
156 #ifdef CONFIG_ESP32_WIFI_RX_IRAM_OPT
157 ESP_LOGI(TAG, "WiFi RX IRAM OP enabled");
158 #endif
159
160 #ifdef CONFIG_ESP_WIFI_SLP_IRAM_OPT
161 ESP_LOGI(TAG, "WiFi SLP IRAM OP enabled");
162 #endif
163
164 #ifdef CONFIG_LWIP_IRAM_OPTIMIZATION
165 ESP_LOGI(TAG, "LWIP IRAM OP enabled");
166 #endif
167
168 #else
169 ESP_LOGI(TAG, "LWIP disabled");
170 #endif
171 }
172
esp_wifi_init(const wifi_init_config_t * config)173 esp_err_t esp_wifi_init(const wifi_init_config_t *config)
174 {
175 esp_wifi_power_domain_on();
176 #ifdef CONFIG_PM_ENABLE
177 if (s_wifi_modem_sleep_lock == NULL) {
178 esp_err_t err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "wifi",
179 &s_wifi_modem_sleep_lock);
180 if (err != ESP_OK) {
181 return err;
182 }
183 }
184 #endif
185
186 #if CONFIG_ESP_WIFI_SLP_IRAM_OPT
187 esp_pm_register_light_sleep_default_params_config_callback(esp_wifi_internal_update_light_sleep_default_params);
188
189 int min_freq_mhz = esp_pm_impl_get_cpu_freq(PM_MODE_LIGHT_SLEEP);
190 int max_freq_mhz = esp_pm_impl_get_cpu_freq(PM_MODE_CPU_MAX);
191 esp_wifi_internal_update_light_sleep_default_params(min_freq_mhz, max_freq_mhz);
192
193 uint32_t sleep_delay_us = CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME * 1000;
194 esp_wifi_set_sleep_delay_time(sleep_delay_us);
195
196 uint32_t keep_alive_time_us = CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME * 1000 * 1000;
197 esp_wifi_set_keep_alive_time(keep_alive_time_us);
198 #endif
199
200 #if CONFIG_FREERTOS_USE_TICKLESS_IDLE
201 #if CONFIG_MAC_BB_PD
202 if (esp_register_mac_bb_pd_callback(pm_mac_sleep) != ESP_OK
203 || esp_register_mac_bb_pu_callback(pm_mac_wakeup) != ESP_OK) {
204
205 esp_unregister_mac_bb_pd_callback(pm_mac_sleep);
206 esp_unregister_mac_bb_pu_callback(pm_mac_wakeup);
207 return ESP_ERR_INVALID_ARG;
208 }
209 #endif
210
211 #if SOC_WIFI_HW_TSF
212 esp_err_t ret = esp_pm_register_skip_light_sleep_callback(esp_wifi_internal_is_tsf_active);
213 if (ret != ESP_OK) {
214 ESP_LOGE(TAG, "Failed to register skip light sleep callback (0x%x)", ret);
215 #if CONFIG_MAC_BB_PD
216 esp_unregister_mac_bb_pd_callback(pm_mac_sleep);
217 esp_unregister_mac_bb_pu_callback(pm_mac_wakeup);
218 #endif
219 return ret;
220 }
221 ret = esp_pm_register_inform_out_light_sleep_overhead_callback(esp_wifi_internal_update_light_sleep_wake_ahead_time);
222 if (ret != ESP_OK) {
223 ESP_LOGE(TAG, "Failed to register inform light sleep overhead callback (0x%x)", ret);
224 return ret;
225 }
226 esp_sleep_enable_wifi_wakeup();
227 #endif
228 #endif
229
230 #if CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER
231 esp_err_t err = tcpip_adapter_set_default_wifi_handlers();
232 if (err != ESP_OK) {
233 ESP_LOGW(TAG, "Failed to set default Wi-Fi event handlers (0x%x)", err);
234 }
235 #endif
236 #if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE
237 coex_init();
238 #endif
239 esp_wifi_set_log_level();
240 esp_err_t result = esp_wifi_init_internal(config);
241 if (result == ESP_OK) {
242 #if CONFIG_MAC_BB_PD
243 esp_mac_bb_pd_mem_init();
244 esp_wifi_internal_set_mac_sleep(true);
245 #endif
246 #if CONFIG_IDF_TARGET_ESP32
247 s_wifi_mac_time_update_cb = esp_wifi_internal_update_mac_time;
248 #endif
249
250 result = esp_supplicant_init();
251 if (result != ESP_OK) {
252 ESP_LOGE(TAG, "Failed to init supplicant (0x%x)", result);
253 esp_err_t deinit_ret = esp_wifi_deinit();
254 if (deinit_ret != ESP_OK) {
255 ESP_LOGE(TAG, "Failed to deinit Wi-Fi (0x%x)", deinit_ret);
256 }
257
258 return result;
259 }
260 }
261 adc2_cal_include(); //This enables the ADC2 calibration constructor at start up.
262
263 esp_wifi_config_info();
264 return result;
265 }
266
267 #ifdef CONFIG_PM_ENABLE
wifi_apb80m_request(void)268 void wifi_apb80m_request(void)
269 {
270 assert(s_wifi_modem_sleep_lock);
271 esp_pm_lock_acquire(s_wifi_modem_sleep_lock);
272 if (rtc_clk_apb_freq_get() != APB_CLK_FREQ) {
273 ESP_LOGE(__func__, "WiFi needs 80MHz APB frequency to work, but got %dHz", rtc_clk_apb_freq_get());
274 }
275 }
276
wifi_apb80m_release(void)277 void wifi_apb80m_release(void)
278 {
279 assert(s_wifi_modem_sleep_lock);
280 esp_pm_lock_release(s_wifi_modem_sleep_lock);
281 }
282 #endif //CONFIG_PM_ENABLE
283
284 #ifndef CONFIG_ESP_WIFI_FTM_ENABLE
ieee80211_ftm_attach(void)285 void ieee80211_ftm_attach(void)
286 {
287 /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */
288 }
289 #endif
290
291 #ifndef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
net80211_softap_funcs_init(void)292 void net80211_softap_funcs_init(void)
293 {
294 }
295 #endif
296