xref: /linux/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c (revision 9557b4376d02088a33e5f4116bcc324d35a3b64c)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) Meta Platforms, Inc. and affiliates. */
3 
4 #include <linux/etherdevice.h>
5 #include <linux/ethtool.h>
6 
7 #include "fbnic.h"
8 #include "fbnic_netdev.h"
9 #include "fbnic_rpc.h"
10 
11 void fbnic_reset_indir_tbl(struct fbnic_net *fbn)
12 {
13 	unsigned int num_rx = fbn->num_rx_queues;
14 	unsigned int i;
15 
16 	for (i = 0; i < FBNIC_RPC_RSS_TBL_SIZE; i++) {
17 		fbn->indir_tbl[0][i] = ethtool_rxfh_indir_default(i, num_rx);
18 		fbn->indir_tbl[1][i] = ethtool_rxfh_indir_default(i, num_rx);
19 	}
20 }
21 
22 void fbnic_rss_key_fill(u32 *buffer)
23 {
24 	static u32 rss_key[FBNIC_RPC_RSS_KEY_DWORD_LEN];
25 
26 	net_get_random_once(rss_key, sizeof(rss_key));
27 	rss_key[FBNIC_RPC_RSS_KEY_LAST_IDX] &= FBNIC_RPC_RSS_KEY_LAST_MASK;
28 
29 	memcpy(buffer, rss_key, sizeof(rss_key));
30 }
31 
32 #define RX_HASH_OPT_L4 \
33 	(RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3)
34 #define RX_HASH_OPT_L3 \
35 	(RXH_IP_SRC | RXH_IP_DST)
36 #define RX_HASH_OPT_L2 RXH_L2DA
37 
38 void fbnic_rss_init_en_mask(struct fbnic_net *fbn)
39 {
40 	fbn->rss_flow_hash[FBNIC_TCP4_HASH_OPT] = RX_HASH_OPT_L4;
41 	fbn->rss_flow_hash[FBNIC_TCP6_HASH_OPT] = RX_HASH_OPT_L4;
42 
43 	fbn->rss_flow_hash[FBNIC_UDP4_HASH_OPT] = RX_HASH_OPT_L3;
44 	fbn->rss_flow_hash[FBNIC_UDP6_HASH_OPT] = RX_HASH_OPT_L3;
45 	fbn->rss_flow_hash[FBNIC_IPV4_HASH_OPT] = RX_HASH_OPT_L3;
46 	fbn->rss_flow_hash[FBNIC_IPV6_HASH_OPT] = RX_HASH_OPT_L3;
47 
48 	fbn->rss_flow_hash[FBNIC_ETHER_HASH_OPT] = RX_HASH_OPT_L2;
49 }
50 
51 void fbnic_rss_disable_hw(struct fbnic_dev *fbd)
52 {
53 	/* Disable RPC by clearing enable bit and configuration */
54 	if (!fbnic_bmc_present(fbd))
55 		wr32(fbd, FBNIC_RPC_RMI_CONFIG,
56 		     FIELD_PREP(FBNIC_RPC_RMI_CONFIG_OH_BYTES, 20));
57 }
58 
59 #define FBNIC_FH_2_RSSEM_BIT(_fh, _rssem, _val)		\
60 	FIELD_PREP(FBNIC_RPC_ACT_TBL1_RSS_ENA_##_rssem,	\
61 		   FIELD_GET(RXH_##_fh, _val))
62 static u16 fbnic_flow_hash_2_rss_en_mask(struct fbnic_net *fbn, int flow_type)
63 {
64 	u32 flow_hash = fbn->rss_flow_hash[flow_type];
65 	u32 rss_en_mask = 0;
66 
67 	rss_en_mask |= FBNIC_FH_2_RSSEM_BIT(L2DA, L2_DA, flow_hash);
68 	rss_en_mask |= FBNIC_FH_2_RSSEM_BIT(IP_SRC, IP_SRC, flow_hash);
69 	rss_en_mask |= FBNIC_FH_2_RSSEM_BIT(IP_DST, IP_DST, flow_hash);
70 	rss_en_mask |= FBNIC_FH_2_RSSEM_BIT(L4_B_0_1, L4_SRC, flow_hash);
71 	rss_en_mask |= FBNIC_FH_2_RSSEM_BIT(L4_B_2_3, L4_DST, flow_hash);
72 
73 	return rss_en_mask;
74 }
75 
76 void fbnic_rss_reinit_hw(struct fbnic_dev *fbd, struct fbnic_net *fbn)
77 {
78 	unsigned int i;
79 
80 	for (i = 0; i < FBNIC_RPC_RSS_TBL_SIZE; i++) {
81 		wr32(fbd, FBNIC_RPC_RSS_TBL(0, i), fbn->indir_tbl[0][i]);
82 		wr32(fbd, FBNIC_RPC_RSS_TBL(1, i), fbn->indir_tbl[1][i]);
83 	}
84 
85 	for (i = 0; i < FBNIC_RPC_RSS_KEY_DWORD_LEN; i++)
86 		wr32(fbd, FBNIC_RPC_RSS_KEY(i), fbn->rss_key[i]);
87 
88 	/* Default action for this to drop w/ no destination */
89 	wr32(fbd, FBNIC_RPC_ACT_TBL0_DEFAULT, FBNIC_RPC_ACT_TBL0_DROP);
90 	wrfl(fbd);
91 
92 	wr32(fbd, FBNIC_RPC_ACT_TBL1_DEFAULT, 0);
93 
94 	/* If it isn't already enabled set the RMI Config value to enable RPC */
95 	wr32(fbd, FBNIC_RPC_RMI_CONFIG,
96 	     FIELD_PREP(FBNIC_RPC_RMI_CONFIG_MTU, FBNIC_MAX_JUMBO_FRAME_SIZE) |
97 	     FIELD_PREP(FBNIC_RPC_RMI_CONFIG_OH_BYTES, 20) |
98 	     FBNIC_RPC_RMI_CONFIG_ENABLE);
99 }
100 
101 void fbnic_bmc_rpc_all_multi_config(struct fbnic_dev *fbd,
102 				    bool enable_host)
103 {
104 	struct fbnic_act_tcam *act_tcam;
105 	struct fbnic_mac_addr *mac_addr;
106 	int j;
107 
108 	/* We need to add the all multicast filter at the end of the
109 	 * multicast address list. This way if there are any that are
110 	 * shared between the host and the BMC they can be directed to
111 	 * both. Otherwise the remainder just get sent directly to the
112 	 * BMC.
113 	 */
114 	mac_addr = &fbd->mac_addr[fbd->mac_addr_boundary - 1];
115 	if (fbnic_bmc_present(fbd) && fbd->fw_cap.all_multi) {
116 		if (mac_addr->state != FBNIC_TCAM_S_VALID) {
117 			eth_zero_addr(mac_addr->value.addr8);
118 			eth_broadcast_addr(mac_addr->mask.addr8);
119 			mac_addr->value.addr8[0] ^= 1;
120 			mac_addr->mask.addr8[0] ^= 1;
121 			set_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam);
122 			mac_addr->state = FBNIC_TCAM_S_ADD;
123 		}
124 		if (enable_host)
125 			set_bit(FBNIC_MAC_ADDR_T_ALLMULTI,
126 				mac_addr->act_tcam);
127 		else
128 			clear_bit(FBNIC_MAC_ADDR_T_ALLMULTI,
129 				  mac_addr->act_tcam);
130 	} else if (!test_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam) &&
131 		   !is_zero_ether_addr(mac_addr->mask.addr8) &&
132 		   mac_addr->state == FBNIC_TCAM_S_VALID) {
133 		clear_bit(FBNIC_MAC_ADDR_T_ALLMULTI, mac_addr->act_tcam);
134 		clear_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam);
135 		mac_addr->state = FBNIC_TCAM_S_DELETE;
136 	}
137 
138 	/* We have to add a special handler for multicast as the
139 	 * BMC may have an all-multi rule already in place. As such
140 	 * adding a rule ourselves won't do any good so we will have
141 	 * to modify the rules for the ALL MULTI below if the BMC
142 	 * already has the rule in place.
143 	 */
144 	act_tcam = &fbd->act_tcam[FBNIC_RPC_ACT_TBL_BMC_ALL_MULTI_OFFSET];
145 
146 	/* If we are not enabling the rule just delete it. We will fall
147 	 * back to the RSS rules that support the multicast addresses.
148 	 */
149 	if (!fbnic_bmc_present(fbd) || !fbd->fw_cap.all_multi || enable_host) {
150 		if (act_tcam->state == FBNIC_TCAM_S_VALID)
151 			act_tcam->state = FBNIC_TCAM_S_DELETE;
152 		return;
153 	}
154 
155 	/* Rewrite TCAM rule 23 to handle BMC all-multi traffic */
156 	act_tcam->dest = FIELD_PREP(FBNIC_RPC_ACT_TBL0_DEST_MASK,
157 				    FBNIC_RPC_ACT_TBL0_DEST_BMC);
158 	act_tcam->mask.tcam[0] = 0xffff;
159 
160 	/* MACDA 0 - 3 is reserved for the BMC MAC address */
161 	act_tcam->value.tcam[1] =
162 			FIELD_PREP(FBNIC_RPC_TCAM_ACT1_L2_MACDA_IDX,
163 				   fbd->mac_addr_boundary - 1) |
164 			FBNIC_RPC_TCAM_ACT1_L2_MACDA_VALID;
165 	act_tcam->mask.tcam[1] = 0xffff &
166 			 ~FBNIC_RPC_TCAM_ACT1_L2_MACDA_IDX &
167 			 ~FBNIC_RPC_TCAM_ACT1_L2_MACDA_VALID;
168 
169 	for (j = 2; j < FBNIC_RPC_TCAM_ACT_WORD_LEN; j++)
170 		act_tcam->mask.tcam[j] = 0xffff;
171 
172 	act_tcam->state = FBNIC_TCAM_S_UPDATE;
173 }
174 
175 void fbnic_bmc_rpc_init(struct fbnic_dev *fbd)
176 {
177 	int i = FBNIC_RPC_TCAM_MACDA_BMC_ADDR_IDX;
178 	struct fbnic_act_tcam *act_tcam;
179 	struct fbnic_mac_addr *mac_addr;
180 	int j;
181 
182 	/* Check if BMC is present */
183 	if (!fbnic_bmc_present(fbd))
184 		return;
185 
186 	/* Fetch BMC MAC addresses from firmware capabilities */
187 	for (j = 0; j < 4; j++) {
188 		u8 *bmc_mac = fbd->fw_cap.bmc_mac_addr[j];
189 
190 		/* Validate BMC MAC addresses */
191 		if (is_zero_ether_addr(bmc_mac))
192 			continue;
193 
194 		if (is_multicast_ether_addr(bmc_mac))
195 			mac_addr = __fbnic_mc_sync(fbd, bmc_mac);
196 		else
197 			mac_addr = &fbd->mac_addr[i++];
198 
199 		if (!mac_addr) {
200 			netdev_err(fbd->netdev,
201 				   "No slot for BMC MAC address[%d]\n", j);
202 			continue;
203 		}
204 
205 		ether_addr_copy(mac_addr->value.addr8, bmc_mac);
206 		eth_zero_addr(mac_addr->mask.addr8);
207 
208 		set_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam);
209 		mac_addr->state = FBNIC_TCAM_S_ADD;
210 	}
211 
212 	/* Validate Broadcast is also present, record it and tag it */
213 	mac_addr = &fbd->mac_addr[FBNIC_RPC_TCAM_MACDA_BROADCAST_IDX];
214 	eth_broadcast_addr(mac_addr->value.addr8);
215 	set_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam);
216 	mac_addr->state = FBNIC_TCAM_S_ADD;
217 
218 	/* Rewrite TCAM rule 0 if it isn't present to relocate BMC rules */
219 	act_tcam = &fbd->act_tcam[FBNIC_RPC_ACT_TBL_BMC_OFFSET];
220 	act_tcam->dest = FIELD_PREP(FBNIC_RPC_ACT_TBL0_DEST_MASK,
221 				    FBNIC_RPC_ACT_TBL0_DEST_BMC);
222 	act_tcam->mask.tcam[0] = 0xffff;
223 
224 	/* MACDA 0 - 3 is reserved for the BMC MAC address
225 	 * to account for that we have to mask out the lower 2 bits
226 	 * of the macda by performing an &= with 0x1c.
227 	 */
228 	act_tcam->value.tcam[1] = FBNIC_RPC_TCAM_ACT1_L2_MACDA_VALID;
229 	act_tcam->mask.tcam[1] = 0xffff &
230 			~FIELD_PREP(FBNIC_RPC_TCAM_ACT1_L2_MACDA_IDX, 0x1c) &
231 			~FBNIC_RPC_TCAM_ACT1_L2_MACDA_VALID;
232 
233 	for (j = 2; j < FBNIC_RPC_TCAM_ACT_WORD_LEN; j++)
234 		act_tcam->mask.tcam[j] = 0xffff;
235 
236 	act_tcam->state = FBNIC_TCAM_S_UPDATE;
237 
238 	fbnic_bmc_rpc_all_multi_config(fbd, false);
239 }
240 
241 #define FBNIC_ACT1_INIT(_l4, _udp, _ip, _v6)		\
242 	(((_l4) ? FBNIC_RPC_TCAM_ACT1_L4_VALID : 0) |	\
243 	 ((_udp) ? FBNIC_RPC_TCAM_ACT1_L4_IS_UDP : 0) |	\
244 	 ((_ip) ? FBNIC_RPC_TCAM_ACT1_IP_VALID : 0) |	\
245 	 ((_v6) ? FBNIC_RPC_TCAM_ACT1_IP_IS_V6 : 0))
246 
247 void fbnic_rss_reinit(struct fbnic_dev *fbd, struct fbnic_net *fbn)
248 {
249 	static const u32 act1_value[FBNIC_NUM_HASH_OPT] = {
250 		FBNIC_ACT1_INIT(1, 1, 1, 1),	/* UDP6 */
251 		FBNIC_ACT1_INIT(1, 1, 1, 0),	/* UDP4 */
252 		FBNIC_ACT1_INIT(1, 0, 1, 1),	/* TCP6 */
253 		FBNIC_ACT1_INIT(1, 0, 1, 0),	/* TCP4 */
254 		FBNIC_ACT1_INIT(0, 0, 1, 1),	/* IP6 */
255 		FBNIC_ACT1_INIT(0, 0, 1, 0),	/* IP4 */
256 		0				/* Ether */
257 	};
258 	unsigned int i;
259 
260 	/* To support scenarios where a BMC is present we must write the
261 	 * rules twice, once for the unicast cases, and once again for
262 	 * the broadcast/multicast cases as we have to support 2 destinations.
263 	 */
264 	BUILD_BUG_ON(FBNIC_RSS_EN_NUM_UNICAST * 2 != FBNIC_RSS_EN_NUM_ENTRIES);
265 	BUILD_BUG_ON(ARRAY_SIZE(act1_value) != FBNIC_NUM_HASH_OPT);
266 
267 	/* Program RSS hash enable mask for host in action TCAM/table. */
268 	for (i = fbnic_bmc_present(fbd) ? 0 : FBNIC_RSS_EN_NUM_UNICAST;
269 	     i < FBNIC_RSS_EN_NUM_ENTRIES; i++) {
270 		unsigned int idx = i + FBNIC_RPC_ACT_TBL_RSS_OFFSET;
271 		struct fbnic_act_tcam *act_tcam = &fbd->act_tcam[idx];
272 		u32 flow_hash, dest, rss_en_mask;
273 		int flow_type, j;
274 		u16 value = 0;
275 
276 		flow_type = i % FBNIC_RSS_EN_NUM_UNICAST;
277 		flow_hash = fbn->rss_flow_hash[flow_type];
278 
279 		/* Set DEST_HOST based on absence of RXH_DISCARD */
280 		dest = FIELD_PREP(FBNIC_RPC_ACT_TBL0_DEST_MASK,
281 				  !(RXH_DISCARD & flow_hash) ?
282 				  FBNIC_RPC_ACT_TBL0_DEST_HOST : 0);
283 
284 		if (i >= FBNIC_RSS_EN_NUM_UNICAST && fbnic_bmc_present(fbd))
285 			dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DEST_MASK,
286 					   FBNIC_RPC_ACT_TBL0_DEST_BMC);
287 
288 		if (!dest)
289 			dest = FBNIC_RPC_ACT_TBL0_DROP;
290 
291 		if (act1_value[flow_type] & FBNIC_RPC_TCAM_ACT1_L4_VALID)
292 			dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DMA_HINT,
293 					   FBNIC_RCD_HDR_AL_DMA_HINT_L4);
294 
295 		rss_en_mask = fbnic_flow_hash_2_rss_en_mask(fbn, flow_type);
296 
297 		act_tcam->dest = dest;
298 		act_tcam->rss_en_mask = rss_en_mask;
299 		act_tcam->state = FBNIC_TCAM_S_UPDATE;
300 
301 		act_tcam->mask.tcam[0] = 0xffff;
302 
303 		/* We reserve the upper 8 MACDA TCAM entries for host
304 		 * unicast. So we set the value to 24, and the mask the
305 		 * lower bits so that the lower entries can be used as
306 		 * multicast or BMC addresses.
307 		 */
308 		if (i < FBNIC_RSS_EN_NUM_UNICAST)
309 			value = FIELD_PREP(FBNIC_RPC_TCAM_ACT1_L2_MACDA_IDX,
310 					   fbd->mac_addr_boundary);
311 		value |= FBNIC_RPC_TCAM_ACT1_L2_MACDA_VALID;
312 
313 		flow_type = i % FBNIC_RSS_EN_NUM_UNICAST;
314 		value |= act1_value[flow_type];
315 
316 		act_tcam->value.tcam[1] = value;
317 		act_tcam->mask.tcam[1] = ~value;
318 
319 		for (j = 2; j < FBNIC_RPC_TCAM_ACT_WORD_LEN; j++)
320 			act_tcam->mask.tcam[j] = 0xffff;
321 
322 		act_tcam->state = FBNIC_TCAM_S_UPDATE;
323 	}
324 }
325 
326 struct fbnic_mac_addr *__fbnic_uc_sync(struct fbnic_dev *fbd,
327 				       const unsigned char *addr)
328 {
329 	struct fbnic_mac_addr *avail_addr = NULL;
330 	unsigned int i;
331 
332 	/* Scan from middle of list to bottom, filling bottom up.
333 	 * Skip the first entry which is reserved for dev_addr and
334 	 * leave the last entry to use for promiscuous filtering.
335 	 */
336 	for (i = fbd->mac_addr_boundary - 1;
337 	     i < FBNIC_RPC_TCAM_MACDA_HOST_ADDR_IDX; i++) {
338 		struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[i];
339 
340 		if (mac_addr->state == FBNIC_TCAM_S_DISABLED) {
341 			avail_addr = mac_addr;
342 		} else if (ether_addr_equal(mac_addr->value.addr8, addr)) {
343 			avail_addr = mac_addr;
344 			break;
345 		}
346 	}
347 
348 	if (avail_addr && avail_addr->state == FBNIC_TCAM_S_DISABLED) {
349 		ether_addr_copy(avail_addr->value.addr8, addr);
350 		eth_zero_addr(avail_addr->mask.addr8);
351 		avail_addr->state = FBNIC_TCAM_S_ADD;
352 	}
353 
354 	return avail_addr;
355 }
356 
357 struct fbnic_mac_addr *__fbnic_mc_sync(struct fbnic_dev *fbd,
358 				       const unsigned char *addr)
359 {
360 	struct fbnic_mac_addr *avail_addr = NULL;
361 	unsigned int i;
362 
363 	/* Scan from middle of list to top, filling top down.
364 	 * Skip over the address reserved for the BMC MAC and
365 	 * exclude index 0 as that belongs to the broadcast address
366 	 */
367 	for (i = fbd->mac_addr_boundary;
368 	     --i > FBNIC_RPC_TCAM_MACDA_BROADCAST_IDX;) {
369 		struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[i];
370 
371 		if (mac_addr->state == FBNIC_TCAM_S_DISABLED) {
372 			avail_addr = mac_addr;
373 		} else if (ether_addr_equal(mac_addr->value.addr8, addr)) {
374 			avail_addr = mac_addr;
375 			break;
376 		}
377 	}
378 
379 	/* Scan the BMC addresses to see if it may have already
380 	 * reserved the address.
381 	 */
382 	while (--i) {
383 		struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[i];
384 
385 		if (!is_zero_ether_addr(mac_addr->mask.addr8))
386 			continue;
387 
388 		/* Only move on if we find a match */
389 		if (!ether_addr_equal(mac_addr->value.addr8, addr))
390 			continue;
391 
392 		/* We need to pull this address to the shared area */
393 		if (avail_addr) {
394 			memcpy(avail_addr, mac_addr, sizeof(*mac_addr));
395 			mac_addr->state = FBNIC_TCAM_S_DELETE;
396 			avail_addr->state = FBNIC_TCAM_S_ADD;
397 		}
398 
399 		break;
400 	}
401 
402 	if (avail_addr && avail_addr->state == FBNIC_TCAM_S_DISABLED) {
403 		ether_addr_copy(avail_addr->value.addr8, addr);
404 		eth_zero_addr(avail_addr->mask.addr8);
405 		avail_addr->state = FBNIC_TCAM_S_ADD;
406 	}
407 
408 	return avail_addr;
409 }
410 
411 int __fbnic_xc_unsync(struct fbnic_mac_addr *mac_addr, unsigned int tcam_idx)
412 {
413 	if (!test_and_clear_bit(tcam_idx, mac_addr->act_tcam))
414 		return -ENOENT;
415 
416 	if (bitmap_empty(mac_addr->act_tcam, FBNIC_RPC_TCAM_ACT_NUM_ENTRIES))
417 		mac_addr->state = FBNIC_TCAM_S_DELETE;
418 
419 	return 0;
420 }
421 
422 void fbnic_sift_macda(struct fbnic_dev *fbd)
423 {
424 	int dest, src;
425 
426 	/* Move BMC only addresses back into BMC region */
427 	for (dest = FBNIC_RPC_TCAM_MACDA_BMC_ADDR_IDX,
428 	     src = FBNIC_RPC_TCAM_MACDA_MULTICAST_IDX;
429 	     ++dest < FBNIC_RPC_TCAM_MACDA_BROADCAST_IDX &&
430 	     src < fbd->mac_addr_boundary;) {
431 		struct fbnic_mac_addr *dest_addr = &fbd->mac_addr[dest];
432 
433 		if (dest_addr->state != FBNIC_TCAM_S_DISABLED)
434 			continue;
435 
436 		while (src < fbd->mac_addr_boundary) {
437 			struct fbnic_mac_addr *src_addr = &fbd->mac_addr[src++];
438 
439 			/* Verify BMC bit is set */
440 			if (!test_bit(FBNIC_MAC_ADDR_T_BMC, src_addr->act_tcam))
441 				continue;
442 
443 			/* Verify filter isn't already disabled */
444 			if (src_addr->state == FBNIC_TCAM_S_DISABLED ||
445 			    src_addr->state == FBNIC_TCAM_S_DELETE)
446 				continue;
447 
448 			/* Verify only BMC bit is set */
449 			if (bitmap_weight(src_addr->act_tcam,
450 					  FBNIC_RPC_TCAM_ACT_NUM_ENTRIES) != 1)
451 				continue;
452 
453 			/* Verify we are not moving wildcard address */
454 			if (!is_zero_ether_addr(src_addr->mask.addr8))
455 				continue;
456 
457 			memcpy(dest_addr, src_addr, sizeof(*src_addr));
458 			src_addr->state = FBNIC_TCAM_S_DELETE;
459 			dest_addr->state = FBNIC_TCAM_S_ADD;
460 		}
461 	}
462 }
463 
464 static void fbnic_clear_macda_entry(struct fbnic_dev *fbd, unsigned int idx)
465 {
466 	int i;
467 
468 	/* Invalidate entry and clear addr state info */
469 	for (i = 0; i <= FBNIC_RPC_TCAM_MACDA_WORD_LEN; i++)
470 		wr32(fbd, FBNIC_RPC_TCAM_MACDA(idx, i), 0);
471 }
472 
473 static void fbnic_clear_macda(struct fbnic_dev *fbd)
474 {
475 	int idx;
476 
477 	for (idx = ARRAY_SIZE(fbd->mac_addr); idx--;) {
478 		struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[idx];
479 
480 		if (mac_addr->state == FBNIC_TCAM_S_DISABLED)
481 			continue;
482 
483 		if (test_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam)) {
484 			if (fbnic_bmc_present(fbd))
485 				continue;
486 			dev_warn_once(fbd->dev,
487 				      "Found BMC MAC address w/ BMC not present\n");
488 		}
489 
490 		fbnic_clear_macda_entry(fbd, idx);
491 
492 		/* If rule was already destined for deletion just wipe it now */
493 		if (mac_addr->state == FBNIC_TCAM_S_DELETE) {
494 			memset(mac_addr, 0, sizeof(*mac_addr));
495 			continue;
496 		}
497 
498 		/* Change state to update so that we will rewrite
499 		 * this tcam the next time fbnic_write_macda is called.
500 		 */
501 		mac_addr->state = FBNIC_TCAM_S_UPDATE;
502 	}
503 }
504 
505 static void fbnic_write_macda_entry(struct fbnic_dev *fbd, unsigned int idx,
506 				    struct fbnic_mac_addr *mac_addr)
507 {
508 	__be16 *mask, *value;
509 	int i;
510 
511 	mask = &mac_addr->mask.addr16[FBNIC_RPC_TCAM_MACDA_WORD_LEN - 1];
512 	value = &mac_addr->value.addr16[FBNIC_RPC_TCAM_MACDA_WORD_LEN - 1];
513 
514 	for (i = 0; i < FBNIC_RPC_TCAM_MACDA_WORD_LEN; i++)
515 		wr32(fbd, FBNIC_RPC_TCAM_MACDA(idx, i),
516 		     FIELD_PREP(FBNIC_RPC_TCAM_MACDA_MASK, ntohs(*mask--)) |
517 		     FIELD_PREP(FBNIC_RPC_TCAM_MACDA_VALUE, ntohs(*value--)));
518 
519 	wrfl(fbd);
520 
521 	wr32(fbd, FBNIC_RPC_TCAM_MACDA(idx, i), FBNIC_RPC_TCAM_VALIDATE);
522 }
523 
524 void fbnic_write_macda(struct fbnic_dev *fbd)
525 {
526 	int idx;
527 
528 	for (idx = ARRAY_SIZE(fbd->mac_addr); idx--;) {
529 		struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[idx];
530 
531 		/* Check if update flag is set else exit. */
532 		if (!(mac_addr->state & FBNIC_TCAM_S_UPDATE))
533 			continue;
534 
535 		/* Clear by writing 0s. */
536 		if (mac_addr->state == FBNIC_TCAM_S_DELETE) {
537 			/* Invalidate entry and clear addr state info */
538 			fbnic_clear_macda_entry(fbd, idx);
539 			memset(mac_addr, 0, sizeof(*mac_addr));
540 
541 			continue;
542 		}
543 
544 		fbnic_write_macda_entry(fbd, idx, mac_addr);
545 
546 		mac_addr->state = FBNIC_TCAM_S_VALID;
547 	}
548 }
549 
550 static void fbnic_clear_act_tcam(struct fbnic_dev *fbd, unsigned int idx)
551 {
552 	int i;
553 
554 	/* Invalidate entry and clear addr state info */
555 	for (i = 0; i <= FBNIC_RPC_TCAM_ACT_WORD_LEN; i++)
556 		wr32(fbd, FBNIC_RPC_TCAM_ACT(idx, i), 0);
557 }
558 
559 void fbnic_clear_rules(struct fbnic_dev *fbd)
560 {
561 	u32 dest = FIELD_PREP(FBNIC_RPC_ACT_TBL0_DEST_MASK,
562 			      FBNIC_RPC_ACT_TBL0_DEST_BMC);
563 	int i = FBNIC_RPC_TCAM_ACT_NUM_ENTRIES - 1;
564 	struct fbnic_act_tcam *act_tcam;
565 
566 	/* Clear MAC rules */
567 	fbnic_clear_macda(fbd);
568 
569 	/* If BMC is present we need to preserve the last rule which
570 	 * will be used to route traffic to the BMC if it is received.
571 	 *
572 	 * At this point it should be the only MAC address in the MACDA
573 	 * so any unicast or multicast traffic received should be routed
574 	 * to it. So leave the last rule in place.
575 	 *
576 	 * It will be rewritten to add the host again when we bring
577 	 * the interface back up.
578 	 */
579 	if (fbnic_bmc_present(fbd)) {
580 		act_tcam = &fbd->act_tcam[i];
581 
582 		if (act_tcam->state == FBNIC_TCAM_S_VALID &&
583 		    (act_tcam->dest & dest)) {
584 			wr32(fbd, FBNIC_RPC_ACT_TBL0(i), dest);
585 			wr32(fbd, FBNIC_RPC_ACT_TBL1(i), 0);
586 
587 			act_tcam->state = FBNIC_TCAM_S_UPDATE;
588 
589 			i--;
590 		}
591 	}
592 
593 	/* Work from the bottom up deleting all other rules from hardware */
594 	do {
595 		act_tcam = &fbd->act_tcam[i];
596 
597 		if (act_tcam->state != FBNIC_TCAM_S_VALID)
598 			continue;
599 
600 		fbnic_clear_act_tcam(fbd, i);
601 		act_tcam->state = FBNIC_TCAM_S_UPDATE;
602 	} while (i--);
603 }
604 
605 static void fbnic_delete_act_tcam(struct fbnic_dev *fbd, unsigned int idx)
606 {
607 	fbnic_clear_act_tcam(fbd, idx);
608 	memset(&fbd->act_tcam[idx], 0, sizeof(struct fbnic_act_tcam));
609 }
610 
611 static void fbnic_update_act_tcam(struct fbnic_dev *fbd, unsigned int idx)
612 {
613 	struct fbnic_act_tcam *act_tcam = &fbd->act_tcam[idx];
614 	int i;
615 
616 	/* Update entry by writing the destination and RSS mask */
617 	wr32(fbd, FBNIC_RPC_ACT_TBL0(idx), act_tcam->dest);
618 	wr32(fbd, FBNIC_RPC_ACT_TBL1(idx), act_tcam->rss_en_mask);
619 
620 	/* Write new TCAM rule to hardware */
621 	for (i = 0; i < FBNIC_RPC_TCAM_ACT_WORD_LEN; i++)
622 		wr32(fbd, FBNIC_RPC_TCAM_ACT(idx, i),
623 		     FIELD_PREP(FBNIC_RPC_TCAM_ACT_MASK,
624 				act_tcam->mask.tcam[i]) |
625 		     FIELD_PREP(FBNIC_RPC_TCAM_ACT_VALUE,
626 				act_tcam->value.tcam[i]));
627 
628 	wrfl(fbd);
629 
630 	wr32(fbd, FBNIC_RPC_TCAM_ACT(idx, i), FBNIC_RPC_TCAM_VALIDATE);
631 	act_tcam->state = FBNIC_TCAM_S_VALID;
632 }
633 
634 void fbnic_write_rules(struct fbnic_dev *fbd)
635 {
636 	int i;
637 
638 	/* Flush any pending action table rules */
639 	for (i = 0; i < FBNIC_RPC_ACT_TBL_NUM_ENTRIES; i++) {
640 		struct fbnic_act_tcam *act_tcam = &fbd->act_tcam[i];
641 
642 		/* Check if update flag is set else exit. */
643 		if (!(act_tcam->state & FBNIC_TCAM_S_UPDATE))
644 			continue;
645 
646 		if (act_tcam->state == FBNIC_TCAM_S_DELETE)
647 			fbnic_delete_act_tcam(fbd, i);
648 		else
649 			fbnic_update_act_tcam(fbd, i);
650 	}
651 }
652