Commit ac797ced authored by Sriharsha Basavapatna's avatar Sriharsha Basavapatna Committed by David S. Miller

bnxt_en: Free and allocate VF-Reps during error recovery.

During firmware recovery, VF-Rep configuration in the firmware is lost.
Fix it by freeing and (re)allocating VF-Reps in FW at relevant points
during the error recovery process.
Signed-off-by: default avatarSriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 90f4fd02
...@@ -11081,6 +11081,7 @@ static void bnxt_fw_reset_close(struct bnxt *bp) ...@@ -11081,6 +11081,7 @@ static void bnxt_fw_reset_close(struct bnxt *bp)
pci_disable_device(bp->pdev); pci_disable_device(bp->pdev);
} }
__bnxt_close_nic(bp, true, false); __bnxt_close_nic(bp, true, false);
bnxt_vf_reps_free(bp);
bnxt_clear_int_mode(bp); bnxt_clear_int_mode(bp);
bnxt_hwrm_func_drv_unrgtr(bp); bnxt_hwrm_func_drv_unrgtr(bp);
if (pci_is_enabled(bp->pdev)) if (pci_is_enabled(bp->pdev))
...@@ -11825,6 +11826,8 @@ static void bnxt_fw_reset_task(struct work_struct *work) ...@@ -11825,6 +11826,8 @@ static void bnxt_fw_reset_task(struct work_struct *work)
bnxt_ulp_start(bp, rc); bnxt_ulp_start(bp, rc);
if (!rc) if (!rc)
bnxt_reenable_sriov(bp); bnxt_reenable_sriov(bp);
bnxt_vf_reps_alloc(bp);
bnxt_vf_reps_open(bp);
bnxt_dl_health_recovery_done(bp); bnxt_dl_health_recovery_done(bp);
bnxt_dl_health_status_update(bp, true); bnxt_dl_health_status_update(bp, true);
rtnl_unlock(); rtnl_unlock();
......
...@@ -284,8 +284,11 @@ void bnxt_vf_reps_open(struct bnxt *bp) ...@@ -284,8 +284,11 @@ void bnxt_vf_reps_open(struct bnxt *bp)
if (bp->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV) if (bp->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
return; return;
for (i = 0; i < pci_num_vf(bp->pdev); i++) for (i = 0; i < pci_num_vf(bp->pdev); i++) {
/* Open the VF-Rep only if it is allocated in the FW */
if (bp->vf_reps[i]->tx_cfa_action != CFA_HANDLE_INVALID)
bnxt_vf_rep_open(bp->vf_reps[i]->dev); bnxt_vf_rep_open(bp->vf_reps[i]->dev);
}
} }
static void __bnxt_free_one_vf_rep(struct bnxt *bp, struct bnxt_vf_rep *vf_rep) static void __bnxt_free_one_vf_rep(struct bnxt *bp, struct bnxt_vf_rep *vf_rep)
...@@ -361,6 +364,23 @@ void bnxt_vf_reps_destroy(struct bnxt *bp) ...@@ -361,6 +364,23 @@ void bnxt_vf_reps_destroy(struct bnxt *bp)
__bnxt_vf_reps_destroy(bp); __bnxt_vf_reps_destroy(bp);
} }
/* Free the VF-Reps in firmware, during firmware hot-reset processing.
* Note that the VF-Rep netdevs are still active (not unregistered) during
* this process. As the mode transition from SWITCHDEV to LEGACY happens
* under the rtnl_lock() this routine is safe under the rtnl_lock().
*/
void bnxt_vf_reps_free(struct bnxt *bp)
{
u16 num_vfs = pci_num_vf(bp->pdev);
int i;
if (bp->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
return;
for (i = 0; i < num_vfs; i++)
__bnxt_free_one_vf_rep(bp, bp->vf_reps[i]);
}
static int bnxt_alloc_vf_rep(struct bnxt *bp, struct bnxt_vf_rep *vf_rep, static int bnxt_alloc_vf_rep(struct bnxt *bp, struct bnxt_vf_rep *vf_rep,
u16 *cfa_code_map) u16 *cfa_code_map)
{ {
...@@ -381,6 +401,43 @@ static int bnxt_alloc_vf_rep(struct bnxt *bp, struct bnxt_vf_rep *vf_rep, ...@@ -381,6 +401,43 @@ static int bnxt_alloc_vf_rep(struct bnxt *bp, struct bnxt_vf_rep *vf_rep,
return 0; return 0;
} }
/* Allocate the VF-Reps in firmware, during firmware hot-reset processing.
* Note that the VF-Rep netdevs are still active (not unregistered) during
* this process. As the mode transition from SWITCHDEV to LEGACY happens
* under the rtnl_lock() this routine is safe under the rtnl_lock().
*/
int bnxt_vf_reps_alloc(struct bnxt *bp)
{
u16 *cfa_code_map = bp->cfa_code_map, num_vfs = pci_num_vf(bp->pdev);
struct bnxt_vf_rep *vf_rep;
int rc, i;
if (bp->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
return 0;
if (!cfa_code_map)
return -EINVAL;
for (i = 0; i < MAX_CFA_CODE; i++)
cfa_code_map[i] = VF_IDX_INVALID;
for (i = 0; i < num_vfs; i++) {
vf_rep = bp->vf_reps[i];
vf_rep->vf_idx = i;
rc = bnxt_alloc_vf_rep(bp, vf_rep, cfa_code_map);
if (rc)
goto err;
}
return 0;
err:
netdev_info(bp->dev, "%s error=%d\n", __func__, rc);
bnxt_vf_reps_free(bp);
return rc;
}
/* Use the OUI of the PF's perm addr and report the same mac addr /* Use the OUI of the PF's perm addr and report the same mac addr
* for the same VF-rep each time * for the same VF-rep each time
*/ */
......
...@@ -19,6 +19,8 @@ void bnxt_vf_reps_close(struct bnxt *bp); ...@@ -19,6 +19,8 @@ void bnxt_vf_reps_close(struct bnxt *bp);
void bnxt_vf_reps_open(struct bnxt *bp); void bnxt_vf_reps_open(struct bnxt *bp);
void bnxt_vf_rep_rx(struct bnxt *bp, struct sk_buff *skb); void bnxt_vf_rep_rx(struct bnxt *bp, struct sk_buff *skb);
struct net_device *bnxt_get_vf_rep(struct bnxt *bp, u16 cfa_code); struct net_device *bnxt_get_vf_rep(struct bnxt *bp, u16 cfa_code);
int bnxt_vf_reps_alloc(struct bnxt *bp);
void bnxt_vf_reps_free(struct bnxt *bp);
static inline u16 bnxt_vf_rep_get_fid(struct net_device *dev) static inline u16 bnxt_vf_rep_get_fid(struct net_device *dev)
{ {
...@@ -61,5 +63,15 @@ static inline bool bnxt_dev_is_vf_rep(struct net_device *dev) ...@@ -61,5 +63,15 @@ static inline bool bnxt_dev_is_vf_rep(struct net_device *dev)
{ {
return false; return false;
} }
static inline int bnxt_vf_reps_alloc(struct bnxt *bp)
{
return 0;
}
static inline void bnxt_vf_reps_free(struct bnxt *bp)
{
}
#endif /* CONFIG_BNXT_SRIOV */ #endif /* CONFIG_BNXT_SRIOV */
#endif /* BNXT_VFR_H */ #endif /* BNXT_VFR_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment