Skip to content

Commit

Permalink
Merge branch '1GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/…
Browse files Browse the repository at this point in the history
…tnguy/next-queue

Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2024-08-30 (igc, e1000e, i40e)

This series contains updates to igc, e1000e, and i40 drivers.

Kurt Kanzenbach adds support for MQPRIO offloads and stops unintended,
excess interrupts on igc.

Sasha adds reporting of EEE (Energy Efficient Ethernet) ability and
moves a register define to a better suited file for igc.

Vitaly stops reporting errors on shutdown and suspend as they are not
fatal for e1000e.

Alex adds reporting of EEE to i40e.

* '1GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
  i40e: Add Energy Efficient Ethernet ability for X710 Base-T/KR/KX cards
  e1000e: avoid failing the system during pm_suspend
  igc: Move the MULTI GBT AN Control Register to _regs file
  igc: Add Energy Efficient Ethernet ability
  igc: Get rid of spurious interrupts
  igc: Add MQPRIO offload support
====================

Link: https://patch.msgid.link/20240830210451.2375215-1-anthony.l.nguyen@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Sep 3, 2024
2 parents 7f85b11 + 0568ee1 commit 3bbefbb
Show file tree
Hide file tree
Showing 11 changed files with 347 additions and 25 deletions.
19 changes: 11 additions & 8 deletions drivers/net/ethernet/intel/e1000e/netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -6671,8 +6671,10 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
/* enable wakeup by the PHY */
retval = e1000_init_phy_wakeup(adapter, wufc);
if (retval)
return retval;
if (retval) {
e_err("Failed to enable wakeup\n");
goto skip_phy_configurations;
}
} else {
/* enable wakeup by the MAC */
ew32(WUFC, wufc);
Expand All @@ -6693,8 +6695,10 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
* or broadcast.
*/
retval = e1000_enable_ulp_lpt_lp(hw, !runtime);
if (retval)
return retval;
if (retval) {
e_err("Failed to enable ULP\n");
goto skip_phy_configurations;
}
}
}

Expand Down Expand Up @@ -6726,6 +6730,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
hw->phy.ops.release(hw);
}

skip_phy_configurations:
/* Release control of h/w to f/w. If f/w is AMT enabled, this
* would have already happened in close and is redundant.
*/
Expand Down Expand Up @@ -6968,15 +6973,13 @@ static int e1000e_pm_suspend(struct device *dev)
e1000e_pm_freeze(dev);

rc = __e1000_shutdown(pdev, false);
if (rc) {
e1000e_pm_thaw(dev);
} else {
if (!rc) {
/* Introduce S0ix implementation */
if (adapter->flags2 & FLAG2_ENABLE_S0IX_FLOWS)
e1000e_s0ix_entry_flow(adapter);
}

return rc;
return 0;
}

static int e1000e_pm_resume(struct device *dev)
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/i40e/i40e.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#ifndef _I40E_H_
#define _I40E_H_

#include <linux/linkmode.h>
#include <linux/pci.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/types.h>
Expand Down
36 changes: 32 additions & 4 deletions drivers/net/ethernet/intel/i40e/i40e_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -5641,14 +5641,34 @@ static int i40e_get_module_eeprom(struct net_device *netdev,
return 0;
}

static void i40e_eee_capability_to_kedata_supported(__le16 eee_capability_,
unsigned long *supported)
{
const int eee_capability = le16_to_cpu(eee_capability_);
static const int lut[] = {
ETHTOOL_LINK_MODE_100baseT_Full_BIT,
ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
};

linkmode_zero(supported);
for (unsigned int i = ARRAY_SIZE(lut); i--; )
if (eee_capability & BIT(i + 1))
linkmode_set_bit(lut[i], supported);
}

static int i40e_get_eee(struct net_device *netdev, struct ethtool_keee *edata)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_aq_get_phy_abilities_resp phy_cfg;
struct i40e_vsi *vsi = np->vsi;
struct i40e_pf *pf = vsi->back;
struct i40e_hw *hw = &pf->hw;
int status = 0;
int status;

