Commit 7e6cadf5 authored by David S. Miller's avatar David S. Miller
Browse files
Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2023-09-11 (i40e, iavf)

This series contains updates to i40e and iavf drivers.

Andrii ensures all VSIs are cleaned up for remove in i40e.

Brett reworks logic for setting promiscuous mode that can, currently, cause
incorrect states on iavf.
---
v2:
 - Remove redundant i40e_vsi_free_q_vectors() and kfree() calls (patch 1)

v1: https://lore.kernel.org/netdev/20230905180521.887861-1-anthony.l.nguyen@intel.com/


====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 8fc8911b 221465de
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -266,6 +266,8 @@ struct sja1105_private {
	 * the switch doesn't confuse them with one another.
	 */
	struct mutex mgmt_lock;
	/* Serializes accesses to the FDB */
	struct mutex fdb_lock;
	/* PTP two-step TX timestamp ID, and its serialization lock */
	spinlock_t ts_id_lock;
	u8 ts_id;
+44 −49
Original line number Diff line number Diff line
@@ -1175,18 +1175,15 @@ const struct sja1105_dynamic_table_ops sja1110_dyn_ops[BLK_IDX_MAX_DYN] = {

static int
sja1105_dynamic_config_poll_valid(struct sja1105_private *priv,
				  struct sja1105_dyn_cmd *cmd,
				  const struct sja1105_dynamic_table_ops *ops)
				  const struct sja1105_dynamic_table_ops *ops,
				  void *entry, bool check_valident,
				  bool check_errors)
{
	u8 packed_buf[SJA1105_MAX_DYN_CMD_SIZE] = {};
	struct sja1105_dyn_cmd cmd = {};
	int rc;

	/* We don't _need_ to read the full entry, just the command area which
	 * is a fixed SJA1105_SIZE_DYN_CMD. But our cmd_packing() API expects a
	 * buffer that contains the full entry too. Additionally, our API
	 * doesn't really know how many bytes into the buffer does the command
	 * area really begin. So just read back the whole entry.
	 */
	/* Read back the whole entry + command structure. */
	rc = sja1105_xfer_buf(priv, SPI_READ, ops->addr, packed_buf,
			      ops->packed_size);
	if (rc)
@@ -1195,11 +1192,25 @@ sja1105_dynamic_config_poll_valid(struct sja1105_private *priv,
	/* Unpack the command structure, and return it to the caller in case it
	 * needs to perform further checks on it (VALIDENT).
	 */
	memset(cmd, 0, sizeof(*cmd));
	ops->cmd_packing(packed_buf, cmd, UNPACK);
	ops->cmd_packing(packed_buf, &cmd, UNPACK);

	/* Hardware hasn't cleared VALID => still working on it */
	return cmd->valid ? -EAGAIN : 0;
	if (cmd.valid)
		return -EAGAIN;

	if (check_valident && !cmd.valident && !(ops->access & OP_VALID_ANYWAY))
		return -ENOENT;

	if (check_errors && cmd.errors)
		return -EINVAL;

	/* Don't dereference possibly NULL pointer - maybe caller
	 * only wanted to see whether the entry existed or not.
	 */
	if (entry)
		ops->entry_packing(packed_buf, entry, UNPACK);

	return 0;
}

/* Poll the dynamic config entry's control area until the hardware has
@@ -1208,16 +1219,19 @@ sja1105_dynamic_config_poll_valid(struct sja1105_private *priv,
 */
static int
sja1105_dynamic_config_wait_complete(struct sja1105_private *priv,
				     struct sja1105_dyn_cmd *cmd,
				     const struct sja1105_dynamic_table_ops *ops)
				     const struct sja1105_dynamic_table_ops *ops,
				     void *entry, bool check_valident,
				     bool check_errors)
{
	int rc;
	int err, rc;

	return read_poll_timeout(sja1105_dynamic_config_poll_valid,
	err = read_poll_timeout(sja1105_dynamic_config_poll_valid,
				rc, rc != -EAGAIN,
				SJA1105_DYNAMIC_CONFIG_SLEEP_US,
				SJA1105_DYNAMIC_CONFIG_TIMEOUT_US,
				 false, priv, cmd, ops);
				false, priv, ops, entry, check_valident,
				check_errors);
	return err < 0 ? err : rc;
}

/* Provides read access to the settings through the dynamic interface
@@ -1286,25 +1300,14 @@ int sja1105_dynamic_config_read(struct sja1105_private *priv,
	mutex_lock(&priv->dynamic_config_lock);
	rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf,
			      ops->packed_size);
	if (rc < 0) {
		mutex_unlock(&priv->dynamic_config_lock);
		return rc;
	}

	rc = sja1105_dynamic_config_wait_complete(priv, &cmd, ops);
	mutex_unlock(&priv->dynamic_config_lock);
	if (rc < 0)
		return rc;
		goto out;

	if (!cmd.valident && !(ops->access & OP_VALID_ANYWAY))
		return -ENOENT;
	rc = sja1105_dynamic_config_wait_complete(priv, ops, entry, true, false);
out:
	mutex_unlock(&priv->dynamic_config_lock);

	/* Don't dereference possibly NULL pointer - maybe caller
	 * only wanted to see whether the entry existed or not.
	 */
	if (entry)
		ops->entry_packing(packed_buf, entry, UNPACK);
	return 0;
	return rc;
}

