diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-09-22 10:58:13 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-09-22 10:58:13 -0700 | 
| commit | 504c25cb76a9cb805407f7701b25a1fbd48605fa (patch) | |
| tree | 0950b1f1ccd34ff02133bd0d73054bd98219faf4 /drivers/net/ethernet | |
| parent | 129e7152184b0224f9ca3f91b870acc14c64e1fa (diff) | |
| parent | 83e4b196838d90799a8879e5054a3beecf9ed256 (diff) | |
Merge tag 'net-6.0-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Jakub Kicinski:
 "Including fixes from wifi, netfilter and can.
  A handful of awaited fixes here - revert of the FEC changes, bluetooth
  fix, fixes for iwlwifi spew.
  We added a warning in PHY/MDIO code which is triggering on a couple of
  platforms in a false-positive-ish way. If we can't iron that out over
  the week we'll drop it and re-add for 6.1.
  I've added a new "follow up fixes" section for fixes to fixes in
  6.0-rcs but it may actually give the false impression that those are
  problematic or that more testing time would have caught them. So
  likely a one time thing.
  Follow up fixes:
   - nf_tables_addchain: fix nft_counters_enabled underflow
   - ebtables: fix memory leak when blob is malformed
   - nf_ct_ftp: fix deadlock when nat rewrite is needed
  Current release - regressions:
   - Revert "fec: Restart PPS after link state change" and the related
     "net: fec: Use a spinlock to guard `fep->ptp_clk_on`"
   - Bluetooth: fix HCIGETDEVINFO regression
   - wifi: mt76: fix 5 GHz connection regression on mt76x0/mt76x2
   - mptcp: fix fwd memory accounting on coalesce
   - rwlock removal fall out:
      - ipmr: always call ip{,6}_mr_forward() from RCU read-side
        critical section
      - ipv6: fix crash when IPv6 is administratively disabled
   - tcp: read multiple skbs in tcp_read_skb()
   - mdio_bus_phy_resume state warning fallout:
      - eth: ravb: fix PHY state warning splat during system resume
      - eth: sh_eth: fix PHY state warning splat during system resume
  Current release - new code bugs:
   - wifi: iwlwifi: don't spam logs with NSS>2 messages
   - eth: mtk_eth_soc: enable XDP support just for MT7986 SoC
  Previous releases - regressions:
   - bonding: fix NULL deref in bond_rr_gen_slave_id
   - wifi: iwlwifi: mark IWLMEI as broken
  Previous releases - always broken:
   - nf_conntrack helpers:
      - irc: tighten matching on DCC message
      - sip: fix ct_sip_walk_headers
      - osf: fix possible bogus match in nf_osf_find()
   - ipvlan: fix out-of-bound bugs caused by unset skb->mac_header
   - core: fix flow symmetric hash
   - bonding, team: unsync device addresses on ndo_stop
   - phy: micrel: fix shared interrupt on LAN8814"
* tag 'net-6.0-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (83 commits)
  selftests: forwarding: add shebang for sch_red.sh
  bnxt: prevent skb UAF after handing over to PTP worker
  net: marvell: Fix refcounting bugs in prestera_port_sfp_bind()
  net: sched: fix possible refcount leak in tc_new_tfilter()
  net: sunhme: Fix packet reception for len < RX_COPY_THRESHOLD
  udp: Use WARN_ON_ONCE() in udp_read_skb()
  selftests: bonding: cause oops in bond_rr_gen_slave_id
  bonding: fix NULL deref in bond_rr_gen_slave_id
  net: phy: micrel: fix shared interrupt on LAN8814
  net/smc: Stop the CLC flow if no link to map buffers on
  ice: Fix ice_xdp_xmit() when XDP TX queue number is not sufficient
  net: atlantic: fix potential memory leak in aq_ndev_close()
  can: gs_usb: gs_usb_set_phys_id(): return with error if identify is not supported
  can: gs_usb: gs_can_open(): fix race dev->can.state condition
  can: flexcan: flexcan_mailbox_read() fix return value for drop = true
  net: sh_eth: Fix PHY state warning splat during system resume
  net: ravb: Fix PHY state warning splat during system resume
  netfilter: nf_ct_ftp: fix deadlock when nat rewrite is needed
  netfilter: ebtables: fix memory leak when blob is malformed
  netfilter: nf_tables: fix percpu memory leak at nf_tables_addchain()
  ...
