162306a36Sopenharmony_ci/* Broadcom NetXtreme-C/E network driver. 262306a36Sopenharmony_ci * 362306a36Sopenharmony_ci * Copyright (c) 2017 Broadcom Limited 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * This program is free software; you can redistribute it and/or modify 662306a36Sopenharmony_ci * it under the terms of the GNU General Public License as published by 762306a36Sopenharmony_ci * the Free Software Foundation. 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#ifndef BNXT_TC_H 1162306a36Sopenharmony_ci#define BNXT_TC_H 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#ifdef CONFIG_BNXT_FLOWER_OFFLOAD 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <net/ip_tunnels.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci/* Structs used for storing the filter/actions of the TC cmd. 1862306a36Sopenharmony_ci */ 1962306a36Sopenharmony_cistruct bnxt_tc_l2_key { 2062306a36Sopenharmony_ci u8 dmac[ETH_ALEN]; 2162306a36Sopenharmony_ci u8 smac[ETH_ALEN]; 2262306a36Sopenharmony_ci __be16 inner_vlan_tpid; 2362306a36Sopenharmony_ci __be16 inner_vlan_tci; 2462306a36Sopenharmony_ci __be16 ether_type; 2562306a36Sopenharmony_ci u8 num_vlans; 2662306a36Sopenharmony_ci u8 dir; 2762306a36Sopenharmony_ci#define BNXT_DIR_RX 1 2862306a36Sopenharmony_ci#define BNXT_DIR_TX 0 2962306a36Sopenharmony_ci}; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistruct bnxt_tc_l3_key { 3262306a36Sopenharmony_ci union { 3362306a36Sopenharmony_ci struct { 3462306a36Sopenharmony_ci struct in_addr daddr; 3562306a36Sopenharmony_ci struct in_addr saddr; 3662306a36Sopenharmony_ci } ipv4; 3762306a36Sopenharmony_ci struct { 3862306a36Sopenharmony_ci struct in6_addr daddr; 3962306a36Sopenharmony_ci struct in6_addr saddr; 4062306a36Sopenharmony_ci } ipv6; 4162306a36Sopenharmony_ci }; 4262306a36Sopenharmony_ci}; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_cistruct bnxt_tc_l4_key { 4562306a36Sopenharmony_ci u8 ip_proto; 4662306a36Sopenharmony_ci union { 4762306a36Sopenharmony_ci struct { 4862306a36Sopenharmony_ci __be16 sport; 4962306a36Sopenharmony_ci __be16 dport; 5062306a36Sopenharmony_ci } ports; 5162306a36Sopenharmony_ci struct { 5262306a36Sopenharmony_ci u8 type; 5362306a36Sopenharmony_ci u8 code; 5462306a36Sopenharmony_ci } icmp; 5562306a36Sopenharmony_ci }; 5662306a36Sopenharmony_ci}; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_cistruct bnxt_tc_tunnel_key { 5962306a36Sopenharmony_ci struct bnxt_tc_l2_key l2; 6062306a36Sopenharmony_ci struct bnxt_tc_l3_key l3; 6162306a36Sopenharmony_ci struct bnxt_tc_l4_key l4; 6262306a36Sopenharmony_ci __be32 id; 6362306a36Sopenharmony_ci}; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci#define bnxt_eth_addr_key_mask_invalid(eth_addr, eth_addr_mask) \ 6662306a36Sopenharmony_ci ((is_wildcard(&(eth_addr)[0], ETH_ALEN) && \ 6762306a36Sopenharmony_ci is_wildcard(&(eth_addr)[ETH_ALEN / 2], ETH_ALEN)) || \ 6862306a36Sopenharmony_ci (is_wildcard(&(eth_addr_mask)[0], ETH_ALEN) && \ 6962306a36Sopenharmony_ci is_wildcard(&(eth_addr_mask)[ETH_ALEN / 2], ETH_ALEN))) 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_cistruct bnxt_tc_actions { 7262306a36Sopenharmony_ci u32 flags; 7362306a36Sopenharmony_ci#define BNXT_TC_ACTION_FLAG_FWD BIT(0) 7462306a36Sopenharmony_ci#define BNXT_TC_ACTION_FLAG_FWD_VXLAN BIT(1) 7562306a36Sopenharmony_ci#define BNXT_TC_ACTION_FLAG_PUSH_VLAN BIT(3) 7662306a36Sopenharmony_ci#define BNXT_TC_ACTION_FLAG_POP_VLAN BIT(4) 7762306a36Sopenharmony_ci#define BNXT_TC_ACTION_FLAG_DROP BIT(5) 7862306a36Sopenharmony_ci#define BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP BIT(6) 7962306a36Sopenharmony_ci#define BNXT_TC_ACTION_FLAG_TUNNEL_DECAP BIT(7) 8062306a36Sopenharmony_ci#define BNXT_TC_ACTION_FLAG_L2_REWRITE BIT(8) 8162306a36Sopenharmony_ci#define BNXT_TC_ACTION_FLAG_NAT_XLATE BIT(9) 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci u16 dst_fid; 8462306a36Sopenharmony_ci struct net_device *dst_dev; 8562306a36Sopenharmony_ci __be16 push_vlan_tpid; 8662306a36Sopenharmony_ci __be16 push_vlan_tci; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci /* tunnel encap */ 8962306a36Sopenharmony_ci struct ip_tunnel_key tun_encap_key; 9062306a36Sopenharmony_ci#define PEDIT_OFFSET_SMAC_LAST_4_BYTES 0x8 9162306a36Sopenharmony_ci __be16 l2_rewrite_dmac[3]; 9262306a36Sopenharmony_ci __be16 l2_rewrite_smac[3]; 9362306a36Sopenharmony_ci struct { 9462306a36Sopenharmony_ci bool src_xlate; /* true => translate src, 9562306a36Sopenharmony_ci * false => translate dst 9662306a36Sopenharmony_ci * Mutually exclusive, i.e cannot set both 9762306a36Sopenharmony_ci */ 9862306a36Sopenharmony_ci bool l3_is_ipv4; /* false means L3 is ipv6 */ 9962306a36Sopenharmony_ci struct bnxt_tc_l3_key l3; 10062306a36Sopenharmony_ci struct bnxt_tc_l4_key l4; 10162306a36Sopenharmony_ci } nat; 10262306a36Sopenharmony_ci}; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_cistruct bnxt_tc_flow { 10562306a36Sopenharmony_ci u32 flags; 10662306a36Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_ETH_ADDRS BIT(1) 10762306a36Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_IPV4_ADDRS BIT(2) 10862306a36Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_IPV6_ADDRS BIT(3) 10962306a36Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_PORTS BIT(4) 11062306a36Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_ICMP BIT(5) 11162306a36Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_TUNL_ETH_ADDRS BIT(6) 11262306a36Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_TUNL_IPV4_ADDRS BIT(7) 11362306a36Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_TUNL_IPV6_ADDRS BIT(8) 11462306a36Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_TUNL_PORTS BIT(9) 11562306a36Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_TUNL_ID BIT(10) 11662306a36Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_TUNNEL (BNXT_TC_FLOW_FLAGS_TUNL_ETH_ADDRS | \ 11762306a36Sopenharmony_ci BNXT_TC_FLOW_FLAGS_TUNL_IPV4_ADDRS | \ 11862306a36Sopenharmony_ci BNXT_TC_FLOW_FLAGS_TUNL_IPV6_ADDRS |\ 11962306a36Sopenharmony_ci BNXT_TC_FLOW_FLAGS_TUNL_PORTS |\ 12062306a36Sopenharmony_ci BNXT_TC_FLOW_FLAGS_TUNL_ID) 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci /* flow applicable to pkts ingressing on this fid */ 12362306a36Sopenharmony_ci u16 src_fid; 12462306a36Sopenharmony_ci struct bnxt_tc_l2_key l2_key; 12562306a36Sopenharmony_ci struct bnxt_tc_l2_key l2_mask; 12662306a36Sopenharmony_ci struct bnxt_tc_l3_key l3_key; 12762306a36Sopenharmony_ci struct bnxt_tc_l3_key l3_mask; 12862306a36Sopenharmony_ci struct bnxt_tc_l4_key l4_key; 12962306a36Sopenharmony_ci struct bnxt_tc_l4_key l4_mask; 13062306a36Sopenharmony_ci struct ip_tunnel_key tun_key; 13162306a36Sopenharmony_ci struct ip_tunnel_key tun_mask; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci struct bnxt_tc_actions actions; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci /* updated stats accounting for hw-counter wrap-around */ 13662306a36Sopenharmony_ci struct bnxt_tc_flow_stats stats; 13762306a36Sopenharmony_ci /* previous snap-shot of stats */ 13862306a36Sopenharmony_ci struct bnxt_tc_flow_stats prev_stats; 13962306a36Sopenharmony_ci unsigned long lastused; /* jiffies */ 14062306a36Sopenharmony_ci /* for calculating delta from prev_stats and 14162306a36Sopenharmony_ci * updating prev_stats atomically. 14262306a36Sopenharmony_ci */ 14362306a36Sopenharmony_ci spinlock_t stats_lock; 14462306a36Sopenharmony_ci}; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci/* Tunnel encap/decap hash table 14762306a36Sopenharmony_ci * This table is used to maintain a list of flows that use 14862306a36Sopenharmony_ci * the same tunnel encap/decap params (ip_daddrs, vni, udp_dport) 14962306a36Sopenharmony_ci * and the FW returned handle. 15062306a36Sopenharmony_ci * A separate table is maintained for encap and decap 15162306a36Sopenharmony_ci */ 15262306a36Sopenharmony_cistruct bnxt_tc_tunnel_node { 15362306a36Sopenharmony_ci struct ip_tunnel_key key; 15462306a36Sopenharmony_ci struct rhash_head node; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci /* tunnel l2 info */ 15762306a36Sopenharmony_ci struct bnxt_tc_l2_key l2_info; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci#define INVALID_TUNNEL_HANDLE cpu_to_le32(0xffffffff) 16062306a36Sopenharmony_ci /* tunnel handle returned by FW */ 16162306a36Sopenharmony_ci __le32 tunnel_handle; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci u32 refcount; 16462306a36Sopenharmony_ci struct rcu_head rcu; 16562306a36Sopenharmony_ci}; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci/* L2 hash table 16862306a36Sopenharmony_ci * The same data-struct is used for L2-flow table and L2-tunnel table. 16962306a36Sopenharmony_ci * The L2 part of a flow or tunnel is stored in a hash table. 17062306a36Sopenharmony_ci * A flow that shares the same L2 key/mask with an 17162306a36Sopenharmony_ci * already existing flow/tunnel must refer to it's flow handle or 17262306a36Sopenharmony_ci * decap_filter_id respectively. 17362306a36Sopenharmony_ci */ 17462306a36Sopenharmony_cistruct bnxt_tc_l2_node { 17562306a36Sopenharmony_ci /* hash key: first 16b of key */ 17662306a36Sopenharmony_ci#define BNXT_TC_L2_KEY_LEN 16 17762306a36Sopenharmony_ci struct bnxt_tc_l2_key key; 17862306a36Sopenharmony_ci struct rhash_head node; 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci /* a linked list of flows that share the same l2 key */ 18162306a36Sopenharmony_ci struct list_head common_l2_flows; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci /* number of flows/tunnels sharing the l2 key */ 18462306a36Sopenharmony_ci u16 refcount; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci struct rcu_head rcu; 18762306a36Sopenharmony_ci}; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_cistruct bnxt_tc_flow_node { 19062306a36Sopenharmony_ci /* hash key: provided by TC */ 19162306a36Sopenharmony_ci unsigned long cookie; 19262306a36Sopenharmony_ci struct rhash_head node; 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci struct bnxt_tc_flow flow; 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci __le64 ext_flow_handle; 19762306a36Sopenharmony_ci __le16 flow_handle; 19862306a36Sopenharmony_ci __le32 flow_id; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci /* L2 node in l2 hashtable that shares flow's l2 key */ 20162306a36Sopenharmony_ci struct bnxt_tc_l2_node *l2_node; 20262306a36Sopenharmony_ci /* for the shared_flows list maintained in l2_node */ 20362306a36Sopenharmony_ci struct list_head l2_list_node; 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci /* tunnel encap related */ 20662306a36Sopenharmony_ci struct bnxt_tc_tunnel_node *encap_node; 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci /* tunnel decap related */ 20962306a36Sopenharmony_ci struct bnxt_tc_tunnel_node *decap_node; 21062306a36Sopenharmony_ci /* L2 node in tunnel-l2 hashtable that shares flow's tunnel l2 key */ 21162306a36Sopenharmony_ci struct bnxt_tc_l2_node *decap_l2_node; 21262306a36Sopenharmony_ci /* for the shared_flows list maintained in tunnel decap l2_node */ 21362306a36Sopenharmony_ci struct list_head decap_l2_list_node; 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci struct rcu_head rcu; 21662306a36Sopenharmony_ci}; 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ciint bnxt_tc_setup_flower(struct bnxt *bp, u16 src_fid, 21962306a36Sopenharmony_ci struct flow_cls_offload *cls_flower); 22062306a36Sopenharmony_ciint bnxt_init_tc(struct bnxt *bp); 22162306a36Sopenharmony_civoid bnxt_shutdown_tc(struct bnxt *bp); 22262306a36Sopenharmony_civoid bnxt_tc_flow_stats_work(struct bnxt *bp); 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_cistatic inline bool bnxt_tc_flower_enabled(struct bnxt *bp) 22562306a36Sopenharmony_ci{ 22662306a36Sopenharmony_ci return bp->tc_info && bp->tc_info->enabled; 22762306a36Sopenharmony_ci} 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci#else /* CONFIG_BNXT_FLOWER_OFFLOAD */ 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_cistatic inline int bnxt_tc_setup_flower(struct bnxt *bp, u16 src_fid, 23262306a36Sopenharmony_ci struct flow_cls_offload *cls_flower) 23362306a36Sopenharmony_ci{ 23462306a36Sopenharmony_ci return -EOPNOTSUPP; 23562306a36Sopenharmony_ci} 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_cistatic inline int bnxt_init_tc(struct bnxt *bp) 23862306a36Sopenharmony_ci{ 23962306a36Sopenharmony_ci return 0; 24062306a36Sopenharmony_ci} 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_cistatic inline void bnxt_shutdown_tc(struct bnxt *bp) 24362306a36Sopenharmony_ci{ 24462306a36Sopenharmony_ci} 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_cistatic inline void bnxt_tc_flow_stats_work(struct bnxt *bp) 24762306a36Sopenharmony_ci{ 24862306a36Sopenharmony_ci} 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_cistatic inline bool bnxt_tc_flower_enabled(struct bnxt *bp) 25162306a36Sopenharmony_ci{ 25262306a36Sopenharmony_ci return false; 25362306a36Sopenharmony_ci} 25462306a36Sopenharmony_ci#endif /* CONFIG_BNXT_FLOWER_OFFLOAD */ 25562306a36Sopenharmony_ci#endif /* BNXT_TC_H */ 256