int sja1105_dynamic_config_write(struct sja1105_private *priv,
@@ -1356,22 +1359,14 @@ int sja1105_dynamic_config_write(struct sja1105_private *priv,
	mutex_lock(&priv->dynamic_config_lock);
	rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf,
			      ops->packed_size);
	if (rc < 0) {
		mutex_unlock(&priv->dynamic_config_lock);
		return rc;
	}

	rc = sja1105_dynamic_config_wait_complete(priv, &cmd, ops);
	mutex_unlock(&priv->dynamic_config_lock);
	if (rc < 0)
		return rc;
		goto out;

	cmd = (struct sja1105_dyn_cmd) {0};
	ops->cmd_packing(packed_buf, &cmd, UNPACK);
	if (cmd.errors)
		return -EINVAL;
	rc = sja1105_dynamic_config_wait_complete(priv, ops, NULL, false, true);
out:
	mutex_unlock(&priv->dynamic_config_lock);

	return 0;
	return rc;
}

static u8 sja1105_crc8_add(u8 crc, u8 byte, u8 poly)
+51 −18
Original line number Diff line number Diff line
@@ -1798,6 +1798,7 @@ static int sja1105_fdb_add(struct dsa_switch *ds, int port,
			   struct dsa_db db)
{
	struct sja1105_private *priv = ds->priv;
	int rc;

