-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
igc: Add support for taprio offloading
Adds support for translating taprio schedules into i225 cycles. This will allow schedules to run in the hardware, making the schedules enforcement more precise and saving CPU time. Right now, the only simple schedules are allowed, complex schedules are rejected. "simple" in this context are schedules that each HW queue is opened and closed only once in each cycle. Changing schedules is still not supported as well. Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com> Reviewed-by: Andre Guedes <andre.guedes@intel.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
- Loading branch information
Vinicius Costa Gomes
authored and
Jeff Kirsher
committed
Apr 17, 2020
1 parent
34428df
commit ec50a9d
Showing
7 changed files
with
294 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* Copyright (c) 2019 Intel Corporation */ | ||
|
||
#include "igc.h" | ||
#include "igc_tsn.h" | ||
|
||
/* Returns the TSN specific registers to their default values after | ||
* TSN offloading is disabled. | ||
*/ | ||
static int igc_tsn_disable_offload(struct igc_adapter *adapter) | ||
{ | ||
struct igc_hw *hw = &adapter->hw; | ||
u32 tqavctrl; | ||
int i; | ||
|
||
if (!(adapter->flags & IGC_FLAG_TSN_QBV_ENABLED)) | ||
return 0; | ||
|
||
adapter->cycle_time = 0; | ||
|
||
wr32(IGC_TXPBS, I225_TXPBSIZE_DEFAULT); | ||
wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_DEFAULT); | ||
|
||
tqavctrl = rd32(IGC_TQAVCTRL); | ||
tqavctrl &= ~(IGC_TQAVCTRL_TRANSMIT_MODE_TSN | | ||
IGC_TQAVCTRL_ENHANCED_QAV); | ||
wr32(IGC_TQAVCTRL, tqavctrl); | ||
|
||
for (i = 0; i < adapter->num_tx_queues; i++) { | ||
struct igc_ring *ring = adapter->tx_ring[i]; | ||
|
||
ring->start_time = 0; | ||
ring->end_time = 0; | ||
ring->launchtime_enable = false; | ||
|
||
wr32(IGC_TXQCTL(i), 0); | ||
wr32(IGC_STQT(i), 0); | ||
wr32(IGC_ENDQT(i), NSEC_PER_SEC); | ||
} | ||
|
||
wr32(IGC_QBVCYCLET_S, NSEC_PER_SEC); | ||
wr32(IGC_QBVCYCLET, NSEC_PER_SEC); | ||
|
||
adapter->flags &= ~IGC_FLAG_TSN_QBV_ENABLED; | ||
|
||
return 0; | ||
} | ||
|
||
static int igc_tsn_enable_offload(struct igc_adapter *adapter) | ||
{ | ||
struct igc_hw *hw = &adapter->hw; | ||
u32 tqavctrl, baset_l, baset_h; | ||
u32 sec, nsec, cycle; | ||
ktime_t base_time, systim; | ||
int i; | ||
|
||
if (adapter->flags & IGC_FLAG_TSN_QBV_ENABLED) | ||
return 0; | ||
|
||
cycle = adapter->cycle_time; | ||
base_time = adapter->base_time; | ||
|
||
wr32(IGC_TSAUXC, 0); | ||
wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_TSN); | ||
wr32(IGC_TXPBS, IGC_TXPBSIZE_TSN); | ||
|
||
tqavctrl = rd32(IGC_TQAVCTRL); | ||
tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN | IGC_TQAVCTRL_ENHANCED_QAV; | ||
wr32(IGC_TQAVCTRL, tqavctrl); | ||
|
||
wr32(IGC_QBVCYCLET_S, cycle); | ||
wr32(IGC_QBVCYCLET, cycle); | ||
|
||
for (i = 0; i < adapter->num_tx_queues; i++) { | ||
struct igc_ring *ring = adapter->tx_ring[i]; | ||
u32 txqctl = 0; | ||
|
||
wr32(IGC_STQT(i), ring->start_time); | ||
wr32(IGC_ENDQT(i), ring->end_time); | ||
|
||
if (adapter->base_time) { | ||
/* If we have a base_time we are in "taprio" | ||
* mode and we need to be strict about the | ||
* cycles: only transmit a packet if it can be | ||
* completed during that cycle. | ||
*/ | ||
txqctl |= IGC_TXQCTL_STRICT_CYCLE | | ||
IGC_TXQCTL_STRICT_END; | ||
} | ||
|
||
wr32(IGC_TXQCTL(i), txqctl); | ||
} | ||
|
||
nsec = rd32(IGC_SYSTIML); | ||
sec = rd32(IGC_SYSTIMH); | ||
|
||
systim = ktime_set(sec, nsec); | ||
|
||
if (ktime_compare(systim, base_time) > 0) { | ||
s64 n; | ||
|
||
n = div64_s64(ktime_sub_ns(systim, base_time), cycle); | ||
base_time = ktime_add_ns(base_time, (n + 1) * cycle); | ||
} | ||
|
||
baset_h = div_s64_rem(base_time, NSEC_PER_SEC, &baset_l); | ||
|
||
wr32(IGC_BASET_H, baset_h); | ||
wr32(IGC_BASET_L, baset_l); | ||
|
||
adapter->flags |= IGC_FLAG_TSN_QBV_ENABLED; | ||
|
||
return 0; | ||
} | ||
|
||
int igc_tsn_offload_apply(struct igc_adapter *adapter) | ||
{ | ||
bool is_any_enabled = adapter->base_time; | ||
|
||
if (!(adapter->flags & IGC_FLAG_TSN_QBV_ENABLED) && !is_any_enabled) | ||
return 0; | ||
|
||
if (!is_any_enabled) { | ||
int err = igc_tsn_disable_offload(adapter); | ||
|
||
if (err < 0) | ||
return err; | ||
|
||
/* The BASET registers aren't cleared when writing | ||
* into them, force a reset if the interface is | ||
* running. | ||
*/ | ||
if (netif_running(adapter->netdev)) | ||
schedule_work(&adapter->reset_task); | ||
|
||
return 0; | ||
} | ||
|
||
return igc_tsn_enable_offload(adapter); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* Copyright (c) 2020 Intel Corporation */ | ||
|
||
#ifndef _IGC_TSN_H_ | ||
#define _IGC_TSN_H_ | ||
|
||
int igc_tsn_offload_apply(struct igc_adapter *adapter); | ||
|
||
#endif /* _IGC_BASE_H */ |