drivers/net/ethernet/intel/iavf/iavf_adminq.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/intel/iavf/iavf_adminq.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/intel/iavf/iavf_adminq.c
Extension
.c
Size
25111 bytes
Lines
923
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 (details->callback) {
			IAVF_ADMINQ_CALLBACK cb_func =
					(IAVF_ADMINQ_CALLBACK)details->callback;
			desc_cb = *desc;
			cb_func(hw, &desc_cb);
		}
		memset((void *)desc, 0, sizeof(struct libie_aq_desc));
		memset((void *)details, 0,
		       sizeof(struct iavf_asq_cmd_details));
		ntc++;
		if (ntc == asq->count)
			ntc = 0;
		desc = IAVF_ADMINQ_DESC(*asq, ntc);
		details = IAVF_ADMINQ_DETAILS(*asq, ntc);
	}

	asq->next_to_clean = ntc;

	return IAVF_DESC_UNUSED(asq);
}

/**
 *  iavf_asq_done - check if FW has processed the Admin Send Queue
 *  @hw: pointer to the hw struct
 *
 *  Returns true if the firmware has processed all descriptors on the
 *  admin send queue. Returns false if there are still requests pending.
 **/
bool iavf_asq_done(struct iavf_hw *hw)
{
	/* AQ designers suggest use of head for better
	 * timing reliability than DD bit
	 */
	return rd32(hw, IAVF_VF_ATQH1) == hw->aq.asq.next_to_use;
}

/**
 *  iavf_asq_send_command - send command to Admin Queue
 *  @hw: pointer to the hw struct
 *  @desc: prefilled descriptor describing the command (non DMA mem)
 *  @buff: buffer to use for indirect commands
 *  @buff_size: size of buffer for indirect commands
 *  @cmd_details: pointer to command details structure
 *
 *  This is the main send command driver routine for the Admin Queue send
 *  queue.  It runs the queue, cleans the queue, etc
 **/
enum iavf_status iavf_asq_send_command(struct iavf_hw *hw,
				       struct libie_aq_desc *desc,
				       void *buff, /* can be NULL */
				       u16  buff_size,
				       struct iavf_asq_cmd_details *cmd_details)
{
	struct iavf_dma_mem *dma_buff = NULL;
	struct iavf_asq_cmd_details *details;
	struct libie_aq_desc *desc_on_ring;
	bool cmd_completed = false;
	enum iavf_status status = 0;
	u16  retval = 0;
	u32  val = 0;

	mutex_lock(&hw->aq.asq_mutex);

	if (hw->aq.asq.count == 0) {
		iavf_debug(hw, IAVF_DEBUG_AQ_MESSAGE,
			   "AQTX: Admin queue not initialized.\n");
		status = IAVF_ERR_QUEUE_EMPTY;
		goto asq_send_command_error;
	}

	hw->aq.asq_last_status = LIBIE_AQ_RC_OK;

	val = rd32(hw, IAVF_VF_ATQH1);
	if (val >= hw->aq.num_asq_entries) {
		iavf_debug(hw, IAVF_DEBUG_AQ_MESSAGE,
			   "AQTX: head overrun at %d\n", val);
		status = IAVF_ERR_QUEUE_EMPTY;
		goto asq_send_command_error;
	}

	details = IAVF_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use);
	if (cmd_details) {
		*details = *cmd_details;

		/* If the cmd_details are defined copy the cookie.  The
		 * cpu_to_le32 is not needed here because the data is ignored
		 * by the FW, only used by the driver
		 */
		if (details->cookie) {
			desc->cookie_high =

Annotation

Implementation Notes