bcm43xx_pio.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. /*
  2. Broadcom BCM43xx wireless driver
  3. PIO Transmission
  4. Copyright (c) 2005 Michael Buesch <mbuesch@freenet.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 "bcm43xx.h"
  19. #include "bcm43xx_pio.h"
  20. #include "bcm43xx_main.h"
  21. #include "bcm43xx_xmit.h"
  22. #include "bcm43xx_power.h"
  23. #include <linux/delay.h>
  24. static void tx_start(struct bcm43xx_pioqueue *queue)
  25. {
  26. bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
  27. BCM43xx_PIO_TXCTL_INIT);
  28. }
  29. static void tx_octet(struct bcm43xx_pioqueue *queue,
  30. u8 octet)
  31. {
  32. if (queue->need_workarounds) {
  33. bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA,
  34. octet);
  35. bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
  36. BCM43xx_PIO_TXCTL_WRITELO);
  37. } else {
  38. bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
  39. BCM43xx_PIO_TXCTL_WRITELO);
  40. bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA,
  41. octet);
  42. }
  43. }
  44. static u16 tx_get_next_word(struct bcm43xx_txhdr *txhdr,
  45. const u8 *packet,
  46. unsigned int *pos)
  47. {
  48. const u8 *source;
  49. unsigned int i = *pos;
  50. u16 ret;
  51. if (i < sizeof(*txhdr)) {
  52. source = (const u8 *)txhdr;
  53. } else {
  54. source = packet;
  55. i -= sizeof(*txhdr);
  56. }
  57. ret = le16_to_cpu( *((u16 *)(source + i)) );
  58. *pos += 2;
  59. return ret;
  60. }
  61. static void tx_data(struct bcm43xx_pioqueue *queue,
  62. struct bcm43xx_txhdr *txhdr,
  63. const u8 *packet,
  64. unsigned int octets)
  65. {
  66. u16 data;
  67. unsigned int i = 0;
  68. if (queue->need_workarounds) {
  69. data = tx_get_next_word(txhdr, packet, &i);
  70. bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, data);
  71. }
  72. bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
  73. BCM43xx_PIO_TXCTL_WRITELO |
  74. BCM43xx_PIO_TXCTL_WRITEHI);
  75. while (i < octets - 1) {
  76. data = tx_get_next_word(txhdr, packet, &i);
  77. bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, data);
  78. }
  79. if (octets % 2)
  80. tx_octet(queue, packet[octets - sizeof(*txhdr) - 1]);
  81. }
  82. static void tx_complete(struct bcm43xx_pioqueue *queue,
  83. struct sk_buff *skb)
  84. {
  85. if (queue->need_workarounds) {
  86. bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA,
  87. skb->data[skb->len - 1]);
  88. bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
  89. BCM43xx_PIO_TXCTL_WRITELO |
  90. BCM43xx_PIO_TXCTL_COMPLETE);
  91. } else {
  92. bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
  93. BCM43xx_PIO_TXCTL_COMPLETE);
  94. }
  95. }
  96. static u16 generate_cookie(struct bcm43xx_pioqueue *queue,
  97. struct bcm43xx_pio_txpacket *packet)
  98. {
  99. u16 cookie = 0x0000;
  100. int packetindex;
  101. /* We use the upper 4 bits for the PIO
  102. * controller ID and the lower 12 bits
  103. * for the packet index (in the cache).
  104. */
  105. switch (queue->mmio_base) {
  106. case BCM43xx_MMIO_PIO1_BASE:
  107. break;
  108. case BCM43xx_MMIO_PIO2_BASE:
  109. cookie = 0x1000;
  110. break;
  111. case BCM43xx_MMIO_PIO3_BASE:
  112. cookie = 0x2000;
  113. break;
  114. case BCM43xx_MMIO_PIO4_BASE:
  115. cookie = 0x3000;
  116. break;
  117. default:
  118. assert(0);
  119. }
  120. packetindex = pio_txpacket_getindex(packet);
  121. assert(((u16)packetindex & 0xF000) == 0x0000);
  122. cookie |= (u16)packetindex;
  123. return cookie;
  124. }
  125. static
  126. struct bcm43xx_pioqueue * parse_cookie(struct bcm43xx_private *bcm,
  127. u16 cookie,
  128. struct bcm43xx_pio_txpacket **packet)
  129. {
  130. struct bcm43xx_pio *pio = bcm43xx_current_pio(bcm);
  131. struct bcm43xx_pioqueue *queue = NULL;
  132. int packetindex;
  133. switch (cookie & 0xF000) {
  134. case 0x0000:
  135. queue = pio->queue0;
  136. break;
  137. case 0x1000:
  138. queue = pio->queue1;
  139. break;
  140. case 0x2000:
  141. queue = pio->queue2;
  142. break;
  143. case 0x3000:
  144. queue = pio->queue3;
  145. break;
  146. default:
  147. assert(0);
  148. }
  149. packetindex = (cookie & 0x0FFF);
  150. assert(packetindex >= 0 && packetindex < BCM43xx_PIO_MAXTXPACKETS);
  151. *packet = &(queue->tx_packets_cache[packetindex]);
  152. return queue;
  153. }
  154. static void pio_tx_write_fragment(struct bcm43xx_pioqueue *queue,
  155. struct sk_buff *skb,
  156. struct bcm43xx_pio_txpacket *packet)
  157. {
  158. struct bcm43xx_txhdr txhdr;
  159. unsigned int octets;
  160. assert(skb_shinfo(skb)->nr_frags == 0);
  161. bcm43xx_generate_txhdr(queue->bcm,
  162. &txhdr, skb->data, skb->len,
  163. (packet->xmitted_frags == 0),
  164. generate_cookie(queue, packet));
  165. tx_start(queue);
  166. octets = skb->len + sizeof(txhdr);
  167. if (queue->need_workarounds)
  168. octets--;
  169. tx_data(queue, &txhdr, (u8 *)skb->data, octets);
  170. tx_complete(queue, skb);
  171. }
  172. static void free_txpacket(struct bcm43xx_pio_txpacket *packet,
  173. int irq_context)
  174. {
  175. struct bcm43xx_pioqueue *queue = packet->queue;
  176. ieee80211_txb_free(packet->txb);
  177. list_move(&packet->list, &queue->txfree);
  178. queue->nr_txfree++;
  179. assert(queue->tx_devq_used >= packet->xmitted_octets);
  180. assert(queue->tx_devq_packets >= packet->xmitted_frags);
  181. queue->tx_devq_used -= packet->xmitted_octets;
  182. queue->tx_devq_packets -= packet->xmitted_frags;
  183. }
  184. static int pio_tx_packet(struct bcm43xx_pio_txpacket *packet)
  185. {
  186. struct bcm43xx_pioqueue *queue = packet->queue;
  187. struct ieee80211_txb *txb = packet->txb;
  188. struct sk_buff *skb;
  189. u16 octets;
  190. int i;
  191. for (i = packet->xmitted_frags; i < txb->nr_frags; i++) {
  192. skb = txb->fragments[i];
  193. octets = (u16)skb->len + sizeof(struct bcm43xx_txhdr);
  194. assert(queue->tx_devq_size >= octets);
  195. assert(queue->tx_devq_packets <= BCM43xx_PIO_MAXTXDEVQPACKETS);
  196. assert(queue->tx_devq_used <= queue->tx_devq_size);
  197. /* Check if there is sufficient free space on the device
  198. * TX queue. If not, return and let the TX tasklet
  199. * retry later.
  200. */
  201. if (queue->tx_devq_packets == BCM43xx_PIO_MAXTXDEVQPACKETS)
  202. return -EBUSY;
  203. if (queue->tx_devq_used + octets > queue->tx_devq_size)
  204. return -EBUSY;
  205. /* Now poke the device. */
  206. pio_tx_write_fragment(queue, skb, packet);
  207. /* Account for the packet size.
  208. * (We must not overflow the device TX queue)
  209. */
  210. queue->tx_devq_packets++;
  211. queue->tx_devq_used += octets;
  212. assert(packet->xmitted_frags < packet->txb->nr_frags);
  213. packet->xmitted_frags++;
  214. packet->xmitted_octets += octets;
  215. }
  216. list_move_tail(&packet->list, &queue->txrunning);
  217. return 0;
  218. }
  219. static void tx_tasklet(unsigned long d)
  220. {
  221. struct bcm43xx_pioqueue *queue = (struct bcm43xx_pioqueue *)d;
  222. struct bcm43xx_private *bcm = queue->bcm;
  223. unsigned long flags;
  224. struct bcm43xx_pio_txpacket *packet, *tmp_packet;
  225. int err;
  226. u16 txctl;
  227. spin_lock_irqsave(&bcm->irq_lock, flags);
  228. if (queue->tx_frozen)
  229. goto out_unlock;
  230. txctl = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL);
  231. if (txctl & BCM43xx_PIO_TXCTL_SUSPEND)
  232. goto out_unlock;
  233. list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list) {
  234. assert(packet->xmitted_frags < packet->txb->nr_frags);
  235. if (packet->xmitted_frags == 0) {
  236. int i;
  237. struct sk_buff *skb;
  238. /* Check if the device queue is big
  239. * enough for every fragment. If not, drop the
  240. * whole packet.
  241. */
  242. for (i = 0; i < packet->txb->nr_frags; i++) {
  243. skb = packet->txb->fragments[i];
  244. if (unlikely(skb->len > queue->tx_devq_size)) {
  245. dprintkl(KERN_ERR PFX "PIO TX device queue too small. "
  246. "Dropping packet.\n");
  247. free_txpacket(packet, 1);
  248. goto next_packet;
  249. }
  250. }
  251. }
  252. /* Try to transmit the packet.
  253. * This may not completely succeed.
  254. */
  255. err = pio_tx_packet(packet);
  256. if (err)
  257. break;
  258. next_packet:
  259. continue;
  260. }
  261. out_unlock:
  262. spin_unlock_irqrestore(&bcm->irq_lock, flags);
  263. }
  264. static void setup_txqueues(struct bcm43xx_pioqueue *queue)
  265. {
  266. struct bcm43xx_pio_txpacket *packet;
  267. int i;
  268. queue->nr_txfree = BCM43xx_PIO_MAXTXPACKETS;
  269. for (i = 0; i < BCM43xx_PIO_MAXTXPACKETS; i++) {
  270. packet = &(queue->tx_packets_cache[i]);
  271. packet->queue = queue;
  272. INIT_LIST_HEAD(&packet->list);
  273. list_add(&packet->list, &queue->txfree);
  274. }
  275. }
  276. static
  277. struct bcm43xx_pioqueue * bcm43xx_setup_pioqueue(struct bcm43xx_private *bcm,
  278. u16 pio_mmio_base)
  279. {
  280. struct bcm43xx_pioqueue *queue;
  281. u32 value;
  282. u16 qsize;
  283. queue = kzalloc(sizeof(*queue), GFP_KERNEL);
  284. if (!queue)
  285. goto out;
  286. queue->bcm = bcm;
  287. queue->mmio_base = pio_mmio_base;
  288. queue->need_workarounds = (bcm->current_core->rev < 3);
  289. INIT_LIST_HEAD(&queue->txfree);
  290. INIT_LIST_HEAD(&queue->txqueue);
  291. INIT_LIST_HEAD(&queue->txrunning);
  292. tasklet_init(&queue->txtask, tx_tasklet,
  293. (unsigned long)queue);
  294. value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
  295. value &= ~BCM43xx_SBF_XFER_REG_BYTESWAP;
  296. bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value);
  297. qsize = bcm43xx_read16(bcm, queue->mmio_base + BCM43xx_PIO_TXQBUFSIZE);
  298. if (qsize == 0) {
  299. printk(KERN_ERR PFX "ERROR: This card does not support PIO "
  300. "operation mode. Please use DMA mode "
  301. "(module parameter pio=0).\n");
  302. goto err_freequeue;
  303. }
  304. if (qsize <= BCM43xx_PIO_TXQADJUST) {
  305. printk(KERN_ERR PFX "PIO tx device-queue too small (%u)\n",
  306. qsize);
  307. goto err_freequeue;
  308. }
  309. qsize -= BCM43xx_PIO_TXQADJUST;
  310. queue->tx_devq_size = qsize;
  311. setup_txqueues(queue);
  312. out:
  313. return queue;
  314. err_freequeue:
  315. kfree(queue);
  316. queue = NULL;
  317. goto out;
  318. }
  319. static void cancel_transfers(struct bcm43xx_pioqueue *queue)
  320. {
  321. struct bcm43xx_pio_txpacket *packet, *tmp_packet;
  322. netif_tx_disable(queue->bcm->net_dev);
  323. tasklet_disable(&queue->txtask);
  324. list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list)
  325. free_txpacket(packet, 0);
  326. list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list)
  327. free_txpacket(packet, 0);
  328. }
  329. static void bcm43xx_destroy_pioqueue(struct bcm43xx_pioqueue *queue)
  330. {
  331. if (!queue)
  332. return;
  333. cancel_transfers(queue);
  334. kfree(queue);
  335. }
  336. void bcm43xx_pio_free(struct bcm43xx_private *bcm)
  337. {
  338. struct bcm43xx_pio *pio;
  339. if (!bcm43xx_using_pio(bcm))
  340. return;
  341. pio = bcm43xx_current_pio(bcm);
  342. bcm43xx_destroy_pioqueue(pio->queue3);
  343. pio->queue3 = NULL;
  344. bcm43xx_destroy_pioqueue(pio->queue2);
  345. pio->queue2 = NULL;
  346. bcm43xx_destroy_pioqueue(pio->queue1);
  347. pio->queue1 = NULL;
  348. bcm43xx_destroy_pioqueue(pio->queue0);
  349. pio->queue0 = NULL;
  350. }
  351. int bcm43xx_pio_init(struct bcm43xx_private *bcm)
  352. {
  353. struct bcm43xx_pio *pio = bcm43xx_current_pio(bcm);
  354. struct bcm43xx_pioqueue *queue;
  355. int err = -ENOMEM;
  356. queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO1_BASE);
  357. if (!queue)
  358. goto out;
  359. pio->queue0 = queue;
  360. queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO2_BASE);
  361. if (!queue)
  362. goto err_destroy0;
  363. pio->queue1 = queue;
  364. queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO3_BASE);
  365. if (!queue)
  366. goto err_destroy1;
  367. pio->queue2 = queue;
  368. queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO4_BASE);
  369. if (!queue)
  370. goto err_destroy2;
  371. pio->queue3 = queue;
  372. if (bcm->current_core->rev < 3)
  373. bcm->irq_savedstate |= BCM43xx_IRQ_PIO_WORKAROUND;
  374. dprintk(KERN_INFO PFX "PIO initialized\n");
  375. err = 0;
  376. out:
  377. return err;
  378. err_destroy2:
  379. bcm43xx_destroy_pioqueue(pio->queue2);
  380. pio->queue2 = NULL;
  381. err_destroy1:
  382. bcm43xx_destroy_pioqueue(pio->queue1);
  383. pio->queue1 = NULL;
  384. err_destroy0:
  385. bcm43xx_destroy_pioqueue(pio->queue0);
  386. pio->queue0 = NULL;
  387. goto out;
  388. }
  389. int bcm43xx_pio_tx(struct bcm43xx_private *bcm,
  390. struct ieee80211_txb *txb)
  391. {
  392. struct bcm43xx_pioqueue *queue = bcm43xx_current_pio(bcm)->queue1;
  393. struct bcm43xx_pio_txpacket *packet;
  394. assert(!queue->tx_suspended);
  395. assert(!list_empty(&queue->txfree));
  396. packet = list_entry(queue->txfree.next, struct bcm43xx_pio_txpacket, list);
  397. packet->txb = txb;
  398. packet->xmitted_frags = 0;
  399. packet->xmitted_octets = 0;
  400. list_move_tail(&packet->list, &queue->txqueue);
  401. queue->nr_txfree--;
  402. assert(queue->nr_txfree < BCM43xx_PIO_MAXTXPACKETS);
  403. /* Suspend TX, if we are out of packets in the "free" queue. */
  404. if (list_empty(&queue->txfree)) {
  405. netif_stop_queue(queue->bcm->net_dev);
  406. queue->tx_suspended = 1;
  407. }
  408. tasklet_schedule(&queue->txtask);
  409. return 0;
  410. }
  411. void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm,
  412. struct bcm43xx_xmitstatus *status)
  413. {
  414. struct bcm43xx_pioqueue *queue;
  415. struct bcm43xx_pio_txpacket *packet;
  416. queue = parse_cookie(bcm, status->cookie, &packet);
  417. assert(queue);
  418. free_txpacket(packet, 1);
  419. if (queue->tx_suspended) {
  420. queue->tx_suspended = 0;
  421. netif_wake_queue(queue->bcm->net_dev);
  422. }
  423. /* If there are packets on the txqueue, poke the tasklet
  424. * to transmit them.
  425. */
  426. if (!list_empty(&queue->txqueue))
  427. tasklet_schedule(&queue->txtask);
  428. }
  429. static void pio_rx_error(struct bcm43xx_pioqueue *queue,
  430. int clear_buffers,
  431. const char *error)
  432. {
  433. int i;
  434. printkl("PIO RX error: %s\n", error);
  435. bcm43xx_pio_write(queue, BCM43xx_PIO_RXCTL,
  436. BCM43xx_PIO_RXCTL_READY);
  437. if (clear_buffers) {
  438. assert(queue->mmio_base == BCM43xx_MMIO_PIO1_BASE);
  439. for (i = 0; i < 15; i++) {
  440. /* Dummy read. */
  441. bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
  442. }
  443. }
  444. }
  445. void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue)
  446. {
  447. u16 preamble[21] = { 0 };
  448. struct bcm43xx_rxhdr *rxhdr;
  449. u16 tmp, len, rxflags2;
  450. int i, preamble_readwords;
  451. struct sk_buff *skb;
  452. tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXCTL);
  453. if (!(tmp & BCM43xx_PIO_RXCTL_DATAAVAILABLE))
  454. return;
  455. bcm43xx_pio_write(queue, BCM43xx_PIO_RXCTL,
  456. BCM43xx_PIO_RXCTL_DATAAVAILABLE);
  457. for (i = 0; i < 10; i++) {
  458. tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXCTL);
  459. if (tmp & BCM43xx_PIO_RXCTL_READY)
  460. goto data_ready;
  461. udelay(10);
  462. }
  463. dprintkl(KERN_ERR PFX "PIO RX timed out\n");
  464. return;
  465. data_ready:
  466. len = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
  467. if (unlikely(len > 0x700)) {
  468. pio_rx_error(queue, 0, "len > 0x700");
  469. return;
  470. }
  471. if (unlikely(len == 0 && queue->mmio_base != BCM43xx_MMIO_PIO4_BASE)) {
  472. pio_rx_error(queue, 0, "len == 0");
  473. return;
  474. }
  475. preamble[0] = cpu_to_le16(len);
  476. if (queue->mmio_base == BCM43xx_MMIO_PIO4_BASE)
  477. preamble_readwords = 14 / sizeof(u16);
  478. else
  479. preamble_readwords = 18 / sizeof(u16);
  480. for (i = 0; i < preamble_readwords; i++) {
  481. tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
  482. preamble[i + 1] = cpu_to_le16(tmp);
  483. }
  484. rxhdr = (struct bcm43xx_rxhdr *)preamble;
  485. rxflags2 = le16_to_cpu(rxhdr->flags2);
  486. if (unlikely(rxflags2 & BCM43xx_RXHDR_FLAGS2_INVALIDFRAME)) {
  487. pio_rx_error(queue,
  488. (queue->mmio_base == BCM43xx_MMIO_PIO1_BASE),
  489. "invalid frame");
  490. return;
  491. }
  492. if (queue->mmio_base == BCM43xx_MMIO_PIO4_BASE) {
  493. /* We received an xmit status. */
  494. struct bcm43xx_hwxmitstatus *hw;
  495. struct bcm43xx_xmitstatus stat;
  496. hw = (struct bcm43xx_hwxmitstatus *)(preamble + 1);
  497. stat.cookie = le16_to_cpu(hw->cookie);
  498. stat.flags = hw->flags;
  499. stat.cnt1 = hw->cnt1;
  500. stat.cnt2 = hw->cnt2;
  501. stat.seq = le16_to_cpu(hw->seq);
  502. stat.unknown = le16_to_cpu(hw->unknown);
  503. bcm43xx_debugfs_log_txstat(queue->bcm, &stat);
  504. bcm43xx_pio_handle_xmitstatus(queue->bcm, &stat);
  505. return;
  506. }
  507. skb = dev_alloc_skb(len);
  508. if (unlikely(!skb)) {
  509. pio_rx_error(queue, 1, "OOM");
  510. return;
  511. }
  512. skb_put(skb, len);
  513. for (i = 0; i < len - 1; i += 2) {
  514. tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
  515. *((u16 *)(skb->data + i)) = cpu_to_le16(tmp);
  516. }
  517. if (len % 2) {
  518. tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
  519. skb->data[len - 1] = (tmp & 0x00FF);
  520. /* The specs say the following is required, but
  521. * it is wrong and corrupts the PLCP. If we don't do
  522. * this, the PLCP seems to be correct. So ifdef it out for now.
  523. */
  524. #if 0
  525. if (rxflags2 & BCM43xx_RXHDR_FLAGS2_TYPE2FRAME)
  526. skb->data[2] = (tmp & 0xFF00) >> 8;
  527. else
  528. skb->data[0] = (tmp & 0xFF00) >> 8;
  529. #endif
  530. }
  531. skb_trim(skb, len - IEEE80211_FCS_LEN);
  532. bcm43xx_rx(queue->bcm, skb, rxhdr);
  533. }
  534. void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue)
  535. {
  536. bcm43xx_power_saving_ctl_bits(queue->bcm, -1, 1);
  537. bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
  538. bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL)
  539. | BCM43xx_PIO_TXCTL_SUSPEND);
  540. }
  541. void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue)
  542. {
  543. bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
  544. bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL)
  545. & ~BCM43xx_PIO_TXCTL_SUSPEND);
  546. bcm43xx_power_saving_ctl_bits(queue->bcm, -1, -1);
  547. if (!list_empty(&queue->txqueue))
  548. tasklet_schedule(&queue->txtask);
  549. }
  550. void bcm43xx_pio_freeze_txqueues(struct bcm43xx_private *bcm)
  551. {
  552. struct bcm43xx_pio *pio;
  553. assert(bcm43xx_using_pio(bcm));
  554. pio = bcm43xx_current_pio(bcm);
  555. pio->queue0->tx_frozen = 1;
  556. pio->queue1->tx_frozen = 1;
  557. pio->queue2->tx_frozen = 1;
  558. pio->queue3->tx_frozen = 1;
  559. }
  560. void bcm43xx_pio_thaw_txqueues(struct bcm43xx_private *bcm)
  561. {
  562. struct bcm43xx_pio *pio;
  563. assert(bcm43xx_using_pio(bcm));
  564. pio = bcm43xx_current_pio(bcm);
  565. pio->queue0->tx_frozen = 0;
  566. pio->queue1->tx_frozen = 0;
  567. pio->queue2->tx_frozen = 0;
  568. pio->queue3->tx_frozen = 0;
  569. if (!list_empty(&pio->queue0->txqueue))
  570. tasklet_schedule(&pio->queue0->txtask);
  571. if (!list_empty(&pio->queue1->txqueue))
  572. tasklet_schedule(&pio->queue1->txtask);
  573. if (!list_empty(&pio->queue2->txqueue))
  574. tasklet_schedule(&pio->queue2->txtask);
  575. if (!list_empty(&pio->queue3->txqueue))
  576. tasklet_schedule(&pio->queue3->txtask);
  577. }