p80211netdev.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093
  1. // SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1)
  2. /* src/p80211/p80211knetdev.c
  3. *
  4. * Linux Kernel net device interface
  5. *
  6. * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
  7. * --------------------------------------------------------------------
  8. *
  9. * linux-wlan
  10. *
  11. * The contents of this file are subject to the Mozilla Public
  12. * License Version 1.1 (the "License"); you may not use this file
  13. * except in compliance with the License. You may obtain a copy of
  14. * the License at http://www.mozilla.org/MPL/
  15. *
  16. * Software distributed under the License is distributed on an "AS
  17. * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  18. * implied. See the License for the specific language governing
  19. * rights and limitations under the License.
  20. *
  21. * Alternatively, the contents of this file may be used under the
  22. * terms of the GNU Public License version 2 (the "GPL"), in which
  23. * case the provisions of the GPL are applicable instead of the
  24. * above. If you wish to allow the use of your version of this file
  25. * only under the terms of the GPL and not to allow others to use
  26. * your version of this file under the MPL, indicate your decision
  27. * by deleting the provisions above and replace them with the notice
  28. * and other provisions required by the GPL. If you do not delete
  29. * the provisions above, a recipient may use your version of this
  30. * file under either the MPL or the GPL.
  31. *
  32. * --------------------------------------------------------------------
  33. *
  34. * Inquiries regarding the linux-wlan Open Source project can be
  35. * made directly to:
  36. *
  37. * AbsoluteValue Systems Inc.
  38. * info@linux-wlan.com
  39. * http://www.linux-wlan.com
  40. *
  41. * --------------------------------------------------------------------
  42. *
  43. * Portions of the development of this software were funded by
  44. * Intersil Corporation as part of PRISM(R) chipset product development.
  45. *
  46. * --------------------------------------------------------------------
  47. *
  48. * The functions required for a Linux network device are defined here.
  49. *
  50. * --------------------------------------------------------------------
  51. */
  52. #include <linux/module.h>
  53. #include <linux/kernel.h>
  54. #include <linux/sched.h>
  55. #include <linux/types.h>
  56. #include <linux/skbuff.h>
  57. #include <linux/slab.h>
  58. #include <linux/proc_fs.h>
  59. #include <linux/interrupt.h>
  60. #include <linux/netdevice.h>
  61. #include <linux/kmod.h>
  62. #include <linux/if_arp.h>
  63. #include <linux/wireless.h>
  64. #include <linux/sockios.h>
  65. #include <linux/etherdevice.h>
  66. #include <linux/if_ether.h>
  67. #include <linux/byteorder/generic.h>
  68. #include <linux/bitops.h>
  69. #include <linux/uaccess.h>
  70. #include <asm/byteorder.h>
  71. #ifdef SIOCETHTOOL
  72. #include <linux/ethtool.h>
  73. #endif
  74. #include <net/iw_handler.h>
  75. #include <net/net_namespace.h>
  76. #include <net/cfg80211.h>
  77. #include "p80211types.h"
  78. #include "p80211hdr.h"
  79. #include "p80211conv.h"
  80. #include "p80211mgmt.h"
  81. #include "p80211msg.h"
  82. #include "p80211netdev.h"
  83. #include "p80211ioctl.h"
  84. #include "p80211req.h"
  85. #include "p80211metastruct.h"
  86. #include "p80211metadef.h"
  87. #include "cfg80211.c"
  88. /* netdevice method functions */
  89. static int p80211knetdev_init(struct net_device *netdev);
  90. static int p80211knetdev_open(struct net_device *netdev);
  91. static int p80211knetdev_stop(struct net_device *netdev);
  92. static netdev_tx_t p80211knetdev_hard_start_xmit(struct sk_buff *skb,
  93. struct net_device *netdev);
  94. static void p80211knetdev_set_multicast_list(struct net_device *dev);
  95. static int p80211knetdev_do_ioctl(struct net_device *dev, struct ifreq *ifr,
  96. int cmd);
  97. static int p80211knetdev_set_mac_address(struct net_device *dev, void *addr);
  98. static void p80211knetdev_tx_timeout(struct net_device *netdev);
  99. static int p80211_rx_typedrop(struct wlandevice *wlandev, u16 fc);
  100. int wlan_watchdog = 5000;
  101. module_param(wlan_watchdog, int, 0644);
  102. MODULE_PARM_DESC(wlan_watchdog, "transmit timeout in milliseconds");
  103. int wlan_wext_write = 1;
  104. module_param(wlan_wext_write, int, 0644);
  105. MODULE_PARM_DESC(wlan_wext_write, "enable write wireless extensions");
  106. /*----------------------------------------------------------------
  107. * p80211knetdev_init
  108. *
  109. * Init method for a Linux netdevice. Called in response to
  110. * register_netdev.
  111. *
  112. * Arguments:
  113. * none
  114. *
  115. * Returns:
  116. * nothing
  117. *----------------------------------------------------------------
  118. */
  119. static int p80211knetdev_init(struct net_device *netdev)
  120. {
  121. /* Called in response to register_netdev */
  122. /* This is usually the probe function, but the probe has */
  123. /* already been done by the MSD and the create_kdev */
  124. /* function. All we do here is return success */
  125. return 0;
  126. }
  127. /*----------------------------------------------------------------
  128. * p80211knetdev_open
  129. *
  130. * Linux netdevice open method. Following a successful call here,
  131. * the device is supposed to be ready for tx and rx. In our
  132. * situation that may not be entirely true due to the state of the
  133. * MAC below.
  134. *
  135. * Arguments:
  136. * netdev Linux network device structure
  137. *
  138. * Returns:
  139. * zero on success, non-zero otherwise
  140. *----------------------------------------------------------------
  141. */
  142. static int p80211knetdev_open(struct net_device *netdev)
  143. {
  144. int result = 0; /* success */
  145. struct wlandevice *wlandev = netdev->ml_priv;
  146. /* Check to make sure the MSD is running */
  147. if (wlandev->msdstate != WLAN_MSD_RUNNING)
  148. return -ENODEV;
  149. /* Tell the MSD to open */
  150. if (wlandev->open) {
  151. result = wlandev->open(wlandev);
  152. if (result == 0) {
  153. netif_start_queue(wlandev->netdev);
  154. wlandev->state = WLAN_DEVICE_OPEN;
  155. }
  156. } else {
  157. result = -EAGAIN;
  158. }
  159. return result;
  160. }
  161. /*----------------------------------------------------------------
  162. * p80211knetdev_stop
  163. *
  164. * Linux netdevice stop (close) method. Following this call,
  165. * no frames should go up or down through this interface.
  166. *
  167. * Arguments:
  168. * netdev Linux network device structure
  169. *
  170. * Returns:
  171. * zero on success, non-zero otherwise
  172. *----------------------------------------------------------------
  173. */
  174. static int p80211knetdev_stop(struct net_device *netdev)
  175. {
  176. int result = 0;
  177. struct wlandevice *wlandev = netdev->ml_priv;
  178. if (wlandev->close)
  179. result = wlandev->close(wlandev);
  180. netif_stop_queue(wlandev->netdev);
  181. wlandev->state = WLAN_DEVICE_CLOSED;
  182. return result;
  183. }
  184. /*----------------------------------------------------------------
  185. * p80211netdev_rx
  186. *
  187. * Frame receive function called by the mac specific driver.
  188. *
  189. * Arguments:
  190. * wlandev WLAN network device structure
  191. * skb skbuff containing a full 802.11 frame.
  192. * Returns:
  193. * nothing
  194. * Side effects:
  195. *
  196. *----------------------------------------------------------------
  197. */
  198. void p80211netdev_rx(struct wlandevice *wlandev, struct sk_buff *skb)
  199. {
  200. /* Enqueue for post-irq processing */
  201. skb_queue_tail(&wlandev->nsd_rxq, skb);
  202. tasklet_schedule(&wlandev->rx_bh);
  203. }
  204. #define CONV_TO_ETHER_SKIPPED 0x01
  205. #define CONV_TO_ETHER_FAILED 0x02
  206. /**
  207. * p80211_convert_to_ether - conversion from 802.11 frame to ethernet frame
  208. * @wlandev: pointer to WLAN device
  209. * @skb: pointer to socket buffer
  210. *
  211. * Returns: 0 if conversion succeeded
  212. * CONV_TO_ETHER_FAILED if conversion failed
  213. * CONV_TO_ETHER_SKIPPED if frame is ignored
  214. */
  215. static int p80211_convert_to_ether(struct wlandevice *wlandev,
  216. struct sk_buff *skb)
  217. {
  218. struct p80211_hdr_a3 *hdr;
  219. hdr = (struct p80211_hdr_a3 *)skb->data;
  220. if (p80211_rx_typedrop(wlandev, le16_to_cpu(hdr->fc)))
  221. return CONV_TO_ETHER_SKIPPED;
  222. /* perform mcast filtering: allow my local address through but reject
  223. * anything else that isn't multicast
  224. */
  225. if (wlandev->netdev->flags & IFF_ALLMULTI) {
  226. if (!ether_addr_equal_unaligned(wlandev->netdev->dev_addr,
  227. hdr->a1)) {
  228. if (!is_multicast_ether_addr(hdr->a1))
  229. return CONV_TO_ETHER_SKIPPED;
  230. }
  231. }
  232. if (skb_p80211_to_ether(wlandev, wlandev->ethconv, skb) == 0) {
  233. wlandev->netdev->stats.rx_packets++;
  234. wlandev->netdev->stats.rx_bytes += skb->len;
  235. netif_rx_ni(skb);
  236. return 0;
  237. }
  238. netdev_dbg(wlandev->netdev, "%s failed.\n", __func__);
  239. return CONV_TO_ETHER_FAILED;
  240. }
  241. /**
  242. * p80211netdev_rx_bh - deferred processing of all received frames
  243. *
  244. * @arg: pointer to WLAN network device structure (cast to unsigned long)
  245. */
  246. static void p80211netdev_rx_bh(unsigned long arg)
  247. {
  248. struct wlandevice *wlandev = (struct wlandevice *)arg;
  249. struct sk_buff *skb = NULL;
  250. struct net_device *dev = wlandev->netdev;
  251. /* Let's empty our our queue */
  252. while ((skb = skb_dequeue(&wlandev->nsd_rxq))) {
  253. if (wlandev->state == WLAN_DEVICE_OPEN) {
  254. if (dev->type != ARPHRD_ETHER) {
  255. /* RAW frame; we shouldn't convert it */
  256. /* XXX Append the Prism Header here instead. */
  257. /* set up various data fields */
  258. skb->dev = dev;
  259. skb_reset_mac_header(skb);
  260. skb->ip_summed = CHECKSUM_NONE;
  261. skb->pkt_type = PACKET_OTHERHOST;
  262. skb->protocol = htons(ETH_P_80211_RAW);
  263. dev->stats.rx_packets++;
  264. dev->stats.rx_bytes += skb->len;
  265. netif_rx_ni(skb);
  266. continue;
  267. } else {
  268. if (!p80211_convert_to_ether(wlandev, skb))
  269. continue;
  270. }
  271. }
  272. dev_kfree_skb(skb);
  273. }
  274. }
  275. /*----------------------------------------------------------------
  276. * p80211knetdev_hard_start_xmit
  277. *
  278. * Linux netdevice method for transmitting a frame.
  279. *
  280. * Arguments:
  281. * skb Linux sk_buff containing the frame.
  282. * netdev Linux netdevice.
  283. *
  284. * Side effects:
  285. * If the lower layers report that buffers are full. netdev->tbusy
  286. * will be set to prevent higher layers from sending more traffic.
  287. *
  288. * Note: If this function returns non-zero, higher layers retain
  289. * ownership of the skb.
  290. *
  291. * Returns:
  292. * zero on success, non-zero on failure.
  293. *----------------------------------------------------------------
  294. */
  295. static netdev_tx_t p80211knetdev_hard_start_xmit(struct sk_buff *skb,
  296. struct net_device *netdev)
  297. {
  298. int result = 0;
  299. int txresult = -1;
  300. struct wlandevice *wlandev = netdev->ml_priv;
  301. union p80211_hdr p80211_hdr;
  302. struct p80211_metawep p80211_wep;
  303. p80211_wep.data = NULL;
  304. if (!skb)
  305. return NETDEV_TX_OK;
  306. if (wlandev->state != WLAN_DEVICE_OPEN) {
  307. result = 1;
  308. goto failed;
  309. }
  310. memset(&p80211_hdr, 0, sizeof(p80211_hdr));
  311. memset(&p80211_wep, 0, sizeof(p80211_wep));
  312. if (netif_queue_stopped(netdev)) {
  313. netdev_dbg(netdev, "called when queue stopped.\n");
  314. result = 1;
  315. goto failed;
  316. }
  317. netif_stop_queue(netdev);
  318. /* Check to see that a valid mode is set */
  319. switch (wlandev->macmode) {
  320. case WLAN_MACMODE_IBSS_STA:
  321. case WLAN_MACMODE_ESS_STA:
  322. case WLAN_MACMODE_ESS_AP:
  323. break;
  324. default:
  325. /* Mode isn't set yet, just drop the frame
  326. * and return success .
  327. * TODO: we need a saner way to handle this
  328. */
  329. if (be16_to_cpu(skb->protocol) != ETH_P_80211_RAW) {
  330. netif_start_queue(wlandev->netdev);
  331. netdev_notice(netdev, "Tx attempt prior to association, frame dropped.\n");
  332. netdev->stats.tx_dropped++;
  333. result = 0;
  334. goto failed;
  335. }
  336. break;
  337. }
  338. /* Check for raw transmits */
  339. if (be16_to_cpu(skb->protocol) == ETH_P_80211_RAW) {
  340. if (!capable(CAP_NET_ADMIN)) {
  341. result = 1;
  342. goto failed;
  343. }
  344. /* move the header over */
  345. memcpy(&p80211_hdr, skb->data, sizeof(p80211_hdr));
  346. skb_pull(skb, sizeof(p80211_hdr));
  347. } else {
  348. if (skb_ether_to_p80211
  349. (wlandev, wlandev->ethconv, skb, &p80211_hdr,
  350. &p80211_wep) != 0) {
  351. /* convert failed */
  352. netdev_dbg(netdev, "ether_to_80211(%d) failed.\n",
  353. wlandev->ethconv);
  354. result = 1;
  355. goto failed;
  356. }
  357. }
  358. if (!wlandev->txframe) {
  359. result = 1;
  360. goto failed;
  361. }
  362. netif_trans_update(netdev);
  363. netdev->stats.tx_packets++;
  364. /* count only the packet payload */
  365. netdev->stats.tx_bytes += skb->len;
  366. txresult = wlandev->txframe(wlandev, skb, &p80211_hdr, &p80211_wep);
  367. if (txresult == 0) {
  368. /* success and more buf */
  369. /* avail, re: hw_txdata */
  370. netif_wake_queue(wlandev->netdev);
  371. result = NETDEV_TX_OK;
  372. } else if (txresult == 1) {
  373. /* success, no more avail */
  374. netdev_dbg(netdev, "txframe success, no more bufs\n");
  375. /* netdev->tbusy = 1; don't set here, irqhdlr */
  376. /* may have already cleared it */
  377. result = NETDEV_TX_OK;
  378. } else if (txresult == 2) {
  379. /* alloc failure, drop frame */
  380. netdev_dbg(netdev, "txframe returned alloc_fail\n");
  381. result = NETDEV_TX_BUSY;
  382. } else {
  383. /* buffer full or queue busy, drop frame. */
  384. netdev_dbg(netdev, "txframe returned full or busy\n");
  385. result = NETDEV_TX_BUSY;
  386. }
  387. failed:
  388. /* Free up the WEP buffer if it's not the same as the skb */
  389. if ((p80211_wep.data) && (p80211_wep.data != skb->data))
  390. kzfree(p80211_wep.data);
  391. /* we always free the skb here, never in a lower level. */
  392. if (!result)
  393. dev_kfree_skb(skb);
  394. return result;
  395. }
  396. /*----------------------------------------------------------------
  397. * p80211knetdev_set_multicast_list
  398. *
  399. * Called from higher layers whenever there's a need to set/clear
  400. * promiscuous mode or rewrite the multicast list.
  401. *
  402. * Arguments:
  403. * none
  404. *
  405. * Returns:
  406. * nothing
  407. *----------------------------------------------------------------
  408. */
  409. static void p80211knetdev_set_multicast_list(struct net_device *dev)
  410. {
  411. struct wlandevice *wlandev = dev->ml_priv;
  412. /* TODO: real multicast support as well */
  413. if (wlandev->set_multicast_list)
  414. wlandev->set_multicast_list(wlandev, dev);
  415. }
  416. #ifdef SIOCETHTOOL
  417. static int p80211netdev_ethtool(struct wlandevice *wlandev,
  418. void __user *useraddr)
  419. {
  420. u32 ethcmd;
  421. struct ethtool_drvinfo info;
  422. struct ethtool_value edata;
  423. memset(&info, 0, sizeof(info));
  424. memset(&edata, 0, sizeof(edata));
  425. if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
  426. return -EFAULT;
  427. switch (ethcmd) {
  428. case ETHTOOL_GDRVINFO:
  429. info.cmd = ethcmd;
  430. snprintf(info.driver, sizeof(info.driver), "p80211_%s",
  431. wlandev->nsdname);
  432. snprintf(info.version, sizeof(info.version), "%s",
  433. WLAN_RELEASE);
  434. if (copy_to_user(useraddr, &info, sizeof(info)))
  435. return -EFAULT;
  436. return 0;
  437. #ifdef ETHTOOL_GLINK
  438. case ETHTOOL_GLINK:
  439. edata.cmd = ethcmd;
  440. if (wlandev->linkstatus &&
  441. (wlandev->macmode != WLAN_MACMODE_NONE)) {
  442. edata.data = 1;
  443. } else {
  444. edata.data = 0;
  445. }
  446. if (copy_to_user(useraddr, &edata, sizeof(edata)))
  447. return -EFAULT;
  448. return 0;
  449. #endif
  450. }
  451. return -EOPNOTSUPP;
  452. }
  453. #endif
  454. /*----------------------------------------------------------------
  455. * p80211knetdev_do_ioctl
  456. *
  457. * Handle an ioctl call on one of our devices. Everything Linux
  458. * ioctl specific is done here. Then we pass the contents of the
  459. * ifr->data to the request message handler.
  460. *
  461. * Arguments:
  462. * dev Linux kernel netdevice
  463. * ifr Our private ioctl request structure, typed for the
  464. * generic struct ifreq so we can use ptr to func
  465. * w/o cast.
  466. *
  467. * Returns:
  468. * zero on success, a negative errno on failure. Possible values:
  469. * -ENETDOWN Device isn't up.
  470. * -EBUSY cmd already in progress
  471. * -ETIME p80211 cmd timed out (MSD may have its own timers)
  472. * -EFAULT memory fault copying msg from user buffer
  473. * -ENOMEM unable to allocate kernel msg buffer
  474. * -EINVAL bad magic, it the cmd really for us?
  475. * -EintR sleeping on cmd, awakened by signal, cmd cancelled.
  476. *
  477. * Call Context:
  478. * Process thread (ioctl caller). TODO: SMP support may require
  479. * locks.
  480. *----------------------------------------------------------------
  481. */
  482. static int p80211knetdev_do_ioctl(struct net_device *dev,
  483. struct ifreq *ifr, int cmd)
  484. {
  485. int result = 0;
  486. struct p80211ioctl_req *req = (struct p80211ioctl_req *)ifr;
  487. struct wlandevice *wlandev = dev->ml_priv;
  488. u8 *msgbuf;
  489. netdev_dbg(dev, "rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len);
  490. #ifdef SIOCETHTOOL
  491. if (cmd == SIOCETHTOOL) {
  492. result =
  493. p80211netdev_ethtool(wlandev, (void __user *)ifr->ifr_data);
  494. goto bail;
  495. }
  496. #endif
  497. /* Test the magic, assume ifr is good if it's there */
  498. if (req->magic != P80211_IOCTL_MAGIC) {
  499. result = -EINVAL;
  500. goto bail;
  501. }
  502. if (cmd == P80211_IFTEST) {
  503. result = 0;
  504. goto bail;
  505. } else if (cmd != P80211_IFREQ) {
  506. result = -EINVAL;
  507. goto bail;
  508. }
  509. /* Allocate a buf of size req->len */
  510. msgbuf = kmalloc(req->len, GFP_KERNEL);
  511. if (msgbuf) {
  512. if (copy_from_user(msgbuf, (void __user *)req->data, req->len))
  513. result = -EFAULT;
  514. else
  515. result = p80211req_dorequest(wlandev, msgbuf);
  516. if (result == 0) {
  517. if (copy_to_user
  518. ((void __user *)req->data, msgbuf, req->len)) {
  519. result = -EFAULT;
  520. }
  521. }
  522. kfree(msgbuf);
  523. } else {
  524. result = -ENOMEM;
  525. }
  526. bail:
  527. /* If allocate,copyfrom or copyto fails, return errno */
  528. return result;
  529. }
  530. /*----------------------------------------------------------------
  531. * p80211knetdev_set_mac_address
  532. *
  533. * Handles the ioctl for changing the MACAddress of a netdevice
  534. *
  535. * references: linux/netdevice.h and drivers/net/net_init.c
  536. *
  537. * NOTE: [MSM] We only prevent address changes when the netdev is
  538. * up. We don't control anything based on dot11 state. If the
  539. * address is changed on a STA that's currently associated, you
  540. * will probably lose the ability to send and receive data frames.
  541. * Just be aware. Therefore, this should usually only be done
  542. * prior to scan/join/auth/assoc.
  543. *
  544. * Arguments:
  545. * dev netdevice struct
  546. * addr the new MACAddress (a struct)
  547. *
  548. * Returns:
  549. * zero on success, a negative errno on failure. Possible values:
  550. * -EBUSY device is bussy (cmd not possible)
  551. * -and errors returned by: p80211req_dorequest(..)
  552. *
  553. * by: Collin R. Mulliner <collin@mulliner.org>
  554. *----------------------------------------------------------------
  555. */
  556. static int p80211knetdev_set_mac_address(struct net_device *dev, void *addr)
  557. {
  558. struct sockaddr *new_addr = addr;
  559. struct p80211msg_dot11req_mibset dot11req;
  560. struct p80211item_unk392 *mibattr;
  561. struct p80211item_pstr6 *macaddr;
  562. struct p80211item_uint32 *resultcode;
  563. int result;
  564. /* If we're running, we don't allow MAC address changes */
  565. if (netif_running(dev))
  566. return -EBUSY;
  567. /* Set up some convenience pointers. */
  568. mibattr = &dot11req.mibattribute;
  569. macaddr = (struct p80211item_pstr6 *)&mibattr->data;
  570. resultcode = &dot11req.resultcode;
  571. /* Set up a dot11req_mibset */
  572. memset(&dot11req, 0, sizeof(dot11req));
  573. dot11req.msgcode = DIDmsg_dot11req_mibset;
  574. dot11req.msglen = sizeof(dot11req);
  575. memcpy(dot11req.devname,
  576. ((struct wlandevice *)dev->ml_priv)->name,
  577. WLAN_DEVNAMELEN_MAX - 1);
  578. /* Set up the mibattribute argument */
  579. mibattr->did = DIDmsg_dot11req_mibset_mibattribute;
  580. mibattr->status = P80211ENUM_msgitem_status_data_ok;
  581. mibattr->len = sizeof(mibattr->data);
  582. macaddr->did = DIDmib_dot11mac_dot11OperationTable_dot11MACAddress;
  583. macaddr->status = P80211ENUM_msgitem_status_data_ok;
  584. macaddr->len = sizeof(macaddr->data);
  585. macaddr->data.len = ETH_ALEN;
  586. memcpy(&macaddr->data.data, new_addr->sa_data, ETH_ALEN);
  587. /* Set up the resultcode argument */
  588. resultcode->did = DIDmsg_dot11req_mibset_resultcode;
  589. resultcode->status = P80211ENUM_msgitem_status_no_value;
  590. resultcode->len = sizeof(resultcode->data);
  591. resultcode->data = 0;
  592. /* now fire the request */
  593. result = p80211req_dorequest(dev->ml_priv, (u8 *)&dot11req);
  594. /* If the request wasn't successful, report an error and don't
  595. * change the netdev address
  596. */
  597. if (result != 0 || resultcode->data != P80211ENUM_resultcode_success) {
  598. netdev_err(dev, "Low-level driver failed dot11req_mibset(dot11MACAddress).\n");
  599. result = -EADDRNOTAVAIL;
  600. } else {
  601. /* everything's ok, change the addr in netdev */
  602. memcpy(dev->dev_addr, new_addr->sa_data, dev->addr_len);
  603. }
  604. return result;
  605. }
  606. static const struct net_device_ops p80211_netdev_ops = {
  607. .ndo_init = p80211knetdev_init,
  608. .ndo_open = p80211knetdev_open,
  609. .ndo_stop = p80211knetdev_stop,
  610. .ndo_start_xmit = p80211knetdev_hard_start_xmit,
  611. .ndo_set_rx_mode = p80211knetdev_set_multicast_list,
  612. .ndo_do_ioctl = p80211knetdev_do_ioctl,
  613. .ndo_set_mac_address = p80211knetdev_set_mac_address,
  614. .ndo_tx_timeout = p80211knetdev_tx_timeout,
  615. .ndo_validate_addr = eth_validate_addr,
  616. };
  617. /*----------------------------------------------------------------
  618. * wlan_setup
  619. *
  620. * Roughly matches the functionality of ether_setup. Here
  621. * we set up any members of the wlandevice structure that are common
  622. * to all devices. Additionally, we allocate a linux 'struct device'
  623. * and perform the same setup as ether_setup.
  624. *
  625. * Note: It's important that the caller have setup the wlandev->name
  626. * ptr prior to calling this function.
  627. *
  628. * Arguments:
  629. * wlandev ptr to the wlandev structure for the
  630. * interface.
  631. * physdev ptr to usb device
  632. * Returns:
  633. * zero on success, non-zero otherwise.
  634. * Call Context:
  635. * Should be process thread. We'll assume it might be
  636. * interrupt though. When we add support for statically
  637. * compiled drivers, this function will be called in the
  638. * context of the kernel startup code.
  639. *----------------------------------------------------------------
  640. */
  641. int wlan_setup(struct wlandevice *wlandev, struct device *physdev)
  642. {
  643. int result = 0;
  644. struct net_device *netdev;
  645. struct wiphy *wiphy;
  646. struct wireless_dev *wdev;
  647. /* Set up the wlandev */
  648. wlandev->state = WLAN_DEVICE_CLOSED;
  649. wlandev->ethconv = WLAN_ETHCONV_8021h;
  650. wlandev->macmode = WLAN_MACMODE_NONE;
  651. /* Set up the rx queue */
  652. skb_queue_head_init(&wlandev->nsd_rxq);
  653. tasklet_init(&wlandev->rx_bh,
  654. p80211netdev_rx_bh, (unsigned long)wlandev);
  655. /* Allocate and initialize the wiphy struct */
  656. wiphy = wlan_create_wiphy(physdev, wlandev);
  657. if (!wiphy) {
  658. dev_err(physdev, "Failed to alloc wiphy.\n");
  659. return 1;
  660. }
  661. /* Allocate and initialize the struct device */
  662. netdev = alloc_netdev(sizeof(struct wireless_dev), "wlan%d",
  663. NET_NAME_UNKNOWN, ether_setup);
  664. if (!netdev) {
  665. dev_err(physdev, "Failed to alloc netdev.\n");
  666. wlan_free_wiphy(wiphy);
  667. result = 1;
  668. } else {
  669. wlandev->netdev = netdev;
  670. netdev->ml_priv = wlandev;
  671. netdev->netdev_ops = &p80211_netdev_ops;
  672. wdev = netdev_priv(netdev);
  673. wdev->wiphy = wiphy;
  674. wdev->iftype = NL80211_IFTYPE_STATION;
  675. netdev->ieee80211_ptr = wdev;
  676. netdev->min_mtu = 68;
  677. /* 2312 is max 802.11 payload, 20 is overhead,
  678. * (ether + llc + snap) and another 8 for wep.
  679. */
  680. netdev->max_mtu = (2312 - 20 - 8);
  681. netif_stop_queue(netdev);
  682. netif_carrier_off(netdev);
  683. }
  684. return result;
  685. }
  686. /*----------------------------------------------------------------
  687. * wlan_unsetup
  688. *
  689. * This function is paired with the wlan_setup routine. It should
  690. * be called after unregister_wlandev. Basically, all it does is
  691. * free the 'struct device' that's associated with the wlandev.
  692. * We do it here because the 'struct device' isn't allocated
  693. * explicitly in the driver code, it's done in wlan_setup. To
  694. * do the free in the driver might seem like 'magic'.
  695. *
  696. * Arguments:
  697. * wlandev ptr to the wlandev structure for the
  698. * interface.
  699. * Call Context:
  700. * Should be process thread. We'll assume it might be
  701. * interrupt though. When we add support for statically
  702. * compiled drivers, this function will be called in the
  703. * context of the kernel startup code.
  704. *----------------------------------------------------------------
  705. */
  706. void wlan_unsetup(struct wlandevice *wlandev)
  707. {
  708. struct wireless_dev *wdev;
  709. tasklet_kill(&wlandev->rx_bh);
  710. if (wlandev->netdev) {
  711. wdev = netdev_priv(wlandev->netdev);
  712. if (wdev->wiphy)
  713. wlan_free_wiphy(wdev->wiphy);
  714. free_netdev(wlandev->netdev);
  715. wlandev->netdev = NULL;
  716. }
  717. }
  718. /*----------------------------------------------------------------
  719. * register_wlandev
  720. *
  721. * Roughly matches the functionality of register_netdev. This function
  722. * is called after the driver has successfully probed and set up the
  723. * resources for the device. It's now ready to become a named device
  724. * in the Linux system.
  725. *
  726. * First we allocate a name for the device (if not already set), then
  727. * we call the Linux function register_netdevice.
  728. *
  729. * Arguments:
  730. * wlandev ptr to the wlandev structure for the
  731. * interface.
  732. * Returns:
  733. * zero on success, non-zero otherwise.
  734. * Call Context:
  735. * Can be either interrupt or not.
  736. *----------------------------------------------------------------
  737. */
  738. int register_wlandev(struct wlandevice *wlandev)
  739. {
  740. return register_netdev(wlandev->netdev);
  741. }
  742. /*----------------------------------------------------------------
  743. * unregister_wlandev
  744. *
  745. * Roughly matches the functionality of unregister_netdev. This
  746. * function is called to remove a named device from the system.
  747. *
  748. * First we tell linux that the device should no longer exist.
  749. * Then we remove it from the list of known wlan devices.
  750. *
  751. * Arguments:
  752. * wlandev ptr to the wlandev structure for the
  753. * interface.
  754. * Returns:
  755. * zero on success, non-zero otherwise.
  756. * Call Context:
  757. * Can be either interrupt or not.
  758. *----------------------------------------------------------------
  759. */
  760. int unregister_wlandev(struct wlandevice *wlandev)
  761. {
  762. struct sk_buff *skb;
  763. unregister_netdev(wlandev->netdev);
  764. /* Now to clean out the rx queue */
  765. while ((skb = skb_dequeue(&wlandev->nsd_rxq)))
  766. dev_kfree_skb(skb);
  767. return 0;
  768. }
  769. /*----------------------------------------------------------------
  770. * p80211netdev_hwremoved
  771. *
  772. * Hardware removed notification. This function should be called
  773. * immediately after an MSD has detected that the underlying hardware
  774. * has been yanked out from under us. The primary things we need
  775. * to do are:
  776. * - Mark the wlandev
  777. * - Prevent any further traffic from the knetdev i/f
  778. * - Prevent any further requests from mgmt i/f
  779. * - If there are any waitq'd mgmt requests or mgmt-frame exchanges,
  780. * shut them down.
  781. * - Call the MSD hwremoved function.
  782. *
  783. * The remainder of the cleanup will be handled by unregister().
  784. * Our primary goal here is to prevent as much tickling of the MSD
  785. * as possible since the MSD is already in a 'wounded' state.
  786. *
  787. * TODO: As new features are added, this function should be
  788. * updated.
  789. *
  790. * Arguments:
  791. * wlandev WLAN network device structure
  792. * Returns:
  793. * nothing
  794. * Side effects:
  795. *
  796. * Call context:
  797. * Usually interrupt.
  798. *----------------------------------------------------------------
  799. */
  800. void p80211netdev_hwremoved(struct wlandevice *wlandev)
  801. {
  802. wlandev->hwremoved = 1;
  803. if (wlandev->state == WLAN_DEVICE_OPEN)
  804. netif_stop_queue(wlandev->netdev);
  805. netif_device_detach(wlandev->netdev);
  806. }
  807. /*----------------------------------------------------------------
  808. * p80211_rx_typedrop
  809. *
  810. * Classifies the frame, increments the appropriate counter, and
  811. * returns 0|1|2 indicating whether the driver should handle, ignore, or
  812. * drop the frame
  813. *
  814. * Arguments:
  815. * wlandev wlan device structure
  816. * fc frame control field
  817. *
  818. * Returns:
  819. * zero if the frame should be handled by the driver,
  820. * one if the frame should be ignored
  821. * anything else means we drop it.
  822. *
  823. * Side effects:
  824. *
  825. * Call context:
  826. * interrupt
  827. *----------------------------------------------------------------
  828. */
  829. static int p80211_rx_typedrop(struct wlandevice *wlandev, u16 fc)
  830. {
  831. u16 ftype;
  832. u16 fstype;
  833. int drop = 0;
  834. /* Classify frame, increment counter */
  835. ftype = WLAN_GET_FC_FTYPE(fc);
  836. fstype = WLAN_GET_FC_FSTYPE(fc);
  837. #if 0
  838. netdev_dbg(wlandev->netdev, "rx_typedrop : ftype=%d fstype=%d.\n",
  839. ftype, fstype);
  840. #endif
  841. switch (ftype) {
  842. case WLAN_FTYPE_MGMT:
  843. if ((wlandev->netdev->flags & IFF_PROMISC) ||
  844. (wlandev->netdev->flags & IFF_ALLMULTI)) {
  845. drop = 1;
  846. break;
  847. }
  848. netdev_dbg(wlandev->netdev, "rx'd mgmt:\n");
  849. wlandev->rx.mgmt++;
  850. switch (fstype) {
  851. case WLAN_FSTYPE_ASSOCREQ:
  852. /* printk("assocreq"); */
  853. wlandev->rx.assocreq++;
  854. break;
  855. case WLAN_FSTYPE_ASSOCRESP:
  856. /* printk("assocresp"); */
  857. wlandev->rx.assocresp++;
  858. break;
  859. case WLAN_FSTYPE_REASSOCREQ:
  860. /* printk("reassocreq"); */
  861. wlandev->rx.reassocreq++;
  862. break;
  863. case WLAN_FSTYPE_REASSOCRESP:
  864. /* printk("reassocresp"); */
  865. wlandev->rx.reassocresp++;
  866. break;
  867. case WLAN_FSTYPE_PROBEREQ:
  868. /* printk("probereq"); */
  869. wlandev->rx.probereq++;
  870. break;
  871. case WLAN_FSTYPE_PROBERESP:
  872. /* printk("proberesp"); */
  873. wlandev->rx.proberesp++;
  874. break;
  875. case WLAN_FSTYPE_BEACON:
  876. /* printk("beacon"); */
  877. wlandev->rx.beacon++;
  878. break;
  879. case WLAN_FSTYPE_ATIM:
  880. /* printk("atim"); */
  881. wlandev->rx.atim++;
  882. break;
  883. case WLAN_FSTYPE_DISASSOC:
  884. /* printk("disassoc"); */
  885. wlandev->rx.disassoc++;
  886. break;
  887. case WLAN_FSTYPE_AUTHEN:
  888. /* printk("authen"); */
  889. wlandev->rx.authen++;
  890. break;
  891. case WLAN_FSTYPE_DEAUTHEN:
  892. /* printk("deauthen"); */
  893. wlandev->rx.deauthen++;
  894. break;
  895. default:
  896. /* printk("unknown"); */
  897. wlandev->rx.mgmt_unknown++;
  898. break;
  899. }
  900. /* printk("\n"); */
  901. drop = 2;
  902. break;
  903. case WLAN_FTYPE_CTL:
  904. if ((wlandev->netdev->flags & IFF_PROMISC) ||
  905. (wlandev->netdev->flags & IFF_ALLMULTI)) {
  906. drop = 1;
  907. break;
  908. }
  909. netdev_dbg(wlandev->netdev, "rx'd ctl:\n");
  910. wlandev->rx.ctl++;
  911. switch (fstype) {
  912. case WLAN_FSTYPE_PSPOLL:
  913. /* printk("pspoll"); */
  914. wlandev->rx.pspoll++;
  915. break;
  916. case WLAN_FSTYPE_RTS:
  917. /* printk("rts"); */
  918. wlandev->rx.rts++;
  919. break;
  920. case WLAN_FSTYPE_CTS:
  921. /* printk("cts"); */
  922. wlandev->rx.cts++;
  923. break;
  924. case WLAN_FSTYPE_ACK:
  925. /* printk("ack"); */
  926. wlandev->rx.ack++;
  927. break;
  928. case WLAN_FSTYPE_CFEND:
  929. /* printk("cfend"); */
  930. wlandev->rx.cfend++;
  931. break;
  932. case WLAN_FSTYPE_CFENDCFACK:
  933. /* printk("cfendcfack"); */
  934. wlandev->rx.cfendcfack++;
  935. break;
  936. default:
  937. /* printk("unknown"); */
  938. wlandev->rx.ctl_unknown++;
  939. break;
  940. }
  941. /* printk("\n"); */
  942. drop = 2;
  943. break;
  944. case WLAN_FTYPE_DATA:
  945. wlandev->rx.data++;
  946. switch (fstype) {
  947. case WLAN_FSTYPE_DATAONLY:
  948. wlandev->rx.dataonly++;
  949. break;
  950. case WLAN_FSTYPE_DATA_CFACK:
  951. wlandev->rx.data_cfack++;
  952. break;
  953. case WLAN_FSTYPE_DATA_CFPOLL:
  954. wlandev->rx.data_cfpoll++;
  955. break;
  956. case WLAN_FSTYPE_DATA_CFACK_CFPOLL:
  957. wlandev->rx.data__cfack_cfpoll++;
  958. break;
  959. case WLAN_FSTYPE_NULL:
  960. netdev_dbg(wlandev->netdev, "rx'd data:null\n");
  961. wlandev->rx.null++;
  962. break;
  963. case WLAN_FSTYPE_CFACK:
  964. netdev_dbg(wlandev->netdev, "rx'd data:cfack\n");
  965. wlandev->rx.cfack++;
  966. break;
  967. case WLAN_FSTYPE_CFPOLL:
  968. netdev_dbg(wlandev->netdev, "rx'd data:cfpoll\n");
  969. wlandev->rx.cfpoll++;
  970. break;
  971. case WLAN_FSTYPE_CFACK_CFPOLL:
  972. netdev_dbg(wlandev->netdev, "rx'd data:cfack_cfpoll\n");
  973. wlandev->rx.cfack_cfpoll++;
  974. break;
  975. default:
  976. /* printk("unknown"); */
  977. wlandev->rx.data_unknown++;
  978. break;
  979. }
  980. break;
  981. }
  982. return drop;
  983. }
  984. static void p80211knetdev_tx_timeout(struct net_device *netdev)
  985. {
  986. struct wlandevice *wlandev = netdev->ml_priv;
  987. if (wlandev->tx_timeout) {
  988. wlandev->tx_timeout(wlandev);
  989. } else {
  990. netdev_warn(netdev, "Implement tx_timeout for %s\n",
  991. wlandev->nsdname);
  992. netif_wake_queue(wlandev->netdev);
  993. }
  994. }