diff options
Diffstat (limited to 'drivers/net/ethernet')
55 files changed, 687 insertions, 403 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 77bcd4cb4ffb..463b9ec57d80 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1278,7 +1278,7 @@ struct bnx2x { #define BNX2X_FW_RX_ALIGN_START (1UL << BNX2X_RX_ALIGN_SHIFT) #define BNX2X_FW_RX_ALIGN_END \ - max(1UL << BNX2X_RX_ALIGN_SHIFT, \ + max_t(u64, 1UL << BNX2X_RX_ALIGN_SHIFT, \ SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) #define BNX2X_PXP_DRAM_ALIGN (BNX2X_RX_ALIGN_SHIFT - 5) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 9aaf863b4237..02b5a343b195 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -4041,20 +4041,6 @@ static bool bnx2x_get_load_status(struct bnx2x *bp, int engine) return val != 0; } -/* - * Reset the load status for the current engine. - */ -static void bnx2x_clear_load_status(struct bnx2x *bp) -{ - u32 val; - u32 mask = (BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : - BNX2X_PATH0_LOAD_CNT_MASK); - bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); - val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); - REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~mask)); - bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); -} - static void _print_next_block(int idx, const char *blk) { pr_cont("%s%s", idx ? ", " : "", blk); @@ -9360,8 +9346,7 @@ static int __devinit bnx2x_prev_mark_path(struct bnx2x *bp) struct bnx2x_prev_path_list *tmp_list; int rc; - tmp_list = (struct bnx2x_prev_path_list *) - kmalloc(sizeof(struct bnx2x_prev_path_list), GFP_KERNEL); + tmp_list = kmalloc(sizeof(struct bnx2x_prev_path_list), GFP_KERNEL); if (!tmp_list) { BNX2X_ERR("Failed to allocate 'bnx2x_prev_path_list'\n"); return -ENOMEM; @@ -9385,32 +9370,24 @@ static int __devinit bnx2x_prev_mark_path(struct bnx2x *bp) return rc; } -static bool __devinit bnx2x_can_flr(struct bnx2x *bp) -{ - int pos; - u32 cap; - struct pci_dev *dev = bp->pdev; - - pos = pci_pcie_cap(dev); - if (!pos) - return false; - - pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP, &cap); - if (!(cap & PCI_EXP_DEVCAP_FLR)) - return false; - - return true; -} - static int __devinit bnx2x_do_flr(struct bnx2x *bp) { int i, pos; u16 status; struct pci_dev *dev = bp->pdev; - /* probe the capability first */ - if (bnx2x_can_flr(bp)) - return -ENOTTY; + + if (CHIP_IS_E1x(bp)) { + BNX2X_DEV_INFO("FLR not supported in E1/E1H\n"); + return -EINVAL; + } + + /* only bootcode REQ_BC_VER_4_INITIATE_FLR and onwards support flr */ + if (bp->common.bc_ver < REQ_BC_VER_4_INITIATE_FLR) { + BNX2X_ERR("FLR not supported by BC_VER: 0x%x\n", + bp->common.bc_ver); + return -EINVAL; + } pos = pci_pcie_cap(dev); if (!pos) @@ -9430,12 +9407,8 @@ static int __devinit bnx2x_do_flr(struct bnx2x *bp) "transaction is not cleared; proceeding with reset anyway\n"); clear: - if (bp->common.bc_ver < REQ_BC_VER_4_INITIATE_FLR) { - BNX2X_ERR("FLR not supported by BC_VER: 0x%x\n", - bp->common.bc_ver); - return -EINVAL; - } + BNX2X_DEV_INFO("Initiating FLR\n"); bnx2x_fw_command(bp, DRV_MSG_CODE_INITIATE_FLR, 0); return 0; @@ -9455,8 +9428,21 @@ static int __devinit bnx2x_prev_unload_uncommon(struct bnx2x *bp) * the one required, then FLR will be sufficient to clean any residue * left by previous driver */ - if (bnx2x_test_firmware_version(bp, false) && bnx2x_can_flr(bp)) - return bnx2x_do_flr(bp); + rc = bnx2x_test_firmware_version(bp, false); + + if (!rc) { + /* fw version is good */ + BNX2X_DEV_INFO("FW version matches our own. Attempting FLR\n"); + rc = bnx2x_do_flr(bp); + } + + if (!rc) { + /* FLR was performed */ + BNX2X_DEV_INFO("FLR successful\n"); + return 0; + } + + BNX2X_DEV_INFO("Could not FLR\n"); /* Close the MCP request, return failure*/ rc = bnx2x_prev_mcp_done(bp); @@ -11428,9 +11414,6 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, if (!chip_is_e1x) REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1); - /* Reset the load counter */ - bnx2x_clear_load_status(bp); - dev->watchdog_timeo = TX_TIMEOUT; dev->netdev_ops = &bnx2x_netdev_ops; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index ec62a5c8bd37..28a0bcfe61ff 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h @@ -1603,6 +1603,10 @@ * of counts that the SM entered the EEE LPI state. Clock 25MHz. Read only * register. Reset on hard reset. */ #define MISC_REG_CPMU_LP_SM_ENT_CNT_P0 0xa8b8 +/* [RW 16] EEE LPI Entry Events Counter. A statistic counter with the number + * of counts that the SM entered the EEE LPI state. Clock 25MHz. Read only + * register. Reset on hard reset. */ +#define MISC_REG_CPMU_LP_SM_ENT_CNT_P1 0xa8bc /* [RW 32] The following driver registers(1...16) represent 16 drivers and 32 clients. Each client can be controlled by one driver only. One in each bit represent that this driver control the appropriate client (Ex: bit 5 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 734fd87cd990..62f754bd0dfe 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -2485,6 +2485,7 @@ static int bnx2x_mcast_enqueue_cmd(struct bnx2x *bp, break; default: + kfree(new_cmd); BNX2X_ERR("Unknown command: %d\n", cmd); return -EINVAL; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index 667d89042d35..332db64dd5be 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c @@ -785,9 +785,11 @@ static int bnx2x_hw_stats_update(struct bnx2x *bp) pstats->host_port_stats_counter++; - if (CHIP_IS_E3(bp)) - estats->eee_tx_lpi += REG_RD(bp, - MISC_REG_CPMU_LP_SM_ENT_CNT_P0); + if (CHIP_IS_E3(bp)) { + u32 lpi_reg = BP_PORT(bp) ? MISC_REG_CPMU_LP_SM_ENT_CNT_P1 + : MISC_REG_CPMU_LP_SM_ENT_CNT_P0; + estats->eee_tx_lpi += REG_RD(bp, lpi_reg); + } if (!BP_NOMCP(bp)) { u32 nig_timer_max = diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 9a009fd6ea1b..bf906c51d82a 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -92,7 +92,7 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits) #define DRV_MODULE_NAME "tg3" #define TG3_MAJ_NUM 3 -#define TG3_MIN_NUM 123 +#define TG3_MIN_NUM 124 #define DRV_MODULE_VERSION \ __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) #define DRV_MODULE_RELDATE "March 21, 2012" @@ -672,6 +672,12 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum) else bit = 1 << tp->pci_fn; break; + case TG3_APE_LOCK_PHY0: + case TG3_APE_LOCK_PHY1: + case TG3_APE_LOCK_PHY2: + case TG3_APE_LOCK_PHY3: + bit = APE_LOCK_REQ_DRIVER; + break; default: return -EINVAL; } @@ -723,6 +729,12 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum) else bit = 1 << tp->pci_fn; break; + case TG3_APE_LOCK_PHY0: + case TG3_APE_LOCK_PHY1: + case TG3_APE_LOCK_PHY2: + case TG3_APE_LOCK_PHY3: + bit = APE_LOCK_GRANT_DRIVER; + break; default: return; } @@ -1052,6 +1064,8 @@ static int tg3_readphy(struct tg3 *tp, int reg, u32 *val) udelay(80); } + tg3_ape_lock(tp, tp->phy_ape_lock); + *val = 0x0; frame_val = ((tp->phy_addr << MI_COM_PHY_ADDR_SHIFT) & @@ -1086,6 +1100,8 @@ static int tg3_readphy(struct tg3 *tp, int reg, u32 *val) udelay(80); } + tg3_ape_unlock(tp, tp->phy_ape_lock); + return ret; } @@ -1105,6 +1121,8 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val) udelay(80); } + tg3_ape_lock(tp, tp->phy_ape_lock); + frame_val = ((tp->phy_addr << MI_COM_PHY_ADDR_SHIFT) & MI_COM_PHY_ADDR_MASK); frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) & @@ -1135,6 +1153,8 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val) udelay(80); } + tg3_ape_unlock(tp, tp->phy_ape_lock); + return ret; } @@ -9066,8 +9086,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 || tg3_flag(tp, 57765_PLUS)) { val = tr32(TG3_RDMA_RSRVCTRL_REG); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) { + if (tp->pci_chip_rev_id == CHIPREV_ID_5719_A0) { val &= ~(TG3_RDMA_RSRVCTRL_TXMRGN_MASK | TG3_RDMA_RSRVCTRL_FIFO_LWM_MASK | TG3_RDMA_RSRVCTRL_FIFO_HWM_MASK); @@ -9257,6 +9276,19 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32_f(RDMAC_MODE, rdmac_mode); udelay(40); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { + for (i = 0; i < TG3_NUM_RDMA_CHANNELS; i++) { + if (tr32(TG3_RDMA_LENGTH + (i << 2)) > TG3_MAX_MTU(tp)) + break; + } + if (i < TG3_NUM_RDMA_CHANNELS) { + val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL); + val |= TG3_LSO_RD_DMA_TX_LENGTH_WA; + tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val); + tg3_flag_set(tp, 5719_RDMA_BUG); + } + } + tw32(RCVDCC_MODE, RCVDCC_MODE_ENABLE | RCVDCC_MODE_ATTN_ENABLE); if (!tg3_flag(tp, 5705_PLUS)) tw32(MBFREE_MODE, MBFREE_MODE_ENABLE); @@ -9616,6 +9648,16 @@ static void tg3_periodic_fetch_stats(struct tg3 *tp) TG3_STAT_ADD32(&sp->tx_ucast_packets, MAC_TX_STATS_UCAST); TG3_STAT_ADD32(&sp->tx_mcast_packets, MAC_TX_STATS_MCAST); TG3_STAT_ADD32(&sp->tx_bcast_packets, MAC_TX_STATS_BCAST); + if (unlikely(tg3_flag(tp, 5719_RDMA_BUG) && + (sp->tx_ucast_packets.low + sp->tx_mcast_packets.low + + sp->tx_bcast_packets.low) > TG3_NUM_RDMA_CHANNELS)) { + u32 val; + + val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL); + val &= ~TG3_LSO_RD_DMA_TX_LENGTH_WA; + tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val); + tg3_flag_clear(tp, 5719_RDMA_BUG); + } TG3_STAT_ADD32(&sp->rx_octets, MAC_RX_STATS_OCTETS); TG3_STAT_ADD32(&sp->rx_fragments, MAC_RX_STATS_FRAGMENTS); @@ -12482,10 +12524,12 @@ static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev, { struct tg3 *tp = netdev_priv(dev); - if (!tp->hw_stats) + spin_lock_bh(&tp->lock); + if (!tp->hw_stats) { + spin_unlock_bh(&tp->lock); return &tp->net_stats_prev; + } - spin_lock_bh(&tp->lock); tg3_get_nstats(tp, stats); spin_unlock_bh(&tp->lock); @@ -13648,6 +13692,23 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) tg3_flag_set(tp, PAUSE_AUTONEG); tp->link_config.flowctrl = FLOW_CTRL_TX | FLOW_CTRL_RX; + if (tg3_flag(tp, ENABLE_APE)) { + switch (tp->pci_fn) { + case 0: + tp->phy_ape_lock = TG3_APE_LOCK_PHY0; + break; + case 1: + tp->phy_ape_lock = TG3_APE_LOCK_PHY1; + break; + case 2: + tp->phy_ape_lock = TG3_APE_LOCK_PHY2; + break; + case 3: + tp->phy_ape_lock = TG3_APE_LOCK_PHY3; + break; + } + } + if (tg3_flag(tp, USE_PHYLIB)) return tg3_phy_init(tp); diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index a1b75cd67b9d..6d52cb286826 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h @@ -1376,7 +1376,11 @@ #define TG3_LSO_RD_DMA_CRPTEN_CTRL 0x00004910 #define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K 0x00030000 #define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K 0x000c0000 -/* 0x4914 --> 0x4c00 unused */ +#define TG3_LSO_RD_DMA_TX_LENGTH_WA 0x02000000 +/* 0x4914 --> 0x4be0 unused */ + +#define TG3_NUM_RDMA_CHANNELS 4 +#define TG3_RDMA_LENGTH 0x00004be0 /* Write DMA control registers */ #define WDMAC_MODE 0x00004c00 @@ -2959,6 +2963,7 @@ enum TG3_FLAGS { TG3_FLAG_L1PLLPD_EN, TG3_FLAG_APE_HAS_NCSI, TG3_FLAG_4K_FIFO_LIMIT, + TG3_FLAG_5719_RDMA_BUG, TG3_FLAG_RESET_TASK_PENDING, TG3_FLAG_5705_PLUS, TG3_FLAG_IS_5788, @@ -3107,6 +3112,7 @@ struct tg3 { int old_link; u8 phy_addr; + u8 phy_ape_lock; /* PHY info */ u32 phy_id; diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index 8596acaa402b..d49933ed551f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -528,7 +528,7 @@ static unsigned int refill_fl(struct adapter *adap, struct sge_fl *q, int n, #endif while (n--) { - pg = alloc_page(gfp); + pg = __skb_alloc_page(gfp, NULL); if (unlikely(!pg)) { q->alloc_failed++; break; diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index f2d1ecdcaf98..8877fbfefb63 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -653,7 +653,7 @@ static unsigned int refill_fl(struct adapter *adapter, struct sge_fl *fl, alloc_small_pages: while (n--) { - page = alloc_page(gfp | __GFP_NOWARN | __GFP_COLD); + page = __skb_alloc_page(gfp | __GFP_NOWARN, NULL); if (unlikely(!page)) { fl->alloc_failed++; break; diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c index e34be1c7ae8a..c0e700653f96 100644 --- a/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c @@ -910,8 +910,9 @@ static void be_set_fw_log_level(struct be_adapter *adapter, u32 level) if (!status) { cfgs = (struct be_fat_conf_params *)(extfat_cmd.va + sizeof(struct be_cmd_resp_hdr)); - for (i = 0; i < cfgs->num_modules; i++) { - for (j = 0; j < cfgs->module[i].num_modes; j++) { + for (i = 0; i < le32_to_cpu(cfgs->num_modules); i++) { + u32 num_modes = le32_to_cpu(cfgs->module[i].num_modes); + for (j = 0; j < num_modes; j++) { if (cfgs->module[i].trace_lvl[j].mode == MODE_UART) cfgs->module[i].trace_lvl[j].dbg_lvl = diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 4d9677174490..90a903d83d87 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -1397,7 +1397,7 @@ static void be_parse_rx_compl_v1(struct be_eth_rx_compl *compl, rxcp->pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, cast_enc, compl); rxcp->rss_hash = - AMAP_GET_BITS(struct amap_eth_rx_compl_v1, rsshash, rxcp); + AMAP_GET_BITS(struct amap_eth_rx_compl_v1, rsshash, compl); if (rxcp->vlanf) { rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtm, compl); @@ -1429,7 +1429,7 @@ static void be_parse_rx_compl_v0(struct be_eth_rx_compl *compl, rxcp->pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, cast_enc, compl); rxcp->rss_hash = - AMAP_GET_BITS(struct amap_eth_rx_compl_v0, rsshash, rxcp); + AMAP_GET_BITS(struct amap_eth_rx_compl_v0, rsshash, compl); if (rxcp->vlanf) { rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtm, compl); @@ -1948,7 +1948,7 @@ static int be_rx_cqs_create(struct be_adapter *adapter) if (adapter->num_rx_qs != MAX_RX_QS) dev_info(&adapter->pdev->dev, - "Created only %d receive queues", adapter->num_rx_qs); + "Created only %d receive queues\n", adapter->num_rx_qs); return 0; } @@ -3579,7 +3579,7 @@ u32 be_get_fw_log_level(struct be_adapter *adapter) if (!status) { cfgs = (struct be_fat_conf_params *)(extfat_cmd.va + sizeof(struct be_cmd_resp_hdr)); - for (j = 0; j < cfgs->module[0].num_modes; j++) { + for (j = 0; j < le32_to_cpu(cfgs->module[0].num_modes); j++) { if (cfgs->module[0].trace_lvl[j].mode == MODE_UART) level = cfgs->module[0].trace_lvl[j].dbg_lvl; } diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c index 0f2d1a710909..151453309401 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c +++ b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c @@ -174,8 +174,10 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev) new_bus->phy_mask = ~0; new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); - if (!new_bus->irq) + if (!new_bus->irq) { + ret = -ENOMEM; goto out_unmap_regs; + } new_bus->parent = &ofdev->dev; dev_set_drvdata(&ofdev->dev, new_bus); diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c index 55bb867258e6..cdf702a59485 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c +++ b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c @@ -137,8 +137,10 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev) snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start); fec->fecp = ioremap(res.start, resource_size(&res)); - if (!fec->fecp) + if (!fec->fecp) { + ret = -ENOMEM; goto out_fec; + } if (get_bus_freq) { clock = get_bus_freq(ofdev->dev.of_node); @@ -172,8 +174,10 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev) new_bus->phy_mask = ~0; new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); - if (!new_bus->irq) + if (!new_bus->irq) { + ret = -ENOMEM; goto out_unmap_regs; + } new_bus->parent = &ofdev->dev; dev_set_drvdata(&ofdev->dev, new_bus); diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index 0b3bade957fd..080c89093feb 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c @@ -999,7 +999,7 @@ static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) **/ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) { - u32 ctrl, ctrl_ext, eecd; + u32 ctrl, ctrl_ext, eecd, tctl; s32 ret_val; /* @@ -1014,7 +1014,9 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) ew32(IMC, 0xffffffff); ew32(RCTL, 0); - ew32(TCTL, E1000_TCTL_PSP); + tctl = er32(TCTL); + tctl &= ~E1000_TCTL_EN; + ew32(TCTL, tctl); e1e_flush(); usleep_range(10000, 20000); @@ -1601,10 +1603,8 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) * auto-negotiation in the TXCW register and disable * forced link in the Device Control register in an * attempt to auto-negotiate with our link partner. - * If the partner code word is null, stop forcing - * and restart auto negotiation. */ - if ((rxcw & E1000_RXCW_C) || !(rxcw & E1000_RXCW_CW)) { + if (rxcw & E1000_RXCW_C) { /* Enable autoneg, and unforce link up */ ew32(TXCW, mac->txcw); ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 95b245310f17..46c3b1f9ff89 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -178,6 +178,24 @@ static void e1000_regdump(struct e1000_hw *hw, struct e1000_reg_info *reginfo) pr_info("%-15s %08x %08x\n", rname, regs[0], regs[1]); } +static void e1000e_dump_ps_pages(struct e1000_adapter *adapter, + struct e1000_buffer *bi) +{ + int i; + struct e1000_ps_page *ps_page; + + for (i = 0; i < adapter->rx_ps_pages; i++) { + ps_page = &bi->ps_pages[i]; + + if (ps_page->page) { + pr_info("packet dump for ps_page %d:\n", i); + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, + 16, 1, page_address(ps_page->page), + PAGE_SIZE, true); + } + } +} + /* * e1000e_dump - Print registers, Tx-ring and Rx-ring */ @@ -299,10 +317,10 @@ static void e1000e_dump(struct e1000_adapter *adapter) (unsigned long long)buffer_info->time_stamp, buffer_info->skb, next_desc); - if (netif_msg_pktdata(adapter) && buffer_info->dma != 0) + if (netif_msg_pktdata(adapter) && buffer_info->skb) print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, - 16, 1, phys_to_virt(buffer_info->dma), - buffer_info->length, true); + 16, 1, buffer_info->skb->data, + buffer_info->skb->len, true); } /* Print Rx Ring Summary */ @@ -381,10 +399,8 @@ rx_ring_summary: buffer_info->skb, next_desc); if (netif_msg_pktdata(adapter)) - print_hex_dump(KERN_INFO, "", - DUMP_PREFIX_ADDRESS, 16, 1, - phys_to_virt(buffer_info->dma), - adapter->rx_ps_bsize0, true); + e1000e_dump_ps_pages(adapter, + buffer_info); } } break; @@ -444,12 +460,12 @@ rx_ring_summary: (unsigned long long)buffer_info->dma, buffer_info->skb, next_desc); - if (netif_msg_pktdata(adapter)) + if (netif_msg_pktdata(adapter) && + buffer_info->skb) print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 1, - phys_to_virt - (buffer_info->dma), + buffer_info->skb->data, adapter->rx_buffer_len, true); } diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index 5e84eaac48c1..ba994fb4cec6 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c @@ -254,6 +254,14 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) */ size += NVM_WORD_SIZE_BASE_SHIFT; + /* + * Check for invalid size + */ + if ((hw->mac.type == e1000_82576) && (size > 15)) { + pr_notice("The NVM size is not valid, defaulting to 32K\n"); + size = 15; + } + nvm->word_size = 1 << size; if (hw->mac.type < e1000_i210) { nvm->opcode_bits = 8; @@ -281,14 +289,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) } else nvm->type = e1000_nvm_flash_hw; - /* - * Check for invalid size - */ - if ((hw->mac.type == e1000_82576) && (size > 15)) { - pr_notice("The NVM size is not valid, defaulting to 32K\n"); - size = 15; - } - /* NVM Function Pointers */ switch (hw->mac.type) { case e1000_82580: diff --git a/drivers/net/ethernet/intel/igb/e1000_regs.h b/drivers/net/ethernet/intel/igb/e1000_regs.h index 10efcd88dca0..28394bea5253 100644 --- a/drivers/net/ethernet/intel/igb/e1000_regs.h +++ b/drivers/net/ethernet/intel/igb/e1000_regs.h @@ -156,8 +156,12 @@ : (0x0E018 + ((_n) * 0x40))) #define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) \ : (0x0E028 + ((_n) * 0x40))) -#define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8)) -#define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8)) +#define E1000_RXCTL(_n) ((_n) < 4 ? (0x02814 + ((_n) * 0x100)) : \ + (0x0C014 + ((_n) * 0x40))) +#define E1000_DCA_RXCTRL(_n) E1000_RXCTL(_n) +#define E1000_TXCTL(_n) ((_n) < 4 ? (0x03814 + ((_n) * 0x100)) : \ + (0x0E014 + ((_n) * 0x40))) +#define E1000_DCA_TXCTRL(_n) E1000_TXCTL(_n) #define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) \ : (0x0E038 + ((_n) * 0x40))) #define E1000_TDWBAH(_n) ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) \ diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index a19c84cad0e9..70591117051b 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c @@ -209,8 +209,8 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) /* When SoL/IDER sessions are active, autoneg/speed/duplex * cannot be changed */ if (igb_check_reset_block(hw)) { - dev_err(&adapter->pdev->dev, "Cannot change link " - "characteristics when SoL/IDER is active.\n"); + dev_err(&adapter->pdev->dev, + "Cannot change link characteristics when SoL/IDER is active.\n"); return -EINVAL; } @@ -1089,8 +1089,8 @@ static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data, wr32(reg, (_test[pat] & write)); val = rd32(reg) & mask; if (val != (_test[pat] & write & mask)) { - dev_err(&adapter->pdev->dev, "pattern test reg %04X " - "failed: got 0x%08X expected 0x%08X\n", + dev_err(&adapter->pdev->dev, + "pattern test reg %04X failed: got 0x%08X expected 0x%08X\n", reg, val, (_test[pat] & write & mask)); *data = reg; return 1; @@ -1108,8 +1108,8 @@ static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data, wr32(reg, write & mask); val = rd32(reg); if ((write & mask) != (val & mask)) { - dev_err(&adapter->pdev->dev, "set/check reg %04X test failed:" - " got 0x%08X expected 0x%08X\n", reg, + dev_err(&adapter->pdev->dev, + "set/check reg %04X test failed: got 0x%08X expected 0x%08X\n", reg, (val & mask), (write & mask)); *data = reg; return 1; @@ -1171,8 +1171,9 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data) wr32(E1000_STATUS, toggle); after = rd32(E1000_STATUS) & toggle; if (value != after) { - dev_err(&adapter->pdev->dev, "failed STATUS register test " - "got: 0x%08X expected: 0x%08X\n", after, value); + dev_err(&adapter->pdev->dev, + "failed STATUS register test got: 0x%08X expected: 0x%08X\n", + after, value); *data = 1; return 1; } @@ -1497,6 +1498,9 @@ static int igb_integrated_phy_loopback(struct igb_adapter *adapter) break; } + /* add small delay to avoid loopback test failure */ + msleep(50); + /* force 1000, set loopback */ igb_write_phy_reg(hw, PHY_CONTROL, 0x4140); @@ -1777,16 +1781,14 @@ static int igb_loopback_test(struct igb_adapter *adapter, u64 *data) * sessions are active */ if (igb_check_reset_block(&adapter->hw)) { dev_err(&adapter->pdev->dev, - "Cannot do PHY loopback test " - "when SoL/IDER is active.\n"); + "Cannot do PHY loopback test when SoL/IDER is active.\n"); *data = 0; goto out; } if ((adapter->hw.mac.type == e1000_i210) - || (adapter->hw.mac.type == e1000_i210)) { + || (adapter->hw.mac.type == e1000_i211)) { dev_err(&adapter->pdev->dev, - "Loopback test not supported " - "on this part at this time.\n"); + "Loopback test not supported on this part at this time.\n"); *data = 0; goto out; } diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 1050411e7ca3..48cc4fb1a307 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -462,10 +462,10 @@ static void igb_dump(struct igb_adapter *adapter) (u64)buffer_info->time_stamp, buffer_info->skb, next_desc); - if (netif_msg_pktdata(adapter) && buffer_info->dma != 0) + if (netif_msg_pktdata(adapter) && buffer_info->skb) print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, - 16, 1, phys_to_virt(buffer_info->dma), + 16, 1, buffer_info->skb->data, buffer_info->length, true); } } @@ -547,18 +547,17 @@ rx_ring_summary: (u64)buffer_info->dma, buffer_info->skb, next_desc); - if (netif_msg_pktdata(adapter)) { + if (netif_msg_pktdata(adapter) && + buffer_info->dma && buffer_info->skb) { print_hex_dump(KERN_INFO, "", - DUMP_PREFIX_ADDRESS, - 16, 1, - phys_to_virt(buffer_info->dma), - IGB_RX_HDR_LEN, true); + DUMP_PREFIX_ADDRESS, + 16, 1, buffer_info->skb->data, + IGB_RX_HDR_LEN, true); print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 1, - phys_to_virt( - buffer_info->page_dma + - buffer_info->page_offset), + page_address(buffer_info->page) + + buffer_info->page_offset, PAGE_SIZE/2, true); } } @@ -6235,7 +6234,7 @@ static bool igb_alloc_mapped_page(struct igb_ring *rx_ring, return true; if (!page) { - page = alloc_page(GFP_ATOMIC | __GFP_COLD); + page = __skb_alloc_page(GFP_ATOMIC, bi->skb); bi->page = page; if (unlikely(!page)) { rx_ring->rx_stats.alloc_failed++; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c index 50fc137501da..18bf08c9d7a4 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c @@ -804,12 +804,13 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) { /* Set KX4/KX/KR support according to speed requested */ autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP); - if (speed & IXGBE_LINK_SPEED_10GB_FULL) + if (speed & IXGBE_LINK_SPEED_10GB_FULL) { if (orig_autoc & IXGBE_AUTOC_KX4_SUPP) autoc |= IXGBE_AUTOC_KX4_SUPP; if ((orig_autoc & IXGBE_AUTOC_KR_SUPP) && (hw->phy.smart_speed_active == false)) autoc |= IXGBE_AUTOC_KR_SUPP; + } if (speed & IXGBE_LINK_SPEED_1GB_FULL) autoc |= IXGBE_AUTOC_KX_SUPP; } else if ((pma_pmd_1g == IXGBE_AUTOC_1G_SFI) && diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 3b6784cf134a..4326f74f7137 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -396,11 +396,10 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) pr_cont("\n"); if (netif_msg_pktdata(adapter) && - dma_unmap_len(tx_buffer, len) != 0) + tx_buffer->skb) print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 1, - phys_to_virt(dma_unmap_addr(tx_buffer, - dma)), + tx_buffer->skb->data, dma_unmap_len(tx_buffer, len), true); } @@ -474,10 +473,12 @@ rx_ring_summary: (u64)rx_buffer_info->dma, rx_buffer_info->skb); - if (netif_msg_pktdata(adapter)) { + if (netif_msg_pktdata(adapter) && + rx_buffer_info->dma) { print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 1, - phys_to_virt(rx_buffer_info->dma), + page_address(rx_buffer_info->page) + + rx_buffer_info->page_offset, ixgbe_rx_bufsz(rx_ring), true); } } @@ -1140,8 +1141,8 @@ static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring, /* alloc new page for storage */ if (likely(!page)) { - page = alloc_pages(GFP_ATOMIC | __GFP_COLD | __GFP_COMP, - ixgbe_rx_pg_order(rx_ring)); + page = __skb_alloc_pages(GFP_ATOMIC | __GFP_COLD | __GFP_COMP, + bi->skb, ixgbe_rx_pg_order(rx_ring)); if (unlikely(!page)) { rx_ring->rx_stats.alloc_rx_page_failed++; return false; diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 3f9841d619ad..60ef64587412 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -352,7 +352,6 @@ static void ixgbevf_alloc_rx_buffers(struct ixgbevf_adapter *adapter, adapter->alloc_rx_buff_failed++; goto no_buffers; } - bi->skb = skb; } if (!bi->dma) { diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index 770ee557924c..087b9e0669f1 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -2983,6 +2983,12 @@ static int mv643xx_eth_probe(struct platform_device *pdev) return 0; out: +#if defined(CONFIG_HAVE_CLK) + if (!IS_ERR(mp->clk)) { + clk_disable_unprepare(mp->clk); + clk_put(mp->clk); + } +#endif free_netdev(dev); return err; diff --git a/drivers/net/ethernet/mellanox/mlx4/catas.c b/drivers/net/ethernet/mellanox/mlx4/catas.c index 915e947b422d..9c656fe4983d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/catas.c +++ b/drivers/net/ethernet/mellanox/mlx4/catas.c @@ -69,16 +69,21 @@ static void poll_catas(unsigned long dev_ptr) struct mlx4_priv *priv = mlx4_priv(dev); if (readl(priv->catas_err.map)) { - dump_err_buf(dev); - - mlx4_dispatch_event(dev, MLX4_DEV_EVENT_CATASTROPHIC_ERROR, 0); + /* If the device is off-line, we cannot try to recover it */ + if (pci_channel_offline(dev->pdev)) + mod_timer(&priv->catas_err.timer, + round_jiffies(jiffies + MLX4_CATAS_POLL_INTERVAL)); + else { + dump_err_buf(dev); + mlx4_dispatch_event(dev, MLX4_DEV_EVENT_CATASTROPHIC_ERROR, 0); - if (internal_err_reset) { - spin_lock(&catas_lock); - list_add(&priv->catas_err.list, &catas_list); - spin_unlock(&catas_lock); + if (internal_err_reset) { + spin_lock(&catas_lock); + list_add(&priv->catas_err.list, &catas_list); + spin_unlock(&catas_lock); - queue_work(mlx4_wq, &catas_work); + queue_work(mlx4_wq, &catas_work); + } } } else mod_timer(&priv->catas_err.timer, @@ -100,6 +105,10 @@ static void catas_reset(struct work_struct *work) list_for_each_entry_safe(priv, tmppriv, &tlist, catas_err.list) { struct pci_dev *pdev = priv->dev.pdev; + /* If the device is off-line, we cannot reset it */ + if (pci_channel_offline(pdev)) + continue; + ret = mlx4_restart_one(priv->dev.pdev); /* 'priv' now is not valid */ if (ret) diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 7e94987d030c..c8fef4353021 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c @@ -296,7 +296,12 @@ int mlx4_comm_cmd(struct mlx4_dev *dev, u8 cmd, u16 param, static int cmd_pending(struct mlx4_dev *dev) { - u32 status = readl(mlx4_priv(dev)->cmd.hcr + HCR_STATUS_OFFSET); + u32 status; + + if (pci_channel_offline(dev->pdev)) + return -EIO; + + status = readl(mlx4_priv(dev)->cmd.hcr + HCR_STATUS_OFFSET); return (status & swab32(1 << HCR_GO_BIT)) || (mlx4_priv(dev)->cmd.toggle == @@ -314,11 +319,29 @@ static int mlx4_cmd_post(struct mlx4_dev *dev, u64 in_param, u64 out_param, mutex_lock(&cmd->hcr_mutex); + if (pci_channel_offline(dev->pdev)) { + /* + * Device is going through error recovery + * and cannot accept commands. + */ + ret = -EIO; + goto out; + } + end = jiffies; if (event) end += msecs_to_jiffies(GO_BIT_TIMEOUT_MSECS); while (cmd_pending(dev)) { + if (pci_channel_offline(dev->pdev)) { + /* + * Device is going through error recovery + * and cannot accept commands. + */ + ret = -EIO; + goto out; + } + if (time_after_eq(jiffies, end)) { mlx4_err(dev, "%s:cmd_pending failed\n", __func__); goto out; @@ -431,14 +454,33 @@ static int mlx4_cmd_poll(struct mlx4_dev *dev, u64 in_param, u64 *out_param, down(&priv->cmd.poll_sem); + if (pci_channel_offline(dev->pdev)) { + /* + * Device is going through error recovery + * and cannot accept commands. + */ + err = -EIO; + goto out; + } + err = mlx4_cmd_post(dev, in_param, out_param ? *out_param : 0, in_modifier, op_modifier, op, CMD_POLL_TOKEN, 0); if (err) goto out; end = msecs_to_jiffies(timeout) + jiffies; - while (cmd_pending(dev) && time_before(jiffies, end)) + while (cmd_pending(dev) && time_before(jiffies, end)) { + if (pci_channel_offline(dev->pdev)) { + /* + * Device is going through error recovery + * and cannot accept commands. + */ + err = -EIO; + goto out; + } + cond_resched(); + } if (cmd_pending(dev)) { err = -ETIMEDOUT; @@ -532,6 +574,9 @@ int __mlx4_cmd(struct mlx4_dev *dev, u64 in_param, u64 *out_param, int out_is_imm, u32 in_modifier, u8 op_modifier, u16 op, unsigned long timeout, int native) { + if (pci_channel_offline(dev->pdev)) + return -EIO; + if (!mlx4_is_mfunc(dev) || (native && mlx4_is_master(dev))) { if (mlx4_priv(dev)->cmd.use_events) return mlx4_cmd_wait(dev, in_param, out_param, diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 8864d8b53737..edd9cb8d3e1d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -201,7 +201,7 @@ mlx4_en_filter_alloc(struct mlx4_en_priv *priv, int rxq_index, __be32 src_ip, filter->flow_id = flow_id; - filter->id = priv->last_filter_id++; + filter->id = priv->last_filter_id++ % RPS_NO_FILTER; list_add_tail(&filter->next, &priv->filters); hlist_add_head(&filter->filter_chain, diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index f32e70300770..5aba5ecdf1e2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -614,8 +614,8 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud /* If source MAC is equal to our own MAC and not performing * the selftest or flb disabled - drop the packet */ if (s_mac == priv->mac && - (!(dev->features & NETIF_F_LOOPBACK) || - !priv->validate_loopback)) + !((dev->features & NETIF_F_LOOPBACK) || + priv->validate_loopback)) goto next; /* diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 019d856b1334..10bba09c44ea 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c @@ -164,7 +164,6 @@ int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv, ring->cons = 0xffffffff; ring->last_nr_txbb = 1; ring->poll_cnt = 0; - ring->blocked = 0; memset(ring->tx_info, 0, ring->size * sizeof(struct mlx4_en_tx_info)); memset(ring->buf, 0, ring->buf_size); @@ -365,14 +364,13 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq) ring->cons += txbbs_skipped; netdev_tx_completed_queue(ring->tx_queue, packets, bytes); - /* Wakeup Tx queue if this ring stopped it */ - if (unlikely(ring->blocked)) { - if ((u32) (ring->prod - ring->cons) <= - ring->size - HEADROOM - MAX_DESC_TXBBS) { - ring->blocked = 0; - netif_tx_wake_queue(ring->tx_queue); - priv->port_stats.wake_queue++; - } + /* + * Wakeup Tx queue if this stopped, and at least 1 packet + * was completed + */ + if (netif_tx_queue_stopped(ring->tx_queue) && txbbs_skipped > 0) { + netif_tx_wake_queue(ring->tx_queue); + priv->port_stats.wake_queue++; } } @@ -592,7 +590,6 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) ring->size - HEADROOM - MAX_DESC_TXBBS)) { /* every full Tx ring stops queue */ netif_tx_stop_queue(ring->tx_queue); - ring->blocked = 1; priv->port_stats.queue_stopped++; return NETDEV_TX_BUSY; diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.c b/drivers/net/ethernet/mellanox/mlx4/icm.c index 88b7b3e75ab1..daf417923661 100644 --- a/drivers/net/ethernet/mellanox/mlx4/icm.c +++ b/drivers/net/ethernet/mellanox/mlx4/icm.c @@ -358,13 +358,14 @@ void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, } int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, - u64 virt, int obj_size, int nobj, int reserved, + u64 virt, int obj_size, u32 nobj, int reserved, int use_lowmem, int use_coherent) { int obj_per_chunk; int num_icm; unsigned chunk_size; int i; + u64 size; obj_per_chunk = MLX4_TABLE_CHUNK_SIZE / obj_size; num_icm = (nobj + obj_per_chunk - 1) / obj_per_chunk; @@ -380,10 +381,12 @@ int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, table->coherent = use_coherent; mutex_init(&table->mutex); + size = (u64) nobj * obj_size; for (i = 0; i * MLX4_TABLE_CHUNK_SIZE < reserved * obj_size; ++i) { chunk_size = MLX4_TABLE_CHUNK_SIZE; - if ((i + 1) * MLX4_TABLE_CHUNK_SIZE > nobj * obj_size) - chunk_size = PAGE_ALIGN(nobj * obj_size - i * MLX4_TABLE_CHUNK_SIZE); + if ((i + 1) * MLX4_TABLE_CHUNK_SIZE > size) + chunk_size = PAGE_ALIGN(size - + i * MLX4_TABLE_CHUNK_SIZE); table->icm[i] = mlx4_alloc_icm(dev, chunk_size >> PAGE_SHIFT, (use_lowmem ? GFP_KERNEL : GFP_HIGHUSER) | diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.h b/drivers/net/ethernet/mellanox/mlx4/icm.h index 19e4efc0b342..a67744f53506 100644 --- a/drivers/net/ethernet/mellanox/mlx4/icm.h +++ b/drivers/net/ethernet/mellanox/mlx4/icm.h @@ -78,7 +78,7 @@ int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, int start, int end); int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, - u64 virt, int obj_size, int nobj, int reserved, + u64 virt, int obj_size, u32 nobj, int reserved, int use_lowmem, int use_coherent); void mlx4_cleanup_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table); void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_handle); diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index e8f8ebb4ae65..827b72dfce99 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -157,9 +157,6 @@ int mlx4_check_port_params(struct mlx4_dev *dev, "on this HCA, aborting.\n"); return -EINVAL; } - if (port_type[i] == MLX4_PORT_TYPE_ETH && - port_type[i + 1] == MLX4_PORT_TYPE_IB) - return -EINVAL; } } @@ -1817,6 +1814,9 @@ static int mlx4_get_ownership(struct mlx4_dev *dev) void __iomem *owner; u32 ret; + if (pci_channel_offline(dev->pdev)) + return -EIO; + owner = ioremap(pci_resource_start(dev->pdev, 0) + MLX4_OWNER_BASE, MLX4_OWNER_SIZE); if (!owner) { @@ -1833,6 +1833,9 @@ static void mlx4_free_ownership(struct mlx4_dev *dev) { void __iomem *owner; + if (pci_channel_offline(dev->pdev)) + return; + owner = ioremap(pci_resource_start(dev->pdev, 0) + MLX4_OWNER_BASE, MLX4_OWNER_SIZE); if (!owner) { @@ -2279,11 +2282,33 @@ static DEFINE_PCI_DEVICE_TABLE(mlx4_pci_table) = { MODULE_DEVICE_TABLE(pci, mlx4_pci_table); +static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + mlx4_remove_one(pdev); + + return state == pci_channel_io_perm_failure ? + PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET; +} + +static pci_ers_result_t mlx4_pci_slot_reset(struct pci_dev *pdev) +{ + int ret = __mlx4_init_one(pdev, NULL); + + return ret ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED; +} + +static struct pci_error_handlers mlx4_err_handler = { + .error_detected = mlx4_pci_err_detected, + .slot_reset = mlx4_pci_slot_reset, +}; + static struct pci_driver mlx4_driver = { .name = DRV_NAME, .id_table = mlx4_pci_table, .probe = mlx4_init_one, - .remove = __devexit_p(mlx4_remove_one) + .remove = __devexit_p(mlx4_remove_one), + .err_handler = &mlx4_err_handler, }; static int __init mlx4_verify_params(void) diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index 4ec3835e1bc2..a018ea2a43de 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c @@ -432,8 +432,10 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port, if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn) { /* Entry already exists, add to duplicates */ dqp = kmalloc(sizeof *dqp, GFP_KERNEL); - if (!dqp) + if (!dqp) { + err = -ENOMEM; goto out_mailbox; + } dqp->qpn = qpn; list_add_tail(&dqp->list, &entry->duplicates); found = true; diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 59ebc0339638..4d9df8f2a126 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -249,7 +249,7 @@ struct mlx4_bitmap { struct mlx4_buddy { unsigned long **bits; unsigned int *num_free; - int max_order; + u32 max_order; spinlock_t lock; }; @@ -258,7 +258,7 @@ struct mlx4_icm; struct mlx4_icm_table { u64 virt; int num_icm; - int num_obj; + u32 num_obj; int obj_size; int lowmem; int coherent; diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 5f1ab105debc..9d27e42264e2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -248,7 +248,6 @@ struct mlx4_en_tx_ring { u32 doorbell_qpn; void *buf; u16 poll_cnt; - int blocked; struct mlx4_en_tx_info *tx_info; u8 *bounce_buf; u32 last_nr_txbb; diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index af55b7ce5341..c202d3ad2a0e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c @@ -37,6 +37,7 @@ #include <linux/export.h> #include <linux/slab.h> #include <linux/kernel.h> +#include <linux/vmalloc.h> #include <linux/mlx4/cmd.h> @@ -120,7 +121,7 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order) buddy->max_order = max_order; spin_lock_init(&buddy->lock); - buddy->bits = kzalloc((buddy->max_order + 1) * sizeof (long *), + buddy->bits = kcalloc(buddy->max_order + 1, sizeof (long *), GFP_KERNEL); buddy->num_free = kcalloc((buddy->max_order + 1), sizeof *buddy->num_free, GFP_KERNEL); @@ -129,10 +130,12 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order) for (i = 0; i <= buddy->max_order; ++i) { s = BITS_TO_LONGS(1 << (buddy->max_order - i)); - buddy->bits[i] = kmalloc(s * sizeof (long), GFP_KERNEL); - if (!buddy->bits[i]) - goto err_out_free; - bitmap_zero(buddy->bits[i], 1 << (buddy->max_order - i)); + buddy->bits[i] = kcalloc(s, sizeof (long), GFP_KERNEL | __GFP_NOWARN); + if (!buddy->bits[i]) { + buddy->bits[i] = vzalloc(s * sizeof(long)); + if (!buddy->bits[i]) + goto err_out_free; + } } set_bit(0, buddy->bits[buddy->max_order]); @@ -142,7 +145,10 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order) err_out_free: for (i = 0; i <= buddy->max_order; ++i) - kfree(buddy->bits[i]); + if (buddy->bits[i] && is_vmalloc_addr(buddy->bits[i])) + vfree(buddy->bits[i]); + else + kfree(buddy->bits[i]); err_out: kfree(buddy->bits); @@ -156,7 +162,10 @@ static void mlx4_buddy_cleanup(struct mlx4_buddy *buddy) int i; for (i = 0; i <= buddy->max_order; ++i) - kfree(buddy->bits[i]); + if (is_vmalloc_addr(buddy->bits[i])) + vfree(buddy->bits[i]); + else + kfree(buddy->bits[i]); kfree(buddy->bits); kfree(buddy->num_free); @@ -668,7 +677,7 @@ int mlx4_init_mr_table(struct mlx4_dev *dev) return err; err = mlx4_buddy_init(&mr_table->mtt_buddy, - ilog2(dev->caps.num_mtts / + ilog2((u32)dev->caps.num_mtts / (1 << log_mtts_per_seg))); if (err) goto err_buddy; @@ -678,7 +687,7 @@ int mlx4_init_mr_table(struct mlx4_dev *dev) mlx4_alloc_mtt_range(dev, fls(dev->caps.reserved_mtts - 1)); if (priv->reserved_mtts < 0) { - mlx4_warn(dev, "MTT table of order %d is too small.\n", + mlx4_warn(dev, "MTT table of order %u is too small.\n", mr_table->mtt_buddy.max_order); err = -ENOMEM; goto err_reserve_mtts; diff --git a/drivers/net/ethernet/mellanox/mlx4/profile.c b/drivers/net/ethernet/mellanox/mlx4/profile.c index 9ee4725363d5..8e0c3cc2a1ec 100644 --- a/drivers/net/ethernet/mellanox/mlx4/profile.c +++ b/drivers/net/ethernet/mellanox/mlx4/profile.c @@ -76,7 +76,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, u64 size; u64 start; int type; - int num; + u32 num; int log_num; }; @@ -105,7 +105,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, si_meminfo(&si); request->num_mtt = roundup_pow_of_two(max_t(unsigned, request->num_mtt, - min(1UL << 31, + min(1UL << (31 - log_mtts_per_seg), si.totalram >> (log_mtts_per_seg - 1)))); profile[MLX4_RES_QP].size = dev_cap->qpc_entry_sz; diff --git a/drivers/net/ethernet/mellanox/mlx4/sense.c b/drivers/net/ethernet/mellanox/mlx4/sense.c index 802498293528..34ee09bae36e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/sense.c +++ b/drivers/net/ethernet/mellanox/mlx4/sense.c @@ -81,20 +81,6 @@ void mlx4_do_sense_ports(struct mlx4_dev *dev, } /* - * Adjust port configuration: - * If port 1 sensed nothing and port 2 is IB, set both as IB - * If port 2 sensed nothing and port 1 is Eth, set both as Eth - */ - if (stype[0] == MLX4_PORT_TYPE_ETH) { - for (i = 1; i < dev->caps.num_ports; i++) - stype[i] = stype[i] ? stype[i] : MLX4_PORT_TYPE_ETH; - } - if (stype[dev->caps.num_ports - 1] == MLX4_PORT_TYPE_IB) { - for (i = 0; i < dev->caps.num_ports - 1; i++) - stype[i] = stype[i] ? stype[i] : MLX4_PORT_TYPE_IB; - } - - /* * If sensed nothing, remain in current configuration. */ for (i = 0; i < dev->caps.num_ports; i++) diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c index 4069edab229e..53743f7a2ca9 100644 --- a/drivers/net/ethernet/nxp/lpc_eth.c +++ b/drivers/net/ethernet/nxp/lpc_eth.c @@ -346,28 +346,15 @@ static phy_interface_t lpc_phy_interface_mode(struct device *dev) "phy-mode", NULL); if (mode && !strcmp(mode, "mii")) return PHY_INTERFACE_MODE_MII; - return PHY_INTERFACE_MODE_RMII; } - - /* non-DT */ -#ifdef CONFIG_ARCH_LPC32XX_MII_SUPPORT - return PHY_INTERFACE_MODE_MII; -#else return PHY_INTERFACE_MODE_RMII; -#endif } static bool use_iram_for_net(struct device *dev) { if (dev && dev->of_node) return of_property_read_bool(dev->of_node, "use-iram"); - - /* non-DT */ -#ifdef CONFIG_ARCH_LPC32XX_IRAM_FOR_NET - return true; -#else return false; -#endif } /* Receive Status information word */ diff --git a/drivers/net/ethernet/octeon/octeon_mgmt.c b/drivers/net/ethernet/octeon/octeon_mgmt.c index cd827ff4a021..c42bbb16cdae 100644 --- a/drivers/net/ethernet/octeon/octeon_mgmt.c +++ b/drivers/net/ethernet/octeon/octeon_mgmt.c @@ -6,19 +6,21 @@ * Copyright (C) 2009 Cavium Networks */ -#include <linux/capability.h> +#include <linux/platform_device.h> #include <linux/dma-mapping.h> -#include <linux/init.h> -#include <linux/module.h> +#include <linux/etherdevice.h> +#include <linux/capability.h> #include <linux/interrupt.h> -#include <linux/platform_device.h> #include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/if.h> +#include <linux/spinlock.h> #include <linux/if_vlan.h> +#include <linux/of_mdio.h> +#include <linux/module.h> +#include <linux/of_net.h> +#include <linux/init.h> #include <linux/slab.h> #include <linux/phy.h> -#include <linux/spinlock.h> +#include <linux/io.h> #include <asm/octeon/octeon.h> #include <asm/octeon/cvmx-mixx-defs.h> @@ -58,8 +60,56 @@ union mgmt_port_ring_entry { } s; }; +#define MIX_ORING1 0x0 +#define MIX_ORING2 0x8 +#define MIX_IRING1 0x10 +#define MIX_IRING2 0x18 +#define MIX_CTL 0x20 +#define MIX_IRHWM 0x28 +#define MIX_IRCNT 0x30 +#define MIX_ORHWM 0x38 +#define MIX_ORCNT 0x40 +#define MIX_ISR 0x48 +#define MIX_INTENA 0x50 +#define MIX_REMCNT 0x58 +#define MIX_BIST 0x78 + +#define AGL_GMX_PRT_CFG 0x10 +#define AGL_GMX_RX_FRM_CTL 0x18 +#define AGL_GMX_RX_FRM_MAX 0x30 +#define AGL_GMX_RX_JABBER 0x38 +#define AGL_GMX_RX_STATS_CTL 0x50 + +#define AGL_GMX_RX_STATS_PKTS_DRP 0xb0 +#define AGL_GMX_RX_STATS_OCTS_DRP 0xb8 +#define AGL_GMX_RX_STATS_PKTS_BAD 0xc0 + +#define AGL_GMX_RX_ADR_CTL 0x100 +#define AGL_GMX_RX_ADR_CAM_EN 0x108 +#define AGL_GMX_RX_ADR_CAM0 0x180 +#define AGL_GMX_RX_ADR_CAM1 0x188 +#define AGL_GMX_RX_ADR_CAM2 0x190 +#define AGL_GMX_RX_ADR_CAM3 0x198 +#define AGL_GMX_RX_ADR_CAM4 0x1a0 +#define AGL_GMX_RX_ADR_CAM5 0x1a8 + +#define AGL_GMX_TX_STATS_CTL 0x268 +#define AGL_GMX_TX_CTL 0x270 +#define AGL_GMX_TX_STAT0 0x280 +#define AGL_GMX_TX_STAT1 0x288 +#define AGL_GMX_TX_STAT2 0x290 +#define AGL_GMX_TX_STAT3 0x298 +#define AGL_GMX_TX_STAT4 0x2a0 +#define AGL_GMX_TX_STAT5 0x2a8 +#define AGL_GMX_TX_STAT6 0x2b0 +#define AGL_GMX_TX_STAT7 0x2b8 +#define AGL_GMX_TX_STAT8 0x2c0 +#define AGL_GMX_TX_STAT9 0x2c8 + struct octeon_mgmt { struct net_device *netdev; + u64 mix; + u64 agl; int port; int irq; u64 *tx_ring; @@ -85,31 +135,34 @@ struct octeon_mgmt { struct napi_struct napi; struct tasklet_struct tx_clean_tasklet; struct phy_device *phydev; + struct device_node *phy_np; + resource_size_t mix_phys; + resource_size_t mix_size; + resource_size_t agl_phys; + resource_size_t agl_size; }; static void octeon_mgmt_set_rx_irq(struct octeon_mgmt *p, int enable) { - int port = p->port; union cvmx_mixx_intena mix_intena; unsigned long flags; spin_lock_irqsave(&p->lock, flags); - mix_intena.u64 = cvmx_read_csr(CVMX_MIXX_INTENA(port)); + mix_intena.u64 = cvmx_read_csr(p->mix + MIX_INTENA); mix_intena.s.ithena = enable ? 1 : 0; - cvmx_write_csr(CVMX_MIXX_INTENA(port), mix_intena.u64); + cvmx_write_csr(p->mix + MIX_INTENA, mix_intena.u64); spin_unlock_irqrestore(&p->lock, flags); } static void octeon_mgmt_set_tx_irq(struct octeon_mgmt *p, int enable) { - int port = p->port; union cvmx_mixx_intena mix_intena; unsigned long flags; spin_lock_irqsave(&p->lock, flags); - mix_intena.u64 = cvmx_read_csr(CVMX_MIXX_INTENA(port)); + mix_intena.u64 = cvmx_read_csr(p->mix + MIX_INTENA); mix_intena.s.othena = enable ? 1 : 0; - cvmx_write_csr(CVMX_MIXX_INTENA(port), mix_intena.u64); + cvmx_write_csr(p->mix + MIX_INTENA, mix_intena.u64); spin_unlock_irqrestore(&p->lock, flags); } @@ -146,7 +199,6 @@ static unsigned int ring_size_to_bytes(unsigned int ring_size) static void octeon_mgmt_rx_fill_ring(struct net_device *netdev) { struct octeon_mgmt *p = netdev_priv(netdev); - int port = p->port; while (p->rx_current_fill < ring_max_fill(OCTEON_MGMT_RX_RING_SIZE)) { unsigned int size; @@ -177,24 +229,23 @@ static void octeon_mgmt_rx_fill_ring(struct net_device *netdev) (p->rx_next_fill + 1) % OCTEON_MGMT_RX_RING_SIZE; p->rx_current_fill++; /* Ring the bell. */ - cvmx_write_csr(CVMX_MIXX_IRING2(port), 1); + cvmx_write_csr(p->mix + MIX_IRING2, 1); } } static void octeon_mgmt_clean_tx_buffers(struct octeon_mgmt *p) { - int port = p->port; union cvmx_mixx_orcnt mix_orcnt; union mgmt_port_ring_entry re; struct sk_buff *skb; int cleaned = 0; unsigned long flags; - mix_orcnt.u64 = cvmx_read_csr(CVMX_MIXX_ORCNT(port)); + mix_orcnt.u64 = cvmx_read_csr(p->mix + MIX_ORCNT); while (mix_orcnt.s.orcnt) { spin_lock_irqsave(&p->tx_list.lock, flags); - mix_orcnt.u64 = cvmx_read_csr(CVMX_MIXX_ORCNT(port)); + mix_orcnt.u64 = cvmx_read_csr(p->mix + MIX_ORCNT); if (mix_orcnt.s.orcnt == 0) { spin_unlock_irqrestore(&p->tx_list.lock, flags); @@ -214,7 +265,7 @@ static void octeon_mgmt_clean_tx_buffers(struct octeon_mgmt *p) mix_orcnt.s.orcnt = 1; /* Acknowledge to hardware that we have the buffer. */ - cvmx_write_csr(CVMX_MIXX_ORCNT(port), mix_orcnt.u64); + cvmx_write_csr(p->mix + MIX_ORCNT, mix_orcnt.u64); p->tx_current_fill--; spin_unlock_irqrestore(&p->tx_list.lock, flags); @@ -224,7 +275,7 @@ static void octeon_mgmt_clean_tx_buffers(struct octeon_mgmt *p) dev_kfree_skb_any(skb); cleaned++; - mix_orcnt.u64 = cvmx_read_csr(CVMX_MIXX_ORCNT(port)); + mix_orcnt.u64 = cvmx_read_csr(p->mix + MIX_ORCNT); } if (cleaned && netif_queue_stopped(p->netdev)) @@ -241,13 +292,12 @@ static void octeon_mgmt_clean_tx_tasklet(unsigned long arg) static void octeon_mgmt_update_rx_stats(struct net_device *netdev) { struct octeon_mgmt *p = netdev_priv(netdev); - int port = p->port; unsigned long flags; u64 drop, bad; /* These reads also clear the count registers. */ - drop = cvmx_read_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(port)); - bad = cvmx_read_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(port)); + drop = cvmx_read_csr(p->agl + AGL_GMX_RX_STATS_PKTS_DRP); + bad = cvmx_read_csr(p->agl + AGL_GMX_RX_STATS_PKTS_BAD); if (drop || bad) { /* Do an atomic update. */ @@ -261,15 +311,14 @@ static void octeon_mgmt_update_rx_stats(struct net_device *netdev) static void octeon_mgmt_update_tx_stats(struct net_device *netdev) { struct octeon_mgmt *p = netdev_priv(netdev); - int port = p->port; unsigned long flags; union cvmx_agl_gmx_txx_stat0 s0; union cvmx_agl_gmx_txx_stat1 s1; /* These reads also clear the count registers. */ - s0.u64 = cvmx_read_csr(CVMX_AGL_GMX_TXX_STAT0(port)); - s1.u64 = cvmx_read_csr(CVMX_AGL_GMX_TXX_STAT1(port)); + s0.u64 = cvmx_read_csr(p->agl + AGL_GMX_TX_STAT0); + s1.u64 = cvmx_read_csr(p->agl + AGL_GMX_TX_STAT1); if (s0.s.xsdef || s0.s.xscol || s1.s.scol || s1.s.mcol) { /* Do an atomic update. */ @@ -308,7 +357,6 @@ static u64 octeon_mgmt_dequeue_rx_buffer(struct octeon_mgmt *p, static int octeon_mgmt_receive_one(struct octeon_mgmt *p) { - int port = p->port; struct net_device *netdev = p->netdev; union cvmx_mixx_ircnt mix_ircnt; union mgmt_port_ring_entry re; @@ -381,18 +429,17 @@ done: /* Tell the hardware we processed a packet. */ mix_ircnt.u64 = 0; mix_ircnt.s.ircnt = 1; - cvmx_write_csr(CVMX_MIXX_IRCNT(port), mix_ircnt.u64); + cvmx_write_csr(p->mix + MIX_IRCNT, mix_ircnt.u64); return rc; } static int octeon_mgmt_receive_packets(struct octeon_mgmt *p, int budget) { - int port = p->port; unsigned int work_done = 0; union cvmx_mixx_ircnt mix_ircnt; int rc; - mix_ircnt.u64 = cvmx_read_csr(CVMX_MIXX_IRCNT(port)); + mix_ircnt.u64 = cvmx_read_csr(p->mix + MIX_IRCNT); while (work_done < budget && mix_ircnt.s.ircnt) { rc = octeon_mgmt_receive_one(p); @@ -400,7 +447,7 @@ static int octeon_mgmt_receive_packets(struct octeon_mgmt *p, int budget) work_done++; /* Check for more packets. */ - mix_ircnt.u64 = cvmx_read_csr(CVMX_MIXX_IRCNT(port)); + mix_ircnt.u64 = cvmx_read_csr(p->mix + MIX_IRCNT); } octeon_mgmt_rx_fill_ring(p->netdev); @@ -434,16 +481,16 @@ static void octeon_mgmt_reset_hw(struct octeon_mgmt *p) union cvmx_agl_gmx_bist agl_gmx_bist; mix_ctl.u64 = 0; - cvmx_write_csr(CVMX_MIXX_CTL(p->port), mix_ctl.u64); + cvmx_write_csr(p->mix + MIX_CTL, mix_ctl.u64); do { - mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(p->port)); + mix_ctl.u64 = cvmx_read_csr(p->mix + MIX_CTL); } while (mix_ctl.s.busy); mix_ctl.s.reset = 1; - cvmx_write_csr(CVMX_MIXX_CTL(p->port), mix_ctl.u64); - cvmx_read_csr(CVMX_MIXX_CTL(p->port)); + cvmx_write_csr(p->mix + MIX_CTL, mix_ctl.u64); + cvmx_read_csr(p->mix + MIX_CTL); cvmx_wait(64); - mix_bist.u64 = cvmx_read_csr(CVMX_MIXX_BIST(p->port)); + mix_bist.u64 = cvmx_read_csr(p->mix + MIX_BIST); if (mix_bist.u64) dev_warn(p->dev, "MIX failed BIST (0x%016llx)\n", (unsigned long long)mix_bist.u64); @@ -474,7 +521,6 @@ static void octeon_mgmt_cam_state_add(struct octeon_mgmt_cam_state *cs, static void octeon_mgmt_set_rx_filtering(struct net_device *netdev) { struct octeon_mgmt *p = netdev_priv(netdev); - int port = p->port; union cvmx_agl_gmx_rxx_adr_ctl adr_ctl; union cvmx_agl_gmx_prtx_cfg agl_gmx_prtx; unsigned long flags; @@ -520,29 +566,29 @@ static void octeon_mgmt_set_rx_filtering(struct net_device *netdev) spin_lock_irqsave(&p->lock, flags); /* Disable packet I/O. */ - agl_gmx_prtx.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port)); + agl_gmx_prtx.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG); prev_packet_enable = agl_gmx_prtx.s.en; agl_gmx_prtx.s.en = 0; - cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), agl_gmx_prtx.u64); + cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, agl_gmx_prtx.u64); adr_ctl.u64 = 0; adr_ctl.s.cam_mode = cam_mode; adr_ctl.s.mcst = multicast_mode; adr_ctl.s.bcst = 1; /* Allow broadcast */ - cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CTL(port), adr_ctl.u64); + cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CTL, adr_ctl.u64); - cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM0(port), cam_state.cam[0]); - cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM1(port), cam_state.cam[1]); - cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM2(port), cam_state.cam[2]); - cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM3(port), cam_state.cam[3]); - cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM4(port), cam_state.cam[4]); - cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM5(port), cam_state.cam[5]); - cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM_EN(port), cam_state.cam_mask); + cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM0, cam_state.cam[0]); + cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM1, cam_state.cam[1]); + cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM2, cam_state.cam[2]); + cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM3, cam_state.cam[3]); + cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM4, cam_state.cam[4]); + cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM5, cam_state.cam[5]); + cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM_EN, cam_state.cam_mask); /* Restore packet I/O. */ agl_gmx_prtx.s.en = prev_packet_enable; - cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), agl_gmx_prtx.u64); + cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, agl_gmx_prtx.u64); spin_unlock_irqrestore(&p->lock, flags); } @@ -564,7 +610,6 @@ static int octeon_mgmt_set_mac_address(struct net_device *netdev, void *addr) static int octeon_mgmt_change_mtu(struct net_device *netdev, int new_mtu) { struct octeon_mgmt *p = netdev_priv(netdev); - int port = p->port; int size_without_fcs = new_mtu + OCTEON_MGMT_RX_HEADROOM; /* @@ -580,8 +625,8 @@ static int octeon_mgmt_change_mtu(struct net_device *netdev, int new_mtu) netdev->mtu = new_mtu; - cvmx_write_csr(CVMX_AGL_GMX_RXX_FRM_MAX(port), size_without_fcs); - cvmx_write_csr(CVMX_AGL_GMX_RXX_JABBER(port), + cvmx_write_csr(p->agl + AGL_GMX_RX_FRM_MAX, size_without_fcs); + cvmx_write_csr(p->agl + AGL_GMX_RX_JABBER, (size_without_fcs + 7) & 0xfff8); return 0; @@ -591,14 +636,13 @@ static irqreturn_t octeon_mgmt_interrupt(int cpl, void *dev_id) { struct net_device *netdev = dev_id; struct octeon_mgmt *p = netdev_priv(netdev); - int port = p->port; union cvmx_mixx_isr mixx_isr; - mixx_isr.u64 = cvmx_read_csr(CVMX_MIXX_ISR(port)); + mixx_isr.u64 = cvmx_read_csr(p->mix + MIX_ISR); /* Clear any pending interrupts */ - cvmx_write_csr(CVMX_MIXX_ISR(port), mixx_isr.u64); - cvmx_read_csr(CVMX_MIXX_ISR(port)); + cvmx_write_csr(p->mix + MIX_ISR, mixx_isr.u64); + cvmx_read_csr(p->mix + MIX_ISR); if (mixx_isr.s.irthresh) { octeon_mgmt_disable_rx_irq(p); @@ -629,7 +673,6 @@ static int octeon_mgmt_ioctl(struct net_device *netdev, static void octeon_mgmt_adjust_link(struct net_device *netdev) { struct octeon_mgmt *p = netdev_priv(netdev); - int port = p->port; union cvmx_agl_gmx_prtx_cfg prtx_cfg; unsigned long flags; int link_changed = 0; @@ -640,11 +683,9 @@ static void octeon_mgmt_adjust_link(struct net_device *netdev) link_changed = 1; if (p->last_duplex != p->phydev->duplex) { p->last_duplex = p->phydev->duplex; - prtx_cfg.u64 = - cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port)); + prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG); prtx_cfg.s.duplex = p->phydev->duplex; - cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), - prtx_cfg.u64); + cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64); } } else { if (p->last_link) @@ -670,18 +711,16 @@ static void octeon_mgmt_adjust_link(struct net_device *netdev) static int octeon_mgmt_init_phy(struct net_device *netdev) { struct octeon_mgmt *p = netdev_priv(netdev); - char phy_id[MII_BUS_ID_SIZE + 3]; - if (octeon_is_simulation()) { + if (octeon_is_simulation() || p->phy_np == NULL) { /* No PHYs in the simulator. */ netif_carrier_on(netdev); return 0; } - snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, "mdio-octeon-0", p->port); - - p->phydev = phy_connect(netdev, phy_id, octeon_mgmt_adjust_link, 0, - PHY_INTERFACE_MODE_MII); + p->phydev = of_phy_connect(netdev, p->phy_np, + octeon_mgmt_adjust_link, 0, + PHY_INTERFACE_MODE_MII); if (IS_ERR(p->phydev)) { p->phydev = NULL; @@ -737,14 +776,14 @@ static int octeon_mgmt_open(struct net_device *netdev) octeon_mgmt_reset_hw(p); - mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(port)); + mix_ctl.u64 = cvmx_read_csr(p->mix + MIX_CTL); /* Bring it out of reset if needed. */ if (mix_ctl.s.reset) { mix_ctl.s.reset = 0; - cvmx_write_csr(CVMX_MIXX_CTL(port), mix_ctl.u64); + cvmx_write_csr(p->mix + MIX_CTL, mix_ctl.u64); do { - mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(port)); + mix_ctl.u64 = cvmx_read_csr(p->mix + MIX_CTL); } while (mix_ctl.s.reset); } @@ -755,17 +794,17 @@ static int octeon_mgmt_open(struct net_device *netdev) oring1.u64 = 0; oring1.s.obase = p->tx_ring_handle >> 3; oring1.s.osize = OCTEON_MGMT_TX_RING_SIZE; - cvmx_write_csr(CVMX_MIXX_ORING1(port), oring1.u64); + cvmx_write_csr(p->mix + MIX_ORING1, oring1.u64); iring1.u64 = 0; iring1.s.ibase = p->rx_ring_handle >> 3; iring1.s.isize = OCTEON_MGMT_RX_RING_SIZE; - cvmx_write_csr(CVMX_MIXX_IRING1(port), iring1.u64); + cvmx_write_csr(p->mix + MIX_IRING1, iring1.u64); /* Disable packet I/O. */ - prtx_cfg.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port)); + prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG); prtx_cfg.s.en = 0; - cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), prtx_cfg.u64); + cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64); memcpy(sa.sa_data, netdev->dev_addr, ETH_ALEN); octeon_mgmt_set_mac_address(netdev, &sa); @@ -782,7 +821,7 @@ static int octeon_mgmt_open(struct net_device *netdev) mix_ctl.s.nbtarb = 0; /* Arbitration mode */ /* MII CB-request FIFO programmable high watermark */ mix_ctl.s.mrq_hwm = 1; - cvmx_write_csr(CVMX_MIXX_CTL(port), mix_ctl.u64); + cvmx_write_csr(p->mix + MIX_CTL, mix_ctl.u64); if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X) || OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) { @@ -809,16 +848,16 @@ static int octeon_mgmt_open(struct net_device *netdev) /* Clear statistics. */ /* Clear on read. */ - cvmx_write_csr(CVMX_AGL_GMX_RXX_STATS_CTL(port), 1); - cvmx_write_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(port), 0); - cvmx_write_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(port), 0); + cvmx_write_csr(p->agl + AGL_GMX_RX_STATS_CTL, 1); + cvmx_write_csr(p->agl + AGL_GMX_RX_STATS_PKTS_DRP, 0); + cvmx_write_csr(p->agl + AGL_GMX_RX_STATS_PKTS_BAD, 0); - cvmx_write_csr(CVMX_AGL_GMX_TXX_STATS_CTL(port), 1); - cvmx_write_csr(CVMX_AGL_GMX_TXX_STAT0(port), 0); - cvmx_write_csr(CVMX_AGL_GMX_TXX_STAT1(port), 0); + cvmx_write_csr(p->agl + AGL_GMX_TX_STATS_CTL, 1); + cvmx_write_csr(p->agl + AGL_GMX_TX_STAT0, 0); + cvmx_write_csr(p->agl + AGL_GMX_TX_STAT1, 0); /* Clear any pending interrupts */ - cvmx_write_csr(CVMX_MIXX_ISR(port), cvmx_read_csr(CVMX_MIXX_ISR(port))); + cvmx_write_csr(p->mix + MIX_ISR, cvmx_read_csr(p->mix + MIX_ISR)); if (request_irq(p->irq, octeon_mgmt_interrupt, 0, netdev->name, netdev)) { @@ -829,18 +868,18 @@ static int octeon_mgmt_open(struct net_device *netdev) /* Interrupt every single RX packet */ mix_irhwm.u64 = 0; mix_irhwm.s.irhwm = 0; - cvmx_write_csr(CVMX_MIXX_IRHWM(port), mix_irhwm.u64); + cvmx_write_csr(p->mix + MIX_IRHWM, mix_irhwm.u64); /* Interrupt when we have 1 or more packets to clean. */ mix_orhwm.u64 = 0; mix_orhwm.s.orhwm = 1; - cvmx_write_csr(CVMX_MIXX_ORHWM(port), mix_orhwm.u64); + cvmx_write_csr(p->mix + MIX_ORHWM, mix_orhwm.u64); /* Enable receive and transmit interrupts */ mix_intena.u64 = 0; mix_intena.s.ithena = 1; mix_intena.s.othena = 1; - cvmx_write_csr(CVMX_MIXX_INTENA(port), mix_intena.u64); + cvmx_write_csr(p->mix + MIX_INTENA, mix_intena.u64); /* Enable packet I/O. */ @@ -871,7 +910,7 @@ static int octeon_mgmt_open(struct net_device *netdev) * frame. GMX checks that the PREAMBLE is sent correctly. */ rxx_frm_ctl.s.pre_chk = 1; - cvmx_write_csr(CVMX_AGL_GMX_RXX_FRM_CTL(port), rxx_frm_ctl.u64); + cvmx_write_csr(p->agl + AGL_GMX_RX_FRM_CTL, rxx_frm_ctl.u64); /* Enable the AGL block */ agl_gmx_inf_mode.u64 = 0; @@ -879,13 +918,13 @@ static int octeon_mgmt_open(struct net_device *netdev) cvmx_write_csr(CVMX_AGL_GMX_INF_MODE, agl_gmx_inf_mode.u64); /* Configure the port duplex and enables */ - prtx_cfg.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port)); + prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG); prtx_cfg.s.tx_en = 1; prtx_cfg.s.rx_en = 1; prtx_cfg.s.en = 1; p->last_duplex = 1; prtx_cfg.s.duplex = p->last_duplex; - cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), prtx_cfg.u64); + cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64); p->last_link = 0; netif_carrier_off(netdev); @@ -949,7 +988,6 @@ static int octeon_mgmt_stop(struct net_device *netdev) static int octeon_mgmt_xmit(struct sk_buff *skb, struct net_device *netdev) { struct octeon_mgmt *p = netdev_priv(netdev); - int port = p->port; union mgmt_port_ring_entry re; unsigned long flags; int rv = NETDEV_TX_BUSY; @@ -993,7 +1031,7 @@ static int octeon_mgmt_xmit(struct sk_buff *skb, struct net_device *netdev) netdev->stats.tx_bytes += skb->len; /* Ring the bell. */ - cvmx_write_csr(CVMX_MIXX_ORING2(port), 1); + cvmx_write_csr(p->mix + MIX_ORING2, 1); rv = NETDEV_TX_OK; out: @@ -1071,10 +1109,14 @@ static const struct net_device_ops octeon_mgmt_ops = { static int __devinit octeon_mgmt_probe(struct platform_device *pdev) { - struct resource *res_irq; struct net_device *netdev; struct octeon_mgmt *p; - int i; + const __be32 *data; + const u8 *mac; + struct resource *res_mix; + struct resource *res_agl; + int len; + int result; netdev = alloc_etherdev(sizeof(struct octeon_mgmt)); if (netdev == NULL) @@ -1088,14 +1130,63 @@ static int __devinit octeon_mgmt_probe(struct platform_device *pdev) p->netdev = netdev; p->dev = &pdev->dev; - p->port = pdev->id; + data = of_get_property(pdev->dev.of_node, "cell-index", &len); + if (data && len == sizeof(*data)) { + p->port = be32_to_cpup(data); + } else { + dev_err(&pdev->dev, "no 'cell-index' property\n"); + result = -ENXIO; + goto err; + } + snprintf(netdev->name, IFNAMSIZ, "mgmt%d", p->port); - res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res_irq) + result = platform_get_irq(pdev, 0); + if (result < 0) + goto err; + + p->irq = result; + + res_mix = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res_mix == NULL) { + dev_err(&pdev->dev, "no 'reg' resource\n"); + result = -ENXIO; + goto err; + } + + res_agl = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (res_agl == NULL) { + dev_err(&pdev->dev, "no 'reg' resource\n"); + result = -ENXIO; + goto err; + } + + p->mix_phys = res_mix->start; + p->mix_size = resource_size(res_mix); + p->agl_phys = res_agl->start; + p->agl_size = resource_size(res_agl); + + + if (!devm_request_mem_region(&pdev->dev, p->mix_phys, p->mix_size, + res_mix->name)) { + dev_err(&pdev->dev, "request_mem_region (%s) failed\n", + res_mix->name); + result = -ENXIO; + goto err; + } + + if (!devm_request_mem_region(&pdev->dev, p->agl_phys, p->agl_size, + res_agl->name)) { + result = -ENXIO; + dev_err(&pdev->dev, "request_mem_region (%s) failed\n", + res_agl->name); goto err; + } + + + p->mix = (u64)devm_ioremap(&pdev->dev, p->mix_phys, p->mix_size); + p->agl = (u64)devm_ioremap(&pdev->dev, p->agl_phys, p->agl_size); - p->irq = res_irq->start; spin_lock_init(&p->lock); skb_queue_head_init(&p->tx_list); @@ -1108,24 +1199,26 @@ static int __devinit octeon_mgmt_probe(struct platform_device *pdev) netdev->netdev_ops = &octeon_mgmt_ops; netdev->ethtool_ops = &octeon_mgmt_ethtool_ops; - /* The mgmt ports get the first N MACs. */ - for (i = 0; i < 6; i++) - netdev->dev_addr[i] = octeon_bootinfo->mac_addr_base[i]; - netdev->dev_addr[5] += p->port; + mac = of_get_mac_address(pdev->dev.of_node); + + if (mac) + memcpy(netdev->dev_addr, mac, 6); - if (p->port >= octeon_bootinfo->mac_addr_count) - dev_err(&pdev->dev, - "Error %s: Using MAC outside of the assigned range: %pM\n", - netdev->name, netdev->dev_addr); + p->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0); - if (register_netdev(netdev)) + pdev->dev.coherent_dma_mask = DMA_BIT_MASK(64); + pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; + + result = register_netdev(netdev); + if (result) goto err; dev_info(&pdev->dev, "Version " DRV_VERSION "\n"); return 0; + err: free_netdev(netdev); - return -ENOENT; + return result; } static int __devexit octeon_mgmt_remove(struct platform_device *pdev) @@ -1137,10 +1230,19 @@ static int __devexit octeon_mgmt_remove(struct platform_device *pdev) return 0; } +static struct of_device_id octeon_mgmt_match[] = { + { + .compatible = "cavium,octeon-5750-mix", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, octeon_mgmt_match); + static struct platform_driver octeon_mgmt_driver = { .driver = { .name = "octeon_mgmt", .owner = THIS_MODULE, + .of_match_table = octeon_mgmt_match, }, .probe = octeon_mgmt_probe, .remove = __devexit_p(octeon_mgmt_remove), 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 9dbf38c10a68..24b787be6062 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 @@ -129,7 +129,6 @@ static int pch_gbe_set_settings(struct net_device *netdev, hw->mac.link_duplex = ecmd->duplex; hw->phy.autoneg_advertised = ecmd->advertising; hw->mac.autoneg = ecmd->autoneg; - pch_gbe_hal_phy_sw_reset(hw); /* reset the link */ if (netif_running(adapter->netdev)) { diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index b1006563f736..feb85d56c750 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -26,7 +26,7 @@ #include <linux/ptp_classify.h> #endif -#define DRV_VERSION "1.00" +#define DRV_VERSION "1.01" const char pch_driver_version[] = DRV_VERSION; #define PCI_DEVICE_ID_INTEL_IOH1_GBE 0x8802 /* Pci device ID */ @@ -35,7 +35,7 @@ const char pch_driver_version[] = DRV_VERSION; #define DSC_INIT16 0xC000 #define PCH_GBE_DMA_ALIGN 0 #define PCH_GBE_DMA_PADDING 2 -#define PCH_GBE_WATCHDOG_PERIOD (1 * HZ) /* watchdog time */ +#define PCH_GBE_WATCHDOG_PERIOD (5 * HZ) /* watchdog time */ #define PCH_GBE_COPYBREAK_DEFAULT 256 #define PCH_GBE_PCI_BAR 1 #define PCH_GBE_RESERVE_MEMORY 0x200000 /* 2MB */ @@ -1579,7 +1579,8 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter, struct sk_buff *skb; unsigned int i; unsigned int cleaned_count = 0; - bool cleaned = true; + bool cleaned = false; + int unused, thresh; pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean); @@ -1588,10 +1589,36 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter, pr_debug("gbec_status:0x%04x dma_status:0x%04x\n", tx_desc->gbec_status, tx_desc->dma_status); + unused = PCH_GBE_DESC_UNUSED(tx_ring); + thresh = tx_ring->count - PCH_GBE_TX_WEIGHT; + if ((tx_desc->gbec_status == DSC_INIT16) && (unused < thresh)) + { /* current marked clean, tx queue filling up, do extra clean */ + int j, k; + if (unused < 8) { /* tx queue nearly full */ + pr_debug("clean_tx: transmit queue warning (%x,%x) unused=%d\n", + tx_ring->next_to_clean,tx_ring->next_to_use,unused); + } + + /* current marked clean, scan for more that need cleaning. */ + k = i; + for (j = 0; j < PCH_GBE_TX_WEIGHT; j++) + { + tx_desc = PCH_GBE_TX_DESC(*tx_ring, k); + if (tx_desc->gbec_status != DSC_INIT16) break; /*found*/ + if (++k >= tx_ring->count) k = 0; /*increment, wrap*/ + } + if (j < PCH_GBE_TX_WEIGHT) { + pr_debug("clean_tx: unused=%d loops=%d found tx_desc[%x,%x:%x].gbec_status=%04x\n", + unused,j, i,k, tx_ring->next_to_use, tx_desc->gbec_status); + i = k; /*found one to clean, usu gbec_status==2000.*/ + } + } + while ((tx_desc->gbec_status & DSC_INIT16) == 0x0000) { pr_debug("gbec_status:0x%04x\n", tx_desc->gbec_status); buffer_info = &tx_ring->buffer_info[i]; skb = buffer_info->skb; + cleaned = true; if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_ABT)) { adapter->stats.tx_aborted_errors++; @@ -1639,18 +1666,21 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter, } pr_debug("called pch_gbe_unmap_and_free_tx_resource() %d count\n", cleaned_count); - /* Recover from running out of Tx resources in xmit_frame */ - spin_lock(&tx_ring->tx_lock); - if (unlikely(cleaned && (netif_queue_stopped(adapter->netdev)))) { - netif_wake_queue(adapter->netdev); - adapter->stats.tx_restart_count++; - pr_debug("Tx wake queue\n"); - } + if (cleaned_count > 0) { /*skip this if nothing cleaned*/ + /* Recover from running out of Tx resources in xmit_frame */ + spin_lock(&tx_ring->tx_lock); + if (unlikely(cleaned && (netif_queue_stopped(adapter->netdev)))) + { + netif_wake_queue(adapter->netdev); + adapter->stats.tx_restart_count++; + pr_debug("Tx wake queue\n"); + } - tx_ring->next_to_clean = i; + tx_ring->next_to_clean = i; - pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean); - spin_unlock(&tx_ring->tx_lock); + pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean); + spin_unlock(&tx_ring->tx_lock); + } return cleaned; } @@ -1988,6 +2018,7 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter) void pch_gbe_down(struct pch_gbe_adapter *adapter) { struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = adapter->pdev; struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring; /* signal that we're down so the interrupt handler does not @@ -2004,7 +2035,8 @@ void pch_gbe_down(struct pch_gbe_adapter *adapter) netif_carrier_off(netdev); netif_stop_queue(netdev); - pch_gbe_reset(adapter); + if ((pdev->error_state) && (pdev->error_state != pci_channel_io_normal)) + pch_gbe_reset(adapter); pch_gbe_clean_tx_ring(adapter, adapter->tx_ring); pch_gbe_clean_rx_ring(adapter, adapter->rx_ring); @@ -2127,13 +2159,6 @@ static int pch_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring; unsigned long flags; - if (unlikely(skb->len > (adapter->hw.mac.max_frame_size - 4))) { - pr_err("Transfer length Error: skb len: %d > max: %d\n", - skb->len, adapter->hw.mac.max_frame_size); - dev_kfree_skb_any(skb); - adapter->stats.tx_length_errors++; - return NETDEV_TX_OK; - } if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags)) { /* Collision - tell upper layer to requeue */ return NETDEV_TX_LOCKED; @@ -2387,7 +2412,7 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget) pch_gbe_clean_rx(adapter, adapter->rx_ring, &work_done, budget); cleaned = pch_gbe_clean_tx(adapter, adapter->tx_ring); - if (!cleaned) + if (cleaned) work_done = budget; /* If no Tx and not enough Rx work done, * exit the polling mode @@ -2793,6 +2818,7 @@ static int __init pch_gbe_init_module(void) { int ret; + pr_info("EG20T PCH Gigabit Ethernet Driver - version %s\n",DRV_VERSION); ret = pci_register_driver(&pch_gbe_driver); if (copybreak != PCH_GBE_COPYBREAK_DEFAULT) { if (copybreak == 0) { diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c index 3769f5711cc3..b53a3b60b648 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -4682,6 +4682,7 @@ static int __devinit qlge_probe(struct pci_dev *pdev, NETIF_F_HW_VLAN_TX | NETIF_F_RXCSUM; ndev->features = ndev->hw_features | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; + ndev->vlan_features = ndev->hw_features; if (test_bit(QL_DMA64, &qdev->flags)) ndev->features |= NETIF_F_HIGHDMA; diff --git a/drivers/net/ethernet/renesas/Kconfig b/drivers/net/ethernet/renesas/Kconfig index 46df3a04030c..24c2305d7948 100644 --- a/drivers/net/ethernet/renesas/Kconfig +++ b/drivers/net/ethernet/renesas/Kconfig @@ -8,7 +8,7 @@ config SH_ETH (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \ CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \ CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7734 || \ - CPU_SUBTYPE_SH7757 || ARCH_R8A7740) + CPU_SUBTYPE_SH7757 || ARCH_R8A7740 || ARCH_R8A7779) select CRC32 select NET_CORE select MII @@ -18,4 +18,4 @@ config SH_ETH Renesas SuperH Ethernet device driver. This driver supporting CPUs are: - SH7619, SH7710, SH7712, SH7724, SH7734, SH7763, SH7757, - and R8A7740. + R8A7740 and R8A7779. diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index af0b867a6cf6..bad8f2eec9b4 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -78,7 +78,7 @@ static void sh_eth_select_mii(struct net_device *ndev) #endif /* There is CPU dependent code */ -#if defined(CONFIG_CPU_SUBTYPE_SH7724) +#if defined(CONFIG_CPU_SUBTYPE_SH7724) || defined(CONFIG_ARCH_R8A7779) #define SH_ETH_RESET_DEFAULT 1 static void sh_eth_set_duplex(struct net_device *ndev) { @@ -93,13 +93,18 @@ static void sh_eth_set_duplex(struct net_device *ndev) static void sh_eth_set_rate(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); + unsigned int bits = ECMR_RTM; + +#if defined(CONFIG_ARCH_R8A7779) + bits |= ECMR_ELB; +#endif switch (mdp->speed) { case 10: /* 10BASE */ - sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_RTM, ECMR); + sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~bits, ECMR); break; case 100:/* 100BASE */ - sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_RTM, ECMR); + sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | bits, ECMR); break; default: break; diff --git a/drivers/net/ethernet/seeq/seeq8005.c b/drivers/net/ethernet/seeq/seeq8005.c index 698edbbfc149..d6e50de71186 100644 --- a/drivers/net/ethernet/seeq/seeq8005.c +++ b/drivers/net/ethernet/seeq/seeq8005.c @@ -736,9 +736,7 @@ MODULE_PARM_DESC(irq, "SEEQ 8005 IRQ number"); int __init init_module(void) { dev_seeq = seeq8005_probe(-1); - if (IS_ERR(dev_seeq)) - return PTR_ERR(dev_seeq); - return 0; + return PTR_RET(dev_seeq); } void __exit cleanup_module(void) diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 70554a1b2b02..65a8d49106a4 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -1503,6 +1503,11 @@ static int efx_probe_all(struct efx_nic *efx) goto fail2; } + BUILD_BUG_ON(EFX_DEFAULT_DMAQ_SIZE < EFX_RXQ_MIN_ENT); + if (WARN_ON(EFX_DEFAULT_DMAQ_SIZE < EFX_TXQ_MIN_ENT(efx))) { + rc = -EINVAL; + goto fail3; + } efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE; rc = efx_probe_filters(efx); @@ -2070,6 +2075,7 @@ static int efx_register_netdev(struct efx_nic *efx) net_dev->irq = efx->pci_dev->irq; net_dev->netdev_ops = &efx_netdev_ops; SET_ETHTOOL_OPS(net_dev, &efx_ethtool_ops); + net_dev->gso_max_segs = EFX_TSO_MAX_SEGS; rtnl_lock(); diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index be8f9158a714..70755c97251a 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h @@ -30,6 +30,7 @@ extern netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb); extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index); extern int efx_setup_tc(struct net_device *net_dev, u8 num_tc); +extern unsigned int efx_tx_max_skb_descs(struct efx_nic *efx); /* RX */ extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue); @@ -52,10 +53,15 @@ extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue); #define EFX_MAX_EVQ_SIZE 16384UL #define EFX_MIN_EVQ_SIZE 512UL -/* The smallest [rt]xq_entries that the driver supports. Callers of - * efx_wake_queue() assume that they can subsequently send at least one - * skb. Falcon/A1 may require up to three descriptors per skb_frag. */ -#define EFX_MIN_RING_SIZE (roundup_pow_of_two(2 * 3 * MAX_SKB_FRAGS)) +/* Maximum number of TCP segments we support for soft-TSO */ +#define EFX_TSO_MAX_SEGS 100 + +/* The smallest [rt]xq_entries that the driver supports. RX minimum + * is a bit arbitrary. For TX, we must have space for at least 2 + * TSO skbs. + */ +#define EFX_RXQ_MIN_ENT 128U +#define EFX_TXQ_MIN_ENT(efx) (2 * efx_tx_max_skb_descs(efx)) /* Filters */ extern int efx_probe_filters(struct efx_nic *efx); diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 10536f93b561..8cba2df82b18 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -680,21 +680,27 @@ static int efx_ethtool_set_ringparam(struct net_device *net_dev, struct ethtool_ringparam *ring) { struct efx_nic *efx = netdev_priv(net_dev); + u32 txq_entries; if (ring->rx_mini_pending || ring->rx_jumbo_pending || ring->rx_pending > EFX_MAX_DMAQ_SIZE || ring->tx_pending > EFX_MAX_DMAQ_SIZE) return -EINVAL; - if (ring->rx_pending < EFX_MIN_RING_SIZE || - ring->tx_pending < EFX_MIN_RING_SIZE) { + if (ring->rx_pending < EFX_RXQ_MIN_ENT) { netif_err(efx, drv, efx->net_dev, - "TX and RX queues cannot be smaller than %ld\n", - EFX_MIN_RING_SIZE); + "RX queues cannot be smaller than %u\n", + EFX_RXQ_MIN_ENT); return -EINVAL; } - return efx_realloc_channels(efx, ring->rx_pending, ring->tx_pending); + txq_entries = max(ring->tx_pending, EFX_TXQ_MIN_ENT(efx)); + if (txq_entries != ring->tx_pending) + netif_warn(efx, drv, efx->net_dev, + "increasing TX queue size to minimum of %u\n", + txq_entries); + + return efx_realloc_channels(efx, ring->rx_pending, txq_entries); } static int efx_ethtool_set_pauseparam(struct net_device *net_dev, diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c index 9b225a7769f7..18713436b443 100644 --- a/drivers/net/ethernet/sfc/tx.c +++ b/drivers/net/ethernet/sfc/tx.c @@ -119,6 +119,25 @@ efx_max_tx_len(struct efx_nic *efx, dma_addr_t dma_addr) return len; } +unsigned int efx_tx_max_skb_descs(struct efx_nic *efx) +{ + /* Header and payload descriptor for each output segment, plus + * one for every input fragment boundary within a segment + */ + unsigned int max_descs = EFX_TSO_MAX_SEGS * 2 + MAX_SKB_FRAGS; + + /* Possibly one more per segment for the alignment workaround */ + if (EFX_WORKAROUND_5391(efx)) + max_descs += EFX_TSO_MAX_SEGS; + + /* Possibly more for PCIe page boundaries within input fragments */ + if (PAGE_SIZE > EFX_PAGE_SIZE) + max_descs += max_t(unsigned int, MAX_SKB_FRAGS, + DIV_ROUND_UP(GSO_MAX_SIZE, EFX_PAGE_SIZE)); + + return max_descs; +} + /* * Add a socket buffer to a TX queue * diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index ab4c376cb276..f2d3665430ad 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -82,9 +82,7 @@ struct stmmac_priv { struct stmmac_counters mmc; struct dma_features dma_cap; int hw_cap_support; -#ifdef CONFIG_HAVE_CLK struct clk *stmmac_clk; -#endif int clk_csr; int synopsys_id; struct timer_list eee_ctrl_timer; @@ -113,46 +111,6 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, void stmmac_disable_eee_mode(struct stmmac_priv *priv); bool stmmac_eee_init(struct stmmac_priv *priv); -#ifdef CONFIG_HAVE_CLK -static inline int stmmac_clk_enable(struct stmmac_priv *priv) -{ - if (!IS_ERR(priv->stmmac_clk)) - return clk_prepare_enable(priv->stmmac_clk); - - return 0; -} - -static inline void stmmac_clk_disable(struct stmmac_priv *priv) -{ - if (IS_ERR(priv->stmmac_clk)) - return; - - clk_disable_unprepare(priv->stmmac_clk); -} -static inline int stmmac_clk_get(struct stmmac_priv *priv) -{ - priv->stmmac_clk = clk_get(priv->device, NULL); - - if (IS_ERR(priv->stmmac_clk)) - return PTR_ERR(priv->stmmac_clk); - - return 0; -} -#else -static inline int stmmac_clk_enable(struct stmmac_priv *priv) -{ - return 0; -} -static inline void stmmac_clk_disable(struct stmmac_priv *priv) -{ -} -static inline int stmmac_clk_get(struct stmmac_priv *priv) -{ - return 0; -} -#endif /* CONFIG_HAVE_CLK */ - - #ifdef CONFIG_STMMAC_PLATFORM extern struct platform_driver stmmac_pltfr_driver; static inline int stmmac_register_platform(void) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index f6b04c1a3672..c136162e6473 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -28,6 +28,7 @@ https://bugzilla.stlinux.com/ *******************************************************************************/ +#include <linux/clk.h> #include <linux/kernel.h> #include <linux/interrupt.h> #include <linux/ip.h> @@ -173,12 +174,8 @@ static void stmmac_verify_args(void) static void stmmac_clk_csr_set(struct stmmac_priv *priv) { -#ifdef CONFIG_HAVE_CLK u32 clk_rate; - if (IS_ERR(priv->stmmac_clk)) - return; - clk_rate = clk_get_rate(priv->stmmac_clk); /* Platform provided default clk_csr would be assumed valid @@ -200,7 +197,6 @@ static void stmmac_clk_csr_set(struct stmmac_priv *priv) * we can not estimate the proper divider as it is not known * the frequency of clk_csr_i. So we do not change the default * divider. */ -#endif } #if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG) @@ -1070,7 +1066,7 @@ static int stmmac_open(struct net_device *dev) } else priv->tm->enable = 1; #endif - stmmac_clk_enable(priv); + clk_enable(priv->stmmac_clk); stmmac_check_ether_addr(priv); @@ -1192,7 +1188,7 @@ open_error: if (priv->phydev) phy_disconnect(priv->phydev); - stmmac_clk_disable(priv); + clk_disable(priv->stmmac_clk); return ret; } @@ -1250,7 +1246,7 @@ static int stmmac_release(struct net_device *dev) #ifdef CONFIG_STMMAC_DEBUG_FS stmmac_exit_fs(); #endif - stmmac_clk_disable(priv); + clk_disable(priv->stmmac_clk); return 0; } @@ -2078,11 +2074,14 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, ret = register_netdev(ndev); if (ret) { pr_err("%s: ERROR %i registering the device\n", __func__, ret); - goto error; + goto error_netdev_register; } - if (stmmac_clk_get(priv)) + priv->stmmac_clk = clk_get(priv->device, STMMAC_RESOURCE_NAME); + if (IS_ERR(priv->stmmac_clk)) { pr_warning("%s: warning: cannot get CSR clock\n", __func__); + goto error_clk_get; + } /* If a specific clk_csr value is passed from the platform * this means that the CSR Clock Range selection cannot be @@ -2100,15 +2099,17 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, if (ret < 0) { pr_debug("%s: MDIO bus (id: %d) registration failed", __func__, priv->plat->bus_id); - goto error; + goto error_mdio_register; } return priv; -error: - netif_napi_del(&priv->napi); - +error_mdio_register: + clk_put(priv->stmmac_clk); +error_clk_get: unregister_netdev(ndev); +error_netdev_register: + netif_napi_del(&priv->napi); free_netdev(ndev); return NULL; @@ -2177,7 +2178,7 @@ int stmmac_suspend(struct net_device *ndev) else { stmmac_set_mac(priv->ioaddr, false); /* Disable clock in case of PWM is off */ - stmmac_clk_disable(priv); + clk_disable(priv->stmmac_clk); } spin_unlock_irqrestore(&priv->lock, flags); return 0; @@ -2202,7 +2203,7 @@ int stmmac_resume(struct net_device *ndev) priv->hw->mac->pmt(priv->ioaddr, 0); else /* enable the clk prevously disabled */ - stmmac_clk_enable(priv); + clk_enable(priv->stmmac_clk); netif_device_attach(ndev); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index cd01ee7ecef1..b93245c11995 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -74,7 +74,7 @@ static int __devinit stmmac_probe_config_dt(struct platform_device *pdev, * the necessary resources and invokes the main to init * the net device, register the mdio bus etc. */ -static int stmmac_pltfr_probe(struct platform_device *pdev) +static int __devinit stmmac_pltfr_probe(struct platform_device *pdev) { int ret = 0; struct resource *res; diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c index 3b5c4571b55e..d15c888e9df8 100644 --- a/drivers/net/ethernet/ti/davinci_cpdma.c +++ b/drivers/net/ethernet/ti/davinci_cpdma.c @@ -538,11 +538,12 @@ EXPORT_SYMBOL_GPL(cpdma_chan_create); int cpdma_chan_destroy(struct cpdma_chan *chan) { - struct cpdma_ctlr *ctlr = chan->ctlr; + struct cpdma_ctlr *ctlr; unsigned long flags; if (!chan) return -EINVAL; + ctlr = chan->ctlr; spin_lock_irqsave(&ctlr->lock, flags); if (chan->state != CPDMA_STATE_IDLE) diff --git a/drivers/net/ethernet/wiznet/Kconfig b/drivers/net/ethernet/wiznet/Kconfig index cb18043f5830..b4d281626fb4 100644 --- a/drivers/net/ethernet/wiznet/Kconfig +++ b/drivers/net/ethernet/wiznet/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_WIZNET bool "WIZnet devices" + depends on HAS_IOMEM default y ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c index 482648fcf0b6..98934bdf6acf 100644 --- a/drivers/net/ethernet/xscale/ixp4xx_eth.c +++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c @@ -1003,6 +1003,7 @@ static int ixp4xx_nway_reset(struct net_device *dev) } int ixp46x_phc_index = -1; +EXPORT_SYMBOL_GPL(ixp46x_phc_index); static int ixp4xx_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info) |