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 8 static 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 23 static const u32 common_reg_addr_list[] = {HCLGEVF_MISC_VECTOR_REG_BASE, 24 HCLGEVF_RST_ING, 25 HCLGEVF_GRO_EN_REG}; 26 27 static 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 54 static 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 60 enum 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) 68 struct hclgevf_reg_tlv { 69 u16 tag; 70 u16 len; 71 }; 72 73 struct 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 87 static 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 97 static 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 107 int 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 123 void 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 = ARRAY_SIZE(cmdq_reg_addr_list); 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 = ARRAY_SIZE(common_reg_addr_list); 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 = ARRAY_SIZE(ring_reg_addr_list); 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 = ARRAY_SIZE(tqp_intr_reg_addr_list); 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 } 165