diff options
Diffstat (limited to 'drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c')
-rw-r--r-- | drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c | 148 |
1 files changed, 56 insertions, 92 deletions
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c index c7c75b772a86..e5cab58e4ddd 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c @@ -15,7 +15,9 @@ #include <linux/jiffies.h> #include <linux/log2.h> #include <linux/err.h> +#include <linux/netdevice.h> +#include "hinic_sriov.h" #include "hinic_hw_if.h" #include "hinic_hw_eqs.h" #include "hinic_hw_mgmt.h" @@ -46,20 +48,6 @@ enum hw_ioctxt_set_cmdq_depth { HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT, }; -/* HW struct */ -struct hinic_dev_cap { - u8 status; - u8 version; - u8 rsvd0[6]; - - u8 rsvd1[5]; - u8 intr_type; - u8 rsvd2[66]; - u16 max_sqs; - u16 max_rqs; - u8 rsvd3[208]; -}; - /** * get_capability - convert device capabilities to NIC capabilities * @hwdev: the HW device to set and convert device capabilities for @@ -67,16 +55,13 @@ struct hinic_dev_cap { * * Return 0 - Success, negative - Failure **/ -static int get_capability(struct hinic_hwdev *hwdev, - struct hinic_dev_cap *dev_cap) +static int parse_capability(struct hinic_hwdev *hwdev, + struct hinic_dev_cap *dev_cap) { struct hinic_cap *nic_cap = &hwdev->nic_cap; int num_aeqs, num_ceqs, num_irqs; - if (!HINIC_IS_PF(hwdev->hwif) && !HINIC_IS_PPF(hwdev->hwif)) - return -EINVAL; - - if (dev_cap->intr_type != INTR_MSIX_TYPE) + if (!HINIC_IS_VF(hwdev->hwif) && dev_cap->intr_type != INTR_MSIX_TYPE) return -EFAULT; num_aeqs = HINIC_HWIF_NUM_AEQS(hwdev->hwif); @@ -89,13 +74,19 @@ static int get_capability(struct hinic_hwdev *hwdev, if (nic_cap->num_qps > HINIC_Q_CTXT_MAX) nic_cap->num_qps = HINIC_Q_CTXT_MAX; - nic_cap->max_qps = dev_cap->max_sqs + 1; - if (nic_cap->max_qps != (dev_cap->max_rqs + 1)) - return -EFAULT; + if (!HINIC_IS_VF(hwdev->hwif)) + nic_cap->max_qps = dev_cap->max_sqs + 1; + else + nic_cap->max_qps = dev_cap->max_sqs; if (nic_cap->num_qps > nic_cap->max_qps) nic_cap->num_qps = nic_cap->max_qps; + if (!HINIC_IS_VF(hwdev->hwif)) { + nic_cap->max_vf = dev_cap->max_vf; + nic_cap->max_vf_qps = dev_cap->max_vf_sqs + 1; + } + return 0; } @@ -105,27 +96,26 @@ static int get_capability(struct hinic_hwdev *hwdev, * * Return 0 - Success, negative - Failure **/ -static int get_cap_from_fw(struct hinic_pfhwdev *pfhwdev) +static int get_capability(struct hinic_pfhwdev *pfhwdev) { struct hinic_hwdev *hwdev = &pfhwdev->hwdev; struct hinic_hwif *hwif = hwdev->hwif; struct pci_dev *pdev = hwif->pdev; struct hinic_dev_cap dev_cap; - u16 in_len, out_len; + u16 out_len; int err; - in_len = 0; out_len = sizeof(dev_cap); err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_CFGM, - HINIC_CFG_NIC_CAP, &dev_cap, in_len, &dev_cap, - &out_len, HINIC_MGMT_MSG_SYNC); + HINIC_CFG_NIC_CAP, &dev_cap, sizeof(dev_cap), + &dev_cap, &out_len, HINIC_MGMT_MSG_SYNC); if (err) { dev_err(&pdev->dev, "Failed to get capability from FW\n"); return err; } - return get_capability(hwdev, &dev_cap); + return parse_capability(hwdev, &dev_cap); } /** @@ -144,15 +134,14 @@ static int get_dev_cap(struct hinic_hwdev *hwdev) switch (HINIC_FUNC_TYPE(hwif)) { case HINIC_PPF: case HINIC_PF: + case HINIC_VF: pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); - - err = get_cap_from_fw(pfhwdev); + err = get_capability(pfhwdev); if (err) { - dev_err(&pdev->dev, "Failed to get capability from FW\n"); + dev_err(&pdev->dev, "Failed to get capability\n"); return err; } break; - default: dev_err(&pdev->dev, "Unsupported PCI Function type\n"); return -EINVAL; @@ -225,15 +214,8 @@ static void disable_msix(struct hinic_hwdev *hwdev) int hinic_port_msg_cmd(struct hinic_hwdev *hwdev, enum hinic_port_cmd cmd, void *buf_in, u16 in_size, void *buf_out, u16 *out_size) { - struct hinic_hwif *hwif = hwdev->hwif; - struct pci_dev *pdev = hwif->pdev; struct hinic_pfhwdev *pfhwdev; - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { - dev_err(&pdev->dev, "unsupported PCI Function type\n"); - return -EINVAL; - } - pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_L2NIC, cmd, @@ -252,14 +234,9 @@ static int init_fw_ctxt(struct hinic_hwdev *hwdev) struct hinic_hwif *hwif = hwdev->hwif; struct pci_dev *pdev = hwif->pdev; struct hinic_cmd_fw_ctxt fw_ctxt; - u16 out_size; + u16 out_size = sizeof(fw_ctxt); int err; - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { - dev_err(&pdev->dev, "Unsupported PCI Function type\n"); - return -EINVAL; - } - fw_ctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif); fw_ctxt.rx_buf_sz = HINIC_RX_BUF_SZ; @@ -288,14 +265,8 @@ static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int rq_depth, { struct hinic_hwif *hwif = hwdev->hwif; struct hinic_cmd_hw_ioctxt hw_ioctxt; - struct pci_dev *pdev = hwif->pdev; struct hinic_pfhwdev *pfhwdev; - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { - dev_err(&pdev->dev, "Unsupported PCI Function type\n"); - return -EINVAL; - } - hw_ioctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif); hw_ioctxt.ppf_idx = HINIC_HWIF_PPF_IDX(hwif); @@ -374,11 +345,6 @@ static int clear_io_resources(struct hinic_hwdev *hwdev) struct hinic_pfhwdev *pfhwdev; int err; - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { - dev_err(&pdev->dev, "Unsupported PCI Function type\n"); - return -EINVAL; - } - /* sleep 100ms to wait for firmware stopping I/O */ msleep(100); @@ -410,14 +376,8 @@ static int set_resources_state(struct hinic_hwdev *hwdev, { struct hinic_cmd_set_res_state res_state; struct hinic_hwif *hwif = hwdev->hwif; - struct pci_dev *pdev = hwif->pdev; struct hinic_pfhwdev *pfhwdev; - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { - dev_err(&pdev->dev, "Unsupported PCI Function type\n"); - return -EINVAL; - } - res_state.func_idx = HINIC_HWIF_FUNC_IDX(hwif); res_state.state = state; @@ -441,8 +401,8 @@ static int get_base_qpn(struct hinic_hwdev *hwdev, u16 *base_qpn) { struct hinic_cmd_base_qpn cmd_base_qpn; struct hinic_hwif *hwif = hwdev->hwif; + u16 out_size = sizeof(cmd_base_qpn); struct pci_dev *pdev = hwif->pdev; - u16 out_size; int err; cmd_base_qpn.func_idx = HINIC_HWIF_FUNC_IDX(hwif); @@ -488,7 +448,7 @@ int hinic_hwdev_ifup(struct hinic_hwdev *hwdev) num_ceqs = HINIC_HWIF_NUM_CEQS(hwif); ceq_msix_entries = &hwdev->msix_entries[num_aeqs]; - + func_to_io->hwdev = hwdev; err = hinic_io_init(func_to_io, hwif, nic_cap->max_qps, num_ceqs, ceq_msix_entries); if (err) { @@ -558,17 +518,10 @@ void hinic_hwdev_cb_register(struct hinic_hwdev *hwdev, u16 in_size, void *buf_out, u16 *out_size)) { - struct hinic_hwif *hwif = hwdev->hwif; - struct pci_dev *pdev = hwif->pdev; struct hinic_pfhwdev *pfhwdev; struct hinic_nic_cb *nic_cb; u8 cmd_cb; - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { - dev_err(&pdev->dev, "unsupported PCI Function type\n"); - return; - } - pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); cmd_cb = cmd - HINIC_MGMT_MSG_CMD_BASE; @@ -588,15 +541,12 @@ void hinic_hwdev_cb_unregister(struct hinic_hwdev *hwdev, enum hinic_mgmt_msg_cmd cmd) { struct hinic_hwif *hwif = hwdev->hwif; - struct pci_dev *pdev = hwif->pdev; struct hinic_pfhwdev *pfhwdev; struct hinic_nic_cb *nic_cb; u8 cmd_cb; - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { - dev_err(&pdev->dev, "unsupported PCI Function type\n"); + if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) return; - } pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); @@ -676,10 +626,23 @@ static int init_pfhwdev(struct hinic_pfhwdev *pfhwdev) return err; } - hinic_register_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, HINIC_MOD_L2NIC, - pfhwdev, nic_mgmt_msg_handler); + err = hinic_func_to_func_init(hwdev); + if (err) { + dev_err(&hwif->pdev->dev, "Failed to init mailbox\n"); + hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt); + return err; + } + + if (!HINIC_IS_VF(hwif)) + hinic_register_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, + HINIC_MOD_L2NIC, pfhwdev, + nic_mgmt_msg_handler); + else + hinic_register_vf_mbox_cb(hwdev, HINIC_MOD_L2NIC, + nic_mgmt_msg_handler); hinic_set_pf_action(hwif, HINIC_PF_MGMT_ACTIVE); + return 0; } @@ -693,7 +656,13 @@ static void free_pfhwdev(struct hinic_pfhwdev *pfhwdev) hinic_set_pf_action(hwdev->hwif, HINIC_PF_MGMT_INIT); - hinic_unregister_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, HINIC_MOD_L2NIC); + if (!HINIC_IS_VF(hwdev->hwif)) + hinic_unregister_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, + HINIC_MOD_L2NIC); + else + hinic_unregister_vf_mbox_cb(hwdev, HINIC_MOD_L2NIC); + + hinic_func_to_func_free(hwdev); hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt); } @@ -723,12 +692,6 @@ struct hinic_hwdev *hinic_init_hwdev(struct pci_dev *pdev) return ERR_PTR(err); } - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { - dev_err(&pdev->dev, "Unsupported PCI Function type\n"); - err = -EFAULT; - goto err_func_type; - } - pfhwdev = devm_kzalloc(&pdev->dev, sizeof(*pfhwdev), GFP_KERNEL); if (!pfhwdev) { err = -ENOMEM; @@ -772,6 +735,12 @@ struct hinic_hwdev *hinic_init_hwdev(struct pci_dev *pdev) goto err_dev_cap; } + err = hinic_vf_func_init(hwdev); + if (err) { + dev_err(&pdev->dev, "Failed to init nic mbox\n"); + goto err_vf_func_init; + } + err = init_fw_ctxt(hwdev); if (err) { dev_err(&pdev->dev, "Failed to init function table\n"); @@ -788,6 +757,8 @@ struct hinic_hwdev *hinic_init_hwdev(struct pci_dev *pdev) err_resources_state: err_init_fw_ctxt: + hinic_vf_func_free(hwdev); +err_vf_func_init: err_dev_cap: free_pfhwdev(pfhwdev); @@ -799,7 +770,6 @@ err_aeqs_init: err_init_msix: err_pfhwdev_alloc: -err_func_type: hinic_free_hwif(hwif); return ERR_PTR(err); } @@ -930,15 +900,9 @@ int hinic_hwdev_hw_ci_addr_set(struct hinic_hwdev *hwdev, struct hinic_sq *sq, { struct hinic_qp *qp = container_of(sq, struct hinic_qp, sq); struct hinic_hwif *hwif = hwdev->hwif; - struct pci_dev *pdev = hwif->pdev; struct hinic_pfhwdev *pfhwdev; struct hinic_cmd_hw_ci hw_ci; - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { - dev_err(&pdev->dev, "Unsupported PCI Function type\n"); - return -EINVAL; - } - hw_ci.dma_attr_off = 0; hw_ci.pending_limit = pending_limit; hw_ci.coalesc_timer = coalesc_timer; |