Commit d7a550d6 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'sja1105-driver-fixes'

Vladimir Oltean says:

====================
sja1105 driver fixes

This is a collection of 3 fixes for the sja1105 DSA driver:
- 1/3: "ethtool -S" shows a bogus counter with no name, and doesn't show
  a valid counter because of it (either "n_not_reach" or "n_rx_bcast").
- 2/3: RX timestamping filters other than L2 PTP event messages don't work,
  but are not rejected, either.
- 3/3: there is a KASAN out-of-bounds warning in sja1105_table_delete_entry()
====================

Link: https://patch.msgid.link/20250318115716.2124395-1-vladimir.oltean@nxp.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 4af9939a 5f2b28b7
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -571,6 +571,9 @@ void sja1105_get_ethtool_stats(struct dsa_switch *ds, int port, u64 *data)
		max_ctr = __MAX_SJA1105PQRS_PORT_COUNTER;

	for (i = 0; i < max_ctr; i++) {
		if (!strlen(sja1105_port_counters[i].name))
			continue;

		rc = sja1105_port_counter_read(priv, port, i, &data[k++]);
		if (rc) {
			dev_err(ds->dev,
@@ -596,9 +599,13 @@ void sja1105_get_strings(struct dsa_switch *ds, int port,
	else
		max_ctr = __MAX_SJA1105PQRS_PORT_COUNTER;

	for (i = 0; i < max_ctr; i++)
	for (i = 0; i < max_ctr; i++) {
		if (!strlen(sja1105_port_counters[i].name))
			continue;

		ethtool_puts(&data, sja1105_port_counters[i].name);
	}
}

int sja1105_get_sset_count(struct dsa_switch *ds, int port, int sset)
{
+15 −5
Original line number Diff line number Diff line
@@ -61,17 +61,21 @@ enum sja1105_ptp_clk_mode {
int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr)
{
	struct sja1105_private *priv = ds->priv;
	unsigned long hwts_tx_en, hwts_rx_en;
	struct hwtstamp_config config;

	if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
		return -EFAULT;

	hwts_tx_en = priv->hwts_tx_en;
	hwts_rx_en = priv->hwts_rx_en;

	switch (config.tx_type) {
	case HWTSTAMP_TX_OFF:
		priv->hwts_tx_en &= ~BIT(port);
		hwts_tx_en &= ~BIT(port);
		break;
	case HWTSTAMP_TX_ON:
		priv->hwts_tx_en |= BIT(port);
		hwts_tx_en |= BIT(port);
		break;
	default:
		return -ERANGE;
@@ -79,15 +83,21 @@ int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr)

	switch (config.rx_filter) {
	case HWTSTAMP_FILTER_NONE:
		priv->hwts_rx_en &= ~BIT(port);
		hwts_rx_en &= ~BIT(port);
		break;
	default:
		priv->hwts_rx_en |= BIT(port);
	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
		hwts_rx_en |= BIT(port);
		break;
	default:
		return -ERANGE;
	}

	if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
		return -EFAULT;

	priv->hwts_tx_en = hwts_tx_en;
	priv->hwts_rx_en = hwts_rx_en;

	return 0;
}

+4 −2
Original line number Diff line number Diff line
@@ -1917,8 +1917,10 @@ int sja1105_table_delete_entry(struct sja1105_table *table, int i)
	if (i > table->entry_count)
		return -ERANGE;

	if (i + 1 < table->entry_count) {
		memmove(entries + i * entry_size, entries + (i + 1) * entry_size,
		(table->entry_count - i) * entry_size);
			(table->entry_count - i - 1) * entry_size);
	}

	table->entry_count--;