igc: Add multiple receive queues control supporting
authorSasha Neftin <sasha.neftin@intel.com>
Wed, 6 Feb 2019 07:48:37 +0000 (09:48 +0200)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Tue, 19 Mar 2019 21:42:02 +0000 (14:42 -0700)
Enable the multi queues to receive.
Program the direction of packets to specified queues according
to the mode selected in the MRQC register.
Multiple receive queues defined by filters and RSS for 4 queues.
Enable/disable RSS hashing and also to enable multiple receive queues.
This patch will allow further ethtool support development.

Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/igc/igc.h
drivers/net/ethernet/intel/igc/igc_defines.h
drivers/net/ethernet/intel/igc/igc_main.c
drivers/net/ethernet/intel/igc/igc_regs.h

index 80faccc..473a65c 100644 (file)
@@ -29,6 +29,7 @@ unsigned int igc_get_max_rss_queues(struct igc_adapter *adapter);
 void igc_set_flag_queue_pairs(struct igc_adapter *adapter,
                              const u32 max_rss_queues);
 int igc_reinit_queues(struct igc_adapter *adapter);
+void igc_write_rss_indir_tbl(struct igc_adapter *adapter);
 bool igc_has_link(struct igc_adapter *adapter);
 void igc_reset(struct igc_adapter *adapter);
 int igc_set_spd_dplx(struct igc_adapter *adapter, u32 spd, u8 dplx);
@@ -51,6 +52,13 @@ extern char igc_driver_version[];
 #define IGC_FLAG_VLAN_PROMISC          BIT(15)
 #define IGC_FLAG_RX_LEGACY             BIT(16)
 
+#define IGC_FLAG_RSS_FIELD_IPV4_UDP    BIT(6)
+#define IGC_FLAG_RSS_FIELD_IPV6_UDP    BIT(7)
+
+#define IGC_MRQC_ENABLE_RSS_MQ         0x00000002
+#define IGC_MRQC_RSS_FIELD_IPV4_UDP    0x00400000
+#define IGC_MRQC_RSS_FIELD_IPV6_UDP    0x00800000
+
 #define IGC_START_ITR                  648 /* ~6000 ints/sec */
 #define IGC_4K_ITR                     980
 #define IGC_20K_ITR                    196
@@ -359,6 +367,7 @@ struct igc_adapter {
        u32 *shadow_vfta;
 
        u32 rss_queues;
+       u32 rss_indir_tbl_init;
 
        /* lock for RX network flow classification filter */
        spinlock_t nfc_lock;
index 7d1bdcd..3666f88 100644 (file)
        IGC_RXDEXT_STATERR_CXE |        \
        IGC_RXDEXT_STATERR_RXE)
 
+#define IGC_MRQC_RSS_FIELD_IPV4_TCP    0x00010000
+#define IGC_MRQC_RSS_FIELD_IPV4                0x00020000
+#define IGC_MRQC_RSS_FIELD_IPV6_TCP_EX 0x00040000
+#define IGC_MRQC_RSS_FIELD_IPV6                0x00100000
+#define IGC_MRQC_RSS_FIELD_IPV6_TCP    0x00200000
+
 /* Header split receive */
 #define IGC_RFCTL_IPV6_EX_DIS  0x00010000
 #define IGC_RFCTL_LEF          0x00040000
 #define I225_RXPBSIZE_DEFAULT  0x000000A2 /* RXPBSIZE default */
 #define I225_TXPBSIZE_DEFAULT  0x04000014 /* TXPBSIZE default */
 
+/* Receive Checksum Control */
+#define IGC_RXCSUM_CRCOFL      0x00000800   /* CRC32 offload enable */
+#define IGC_RXCSUM_PCSD                0x00002000   /* packet checksum disabled */
+
 /* GPY211 - I225 defines */
 #define GPY_MMD_MASK           0xFFFF0000
 #define GPY_MMD_SHIFT          16
index 87a1187..a6fe614 100644 (file)
@@ -620,6 +620,55 @@ static void igc_configure_tx(struct igc_adapter *adapter)
  */
 static void igc_setup_mrqc(struct igc_adapter *adapter)
 {
+       struct igc_hw *hw = &adapter->hw;
+       u32 j, num_rx_queues;
+       u32 mrqc, rxcsum;
+       u32 rss_key[10];
+
+       netdev_rss_key_fill(rss_key, sizeof(rss_key));
+       for (j = 0; j < 10; j++)
+               wr32(IGC_RSSRK(j), rss_key[j]);
+
+       num_rx_queues = adapter->rss_queues;
+
+       if (adapter->rss_indir_tbl_init != num_rx_queues) {
+               for (j = 0; j < IGC_RETA_SIZE; j++)
+                       adapter->rss_indir_tbl[j] =
+                       (j * num_rx_queues) / IGC_RETA_SIZE;
+               adapter->rss_indir_tbl_init = num_rx_queues;
+       }
+       igc_write_rss_indir_tbl(adapter);
+
+       /* Disable raw packet checksumming so that RSS hash is placed in
+        * descriptor on writeback.  No need to enable TCP/UDP/IP checksum
+        * offloads as they are enabled by default
+        */
+       rxcsum = rd32(IGC_RXCSUM);
+       rxcsum |= IGC_RXCSUM_PCSD;
+
+       /* Enable Receive Checksum Offload for SCTP */
+       rxcsum |= IGC_RXCSUM_CRCOFL;
+
+       /* Don't need to set TUOFL or IPOFL, they default to 1 */
+       wr32(IGC_RXCSUM, rxcsum);
+
+       /* Generate RSS hash based on packet types, TCP/UDP
+        * port numbers and/or IPv4/v6 src and dst addresses
+        */
+       mrqc = IGC_MRQC_RSS_FIELD_IPV4 |
+              IGC_MRQC_RSS_FIELD_IPV4_TCP |
+              IGC_MRQC_RSS_FIELD_IPV6 |
+              IGC_MRQC_RSS_FIELD_IPV6_TCP |
+              IGC_MRQC_RSS_FIELD_IPV6_TCP_EX;
+
+       if (adapter->flags & IGC_FLAG_RSS_FIELD_IPV4_UDP)
+               mrqc |= IGC_MRQC_RSS_FIELD_IPV4_UDP;
+       if (adapter->flags & IGC_FLAG_RSS_FIELD_IPV6_UDP)
+               mrqc |= IGC_MRQC_RSS_FIELD_IPV6_UDP;
+
+       mrqc |= IGC_MRQC_ENABLE_RSS_MQ;
+
+       wr32(IGC_MRQC, mrqc);
 }
 
 /**
index 5afe7a8..325109c 100644 (file)
 /* MSI-X Table Register Descriptions */
 #define IGC_PBACL              0x05B68  /* MSIx PBA Clear - R/W 1 to clear */
 
+/* RSS registers */
+#define IGC_MRQC               0x05818 /* Multiple Receive Control - RW */
+
 /* Redirection Table - RW Array */
 #define IGC_RETA(_i)           (0x05C00 + ((_i) * 4))
+/* RSS Random Key - RW Array */
+#define IGC_RSSRK(_i)          (0x05C80 + ((_i) * 4))
 
 /* Receive Register Descriptions */
 #define IGC_RCTL               0x00100  /* Rx Control - RW */