enic: set UDP rss flag
authorGovindarajulu Varadarajan <gvaradar@cisco.com>
Thu, 1 Mar 2018 19:07:22 +0000 (11:07 -0800)
committerDavid S. Miller <davem@davemloft.net>
Sun, 4 Mar 2018 23:19:25 +0000 (18:19 -0500)
New hardware needs UDP flag set to enable UDP L4 rss hash. Add ethtool
get option to display supported rss flow hash.

Signed-off-by: Govindarajulu Varadarajan <gvaradar@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/cisco/enic/enic_ethtool.c
drivers/net/ethernet/cisco/enic/enic_main.c
drivers/net/ethernet/cisco/enic/vnic_dev.c
drivers/net/ethernet/cisco/enic/vnic_dev.h
drivers/net/ethernet/cisco/enic/vnic_nic.h

index efb9333c7cf80179560915f0e251f05252f1baa5..869006c2002d3be453f2443fd69cb6d07fbee4b2 100644 (file)
@@ -474,6 +474,39 @@ static int enic_grxclsrule(struct enic *enic, struct ethtool_rxnfc *cmd)
        return 0;
 }
 
+static int enic_get_rx_flow_hash(struct enic *enic, struct ethtool_rxnfc *cmd)
+{
+       cmd->data = 0;
+
+       switch (cmd->flow_type) {
+       case TCP_V6_FLOW:
+       case TCP_V4_FLOW:
+               cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+               /* Fall through */
+       case UDP_V6_FLOW:
+       case UDP_V4_FLOW:
+               if (vnic_dev_capable_udp_rss(enic->vdev))
+                       cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+               /* Fall through */
+       case SCTP_V4_FLOW:
+       case AH_ESP_V4_FLOW:
+       case AH_V4_FLOW:
+       case ESP_V4_FLOW:
+       case SCTP_V6_FLOW:
+       case AH_ESP_V6_FLOW:
+       case AH_V6_FLOW:
+       case ESP_V6_FLOW:
+       case IPV4_FLOW:
+       case IPV6_FLOW:
+               cmd->data |= RXH_IP_SRC | RXH_IP_DST;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static int enic_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
                          u32 *rule_locs)
 {
@@ -500,6 +533,9 @@ static int enic_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
                ret = enic_grxclsrule(enic, cmd);
                spin_unlock_bh(&enic->rfs_h.lock);
                break;
+       case ETHTOOL_GRXFH:
+               ret = enic_get_rx_flow_hash(enic, cmd);
+               break;
        default:
                ret = -EOPNOTSUPP;
                break;
index 3280a05f9cf1b40d181baa2f66b02e1c4439002b..5213bc01a6e901a2ea578a750762e172e304d135 100644 (file)
@@ -2316,7 +2316,7 @@ static int enic_set_rss_nic_cfg(struct enic *enic)
 {
        struct device *dev = enic_get_dev(enic);
        const u8 rss_default_cpu = 0;
-       const u8 rss_hash_type = NIC_CFG_RSS_HASH_TYPE_IPV4 |
+       u8 rss_hash_type = NIC_CFG_RSS_HASH_TYPE_IPV4 |
                NIC_CFG_RSS_HASH_TYPE_TCP_IPV4 |
                NIC_CFG_RSS_HASH_TYPE_IPV6 |
                NIC_CFG_RSS_HASH_TYPE_TCP_IPV6;
@@ -2324,6 +2324,8 @@ static int enic_set_rss_nic_cfg(struct enic *enic)
        const u8 rss_base_cpu = 0;
        u8 rss_enable = ENIC_SETTING(enic, RSS) && (enic->rq_count > 1);
 
+       if (vnic_dev_capable_udp_rss(enic->vdev))
+               rss_hash_type |= NIC_CFG_RSS_HASH_TYPE_UDP;
        if (rss_enable) {
                if (!enic_set_rsskey(enic)) {
                        if (enic_set_rsscpu(enic, rss_hash_bits)) {
index b60fb6e3e77598ff2cc1e1955c756bd14f535a9e..a2b376055b2d88b97c6b000c7d35c86be944d0d7 100644 (file)
@@ -1281,3 +1281,20 @@ int vnic_dev_get_supported_feature_ver(struct vnic_dev *vdev, u8 feature,
 
        return ret;
 }
+
+bool vnic_dev_capable_udp_rss(struct vnic_dev *vdev)
+{
+       u64 a0 = CMD_NIC_CFG, a1 = 0;
+       u64 rss_hash_type;
+       int wait = 1000;
+       int err;
+
+       err = vnic_dev_cmd(vdev, CMD_CAPABILITY, &a0, &a1, wait);
+       if (err || !a0)
+               return 0;
+
+       rss_hash_type = (a1 >> NIC_CFG_RSS_HASH_TYPE_SHIFT) &
+                       NIC_CFG_RSS_HASH_TYPE_MASK_FIELD;
+
+       return (rss_hash_type & NIC_CFG_RSS_HASH_TYPE_UDP);
+}
index db160f459852f691fa6fe5227e81d4b86e762041..59d4cc8fbb85b21f4ce37e39a64066112db68844 100644 (file)
@@ -184,5 +184,6 @@ int vnic_dev_overlay_offload_cfg(struct vnic_dev *vdev, u8 overlay,
                                 u16 vxlan_udp_port_number);
 int vnic_dev_get_supported_feature_ver(struct vnic_dev *vdev, u8 feature,
                                       u64 *supported_versions, u64 *a1);
+bool vnic_dev_capable_udp_rss(struct vnic_dev *vdev);
 
 #endif /* _VNIC_DEV_H_ */
index 995a50dd4c99ca926769e8caeb1a5fbd51c22d9b..5a93db0d7afcaee53e6f5cd47a9c00d1e6672845 100644 (file)
@@ -47,6 +47,7 @@
 #define NIC_CFG_RSS_HASH_TYPE_TCP_IPV6         (1 << 4)
 #define NIC_CFG_RSS_HASH_TYPE_IPV6_EX          (1 << 5)
 #define NIC_CFG_RSS_HASH_TYPE_TCP_IPV6_EX      (1 << 6)
+#define NIC_CFG_RSS_HASH_TYPE_UDP              (1 << 7)
 
 static inline void vnic_set_nic_cfg(u32 *nic_cfg,
        u8 rss_default_cpu, u8 rss_hash_type,