Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0f9b232b authored by Don Skidmore's avatar Don Skidmore Committed by Jeff Kirsher
Browse files

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: default avatarDon Skidmore <donald.c.skidmore@intel.com>
Tested-by: default avatarPhil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 9079e416
Loading
Loading
Loading
Loading
+26 −10
Original line number Diff line number Diff line
@@ -301,6 +301,7 @@ enum ixgbe_ring_f_enum {
};

#define IXGBE_MAX_RSS_INDICES		16
#define IXGBE_MAX_RSS_INDICES_X550	64
#define IXGBE_MAX_VMDQ_INDICES		64
#define IXGBE_MAX_FDIR_INDICES		63	/* based on q_vector limit */
#define IXGBE_MAX_FCOE_INDICES		8
@@ -764,6 +765,21 @@ struct ixgbe_adapter {
	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 hlist_node fdir_node;
	union ixgbe_atr_input filter;
+5 −4
Original line number Diff line number Diff line
@@ -2927,7 +2927,7 @@ static unsigned int ixgbe_max_channels(struct ixgbe_adapter *adapter)
		max_combined = IXGBE_MAX_FDIR_INDICES;
	} else {
		/* support up to 16 queues with RSS */
		max_combined = IXGBE_MAX_RSS_INDICES;
		max_combined = ixgbe_max_rss_indices(adapter);
	}

	return max_combined;
@@ -2975,6 +2975,7 @@ static int ixgbe_set_channels(struct net_device *dev,
{
	struct ixgbe_adapter *adapter = netdev_priv(dev);
	unsigned int count = ch->combined_count;
	u8 max_rss_indices = ixgbe_max_rss_indices(adapter);

	/* verify they are not requesting separate vectors */
	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 */
	adapter->ring_feature[RING_F_FDIR].limit = count;

	/* cap RSS limit at 16 */
	if (count > IXGBE_MAX_RSS_INDICES)
		count = IXGBE_MAX_RSS_INDICES;
	/* cap RSS limit */
	if (count > max_rss_indices)
		count = max_rss_indices;
	adapter->ring_feature[RING_F_RSS].limit = count;

#ifdef IXGBE_FCOE
+72 −10
Original line number Diff line number Diff line
@@ -3217,7 +3217,9 @@ static void ixgbe_setup_reta(struct ixgbe_adapter *adapter, const u32 *seed)
	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
@@ -3231,22 +3233,67 @@ static void ixgbe_setup_reta(struct ixgbe_adapter *adapter, const u32 *seed)
	for (i = 0; i < 10; 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 */
	for (i = 0, j = 0; i < 128; i++, j++) {
	for (i = 0, j = 0; i < reta_entries; i++, j++) {
		if (j == rss_i)
			j = 0;
		/* reta = 4-byte sliding window of
		 * 0x00..(indices-1)(indices-1)00..etc. */
		reta = (reta << 8) | (j * 0x11);
		if ((i & 3) == 3)
		reta = (reta << 8) | (j * indices_multi);
		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);
		}
	}
}

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)
{
	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 rxcsum;

@@ -3292,10 +3339,25 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
		rss_field |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP;

	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);
		mrqc |= rss_field;
		IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
	}
}

/**
 * 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;

	/* 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->flags2 |= IXGBE_FLAG2_RSC_CAPABLE;
	adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED;
+2 −1
Original line number Diff line number Diff line
@@ -221,7 +221,8 @@ int ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
	if (adapter->ring_feature[RING_F_VMDQ].limit == 1) {
		adapter->flags &= ~IXGBE_FLAG_VMDQ_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 {
		rss = min_t(int, IXGBE_MAX_L2A_QUEUES, num_online_cpus());
	}
+2 −0
Original line number Diff line number Diff line
@@ -297,6 +297,7 @@ struct ixgbe_thermal_sensor_data {
#define IXGBE_IMIRVP    0x05AC0
#define IXGBE_VMD_CTL   0x0581C
#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) */

/* 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_IPV6_UDP    0x00800000
#define IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP 0x01000000
#define IXGBE_MRQC_MULTIPLE_RSS          0x00002000
#define IXGBE_MRQC_L3L4TXSWEN            0x00008000

#define IXGBE_FWSM_TS_ENABLED	0x1