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