drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c
Extension
.c
Size
5133 bytes
Lines
167
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

struct hclgevf_reg_tlv {
	u16 tag;
	u16 len;
};

struct hclgevf_reg_header {
	u64 magic_number;
	u8 is_vf;
	u8 rsv[7];
};

#pragma pack()

#define HCLGEVF_REG_TLV_SIZE		sizeof(struct hclgevf_reg_tlv)
#define HCLGEVF_REG_HEADER_SIZE		sizeof(struct hclgevf_reg_header)
#define HCLGEVF_REG_TLV_SPACE		(sizeof(struct hclgevf_reg_tlv) / sizeof(u32))
#define HCLGEVF_REG_HEADER_SPACE	(sizeof(struct hclgevf_reg_header) / sizeof(u32))
#define HCLGEVF_REG_MAGIC_NUMBER	0x686e733372656773 /* meaning is hns3regs */

static u32 hclgevf_reg_get_header(void *data)
{
	struct hclgevf_reg_header *header = data;

	header->magic_number = HCLGEVF_REG_MAGIC_NUMBER;
	header->is_vf = 0x1;

	return HCLGEVF_REG_HEADER_SPACE;
}

static u32 hclgevf_reg_get_tlv(u32 tag, u32 regs_num, void *data)
{
	struct hclgevf_reg_tlv *tlv = data;

	tlv->tag = tag;
	tlv->len = regs_num * sizeof(u32) + HCLGEVF_REG_TLV_SIZE;

	return HCLGEVF_REG_TLV_SPACE;
}

int hclgevf_get_regs_len(struct hnae3_handle *handle)
{
	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
	int cmdq_len, common_len, ring_len, tqp_intr_len;

	cmdq_len = HCLGEVF_REG_TLV_SIZE + sizeof(cmdq_reg_addr_list);
	common_len = HCLGEVF_REG_TLV_SIZE + sizeof(common_reg_addr_list);
	ring_len = HCLGEVF_REG_TLV_SIZE + sizeof(ring_reg_addr_list);
	tqp_intr_len = HCLGEVF_REG_TLV_SIZE + sizeof(tqp_intr_reg_addr_list);

	/* return the total length of all register values */
	return HCLGEVF_REG_HEADER_SIZE + cmdq_len + common_len +
	       tqp_intr_len * (hdev->num_msi_used - 1) +
	       ring_len * hdev->num_tqps;
}

void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version,
		      void *data)
{
#define HCLGEVF_RING_INT_REG_OFFSET	0x4

	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
	struct hnae3_queue *tqp;
	int i, j, reg_num;
	u32 *reg = data;

	*version = hdev->fw_version;
	reg += hclgevf_reg_get_header(reg);

	/* fetching per-VF registers values from VF PCIe register space */
	reg_num = ARRAY_SIZE(cmdq_reg_addr_list);
	reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_CMDQ, reg_num, reg);
	for (i = 0; i < reg_num; i++)
		*reg++ = hclgevf_read_dev(&hdev->hw, cmdq_reg_addr_list[i]);

	reg_num = ARRAY_SIZE(common_reg_addr_list);
	reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_COMMON, reg_num, reg);
	for (i = 0; i < reg_num; i++)
		*reg++ = hclgevf_read_dev(&hdev->hw, common_reg_addr_list[i]);

	reg_num = ARRAY_SIZE(ring_reg_addr_list);
	for (j = 0; j < hdev->num_tqps; j++) {
		reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_num, reg);
		tqp = &hdev->htqp[j].q;
		for (i = 0; i < reg_num; i++)
			*reg++ = readl_relaxed(tqp->io_base -
					       HCLGEVF_TQP_REG_OFFSET +
					       ring_reg_addr_list[i]);
	}

	reg_num = ARRAY_SIZE(tqp_intr_reg_addr_list);

Annotation

Implementation Notes