igc: Lift TAPRIO schedule restriction
Add support for Qbv schedules where one queue stays open in consecutive entries. Currently that's not supported. Example schedule: |tc qdisc replace dev ${INTERFACE} handle 100 parent root taprio num_tc 3 \ | map 2 2 1 0 2 2 2 2 2 2 2 2 2 2 2 2 \ | queues 1@0 1@1 2@2 \ | base-time ${BASETIME} \ | sched-entry S 0x01 300000 \ # Stream High/Low | sched-entry S 0x06 500000 \ # Management and Best Effort | sched-entry S 0x04 200000 \ # Best Effort | flags 0x02 Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de> Reviewed-by: Vinicius Costa Gomes <vinicius.gomes@intel.com> Tested-by: Naama Meir <naamax.meir@linux.intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
parent
6e693a1042
commit
a5fd39464a
@ -5813,9 +5813,10 @@ static bool validate_schedule(struct igc_adapter *adapter,
|
||||
return false;
|
||||
|
||||
for (n = 0; n < qopt->num_entries; n++) {
|
||||
const struct tc_taprio_sched_entry *e;
|
||||
const struct tc_taprio_sched_entry *e, *prev;
|
||||
int i;
|
||||
|
||||
prev = n ? &qopt->entries[n - 1] : NULL;
|
||||
e = &qopt->entries[n];
|
||||
|
||||
/* i225 only supports "global" frame preemption
|
||||
@ -5828,7 +5829,12 @@ static bool validate_schedule(struct igc_adapter *adapter,
|
||||
if (e->gate_mask & BIT(i))
|
||||
queue_uses[i]++;
|
||||
|
||||
if (queue_uses[i] > 1)
|
||||
/* There are limitations: A single queue cannot be
|
||||
* opened and closed multiple times per cycle unless the
|
||||
* gate stays open. Check for it.
|
||||
*/
|
||||
if (queue_uses[i] > 1 &&
|
||||
!(prev->gate_mask & BIT(i)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -5872,6 +5878,7 @@ static int igc_tsn_clear_schedule(struct igc_adapter *adapter)
|
||||
static int igc_save_qbv_schedule(struct igc_adapter *adapter,
|
||||
struct tc_taprio_qopt_offload *qopt)
|
||||
{
|
||||
bool queue_configured[IGC_MAX_TX_QUEUES] = { };
|
||||
u32 start_time = 0, end_time = 0;
|
||||
size_t n;
|
||||
|
||||
@ -5887,9 +5894,6 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
|
||||
adapter->cycle_time = qopt->cycle_time;
|
||||
adapter->base_time = qopt->base_time;
|
||||
|
||||
/* FIXME: be a little smarter about cases when the gate for a
|
||||
* queue stays open for more than one entry.
|
||||
*/
|
||||
for (n = 0; n < qopt->num_entries; n++) {
|
||||
struct tc_taprio_sched_entry *e = &qopt->entries[n];
|
||||
int i;
|
||||
@ -5902,8 +5906,15 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
|
||||
if (!(e->gate_mask & BIT(i)))
|
||||
continue;
|
||||
|
||||
ring->start_time = start_time;
|
||||
/* Check whether a queue stays open for more than one
|
||||
* entry. If so, keep the start and advance the end
|
||||
* time.
|
||||
*/
|
||||
if (!queue_configured[i])
|
||||
ring->start_time = start_time;
|
||||
ring->end_time = end_time;
|
||||
|
||||
queue_configured[i] = true;
|
||||
}
|
||||
|
||||
start_time += e->interval;
|
||||
|
Loading…
Reference in New Issue
Block a user