dpdk/drivers/net/hns3/hns3_regs.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2018-2021 HiSilicon Limited.
   3 */
   4
   5#include <ethdev_pci.h>
   6#include <rte_io.h>
   7
   8#include "hns3_ethdev.h"
   9#include "hns3_logs.h"
  10#include "hns3_rxtx.h"
  11#include "hns3_regs.h"
  12
  13#define MAX_SEPARATE_NUM        4
  14#define SEPARATOR_VALUE         0xFFFFFFFF
  15#define REG_NUM_PER_LINE        4
  16#define REG_LEN_PER_LINE        (REG_NUM_PER_LINE * sizeof(uint32_t))
  17
  18static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *length);
  19
  20static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG,
  21                                          HNS3_CMDQ_TX_ADDR_H_REG,
  22                                          HNS3_CMDQ_TX_DEPTH_REG,
  23                                          HNS3_CMDQ_TX_TAIL_REG,
  24                                          HNS3_CMDQ_TX_HEAD_REG,
  25                                          HNS3_CMDQ_RX_ADDR_L_REG,
  26                                          HNS3_CMDQ_RX_ADDR_H_REG,
  27                                          HNS3_CMDQ_RX_DEPTH_REG,
  28                                          HNS3_CMDQ_RX_TAIL_REG,
  29                                          HNS3_CMDQ_RX_HEAD_REG,
  30                                          HNS3_VECTOR0_CMDQ_SRC_REG,
  31                                          HNS3_CMDQ_INTR_STS_REG,
  32                                          HNS3_CMDQ_INTR_EN_REG,
  33                                          HNS3_CMDQ_INTR_GEN_REG};
  34
  35static const uint32_t common_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
  36                                            HNS3_VECTOR0_OTER_EN_REG,
  37                                            HNS3_MISC_RESET_STS_REG,
  38                                            HNS3_VECTOR0_OTHER_INT_STS_REG,
  39                                            HNS3_GLOBAL_RESET_REG,
  40                                            HNS3_FUN_RST_ING,
  41                                            HNS3_GRO_EN_REG};
  42
  43static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
  44                                               HNS3_FUN_RST_ING,
  45                                               HNS3_GRO_EN_REG};
  46
  47static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
  48                                          HNS3_RING_RX_BASEADDR_H_REG,
  49                                          HNS3_RING_RX_BD_NUM_REG,
  50                                          HNS3_RING_RX_BD_LEN_REG,
  51                                          HNS3_RING_RX_EN_REG,
  52                                          HNS3_RING_RX_MERGE_EN_REG,
  53                                          HNS3_RING_RX_TAIL_REG,
  54                                          HNS3_RING_RX_HEAD_REG,
  55                                          HNS3_RING_RX_FBDNUM_REG,
  56                                          HNS3_RING_RX_OFFSET_REG,
  57                                          HNS3_RING_RX_FBD_OFFSET_REG,
  58                                          HNS3_RING_RX_STASH_REG,
  59                                          HNS3_RING_RX_BD_ERR_REG,
  60                                          HNS3_RING_TX_BASEADDR_L_REG,
  61                                          HNS3_RING_TX_BASEADDR_H_REG,
  62                                          HNS3_RING_TX_BD_NUM_REG,
  63                                          HNS3_RING_TX_EN_REG,
  64                                          HNS3_RING_TX_PRIORITY_REG,
  65                                          HNS3_RING_TX_TC_REG,
  66                                          HNS3_RING_TX_MERGE_EN_REG,
  67                                          HNS3_RING_TX_TAIL_REG,
  68                                          HNS3_RING_TX_HEAD_REG,
  69                                          HNS3_RING_TX_FBDNUM_REG,
  70                                          HNS3_RING_TX_OFFSET_REG,
  71                                          HNS3_RING_TX_EBD_NUM_REG,
  72                                          HNS3_RING_TX_EBD_OFFSET_REG,
  73                                          HNS3_RING_TX_BD_ERR_REG,
  74                                          HNS3_RING_EN_REG};
  75
  76static const uint32_t tqp_intr_reg_addrs[] = {HNS3_TQP_INTR_CTRL_REG,
  77                                              HNS3_TQP_INTR_GL0_REG,
  78                                              HNS3_TQP_INTR_GL1_REG,
  79                                              HNS3_TQP_INTR_GL2_REG,
  80                                              HNS3_TQP_INTR_RL_REG};
  81
  82static const uint32_t hns3_dfx_reg_opcode_list[] = {
  83        HNS3_OPC_DFX_BIOS_COMMON_REG,
  84        HNS3_OPC_DFX_SSU_REG_0,
  85        HNS3_OPC_DFX_SSU_REG_1,
  86        HNS3_OPC_DFX_IGU_EGU_REG,
  87        HNS3_OPC_DFX_RPU_REG_0,
  88        HNS3_OPC_DFX_RPU_REG_1,
  89        HNS3_OPC_DFX_NCSI_REG,
  90        HNS3_OPC_DFX_RTC_REG,
  91        HNS3_OPC_DFX_PPP_REG,
  92        HNS3_OPC_DFX_RCB_REG,
  93        HNS3_OPC_DFX_TQP_REG,
  94        HNS3_OPC_DFX_SSU_REG_2
  95};
  96
  97static int
  98hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
  99                  uint32_t *regs_num_64_bit)
 100{
 101        struct hns3_cmd_desc desc;
 102        int ret;
 103
 104        hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_REG_NUM, true);
 105        ret = hns3_cmd_send(hw, &desc, 1);
 106        if (ret) {
 107                hns3_err(hw, "Query register number cmd failed, ret = %d",
 108                         ret);
 109                return ret;
 110        }
 111
 112        *regs_num_32_bit = rte_le_to_cpu_32(desc.data[0]);
 113        *regs_num_64_bit = rte_le_to_cpu_32(desc.data[1]);
 114
 115        return 0;
 116}
 117
 118static int
 119hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 120{
 121        struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 122        uint32_t cmdq_lines, common_lines, ring_lines, tqp_intr_lines;
 123        uint32_t regs_num_32_bit, regs_num_64_bit;
 124        uint32_t dfx_reg_lines;
 125        uint32_t len;
 126        int ret;
 127
 128        cmdq_lines = sizeof(cmdq_reg_addrs) / REG_LEN_PER_LINE + 1;
 129        if (hns->is_vf)
 130                common_lines =
 131                        sizeof(common_vf_reg_addrs) / REG_LEN_PER_LINE + 1;
 132        else
 133                common_lines = sizeof(common_reg_addrs) / REG_LEN_PER_LINE + 1;
 134        ring_lines = sizeof(ring_reg_addrs) / REG_LEN_PER_LINE + 1;
 135        tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
 136
 137        len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
 138              tqp_intr_lines * hw->num_msi) * REG_NUM_PER_LINE;
 139
 140        if (!hns->is_vf) {
 141                ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
 142                if (ret) {
 143                        hns3_err(hw, "fail to get the number of registers, "
 144                                 "ret = %d.", ret);
 145                        return ret;
 146                }
 147                dfx_reg_lines = regs_num_32_bit * sizeof(uint32_t) /
 148                                        REG_LEN_PER_LINE + 1;
 149                dfx_reg_lines += regs_num_64_bit * sizeof(uint64_t) /
 150                                        REG_LEN_PER_LINE + 1;
 151
 152                ret = hns3_get_dfx_reg_line(hw, &dfx_reg_lines);
 153                if (ret) {
 154                        hns3_err(hw, "fail to get the number of dfx registers, "
 155                                 "ret = %d.", ret);
 156                        return ret;
 157                }
 158                len += dfx_reg_lines * REG_NUM_PER_LINE;
 159        }
 160
 161        *length = len;
 162        return 0;
 163}
 164
 165static int
 166hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 167{
 168#define HNS3_32_BIT_REG_RTN_DATANUM 8
 169#define HNS3_32_BIT_DESC_NODATA_LEN 2
 170        struct hns3_cmd_desc *desc;
 171        uint32_t *reg_val = data;
 172        uint32_t *desc_data;
 173        int cmd_num;
 174        int i, k, n;
 175        int ret;
 176
 177        if (regs_num == 0)
 178                return 0;
 179
 180        cmd_num = DIV_ROUND_UP(regs_num + HNS3_32_BIT_DESC_NODATA_LEN,
 181                               HNS3_32_BIT_REG_RTN_DATANUM);
 182        desc = rte_zmalloc("hns3-32bit-regs",
 183                           sizeof(struct hns3_cmd_desc) * cmd_num, 0);
 184        if (desc == NULL) {
 185                hns3_err(hw, "Failed to allocate %zx bytes needed to "
 186                         "store 32bit regs",
 187                         sizeof(struct hns3_cmd_desc) * cmd_num);
 188                return -ENOMEM;
 189        }
 190
 191        hns3_cmd_setup_basic_desc(&desc[0], HNS3_OPC_QUERY_32_BIT_REG, true);
 192        ret = hns3_cmd_send(hw, desc, cmd_num);
 193        if (ret) {
 194                hns3_err(hw, "Query 32 bit register cmd failed, ret = %d",
 195                         ret);
 196                rte_free(desc);
 197                return ret;
 198        }
 199
 200        for (i = 0; i < cmd_num; i++) {
 201                if (i == 0) {
 202                        desc_data = &desc[i].data[0];
 203                        n = HNS3_32_BIT_REG_RTN_DATANUM -
 204                            HNS3_32_BIT_DESC_NODATA_LEN;
 205                } else {
 206                        desc_data = (uint32_t *)(&desc[i]);
 207                        n = HNS3_32_BIT_REG_RTN_DATANUM;
 208                }
 209                for (k = 0; k < n; k++) {
 210                        *reg_val++ = rte_le_to_cpu_32(*desc_data++);
 211
 212                        regs_num--;
 213                        if (regs_num == 0)
 214                                break;
 215                }
 216        }
 217
 218        rte_free(desc);
 219        return 0;
 220}
 221
 222static int
 223hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 224{
 225#define HNS3_64_BIT_REG_RTN_DATANUM 4
 226#define HNS3_64_BIT_DESC_NODATA_LEN 1
 227        struct hns3_cmd_desc *desc;
 228        uint64_t *reg_val = data;
 229        uint64_t *desc_data;
 230        int cmd_num;
 231        int i, k, n;
 232        int ret;
 233
 234        if (regs_num == 0)
 235                return 0;
 236
 237        cmd_num = DIV_ROUND_UP(regs_num + HNS3_64_BIT_DESC_NODATA_LEN,
 238                               HNS3_64_BIT_REG_RTN_DATANUM);
 239        desc = rte_zmalloc("hns3-64bit-regs",
 240                           sizeof(struct hns3_cmd_desc) * cmd_num, 0);
 241        if (desc == NULL) {
 242                hns3_err(hw, "Failed to allocate %zx bytes needed to "
 243                         "store 64bit regs",
 244                         sizeof(struct hns3_cmd_desc) * cmd_num);
 245                return -ENOMEM;
 246        }
 247
 248        hns3_cmd_setup_basic_desc(&desc[0], HNS3_OPC_QUERY_64_BIT_REG, true);
 249        ret = hns3_cmd_send(hw, desc, cmd_num);
 250        if (ret) {
 251                hns3_err(hw, "Query 64 bit register cmd failed, ret = %d",
 252                         ret);
 253                rte_free(desc);
 254                return ret;
 255        }
 256
 257        for (i = 0; i < cmd_num; i++) {
 258                if (i == 0) {
 259                        desc_data = (uint64_t *)(&desc[i].data[0]);
 260                        n = HNS3_64_BIT_REG_RTN_DATANUM -
 261                            HNS3_64_BIT_DESC_NODATA_LEN;
 262                } else {
 263                        desc_data = (uint64_t *)(&desc[i]);
 264                        n = HNS3_64_BIT_REG_RTN_DATANUM;
 265                }
 266                for (k = 0; k < n; k++) {
 267                        *reg_val++ = rte_le_to_cpu_64(*desc_data++);
 268
 269                        regs_num--;
 270                        if (!regs_num)
 271                                break;
 272                }
 273        }
 274
 275        rte_free(desc);
 276        return 0;
 277}
 278
 279static int
 280hns3_insert_reg_separator(int reg_num, uint32_t *data)
 281{
 282        int separator_num;
 283        int i;
 284
 285        separator_num = MAX_SEPARATE_NUM - reg_num % REG_NUM_PER_LINE;
 286        for (i = 0; i < separator_num; i++)
 287                *data++ = SEPARATOR_VALUE;
 288        return separator_num;
 289}
 290
 291static int
 292hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 293{
 294        struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 295        uint32_t *origin_data_ptr = data;
 296        uint32_t reg_offset;
 297        int reg_num;
 298        int i, j;
 299
 300        /* fetching per-PF registers values from PF PCIe register space */
 301        reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
 302        for (i = 0; i < reg_num; i++)
 303                *data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
 304        data += hns3_insert_reg_separator(reg_num, data);
 305
 306        if (hns->is_vf)
 307                reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
 308        else
 309                reg_num = sizeof(common_reg_addrs) / sizeof(uint32_t);
 310        for (i = 0; i < reg_num; i++)
 311                if (hns->is_vf)
 312                        *data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
 313                else
 314                        *data++ = hns3_read_dev(hw, common_reg_addrs[i]);
 315        data += hns3_insert_reg_separator(reg_num, data);
 316
 317        reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
 318        for (j = 0; j < hw->tqps_num; j++) {
 319                reg_offset = hns3_get_tqp_reg_offset(j);
 320                for (i = 0; i < reg_num; i++)
 321                        *data++ = hns3_read_dev(hw,
 322                                                ring_reg_addrs[i] + reg_offset);
 323                data += hns3_insert_reg_separator(reg_num, data);
 324        }
 325
 326        reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
 327        for (j = 0; j < hw->intr_tqps_num; j++) {
 328                reg_offset = hns3_get_tqp_intr_reg_offset(j);
 329                for (i = 0; i < reg_num; i++)
 330                        *data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
 331                                                reg_offset);
 332                data += hns3_insert_reg_separator(reg_num, data);
 333        }
 334        return data - origin_data_ptr;
 335}
 336
 337static int
 338hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
 339                        uint32_t list_size)
 340{
 341#define HNS3_GET_DFX_REG_BD_NUM_SIZE    4
 342        struct hns3_cmd_desc desc[HNS3_GET_DFX_REG_BD_NUM_SIZE];
 343        uint32_t index, desc_index;
 344        uint32_t bd_num;
 345        uint32_t i;
 346        int ret;
 347
 348        for (i = 0; i < HNS3_GET_DFX_REG_BD_NUM_SIZE - 1; i++) {
 349                hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
 350                desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
 351        }
 352        /* The last BD does not need a next flag */
 353        hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
 354
 355        ret = hns3_cmd_send(hw, desc, HNS3_GET_DFX_REG_BD_NUM_SIZE);
 356        if (ret) {
 357                hns3_err(hw, "fail to get dfx bd num, ret = %d.\n", ret);
 358                return ret;
 359        }
 360
 361        /* The first data in the first BD is a reserved field */
 362        for (i = 1; i <= list_size; i++) {
 363                desc_index = i / HNS3_CMD_DESC_DATA_NUM;
 364                index = i % HNS3_CMD_DESC_DATA_NUM;
 365                bd_num = rte_le_to_cpu_32(desc[desc_index].data[index]);
 366                bd_num_list[i - 1] = bd_num;
 367        }
 368
 369        return 0;
 370}
 371
 372static int
 373hns3_dfx_reg_cmd_send(struct hns3_hw *hw, struct hns3_cmd_desc *desc,
 374                        int bd_num, uint32_t opcode)
 375{
 376        int ret;
 377        int i;
 378
 379        for (i = 0; i < bd_num - 1; i++) {
 380                hns3_cmd_setup_basic_desc(&desc[i], opcode, true);
 381                desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
 382        }
 383        /* The last BD does not need a next flag */
 384        hns3_cmd_setup_basic_desc(&desc[i], opcode, true);
 385
 386        ret = hns3_cmd_send(hw, desc, bd_num);
 387        if (ret) {
 388                hns3_err(hw, "fail to query dfx registers, opcode = 0x%04X, "
 389                         "ret = %d.\n", opcode, ret);
 390        }
 391
 392        return ret;
 393}
 394
 395static int
 396hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 397{
 398        int desc_index;
 399        int reg_num;
 400        int index;
 401        int i;
 402
 403        reg_num = bd_num * HNS3_CMD_DESC_DATA_NUM;
 404        for (i = 0; i < reg_num; i++) {
 405                desc_index = i / HNS3_CMD_DESC_DATA_NUM;
 406                index = i % HNS3_CMD_DESC_DATA_NUM;
 407                *reg++ = desc[desc_index].data[index];
 408        }
 409        reg_num += hns3_insert_reg_separator(reg_num, reg);
 410
 411        return reg_num;
 412}
 413
 414static int
 415hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
 416{
 417        int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 418        uint32_t bd_num_list[opcode_num];
 419        uint32_t bd_num, data_len;
 420        int ret;
 421        int i;
 422
 423        ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
 424        if (ret)
 425                return ret;
 426
 427        for (i = 0; i < opcode_num; i++) {
 428                bd_num = bd_num_list[i];
 429                data_len = bd_num * HNS3_CMD_DESC_DATA_NUM * sizeof(uint32_t);
 430                *lines += data_len / REG_LEN_PER_LINE + 1;
 431        }
 432
 433        return 0;
 434}
 435
 436static int
 437hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 438{
 439        int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 440        uint32_t max_bd_num, bd_num, opcode;
 441        uint32_t bd_num_list[opcode_num];
 442        struct hns3_cmd_desc *cmd_descs;
 443        uint32_t *reg_val = (uint32_t *)*data;
 444        int ret;
 445        int i;
 446
 447        ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
 448        if (ret)
 449                return ret;
 450
 451        max_bd_num = 0;
 452        for (i = 0; i < opcode_num; i++)
 453                max_bd_num = RTE_MAX(bd_num_list[i], max_bd_num);
 454
 455        cmd_descs = rte_zmalloc(NULL, sizeof(*cmd_descs) * max_bd_num, 0);
 456        if (cmd_descs == NULL)
 457                return -ENOMEM;
 458
 459        for (i = 0; i < opcode_num; i++) {
 460                opcode = hns3_dfx_reg_opcode_list[i];
 461                bd_num = bd_num_list[i];
 462                if (bd_num == 0)
 463                        continue;
 464                ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
 465                if (ret)
 466                        break;
 467                reg_val += hns3_dfx_reg_fetch_data(cmd_descs, bd_num, reg_val);
 468        }
 469        rte_free(cmd_descs);
 470        *data = (void *)reg_val;
 471
 472        return ret;
 473}
 474
 475int
 476hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 477{
 478#define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 479        struct hns3_adapter *hns = eth_dev->data->dev_private;
 480        struct hns3_hw *hw = &hns->hw;
 481        uint32_t regs_num_32_bit;
 482        uint32_t regs_num_64_bit;
 483        uint32_t length;
 484        uint32_t *data;
 485        int ret;
 486
 487        ret = hns3_get_regs_length(hw, &length);
 488        if (ret)
 489                return ret;
 490
 491        data = regs->data;
 492        if (data == NULL) {
 493                regs->length = length;
 494                regs->width = sizeof(uint32_t);
 495                return 0;
 496        }
 497
 498        /* Only full register dump is supported */
 499        if (regs->length && regs->length != length)
 500                return -ENOTSUP;
 501
 502        regs->version = hw->fw_version;
 503
 504        /* fetching per-PF registers values from PF PCIe register space */
 505        data += hns3_direct_access_regs(hw, data);
 506
 507        if (hns->is_vf)
 508                return 0;
 509
 510        ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
 511        if (ret) {
 512                hns3_err(hw, "Get register number failed, ret = %d", ret);
 513                return ret;
 514        }
 515
 516        /* fetching PF common registers values from firmware */
 517        ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
 518        if (ret) {
 519                hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
 520                return ret;
 521        }
 522        data += regs_num_32_bit;
 523        data += hns3_insert_reg_separator(regs_num_32_bit, data);
 524
 525        ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
 526        if (ret) {
 527                hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
 528                return ret;
 529        }
 530        data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
 531        data += hns3_insert_reg_separator(regs_num_64_bit *
 532                                          HNS3_64_BIT_REG_SIZE, data);
 533
 534        return  hns3_get_dfx_regs(hw, (void **)&data);
 535}
 536