summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/meta/fbnic/fbnic_rpc.h
blob: d62935f722a2c229703e0fa84de76e68682fccc2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) Meta Platforms, Inc. and affiliates. */

#ifndef _FBNIC_RPC_H_
#define _FBNIC_RPC_H_

#include <uapi/linux/in6.h>
#include <linux/bitfield.h>

/*  The TCAM state definitions follow an expected ordering.
 *  They start out disabled, then move through the following states:
 *  Disabled  0	-> Add	      2
 *  Add	      2	-> Valid      1
 *
 *  Valid     1	-> Add/Update 2
 *  Add	      2	-> Valid      1
 *
 *  Valid     1	-> Delete     3
 *  Delete    3	-> Disabled   0
 */
enum {
	FBNIC_TCAM_S_DISABLED	= 0,
	FBNIC_TCAM_S_VALID	= 1,
	FBNIC_TCAM_S_ADD	= 2,
	FBNIC_TCAM_S_UPDATE	= FBNIC_TCAM_S_ADD,
	FBNIC_TCAM_S_DELETE	= 3,
};

/* 32 MAC Destination Address TCAM Entries
 * 4 registers DA[1:0], DA[3:2], DA[5:4], Validate
 */
#define FBNIC_RPC_TCAM_MACDA_WORD_LEN		3
#define FBNIC_RPC_TCAM_MACDA_NUM_ENTRIES	32

#define FBNIC_RPC_TCAM_ACT_WORD_LEN		11
#define FBNIC_RPC_TCAM_ACT_NUM_ENTRIES		64

struct fbnic_mac_addr {
	union {
		unsigned char addr8[ETH_ALEN];
		__be16 addr16[FBNIC_RPC_TCAM_MACDA_WORD_LEN];
	} mask, value;
	unsigned char state;
	DECLARE_BITMAP(act_tcam, FBNIC_RPC_TCAM_ACT_NUM_ENTRIES);
};

struct fbnic_act_tcam {
	struct {
		u16 tcam[FBNIC_RPC_TCAM_ACT_WORD_LEN];
	} mask, value;
	unsigned char state;
	u16 rss_en_mask;
	u32 dest;
};

enum {
	FBNIC_RSS_EN_HOST_UDP6,
	FBNIC_RSS_EN_HOST_UDP4,
	FBNIC_RSS_EN_HOST_TCP6,
	FBNIC_RSS_EN_HOST_TCP4,
	FBNIC_RSS_EN_HOST_IP6,
	FBNIC_RSS_EN_HOST_IP4,
	FBNIC_RSS_EN_HOST_ETHER,
	FBNIC_RSS_EN_XCAST_UDP6,
#define FBNIC_RSS_EN_NUM_UNICAST FBNIC_RSS_EN_XCAST_UDP6
	FBNIC_RSS_EN_XCAST_UDP4,
	FBNIC_RSS_EN_XCAST_TCP6,
	FBNIC_RSS_EN_XCAST_TCP4,
	FBNIC_RSS_EN_XCAST_IP6,
	FBNIC_RSS_EN_XCAST_IP4,
	FBNIC_RSS_EN_XCAST_ETHER,
	FBNIC_RSS_EN_NUM_ENTRIES
};

/* Reserve the first 2 entries for the use by the BMC so that we can
 * avoid allowing rules to get in the way of BMC unicast traffic.
 */
#define FBNIC_RPC_ACT_TBL_BMC_OFFSET		0
#define FBNIC_RPC_ACT_TBL_BMC_ALL_MULTI_OFFSET	1

/* We reserve the last 14 entries for RSS rules on the host. The BMC
 * unicast rule will need to be populated above these and is expected to
 * use MACDA TCAM entry 23 to store the BMC MAC address.
 */
#define FBNIC_RPC_ACT_TBL_RSS_OFFSET \
	(FBNIC_RPC_ACT_TBL_NUM_ENTRIES - FBNIC_RSS_EN_NUM_ENTRIES)

/* Flags used to identify the owner for this MAC filter. Note that any
 * flags set for Broadcast thru Promisc indicate that the rule belongs
 * to the RSS filters for the host.
 */
enum {
	FBNIC_MAC_ADDR_T_BMC            = 0,
	FBNIC_MAC_ADDR_T_BROADCAST	= FBNIC_RPC_ACT_TBL_RSS_OFFSET,
#define FBNIC_MAC_ADDR_T_HOST_START	FBNIC_MAC_ADDR_T_BROADCAST
	FBNIC_MAC_ADDR_T_MULTICAST,
	FBNIC_MAC_ADDR_T_UNICAST,
	FBNIC_MAC_ADDR_T_ALLMULTI,	/* BROADCAST ... MULTICAST*/
	FBNIC_MAC_ADDR_T_PROMISC,	/* BROADCAST ... UNICAST */
	FBNIC_MAC_ADDR_T_HOST_LAST
};

#define FBNIC_MAC_ADDR_T_HOST_LEN \
	(FBNIC_MAC_ADDR_T_HOST_LAST - FBNIC_MAC_ADDR_T_HOST_START)

