Commit b0b02c77 authored by David S. Miller's avatar David S. Miller

Merge branch 'bnx2x'

Yuval Mintz says:

====================
This patch series mostly revolves around improving SR-IOV implementation
(Better PF-VF relation, sanity checks and timings), as well as including
a patch correcting the (outward) advertisement of 20G capabilities.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a49dd9dc b8e0d884
...@@ -1330,6 +1330,7 @@ enum { ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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 @@ static void bnx2x_sp_rtnl_task(struct work_struct *work) ...@@ -9620,6 +9630,13 @@ static void bnx2x_sp_rtnl_task(struct work_struct *work)
"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)) {
...@@ -10541,6 +10558,10 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg) ...@@ -10541,6 +10558,10 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg)
if (!(bp->link_params.speed_cap_mask[idx] & if (!(bp->link_params.speed_cap_mask[idx] &
PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) PORT_HW_CFG_SPEED_CAPABILITY_D0_10G))
bp->port.supported[idx] &= ~SUPPORTED_10000baseT_Full; bp->port.supported[idx] &= ~SUPPORTED_10000baseT_Full;
if (!(bp->link_params.speed_cap_mask[idx] &
PORT_HW_CFG_SPEED_CAPABILITY_D0_20G))
bp->port.supported[idx] &= ~SUPPORTED_20000baseKR2_Full;
} }
BNX2X_DEV_INFO("supported 0x%x 0x%x\n", bp->port.supported[0], BNX2X_DEV_INFO("supported 0x%x 0x%x\n", bp->port.supported[0],
...@@ -12814,6 +12835,8 @@ static void __bnx2x_remove(struct pci_dev *pdev, ...@@ -12814,6 +12835,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 +12851,6 @@ static void __bnx2x_remove(struct pci_dev *pdev, ...@@ -12828,8 +12851,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,21 +1459,16 @@ static u8 bnx2x_vf_is_pcie_pending(struct bnx2x *bp, u8 abs_vfid) ...@@ -1459,21 +1459,16 @@ 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;
} }
int bnx2x_vf_flr_clnup_epilog(struct bnx2x *bp, u8 abs_vfid) int bnx2x_vf_flr_clnup_epilog(struct bnx2x *bp, u8 abs_vfid)
{ {
/* Wait 100ms */
msleep(100);
/* Verify no pending pci transactions */ /* Verify no pending pci transactions */
if (bnx2x_vf_is_pcie_pending(bp, abs_vfid)) if (bnx2x_vf_is_pcie_pending(bp, abs_vfid))
BNX2X_ERR("PCIE Transactions still pending\n"); BNX2X_ERR("PCIE Transactions still pending\n");
...@@ -2176,6 +2171,9 @@ int bnx2x_iov_nic_init(struct bnx2x *bp) ...@@ -2176,6 +2171,9 @@ int bnx2x_iov_nic_init(struct bnx2x *bp)
DP(BNX2X_MSG_IOV, "num of vfs: %d\n", (bp)->vfdb->sriov.nr_virtfn); DP(BNX2X_MSG_IOV, "num of vfs: %d\n", (bp)->vfdb->sriov.nr_virtfn);
/* let FLR complete ... */
msleep(100);
/* initialize vf database */ /* initialize vf database */
for_each_vf(bp, vfid) { for_each_vf(bp, vfid) {
struct bnx2x_virtf *vf = BP_VF(bp, vfid); struct bnx2x_virtf *vf = BP_VF(bp, vfid);
...@@ -2777,6 +2775,10 @@ int bnx2x_vf_init(struct bnx2x *bp, struct bnx2x_virtf *vf, dma_addr_t *sb_map) ...@@ -2777,6 +2775,10 @@ int bnx2x_vf_init(struct bnx2x *bp, struct bnx2x_virtf *vf, dma_addr_t *sb_map)
vf->abs_vfid, vf->state); vf->abs_vfid, vf->state);
return -EINVAL; return -EINVAL;
} }
/* let FLR complete ... */
msleep(100);
/* FLR cleanup epilogue */ /* FLR cleanup epilogue */
if (bnx2x_vf_flr_clnup_epilog(bp, vf->abs_vfid)) if (bnx2x_vf_flr_clnup_epilog(bp, vf->abs_vfid))
return -EBUSY; return -EBUSY;
...@@ -3085,6 +3087,11 @@ void bnx2x_disable_sriov(struct bnx2x *bp) ...@@ -3085,6 +3087,11 @@ void bnx2x_disable_sriov(struct bnx2x *bp)
static int bnx2x_vf_ndo_sanity(struct bnx2x *bp, int vfidx, static int bnx2x_vf_ndo_sanity(struct bnx2x *bp, int vfidx,
struct bnx2x_virtf *vf) struct bnx2x_virtf *vf)
{ {
if (bp->state != BNX2X_STATE_OPEN) {
BNX2X_ERR("vf ndo called though PF is down\n");
return -EINVAL;
}
if (!IS_SRIOV(bp)) { if (!IS_SRIOV(bp)) {
BNX2X_ERR("vf ndo called though sriov is disabled\n"); BNX2X_ERR("vf ndo called though sriov is disabled\n");
return -EINVAL; return -EINVAL;
...@@ -3469,3 +3476,23 @@ int bnx2x_open_epilog(struct bnx2x *bp) ...@@ -3469,3 +3476,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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 { ...@@ -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];
......
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