dpdk/drivers/net/hinic/base/hinic_pmd_cfg.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2017 Huawei Technologies Co., Ltd
   3 */
   4
   5#include "hinic_compat.h"
   6#include "hinic_pmd_hwdev.h"
   7#include "hinic_pmd_hwif.h"
   8#include "hinic_pmd_mgmt.h"
   9#include "hinic_pmd_eqs.h"
  10#include "hinic_pmd_cfg.h"
  11#include "hinic_pmd_mbox.h"
  12
  13bool hinic_support_nic(struct hinic_hwdev *hwdev, struct nic_service_cap *cap)
  14{
  15        if (!IS_NIC_TYPE(hwdev))
  16                return false;
  17
  18        if (cap)
  19                memcpy(cap, &hwdev->cfg_mgmt->svc_cap.nic_cap, sizeof(*cap));
  20
  21        return true;
  22}
  23
  24static void hinic_parse_shared_res_cap(struct service_cap *cap,
  25                                        struct hinic_dev_cap *dev_cap,
  26                                        __rte_unused enum func_type type)
  27{
  28        struct host_shared_resource_cap *shared_cap = &cap->shared_res_cap;
  29
  30        shared_cap->host_pctxs = dev_cap->host_pctx_num;
  31
  32        if (dev_cap->host_sf_en)
  33                cap->sf_en = true;
  34        else
  35                cap->sf_en = false;
  36
  37        shared_cap->host_cctxs = dev_cap->host_ccxt_num;
  38        shared_cap->host_scqs = dev_cap->host_scq_num;
  39        shared_cap->host_srqs = dev_cap->host_srq_num;
  40        shared_cap->host_mpts = dev_cap->host_mpt_num;
  41
  42        PMD_DRV_LOG(INFO, "Get share resource capability:");
  43        PMD_DRV_LOG(INFO, "host_pctxs: 0x%x, host_cctxs: 0x%x, host_scqs: 0x%x, host_srqs: 0x%x, host_mpts: 0x%x",
  44                    shared_cap->host_pctxs, shared_cap->host_cctxs,
  45                    shared_cap->host_scqs, shared_cap->host_srqs,
  46                    shared_cap->host_mpts);
  47}
  48
  49static void hinic_parse_l2nic_res_cap(struct service_cap *cap,
  50                                struct hinic_dev_cap *dev_cap,
  51                                enum func_type type)
  52{
  53        struct nic_service_cap *nic_cap = &cap->nic_cap;
  54
  55        if (type == TYPE_PF || type == TYPE_PPF) {
  56                nic_cap->max_sqs = dev_cap->nic_max_sq + 1;
  57                nic_cap->max_rqs = dev_cap->nic_max_rq + 1;
  58                nic_cap->vf_max_sqs = dev_cap->nic_vf_max_sq + 1;
  59                nic_cap->vf_max_rqs = dev_cap->nic_vf_max_rq + 1;
  60        } else {
  61                nic_cap->max_sqs = dev_cap->nic_max_sq;
  62                nic_cap->max_rqs = dev_cap->nic_max_rq;
  63                nic_cap->vf_max_sqs = 0;
  64                nic_cap->vf_max_rqs = 0;
  65        }
  66
  67        if (dev_cap->nic_lro_en)
  68                nic_cap->lro_en = true;
  69        else
  70                nic_cap->lro_en = false;
  71
  72        nic_cap->lro_sz = dev_cap->nic_lro_sz;
  73        nic_cap->tso_sz = dev_cap->nic_tso_sz;
  74
  75        PMD_DRV_LOG(INFO, "Get l2nic resource capability:");
  76        PMD_DRV_LOG(INFO, "max_sqs: 0x%x, max_rqs: 0x%x, vf_max_sqs: 0x%x, vf_max_rqs: 0x%x",
  77                    nic_cap->max_sqs, nic_cap->max_rqs,
  78                    nic_cap->vf_max_sqs, nic_cap->vf_max_rqs);
  79}
  80
  81u16 hinic_func_max_qnum(void *hwdev)
  82{
  83        struct hinic_hwdev *dev = hwdev;
  84
  85        return dev->cfg_mgmt->svc_cap.max_sqs;
  86}
  87
  88int init_cfg_mgmt(struct hinic_hwdev *hwdev)
  89{
  90        struct cfg_mgmt_info *cfg_mgmt;
  91
  92        cfg_mgmt = kzalloc(sizeof(*cfg_mgmt), GFP_KERNEL);
  93        if (!cfg_mgmt)
  94                return -ENOMEM;
  95
  96        hwdev->cfg_mgmt = cfg_mgmt;
  97        cfg_mgmt->hwdev = hwdev;
  98
  99        return 0;
 100}
 101
 102void free_cfg_mgmt(struct hinic_hwdev *hwdev)
 103{
 104        kfree(hwdev->cfg_mgmt);
 105        hwdev->cfg_mgmt = NULL;
 106}
 107
 108static void hinic_parse_pub_res_cap(struct service_cap *cap,
 109                              struct hinic_dev_cap *dev_cap,
 110                              enum func_type type)
 111{
 112        cap->host_id = dev_cap->host_id;
 113        cap->ep_id = dev_cap->ep_id;
 114        cap->max_cos_id = dev_cap->max_cos_id;
 115        cap->valid_cos_bitmap = dev_cap->valid_cos_bitmap;
 116        cap->er_id = dev_cap->er_id;
 117        cap->port_id = dev_cap->port_id;
 118
 119        if (type == TYPE_PF || type == TYPE_PPF) {
 120                cap->max_vf = dev_cap->max_vf;
 121                cap->pf_num = dev_cap->pf_num;
 122                cap->pf_id_start = dev_cap->pf_id_start;
 123                cap->vf_num = dev_cap->vf_num;
 124                cap->vf_id_start = dev_cap->vf_id_start;
 125                cap->max_sqs = dev_cap->nic_max_sq + 1;
 126                cap->max_rqs = dev_cap->nic_max_rq + 1;
 127        } else {
 128                cap->max_vf = 0;
 129                cap->max_sqs = dev_cap->nic_max_sq;
 130                cap->max_rqs = dev_cap->nic_max_rq;
 131        }
 132
 133        cap->chip_svc_type = dev_cap->svc_cap_en;
 134        cap->host_total_function = dev_cap->host_total_func;
 135        cap->host_oq_id_mask_val = dev_cap->host_oq_id_mask_val;
 136
 137        PMD_DRV_LOG(INFO, "Get public resource capability:");
 138        PMD_DRV_LOG(INFO, "host_id: 0x%x, ep_id: 0x%x, intr_type: 0x%x, "
 139                    "max_cos_id: 0x%x, cos_bitmap: 0x%x, er_id: 0x%x, port_id: 0x%x",
 140                    cap->host_id, cap->ep_id, cap->intr_chip_en,
 141                    cap->max_cos_id, cap->valid_cos_bitmap, cap->er_id,
 142                    cap->port_id);
 143        PMD_DRV_LOG(INFO, "host_total_function: 0x%x, host_oq_id_mask_val: 0x%x, max_vf: 0x%x",
 144                    cap->host_total_function, cap->host_oq_id_mask_val,
 145                    cap->max_vf);
 146        PMD_DRV_LOG(INFO, "chip_svc_type: 0x%x", cap->chip_svc_type);
 147        PMD_DRV_LOG(INFO, "pf_num: 0x%x, pf_id_start: 0x%x, vf_num: 0x%x, vf_id_start: 0x%x",
 148                    cap->pf_num, cap->pf_id_start,
 149                    cap->vf_num, cap->vf_id_start);
 150}
 151
 152static void parse_dev_cap(struct hinic_hwdev *dev,
 153                          struct hinic_dev_cap *dev_cap,
 154                          enum func_type type)
 155{
 156        struct service_cap *cap = &dev->cfg_mgmt->svc_cap;
 157
 158        /* Public resource */
 159        hinic_parse_pub_res_cap(cap, dev_cap, type);
 160
 161        /* PPF managed dynamic resource */
 162        if (type == TYPE_PPF)
 163                hinic_parse_shared_res_cap(cap, dev_cap, type);
 164
 165        /* L2 NIC resource */
 166        if (IS_NIC_TYPE(dev))
 167                hinic_parse_l2nic_res_cap(cap, dev_cap, type);
 168}
 169
 170static int get_cap_from_fw(struct hinic_hwdev *dev, enum func_type type)
 171{
 172        int err;
 173        u16 in_len, out_len;
 174        struct hinic_dev_cap dev_cap;
 175
 176        memset(&dev_cap, 0, sizeof(dev_cap));
 177        in_len = sizeof(dev_cap);
 178        out_len = in_len;
 179        dev_cap.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 180        err = hinic_msg_to_mgmt_sync(dev, HINIC_MOD_CFGM, HINIC_CFG_NIC_CAP,
 181                                     &dev_cap, in_len, &dev_cap, &out_len, 0);
 182        if (err || dev_cap.mgmt_msg_head.status || !out_len) {
 183                PMD_DRV_LOG(ERR, "Get capability from FW failed, err: %d, status: %d, out_len: %d",
 184                        err, dev_cap.mgmt_msg_head.status, out_len);
 185                return -EIO;
 186        }
 187
 188        parse_dev_cap(dev, &dev_cap, type);
 189        return 0;
 190}
 191
 192static int get_cap_from_pf(struct hinic_hwdev *dev, enum func_type type)
 193{
 194        int err;
 195        u16 in_len, out_len;
 196        struct hinic_dev_cap dev_cap;
 197
 198        memset(&dev_cap, 0, sizeof(dev_cap));
 199        in_len = sizeof(dev_cap);
 200        out_len = in_len;
 201        err = hinic_mbox_to_pf(dev, HINIC_MOD_CFGM, HINIC_CFG_MBOX_CAP,
 202                               &dev_cap, in_len, &dev_cap, &out_len,
 203                               CFG_MAX_CMD_TIMEOUT);
 204        if (err || dev_cap.mgmt_msg_head.status || !out_len) {
 205                PMD_DRV_LOG(ERR, "Get capability from PF failed, err: %d, status: %d, out_len: %d",
 206                                err, dev_cap.mgmt_msg_head.status, out_len);
 207                return -EIO;
 208        }
 209
 210        parse_dev_cap(dev, &dev_cap, type);
 211        return 0;
 212}
 213
 214static int get_dev_cap(struct hinic_hwdev *dev)
 215{
 216        int err;
 217        enum func_type type = HINIC_FUNC_TYPE(dev);
 218
 219        switch (type) {
 220        case TYPE_PF:
 221        case TYPE_PPF:
 222                err = get_cap_from_fw(dev, type);
 223                if (err) {
 224                        PMD_DRV_LOG(ERR, "Get PF/PPF capability failed");
 225                        return err;
 226                }
 227                break;
 228        case TYPE_VF:
 229                err = get_cap_from_pf(dev, type);
 230                if (err) {
 231                        PMD_DRV_LOG(ERR, "Get VF capability failed, err: %d",
 232                                        err);
 233                        return err;
 234                }
 235                break;
 236        default:
 237                PMD_DRV_LOG(ERR, "Unsupported PCI function type");
 238                return -EINVAL;
 239        }
 240
 241        return 0;
 242}
 243
 244int hinic_init_capability(struct hinic_hwdev *hwdev)
 245{
 246        return get_dev_cap(hwdev);
 247}
 248