/* Get initial PHY capabilities */
status = i40e_aq_get_phy_capabilities(hw, false, true, &phy_cfg, NULL);
Expand All @@ -5661,11 +5681,18 @@ static int i40e_get_eee(struct net_device *netdev, struct ethtool_keee *edata)
if (phy_cfg.eee_capability == 0)
return -EOPNOTSUPP;

i40e_eee_capability_to_kedata_supported(phy_cfg.eee_capability,
edata->supported);
linkmode_copy(edata->lp_advertised, edata->supported);

/* Get current configuration */
status = i40e_aq_get_phy_capabilities(hw, false, false, &phy_cfg, NULL);
if (status)
return -EAGAIN;

linkmode_zero(edata->advertised);
if (phy_cfg.eee_capability)
linkmode_copy(edata->advertised, edata->supported);
edata->eee_enabled = !!phy_cfg.eee_capability;
edata->tx_lpi_enabled = pf->stats.tx_lpi_status;

Expand All @@ -5681,10 +5708,11 @@ static int i40e_is_eee_param_supported(struct net_device *netdev,
struct i40e_vsi *vsi = np->vsi;
struct i40e_pf *pf = vsi->back;
struct i40e_ethtool_not_used {
u32 value;
bool value;
const char *name;
} param[] = {
{edata->tx_lpi_timer, "tx-timer"},
{!!(edata->advertised[0] & ~edata->supported[0]), "advertise"},
{!!edata->tx_lpi_timer, "tx-timer"},
{edata->tx_lpi_enabled != pf->stats.tx_lpi_status, "tx-lpi"}
};
int i;
Expand All @@ -5710,7 +5738,7 @@ static int i40e_set_eee(struct net_device *netdev, struct ethtool_keee *edata)
struct i40e_pf *pf = vsi->back;
struct i40e_hw *hw = &pf->hw;
__le16 eee_capability;
int status = 0;
int status;

/* Deny parameters we don't support */
if (i40e_is_eee_param_supported(netdev, edata))
Expand Down
24 changes: 21 additions & 3 deletions drivers/net/ethernet/intel/i40e/i40e_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7264,6 +7264,26 @@ static int i40e_init_pf_dcb(struct i40e_pf *pf)
}
#endif /* CONFIG_I40E_DCB */

static void i40e_print_link_message_eee(struct i40e_vsi *vsi,
const char *speed, const char *fc)
{
struct ethtool_keee kedata;

memzero_explicit(&kedata, sizeof(kedata));
if (vsi->netdev->ethtool_ops->get_eee)
vsi->netdev->ethtool_ops->get_eee(vsi->netdev, &kedata);

if (!linkmode_empty(kedata.supported))
netdev_info(vsi->netdev,
"NIC Link is Up, %sbps Full Duplex, Flow Control: %s, EEE: %s\n",
speed, fc,
kedata.eee_enabled ? "Enabled" : "Disabled");
else
netdev_info(vsi->netdev,
"NIC Link is Up, %sbps Full Duplex, Flow Control: %s\n",
speed, fc);
}

/**
* i40e_print_link_message - print link up or down
* @vsi: the VSI for which link needs a message
Expand Down Expand Up @@ -7395,9 +7415,7 @@ void i40e_print_link_message(struct i40e_vsi *vsi, bool isup)
"NIC Link is Up, %sbps Full Duplex, Requested FEC: %s, Negotiated FEC: %s, Autoneg: %s, Flow Control: %s\n",
speed, req_fec, fec, an, fc);
} else {
netdev_info(vsi->netdev,
"NIC Link is Up, %sbps Full Duplex, Flow Control: %s\n",
speed, fc);
i40e_print_link_message_eee(vsi, speed, fc);
}

}
Expand Down
11 changes: 9 additions & 2 deletions drivers/net/ethernet/intel/igc/igc.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,10 @@ struct igc_adapter {
*/
spinlock_t qbv_tx_lock;

