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