Diffstat (limited to 'drivers/net/ethernet')
33 files changed, 251 insertions, 219 deletions
| diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c b/drivers/net/ethernet/aquantia/atlantic/aq_main.c index 88595863d8bc..8a0af371e7dc 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c @@ -94,11 +94,8 @@ static int aq_ndev_close(struct net_device *ndev)  	int err = 0;  	err = aq_nic_stop(aq_nic); -	if (err < 0) -		goto err_exit;  	aq_nic_deinit(aq_nic, true); -err_exit:  	return err;  } diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index f46eefb5a029..96da0ba3d507 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -659,7 +659,6 @@ static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)  	for (i = 0; i < nr_pkts; i++) {  		struct bnxt_sw_tx_bd *tx_buf; -		bool compl_deferred = false;  		struct sk_buff *skb;  		int j, last; @@ -668,6 +667,8 @@ static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)  		skb = tx_buf->skb;  		tx_buf->skb = NULL; +		tx_bytes += skb->len; +  		if (tx_buf->is_push) {  			tx_buf->is_push = 0;  			goto next_tx_int; @@ -688,8 +689,9 @@ static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)  		}  		if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) {  			if (bp->flags & BNXT_FLAG_CHIP_P5) { +				/* PTP worker takes ownership of the skb */  				if (!bnxt_get_tx_ts_p5(bp, skb)) -					compl_deferred = true; +					skb = NULL;  				else  					atomic_inc(&bp->ptp_cfg->tx_avail);  			} @@ -698,9 +700,7 @@ static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)  next_tx_int:  		cons = NEXT_TX(cons); -		tx_bytes += skb->len; -		if (!compl_deferred) -			dev_kfree_skb_any(skb); +		dev_kfree_skb_any(skb);  	}  	netdev_tx_completed_queue(txq, nr_pkts, tx_bytes); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c index 7f3c0875b6f5..8e316367f6ce 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c @@ -317,9 +317,9 @@ void bnxt_ptp_cfg_tstamp_filters(struct bnxt *bp)  	if (!(bp->fw_cap & BNXT_FW_CAP_RX_ALL_PKT_TS) && (ptp->tstamp_filters &  	    (PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_ENABLE | -	     PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_DISABLE))) { +	     PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_DISABLE))) {  		ptp->tstamp_filters &= ~(PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_ENABLE | -					 PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_DISABLE); +					 PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_DISABLE);  		netdev_warn(bp->dev, "Unsupported FW for all RX pkts timestamp filter\n");  	} diff --git a/drivers/net/ethernet/freescale/enetc/Makefile b/drivers/net/ethernet/freescale/enetc/Makefile index a139f2e9d59f..e0e8dfd13793 100644 --- a/drivers/net/ethernet/freescale/enetc/Makefile +++ b/drivers/net/ethernet/freescale/enetc/Makefile @@ -9,7 +9,6 @@ fsl-enetc-$(CONFIG_FSL_ENETC_QOS) += enetc_qos.o  obj-$(CONFIG_FSL_ENETC_VF) += fsl-enetc-vf.o  fsl-enetc-vf-y := enetc_vf.o $(common-objs) -fsl-enetc-vf-$(CONFIG_FSL_ENETC_QOS) += enetc_qos.o  obj-$(CONFIG_FSL_ENETC_IERB) += fsl-enetc-ierb.o  fsl-enetc-ierb-y := enetc_ierb.o diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c index 4470a4a3e4c3..9f5b921039bd 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc.c +++ b/drivers/net/ethernet/freescale/enetc/enetc.c @@ -2432,7 +2432,7 @@ int enetc_close(struct net_device *ndev)  	return 0;  } -static int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data) +int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)  {  	struct enetc_ndev_priv *priv = netdev_priv(ndev);  	struct tc_mqprio_qopt *mqprio = type_data; @@ -2486,25 +2486,6 @@ static int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)  	return 0;  } -int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type, -		   void *type_data) -{ -	switch (type) { -	case TC_SETUP_QDISC_MQPRIO: -		return enetc_setup_tc_mqprio(ndev, type_data); -	case TC_SETUP_QDISC_TAPRIO: -		return enetc_setup_tc_taprio(ndev, type_data); -	case TC_SETUP_QDISC_CBS: -		return enetc_setup_tc_cbs(ndev, type_data); -	case TC_SETUP_QDISC_ETF: -		return enetc_setup_tc_txtime(ndev, type_data); -	case TC_SETUP_BLOCK: -		return enetc_setup_tc_psfp(ndev, type_data); -	default: -		return -EOPNOTSUPP; -	} -} -  static int enetc_setup_xdp_prog(struct net_device *dev, struct bpf_prog *prog,  				struct netlink_ext_ack *extack)  { @@ -2600,29 +2581,6 @@ static int enetc_set_rss(struct net_device *ndev, int en)  	return 0;  } -static int enetc_set_psfp(struct net_device *ndev, int en) -{ -	struct enetc_ndev_priv *priv = netdev_priv(ndev); -	int err; - -	if (en) { -		err = enetc_psfp_enable(priv); -		if (err) -			return err; - -		priv->active_offloads |= ENETC_F_QCI; -		return 0; -	} - -	err = enetc_psfp_disable(priv); -	if (err) -		return err; - -	priv->active_offloads &= ~ENETC_F_QCI; - -	return 0; -} -  static void enetc_enable_rxvlan(struct net_device *ndev, bool en)  {  	struct enetc_ndev_priv *priv = netdev_priv(ndev); @@ -2641,11 +2599,9 @@ static void enetc_enable_txvlan(struct net_device *ndev, bool en)  		enetc_bdr_enable_txvlan(&priv->si->hw, i, en);  } -int enetc_set_features(struct net_device *ndev, -		       netdev_features_t features) +void enetc_set_features(struct net_device *ndev, netdev_features_t features)  {  	netdev_features_t changed = ndev->features ^ features; -	int err = 0;  	if (changed & NETIF_F_RXHASH)  		enetc_set_rss(ndev, !!(features & NETIF_F_RXHASH)); @@ -2657,11 +2613,6 @@ int enetc_set_features(struct net_device *ndev,  	if (changed & NETIF_F_HW_VLAN_CTAG_TX)  		enetc_enable_txvlan(ndev,  				    !!(features & NETIF_F_HW_VLAN_CTAG_TX)); - -	if (changed & NETIF_F_HW_TC) -		err = enetc_set_psfp(ndev, !!(features & NETIF_F_HW_TC)); - -	return err;  }  #ifdef CONFIG_FSL_ENETC_PTP_CLOCK diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h index 29922c20531f..2cfe6944ebd3 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc.h +++ b/drivers/net/ethernet/freescale/enetc/enetc.h @@ -393,11 +393,9 @@ void enetc_start(struct net_device *ndev);  void enetc_stop(struct net_device *ndev);  netdev_tx_t enetc_xmit(struct sk_buff *skb, struct net_device *ndev);  struct net_device_stats *enetc_get_stats(struct net_device *ndev); -int enetc_set_features(struct net_device *ndev, -		       netdev_features_t features); +void enetc_set_features(struct net_device *ndev, netdev_features_t features);  int enetc_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd); -int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type, -		   void *type_data); +int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data);  int enetc_setup_bpf(struct net_device *dev, struct netdev_bpf *xdp);  int enetc_xdp_xmit(struct net_device *ndev, int num_frames,  		   struct xdp_frame **frames, u32 flags); @@ -465,6 +463,7 @@ int enetc_setup_tc_block_cb(enum tc_setup_type type, void *type_data,  int enetc_setup_tc_psfp(struct net_device *ndev, void *type_data);  int enetc_psfp_init(struct enetc_ndev_priv *priv);  int enetc_psfp_clean(struct enetc_ndev_priv *priv); +int enetc_set_psfp(struct net_device *ndev, bool en);  static inline void enetc_get_max_cap(struct enetc_ndev_priv *priv)  { @@ -540,4 +539,9 @@ static inline int enetc_psfp_disable(struct enetc_ndev_priv *priv)  {  	return 0;  } + +static inline int enetc_set_psfp(struct net_device *ndev, bool en) +{ +	return 0; +}  #endif diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c index c4a0e836d4f0..bb7750222691 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -709,6 +709,13 @@ static int enetc_pf_set_features(struct net_device *ndev,  {  	netdev_features_t changed = ndev->features ^ features;  	struct enetc_ndev_priv *priv = netdev_priv(ndev); +	int err; + +	if (changed & NETIF_F_HW_TC) { +		err = enetc_set_psfp(ndev, !!(features & NETIF_F_HW_TC)); +		if (err) +			return err; +	}  	if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) {  		struct enetc_pf *pf = enetc_si_priv(priv->si); @@ -722,7 +729,28 @@ static int enetc_pf_set_features(struct net_device *ndev,  	if (changed & NETIF_F_LOOPBACK)  		enetc_set_loopback(ndev, !!(features & NETIF_F_LOOPBACK)); -	return enetc_set_features(ndev, features); +	enetc_set_features(ndev, features); + +	return 0; +} + +static int enetc_pf_setup_tc(struct net_device *ndev, enum tc_setup_type type, +			     void *type_data) +{ +	switch (type) { +	case TC_SETUP_QDISC_MQPRIO: +		return enetc_setup_tc_mqprio(ndev, type_data); +	case TC_SETUP_QDISC_TAPRIO: +		return enetc_setup_tc_taprio(ndev, type_data); +	case TC_SETUP_QDISC_CBS: +		return enetc_setup_tc_cbs(ndev, type_data); +	case TC_SETUP_QDISC_ETF: +		return enetc_setup_tc_txtime(ndev, type_data); +	case TC_SETUP_BLOCK: +		return enetc_setup_tc_psfp(ndev, type_data); +	default: +		return -EOPNOTSUPP; +	}  }  static const struct net_device_ops enetc_ndev_ops = { @@ -739,7 +767,7 @@ static const struct net_device_ops enetc_ndev_ops = {  	.ndo_set_vf_spoofchk	= enetc_pf_set_vf_spoofchk,  	.ndo_set_features	= enetc_pf_set_features,  	.ndo_eth_ioctl		= enetc_ioctl, -	.ndo_setup_tc		= enetc_setup_tc, +	.ndo_setup_tc		= enetc_pf_setup_tc,  	.ndo_bpf		= enetc_setup_bpf,  	.ndo_xdp_xmit		= enetc_xdp_xmit,  }; diff --git a/drivers/net/ethernet/freescale/enetc/enetc_qos.c b/drivers/net/ethernet/freescale/enetc/enetc_qos.c index 582a663ed0ba..f8a2f02ce22d 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c @@ -1517,6 +1517,29 @@ int enetc_setup_tc_block_cb(enum tc_setup_type type, void *type_data,  	}  } +int enetc_set_psfp(struct net_device *ndev, bool en) +{ +	struct enetc_ndev_priv *priv = netdev_priv(ndev); +	int err; + +	if (en) { +		err = enetc_psfp_enable(priv); +		if (err) +			return err; + +		priv->active_offloads |= ENETC_F_QCI; +		return 0; +	} + +	err = enetc_psfp_disable(priv); +	if (err) +		return err; + +	priv->active_offloads &= ~ENETC_F_QCI; + +	return 0; +} +  int enetc_psfp_init(struct enetc_ndev_priv *priv)  {  	if (epsfp.psfp_sfi_bitmap) diff --git a/drivers/net/ethernet/freescale/enetc/enetc_vf.c b/drivers/net/ethernet/freescale/enetc/enetc_vf.c index 17924305afa2..dfcaac302e24 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c @@ -88,7 +88,20 @@ static int enetc_vf_set_mac_addr(struct net_device *ndev, void *addr)  static int enetc_vf_set_features(struct net_device *ndev,  				 netdev_features_t features)  { -	return enetc_set_features(ndev, features); +	enetc_set_features(ndev, features); + +	return 0; +} + +static int enetc_vf_setup_tc(struct net_device *ndev, enum tc_setup_type type, +			     void *type_data) +{ +	switch (type) { +	case TC_SETUP_QDISC_MQPRIO: +		return enetc_setup_tc_mqprio(ndev, type_data); +	default: +		return -EOPNOTSUPP; +	}  }  /* Probing/ Init */ @@ -100,7 +113,7 @@ static const struct net_device_ops enetc_ndev_ops = {  	.ndo_set_mac_address	= enetc_vf_set_mac_addr,  	.ndo_set_features	= enetc_vf_set_features,  	.ndo_eth_ioctl		= enetc_ioctl, -	.ndo_setup_tc		= enetc_setup_tc, +	.ndo_setup_tc		= enetc_vf_setup_tc,  };  static void enetc_vf_netdev_setup(struct enetc_si *si, struct net_device *ndev, diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index d77ee8936c6a..a5fed00cb971 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -561,6 +561,7 @@ struct fec_enet_private {  	struct clk *clk_2x_txclk;  	bool ptp_clk_on; +	struct mutex ptp_clk_mutex;  	unsigned int num_tx_queues;  	unsigned int num_rx_queues; @@ -638,13 +639,6 @@ struct fec_enet_private {  	int pps_enable;  	unsigned int next_counter; -	struct { -		struct timespec64 ts_phc; -		u64 ns_sys; -		u32 at_corr; -		u8 at_inc_corr; -	} ptp_saved_state; -  	u64 ethtool_stats[];  }; @@ -655,8 +649,5 @@ void fec_ptp_disable_hwts(struct net_device *ndev);  int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr);  int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr); -void fec_ptp_save_state(struct fec_enet_private *fep); -int fec_ptp_restore_state(struct fec_enet_private *fep); -  /****************************************************************************/  #endif /* FEC_H */ diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 6152f6dbf1bc..92c55e1a5507 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -286,11 +286,8 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");  #define FEC_MMFR_TA		(2 << 16)  #define FEC_MMFR_DATA(v)	(v & 0xffff)  /* FEC ECR bits definition */ -#define FEC_ECR_RESET   BIT(0) -#define FEC_ECR_ETHEREN BIT(1) -#define FEC_ECR_MAGICEN BIT(2) -#define FEC_ECR_SLEEP   BIT(3) -#define FEC_ECR_EN1588  BIT(4) +#define FEC_ECR_MAGICEN		(1 << 2) +#define FEC_ECR_SLEEP		(1 << 3)  #define FEC_MII_TIMEOUT		30000 /* us */ @@ -986,9 +983,6 @@ fec_restart(struct net_device *ndev)  	u32 temp_mac[2];  	u32 rcntl = OPT_FRAME_SIZE | 0x04;  	u32 ecntl = 0x2; /* ETHEREN */ -	struct ptp_clock_request ptp_rq = { .type = PTP_CLK_REQ_PPS }; - -	fec_ptp_save_state(fep);  	/* Whack a reset.  We should wait for this.  	 * For i.MX6SX SOC, enet use AXI bus, we use disable MAC @@ -1142,7 +1136,7 @@ fec_restart(struct net_device *ndev)  	}  	if (fep->bufdesc_ex) -		ecntl |= FEC_ECR_EN1588; +		ecntl |= (1 << 4);  	if (fep->quirks & FEC_QUIRK_DELAYED_CLKS_SUPPORT &&  	    fep->rgmii_txc_dly) @@ -1163,14 +1157,6 @@ fec_restart(struct net_device *ndev)  	if (fep->bufdesc_ex)  		fec_ptp_start_cyclecounter(ndev); -	/* Restart PPS if needed */ -	if (fep->pps_enable) { -		/* Clear flag so fec_ptp_enable_pps() doesn't return immediately */ -		fep->pps_enable = 0; -		fec_ptp_restore_state(fep); -		fep->ptp_caps.enable(&fep->ptp_caps, &ptp_rq, 1); -	} -  	/* Enable interrupts we wish to service */  	if (fep->link)  		writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); @@ -1221,8 +1207,6 @@ fec_stop(struct net_device *ndev)  	struct fec_enet_private *fep = netdev_priv(ndev);  	u32 rmii_mode = readl(fep->hwp + FEC_R_CNTRL) & (1 << 8);  	u32 val; -	struct ptp_clock_request ptp_rq = { .type = PTP_CLK_REQ_PPS }; -	u32 ecntl = 0;  	/* We cannot expect a graceful transmit stop without link !!! */  	if (fep->link) { @@ -1232,8 +1216,6 @@ fec_stop(struct net_device *ndev)  			netdev_err(ndev, "Graceful transmit stop did not complete!\n");  	} -	fec_ptp_save_state(fep); -  	/* Whack a reset.  We should wait for this.  	 * For i.MX6SX SOC, enet use AXI bus, we use disable MAC  	 * instead of reset MAC itself. @@ -1253,28 +1235,12 @@ fec_stop(struct net_device *ndev)  	writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);  	writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); -	if (fep->bufdesc_ex) -		ecntl |= FEC_ECR_EN1588; -  	/* We have to keep ENET enabled to have MII interrupt stay working */  	if (fep->quirks & FEC_QUIRK_ENET_MAC &&  		!(fep->wol_flag & FEC_WOL_FLAG_SLEEP_ON)) { -		ecntl |= FEC_ECR_ETHEREN; +		writel(2, fep->hwp + FEC_ECNTRL);  		writel(rmii_mode, fep->hwp + FEC_R_CNTRL);  	} - -	writel(ecntl, fep->hwp + FEC_ECNTRL); - -	if (fep->bufdesc_ex) -		fec_ptp_start_cyclecounter(ndev); - -	/* Restart PPS if needed */ -	if (fep->pps_enable) { -		/* Clear flag so fec_ptp_enable_pps() doesn't return immediately */ -		fep->pps_enable = 0; -		fec_ptp_restore_state(fep); -		fep->ptp_caps.enable(&fep->ptp_caps, &ptp_rq, 1); -	}  } @@ -2029,7 +1995,6 @@ static void fec_enet_phy_reset_after_clk_enable(struct net_device *ndev)  static int fec_enet_clk_enable(struct net_device *ndev, bool enable)  {  	struct fec_enet_private *fep = netdev_priv(ndev); -	unsigned long flags;  	int ret;  	if (enable) { @@ -2038,15 +2003,15 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)  			return ret;  		if (fep->clk_ptp) { -			spin_lock_irqsave(&fep->tmreg_lock, flags); +			mutex_lock(&fep->ptp_clk_mutex);  			ret = clk_prepare_enable(fep->clk_ptp);  			if (ret) { -				spin_unlock_irqrestore(&fep->tmreg_lock, flags); +				mutex_unlock(&fep->ptp_clk_mutex);  				goto failed_clk_ptp;  			} else {  				fep->ptp_clk_on = true;  			} -			spin_unlock_irqrestore(&fep->tmreg_lock, flags); +			mutex_unlock(&fep->ptp_clk_mutex);  		}  		ret = clk_prepare_enable(fep->clk_ref); @@ -2061,10 +2026,10 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)  	} else {  		clk_disable_unprepare(fep->clk_enet_out);  		if (fep->clk_ptp) { -			spin_lock_irqsave(&fep->tmreg_lock, flags); +			mutex_lock(&fep->ptp_clk_mutex);  			clk_disable_unprepare(fep->clk_ptp);  			fep->ptp_clk_on = false; -			spin_unlock_irqrestore(&fep->tmreg_lock, flags); +			mutex_unlock(&fep->ptp_clk_mutex);  		}  		clk_disable_unprepare(fep->clk_ref);  		clk_disable_unprepare(fep->clk_2x_txclk); @@ -2077,10 +2042,10 @@ failed_clk_2x_txclk:  		clk_disable_unprepare(fep->clk_ref);  failed_clk_ref:  	if (fep->clk_ptp) { -		spin_lock_irqsave(&fep->tmreg_lock, flags); +		mutex_lock(&fep->ptp_clk_mutex);  		clk_disable_unprepare(fep->clk_ptp);  		fep->ptp_clk_on = false; -		spin_unlock_irqrestore(&fep->tmreg_lock, flags); +		mutex_unlock(&fep->ptp_clk_mutex);  	}  failed_clk_ptp:  	clk_disable_unprepare(fep->clk_enet_out); @@ -3915,7 +3880,7 @@ fec_probe(struct platform_device *pdev)  	}  	fep->ptp_clk_on = false; -	spin_lock_init(&fep->tmreg_lock); +	mutex_init(&fep->ptp_clk_mutex);  	/* clk_ref is optional, depends on board */  	fep->clk_ref = devm_clk_get_optional(&pdev->dev, "enet_clk_ref"); diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index 8dd5a2615a89..3dc3c0b626c2 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -365,19 +365,21 @@ static int fec_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)   */  static int fec_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)  { -	struct fec_enet_private *fep = +	struct fec_enet_private *adapter =  	    container_of(ptp, struct fec_enet_private, ptp_caps);  	u64 ns;  	unsigned long flags; -	spin_lock_irqsave(&fep->tmreg_lock, flags); +	mutex_lock(&adapter->ptp_clk_mutex);  	/* Check the ptp clock */ -	if (!fep->ptp_clk_on) { -		spin_unlock_irqrestore(&fep->tmreg_lock, flags); +	if (!adapter->ptp_clk_on) { +		mutex_unlock(&adapter->ptp_clk_mutex);  		return -EINVAL;  	} -	ns = timecounter_read(&fep->tc); -	spin_unlock_irqrestore(&fep->tmreg_lock, flags); +	spin_lock_irqsave(&adapter->tmreg_lock, flags); +	ns = timecounter_read(&adapter->tc); +	spin_unlock_irqrestore(&adapter->tmreg_lock, flags); +	mutex_unlock(&adapter->ptp_clk_mutex);  	*ts = ns_to_timespec64(ns); @@ -402,10 +404,10 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp,  	unsigned long flags;  	u32 counter; -	spin_lock_irqsave(&fep->tmreg_lock, flags); +	mutex_lock(&fep->ptp_clk_mutex);  	/* Check the ptp clock */  	if (!fep->ptp_clk_on) { -		spin_unlock_irqrestore(&fep->tmreg_lock, flags); +		mutex_unlock(&fep->ptp_clk_mutex);  		return -EINVAL;  	} @@ -415,9 +417,11 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp,  	 */  	counter = ns & fep->cc.mask; +	spin_lock_irqsave(&fep->tmreg_lock, flags);  	writel(counter, fep->hwp + FEC_ATIME);  	timecounter_init(&fep->tc, &fep->cc, ns);  	spin_unlock_irqrestore(&fep->tmreg_lock, flags); +	mutex_unlock(&fep->ptp_clk_mutex);  	return 0;  } @@ -514,11 +518,13 @@ static void fec_time_keep(struct work_struct *work)  	struct fec_enet_private *fep = container_of(dwork, struct fec_enet_private, time_keep);  	unsigned long flags; -	spin_lock_irqsave(&fep->tmreg_lock, flags); +	mutex_lock(&fep->ptp_clk_mutex);  	if (fep->ptp_clk_on) { +		spin_lock_irqsave(&fep->tmreg_lock, flags);  		timecounter_read(&fep->tc); +		spin_unlock_irqrestore(&fep->tmreg_lock, flags);  	} -	spin_unlock_irqrestore(&fep->tmreg_lock, flags); +	mutex_unlock(&fep->ptp_clk_mutex);  	schedule_delayed_work(&fep->time_keep, HZ);  } @@ -593,6 +599,8 @@ void fec_ptp_init(struct platform_device *pdev, int irq_idx)  	}  	fep->ptp_inc = NSEC_PER_SEC / fep->cycle_speed; +	spin_lock_init(&fep->tmreg_lock); +  	fec_ptp_start_cyclecounter(ndev);  	INIT_DELAYED_WORK(&fep->time_keep, fec_time_keep); @@ -625,36 +633,7 @@ void fec_ptp_stop(struct platform_device *pdev)  	struct net_device *ndev = platform_get_drvdata(pdev);  	struct fec_enet_private *fep = netdev_priv(ndev); -	if (fep->pps_enable) -		fec_ptp_enable_pps(fep, 0); -  	cancel_delayed_work_sync(&fep->time_keep);  	if (fep->ptp_clock)  		ptp_clock_unregister(fep->ptp_clock);  } - -void fec_ptp_save_state(struct fec_enet_private *fep) -{ -	u32 atime_inc_corr; - -	fec_ptp_gettime(&fep->ptp_caps, &fep->ptp_saved_state.ts_phc); -	fep->ptp_saved_state.ns_sys = ktime_get_ns(); - -	fep->ptp_saved_state.at_corr = readl(fep->hwp + FEC_ATIME_CORR); -	atime_inc_corr = readl(fep->hwp + FEC_ATIME_INC) & FEC_T_INC_CORR_MASK; -	fep->ptp_saved_state.at_inc_corr = (u8)(atime_inc_corr >> FEC_T_INC_CORR_OFFSET); -} - -int fec_ptp_restore_state(struct fec_enet_private *fep) -{ -	u32 atime_inc = readl(fep->hwp + FEC_ATIME_INC) & FEC_T_INC_MASK; -	u64 ns_sys; - -	writel(fep->ptp_saved_state.at_corr, fep->hwp + FEC_ATIME_CORR); -	atime_inc |= ((u32)fep->ptp_saved_state.at_inc_corr) << FEC_T_INC_CORR_OFFSET; -	writel(atime_inc, fep->hwp + FEC_ATIME_INC); - -	ns_sys = ktime_get_ns() - fep->ptp_saved_state.ns_sys; -	timespec64_add_ns(&fep->ptp_saved_state.ts_phc, ns_sys); -	return fec_ptp_settime(&fep->ptp_caps, &fep->ptp_saved_state.ts_phc); -} diff --git a/drivers/net/ethernet/google/gve/gve_rx_dqo.c b/drivers/net/ethernet/google/gve/gve_rx_dqo.c index 8c939628e2d8..2e6461b0ea8b 100644 --- a/drivers/net/ethernet/google/gve/gve_rx_dqo.c +++ b/drivers/net/ethernet/google/gve/gve_rx_dqo.c @@ -157,7 +157,7 @@ static int gve_alloc_page_dqo(struct gve_priv *priv,  	int err;  	err = gve_alloc_page(priv, &priv->pdev->dev, &buf_state->page_info.page, -			     &buf_state->addr, DMA_FROM_DEVICE, GFP_KERNEL); +			     &buf_state->addr, DMA_FROM_DEVICE, GFP_ATOMIC);  	if (err)  		return err; diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 10c1e1ea83a1..e3d9804aeb25 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -5909,6 +5909,26 @@ static int i40e_get_link_speed(struct i40e_vsi *vsi)  }  /** + * i40e_bw_bytes_to_mbits - Convert max_tx_rate from bytes to mbits + * @vsi: Pointer to vsi structure + * @max_tx_rate: max TX rate in bytes to be converted into Mbits + * + * Helper function to convert units before send to set BW limit + **/ +static u64 i40e_bw_bytes_to_mbits(struct i40e_vsi *vsi, u64 max_tx_rate) +{ +	if (max_tx_rate < I40E_BW_MBPS_DIVISOR) { +		dev_warn(&vsi->back->pdev->dev, +			 "Setting max tx rate to minimum usable value of 50Mbps.\n"); +		max_tx_rate = I40E_BW_CREDIT_DIVISOR; +	} else { +		do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR); +	} + +	return max_tx_rate; +} + +/**   * i40e_set_bw_limit - setup BW limit for Tx traffic based on max_tx_rate   * @vsi: VSI to be configured   * @seid: seid of the channel/VSI @@ -5930,10 +5950,10 @@ int i40e_set_bw_limit(struct i40e_vsi *vsi, u16 seid, u64 max_tx_rate)  			max_tx_rate, seid);  		return -EINVAL;  	} -	if (max_tx_rate && max_tx_rate < 50) { +	if (max_tx_rate && max_tx_rate < I40E_BW_CREDIT_DIVISOR) {  		dev_warn(&pf->pdev->dev,  			 "Setting max tx rate to minimum usable value of 50Mbps.\n"); -		max_tx_rate = 50; +		max_tx_rate = I40E_BW_CREDIT_DIVISOR;  	}  	/* Tx rate credits are in values of 50Mbps, 0 is disabled */ @@ -8224,9 +8244,9 @@ config_tc:  	if (i40e_is_tc_mqprio_enabled(pf)) {  		if (vsi->mqprio_qopt.max_rate[0]) { -			u64 max_tx_rate = vsi->mqprio_qopt.max_rate[0]; +			u64 max_tx_rate = i40e_bw_bytes_to_mbits(vsi, +						  vsi->mqprio_qopt.max_rate[0]); -			do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR);  			ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate);  			if (!ret) {  				u64 credits = max_tx_rate; @@ -10971,10 +10991,10 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)  	}  	if (vsi->mqprio_qopt.max_rate[0]) { -		u64 max_tx_rate = vsi->mqprio_qopt.max_rate[0]; +		u64 max_tx_rate = i40e_bw_bytes_to_mbits(vsi, +						  vsi->mqprio_qopt.max_rate[0]);  		u64 credits = 0; -		do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR);  		ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate);  		if (ret)  			goto end_unlock; diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 4f184c50f6e8..7e9f6a69eb10 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -2039,6 +2039,25 @@ static void i40e_del_qch(struct i40e_vf *vf)  }  /** + * i40e_vc_get_max_frame_size + * @vf: pointer to the VF + * + * Max frame size is determined based on the current port's max frame size and + * whether a port VLAN is configured on this VF. The VF is not aware whether + * it's in a port VLAN so the PF needs to account for this in max frame size + * checks and sending the max frame size to the VF. + **/ +static u16 i40e_vc_get_max_frame_size(struct i40e_vf *vf) +{ +	u16 max_frame_size = vf->pf->hw.phy.link_info.max_frame_size; + +	if (vf->port_vlan_id) +		max_frame_size -= VLAN_HLEN; + +	return max_frame_size; +} + +/**   * i40e_vc_get_vf_resources_msg   * @vf: pointer to the VF info   * @msg: pointer to the msg buffer @@ -2139,6 +2158,7 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg)  	vfres->max_vectors = pf->hw.func_caps.num_msix_vectors_vf;  	vfres->rss_key_size = I40E_HKEY_ARRAY_SIZE;  	vfres->rss_lut_size = I40E_VF_HLUT_ARRAY_SIZE; +	vfres->max_mtu = i40e_vc_get_max_frame_size(vf);  	if (vf->lan_vsi_idx) {  		vfres->vsi_res[0].vsi_id = vf->lan_vsi_id; diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index 10aa99dfdcdb..0c89f16bf1e2 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -1077,7 +1077,6 @@ static int iavf_set_mac(struct net_device *netdev, void *p)  {  	struct iavf_adapter *adapter = netdev_priv(netdev);  	struct sockaddr *addr = p; -	bool handle_mac = iavf_is_mac_set_handled(netdev, addr->sa_data);  	int ret;  	if (!is_valid_ether_addr(addr->sa_data)) @@ -1094,10 +1093,9 @@ static int iavf_set_mac(struct net_device *netdev, void *p)  		return 0;  	} -	if (handle_mac) -		goto done; - -	ret = wait_event_interruptible_timeout(adapter->vc_waitqueue, false, msecs_to_jiffies(2500)); +	ret = wait_event_interruptible_timeout(adapter->vc_waitqueue, +					       iavf_is_mac_set_handled(netdev, addr->sa_data), +					       msecs_to_jiffies(2500));  	/* If ret < 0 then it means wait was interrupted.  	 * If ret == 0 then it means we got a timeout. @@ -1111,7 +1109,6 @@ static int iavf_set_mac(struct net_device *netdev, void *p)  	if (!ret)  		return -EAGAIN; -done:  	if (!ether_addr_equal(netdev->dev_addr, addr->sa_data))  		return -EACCES; diff --git a/drivers/net/ethernet/intel/iavf/iavf_txrx.c b/drivers/net/ethernet/intel/iavf/iavf_txrx.c index 06d18797d25a..18b6a702a1d6 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_txrx.c +++ b/drivers/net/ethernet/intel/iavf/iavf_txrx.c @@ -114,8 +114,11 @@ u32 iavf_get_tx_pending(struct iavf_ring *ring, bool in_sw)  {  	u32 head, tail; +	/* underlying hardware might not allow access and/or always return +	 * 0 for the head/tail registers so just use the cached values +	 */  	head = ring->next_to_clean; -	tail = readl(ring->tail); +	tail = ring->next_to_use;  	if (head != tail)  		return (head < tail) ? @@ -1390,7 +1393,7 @@ static struct sk_buff *iavf_build_skb(struct iavf_ring *rx_ring,  #endif  	struct sk_buff *skb; -	if (!rx_buffer) +	if (!rx_buffer || !size)  		return NULL;  	/* prefetch first cache line of first page */  	va = page_address(rx_buffer->page) + rx_buffer->page_offset; @@ -1548,7 +1551,7 @@ static int iavf_clean_rx_irq(struct iavf_ring *rx_ring, int budget)  		/* exit if we failed to retrieve a buffer */  		if (!skb) {  			rx_ring->rx_stats.alloc_buff_failed++; -			if (rx_buffer) +			if (rx_buffer && size)  				rx_buffer->pagecnt_bias++;  			break;  		} diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c index 15ee85dc33bd..5a9e6563923e 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c @@ -269,11 +269,14 @@ int iavf_get_vf_vlan_v2_caps(struct iavf_adapter *adapter)  void iavf_configure_queues(struct iavf_adapter *adapter)  {  	struct virtchnl_vsi_queue_config_info *vqci; -	struct virtchnl_queue_pair_info *vqpi; +	int i, max_frame = adapter->vf_res->max_mtu;  	int pairs = adapter->num_active_queues; -	int i, max_frame = IAVF_MAX_RXBUFFER; +	struct virtchnl_queue_pair_info *vqpi;  	size_t len; +	if (max_frame > IAVF_MAX_RXBUFFER || !max_frame) +		max_frame = IAVF_MAX_RXBUFFER; +  	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {  		/* bail because we already have a command pending */  		dev_err(&adapter->pdev->dev, "Cannot configure queues, command %d pending\n", diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index 0c4ec9264071..58d483e2f539 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c @@ -914,7 +914,7 @@ static void ice_set_dflt_vsi_ctx(struct ice_hw *hw, struct ice_vsi_ctx *ctxt)   */  static int ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt)  { -	u16 offset = 0, qmap = 0, tx_count = 0, pow = 0; +	u16 offset = 0, qmap = 0, tx_count = 0, rx_count = 0, pow = 0;  	u16 num_txq_per_tc, num_rxq_per_tc;  	u16 qcount_tx = vsi->alloc_txq;  	u16 qcount_rx = vsi->alloc_rxq; @@ -981,23 +981,25 @@ static int ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt)  	 * at least 1)  	 */  	if (offset) -		vsi->num_rxq = offset; +		rx_count = offset;  	else -		vsi->num_rxq = num_rxq_per_tc; +		rx_count = num_rxq_per_tc; -	if (vsi->num_rxq > vsi->alloc_rxq) { +	if (rx_count > vsi->alloc_rxq) {  		dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Rx queues (%u), than were allocated (%u)!\n", -			vsi->num_rxq, vsi->alloc_rxq); +			rx_count, vsi->alloc_rxq);  		return -EINVAL;  	} -	vsi->num_txq = tx_count; -	if (vsi->num_txq > vsi->alloc_txq) { +	if (tx_count > vsi->alloc_txq) {  		dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Tx queues (%u), than were allocated (%u)!\n", -			vsi->num_txq, vsi->alloc_txq); +			tx_count, vsi->alloc_txq);  		return -EINVAL;  	} +	vsi->num_txq = tx_count; +	vsi->num_rxq = rx_count; +  	if (vsi->type == ICE_VSI_VF && vsi->num_txq != vsi->num_rxq) {  		dev_dbg(ice_pf_to_dev(vsi->back), "VF VSI should have same number of Tx and Rx queues. Hence making them equal\n");  		/* since there is a chance that num_rxq could have been changed @@ -3490,6 +3492,7 @@ ice_vsi_setup_q_map_mqprio(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt,  	u16 pow, offset = 0, qcount_tx = 0, qcount_rx = 0, qmap;  	u16 tc0_offset = vsi->mqprio_qopt.qopt.offset[0];  	int tc0_qcount = vsi->mqprio_qopt.qopt.count[0]; +	u16 new_txq, new_rxq;  	u8 netdev_tc = 0;  	int i; @@ -3530,21 +3533,24 @@ ice_vsi_setup_q_map_mqprio(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt,  		}  	} -	/* Set actual Tx/Rx queue pairs */ -	vsi->num_txq = offset + qcount_tx; -	if (vsi->num_txq > vsi->alloc_txq) { +	new_txq = offset + qcount_tx; +	if (new_txq > vsi->alloc_txq) {  		dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Tx queues (%u), than were allocated (%u)!\n", -			vsi->num_txq, vsi->alloc_txq); +			new_txq, vsi->alloc_txq);  		return -EINVAL;  	} -	vsi->num_rxq = offset + qcount_rx; -	if (vsi->num_rxq > vsi->alloc_rxq) { +	new_rxq = offset + qcount_rx; +	if (new_rxq > vsi->alloc_rxq) {  		dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Rx queues (%u), than were allocated (%u)!\n", -			vsi->num_rxq, vsi->alloc_rxq); +			new_rxq, vsi->alloc_rxq);  		return -EINVAL;  	} +	/* Set actual Tx/Rx queue pairs */ +	vsi->num_txq = new_txq; +	vsi->num_rxq = new_rxq; +  	/* Setup queue TC[0].qmap for given VSI context */  	ctxt->info.tc_mapping[0] = cpu_to_le16(qmap);  	ctxt->info.q_mapping[0] = cpu_to_le16(vsi->rxq_map[0]); @@ -3576,6 +3582,7 @@ int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc)  {  	u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };  	struct ice_pf *pf = vsi->back; +	struct ice_tc_cfg old_tc_cfg;  	struct ice_vsi_ctx *ctx;  	struct device *dev;  	int i, ret = 0; @@ -3600,6 +3607,7 @@ int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc)  			max_txqs[i] = vsi->num_txq;  	} +	memcpy(&old_tc_cfg, &vsi->tc_cfg, sizeof(old_tc_cfg));  	vsi->tc_cfg.ena_tc = ena_tc;  	vsi->tc_cfg.numtc = num_tc; @@ -3616,8 +3624,10 @@ int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc)  	else  		ret = ice_vsi_setup_q_map(vsi, ctx); -	if (ret) +	if (ret) { +		memcpy(&vsi->tc_cfg, &old_tc_cfg, sizeof(vsi->tc_cfg));  		goto out; +	}  	/* must to indicate which section of VSI context are being modified */  	ctx->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_RXQ_MAP_VALID); diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index 8c30eea61b6d..e109cb93886b 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -2399,8 +2399,6 @@ int ice_schedule_reset(struct ice_pf *pf, enum ice_reset_req reset)  		return -EBUSY;  	} -	ice_unplug_aux_dev(pf); -  	switch (reset) {  	case ICE_RESET_PFR:  		set_bit(ICE_PFR_REQ, pf->state); @@ -6651,7 +6649,7 @@ static void ice_napi_disable_all(struct ice_vsi *vsi)   */  int ice_down(struct ice_vsi *vsi)  { -	int i, tx_err, rx_err, link_err = 0, vlan_err = 0; +	int i, tx_err, rx_err, vlan_err = 0;  	WARN_ON(!test_bit(ICE_VSI_DOWN, vsi->state)); @@ -6685,20 +6683,13 @@ int ice_down(struct ice_vsi *vsi)  	ice_napi_disable_all(vsi); -	if (test_bit(ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, vsi->back->flags)) { -		link_err = ice_force_phys_link_state(vsi, false); -		if (link_err) -			netdev_err(vsi->netdev, "Failed to set physical link down, VSI %d error %d\n", -				   vsi->vsi_num, link_err); -	} -  	ice_for_each_txq(vsi, i)  		ice_clean_tx_ring(vsi->tx_rings[i]);  	ice_for_each_rxq(vsi, i)  		ice_clean_rx_ring(vsi->rx_rings[i]); -	if (tx_err || rx_err || link_err || vlan_err) { +	if (tx_err || rx_err || vlan_err) {  		netdev_err(vsi->netdev, "Failed to close VSI 0x%04X on switch 0x%04X\n",  			   vsi->vsi_num, vsi->vsw->sw_id);  		return -EIO; @@ -6860,6 +6851,8 @@ int ice_vsi_open(struct ice_vsi *vsi)  	if (err)  		goto err_setup_rx; +	ice_vsi_cfg_netdev_tc(vsi, vsi->tc_cfg.ena_tc); +  	if (vsi->type == ICE_VSI_PF) {  		/* Notify the stack of the actual queue counts. */  		err = netif_set_real_num_tx_queues(vsi->netdev, vsi->num_txq); @@ -8892,6 +8885,16 @@ int ice_stop(struct net_device *netdev)  		return -EBUSY;  	} +	if (test_bit(ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, vsi->back->flags)) { +		int link_err = ice_force_phys_link_state(vsi, false); + +		if (link_err) { +			netdev_err(vsi->netdev, "Failed to set physical link down, VSI %d error %d\n", +				   vsi->vsi_num, link_err); +			return -EIO; +		} +	} +  	ice_vsi_close(vsi);  	return 0; diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c index 836dce840712..97453d1dfafe 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.c +++ b/drivers/net/ethernet/intel/ice/ice_txrx.c @@ -610,7 +610,7 @@ ice_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,  	if (test_bit(ICE_VSI_DOWN, vsi->state))  		return -ENETDOWN; -	if (!ice_is_xdp_ena_vsi(vsi) || queue_index >= vsi->num_xdp_txq) +	if (!ice_is_xdp_ena_vsi(vsi))  		return -ENXIO;  	if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) @@ -621,6 +621,9 @@ ice_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,  		xdp_ring = vsi->xdp_rings[queue_index];  		spin_lock(&xdp_ring->tx_lock);  	} else { +		/* Generally, should not happen */ +		if (unlikely(queue_index >= vsi->num_xdp_txq)) +			return -ENXIO;  		xdp_ring = vsi->xdp_rings[queue_index];  	} diff --git a/drivers/net/ethernet/marvell/prestera/prestera_main.c b/drivers/net/ethernet/marvell/prestera/prestera_main.c index ede3e53b9790..a895862b4821 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_main.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_main.c @@ -368,6 +368,7 @@ static int prestera_port_sfp_bind(struct prestera_port *port)  	if (!sw->np)  		return 0; +	of_node_get(sw->np);  	ports = of_find_node_by_name(sw->np, "ports");  	for_each_child_of_node(ports, node) { @@ -417,6 +418,7 @@ static int prestera_port_sfp_bind(struct prestera_port *port)  	}  out: +	of_node_put(node);  	of_node_put(ports);  	return err;  } diff --git a/drivers/net/ethernet/marvell/prestera/prestera_pci.c b/drivers/net/ethernet/marvell/prestera/prestera_pci.c index f538a749ebd4..59470d99f522 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_pci.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_pci.c @@ -872,6 +872,7 @@ static void prestera_pci_remove(struct pci_dev *pdev)  static const struct pci_device_id prestera_pci_devices[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0xC804) },  	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0xC80C) }, +	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0xCC1E) },  	{ }  };  MODULE_DEVICE_TABLE(pci, prestera_pci_devices); diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index 5ace4609de47..b344632beadd 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -1458,7 +1458,7 @@ static void mtk_update_rx_cpu_idx(struct mtk_eth *eth)  static bool mtk_page_pool_enabled(struct mtk_eth *eth)  { -	return !eth->hwlro; +	return MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2);  }  static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth, diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c index 85155cd9405c..4aeb927c3715 100644 --- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c +++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c @@ -179,6 +179,9 @@ static int mlxbf_gige_mdio_read(struct mii_bus *bus, int phy_add, int phy_reg)  	/* Only return ad bits of the gw register */  	ret &= MLXBF_GIGE_MDIO_GW_AD_MASK; +	/* The MDIO lock is set on read. To release it, clear gw register */ +	writel(0, priv->mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET); +  	return ret;  } @@ -203,6 +206,9 @@ static int mlxbf_gige_mdio_write(struct mii_bus *bus, int phy_add,  					temp, !(temp & MLXBF_GIGE_MDIO_GW_BUSY_MASK),  					5, 1000000); +	/* The MDIO lock is set on read. To release it, clear gw register */ +	writel(0, priv->mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET); +  	return ret;  } diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c index 00d8198072ae..a6f99b4344d9 100644 --- a/drivers/net/ethernet/microsoft/mana/gdma_main.c +++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c @@ -397,6 +397,11 @@ static void mana_gd_process_eq_events(void *arg)  			break;  		} +		/* Per GDMA spec, rmb is necessary after checking owner_bits, before +		 * reading eqe. +		 */ +		rmb(); +  		mana_gd_process_eqe(eq);  		eq->head++; @@ -1134,6 +1139,11 @@ static int mana_gd_read_cqe(struct gdma_queue *cq, struct gdma_comp *comp)  	if (WARN_ON_ONCE(owner_bits != new_bits))  		return -1; +	/* Per GDMA spec, rmb is necessary after checking owner_bits, before +	 * reading completion info +	 */ +	rmb(); +  	comp->wq_num = cqe->cqe_info.wq_num;  	comp->is_sq = cqe->cqe_info.is_sq;  	memcpy(comp->cqe_data, cqe->cqe_data, GDMA_COMP_DATA_SIZE); diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c index b357ac4c56c5..7e32b04eb0c7 100644 --- a/drivers/net/ethernet/renesas/ravb_main.c +++ b/drivers/net/ethernet/renesas/ravb_main.c @@ -1449,6 +1449,8 @@ static int ravb_phy_init(struct net_device *ndev)  		phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);  	} +	/* Indicate that the MAC is responsible for managing PHY PM */ +	phydev->mac_managed_pm = true;  	phy_attached_info(phydev);  	return 0; diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 67ade78fb767..7fd8828d3a84 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -2029,6 +2029,8 @@ static int sh_eth_phy_init(struct net_device *ndev)  	if (mdp->cd->register_type != SH_ETH_REG_GIGABIT)  		phy_set_max_speed(phydev, SPEED_100); +	/* Indicate that the MAC is responsible for managing PHY PM */ +	phydev->mac_managed_pm = true;  	phy_attached_info(phydev);  	return 0; diff --git a/drivers/net/ethernet/sfc/efx_channels.c b/drivers/net/ethernet/sfc/efx_channels.c index 032b8c0bd788..5b4d661ab986 100644 --- a/drivers/net/ethernet/sfc/efx_channels.c +++ b/drivers/net/ethernet/sfc/efx_channels.c @@ -319,7 +319,7 @@ int efx_probe_interrupts(struct efx_nic *efx)  		efx->n_channels = 1 + (efx_separate_tx_channels ? 1 : 0);  		efx->n_rx_channels = 1;  		efx->n_tx_channels = 1; -		efx->tx_channel_offset = 1; +		efx->tx_channel_offset = efx_separate_tx_channels ? 1 : 0;  		efx->n_xdp_channels = 0;  		efx->xdp_channel_offset = efx->n_channels;  		efx->legacy_irq = efx->pci_dev->irq; diff --git a/drivers/net/ethernet/sfc/siena/efx_channels.c b/drivers/net/ethernet/sfc/siena/efx_channels.c index 017212a40df3..f54ebd007286 100644 --- a/drivers/net/ethernet/sfc/siena/efx_channels.c +++ b/drivers/net/ethernet/sfc/siena/efx_channels.c @@ -320,7 +320,7 @@ int efx_siena_probe_interrupts(struct efx_nic *efx)  		efx->n_channels = 1 + (efx_siena_separate_tx_channels ? 1 : 0);  		efx->n_rx_channels = 1;  		efx->n_tx_channels = 1; -		efx->tx_channel_offset = 1; +		efx->tx_channel_offset = efx_siena_separate_tx_channels ? 1 : 0;  		efx->n_xdp_channels = 0;  		efx->xdp_channel_offset = efx->n_channels;  		efx->legacy_irq = efx->pci_dev->irq; diff --git a/drivers/net/ethernet/sfc/siena/tx.c b/drivers/net/ethernet/sfc/siena/tx.c index e166dcb9b99c..91e87594ed1e 100644 --- a/drivers/net/ethernet/sfc/siena/tx.c +++ b/drivers/net/ethernet/sfc/siena/tx.c @@ -336,7 +336,7 @@ netdev_tx_t efx_siena_hard_start_xmit(struct sk_buff *skb,  		 * previous packets out.  		 */  		if (!netdev_xmit_more()) -			efx_tx_send_pending(tx_queue->channel); +			efx_tx_send_pending(efx_get_tx_channel(efx, index));  		return NETDEV_TX_OK;  	} diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c index d12474042c84..c5f88f7a7a04 100644 --- a/drivers/net/ethernet/sfc/tx.c +++ b/drivers/net/ethernet/sfc/tx.c @@ -549,7 +549,7 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,  		 * previous packets out.  		 */  		if (!netdev_xmit_more()) -			efx_tx_send_pending(tx_queue->channel); +			efx_tx_send_pending(efx_get_tx_channel(efx, index));  		return NETDEV_TX_OK;  	} diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c index 8594ee839628..88aa0d310aee 100644 --- a/drivers/net/ethernet/sun/sunhme.c +++ b/drivers/net/ethernet/sun/sunhme.c @@ -2020,9 +2020,9 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev)  			skb_reserve(copy_skb, 2);  			skb_put(copy_skb, len); -			dma_sync_single_for_cpu(hp->dma_dev, dma_addr, len, DMA_FROM_DEVICE); +			dma_sync_single_for_cpu(hp->dma_dev, dma_addr, len + 2, DMA_FROM_DEVICE);  			skb_copy_from_linear_data(skb, copy_skb->data, len); -			dma_sync_single_for_device(hp->dma_dev, dma_addr, len, DMA_FROM_DEVICE); +			dma_sync_single_for_device(hp->dma_dev, dma_addr, len + 2, DMA_FROM_DEVICE);  			/* Reuse original ring buffer. */  			hme_write_rxd(hp, this,  				      (RXFLAG_OWN|((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)), | 
