summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Fastabend <john.fastabend@gmail.com>2016-02-16 21:19:19 -0800
committerDavid S. Miller <davem@davemloft.net>2016-02-17 09:47:37 -0500
commitdb956ae882f4e7aa99c9c242a91ae942d08b6939 (patch)
treea13405bcc7436c5c70b65096bc774ecf9134d6a9
parentb82b17d929a692df1122fedc0ff4ddcef9cb6ad4 (diff)
downloadlinux-db956ae882f4e7aa99c9c242a91ae942d08b6939.tar.bz2
net: ixgbe: abort with cls u32 divisor groups greater than 1
This patch ensures ixgbe will not try to offload hash tables from the u32 module. The device class does not currently support this so until it is enabled just abort on these tables. Interestingly the more flexible your hardware is the less code you need to implement to guard against these cases. Signed-off-by: John Fastabend <john.r.fastabend@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe.h1
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c31
2 files changed, 32 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index fc877c715c64..84fa28ceb200 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -798,6 +798,7 @@ struct ixgbe_adapter {
#define IXGBE_MAX_LINK_HANDLE 10
struct ixgbe_mat_field *jump_tables[IXGBE_MAX_LINK_HANDLE];
+ unsigned long tables;
/* maximum number of RETA entries among all devices supported by ixgbe
* driver: currently it's x550 device in non-SRIOV mode
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index abdfaead1ba1..cf4b729c92d7 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -8217,6 +8217,27 @@ static int ixgbe_delete_clsu32(struct ixgbe_adapter *adapter,
return err;
}
+static int ixgbe_configure_clsu32_add_hnode(struct ixgbe_adapter *adapter,
+ __be16 protocol,
+ struct tc_cls_u32_offload *cls)
+{
+ /* This ixgbe devices do not support hash tables at the moment
+ * so abort when given hash tables.
+ */
+ if (cls->hnode.divisor > 0)
+ return -EINVAL;
+
+ set_bit(TC_U32_USERHTID(cls->hnode.handle), &adapter->tables);
+ return 0;
+}
+
+static int ixgbe_configure_clsu32_del_hnode(struct ixgbe_adapter *adapter,
+ struct tc_cls_u32_offload *cls)
+{
+ clear_bit(TC_U32_USERHTID(cls->hnode.handle), &adapter->tables);
+ return 0;
+}
+
static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter,
__be16 protocol,
struct tc_cls_u32_offload *cls)
@@ -8251,6 +8272,9 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter,
struct ixgbe_nexthdr *nexthdr = ixgbe_ipv4_jumps;
u32 uhtid = TC_U32_USERHTID(cls->knode.link_handle);
+ if (!test_bit(uhtid, &adapter->tables))
+ return -EINVAL;
+
for (i = 0; nexthdr[i].jump; i++) {
if (nexthdr->o != cls->knode.sel->offoff ||
nexthdr->s != cls->knode.sel->offshift ||
@@ -8386,6 +8410,13 @@ int __ixgbe_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
proto, tc->cls_u32);
case TC_CLSU32_DELETE_KNODE:
return ixgbe_delete_clsu32(adapter, tc->cls_u32);
+ case TC_CLSU32_NEW_HNODE:
+ case TC_CLSU32_REPLACE_HNODE:
+ return ixgbe_configure_clsu32_add_hnode(adapter, proto,
+ tc->cls_u32);
+ case TC_CLSU32_DELETE_HNODE:
+ return ixgbe_configure_clsu32_del_hnode(adapter,
+ tc->cls_u32);
default:
return -EINVAL;
}