Skip to content

Commit 30e96f4

Browse files
Michael Chandavem330
authored andcommitted
bnxt_en: Do not read the PTP PHC during chip reset
During error recovery or hot firmware upgrade, the chip may be under reset and the PHC register read cycles may cause completion timeouts. Check that the chip is not under reset condition before proceeding to read the PHC by checking the flag BNXT_STATE_IN_FW_RESET. We also need to take the ptp_lock before we set this flag to prevent race conditions. We need this logic because the PHC now will stay registered after bnxt_close(). Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com> Signed-off-by: Michael Chan <michael.chan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent a521c8a commit 30e96f4

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11397,13 +11397,20 @@ static bool is_bnxt_fw_ok(struct bnxt *bp)
1139711397
static void bnxt_force_fw_reset(struct bnxt *bp)
1139811398
{
1139911399
struct bnxt_fw_health *fw_health = bp->fw_health;
11400+
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
1140011401
u32 wait_dsecs;
1140111402

1140211403
if (!test_bit(BNXT_STATE_OPEN, &bp->state) ||
1140311404
test_bit(BNXT_STATE_IN_FW_RESET, &bp->state))
1140411405
return;
1140511406

11406-
set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
11407+
if (ptp) {
11408+
spin_lock_bh(&ptp->ptp_lock);
11409+
set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
11410+
spin_unlock_bh(&ptp->ptp_lock);
11411+
} else {
11412+
set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
11413+
}
1140711414
bnxt_fw_reset_close(bp);
1140811415
wait_dsecs = fw_health->master_func_wait_dsecs;
1140911416
if (fw_health->master) {
@@ -11459,9 +11466,16 @@ void bnxt_fw_reset(struct bnxt *bp)
1145911466
bnxt_rtnl_lock_sp(bp);
1146011467
if (test_bit(BNXT_STATE_OPEN, &bp->state) &&
1146111468
!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) {
11469+
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
1146211470
int n = 0, tmo;
1146311471

11464-
set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
11472+
if (ptp) {
11473+
spin_lock_bh(&ptp->ptp_lock);
11474+
set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
11475+
spin_unlock_bh(&ptp->ptp_lock);
11476+
} else {
11477+
set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
11478+
}
1146511479
if (bp->pf.active_vfs &&
1146611480
!test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state))
1146711481
n = bnxt_get_registered_vfs(bp);

drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,19 @@ static int bnxt_ptp_settime(struct ptp_clock_info *ptp_info,
5555
}
5656

5757
/* Caller holds ptp_lock */
58-
static u64 bnxt_refclk_read(struct bnxt *bp, struct ptp_system_timestamp *sts)
58+
static int bnxt_refclk_read(struct bnxt *bp, struct ptp_system_timestamp *sts,
59+
u64 *ns)
5960
{
6061
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
61-
u64 ns;
62+
63+
if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state))
64+
return -EIO;
6265

6366
ptp_read_system_prets(sts);
64-
ns = readl(bp->bar0 + ptp->refclk_mapped_regs[0]);
67+
*ns = readl(bp->bar0 + ptp->refclk_mapped_regs[0]);
6568
ptp_read_system_postts(sts);
66-
ns |= (u64)readl(bp->bar0 + ptp->refclk_mapped_regs[1]) << 32;
67-
return ns;
69+
*ns |= (u64)readl(bp->bar0 + ptp->refclk_mapped_regs[1]) << 32;
70+
return 0;
6871
}
6972

7073
static void bnxt_ptp_get_current_time(struct bnxt *bp)
@@ -75,7 +78,7 @@ static void bnxt_ptp_get_current_time(struct bnxt *bp)
7578
return;
7679
spin_lock_bh(&ptp->ptp_lock);
7780
WRITE_ONCE(ptp->old_time, ptp->current_time);
78-
ptp->current_time = bnxt_refclk_read(bp, NULL);
81+
bnxt_refclk_read(bp, NULL, &ptp->current_time);
7982
spin_unlock_bh(&ptp->ptp_lock);
8083
}
8184

@@ -108,9 +111,14 @@ static int bnxt_ptp_gettimex(struct ptp_clock_info *ptp_info,
108111
struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
109112
ptp_info);
110113
u64 ns, cycles;
114+
int rc;
111115

112116
spin_lock_bh(&ptp->ptp_lock);
113-
cycles = bnxt_refclk_read(ptp->bp, sts);
117+
rc = bnxt_refclk_read(ptp->bp, sts, &cycles);
118+
if (rc) {
119+
spin_unlock_bh(&ptp->ptp_lock);
120+
return rc;
121+
}
114122
ns = timecounter_cyc2time(&ptp->tc, cycles);
115123
spin_unlock_bh(&ptp->ptp_lock);
116124
*ts = ns_to_timespec64(ns);
@@ -309,8 +317,10 @@ static void bnxt_unmap_ptp_regs(struct bnxt *bp)
309317
static u64 bnxt_cc_read(const struct cyclecounter *cc)
310318
{
311319
struct bnxt_ptp_cfg *ptp = container_of(cc, struct bnxt_ptp_cfg, cc);
320+
u64 ns = 0;
312321

313-
return bnxt_refclk_read(ptp->bp, NULL);
322+
bnxt_refclk_read(ptp->bp, NULL, &ns);
323+
return ns;
314324
}
315325

316326
static void bnxt_stamp_tx_skb(struct bnxt *bp, struct sk_buff *skb)
@@ -439,7 +449,7 @@ int bnxt_ptp_init(struct bnxt *bp)
439449
}
440450
if (bp->flags & BNXT_FLAG_CHIP_P5) {
441451
spin_lock_bh(&ptp->ptp_lock);
442-
ptp->current_time = bnxt_refclk_read(bp, NULL);
452+
bnxt_refclk_read(bp, NULL, &ptp->current_time);
443453
WRITE_ONCE(ptp->old_time, ptp->current_time);
444454
spin_unlock_bh(&ptp->ptp_lock);
445455
ptp_schedule_worker(ptp->ptp_clock, 0);

0 commit comments

Comments
 (0)