Skip to content

Commit 5711ffd

Browse files
committed
Merge branch 'bnxt_en-error-recovery'
Michael Chan says: ==================== bnxt_en: Error recovery fixes. This series adds some fixes and enhancements to the error recovery logic. The health register logic is improved and we also add missing code to free and re-create VF representors in the firmware after error recovery. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 0d77036 + ac797ce commit 5711ffd

File tree

3 files changed

+115
-27
lines changed

3 files changed

+115
-27
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9532,8 +9532,8 @@ static int bnxt_try_recover_fw(struct bnxt *bp)
95329532
do {
95339533
sts = bnxt_fw_health_readl(bp, BNXT_FW_HEALTH_REG);
95349534
rc = __bnxt_hwrm_ver_get(bp, true);
9535-
if (!sts || (!BNXT_FW_IS_BOOTING(sts) &&
9536-
!BNXT_FW_IS_RECOVERING(sts)))
9535+
if (!BNXT_FW_IS_BOOTING(sts) &&
9536+
!BNXT_FW_IS_RECOVERING(sts))
95379537
break;
95389538
retry++;
95399539
} while (rc == -EBUSY && retry < BNXT_FW_RETRY);
@@ -11081,6 +11081,7 @@ static void bnxt_fw_reset_close(struct bnxt *bp)
1108111081
pci_disable_device(bp->pdev);
1108211082
}
1108311083
__bnxt_close_nic(bp, true, false);
11084+
bnxt_vf_reps_free(bp);
1108411085
bnxt_clear_int_mode(bp);
1108511086
bnxt_hwrm_func_drv_unrgtr(bp);
1108611087
if (pci_is_enabled(bp->pdev))
@@ -11825,6 +11826,8 @@ static void bnxt_fw_reset_task(struct work_struct *work)
1182511826
bnxt_ulp_start(bp, rc);
1182611827
if (!rc)
1182711828
bnxt_reenable_sriov(bp);
11829+
bnxt_vf_reps_alloc(bp);
11830+
bnxt_vf_reps_open(bp);
1182811831
bnxt_dl_health_recovery_done(bp);
1182911832
bnxt_dl_health_status_update(bp, true);
1183011833
rtnl_unlock();
@@ -12972,6 +12975,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1297212975
rc);
1297312976
}
1297412977

12978+
bnxt_inv_fw_health_reg(bp);
1297512979
bnxt_dl_register(bp);
1297612980

1297712981
rc = register_netdev(dev);

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

Lines changed: 97 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,26 @@ void bnxt_vf_reps_open(struct bnxt *bp)
284284
if (bp->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
285285
return;
286286

287-
for (i = 0; i < pci_num_vf(bp->pdev); i++)
288-
bnxt_vf_rep_open(bp->vf_reps[i]->dev);
287+
for (i = 0; i < pci_num_vf(bp->pdev); i++) {
288+
/* Open the VF-Rep only if it is allocated in the FW */
289+
if (bp->vf_reps[i]->tx_cfa_action != CFA_HANDLE_INVALID)
290+
bnxt_vf_rep_open(bp->vf_reps[i]->dev);
291+
}
292+
}
293+
294+
static void __bnxt_free_one_vf_rep(struct bnxt *bp, struct bnxt_vf_rep *vf_rep)
295+
{
296+
if (!vf_rep)
297+
return;
298+
299+
if (vf_rep->dst) {
300+
dst_release((struct dst_entry *)vf_rep->dst);
301+
vf_rep->dst = NULL;
302+
}
303+
if (vf_rep->tx_cfa_action != CFA_HANDLE_INVALID) {
304+
hwrm_cfa_vfr_free(bp, vf_rep->vf_idx);
305+
vf_rep->tx_cfa_action = CFA_HANDLE_INVALID;
306+
}
289307
}
290308

