Commit 26b12249 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull networking fixes from Paolo Abeni:
 "Including fixes from rxrpc, netfilter, wireless and bluetooth
  subtrees.

  Current release - regressions:

   - skb: export skb drop reaons to user by TRACE_DEFINE_ENUM

   - bluetooth: fix regression preventing ACL packet transmission

  Current release - new code bugs:

   - dsa: microchip: fix kernel oops on ksz8 switches

   - dsa: qca8k: fix NULL pointer dereference for
     of_device_get_match_data

  Previous releases - regressions:

   - netfilter: clean up hook list when offload flags check fails

   - wifi: mt76: fix crash in chip reset fail

   - rxrpc: fix ICMP/ICMP6 error handling

   - ice: fix DMA mappings leak

   - i40e: fix kernel crash during module removal

  Previous releases - always broken:

   - ipv6: sr: fix out-of-bounds read when setting HMAC data.

   - tcp: TX zerocopy should not sense pfmemalloc status

   - sch_sfb: don't assume the skb is still around after
     enqueueing to child

   - netfilter: drop dst references before setting

   - wifi: wilc1000: fix DMA on stack objects

   - rxrpc: fix an insufficiently large sglist in
     rxkad_verify_packet_2()

   - fec: use a spinlock to guard `fep->ptp_clk_on`

  Misc:

   - usb: qmi_wwan: add Quectel RM520N"

* tag 'net-6.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (50 commits)
  sch_sfb: Also store skb len before calling child enqueue
  net: phy: lan87xx: change interrupt src of link_up to comm_ready
  net/smc: Fix possible access to freed memory in link clear
  net: ethernet: mtk_eth_soc: check max allowed hash in mtk_ppe_check_skb
  net: skb: export skb drop reaons to user by TRACE_DEFINE_ENUM
  net: ethernet: mtk_eth_soc: fix typo in __mtk_foe_entry_clear
  net: dsa: felix: access QSYS_TAG_CONFIG under tas_lock in vsc9959_sched_speed_set
  net: dsa: felix: disable cut-through forwarding for frames oversized for tc-taprio
  net: dsa: felix: tc-taprio intervals smaller than MTU should send at least one packet
  net: usb: qmi_wwan: add Quectel RM520N
  net: dsa: qca8k: fix NULL pointer dereference for of_device_get_match_data
  tcp: fix early ETIMEDOUT after spurious non-SACK RTO
  stmmac: intel: Simplify intel_eth_pci_remove()
  net: mvpp2: debugfs: fix memory leak when using debugfs_lookup()
  ipv6: sr: fix out-of-bounds read when setting HMAC data.
  bonding: accept unsolicited NA message
  bonding: add all node mcast address when slave up
  bonding: use unspecified address if no available link local address
  wifi: use struct_group to copy addresses
  wifi: mac80211_hwsim: check length for virtio packets
  ...
