After the set of queues that are marked as preemptible are exposed to the driver we can configure the hardware to enable the frame preemption functionality.
Signed-off-by: Vinicius Costa Gomes <vinicius.go...@intel.com> --- drivers/net/ethernet/intel/igc/igc_main.c | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index 3af54fd9cc0d..763f39082f91 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -4817,6 +4817,23 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter, return 0; } +static int igc_save_frame_preemption(struct igc_adapter *adapter, + struct tc_preempt_qopt_offload *qopt) +{ + u32 preempt; + int i; + + preempt = qopt->preemptible_queues; + + for (i = 0; i < adapter->num_tx_queues; i++) { + struct igc_ring *ring = adapter->tx_ring[i]; + + ring->preemptible = preempt & BIT(i); + } + + return 0; +} + static int igc_tsn_enable_qbv_scheduling(struct igc_adapter *adapter, struct tc_taprio_qopt_offload *qopt) { @@ -4833,6 +4850,18 @@ static int igc_tsn_enable_qbv_scheduling(struct igc_adapter *adapter, return igc_tsn_offload_apply(adapter); } +static int igc_tsn_enable_frame_preemption(struct igc_adapter *adapter, + struct tc_preempt_qopt_offload *qopt) +{ + int err; + + err = igc_save_frame_preemption(adapter, qopt); + if (err) + return err; + + return igc_tsn_offload_apply(adapter); +} + static int igc_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data) { @@ -4845,6 +4874,9 @@ static int igc_setup_tc(struct net_device *dev, enum tc_setup_type type, case TC_SETUP_QDISC_ETF: return igc_tsn_enable_launchtime(adapter, type_data); + case TC_SETUP_PREEMPT: + return igc_tsn_enable_frame_preemption(adapter, type_data); + default: return -EOPNOTSUPP; } -- 2.29.2