Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch '1GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/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>

+347 -25
+11 -8
drivers/net/ethernet/intel/e1000e/netdev.c
··· 6671 6671 if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) { 6672 6672 /* enable wakeup by the PHY */ 6673 6673 retval = e1000_init_phy_wakeup(adapter, wufc); 6674 - if (retval) 6675 - return retval; 6674 + if (retval) { 6675 + e_err("Failed to enable wakeup\n"); 6676 + goto skip_phy_configurations; 6677 + } 6676 6678 } else { 6677 6679 /* enable wakeup by the MAC */ 6678 6680 ew32(WUFC, wufc); ··· 6695 6693 * or broadcast. 6696 6694 */ 6697 6695 retval = e1000_enable_ulp_lpt_lp(hw, !runtime); 6698 - if (retval) 6699 - return retval; 6696 + if (retval) { 6697 + e_err("Failed to enable ULP\n"); 6698 + goto skip_phy_configurations; 6699 + } 6700 6700 } 6701 6701 } 6702 6702 ··· 6730 6726 hw->phy.ops.release(hw); 6731 6727 } 6732 6728 6729 + skip_phy_configurations: 6733 6730 /* Release control of h/w to f/w. If f/w is AMT enabled, this 6734 6731 * would have already happened in close and is redundant. 6735 6732 */ ··· 6973 6968 e1000e_pm_freeze(dev); 6974 6969 6975 6970 rc = __e1000_shutdown(pdev, false); 6976 - if (rc) { 6977 - e1000e_pm_thaw(dev); 6978 - } else { 6971 + if (!rc) { 6979 6972 /* Introduce S0ix implementation */ 6980 6973 if (adapter->flags2 & FLAG2_ENABLE_S0IX_FLOWS) 6981 6974 e1000e_s0ix_entry_flow(adapter); 6982 6975 } 6983 6976 6984 - return rc; 6977 + return 0; 6985 6978 } 6986 6979 6987 6980 static int e1000e_pm_resume(struct device *dev)
+1
drivers/net/ethernet/intel/i40e/i40e.h
··· 4 4 #ifndef _I40E_H_ 5 5 #define _I40E_H_ 6 6 7 + #include <linux/linkmode.h> 7 8 #include <linux/pci.h> 8 9 #include <linux/ptp_clock_kernel.h> 9 10 #include <linux/types.h>
+32 -4
drivers/net/ethernet/intel/i40e/i40e_ethtool.c
··· 5641 5641 return 0; 5642 5642 } 5643 5643 5644 + static void i40e_eee_capability_to_kedata_supported(__le16 eee_capability_, 5645 + unsigned long *supported) 5646 + { 5647 + const int eee_capability = le16_to_cpu(eee_capability_); 5648 + static const int lut[] = { 5649 + ETHTOOL_LINK_MODE_100baseT_Full_BIT, 5650 + ETHTOOL_LINK_MODE_1000baseT_Full_BIT, 5651 + ETHTOOL_LINK_MODE_10000baseT_Full_BIT, 5652 + ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, 5653 + ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, 5654 + ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, 5655 + ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, 5656 + }; 5657 + 5658 + linkmode_zero(supported); 5659 + for (unsigned int i = ARRAY_SIZE(lut); i--; ) 5660 + if (eee_capability & BIT(i + 1)) 5661 + linkmode_set_bit(lut[i], supported); 5662 + } 5663 + 5644 5664 static int i40e_get_eee(struct net_device *netdev, struct ethtool_keee *edata) 5645 5665 { 5646 5666 struct i40e_netdev_priv *np = netdev_priv(netdev); ··· 5668 5648 struct i40e_vsi *vsi = np->vsi; 5669 5649 struct i40e_pf *pf = vsi->back; 5670 5650 struct i40e_hw *hw = &pf->hw; 5671 - int status = 0; 5651 + int status; 5672 5652 5673 5653 /* Get initial PHY capabilities */ 5674 5654 status = i40e_aq_get_phy_capabilities(hw, false, true, &phy_cfg, NULL); ··· 5681 5661 if (phy_cfg.eee_capability == 0) 5682 5662 return -EOPNOTSUPP; 5683 5663 5664 + i40e_eee_capability_to_kedata_supported(phy_cfg.eee_capability, 5665 + edata->supported); 5666 + linkmode_copy(edata->lp_advertised, edata->supported); 5667 + 5684 5668 /* Get current configuration */ 5685 5669 status = i40e_aq_get_phy_capabilities(hw, false, false, &phy_cfg, NULL); 5686 5670 if (status) 5687 5671 return -EAGAIN; 5688 5672 5673 + linkmode_zero(edata->advertised); 5674 + if (phy_cfg.eee_capability) 5675 + linkmode_copy(edata->advertised, edata->supported); 5689 5676 edata->eee_enabled = !!phy_cfg.eee_capability; 5690 5677 edata->tx_lpi_enabled = pf->stats.tx_lpi_status; 5691 5678 ··· 5708 5681 struct i40e_vsi *vsi = np->vsi; 5709 5682 struct i40e_pf *pf = vsi->back; 5710 5683 struct i40e_ethtool_not_used { 5711 - u32 value; 5684 + bool value; 5712 5685 const char *name; 5713 5686 } param[] = { 5714 - {edata->tx_lpi_timer, "tx-timer"}, 5687 + {!!(edata->advertised[0] & ~edata->supported[0]), "advertise"}, 5688 + {!!edata->tx_lpi_timer, "tx-timer"}, 5715 5689 {edata->tx_lpi_enabled != pf->stats.tx_lpi_status, "tx-lpi"} 5716 5690 }; 5717 5691 int i; ··· 5738 5710 struct i40e_pf *pf = vsi->back; 5739 5711 struct i40e_hw *hw = &pf->hw; 5740 5712 __le16 eee_capability; 5741 - int status = 0; 5713 + int status; 5742 5714 5743 5715 /* Deny parameters we don't support */ 5744 5716 if (i40e_is_eee_param_supported(netdev, edata))
+21 -3
drivers/net/ethernet/intel/i40e/i40e_main.c
··· 7264 7264 } 7265 7265 #endif /* CONFIG_I40E_DCB */ 7266 7266 7267 + static void i40e_print_link_message_eee(struct i40e_vsi *vsi, 7268 + const char *speed, const char *fc) 7269 + { 7270 + struct ethtool_keee kedata; 7271 + 7272 + memzero_explicit(&kedata, sizeof(kedata)); 7273 + if (vsi->netdev->ethtool_ops->get_eee) 7274 + vsi->netdev->ethtool_ops->get_eee(vsi->netdev, &kedata); 7275 + 7276 + if (!linkmode_empty(kedata.supported)) 7277 + netdev_info(vsi->netdev, 7278 + "NIC Link is Up, %sbps Full Duplex, Flow Control: %s, EEE: %s\n", 7279 + speed, fc, 7280 + kedata.eee_enabled ? "Enabled" : "Disabled"); 7281 + else 7282 + netdev_info(vsi->netdev, 7283 + "NIC Link is Up, %sbps Full Duplex, Flow Control: %s\n", 7284 + speed, fc); 7285 + } 7286 + 7267 7287 /** 7268 7288 * i40e_print_link_message - print link up or down 7269 7289 * @vsi: the VSI for which link needs a message ··· 7415 7395 "NIC Link is Up, %sbps Full Duplex, Requested FEC: %s, Negotiated FEC: %s, Autoneg: %s, Flow Control: %s\n", 7416 7396 speed, req_fec, fec, an, fc); 7417 7397 } else { 7418 - netdev_info(vsi->netdev, 7419 - "NIC Link is Up, %sbps Full Duplex, Flow Control: %s\n", 7420 - speed, fc); 7398 + i40e_print_link_message_eee(vsi, speed, fc); 7421 7399 } 7422 7400 7423 7401 }
+9 -2
drivers/net/ethernet/intel/igc/igc.h
··· 259 259 */ 260 260 spinlock_t qbv_tx_lock; 261 261 262 + bool strict_priority_enable; 263 + u8 num_tc; 264 + u16 queue_per_tc[IGC_MAX_TX_QUEUES]; 265 + 262 266 /* OS defined structs */ 263 267 struct pci_dev *pdev; 264 268 /* lock for statistics */ ··· 386 382 #define IGC_FLAG_RX_LEGACY BIT(16) 387 383 #define IGC_FLAG_TSN_QBV_ENABLED BIT(17) 388 384 #define IGC_FLAG_TSN_QAV_ENABLED BIT(18) 385 + #define IGC_FLAG_TSN_LEGACY_ENABLED BIT(19) 389 386 390 - #define IGC_FLAG_TSN_ANY_ENABLED \ 391 - (IGC_FLAG_TSN_QBV_ENABLED | IGC_FLAG_TSN_QAV_ENABLED) 387 + #define IGC_FLAG_TSN_ANY_ENABLED \ 388 + (IGC_FLAG_TSN_QBV_ENABLED | IGC_FLAG_TSN_QAV_ENABLED | \ 389 + IGC_FLAG_TSN_LEGACY_ENABLED) 392 390 393 391 #define IGC_FLAG_RSS_FIELD_IPV4_UDP BIT(6) 394 392 #define IGC_FLAG_RSS_FIELD_IPV6_UDP BIT(7) ··· 687 681 IGC_RING_FLAG_TX_DETECT_HANG, 688 682 IGC_RING_FLAG_AF_XDP_ZC, 689 683 IGC_RING_FLAG_TX_HWTSTAMP, 684 + IGC_RING_FLAG_RX_ALLOC_FAILED, 690 685 }; 691 686 692 687 #define ring_uses_large_buffer(ring) \
+21 -1
drivers/net/ethernet/intel/igc/igc_defines.h
··· 4 4 #ifndef _IGC_DEFINES_H_ 5 5 #define _IGC_DEFINES_H_ 6 6 7 + #include <linux/bitfield.h> 8 + 7 9 /* Number of Transmit and Receive Descriptors must be a multiple of 8 */ 8 10 #define REQ_TX_DESCRIPTOR_MULTIPLE 8 9 11 #define REQ_RX_DESCRIPTOR_MULTIPLE 8 ··· 178 176 179 177 /* PHY GPY 211 registers */ 180 178 #define STANDARD_AN_REG_MASK 0x0007 /* MMD */ 181 - #define ANEG_MULTIGBT_AN_CTRL 0x0020 /* MULTI GBT AN Control Register */ 182 179 #define MMD_DEVADDR_SHIFT 16 /* Shift MMD to higher bits */ 183 180 #define CR_2500T_FD_CAPS 0x0080 /* Advertise 2500T FD capability */ 184 181 ··· 554 553 555 554 #define IGC_MAX_SR_QUEUES 2 556 555 556 + #define IGC_TXARB_TXQ_PRIO_0_MASK GENMASK(1, 0) 557 + #define IGC_TXARB_TXQ_PRIO_1_MASK GENMASK(3, 2) 558 + #define IGC_TXARB_TXQ_PRIO_2_MASK GENMASK(5, 4) 559 + #define IGC_TXARB_TXQ_PRIO_3_MASK GENMASK(7, 6) 560 + #define IGC_TXARB_TXQ_PRIO_0(x) FIELD_PREP(IGC_TXARB_TXQ_PRIO_0_MASK, (x)) 561 + #define IGC_TXARB_TXQ_PRIO_1(x) FIELD_PREP(IGC_TXARB_TXQ_PRIO_1_MASK, (x)) 562 + #define IGC_TXARB_TXQ_PRIO_2(x) FIELD_PREP(IGC_TXARB_TXQ_PRIO_2_MASK, (x)) 563 + #define IGC_TXARB_TXQ_PRIO_3(x) FIELD_PREP(IGC_TXARB_TXQ_PRIO_3_MASK, (x)) 564 + 557 565 /* Receive Checksum Control */ 558 566 #define IGC_RXCSUM_CRCOFL 0x00000800 /* CRC32 offload enable */ 559 567 #define IGC_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */ ··· 650 640 #define IGC_MDIC_OP_READ 0x08000000 651 641 #define IGC_MDIC_READY 0x10000000 652 642 #define IGC_MDIC_ERROR 0x40000000 643 + 644 + /* EEE Link Ability */ 645 + #define IGC_EEE_2500BT_MASK BIT(0) 646 + #define IGC_EEE_1000BT_MASK BIT(2) 647 + #define IGC_EEE_100BT_MASK BIT(1) 648 + 649 + /* EEE Link-Partner Ability */ 650 + #define IGC_LP_EEE_2500BT_MASK BIT(0) 651 + #define IGC_LP_EEE_1000BT_MASK BIT(2) 652 + #define IGC_LP_EEE_100BT_MASK BIT(1) 653 653 654 654 #define IGC_N0_QUEUE -1 655 655
+76 -1
drivers/net/ethernet/intel/igc/igc_ethtool.c
··· 1540 1540 if (ch->other_count != NON_Q_VECTORS) 1541 1541 return -EINVAL; 1542 1542 1543 + /* Do not allow channel reconfiguration when mqprio is enabled */ 1544 + if (adapter->strict_priority_enable) 1545 + return -EINVAL; 1546 + 1543 1547 /* Verify the number of channels doesn't exceed hw limits */ 1544 1548 max_combined = igc_get_max_rss_queues(adapter); 1545 1549 if (count > max_combined) ··· 1631 1627 { 1632 1628 struct igc_adapter *adapter = netdev_priv(netdev); 1633 1629 struct igc_hw *hw = &adapter->hw; 1634 - u32 eeer; 1630 + struct igc_phy_info *phy = &hw->phy; 1631 + u16 eee_advert, eee_lp_advert; 1632 + u32 eeer, ret_val; 1635 1633 1634 + /* EEE supported */ 1636 1635 linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, 1637 1636 edata->supported); 1638 1637 linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, 1639 1638 edata->supported); 1640 1639 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, 1641 1640 edata->supported); 1641 + 1642 + /* EEE Advertisement 1 - reg 7.60 */ 1643 + ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK << 1644 + MMD_DEVADDR_SHIFT) | 1645 + IGC_ANEG_EEE_AB1, 1646 + &eee_advert); 1647 + if (ret_val) { 1648 + netdev_err(adapter->netdev, 1649 + "Failed to read IEEE 7.60 register\n"); 1650 + return -EINVAL; 1651 + } 1652 + 1653 + if (eee_advert & IGC_EEE_1000BT_MASK) 1654 + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, 1655 + edata->advertised); 1656 + 1657 + if (eee_advert & IGC_EEE_100BT_MASK) 1658 + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, 1659 + edata->advertised); 1660 + 1661 + /* EEE Advertisement 2 - reg 7.62 */ 1662 + ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK << 1663 + MMD_DEVADDR_SHIFT) | 1664 + IGC_ANEG_EEE_AB2, 1665 + &eee_advert); 1666 + if (ret_val) { 1667 + netdev_err(adapter->netdev, 1668 + "Failed to read IEEE 7.62 register\n"); 1669 + return -EINVAL; 1670 + } 1671 + 1672 + if (eee_advert & IGC_EEE_2500BT_MASK) 1673 + linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, 1674 + edata->advertised); 1675 + 1676 + /* EEE Link-Partner Ability 1 - reg 7.61 */ 1677 + ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK << 1678 + MMD_DEVADDR_SHIFT) | 1679 + IGC_ANEG_EEE_LP_AB1, 1680 + &eee_lp_advert); 1681 + if (ret_val) { 1682 + netdev_err(adapter->netdev, 1683 + "Failed to read IEEE 7.61 register\n"); 1684 + return -EINVAL; 1685 + } 1686 + 1687 + if (eee_lp_advert & IGC_LP_EEE_1000BT_MASK) 1688 + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, 1689 + edata->lp_advertised); 1690 + 1691 + if (eee_lp_advert & IGC_LP_EEE_100BT_MASK) 1692 + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, 1693 + edata->lp_advertised); 1694 + 1695 + /* EEE Link-Partner Ability 2 - reg 7.63 */ 1696 + ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK << 1697 + MMD_DEVADDR_SHIFT) | 1698 + IGC_ANEG_EEE_LP_AB2, 1699 + &eee_lp_advert); 1700 + if (ret_val) { 1701 + netdev_err(adapter->netdev, 1702 + "Failed to read IEEE 7.63 register\n"); 1703 + return -EINVAL; 1704 + } 1705 + 1706 + if (eee_lp_advert & IGC_LP_EEE_2500BT_MASK) 1707 + linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, 1708 + edata->lp_advertised); 1642 1709 1643 1710 eeer = rd32(IGC_EEER); 1644 1711
+95 -4
drivers/net/ethernet/intel/igc/igc_main.c
··· 2191 2191 page = dev_alloc_pages(igc_rx_pg_order(rx_ring)); 2192 2192 if (unlikely(!page)) { 2193 2193 rx_ring->rx_stats.alloc_failed++; 2194 + set_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags); 2194 2195 return false; 2195 2196 } 2196 2197 ··· 2208 2207 __free_page(page); 2209 2208 2210 2209 rx_ring->rx_stats.alloc_failed++; 2210 + set_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags); 2211 2211 return false; 2212 2212 } 2213 2213 ··· 2660 2658 if (!skb) { 2661 2659 rx_ring->rx_stats.alloc_failed++; 2662 2660 rx_buffer->pagecnt_bias++; 2661 + set_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags); 2663 2662 break; 2664 2663 } 2665 2664 ··· 2741 2738 skb = igc_construct_skb_zc(ring, xdp); 2742 2739 if (!skb) { 2743 2740 ring->rx_stats.alloc_failed++; 2741 + set_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &ring->flags); 2744 2742 return; 2745 2743 } 2746 2744 ··· 5811 5807 if (adapter->flags & IGC_FLAG_HAS_MSIX) { 5812 5808 u32 eics = 0; 5813 5809 5814 - for (i = 0; i < adapter->num_q_vectors; i++) 5815 - eics |= adapter->q_vector[i]->eims_value; 5816 - wr32(IGC_EICS, eics); 5810 + for (i = 0; i < adapter->num_q_vectors; i++) { 5811 + struct igc_q_vector *q_vector = adapter->q_vector[i]; 5812 + struct igc_ring *rx_ring; 5813 + 5814 + if (!q_vector->rx.ring) 5815 + continue; 5816 + 5817 + rx_ring = adapter->rx_ring[q_vector->rx.ring->queue_index]; 5818 + 5819 + if (test_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags)) { 5820 + eics |= q_vector->eims_value; 5821 + clear_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags); 5822 + } 5823 + } 5824 + if (eics) 5825 + wr32(IGC_EICS, eics); 5817 5826 } else { 5818 - wr32(IGC_ICS, IGC_ICS_RXDMT0); 5827 + struct igc_ring *rx_ring = adapter->rx_ring[0]; 5828 + 5829 + if (test_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags)) { 5830 + clear_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags); 5831 + wr32(IGC_ICS, IGC_ICS_RXDMT0); 5832 + } 5819 5833 } 5820 5834 5821 5835 igc_ptp_tx_hang(adapter); ··· 6537 6515 struct igc_hw *hw = &adapter->hw; 6538 6516 6539 6517 switch (base->type) { 6518 + case TC_SETUP_QDISC_MQPRIO: { 6519 + struct tc_mqprio_caps *caps = base->caps; 6520 + 6521 + caps->validate_queue_counts = true; 6522 + 6523 + return 0; 6524 + } 6540 6525 case TC_SETUP_QDISC_TAPRIO: { 6541 6526 struct tc_taprio_caps *caps = base->caps; 6542 6527 ··· 6559 6530 default: 6560 6531 return -EOPNOTSUPP; 6561 6532 } 6533 + } 6534 + 6535 + static void igc_save_mqprio_params(struct igc_adapter *adapter, u8 num_tc, 6536 + u16 *offset) 6537 + { 6538 + int i; 6539 + 6540 + adapter->strict_priority_enable = true; 6541 + adapter->num_tc = num_tc; 6542 + 6543 + for (i = 0; i < num_tc; i++) 6544 + adapter->queue_per_tc[i] = offset[i]; 6545 + } 6546 + 6547 + static int igc_tsn_enable_mqprio(struct igc_adapter *adapter, 6548 + struct tc_mqprio_qopt_offload *mqprio) 6549 + { 6550 + struct igc_hw *hw = &adapter->hw; 6551 + int i; 6552 + 6553 + if (hw->mac.type != igc_i225) 6554 + return -EOPNOTSUPP; 6555 + 6556 + if (!mqprio->qopt.num_tc) { 6557 + adapter->strict_priority_enable = false; 6558 + goto apply; 6559 + } 6560 + 6561 + /* There are as many TCs as Tx queues. */ 6562 + if (mqprio->qopt.num_tc != adapter->num_tx_queues) { 6563 + NL_SET_ERR_MSG_FMT_MOD(mqprio->extack, 6564 + "Only %d traffic classes supported", 6565 + adapter->num_tx_queues); 6566 + return -EOPNOTSUPP; 6567 + } 6568 + 6569 + /* Only one queue per TC is supported. */ 6570 + for (i = 0; i < mqprio->qopt.num_tc; i++) { 6571 + if (mqprio->qopt.count[i] != 1) { 6572 + NL_SET_ERR_MSG_MOD(mqprio->extack, 6573 + "Only one queue per TC supported"); 6574 + return -EOPNOTSUPP; 6575 + } 6576 + } 6577 + 6578 + /* Preemption is not supported yet. */ 6579 + if (mqprio->preemptible_tcs) { 6580 + NL_SET_ERR_MSG_MOD(mqprio->extack, 6581 + "Preemption is not supported yet"); 6582 + return -EOPNOTSUPP; 6583 + } 6584 + 6585 + igc_save_mqprio_params(adapter, mqprio->qopt.num_tc, 6586 + mqprio->qopt.offset); 6587 + 6588 + mqprio->qopt.hw = TC_MQPRIO_HW_OFFLOAD_TCS; 6589 + 6590 + apply: 6591 + return igc_tsn_offload_apply(adapter); 6562 6592 } 6563 6593 6564 6594 static int igc_setup_tc(struct net_device *dev, enum tc_setup_type type, ··· 6638 6550 6639 6551 case TC_SETUP_QDISC_CBS: 6640 6552 return igc_tsn_enable_cbs(adapter, type_data); 6553 + 6554 + case TC_SETUP_QDISC_MQPRIO: 6555 + return igc_tsn_enable_mqprio(adapter, type_data); 6641 6556 6642 6557 default: 6643 6558 return -EOPNOTSUPP;
+2 -2
drivers/net/ethernet/intel/igc/igc_phy.c
··· 240 240 /* Read the MULTI GBT AN Control Register - reg 7.32 */ 241 241 ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK << 242 242 MMD_DEVADDR_SHIFT) | 243 - ANEG_MULTIGBT_AN_CTRL, 243 + IGC_ANEG_MULTIGBT_AN_CTRL, 244 244 &aneg_multigbt_an_ctrl); 245 245 246 246 if (ret_val) ··· 380 380 ret_val = phy->ops.write_reg(hw, 381 381 (STANDARD_AN_REG_MASK << 382 382 MMD_DEVADDR_SHIFT) | 383 - ANEG_MULTIGBT_AN_CTRL, 383 + IGC_ANEG_MULTIGBT_AN_CTRL, 384 384 aneg_multigbt_an_ctrl); 385 385 386 386 return ret_val;
+12
drivers/net/ethernet/intel/igc/igc_regs.h
··· 238 238 #define IGC_TQAVCC(_n) (0x3004 + ((_n) * 0x40)) 239 239 #define IGC_TQAVHC(_n) (0x300C + ((_n) * 0x40)) 240 240 241 + #define IGC_TXARB 0x3354 /* Tx Arbitration Control TxARB - RW */ 242 + 241 243 /* System Time Registers */ 242 244 #define IGC_SYSTIML 0x0B600 /* System time register Low - RO */ 243 245 #define IGC_SYSTIMH 0x0B604 /* System time register High - RO */ ··· 309 307 #define IGC_EEER 0x0E30 /* Energy Efficient Ethernet "EEE"*/ 310 308 #define IGC_IPCNFG 0x0E38 /* Internal PHY Configuration */ 311 309 #define IGC_EEE_SU 0x0E34 /* EEE Setup */ 310 + 311 + /* MULTI GBT AN Control Register - reg. 7.32 */ 312 + #define IGC_ANEG_MULTIGBT_AN_CTRL 0x0020 313 + 314 + /* EEE ANeg Advertisement Register - reg 7.60 and reg 7.62 */ 315 + #define IGC_ANEG_EEE_AB1 0x003c 316 + #define IGC_ANEG_EEE_AB2 0x003e 317 + /* EEE ANeg Link-Partner Advertisement Register - reg 7.61 and reg 7.63 */ 318 + #define IGC_ANEG_EEE_LP_AB1 0x003d 319 + #define IGC_ANEG_EEE_LP_AB2 0x003f 312 320 313 321 /* LTR registers */ 314 322 #define IGC_LTRC 0x01A0 /* Latency Tolerance Reporting Control */
+67
drivers/net/ethernet/intel/igc/igc_tsn.c
··· 46 46 if (is_cbs_enabled(adapter)) 47 47 new_flags |= IGC_FLAG_TSN_QAV_ENABLED; 48 48 49 + if (adapter->strict_priority_enable) 50 + new_flags |= IGC_FLAG_TSN_LEGACY_ENABLED; 51 + 49 52 return new_flags; 50 53 } 51 54 ··· 105 102 adapter->taprio_offload_enable; 106 103 } 107 104 105 + static void igc_tsn_tx_arb(struct igc_adapter *adapter, u16 *queue_per_tc) 106 + { 107 + struct igc_hw *hw = &adapter->hw; 108 + u32 txarb; 109 + 110 + txarb = rd32(IGC_TXARB); 111 + 112 + txarb &= ~(IGC_TXARB_TXQ_PRIO_0_MASK | 113 + IGC_TXARB_TXQ_PRIO_1_MASK | 114 + IGC_TXARB_TXQ_PRIO_2_MASK | 115 + IGC_TXARB_TXQ_PRIO_3_MASK); 116 + 117 + txarb |= IGC_TXARB_TXQ_PRIO_0(queue_per_tc[3]); 118 + txarb |= IGC_TXARB_TXQ_PRIO_1(queue_per_tc[2]); 119 + txarb |= IGC_TXARB_TXQ_PRIO_2(queue_per_tc[1]); 120 + txarb |= IGC_TXARB_TXQ_PRIO_3(queue_per_tc[0]); 121 + 122 + wr32(IGC_TXARB, txarb); 123 + } 124 + 108 125 /* Returns the TSN specific registers to their default values after 109 126 * the adapter is reset. 110 127 */ 111 128 static int igc_tsn_disable_offload(struct igc_adapter *adapter) 112 129 { 130 + u16 queue_per_tc[4] = { 3, 2, 1, 0 }; 113 131 struct igc_hw *hw = &adapter->hw; 114 132 u32 tqavctrl; 115 133 int i; ··· 157 133 wr32(IGC_QBVCYCLET_S, 0); 158 134 wr32(IGC_QBVCYCLET, NSEC_PER_SEC); 159 135 136 + /* Reset mqprio TC configuration. */ 137 + netdev_reset_tc(adapter->netdev); 138 + 139 + /* Restore the default Tx arbitration: Priority 0 has the highest 140 + * priority and is assigned to queue 0 and so on and so forth. 141 + */ 142 + igc_tsn_tx_arb(adapter, queue_per_tc); 143 + 160 144 adapter->flags &= ~IGC_FLAG_TSN_QBV_ENABLED; 145 + adapter->flags &= ~IGC_FLAG_TSN_LEGACY_ENABLED; 161 146 162 147 return 0; 163 148 } ··· 204 171 205 172 if (igc_is_device_id_i226(hw)) 206 173 igc_tsn_set_retx_qbvfullthreshold(adapter); 174 + 175 + if (adapter->strict_priority_enable) { 176 + int err; 177 + 178 + err = netdev_set_num_tc(adapter->netdev, adapter->num_tc); 179 + if (err) 180 + return err; 181 + 182 + for (i = 0; i < adapter->num_tc; i++) { 183 + err = netdev_set_tc_queue(adapter->netdev, i, 1, 184 + adapter->queue_per_tc[i]); 185 + if (err) 186 + return err; 187 + } 188 + 189 + /* In case the card is configured with less than four queues. */ 190 + for (; i < IGC_MAX_TX_QUEUES; i++) 191 + adapter->queue_per_tc[i] = i; 192 + 193 + /* Configure queue priorities according to the user provided 194 + * mapping. 195 + */ 196 + igc_tsn_tx_arb(adapter, adapter->queue_per_tc); 197 + 198 + /* Enable legacy TSN mode which will do strict priority without 199 + * any other TSN features. 200 + */ 201 + tqavctrl = rd32(IGC_TQAVCTRL); 202 + tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN; 203 + tqavctrl &= ~IGC_TQAVCTRL_ENHANCED_QAV; 204 + wr32(IGC_TQAVCTRL, tqavctrl); 205 + 206 + return 0; 207 + } 207 208 208 209 for (i = 0; i < adapter->num_tx_queues; i++) { 209 210 struct igc_ring *ring = adapter->tx_ring[i];