bool strict_priority_enable;
u8 num_tc;
u16 queue_per_tc[IGC_MAX_TX_QUEUES];

/* OS defined structs */
struct pci_dev *pdev;
/* lock for statistics */
Expand Down Expand Up @@ -382,9 +386,11 @@ extern char igc_driver_name[];
#define IGC_FLAG_RX_LEGACY BIT(16)
#define IGC_FLAG_TSN_QBV_ENABLED BIT(17)
#define IGC_FLAG_TSN_QAV_ENABLED BIT(18)
#define IGC_FLAG_TSN_LEGACY_ENABLED BIT(19)

#define IGC_FLAG_TSN_ANY_ENABLED \
(IGC_FLAG_TSN_QBV_ENABLED | IGC_FLAG_TSN_QAV_ENABLED)
#define IGC_FLAG_TSN_ANY_ENABLED \
(IGC_FLAG_TSN_QBV_ENABLED | IGC_FLAG_TSN_QAV_ENABLED | \
IGC_FLAG_TSN_LEGACY_ENABLED)

#define IGC_FLAG_RSS_FIELD_IPV4_UDP BIT(6)
#define IGC_FLAG_RSS_FIELD_IPV6_UDP BIT(7)
Expand Down Expand Up @@ -681,6 +687,7 @@ enum igc_ring_flags_t {
IGC_RING_FLAG_TX_DETECT_HANG,
IGC_RING_FLAG_AF_XDP_ZC,
IGC_RING_FLAG_TX_HWTSTAMP,
IGC_RING_FLAG_RX_ALLOC_FAILED,
};

#define ring_uses_large_buffer(ring) \
Expand Down
22 changes: 21 additions & 1 deletion drivers/net/ethernet/intel/igc/igc_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#ifndef _IGC_DEFINES_H_
#define _IGC_DEFINES_H_

#include <linux/bitfield.h>

/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
#define REQ_TX_DESCRIPTOR_MULTIPLE 8
#define REQ_RX_DESCRIPTOR_MULTIPLE 8
Expand Down Expand Up @@ -176,7 +178,6 @@

/* PHY GPY 211 registers */
#define STANDARD_AN_REG_MASK 0x0007 /* MMD */
#define ANEG_MULTIGBT_AN_CTRL 0x0020 /* MULTI GBT AN Control Register */
#define MMD_DEVADDR_SHIFT 16 /* Shift MMD to higher bits */
#define CR_2500T_FD_CAPS 0x0080 /* Advertise 2500T FD capability */

Expand Down Expand Up @@ -553,6 +554,15 @@

#define IGC_MAX_SR_QUEUES 2

#define IGC_TXARB_TXQ_PRIO_0_MASK GENMASK(1, 0)
#define IGC_TXARB_TXQ_PRIO_1_MASK GENMASK(3, 2)
#define IGC_TXARB_TXQ_PRIO_2_MASK GENMASK(5, 4)
#define IGC_TXARB_TXQ_PRIO_3_MASK GENMASK(7, 6)
#define IGC_TXARB_TXQ_PRIO_0(x) FIELD_PREP(IGC_TXARB_TXQ_PRIO_0_MASK, (x))
#define IGC_TXARB_TXQ_PRIO_1(x) FIELD_PREP(IGC_TXARB_TXQ_PRIO_1_MASK, (x))
#define IGC_TXARB_TXQ_PRIO_2(x) FIELD_PREP(IGC_TXARB_TXQ_PRIO_2_MASK, (x))
#define IGC_TXARB_TXQ_PRIO_3(x) FIELD_PREP(IGC_TXARB_TXQ_PRIO_3_MASK, (x))

/* Receive Checksum Control */
#define IGC_RXCSUM_CRCOFL 0x00000800 /* CRC32 offload enable */
#define IGC_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
Expand Down Expand Up @@ -641,6 +651,16 @@
#define IGC_MDIC_READY 0x10000000
#define IGC_MDIC_ERROR 0x40000000

