drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c
Extension
.c
Size
25651 bytes
Lines
988
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 (chain->cons_idx == MASKED_IDX(chain, prod_idx + 1)) {
			dev_err(&pdev->dev, "API CMD chain %d is busy, cons_idx: %d, prod_idx: %d\n",
				chain->chain_type, chain->cons_idx,
				chain->prod_idx);
			dump_api_chain_reg(chain);
			return -EBUSY;
		}
		break;

	default:
		dev_err(&pdev->dev, "Unknown API CMD Chain type\n");
		break;
	}

	return 0;
}

/**
 * get_cell_data_size - get the data size of a specific cell type
 * @type: chain type
 *
 * Return the data(Desc + Address) size in the cell
 **/
static u8 get_cell_data_size(enum hinic_api_cmd_chain_type type)
{
	u8 cell_data_size = 0;

	switch (type) {
	case HINIC_API_CMD_WRITE_TO_MGMT_CPU:
		cell_data_size = ALIGN(API_CMD_CELL_DESC_SIZE +
				       API_CMD_CELL_DATA_ADDR_SIZE,
				       API_CMD_CELL_ALIGNMENT);
		break;
	default:
		break;
	}

	return cell_data_size;
}

/**
 * prepare_cell_ctrl - prepare the ctrl of the cell for the command
 * @cell_ctrl: the control of the cell to set the control value into it
 * @data_size: the size of the data in the cell
 **/
static void prepare_cell_ctrl(u64 *cell_ctrl, u16 data_size)
{
	u8 chksum;
	u64 ctrl;

	ctrl =  HINIC_API_CMD_CELL_CTRL_SET(SIZE_8BYTES(data_size), DATA_SZ)  |
		HINIC_API_CMD_CELL_CTRL_SET(RD_DMA_ATTR_DEFAULT, RD_DMA_ATTR) |
		HINIC_API_CMD_CELL_CTRL_SET(WR_DMA_ATTR_DEFAULT, WR_DMA_ATTR);

	chksum = xor_chksum_set(&ctrl);

	ctrl |= HINIC_API_CMD_CELL_CTRL_SET(chksum, XOR_CHKSUM);

	/* The data in the HW should be in Big Endian Format */
	*cell_ctrl = cpu_to_be64(ctrl);
}

/**
 * prepare_api_cmd - prepare API CMD command
 * @chain: chain for the command
 * @dest: destination node on the card that will receive the command
 * @cmd: command data
 * @cmd_size: the command size
 **/
static void prepare_api_cmd(struct hinic_api_cmd_chain *chain,
			    enum hinic_node_id dest,
			    void *cmd, u16 cmd_size)
{
	struct hinic_api_cmd_cell *cell = chain->curr_node;
	struct hinic_api_cmd_cell_ctxt *cell_ctxt;
	struct hinic_hwif *hwif = chain->hwif;
	struct pci_dev *pdev = hwif->pdev;

	cell_ctxt = &chain->cell_ctxt[chain->prod_idx];

	switch (chain->chain_type) {
	case HINIC_API_CMD_WRITE_TO_MGMT_CPU:
		cell->desc = HINIC_API_CMD_DESC_SET(SGE_DATA, API_TYPE)   |
			     HINIC_API_CMD_DESC_SET(API_CMD_WRITE, RD_WR) |
			     HINIC_API_CMD_DESC_SET(NO_BYPASS, MGMT_BYPASS);
		break;

	default:
		dev_err(&pdev->dev, "unknown Chain type\n");
		return;

Annotation

Implementation Notes