291309
static void __bnxt_vf_reps_destroy(struct bnxt *bp)
@@ -297,11 +315,7 @@ static void __bnxt_vf_reps_destroy(struct bnxt *bp)
297315
for (i = 0; i < num_vfs; i++) {
298316
vf_rep = bp->vf_reps[i];
299317
if (vf_rep) {
300-
dst_release((struct dst_entry *)vf_rep->dst);
301-
302-
if (vf_rep->tx_cfa_action != CFA_HANDLE_INVALID)
303-
hwrm_cfa_vfr_free(bp, vf_rep->vf_idx);
304-
318+
__bnxt_free_one_vf_rep(bp, vf_rep);
305319
if (vf_rep->dev) {
306320
/* if register_netdev failed, then netdev_ops
307321
* would have been set to NULL
@@ -350,6 +364,80 @@ void bnxt_vf_reps_destroy(struct bnxt *bp)
350364
__bnxt_vf_reps_destroy(bp);
351365
}
352366

367+
/* Free the VF-Reps in firmware, during firmware hot-reset processing.
368+
* Note that the VF-Rep netdevs are still active (not unregistered) during
369+
* this process. As the mode transition from SWITCHDEV to LEGACY happens
370+
* under the rtnl_lock() this routine is safe under the rtnl_lock().
371+
*/
372+
void bnxt_vf_reps_free(struct bnxt *bp)
373+
{
374+
u16 num_vfs = pci_num_vf(bp->pdev);
375+
int i;
376+
377+
if (bp->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
378+
return;
379+
380+
for (i = 0; i < num_vfs; i++)
381+
__bnxt_free_one_vf_rep(bp, bp->vf_reps[i]);
382+
}
383+
384+
static int bnxt_alloc_vf_rep(struct bnxt *bp, struct bnxt_vf_rep *vf_rep,
385+
u16 *cfa_code_map)
386+
{
387+
/* get cfa handles from FW */
388+
if (hwrm_cfa_vfr_alloc(bp, vf_rep->vf_idx, &vf_rep->tx_cfa_action,
389+
&vf_rep->rx_cfa_code))
390+
return -ENOLINK;
391+
392+
cfa_code_map[vf_rep->rx_cfa_code] = vf_rep->vf_idx;
393+
vf_rep->dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, GFP_KERNEL);
394+
if (!vf_rep->dst)
395+
return -ENOMEM;
396+
397+
/* only cfa_action is needed to mux a packet while TXing */
398+
vf_rep->dst->u.port_info.port_id = vf_rep->tx_cfa_action;
399+
vf_rep->dst->u.port_info.lower_dev = bp->dev;
400+
401+
return 0;
402+
}
403+
404+
/* Allocate the VF-Reps in firmware, during firmware hot-reset processing.
405+
* Note that the VF-Rep netdevs are still active (not unregistered) during
406+
* this process. As the mode transition from SWITCHDEV to LEGACY happens
407+
* under the rtnl_lock() this routine is safe under the rtnl_lock().
408+
*/
409+
int bnxt_vf_reps_alloc(struct bnxt *bp)
410+
{
411+
u16 *cfa_code_map = bp->cfa_code_map, num_vfs = pci_num_vf(bp->pdev);
412+
struct bnxt_vf_rep *vf_rep;
413+
int rc, i;
414+
415+
if (bp->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
416+
return 0;
417+
418+
if (!cfa_code_map)
419+
return -EINVAL;
420+
421+
for (i = 0; i < MAX_CFA_CODE; i++)
422+
cfa_code_map[i] = VF_IDX_INVALID;
423+
424+
for (i = 0; i < num_vfs; i++) {
425+
vf_rep = bp->vf_reps[i];
426+
vf_rep->vf_idx = i;
427+
428+
rc = bnxt_alloc_vf_rep(bp, vf_rep, cfa_code_map);
429+
if (rc)
430+
goto err;
431+
}
432+
433+
return 0;
434+
435+
err:
436+
netdev_info(bp->dev, "%s error=%d\n", __func__, rc);
437+
bnxt_vf_reps_free(bp);
438+
return rc;
439+
}
440+
353441
/* Use the OUI of the PF's perm addr and report the same mac addr
354442
* for the same VF-rep each time
355443
*/
@@ -428,25 +516,9 @@ static int bnxt_vf_reps_create(struct bnxt *bp)
428516
vf_rep->vf_idx = i;
429517
vf_rep->tx_cfa_action = CFA_HANDLE_INVALID;
430518

431-
/* get cfa handles from FW */
432-
rc = hwrm_cfa_vfr_alloc(bp, vf_rep->vf_idx,
433-
&vf_rep->tx_cfa_action,
434-
&vf_rep->rx_cfa_code);
435-
if (rc) {
436-
rc = -ENOLINK;
519+
rc = bnxt_alloc_vf_rep(bp, vf_rep, cfa_code_map);
520+
if (rc)
437521
goto err;
438-
}
439-
cfa_code_map[vf_rep->rx_cfa_code] = vf_rep->vf_idx;
440-
441-
vf_rep->dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
442-
GFP_KERNEL);
443-
if (!vf_rep->dst) {
444-
rc = -ENOMEM;
445-
goto err;
446-
}
447-
/* only cfa_action is needed to mux a packet while TXing */
448-
vf_rep->dst->u.port_info.port_id = vf_rep->tx_cfa_action;
449-
vf_rep->dst->u.port_info.lower_dev = bp->dev;
450522

451523
bnxt_vf_rep_netdev_init(bp, vf_rep, dev);
452524
rc = register_netdev(dev);

drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ void bnxt_vf_reps_close(struct bnxt *bp);
1919
void bnxt_vf_reps_open(struct bnxt *bp);
2020
void bnxt_vf_rep_rx(struct bnxt *bp, struct sk_buff *skb);
2121
struct net_device *bnxt_get_vf_rep(struct bnxt *bp, u16 cfa_code);
22+
int bnxt_vf_reps_alloc(struct bnxt *bp);
23+
void bnxt_vf_reps_free(struct bnxt *bp);
2224

2325
static inline u16 bnxt_vf_rep_get_fid(struct net_device *dev)
2426
{
@@ -61,5 +63,15 @@ static inline bool bnxt_dev_is_vf_rep(struct net_device *dev)
6163
{
6264
return false;
6365
}
66+
67+
static inline int bnxt_vf_reps_alloc(struct bnxt *bp)
68+
{
69+
return 0;
70+
}
71+
72+
static inline void bnxt_vf_reps_free(struct bnxt *bp)
73+
{
74+
}
75+
6476
#endif /* CONFIG_BNXT_SRIOV */
6577
#endif /* BNXT_VFR_H */

0 commit comments

Comments
 (0)