/* EEE Link Ability */
#define IGC_EEE_2500BT_MASK BIT(0)
#define IGC_EEE_1000BT_MASK BIT(2)
#define IGC_EEE_100BT_MASK BIT(1)

/* EEE Link-Partner Ability */
#define IGC_LP_EEE_2500BT_MASK BIT(0)
#define IGC_LP_EEE_1000BT_MASK BIT(2)
#define IGC_LP_EEE_100BT_MASK BIT(1)

#define IGC_N0_QUEUE -1

#define IGC_MAX_MAC_HDR_LEN 127
Expand Down
77 changes: 76 additions & 1 deletion drivers/net/ethernet/intel/igc/igc_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -1540,6 +1540,10 @@ static int igc_ethtool_set_channels(struct net_device *netdev,
if (ch->other_count != NON_Q_VECTORS)
return -EINVAL;

/* Do not allow channel reconfiguration when mqprio is enabled */
if (adapter->strict_priority_enable)
return -EINVAL;

/* Verify the number of channels doesn't exceed hw limits */
max_combined = igc_get_max_rss_queues(adapter);
if (count > max_combined)
Expand Down Expand Up @@ -1627,15 +1631,86 @@ static int igc_ethtool_get_eee(struct net_device *netdev,
{
struct igc_adapter *adapter = netdev_priv(netdev);
struct igc_hw *hw = &adapter->hw;
u32 eeer;
struct igc_phy_info *phy = &hw->phy;
u16 eee_advert, eee_lp_advert;
u32 eeer, ret_val;

/* EEE supported */
linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
edata->supported);
linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
edata->supported);
linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
edata->supported);

/* EEE Advertisement 1 - reg 7.60 */
ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK <<
MMD_DEVADDR_SHIFT) |
IGC_ANEG_EEE_AB1,
&eee_advert);
if (ret_val) {
netdev_err(adapter->netdev,
"Failed to read IEEE 7.60 register\n");
return -EINVAL;
}

if (eee_advert & IGC_EEE_1000BT_MASK)
linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
edata->advertised);

if (eee_advert & IGC_EEE_100BT_MASK)
linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
edata->advertised);

/* EEE Advertisement 2 - reg 7.62 */
ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK <<
MMD_DEVADDR_SHIFT) |
IGC_ANEG_EEE_AB2,
&eee_advert);
if (ret_val) {
netdev_err(adapter->netdev,
"Failed to read IEEE 7.62 register\n");
return -EINVAL;
}

if (eee_advert & IGC_EEE_2500BT_MASK)
linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
edata->advertised);

/* EEE Link-Partner Ability 1 - reg 7.61 */
ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK <<
MMD_DEVADDR_SHIFT) |
IGC_ANEG_EEE_LP_AB1,
&eee_lp_advert);
if (ret_val) {
netdev_err(adapter->netdev,
"Failed to read IEEE 7.61 register\n");
return -EINVAL;
}

if (eee_lp_advert & IGC_LP_EEE_1000BT_MASK)
linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
edata->lp_advertised);

if (eee_lp_advert & IGC_LP_EEE_100BT_MASK)
linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
edata->lp_advertised);

/* EEE Link-Partner Ability 2 - reg 7.63 */
ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK <<
MMD_DEVADDR_SHIFT) |
IGC_ANEG_EEE_LP_AB2,
&eee_lp_advert);
if (ret_val) {
netdev_err(adapter->netdev,
"Failed to read IEEE 7.63 register\n");
return -EINVAL;
}

if (eee_lp_advert & IGC_LP_EEE_2500BT_MASK)
linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
edata->lp_advertised);

eeer = rd32(IGC_EEER);

/* EEE status on negotiated link */
Expand Down
Loading

0 comments on commit 3bbefbb

Please sign in to comment.