Commit 2607c090 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2026-04-06 (idpf, ice, ixgbe, ixgbevf, igb, e1000)

Emil converts to use spinlock_t for virtchnl transactions to make
consistent use of the xn_bm_lock when accessing the free_xn_bm bitmap,
while also avoiding nested raw/bh spinlock issue on PREEMPT_RT kernels.
He also sets payload size before calling the async handler, to make sure
it doesn't error out prematurely due to invalid size check for idpf.

Kohei Enju changes WARN_ON for missing PTP control PF to a dev_info() on
ice as there are cases where this is expected and acceptable.

Petr Oros fixes conditions in which error paths failed to call
ice_ptp_port_phy_restart() breaking PTP functionality on ice.

Alex significantly reduces reporting of driver information, and time
under RTNL locl, on ixgbe e610 devices by reducing reads of flash info
only on events that could change it.

Michal Schmidt adds missing Hyper-V op on ixgbevf.

Alex Dvoretsky removes call to napi_synchronize() in igb_down() to
resolve a deadlock.

Agalakov Daniil adds error check on e1000 for failed EEPROM read.

* '200GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue:
  e1000: check return value of e1000_read_eeprom
  igb: remove napi_synchronize() in igb_down()
  ixgbevf: add missing negotiate_features op to Hyper-V ops table
  ixgbe: stop re-reading flash on every get_drvinfo for e610
  ice: fix PTP timestamping broken by SyncE code on E825C
  ice: ptp: don't WARN when controlling PF is unavailable
  idpf: set the payload size before calling the async handler
  idpf: improve locking around idpf_vc_xn_push_free()
  idpf: fix PREEMPT_RT raw/bh spinlock nesting for async VC handling
====================

