Commit 452446f8 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2025-04-11 (ice, i40e, ixgbe, igc, e1000e)

For ice:
Mateusz and Larysa add support for LLDP packets to be received on a VF
and transmitted by a VF in switchdev mode. Additional information:
https://lore.kernel.org/intel-wired-lan/20250214085215.2846063-1-larysa.zaremba@intel.com/

Karol adds timesync support for E825C devices using 2xNAC (Network
Acceleration Complex) configuration. 2xNAC mode is the mode in which
IO die is housing two complexes and each of them has its own PHY
connected to it.

Martyna adds messaging to clarify filter errors when recipe space is
exhausted.

Colin Ian King adds static modifier to a const array to avoid stack
usage.

For i40e:
Kyungwook Boo changes variable declaration types to prevent possible
underflow.

For ixgbe:
Rand Deeb adjusts retry values so that retries are attempted.

For igc:
Rui Salvaterra sets VLAN offloads to be enabled as default.

For e1000e:
Piotr Wejman converts driver to use newer hardware timestamping API.

* '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
  net: e1000e: convert to ndo_hwtstamp_get() and ndo_hwtstamp_set()
  igc: enable HW vlan tag insertion/stripping by default
  ixgbe: Fix unreachable retry logic in combined and byte I2C write functions
  i40e: fix MMIO write access to an invalid page in i40e_clear_hw
  ice: make const read-only array dflt_rules static
  ice: improve error message for insufficient filter space
  ice: enable timesync operation on 2xNAC E825 devices
  ice: refactor ice_sbq_msg_dev enum
  ice: remove SW side band access workaround for E825
  ice: enable LLDP TX for VFs through tc
  ice: support egress drop rules on PF
  ice: remove headers argument from ice_tc_count_lkups
  ice: receive LLDP on trusted VFs
  ice: do not add LLDP-specific filter if not necessary
  ice: fix check for existing switch rule
====================

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


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 63c5e952 39aa687a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -319,7 +319,7 @@ struct e1000_adapter {
	u16 tx_ring_count;
	u16 rx_ring_count;

	struct hwtstamp_config hwtstamp_config;
	struct kernel_hwtstamp_config hwtstamp_config;
	struct delayed_work systim_overflow_work;
	struct sk_buff *tx_hwtstamp_skb;
	unsigned long tx_hwtstamp_start;
+37 −38
Original line number Diff line number Diff line
@@ -3574,6 +3574,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca)
 * e1000e_config_hwtstamp - configure the hwtstamp registers and enable/disable
 * @adapter: board private structure
 * @config: timestamp configuration
 * @extack: netlink extended ACK for error report
 *
 * Outgoing time stamping can be enabled and disabled. Play nice and
 * disable it when requested, although it shouldn't cause any overhead
@@ -3587,7 +3588,8 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca)
 * exception of "all V2 events regardless of level 2 or 4".
 **/
