From 2e0bf125ac7d3d32dd699d345d19a7f3e675776c Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Tue, 17 Feb 2015 19:26:18 -0500 Subject: bnx2-cnic: Driver Rebranding Changes This patch provides additional changes as a part of BNX2 and CNIC driver re-branding effort. Signed-off-by: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/Kconfig | 8 ++++---- drivers/net/ethernet/broadcom/bnx2.c | 8 ++++---- drivers/net/ethernet/broadcom/bnx2.h | 4 ++-- drivers/net/ethernet/broadcom/bnx2_fw.h | 4 ++-- drivers/net/ethernet/broadcom/cnic.c | 6 +++--- drivers/net/ethernet/broadcom/cnic_if.h | 4 ++-- 6 files changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig index 41a3c9804427..ee4fdfe65e9e 100644 --- a/drivers/net/ethernet/broadcom/Kconfig +++ b/drivers/net/ethernet/broadcom/Kconfig @@ -71,12 +71,12 @@ config BCMGENET Broadcom BCM7xxx Set Top Box family chipset. config BNX2 - tristate "QLogic NetXtremeII support" + tristate "QLogic bnx2 support" depends on PCI select CRC32 select FW_LOADER ---help--- - This driver supports QLogic NetXtremeII gigabit Ethernet cards. + This driver supports QLogic bnx2 gigabit Ethernet cards. To compile this driver as a module, choose M here: the module will be called bnx2. This is recommended. @@ -87,8 +87,8 @@ config CNIC select BNX2 select UIO ---help--- - This driver supports offload features of QLogic NetXtremeII - gigabit Ethernet cards. + This driver supports offload features of QLogic bnx2 gigabit + Ethernet cards. To compile this driver as a module, choose M here: the module will be called cnic. This is recommended. diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 02bf0b86995b..8957eb5f4478 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -1,7 +1,7 @@ -/* bnx2.c: QLogic NX2 network driver. +/* bnx2.c: QLogic bnx2 network driver. * * Copyright (c) 2004-2014 Broadcom Corporation - * Copyright (c) 2014 QLogic Corporation + * Copyright (c) 2014-2015 QLogic Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -72,10 +72,10 @@ #define TX_TIMEOUT (5*HZ) static char version[] = - "QLogic NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; + "QLogic " DRV_MODULE_NAME " Gigabit Ethernet Driver v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; MODULE_AUTHOR("Michael Chan "); -MODULE_DESCRIPTION("QLogic NetXtreme II BCM5706/5708/5709/5716 Driver"); +MODULE_DESCRIPTION("QLogic BCM5706/5708/5709/5716 Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); MODULE_FIRMWARE(FW_MIPS_FILE_06); diff --git a/drivers/net/ethernet/broadcom/bnx2.h b/drivers/net/ethernet/broadcom/bnx2.h index 28df35d35893..f92f76c44756 100644 --- a/drivers/net/ethernet/broadcom/bnx2.h +++ b/drivers/net/ethernet/broadcom/bnx2.h @@ -1,7 +1,7 @@ -/* bnx2.h: QLogic NX2 network driver. +/* bnx2.h: QLogic bnx2 network driver. * * Copyright (c) 2004-2014 Broadcom Corporation - * Copyright (c) 2014 QLogic Corporation + * Copyright (c) 2014-2015 QLogic Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/net/ethernet/broadcom/bnx2_fw.h b/drivers/net/ethernet/broadcom/bnx2_fw.h index 7db79c28b5ff..b0f2ccadaffd 100644 --- a/drivers/net/ethernet/broadcom/bnx2_fw.h +++ b/drivers/net/ethernet/broadcom/bnx2_fw.h @@ -1,7 +1,7 @@ -/* bnx2_fw.h: QLogic NX2 network driver. +/* bnx2_fw.h: QLogic bnx2 network driver. * * Copyright (c) 2004, 2005, 2006, 2007 Broadcom Corporation - * Copyright (c) 2014 QLogic Corporation + * Copyright (c) 2014-2015 QLogic Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index f05fab65d78a..17c145fdf3ff 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c @@ -1,7 +1,7 @@ /* cnic.c: QLogic CNIC core network driver. * * Copyright (c) 2006-2014 Broadcom Corporation - * Copyright (c) 2014 QLogic Corporation + * Copyright (c) 2014-2015 QLogic Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -58,11 +58,11 @@ #define CNIC_MODULE_NAME "cnic" static char version[] = - "QLogic NetXtreme II CNIC Driver " CNIC_MODULE_NAME " v" CNIC_MODULE_VERSION " (" CNIC_MODULE_RELDATE ")\n"; + "QLogic " CNIC_MODULE_NAME "Driver v" CNIC_MODULE_VERSION " (" CNIC_MODULE_RELDATE ")\n"; MODULE_AUTHOR("Michael Chan and John(Zongxi) " "Chen (zongxi@broadcom.com"); -MODULE_DESCRIPTION("QLogic NetXtreme II CNIC Driver"); +MODULE_DESCRIPTION("QLogic cnic Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(CNIC_MODULE_VERSION); diff --git a/drivers/net/ethernet/broadcom/cnic_if.h b/drivers/net/ethernet/broadcom/cnic_if.h index 8bb36c1c4d68..7fe0b64e34de 100644 --- a/drivers/net/ethernet/broadcom/cnic_if.h +++ b/drivers/net/ethernet/broadcom/cnic_if.h @@ -1,7 +1,7 @@ -/* cnic_if.h: QLogic CNIC core network driver. +/* cnic_if.h: QLogic cnic core network driver. * * Copyright (c) 2006-2014 Broadcom Corporation - * Copyright (c) 2014 QLogic Corporation + * Copyright (c) 2014-2015 QLogic Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -- cgit v1.2.3 From 0021850d0417a4dc38ed871d929b651b87e2ead9 Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Tue, 17 Feb 2015 19:26:19 -0500 Subject: bnx2: Fix for Chip Initialization Do not enable filter SORT MODE in chip init routine. This patch addresses an issue where BCM5716 sporadically drops packets when changing multicast list. Signed-off-by: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 8957eb5f4478..8c9a8b7787d2 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -4984,8 +4984,6 @@ bnx2_init_chip(struct bnx2 *bp) bp->idle_chk_status_idx = 0xffff; - bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE; - /* Set up how to generate a link change interrupt. */ BNX2_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK); -- cgit v1.2.3 From 85fe7cd21f99fed1842275ef86c88de5ecc998b4 Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Tue, 17 Feb 2015 19:26:20 -0500 Subject: bnx2-cnic: Driver Version Update This patch updates BNX2 driver version to 2.2.6 and CNIC driver version to 2.5.21. Signed-off-by: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2.c | 4 ++-- drivers/net/ethernet/broadcom/cnic_if.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 8c9a8b7787d2..9f146b990c01 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -58,8 +58,8 @@ #include "bnx2_fw.h" #define DRV_MODULE_NAME "bnx2" -#define DRV_MODULE_VERSION "2.2.5" -#define DRV_MODULE_RELDATE "December 20, 2013" +#define DRV_MODULE_VERSION "2.2.6" +#define DRV_MODULE_RELDATE "January 29, 2014" #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.2.3.fw" #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw" #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1b.fw" diff --git a/drivers/net/ethernet/broadcom/cnic_if.h b/drivers/net/ethernet/broadcom/cnic_if.h index 7fe0b64e34de..ef6125b0ee3e 100644 --- a/drivers/net/ethernet/broadcom/cnic_if.h +++ b/drivers/net/ethernet/broadcom/cnic_if.h @@ -15,8 +15,8 @@ #include "bnx2x/bnx2x_mfw_req.h" -#define CNIC_MODULE_VERSION "2.5.20" -#define CNIC_MODULE_RELDATE "March 14, 2014" +#define CNIC_MODULE_VERSION "2.5.21" +#define CNIC_MODULE_RELDATE "January 29, 2015" #define CNIC_ULP_RDMA 0 #define CNIC_ULP_ISCSI 1 -- cgit v1.2.3 From 4f8b2d7d1b514b6b722d91118849ece096217825 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Mon, 23 Feb 2015 11:00:45 -0800 Subject: net: bcmgenet: bcmgenet_init_tx_ring() cleanup 1. Simplify function description 2. Rename function parameter write_ptr to start_ptr to better indicate use 3. Remove unnecessary local variable first_bd 4. Remove out-of-place comment "Unclassified traffic goes to ring 16" 5. Fix TDMA_WRITE_PTR register init Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index ff83c46bc389..bc4c5b4eb00c 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1680,17 +1680,14 @@ static int init_umac(struct bcmgenet_priv *priv) return 0; } -/* Initialize all house-keeping variables for a TX ring, along - * with corresponding hardware registers - */ +/* Initialize a Tx ring along with corresponding hardware registers */ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv, unsigned int index, unsigned int size, - unsigned int write_ptr, unsigned int end_ptr) + unsigned int start_ptr, unsigned int end_ptr) { struct bcmgenet_tx_ring *ring = &priv->tx_rings[index]; u32 words_per_bd = WORDS_PER_BD(priv); u32 flow_period_val = 0; - unsigned int first_bd; spin_lock_init(&ring->lock); ring->index = index; @@ -1703,12 +1700,12 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv, ring->int_enable = bcmgenet_tx_ring_int_enable; ring->int_disable = bcmgenet_tx_ring_int_disable; } - ring->cbs = priv->tx_cbs + write_ptr; + ring->cbs = priv->tx_cbs + start_ptr; ring->size = size; ring->c_index = 0; ring->free_bds = size; - ring->write_ptr = write_ptr; - ring->cb_ptr = write_ptr; + ring->write_ptr = start_ptr; + ring->cb_ptr = start_ptr; ring->end_ptr = end_ptr - 1; ring->prod_index = 0; @@ -1722,19 +1719,16 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv, /* Disable rate control for now */ bcmgenet_tdma_ring_writel(priv, index, flow_period_val, TDMA_FLOW_PERIOD); - /* Unclassified traffic goes to ring 16 */ bcmgenet_tdma_ring_writel(priv, index, ((size << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH), DMA_RING_BUF_SIZE); - first_bd = write_ptr; - /* Set start and end address, read and write pointers */ - bcmgenet_tdma_ring_writel(priv, index, first_bd * words_per_bd, + bcmgenet_tdma_ring_writel(priv, index, start_ptr * words_per_bd, DMA_START_ADDR); - bcmgenet_tdma_ring_writel(priv, index, first_bd * words_per_bd, + bcmgenet_tdma_ring_writel(priv, index, start_ptr * words_per_bd, TDMA_READ_PTR); - bcmgenet_tdma_ring_writel(priv, index, first_bd, + bcmgenet_tdma_ring_writel(priv, index, start_ptr * words_per_bd, TDMA_WRITE_PTR); bcmgenet_tdma_ring_writel(priv, index, end_ptr * words_per_bd - 1, DMA_END_ADDR); -- cgit v1.2.3 From 16c6d667883f41d3e06cf5f6bba964057e67895a Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Mon, 23 Feb 2015 11:00:45 -0800 Subject: net: bcmgenet: rework Tx queue init 1. Rename bcmgenet_init_multiq() to bcmgenet_init_tx_queues() 2. Fix bcmgenet_init_tx_queues() function description 3. Move Tx default queue init inside bcmgenet_init_tx_queues() 4. Modify bcmgenet_init_dma() to call bcmgenet_init_tx_queues() Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 81 +++++++++++--------------- 1 file changed, 35 insertions(+), 46 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index bc4c5b4eb00c..0798f23d7eb7 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1776,78 +1776,73 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv, return ret; } -/* init multi xmit queues, only available for GENET2+ - * the queue is partitioned as follows: +/* Initialize Tx queues * - * queue 0 - 3 is priority based, each one has 32 descriptors, + * Queues 0-3 are priority-based, each one has 32 descriptors, * with queue 0 being the highest priority queue. * - * queue 16 is the default tx queue with GENET_DEFAULT_BD_CNT - * descriptors: 256 - (number of tx queues * bds per queues) = 128 - * descriptors. + * Queue 16 is the default Tx queue with + * GENET_DEFAULT_BD_CNT = 256 - 4 * 32 = 128 descriptors. * - * The transmit control block pool is then partitioned as following: - * - tx_cbs[0...127] are for queue 16 - * - tx_ring_cbs[0] points to tx_cbs[128..159] - * - tx_ring_cbs[1] points to tx_cbs[160..191] - * - tx_ring_cbs[2] points to tx_cbs[192..223] - * - tx_ring_cbs[3] points to tx_cbs[224..255] + * The transmit control block pool is then partitioned as follows: + * - Tx queue 0 uses tx_cbs[0..31] + * - Tx queue 1 uses tx_cbs[32..63] + * - Tx queue 2 uses tx_cbs[64..95] + * - Tx queue 3 uses tx_cbs[96..127] + * - Tx queue 16 uses tx_cbs[128..255] */ -static void bcmgenet_init_multiq(struct net_device *dev) +static void bcmgenet_init_tx_queues(struct net_device *dev) { struct bcmgenet_priv *priv = netdev_priv(dev); - unsigned int i, dma_enable; - u32 reg, dma_ctrl, ring_cfg = 0; + u32 i, dma_enable; + u32 dma_ctrl, ring_cfg; u32 dma_priority[3] = {0, 0, 0}; - if (!netif_is_multiqueue(dev)) { - netdev_warn(dev, "called with non multi queue aware HW\n"); - return; - } - dma_ctrl = bcmgenet_tdma_readl(priv, DMA_CTRL); dma_enable = dma_ctrl & DMA_EN; dma_ctrl &= ~DMA_EN; bcmgenet_tdma_writel(priv, dma_ctrl, DMA_CTRL); + dma_ctrl = 0; + ring_cfg = 0; + /* Enable strict priority arbiter mode */ bcmgenet_tdma_writel(priv, DMA_ARBITER_SP, DMA_ARB_CTRL); + /* Initialize Tx priority queues */ for (i = 0; i < priv->hw_params->tx_queues; i++) { - /* first 64 tx_cbs are reserved for default tx queue - * (ring 16) - */ bcmgenet_init_tx_ring(priv, i, priv->hw_params->bds_cnt, i * priv->hw_params->bds_cnt, (i + 1) * priv->hw_params->bds_cnt); - - /* Configure ring as descriptor ring and setup priority */ - ring_cfg |= 1 << i; - dma_ctrl |= 1 << (i + DMA_RING_BUF_EN_SHIFT); - + ring_cfg |= (1 << i); + dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT)); dma_priority[DMA_PRIO_REG_INDEX(i)] |= ((GENET_Q0_PRIORITY + i) << DMA_PRIO_REG_SHIFT(i)); } - /* Set ring 16 priority and program the hardware registers */ + /* Initialize Tx default queue 16 */ + bcmgenet_init_tx_ring(priv, DESC_INDEX, GENET_DEFAULT_BD_CNT, + priv->hw_params->tx_queues * + priv->hw_params->bds_cnt, + TOTAL_DESC); + ring_cfg |= (1 << DESC_INDEX); + dma_ctrl |= (1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT)); dma_priority[DMA_PRIO_REG_INDEX(DESC_INDEX)] |= ((GENET_Q0_PRIORITY + priv->hw_params->tx_queues) << DMA_PRIO_REG_SHIFT(DESC_INDEX)); + + /* Set Tx queue priorities */ bcmgenet_tdma_writel(priv, dma_priority[0], DMA_PRIORITY_0); bcmgenet_tdma_writel(priv, dma_priority[1], DMA_PRIORITY_1); bcmgenet_tdma_writel(priv, dma_priority[2], DMA_PRIORITY_2); - /* Enable rings */ - reg = bcmgenet_tdma_readl(priv, DMA_RING_CFG); - reg |= ring_cfg; - bcmgenet_tdma_writel(priv, reg, DMA_RING_CFG); + /* Enable Tx queues */ + bcmgenet_tdma_writel(priv, ring_cfg, DMA_RING_CFG); - /* Configure ring as descriptor ring and re-enable DMA if enabled */ - reg = bcmgenet_tdma_readl(priv, DMA_CTRL); - reg |= dma_ctrl; + /* Enable Tx DMA */ if (dma_enable) - reg |= DMA_EN; - bcmgenet_tdma_writel(priv, reg, DMA_CTRL); + dma_ctrl |= DMA_EN; + bcmgenet_tdma_writel(priv, dma_ctrl, DMA_CTRL); } static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv) @@ -1950,14 +1945,8 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv) return -ENOMEM; } - /* initialize multi xmit queue */ - bcmgenet_init_multiq(priv->dev); - - /* initialize special ring 16 */ - bcmgenet_init_tx_ring(priv, DESC_INDEX, GENET_DEFAULT_BD_CNT, - priv->hw_params->tx_queues * - priv->hw_params->bds_cnt, - TOTAL_DESC); + /* Initialize Tx queues */ + bcmgenet_init_tx_queues(priv->dev); return 0; } -- cgit v1.2.3 From 014012a49148d6968afabb0e8d638fad5f65b72d Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Mon, 23 Feb 2015 11:00:45 -0800 Subject: net: bcmgenet: precalculate TxCB->bd_addr There is 1-to-1 mapping between TxCBs and TxBDs. Precalculate TxCB->bd_addr once in bcmgenet_init_dma() instead of doing it over and over needlessly in bcmgenet_get_txcb(). Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 0798f23d7eb7..6e3d83b709ad 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -920,7 +920,7 @@ static struct enet_cb *bcmgenet_get_txcb(struct bcmgenet_priv *priv, tx_cb_ptr = ring->cbs; tx_cb_ptr += ring->write_ptr - ring->cb_ptr; - tx_cb_ptr->bd_addr = priv->tx_bds + ring->write_ptr * DMA_DESC_SIZE; + /* Advancing local write pointer */ if (ring->write_ptr == ring->end_ptr) ring->write_ptr = ring->cb_ptr; @@ -1919,6 +1919,8 @@ static void bcmgenet_fini_dma(struct bcmgenet_priv *priv) static int bcmgenet_init_dma(struct bcmgenet_priv *priv) { int ret; + unsigned int i; + struct enet_cb *cb; netif_dbg(priv, hw, priv->dev, "bcmgenet: init_edma\n"); @@ -1945,6 +1947,11 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv) return -ENOMEM; } + for (i = 0; i < priv->num_tx_bds; i++) { + cb = priv->tx_cbs + i; + cb->bd_addr = priv->tx_bds + i * DMA_DESC_SIZE; + } + /* Initialize Tx queues */ bcmgenet_init_tx_queues(priv->dev); -- cgit v1.2.3 From 51a966a7185c86df9a7ab1d59d4d1ca6b938ebb6 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Mon, 23 Feb 2015 11:00:46 -0800 Subject: net: bcmgenet: rename bcmgenet_hw_params->bds_cnt and GENET_DEFAULT_BD_CNT bcmgenet_hw_params->bds_cnt and GENET_DEFAULT_BD_CNT are used only in Tx init. Rename them accordingly: - bcmgenet_hw_params->bds_cnt => bcmgenet_hw_params->tx_bds_per_q - GENET_DEFAULT_BD_CNT => GENET_Q16_TX_BD_CNT Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 29 +++++++++++++------------- drivers/net/ethernet/broadcom/genet/bcmgenet.h | 2 +- 2 files changed, 16 insertions(+), 15 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 6e3d83b709ad..51300532ec26 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -54,8 +54,8 @@ /* Default highest priority queue for multi queue support */ #define GENET_Q0_PRIORITY 0 -#define GENET_DEFAULT_BD_CNT \ - (TOTAL_DESC - priv->hw_params->tx_queues * priv->hw_params->bds_cnt) +#define GENET_Q16_TX_BD_CNT \ + (TOTAL_DESC - priv->hw_params->tx_queues * priv->hw_params->tx_bds_per_q) #define RX_BUF_LENGTH 2048 #define SKB_ALIGNMENT 32 @@ -1782,7 +1782,7 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv, * with queue 0 being the highest priority queue. * * Queue 16 is the default Tx queue with - * GENET_DEFAULT_BD_CNT = 256 - 4 * 32 = 128 descriptors. + * GENET_Q16_TX_BD_CNT = 256 - 4 * 32 = 128 descriptors. * * The transmit control block pool is then partitioned as follows: * - Tx queue 0 uses tx_cbs[0..31] @@ -1811,9 +1811,9 @@ static void bcmgenet_init_tx_queues(struct net_device *dev) /* Initialize Tx priority queues */ for (i = 0; i < priv->hw_params->tx_queues; i++) { - bcmgenet_init_tx_ring(priv, i, priv->hw_params->bds_cnt, - i * priv->hw_params->bds_cnt, - (i + 1) * priv->hw_params->bds_cnt); + bcmgenet_init_tx_ring(priv, i, priv->hw_params->tx_bds_per_q, + i * priv->hw_params->tx_bds_per_q, + (i + 1) * priv->hw_params->tx_bds_per_q); ring_cfg |= (1 << i); dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT)); dma_priority[DMA_PRIO_REG_INDEX(i)] |= @@ -1821,9 +1821,9 @@ static void bcmgenet_init_tx_queues(struct net_device *dev) } /* Initialize Tx default queue 16 */ - bcmgenet_init_tx_ring(priv, DESC_INDEX, GENET_DEFAULT_BD_CNT, + bcmgenet_init_tx_ring(priv, DESC_INDEX, GENET_Q16_TX_BD_CNT, priv->hw_params->tx_queues * - priv->hw_params->bds_cnt, + priv->hw_params->tx_bds_per_q, TOTAL_DESC); ring_cfg |= (1 << DESC_INDEX); dma_ctrl |= (1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT)); @@ -2427,8 +2427,8 @@ static const struct net_device_ops bcmgenet_netdev_ops = { static struct bcmgenet_hw_params bcmgenet_hw_params[] = { [GENET_V1] = { .tx_queues = 0, + .tx_bds_per_q = 0, .rx_queues = 0, - .bds_cnt = 0, .bp_in_en_shift = 16, .bp_in_mask = 0xffff, .hfb_filter_cnt = 16, @@ -2440,8 +2440,8 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { }, [GENET_V2] = { .tx_queues = 4, + .tx_bds_per_q = 32, .rx_queues = 4, - .bds_cnt = 32, .bp_in_en_shift = 16, .bp_in_mask = 0xffff, .hfb_filter_cnt = 16, @@ -2456,8 +2456,8 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { }, [GENET_V3] = { .tx_queues = 4, + .tx_bds_per_q = 32, .rx_queues = 4, - .bds_cnt = 32, .bp_in_en_shift = 17, .bp_in_mask = 0x1ffff, .hfb_filter_cnt = 48, @@ -2472,8 +2472,8 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { }, [GENET_V4] = { .tx_queues = 4, + .tx_bds_per_q = 32, .rx_queues = 4, - .bds_cnt = 32, .bp_in_en_shift = 17, .bp_in_mask = 0x1ffff, .hfb_filter_cnt = 48, @@ -2573,14 +2573,15 @@ static void bcmgenet_set_hw_params(struct bcmgenet_priv *priv) #endif pr_debug("Configuration for version: %d\n" - "TXq: %1d, RXq: %1d, BDs: %1d\n" + "TXq: %1d, TXqBDs: %1d, RXq: %1d\n" "BP << en: %2d, BP msk: 0x%05x\n" "HFB count: %2d, QTAQ msk: 0x%05x\n" "TBUF: 0x%04x, HFB: 0x%04x, HFBreg: 0x%04x\n" "RDMA: 0x%05x, TDMA: 0x%05x\n" "Words/BD: %d\n", priv->version, - params->tx_queues, params->rx_queues, params->bds_cnt, + params->tx_queues, params->tx_bds_per_q, + params->rx_queues, params->bp_in_en_shift, params->bp_in_mask, params->hfb_filter_cnt, params->qtag_mask, params->tbuf_offset, params->hfb_offset, diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index b36ddec0cc0a..3a8a90f95365 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -503,8 +503,8 @@ enum bcmgenet_version { */ struct bcmgenet_hw_params { u8 tx_queues; + u8 tx_bds_per_q; u8 rx_queues; - u8 bds_cnt; u8 bp_in_en_shift; u32 bp_in_mask; u8 hfb_filter_cnt; -- cgit v1.2.3 From 4092e6acf5cb16f56154e2dd22d647023dc3d646 Mon Sep 17 00:00:00 2001 From: Jaedon Shin Date: Sat, 28 Feb 2015 11:48:26 +0900 Subject: net: bcmgenet: fix throughtput regression This patch adds bcmgenet_tx_poll for the tx_rings. This can reduce the interrupt load and send xmit in network stack on time. This also separated for the completion of tx_ring16 from bcmgenet_poll. The bcmgenet_tx_reclaim of tx_ring[{0,1,2,3}] operative by an interrupt is to be not more than a certain number TxBDs. It is caused by too slowly reclaiming the transmitted skb. Therefore, performance degradation of xmit after 605ad7f ("tcp: refine TSO autosizing"). Signed-off-by: Jaedon Shin Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 113 +++++++++++++++++++------ drivers/net/ethernet/broadcom/genet/bcmgenet.h | 2 + 2 files changed, 88 insertions(+), 27 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index ff83c46bc389..2874a004f815 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -971,13 +971,14 @@ static inline void bcmgenet_tx_ring_int_disable(struct bcmgenet_priv *priv, } /* Unlocked version of the reclaim routine */ -static void __bcmgenet_tx_reclaim(struct net_device *dev, - struct bcmgenet_tx_ring *ring) +static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev, + struct bcmgenet_tx_ring *ring) { struct bcmgenet_priv *priv = netdev_priv(dev); int last_tx_cn, last_c_index, num_tx_bds; struct enet_cb *tx_cb_ptr; struct netdev_queue *txq; + unsigned int pkts_compl = 0; unsigned int bds_compl; unsigned int c_index; @@ -1005,6 +1006,7 @@ static void __bcmgenet_tx_reclaim(struct net_device *dev, tx_cb_ptr = ring->cbs + last_c_index; bds_compl = 0; if (tx_cb_ptr->skb) { + pkts_compl++; bds_compl = skb_shinfo(tx_cb_ptr->skb)->nr_frags + 1; dev->stats.tx_bytes += tx_cb_ptr->skb->len; dma_unmap_single(&dev->dev, @@ -1028,23 +1030,45 @@ static void __bcmgenet_tx_reclaim(struct net_device *dev, last_c_index &= (num_tx_bds - 1); } - if (ring->free_bds > (MAX_SKB_FRAGS + 1)) - ring->int_disable(priv, ring); - - if (netif_tx_queue_stopped(txq)) - netif_tx_wake_queue(txq); + if (ring->free_bds > (MAX_SKB_FRAGS + 1)) { + if (netif_tx_queue_stopped(txq)) + netif_tx_wake_queue(txq); + } ring->c_index = c_index; + + return pkts_compl; } -static void bcmgenet_tx_reclaim(struct net_device *dev, +static unsigned int bcmgenet_tx_reclaim(struct net_device *dev, struct bcmgenet_tx_ring *ring) { + unsigned int released; unsigned long flags; spin_lock_irqsave(&ring->lock, flags); - __bcmgenet_tx_reclaim(dev, ring); + released = __bcmgenet_tx_reclaim(dev, ring); spin_unlock_irqrestore(&ring->lock, flags); + + return released; +} + +static int bcmgenet_tx_poll(struct napi_struct *napi, int budget) +{ + struct bcmgenet_tx_ring *ring = + container_of(napi, struct bcmgenet_tx_ring, napi); + unsigned int work_done = 0; + + work_done = bcmgenet_tx_reclaim(ring->priv->dev, ring); + + if (work_done == 0) { + napi_complete(napi); + ring->int_enable(ring->priv, ring); + + return 0; + } + + return budget; } static void bcmgenet_tx_reclaim_all(struct net_device *dev) @@ -1302,10 +1326,8 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) bcmgenet_tdma_ring_writel(priv, ring->index, ring->prod_index, TDMA_PROD_INDEX); - if (ring->free_bds <= (MAX_SKB_FRAGS + 1)) { + if (ring->free_bds <= (MAX_SKB_FRAGS + 1)) netif_tx_stop_queue(txq); - ring->int_enable(priv, ring); - } out: spin_unlock_irqrestore(&ring->lock, flags); @@ -1621,6 +1643,7 @@ static int init_umac(struct bcmgenet_priv *priv) struct device *kdev = &priv->pdev->dev; int ret; u32 reg, cpu_mask_clear; + int index; dev_dbg(&priv->pdev->dev, "bcmgenet: init_umac\n"); @@ -1647,7 +1670,7 @@ static int init_umac(struct bcmgenet_priv *priv) bcmgenet_intr_disable(priv); - cpu_mask_clear = UMAC_IRQ_RXDMA_BDONE; + cpu_mask_clear = UMAC_IRQ_RXDMA_BDONE | UMAC_IRQ_TXDMA_BDONE; dev_dbg(kdev, "%s:Enabling RXDMA_BDONE interrupt\n", __func__); @@ -1674,6 +1697,10 @@ static int init_umac(struct bcmgenet_priv *priv) bcmgenet_intrl2_0_writel(priv, cpu_mask_clear, INTRL2_CPU_MASK_CLEAR); + for (index = 0; index < priv->hw_params->tx_queues; index++) + bcmgenet_intrl2_1_writel(priv, (1 << index), + INTRL2_CPU_MASK_CLEAR); + /* Enable rx/tx engine.*/ dev_dbg(kdev, "done init umac\n"); @@ -1693,6 +1720,8 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv, unsigned int first_bd; spin_lock_init(&ring->lock); + ring->priv = priv; + netif_napi_add(priv->dev, &ring->napi, bcmgenet_tx_poll, 64); ring->index = index; if (index == DESC_INDEX) { ring->queue = 0; @@ -1738,6 +1767,17 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv, TDMA_WRITE_PTR); bcmgenet_tdma_ring_writel(priv, index, end_ptr * words_per_bd - 1, DMA_END_ADDR); + + napi_enable(&ring->napi); +} + +static void bcmgenet_fini_tx_ring(struct bcmgenet_priv *priv, + unsigned int index) +{ + struct bcmgenet_tx_ring *ring = &priv->tx_rings[index]; + + napi_disable(&ring->napi); + netif_napi_del(&ring->napi); } /* Initialize a RDMA ring */ @@ -1907,7 +1947,7 @@ static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv) return ret; } -static void bcmgenet_fini_dma(struct bcmgenet_priv *priv) +static void __bcmgenet_fini_dma(struct bcmgenet_priv *priv) { int i; @@ -1926,6 +1966,18 @@ static void bcmgenet_fini_dma(struct bcmgenet_priv *priv) kfree(priv->tx_cbs); } +static void bcmgenet_fini_dma(struct bcmgenet_priv *priv) +{ + int i; + + bcmgenet_fini_tx_ring(priv, DESC_INDEX); + + for (i = 0; i < priv->hw_params->tx_queues; i++) + bcmgenet_fini_tx_ring(priv, i); + + __bcmgenet_fini_dma(priv); +} + /* init_edma: Initialize DMA control register */ static int bcmgenet_init_dma(struct bcmgenet_priv *priv) { @@ -1952,7 +2004,7 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv) priv->tx_cbs = kcalloc(priv->num_tx_bds, sizeof(struct enet_cb), GFP_KERNEL); if (!priv->tx_cbs) { - bcmgenet_fini_dma(priv); + __bcmgenet_fini_dma(priv); return -ENOMEM; } @@ -1975,9 +2027,6 @@ static int bcmgenet_poll(struct napi_struct *napi, int budget) struct bcmgenet_priv, napi); unsigned int work_done; - /* tx reclaim */ - bcmgenet_tx_reclaim(priv->dev, &priv->tx_rings[DESC_INDEX]); - work_done = bcmgenet_desc_rx(priv, budget); /* Advancing our consumer index*/ @@ -2022,28 +2071,34 @@ static void bcmgenet_irq_task(struct work_struct *work) static irqreturn_t bcmgenet_isr1(int irq, void *dev_id) { struct bcmgenet_priv *priv = dev_id; + struct bcmgenet_tx_ring *ring; unsigned int index; /* Save irq status for bottom-half processing. */ priv->irq1_stat = bcmgenet_intrl2_1_readl(priv, INTRL2_CPU_STAT) & - ~priv->int1_mask; + ~bcmgenet_intrl2_1_readl(priv, INTRL2_CPU_MASK_STATUS); /* clear interrupts */ bcmgenet_intrl2_1_writel(priv, priv->irq1_stat, INTRL2_CPU_CLEAR); netif_dbg(priv, intr, priv->dev, "%s: IRQ=0x%x\n", __func__, priv->irq1_stat); + /* Check the MBDONE interrupts. * packet is done, reclaim descriptors */ - if (priv->irq1_stat & 0x0000ffff) { - index = 0; - for (index = 0; index < 16; index++) { - if (priv->irq1_stat & (1 << index)) - bcmgenet_tx_reclaim(priv->dev, - &priv->tx_rings[index]); + for (index = 0; index < priv->hw_params->tx_queues; index++) { + if (!(priv->irq1_stat & BIT(index))) + continue; + + ring = &priv->tx_rings[index]; + + if (likely(napi_schedule_prep(&ring->napi))) { + ring->int_disable(priv, ring); + __napi_schedule(&ring->napi); } } + return IRQ_HANDLED; } @@ -2075,8 +2130,12 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id) } if (priv->irq0_stat & (UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE)) { - /* Tx reclaim */ - bcmgenet_tx_reclaim(priv->dev, &priv->tx_rings[DESC_INDEX]); + struct bcmgenet_tx_ring *ring = &priv->tx_rings[DESC_INDEX]; + + if (likely(napi_schedule_prep(&ring->napi))) { + ring->int_disable(priv, ring); + __napi_schedule(&ring->napi); + } } if (priv->irq0_stat & (UMAC_IRQ_PHY_DET_R | UMAC_IRQ_PHY_DET_F | diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index b36ddec0cc0a..0d370d168aee 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -520,6 +520,7 @@ struct bcmgenet_hw_params { struct bcmgenet_tx_ring { spinlock_t lock; /* ring lock */ + struct napi_struct napi; /* NAPI per tx queue */ unsigned int index; /* ring index */ unsigned int queue; /* queue index */ struct enet_cb *cbs; /* tx ring buffer control block*/ @@ -534,6 +535,7 @@ struct bcmgenet_tx_ring { struct bcmgenet_tx_ring *); void (*int_disable)(struct bcmgenet_priv *priv, struct bcmgenet_tx_ring *); + struct bcmgenet_priv *priv; }; /* device context */ -- cgit v1.2.3 From f62ba9c14b85a682b64a4c421f91de0bd2aa8538 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sat, 28 Feb 2015 18:09:16 -0800 Subject: net: bcmgenet: fix software maintained statistics Commit 44c8bc3ce39f ("net: bcmgenet: log RX buffer allocation and RX/TX dma failures") added a few software maintained statistics using BCMGENET_STAT_MIB_RX and BCMGENET_STAT_MIB_TX. These statistics are read from the hardware MIB counters, such that bcmgenet_update_mib_counters() was trying to read from a non-existing MIB offset for these counters. Fix this by introducing a special type: BCMGENET_STAT_SOFT, similar to BCMGENET_STAT_NETDEV, such that bcmgenet_get_ethtool_stats will read from the software mib. Fixes: 44c8bc3ce39f ("net: bcmgenet: log RX buffer allocation and RX/TX dma failures") Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 2874a004f815..6befde61c203 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -487,6 +487,7 @@ enum bcmgenet_stat_type { BCMGENET_STAT_MIB_TX, BCMGENET_STAT_RUNT, BCMGENET_STAT_MISC, + BCMGENET_STAT_SOFT, }; struct bcmgenet_stats { @@ -515,6 +516,7 @@ struct bcmgenet_stats { #define STAT_GENET_MIB_RX(str, m) STAT_GENET_MIB(str, m, BCMGENET_STAT_MIB_RX) #define STAT_GENET_MIB_TX(str, m) STAT_GENET_MIB(str, m, BCMGENET_STAT_MIB_TX) #define STAT_GENET_RUNT(str, m) STAT_GENET_MIB(str, m, BCMGENET_STAT_RUNT) +#define STAT_GENET_SOFT_MIB(str, m) STAT_GENET_MIB(str, m, BCMGENET_STAT_SOFT) #define STAT_GENET_MISC(str, m, offset) { \ .stat_string = str, \ @@ -614,9 +616,9 @@ static const struct bcmgenet_stats bcmgenet_gstrings_stats[] = { UMAC_RBUF_OVFL_CNT), STAT_GENET_MISC("rbuf_err_cnt", mib.rbuf_err_cnt, UMAC_RBUF_ERR_CNT), STAT_GENET_MISC("mdf_err_cnt", mib.mdf_err_cnt, UMAC_MDF_ERR_CNT), - STAT_GENET_MIB_RX("alloc_rx_buff_failed", mib.alloc_rx_buff_failed), - STAT_GENET_MIB_RX("rx_dma_failed", mib.rx_dma_failed), - STAT_GENET_MIB_TX("tx_dma_failed", mib.tx_dma_failed), + STAT_GENET_SOFT_MIB("alloc_rx_buff_failed", mib.alloc_rx_buff_failed), + STAT_GENET_SOFT_MIB("rx_dma_failed", mib.rx_dma_failed), + STAT_GENET_SOFT_MIB("tx_dma_failed", mib.tx_dma_failed), }; #define BCMGENET_STATS_LEN ARRAY_SIZE(bcmgenet_gstrings_stats) @@ -668,6 +670,7 @@ static void bcmgenet_update_mib_counters(struct bcmgenet_priv *priv) s = &bcmgenet_gstrings_stats[i]; switch (s->type) { case BCMGENET_STAT_NETDEV: + case BCMGENET_STAT_SOFT: continue; case BCMGENET_STAT_MIB_RX: case BCMGENET_STAT_MIB_TX: -- cgit v1.2.3 From 55ff4ea9a853f5ec9a8290c0ccc1d00c97e49f82 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sat, 28 Feb 2015 18:09:17 -0800 Subject: net: systemport: fix software maintained statistics Commit 60b4ea1781fd ("net: systemport: log RX buffer allocation and RX/TX DMA failures") added a few software maintained statistics using BCM_SYSPORT_STAT_MIB_RX and BCM_SYSPORT_STAT_MIB_TX. These statistics are read from the hardware MIB counters, such that bcm_sysport_update_mib_counters() was trying to read from a non-existing MIB offset for these counters. Fix this by introducing a special type: BCM_SYSPORT_STAT_SOFT, similar to BCM_SYSPORT_STAT_NETDEV, such that bcm_sysport_get_ethtool_stats will read from the software mib. Fixes: 60b4ea1781fd ("net: systemport: log RX buffer allocation and RX/TX DMA failures") Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bcmsysport.c | 7 ++++--- drivers/net/ethernet/broadcom/bcmsysport.h | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index 5b308a4a4d0e..783543ad1fcf 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -274,9 +274,9 @@ static const struct bcm_sysport_stats bcm_sysport_gstrings_stats[] = { /* RBUF misc statistics */ STAT_RBUF("rbuf_ovflow_cnt", mib.rbuf_ovflow_cnt, RBUF_OVFL_DISC_CNTR), STAT_RBUF("rbuf_err_cnt", mib.rbuf_err_cnt, RBUF_ERR_PKT_CNTR), - STAT_MIB_RX("alloc_rx_buff_failed", mib.alloc_rx_buff_failed), - STAT_MIB_RX("rx_dma_failed", mib.rx_dma_failed), - STAT_MIB_TX("tx_dma_failed", mib.tx_dma_failed), + STAT_MIB_SOFT("alloc_rx_buff_failed", mib.alloc_rx_buff_failed), + STAT_MIB_SOFT("rx_dma_failed", mib.rx_dma_failed), + STAT_MIB_SOFT("tx_dma_failed", mib.tx_dma_failed), }; #define BCM_SYSPORT_STATS_LEN ARRAY_SIZE(bcm_sysport_gstrings_stats) @@ -345,6 +345,7 @@ static void bcm_sysport_update_mib_counters(struct bcm_sysport_priv *priv) s = &bcm_sysport_gstrings_stats[i]; switch (s->type) { case BCM_SYSPORT_STAT_NETDEV: + case BCM_SYSPORT_STAT_SOFT: continue; case BCM_SYSPORT_STAT_MIB_RX: case BCM_SYSPORT_STAT_MIB_TX: diff --git a/drivers/net/ethernet/broadcom/bcmsysport.h b/drivers/net/ethernet/broadcom/bcmsysport.h index fc19417d82a5..7e3d87a88c76 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.h +++ b/drivers/net/ethernet/broadcom/bcmsysport.h @@ -570,6 +570,7 @@ enum bcm_sysport_stat_type { BCM_SYSPORT_STAT_RUNT, BCM_SYSPORT_STAT_RXCHK, BCM_SYSPORT_STAT_RBUF, + BCM_SYSPORT_STAT_SOFT, }; /* Macros to help define ethtool statistics */ @@ -590,6 +591,7 @@ enum bcm_sysport_stat_type { #define STAT_MIB_RX(str, m) STAT_MIB(str, m, BCM_SYSPORT_STAT_MIB_RX) #define STAT_MIB_TX(str, m) STAT_MIB(str, m, BCM_SYSPORT_STAT_MIB_TX) #define STAT_RUNT(str, m) STAT_MIB(str, m, BCM_SYSPORT_STAT_RUNT) +#define STAT_MIB_SOFT(str, m) STAT_MIB(str, m, BCM_SYSPORT_STAT_SOFT) #define STAT_RXCHK(str, m, ofs) { \ .stat_string = str, \ -- cgit v1.2.3 From 26caa3469a2de617d95c29371571a9585603a023 Mon Sep 17 00:00:00 2001 From: Ivan Vecera Date: Thu, 26 Feb 2015 14:48:07 +0100 Subject: bnx2: disable toggling of rxvlan if necessary The bnx2 driver uses .ndo_fix_features to force enable of Rx VLAN tag stripping when the card cannot disable it. The driver should remove NETIF_F_HW_VLAN_CTAG_RX flag from hw_features instead so it is fixed for the ethtool. Cc: Sony Chacko Cc: Dept-HSGLinuxNICDev@qlogic.com Signed-off-by: Ivan Vecera Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 9f146b990c01..2b66ef3d8217 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -7708,17 +7708,6 @@ bnx2_set_phys_id(struct net_device *dev, enum ethtool_phys_id_state state) return 0; } -static netdev_features_t -bnx2_fix_features(struct net_device *dev, netdev_features_t features) -{ - struct bnx2 *bp = netdev_priv(dev); - - if (!(bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)) - features |= NETIF_F_HW_VLAN_CTAG_RX; - - return features; -} - static int bnx2_set_features(struct net_device *dev, netdev_features_t features) { @@ -8525,7 +8514,6 @@ static const struct net_device_ops bnx2_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = bnx2_change_mac_addr, .ndo_change_mtu = bnx2_change_mtu, - .ndo_fix_features = bnx2_fix_features, .ndo_set_features = bnx2_set_features, .ndo_tx_timeout = bnx2_tx_timeout, #ifdef CONFIG_NET_POLL_CONTROLLER @@ -8576,6 +8564,9 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->features |= dev->hw_features; dev->priv_flags |= IFF_UNICAST_FLT; + if (!(bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)) + dev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_RX; + if ((rc = register_netdev(dev))) { dev_err(&pdev->dev, "Cannot register net device\n"); goto error; -- cgit v1.2.3 From c7bf716940c6a8ed39b444bfb0b97c2939ac312b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 2 Mar 2015 19:54:47 -0800 Subject: ethernet: Use eth__addr instead of memset Use the built-in function instead of memset. Signed-off-by: Joe Perches Acked-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ethernet/amd/pcnet32.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 6 +++--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 2 +- drivers/net/ethernet/cisco/enic/enic_main.c | 8 ++++---- drivers/net/ethernet/emulex/benet/be_cmds.c | 2 +- drivers/net/ethernet/emulex/benet/be_main.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 ++-- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 4 ++-- drivers/net/ethernet/mellanox/mlx4/en_selftest.c | 2 +- drivers/net/ethernet/micrel/ksz884x.c | 2 +- drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c | 2 +- drivers/net/ethernet/qlogic/qlge/qlge_main.c | 2 +- drivers/net/ethernet/smsc/smsc911x.c | 2 +- drivers/net/ethernet/ti/netcp_core.c | 2 +- drivers/net/ethernet/toshiba/ps3_gelic_wireless.c | 4 ++-- drivers/net/ethernet/xscale/ixp4xx_eth.c | 2 +- 17 files changed, 25 insertions(+), 25 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/amd/pcnet32.c b/drivers/net/ethernet/amd/pcnet32.c index 11d6e6561df1..8eb37e0194b5 100644 --- a/drivers/net/ethernet/amd/pcnet32.c +++ b/drivers/net/ethernet/amd/pcnet32.c @@ -1708,7 +1708,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) /* if the ethernet address is not valid, force to 00:00:00:00:00:00 */ if (!is_valid_ether_addr(dev->dev_addr)) - memset(dev->dev_addr, 0, ETH_ALEN); + eth_zero_addr(dev->dev_addr); if (pcnet32_debug & NETIF_MSG_PROBE) { pr_cont(" %pM", dev->dev_addr); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index ffe4e003e636..e3d853cab7c9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -2446,7 +2446,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode) } packet = skb_put(skb, pkt_size); memcpy(packet, bp->dev->dev_addr, ETH_ALEN); - memset(packet + ETH_ALEN, 0, ETH_ALEN); + eth_zero_addr(packet + ETH_ALEN); memset(packet + 2*ETH_ALEN, 0x77, (ETH_HLEN - 2*ETH_ALEN)); for (i = ETH_HLEN; i < pkt_size; i++) packet[i] = (unsigned char) (i & 0xff); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 7155e1d2c208..98dcb03fe1b8 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -11546,13 +11546,13 @@ static void bnx2x_get_cnic_mac_hwinfo(struct bnx2x *bp) /* Disable iSCSI OOO if MAC configuration is invalid. */ if (!is_valid_ether_addr(iscsi_mac)) { bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG; - memset(iscsi_mac, 0, ETH_ALEN); + eth_zero_addr(iscsi_mac); } /* Disable FCoE if MAC configuration is invalid. */ if (!is_valid_ether_addr(fip_mac)) { bp->flags |= NO_FCOE_FLAG; - memset(bp->fip_mac, 0, ETH_ALEN); + eth_zero_addr(bp->fip_mac); } } @@ -11563,7 +11563,7 @@ static void bnx2x_get_mac_hwinfo(struct bnx2x *bp) int port = BP_PORT(bp); /* Zero primary MAC configuration */ - memset(bp->dev->dev_addr, 0, ETH_ALEN); + eth_zero_addr(bp->dev->dev_addr); if (BP_NOMCP(bp)) { BNX2X_ERROR("warning: random MAC workaround active\n"); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index e5aca2de1871..8638d6c97caa 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -2693,7 +2693,7 @@ int bnx2x_get_vf_config(struct net_device *dev, int vfidx, memcpy(&ivi->mac, bulletin->mac, ETH_ALEN); else /* function has not been loaded yet. Show mac as 0s */ - memset(&ivi->mac, 0, ETH_ALEN); + eth_zero_addr(ivi->mac); /* vlan */ if (bulletin->valid_bitmap & (1 << VLAN_VALID)) diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 9cbe038a388e..a368c0a96ec7 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -893,7 +893,7 @@ static int enic_set_vf_port(struct net_device *netdev, int vf, } else { memset(pp, 0, sizeof(*pp)); if (vf == PORT_SELF_VF) - memset(netdev->dev_addr, 0, ETH_ALEN); + eth_zero_addr(netdev->dev_addr); } } else { /* Set flag to indicate that the port assoc/disassoc @@ -903,14 +903,14 @@ static int enic_set_vf_port(struct net_device *netdev, int vf, /* If DISASSOCIATE, clean up all assigned/saved macaddresses */ if (pp->request == PORT_REQUEST_DISASSOCIATE) { - memset(pp->mac_addr, 0, ETH_ALEN); + eth_zero_addr(pp->mac_addr); if (vf == PORT_SELF_VF) - memset(netdev->dev_addr, 0, ETH_ALEN); + eth_zero_addr(netdev->dev_addr); } } if (vf == PORT_SELF_VF) - memset(pp->vf_mac, 0, ETH_ALEN); + eth_zero_addr(pp->vf_mac); return err; } diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index f6db7b3e9b70..be00695b3be7 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -3076,7 +3076,7 @@ int be_cmd_get_perm_mac(struct be_adapter *adapter, u8 *mac) int status; bool pmac_valid = false; - memset(mac, 0, ETH_ALEN); + eth_zero_addr(mac); if (BEx_chip(adapter)) { if (be_physfn(adapter)) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index b2277a4c7ddf..7eccebc676e2 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -3218,7 +3218,7 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable) int status = 0; u8 mac[ETH_ALEN]; - memset(mac, 0, ETH_ALEN); + eth_zero_addr(mac); cmd.size = sizeof(struct be_cmd_req_acpi_wol_magic_config); cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma, diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 70cc4c5c0a01..903664ff6904 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -3924,7 +3924,7 @@ static void ixgbe_flush_sw_mac_table(struct ixgbe_adapter *adapter) for (i = 0; i < hw->mac.num_rar_entries; i++) { adapter->mac_table[i].state |= IXGBE_MAC_STATE_MODIFIED; adapter->mac_table[i].state &= ~IXGBE_MAC_STATE_IN_USE; - memset(adapter->mac_table[i].addr, 0, ETH_ALEN); + eth_zero_addr(adapter->mac_table[i].addr); adapter->mac_table[i].queue = 0; } ixgbe_sync_mac_table(adapter); @@ -3992,7 +3992,7 @@ int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter, u8 *addr, u16 queue) adapter->mac_table[i].queue == queue) { adapter->mac_table[i].state |= IXGBE_MAC_STATE_MODIFIED; adapter->mac_table[i].state &= ~IXGBE_MAC_STATE_IN_USE; - memset(adapter->mac_table[i].addr, 0, ETH_ALEN); + eth_zero_addr(adapter->mac_table[i].addr); adapter->mac_table[i].queue = 0; ixgbe_sync_mac_table(adapter); return 0; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 2a210c4efb89..c59ed925adaf 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -1685,7 +1685,7 @@ int mlx4_en_start_port(struct net_device *dev) } /* Attach rx QP to bradcast address */ - memset(&mc_list[10], 0xff, ETH_ALEN); + eth_broadcast_addr(&mc_list[10]); mc_list[5] = priv->port; /* needed for B0 steering support */ if (mlx4_multicast_attach(mdev->dev, &priv->rss_map.indir_qp, mc_list, priv->port, 0, MLX4_PROT_ETH, @@ -1788,7 +1788,7 @@ void mlx4_en_stop_port(struct net_device *dev, int detach) } /* Detach All multicasts */ - memset(&mc_list[10], 0xff, ETH_ALEN); + eth_broadcast_addr(&mc_list[10]); mc_list[5] = priv->port; /* needed for B0 steering support */ mlx4_multicast_detach(mdev->dev, &priv->rss_map.indir_qp, mc_list, MLX4_PROT_ETH, priv->broadcast_id); diff --git a/drivers/net/ethernet/mellanox/mlx4/en_selftest.c b/drivers/net/ethernet/mellanox/mlx4/en_selftest.c index 2d8ee66138e8..4e789479f00f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_selftest.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_selftest.c @@ -66,7 +66,7 @@ static int mlx4_en_test_loopback_xmit(struct mlx4_en_priv *priv) ethh = (struct ethhdr *)skb_put(skb, sizeof(struct ethhdr)); packet = (unsigned char *)skb_put(skb, packet_size); memcpy(ethh->h_dest, priv->dev->dev_addr, ETH_ALEN); - memset(ethh->h_source, 0, ETH_ALEN); + eth_zero_addr(ethh->h_source); ethh->h_proto = htons(ETH_P_ARP); skb_set_mac_header(skb, 0); for (i = 0; i < packet_size; ++i) /* fill our packet */ diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index 10988fbf47eb..6f332ebdf3b5 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -4144,7 +4144,7 @@ static int hw_del_addr(struct ksz_hw *hw, u8 *mac_addr) for (i = 0; i < hw->addr_list_size; i++) { if (ether_addr_equal(hw->address[i], mac_addr)) { - memset(hw->address[i], 0, ETH_ALEN); + eth_zero_addr(hw->address[i]); writel(0, hw->io + ADD_ADDR_INCR * i + KS_ADD_ADDR_0_HI); return 0; diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c index 716fc37ada5a..db80eb1c6d4f 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c @@ -537,7 +537,7 @@ static void netxen_p2_nic_set_multi(struct net_device *netdev) u8 null_addr[ETH_ALEN]; int i; - memset(null_addr, 0, ETH_ALEN); + eth_zero_addr(null_addr); if (netdev->flags & IFF_PROMISC) { diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c index 8011ef3e7707..25800a1dedcb 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -460,7 +460,7 @@ static int ql_set_mac_addr(struct ql_adapter *qdev, int set) netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, "Set Mac addr %pM\n", addr); } else { - memset(zero_mac_addr, 0, ETH_ALEN); + eth_zero_addr(zero_mac_addr); addr = &zero_mac_addr[0]; netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, "Clearing MAC address\n"); diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 2965c6ae7d6e..41047c9143d0 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -843,7 +843,7 @@ static int smsc911x_phy_loopbacktest(struct net_device *dev) unsigned long flags; /* Initialise tx packet using broadcast destination address */ - memset(pdata->loopback_tx_pkt, 0xff, ETH_ALEN); + eth_broadcast_addr(pdata->loopback_tx_pkt); /* Use incrementing source address */ for (i = 6; i < 12; i++) diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c index a31a8c3c8e7c..9f14d8b515c7 100644 --- a/drivers/net/ethernet/ti/netcp_core.c +++ b/drivers/net/ethernet/ti/netcp_core.c @@ -1320,7 +1320,7 @@ static struct netcp_addr *netcp_addr_add(struct netcp_intf *netcp, if (addr) ether_addr_copy(naddr->addr, addr); else - memset(naddr->addr, 0, ETH_ALEN); + eth_zero_addr(naddr->addr); list_add_tail(&naddr->node, &netcp->addr_list); return naddr; diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c index 0a7f2e77557f..13214a6492ac 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c +++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c @@ -1167,7 +1167,7 @@ static int gelic_wl_set_ap(struct net_device *netdev, } else { pr_debug("%s: clear bssid\n", __func__); clear_bit(GELIC_WL_STAT_BSSID_SET, &wl->stat); - memset(wl->bssid, 0, ETH_ALEN); + eth_zero_addr(wl->bssid); } spin_unlock_irqrestore(&wl->lock, irqflag); pr_debug("%s: ->\n", __func__); @@ -1189,7 +1189,7 @@ static int gelic_wl_get_ap(struct net_device *netdev, memcpy(data->ap_addr.sa_data, wl->active_bssid, ETH_ALEN); } else - memset(data->ap_addr.sa_data, 0, ETH_ALEN); + eth_zero_addr(data->ap_addr.sa_data); spin_unlock_irqrestore(&wl->lock, irqflag); mutex_unlock(&wl->assoc_stat_lock); diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c index f7e0f0f7c2e2..44ff8d7c64a5 100644 --- a/drivers/net/ethernet/xscale/ixp4xx_eth.c +++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c @@ -954,7 +954,7 @@ static void eth_set_mcast_list(struct net_device *dev) return; } - memset(diffs, 0, ETH_ALEN); + eth_zero_addr(diffs); addr = NULL; netdev_for_each_mc_addr(ha, dev) { -- cgit v1.2.3 From cd33ccf5fd87e94342b6cf8990e2e1570632c276 Mon Sep 17 00:00:00 2001 From: Nicolas Schichan Date: Tue, 3 Mar 2015 12:45:12 +0100 Subject: bcm63xx_enet: fix poll callback. In case there was some tx buffer reclaimed and not enough rx packets to consume the whole budget, napi_complete would not be called and interrupts would be kept disabled, effectively resulting in the network core never to call the poll callback again and no rx/tx interrupts to be fired either. Fix that by only accounting the rx work done in the poll callback. Signed-off-by: Nicolas Schichan Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bcm63xx_enet.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c index 21206d33b638..a7f2cc3e485e 100644 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c @@ -486,7 +486,7 @@ static int bcm_enet_poll(struct napi_struct *napi, int budget) { struct bcm_enet_priv *priv; struct net_device *dev; - int tx_work_done, rx_work_done; + int rx_work_done; priv = container_of(napi, struct bcm_enet_priv, napi); dev = priv->net_dev; @@ -498,14 +498,14 @@ static int bcm_enet_poll(struct napi_struct *napi, int budget) ENETDMAC_IR, priv->tx_chan); /* reclaim sent skb */ - tx_work_done = bcm_enet_tx_reclaim(dev, 0); + bcm_enet_tx_reclaim(dev, 0); spin_lock(&priv->rx_lock); rx_work_done = bcm_enet_receive_queue(dev, budget); spin_unlock(&priv->rx_lock); - if (rx_work_done >= budget || tx_work_done > 0) { - /* rx/tx queue is not yet empty/clean */ + if (rx_work_done >= budget) { + /* rx queue is not yet empty/clean */ return rx_work_done; } -- cgit v1.2.3 From 66d06757d9eb74a29775737b8c770e3b57e536d9 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Wed, 4 Mar 2015 14:30:01 -0800 Subject: net: bcmgenet: simplify __bcmgenet_tx_reclaim() 1. Use c_index and ring->c_index to determine how many TxCBs/TxBDs are ready for cleanup - c_index = the current value of TDMA_CONS_INDEX - TDMA_CONS_INDEX is HW-incremented and auto-wraparound (0x0-0xFFFF) - ring->c_index = __bcmgenet_tx_reclaim() cleaned up to this point on the previous invocation 2. Add bcmgenet_tx_ring->clean_ptr - index of the next TxCB to be cleaned - incremented as TxCBs/TxBDs are processed - value always in range [ring->cb_ptr, ring->end_ptr] 3. Fix incrementing of dev->stats.tx_packets - should be incremented only when tx_cb_ptr->skb != NULL These changes simplify __bcmgenet_tx_reclaim(). Furthermore, Tx ring size can now be any value. With the old code, Tx ring size had to be a power-of-2: num_tx_bds = ring->size; c_index &= (num_tx_bds - 1); last_c_index &= (num_tx_bds - 1); Signed-off-by: Petri Gynther Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 45 ++++++++++++-------------- drivers/net/ethernet/broadcom/genet/bcmgenet.h | 1 + 2 files changed, 22 insertions(+), 24 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 84feb241d60b..9137187063f7 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -978,39 +978,32 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev, struct bcmgenet_tx_ring *ring) { struct bcmgenet_priv *priv = netdev_priv(dev); - int last_tx_cn, last_c_index, num_tx_bds; struct enet_cb *tx_cb_ptr; struct netdev_queue *txq; unsigned int pkts_compl = 0; - unsigned int bds_compl; unsigned int c_index; + unsigned int txbds_ready; + unsigned int txbds_processed = 0; /* Compute how many buffers are transmitted since last xmit call */ c_index = bcmgenet_tdma_ring_readl(priv, ring->index, TDMA_CONS_INDEX); - txq = netdev_get_tx_queue(dev, ring->queue); - - last_c_index = ring->c_index; - num_tx_bds = ring->size; - - c_index &= (num_tx_bds - 1); + c_index &= DMA_C_INDEX_MASK; - if (c_index >= last_c_index) - last_tx_cn = c_index - last_c_index; + if (likely(c_index >= ring->c_index)) + txbds_ready = c_index - ring->c_index; else - last_tx_cn = num_tx_bds - last_c_index + c_index; + txbds_ready = (DMA_C_INDEX_MASK + 1) - ring->c_index + c_index; netif_dbg(priv, tx_done, dev, - "%s ring=%d index=%d last_tx_cn=%d last_index=%d\n", - __func__, ring->index, - c_index, last_tx_cn, last_c_index); + "%s ring=%d old_c_index=%u c_index=%u txbds_ready=%u\n", + __func__, ring->index, ring->c_index, c_index, txbds_ready); /* Reclaim transmitted buffers */ - while (last_tx_cn-- > 0) { - tx_cb_ptr = ring->cbs + last_c_index; - bds_compl = 0; + while (txbds_processed < txbds_ready) { + tx_cb_ptr = &priv->tx_cbs[ring->clean_ptr]; if (tx_cb_ptr->skb) { pkts_compl++; - bds_compl = skb_shinfo(tx_cb_ptr->skb)->nr_frags + 1; + dev->stats.tx_packets++; dev->stats.tx_bytes += tx_cb_ptr->skb->len; dma_unmap_single(&dev->dev, dma_unmap_addr(tx_cb_ptr, dma_addr), @@ -1026,20 +1019,23 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev, DMA_TO_DEVICE); dma_unmap_addr_set(tx_cb_ptr, dma_addr, 0); } - dev->stats.tx_packets++; - ring->free_bds += bds_compl; - last_c_index++; - last_c_index &= (num_tx_bds - 1); + txbds_processed++; + if (likely(ring->clean_ptr < ring->end_ptr)) + ring->clean_ptr++; + else + ring->clean_ptr = ring->cb_ptr; } + ring->free_bds += txbds_processed; + ring->c_index = (ring->c_index + txbds_processed) & DMA_C_INDEX_MASK; + if (ring->free_bds > (MAX_SKB_FRAGS + 1)) { + txq = netdev_get_tx_queue(dev, ring->queue); if (netif_tx_queue_stopped(txq)) netif_tx_wake_queue(txq); } - ring->c_index = c_index; - return pkts_compl; } @@ -1734,6 +1730,7 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv, } ring->cbs = priv->tx_cbs + start_ptr; ring->size = size; + ring->clean_ptr = start_ptr; ring->c_index = 0; ring->free_bds = size; ring->write_ptr = start_ptr; diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 016bd12bf493..548b7e934727 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -525,6 +525,7 @@ struct bcmgenet_tx_ring { unsigned int queue; /* queue index */ struct enet_cb *cbs; /* tx ring buffer control block*/ unsigned int size; /* size of each tx ring */ + unsigned int clean_ptr; /* Tx ring clean pointer */ unsigned int c_index; /* last consumer index of each ring*/ unsigned int free_bds; /* # of free bds for each ring */ unsigned int write_ptr; /* Tx ring write pointer SW copy */ -- cgit v1.2.3 From da293700568ed3d96fcf062ac15d7d7c41377f11 Mon Sep 17 00:00:00 2001 From: Brian King Date: Wed, 4 Mar 2015 08:09:44 -0600 Subject: bnx2x: Force fundamental reset for EEH recovery EEH recovery for bnx2x based adapters is not reliable on all Power systems using the default hot reset, which can result in an unrecoverable EEH error. Forcing the use of fundamental reset during EEH recovery fixes this. Cc: stable Signed-off-by: Brian King Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 7155e1d2c208..bef750a09027 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -12722,6 +12722,9 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev, pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, PCICFG_VENDOR_ID_OFFSET); + /* Set PCIe reset type to fundamental for EEH recovery */ + pdev->needs_freset = 1; + /* AER (Advanced Error reporting) configuration */ rc = pci_enable_pcie_error_reporting(pdev); if (!rc) -- cgit v1.2.3 From 386668a61f90412a61a12719d15dfec58d0ece1c Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 4 Mar 2015 11:43:03 -0800 Subject: net: bcmgenet: properly disable password matching bcmgenet_set_wol() correctly sets MPD_PW_EN when a password is specified to match magic packets against, however, when we switch from a password-matching to a matching without password we would leave this bit turned on, and GENET would only match magic packets with passwords. This can be reproduced using the following sequence: ethtool -s eth0 wol g ethtool -s eth0 wol s sopass 00:11:22:33:44:55 ethtool -s eth0 wol g The simple fix is to clear the MPD_PWD_EN bit when WAKE_MAGICSECURE is not set. Fixes: c51de7f3976b ("net: bcmgenet: add Wake-on-LAN support code") Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c index 149a0d70c108..b97122926d3a 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c @@ -73,15 +73,17 @@ int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) if (wol->wolopts & ~(WAKE_MAGIC | WAKE_MAGICSECURE)) return -EINVAL; + reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); if (wol->wolopts & WAKE_MAGICSECURE) { bcmgenet_umac_writel(priv, get_unaligned_be16(&wol->sopass[0]), UMAC_MPD_PW_MS); bcmgenet_umac_writel(priv, get_unaligned_be32(&wol->sopass[2]), UMAC_MPD_PW_LS); - reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); reg |= MPD_PW_EN; - bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); + } else { + reg &= ~MPD_PW_EN; } + bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); /* Flag the device and relevant IRQ as wakeup capable */ if (wol->wolopts) { -- cgit v1.2.3 From 24d2e4a50737867aba1e96a587ef0d90c17e3035 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 5 Mar 2015 10:41:34 -0800 Subject: tg3: use napi_complete_done() Using napi_complete_done() instead of napi_complete() allows us to use /sys/class/net/ethX/gro_flush_timeout GRO layer can aggregate more packets if the flush is delayed a bit, without having to set too big coalescing parameters that impact latencies. Tested: lpx:~# echo 0 >/sys/class/net/eth1/gro_flush_timeout lpx:~# sar -n DEV 1 10 | grep eth1 10:36:25 AM eth1 81290.00 40617.00 120479.67 2777.01 0.00 0.00 0.00 10:36:26 AM eth1 81283.00 40608.00 120481.81 2778.13 0.00 0.00 1.00 10:36:27 AM eth1 81304.00 40639.00 120518.42 2778.28 0.00 0.00 0.00 10:36:28 AM eth1 81255.00 40605.00 120437.34 2775.95 0.00 0.00 1.00 10:36:29 AM eth1 81306.00 40630.00 120521.44 2777.70 0.00 0.00 0.00 10:36:30 AM eth1 81286.00 40564.00 120480.20 2773.31 0.00 0.00 0.00 10:36:31 AM eth1 81256.00 40599.00 120438.81 2776.27 0.00 0.00 0.00 10:36:32 AM eth1 81287.00 40594.00 120480.69 2776.69 0.00 0.00 0.00 10:36:33 AM eth1 81279.00 40601.00 120478.53 2775.84 0.00 0.00 0.00 10:36:34 AM eth1 81277.00 40610.00 120476.94 2776.25 0.00 0.00 0.00 Average: eth1 81282.30 40606.70 120479.39 2776.54 0.00 0.00 0.20 lpx:~# echo 13000 >/sys/class/net/eth1/gro_flush_timeout lpx:~# sar -n DEV 1 10 | grep eth1 10:36:43 AM eth1 81257.00 7747.00 120437.44 530.00 0.00 0.00 0.00 10:36:44 AM eth1 81278.00 7748.00 120480.00 529.85 0.00 0.00 0.00 10:36:45 AM eth1 81282.00 7752.00 120479.09 531.09 0.00 0.00 0.00 10:36:46 AM eth1 81282.00 7751.00 120478.80 530.90 0.00 0.00 0.00 10:36:47 AM eth1 81276.00 7745.00 120478.31 529.64 0.00 0.00 0.00 10:36:48 AM eth1 81278.00 7747.00 120478.50 529.81 0.00 0.00 0.00 10:36:49 AM eth1 81282.00 7749.00 120478.88 530.01 0.00 0.00 0.00 10:36:50 AM eth1 81284.00 7751.00 120481.52 530.20 0.00 0.00 0.00 10:36:51 AM eth1 81299.00 7769.00 120481.74 533.81 0.00 0.00 0.00 10:36:52 AM eth1 81281.00 7748.00 120478.62 529.96 0.00 0.00 0.00 Average: eth1 81279.90 7750.70 120475.29 530.53 0.00 0.00 0.00 Signed-off-by: Eric Dumazet Acked-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 23a019cee279..22b33da32ba4 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -7244,7 +7244,7 @@ static int tg3_poll_msix(struct napi_struct *napi, int budget) if (tnapi == &tp->napi[1] && tp->rx_refill) continue; - napi_complete(napi); + napi_complete_done(napi, work_done); /* Reenable interrupts. */ tw32_mailbox(tnapi->int_mbox, tnapi->last_tag << 24); @@ -7337,7 +7337,7 @@ static int tg3_poll(struct napi_struct *napi, int budget) sblk->status &= ~SD_STATUS_UPDATED; if (likely(!tg3_has_work(tnapi))) { - napi_complete(napi); + napi_complete_done(napi, work_done); tg3_int_reenable(tnapi); break; } -- cgit v1.2.3 From 7e906e025d2ccf94f23b0cf8967a52134d6be6d1 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Thu, 5 Mar 2015 17:40:10 -0800 Subject: net: bcmgenet: set hw_params->rx_queues = 0 bcmgenet driver doesn't yet support multiple Rx queues. Set hw_params->rx_queues = 0 accordingly. The default Rx queue (Q16) is still created and operational. Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 9137187063f7..f56553b9f915 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2500,7 +2500,7 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { [GENET_V2] = { .tx_queues = 4, .tx_bds_per_q = 32, - .rx_queues = 4, + .rx_queues = 0, .bp_in_en_shift = 16, .bp_in_mask = 0xffff, .hfb_filter_cnt = 16, @@ -2516,7 +2516,7 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { [GENET_V3] = { .tx_queues = 4, .tx_bds_per_q = 32, - .rx_queues = 4, + .rx_queues = 0, .bp_in_en_shift = 17, .bp_in_mask = 0x1ffff, .hfb_filter_cnt = 48, @@ -2532,7 +2532,7 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { [GENET_V4] = { .tx_queues = 4, .tx_bds_per_q = 32, - .rx_queues = 4, + .rx_queues = 0, .bp_in_en_shift = 17, .bp_in_mask = 0x1ffff, .hfb_filter_cnt = 48, -- cgit v1.2.3 From 3feafeed16f92b96b7b67a3e30882c62c859f4bb Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Thu, 5 Mar 2015 17:40:12 -0800 Subject: net: bcmgenet: adjust the call to alloc_etherdev_mqs() In preparation for supporting multiple Rx queues, adjust the call to alloc_etherdev_mqs() to allow max GENET_MAX_MQ_CNT + 1 Rx queues. The actual number of Rx queues in use is correctly adjusted with: netif_set_real_num_rx_queues(priv->dev, priv->hw_params->rx_queues + 1); Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index f56553b9f915..57271f7b2456 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2668,8 +2668,9 @@ static int bcmgenet_probe(struct platform_device *pdev) struct resource *r; int err = -EIO; - /* Up to GENET_MAX_MQ_CNT + 1 TX queues and a single RX queue */ - dev = alloc_etherdev_mqs(sizeof(*priv), GENET_MAX_MQ_CNT + 1, 1); + /* Up to GENET_MAX_MQ_CNT + 1 TX queues and RX queues */ + dev = alloc_etherdev_mqs(sizeof(*priv), GENET_MAX_MQ_CNT + 1, + GENET_MAX_MQ_CNT + 1); if (!dev) { dev_err(&pdev->dev, "can't allocate net device\n"); return -ENOMEM; -- cgit v1.2.3 From 3feafa02156681a5a2a843680c7daeb93d22e280 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Thu, 5 Mar 2015 17:40:14 -0800 Subject: net: bcmgenet: add GENET_Q16_RX_BD_CNT and hw_params->rx_bds_per_q In preparation for supporting multiple Rx queues, add GENET_Q16_RX_BD_CNT and hw_params->rx_bds_per_q. Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 10 ++++++++-- drivers/net/ethernet/broadcom/genet/bcmgenet.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 57271f7b2456..d90785caab59 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -54,6 +54,8 @@ /* Default highest priority queue for multi queue support */ #define GENET_Q0_PRIORITY 0 +#define GENET_Q16_RX_BD_CNT \ + (TOTAL_DESC - priv->hw_params->rx_queues * priv->hw_params->rx_bds_per_q) #define GENET_Q16_TX_BD_CNT \ (TOTAL_DESC - priv->hw_params->tx_queues * priv->hw_params->tx_bds_per_q) @@ -2488,6 +2490,7 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { .tx_queues = 0, .tx_bds_per_q = 0, .rx_queues = 0, + .rx_bds_per_q = 0, .bp_in_en_shift = 16, .bp_in_mask = 0xffff, .hfb_filter_cnt = 16, @@ -2501,6 +2504,7 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { .tx_queues = 4, .tx_bds_per_q = 32, .rx_queues = 0, + .rx_bds_per_q = 0, .bp_in_en_shift = 16, .bp_in_mask = 0xffff, .hfb_filter_cnt = 16, @@ -2517,6 +2521,7 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { .tx_queues = 4, .tx_bds_per_q = 32, .rx_queues = 0, + .rx_bds_per_q = 0, .bp_in_en_shift = 17, .bp_in_mask = 0x1ffff, .hfb_filter_cnt = 48, @@ -2533,6 +2538,7 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { .tx_queues = 4, .tx_bds_per_q = 32, .rx_queues = 0, + .rx_bds_per_q = 0, .bp_in_en_shift = 17, .bp_in_mask = 0x1ffff, .hfb_filter_cnt = 48, @@ -2632,7 +2638,7 @@ static void bcmgenet_set_hw_params(struct bcmgenet_priv *priv) #endif pr_debug("Configuration for version: %d\n" - "TXq: %1d, TXqBDs: %1d, RXq: %1d\n" + "TXq: %1d, TXqBDs: %1d, RXq: %1d, RXqBDs: %1d\n" "BP << en: %2d, BP msk: 0x%05x\n" "HFB count: %2d, QTAQ msk: 0x%05x\n" "TBUF: 0x%04x, HFB: 0x%04x, HFBreg: 0x%04x\n" @@ -2640,7 +2646,7 @@ static void bcmgenet_set_hw_params(struct bcmgenet_priv *priv) "Words/BD: %d\n", priv->version, params->tx_queues, params->tx_bds_per_q, - params->rx_queues, + params->rx_queues, params->rx_bds_per_q, params->bp_in_en_shift, params->bp_in_mask, params->hfb_filter_cnt, params->qtag_mask, params->tbuf_offset, params->hfb_offset, diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 548b7e934727..5684e8529ecc 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -505,6 +505,7 @@ struct bcmgenet_hw_params { u8 tx_queues; u8 tx_bds_per_q; u8 rx_queues; + u8 rx_bds_per_q; u8 bp_in_en_shift; u32 bp_in_mask; u8 hfb_filter_cnt; -- cgit v1.2.3 From d939be3add4f1410079dad2755d4936cdb70903b Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 27 Feb 2015 23:52:31 +0900 Subject: treewide: Fix typo in printk messages This patch fix spelling typo in printk messages. Signed-off-by: Masanari Iida Acked-by: Randy Dunlap Signed-off-by: Jiri Kosina --- arch/arc/kernel/unwind.c | 2 +- arch/powerpc/kernel/prom.c | 2 +- arch/powerpc/platforms/85xx/p1022_rdk.c | 4 ++-- arch/x86/kernel/test_rodata.c | 2 +- drivers/iio/adc/max1027.c | 2 +- drivers/isdn/hardware/mISDN/mISDNinfineon.c | 2 +- drivers/isdn/mISDN/dsp_cmx.c | 2 +- drivers/isdn/mISDN/dsp_core.c | 4 ++-- drivers/media/tuners/msi001.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 2 +- drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | 2 +- drivers/net/wireless/ath/ath10k/mac.c | 2 +- drivers/net/wireless/rtlwifi/rtl8723be/dm.c | 2 +- drivers/net/wireless/rtlwifi/rtl8821ae/dm.c | 2 +- drivers/parisc/eisa_enumerator.c | 2 +- drivers/scsi/be2iscsi/be_cmds.c | 2 +- drivers/scsi/osd/osd_initiator.c | 2 +- drivers/scsi/qla2xxx/qla_nx.c | 2 +- drivers/scsi/qla2xxx/qla_os.c | 4 ++-- net/sunrpc/xprtrdma/verbs.c | 4 ++-- tools/perf/util/probe-finder.c | 2 +- 21 files changed, 25 insertions(+), 25 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c index e550b117ec4f..93c6ea52b671 100644 --- a/arch/arc/kernel/unwind.c +++ b/arch/arc/kernel/unwind.c @@ -841,7 +841,7 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc, break; case DW_CFA_GNU_window_save: default: - unw_debug("UNKNOW OPCODE 0x%x\n", opcode); + unw_debug("UNKNOWN OPCODE 0x%x\n", opcode); result = 0; break; } diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 099f27e6d1b0..20ce051312fc 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -721,7 +721,7 @@ void __init early_init_devtree(void *params) */ of_scan_flat_dt(early_init_dt_scan_cpus, NULL); if (boot_cpuid < 0) { - printk("Failed to indentify boot CPU !\n"); + printk("Failed to identify boot CPU !\n"); BUG(); } diff --git a/arch/powerpc/platforms/85xx/p1022_rdk.c b/arch/powerpc/platforms/85xx/p1022_rdk.c index 7a180f0308d5..680232d6ba48 100644 --- a/arch/powerpc/platforms/85xx/p1022_rdk.c +++ b/arch/powerpc/platforms/85xx/p1022_rdk.c @@ -50,14 +50,14 @@ void p1022rdk_set_pixel_clock(unsigned int pixclock) /* Map the global utilities registers. */ guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts"); if (!guts_np) { - pr_err("p1022rdk: missing global utilties device node\n"); + pr_err("p1022rdk: missing global utilities device node\n"); return; } guts = of_iomap(guts_np, 0); of_node_put(guts_np); if (!guts) { - pr_err("p1022rdk: could not map global utilties device\n"); + pr_err("p1022rdk: could not map global utilities device\n"); return; } diff --git a/arch/x86/kernel/test_rodata.c b/arch/x86/kernel/test_rodata.c index b79133abda48..5ecbfe5099da 100644 --- a/arch/x86/kernel/test_rodata.c +++ b/arch/x86/kernel/test_rodata.c @@ -57,7 +57,7 @@ int rodata_test(void) /* test 3: check the value hasn't changed */ /* If this test fails, we managed to overwrite the data */ if (!rodata_test_data) { - printk(KERN_ERR "rodata_test: Test 3 failes (end data)\n"); + printk(KERN_ERR "rodata_test: Test 3 fails (end data)\n"); return -ENODEV; } /* test 4: check if the rodata section is 4Kb aligned */ diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c index 87ee1c7d0b54..44bf815adb6c 100644 --- a/drivers/iio/adc/max1027.c +++ b/drivers/iio/adc/max1027.c @@ -436,7 +436,7 @@ static int max1027_probe(struct spi_device *spi) indio_dev->num_channels * 2, GFP_KERNEL); if (st->buffer == NULL) { - dev_err(&indio_dev->dev, "Can't allocate bufffer\n"); + dev_err(&indio_dev->dev, "Can't allocate buffer\n"); return -ENOMEM; } diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c index c1493f4162fb..d5bdbaf93a1a 100644 --- a/drivers/isdn/hardware/mISDN/mISDNinfineon.c +++ b/drivers/isdn/hardware/mISDN/mISDNinfineon.c @@ -1092,7 +1092,7 @@ inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } card->ci = get_card_info(ent->driver_data); if (!card->ci) { - pr_info("mISDN: do not have informations about adapter at %s\n", + pr_info("mISDN: do not have information about adapter at %s\n", pci_name(pdev)); kfree(card); pci_disable_device(pdev); diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c index 87f7dff20ff6..52c43821f746 100644 --- a/drivers/isdn/mISDN/dsp_cmx.c +++ b/drivers/isdn/mISDN/dsp_cmx.c @@ -295,7 +295,7 @@ dsp_cmx_del_conf_member(struct dsp *dsp) } } printk(KERN_WARNING - "%s: dsp is not present in its own conf_meber list.\n", + "%s: dsp is not present in its own conf_member list.\n", __func__); return -EINVAL; diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c index 77025f5cb57d..0222b1a35a2d 100644 --- a/drivers/isdn/mISDN/dsp_core.c +++ b/drivers/isdn/mISDN/dsp_core.c @@ -460,7 +460,7 @@ dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb) } if (dsp_debug & DEBUG_DSP_CORE) printk(KERN_DEBUG "%s: enable mixing of " - "tx-data with conf mebers\n", __func__); + "tx-data with conf members\n", __func__); dsp->tx_mix = 1; dsp_cmx_hardware(dsp->conf, dsp); dsp_rx_off(dsp); @@ -474,7 +474,7 @@ dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb) } if (dsp_debug & DEBUG_DSP_CORE) printk(KERN_DEBUG "%s: disable mixing of " - "tx-data with conf mebers\n", __func__); + "tx-data with conf members\n", __func__); dsp->tx_mix = 0; dsp_cmx_hardware(dsp->conf, dsp); dsp_rx_off(dsp); diff --git a/drivers/media/tuners/msi001.c b/drivers/media/tuners/msi001.c index 26019e731993..74cfc3c98edb 100644 --- a/drivers/media/tuners/msi001.c +++ b/drivers/media/tuners/msi001.c @@ -408,7 +408,7 @@ static int msi001_s_ctrl(struct v4l2_ctrl *ctrl) s->mixer_gain->cur.val, s->if_gain->val); break; default: - dev_dbg(&s->spi->dev, "unkown control %d\n", ctrl->id); + dev_dbg(&s->spi->dev, "unknown control %d\n", ctrl->id); ret = -EINVAL; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index c88b20af87df..bb2af7207826 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -591,7 +591,7 @@ int bnx2x_vf_mcast(struct bnx2x *bp, struct bnx2x_virtf *vf, mc = kzalloc(mc_num * sizeof(struct bnx2x_mcast_list_elem), GFP_KERNEL); if (!mc) { - BNX2X_ERR("Cannot Configure mulicasts due to lack of memory\n"); + BNX2X_ERR("Cannot Configure multicasts due to lack of memory\n"); return -ENOMEM; } } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index 69b46c051cc0..a5a482946679 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c @@ -794,7 +794,7 @@ int qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *adapter, if (rv) netdev_err(adapter->netdev, - "Failed to set Rx coalescing parametrs\n"); + "Failed to set Rx coalescing parameters\n"); return rv; } diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 46709301a51e..8698af91eaca 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -4342,7 +4342,7 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw, bw = WMI_PEER_CHWIDTH_80MHZ; break; case IEEE80211_STA_RX_BW_160: - ath10k_warn(ar, "Invalid bandwith %d in rc update for %pM\n", + ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n", sta->bandwidth, sta->addr); bw = WMI_PEER_CHWIDTH_20MHZ; break; diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/dm.c b/drivers/net/wireless/rtlwifi/rtl8723be/dm.c index dd7eb4371f49..13430b53f7ca 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723be/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8723be/dm.c @@ -336,7 +336,7 @@ static void rtl8723be_dm_find_minimum_rssi(struct ieee80211_hw *hw) rtl_dm_dig->min_undec_pwdb_for_dm = rtlpriv->dm.entry_min_undec_sm_pwdb; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, - "AP Ext Port or disconnet PWDB = 0x%x\n", + "AP Ext Port or disconnect PWDB = 0x%x\n", rtl_dm_dig->min_undec_pwdb_for_dm); } RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n", diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c b/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c index 9be106109921..cb20e23744e3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c @@ -899,7 +899,7 @@ static void rtl8821ae_dm_dig(struct ieee80211_hw *hw) if (rtlpriv->falsealm_cnt.cnt_all > 10000) { RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - "Abnornally false alarm case.\n"); + "Abnormally false alarm case.\n"); if (dm_digtable->large_fa_hit != 3) dm_digtable->large_fa_hit++; diff --git a/drivers/parisc/eisa_enumerator.c b/drivers/parisc/eisa_enumerator.c index caa153133754..a656d9e83343 100644 --- a/drivers/parisc/eisa_enumerator.c +++ b/drivers/parisc/eisa_enumerator.c @@ -357,7 +357,7 @@ static int parse_slot_config(int slot, } if (flags & HPEE_FUNCTION_INFO_CFG_FREE_FORM) { /* I have no idea how to handle this */ - printk("function %d have free-form confgiuration, skipping ", + printk("function %d have free-form configuration, skipping ", num_func); pos = p0 + function_len; continue; diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index 80d97f3d2ed9..1028760b8a22 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c @@ -237,7 +237,7 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba, beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT | BEISCSI_LOG_EH | BEISCSI_LOG_CONFIG, - "BC_%d : Insufficent Buffer Error " + "BC_%d : Insufficient Buffer Error " "Resp_Len : %d Actual_Resp_Len : %d\n", mbx_resp_hdr->response_length, mbx_resp_hdr->actual_resp_len); diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index 488c3929f19a..0cccd6033feb 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c @@ -186,7 +186,7 @@ static int _osd_get_print_system_info(struct osd_dev *od, if (unlikely(len > sizeof(odi->systemid))) { OSD_ERR("OSD Target error: OSD_SYSTEM_ID too long(%d). " - "device idetification might not work\n", len); + "device identification might not work\n", len); len = sizeof(odi->systemid); } odi->systemid_len = len; diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 54cb2ac9339b..7d2b18f2675c 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -1274,7 +1274,7 @@ qla82xx_pinit_from_rom(scsi_qla_host_t *vha) if (off == ADDR_ERROR) { ql_log(ql_log_fatal, vha, 0x0116, - "Unknow addr: 0x%08lx.\n", buf[i].addr); + "Unknown addr: 0x%08lx.\n", buf[i].addr); continue; } diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index db3dbd999cb6..45bdc4d558c0 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -4174,7 +4174,7 @@ qla83xx_schedule_work(scsi_qla_host_t *base_vha, int work_code) break; default: ql_log(ql_log_warn, base_vha, 0xb05f, - "Unknow work-code=0x%x.\n", work_code); + "Unknown work-code=0x%x.\n", work_code); } return; @@ -4774,7 +4774,7 @@ qla83xx_idc_state_handler(scsi_qla_host_t *base_vha) break; default: ql_log(ql_log_warn, base_vha, 0xb071, - "Unknow Device State: %x.\n", dev_state); + "Unknown Device State: %x.\n", dev_state); qla83xx_idc_unlock(base_vha, 0); qla8xxx_dev_failed_handler(base_vha); rval = QLA_FUNCTION_FAILED; diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 61c41298b4ea..3b91aedf439e 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -1005,7 +1005,7 @@ rpcrdma_init_fmrs(struct rpcrdma_ia *ia, struct rpcrdma_buffer *buf) int i, rc; i = (buf->rb_max_requests + 1) * RPCRDMA_MAX_SEGS; - dprintk("RPC: %s: initalizing %d FMRs\n", __func__, i); + dprintk("RPC: %s: initializing %d FMRs\n", __func__, i); while (i--) { r = kzalloc(sizeof(*r), GFP_KERNEL); @@ -1038,7 +1038,7 @@ rpcrdma_init_frmrs(struct rpcrdma_ia *ia, struct rpcrdma_buffer *buf) int i, rc; i = (buf->rb_max_requests + 1) * RPCRDMA_MAX_SEGS; - dprintk("RPC: %s: initalizing %d FRMRs\n", __func__, i); + dprintk("RPC: %s: initializing %d FRMRs\n", __func__, i); while (i--) { r = kzalloc(sizeof(*r), GFP_KERNEL); diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index c7918f83b300..1cb1ef765ca0 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -456,7 +456,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, return -EINVAL; } if (field->name[0] == '[') { - pr_err("Semantic error: %s is not a pointor" + pr_err("Semantic error: %s is not a pointer" " nor array.\n", varname); return -EINVAL; } -- cgit v1.2.3 From 6f5a272c99108d9f8450c454a4baede9e7cc643f Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Fri, 6 Mar 2015 13:45:00 -0800 Subject: net: bcmgenet: rework Rx queue init In preparation for supporting multiple Rx queues: 1. Move the initialization of priv->num_rx_bds, priv->rx_bds, and priv->rx_cbs from bcmgenet_init_rx_ring() to bcmgenet_init_dma() since they are not specific to a single Rx queue. Mimics the Tx init model where priv->num_tx_bds, priv->tx_bds, and priv->tx_cbs are initialized in bcmgenet_init_dma(). 2. Program DMA_MBUF_DONE_THRESH = 1 so that future Rx queues Q0-Q15 will get per-packet Rx interrupt. 3. Group DMA_START_ADDR, RDMA_READ_PTR, RDMA_WRITE_PTR, and DMA_END_ADDR initialization together. Mimics the Tx init model. 4. There is 1-to-1 mapping between RxCBs and RxBDs. Precalculate RxCB->bd_addr so that it can be used in the future. Signed-off-by: Petri Gynther Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 43 ++++++++++++++++---------- 1 file changed, 27 insertions(+), 16 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index d90785caab59..83c0cb323e0c 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1783,37 +1783,33 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv, u32 words_per_bd = WORDS_PER_BD(priv); int ret; - priv->num_rx_bds = TOTAL_DESC; - priv->rx_bds = priv->base + priv->hw_params->rdma_offset; priv->rx_bd_assign_ptr = priv->rx_bds; priv->rx_bd_assign_index = 0; priv->rx_c_index = 0; priv->rx_read_ptr = 0; - priv->rx_cbs = kcalloc(priv->num_rx_bds, sizeof(struct enet_cb), - GFP_KERNEL); - if (!priv->rx_cbs) - return -ENOMEM; ret = bcmgenet_alloc_rx_buffers(priv); if (ret) { - kfree(priv->rx_cbs); return ret; } - bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_WRITE_PTR); bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_PROD_INDEX); bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_CONS_INDEX); + bcmgenet_rdma_ring_writel(priv, index, 1, DMA_MBUF_DONE_THRESH); bcmgenet_rdma_ring_writel(priv, index, ((size << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH), DMA_RING_BUF_SIZE); - bcmgenet_rdma_ring_writel(priv, index, 0, DMA_START_ADDR); - bcmgenet_rdma_ring_writel(priv, index, - words_per_bd * size - 1, DMA_END_ADDR); bcmgenet_rdma_ring_writel(priv, index, (DMA_FC_THRESH_LO << DMA_XOFF_THRESHOLD_SHIFT) | DMA_FC_THRESH_HI, RDMA_XON_XOFF_THRESH); + + /* Set start and end address, read and write pointers */ + bcmgenet_rdma_ring_writel(priv, index, 0, DMA_START_ADDR); bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_READ_PTR); + bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_WRITE_PTR); + bcmgenet_rdma_ring_writel(priv, index, words_per_bd * size - 1, + DMA_END_ADDR); return ret; } @@ -1976,18 +1972,33 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv) unsigned int i; struct enet_cb *cb; - netif_dbg(priv, hw, priv->dev, "bcmgenet: init_edma\n"); + netif_dbg(priv, hw, priv->dev, "%s\n", __func__); - /* by default, enable ring 16 (descriptor based) */ + /* Init rDma */ + bcmgenet_rdma_writel(priv, DMA_MAX_BURST_LENGTH, DMA_SCB_BURST_SIZE); + + /* Initialize common Rx ring structures */ + priv->rx_bds = priv->base + priv->hw_params->rdma_offset; + priv->num_rx_bds = TOTAL_DESC; + priv->rx_cbs = kcalloc(priv->num_rx_bds, sizeof(struct enet_cb), + GFP_KERNEL); + if (!priv->rx_cbs) + return -ENOMEM; + + for (i = 0; i < priv->num_rx_bds; i++) { + cb = priv->rx_cbs + i; + cb->bd_addr = priv->rx_bds + i * DMA_DESC_SIZE; + } + + /* Initialize Rx default queue 16 */ ret = bcmgenet_init_rx_ring(priv, DESC_INDEX, TOTAL_DESC); if (ret) { netdev_err(priv->dev, "failed to initialize RX ring\n"); + bcmgenet_free_rx_buffers(priv); + kfree(priv->rx_cbs); return ret; } - /* init rDma */ - bcmgenet_rdma_writel(priv, DMA_MAX_BURST_LENGTH, DMA_SCB_BURST_SIZE); - /* Init tDma */ bcmgenet_tdma_writel(priv, DMA_MAX_BURST_LENGTH, DMA_SCB_BURST_SIZE); -- cgit v1.2.3 From dbedd44e982d61c156337b1a3fb252b24085f8e3 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 6 Mar 2015 20:49:12 -0800 Subject: ethernet: codespell comment spelling fixes To test a checkpatch spelling patch, I ran codespell against drivers/net/ethernet/. $ git ls-files drivers/net/ethernet/ | \ while read file ; do \ codespell -w $file; \ done I removed a false positive in e1000_hw.h Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/ethernet/allwinner/sun4i-emac.c | 2 +- drivers/net/ethernet/amd/amd8111e.c | 4 ++-- drivers/net/ethernet/amd/amd8111e.h | 2 +- drivers/net/ethernet/amd/xgbe/xgbe.h | 2 +- drivers/net/ethernet/apple/mace.c | 2 +- drivers/net/ethernet/apple/macmace.c | 2 +- drivers/net/ethernet/atheros/atl1c/atl1c_hw.c | 4 ++-- drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 12 ++++++------ drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c | 4 ++-- drivers/net/ethernet/brocade/bna/bfa_defs_cna.h | 2 +- drivers/net/ethernet/brocade/bna/bfa_ioc.c | 2 +- drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c | 2 +- drivers/net/ethernet/brocade/bna/bfi.h | 4 ++-- drivers/net/ethernet/brocade/bna/bna_hw_defs.h | 2 +- drivers/net/ethernet/calxeda/xgmac.c | 20 ++++++++++---------- drivers/net/ethernet/chelsio/cxgb3/t3_hw.c | 2 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 2 +- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 6 +++--- drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 2 +- drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 2 +- drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 2 +- drivers/net/ethernet/cirrus/cs89x0.c | 2 +- drivers/net/ethernet/dec/tulip/dmfe.c | 2 +- drivers/net/ethernet/dec/tulip/uli526x.c | 2 +- drivers/net/ethernet/emulex/benet/be_cmds.c | 2 +- drivers/net/ethernet/freescale/fec_ptp.c | 2 +- drivers/net/ethernet/intel/e100.c | 2 +- drivers/net/ethernet/intel/e1000/e1000_main.c | 2 +- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 4 ++-- drivers/net/ethernet/intel/igb/igb_ptp.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | 2 +- drivers/net/ethernet/intel/ixgbevf/vf.c | 2 +- drivers/net/ethernet/marvell/mvpp2.c | 4 ++-- drivers/net/ethernet/mellanox/mlx4/mlx4.h | 2 +- .../net/ethernet/mellanox/mlx4/resource_tracker.c | 2 +- drivers/net/ethernet/moxa/moxart_ether.c | 2 +- drivers/net/ethernet/neterion/s2io.c | 2 +- .../net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c | 2 +- drivers/net/ethernet/packetengines/hamachi.c | 2 +- drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 2 +- .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 4 ++-- drivers/net/ethernet/qualcomm/qca_spi.c | 2 +- drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 12 ++++++------ drivers/net/ethernet/sfc/efx.c | 2 +- drivers/net/ethernet/sfc/farch.c | 4 ++-- drivers/net/ethernet/sfc/mcdi_pcol.h | 2 +- drivers/net/ethernet/sfc/siena_sriov.c | 2 +- drivers/net/ethernet/sfc/vfdi.h | 4 ++-- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- drivers/net/ethernet/sun/sungem.c | 4 ++-- drivers/net/ethernet/ti/cpsw.c | 2 +- drivers/net/ethernet/toshiba/ps3_gelic_net.c | 2 +- drivers/net/ethernet/wiznet/w5100.c | 2 +- drivers/net/ethernet/wiznet/w5300.c | 2 +- 61 files changed, 92 insertions(+), 92 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c index f3470d96837a..bab01c849165 100644 --- a/drivers/net/ethernet/allwinner/sun4i-emac.c +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c @@ -757,7 +757,7 @@ static void emac_shutdown(struct net_device *dev) /* Disable all interrupt */ writel(0, db->membase + EMAC_INT_CTL_REG); - /* clear interupt status */ + /* clear interrupt status */ reg_val = readl(db->membase + EMAC_INT_STA_REG); writel(reg_val, db->membase + EMAC_INT_STA_REG); diff --git a/drivers/net/ethernet/amd/amd8111e.c b/drivers/net/ethernet/amd/amd8111e.c index 4c2ae2221780..94960055fa1f 100644 --- a/drivers/net/ethernet/amd/amd8111e.c +++ b/drivers/net/ethernet/amd/amd8111e.c @@ -723,13 +723,13 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget) * the last correctly noting the error. */ if(status & ERR_BIT) { - /* reseting flags */ + /* resetting flags */ lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS; goto err_next_pkt; } /* check for STP and ENP */ if(!((status & STP_BIT) && (status & ENP_BIT))){ - /* reseting flags */ + /* resetting flags */ lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS; goto err_next_pkt; } diff --git a/drivers/net/ethernet/amd/amd8111e.h b/drivers/net/ethernet/amd/amd8111e.h index a75092d584cc..7cdb18512407 100644 --- a/drivers/net/ethernet/amd/amd8111e.h +++ b/drivers/net/ethernet/amd/amd8111e.h @@ -614,7 +614,7 @@ typedef enum { /* Assume contoller gets data 10 times the maximum processing time */ #define REPEAT_CNT 10 -/* amd8111e decriptor flag definitions */ +/* amd8111e descriptor flag definitions */ typedef enum { OWN_BIT = (1 << 15), diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h index 13e8f95c077c..1eea3e5a5d08 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe.h @@ -620,7 +620,7 @@ struct xgbe_hw_features { unsigned int mgk; /* PMT magic packet */ unsigned int mmc; /* RMON module */ unsigned int aoe; /* ARP Offload */ - unsigned int ts; /* IEEE 1588-2008 Adavanced Timestamp */ + unsigned int ts; /* IEEE 1588-2008 Advanced Timestamp */ unsigned int eee; /* Energy Efficient Ethernet */ unsigned int tx_coe; /* Tx Checksum Offload */ unsigned int rx_coe; /* Rx Checksum Offload */ diff --git a/drivers/net/ethernet/apple/mace.c b/drivers/net/ethernet/apple/mace.c index 842fe7684904..7fcaf0da42a8 100644 --- a/drivers/net/ethernet/apple/mace.c +++ b/drivers/net/ethernet/apple/mace.c @@ -720,7 +720,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id) mace_reset(dev); /* * XXX mace likes to hang the machine after a xmtfs error. - * This is hard to reproduce, reseting *may* help + * This is hard to reproduce, resetting *may* help */ } cp = mp->tx_cmds + NCMDS_TX * i; diff --git a/drivers/net/ethernet/apple/macmace.c b/drivers/net/ethernet/apple/macmace.c index 6e66127e6abf..89914ca17a49 100644 --- a/drivers/net/ethernet/apple/macmace.c +++ b/drivers/net/ethernet/apple/macmace.c @@ -575,7 +575,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id) mace_reset(dev); /* * XXX mace likes to hang the machine after a xmtfs error. - * This is hard to reproduce, reseting *may* help + * This is hard to reproduce, resetting *may* help */ } /* dma should have finished */ diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c index 52fdfe225978..a8b80c56ac25 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c @@ -307,7 +307,7 @@ void atl1c_start_phy_polling(struct atl1c_hw *hw, u16 clk_sel) /* * atl1c_read_phy_core - * core funtion to read register in PHY via MDIO control regsiter. + * core function to read register in PHY via MDIO control regsiter. * ext: extension register (see IEEE 802.3) * dev: device address (see IEEE 802.3 DEVAD, PRTAD is fixed to 0) * reg: reg to read @@ -356,7 +356,7 @@ int atl1c_read_phy_core(struct atl1c_hw *hw, bool ext, u8 dev, /* * atl1c_write_phy_core - * core funtion to write to register in PHY via MDIO control regsiter. + * core function to write to register in PHY via MDIO control register. * ext: extension register (see IEEE 802.3) * dev: device address (see IEEE 802.3 DEVAD, PRTAD is fixed to 0) * reg: reg to write diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 587f63e87588..932bd1862f7a 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -752,7 +752,7 @@ static void atl1c_patch_assign(struct atl1c_hw *hw) if (hw->device_id == PCI_DEVICE_ID_ATHEROS_L2C_B2 && hw->revision_id == L2CB_V21) { - /* config acess mode */ + /* config access mode */ pci_write_config_dword(pdev, REG_PCIE_IND_ACC_ADDR, REG_PCIE_DEV_MISC_CTRL); pci_read_config_dword(pdev, REG_PCIE_IND_ACC_DATA, &misc_ctrl); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h index bd90e50bd8e6..d6e1975b7b69 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h @@ -278,7 +278,7 @@ static inline void bnx2x_dcb_config_qm(struct bnx2x *bp, enum cos_mode mode, } -/* congestion managment port init api description +/* congestion management port init api description * the api works as follows: * the driver should pass the cmng_init_input struct, the port_init function * will prepare the required internal ram structure which will be passed back diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 778e4cd32571..b7c77b26a8a4 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -563,7 +563,7 @@ static void bnx2x_ets_e3b0_set_credit_upper_bound_nig( * Will return the NIG ETS registers to init values.Except * credit_upper_bound. * That isn't used in this configuration (No WFQ is enabled) and will be -* configured acording to spec +* configured according to spec *. ******************************************************************************/ static void bnx2x_ets_e3b0_nig_disabled(const struct link_params *params, @@ -680,7 +680,7 @@ static void bnx2x_ets_e3b0_set_credit_upper_bound_pbf( * Will return the PBF ETS registers to init values.Except * credit_upper_bound. * That isn't used in this configuration (No WFQ is enabled) and will be -* configured acording to spec +* configured according to spec *. ******************************************************************************/ static void bnx2x_ets_e3b0_pbf_disabled(const struct link_params *params) @@ -738,7 +738,7 @@ static void bnx2x_ets_e3b0_pbf_disabled(const struct link_params *params) } /****************************************************************************** * Description: -* E3B0 disable will return basicly the values to init values. +* E3B0 disable will return basically the values to init values. *. ******************************************************************************/ static int bnx2x_ets_e3b0_disabled(const struct link_params *params, @@ -761,7 +761,7 @@ static int bnx2x_ets_e3b0_disabled(const struct link_params *params, /****************************************************************************** * Description: -* Disable will return basicly the values to init values. +* Disable will return basically the values to init values. * ******************************************************************************/ int bnx2x_ets_disabled(struct link_params *params, @@ -2938,7 +2938,7 @@ static int bnx2x_eee_initial_config(struct link_params *params, { vars->eee_status |= ((u32) mode) << SHMEM_EEE_SUPPORTED_SHIFT; - /* Propogate params' bits --> vars (for migration exposure) */ + /* Propagate params' bits --> vars (for migration exposure) */ if (params->eee_mode & EEE_MODE_ENABLE_LPI) vars->eee_status |= SHMEM_EEE_LPI_REQUESTED_BIT; else @@ -13308,7 +13308,7 @@ static void bnx2x_check_over_curr(struct link_params *params, vars->phy_flags &= ~PHY_OVER_CURRENT_FLAG; } -/* Returns 0 if no change occured since last check; 1 otherwise. */ +/* Returns 0 if no change occurred since last check; 1 otherwise. */ static u8 bnx2x_analyze_link_error(struct link_params *params, struct link_vars *vars, u32 status, u32 phy_flag, u32 link_flag, u8 notify) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index 6fe547c93e74..0770e4bff89b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h @@ -29,7 +29,7 @@ #define ATC_ATC_INT_STS_REG_ATC_TCPL_TO_NOT_PEND (0x1<<1) /* [RW 1] Initiate the ATC array - reset all the valid bits */ #define ATC_REG_ATC_INIT_ARRAY 0x1100b8 -/* [R 1] ATC initalization done */ +/* [R 1] ATC initialization done */ #define ATC_REG_ATC_INIT_DONE 0x1100bc /* [RC 6] Interrupt register #0 read clear */ #define ATC_REG_ATC_INT_STS_CLR 0x1101c0 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index d1608297c773..612cafb5df53 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c @@ -1620,7 +1620,7 @@ void bnx2x_memset_stats(struct bnx2x *bp) if (bp->port.pmf && bp->port.port_stx) bnx2x_port_stats_base_init(bp); - /* mark the end of statistics initializiation */ + /* mark the end of statistics initialization */ bp->stats_init = false; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c index be40eabc5304..15b2d1647560 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c @@ -800,7 +800,7 @@ int bnx2x_vfpf_config_rss(struct bnx2x *bp, req->rss_key_size = T_ETH_RSS_KEY; req->rss_result_mask = params->rss_result_mask; - /* flags handled individually for backward/forward compatability */ + /* flags handled individually for backward/forward compatibility */ if (params->rss_flags & (1 << BNX2X_RSS_MODE_DISABLED)) req->rss_flags |= VFPF_RSS_MODE_DISABLED; if (params->rss_flags & (1 << BNX2X_RSS_MODE_REGULAR)) @@ -1869,7 +1869,7 @@ static void bnx2x_vf_mbx_update_rss(struct bnx2x *bp, struct bnx2x_virtf *vf, rss.rss_obj = &vf->rss_conf_obj; rss.rss_result_mask = rss_tlv->rss_result_mask; - /* flags handled individually for backward/forward compatability */ + /* flags handled individually for backward/forward compatibility */ rss.rss_flags = 0; rss.ramrod_flags = 0; diff --git a/drivers/net/ethernet/brocade/bna/bfa_defs_cna.h b/drivers/net/ethernet/brocade/bna/bfa_defs_cna.h index 63e300f5ba41..a37326d44fbb 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_defs_cna.h +++ b/drivers/net/ethernet/brocade/bna/bfa_defs_cna.h @@ -135,7 +135,7 @@ struct bfa_cee_lldp_str { u8 value[BFA_CEE_LLDP_MAX_STRING_LEN]; }; -/* LLDP paramters */ +/* LLDP parameters */ struct bfa_cee_lldp_cfg { struct bfa_cee_lldp_str chassis_id; struct bfa_cee_lldp_str port_id; diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.c b/drivers/net/ethernet/brocade/bna/bfa_ioc.c index f2d13238b02e..594a2ab36d31 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c +++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c @@ -1340,7 +1340,7 @@ bfa_ioc_fwver_md5_check(struct bfi_ioc_image_hdr *fwhdr_1, return true; } -/* Returns TRUE if major minor and maintainence are same. +/* Returns TRUE if major minor and maintenance are same. * If patch version are same, check for MD5 Checksum to be same. */ static bool diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c b/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c index 66c8507d7717..2e72445dbb4f 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c +++ b/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c @@ -699,7 +699,7 @@ bfa_ioc_ct2_sclk_init(void __iomem *rb) /* * Ignore mode and program for the max clock (which is FC16) - * Firmware/NFC will do the PLL init appropiately + * Firmware/NFC will do the PLL init appropriately */ r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG)); r32 &= ~(__APP_PLL_SCLK_REFCLK_SEL | __APP_PLL_SCLK_CLK_DIV2); diff --git a/drivers/net/ethernet/brocade/bna/bfi.h b/drivers/net/ethernet/brocade/bna/bfi.h index f1e1129e6241..2bcde4042268 100644 --- a/drivers/net/ethernet/brocade/bna/bfi.h +++ b/drivers/net/ethernet/brocade/bna/bfi.h @@ -159,8 +159,8 @@ enum bfi_asic_gen { }; enum bfi_asic_mode { - BFI_ASIC_MODE_FC = 1, /* FC upto 8G speed */ - BFI_ASIC_MODE_FC16 = 2, /* FC upto 16G speed */ + BFI_ASIC_MODE_FC = 1, /* FC up to 8G speed */ + BFI_ASIC_MODE_FC16 = 2, /* FC up to 16G speed */ BFI_ASIC_MODE_ETH = 3, /* Ethernet ports */ BFI_ASIC_MODE_COMBO = 4, /* FC 16G and Ethernet 10G port */ }; diff --git a/drivers/net/ethernet/brocade/bna/bna_hw_defs.h b/drivers/net/ethernet/brocade/bna/bna_hw_defs.h index c5feab130d6d..174af0e9d056 100644 --- a/drivers/net/ethernet/brocade/bna/bna_hw_defs.h +++ b/drivers/net/ethernet/brocade/bna/bna_hw_defs.h @@ -363,7 +363,7 @@ struct bna_txq_wi_vector { /* TxQ Entry Structure * - * BEWARE: Load values into this structure with correct endianess. + * BEWARE: Load values into this structure with correct endianness. */ struct bna_txq_entry { union { diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c index 47bfea24b9e1..63efa0dc45ba 100644 --- a/drivers/net/ethernet/calxeda/xgmac.c +++ b/drivers/net/ethernet/calxeda/xgmac.c @@ -47,9 +47,9 @@ #define XGMAC_REMOTE_WAKE 0x00000700 /* Remote Wake-Up Frm Filter */ #define XGMAC_PMT 0x00000704 /* PMT Control and Status */ #define XGMAC_MMC_CTRL 0x00000800 /* XGMAC MMC Control */ -#define XGMAC_MMC_INTR_RX 0x00000804 /* Recieve Interrupt */ +#define XGMAC_MMC_INTR_RX 0x00000804 /* Receive Interrupt */ #define XGMAC_MMC_INTR_TX 0x00000808 /* Transmit Interrupt */ -#define XGMAC_MMC_INTR_MASK_RX 0x0000080c /* Recieve Interrupt Mask */ +#define XGMAC_MMC_INTR_MASK_RX 0x0000080c /* Receive Interrupt Mask */ #define XGMAC_MMC_INTR_MASK_TX 0x00000810 /* Transmit Interrupt Mask */ /* Hardware TX Statistics Counters */ @@ -153,7 +153,7 @@ #define XGMAC_FLOW_CTRL_PT_MASK 0xffff0000 /* Pause Time Mask */ #define XGMAC_FLOW_CTRL_PT_SHIFT 16 #define XGMAC_FLOW_CTRL_DZQP 0x00000080 /* Disable Zero-Quanta Phase */ -#define XGMAC_FLOW_CTRL_PLT 0x00000020 /* Pause Low Threshhold */ +#define XGMAC_FLOW_CTRL_PLT 0x00000020 /* Pause Low Threshold */ #define XGMAC_FLOW_CTRL_PLT_MASK 0x00000030 /* PLT MASK */ #define XGMAC_FLOW_CTRL_UP 0x00000008 /* Unicast Pause Frame Detect */ #define XGMAC_FLOW_CTRL_RFE 0x00000004 /* Rx Flow Control Enable */ @@ -254,18 +254,18 @@ /* XGMAC Operation Mode Register */ #define XGMAC_OMR_TSF 0x00200000 /* TX FIFO Store and Forward */ #define XGMAC_OMR_FTF 0x00100000 /* Flush Transmit FIFO */ -#define XGMAC_OMR_TTC 0x00020000 /* Transmit Threshhold Ctrl */ +#define XGMAC_OMR_TTC 0x00020000 /* Transmit Threshold Ctrl */ #define XGMAC_OMR_TTC_MASK 0x00030000 -#define XGMAC_OMR_RFD 0x00006000 /* FC Deactivation Threshhold */ -#define XGMAC_OMR_RFD_MASK 0x00007000 /* FC Deact Threshhold MASK */ -#define XGMAC_OMR_RFA 0x00000600 /* FC Activation Threshhold */ -#define XGMAC_OMR_RFA_MASK 0x00000E00 /* FC Act Threshhold MASK */ +#define XGMAC_OMR_RFD 0x00006000 /* FC Deactivation Threshold */ +#define XGMAC_OMR_RFD_MASK 0x00007000 /* FC Deact Threshold MASK */ +#define XGMAC_OMR_RFA 0x00000600 /* FC Activation Threshold */ +#define XGMAC_OMR_RFA_MASK 0x00000E00 /* FC Act Threshold MASK */ #define XGMAC_OMR_EFC 0x00000100 /* Enable Hardware FC */ #define XGMAC_OMR_FEF 0x00000080 /* Forward Error Frames */ #define XGMAC_OMR_DT 0x00000040 /* Drop TCP/IP csum Errors */ #define XGMAC_OMR_RSF 0x00000020 /* RX FIFO Store and Forward */ -#define XGMAC_OMR_RTC_256 0x00000018 /* RX Threshhold Ctrl */ -#define XGMAC_OMR_RTC_MASK 0x00000018 /* RX Threshhold Ctrl MASK */ +#define XGMAC_OMR_RTC_256 0x00000018 /* RX Threshold Ctrl */ +#define XGMAC_OMR_RTC_MASK 0x00000018 /* RX Threshold Ctrl MASK */ /* XGMAC HW Features Register */ #define DMA_HW_FEAT_TXCOESEL 0x00010000 /* TX Checksum offload */ diff --git a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c index 184a8d545ac4..a22768c94200 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c @@ -840,7 +840,7 @@ static int flash_wait_op(struct adapter *adapter, int attempts, int delay) * Read the specified number of 32-bit words from the serial flash. * If @byte_oriented is set the read data is stored as a byte array * (i.e., big-endian), otherwise as 32-bit words in the platform's - * natural endianess. + * natural endianness. */ static int t3_read_flash(struct adapter *adapter, unsigned int addr, unsigned int nwords, u32 *data, int byte_oriented) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index e344bdcd40b3..4af8a9fd75ae 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -5366,7 +5366,7 @@ static int adap_init0(struct adapter *adap) adap->tids.stid_base = val[1]; adap->tids.nstids = val[2] - val[1] + 1; /* - * Setup server filter region. Divide the availble filter + * Setup server filter region. Divide the available filter * region into two parts. Regular filters get 1/3rd and server * filters get 2/3rd part. This is only enabled if workarond * path is enabled. diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 853c38997c82..1498d078c319 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -867,7 +867,7 @@ static int flash_wait_op(struct adapter *adapter, int attempts, int delay) * Read the specified number of 32-bit words from the serial flash. * If @byte_oriented is set the read data is stored as a byte array * (i.e., big-endian), otherwise as 32-bit words in the platform's - * natural endianess. + * natural endianness. */ int t4_read_flash(struct adapter *adapter, unsigned int addr, unsigned int nwords, u32 *data, int byte_oriented) @@ -3558,7 +3558,7 @@ int t4_fixup_host_params(struct adapter *adap, unsigned int page_size, * For the single-MTU buffers in unpacked mode we need to include * space for the SGE Control Packet Shift, 14 byte Ethernet header, * possible 4 byte VLAN tag, all rounded up to the next Ingress Packet - * Padding boundry. All of these are accommodated in the Factory + * Padding boundary. All of these are accommodated in the Factory * Default Firmware Configuration File but we need to adjust it for * this host's cache line size. */ @@ -4529,7 +4529,7 @@ int t4_init_tp_params(struct adapter *adap) PROTOCOL_F); /* If TP_INGRESS_CONFIG.VNID == 0, then TP_VLAN_PRI_MAP.VNIC_ID - * represents the presense of an Outer VLAN instead of a VNIC ID. + * represents the presence of an Outer VLAN instead of a VNIC ID. */ if ((adap->params.tp.ingress_config & VNIC_F) == 0) adap->params.tp.vnic_shift = -1; diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index 9b353a88cbda..d136ca6a0c8a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h @@ -36,7 +36,7 @@ #define _T4FW_INTERFACE_H_ enum fw_retval { - FW_SUCCESS = 0, /* completed sucessfully */ + FW_SUCCESS = 0, /* completed successfully */ FW_EPERM = 1, /* operation not permitted */ FW_ENOENT = 2, /* no such file or directory */ FW_EIO = 5, /* input/output error; hw bad */ diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index 0545f0de1c52..5ba14b32c370 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -875,7 +875,7 @@ static inline unsigned int calc_tx_flits(const struct sk_buff *skb) * Write Header (incorporated as part of the cpl_tx_pkt_lso and * cpl_tx_pkt structures), followed by either a TX Packet Write CPL * message or, if we're doing a Large Send Offload, an LSO CPL message - * with an embeded TX Packet Write CPL message. + * with an embedded TX Packet Write CPL message. */ flits = sgl_len(skb_shinfo(skb)->nr_frags + 1); if (skb_shinfo(skb)->gso_size) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c index 1b5506df35b1..c21e2e954ad8 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c @@ -339,7 +339,7 @@ int t4vf_port_init(struct adapter *adapter, int pidx) * @adapter: the adapter * * Issues a reset command to FW. For a Physical Function this would - * result in the Firmware reseting all of its state. For a Virtual + * result in the Firmware resetting all of its state. For a Virtual * Function this just resets the state associated with the VF. */ int t4vf_fw_reset(struct adapter *adapter) diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c index d1c025fd9726..60383040d6c6 100644 --- a/drivers/net/ethernet/cirrus/cs89x0.c +++ b/drivers/net/ethernet/cirrus/cs89x0.c @@ -1578,7 +1578,7 @@ out1: #ifndef CONFIG_CS89x0_PLATFORM /* - * This function converts the I/O port addres used by the cs89x0_probe() and + * This function converts the I/O port address used by the cs89x0_probe() and * init_module() functions to the I/O memory address used by the * cs89x0_probe1() function. */ diff --git a/drivers/net/ethernet/dec/tulip/dmfe.c b/drivers/net/ethernet/dec/tulip/dmfe.c index 50a00777228e..afd8e78e024e 100644 --- a/drivers/net/ethernet/dec/tulip/dmfe.c +++ b/drivers/net/ethernet/dec/tulip/dmfe.c @@ -653,7 +653,7 @@ static void dmfe_init_dm910x(struct DEVICE *dev) if ( !(db->media_mode & DMFE_AUTO) ) db->op_mode = db->media_mode; /* Force Mode */ - /* Initialize Transmit/Receive decriptor and CR3/4 */ + /* Initialize Transmit/Receive descriptor and CR3/4 */ dmfe_descriptor_init(dev); /* Init CR6 to program DM910x operation */ diff --git a/drivers/net/ethernet/dec/tulip/uli526x.c b/drivers/net/ethernet/dec/tulip/uli526x.c index 1c5916b13778..2c30c0c83f98 100644 --- a/drivers/net/ethernet/dec/tulip/uli526x.c +++ b/drivers/net/ethernet/dec/tulip/uli526x.c @@ -564,7 +564,7 @@ static void uli526x_init(struct net_device *dev) if ( !(db->media_mode & ULI526X_AUTO) ) db->op_mode = db->media_mode; /* Force Mode */ - /* Initialize Transmit/Receive decriptor and CR3/4 */ + /* Initialize Transmit/Receive descriptor and CR3/4 */ uli526x_descriptor_init(dev, ioaddr); /* Init CR6 to program M526X operation */ diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 75cb4610423b..dc278391a391 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -3021,7 +3021,7 @@ int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac, mac_count = resp->true_mac_count + resp->pseudo_mac_count; /* Mac list returned could contain one or more active mac_ids - * or one or more true or pseudo permanant mac addresses. + * or one or more true or pseudo permanent mac addresses. * If an active mac_id is present, return first active mac_id * found. */ diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index 1f9cf2345266..4585895ddc9a 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -136,7 +136,7 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable) */ writel(FEC_T_TF_MASK, fep->hwp + FEC_TCSR(fep->pps_channel)); - /* It is recommended to doulbe check the TMODE field in the + /* It is recommended to double check the TMODE field in the * TCSR register to be cleared before the first compare counter * is written into TCCR register. Just add a double check. */ diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index e9c3a87e5b11..05f88394f9a5 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c @@ -414,7 +414,7 @@ enum cb_status { /** * cb_command - Command Block flags - * @cb_tx_nc: 0: controler does CRC (normal), 1: CRC from skb memory + * @cb_tx_nc: 0: controller does CRC (normal), 1: CRC from skb memory */ enum cb_command { cb_nop = 0x0000, diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 73c98d34fa1f..b548ef0cf56b 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -1116,7 +1116,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (e1000_read_mac_addr(hw)) e_err(probe, "EEPROM Read Error\n"); } - /* don't block initalization here due to bad MAC address */ + /* don't block initialization here due to bad MAC address */ memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len); if (!is_valid_ether_addr(netdev->dev_addr)) diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index 8537416123a5..f44911df286a 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -2009,7 +2009,7 @@ static int i40evf_check_reset_complete(struct i40e_hw *hw) * * This task completes the work that was begun in probe. Due to the nature * of VF-PF communications, we may need to wait tens of milliseconds to get - * reponses back from the PF. Rather than busy-wait in probe and bog down the + * responses back from the PF. Rather than busy-wait in probe and bog down the * whole system, we'll do it in a task so we can sleep. * This task only runs during driver init. Once we've established * communications with the PF driver and set up our netdev, the watchdog @@ -2400,7 +2400,7 @@ static int i40evf_suspend(struct pci_dev *pdev, pm_message_t state) } /** - * i40evf_resume - Power managment resume routine + * i40evf_resume - Power management resume routine * @pdev: PCI device information struct * * Called when the system (VM) is resumed from sleep/suspend. diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c index d6be4c69172d..52d01b8b01ed 100644 --- a/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c @@ -30,7 +30,7 @@ * * Neither the 82576 nor the 82580 offer registers wide enough to hold * nanoseconds time values for very long. For the 82580, SYSTIM always - * counts nanoseconds, but the upper 24 bits are not availible. The + * counts nanoseconds, but the upper 24 bits are not available. The * frequency is adjusted by changing the 32 bit fractional nanoseconds * register, TIMINCA. * diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 903664ff6904..21aea7e7f03f 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -2609,7 +2609,7 @@ static irqreturn_t ixgbe_msix_other(int irq, void *data) eicr = IXGBE_READ_REG(hw, IXGBE_EICS); /* The lower 16bits of the EICR register are for the queue interrupts - * which should be masked here in order to not accidently clear them if + * which should be masked here in order to not accidentally clear them if * the bits are high when ixgbe_msix_other is called. There is a race * condition otherwise which results in possible performance loss * especially if the ixgbe_msix_other interrupt is triggering diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index 79c00f57d3e7..bd46f5d1c943 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -488,7 +488,7 @@ static void ixgbe_ptp_tx_hwtstamp(struct ixgbe_adapter *adapter) * @work: pointer to the work struct * * This work item polls TSYNCTXCTL valid bit to determine when a Tx hardware - * timestamp has been taken for the current skb. It is necesary, because the + * timestamp has been taken for the current skb. It is necessary, because the * descriptor's "done" bit does not correlate with the timestamp event. */ static void ixgbe_ptp_tx_hwtstamp_work(struct work_struct *work) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index 7f37fe7269a7..09a291bb7c34 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -141,7 +141,7 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter) * The 82599 supports up to 64 VFs per physical function * but this implementation limits allocation to 63 so that * basic networking resources are still available to the - * physical function. If the user requests greater thn + * physical function. If the user requests greater than * 63 VFs then it is an error - reset to default of zero. */ adapter->num_vfs = min_t(unsigned int, adapter->num_vfs, IXGBE_MAX_VFS_DRV_LIMIT); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h index fc5ecee56ca8..8451f9a7cbd8 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h @@ -1690,7 +1690,7 @@ enum { #define IXGBE_MACC_FS 0x00040000 #define IXGBE_MAC_RX2TX_LPBK 0x00000002 -/* Veto Bit definiton */ +/* Veto Bit definition */ #define IXGBE_MMNGC_MNG_VETO 0x00000001 /* LINKS Bit Masks */ diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c b/drivers/net/ethernet/intel/ixgbevf/vf.c index cdb53be7d995..f510a5822f90 100644 --- a/drivers/net/ethernet/intel/ixgbevf/vf.c +++ b/drivers/net/ethernet/intel/ixgbevf/vf.c @@ -65,7 +65,7 @@ static s32 ixgbevf_init_hw_vf(struct ixgbe_hw *hw) * ixgbevf_reset_hw_vf - Performs hardware reset * @hw: pointer to hardware structure * - * Resets the hardware by reseting the transmit and receive units, masks and + * Resets the hardware by resetting the transmit and receive units, masks and * clears all interrupts. **/ static s32 ixgbevf_reset_hw_vf(struct ixgbe_hw *hw) diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index fdf3e382e464..3e8b1bfb1f2e 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -1423,7 +1423,7 @@ static void mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port, bool add) { struct mvpp2_prs_entry pe; - /* Promiscous mode - Accept unknown packets */ + /* Promiscuous mode - Accept unknown packets */ if (priv->prs_shadow[MVPP2_PE_MAC_PROMISCUOUS].valid) { /* Entry exist - update port only */ @@ -3402,7 +3402,7 @@ static void mvpp2_bm_bufs_free(struct mvpp2 *priv, struct mvpp2_bm_pool *bm_pool for (i = 0; i < bm_pool->buf_num; i++) { u32 vaddr; - /* Get buffer virtual adress (indirect access) */ + /* Get buffer virtual address (indirect access) */ mvpp2_read(priv, MVPP2_BM_PHY_ALLOC_REG(bm_pool->id)); vaddr = mvpp2_read(priv, MVPP2_BM_VIRT_ALLOC_REG); if (!vaddr) diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 1409d0cd6143..0b16db015745 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -175,7 +175,7 @@ enum mlx4_res_tracker_free_type { /* *Virtual HCR structures. - * mlx4_vhcr is the sw representation, in machine endianess + * mlx4_vhcr is the sw representation, in machine endianness * * mlx4_vhcr_cmd is the formalized structure, the one that is passed * to FW to go through communication channel. diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index d97ca88c55b5..d43e25914d19 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -3027,7 +3027,7 @@ int mlx4_WRITE_MTT_wrapper(struct mlx4_dev *dev, int slave, /* Call the SW implementation of write_mtt: * - Prepare a dummy mtt struct - * - Translate inbox contents to simple addresses in host endianess */ + * - Translate inbox contents to simple addresses in host endianness */ mtt.offset = 0; /* TBD this is broken but I don't handle it since we don't really use it */ mtt.order = 0; diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c index 6c72e74fef3e..81d0f1c86d6d 100644 --- a/drivers/net/ethernet/moxa/moxart_ether.c +++ b/drivers/net/ethernet/moxa/moxart_ether.c @@ -150,7 +150,7 @@ static void moxart_mac_setup_desc_ring(struct net_device *ndev) priv->rx_head = 0; - /* reset the MAC controler TX/RX desciptor base address */ + /* reset the MAC controller TX/RX desciptor base address */ writel(priv->tx_base, priv->base + REG_TXR_BASE_ADDRESS); writel(priv->rx_base, priv->base + REG_RXR_BASE_ADDRESS); } diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index a4cdf2f8041a..092dcae0d4a9 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c @@ -1343,7 +1343,7 @@ static int init_nic(struct s2io_nic *nic) TX_PA_CFG_IGNORE_L2_ERR; writeq(val64, &bar0->tx_pa_cfg); - /* Rx DMA intialization. */ + /* Rx DMA initialization. */ val64 = 0; for (i = 0; i < config->rx_ring_num; i++) { struct rx_ring_config *rx_cfg = &config->rx_cfg[i]; diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c index 4fe8ea96bd25..f6fcf7450352 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c @@ -394,7 +394,7 @@ static void pch_gbe_get_pauseparam(struct net_device *netdev, } /** - * pch_gbe_set_pauseparam - Set pause paramters + * pch_gbe_set_pauseparam - Set pause parameters * @netdev: Network interface device structure * @pause: Pause parameters structure * Returns: diff --git a/drivers/net/ethernet/packetengines/hamachi.c b/drivers/net/ethernet/packetengines/hamachi.c index 319d9d40f922..13d88a6025c8 100644 --- a/drivers/net/ethernet/packetengines/hamachi.c +++ b/drivers/net/ethernet/packetengines/hamachi.c @@ -350,7 +350,7 @@ V. Recent Changes incorrectly defined and corrected (as per Michel Mueller). 02/23/1999 EPK Corrected the Tx full check to check that at least 4 slots - were available before reseting the tbusy and tx_full flags + were available before resetting the tbusy and tx_full flags (as per Michel Mueller). 03/11/1999 EPK Added Pete Wyckoff's hardware checksumming support. diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h index f3346a3779d3..69f828eb42cf 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h @@ -205,7 +205,7 @@ struct qlcnic_add_rings_mbx_out { * @phys_addr_{low|high}: DMA address of the transmit buffer * @cnsmr_index_{low|high}: host consumer index * @size: legth of transmit buffer ring - * @intr_id: interrput id + * @intr_id: interrupt id * @src: src of interrupt */ struct qlcnic_tx_mbx { diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index 2bb48d57e7a5..33669c29b341 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c @@ -269,7 +269,7 @@ static int qlcnic_83xx_idc_clear_registers(struct qlcnic_adapter *adapter, } QLCWRX(adapter->ahw, QLC_83XX_IDC_DRV_ACK, 0); - /* Clear gracefull reset bit */ + /* Clear graceful reset bit */ val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL); val &= ~QLC_83XX_IDC_GRACEFULL_RESET; QLCWRX(adapter->ahw, QLC_83XX_IDC_CTRL, val); @@ -889,7 +889,7 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter) * @adapter: adapter structure * * Device will remain in this state until: - * Reset request ACK's are recieved from all the functions + * Reset request ACK's are received from all the functions * Wait time exceeds max time limit * * Returns: Error code or Success(0) diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c index 2c811f66d5ac..4a42e960d331 100644 --- a/drivers/net/ethernet/qualcomm/qca_spi.c +++ b/drivers/net/ethernet/qualcomm/qca_spi.c @@ -571,7 +571,7 @@ qcaspi_spi_thread(void *data) } /* can only handle other interrupts - * if sync has occured + * if sync has occurred */ if (qca->sync == QCASPI_SYNC_READY) { if (intr_cause & SPI_INT_PKT_AVLBL) diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c index c8a01ee4d25e..413ea14ab91f 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c @@ -422,11 +422,11 @@ static int init_tx_ring(struct device *dev, u8 queue_no, /* assign queue number */ tx_ring->queue_no = queue_no; - /* initalise counters */ + /* initialise counters */ tx_ring->dirty_tx = 0; tx_ring->cur_tx = 0; - /* initalise TX queue lock */ + /* initialise TX queue lock */ spin_lock_init(&tx_ring->tx_lock); return 0; @@ -515,7 +515,7 @@ static int init_rx_ring(struct net_device *dev, u8 queue_no, goto err_free_rx_buffers; } - /* initalise counters */ + /* initialise counters */ rx_ring->cur_rx = 0; rx_ring->dirty_rx = (unsigned int)(desc_index - rx_rsize); priv->dma_buf_sz = bfsize; @@ -837,7 +837,7 @@ static void sxgbe_restart_tx_queue(struct sxgbe_priv_data *priv, int queue_num) /* free the skbuffs of the ring */ tx_free_ring_skbufs(tx_ring); - /* initalise counters */ + /* initialise counters */ tx_ring->cur_tx = 0; tx_ring->dirty_tx = 0; @@ -1176,7 +1176,7 @@ static int sxgbe_open(struct net_device *dev) if (priv->phydev) phy_start(priv->phydev); - /* initalise TX coalesce parameters */ + /* initialise TX coalesce parameters */ sxgbe_tx_init_coalesce(priv); if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) { @@ -1721,7 +1721,7 @@ static inline u64 sxgbe_get_stat64(void __iomem *ioaddr, int reg_lo, int reg_hi) * Description: * This function is a driver entry point whenever ifconfig command gets * executed to see device statistics. Statistics are number of - * bytes sent or received, errors occured etc. + * bytes sent or received, errors occurred etc. * Return value: * This function returns various statistical information of device. */ diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 238482495e81..33d2f9aa1b53 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -3215,7 +3215,7 @@ static pci_ers_result_t efx_io_error_detected(struct pci_dev *pdev, return status; } -/* Fake a successfull reset, which will be performed later in efx_io_resume. */ +/* Fake a successful reset, which will be performed later in efx_io_resume. */ static pci_ers_result_t efx_io_slot_reset(struct pci_dev *pdev) { struct efx_nic *efx = pci_get_drvdata(pdev); diff --git a/drivers/net/ethernet/sfc/farch.c b/drivers/net/ethernet/sfc/farch.c index 75975328e020..bb89e96a125e 100644 --- a/drivers/net/ethernet/sfc/farch.c +++ b/drivers/net/ethernet/sfc/farch.c @@ -645,7 +645,7 @@ static bool efx_check_tx_flush_complete(struct efx_nic *efx) } /* Flush all the transmit queues, and continue flushing receive queues until - * they're all flushed. Wait for the DRAIN events to be recieved so that there + * they're all flushed. Wait for the DRAIN events to be received so that there * are no more RX and TX events left on any channel. */ static int efx_farch_do_flush(struct efx_nic *efx) { @@ -1108,7 +1108,7 @@ efx_farch_handle_tx_flush_done(struct efx_nic *efx, efx_qword_t *event) } /* If this flush done event corresponds to a &struct efx_rx_queue: If the flush - * was succesful then send an %EFX_CHANNEL_MAGIC_RX_DRAIN, otherwise add + * was successful then send an %EFX_CHANNEL_MAGIC_RX_DRAIN, otherwise add * the RX queue back to the mask of RX queues in need of flushing. */ static void diff --git a/drivers/net/ethernet/sfc/mcdi_pcol.h b/drivers/net/ethernet/sfc/mcdi_pcol.h index a707fb5ef14c..e028de10e1b7 100644 --- a/drivers/net/ethernet/sfc/mcdi_pcol.h +++ b/drivers/net/ethernet/sfc/mcdi_pcol.h @@ -6497,7 +6497,7 @@ #define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_LENMIN 12 #define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_LENMAX 252 #define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_LEN(num) (0+12*(num)) -/* Raw buffer table entries, layed out as BUFTBL_ENTRY. */ +/* Raw buffer table entries, laid out as BUFTBL_ENTRY. */ #define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_OFST 0 #define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_LEN 12 #define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_MINNUM 1 diff --git a/drivers/net/ethernet/sfc/siena_sriov.c b/drivers/net/ethernet/sfc/siena_sriov.c index a8bbbad68a88..fe83430796fd 100644 --- a/drivers/net/ethernet/sfc/siena_sriov.c +++ b/drivers/net/ethernet/sfc/siena_sriov.c @@ -1067,7 +1067,7 @@ void efx_siena_sriov_probe(struct efx_nic *efx) } /* Copy the list of individual addresses into the vfdi_status.peers - * array and auxillary pages, protected by %local_lock. Drop that lock + * array and auxiliary pages, protected by %local_lock. Drop that lock * and then broadcast the address list to every VF. */ static void efx_siena_sriov_peer_work(struct work_struct *data) diff --git a/drivers/net/ethernet/sfc/vfdi.h b/drivers/net/ethernet/sfc/vfdi.h index ae044f44936a..f62901d4cae0 100644 --- a/drivers/net/ethernet/sfc/vfdi.h +++ b/drivers/net/ethernet/sfc/vfdi.h @@ -98,7 +98,7 @@ struct vfdi_endpoint { * @VFDI_OP_INIT_TXQ: Initialize SRAM entries and initialize a TXQ. * @VFDI_OP_FINI_ALL_QUEUES: Flush all queues, finalize all queues, then * finalize the SRAM entries. - * @VFDI_OP_INSERT_FILTER: Insert a MAC filter targetting the given RXQ. + * @VFDI_OP_INSERT_FILTER: Insert a MAC filter targeting the given RXQ. * @VFDI_OP_REMOVE_ALL_FILTERS: Remove all filters. * @VFDI_OP_SET_STATUS_PAGE: Set the DMA page(s) used for status updates * from PF and write the initial status. @@ -148,7 +148,7 @@ enum vfdi_op { * @u.init_txq.flags: Checksum offload flags. * @u.init_txq.addr: Array of length %u.init_txq.buf_count containing DMA * address of each page backing the transmit queue. - * @u.mac_filter.rxq: Insert MAC filter at VF local address/VLAN targetting + * @u.mac_filter.rxq: Insert MAC filter at VF local address/VLAN targeting * all traffic at this receive queue. * @u.mac_filter.flags: MAC filter flags. * @u.set_status_page.dma_addr: Base address for the &struct vfdi_status. diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index a0ea84fe6519..5336594abed1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -609,7 +609,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) * where, freq_div_ratio = clk_ptp_ref_i/50MHz * hence, addend = ((2^32) * 50MHz)/clk_ptp_ref_i; * NOTE: clk_ptp_ref_i should be >= 50MHz to - * achive 20ns accuracy. + * achieve 20ns accuracy. * * 2^x * y == (y << x), hence * 2^32 * 50000000 ==> (50000000 << 32) diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c index fef5dec2cffe..74e9b148378c 100644 --- a/drivers/net/ethernet/sun/sungem.c +++ b/drivers/net/ethernet/sun/sungem.c @@ -2175,7 +2175,7 @@ static int gem_do_start(struct net_device *dev) } /* Mark us as attached again if we come from resume(), this has - * no effect if we weren't detatched and needs to be done now. + * no effect if we weren't detached and needs to be done now. */ netif_device_attach(dev); @@ -2794,7 +2794,7 @@ static void gem_remove_one(struct pci_dev *pdev) unregister_netdev(dev); - /* Ensure reset task is truely gone */ + /* Ensure reset task is truly gone */ cancel_work_sync(&gp->reset_task); /* Free resources */ diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index a1bbaf6352ba..b536b4c82752 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -726,7 +726,7 @@ static void cpsw_rx_handler(void *token, int len, int status) if (ndev_status && (status >= 0)) { /* The packet received is for the interface which * is already down and the other interface is up - * and running, intead of freeing which results + * and running, instead of freeing which results * in reducing of the number of rx descriptor in * DMA engine, requeue skb back to cpdma. */ diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_net.c b/drivers/net/ethernet/toshiba/ps3_gelic_net.c index bb7992804664..ac62a5e248b0 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_net.c +++ b/drivers/net/ethernet/toshiba/ps3_gelic_net.c @@ -1065,7 +1065,7 @@ refill: /* * this call can fail, but for now, just leave this - * decriptor without skb + * descriptor without skb */ gelic_descr_prepare_rx(card, descr); diff --git a/drivers/net/ethernet/wiznet/w5100.c b/drivers/net/ethernet/wiznet/w5100.c index a495931a66a1..f5498c26b3c7 100644 --- a/drivers/net/ethernet/wiznet/w5100.c +++ b/drivers/net/ethernet/wiznet/w5100.c @@ -56,7 +56,7 @@ MODULE_LICENSE("GPL"); #define W5100_S0_REGS 0x0400 #define W5100_S0_MR 0x0400 /* S0 Mode Register */ -#define S0_MR_MACRAW 0x04 /* MAC RAW mode (promiscous) */ +#define S0_MR_MACRAW 0x04 /* MAC RAW mode (promiscuous) */ #define S0_MR_MACRAW_MF 0x44 /* MAC RAW mode (filtered) */ #define W5100_S0_CR 0x0401 /* S0 Command Register */ #define S0_CR_OPEN 0x01 /* OPEN command */ diff --git a/drivers/net/ethernet/wiznet/w5300.c b/drivers/net/ethernet/wiznet/w5300.c index 09322d9db578..ca0c631ed628 100644 --- a/drivers/net/ethernet/wiznet/w5300.c +++ b/drivers/net/ethernet/wiznet/w5300.c @@ -63,7 +63,7 @@ MODULE_LICENSE("GPL"); #define IDR_W5300 0x5300 /* =0x5300 for WIZnet W5300 */ #define W5300_S0_MR 0x0200 /* S0 Mode Register */ #define S0_MR_CLOSED 0x0000 /* Close mode */ -#define S0_MR_MACRAW 0x0004 /* MAC RAW mode (promiscous) */ +#define S0_MR_MACRAW 0x0004 /* MAC RAW mode (promiscuous) */ #define S0_MR_MACRAW_MF 0x0044 /* MAC RAW mode (filtered) */ #define W5300_S0_CR 0x0202 /* S0 Command Register */ #define S0_CR_OPEN 0x0001 /* OPEN command */ -- cgit v1.2.3 From 8edfe3b6fad28da191c8fa15e4e0d8f7335a0091 Mon Sep 17 00:00:00 2001 From: Peter Senna Tschudin Date: Sat, 7 Mar 2015 12:10:26 +0100 Subject: bgmac: Clean warning messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On my test environment the throughput of a file transfer drops from 4.4MBps to 116KBps due the number of repeated warning messages. This patch removes the warning messages as DMA works correctly with addresses using 0xC0000000 bits. Signed-off-by: Peter Senna Tschudin Acked-by: Rafał Miłecki Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 676ffe093180..0469f72c6e7e 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -302,9 +302,6 @@ static int bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac, slot->skb = skb; slot->dma_addr = dma_addr; - if (slot->dma_addr & 0xC0000000) - bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n"); - return 0; } @@ -505,8 +502,6 @@ static int bgmac_dma_alloc(struct bgmac *bgmac) ring->mmio_base); goto err_dma_free; } - if (ring->dma_base & 0xC0000000) - bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n"); ring->unaligned = bgmac_dma_unaligned(bgmac, ring, BGMAC_DMA_RING_TX); @@ -536,8 +531,6 @@ static int bgmac_dma_alloc(struct bgmac *bgmac) err = -ENOMEM; goto err_dma_free; } - if (ring->dma_base & 0xC0000000) - bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n"); ring->unaligned = bgmac_dma_unaligned(bgmac, ring, BGMAC_DMA_RING_RX); -- cgit v1.2.3 From 8ac467e837a24eb024177b4b01013d8e6764913a Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Mon, 9 Mar 2015 13:40:00 -0700 Subject: net: bcmgenet: core changes for supporting multiple Rx queues 1. Add struct bcmgenet_rx_ring to hold all necessary information for a single Rx queue. 2. Add bcmgenet_init_rx_queues() to initialize all Rx queues. 3. Modify bcmgenet_init_rx_ring() to initialize a single Rx queue. 4. Modify Rx interrupt path code to use per-queue data. 5. Modify bcmgenet_rx_refill() to use RxCB->bd_addr. Signed-off-by: Petri Gynther Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 156 +++++++++++++++++-------- drivers/net/ethernet/broadcom/genet/bcmgenet.h | 16 ++- 2 files changed, 119 insertions(+), 53 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 83c0cb323e0c..275be56fd324 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1363,16 +1363,7 @@ static int bcmgenet_rx_refill(struct bcmgenet_priv *priv, struct enet_cb *cb) } dma_unmap_addr_set(cb, dma_addr, mapping); - /* assign packet, prepare descriptor, and advance pointer */ - - dmadesc_set_addr(priv, priv->rx_bd_assign_ptr, mapping); - - /* turn on the newly assigned BD for DMA to use */ - priv->rx_bd_assign_index++; - priv->rx_bd_assign_index &= (priv->num_rx_bds - 1); - - priv->rx_bd_assign_ptr = priv->rx_bds + - (priv->rx_bd_assign_index * DMA_DESC_SIZE); + dmadesc_set_addr(priv, cb->bd_addr, mapping); return 0; } @@ -1381,8 +1372,10 @@ static int bcmgenet_rx_refill(struct bcmgenet_priv *priv, struct enet_cb *cb) * this could be called from bottom half, or from NAPI polling method. */ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, + unsigned int index, unsigned int budget) { + struct bcmgenet_rx_ring *ring = &priv->rx_rings[index]; struct net_device *dev = priv->dev; struct enet_cb *cb; struct sk_buff *skb; @@ -1393,21 +1386,21 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, unsigned int p_index; unsigned int chksum_ok = 0; - p_index = bcmgenet_rdma_ring_readl(priv, DESC_INDEX, RDMA_PROD_INDEX); + p_index = bcmgenet_rdma_ring_readl(priv, index, RDMA_PROD_INDEX); p_index &= DMA_P_INDEX_MASK; - if (p_index < priv->rx_c_index) - rxpkttoprocess = (DMA_C_INDEX_MASK + 1) - - priv->rx_c_index + p_index; + if (likely(p_index >= ring->c_index)) + rxpkttoprocess = p_index - ring->c_index; else - rxpkttoprocess = p_index - priv->rx_c_index; + rxpkttoprocess = (DMA_C_INDEX_MASK + 1) - ring->c_index + + p_index; netif_dbg(priv, rx_status, dev, "RDMA: rxpkttoprocess=%d\n", rxpkttoprocess); while ((rxpktprocessed < rxpkttoprocess) && (rxpktprocessed < budget)) { - cb = &priv->rx_cbs[priv->rx_read_ptr]; + cb = &priv->rx_cbs[ring->read_ptr]; skb = cb->skb; /* We do not have a backing SKB, so we do not have a @@ -1430,10 +1423,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, if (!priv->desc_64b_en) { dma_length_status = - dmadesc_get_length_status(priv, - priv->rx_bds + - (priv->rx_read_ptr * - DMA_DESC_SIZE)); + dmadesc_get_length_status(priv, cb->bd_addr); } else { struct status_64 *status; @@ -1449,8 +1439,8 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, netif_dbg(priv, rx_status, dev, "%s:p_ind=%d c_ind=%d read_ptr=%d len_stat=0x%08x\n", - __func__, p_index, priv->rx_c_index, - priv->rx_read_ptr, dma_length_status); + __func__, p_index, ring->c_index, + ring->read_ptr, dma_length_status); if (unlikely(!(dma_flag & DMA_EOP) || !(dma_flag & DMA_SOP))) { netif_err(priv, rx_status, dev, @@ -1528,25 +1518,31 @@ refill: } rxpktprocessed++; - priv->rx_read_ptr++; - priv->rx_read_ptr &= (priv->num_rx_bds - 1); + if (likely(ring->read_ptr < ring->end_ptr)) + ring->read_ptr++; + else + ring->read_ptr = ring->cb_ptr; + + ring->c_index = (ring->c_index + 1) & DMA_C_INDEX_MASK; + bcmgenet_rdma_ring_writel(priv, index, ring->c_index, RDMA_CONS_INDEX); } return rxpktprocessed; } /* Assign skb to RX DMA descriptor. */ -static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv) +static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv, + struct bcmgenet_rx_ring *ring) { struct enet_cb *cb; int ret = 0; int i; - netif_dbg(priv, hw, priv->dev, "%s:\n", __func__); + netif_dbg(priv, hw, priv->dev, "%s\n", __func__); /* loop here for each buffer needing assign */ - for (i = 0; i < priv->num_rx_bds; i++) { - cb = &priv->rx_cbs[priv->rx_bd_assign_index]; + for (i = 0; i < ring->size; i++) { + cb = ring->cbs + i; if (cb->skb) continue; @@ -1778,20 +1774,24 @@ static void bcmgenet_fini_tx_ring(struct bcmgenet_priv *priv, /* Initialize a RDMA ring */ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv, - unsigned int index, unsigned int size) + unsigned int index, unsigned int size, + unsigned int start_ptr, unsigned int end_ptr) { + struct bcmgenet_rx_ring *ring = &priv->rx_rings[index]; u32 words_per_bd = WORDS_PER_BD(priv); int ret; - priv->rx_bd_assign_ptr = priv->rx_bds; - priv->rx_bd_assign_index = 0; - priv->rx_c_index = 0; - priv->rx_read_ptr = 0; + ring->index = index; + ring->cbs = priv->rx_cbs + start_ptr; + ring->size = size; + ring->c_index = 0; + ring->read_ptr = start_ptr; + ring->cb_ptr = start_ptr; + ring->end_ptr = end_ptr - 1; - ret = bcmgenet_alloc_rx_buffers(priv); - if (ret) { + ret = bcmgenet_alloc_rx_buffers(priv, ring); + if (ret) return ret; - } bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_PROD_INDEX); bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_CONS_INDEX); @@ -1805,10 +1805,13 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv, DMA_FC_THRESH_HI, RDMA_XON_XOFF_THRESH); /* Set start and end address, read and write pointers */ - bcmgenet_rdma_ring_writel(priv, index, 0, DMA_START_ADDR); - bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_READ_PTR); - bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_WRITE_PTR); - bcmgenet_rdma_ring_writel(priv, index, words_per_bd * size - 1, + bcmgenet_rdma_ring_writel(priv, index, start_ptr * words_per_bd, + DMA_START_ADDR); + bcmgenet_rdma_ring_writel(priv, index, start_ptr * words_per_bd, + RDMA_READ_PTR); + bcmgenet_rdma_ring_writel(priv, index, start_ptr * words_per_bd, + RDMA_WRITE_PTR); + bcmgenet_rdma_ring_writel(priv, index, end_ptr * words_per_bd - 1, DMA_END_ADDR); return ret; @@ -1883,6 +1886,66 @@ static void bcmgenet_init_tx_queues(struct net_device *dev) bcmgenet_tdma_writel(priv, dma_ctrl, DMA_CTRL); } +/* Initialize Rx queues + * + * Queues 0-15 are priority queues. Hardware Filtering Block (HFB) can be + * used to direct traffic to these queues. + * + * Queue 16 is the default Rx queue with GENET_Q16_RX_BD_CNT descriptors. + */ +static int bcmgenet_init_rx_queues(struct net_device *dev) +{ + struct bcmgenet_priv *priv = netdev_priv(dev); + u32 i; + u32 dma_enable; + u32 dma_ctrl; + u32 ring_cfg; + int ret; + + dma_ctrl = bcmgenet_rdma_readl(priv, DMA_CTRL); + dma_enable = dma_ctrl & DMA_EN; + dma_ctrl &= ~DMA_EN; + bcmgenet_rdma_writel(priv, dma_ctrl, DMA_CTRL); + + dma_ctrl = 0; + ring_cfg = 0; + + /* Initialize Rx priority queues */ + for (i = 0; i < priv->hw_params->rx_queues; i++) { + ret = bcmgenet_init_rx_ring(priv, i, + priv->hw_params->rx_bds_per_q, + i * priv->hw_params->rx_bds_per_q, + (i + 1) * + priv->hw_params->rx_bds_per_q); + if (ret) + return ret; + + ring_cfg |= (1 << i); + dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT)); + } + + /* Initialize Rx default queue 16 */ + ret = bcmgenet_init_rx_ring(priv, DESC_INDEX, GENET_Q16_RX_BD_CNT, + priv->hw_params->rx_queues * + priv->hw_params->rx_bds_per_q, + TOTAL_DESC); + if (ret) + return ret; + + ring_cfg |= (1 << DESC_INDEX); + dma_ctrl |= (1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT)); + + /* Enable rings */ + bcmgenet_rdma_writel(priv, ring_cfg, DMA_RING_CFG); + + /* Configure ring as descriptor ring and re-enable DMA if enabled */ + if (dma_enable) + dma_ctrl |= DMA_EN; + bcmgenet_rdma_writel(priv, dma_ctrl, DMA_CTRL); + + return 0; +} + static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv) { int ret = 0; @@ -1990,10 +2053,10 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv) cb->bd_addr = priv->rx_bds + i * DMA_DESC_SIZE; } - /* Initialize Rx default queue 16 */ - ret = bcmgenet_init_rx_ring(priv, DESC_INDEX, TOTAL_DESC); + /* Initialize Rx queues */ + ret = bcmgenet_init_rx_queues(priv->dev); if (ret) { - netdev_err(priv->dev, "failed to initialize RX ring\n"); + netdev_err(priv->dev, "failed to initialize Rx queues\n"); bcmgenet_free_rx_buffers(priv); kfree(priv->rx_cbs); return ret; @@ -2030,13 +2093,8 @@ static int bcmgenet_poll(struct napi_struct *napi, int budget) struct bcmgenet_priv, napi); unsigned int work_done; - work_done = bcmgenet_desc_rx(priv, budget); + work_done = bcmgenet_desc_rx(priv, DESC_INDEX, budget); - /* Advancing our consumer index*/ - priv->rx_c_index += work_done; - priv->rx_c_index &= DMA_C_INDEX_MASK; - bcmgenet_rdma_ring_writel(priv, DESC_INDEX, - priv->rx_c_index, RDMA_CONS_INDEX); if (work_done < budget) { napi_complete(napi); bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_RXDMA_BDONE, diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 5684e8529ecc..17443db8dc53 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -540,6 +540,16 @@ struct bcmgenet_tx_ring { struct bcmgenet_priv *priv; }; +struct bcmgenet_rx_ring { + unsigned int index; /* Rx ring index */ + struct enet_cb *cbs; /* Rx ring buffer control block */ + unsigned int size; /* Rx ring size */ + unsigned int c_index; /* Rx last consumer index */ + unsigned int read_ptr; /* Rx ring read pointer */ + unsigned int cb_ptr; /* Rx ring initial CB ptr */ + unsigned int end_ptr; /* Rx ring end CB ptr */ +}; + /* device context */ struct bcmgenet_priv { void __iomem *base; @@ -560,13 +570,11 @@ struct bcmgenet_priv { /* receive variables */ void __iomem *rx_bds; - void __iomem *rx_bd_assign_ptr; - int rx_bd_assign_index; struct enet_cb *rx_cbs; unsigned int num_rx_bds; unsigned int rx_buf_len; - unsigned int rx_read_ptr; - unsigned int rx_c_index; + + struct bcmgenet_rx_ring rx_rings[DESC_INDEX + 1]; /* other misc variables */ struct bcmgenet_hw_params *hw_params; -- cgit v1.2.3 From d26ea6cc48da5a97d8188220c334cf3669fa8dc7 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Tue, 10 Mar 2015 15:55:00 -0700 Subject: net: bcmgenet: collect Rx discarded packet count Bits 31:16 of RDMA_PROD_INDEX contain Rx discarded packet count, which are the Rx packets that had to be dropped by MAC hardware since there was no room on the Rx queue. Add code to collect this information into the netdev stats. Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 18 ++++++++++++++++++ drivers/net/ethernet/broadcom/genet/bcmgenet.h | 1 + 2 files changed, 19 insertions(+) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 275be56fd324..d3be1aeb7f47 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1384,9 +1384,27 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, int len, err; unsigned int rxpktprocessed = 0, rxpkttoprocess; unsigned int p_index; + unsigned int discards; unsigned int chksum_ok = 0; p_index = bcmgenet_rdma_ring_readl(priv, index, RDMA_PROD_INDEX); + + discards = (p_index >> DMA_P_INDEX_DISCARD_CNT_SHIFT) & + DMA_P_INDEX_DISCARD_CNT_MASK; + if (discards > ring->old_discards) { + discards = discards - ring->old_discards; + dev->stats.rx_missed_errors += discards; + dev->stats.rx_errors += discards; + ring->old_discards += discards; + + /* Clear HW register when we reach 75% of maximum 0xFFFF */ + if (ring->old_discards >= 0xC000) { + ring->old_discards = 0; + bcmgenet_rdma_ring_writel(priv, index, 0, + RDMA_PROD_INDEX); + } + } + p_index &= DMA_P_INDEX_MASK; if (likely(p_index >= ring->c_index)) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 17443db8dc53..2a8113898aed 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -548,6 +548,7 @@ struct bcmgenet_rx_ring { unsigned int read_ptr; /* Rx ring read pointer */ unsigned int cb_ptr; /* Rx ring initial CB ptr */ unsigned int end_ptr; /* Rx ring end CB ptr */ + unsigned int old_discards; }; /* device context */ -- cgit v1.2.3 From d6707bec598649450ee0887bf11896e525777874 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Thu, 12 Mar 2015 15:48:00 -0700 Subject: net: bcmgenet: rewrite bcmgenet_rx_refill() Currently, bcmgenet_desc_rx() calls bcmgenet_rx_refill() at the end of Rx packet processing loop, after the current Rx packet has already been passed to napi_gro_receive(). However, bcmgenet_rx_refill() might fail to allocate a new Rx skb, thus leaving a hole on the Rx queue where no valid Rx buffer exists. To eliminate this situation: 1. Rewrite bcmgenet_rx_refill() to retain the current Rx skb on the Rx queue if a new replacement Rx skb can't be allocated and DMA-mapped. In this case, the data on the current Rx skb is effectively dropped. 2. Modify bcmgenet_desc_rx() to call bcmgenet_rx_refill() at the top of Rx packet processing loop, so that the new replacement Rx skb is already in place before the current Rx skb is processed. Signed-off-by: Petri Gynther Tested-by: Jaedon Shin -- Reviewed-by: Florian Fainelli Tested-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 99 +++++++++++--------------- 1 file changed, 43 insertions(+), 56 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index d3be1aeb7f47..875967e8d719 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1336,36 +1336,47 @@ out: return ret; } - -static int bcmgenet_rx_refill(struct bcmgenet_priv *priv, struct enet_cb *cb) +static struct sk_buff *bcmgenet_rx_refill(struct bcmgenet_priv *priv, + struct enet_cb *cb) { struct device *kdev = &priv->pdev->dev; struct sk_buff *skb; + struct sk_buff *rx_skb; dma_addr_t mapping; - int ret; + /* Allocate a new Rx skb */ skb = netdev_alloc_skb(priv->dev, priv->rx_buf_len + SKB_ALIGNMENT); - if (!skb) - return -ENOMEM; + if (!skb) { + priv->mib.alloc_rx_buff_failed++; + netif_err(priv, rx_err, priv->dev, + "%s: Rx skb allocation failed\n", __func__); + return NULL; + } - /* a caller did not release this control block */ - WARN_ON(cb->skb != NULL); - cb->skb = skb; - mapping = dma_map_single(kdev, skb->data, - priv->rx_buf_len, DMA_FROM_DEVICE); - ret = dma_mapping_error(kdev, mapping); - if (ret) { + /* DMA-map the new Rx skb */ + mapping = dma_map_single(kdev, skb->data, priv->rx_buf_len, + DMA_FROM_DEVICE); + if (dma_mapping_error(kdev, mapping)) { priv->mib.rx_dma_failed++; - bcmgenet_free_cb(cb); + dev_kfree_skb_any(skb); netif_err(priv, rx_err, priv->dev, - "%s DMA map failed\n", __func__); - return ret; + "%s: Rx skb DMA mapping failed\n", __func__); + return NULL; } + /* Grab the current Rx skb from the ring and DMA-unmap it */ + rx_skb = cb->skb; + if (likely(rx_skb)) + dma_unmap_single(kdev, dma_unmap_addr(cb, dma_addr), + priv->rx_buf_len, DMA_FROM_DEVICE); + + /* Put the new Rx skb on the ring */ + cb->skb = skb; dma_unmap_addr_set(cb, dma_addr, mapping); dmadesc_set_addr(priv, cb->bd_addr, mapping); - return 0; + /* Return the current Rx skb to caller */ + return rx_skb; } /* bcmgenet_desc_rx - descriptor based rx process. @@ -1381,7 +1392,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, struct sk_buff *skb; u32 dma_length_status; unsigned long dma_flag; - int len, err; + int len; unsigned int rxpktprocessed = 0, rxpkttoprocess; unsigned int p_index; unsigned int discards; @@ -1419,26 +1430,14 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, while ((rxpktprocessed < rxpkttoprocess) && (rxpktprocessed < budget)) { cb = &priv->rx_cbs[ring->read_ptr]; - skb = cb->skb; + skb = bcmgenet_rx_refill(priv, cb); - /* We do not have a backing SKB, so we do not have a - * corresponding DMA mapping for this incoming packet since - * bcmgenet_rx_refill always either has both skb and mapping or - * none. - */ if (unlikely(!skb)) { dev->stats.rx_dropped++; dev->stats.rx_errors++; - goto refill; + goto next; } - /* Unmap the packet contents such that we can use the - * RSV from the 64 bytes descriptor when enabled and save - * a 32-bits register read - */ - dma_unmap_single(&dev->dev, dma_unmap_addr(cb, dma_addr), - priv->rx_buf_len, DMA_FROM_DEVICE); - if (!priv->desc_64b_en) { dma_length_status = dmadesc_get_length_status(priv, cb->bd_addr); @@ -1465,10 +1464,10 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, "dropping fragmented packet!\n"); dev->stats.rx_dropped++; dev->stats.rx_errors++; - dev_kfree_skb_any(cb->skb); - cb->skb = NULL; - goto refill; + dev_kfree_skb_any(skb); + goto next; } + /* report errors */ if (unlikely(dma_flag & (DMA_RX_CRC_ERROR | DMA_RX_OV | @@ -1487,11 +1486,8 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, dev->stats.rx_length_errors++; dev->stats.rx_dropped++; dev->stats.rx_errors++; - - /* discard the packet and advance consumer index.*/ - dev_kfree_skb_any(cb->skb); - cb->skb = NULL; - goto refill; + dev_kfree_skb_any(skb); + goto next; } /* error packet */ chksum_ok = (dma_flag & priv->dma_rx_chk_bit) && @@ -1524,17 +1520,9 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, /* Notify kernel */ napi_gro_receive(&priv->napi, skb); - cb->skb = NULL; netif_dbg(priv, rx_status, dev, "pushed up to kernel\n"); - /* refill RX path on the current control block */ -refill: - err = bcmgenet_rx_refill(priv, cb); - if (err) { - priv->mib.alloc_rx_buff_failed++; - netif_err(priv, rx_err, dev, "Rx refill failed\n"); - } - +next: rxpktprocessed++; if (likely(ring->read_ptr < ring->end_ptr)) ring->read_ptr++; @@ -1553,7 +1541,7 @@ static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv, struct bcmgenet_rx_ring *ring) { struct enet_cb *cb; - int ret = 0; + struct sk_buff *skb; int i; netif_dbg(priv, hw, priv->dev, "%s\n", __func__); @@ -1561,15 +1549,14 @@ static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv, /* loop here for each buffer needing assign */ for (i = 0; i < ring->size; i++) { cb = ring->cbs + i; - if (cb->skb) - continue; - - ret = bcmgenet_rx_refill(priv, cb); - if (ret) - break; + skb = bcmgenet_rx_refill(priv, cb); + if (skb) + dev_kfree_skb_any(skb); + if (!cb->skb) + return -ENOMEM; } - return ret; + return 0; } static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv) -- cgit v1.2.3 From ae67bf0188cbb9d1786bdfcca9e1976cb36ee327 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 13 Mar 2015 12:11:06 -0700 Subject: net: bcmgenet: update ring producer index and buffer count in xmit There is no need to have both bcmgenet_xmit_single() and bcmgenet_xmit_frag() perform a free_bds decrement and a prod_index increment by one. In case one of these functions fails to map a SKB or fragment for transmit, we will return and exit bcmgenet_xmit() with an error. We can therefore safely use our local copy of nr_frags to know by how much we should decrement the number of free buffers available, and by how much the producer count must be incremented and do this in the tail of bcmgenet_xmit(). Signed-off-by: Florian Fainelli Acked-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 875967e8d719..53c916ea06a2 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1130,11 +1130,6 @@ static int bcmgenet_xmit_single(struct net_device *dev, dmadesc_set(priv, tx_cb_ptr->bd_addr, mapping, length_status); - /* Decrement total BD count and advance our write pointer */ - ring->free_bds -= 1; - ring->prod_index += 1; - ring->prod_index &= DMA_P_INDEX_MASK; - return 0; } @@ -1173,11 +1168,6 @@ static int bcmgenet_xmit_frag(struct net_device *dev, (frag->size << DMA_BUFLENGTH_SHIFT) | dma_desc_flags | (priv->hw_params->qtag_mask << DMA_TX_QTAG_SHIFT)); - - ring->free_bds -= 1; - ring->prod_index += 1; - ring->prod_index &= DMA_P_INDEX_MASK; - return 0; } @@ -1321,9 +1311,11 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) skb_tx_timestamp(skb); - /* we kept a software copy of how much we should advance the TDMA - * producer index, now write it down to the hardware - */ + /* Decrement total BD count and advance our write pointer */ + ring->free_bds -= nr_frags + 1; + ring->prod_index += nr_frags + 1; + ring->prod_index &= DMA_P_INDEX_MASK; + bcmgenet_tdma_ring_writel(priv, ring->index, ring->prod_index, TDMA_PROD_INDEX); -- cgit v1.2.3 From ddd0ca5d60b350bbfbfb60b25885a9779ce6d6c7 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 13 Mar 2015 12:11:07 -0700 Subject: net: bcmgenet: add support for xmit_more Delay the update of the TDMA producer index unless this is the last SKB in a batch, or the queue is already stopped. Move the check for whether the queue should be stopped before the xmit_more check to avoid locking the transmit queue in case there was a SKB submitted which has xmit_more set. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 53c916ea06a2..e74ae628bbb9 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1316,12 +1316,13 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) ring->prod_index += nr_frags + 1; ring->prod_index &= DMA_P_INDEX_MASK; - bcmgenet_tdma_ring_writel(priv, ring->index, - ring->prod_index, TDMA_PROD_INDEX); - if (ring->free_bds <= (MAX_SKB_FRAGS + 1)) netif_tx_stop_queue(txq); + if (!skb->xmit_more || netif_xmit_stopped(txq)) + /* Packets are ready, update producer index */ + bcmgenet_tdma_ring_writel(priv, ring->index, + ring->prod_index, TDMA_PROD_INDEX); out: spin_unlock_irqrestore(&ring->lock, flags); -- cgit v1.2.3 From 0034de4193e4aad30bbbef4e74ca5e0631ba08a7 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Fri, 13 Mar 2015 14:45:00 -0700 Subject: net: bcmgenet: add support for Hardware Filter Block Add support for Hardware Filter Block (HFB) so that incoming Rx traffic can be matched and directed to desired Rx queues. Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 175 +++++++++++++++++++++++++ drivers/net/ethernet/broadcom/genet/bcmgenet.h | 1 + 2 files changed, 176 insertions(+) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index e74ae628bbb9..12956b143b11 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -197,6 +197,14 @@ enum dma_reg { DMA_PRIORITY_0, DMA_PRIORITY_1, DMA_PRIORITY_2, + DMA_INDEX2RING_0, + DMA_INDEX2RING_1, + DMA_INDEX2RING_2, + DMA_INDEX2RING_3, + DMA_INDEX2RING_4, + DMA_INDEX2RING_5, + DMA_INDEX2RING_6, + DMA_INDEX2RING_7, }; static const u8 bcmgenet_dma_regs_v3plus[] = { @@ -208,6 +216,14 @@ static const u8 bcmgenet_dma_regs_v3plus[] = { [DMA_PRIORITY_0] = 0x30, [DMA_PRIORITY_1] = 0x34, [DMA_PRIORITY_2] = 0x38, + [DMA_INDEX2RING_0] = 0x70, + [DMA_INDEX2RING_1] = 0x74, + [DMA_INDEX2RING_2] = 0x78, + [DMA_INDEX2RING_3] = 0x7C, + [DMA_INDEX2RING_4] = 0x80, + [DMA_INDEX2RING_5] = 0x84, + [DMA_INDEX2RING_6] = 0x88, + [DMA_INDEX2RING_7] = 0x8C, }; static const u8 bcmgenet_dma_regs_v2[] = { @@ -2283,6 +2299,160 @@ static void bcmgenet_enable_dma(struct bcmgenet_priv *priv, u32 dma_ctrl) bcmgenet_tdma_writel(priv, reg, DMA_CTRL); } +static bool bcmgenet_hfb_is_filter_enabled(struct bcmgenet_priv *priv, + u32 f_index) +{ + u32 offset; + u32 reg; + + offset = HFB_FLT_ENABLE_V3PLUS + (f_index < 32) * sizeof(u32); + reg = bcmgenet_hfb_reg_readl(priv, offset); + return !!(reg & (1 << (f_index % 32))); +} + +static void bcmgenet_hfb_enable_filter(struct bcmgenet_priv *priv, u32 f_index) +{ + u32 offset; + u32 reg; + + offset = HFB_FLT_ENABLE_V3PLUS + (f_index < 32) * sizeof(u32); + reg = bcmgenet_hfb_reg_readl(priv, offset); + reg |= (1 << (f_index % 32)); + bcmgenet_hfb_reg_writel(priv, reg, offset); +} + +static void bcmgenet_hfb_set_filter_rx_queue_mapping(struct bcmgenet_priv *priv, + u32 f_index, u32 rx_queue) +{ + u32 offset; + u32 reg; + + offset = f_index / 8; + reg = bcmgenet_rdma_readl(priv, DMA_INDEX2RING_0 + offset); + reg &= ~(0xF << (4 * (f_index % 8))); + reg |= ((rx_queue & 0xF) << (4 * (f_index % 8))); + bcmgenet_rdma_writel(priv, reg, DMA_INDEX2RING_0 + offset); +} + +static void bcmgenet_hfb_set_filter_length(struct bcmgenet_priv *priv, + u32 f_index, u32 f_length) +{ + u32 offset; + u32 reg; + + offset = HFB_FLT_LEN_V3PLUS + + ((priv->hw_params->hfb_filter_cnt - 1 - f_index) / 4) * + sizeof(u32); + reg = bcmgenet_hfb_reg_readl(priv, offset); + reg &= ~(0xFF << (8 * (f_index % 4))); + reg |= ((f_length & 0xFF) << (8 * (f_index % 4))); + bcmgenet_hfb_reg_writel(priv, reg, offset); +} + +static int bcmgenet_hfb_find_unused_filter(struct bcmgenet_priv *priv) +{ + u32 f_index; + + for (f_index = 0; f_index < priv->hw_params->hfb_filter_cnt; f_index++) + if (!bcmgenet_hfb_is_filter_enabled(priv, f_index)) + return f_index; + + return -ENOMEM; +} + +/* bcmgenet_hfb_add_filter + * + * Add new filter to Hardware Filter Block to match and direct Rx traffic to + * desired Rx queue. + * + * f_data is an array of unsigned 32-bit integers where each 32-bit integer + * provides filter data for 2 bytes (4 nibbles) of Rx frame: + * + * bits 31:20 - unused + * bit 19 - nibble 0 match enable + * bit 18 - nibble 1 match enable + * bit 17 - nibble 2 match enable + * bit 16 - nibble 3 match enable + * bits 15:12 - nibble 0 data + * bits 11:8 - nibble 1 data + * bits 7:4 - nibble 2 data + * bits 3:0 - nibble 3 data + * + * Example: + * In order to match: + * - Ethernet frame type = 0x0800 (IP) + * - IP version field = 4 + * - IP protocol field = 0x11 (UDP) + * + * The following filter is needed: + * u32 hfb_filter_ipv4_udp[] = { + * Rx frame offset 0x00: 0x00000000, 0x00000000, 0x00000000, 0x00000000, + * Rx frame offset 0x08: 0x00000000, 0x00000000, 0x000F0800, 0x00084000, + * Rx frame offset 0x10: 0x00000000, 0x00000000, 0x00000000, 0x00030011, + * }; + * + * To add the filter to HFB and direct the traffic to Rx queue 0, call: + * bcmgenet_hfb_add_filter(priv, hfb_filter_ipv4_udp, + * ARRAY_SIZE(hfb_filter_ipv4_udp), 0); + */ +int bcmgenet_hfb_add_filter(struct bcmgenet_priv *priv, u32 *f_data, + u32 f_length, u32 rx_queue) +{ + int f_index; + u32 i; + + f_index = bcmgenet_hfb_find_unused_filter(priv); + if (f_index < 0) + return -ENOMEM; + + if (f_length > priv->hw_params->hfb_filter_size) + return -EINVAL; + + for (i = 0; i < f_length; i++) + bcmgenet_hfb_writel(priv, f_data[i], + (f_index * priv->hw_params->hfb_filter_size + i) * + sizeof(u32)); + + bcmgenet_hfb_set_filter_length(priv, f_index, 2 * f_length); + bcmgenet_hfb_set_filter_rx_queue_mapping(priv, f_index, rx_queue); + bcmgenet_hfb_enable_filter(priv, f_index); + bcmgenet_hfb_reg_writel(priv, 0x1, HFB_CTRL); + + return 0; +} + +/* bcmgenet_hfb_clear + * + * Clear Hardware Filter Block and disable all filtering. + */ +static void bcmgenet_hfb_clear(struct bcmgenet_priv *priv) +{ + u32 i; + + bcmgenet_hfb_reg_writel(priv, 0x0, HFB_CTRL); + bcmgenet_hfb_reg_writel(priv, 0x0, HFB_FLT_ENABLE_V3PLUS); + bcmgenet_hfb_reg_writel(priv, 0x0, HFB_FLT_ENABLE_V3PLUS + 4); + + for (i = DMA_INDEX2RING_0; i <= DMA_INDEX2RING_7; i++) + bcmgenet_rdma_writel(priv, 0x0, i); + + for (i = 0; i < (priv->hw_params->hfb_filter_cnt / 4); i++) + bcmgenet_hfb_reg_writel(priv, 0x0, + HFB_FLT_LEN_V3PLUS + i * sizeof(u32)); + + for (i = 0; i < priv->hw_params->hfb_filter_cnt * + priv->hw_params->hfb_filter_size; i++) + bcmgenet_hfb_writel(priv, 0x0, i * sizeof(u32)); +} + +static void bcmgenet_hfb_init(struct bcmgenet_priv *priv) +{ + if (GENET_IS_V1(priv) || GENET_IS_V2(priv)) + return; + + bcmgenet_hfb_clear(priv); +} + static void bcmgenet_netif_start(struct net_device *dev) { struct bcmgenet_priv *priv = netdev_priv(dev); @@ -2348,6 +2518,9 @@ static int bcmgenet_open(struct net_device *dev) /* Always enable ring 16 - descriptor ring */ bcmgenet_enable_dma(priv, dma_ctrl); + /* HFB init */ + bcmgenet_hfb_init(priv); + ret = request_irq(priv->irq0, bcmgenet_isr0, IRQF_SHARED, dev->name, priv); if (ret < 0) { @@ -2592,6 +2765,7 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { .bp_in_en_shift = 17, .bp_in_mask = 0x1ffff, .hfb_filter_cnt = 48, + .hfb_filter_size = 128, .qtag_mask = 0x3F, .tbuf_offset = 0x0600, .hfb_offset = 0x8000, @@ -2609,6 +2783,7 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { .bp_in_en_shift = 17, .bp_in_mask = 0x1ffff, .hfb_filter_cnt = 48, + .hfb_filter_size = 128, .qtag_mask = 0x3F, .tbuf_offset = 0x0600, .hfb_offset = 0x8000, diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 2a8113898aed..1ea838946318 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -509,6 +509,7 @@ struct bcmgenet_hw_params { u8 bp_in_en_shift; u32 bp_in_mask; u8 hfb_filter_cnt; + u8 hfb_filter_size; u8 qtag_mask; u16 tbuf_offset; u32 hfb_offset; -- cgit v1.2.3 From a8e0c246dacfb0558e801ab81af3f670056fd1b2 Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Mon, 16 Mar 2015 16:15:59 +0100 Subject: bnx2x: fix encapsulation features on 57710/57711 E1x chips (57710, 57711(E)) have no support for encapsulation offload. bnx2x incorrectly advertises the support as available. Setting of those features is conditional on "!CHIP_IS_E1x(bp)", but the bp struct is not initialized yet at this point and consequently any chip passes the check. The check must use the "chip_is_e1x" local variable instead to work correctly. Signed-off-by: Michal Schmidt Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index bef750a09027..996e215fc324 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -12769,7 +12769,7 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev, NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_GRO | NETIF_F_RXHASH | NETIF_F_HW_VLAN_CTAG_TX; - if (!CHIP_IS_E1x(bp)) { + if (!chip_is_e1x) { dev->hw_features |= NETIF_F_GSO_GRE | NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_IPIP | NETIF_F_GSO_SIT; dev->hw_enc_features = -- cgit v1.2.3 From c25b23b8a387e7d31f7a74af8e37b61e9e6ebb21 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Fri, 20 Mar 2015 23:14:31 +0100 Subject: bgmac: register fixed PHY for ARM BCM470X / BCM5301X chipsets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On ARM SoCs with bgmac Ethernet hardware we don't have any normal PHY. There is always a switch attached but it's not even controlled over MDIO like in case of MIPS devices. We need a fixed PHY to be able to send/receive packets from the switch. Signed-off-by: Rafał Miłecki Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 0469f72c6e7e..efda7cf82394 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -1330,13 +1331,46 @@ static void bgmac_adjust_link(struct net_device *net_dev) } } +static int bgmac_fixed_phy_register(struct bgmac *bgmac) +{ + struct fixed_phy_status fphy_status = { + .link = 1, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, + }; + struct phy_device *phy_dev; + int err; + + phy_dev = fixed_phy_register(PHY_POLL, &fphy_status, NULL); + if (!phy_dev || IS_ERR(phy_dev)) { + bgmac_err(bgmac, "Failed to register fixed PHY device\n"); + return -ENODEV; + } + + err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link, + PHY_INTERFACE_MODE_MII); + if (err) { + bgmac_err(bgmac, "Connecting PHY failed\n"); + return err; + } + + bgmac->phy_dev = phy_dev; + + return err; +} + static int bgmac_mii_register(struct bgmac *bgmac) { + struct bcma_chipinfo *ci = &bgmac->core->bus->chipinfo; struct mii_bus *mii_bus; struct phy_device *phy_dev; char bus_id[MII_BUS_ID_SIZE + 3]; int i, err = 0; + if (ci->id == BCMA_CHIP_ID_BCM4707 || + ci->id == BCMA_CHIP_ID_BCM53018) + return bgmac_fixed_phy_register(bgmac); + mii_bus = mdiobus_alloc(); if (!mii_bus) return -ENOMEM; -- cgit v1.2.3 From fc300dc3733fdc328e6e10c7b8379b60c26cd648 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Fri, 20 Mar 2015 23:14:32 +0100 Subject: bgmac: allow enabling on ARCH_BCM_5301X MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Home routers based on ARM SoCs like BCM4708 also have bcma bus with core supported by bgmac. Signed-off-by: Rafał Miłecki Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig index ee4fdfe65e9e..a6f9142b9048 100644 --- a/drivers/net/ethernet/broadcom/Kconfig +++ b/drivers/net/ethernet/broadcom/Kconfig @@ -142,7 +142,7 @@ config BNX2X_SRIOV config BGMAC tristate "BCMA bus GBit core support" - depends on BCMA_HOST_SOC && HAS_DMA && BCM47XX + depends on BCMA_HOST_SOC && HAS_DMA && (BCM47XX || ARCH_BCM_5301X) select PHYLIB ---help--- This driver supports GBit MAC and BCM4706 GBit MAC cores on BCMA bus. -- cgit v1.2.3 From 0addb83d4c71a68fa716fbd69a605ac0ba5e2b50 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 23 Mar 2015 12:35:35 +0100 Subject: bgmac: fix descriptor frame start/end definitions The start-of-frame and end-of-frame bits were accidentally swapped. In the current code it does not make any difference, since they are always used together. Signed-off-by: Felix Fietkau Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index 89fa5bc69c51..1f9f36f2b658 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -345,8 +345,8 @@ #define BGMAC_DESC_CTL0_EOT 0x10000000 /* End of ring */ #define BGMAC_DESC_CTL0_IOC 0x20000000 /* IRQ on complete */ -#define BGMAC_DESC_CTL0_SOF 0x40000000 /* Start of frame */ -#define BGMAC_DESC_CTL0_EOF 0x80000000 /* End of frame */ +#define BGMAC_DESC_CTL0_EOF 0x40000000 /* End of frame */ +#define BGMAC_DESC_CTL0_SOF 0x80000000 /* Start of frame */ #define BGMAC_DESC_CTL1_LEN 0x00001FFF #define BGMAC_PHY_NOREGS 0x1E -- cgit v1.2.3 From 45c9b3c09490ef4a4ac19df75b5919849423f3e7 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 23 Mar 2015 12:35:36 +0100 Subject: bgmac: implement GRO and use build_skb This improves performance for routing and local rx Signed-off-by: Felix Fietkau Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.c | 80 ++++++++++++++++++++++++----------- drivers/net/ethernet/broadcom/bgmac.h | 7 ++- 2 files changed, 62 insertions(+), 25 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index efda7cf82394..c7da37aef035 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -276,31 +276,31 @@ static int bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac, struct bgmac_slot_info *slot) { struct device *dma_dev = bgmac->core->dma_dev; - struct sk_buff *skb; dma_addr_t dma_addr; struct bgmac_rx_header *rx; + void *buf; /* Alloc skb */ - skb = netdev_alloc_skb(bgmac->net_dev, BGMAC_RX_BUF_SIZE); - if (!skb) + buf = netdev_alloc_frag(BGMAC_RX_ALLOC_SIZE); + if (!buf) return -ENOMEM; /* Poison - if everything goes fine, hardware will overwrite it */ - rx = (struct bgmac_rx_header *)skb->data; + rx = buf; rx->len = cpu_to_le16(0xdead); rx->flags = cpu_to_le16(0xbeef); /* Map skb for the DMA */ - dma_addr = dma_map_single(dma_dev, skb->data, - BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); + dma_addr = dma_map_single(dma_dev, buf, BGMAC_RX_BUF_SIZE, + DMA_FROM_DEVICE); if (dma_mapping_error(dma_dev, dma_addr)) { bgmac_err(bgmac, "DMA mapping error\n"); - dev_kfree_skb(skb); + put_page(virt_to_head_page(buf)); return -ENOMEM; } /* Update the slot */ - slot->skb = skb; + slot->buf = buf; slot->dma_addr = dma_addr; return 0; @@ -343,8 +343,9 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, while (ring->start != ring->end) { struct device *dma_dev = bgmac->core->dma_dev; struct bgmac_slot_info *slot = &ring->slots[ring->start]; - struct sk_buff *skb = slot->skb; - struct bgmac_rx_header *rx; + struct bgmac_rx_header *rx = slot->buf; + struct sk_buff *skb; + void *buf = slot->buf; u16 len, flags; /* Unmap buffer to make it accessible to the CPU */ @@ -352,7 +353,6 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); /* Get info from the header */ - rx = (struct bgmac_rx_header *)skb->data; len = le16_to_cpu(rx->len); flags = le16_to_cpu(rx->flags); @@ -393,12 +393,13 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, dma_unmap_single(dma_dev, old_dma_addr, BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); + skb = build_skb(buf, BGMAC_RX_ALLOC_SIZE); skb_put(skb, BGMAC_RX_FRAME_OFFSET + len); skb_pull(skb, BGMAC_RX_FRAME_OFFSET); skb_checksum_none_assert(skb); skb->protocol = eth_type_trans(skb, bgmac->net_dev); - netif_receive_skb(skb); + napi_gro_receive(&bgmac->napi, skb); handled++; } while (0); @@ -434,12 +435,11 @@ static bool bgmac_dma_unaligned(struct bgmac *bgmac, return false; } -static void bgmac_dma_ring_free(struct bgmac *bgmac, - struct bgmac_dma_ring *ring) +static void bgmac_dma_tx_ring_free(struct bgmac *bgmac, + struct bgmac_dma_ring *ring) { struct device *dma_dev = bgmac->core->dma_dev; struct bgmac_slot_info *slot; - int size; int i; for (i = 0; i < ring->num_slots; i++) { @@ -451,23 +451,55 @@ static void bgmac_dma_ring_free(struct bgmac *bgmac, dev_kfree_skb(slot->skb); } } +} - if (ring->cpu_base) { - /* Free ring of descriptors */ - size = ring->num_slots * sizeof(struct bgmac_dma_desc); - dma_free_coherent(dma_dev, size, ring->cpu_base, - ring->dma_base); +static void bgmac_dma_rx_ring_free(struct bgmac *bgmac, + struct bgmac_dma_ring *ring) +{ + struct device *dma_dev = bgmac->core->dma_dev; + struct bgmac_slot_info *slot; + int i; + + for (i = 0; i < ring->num_slots; i++) { + slot = &ring->slots[i]; + if (!slot->buf) + continue; + + if (slot->dma_addr) + dma_unmap_single(dma_dev, slot->dma_addr, + BGMAC_RX_BUF_SIZE, + DMA_FROM_DEVICE); + put_page(virt_to_head_page(slot->buf)); } } +static void bgmac_dma_ring_desc_free(struct bgmac *bgmac, + struct bgmac_dma_ring *ring) +{ + struct device *dma_dev = bgmac->core->dma_dev; + int size; + + if (!ring->cpu_base) + return; + + /* Free ring of descriptors */ + size = ring->num_slots * sizeof(struct bgmac_dma_desc); + dma_free_coherent(dma_dev, size, ring->cpu_base, + ring->dma_base); +} + static void bgmac_dma_free(struct bgmac *bgmac) { int i; - for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) - bgmac_dma_ring_free(bgmac, &bgmac->tx_ring[i]); - for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) - bgmac_dma_ring_free(bgmac, &bgmac->rx_ring[i]); + for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) { + bgmac_dma_tx_ring_free(bgmac, &bgmac->tx_ring[i]); + bgmac_dma_ring_desc_free(bgmac, &bgmac->tx_ring[i]); + } + for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) { + bgmac_dma_rx_ring_free(bgmac, &bgmac->rx_ring[i]); + bgmac_dma_ring_desc_free(bgmac, &bgmac->rx_ring[i]); + } } static int bgmac_dma_alloc(struct bgmac *bgmac) diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index 1f9f36f2b658..3ad965fe7fcc 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -362,6 +362,8 @@ #define BGMAC_RX_FRAME_OFFSET 30 /* There are 2 unused bytes between header and real data */ #define BGMAC_RX_MAX_FRAME_SIZE 1536 /* Copied from b44/tg3 */ #define BGMAC_RX_BUF_SIZE (BGMAC_RX_FRAME_OFFSET + BGMAC_RX_MAX_FRAME_SIZE) +#define BGMAC_RX_ALLOC_SIZE (SKB_DATA_ALIGN(BGMAC_RX_BUF_SIZE) + \ + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) #define BGMAC_BFL_ENETROBO 0x0010 /* has ephy roboswitch spi */ #define BGMAC_BFL_ENETADM 0x0080 /* has ADMtek switch */ @@ -383,7 +385,10 @@ #define ETHER_MAX_LEN 1518 struct bgmac_slot_info { - struct sk_buff *skb; + union { + struct sk_buff *skb; + void *buf; + }; dma_addr_t dma_addr; }; -- cgit v1.2.3 From 9cde94506eacfcda570b6c304b8deae1a7191ee2 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 23 Mar 2015 12:35:37 +0100 Subject: bgmac: implement scatter/gather support Always use software checksumming, since the hardware does not have any checksum offload support. This significantly improves local TCP tx performance. Signed-off-by: Felix Fietkau Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.c | 164 +++++++++++++++++++++++++--------- 1 file changed, 121 insertions(+), 43 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index c7da37aef035..fa8f9e147c34 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -115,53 +115,91 @@ static void bgmac_dma_tx_enable(struct bgmac *bgmac, bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL, ctl); } +static void +bgmac_dma_tx_add_buf(struct bgmac *bgmac, struct bgmac_dma_ring *ring, + int i, int len, u32 ctl0) +{ + struct bgmac_slot_info *slot; + struct bgmac_dma_desc *dma_desc; + u32 ctl1; + + if (i == ring->num_slots - 1) + ctl0 |= BGMAC_DESC_CTL0_EOT; + + ctl1 = len & BGMAC_DESC_CTL1_LEN; + + slot = &ring->slots[i]; + dma_desc = &ring->cpu_base[i]; + dma_desc->addr_low = cpu_to_le32(lower_32_bits(slot->dma_addr)); + dma_desc->addr_high = cpu_to_le32(upper_32_bits(slot->dma_addr)); + dma_desc->ctl0 = cpu_to_le32(ctl0); + dma_desc->ctl1 = cpu_to_le32(ctl1); +} + static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, struct bgmac_dma_ring *ring, struct sk_buff *skb) { struct device *dma_dev = bgmac->core->dma_dev; struct net_device *net_dev = bgmac->net_dev; - struct bgmac_dma_desc *dma_desc; - struct bgmac_slot_info *slot; - u32 ctl0, ctl1; + struct bgmac_slot_info *slot = &ring->slots[ring->end]; int free_slots; + int nr_frags; + u32 flags; + int index = ring->end; + int i; if (skb->len > BGMAC_DESC_CTL1_LEN) { bgmac_err(bgmac, "Too long skb (%d)\n", skb->len); - goto err_stop_drop; + goto err_drop; } + if (skb->ip_summed == CHECKSUM_PARTIAL) + skb_checksum_help(skb); + + nr_frags = skb_shinfo(skb)->nr_frags; + if (ring->start <= ring->end) free_slots = ring->start - ring->end + BGMAC_TX_RING_SLOTS; else free_slots = ring->start - ring->end; - if (free_slots == 1) { + + if (free_slots <= nr_frags + 1) { bgmac_err(bgmac, "TX ring is full, queue should be stopped!\n"); netif_stop_queue(net_dev); return NETDEV_TX_BUSY; } - slot = &ring->slots[ring->end]; - slot->skb = skb; - slot->dma_addr = dma_map_single(dma_dev, skb->data, skb->len, + slot->dma_addr = dma_map_single(dma_dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); - if (dma_mapping_error(dma_dev, slot->dma_addr)) { - bgmac_err(bgmac, "Mapping error of skb on ring 0x%X\n", - ring->mmio_base); - goto err_stop_drop; - } + if (unlikely(dma_mapping_error(dma_dev, slot->dma_addr))) + goto err_dma_head; - ctl0 = BGMAC_DESC_CTL0_IOC | BGMAC_DESC_CTL0_SOF | BGMAC_DESC_CTL0_EOF; - if (ring->end == ring->num_slots - 1) - ctl0 |= BGMAC_DESC_CTL0_EOT; - ctl1 = skb->len & BGMAC_DESC_CTL1_LEN; + flags = BGMAC_DESC_CTL0_SOF; + if (!nr_frags) + flags |= BGMAC_DESC_CTL0_EOF | BGMAC_DESC_CTL0_IOC; - dma_desc = ring->cpu_base; - dma_desc += ring->end; - dma_desc->addr_low = cpu_to_le32(lower_32_bits(slot->dma_addr)); - dma_desc->addr_high = cpu_to_le32(upper_32_bits(slot->dma_addr)); - dma_desc->ctl0 = cpu_to_le32(ctl0); - dma_desc->ctl1 = cpu_to_le32(ctl1); + bgmac_dma_tx_add_buf(bgmac, ring, index, skb_headlen(skb), flags); + flags = 0; + + for (i = 0; i < nr_frags; i++) { + struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; + int len = skb_frag_size(frag); + + index = (index + 1) % BGMAC_TX_RING_SLOTS; + slot = &ring->slots[index]; + slot->dma_addr = skb_frag_dma_map(dma_dev, frag, 0, + len, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(dma_dev, slot->dma_addr))) + goto err_dma; + + if (i == nr_frags - 1) + flags |= BGMAC_DESC_CTL0_EOF | BGMAC_DESC_CTL0_IOC; + + bgmac_dma_tx_add_buf(bgmac, ring, index, len, flags); + } + + slot->skb = skb; netdev_sent_queue(net_dev, skb->len); @@ -170,20 +208,35 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, /* Increase ring->end to point empty slot. We tell hardware the first * slot it should *not* read. */ - if (++ring->end >= BGMAC_TX_RING_SLOTS) - ring->end = 0; + ring->end = (index + 1) % BGMAC_TX_RING_SLOTS; bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_INDEX, ring->index_base + ring->end * sizeof(struct bgmac_dma_desc)); - /* Always keep one slot free to allow detecting bugged calls. */ - if (--free_slots == 1) + free_slots -= nr_frags + 1; + if (free_slots < 8) netif_stop_queue(net_dev); return NETDEV_TX_OK; -err_stop_drop: - netif_stop_queue(net_dev); +err_dma: + dma_unmap_single(dma_dev, slot->dma_addr, skb_headlen(skb), + DMA_TO_DEVICE); + + while (i > 0) { + int index = (ring->end + i) % BGMAC_TX_RING_SLOTS; + struct bgmac_slot_info *slot = &ring->slots[index]; + u32 ctl1 = le32_to_cpu(ring->cpu_base[index].ctl1); + int len = ctl1 & BGMAC_DESC_CTL1_LEN; + + dma_unmap_page(dma_dev, slot->dma_addr, len, DMA_TO_DEVICE); + } + +err_dma_head: + bgmac_err(bgmac, "Mapping error of skb on ring 0x%X\n", + ring->mmio_base); + +err_drop: dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -205,32 +258,45 @@ static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring) while (ring->start != empty_slot) { struct bgmac_slot_info *slot = &ring->slots[ring->start]; + u32 ctl1 = le32_to_cpu(ring->cpu_base[ring->start].ctl1); + int len = ctl1 & BGMAC_DESC_CTL1_LEN; - if (slot->skb) { + if (!slot->dma_addr) { + bgmac_err(bgmac, "Hardware reported transmission for empty TX ring slot %d! End of ring: %d\n", + ring->start, ring->end); + goto next; + } + + if (ctl1 & BGMAC_DESC_CTL0_SOF) /* Unmap no longer used buffer */ - dma_unmap_single(dma_dev, slot->dma_addr, - slot->skb->len, DMA_TO_DEVICE); - slot->dma_addr = 0; + dma_unmap_single(dma_dev, slot->dma_addr, len, + DMA_TO_DEVICE); + else + dma_unmap_page(dma_dev, slot->dma_addr, len, + DMA_TO_DEVICE); + if (slot->skb) { bytes_compl += slot->skb->len; pkts_compl++; /* Free memory! :) */ dev_kfree_skb(slot->skb); slot->skb = NULL; - } else { - bgmac_err(bgmac, "Hardware reported transmission for empty TX ring slot %d! End of ring: %d\n", - ring->start, ring->end); } +next: + slot->dma_addr = 0; if (++ring->start >= BGMAC_TX_RING_SLOTS) ring->start = 0; freed = true; } + if (!pkts_compl) + return; + netdev_completed_queue(bgmac->net_dev, pkts_compl, bytes_compl); - if (freed && netif_queue_stopped(bgmac->net_dev)) + if (netif_queue_stopped(bgmac->net_dev)) netif_wake_queue(bgmac->net_dev); } @@ -439,17 +505,25 @@ static void bgmac_dma_tx_ring_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring) { struct device *dma_dev = bgmac->core->dma_dev; + struct bgmac_dma_desc *dma_desc = ring->cpu_base; struct bgmac_slot_info *slot; int i; for (i = 0; i < ring->num_slots; i++) { + int len = dma_desc[i].ctl1 & BGMAC_DESC_CTL1_LEN; + slot = &ring->slots[i]; - if (slot->skb) { - if (slot->dma_addr) - dma_unmap_single(dma_dev, slot->dma_addr, - slot->skb->len, DMA_TO_DEVICE); - dev_kfree_skb(slot->skb); - } + dev_kfree_skb(slot->skb); + + if (!slot->dma_addr) + continue; + + if (slot->skb) + dma_unmap_single(dma_dev, slot->dma_addr, + len, DMA_TO_DEVICE); + else + dma_unmap_page(dma_dev, slot->dma_addr, + len, DMA_TO_DEVICE); } } @@ -1583,6 +1657,10 @@ static int bgmac_probe(struct bcma_device *core) goto err_dma_free; } + net_dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + net_dev->hw_features = net_dev->features; + net_dev->vlan_features = net_dev->features; + err = register_netdev(bgmac->net_dev); if (err) { bgmac_err(bgmac, "Cannot register net device\n"); -- cgit v1.2.3 From ca8cf341903f90070e191cc8be8f705ab7af2d4a Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 23 Mar 2015 15:09:51 -0700 Subject: net: bcmgenet: propagate errors from bcmgenet_power_down If bcmgenet_power_down() fails, we would want to propagate a return value from bcmgenet_wol_power_down_cfg() to know about this. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 12956b143b11..f86837f1656a 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -847,9 +847,10 @@ static struct ethtool_ops bcmgenet_ethtool_ops = { }; /* Power down the unimac, based on mode. */ -static void bcmgenet_power_down(struct bcmgenet_priv *priv, +static int bcmgenet_power_down(struct bcmgenet_priv *priv, enum bcmgenet_power_mode mode) { + int ret = 0; u32 reg; switch (mode) { @@ -858,7 +859,7 @@ static void bcmgenet_power_down(struct bcmgenet_priv *priv, break; case GENET_POWER_WOL_MAGIC: - bcmgenet_wol_power_down_cfg(priv, mode); + ret = bcmgenet_wol_power_down_cfg(priv, mode); break; case GENET_POWER_PASSIVE: @@ -873,6 +874,8 @@ static void bcmgenet_power_down(struct bcmgenet_priv *priv, default: break; } + + return 0; } static void bcmgenet_power_up(struct bcmgenet_priv *priv, @@ -2606,12 +2609,12 @@ static int bcmgenet_close(struct net_device *dev) free_irq(priv->irq1, priv); if (phy_is_internal(priv->phydev)) - bcmgenet_power_down(priv, GENET_POWER_PASSIVE); + ret = bcmgenet_power_down(priv, GENET_POWER_PASSIVE); if (!IS_ERR(priv->clk)) clk_disable_unprepare(priv->clk); - return 0; + return ret; } static void bcmgenet_timeout(struct net_device *dev) @@ -3097,14 +3100,14 @@ static int bcmgenet_suspend(struct device *d) /* Prepare the device for Wake-on-LAN and switch to the slow clock */ if (device_may_wakeup(d) && priv->wolopts) { - bcmgenet_power_down(priv, GENET_POWER_WOL_MAGIC); + ret = bcmgenet_power_down(priv, GENET_POWER_WOL_MAGIC); clk_prepare_enable(priv->clk_wol); } /* Turn off the clocks */ clk_disable_unprepare(priv->clk); - return 0; + return ret; } static int bcmgenet_resume(struct device *d) -- cgit v1.2.3 From 0d017e2193ad285d7d0aac429c4c73945729de73 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 23 Mar 2015 15:09:52 -0700 Subject: net: bcmgenet: update bcmgenet_ephy_power_up to clear CK25_DIS bit The CK25_DIS bit controls whether a 25Mhz clock is fed to the GPHY or not, in preparation for powering down the integrated GPHY when relevant, make sure we clear that bit. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.h | 1 + drivers/net/ethernet/broadcom/genet/bcmmii.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 1ea838946318..a27ef777cc81 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -354,6 +354,7 @@ struct bcmgenet_mib_counters { #define EXT_GPHY_CTRL 0x1C #define EXT_CFG_IDDQ_BIAS (1 << 0) #define EXT_CFG_PWR_DOWN (1 << 1) +#define EXT_CK25_DIS (1 << 4) #define EXT_GPHY_RESET (1 << 5) /* DMA rings size */ diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index 446889cc3c6a..f7d9d2753141 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c @@ -178,7 +178,7 @@ static void bcmgenet_ephy_power_up(struct net_device *dev) return; reg = bcmgenet_ext_readl(priv, EXT_GPHY_CTRL); - reg &= ~(EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN); + reg &= ~(EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN | EXT_CK25_DIS); reg |= EXT_GPHY_RESET; bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); mdelay(2); -- cgit v1.2.3 From 8212c98358f44a1c54941c2c01d54ea4a7ddb6dd Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 23 Mar 2015 15:09:53 -0700 Subject: net: bcmgenet: rename bcmgenet_ephy_power_up In preparation for implementing the power down GPHY sequence, rename bcmgenet_ephy_power_up to illustrate that it is not EPHY specific but PHY agnostic, and add an "enable" argument. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmmii.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index f7d9d2753141..3fdbf57208a3 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c @@ -168,7 +168,7 @@ void bcmgenet_mii_reset(struct net_device *dev) } } -static void bcmgenet_ephy_power_up(struct net_device *dev) +static void bcmgenet_phy_power_set(struct net_device *dev, bool enable) { struct bcmgenet_priv *priv = netdev_priv(dev); u32 reg = 0; @@ -177,15 +177,17 @@ static void bcmgenet_ephy_power_up(struct net_device *dev) if (!GENET_IS_V4(priv)) return; - reg = bcmgenet_ext_readl(priv, EXT_GPHY_CTRL); - reg &= ~(EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN | EXT_CK25_DIS); - reg |= EXT_GPHY_RESET; - bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); - mdelay(2); + if (enable) { + reg = bcmgenet_ext_readl(priv, EXT_GPHY_CTRL); + reg &= ~(EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN | EXT_CK25_DIS); + reg |= EXT_GPHY_RESET; + bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); + mdelay(2); - reg &= ~EXT_GPHY_RESET; - bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); - udelay(20); + reg &= ~EXT_GPHY_RESET; + bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); + udelay(20); + } } static void bcmgenet_internal_phy_setup(struct net_device *dev) @@ -193,8 +195,8 @@ static void bcmgenet_internal_phy_setup(struct net_device *dev) struct bcmgenet_priv *priv = netdev_priv(dev); u32 reg; - /* Power up EPHY */ - bcmgenet_ephy_power_up(dev); + /* Power up PHY */ + bcmgenet_phy_power_set(dev, true); /* enable APD */ reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT); reg |= EXT_PWR_DN_EN_LD; -- cgit v1.2.3 From 0c81a8ee61cf4ad29371d7454f65bd8769ba4395 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 23 Mar 2015 15:09:54 -0700 Subject: net: bcmgenet: fix GPHY power-up sequence We were missing a number of extra steps and delays to power-up the GPHY, update the sequence to reflect the proper procedure here. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmmii.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index 3fdbf57208a3..c26c0757d755 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c @@ -179,14 +179,18 @@ static void bcmgenet_phy_power_set(struct net_device *dev, bool enable) if (enable) { reg = bcmgenet_ext_readl(priv, EXT_GPHY_CTRL); - reg &= ~(EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN | EXT_CK25_DIS); + reg &= ~EXT_CK25_DIS; + bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); + mdelay(1); + + reg &= ~(EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN); reg |= EXT_GPHY_RESET; bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); - mdelay(2); + mdelay(1); reg &= ~EXT_GPHY_RESET; bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); - udelay(20); + udelay(60); } } -- cgit v1.2.3 From a9d608c153a28758e0cd11c907edbaf5cce47abc Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 23 Mar 2015 15:09:55 -0700 Subject: net: bcmgenet: implement GPHY power down sequence Implement the GPHY power down sequence by setting all power down bits, putting the GPHY in reset, and finally cutting the 25Mhz reference clock. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmmii.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index c26c0757d755..3320219003fb 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c @@ -177,8 +177,8 @@ static void bcmgenet_phy_power_set(struct net_device *dev, bool enable) if (!GENET_IS_V4(priv)) return; + reg = bcmgenet_ext_readl(priv, EXT_GPHY_CTRL); if (enable) { - reg = bcmgenet_ext_readl(priv, EXT_GPHY_CTRL); reg &= ~EXT_CK25_DIS; bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); mdelay(1); @@ -189,9 +189,14 @@ static void bcmgenet_phy_power_set(struct net_device *dev, bool enable) mdelay(1); reg &= ~EXT_GPHY_RESET; + } else { + reg |= EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN | EXT_GPHY_RESET; bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); - udelay(60); + mdelay(1); + reg |= EXT_CK25_DIS; } + bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); + udelay(60); } static void bcmgenet_internal_phy_setup(struct net_device *dev) -- cgit v1.2.3 From a642c4f7906f36bf431da41973d6ff16b723f079 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 23 Mar 2015 15:09:56 -0700 Subject: net: bcmgenet: power up and down integrated GPHY when unused Power up the GPHY while we are bringing-up the network interface, and conversely, upon bring down, power the GPHY down. In order to avoid creating hardware hazards, make sure that the GPHY gets powered on during bcmgenet_open() prior to the UniMAC being reset as the UniMAC may start creating activity towards the GPHY if we reverse the steps. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 11 ++++++++--- drivers/net/ethernet/broadcom/genet/bcmgenet.h | 1 + drivers/net/ethernet/broadcom/genet/bcmmii.c | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index f86837f1656a..c6b15c3cf023 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -869,6 +869,8 @@ static int bcmgenet_power_down(struct bcmgenet_priv *priv, reg |= (EXT_PWR_DOWN_PHY | EXT_PWR_DOWN_DLL | EXT_PWR_DOWN_BIAS); bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT); + + bcmgenet_phy_power_set(priv->dev, false); } break; default: @@ -2465,9 +2467,6 @@ static void bcmgenet_netif_start(struct net_device *dev) umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true); - if (phy_is_internal(priv->phydev)) - bcmgenet_power_up(priv, GENET_POWER_PASSIVE); - netif_tx_start_all_queues(dev); phy_start(priv->phydev); @@ -2486,6 +2485,12 @@ static int bcmgenet_open(struct net_device *dev) if (!IS_ERR(priv->clk)) clk_prepare_enable(priv->clk); + /* If this is an internal GPHY, power it back on now, before UniMAC is + * brought out of reset as absolutely no UniMAC activity is allowed + */ + if (phy_is_internal(priv->phydev)) + bcmgenet_power_up(priv, GENET_POWER_PASSIVE); + /* take MAC out of reset */ bcmgenet_umac_reset(priv); diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index a27ef777cc81..7a59879d441f 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -664,6 +664,7 @@ int bcmgenet_mii_init(struct net_device *dev); int bcmgenet_mii_config(struct net_device *dev, bool init); void bcmgenet_mii_exit(struct net_device *dev); void bcmgenet_mii_reset(struct net_device *dev); +void bcmgenet_phy_power_set(struct net_device *dev, bool enable); void bcmgenet_mii_setup(struct net_device *dev); /* Wake-on-LAN routines */ diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index 3320219003fb..6d3b66a103cc 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c @@ -168,7 +168,7 @@ void bcmgenet_mii_reset(struct net_device *dev) } } -static void bcmgenet_phy_power_set(struct net_device *dev, bool enable) +void bcmgenet_phy_power_set(struct net_device *dev, bool enable) { struct bcmgenet_priv *priv = netdev_priv(dev); u32 reg = 0; -- cgit v1.2.3 From a6f31f5e3b0498fc0034e07c172925316064201c Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 23 Mar 2015 15:09:57 -0700 Subject: net: bcmgenet: power down and up GPHY during suspend/resume In case the interface is not used, power down the integrated GPHY during suspend. Similarly to bcmgenet_open(), bcmgenet_resume() powers on the GPHY prior to any UniMAC activity. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index c6b15c3cf023..c38d5429e27a 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -3107,6 +3107,8 @@ static int bcmgenet_suspend(struct device *d) if (device_may_wakeup(d) && priv->wolopts) { ret = bcmgenet_power_down(priv, GENET_POWER_WOL_MAGIC); clk_prepare_enable(priv->clk_wol); + } else if (phy_is_internal(priv->phydev)) { + ret = bcmgenet_power_down(priv, GENET_POWER_PASSIVE); } /* Turn off the clocks */ @@ -3131,6 +3133,12 @@ static int bcmgenet_resume(struct device *d) if (ret) return ret; + /* If this is an internal GPHY, power it back on now, before UniMAC is + * brought out of reset as absolutely no UniMAC activity is allowed + */ + if (phy_is_internal(priv->phydev)) + bcmgenet_power_up(priv, GENET_POWER_PASSIVE); + bcmgenet_umac_reset(priv); ret = init_umac(priv); -- cgit v1.2.3 From dff173de84958a677ce0d24b1da3cdc3a32b4238 Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Mon, 23 Mar 2015 10:56:14 +0200 Subject: bnx2x: Fix statistics locking scheme Statistics' state-machine in bnx2x driver must be synced with various driver flows, but its current locking scheme manages to be wasteful [using 2 locks + additional local variable] and prone to race-conditions at the same time, as the state-machine and 'action' are being accessed under different locks. In addition, current 'safe exec' isn't in fact safe, since the only guarantee it gives is that DMA transactions are over, but ramrods might still be running. This patch cleans up said logic, leaving us with a single lock for the entire flow and removing the possible races. Changes from v2: - Switched into mutex locking from semaphore locking. - Release locks on error flows. Changes from v1: Failure to acquire lock fails flow instead of printing a warning and allowing access to the critical section. Signed-off-by: Yuval Mintz Signed-off-by: Ariel Elior Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 4 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 7 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 4 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c | 162 ++++++++++------------ drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h | 6 +- 5 files changed, 83 insertions(+), 100 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 756053c028be..4085c4b31047 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1811,7 +1811,7 @@ struct bnx2x { int stats_state; /* used for synchronization of concurrent threads statistics handling */ - spinlock_t stats_lock; + struct mutex stats_lock; /* used by dmae command loader */ struct dmae_command stats_dmae; @@ -1935,8 +1935,6 @@ struct bnx2x { int fp_array_size; u32 dump_preset_idx; - bool stats_started; - struct semaphore stats_sema; u8 phys_port_id[ETH_ALEN]; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 996e215fc324..ae571a199f2f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -12037,9 +12037,8 @@ static int bnx2x_init_bp(struct bnx2x *bp) mutex_init(&bp->port.phy_mutex); mutex_init(&bp->fw_mb_mutex); mutex_init(&bp->drv_info_mutex); + mutex_init(&bp->stats_lock); bp->drv_info_mng_owner = false; - spin_lock_init(&bp->stats_lock); - sema_init(&bp->stats_sema, 1); INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task); INIT_DELAYED_WORK(&bp->sp_rtnl_task, bnx2x_sp_rtnl_task); @@ -13668,9 +13667,9 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) cancel_delayed_work_sync(&bp->sp_task); cancel_delayed_work_sync(&bp->period_task); - spin_lock_bh(&bp->stats_lock); + mutex_lock(&bp->stats_lock); bp->stats_state = STATS_STATE_DISABLED; - spin_unlock_bh(&bp->stats_lock); + mutex_unlock(&bp->stats_lock); bnx2x_save_statistics(bp); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index e5aca2de1871..cfe3c7695455 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -2238,7 +2238,9 @@ int bnx2x_vf_close(struct bnx2x *bp, struct bnx2x_virtf *vf) cookie.vf = vf; cookie.state = VF_ACQUIRED; - bnx2x_stats_safe_exec(bp, bnx2x_set_vf_state, &cookie); + rc = bnx2x_stats_safe_exec(bp, bnx2x_set_vf_state, &cookie); + if (rc) + goto op_err; } DP(BNX2X_MSG_IOV, "set state to acquired\n"); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index d1608297c773..800ab44a07ce 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c @@ -123,36 +123,28 @@ static void bnx2x_dp_stats(struct bnx2x *bp) */ static void bnx2x_storm_stats_post(struct bnx2x *bp) { - if (!bp->stats_pending) { - int rc; + int rc; - spin_lock_bh(&bp->stats_lock); - - if (bp->stats_pending) { - spin_unlock_bh(&bp->stats_lock); - return; - } - - bp->fw_stats_req->hdr.drv_stats_counter = - cpu_to_le16(bp->stats_counter++); + if (bp->stats_pending) + return; - DP(BNX2X_MSG_STATS, "Sending statistics ramrod %d\n", - le16_to_cpu(bp->fw_stats_req->hdr.drv_stats_counter)); + bp->fw_stats_req->hdr.drv_stats_counter = + cpu_to_le16(bp->stats_counter++); - /* adjust the ramrod to include VF queues statistics */ - bnx2x_iov_adjust_stats_req(bp); - bnx2x_dp_stats(bp); + DP(BNX2X_MSG_STATS, "Sending statistics ramrod %d\n", + le16_to_cpu(bp->fw_stats_req->hdr.drv_stats_counter)); - /* send FW stats ramrod */ - rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STAT_QUERY, 0, - U64_HI(bp->fw_stats_req_mapping), - U64_LO(bp->fw_stats_req_mapping), - NONE_CONNECTION_TYPE); - if (rc == 0) - bp->stats_pending = 1; + /* adjust the ramrod to include VF queues statistics */ + bnx2x_iov_adjust_stats_req(bp); + bnx2x_dp_stats(bp); - spin_unlock_bh(&bp->stats_lock); - } + /* send FW stats ramrod */ + rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STAT_QUERY, 0, + U64_HI(bp->fw_stats_req_mapping), + U64_LO(bp->fw_stats_req_mapping), + NONE_CONNECTION_TYPE); + if (rc == 0) + bp->stats_pending = 1; } static void bnx2x_hw_stats_post(struct bnx2x *bp) @@ -221,7 +213,7 @@ static void bnx2x_stats_comp(struct bnx2x *bp) */ /* should be called under stats_sema */ -static void __bnx2x_stats_pmf_update(struct bnx2x *bp) +static void bnx2x_stats_pmf_update(struct bnx2x *bp) { struct dmae_command *dmae; u32 opcode; @@ -519,7 +511,7 @@ static void bnx2x_func_stats_init(struct bnx2x *bp) } /* should be called under stats_sema */ -static void __bnx2x_stats_start(struct bnx2x *bp) +static void bnx2x_stats_start(struct bnx2x *bp) { if (IS_PF(bp)) { if (bp->port.pmf) @@ -531,34 +523,13 @@ static void __bnx2x_stats_start(struct bnx2x *bp) bnx2x_hw_stats_post(bp); bnx2x_storm_stats_post(bp); } - - bp->stats_started = true; -} - -static void bnx2x_stats_start(struct bnx2x *bp) -{ - if (down_timeout(&bp->stats_sema, HZ/10)) - BNX2X_ERR("Unable to acquire stats lock\n"); - __bnx2x_stats_start(bp); - up(&bp->stats_sema); } static void bnx2x_stats_pmf_start(struct bnx2x *bp) { - if (down_timeout(&bp->stats_sema, HZ/10)) - BNX2X_ERR("Unable to acquire stats lock\n"); bnx2x_stats_comp(bp); - __bnx2x_stats_pmf_update(bp); - __bnx2x_stats_start(bp); - up(&bp->stats_sema); -} - -static void bnx2x_stats_pmf_update(struct bnx2x *bp) -{ - if (down_timeout(&bp->stats_sema, HZ/10)) - BNX2X_ERR("Unable to acquire stats lock\n"); - __bnx2x_stats_pmf_update(bp); - up(&bp->stats_sema); + bnx2x_stats_pmf_update(bp); + bnx2x_stats_start(bp); } static void bnx2x_stats_restart(struct bnx2x *bp) @@ -568,11 +539,9 @@ static void bnx2x_stats_restart(struct bnx2x *bp) */ if (IS_VF(bp)) return; - if (down_timeout(&bp->stats_sema, HZ/10)) - BNX2X_ERR("Unable to acquire stats lock\n"); + bnx2x_stats_comp(bp); - __bnx2x_stats_start(bp); - up(&bp->stats_sema); + bnx2x_stats_start(bp); } static void bnx2x_bmac_stats_update(struct bnx2x *bp) @@ -1246,18 +1215,12 @@ static void bnx2x_stats_update(struct bnx2x *bp) { u32 *stats_comp = bnx2x_sp(bp, stats_comp); - /* we run update from timer context, so give up - * if somebody is in the middle of transition - */ - if (down_trylock(&bp->stats_sema)) + if (bnx2x_edebug_stats_stopped(bp)) return; - if (bnx2x_edebug_stats_stopped(bp) || !bp->stats_started) - goto out; - if (IS_PF(bp)) { if (*stats_comp != DMAE_COMP_VAL) - goto out; + return; if (bp->port.pmf) bnx2x_hw_stats_update(bp); @@ -1267,7 +1230,7 @@ static void bnx2x_stats_update(struct bnx2x *bp) BNX2X_ERR("storm stats were not updated for 3 times\n"); bnx2x_panic(); } - goto out; + return; } } else { /* vf doesn't collect HW statistics, and doesn't get completions @@ -1281,7 +1244,7 @@ static void bnx2x_stats_update(struct bnx2x *bp) /* vf is done */ if (IS_VF(bp)) - goto out; + return; if (netif_msg_timer(bp)) { struct bnx2x_eth_stats *estats = &bp->eth_stats; @@ -1292,9 +1255,6 @@ static void bnx2x_stats_update(struct bnx2x *bp) bnx2x_hw_stats_post(bp); bnx2x_storm_stats_post(bp); - -out: - up(&bp->stats_sema); } static void bnx2x_port_stats_stop(struct bnx2x *bp) @@ -1358,12 +1318,7 @@ static void bnx2x_port_stats_stop(struct bnx2x *bp) static void bnx2x_stats_stop(struct bnx2x *bp) { - int update = 0; - - if (down_timeout(&bp->stats_sema, HZ/10)) - BNX2X_ERR("Unable to acquire stats lock\n"); - - bp->stats_started = false; + bool update = false; bnx2x_stats_comp(bp); @@ -1381,8 +1336,6 @@ static void bnx2x_stats_stop(struct bnx2x *bp) bnx2x_hw_stats_post(bp); bnx2x_stats_comp(bp); } - - up(&bp->stats_sema); } static void bnx2x_stats_do_nothing(struct bnx2x *bp) @@ -1410,18 +1363,28 @@ static const struct { void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) { - enum bnx2x_stats_state state; - void (*action)(struct bnx2x *bp); + enum bnx2x_stats_state state = bp->stats_state; + if (unlikely(bp->panic)) return; - spin_lock_bh(&bp->stats_lock); - state = bp->stats_state; + /* Statistics update run from timer context, and we don't want to stop + * that context in case someone is in the middle of a transition. + * For other events, wait a bit until lock is taken. + */ + if (!mutex_trylock(&bp->stats_lock)) { + if (event == STATS_EVENT_UPDATE) + return; + + DP(BNX2X_MSG_STATS, + "Unlikely stats' lock contention [event %d]\n", event); + mutex_lock(&bp->stats_lock); + } + + bnx2x_stats_stm[state][event].action(bp); bp->stats_state = bnx2x_stats_stm[state][event].next_state; - action = bnx2x_stats_stm[state][event].action; - spin_unlock_bh(&bp->stats_lock); - action(bp); + mutex_unlock(&bp->stats_lock); if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", @@ -1998,13 +1961,34 @@ void bnx2x_afex_collect_stats(struct bnx2x *bp, void *void_afex_stats, } } -void bnx2x_stats_safe_exec(struct bnx2x *bp, - void (func_to_exec)(void *cookie), - void *cookie){ - if (down_timeout(&bp->stats_sema, HZ/10)) - BNX2X_ERR("Unable to acquire stats lock\n"); +int bnx2x_stats_safe_exec(struct bnx2x *bp, + void (func_to_exec)(void *cookie), + void *cookie) +{ + int cnt = 10, rc = 0; + + /* Wait for statistics to end [while blocking further requests], + * then run supplied function 'safely'. + */ + mutex_lock(&bp->stats_lock); + bnx2x_stats_comp(bp); + while (bp->stats_pending && cnt--) + if (bnx2x_storm_stats_update(bp)) + usleep_range(1000, 2000); + if (bp->stats_pending) { + BNX2X_ERR("Failed to wait for stats pending to clear [possibly FW is stuck]\n"); + rc = -EBUSY; + goto out; + } + func_to_exec(cookie); - __bnx2x_stats_start(bp); - up(&bp->stats_sema); + +out: + /* No need to restart statistics - if they're enabled, the timer + * will restart the statistics. + */ + mutex_unlock(&bp->stats_lock); + + return rc; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h index 2beceaefdeea..965539a9dabe 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h @@ -539,9 +539,9 @@ struct bnx2x; void bnx2x_memset_stats(struct bnx2x *bp); void bnx2x_stats_init(struct bnx2x *bp); void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event); -void bnx2x_stats_safe_exec(struct bnx2x *bp, - void (func_to_exec)(void *cookie), - void *cookie); +int bnx2x_stats_safe_exec(struct bnx2x *bp, + void (func_to_exec)(void *cookie), + void *cookie); /** * bnx2x_save_statistics - save statistics when unloading. -- cgit v1.2.3 From e412b1045c3bddd31e16f9e93d6843de2482be0c Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Wed, 25 Mar 2015 12:35:09 -0700 Subject: net: bcmgenet: remove priv->int0_mask and priv->int1_mask Remove unused priv->int0_mask and priv->int1_mask. Signed-off-by: Petri Gynther Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 2 -- drivers/net/ethernet/broadcom/genet/bcmgenet.h | 2 -- 2 files changed, 4 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index c38d5429e27a..030249dd09f0 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -985,7 +985,6 @@ static inline void bcmgenet_tx_ring_int_enable(struct bcmgenet_priv *priv, { bcmgenet_intrl2_1_writel(priv, (1 << ring->index), INTRL2_CPU_MASK_CLEAR); - priv->int1_mask &= ~(1 << ring->index); } static inline void bcmgenet_tx_ring_int_disable(struct bcmgenet_priv *priv, @@ -993,7 +992,6 @@ static inline void bcmgenet_tx_ring_int_disable(struct bcmgenet_priv *priv, { bcmgenet_intrl2_1_writel(priv, (1 << ring->index), INTRL2_CPU_MASK_SET); - priv->int1_mask |= (1 << ring->index); } /* Unlocked version of the reclaim routine */ diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 7a59879d441f..a9e16122f231 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -558,8 +558,6 @@ struct bcmgenet_priv { void __iomem *base; enum bcmgenet_version version; struct net_device *dev; - u32 int0_mask; - u32 int1_mask; /* NAPI for descriptor based rx */ struct napi_struct napi ____cacheline_aligned; -- cgit v1.2.3 From 9dbac28fc193e3972f566f120dce67d69a1df634 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Wed, 25 Mar 2015 12:35:10 -0700 Subject: net: bcmgenet: modify Tx ring int_enable and int_disable vectors Remove unnecessary function parameter priv. Use ring->priv instead. Signed-off-by: Petri Gynther Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 26 +++++++++++--------------- drivers/net/ethernet/broadcom/genet/bcmgenet.h | 6 ++---- 2 files changed, 13 insertions(+), 19 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 030249dd09f0..550bf98d0730 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -964,33 +964,29 @@ static void bcmgenet_free_cb(struct enet_cb *cb) dma_unmap_addr_set(cb, dma_addr, 0); } -static inline void bcmgenet_tx_ring16_int_disable(struct bcmgenet_priv *priv, - struct bcmgenet_tx_ring *ring) +static inline void bcmgenet_tx_ring16_int_disable(struct bcmgenet_tx_ring *ring) { - bcmgenet_intrl2_0_writel(priv, + bcmgenet_intrl2_0_writel(ring->priv, UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE, INTRL2_CPU_MASK_SET); } -static inline void bcmgenet_tx_ring16_int_enable(struct bcmgenet_priv *priv, - struct bcmgenet_tx_ring *ring) +static inline void bcmgenet_tx_ring16_int_enable(struct bcmgenet_tx_ring *ring) { - bcmgenet_intrl2_0_writel(priv, + bcmgenet_intrl2_0_writel(ring->priv, UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE, INTRL2_CPU_MASK_CLEAR); } -static inline void bcmgenet_tx_ring_int_enable(struct bcmgenet_priv *priv, - struct bcmgenet_tx_ring *ring) +static inline void bcmgenet_tx_ring_int_enable(struct bcmgenet_tx_ring *ring) { - bcmgenet_intrl2_1_writel(priv, (1 << ring->index), + bcmgenet_intrl2_1_writel(ring->priv, 1 << ring->index, INTRL2_CPU_MASK_CLEAR); } -static inline void bcmgenet_tx_ring_int_disable(struct bcmgenet_priv *priv, - struct bcmgenet_tx_ring *ring) +static inline void bcmgenet_tx_ring_int_disable(struct bcmgenet_tx_ring *ring) { - bcmgenet_intrl2_1_writel(priv, (1 << ring->index), + bcmgenet_intrl2_1_writel(ring->priv, 1 << ring->index, INTRL2_CPU_MASK_SET); } @@ -1083,7 +1079,7 @@ static int bcmgenet_tx_poll(struct napi_struct *napi, int budget) if (work_done == 0) { napi_complete(napi); - ring->int_enable(ring->priv, ring); + ring->int_enable(ring); return 0; } @@ -2172,7 +2168,7 @@ static irqreturn_t bcmgenet_isr1(int irq, void *dev_id) ring = &priv->tx_rings[index]; if (likely(napi_schedule_prep(&ring->napi))) { - ring->int_disable(priv, ring); + ring->int_disable(ring); __napi_schedule(&ring->napi); } } @@ -2211,7 +2207,7 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id) struct bcmgenet_tx_ring *ring = &priv->tx_rings[DESC_INDEX]; if (likely(napi_schedule_prep(&ring->napi))) { - ring->int_disable(priv, ring); + ring->int_disable(ring); __napi_schedule(&ring->napi); } } diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index a9e16122f231..7b11e7a7e153 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -535,10 +535,8 @@ struct bcmgenet_tx_ring { unsigned int prod_index; /* Tx ring producer index SW copy */ unsigned int cb_ptr; /* Tx ring initial CB ptr */ unsigned int end_ptr; /* Tx ring end CB ptr */ - void (*int_enable)(struct bcmgenet_priv *priv, - struct bcmgenet_tx_ring *); - void (*int_disable)(struct bcmgenet_priv *priv, - struct bcmgenet_tx_ring *); + void (*int_enable)(struct bcmgenet_tx_ring *); + void (*int_disable)(struct bcmgenet_tx_ring *); struct bcmgenet_priv *priv; }; -- cgit v1.2.3 From ebbd96fb2861f591df011cd0eac67dd367596cca Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Wed, 25 Mar 2015 12:35:11 -0700 Subject: net: bcmgenet: simplify bcmgenet_init_dma() Do the two kcalloc() calls first, before proceeding into Rx/Tx DMA init. Makes the error case handling much simpler. Signed-off-by: Petri Gynther Reviewed-by: Florian Fainelli Reviewed-by: Jaedon Shin Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 33 +++++++++++++------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 550bf98d0730..1c9f9b418c52 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2050,9 +2050,6 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv) netif_dbg(priv, hw, priv->dev, "%s\n", __func__); - /* Init rDma */ - bcmgenet_rdma_writel(priv, DMA_MAX_BURST_LENGTH, DMA_SCB_BURST_SIZE); - /* Initialize common Rx ring structures */ priv->rx_bds = priv->base + priv->hw_params->rdma_offset; priv->num_rx_bds = TOTAL_DESC; @@ -2066,25 +2063,13 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv) cb->bd_addr = priv->rx_bds + i * DMA_DESC_SIZE; } - /* Initialize Rx queues */ - ret = bcmgenet_init_rx_queues(priv->dev); - if (ret) { - netdev_err(priv->dev, "failed to initialize Rx queues\n"); - bcmgenet_free_rx_buffers(priv); - kfree(priv->rx_cbs); - return ret; - } - - /* Init tDma */ - bcmgenet_tdma_writel(priv, DMA_MAX_BURST_LENGTH, DMA_SCB_BURST_SIZE); - /* Initialize common TX ring structures */ priv->tx_bds = priv->base + priv->hw_params->tdma_offset; priv->num_tx_bds = TOTAL_DESC; priv->tx_cbs = kcalloc(priv->num_tx_bds, sizeof(struct enet_cb), GFP_KERNEL); if (!priv->tx_cbs) { - __bcmgenet_fini_dma(priv); + kfree(priv->rx_cbs); return -ENOMEM; } @@ -2093,6 +2078,22 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv) cb->bd_addr = priv->tx_bds + i * DMA_DESC_SIZE; } + /* Init rDma */ + bcmgenet_rdma_writel(priv, DMA_MAX_BURST_LENGTH, DMA_SCB_BURST_SIZE); + + /* Initialize Rx queues */ + ret = bcmgenet_init_rx_queues(priv->dev); + if (ret) { + netdev_err(priv->dev, "failed to initialize Rx queues\n"); + bcmgenet_free_rx_buffers(priv); + kfree(priv->rx_cbs); + kfree(priv->tx_cbs); + return ret; + } + + /* Init tDma */ + bcmgenet_tdma_writel(priv, DMA_MAX_BURST_LENGTH, DMA_SCB_BURST_SIZE); + /* Initialize Tx queues */ bcmgenet_init_tx_queues(priv->dev); -- cgit v1.2.3 From b2e97eca88f07d1a4dae691ad8d751ba1de15645 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Wed, 25 Mar 2015 12:35:12 -0700 Subject: net: bcmgenet: tweak init_umac() Use more meaningful variable names int0_enable and int1_enable when enabling bcmgenet interrupts. For Rx default queue interrupts, use: UMAC_IRQ_RXDMA_BDONE | UMAC_IRQ_RXDMA_PDONE For Tx default queue interrupts, use: UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE Signed-off-by: Petri Gynther Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 33 ++++++++++++++++---------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 1c9f9b418c52..68873beba760 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1652,8 +1652,10 @@ static int init_umac(struct bcmgenet_priv *priv) { struct device *kdev = &priv->pdev->dev; int ret; - u32 reg, cpu_mask_clear; - int index; + u32 reg; + u32 int0_enable = 0; + u32 int1_enable = 0; + int i; dev_dbg(&priv->pdev->dev, "bcmgenet: init_umac\n"); @@ -1680,15 +1682,17 @@ static int init_umac(struct bcmgenet_priv *priv) bcmgenet_intr_disable(priv); - cpu_mask_clear = UMAC_IRQ_RXDMA_BDONE | UMAC_IRQ_TXDMA_BDONE; + /* Enable Rx default queue 16 interrupts */ + int0_enable |= (UMAC_IRQ_RXDMA_BDONE | UMAC_IRQ_RXDMA_PDONE); - dev_dbg(kdev, "%s:Enabling RXDMA_BDONE interrupt\n", __func__); + /* Enable Tx default queue 16 interrupts */ + int0_enable |= (UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE); /* Monitor cable plug/unplugged event for internal PHY */ if (phy_is_internal(priv->phydev)) { - cpu_mask_clear |= (UMAC_IRQ_LINK_DOWN | UMAC_IRQ_LINK_UP); + int0_enable |= (UMAC_IRQ_LINK_DOWN | UMAC_IRQ_LINK_UP); } else if (priv->ext_phy) { - cpu_mask_clear |= (UMAC_IRQ_LINK_DOWN | UMAC_IRQ_LINK_UP); + int0_enable |= (UMAC_IRQ_LINK_DOWN | UMAC_IRQ_LINK_UP); } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) { reg = bcmgenet_bp_mc_get(priv); reg |= BIT(priv->hw_params->bp_in_en_shift); @@ -1703,13 +1707,14 @@ static int init_umac(struct bcmgenet_priv *priv) /* Enable MDIO interrupts on GENET v3+ */ if (priv->hw_params->flags & GENET_HAS_MDIO_INTR) - cpu_mask_clear |= UMAC_IRQ_MDIO_DONE | UMAC_IRQ_MDIO_ERROR; + int0_enable |= (UMAC_IRQ_MDIO_DONE | UMAC_IRQ_MDIO_ERROR); - bcmgenet_intrl2_0_writel(priv, cpu_mask_clear, INTRL2_CPU_MASK_CLEAR); + /* Enable Tx priority queue interrupts */ + for (i = 0; i < priv->hw_params->tx_queues; ++i) + int1_enable |= (1 << i); - for (index = 0; index < priv->hw_params->tx_queues; index++) - bcmgenet_intrl2_1_writel(priv, (1 << index), - INTRL2_CPU_MASK_CLEAR); + bcmgenet_intrl2_0_writel(priv, int0_enable, INTRL2_CPU_MASK_CLEAR); + bcmgenet_intrl2_1_writel(priv, int1_enable, INTRL2_CPU_MASK_CLEAR); /* Enable rx/tx engine.*/ dev_dbg(kdev, "done init umac\n"); @@ -2111,7 +2116,8 @@ static int bcmgenet_poll(struct napi_struct *napi, int budget) if (work_done < budget) { napi_complete(napi); - bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_RXDMA_BDONE, + bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_RXDMA_BDONE | + UMAC_IRQ_RXDMA_PDONE, INTRL2_CPU_MASK_CLEAR); } @@ -2198,7 +2204,8 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id) * Disable interrupt, will be enabled in the poll method. */ if (likely(napi_schedule_prep(&priv->napi))) { - bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_RXDMA_BDONE, + bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_RXDMA_BDONE | + UMAC_IRQ_RXDMA_PDONE, INTRL2_CPU_MASK_SET); __napi_schedule(&priv->napi); } -- cgit v1.2.3 From e2aadb4aa9fe4619a78dd925a4756535e9bf3d74 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Wed, 25 Mar 2015 12:35:14 -0700 Subject: net: bcmgenet: rework Tx NAPI code Introduce new bcmgenet functions to handle the NAPI calls to: netif_napi_add() napi_enable() napi_disable() netif_napi_del() Signed-off-by: Petri Gynther Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 80 ++++++++++++++++++++------ 1 file changed, 62 insertions(+), 18 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 68873beba760..367006dcc70d 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1733,7 +1733,6 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv, spin_lock_init(&ring->lock); ring->priv = priv; - netif_napi_add(priv->dev, &ring->napi, bcmgenet_tx_poll, 64); ring->index = index; if (index == DESC_INDEX) { ring->queue = 0; @@ -1777,17 +1776,6 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv, TDMA_WRITE_PTR); bcmgenet_tdma_ring_writel(priv, index, end_ptr * words_per_bd - 1, DMA_END_ADDR); - - napi_enable(&ring->napi); -} - -static void bcmgenet_fini_tx_ring(struct bcmgenet_priv *priv, - unsigned int index) -{ - struct bcmgenet_tx_ring *ring = &priv->tx_rings[index]; - - napi_disable(&ring->napi); - netif_napi_del(&ring->napi); } /* Initialize a RDMA ring */ @@ -1835,6 +1823,62 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv, return ret; } +static void bcmgenet_init_tx_napi(struct bcmgenet_priv *priv) +{ + unsigned int i; + struct bcmgenet_tx_ring *ring; + + for (i = 0; i < priv->hw_params->tx_queues; ++i) { + ring = &priv->tx_rings[i]; + netif_napi_add(priv->dev, &ring->napi, bcmgenet_tx_poll, 64); + } + + ring = &priv->tx_rings[DESC_INDEX]; + netif_napi_add(priv->dev, &ring->napi, bcmgenet_tx_poll, 64); +} + +static void bcmgenet_enable_tx_napi(struct bcmgenet_priv *priv) +{ + unsigned int i; + struct bcmgenet_tx_ring *ring; + + for (i = 0; i < priv->hw_params->tx_queues; ++i) { + ring = &priv->tx_rings[i]; + napi_enable(&ring->napi); + } + + ring = &priv->tx_rings[DESC_INDEX]; + napi_enable(&ring->napi); +} + +static void bcmgenet_disable_tx_napi(struct bcmgenet_priv *priv) +{ + unsigned int i; + struct bcmgenet_tx_ring *ring; + + for (i = 0; i < priv->hw_params->tx_queues; ++i) { + ring = &priv->tx_rings[i]; + napi_disable(&ring->napi); + } + + ring = &priv->tx_rings[DESC_INDEX]; + napi_disable(&ring->napi); +} + +static void bcmgenet_fini_tx_napi(struct bcmgenet_priv *priv) +{ + unsigned int i; + struct bcmgenet_tx_ring *ring; + + for (i = 0; i < priv->hw_params->tx_queues; ++i) { + ring = &priv->tx_rings[i]; + netif_napi_del(&ring->napi); + } + + ring = &priv->tx_rings[DESC_INDEX]; + netif_napi_del(&ring->napi); +} + /* Initialize Tx queues * * Queues 0-3 are priority-based, each one has 32 descriptors, @@ -1895,6 +1939,9 @@ static void bcmgenet_init_tx_queues(struct net_device *dev) bcmgenet_tdma_writel(priv, dma_priority[1], DMA_PRIORITY_1); bcmgenet_tdma_writel(priv, dma_priority[2], DMA_PRIORITY_2); + /* Initialize Tx NAPI */ + bcmgenet_init_tx_napi(priv); + /* Enable Tx queues */ bcmgenet_tdma_writel(priv, ring_cfg, DMA_RING_CFG); @@ -2036,12 +2083,7 @@ static void __bcmgenet_fini_dma(struct bcmgenet_priv *priv) static void bcmgenet_fini_dma(struct bcmgenet_priv *priv) { - int i; - - bcmgenet_fini_tx_ring(priv, DESC_INDEX); - - for (i = 0; i < priv->hw_params->tx_queues; i++) - bcmgenet_fini_tx_ring(priv, i); + bcmgenet_fini_tx_napi(priv); __bcmgenet_fini_dma(priv); } @@ -2466,6 +2508,7 @@ static void bcmgenet_netif_start(struct net_device *dev) /* Start the network engine */ napi_enable(&priv->napi); + bcmgenet_enable_tx_napi(priv); umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true); @@ -2574,6 +2617,7 @@ static void bcmgenet_netif_stop(struct net_device *dev) phy_stop(priv->phydev); bcmgenet_intr_disable(priv); + bcmgenet_disable_tx_napi(priv); /* Wait for pending work items to complete. Since interrupts are * disabled no new work will be scheduled. -- cgit v1.2.3 From 3ab113399b633bacb500a903d2f96f25ded2226c Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Wed, 25 Mar 2015 12:35:15 -0700 Subject: net: bcmgenet: rework Rx NAPI code Introduce new bcmgenet functions to handle the NAPI calls to: netif_napi_add() napi_enable() napi_disable() netif_napi_del() Signed-off-by: Petri Gynther Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 68 +++++++++++++++++--------- 1 file changed, 45 insertions(+), 23 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 367006dcc70d..dc3b1faf6bbd 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1544,6 +1544,25 @@ next: return rxpktprocessed; } +/* Rx NAPI polling method */ +static int bcmgenet_rx_poll(struct napi_struct *napi, int budget) +{ + struct bcmgenet_priv *priv = container_of(napi, + struct bcmgenet_priv, napi); + unsigned int work_done; + + work_done = bcmgenet_desc_rx(priv, DESC_INDEX, budget); + + if (work_done < budget) { + napi_complete(napi); + bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_RXDMA_BDONE | + UMAC_IRQ_RXDMA_PDONE, + INTRL2_CPU_MASK_CLEAR); + } + + return work_done; +} + /* Assign skb to RX DMA descriptor. */ static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv, struct bcmgenet_rx_ring *ring) @@ -1951,6 +1970,26 @@ static void bcmgenet_init_tx_queues(struct net_device *dev) bcmgenet_tdma_writel(priv, dma_ctrl, DMA_CTRL); } +static void bcmgenet_init_rx_napi(struct bcmgenet_priv *priv) +{ + netif_napi_add(priv->dev, &priv->napi, bcmgenet_rx_poll, 64); +} + +static void bcmgenet_enable_rx_napi(struct bcmgenet_priv *priv) +{ + napi_enable(&priv->napi); +} + +static void bcmgenet_disable_rx_napi(struct bcmgenet_priv *priv) +{ + napi_disable(&priv->napi); +} + +static void bcmgenet_fini_rx_napi(struct bcmgenet_priv *priv) +{ + netif_napi_del(&priv->napi); +} + /* Initialize Rx queues * * Queues 0-15 are priority queues. Hardware Filtering Block (HFB) can be @@ -2000,6 +2039,9 @@ static int bcmgenet_init_rx_queues(struct net_device *dev) ring_cfg |= (1 << DESC_INDEX); dma_ctrl |= (1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT)); + /* Initialize Rx NAPI */ + bcmgenet_init_rx_napi(priv); + /* Enable rings */ bcmgenet_rdma_writel(priv, ring_cfg, DMA_RING_CFG); @@ -2083,6 +2125,7 @@ static void __bcmgenet_fini_dma(struct bcmgenet_priv *priv) static void bcmgenet_fini_dma(struct bcmgenet_priv *priv) { + bcmgenet_fini_rx_napi(priv); bcmgenet_fini_tx_napi(priv); __bcmgenet_fini_dma(priv); @@ -2147,25 +2190,6 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv) return 0; } -/* NAPI polling method*/ -static int bcmgenet_poll(struct napi_struct *napi, int budget) -{ - struct bcmgenet_priv *priv = container_of(napi, - struct bcmgenet_priv, napi); - unsigned int work_done; - - work_done = bcmgenet_desc_rx(priv, DESC_INDEX, budget); - - if (work_done < budget) { - napi_complete(napi); - bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_RXDMA_BDONE | - UMAC_IRQ_RXDMA_PDONE, - INTRL2_CPU_MASK_CLEAR); - } - - return work_done; -} - /* Interrupt bottom half */ static void bcmgenet_irq_task(struct work_struct *work) { @@ -2507,7 +2531,7 @@ static void bcmgenet_netif_start(struct net_device *dev) struct bcmgenet_priv *priv = netdev_priv(dev); /* Start the network engine */ - napi_enable(&priv->napi); + bcmgenet_enable_rx_napi(priv); bcmgenet_enable_tx_napi(priv); umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true); @@ -2613,10 +2637,9 @@ static void bcmgenet_netif_stop(struct net_device *dev) struct bcmgenet_priv *priv = netdev_priv(dev); netif_tx_stop_all_queues(dev); - napi_disable(&priv->napi); phy_stop(priv->phydev); - bcmgenet_intr_disable(priv); + bcmgenet_disable_rx_napi(priv); bcmgenet_disable_tx_napi(priv); /* Wait for pending work items to complete. Since interrupts are @@ -3018,7 +3041,6 @@ static int bcmgenet_probe(struct platform_device *pdev) dev->watchdog_timeo = 2 * HZ; dev->ethtool_ops = &bcmgenet_ethtool_ops; dev->netdev_ops = &bcmgenet_netdev_ops; - netif_napi_add(dev, &priv->napi, bcmgenet_poll, 64); priv->msg_enable = netif_msg_init(-1, GENET_MSG_DEFAULT); -- cgit v1.2.3 From 4055eaefb3603a2a55305c81292379922a742131 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Wed, 25 Mar 2015 12:35:16 -0700 Subject: net: bcmgenet: add support for multiple Rx queues Add support for multiple Rx queues: 1. Add NAPI context per Rx queue 2. Modify Rx interrupt and Rx NAPI code to handle multiple Rx queues Signed-off-by: Petri Gynther Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 170 +++++++++++++++++++------ drivers/net/ethernet/broadcom/genet/bcmgenet.h | 12 +- 2 files changed, 137 insertions(+), 45 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index dc3b1faf6bbd..31e14079e1d7 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -964,6 +964,34 @@ static void bcmgenet_free_cb(struct enet_cb *cb) dma_unmap_addr_set(cb, dma_addr, 0); } +static inline void bcmgenet_rx_ring16_int_disable(struct bcmgenet_rx_ring *ring) +{ + bcmgenet_intrl2_0_writel(ring->priv, + UMAC_IRQ_RXDMA_BDONE | UMAC_IRQ_RXDMA_PDONE, + INTRL2_CPU_MASK_SET); +} + +static inline void bcmgenet_rx_ring16_int_enable(struct bcmgenet_rx_ring *ring) +{ + bcmgenet_intrl2_0_writel(ring->priv, + UMAC_IRQ_RXDMA_BDONE | UMAC_IRQ_RXDMA_PDONE, + INTRL2_CPU_MASK_CLEAR); +} + +static inline void bcmgenet_rx_ring_int_disable(struct bcmgenet_rx_ring *ring) +{ + bcmgenet_intrl2_1_writel(ring->priv, + 1 << (UMAC_IRQ1_RX_INTR_SHIFT + ring->index), + INTRL2_CPU_MASK_SET); +} + +static inline void bcmgenet_rx_ring_int_enable(struct bcmgenet_rx_ring *ring) +{ + bcmgenet_intrl2_1_writel(ring->priv, + 1 << (UMAC_IRQ1_RX_INTR_SHIFT + ring->index), + INTRL2_CPU_MASK_CLEAR); +} + static inline void bcmgenet_tx_ring16_int_disable(struct bcmgenet_tx_ring *ring) { bcmgenet_intrl2_0_writel(ring->priv, @@ -1390,11 +1418,10 @@ static struct sk_buff *bcmgenet_rx_refill(struct bcmgenet_priv *priv, /* bcmgenet_desc_rx - descriptor based rx process. * this could be called from bottom half, or from NAPI polling method. */ -static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, - unsigned int index, +static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring, unsigned int budget) { - struct bcmgenet_rx_ring *ring = &priv->rx_rings[index]; + struct bcmgenet_priv *priv = ring->priv; struct net_device *dev = priv->dev; struct enet_cb *cb; struct sk_buff *skb; @@ -1406,7 +1433,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, unsigned int discards; unsigned int chksum_ok = 0; - p_index = bcmgenet_rdma_ring_readl(priv, index, RDMA_PROD_INDEX); + p_index = bcmgenet_rdma_ring_readl(priv, ring->index, RDMA_PROD_INDEX); discards = (p_index >> DMA_P_INDEX_DISCARD_CNT_SHIFT) & DMA_P_INDEX_DISCARD_CNT_MASK; @@ -1419,7 +1446,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, /* Clear HW register when we reach 75% of maximum 0xFFFF */ if (ring->old_discards >= 0xC000) { ring->old_discards = 0; - bcmgenet_rdma_ring_writel(priv, index, 0, + bcmgenet_rdma_ring_writel(priv, ring->index, 0, RDMA_PROD_INDEX); } } @@ -1527,7 +1554,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, dev->stats.multicast++; /* Notify kernel */ - napi_gro_receive(&priv->napi, skb); + napi_gro_receive(&ring->napi, skb); netif_dbg(priv, rx_status, dev, "pushed up to kernel\n"); next: @@ -1538,7 +1565,7 @@ next: ring->read_ptr = ring->cb_ptr; ring->c_index = (ring->c_index + 1) & DMA_C_INDEX_MASK; - bcmgenet_rdma_ring_writel(priv, index, ring->c_index, RDMA_CONS_INDEX); + bcmgenet_rdma_ring_writel(priv, ring->index, ring->c_index, RDMA_CONS_INDEX); } return rxpktprocessed; @@ -1547,17 +1574,15 @@ next: /* Rx NAPI polling method */ static int bcmgenet_rx_poll(struct napi_struct *napi, int budget) { - struct bcmgenet_priv *priv = container_of(napi, - struct bcmgenet_priv, napi); + struct bcmgenet_rx_ring *ring = container_of(napi, + struct bcmgenet_rx_ring, napi); unsigned int work_done; - work_done = bcmgenet_desc_rx(priv, DESC_INDEX, budget); + work_done = bcmgenet_desc_rx(ring, budget); if (work_done < budget) { napi_complete(napi); - bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_RXDMA_BDONE | - UMAC_IRQ_RXDMA_PDONE, - INTRL2_CPU_MASK_CLEAR); + ring->int_enable(ring); } return work_done; @@ -1728,6 +1753,10 @@ static int init_umac(struct bcmgenet_priv *priv) if (priv->hw_params->flags & GENET_HAS_MDIO_INTR) int0_enable |= (UMAC_IRQ_MDIO_DONE | UMAC_IRQ_MDIO_ERROR); + /* Enable Rx priority queue interrupts */ + for (i = 0; i < priv->hw_params->rx_queues; ++i) + int1_enable |= (1 << (UMAC_IRQ1_RX_INTR_SHIFT + i)); + /* Enable Tx priority queue interrupts */ for (i = 0; i < priv->hw_params->tx_queues; ++i) int1_enable |= (1 << i); @@ -1806,7 +1835,15 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv, u32 words_per_bd = WORDS_PER_BD(priv); int ret; + ring->priv = priv; ring->index = index; + if (index == DESC_INDEX) { + ring->int_enable = bcmgenet_rx_ring16_int_enable; + ring->int_disable = bcmgenet_rx_ring16_int_disable; + } else { + ring->int_enable = bcmgenet_rx_ring_int_enable; + ring->int_disable = bcmgenet_rx_ring_int_disable; + } ring->cbs = priv->rx_cbs + start_ptr; ring->size = size; ring->c_index = 0; @@ -1972,22 +2009,58 @@ static void bcmgenet_init_tx_queues(struct net_device *dev) static void bcmgenet_init_rx_napi(struct bcmgenet_priv *priv) { - netif_napi_add(priv->dev, &priv->napi, bcmgenet_rx_poll, 64); + unsigned int i; + struct bcmgenet_rx_ring *ring; + + for (i = 0; i < priv->hw_params->rx_queues; ++i) { + ring = &priv->rx_rings[i]; + netif_napi_add(priv->dev, &ring->napi, bcmgenet_rx_poll, 64); + } + + ring = &priv->rx_rings[DESC_INDEX]; + netif_napi_add(priv->dev, &ring->napi, bcmgenet_rx_poll, 64); } static void bcmgenet_enable_rx_napi(struct bcmgenet_priv *priv) { - napi_enable(&priv->napi); + unsigned int i; + struct bcmgenet_rx_ring *ring; + + for (i = 0; i < priv->hw_params->rx_queues; ++i) { + ring = &priv->rx_rings[i]; + napi_enable(&ring->napi); + } + + ring = &priv->rx_rings[DESC_INDEX]; + napi_enable(&ring->napi); } static void bcmgenet_disable_rx_napi(struct bcmgenet_priv *priv) { - napi_disable(&priv->napi); + unsigned int i; + struct bcmgenet_rx_ring *ring; + + for (i = 0; i < priv->hw_params->rx_queues; ++i) { + ring = &priv->rx_rings[i]; + napi_disable(&ring->napi); + } + + ring = &priv->rx_rings[DESC_INDEX]; + napi_disable(&ring->napi); } static void bcmgenet_fini_rx_napi(struct bcmgenet_priv *priv) { - netif_napi_del(&priv->napi); + unsigned int i; + struct bcmgenet_rx_ring *ring; + + for (i = 0; i < priv->hw_params->rx_queues; ++i) { + ring = &priv->rx_rings[i]; + netif_napi_del(&ring->napi); + } + + ring = &priv->rx_rings[DESC_INDEX]; + netif_napi_del(&ring->napi); } /* Initialize Rx queues @@ -2214,50 +2287,66 @@ static void bcmgenet_irq_task(struct work_struct *work) } } -/* bcmgenet_isr1: interrupt handler for ring buffer. */ +/* bcmgenet_isr1: handle Rx and Tx priority queues */ static irqreturn_t bcmgenet_isr1(int irq, void *dev_id) { struct bcmgenet_priv *priv = dev_id; - struct bcmgenet_tx_ring *ring; + struct bcmgenet_rx_ring *rx_ring; + struct bcmgenet_tx_ring *tx_ring; unsigned int index; /* Save irq status for bottom-half processing. */ priv->irq1_stat = bcmgenet_intrl2_1_readl(priv, INTRL2_CPU_STAT) & ~bcmgenet_intrl2_1_readl(priv, INTRL2_CPU_MASK_STATUS); + /* clear interrupts */ bcmgenet_intrl2_1_writel(priv, priv->irq1_stat, INTRL2_CPU_CLEAR); netif_dbg(priv, intr, priv->dev, "%s: IRQ=0x%x\n", __func__, priv->irq1_stat); - /* Check the MBDONE interrupts. - * packet is done, reclaim descriptors - */ + /* Check Rx priority queue interrupts */ + for (index = 0; index < priv->hw_params->rx_queues; index++) { + if (!(priv->irq1_stat & BIT(UMAC_IRQ1_RX_INTR_SHIFT + index))) + continue; + + rx_ring = &priv->rx_rings[index]; + + if (likely(napi_schedule_prep(&rx_ring->napi))) { + rx_ring->int_disable(rx_ring); + __napi_schedule(&rx_ring->napi); + } + } + + /* Check Tx priority queue interrupts */ for (index = 0; index < priv->hw_params->tx_queues; index++) { if (!(priv->irq1_stat & BIT(index))) continue; - ring = &priv->tx_rings[index]; + tx_ring = &priv->tx_rings[index]; - if (likely(napi_schedule_prep(&ring->napi))) { - ring->int_disable(ring); - __napi_schedule(&ring->napi); + if (likely(napi_schedule_prep(&tx_ring->napi))) { + tx_ring->int_disable(tx_ring); + __napi_schedule(&tx_ring->napi); } } return IRQ_HANDLED; } -/* bcmgenet_isr0: Handle various interrupts. */ +/* bcmgenet_isr0: handle Rx and Tx default queues + other stuff */ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id) { struct bcmgenet_priv *priv = dev_id; + struct bcmgenet_rx_ring *rx_ring; + struct bcmgenet_tx_ring *tx_ring; /* Save irq status for bottom-half processing. */ priv->irq0_stat = bcmgenet_intrl2_0_readl(priv, INTRL2_CPU_STAT) & ~bcmgenet_intrl2_0_readl(priv, INTRL2_CPU_MASK_STATUS); + /* clear interrupts */ bcmgenet_intrl2_0_writel(priv, priv->irq0_stat, INTRL2_CPU_CLEAR); @@ -2265,26 +2354,23 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id) "IRQ=0x%x\n", priv->irq0_stat); if (priv->irq0_stat & (UMAC_IRQ_RXDMA_BDONE | UMAC_IRQ_RXDMA_PDONE)) { - /* We use NAPI(software interrupt throttling, if - * Rx Descriptor throttling is not used. - * Disable interrupt, will be enabled in the poll method. - */ - if (likely(napi_schedule_prep(&priv->napi))) { - bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_RXDMA_BDONE | - UMAC_IRQ_RXDMA_PDONE, - INTRL2_CPU_MASK_SET); - __napi_schedule(&priv->napi); + rx_ring = &priv->rx_rings[DESC_INDEX]; + + if (likely(napi_schedule_prep(&rx_ring->napi))) { + rx_ring->int_disable(rx_ring); + __napi_schedule(&rx_ring->napi); } } - if (priv->irq0_stat & - (UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE)) { - struct bcmgenet_tx_ring *ring = &priv->tx_rings[DESC_INDEX]; - if (likely(napi_schedule_prep(&ring->napi))) { - ring->int_disable(ring); - __napi_schedule(&ring->napi); + if (priv->irq0_stat & (UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE)) { + tx_ring = &priv->tx_rings[DESC_INDEX]; + + if (likely(napi_schedule_prep(&tx_ring->napi))) { + tx_ring->int_disable(tx_ring); + __napi_schedule(&tx_ring->napi); } } + if (priv->irq0_stat & (UMAC_IRQ_PHY_DET_R | UMAC_IRQ_PHY_DET_F | UMAC_IRQ_LINK_UP | diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 7b11e7a7e153..a834da1dfe4c 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -310,6 +310,11 @@ struct bcmgenet_mib_counters { #define UMAC_IRQ_MDIO_DONE (1 << 23) #define UMAC_IRQ_MDIO_ERROR (1 << 24) +/* INTRL2 instance 1 definitions */ +#define UMAC_IRQ1_TX_INTR_MASK 0xFFFF +#define UMAC_IRQ1_RX_INTR_MASK 0xFFFF +#define UMAC_IRQ1_RX_INTR_SHIFT 16 + /* Register block offsets */ #define GENET_SYS_OFF 0x0000 #define GENET_GR_BRIDGE_OFF 0x0040 @@ -541,6 +546,7 @@ struct bcmgenet_tx_ring { }; struct bcmgenet_rx_ring { + struct napi_struct napi; /* Rx NAPI struct */ unsigned int index; /* Rx ring index */ struct enet_cb *cbs; /* Rx ring buffer control block */ unsigned int size; /* Rx ring size */ @@ -549,6 +555,9 @@ struct bcmgenet_rx_ring { unsigned int cb_ptr; /* Rx ring initial CB ptr */ unsigned int end_ptr; /* Rx ring end CB ptr */ unsigned int old_discards; + void (*int_enable)(struct bcmgenet_rx_ring *); + void (*int_disable)(struct bcmgenet_rx_ring *); + struct bcmgenet_priv *priv; }; /* device context */ @@ -557,9 +566,6 @@ struct bcmgenet_priv { enum bcmgenet_version version; struct net_device *dev; - /* NAPI for descriptor based rx */ - struct napi_struct napi ____cacheline_aligned; - /* transmit variables */ void __iomem *tx_bds; struct enet_cb *tx_cbs; -- cgit v1.2.3 From 8cb65d00086bfba22bac87ff18b751432fc74003 Mon Sep 17 00:00:00 2001 From: Toshiaki Makita Date: Fri, 27 Mar 2015 14:31:12 +0900 Subject: net: Move check for multiple vlans to drivers To allow drivers to handle the features check for multiple tags, move the check to ndo_features_check(). As no drivers currently handle multiple tagged TSO, introduce dflt_features_check() and call it if the driver does not have ndo_features_check(). Signed-off-by: Toshiaki Makita Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 1 + drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 1 + drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 1 + include/linux/if_vlan.h | 22 ++++++++++++++++++++++ net/core/dev.c | 21 +++++++++------------ 5 files changed, 34 insertions(+), 12 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 9677431c582a..039b0c1f480e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -12557,6 +12557,7 @@ static netdev_features_t bnx2x_features_check(struct sk_buff *skb, struct net_device *dev, netdev_features_t features) { + features = vlan_features_check(skb, features); return vxlan_features_check(skb, features); } diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index a8339e98ad24..ebc93a101c93 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -2373,6 +2373,7 @@ static netdev_features_t mlx4_en_features_check(struct sk_buff *skb, struct net_device *dev, netdev_features_t features) { + features = vlan_features_check(skb, features); return vxlan_features_check(skb, features); } #endif diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index a430a34a4434..367f3976df56 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -507,6 +507,7 @@ static netdev_features_t qlcnic_features_check(struct sk_buff *skb, struct net_device *dev, netdev_features_t features) { + features = vlan_features_check(skb, features); return vxlan_features_check(skb, features); } #endif diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 4265d440ec4d..920e4457ce6e 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -606,4 +606,26 @@ static inline bool skb_vlan_tagged_multi(const struct sk_buff *skb) return true; } +/** + * vlan_features_check - drop unsafe features for skb with multiple tags. + * @skb: skbuff to query + * @features: features to be checked + * + * Returns features without unsafe ones if the skb has multiple tags. + */ +static inline netdev_features_t vlan_features_check(const struct sk_buff *skb, + netdev_features_t features) +{ + if (skb_vlan_tagged_multi(skb)) + features = netdev_intersect_features(features, + NETIF_F_SG | + NETIF_F_HIGHDMA | + NETIF_F_FRAGLIST | + NETIF_F_GEN_CSUM | + NETIF_F_HW_VLAN_CTAG_TX | + NETIF_F_HW_VLAN_STAG_TX); + + return features; +} + #endif /* !(_LINUX_IF_VLAN_H_) */ diff --git a/net/core/dev.c b/net/core/dev.c index 04bffcd4a48d..cb46badbef5a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2562,6 +2562,13 @@ static netdev_features_t harmonize_features(struct sk_buff *skb, return features; } +static netdev_features_t dflt_features_check(const struct sk_buff *skb, + struct net_device *dev, + netdev_features_t features) +{ + return vlan_features_check(skb, features); +} + netdev_features_t netif_skb_features(struct sk_buff *skb) { struct net_device *dev = skb->dev; @@ -2583,22 +2590,12 @@ netdev_features_t netif_skb_features(struct sk_buff *skb) dev->vlan_features | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX); - else - goto finalize; - if (skb_vlan_tagged_multi(skb)) - features = netdev_intersect_features(features, - NETIF_F_SG | - NETIF_F_HIGHDMA | - NETIF_F_FRAGLIST | - NETIF_F_GEN_CSUM | - NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_STAG_TX); - -finalize: if (dev->netdev_ops->ndo_features_check) features &= dev->netdev_ops->ndo_features_check(skb, dev, features); + else + features &= dflt_features_check(skb, dev, features); return harmonize_features(skb, features); } -- cgit v1.2.3 From 5d45186b4772512e6db9f1494735c983518e3a09 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 29 Mar 2015 23:11:56 +0200 Subject: ptp: bnx2x: convert to the 64 bit get/set time methods. This driver's clock is implemented using a timecounter, and so with this patch the driver is ready for the year 2038. Compile tested only. Signed-off-by: Richard Cochran Acked-by: Sony Chacko Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 039b0c1f480e..8120d266e068 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -13279,7 +13279,7 @@ static int bnx2x_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) return 0; } -static int bnx2x_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts) +static int bnx2x_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) { struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info); u64 ns; @@ -13296,7 +13296,7 @@ static int bnx2x_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts) } static int bnx2x_ptp_settime(struct ptp_clock_info *ptp, - const struct timespec *ts) + const struct timespec64 *ts) { struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info); u64 ns; @@ -13334,8 +13334,8 @@ static void bnx2x_register_phc(struct bnx2x *bp) bp->ptp_clock_info.pps = 0; bp->ptp_clock_info.adjfreq = bnx2x_ptp_adjfreq; bp->ptp_clock_info.adjtime = bnx2x_ptp_adjtime; - bp->ptp_clock_info.gettime = bnx2x_ptp_gettime; - bp->ptp_clock_info.settime = bnx2x_ptp_settime; + bp->ptp_clock_info.gettime64 = bnx2x_ptp_gettime; + bp->ptp_clock_info.settime64 = bnx2x_ptp_settime; bp->ptp_clock_info.enable = bnx2x_ptp_enable; bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &bp->pdev->dev); -- cgit v1.2.3 From f578b41812069e99504f0c2c54412e7ede08532b Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 29 Mar 2015 23:11:57 +0200 Subject: ptp: tg3: convert to the 64 bit get/set time methods. The device appears to use a 64 bit nanoseconds register, and so with this patch the driver should be ready for the year 2038. Compile tested only. Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 22b33da32ba4..d02d19bd34e0 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -6217,7 +6217,7 @@ static int tg3_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) return 0; } -static int tg3_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts) +static int tg3_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) { u64 ns; u32 remainder; @@ -6235,12 +6235,12 @@ static int tg3_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts) } static int tg3_ptp_settime(struct ptp_clock_info *ptp, - const struct timespec *ts) + const struct timespec64 *ts) { u64 ns; struct tg3 *tp = container_of(ptp, struct tg3, ptp_info); - ns = timespec_to_ns(ts); + ns = timespec64_to_ns(ts); tg3_full_lock(tp, 0); tg3_refclk_write(tp, ns); @@ -6320,8 +6320,8 @@ static const struct ptp_clock_info tg3_ptp_caps = { .pps = 0, .adjfreq = tg3_ptp_adjfreq, .adjtime = tg3_ptp_adjtime, - .gettime = tg3_ptp_gettime, - .settime = tg3_ptp_settime, + .gettime64 = tg3_ptp_gettime, + .settime64 = tg3_ptp_settime, .enable = tg3_ptp_enable, }; -- cgit v1.2.3 From 30fd9ff0d9e0d1f83e0ae59cbef3b78648f42b46 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Sun, 29 Mar 2015 10:04:59 +0300 Subject: bnx2x: Configure IFir et al. according to nvram Enable controlling Post2, coeff, IPreDriver and IFir according to NVRAM setup. Signed-off-by: Yaniv Rosner Signed-off-by: Yuval Mintz Signed-off-by: Ariel Elior Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 11 +++++ drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 57 +++++++++++++++++------- drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 2 + 3 files changed, 55 insertions(+), 15 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h index 583591d52497..06df560e1ade 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h @@ -521,6 +521,17 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ */ #define PORT_HW_CFG_TX_DRV_BROADCAST_MASK 0x000F0000 #define PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT 16 + /* Set non-default values for TXFIR in SFP mode. */ + #define PORT_HW_CFG_TX_DRV_IFIR_MASK 0x00F00000 + #define PORT_HW_CFG_TX_DRV_IFIR_SHIFT 20 + + /* Set non-default values for IPREDRIVER in SFP mode. */ + #define PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK 0x0F000000 + #define PORT_HW_CFG_TX_DRV_IPREDRIVER_SHIFT 24 + + /* Set non-default values for POST2 in SFP mode. */ + #define PORT_HW_CFG_TX_DRV_POST2_MASK 0xF0000000 + #define PORT_HW_CFG_TX_DRV_POST2_SHIFT 28 u32 reserved0[5]; /* 0x17c */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index b7c77b26a8a4..a5b174345ce4 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -195,6 +195,10 @@ typedef int (*read_sfp_module_eeprom_func_p)(struct bnx2x_phy *phy, #define MAX_PACKET_SIZE (9700) #define MAX_KR_LINK_RETRY 4 +#define DEFAULT_TX_DRV_BRDCT 2 +#define DEFAULT_TX_DRV_IFIR 0 +#define DEFAULT_TX_DRV_POST2 3 +#define DEFAULT_TX_DRV_IPRE_DRIVER 6 /**********************************************************/ /* INTERFACE */ @@ -3595,10 +3599,11 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, * init configuration, and set/clear SGMII flag. Internal * phy init is done purely in phy_init stage. */ -#define WC_TX_DRIVER(post2, idriver, ipre) \ +#define WC_TX_DRIVER(post2, idriver, ipre, ifir) \ ((post2 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | \ (idriver << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | \ - (ipre << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)) + (ipre << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET) | \ + (ifir << MDIO_WC_REG_TX0_TX_DRIVER_IFIR_OFFSET)) #define WC_TX_FIR(post, main, pre) \ ((post << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | \ @@ -3765,12 +3770,12 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, lane = bnx2x_get_warpcore_lane(phy, params); bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, - WC_TX_DRIVER(0x02, 0x06, 0x09)); + WC_TX_DRIVER(0x02, 0x06, 0x09, 0)); /* Configure the next lane if dual mode */ if (phy->flags & FLAGS_WC_DUAL_MODE) bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_TX0_TX_DRIVER + 0x10*(lane+1), - WC_TX_DRIVER(0x02, 0x06, 0x09)); + WC_TX_DRIVER(0x02, 0x06, 0x09, 0)); bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL, 0x03f0); @@ -3933,6 +3938,7 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; u16 misc1_val, tap_val, tx_driver_val, lane, val; u32 cfg_tap_val, tx_drv_brdct, tx_equal; + u32 ifir_val, ipost2_val, ipre_driver_val; /* Hold rxSeqStart */ bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, @@ -3978,7 +3984,7 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, if (is_xfi) { misc1_val |= 0x5; tap_val = WC_TX_FIR(0x08, 0x37, 0x00); - tx_driver_val = WC_TX_DRIVER(0x00, 0x02, 0x03); + tx_driver_val = WC_TX_DRIVER(0x00, 0x02, 0x03, 0); } else { cfg_tap_val = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, dev_info. @@ -3987,10 +3993,6 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, tx_equal = cfg_tap_val & PORT_HW_CFG_TX_EQUALIZATION_MASK; - tx_drv_brdct = (cfg_tap_val & - PORT_HW_CFG_TX_DRV_BROADCAST_MASK) >> - PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT; - misc1_val |= 0x9; /* TAP values are controlled by nvram, if value there isn't 0 */ @@ -3999,11 +4001,36 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, else tap_val = WC_TX_FIR(0x0f, 0x2b, 0x02); - if (tx_drv_brdct) - tx_driver_val = WC_TX_DRIVER(0x03, (u16)tx_drv_brdct, - 0x06); - else - tx_driver_val = WC_TX_DRIVER(0x03, 0x02, 0x06); + ifir_val = DEFAULT_TX_DRV_IFIR; + ipost2_val = DEFAULT_TX_DRV_POST2; + ipre_driver_val = DEFAULT_TX_DRV_IPRE_DRIVER; + tx_drv_brdct = DEFAULT_TX_DRV_BRDCT; + + /* If any of the IFIR/IPRE_DRIVER/POST@ is set, apply all + * configuration. + */ + if (cfg_tap_val & (PORT_HW_CFG_TX_DRV_IFIR_MASK | + PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK | + PORT_HW_CFG_TX_DRV_POST2_MASK)) { + ifir_val = (cfg_tap_val & + PORT_HW_CFG_TX_DRV_IFIR_MASK) >> + PORT_HW_CFG_TX_DRV_IFIR_SHIFT; + ipre_driver_val = (cfg_tap_val & + PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK) + >> PORT_HW_CFG_TX_DRV_IPREDRIVER_SHIFT; + ipost2_val = (cfg_tap_val & + PORT_HW_CFG_TX_DRV_POST2_MASK) >> + PORT_HW_CFG_TX_DRV_POST2_SHIFT; + } + + if (cfg_tap_val & PORT_HW_CFG_TX_DRV_BROADCAST_MASK) { + tx_drv_brdct = (cfg_tap_val & + PORT_HW_CFG_TX_DRV_BROADCAST_MASK) >> + PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT; + } + + tx_driver_val = WC_TX_DRIVER(ipost2_val, tx_drv_brdct, + ipre_driver_val, ifir_val); } bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val); @@ -4144,7 +4171,7 @@ static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp, MDIO_WC_REG_TX_FIR_TAP_ENABLE)); bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, - WC_TX_DRIVER(0x02, 0x02, 0x02)); + WC_TX_DRIVER(0x02, 0x02, 0x02, 0)); } static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy, diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index 0770e4bff89b..49d511092c82 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h @@ -7341,6 +7341,8 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_WC_REG_TX2_ANA_CTRL0 0x8081 #define MDIO_WC_REG_TX3_ANA_CTRL0 0x8091 #define MDIO_WC_REG_TX0_TX_DRIVER 0x8067 +#define MDIO_WC_REG_TX0_TX_DRIVER_IFIR_OFFSET 0x01 +#define MDIO_WC_REG_TX0_TX_DRIVER_IFIR_MASK 0x000e #define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET 0x04 #define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_MASK 0x00f0 #define MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET 0x08 -- cgit v1.2.3 From fcd02d27b5c543f2d4538d2ac402fed1154c6dfb Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Sun, 29 Mar 2015 10:05:00 +0300 Subject: bnx2x: Count number of link changes Number of link changes are now being stored in shared memory [by all possible link owners], for management use [as well as possible debug information for dumps]. Signed-off-by: Yaniv Rosner Signed-off-by: Yuval Mintz Signed-off-by: Ariel Elior Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 4 ++-- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 25 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h index 06df560e1ade..058bc7328220 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h @@ -2258,8 +2258,8 @@ struct shmem2_region { #define LINK_SFP_EEPROM_COMP_CODE_LRM 0x00004000 u32 reserved5[2]; - u32 reserved6[PORT_MAX]; - + u32 link_change_count[PORT_MAX]; /* Offset 0x160-0x164 */ + #define LINK_CHANGE_COUNT_MASK 0xff /* Offset 0x168 */ /* driver version for each personality */ struct os_drv_ver func_os_drv_ver[E2_FUNC_MAX]; /* Offset 0x16c */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index a5b174345ce4..21a0d6afca4a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -6758,6 +6758,25 @@ static int bnx2x_update_link_up(struct link_params *params, msleep(20); return rc; } + +static void bnx2x_chng_link_count(struct link_params *params, bool clear) +{ + struct bnx2x *bp = params->bp; + u32 addr, val; + + /* Verify the link_change_count is supported by the MFW */ + if (!(SHMEM2_HAS(bp, link_change_count))) + return; + + addr = params->shmem2_base + + offsetof(struct shmem2_region, link_change_count[params->port]); + if (clear) + val = 0; + else + val = REG_RD(bp, addr) + 1; + REG_WR(bp, addr, val); +} + /* The bnx2x_link_update function should be called upon link * interrupt. * Link is considered up as follows: @@ -6776,6 +6795,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) struct link_vars phy_vars[MAX_PHYS]; u8 port = params->port; u8 link_10g_plus, phy_index; + u32 prev_link_status = vars->link_status; u8 ext_phy_link_up = 0, cur_link_up; int rc = 0; u8 is_mi_int = 0; @@ -7015,6 +7035,9 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) else rc = bnx2x_update_link_down(params, vars); + if ((prev_link_status ^ vars->link_status) & LINK_STATUS_LINK_UP) + bnx2x_chng_link_count(params, false); + /* Update MCP link status was changed */ if (params->feature_config_flags & FEATURE_CONFIG_BC_SUPPORTS_AFEX) bnx2x_fw_command(bp, DRV_MSG_CODE_LINK_STATUS_CHANGED, 0); @@ -12658,6 +12681,7 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) params->link_flags = PHY_INITIALIZED; /* Driver opens NIG-BRB filters */ bnx2x_set_rx_filter(params, 1); + bnx2x_chng_link_count(params, true); /* Check if link flap can be avoided */ lfa_status = bnx2x_check_lfa(params); @@ -12732,6 +12756,7 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); /* Disable attentions */ vars->link_status = 0; + bnx2x_chng_link_count(params, true); bnx2x_update_mng(params, vars->link_status); vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK | SHMEM_EEE_ACTIVE_BIT); -- cgit v1.2.3 From 0f587f1bfb1fb15d9ebd94c565dd11ae6d4e03b6 Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Sun, 29 Mar 2015 10:05:01 +0300 Subject: bnx2x: Prevent probe as early as possible It's possible that due to errors [either on PCI or on device itself] registers reads would fail, returning all-Fs. This adds a check as early as possible so that driver will not read junk values and make incorrect probe decisions according to them; instead, gracefully fail the probe. Signed-off-by: Yuval Mintz Signed-off-by: Ariel Elior Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 8120d266e068..768dfb16bc80 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -11650,6 +11650,13 @@ static int bnx2x_get_hwinfo(struct bnx2x *bp) u32 val = 0, val2 = 0; int rc = 0; + /* Validate that chip access is feasible */ + if (REG_RD(bp, MISC_REG_CHIP_NUM) == 0xffffffff) { + dev_err(&bp->pdev->dev, + "Chip read returns all Fs. Preventing probe from continuing\n"); + return -EINVAL; + } + bnx2x_get_common_hwinfo(bp); /* -- cgit v1.2.3 From 4e833c596ef5f699479a8ba2d3294a004895f5f4 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 29 Mar 2015 18:25:12 -0700 Subject: ethernet: Use bool function returns of true/false instead of 1/0 Use bool constants as the return values instead of 1 and 0. Signed-off-by: Joe Perches Acked-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 4 ++-- drivers/net/ethernet/xilinx/xilinx_emaclite.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 768dfb16bc80..f0466a028145 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -11610,7 +11610,7 @@ static bool bnx2x_get_dropless_info(struct bnx2x *bp) u32 cfg; if (IS_VF(bp)) - return 0; + return false; if (IS_MF(bp) && !CHIP_IS_E1x(bp)) { /* Take function: tmp = func */ diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 02ffb3081b11..ccaecb1b8619 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -1351,7 +1351,7 @@ static bool reg_pattern_test(struct ixgbe_adapter *adapter, u64 *data, int reg, if (ixgbe_removed(adapter->hw.hw_addr)) { *data = 1; - return 1; + return true; } for (pat = 0; pat < ARRAY_SIZE(test_pattern); pat++) { before = ixgbe_read_reg(&adapter->hw, reg); @@ -1376,7 +1376,7 @@ static bool reg_set_and_check(struct ixgbe_adapter *adapter, u64 *data, int reg, if (ixgbe_removed(adapter->hw.hw_addr)) { *data = 1; - return 1; + return true; } before = ixgbe_read_reg(&adapter->hw, reg); ixgbe_write_reg(&adapter->hw, reg, write & mask); diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c index 2111b91f5e49..6008eee01a33 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c @@ -1062,7 +1062,7 @@ static bool get_bool(struct platform_device *ofdev, const char *s) } else { dev_warn(&ofdev->dev, "Parameter %s not found," "defaulting to false\n", s); - return 0; + return false; } } -- cgit v1.2.3 From ee7d8c2067e1bc633f4df3159698b32a9714f724 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Mon, 30 Mar 2015 00:28:50 -0700 Subject: net: bcmgenet: add UMAC_IRQ_RXDMA_DONE and UMAC_IRQ_TXDMA_DONE Add #define for UMAC_IRQ_RXDMA_DONE and UMAC_IRQ_TXDMA_DONE in order to simplify the code that handles Rx and Tx default queue interrupts. Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 20 ++++++++------------ drivers/net/ethernet/broadcom/genet/bcmgenet.h | 4 ++++ 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 31e14079e1d7..620021e8365a 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -966,15 +966,13 @@ static void bcmgenet_free_cb(struct enet_cb *cb) static inline void bcmgenet_rx_ring16_int_disable(struct bcmgenet_rx_ring *ring) { - bcmgenet_intrl2_0_writel(ring->priv, - UMAC_IRQ_RXDMA_BDONE | UMAC_IRQ_RXDMA_PDONE, + bcmgenet_intrl2_0_writel(ring->priv, UMAC_IRQ_RXDMA_DONE, INTRL2_CPU_MASK_SET); } static inline void bcmgenet_rx_ring16_int_enable(struct bcmgenet_rx_ring *ring) { - bcmgenet_intrl2_0_writel(ring->priv, - UMAC_IRQ_RXDMA_BDONE | UMAC_IRQ_RXDMA_PDONE, + bcmgenet_intrl2_0_writel(ring->priv, UMAC_IRQ_RXDMA_DONE, INTRL2_CPU_MASK_CLEAR); } @@ -994,15 +992,13 @@ static inline void bcmgenet_rx_ring_int_enable(struct bcmgenet_rx_ring *ring) static inline void bcmgenet_tx_ring16_int_disable(struct bcmgenet_tx_ring *ring) { - bcmgenet_intrl2_0_writel(ring->priv, - UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE, + bcmgenet_intrl2_0_writel(ring->priv, UMAC_IRQ_TXDMA_DONE, INTRL2_CPU_MASK_SET); } static inline void bcmgenet_tx_ring16_int_enable(struct bcmgenet_tx_ring *ring) { - bcmgenet_intrl2_0_writel(ring->priv, - UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE, + bcmgenet_intrl2_0_writel(ring->priv, UMAC_IRQ_TXDMA_DONE, INTRL2_CPU_MASK_CLEAR); } @@ -1727,10 +1723,10 @@ static int init_umac(struct bcmgenet_priv *priv) bcmgenet_intr_disable(priv); /* Enable Rx default queue 16 interrupts */ - int0_enable |= (UMAC_IRQ_RXDMA_BDONE | UMAC_IRQ_RXDMA_PDONE); + int0_enable |= UMAC_IRQ_RXDMA_DONE; /* Enable Tx default queue 16 interrupts */ - int0_enable |= (UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE); + int0_enable |= UMAC_IRQ_TXDMA_DONE; /* Monitor cable plug/unplugged event for internal PHY */ if (phy_is_internal(priv->phydev)) { @@ -2353,7 +2349,7 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id) netif_dbg(priv, intr, priv->dev, "IRQ=0x%x\n", priv->irq0_stat); - if (priv->irq0_stat & (UMAC_IRQ_RXDMA_BDONE | UMAC_IRQ_RXDMA_PDONE)) { + if (priv->irq0_stat & UMAC_IRQ_RXDMA_DONE) { rx_ring = &priv->rx_rings[DESC_INDEX]; if (likely(napi_schedule_prep(&rx_ring->napi))) { @@ -2362,7 +2358,7 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id) } } - if (priv->irq0_stat & (UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE)) { + if (priv->irq0_stat & UMAC_IRQ_TXDMA_DONE) { tx_ring = &priv->tx_rings[DESC_INDEX]; if (likely(napi_schedule_prep(&tx_ring->napi))) { diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index a834da1dfe4c..f86d635f8a6b 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -303,9 +303,13 @@ struct bcmgenet_mib_counters { #define UMAC_IRQ_RXDMA_MBDONE (1 << 13) #define UMAC_IRQ_RXDMA_PDONE (1 << 14) #define UMAC_IRQ_RXDMA_BDONE (1 << 15) +#define UMAC_IRQ_RXDMA_DONE (UMAC_IRQ_RXDMA_PDONE | \ + UMAC_IRQ_RXDMA_BDONE) #define UMAC_IRQ_TXDMA_MBDONE (1 << 16) #define UMAC_IRQ_TXDMA_PDONE (1 << 17) #define UMAC_IRQ_TXDMA_BDONE (1 << 18) +#define UMAC_IRQ_TXDMA_DONE (UMAC_IRQ_TXDMA_PDONE | \ + UMAC_IRQ_TXDMA_BDONE) /* Only valid for GENETv3+ */ #define UMAC_IRQ_MDIO_DONE (1 << 23) #define UMAC_IRQ_MDIO_ERROR (1 << 24) -- cgit v1.2.3 From 9abab96d9feabf4df87464de035344e91aeefa0a Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Mon, 30 Mar 2015 00:29:01 -0700 Subject: net: bcmgenet: remove __bcmgenet_fini_dma() bcmgenet_fini_dma() is the only caller of __bcmgenet_fini_dma(). Move __bcmgenet_fini_dma() code inside bcmgenet_fini_dma(). Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 620021e8365a..546d8623d8eb 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2173,10 +2173,13 @@ static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv) return ret; } -static void __bcmgenet_fini_dma(struct bcmgenet_priv *priv) +static void bcmgenet_fini_dma(struct bcmgenet_priv *priv) { int i; + bcmgenet_fini_rx_napi(priv); + bcmgenet_fini_tx_napi(priv); + /* disable DMA */ bcmgenet_dma_teardown(priv); @@ -2192,14 +2195,6 @@ static void __bcmgenet_fini_dma(struct bcmgenet_priv *priv) kfree(priv->tx_cbs); } -static void bcmgenet_fini_dma(struct bcmgenet_priv *priv) -{ - bcmgenet_fini_rx_napi(priv); - bcmgenet_fini_tx_napi(priv); - - __bcmgenet_fini_dma(priv); -} - /* init_edma: Initialize DMA control register */ static int bcmgenet_init_dma(struct bcmgenet_priv *priv) { -- cgit v1.2.3 From fac25940c5e0d6f31d56bb2a704fadad6d5e382a Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Mon, 30 Mar 2015 00:29:13 -0700 Subject: net: bcmgenet: fix bcmgenet_open() If bcmgenet_init_dma() fails, it cleans up after itself. Rx and Tx DMAs are off, and NAPI instances haven't been netif_napi_add()'ed. Therefore, we need to skip calling bcmgenet_fini_dma() on the error handling path. bcmgenet_resume() already does this correctly. Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 546d8623d8eb..5238b33f7b8d 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2666,7 +2666,7 @@ static int bcmgenet_open(struct net_device *dev) ret = bcmgenet_init_dma(priv); if (ret) { netdev_err(dev, "failed to initialize DMA\n"); - goto err_fini_dma; + goto err_clk_disable; } /* Always enable ring 16 - descriptor ring */ -- cgit v1.2.3 From e122966dd9aedb666df93f5ee6007e1688194611 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Mon, 30 Mar 2015 00:29:24 -0700 Subject: net: bcmgenet: add UMAC_IRQ_LINK_EVENT Add #define UMAC_IRQ_LINK_EVENT to simplify link event handling code. Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 11 +++++------ drivers/net/ethernet/broadcom/genet/bcmgenet.h | 1 + 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 5238b33f7b8d..bf1a8711dbc0 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1730,9 +1730,9 @@ static int init_umac(struct bcmgenet_priv *priv) /* Monitor cable plug/unplugged event for internal PHY */ if (phy_is_internal(priv->phydev)) { - int0_enable |= (UMAC_IRQ_LINK_DOWN | UMAC_IRQ_LINK_UP); + int0_enable |= UMAC_IRQ_LINK_EVENT; } else if (priv->ext_phy) { - int0_enable |= (UMAC_IRQ_LINK_DOWN | UMAC_IRQ_LINK_UP); + int0_enable |= UMAC_IRQ_LINK_EVENT; } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) { reg = bcmgenet_bp_mc_get(priv); reg |= BIT(priv->hw_params->bp_in_en_shift); @@ -2271,10 +2271,10 @@ static void bcmgenet_irq_task(struct work_struct *work) /* Link UP/DOWN event */ if ((priv->hw_params->flags & GENET_HAS_MDIO_INTR) && - (priv->irq0_stat & (UMAC_IRQ_LINK_UP|UMAC_IRQ_LINK_DOWN))) { + (priv->irq0_stat & UMAC_IRQ_LINK_EVENT)) { phy_mac_interrupt(priv->phydev, priv->irq0_stat & UMAC_IRQ_LINK_UP); - priv->irq0_stat &= ~(UMAC_IRQ_LINK_UP|UMAC_IRQ_LINK_DOWN); + priv->irq0_stat &= ~UMAC_IRQ_LINK_EVENT; } } @@ -2364,8 +2364,7 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id) if (priv->irq0_stat & (UMAC_IRQ_PHY_DET_R | UMAC_IRQ_PHY_DET_F | - UMAC_IRQ_LINK_UP | - UMAC_IRQ_LINK_DOWN | + UMAC_IRQ_LINK_EVENT | UMAC_IRQ_HFB_SM | UMAC_IRQ_HFB_MM | UMAC_IRQ_MPD_R)) { diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index f86d635f8a6b..ddaa40cb0f21 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -293,6 +293,7 @@ struct bcmgenet_mib_counters { #define UMAC_IRQ_PHY_DET_F (1 << 3) #define UMAC_IRQ_LINK_UP (1 << 4) #define UMAC_IRQ_LINK_DOWN (1 << 5) +#define UMAC_IRQ_LINK_EVENT (UMAC_IRQ_LINK_UP | UMAC_IRQ_LINK_DOWN) #define UMAC_IRQ_UMAC (1 << 6) #define UMAC_IRQ_UMAC_TSV (1 << 7) #define UMAC_IRQ_TBUF_UNDERRUN (1 << 8) -- cgit v1.2.3 From 451e1ca2ab68b9184379fde7867f278c4b3efc61 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Mon, 30 Mar 2015 00:29:35 -0700 Subject: net: bcmgenet: fix the call to phy_mac_interrupt() On phy_mac_interrupt() call, the new_link parameter should be 0 or 1. Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index bf1a8711dbc0..f7855a61e7ad 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2273,7 +2273,7 @@ static void bcmgenet_irq_task(struct work_struct *work) if ((priv->hw_params->flags & GENET_HAS_MDIO_INTR) && (priv->irq0_stat & UMAC_IRQ_LINK_EVENT)) { phy_mac_interrupt(priv->phydev, - priv->irq0_stat & UMAC_IRQ_LINK_UP); + !!(priv->irq0_stat & UMAC_IRQ_LINK_UP)); priv->irq0_stat &= ~UMAC_IRQ_LINK_EVENT; } } -- cgit v1.2.3 From f7dcdefe362c06a36483679defb116dda02177e1 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Tue, 31 Mar 2015 23:08:07 +0200 Subject: ptp: bnx2x: use helpers for converting ns to timespec. This patch changes the driver to use ns_to_timespec64() and timespec64_to_ns() instead of open coding the same logic. Compile tested only. Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index f0466a028145..177cb0e722e7 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -13290,14 +13290,12 @@ static int bnx2x_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) { struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info); u64 ns; - u32 remainder; ns = timecounter_read(&bp->timecounter); DP(BNX2X_MSG_PTP, "PTP gettime called, ns = %llu\n", ns); - ts->tv_sec = div_u64_rem(ns, 1000000000ULL, &remainder); - ts->tv_nsec = remainder; + *ts = ns_to_timespec64(ns); return 0; } @@ -13308,8 +13306,7 @@ static int bnx2x_ptp_settime(struct ptp_clock_info *ptp, struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info); u64 ns; - ns = ts->tv_sec * 1000000000ULL; - ns += ts->tv_nsec; + ns = timespec64_to_ns(ts); DP(BNX2X_MSG_PTP, "PTP settime called, ns = %llu\n", ns); -- cgit v1.2.3 From 7a20efb07437f8716977401c5bd183c3d192ff12 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Tue, 31 Mar 2015 23:08:08 +0200 Subject: ptp: tg3: use helpers for converting ns to timespec. This patch changes the driver to use ns_to_timespec64() instead of open coding the same logic. Compile tested only. Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index d02d19bd34e0..1270b189a9a2 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -6220,7 +6220,6 @@ static int tg3_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) static int tg3_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) { u64 ns; - u32 remainder; struct tg3 *tp = container_of(ptp, struct tg3, ptp_info); tg3_full_lock(tp, 0); @@ -6228,8 +6227,7 @@ static int tg3_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) ns += tp->ptp_adjust; tg3_full_unlock(tp); - ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder); - ts->tv_nsec = remainder; + *ts = ns_to_timespec64(ns); return 0; } -- cgit v1.2.3 From 138173d4e826587da66c7d321da1a91283222536 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 1 Dec 2014 07:58:18 +0100 Subject: MIPS: BCM47xx: Move NVRAM header to the include/linux/. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are two reasons for having this header in the common place: 1) Simplifying drivers that read NVRAM entries. We will be able to safely call bcm47xx_nvram_* functions without #ifdef-s. 2) Getting NVRAM driver out of MIPS arch code. This is needed to support BCM5301X arch which also requires this NVRAM driver. Patch for that will follow once we get is reviewed. Signed-off-by: Rafał Miłecki Acked-by: Hauke Mehrtens Cc: linux-mips@linux-mips.org Cc: Arnd Bergmann Cc: Paul Walmsley Cc: linux-soc@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8619/ Signed-off-by: Ralf Baechle --- arch/mips/bcm47xx/board.c | 2 +- arch/mips/bcm47xx/nvram.c | 2 +- arch/mips/bcm47xx/setup.c | 1 - arch/mips/bcm47xx/sprom.c | 1 - arch/mips/bcm47xx/time.c | 1 - arch/mips/include/asm/mach-bcm47xx/bcm47xx.h | 1 + arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h | 21 ------------- drivers/bcma/driver_mips.c | 2 +- drivers/net/ethernet/broadcom/b44.c | 2 +- drivers/net/ethernet/broadcom/bgmac.c | 2 +- drivers/ssb/driver_chipcommon_pmu.c | 2 +- drivers/ssb/driver_mipscore.c | 2 +- include/linux/bcm47xx_nvram.h | 34 ++++++++++++++++++++++ 13 files changed, 42 insertions(+), 31 deletions(-) delete mode 100644 arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h create mode 100644 include/linux/bcm47xx_nvram.h (limited to 'drivers/net/ethernet/broadcom') diff --git a/arch/mips/bcm47xx/board.c b/arch/mips/bcm47xx/board.c index b3ae068ca4fa..6e8513068325 100644 --- a/arch/mips/bcm47xx/board.c +++ b/arch/mips/bcm47xx/board.c @@ -1,8 +1,8 @@ #include #include #include +#include #include -#include struct bcm47xx_board_type { const enum bcm47xx_board board; diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c index d805d8af415f..7c77a88eedf9 100644 --- a/arch/mips/bcm47xx/nvram.c +++ b/arch/mips/bcm47xx/nvram.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */ #define NVRAM_SPACE 0x8000 diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index e43b5046cb30..b26c9c24275e 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c @@ -42,7 +42,6 @@ #include #include #include -#include #include union bcm47xx_bus bcm47xx_bus; diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c index eff920560689..c114b0239758 100644 --- a/arch/mips/bcm47xx/sprom.c +++ b/arch/mips/bcm47xx/sprom.c @@ -27,7 +27,6 @@ */ #include -#include #include #include diff --git a/arch/mips/bcm47xx/time.c b/arch/mips/bcm47xx/time.c index 2c85d9254b5e..5b46510daa7b 100644 --- a/arch/mips/bcm47xx/time.c +++ b/arch/mips/bcm47xx/time.c @@ -27,7 +27,6 @@ #include #include #include -#include #include void __init plat_time_init(void) diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h index 7527c1d33d02..8ed77f618940 100644 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h @@ -22,6 +22,7 @@ #include #include #include +#include enum bcm47xx_bus_type { #ifdef CONFIG_BCM47XX_SSB diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h deleted file mode 100644 index ee59ffe99922..000000000000 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2005, Broadcom Corporation - * Copyright (C) 2006, Felix Fietkau - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef __BCM47XX_NVRAM_H -#define __BCM47XX_NVRAM_H - -#include -#include - -int bcm47xx_nvram_init_from_mem(u32 base, u32 lim); -int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len); -int bcm47xx_nvram_gpio_pin(const char *name); - -#endif /* __BCM47XX_NVRAM_H */ diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c index 04faf6df959f..24424f3fef96 100644 --- a/drivers/bcma/driver_mips.c +++ b/drivers/bcma/driver_mips.c @@ -21,7 +21,7 @@ #include #include #ifdef CONFIG_BCM47XX -#include +#include #endif enum bcma_boot_dev { diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c index bd5916a60cb5..77363d680532 100644 --- a/drivers/net/ethernet/broadcom/b44.c +++ b/drivers/net/ethernet/broadcom/b44.c @@ -400,7 +400,7 @@ static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote) } #ifdef CONFIG_BCM47XX -#include +#include static void b44_wap54g10_workaround(struct b44 *bp) { char buf[20]; diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 0469f72c6e7e..be059df8c852 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include static const struct bcma_device_id bgmac_bcma_tbl[] = { BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS), diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c index 1173a091b402..09428412139e 100644 --- a/drivers/ssb/driver_chipcommon_pmu.c +++ b/drivers/ssb/driver_chipcommon_pmu.c @@ -14,7 +14,7 @@ #include #include #ifdef CONFIG_BCM47XX -#include +#include #endif #include "ssb_private.h" diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c index 7b986f9f213f..f87efef42252 100644 --- a/drivers/ssb/driver_mipscore.c +++ b/drivers/ssb/driver_mipscore.c @@ -16,7 +16,7 @@ #include #include #ifdef CONFIG_BCM47XX -#include +#include #endif #include "ssb_private.h" diff --git a/include/linux/bcm47xx_nvram.h b/include/linux/bcm47xx_nvram.h new file mode 100644 index 000000000000..b12b07e75929 --- /dev/null +++ b/include/linux/bcm47xx_nvram.h @@ -0,0 +1,34 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __BCM47XX_NVRAM_H +#define __BCM47XX_NVRAM_H + +#include +#include + +#ifdef CONFIG_BCM47XX +int bcm47xx_nvram_init_from_mem(u32 base, u32 lim); +int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len); +int bcm47xx_nvram_gpio_pin(const char *name); +#else +static inline int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) +{ + return -ENOTSUPP; +}; +static inline int bcm47xx_nvram_getenv(const char *name, char *val, + size_t val_len) +{ + return -ENOTSUPP; +}; +static inline int bcm47xx_nvram_gpio_pin(const char *name) +{ + return -ENOTSUPP; +}; +#endif + +#endif /* __BCM47XX_NVRAM_H */ -- cgit v1.2.3 From 3d6b72534a109be4353b161a09a5683b441d0941 Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Wed, 1 Apr 2015 10:02:19 +0300 Subject: bnx2x: Fix kdump on 4-port device When running in a kdump kernel, it's very likely that due to sync. loss with management firmware the first PCI function to probe and reach the previous unload flow would decide it can reset the chip and continue onward. While doing so, it will only close its own Rx port. On a 4-port device where 2nd port on engine is a 1g-port, the 2nd port would allow ingress traffic after the chip is reset [assuming it was active on the first kernel]. This would later cause a HW attention. This changes driver flow to close both ports' 1g capabilities during the previous driver unload flow prior to the chip reset. Signed-off-by: Yuval Mintz Signed-off-by: Ariel Elior Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 53 ++++++++++++++++-------- 1 file changed, 35 insertions(+), 18 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index ae571a199f2f..e6dec47fec68 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -129,8 +129,8 @@ struct bnx2x_mac_vals { u32 xmac_val; u32 emac_addr; u32 emac_val; - u32 umac_addr; - u32 umac_val; + u32 umac_addr[2]; + u32 umac_val[2]; u32 bmac_addr; u32 bmac_val[2]; }; @@ -10141,6 +10141,25 @@ static u32 bnx2x_get_pretend_reg(struct bnx2x *bp) return base + (BP_ABS_FUNC(bp)) * stride; } +static bool bnx2x_prev_unload_close_umac(struct bnx2x *bp, + u8 port, u32 reset_reg, + struct bnx2x_mac_vals *vals) +{ + u32 mask = MISC_REGISTERS_RESET_REG_2_UMAC0 << port; + u32 base_addr; + + if (!(mask & reset_reg)) + return false; + + BNX2X_DEV_INFO("Disable umac Rx %02x\n", port); + base_addr = port ? GRCBASE_UMAC1 : GRCBASE_UMAC0; + vals->umac_addr[port] = base_addr + UMAC_REG_COMMAND_CONFIG; + vals->umac_val[port] = REG_RD(bp, vals->umac_addr[port]); + REG_WR(bp, vals->umac_addr[port], 0); + + return true; +} + static void bnx2x_prev_unload_close_mac(struct bnx2x *bp, struct bnx2x_mac_vals *vals) { @@ -10149,10 +10168,7 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp, u8 port = BP_PORT(bp); /* reset addresses as they also mark which values were changed */ - vals->bmac_addr = 0; - vals->umac_addr = 0; - vals->xmac_addr = 0; - vals->emac_addr = 0; + memset(vals, 0, sizeof(*vals)); reset_reg = REG_RD(bp, MISC_REG_RESET_REG_2); @@ -10201,15 +10217,11 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp, REG_WR(bp, vals->xmac_addr, 0); mac_stopped = true; } - mask = MISC_REGISTERS_RESET_REG_2_UMAC0 << port; - if (mask & reset_reg) { - BNX2X_DEV_INFO("Disable umac Rx\n"); - base_addr = BP_PORT(bp) ? GRCBASE_UMAC1 : GRCBASE_UMAC0; - vals->umac_addr = base_addr + UMAC_REG_COMMAND_CONFIG; - vals->umac_val = REG_RD(bp, vals->umac_addr); - REG_WR(bp, vals->umac_addr, 0); - mac_stopped = true; - } + + mac_stopped |= bnx2x_prev_unload_close_umac(bp, 0, + reset_reg, vals); + mac_stopped |= bnx2x_prev_unload_close_umac(bp, 1, + reset_reg, vals); } if (mac_stopped) @@ -10505,8 +10517,11 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp) /* Close the MAC Rx to prevent BRB from filling up */ bnx2x_prev_unload_close_mac(bp, &mac_vals); - /* close LLH filters towards the BRB */ + /* close LLH filters for both ports towards the BRB */ + bnx2x_set_rx_filter(&bp->link_params, 0); + bp->link_params.port ^= 1; bnx2x_set_rx_filter(&bp->link_params, 0); + bp->link_params.port ^= 1; /* Check if the UNDI driver was previously loaded */ if (bnx2x_prev_is_after_undi(bp)) { @@ -10553,8 +10568,10 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp) if (mac_vals.xmac_addr) REG_WR(bp, mac_vals.xmac_addr, mac_vals.xmac_val); - if (mac_vals.umac_addr) - REG_WR(bp, mac_vals.umac_addr, mac_vals.umac_val); + if (mac_vals.umac_addr[0]) + REG_WR(bp, mac_vals.umac_addr[0], mac_vals.umac_val[0]); + if (mac_vals.umac_addr[1]) + REG_WR(bp, mac_vals.umac_addr[1], mac_vals.umac_val[1]); if (mac_vals.emac_addr) REG_WR(bp, mac_vals.emac_addr, mac_vals.emac_val); if (mac_vals.bmac_addr) { -- cgit v1.2.3 From da254fbc6357a66a127e4e4e234b4f9c555d5ed1 Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Wed, 1 Apr 2015 10:02:20 +0300 Subject: bnx2x: Fix kdump when iommu=on When IOMM-vtd is active, once main kernel crashes unfinished DMAE transactions will be blocked, putting the HW in an error state which will cause further transactions to timeout. Current employed logic uses wrong macros, causing the first function to be the only function that cleanups that error state during its probe/load. This patch allows all the functions to successfully re-load in kdump kernel. Signed-off-by: Yuval Mintz Signed-off-by: Ariel Elior Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 39 ++++++++++-------------- 1 file changed, 16 insertions(+), 23 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index e6dec47fec68..1ec635f54994 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -7866,6 +7866,20 @@ int bnx2x_init_hw_func_cnic(struct bnx2x *bp) return 0; } +/* previous driver DMAE transaction may have occurred when pre-boot stage ended + * and boot began, or when kdump kernel was loaded. Either case would invalidate + * the addresses of the transaction, resulting in was-error bit set in the pci + * causing all hw-to-host pcie transactions to timeout. If this happened we want + * to clear the interrupt which detected this from the pglueb and the was done + * bit + */ +static void bnx2x_clean_pglue_errors(struct bnx2x *bp) +{ + if (!CHIP_IS_E1x(bp)) + REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, + 1 << BP_ABS_FUNC(bp)); +} + static int bnx2x_init_hw_func(struct bnx2x *bp) { int port = BP_PORT(bp); @@ -7958,8 +7972,7 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) bnx2x_init_block(bp, BLOCK_PGLUE_B, init_phase); - if (!CHIP_IS_E1x(bp)) - REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, func); + bnx2x_clean_pglue_errors(bp); bnx2x_init_block(bp, BLOCK_ATC, init_phase); bnx2x_init_block(bp, BLOCK_DMAE, init_phase); @@ -10588,26 +10601,6 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp) return bnx2x_prev_mcp_done(bp); } -/* previous driver DMAE transaction may have occurred when pre-boot stage ended - * and boot began, or when kdump kernel was loaded. Either case would invalidate - * the addresses of the transaction, resulting in was-error bit set in the pci - * causing all hw-to-host pcie transactions to timeout. If this happened we want - * to clear the interrupt which detected this from the pglueb and the was done - * bit - */ -static void bnx2x_prev_interrupted_dmae(struct bnx2x *bp) -{ - if (!CHIP_IS_E1x(bp)) { - u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS); - if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) { - DP(BNX2X_MSG_SP, - "'was error' bit was found to be set in pglueb upon startup. Clearing\n"); - REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, - 1 << BP_FUNC(bp)); - } - } -} - static int bnx2x_prev_unload(struct bnx2x *bp) { int time_counter = 10; @@ -10617,7 +10610,7 @@ static int bnx2x_prev_unload(struct bnx2x *bp) /* clear hw from errors which may have resulted from an interrupted * dmae transaction. */ - bnx2x_prev_interrupted_dmae(bp); + bnx2x_clean_pglue_errors(bp); /* Release previously held locks */ hw_lock_reg = (BP_FUNC(bp) <= 5) ? -- cgit v1.2.3 From 8d88c6ebb34c3e54debe81e9b0d81b60411f8179 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Wed, 1 Apr 2015 00:40:00 -0700 Subject: net: bcmgenet: enable MoCA link state change detection Currently, MoCA fixed PHYs are always in link-up state, regardless of whether the link is actually up or not. Add code to properly detect MoCA link state changes and to reflect the new state in MoCA fixed PHY. Only GENET V3 and V4 MACs are capable of detecting MoCA link state changes. The code works as follows: 1. GENET MAC detects MoCA link state change and issues UMAC_IRQ_LINK_UP or UMAC_IRQ_LINK_DOWN interrupt. 2. Link up/down interrupt is processed in bcmgenet_irq_task(), which calls phy_mac_interrupt(). 3. phy_mac_interrupt() updates the fixed PHY phydev->link and kicks the PHY state machine. 4. PHY state machine proceeds to read the fixed PHY link status register. 5. When the fixed PHY link status register is being read, the new function bcmgenet_fixed_phy_link_update() gets called. It copies the fixed PHY phydev->link value to the fixed PHY status->link. 6. PHY state machine receives the new link state of the fixed PHY. 7. MoCA fixed PHY link state now correctly reflects the real MoCA hardware link state. Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 9 +++++++-- drivers/net/ethernet/broadcom/genet/bcmgenet.h | 1 + drivers/net/ethernet/broadcom/genet/bcmmii.c | 16 ++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index f7855a61e7ad..6043734ea613 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1734,6 +1734,9 @@ static int init_umac(struct bcmgenet_priv *priv) } else if (priv->ext_phy) { int0_enable |= UMAC_IRQ_LINK_EVENT; } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) { + if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET) + int0_enable |= UMAC_IRQ_LINK_EVENT; + reg = bcmgenet_bp_mc_get(priv); reg |= BIT(priv->hw_params->bp_in_en_shift); @@ -2926,7 +2929,8 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { .rdma_offset = 0x10000, .tdma_offset = 0x11000, .words_per_bd = 2, - .flags = GENET_HAS_EXT | GENET_HAS_MDIO_INTR, + .flags = GENET_HAS_EXT | GENET_HAS_MDIO_INTR | + GENET_HAS_MOCA_LINK_DET, }, [GENET_V4] = { .tx_queues = 4, @@ -2944,7 +2948,8 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { .rdma_offset = 0x2000, .tdma_offset = 0x4000, .words_per_bd = 3, - .flags = GENET_HAS_40BITS | GENET_HAS_EXT | GENET_HAS_MDIO_INTR, + .flags = GENET_HAS_40BITS | GENET_HAS_EXT | + GENET_HAS_MDIO_INTR | GENET_HAS_MOCA_LINK_DET, }, }; diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index ddaa40cb0f21..6f2887a5e0be 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -508,6 +508,7 @@ enum bcmgenet_version { #define GENET_HAS_40BITS (1 << 0) #define GENET_HAS_EXT (1 << 1) #define GENET_HAS_MDIO_INTR (1 << 2) +#define GENET_HAS_MOCA_LINK_DET (1 << 3) /* BCMGENET hardware parameters, keep this structure nicely aligned * since it is going to be used in hot paths diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index 6d3b66a103cc..e7651b3c6c57 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c @@ -462,6 +462,15 @@ static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv) return 0; } +static int bcmgenet_fixed_phy_link_update(struct net_device *dev, + struct fixed_phy_status *status) +{ + if (dev && dev->phydev && status) + status->link = dev->phydev->link; + + return 0; +} + static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv) { struct device *kdev = &priv->pdev->dev; @@ -513,6 +522,13 @@ static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv) dev_err(kdev, "failed to register fixed PHY device\n"); return -ENODEV; } + + if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET) { + ret = fixed_phy_set_link_update( + phydev, bcmgenet_fixed_phy_link_update); + if (!ret) + phydev->link = 0; + } } priv->phydev = phydev; -- cgit v1.2.3 From b38c83dd08665a93e439c4ffd9eef31bc098a6ea Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 14 Apr 2015 12:07:54 +0200 Subject: bgmac: simplify tx ring index handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep incrementing ring->start and ring->end instead of pointing it to the actual ring slot entry. This simplifies the calculation of the number of free slots. Signed-off-by: Felix Fietkau Acked-by: Rafał Miłecki Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.c | 46 +++++++++++++++-------------------- drivers/net/ethernet/broadcom/bgmac.h | 6 ++--- 2 files changed, 23 insertions(+), 29 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index fa8f9e147c34..b9e02e484d72 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -142,11 +142,10 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, { struct device *dma_dev = bgmac->core->dma_dev; struct net_device *net_dev = bgmac->net_dev; - struct bgmac_slot_info *slot = &ring->slots[ring->end]; - int free_slots; + int index = ring->end % BGMAC_TX_RING_SLOTS; + struct bgmac_slot_info *slot = &ring->slots[index]; int nr_frags; u32 flags; - int index = ring->end; int i; if (skb->len > BGMAC_DESC_CTL1_LEN) { @@ -159,12 +158,10 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, nr_frags = skb_shinfo(skb)->nr_frags; - if (ring->start <= ring->end) - free_slots = ring->start - ring->end + BGMAC_TX_RING_SLOTS; - else - free_slots = ring->start - ring->end; - - if (free_slots <= nr_frags + 1) { + /* ring->end - ring->start will return the number of valid slots, + * even when ring->end overflows + */ + if (ring->end - ring->start + nr_frags + 1 >= BGMAC_TX_RING_SLOTS) { bgmac_err(bgmac, "TX ring is full, queue should be stopped!\n"); netif_stop_queue(net_dev); return NETDEV_TX_BUSY; @@ -200,7 +197,7 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, } slot->skb = skb; - + ring->end += nr_frags + 1; netdev_sent_queue(net_dev, skb->len); wmb(); @@ -208,13 +205,12 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, /* Increase ring->end to point empty slot. We tell hardware the first * slot it should *not* read. */ - ring->end = (index + 1) % BGMAC_TX_RING_SLOTS; bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_INDEX, ring->index_base + - ring->end * sizeof(struct bgmac_dma_desc)); + (ring->end % BGMAC_TX_RING_SLOTS) * + sizeof(struct bgmac_dma_desc)); - free_slots -= nr_frags + 1; - if (free_slots < 8) + if (ring->end - ring->start >= BGMAC_TX_RING_SLOTS - 8) netif_stop_queue(net_dev); return NETDEV_TX_OK; @@ -256,17 +252,17 @@ static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring) empty_slot &= BGMAC_DMA_TX_STATDPTR; empty_slot /= sizeof(struct bgmac_dma_desc); - while (ring->start != empty_slot) { - struct bgmac_slot_info *slot = &ring->slots[ring->start]; - u32 ctl1 = le32_to_cpu(ring->cpu_base[ring->start].ctl1); - int len = ctl1 & BGMAC_DESC_CTL1_LEN; + while (ring->start != ring->end) { + int slot_idx = ring->start % BGMAC_TX_RING_SLOTS; + struct bgmac_slot_info *slot = &ring->slots[slot_idx]; + u32 ctl1; + int len; - if (!slot->dma_addr) { - bgmac_err(bgmac, "Hardware reported transmission for empty TX ring slot %d! End of ring: %d\n", - ring->start, ring->end); - goto next; - } + if (slot_idx == empty_slot) + break; + ctl1 = le32_to_cpu(ring->cpu_base[slot_idx].ctl1); + len = ctl1 & BGMAC_DESC_CTL1_LEN; if (ctl1 & BGMAC_DESC_CTL0_SOF) /* Unmap no longer used buffer */ dma_unmap_single(dma_dev, slot->dma_addr, len, @@ -284,10 +280,8 @@ static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring) slot->skb = NULL; } -next: slot->dma_addr = 0; - if (++ring->start >= BGMAC_TX_RING_SLOTS) - ring->start = 0; + ring->start++; freed = true; } diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index 3ad965fe7fcc..5a198d56f3e7 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -414,10 +414,10 @@ enum bgmac_dma_ring_type { * empty. */ struct bgmac_dma_ring { - u16 num_slots; - u16 start; - u16 end; + u32 start; + u32 end; + u16 num_slots; u16 mmio_base; struct bgmac_dma_desc *cpu_base; dma_addr_t dma_base; -- cgit v1.2.3 From eb64e2923a886441c7b322f138b36029f3fa6a36 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 14 Apr 2015 12:07:55 +0200 Subject: bgmac: leave interrupts disabled as long as there is work to do Always poll rx and tx during NAPI poll instead of relying on the status of the first interrupt. This prevents bgmac_poll from leaving unfinished work around until the next IRQ. In my tests this makes bridging/routing throughput under heavy load more stable and ensures that no new IRQs arrive as long as bgmac_poll uses up the entire budget. Signed-off-by: Felix Fietkau Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.c | 31 ++++++++++--------------------- drivers/net/ethernet/broadcom/bgmac.h | 1 - 2 files changed, 10 insertions(+), 22 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index b9e02e484d72..9c3b2ff33e63 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1109,8 +1109,6 @@ static void bgmac_chip_reset(struct bgmac *bgmac) bgmac_phy_init(bgmac); netdev_reset_queue(bgmac->net_dev); - - bgmac->int_status = 0; } static void bgmac_chip_intrs_on(struct bgmac *bgmac) @@ -1225,14 +1223,13 @@ static irqreturn_t bgmac_interrupt(int irq, void *dev_id) if (!int_status) return IRQ_NONE; - /* Ack */ - bgmac_write(bgmac, BGMAC_INT_STATUS, int_status); + int_status &= ~(BGMAC_IS_TX0 | BGMAC_IS_RX); + if (int_status) + bgmac_err(bgmac, "Unknown IRQs: 0x%08X\n", int_status); /* Disable new interrupts until handling existing ones */ bgmac_chip_intrs_off(bgmac); - bgmac->int_status = int_status; - napi_schedule(&bgmac->napi); return IRQ_HANDLED; @@ -1241,25 +1238,17 @@ static irqreturn_t bgmac_interrupt(int irq, void *dev_id) static int bgmac_poll(struct napi_struct *napi, int weight) { struct bgmac *bgmac = container_of(napi, struct bgmac, napi); - struct bgmac_dma_ring *ring; int handled = 0; - if (bgmac->int_status & BGMAC_IS_TX0) { - ring = &bgmac->tx_ring[0]; - bgmac_dma_tx_free(bgmac, ring); - bgmac->int_status &= ~BGMAC_IS_TX0; - } + /* Ack */ + bgmac_write(bgmac, BGMAC_INT_STATUS, ~0); - if (bgmac->int_status & BGMAC_IS_RX) { - ring = &bgmac->rx_ring[0]; - handled += bgmac_dma_rx_read(bgmac, ring, weight); - bgmac->int_status &= ~BGMAC_IS_RX; - } + bgmac_dma_tx_free(bgmac, &bgmac->tx_ring[0]); + handled += bgmac_dma_rx_read(bgmac, &bgmac->rx_ring[0], weight); - if (bgmac->int_status) { - bgmac_err(bgmac, "Unknown IRQs: 0x%08X\n", bgmac->int_status); - bgmac->int_status = 0; - } + /* Poll again if more events arrived in the meantime */ + if (bgmac_read(bgmac, BGMAC_INT_STATUS) & (BGMAC_IS_TX0 | BGMAC_IS_RX)) + return handled; if (handled < weight) { napi_complete(napi); diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index 5a198d56f3e7..abd50d128e6c 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -452,7 +452,6 @@ struct bgmac { /* Int */ u32 int_mask; - u32 int_status; /* Current MAC state */ int mac_speed; -- cgit v1.2.3 From 4b62dce450e2447146ff6924a1ce8ad1a6592107 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 14 Apr 2015 12:07:56 +0200 Subject: bgmac: set received skb headroom to NET_SKB_PAD A packet buffer offset of 30 bytes is inefficient, because the first 2 bytes end up in a different cacheline. Signed-off-by: Felix Fietkau Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.c | 14 ++++++++------ drivers/net/ethernet/broadcom/bgmac.h | 4 +++- 2 files changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 9c3b2ff33e63..424a68ce5aa0 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -346,13 +346,13 @@ static int bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac, return -ENOMEM; /* Poison - if everything goes fine, hardware will overwrite it */ - rx = buf; + rx = buf + BGMAC_RX_BUF_OFFSET; rx->len = cpu_to_le16(0xdead); rx->flags = cpu_to_le16(0xbeef); /* Map skb for the DMA */ - dma_addr = dma_map_single(dma_dev, buf, BGMAC_RX_BUF_SIZE, - DMA_FROM_DEVICE); + dma_addr = dma_map_single(dma_dev, buf + BGMAC_RX_BUF_OFFSET, + BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); if (dma_mapping_error(dma_dev, dma_addr)) { bgmac_err(bgmac, "DMA mapping error\n"); put_page(virt_to_head_page(buf)); @@ -403,7 +403,7 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, while (ring->start != ring->end) { struct device *dma_dev = bgmac->core->dma_dev; struct bgmac_slot_info *slot = &ring->slots[ring->start]; - struct bgmac_rx_header *rx = slot->buf; + struct bgmac_rx_header *rx = slot->buf + BGMAC_RX_BUF_OFFSET; struct sk_buff *skb; void *buf = slot->buf; u16 len, flags; @@ -454,8 +454,10 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); skb = build_skb(buf, BGMAC_RX_ALLOC_SIZE); - skb_put(skb, BGMAC_RX_FRAME_OFFSET + len); - skb_pull(skb, BGMAC_RX_FRAME_OFFSET); + skb_put(skb, BGMAC_RX_FRAME_OFFSET + + BGMAC_RX_BUF_OFFSET + len); + skb_pull(skb, BGMAC_RX_FRAME_OFFSET + + BGMAC_RX_BUF_OFFSET); skb_checksum_none_assert(skb); skb->protocol = eth_type_trans(skb, bgmac->net_dev); diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index abd50d128e6c..3db0d5211c5d 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -360,9 +360,11 @@ #define BGMAC_RX_HEADER_LEN 28 /* Last 24 bytes are unused. Well... */ #define BGMAC_RX_FRAME_OFFSET 30 /* There are 2 unused bytes between header and real data */ +#define BGMAC_RX_BUF_OFFSET (NET_SKB_PAD + NET_IP_ALIGN - \ + BGMAC_RX_FRAME_OFFSET) #define BGMAC_RX_MAX_FRAME_SIZE 1536 /* Copied from b44/tg3 */ #define BGMAC_RX_BUF_SIZE (BGMAC_RX_FRAME_OFFSET + BGMAC_RX_MAX_FRAME_SIZE) -#define BGMAC_RX_ALLOC_SIZE (SKB_DATA_ALIGN(BGMAC_RX_BUF_SIZE) + \ +#define BGMAC_RX_ALLOC_SIZE (SKB_DATA_ALIGN(BGMAC_RX_BUF_SIZE + BGMAC_RX_BUF_OFFSET) + \ SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) #define BGMAC_BFL_ENETROBO 0x0010 /* has ephy roboswitch spi */ -- cgit v1.2.3 From 56faacd04509f0a60ed646473a930fe584f1cb02 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 14 Apr 2015 12:07:57 +0200 Subject: bgmac: simplify/optimize rx DMA error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allocate a new buffer before processing the completed one. If allocation fails, reuse the old buffer. Signed-off-by: Felix Fietkau Acked-by: Rafał Miłecki Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.c | 71 +++++++++++++++++------------------ 1 file changed, 34 insertions(+), 37 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 424a68ce5aa0..60b5c3ca8551 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -386,6 +386,19 @@ static void bgmac_dma_rx_setup_desc(struct bgmac *bgmac, dma_desc->ctl1 = cpu_to_le32(ctl1); } +static void bgmac_dma_rx_poison_buf(struct device *dma_dev, + struct bgmac_slot_info *slot) +{ + struct bgmac_rx_header *rx = slot->buf + BGMAC_RX_BUF_OFFSET; + + dma_sync_single_for_cpu(dma_dev, slot->dma_addr, BGMAC_RX_BUF_SIZE, + DMA_FROM_DEVICE); + rx->len = cpu_to_le16(0xdead); + rx->flags = cpu_to_le16(0xbeef); + dma_sync_single_for_device(dma_dev, slot->dma_addr, BGMAC_RX_BUF_SIZE, + DMA_FROM_DEVICE); +} + static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, int weight) { @@ -406,53 +419,35 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, struct bgmac_rx_header *rx = slot->buf + BGMAC_RX_BUF_OFFSET; struct sk_buff *skb; void *buf = slot->buf; + dma_addr_t dma_addr = slot->dma_addr; u16 len, flags; - /* Unmap buffer to make it accessible to the CPU */ - dma_sync_single_for_cpu(dma_dev, slot->dma_addr, - BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); + do { + /* Prepare new skb as replacement */ + if (bgmac_dma_rx_skb_for_slot(bgmac, slot)) { + bgmac_dma_rx_poison_buf(dma_dev, slot); + break; + } - /* Get info from the header */ - len = le16_to_cpu(rx->len); - flags = le16_to_cpu(rx->flags); + /* Unmap buffer to make it accessible to the CPU */ + dma_unmap_single(dma_dev, dma_addr, + BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); - do { - dma_addr_t old_dma_addr = slot->dma_addr; - int err; + /* Get info from the header */ + len = le16_to_cpu(rx->len); + flags = le16_to_cpu(rx->flags); /* Check for poison and drop or pass the packet */ if (len == 0xdead && flags == 0xbeef) { bgmac_err(bgmac, "Found poisoned packet at slot %d, DMA issue!\n", ring->start); - dma_sync_single_for_device(dma_dev, - slot->dma_addr, - BGMAC_RX_BUF_SIZE, - DMA_FROM_DEVICE); + put_page(virt_to_head_page(buf)); break; } /* Omit CRC. */ len -= ETH_FCS_LEN; - /* Prepare new skb as replacement */ - err = bgmac_dma_rx_skb_for_slot(bgmac, slot); - if (err) { - /* Poison the old skb */ - rx->len = cpu_to_le16(0xdead); - rx->flags = cpu_to_le16(0xbeef); - - dma_sync_single_for_device(dma_dev, - slot->dma_addr, - BGMAC_RX_BUF_SIZE, - DMA_FROM_DEVICE); - break; - } - bgmac_dma_rx_setup_desc(bgmac, ring, ring->start); - - /* Unmap old skb, we'll pass it to the netfif */ - dma_unmap_single(dma_dev, old_dma_addr, - BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); - skb = build_skb(buf, BGMAC_RX_ALLOC_SIZE); skb_put(skb, BGMAC_RX_FRAME_OFFSET + BGMAC_RX_BUF_OFFSET + len); @@ -465,6 +460,8 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, handled++; } while (0); + bgmac_dma_rx_setup_desc(bgmac, ring, ring->start); + if (++ring->start >= BGMAC_RX_RING_SLOTS) ring->start = 0; @@ -532,14 +529,14 @@ static void bgmac_dma_rx_ring_free(struct bgmac *bgmac, for (i = 0; i < ring->num_slots; i++) { slot = &ring->slots[i]; - if (!slot->buf) + if (!slot->dma_addr) continue; - if (slot->dma_addr) - dma_unmap_single(dma_dev, slot->dma_addr, - BGMAC_RX_BUF_SIZE, - DMA_FROM_DEVICE); + dma_unmap_single(dma_dev, slot->dma_addr, + BGMAC_RX_BUF_SIZE, + DMA_FROM_DEVICE); put_page(virt_to_head_page(slot->buf)); + slot->dma_addr = 0; } } -- cgit v1.2.3 From 6a6c708469c9e10fd87adcc3abff164270538d62 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 14 Apr 2015 12:07:58 +0200 Subject: bgmac: add check for oversized packets In very rare cases, the MAC can catch an internal buffer that is bigger than it's supposed to be. Instead of crashing the kernel, simply pass the buffer back to the hardware Signed-off-by: Felix Fietkau Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 60b5c3ca8551..5a20108c80e5 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -445,6 +445,13 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, break; } + if (len > BGMAC_RX_ALLOC_SIZE) { + bgmac_err(bgmac, "Found oversized packet at slot %d, DMA issue!\n", + ring->start); + put_page(virt_to_head_page(buf)); + break; + } + /* Omit CRC. */ len -= ETH_FCS_LEN; -- cgit v1.2.3 From b9650557f3d58924e3be040df0ff7a3dae19ad83 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 14 Apr 2015 12:07:59 +0200 Subject: bgmac: increase rx ring size from 511 to 512 Limiting it to 511 looks like a failed attempt at leaving one descriptor empty to allow the hardware to stop processing a buffer that has not been prepared yet. However, this doesn't work because this affects the total ring size as well Signed-off-by: Felix Fietkau Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index 3db0d5211c5d..e45e303ebc22 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -356,7 +356,7 @@ #define BGMAC_MAX_RX_RINGS 1 #define BGMAC_TX_RING_SLOTS 128 -#define BGMAC_RX_RING_SLOTS 512 - 1 /* Why -1? Well, Broadcom does that... */ +#define BGMAC_RX_RING_SLOTS 512 #define BGMAC_RX_HEADER_LEN 28 /* Last 24 bytes are unused. Well... */ #define BGMAC_RX_FRAME_OFFSET 30 /* There are 2 unused bytes between header and real data */ -- cgit v1.2.3 From 74b6f29163490d88ff53f7c54d0e4514bbf1630b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 14 Apr 2015 12:08:00 +0200 Subject: bgmac: simplify dma init/cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of allocating buffers at device init time and initializing descriptors at device open, do both at the same time (during open). Free all buffers when closing the device. Signed-off-by: Felix Fietkau Acked-by: Rafał Miłecki Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.c | 79 ++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 39 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 5a20108c80e5..79216d6cc0c9 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -562,18 +562,26 @@ static void bgmac_dma_ring_desc_free(struct bgmac *bgmac, ring->dma_base); } -static void bgmac_dma_free(struct bgmac *bgmac) +static void bgmac_dma_cleanup(struct bgmac *bgmac) { int i; - for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) { + for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) bgmac_dma_tx_ring_free(bgmac, &bgmac->tx_ring[i]); - bgmac_dma_ring_desc_free(bgmac, &bgmac->tx_ring[i]); - } - for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) { + + for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) bgmac_dma_rx_ring_free(bgmac, &bgmac->rx_ring[i]); +} + +static void bgmac_dma_free(struct bgmac *bgmac) +{ + int i; + + for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) + bgmac_dma_ring_desc_free(bgmac, &bgmac->tx_ring[i]); + + for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) bgmac_dma_ring_desc_free(bgmac, &bgmac->rx_ring[i]); - } } static int bgmac_dma_alloc(struct bgmac *bgmac) @@ -621,8 +629,6 @@ static int bgmac_dma_alloc(struct bgmac *bgmac) } for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) { - int j; - ring = &bgmac->rx_ring[i]; ring->num_slots = BGMAC_RX_RING_SLOTS; ring->mmio_base = ring_base[i]; @@ -645,15 +651,6 @@ static int bgmac_dma_alloc(struct bgmac *bgmac) ring->index_base = lower_32_bits(ring->dma_base); else ring->index_base = 0; - - /* Alloc RX slots */ - for (j = 0; j < ring->num_slots; j++) { - err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[j]); - if (err) { - bgmac_err(bgmac, "Can't allocate skb for slot in RX ring\n"); - goto err_dma_free; - } - } } return 0; @@ -663,10 +660,10 @@ err_dma_free: return -ENOMEM; } -static void bgmac_dma_init(struct bgmac *bgmac) +static int bgmac_dma_init(struct bgmac *bgmac) { struct bgmac_dma_ring *ring; - int i; + int i, err; for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) { ring = &bgmac->tx_ring[i]; @@ -698,8 +695,13 @@ static void bgmac_dma_init(struct bgmac *bgmac) if (ring->unaligned) bgmac_dma_rx_enable(bgmac, ring); - for (j = 0; j < ring->num_slots; j++) + for (j = 0; j < ring->num_slots; j++) { + err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[j]); + if (err) + goto error; + bgmac_dma_rx_setup_desc(bgmac, ring, j); + } bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX, ring->index_base + @@ -708,6 +710,12 @@ static void bgmac_dma_init(struct bgmac *bgmac) ring->start = 0; ring->end = 0; } + + return 0; + +error: + bgmac_dma_cleanup(bgmac); + return err; } /************************************************** @@ -1183,11 +1191,8 @@ static void bgmac_enable(struct bgmac *bgmac) } /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */ -static void bgmac_chip_init(struct bgmac *bgmac, bool full_init) +static void bgmac_chip_init(struct bgmac *bgmac) { - struct bgmac_dma_ring *ring; - int i; - /* 1 interrupt per received frame */ bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT); @@ -1205,16 +1210,7 @@ static void bgmac_chip_init(struct bgmac *bgmac, bool full_init) bgmac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + ETHER_MAX_LEN); - if (full_init) { - bgmac_dma_init(bgmac); - if (1) /* FIXME: is there any case we don't want IRQs? */ - bgmac_chip_intrs_on(bgmac); - } else { - for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) { - ring = &bgmac->rx_ring[i]; - bgmac_dma_rx_enable(bgmac, ring); - } - } + bgmac_chip_intrs_on(bgmac); bgmac_enable(bgmac); } @@ -1274,23 +1270,27 @@ static int bgmac_open(struct net_device *net_dev) int err = 0; bgmac_chip_reset(bgmac); + + err = bgmac_dma_init(bgmac); + if (err) + return err; + /* Specs say about reclaiming rings here, but we do that in DMA init */ - bgmac_chip_init(bgmac, true); + bgmac_chip_init(bgmac); err = request_irq(bgmac->core->irq, bgmac_interrupt, IRQF_SHARED, KBUILD_MODNAME, net_dev); if (err < 0) { bgmac_err(bgmac, "IRQ request error: %d!\n", err); - goto err_out; + bgmac_dma_cleanup(bgmac); + return err; } napi_enable(&bgmac->napi); phy_start(bgmac->phy_dev); netif_carrier_on(net_dev); - -err_out: - return err; + return 0; } static int bgmac_stop(struct net_device *net_dev) @@ -1306,6 +1306,7 @@ static int bgmac_stop(struct net_device *net_dev) free_irq(bgmac->core->irq, net_dev); bgmac_chip_reset(bgmac); + bgmac_dma_cleanup(bgmac); return 0; } -- cgit v1.2.3 From 4668ae1fbcab89af5ffbb161d4c70b25ce4c50f4 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 14 Apr 2015 12:08:01 +0200 Subject: bgmac: fix DMA rx corruption The driver needs to inform the hardware about the first invalid (not yet filled) rx slot, by writing its DMA descriptor pointer offset to the BGMAC_DMA_RX_INDEX register. This register was set to a value exceeding the rx ring size, effectively allowing the hardware constant access to the full ring, regardless of which slots are initialized. To fix this issue, always mark the last filled rx slot as invalid. Signed-off-by: Felix Fietkau Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 79216d6cc0c9..29af9e656a7a 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -366,6 +366,16 @@ static int bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac, return 0; } +static void bgmac_dma_rx_update_index(struct bgmac *bgmac, + struct bgmac_dma_ring *ring) +{ + dma_wmb(); + + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX, + ring->index_base + + ring->end * sizeof(struct bgmac_dma_desc)); +} + static void bgmac_dma_rx_setup_desc(struct bgmac *bgmac, struct bgmac_dma_ring *ring, int desc_idx) { @@ -384,6 +394,8 @@ static void bgmac_dma_rx_setup_desc(struct bgmac *bgmac, dma_desc->addr_high = cpu_to_le32(upper_32_bits(ring->slots[desc_idx].dma_addr)); dma_desc->ctl0 = cpu_to_le32(ctl0); dma_desc->ctl1 = cpu_to_le32(ctl1); + + ring->end = desc_idx; } static void bgmac_dma_rx_poison_buf(struct device *dma_dev, @@ -411,9 +423,7 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, end_slot &= BGMAC_DMA_RX_STATDPTR; end_slot /= sizeof(struct bgmac_dma_desc); - ring->end = end_slot; - - while (ring->start != ring->end) { + while (ring->start != end_slot) { struct device *dma_dev = bgmac->core->dma_dev; struct bgmac_slot_info *slot = &ring->slots[ring->start]; struct bgmac_rx_header *rx = slot->buf + BGMAC_RX_BUF_OFFSET; @@ -476,6 +486,8 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, break; } + bgmac_dma_rx_update_index(bgmac, ring); + return handled; } @@ -695,6 +707,8 @@ static int bgmac_dma_init(struct bgmac *bgmac) if (ring->unaligned) bgmac_dma_rx_enable(bgmac, ring); + ring->start = 0; + ring->end = 0; for (j = 0; j < ring->num_slots; j++) { err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[j]); if (err) @@ -703,12 +717,7 @@ static int bgmac_dma_init(struct bgmac *bgmac) bgmac_dma_rx_setup_desc(bgmac, ring, j); } - bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX, - ring->index_base + - ring->num_slots * sizeof(struct bgmac_dma_desc)); - - ring->start = 0; - ring->end = 0; + bgmac_dma_rx_update_index(bgmac, ring); } return 0; -- cgit v1.2.3 From 29ba877e7c8092a4dd3cbef80cca4e857129ca55 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 14 Apr 2015 12:08:02 +0200 Subject: bgmac: drop ring->num_slots The ring size is always known at compile time, so make the code a bit more efficient Signed-off-by: Felix Fietkau Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.c | 27 ++++++++++++++------------- drivers/net/ethernet/broadcom/bgmac.h | 3 +-- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 29af9e656a7a..5cb93d1f50a4 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -123,7 +123,7 @@ bgmac_dma_tx_add_buf(struct bgmac *bgmac, struct bgmac_dma_ring *ring, struct bgmac_dma_desc *dma_desc; u32 ctl1; - if (i == ring->num_slots - 1) + if (i == BGMAC_TX_RING_SLOTS - 1) ctl0 |= BGMAC_DESC_CTL0_EOT; ctl1 = len & BGMAC_DESC_CTL1_LEN; @@ -382,7 +382,7 @@ static void bgmac_dma_rx_setup_desc(struct bgmac *bgmac, struct bgmac_dma_desc *dma_desc = ring->cpu_base + desc_idx; u32 ctl0 = 0, ctl1 = 0; - if (desc_idx == ring->num_slots - 1) + if (desc_idx == BGMAC_RX_RING_SLOTS - 1) ctl0 |= BGMAC_DESC_CTL0_EOT; ctl1 |= BGMAC_RX_BUF_SIZE & BGMAC_DESC_CTL1_LEN; /* Is there any BGMAC device that requires extension? */ @@ -521,7 +521,7 @@ static void bgmac_dma_tx_ring_free(struct bgmac *bgmac, struct bgmac_slot_info *slot; int i; - for (i = 0; i < ring->num_slots; i++) { + for (i = 0; i < BGMAC_TX_RING_SLOTS; i++) { int len = dma_desc[i].ctl1 & BGMAC_DESC_CTL1_LEN; slot = &ring->slots[i]; @@ -546,7 +546,7 @@ static void bgmac_dma_rx_ring_free(struct bgmac *bgmac, struct bgmac_slot_info *slot; int i; - for (i = 0; i < ring->num_slots; i++) { + for (i = 0; i < BGMAC_RX_RING_SLOTS; i++) { slot = &ring->slots[i]; if (!slot->dma_addr) continue; @@ -560,7 +560,8 @@ static void bgmac_dma_rx_ring_free(struct bgmac *bgmac, } static void bgmac_dma_ring_desc_free(struct bgmac *bgmac, - struct bgmac_dma_ring *ring) + struct bgmac_dma_ring *ring, + int num_slots) { struct device *dma_dev = bgmac->core->dma_dev; int size; @@ -569,7 +570,7 @@ static void bgmac_dma_ring_desc_free(struct bgmac *bgmac, return; /* Free ring of descriptors */ - size = ring->num_slots * sizeof(struct bgmac_dma_desc); + size = num_slots * sizeof(struct bgmac_dma_desc); dma_free_coherent(dma_dev, size, ring->cpu_base, ring->dma_base); } @@ -590,10 +591,12 @@ static void bgmac_dma_free(struct bgmac *bgmac) int i; for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) - bgmac_dma_ring_desc_free(bgmac, &bgmac->tx_ring[i]); + bgmac_dma_ring_desc_free(bgmac, &bgmac->tx_ring[i], + BGMAC_TX_RING_SLOTS); for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) - bgmac_dma_ring_desc_free(bgmac, &bgmac->rx_ring[i]); + bgmac_dma_ring_desc_free(bgmac, &bgmac->rx_ring[i], + BGMAC_RX_RING_SLOTS); } static int bgmac_dma_alloc(struct bgmac *bgmac) @@ -616,11 +619,10 @@ static int bgmac_dma_alloc(struct bgmac *bgmac) for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) { ring = &bgmac->tx_ring[i]; - ring->num_slots = BGMAC_TX_RING_SLOTS; ring->mmio_base = ring_base[i]; /* Alloc ring of descriptors */ - size = ring->num_slots * sizeof(struct bgmac_dma_desc); + size = BGMAC_TX_RING_SLOTS * sizeof(struct bgmac_dma_desc); ring->cpu_base = dma_zalloc_coherent(dma_dev, size, &ring->dma_base, GFP_KERNEL); @@ -642,11 +644,10 @@ static int bgmac_dma_alloc(struct bgmac *bgmac) for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) { ring = &bgmac->rx_ring[i]; - ring->num_slots = BGMAC_RX_RING_SLOTS; ring->mmio_base = ring_base[i]; /* Alloc ring of descriptors */ - size = ring->num_slots * sizeof(struct bgmac_dma_desc); + size = BGMAC_RX_RING_SLOTS * sizeof(struct bgmac_dma_desc); ring->cpu_base = dma_zalloc_coherent(dma_dev, size, &ring->dma_base, GFP_KERNEL); @@ -709,7 +710,7 @@ static int bgmac_dma_init(struct bgmac *bgmac) ring->start = 0; ring->end = 0; - for (j = 0; j < ring->num_slots; j++) { + for (j = 0; j < BGMAC_RX_RING_SLOTS; j++) { err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[j]); if (err) goto error; diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index e45e303ebc22..db27febbb215 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -419,11 +419,10 @@ struct bgmac_dma_ring { u32 start; u32 end; - u16 num_slots; - u16 mmio_base; struct bgmac_dma_desc *cpu_base; dma_addr_t dma_base; u32 index_base; /* Used for unaligned rings only, otherwise 0 */ + u16 mmio_base; bool unaligned; struct bgmac_slot_info slots[BGMAC_RX_RING_SLOTS]; -- cgit v1.2.3 From 074975d0374333f656c48487aa046a21a9b9d7a1 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 14 Apr 2015 18:45:00 -0700 Subject: bnx2x: Fix busy_poll vs netpoll Commit 9a2620c877454 ("bnx2x: prevent WARN during driver unload") switched the napi/busy_lock locking mechanism from spin_lock() into spin_lock_bh(), breaking inter-operability with netconsole, as netpoll disables interrupts prior to calling our napi mechanism. This switches the driver into using atomic assignments instead of the spinlock mechanisms previously employed. Based on initial patch from Yuval Mintz & Ariel Elior I basically added softirq starvation avoidance, and mixture of atomic operations, plain writes and barriers. Note this slightly reduces the overhead for this driver when no busy_poll sockets are in use. Fixes: 9a2620c877454 ("bnx2x: prevent WARN during driver unload") Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 137 +++++++++--------------- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 9 +- 2 files changed, 56 insertions(+), 90 deletions(-) (limited to 'drivers/net/ethernet/broadcom') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 4085c4b31047..355d5fea5be9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -531,20 +531,8 @@ struct bnx2x_fastpath { struct napi_struct napi; #ifdef CONFIG_NET_RX_BUSY_POLL - unsigned int state; -#define BNX2X_FP_STATE_IDLE 0 -#define BNX2X_FP_STATE_NAPI (1 << 0) /* NAPI owns this FP */ -#define BNX2X_FP_STATE_POLL (1 << 1) /* poll owns this FP */ -#define BNX2X_FP_STATE_DISABLED (1 << 2) -#define BNX2X_FP_STATE_NAPI_YIELD (1 << 3) /* NAPI yielded this FP */ -#define BNX2X_FP_STATE_POLL_YIELD (1 << 4) /* poll yielded this FP */ -#define BNX2X_FP_OWNED (BNX2X_FP_STATE_NAPI | BNX2X_FP_STATE_POLL) -#define BNX2X_FP_YIELD (BNX2X_FP_STATE_NAPI_YIELD | BNX2X_FP_STATE_POLL_YIELD) -#define BNX2X_FP_LOCKED (BNX2X_FP_OWNED | BNX2X_FP_STATE_DISABLED) -#define BNX2X_FP_USER_PEND (BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_POLL_YIELD) - /* protect state */ - spinlock_t lock; -#endif /* CONFIG_NET_RX_BUSY_POLL */ + unsigned long busy_poll_state; +#endif union host_hc_status_block status_blk; /* chip independent shortcuts into sb structure */ @@ -619,104 +607,83 @@ struct bnx2x_fastpath { #define bnx2x_fp_qstats(bp, fp) (&((bp)->fp_stats[(fp)->index].eth_q_stats)) #ifdef CONFIG_NET_RX_BUSY_POLL -static inline void bnx2x_fp_init_lock(struct bnx2x_fastpath *fp) + +enum bnx2x_fp_state { + BNX2X_STATE_FP_NAPI = BIT(0), /* NAPI handler owns the queue */ + + BNX2X_STATE_FP_NAPI_REQ_BIT = 1, /* NAPI would like to own the queue */ + BNX2X_STATE_FP_NAPI_REQ = BIT(1), + + BNX2X_STATE_FP_POLL_BIT = 2, + BNX2X_STATE_FP_POLL = BIT(2), /* busy_poll owns the queue */ + + BNX2X_STATE_FP_DISABLE_BIT = 3, /* queue is dismantled */ +}; + +static inline void bnx2x_fp_busy_poll_init(struct bnx2x_fastpath *fp) { - spin_lock_init(&fp->lock); - fp->state = BNX2X_FP_STATE_IDLE; + WRITE_ONCE(fp->busy_poll_state, 0); } /* called from the device poll routine to get ownership of a FP */ static inline bool bnx2x_fp_lock_napi(struct bnx2x_fastpath *fp) { - bool rc = true; - - spin_lock_bh(&fp->lock); - if (fp->state & BNX2X_FP_LOCKED) { - WARN_ON(fp->state & BNX2X_FP_STATE_NAPI); - fp->state |= BNX2X_FP_STATE_NAPI_YIELD; - rc = false; - } else { - /* we don't care if someone yielded */ - fp->state = BNX2X_FP_STATE_NAPI; + unsigned long prev, old = READ_ONCE(fp->busy_poll_state); + + while (1) { + switch (old) { + case BNX2X_STATE_FP_POLL: + /* make sure bnx2x_fp_lock_poll() wont starve us */ + set_bit(BNX2X_STATE_FP_NAPI_REQ_BIT, + &fp->busy_poll_state); + /* fallthrough */ + case BNX2X_STATE_FP_POLL | BNX2X_STATE_FP_NAPI_REQ: + return false; + default: + break; + } + prev = cmpxchg(&fp->busy_poll_state, old, BNX2X_STATE_FP_NAPI); + if (unlikely(prev != old)) { + old = prev; + continue; + } + return true; } - spin_unlock_bh(&fp->lock); - return rc; } -/* returns true is someone tried to get the FP while napi had it */ -static inline bool bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp) +static inline void bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp) { - bool rc = false; - - spin_lock_bh(&fp->lock); - WARN_ON(fp->state & - (BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_NAPI_YIELD)); - - if (fp->state & BNX2X_FP_STATE_POLL_YIELD) - rc = true; - - /* state ==> idle, unless currently disabled */ - fp->state &= BNX2X_FP_STATE_DISABLED; - spin_unlock_bh(&fp->lock); - return rc; + smp_wmb(); + fp->busy_poll_state = 0; } /* called from bnx2x_low_latency_poll() */ static inline bool bnx2x_fp_lock_poll(struct bnx2x_fastpath *fp) { - bool rc = true; - - spin_lock_bh(&fp->lock); - if ((fp->state & BNX2X_FP_LOCKED)) { - fp->state |= BNX2X_FP_STATE_POLL_YIELD; - rc = false; - } else { - /* preserve yield marks */ - fp->state |= BNX2X_FP_STATE_POLL; - } - spin_unlock_bh(&fp->lock); - return rc; + return cmpxchg(&fp->busy_poll_state, 0, BNX2X_STATE_FP_POLL) == 0; } -/* returns true if someone tried to get the FP while it was locked */ -static inline bool bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp) +static inline void bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp) { - bool rc = false; - - spin_lock_bh(&fp->lock); - WARN_ON(fp->state & BNX2X_FP_STATE_NAPI); - - if (fp->state & BNX2X_FP_STATE_POLL_YIELD) - rc = true; - - /* state ==> idle, unless currently disabled */ - fp->state &= BNX2X_FP_STATE_DISABLED; - spin_unlock_bh(&fp->lock); - return rc; + smp_mb__before_atomic(); + clear_bit(BNX2X_STATE_FP_POLL_BIT, &fp->busy_poll_state); } -/* true if a socket is polling, even if it did not get the lock */ +/* true if a socket is polling */ static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp) { - WARN_ON(!(fp->state & BNX2X_FP_OWNED)); - return fp->state & BNX2X_FP_USER_PEND; + return READ_ONCE(fp->busy_poll_state) & BNX2X_STATE_FP_POLL; } /* false if fp is currently owned */ static inline bool bnx2x_fp_ll_disable(struct bnx2x_fastpath *fp) { - int rc = true; - - spin_lock_bh(&fp->lock); - if (fp->state & BNX2X_FP_OWNED) - rc = false; - fp->state |= BNX2X_FP_STATE_DISABLED; - spin_unlock_bh(&fp->lock); + set_bit(BNX2X_STATE_FP_DISABLE_BIT, &fp->busy_poll_state); + return !bnx2x_fp_ll_polling(fp); - return rc; } #else -static inline void bnx2x_fp_init_lock(struct bnx2x_fastpath *fp) +static inline void bnx2x_fp_busy_poll_init(struct bnx2x_fastpath *fp) { } @@ -725,9 +692,8 @@ static inline bool bnx2x_fp_lock_napi(struct bnx2x_fastpath *fp) return true; } -static inline bool bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp) +static inline void bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp) { - return false; } static inline bool bnx2x_fp_lock_poll(struct bnx2x_fastpath *fp) @@ -735,9 +701,8 @@ static inline bool bnx2x_fp_lock_poll(struct bnx2x_fastpath *fp) return false; } -static inline bool bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp) +static inline void bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp) { - return false; } static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 0a9faa134a9a..2f63467bce46 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -1849,7 +1849,7 @@ static void bnx2x_napi_enable_cnic(struct bnx2x *bp) int i; for_each_rx_queue_cnic(bp, i) { - bnx2x_fp_init_lock(&bp->fp[i]); + bnx2x_fp_busy_poll_init(&bp->fp[i]); napi_enable(&bnx2x_fp(bp, i, napi)); } } @@ -1859,7 +1859,7 @@ static void bnx2x_napi_enable(struct bnx2x *bp) int i; for_each_eth_queue(bp, i) { - bnx2x_fp_init_lock(&bp->fp[i]); + bnx2x_fp_busy_poll_init(&bp->fp[i]); napi_enable(&bnx2x_fp(bp, i, napi)); } } @@ -3191,9 +3191,10 @@ static int bnx2x_poll(struct napi_struct *napi, int budget) } } + bnx2x_fp_unlock_napi(fp); + /* Fall out from the NAPI loop if needed */ - if (!bnx2x_fp_unlock_napi(fp) && - !(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { + if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { /* No need to update SB for FCoE L2 ring as long as * it's connected to the default SB and the SB -- cgit v1.2.3