1 /*
2  * Copyright (c) 2020 Espressif Systems (Shanghai) Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT espressif_esp32_wifi
8 
9 #include <zephyr/logging/log.h>
10 LOG_MODULE_REGISTER(esp32_wifi, CONFIG_WIFI_LOG_LEVEL);
11 
12 #include <zephyr/net/ethernet.h>
13 #include <zephyr/net/net_pkt.h>
14 #include <zephyr/net/net_if.h>
15 #include <zephyr/net/wifi_mgmt.h>
16 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
17 #include <zephyr/net/wifi_nm.h>
18 #include <zephyr/net/conn_mgr/connectivity_wifi_mgmt.h>
19 #endif
20 #include <zephyr/device.h>
21 #include <soc.h>
22 #include "esp_private/wifi.h"
23 #include "esp_event.h"
24 #include "esp_timer.h"
25 #include "esp_system.h"
26 #include "esp_wpa.h"
27 #include <esp_mac.h>
28 #include "wifi/wifi_event.h"
29 
30 #if CONFIG_SOC_SERIES_ESP32S2 || CONFIG_SOC_SERIES_ESP32C3
31 #include <esp_private/adc_share_hw_ctrl.h>
32 #endif /* CONFIG_SOC_SERIES_ESP32S2 || CONFIG_SOC_SERIES_ESP32C3 */
33 
34 #define DHCPV4_MASK (NET_EVENT_IPV4_DHCP_BOUND | NET_EVENT_IPV4_DHCP_STOP)
35 
36 /* use global iface pointer to support any ethernet driver */
37 /* necessary for wifi callback functions */
38 static struct net_if *esp32_wifi_iface;
39 static struct esp32_wifi_runtime esp32_data;
40 
41 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
42 static struct net_if *esp32_wifi_iface_ap;
43 static struct esp32_wifi_runtime esp32_ap_sta_data;
44 #endif
45 
46 enum esp32_state_flag {
47 	ESP32_STA_STOPPED,
48 	ESP32_STA_STARTED,
49 	ESP32_STA_CONNECTING,
50 	ESP32_STA_CONNECTED,
51 	ESP32_AP_STARTED,
52 	ESP32_AP_CONNECTED,
53 	ESP32_AP_DISCONNECTED,
54 	ESP32_AP_STOPPED,
55 };
56 
57 struct esp32_wifi_status {
58 	char ssid[WIFI_SSID_MAX_LEN + 1];
59 	char pass[WIFI_PSK_MAX_LEN + 1];
60 	wifi_auth_mode_t security;
61 	bool connected;
62 	uint8_t channel;
63 	int rssi;
64 };
65 
66 struct esp32_wifi_runtime {
67 	uint8_t mac_addr[6];
68 	uint8_t frame_buf[NET_ETH_MAX_FRAME_SIZE];
69 #if defined(CONFIG_NET_STATISTICS_WIFI)
70 	struct net_stats_wifi stats;
71 #endif
72 	struct esp32_wifi_status status;
73 	scan_result_cb_t scan_cb;
74 	uint8_t state;
75 	uint8_t ap_connection_cnt;
76 };
77 
78 static struct net_mgmt_event_callback esp32_dhcp_cb;
79 
wifi_event_handler(struct net_mgmt_event_callback * cb,uint32_t mgmt_event,struct net_if * iface)80 static void wifi_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event,
81 			       struct net_if *iface)
82 {
83 	switch (mgmt_event) {
84 	case NET_EVENT_IPV4_DHCP_BOUND:
85 		wifi_mgmt_raise_connect_result_event(iface, 0);
86 		break;
87 	default:
88 		break;
89 	}
90 }
91 
esp32_wifi_send(const struct device * dev,struct net_pkt * pkt)92 static int esp32_wifi_send(const struct device *dev, struct net_pkt *pkt)
93 {
94 	struct esp32_wifi_runtime *data = dev->data;
95 	const int pkt_len = net_pkt_get_len(pkt);
96 	esp_interface_t ifx = data->state == ESP32_AP_CONNECTED ? ESP_IF_WIFI_AP : ESP_IF_WIFI_STA;
97 
98 	/* Read the packet payload */
99 	if (net_pkt_read(pkt, data->frame_buf, pkt_len) < 0) {
100 		goto out;
101 	}
102 
103 	/* Enqueue packet for transmission */
104 	if (esp_wifi_internal_tx(ifx, (void *)data->frame_buf, pkt_len) != ESP_OK) {
105 		goto out;
106 	}
107 
108 #if defined(CONFIG_NET_STATISTICS_WIFI)
109 	data->stats.bytes.sent += pkt_len;
110 	data->stats.pkts.tx++;
111 #endif
112 
113 	LOG_DBG("pkt sent %p len %d", pkt, pkt_len);
114 	return 0;
115 
116 out:
117 
118 	LOG_ERR("Failed to send packet");
119 #if defined(CONFIG_NET_STATISTICS_WIFI)
120 	data->stats.errors.tx++;
121 #endif
122 	return -EIO;
123 }
124 
eth_esp32_rx(void * buffer,uint16_t len,void * eb)125 static esp_err_t eth_esp32_rx(void *buffer, uint16_t len, void *eb)
126 {
127 	struct net_pkt *pkt;
128 
129 	if (esp32_wifi_iface == NULL) {
130 		esp_wifi_internal_free_rx_buffer(eb);
131 		LOG_ERR("network interface unavailable");
132 		return -EIO;
133 	}
134 
135 	pkt = net_pkt_rx_alloc_with_buffer(esp32_wifi_iface, len, AF_UNSPEC, 0, K_MSEC(100));
136 	if (!pkt) {
137 		LOG_ERR("Failed to allocate net buffer");
138 		esp_wifi_internal_free_rx_buffer(eb);
139 		return -EIO;
140 	}
141 
142 	if (net_pkt_write(pkt, buffer, len) < 0) {
143 		LOG_ERR("Failed to write to net buffer");
144 		goto pkt_unref;
145 	}
146 
147 	if (net_recv_data(esp32_wifi_iface, pkt) < 0) {
148 		LOG_ERR("Failed to push received data");
149 		goto pkt_unref;
150 	}
151 
152 #if defined(CONFIG_NET_STATISTICS_WIFI)
153 	esp32_data.stats.bytes.received += len;
154 	esp32_data.stats.pkts.rx++;
155 #endif
156 
157 	esp_wifi_internal_free_rx_buffer(eb);
158 	return 0;
159 
160 pkt_unref:
161 	esp_wifi_internal_free_rx_buffer(eb);
162 	net_pkt_unref(pkt);
163 
164 #if defined(CONFIG_NET_STATISTICS_WIFI)
165 	esp32_data.stats.errors.rx++;
166 #endif
167 
168 	return -EIO;
169 }
170 
171 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
wifi_esp32_ap_iface_rx(void * buffer,uint16_t len,void * eb)172 static esp_err_t wifi_esp32_ap_iface_rx(void *buffer, uint16_t len, void *eb)
173 {
174 	struct net_pkt *pkt;
175 
176 	if (esp32_wifi_iface_ap == NULL) {
177 		esp_wifi_internal_free_rx_buffer(eb);
178 		LOG_ERR("network interface unavailable");
179 		return -EIO;
180 	}
181 
182 	pkt = net_pkt_rx_alloc_with_buffer(esp32_wifi_iface_ap, len, AF_UNSPEC, 0, K_MSEC(100));
183 	if (!pkt) {
184 		esp_wifi_internal_free_rx_buffer(eb);
185 		LOG_ERR("Failed to get net buffer");
186 		return -EIO;
187 	}
188 
189 	if (net_pkt_write(pkt, buffer, len) < 0) {
190 		LOG_ERR("Failed to write pkt");
191 		goto pkt_unref;
192 	}
193 
194 	if (net_recv_data(esp32_wifi_iface_ap, pkt) < 0) {
195 		LOG_ERR("Failed to push received data");
196 		goto pkt_unref;
197 	}
198 
199 #if defined(CONFIG_NET_STATISTICS_WIFI)
200 	esp32_ap_sta_data.stats.bytes.received += len;
201 	esp32_ap_sta_data.stats.pkts.rx++;
202 #endif
203 
204 	esp_wifi_internal_free_rx_buffer(eb);
205 	return 0;
206 
207 pkt_unref:
208 	esp_wifi_internal_free_rx_buffer(eb);
209 	net_pkt_unref(pkt);
210 
211 #if defined(CONFIG_NET_STATISTICS_WIFI)
212 	esp32_ap_sta_data.stats.errors.rx++;
213 #endif
214 	return -EIO;
215 }
216 #endif
217 
scan_done_handler(void)218 static void scan_done_handler(void)
219 {
220 	uint16_t aps = 0;
221 	wifi_ap_record_t *ap_list_buffer;
222 	struct wifi_scan_result res = { 0 };
223 
224 	esp_wifi_scan_get_ap_num(&aps);
225 	if (!aps) {
226 		LOG_INF("No Wi-Fi AP found");
227 		goto out;
228 	}
229 
230 	ap_list_buffer = k_malloc(aps * sizeof(wifi_ap_record_t));
231 	if (ap_list_buffer == NULL) {
232 		LOG_INF("Failed to malloc buffer to print scan results");
233 		goto out;
234 	}
235 
236 	if (esp_wifi_scan_get_ap_records(&aps, (wifi_ap_record_t *)ap_list_buffer) == ESP_OK) {
237 		for (int k = 0; k < aps; k++) {
238 			memset(&res, 0, sizeof(struct wifi_scan_result));
239 			int ssid_len = strnlen(ap_list_buffer[k].ssid, WIFI_SSID_MAX_LEN);
240 
241 			res.ssid_length = ssid_len;
242 			strncpy(res.ssid, ap_list_buffer[k].ssid, ssid_len);
243 			res.rssi = ap_list_buffer[k].rssi;
244 			res.channel = ap_list_buffer[k].primary;
245 
246 			memcpy(res.mac, ap_list_buffer[k].bssid, WIFI_MAC_ADDR_LEN);
247 			res.mac_length = WIFI_MAC_ADDR_LEN;
248 
249 			switch (ap_list_buffer[k].authmode) {
250 			case WIFI_AUTH_OPEN:
251 				res.security = WIFI_SECURITY_TYPE_NONE;
252 				break;
253 			case WIFI_AUTH_WPA2_PSK:
254 				res.security = WIFI_SECURITY_TYPE_PSK;
255 				break;
256 			case WIFI_AUTH_WPA3_PSK:
257 				res.security = WIFI_SECURITY_TYPE_SAE;
258 				break;
259 			case WIFI_AUTH_WAPI_PSK:
260 				res.security = WIFI_SECURITY_TYPE_WAPI;
261 				break;
262 			case WIFI_AUTH_WPA2_ENTERPRISE:
263 				res.security = WIFI_SECURITY_TYPE_EAP;
264 				break;
265 			case WIFI_AUTH_WEP:
266 				res.security = WIFI_SECURITY_TYPE_WEP;
267 				break;
268 			case WIFI_AUTH_WPA_PSK:
269 				res.security = WIFI_SECURITY_TYPE_WPA_PSK;
270 				break;
271 			default:
272 				res.security = WIFI_SECURITY_TYPE_UNKNOWN;
273 				break;
274 			}
275 
276 			if (esp32_data.scan_cb) {
277 				esp32_data.scan_cb(esp32_wifi_iface, 0, &res);
278 
279 				/* ensure notifications get delivered */
280 				k_yield();
281 			}
282 		}
283 	} else {
284 		LOG_INF("Unable to retrieve AP records");
285 	}
286 
287 	k_free(ap_list_buffer);
288 
289 out:
290 	/* report end of scan event */
291 	esp32_data.scan_cb(esp32_wifi_iface, 0, NULL);
292 	esp32_data.scan_cb = NULL;
293 }
294 
esp_wifi_handle_sta_connect_event(void * event_data)295 static void esp_wifi_handle_sta_connect_event(void *event_data)
296 {
297 	ARG_UNUSED(event_data);
298 	esp32_data.state = ESP32_STA_CONNECTED;
299 #if defined(CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4)
300 	net_dhcpv4_start(esp32_wifi_iface);
301 #else
302 	wifi_mgmt_raise_connect_result_event(esp32_wifi_iface, 0);
303 #endif
304 }
305 
esp_wifi_handle_sta_disconnect_event(void * event_data)306 static void esp_wifi_handle_sta_disconnect_event(void *event_data)
307 {
308 	wifi_event_sta_disconnected_t *event = (wifi_event_sta_disconnected_t *)event_data;
309 
310 	if (esp32_data.state == ESP32_STA_CONNECTED) {
311 #if defined(CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4)
312 		net_dhcpv4_stop(esp32_wifi_iface);
313 #endif
314 		wifi_mgmt_raise_disconnect_result_event(esp32_wifi_iface, 0);
315 	} else {
316 		wifi_mgmt_raise_disconnect_result_event(esp32_wifi_iface, -1);
317 	}
318 
319 	LOG_DBG("Disconnect reason: %d", event->reason);
320 	switch (event->reason) {
321 	case WIFI_REASON_AUTH_EXPIRE:
322 	case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT:
323 	case WIFI_REASON_AUTH_FAIL:
324 	case WIFI_REASON_HANDSHAKE_TIMEOUT:
325 	case WIFI_REASON_MIC_FAILURE:
326 		LOG_DBG("STA Auth Error");
327 		break;
328 	case WIFI_REASON_NO_AP_FOUND:
329 		LOG_DBG("AP Not found");
330 		break;
331 	default:
332 		break;
333 	}
334 
335 	if (IS_ENABLED(CONFIG_ESP32_WIFI_STA_RECONNECT) &&
336 	    (event->reason != WIFI_REASON_ASSOC_LEAVE)) {
337 		esp32_data.state = ESP32_STA_CONNECTING;
338 		esp_wifi_connect();
339 	} else {
340 		esp32_data.state = ESP32_STA_STARTED;
341 	}
342 }
343 
esp_wifi_handle_ap_connect_event(void * event_data)344 static void esp_wifi_handle_ap_connect_event(void *event_data)
345 {
346 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
347 	struct net_if *iface = esp32_wifi_iface_ap;
348 	wifi_rxcb_t esp32_rx = wifi_esp32_ap_iface_rx;
349 #else
350 	struct net_if *iface = esp32_wifi_iface;
351 	wifi_rxcb_t esp32_rx = eth_esp32_rx;
352 #endif
353 	wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *)event_data;
354 
355 	LOG_DBG("Station " MACSTR " join, AID=%d", MAC2STR(event->mac), event->aid);
356 
357 	wifi_sta_list_t sta_list;
358 	struct wifi_ap_sta_info sta_info;
359 
360 	sta_info.link_mode = WIFI_LINK_MODE_UNKNOWN;
361 	sta_info.twt_capable = false; /* Only support in 802.11ax */
362 	sta_info.mac_length = WIFI_MAC_ADDR_LEN;
363 	memcpy(sta_info.mac, event->mac, WIFI_MAC_ADDR_LEN);
364 
365 	/* Expect the return value to always be ESP_OK,
366 	 * since it is called in esp_wifi_event_handler()
367 	 */
368 	(void)esp_wifi_ap_get_sta_list(&sta_list);
369 	for (int i = 0; i < sta_list.num; i++) {
370 		wifi_sta_info_t *sta = &sta_list.sta[i];
371 
372 		if (memcmp(event->mac, sta->mac, 6) == 0) {
373 			if (sta->phy_11n) {
374 				sta_info.link_mode = WIFI_4;
375 			} else if (sta->phy_11g) {
376 				sta_info.link_mode = WIFI_3;
377 			} else if (sta->phy_11b) {
378 				sta_info.link_mode = WIFI_1;
379 			} else {
380 				sta_info.link_mode = WIFI_LINK_MODE_UNKNOWN;
381 			}
382 			break;
383 		}
384 	}
385 
386 	wifi_mgmt_raise_ap_sta_connected_event(iface, &sta_info);
387 
388 	if (!(esp32_data.ap_connection_cnt++)) {
389 		esp_wifi_internal_reg_rxcb(WIFI_IF_AP, esp32_rx);
390 	}
391 }
392 
esp_wifi_handle_ap_disconnect_event(void * event_data)393 static void esp_wifi_handle_ap_disconnect_event(void *event_data)
394 {
395 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
396 	struct net_if *iface = esp32_wifi_iface_ap;
397 #else
398 	struct net_if *iface = esp32_wifi_iface;
399 #endif
400 	wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *)event_data;
401 
402 	LOG_DBG("station " MACSTR " leave, AID=%d", MAC2STR(event->mac), event->aid);
403 	struct wifi_ap_sta_info sta_info;
404 
405 	sta_info.link_mode = WIFI_LINK_MODE_UNKNOWN;
406 	sta_info.twt_capable = false; /* Only support in 802.11ax */
407 	sta_info.mac_length = WIFI_MAC_ADDR_LEN;
408 	memcpy(sta_info.mac, event->mac, WIFI_MAC_ADDR_LEN);
409 	wifi_mgmt_raise_ap_sta_disconnected_event(iface, &sta_info);
410 
411 	if (!(--esp32_data.ap_connection_cnt)) {
412 		esp_wifi_internal_reg_rxcb(WIFI_IF_AP, NULL);
413 	}
414 }
415 
esp_wifi_event_handler(const char * event_base,int32_t event_id,void * event_data,size_t event_data_size,uint32_t ticks_to_wait)416 void esp_wifi_event_handler(const char *event_base, int32_t event_id, void *event_data,
417 			    size_t event_data_size, uint32_t ticks_to_wait)
418 {
419 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
420 	struct net_if *iface_ap = esp32_wifi_iface_ap;
421 	struct esp32_wifi_runtime *ap_data = &esp32_ap_sta_data;
422 #else
423 	struct net_if *iface_ap = esp32_wifi_iface;
424 	struct esp32_wifi_runtime *ap_data = &esp32_data;
425 #endif
426 
427 	LOG_DBG("Wi-Fi event: %d", event_id);
428 	switch (event_id) {
429 	case WIFI_EVENT_STA_START:
430 		esp32_data.state = ESP32_STA_STARTED;
431 		net_eth_carrier_on(esp32_wifi_iface);
432 		break;
433 	case WIFI_EVENT_STA_STOP:
434 		esp32_data.state = ESP32_STA_STOPPED;
435 		net_eth_carrier_off(esp32_wifi_iface);
436 		break;
437 	case WIFI_EVENT_STA_CONNECTED:
438 		esp_wifi_handle_sta_connect_event(event_data);
439 		break;
440 	case WIFI_EVENT_STA_DISCONNECTED:
441 		esp_wifi_handle_sta_disconnect_event(event_data);
442 		break;
443 	case WIFI_EVENT_SCAN_DONE:
444 		scan_done_handler();
445 		break;
446 	case WIFI_EVENT_AP_START:
447 		ap_data->state = ESP32_AP_STARTED;
448 		net_eth_carrier_on(iface_ap);
449 		wifi_mgmt_raise_ap_enable_result_event(iface_ap, 0);
450 		break;
451 	case WIFI_EVENT_AP_STOP:
452 		ap_data->state = ESP32_AP_STOPPED;
453 		net_eth_carrier_off(iface_ap);
454 		wifi_mgmt_raise_ap_disable_result_event(iface_ap, 0);
455 		break;
456 	case WIFI_EVENT_AP_STACONNECTED:
457 		ap_data->state = ESP32_AP_CONNECTED;
458 		esp_wifi_handle_ap_connect_event(event_data);
459 		break;
460 	case WIFI_EVENT_AP_STADISCONNECTED:
461 		ap_data->state = ESP32_AP_DISCONNECTED;
462 		esp_wifi_handle_ap_disconnect_event(event_data);
463 		break;
464 	default:
465 		break;
466 	}
467 }
468 
esp32_wifi_disconnect(const struct device * dev)469 static int esp32_wifi_disconnect(const struct device *dev)
470 {
471 	int ret = esp_wifi_disconnect();
472 
473 	if (ret != ESP_OK) {
474 		LOG_INF("Failed to disconnect from hotspot");
475 		return -EAGAIN;
476 	}
477 
478 	return 0;
479 }
480 
esp32_wifi_connect(const struct device * dev,struct wifi_connect_req_params * params)481 static int esp32_wifi_connect(const struct device *dev,
482 			    struct wifi_connect_req_params *params)
483 {
484 	struct esp32_wifi_runtime *data = dev->data;
485 	struct net_if *iface = net_if_lookup_by_dev(dev);
486 	wifi_mode_t mode;
487 	int ret;
488 
489 	if (data->state == ESP32_STA_CONNECTING || data->state == ESP32_STA_CONNECTED) {
490 		wifi_mgmt_raise_connect_result_event(iface, -1);
491 		return -EALREADY;
492 	}
493 
494 	ret = esp_wifi_get_mode(&mode);
495 	if (ret) {
496 		LOG_ERR("Failed to get Wi-Fi mode (%d)", ret);
497 		return -EAGAIN;
498 	}
499 
500 	if (IS_ENABLED(CONFIG_ESP32_WIFI_AP_STA_MODE) &&
501 	    (mode == ESP32_WIFI_MODE_AP || mode == ESP32_WIFI_MODE_APSTA)) {
502 		ret = esp_wifi_set_mode(ESP32_WIFI_MODE_APSTA);
503 	} else {
504 		ret = esp_wifi_set_mode(ESP32_WIFI_MODE_STA);
505 	}
506 
507 	if (ret) {
508 		LOG_ERR("Failed to set Wi-Fi mode (%d)", ret);
509 		return -EAGAIN;
510 	}
511 	ret = esp_wifi_start();
512 	if (ret) {
513 		LOG_ERR("Failed to start Wi-Fi driver (%d)", ret);
514 		return -EAGAIN;
515 	}
516 
517 	if (data->state != ESP32_STA_STARTED) {
518 		LOG_ERR("Wi-Fi not in station mode");
519 		wifi_mgmt_raise_connect_result_event(iface, -1);
520 		return -EIO;
521 	}
522 
523 	data->state = ESP32_STA_CONNECTING;
524 
525 	memcpy(data->status.ssid, params->ssid, params->ssid_length);
526 	data->status.ssid[params->ssid_length] = '\0';
527 
528 	wifi_config_t wifi_config;
529 
530 	memset(&wifi_config, 0, sizeof(wifi_config_t));
531 
532 	memcpy(wifi_config.sta.ssid, params->ssid, params->ssid_length);
533 	wifi_config.sta.ssid[params->ssid_length] = '\0';
534 	switch (params->security) {
535 	case WIFI_SECURITY_TYPE_NONE:
536 		wifi_config.sta.threshold.authmode = WIFI_AUTH_OPEN;
537 		data->status.security = WIFI_AUTH_OPEN;
538 		wifi_config.sta.pmf_cfg.required = false;
539 		break;
540 	case WIFI_SECURITY_TYPE_PSK:
541 		memcpy(wifi_config.sta.password, params->psk, params->psk_length);
542 		wifi_config.sta.password[params->psk_length] = '\0';
543 		wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK;
544 		wifi_config.sta.pmf_cfg.required = false;
545 		data->status.security = WIFI_AUTH_WPA2_PSK;
546 		break;
547 	case WIFI_SECURITY_TYPE_SAE:
548 #if defined(CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE)
549 		if (params->sae_password) {
550 			memcpy(wifi_config.sta.password, params->sae_password,
551 			       params->sae_password_length);
552 			wifi_config.sta.password[params->sae_password_length] = '\0';
553 		} else {
554 			memcpy(wifi_config.sta.password, params->psk, params->psk_length);
555 			wifi_config.sta.password[params->psk_length] = '\0';
556 		}
557 		data->status.security = WIFI_AUTH_WPA3_PSK;
558 		wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA3_PSK;
559 		wifi_config.sta.sae_pwe_h2e = WPA3_SAE_PWE_BOTH;
560 		break;
561 #else
562 		LOG_ERR("WPA3 not supported for STA mode. Enable "
563 			"CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE");
564 		return -EINVAL;
565 #endif /* CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE */
566 	default:
567 		LOG_ERR("Authentication method not supported");
568 		return -EIO;
569 	}
570 
571 	if (params->channel == WIFI_CHANNEL_ANY) {
572 		wifi_config.sta.channel = 0U;
573 		data->status.channel = 0U;
574 	} else {
575 		wifi_config.sta.channel = params->channel;
576 		data->status.channel = params->channel;
577 	}
578 
579 	ret = esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
580 	if (ret) {
581 		LOG_ERR("Failed to set Wi-Fi configuration (%d)", ret);
582 		return -EINVAL;
583 	}
584 
585 	ret = esp_wifi_connect();
586 	if (ret) {
587 		LOG_ERR("Failed to connect to Wi-Fi access point (%d)", ret);
588 		return -EAGAIN;
589 	}
590 
591 	return 0;
592 }
593 
esp32_wifi_scan(const struct device * dev,struct wifi_scan_params * params,scan_result_cb_t cb)594 static int esp32_wifi_scan(const struct device *dev, struct wifi_scan_params *params,
595 			   scan_result_cb_t cb)
596 {
597 	struct esp32_wifi_runtime *data = dev->data;
598 	int ret = 0;
599 
600 	if (data->scan_cb != NULL) {
601 		LOG_INF("Scan callback in progress");
602 		return -EINPROGRESS;
603 	}
604 
605 	data->scan_cb = cb;
606 
607 	wifi_scan_config_t scan_config = { 0 };
608 
609 	if (params) {
610 		/* The enum values are same, so, no conversion needed */
611 		scan_config.scan_type = params->scan_type;
612 	}
613 
614 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
615 	wifi_mode_t mode;
616 
617 	esp_wifi_get_mode(&mode);
618 	if (mode == ESP32_WIFI_MODE_AP || mode == ESP32_WIFI_MODE_APSTA) {
619 		ret = esp_wifi_set_mode(ESP32_WIFI_MODE_APSTA);
620 	} else {
621 		ret = esp_wifi_set_mode(ESP32_WIFI_MODE_STA);
622 	}
623 #else
624 	ret = esp_wifi_set_mode(ESP32_WIFI_MODE_STA);
625 #endif
626 
627 	if (ret) {
628 		LOG_ERR("Failed to set Wi-Fi mode (%d)", ret);
629 		return -EINVAL;
630 	}
631 
632 	ret = esp_wifi_start();
633 	if (ret) {
634 		LOG_ERR("Failed to start Wi-Fi driver (%d)", ret);
635 		return -EAGAIN;
636 	}
637 
638 	ret = esp_wifi_scan_start(&scan_config, false);
639 	if (ret != ESP_OK) {
640 		LOG_ERR("Failed to start Wi-Fi scanning");
641 		return -EAGAIN;
642 	}
643 
644 	return 0;
645 };
646 
esp32_wifi_ap_enable(const struct device * dev,struct wifi_connect_req_params * params)647 static int esp32_wifi_ap_enable(const struct device *dev,
648 			 struct wifi_connect_req_params *params)
649 {
650 	struct esp32_wifi_runtime *data = dev->data;
651 	esp_err_t err = 0;
652 
653 	/* Build Wi-Fi configuration for AP mode */
654 	wifi_config_t wifi_config = {
655 		.ap = {
656 			.max_connection = 5,
657 			.channel = params->channel == WIFI_CHANNEL_ANY ?
658 				0 : params->channel,
659 		},
660 	};
661 
662 	memcpy(data->status.ssid, params->ssid, params->ssid_length);
663 	data->status.ssid[params->ssid_length] = '\0';
664 
665 	strncpy((char *) wifi_config.ap.ssid, params->ssid, params->ssid_length);
666 	wifi_config.ap.ssid_len = params->ssid_length;
667 
668 	switch (params->security) {
669 	case WIFI_SECURITY_TYPE_NONE:
670 		memset(wifi_config.ap.password, 0, sizeof(wifi_config.ap.password));
671 		wifi_config.ap.authmode = WIFI_AUTH_OPEN;
672 		data->status.security = WIFI_AUTH_OPEN;
673 		wifi_config.ap.pmf_cfg.required = false;
674 		break;
675 	case WIFI_SECURITY_TYPE_PSK:
676 		strncpy((char *) wifi_config.ap.password, params->psk, params->psk_length);
677 		wifi_config.ap.authmode = WIFI_AUTH_WPA2_PSK;
678 		data->status.security = WIFI_AUTH_WPA2_PSK;
679 		wifi_config.ap.pmf_cfg.required = false;
680 		break;
681 	default:
682 		LOG_ERR("Authentication method not supported");
683 		return -EINVAL;
684 	}
685 
686 	/* Start Wi-Fi in AP mode with configuration built above */
687 	wifi_mode_t mode;
688 
689 	err = esp_wifi_get_mode(&mode);
690 	if (IS_ENABLED(CONFIG_ESP32_WIFI_AP_STA_MODE) &&
691 	    (mode == ESP32_WIFI_MODE_STA || mode == ESP32_WIFI_MODE_APSTA)) {
692 		err |= esp_wifi_set_mode(ESP32_WIFI_MODE_APSTA);
693 	} else {
694 		err |= esp_wifi_set_mode(ESP32_WIFI_MODE_AP);
695 	}
696 	if (err) {
697 		LOG_ERR("Failed to set Wi-Fi mode (%d)", err);
698 		return -EINVAL;
699 	}
700 
701 	err = esp_wifi_set_config(WIFI_IF_AP, &wifi_config);
702 	if (err) {
703 		LOG_ERR("Failed to set Wi-Fi configuration (%d)", err);
704 		return -EINVAL;
705 	}
706 
707 	err = esp_wifi_start();
708 	if (err) {
709 		LOG_ERR("Failed to enable Wi-Fi AP mode");
710 		return -EAGAIN;
711 	}
712 
713 	return 0;
714 };
715 
esp32_wifi_ap_disable(const struct device * dev)716 static int esp32_wifi_ap_disable(const struct device *dev)
717 {
718 	int err = 0;
719 	wifi_mode_t mode;
720 
721 	esp_wifi_get_mode(&mode);
722 	if (mode == ESP32_WIFI_MODE_APSTA) {
723 		err = esp_wifi_set_mode(ESP32_WIFI_MODE_STA);
724 		err |= esp_wifi_start();
725 	} else {
726 		err = esp_wifi_stop();
727 	}
728 	if (err) {
729 		LOG_ERR("Failed to disable Wi-Fi AP mode: (%d)", err);
730 		return -EAGAIN;
731 	}
732 
733 	return 0;
734 };
735 
esp32_wifi_status(const struct device * dev,struct wifi_iface_status * status)736 static int esp32_wifi_status(const struct device *dev, struct wifi_iface_status *status)
737 {
738 	struct esp32_wifi_runtime *data = dev->data;
739 	wifi_mode_t mode;
740 	wifi_config_t conf;
741 	wifi_ap_record_t ap_info;
742 
743 	switch (data->state) {
744 	case ESP32_STA_STOPPED:
745 	case ESP32_AP_STOPPED:
746 		status->state = WIFI_STATE_INACTIVE;
747 		break;
748 	case ESP32_STA_STARTED:
749 	case ESP32_AP_DISCONNECTED:
750 		status->state = WIFI_STATE_DISCONNECTED;
751 		break;
752 	case ESP32_STA_CONNECTING:
753 		status->state = WIFI_STATE_SCANNING;
754 		break;
755 	case ESP32_STA_CONNECTED:
756 	case ESP32_AP_CONNECTED:
757 		status->state = WIFI_STATE_COMPLETED;
758 		break;
759 	default:
760 		break;
761 	}
762 
763 	strncpy(status->ssid, data->status.ssid, WIFI_SSID_MAX_LEN);
764 	status->ssid_len = strnlen(data->status.ssid, WIFI_SSID_MAX_LEN);
765 	status->ssid[status->ssid_len] = '\0';
766 	status->band = WIFI_FREQ_BAND_2_4_GHZ;
767 	status->link_mode = WIFI_LINK_MODE_UNKNOWN;
768 	status->mfp = WIFI_MFP_DISABLE;
769 
770 	if (esp_wifi_get_mode(&mode) == ESP_OK) {
771 		if (mode == ESP32_WIFI_MODE_STA) {
772 			wifi_phy_mode_t phy_mode;
773 			esp_err_t err;
774 
775 			esp_wifi_get_config(ESP_IF_WIFI_STA, &conf);
776 			esp_wifi_sta_get_ap_info(&ap_info);
777 
778 			status->iface_mode = WIFI_MODE_INFRA;
779 			status->channel = ap_info.primary;
780 			status->rssi = ap_info.rssi;
781 			memcpy(status->bssid, ap_info.bssid, WIFI_MAC_ADDR_LEN);
782 
783 			err = esp_wifi_sta_get_negotiated_phymode(&phy_mode);
784 			if (err == ESP_OK) {
785 				if (phy_mode == WIFI_PHY_MODE_11B) {
786 					status->link_mode = WIFI_1;
787 				} else if (phy_mode == WIFI_PHY_MODE_11G) {
788 					status->link_mode = WIFI_3;
789 				} else if ((phy_mode == WIFI_PHY_MODE_HT20) ||
790 					   (phy_mode == WIFI_PHY_MODE_HT40)) {
791 					status->link_mode = WIFI_4;
792 				} else if (phy_mode == WIFI_PHY_MODE_HE20) {
793 					status->link_mode = WIFI_6;
794 				}
795 			}
796 
797 			status->beacon_interval = conf.sta.listen_interval;
798 		} else if (mode == ESP32_WIFI_MODE_AP) {
799 			esp_wifi_get_config(ESP_IF_WIFI_AP, &conf);
800 			status->iface_mode = WIFI_MODE_AP;
801 			status->link_mode = WIFI_LINK_MODE_UNKNOWN;
802 			status->channel = conf.ap.channel;
803 			status->beacon_interval = conf.ap.beacon_interval;
804 
805 		} else {
806 			status->iface_mode = WIFI_MODE_UNKNOWN;
807 			status->link_mode = WIFI_LINK_MODE_UNKNOWN;
808 			status->channel = 0;
809 		}
810 	}
811 
812 	switch (data->status.security) {
813 	case WIFI_AUTH_OPEN:
814 		status->security = WIFI_SECURITY_TYPE_NONE;
815 		break;
816 	case WIFI_AUTH_WPA2_PSK:
817 		status->security = WIFI_SECURITY_TYPE_PSK;
818 		break;
819 	case WIFI_AUTH_WPA3_PSK:
820 		status->security = WIFI_SECURITY_TYPE_SAE;
821 		break;
822 	default:
823 		status->security = WIFI_SECURITY_TYPE_UNKNOWN;
824 	}
825 
826 	return 0;
827 }
828 
esp32_wifi_init(struct net_if * iface)829 static void esp32_wifi_init(struct net_if *iface)
830 {
831 	const struct device *dev = net_if_get_device(iface);
832 	struct esp32_wifi_runtime *dev_data = dev->data;
833 	struct ethernet_context *eth_ctx = net_if_l2_data(iface);
834 
835 	eth_ctx->eth_if_type = L2_ETH_IF_TYPE_WIFI;
836 
837 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
838 	struct wifi_nm_instance *nm = wifi_nm_get_instance("esp32_wifi_nm");
839 
840 	if (!esp32_wifi_iface_ap) {
841 		esp32_wifi_iface_ap = iface;
842 		dev_data->state = ESP32_AP_STOPPED;
843 
844 		esp_read_mac(dev_data->mac_addr, ESP_MAC_WIFI_SOFTAP);
845 		wifi_nm_register_mgd_type_iface(nm, WIFI_TYPE_SAP, esp32_wifi_iface_ap);
846 	} else {
847 		esp32_wifi_iface = iface;
848 		dev_data->state = ESP32_STA_STOPPED;
849 
850 		/* Start interface when we are actually connected with Wi-Fi network */
851 		esp_read_mac(dev_data->mac_addr, ESP_MAC_WIFI_STA);
852 		esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, eth_esp32_rx);
853 		wifi_nm_register_mgd_type_iface(nm, WIFI_TYPE_STA, esp32_wifi_iface);
854 	}
855 #else
856 
857 	esp32_wifi_iface = iface;
858 	dev_data->state = ESP32_STA_STOPPED;
859 
860 	/* Start interface when we are actually connected with Wi-Fi network */
861 	esp_read_mac(dev_data->mac_addr, ESP_MAC_WIFI_STA);
862 	esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, eth_esp32_rx);
863 
864 #endif
865 
866 	/* Assign link local address. */
867 	net_if_set_link_addr(iface, dev_data->mac_addr, 6, NET_LINK_ETHERNET);
868 
869 	ethernet_init(iface);
870 	net_if_carrier_off(iface);
871 }
872 
873 #if defined(CONFIG_NET_STATISTICS_WIFI)
esp32_wifi_stats(const struct device * dev,struct net_stats_wifi * stats)874 static int esp32_wifi_stats(const struct device *dev, struct net_stats_wifi *stats)
875 {
876 	struct esp32_wifi_runtime *data = dev->data;
877 
878 	stats->bytes.received = data->stats.bytes.received;
879 	stats->bytes.sent = data->stats.bytes.sent;
880 	stats->pkts.rx = data->stats.pkts.rx;
881 	stats->pkts.tx = data->stats.pkts.tx;
882 	stats->errors.rx = data->stats.errors.rx;
883 	stats->errors.tx = data->stats.errors.tx;
884 	stats->broadcast.rx = data->stats.broadcast.rx;
885 	stats->broadcast.tx = data->stats.broadcast.tx;
886 	stats->multicast.rx = data->stats.multicast.rx;
887 	stats->multicast.tx = data->stats.multicast.tx;
888 	stats->sta_mgmt.beacons_rx = data->stats.sta_mgmt.beacons_rx;
889 	stats->sta_mgmt.beacons_miss = data->stats.sta_mgmt.beacons_miss;
890 
891 	return 0;
892 }
893 #endif
894 
esp32_wifi_dev_init(const struct device * dev)895 static int esp32_wifi_dev_init(const struct device *dev)
896 {
897 #if CONFIG_SOC_SERIES_ESP32S2 || CONFIG_SOC_SERIES_ESP32C3
898 	adc2_init_code_calibration();
899 #endif /* CONFIG_SOC_SERIES_ESP32S2 || CONFIG_SOC_SERIES_ESP32C3 */
900 
901 	wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
902 	esp_err_t ret = esp_wifi_init(&config);
903 
904 	if (ret == ESP_ERR_NO_MEM) {
905 		LOG_ERR("Not enough memory to initialize Wi-Fi.");
906 		LOG_ERR("Consider increasing CONFIG_HEAP_MEM_POOL_SIZE value.");
907 		return -ENOMEM;
908 	} else if (ret != ESP_OK) {
909 		LOG_ERR("Unable to initialize the Wi-Fi: %d", ret);
910 		return -EIO;
911 	}
912 	if (IS_ENABLED(CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4)) {
913 		net_mgmt_init_event_callback(&esp32_dhcp_cb, wifi_event_handler, DHCPV4_MASK);
914 		net_mgmt_add_event_callback(&esp32_dhcp_cb);
915 	}
916 
917 	return 0;
918 }
919 
920 static const struct wifi_mgmt_ops esp32_wifi_mgmt = {
921 	.scan		   = esp32_wifi_scan,
922 	.connect	   = esp32_wifi_connect,
923 	.disconnect	   = esp32_wifi_disconnect,
924 	.ap_enable	   = esp32_wifi_ap_enable,
925 	.ap_disable	   = esp32_wifi_ap_disable,
926 	.iface_status	   = esp32_wifi_status,
927 #if defined(CONFIG_NET_STATISTICS_WIFI)
928 	.get_stats	   = esp32_wifi_stats,
929 #endif
930 };
931 
932 static const struct net_wifi_mgmt_offload esp32_api = {
933 	.wifi_iface.iface_api.init	  = esp32_wifi_init,
934 	.wifi_iface.send = esp32_wifi_send,
935 	.wifi_mgmt_api = &esp32_wifi_mgmt,
936 };
937 
938 NET_DEVICE_DT_INST_DEFINE(0,
939 		esp32_wifi_dev_init, NULL,
940 		&esp32_data, NULL, CONFIG_WIFI_INIT_PRIORITY,
941 		&esp32_api, ETHERNET_L2,
942 		NET_L2_GET_CTX_TYPE(ETHERNET_L2), NET_ETH_MTU);
943 
944 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
945 NET_DEVICE_DT_INST_DEFINE(1,
946 		NULL, NULL,
947 		&esp32_ap_sta_data, NULL, CONFIG_WIFI_INIT_PRIORITY,
948 		&esp32_api, ETHERNET_L2,
949 		NET_L2_GET_CTX_TYPE(ETHERNET_L2), NET_ETH_MTU);
950 
951 DEFINE_WIFI_NM_INSTANCE(esp32_wifi_nm, &esp32_wifi_mgmt);
952 
953 CONNECTIVITY_WIFI_MGMT_BIND(Z_DEVICE_DT_DEV_ID(DT_DRV_INST(0)));
954 #endif
955