Convert to use test_and_clear_bit() for link event subtasks. Only re-arm the WX_FLAG_NEED_MODULE_RESET flag when module is absent. Unsupported or invalid modules no longer cause the service task to continuously retry module identification. Additionally, explicitly cancel service_task during device teardown to ensure no pending asynchronous service work survives after the device has entered the DOWN state. Signed-off-by: Jiawen Wu --- .../net/ethernet/wangxun/txgbe/txgbe_aml.c | 10 +++------- .../net/ethernet/wangxun/txgbe/txgbe_aml.h | 2 +- .../net/ethernet/wangxun/txgbe/txgbe_main.c | 19 ++++++------------- 3 files changed, 10 insertions(+), 21 deletions(-) diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c index f0514251d4f3..da1d3976ed33 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c @@ -186,19 +186,15 @@ static void txgbe_get_mac_link(struct wx *wx, int *speed) *speed = SPEED_UNKNOWN; } -int txgbe_set_phy_link(struct wx *wx) +void txgbe_set_phy_link(struct wx *wx) { int speed, autoneg, duplex, err; txgbe_get_link_capabilities(wx, &speed, &autoneg, &duplex); err = txgbe_set_phy_link_hostif(wx, speed, autoneg, duplex); - if (err) { + if (err) wx_err(wx, "Failed to setup link\n"); - return err; - } - - return 0; } static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sff_id *id) @@ -362,7 +358,7 @@ int txgbe_identify_module(struct wx *wx) id->identifier != TXGBE_SFF_IDENTIFIER_QSFP_PLUS && id->identifier != TXGBE_SFF_IDENTIFIER_QSFP28) { wx_err(wx, "Invalid module\n"); - return -ENODEV; + return -EINVAL; } if (id->transceiver_type == 0xFF) diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.h b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.h index 4f6df0ee860b..379c74ad19c6 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.h +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.h @@ -10,7 +10,7 @@ int txgbe_test_hostif(struct wx *wx); int txgbe_read_eeprom_hostif(struct wx *wx, struct txgbe_hic_i2c_read *buffer, u32 length, u8 *data); -int txgbe_set_phy_link(struct wx *wx); +void txgbe_set_phy_link(struct wx *wx); int txgbe_identify_module(struct wx *wx); void txgbe_setup_link(struct wx *wx); int txgbe_phylink_init_aml(struct txgbe *txgbe); diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c index 6755464b4637..ce82e13aa8ae 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c @@ -93,31 +93,23 @@ static void txgbe_module_detection_subtask(struct wx *wx) { int err; - if (!test_bit(WX_FLAG_NEED_MODULE_RESET, wx->flags)) + if (!test_and_clear_bit(WX_FLAG_NEED_MODULE_RESET, wx->flags)) return; /* wait for SFF module ready */ msleep(200); err = txgbe_identify_module(wx); - if (err) - return; - - clear_bit(WX_FLAG_NEED_MODULE_RESET, wx->flags); + if (err == -ENODEV) + set_bit(WX_FLAG_NEED_MODULE_RESET, wx->flags); } static void txgbe_link_config_subtask(struct wx *wx) { - int err; - - if (!test_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags)) + if (!test_and_clear_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags)) return; - err = txgbe_set_phy_link(wx); - if (err) - return; - - clear_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags); + txgbe_set_phy_link(wx); } /** @@ -233,6 +225,7 @@ static void txgbe_disable_device(struct wx *wx) wx_napi_disable_all(wx); timer_delete_sync(&wx->service_timer); + cancel_work_sync(&wx->service_task); if (wx->bus.func < 2) wr32m(wx, TXGBE_MIS_PRB_CTL, TXGBE_MIS_PRB_CTL_LAN_UP(wx->bus.func), 0); -- 2.51.0