i40e: enable early hardware support

Enable a couple of workarounds based on revision ID that allow the
driver to work more fully on early hardware.

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
Jesse Brandeburg 2013-11-26 08:56:05 +00:00 committed by Jeff Kirsher
parent e1c51b9586
commit 7134f9cee0
4 changed files with 68 additions and 10 deletions

View File

@ -61,6 +61,7 @@
#define I40E_BASE_VSI_SEID 512 #define I40E_BASE_VSI_SEID 512
#define I40E_BASE_VEB_SEID 288 #define I40E_BASE_VEB_SEID 288
#define I40E_MAX_VEB 16 #define I40E_MAX_VEB 16
#define I40E_MAX_NPAR_QPS 32
#define I40E_MAX_NUM_DESCRIPTORS 4096 #define I40E_MAX_NUM_DESCRIPTORS 4096
#define I40E_MAX_REGISTER 0x0038FFFF #define I40E_MAX_REGISTER 0x0038FFFF

View File

@ -312,6 +312,8 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
return media; return media;
} }
#define I40E_PF_RESET_WAIT_COUNT_A0 200
#define I40E_PF_RESET_WAIT_COUNT 10
/** /**
* i40e_pf_reset - Reset the PF * i40e_pf_reset - Reset the PF
* @hw: pointer to the hardware structure * @hw: pointer to the hardware structure
@ -321,7 +323,7 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
**/ **/
i40e_status i40e_pf_reset(struct i40e_hw *hw) i40e_status i40e_pf_reset(struct i40e_hw *hw)
{ {
u32 wait_cnt = 0; u32 cnt = 0;
u32 reg = 0; u32 reg = 0;
u32 grst_del; u32 grst_del;
@ -331,7 +333,7 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw)
*/ */
grst_del = rd32(hw, I40E_GLGEN_RSTCTL) & I40E_GLGEN_RSTCTL_GRSTDEL_MASK grst_del = rd32(hw, I40E_GLGEN_RSTCTL) & I40E_GLGEN_RSTCTL_GRSTDEL_MASK
>> I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT; >> I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT;
for (wait_cnt = 0; wait_cnt < grst_del + 2; wait_cnt++) { for (cnt = 0; cnt < grst_del + 2; cnt++) {
reg = rd32(hw, I40E_GLGEN_RSTAT); reg = rd32(hw, I40E_GLGEN_RSTAT);
if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK)) if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK))
break; break;
@ -352,11 +354,15 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw)
/* If there was a Global Reset in progress when we got here, /* If there was a Global Reset in progress when we got here,
* we don't need to do the PF Reset * we don't need to do the PF Reset
*/ */
if (!wait_cnt) { if (!cnt) {
if (hw->revision_id == 0)
cnt = I40E_PF_RESET_WAIT_COUNT_A0;
else
cnt = I40E_PF_RESET_WAIT_COUNT;
reg = rd32(hw, I40E_PFGEN_CTRL); reg = rd32(hw, I40E_PFGEN_CTRL);
wr32(hw, I40E_PFGEN_CTRL, wr32(hw, I40E_PFGEN_CTRL,
(reg | I40E_PFGEN_CTRL_PFSWR_MASK)); (reg | I40E_PFGEN_CTRL_PFSWR_MASK));
for (wait_cnt = 0; wait_cnt < 10; wait_cnt++) { for (; cnt; cnt--) {
reg = rd32(hw, I40E_PFGEN_CTRL); reg = rd32(hw, I40E_PFGEN_CTRL);
if (!(reg & I40E_PFGEN_CTRL_PFSWR_MASK)) if (!(reg & I40E_PFGEN_CTRL_PFSWR_MASK))
break; break;
@ -385,8 +391,14 @@ void i40e_clear_pxe_mode(struct i40e_hw *hw)
/* Clear single descriptor fetch/write-back mode */ /* Clear single descriptor fetch/write-back mode */
reg = rd32(hw, I40E_GLLAN_RCTL_0); reg = rd32(hw, I40E_GLLAN_RCTL_0);
if (hw->revision_id == 0) {
/* As a work around clear PXE_MODE instead of setting it */
wr32(hw, I40E_GLLAN_RCTL_0, (reg & (~I40E_GLLAN_RCTL_0_PXE_MODE_MASK)));
} else {
wr32(hw, I40E_GLLAN_RCTL_0, (reg | I40E_GLLAN_RCTL_0_PXE_MODE_MASK)); wr32(hw, I40E_GLLAN_RCTL_0, (reg | I40E_GLLAN_RCTL_0_PXE_MODE_MASK));
} }
}
/** /**
* i40e_led_get - return current on/off mode * i40e_led_get - return current on/off mode

View File

@ -574,10 +574,11 @@ static void i40e_update_veb_stats(struct i40e_veb *veb)
i40e_stat_update32(hw, I40E_GLSW_TDPC(idx), i40e_stat_update32(hw, I40E_GLSW_TDPC(idx),
veb->stat_offsets_loaded, veb->stat_offsets_loaded,
&oes->tx_discards, &es->tx_discards); &oes->tx_discards, &es->tx_discards);
if (hw->revision_id > 0)
i40e_stat_update32(hw, I40E_GLSW_RUPP(idx), i40e_stat_update32(hw, I40E_GLSW_RUPP(idx),
veb->stat_offsets_loaded, veb->stat_offsets_loaded,
&oes->rx_unknown_protocol, &es->rx_unknown_protocol); &oes->rx_unknown_protocol,
&es->rx_unknown_protocol);
i40e_stat_update48(hw, I40E_GLSW_GORCH(idx), I40E_GLSW_GORCL(idx), i40e_stat_update48(hw, I40E_GLSW_GORCH(idx), I40E_GLSW_GORCL(idx),
veb->stat_offsets_loaded, veb->stat_offsets_loaded,
&oes->rx_bytes, &es->rx_bytes); &oes->rx_bytes, &es->rx_bytes);
@ -2240,6 +2241,9 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
rx_ctx.tphwdesc_ena = 1; rx_ctx.tphwdesc_ena = 1;
rx_ctx.tphdata_ena = 1; rx_ctx.tphdata_ena = 1;
rx_ctx.tphhead_ena = 1; rx_ctx.tphhead_ena = 1;
if (hw->revision_id == 0)
rx_ctx.lrxqthresh = 0;
else
rx_ctx.lrxqthresh = 2; rx_ctx.lrxqthresh = 2;
rx_ctx.crcstrip = 1; rx_ctx.crcstrip = 1;
rx_ctx.l2tsel = 1; rx_ctx.l2tsel = 1;
@ -3021,6 +3025,9 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable)
} }
} }
if (hw->revision_id == 0)
mdelay(50);
return 0; return 0;
} }
@ -4612,6 +4619,13 @@ static int i40e_get_capabilities(struct i40e_pf *pf)
} }
} while (err); } while (err);
if (pf->hw.revision_id == 0 && pf->hw.func_caps.npar_enable) {
pf->hw.func_caps.num_msix_vectors += 1;
pf->hw.func_caps.num_tx_qp =
min_t(int, pf->hw.func_caps.num_tx_qp,
I40E_MAX_NPAR_QPS);
}
if (pf->hw.debug_mask & I40E_DEBUG_USER) if (pf->hw.debug_mask & I40E_DEBUG_USER)
dev_info(&pf->pdev->dev, dev_info(&pf->pdev->dev,
"pf=%d, num_vfs=%d, msix_pf=%d, msix_vf=%d, fd_g=%d, fd_b=%d, pf_max_q=%d num_vsi=%d\n", "pf=%d, num_vfs=%d, msix_pf=%d, msix_vf=%d, fd_g=%d, fd_b=%d, pf_max_q=%d num_vsi=%d\n",
@ -4623,6 +4637,15 @@ static int i40e_get_capabilities(struct i40e_pf *pf)
pf->hw.func_caps.num_tx_qp, pf->hw.func_caps.num_tx_qp,
pf->hw.func_caps.num_vsis); pf->hw.func_caps.num_vsis);
#define DEF_NUM_VSI (1 + (pf->hw.func_caps.fcoe ? 1 : 0) \
+ pf->hw.func_caps.num_vfs)
if (pf->hw.revision_id == 0 && (DEF_NUM_VSI > pf->hw.func_caps.num_vsis)) {
dev_info(&pf->pdev->dev,
"got num_vsis %d, setting num_vsis to %d\n",
pf->hw.func_caps.num_vsis, DEF_NUM_VSI);
pf->hw.func_caps.num_vsis = DEF_NUM_VSI;
}
return 0; return 0;
} }
@ -5618,7 +5641,12 @@ static int i40e_sw_init(struct i40e_pf *pf)
I40E_FLAG_MQ_ENABLED | I40E_FLAG_MQ_ENABLED |
I40E_FLAG_RX_1BUF_ENABLED; I40E_FLAG_RX_1BUF_ENABLED;
/* Depending on PF configurations, it is possible that the RSS
* maximum might end up larger than the available queues
*/
pf->rss_size_max = 0x1 << pf->hw.func_caps.rss_table_entry_width; pf->rss_size_max = 0x1 << pf->hw.func_caps.rss_table_entry_width;
pf->rss_size_max = min_t(int, pf->rss_size_max,
pf->hw.func_caps.num_tx_qp);
if (pf->hw.func_caps.rss) { if (pf->hw.func_caps.rss) {
pf->flags |= I40E_FLAG_RSS_ENABLED; pf->flags |= I40E_FLAG_RSS_ENABLED;
pf->rss_size = min_t(int, pf->rss_size_max, pf->rss_size = min_t(int, pf->rss_size_max,
@ -7142,6 +7170,17 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
hw->bus.device = PCI_SLOT(pdev->devfn); hw->bus.device = PCI_SLOT(pdev->devfn);
hw->bus.func = PCI_FUNC(pdev->devfn); hw->bus.func = PCI_FUNC(pdev->devfn);
/* do a special CORER for clearing PXE mode once at init */
if (hw->revision_id == 0 &&
(rd32(hw, I40E_GLLAN_RCTL_0) & I40E_GLLAN_RCTL_0_PXE_MODE_MASK)) {
wr32(hw, I40E_GLGEN_RTRIG, I40E_GLGEN_RTRIG_CORER_MASK);
i40e_flush(hw);
msleep(200);
pf->corer_count++;
i40e_clear_pxe_mode(hw);
}
/* Reset here to make sure all is clean and to define PF 'n' */ /* Reset here to make sure all is clean and to define PF 'n' */
err = i40e_pf_reset(hw); err = i40e_pf_reset(hw);
if (err) { if (err) {

View File

@ -2187,6 +2187,12 @@
#define I40E_GLPCI_PCIERR 0x000BE4FC #define I40E_GLPCI_PCIERR 0x000BE4FC
#define I40E_GLPCI_PCIERR_PCIE_ERR_REP_SHIFT 0 #define I40E_GLPCI_PCIERR_PCIE_ERR_REP_SHIFT 0
#define I40E_GLPCI_PCIERR_PCIE_ERR_REP_MASK (0xFFFFFFFF << I40E_GLPCI_PCIERR_PCIE_ERR_REP_SHIFT) #define I40E_GLPCI_PCIERR_PCIE_ERR_REP_MASK (0xFFFFFFFF << I40E_GLPCI_PCIERR_PCIE_ERR_REP_SHIFT)
#define I40E_GLPCI_PCITEST2 0x000BE4BC
#define I40E_GLPCI_PCITEST2_IOV_TEST_MODE_SHIFT 0
#define I40E_GLPCI_PCITEST2_IOV_TEST_MODE_MASK (0x1 << I40E_GLPCI_PCITEST2_IOV_TEST_MODE_SHIFT)
#define I40E_GLPCI_PCITEST2_TAG_ALLOC_SHIFT 1
#define I40E_GLPCI_PCITEST2_TAG_ALLOC_MASK (0x1 << I40E_GLPCI_PCITEST2_TAG_ALLOC_SHIFT)
#define I40E_GLPCI_PKTCT 0x0009C4BC #define I40E_GLPCI_PKTCT 0x0009C4BC
#define I40E_GLPCI_PKTCT_PCI_COUNT_BW_PCT_SHIFT 0 #define I40E_GLPCI_PKTCT_PCI_COUNT_BW_PCT_SHIFT 0
#define I40E_GLPCI_PKTCT_PCI_COUNT_BW_PCT_MASK (0xFFFFFFFF << I40E_GLPCI_PKTCT_PCI_COUNT_BW_PCT_SHIFT) #define I40E_GLPCI_PKTCT_PCI_COUNT_BW_PCT_MASK (0xFFFFFFFF << I40E_GLPCI_PKTCT_PCI_COUNT_BW_PCT_SHIFT)