File Index
Files and directories
Sign in
FILE

fbnic_rpc.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c 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.