From be63459e0bdd00fcb679999dc171e50a1486b91f Mon Sep 17 00:00:00 2001 From: Andrew Boyer Date: Wed, 16 Dec 2020 13:12:55 -0800 Subject: [PATCH] net/ionic: improve link state handling Add UP and FW_RESET state flags. Update the stack info when the link state changes. Convert set_link_up/set_link_down to lif_start/lif_stop. Condition reported link state on UP flag. Signed-off-by: Andrew Boyer --- drivers/net/ionic/ionic_ethdev.c | 49 ++++++++++--------------------- drivers/net/ionic/ionic_ethdev.h | 4 +++ drivers/net/ionic/ionic_lif.c | 50 ++++++++++++++++++++++++++------ drivers/net/ionic/ionic_lif.h | 4 ++- 4 files changed, 64 insertions(+), 43 deletions(-) diff --git a/drivers/net/ionic/ionic_ethdev.c b/drivers/net/ionic/ionic_ethdev.c index 7ab32a0d72..fd7cd510e6 100644 --- a/drivers/net/ionic/ionic_ethdev.c +++ b/drivers/net/ionic/ionic_ethdev.c @@ -28,8 +28,6 @@ static int ionic_dev_stop(struct rte_eth_dev *dev); static int ionic_dev_close(struct rte_eth_dev *dev); static int ionic_dev_set_link_up(struct rte_eth_dev *dev); static int ionic_dev_set_link_down(struct rte_eth_dev *dev); -static int ionic_dev_link_update(struct rte_eth_dev *eth_dev, - int wait_to_complete); static int ionic_flow_ctrl_get(struct rte_eth_dev *eth_dev, struct rte_eth_fc_conf *fc_conf); static int ionic_flow_ctrl_set(struct rte_eth_dev *eth_dev, @@ -236,21 +234,17 @@ static int ionic_dev_set_link_up(struct rte_eth_dev *eth_dev) { struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); - struct ionic_adapter *adapter = lif->adapter; - struct ionic_dev *idev = &adapter->idev; int err; IONIC_PRINT_CALL(); - ionic_dev_cmd_port_state(idev, IONIC_PORT_ADMIN_STATE_UP); + err = ionic_lif_start(lif); + if (err) + IONIC_PRINT(ERR, "Could not start lif to set link up"); - err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT); - if (err) { - IONIC_PRINT(WARNING, "Failed to bring port UP"); - return err; - } + ionic_dev_link_update(lif->eth_dev, 0); - return 0; + return err; } /* @@ -260,24 +254,17 @@ static int ionic_dev_set_link_down(struct rte_eth_dev *eth_dev) { struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); - struct ionic_adapter *adapter = lif->adapter; - struct ionic_dev *idev = &adapter->idev; - int err; IONIC_PRINT_CALL(); - ionic_dev_cmd_port_state(idev, IONIC_PORT_ADMIN_STATE_DOWN); + ionic_lif_stop(lif); - err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT); - if (err) { - IONIC_PRINT(WARNING, "Failed to bring port DOWN"); - return err; - } + ionic_dev_link_update(lif->eth_dev, 0); return 0; } -static int +int ionic_dev_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete __rte_unused) { @@ -291,7 +278,8 @@ ionic_dev_link_update(struct rte_eth_dev *eth_dev, memset(&link, 0, sizeof(link)); link.link_autoneg = ETH_LINK_AUTONEG; - if (!adapter->link_up) { + if (!adapter->link_up || + !(lif->state & IONIC_LIF_F_UP)) { /* Interface is down */ link.link_status = ETH_LINK_DOWN; link.link_duplex = ETH_LINK_HALF_DUPLEX; @@ -944,15 +932,12 @@ static int ionic_dev_stop(struct rte_eth_dev *eth_dev) { struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); - int err; IONIC_PRINT_CALL(); - err = ionic_lif_stop(lif); - if (err) - IONIC_PRINT(ERR, "Cannot stop LIF: %d", err); + ionic_lif_stop(lif); - return err; + return 0; } static void ionic_unconfigure_intr(struct ionic_adapter *adapter); @@ -965,17 +950,12 @@ ionic_dev_close(struct rte_eth_dev *eth_dev) { struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); struct ionic_adapter *adapter = lif->adapter; - int err; IONIC_PRINT_CALL(); if (rte_eal_process_type() != RTE_PROC_PRIMARY) return 0; - err = ionic_lif_stop(lif); - if (err) { - IONIC_PRINT(ERR, "Cannot stop LIF: %d", err); - return -1; - } + ionic_lif_stop(lif); ionic_lif_free_queues(lif); @@ -1076,6 +1056,9 @@ eth_ionic_dev_uninit(struct rte_eth_dev *eth_dev) ionic_lif_deinit(lif); ionic_lif_free(lif); + if (!(lif->state & IONIC_LIF_F_FW_RESET)) + ionic_lif_reset(lif); + return 0; } diff --git a/drivers/net/ionic/ionic_ethdev.h b/drivers/net/ionic/ionic_ethdev.h index 578e2301fa..6cbcd0f825 100644 --- a/drivers/net/ionic/ionic_ethdev.h +++ b/drivers/net/ionic/ionic_ethdev.h @@ -5,6 +5,8 @@ #ifndef _IONIC_ETHDEV_H_ #define _IONIC_ETHDEV_H_ +#include + #define IONIC_ETH_RSS_OFFLOAD_ALL ( \ ETH_RSS_IPV4 | \ ETH_RSS_NONFRAG_IPV4_TCP | \ @@ -18,5 +20,7 @@ #define IONIC_ETH_DEV_TO_ADAPTER(eth_dev) \ (IONIC_ETH_DEV_TO_LIF(eth_dev)->adapter) +int ionic_dev_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete); + #endif /* _IONIC_ETHDEV_H_ */ diff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c index 9b11e63101..c1a95ca7c2 100644 --- a/drivers/net/ionic/ionic_lif.c +++ b/drivers/net/ionic/ionic_lif.c @@ -63,12 +63,12 @@ ionic_qcq_disable(struct ionic_qcq *qcq) return ionic_adminq_post_wait(lif, &ctx); } -int -ionic_lif_stop(struct ionic_lif *lif __rte_unused) +void +ionic_lif_stop(struct ionic_lif *lif) { - /* Carrier OFF here */ + IONIC_PRINT_CALL(); - return 0; + lif->state &= ~IONIC_LIF_F_UP; } void @@ -1098,14 +1098,32 @@ ionic_link_status_check(struct ionic_lif *lif) return; if (link_up) { - IONIC_PRINT(DEBUG, "Link up - %d Gbps", - lif->info->status.link_speed); adapter->link_speed = lif->info->status.link_speed; + IONIC_PRINT(DEBUG, "Link up - %d Gbps", + adapter->link_speed); } else { IONIC_PRINT(DEBUG, "Link down"); } adapter->link_up = link_up; + ionic_dev_link_update(lif->eth_dev, 0); +} + +static void +ionic_lif_handle_fw_down(struct ionic_lif *lif) +{ + if (lif->state & IONIC_LIF_F_FW_RESET) + return; + + lif->state |= IONIC_LIF_F_FW_RESET; + + if (lif->state & IONIC_LIF_F_UP) { + IONIC_PRINT(NOTICE, + "Surprise FW stop, stopping %s\n", lif->name); + ionic_lif_stop(lif); + } + + IONIC_PRINT(NOTICE, "FW down, %s stopped", lif->name); } static bool @@ -1127,14 +1145,27 @@ ionic_notifyq_cb(struct ionic_cq *cq, uint32_t cq_desc_index, void *cb_arg) switch (cq_desc->event.ecode) { case IONIC_EVENT_LINK_CHANGE: IONIC_PRINT(DEBUG, - "Notifyq IONIC_EVENT_LINK_CHANGE eid=%jd link_status=%d link_speed=%d", + "Notifyq IONIC_EVENT_LINK_CHANGE %s " + "eid=%jd link_status=%d link_speed=%d", + lif->name, cq_desc->event.eid, cq_desc->link_change.link_status, cq_desc->link_change.link_speed); lif->state |= IONIC_LIF_F_LINK_CHECK_NEEDED; + break; + case IONIC_EVENT_RESET: + IONIC_PRINT(NOTICE, + "Notifyq IONIC_EVENT_RESET %s " + "eid=%jd, reset_code=%d state=%d", + lif->name, + cq_desc->event.eid, + cq_desc->reset.reset_code, + cq_desc->reset.state); + ionic_lif_handle_fw_down(lif); break; + default: IONIC_PRINT(WARNING, "Notifyq bad event ecode=%d eid=%jd", cq_desc->event.ecode, cq_desc->event.eid); @@ -1618,9 +1649,10 @@ ionic_lif_start(struct ionic_lif *lif) } } - ionic_link_status_check(lif); - /* Carrier ON here */ + lif->state |= IONIC_LIF_F_UP; + + ionic_link_status_check(lif); return 0; } diff --git a/drivers/net/ionic/ionic_lif.h b/drivers/net/ionic/ionic_lif.h index cc0e4f04ec..86d933606a 100644 --- a/drivers/net/ionic/ionic_lif.h +++ b/drivers/net/ionic/ionic_lif.h @@ -77,6 +77,8 @@ struct ionic_qcq { #define IONIC_LIF_F_INITED BIT(0) #define IONIC_LIF_F_LINK_CHECK_NEEDED BIT(1) +#define IONIC_LIF_F_UP BIT(2) +#define IONIC_LIF_F_FW_RESET BIT(3) #define IONIC_LIF_NAME_MAX_SZ (32) @@ -127,7 +129,7 @@ int ionic_lif_init(struct ionic_lif *lif); void ionic_lif_deinit(struct ionic_lif *lif); int ionic_lif_start(struct ionic_lif *lif); -int ionic_lif_stop(struct ionic_lif *lif); +void ionic_lif_stop(struct ionic_lif *lif); int ionic_lif_configure(struct ionic_lif *lif); void ionic_lif_reset(struct ionic_lif *lif); -- 2.20.1