Commit 096c0fa4 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2024-09-30 (ice, idpf)

This series contains updates to ice and idpf drivers:

For ice:

Michal corrects setting of dst VSI on LAN filters and adds clearing of
port VLAN configuration during reset.

Gui-Dong Han corrects failures to decrement refcount in some error
paths.

Przemek resolves a memory leak in ice_init_tx_topology().

Arkadiusz prevents setting of DPLL_PIN_STATE_SELECTABLE to an improper
value.

Dave stops clearing of VLAN tracking bit to allow for VLANs to be properly
restored after reset.

For idpf:

Ahmed sets uninitialized dyn_ctl_intrvl_s value.

Josh corrects use and reporting of mailbox size.

Larysa corrects order of function calls during de-initialization.

* '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue:
  idpf: deinit virtchnl transaction manager after vport and vectors
  idpf: use actual mbx receive payload length
  idpf: fix VF dynamic interrupt ctl register initialization
  ice: fix VLAN replay after reset
  ice: disallow DPLL_PIN_STATE_SELECTABLE for dpll output pins
  ice: fix memleak in ice_init_tx_topology()
  ice: clear port vlan config during reset
  ice: Fix improper handling of refcount in ice_sriov_set_msix_vec_count()
  ice: Fix improper handling of refcount in ice_dpll_init_rclk_pins()
  ice: set correct dst VSI in only LAN filters
