]> Git Repo - esp-hosted.git/blame - esp_hosted_ng/host/main.c
Merge branch 'esp-hosted-ng_c3_support' into 'master'
[esp-hosted.git] / esp_hosted_ng / host / main.c
CommitLineData
774e9b2e
MM
1/*
2 * Espressif Systems Wireless LAN device driver
3 *
4 * Copyright (C) 2015-2021 Espressif Systems (Shanghai) PTE LTD
5 *
6 * This software file (the "File") is distributed by Espressif Systems (Shanghai)
7 * PTE LTD under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include <linux/init.h>
21#include <linux/module.h>
22#include <linux/kernel.h>
23#include <linux/gpio.h>
24
25#include "esp.h"
26#include "esp_if.h"
27#include "esp_bt_api.h"
28#include "esp_api.h"
29#include "esp_cmd.h"
aad2ae2e 30#include "esp_kernel_port.h"
774e9b2e
MM
31
32#include "esp_cfg80211.h"
33
774e9b2e
MM
34#define HOST_GPIO_PIN_INVALID -1
35static int resetpin = HOST_GPIO_PIN_INVALID;
36extern u8 ap_bssid[MAC_ADDR_LEN];
37
38module_param(resetpin, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
39MODULE_PARM_DESC(resetpin, "Host's GPIO pin number which is connected to ESP32's EN to reset ESP32 device");
40
41static void deinit_adapter(void);
42
43
44struct esp_adapter adapter;
45/*struct esp_device esp_dev;*/
46
47struct esp_adapter * esp_get_adapter(void)
48{
49 return &adapter;
50}
51
52void esp_process_new_packet_intr(struct esp_adapter *adapter)
53{
54 if(adapter)
55 queue_work(adapter->if_rx_workqueue, &adapter->if_rx_work);
56}
57
58static int process_tx_packet (struct sk_buff *skb)
59{
60 struct esp_wifi_device *priv = NULL;
61 struct esp_skb_cb *cb = NULL;
62 struct esp_payload_header *payload_header = NULL;
63 struct sk_buff *new_skb = NULL;
64 int ret = 0;
65 u8 pad_len = 0, realloc_skb = 0;
66 u16 len = 0;
67 u16 total_len = 0;
68 static u8 c = 0;
69 u8 *pos = NULL;
70
71 c++;
72 /* Get the priv */
73 cb = (struct esp_skb_cb *) skb->cb;
74 priv = cb->priv;
75
76 if (!priv) {
77 dev_kfree_skb(skb);
78 printk(KERN_INFO "%s: no priv\n", __func__);
79 return NETDEV_TX_OK;
80 }
81
82 if (netif_queue_stopped((const struct net_device *) priv->ndev)) {
83 printk(KERN_INFO "%s: Netif queue stopped\n", __func__);
84 return NETDEV_TX_BUSY;
85 }
86
87 len = skb->len;
88
89 /* Create space for payload header */
90 pad_len = sizeof(struct esp_payload_header);
91
92 total_len = len + pad_len;
93
94 /* Align buffer length */
95 pad_len += SKB_DATA_ADDR_ALIGNMENT - (total_len % SKB_DATA_ADDR_ALIGNMENT);
96
97 if (skb_headroom(skb) < pad_len) {
98 /* Headroom is not sufficient */
99 realloc_skb = 1;
100 }
101
102 if (realloc_skb || !IS_ALIGNED((unsigned long) skb->data, SKB_DATA_ADDR_ALIGNMENT)) {
103 /* Realloc SKB */
104 if (skb_linearize(skb)) {
105 priv->stats.tx_errors++;
106 dev_kfree_skb(skb);
107 printk(KERN_ERR "%s: Failed to linearize SKB", __func__);
108 return NETDEV_TX_OK;
109 }
110
111 new_skb = esp_alloc_skb(skb->len + pad_len);
112
113 if (!new_skb) {
114 printk(KERN_ERR "%s: Failed to allocate SKB", __func__);
115 priv->stats.tx_errors++;
116 dev_kfree_skb(skb);
117 return NETDEV_TX_OK;
118 }
119
120 pos = new_skb->data;
121 pos += pad_len;
122
123 /* Populate new SKB */
124 skb_copy_from_linear_data(skb, pos, skb->len);
125 skb_put(new_skb, skb->len + pad_len);
126
127 /* Replace old SKB */
128 dev_kfree_skb_any(skb);
129 skb = new_skb;
130 } else {
131 /* Realloc is not needed, Make space for interface header */
132 skb_push(skb, pad_len);
133 }
134
135 /* Set payload header */
136 payload_header = (struct esp_payload_header *) skb->data;
137 memset(payload_header, 0, pad_len);
138
139 payload_header->if_type = priv->if_type;
140 payload_header->if_num = priv->if_num;
141 payload_header->len = cpu_to_le16(len);
142 payload_header->offset = cpu_to_le16(pad_len);
143 payload_header->packet_type = PACKET_TYPE_DATA;
144
145 payload_header->checksum = cpu_to_le16(compute_checksum(skb->data, (len + pad_len)));
146
147 if (!priv->stop_data) {
148 ret = esp_send_packet(priv->adapter, skb);
149
150 if (ret) {
151/* printk(KERN_ERR "%s: Failed to send SKB", __func__);*/
152 priv->stats.tx_errors++;
153 } else {
154 priv->stats.tx_packets++;
155 priv->stats.tx_bytes += skb->len;
156 }
157 } else {
158 dev_kfree_skb_any(skb);
159 priv->stats.tx_dropped++;
160 }
161
162 return 0;
163}
164
165void esp_port_open(struct esp_wifi_device * priv)
166{
167 priv->port_open = 1;
168 priv->stop_data = 0;
169}
170
171void esp_port_close(struct esp_wifi_device * priv)
172{
173 if (!priv)
174 return;
175
176 priv->port_open = 0;
177 priv->stop_data = 1;
178}
179
180void print_capabilities(u32 cap)
181{
182 printk(KERN_INFO "Capabilities: 0x%x. Features supported are:\n", cap);
183 if (cap & ESP_WLAN_SDIO_SUPPORT)
184 printk(KERN_INFO "\t * WLAN on SDIO\n");
185 else if (cap & ESP_WLAN_SPI_SUPPORT)
186 printk(KERN_INFO "\t * WLAN on SPI\n");
187
188 if ((cap & ESP_BT_UART_SUPPORT) ||
189 (cap & ESP_BT_SDIO_SUPPORT) ||
190 (cap & ESP_BT_SPI_SUPPORT)) {
191 printk(KERN_INFO "\t * BT/BLE\n");
192 if (cap & ESP_BT_UART_SUPPORT)
193 printk(KERN_INFO "\t - HCI over UART\n");
194 if (cap & ESP_BT_SDIO_SUPPORT)
195 printk(KERN_INFO "\t - HCI over SDIO\n");
196 if (cap & ESP_BT_SPI_SUPPORT)
197 printk(KERN_INFO "\t - HCI over SPI\n");
198
199 if ((cap & ESP_BLE_ONLY_SUPPORT) && (cap & ESP_BR_EDR_ONLY_SUPPORT))
200 printk(KERN_INFO "\t - BT/BLE dual mode\n");
201 else if (cap & ESP_BLE_ONLY_SUPPORT)
202 printk(KERN_INFO "\t - BLE only\n");
203 else if (cap & ESP_BR_EDR_ONLY_SUPPORT)
204 printk(KERN_INFO "\t - BR EDR only\n");
205 }
206}
207
208void process_capabilities(struct esp_adapter *adapter)
209{
210 printk(KERN_INFO "ESP peripheral capabilities: 0x%x\n", adapter->capabilities);
211
212 /* Reset BT */
213 esp_deinit_bt(adapter);
214
215 if ((adapter->capabilities & ESP_BT_SPI_SUPPORT) ||
216 (adapter->capabilities & ESP_BT_SDIO_SUPPORT)) {
217 msleep(200);
218 printk(KERN_INFO "ESP Bluetooth init\n");
219 esp_init_bt(adapter);
220 }
221}
222
223static int check_esp_version(struct fw_version *ver)
224{
225 printk(KERN_INFO "esp32: ESP Firmware version: %u.%u.%u\n",
226 ver->major1, ver->major2, ver->minor);
227 if (!ver->major1) {
228 printk(KERN_ERR "Incompatible ESP firmware release detected, Please use correct ESP-Hosted branch/compatible release\n");
229 return -1;
230 }
231 return 0;
232}
233
234static void print_reset_reason(uint32_t reason)
235{
236 switch (reason)
237 {
238 case 1 : printk(KERN_INFO "POWERON_RESET\n");break; /**<1, Vbat power on reset*/
239 case 3 : printk(KERN_INFO "SW_RESET\n");break; /**<3, Software reset digital core*/
240 case 4 : printk(KERN_INFO "OWDT_RESET\n");break; /**<4, Legacy watch dog reset digital core*/
241 case 5 : printk(KERN_INFO "DEEPSLEEP_RESET\n");break; /**<5, Deep Sleep reset digital core*/
242 case 6 : printk(KERN_INFO "SDIO_RESET\n");break; /**<6, Reset by SLC module, reset digital core*/
243 case 7 : printk(KERN_INFO "TG0WDT_SYS_RESET\n");break; /**<7, Timer Group0 Watch dog reset digital core*/
244 case 8 : printk(KERN_INFO "TG1WDT_SYS_RESET\n");break; /**<8, Timer Group1 Watch dog reset digital core*/
245 case 9 : printk(KERN_INFO "RTCWDT_SYS_RESET\n");break; /**<9, RTC Watch dog Reset digital core*/
246 case 10 : printk(KERN_INFO "INTRUSION_RESET\n");break; /**<10, Instrusion tested to reset CPU*/
247 case 11 : printk(KERN_INFO "TGWDT_CPU_RESET\n");break; /**<11, Time Group reset CPU*/
248 case 12 : printk(KERN_INFO "SW_CPU_RESET\n");break; /**<12, Software reset CPU*/
249 case 13 : printk(KERN_INFO "RTCWDT_CPU_RESET\n");break; /**<13, RTC Watch dog Reset CPU*/
250 case 14 : printk(KERN_INFO "EXT_CPU_RESET\n");break; /**<14, for APP CPU, reseted by PRO CPU*/
251 case 15 : printk(KERN_INFO "RTCWDT_BROWN_OUT_RESET\n");break;/**<15, Reset when the vdd voltage is not stable*/
252 case 16 : printk(KERN_INFO "RTCWDT_RTC_RESET\n");break; /**<16, RTC Watch dog reset digital core and rtc module*/
253 default : printk(KERN_INFO "Unknown[%u]\n",reason);break;
254 }
255}
256
257int process_fw_data(struct fw_data *fw_p)
258{
259 if (!fw_p) {
260 printk(KERN_ERR "Incomplete/incorrect bootup event received\n");
261 return -1;
262 }
263
264 printk(KERN_INFO "esp32: %s ESP chipset's last reset cause: ", __func__);
265 print_reset_reason(le32_to_cpu(fw_p->last_reset_reason));
266 return check_esp_version(&fw_p->version);
267}
268
269static int esp_open(struct net_device *ndev)
270{
774e9b2e
MM
271 return 0;
272}
273
274static int esp_stop(struct net_device *ndev)
275{
225e14eb 276 struct esp_wifi_device *priv = netdev_priv(ndev);
0af9c02e 277 ESP_MARK_SCAN_DONE(priv, true);
774e9b2e
MM
278 return 0;
279}
280
281static struct net_device_stats* esp_get_stats(struct net_device *ndev)
282{
283 struct esp_wifi_device *priv = netdev_priv(ndev);
284
285 if (!priv)
286 return NULL;
287
288 return &priv->stats;
289}
290
291static int esp_set_mac_address(struct net_device *ndev, void *data)
292{
293 struct esp_wifi_device *priv = netdev_priv(ndev);
294 //struct sockaddr *mac_addr = data;
295
296 if (!priv || !priv->adapter)
297 return -EINVAL;
298
299 printk(KERN_INFO "%s:%u %pM\n", __func__, __LINE__, priv->mac_address);
300 /* TODO Handle in correct way */
301 ether_addr_copy(ndev->dev_addr, priv->mac_address/*mac_addr->sa_data*/);
302
774e9b2e
MM
303 return 0;
304}
305
4c494b4b 306static NDO_TX_TIMEOUT_PROTOTYPE()
774e9b2e
MM
307{
308}
309
310static void esp_set_rx_mode(struct net_device *ndev)
311{
312}
313
314static int esp_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
315{
316 struct esp_wifi_device *priv = NULL;
317 struct esp_skb_cb *cb = NULL;
318
319 if (!skb || !ndev)
320 return NETDEV_TX_OK;
321
322 priv = netdev_priv(ndev);
323 if (!priv) {
324 dev_kfree_skb(skb);
325 return NETDEV_TX_OK;
326 }
327
328 if (!priv->port_open) {
329 priv->stats.tx_dropped++;
330 /*printk(KERN_ERR "esp32: %s: port not yet open\n", __func__);*/
331 dev_kfree_skb(skb);
332 return NETDEV_TX_OK;
333 }
334
335 if (!skb->len || (skb->len > ETH_FRAME_LEN)) {
336 printk(KERN_ERR "esp32: %s: Bad len %d\n", __func__, skb->len);
337 priv->stats.tx_dropped++;
338 dev_kfree_skb(skb);
339 return NETDEV_TX_OK;
340 }
341
342 cb = (struct esp_skb_cb *) skb->cb;
343 cb->priv = priv;
344
345 return process_tx_packet(skb);
346}
347
348static const struct net_device_ops esp_netdev_ops = {
349 .ndo_open = esp_open,
350 .ndo_stop = esp_stop,
351 .ndo_start_xmit = esp_hard_start_xmit,
352 .ndo_set_mac_address = esp_set_mac_address,
353 .ndo_validate_addr = eth_validate_addr,
354 .ndo_tx_timeout = esp_tx_timeout,
355 .ndo_get_stats = esp_get_stats,
356 .ndo_set_rx_mode = esp_set_rx_mode,
357};
358
359
360void esp_init_priv(struct net_device *ndev)
361{
362 ndev->netdev_ops = &esp_netdev_ops;
363 ndev->needed_headroom = roundup(sizeof(struct esp_payload_header) +
364 INTERFACE_HEADER_PADDING, 4);
365}
366
774e9b2e
MM
367static int add_network_iface(void)
368{
369 int ret = 0;
370 struct esp_adapter * adapter = esp_get_adapter();
225e14eb 371 struct wireless_dev * wdev = NULL;
774e9b2e
MM
372
373 if (!adapter) {
374 printk(KERN_INFO "%s: adapter not yet init\n", __func__);
375 return -EINVAL;
376 }
377
378 ret = esp_cfg80211_register(adapter);
379 if (ret) {
380 printk(KERN_ERR "Failed to register with cfg80211 (err code 0x%x)\n", ret);
381 return ret;
382 }
383
384 rtnl_lock();
225e14eb 385 wdev = esp_cfg80211_add_iface(adapter->wiphy, "espsta%d", 1, NL80211_IFTYPE_STATION, NULL);
774e9b2e
MM
386 rtnl_unlock();
387
225e14eb
YM
388 /* Return success if network added successfully */
389 if (wdev)
390 return 0;
391
392 return -1;
774e9b2e
MM
393}
394
395int esp_add_card(struct esp_adapter *adapter)
396{
225e14eb 397 RET_ON_FAIL(esp_commands_setup(adapter));
774e9b2e 398
225e14eb 399 RET_ON_FAIL(add_network_iface());
774e9b2e 400
225e14eb 401 return 0;
774e9b2e
MM
402}
403
404void esp_remove_network_interfaces(struct esp_adapter *adapter)
405{
406 uint8_t iface_idx = 0;
407 struct net_device *ndev = NULL;
408 struct esp_wifi_device *priv = NULL;
409
410 for (iface_idx=0; iface_idx < ESP_MAX_INTERFACE; iface_idx++) {
411
412 priv = adapter->priv[iface_idx];
413
414 if (!priv)
415 continue;
416
417 if (!test_bit(ESP_NETWORK_UP, &priv->priv_flags))
418 continue;
419
420 /* stop and unregister network */
421 ndev = priv->ndev;
422
423 if (ndev) {
424
425 if (netif_carrier_ok(ndev))
426 netif_carrier_off(ndev);
427
428 netif_device_detach(ndev);
429
430 if (ndev->reg_state == NETREG_REGISTERED) {
431 unregister_netdev(ndev);
432 free_netdev(ndev);
433 ndev = NULL;
434 }
435 }
436 clear_bit(ESP_NETWORK_UP, &priv->priv_flags);
437 }
438
439 if (adapter->wiphy) {
440
441 wiphy_unregister(adapter->wiphy);
442 wiphy_free(adapter->wiphy);
443 adapter->wiphy = NULL;
444 }
445}
446
447int esp_remove_card(struct esp_adapter *adapter)
448{
449 uint8_t iface_idx = 0;
450
451 if (!adapter) {
452 return 0;
453 }
454
225e14eb 455 esp_deinit_bt(adapter);
774e9b2e 456
225e14eb 457 esp_commands_teardown(adapter);
774e9b2e
MM
458
459 esp_remove_network_interfaces(adapter);
460
461 for (iface_idx=0; iface_idx < ESP_MAX_INTERFACE; iface_idx++) {
462 esp_port_close(adapter->priv[iface_idx]);
463 adapter->priv[iface_idx] = NULL;
464 }
465
466 return 0;
467}
468
469struct esp_wifi_device * get_priv_from_payload_header(
470 struct esp_payload_header *header)
471{
472 struct esp_wifi_device *priv = NULL;
473 u8 i = 0;
474
475 if (!header)
476 return NULL;
477
478 for (i = 0; i < ESP_MAX_INTERFACE; i++) {
479 priv = adapter.priv[i];
480
481 if (!priv)
482 continue;
483
484 if (priv->if_type == header->if_type &&
485 priv->if_num == header->if_num) {
486 return priv;
487 }
488 }
489 return NULL;
490}
491
492static void process_esp_bootup_event(struct esp_adapter *adapter,
493 struct esp_internal_bootup_event *evt)
494{
495 if (!adapter || !evt) {
496 printk(KERN_ERR "%s: Invalid arguments\n", __func__);
497 return;
498 }
499
500 if (evt->header.status) {
501 printk(KERN_ERR "%s: Incorrect ESP bootup event\n", __func__);
502 return;
503 }
504
505 printk (KERN_INFO "\nReceived ESP bootup event\n");
506 process_event_esp_bootup(adapter, evt->data, evt->len);
507}
508
509static int process_internal_event(struct esp_adapter *adapter,
510 struct sk_buff *skb)
511{
512 struct event_header *header = NULL;
513
514 if (!skb || !adapter) {
515 printk (KERN_ERR "esp32: Incorrect event data!\n");
516 return -1;
517 }
518
519 header = (struct event_header *) (skb->data);
520
521 switch (header->event_code) {
522
523 case ESP_INTERNAL_BOOTUP_EVENT:
524 process_esp_bootup_event(adapter,
525 (struct esp_internal_bootup_event *)(skb->data));
526 break;
527
528 default:
529 printk(KERN_INFO "%s:%u unhandled internal event[%u]\n",
530 __func__, __LINE__, header->event_code);
531 break;
532 }
533
534 return 0;
535}
536
537static void process_rx_packet(struct esp_adapter *adapter, struct sk_buff *skb)
538{
539 struct esp_wifi_device *priv = NULL;
540 struct esp_payload_header *payload_header = NULL;
541 u16 len = 0, offset = 0;
542 struct hci_dev *hdev = adapter->hcidev;
543 u8 *type = NULL;
544 struct sk_buff * eap_skb = NULL;
545 struct ethhdr * eth = NULL;
546
547 if (!skb)
548 return;
549
550 /* get the paload header */
551 payload_header = (struct esp_payload_header *) skb->data;
552
553 len = le16_to_cpu(payload_header->len);
554 offset = le16_to_cpu(payload_header->offset);
555
556 /*print_hex_dump(KERN_ERR , "rx: ", DUMP_PREFIX_ADDRESS, 16, 1, skb->data, len, 1);*/
557
558 payload_header->checksum = 0;
559
560 /* chop off the header from skb */
561 skb_pull(skb, offset);
562
563 if (payload_header->if_type == ESP_STA_IF || payload_header->if_type == ESP_AP_IF) {
564
565 /* retrieve priv based on payload header contents */
566 priv = get_priv_from_payload_header(payload_header);
567
568 if (!priv) {
569 printk(KERN_ERR "%s: empty priv\n", __func__);
570 dev_kfree_skb_any(skb);
571 return;
572 }
573
574 if (payload_header->packet_type == PACKET_TYPE_EAPOL) {
bd131325 575 printk(KERN_INFO "%s: Rx PACKET_TYPE_EAPOL!!!!\n", __func__);
774e9b2e
MM
576 esp_port_open(priv);
577
7b6ed49e 578 eap_skb = alloc_skb(skb->len + ETH_HLEN, GFP_KERNEL);
774e9b2e
MM
579 if(!eap_skb) {
580 printk(KERN_INFO "%s:%u memory alloc failed\n",__func__, __LINE__);
581 return;
582 }
583 eap_skb->dev = priv->ndev;
584
585 if (!IS_ALIGNED((unsigned long) eap_skb->data, SKB_DATA_ADDR_ALIGNMENT)) {
586 printk(KERN_INFO "%s:%u eap skb unaligned\n",__func__, __LINE__);
587 }
588
aad2ae2e 589 eth = (struct ethhdr *) skb_put(eap_skb, ETH_HLEN);
774e9b2e
MM
590 ether_addr_copy(eth->h_dest, /*skb->data*/priv->ndev->dev_addr);
591 ether_addr_copy(eth->h_source, /*skb->data+6*/ ap_bssid);
592 eth->h_proto = cpu_to_be16(ETH_P_PAE);
593
594 skb_put_data(eap_skb, skb->data, skb->len);
595 eap_skb->protocol = eth_type_trans(eap_skb, eap_skb->dev);
596
597 netif_rx(eap_skb);
598
599 } else if (payload_header->packet_type == PACKET_TYPE_DATA) {
600
601 skb->dev = priv->ndev;
602 skb->protocol = eth_type_trans(skb, priv->ndev);
603 skb->ip_summed = CHECKSUM_NONE;
604
605 priv->stats.rx_bytes += skb->len;
606 /* Forward skb to kernel */
607 netif_rx_ni(skb);
608
609 priv->stats.rx_packets++;
610 } else if (payload_header->packet_type == PACKET_TYPE_COMMAND_RESPONSE) {
225e14eb 611 process_cmd_resp(priv->adapter, skb);
774e9b2e 612 } else if (payload_header->packet_type == PACKET_TYPE_EVENT) {
225e14eb 613 process_cmd_event(priv, skb);
774e9b2e
MM
614 dev_kfree_skb_any(skb);
615 }
616
617 } else if (payload_header->if_type == ESP_HCI_IF) {
618 if (hdev) {
619
620 type = skb->data;
621 hci_skb_pkt_type(skb) = *type;
622 skb_pull(skb, 1);
623
624#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
625 if (hci_recv_frame(hdev, skb)) {
626#else
627 if (hci_recv_frame(skb)) {
628#endif
629 hdev->stat.err_rx++;
630 } else {
631 esp_hci_update_rx_counter(hdev, *type, skb->len);
632 }
633 }
634 } else if (payload_header->if_type == ESP_INTERNAL_IF) {
635
636 /* Queue event skb for processing in events workqueue */
637 skb_queue_tail(&adapter->events_skb_q, skb);
638
639 if (adapter->events_wq)
640 queue_work(adapter->events_wq, &adapter->events_work);
641 else
642 dev_kfree_skb_any(skb);
643
644 } else {
645 dev_kfree_skb_any(skb);
646 }
647}
648
649void esp_tx_pause(struct esp_wifi_device *priv)
650{
651 if (!priv || !priv->ndev)
652 return;
653
654 if (!netif_queue_stopped((const struct net_device *)priv->ndev)) {
655 netif_stop_queue(priv->ndev);
656 }
657}
658
659void esp_tx_resume(struct esp_wifi_device *priv)
660{
661 if (!priv || !priv->ndev)
662 return;
663
664 if (netif_queue_stopped((const struct net_device *)priv->ndev)) {
665 netif_wake_queue(priv->ndev);
666 }
667}
668
669struct sk_buff * esp_alloc_skb(u32 len)
670{
671 struct sk_buff *skb = NULL;
672
673 u8 offset;
674
675 skb = netdev_alloc_skb(NULL, len + INTERFACE_HEADER_PADDING);
676
677 if (skb) {
678 /* Align SKB data pointer */
679 offset = ((unsigned long)skb->data) & (SKB_DATA_ADDR_ALIGNMENT - 1);
680
681 if (offset)
682 skb_reserve(skb, INTERFACE_HEADER_PADDING - offset);
683 }
684
685 return skb;
686}
687
688
689static int esp_get_packets(struct esp_adapter *adapter)
690{
691 struct sk_buff *skb = NULL;
692
693 if (!adapter || !adapter->if_ops || !adapter->if_ops->read)
694 return -EINVAL;
695
696 skb = adapter->if_ops->read(adapter);
697
698 if (!skb)
699 return -EFAULT;
700
701 process_rx_packet(adapter, skb);
702
703 return 0;
704}
705
706int esp_send_packet(struct esp_adapter *adapter, struct sk_buff *skb)
707{
225e14eb
YM
708 if (!adapter || !adapter->if_ops || !adapter->if_ops->write) {
709 printk(KERN_ERR "esp32: %s:%u adapter: %p\n", __func__, __LINE__, adapter);
774e9b2e 710 return -EINVAL;
225e14eb 711 }
774e9b2e
MM
712
713 return adapter->if_ops->write(adapter, skb);
714}
715
716static void esp_if_rx_work(struct work_struct *work)
717{
718 /* read inbound packet and forward it to network/serial interface */
719 esp_get_packets(&adapter);
720}
721
722static void esp_events_work(struct work_struct *work)
723{
724 struct sk_buff *skb = NULL;
725
726 skb = skb_dequeue(&adapter.events_skb_q);
727 if (!skb)
728 return;
729
730 process_internal_event(&adapter, skb);
731 dev_kfree_skb_any(skb);
732}
733
734static struct esp_adapter * init_adapter(void)
735{
736 memset(&adapter, 0, sizeof(adapter));
737
738 /* Prepare interface RX work */
739 adapter.if_rx_workqueue = alloc_workqueue("ESP_IF_RX_WORK_QUEUE", 0, 0);
740
741 if (!adapter.if_rx_workqueue) {
742 deinit_adapter();
743 return NULL;
744 }
745
746 INIT_WORK(&adapter.if_rx_work, esp_if_rx_work);
747
748 skb_queue_head_init(&adapter.events_skb_q);
749
750 adapter.events_wq = alloc_workqueue("ESP_EVENTS_WORKQUEUE", WQ_HIGHPRI, 0);
751
752 if (!adapter.events_wq) {
753 deinit_adapter();
754 return NULL;
755 }
756
757 INIT_WORK(&adapter.events_work, esp_events_work);
758
759 return &adapter;
760}
761
762static void deinit_adapter(void)
763{
764 skb_queue_purge(&adapter.events_skb_q);
765
766 if (adapter.events_wq)
767 destroy_workqueue(adapter.events_wq);
768
769 if (adapter.if_rx_workqueue)
770 destroy_workqueue(adapter.if_rx_workqueue);
771}
772
773static void esp_reset(void)
774{
775 if (resetpin != HOST_GPIO_PIN_INVALID) {
776 /* Check valid GPIO or not */
777 if (!gpio_is_valid(resetpin)) {
778 printk(KERN_WARNING "%s, ESP32: host resetpin (%d) configured is invalid GPIO\n", __func__, resetpin);
779 resetpin = HOST_GPIO_PIN_INVALID;
780 } else {
781 gpio_request(resetpin, "sysfs");
782
783 /* HOST's resetpin set to OUTPUT, HIGH */
784 gpio_direction_output(resetpin, true);
785
786 /* HOST's resetpin set to LOW */
787 gpio_set_value(resetpin, 0);
788 udelay(200);
789
790 /* HOST's resetpin set to INPUT */
791 gpio_direction_input(resetpin);
792
793 printk(KERN_DEBUG "%s, ESP32: Triggering ESP reset.\n", __func__);
794 }
795 }
796}
797
798
799static int __init esp_init(void)
800{
801 int ret = 0;
802 struct esp_adapter *adapter = NULL;
803
804 /* Reset ESP, Clean start ESP */
805 esp_reset();
806 msleep(200);
807
808 adapter = init_adapter();
809
810 if (!adapter)
811 return -EFAULT;
812
813 /* Init transport layer */
814 ret = esp_init_interface_layer(adapter);
815
816 if (ret != 0) {
817 deinit_adapter();
818 }
819
820 return ret;
821}
822
823static void __exit esp_exit(void)
824{
825 uint8_t iface_idx = 0;
826
827 for (iface_idx=0; iface_idx<ESP_MAX_INTERFACE; iface_idx++) {
828 cmd_deinit_interface(adapter.priv[iface_idx]);
829 }
225e14eb 830 clear_bit(ESP_DRIVER_ACTIVE, &adapter.state_flags);
774e9b2e
MM
831
832 esp_deinit_interface_layer();
833 deinit_adapter();
834
835 if (resetpin != HOST_GPIO_PIN_INVALID) {
836 gpio_free(resetpin);
837 }
838}
839MODULE_LICENSE("GPL");
840MODULE_AUTHOR("Amey Inamdar <[email protected]>");
841MODULE_AUTHOR("Mangesh Malusare <[email protected]>");
842MODULE_AUTHOR("Yogesh Mantri <[email protected]>");
843MODULE_DESCRIPTION("Wifi driver for ESP-Hosted solution");
844MODULE_VERSION("0.1");
845module_init(esp_init);
846module_exit(esp_exit);
This page took 0.116663 seconds and 4 git commands to generate.