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