From patchwork Fri Sep 25 11:11:10 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sven Eckelmann X-Patchwork-Id: 522723 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from arrakis.dune.hu (arrakis.dune.hu [78.24.191.176]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id AB0E5140281 for ; Fri, 25 Sep 2015 21:13:46 +1000 (AEST) Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id D4BDE28C6E8; Fri, 25 Sep 2015 13:10:52 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on arrakis.dune.hu X-Spam-Level: X-Spam-Status: No, score=-1.5 required=5.0 tests=BAYES_00, T_RP_MATCHES_RCVD autolearn=unavailable version=3.3.2 Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 14B632803E1 for ; Fri, 25 Sep 2015 13:10:20 +0200 (CEST) X-policyd-weight: using cached result; rate:hard: -7.6 Received: from v3-1039.vlinux.de (narfation.org [79.140.41.39]) by arrakis.dune.hu (Postfix) with ESMTPS for ; Fri, 25 Sep 2015 13:10:20 +0200 (CEST) Received: from sven-desktop.home.narfation.org (xd9bda8d1.dyn.telefonica.de [217.189.168.209]) by v3-1039.vlinux.de (Postfix) with ESMTPSA id 4A1F61100F9; Fri, 25 Sep 2015 13:11:36 +0200 (CEST) From: Sven Eckelmann To: openwrt-devel@lists.openwrt.org Date: Fri, 25 Sep 2015 13:11:10 +0200 Message-Id: <1443179471-17029-3-git-send-email-sven@open-mesh.com> X-Mailer: git-send-email 2.5.3 In-Reply-To: <1443179471-17029-1-git-send-email-sven@open-mesh.com> References: <1443179471-17029-1-git-send-email-sven@open-mesh.com> Cc: Sven Eckelmann Subject: [OpenWrt-Devel] [PATCH 3/4] ramips: Fix too small rx buffer X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: openwrt-devel-bounces@lists.openwrt.org Sender: "openwrt-devel" The driver assumes that the maximum received buffer for non-jumbo frames is 1536 bytes. But the allocation of the rx fragment doesn't reflect that. It currently allocates fragments which will only be large enough to be used as rx buffer with the size of 1534 bytes. This is problematic because the GMAC will now try to write to 2 bytes which don't belong to its receive buffer when a large enough ethernet frame is received. This may already be a problem on existing chips but will at least become a problem when the 1536 byte rx modus is enabled on MT7621a. It is required on this SoC to receive ethernet frames which use their full 1500 bytes MTU and a VLAN header next to the switch VLAN tag. Signed-off-by: Sven Eckelmann --- .../files/drivers/net/ethernet/ralink/ralink_soc_eth.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.c index 2691cfb..05b810a 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.c +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.c @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -41,8 +42,8 @@ #include "ralink_ethtool.h" #define MAX_RX_LENGTH 1536 -#define FE_RX_HLEN (NET_SKB_PAD + VLAN_ETH_HLEN + VLAN_HLEN + \ - + NET_IP_ALIGN + ETH_FCS_LEN) +#define FE_RX_ETH_HLEN (VLAN_ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN) +#define FE_RX_HLEN (NET_SKB_PAD + FE_RX_ETH_HLEN + NET_IP_ALIGN) #define DMA_DUMMY_DESC 0xffffffff #define FE_DEFAULT_MSG_ENABLE \ (NETIF_MSG_DRV | \ @@ -172,14 +173,21 @@ static int fe_set_mac_address(struct net_device *dev, void *p) static inline int fe_max_frag_size(int mtu) { + /* make sure buf_size will be at least MAX_RX_LENGTH */ + if (mtu + FE_RX_ETH_HLEN < MAX_RX_LENGTH) + mtu = MAX_RX_LENGTH - FE_RX_ETH_HLEN; + return SKB_DATA_ALIGN(FE_RX_HLEN + mtu) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); } static inline int fe_max_buf_size(int frag_size) { - return frag_size - NET_SKB_PAD - NET_IP_ALIGN - - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + int buf_size = frag_size - NET_SKB_PAD - NET_IP_ALIGN - + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + + BUG_ON(buf_size < MAX_RX_LENGTH); + return buf_size; } static inline void fe_get_rxd(struct fe_rx_dma *rxd, struct fe_rx_dma *dma_rxd)