parents 2f79cdfe 2f09707d
Loading
Loading
Loading
Loading
+0 −11
Original line number Diff line number Diff line
@@ -1055,17 +1055,6 @@ The kernel interface functions are as follows:
     first function to change.  Note that this must be called in TASK_RUNNING
     state.

 (#) Get reply timestamp::

	bool rxrpc_kernel_get_reply_time(struct socket *sock,
					 struct rxrpc_call *call,
					 ktime_t *_ts)

     This allows the timestamp on the first DATA packet of the reply of a
     client call to be queried, provided that it is still in the Rx ring.  If
     successful, the timestamp will be stored into ``*_ts`` and true will be
     returned; false will be returned otherwise.

 (#) Get remote client epoch::

	u32 rxrpc_kernel_get_epoch(struct socket *sock,
+15 −5
Original line number Diff line number Diff line
@@ -3167,6 +3167,9 @@ static void bond_ns_send_all(struct bonding *bond, struct slave *slave)
found:
		if (!ipv6_dev_get_saddr(dev_net(dst->dev), dst->dev, &targets[i], 0, &saddr))
			bond_ns_send(slave, &targets[i], &saddr, tags);
		else
			bond_ns_send(slave, &targets[i], &in6addr_any, tags);

		dst_release(dst);
		kfree(tags);
	}
@@ -3198,12 +3201,19 @@ static bool bond_has_this_ip6(struct bonding *bond, struct in6_addr *addr)
	return ret;
}

static void bond_validate_ns(struct bonding *bond, struct slave *slave,
static void bond_validate_na(struct bonding *bond, struct slave *slave,
			     struct in6_addr *saddr, struct in6_addr *daddr)
{
	int i;

	if (ipv6_addr_any(saddr) || !bond_has_this_ip6(bond, daddr)) {
	/* Ignore NAs that:
	 * 1. Source address is unspecified address.
	 * 2. Dest address is neither all-nodes multicast address nor
	 *    exist on bond interface.
	 */
	if (ipv6_addr_any(saddr) ||
	    (!ipv6_addr_equal(daddr, &in6addr_linklocal_allnodes) &&
	     !bond_has_this_ip6(bond, daddr))) {
		slave_dbg(bond->dev, slave->dev, "%s: sip %pI6c tip %pI6c not found\n",
			  __func__, saddr, daddr);
		return;
@@ -3246,14 +3256,14 @@ static int bond_na_rcv(const struct sk_buff *skb, struct bonding *bond,
	 * see bond_arp_rcv().
	 */
	if (bond_is_active_slave(slave))
		bond_validate_ns(bond, slave, saddr, daddr);
		bond_validate_na(bond, slave, saddr, daddr);
	else if (curr_active_slave &&
		 time_after(slave_last_rx(bond, curr_active_slave),
			    curr_active_slave->last_link_up))
		bond_validate_ns(bond, slave, saddr, daddr);
		bond_validate_na(bond, slave, saddr, daddr);
	else if (curr_arp_slave &&
		 bond_time_in_interval(bond, slave_last_tx(curr_arp_slave), 1))
		bond_validate_ns(bond, slave, saddr, daddr);
		bond_validate_na(bond, slave, saddr, daddr);

out:
	return RX_HANDLER_ANOTHER;
+24 −6
Original line number Diff line number Diff line
@@ -170,6 +170,13 @@ static const struct ksz_dev_ops ksz8_dev_ops = {
	.exit = ksz8_switch_exit,
};

static void ksz9477_phylink_mac_link_up(struct ksz_device *dev, int port,
					unsigned int mode,
					phy_interface_t interface,
					struct phy_device *phydev, int speed,
					int duplex, bool tx_pause,
					bool rx_pause);

static const struct ksz_dev_ops ksz9477_dev_ops = {
	.setup = ksz9477_setup,
	.get_port_addr = ksz9477_get_port_addr,
@@ -196,6 +203,7 @@ static const struct ksz_dev_ops ksz9477_dev_ops = {
	.mdb_del = ksz9477_mdb_del,
	.change_mtu = ksz9477_change_mtu,
	.max_mtu = ksz9477_max_mtu,
	.phylink_mac_link_up = ksz9477_phylink_mac_link_up,
	.config_cpu_port = ksz9477_config_cpu_port,
	.enable_stp_addr = ksz9477_enable_stp_addr,
	.reset = ksz9477_reset_switch,
@@ -230,6 +238,7 @@ static const struct ksz_dev_ops lan937x_dev_ops = {
	.mdb_del = ksz9477_mdb_del,
	.change_mtu = lan937x_change_mtu,
	.max_mtu = ksz9477_max_mtu,
	.phylink_mac_link_up = ksz9477_phylink_mac_link_up,
	.config_cpu_port = lan937x_config_cpu_port,
	.enable_stp_addr = ksz9477_enable_stp_addr,
	.reset = lan937x_reset_switch,
@@ -1656,13 +1665,13 @@ static void ksz_duplex_flowctrl(struct ksz_device *dev, int port, int duplex,
	ksz_prmw8(dev, port, regs[P_XMII_CTRL_0], mask, val);
}

static void ksz_phylink_mac_link_up(struct dsa_switch *ds, int port,
static void ksz9477_phylink_mac_link_up(struct ksz_device *dev, int port,
					unsigned int mode,
					phy_interface_t interface,
					struct phy_device *phydev, int speed,
				    int duplex, bool tx_pause, bool rx_pause)
					int duplex, bool tx_pause,
					bool rx_pause)
{
	struct ksz_device *dev = ds->priv;
	struct ksz_port *p;

	p = &dev->ports[port];
@@ -1676,6 +1685,15 @@ static void ksz_phylink_mac_link_up(struct dsa_switch *ds, int port,
	ksz_port_set_xmii_speed(dev, port, speed);

	ksz_duplex_flowctrl(dev, port, duplex, tx_pause, rx_pause);
}

static void ksz_phylink_mac_link_up(struct dsa_switch *ds, int port,
				    unsigned int mode,
				    phy_interface_t interface,
				    struct phy_device *phydev, int speed,
				    int duplex, bool tx_pause, bool rx_pause)
{
	struct ksz_device *dev = ds->priv;

	if (dev->dev_ops->phylink_mac_link_up)
		dev->dev_ops->phylink_mac_link_up(dev, port, mode, interface,
+112 −49
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#define VSC9959_NUM_PORTS		6

#define VSC9959_TAS_GCL_ENTRY_MAX	63
#define VSC9959_TAS_MIN_GATE_LEN_NS	33
#define VSC9959_VCAP_POLICER_BASE	63
#define VSC9959_VCAP_POLICER_MAX	383
#define VSC9959_SWITCH_PCI_BAR		4
@@ -1478,6 +1479,23 @@ static void vsc9959_mdio_bus_free(struct ocelot *ocelot)
	mdiobus_free(felix->imdio);
}

/* The switch considers any frame (regardless of size) as eligible for
 * transmission if the traffic class gate is open for at least 33 ns.
 * Overruns are prevented by cropping an interval at the end of the gate time
 * slot for which egress scheduling is blocked, but we need to still keep 33 ns
 * available for one packet to be transmitted, otherwise the port tc will hang.
 * This function returns the size of a gate interval that remains available for
 * setting the guard band, after reserving the space for one egress frame.
 */
static u64 vsc9959_tas_remaining_gate_len_ps(u64 gate_len_ns)
{
	/* Gate always open */
	if (gate_len_ns == U64_MAX)
		return U64_MAX;

	return (gate_len_ns - VSC9959_TAS_MIN_GATE_LEN_NS) * PSEC_PER_NSEC;
}

/* Extract shortest continuous gate open intervals in ns for each traffic class
 * of a cyclic tc-taprio schedule. If a gate is always open, the duration is
 * considered U64_MAX. If the gate is always closed, it is considered 0.
@@ -1539,6 +1557,65 @@ static void vsc9959_tas_min_gate_lengths(struct tc_taprio_qopt_offload *taprio,
			min_gate_len[tc] = 0;
}

/* ocelot_write_rix is a macro that concatenates QSYS_MAXSDU_CFG_* with _RSZ,
 * so we need to spell out the register access to each traffic class in helper
 * functions, to simplify callers
 */
static void vsc9959_port_qmaxsdu_set(struct ocelot *ocelot, int port, int tc,
				     u32 max_sdu)
{
	switch (tc) {
	case 0:
		ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_0,
				 port);
		break;
	case 1:
		ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_1,
				 port);
		break;
	case 2:
		ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_2,
				 port);
		break;
	case 3:
		ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_3,
				 port);
		break;
	case 4:
		ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_4,
				 port);
		break;
	case 5:
		ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_5,
				 port);
		break;
	case 6:
		ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_6,
				 port);
		break;
	case 7:
		ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_7,
				 port);
		break;
	}
}

static u32 vsc9959_port_qmaxsdu_get(struct ocelot *ocelot, int port, int tc)
{
	switch (tc) {
	case 0: return ocelot_read_rix(ocelot, QSYS_QMAXSDU_CFG_0, port);
	case 1: return ocelot_read_rix(ocelot, QSYS_QMAXSDU_CFG_1, port);
	case 2: return ocelot_read_rix(ocelot, QSYS_QMAXSDU_CFG_2, port);
	case 3: return ocelot_read_rix(ocelot, QSYS_QMAXSDU_CFG_3, port);
	case 4: return ocelot_read_rix(ocelot, QSYS_QMAXSDU_CFG_4, port);
	case 5: return ocelot_read_rix(ocelot, QSYS_QMAXSDU_CFG_5, port);
	case 6: return ocelot_read_rix(ocelot, QSYS_QMAXSDU_CFG_6, port);
	case 7: return ocelot_read_rix(ocelot, QSYS_QMAXSDU_CFG_7, port);
	default:
		return 0;
	}
}

/* Update QSYS_PORT_MAX_SDU to make sure the static guard bands added by the
 * switch (see the ALWAYS_GUARD_BAND_SCH_Q comment) are correct at all MTU
 * values (the default value is 1518). Also, for traffic class windows smaller
@@ -1595,11 +1672,16 @@ static void vsc9959_tas_guard_bands_update(struct ocelot *ocelot, int port)

	vsc9959_tas_min_gate_lengths(ocelot_port->taprio, min_gate_len);

	mutex_lock(&ocelot->fwd_domain_lock);

	for (tc = 0; tc < OCELOT_NUM_TC; tc++) {
		u64 remaining_gate_len_ps;
		u32 max_sdu;

		if (min_gate_len[tc] == U64_MAX /* Gate always open */ ||
		    min_gate_len[tc] * PSEC_PER_NSEC > needed_bit_time_ps) {
		remaining_gate_len_ps =
			vsc9959_tas_remaining_gate_len_ps(min_gate_len[tc]);

		if (remaining_gate_len_ps > needed_bit_time_ps) {
			/* Setting QMAXSDU_CFG to 0 disables oversized frame
			 * dropping.
			 */
@@ -1612,9 +1694,15 @@ static void vsc9959_tas_guard_bands_update(struct ocelot *ocelot, int port)
			/* If traffic class doesn't support a full MTU sized
			 * frame, make sure to enable oversize frame dropping
			 * for frames larger than the smallest that would fit.
			 *
			 * However, the exact same register, QSYS_QMAXSDU_CFG_*,
			 * controls not only oversized frame dropping, but also
			 * per-tc static guard band lengths, so it reduces the
			 * useful gate interval length. Therefore, be careful
			 * to calculate a guard band (and therefore max_sdu)
			 * that still leaves 33 ns available in the time slot.
			 */
			max_sdu = div_u64(min_gate_len[tc] * PSEC_PER_NSEC,
					  picos_per_byte);
			max_sdu = div_u64(remaining_gate_len_ps, picos_per_byte);
			/* A TC gate may be completely closed, which is a
			 * special case where all packets are oversized.
			 * Any limit smaller than 64 octets accomplishes this
@@ -1637,47 +1725,14 @@ static void vsc9959_tas_guard_bands_update(struct ocelot *ocelot, int port)
				 max_sdu);
		}

		/* ocelot_write_rix is a macro that concatenates
		 * QSYS_MAXSDU_CFG_* with _RSZ, so we need to spell out
		 * the writes to each traffic class
		 */
		switch (tc) {
		case 0:
			ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_0,
					 port);
			break;
		case 1:
			ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_1,
					 port);
			break;
		case 2:
			ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_2,
					 port);
			break;
		case 3:
			ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_3,
					 port);
			break;
		case 4:
			ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_4,
					 port);
			break;
		case 5:
			ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_5,
					 port);
			break;
		case 6:
			ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_6,
					 port);
			break;
		case 7:
			ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_7,
					 port);
			break;
		}
		vsc9959_port_qmaxsdu_set(ocelot, port, tc, max_sdu);
	}

	ocelot_write_rix(ocelot, maxlen, QSYS_PORT_MAX_SDU, port);

	ocelot->ops->cut_through_fwd(ocelot);

	mutex_unlock(&ocelot->fwd_domain_lock);
}

