Skip to content

Commit 9149a63

Browse files
author
Paolo Abeni
committed
Merge branch 'intel-next-queue-1GbE'
Tony Nguyen says: ==================== Faizal Rahim says: MAC Merge support for frame preemption was previously added for igc: https://lore.kernel.org/netdev/[email protected]/ This series builds on that work and adds support for: - Harmonizing taprio and mqprio queue priority behavior, based on past discussions and suggestions: https://lore.kernel.org/all/20250214102206.25dqgut5tbak2rkz@skbuf/ - Enabling preemptible queue support for both taprio and mqprio, with priority harmonization as a prerequisite. Patch organization: - Patches 1-3: Preparation work for patches 6 and 7 - Patches 4-5: Queue priority harmonization - Patches 6-7: Add preemptible queue support ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
2 parents dd4a578 + a7d45bc commit 9149a63

File tree

7 files changed

+189
-43
lines changed

7 files changed

+189
-43
lines changed

drivers/net/ethernet/intel/igc/igc.h

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ void igc_ethtool_set_ops(struct net_device *);
4343
struct igc_fpe_t {
4444
struct ethtool_mmsv mmsv;
4545
u32 tx_min_frag_size;
46+
bool tx_enabled;
4647
};
4748

4849
enum igc_mac_filter_type {
@@ -163,6 +164,7 @@ struct igc_ring {
163164
bool launchtime_enable; /* true if LaunchTime is enabled */
164165
ktime_t last_tx_cycle; /* end of the cycle with a launchtime transmission */
165166
ktime_t last_ff_cycle; /* Last cycle with an active first flag */
167+
bool preemptible; /* True if preemptible queue, false if express queue */
166168

167169
u32 start_time;
168170
u32 end_time;
@@ -395,6 +397,7 @@ extern char igc_driver_name[];
395397
#define IGC_FLAG_TSN_QBV_ENABLED BIT(17)
396398
#define IGC_FLAG_TSN_QAV_ENABLED BIT(18)
397399
#define IGC_FLAG_TSN_PREEMPT_ENABLED BIT(19)
400+
#define IGC_FLAG_TSN_REVERSE_TXQ_PRIO BIT(20)
398401

399402
#define IGC_FLAG_TSN_ANY_ENABLED \
400403
(IGC_FLAG_TSN_QBV_ENABLED | IGC_FLAG_TSN_QAV_ENABLED | \
@@ -485,12 +488,30 @@ static inline u32 igc_rss_type(const union igc_adv_rx_desc *rx_desc)
485488
* descriptors until either it has this many to write back, or the
486489
* ITR timer expires.
487490
*/
488-
#define IGC_RX_PTHRESH 8
489-
#define IGC_RX_HTHRESH 8
490-
#define IGC_TX_PTHRESH 8
491-
#define IGC_TX_HTHRESH 1
492-
#define IGC_RX_WTHRESH 4
493-
#define IGC_TX_WTHRESH 16
491+
#define IGC_RXDCTL_PTHRESH 8
492+
#define IGC_RXDCTL_HTHRESH 8
493+
#define IGC_RXDCTL_WTHRESH 4
494+
/* Ena specific Rx Queue */
495+
#define IGC_RXDCTL_QUEUE_ENABLE 0x02000000
496+
/* Receive Software Flush */
497+
#define IGC_RXDCTL_SWFLUSH 0x04000000
498+
499+
#define IGC_TXDCTL_PTHRESH_MASK GENMASK(4, 0)
500+
#define IGC_TXDCTL_HTHRESH_MASK GENMASK(12, 8)
501+
#define IGC_TXDCTL_WTHRESH_MASK GENMASK(20, 16)
502+
#define IGC_TXDCTL_QUEUE_ENABLE_MASK GENMASK(25, 25)
503+
#define IGC_TXDCTL_SWFLUSH_MASK GENMASK(26, 26)
504+
#define IGC_TXDCTL_PRIORITY_MASK GENMASK(27, 27)
505+
506+
#define IGC_TXDCTL_PTHRESH(x) FIELD_PREP(IGC_TXDCTL_PTHRESH_MASK, (x))
507+
#define IGC_TXDCTL_HTHRESH(x) FIELD_PREP(IGC_TXDCTL_HTHRESH_MASK, (x))
508+
#define IGC_TXDCTL_WTHRESH(x) FIELD_PREP(IGC_TXDCTL_WTHRESH_MASK, (x))
509+
/* Ena specific Tx Queue */
510+
#define IGC_TXDCTL_QUEUE_ENABLE FIELD_PREP(IGC_TXDCTL_QUEUE_ENABLE_MASK, 1)
511+
/* Transmit Software Flush */
512+
#define IGC_TXDCTL_SWFLUSH FIELD_PREP(IGC_TXDCTL_SWFLUSH_MASK, 1)
513+
#define IGC_TXDCTL_PRIORITY(x) FIELD_PREP(IGC_TXDCTL_PRIORITY_MASK, (x))
514+
#define IGC_TXDCTL_PRIORITY_HIGH IGC_TXDCTL_PRIORITY(1)
494515

495516
#define IGC_RX_DMA_ATTR \
496517
(DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING)

drivers/net/ethernet/intel/igc/igc_base.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,6 @@ union igc_adv_rx_desc {
8686
} wb; /* writeback */
8787
};
8888

89-
/* Additional Transmit Descriptor Control definitions */
90-
#define IGC_TXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Tx Queue */
91-
#define IGC_TXDCTL_SWFLUSH 0x04000000 /* Transmit Software Flush */
92-
93-
/* Additional Receive Descriptor Control definitions */
94-
#define IGC_RXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Rx Queue */
95-
#define IGC_RXDCTL_SWFLUSH 0x04000000 /* Receive Software Flush */
96-
9789
/* SRRCTL bit definitions */
9890
#define IGC_SRRCTL_BSIZEPKT_MASK GENMASK(6, 0)
9991
#define IGC_SRRCTL_BSIZEPKT(x) FIELD_PREP(IGC_SRRCTL_BSIZEPKT_MASK, \

drivers/net/ethernet/intel/igc/igc_defines.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,7 @@
588588
#define IGC_TXQCTL_QUEUE_MODE_LAUNCHT 0x00000001
589589
#define IGC_TXQCTL_STRICT_CYCLE 0x00000002
590590
#define IGC_TXQCTL_STRICT_END 0x00000004
591+
#define IGC_TXQCTL_PREEMPTIBLE 0x00000008
591592
#define IGC_TXQCTL_QAV_SEL_MASK 0x000000C0
592593
#define IGC_TXQCTL_QAV_SEL_CBS0 0x00000080
593594
#define IGC_TXQCTL_QAV_SEL_CBS1 0x000000C0

drivers/net/ethernet/intel/igc/igc_ethtool.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,11 @@ static const char igc_gstrings_test[][ETH_GSTRING_LEN] = {
122122
#define IGC_STATS_LEN \
123123
(IGC_GLOBAL_STATS_LEN + IGC_NETDEV_STATS_LEN + IGC_QUEUE_STATS_LEN)
124124

125+
#define IGC_PRIV_FLAGS_LEGACY_RX BIT(0)
126+
#define IGC_PRIV_FLAGS_REVERSE_TSN_TXQ_PRIO BIT(1)
125127
static const char igc_priv_flags_strings[][ETH_GSTRING_LEN] = {
126-
#define IGC_PRIV_FLAGS_LEGACY_RX BIT(0)
127128
"legacy-rx",
129+
"reverse-tsn-txq-prio",
128130
};
129131

130132
#define IGC_PRIV_FLAGS_STR_LEN ARRAY_SIZE(igc_priv_flags_strings)
@@ -1600,6 +1602,9 @@ static u32 igc_ethtool_get_priv_flags(struct net_device *netdev)
16001602
if (adapter->flags & IGC_FLAG_RX_LEGACY)
16011603
priv_flags |= IGC_PRIV_FLAGS_LEGACY_RX;
16021604

1605+
if (adapter->flags & IGC_FLAG_TSN_REVERSE_TXQ_PRIO)
1606+
priv_flags |= IGC_PRIV_FLAGS_REVERSE_TSN_TXQ_PRIO;
1607+
16031608
return priv_flags;
16041609
}
16051610

@@ -1608,10 +1613,13 @@ static int igc_ethtool_set_priv_flags(struct net_device *netdev, u32 priv_flags)
16081613
struct igc_adapter *adapter = netdev_priv(netdev);
16091614
unsigned int flags = adapter->flags;
16101615

1611-
flags &= ~IGC_FLAG_RX_LEGACY;
1616+
flags &= ~(IGC_FLAG_RX_LEGACY | IGC_FLAG_TSN_REVERSE_TXQ_PRIO);
16121617
if (priv_flags & IGC_PRIV_FLAGS_LEGACY_RX)
16131618
flags |= IGC_FLAG_RX_LEGACY;
16141619

1620+
if (priv_flags & IGC_PRIV_FLAGS_REVERSE_TSN_TXQ_PRIO)
1621+
flags |= IGC_FLAG_TSN_REVERSE_TXQ_PRIO;
1622+
16151623
if (flags != adapter->flags) {
16161624
adapter->flags = flags;
16171625

drivers/net/ethernet/intel/igc/igc_main.c

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -683,9 +683,9 @@ static void igc_configure_rx_ring(struct igc_adapter *adapter,
683683

684684
wr32(IGC_SRRCTL(reg_idx), srrctl);
685685

686-
rxdctl |= IGC_RX_PTHRESH;
687-
rxdctl |= IGC_RX_HTHRESH << 8;
688-
rxdctl |= IGC_RX_WTHRESH << 16;
686+
rxdctl |= IGC_RXDCTL_PTHRESH;
687+
rxdctl |= IGC_RXDCTL_HTHRESH << 8;
688+
rxdctl |= IGC_RXDCTL_WTHRESH << 16;
689689

690690
/* initialize rx_buffer_info */
691691
memset(ring->rx_buffer_info, 0,
@@ -749,11 +749,9 @@ static void igc_configure_tx_ring(struct igc_adapter *adapter,
749749
wr32(IGC_TDH(reg_idx), 0);
750750
writel(0, ring->tail);
751751

752-
txdctl |= IGC_TX_PTHRESH;
753-
txdctl |= IGC_TX_HTHRESH << 8;
754-
txdctl |= IGC_TX_WTHRESH << 16;
752+
txdctl |= IGC_TXDCTL_PTHRESH(8) | IGC_TXDCTL_HTHRESH(1) |
753+
IGC_TXDCTL_WTHRESH(16) | IGC_TXDCTL_QUEUE_ENABLE;
755754

756-
txdctl |= IGC_TXDCTL_QUEUE_ENABLE;
757755
wr32(IGC_TXDCTL(reg_idx), txdctl);
758756
}
759757

@@ -1687,6 +1685,15 @@ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
16871685
first->tx_flags = tx_flags;
16881686
first->protocol = protocol;
16891687

1688+
/* For preemptible queue, manually pad the skb so that HW includes
1689+
* padding bytes in mCRC calculation
1690+
*/
1691+
if (tx_ring->preemptible && skb->len < ETH_ZLEN) {
1692+
if (skb_padto(skb, ETH_ZLEN))
1693+
goto out_drop;
1694+
skb_put(skb, ETH_ZLEN - skb->len);
1695+
}
1696+
16901697
tso = igc_tso(tx_ring, first, launch_time, first_flag, &hdr_len);
16911698
if (tso < 0)
16921699
goto out_drop;
@@ -6423,6 +6430,7 @@ static int igc_qbv_clear_schedule(struct igc_adapter *adapter)
64236430
ring->start_time = 0;
64246431
ring->end_time = NSEC_PER_SEC;
64256432
ring->max_sdu = 0;
6433+
ring->preemptible = false;
64266434
}
64276435

64286436
spin_lock_irqsave(&adapter->qbv_tx_lock, flags);
@@ -6488,9 +6496,12 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
64886496
if (!validate_schedule(adapter, qopt))
64896497
return -EINVAL;
64906498

6491-
/* preemptible isn't supported yet */
6492-
if (qopt->mqprio.preemptible_tcs)
6493-
return -EOPNOTSUPP;
6499+
if (qopt->mqprio.preemptible_tcs &&
6500+
!(adapter->flags & IGC_FLAG_TSN_REVERSE_TXQ_PRIO)) {
6501+
NL_SET_ERR_MSG_MOD(qopt->extack,
6502+
"reverse-tsn-txq-prio private flag must be enabled before setting preemptible tc");
6503+
return -ENODEV;
6504+
}
64946505

64956506
igc_ptp_read(adapter, &now);
64966507

@@ -6583,6 +6594,8 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
65836594
ring->max_sdu = 0;
65846595
}
65856596

6597+
igc_fpe_save_preempt_queue(adapter, &qopt->mqprio);
6598+
65866599
return 0;
65876600
}
65886601

@@ -6702,7 +6715,8 @@ static int igc_tc_query_caps(struct igc_adapter *adapter,
67026715
case TC_SETUP_QDISC_TAPRIO: {
67036716
struct tc_taprio_caps *caps = base->caps;
67046717

6705-
caps->broken_mqprio = true;
6718+
if (!(adapter->flags & IGC_FLAG_TSN_REVERSE_TXQ_PRIO))
6719+
caps->broken_mqprio = true;
67066720

67076721
if (hw->mac.type == igc_i225) {
67086722
caps->supports_queue_max_sdu = true;
@@ -6728,6 +6742,20 @@ static void igc_save_mqprio_params(struct igc_adapter *adapter, u8 num_tc,
67286742
adapter->queue_per_tc[i] = offset[i];
67296743
}
67306744

6745+
static bool
6746+
igc_tsn_is_tc_to_queue_priority_ordered(struct tc_mqprio_qopt_offload *mqprio)
6747+
{
6748+
int num_tc = mqprio->qopt.num_tc;
6749+
int i;
6750+
6751+
for (i = 1; i < num_tc; i++) {
6752+
if (mqprio->qopt.offset[i - 1] > mqprio->qopt.offset[i])
6753+
return false;
6754+
}
6755+
6756+
return true;
6757+
}
6758+
67316759
static int igc_tsn_enable_mqprio(struct igc_adapter *adapter,
67326760
struct tc_mqprio_qopt_offload *mqprio)
67336761
{
@@ -6739,6 +6767,7 @@ static int igc_tsn_enable_mqprio(struct igc_adapter *adapter,
67396767

67406768
if (!mqprio->qopt.num_tc) {
67416769
adapter->strict_priority_enable = false;
6770+
igc_fpe_clear_preempt_queue(adapter);
67426771
netdev_reset_tc(adapter->netdev);
67436772
goto apply;
67446773
}
@@ -6760,10 +6789,9 @@ static int igc_tsn_enable_mqprio(struct igc_adapter *adapter,
67606789
}
67616790
}
67626791

6763-
/* Preemption is not supported yet. */
6764-
if (mqprio->preemptible_tcs) {
6792+
if (!igc_tsn_is_tc_to_queue_priority_ordered(mqprio)) {
67656793
NL_SET_ERR_MSG_MOD(mqprio->extack,
6766-
"Preemption is not supported yet");
6794+
"tc to queue mapping must preserve increasing priority (higher tc -> higher queue)");
67676795
return -EOPNOTSUPP;
67686796
}
67696797

@@ -6786,6 +6814,7 @@ static int igc_tsn_enable_mqprio(struct igc_adapter *adapter,
67866814
adapter->queue_per_tc[i] = i;
67876815

67886816
mqprio->qopt.hw = TC_MQPRIO_HW_OFFLOAD_TCS;
6817+
igc_fpe_save_preempt_queue(adapter, mqprio);
67896818

67906819
apply:
67916820
return igc_tsn_offload_apply(adapter);

0 commit comments

Comments
 (0)