Skip to content

Commit

Permalink
Merge branch 'am65-cpsw-rx-mq'
Browse files Browse the repository at this point in the history
Roger Quadros says:

====================
net: ethernet: ti: am65-cpsw: Add multi queue RX support

am65-cpsw can support up to 8 queues at Rx. So far we have
been using only one queue (i.e. default flow) for all RX traffic.

This series adds multi-queue support. The driver starts with
1 RX queue by default. User can increase the RX queues via ethtool,
e.g. 'ethtool -L ethx rx <N>'

The series also adds regmap and regfield support to some of the
ALE registers. It adds Policer/Classifier registers and fields.

Converting the existing ALE control APIs to regfields can be a separate
exercise.

Some helper functions are added to read/write to the Policer/Classifier
registers and a default Classifier setup function is added that
routes packets based on their PCP/DSCP priority to different RX queues.

Signed-off-by: Roger Quadros <rogerq@kernel.org>
---
Changes in v4:
- Use single macro AM65_CPSW_MAX_QUEUES for both TX and RX queues
  to simplify code
- reuse am65_cpsw_get/set_per_queue_coalesce for am65_cpsw_get/set_coalesce.
- return -EINVAL if unsupported tx/rx_coalesce_usecs in
  am65_cpsw_set_coalesce.
- reverse Xmas tree declaration order fixes in cpsw_ale
- Link to v3: https://lore.kernel.org/r/20240703-am65-cpsw-multi-rx-v3-0-f11cd860fd72@kernel.org

Changes in v3:
- code style fixes
- squashed patches 5 and 6
- added comment about priority to thread mapping table.
- Added Reviewed-by Simon Horman.
- Link to v2: https://lore.kernel.org/r/20240628-am65-cpsw-multi-rx-v2-0-c399cb77db56@kernel.org

Changes in v2:
- rebase to net/next
- fixed RX stall issue during iperf
- Link to v1: https://lore.kernel.org/r/20240606-am65-cpsw-multi-rx-v1-0-0704b0cb6fdc@kernel.org
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
davem330 committed Sep 13, 2024
2 parents 52fa3b6 + b7468c0 commit bdf2ba1
Show file tree
Hide file tree
Showing 5 changed files with 594 additions and 257 deletions.
75 changes: 29 additions & 46 deletions drivers/net/ethernet/ti/am65-cpsw-ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,9 +427,9 @@ static void am65_cpsw_get_channels(struct net_device *ndev,
{
struct am65_cpsw_common *common = am65_ndev_to_common(ndev);

ch->max_rx = AM65_CPSW_MAX_RX_QUEUES;
ch->max_tx = AM65_CPSW_MAX_TX_QUEUES;
ch->rx_count = AM65_CPSW_MAX_RX_QUEUES;
ch->max_rx = AM65_CPSW_MAX_QUEUES;
ch->max_tx = AM65_CPSW_MAX_QUEUES;
ch->rx_count = common->rx_ch_num_flows;
ch->tx_count = common->tx_ch_num;
}

Expand All @@ -447,9 +447,8 @@ static int am65_cpsw_set_channels(struct net_device *ndev,
if (common->usage_count)
return -EBUSY;

am65_cpsw_nuss_remove_tx_chns(common);

return am65_cpsw_nuss_update_tx_chns(common, chs->tx_count);
return am65_cpsw_nuss_update_tx_rx_chns(common, chs->tx_count,
chs->rx_count);
}

static void
Expand Down Expand Up @@ -913,80 +912,64 @@ static void am65_cpsw_get_mm_stats(struct net_device *ndev,
s->MACMergeHoldCount = readl(base + AM65_CPSW_STATN_IET_TX_HOLD);
}

static int am65_cpsw_get_coalesce(struct net_device *ndev, struct ethtool_coalesce *coal,
struct kernel_ethtool_coalesce *kernel_coal,
struct netlink_ext_ack *extack)
{
struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
struct am65_cpsw_tx_chn *tx_chn;

tx_chn = &common->tx_chns[0];

coal->rx_coalesce_usecs = common->rx_pace_timeout / 1000;
coal->tx_coalesce_usecs = tx_chn->tx_pace_timeout / 1000;

return 0;
}

static int am65_cpsw_get_per_queue_coalesce(struct net_device *ndev, u32 queue,
struct ethtool_coalesce *coal)
{
struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
struct am65_cpsw_rx_flow *rx_flow;
struct am65_cpsw_tx_chn *tx_chn;

if (queue >= AM65_CPSW_MAX_TX_QUEUES)
if (queue >= AM65_CPSW_MAX_QUEUES)
return -EINVAL;

tx_chn = &common->tx_chns[queue];

coal->tx_coalesce_usecs = tx_chn->tx_pace_timeout / 1000;

rx_flow = &common->rx_chns.flows[queue];
coal->rx_coalesce_usecs = rx_flow->rx_pace_timeout / 1000;

return 0;
}

static int am65_cpsw_set_coalesce(struct net_device *ndev, struct ethtool_coalesce *coal,
static int am65_cpsw_get_coalesce(struct net_device *ndev, struct ethtool_coalesce *coal,
struct kernel_ethtool_coalesce *kernel_coal,
struct netlink_ext_ack *extack)
{
struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
struct am65_cpsw_tx_chn *tx_chn;

tx_chn = &common->tx_chns[0];

if (coal->rx_coalesce_usecs && coal->rx_coalesce_usecs < 20)
return -EINVAL;

if (coal->tx_coalesce_usecs && coal->tx_coalesce_usecs < 20)
return -EINVAL;

common->rx_pace_timeout = coal->rx_coalesce_usecs * 1000;
tx_chn->tx_pace_timeout = coal->tx_coalesce_usecs * 1000;

return 0;
return am65_cpsw_get_per_queue_coalesce(ndev, 0, coal);
}

static int am65_cpsw_set_per_queue_coalesce(struct net_device *ndev, u32 queue,
struct ethtool_coalesce *coal)
{
struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
struct am65_cpsw_rx_flow *rx_flow;
struct am65_cpsw_tx_chn *tx_chn;

if (queue >= AM65_CPSW_MAX_TX_QUEUES)
if (queue >= AM65_CPSW_MAX_QUEUES)
return -EINVAL;

tx_chn = &common->tx_chns[queue];

if (coal->tx_coalesce_usecs && coal->tx_coalesce_usecs < 20) {
dev_info(common->dev, "defaulting to min value of 20us for tx-usecs for tx-%u\n",
queue);
coal->tx_coalesce_usecs = 20;
}
if (coal->tx_coalesce_usecs && coal->tx_coalesce_usecs < 20)
return -EINVAL;

tx_chn->tx_pace_timeout = coal->tx_coalesce_usecs * 1000;

rx_flow = &common->rx_chns.flows[queue];
if (coal->rx_coalesce_usecs && coal->rx_coalesce_usecs < 20)
return -EINVAL;

rx_flow->rx_pace_timeout = coal->rx_coalesce_usecs * 1000;

return 0;
}

static int am65_cpsw_set_coalesce(struct net_device *ndev, struct ethtool_coalesce *coal,
struct kernel_ethtool_coalesce *kernel_coal,
struct netlink_ext_ack *extack)
{
return am65_cpsw_set_per_queue_coalesce(ndev, 0, coal);
}

const struct ethtool_ops am65_cpsw_ethtool_ops_slave = {
.begin = am65_cpsw_ethtool_op_begin,
.complete = am65_cpsw_ethtool_op_complete,
Expand Down
Loading

0 comments on commit bdf2ba1

Please sign in to comment.