Commit 2e957f9c authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2024-01-03 (i40e, ice, igc)

This series contains updates to i40e, ice, and igc drivers.

Ke Xiao fixes use after free for unicast filters on i40e.

Andrii restores VF MSI-X flag after PCI reset on i40e.

Paul corrects admin queue link status structure to fulfill firmware
expectations for ice.

Rodrigo Cataldo corrects value used for hicredit calculations on igc.

* '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue:
  igc: Fix hicredit calculation
  ice: fix Get link status data length
  i40e: Restore VF MSI-X state during PCI reset
  i40e: fix use-after-free in i40e_aqc_add_filters()
====================

Link: https://lore.kernel.org/r/20240103193254.822968-1-anthony.l.nguyen@intel.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 382a3201 947dfc81
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -107,12 +107,18 @@ static struct workqueue_struct *i40e_wq;
static void netdev_hw_addr_refcnt(struct i40e_mac_filter *f,
				  struct net_device *netdev, int delta)
{
	struct netdev_hw_addr_list *ha_list;
	struct netdev_hw_addr *ha;

	if (!f || !netdev)
		return;

	netdev_for_each_mc_addr(ha, netdev) {
	if (is_unicast_ether_addr(f->macaddr) || is_link_local_ether_addr(f->macaddr))
		ha_list = &netdev->uc;
	else
		ha_list = &netdev->mc;

	netdev_hw_addr_list_for_each(ha, ha_list) {
		if (ether_addr_equal(ha->addr, f->macaddr)) {
			ha->refcount += delta;
			if (ha->refcount <= 0)
@@ -16512,6 +16518,9 @@ static void i40e_pci_error_reset_done(struct pci_dev *pdev)
		return;

	i40e_reset_and_rebuild(pf, false, false);
#ifdef CONFIG_PCI_IOV
	i40e_restore_all_vfs_msi_state(pdev);
#endif /* CONFIG_PCI_IOV */
}

/**
+26 −0
Original line number Diff line number Diff line
@@ -154,6 +154,32 @@ void i40e_vc_notify_reset(struct i40e_pf *pf)
			     (u8 *)&pfe, sizeof(struct virtchnl_pf_event));
}

#ifdef CONFIG_PCI_IOV
void i40e_restore_all_vfs_msi_state(struct pci_dev *pdev)
{
	u16 vf_id;
	u16 pos;

	/* Continue only if this is a PF */
	if (!pdev->is_physfn)
		return;

	if (!pci_num_vf(pdev))
		return;

	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
	if (pos) {
		struct pci_dev *vf_dev = NULL;

		pci_read_config_word(pdev, pos + PCI_SRIOV_VF_DID, &vf_id);
		while ((vf_dev = pci_get_device(pdev->vendor, vf_id, vf_dev))) {
			if (vf_dev->is_virtfn && vf_dev->physfn == pdev)
				pci_restore_msi_state(vf_dev);
		}
	}
}
#endif /* CONFIG_PCI_IOV */

/**
 * i40e_vc_notify_vf_reset
 * @vf: pointer to the VF structure
+3 −0
Original line number Diff line number Diff line
@@ -137,6 +137,9 @@ int i40e_ndo_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool enable);

void i40e_vc_notify_link_state(struct i40e_pf *pf);
void i40e_vc_notify_reset(struct i40e_pf *pf);
#ifdef CONFIG_PCI_IOV
void i40e_restore_all_vfs_msi_state(struct pci_dev *pdev);
#endif /* CONFIG_PCI_IOV */
int i40e_get_vf_stats(struct net_device *netdev, int vf_id,
		      struct ifla_vf_stats *vf_stats);

+2 −1
Original line number Diff line number Diff line
@@ -1359,8 +1359,9 @@ struct ice_aqc_get_link_status_data {
	u8 lp_flowcontrol;
#define ICE_AQ_LINK_LP_PAUSE_ADV       BIT(0)
#define ICE_AQ_LINK_LP_ASM_DIR_ADV     BIT(1)
	u8 reserved5[5];
#define ICE_AQC_LS_DATA_SIZE_V2 \
	offsetofend(struct ice_aqc_get_link_status_data, lp_flowcontrol)
	offsetofend(struct ice_aqc_get_link_status_data, reserved5)
} __packed;

/* Set event mask command (direct 0x0613) */
+1 −1
Original line number Diff line number Diff line
@@ -227,7 +227,7 @@ static int igc_tsn_enable_offload(struct igc_adapter *adapter)
			wr32(IGC_TQAVCC(i), tqavcc);

			wr32(IGC_TQAVHC(i),
			     0x80000000 + ring->hicredit * 0x7735);
			     0x80000000 + ring->hicredit * 0x7736);
		} else {
			/* Disable any CBS for the queue */
			txqctl &= ~(IGC_TXQCTL_QAV_SEL_MASK);