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 #define _POSIX_C_SOURCE 200809
10 
11 #include <zephyr/logging/log.h>
12 LOG_MODULE_REGISTER(esp32_wifi, CONFIG_WIFI_LOG_LEVEL);
13 
14 #include <zephyr/net/ethernet.h>
15 #include <zephyr/net/net_pkt.h>
16 #include <zephyr/net/net_if.h>
17 #include <zephyr/net/wifi_mgmt.h>
18 #include <zephyr/device.h>
19 #include <soc.h>
20 #include "esp_networking_priv.h"
21 #include "esp_private/wifi.h"
22 #include "esp_event.h"
23 #include "esp_timer.h"
24 #include "esp_system.h"
25 #include "esp_wpa.h"
26 
27 #define DHCPV4_MASK (NET_EVENT_IPV4_DHCP_BOUND | NET_EVENT_IPV4_DHCP_STOP)
28 
29 /* use global iface pointer to support any ethernet driver */
30 /* necessary for wifi callback functions */
31 static struct net_if *esp32_wifi_iface;
32 static struct esp32_wifi_runtime esp32_data;
33 
34 enum esp32_state_flag {
35 	ESP32_STA_STOPPED,
36 	ESP32_STA_STARTED,
37 	ESP32_STA_CONNECTING,
38 	ESP32_STA_CONNECTED,
39 	ESP32_AP_CONNECTED,
40 	ESP32_AP_DISCONNECTED,
41 	ESP32_AP_STOPPED,
42 };
43 
44 struct esp32_wifi_status {
45 	char ssid[WIFI_SSID_MAX_LEN + 1];
46 	char pass[WIFI_PSK_MAX_LEN + 1];
47 	wifi_auth_mode_t security;
48 	bool connected;
49 	uint8_t channel;
50 	int rssi;
51 };
52 
53 struct esp32_wifi_runtime {
54 	uint8_t mac_addr[6];
55 	uint8_t frame_buf[NET_ETH_MAX_FRAME_SIZE];
56 #if defined(CONFIG_NET_STATISTICS_WIFI)
57 	struct net_stats_wifi stats;
58 #endif
59 	struct esp32_wifi_status status;
60 	scan_result_cb_t scan_cb;
61 	uint8_t state;
62 };
63 
64 static void esp_wifi_event_task(void);
65 
66 K_MSGQ_DEFINE(esp_wifi_msgq, sizeof(system_event_t), 10, 4);
67 K_THREAD_STACK_DEFINE(esp_wifi_event_stack, CONFIG_ESP32_WIFI_EVENT_TASK_STACK_SIZE);
68 static struct k_thread esp_wifi_event_thread;
69 
70 static struct net_mgmt_event_callback esp32_dhcp_cb;
71 
wifi_event_handler(struct net_mgmt_event_callback * cb,uint32_t mgmt_event,struct net_if * iface)72 static void wifi_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event,
73 			       struct net_if *iface)
74 {
75 	const struct wifi_status *status = (const struct wifi_status *)cb->info;
76 
77 	switch (mgmt_event) {
78 	case NET_EVENT_IPV4_DHCP_BOUND:
79 		wifi_mgmt_raise_connect_result_event(esp32_wifi_iface, 0);
80 		break;
81 	default:
82 		break;
83 	}
84 }
85 
86 /* internal wifi library callback function */
esp_event_send_internal(esp_event_base_t event_base,int32_t event_id,void * event_data,size_t event_data_size,uint32_t ticks_to_wait)87 esp_err_t esp_event_send_internal(esp_event_base_t event_base,
88 				  int32_t event_id,
89 				  void *event_data,
90 				  size_t event_data_size,
91 				  uint32_t ticks_to_wait)
92 {
93 	system_event_t evt = {
94 		.event_id = event_id,
95 	};
96 
97 	if (event_data_size > sizeof(evt.event_info)) {
98 		LOG_ERR("MSG %d wont find %d > %d",
99 			event_id, event_data_size, sizeof(evt.event_info));
100 		return -EIO;
101 	}
102 
103 	memcpy(&evt.event_info, event_data, event_data_size);
104 	k_msgq_put(&esp_wifi_msgq, &evt, K_FOREVER);
105 	return 0;
106 }
107 
esp32_wifi_send(const struct device * dev,struct net_pkt * pkt)108 static int esp32_wifi_send(const struct device *dev, struct net_pkt *pkt)
109 {
110 	struct esp32_wifi_runtime *data = dev->data;
111 	const int pkt_len = net_pkt_get_len(pkt);
112 	esp_interface_t ifx =
113 		esp32_data.state == ESP32_AP_CONNECTED ? ESP_IF_WIFI_AP : ESP_IF_WIFI_STA;
114 
115 	/* Read the packet payload */
116 	if (net_pkt_read(pkt, data->frame_buf, pkt_len) < 0) {
117 		goto out;
118 	}
119 
120 	/* Enqueue packet for transmission */
121 	if (esp_wifi_internal_tx(ifx, (void *)data->frame_buf, pkt_len) != ESP_OK) {
122 		goto out;
123 	}
124 
125 #if defined(CONFIG_NET_STATISTICS_WIFI)
126 	data->stats.bytes.sent += pkt_len;
127 	data->stats.pkts.tx++;
128 #endif
129 
130 	LOG_DBG("pkt sent %p len %d", pkt, pkt_len);
131 	return 0;
132 
133 out:
134 
135 	LOG_ERR("Failed to send packet");
136 #if defined(CONFIG_NET_STATISTICS_WIFI)
137 	data->stats.errors.tx++;
138 #endif
139 	return -EIO;
140 }
141 
eth_esp32_rx(void * buffer,uint16_t len,void * eb)142 static esp_err_t eth_esp32_rx(void *buffer, uint16_t len, void *eb)
143 {
144 	struct net_pkt *pkt;
145 
146 	if (esp32_wifi_iface == NULL) {
147 		LOG_ERR("network interface unavailable");
148 		return -EIO;
149 	}
150 
151 	pkt = net_pkt_rx_alloc_with_buffer(esp32_wifi_iface, len, AF_UNSPEC, 0, K_MSEC(100));
152 	if (!pkt) {
153 		LOG_ERR("Failed to get net buffer");
154 		return -EIO;
155 	}
156 
157 	if (net_pkt_write(pkt, buffer, len) < 0) {
158 		LOG_ERR("Failed to write pkt");
159 		goto pkt_unref;
160 	}
161 
162 	if (net_recv_data(esp32_wifi_iface, pkt) < 0) {
163 		LOG_ERR("Failed to push received data");
164 		goto pkt_unref;
165 	}
166 
167 #if defined(CONFIG_NET_STATISTICS_WIFI)
168 	esp32_data.stats.bytes.received += len;
169 	esp32_data.stats.pkts.rx++;
170 #endif
171 
172 	esp_wifi_internal_free_rx_buffer(eb);
173 	return 0;
174 
175 pkt_unref:
176 	net_pkt_unref(pkt);
177 
178 #if defined(CONFIG_NET_STATISTICS_WIFI)
179 	esp32_data.stats.errors.rx++;
180 #endif
181 
182 	return -EIO;
183 }
184 
scan_done_handler(void)185 static void scan_done_handler(void)
186 {
187 	uint16_t aps = 0;
188 	wifi_ap_record_t *ap_list_buffer;
189 	struct wifi_scan_result res = { 0 };
190 
191 	esp_wifi_scan_get_ap_num(&aps);
192 	if (!aps) {
193 		LOG_INF("No Wi-Fi AP found");
194 		goto out;
195 	}
196 
197 	ap_list_buffer = k_malloc(aps * sizeof(wifi_ap_record_t));
198 	if (ap_list_buffer == NULL) {
199 		LOG_INF("Failed to malloc buffer to print scan results");
200 		goto out;
201 	}
202 
203 	if (esp_wifi_scan_get_ap_records(&aps, (wifi_ap_record_t *)ap_list_buffer) == ESP_OK) {
204 		for (int k = 0; k < aps; k++) {
205 			memset(&res, 0, sizeof(struct wifi_scan_result));
206 			int ssid_len = strnlen(ap_list_buffer[k].ssid, WIFI_SSID_MAX_LEN);
207 
208 			res.ssid_length = ssid_len;
209 			strncpy(res.ssid, ap_list_buffer[k].ssid, ssid_len);
210 			res.rssi = ap_list_buffer[k].rssi;
211 			res.channel = ap_list_buffer[k].primary;
212 			res.security = WIFI_SECURITY_TYPE_NONE;
213 			if (ap_list_buffer[k].authmode > WIFI_AUTH_OPEN) {
214 				res.security = WIFI_SECURITY_TYPE_PSK;
215 			}
216 
217 			if (esp32_data.scan_cb) {
218 				esp32_data.scan_cb(esp32_wifi_iface, 0, &res);
219 
220 				/* ensure notifications get delivered */
221 				k_yield();
222 			}
223 		}
224 	} else {
225 		LOG_INF("Unable to retrieve AP records");
226 	}
227 
228 	k_free(ap_list_buffer);
229 
230 out:
231 	/* report end of scan event */
232 	esp32_data.scan_cb(esp32_wifi_iface, 0, NULL);
233 	esp32_data.scan_cb = NULL;
234 }
235 
esp_wifi_handle_connect_event(void)236 static void esp_wifi_handle_connect_event(void)
237 {
238 	esp32_data.state = ESP32_STA_CONNECTED;
239 	if (IS_ENABLED(CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4)) {
240 		net_dhcpv4_start(esp32_wifi_iface);
241 	} else {
242 		wifi_mgmt_raise_connect_result_event(esp32_wifi_iface, 0);
243 	}
244 }
245 
esp_wifi_handle_disconnect_event(void)246 static void esp_wifi_handle_disconnect_event(void)
247 {
248 	if (esp32_data.state == ESP32_STA_CONNECTED) {
249 		if (IS_ENABLED(CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4)) {
250 			net_dhcpv4_stop(esp32_wifi_iface);
251 		}
252 		wifi_mgmt_raise_disconnect_result_event(esp32_wifi_iface, 0);
253 	} else {
254 		wifi_mgmt_raise_disconnect_result_event(esp32_wifi_iface, -1);
255 	}
256 
257 	if (IS_ENABLED(CONFIG_ESP32_WIFI_STA_RECONNECT)) {
258 		esp32_data.state = ESP32_STA_CONNECTING;
259 		esp_wifi_connect();
260 	} else {
261 		esp32_data.state = ESP32_STA_STARTED;
262 	}
263 }
264 
esp_wifi_event_task(void)265 static void esp_wifi_event_task(void)
266 {
267 	system_event_t evt;
268 	uint8_t s_con_cnt = 0;
269 
270 	while (1) {
271 		k_msgq_get(&esp_wifi_msgq, &evt, K_FOREVER);
272 
273 		switch (evt.event_id) {
274 		case ESP32_WIFI_EVENT_STA_START:
275 			esp32_data.state = ESP32_STA_STARTED;
276 			net_eth_carrier_on(esp32_wifi_iface);
277 			break;
278 		case ESP32_WIFI_EVENT_STA_STOP:
279 			esp32_data.state = ESP32_STA_STOPPED;
280 			net_eth_carrier_off(esp32_wifi_iface);
281 			break;
282 		case ESP32_WIFI_EVENT_STA_CONNECTED:
283 			esp_wifi_handle_connect_event();
284 			break;
285 		case ESP32_WIFI_EVENT_STA_DISCONNECTED:
286 			esp_wifi_handle_disconnect_event();
287 			break;
288 		case ESP32_WIFI_EVENT_SCAN_DONE:
289 			scan_done_handler();
290 			break;
291 		case ESP32_WIFI_EVENT_AP_STOP:
292 			esp32_data.state = ESP32_AP_STOPPED;
293 			net_eth_carrier_off(esp32_wifi_iface);
294 			break;
295 		case ESP32_WIFI_EVENT_AP_STACONNECTED:
296 			esp32_data.state = ESP32_AP_CONNECTED;
297 			if (!s_con_cnt) {
298 				esp_wifi_internal_reg_rxcb(WIFI_IF_AP, eth_esp32_rx);
299 			}
300 			s_con_cnt++;
301 			break;
302 		case ESP32_WIFI_EVENT_AP_STADISCONNECTED:
303 			esp32_data.state = ESP32_AP_DISCONNECTED;
304 			s_con_cnt--;
305 			if (!s_con_cnt) {
306 				esp_wifi_internal_reg_rxcb(WIFI_IF_AP, NULL);
307 			}
308 			break;
309 		default:
310 			break;
311 		}
312 	}
313 }
314 
esp32_wifi_disconnect(const struct device * dev)315 static int esp32_wifi_disconnect(const struct device *dev)
316 {
317 	struct esp32_wifi_runtime *data = dev->data;
318 	int ret = esp_wifi_disconnect();
319 
320 	if (ret != ESP_OK) {
321 		LOG_INF("Failed to disconnect from hotspot");
322 		return -EAGAIN;
323 	}
324 
325 	return 0;
326 }
327 
esp32_wifi_connect(const struct device * dev,struct wifi_connect_req_params * params)328 static int esp32_wifi_connect(const struct device *dev,
329 			    struct wifi_connect_req_params *params)
330 {
331 	struct esp32_wifi_runtime *data = dev->data;
332 	int ret;
333 
334 	if (data->state == ESP32_STA_CONNECTING || data->state == ESP32_STA_CONNECTED) {
335 		wifi_mgmt_raise_connect_result_event(esp32_wifi_iface, -1);
336 		return -EALREADY;
337 	}
338 
339 	if (data->state != ESP32_STA_STARTED) {
340 		LOG_ERR("Wi-Fi not in station mode");
341 		wifi_mgmt_raise_connect_result_event(esp32_wifi_iface, -1);
342 		return -EIO;
343 	}
344 
345 	data->state = ESP32_STA_CONNECTING;
346 
347 	memcpy(data->status.ssid, params->ssid, params->ssid_length);
348 	data->status.ssid[params->ssid_length] = '\0';
349 
350 	wifi_config_t wifi_config;
351 
352 	memset(&wifi_config, 0, sizeof(wifi_config_t));
353 
354 	memcpy(wifi_config.sta.ssid, params->ssid, params->ssid_length);
355 	wifi_config.sta.ssid[params->ssid_length] = '\0';
356 
357 	if (params->security == WIFI_SECURITY_TYPE_PSK) {
358 		memcpy(wifi_config.sta.password, params->psk, params->psk_length);
359 		wifi_config.sta.password[params->psk_length] = '\0';
360 		wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK;
361 		data->status.security = WIFI_AUTH_WPA2_PSK;
362 	} else if (params->security == WIFI_SECURITY_TYPE_NONE) {
363 		wifi_config.sta.threshold.authmode = WIFI_AUTH_OPEN;
364 		data->status.security = WIFI_AUTH_OPEN;
365 	} else {
366 		LOG_ERR("Authentication method not supported");
367 		return -EIO;
368 	}
369 
370 	if (params->channel == WIFI_CHANNEL_ANY) {
371 		wifi_config.sta.channel = 0U;
372 		data->status.channel = 0U;
373 	} else {
374 		wifi_config.sta.channel = params->channel;
375 		data->status.channel = params->channel;
376 	}
377 
378 	wifi_config.sta.pmf_cfg.capable = true;
379 	wifi_config.sta.pmf_cfg.required = false;
380 
381 	ret = esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
382 	ret |= esp_wifi_set_mode(ESP32_WIFI_MODE_STA);
383 	ret |= esp_wifi_connect();
384 
385 	if (ret != ESP_OK) {
386 		LOG_ERR("Failed to connect to Wi-Fi access point");
387 		return -EAGAIN;
388 	}
389 
390 	return 0;
391 }
392 
esp32_wifi_scan(const struct device * dev,struct wifi_scan_params * params,scan_result_cb_t cb)393 static int esp32_wifi_scan(const struct device *dev,
394 			   struct wifi_scan_params *params,
395 			   scan_result_cb_t cb)
396 {
397 	struct esp32_wifi_runtime *data = dev->data;
398 	int ret = 0;
399 
400 	if (data->scan_cb != NULL) {
401 		LOG_INF("Scan callback in progress");
402 		return -EINPROGRESS;
403 	}
404 
405 	data->scan_cb = cb;
406 
407 	wifi_scan_config_t scan_config = { 0 };
408 
409 	if (params) {
410 		/* The enum values are same, so, no conversion needed */
411 		scan_config.scan_type = params->scan_type;
412 	}
413 
414 	ret = esp_wifi_set_mode(ESP32_WIFI_MODE_STA);
415 	ret |= esp_wifi_scan_start(&scan_config, false);
416 
417 	if (ret != ESP_OK) {
418 		LOG_ERR("Failed to start Wi-Fi scanning");
419 		return -EAGAIN;
420 	}
421 
422 	return 0;
423 };
424 
esp32_wifi_ap_enable(const struct device * dev,struct wifi_connect_req_params * params)425 static int esp32_wifi_ap_enable(const struct device *dev,
426 			 struct wifi_connect_req_params *params)
427 {
428 	struct esp32_wifi_runtime *data = dev->data;
429 	esp_err_t ret = 0;
430 
431 	/* Build Wi-Fi configuration for AP mode */
432 	wifi_config_t wifi_config = {
433 		.ap = {
434 			.max_connection = 5,
435 			.channel = params->channel == WIFI_CHANNEL_ANY ?
436 				0 : params->channel,
437 		},
438 	};
439 
440 	memcpy(data->status.ssid, params->ssid, params->ssid_length);
441 	data->status.ssid[params->ssid_length] = '\0';
442 
443 	strncpy((char *) wifi_config.ap.ssid, params->ssid, params->ssid_length);
444 
445 	if (params->psk_length == 0) {
446 		memset(wifi_config.ap.password, 0, sizeof(wifi_config.ap.password));
447 		wifi_config.ap.authmode = WIFI_AUTH_OPEN;
448 		data->status.security = WIFI_AUTH_OPEN;
449 	} else {
450 		strncpy((char *) wifi_config.ap.password, params->psk, params->psk_length);
451 		wifi_config.ap.authmode = WIFI_AUTH_WPA2_PSK;
452 		data->status.security = WIFI_AUTH_WPA2_PSK;
453 	}
454 
455 	/* Start Wi-Fi in AP mode with configuration built above */
456 	ret = esp_wifi_set_mode(ESP32_WIFI_MODE_AP);
457 	ret |= esp_wifi_set_config(WIFI_IF_AP, &wifi_config);
458 	ret |= esp_wifi_start();
459 	if (ret != ESP_OK) {
460 		LOG_ERR("Failed to enable Wi-Fi AP mode");
461 		return -EAGAIN;
462 	}
463 
464 	net_eth_carrier_on(esp32_wifi_iface);
465 
466 	return 0;
467 };
468 
esp32_wifi_ap_disable(const struct device * dev)469 static int esp32_wifi_ap_disable(const struct device *dev)
470 {
471 	esp_err_t ret = esp_wifi_set_mode(ESP32_WIFI_MODE_NULL);
472 
473 	ret |= esp_wifi_start();
474 	if (ret != ESP_OK) {
475 		LOG_ERR("Failed to disable Wi-Fi AP mode");
476 		return -EAGAIN;
477 	}
478 
479 	return 0;
480 };
481 
esp32_wifi_status(const struct device * dev,struct wifi_iface_status * status)482 static int esp32_wifi_status(const struct device *dev, struct wifi_iface_status *status)
483 {
484 	struct esp32_wifi_runtime *data = dev->data;
485 	wifi_mode_t mode;
486 	wifi_config_t conf;
487 	wifi_ap_record_t ap_info;
488 
489 	switch (data->state) {
490 	case ESP32_STA_STOPPED:
491 	case ESP32_AP_STOPPED:
492 		status->state = WIFI_STATE_INACTIVE;
493 		break;
494 	case ESP32_STA_STARTED:
495 	case ESP32_AP_DISCONNECTED:
496 		status->state = WIFI_STATE_DISCONNECTED;
497 		break;
498 	case ESP32_STA_CONNECTING:
499 		status->state = WIFI_STATE_SCANNING;
500 		break;
501 	case ESP32_STA_CONNECTED:
502 	case ESP32_AP_CONNECTED:
503 		status->state = WIFI_STATE_COMPLETED;
504 		break;
505 	default:
506 		break;
507 	}
508 
509 	strncpy(status->ssid, data->status.ssid, WIFI_SSID_MAX_LEN);
510 	status->ssid_len = strnlen(data->status.ssid, WIFI_SSID_MAX_LEN);
511 	status->band = WIFI_FREQ_BAND_2_4_GHZ;
512 	status->link_mode = WIFI_LINK_MODE_UNKNOWN;
513 	status->mfp = WIFI_MFP_DISABLE;
514 
515 	if (esp_wifi_get_mode(&mode) == ESP_OK) {
516 		if (mode == ESP32_WIFI_MODE_STA) {
517 			esp_wifi_get_config(ESP_IF_WIFI_STA, &conf);
518 			esp_wifi_sta_get_ap_info(&ap_info);
519 			status->iface_mode = WIFI_MODE_INFRA;
520 			status->channel = ap_info.primary;
521 			status->rssi = ap_info.rssi;
522 			memcpy(status->bssid, ap_info.bssid, WIFI_MAC_ADDR_LEN);
523 
524 			if (ap_info.phy_11n) {
525 				status->link_mode = WIFI_4;
526 			} else if (ap_info.phy_11g) {
527 				status->link_mode |= WIFI_3;
528 			} else if (ap_info.phy_11b) {
529 				status->link_mode = WIFI_1;
530 			}
531 
532 		} else if (mode == ESP32_WIFI_MODE_AP) {
533 			esp_wifi_get_config(ESP_IF_WIFI_AP, &conf);
534 			status->iface_mode = WIFI_MODE_AP;
535 			status->link_mode = WIFI_LINK_MODE_UNKNOWN;
536 			status->channel = conf.ap.channel;
537 		} else {
538 			status->iface_mode = WIFI_MODE_UNKNOWN;
539 			status->link_mode = WIFI_LINK_MODE_UNKNOWN;
540 			status->channel = 0;
541 		}
542 	}
543 
544 	switch (data->status.security) {
545 	case WIFI_AUTH_OPEN:
546 		status->security = WIFI_SECURITY_TYPE_NONE;
547 		break;
548 	case WIFI_AUTH_WPA2_PSK:
549 		status->security = WIFI_SECURITY_TYPE_PSK;
550 		break;
551 	default:
552 		status->security = WIFI_SECURITY_TYPE_UNKNOWN;
553 	}
554 
555 	return 0;
556 }
557 
esp32_wifi_init(struct net_if * iface)558 static void esp32_wifi_init(struct net_if *iface)
559 {
560 	const struct device *dev = net_if_get_device(iface);
561 	struct esp32_wifi_runtime *dev_data = dev->data;
562 	struct ethernet_context *eth_ctx = net_if_l2_data(iface);
563 
564 	eth_ctx->eth_if_type = L2_ETH_IF_TYPE_WIFI;
565 	esp32_wifi_iface = iface;
566 	dev_data->state = ESP32_STA_STOPPED;
567 
568 	/* Start interface when we are actually connected with Wi-Fi network */
569 	esp_read_mac(dev_data->mac_addr, ESP_MAC_WIFI_STA);
570 
571 	/* Assign link local address. */
572 	net_if_set_link_addr(iface, dev_data->mac_addr, 6, NET_LINK_ETHERNET);
573 
574 	ethernet_init(iface);
575 	net_if_carrier_off(iface);
576 
577 	wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
578 	esp_err_t ret = esp_wifi_init(&config);
579 
580 	esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, eth_esp32_rx);
581 
582 	ret |= esp_wifi_set_mode(ESP32_WIFI_MODE_STA);
583 	ret |= esp_wifi_start();
584 
585 	if (ret != ESP_OK) {
586 		LOG_ERR("Failed to start Wi-Fi driver");
587 	}
588 }
589 
590 #if defined(CONFIG_NET_STATISTICS_WIFI)
esp32_wifi_stats(const struct device * dev,struct net_stats_wifi * stats)591 static int esp32_wifi_stats(const struct device *dev, struct net_stats_wifi *stats)
592 {
593 	struct esp32_wifi_runtime *data = dev->data;
594 
595 	stats->bytes.received = data->stats.bytes.received;
596 	stats->bytes.sent = data->stats.bytes.sent;
597 	stats->pkts.rx = data->stats.pkts.rx;
598 	stats->pkts.tx = data->stats.pkts.tx;
599 	stats->errors.rx = data->stats.errors.rx;
600 	stats->errors.tx = data->stats.errors.tx;
601 	stats->broadcast.rx = data->stats.broadcast.rx;
602 	stats->broadcast.tx = data->stats.broadcast.tx;
603 	stats->multicast.rx = data->stats.multicast.rx;
604 	stats->multicast.tx = data->stats.multicast.tx;
605 	stats->sta_mgmt.beacons_rx = data->stats.sta_mgmt.beacons_rx;
606 	stats->sta_mgmt.beacons_miss = data->stats.sta_mgmt.beacons_miss;
607 
608 	return 0;
609 }
610 #endif
611 
esp32_wifi_dev_init(const struct device * dev)612 static int esp32_wifi_dev_init(const struct device *dev)
613 {
614 	esp_timer_init();
615 
616 	k_tid_t tid = k_thread_create(&esp_wifi_event_thread, esp_wifi_event_stack,
617 			CONFIG_ESP32_WIFI_EVENT_TASK_STACK_SIZE,
618 			(k_thread_entry_t)esp_wifi_event_task, NULL, NULL, NULL,
619 			CONFIG_ESP32_WIFI_EVENT_TASK_PRIO, K_INHERIT_PERMS,
620 			K_NO_WAIT);
621 
622 	k_thread_name_set(tid, "esp_event");
623 
624 	if (IS_ENABLED(CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4)) {
625 		net_mgmt_init_event_callback(&esp32_dhcp_cb, wifi_event_handler, DHCPV4_MASK);
626 		net_mgmt_add_event_callback(&esp32_dhcp_cb);
627 	}
628 
629 	return 0;
630 }
631 
632 static const struct wifi_mgmt_ops esp32_wifi_mgmt = {
633 	.scan		   = esp32_wifi_scan,
634 	.connect	   = esp32_wifi_connect,
635 	.disconnect	   = esp32_wifi_disconnect,
636 	.ap_enable	   = esp32_wifi_ap_enable,
637 	.ap_disable	   = esp32_wifi_ap_disable,
638 	.iface_status	   = esp32_wifi_status,
639 #if defined(CONFIG_NET_STATISTICS_WIFI)
640 	.get_stats	   = esp32_wifi_stats,
641 #endif
642 };
643 
644 static const struct net_wifi_mgmt_offload esp32_api = {
645 	.wifi_iface.iface_api.init	  = esp32_wifi_init,
646 	.wifi_iface.send = esp32_wifi_send,
647 	.wifi_mgmt_api = &esp32_wifi_mgmt,
648 };
649 
650 NET_DEVICE_DT_INST_DEFINE(0,
651 		esp32_wifi_dev_init, NULL,
652 		&esp32_data, NULL, CONFIG_WIFI_INIT_PRIORITY,
653 		&esp32_api, ETHERNET_L2,
654 		NET_L2_GET_CTX_TYPE(ETHERNET_L2), NET_ETH_MTU);
655