Skip to content

Commit

Permalink
bnxt_en: Add PHY retry logic.
Browse files Browse the repository at this point in the history
During hotplug, the driver's open function can be called almost
immediately after power on reset.  The PHY may not be ready and the
firmware may return failure when the driver tries to update PHY
settings.  Add retry logic fired from the driver's timer to retry
the operation for 5 seconds.

Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Michael Chan authored and David S. Miller committed Aug 6, 2018
1 parent 55fd0cf commit a1ef4a7
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
31 changes: 30 additions & 1 deletion drivers/net/ethernet/broadcom/bnxt/bnxt.c
Original file line number Diff line number Diff line change
Expand Up @@ -6898,8 +6898,14 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
mutex_lock(&bp->link_lock);
rc = bnxt_update_phy_setting(bp);
mutex_unlock(&bp->link_lock);
if (rc)
if (rc) {
netdev_warn(bp->dev, "failed to update phy settings\n");
if (BNXT_SINGLE_PF(bp)) {
bp->link_info.phy_retry = true;
bp->link_info.phy_retry_expires =
jiffies + 5 * HZ;
}
}
}

if (irq_re_init)
Expand Down Expand Up @@ -7583,6 +7589,16 @@ static void bnxt_timer(struct timer_list *t)
set_bit(BNXT_FLOW_STATS_SP_EVENT, &bp->sp_event);
bnxt_queue_sp_work(bp);
}

if (bp->link_info.phy_retry) {
if (time_after(jiffies, bp->link_info.phy_retry_expires)) {
bp->link_info.phy_retry = 0;
netdev_warn(bp->dev, "failed to update phy settings after maximum retries.\n");
} else {
set_bit(BNXT_UPDATE_PHY_SP_EVENT, &bp->sp_event);
bnxt_queue_sp_work(bp);
}
}
bnxt_restart_timer:
mod_timer(&bp->timer, jiffies + bp->current_interval);
}
Expand Down Expand Up @@ -7670,6 +7686,19 @@ static void bnxt_sp_task(struct work_struct *work)
netdev_err(bp->dev, "SP task can't update link (rc: %x)\n",
rc);
}
if (test_and_clear_bit(BNXT_UPDATE_PHY_SP_EVENT, &bp->sp_event)) {
int rc;

mutex_lock(&bp->link_lock);
rc = bnxt_update_phy_setting(bp);
mutex_unlock(&bp->link_lock);
if (rc) {
netdev_warn(bp->dev, "update phy settings retry failed\n");
} else {
bp->link_info.phy_retry = false;
netdev_info(bp->dev, "update phy settings retry succeeded\n");
}
}
if (test_and_clear_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event)) {
mutex_lock(&bp->link_lock);
bnxt_get_port_module_status(bp);
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/broadcom/bnxt/bnxt.h
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,9 @@ struct bnxt_link_info {
u16 advertising; /* user adv setting */
bool force_link_chng;

bool phy_retry;
unsigned long phy_retry_expires;

/* a copy of phy_qcfg output used to report link
* info to VF
*/
Expand Down Expand Up @@ -1344,6 +1347,7 @@ struct bnxt {
#define BNXT_GENEVE_DEL_PORT_SP_EVENT 13
#define BNXT_LINK_SPEED_CHNG_SP_EVENT 14
#define BNXT_FLOW_STATS_SP_EVENT 15
#define BNXT_UPDATE_PHY_SP_EVENT 16

struct bnxt_hw_resc hw_resc;
struct bnxt_pf_info pf;
Expand Down

0 comments on commit a1ef4a7

Please sign in to comment.