	if (!vid) {
		switch (db.type) {
@@ -1812,10 +1813,14 @@ static int sja1105_fdb_add(struct dsa_switch *ds, int port,
		}
	}

	return priv->info->fdb_add_cmd(ds, port, addr, vid);
	mutex_lock(&priv->fdb_lock);
	rc = priv->info->fdb_add_cmd(ds, port, addr, vid);
	mutex_unlock(&priv->fdb_lock);

	return rc;
}

static int sja1105_fdb_del(struct dsa_switch *ds, int port,
static int __sja1105_fdb_del(struct dsa_switch *ds, int port,
			     const unsigned char *addr, u16 vid,
			     struct dsa_db db)
{
@@ -1837,6 +1842,20 @@ static int sja1105_fdb_del(struct dsa_switch *ds, int port,
	return priv->info->fdb_del_cmd(ds, port, addr, vid);
}

static int sja1105_fdb_del(struct dsa_switch *ds, int port,
			   const unsigned char *addr, u16 vid,
			   struct dsa_db db)
{
	struct sja1105_private *priv = ds->priv;
	int rc;

	mutex_lock(&priv->fdb_lock);
	rc = __sja1105_fdb_del(ds, port, addr, vid, db);
	mutex_unlock(&priv->fdb_lock);

	return rc;
}

static int sja1105_fdb_dump(struct dsa_switch *ds, int port,
			    dsa_fdb_dump_cb_t *cb, void *data)
{
@@ -1868,13 +1887,14 @@ static int sja1105_fdb_dump(struct dsa_switch *ds, int port,
		if (!(l2_lookup.destports & BIT(port)))
			continue;

		/* We need to hide the FDB entry for unknown multicast */
		if (l2_lookup.macaddr == SJA1105_UNKNOWN_MULTICAST &&
		    l2_lookup.mask_macaddr == SJA1105_UNKNOWN_MULTICAST)
			continue;

		u64_to_ether_addr(l2_lookup.macaddr, macaddr);

		/* Hardware FDB is shared for fdb and mdb, "bridge fdb show"
		 * only wants to see unicast
		 */
		if (is_multicast_ether_addr(macaddr))
			continue;

		/* We need to hide the dsa_8021q VLANs from the user. */
		if (vid_is_dsa_8021q(l2_lookup.vlanid))
			l2_lookup.vlanid = 0;
@@ -1898,6 +1918,8 @@ static void sja1105_fast_age(struct dsa_switch *ds, int port)
	};
	int i;

	mutex_lock(&priv->fdb_lock);

	for (i = 0; i < SJA1105_MAX_L2_LOOKUP_COUNT; i++) {
		struct sja1105_l2_lookup_entry l2_lookup = {0};
		u8 macaddr[ETH_ALEN];
@@ -1911,7 +1933,7 @@ static void sja1105_fast_age(struct dsa_switch *ds, int port)
		if (rc) {
			dev_err(ds->dev, "Failed to read FDB: %pe\n",
				ERR_PTR(rc));
			return;
			break;
		}

		if (!(l2_lookup.destports & BIT(port)))
@@ -1923,14 +1945,16 @@ static void sja1105_fast_age(struct dsa_switch *ds, int port)

		u64_to_ether_addr(l2_lookup.macaddr, macaddr);

		rc = sja1105_fdb_del(ds, port, macaddr, l2_lookup.vlanid, db);
		rc = __sja1105_fdb_del(ds, port, macaddr, l2_lookup.vlanid, db);
		if (rc) {
			dev_err(ds->dev,
				"Failed to delete FDB entry %pM vid %lld: %pe\n",
				macaddr, l2_lookup.vlanid, ERR_PTR(rc));
			return;
			break;
		}
	}

	mutex_unlock(&priv->fdb_lock);
}

static int sja1105_mdb_add(struct dsa_switch *ds, int port,
@@ -2273,6 +2297,7 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
	int rc, i;
	s64 now;

	mutex_lock(&priv->fdb_lock);
	mutex_lock(&priv->mgmt_lock);

	mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
@@ -2385,6 +2410,7 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
		goto out;
out:
	mutex_unlock(&priv->mgmt_lock);
	mutex_unlock(&priv->fdb_lock);

	return rc;
}
@@ -2954,7 +2980,9 @@ static int sja1105_port_mcast_flood(struct sja1105_private *priv, int to,
{
	struct sja1105_l2_lookup_entry *l2_lookup;
	struct sja1105_table *table;
	int match;
	int match, rc;

	mutex_lock(&priv->fdb_lock);

	table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP];
	l2_lookup = table->entries;
@@ -2967,7 +2995,8 @@ static int sja1105_port_mcast_flood(struct sja1105_private *priv, int to,
	if (match == table->entry_count) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Could not find FDB entry for unknown multicast");
		return -ENOSPC;
		rc = -ENOSPC;
		goto out;
	}

	if (flags.val & BR_MCAST_FLOOD)
@@ -2975,10 +3004,13 @@ static int sja1105_port_mcast_flood(struct sja1105_private *priv, int to,
	else
		l2_lookup[match].destports &= ~BIT(to);

	return sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP,
	rc = sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP,
					  l2_lookup[match].index,
					    &l2_lookup[match],
					    true);
					  &l2_lookup[match], true);
out:
	mutex_unlock(&priv->fdb_lock);

	return rc;
}

static int sja1105_port_pre_bridge_flags(struct dsa_switch *ds, int port,
@@ -3348,6 +3380,7 @@ static int sja1105_probe(struct spi_device *spi)
	mutex_init(&priv->ptp_data.lock);
	mutex_init(&priv->dynamic_config_lock);
	mutex_init(&priv->mgmt_lock);
	mutex_init(&priv->fdb_lock);
	spin_lock_init(&priv->ts_id_lock);

	rc = sja1105_parse_dt(priv);
+1 −1
Original line number Diff line number Diff line
@@ -1385,7 +1385,7 @@ static int adin1110_fdb_add(struct adin1110_port_priv *port_priv,
		return -ENOMEM;

	other_port = priv->ports[!port_priv->nr];
	port_rules = adin1110_port_rules(port_priv, false, true);
	port_rules = adin1110_port_rules(other_port, false, true);
	eth_broadcast_addr(mask);

	return adin1110_write_mac_address(other_port, mac_nr, (u8 *)fdb->addr,
+8 −2
Original line number Diff line number Diff line
@@ -528,13 +528,16 @@ void bcmasp_netfilt_suspend(struct bcmasp_intf *intf)
				  ASP_RX_FILTER_BLK_CTRL);
}

void bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs,
int bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs,
				  u32 *rule_cnt)
{
	struct bcmasp_priv *priv = intf->parent;
	int j = 0, i;

	for (i = 0; i < NUM_NET_FILTERS; i++) {
		if (j == *rule_cnt)
			return -EMSGSIZE;

		if (!priv->net_filters[i].claimed ||
		    priv->net_filters[i].port != intf->port)
			continue;
@@ -548,6 +551,8 @@ void bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs,
	}

	*rule_cnt = j;

	return 0;
}

int bcmasp_netfilt_get_active(struct bcmasp_intf *intf)
@@ -1300,6 +1305,7 @@ static int bcmasp_probe(struct platform_device *pdev)
		if (!intf) {
			dev_err(dev, "Cannot create eth interface %d\n", i);
			bcmasp_remove_intfs(priv);
			of_node_put(intf_node);
			goto of_put_exit;
		}
		list_add_tail(&intf->list, &priv->intfs);
Loading