Skip to content

Commit 82faa9b

Browse files
vcgomesJeff Kirsher
authored andcommitted
igc: Add support for ETF offloading
This adds support for ETF offloading for the i225 controller. For i225, the LaunchTime feature is almost a subset of the Qbv feature. The main change from the i210 is that the launchtime of each packet is specified as an offset applied to the BASET register. BASET is automatically incremented each cycle. For i225, the approach chosen is to re-use most of the setup used for taprio offloading. With a few changes: - The more or less obvious one is that when ETF is enabled, we should set add the expected launchtime to the (advanced) transmit descriptor; - The less obvious, is that when taprio offloading is not enabled, we add a dummy schedule (all queues are open all the time, with a cycle time of 1 second). Signed-off-by: Vinicius Costa Gomes <[email protected]> Reviewed-by: Andre Guedes <[email protected]> Tested-by: Aaron Brown <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent ec50a9d commit 82faa9b

File tree

3 files changed

+86
-4
lines changed

3 files changed

+86
-4
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@
440440
#define IGC_TQAVCTRL_TRANSMIT_MODE_TSN 0x00000001
441441
#define IGC_TQAVCTRL_ENHANCED_QAV 0x00000008
442442

443+
#define IGC_TXQCTL_QUEUE_MODE_LAUNCHT 0x00000001
443444
#define IGC_TXQCTL_STRICT_CYCLE 0x00000002
444445
#define IGC_TXQCTL_STRICT_END 0x00000004
445446

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

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -869,14 +869,30 @@ static int igc_write_mc_addr_list(struct net_device *netdev)
869869
return netdev_mc_count(netdev);
870870
}
871871

872+
static __le32 igc_tx_launchtime(struct igc_adapter *adapter, ktime_t txtime)
873+
{
874+
ktime_t cycle_time = adapter->cycle_time;
875+
ktime_t base_time = adapter->base_time;
876+
u32 launchtime;
877+
878+
/* FIXME: when using ETF together with taprio, we may have a
879+
* case where 'delta' is larger than the cycle_time, this may
880+
* cause problems if we don't read the current value of
881+
* IGC_BASET, as the value writen into the launchtime
882+
* descriptor field may be misinterpreted.
883+
*/
884+
div_s64_rem(ktime_sub_ns(txtime, base_time), cycle_time, &launchtime);
885+
886+
return cpu_to_le32(launchtime);
887+
}
888+
872889
static void igc_tx_ctxtdesc(struct igc_ring *tx_ring,
873890
struct igc_tx_buffer *first,
874891
u32 vlan_macip_lens, u32 type_tucmd,
875892
u32 mss_l4len_idx)
876893
{
877894
struct igc_adv_tx_context_desc *context_desc;
878895
u16 i = tx_ring->next_to_use;
879-
struct timespec64 ts;
880896

881897
context_desc = IGC_TX_CTXTDESC(tx_ring, i);
882898

@@ -898,9 +914,12 @@ static void igc_tx_ctxtdesc(struct igc_ring *tx_ring,
898914
* should have been handled by the upper layers.
899915
*/
900916
if (tx_ring->launchtime_enable) {
901-
ts = ktime_to_timespec64(first->skb->tstamp);
917+
struct igc_adapter *adapter = netdev_priv(tx_ring->netdev);
918+
ktime_t txtime = first->skb->tstamp;
919+
902920
first->skb->tstamp = ktime_set(0, 0);
903-
context_desc->launch_time = cpu_to_le32(ts.tv_nsec / 32);
921+
context_desc->launch_time = igc_tx_launchtime(adapter,
922+
txtime);
904923
} else {
905924
context_desc->launch_time = 0;
906925
}
@@ -4496,6 +4515,32 @@ static int igc_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
44964515
}
44974516
}
44984517

