Skip to content

Commit

Permalink
Merge branch '1GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/…
Browse files Browse the repository at this point in the history
…tnguy/next-

queue

Tony Nguyen says:

====================
1GbE Intel Wired LAN Driver Updates 2021-08-27

ravindhan Gunasekaran says:

This adds support for Credit-based shaper qdisc offload from
Traffic Control system. It enables traffic prioritization and
bandwidth reservation via the Credit-Based Shaper which is
implemented in hardware by i225 controller.

Patch 1/3 adds a default cycle-time for TSN mode to be configured.

Patch 2/3 helps to separate TSN mode programming on the fly and
during reset sequence. It also simplifies handling features flags
for various TSN modes supported by i225 in the driver.

Patch 3/3 adds support for IEEE802.1Qav(CBS) standard
implemented in i225 HW. Two sets of CBS HW shapers are present
in i225 and driver enables them in the two high priority queues.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Aug 29, 2021
2 parents c772251 + 1ab011b commit d65a606
Show file tree
Hide file tree
Showing 6 changed files with 258 additions and 49 deletions.
11 changes: 11 additions & 0 deletions drivers/net/ethernet/intel/igc/igc.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ struct igc_ring {
u32 start_time;
u32 end_time;

/* CBS parameters */
bool cbs_enable; /* indicates if CBS is enabled */
s32 idleslope; /* idleSlope in kbps */
s32 sendslope; /* sendSlope in kbps */
s32 hicredit; /* hiCredit in bytes */
s32 locredit; /* loCredit in bytes */

/* everything past this point are written often */
u16 next_to_clean;
u16 next_to_use;
Expand Down Expand Up @@ -290,6 +297,10 @@ extern char igc_driver_name[];
#define IGC_FLAG_VLAN_PROMISC BIT(15)
#define IGC_FLAG_RX_LEGACY BIT(16)
#define IGC_FLAG_TSN_QBV_ENABLED BIT(17)
#define IGC_FLAG_TSN_QAV_ENABLED BIT(18)

#define IGC_FLAG_TSN_ANY_ENABLED \
(IGC_FLAG_TSN_QBV_ENABLED | IGC_FLAG_TSN_QAV_ENABLED)

#define IGC_FLAG_RSS_FIELD_IPV4_UDP BIT(6)
#define IGC_FLAG_RSS_FIELD_IPV6_UDP BIT(7)
Expand Down
8 changes: 8 additions & 0 deletions drivers/net/ethernet/intel/igc/igc_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,14 @@
#define IGC_TXQCTL_QUEUE_MODE_LAUNCHT 0x00000001
#define IGC_TXQCTL_STRICT_CYCLE 0x00000002
#define IGC_TXQCTL_STRICT_END 0x00000004
#define IGC_TXQCTL_QAV_SEL_MASK 0x000000C0
#define IGC_TXQCTL_QAV_SEL_CBS0 0x00000080
#define IGC_TXQCTL_QAV_SEL_CBS1 0x000000C0

#define IGC_TQAVCC_IDLESLOPE_MASK 0xFFFF
#define IGC_TQAVCC_KEEP_CREDITS BIT(30)

#define IGC_MAX_SR_QUEUES 2

/* Receive Checksum Control */
#define IGC_RXCSUM_CRCOFL 0x00000800 /* CRC32 offload enable */
Expand Down
110 changes: 93 additions & 17 deletions drivers/net/ethernet/intel/igc/igc_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ void igc_reset(struct igc_adapter *adapter)
igc_ptp_reset(adapter);

/* Re-enable TSN offloading, where applicable. */
igc_tsn_offload_apply(adapter);
igc_tsn_reset(adapter);

igc_get_phy_info(hw);
}
Expand Down Expand Up @@ -5749,25 +5749,13 @@ static int igc_save_launchtime_params(struct igc_adapter *adapter, int queue,
bool enable)
{
struct igc_ring *ring;
int i;

if (queue < 0 || queue >= adapter->num_tx_queues)
return -EINVAL;

ring = adapter->tx_ring[queue];
ring->launchtime_enable = enable;

if (adapter->base_time)
return 0;

adapter->cycle_time = NSEC_PER_SEC;

for (i = 0; i < adapter->num_tx_queues; i++) {
ring = adapter->tx_ring[i];
ring->start_time = 0;
ring->end_time = NSEC_PER_SEC;
}

return 0;
}

