Linux Audio

Check our new training course

Loading...
  1// SPDX-License-Identifier: GPL-2.0+
  2// Copyright (c) 2023 Hisilicon Limited.
  3
  4#include "hclgevf_main.h"
  5#include "hclgevf_regs.h"
  6#include "hnae3.h"
  7
  8static const u32 cmdq_reg_addr_list[] = {HCLGE_COMM_NIC_CSQ_BASEADDR_L_REG,
  9					 HCLGE_COMM_NIC_CSQ_BASEADDR_H_REG,
 10					 HCLGE_COMM_NIC_CSQ_DEPTH_REG,
 11					 HCLGE_COMM_NIC_CSQ_TAIL_REG,
 12					 HCLGE_COMM_NIC_CSQ_HEAD_REG,
 13					 HCLGE_COMM_NIC_CRQ_BASEADDR_L_REG,
 14					 HCLGE_COMM_NIC_CRQ_BASEADDR_H_REG,
 15					 HCLGE_COMM_NIC_CRQ_DEPTH_REG,
 16					 HCLGE_COMM_NIC_CRQ_TAIL_REG,
 17					 HCLGE_COMM_NIC_CRQ_HEAD_REG,
 18					 HCLGE_COMM_VECTOR0_CMDQ_SRC_REG,
 19					 HCLGE_COMM_VECTOR0_CMDQ_STATE_REG,
 20					 HCLGE_COMM_CMDQ_INTR_EN_REG,
 21					 HCLGE_COMM_CMDQ_INTR_GEN_REG};
 22
 23static const u32 common_reg_addr_list[] = {HCLGEVF_MISC_VECTOR_REG_BASE,
 24					   HCLGEVF_RST_ING,
 25					   HCLGEVF_GRO_EN_REG};
 26
 27static const u32 ring_reg_addr_list[] = {HCLGEVF_RING_RX_ADDR_L_REG,
 28					 HCLGEVF_RING_RX_ADDR_H_REG,
 29					 HCLGEVF_RING_RX_BD_NUM_REG,
 30					 HCLGEVF_RING_RX_BD_LENGTH_REG,
 31					 HCLGEVF_RING_RX_MERGE_EN_REG,
 32					 HCLGEVF_RING_RX_TAIL_REG,
 33					 HCLGEVF_RING_RX_HEAD_REG,
 34					 HCLGEVF_RING_RX_FBD_NUM_REG,
 35					 HCLGEVF_RING_RX_OFFSET_REG,
 36					 HCLGEVF_RING_RX_FBD_OFFSET_REG,
 37					 HCLGEVF_RING_RX_STASH_REG,
 38					 HCLGEVF_RING_RX_BD_ERR_REG,
 39					 HCLGEVF_RING_TX_ADDR_L_REG,
 40					 HCLGEVF_RING_TX_ADDR_H_REG,
 41					 HCLGEVF_RING_TX_BD_NUM_REG,
 42					 HCLGEVF_RING_TX_PRIORITY_REG,
 43					 HCLGEVF_RING_TX_TC_REG,
 44					 HCLGEVF_RING_TX_MERGE_EN_REG,
 45					 HCLGEVF_RING_TX_TAIL_REG,
 46					 HCLGEVF_RING_TX_HEAD_REG,
 47					 HCLGEVF_RING_TX_FBD_NUM_REG,
 48					 HCLGEVF_RING_TX_OFFSET_REG,
 49					 HCLGEVF_RING_TX_EBD_NUM_REG,
 50					 HCLGEVF_RING_TX_EBD_OFFSET_REG,
 51					 HCLGEVF_RING_TX_BD_ERR_REG,
 52					 HCLGEVF_RING_EN_REG};
 53
 54static const u32 tqp_intr_reg_addr_list[] = {HCLGEVF_TQP_INTR_CTRL_REG,
 55					     HCLGEVF_TQP_INTR_GL0_REG,
 56					     HCLGEVF_TQP_INTR_GL1_REG,
 57					     HCLGEVF_TQP_INTR_GL2_REG,
 58					     HCLGEVF_TQP_INTR_RL_REG};
 59
 60enum hclgevf_reg_tag {
 61	HCLGEVF_REG_TAG_CMDQ = 0,
 62	HCLGEVF_REG_TAG_COMMON,
 63	HCLGEVF_REG_TAG_RING,
 64	HCLGEVF_REG_TAG_TQP_INTR,
 65};
 66
 67#pragma pack(4)
 68struct hclgevf_reg_tlv {
 69	u16 tag;
 70	u16 len;
 71};
 72
 73struct hclgevf_reg_header {
 74	u64 magic_number;
 75	u8 is_vf;
 76	u8 rsv[7];
 77};
 78
 79#pragma pack()
 80
 81#define HCLGEVF_REG_TLV_SIZE		sizeof(struct hclgevf_reg_tlv)
 82#define HCLGEVF_REG_HEADER_SIZE		sizeof(struct hclgevf_reg_header)
 83#define HCLGEVF_REG_TLV_SPACE		(sizeof(struct hclgevf_reg_tlv) / sizeof(u32))
 84#define HCLGEVF_REG_HEADER_SPACE	(sizeof(struct hclgevf_reg_header) / sizeof(u32))
 85#define HCLGEVF_REG_MAGIC_NUMBER	0x686e733372656773 /* meaning is hns3regs */
 86
 87static u32 hclgevf_reg_get_header(void *data)
 88{
 89	struct hclgevf_reg_header *header = data;
 90
 91	header->magic_number = HCLGEVF_REG_MAGIC_NUMBER;
 92	header->is_vf = 0x1;
 93
 94	return HCLGEVF_REG_HEADER_SPACE;
 95}
 96
 97static u32 hclgevf_reg_get_tlv(u32 tag, u32 regs_num, void *data)
 98{
 99	struct hclgevf_reg_tlv *tlv = data;
100
101	tlv->tag = tag;
102	tlv->len = regs_num * sizeof(u32) + HCLGEVF_REG_TLV_SIZE;
103
104	return HCLGEVF_REG_TLV_SPACE;
105}
106
107int hclgevf_get_regs_len(struct hnae3_handle *handle)
108{
109	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
110	int cmdq_len, common_len, ring_len, tqp_intr_len;
111
112	cmdq_len = HCLGEVF_REG_TLV_SIZE + sizeof(cmdq_reg_addr_list);
113	common_len = HCLGEVF_REG_TLV_SIZE + sizeof(common_reg_addr_list);
114	ring_len = HCLGEVF_REG_TLV_SIZE + sizeof(ring_reg_addr_list);
115	tqp_intr_len = HCLGEVF_REG_TLV_SIZE + sizeof(tqp_intr_reg_addr_list);
116
117	/* return the total length of all register values */
118	return HCLGEVF_REG_HEADER_SIZE + cmdq_len + common_len +
119	       tqp_intr_len * (hdev->num_msi_used - 1) +
120	       ring_len * hdev->num_tqps;
121}
122
123void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version,
124		      void *data)
125{
126#define HCLGEVF_RING_REG_OFFSET		0x200
127#define HCLGEVF_RING_INT_REG_OFFSET	0x4
128
129	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
130	int i, j, reg_um;
131	u32 *reg = data;
132
133	*version = hdev->fw_version;
134	reg += hclgevf_reg_get_header(reg);
135
136	/* fetching per-VF registers values from VF PCIe register space */
137	reg_um = sizeof(cmdq_reg_addr_list) / sizeof(u32);
138	reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_CMDQ, reg_um, reg);
139	for (i = 0; i < reg_um; i++)
140		*reg++ = hclgevf_read_dev(&hdev->hw, cmdq_reg_addr_list[i]);
141
142	reg_um = sizeof(common_reg_addr_list) / sizeof(u32);
143	reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_COMMON, reg_um, reg);
144	for (i = 0; i < reg_um; i++)
145		*reg++ = hclgevf_read_dev(&hdev->hw, common_reg_addr_list[i]);
146
147	reg_um = sizeof(ring_reg_addr_list) / sizeof(u32);
148	for (j = 0; j < hdev->num_tqps; j++) {
149		reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_um, reg);
150		for (i = 0; i < reg_um; i++)
151			*reg++ = hclgevf_read_dev(&hdev->hw,
152						  ring_reg_addr_list[i] +
153						  HCLGEVF_RING_REG_OFFSET * j);
154	}
155
156	reg_um = sizeof(tqp_intr_reg_addr_list) / sizeof(u32);
157	for (j = 0; j < hdev->num_msi_used - 1; j++) {
158		reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_TQP_INTR, reg_um, reg);
159		for (i = 0; i < reg_um; i++)
160			*reg++ = hclgevf_read_dev(&hdev->hw,
161						  tqp_intr_reg_addr_list[i] +
162						  HCLGEVF_RING_INT_REG_OFFSET * j);
163	}
164}