rt2x00usb.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. /*
  2. Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
  3. <http://rt2x00.serialmonkey.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the
  14. Free Software Foundation, Inc.,
  15. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  16. */
  17. /*
  18. Module: rt2x00usb
  19. Abstract: rt2x00 generic usb device routines.
  20. */
  21. #include <linux/kernel.h>
  22. #include <linux/module.h>
  23. #include <linux/usb.h>
  24. #include <linux/bug.h>
  25. #include "rt2x00.h"
  26. #include "rt2x00usb.h"
  27. /*
  28. * Interfacing with the HW.
  29. */
  30. int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev,
  31. const u8 request, const u8 requesttype,
  32. const u16 offset, const u16 value,
  33. void *buffer, const u16 buffer_length,
  34. const int timeout)
  35. {
  36. struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
  37. int status;
  38. unsigned int i;
  39. unsigned int pipe =
  40. (requesttype == USB_VENDOR_REQUEST_IN) ?
  41. usb_rcvctrlpipe(usb_dev, 0) : usb_sndctrlpipe(usb_dev, 0);
  42. for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
  43. status = usb_control_msg(usb_dev, pipe, request, requesttype,
  44. value, offset, buffer, buffer_length,
  45. timeout);
  46. if (status >= 0)
  47. return 0;
  48. /*
  49. * Check for errors
  50. * -ENODEV: Device has disappeared, no point continuing.
  51. * All other errors: Try again.
  52. */
  53. else if (status == -ENODEV)
  54. break;
  55. }
  56. ERROR(rt2x00dev,
  57. "Vendor Request 0x%02x failed for offset 0x%04x with error %d.\n",
  58. request, offset, status);
  59. return status;
  60. }
  61. EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request);
  62. int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev,
  63. const u8 request, const u8 requesttype,
  64. const u16 offset, void *buffer,
  65. const u16 buffer_length, const int timeout)
  66. {
  67. int status;
  68. BUG_ON(!mutex_is_locked(&rt2x00dev->usb_cache_mutex));
  69. /*
  70. * Check for Cache availability.
  71. */
  72. if (unlikely(!rt2x00dev->csr.cache || buffer_length > CSR_CACHE_SIZE)) {
  73. ERROR(rt2x00dev, "CSR cache not available.\n");
  74. return -ENOMEM;
  75. }
  76. if (requesttype == USB_VENDOR_REQUEST_OUT)
  77. memcpy(rt2x00dev->csr.cache, buffer, buffer_length);
  78. status = rt2x00usb_vendor_request(rt2x00dev, request, requesttype,
  79. offset, 0, rt2x00dev->csr.cache,
  80. buffer_length, timeout);
  81. if (!status && requesttype == USB_VENDOR_REQUEST_IN)
  82. memcpy(buffer, rt2x00dev->csr.cache, buffer_length);
  83. return status;
  84. }
  85. EXPORT_SYMBOL_GPL(rt2x00usb_vendor_req_buff_lock);
  86. int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev,
  87. const u8 request, const u8 requesttype,
  88. const u16 offset, void *buffer,
  89. const u16 buffer_length, const int timeout)
  90. {
  91. int status;
  92. mutex_lock(&rt2x00dev->usb_cache_mutex);
  93. status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request,
  94. requesttype, offset, buffer,
  95. buffer_length, timeout);
  96. mutex_unlock(&rt2x00dev->usb_cache_mutex);
  97. return status;
  98. }
  99. EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff);
  100. int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
  101. const u8 request, const u8 requesttype,
  102. const u16 offset, const void *buffer,
  103. const u16 buffer_length,
  104. const int timeout)
  105. {
  106. int status = 0;
  107. unsigned char *tb;
  108. u16 off, len, bsize;
  109. mutex_lock(&rt2x00dev->usb_cache_mutex);
  110. tb = (char *)buffer;
  111. off = offset;
  112. len = buffer_length;
  113. while (len && !status) {
  114. bsize = min_t(u16, CSR_CACHE_SIZE, len);
  115. status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request,
  116. requesttype, off, tb,
  117. bsize, timeout);
  118. tb += bsize;
  119. len -= bsize;
  120. off += bsize;
  121. }
  122. mutex_unlock(&rt2x00dev->usb_cache_mutex);
  123. return status;
  124. }
  125. EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_large_buff);
  126. /*
  127. * TX data handlers.
  128. */
  129. static void rt2x00usb_interrupt_txdone(struct urb *urb)
  130. {
  131. struct queue_entry *entry = (struct queue_entry *)urb->context;
  132. struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
  133. struct txdone_entry_desc txdesc;
  134. if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
  135. !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
  136. return;
  137. /*
  138. * Remove the descriptor data from the buffer.
  139. */
  140. skb_pull(entry->skb, entry->queue->desc_size);
  141. /*
  142. * Obtain the status about this packet.
  143. * Note that when the status is 0 it does not mean the
  144. * frame was send out correctly. It only means the frame
  145. * was succesfully pushed to the hardware, we have no
  146. * way to determine the transmission status right now.
  147. * (Only indirectly by looking at the failed TX counters
  148. * in the register).
  149. */
  150. if (!urb->status)
  151. __set_bit(TXDONE_UNKNOWN, &txdesc.flags);
  152. else
  153. __set_bit(TXDONE_FAILURE, &txdesc.flags);
  154. txdesc.retry = 0;
  155. rt2x00lib_txdone(entry, &txdesc);
  156. }
  157. int rt2x00usb_write_tx_data(struct queue_entry *entry)
  158. {
  159. struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
  160. struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
  161. struct queue_entry_priv_usb *entry_priv = entry->priv_data;
  162. struct skb_frame_desc *skbdesc;
  163. u32 length;
  164. /*
  165. * Add the descriptor in front of the skb.
  166. */
  167. skb_push(entry->skb, entry->queue->desc_size);
  168. memset(entry->skb->data, 0, entry->queue->desc_size);
  169. /*
  170. * Fill in skb descriptor
  171. */
  172. skbdesc = get_skb_frame_desc(entry->skb);
  173. skbdesc->desc = entry->skb->data;
  174. skbdesc->desc_len = entry->queue->desc_size;
  175. /*
  176. * USB devices cannot blindly pass the skb->len as the
  177. * length of the data to usb_fill_bulk_urb. Pass the skb
  178. * to the driver to determine what the length should be.
  179. */
  180. length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, entry->skb);
  181. usb_fill_bulk_urb(entry_priv->urb, usb_dev,
  182. usb_sndbulkpipe(usb_dev, 1),
  183. entry->skb->data, length,
  184. rt2x00usb_interrupt_txdone, entry);
  185. return 0;
  186. }
  187. EXPORT_SYMBOL_GPL(rt2x00usb_write_tx_data);
  188. static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
  189. {
  190. struct queue_entry_priv_usb *entry_priv = entry->priv_data;
  191. if (__test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags))
  192. usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
  193. }
  194. void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
  195. const enum data_queue_qid qid)
  196. {
  197. struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid);
  198. unsigned long irqflags;
  199. unsigned int index;
  200. unsigned int index_done;
  201. unsigned int i;
  202. /*
  203. * Only protect the range we are going to loop over,
  204. * if during our loop a extra entry is set to pending
  205. * it should not be kicked during this run, since it
  206. * is part of another TX operation.
  207. */
  208. spin_lock_irqsave(&queue->lock, irqflags);
  209. index = queue->index[Q_INDEX];
  210. index_done = queue->index[Q_INDEX_DONE];
  211. spin_unlock_irqrestore(&queue->lock, irqflags);
  212. /*
  213. * Start from the TX done pointer, this guarentees that we will
  214. * send out all frames in the correct order.
  215. */
  216. if (index_done < index) {
  217. for (i = index_done; i < index; i++)
  218. rt2x00usb_kick_tx_entry(&queue->entries[i]);
  219. } else {
  220. for (i = index_done; i < queue->limit; i++)
  221. rt2x00usb_kick_tx_entry(&queue->entries[i]);
  222. for (i = 0; i < index; i++)
  223. rt2x00usb_kick_tx_entry(&queue->entries[i]);
  224. }
  225. }
  226. EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue);
  227. /*
  228. * RX data handlers.
  229. */
  230. static void rt2x00usb_interrupt_rxdone(struct urb *urb)
  231. {
  232. struct queue_entry *entry = (struct queue_entry *)urb->context;
  233. struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
  234. struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
  235. u8 rxd[32];
  236. if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
  237. !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
  238. return;
  239. /*
  240. * Check if the received data is simply too small
  241. * to be actually valid, or if the urb is signaling
  242. * a problem.
  243. */
  244. if (urb->actual_length < entry->queue->desc_size || urb->status) {
  245. __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
  246. usb_submit_urb(urb, GFP_ATOMIC);
  247. return;
  248. }
  249. /*
  250. * Fill in desc fields of the skb descriptor
  251. */
  252. skbdesc->desc = rxd;
  253. skbdesc->desc_len = entry->queue->desc_size;
  254. /*
  255. * Send the frame to rt2x00lib for further processing.
  256. */
  257. rt2x00lib_rxdone(rt2x00dev, entry);
  258. }
  259. /*
  260. * Radio handlers
  261. */
  262. void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
  263. {
  264. struct queue_entry_priv_usb *entry_priv;
  265. struct queue_entry_priv_usb_bcn *bcn_priv;
  266. struct data_queue *queue;
  267. unsigned int i;
  268. rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0,
  269. REGISTER_TIMEOUT);
  270. /*
  271. * Cancel all queues.
  272. */
  273. queue_for_each(rt2x00dev, queue) {
  274. for (i = 0; i < queue->limit; i++) {
  275. entry_priv = queue->entries[i].priv_data;
  276. usb_kill_urb(entry_priv->urb);
  277. }
  278. }
  279. /*
  280. * Kill guardian urb (if required by driver).
  281. */
  282. if (!test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
  283. return;
  284. for (i = 0; i < rt2x00dev->bcn->limit; i++) {
  285. bcn_priv = rt2x00dev->bcn->entries[i].priv_data;
  286. if (bcn_priv->guardian_urb)
  287. usb_kill_urb(bcn_priv->guardian_urb);
  288. }
  289. }
  290. EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
  291. /*
  292. * Device initialization handlers.
  293. */
  294. void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev,
  295. struct queue_entry *entry)
  296. {
  297. struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
  298. struct queue_entry_priv_usb *entry_priv = entry->priv_data;
  299. usb_fill_bulk_urb(entry_priv->urb, usb_dev,
  300. usb_rcvbulkpipe(usb_dev, 1),
  301. entry->skb->data, entry->skb->len,
  302. rt2x00usb_interrupt_rxdone, entry);
  303. __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
  304. usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
  305. }
  306. EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry);
  307. void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev,
  308. struct queue_entry *entry)
  309. {
  310. entry->flags = 0;
  311. }
  312. EXPORT_SYMBOL_GPL(rt2x00usb_init_txentry);
  313. static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
  314. struct data_queue *queue)
  315. {
  316. struct queue_entry_priv_usb *entry_priv;
  317. struct queue_entry_priv_usb_bcn *bcn_priv;
  318. unsigned int i;
  319. for (i = 0; i < queue->limit; i++) {
  320. entry_priv = queue->entries[i].priv_data;
  321. entry_priv->urb = usb_alloc_urb(0, GFP_KERNEL);
  322. if (!entry_priv->urb)
  323. return -ENOMEM;
  324. }
  325. /*
  326. * If this is not the beacon queue or
  327. * no guardian byte was required for the beacon,
  328. * then we are done.
  329. */
  330. if (rt2x00dev->bcn != queue ||
  331. !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
  332. return 0;
  333. for (i = 0; i < queue->limit; i++) {
  334. bcn_priv = queue->entries[i].priv_data;
  335. bcn_priv->guardian_urb = usb_alloc_urb(0, GFP_KERNEL);
  336. if (!bcn_priv->guardian_urb)
  337. return -ENOMEM;
  338. }
  339. return 0;
  340. }
  341. static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev,
  342. struct data_queue *queue)
  343. {
  344. struct queue_entry_priv_usb *entry_priv;
  345. struct queue_entry_priv_usb_bcn *bcn_priv;
  346. unsigned int i;
  347. if (!queue->entries)
  348. return;
  349. for (i = 0; i < queue->limit; i++) {
  350. entry_priv = queue->entries[i].priv_data;
  351. usb_kill_urb(entry_priv->urb);
  352. usb_free_urb(entry_priv->urb);
  353. }
  354. /*
  355. * If this is not the beacon queue or
  356. * no guardian byte was required for the beacon,
  357. * then we are done.
  358. */
  359. if (rt2x00dev->bcn != queue ||
  360. !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
  361. return;
  362. for (i = 0; i < queue->limit; i++) {
  363. bcn_priv = queue->entries[i].priv_data;
  364. usb_kill_urb(bcn_priv->guardian_urb);
  365. usb_free_urb(bcn_priv->guardian_urb);
  366. }
  367. }
  368. int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
  369. {
  370. struct data_queue *queue;
  371. int status;
  372. /*
  373. * Allocate DMA
  374. */
  375. queue_for_each(rt2x00dev, queue) {
  376. status = rt2x00usb_alloc_urb(rt2x00dev, queue);
  377. if (status)
  378. goto exit;
  379. }
  380. return 0;
  381. exit:
  382. rt2x00usb_uninitialize(rt2x00dev);
  383. return status;
  384. }
  385. EXPORT_SYMBOL_GPL(rt2x00usb_initialize);
  386. void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev)
  387. {
  388. struct data_queue *queue;
  389. queue_for_each(rt2x00dev, queue)
  390. rt2x00usb_free_urb(rt2x00dev, queue);
  391. }
  392. EXPORT_SYMBOL_GPL(rt2x00usb_uninitialize);
  393. /*
  394. * USB driver handlers.
  395. */
  396. static void rt2x00usb_free_reg(struct rt2x00_dev *rt2x00dev)
  397. {
  398. kfree(rt2x00dev->rf);
  399. rt2x00dev->rf = NULL;
  400. kfree(rt2x00dev->eeprom);
  401. rt2x00dev->eeprom = NULL;
  402. kfree(rt2x00dev->csr.cache);
  403. rt2x00dev->csr.cache = NULL;
  404. }
  405. static int rt2x00usb_alloc_reg(struct rt2x00_dev *rt2x00dev)
  406. {
  407. rt2x00dev->csr.cache = kzalloc(CSR_CACHE_SIZE, GFP_KERNEL);
  408. if (!rt2x00dev->csr.cache)
  409. goto exit;
  410. rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL);
  411. if (!rt2x00dev->eeprom)
  412. goto exit;
  413. rt2x00dev->rf = kzalloc(rt2x00dev->ops->rf_size, GFP_KERNEL);
  414. if (!rt2x00dev->rf)
  415. goto exit;
  416. return 0;
  417. exit:
  418. ERROR_PROBE("Failed to allocate registers.\n");
  419. rt2x00usb_free_reg(rt2x00dev);
  420. return -ENOMEM;
  421. }
  422. int rt2x00usb_probe(struct usb_interface *usb_intf,
  423. const struct usb_device_id *id)
  424. {
  425. struct usb_device *usb_dev = interface_to_usbdev(usb_intf);
  426. struct rt2x00_ops *ops = (struct rt2x00_ops *)id->driver_info;
  427. struct ieee80211_hw *hw;
  428. struct rt2x00_dev *rt2x00dev;
  429. int retval;
  430. usb_dev = usb_get_dev(usb_dev);
  431. hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw);
  432. if (!hw) {
  433. ERROR_PROBE("Failed to allocate hardware.\n");
  434. retval = -ENOMEM;
  435. goto exit_put_device;
  436. }
  437. usb_set_intfdata(usb_intf, hw);
  438. rt2x00dev = hw->priv;
  439. rt2x00dev->dev = &usb_intf->dev;
  440. rt2x00dev->ops = ops;
  441. rt2x00dev->hw = hw;
  442. mutex_init(&rt2x00dev->usb_cache_mutex);
  443. rt2x00dev->usb_maxpacket =
  444. usb_maxpacket(usb_dev, usb_sndbulkpipe(usb_dev, 1), 1);
  445. if (!rt2x00dev->usb_maxpacket)
  446. rt2x00dev->usb_maxpacket = 1;
  447. retval = rt2x00usb_alloc_reg(rt2x00dev);
  448. if (retval)
  449. goto exit_free_device;
  450. retval = rt2x00lib_probe_dev(rt2x00dev);
  451. if (retval)
  452. goto exit_free_reg;
  453. return 0;
  454. exit_free_reg:
  455. rt2x00usb_free_reg(rt2x00dev);
  456. exit_free_device:
  457. ieee80211_free_hw(hw);
  458. exit_put_device:
  459. usb_put_dev(usb_dev);
  460. usb_set_intfdata(usb_intf, NULL);
  461. return retval;
  462. }
  463. EXPORT_SYMBOL_GPL(rt2x00usb_probe);
  464. void rt2x00usb_disconnect(struct usb_interface *usb_intf)
  465. {
  466. struct ieee80211_hw *hw = usb_get_intfdata(usb_intf);
  467. struct rt2x00_dev *rt2x00dev = hw->priv;
  468. /*
  469. * Free all allocated data.
  470. */
  471. rt2x00lib_remove_dev(rt2x00dev);
  472. rt2x00usb_free_reg(rt2x00dev);
  473. ieee80211_free_hw(hw);
  474. /*
  475. * Free the USB device data.
  476. */
  477. usb_set_intfdata(usb_intf, NULL);
  478. usb_put_dev(interface_to_usbdev(usb_intf));
  479. }
  480. EXPORT_SYMBOL_GPL(rt2x00usb_disconnect);
  481. #ifdef CONFIG_PM
  482. int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state)
  483. {
  484. struct ieee80211_hw *hw = usb_get_intfdata(usb_intf);
  485. struct rt2x00_dev *rt2x00dev = hw->priv;
  486. int retval;
  487. retval = rt2x00lib_suspend(rt2x00dev, state);
  488. if (retval)
  489. return retval;
  490. rt2x00usb_free_reg(rt2x00dev);
  491. /*
  492. * Decrease usbdev refcount.
  493. */
  494. usb_put_dev(interface_to_usbdev(usb_intf));
  495. return 0;
  496. }
  497. EXPORT_SYMBOL_GPL(rt2x00usb_suspend);
  498. int rt2x00usb_resume(struct usb_interface *usb_intf)
  499. {
  500. struct ieee80211_hw *hw = usb_get_intfdata(usb_intf);
  501. struct rt2x00_dev *rt2x00dev = hw->priv;
  502. int retval;
  503. usb_get_dev(interface_to_usbdev(usb_intf));
  504. retval = rt2x00usb_alloc_reg(rt2x00dev);
  505. if (retval)
  506. return retval;
  507. retval = rt2x00lib_resume(rt2x00dev);
  508. if (retval)
  509. goto exit_free_reg;
  510. return 0;
  511. exit_free_reg:
  512. rt2x00usb_free_reg(rt2x00dev);
  513. return retval;
  514. }
  515. EXPORT_SYMBOL_GPL(rt2x00usb_resume);
  516. #endif /* CONFIG_PM */
  517. /*
  518. * rt2x00usb module information.
  519. */
  520. MODULE_AUTHOR(DRV_PROJECT);
  521. MODULE_VERSION(DRV_VERSION);
  522. MODULE_DESCRIPTION("rt2x00 usb library");
  523. MODULE_LICENSE("GPL");