static int e1000e_config_hwtstamp(struct e1000_adapter *adapter,
				  struct hwtstamp_config *config)
				  struct kernel_hwtstamp_config *config,
				  struct netlink_ext_ack *extack)
{
	struct e1000_hw *hw = &adapter->hw;
	u32 tsync_tx_ctl = E1000_TSYNCTXCTL_ENABLED;
@@ -3598,8 +3600,10 @@ static int e1000e_config_hwtstamp(struct e1000_adapter *adapter,
	bool is_l2 = false;
	u32 regval;

	if (!(adapter->flags & FLAG_HAS_HW_TIMESTAMP))
	if (!(adapter->flags & FLAG_HAS_HW_TIMESTAMP)) {
		NL_SET_ERR_MSG(extack, "No HW timestamp support");
		return -EINVAL;
	}

	switch (config->tx_type) {
	case HWTSTAMP_TX_OFF:
@@ -3608,6 +3612,7 @@ static int e1000e_config_hwtstamp(struct e1000_adapter *adapter,
	case HWTSTAMP_TX_ON:
		break;
	default:
		NL_SET_ERR_MSG(extack, "Unsupported TX HW timestamp type");
		return -ERANGE;
	}

@@ -3681,6 +3686,7 @@ static int e1000e_config_hwtstamp(struct e1000_adapter *adapter,
		config->rx_filter = HWTSTAMP_FILTER_ALL;
		break;
	default:
		NL_SET_ERR_MSG(extack, "Unsupported RX HW timestamp filter");
		return -ERANGE;
	}

@@ -3693,7 +3699,8 @@ static int e1000e_config_hwtstamp(struct e1000_adapter *adapter,
	ew32(TSYNCTXCTL, regval);
	if ((er32(TSYNCTXCTL) & E1000_TSYNCTXCTL_ENABLED) !=
	    (regval & E1000_TSYNCTXCTL_ENABLED)) {
		e_err("Timesync Tx Control register not set as expected\n");
		NL_SET_ERR_MSG(extack,
			       "Timesync Tx Control register not set as expected");
		return -EAGAIN;
	}

@@ -3706,7 +3713,8 @@ static int e1000e_config_hwtstamp(struct e1000_adapter *adapter,
				 E1000_TSYNCRXCTL_TYPE_MASK)) !=
	    (regval & (E1000_TSYNCRXCTL_ENABLED |
		       E1000_TSYNCRXCTL_TYPE_MASK))) {
		e_err("Timesync Rx Control register not set as expected\n");
		NL_SET_ERR_MSG(extack,
			       "Timesync Rx Control register not set as expected");
		return -EAGAIN;
	}

@@ -3901,6 +3909,7 @@ static void e1000e_systim_reset(struct e1000_adapter *adapter)
{
	struct ptp_clock_info *info = &adapter->ptp_clock_info;
	struct e1000_hw *hw = &adapter->hw;
	struct netlink_ext_ack extack = {};
	unsigned long flags;
	u32 timinca;
	s32 ret_val;
@@ -3932,7 +3941,12 @@ static void e1000e_systim_reset(struct e1000_adapter *adapter)
	spin_unlock_irqrestore(&adapter->systim_lock, flags);

	/* restore the previous hwtstamp configuration settings */
	e1000e_config_hwtstamp(adapter, &adapter->hwtstamp_config);
	ret_val = e1000e_config_hwtstamp(adapter, &adapter->hwtstamp_config,
					 &extack);
	if (ret_val) {
		if (extack._msg)
			e_err("%s\n", extack._msg);
	}
}

/**
@@ -6079,8 +6093,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
	return 0;
}

static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
			   int cmd)
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	struct mii_ioctl_data *data = if_mii(ifr);
@@ -6140,7 +6153,8 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
/**
 * e1000e_hwtstamp_set - control hardware time stamping
 * @netdev: network interface device structure
 * @ifr: interface request
 * @config: timestamp configuration
 * @extack: netlink extended ACK report
 *
 * Outgoing time stamping can be enabled and disabled. Play nice and
 * disable it when requested, although it shouldn't cause any overhead
@@ -6153,20 +6167,18 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
 * specified. Matching the kind of event packet is not supported, with the
 * exception of "all V2 events regardless of level 2 or 4".
 **/
static int e1000e_hwtstamp_set(struct net_device *netdev, struct ifreq *ifr)
static int e1000e_hwtstamp_set(struct net_device *netdev,
			       struct kernel_hwtstamp_config *config,
			       struct netlink_ext_ack *extack)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	struct hwtstamp_config config;
	int ret_val;

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

	ret_val = e1000e_config_hwtstamp(adapter, &config);
	ret_val = e1000e_config_hwtstamp(adapter, config, extack);
	if (ret_val)
		return ret_val;

	switch (config.rx_filter) {
	switch (config->rx_filter) {
	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_SYNC:
@@ -6178,38 +6190,23 @@ static int e1000e_hwtstamp_set(struct net_device *netdev, struct ifreq *ifr)
		 * by hardware so notify the caller the requested packets plus
		 * some others are time stamped.
		 */
		config.rx_filter = HWTSTAMP_FILTER_SOME;
		config->rx_filter = HWTSTAMP_FILTER_SOME;
		break;
	default:
		break;
	}

	return copy_to_user(ifr->ifr_data, &config,
			    sizeof(config)) ? -EFAULT : 0;
	return 0;
}

static int e1000e_hwtstamp_get(struct net_device *netdev, struct ifreq *ifr)
static int e1000e_hwtstamp_get(struct net_device *netdev,
			       struct kernel_hwtstamp_config *kernel_config)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);

