18c2ecf20Sopenharmony_ci/* Broadcom NetXtreme-C/E network driver.
28c2ecf20Sopenharmony_ci *
38c2ecf20Sopenharmony_ci * Copyright (c) 2017 Broadcom Limited
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or modify
68c2ecf20Sopenharmony_ci * it under the terms of the GNU General Public License as published by
78c2ecf20Sopenharmony_ci * the Free Software Foundation.
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#ifndef BNXT_TC_H
118c2ecf20Sopenharmony_ci#define BNXT_TC_H
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#ifdef CONFIG_BNXT_FLOWER_OFFLOAD
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#include <net/ip_tunnels.h>
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci/* Structs used for storing the filter/actions of the TC cmd.
188c2ecf20Sopenharmony_ci */
198c2ecf20Sopenharmony_cistruct bnxt_tc_l2_key {
208c2ecf20Sopenharmony_ci	u8		dmac[ETH_ALEN];
218c2ecf20Sopenharmony_ci	u8		smac[ETH_ALEN];
228c2ecf20Sopenharmony_ci	__be16		inner_vlan_tpid;
238c2ecf20Sopenharmony_ci	__be16		inner_vlan_tci;
248c2ecf20Sopenharmony_ci	__be16		ether_type;
258c2ecf20Sopenharmony_ci	u8		num_vlans;
268c2ecf20Sopenharmony_ci	u8		dir;
278c2ecf20Sopenharmony_ci#define BNXT_DIR_RX	1
288c2ecf20Sopenharmony_ci#define BNXT_DIR_TX	0
298c2ecf20Sopenharmony_ci};
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cistruct bnxt_tc_l3_key {
328c2ecf20Sopenharmony_ci	union {
338c2ecf20Sopenharmony_ci		struct {
348c2ecf20Sopenharmony_ci			struct in_addr daddr;
358c2ecf20Sopenharmony_ci			struct in_addr saddr;
368c2ecf20Sopenharmony_ci		} ipv4;
378c2ecf20Sopenharmony_ci		struct {
388c2ecf20Sopenharmony_ci			struct in6_addr daddr;
398c2ecf20Sopenharmony_ci			struct in6_addr saddr;
408c2ecf20Sopenharmony_ci		} ipv6;
418c2ecf20Sopenharmony_ci	};
428c2ecf20Sopenharmony_ci};
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_cistruct bnxt_tc_l4_key {
458c2ecf20Sopenharmony_ci	u8  ip_proto;
468c2ecf20Sopenharmony_ci	union {
478c2ecf20Sopenharmony_ci		struct {
488c2ecf20Sopenharmony_ci			__be16 sport;
498c2ecf20Sopenharmony_ci			__be16 dport;
508c2ecf20Sopenharmony_ci		} ports;
518c2ecf20Sopenharmony_ci		struct {
528c2ecf20Sopenharmony_ci			u8 type;
538c2ecf20Sopenharmony_ci			u8 code;
548c2ecf20Sopenharmony_ci		} icmp;
558c2ecf20Sopenharmony_ci	};
568c2ecf20Sopenharmony_ci};
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_cistruct bnxt_tc_tunnel_key {
598c2ecf20Sopenharmony_ci	struct bnxt_tc_l2_key	l2;
608c2ecf20Sopenharmony_ci	struct bnxt_tc_l3_key	l3;
618c2ecf20Sopenharmony_ci	struct bnxt_tc_l4_key	l4;
628c2ecf20Sopenharmony_ci	__be32			id;
638c2ecf20Sopenharmony_ci};
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci#define bnxt_eth_addr_key_mask_invalid(eth_addr, eth_addr_mask)		\
668c2ecf20Sopenharmony_ci	((is_wildcard(&(eth_addr)[0], ETH_ALEN) &&			\
678c2ecf20Sopenharmony_ci	 is_wildcard(&(eth_addr)[ETH_ALEN / 2], ETH_ALEN)) ||		\
688c2ecf20Sopenharmony_ci	(is_wildcard(&(eth_addr_mask)[0], ETH_ALEN) &&			\
698c2ecf20Sopenharmony_ci	 is_wildcard(&(eth_addr_mask)[ETH_ALEN / 2], ETH_ALEN)))
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_cistruct bnxt_tc_actions {
728c2ecf20Sopenharmony_ci	u32				flags;
738c2ecf20Sopenharmony_ci#define BNXT_TC_ACTION_FLAG_FWD			BIT(0)
748c2ecf20Sopenharmony_ci#define BNXT_TC_ACTION_FLAG_FWD_VXLAN		BIT(1)
758c2ecf20Sopenharmony_ci#define BNXT_TC_ACTION_FLAG_PUSH_VLAN		BIT(3)
768c2ecf20Sopenharmony_ci#define BNXT_TC_ACTION_FLAG_POP_VLAN		BIT(4)
778c2ecf20Sopenharmony_ci#define BNXT_TC_ACTION_FLAG_DROP		BIT(5)
788c2ecf20Sopenharmony_ci#define BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP	BIT(6)
798c2ecf20Sopenharmony_ci#define BNXT_TC_ACTION_FLAG_TUNNEL_DECAP	BIT(7)
808c2ecf20Sopenharmony_ci#define BNXT_TC_ACTION_FLAG_L2_REWRITE		BIT(8)
818c2ecf20Sopenharmony_ci#define BNXT_TC_ACTION_FLAG_NAT_XLATE		BIT(9)
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci	u16				dst_fid;
848c2ecf20Sopenharmony_ci	struct net_device		*dst_dev;
858c2ecf20Sopenharmony_ci	__be16				push_vlan_tpid;
868c2ecf20Sopenharmony_ci	__be16				push_vlan_tci;
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci	/* tunnel encap */
898c2ecf20Sopenharmony_ci	struct ip_tunnel_key		tun_encap_key;
908c2ecf20Sopenharmony_ci#define	PEDIT_OFFSET_SMAC_LAST_4_BYTES		0x8
918c2ecf20Sopenharmony_ci	__be16				l2_rewrite_dmac[3];
928c2ecf20Sopenharmony_ci	__be16				l2_rewrite_smac[3];
938c2ecf20Sopenharmony_ci	struct {
948c2ecf20Sopenharmony_ci		bool src_xlate;  /* true => translate src,
958c2ecf20Sopenharmony_ci				  * false => translate dst
968c2ecf20Sopenharmony_ci				  * Mutually exclusive, i.e cannot set both
978c2ecf20Sopenharmony_ci				  */
988c2ecf20Sopenharmony_ci		bool l3_is_ipv4; /* false means L3 is ipv6 */
998c2ecf20Sopenharmony_ci		struct bnxt_tc_l3_key l3;
1008c2ecf20Sopenharmony_ci		struct bnxt_tc_l4_key l4;
1018c2ecf20Sopenharmony_ci	} nat;
1028c2ecf20Sopenharmony_ci};
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_cistruct bnxt_tc_flow {
1058c2ecf20Sopenharmony_ci	u32				flags;
1068c2ecf20Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_ETH_ADDRS		BIT(1)
1078c2ecf20Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_IPV4_ADDRS		BIT(2)
1088c2ecf20Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_IPV6_ADDRS		BIT(3)
1098c2ecf20Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_PORTS		BIT(4)
1108c2ecf20Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_ICMP			BIT(5)
1118c2ecf20Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_TUNL_ETH_ADDRS	BIT(6)
1128c2ecf20Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_TUNL_IPV4_ADDRS	BIT(7)
1138c2ecf20Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_TUNL_IPV6_ADDRS	BIT(8)
1148c2ecf20Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_TUNL_PORTS		BIT(9)
1158c2ecf20Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_TUNL_ID		BIT(10)
1168c2ecf20Sopenharmony_ci#define BNXT_TC_FLOW_FLAGS_TUNNEL	(BNXT_TC_FLOW_FLAGS_TUNL_ETH_ADDRS | \
1178c2ecf20Sopenharmony_ci					 BNXT_TC_FLOW_FLAGS_TUNL_IPV4_ADDRS | \
1188c2ecf20Sopenharmony_ci					 BNXT_TC_FLOW_FLAGS_TUNL_IPV6_ADDRS |\
1198c2ecf20Sopenharmony_ci					 BNXT_TC_FLOW_FLAGS_TUNL_PORTS |\
1208c2ecf20Sopenharmony_ci					 BNXT_TC_FLOW_FLAGS_TUNL_ID)
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci	/* flow applicable to pkts ingressing on this fid */
1238c2ecf20Sopenharmony_ci	u16				src_fid;
1248c2ecf20Sopenharmony_ci	struct bnxt_tc_l2_key		l2_key;
1258c2ecf20Sopenharmony_ci	struct bnxt_tc_l2_key		l2_mask;
1268c2ecf20Sopenharmony_ci	struct bnxt_tc_l3_key		l3_key;
1278c2ecf20Sopenharmony_ci	struct bnxt_tc_l3_key		l3_mask;
1288c2ecf20Sopenharmony_ci	struct bnxt_tc_l4_key		l4_key;
1298c2ecf20Sopenharmony_ci	struct bnxt_tc_l4_key		l4_mask;
1308c2ecf20Sopenharmony_ci	struct ip_tunnel_key		tun_key;
1318c2ecf20Sopenharmony_ci	struct ip_tunnel_key		tun_mask;
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci	struct bnxt_tc_actions		actions;
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ci	/* updated stats accounting for hw-counter wrap-around */
1368c2ecf20Sopenharmony_ci	struct bnxt_tc_flow_stats	stats;
1378c2ecf20Sopenharmony_ci	/* previous snap-shot of stats */
1388c2ecf20Sopenharmony_ci	struct bnxt_tc_flow_stats	prev_stats;
1398c2ecf20Sopenharmony_ci	unsigned long			lastused; /* jiffies */
1408c2ecf20Sopenharmony_ci	/* for calculating delta from prev_stats and
1418c2ecf20Sopenharmony_ci	 * updating prev_stats atomically.
1428c2ecf20Sopenharmony_ci	 */
1438c2ecf20Sopenharmony_ci	spinlock_t			stats_lock;
1448c2ecf20Sopenharmony_ci};
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci/* Tunnel encap/decap hash table
1478c2ecf20Sopenharmony_ci * This table is used to maintain a list of flows that use
1488c2ecf20Sopenharmony_ci * the same tunnel encap/decap params (ip_daddrs, vni, udp_dport)
1498c2ecf20Sopenharmony_ci * and the FW returned handle.
1508c2ecf20Sopenharmony_ci * A separate table is maintained for encap and decap
1518c2ecf20Sopenharmony_ci */
1528c2ecf20Sopenharmony_cistruct bnxt_tc_tunnel_node {
1538c2ecf20Sopenharmony_ci	struct ip_tunnel_key		key;
1548c2ecf20Sopenharmony_ci	struct rhash_head		node;
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci	/* tunnel l2 info */
1578c2ecf20Sopenharmony_ci	struct bnxt_tc_l2_key		l2_info;
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci#define	INVALID_TUNNEL_HANDLE		cpu_to_le32(0xffffffff)
1608c2ecf20Sopenharmony_ci	/* tunnel handle returned by FW */
1618c2ecf20Sopenharmony_ci	__le32				tunnel_handle;
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci	u32				refcount;
1648c2ecf20Sopenharmony_ci	struct rcu_head			rcu;
1658c2ecf20Sopenharmony_ci};
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci/* L2 hash table
1688c2ecf20Sopenharmony_ci * The same data-struct is used for L2-flow table and L2-tunnel table.
1698c2ecf20Sopenharmony_ci * The L2 part of a flow or tunnel is stored in a hash table.
1708c2ecf20Sopenharmony_ci * A flow that shares the same L2 key/mask with an
1718c2ecf20Sopenharmony_ci * already existing flow/tunnel must refer to it's flow handle or
1728c2ecf20Sopenharmony_ci * decap_filter_id respectively.
1738c2ecf20Sopenharmony_ci */
1748c2ecf20Sopenharmony_cistruct bnxt_tc_l2_node {
1758c2ecf20Sopenharmony_ci	/* hash key: first 16b of key */
1768c2ecf20Sopenharmony_ci#define BNXT_TC_L2_KEY_LEN			16
1778c2ecf20Sopenharmony_ci	struct bnxt_tc_l2_key	key;
1788c2ecf20Sopenharmony_ci	struct rhash_head	node;
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci	/* a linked list of flows that share the same l2 key */
1818c2ecf20Sopenharmony_ci	struct list_head	common_l2_flows;
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_ci	/* number of flows/tunnels sharing the l2 key */
1848c2ecf20Sopenharmony_ci	u16			refcount;
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci	struct rcu_head		rcu;
1878c2ecf20Sopenharmony_ci};
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_cistruct bnxt_tc_flow_node {
1908c2ecf20Sopenharmony_ci	/* hash key: provided by TC */
1918c2ecf20Sopenharmony_ci	unsigned long			cookie;
1928c2ecf20Sopenharmony_ci	struct rhash_head		node;
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ci	struct bnxt_tc_flow		flow;
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci	__le64				ext_flow_handle;
1978c2ecf20Sopenharmony_ci	__le16				flow_handle;
1988c2ecf20Sopenharmony_ci	__le32				flow_id;
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci	/* L2 node in l2 hashtable that shares flow's l2 key */
2018c2ecf20Sopenharmony_ci	struct bnxt_tc_l2_node		*l2_node;
2028c2ecf20Sopenharmony_ci	/* for the shared_flows list maintained in l2_node */
2038c2ecf20Sopenharmony_ci	struct list_head		l2_list_node;
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ci	/* tunnel encap related */
2068c2ecf20Sopenharmony_ci	struct bnxt_tc_tunnel_node	*encap_node;
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_ci	/* tunnel decap related */
2098c2ecf20Sopenharmony_ci	struct bnxt_tc_tunnel_node	*decap_node;
2108c2ecf20Sopenharmony_ci	/* L2 node in tunnel-l2 hashtable that shares flow's tunnel l2 key */
2118c2ecf20Sopenharmony_ci	struct bnxt_tc_l2_node		*decap_l2_node;
2128c2ecf20Sopenharmony_ci	/* for the shared_flows list maintained in tunnel decap l2_node */
2138c2ecf20Sopenharmony_ci	struct list_head		decap_l2_list_node;
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci	struct rcu_head			rcu;
2168c2ecf20Sopenharmony_ci};
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ciint bnxt_tc_setup_flower(struct bnxt *bp, u16 src_fid,
2198c2ecf20Sopenharmony_ci			 struct flow_cls_offload *cls_flower);
2208c2ecf20Sopenharmony_ciint bnxt_init_tc(struct bnxt *bp);
2218c2ecf20Sopenharmony_civoid bnxt_shutdown_tc(struct bnxt *bp);
2228c2ecf20Sopenharmony_civoid bnxt_tc_flow_stats_work(struct bnxt *bp);
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_cistatic inline bool bnxt_tc_flower_enabled(struct bnxt *bp)
2258c2ecf20Sopenharmony_ci{
2268c2ecf20Sopenharmony_ci	return bp->tc_info && bp->tc_info->enabled;
2278c2ecf20Sopenharmony_ci}
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci#else /* CONFIG_BNXT_FLOWER_OFFLOAD */
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_cistatic inline int bnxt_tc_setup_flower(struct bnxt *bp, u16 src_fid,
2328c2ecf20Sopenharmony_ci				       struct flow_cls_offload *cls_flower)
2338c2ecf20Sopenharmony_ci{
2348c2ecf20Sopenharmony_ci	return -EOPNOTSUPP;
2358c2ecf20Sopenharmony_ci}
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_cistatic inline int bnxt_init_tc(struct bnxt *bp)
2388c2ecf20Sopenharmony_ci{
2398c2ecf20Sopenharmony_ci	return 0;
2408c2ecf20Sopenharmony_ci}
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_cistatic inline void bnxt_shutdown_tc(struct bnxt *bp)
2438c2ecf20Sopenharmony_ci{
2448c2ecf20Sopenharmony_ci}
2458c2ecf20Sopenharmony_ci
2468c2ecf20Sopenharmony_cistatic inline void bnxt_tc_flow_stats_work(struct bnxt *bp)
2478c2ecf20Sopenharmony_ci{
2488c2ecf20Sopenharmony_ci}
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_cistatic inline bool bnxt_tc_flower_enabled(struct bnxt *bp)
2518c2ecf20Sopenharmony_ci{
2528c2ecf20Sopenharmony_ci	return false;
2538c2ecf20Sopenharmony_ci}
2548c2ecf20Sopenharmony_ci#endif /* CONFIG_BNXT_FLOWER_OFFLOAD */
2558c2ecf20Sopenharmony_ci#endif /* BNXT_TC_H */
256