32 #include <linux/slab.h>
41 static void tx_octet(
struct b43legacy_pioqueue *
queue,
44 if (queue->need_workarounds) {
55 static u16 tx_get_next_word(
const u8 *txhdr,
61 unsigned int i = *
pos;
76 static void tx_data(
struct b43legacy_pioqueue *queue,
84 if (queue->need_workarounds) {
85 data = tx_get_next_word(txhdr, packet,
92 while (i < octets - 1) {
93 data = tx_get_next_word(txhdr, packet,
98 tx_octet(queue, packet[octets -
102 static void tx_complete(
struct b43legacy_pioqueue *queue,
105 if (queue->need_workarounds) {
116 static u16 generate_cookie(
struct b43legacy_pioqueue *queue,
117 struct b43legacy_pio_txpacket *packet)
126 switch (queue->mmio_base) {
141 packetindex = pio_txpacket_getindex(packet);
143 cookie |= (
u16)packetindex;
151 struct b43legacy_pio_txpacket **packet)
154 struct b43legacy_pioqueue *queue =
NULL;
157 switch (cookie & 0xF000) {
173 packetindex = (cookie & 0x0FFF);
176 *packet = &(queue->tx_packets_cache[packetindex]);
185 static int pio_tx_write_fragment(
struct b43legacy_pioqueue *queue,
187 struct b43legacy_pio_txpacket *packet,
195 txhdr = (
u8 *)(&txhdr_data.txhdr_fw3);
200 IEEE80211_SKB_CB(skb),
201 generate_cookie(queue, packet));
206 octets = skb->
len + txhdr_size;
207 if (queue->need_workarounds)
209 tx_data(queue, txhdr, (
u8 *)skb->
data, octets);
210 tx_complete(queue, skb);
215 static void free_txpacket(
struct b43legacy_pio_txpacket *packet,
218 struct b43legacy_pioqueue *queue = packet->queue;
224 dev_kfree_skb(packet->skb);
226 list_move(&packet->list, &queue->txfree);
230 static int pio_tx_packet(
struct b43legacy_pio_txpacket *packet)
232 struct b43legacy_pioqueue *queue = packet->queue;
233 struct sk_buff *skb = packet->skb;
238 if (queue->tx_devq_size < octets) {
240 "Dropping packet.\n");
242 free_txpacket(packet, 1);
254 if (queue->tx_devq_used + octets > queue->tx_devq_size)
257 err = pio_tx_write_fragment(queue, skb, packet,
262 free_txpacket(packet, 1);
269 queue->tx_devq_packets++;
270 queue->tx_devq_used += octets;
275 list_move_tail(&packet->list, &queue->txrunning);
280 static void tx_tasklet(
unsigned long d)
282 struct b43legacy_pioqueue *queue = (
struct b43legacy_pioqueue *)d;
285 struct b43legacy_pio_txpacket *packet, *tmp_packet;
290 if (queue->tx_frozen)
304 err = pio_tx_packet(packet);
309 spin_unlock_irqrestore(&dev->
wl->irq_lock, flags);
312 static void setup_txqueues(
struct b43legacy_pioqueue *queue)
314 struct b43legacy_pio_txpacket *packet;
319 packet = &(queue->tx_packets_cache[
i]);
321 packet->queue = queue;
322 INIT_LIST_HEAD(&packet->list);
324 list_add(&packet->list, &queue->txfree);
329 struct b43legacy_pioqueue *b43legacy_setup_pioqueue(
struct b43legacy_wldev *dev,
332 struct b43legacy_pioqueue *queue;
341 queue->mmio_base = pio_mmio_base;
342 queue->need_workarounds = (dev->
dev->id.revision < 3);
344 INIT_LIST_HEAD(&queue->txfree);
345 INIT_LIST_HEAD(&queue->txqueue);
346 INIT_LIST_HEAD(&queue->txrunning);
348 (
unsigned long)queue);
354 qsize = b43legacy_read16(dev, queue->mmio_base
358 "operation mode. Please use DMA mode "
359 "(module parameter pio=0).\n");
368 queue->tx_devq_size = qsize;
370 setup_txqueues(queue);
381 static void cancel_transfers(
struct b43legacy_pioqueue *queue)
383 struct b43legacy_pio_txpacket *packet, *tmp_packet;
388 free_txpacket(packet, 0);
390 free_txpacket(packet, 0);
393 static
void b43legacy_destroy_pioqueue(
struct b43legacy_pioqueue *queue)
398 cancel_transfers(queue);
406 if (!b43legacy_using_pio(dev))
410 b43legacy_destroy_pioqueue(pio->
queue3);
412 b43legacy_destroy_pioqueue(pio->
queue2);
414 b43legacy_destroy_pioqueue(pio->
queue1);
416 b43legacy_destroy_pioqueue(pio->
queue0);
423 struct b43legacy_pioqueue *queue;
446 if (dev->
dev->id.revision < 3)
455 b43legacy_destroy_pioqueue(pio->
queue2);
458 b43legacy_destroy_pioqueue(pio->
queue1);
461 b43legacy_destroy_pioqueue(pio->
queue0);
469 struct b43legacy_pioqueue *queue = dev->
pio.queue1;
470 struct b43legacy_pio_txpacket *packet;
475 packet =
list_entry(queue->txfree.next,
struct b43legacy_pio_txpacket,
479 list_move_tail(&packet->list, &queue->txqueue);
483 tasklet_schedule(&queue->txtask);
491 struct b43legacy_pioqueue *queue;
492 struct b43legacy_pio_txpacket *packet;
496 queue = parse_cookie(dev, status->
cookie, &packet);
502 queue->tx_devq_packets--;
503 queue->tx_devq_used -= (packet->skb->len +
506 info = IEEE80211_SKB_CB(packet->skb);
511 retry_limit = info->
status.rates[0].count;
512 ieee80211_tx_info_clear_status(info);
517 if (status->
rts_count > dev->
wl->hw->conf.short_frame_max_tx_count) {
525 info->
status.rates[0].count = 0;
529 info->
status.rates[0].count = retry_limit;
535 info->
status.rates[1].idx = -1;
541 free_txpacket(packet, 1);
545 if (!list_empty(&queue->txqueue))
546 tasklet_schedule(&queue->txtask);
549 static void pio_rx_error(
struct b43legacy_pioqueue *queue,
555 b43legacyerr(queue->dev->wl,
"PIO RX error: %s\n", error);
560 for (i = 0; i < 15; i++) {
569 __le16 preamble[21] = { 0 };
575 int preamble_readwords;
582 B43legacy_PIO_RXCTL_DATAAVAILABLE);
584 for (i = 0; i < 10; i++) {
596 pio_rx_error(queue, 0,
"len > 0x700");
599 if (
unlikely(len == 0 && queue->mmio_base !=
601 pio_rx_error(queue, 0,
"len == 0");
606 preamble_readwords = 14 /
sizeof(
u16);
608 preamble_readwords = 18 /
sizeof(
u16);
609 for (i = 0; i < preamble_readwords; i++) {
631 skb = dev_alloc_skb(len);
633 pio_rx_error(queue, 1,
"OOM");
637 for (i = 0; i < len - 1; i += 2) {
643 skb->
data[len - 1] = (tmp & 0x00FF);
653 | B43legacy_PIO_TXCTL_SUSPEND);
660 & ~B43legacy_PIO_TXCTL_SUSPEND);
662 tasklet_schedule(&queue->txtask);
671 pio->
queue0->tx_frozen = 1;
672 pio->
queue1->tx_frozen = 1;
673 pio->
queue2->tx_frozen = 1;
674 pio->
queue3->tx_frozen = 1;
683 pio->
queue0->tx_frozen = 0;
684 pio->
queue1->tx_frozen = 0;
685 pio->
queue2->tx_frozen = 0;
686 pio->
queue3->tx_frozen = 0;
687 if (!list_empty(&pio->
queue0->txqueue))
688 tasklet_schedule(&pio->
queue0->txtask);
689 if (!list_empty(&pio->
queue1->txqueue))
690 tasklet_schedule(&pio->
queue1->txtask);
691 if (!list_empty(&pio->
queue2->txqueue))
692 tasklet_schedule(&pio->
queue2->txtask);
693 if (!list_empty(&pio->
queue3->txqueue))
694 tasklet_schedule(&pio->
queue3->txtask);