1 /**
2  * Copyright (c) 2018 Linaro
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #if defined(CONFIG_WIFI_ESWIFI_BUS_UART)
8 #define DT_DRV_COMPAT inventek_eswifi_uart
9 #else
10 #define DT_DRV_COMPAT inventek_eswifi
11 #endif
12 
13 #include "eswifi_log.h"
14 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
15 
16 #include <zephyr/kernel.h>
17 #include <zephyr/device.h>
18 #include <string.h>
19 #include <errno.h>
20 #include <zephyr/drivers/gpio.h>
21 #include <zephyr/net/net_pkt.h>
22 #include <zephyr/net/net_if.h>
23 #include <zephyr/net/net_context.h>
24 #include <zephyr/net/net_offload.h>
25 #include <zephyr/net/wifi_mgmt.h>
26 #include <zephyr/net/conn_mgr/connectivity_wifi_mgmt.h>
27 
28 #include <zephyr/net/ethernet.h>
29 #include <net_private.h>
30 #include <zephyr/net/net_core.h>
31 #include <zephyr/net/net_pkt.h>
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 
36 #include <zephyr/sys/printk.h>
37 
38 #include "eswifi.h"
39 
40 #define ESWIFI_WORKQUEUE_STACK_SIZE 1024
41 K_KERNEL_STACK_DEFINE(eswifi_work_q_stack, ESWIFI_WORKQUEUE_STACK_SIZE);
42 
43 static const struct eswifi_cfg eswifi0_cfg = {
44 	.resetn = GPIO_DT_SPEC_INST_GET(0, resetn_gpios),
45 	.wakeup = GPIO_DT_SPEC_INST_GET(0, wakeup_gpios),
46 };
47 
48 static struct eswifi_dev eswifi0; /* static instance */
49 
eswifi_reset(struct eswifi_dev * eswifi,const struct eswifi_cfg * cfg)50 static int eswifi_reset(struct eswifi_dev *eswifi, const struct eswifi_cfg *cfg)
51 {
52 	gpio_pin_set_dt(&cfg->resetn, 0);
53 	k_sleep(K_MSEC(10));
54 	gpio_pin_set_dt(&cfg->resetn, 1);
55 	gpio_pin_set_dt(&cfg->wakeup, 1);
56 	k_sleep(K_MSEC(500));
57 
58 	/* fetch the cursor */
59 	return eswifi_request(eswifi, NULL, 0, eswifi->buf,
60 			      sizeof(eswifi->buf));
61 }
62 
__parse_ssid(char * str,char * ssid)63 static inline int __parse_ssid(char *str, char *ssid)
64 {
65 	int i = 0;
66 
67 	/* fmt => "SSID" */
68 
69 	if (*str != '"') {
70 		return 0;
71 	}
72 	str++;
73 
74 	while (*str && (*str != '"') && i < WIFI_SSID_MAX_LEN) {
75 		ssid[i++] = *str++;
76 	}
77 
78 	if (*str != '"') {
79 		return 0;
80 	}
81 
82 	return i;
83 }
84 
__parse_scan_res(char * str,struct wifi_scan_result * res)85 static void __parse_scan_res(char *str, struct wifi_scan_result *res)
86 {
87 	int field = 0;
88 
89 	/* fmt => #001,"SSID",MACADDR,RSSI,BITRATE,MODE,SECURITY,BAND,CHANNEL */
90 
91 	while (*str) {
92 		if (*str != ',') {
93 			str++;
94 			continue;
95 		}
96 
97 		if (!*++str) {
98 			break;
99 		}
100 
101 		switch (++field) {
102 		case 1: /* SSID */
103 			res->ssid_length = __parse_ssid(str, res->ssid);
104 			str += res->ssid_length;
105 			break;
106 		case 2: /* mac addr */
107 			break;
108 		case 3: /* RSSI */
109 			res->rssi = atoi(str);
110 			break;
111 		case 4: /* bitrate */
112 			break;
113 		case 5: /* mode */
114 			break;
115 		case 6: /* security */
116 			if (!strncmp(str, "Open", 4)) {
117 				res->security = WIFI_SECURITY_TYPE_NONE;
118 			} else {
119 				res->security = WIFI_SECURITY_TYPE_PSK;
120 			}
121 			break;
122 		case 7: /* band */
123 			break;
124 		case 8: /* channel */
125 			res->channel = atoi(str);
126 			break;
127 		}
128 
129 	}
130 }
131 
eswifi_at_cmd_rsp(struct eswifi_dev * eswifi,char * cmd,char ** rsp)132 int eswifi_at_cmd_rsp(struct eswifi_dev *eswifi, char *cmd, char **rsp)
133 {
134 	const char startstr[] = "\r\n";
135 	const char endstr[] = "\r\nOK\r\n>";
136 	int i, len, rsplen = -EINVAL;
137 
138 	len = eswifi_request(eswifi, cmd, strlen(cmd), eswifi->buf,
139 			     sizeof(eswifi->buf));
140 	if (len < 0) {
141 		return -EIO;
142 	}
143 
144 	if (len >= CONFIG_WIFI_ESWIFI_MAX_DATA_SIZE) {
145 		LOG_WRN("Buffer might be too small for response!");
146 		LOG_WRN("Data length %d", len);
147 		LOG_WRN("See CONFIG_WIFI_ESWIFI_MAX_DATA_SIZE (in build: %d)",
148 			CONFIG_WIFI_ESWIFI_MAX_DATA_SIZE);
149 	}
150 
151 	/*
152 	 * Check response, format should be "\r\n[DATA]\r\nOK\r\n>"
153 	 * Data is in arbitrary format (not only ASCII)
154 	 */
155 
156 	/* Check start characters */
157 	if (strncmp(eswifi->buf, startstr, strlen(startstr))) {
158 		return -EINVAL;
159 	}
160 
161 	if (len < sizeof(endstr) - 1 + sizeof(startstr) - 1) {
162 		return -EINVAL;
163 	}
164 
165 	/* Check end characters */
166 	for (i = len - sizeof(endstr); i > 0; i--) {
167 		if (!strncmp(&eswifi->buf[i], endstr, 7)) {
168 			if (rsp) {
169 				eswifi->buf[i] = '\0';
170 				*rsp = &eswifi->buf[2];
171 				rsplen = &eswifi->buf[i] - *rsp;
172 			} else {
173 				rsplen = 0;
174 			}
175 			break;
176 		}
177 	}
178 
179 	return rsplen;
180 }
181 
eswifi_at_cmd(struct eswifi_dev * eswifi,char * cmd)182 int eswifi_at_cmd(struct eswifi_dev *eswifi, char *cmd)
183 {
184 	return eswifi_at_cmd_rsp(eswifi, cmd, NULL);
185 }
186 
eswifi_by_iface_idx(uint8_t iface)187 struct eswifi_dev *eswifi_by_iface_idx(uint8_t iface)
188 {
189 	/* only one instance */
190 	LOG_DBG("%d", iface);
191 	return &eswifi0;
192 }
193 
__parse_ipv4_address(char * str,char * ssid,uint8_t ip[4])194 static int __parse_ipv4_address(char *str, char *ssid, uint8_t ip[4])
195 {
196 	int byte = -1;
197 
198 	/* fmt => [JOIN   ] SSID,192.168.2.18,0,0 */
199 	while (*str && byte < 4) {
200 		if (byte == -1) {
201 			if (!strncmp(str, ssid, strlen(ssid))) {
202 				byte = 0;
203 				str += strlen(ssid);
204 			}
205 			str++;
206 			continue;
207 		}
208 
209 		ip[byte++] = atoi(str);
210 		while (*str && (*str++ != '.')) {
211 		}
212 	}
213 
214 	return 0;
215 }
216 
eswifi_scan(struct eswifi_dev * eswifi)217 static void eswifi_scan(struct eswifi_dev *eswifi)
218 {
219 	char cmd[] = "F0\r";
220 	char *data;
221 	int i, ret;
222 
223 	LOG_DBG("");
224 
225 	eswifi_lock(eswifi);
226 
227 	ret = eswifi_at_cmd_rsp(eswifi, cmd, &data);
228 	if (ret < 0) {
229 		eswifi->scan_cb(eswifi->iface, -EIO, NULL);
230 		eswifi_unlock(eswifi);
231 		return;
232 	}
233 
234 	for (i = 0; i < ret; i++) {
235 		if (data[i] == '#') {
236 			struct wifi_scan_result res = {0};
237 
238 			__parse_scan_res(&data[i], &res);
239 
240 			eswifi->scan_cb(eswifi->iface, 0, &res);
241 			k_yield();
242 
243 			while (data[i] && data[i] != '\n') {
244 				i++;
245 			}
246 		}
247 	}
248 
249 	/* WiFi scan is done. */
250 	eswifi->scan_cb(eswifi->iface, 0, NULL);
251 
252 	eswifi_unlock(eswifi);
253 }
254 
eswifi_connect(struct eswifi_dev * eswifi)255 static int eswifi_connect(struct eswifi_dev *eswifi)
256 {
257 	char connect[] = "C0\r";
258 	struct in_addr addr;
259 	char *rsp;
260 	int err;
261 
262 	LOG_DBG("Connecting to %s (pass=%s)", eswifi->sta.ssid,
263 		eswifi->sta.pass);
264 
265 	eswifi_lock(eswifi);
266 
267 	/* Set SSID */
268 	snprintk(eswifi->buf, sizeof(eswifi->buf), "C1=%s\r", eswifi->sta.ssid);
269 	err = eswifi_at_cmd(eswifi, eswifi->buf);
270 	if (err < 0) {
271 		LOG_ERR("Unable to set SSID");
272 		goto error;
273 	}
274 
275 	/* Set passphrase */
276 	snprintk(eswifi->buf, sizeof(eswifi->buf), "C2=%s\r", eswifi->sta.pass);
277 	err = eswifi_at_cmd(eswifi, eswifi->buf);
278 	if (err < 0) {
279 		LOG_ERR("Unable to set passphrase");
280 		goto error;
281 	}
282 
283 	/* Set Security type */
284 	snprintk(eswifi->buf, sizeof(eswifi->buf), "C3=%u\r",
285 		 eswifi->sta.security);
286 	err = eswifi_at_cmd(eswifi, eswifi->buf);
287 	if (err < 0) {
288 		LOG_ERR("Unable to configure security");
289 		goto error;
290 	}
291 
292 	/* Join Network */
293 	err = eswifi_at_cmd_rsp(eswifi, connect, &rsp);
294 	if (err < 0) {
295 		LOG_ERR("Unable to join network");
296 		goto error;
297 	}
298 
299 	/* Any IP assigned ? (dhcp offload or manually) */
300 	err = __parse_ipv4_address(rsp, eswifi->sta.ssid,
301 				   (uint8_t *)&addr.s4_addr);
302 	if (err < 0) {
303 		LOG_ERR("Unable to retrieve IP address");
304 		goto error;
305 	}
306 
307 	LOG_DBG("ip = %d.%d.%d.%d", addr.s4_addr[0], addr.s4_addr[1],
308 		   addr.s4_addr[2], addr.s4_addr[3]);
309 
310 	net_if_ipv4_addr_add(eswifi->iface, &addr, NET_ADDR_DHCP, 0);
311 
312 	eswifi->sta.connected = true;
313 
314 	LOG_DBG("Connected!");
315 
316 	eswifi_unlock(eswifi);
317 	return 0;
318 
319 error:
320 	eswifi_unlock(eswifi);
321 	return -EIO;
322 }
323 
eswifi_disconnect(struct eswifi_dev * eswifi)324 static int eswifi_disconnect(struct eswifi_dev *eswifi)
325 {
326 	char disconnect[] = "CD\r";
327 	int err;
328 
329 	LOG_DBG("");
330 
331 	eswifi_lock(eswifi);
332 
333 	err = eswifi_at_cmd(eswifi, disconnect);
334 	if (err < 0) {
335 		LOG_ERR("Unable to disconnect network");
336 		err = -EIO;
337 	}
338 
339 	eswifi->sta.connected = false;
340 
341 	eswifi_unlock(eswifi);
342 
343 	return err;
344 }
345 
eswifi_status_work(struct k_work * work)346 static void eswifi_status_work(struct k_work *work)
347 {
348 	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
349 	struct eswifi_dev *eswifi;
350 	char status[] = "CS\r";
351 	char rssi[] = "CR\r";
352 	char *rsp;
353 	int ret;
354 
355 	eswifi = CONTAINER_OF(dwork, struct eswifi_dev, status_work);
356 
357 	eswifi_lock(eswifi);
358 
359 	if (eswifi->role == ESWIFI_ROLE_AP) {
360 		goto done;
361 	}
362 
363 	ret = eswifi_at_cmd_rsp(eswifi, status, &rsp);
364 	if (ret < 1) {
365 		LOG_ERR("Unable to retrieve status");
366 		goto done;
367 	}
368 
369 	if (rsp[0] == '0' && eswifi->sta.connected) {
370 		eswifi->sta.connected = false;
371 		wifi_mgmt_raise_disconnect_result_event(eswifi->iface, 0);
372 		goto done;
373 	} else if (rsp[0] == '1' && !eswifi->sta.connected) {
374 		eswifi->sta.connected = true;
375 		wifi_mgmt_raise_connect_result_event(eswifi->iface, 0);
376 	}
377 
378 	ret = eswifi_at_cmd_rsp(eswifi, rssi, &rsp);
379 	if (ret < 1) {
380 		LOG_ERR("Unable to retrieve rssi");
381 		/* continue */
382 	} else {
383 		eswifi->sta.rssi = atoi(rsp);
384 	}
385 
386 	k_work_reschedule_for_queue(&eswifi->work_q, &eswifi->status_work,
387 				    K_MSEC(1000 * 30));
388 
389 done:
390 	eswifi_unlock(eswifi);
391 }
392 
eswifi_request_work(struct k_work * item)393 static void eswifi_request_work(struct k_work *item)
394 {
395 	struct eswifi_dev *eswifi;
396 	int err;
397 
398 	LOG_DBG("");
399 
400 	eswifi = CONTAINER_OF(item, struct eswifi_dev, request_work);
401 
402 	switch (eswifi->req) {
403 	case ESWIFI_REQ_CONNECT:
404 		err = eswifi_connect(eswifi);
405 		wifi_mgmt_raise_connect_result_event(eswifi->iface, err);
406 		k_work_reschedule_for_queue(&eswifi->work_q, &eswifi->status_work,
407 					    K_MSEC(1000));
408 		break;
409 	case ESWIFI_REQ_DISCONNECT:
410 		err = eswifi_disconnect(eswifi);
411 		wifi_mgmt_raise_disconnect_result_event(eswifi->iface, err);
412 		break;
413 	case ESWIFI_REQ_SCAN:
414 		eswifi_scan(eswifi);
415 		break;
416 	case ESWIFI_REQ_NONE:
417 	default:
418 		break;
419 	}
420 }
421 
eswifi_get_mac_addr(struct eswifi_dev * eswifi,uint8_t addr[6])422 static int eswifi_get_mac_addr(struct eswifi_dev *eswifi, uint8_t addr[6])
423 {
424 	char cmd[] = "Z5\r";
425 	int ret, i, byte = 0;
426 	char *rsp;
427 
428 	ret = eswifi_at_cmd_rsp(eswifi, cmd, &rsp);
429 	if (ret < 0) {
430 		return ret;
431 	}
432 
433 	/* format is "ff:ff:ff:ff:ff:ff" */
434 	for (i = 0; i < ret && byte < 6; i++) {
435 		addr[byte++] = strtol(&rsp[i], NULL, 16);
436 		i += 2;
437 	}
438 
439 	if (byte != 6) {
440 		return -EIO;
441 	}
442 
443 	return 0;
444 }
445 
eswifi_iface_init(struct net_if * iface)446 static void eswifi_iface_init(struct net_if *iface)
447 {
448 	struct eswifi_dev *eswifi = &eswifi0;
449 	const struct eswifi_cfg *cfg = &eswifi0_cfg;
450 	uint8_t mac[6];
451 
452 	LOG_DBG("");
453 
454 	eswifi_lock(eswifi);
455 
456 	if (eswifi_reset(eswifi, cfg) < 0) {
457 		LOG_ERR("Unable to reset device");
458 		return;
459 	}
460 
461 	if (eswifi_get_mac_addr(eswifi, mac) < 0) {
462 		LOG_ERR("Unable to read MAC address");
463 		return;
464 	}
465 
466 	LOG_DBG("MAC Address %02X:%02X:%02X:%02X:%02X:%02X",
467 		   mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
468 
469 	memcpy(eswifi->mac, mac, sizeof(eswifi->mac));
470 	net_if_set_link_addr(iface, eswifi->mac, sizeof(eswifi->mac),
471 			     NET_LINK_ETHERNET);
472 
473 	eswifi->iface = iface;
474 
475 	eswifi_unlock(eswifi);
476 
477 	eswifi_offload_init(eswifi);
478 #if defined(CONFIG_NET_SOCKETS_OFFLOAD)
479 	eswifi_socket_offload_init(eswifi);
480 
481 	net_if_socket_offload_set(iface, eswifi_socket_create);
482 #endif
483 
484 }
485 
eswifi_mgmt_iface_status(const struct device * dev,struct wifi_iface_status * status)486 int eswifi_mgmt_iface_status(const struct device *dev,
487 			     struct wifi_iface_status *status)
488 {
489 	struct eswifi_dev *eswifi = dev->data;
490 	struct eswifi_sta *sta = &eswifi->sta;
491 
492 	/* Update status */
493 	eswifi_status_work(&eswifi->status_work.work);
494 
495 	if (!sta->connected) {
496 		status->state = WIFI_STATE_DISCONNECTED;
497 		return 0;
498 	}
499 
500 	status->state = WIFI_STATE_COMPLETED;
501 	status->ssid_len = strnlen(sta->ssid, WIFI_SSID_MAX_LEN);
502 	strncpy(status->ssid, sta->ssid, status->ssid_len);
503 	status->band = WIFI_FREQ_BAND_2_4_GHZ;
504 	status->channel = 0;
505 
506 	if (eswifi->role == ESWIFI_ROLE_CLIENT) {
507 		status->iface_mode = WIFI_MODE_INFRA;
508 	} else {
509 		status->iface_mode = WIFI_MODE_AP;
510 	}
511 
512 	status->link_mode = WIFI_LINK_MODE_UNKNOWN;
513 
514 	switch (sta->security) {
515 	case ESWIFI_SEC_OPEN:
516 		status->security = WIFI_SECURITY_TYPE_NONE;
517 		break;
518 	case ESWIFI_SEC_WPA2_MIXED:
519 		status->security = WIFI_SECURITY_TYPE_PSK;
520 		break;
521 	default:
522 		status->security = WIFI_SECURITY_TYPE_UNKNOWN;
523 	}
524 
525 	status->mfp = WIFI_MFP_DISABLE;
526 	status->rssi = sta->rssi;
527 
528 	return 0;
529 }
530 
eswifi_mgmt_scan(const struct device * dev,struct wifi_scan_params * params,scan_result_cb_t cb)531 static int eswifi_mgmt_scan(const struct device *dev,
532 			    struct wifi_scan_params *params,
533 			    scan_result_cb_t cb)
534 {
535 	struct eswifi_dev *eswifi = dev->data;
536 
537 	ARG_UNUSED(params);
538 
539 	LOG_DBG("");
540 
541 	eswifi_lock(eswifi);
542 
543 	eswifi->scan_cb = cb;
544 	eswifi->req = ESWIFI_REQ_SCAN;
545 	k_work_submit_to_queue(&eswifi->work_q, &eswifi->request_work);
546 
547 	eswifi_unlock(eswifi);
548 
549 	return 0;
550 }
551 
eswifi_mgmt_disconnect(const struct device * dev)552 static int eswifi_mgmt_disconnect(const struct device *dev)
553 {
554 	struct eswifi_dev *eswifi = dev->data;
555 
556 	LOG_DBG("");
557 
558 	eswifi_lock(eswifi);
559 
560 	eswifi->req = ESWIFI_REQ_DISCONNECT;
561 	k_work_submit_to_queue(&eswifi->work_q, &eswifi->request_work);
562 
563 	eswifi_unlock(eswifi);
564 
565 	return 0;
566 }
567 
__eswifi_sta_config(struct eswifi_dev * eswifi,struct wifi_connect_req_params * params)568 static int __eswifi_sta_config(struct eswifi_dev *eswifi,
569 			       struct wifi_connect_req_params *params)
570 {
571 	memcpy(eswifi->sta.ssid, params->ssid, params->ssid_length);
572 	eswifi->sta.ssid[params->ssid_length] = '\0';
573 
574 	switch (params->security) {
575 	case WIFI_SECURITY_TYPE_NONE:
576 		eswifi->sta.pass[0] = '\0';
577 		eswifi->sta.security = ESWIFI_SEC_OPEN;
578 		break;
579 	case WIFI_SECURITY_TYPE_PSK:
580 		memcpy(eswifi->sta.pass, params->psk, params->psk_length);
581 		eswifi->sta.pass[params->psk_length] = '\0';
582 		eswifi->sta.security = ESWIFI_SEC_WPA2_MIXED;
583 		break;
584 	default:
585 		return -EINVAL;
586 	}
587 
588 	if (params->channel == WIFI_CHANNEL_ANY) {
589 		eswifi->sta.channel = 0U;
590 	} else {
591 		eswifi->sta.channel = params->channel;
592 	}
593 
594 	return 0;
595 }
596 
eswifi_mgmt_connect(const struct device * dev,struct wifi_connect_req_params * params)597 static int eswifi_mgmt_connect(const struct device *dev,
598 			       struct wifi_connect_req_params *params)
599 {
600 	struct eswifi_dev *eswifi = dev->data;
601 	int err;
602 
603 	LOG_DBG("");
604 
605 	eswifi_lock(eswifi);
606 
607 	err = __eswifi_sta_config(eswifi, params);
608 	if (!err) {
609 		eswifi->req = ESWIFI_REQ_CONNECT;
610 		k_work_submit_to_queue(&eswifi->work_q,
611 				       &eswifi->request_work);
612 	}
613 
614 	eswifi_unlock(eswifi);
615 
616 	return err;
617 }
618 
eswifi_async_msg(struct eswifi_dev * eswifi,char * msg,size_t len)619 void eswifi_async_msg(struct eswifi_dev *eswifi, char *msg, size_t len)
620 {
621 	eswifi_offload_async_msg(eswifi, msg, len);
622 }
623 
624 #if defined(CONFIG_NET_IPV4)
eswifi_mgmt_ap_enable(const struct device * dev,struct wifi_connect_req_params * params)625 static int eswifi_mgmt_ap_enable(const struct device *dev,
626 				 struct wifi_connect_req_params *params)
627 {
628 	struct eswifi_dev *eswifi = dev->data;
629 	struct net_if_ipv4 *ipv4 = eswifi->iface->config.ip.ipv4;
630 	struct net_if_addr *unicast = NULL;
631 	int err = -EIO, i;
632 
633 	LOG_DBG("");
634 
635 	eswifi_lock(eswifi);
636 
637 	if (eswifi->role == ESWIFI_ROLE_AP) {
638 		err = -EALREADY;
639 		goto error;
640 	}
641 
642 	err = __eswifi_sta_config(eswifi, params);
643 	if (err) {
644 		goto error;
645 	}
646 
647 	/* security */
648 	snprintk(eswifi->buf, sizeof(eswifi->buf), "A1=%u\r",
649 		 eswifi->sta.security);
650 	err = eswifi_at_cmd(eswifi, eswifi->buf);
651 	if (err < 0) {
652 		LOG_ERR("Unable to set Security");
653 		goto error;
654 	}
655 
656 	/* Passkey */
657 	if (eswifi->sta.security != ESWIFI_SEC_OPEN) {
658 		snprintk(eswifi->buf, sizeof(eswifi->buf), "A2=%s\r",
659 			 eswifi->sta.pass);
660 		err = eswifi_at_cmd(eswifi, eswifi->buf);
661 		if (err < 0) {
662 			LOG_ERR("Unable to set passkey");
663 			goto error;
664 		}
665 	}
666 
667 	/* Set SSID (0=no MAC, 1=append MAC) */
668 	snprintk(eswifi->buf, sizeof(eswifi->buf), "AS=0,%s\r",
669 		 eswifi->sta.ssid);
670 	err = eswifi_at_cmd(eswifi, eswifi->buf);
671 	if (err < 0) {
672 		LOG_ERR("Unable to set SSID");
673 		goto error;
674 	}
675 
676 	/* Set Channel */
677 	snprintk(eswifi->buf, sizeof(eswifi->buf), "AC=%u\r",
678 		 eswifi->sta.channel);
679 	err = eswifi_at_cmd(eswifi, eswifi->buf);
680 	if (err < 0) {
681 		LOG_ERR("Unable to set Channel");
682 		goto error;
683 	}
684 
685 	/* Set IP Address */
686 	for (i = 0; ipv4 && i < NET_IF_MAX_IPV4_ADDR; i++) {
687 		if (ipv4->unicast[i].ipv4.is_used) {
688 			unicast = &ipv4->unicast[i].ipv4;
689 			break;
690 		}
691 	}
692 
693 	if (!unicast) {
694 		LOG_ERR("No IPv4 assigned for AP mode");
695 		err = -EADDRNOTAVAIL;
696 		goto error;
697 	}
698 
699 	snprintk(eswifi->buf, sizeof(eswifi->buf), "Z6=%s\r",
700 		 net_sprint_ipv4_addr(&unicast->address.in_addr));
701 	err = eswifi_at_cmd(eswifi, eswifi->buf);
702 	if (err < 0) {
703 		LOG_ERR("Unable to active access point");
704 		goto error;
705 	}
706 
707 	/* Enable AP */
708 	snprintk(eswifi->buf, sizeof(eswifi->buf), "AD\r");
709 	err = eswifi_at_cmd(eswifi, eswifi->buf);
710 	if (err < 0) {
711 		LOG_ERR("Unable to active access point");
712 		goto error;
713 	}
714 
715 	eswifi->role = ESWIFI_ROLE_AP;
716 
717 	eswifi_unlock(eswifi);
718 	return 0;
719 error:
720 	eswifi_unlock(eswifi);
721 	return err;
722 }
723 #else
eswifi_mgmt_ap_enable(const struct device * dev,struct wifi_connect_req_params * params)724 static int eswifi_mgmt_ap_enable(const struct device *dev,
725 				 struct wifi_connect_req_params *params)
726 {
727 	LOG_ERR("IPv4 requested for AP mode");
728 	return -ENOTSUP;
729 }
730 #endif /* CONFIG_NET_IPV4 */
731 
eswifi_mgmt_ap_disable(const struct device * dev)732 static int eswifi_mgmt_ap_disable(const struct device *dev)
733 {
734 	struct eswifi_dev *eswifi = dev->data;
735 	char cmd[] = "AE\r";
736 	int err;
737 
738 	eswifi_lock(eswifi);
739 
740 	err = eswifi_at_cmd(eswifi, cmd);
741 	if (err < 0) {
742 		eswifi_unlock(eswifi);
743 		return -EIO;
744 	}
745 
746 	eswifi->role = ESWIFI_ROLE_CLIENT;
747 
748 	eswifi_unlock(eswifi);
749 
750 	return 0;
751 }
752 
eswifi_init(const struct device * dev)753 static int eswifi_init(const struct device *dev)
754 {
755 	struct eswifi_dev *eswifi = dev->data;
756 	const struct eswifi_cfg *cfg = dev->config;
757 
758 	LOG_DBG("");
759 
760 	eswifi->role = ESWIFI_ROLE_CLIENT;
761 	k_mutex_init(&eswifi->mutex);
762 
763 	eswifi->bus = eswifi_get_bus();
764 	eswifi->bus->init(eswifi);
765 
766 	if (!gpio_is_ready_dt(&cfg->resetn)) {
767 		LOG_ERR("%s: device %s is not ready", dev->name,
768 				cfg->resetn.port->name);
769 		return -ENODEV;
770 	}
771 	gpio_pin_configure_dt(&cfg->resetn, GPIO_OUTPUT_INACTIVE);
772 
773 	if (!gpio_is_ready_dt(&cfg->wakeup)) {
774 		LOG_ERR("%s: device %s is not ready", dev->name,
775 				cfg->wakeup.port->name);
776 		return -ENODEV;
777 	}
778 	gpio_pin_configure_dt(&cfg->wakeup, GPIO_OUTPUT_ACTIVE);
779 
780 	k_work_queue_start(&eswifi->work_q, eswifi_work_q_stack,
781 			   K_KERNEL_STACK_SIZEOF(eswifi_work_q_stack),
782 			   CONFIG_SYSTEM_WORKQUEUE_PRIORITY - 1, NULL);
783 
784 	k_work_init(&eswifi->request_work, eswifi_request_work);
785 	k_work_init_delayable(&eswifi->status_work, eswifi_status_work);
786 
787 	eswifi_shell_register(eswifi);
788 
789 	return 0;
790 }
791 
eswifi_get_type(void)792 static enum offloaded_net_if_types eswifi_get_type(void)
793 {
794 	return L2_OFFLOADED_NET_IF_TYPE_WIFI;
795 }
796 
797 static const struct wifi_mgmt_ops eswifi_mgmt_api = {
798 	.scan		= eswifi_mgmt_scan,
799 	.connect	= eswifi_mgmt_connect,
800 	.disconnect	= eswifi_mgmt_disconnect,
801 	.ap_enable	= eswifi_mgmt_ap_enable,
802 	.ap_disable	= eswifi_mgmt_ap_disable,
803 	.iface_status	= eswifi_mgmt_iface_status,
804 };
805 
806 static const struct net_wifi_mgmt_offload eswifi_offload_api = {
807 	.wifi_iface.iface_api.init = eswifi_iface_init,
808 	.wifi_iface.get_type = eswifi_get_type,
809 	.wifi_mgmt_api = &eswifi_mgmt_api,
810 };
811 
812 NET_DEVICE_DT_INST_OFFLOAD_DEFINE(0, eswifi_init, NULL,
813 				  &eswifi0, &eswifi0_cfg,
814 				  CONFIG_WIFI_INIT_PRIORITY,
815 				  &eswifi_offload_api,
816 				  1500);
817 
818 CONNECTIVITY_WIFI_MGMT_BIND(Z_DEVICE_DT_DEV_ID(DT_DRV_INST(0)));
819