]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
qede: Add getter APIs support for RX flow classification
authorChopra, Manish <Manish.Chopra@cavium.com>
Wed, 26 Jul 2017 13:07:09 +0000 (06:07 -0700)
committerChuck Anderson <chuck.anderson@oracle.com>
Tue, 19 Sep 2017 05:32:42 +0000 (22:32 -0700)
Orabug: 26783820

This patch adds support for ethtool getter APIs to query
RX flow classification rules.

Signed-off-by: Manish Chopra <manish.chopra@cavium.com>
Signed-off-by: Yuval Mintz <yuval.mintz@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Somasundaram Krishnasamy <somasundaram.krishnasamy@oracle.com>
drivers/net/ethernet/qlogic/qede/qede.h
drivers/net/ethernet/qlogic/qede/qede_ethtool.c
drivers/net/ethernet/qlogic/qede/qede_filter.c

index 145412487857693690c186180c9d52570bb8bef4..bc9524d3694e03e3cce7ed1f316245c820e04fab 100644 (file)
@@ -159,6 +159,8 @@ struct qede_rdma_dev {
 
 struct qede_ptp;
 
+#define QEDE_RFS_MAX_FLTR      256
+
 struct qede_dev {
        struct qed_dev                  *cdev;
        struct net_device               *ndev;
@@ -236,9 +238,7 @@ struct qede_dev {
        u16                             vxlan_dst_port;
        u16                             geneve_dst_port;
 
-#ifdef CONFIG_RFS_ACCEL
        struct qede_arfs                *arfs;
-#endif
        bool                            wol_enabled;
 
        struct qede_rdma_dev            rdma_info;
@@ -425,9 +425,13 @@ int qede_alloc_arfs(struct qede_dev *edev);
 
 #define QEDE_SP_ARFS_CONFIG    4
 #define QEDE_SP_TASK_POLL_DELAY        (5 * HZ)
-#define QEDE_RFS_MAX_FLTR      256
 #endif
 
+int qede_get_cls_rule_entry(struct qede_dev *edev, struct ethtool_rxnfc *cmd);
+int qede_get_cls_rule_all(struct qede_dev *edev, struct ethtool_rxnfc *info,
+                         u32 *rule_locs);
+int qede_get_arfs_filter_count(struct qede_dev *edev);
+
 struct qede_reload_args {
        void (*func)(struct qede_dev *edev, struct qede_reload_args *args);
        union {
index bf90dfba027700e86b6482ad7e675ea54bcf9c48..7313acf324a97712ee7110edd553cf651ffffca8 100644 (file)
@@ -952,20 +952,34 @@ static int qede_get_rss_flags(struct qede_dev *edev, struct ethtool_rxnfc *info)
 }
 
 static int qede_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
-                         u32 *rules __always_unused)
+                         u32 *rule_locs)
 {
        struct qede_dev *edev = netdev_priv(dev);
+       int rc = 0;
 
        switch (info->cmd) {
        case ETHTOOL_GRXRINGS:
                info->data = QEDE_RSS_COUNT(edev);
-               return 0;
+               break;
        case ETHTOOL_GRXFH:
-               return qede_get_rss_flags(edev, info);
+               rc = qede_get_rss_flags(edev, info);
+               break;
+       case ETHTOOL_GRXCLSRLCNT:
+               info->rule_cnt = qede_get_arfs_filter_count(edev);
+               info->data = QEDE_RFS_MAX_FLTR;
+               break;
+       case ETHTOOL_GRXCLSRULE:
+               rc = qede_get_cls_rule_entry(edev, info);
+               break;
+       case ETHTOOL_GRXCLSRLALL:
+               rc = qede_get_cls_rule_all(edev, info, rule_locs);
+               break;
        default:
                DP_ERR(edev, "Command parameters not supported\n");
-               return -EOPNOTSUPP;
+               rc = -EOPNOTSUPP;
        }
+
+       return rc;
 }
 
 static int qede_set_rss_flags(struct qede_dev *edev, struct ethtool_rxnfc *info)
index a6e4ad80ffa33a5872af6f1c9cb212e7dbf7ff8a..db7d4e1a287a14bad790b864f3103961996c57da 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/qed/qed_if.h>
 #include "qede.h"
 
-#ifdef CONFIG_RFS_ACCEL
 struct qede_arfs_tuple {
        union {
                __be32 src_ipv4;
@@ -79,6 +78,7 @@ struct qede_arfs_fltr_node {
 };
 
 struct qede_arfs {
+#define QEDE_ARFS_BUCKET_HEAD(edev, idx) (&(edev)->arfs->arfs_hl_head[idx])
 #define QEDE_ARFS_POLL_COUNT   100
 #define QEDE_RFS_FLW_BITSHIFT  (4)
 #define QEDE_RFS_FLW_MASK      ((1 << QEDE_RFS_FLW_BITSHIFT) - 1)
@@ -91,6 +91,7 @@ struct qede_arfs {
        bool                    enable;
 };
 
+#ifdef CONFIG_RFS_ACCEL
 static void qede_configure_arfs_fltr(struct qede_dev *edev,
                                     struct qede_arfs_fltr_node *n,
                                     u16 rxq_id, bool add_fltr)
@@ -1033,3 +1034,114 @@ void qede_config_rx_mode(struct net_device *ndev)
 out:
        kfree(uc_macs);
 }
+
+static struct qede_arfs_fltr_node *
+qede_get_arfs_fltr_by_loc(struct hlist_head *head, u32 location)
+{
+       struct qede_arfs_fltr_node *fltr;
+
+       hlist_for_each_entry(fltr, head, node)
+               if (location == fltr->sw_id)
+                       return fltr;
+
+       return NULL;
+}
+
+int qede_get_cls_rule_all(struct qede_dev *edev, struct ethtool_rxnfc *info,
+                         u32 *rule_locs)
+{
+       struct qede_arfs_fltr_node *fltr;
+       struct hlist_head *head;
+       int cnt = 0, rc = 0;
+
+       info->data = QEDE_RFS_MAX_FLTR;
+
+       __qede_lock(edev);
+
+       if (!edev->arfs) {
+               rc = -EPERM;
+               goto unlock;
+       }
+
+       head = QEDE_ARFS_BUCKET_HEAD(edev, 0);
+
+       hlist_for_each_entry(fltr, head, node) {
+               if (cnt == info->rule_cnt) {
+                       rc = -EMSGSIZE;
+                       goto unlock;
+               }
+
+               rule_locs[cnt] = fltr->sw_id;
+               cnt++;
+       }
+
+       info->rule_cnt = cnt;
+
+unlock:
+       __qede_unlock(edev);
+       return rc;
+}
+
+int qede_get_cls_rule_entry(struct qede_dev *edev, struct ethtool_rxnfc *cmd)
+{
+       struct ethtool_rx_flow_spec *fsp = &cmd->fs;
+       struct qede_arfs_fltr_node *fltr = NULL;
+       int rc = 0;
+
+       cmd->data = QEDE_RFS_MAX_FLTR;
+
+       __qede_lock(edev);
+
+       if (!edev->arfs) {
+               rc = -EPERM;
+               goto unlock;
+       }
+
+       fltr = qede_get_arfs_fltr_by_loc(QEDE_ARFS_BUCKET_HEAD(edev, 0),
+                                        fsp->location);
+       if (!fltr) {
+               DP_NOTICE(edev, "Rule not found - location=0x%x\n",
+                         fsp->location);
+               rc = -EINVAL;
+               goto unlock;
+       }
+
+       if (fltr->tuple.eth_proto == htons(ETH_P_IP)) {
+               if (fltr->tuple.ip_proto == IPPROTO_TCP)
+                       fsp->flow_type = TCP_V4_FLOW;
+               else
+                       fsp->flow_type = UDP_V4_FLOW;
+
+               fsp->h_u.tcp_ip4_spec.psrc = fltr->tuple.src_port;
+               fsp->h_u.tcp_ip4_spec.pdst = fltr->tuple.dst_port;
+               fsp->h_u.tcp_ip4_spec.ip4src = fltr->tuple.src_ipv4;
+               fsp->h_u.tcp_ip4_spec.ip4dst = fltr->tuple.dst_ipv4;
+       } else {
+               if (fltr->tuple.ip_proto == IPPROTO_TCP)
+                       fsp->flow_type = TCP_V6_FLOW;
+               else
+                       fsp->flow_type = UDP_V6_FLOW;
+       }
+
+       fsp->ring_cookie = fltr->rxq_id;
+
+unlock:
+       __qede_unlock(edev);
+       return rc;
+}
+
+int qede_get_arfs_filter_count(struct qede_dev *edev)
+{
+       int count = 0;
+
+       __qede_lock(edev);
+
+       if (!edev->arfs)
+               goto unlock;
+
+       count = edev->arfs->filter_count;
+
+unlock:
+       __qede_unlock(edev);
+       return count;
+}