Add HINIC3_INIT_UP flags to trace netdev open status. Add port module event handler. Add link status event type(FAULT, PCIE link down, heart lost, mgmt watchdog). Co-developed-by: Zhu Yikai Signed-off-by: Zhu Yikai Signed-off-by: Fan Gong --- .../net/ethernet/huawei/hinic3/hinic3_hwdev.h | 9 ++++ .../net/ethernet/huawei/hinic3/hinic3_irq.c | 3 +- .../net/ethernet/huawei/hinic3/hinic3_main.c | 50 +++++++++++++++++++ .../huawei/hinic3/hinic3_netdev_ops.c | 12 +++++ .../ethernet/huawei/hinic3/hinic3_nic_cfg.h | 18 +++++++ .../ethernet/huawei/hinic3/hinic3_nic_dev.h | 1 + 6 files changed, 92 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.h b/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.h index 58bc561f95b3..9686c2600b46 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.h +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.h @@ -17,6 +17,15 @@ enum hinic3_event_service_type { HINIC3_EVENT_SRV_NIC = 1 }; +enum hinic3_comm_event_type { + HINIC3_COMM_EVENT_PCIE_LINK_DOWN = 0, + HINIC3_COMM_EVENT_HEART_LOST = 1, + HINIC3_COMM_EVENT_FAULT = 2, + HINIC3_COMM_EVENT_SRIOV_STATE_CHANGE = 3, + HINIC3_COMM_EVENT_CARD_REMOVE = 4, + HINIC3_COMM_EVENT_MGMT_WATCHDOG = 5, +}; + enum hinic3_fault_err_level { HINIC3_FAULT_LEVEL_SERIOUS_FLR = 3, }; diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c index 604e09812977..8a47320ffd3f 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c @@ -19,7 +19,8 @@ static void hinic3_net_dim(struct hinic3_nic_dev *nic_dev, struct hinic3_rxq *rxq = irq_cfg->rxq; struct dim_sample sample = {}; - if (!nic_dev->adaptive_rx_coal) + if (!test_bit(HINIC3_INTF_UP, &nic_dev->flags) || + !nic_dev->adaptive_rx_coal) return; dim_update_sample(irq_cfg->total_events, rxq->rxq_stats.packets, diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c index 463609585f46..c556c853859d 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c @@ -416,6 +416,44 @@ static void hinic3_link_status_change(struct net_device *netdev, } } +static void hinic3_port_module_event_handler(struct net_device *netdev, + struct hinic3_event_info *event) +{ + const char *g_hinic3_module_link_err[LINK_ERR_NUM] = { + "Unrecognized module" + }; + struct hinic3_port_module_event *module_event; + enum port_module_event_type type; + enum link_err_type err_type; + + module_event = (struct hinic3_port_module_event *)event->event_data; + type = module_event->type; + err_type = module_event->err_type; + + switch (type) { + case HINIC3_PORT_MODULE_CABLE_PLUGGED: + case HINIC3_PORT_MODULE_CABLE_UNPLUGGED: + netdev_info(netdev, "Port module event: Cable %s\n", + type == HINIC3_PORT_MODULE_CABLE_PLUGGED ? + "plugged" : "unplugged"); + break; + case HINIC3_PORT_MODULE_LINK_ERR: + if (err_type >= LINK_ERR_NUM) { + netdev_info(netdev, "Link failed, Unknown error type: 0x%x\n", + err_type); + } else { + netdev_info(netdev, + "Link failed, error type: 0x%x: %s\n", + err_type, + g_hinic3_module_link_err[err_type]); + } + break; + default: + netdev_err(netdev, "Unknown port module type %d\n", type); + break; + } +} + static void hinic3_nic_event(struct auxiliary_device *adev, struct hinic3_event_info *event) { @@ -429,8 +467,20 @@ static void hinic3_nic_event(struct auxiliary_device *adev, HINIC3_NIC_EVENT_LINK_UP): hinic3_link_status_change(netdev, true); break; + case HINIC3_SRV_EVENT_TYPE(HINIC3_EVENT_SRV_NIC, + HINIC3_NIC_EVENT_PORT_MODULE_EVENT): + hinic3_port_module_event_handler(netdev, event); + break; case HINIC3_SRV_EVENT_TYPE(HINIC3_EVENT_SRV_NIC, HINIC3_NIC_EVENT_LINK_DOWN): + case HINIC3_SRV_EVENT_TYPE(HINIC3_EVENT_SRV_COMM, + HINIC3_COMM_EVENT_FAULT): + case HINIC3_SRV_EVENT_TYPE(HINIC3_EVENT_SRV_COMM, + HINIC3_COMM_EVENT_PCIE_LINK_DOWN): + case HINIC3_SRV_EVENT_TYPE(HINIC3_EVENT_SRV_COMM, + HINIC3_COMM_EVENT_HEART_LOST): + case HINIC3_SRV_EVENT_TYPE(HINIC3_EVENT_SRV_COMM, + HINIC3_COMM_EVENT_MGMT_WATCHDOG): hinic3_link_status_change(netdev, false); break; default: diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c index 52bc30cc8a0b..439f1cecc2b4 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c @@ -430,6 +430,11 @@ static int hinic3_open(struct net_device *netdev) struct hinic3_dyna_qp_params qp_params; int err; + if (test_bit(HINIC3_INTF_UP, &nic_dev->flags)) { + netdev_dbg(netdev, "Netdev already open, do nothing\n"); + return 0; + } + err = hinic3_init_nicio_res(nic_dev); if (err) { netdev_err(netdev, "Failed to init nicio resources\n"); @@ -457,6 +462,8 @@ static int hinic3_open(struct net_device *netdev) if (err) goto err_close_channel; + set_bit(HINIC3_INTF_UP, &nic_dev->flags); + return 0; err_close_channel: @@ -477,6 +484,11 @@ static int hinic3_close(struct net_device *netdev) struct hinic3_nic_dev *nic_dev = netdev_priv(netdev); struct hinic3_dyna_qp_params qp_params; + if (!test_and_clear_bit(HINIC3_INTF_UP, &nic_dev->flags)) { + netdev_dbg(netdev, "Netdev already close, do nothing\n"); + return 0; + } + hinic3_vport_down(netdev); hinic3_close_channel(netdev); hinic3_uninit_qps(nic_dev, &qp_params); diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h index f83913e74cb5..c32eaa886e17 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h @@ -22,6 +22,7 @@ struct hinic3_nic_dev; enum hinic3_nic_event_type { HINIC3_NIC_EVENT_LINK_DOWN = 0, HINIC3_NIC_EVENT_LINK_UP = 1, + HINIC3_NIC_EVENT_PORT_MODULE_EVENT = 2, }; struct hinic3_sq_attr { @@ -51,6 +52,23 @@ struct mag_cmd_set_port_enable { u8 rsvd1[3]; }; +enum link_err_type { + LINK_ERR_MODULE_UNRECOGENIZED, + LINK_ERR_NUM, +}; + +enum port_module_event_type { + HINIC3_PORT_MODULE_CABLE_PLUGGED, + HINIC3_PORT_MODULE_CABLE_UNPLUGGED, + HINIC3_PORT_MODULE_LINK_ERR, + HINIC3_PORT_MODULE_MAX_EVENT, +}; + +struct hinic3_port_module_event { + enum port_module_event_type type; + enum link_err_type err_type; +}; + 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, diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h index 899f60588d25..ff0ce5804d53 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h @@ -16,6 +16,7 @@ (VLAN_N_VID / HINIC3_VLAN_BITMAP_BYTE_SIZE(nic_dev)) enum hinic3_flags { + HINIC3_INTF_UP, HINIC3_MAC_FILTER_CHANGED, HINIC3_RSS_ENABLE, HINIC3_UPDATE_MAC_FILTER, -- 2.43.0