Link: https://patch.msgid.link/20260406213038.444732-1-anthony.l.nguyen@intel.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 30f3b767 d3baa34a
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -496,14 +496,19 @@ static int e1000_set_eeprom(struct net_device *netdev,
		 */
		ret_val = e1000_read_eeprom(hw, first_word, 1,
					    &eeprom_buff[0]);
		if (ret_val)
			goto out;

		ptr++;
	}
	if (((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) {
	if ((eeprom->offset + eeprom->len) & 1) {
		/* need read/modify/write of last changed EEPROM word
		 * only the first byte of the word is being modified
		 */
		ret_val = e1000_read_eeprom(hw, last_word, 1,
					    &eeprom_buff[last_word - first_word]);
		if (ret_val)
			goto out;
	}

	/* Device's eeprom is always little-endian, word addressable */
@@ -522,6 +527,7 @@ static int e1000_set_eeprom(struct net_device *netdev,
	if ((ret_val == 0) && (first_word <= EEPROM_CHECKSUM_REG))
		e1000_update_eeprom_checksum(hw);

out:
	kfree(eeprom_buff);
	return ret_val;
}
+19 −11
Original line number Diff line number Diff line
@@ -1296,12 +1296,10 @@ void ice_ptp_link_change(struct ice_pf *pf, bool linkup)
	if (pf->hw.reset_ongoing)
		return;

	if (hw->mac_type == ICE_MAC_GENERIC_3K_E825) {
	if (hw->mac_type == ICE_MAC_GENERIC_3K_E825 &&
	    test_bit(ICE_FLAG_DPLL, pf->flags)) {
		int pin, err;

		if (!test_bit(ICE_FLAG_DPLL, pf->flags))
			return;

		mutex_lock(&pf->dplls.lock);
		for (pin = 0; pin < ICE_SYNCE_CLK_NUM; pin++) {
			enum ice_synce_clk clk_pin;
@@ -1314,15 +1312,19 @@ void ice_ptp_link_change(struct ice_pf *pf, bool linkup)
								port_num,
								&active,
								clk_pin);
			if (WARN_ON_ONCE(err)) {
				mutex_unlock(&pf->dplls.lock);
				return;
			if (err) {
				dev_err_once(ice_pf_to_dev(pf),
					     "Failed to read SyncE bypass mux for pin %d, err %d\n",
					     pin, err);
				break;
			}

			err = ice_tspll_cfg_synce_ethdiv_e825c(hw, clk_pin);
			if (active && WARN_ON_ONCE(err)) {
				mutex_unlock(&pf->dplls.lock);
				return;
			if (active && err) {
				dev_err_once(ice_pf_to_dev(pf),
					     "Failed to configure SyncE ETH divider for pin %d, err %d\n",
					     pin, err);
				break;
			}
		}
		mutex_unlock(&pf->dplls.lock);
@@ -3080,7 +3082,13 @@ static int ice_ptp_setup_pf(struct ice_pf *pf)
	struct ice_ptp *ctrl_ptp = ice_get_ctrl_ptp(pf);
	struct ice_ptp *ptp = &pf->ptp;

	if (WARN_ON(!ctrl_ptp) || pf->hw.mac_type == ICE_MAC_UNKNOWN)
	if (!ctrl_ptp) {
		dev_info(ice_pf_to_dev(pf),
			 "PTP unavailable: no controlling PF\n");
		return -EOPNOTSUPP;
	}

	if (pf->hw.mac_type == ICE_MAC_UNKNOWN)
		return -ENODEV;

	INIT_LIST_HEAD(&ptp->port.list_node);
+11 −9
Original line number Diff line number Diff line
@@ -287,26 +287,21 @@ int idpf_send_mb_msg(struct idpf_adapter *adapter, struct idpf_ctlq_info *asq,
	return err;
}

/* API for virtchnl "transaction" support ("xn" for short).
 *
 * We are reusing the completion lock to serialize the accesses to the
 * transaction state for simplicity, but it could be its own separate synchro
 * as well. For now, this API is only used from within a workqueue context;
 * raw_spin_lock() is enough.
 */
/* API for virtchnl "transaction" support ("xn" for short). */

/**
 * idpf_vc_xn_lock - Request exclusive access to vc transaction
 * @xn: struct idpf_vc_xn* to access
 */
#define idpf_vc_xn_lock(xn)			\
	raw_spin_lock(&(xn)->completed.wait.lock)
	spin_lock(&(xn)->lock)

/**
 * idpf_vc_xn_unlock - Release exclusive access to vc transaction
 * @xn: struct idpf_vc_xn* to access
 */
#define idpf_vc_xn_unlock(xn)		\
	raw_spin_unlock(&(xn)->completed.wait.lock)
	spin_unlock(&(xn)->lock)

/**
 * idpf_vc_xn_release_bufs - Release reference to reply buffer(s) and
@@ -338,6 +333,7 @@ static void idpf_vc_xn_init(struct idpf_vc_xn_manager *vcxn_mngr)
		xn->state = IDPF_VC_XN_IDLE;
		xn->idx = i;
		idpf_vc_xn_release_bufs(xn);
		spin_lock_init(&xn->lock);
		init_completion(&xn->completed);
	}

@@ -406,7 +402,9 @@ static void idpf_vc_xn_push_free(struct idpf_vc_xn_manager *vcxn_mngr,
				 struct idpf_vc_xn *xn)
{
	idpf_vc_xn_release_bufs(xn);
	spin_lock_bh(&vcxn_mngr->xn_bm_lock);
	set_bit(xn->idx, vcxn_mngr->free_xn_bm);
	spin_unlock_bh(&vcxn_mngr->xn_bm_lock);
}

/**
@@ -617,6 +615,10 @@ idpf_vc_xn_forward_reply(struct idpf_adapter *adapter,
		err = -ENXIO;
		goto out_unlock;
	case IDPF_VC_XN_ASYNC:
		/* Set reply_sz from the actual payload so that async_handler
		 * can evaluate the response.
		 */
		xn->reply_sz = ctlq_msg->data_len;
		err = idpf_vc_xn_forward_async(adapter, xn, ctlq_msg);
		idpf_vc_xn_unlock(xn);
		return err;
+3 −2
Original line number Diff line number Diff line
@@ -42,8 +42,8 @@ typedef int (*async_vc_cb) (struct idpf_adapter *, struct idpf_vc_xn *,
 * struct idpf_vc_xn - Data structure representing virtchnl transactions
 * @completed: virtchnl event loop uses that to signal when a reply is
 *	       available, uses kernel completion API
 * @state: virtchnl event loop stores the data below, protected by the
 *	   completion's lock.
 * @lock: protects the transaction state fields below
 * @state: virtchnl event loop stores the data below, protected by @lock
 * @reply_sz: Original size of reply, may be > reply_buf.iov_len; it will be
 *	      truncated on its way to the receiver thread according to
 *	      reply_buf.iov_len.
@@ -58,6 +58,7 @@ typedef int (*async_vc_cb) (struct idpf_adapter *, struct idpf_vc_xn *,
 */
struct idpf_vc_xn {
	struct completion completed;
	spinlock_t lock;
	enum idpf_vc_xn_state state;
	size_t reply_sz;
	struct kvec reply;
+1 −2
Original line number Diff line number Diff line
@@ -2203,9 +2203,8 @@ void igb_down(struct igb_adapter *adapter)

	for (i = 0; i < adapter->num_q_vectors; i++) {
		if (adapter->q_vector[i]) {
			napi_synchronize(&adapter->q_vector[i]->napi);
			igb_set_queue_napi(adapter, i, NULL);
			napi_disable(&adapter->q_vector[i]->napi);
			igb_set_queue_napi(adapter, i, NULL);
		}
	}

Loading