diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c index d4c27f849f9b..c2a9e64bc57b 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c @@ -227,6 +227,45 @@ done: spin_unlock_bh(&nn->reconfig_lock); } +static void nfp_net_reconfig_sync_enter(struct nfp_net *nn) +{ + bool cancelled_timer = false; + u32 pre_posted_requests; + + spin_lock_bh(&nn->reconfig_lock); + + nn->reconfig_sync_present = true; + + if (nn->reconfig_timer_active) { + nn->reconfig_timer_active = false; + cancelled_timer = true; + } + pre_posted_requests = nn->reconfig_posted; + nn->reconfig_posted = 0; + + spin_unlock_bh(&nn->reconfig_lock); + + if (cancelled_timer) { + del_timer_sync(&nn->reconfig_timer); + nfp_net_reconfig_wait(nn, nn->reconfig_timer.expires); + } + + /* Run the posted reconfigs which were issued before we started */ + if (pre_posted_requests) { + nfp_net_reconfig_start(nn, pre_posted_requests); + nfp_net_reconfig_wait(nn, jiffies + HZ * NFP_NET_POLL_TIMEOUT); + } +} + +static void nfp_net_reconfig_wait_posted(struct nfp_net *nn) +{ + nfp_net_reconfig_sync_enter(nn); + + spin_lock_bh(&nn->reconfig_lock); + nn->reconfig_sync_present = false; + spin_unlock_bh(&nn->reconfig_lock); +} + /** * nfp_net_reconfig() - Reconfigure the firmware * @nn: NFP Net device to reconfigure @@ -240,32 +279,9 @@ done: */ int nfp_net_reconfig(struct nfp_net *nn, u32 update) { - bool cancelled_timer = false; - u32 pre_posted_requests; int ret; - spin_lock_bh(&nn->reconfig_lock); - - nn->reconfig_sync_present = true; - - if (nn->reconfig_timer_active) { - del_timer(&nn->reconfig_timer); - nn->reconfig_timer_active = false; - cancelled_timer = true; - } - pre_posted_requests = nn->reconfig_posted; - nn->reconfig_posted = 0; - - spin_unlock_bh(&nn->reconfig_lock); - - if (cancelled_timer) - nfp_net_reconfig_wait(nn, nn->reconfig_timer.expires); - - /* Run the posted reconfigs which were issued before we started */ - if (pre_posted_requests) { - nfp_net_reconfig_start(nn, pre_posted_requests); - nfp_net_reconfig_wait(nn, jiffies + HZ * NFP_NET_POLL_TIMEOUT); - } + nfp_net_reconfig_sync_enter(nn); nfp_net_reconfig_start(nn, update); ret = nfp_net_reconfig_wait(nn, jiffies + HZ * NFP_NET_POLL_TIMEOUT); @@ -3609,6 +3625,7 @@ struct nfp_net *nfp_net_alloc(struct pci_dev *pdev, bool needs_netdev, */ void nfp_net_free(struct nfp_net *nn) { + WARN_ON(timer_pending(&nn->reconfig_timer) || nn->reconfig_posted); if (nn->dp.netdev) free_netdev(nn->dp.netdev); else @@ -3893,4 +3910,5 @@ void nfp_net_clean(struct nfp_net *nn) return; unregister_netdev(nn->dp.netdev); + nfp_net_reconfig_wait_posted(nn); }