diff options
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 50 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | 15 | ||||
-rw-r--r-- | drivers/net/ethernet/cadence/Kconfig | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/lantiq_etop.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/marvell/sky2.c | 106 | ||||
-rw-r--r-- | drivers/net/ethernet/marvell/sky2.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_rx.c | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/nvidia/forcedeth.c | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/rdc/r6040.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/smsc/smsc911x.c | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 117 | ||||
-rw-r--r-- | drivers/net/ethernet/xilinx/ll_temac_main.c | 7 |
18 files changed, 224 insertions, 120 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 9090afc7532..83481e20f14 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -10574,33 +10574,38 @@ do { \ int bnx2x_init_firmware(struct bnx2x *bp) { - const char *fw_file_name; struct bnx2x_fw_file_hdr *fw_hdr; int rc; - if (CHIP_IS_E1(bp)) - fw_file_name = FW_FILE_NAME_E1; - else if (CHIP_IS_E1H(bp)) - fw_file_name = FW_FILE_NAME_E1H; - else if (!CHIP_IS_E1x(bp)) - fw_file_name = FW_FILE_NAME_E2; - else { - BNX2X_ERR("Unsupported chip revision\n"); - return -EINVAL; - } - BNX2X_DEV_INFO("Loading %s\n", fw_file_name); + if (!bp->firmware) { + const char *fw_file_name; - rc = request_firmware(&bp->firmware, fw_file_name, &bp->pdev->dev); - if (rc) { - BNX2X_ERR("Can't load firmware file %s\n", fw_file_name); - goto request_firmware_exit; - } + if (CHIP_IS_E1(bp)) + fw_file_name = FW_FILE_NAME_E1; + else if (CHIP_IS_E1H(bp)) + fw_file_name = FW_FILE_NAME_E1H; + else if (!CHIP_IS_E1x(bp)) + fw_file_name = FW_FILE_NAME_E2; + else { + BNX2X_ERR("Unsupported chip revision\n"); + return -EINVAL; + } + BNX2X_DEV_INFO("Loading %s\n", fw_file_name); - rc = bnx2x_check_firmware(bp); - if (rc) { - BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name); - goto request_firmware_exit; + rc = request_firmware(&bp->firmware, fw_file_name, + &bp->pdev->dev); + if (rc) { + BNX2X_ERR("Can't load firmware file %s\n", + fw_file_name); + goto request_firmware_exit; + } + + rc = bnx2x_check_firmware(bp); + if (rc) { + BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name); + goto request_firmware_exit; + } } fw_hdr = (struct bnx2x_fw_file_hdr *)bp->firmware->data; @@ -10656,6 +10661,7 @@ static void bnx2x_release_firmware(struct bnx2x *bp) kfree(bp->init_ops); kfree(bp->init_data); release_firmware(bp->firmware); + bp->firmware = NULL; } @@ -10951,6 +10957,8 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) if (bp->doorbells) iounmap(bp->doorbells); + bnx2x_release_firmware(bp); + bnx2x_free_mem_bp(bp); free_netdev(dev); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 0440425c83d..14517691f8d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -5380,7 +5380,7 @@ static int bnx2x_func_hw_init(struct bnx2x *bp, rc = drv->init_fw(bp); if (rc) { BNX2X_ERR("Error loading firmware\n"); - goto fw_init_err; + goto init_err; } /* Handle the beginning of COMMON_XXX pases separatelly... */ @@ -5388,25 +5388,25 @@ static int bnx2x_func_hw_init(struct bnx2x *bp, case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP: rc = bnx2x_func_init_cmn_chip(bp, drv); if (rc) - goto init_hw_err; + goto init_err; break; case FW_MSG_CODE_DRV_LOAD_COMMON: rc = bnx2x_func_init_cmn(bp, drv); if (rc) - goto init_hw_err; + goto init_err; break; case FW_MSG_CODE_DRV_LOAD_PORT: rc = bnx2x_func_init_port(bp, drv); if (rc) - goto init_hw_err; + goto init_err; break; case FW_MSG_CODE_DRV_LOAD_FUNCTION: rc = bnx2x_func_init_func(bp, drv); if (rc) - goto init_hw_err; + goto init_err; break; default: @@ -5414,10 +5414,7 @@ static int bnx2x_func_hw_init(struct bnx2x *bp, rc = -EINVAL; } -init_hw_err: - drv->release_fw(bp); - -fw_init_err: +init_err: drv->gunzip_end(bp); /* In case of success, complete the comand immediatelly: no ramrods diff --git a/drivers/net/ethernet/cadence/Kconfig b/drivers/net/ethernet/cadence/Kconfig index 98849a1fc74..b48378a41e4 100644 --- a/drivers/net/ethernet/cadence/Kconfig +++ b/drivers/net/ethernet/cadence/Kconfig @@ -7,6 +7,7 @@ config HAVE_NET_MACB config NET_ATMEL bool "Atmel devices" + default y depends on HAVE_NET_MACB || (ARM && ARCH_AT91RM9200) ---help--- If you have a network (Ethernet) card belonging to this class, say Y. diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c index 6bb2b9506ca..0b3567ab812 100644 --- a/drivers/net/ethernet/lantiq_etop.c +++ b/drivers/net/ethernet/lantiq_etop.c @@ -34,6 +34,8 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/io.h> +#include <linux/dma-mapping.h> +#include <linux/module.h> #include <asm/checksum.h> diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index 7db6e36ec4f..ca33908bc7f 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -50,7 +50,7 @@ #include "sky2.h" #define DRV_NAME "sky2" -#define DRV_VERSION "1.29" +#define DRV_VERSION "1.30" /* * The Yukon II chipset takes 64 bit command blocks (called list elements) @@ -68,7 +68,7 @@ #define MAX_SKB_TX_LE (2 + (sizeof(dma_addr_t)/sizeof(u32))*(MAX_SKB_FRAGS+1)) #define TX_MIN_PENDING (MAX_SKB_TX_LE+1) #define TX_MAX_PENDING 1024 -#define TX_DEF_PENDING 127 +#define TX_DEF_PENDING 63 #define TX_WATCHDOG (5 * HZ) #define NAPI_WEIGHT 64 @@ -869,6 +869,7 @@ static void sky2_wol_init(struct sky2_port *sky2) /* block receiver */ sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); + sky2_read32(hw, B0_CTST); } static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port) @@ -1274,6 +1275,14 @@ static void rx_set_checksum(struct sky2_port *sky2) ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); } +/* + * Fixed initial key as seed to RSS. + */ +static const uint32_t rss_init_key[10] = { + 0x7c3351da, 0x51c5cf4e, 0x44adbdd1, 0xe8d38d18, 0x48897c43, + 0xb1d60e7e, 0x6a3dd760, 0x01a2e453, 0x16f46f13, 0x1a0e7b30 +}; + /* Enable/disable receive hash calculation (RSS) */ static void rx_set_rss(struct net_device *dev, netdev_features_t features) { @@ -1289,12 +1298,9 @@ static void rx_set_rss(struct net_device *dev, netdev_features_t features) /* Program RSS initial values */ if (features & NETIF_F_RXHASH) { - u32 key[nkeys]; - - get_random_bytes(key, nkeys * sizeof(u32)); for (i = 0; i < nkeys; i++) sky2_write32(hw, SK_REG(sky2->port, RSS_KEY + i * 4), - key[i]); + rss_init_key[i]); /* Need to turn on (undocumented) flag to make hashing work */ sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), @@ -1717,6 +1723,8 @@ static int sky2_setup_irq(struct sky2_hw *hw, const char *name) if (err) dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq); else { + hw->flags |= SKY2_HW_IRQ_SETUP; + napi_enable(&hw->napi); sky2_write32(hw, B0_IMSK, Y2_IS_BASE); sky2_read32(hw, B0_IMSK); @@ -1727,7 +1735,7 @@ static int sky2_setup_irq(struct sky2_hw *hw, const char *name) /* Bring up network interface. */ -static int sky2_up(struct net_device *dev) +static int sky2_open(struct net_device *dev) { struct sky2_port *sky2 = netdev_priv(dev); struct sky2_hw *hw = sky2->hw; @@ -1747,6 +1755,11 @@ static int sky2_up(struct net_device *dev) sky2_hw_up(sky2); + if (hw->chip_id == CHIP_ID_YUKON_OPT || + hw->chip_id == CHIP_ID_YUKON_PRM || + hw->chip_id == CHIP_ID_YUKON_OP_2) + imask |= Y2_IS_PHY_QLNK; /* enable PHY Quick Link */ + /* Enable interrupts from phy/mac for port */ imask = sky2_read32(hw, B0_IMSK); imask |= portirq_msk[port]; @@ -2040,6 +2053,8 @@ static void sky2_tx_reset(struct sky2_hw *hw, unsigned port) sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET); sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); + + sky2_read32(hw, B0_CTST); } static void sky2_hw_down(struct sky2_port *sky2) @@ -2090,7 +2105,7 @@ static void sky2_hw_down(struct sky2_port *sky2) } /* Network shutdown */ -static int sky2_down(struct net_device *dev) +static int sky2_close(struct net_device *dev) { struct sky2_port *sky2 = netdev_priv(dev); struct sky2_hw *hw = sky2->hw; @@ -2101,15 +2116,22 @@ static int sky2_down(struct net_device *dev) netif_info(sky2, ifdown, dev, "disabling interface\n"); - /* Disable port IRQ */ - sky2_write32(hw, B0_IMSK, - sky2_read32(hw, B0_IMSK) & ~portirq_msk[sky2->port]); - sky2_read32(hw, B0_IMSK); - if (hw->ports == 1) { + sky2_write32(hw, B0_IMSK, 0); + sky2_read32(hw, B0_IMSK); + napi_disable(&hw->napi); free_irq(hw->pdev->irq, hw); + hw->flags &= ~SKY2_HW_IRQ_SETUP; } else { + u32 imask; + + /* Disable port IRQ */ + imask = sky2_read32(hw, B0_IMSK); + imask &= ~portirq_msk[sky2->port]; + sky2_write32(hw, B0_IMSK, imask); + sky2_read32(hw, B0_IMSK); + synchronize_irq(hw->pdev->irq); napi_synchronize(&hw->napi); } @@ -2587,7 +2609,7 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last) if (netif_running(dev)) { sky2_tx_complete(sky2, last); - /* Wake unless it's detached, and called e.g. from sky2_down() */ + /* Wake unless it's detached, and called e.g. from sky2_close() */ if (tx_avail(sky2) > MAX_SKB_TX_LE + 4) netif_wake_queue(dev); } @@ -3258,7 +3280,6 @@ static void sky2_reset(struct sky2_hw *hw) hw->chip_id == CHIP_ID_YUKON_PRM || hw->chip_id == CHIP_ID_YUKON_OP_2) { u16 reg; - u32 msk; if (hw->chip_id == CHIP_ID_YUKON_OPT && hw->chip_rev == 0) { /* disable PCI-E PHY power down (set PHY reg 0x80, bit 7 */ @@ -3281,11 +3302,6 @@ static void sky2_reset(struct sky2_hw *hw) sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); sky2_pci_write16(hw, PSM_CONFIG_REG4, reg); - /* enable PHY Quick Link */ - msk = sky2_read32(hw, B0_IMSK); - msk |= Y2_IS_PHY_QLNK; - sky2_write32(hw, B0_IMSK, msk); - /* check if PSMv2 was running before */ reg = sky2_pci_read16(hw, PSM_CONFIG_REG3); if (reg & PCI_EXP_LNKCTL_ASPMC) @@ -3383,7 +3399,7 @@ static void sky2_detach(struct net_device *dev) netif_tx_lock(dev); netif_device_detach(dev); /* stop txq */ netif_tx_unlock(dev); - sky2_down(dev); + sky2_close(dev); } } @@ -3393,7 +3409,7 @@ static int sky2_reattach(struct net_device *dev) int err = 0; if (netif_running(dev)) { - err = sky2_up(dev); + err = sky2_open(dev); if (err) { netdev_info(dev, "could not restart %d\n", err); dev_close(dev); @@ -3410,10 +3426,13 @@ static void sky2_all_down(struct sky2_hw *hw) { int i; - sky2_read32(hw, B0_IMSK); - sky2_write32(hw, B0_IMSK, 0); - synchronize_irq(hw->pdev->irq); - napi_disable(&hw->napi); + if (hw->flags & SKY2_HW_IRQ_SETUP) { + sky2_read32(hw, B0_IMSK); + sky2_write32(hw, B0_IMSK, 0); + + synchronize_irq(hw->pdev->irq); + napi_disable(&hw->napi); + } for (i = 0; i < hw->ports; i++) { struct net_device *dev = hw->dev[i]; @@ -3446,11 +3465,12 @@ static void sky2_all_up(struct sky2_hw *hw) netif_wake_queue(dev); } - sky2_write32(hw, B0_IMSK, imask); - sky2_read32(hw, B0_IMSK); - - sky2_read32(hw, B0_Y2_SP_LISR); - napi_enable(&hw->napi); + if (hw->flags & SKY2_HW_IRQ_SETUP) { + sky2_write32(hw, B0_IMSK, imask); + sky2_read32(hw, B0_IMSK); + sky2_read32(hw, B0_Y2_SP_LISR); + napi_enable(&hw->napi); + } } static void sky2_restart(struct work_struct *work) @@ -4072,6 +4092,16 @@ static int sky2_set_coalesce(struct net_device *dev, return 0; } +/* + * Hardware is limited to min of 128 and max of 2048 for ring size + * and rounded up to next power of two + * to avoid division in modulus calclation + */ +static unsigned long roundup_ring_size(unsigned long pending) +{ + return max(128ul, roundup_pow_of_two(pending+1)); +} + static void sky2_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) { @@ -4099,7 +4129,7 @@ static int sky2_set_ringparam(struct net_device *dev, sky2->rx_pending = ering->rx_pending; sky2->tx_pending = ering->tx_pending; - sky2->tx_ring_size = roundup_pow_of_two(sky2->tx_pending+1); + sky2->tx_ring_size = roundup_ring_size(sky2->tx_pending); return sky2_reattach(dev); } @@ -4558,7 +4588,7 @@ static int sky2_device_event(struct notifier_block *unused, struct net_device *dev = ptr; struct sky2_port *sky2 = netdev_priv(dev); - if (dev->netdev_ops->ndo_open != sky2_up || !sky2_debug) + if (dev->netdev_ops->ndo_open != sky2_open || !sky2_debug) return NOTIFY_DONE; switch (event) { @@ -4623,8 +4653,8 @@ static __exit void sky2_debug_cleanup(void) not allowing netpoll on second port */ static const struct net_device_ops sky2_netdev_ops[2] = { { - .ndo_open = sky2_up, - .ndo_stop = sky2_down, + .ndo_open = sky2_open, + .ndo_stop = sky2_close, .ndo_start_xmit = sky2_xmit_frame, .ndo_do_ioctl = sky2_ioctl, .ndo_validate_addr = eth_validate_addr, @@ -4640,8 +4670,8 @@ static const struct net_device_ops sky2_netdev_ops[2] = { #endif }, { - .ndo_open = sky2_up, - .ndo_stop = sky2_down, + .ndo_open = sky2_open, + .ndo_stop = sky2_close, .ndo_start_xmit = sky2_xmit_frame, .ndo_do_ioctl = sky2_ioctl, .ndo_validate_addr = eth_validate_addr, @@ -4694,7 +4724,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, spin_lock_init(&sky2->phy_lock); sky2->tx_pending = TX_DEF_PENDING; - sky2->tx_ring_size = roundup_pow_of_two(TX_DEF_PENDING+1); + sky2->tx_ring_size = roundup_ring_size(TX_DEF_PENDING); sky2->rx_pending = RX_DEF_PENDING; hw->dev[port] = dev; diff --git a/drivers/net/ethernet/marvell/sky2.h b/drivers/net/ethernet/marvell/sky2.h index 0af31b8b5f1..ff6f58bf822 100644 --- a/drivers/net/ethernet/marvell/sky2.h +++ b/drivers/net/ethernet/marvell/sky2.h @@ -2287,6 +2287,7 @@ struct sky2_hw { #define SKY2_HW_RSS_BROKEN 0x00000100 #define SKY2_HW_VLAN_BROKEN 0x00000200 #define SKY2_HW_RSS_CHKSUM 0x00000400 /* RSS requires chksum */ +#define SKY2_HW_IRQ_SETUP 0x00000800 u8 chip_id; u8 chip_rev; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index b89c36dbf5b..c2df6c35860 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -581,6 +581,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud * Packet is OK - process it. */ length = be32_to_cpu(cqe->byte_cnt); + length -= ring->fcs_del; ring->bytes += length; ring->packets++; @@ -813,8 +814,11 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, int qpn, context->db_rec_addr = cpu_to_be64(ring->wqres.db.dma); /* Cancel FCS removal if FW allows */ - if (mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_FCS_KEEP) + if (mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_FCS_KEEP) { context->param3 |= cpu_to_be32(1 << 29); + ring->fcs_del = ETH_FCS_LEN; + } else + ring->fcs_del = 0; err = mlx4_qp_to_ready(mdev->dev, &ring->wqres.mtt, context, qp, state); if (err) { diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 8fda331c65d..207b5add3ca 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -272,6 +272,7 @@ struct mlx4_en_rx_ring { u32 prod; u32 cons; u32 buf_size; + u8 fcs_del; void *buf; void *rx_info; unsigned long bytes; diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index 49905347e0b..8db0b376d5b 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c @@ -2532,10 +2532,10 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit) nv_legacybackoff_reseed(dev); } } else { - u64_stats_update_begin(&np->swstats_tx_syncp); - np->stat_tx_packets++; - np->stat_tx_bytes += np->get_tx_ctx->skb->len; - u64_stats_update_end(&np->swstats_tx_syncp); + u64_stats_update_begin(&np->swstats_tx_syncp); + np->stat_tx_packets++; + np->stat_tx_bytes += np->get_tx_ctx->skb->len; + u64_stats_update_end(&np->swstats_tx_syncp); } dev_kfree_skb_any(np->get_tx_ctx->skb); diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c index 9c075ea2682..9cb5f912e48 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c @@ -18,8 +18,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ -#include <linux/module.h> /* for __MODULE_STRING */ #include "pch_gbe.h" +#include <linux/module.h> /* for __MODULE_STRING */ #define OPTION_UNSET -1 #define OPTION_DISABLED 0 diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c index 1fc01ca72b4..4bf68cfef39 100644 --- a/drivers/net/ethernet/rdc/r6040.c +++ b/drivers/net/ethernet/rdc/r6040.c @@ -940,7 +940,7 @@ static void r6040_multicast_list(struct net_device *dev) iowrite16(lp->mcr0, ioaddr + MCR0); /* Fill the MAC hash tables with their values */ - if (lp->mcr0 && MCR0_HASH_EN) { + if (lp->mcr0 & MCR0_HASH_EN) { iowrite16(hash_table[0], ioaddr + MAR0); iowrite16(hash_table[1], ioaddr + MAR1); iowrite16(hash_table[2], ioaddr + MAR2); diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index d2be42aafbe..8843071fe98 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -1937,6 +1937,7 @@ static int __devinit smsc911x_init(struct net_device *dev) { struct smsc911x_data *pdata = netdev_priv(dev); unsigned int byte_test; + unsigned int to = 100; SMSC_TRACE(pdata, probe, "Driver Parameters:"); SMSC_TRACE(pdata, probe, "LAN base: 0x%08lX", @@ -1952,6 +1953,17 @@ static int __devinit smsc911x_init(struct net_device *dev) return -ENODEV; } + /* + * poll the READY bit in PMT_CTRL. Any other access to the device is + * forbidden while this bit isn't set. Try for 100ms + */ + while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to) + udelay(1000); + if (to == 0) { + pr_err("Device not READY in 100ms aborting\n"); + return -ENODEV; + } + /* Check byte ordering */ byte_test = smsc911x_reg_read(pdata, BYTE_TEST); SMSC_TRACE(pdata, probe, "BYTE_TEST: 0x%08X", byte_test); diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c index da66ac511c4..4d5402a1d26 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c @@ -39,10 +39,11 @@ static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx, /* DMA SW reset */ value |= DMA_BUS_MODE_SFT_RESET; writel(value, ioaddr + DMA_BUS_MODE); - limit = 15000; + limit = 10; while (limit--) { if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)) break; + mdelay(10); } if (limit < 0) return -EBUSY; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c index 627f656b0f3..bc17fd08b55 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c @@ -41,10 +41,11 @@ static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx, /* DMA SW reset */ value |= DMA_BUS_MODE_SFT_RESET; writel(value, ioaddr + DMA_BUS_MODE); - limit = 15000; + limit = 10; while (limit--) { if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)) break; + mdelay(10); } if (limit < 0) return -EBUSY; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 9bafa6cf9e8..a140a8fbf05 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -72,7 +72,6 @@ struct stmmac_priv { spinlock_t lock; spinlock_t tx_lock; int wolopts; - int wolenabled; int wol_irq; #ifdef CONFIG_STMMAC_TIMER struct stmmac_timer *tm; @@ -80,6 +79,7 @@ struct stmmac_priv { struct plat_stmmacenet_data *plat; struct stmmac_counters mmc; struct dma_features dma_cap; + int hw_cap_support; }; extern int stmmac_mdio_unregister(struct net_device *ndev); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index c18ca596a49..ed83c4c47b8 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -431,6 +431,12 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) struct stmmac_priv *priv = netdev_priv(dev); u32 support = WAKE_MAGIC | WAKE_UCAST; + /* By default almost all GMAC devices support the WoL via + * magic frame but we can disable it if the HW capability + * register shows no support for pmt_magic_frame. */ + if ((priv->hw_cap_support) && (!priv->dma_cap.pmt_magic_frame)) + wol->wolopts &= ~WAKE_MAGIC; + if (!device_can_wakeup(priv->device)) return -EINVAL; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 643ca97a2d9..de71859bb29 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -321,12 +321,10 @@ static int stmmac_init_phy(struct net_device *dev) } /* Stop Advertising 1000BASE Capability if interface is not GMII */ - if ((interface) && ((interface == PHY_INTERFACE_MODE_MII) || - (interface == PHY_INTERFACE_MODE_RMII))) { - phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - phydev->advertising = phydev->supported; - } + if ((interface == PHY_INTERFACE_MODE_MII) || + (interface == PHY_INTERFACE_MODE_RMII)) + phydev->advertising &= ~(SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full); /* * Broken HW is sometimes missing the pull-up resistor on the @@ -807,8 +805,29 @@ static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) return 0; } -/* New GMAC chips support a new register to indicate the - * presence of the optional feature/functions. +/** + * stmmac_selec_desc_mode + * @dev : device pointer + * Description: select the Enhanced/Alternate or Normal descriptors */ +static void stmmac_selec_desc_mode(struct stmmac_priv *priv) +{ + if (priv->plat->enh_desc) { + pr_info(" Enhanced/Alternate descriptors\n"); + priv->hw->desc = &enh_desc_ops; + } else { + pr_info(" Normal descriptors\n"); + priv->hw->desc = &ndesc_ops; + } +} + +/** + * stmmac_get_hw_features + * @priv : private device pointer + * Description: + * new GMAC chip generations have a new register to indicate the + * presence of the optional feature/functions. + * This can be also used to override the value passed through the + * platform and necessary for old MAC10/100 and GMAC chips. */ static int stmmac_get_hw_features(struct stmmac_priv *priv) { @@ -829,7 +848,7 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv) (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9; priv->dma_cap.pmt_magic_frame = (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10; - /*MMC*/ + /* MMC */ priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11; /* IEEE 1588-2002*/ priv->dma_cap.time_stamp = @@ -857,8 +876,7 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv) priv->dma_cap.enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; - } else - pr_debug("\tNo HW DMA feature register supported"); + } return hw_cap; } @@ -913,6 +931,44 @@ static int stmmac_open(struct net_device *dev) goto open_error; } + stmmac_get_synopsys_id(priv); + + priv->hw_cap_support = stmmac_get_hw_features(priv); + + if (priv->hw_cap_support) { + pr_info(" Support DMA HW capability register"); + + /* We can override some gmac/dma configuration fields: e.g. + * enh_desc, tx_coe (e.g. that are passed through the + * platform) with the values from the HW capability + * register (if supported). + */ + priv->plat->enh_desc = priv->dma_cap.enh_desc; + priv->plat->tx_coe = priv->dma_cap.tx_coe; + priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up; + + /* By default disable wol on magic frame if not supported */ + if (!priv->dma_cap.pmt_magic_frame) + priv->wolopts &= ~WAKE_MAGIC; + + } else + pr_info(" No HW DMA feature register supported"); + + /* Select the enhnaced/normal descriptor structures */ + stmmac_selec_desc_mode(priv); + + /* PMT module is not integrated in all the MAC devices. */ + if (priv->plat->pmt) { + pr_info(" Remote wake-up capable\n"); + device_set_wakeup_capable(priv->device, 1); + } + + priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr); + if (priv->rx_coe) + pr_info(" Checksum Offload Engine supported\n"); + if (priv->plat->tx_coe) + pr_info(" Checksum insertion supported\n"); + /* Create and initialize the TX/RX descriptors chains. */ priv->dma_tx_size = STMMAC_ALIGN(dma_txsize); priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); @@ -935,15 +991,6 @@ static int stmmac_open(struct net_device *dev) /* Initialize the MAC Core */ priv->hw->mac->core_init(priv->ioaddr); - stmmac_get_synopsys_id(priv); - - stmmac_get_hw_features(priv); - - priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr); - if (priv->rx_coe) - pr_info("stmmac: Rx Checksum Offload Engine supported\n"); - if (priv->plat->tx_coe) - pr_info("\tTX Checksum insertion supported\n"); netdev_update_features(dev); /* Request the IRQ lines */ @@ -1490,9 +1537,7 @@ static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (!priv->phydev) return -EINVAL; - spin_lock(&priv->lock); ret = phy_mii_ioctl(priv->phydev, rq, cmd); - spin_unlock(&priv->lock); return ret; } @@ -1559,7 +1604,7 @@ static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v) struct net_device *dev = seq->private; struct stmmac_priv *priv = netdev_priv(dev); - if (!stmmac_get_hw_features(priv)) { + if (!priv->hw_cap_support) { seq_printf(seq, "DMA HW features not supported\n"); return 0; } @@ -1767,12 +1812,6 @@ static int stmmac_mac_device_setup(struct net_device *dev) if (!device) return -ENOMEM; - if (priv->plat->enh_desc) { - device->desc = &enh_desc_ops; - pr_info("\tEnhanced descriptor structure\n"); - } else - device->desc = &ndesc_ops; - priv->hw = device; priv->hw->ring = &ring_mode_ops; @@ -1846,11 +1885,6 @@ static int stmmac_dvr_probe(struct platform_device *pdev) priv->ioaddr = addr; - /* PMT module is not integrated in all the MAC devices. */ - if (plat_dat->pmt) { - pr_info("\tPMT module supported\n"); - device_set_wakeup_capable(&pdev->dev, 1); - } /* * On some platforms e.g. SPEAr the wake up irq differs from the mac irq * The external wake up irq can be passed through the platform code @@ -1863,7 +1897,6 @@ static int stmmac_dvr_probe(struct platform_device *pdev) if (priv->wol_irq == -ENXIO) priv->wol_irq = ndev->irq; - platform_set_drvdata(pdev, ndev); /* Set the I/O base addr */ @@ -1876,7 +1909,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev) goto out_free_ndev; } - /* MAC HW revice detection */ + /* MAC HW device detection */ ret = stmmac_mac_device_setup(ndev); if (ret < 0) goto out_plat_exit; @@ -1979,12 +2012,13 @@ static int stmmac_suspend(struct device *dev) if (!ndev || !netif_running(ndev)) return 0; + if (priv->phydev) + phy_stop(priv->phydev); + spin_lock(&priv->lock); netif_device_detach(ndev); netif_stop_queue(ndev); - if (priv->phydev) - phy_stop(priv->phydev); #ifdef CONFIG_STMMAC_TIMER priv->tm->timer_stop(); @@ -2042,12 +2076,13 @@ static int stmmac_resume(struct device *dev) #endif napi_enable(&priv->napi); - if (priv->phydev) - phy_start(priv->phydev); - netif_start_queue(ndev); spin_unlock(&priv->lock); + + if (priv->phydev) + phy_start(priv->phydev); + return 0; } diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index bbfcb59f69a..1ade9e18d29 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -114,6 +114,7 @@ void temac_indirect_out32(struct temac_local *lp, int reg, u32 value) return; temac_iow(lp, XTE_LSW0_OFFSET, value); temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg); + temac_indirect_busywait(lp); } /** @@ -203,6 +204,9 @@ static void temac_dma_bd_release(struct net_device *ndev) struct temac_local *lp = netdev_priv(ndev); int i; + /* Reset Local Link (DMA) */ + lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST); + for (i = 0; i < RX_BD_NUM; i++) { if (!lp->rx_skb[i]) break; @@ -860,6 +864,8 @@ static int temac_open(struct net_device *ndev) phy_start(lp->phy_dev); } + temac_device_reset(ndev); + rc = request_irq(lp->tx_irq, ll_temac_tx_irq, 0, ndev->name, ndev); if (rc) goto err_tx_irq; @@ -867,7 +873,6 @@ static int temac_open(struct net_device *ndev) if (rc) goto err_rx_irq; - temac_device_reset(ndev); return 0; err_rx_irq: |