Expand Down Expand Up @@ -5840,16 +5828,31 @@ static int igc_tsn_enable_launchtime(struct igc_adapter *adapter,
return igc_tsn_offload_apply(adapter);
}

static int igc_tsn_clear_schedule(struct igc_adapter *adapter)
{
int i;

adapter->base_time = 0;
adapter->cycle_time = NSEC_PER_SEC;

for (i = 0; i < adapter->num_tx_queues; i++) {
struct igc_ring *ring = adapter->tx_ring[i];

ring->start_time = 0;
ring->end_time = NSEC_PER_SEC;
}

return 0;
}

static int igc_save_qbv_schedule(struct igc_adapter *adapter,
struct tc_taprio_qopt_offload *qopt)
{
u32 start_time = 0, end_time = 0;
size_t n;

if (!qopt->enable) {
adapter->base_time = 0;
return 0;
}
if (!qopt->enable)
return igc_tsn_clear_schedule(adapter);

if (adapter->base_time)
return -EALREADY;
Expand Down Expand Up @@ -5901,6 +5904,74 @@ static int igc_tsn_enable_qbv_scheduling(struct igc_adapter *adapter,
return igc_tsn_offload_apply(adapter);
}

static int igc_save_cbs_params(struct igc_adapter *adapter, int queue,
bool enable, int idleslope, int sendslope,
int hicredit, int locredit)
{
bool cbs_status[IGC_MAX_SR_QUEUES] = { false };
struct net_device *netdev = adapter->netdev;
struct igc_ring *ring;
int i;

/* i225 has two sets of credit-based shaper logic.
* Supporting it only on the top two priority queues
*/
if (queue < 0 || queue > 1)
return -EINVAL;

ring = adapter->tx_ring[queue];

for (i = 0; i < IGC_MAX_SR_QUEUES; i++)
if (adapter->tx_ring[i])
cbs_status[i] = adapter->tx_ring[i]->cbs_enable;

/* CBS should be enabled on the highest priority queue first in order
* for the CBS algorithm to operate as intended.
*/
if (enable) {
if (queue == 1 && !cbs_status[0]) {
netdev_err(netdev,
"Enabling CBS on queue1 before queue0\n");
return -EINVAL;
}
} else {
if (queue == 0 && cbs_status[1]) {
netdev_err(netdev,
"Disabling CBS on queue0 before queue1\n");
return -EINVAL;
}
}

ring->cbs_enable = enable;
ring->idleslope = idleslope;
ring->sendslope = sendslope;
ring->hicredit = hicredit;
ring->locredit = locredit;

return 0;
}

static int igc_tsn_enable_cbs(struct igc_adapter *adapter,
struct tc_cbs_qopt_offload *qopt)
{
struct igc_hw *hw = &adapter->hw;
int err;

if (hw->mac.type != igc_i225)
return -EOPNOTSUPP;

if (qopt->queue < 0 || qopt->queue > 1)
return -EINVAL;

err = igc_save_cbs_params(adapter, qopt->queue, qopt->enable,
qopt->idleslope, qopt->sendslope,
qopt->hicredit, qopt->locredit);
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)
{
Expand All @@ -5913,6 +5984,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_QDISC_CBS:
return igc_tsn_enable_cbs(adapter, type_data);

default:
return -EOPNOTSUPP;
}
Expand Down Expand Up @@ -6339,6 +6413,8 @@ static int igc_probe(struct pci_dev *pdev,

igc_ptp_init(adapter);

igc_tsn_clear_schedule(adapter);

/* reset the hardware with the new settings */
igc_reset(adapter);

Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/intel/igc/igc_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@
#define IGC_ENDQT(_n) (0x3334 + 0x4 * (_n))
#define IGC_DTXMXPKTSZ 0x355C

#define IGC_TQAVCC(_n) (0x3004 + ((_n) * 0x40))
#define IGC_TQAVHC(_n) (0x300C + ((_n) * 0x40))

/* System Time Registers */
#define IGC_SYSTIML 0x0B600 /* System time register Low - RO */
#define IGC_SYSTIMH 0x0B604 /* System time register High - RO */
Expand Down
Loading

0 comments on commit d65a606

Please sign in to comment.