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