summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbe/ixgbe_main.c')
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c152
1 files changed, 108 insertions, 44 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index a7acb2dee009..d3f4b0ceb3f7 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3228,89 +3228,148 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter,
IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(reg_idx), srrctl);
}
-static void ixgbe_setup_reta(struct ixgbe_adapter *adapter, const u32 *seed)
+/**
+ * Return a number of entries in the RSS indirection table
+ *
+ * @adapter: device handle
+ *
+ * - 82598/82599/X540: 128
+ * - X550(non-SRIOV mode): 512
+ * - X550(SRIOV mode): 64
+ */
+u32 ixgbe_rss_indir_tbl_entries(struct ixgbe_adapter *adapter)
+{
+ if (adapter->hw.mac.type < ixgbe_mac_X550)
+ return 128;
+ else if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
+ return 64;
+ else
+ return 512;
+}
+
+/**
+ * Write the RETA table to HW
+ *
+ * @adapter: device handle
+ *
+ * Write the RSS redirection table stored in adapter.rss_indir_tbl[] to HW.
+ */
+static void ixgbe_store_reta(struct ixgbe_adapter *adapter)
{
+ u32 i, reta_entries = ixgbe_rss_indir_tbl_entries(adapter);
struct ixgbe_hw *hw = &adapter->hw;
u32 reta = 0;
- int i, j;
- int reta_entries = 128;
- u16 rss_i = adapter->ring_feature[RING_F_RSS].indices;
- int indices_multi;
-
- /*
- * Program table for at least 2 queues w/ SR-IOV so that VFs can
- * make full use of any rings they may have. We will use the
- * PSRTYPE register to control how many rings we use within the PF.
- */
- if ((adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) && (rss_i < 2))
- rss_i = 2;
-
- /* Fill out hash function seeds */
- for (i = 0; i < 10; i++)
- IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), seed[i]);
+ u32 indices_multi;
+ u8 *indir_tbl = adapter->rss_indir_tbl;
/* Fill out the redirection table as follows:
- * 82598: 128 (8 bit wide) entries containing pair of 4 bit RSS indices
- * 82599/X540: 128 (8 bit wide) entries containing 4 bit RSS index
- * X550: 512 (8 bit wide) entries containing 6 bit RSS index
+ * - 82598: 8 bit wide entries containing pair of 4 bit RSS
+ * indices.
+ * - 82599/X540: 8 bit wide entries containing 4 bit RSS index
+ * - X550: 8 bit wide entries containing 6 bit RSS index
*/
if (adapter->hw.mac.type == ixgbe_mac_82598EB)
indices_multi = 0x11;
else
indices_multi = 0x1;
- switch (adapter->hw.mac.type) {
- case ixgbe_mac_X550:
- case ixgbe_mac_X550EM_x:
- if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
- reta_entries = 512;
- default:
- break;
- }
-
- /* Fill out redirection table */
- for (i = 0, j = 0; i < reta_entries; i++, j++) {
- if (j == rss_i)
- j = 0;
- reta = (reta << 8) | (j * indices_multi);
+ /* Write redirection table to HW */
+ for (i = 0; i < reta_entries; i++) {
+ reta |= indices_multi * indir_tbl[i] << (i & 0x3) * 8;
if ((i & 3) == 3) {
if (i < 128)
IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta);
else
IXGBE_WRITE_REG(hw, IXGBE_ERETA((i >> 2) - 32),
reta);
+ reta = 0;
}
}
}
-static void ixgbe_setup_vfreta(struct ixgbe_adapter *adapter, const u32 *seed)
+/**
+ * Write the RETA table to HW (for x550 devices in SRIOV mode)
+ *
+ * @adapter: device handle
+ *
+ * Write the RSS redirection table stored in adapter.rss_indir_tbl[] to HW.
+ */
+static void ixgbe_store_vfreta(struct ixgbe_adapter *adapter)
{
+ u32 i, reta_entries = ixgbe_rss_indir_tbl_entries(adapter);
struct ixgbe_hw *hw = &adapter->hw;
u32 vfreta = 0;
+ unsigned int pf_pool = adapter->num_vfs;
+
+ /* Write redirection table to HW */
+ for (i = 0; i < reta_entries; i++) {
+ vfreta |= (u32)adapter->rss_indir_tbl[i] << (i & 0x3) * 8;
+ if ((i & 3) == 3) {
+ IXGBE_WRITE_REG(hw, IXGBE_PFVFRETA(i >> 2, pf_pool),
+ vfreta);
+ vfreta = 0;
+ }
+ }
+}
+
+static void ixgbe_setup_reta(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 i, j;
+ u32 reta_entries = ixgbe_rss_indir_tbl_entries(adapter);
+ u16 rss_i = adapter->ring_feature[RING_F_RSS].indices;
+
+ /* Program table for at least 2 queues w/ SR-IOV so that VFs can
+ * make full use of any rings they may have. We will use the
+ * PSRTYPE register to control how many rings we use within the PF.
+ */
+ if ((adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) && (rss_i < 2))
+ rss_i = 2;
+
+ /* Fill out hash function seeds */
+ for (i = 0; i < 10; i++)
+ IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), adapter->rss_key[i]);
+
+ /* Fill out redirection table */
+ memset(adapter->rss_indir_tbl, 0, sizeof(adapter->rss_indir_tbl));
+
+ for (i = 0, j = 0; i < reta_entries; i++, j++) {
+ if (j == rss_i)
+ j = 0;
+
+ adapter->rss_indir_tbl[i] = j;
+ }
+
+ ixgbe_store_reta(adapter);
+}
+
+static void ixgbe_setup_vfreta(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
u16 rss_i = adapter->ring_feature[RING_F_RSS].indices;
unsigned int pf_pool = adapter->num_vfs;
int i, j;
/* Fill out hash function seeds */
for (i = 0; i < 10; i++)
- IXGBE_WRITE_REG(hw, IXGBE_PFVFRSSRK(i, pf_pool), seed[i]);
+ IXGBE_WRITE_REG(hw, IXGBE_PFVFRSSRK(i, pf_pool),
+ adapter->rss_key[i]);
/* Fill out the redirection table */
for (i = 0, j = 0; i < 64; i++, j++) {
if (j == rss_i)
j = 0;
- vfreta = (vfreta << 8) | j;
- if ((i & 3) == 3)
- IXGBE_WRITE_REG(hw, IXGBE_PFVFRETA(i >> 2, pf_pool),
- vfreta);
+
+ adapter->rss_indir_tbl[i] = j;
}
+
+ ixgbe_store_vfreta(adapter);
}
static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 mrqc = 0, rss_field = 0, vfmrqc = 0;
- u32 rss_key[10];
u32 rxcsum;
/* Disable indicating checksum in descriptor, enables RSS hash */
@@ -3354,7 +3413,7 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
if (adapter->flags2 & IXGBE_FLAG2_RSS_FIELD_IPV6_UDP)
rss_field |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP;
- netdev_rss_key_fill(rss_key, sizeof(rss_key));
+ netdev_rss_key_fill(adapter->rss_key, sizeof(adapter->rss_key));
if ((hw->mac.type >= ixgbe_mac_X550) &&
(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) {
unsigned int pf_pool = adapter->num_vfs;
@@ -3364,12 +3423,12 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
/* Setup RSS through the VF registers */
- ixgbe_setup_vfreta(adapter, rss_key);
+ ixgbe_setup_vfreta(adapter);
vfmrqc = IXGBE_MRQC_RSSEN;
vfmrqc |= rss_field;
IXGBE_WRITE_REG(hw, IXGBE_PFVFMRQC(pf_pool), vfmrqc);
} else {
- ixgbe_setup_reta(adapter, rss_key);
+ ixgbe_setup_reta(adapter);
mrqc |= rss_field;
IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
}
@@ -3599,6 +3658,10 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
/* enable ethertype anti spoofing if hw supports it */
if (hw->mac.ops.set_ethertype_anti_spoofing)
hw->mac.ops.set_ethertype_anti_spoofing(hw, true, i);
+
+ /* Enable/Disable RSS query feature */
+ ixgbe_ndo_set_vf_rss_query_en(adapter->netdev, i,
+ adapter->vfinfo[i].rss_query_enabled);
}
}
@@ -8101,6 +8164,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_set_vf_vlan = ixgbe_ndo_set_vf_vlan,
.ndo_set_vf_rate = ixgbe_ndo_set_vf_bw,
.ndo_set_vf_spoofchk = ixgbe_ndo_set_vf_spoofchk,
+ .ndo_set_vf_rss_query_en = ixgbe_ndo_set_vf_rss_query_en,
.ndo_get_vf_config = ixgbe_ndo_get_vf_config,
.ndo_get_stats64 = ixgbe_get_stats64,
#ifdef CONFIG_IXGBE_DCB