drv_wifi.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. /*
  2. * File : drv_wifi.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2017, RT-Thread Development Team
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2017-5-30 Bernard the first version
  23. * 2018-5-30 flyingcys add amebaz wifi driver
  24. */
  25. #include <rtthread.h>
  26. #include <wlan_dev.h>
  27. #include <skbuff.h>
  28. #include "amebaz_wlan.h"
  29. //#define ETH_RX_DUMP
  30. //#define ETH_TX_DUMP
  31. //#define MINI_DUMP
  32. struct sk_buff * rltk_wlan_get_recv_skb(int idx);
  33. struct sk_buff * rltk_wlan_alloc_skb(unsigned int total_len);
  34. #define MAX_ADDR_LEN 6
  35. struct ameba_wifi
  36. {
  37. struct rt_wlan_device parent;
  38. rt_uint8_t dev_addr[MAX_ADDR_LEN];
  39. int idx;
  40. int connected;
  41. };
  42. #ifdef RT_USING_WLAN_STA
  43. static struct ameba_wifi wifi_sta;
  44. #endif
  45. #ifdef RT_USING_WLAN_AP
  46. static struct ameba_wifi wifi_ap;
  47. #endif
  48. #if defined(ETH_RX_DUMP) || defined(ETH_TX_DUMP)
  49. static void packet_dump(const char *msg, const struct pbuf *p)
  50. {
  51. const struct pbuf *q;
  52. rt_uint32_t i, j;
  53. rt_uint8_t *ptr;
  54. rt_kprintf("%s %d byte\n", msg, p->tot_len);
  55. #ifdef MINI_DUMP
  56. return;
  57. #endif
  58. i = 0;
  59. for (q = p; q != RT_NULL; q = q->next)
  60. {
  61. ptr = q->payload;
  62. for (j = 0; j < q->len; j++)
  63. {
  64. if ((i % 8) == 0)
  65. {
  66. rt_kprintf(" ");
  67. }
  68. if ((i % 16) == 0)
  69. {
  70. rt_kprintf("\r\n");
  71. }
  72. rt_kprintf("%02x ", *ptr);
  73. i++;
  74. ptr++;
  75. }
  76. }
  77. rt_kprintf("\n\n");
  78. }
  79. #endif /* dump */
  80. #define netifapi_netif_set_link_up(n) netifapi_netif_common(n, netif_set_link_up, NULL)
  81. #define netifapi_netif_set_link_down(n) netifapi_netif_common(n, netif_set_link_down, NULL)
  82. void netif_set_connected(int connected)
  83. {
  84. wifi_sta.connected = connected;
  85. if (connected)
  86. {
  87. netifapi_netif_set_link_up(wifi_sta.parent.parent.netif);
  88. }
  89. else
  90. {
  91. netifapi_netif_set_link_down(wifi_sta.parent.parent.netif);
  92. }
  93. }
  94. void rltk_wlan_set_netif_info(int idx_wlan, void * dev, unsigned char * dev_addr)
  95. {
  96. struct ameba_wifi *wifi;
  97. if(idx_wlan == 0)
  98. wifi = &wifi_sta;
  99. rtw_memcpy(wifi->dev_addr, dev_addr, 6);
  100. rt_hw_wifi_init();
  101. }
  102. void netif_rx(int idx, unsigned int len)
  103. {
  104. struct ameba_wifi *wifi;
  105. struct pbuf *p, *q;
  106. int sg_len = 0;
  107. struct sk_buff *skb = RT_NULL;
  108. if(idx == 0)
  109. wifi = &wifi_sta;
  110. #if CONFIG_WLAN
  111. if(!wifi->connected || !rltk_wlan_running(idx))
  112. return;
  113. #endif
  114. skb = rltk_wlan_get_recv_skb(idx);
  115. if(!skb)
  116. {
  117. rt_kprintf("netif_rx rltk_wlan_get_recv_skb NULL.\n");
  118. return;
  119. }
  120. p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
  121. if (p != RT_NULL)
  122. {
  123. pbuf_take(p, skb->data, len);
  124. skb_pull(skb, len);
  125. #ifdef ETH_RX_DUMP
  126. packet_dump("RX dump", p);
  127. #endif /* ETH_RX_DUMP */
  128. if(wifi->parent.parent.netif->input(p, wifi->parent.parent.netif) != ERR_OK)
  129. {
  130. pbuf_free(p);
  131. }
  132. }
  133. else
  134. {
  135. rt_kprintf("pbuf_alloc NULL for wifi RX.\n");
  136. }
  137. }
  138. int netif_is_valid_IP(int idx, unsigned char *ip_dest)
  139. {
  140. struct netif * pnetif;
  141. struct ip_addr addr = { 0 };
  142. u32_t *ip_dest_addr = (u32_t*)ip_dest;
  143. if(idx == 0)
  144. pnetif = wifi_sta.parent.parent.netif;
  145. addr.addr = *ip_dest_addr;
  146. if(pnetif == RT_NULL)
  147. return 0;
  148. if(pnetif->ip_addr.addr == 0)
  149. return 1;
  150. if(ip_addr_ismulticast(&addr) || ip_addr_isbroadcast(&addr,pnetif))
  151. {
  152. return 1;
  153. }
  154. if(ip_addr_cmp(&(pnetif->ip_addr), &addr))
  155. return 1;
  156. return 0;
  157. }
  158. void netif_post_sleep_processing(void)
  159. {
  160. }
  161. void netif_pre_sleep_processing(void)
  162. {
  163. }
  164. unsigned char *rltk_wlan_get_ip(int idx)
  165. {
  166. struct ameba_wifi *wifi;
  167. if(idx == 0)
  168. wifi = &wifi_sta;
  169. return (unsigned char *)&(wifi->parent.parent.netif->ip_addr);
  170. }
  171. struct netif *rltk_wlan_get_netif(int idx)
  172. {
  173. struct netif *netif;
  174. if(idx == 0)
  175. netif = wifi_sta.parent.parent.netif;
  176. else if(idx == 1)
  177. netif = wifi_ap.parent.parent.netif;
  178. return netif;
  179. }
  180. rt_err_t rt_ameba_wifi_init(rt_device_t dev)
  181. {
  182. return RT_EOK;
  183. }
  184. rt_err_t rt_ameba_wifi_open(rt_device_t dev, rt_uint16_t oflag)
  185. {
  186. return RT_EOK;
  187. }
  188. rt_err_t rt_ameba_wifi_close(rt_device_t dev)
  189. {
  190. return RT_EOK;
  191. }
  192. rt_size_t rt_ameba_wifi_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  193. {
  194. rt_set_errno(-RT_ENOSYS);
  195. return 0;
  196. }
  197. rt_size_t rt_ameba_wifi_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  198. {
  199. rt_set_errno(-RT_ENOSYS);
  200. return 0;
  201. }
  202. rt_err_t rt_ameba_wifi_control(rt_device_t dev, int cmd, void *args)
  203. {
  204. switch(cmd)
  205. {
  206. case NIOCTL_GADDR:
  207. {
  208. struct ameba_wifi *wifi = (struct ameba_wifi *)dev;
  209. if(args)
  210. memcpy(args, wifi->dev_addr, MAX_ADDR_LEN);
  211. else
  212. return -RT_ERROR;
  213. }
  214. break;
  215. case WIFI_INIT:
  216. {
  217. rt_wlan_mode_t mode = *(rt_wlan_mode_t *)args;
  218. rt_kprintf("mode:%d\n", mode);
  219. }
  220. break;
  221. case WIFI_SCAN:
  222. {
  223. struct rt_wlan_scan_result *dst = RT_NULL;
  224. dst = (struct rt_wlan_scan_result *)rt_malloc(sizeof(struct rt_wlan_scan_result));
  225. if(dst == RT_NULL)
  226. {
  227. rt_kprintf("rt_malloc for scan result failed!\n");
  228. return -RT_ENOMEM;
  229. }
  230. memset(dst, 0, sizeof(struct rt_wlan_scan_result));
  231. if(amebaz_wifi_scan(dst) != RT_EOK)
  232. {
  233. rt_kprintf("amebaz_wifi_scan failed...\n");
  234. return -RT_ERROR;
  235. }
  236. *(struct rt_wlan_scan_result **)args = dst;
  237. }
  238. break;
  239. case WIFI_JOIN:
  240. break;
  241. case WIFI_EASYJOIN:
  242. {
  243. struct rt_wlan_device *wlan = (struct rt_wlan_device *)dev;
  244. if(amebaz_wifi_connect(wlan->info->ssid, (char *)args) != RT_EOK)
  245. {
  246. rt_kprintf("amebaz_wifi_connect failed...\n");
  247. return -RT_ERROR;
  248. }
  249. }
  250. break;
  251. case WIFI_SOFTAP:
  252. {
  253. struct rt_wlan_device *wlan = (struct rt_wlan_device *)dev;
  254. if(amebaz_wifi_ap_start(wlan->info->ssid, (char *)args, wlan->info->channel) != RT_EOK)
  255. {
  256. rt_kprintf("amebaz_wifi_ap_start failed...\n");
  257. return -RT_ERROR;
  258. }
  259. }
  260. break;
  261. case WIFI_DISCONNECT:
  262. if(amebaz_wifi_disconnect() != RT_EOK)
  263. {
  264. rt_kprintf("amebaz_wifi_disconnect failed...\n");
  265. return -RT_ERROR;
  266. }
  267. break;
  268. case WIFI_GET_RSSI:
  269. {
  270. int *rssi = (int *)args;
  271. *rssi = amebaz_wifi_get_rssi();
  272. }
  273. break;
  274. case WIFI_ENTER_POWERSAVE:
  275. break;
  276. case WIFI_CFG_MONITOR:
  277. break;
  278. case WIFI_SET_CHANNEL:
  279. {
  280. int channel = *(int *)args;
  281. amebaz_wifi_set_channel(channel);
  282. }
  283. break;
  284. case WIFI_GET_CHANNEL:
  285. {
  286. int *channel = (int *)args;
  287. *channel = amebaz_wifi_get_channel();
  288. }
  289. break;
  290. case WIFI_SET_MONITOR_CALLBACK:
  291. break;
  292. }
  293. return RT_EOK;
  294. }
  295. rt_err_t rt_ameba_wifi_tx(rt_device_t dev, struct pbuf* p)
  296. {
  297. rt_err_t result = RT_EOK;
  298. struct ameba_wifi *wifi = (struct ameba_wifi *)dev;
  299. int idx;
  300. rt_base_t level;
  301. struct sk_buff *skb = RT_NULL;
  302. idx = wifi->idx;
  303. level = rt_hw_interrupt_disable();
  304. if(wifi->connected && rltk_wlan_check_isup(idx))
  305. rltk_wlan_tx_inc(idx);
  306. else
  307. {
  308. rt_hw_interrupt_enable(level);
  309. // rt_kprintf("is not: connected && rltk_wlan_check_isup(idx)\n");
  310. result = -RT_ERROR;
  311. goto _exit;
  312. }
  313. rt_hw_interrupt_enable(level);
  314. #ifdef ETH_TX_DUMP
  315. packet_dump("TX dump", p);
  316. #endif /* ETH_TX_DUMP */
  317. skb = rltk_wlan_alloc_skb(p->tot_len);
  318. if(skb != RT_NULL)
  319. {
  320. /* copy pbuf to a whole ETH frame */
  321. pbuf_copy_partial(p, skb->tail, p->tot_len, 0);
  322. skb_put(skb, p->tot_len);
  323. rltk_wlan_send_skb(idx, skb);
  324. }
  325. else
  326. {
  327. rt_kprintf("rltk_wlan_alloc_skb NULL for WIFI TX.\n");
  328. result = -RT_ENOMEM;
  329. }
  330. _exit:
  331. level = rt_hw_interrupt_disable();
  332. rltk_wlan_tx_dec(idx);
  333. rt_hw_interrupt_enable(level);
  334. return result;
  335. }
  336. int rt_hw_wifi_init(void)
  337. {
  338. rt_kprintf("%s %d\n", __FUNCTION__, __LINE__);
  339. #ifdef RT_USING_WLAN_STA
  340. wifi_sta.parent.parent.parent.init = rt_ameba_wifi_init;
  341. wifi_sta.parent.parent.parent.open = rt_ameba_wifi_open;
  342. wifi_sta.parent.parent.parent.close = rt_ameba_wifi_close;
  343. wifi_sta.parent.parent.parent.read = rt_ameba_wifi_read;
  344. wifi_sta.parent.parent.parent.write = rt_ameba_wifi_write;
  345. wifi_sta.parent.parent.parent.control = rt_ameba_wifi_control;
  346. wifi_sta.parent.parent.parent.user_data = RT_NULL;
  347. //
  348. wifi_sta.idx = 0;
  349. //
  350. wifi_sta.parent.parent.eth_rx = RT_NULL;
  351. wifi_sta.parent.parent.eth_tx = rt_ameba_wifi_tx;
  352. /* register wifi device */
  353. eth_device_init(&wifi_sta.parent.parent, WIFI_DEVICE_STA_NAME);
  354. #endif
  355. #ifdef RT_USING_WLAN_AP
  356. #endif
  357. return RT_EOK;
  358. }