	return copy_to_user(ifr->ifr_data, &adapter->hwtstamp_config,
			    sizeof(adapter->hwtstamp_config)) ? -EFAULT : 0;
}
	*kernel_config = adapter->hwtstamp_config;

static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{
	switch (cmd) {
	case SIOCGMIIPHY:
	case SIOCGMIIREG:
	case SIOCSMIIREG:
		return e1000_mii_ioctl(netdev, ifr, cmd);
	case SIOCSHWTSTAMP:
		return e1000e_hwtstamp_set(netdev, ifr);
	case SIOCGHWTSTAMP:
		return e1000e_hwtstamp_get(netdev, ifr);
	default:
		return -EOPNOTSUPP;
	}
	return 0;
}

static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc)
@@ -7349,6 +7346,8 @@ static const struct net_device_ops e1000e_netdev_ops = {
	.ndo_set_features	= e1000_set_features,
	.ndo_fix_features	= e1000_fix_features,
	.ndo_features_check	= passthru_features_check,
	.ndo_hwtstamp_get	= e1000e_hwtstamp_get,
	.ndo_hwtstamp_set	= e1000e_hwtstamp_set,
};

/**
+4 −3
Original line number Diff line number Diff line
@@ -817,10 +817,11 @@ int i40e_pf_reset(struct i40e_hw *hw)
void i40e_clear_hw(struct i40e_hw *hw)
{
	u32 num_queues, base_queue;
	u32 num_pf_int;
	u32 num_vf_int;
	s32 num_pf_int;
	s32 num_vf_int;
	u32 num_vfs;
	u32 i, j;
	s32 i;
	u32 j;
	u32 val;
	u32 eol = 0x7ff;

+59 −2
Original line number Diff line number Diff line
@@ -193,8 +193,6 @@

#define ice_pf_to_dev(pf) (&((pf)->pdev->dev))

#define ice_pf_src_tmr_owned(pf) ((pf)->hw.func_caps.ts_func_info.src_tmr_owned)

enum ice_feature {
	ICE_F_DSCP,
	ICE_F_PHY_RCLK,
@@ -515,6 +513,7 @@ enum ice_pf_flags {
	ICE_FLAG_MTU_CHANGED,
	ICE_FLAG_GNSS,			/* GNSS successfully initialized */
	ICE_FLAG_DPLL,			/* SyncE/PTP dplls initialized */
	ICE_FLAG_LLDP_AQ_FLTR,
	ICE_PF_FLAGS_NBITS		/* must be last */
};

@@ -1045,4 +1044,62 @@ static inline void ice_clear_rdma_cap(struct ice_pf *pf)
}

extern const struct xdp_metadata_ops ice_xdp_md_ops;

/**
 * ice_is_dual - Check if given config is multi-NAC
 * @hw: pointer to HW structure
 *
 * Return: true if the device is running in mutli-NAC (Network
 * Acceleration Complex) configuration variant, false otherwise
 * (always false for non-E825 devices).
 */
static inline bool ice_is_dual(struct ice_hw *hw)
{
	return hw->mac_type == ICE_MAC_GENERIC_3K_E825 &&
	       (hw->dev_caps.nac_topo.mode & ICE_NAC_TOPO_DUAL_M);
}

/**
 * ice_is_primary - Check if given device belongs to the primary complex
 * @hw: pointer to HW structure
 *
 * Check if given PF/HW is running on primary complex in multi-NAC
 * configuration.
 *
 * Return: true if the device is dual, false otherwise (always true
 * for non-E825 devices).
 */
