drivers/net/wireless/broadcom/b43legacy/pio.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/broadcom/b43legacy/pio.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/broadcom/b43legacy/pio.c
Extension
.c
Size
17252 bytes
Lines
682
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (status->frame_count > retry_limit) {
			info->status.rates[0].count = retry_limit;
			info->status.rates[1].count = status->frame_count -
					retry_limit;

		} else {
			info->status.rates[0].count = status->frame_count;
			info->status.rates[1].idx = -1;
		}
	}
	ieee80211_tx_status_irqsafe(dev->wl->hw, packet->skb);
	packet->skb = NULL;

	free_txpacket(packet, 1);
	/* If there are packets on the txqueue, poke the tasklet
	 * to transmit them.
	 */
	if (!list_empty(&queue->txqueue))
		tasklet_schedule(&queue->txtask);
}

static void pio_rx_error(struct b43legacy_pioqueue *queue,
			 int clear_buffers,
			 const char *error)
{
	int i;

	b43legacyerr(queue->dev->wl, "PIO RX error: %s\n", error);
	b43legacy_pio_write(queue, B43legacy_PIO_RXCTL,
			    B43legacy_PIO_RXCTL_READY);
	if (clear_buffers) {
		B43legacy_WARN_ON(queue->mmio_base != B43legacy_MMIO_PIO1_BASE);
		for (i = 0; i < 15; i++) {
			/* Dummy read. */
			b43legacy_pio_read(queue, B43legacy_PIO_RXDATA);
		}
	}
}

void b43legacy_pio_rx(struct b43legacy_pioqueue *queue)
{
	__le16 preamble[21] = { 0 };
	struct b43legacy_rxhdr_fw3 *rxhdr;
	u16 tmp;
	u16 len;
	u16 macstat;
	int i;
	int preamble_readwords;
	struct sk_buff *skb;

	tmp = b43legacy_pio_read(queue, B43legacy_PIO_RXCTL);
	if (!(tmp & B43legacy_PIO_RXCTL_DATAAVAILABLE))
		return;
	b43legacy_pio_write(queue, B43legacy_PIO_RXCTL,
			    B43legacy_PIO_RXCTL_DATAAVAILABLE);

	for (i = 0; i < 10; i++) {
		tmp = b43legacy_pio_read(queue, B43legacy_PIO_RXCTL);
		if (tmp & B43legacy_PIO_RXCTL_READY)
			goto data_ready;
		udelay(10);
	}
	b43legacydbg(queue->dev->wl, "PIO RX timed out\n");
	return;
data_ready:

	len = b43legacy_pio_read(queue, B43legacy_PIO_RXDATA);
	if (unlikely(len > 0x700)) {
		pio_rx_error(queue, 0, "len > 0x700");
		return;
	}
	if (unlikely(len == 0 && queue->mmio_base !=
		     B43legacy_MMIO_PIO4_BASE)) {
		pio_rx_error(queue, 0, "len == 0");
		return;
	}
	preamble[0] = cpu_to_le16(len);
	if (queue->mmio_base == B43legacy_MMIO_PIO4_BASE)
		preamble_readwords = 14 / sizeof(u16);
	else
		preamble_readwords = 18 / sizeof(u16);
	for (i = 0; i < preamble_readwords; i++) {
		tmp = b43legacy_pio_read(queue, B43legacy_PIO_RXDATA);
		preamble[i + 1] = cpu_to_le16(tmp);
	}
	rxhdr = (struct b43legacy_rxhdr_fw3 *)preamble;
	macstat = le16_to_cpu(rxhdr->mac_status);
	if (macstat & B43legacy_RX_MAC_FCSERR) {
		pio_rx_error(queue,
			     (queue->mmio_base == B43legacy_MMIO_PIO1_BASE),

Annotation

Implementation Notes