mirror of https://gitee.com/openkylin/linux.git
ixgbe: add support for X550 extended RSS support
The new X550 family of MAC's will have a larger RSS hash (16 -> 64). It will also support individual VF to have their own independent RSS hash key. This patch will enable this functionality Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
9079e41631
commit
0f9b232b17
|
@ -301,6 +301,7 @@ enum ixgbe_ring_f_enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IXGBE_MAX_RSS_INDICES 16
|
#define IXGBE_MAX_RSS_INDICES 16
|
||||||
|
#define IXGBE_MAX_RSS_INDICES_X550 64
|
||||||
#define IXGBE_MAX_VMDQ_INDICES 64
|
#define IXGBE_MAX_VMDQ_INDICES 64
|
||||||
#define IXGBE_MAX_FDIR_INDICES 63 /* based on q_vector limit */
|
#define IXGBE_MAX_FDIR_INDICES 63 /* based on q_vector limit */
|
||||||
#define IXGBE_MAX_FCOE_INDICES 8
|
#define IXGBE_MAX_FCOE_INDICES 8
|
||||||
|
@ -764,6 +765,21 @@ struct ixgbe_adapter {
|
||||||
unsigned long fwd_bitmask; /* Bitmask indicating in use pools */
|
unsigned long fwd_bitmask; /* Bitmask indicating in use pools */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline u8 ixgbe_max_rss_indices(struct ixgbe_adapter *adapter)
|
||||||
|
{
|
||||||
|
switch (adapter->hw.mac.type) {
|
||||||
|
case ixgbe_mac_82598EB:
|
||||||
|
case ixgbe_mac_82599EB:
|
||||||
|
case ixgbe_mac_X540:
|
||||||
|
return IXGBE_MAX_RSS_INDICES;
|
||||||
|
case ixgbe_mac_X550:
|
||||||
|
case ixgbe_mac_X550EM_x:
|
||||||
|
return IXGBE_MAX_RSS_INDICES_X550;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct ixgbe_fdir_filter {
|
struct ixgbe_fdir_filter {
|
||||||
struct hlist_node fdir_node;
|
struct hlist_node fdir_node;
|
||||||
union ixgbe_atr_input filter;
|
union ixgbe_atr_input filter;
|
||||||
|
|
|
@ -2927,7 +2927,7 @@ static unsigned int ixgbe_max_channels(struct ixgbe_adapter *adapter)
|
||||||
max_combined = IXGBE_MAX_FDIR_INDICES;
|
max_combined = IXGBE_MAX_FDIR_INDICES;
|
||||||
} else {
|
} else {
|
||||||
/* support up to 16 queues with RSS */
|
/* support up to 16 queues with RSS */
|
||||||
max_combined = IXGBE_MAX_RSS_INDICES;
|
max_combined = ixgbe_max_rss_indices(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
return max_combined;
|
return max_combined;
|
||||||
|
@ -2975,6 +2975,7 @@ static int ixgbe_set_channels(struct net_device *dev,
|
||||||
{
|
{
|
||||||
struct ixgbe_adapter *adapter = netdev_priv(dev);
|
struct ixgbe_adapter *adapter = netdev_priv(dev);
|
||||||
unsigned int count = ch->combined_count;
|
unsigned int count = ch->combined_count;
|
||||||
|
u8 max_rss_indices = ixgbe_max_rss_indices(adapter);
|
||||||
|
|
||||||
/* verify they are not requesting separate vectors */
|
/* verify they are not requesting separate vectors */
|
||||||
if (!count || ch->rx_count || ch->tx_count)
|
if (!count || ch->rx_count || ch->tx_count)
|
||||||
|
@ -2991,9 +2992,9 @@ static int ixgbe_set_channels(struct net_device *dev,
|
||||||
/* update feature limits from largest to smallest supported values */
|
/* update feature limits from largest to smallest supported values */
|
||||||
adapter->ring_feature[RING_F_FDIR].limit = count;
|
adapter->ring_feature[RING_F_FDIR].limit = count;
|
||||||
|
|
||||||
/* cap RSS limit at 16 */
|
/* cap RSS limit */
|
||||||
if (count > IXGBE_MAX_RSS_INDICES)
|
if (count > max_rss_indices)
|
||||||
count = IXGBE_MAX_RSS_INDICES;
|
count = max_rss_indices;
|
||||||
adapter->ring_feature[RING_F_RSS].limit = count;
|
adapter->ring_feature[RING_F_RSS].limit = count;
|
||||||
|
|
||||||
#ifdef IXGBE_FCOE
|
#ifdef IXGBE_FCOE
|
||||||
|
|
|
@ -3217,7 +3217,9 @@ static void ixgbe_setup_reta(struct ixgbe_adapter *adapter, const u32 *seed)
|
||||||
struct ixgbe_hw *hw = &adapter->hw;
|
struct ixgbe_hw *hw = &adapter->hw;
|
||||||
u32 reta = 0;
|
u32 reta = 0;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
int reta_entries = 128;
|
||||||
u16 rss_i = adapter->ring_feature[RING_F_RSS].indices;
|
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
|
* Program table for at least 2 queues w/ SR-IOV so that VFs can
|
||||||
|
@ -3231,22 +3233,67 @@ static void ixgbe_setup_reta(struct ixgbe_adapter *adapter, const u32 *seed)
|
||||||
for (i = 0; i < 10; i++)
|
for (i = 0; i < 10; i++)
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), seed[i]);
|
IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), seed[i]);
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
*/
|
||||||
|
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 */
|
/* Fill out redirection table */
|
||||||
for (i = 0, j = 0; i < 128; i++, j++) {
|
for (i = 0, j = 0; i < reta_entries; i++, j++) {
|
||||||
if (j == rss_i)
|
if (j == rss_i)
|
||||||
j = 0;
|
j = 0;
|
||||||
/* reta = 4-byte sliding window of
|
reta = (reta << 8) | (j * indices_multi);
|
||||||
* 0x00..(indices-1)(indices-1)00..etc. */
|
if ((i & 3) == 3) {
|
||||||
reta = (reta << 8) | (j * 0x11);
|
if (i < 128)
|
||||||
if ((i & 3) == 3)
|
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta);
|
IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta);
|
||||||
|
else
|
||||||
|
IXGBE_WRITE_REG(hw, IXGBE_ERETA((i >> 2) - 32),
|
||||||
|
reta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ixgbe_setup_vfreta(struct ixgbe_adapter *adapter, const u32 *seed)
|
||||||
|
{
|
||||||
|
struct ixgbe_hw *hw = &adapter->hw;
|
||||||
|
u32 vfreta = 0;
|
||||||
|
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]);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
|
static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
|
||||||
{
|
{
|
||||||
struct ixgbe_hw *hw = &adapter->hw;
|
struct ixgbe_hw *hw = &adapter->hw;
|
||||||
u32 mrqc = 0, rss_field = 0;
|
u32 mrqc = 0, rss_field = 0, vfmrqc = 0;
|
||||||
u32 rss_key[10];
|
u32 rss_key[10];
|
||||||
u32 rxcsum;
|
u32 rxcsum;
|
||||||
|
|
||||||
|
@ -3292,10 +3339,25 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
|
||||||
rss_field |= IXGBE_MRQC_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(rss_key, sizeof(rss_key));
|
||||||
|
if ((hw->mac.type >= ixgbe_mac_X550) &&
|
||||||
|
(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) {
|
||||||
|
unsigned int pf_pool = adapter->num_vfs;
|
||||||
|
|
||||||
|
/* Enable VF RSS mode */
|
||||||
|
mrqc |= IXGBE_MRQC_MULTIPLE_RSS;
|
||||||
|
IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
|
||||||
|
|
||||||
|
/* Setup RSS through the VF registers */
|
||||||
|
ixgbe_setup_vfreta(adapter, rss_key);
|
||||||
|
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, rss_key);
|
||||||
mrqc |= rss_field;
|
mrqc |= rss_field;
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
|
IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ixgbe_configure_rscctl - enable RSC for the indicated ring
|
* ixgbe_configure_rscctl - enable RSC for the indicated ring
|
||||||
|
@ -5056,7 +5118,7 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter)
|
||||||
hw->subsystem_device_id = pdev->subsystem_device;
|
hw->subsystem_device_id = pdev->subsystem_device;
|
||||||
|
|
||||||
/* Set common capability flags and settings */
|
/* Set common capability flags and settings */
|
||||||
rss = min_t(int, IXGBE_MAX_RSS_INDICES, num_online_cpus());
|
rss = min_t(int, ixgbe_max_rss_indices(adapter), num_online_cpus());
|
||||||
adapter->ring_feature[RING_F_RSS].limit = rss;
|
adapter->ring_feature[RING_F_RSS].limit = rss;
|
||||||
adapter->flags2 |= IXGBE_FLAG2_RSC_CAPABLE;
|
adapter->flags2 |= IXGBE_FLAG2_RSC_CAPABLE;
|
||||||
adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED;
|
adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED;
|
||||||
|
|
|
@ -221,7 +221,8 @@ int ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
|
||||||
if (adapter->ring_feature[RING_F_VMDQ].limit == 1) {
|
if (adapter->ring_feature[RING_F_VMDQ].limit == 1) {
|
||||||
adapter->flags &= ~IXGBE_FLAG_VMDQ_ENABLED;
|
adapter->flags &= ~IXGBE_FLAG_VMDQ_ENABLED;
|
||||||
adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED;
|
adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED;
|
||||||
rss = min_t(int, IXGBE_MAX_RSS_INDICES, num_online_cpus());
|
rss = min_t(int, ixgbe_max_rss_indices(adapter),
|
||||||
|
num_online_cpus());
|
||||||
} else {
|
} else {
|
||||||
rss = min_t(int, IXGBE_MAX_L2A_QUEUES, num_online_cpus());
|
rss = min_t(int, IXGBE_MAX_L2A_QUEUES, num_online_cpus());
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,6 +297,7 @@ struct ixgbe_thermal_sensor_data {
|
||||||
#define IXGBE_IMIRVP 0x05AC0
|
#define IXGBE_IMIRVP 0x05AC0
|
||||||
#define IXGBE_VMD_CTL 0x0581C
|
#define IXGBE_VMD_CTL 0x0581C
|
||||||
#define IXGBE_RETA(_i) (0x05C00 + ((_i) * 4)) /* 32 of these (0-31) */
|
#define IXGBE_RETA(_i) (0x05C00 + ((_i) * 4)) /* 32 of these (0-31) */
|
||||||
|
#define IXGBE_ERETA(_i) (0x0EE80 + ((_i) * 4)) /* 96 of these (0-95) */
|
||||||
#define IXGBE_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* 10 of these (0-9) */
|
#define IXGBE_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* 10 of these (0-9) */
|
||||||
|
|
||||||
/* Registers for setting up RSS on X550 with SRIOV
|
/* Registers for setting up RSS on X550 with SRIOV
|
||||||
|
@ -2016,6 +2017,7 @@ enum {
|
||||||
#define IXGBE_MRQC_RSS_FIELD_IPV4_UDP 0x00400000
|
#define IXGBE_MRQC_RSS_FIELD_IPV4_UDP 0x00400000
|
||||||
#define IXGBE_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
|
#define IXGBE_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
|
||||||
#define IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP 0x01000000
|
#define IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP 0x01000000
|
||||||
|
#define IXGBE_MRQC_MULTIPLE_RSS 0x00002000
|
||||||
#define IXGBE_MRQC_L3L4TXSWEN 0x00008000
|
#define IXGBE_MRQC_L3L4TXSWEN 0x00008000
|
||||||
|
|
||||||
#define IXGBE_FWSM_TS_ENABLED 0x1
|
#define IXGBE_FWSM_TS_ENABLED 0x1
|
||||||
|
|
Loading…
Reference in New Issue