summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h')
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h255
1 files changed, 255 insertions, 0 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h
new file mode 100644
index 000000000..10c62b094
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h
@@ -0,0 +1,255 @@
+/* Broadcom NetXtreme-C/E network driver.
+ *
+ * Copyright (c) 2017 Broadcom Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ */
+
+#ifndef BNXT_TC_H
+#define BNXT_TC_H
+
+#ifdef CONFIG_BNXT_FLOWER_OFFLOAD
+
+#include <net/ip_tunnels.h>
+
+/* Structs used for storing the filter/actions of the TC cmd.
+ */
+struct bnxt_tc_l2_key {
+ u8 dmac[ETH_ALEN];
+ u8 smac[ETH_ALEN];
+ __be16 inner_vlan_tpid;
+ __be16 inner_vlan_tci;
+ __be16 ether_type;
+ u8 num_vlans;
+ u8 dir;
+#define BNXT_DIR_RX 1
+#define BNXT_DIR_TX 0
+};
+
+struct bnxt_tc_l3_key {
+ union {
+ struct {
+ struct in_addr daddr;
+ struct in_addr saddr;
+ } ipv4;
+ struct {
+ struct in6_addr daddr;
+ struct in6_addr saddr;
+ } ipv6;
+ };
+};
+
+struct bnxt_tc_l4_key {
+ u8 ip_proto;
+ union {
+ struct {
+ __be16 sport;
+ __be16 dport;
+ } ports;
+ struct {
+ u8 type;
+ u8 code;
+ } icmp;
+ };
+};
+
+struct bnxt_tc_tunnel_key {
+ struct bnxt_tc_l2_key l2;
+ struct bnxt_tc_l3_key l3;
+ struct bnxt_tc_l4_key l4;
+ __be32 id;
+};
+
+#define bnxt_eth_addr_key_mask_invalid(eth_addr, eth_addr_mask) \
+ ((is_wildcard(&(eth_addr)[0], ETH_ALEN) && \
+ is_wildcard(&(eth_addr)[ETH_ALEN / 2], ETH_ALEN)) || \
+ (is_wildcard(&(eth_addr_mask)[0], ETH_ALEN) && \
+ is_wildcard(&(eth_addr_mask)[ETH_ALEN / 2], ETH_ALEN)))
+
+struct bnxt_tc_actions {
+ u32 flags;
+#define BNXT_TC_ACTION_FLAG_FWD BIT(0)
+#define BNXT_TC_ACTION_FLAG_FWD_VXLAN BIT(1)
+#define BNXT_TC_ACTION_FLAG_PUSH_VLAN BIT(3)
+#define BNXT_TC_ACTION_FLAG_POP_VLAN BIT(4)
+#define BNXT_TC_ACTION_FLAG_DROP BIT(5)
+#define BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP BIT(6)
+#define BNXT_TC_ACTION_FLAG_TUNNEL_DECAP BIT(7)
+#define BNXT_TC_ACTION_FLAG_L2_REWRITE BIT(8)
+#define BNXT_TC_ACTION_FLAG_NAT_XLATE BIT(9)
+
+ u16 dst_fid;
+ struct net_device *dst_dev;
+ __be16 push_vlan_tpid;
+ __be16 push_vlan_tci;
+
+ /* tunnel encap */
+ struct ip_tunnel_key tun_encap_key;
+#define PEDIT_OFFSET_SMAC_LAST_4_BYTES 0x8
+ __be16 l2_rewrite_dmac[3];
+ __be16 l2_rewrite_smac[3];
+ struct {
+ bool src_xlate; /* true => translate src,
+ * false => translate dst
+ * Mutually exclusive, i.e cannot set both
+ */
+ bool l3_is_ipv4; /* false means L3 is ipv6 */
+ struct bnxt_tc_l3_key l3;
+ struct bnxt_tc_l4_key l4;
+ } nat;
+};
+
+struct bnxt_tc_flow {
+ u32 flags;
+#define BNXT_TC_FLOW_FLAGS_ETH_ADDRS BIT(1)
+#define BNXT_TC_FLOW_FLAGS_IPV4_ADDRS BIT(2)
+#define BNXT_TC_FLOW_FLAGS_IPV6_ADDRS BIT(3)
+#define BNXT_TC_FLOW_FLAGS_PORTS BIT(4)
+#define BNXT_TC_FLOW_FLAGS_ICMP BIT(5)
+#define BNXT_TC_FLOW_FLAGS_TUNL_ETH_ADDRS BIT(6)
+#define BNXT_TC_FLOW_FLAGS_TUNL_IPV4_ADDRS BIT(7)
+#define BNXT_TC_FLOW_FLAGS_TUNL_IPV6_ADDRS BIT(8)
+#define BNXT_TC_FLOW_FLAGS_TUNL_PORTS BIT(9)
+#define BNXT_TC_FLOW_FLAGS_TUNL_ID BIT(10)
+#define BNXT_TC_FLOW_FLAGS_TUNNEL (BNXT_TC_FLOW_FLAGS_TUNL_ETH_ADDRS | \
+ BNXT_TC_FLOW_FLAGS_TUNL_IPV4_ADDRS | \
+ BNXT_TC_FLOW_FLAGS_TUNL_IPV6_ADDRS |\
+ BNXT_TC_FLOW_FLAGS_TUNL_PORTS |\
+ BNXT_TC_FLOW_FLAGS_TUNL_ID)
+
+ /* flow applicable to pkts ingressing on this fid */
+ u16 src_fid;
+ struct bnxt_tc_l2_key l2_key;
+ struct bnxt_tc_l2_key l2_mask;
+ struct bnxt_tc_l3_key l3_key;
+ struct bnxt_tc_l3_key l3_mask;
+ struct bnxt_tc_l4_key l4_key;
+ struct bnxt_tc_l4_key l4_mask;
+ struct ip_tunnel_key tun_key;
+ struct ip_tunnel_key tun_mask;
+
+ struct bnxt_tc_actions actions;
+
+ /* updated stats accounting for hw-counter wrap-around */
+ struct bnxt_tc_flow_stats stats;
+ /* previous snap-shot of stats */
+ struct bnxt_tc_flow_stats prev_stats;
+ unsigned long lastused; /* jiffies */
+ /* for calculating delta from prev_stats and
+ * updating prev_stats atomically.
+ */
+ spinlock_t stats_lock;
+};
+
+/* Tunnel encap/decap hash table
+ * This table is used to maintain a list of flows that use
+ * the same tunnel encap/decap params (ip_daddrs, vni, udp_dport)
+ * and the FW returned handle.
+ * A separate table is maintained for encap and decap
+ */
+struct bnxt_tc_tunnel_node {
+ struct ip_tunnel_key key;
+ struct rhash_head node;
+
+ /* tunnel l2 info */
+ struct bnxt_tc_l2_key l2_info;
+
+#define INVALID_TUNNEL_HANDLE cpu_to_le32(0xffffffff)
+ /* tunnel handle returned by FW */
+ __le32 tunnel_handle;
+
+ u32 refcount;
+ struct rcu_head rcu;
+};
+
+/* L2 hash table
+ * The same data-struct is used for L2-flow table and L2-tunnel table.
+ * The L2 part of a flow or tunnel is stored in a hash table.
+ * A flow that shares the same L2 key/mask with an
+ * already existing flow/tunnel must refer to it's flow handle or
+ * decap_filter_id respectively.
+ */
+struct bnxt_tc_l2_node {
+ /* hash key: first 16b of key */
+#define BNXT_TC_L2_KEY_LEN 16
+ struct bnxt_tc_l2_key key;
+ struct rhash_head node;
+
+ /* a linked list of flows that share the same l2 key */
+ struct list_head common_l2_flows;
+
+ /* number of flows/tunnels sharing the l2 key */
+ u16 refcount;
+
+ struct rcu_head rcu;
+};
+
+struct bnxt_tc_flow_node {
+ /* hash key: provided by TC */
+ unsigned long cookie;
+ struct rhash_head node;
+
+ struct bnxt_tc_flow flow;
+
+ __le64 ext_flow_handle;
+ __le16 flow_handle;
+ __le32 flow_id;
+
+ /* L2 node in l2 hashtable that shares flow's l2 key */
+ struct bnxt_tc_l2_node *l2_node;
+ /* for the shared_flows list maintained in l2_node */
+ struct list_head l2_list_node;
+
+ /* tunnel encap related */
+ struct bnxt_tc_tunnel_node *encap_node;
+
+ /* tunnel decap related */
+ struct bnxt_tc_tunnel_node *decap_node;
+ /* L2 node in tunnel-l2 hashtable that shares flow's tunnel l2 key */
+ struct bnxt_tc_l2_node *decap_l2_node;
+ /* for the shared_flows list maintained in tunnel decap l2_node */
+ struct list_head decap_l2_list_node;
+
+ struct rcu_head rcu;
+};
+
+int bnxt_tc_setup_flower(struct bnxt *bp, u16 src_fid,
+ struct flow_cls_offload *cls_flower);
+int bnxt_init_tc(struct bnxt *bp);
+void bnxt_shutdown_tc(struct bnxt *bp);
+void bnxt_tc_flow_stats_work(struct bnxt *bp);
+
+static inline bool bnxt_tc_flower_enabled(struct bnxt *bp)
+{
+ return bp->tc_info && bp->tc_info->enabled;
+}
+
+#else /* CONFIG_BNXT_FLOWER_OFFLOAD */
+
+static inline int bnxt_tc_setup_flower(struct bnxt *bp, u16 src_fid,
+ struct flow_cls_offload *cls_flower)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int bnxt_init_tc(struct bnxt *bp)
+{
+ return 0;
+}
+
+static inline void bnxt_shutdown_tc(struct bnxt *bp)
+{
+}
+
+static inline void bnxt_tc_flow_stats_work(struct bnxt *bp)
+{
+}
+
+static inline bool bnxt_tc_flower_enabled(struct bnxt *bp)
+{
+ return false;
+}
+#endif /* CONFIG_BNXT_FLOWER_OFFLOAD */
+#endif /* BNXT_TC_H */