#define FBNIC_RPC_TCAM_ACT0_IPSRC_IDX		CSR_GENMASK(2, 0)
#define FBNIC_RPC_TCAM_ACT0_IPSRC_VALID		CSR_BIT(3)
#define FBNIC_RPC_TCAM_ACT0_IPDST_IDX		CSR_GENMASK(6, 4)
#define FBNIC_RPC_TCAM_ACT0_IPDST_VALID		CSR_BIT(7)
#define FBNIC_RPC_TCAM_ACT0_OUTER_IPSRC_IDX	CSR_GENMASK(10, 8)
#define FBNIC_RPC_TCAM_ACT0_OUTER_IPSRC_VALID	CSR_BIT(11)
#define FBNIC_RPC_TCAM_ACT0_OUTER_IPDST_IDX	CSR_GENMASK(14, 12)
#define FBNIC_RPC_TCAM_ACT0_OUTER_IPDST_VALID	CSR_BIT(15)

#define FBNIC_RPC_TCAM_ACT1_L2_MACDA_IDX	CSR_GENMASK(9, 5)
#define FBNIC_RPC_TCAM_ACT1_L2_MACDA_VALID	CSR_BIT(10)
#define FBNIC_RPC_TCAM_ACT1_IP_IS_V6		CSR_BIT(11)
#define FBNIC_RPC_TCAM_ACT1_IP_VALID		CSR_BIT(12)
#define FBNIC_RPC_TCAM_ACT1_OUTER_IP_VALID	CSR_BIT(13)
#define FBNIC_RPC_TCAM_ACT1_L4_IS_UDP		CSR_BIT(14)
#define FBNIC_RPC_TCAM_ACT1_L4_VALID		CSR_BIT(15)

/* TCAM 0 - 3 reserved for BMC MAC addresses */
#define FBNIC_RPC_TCAM_MACDA_BMC_ADDR_IDX	0
/* TCAM 4 reserved for broadcast MAC address */
#define FBNIC_RPC_TCAM_MACDA_BROADCAST_IDX	4
/* TCAMs 5 - 30 will be used for multicast and unicast addresses. The
 * boundary between the two can be variable it is currently set to 24
 * on which the unicast addresses start. The general idea is that we will
 * always go top-down with unicast, and bottom-up with multicast so that
 * there should be free-space in the middle between the two.
 *
 * The entry at MADCA_DEFAULT_BOUNDARY is a special case as it can be used
 * for the ALL MULTI address if the list is full, or the BMC has requested
 * it.
 */
#define FBNIC_RPC_TCAM_MACDA_MULTICAST_IDX	5
#define FBNIC_RPC_TCAM_MACDA_DEFAULT_BOUNDARY	24
#define FBNIC_RPC_TCAM_MACDA_HOST_ADDR_IDX	30
/* Reserved for use to record Multicast promisc, or Promiscuous */
#define FBNIC_RPC_TCAM_MACDA_PROMISC_IDX	31

enum {
	FBNIC_UDP6_HASH_OPT,
	FBNIC_UDP4_HASH_OPT,
	FBNIC_TCP6_HASH_OPT,
	FBNIC_TCP4_HASH_OPT,
#define FBNIC_L4_HASH_OPT FBNIC_TCP4_HASH_OPT
	FBNIC_IPV6_HASH_OPT,
	FBNIC_IPV4_HASH_OPT,
#define FBNIC_IP_HASH_OPT FBNIC_IPV4_HASH_OPT
	FBNIC_ETHER_HASH_OPT,
	FBNIC_NUM_HASH_OPT,
};

struct fbnic_dev;
struct fbnic_net;

void fbnic_bmc_rpc_init(struct fbnic_dev *fbd);
void fbnic_bmc_rpc_all_multi_config(struct fbnic_dev *fbd, bool enable_host);

void fbnic_reset_indir_tbl(struct fbnic_net *fbn);
void fbnic_rss_key_fill(u32 *buffer);
void fbnic_rss_init_en_mask(struct fbnic_net *fbn);
void fbnic_rss_disable_hw(struct fbnic_dev *fbd);
void fbnic_rss_reinit_hw(struct fbnic_dev *fbd, struct fbnic_net *fbn);
void fbnic_rss_reinit(struct fbnic_dev *fbd, struct fbnic_net *fbn);

int __fbnic_xc_unsync(struct fbnic_mac_addr *mac_addr, unsigned int tcam_idx);
struct fbnic_mac_addr *__fbnic_uc_sync(struct fbnic_dev *fbd,
				       const unsigned char *addr);
struct fbnic_mac_addr *__fbnic_mc_sync(struct fbnic_dev *fbd,
				       const unsigned char *addr);
void fbnic_sift_macda(struct fbnic_dev *fbd);
void fbnic_write_macda(struct fbnic_dev *fbd);

static inline int __fbnic_uc_unsync(struct fbnic_mac_addr *mac_addr)
{
	return __fbnic_xc_unsync(mac_addr, FBNIC_MAC_ADDR_T_UNICAST);
}

static inline int __fbnic_mc_unsync(struct fbnic_mac_addr *mac_addr)
{
	return __fbnic_xc_unsync(mac_addr, FBNIC_MAC_ADDR_T_MULTICAST);
}

void fbnic_clear_rules(struct fbnic_dev *fbd);
void fbnic_write_rules(struct fbnic_dev *fbd);
#endif /* _FBNIC_RPC_H_ */