p80211netdev.c 30 KB

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