1 // SPDX-License-Identifier: GPL-2.0-or-later
4 Broadcom B43legacy wireless driver
8 Copyright (c) 2005 Michael Buesch <m@bues.ch>
13 #include "b43legacy.h"
18 #include <linux/delay.h>
19 #include <linux/slab.h>
22 static void tx_start(struct b43legacy_pioqueue
*queue
)
24 b43legacy_pio_write(queue
, B43legacy_PIO_TXCTL
,
25 B43legacy_PIO_TXCTL_INIT
);
28 static void tx_octet(struct b43legacy_pioqueue
*queue
,
31 if (queue
->need_workarounds
) {
32 b43legacy_pio_write(queue
, B43legacy_PIO_TXDATA
, octet
);
33 b43legacy_pio_write(queue
, B43legacy_PIO_TXCTL
,
34 B43legacy_PIO_TXCTL_WRITELO
);
36 b43legacy_pio_write(queue
, B43legacy_PIO_TXCTL
,
37 B43legacy_PIO_TXCTL_WRITELO
);
38 b43legacy_pio_write(queue
, B43legacy_PIO_TXDATA
, octet
);
42 static u16
tx_get_next_word(const u8
*txhdr
,
48 unsigned int i
= *pos
;
57 ret
= le16_to_cpu(*((__le16
*)(source
+ i
)));
63 static void tx_data(struct b43legacy_pioqueue
*queue
,
71 if (queue
->need_workarounds
) {
72 data
= tx_get_next_word(txhdr
, packet
,
73 sizeof(struct b43legacy_txhdr_fw3
), &i
);
74 b43legacy_pio_write(queue
, B43legacy_PIO_TXDATA
, data
);
76 b43legacy_pio_write(queue
, B43legacy_PIO_TXCTL
,
77 B43legacy_PIO_TXCTL_WRITELO
|
78 B43legacy_PIO_TXCTL_WRITEHI
);
79 while (i
< octets
- 1) {
80 data
= tx_get_next_word(txhdr
, packet
,
81 sizeof(struct b43legacy_txhdr_fw3
), &i
);
82 b43legacy_pio_write(queue
, B43legacy_PIO_TXDATA
, data
);
85 tx_octet(queue
, packet
[octets
-
86 sizeof(struct b43legacy_txhdr_fw3
) - 1]);
89 static void tx_complete(struct b43legacy_pioqueue
*queue
,
92 if (queue
->need_workarounds
) {
93 b43legacy_pio_write(queue
, B43legacy_PIO_TXDATA
,
94 skb
->data
[skb
->len
- 1]);
95 b43legacy_pio_write(queue
, B43legacy_PIO_TXCTL
,
96 B43legacy_PIO_TXCTL_WRITELO
|
97 B43legacy_PIO_TXCTL_COMPLETE
);
99 b43legacy_pio_write(queue
, B43legacy_PIO_TXCTL
,
100 B43legacy_PIO_TXCTL_COMPLETE
);
103 static u16
generate_cookie(struct b43legacy_pioqueue
*queue
,
104 struct b43legacy_pio_txpacket
*packet
)
109 /* We use the upper 4 bits for the PIO
110 * controller ID and the lower 12 bits
111 * for the packet index (in the cache).
113 switch (queue
->mmio_base
) {
114 case B43legacy_MMIO_PIO1_BASE
:
116 case B43legacy_MMIO_PIO2_BASE
:
119 case B43legacy_MMIO_PIO3_BASE
:
122 case B43legacy_MMIO_PIO4_BASE
:
126 B43legacy_WARN_ON(1);
128 packetindex
= pio_txpacket_getindex(packet
);
129 B43legacy_WARN_ON(!(((u16
)packetindex
& 0xF000) == 0x0000));
130 cookie
|= (u16
)packetindex
;
136 struct b43legacy_pioqueue
*parse_cookie(struct b43legacy_wldev
*dev
,
138 struct b43legacy_pio_txpacket
**packet
)
140 struct b43legacy_pio
*pio
= &dev
->pio
;
141 struct b43legacy_pioqueue
*queue
= NULL
;
144 switch (cookie
& 0xF000) {
158 B43legacy_WARN_ON(1);
160 packetindex
= (cookie
& 0x0FFF);
161 B43legacy_WARN_ON(!(packetindex
>= 0 && packetindex
162 < B43legacy_PIO_MAXTXPACKETS
));
163 *packet
= &(queue
->tx_packets_cache
[packetindex
]);
169 struct b43legacy_txhdr_fw3 txhdr_fw3
;
172 static int pio_tx_write_fragment(struct b43legacy_pioqueue
*queue
,
174 struct b43legacy_pio_txpacket
*packet
,
177 union txhdr_union txhdr_data
;
182 txhdr
= (u8
*)(&txhdr_data
.txhdr_fw3
);
184 B43legacy_WARN_ON(skb_shinfo(skb
)->nr_frags
!= 0);
185 err
= b43legacy_generate_txhdr(queue
->dev
,
186 txhdr
, skb
->data
, skb
->len
,
187 IEEE80211_SKB_CB(skb
),
188 generate_cookie(queue
, packet
));
193 octets
= skb
->len
+ txhdr_size
;
194 if (queue
->need_workarounds
)
196 tx_data(queue
, txhdr
, (u8
*)skb
->data
, octets
);
197 tx_complete(queue
, skb
);
202 static void free_txpacket(struct b43legacy_pio_txpacket
*packet
,
205 struct b43legacy_pioqueue
*queue
= packet
->queue
;
209 dev_kfree_skb_irq(packet
->skb
);
211 dev_kfree_skb(packet
->skb
);
213 list_move(&packet
->list
, &queue
->txfree
);
217 static int pio_tx_packet(struct b43legacy_pio_txpacket
*packet
)
219 struct b43legacy_pioqueue
*queue
= packet
->queue
;
220 struct sk_buff
*skb
= packet
->skb
;
224 octets
= (u16
)skb
->len
+ sizeof(struct b43legacy_txhdr_fw3
);
225 if (queue
->tx_devq_size
< octets
) {
226 b43legacywarn(queue
->dev
->wl
, "PIO queue too small. "
227 "Dropping packet.\n");
228 /* Drop it silently (return success) */
229 free_txpacket(packet
, 1);
232 B43legacy_WARN_ON(queue
->tx_devq_packets
>
233 B43legacy_PIO_MAXTXDEVQPACKETS
);
234 B43legacy_WARN_ON(queue
->tx_devq_used
> queue
->tx_devq_size
);
235 /* Check if there is sufficient free space on the device
236 * TX queue. If not, return and let the TX tasklet
239 if (queue
->tx_devq_packets
== B43legacy_PIO_MAXTXDEVQPACKETS
)
241 if (queue
->tx_devq_used
+ octets
> queue
->tx_devq_size
)
243 /* Now poke the device. */
244 err
= pio_tx_write_fragment(queue
, skb
, packet
,
245 sizeof(struct b43legacy_txhdr_fw3
));
246 if (unlikely(err
== -ENOKEY
)) {
247 /* Drop this packet, as we don't have the encryption key
248 * anymore and must not transmit it unencrypted. */
249 free_txpacket(packet
, 1);
253 /* Account for the packet size.
254 * (We must not overflow the device TX queue)
256 queue
->tx_devq_packets
++;
257 queue
->tx_devq_used
+= octets
;
259 /* Transmission started, everything ok, move the
260 * packet to the txrunning list.
262 list_move_tail(&packet
->list
, &queue
->txrunning
);
267 static void tx_tasklet(struct tasklet_struct
*t
)
269 struct b43legacy_pioqueue
*queue
= from_tasklet(queue
, t
, txtask
);
270 struct b43legacy_wldev
*dev
= queue
->dev
;
272 struct b43legacy_pio_txpacket
*packet
, *tmp_packet
;
276 spin_lock_irqsave(&dev
->wl
->irq_lock
, flags
);
277 if (queue
->tx_frozen
)
279 txctl
= b43legacy_pio_read(queue
, B43legacy_PIO_TXCTL
);
280 if (txctl
& B43legacy_PIO_TXCTL_SUSPEND
)
283 list_for_each_entry_safe(packet
, tmp_packet
, &queue
->txqueue
, list
) {
284 /* Try to transmit the packet. This can fail, if
285 * the device queue is full. In case of failure, the
286 * packet is left in the txqueue.
287 * If transmission succeed, the packet is moved to txrunning.
288 * If it is impossible to transmit the packet, it
291 err
= pio_tx_packet(packet
);
296 spin_unlock_irqrestore(&dev
->wl
->irq_lock
, flags
);
299 static void setup_txqueues(struct b43legacy_pioqueue
*queue
)
301 struct b43legacy_pio_txpacket
*packet
;
304 queue
->nr_txfree
= B43legacy_PIO_MAXTXPACKETS
;
305 for (i
= 0; i
< B43legacy_PIO_MAXTXPACKETS
; i
++) {
306 packet
= &(queue
->tx_packets_cache
[i
]);
308 packet
->queue
= queue
;
309 INIT_LIST_HEAD(&packet
->list
);
311 list_add(&packet
->list
, &queue
->txfree
);
316 struct b43legacy_pioqueue
*b43legacy_setup_pioqueue(struct b43legacy_wldev
*dev
,
319 struct b43legacy_pioqueue
*queue
;
323 queue
= kzalloc(sizeof(*queue
), GFP_KERNEL
);
328 queue
->mmio_base
= pio_mmio_base
;
329 queue
->need_workarounds
= (dev
->dev
->id
.revision
< 3);
331 INIT_LIST_HEAD(&queue
->txfree
);
332 INIT_LIST_HEAD(&queue
->txqueue
);
333 INIT_LIST_HEAD(&queue
->txrunning
);
334 tasklet_setup(&queue
->txtask
, tx_tasklet
);
336 value
= b43legacy_read32(dev
, B43legacy_MMIO_MACCTL
);
337 value
&= ~B43legacy_MACCTL_BE
;
338 b43legacy_write32(dev
, B43legacy_MMIO_MACCTL
, value
);
340 qsize
= b43legacy_read16(dev
, queue
->mmio_base
341 + B43legacy_PIO_TXQBUFSIZE
);
343 b43legacyerr(dev
->wl
, "This card does not support PIO "
344 "operation mode. Please use DMA mode "
345 "(module parameter pio=0).\n");
348 if (qsize
<= B43legacy_PIO_TXQADJUST
) {
349 b43legacyerr(dev
->wl
, "PIO tx device-queue too small (%u)\n",
353 qsize
-= B43legacy_PIO_TXQADJUST
;
354 queue
->tx_devq_size
= qsize
;
356 setup_txqueues(queue
);
367 static void cancel_transfers(struct b43legacy_pioqueue
*queue
)
369 struct b43legacy_pio_txpacket
*packet
, *tmp_packet
;
371 tasklet_kill(&queue
->txtask
);
373 list_for_each_entry_safe(packet
, tmp_packet
, &queue
->txrunning
, list
)
374 free_txpacket(packet
, 0);
375 list_for_each_entry_safe(packet
, tmp_packet
, &queue
->txqueue
, list
)
376 free_txpacket(packet
, 0);
379 static void b43legacy_destroy_pioqueue(struct b43legacy_pioqueue
*queue
)
384 cancel_transfers(queue
);
388 void b43legacy_pio_free(struct b43legacy_wldev
*dev
)
390 struct b43legacy_pio
*pio
;
392 if (!b43legacy_using_pio(dev
))
396 b43legacy_destroy_pioqueue(pio
->queue3
);
398 b43legacy_destroy_pioqueue(pio
->queue2
);
400 b43legacy_destroy_pioqueue(pio
->queue1
);
402 b43legacy_destroy_pioqueue(pio
->queue0
);
406 int b43legacy_pio_init(struct b43legacy_wldev
*dev
)
408 struct b43legacy_pio
*pio
= &dev
->pio
;
409 struct b43legacy_pioqueue
*queue
;
412 queue
= b43legacy_setup_pioqueue(dev
, B43legacy_MMIO_PIO1_BASE
);
417 queue
= b43legacy_setup_pioqueue(dev
, B43legacy_MMIO_PIO2_BASE
);
422 queue
= b43legacy_setup_pioqueue(dev
, B43legacy_MMIO_PIO3_BASE
);
427 queue
= b43legacy_setup_pioqueue(dev
, B43legacy_MMIO_PIO4_BASE
);
432 if (dev
->dev
->id
.revision
< 3)
433 dev
->irq_mask
|= B43legacy_IRQ_PIO_WORKAROUND
;
435 b43legacydbg(dev
->wl
, "PIO initialized\n");
441 b43legacy_destroy_pioqueue(pio
->queue2
);
444 b43legacy_destroy_pioqueue(pio
->queue1
);
447 b43legacy_destroy_pioqueue(pio
->queue0
);
452 int b43legacy_pio_tx(struct b43legacy_wldev
*dev
,
455 struct b43legacy_pioqueue
*queue
= dev
->pio
.queue1
;
456 struct b43legacy_pio_txpacket
*packet
;
458 B43legacy_WARN_ON(queue
->tx_suspended
);
459 B43legacy_WARN_ON(list_empty(&queue
->txfree
));
461 packet
= list_entry(queue
->txfree
.next
, struct b43legacy_pio_txpacket
,
465 list_move_tail(&packet
->list
, &queue
->txqueue
);
467 B43legacy_WARN_ON(queue
->nr_txfree
>= B43legacy_PIO_MAXTXPACKETS
);
469 tasklet_schedule(&queue
->txtask
);
474 void b43legacy_pio_handle_txstatus(struct b43legacy_wldev
*dev
,
475 const struct b43legacy_txstatus
*status
)
477 struct b43legacy_pioqueue
*queue
;
478 struct b43legacy_pio_txpacket
*packet
;
479 struct ieee80211_tx_info
*info
;
482 queue
= parse_cookie(dev
, status
->cookie
, &packet
);
483 B43legacy_WARN_ON(!queue
);
488 queue
->tx_devq_packets
--;
489 queue
->tx_devq_used
-= (packet
->skb
->len
+
490 sizeof(struct b43legacy_txhdr_fw3
));
492 info
= IEEE80211_SKB_CB(packet
->skb
);
494 /* preserve the confiured retry limit before clearing the status
495 * The xmit function has overwritten the rc's value with the actual
496 * retry limit done by the hardware */
497 retry_limit
= info
->status
.rates
[0].count
;
498 ieee80211_tx_info_clear_status(info
);
501 info
->flags
|= IEEE80211_TX_STAT_ACK
;
503 if (status
->rts_count
> dev
->wl
->hw
->conf
.short_frame_max_tx_count
) {
505 * If the short retries (RTS, not data frame) have exceeded
506 * the limit, the hw will not have tried the selected rate,
507 * but will have used the fallback rate instead.
508 * Don't let the rate control count attempts for the selected
509 * rate in this case, otherwise the statistics will be off.
511 info
->status
.rates
[0].count
= 0;
512 info
->status
.rates
[1].count
= status
->frame_count
;
514 if (status
->frame_count
> retry_limit
) {
515 info
->status
.rates
[0].count
= retry_limit
;
516 info
->status
.rates
[1].count
= status
->frame_count
-
520 info
->status
.rates
[0].count
= status
->frame_count
;
521 info
->status
.rates
[1].idx
= -1;
524 ieee80211_tx_status_irqsafe(dev
->wl
->hw
, packet
->skb
);
527 free_txpacket(packet
, 1);
528 /* If there are packets on the txqueue, poke the tasklet
531 if (!list_empty(&queue
->txqueue
))
532 tasklet_schedule(&queue
->txtask
);
535 static void pio_rx_error(struct b43legacy_pioqueue
*queue
,
541 b43legacyerr(queue
->dev
->wl
, "PIO RX error: %s\n", error
);
542 b43legacy_pio_write(queue
, B43legacy_PIO_RXCTL
,
543 B43legacy_PIO_RXCTL_READY
);
545 B43legacy_WARN_ON(queue
->mmio_base
!= B43legacy_MMIO_PIO1_BASE
);
546 for (i
= 0; i
< 15; i
++) {
548 b43legacy_pio_read(queue
, B43legacy_PIO_RXDATA
);
553 void b43legacy_pio_rx(struct b43legacy_pioqueue
*queue
)
555 __le16 preamble
[21] = { 0 };
556 struct b43legacy_rxhdr_fw3
*rxhdr
;
561 int preamble_readwords
;
564 tmp
= b43legacy_pio_read(queue
, B43legacy_PIO_RXCTL
);
565 if (!(tmp
& B43legacy_PIO_RXCTL_DATAAVAILABLE
))
567 b43legacy_pio_write(queue
, B43legacy_PIO_RXCTL
,
568 B43legacy_PIO_RXCTL_DATAAVAILABLE
);
570 for (i
= 0; i
< 10; i
++) {
571 tmp
= b43legacy_pio_read(queue
, B43legacy_PIO_RXCTL
);
572 if (tmp
& B43legacy_PIO_RXCTL_READY
)
576 b43legacydbg(queue
->dev
->wl
, "PIO RX timed out\n");
580 len
= b43legacy_pio_read(queue
, B43legacy_PIO_RXDATA
);
581 if (unlikely(len
> 0x700)) {
582 pio_rx_error(queue
, 0, "len > 0x700");
585 if (unlikely(len
== 0 && queue
->mmio_base
!=
586 B43legacy_MMIO_PIO4_BASE
)) {
587 pio_rx_error(queue
, 0, "len == 0");
590 preamble
[0] = cpu_to_le16(len
);
591 if (queue
->mmio_base
== B43legacy_MMIO_PIO4_BASE
)
592 preamble_readwords
= 14 / sizeof(u16
);
594 preamble_readwords
= 18 / sizeof(u16
);
595 for (i
= 0; i
< preamble_readwords
; i
++) {
596 tmp
= b43legacy_pio_read(queue
, B43legacy_PIO_RXDATA
);
597 preamble
[i
+ 1] = cpu_to_le16(tmp
);
599 rxhdr
= (struct b43legacy_rxhdr_fw3
*)preamble
;
600 macstat
= le16_to_cpu(rxhdr
->mac_status
);
601 if (macstat
& B43legacy_RX_MAC_FCSERR
) {
603 (queue
->mmio_base
== B43legacy_MMIO_PIO1_BASE
),
607 if (queue
->mmio_base
== B43legacy_MMIO_PIO4_BASE
) {
608 /* We received an xmit status. */
609 struct b43legacy_hwtxstatus
*hw
;
611 hw
= (struct b43legacy_hwtxstatus
*)(preamble
+ 1);
612 b43legacy_handle_hwtxstatus(queue
->dev
, hw
);
617 skb
= dev_alloc_skb(len
);
618 if (unlikely(!skb
)) {
619 pio_rx_error(queue
, 1, "OOM");
623 for (i
= 0; i
< len
- 1; i
+= 2) {
624 tmp
= b43legacy_pio_read(queue
, B43legacy_PIO_RXDATA
);
625 *((__le16
*)(skb
->data
+ i
)) = cpu_to_le16(tmp
);
628 tmp
= b43legacy_pio_read(queue
, B43legacy_PIO_RXDATA
);
629 skb
->data
[len
- 1] = (tmp
& 0x00FF);
631 b43legacy_rx(queue
->dev
, skb
, rxhdr
);
634 void b43legacy_pio_tx_suspend(struct b43legacy_pioqueue
*queue
)
636 b43legacy_power_saving_ctl_bits(queue
->dev
, -1, 1);
637 b43legacy_pio_write(queue
, B43legacy_PIO_TXCTL
,
638 b43legacy_pio_read(queue
, B43legacy_PIO_TXCTL
)
639 | B43legacy_PIO_TXCTL_SUSPEND
);
642 void b43legacy_pio_tx_resume(struct b43legacy_pioqueue
*queue
)
644 b43legacy_pio_write(queue
, B43legacy_PIO_TXCTL
,
645 b43legacy_pio_read(queue
, B43legacy_PIO_TXCTL
)
646 & ~B43legacy_PIO_TXCTL_SUSPEND
);
647 b43legacy_power_saving_ctl_bits(queue
->dev
, -1, -1);
648 tasklet_schedule(&queue
->txtask
);
651 void b43legacy_pio_freeze_txqueues(struct b43legacy_wldev
*dev
)
653 struct b43legacy_pio
*pio
;
655 B43legacy_WARN_ON(!b43legacy_using_pio(dev
));
657 pio
->queue0
->tx_frozen
= 1;
658 pio
->queue1
->tx_frozen
= 1;
659 pio
->queue2
->tx_frozen
= 1;
660 pio
->queue3
->tx_frozen
= 1;
663 void b43legacy_pio_thaw_txqueues(struct b43legacy_wldev
*dev
)
665 struct b43legacy_pio
*pio
;
667 B43legacy_WARN_ON(!b43legacy_using_pio(dev
));
669 pio
->queue0
->tx_frozen
= 0;
670 pio
->queue1
->tx_frozen
= 0;
671 pio
->queue2
->tx_frozen
= 0;
672 pio
->queue3
->tx_frozen
= 0;
673 if (!list_empty(&pio
->queue0
->txqueue
))
674 tasklet_schedule(&pio
->queue0
->txtask
);
675 if (!list_empty(&pio
->queue1
->txqueue
))
676 tasklet_schedule(&pio
->queue1
->txtask
);
677 if (!list_empty(&pio
->queue2
->txqueue
))
678 tasklet_schedule(&pio
->queue2
->txtask
);
679 if (!list_empty(&pio
->queue3
->txqueue
))
680 tasklet_schedule(&pio
->queue3
->txtask
);