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 #include <net/ipv6.h>
7
8 #include "fbnic.h"
9 #include "fbnic_fw.h"
10 #include "fbnic_netdev.h"
11 #include "fbnic_rpc.h"
12
fbnic_reset_indir_tbl(struct fbnic_net * fbn)13 void fbnic_reset_indir_tbl(struct fbnic_net *fbn)
14 {
15 unsigned int num_rx = fbn->num_rx_queues;
16 unsigned int i;
17
18 if (netif_is_rxfh_configured(fbn->netdev))
19 return;
20
21 for (i = 0; i < FBNIC_RPC_RSS_TBL_SIZE; i++)
22 fbn->indir_tbl[0][i] = ethtool_rxfh_indir_default(i, num_rx);
23 }
24
fbnic_rss_key_fill(u32 * buffer)25 void fbnic_rss_key_fill(u32 *buffer)
26 {
27 static u32 rss_key[FBNIC_RPC_RSS_KEY_DWORD_LEN];
28
29 net_get_random_once(rss_key, sizeof(rss_key));
30 rss_key[FBNIC_RPC_RSS_KEY_LAST_IDX] &= FBNIC_RPC_RSS_KEY_LAST_MASK;
31
32 memcpy(buffer, rss_key, sizeof(rss_key));
33 }
34
35 #define RX_HASH_OPT_L4 \
36 (RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3)
37 #define RX_HASH_OPT_L3 \
38 (RXH_IP_SRC | RXH_IP_DST)
39 #define RX_HASH_OPT_L2 RXH_L2DA
40
fbnic_rss_init_en_mask(struct fbnic_net * fbn)41 void fbnic_rss_init_en_mask(struct fbnic_net *fbn)
42 {
43 fbn->rss_flow_hash[FBNIC_TCP4_HASH_OPT] = RX_HASH_OPT_L4;
44 fbn->rss_flow_hash[FBNIC_TCP6_HASH_OPT] = RX_HASH_OPT_L4;
45
46 fbn->rss_flow_hash[FBNIC_UDP4_HASH_OPT] = RX_HASH_OPT_L3;
47 fbn->rss_flow_hash[FBNIC_UDP6_HASH_OPT] = RX_HASH_OPT_L3;
48 fbn->rss_flow_hash[FBNIC_IPV4_HASH_OPT] = RX_HASH_OPT_L3;
49 fbn->rss_flow_hash[FBNIC_IPV6_HASH_OPT] = RX_HASH_OPT_L3;
50
51 fbn->rss_flow_hash[FBNIC_ETHER_HASH_OPT] = RX_HASH_OPT_L2;
52 }
53
fbnic_rss_disable_hw(struct fbnic_dev * fbd)54 void fbnic_rss_disable_hw(struct fbnic_dev *fbd)
55 {
56 /* Disable RPC by clearing enable bit and configuration */
57 if (!fbnic_bmc_present(fbd))
58 wr32(fbd, FBNIC_RPC_RMI_CONFIG,
59 FIELD_PREP(FBNIC_RPC_RMI_CONFIG_OH_BYTES, 20));
60 }
61
62 #define FBNIC_FH_2_RSSEM_BIT(_fh, _rssem, _val) \
63 FIELD_PREP(FBNIC_RPC_ACT_TBL1_RSS_ENA_##_rssem, \
64 FIELD_GET(RXH_##_fh, _val))
fbnic_flow_hash_2_rss_en_mask(struct fbnic_net * fbn,int flow_type)65 u16 fbnic_flow_hash_2_rss_en_mask(struct fbnic_net *fbn, int flow_type)
66 {
67 u32 flow_hash = fbn->rss_flow_hash[flow_type];
68 u32 rss_en_mask = 0;
69
70 rss_en_mask |= FBNIC_FH_2_RSSEM_BIT(L2DA, L2_DA, flow_hash);
71 rss_en_mask |= FBNIC_FH_2_RSSEM_BIT(IP_SRC, IP_SRC, flow_hash);
72 rss_en_mask |= FBNIC_FH_2_RSSEM_BIT(IP_DST, IP_DST, flow_hash);
73 rss_en_mask |= FBNIC_FH_2_RSSEM_BIT(L4_B_0_1, L4_SRC, flow_hash);
74 rss_en_mask |= FBNIC_FH_2_RSSEM_BIT(L4_B_2_3, L4_DST, flow_hash);
75 rss_en_mask |= FBNIC_FH_2_RSSEM_BIT(IP6_FL, OV6_FL_LBL, flow_hash);
76 rss_en_mask |= FBNIC_FH_2_RSSEM_BIT(IP6_FL, IV6_FL_LBL, flow_hash);
77
78 return rss_en_mask;
79 }
80
fbnic_rss_reinit_hw(struct fbnic_dev * fbd,struct fbnic_net * fbn)81 void fbnic_rss_reinit_hw(struct fbnic_dev *fbd, struct fbnic_net *fbn)
82 {
83 unsigned int i;
84
85 for (i = 0; i < FBNIC_RPC_RSS_TBL_SIZE; i++) {
86 wr32(fbd, FBNIC_RPC_RSS_TBL(0, i), fbn->indir_tbl[0][i]);
87 wr32(fbd, FBNIC_RPC_RSS_TBL(1, i), fbn->indir_tbl[1][i]);
88 }
89
90 for (i = 0; i < FBNIC_RPC_RSS_KEY_DWORD_LEN; i++)
91 wr32(fbd, FBNIC_RPC_RSS_KEY(i), fbn->rss_key[i]);
92
93 /* Default action for this to drop w/ no destination */
94 wr32(fbd, FBNIC_RPC_ACT_TBL0_DEFAULT, FBNIC_RPC_ACT_TBL0_DROP);
95 wrfl(fbd);
96
97 wr32(fbd, FBNIC_RPC_ACT_TBL1_DEFAULT, 0);
98
99 /* If it isn't already enabled set the RMI Config value to enable RPC */
100 wr32(fbd, FBNIC_RPC_RMI_CONFIG,
101 FIELD_PREP(FBNIC_RPC_RMI_CONFIG_MTU, FBNIC_MAX_JUMBO_FRAME_SIZE) |
102 FIELD_PREP(FBNIC_RPC_RMI_CONFIG_OH_BYTES, 20) |
103 FBNIC_RPC_RMI_CONFIG_ENABLE);
104 }
105
fbnic_bmc_rpc_all_multi_config(struct fbnic_dev * fbd,bool enable_host)106 void fbnic_bmc_rpc_all_multi_config(struct fbnic_dev *fbd,
107 bool enable_host)
108 {
109 struct fbnic_act_tcam *act_tcam;
110 struct fbnic_mac_addr *mac_addr;
111 int j;
112
113 /* We need to add the all multicast filter at the end of the
114 * multicast address list. This way if there are any that are
115 * shared between the host and the BMC they can be directed to
116 * both. Otherwise the remainder just get sent directly to the
117 * BMC.
118 */
119 mac_addr = &fbd->mac_addr[fbd->mac_addr_boundary - 1];
120 if (fbnic_bmc_present(fbd) && fbd->fw_cap.all_multi) {
121 if (mac_addr->state != FBNIC_TCAM_S_VALID) {
122 eth_zero_addr(mac_addr->value.addr8);
123 eth_broadcast_addr(mac_addr->mask.addr8);
124 mac_addr->value.addr8[0] ^= 1;
125 mac_addr->mask.addr8[0] ^= 1;
126 set_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam);
127 mac_addr->state = FBNIC_TCAM_S_ADD;
128 }
129 if (enable_host)
130 set_bit(FBNIC_MAC_ADDR_T_ALLMULTI,
131 mac_addr->act_tcam);
132 else
133 clear_bit(FBNIC_MAC_ADDR_T_ALLMULTI,
134 mac_addr->act_tcam);
135 } else {
136 __fbnic_xc_unsync(mac_addr, FBNIC_MAC_ADDR_T_BMC);
137 __fbnic_xc_unsync(mac_addr, FBNIC_MAC_ADDR_T_ALLMULTI);
138 }
139
140 /* We have to add a special handler for multicast as the
141 * BMC may have an all-multi rule already in place. As such
142 * adding a rule ourselves won't do any good so we will have
143 * to modify the rules for the ALL MULTI below if the BMC
144 * already has the rule in place.
145 */
146 act_tcam = &fbd->act_tcam[FBNIC_RPC_ACT_TBL_BMC_ALL_MULTI_OFFSET];
147
148 /* If we are not enabling the rule just delete it. We will fall
149 * back to the RSS rules that support the multicast addresses.
150 */
151 if (!fbnic_bmc_present(fbd) || !fbd->fw_cap.all_multi || enable_host) {
152 if (act_tcam->state == FBNIC_TCAM_S_VALID)
153 act_tcam->state = FBNIC_TCAM_S_DELETE;
154 return;
155 }
156
157 /* Rewrite TCAM rule 23 to handle BMC all-multi traffic */
158 act_tcam->dest = FIELD_PREP(FBNIC_RPC_ACT_TBL0_DEST_MASK,
159 FBNIC_RPC_ACT_TBL0_DEST_BMC);
160 act_tcam->mask.tcam[0] = 0xffff;
161
162 /* MACDA 0 - 3 is reserved for the BMC MAC address */
163 act_tcam->value.tcam[1] =
164 FIELD_PREP(FBNIC_RPC_TCAM_ACT1_L2_MACDA_IDX,
165 fbd->mac_addr_boundary - 1) |
166 FBNIC_RPC_TCAM_ACT1_L2_MACDA_VALID;
167 act_tcam->mask.tcam[1] = 0xffff &
168 ~FBNIC_RPC_TCAM_ACT1_L2_MACDA_IDX &
169 ~FBNIC_RPC_TCAM_ACT1_L2_MACDA_VALID;
170
171 for (j = 2; j < FBNIC_RPC_TCAM_ACT_WORD_LEN; j++)
172 act_tcam->mask.tcam[j] = 0xffff;
173
174 act_tcam->state = FBNIC_TCAM_S_UPDATE;
175 }
176
fbnic_bmc_rpc_init(struct fbnic_dev * fbd)177 void fbnic_bmc_rpc_init(struct fbnic_dev *fbd)
178 {
179 int i = FBNIC_RPC_TCAM_MACDA_BMC_ADDR_IDX;
180 struct fbnic_act_tcam *act_tcam;
181 struct fbnic_mac_addr *mac_addr;
182 int j;
183
184 /* Check if BMC is present */
185 if (!fbnic_bmc_present(fbd))
186 return;
187
188 /* Fetch BMC MAC addresses from firmware capabilities */
189 for (j = 0; j < 4; j++) {
190 u8 *bmc_mac = fbd->fw_cap.bmc_mac_addr[j];
191
192 /* Validate BMC MAC addresses */
193 if (is_zero_ether_addr(bmc_mac))
194 continue;
195
196 if (is_multicast_ether_addr(bmc_mac))
197 mac_addr = __fbnic_mc_sync(fbd, bmc_mac);
198 else
199 mac_addr = &fbd->mac_addr[i++];
200
201 if (!mac_addr) {
202 netdev_err(fbd->netdev,
203 "No slot for BMC MAC address[%d]\n", j);
204 continue;
205 }
206
207 ether_addr_copy(mac_addr->value.addr8, bmc_mac);
208 eth_zero_addr(mac_addr->mask.addr8);
209
210 set_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam);
211 mac_addr->state = FBNIC_TCAM_S_ADD;
212 }
213
214 /* Validate Broadcast is also present, record it and tag it */
215 mac_addr = &fbd->mac_addr[FBNIC_RPC_TCAM_MACDA_BROADCAST_IDX];
216 eth_broadcast_addr(mac_addr->value.addr8);
217 set_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam);
218 mac_addr->state = FBNIC_TCAM_S_ADD;
219
220 /* Rewrite TCAM rule 0 if it isn't present to relocate BMC rules */
221 act_tcam = &fbd->act_tcam[FBNIC_RPC_ACT_TBL_BMC_OFFSET];
222 act_tcam->dest = FIELD_PREP(FBNIC_RPC_ACT_TBL0_DEST_MASK,
223 FBNIC_RPC_ACT_TBL0_DEST_BMC);
224 act_tcam->mask.tcam[0] = 0xffff;
225
226 /* MACDA 0 - 3 is reserved for the BMC MAC address
227 * to account for that we have to mask out the lower 2 bits
228 * of the macda by performing an &= with 0x1c.
229 */
230 act_tcam->value.tcam[1] = FBNIC_RPC_TCAM_ACT1_L2_MACDA_VALID;
231 act_tcam->mask.tcam[1] = 0xffff &
232 ~FIELD_PREP(FBNIC_RPC_TCAM_ACT1_L2_MACDA_IDX, 0x1c) &
233 ~FBNIC_RPC_TCAM_ACT1_L2_MACDA_VALID;
234
235 for (j = 2; j < FBNIC_RPC_TCAM_ACT_WORD_LEN; j++)
236 act_tcam->mask.tcam[j] = 0xffff;
237
238 act_tcam->state = FBNIC_TCAM_S_UPDATE;
239 }
240
fbnic_bmc_rpc_check(struct fbnic_dev * fbd)241 void fbnic_bmc_rpc_check(struct fbnic_dev *fbd)
242 {
243 int err;
244
245 if (fbd->fw_cap.need_bmc_tcam_reinit) {
246 fbnic_bmc_rpc_init(fbd);
247 netif_addr_lock_bh(fbd->netdev);
248 __fbnic_set_rx_mode(fbd, &fbd->netdev->uc, &fbd->netdev->mc);
249 netif_addr_unlock_bh(fbd->netdev);
250 fbd->fw_cap.need_bmc_tcam_reinit = false;
251 }
252
253 if (fbd->fw_cap.need_bmc_macda_sync) {
254 err = fbnic_fw_xmit_rpc_macda_sync(fbd);
255 if (err)
256 dev_warn(fbd->dev,
257 "Writing MACDA table to FW failed, err: %d\n", err);
258 fbd->fw_cap.need_bmc_macda_sync = false;
259 }
260 }
261
262 #define FBNIC_ACT1_INIT(_l4, _udp, _ip, _v6) \
263 (((_l4) ? FBNIC_RPC_TCAM_ACT1_L4_VALID : 0) | \
264 ((_udp) ? FBNIC_RPC_TCAM_ACT1_L4_IS_UDP : 0) | \
265 ((_ip) ? FBNIC_RPC_TCAM_ACT1_IP_VALID : 0) | \
266 ((_v6) ? FBNIC_RPC_TCAM_ACT1_IP_IS_V6 : 0))
267
268 #define FBNIC_TSTAMP_MASK(_all, _udp, _ether) \
269 (((_all) ? ((1u << FBNIC_NUM_HASH_OPT) - 1) : 0) | \
270 ((_udp) ? (1u << FBNIC_UDP6_HASH_OPT) | \
271 (1u << FBNIC_UDP4_HASH_OPT) : 0) | \
272 ((_ether) ? (1u << FBNIC_ETHER_HASH_OPT) : 0))
273
fbnic_rss_reinit(struct fbnic_dev * fbd,struct fbnic_net * fbn)274 void fbnic_rss_reinit(struct fbnic_dev *fbd, struct fbnic_net *fbn)
275 {
276 static const u32 act1_value[FBNIC_NUM_HASH_OPT] = {
277 FBNIC_ACT1_INIT(1, 1, 1, 1), /* UDP6 */
278 FBNIC_ACT1_INIT(1, 1, 1, 0), /* UDP4 */
279 FBNIC_ACT1_INIT(1, 0, 1, 1), /* TCP6 */
280 FBNIC_ACT1_INIT(1, 0, 1, 0), /* TCP4 */
281 FBNIC_ACT1_INIT(0, 0, 1, 1), /* IP6 */
282 FBNIC_ACT1_INIT(0, 0, 1, 0), /* IP4 */
283 0 /* Ether */
284 };
285 u32 tstamp_mask = 0;
286 unsigned int i;
287
288 /* To support scenarios where a BMC is present we must write the
289 * rules twice, once for the unicast cases, and once again for
290 * the broadcast/multicast cases as we have to support 2 destinations.
291 */
292 BUILD_BUG_ON(FBNIC_RSS_EN_NUM_UNICAST * 2 != FBNIC_RSS_EN_NUM_ENTRIES);
293 BUILD_BUG_ON(ARRAY_SIZE(act1_value) != FBNIC_NUM_HASH_OPT);
294
295 /* Set timestamp mask with 1b per flow type */
296 if (fbn->hwtstamp_config.rx_filter != HWTSTAMP_FILTER_NONE) {
297 switch (fbn->hwtstamp_config.rx_filter) {
298 case HWTSTAMP_FILTER_ALL:
299 tstamp_mask = FBNIC_TSTAMP_MASK(1, 1, 1);
300 break;
301 case HWTSTAMP_FILTER_PTP_V2_EVENT:
302 tstamp_mask = FBNIC_TSTAMP_MASK(0, 1, 1);
303 break;
304 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
305 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
306 tstamp_mask = FBNIC_TSTAMP_MASK(0, 1, 0);
307 break;
308 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
309 tstamp_mask = FBNIC_TSTAMP_MASK(0, 0, 1);
310 break;
311 default:
312 netdev_warn(fbn->netdev, "Unsupported hwtstamp_rx_filter\n");
313 break;
314 }
315 }
316
317 /* Program RSS hash enable mask for host in action TCAM/table. */
318 for (i = fbnic_bmc_present(fbd) ? 0 : FBNIC_RSS_EN_NUM_UNICAST;
319 i < FBNIC_RSS_EN_NUM_ENTRIES; i++) {
320 unsigned int idx = i + FBNIC_RPC_ACT_TBL_RSS_OFFSET;
321 struct fbnic_act_tcam *act_tcam = &fbd->act_tcam[idx];
322 u32 flow_hash, dest, rss_en_mask;
323 int flow_type, j;
324 u16 value = 0;
325
326 flow_type = i % FBNIC_RSS_EN_NUM_UNICAST;
327 flow_hash = fbn->rss_flow_hash[flow_type];
328
329 /* Set DEST_HOST based on absence of RXH_DISCARD */
330 dest = FIELD_PREP(FBNIC_RPC_ACT_TBL0_DEST_MASK,
331 !(RXH_DISCARD & flow_hash) ?
332 FBNIC_RPC_ACT_TBL0_DEST_HOST : 0);
333
334 if (i >= FBNIC_RSS_EN_NUM_UNICAST && fbnic_bmc_present(fbd))
335 dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DEST_MASK,
336 FBNIC_RPC_ACT_TBL0_DEST_BMC);
337
338 if (!dest)
339 dest = FBNIC_RPC_ACT_TBL0_DROP;
340 else if (tstamp_mask & (1u << flow_type))
341 dest |= FBNIC_RPC_ACT_TBL0_TS_ENA;
342
343 dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DMA_HINT,
344 FBNIC_RCD_HDR_AL_DMA_HINT_L4);
345
346 rss_en_mask = fbnic_flow_hash_2_rss_en_mask(fbn, flow_type);
347
348 act_tcam->dest = dest;
349 act_tcam->rss_en_mask = rss_en_mask;
350 act_tcam->state = FBNIC_TCAM_S_UPDATE;
351
352 act_tcam->mask.tcam[0] = 0xffff;
353
354 /* We reserve the upper 8 MACDA TCAM entries for host
355 * unicast. So we set the value to 24, and the mask the
356 * lower bits so that the lower entries can be used as
357 * multicast or BMC addresses.
358 */
359 if (i < FBNIC_RSS_EN_NUM_UNICAST)
360 value = FIELD_PREP(FBNIC_RPC_TCAM_ACT1_L2_MACDA_IDX,
361 fbd->mac_addr_boundary);
362 value |= FBNIC_RPC_TCAM_ACT1_L2_MACDA_VALID;
363
364 flow_type = i % FBNIC_RSS_EN_NUM_UNICAST;
365 value |= act1_value[flow_type];
366
367 act_tcam->value.tcam[1] = value;
368 act_tcam->mask.tcam[1] = ~value;
369
370 for (j = 2; j < FBNIC_RPC_TCAM_ACT_WORD_LEN; j++)
371 act_tcam->mask.tcam[j] = 0xffff;
372
373 act_tcam->state = FBNIC_TCAM_S_UPDATE;
374 }
375 }
376
__fbnic_uc_sync(struct fbnic_dev * fbd,const unsigned char * addr)377 struct fbnic_mac_addr *__fbnic_uc_sync(struct fbnic_dev *fbd,
378 const unsigned char *addr)
379 {
380 struct fbnic_mac_addr *avail_addr = NULL;
381 unsigned int i;
382
383 /* Scan from middle of list to bottom, filling bottom up.
384 * Skip the first entry which is reserved for dev_addr and
385 * leave the last entry to use for promiscuous filtering.
386 */
387 for (i = fbd->mac_addr_boundary - 1;
388 i < FBNIC_RPC_TCAM_MACDA_HOST_ADDR_IDX; i++) {
389 struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[i];
390
391 if (mac_addr->state == FBNIC_TCAM_S_DISABLED) {
392 avail_addr = mac_addr;
393 } else if (ether_addr_equal(mac_addr->value.addr8, addr)) {
394 avail_addr = mac_addr;
395 break;
396 }
397 }
398
399 if (avail_addr && avail_addr->state == FBNIC_TCAM_S_DISABLED) {
400 ether_addr_copy(avail_addr->value.addr8, addr);
401 eth_zero_addr(avail_addr->mask.addr8);
402 avail_addr->state = FBNIC_TCAM_S_ADD;
403 }
404
405 return avail_addr;
406 }
407
__fbnic_mc_sync(struct fbnic_dev * fbd,const unsigned char * addr)408 struct fbnic_mac_addr *__fbnic_mc_sync(struct fbnic_dev *fbd,
409 const unsigned char *addr)
410 {
411 struct fbnic_mac_addr *avail_addr = NULL;
412 unsigned int i;
413
414 /* Scan from middle of list to top, filling top down.
415 * Skip over the address reserved for the BMC MAC and
416 * exclude index 0 as that belongs to the broadcast address
417 */
418 for (i = fbd->mac_addr_boundary;
419 --i > FBNIC_RPC_TCAM_MACDA_BROADCAST_IDX;) {
420 struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[i];
421
422 if (mac_addr->state == FBNIC_TCAM_S_DISABLED) {
423 avail_addr = mac_addr;
424 } else if (ether_addr_equal(mac_addr->value.addr8, addr)) {
425 avail_addr = mac_addr;
426 break;
427 }
428 }
429
430 /* Scan the BMC addresses to see if it may have already
431 * reserved the address.
432 */
433 while (--i) {
434 struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[i];
435
436 if (!is_zero_ether_addr(mac_addr->mask.addr8))
437 continue;
438
439 /* Only move on if we find a match */
440 if (!ether_addr_equal(mac_addr->value.addr8, addr))
441 continue;
442
443 /* We need to pull this address to the shared area */
444 if (avail_addr) {
445 memcpy(avail_addr, mac_addr, sizeof(*mac_addr));
446 mac_addr->state = FBNIC_TCAM_S_DELETE;
447 avail_addr->state = FBNIC_TCAM_S_ADD;
448 }
449
450 break;
451 }
452
453 if (avail_addr && avail_addr->state == FBNIC_TCAM_S_DISABLED) {
454 ether_addr_copy(avail_addr->value.addr8, addr);
455 eth_zero_addr(avail_addr->mask.addr8);
456 avail_addr->state = FBNIC_TCAM_S_ADD;
457 }
458
459 return avail_addr;
460 }
461
__fbnic_xc_unsync(struct fbnic_mac_addr * mac_addr,unsigned int tcam_idx)462 int __fbnic_xc_unsync(struct fbnic_mac_addr *mac_addr, unsigned int tcam_idx)
463 {
464 if (!test_and_clear_bit(tcam_idx, mac_addr->act_tcam))
465 return -ENOENT;
466
467 if (bitmap_empty(mac_addr->act_tcam, FBNIC_RPC_TCAM_ACT_NUM_ENTRIES))
468 mac_addr->state = FBNIC_TCAM_S_DELETE;
469
470 return 0;
471 }
472
fbnic_promisc_sync(struct fbnic_dev * fbd,bool uc_promisc,bool mc_promisc)473 void fbnic_promisc_sync(struct fbnic_dev *fbd,
474 bool uc_promisc, bool mc_promisc)
475 {
476 struct fbnic_mac_addr *mac_addr;
477
478 /* Populate last TCAM entry with promiscuous entry and 0/1 bit mask */
479 mac_addr = &fbd->mac_addr[FBNIC_RPC_TCAM_MACDA_PROMISC_IDX];
480 if (uc_promisc) {
481 if (!is_zero_ether_addr(mac_addr->value.addr8) ||
482 mac_addr->state != FBNIC_TCAM_S_VALID) {
483 eth_zero_addr(mac_addr->value.addr8);
484 eth_broadcast_addr(mac_addr->mask.addr8);
485 clear_bit(FBNIC_MAC_ADDR_T_ALLMULTI,
486 mac_addr->act_tcam);
487 set_bit(FBNIC_MAC_ADDR_T_PROMISC,
488 mac_addr->act_tcam);
489 mac_addr->state = FBNIC_TCAM_S_ADD;
490 }
491 } else if (mc_promisc &&
492 (!fbnic_bmc_present(fbd) || !fbd->fw_cap.all_multi)) {
493 /* We have to add a special handler for multicast as the
494 * BMC may have an all-multi rule already in place. As such
495 * adding a rule ourselves won't do any good so we will have
496 * to modify the rules for the ALL MULTI below if the BMC
497 * already has the rule in place.
498 */
499 if (!is_multicast_ether_addr(mac_addr->value.addr8) ||
500 mac_addr->state != FBNIC_TCAM_S_VALID) {
501 eth_zero_addr(mac_addr->value.addr8);
502 eth_broadcast_addr(mac_addr->mask.addr8);
503 mac_addr->value.addr8[0] ^= 1;
504 mac_addr->mask.addr8[0] ^= 1;
505 set_bit(FBNIC_MAC_ADDR_T_ALLMULTI,
506 mac_addr->act_tcam);
507 clear_bit(FBNIC_MAC_ADDR_T_PROMISC,
508 mac_addr->act_tcam);
509 mac_addr->state = FBNIC_TCAM_S_ADD;
510 }
511 } else if (mac_addr->state == FBNIC_TCAM_S_VALID) {
512 __fbnic_xc_unsync(mac_addr, FBNIC_MAC_ADDR_T_ALLMULTI);
513 __fbnic_xc_unsync(mac_addr, FBNIC_MAC_ADDR_T_PROMISC);
514 }
515 }
516
fbnic_sift_macda(struct fbnic_dev * fbd)517 void fbnic_sift_macda(struct fbnic_dev *fbd)
518 {
519 int dest, src;
520
521 /* Move BMC only addresses back into BMC region */
522 for (dest = FBNIC_RPC_TCAM_MACDA_BMC_ADDR_IDX,
523 src = FBNIC_RPC_TCAM_MACDA_MULTICAST_IDX;
524 ++dest < FBNIC_RPC_TCAM_MACDA_BROADCAST_IDX &&
525 src < fbd->mac_addr_boundary;) {
526 struct fbnic_mac_addr *dest_addr = &fbd->mac_addr[dest];
527
528 if (dest_addr->state != FBNIC_TCAM_S_DISABLED)
529 continue;
530
531 while (src < fbd->mac_addr_boundary) {
532 struct fbnic_mac_addr *src_addr = &fbd->mac_addr[src++];
533
534 /* Verify BMC bit is set */
535 if (!test_bit(FBNIC_MAC_ADDR_T_BMC, src_addr->act_tcam))
536 continue;
537
538 /* Verify filter isn't already disabled */
539 if (src_addr->state == FBNIC_TCAM_S_DISABLED ||
540 src_addr->state == FBNIC_TCAM_S_DELETE)
541 continue;
542
543 /* Verify only BMC bit is set */
544 if (bitmap_weight(src_addr->act_tcam,
545 FBNIC_RPC_TCAM_ACT_NUM_ENTRIES) != 1)
546 continue;
547
548 /* Verify we are not moving wildcard address */
549 if (!is_zero_ether_addr(src_addr->mask.addr8))
550 continue;
551
552 memcpy(dest_addr, src_addr, sizeof(*src_addr));
553 src_addr->state = FBNIC_TCAM_S_DELETE;
554 dest_addr->state = FBNIC_TCAM_S_ADD;
555 }
556 }
557 }
558
fbnic_clear_macda_entry(struct fbnic_dev * fbd,unsigned int idx)559 static void fbnic_clear_macda_entry(struct fbnic_dev *fbd, unsigned int idx)
560 {
561 int i;
562
563 /* Invalidate entry and clear addr state info */
564 for (i = 0; i <= FBNIC_RPC_TCAM_MACDA_WORD_LEN; i++)
565 wr32(fbd, FBNIC_RPC_TCAM_MACDA(idx, i), 0);
566 }
567
fbnic_clear_macda(struct fbnic_dev * fbd)568 static void fbnic_clear_macda(struct fbnic_dev *fbd)
569 {
570 int idx;
571
572 for (idx = ARRAY_SIZE(fbd->mac_addr); idx--;) {
573 struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[idx];
574
575 if (mac_addr->state == FBNIC_TCAM_S_DISABLED)
576 continue;
577
578 if (test_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam)) {
579 if (fbnic_bmc_present(fbd))
580 continue;
581 dev_warn_once(fbd->dev,
582 "Found BMC MAC address w/ BMC not present\n");
583 }
584
585 fbnic_clear_macda_entry(fbd, idx);
586
587 /* If rule was already destined for deletion just wipe it now */
588 if (mac_addr->state == FBNIC_TCAM_S_DELETE) {
589 memset(mac_addr, 0, sizeof(*mac_addr));
590 continue;
591 }
592
593 /* Change state to update so that we will rewrite
594 * this tcam the next time fbnic_write_macda is called.
595 */
596 mac_addr->state = FBNIC_TCAM_S_UPDATE;
597 }
598 }
599
fbnic_clear_valid_macda(struct fbnic_dev * fbd)600 static void fbnic_clear_valid_macda(struct fbnic_dev *fbd)
601 {
602 int idx;
603
604 for (idx = ARRAY_SIZE(fbd->mac_addr); idx--;) {
605 struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[idx];
606
607 if (mac_addr->state == FBNIC_TCAM_S_VALID) {
608 fbnic_clear_macda_entry(fbd, idx);
609
610 mac_addr->state = FBNIC_TCAM_S_UPDATE;
611 }
612 }
613 }
614
fbnic_write_macda_entry(struct fbnic_dev * fbd,unsigned int idx,struct fbnic_mac_addr * mac_addr)615 static void fbnic_write_macda_entry(struct fbnic_dev *fbd, unsigned int idx,
616 struct fbnic_mac_addr *mac_addr)
617 {
618 __be16 *mask, *value;
619 int i;
620
621 mask = &mac_addr->mask.addr16[FBNIC_RPC_TCAM_MACDA_WORD_LEN - 1];
622 value = &mac_addr->value.addr16[FBNIC_RPC_TCAM_MACDA_WORD_LEN - 1];
623
624 for (i = 0; i < FBNIC_RPC_TCAM_MACDA_WORD_LEN; i++)
625 wr32(fbd, FBNIC_RPC_TCAM_MACDA(idx, i),
626 FIELD_PREP(FBNIC_RPC_TCAM_MACDA_MASK, ntohs(*mask--)) |
627 FIELD_PREP(FBNIC_RPC_TCAM_MACDA_VALUE, ntohs(*value--)));
628
629 wrfl(fbd);
630
631 wr32(fbd, FBNIC_RPC_TCAM_MACDA(idx, i), FBNIC_RPC_TCAM_VALIDATE);
632 }
633
fbnic_write_macda(struct fbnic_dev * fbd)634 void fbnic_write_macda(struct fbnic_dev *fbd)
635 {
636 int idx, updates = 0;
637
638 for (idx = ARRAY_SIZE(fbd->mac_addr); idx--;) {
639 struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[idx];
640
641 /* Check if update flag is set else exit. */
642 if (!(mac_addr->state & FBNIC_TCAM_S_UPDATE))
643 continue;
644
645 /* Record update count */
646 updates++;
647
648 /* Clear by writing 0s. */
649 if (mac_addr->state == FBNIC_TCAM_S_DELETE) {
650 /* Invalidate entry and clear addr state info */
651 fbnic_clear_macda_entry(fbd, idx);
652 memset(mac_addr, 0, sizeof(*mac_addr));
653
654 continue;
655 }
656
657 fbnic_write_macda_entry(fbd, idx, mac_addr);
658
659 mac_addr->state = FBNIC_TCAM_S_VALID;
660 }
661
662 /* If reinitializing the BMC TCAM we are doing an initial update */
663 if (fbd->fw_cap.need_bmc_tcam_reinit)
664 updates++;
665
666 /* If needed notify firmware of changes to MACDA TCAM */
667 if (updates != 0 && fbnic_bmc_present(fbd))
668 fbd->fw_cap.need_bmc_macda_sync = true;
669 }
670
fbnic_clear_act_tcam(struct fbnic_dev * fbd,unsigned int idx)671 static void fbnic_clear_act_tcam(struct fbnic_dev *fbd, unsigned int idx)
672 {
673 int i;
674
675 /* Invalidate entry and clear addr state info */
676 for (i = 0; i <= FBNIC_RPC_TCAM_ACT_WORD_LEN; i++)
677 wr32(fbd, FBNIC_RPC_TCAM_ACT(idx, i), 0);
678 }
679
fbnic_clear_tce_tcam_entry(struct fbnic_dev * fbd,unsigned int idx)680 static void fbnic_clear_tce_tcam_entry(struct fbnic_dev *fbd, unsigned int idx)
681 {
682 int i;
683
684 /* Invalidate entry and clear addr state info */
685 for (i = 0; i <= FBNIC_TCE_TCAM_WORD_LEN; i++)
686 wr32(fbd, FBNIC_TCE_RAM_TCAM(idx, i), 0);
687 }
688
fbnic_write_tce_tcam_dest(struct fbnic_dev * fbd,unsigned int idx,struct fbnic_mac_addr * mac_addr)689 static void fbnic_write_tce_tcam_dest(struct fbnic_dev *fbd, unsigned int idx,
690 struct fbnic_mac_addr *mac_addr)
691 {
692 u32 dest = FBNIC_TCE_TCAM_DEST_BMC;
693 u32 idx2dest_map;
694
695 if (is_multicast_ether_addr(mac_addr->value.addr8))
696 dest |= FBNIC_TCE_TCAM_DEST_MAC;
697
698 idx2dest_map = rd32(fbd, FBNIC_TCE_TCAM_IDX2DEST_MAP);
699 idx2dest_map &= ~(FBNIC_TCE_TCAM_IDX2DEST_MAP_DEST_ID_0 << (4 * idx));
700 idx2dest_map |= dest << (4 * idx);
701
702 wr32(fbd, FBNIC_TCE_TCAM_IDX2DEST_MAP, idx2dest_map);
703 }
704
fbnic_write_tce_tcam_entry(struct fbnic_dev * fbd,unsigned int idx,struct fbnic_mac_addr * mac_addr)705 static void fbnic_write_tce_tcam_entry(struct fbnic_dev *fbd, unsigned int idx,
706 struct fbnic_mac_addr *mac_addr)
707 {
708 __be16 *mask, *value;
709 int i;
710
711 mask = &mac_addr->mask.addr16[FBNIC_TCE_TCAM_WORD_LEN - 1];
712 value = &mac_addr->value.addr16[FBNIC_TCE_TCAM_WORD_LEN - 1];
713
714 for (i = 0; i < FBNIC_TCE_TCAM_WORD_LEN; i++)
715 wr32(fbd, FBNIC_TCE_RAM_TCAM(idx, i),
716 FIELD_PREP(FBNIC_TCE_RAM_TCAM_MASK, ntohs(*mask--)) |
717 FIELD_PREP(FBNIC_TCE_RAM_TCAM_VALUE, ntohs(*value--)));
718
719 wrfl(fbd);
720
721 wr32(fbd, FBNIC_TCE_RAM_TCAM3(idx), FBNIC_TCE_RAM_TCAM3_MCQ_MASK |
722 FBNIC_TCE_RAM_TCAM3_DEST_MASK |
723 FBNIC_TCE_RAM_TCAM3_VALIDATE);
724 }
725
__fbnic_write_tce_tcam_rev(struct fbnic_dev * fbd)726 static void __fbnic_write_tce_tcam_rev(struct fbnic_dev *fbd)
727 {
728 int tcam_idx = FBNIC_TCE_TCAM_NUM_ENTRIES;
729 int mac_idx;
730
731 for (mac_idx = ARRAY_SIZE(fbd->mac_addr); mac_idx--;) {
732 struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[mac_idx];
733
734 /* Verify BMC bit is set */
735 if (!test_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam))
736 continue;
737
738 if (!tcam_idx) {
739 dev_err(fbd->dev, "TCE TCAM overflow\n");
740 return;
741 }
742
743 tcam_idx--;
744 fbnic_write_tce_tcam_dest(fbd, tcam_idx, mac_addr);
745 fbnic_write_tce_tcam_entry(fbd, tcam_idx, mac_addr);
746 }
747
748 while (tcam_idx)
749 fbnic_clear_tce_tcam_entry(fbd, --tcam_idx);
750
751 fbd->tce_tcam_last = tcam_idx;
752 }
753
__fbnic_write_tce_tcam(struct fbnic_dev * fbd)754 static void __fbnic_write_tce_tcam(struct fbnic_dev *fbd)
755 {
756 int tcam_idx = 0;
757 int mac_idx;
758
759 for (mac_idx = 0; mac_idx < ARRAY_SIZE(fbd->mac_addr); mac_idx++) {
760 struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[mac_idx];
761
762 /* Verify BMC bit is set */
763 if (!test_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam))
764 continue;
765
766 if (tcam_idx == FBNIC_TCE_TCAM_NUM_ENTRIES) {
767 dev_err(fbd->dev, "TCE TCAM overflow\n");
768 return;
769 }
770
771 fbnic_write_tce_tcam_dest(fbd, tcam_idx, mac_addr);
772 fbnic_write_tce_tcam_entry(fbd, tcam_idx, mac_addr);
773 tcam_idx++;
774 }
775
776 while (tcam_idx < FBNIC_TCE_TCAM_NUM_ENTRIES)
777 fbnic_clear_tce_tcam_entry(fbd, tcam_idx++);
778
779 fbd->tce_tcam_last = tcam_idx;
780 }
781
fbnic_write_tce_tcam(struct fbnic_dev * fbd)782 void fbnic_write_tce_tcam(struct fbnic_dev *fbd)
783 {
784 if (fbd->tce_tcam_last)
785 __fbnic_write_tce_tcam_rev(fbd);
786 else
787 __fbnic_write_tce_tcam(fbd);
788 }
789
__fbnic_ip4_sync(struct fbnic_dev * fbd,struct fbnic_ip_addr * ip_addr,const struct in_addr * addr,const struct in_addr * mask)790 struct fbnic_ip_addr *__fbnic_ip4_sync(struct fbnic_dev *fbd,
791 struct fbnic_ip_addr *ip_addr,
792 const struct in_addr *addr,
793 const struct in_addr *mask)
794 {
795 struct fbnic_ip_addr *avail_addr = NULL;
796 unsigned int i;
797
798 /* Scan from top of list to bottom, filling bottom up. */
799 for (i = 0; i < FBNIC_RPC_TCAM_IP_ADDR_NUM_ENTRIES; i++, ip_addr++) {
800 struct in6_addr *m = &ip_addr->mask;
801
802 if (ip_addr->state == FBNIC_TCAM_S_DISABLED) {
803 avail_addr = ip_addr;
804 continue;
805 }
806
807 if (ip_addr->version != 4)
808 continue;
809
810 /* Drop avail_addr if mask is a subset of our current mask,
811 * This prevents us from inserting a longer prefix behind a
812 * shorter one.
813 *
814 * The mask is stored inverted value so as an example:
815 * m ffff ffff ffff ffff ffff ffff ffff 0000 0000
816 * mask 0000 0000 0000 0000 0000 0000 0000 ffff ffff
817 *
818 * "m" and "mask" represent typical IPv4 mask stored in
819 * the TCAM and those provided by the stack. The code below
820 * should return a non-zero result if there is a 0 stored
821 * anywhere in "m" where "mask" has a 0.
822 */
823 if (~m->s6_addr32[3] & ~mask->s_addr) {
824 avail_addr = NULL;
825 continue;
826 }
827
828 /* Check to see if the mask actually contains fewer bits than
829 * our new mask "m". The XOR below should only result in 0 if
830 * "m" is masking a bit that we are looking for in our new
831 * "mask", we eliminated the 0^0 case with the check above.
832 *
833 * If it contains fewer bits we need to stop here, otherwise
834 * we might be adding an unreachable rule.
835 */
836 if (~(m->s6_addr32[3] ^ mask->s_addr))
837 break;
838
839 if (ip_addr->value.s6_addr32[3] == addr->s_addr) {
840 avail_addr = ip_addr;
841 break;
842 }
843 }
844
845 if (avail_addr && avail_addr->state == FBNIC_TCAM_S_DISABLED) {
846 ipv6_addr_set(&avail_addr->value, 0, 0, 0, addr->s_addr);
847 ipv6_addr_set(&avail_addr->mask, htonl(~0), htonl(~0),
848 htonl(~0), ~mask->s_addr);
849 avail_addr->version = 4;
850
851 avail_addr->state = FBNIC_TCAM_S_ADD;
852 }
853
854 return avail_addr;
855 }
856
__fbnic_ip6_sync(struct fbnic_dev * fbd,struct fbnic_ip_addr * ip_addr,const struct in6_addr * addr,const struct in6_addr * mask)857 struct fbnic_ip_addr *__fbnic_ip6_sync(struct fbnic_dev *fbd,
858 struct fbnic_ip_addr *ip_addr,
859 const struct in6_addr *addr,
860 const struct in6_addr *mask)
861 {
862 struct fbnic_ip_addr *avail_addr = NULL;
863 unsigned int i;
864
865 ip_addr = &ip_addr[FBNIC_RPC_TCAM_IP_ADDR_NUM_ENTRIES - 1];
866
867 /* Scan from bottom of list to top, filling top down. */
868 for (i = FBNIC_RPC_TCAM_IP_ADDR_NUM_ENTRIES; i--; ip_addr--) {
869 struct in6_addr *m = &ip_addr->mask;
870
871 if (ip_addr->state == FBNIC_TCAM_S_DISABLED) {
872 avail_addr = ip_addr;
873 continue;
874 }
875
876 if (ip_addr->version != 6)
877 continue;
878
879 /* Drop avail_addr if mask is a superset of our current mask.
880 * This prevents us from inserting a longer prefix behind a
881 * shorter one.
882 *
883 * The mask is stored inverted value so as an example:
884 * m 0000 0000 0000 0000 0000 0000 0000 0000 0000
885 * mask ffff ffff ffff ffff ffff ffff ffff ffff ffff
886 *
887 * "m" and "mask" represent typical IPv6 mask stored in
888 * the TCAM and those provided by the stack. The code below
889 * should return a non-zero result which will cause us
890 * to drop the avail_addr value that might be cached
891 * to prevent us from dropping a v6 address behind it.
892 */
893 if ((m->s6_addr32[0] & mask->s6_addr32[0]) |
894 (m->s6_addr32[1] & mask->s6_addr32[1]) |
895 (m->s6_addr32[2] & mask->s6_addr32[2]) |
896 (m->s6_addr32[3] & mask->s6_addr32[3])) {
897 avail_addr = NULL;
898 continue;
899 }
900
901 /* The previous test eliminated any overlap between the
902 * two values so now we need to check for gaps.
903 *
904 * If the mask is equal to our current mask then it should
905 * result with m ^ mask = ffff ffff, if however the value
906 * stored in m is bigger then we should see a 0 appear
907 * somewhere in the mask.
908 */
909 if (~(m->s6_addr32[0] ^ mask->s6_addr32[0]) |
910 ~(m->s6_addr32[1] ^ mask->s6_addr32[1]) |
911 ~(m->s6_addr32[2] ^ mask->s6_addr32[2]) |
912 ~(m->s6_addr32[3] ^ mask->s6_addr32[3]))
913 break;
914
915 if (ipv6_addr_cmp(&ip_addr->value, addr))
916 continue;
917
918 avail_addr = ip_addr;
919 break;
920 }
921
922 if (avail_addr && avail_addr->state == FBNIC_TCAM_S_DISABLED) {
923 memcpy(&avail_addr->value, addr, sizeof(*addr));
924 ipv6_addr_set(&avail_addr->mask,
925 ~mask->s6_addr32[0], ~mask->s6_addr32[1],
926 ~mask->s6_addr32[2], ~mask->s6_addr32[3]);
927 avail_addr->version = 6;
928
929 avail_addr->state = FBNIC_TCAM_S_ADD;
930 }
931
932 return avail_addr;
933 }
934
__fbnic_ip_unsync(struct fbnic_ip_addr * ip_addr,unsigned int tcam_idx)935 int __fbnic_ip_unsync(struct fbnic_ip_addr *ip_addr, unsigned int tcam_idx)
936 {
937 if (!test_and_clear_bit(tcam_idx, ip_addr->act_tcam))
938 return -ENOENT;
939
940 if (bitmap_empty(ip_addr->act_tcam, FBNIC_RPC_TCAM_ACT_NUM_ENTRIES))
941 ip_addr->state = FBNIC_TCAM_S_DELETE;
942
943 return 0;
944 }
945
fbnic_clear_ip_src_entry(struct fbnic_dev * fbd,unsigned int idx)946 static void fbnic_clear_ip_src_entry(struct fbnic_dev *fbd, unsigned int idx)
947 {
948 int i;
949
950 /* Invalidate entry and clear addr state info */
951 for (i = 0; i <= FBNIC_RPC_TCAM_IP_ADDR_WORD_LEN; i++)
952 wr32(fbd, FBNIC_RPC_TCAM_IPSRC(idx, i), 0);
953 }
954
fbnic_clear_ip_dst_entry(struct fbnic_dev * fbd,unsigned int idx)955 static void fbnic_clear_ip_dst_entry(struct fbnic_dev *fbd, unsigned int idx)
956 {
957 int i;
958
959 /* Invalidate entry and clear addr state info */
960 for (i = 0; i <= FBNIC_RPC_TCAM_IP_ADDR_WORD_LEN; i++)
961 wr32(fbd, FBNIC_RPC_TCAM_IPDST(idx, i), 0);
962 }
963
fbnic_clear_ip_outer_src_entry(struct fbnic_dev * fbd,unsigned int idx)964 static void fbnic_clear_ip_outer_src_entry(struct fbnic_dev *fbd,
965 unsigned int idx)
966 {
967 int i;
968
969 /* Invalidate entry and clear addr state info */
970 for (i = 0; i <= FBNIC_RPC_TCAM_IP_ADDR_WORD_LEN; i++)
971 wr32(fbd, FBNIC_RPC_TCAM_OUTER_IPSRC(idx, i), 0);
972 }
973
fbnic_clear_ip_outer_dst_entry(struct fbnic_dev * fbd,unsigned int idx)974 static void fbnic_clear_ip_outer_dst_entry(struct fbnic_dev *fbd,
975 unsigned int idx)
976 {
977 int i;
978
979 /* Invalidate entry and clear addr state info */
980 for (i = 0; i <= FBNIC_RPC_TCAM_IP_ADDR_WORD_LEN; i++)
981 wr32(fbd, FBNIC_RPC_TCAM_OUTER_IPDST(idx, i), 0);
982 }
983
fbnic_write_ip_src_entry(struct fbnic_dev * fbd,unsigned int idx,struct fbnic_ip_addr * ip_addr)984 static void fbnic_write_ip_src_entry(struct fbnic_dev *fbd, unsigned int idx,
985 struct fbnic_ip_addr *ip_addr)
986 {
987 __be16 *mask, *value;
988 int i;
989
990 mask = &ip_addr->mask.s6_addr16[FBNIC_RPC_TCAM_IP_ADDR_WORD_LEN - 1];
991 value = &ip_addr->value.s6_addr16[FBNIC_RPC_TCAM_IP_ADDR_WORD_LEN - 1];
992
993 for (i = 0; i < FBNIC_RPC_TCAM_IP_ADDR_WORD_LEN; i++)
994 wr32(fbd, FBNIC_RPC_TCAM_IPSRC(idx, i),
995 FIELD_PREP(FBNIC_RPC_TCAM_IP_ADDR_MASK, ntohs(*mask--)) |
996 FIELD_PREP(FBNIC_RPC_TCAM_IP_ADDR_VALUE, ntohs(*value--)));
997 wrfl(fbd);
998
999 /* Bit 129 is used to flag for v4/v6 */
1000 wr32(fbd, FBNIC_RPC_TCAM_IPSRC(idx, i),
1001 (ip_addr->version == 6) | FBNIC_RPC_TCAM_VALIDATE);
1002 }
1003
fbnic_write_ip_dst_entry(struct fbnic_dev * fbd,unsigned int idx,struct fbnic_ip_addr * ip_addr)1004 static void fbnic_write_ip_dst_entry(struct fbnic_dev *fbd, unsigned int idx,
1005 struct fbnic_ip_addr *ip_addr)
1006 {
1007 __be16 *mask, *value;
1008 int i;
1009
1010 mask = &ip_addr->mask.s6_addr16[FBNIC_RPC_TCAM_IP_ADDR_WORD_LEN - 1];
1011 value = &ip_addr->value.s6_addr16[FBNIC_RPC_TCAM_IP_ADDR_WORD_LEN - 1];
1012
1013 for (i = 0; i < FBNIC_RPC_TCAM_IP_ADDR_WORD_LEN; i++)
1014 wr32(fbd, FBNIC_RPC_TCAM_IPDST(idx, i),
1015 FIELD_PREP(FBNIC_RPC_TCAM_IP_ADDR_MASK, ntohs(*mask--)) |
1016 FIELD_PREP(FBNIC_RPC_TCAM_IP_ADDR_VALUE, ntohs(*value--)));
1017 wrfl(fbd);
1018
1019 /* Bit 129 is used to flag for v4/v6 */
1020 wr32(fbd, FBNIC_RPC_TCAM_IPDST(idx, i),
1021 (ip_addr->version == 6) | FBNIC_RPC_TCAM_VALIDATE);
1022 }
1023
fbnic_write_ip_outer_src_entry(struct fbnic_dev * fbd,unsigned int idx,struct fbnic_ip_addr * ip_addr)1024 static void fbnic_write_ip_outer_src_entry(struct fbnic_dev *fbd,
1025 unsigned int idx,
1026 struct fbnic_ip_addr *ip_addr)
1027 {
1028 __be16 *mask, *value;
1029 int i;
1030
1031 mask = &ip_addr->mask.s6_addr16[FBNIC_RPC_TCAM_IP_ADDR_WORD_LEN - 1];
1032 value = &ip_addr->value.s6_addr16[FBNIC_RPC_TCAM_IP_ADDR_WORD_LEN - 1];
1033
1034 for (i = 0; i < FBNIC_RPC_TCAM_IP_ADDR_WORD_LEN; i++)
1035 wr32(fbd, FBNIC_RPC_TCAM_OUTER_IPSRC(idx, i),
1036 FIELD_PREP(FBNIC_RPC_TCAM_IP_ADDR_MASK, ntohs(*mask--)) |
1037 FIELD_PREP(FBNIC_RPC_TCAM_IP_ADDR_VALUE, ntohs(*value--)));
1038 wrfl(fbd);
1039
1040 wr32(fbd, FBNIC_RPC_TCAM_OUTER_IPSRC(idx, i), FBNIC_RPC_TCAM_VALIDATE);
1041 }
1042
fbnic_write_ip_outer_dst_entry(struct fbnic_dev * fbd,unsigned int idx,struct fbnic_ip_addr * ip_addr)1043 static void fbnic_write_ip_outer_dst_entry(struct fbnic_dev *fbd,
1044 unsigned int idx,
1045 struct fbnic_ip_addr *ip_addr)
1046 {
1047 __be16 *mask, *value;
1048 int i;
1049
1050 mask = &ip_addr->mask.s6_addr16[FBNIC_RPC_TCAM_IP_ADDR_WORD_LEN - 1];
1051 value = &ip_addr->value.s6_addr16[FBNIC_RPC_TCAM_IP_ADDR_WORD_LEN - 1];
1052
1053 for (i = 0; i < FBNIC_RPC_TCAM_IP_ADDR_WORD_LEN; i++)
1054 wr32(fbd, FBNIC_RPC_TCAM_OUTER_IPDST(idx, i),
1055 FIELD_PREP(FBNIC_RPC_TCAM_IP_ADDR_MASK, ntohs(*mask--)) |
1056 FIELD_PREP(FBNIC_RPC_TCAM_IP_ADDR_VALUE, ntohs(*value--)));
1057 wrfl(fbd);
1058
1059 wr32(fbd, FBNIC_RPC_TCAM_OUTER_IPDST(idx, i), FBNIC_RPC_TCAM_VALIDATE);
1060 }
1061
fbnic_write_ip_addr(struct fbnic_dev * fbd)1062 void fbnic_write_ip_addr(struct fbnic_dev *fbd)
1063 {
1064 int idx;
1065
1066 for (idx = ARRAY_SIZE(fbd->ip_src); idx--;) {
1067 struct fbnic_ip_addr *ip_addr = &fbd->ip_src[idx];
1068
1069 /* Check if update flag is set else skip. */
1070 if (!(ip_addr->state & FBNIC_TCAM_S_UPDATE))
1071 continue;
1072
1073 /* Clear by writing 0s. */
1074 if (ip_addr->state == FBNIC_TCAM_S_DELETE) {
1075 /* Invalidate entry and clear addr state info */
1076 fbnic_clear_ip_src_entry(fbd, idx);
1077 memset(ip_addr, 0, sizeof(*ip_addr));
1078
1079 continue;
1080 }
1081
1082 fbnic_write_ip_src_entry(fbd, idx, ip_addr);
1083
1084 ip_addr->state = FBNIC_TCAM_S_VALID;
1085 }
1086
1087 /* Repeat process for other IP TCAMs */
1088 for (idx = ARRAY_SIZE(fbd->ip_dst); idx--;) {
1089 struct fbnic_ip_addr *ip_addr = &fbd->ip_dst[idx];
1090
1091 if (!(ip_addr->state & FBNIC_TCAM_S_UPDATE))
1092 continue;
1093
1094 if (ip_addr->state == FBNIC_TCAM_S_DELETE) {
1095 fbnic_clear_ip_dst_entry(fbd, idx);
1096 memset(ip_addr, 0, sizeof(*ip_addr));
1097
1098 continue;
1099 }
1100
1101 fbnic_write_ip_dst_entry(fbd, idx, ip_addr);
1102
1103 ip_addr->state = FBNIC_TCAM_S_VALID;
1104 }
1105
1106 for (idx = ARRAY_SIZE(fbd->ipo_src); idx--;) {
1107 struct fbnic_ip_addr *ip_addr = &fbd->ipo_src[idx];
1108
1109 if (!(ip_addr->state & FBNIC_TCAM_S_UPDATE))
1110 continue;
1111
1112 if (ip_addr->state == FBNIC_TCAM_S_DELETE) {
1113 fbnic_clear_ip_outer_src_entry(fbd, idx);
1114 memset(ip_addr, 0, sizeof(*ip_addr));
1115
1116 continue;
1117 }
1118
1119 fbnic_write_ip_outer_src_entry(fbd, idx, ip_addr);
1120
1121 ip_addr->state = FBNIC_TCAM_S_VALID;
1122 }
1123
1124 for (idx = ARRAY_SIZE(fbd->ipo_dst); idx--;) {
1125 struct fbnic_ip_addr *ip_addr = &fbd->ipo_dst[idx];
1126
1127 if (!(ip_addr->state & FBNIC_TCAM_S_UPDATE))
1128 continue;
1129
1130 if (ip_addr->state == FBNIC_TCAM_S_DELETE) {
1131 fbnic_clear_ip_outer_dst_entry(fbd, idx);
1132 memset(ip_addr, 0, sizeof(*ip_addr));
1133
1134 continue;
1135 }
1136
1137 fbnic_write_ip_outer_dst_entry(fbd, idx, ip_addr);
1138
1139 ip_addr->state = FBNIC_TCAM_S_VALID;
1140 }
1141 }
1142
fbnic_clear_valid_act_tcam(struct fbnic_dev * fbd)1143 static void fbnic_clear_valid_act_tcam(struct fbnic_dev *fbd)
1144 {
1145 int i = FBNIC_RPC_TCAM_ACT_NUM_ENTRIES - 1;
1146 struct fbnic_act_tcam *act_tcam;
1147
1148 /* Work from the bottom up deleting all other rules from hardware */
1149 do {
1150 act_tcam = &fbd->act_tcam[i];
1151
1152 if (act_tcam->state != FBNIC_TCAM_S_VALID)
1153 continue;
1154
1155 fbnic_clear_act_tcam(fbd, i);
1156 act_tcam->state = FBNIC_TCAM_S_UPDATE;
1157 } while (i--);
1158 }
1159
fbnic_clear_rules(struct fbnic_dev * fbd)1160 void fbnic_clear_rules(struct fbnic_dev *fbd)
1161 {
1162 /* Clear MAC rules */
1163 fbnic_clear_macda(fbd);
1164
1165 /* If BMC is present we need to preserve the last rule which
1166 * will be used to route traffic to the BMC if it is received.
1167 *
1168 * At this point it should be the only MAC address in the MACDA
1169 * so any unicast or multicast traffic received should be routed
1170 * to it. So leave the last rule in place.
1171 *
1172 * It will be rewritten to add the host again when we bring
1173 * the interface back up.
1174 */
1175 if (fbnic_bmc_present(fbd)) {
1176 u32 dest = FIELD_PREP(FBNIC_RPC_ACT_TBL0_DEST_MASK,
1177 FBNIC_RPC_ACT_TBL0_DEST_BMC);
1178 int i = FBNIC_RPC_TCAM_ACT_NUM_ENTRIES - 1;
1179 struct fbnic_act_tcam *act_tcam;
1180
1181 act_tcam = &fbd->act_tcam[i];
1182
1183 if (act_tcam->state == FBNIC_TCAM_S_VALID &&
1184 (act_tcam->dest & dest)) {
1185 wr32(fbd, FBNIC_RPC_ACT_TBL0(i), dest);
1186 wr32(fbd, FBNIC_RPC_ACT_TBL1(i), 0);
1187
1188 act_tcam->state = FBNIC_TCAM_S_UPDATE;
1189 }
1190 }
1191
1192 fbnic_clear_valid_act_tcam(fbd);
1193 }
1194
fbnic_delete_act_tcam(struct fbnic_dev * fbd,unsigned int idx)1195 static void fbnic_delete_act_tcam(struct fbnic_dev *fbd, unsigned int idx)
1196 {
1197 fbnic_clear_act_tcam(fbd, idx);
1198 memset(&fbd->act_tcam[idx], 0, sizeof(struct fbnic_act_tcam));
1199 }
1200
fbnic_update_act_tcam(struct fbnic_dev * fbd,unsigned int idx)1201 static void fbnic_update_act_tcam(struct fbnic_dev *fbd, unsigned int idx)
1202 {
1203 struct fbnic_act_tcam *act_tcam = &fbd->act_tcam[idx];
1204 int i;
1205
1206 /* Update entry by writing the destination and RSS mask */
1207 wr32(fbd, FBNIC_RPC_ACT_TBL0(idx), act_tcam->dest);
1208 wr32(fbd, FBNIC_RPC_ACT_TBL1(idx), act_tcam->rss_en_mask);
1209
1210 /* Write new TCAM rule to hardware */
1211 for (i = 0; i < FBNIC_RPC_TCAM_ACT_WORD_LEN; i++)
1212 wr32(fbd, FBNIC_RPC_TCAM_ACT(idx, i),
1213 FIELD_PREP(FBNIC_RPC_TCAM_ACT_MASK,
1214 act_tcam->mask.tcam[i]) |
1215 FIELD_PREP(FBNIC_RPC_TCAM_ACT_VALUE,
1216 act_tcam->value.tcam[i]));
1217
1218 wrfl(fbd);
1219
1220 wr32(fbd, FBNIC_RPC_TCAM_ACT(idx, i), FBNIC_RPC_TCAM_VALIDATE);
1221 act_tcam->state = FBNIC_TCAM_S_VALID;
1222 }
1223
fbnic_write_rules(struct fbnic_dev * fbd)1224 void fbnic_write_rules(struct fbnic_dev *fbd)
1225 {
1226 int i;
1227
1228 /* Flush any pending action table rules */
1229 for (i = 0; i < FBNIC_RPC_ACT_TBL_NUM_ENTRIES; i++) {
1230 struct fbnic_act_tcam *act_tcam = &fbd->act_tcam[i];
1231
1232 /* Check if update flag is set else exit. */
1233 if (!(act_tcam->state & FBNIC_TCAM_S_UPDATE))
1234 continue;
1235
1236 if (act_tcam->state == FBNIC_TCAM_S_DELETE)
1237 fbnic_delete_act_tcam(fbd, i);
1238 else
1239 fbnic_update_act_tcam(fbd, i);
1240 }
1241 }
1242
fbnic_rpc_reset_valid_entries(struct fbnic_dev * fbd)1243 void fbnic_rpc_reset_valid_entries(struct fbnic_dev *fbd)
1244 {
1245 fbnic_clear_valid_act_tcam(fbd);
1246 fbnic_clear_valid_macda(fbd);
1247 }
1248