Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / drivers / net / ethernet / meta / fbnic / fbnic_rpc.c
blob908c098cd59e7198da5ec66c38478361493c5210
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) Meta Platforms, Inc. and affiliates. */
4 #include <linux/etherdevice.h>
5 #include <linux/ethtool.h>
7 #include "fbnic.h"
8 #include "fbnic_netdev.h"
9 #include "fbnic_rpc.h"
11 void fbnic_reset_indir_tbl(struct fbnic_net *fbn)
13 unsigned int num_rx = fbn->num_rx_queues;
14 unsigned int i;
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);
22 void fbnic_rss_key_fill(u32 *buffer)
24 static u32 rss_key[FBNIC_RPC_RSS_KEY_DWORD_LEN];
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;
29 memcpy(buffer, rss_key, sizeof(rss_key));
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
38 void fbnic_rss_init_en_mask(struct fbnic_net *fbn)
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;
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;
48 fbn->rss_flow_hash[FBNIC_ETHER_HASH_OPT] = RX_HASH_OPT_L2;
51 void fbnic_rss_disable_hw(struct fbnic_dev *fbd)
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));
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)
64 u32 flow_hash = fbn->rss_flow_hash[flow_type];
65 u32 rss_en_mask = 0;
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);
73 return rss_en_mask;
76 void fbnic_rss_reinit_hw(struct fbnic_dev *fbd, struct fbnic_net *fbn)
78 unsigned int i;
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]);
85 for (i = 0; i < FBNIC_RPC_RSS_KEY_DWORD_LEN; i++)
86 wr32(fbd, FBNIC_RPC_RSS_KEY(i), fbn->rss_key[i]);
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);
92 wr32(fbd, FBNIC_RPC_ACT_TBL1_DEFAULT, 0);
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);
101 void fbnic_bmc_rpc_all_multi_config(struct fbnic_dev *fbd,
102 bool enable_host)
104 struct fbnic_act_tcam *act_tcam;
105 struct fbnic_mac_addr *mac_addr;
106 int j;
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.
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;
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;
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.
144 act_tcam = &fbd->act_tcam[FBNIC_RPC_ACT_TBL_BMC_ALL_MULTI_OFFSET];
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.
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;
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;
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;
169 for (j = 2; j < FBNIC_RPC_TCAM_ACT_WORD_LEN; j++)
170 act_tcam->mask.tcam[j] = 0xffff;
172 act_tcam->state = FBNIC_TCAM_S_UPDATE;
175 void fbnic_bmc_rpc_init(struct fbnic_dev *fbd)
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;
182 /* Check if BMC is present */
183 if (!fbnic_bmc_present(fbd))
184 return;
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];
190 /* Validate BMC MAC addresses */
191 if (is_zero_ether_addr(bmc_mac))
192 continue;
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++];
199 if (!mac_addr) {
200 netdev_err(fbd->netdev,
201 "No slot for BMC MAC address[%d]\n", j);
202 continue;
205 ether_addr_copy(mac_addr->value.addr8, bmc_mac);
206 eth_zero_addr(mac_addr->mask.addr8);
208 set_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam);
209 mac_addr->state = FBNIC_TCAM_S_ADD;
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;
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;
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.
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;
233 for (j = 2; j < FBNIC_RPC_TCAM_ACT_WORD_LEN; j++)
234 act_tcam->mask.tcam[j] = 0xffff;
236 act_tcam->state = FBNIC_TCAM_S_UPDATE;
238 fbnic_bmc_rpc_all_multi_config(fbd, false);
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))
247 #define FBNIC_TSTAMP_MASK(_all, _udp, _ether) \
248 (((_all) ? ((1u << FBNIC_NUM_HASH_OPT) - 1) : 0) | \
249 ((_udp) ? (1u << FBNIC_UDP6_HASH_OPT) | \
250 (1u << FBNIC_UDP4_HASH_OPT) : 0) | \
251 ((_ether) ? (1u << FBNIC_ETHER_HASH_OPT) : 0))
253 void fbnic_rss_reinit(struct fbnic_dev *fbd, struct fbnic_net *fbn)
255 static const u32 act1_value[FBNIC_NUM_HASH_OPT] = {
256 FBNIC_ACT1_INIT(1, 1, 1, 1), /* UDP6 */
257 FBNIC_ACT1_INIT(1, 1, 1, 0), /* UDP4 */
258 FBNIC_ACT1_INIT(1, 0, 1, 1), /* TCP6 */
259 FBNIC_ACT1_INIT(1, 0, 1, 0), /* TCP4 */
260 FBNIC_ACT1_INIT(0, 0, 1, 1), /* IP6 */
261 FBNIC_ACT1_INIT(0, 0, 1, 0), /* IP4 */
262 0 /* Ether */
264 u32 tstamp_mask = 0;
265 unsigned int i;
267 /* To support scenarios where a BMC is present we must write the
268 * rules twice, once for the unicast cases, and once again for
269 * the broadcast/multicast cases as we have to support 2 destinations.
271 BUILD_BUG_ON(FBNIC_RSS_EN_NUM_UNICAST * 2 != FBNIC_RSS_EN_NUM_ENTRIES);
272 BUILD_BUG_ON(ARRAY_SIZE(act1_value) != FBNIC_NUM_HASH_OPT);
274 /* Set timestamp mask with 1b per flow type */
275 if (fbn->hwtstamp_config.rx_filter != HWTSTAMP_FILTER_NONE) {
276 switch (fbn->hwtstamp_config.rx_filter) {
277 case HWTSTAMP_FILTER_ALL:
278 tstamp_mask = FBNIC_TSTAMP_MASK(1, 1, 1);
279 break;
280 case HWTSTAMP_FILTER_PTP_V2_EVENT:
281 tstamp_mask = FBNIC_TSTAMP_MASK(0, 1, 1);
282 break;
283 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
284 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
285 tstamp_mask = FBNIC_TSTAMP_MASK(0, 1, 0);
286 break;
287 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
288 tstamp_mask = FBNIC_TSTAMP_MASK(0, 0, 1);
289 break;
290 default:
291 netdev_warn(fbn->netdev, "Unsupported hwtstamp_rx_filter\n");
292 break;
296 /* Program RSS hash enable mask for host in action TCAM/table. */
297 for (i = fbnic_bmc_present(fbd) ? 0 : FBNIC_RSS_EN_NUM_UNICAST;
298 i < FBNIC_RSS_EN_NUM_ENTRIES; i++) {
299 unsigned int idx = i + FBNIC_RPC_ACT_TBL_RSS_OFFSET;
300 struct fbnic_act_tcam *act_tcam = &fbd->act_tcam[idx];
301 u32 flow_hash, dest, rss_en_mask;
302 int flow_type, j;
303 u16 value = 0;
305 flow_type = i % FBNIC_RSS_EN_NUM_UNICAST;
306 flow_hash = fbn->rss_flow_hash[flow_type];
308 /* Set DEST_HOST based on absence of RXH_DISCARD */
309 dest = FIELD_PREP(FBNIC_RPC_ACT_TBL0_DEST_MASK,
310 !(RXH_DISCARD & flow_hash) ?
311 FBNIC_RPC_ACT_TBL0_DEST_HOST : 0);
313 if (i >= FBNIC_RSS_EN_NUM_UNICAST && fbnic_bmc_present(fbd))
314 dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DEST_MASK,
315 FBNIC_RPC_ACT_TBL0_DEST_BMC);
317 if (!dest)
318 dest = FBNIC_RPC_ACT_TBL0_DROP;
319 else if (tstamp_mask & (1u << flow_type))
320 dest |= FBNIC_RPC_ACT_TBL0_TS_ENA;
322 if (act1_value[flow_type] & FBNIC_RPC_TCAM_ACT1_L4_VALID)
323 dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DMA_HINT,
324 FBNIC_RCD_HDR_AL_DMA_HINT_L4);
326 rss_en_mask = fbnic_flow_hash_2_rss_en_mask(fbn, flow_type);
328 act_tcam->dest = dest;
329 act_tcam->rss_en_mask = rss_en_mask;
330 act_tcam->state = FBNIC_TCAM_S_UPDATE;
332 act_tcam->mask.tcam[0] = 0xffff;
334 /* We reserve the upper 8 MACDA TCAM entries for host
335 * unicast. So we set the value to 24, and the mask the
336 * lower bits so that the lower entries can be used as
337 * multicast or BMC addresses.
339 if (i < FBNIC_RSS_EN_NUM_UNICAST)
340 value = FIELD_PREP(FBNIC_RPC_TCAM_ACT1_L2_MACDA_IDX,
341 fbd->mac_addr_boundary);
342 value |= FBNIC_RPC_TCAM_ACT1_L2_MACDA_VALID;
344 flow_type = i % FBNIC_RSS_EN_NUM_UNICAST;
345 value |= act1_value[flow_type];
347 act_tcam->value.tcam[1] = value;
348 act_tcam->mask.tcam[1] = ~value;
350 for (j = 2; j < FBNIC_RPC_TCAM_ACT_WORD_LEN; j++)
351 act_tcam->mask.tcam[j] = 0xffff;
353 act_tcam->state = FBNIC_TCAM_S_UPDATE;
357 struct fbnic_mac_addr *__fbnic_uc_sync(struct fbnic_dev *fbd,
358 const unsigned char *addr)
360 struct fbnic_mac_addr *avail_addr = NULL;
361 unsigned int i;
363 /* Scan from middle of list to bottom, filling bottom up.
364 * Skip the first entry which is reserved for dev_addr and
365 * leave the last entry to use for promiscuous filtering.
367 for (i = fbd->mac_addr_boundary - 1;
368 i < FBNIC_RPC_TCAM_MACDA_HOST_ADDR_IDX; i++) {
369 struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[i];
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;
379 if (avail_addr && avail_addr->state == FBNIC_TCAM_S_DISABLED) {
380 ether_addr_copy(avail_addr->value.addr8, addr);
381 eth_zero_addr(avail_addr->mask.addr8);
382 avail_addr->state = FBNIC_TCAM_S_ADD;
385 return avail_addr;
388 struct fbnic_mac_addr *__fbnic_mc_sync(struct fbnic_dev *fbd,
389 const unsigned char *addr)
391 struct fbnic_mac_addr *avail_addr = NULL;
392 unsigned int i;
394 /* Scan from middle of list to top, filling top down.
395 * Skip over the address reserved for the BMC MAC and
396 * exclude index 0 as that belongs to the broadcast address
398 for (i = fbd->mac_addr_boundary;
399 --i > FBNIC_RPC_TCAM_MACDA_BROADCAST_IDX;) {
400 struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[i];
402 if (mac_addr->state == FBNIC_TCAM_S_DISABLED) {
403 avail_addr = mac_addr;
404 } else if (ether_addr_equal(mac_addr->value.addr8, addr)) {
405 avail_addr = mac_addr;
406 break;
410 /* Scan the BMC addresses to see if it may have already
411 * reserved the address.
413 while (--i) {
414 struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[i];
416 if (!is_zero_ether_addr(mac_addr->mask.addr8))
417 continue;
419 /* Only move on if we find a match */
420 if (!ether_addr_equal(mac_addr->value.addr8, addr))
421 continue;
423 /* We need to pull this address to the shared area */
424 if (avail_addr) {
425 memcpy(avail_addr, mac_addr, sizeof(*mac_addr));
426 mac_addr->state = FBNIC_TCAM_S_DELETE;
427 avail_addr->state = FBNIC_TCAM_S_ADD;
430 break;
433 if (avail_addr && avail_addr->state == FBNIC_TCAM_S_DISABLED) {
434 ether_addr_copy(avail_addr->value.addr8, addr);
435 eth_zero_addr(avail_addr->mask.addr8);
436 avail_addr->state = FBNIC_TCAM_S_ADD;
439 return avail_addr;
442 int __fbnic_xc_unsync(struct fbnic_mac_addr *mac_addr, unsigned int tcam_idx)
444 if (!test_and_clear_bit(tcam_idx, mac_addr->act_tcam))
445 return -ENOENT;
447 if (bitmap_empty(mac_addr->act_tcam, FBNIC_RPC_TCAM_ACT_NUM_ENTRIES))
448 mac_addr->state = FBNIC_TCAM_S_DELETE;
450 return 0;
453 void fbnic_sift_macda(struct fbnic_dev *fbd)
455 int dest, src;
457 /* Move BMC only addresses back into BMC region */
458 for (dest = FBNIC_RPC_TCAM_MACDA_BMC_ADDR_IDX,
459 src = FBNIC_RPC_TCAM_MACDA_MULTICAST_IDX;
460 ++dest < FBNIC_RPC_TCAM_MACDA_BROADCAST_IDX &&
461 src < fbd->mac_addr_boundary;) {
462 struct fbnic_mac_addr *dest_addr = &fbd->mac_addr[dest];
464 if (dest_addr->state != FBNIC_TCAM_S_DISABLED)
465 continue;
467 while (src < fbd->mac_addr_boundary) {
468 struct fbnic_mac_addr *src_addr = &fbd->mac_addr[src++];
470 /* Verify BMC bit is set */
471 if (!test_bit(FBNIC_MAC_ADDR_T_BMC, src_addr->act_tcam))
472 continue;
474 /* Verify filter isn't already disabled */
475 if (src_addr->state == FBNIC_TCAM_S_DISABLED ||
476 src_addr->state == FBNIC_TCAM_S_DELETE)
477 continue;
479 /* Verify only BMC bit is set */
480 if (bitmap_weight(src_addr->act_tcam,
481 FBNIC_RPC_TCAM_ACT_NUM_ENTRIES) != 1)
482 continue;
484 /* Verify we are not moving wildcard address */
485 if (!is_zero_ether_addr(src_addr->mask.addr8))
486 continue;
488 memcpy(dest_addr, src_addr, sizeof(*src_addr));
489 src_addr->state = FBNIC_TCAM_S_DELETE;
490 dest_addr->state = FBNIC_TCAM_S_ADD;
495 static void fbnic_clear_macda_entry(struct fbnic_dev *fbd, unsigned int idx)
497 int i;
499 /* Invalidate entry and clear addr state info */
500 for (i = 0; i <= FBNIC_RPC_TCAM_MACDA_WORD_LEN; i++)
501 wr32(fbd, FBNIC_RPC_TCAM_MACDA(idx, i), 0);
504 static void fbnic_clear_macda(struct fbnic_dev *fbd)
506 int idx;
508 for (idx = ARRAY_SIZE(fbd->mac_addr); idx--;) {
509 struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[idx];
511 if (mac_addr->state == FBNIC_TCAM_S_DISABLED)
512 continue;
514 if (test_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam)) {
515 if (fbnic_bmc_present(fbd))
516 continue;
517 dev_warn_once(fbd->dev,
518 "Found BMC MAC address w/ BMC not present\n");
521 fbnic_clear_macda_entry(fbd, idx);
523 /* If rule was already destined for deletion just wipe it now */
524 if (mac_addr->state == FBNIC_TCAM_S_DELETE) {
525 memset(mac_addr, 0, sizeof(*mac_addr));
526 continue;
529 /* Change state to update so that we will rewrite
530 * this tcam the next time fbnic_write_macda is called.
532 mac_addr->state = FBNIC_TCAM_S_UPDATE;
536 static void fbnic_write_macda_entry(struct fbnic_dev *fbd, unsigned int idx,
537 struct fbnic_mac_addr *mac_addr)
539 __be16 *mask, *value;
540 int i;
542 mask = &mac_addr->mask.addr16[FBNIC_RPC_TCAM_MACDA_WORD_LEN - 1];
543 value = &mac_addr->value.addr16[FBNIC_RPC_TCAM_MACDA_WORD_LEN - 1];
545 for (i = 0; i < FBNIC_RPC_TCAM_MACDA_WORD_LEN; i++)
546 wr32(fbd, FBNIC_RPC_TCAM_MACDA(idx, i),
547 FIELD_PREP(FBNIC_RPC_TCAM_MACDA_MASK, ntohs(*mask--)) |
548 FIELD_PREP(FBNIC_RPC_TCAM_MACDA_VALUE, ntohs(*value--)));
550 wrfl(fbd);
552 wr32(fbd, FBNIC_RPC_TCAM_MACDA(idx, i), FBNIC_RPC_TCAM_VALIDATE);
555 void fbnic_write_macda(struct fbnic_dev *fbd)
557 int idx;
559 for (idx = ARRAY_SIZE(fbd->mac_addr); idx--;) {
560 struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[idx];
562 /* Check if update flag is set else exit. */
563 if (!(mac_addr->state & FBNIC_TCAM_S_UPDATE))
564 continue;
566 /* Clear by writing 0s. */
567 if (mac_addr->state == FBNIC_TCAM_S_DELETE) {
568 /* Invalidate entry and clear addr state info */
569 fbnic_clear_macda_entry(fbd, idx);
570 memset(mac_addr, 0, sizeof(*mac_addr));
572 continue;
575 fbnic_write_macda_entry(fbd, idx, mac_addr);
577 mac_addr->state = FBNIC_TCAM_S_VALID;
581 static void fbnic_clear_act_tcam(struct fbnic_dev *fbd, unsigned int idx)
583 int i;
585 /* Invalidate entry and clear addr state info */
586 for (i = 0; i <= FBNIC_RPC_TCAM_ACT_WORD_LEN; i++)
587 wr32(fbd, FBNIC_RPC_TCAM_ACT(idx, i), 0);
590 static void fbnic_clear_tce_tcam_entry(struct fbnic_dev *fbd, unsigned int idx)
592 int i;
594 /* Invalidate entry and clear addr state info */
595 for (i = 0; i <= FBNIC_TCE_TCAM_WORD_LEN; i++)
596 wr32(fbd, FBNIC_TCE_RAM_TCAM(idx, i), 0);
599 static void fbnic_write_tce_tcam_dest(struct fbnic_dev *fbd, unsigned int idx,
600 struct fbnic_mac_addr *mac_addr)
602 u32 dest = FBNIC_TCE_TCAM_DEST_BMC;
603 u32 idx2dest_map;
605 if (is_multicast_ether_addr(mac_addr->value.addr8))
606 dest |= FBNIC_TCE_TCAM_DEST_MAC;
608 idx2dest_map = rd32(fbd, FBNIC_TCE_TCAM_IDX2DEST_MAP);
609 idx2dest_map &= ~(FBNIC_TCE_TCAM_IDX2DEST_MAP_DEST_ID_0 << (4 * idx));
610 idx2dest_map |= dest << (4 * idx);
612 wr32(fbd, FBNIC_TCE_TCAM_IDX2DEST_MAP, idx2dest_map);
615 static void fbnic_write_tce_tcam_entry(struct fbnic_dev *fbd, unsigned int idx,
616 struct fbnic_mac_addr *mac_addr)
618 __be16 *mask, *value;
619 int i;
621 mask = &mac_addr->mask.addr16[FBNIC_TCE_TCAM_WORD_LEN - 1];
622 value = &mac_addr->value.addr16[FBNIC_TCE_TCAM_WORD_LEN - 1];
624 for (i = 0; i < FBNIC_TCE_TCAM_WORD_LEN; i++)
625 wr32(fbd, FBNIC_TCE_RAM_TCAM(idx, i),
626 FIELD_PREP(FBNIC_TCE_RAM_TCAM_MASK, ntohs(*mask--)) |
627 FIELD_PREP(FBNIC_TCE_RAM_TCAM_VALUE, ntohs(*value--)));
629 wrfl(fbd);
631 wr32(fbd, FBNIC_TCE_RAM_TCAM3(idx), FBNIC_TCE_RAM_TCAM3_MCQ_MASK |
632 FBNIC_TCE_RAM_TCAM3_DEST_MASK |
633 FBNIC_TCE_RAM_TCAM3_VALIDATE);
636 static void __fbnic_write_tce_tcam_rev(struct fbnic_dev *fbd)
638 int tcam_idx = FBNIC_TCE_TCAM_NUM_ENTRIES;
639 int mac_idx;
641 for (mac_idx = ARRAY_SIZE(fbd->mac_addr); mac_idx--;) {
642 struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[mac_idx];
644 /* Verify BMC bit is set */
645 if (!test_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam))
646 continue;
648 if (!tcam_idx) {
649 dev_err(fbd->dev, "TCE TCAM overflow\n");
650 return;
653 tcam_idx--;
654 fbnic_write_tce_tcam_dest(fbd, tcam_idx, mac_addr);
655 fbnic_write_tce_tcam_entry(fbd, tcam_idx, mac_addr);
658 while (tcam_idx)
659 fbnic_clear_tce_tcam_entry(fbd, --tcam_idx);
661 fbd->tce_tcam_last = tcam_idx;
664 static void __fbnic_write_tce_tcam(struct fbnic_dev *fbd)
666 int tcam_idx = 0;
667 int mac_idx;
669 for (mac_idx = 0; mac_idx < ARRAY_SIZE(fbd->mac_addr); mac_idx++) {
670 struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[mac_idx];
672 /* Verify BMC bit is set */
673 if (!test_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam))
674 continue;
676 if (tcam_idx == FBNIC_TCE_TCAM_NUM_ENTRIES) {
677 dev_err(fbd->dev, "TCE TCAM overflow\n");
678 return;
681 fbnic_write_tce_tcam_dest(fbd, tcam_idx, mac_addr);
682 fbnic_write_tce_tcam_entry(fbd, tcam_idx, mac_addr);
683 tcam_idx++;
686 while (tcam_idx < FBNIC_TCE_TCAM_NUM_ENTRIES)
687 fbnic_clear_tce_tcam_entry(fbd, tcam_idx++);
689 fbd->tce_tcam_last = tcam_idx;
692 void fbnic_write_tce_tcam(struct fbnic_dev *fbd)
694 if (fbd->tce_tcam_last)
695 __fbnic_write_tce_tcam_rev(fbd);
696 else
697 __fbnic_write_tce_tcam(fbd);
700 void fbnic_clear_rules(struct fbnic_dev *fbd)
702 u32 dest = FIELD_PREP(FBNIC_RPC_ACT_TBL0_DEST_MASK,
703 FBNIC_RPC_ACT_TBL0_DEST_BMC);
704 int i = FBNIC_RPC_TCAM_ACT_NUM_ENTRIES - 1;
705 struct fbnic_act_tcam *act_tcam;
707 /* Clear MAC rules */
708 fbnic_clear_macda(fbd);
710 /* If BMC is present we need to preserve the last rule which
711 * will be used to route traffic to the BMC if it is received.
713 * At this point it should be the only MAC address in the MACDA
714 * so any unicast or multicast traffic received should be routed
715 * to it. So leave the last rule in place.
717 * It will be rewritten to add the host again when we bring
718 * the interface back up.
720 if (fbnic_bmc_present(fbd)) {
721 act_tcam = &fbd->act_tcam[i];
723 if (act_tcam->state == FBNIC_TCAM_S_VALID &&
724 (act_tcam->dest & dest)) {
725 wr32(fbd, FBNIC_RPC_ACT_TBL0(i), dest);
726 wr32(fbd, FBNIC_RPC_ACT_TBL1(i), 0);
728 act_tcam->state = FBNIC_TCAM_S_UPDATE;
730 i--;
734 /* Work from the bottom up deleting all other rules from hardware */
735 do {
736 act_tcam = &fbd->act_tcam[i];
738 if (act_tcam->state != FBNIC_TCAM_S_VALID)
739 continue;
741 fbnic_clear_act_tcam(fbd, i);
742 act_tcam->state = FBNIC_TCAM_S_UPDATE;
743 } while (i--);
746 static void fbnic_delete_act_tcam(struct fbnic_dev *fbd, unsigned int idx)
748 fbnic_clear_act_tcam(fbd, idx);
749 memset(&fbd->act_tcam[idx], 0, sizeof(struct fbnic_act_tcam));
752 static void fbnic_update_act_tcam(struct fbnic_dev *fbd, unsigned int idx)
754 struct fbnic_act_tcam *act_tcam = &fbd->act_tcam[idx];
755 int i;
757 /* Update entry by writing the destination and RSS mask */
758 wr32(fbd, FBNIC_RPC_ACT_TBL0(idx), act_tcam->dest);
759 wr32(fbd, FBNIC_RPC_ACT_TBL1(idx), act_tcam->rss_en_mask);
761 /* Write new TCAM rule to hardware */
762 for (i = 0; i < FBNIC_RPC_TCAM_ACT_WORD_LEN; i++)
763 wr32(fbd, FBNIC_RPC_TCAM_ACT(idx, i),
764 FIELD_PREP(FBNIC_RPC_TCAM_ACT_MASK,
765 act_tcam->mask.tcam[i]) |
766 FIELD_PREP(FBNIC_RPC_TCAM_ACT_VALUE,
767 act_tcam->value.tcam[i]));
769 wrfl(fbd);
771 wr32(fbd, FBNIC_RPC_TCAM_ACT(idx, i), FBNIC_RPC_TCAM_VALIDATE);
772 act_tcam->state = FBNIC_TCAM_S_VALID;
775 void fbnic_write_rules(struct fbnic_dev *fbd)
777 int i;
779 /* Flush any pending action table rules */
780 for (i = 0; i < FBNIC_RPC_ACT_TBL_NUM_ENTRIES; i++) {
781 struct fbnic_act_tcam *act_tcam = &fbd->act_tcam[i];
783 /* Check if update flag is set else exit. */
784 if (!(act_tcam->state & FBNIC_TCAM_S_UPDATE))
785 continue;
787 if (act_tcam->state == FBNIC_TCAM_S_DELETE)
788 fbnic_delete_act_tcam(fbd, i);
789 else
790 fbnic_update_act_tcam(fbd, i);