Commit 8c95f773 authored by Sathya Perla's avatar Sathya Perla Committed by David S. Miller

bnxt_en: add support for Flower based vxlan encap/decap offload

This patch adds IPv4 vxlan encap/decap action support to TC-flower
offload.

For vxlan encap, the driver maintains a tunnel encap hash-table.
When a new flow with a tunnel encap action arrives, this table
is looked up; if an encap entry exists, it uses the already
programmed encap_record_handle as the tunnel_handle in the
hwrm_cfa_flow_alloc cmd. Else, a new encap node is added and the
L2 header fields are queried via a route lookup.
hwrm_cfa_encap_record_alloc cmd is used to create a new encap
record and the encap_record_handle is used as the tunnel_handle
while adding the flow.

For vxlan decap, the driver maintains a tunnel decap hash-table.
When a new flow with a tunnel decap action arrives, this table
is looked up; if a decap entry exists, it uses the already
programmed decap_filter_handle as the tunnel_handle in the
hwrm_cfa_flow_alloc cmd. Else, a new decap node is added and
a decap_filter_handle is alloc'd via the hwrm_cfa_decap_filter_alloc
cmd. This handle is used as the tunnel_handle while adding the flow.

The code to issue the HWRM FW cmds is introduced in a follow-up patch.
Signed-off-by: default avatarSathya Perla <sathya.perla@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f8503969
...@@ -965,6 +965,15 @@ struct bnxt_tc_info { ...@@ -965,6 +965,15 @@ struct bnxt_tc_info {
/* hash table to store L2 keys of TC flows */ /* hash table to store L2 keys of TC flows */
struct rhashtable l2_table; struct rhashtable l2_table;
struct rhashtable_params l2_ht_params; struct rhashtable_params l2_ht_params;
/* hash table to store L2 keys for TC tunnel decap */
struct rhashtable decap_l2_table;
struct rhashtable_params decap_l2_ht_params;
/* hash table to store tunnel decap entries */
struct rhashtable decap_table;
struct rhashtable_params decap_ht_params;
/* hash table to store tunnel encap entries */
struct rhashtable encap_table;
struct rhashtable_params encap_ht_params;
/* lock to atomically add/del an l2 node when a flow is /* lock to atomically add/del an l2 node when a flow is
* added or deleted. * added or deleted.
......
...@@ -29,7 +29,7 @@ int bnxt_dl_register(struct bnxt *bp) ...@@ -29,7 +29,7 @@ int bnxt_dl_register(struct bnxt *bp)
if (!pci_find_ext_capability(bp->pdev, PCI_EXT_CAP_ID_SRIOV)) if (!pci_find_ext_capability(bp->pdev, PCI_EXT_CAP_ID_SRIOV))
return 0; return 0;
if (bp->hwrm_spec_code < 0x10800) { if (bp->hwrm_spec_code < 0x10803) {
netdev_warn(bp->dev, "Firmware does not support SR-IOV E-Switch SWITCHDEV mode.\n"); netdev_warn(bp->dev, "Firmware does not support SR-IOV E-Switch SWITCHDEV mode.\n");
return -ENOTSUPP; return -ENOTSUPP;
} }
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#ifdef CONFIG_BNXT_FLOWER_OFFLOAD #ifdef CONFIG_BNXT_FLOWER_OFFLOAD
#include <net/ip_tunnels.h>
/* Structs used for storing the filter/actions of the TC cmd. /* Structs used for storing the filter/actions of the TC cmd.
*/ */
struct bnxt_tc_l2_key { struct bnxt_tc_l2_key {
...@@ -50,6 +52,13 @@ struct bnxt_tc_l4_key { ...@@ -50,6 +52,13 @@ struct bnxt_tc_l4_key {
}; };
}; };
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;
};
struct bnxt_tc_actions { struct bnxt_tc_actions {
u32 flags; u32 flags;
#define BNXT_TC_ACTION_FLAG_FWD BIT(0) #define BNXT_TC_ACTION_FLAG_FWD BIT(0)
...@@ -57,11 +66,16 @@ struct bnxt_tc_actions { ...@@ -57,11 +66,16 @@ struct bnxt_tc_actions {
#define BNXT_TC_ACTION_FLAG_PUSH_VLAN BIT(3) #define BNXT_TC_ACTION_FLAG_PUSH_VLAN BIT(3)
#define BNXT_TC_ACTION_FLAG_POP_VLAN BIT(4) #define BNXT_TC_ACTION_FLAG_POP_VLAN BIT(4)
#define BNXT_TC_ACTION_FLAG_DROP BIT(5) #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)
u16 dst_fid; u16 dst_fid;
struct net_device *dst_dev; struct net_device *dst_dev;
__be16 push_vlan_tpid; __be16 push_vlan_tpid;
__be16 push_vlan_tci; __be16 push_vlan_tci;
/* tunnel encap */
struct ip_tunnel_key tun_encap_key;
}; };
struct bnxt_tc_flow_stats { struct bnxt_tc_flow_stats {
...@@ -76,6 +90,16 @@ struct bnxt_tc_flow { ...@@ -76,6 +90,16 @@ struct bnxt_tc_flow {
#define BNXT_TC_FLOW_FLAGS_IPV6_ADDRS BIT(3) #define BNXT_TC_FLOW_FLAGS_IPV6_ADDRS BIT(3)
#define BNXT_TC_FLOW_FLAGS_PORTS BIT(4) #define BNXT_TC_FLOW_FLAGS_PORTS BIT(4)
#define BNXT_TC_FLOW_FLAGS_ICMP BIT(5) #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 */ /* flow applicable to pkts ingressing on this fid */
u16 src_fid; u16 src_fid;
...@@ -85,6 +109,8 @@ struct bnxt_tc_flow { ...@@ -85,6 +109,8 @@ struct bnxt_tc_flow {
struct bnxt_tc_l3_key l3_mask; struct bnxt_tc_l3_key l3_mask;
struct bnxt_tc_l4_key l4_key; struct bnxt_tc_l4_key l4_key;
struct bnxt_tc_l4_key l4_mask; struct bnxt_tc_l4_key l4_mask;
struct ip_tunnel_key tun_key;
struct ip_tunnel_key tun_mask;
struct bnxt_tc_actions actions; struct bnxt_tc_actions actions;
...@@ -95,11 +121,33 @@ struct bnxt_tc_flow { ...@@ -95,11 +121,33 @@ struct bnxt_tc_flow {
unsigned long lastused; /* jiffies */ unsigned long lastused; /* jiffies */
}; };
/* 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 /* L2 hash table
* This data-struct is used for L2-flow table. * The same data-struct is used for L2-flow table and L2-tunnel table.
* The L2 part of a flow is stored in a hash 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 * A flow that shares the same L2 key/mask with an
* already existing flow must refer to it's flow handle. * already existing flow/tunnel must refer to it's flow handle or
* decap_filter_id respectively.
*/ */
struct bnxt_tc_l2_node { struct bnxt_tc_l2_node {
/* hash key: first 16b of key */ /* hash key: first 16b of key */
...@@ -110,7 +158,7 @@ struct bnxt_tc_l2_node { ...@@ -110,7 +158,7 @@ struct bnxt_tc_l2_node {
/* a linked list of flows that share the same l2 key */ /* a linked list of flows that share the same l2 key */
struct list_head common_l2_flows; struct list_head common_l2_flows;
/* number of flows sharing the l2 key */ /* number of flows/tunnels sharing the l2 key */
u16 refcount; u16 refcount;
struct rcu_head rcu; struct rcu_head rcu;
...@@ -130,6 +178,16 @@ struct bnxt_tc_flow_node { ...@@ -130,6 +178,16 @@ struct bnxt_tc_flow_node {
/* for the shared_flows list maintained in l2_node */ /* for the shared_flows list maintained in l2_node */
struct list_head l2_list_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; struct rcu_head rcu;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment