bnx2x: Improve PF behaviour toward VF
If PF is unloaded with loaded VFs, signal towards VFs so they can detect this gracefully. Signed-off-by: Ariel Elior <ariele@broadcom.com> Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> ---- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 2 ++ drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 3 +++ drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 23 +++++++++++++++++++--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 24 ++++++++++++++++++++--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h | 2 ++ drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c | 12 +++++++++++- drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h | 5 ++++- 7 files changed, 63 insertions(+), 8 deletions(-) Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
a49dd9dcb5
commit
78c3bcc5d1
|
@ -1330,6 +1330,7 @@ enum {
|
||||||
BNX2X_SP_RTNL_AFEX_F_UPDATE,
|
BNX2X_SP_RTNL_AFEX_F_UPDATE,
|
||||||
BNX2X_SP_RTNL_ENABLE_SRIOV,
|
BNX2X_SP_RTNL_ENABLE_SRIOV,
|
||||||
BNX2X_SP_RTNL_VFPF_MCAST,
|
BNX2X_SP_RTNL_VFPF_MCAST,
|
||||||
|
BNX2X_SP_RTNL_VFPF_CHANNEL_DOWN,
|
||||||
BNX2X_SP_RTNL_VFPF_STORM_RX_MODE,
|
BNX2X_SP_RTNL_VFPF_STORM_RX_MODE,
|
||||||
BNX2X_SP_RTNL_HYPERVISOR_VLAN,
|
BNX2X_SP_RTNL_HYPERVISOR_VLAN,
|
||||||
};
|
};
|
||||||
|
@ -1500,6 +1501,7 @@ struct bnx2x {
|
||||||
#define USING_SINGLE_MSIX_FLAG (1 << 20)
|
#define USING_SINGLE_MSIX_FLAG (1 << 20)
|
||||||
#define BC_SUPPORTS_DCBX_MSG_NON_PMF (1 << 21)
|
#define BC_SUPPORTS_DCBX_MSG_NON_PMF (1 << 21)
|
||||||
#define IS_VF_FLAG (1 << 22)
|
#define IS_VF_FLAG (1 << 22)
|
||||||
|
#define INTERRUPTS_ENABLED_FLAG (1 << 23)
|
||||||
|
|
||||||
#define BP_NOMCP(bp) ((bp)->flags & NO_MCP_FLAG)
|
#define BP_NOMCP(bp) ((bp)->flags & NO_MCP_FLAG)
|
||||||
|
|
||||||
|
|
|
@ -2871,6 +2871,9 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link)
|
||||||
bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
|
bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
|
||||||
smp_mb();
|
smp_mb();
|
||||||
|
|
||||||
|
/* indicate to VFs that the PF is going down */
|
||||||
|
bnx2x_iov_channel_down(bp);
|
||||||
|
|
||||||
if (CNIC_LOADED(bp))
|
if (CNIC_LOADED(bp))
|
||||||
bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD);
|
bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD);
|
||||||
|
|
||||||
|
|
|
@ -5457,9 +5457,19 @@ static void bnx2x_timer(unsigned long data)
|
||||||
bnx2x_stats_handle(bp, STATS_EVENT_UPDATE);
|
bnx2x_stats_handle(bp, STATS_EVENT_UPDATE);
|
||||||
|
|
||||||
/* sample pf vf bulletin board for new posts from pf */
|
/* sample pf vf bulletin board for new posts from pf */
|
||||||
if (IS_VF(bp))
|
if (IS_VF(bp)) {
|
||||||
bnx2x_sample_bulletin(bp);
|
bnx2x_sample_bulletin(bp);
|
||||||
|
|
||||||
|
/* if channel is down we need to self destruct */
|
||||||
|
if (bp->old_bulletin.valid_bitmap & 1 << CHANNEL_DOWN) {
|
||||||
|
smp_mb__before_clear_bit();
|
||||||
|
set_bit(BNX2X_SP_RTNL_VFPF_CHANNEL_DOWN,
|
||||||
|
&bp->sp_rtnl_state);
|
||||||
|
smp_mb__after_clear_bit();
|
||||||
|
schedule_delayed_work(&bp->sp_rtnl_task, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mod_timer(&bp->timer, jiffies + bp->current_interval);
|
mod_timer(&bp->timer, jiffies + bp->current_interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9620,6 +9630,13 @@ sp_rtnl_not_reset:
|
||||||
"sending set mcast vf pf channel message from rtnl sp-task\n");
|
"sending set mcast vf pf channel message from rtnl sp-task\n");
|
||||||
bnx2x_vfpf_set_mcast(bp->dev);
|
bnx2x_vfpf_set_mcast(bp->dev);
|
||||||
}
|
}
|
||||||
|
if (test_and_clear_bit(BNX2X_SP_RTNL_VFPF_CHANNEL_DOWN,
|
||||||
|
&bp->sp_rtnl_state)){
|
||||||
|
if (!test_bit(__LINK_STATE_NOCARRIER, &bp->dev->state)) {
|
||||||
|
bnx2x_tx_disable(bp);
|
||||||
|
BNX2X_ERR("PF indicated channel is not servicable anymore. This means this VF device is no longer operational\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (test_and_clear_bit(BNX2X_SP_RTNL_VFPF_STORM_RX_MODE,
|
if (test_and_clear_bit(BNX2X_SP_RTNL_VFPF_STORM_RX_MODE,
|
||||||
&bp->sp_rtnl_state)) {
|
&bp->sp_rtnl_state)) {
|
||||||
|
@ -12814,6 +12831,8 @@ static void __bnx2x_remove(struct pci_dev *pdev,
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bnx2x_iov_remove_one(bp);
|
||||||
|
|
||||||
/* Power on: we can't let PCI layer write to us while we are in D3 */
|
/* Power on: we can't let PCI layer write to us while we are in D3 */
|
||||||
if (IS_PF(bp))
|
if (IS_PF(bp))
|
||||||
bnx2x_set_power_state(bp, PCI_D0);
|
bnx2x_set_power_state(bp, PCI_D0);
|
||||||
|
@ -12828,8 +12847,6 @@ static void __bnx2x_remove(struct pci_dev *pdev,
|
||||||
/* Make sure RESET task is not scheduled before continuing */
|
/* Make sure RESET task is not scheduled before continuing */
|
||||||
cancel_delayed_work_sync(&bp->sp_rtnl_task);
|
cancel_delayed_work_sync(&bp->sp_rtnl_task);
|
||||||
|
|
||||||
bnx2x_iov_remove_one(bp);
|
|
||||||
|
|
||||||
/* send message via vfpf channel to release the resources of this vf */
|
/* send message via vfpf channel to release the resources of this vf */
|
||||||
if (IS_VF(bp))
|
if (IS_VF(bp))
|
||||||
bnx2x_vfpf_release(bp);
|
bnx2x_vfpf_release(bp);
|
||||||
|
|
|
@ -1459,13 +1459,11 @@ static u8 bnx2x_vf_is_pcie_pending(struct bnx2x *bp, u8 abs_vfid)
|
||||||
struct bnx2x_virtf *vf = bnx2x_vf_by_abs_fid(bp, abs_vfid);
|
struct bnx2x_virtf *vf = bnx2x_vf_by_abs_fid(bp, abs_vfid);
|
||||||
|
|
||||||
if (!vf)
|
if (!vf)
|
||||||
goto unknown_dev;
|
return false;
|
||||||
|
|
||||||
dev = pci_get_bus_and_slot(vf->bus, vf->devfn);
|
dev = pci_get_bus_and_slot(vf->bus, vf->devfn);
|
||||||
if (dev)
|
if (dev)
|
||||||
return bnx2x_is_pcie_pending(dev);
|
return bnx2x_is_pcie_pending(dev);
|
||||||
|
|
||||||
unknown_dev:
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3469,3 +3467,23 @@ int bnx2x_open_epilog(struct bnx2x *bp)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bnx2x_iov_channel_down(struct bnx2x *bp)
|
||||||
|
{
|
||||||
|
int vf_idx;
|
||||||
|
struct pf_vf_bulletin_content *bulletin;
|
||||||
|
|
||||||
|
if (!IS_SRIOV(bp))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for_each_vf(bp, vf_idx) {
|
||||||
|
/* locate this VFs bulletin board and update the channel down
|
||||||
|
* bit
|
||||||
|
*/
|
||||||
|
bulletin = BP_VF_BULLETIN(bp, vf_idx);
|
||||||
|
bulletin->valid_bitmap |= 1 << CHANNEL_DOWN;
|
||||||
|
|
||||||
|
/* update vf bulletin board */
|
||||||
|
bnx2x_post_vf_bulletin(bp, vf_idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -761,6 +761,7 @@ static inline int bnx2x_vf_headroom(struct bnx2x *bp)
|
||||||
}
|
}
|
||||||
void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp);
|
void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp);
|
||||||
int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs);
|
int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs);
|
||||||
|
void bnx2x_iov_channel_down(struct bnx2x *bp);
|
||||||
int bnx2x_open_epilog(struct bnx2x *bp);
|
int bnx2x_open_epilog(struct bnx2x *bp);
|
||||||
|
|
||||||
#else /* CONFIG_BNX2X_SRIOV */
|
#else /* CONFIG_BNX2X_SRIOV */
|
||||||
|
@ -817,6 +818,7 @@ static inline void __iomem *bnx2x_vf_doorbells(struct bnx2x *bp)
|
||||||
static inline int bnx2x_vf_pci_alloc(struct bnx2x *bp) {return 0; }
|
static inline int bnx2x_vf_pci_alloc(struct bnx2x *bp) {return 0; }
|
||||||
static inline void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp) {}
|
static inline void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp) {}
|
||||||
static inline int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs) {return 0; }
|
static inline int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs) {return 0; }
|
||||||
|
static inline void bnx2x_iov_channel_down(struct bnx2x *bp) {}
|
||||||
static inline int bnx2x_open_epilog(struct bnx2x *bp) {return 0; }
|
static inline int bnx2x_open_epilog(struct bnx2x *bp) {return 0; }
|
||||||
|
|
||||||
#endif /* CONFIG_BNX2X_SRIOV */
|
#endif /* CONFIG_BNX2X_SRIOV */
|
||||||
|
|
|
@ -113,7 +113,7 @@ static int bnx2x_send_msg2pf(struct bnx2x *bp, u8 *done, dma_addr_t msg_mapping)
|
||||||
{
|
{
|
||||||
struct cstorm_vf_zone_data __iomem *zone_data =
|
struct cstorm_vf_zone_data __iomem *zone_data =
|
||||||
REG_ADDR(bp, PXP_VF_ADDR_CSDM_GLOBAL_START);
|
REG_ADDR(bp, PXP_VF_ADDR_CSDM_GLOBAL_START);
|
||||||
int tout = 600, interval = 100; /* wait for 60 seconds */
|
int tout = 100, interval = 100; /* wait for 10 seconds */
|
||||||
|
|
||||||
if (*done) {
|
if (*done) {
|
||||||
BNX2X_ERR("done was non zero before message to pf was sent\n");
|
BNX2X_ERR("done was non zero before message to pf was sent\n");
|
||||||
|
@ -121,6 +121,16 @@ static int bnx2x_send_msg2pf(struct bnx2x *bp, u8 *done, dma_addr_t msg_mapping)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if PF indicated channel is down avoid sending message. Return success
|
||||||
|
* so calling flow can continue
|
||||||
|
*/
|
||||||
|
bnx2x_sample_bulletin(bp);
|
||||||
|
if (bp->old_bulletin.valid_bitmap & 1 << CHANNEL_DOWN) {
|
||||||
|
DP(BNX2X_MSG_IOV, "detecting channel down. Aborting message\n");
|
||||||
|
*done = PFVF_STATUS_SUCCESS;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Write message address */
|
/* Write message address */
|
||||||
writel(U64_LO(msg_mapping),
|
writel(U64_LO(msg_mapping),
|
||||||
&zone_data->non_trigger.vf_pf_channel.msg_addr_lo);
|
&zone_data->non_trigger.vf_pf_channel.msg_addr_lo);
|
||||||
|
|
|
@ -331,7 +331,10 @@ struct pf_vf_bulletin_content {
|
||||||
#define VLAN_VALID 1 /* when set, the vf should not access
|
#define VLAN_VALID 1 /* when set, the vf should not access
|
||||||
* the vfpf channel
|
* the vfpf channel
|
||||||
*/
|
*/
|
||||||
|
#define CHANNEL_DOWN 2 /* vfpf channel is disabled. VFs are not
|
||||||
|
* to attempt to send messages on the
|
||||||
|
* channel after this bit is set
|
||||||
|
*/
|
||||||
u8 mac[ETH_ALEN];
|
u8 mac[ETH_ALEN];
|
||||||
u8 mac_padding[2];
|
u8 mac_padding[2];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue