From patchwork Sat Dec 10 12:23:49 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Khoronzhuk X-Patchwork-Id: 9469265 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 96512607F2 for ; Sat, 10 Dec 2016 12:24:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 87CCF28598 for ; Sat, 10 Dec 2016 12:24:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 797A4285D6; Sat, 10 Dec 2016 12:24:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 194AA285A8 for ; Sat, 10 Dec 2016 12:24:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753239AbcLJMY3 (ORCPT ); Sat, 10 Dec 2016 07:24:29 -0500 Received: from mail-lf0-f53.google.com ([209.85.215.53]:35539 "EHLO mail-lf0-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753219AbcLJMYA (ORCPT ); Sat, 10 Dec 2016 07:24:00 -0500 Received: by mail-lf0-f53.google.com with SMTP id b14so17030882lfg.2 for ; Sat, 10 Dec 2016 04:23:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Xn65tDyNeO9Nk8egymEmZ30FNtgpdro7d7UyExMCAYY=; b=jPxyjctr6akT46VO/XZ8UGnT1Qnp2LwOyZTD8k4gIcU/DB0bXWJtrz4Na7d0o3taWZ xx48SlmKy14zV+QD9hmDleKDMM6eJfUjfCjmPGeF5KZkfmBbk8x07hK1/cNWkwPglQpE +EASnhzo91+C0cWCef8K3QWcBCQb4fKoOO8Sw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Xn65tDyNeO9Nk8egymEmZ30FNtgpdro7d7UyExMCAYY=; b=K5WT84tHv3QErNA7qhZmAzVhyO2XljKJ+nuzAbEjvTHtjTenHTVTstbX4YzXxiSvvj naBDMAcy7ewwc8+Csba9IlLefqeolDEy6c9CmlwlHFCJN2x0scK5uW9GpQdEA9urhIgA 5Tv4vvH1ao/qkrcKuo6HmNoSO1Au/o8tFHitZqZEQ9Gf0sEjaEDSriDtHqFysMnh4nyo uUWDv46rtL8osPyiE81ha8HQCtcLNqdyJL3UMSYSJBY9HJ70wNEKOgIqF23JnTYfJYqH ruVpxvzUrDhky1AgZ3xexQXJ/rY73XNzqsuIfYW1V2/5SUkWVx/IGKJjYSVdTQL35rqQ 1b5Q== X-Gm-Message-State: AKaTC02E8ti7trnrPRDfCAFWGP8TZREvVCN036SXAM87V7popcaHslHLaIEidgcuYUfGlCLl X-Received: by 10.46.5.149 with SMTP id 143mr36850718ljf.73.1481372638411; Sat, 10 Dec 2016 04:23:58 -0800 (PST) Received: from localhost.localdomain (183-224-132-95.pool.ukrtel.net. [95.132.224.183]) by smtp.gmail.com with ESMTPSA id f14sm2507060lff.40.2016.12.10.04.23.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 10 Dec 2016 04:23:57 -0800 (PST) From: Ivan Khoronzhuk To: mugunthanvnm@ti.com, grygorii.strashko@ti.com Cc: linux-omap@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Ivan Khoronzhuk Subject: [PATCH 4/5] net: ethernet: ti: cpsw: re-split res only when speed is changed Date: Sat, 10 Dec 2016 14:23:49 +0200 Message-Id: <1481372630-14914-5-git-send-email-ivan.khoronzhuk@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1481372630-14914-1-git-send-email-ivan.khoronzhuk@linaro.org> References: <1481372630-14914-1-git-send-email-ivan.khoronzhuk@linaro.org> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Don't re-split res in the following cases: - speed of phys is not changed - speed of phys is changed and no rate limited channels - speed of phys is changed and all channels are rate limited - phy is unlinked while dev is open - phy is linked back but speed is not changed The maximum speed is sum of "linked" phys, thus res are split taken in account two interfaces, both for dual emac mode and for switch mode. Signed-off-by: Ivan Khoronzhuk --- drivers/net/ethernet/ti/cpsw.c | 64 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index a2c2c06..7ccfa63 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -394,6 +394,7 @@ struct cpsw_common { u32 irqs_table[IRQ_NUM]; struct cpts *cpts; int rx_ch_num, tx_ch_num; + int speed; }; struct cpsw_priv { @@ -761,7 +762,6 @@ static void cpsw_split_res(struct net_device *ndev) struct cpsw_vector *txv = cpsw->txv; int i, ch_weight, rlim_ch_num = 0; int budget, bigest_rate_ch = 0; - struct cpsw_slave *slave; u32 ch_rate, max_rate; int ch_budget = 0; @@ -781,8 +781,16 @@ static void cpsw_split_res(struct net_device *ndev) bigest_rate = 0; max_rate = consumed_rate; } else { - slave = &cpsw->slaves[cpsw_slave_index(cpsw, priv)]; - max_rate = slave->phy->speed * 1000; + max_rate = cpsw->speed * 1000; + + /* if max_rate is less then expected due to reduced link speed, + * split proportionally according next potential max speed + */ + if (max_rate < consumed_rate) + max_rate *= 10; + + if (max_rate < consumed_rate) + max_rate *= 10; ch_budget = (consumed_rate * CPSW_POLL_WEIGHT) / max_rate; ch_budget = (CPSW_POLL_WEIGHT - ch_budget) / @@ -1013,15 +1021,56 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave, slave->mac_control = mac_control; } +static int cpsw_get_common_speed(struct cpsw_common *cpsw) +{ + int i, speed; + + for (i = 0, speed = 0; i < cpsw->data.slaves; i++) + if (cpsw->slaves[i].phy && cpsw->slaves[i].phy->link) + speed += cpsw->slaves[i].phy->speed; + + return speed; +} + +static int cpsw_need_resplit(struct cpsw_common *cpsw) +{ + int i, rlim_ch_num; + int speed, ch_rate; + + /* re-split resources only in case speed was changed */ + speed = cpsw_get_common_speed(cpsw); + if (speed == cpsw->speed || !speed) + return 0; + + cpsw->speed = speed; + + for (i = 0, rlim_ch_num = 0; i < cpsw->tx_ch_num; i++) { + ch_rate = cpdma_chan_get_rate(cpsw->txv[i].ch); + if (!ch_rate) + break; + + rlim_ch_num++; + } + + /* cases not dependent on speed */ + if (!rlim_ch_num || rlim_ch_num == cpsw->tx_ch_num) + return 0; + + return 1; +} + static void cpsw_adjust_link(struct net_device *ndev) { struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = priv->cpsw; bool link = false; for_each_slave(priv, _cpsw_adjust_link, priv, &link); if (link) { - cpsw_split_res(priv->ndev); + if (cpsw_need_resplit(cpsw)) + cpsw_split_res(ndev); + netif_carrier_on(ndev); if (netif_running(ndev)) netif_tx_wake_all_queues(ndev); @@ -1538,6 +1587,10 @@ static int cpsw_ndo_stop(struct net_device *ndev) cpsw_ale_stop(cpsw->ale); } for_each_slave(priv, cpsw_slave_stop, cpsw); + + if (cpsw_need_resplit(cpsw)) + cpsw_split_res(ndev); + pm_runtime_put_sync(cpsw->dev); if (cpsw->data.dual_emac) cpsw->slaves[priv->emac_port].open_stat = false; @@ -1983,7 +2036,7 @@ static int cpsw_ndo_set_tx_maxrate(struct net_device *ndev, int queue, u32 rate) return -EINVAL; } - if (rate > 2000) { + if (rate > cpsw->speed) { dev_err(priv->dev, "The channel rate cannot be more than 2Gbps"); return -EINVAL; } @@ -2998,6 +3051,7 @@ static int cpsw_probe(struct platform_device *pdev) ndev->ethtool_ops = &cpsw_ethtool_ops; netif_napi_add(ndev, &cpsw->napi_rx, cpsw_rx_poll, CPSW_POLL_WEIGHT); netif_tx_napi_add(ndev, &cpsw->napi_tx, cpsw_tx_poll, CPSW_POLL_WEIGHT); + cpsw_split_res(ndev); /* register the network device */ SET_NETDEV_DEV(ndev, &pdev->dev);