drivers/net/wireless/ti/wlcore/cmd.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/ti/wlcore/cmd.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/ti/wlcore/cmd.c
Extension
.c
Size
48974 bytes
Lines
2077
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (time_after(jiffies, timeout)) {
			wl1271_error("command complete timeout");
			return -ETIMEDOUT;
		}

		poll_count++;
		if (poll_count < WL1271_CMD_FAST_POLL_COUNT)
			udelay(10);
		else
			msleep(1);

		ret = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR, &intr);
		if (ret < 0)
			return ret;
	}

	/* read back the status code of the command */
	if (res_len == 0)
		res_len = sizeof(struct wl1271_cmd_header);

	ret = wlcore_read(wl, wl->cmd_box_addr, cmd, res_len, false);
	if (ret < 0)
		return ret;

	status = le16_to_cpu(cmd->status);

	ret = wlcore_write_reg(wl, REG_INTERRUPT_ACK,
			       WL1271_ACX_INTR_CMD_COMPLETE);
	if (ret < 0)
		return ret;

	return status;
}

/*
 * send command to fw and return cmd status on success
 * valid_rets contains a bitmap of allowed error codes
 */
static int wlcore_cmd_send_failsafe(struct wl1271 *wl, u16 id, void *buf,
				    size_t len, size_t res_len,
				    unsigned long valid_rets)
{
	int ret = __wlcore_cmd_send(wl, id, buf, len, res_len);

	if (ret < 0)
		goto fail;

	/* success is always a valid status */
	valid_rets |= BIT(CMD_STATUS_SUCCESS);

	if (ret >= MAX_COMMAND_STATUS ||
	    !test_bit(ret, &valid_rets)) {
		wl1271_error("command execute failure %d", ret);
		ret = -EIO;
		goto fail;
	}
	return ret;
fail:
	wl12xx_queue_recovery_work(wl);
	return ret;
}

/*
 * wrapper for wlcore_cmd_send that accept only CMD_STATUS_SUCCESS
 * return 0 on success.
 */
int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
		    size_t res_len)
{
	int ret = wlcore_cmd_send_failsafe(wl, id, buf, len, res_len, 0);

	if (ret < 0)
		return ret;
	return 0;
}
EXPORT_SYMBOL_GPL(wl1271_cmd_send);

/*
 * Poll the mailbox event field until any of the bits in the mask is set or a
 * timeout occurs (WL1271_EVENT_TIMEOUT in msecs)
 */
int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl,
					 u32 mask, bool *timeout)
{
	u32 *events_vector;
	u32 event;
	unsigned long timeout_time;
	u16 poll_count = 0;
	int ret = 0;

Annotation

Implementation Notes