drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
Extension
.c
Size
116656 bytes
Lines
4103
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 (desc->flags & cpu_to_le16(LIBIE_AQ_FLAG_RD)) {
			for (i = 0; i < buf_size / 4; i++)
				IXGBE_WRITE_REG(hw, IXGBE_PF_HIBA(i), ((u32 *)buf)[i]);
			if (buf_tail_size)
				IXGBE_WRITE_REG(hw, IXGBE_PF_HIBA(i), buf_tail);
		}
	}

	/* Descriptor is written to specific registers */
	for (i = 0; i < IXGBE_ACI_DESC_SIZE_IN_DWORDS; i++)
		IXGBE_WRITE_REG(hw, IXGBE_PF_HIDA(i), raw_desc[i]);

	/* SW has to set PF_HICR.C bit and clear PF_HICR.SV and
	 * PF_HICR_EV
	 */
	hicr = (IXGBE_READ_REG(hw, IXGBE_PF_HICR) | IXGBE_PF_HICR_C) &
	       ~(IXGBE_PF_HICR_SV | IXGBE_PF_HICR_EV);
	IXGBE_WRITE_REG(hw, IXGBE_PF_HICR, hicr);

#define MAX_SLEEP_RESP_US 1000
#define MAX_TMOUT_RESP_SYNC_US 100000000

	/* Wait for sync Admin Command response */
	read_poll_timeout(IXGBE_READ_REG, hicr,
			  (hicr & IXGBE_PF_HICR_SV) ||
			  !(hicr & IXGBE_PF_HICR_C),
			  MAX_SLEEP_RESP_US, MAX_TMOUT_RESP_SYNC_US, true, hw,
			  IXGBE_PF_HICR);

#define MAX_TMOUT_RESP_ASYNC_US 150000000

	/* Wait for async Admin Command response */
	read_poll_timeout(IXGBE_READ_REG, hicr,
			  (hicr & IXGBE_PF_HICR_EV) ||
			  !(hicr & IXGBE_PF_HICR_C),
			  MAX_SLEEP_RESP_US, MAX_TMOUT_RESP_ASYNC_US, true, hw,
			  IXGBE_PF_HICR);

	/* Read sync Admin Command response */
	if ((hicr & IXGBE_PF_HICR_SV))
		for (i = 0; i < IXGBE_ACI_DESC_SIZE_IN_DWORDS; i++)
			raw_desc[i] = IXGBE_READ_REG(hw, IXGBE_PF_HIDA(i));

	/* Read async Admin Command response */
	if ((hicr & IXGBE_PF_HICR_EV) && !(hicr & IXGBE_PF_HICR_C))
		for (i = 0; i < IXGBE_ACI_DESC_SIZE_IN_DWORDS; i++)
			raw_desc[i] = IXGBE_READ_REG(hw, IXGBE_PF_HIDA_2(i));

	/* Handle timeout and invalid state of HICR register */
	if (hicr & IXGBE_PF_HICR_C)
		return -ETIME;

	if (!(hicr & IXGBE_PF_HICR_SV) && !(hicr & IXGBE_PF_HICR_EV))
		return -EIO;

	/* For every command other than 0x0014 treat opcode mismatch
	 * as an error. Response to 0x0014 command read from HIDA_2
	 * is a descriptor of an event which is expected to contain
	 * different opcode than the command.
	 */
	if (desc->opcode != cpu_to_le16(opcode) &&
	    opcode != ixgbe_aci_opc_get_fw_event)
		return -EIO;

	if (desc->retval) {
		hw->aci.last_status = (enum libie_aq_err)
			le16_to_cpu(desc->retval);
		return -EIO;
	}

	/* Write a response values to a buf */
	if (valid_buf) {
		for (i = 0; i < buf_size / 4; i++)
			((u32 *)buf)[i] = IXGBE_READ_REG(hw, IXGBE_PF_HIBA(i));
		if (buf_tail_size) {
			buf_tail = IXGBE_READ_REG(hw, IXGBE_PF_HIBA(i));
			memcpy(buf + buf_size - buf_tail_size, &buf_tail,
			       buf_tail_size);
		}
	}

	return 0;
}

/**
 * ixgbe_aci_send_cmd - send FW Admin Command to FW Admin Command Interface
 * @hw: pointer to the HW struct
 * @desc: descriptor describing the command
 * @buf: buffer to use for indirect commands (NULL for direct commands)
 * @buf_size: size of buffer for indirect commands (0 for direct commands)

Annotation

Implementation Notes