From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id E2842A2EDB for ; Fri, 6 Sep 2019 14:12:07 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id D21D41F304; Fri, 6 Sep 2019 14:12:07 +0200 (CEST) Received: from huawei.com (szxga06-in.huawei.com [45.249.212.32]) by dpdk.org (Postfix) with ESMTP id 241431F304 for ; Fri, 6 Sep 2019 14:12:06 +0200 (CEST) Received: from DGGEMS405-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id ECF2CF46A8197219A6CC for ; Fri, 6 Sep 2019 20:12:04 +0800 (CST) Received: from tester.localdomain (10.175.119.39) by DGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP Server id 14.3.439.0; Fri, 6 Sep 2019 20:11:55 +0800 From: Ziyang Xuan To: CC: , , , , , , , , Xiaoyun Wang Date: Fri, 6 Sep 2019 20:26:37 +0800 Message-ID: <3071d40fb21e099023aad64b453a0fc8a66f1958.1567771268.git.cloud.wangxiaoyun@huawei.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.175.119.39] X-CFilter-Loop: Reflected Subject: [dpdk-stable] [PATCH v1 02/15] net/hinic/base: add HW interfaces of SRIOV X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Sender: "stable" From: Xiaoyun Wang This patch makes some HW interfaces support SRIOV, including: init hwdev, set port state, get default cos, vf dma attribute table, vf txrx flush and so on. Signed-off-by: Xiaoyun Wang --- drivers/net/hinic/base/hinic_compat.h | 33 ------- drivers/net/hinic/base/hinic_pmd_cfg.c | 35 +++++++ drivers/net/hinic/base/hinic_pmd_cmd.h | 6 ++ drivers/net/hinic/base/hinic_pmd_hwdev.c | 152 +++++++++++++++++++++++++++--- drivers/net/hinic/base/hinic_pmd_hwdev.h | 8 ++ drivers/net/hinic/base/hinic_pmd_hwif.c | 46 ++++++++- drivers/net/hinic/base/hinic_pmd_hwif.h | 7 ++ drivers/net/hinic/base/hinic_pmd_mgmt.c | 25 ++++- drivers/net/hinic/base/hinic_pmd_niccfg.c | 64 ++++++++++++- drivers/net/hinic/base/hinic_pmd_niccfg.h | 18 ++++ drivers/net/hinic/base/hinic_pmd_nicio.c | 7 ++ 11 files changed, 351 insertions(+), 50 deletions(-) diff --git a/drivers/net/hinic/base/hinic_compat.h b/drivers/net/hinic/base/hinic_compat.h index f599947..9082c38 100644 --- a/drivers/net/hinic/base/hinic_compat.h +++ b/drivers/net/hinic/base/hinic_compat.h @@ -222,39 +222,6 @@ static inline u16 ilog2(u32 n) return res; } - -/** - * hinic_cpu_to_be32 - convert data to big endian 32 bit format - * @data: the data to convert - * @len: length of data to convert, must be Multiple of 4B - **/ -static inline void hinic_cpu_to_be32(void *data, u32 len) -{ - u32 i; - u32 *mem = (u32 *)data; - - for (i = 0; i < (len >> 2); i++) { - *mem = cpu_to_be32(*mem); - mem++; - } -} - -/** - * hinic_be32_to_cpu - convert data from big endian 32 bit format - * @data: the data to convert - * @len: length of data to convert, must be Multiple of 4B - **/ -static inline void hinic_be32_to_cpu(void *data, u32 len) -{ - u32 i; - u32 *mem = (u32 *)data; - - for (i = 0; i < (len >> 2); i++) { - *mem = be32_to_cpu(*mem); - mem++; - } -} - static inline int hinic_mutex_init(pthread_mutex_t *pthreadmutex, const pthread_mutexattr_t *mattr) { diff --git a/drivers/net/hinic/base/hinic_pmd_cfg.c b/drivers/net/hinic/base/hinic_pmd_cfg.c index 61537b1..aa883e0 100644 --- a/drivers/net/hinic/base/hinic_pmd_cfg.c +++ b/drivers/net/hinic/base/hinic_pmd_cfg.c @@ -8,6 +8,7 @@ #include "hinic_pmd_mgmt.h" #include "hinic_pmd_eqs.h" #include "hinic_pmd_cfg.h" +#include "hinic_pmd_mbox.h" bool hinic_support_nic(struct hinic_hwdev *hwdev, struct nic_service_cap *cap) { @@ -122,6 +123,10 @@ static void hinic_parse_pub_res_cap(struct service_cap *cap, cap->vf_id_start = dev_cap->vf_id_start; cap->max_sqs = dev_cap->nic_max_sq + 1; cap->max_rqs = dev_cap->nic_max_rq + 1; + } else { + cap->max_vf = 0; + cap->max_sqs = dev_cap->nic_max_sq; + cap->max_rqs = dev_cap->nic_max_rq; } cap->chip_svc_type = CFG_SVC_NIC_BIT0; @@ -180,6 +185,28 @@ static int get_cap_from_fw(struct hinic_hwdev *dev, enum func_type type) return 0; } +static int get_cap_from_pf(struct hinic_hwdev *dev, enum func_type type) +{ + int err; + u16 in_len, out_len; + struct hinic_dev_cap dev_cap; + + memset(&dev_cap, 0, sizeof(dev_cap)); + in_len = sizeof(dev_cap); + out_len = in_len; + err = hinic_mbox_to_pf(dev, HINIC_MOD_CFGM, HINIC_CFG_MBOX_CAP, + &dev_cap, in_len, &dev_cap, &out_len, + CFG_MAX_CMD_TIMEOUT); + if (err || dev_cap.mgmt_msg_head.status || !out_len) { + PMD_DRV_LOG(ERR, "Get capability from PF failed, err: %d, status: %d, out_len: %d", + err, dev_cap.mgmt_msg_head.status, out_len); + return -EFAULT; + } + + parse_dev_cap(dev, &dev_cap, type); + return 0; +} + static int get_dev_cap(struct hinic_hwdev *dev) { int err; @@ -194,6 +221,14 @@ static int get_dev_cap(struct hinic_hwdev *dev) return err; } break; + case TYPE_VF: + err = get_cap_from_pf(dev, type); + if (err) { + PMD_DRV_LOG(ERR, "Get VF capability failed, err: %d", + err); + return err; + } + break; default: PMD_DRV_LOG(ERR, "Unsupported PCI function type"); return -EINVAL; diff --git a/drivers/net/hinic/base/hinic_pmd_cmd.h b/drivers/net/hinic/base/hinic_pmd_cmd.h index 7a9e9f6..73f96b1 100644 --- a/drivers/net/hinic/base/hinic_pmd_cmd.h +++ b/drivers/net/hinic/base/hinic_pmd_cmd.h @@ -25,6 +25,12 @@ enum hinic_mod_type { HINIC_MOD_MAX = 15 }; +/* only used by VFD communicating with PFD to register or unregister, + * command mode type is HINIC_MOD_L2NIC + */ +#define HINIC_PORT_CMD_VF_REGISTER 0x0 +#define HINIC_PORT_CMD_VF_UNREGISTER 0x1 + /* cmd of mgmt CPU message for NIC module */ enum hinic_port_cmd { HINIC_PORT_CMD_MGMT_RESET = 0x0, diff --git a/drivers/net/hinic/base/hinic_pmd_hwdev.c b/drivers/net/hinic/base/hinic_pmd_hwdev.c index 4f70baf..4d6f90f 100644 --- a/drivers/net/hinic/base/hinic_pmd_hwdev.c +++ b/drivers/net/hinic/base/hinic_pmd_hwdev.c @@ -15,6 +15,7 @@ #include "hinic_pmd_cmdq.h" #include "hinic_pmd_mgmt.h" #include "hinic_pmd_niccfg.h" +#include "hinic_pmd_mbox.h" #define HINIC_DEAULT_EQ_MSIX_PENDING_LIMIT 0 #define HINIC_DEAULT_EQ_MSIX_COALESC_TIMER_CFG 0xFF @@ -65,6 +66,52 @@ "Unrecognized module", }; +struct hinic_vf_dma_attr_table { + struct hinic_mgmt_msg_head mgmt_msg_head; + + u16 func_idx; + u8 func_dma_entry_num; + u8 entry_idx; + u8 st; + u8 at; + u8 ph; + u8 no_snooping; + u8 tph_en; + u8 resv1[3]; +}; + +/** + * hinic_cpu_to_be32 - convert data to big endian 32 bit format + * @data: the data to convert + * @len: length of data to convert, must be Multiple of 4B + **/ +void hinic_cpu_to_be32(void *data, u32 len) +{ + u32 i; + u32 *mem = (u32 *)data; + + for (i = 0; i < (len >> 2); i++) { + *mem = cpu_to_be32(*mem); + mem++; + } +} + +/** + * hinic_be32_to_cpu - convert data from big endian 32 bit format + * @data: the data to convert + * @len: length of data to convert, must be Multiple of 4B + **/ +void hinic_be32_to_cpu(void *data, u32 len) +{ + u32 i; + u32 *mem = (u32 *)data; + + for (i = 0; i < (len >> 2); i++) { + *mem = be32_to_cpu(*mem); + mem++; + } +} + static void * hinic_dma_mem_zalloc(struct hinic_hwdev *hwdev, size_t size, dma_addr_t *dma_handle, unsigned int flag, unsigned int align) @@ -463,6 +510,44 @@ static int wait_cmdq_stop(struct hinic_hwdev *hwdev) return err; } +static int hinic_vf_rx_tx_flush(struct hinic_hwdev *hwdev) +{ + struct hinic_clear_resource clr_res; + int err; + + err = wait_cmdq_stop(hwdev); + if (err) { + PMD_DRV_LOG(WARNING, "Cmdq is still working"); + return err; + } + + memset(&clr_res, 0, sizeof(clr_res)); + clr_res.func_idx = HINIC_HWIF_GLOBAL_IDX(hwdev->hwif); + clr_res.ppf_idx = HINIC_HWIF_PPF_IDX(hwdev->hwif); + err = hinic_mbox_to_pf_no_ack(hwdev, HINIC_MOD_COMM, + HINIC_MGMT_CMD_START_FLR, &clr_res, sizeof(clr_res)); + if (err) + PMD_DRV_LOG(WARNING, "Notice flush message failed"); + + /* + * PF firstly set VF doorbell flush csr to be disabled. After PF finish + * VF resources flush, PF will set VF doorbell flush csr to be enabled. + */ + err = wait_until_doorbell_flush_states(hwdev->hwif, DISABLE_DOORBELL); + if (err) + PMD_DRV_LOG(WARNING, "Wait doorbell flush disable timeout"); + + err = wait_until_doorbell_flush_states(hwdev->hwif, ENABLE_DOORBELL); + if (err) + PMD_DRV_LOG(WARNING, "Wait doorbell flush enable timeout"); + + err = hinic_reinit_cmdq_ctxts(hwdev); + if (err) + PMD_DRV_LOG(WARNING, "Reinit cmdq failed"); + + return err; +} + /** * hinic_pf_rx_tx_flush - clean up hardware resource * @hwdev: the hardware interface of a nic device @@ -523,7 +608,10 @@ static int hinic_pf_rx_tx_flush(struct hinic_hwdev *hwdev) int hinic_func_rx_tx_flush(struct hinic_hwdev *hwdev) { - return hinic_pf_rx_tx_flush(hwdev); + if (HINIC_FUNC_TYPE(hwdev) == TYPE_VF) + return hinic_vf_rx_tx_flush(hwdev); + else + return hinic_pf_rx_tx_flush(hwdev); } /** @@ -690,28 +778,70 @@ static void set_pf_dma_attr_entry(struct hinic_hwdev *hwdev, u32 entry_idx, hinic_hwif_write_reg(hwdev->hwif, addr, val); } +static int set_vf_dma_attr_entry(struct hinic_hwdev *hwdev, u8 entry_idx, + u8 st, u8 at, u8 ph, + enum hinic_pcie_nosnoop no_snooping, + enum hinic_pcie_tph tph_en) +{ + struct hinic_vf_dma_attr_table attr; + + memset(&attr, 0, sizeof(attr)); + attr.func_idx = hinic_global_func_id(hwdev); + attr.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1; + attr.func_dma_entry_num = hinic_dma_attr_entry_num(hwdev); + attr.entry_idx = entry_idx; + attr.st = st; + attr.at = at; + attr.ph = ph; + attr.no_snooping = no_snooping; + attr.tph_en = tph_en; + + return hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, + HINIC_MGMT_CMD_DMA_ATTR_SET, + &attr, sizeof(attr), NULL, NULL, 0); +} + /** * dma_attr_table_init - initialize the the default dma attributes * @hwdev: the pointer to the private hardware device object **/ -static void dma_attr_table_init(struct hinic_hwdev *hwdev) +static int dma_attr_table_init(struct hinic_hwdev *hwdev) { + int err = 0; + if (HINIC_IS_VF(hwdev)) - return; + err = set_vf_dma_attr_entry(hwdev, PCIE_MSIX_ATTR_ENTRY, + HINIC_PCIE_ST_DISABLE, HINIC_PCIE_AT_DISABLE, + HINIC_PCIE_PH_DISABLE, HINIC_PCIE_SNOOP, + HINIC_PCIE_TPH_DISABLE); + else + set_pf_dma_attr_entry(hwdev, PCIE_MSIX_ATTR_ENTRY, + HINIC_PCIE_ST_DISABLE, HINIC_PCIE_AT_DISABLE, + HINIC_PCIE_PH_DISABLE, HINIC_PCIE_SNOOP, + HINIC_PCIE_TPH_DISABLE); - set_pf_dma_attr_entry(hwdev, PCIE_MSIX_ATTR_ENTRY, - HINIC_PCIE_ST_DISABLE, - HINIC_PCIE_AT_DISABLE, - HINIC_PCIE_PH_DISABLE, - HINIC_PCIE_SNOOP, - HINIC_PCIE_TPH_DISABLE); + return err; } int hinic_init_attr_table(struct hinic_hwdev *hwdev) { - dma_attr_table_init(hwdev); + int err; - return init_aeqs_msix_attr(hwdev); + err = dma_attr_table_init(hwdev); + if (err) { + PMD_DRV_LOG(ERR, "Initialize dma attribute table failed, err: %d", + err); + return err; + } + + err = init_aeqs_msix_attr(hwdev); + if (err) { + PMD_DRV_LOG(ERR, "Initialize aeqs msix attribute failed, err: %d", + err); + return err; + } + + return 0; } #define FAULT_SHOW_STR_LEN 16 diff --git a/drivers/net/hinic/base/hinic_pmd_hwdev.h b/drivers/net/hinic/base/hinic_pmd_hwdev.h index 6c21c47..d12e631 100644 --- a/drivers/net/hinic/base/hinic_pmd_hwdev.h +++ b/drivers/net/hinic/base/hinic_pmd_hwdev.h @@ -14,6 +14,8 @@ #define MAX_PCIE_DFX_BUF_SIZE 1024 +#define HINIC_DEV_BUSY_ACTIVE_FW 0xFE + /* dma pool */ struct dma_pool { u32 inuse; @@ -436,6 +438,7 @@ struct hinic_hwdev { struct hinic_hwif *hwif; struct cfg_mgmt_info *cfg_mgmt; struct hinic_aeqs *aeqs; + struct hinic_mbox_func_to_func *func_to_func; struct hinic_msg_pf_to_mgmt *pf_to_mgmt; struct hinic_cmdqs *cmdqs; struct hinic_nic_io *nic_io; @@ -482,4 +485,9 @@ void hinic_hilink_async_event_handle(struct hinic_hwdev *hwdev, u8 cmd, int hinic_set_pagesize(void *hwdev, u8 page_size); +void hinic_cpu_to_be32(void *data, u32 len); + +void hinic_be32_to_cpu(void *data, u32 len); + + #endif /* _HINIC_PMD_HWDEV_H_ */ diff --git a/drivers/net/hinic/base/hinic_pmd_hwif.c b/drivers/net/hinic/base/hinic_pmd_hwif.c index a5e223b..98299f2 100644 --- a/drivers/net/hinic/base/hinic_pmd_hwif.c +++ b/drivers/net/hinic/base/hinic_pmd_hwif.c @@ -27,14 +27,19 @@ **/ static int hwif_ready(struct hinic_hwdev *hwdev) { - u32 addr, attr1; + u32 addr, attr0, attr1; addr = HINIC_CSR_FUNC_ATTR1_ADDR; attr1 = hinic_hwif_read_reg(hwdev->hwif, addr); - if (!HINIC_AF1_GET(attr1, MGMT_INIT_STATUS)) return -EBUSY; + addr = HINIC_CSR_FUNC_ATTR0_ADDR; + attr0 = hinic_hwif_read_reg(hwdev->hwif, addr); + if ((HINIC_AF0_GET(attr0, FUNC_TYPE) == TYPE_VF) && + !HINIC_AF1_GET(attr1, PF_INIT_STATUS)) + return -EBUSY; + return 0; } @@ -90,6 +95,9 @@ void hinic_set_pf_status(struct hinic_hwif *hwif, enum hinic_pf_status status) u32 attr5 = HINIC_AF5_SET(status, PF_STATUS); u32 addr = HINIC_CSR_FUNC_ATTR5_ADDR; + if (hwif->attr.func_type == TYPE_VF) + return; + hinic_hwif_write_reg(hwif, addr, attr5); } @@ -285,6 +293,25 @@ static void disable_all_msix(struct hinic_hwdev *hwdev) hinic_set_msix_state(hwdev, i, HINIC_MSIX_DISABLE); } +int wait_until_doorbell_flush_states(struct hinic_hwif *hwif, + enum hinic_doorbell_ctrl states) +{ + unsigned long end; + enum hinic_doorbell_ctrl db_ctrl; + + end = jiffies + + msecs_to_jiffies(HINIC_WAIT_DOORBELL_AND_OUTBOUND_TIMEOUT); + do { + db_ctrl = hinic_get_doorbell_ctrl_status(hwif); + if (db_ctrl == states) + return 0; + + rte_delay_ms(1); + } while (time_before(jiffies, end)); + + return -EFAULT; +} + static int wait_until_doorbell_and_outbound_enabled(struct hinic_hwif *hwif) { unsigned long end; @@ -321,6 +348,12 @@ enum func_type hinic_func_type(void *hwdev) return hwif->attr.func_type; } +u8 hinic_pf_id_of_vf(void *hwdev) +{ + struct hinic_hwif *hwif = ((struct hinic_hwdev *)hwdev)->hwif; + return hwif->attr.port_to_port_idx; +} + u8 hinic_ppf_idx(void *hwdev) { struct hinic_hwif *hwif = ((struct hinic_hwdev *)hwdev)->hwif; @@ -328,6 +361,12 @@ u8 hinic_ppf_idx(void *hwdev) return hwif->attr.ppf_idx; } +u8 hinic_dma_attr_entry_num(void *hwdev) +{ + struct hinic_hwif *hwif = ((struct hinic_hwdev *)hwdev)->hwif; + return hwif->attr.num_dma_attr; +} + /** * hinic_init_hwif - initialize the hw interface * @hwdev: the pointer to the private hardware device object @@ -371,6 +410,9 @@ static int hinic_init_hwif(struct hinic_hwdev *hwdev, void *cfg_reg_base, if (!HINIC_IS_VF(hwdev)) set_ppf(hwif); + /* disable mgmt cpu report any event */ + hinic_set_pf_status(hwdev->hwif, HINIC_PF_STATUS_INIT); + return 0; hwif_ready_err: diff --git a/drivers/net/hinic/base/hinic_pmd_hwif.h b/drivers/net/hinic/base/hinic_pmd_hwif.h index c1289b5..fba6c31 100644 --- a/drivers/net/hinic/base/hinic_pmd_hwif.h +++ b/drivers/net/hinic/base/hinic_pmd_hwif.h @@ -104,6 +104,9 @@ static inline u32 hinic_hwif_read_reg(struct hinic_hwif *hwif, u32 reg) void hinic_free_db_addr(void *hwdev, void __iomem *db_base); +int wait_until_doorbell_flush_states(struct hinic_hwif *hwif, + enum hinic_doorbell_ctrl states); + void hinic_set_msix_state(void *hwdev, u16 msix_idx, enum hinic_msix_state flag); @@ -116,4 +119,8 @@ void hinic_misx_intr_clear_resend_bit(void *hwdev, u16 msix_idx, void hinic_hwif_res_free(struct hinic_hwdev *hwdev); +u8 hinic_pf_id_of_vf(void *hwdev); + +u8 hinic_dma_attr_entry_num(void *hwdev); + #endif /* _HINIC_PMD_HWIF_H_ */ diff --git a/drivers/net/hinic/base/hinic_pmd_mgmt.c b/drivers/net/hinic/base/hinic_pmd_mgmt.c index a18e567..4b7994a 100644 --- a/drivers/net/hinic/base/hinic_pmd_mgmt.c +++ b/drivers/net/hinic/base/hinic_pmd_mgmt.c @@ -7,6 +7,7 @@ #include "hinic_pmd_hwdev.h" #include "hinic_pmd_hwif.h" #include "hinic_pmd_mgmt.h" +#include "hinic_pmd_mbox.h" #define BUF_OUT_DEFAULT_SIZE 1 @@ -464,6 +465,9 @@ static int hinic_get_mgmt_channel_status(void *hwdev) struct hinic_hwif *hwif = ((struct hinic_hwdev *)hwdev)->hwif; u32 val; + if (hinic_func_type((struct hinic_hwdev *)hwdev) == TYPE_VF) + return false; + val = hinic_hwif_read_reg(hwif, HINIC_ICPL_RESERVD_ADDR); return HINIC_GET_MGMT_CHANNEL_STATUS(val, MGMT_CHANNEL_STATUS); @@ -482,9 +486,13 @@ int hinic_msg_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd, if (hinic_get_mgmt_channel_status(hwdev)) return -EPERM; - rc = hinic_pf_to_mgmt_sync(hwdev, mod, cmd, buf_in, - in_size, buf_out, out_size, - timeout); + if (hinic_func_type(hwdev) == TYPE_VF) { + rc = hinic_mbox_to_pf(hwdev, mod, cmd, buf_in, in_size, + buf_out, out_size, timeout); + } else { + rc = hinic_pf_to_mgmt_sync(hwdev, mod, cmd, buf_in, in_size, + buf_out, out_size, timeout); + } return rc; } @@ -667,6 +675,9 @@ static int hinic_handle_aeqe(void *handle, enum hinic_aeq_type event, case HINIC_MSG_FROM_MGMT_CPU: rc = hinic_mgmt_msg_aeqe_handler(handle, data, size, param); break; + case HINIC_MBX_FROM_FUNC: + rc = hinic_mbox_func_aeqe_handler(handle, data, size, param); + break; default: PMD_DRV_LOG(ERR, "Unknown event type: 0x%x, size: %d", event, size); @@ -753,6 +764,10 @@ int hinic_comm_pf_to_mgmt_init(struct hinic_hwdev *hwdev) { int rc; + /* VF do not support send msg to mgmt directly */ + if (hinic_func_type(hwdev) == TYPE_VF) + return 0; + rc = hinic_pf_to_mgmt_init(hwdev); if (rc) return rc; @@ -764,6 +779,10 @@ int hinic_comm_pf_to_mgmt_init(struct hinic_hwdev *hwdev) void hinic_comm_pf_to_mgmt_free(struct hinic_hwdev *hwdev) { + /* VF do not support send msg to mgmt directly */ + if (hinic_func_type(hwdev) == TYPE_VF) + return; + hinic_pf_to_mgmt_free(hwdev); } diff --git a/drivers/net/hinic/base/hinic_pmd_niccfg.c b/drivers/net/hinic/base/hinic_pmd_niccfg.c index 7da0a88..d245315 100644 --- a/drivers/net/hinic/base/hinic_pmd_niccfg.c +++ b/drivers/net/hinic/base/hinic_pmd_niccfg.c @@ -10,6 +10,7 @@ #include "hinic_pmd_mgmt.h" #include "hinic_pmd_cmdq.h" #include "hinic_pmd_niccfg.h" +#include "hinic_pmd_mbox.h" #define l2nic_msg_to_mgmt_sync(hwdev, cmd, buf_in, \ in_size, buf_out, out_size) \ @@ -318,6 +319,9 @@ int hinic_set_port_enable(void *hwdev, bool enable) return -EINVAL; } + if (HINIC_IS_VF((struct hinic_hwdev *)hwdev)) + return 0; + memset(&en_state, 0, sizeof(en_state)); en_state.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1; en_state.state = (enable ? HINIC_PORT_ENABLE : HINIC_PORT_DISABLE); @@ -432,7 +436,7 @@ int hinic_dcb_set_ets(void *hwdev, u8 *up_tc, u8 *pg_bw, memset(&ets, 0, sizeof(ets)); ets.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1; - ets.port_id = 0; /* reserved */ + ets.port_id = 0; /* reserved */ memcpy(ets.up_tc, up_tc, HINIC_DCB_TC_MAX); memcpy(ets.pg_bw, pg_bw, HINIC_DCB_UP_MAX); memcpy(ets.pgid, pgid, HINIC_DCB_UP_MAX); @@ -1100,6 +1104,38 @@ int hinic_reset_port_link_cfg(void *hwdev) return 0; } +int hinic_vf_func_init(struct hinic_hwdev *hwdev) +{ + int err, state = 0; + + if (!HINIC_IS_VF(hwdev)) + return 0; + + err = hinic_mbox_to_pf(hwdev, HINIC_MOD_L2NIC, + HINIC_PORT_CMD_VF_REGISTER, &state, sizeof(state), + NULL, NULL, 0); + if (err) { + PMD_DRV_LOG(ERR, "Fail to register vf"); + return err; + } + + return 0; +} + +void hinic_vf_func_free(struct hinic_hwdev *hwdev) +{ + int err; + + if (hinic_func_type(hwdev) != TYPE_VF) + return; + + err = hinic_mbox_to_pf(hwdev, HINIC_MOD_L2NIC, + HINIC_PORT_CMD_VF_UNREGISTER, &err, sizeof(err), + NULL, NULL, 0); + if (err) + PMD_DRV_LOG(ERR, "Fail to unregister VF, err: %d", err); +} + int hinic_set_fast_recycle_mode(void *hwdev, u8 mode) { struct hinic_fast_recycled_mode fast_recycled_mode; @@ -1193,6 +1229,9 @@ int hinic_set_link_status_follow(void *hwdev, if (!hwdev) return -EINVAL; + if (HINIC_IS_VF((struct hinic_hwdev *)hwdev)) + return 0; + if (status >= HINIC_LINK_FOLLOW_STATUS_MAX) { PMD_DRV_LOG(ERR, "Invalid link follow status: %d", status); @@ -1274,3 +1313,26 @@ int hinic_flush_qp_res(void *hwdev) return 0; } + +int hinic_vf_get_default_cos(struct hinic_hwdev *hwdev, u8 *cos_id) +{ + struct hinic_vf_default_cos vf_cos; + u16 out_size = sizeof(vf_cos); + int err; + + memset(&vf_cos, 0, sizeof(vf_cos)); + vf_cos.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1; + + err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_L2NIC, + HINIC_PORT_CMD_GET_VF_COS, &vf_cos, + sizeof(vf_cos), &vf_cos, + &out_size, 0); + if (err || !out_size || vf_cos.mgmt_msg_head.status) { + PMD_DRV_LOG(ERR, "Get VF default cos failed, err: %d, status: 0x%x, out size: 0x%x", + err, vf_cos.mgmt_msg_head.status, out_size); + return -EFAULT; + } + *cos_id = vf_cos.state.default_cos; + + return 0; +} diff --git a/drivers/net/hinic/base/hinic_pmd_niccfg.h b/drivers/net/hinic/base/hinic_pmd_niccfg.h index eaa3f2a..253dbf4 100644 --- a/drivers/net/hinic/base/hinic_pmd_niccfg.h +++ b/drivers/net/hinic/base/hinic_pmd_niccfg.h @@ -562,6 +562,18 @@ struct hinic_clear_qp_resource { u16 rsvd1; }; +struct hinic_dcb_state { + u8 dcb_on; + u8 default_cos; + u8 up_cos[8]; +}; + +struct hinic_vf_default_cos { + struct hinic_mgmt_msg_head mgmt_msg_head; + + struct hinic_dcb_state state; +}; + /* set physical port Anti-Attack rate */ struct hinic_port_anti_attack_rate { struct hinic_mgmt_msg_head mgmt_msg_head; @@ -655,4 +667,10 @@ int hinic_set_link_status_follow(void *hwdev, void hinic_clear_phy_port_stats(struct hinic_hwdev *hwdev); +int hinic_vf_func_init(struct hinic_hwdev *hwdev); + +void hinic_vf_func_free(struct hinic_hwdev *hwdev); + +int hinic_vf_get_default_cos(struct hinic_hwdev *hwdev, u8 *cos_id); + #endif /* _HINIC_PMD_NICCFG_H_ */ diff --git a/drivers/net/hinic/base/hinic_pmd_nicio.c b/drivers/net/hinic/base/hinic_pmd_nicio.c index 248211f..7ccaa89 100644 --- a/drivers/net/hinic/base/hinic_pmd_nicio.c +++ b/drivers/net/hinic/base/hinic_pmd_nicio.c @@ -618,6 +618,12 @@ static int hinic_init_nic_hwdev(struct hinic_hwdev *hwdev) goto err_init_nic_hwdev; } + err = hinic_vf_func_init(hwdev); + if (err) { + PMD_DRV_LOG(ERR, "Failed to init nic mbox"); + goto err_init_nic_hwdev; + } + err = hinic_set_fast_recycle_mode(hwdev, RECYCLE_MODE_DPDK); if (err) { PMD_DRV_LOG(ERR, "Failed to set fast recycle mode"); @@ -632,6 +638,7 @@ static int hinic_init_nic_hwdev(struct hinic_hwdev *hwdev) static void hinic_free_nic_hwdev(struct hinic_hwdev *hwdev) { + hinic_vf_func_free(hwdev); hwdev->nic_io = NULL; } -- 1.8.3.1