Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp1641856imm; Thu, 14 Jun 2018 01:10:03 -0700 (PDT) X-Google-Smtp-Source: ADUXVKLYXLevRfp8aKeoHXkzm9Qc5chPsTwK0G0n5KZTUUHsz1IZynwwC2i142Cbc4TxXaOc9pQK X-Received: by 2002:a17:902:9685:: with SMTP id n5-v6mr1846846plp.15.1528963803609; Thu, 14 Jun 2018 01:10:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528963803; cv=none; d=google.com; s=arc-20160816; b=wX05ST2JhkO+4hf9QSBL3QAZqsLJnTm7lGuQTpUBwHkaN5YGjHJj3xjWuWcptLHPhz QUJiTX3aaizpZhwrzpHHHtAFl8Bwo843RGup3DqjXzZQvu1OGoGtDQ7pTOTgx9vchogv r56KfkHy8M40LQAtTNyHwOOF87MXIn40Id8wFvJPs9rA6FTa0oJN3PQMT/HPoTLxK1u9 D1g/slcq+13KDTlpXsWuy69aaUct613uHJ1FsBDh6H0Dl5whgNKH+Dv2/SRYc/0Nt/HK 9YhSsivq9qAFq3fVdSyJlKMOjbJS5bYmgoM7R0NXBGgmXP1ukiIDXQ+vOt+GGQVEPq/X DHkA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-transfer-encoding:content-disposition:mime-version :references:message-id:subject:cc:to:from:date:dkim-signature :arc-authentication-results; bh=PAgv24aXR2FV0sL7UMLQhUX29wSzcBLsr4/muIepMRA=; b=LybiViQ9yhkj+0kGrNxBl3Ufe0IXsyM9OUm2R2+U40ZUyXMXT7RrHhfvFMI2m/TBoG t3nVisVQCP0ay+25BR8uWn7q9116SRjIzONKbcNf2OTzSIrfR1Af+aRUMnRbMJ7Yn3KS C6PVJxv67KOAjlgeX+kLnMsXbxLw/bD/TfVLSTqJTIALEjzTzJOoRUahWA1rAXmSsp4W 3DfQFgu+b4P/i6B4d2RLM2e7XcGFMwE4sgqvkgLmU6XRAs8MY1dbOYUNuMGTs0Db3xAl Flqr9GetfYWkS+XXHsjlSW8xLCAW+6OxJ2556+abr3mDs4a/SDYRP/Q5Ro9feFSYl+wR 79bA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=bFPFp3EJ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p91-v6si4625655plb.457.2018.06.14.01.09.49; Thu, 14 Jun 2018 01:10:03 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=bFPFp3EJ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754730AbeFNIJP (ORCPT + 99 others); Thu, 14 Jun 2018 04:09:15 -0400 Received: from mail-wr0-f196.google.com ([209.85.128.196]:35358 "EHLO mail-wr0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752791AbeFNIJI (ORCPT ); Thu, 14 Jun 2018 04:09:08 -0400 Received: by mail-wr0-f196.google.com with SMTP id l10-v6so5377113wrn.2 for ; Thu, 14 Jun 2018 01:09:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to :user-agent; bh=PAgv24aXR2FV0sL7UMLQhUX29wSzcBLsr4/muIepMRA=; b=bFPFp3EJs+M0x1FE7nK5YUxRbvqDwAxxAjHQGWKobR/NqMPi6QOw4VAnw93QDD4QXP CkTnIACPixt5ydQ2ReWpJKhKvv7XjQh+ytDmVzAx2S/G9t0jz72cF+6myax42R7ejcMz LFkzMm4h+TO7/LzuMwOBzOuM/aEf9jtJk2Nes= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to:user-agent; bh=PAgv24aXR2FV0sL7UMLQhUX29wSzcBLsr4/muIepMRA=; b=ZLAKU16oZ1kTxYP5VCTEk/LinuThcRXsctxcCEPvIxtWKHOtCF/Q22HpAfrAVW9q/a QQBGtIvhRwvB04t1R91hoQdNYPh06ZloIjOhaTAWKTLjEVH0YhuTrUSPvL2x+T9UK5+h BRgyxxl0ObtHXZVee0TTVdIuKWd4t9haEV2fjQo/KqmA5W8dn/Shb1ixLhLBCl0QTwhk /ebeW8ek1aKmUoRfqQ2wXEMCum6BeZ/n3ZU0/7eibMU2nLdnst2ZSRLbu5sbttzInZMe iBBZg4tAKiWhD0i7Lguwb+A5CJhXV+NjsPnp1ve/cuNtQdIRwQ2Anu310hhv0gs7T3d7 /ptg== X-Gm-Message-State: APt69E0u9d/BkP1s5L7abDLGkNI5k/QTG9/7c7T9wyevAMaYnj9Z2Mxk K+eQK6Za5Fr0JAZT5T03W2B1NA== X-Received: by 2002:adf:e311:: with SMTP id b17-v6mr1317430wrj.158.1528963746506; Thu, 14 Jun 2018 01:09:06 -0700 (PDT) Received: from apalos ([2a02:587:4609:4e00:6c01:5076:e5d5:7a4c]) by smtp.gmail.com with ESMTPSA id b74-v6sm6321714wmi.13.2018.06.14.01.09.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Jun 2018 01:09:05 -0700 (PDT) Date: Thu, 14 Jun 2018 11:09:02 +0300 From: Ilias Apalodimas To: Ivan Khoronzhuk Cc: grygorii.strashko@ti.com, davem@davemloft.net, corbet@lwn.net, akpm@linux-foundation.org, netdev@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org, vinicius.gomes@intel.com, henrik@austad.us, jesus.sanchez-palencia@intel.com, p-varis@ti.com, spatton@ti.com, francois.ozog@linaro.org, yogeshs@ti.com, nsekhar@ti.com, andrew@lunn.ch Subject: Re: [PATCH v2 net-next 4/6] net: ethernet: ti: cpsw: add CBS Qdisc offload Message-ID: <20180614080902.GA8377@apalos> References: <20180614073650.29659-1-ivan.khoronzhuk@linaro.org> <20180614073650.29659-5-ivan.khoronzhuk@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20180614073650.29659-5-ivan.khoronzhuk@linaro.org> User-Agent: Mutt/1.5.24 (2015-08-30) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Jun 14, 2018 at 10:36:48AM +0300, Ivan Khoronzhuk wrote: > The cpsw has up to 4 FIFOs per port and upper 3 FIFOs can feed rate > limited queue with shaping. In order to set and enable shaping for > those 3 FIFOs queues the network device with CBS qdisc attached is > needed. The CBS configuration is added for dual-emac/single port mode > only, but potentially can be used in switch mode also, based on > switchdev for instance. > > Despite the FIFO shapers can work w/o cpdma level shapers the base > usage must be in combine with cpdma level shapers as described in TRM, > that are set as maximum rates for interface queues with sysfs. > > One of the possible configuration with txq shapers and CBS shapers: > > Configured with echo RATE > > /sys/class/net/eth0/queues/tx-0/tx_maxrate > /--------------------------------------------------- > / > / cpdma level shapers > +----+ +----+ +----+ +----+ +----+ +----+ +----+ +----+ > | c7 | | c6 | | c5 | | c4 | | c3 | | c2 | | c1 | | c0 | > \ / \ / \ / \ / \ / \ / \ / \ / > \ / \ / \ / \ / \ / \ / \ / \ / > \/ \/ \/ \/ \/ \/ \/ \/ > +---------|------|------|------|-------------------------------------+ > | +----+ | | +---+ | > | | +----+ | | | > | v v v v | > | +----+ +----+ +----+ +----+ p p+----+ +----+ +----+ +----+ | > | | | | | | | | | o o| | | | | | | | | > | | f3 | | f2 | | f1 | | f0 | r CPSW r| f3 | | f2 | | f1 | | f0 | | > | | | | | | | | | t t| | | | | | | | | > | \ / \ / \ / \ / 0 1\ / \ / \ / \ / | > | \ X \ / \ / \ / \ / \ / \ / \ / | > | \/ \ \/ \/ \/ \/ \/ \/ \/ | > +-------\------------------------------------------------------------+ > \ > \ FIFO shaper, set with CBS offload added in this patch, > \ FIFO0 cannot be rate limited > ------------------------------------------------------ > > CBS shaper configuration is supposed to be used with root MQPRIO Qdisc > offload allowing to add sk_prio->tc->txq maps that direct traffic to > appropriate tx queue and maps L2 priority to FIFO shaper. > > The CBS shaper is intended to be used for AVB where L2 priority > (pcp field) is used to differentiate class of traffic. So additionally > vlan needs to be created with appropriate egress sk_prio->l2 prio map. > > If CBS has several tx queues assigned to it, the sum of their > bandwidth has not overlap bandwidth set for CBS. It's recomended the > CBS bandwidth to be a little bit more. > > The CBS shaper is configured with CBS qdisc offload interface using tc > tool from iproute2 packet. > > For instance: > > $ tc qdisc replace dev eth0 handle 100: parent root mqprio 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 hw 1 > > $ tc -g class show dev eth0 > +---(100:ffe2) mqprio > | ???+---(100:3) mqprio > | ???+---(100:4) mqprio > | ??? > +---(100:ffe1) mqprio > | ???+---(100:2) mqprio > | ??? > +---(100:ffe0) mqprio > ????+---(100:1) mqprio > > $ tc qdisc add dev eth0 parent 100:1 cbs locredit -1440 \ > hicredit 60 sendslope -960000 idleslope 40000 offload 1 > > $ tc qdisc add dev eth0 parent 100:2 cbs locredit -1470 \ > hicredit 62 sendslope -980000 idleslope 20000 offload 1 > > The above code set CBS shapers for tc0 and tc1, for that txq0 and > txq1 is used. Pay attention, the real set bandwidth can differ a bit > due to discreteness of configuration parameters. > > Here parameters like locredit, hicredit and sendslope are ignored > internally and are supposed to be set with assumption that maximum > frame size for frame - 1500. > > It's supposed that interface speed is not changed while reconnection, > not always is true, so inform user in case speed of interface was > changed, as it can impact on dependent shapers configuration. > > For more examples see Documentation. > > Signed-off-by: Ivan Khoronzhuk > --- > drivers/net/ethernet/ti/cpsw.c | 221 +++++++++++++++++++++++++++++++++ > 1 file changed, 221 insertions(+) > > diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c > index edd14def98df..3623c2994ddf 100644 > --- a/drivers/net/ethernet/ti/cpsw.c > +++ b/drivers/net/ethernet/ti/cpsw.c > @@ -46,6 +46,8 @@ > #include "cpts.h" > #include "davinci_cpdma.h" > > +#include > + > #define CPSW_DEBUG (NETIF_MSG_HW | NETIF_MSG_WOL | \ > NETIF_MSG_DRV | NETIF_MSG_LINK | \ > NETIF_MSG_IFUP | NETIF_MSG_INTR | \ > @@ -154,8 +156,12 @@ do { \ > #define IRQ_NUM 2 > #define CPSW_MAX_QUEUES 8 > #define CPSW_CPDMA_DESCS_POOL_SIZE_DEFAULT 256 > +#define CPSW_FIFO_QUEUE_TYPE_SHIFT 16 > +#define CPSW_FIFO_SHAPE_EN_SHIFT 16 > +#define CPSW_FIFO_RATE_EN_SHIFT 20 > #define CPSW_TC_NUM 4 > #define CPSW_FIFO_SHAPERS_NUM (CPSW_TC_NUM - 1) > +#define CPSW_PCT_MASK 0x7f > > #define CPSW_RX_VLAN_ENCAP_HDR_PRIO_SHIFT 29 > #define CPSW_RX_VLAN_ENCAP_HDR_PRIO_MSK GENMASK(2, 0) > @@ -457,6 +463,8 @@ struct cpsw_priv { > bool rx_pause; > bool tx_pause; > bool mqprio_hw; > + int fifo_bw[CPSW_TC_NUM]; > + int shp_cfg_speed; > u32 emac_port; > struct cpsw_common *cpsw; > }; > @@ -1081,6 +1089,38 @@ static void cpsw_set_slave_mac(struct cpsw_slave *slave, > slave_write(slave, mac_lo(priv->mac_addr), SA_LO); > } > > +static bool cpsw_shp_is_off(struct cpsw_priv *priv) > +{ > + struct cpsw_common *cpsw = priv->cpsw; > + struct cpsw_slave *slave; > + u32 shift, mask, val; > + > + val = readl_relaxed(&cpsw->regs->ptype); > + > + slave = &cpsw->slaves[cpsw_slave_index(cpsw, priv)]; > + shift = CPSW_FIFO_SHAPE_EN_SHIFT + 3 * slave->slave_num; > + mask = 7 << shift; > + val = val & mask; > + > + return !val; > +} > + > +static void cpsw_fifo_shp_on(struct cpsw_priv *priv, int fifo, int on) > +{ > + struct cpsw_common *cpsw = priv->cpsw; > + struct cpsw_slave *slave; > + u32 shift, mask, val; > + > + val = readl_relaxed(&cpsw->regs->ptype); > + > + slave = &cpsw->slaves[cpsw_slave_index(cpsw, priv)]; > + shift = CPSW_FIFO_SHAPE_EN_SHIFT + 3 * slave->slave_num; > + mask = (1 << --fifo) << shift; > + val = on ? val | mask : val & ~mask; > + > + writel_relaxed(val, &cpsw->regs->ptype); > +} > + > static void _cpsw_adjust_link(struct cpsw_slave *slave, > struct cpsw_priv *priv, bool *link) > { > @@ -1120,6 +1160,12 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave, > mac_control |= BIT(4); > > *link = true; > + > + if (priv->shp_cfg_speed && > + priv->shp_cfg_speed != slave->phy->speed && > + !cpsw_shp_is_off(priv)) > + dev_warn(priv->dev, > + "Speed was changed, CBS sahper speeds are changed!"); typo here, should be shaper > } else { > mac_control = 0; > /* disable forwarding */ > @@ -1589,6 +1635,178 @@ static int cpsw_tc_to_fifo(int tc, int num_tc) > return CPSW_FIFO_SHAPERS_NUM - tc; > } > > +static int cpsw_set_fifo_bw(struct cpsw_priv *priv, int fifo, int bw) > +{ > + struct cpsw_common *cpsw = priv->cpsw; > + u32 val = 0, send_pct, shift; > + struct cpsw_slave *slave; > + int pct = 0, i; > + > + if (bw > priv->shp_cfg_speed * 1000) > + goto err; > + > + /* shaping has to stay enabled for highest fifos linearly > + * and fifo bw no more then interface can allow > + */ > + slave = &cpsw->slaves[cpsw_slave_index(cpsw, priv)]; > + send_pct = slave_read(slave, SEND_PERCENT); > + for (i = CPSW_FIFO_SHAPERS_NUM; i > 0; i--) { > + if (!bw) { > + if (i >= fifo || !priv->fifo_bw[i]) > + continue; > + > + dev_warn(priv->dev, "Prev FIFO%d is shaped", i); > + continue; > + } > + > + if (!priv->fifo_bw[i] && i > fifo) { > + dev_err(priv->dev, "Upper FIFO%d is not shaped", i); > + return -EINVAL; > + } > + > + shift = (i - 1) * 8; > + if (i == fifo) { > + send_pct &= ~(CPSW_PCT_MASK << shift); > + val = DIV_ROUND_UP(bw, priv->shp_cfg_speed * 10); > + if (!val) > + val = 1; > + > + send_pct |= val << shift; > + pct += val; > + continue; > + } > + > + if (priv->fifo_bw[i]) > + pct += (send_pct >> shift) & CPSW_PCT_MASK; > + } > + > + if (pct >= 100) > + goto err; > + > + slave_write(slave, send_pct, SEND_PERCENT); > + priv->fifo_bw[fifo] = bw; > + > + dev_warn(priv->dev, "set FIFO%d bw = %d\n", fifo, > + DIV_ROUND_CLOSEST(val * priv->shp_cfg_speed, 100)); > + > + return 0; > +err: > + dev_err(priv->dev, "Bandwidth doesn't fit in tc configuration"); > + return -EINVAL; > +} > + > +static int cpsw_set_fifo_rlimit(struct cpsw_priv *priv, int fifo, int bw) > +{ > + struct cpsw_common *cpsw = priv->cpsw; > + struct cpsw_slave *slave; > + u32 tx_in_ctl_rg, val; > + int ret; > + > + ret = cpsw_set_fifo_bw(priv, fifo, bw); > + if (ret) > + return ret; > + > + slave = &cpsw->slaves[cpsw_slave_index(cpsw, priv)]; > + tx_in_ctl_rg = cpsw->version == CPSW_VERSION_1 ? > + CPSW1_TX_IN_CTL : CPSW2_TX_IN_CTL; > + > + if (!bw) > + cpsw_fifo_shp_on(priv, fifo, bw); > + > + val = slave_read(slave, tx_in_ctl_rg); > + if (cpsw_shp_is_off(priv)) { > + /* disable FIFOs rate limited queues */ > + val &= ~(0xf << CPSW_FIFO_RATE_EN_SHIFT); > + > + /* set type of FIFO queues to normal priority mode */ > + val &= ~(3 << CPSW_FIFO_QUEUE_TYPE_SHIFT); > + > + /* set type of FIFO queues to be rate limited */ > + if (bw) > + val |= 2 << CPSW_FIFO_QUEUE_TYPE_SHIFT; > + else > + priv->shp_cfg_speed = 0; > + } > + > + /* toggle a FIFO rate limited queue */ > + if (bw) > + val |= BIT(fifo + CPSW_FIFO_RATE_EN_SHIFT); > + else > + val &= ~BIT(fifo + CPSW_FIFO_RATE_EN_SHIFT); > + slave_write(slave, val, tx_in_ctl_rg); > + > + /* FIFO transmit shape enable */ > + cpsw_fifo_shp_on(priv, fifo, bw); > + return 0; > +} > + > +/* Defaults: > + * class A - prio 3 > + * class B - prio 2 > + * shaping for class A should be set first > + */ > +static int cpsw_set_cbs(struct net_device *ndev, > + struct tc_cbs_qopt_offload *qopt) > +{ > + struct cpsw_priv *priv = netdev_priv(ndev); > + struct cpsw_common *cpsw = priv->cpsw; > + struct cpsw_slave *slave; > + int prev_speed = 0; > + int tc, ret, fifo; > + u32 bw = 0; > + > + tc = netdev_txq_to_tc(priv->ndev, qopt->queue); > + > + /* enable channels in backward order, as highest FIFOs must be rate > + * limited first and for compliance with CPDMA rate limited channels > + * that also used in bacward order. FIFO0 cannot be rate limited. > + */ > + fifo = cpsw_tc_to_fifo(tc, ndev->num_tc); > + if (!fifo) { > + dev_err(priv->dev, "Last tc%d can't be rate limited", tc); > + return -EINVAL; > + } > + > + /* do nothing, it's disabled anyway */ > + if (!qopt->enable && !priv->fifo_bw[fifo]) > + return 0; > + > + /* shapers can be set if link speed is known */ > + slave = &cpsw->slaves[cpsw_slave_index(cpsw, priv)]; > + if (slave->phy && slave->phy->link) { > + if (priv->shp_cfg_speed && > + priv->shp_cfg_speed != slave->phy->speed) > + prev_speed = priv->shp_cfg_speed; > + > + priv->shp_cfg_speed = slave->phy->speed; > + } > + > + if (!priv->shp_cfg_speed) { > + dev_err(priv->dev, "Link speed is not known"); > + return -1; > + } > + > + ret = pm_runtime_get_sync(cpsw->dev); > + if (ret < 0) { > + pm_runtime_put_noidle(cpsw->dev); > + return ret; > + } > + > + bw = qopt->enable ? qopt->idleslope : 0; > + ret = cpsw_set_fifo_rlimit(priv, fifo, bw); > + if (ret) { > + priv->shp_cfg_speed = prev_speed; > + prev_speed = 0; > + } > + > + if (bw && prev_speed) > + dev_warn(priv->dev, > + "Speed was changed, CBS sahper speeds are changed!"); same c/p typo > + > + pm_runtime_put_sync(cpsw->dev); > + return ret; > +} > + > static int cpsw_ndo_open(struct net_device *ndev) > { > struct cpsw_priv *priv = netdev_priv(ndev); > @@ -2263,6 +2481,9 @@ static int cpsw_ndo_setup_tc(struct net_device *ndev, enum tc_setup_type type, > void *type_data) > { > switch (type) { > + case TC_SETUP_QDISC_CBS: > + return cpsw_set_cbs(ndev, type_data); > + > case TC_SETUP_QDISC_MQPRIO: > return cpsw_set_mqprio(ndev, type_data); > > -- > 2.17.1 > Other than that looks good