drivers/net/wireless/ath/ar5523/ar5523.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/ath/ar5523/ar5523.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/ath/ar5523/ar5523.c
Extension
.c
Size
48570 bytes
Lines
1828
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 (olen == 0) {
			/* convention is 0 =>'s one word */
			olen = sizeof(u32);
		}
	} else
		olen = 0;

	if (cmd->odata) {
		if (cmd->olen < olen) {
			ar5523_err(ar, "olen too small %d < %d\n",
				   cmd->olen, olen);
			cmd->olen = 0;
			cmd->res = -EOVERFLOW;
		} else {
			cmd->olen = olen;
			memcpy(cmd->odata, &rp[1], olen);
			cmd->res = 0;
		}
	}

out:
	complete(&cmd->done);
}

static void ar5523_cmd_rx_cb(struct urb *urb)
{
	struct ar5523 *ar = urb->context;
	struct ar5523_tx_cmd *cmd = &ar->tx_cmd;
	struct ar5523_cmd_hdr *hdr = ar->rx_cmd_buf;
	int dlen;
	u32 code, hdrlen;

	if (urb->status) {
		if (urb->status != -ESHUTDOWN)
			ar5523_err(ar, "RX USB error %d.\n", urb->status);
		goto skip;
	}

	if (urb->actual_length < sizeof(struct ar5523_cmd_hdr)) {
		ar5523_err(ar, "RX USB too short.\n");
		goto skip;
	}

	ar5523_dbg(ar, "%s code %02x priv %d\n", __func__,
		   be32_to_cpu(hdr->code) & 0xff, hdr->priv);

	code = be32_to_cpu(hdr->code);
	hdrlen = be32_to_cpu(hdr->len);

	switch (code & 0xff) {
	default:
		/* reply to a read command */
		if (hdr->priv != AR5523_CMD_ID) {
			ar5523_err(ar, "Unexpected command id: %02x\n",
				   code & 0xff);
			goto skip;
		}
		ar5523_read_reply(ar, hdr, cmd);
		break;

	case WDCMSG_DEVICE_AVAIL:
		ar5523_dbg(ar, "WDCMSG_DEVICE_AVAIL\n");
		cmd->res = 0;
		cmd->olen = 0;
		complete(&cmd->done);
		break;

	case WDCMSG_SEND_COMPLETE:
		ar5523_dbg(ar, "WDCMSG_SEND_COMPLETE: %d pending\n",
			atomic_read(&ar->tx_nr_pending));
		if (!test_bit(AR5523_HW_UP, &ar->flags))
			ar5523_dbg(ar, "Unexpected WDCMSG_SEND_COMPLETE\n");
		else {
			mod_timer(&ar->tx_wd_timer,
				  jiffies + AR5523_TX_WD_TIMEOUT);
			ar5523_data_tx_pkt_put(ar);

		}
		break;

	case WDCMSG_TARGET_START:
		/* This command returns a bogus id so it needs special
		   handling */
		dlen = hdrlen - sizeof(*hdr);
		if (dlen != (int)sizeof(u32)) {
			ar5523_err(ar, "Invalid reply to WDCMSG_TARGET_START");
			return;
		}
		if (!cmd->odata) {
			ar5523_err(ar, "Unexpected WDCMSG_TARGET_START reply");

Annotation

Implementation Notes