pio.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. /*
  2. Broadcom B43 wireless driver
  3. PIO Transmission
  4. Copyright (c) 2005 Michael Buesch <mb@bu3sch.de>
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; see the file COPYING. If not, write to
  15. the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
  16. Boston, MA 02110-1301, USA.
  17. */
  18. #include "b43.h"
  19. #include "pio.h"
  20. #include "main.h"
  21. #include "xmit.h"
  22. #include <linux/delay.h>
  23. static void tx_start(struct b43_pioqueue *queue)
  24. {
  25. b43_pio_write(queue, B43_PIO_TXCTL, B43_PIO_TXCTL_INIT);
  26. }
  27. static void tx_octet(struct b43_pioqueue *queue, u8 octet)
  28. {
  29. if (queue->need_workarounds) {
  30. b43_pio_write(queue, B43_PIO_TXDATA, octet);
  31. b43_pio_write(queue, B43_PIO_TXCTL, B43_PIO_TXCTL_WRITELO);
  32. } else {
  33. b43_pio_write(queue, B43_PIO_TXCTL, B43_PIO_TXCTL_WRITELO);
  34. b43_pio_write(queue, B43_PIO_TXDATA, octet);
  35. }
  36. }
  37. static u16 tx_get_next_word(const u8 * txhdr,
  38. const u8 * packet,
  39. size_t txhdr_size, unsigned int *pos)
  40. {
  41. const u8 *source;
  42. unsigned int i = *pos;
  43. u16 ret;
  44. if (i < txhdr_size) {
  45. source = txhdr;
  46. } else {
  47. source = packet;
  48. i -= txhdr_size;
  49. }
  50. ret = le16_to_cpu(*((__le16 *)(source + i)));
  51. *pos += 2;
  52. return ret;
  53. }
  54. static void tx_data(struct b43_pioqueue *queue,
  55. u8 * txhdr, const u8 * packet, unsigned int octets)
  56. {
  57. u16 data;
  58. unsigned int i = 0;
  59. if (queue->need_workarounds) {
  60. data = tx_get_next_word(txhdr, packet,
  61. sizeof(struct b43_txhdr_fw4), &i);
  62. b43_pio_write(queue, B43_PIO_TXDATA, data);
  63. }
  64. b43_pio_write(queue, B43_PIO_TXCTL,
  65. B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI);
  66. while (i < octets - 1) {
  67. data = tx_get_next_word(txhdr, packet,
  68. sizeof(struct b43_txhdr_fw4), &i);
  69. b43_pio_write(queue, B43_PIO_TXDATA, data);
  70. }
  71. if (octets % 2)
  72. tx_octet(queue,
  73. packet[octets - sizeof(struct b43_txhdr_fw4) - 1]);
  74. }
  75. static void tx_complete(struct b43_pioqueue *queue, struct sk_buff *skb)
  76. {
  77. if (queue->need_workarounds) {
  78. b43_pio_write(queue, B43_PIO_TXDATA, skb->data[skb->len - 1]);
  79. b43_pio_write(queue, B43_PIO_TXCTL,
  80. B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_COMPLETE);
  81. } else {
  82. b43_pio_write(queue, B43_PIO_TXCTL, B43_PIO_TXCTL_COMPLETE);
  83. }
  84. }
  85. static u16 generate_cookie(struct b43_pioqueue *queue,
  86. struct b43_pio_txpacket *packet)
  87. {
  88. u16 cookie = 0x0000;
  89. u16 packetindex;
  90. /* We use the upper 4 bits for the PIO
  91. * controller ID and the lower 12 bits
  92. * for the packet index (in the cache).
  93. */
  94. switch (queue->mmio_base) {
  95. case B43_MMIO_PIO1_BASE:
  96. break;
  97. case B43_MMIO_PIO2_BASE:
  98. cookie = 0x1000;
  99. break;
  100. case B43_MMIO_PIO3_BASE:
  101. cookie = 0x2000;
  102. break;
  103. case B43_MMIO_PIO4_BASE:
  104. cookie = 0x3000;
  105. break;
  106. default:
  107. B43_WARN_ON(1);
  108. }
  109. packetindex = packet->index;
  110. B43_WARN_ON(packetindex & ~0x0FFF);
  111. cookie |= (u16) packetindex;
  112. return cookie;
  113. }
  114. static
  115. struct b43_pioqueue *parse_cookie(struct b43_wldev *dev,
  116. u16 cookie, struct b43_pio_txpacket **packet)
  117. {
  118. struct b43_pio *pio = &dev->pio;
  119. struct b43_pioqueue *queue = NULL;
  120. int packetindex;
  121. switch (cookie & 0xF000) {
  122. case 0x0000:
  123. queue = pio->queue0;
  124. break;
  125. case 0x1000:
  126. queue = pio->queue1;
  127. break;
  128. case 0x2000:
  129. queue = pio->queue2;
  130. break;
  131. case 0x3000:
  132. queue = pio->queue3;
  133. break;
  134. default:
  135. B43_WARN_ON(1);
  136. }
  137. packetindex = (cookie & 0x0FFF);
  138. B43_WARN_ON(!(packetindex >= 0 && packetindex < B43_PIO_MAXTXPACKETS));
  139. *packet = &(queue->tx_packets_cache[packetindex]);
  140. return queue;
  141. }
  142. union txhdr_union {
  143. struct b43_txhdr_fw4 txhdr_fw4;
  144. };
  145. static void pio_tx_write_fragment(struct b43_pioqueue *queue,
  146. struct sk_buff *skb,
  147. struct b43_pio_txpacket *packet,
  148. size_t txhdr_size)
  149. {
  150. union txhdr_union txhdr_data;
  151. u8 *txhdr = NULL;
  152. unsigned int octets;
  153. txhdr = (u8 *) (&txhdr_data.txhdr_fw4);
  154. B43_WARN_ON(skb_shinfo(skb)->nr_frags);
  155. b43_generate_txhdr(queue->dev,
  156. txhdr, skb->data, skb->len,
  157. &packet->txstat.control,
  158. generate_cookie(queue, packet));
  159. tx_start(queue);
  160. octets = skb->len + txhdr_size;
  161. if (queue->need_workarounds)
  162. octets--;
  163. tx_data(queue, txhdr, (u8 *) skb->data, octets);
  164. tx_complete(queue, skb);
  165. }
  166. static void free_txpacket(struct b43_pio_txpacket *packet)
  167. {
  168. struct b43_pioqueue *queue = packet->queue;
  169. if (packet->skb)
  170. dev_kfree_skb_any(packet->skb);
  171. list_move(&packet->list, &queue->txfree);
  172. queue->nr_txfree++;
  173. }
  174. static int pio_tx_packet(struct b43_pio_txpacket *packet)
  175. {
  176. struct b43_pioqueue *queue = packet->queue;
  177. struct sk_buff *skb = packet->skb;
  178. u16 octets;
  179. octets = (u16) skb->len + sizeof(struct b43_txhdr_fw4);
  180. if (queue->tx_devq_size < octets) {
  181. b43warn(queue->dev->wl, "PIO queue too small. "
  182. "Dropping packet.\n");
  183. /* Drop it silently (return success) */
  184. free_txpacket(packet);
  185. return 0;
  186. }
  187. B43_WARN_ON(queue->tx_devq_packets > B43_PIO_MAXTXDEVQPACKETS);
  188. B43_WARN_ON(queue->tx_devq_used > queue->tx_devq_size);
  189. /* Check if there is sufficient free space on the device
  190. * TX queue. If not, return and let the TX tasklet
  191. * retry later.
  192. */
  193. if (queue->tx_devq_packets == B43_PIO_MAXTXDEVQPACKETS)
  194. return -EBUSY;
  195. if (queue->tx_devq_used + octets > queue->tx_devq_size)
  196. return -EBUSY;
  197. /* Now poke the device. */
  198. pio_tx_write_fragment(queue, skb, packet, sizeof(struct b43_txhdr_fw4));
  199. /* Account for the packet size.
  200. * (We must not overflow the device TX queue)
  201. */
  202. queue->tx_devq_packets++;
  203. queue->tx_devq_used += octets;
  204. /* Transmission started, everything ok, move the
  205. * packet to the txrunning list.
  206. */
  207. list_move_tail(&packet->list, &queue->txrunning);
  208. return 0;
  209. }
  210. static void tx_tasklet(unsigned long d)
  211. {
  212. struct b43_pioqueue *queue = (struct b43_pioqueue *)d;
  213. struct b43_wldev *dev = queue->dev;
  214. unsigned long flags;
  215. struct b43_pio_txpacket *packet, *tmp_packet;
  216. int err;
  217. u16 txctl;
  218. spin_lock_irqsave(&dev->wl->irq_lock, flags);
  219. if (queue->tx_frozen)
  220. goto out_unlock;
  221. txctl = b43_pio_read(queue, B43_PIO_TXCTL);
  222. if (txctl & B43_PIO_TXCTL_SUSPEND)
  223. goto out_unlock;
  224. list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list) {
  225. /* Try to transmit the packet. This can fail, if
  226. * the device queue is full. In case of failure, the
  227. * packet is left in the txqueue.
  228. * If transmission succeed, the packet is moved to txrunning.
  229. * If it is impossible to transmit the packet, it
  230. * is dropped.
  231. */
  232. err = pio_tx_packet(packet);
  233. if (err)
  234. break;
  235. }
  236. out_unlock:
  237. spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
  238. }
  239. static void setup_txqueues(struct b43_pioqueue *queue)
  240. {
  241. struct b43_pio_txpacket *packet;
  242. int i;
  243. queue->nr_txfree = B43_PIO_MAXTXPACKETS;
  244. for (i = 0; i < B43_PIO_MAXTXPACKETS; i++) {
  245. packet = &(queue->tx_packets_cache[i]);
  246. packet->queue = queue;
  247. INIT_LIST_HEAD(&packet->list);
  248. packet->index = i;
  249. list_add(&packet->list, &queue->txfree);
  250. }
  251. }
  252. static
  253. struct b43_pioqueue *b43_setup_pioqueue(struct b43_wldev *dev,
  254. u16 pio_mmio_base)
  255. {
  256. struct b43_pioqueue *queue;
  257. u16 qsize;
  258. queue = kzalloc(sizeof(*queue), GFP_KERNEL);
  259. if (!queue)
  260. goto out;
  261. queue->dev = dev;
  262. queue->mmio_base = pio_mmio_base;
  263. queue->need_workarounds = (dev->dev->id.revision < 3);
  264. INIT_LIST_HEAD(&queue->txfree);
  265. INIT_LIST_HEAD(&queue->txqueue);
  266. INIT_LIST_HEAD(&queue->txrunning);
  267. tasklet_init(&queue->txtask, tx_tasklet, (unsigned long)queue);
  268. b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)
  269. & ~B43_MACCTL_BE);
  270. qsize = b43_read16(dev, queue->mmio_base + B43_PIO_TXQBUFSIZE);
  271. if (qsize == 0) {
  272. b43err(dev->wl, "This card does not support PIO "
  273. "operation mode. Please use DMA mode "
  274. "(module parameter pio=0).\n");
  275. goto err_freequeue;
  276. }
  277. if (qsize <= B43_PIO_TXQADJUST) {
  278. b43err(dev->wl, "PIO tx device-queue too small (%u)\n", qsize);
  279. goto err_freequeue;
  280. }
  281. qsize -= B43_PIO_TXQADJUST;
  282. queue->tx_devq_size = qsize;
  283. setup_txqueues(queue);
  284. out:
  285. return queue;
  286. err_freequeue:
  287. kfree(queue);
  288. queue = NULL;
  289. goto out;
  290. }
  291. static void cancel_transfers(struct b43_pioqueue *queue)
  292. {
  293. struct b43_pio_txpacket *packet, *tmp_packet;
  294. tasklet_disable(&queue->txtask);
  295. list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list)
  296. free_txpacket(packet);
  297. list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list)
  298. free_txpacket(packet);
  299. }
  300. static void b43_destroy_pioqueue(struct b43_pioqueue *queue)
  301. {
  302. if (!queue)
  303. return;
  304. cancel_transfers(queue);
  305. kfree(queue);
  306. }
  307. void b43_pio_free(struct b43_wldev *dev)
  308. {
  309. struct b43_pio *pio;
  310. if (!b43_using_pio(dev))
  311. return;
  312. pio = &dev->pio;
  313. b43_destroy_pioqueue(pio->queue3);
  314. pio->queue3 = NULL;
  315. b43_destroy_pioqueue(pio->queue2);
  316. pio->queue2 = NULL;
  317. b43_destroy_pioqueue(pio->queue1);
  318. pio->queue1 = NULL;
  319. b43_destroy_pioqueue(pio->queue0);
  320. pio->queue0 = NULL;
  321. }
  322. int b43_pio_init(struct b43_wldev *dev)
  323. {
  324. struct b43_pio *pio = &dev->pio;
  325. struct b43_pioqueue *queue;
  326. int err = -ENOMEM;
  327. queue = b43_setup_pioqueue(dev, B43_MMIO_PIO1_BASE);
  328. if (!queue)
  329. goto out;
  330. pio->queue0 = queue;
  331. queue = b43_setup_pioqueue(dev, B43_MMIO_PIO2_BASE);
  332. if (!queue)
  333. goto err_destroy0;
  334. pio->queue1 = queue;
  335. queue = b43_setup_pioqueue(dev, B43_MMIO_PIO3_BASE);
  336. if (!queue)
  337. goto err_destroy1;
  338. pio->queue2 = queue;
  339. queue = b43_setup_pioqueue(dev, B43_MMIO_PIO4_BASE);
  340. if (!queue)
  341. goto err_destroy2;
  342. pio->queue3 = queue;
  343. if (dev->dev->id.revision < 3)
  344. dev->irq_savedstate |= B43_IRQ_PIO_WORKAROUND;
  345. b43dbg(dev->wl, "PIO initialized\n");
  346. err = 0;
  347. out:
  348. return err;
  349. err_destroy2:
  350. b43_destroy_pioqueue(pio->queue2);
  351. pio->queue2 = NULL;
  352. err_destroy1:
  353. b43_destroy_pioqueue(pio->queue1);
  354. pio->queue1 = NULL;
  355. err_destroy0:
  356. b43_destroy_pioqueue(pio->queue0);
  357. pio->queue0 = NULL;
  358. goto out;
  359. }
  360. int b43_pio_tx(struct b43_wldev *dev,
  361. struct sk_buff *skb, struct ieee80211_tx_control *ctl)
  362. {
  363. struct b43_pioqueue *queue = dev->pio.queue1;
  364. struct b43_pio_txpacket *packet;
  365. B43_WARN_ON(queue->tx_suspended);
  366. B43_WARN_ON(list_empty(&queue->txfree));
  367. packet = list_entry(queue->txfree.next, struct b43_pio_txpacket, list);
  368. packet->skb = skb;
  369. memset(&packet->txstat, 0, sizeof(packet->txstat));
  370. memcpy(&packet->txstat.control, ctl, sizeof(*ctl));
  371. list_move_tail(&packet->list, &queue->txqueue);
  372. queue->nr_txfree--;
  373. queue->nr_tx_packets++;
  374. B43_WARN_ON(queue->nr_txfree >= B43_PIO_MAXTXPACKETS);
  375. tasklet_schedule(&queue->txtask);
  376. return 0;
  377. }
  378. void b43_pio_handle_txstatus(struct b43_wldev *dev,
  379. const struct b43_txstatus *status)
  380. {
  381. struct b43_pioqueue *queue;
  382. struct b43_pio_txpacket *packet;
  383. queue = parse_cookie(dev, status->cookie, &packet);
  384. if (B43_WARN_ON(!queue))
  385. return;
  386. queue->tx_devq_packets--;
  387. queue->tx_devq_used -=
  388. (packet->skb->len + sizeof(struct b43_txhdr_fw4));
  389. if (status->acked) {
  390. packet->txstat.flags |= IEEE80211_TX_STATUS_ACK;
  391. } else {
  392. if (!(packet->txstat.control.flags & IEEE80211_TXCTL_NO_ACK))
  393. packet->txstat.excessive_retries = 1;
  394. }
  395. if (status->frame_count == 0) {
  396. /* The frame was not transmitted at all. */
  397. packet->txstat.retry_count = 0;
  398. } else
  399. packet->txstat.retry_count = status->frame_count - 1;
  400. ieee80211_tx_status_irqsafe(dev->wl->hw, packet->skb,
  401. &(packet->txstat));
  402. packet->skb = NULL;
  403. free_txpacket(packet);
  404. /* If there are packets on the txqueue, poke the tasklet
  405. * to transmit them.
  406. */
  407. if (!list_empty(&queue->txqueue))
  408. tasklet_schedule(&queue->txtask);
  409. }
  410. void b43_pio_get_tx_stats(struct b43_wldev *dev,
  411. struct ieee80211_tx_queue_stats *stats)
  412. {
  413. struct b43_pio *pio = &dev->pio;
  414. struct b43_pioqueue *queue;
  415. struct ieee80211_tx_queue_stats_data *data;
  416. queue = pio->queue1;
  417. data = &(stats->data[0]);
  418. data->len = B43_PIO_MAXTXPACKETS - queue->nr_txfree;
  419. data->limit = B43_PIO_MAXTXPACKETS;
  420. data->count = queue->nr_tx_packets;
  421. }
  422. static void pio_rx_error(struct b43_pioqueue *queue,
  423. int clear_buffers, const char *error)
  424. {
  425. int i;
  426. b43err(queue->dev->wl, "PIO RX error: %s\n", error);
  427. b43_pio_write(queue, B43_PIO_RXCTL, B43_PIO_RXCTL_READY);
  428. if (clear_buffers) {
  429. B43_WARN_ON(queue->mmio_base != B43_MMIO_PIO1_BASE);
  430. for (i = 0; i < 15; i++) {
  431. /* Dummy read. */
  432. b43_pio_read(queue, B43_PIO_RXDATA);
  433. }
  434. }
  435. }
  436. void b43_pio_rx(struct b43_pioqueue *queue)
  437. {
  438. __le16 preamble[21] = { 0 };
  439. struct b43_rxhdr_fw4 *rxhdr;
  440. u16 tmp, len;
  441. u32 macstat;
  442. int i, preamble_readwords;
  443. struct sk_buff *skb;
  444. tmp = b43_pio_read(queue, B43_PIO_RXCTL);
  445. if (!(tmp & B43_PIO_RXCTL_DATAAVAILABLE))
  446. return;
  447. b43_pio_write(queue, B43_PIO_RXCTL, B43_PIO_RXCTL_DATAAVAILABLE);
  448. for (i = 0; i < 10; i++) {
  449. tmp = b43_pio_read(queue, B43_PIO_RXCTL);
  450. if (tmp & B43_PIO_RXCTL_READY)
  451. goto data_ready;
  452. udelay(10);
  453. }
  454. b43dbg(queue->dev->wl, "PIO RX timed out\n");
  455. return;
  456. data_ready:
  457. len = b43_pio_read(queue, B43_PIO_RXDATA);
  458. if (unlikely(len > 0x700)) {
  459. pio_rx_error(queue, 0, "len > 0x700");
  460. return;
  461. }
  462. if (unlikely(len == 0 && queue->mmio_base != B43_MMIO_PIO4_BASE)) {
  463. pio_rx_error(queue, 0, "len == 0");
  464. return;
  465. }
  466. preamble[0] = cpu_to_le16(len);
  467. if (queue->mmio_base == B43_MMIO_PIO4_BASE)
  468. preamble_readwords = 14 / sizeof(u16);
  469. else
  470. preamble_readwords = 18 / sizeof(u16);
  471. for (i = 0; i < preamble_readwords; i++) {
  472. tmp = b43_pio_read(queue, B43_PIO_RXDATA);
  473. preamble[i + 1] = cpu_to_le16(tmp);
  474. }
  475. rxhdr = (struct b43_rxhdr_fw4 *)preamble;
  476. macstat = le32_to_cpu(rxhdr->mac_status);
  477. if (macstat & B43_RX_MAC_FCSERR) {
  478. pio_rx_error(queue,
  479. (queue->mmio_base == B43_MMIO_PIO1_BASE),
  480. "Frame FCS error");
  481. return;
  482. }
  483. if (queue->mmio_base == B43_MMIO_PIO4_BASE) {
  484. /* We received an xmit status. */
  485. struct b43_hwtxstatus *hw;
  486. hw = (struct b43_hwtxstatus *)(preamble + 1);
  487. b43_handle_hwtxstatus(queue->dev, hw);
  488. return;
  489. }
  490. skb = dev_alloc_skb(len);
  491. if (unlikely(!skb)) {
  492. pio_rx_error(queue, 1, "OOM");
  493. return;
  494. }
  495. skb_put(skb, len);
  496. for (i = 0; i < len - 1; i += 2) {
  497. tmp = b43_pio_read(queue, B43_PIO_RXDATA);
  498. *((__le16 *)(skb->data + i)) = cpu_to_le16(tmp);
  499. }
  500. if (len % 2) {
  501. tmp = b43_pio_read(queue, B43_PIO_RXDATA);
  502. skb->data[len - 1] = (tmp & 0x00FF);
  503. /* The specs say the following is required, but
  504. * it is wrong and corrupts the PLCP. If we don't do
  505. * this, the PLCP seems to be correct. So ifdef it out for now.
  506. */
  507. #if 0
  508. if (rxflags2 & B43_RXHDR_FLAGS2_TYPE2FRAME)
  509. skb->data[2] = (tmp & 0xFF00) >> 8;
  510. else
  511. skb->data[0] = (tmp & 0xFF00) >> 8;
  512. #endif
  513. }
  514. b43_rx(queue->dev, skb, rxhdr);
  515. }
  516. void b43_pio_tx_suspend(struct b43_pioqueue *queue)
  517. {
  518. b43_power_saving_ctl_bits(queue->dev, B43_PS_AWAKE);
  519. b43_pio_write(queue, B43_PIO_TXCTL, b43_pio_read(queue, B43_PIO_TXCTL)
  520. | B43_PIO_TXCTL_SUSPEND);
  521. }
  522. void b43_pio_tx_resume(struct b43_pioqueue *queue)
  523. {
  524. b43_pio_write(queue, B43_PIO_TXCTL, b43_pio_read(queue, B43_PIO_TXCTL)
  525. & ~B43_PIO_TXCTL_SUSPEND);
  526. b43_power_saving_ctl_bits(queue->dev, 0);
  527. tasklet_schedule(&queue->txtask);
  528. }
  529. void b43_pio_freeze_txqueues(struct b43_wldev *dev)
  530. {
  531. struct b43_pio *pio;
  532. B43_WARN_ON(!b43_using_pio(dev));
  533. pio = &dev->pio;
  534. pio->queue0->tx_frozen = 1;
  535. pio->queue1->tx_frozen = 1;
  536. pio->queue2->tx_frozen = 1;
  537. pio->queue3->tx_frozen = 1;
  538. }
  539. void b43_pio_thaw_txqueues(struct b43_wldev *dev)
  540. {
  541. struct b43_pio *pio;
  542. B43_WARN_ON(!b43_using_pio(dev));
  543. pio = &dev->pio;
  544. pio->queue0->tx_frozen = 0;
  545. pio->queue1->tx_frozen = 0;
  546. pio->queue2->tx_frozen = 0;
  547. pio->queue3->tx_frozen = 0;
  548. if (!list_empty(&pio->queue0->txqueue))
  549. tasklet_schedule(&pio->queue0->txtask);
  550. if (!list_empty(&pio->queue1->txqueue))
  551. tasklet_schedule(&pio->queue1->txtask);
  552. if (!list_empty(&pio->queue2->txqueue))
  553. tasklet_schedule(&pio->queue2->txtask);
  554. if (!list_empty(&pio->queue3->txqueue))
  555. tasklet_schedule(&pio->queue3->txtask);
  556. }