From patchwork Tue Jan 19 20:24:04 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anatolij Gustschin X-Patchwork-Id: 43212 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from bilbo.ozlabs.org (localhost [127.0.0.1]) by ozlabs.org (Postfix) with ESMTP id 6ECCFB8099 for ; Wed, 20 Jan 2010 07:24:59 +1100 (EST) Received: by ozlabs.org (Postfix) id 3D82FB7E78; Wed, 20 Jan 2010 07:24:22 +1100 (EST) Delivered-To: linuxppc-dev@ozlabs.org Received: from mail-out.m-online.net (mail-out.m-online.net [212.18.0.10]) by ozlabs.org (Postfix) with ESMTP id 92A65B7E44 for ; Wed, 20 Jan 2010 07:24:21 +1100 (EST) Received: from mail01.m-online.net (mail.m-online.net [192.168.3.149]) by mail-out.m-online.net (Postfix) with ESMTP id 1F6BB1C001E7; Tue, 19 Jan 2010 21:24:20 +0100 (CET) X-Auth-Info: pz9Ypf6DA1bmA9g8sp/UiW1KdMUeTU2FR2cZsuqTNNs= Received: from localhost (pD953D0E8.dip.t-dialin.net [217.83.208.232]) (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTP id C5A9C90136; Tue, 19 Jan 2010 21:24:19 +0100 (CET) From: Anatolij Gustschin To: linuxppc-dev@ozlabs.org Subject: [PATCH 02/11] fs_enet: Add FEC TX Alignment workaround for MPC5121 Date: Tue, 19 Jan 2010 21:24:04 +0100 Message-Id: <1263932653-3634-3-git-send-email-agust@denx.de> X-Mailer: git-send-email 1.5.6.3 In-Reply-To: <1263932653-3634-1-git-send-email-agust@denx.de> References: <1263932653-3634-1-git-send-email-agust@denx.de> Cc: wd@denx.de, John Rigby , netdev@vger.kernel.org, Anatolij Gustschin , dzu@denx.de, Piotr Ziecik X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org From: John Rigby The FEC on 5121 has problems with misaligned tx buffers. The RM says any alignment is ok but empirical results show that packet buffers ending in 0x1E will sometimes hang the FEC. Other bad alignment does not hang but will cause silent TX failures resulting in about a 1% packet loss as tested by ping -f from a remote host. This patch is a work around that copies every tx packet to an aligned skb before sending. Signed-off-by: John Rigby Signed-off-by: Piotr Ziecik Signed-off-by: Wolfgang Denk Signed-off-by: Anatolij Gustschin Cc: Cc: Grant Likely Cc: John Rigby --- drivers/net/fs_enet/fs_enet-main.c | 39 ++++++++++++++++++++++++++++++++++++ 1 files changed, 39 insertions(+), 0 deletions(-) diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 909b78d..a391219 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -587,6 +587,33 @@ void fs_cleanup_bds(struct net_device *dev) /**********************************************************************************/ +static struct sk_buff *tx_skb_align_workaround(struct net_device *dev, + struct sk_buff *skb) +{ + struct sk_buff *new_skb; + + /* Alloc new skb */ + new_skb = dev_alloc_skb(ENET_RX_FRSIZE + 32); + if (!new_skb) { + printk(KERN_WARNING DRV_MODULE_NAME + ": %s Memory squeeze, dropping tx packet.\n", + dev->name); + return NULL; + } + + /* Make sure new skb is properly aligned */ + skb_align(new_skb, 32); + + /* Copy data to new skb ... */ + skb_copy_from_linear_data(skb, new_skb->data, skb->len); + skb_put(new_skb, skb->len); + + /* ... and free an old one */ + dev_kfree_skb_any(skb); + + return new_skb; +} + static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); @@ -595,6 +622,18 @@ static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) u16 sc; unsigned long flags; + if (fep->fec.fec_id == FS_ENET_MPC5121_FEC) { + skb = tx_skb_align_workaround(dev, skb); + if (!skb) { + /* + * We have lost packet due to memory allocation error + * in tx_skb_align_workaround(). Hopefully original skb + * is still valid, so try transmit it later. + */ + return NETDEV_TX_BUSY; + } + } + spin_lock_irqsave(&fep->tx_lock, flags); /*