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