4518+
static int igc_save_launchtime_params(struct igc_adapter *adapter, int queue,
4519+
bool enable)
4520+
{
4521+
struct igc_ring *ring;
4522+
int i;
4523+
4524+
if (queue < 0 || queue >= adapter->num_tx_queues)
4525+
return -EINVAL;
4526+
4527+
ring = adapter->tx_ring[queue];
4528+
ring->launchtime_enable = enable;
4529+
4530+
if (adapter->base_time)
4531+
return 0;
4532+
4533+
adapter->cycle_time = NSEC_PER_SEC;
4534+
4535+
for (i = 0; i < adapter->num_tx_queues; i++) {
4536+
ring = adapter->tx_ring[i];
4537+
ring->start_time = 0;
4538+
ring->end_time = NSEC_PER_SEC;
4539+
}
4540+
4541+
return 0;
4542+
}
4543+
44994544
static bool validate_schedule(const struct tc_taprio_qopt_offload *qopt)
45004545
{
45014546
int queue_uses[IGC_MAX_TX_QUEUES] = { };
@@ -4528,6 +4573,22 @@ static bool validate_schedule(const struct tc_taprio_qopt_offload *qopt)
45284573
return true;
45294574
}
45304575

4576+
static int igc_tsn_enable_launchtime(struct igc_adapter *adapter,
4577+
struct tc_etf_qopt_offload *qopt)
4578+
{
4579+
struct igc_hw *hw = &adapter->hw;
4580+
int err;
4581+
4582+
if (hw->mac.type != igc_i225)
4583+
return -EOPNOTSUPP;
4584+
4585+
err = igc_save_launchtime_params(adapter, qopt->queue, qopt->enable);
4586+
if (err)
4587+
return err;
4588+
4589+
return igc_tsn_offload_apply(adapter);
4590+
}
4591+
45314592
static int igc_save_qbv_schedule(struct igc_adapter *adapter,
45324593
struct tc_taprio_qopt_offload *qopt)
45334594
{
@@ -4598,6 +4659,9 @@ static int igc_setup_tc(struct net_device *dev, enum tc_setup_type type,
45984659
case TC_SETUP_QDISC_TAPRIO:
45994660
return igc_tsn_enable_qbv_scheduling(adapter, type_data);
46004661

4662+
case TC_SETUP_QDISC_ETF:
4663+
return igc_tsn_enable_launchtime(adapter, type_data);
4664+
46014665
default:
46024666
return -EOPNOTSUPP;
46034667
}

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@
44
#include "igc.h"
55
#include "igc_tsn.h"
66

7+
static bool is_any_launchtime(struct igc_adapter *adapter)
8+
{
9+
int i;
10+
11+
for (i = 0; i < adapter->num_tx_queues; i++) {
12+
struct igc_ring *ring = adapter->tx_ring[i];
13+
14+
if (ring->launchtime_enable)
15+
return true;
16+
}
17+
18+
return false;
19+
}
20+
721
/* Returns the TSN specific registers to their default values after
822
* TSN offloading is disabled.
923
*/
@@ -88,6 +102,9 @@ static int igc_tsn_enable_offload(struct igc_adapter *adapter)
88102
IGC_TXQCTL_STRICT_END;
89103
}
90104

105+
if (ring->launchtime_enable)
106+
txqctl |= IGC_TXQCTL_QUEUE_MODE_LAUNCHT;
107+
91108
wr32(IGC_TXQCTL(i), txqctl);
92109
}
93110

@@ -115,7 +132,7 @@ static int igc_tsn_enable_offload(struct igc_adapter *adapter)
115132

116133
int igc_tsn_offload_apply(struct igc_adapter *adapter)
117134
{
118-
bool is_any_enabled = adapter->base_time;
135+
bool is_any_enabled = adapter->base_time || is_any_launchtime(adapter);
119136

120137
if (!(adapter->flags & IGC_FLAG_TSN_QBV_ENABLED) && !is_any_enabled)
121138
return 0;

0 commit comments

Comments
 (0)