static void vsc9959_sched_speed_set(struct ocelot *ocelot, int port,
@@ -1704,13 +1759,13 @@ static void vsc9959_sched_speed_set(struct ocelot *ocelot, int port,
		break;
	}

	mutex_lock(&ocelot->tas_lock);

	ocelot_rmw_rix(ocelot,
		       QSYS_TAG_CONFIG_LINK_SPEED(tas_speed),
		       QSYS_TAG_CONFIG_LINK_SPEED_M,
		       QSYS_TAG_CONFIG, port);

	mutex_lock(&ocelot->tas_lock);

	if (ocelot_port->taprio)
		vsc9959_tas_guard_bands_update(ocelot, port);

@@ -2770,7 +2825,7 @@ static void vsc9959_cut_through_fwd(struct ocelot *ocelot)
{
	struct felix *felix = ocelot_to_felix(ocelot);
	struct dsa_switch *ds = felix->ds;
	int port, other_port;
	int tc, port, other_port;

	lockdep_assert_held(&ocelot->fwd_domain_lock);

@@ -2814,19 +2869,27 @@ static void vsc9959_cut_through_fwd(struct ocelot *ocelot)
				min_speed = other_ocelot_port->speed;
		}

		/* Enable cut-through forwarding for all traffic classes. */
		if (ocelot_port->speed == min_speed)
		/* Enable cut-through forwarding for all traffic classes that
		 * don't have oversized dropping enabled, since this check is
		 * bypassed in cut-through mode.
		 */
		if (ocelot_port->speed == min_speed) {
			val = GENMASK(7, 0);

			for (tc = 0; tc < OCELOT_NUM_TC; tc++)
				if (vsc9959_port_qmaxsdu_get(ocelot, port, tc))
					val &= ~BIT(tc);
		}

set:
		tmp = ocelot_read_rix(ocelot, ANA_CUT_THRU_CFG, port);
		if (tmp == val)
			continue;

		dev_dbg(ocelot->dev,
			"port %d fwd mask 0x%lx speed %d min_speed %d, %s cut-through forwarding\n",
			"port %d fwd mask 0x%lx speed %d min_speed %d, %s cut-through forwarding on TC mask 0x%x\n",
			port, mask, ocelot_port->speed, min_speed,
			val ? "enabling" : "disabling");
			val ? "enabling" : "disabling", val);

		ocelot_write_rix(ocelot, val, ANA_CUT_THRU_CFG, port);
	}
+1 −1
Original line number Diff line number Diff line
@@ -1889,9 +1889,9 @@ qca8k_sw_probe(struct mdio_device *mdiodev)
	if (!priv)
		return -ENOMEM;

	priv->info = of_device_get_match_data(priv->dev);
	priv->bus = mdiodev->bus;
	priv->dev = &mdiodev->dev;
	priv->info = of_device_get_match_data(priv->dev);

	priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset",
						   GPIOD_ASIS);
Loading