From patchwork Mon Jun 10 17:19:48 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Claudiu Manoil X-Patchwork-Id: 250324 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 8D34D2C0097 for ; Tue, 11 Jun 2013 03:20:36 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753417Ab3FJRUc (ORCPT ); Mon, 10 Jun 2013 13:20:32 -0400 Received: from co9ehsobe001.messaging.microsoft.com ([207.46.163.24]:32619 "EHLO co9outboundpool.messaging.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751751Ab3FJRUa (ORCPT ); Mon, 10 Jun 2013 13:20:30 -0400 Received: from mail91-co9-R.bigfish.com (10.236.132.253) by CO9EHSOBE020.bigfish.com (10.236.130.83) with Microsoft SMTP Server id 14.1.225.23; Mon, 10 Jun 2013 17:20:29 +0000 Received: from mail91-co9 (localhost [127.0.0.1]) by mail91-co9-R.bigfish.com (Postfix) with ESMTP id ABB38B0031F; Mon, 10 Jun 2013 17:20:29 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 0 X-BigFish: VS0(zzzz1f42h1ee6h1de0h1fdah1202h1e76h1d1ah1d2ah1fc6hzz8275bhz2dh2a8h668h839hd24he5bhf0ah107ah11b5h121eh1288h12a5h12a9h12bdh12e5h137ah139eh13b6h1441h14afh1504h1537h162dh1631h1758h1898h18e1h1946h19b5h1ad9h1b0ah1d0ch1d2eh1d3fh1dfeh1dffh1e1dh1e23h1155h) Received: from mail91-co9 (localhost.localdomain [127.0.0.1]) by mail91-co9 (MessageSwitch) id 1370884826444812_12920; Mon, 10 Jun 2013 17:20:26 +0000 (UTC) Received: from CO9EHSMHS022.bigfish.com (unknown [10.236.132.235]) by mail91-co9.bigfish.com (Postfix) with ESMTP id 4A11078009D; Mon, 10 Jun 2013 17:20:26 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by CO9EHSMHS022.bigfish.com (10.236.130.32) with Microsoft SMTP Server (TLS) id 14.1.225.23; Mon, 10 Jun 2013 17:20:23 +0000 Received: from tx30smr01.am.freescale.net (10.81.153.31) by 039-SN1MMR1-005.039d.mgd.msft.net (10.84.1.17) with Microsoft SMTP Server (TLS) id 14.2.328.11; Mon, 10 Jun 2013 17:20:22 +0000 Received: from zro04cle141.ea.freescale.net (udp157456uds.ea.freescale.net [140.101.223.141]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id r5AHKKIM011662; Mon, 10 Jun 2013 10:20:20 -0700 Received: by zro04cle141.ea.freescale.net (Postfix, from userid 23113) id 1155240080; Mon, 10 Jun 2013 20:20:18 +0300 (EEST) From: Claudiu Manoil To: CC: , Claudiu Manoil Subject: [PATCH][net-next] gianfar: Add backwards compatible Single Queue mode polling Date: Mon, 10 Jun 2013 20:19:48 +0300 Message-ID: <1370884788-4862-1-git-send-email-claudiu.manoil@freescale.com> X-Mailer: git-send-email 1.7.11.3 In-Reply-To: References: MIME-Version: 1.0 X-OriginatorOrg: freescale.net Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Older Single Queue (SQ_SG_MODE) devices like TSEC (i.e. mpc83xx) don't feature the frame receive indication bits (RXF) in RSTAT. For these and for the rest of the SQ_SG_MODE devices, provide the appropiate polling routine that handles a single pair of Rx/Tx BD rings, removing the overhead incurred by the multiple queues/ multiple interrupt group devices (veTSEC/ eTSEC2.0 devices). So this is primarily a fix for the TSEC devices. Signed-off-by: Claudiu Manoil --- drivers/net/ethernet/freescale/gianfar.c | 51 ++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 96fbe35..ac9bb63 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -128,6 +128,7 @@ static void gfar_set_multi(struct net_device *dev); static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr); static void gfar_configure_serdes(struct net_device *dev); static int gfar_poll(struct napi_struct *napi, int budget); +static int gfar_poll_sq(struct napi_struct *napi, int budget); #ifdef CONFIG_NET_POLL_CONTROLLER static void gfar_netpoll(struct net_device *dev); #endif @@ -1038,9 +1039,13 @@ static int gfar_probe(struct platform_device *ofdev) dev->ethtool_ops = &gfar_ethtool_ops; /* Register for napi ...We are registering NAPI for each grp */ - for (i = 0; i < priv->num_grps; i++) - netif_napi_add(dev, &priv->gfargrp[i].napi, gfar_poll, + if (priv->mode == SQ_SG_MODE) + netif_napi_add(dev, &priv->gfargrp[0].napi, gfar_poll_sq, GFAR_DEV_WEIGHT); + else + for (i = 0; i < priv->num_grps; i++) + netif_napi_add(dev, &priv->gfargrp[i].napi, gfar_poll, + GFAR_DEV_WEIGHT); if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) { dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | @@ -2824,6 +2829,48 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) return howmany; } +static int gfar_poll_sq(struct napi_struct *napi, int budget) +{ + struct gfar_priv_grp *gfargrp = + container_of(napi, struct gfar_priv_grp, napi); + struct gfar __iomem *regs = gfargrp->regs; + struct gfar_priv_tx_q *tx_queue = gfargrp->priv->tx_queue[0]; + struct gfar_priv_rx_q *rx_queue = gfargrp->priv->rx_queue[0]; + int work_done = 0; + + /* Clear IEVENT, so interrupts aren't called again + * because of the packets that have already arrived + */ + gfar_write(®s->ievent, IEVENT_RTX_MASK); + + /* run Tx cleanup to completion */ + if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx]) + gfar_clean_tx_ring(tx_queue); + + work_done = gfar_clean_rx_ring(rx_queue, budget); + + if (work_done < budget) { + napi_complete(napi); + /* Clear the halt bit in RSTAT */ + gfar_write(®s->rstat, gfargrp->rstat); + + gfar_write(®s->imask, IMASK_DEFAULT); + + /* If we are coalescing interrupts, update the timer + * Otherwise, clear it + */ + gfar_write(®s->txic, 0); + if (likely(tx_queue->txcoalescing)) + gfar_write(®s->txic, tx_queue->txic); + + gfar_write(®s->rxic, 0); + if (unlikely(rx_queue->rxcoalescing)) + gfar_write(®s->rxic, rx_queue->rxic); + } + + return work_done; +} + static int gfar_poll(struct napi_struct *napi, int budget) { struct gfar_priv_grp *gfargrp =