static inline bool ice_is_primary(struct ice_hw *hw)
{
	return hw->mac_type != ICE_MAC_GENERIC_3K_E825 ||
	       !ice_is_dual(hw) ||
	       (hw->dev_caps.nac_topo.mode & ICE_NAC_TOPO_PRIMARY_M);
}

/**
 * ice_pf_src_tmr_owned - Check if a primary timer is owned by PF
 * @pf: pointer to PF structure
 *
 * Return: true if PF owns primary timer, false otherwise.
 */
static inline bool ice_pf_src_tmr_owned(struct ice_pf *pf)
{
	return pf->hw.func_caps.ts_func_info.src_tmr_owned &&
	       ice_is_primary(&pf->hw);
}

/**
 * ice_get_primary_hw - Get pointer to primary ice_hw structure
 * @pf: pointer to PF structure
 *
 * Return: A pointer to ice_hw structure with access to timesync
 * register space.
 */
static inline struct ice_hw *ice_get_primary_hw(struct ice_pf *pf)
{
	if (!pf->adapter->ctrl_pf)
		return &pf->hw;
	else
		return &pf->adapter->ctrl_pf->hw;
}
#endif /* _ICE_H_ */
+16 −6
Original line number Diff line number Diff line
@@ -1135,6 +1135,8 @@ int ice_init_hw(struct ice_hw *hw)
		}
	}

	hw->lane_num = ice_get_phy_lane_number(hw);

	return 0;
err_unroll_fltr_mgmt_struct:
	ice_cleanup_fltr_mgmt_struct(hw);
@@ -3434,7 +3436,7 @@ int ice_aq_get_fec_stats(struct ice_hw *hw, u16 pcs_quad, u16 pcs_port,
	msg.msg_addr_low = lower_16_bits(reg_offset);
	msg.msg_addr_high = receiver_id;
	msg.opcode = ice_sbq_msg_rd;
	msg.dest_dev = rmn_0;
	msg.dest_dev = ice_sbq_dev_phy_0;

	err = ice_sbq_rw_reg(hw, &msg, flag);
	if (err)
@@ -4082,10 +4084,12 @@ int ice_get_phy_lane_number(struct ice_hw *hw)
			continue;

		if (hw->pf_id == lport) {
			if (hw->mac_type == ICE_MAC_GENERIC_3K_E825 &&
			    ice_is_dual(hw) && !ice_is_primary(hw))
				lane += ICE_PORTS_PER_QUAD;
			kfree(options);
			return lane;
		}

		lport++;
	}

@@ -6011,15 +6015,21 @@ bool ice_fw_supports_lldp_fltr_ctrl(struct ice_hw *hw)
/**
 * ice_lldp_fltr_add_remove - add or remove a LLDP Rx switch filter
 * @hw: pointer to HW struct
 * @vsi_num: absolute HW index for VSI
 * @vsi: VSI to add the filter to
 * @add: boolean for if adding or removing a filter
 *
 * Return: 0 on success, -EOPNOTSUPP if the operation cannot be performed
 *	   with this HW or VSI, otherwise an error corresponding to
 *	   the AQ transaction result.
 */
int
ice_lldp_fltr_add_remove(struct ice_hw *hw, u16 vsi_num, bool add)
int ice_lldp_fltr_add_remove(struct ice_hw *hw, struct ice_vsi *vsi, bool add)
{
	struct ice_aqc_lldp_filter_ctrl *cmd;
	struct ice_aq_desc desc;

	if (vsi->type != ICE_VSI_PF || !ice_fw_supports_lldp_fltr_ctrl(hw))
		return -EOPNOTSUPP;

	cmd = &desc.params.lldp_filter_ctrl;

	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_filter_ctrl);
@@ -6029,7 +6039,7 @@ ice_lldp_fltr_add_remove(struct ice_hw *hw, u16 vsi_num, bool add)
	else
		cmd->cmd_flags = ICE_AQC_LLDP_FILTER_ACTION_DELETE;

	cmd->vsi_num = cpu_to_le16(vsi_num);
	cmd->vsi_num = cpu_to_le16(vsi->vsi_num);

	return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
}
Loading