====================

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


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 2d7a098b 09d0fb5c
Loading
Loading
Loading
Loading
+28 −30
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ static const struct ice_tunnel_type_scan tnls[] = {
 * Verifies various attributes of the package file, including length, format
 * version, and the requirement of at least one segment.
 */
static enum ice_ddp_state ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len)
static enum ice_ddp_state ice_verify_pkg(const struct ice_pkg_hdr *pkg, u32 len)
{
	u32 seg_count;
	u32 i;
@@ -57,13 +57,13 @@ static enum ice_ddp_state ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len)
	/* all segments must fit within length */
	for (i = 0; i < seg_count; i++) {
		u32 off = le32_to_cpu(pkg->seg_offset[i]);
		struct ice_generic_seg_hdr *seg;
		const struct ice_generic_seg_hdr *seg;

		/* segment header must fit */
		if (len < off + sizeof(*seg))
			return ICE_DDP_PKG_INVALID_FILE;

		seg = (struct ice_generic_seg_hdr *)((u8 *)pkg + off);
		seg = (void *)pkg + off;

		/* segment body must fit */
		if (len < off + le32_to_cpu(seg->seg_size))
@@ -119,13 +119,13 @@ static enum ice_ddp_state ice_chk_pkg_version(struct ice_pkg_ver *pkg_ver)
 *
 * This helper function validates a buffer's header.
 */
static struct ice_buf_hdr *ice_pkg_val_buf(struct ice_buf *buf)
static const struct ice_buf_hdr *ice_pkg_val_buf(const struct ice_buf *buf)
{
	struct ice_buf_hdr *hdr;
	const struct ice_buf_hdr *hdr;
	u16 section_count;
	u16 data_end;

	hdr = (struct ice_buf_hdr *)buf->buf;
	hdr = (const struct ice_buf_hdr *)buf->buf;
	/* verify data */
	section_count = le16_to_cpu(hdr->section_count);
	if (section_count < ICE_MIN_S_COUNT || section_count > ICE_MAX_S_COUNT)
@@ -165,7 +165,7 @@ static struct ice_buf_table *ice_find_buf_table(struct ice_seg *ice_seg)
 * unexpected value has been detected (for example an invalid section count or
 * an invalid buffer end value).
 */
static struct ice_buf_hdr *ice_pkg_enum_buf(struct ice_seg *ice_seg,
static const struct ice_buf_hdr *ice_pkg_enum_buf(struct ice_seg *ice_seg,
						  struct ice_pkg_enum *state)
{
	if (ice_seg) {
@@ -1800,9 +1800,9 @@ int ice_update_pkg(struct ice_hw *hw, struct ice_buf *bufs, u32 count)
 * success it returns a pointer to the segment header, otherwise it will
 * return NULL.
 */
static struct ice_generic_seg_hdr *
static const struct ice_generic_seg_hdr *
ice_find_seg_in_pkg(struct ice_hw *hw, u32 seg_type,
		    struct ice_pkg_hdr *pkg_hdr)
		    const struct ice_pkg_hdr *pkg_hdr)
{
	u32 i;

@@ -1813,11 +1813,9 @@ ice_find_seg_in_pkg(struct ice_hw *hw, u32 seg_type,

	/* Search all package segments for the requested segment type */
	for (i = 0; i < le32_to_cpu(pkg_hdr->seg_count); i++) {
		struct ice_generic_seg_hdr *seg;
		const struct ice_generic_seg_hdr *seg;

		seg = (struct ice_generic_seg_hdr
			       *)((u8 *)pkg_hdr +
				  le32_to_cpu(pkg_hdr->seg_offset[i]));
		seg = (void *)pkg_hdr + le32_to_cpu(pkg_hdr->seg_offset[i]);

		if (le32_to_cpu(seg->seg_type) == seg_type)
			return seg;
@@ -2354,12 +2352,12 @@ ice_get_set_tx_topo(struct ice_hw *hw, u8 *buf, u16 buf_size,
 *
 * Return: zero when update was successful, negative values otherwise.
 */
int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len)
int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)
{
	u8 *current_topo, *new_topo = NULL;
	struct ice_run_time_cfg_seg *seg;
	struct ice_buf_hdr *section;
	struct ice_pkg_hdr *pkg_hdr;
	u8 *new_topo = NULL, *topo __free(kfree) = NULL;
	const struct ice_run_time_cfg_seg *seg;
	const struct ice_buf_hdr *section;
	const struct ice_pkg_hdr *pkg_hdr;
	enum ice_ddp_state state;
	u16 offset, size = 0;
	u32 reg = 0;
@@ -2375,15 +2373,13 @@ int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len)
		return -EOPNOTSUPP;
	}

	current_topo = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL);
	if (!current_topo)
	topo = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL);
	if (!topo)
		return -ENOMEM;

	/* Get the current Tx topology */
	status = ice_get_set_tx_topo(hw, current_topo, ICE_AQ_MAX_BUF_LEN, NULL,
				     &flags, false);

	kfree(current_topo);
	/* Get the current Tx topology flags */
	status = ice_get_set_tx_topo(hw, topo, ICE_AQ_MAX_BUF_LEN, NULL, &flags,
				     false);

	if (status) {
		ice_debug(hw, ICE_DBG_INIT, "Get current topology is failed\n");
@@ -2419,7 +2415,7 @@ int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len)
		goto update_topo;
	}

	pkg_hdr = (struct ice_pkg_hdr *)buf;
	pkg_hdr = (const struct ice_pkg_hdr *)buf;
	state = ice_verify_pkg(pkg_hdr, len);
	if (state) {
		ice_debug(hw, ICE_DBG_INIT, "Failed to verify pkg (err: %d)\n",
@@ -2428,7 +2424,7 @@ int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len)
	}

	/* Find runtime configuration segment */
	seg = (struct ice_run_time_cfg_seg *)
	seg = (const struct ice_run_time_cfg_seg *)
	      ice_find_seg_in_pkg(hw, SEGMENT_TYPE_ICE_RUN_TIME_CFG, pkg_hdr);
	if (!seg) {
		ice_debug(hw, ICE_DBG_INIT, "5 layer topology segment is missing\n");
@@ -2461,8 +2457,10 @@ int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len)
		return -EIO;
	}

	/* Get the new topology buffer */
	new_topo = ((u8 *)section) + offset;
	/* Get the new topology buffer, reuse current topo copy mem */
	static_assert(ICE_PKG_BUF_SIZE == ICE_AQ_MAX_BUF_LEN);
	new_topo = topo;
	memcpy(new_topo, (u8 *)section + offset, size);

update_topo:
	/* Acquire global lock to make sure that set topology issued
+2 −2
Original line number Diff line number Diff line
@@ -438,7 +438,7 @@ struct ice_pkg_enum {
	u32 buf_idx;

	u32 type;
	struct ice_buf_hdr *buf;
	const struct ice_buf_hdr *buf;
	u32 sect_idx;
	void *sect;
	u32 sect_type;
@@ -467,6 +467,6 @@ ice_pkg_enum_entry(struct ice_seg *ice_seg, struct ice_pkg_enum *state,
void *ice_pkg_enum_section(struct ice_seg *ice_seg, struct ice_pkg_enum *state,
			   u32 sect_type);

int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len);
int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len);

#endif
+4 −2
Original line number Diff line number Diff line
@@ -656,6 +656,8 @@ ice_dpll_output_state_set(const struct dpll_pin *pin, void *pin_priv,
	struct ice_dpll_pin *p = pin_priv;
	struct ice_dpll *d = dpll_priv;

	if (state == DPLL_PIN_STATE_SELECTABLE)
		return -EINVAL;
	if (!enable && p->state[d->dpll_idx] == DPLL_PIN_STATE_DISCONNECTED)
		return 0;

@@ -1843,6 +1845,8 @@ ice_dpll_init_rclk_pins(struct ice_pf *pf, struct ice_dpll_pin *pin,
	struct dpll_pin *parent;
	int ret, i;

	if (WARN_ON((!vsi || !vsi->netdev)))
		return -EINVAL;
	ret = ice_dpll_get_pins(pf, pin, start_idx, ICE_DPLL_RCLK_NUM_PER_PF,
				pf->dplls.clock_id);
	if (ret)
@@ -1858,8 +1862,6 @@ ice_dpll_init_rclk_pins(struct ice_pf *pf, struct ice_dpll_pin *pin,
		if (ret)
			goto unregister_pins;
	}
	if (WARN_ON((!vsi || !vsi->netdev)))
		return -EINVAL;
	dpll_netdev_pin_set(vsi->netdev, pf->dplls.rclk.pin);

	return 0;
+1 −7
Original line number Diff line number Diff line
@@ -4536,16 +4536,10 @@ ice_init_tx_topology(struct ice_hw *hw, const struct firmware *firmware)
	u8 num_tx_sched_layers = hw->num_tx_sched_layers;
	struct ice_pf *pf = hw->back;
	struct device *dev;
	u8 *buf_copy;
	int err;

	dev = ice_pf_to_dev(pf);
	/* ice_cfg_tx_topo buf argument is not a constant,
	 * so we have to make a copy
	 */
	buf_copy = kmemdup(firmware->data, firmware->size, GFP_KERNEL);

	err = ice_cfg_tx_topo(hw, buf_copy, firmware->size);
	err = ice_cfg_tx_topo(hw, firmware->data, firmware->size);
	if (!err) {
		if (hw->num_tx_sched_layers > num_tx_sched_layers)
			dev_info(dev, "Tx scheduling layers switching feature disabled\n");
+6 −2
Original line number Diff line number Diff line
@@ -1096,8 +1096,10 @@ int ice_sriov_set_msix_vec_count(struct pci_dev *vf_dev, int msix_vec_count)
		return -ENOENT;

	vsi = ice_get_vf_vsi(vf);
	if (!vsi)
	if (!vsi) {
		ice_put_vf(vf);
		return -ENOENT;
	}

	prev_msix = vf->num_msix;
	prev_queues = vf->num_vf_qs;
@@ -1142,8 +1144,10 @@ int ice_sriov_set_msix_vec_count(struct pci_dev *vf_dev, int msix_vec_count)
	vf->num_msix = prev_msix;
	vf->num_vf_qs = prev_queues;
	vf->first_vector_idx = ice_sriov_get_irqs(pf, vf->num_msix);
	if (vf->first_vector_idx < 0)
	if (vf->first_vector_idx < 0) {
		ice_put_vf(vf);
		return -EINVAL;
	}

	if (needs_rebuild) {
		ice_vf_reconfig_vsi(vf);
Loading