mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-14 15:55:28 -04:00
hinic3: Nic_io initialization
Add nic_io initialization to enable NIC service, configure the function table, initialize hwdev dev_id and negotiate activation of NIC features. Co-developed-by: Zhu Yikai <zhuyikai1@h-partners.com> Signed-off-by: Zhu Yikai <zhuyikai1@h-partners.com> Signed-off-by: Fan Gong <gongfan1@huawei.com> Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev> Link: https://patch.msgid.link/fab9c4235c0fc0f65c9ac1add20dba5ac2160328.1757653621.git.zhuyikai1@h-partners.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
@@ -436,6 +436,18 @@ static void hinic3_uninit_comm_ch(struct hinic3_hwdev *hwdev)
|
||||
free_base_mgmt_channel(hwdev);
|
||||
}
|
||||
|
||||
static DEFINE_IDA(hinic3_adev_ida);
|
||||
|
||||
static int hinic3_adev_idx_alloc(void)
|
||||
{
|
||||
return ida_alloc(&hinic3_adev_ida, GFP_KERNEL);
|
||||
}
|
||||
|
||||
static void hinic3_adev_idx_free(int id)
|
||||
{
|
||||
ida_free(&hinic3_adev_ida, id);
|
||||
}
|
||||
|
||||
int hinic3_init_hwdev(struct pci_dev *pdev)
|
||||
{
|
||||
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
|
||||
@@ -451,6 +463,7 @@ int hinic3_init_hwdev(struct pci_dev *pdev)
|
||||
hwdev->pdev = pci_adapter->pdev;
|
||||
hwdev->dev = &pci_adapter->pdev->dev;
|
||||
hwdev->func_state = 0;
|
||||
hwdev->dev_id = hinic3_adev_idx_alloc();
|
||||
spin_lock_init(&hwdev->channel_lock);
|
||||
|
||||
err = hinic3_init_hwif(hwdev);
|
||||
@@ -504,6 +517,7 @@ int hinic3_init_hwdev(struct pci_dev *pdev)
|
||||
hinic3_free_hwif(hwdev);
|
||||
err_free_hwdev:
|
||||
pci_adapter->hwdev = NULL;
|
||||
hinic3_adev_idx_free(hwdev->dev_id);
|
||||
kfree(hwdev);
|
||||
|
||||
return err;
|
||||
@@ -519,6 +533,7 @@ void hinic3_free_hwdev(struct hinic3_hwdev *hwdev)
|
||||
hinic3_free_cfg_mgmt(hwdev);
|
||||
destroy_workqueue(hwdev->workq);
|
||||
hinic3_free_hwif(hwdev);
|
||||
hinic3_adev_idx_free(hwdev->dev_id);
|
||||
kfree(hwdev);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,12 @@ static int hinic3_feature_nego(struct hinic3_hwdev *hwdev, u8 opcode,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hinic3_get_nic_feature_from_hw(struct hinic3_nic_dev *nic_dev)
|
||||
{
|
||||
return hinic3_feature_nego(nic_dev->hwdev, MGMT_MSG_CMD_OP_GET,
|
||||
&nic_dev->nic_io->feature_cap, 1);
|
||||
}
|
||||
|
||||
int hinic3_set_nic_feature_to_hw(struct hinic3_nic_dev *nic_dev)
|
||||
{
|
||||
return hinic3_feature_nego(nic_dev->hwdev, MGMT_MSG_CMD_OP_SET,
|
||||
@@ -82,6 +88,23 @@ static int hinic3_set_function_table(struct hinic3_hwdev *hwdev, u32 cfg_bitmap,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hinic3_init_function_table(struct hinic3_nic_dev *nic_dev)
|
||||
{
|
||||
struct hinic3_nic_io *nic_io = nic_dev->nic_io;
|
||||
struct l2nic_func_tbl_cfg func_tbl_cfg = {};
|
||||
u32 cfg_bitmap;
|
||||
|
||||
func_tbl_cfg.mtu = 0x3FFF; /* default, max mtu */
|
||||
func_tbl_cfg.rx_wqe_buf_size = nic_io->rx_buf_len;
|
||||
|
||||
cfg_bitmap = BIT(L2NIC_FUNC_TBL_CFG_INIT) |
|
||||
BIT(L2NIC_FUNC_TBL_CFG_MTU) |
|
||||
BIT(L2NIC_FUNC_TBL_CFG_RX_BUF_SIZE);
|
||||
|
||||
return hinic3_set_function_table(nic_dev->hwdev, cfg_bitmap,
|
||||
&func_tbl_cfg);
|
||||
}
|
||||
|
||||
int hinic3_set_port_mtu(struct net_device *netdev, u16 new_mtu)
|
||||
{
|
||||
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
|
||||
|
||||
@@ -22,11 +22,13 @@ enum hinic3_nic_event_type {
|
||||
HINIC3_NIC_EVENT_LINK_UP = 1,
|
||||
};
|
||||
|
||||
int hinic3_get_nic_feature_from_hw(struct hinic3_nic_dev *nic_dev);
|
||||
int hinic3_set_nic_feature_to_hw(struct hinic3_nic_dev *nic_dev);
|
||||
bool hinic3_test_support(struct hinic3_nic_dev *nic_dev,
|
||||
enum hinic3_nic_feature_cap feature_bits);
|
||||
void hinic3_update_nic_feature(struct hinic3_nic_dev *nic_dev, u64 feature_cap);
|
||||
|
||||
int hinic3_init_function_table(struct hinic3_nic_dev *nic_dev);
|
||||
int hinic3_set_port_mtu(struct net_device *netdev, u16 new_mtu);
|
||||
|
||||
int hinic3_set_mac(struct hinic3_hwdev *hwdev, const u8 *mac_addr, u16 vlan_id,
|
||||
|
||||
@@ -11,11 +11,56 @@
|
||||
|
||||
int hinic3_init_nic_io(struct hinic3_nic_dev *nic_dev)
|
||||
{
|
||||
/* Completed by later submission due to LoC limit. */
|
||||
return -EFAULT;
|
||||
struct hinic3_hwdev *hwdev = nic_dev->hwdev;
|
||||
struct hinic3_nic_io *nic_io;
|
||||
int err;
|
||||
|
||||
nic_io = kzalloc(sizeof(*nic_io), GFP_KERNEL);
|
||||
if (!nic_io)
|
||||
return -ENOMEM;
|
||||
|
||||
nic_dev->nic_io = nic_io;
|
||||
|
||||
err = hinic3_set_func_svc_used_state(hwdev, COMM_FUNC_SVC_T_NIC, 1);
|
||||
if (err) {
|
||||
dev_err(hwdev->dev, "Failed to set function svc used state\n");
|
||||
goto err_free_nicio;
|
||||
}
|
||||
|
||||
err = hinic3_init_function_table(nic_dev);
|
||||
if (err) {
|
||||
dev_err(hwdev->dev, "Failed to init function table\n");
|
||||
goto err_clear_func_svc_used_state;
|
||||
}
|
||||
|
||||
nic_io->rx_buf_len = nic_dev->rx_buf_len;
|
||||
|
||||
err = hinic3_get_nic_feature_from_hw(nic_dev);
|
||||
if (err) {
|
||||
dev_err(hwdev->dev, "Failed to get nic features\n");
|
||||
goto err_clear_func_svc_used_state;
|
||||
}
|
||||
|
||||
nic_io->feature_cap &= HINIC3_NIC_F_ALL_MASK;
|
||||
nic_io->feature_cap &= HINIC3_NIC_DRV_DEFAULT_FEATURE;
|
||||
dev_dbg(hwdev->dev, "nic features: 0x%llx\n\n", nic_io->feature_cap);
|
||||
|
||||
return 0;
|
||||
|
||||
err_clear_func_svc_used_state:
|
||||
hinic3_set_func_svc_used_state(hwdev, COMM_FUNC_SVC_T_NIC, 0);
|
||||
err_free_nicio:
|
||||
nic_dev->nic_io = NULL;
|
||||
kfree(nic_io);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void hinic3_free_nic_io(struct hinic3_nic_dev *nic_dev)
|
||||
{
|
||||
/* Completed by later submission due to LoC limit. */
|
||||
struct hinic3_nic_io *nic_io = nic_dev->nic_io;
|
||||
|
||||
hinic3_set_func_svc_used_state(nic_dev->hwdev, COMM_FUNC_SVC_T_NIC, 0);
|
||||
nic_dev->nic_io = NULL;
|
||||
kfree(nic_io);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user