mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 14:33:24 -04:00
Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue
Tony Nguyen says: ==================== Intel Wired LAN Driver Updates 2026-08-11 (ice, idpf) For ice: Przemyslaw Korba adds a fallback path to utilize sideband queue when the low-latency PHY timer writes time out, likely, due to NVM updates or EMP resets. Petr Oros restores call to ice_clear_dflt_vsi() for the default VSI in ice_vsi_release() to ensure no stale rules are left in the device which can cause various issues. Robert Malz breaks NVM reads to occur under separate lock requests as large combined NVM reads can cause the NVM lock to be held longer than maximum allowed time and be reclaimed by firmware. For idpf: Willem de Bruijn fixes possible endian issue of descriptor by adding cpu_to_le32() call. * '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue: idpf: add missing cpu_to_le32 in idpf_tx_splitq_build_flow_desc ice: acquire NVM lock around each flash read ice: clear the default forwarding VSI rule when releasing a VSI ice: fall back to SBQ when LL PHY timer interface times out ==================== Link: https://patch.msgid.link/20260812000918.220714-1-anthony.l.nguyen@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -1890,27 +1890,18 @@ static int ice_devlink_nvm_snapshot(struct devlink *devlink,
|
||||
*/
|
||||
for (i = 0; i < num_blks; i++) {
|
||||
u32 read_sz = min_t(u32, ICE_DEVLINK_READ_BLK_SIZE, left);
|
||||
|
||||
status = ice_acquire_nvm(hw, ICE_RES_READ);
|
||||
if (status) {
|
||||
dev_dbg(dev, "ice_acquire_nvm failed, err %d aq_err %d\n",
|
||||
status, hw->adminq.sq_last_status);
|
||||
NL_SET_ERR_MSG_MOD(extack, "Failed to acquire NVM semaphore");
|
||||
vfree(nvm_data);
|
||||
return -EIO;
|
||||
}
|
||||
enum libie_aq_err read_aq_err = LIBIE_AQ_RC_OK;
|
||||
|
||||
status = ice_read_flat_nvm(hw, i * ICE_DEVLINK_READ_BLK_SIZE,
|
||||
&read_sz, tmp, read_shadow_ram);
|
||||
&read_sz, tmp, read_shadow_ram,
|
||||
&read_aq_err);
|
||||
if (status) {
|
||||
dev_dbg(dev, "ice_read_flat_nvm failed after reading %u bytes, err %d aq_err %d\n",
|
||||
read_sz, status, hw->adminq.sq_last_status);
|
||||
read_sz, status, read_aq_err);
|
||||
NL_SET_ERR_MSG_MOD(extack, "Failed to read NVM contents");
|
||||
ice_release_nvm(hw);
|
||||
vfree(nvm_data);
|
||||
return -EIO;
|
||||
}
|
||||
ice_release_nvm(hw);
|
||||
|
||||
tmp += read_sz;
|
||||
left -= read_sz;
|
||||
@@ -1943,6 +1934,7 @@ static int ice_devlink_nvm_read(struct devlink *devlink,
|
||||
struct netlink_ext_ack *extack,
|
||||
u64 offset, u32 size, u8 *data)
|
||||
{
|
||||
enum libie_aq_err read_aq_err = LIBIE_AQ_RC_OK;
|
||||
struct ice_pf *pf = devlink_priv(devlink);
|
||||
struct device *dev = ice_pf_to_dev(pf);
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
@@ -1966,24 +1958,14 @@ static int ice_devlink_nvm_read(struct devlink *devlink,
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
status = ice_acquire_nvm(hw, ICE_RES_READ);
|
||||
if (status) {
|
||||
dev_dbg(dev, "ice_acquire_nvm failed, err %d aq_err %d\n",
|
||||
status, hw->adminq.sq_last_status);
|
||||
NL_SET_ERR_MSG_MOD(extack, "Failed to acquire NVM semaphore");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
status = ice_read_flat_nvm(hw, (u32)offset, &size, data,
|
||||
read_shadow_ram);
|
||||
read_shadow_ram, &read_aq_err);
|
||||
if (status) {
|
||||
dev_dbg(dev, "ice_read_flat_nvm failed after reading %u bytes, err %d aq_err %d\n",
|
||||
size, status, hw->adminq.sq_last_status);
|
||||
size, status, read_aq_err);
|
||||
NL_SET_ERR_MSG_MOD(extack, "Failed to read NVM contents");
|
||||
ice_release_nvm(hw);
|
||||
return -EIO;
|
||||
}
|
||||
ice_release_nvm(hw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -853,6 +853,7 @@ static int
|
||||
ice_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
|
||||
u8 *bytes)
|
||||
{
|
||||
enum libie_aq_err read_aq_err = LIBIE_AQ_RC_OK;
|
||||
struct ice_pf *pf = ice_netdev_to_pf(netdev);
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
struct device *dev;
|
||||
@@ -869,24 +870,15 @@ ice_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = ice_acquire_nvm(hw, ICE_RES_READ);
|
||||
ret = ice_read_flat_nvm(hw, eeprom->offset, &eeprom->len, buf,
|
||||
false, &read_aq_err);
|
||||
if (ret) {
|
||||
dev_err(dev, "ice_acquire_nvm failed, err %d aq_err %s\n",
|
||||
ret, libie_aq_str(hw->adminq.sq_last_status));
|
||||
dev_err(dev, "ice_read_flat_nvm failed, err %d aq_err %s\n",
|
||||
ret, libie_aq_str(read_aq_err));
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ice_read_flat_nvm(hw, eeprom->offset, &eeprom->len, buf,
|
||||
false);
|
||||
if (ret) {
|
||||
dev_err(dev, "ice_read_flat_nvm failed, err %d aq_err %s\n",
|
||||
ret, libie_aq_str(hw->adminq.sq_last_status));
|
||||
goto release;
|
||||
}
|
||||
|
||||
memcpy(bytes, buf, eeprom->len);
|
||||
release:
|
||||
ice_release_nvm(hw);
|
||||
out:
|
||||
kfree(buf);
|
||||
return ret;
|
||||
|
||||
@@ -2871,6 +2871,9 @@ int ice_vsi_release(struct ice_vsi *vsi)
|
||||
return -ENODEV;
|
||||
pf = vsi->back;
|
||||
|
||||
if (ice_is_vsi_dflt_vsi(vsi))
|
||||
ice_clear_dflt_vsi(vsi);
|
||||
|
||||
if (test_bit(ICE_FLAG_RSS_ENA, pf->flags))
|
||||
ice_rss_clean(vsi);
|
||||
|
||||
|
||||
@@ -53,17 +53,27 @@ int ice_aq_read_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset,
|
||||
* @length: (in) number of bytes to read; (out) number of bytes actually read
|
||||
* @data: buffer to return data in (sized to fit the specified length)
|
||||
* @read_shadow_ram: if true, read from shadow RAM instead of NVM
|
||||
* @read_aq_err: if non-NULL, receives the AQ error status of the failing read
|
||||
*
|
||||
* Reads a portion of the NVM, as a flat memory space. This function correctly
|
||||
* breaks read requests across Shadow RAM sectors and ensures that no single
|
||||
* read request exceeds the maximum 4KB read for a single AdminQ command.
|
||||
*
|
||||
* FW caps the read lock at a maximum of 3000ms, so a read spanning multiple
|
||||
* 4KB sectors cannot be done under a single lock without FW reclaiming it
|
||||
* mid-read. The NVM lock is therefore acquired and released around each AQ
|
||||
* read, so this function must be called without the lock held.
|
||||
*
|
||||
* Since ice_release_nvm() issues an AQ command that overwrites
|
||||
* hw->adminq.sq_last_status, callers that need the failing read's AQ error
|
||||
* must use @read_aq_err rather than inspecting sq_last_status afterwards.
|
||||
*
|
||||
* Returns a status code on failure. Note that the data pointer may be
|
||||
* partially updated if some reads succeed before a failure.
|
||||
*/
|
||||
int
|
||||
ice_read_flat_nvm(struct ice_hw *hw, u32 offset, u32 *length, u8 *data,
|
||||
bool read_shadow_ram)
|
||||
bool read_shadow_ram, enum libie_aq_err *read_aq_err)
|
||||
{
|
||||
u32 inlen = *length;
|
||||
u32 bytes_read = 0;
|
||||
@@ -92,12 +102,30 @@ ice_read_flat_nvm(struct ice_hw *hw, u32 offset, u32 *length, u8 *data,
|
||||
|
||||
last_cmd = !(bytes_read + read_size < inlen);
|
||||
|
||||
status = ice_acquire_nvm(hw, ICE_RES_READ);
|
||||
if (status) {
|
||||
ice_debug(hw, ICE_DBG_NVM, "Failed to acquire NVM lock, err %d aq_err %s\n",
|
||||
status, libie_aq_str(hw->adminq.sq_last_status));
|
||||
break;
|
||||
}
|
||||
|
||||
status = ice_aq_read_nvm(hw, ICE_AQC_NVM_START_POINT,
|
||||
offset, read_size,
|
||||
data + bytes_read, last_cmd,
|
||||
read_shadow_ram, NULL);
|
||||
if (status)
|
||||
if (status) {
|
||||
/* Capture the read's AQ error before ice_release_nvm()
|
||||
* issues its own AQ command and overwrites
|
||||
* sq_last_status.
|
||||
*/
|
||||
if (read_aq_err)
|
||||
*read_aq_err = hw->adminq.sq_last_status;
|
||||
|
||||
ice_release_nvm(hw);
|
||||
break;
|
||||
}
|
||||
|
||||
ice_release_nvm(hw);
|
||||
|
||||
bytes_read += read_size;
|
||||
offset += read_size;
|
||||
@@ -177,14 +205,19 @@ int ice_aq_erase_nvm(struct ice_hw *hw, u16 module_typeid, struct ice_sq_cd *cd)
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_read_sr_word_aq - Reads Shadow RAM via AQ
|
||||
* ice_read_sr_word - Reads Shadow RAM word
|
||||
* @hw: pointer to the HW structure
|
||||
* @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
|
||||
* @data: word read from the Shadow RAM
|
||||
*
|
||||
* Reads one 16 bit word from the Shadow RAM using ice_read_flat_nvm.
|
||||
*
|
||||
* The NVM lock is acquired and released internally by ice_read_flat_nvm()
|
||||
* around the FW read, so this function must be called without the lock held.
|
||||
*
|
||||
* Return: zero on success, or a negative error code on failure.
|
||||
*/
|
||||
static int ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data)
|
||||
int ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
|
||||
{
|
||||
u32 bytes = sizeof(u16);
|
||||
__le16 data_local;
|
||||
@@ -194,7 +227,7 @@ static int ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data)
|
||||
* Shadow RAM sector restrictions necessary when reading from the NVM.
|
||||
*/
|
||||
status = ice_read_flat_nvm(hw, offset * sizeof(u16), &bytes,
|
||||
(__force u8 *)&data_local, true);
|
||||
(__force u8 *)&data_local, true, NULL);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
@@ -330,13 +363,8 @@ ice_read_flash_module(struct ice_hw *hw, enum ice_bank_select bank, u16 module,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
status = ice_acquire_nvm(hw, ICE_RES_READ);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = ice_read_flat_nvm(hw, start + offset, &length, data, false);
|
||||
|
||||
ice_release_nvm(hw);
|
||||
status = ice_read_flat_nvm(hw, start + offset, &length, data, false,
|
||||
NULL);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -418,27 +446,6 @@ ice_read_netlist_module(struct ice_hw *hw, enum ice_bank_select bank, u32 offset
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_read_sr_word - Reads Shadow RAM word and acquire NVM if necessary
|
||||
* @hw: pointer to the HW structure
|
||||
* @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
|
||||
* @data: word read from the Shadow RAM
|
||||
*
|
||||
* Reads one 16 bit word from the Shadow RAM using the ice_read_sr_word_aq.
|
||||
*/
|
||||
int ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = ice_acquire_nvm(hw, ICE_RES_READ);
|
||||
if (!status) {
|
||||
status = ice_read_sr_word_aq(hw, offset, data);
|
||||
ice_release_nvm(hw);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_get_pfa_module_tlv - Reads sub module TLV from NVM PFA
|
||||
* @hw: pointer to hardware structure
|
||||
@@ -856,20 +863,18 @@ int ice_get_inactive_netlist_ver(struct ice_hw *hw, struct ice_netlist_info *net
|
||||
static int ice_discover_flash_size(struct ice_hw *hw)
|
||||
{
|
||||
u32 min_size = 0, max_size = ICE_AQC_NVM_MAX_OFFSET + 1;
|
||||
int status;
|
||||
|
||||
status = ice_acquire_nvm(hw, ICE_RES_READ);
|
||||
if (status)
|
||||
return status;
|
||||
int status = 0;
|
||||
|
||||
while ((max_size - min_size) > 1) {
|
||||
enum libie_aq_err read_aq_err = LIBIE_AQ_RC_OK;
|
||||
u32 offset = (max_size + min_size) / 2;
|
||||
u32 len = 1;
|
||||
u8 data;
|
||||
|
||||
status = ice_read_flat_nvm(hw, offset, &len, &data, false);
|
||||
status = ice_read_flat_nvm(hw, offset, &len, &data, false,
|
||||
&read_aq_err);
|
||||
if (status == -EIO &&
|
||||
hw->adminq.sq_last_status == LIBIE_AQ_RC_EINVAL) {
|
||||
read_aq_err == LIBIE_AQ_RC_EINVAL) {
|
||||
ice_debug(hw, ICE_DBG_NVM, "%s: New upper bound of %u bytes\n",
|
||||
__func__, offset);
|
||||
status = 0;
|
||||
@@ -880,7 +885,7 @@ static int ice_discover_flash_size(struct ice_hw *hw)
|
||||
min_size = offset;
|
||||
} else {
|
||||
/* an unexpected error occurred */
|
||||
goto err_read_flat_nvm;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -888,9 +893,6 @@ static int ice_discover_flash_size(struct ice_hw *hw)
|
||||
|
||||
hw->flash.flash_size = max_size;
|
||||
|
||||
err_read_flat_nvm:
|
||||
ice_release_nvm(hw);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ int ice_aq_read_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset,
|
||||
bool read_shadow_ram, struct ice_sq_cd *cd);
|
||||
int
|
||||
ice_read_flat_nvm(struct ice_hw *hw, u32 offset, u32 *length, u8 *data,
|
||||
bool read_shadow_ram);
|
||||
bool read_shadow_ram, enum libie_aq_err *read_aq_err);
|
||||
int
|
||||
ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len,
|
||||
u16 module_type);
|
||||
|
||||
@@ -4808,15 +4808,12 @@ static int ice_ptp_prep_phy_adj_ll_e810(struct ice_hw *hw, s32 adj)
|
||||
!FIELD_GET(REG_LL_PROXY_H_EXEC, val),
|
||||
10, REG_LL_PROXY_H_TIMEOUT_US, false, hw,
|
||||
REG_LL_PROXY_H);
|
||||
if (err) {
|
||||
ice_debug(hw, ICE_DBG_PTP, "Failed to prepare PHY timer adjustment using low latency interface\n");
|
||||
spin_unlock_irq(¶ms->atqbal_wq.lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
spin_unlock_irq(¶ms->atqbal_wq.lock);
|
||||
|
||||
return 0;
|
||||
if (err)
|
||||
ice_debug(hw, ICE_DBG_PTP, "Failed to prepare PHY timer adjustment using low latency interface\n");
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4837,8 +4834,12 @@ static int ice_ptp_prep_phy_adj_e810(struct ice_hw *hw, s32 adj)
|
||||
u8 tmr_idx;
|
||||
int err;
|
||||
|
||||
if (hw->dev_caps.ts_dev_info.ll_phy_tmr_update)
|
||||
return ice_ptp_prep_phy_adj_ll_e810(hw, adj);
|
||||
if (hw->dev_caps.ts_dev_info.ll_phy_tmr_update) {
|
||||
err = ice_ptp_prep_phy_adj_ll_e810(hw, adj);
|
||||
if (err != -ETIMEDOUT)
|
||||
return err;
|
||||
ice_debug(hw, ICE_DBG_PTP, "LL adj timed out, falling back to SBQ\n");
|
||||
}
|
||||
|
||||
tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
|
||||
|
||||
@@ -4901,15 +4902,12 @@ static int ice_ptp_prep_phy_incval_ll_e810(struct ice_hw *hw, u64 incval)
|
||||
!FIELD_GET(REG_LL_PROXY_H_EXEC, val),
|
||||
10, REG_LL_PROXY_H_TIMEOUT_US, false, hw,
|
||||
REG_LL_PROXY_H);
|
||||
if (err) {
|
||||
ice_debug(hw, ICE_DBG_PTP, "Failed to prepare PHY timer increment using low latency interface\n");
|
||||
spin_unlock_irq(¶ms->atqbal_wq.lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
spin_unlock_irq(¶ms->atqbal_wq.lock);
|
||||
|
||||
return 0;
|
||||
if (err)
|
||||
ice_debug(hw, ICE_DBG_PTP, "Failed to prepare PHY timer increment using low latency interface\n");
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4927,8 +4925,12 @@ static int ice_ptp_prep_phy_incval_e810(struct ice_hw *hw, u64 incval)
|
||||
u8 tmr_idx;
|
||||
int err;
|
||||
|
||||
if (hw->dev_caps.ts_dev_info.ll_phy_tmr_update)
|
||||
return ice_ptp_prep_phy_incval_ll_e810(hw, incval);
|
||||
if (hw->dev_caps.ts_dev_info.ll_phy_tmr_update) {
|
||||
err = ice_ptp_prep_phy_incval_ll_e810(hw, incval);
|
||||
if (err != -ETIMEDOUT)
|
||||
return err;
|
||||
ice_debug(hw, ICE_DBG_PTP, "LL incval timed out, falling back to SBQ\n");
|
||||
}
|
||||
|
||||
tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
|
||||
low = lower_32_bits(incval);
|
||||
|
||||
@@ -2408,7 +2408,7 @@ void idpf_tx_splitq_build_flow_desc(union idpf_tx_flex_desc *desc,
|
||||
struct idpf_tx_splitq_params *params,
|
||||
u16 td_cmd, u16 size)
|
||||
{
|
||||
*(u32 *)&desc->flow.qw1.cmd_dtype = (u8)(params->dtype | td_cmd);
|
||||
*(__le32 *)&desc->flow.qw1.cmd_dtype = cpu_to_le32((u8)(params->dtype | td_cmd));
|
||||
desc->flow.qw1.rxr_bufsize = cpu_to_le16((u16)size);
|
||||
desc->flow.qw1.compl_tag = cpu_to_le16(params->compl_tag);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user