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