diff options
33 files changed, 218 insertions, 233 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 56c2d75..87f1d39 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -150,7 +150,7 @@ config MACVTAP config VXLAN tristate "Virtual eXtensible Local Area Network (VXLAN)" - depends on EXPERIMENTAL && INET + depends on INET ---help--- This allows one to create vxlan virtual interfaces that provide Layer 2 Networks over Layer 3 Networks. VXLAN is often used diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 3fd3288..bf985c0 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -436,6 +436,8 @@ static int bgmac_dma_alloc(struct bgmac *bgmac) } for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) { + int j; + ring = &bgmac->rx_ring[i]; ring->num_slots = BGMAC_RX_RING_SLOTS; ring->mmio_base = ring_base[i]; @@ -458,8 +460,8 @@ static int bgmac_dma_alloc(struct bgmac *bgmac) bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n"); /* Alloc RX slots */ - for (i = 0; i < ring->num_slots; i++) { - err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[i]); + for (j = 0; j < ring->num_slots; j++) { + err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[j]); if (err) { bgmac_err(bgmac, "Can't allocate skb for slot in RX ring\n"); goto err_dma_free; @@ -496,6 +498,8 @@ static void bgmac_dma_init(struct bgmac *bgmac) } for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) { + int j; + ring = &bgmac->rx_ring[i]; /* We don't implement unaligned addressing, so enable first */ @@ -505,11 +509,11 @@ static void bgmac_dma_init(struct bgmac *bgmac) bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGHI, upper_32_bits(ring->dma_base)); - for (i = 0, dma_desc = ring->cpu_base; i < ring->num_slots; - i++, dma_desc++) { + for (j = 0, dma_desc = ring->cpu_base; j < ring->num_slots; + j++, dma_desc++) { ctl0 = ctl1 = 0; - if (i == ring->num_slots - 1) + if (j == ring->num_slots - 1) ctl0 |= BGMAC_DESC_CTL0_EOT; ctl1 |= BGMAC_RX_BUF_SIZE & BGMAC_DESC_CTL1_LEN; /* Is there any BGMAC device that requires extension? */ @@ -517,8 +521,8 @@ static void bgmac_dma_init(struct bgmac *bgmac) * B43_DMA64_DCTL1_ADDREXT_MASK; */ - dma_desc->addr_low = cpu_to_le32(lower_32_bits(ring->slots[i].dma_addr)); - dma_desc->addr_high = cpu_to_le32(upper_32_bits(ring->slots[i].dma_addr)); + dma_desc->addr_low = cpu_to_le32(lower_32_bits(ring->slots[j].dma_addr)); + dma_desc->addr_high = cpu_to_le32(upper_32_bits(ring->slots[j].dma_addr)); dma_desc->ctl0 = cpu_to_le32(ctl0); dma_desc->ctl1 = cpu_to_le32(ctl1); } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index c6da77f..1663e0b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -13013,64 +13013,6 @@ static int bnx2x_84833_common_init_phy(struct bnx2x *bp, return 0; } -static int bnx2x_84833_pre_init_phy(struct bnx2x *bp, - struct bnx2x_phy *phy, - u8 port) -{ - u16 val, cnt; - /* Wait for FW completing its initialization. */ - for (cnt = 0; cnt < 1500; cnt++) { - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, &val); - if (!(val & (1<<15))) - break; - usleep_range(1000, 2000); - } - if (cnt >= 1500) { - DP(NETIF_MSG_LINK, "84833 reset timeout\n"); - return -EINVAL; - } - - /* Put the port in super isolate mode. */ - bnx2x_cl45_read(bp, phy, - MDIO_CTL_DEVAD, - MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val); - val |= MDIO_84833_SUPER_ISOLATE; - bnx2x_cl45_write(bp, phy, - MDIO_CTL_DEVAD, - MDIO_84833_TOP_CFG_XGPHY_STRAP1, val); - - /* Save spirom version */ - bnx2x_save_848xx_spirom_version(phy, bp, port); - return 0; -} - -int bnx2x_pre_init_phy(struct bnx2x *bp, - u32 shmem_base, - u32 shmem2_base, - u32 chip_id, - u8 port) -{ - int rc = 0; - struct bnx2x_phy phy; - if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base, shmem2_base, - port, &phy) != 0) { - DP(NETIF_MSG_LINK, "populate_phy failed\n"); - return -EINVAL; - } - bnx2x_set_mdio_clk(bp, chip_id, phy.mdio_ctrl); - switch (phy.type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834: - rc = bnx2x_84833_pre_init_phy(bp, &phy, port); - break; - default: - break; - } - return rc; -} - static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[], u32 shmem2_base_path[], u8 phy_index, u32 ext_phy_type, u32 chip_id) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c index 3624612..531eebf 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c @@ -98,7 +98,7 @@ static inline int bnx2x_pfvf_status_codes(int rc) } } -int bnx2x_send_msg2pf(struct bnx2x *bp, u8 *done, dma_addr_t msg_mapping) +static int bnx2x_send_msg2pf(struct bnx2x *bp, u8 *done, dma_addr_t msg_mapping) { struct cstorm_vf_zone_data __iomem *zone_data = REG_ADDR(bp, PXP_VF_ADDR_CSDM_GLOBAL_START); @@ -141,7 +141,7 @@ int bnx2x_send_msg2pf(struct bnx2x *bp, u8 *done, dma_addr_t msg_mapping) return 0; } -int bnx2x_get_vf_id(struct bnx2x *bp, u32 *vf_id) +static int bnx2x_get_vf_id(struct bnx2x *bp, u32 *vf_id) { u32 me_reg; int tout = 10, interval = 100; /* Wait for 1 sec */ diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 29d82cf..fccc3bf 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -1782,24 +1782,6 @@ fec_probe(struct platform_device *pdev) fep->phy_interface = ret; } - for (i = 0; i < FEC_IRQ_NUM; i++) { - irq = platform_get_irq(pdev, i); - if (irq < 0) { - if (i) - break; - ret = irq; - goto failed_irq; - } - ret = request_irq(irq, fec_enet_interrupt, IRQF_DISABLED, pdev->name, ndev); - if (ret) { - while (--i >= 0) { - irq = platform_get_irq(pdev, i); - free_irq(irq, ndev); - } - goto failed_irq; - } - } - pinctrl = devm_pinctrl_get_select_default(&pdev->dev); if (IS_ERR(pinctrl)) { ret = PTR_ERR(pinctrl); @@ -1850,6 +1832,24 @@ fec_probe(struct platform_device *pdev) if (ret) goto failed_init; + for (i = 0; i < FEC_IRQ_NUM; i++) { + irq = platform_get_irq(pdev, i); + if (irq < 0) { + if (i) + break; + ret = irq; + goto failed_irq; + } + ret = request_irq(irq, fec_enet_interrupt, IRQF_DISABLED, pdev->name, ndev); + if (ret) { + while (--i >= 0) { + irq = platform_get_irq(pdev, i); + free_irq(irq, ndev); + } + goto failed_irq; + } + } + ret = fec_enet_mii_init(pdev); if (ret) goto failed_mii_init; @@ -1867,6 +1867,12 @@ failed_register: fec_enet_mii_remove(fep); failed_mii_init: failed_init: + for (i = 0; i < FEC_IRQ_NUM; i++) { + irq = platform_get_irq(pdev, i); + if (irq > 0) + free_irq(irq, ndev); + } +failed_irq: failed_regulator: clk_disable_unprepare(fep->clk_ahb); clk_disable_unprepare(fep->clk_ipg); @@ -1874,12 +1880,6 @@ failed_regulator: clk_disable_unprepare(fep->clk_ptp); failed_pin: failed_clk: - for (i = 0; i < FEC_IRQ_NUM; i++) { - irq = platform_get_irq(pdev, i); - if (irq > 0) - free_irq(irq, ndev); - } -failed_irq: iounmap(fep->hwp); failed_ioremap: free_netdev(ndev); @@ -1899,17 +1899,17 @@ fec_drv_remove(struct platform_device *pdev) unregister_netdev(ndev); fec_enet_mii_remove(fep); - for (i = 0; i < FEC_IRQ_NUM; i++) { - int irq = platform_get_irq(pdev, i); - if (irq > 0) - free_irq(irq, ndev); - } del_timer_sync(&fep->time_keep); clk_disable_unprepare(fep->clk_ptp); if (fep->ptp_clock) ptp_clock_unregister(fep->ptp_clock); clk_disable_unprepare(fep->clk_ahb); clk_disable_unprepare(fep->clk_ipg); + for (i = 0; i < FEC_IRQ_NUM; i++) { + int irq = platform_get_irq(pdev, i); + if (irq > 0) + free_irq(irq, ndev); + } iounmap(fep->hwp); free_netdev(ndev); diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 4b5e8a6..d2c5441 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -2906,21 +2906,23 @@ static void gfar_netpoll(struct net_device *dev) /* If the device has multiple interrupts, run tx/rx */ if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { for (i = 0; i < priv->num_grps; i++) { - disable_irq(priv->gfargrp[i].interruptTransmit); - disable_irq(priv->gfargrp[i].interruptReceive); - disable_irq(priv->gfargrp[i].interruptError); - gfar_interrupt(priv->gfargrp[i].interruptTransmit, - &priv->gfargrp[i]); - enable_irq(priv->gfargrp[i].interruptError); - enable_irq(priv->gfargrp[i].interruptReceive); - enable_irq(priv->gfargrp[i].interruptTransmit); + struct gfar_priv_grp *grp = &priv->gfargrp[i]; + + disable_irq(gfar_irq(grp, TX)->irq); + disable_irq(gfar_irq(grp, RX)->irq); + disable_irq(gfar_irq(grp, ER)->irq); + gfar_interrupt(gfar_irq(grp, TX)->irq, grp); + enable_irq(gfar_irq(grp, ER)->irq); + enable_irq(gfar_irq(grp, RX)->irq); + enable_irq(gfar_irq(grp, TX)->irq); } } else { for (i = 0; i < priv->num_grps; i++) { - disable_irq(priv->gfargrp[i].interruptTransmit); - gfar_interrupt(priv->gfargrp[i].interruptTransmit, - &priv->gfargrp[i]); - enable_irq(priv->gfargrp[i].interruptTransmit); + struct gfar_priv_grp *grp = &priv->gfargrp[i]; + + disable_irq(gfar_irq(grp, TX)->irq); + gfar_interrupt(gfar_irq(grp, TX)->irq, grp); + enable_irq(gfar_irq(grp, TX)->irq); } } } diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 5088dc5..5385474 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -1829,7 +1829,7 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv) } #ifdef CONFIG_RFS_ACCEL - priv->dev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->rx_ring_num); + priv->dev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->mdev->dev->caps.comp_pool); if (!priv->dev->rx_cpu_rmap) goto err; #endif @@ -2067,7 +2067,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, err = -ENOMEM; goto out; } - priv->tx_cq = kzalloc(sizeof(struct mlx4_en_cq) * MAX_RX_RINGS, + priv->tx_cq = kzalloc(sizeof(struct mlx4_en_cq) * MAX_TX_RINGS, GFP_KERNEL); if (!priv->tx_cq) { err = -ENOMEM; diff --git a/drivers/net/ethernet/pasemi/pasemi_mac.c b/drivers/net/ethernet/pasemi/pasemi_mac.c index 0be5844..b1cfbb7 100644 --- a/drivers/net/ethernet/pasemi/pasemi_mac.c +++ b/drivers/net/ethernet/pasemi/pasemi_mac.c @@ -579,8 +579,9 @@ static void pasemi_mac_free_tx_resources(struct pasemi_mac *mac) (TX_RING_SIZE-1)].dma; freed = pasemi_mac_unmap_tx_skb(mac, nfrags, info->skb, dmas); - } else + } else { freed = 2; + } } kfree(txring->ring_info); @@ -808,8 +809,9 @@ static int pasemi_mac_clean_rx(struct pasemi_mac_rxring *rx, skb->ip_summed = CHECKSUM_UNNECESSARY; skb->csum = (macrx & XCT_MACRX_CSUM_M) >> XCT_MACRX_CSUM_S; - } else + } else { skb_checksum_none_assert(skb); + } packets++; tot_bytes += len; @@ -1829,10 +1831,11 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_err(&mac->pdev->dev, "register_netdev failed with error %d\n", err); goto out; - } else if netif_msg_probe(mac) + } else if (netif_msg_probe(mac)) { printk(KERN_INFO "%s: PA Semi %s: intf %d, hw addr %pM\n", dev->name, mac->type == MAC_TYPE_GMAC ? "GMAC" : "XAUI", mac->dma_if, dev->dev_addr); + } return err; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 11c3db6..ba3c72f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -38,8 +38,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 1 -#define _QLCNIC_LINUX_SUBVERSION 34 -#define QLCNIC_LINUX_VERSIONID "5.1.34" +#define _QLCNIC_LINUX_SUBVERSION 35 +#define QLCNIC_LINUX_VERSIONID "5.1.35" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) @@ -1755,7 +1755,7 @@ static inline int qlcnic_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode) static inline int qlcnic_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode) { - return adapter->ahw->hw_ops->config_loopback(adapter, mode); + return adapter->ahw->hw_ops->clear_loopback(adapter, mode); } static inline int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index c53832b..5c033f2 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c @@ -589,13 +589,6 @@ static int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter) qlcnic_83xx_register_nic_idc_func(adapter, 1); qlcnic_83xx_enable_mbx_intrpt(adapter); - if ((adapter->flags & QLCNIC_MSIX_ENABLED)) { - if (qlcnic_83xx_config_intrpt(adapter, 1)) { - netdev_err(adapter->netdev, - "Failed to enable mbx intr\n"); - return -EIO; - } - } if (qlcnic_83xx_configure_opmode(adapter)) { qlcnic_83xx_idc_enter_failed_state(adapter, 1); diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index ff4fa37..e6d2dea 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -53,7 +53,7 @@ #define FEATURE_8_WAKEUP_FILTERS (0x01) #define FEATURE_PHY_NLP_CROSSOVER (0x02) -#define FEATURE_AUTOSUSPEND (0x04) +#define FEATURE_REMOTE_WAKEUP (0x04) #define SUSPEND_SUSPEND0 (0x01) #define SUSPEND_SUSPEND1 (0x02) @@ -1146,7 +1146,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) (val == ID_REV_CHIP_ID_89530_) || (val == ID_REV_CHIP_ID_9730_)) pdata->features = (FEATURE_8_WAKEUP_FILTERS | FEATURE_PHY_NLP_CROSSOVER | - FEATURE_AUTOSUSPEND); + FEATURE_REMOTE_WAKEUP); else if (val == ID_REV_CHIP_ID_9512_) pdata->features = FEATURE_8_WAKEUP_FILTERS; @@ -1247,10 +1247,12 @@ static int smsc95xx_enter_suspend0(struct usbnet *dev) /* read back PM_CTRL */ ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); + if (ret < 0) + return ret; pdata->suspend_flags |= SUSPEND_SUSPEND0; - return ret; + return 0; } static int smsc95xx_enter_suspend1(struct usbnet *dev) @@ -1293,10 +1295,12 @@ static int smsc95xx_enter_suspend1(struct usbnet *dev) val |= (PM_CTL_WUPS_ED_ | PM_CTL_ED_EN_); ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); + if (ret < 0) + return ret; pdata->suspend_flags |= SUSPEND_SUSPEND1; - return ret; + return 0; } static int smsc95xx_enter_suspend2(struct usbnet *dev) @@ -1313,10 +1317,12 @@ static int smsc95xx_enter_suspend2(struct usbnet *dev) val |= PM_CTL_SUS_MODE_2; ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); + if (ret < 0) + return ret; pdata->suspend_flags |= SUSPEND_SUSPEND2; - return ret; + return 0; } static int smsc95xx_enter_suspend3(struct usbnet *dev) @@ -1372,7 +1378,7 @@ static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up) if (!link_up) { /* link is down so enter EDPD mode, but only if device can * reliably resume from it. This check should be redundant - * as current FEATURE_AUTOSUSPEND parts also support + * as current FEATURE_REMOTE_WAKEUP parts also support * FEATURE_PHY_NLP_CROSSOVER but it's included for clarity */ if (!(pdata->features & FEATURE_PHY_NLP_CROSSOVER)) { netdev_warn(dev->net, "EDPD not supported\n"); @@ -1412,15 +1418,6 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message) u32 val, link_up; int ret; - /* TODO: don't indicate this feature to usb framework if - * our current hardware doesn't have the capability - */ - if ((message.event == PM_EVENT_AUTO_SUSPEND) && - (!(pdata->features & FEATURE_AUTOSUSPEND))) { - netdev_warn(dev->net, "autosuspend not supported\n"); - return -EBUSY; - } - ret = usbnet_suspend(intf, message); if (ret < 0) { netdev_warn(dev->net, "usbnet_suspend error\n"); @@ -1435,7 +1432,8 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message) /* determine if link is up using only _nopm functions */ link_up = smsc95xx_link_ok_nopm(dev); - if (message.event == PM_EVENT_AUTO_SUSPEND) { + if (message.event == PM_EVENT_AUTO_SUSPEND && + (pdata->features & FEATURE_REMOTE_WAKEUP)) { ret = smsc95xx_autosuspend(dev, link_up); goto done; } @@ -1872,11 +1870,11 @@ static int smsc95xx_manage_power(struct usbnet *dev, int on) dev->intf->needs_remote_wakeup = on; - if (pdata->features & FEATURE_AUTOSUSPEND) + if (pdata->features & FEATURE_REMOTE_WAKEUP) return 0; - /* this chip revision doesn't support autosuspend */ - netdev_info(dev->net, "hardware doesn't support USB autosuspend\n"); + /* this chip revision isn't capable of remote wakeup */ + netdev_info(dev->net, "hardware isn't capable of remote wakeup\n"); if (on) usb_autopm_get_interface_no_resume(dev->intf); diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index ffb97b2..4aad350 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -1385,8 +1385,8 @@ vmxnet3_rq_cleanup_all(struct vmxnet3_adapter *adapter) } -void vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq, - struct vmxnet3_adapter *adapter) +static void vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq, + struct vmxnet3_adapter *adapter) { int i; int j; diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c index 9bc542b..a0feb17 100644 --- a/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c @@ -448,10 +448,8 @@ vmxnet3_get_ringparam(struct net_device *netdev, param->rx_mini_max_pending = 0; param->rx_jumbo_max_pending = 0; - param->rx_pending = adapter->rx_queue[0].rx_ring[0].size * - adapter->num_rx_queues; - param->tx_pending = adapter->tx_queue[0].tx_ring.size * - adapter->num_tx_queues; + param->rx_pending = adapter->rx_queue[0].rx_ring[0].size; + param->tx_pending = adapter->tx_queue[0].tx_ring.size; param->rx_mini_pending = 0; param->rx_jumbo_pending = 0; } diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 9d70421..f736823 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -33,6 +33,7 @@ #include <net/arp.h> #include <net/ndisc.h> #include <net/ip.h> +#include <net/ipip.h> #include <net/icmp.h> #include <net/udp.h> #include <net/rtnetlink.h> @@ -962,13 +963,13 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev) iph->daddr = dst; iph->saddr = fl4.saddr; iph->ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); + tunnel_ip_select_ident(skb, old_iph, &rt->dst); vxlan_set_owner(dev, skb); /* See iptunnel_xmit() */ if (skb->ip_summed != CHECKSUM_PARTIAL) skb->ip_summed = CHECKSUM_NONE; - ip_select_ident(iph, &rt->dst, NULL); err = ip_local_out(skb); if (likely(net_xmit_eval(err) == 0)) { diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 806e34c..0568273 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4214,7 +4214,6 @@ redo: mutex_unlock(&wl->mutex); cancel_delayed_work_sync(&dev->periodic_work); cancel_work_sync(&wl->tx_work); - cancel_work_sync(&wl->firmware_load); mutex_lock(&wl->mutex); dev = wl->current_dev; if (!dev || b43_status(dev) < B43_STAT_STARTED) { @@ -5434,6 +5433,7 @@ static void b43_bcma_remove(struct bcma_device *core) /* We must cancel any work here before unregistering from ieee80211, * as the ieee80211 unreg will destroy the workqueue. */ cancel_work_sync(&wldev->restart_work); + cancel_work_sync(&wl->firmware_load); B43_WARN_ON(!wl); if (!wldev->fw.ucode.data) @@ -5510,6 +5510,7 @@ static void b43_ssb_remove(struct ssb_device *sdev) /* We must cancel any work here before unregistering from ieee80211, * as the ieee80211 unreg will destroy the workqueue. */ cancel_work_sync(&wldev->restart_work); + cancel_work_sync(&wl->firmware_load); B43_WARN_ON(!wl); if (!wldev->fw.ucode.data) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index cecc3ef..2af9c0f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -4615,8 +4615,10 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp, switch (ifevent->action) { case BRCMF_E_IF_ADD: /* waiting process may have timed out */ - if (!cfg->vif_event.vif) + if (!cfg->vif_event.vif) { + mutex_unlock(&event->vif_event_lock); return -EBADF; + } ifp->vif = vif; vif->ifp = ifp; diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 4b54bcf..35c7972 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -171,7 +171,7 @@ static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state) { struct mwifiex_adapter *adapter; struct pcie_service_card *card; - int hs_actived, i; + int hs_actived; if (pdev) { card = (struct pcie_service_card *) pci_get_drvdata(pdev); @@ -191,9 +191,6 @@ static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state) /* Indicate device suspended */ adapter->is_suspended = true; - for (i = 0; i < adapter->priv_num; i++) - netif_carrier_off(adapter->priv[i]->netdev); - return 0; } @@ -209,7 +206,6 @@ static int mwifiex_pcie_resume(struct pci_dev *pdev) { struct mwifiex_adapter *adapter; struct pcie_service_card *card; - int i; if (pdev) { card = (struct pcie_service_card *) pci_get_drvdata(pdev); @@ -231,10 +227,6 @@ static int mwifiex_pcie_resume(struct pci_dev *pdev) adapter->is_suspended = false; - for (i = 0; i < adapter->priv_num; i++) - if (adapter->priv[i]->media_connected) - netif_carrier_on(adapter->priv[i]->netdev); - mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), MWIFIEX_ASYNC_CMD); @@ -916,17 +908,8 @@ static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter) static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; - const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; - u32 rdptr; - - /* Read the TX ring read pointer set by firmware */ - if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) { - dev_err(adapter->dev, - "Flush TXBD: failed to read reg->tx_rdptr\n"); - return -1; - } - if (!mwifiex_pcie_txbd_empty(card, rdptr)) { + if (!mwifiex_pcie_txbd_empty(card, card->txbd_rdptr)) { card->txbd_flush = 1; /* write pointer already set at last send * send dnld-rdy intr again, wait for completion. diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index e63f646..363ba31 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -161,7 +161,6 @@ static int mwifiex_sdio_suspend(struct device *dev) struct sdio_mmc_card *card; struct mwifiex_adapter *adapter; mmc_pm_flag_t pm_flag = 0; - int i; int ret = 0; if (func) { @@ -198,9 +197,6 @@ static int mwifiex_sdio_suspend(struct device *dev) /* Indicate device suspended */ adapter->is_suspended = true; - for (i = 0; i < adapter->priv_num; i++) - netif_carrier_off(adapter->priv[i]->netdev); - return ret; } @@ -220,7 +216,6 @@ static int mwifiex_sdio_resume(struct device *dev) struct sdio_mmc_card *card; struct mwifiex_adapter *adapter; mmc_pm_flag_t pm_flag = 0; - int i; if (func) { pm_flag = sdio_get_host_pm_caps(func); @@ -243,10 +238,6 @@ static int mwifiex_sdio_resume(struct device *dev) adapter->is_suspended = false; - for (i = 0; i < adapter->priv_num; i++) - if (adapter->priv[i]->media_connected) - netif_carrier_on(adapter->priv[i]->netdev); - /* Disable Host Sleep */ mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), MWIFIEX_ASYNC_CMD); diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index d06cc5c..218a3b6 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -331,7 +331,7 @@ static inline void vlan_set_encap_proto(struct sk_buff *skb, struct vlan_hdr *vhdr) { __be16 proto; - unsigned char *rawp; + unsigned short *rawp; /* * Was a VLAN packet, grab the encapsulated protocol, which the layer @@ -344,8 +344,8 @@ static inline void vlan_set_encap_proto(struct sk_buff *skb, return; } - rawp = skb->data; - if (*(unsigned short *) rawp == 0xFFFF) + rawp = (unsigned short *)(vhdr + 1); + if (*rawp == 0xFFFF) /* * This is a magic hack to spot IPX packets. Older Novell * breaks the protocol design and runs IPX over 802.3 without diff --git a/include/net/icmp.h b/include/net/icmp.h index 9ac2524..081439f 100644 --- a/include/net/icmp.h +++ b/include/net/icmp.h @@ -41,6 +41,7 @@ struct net; extern void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info); extern int icmp_rcv(struct sk_buff *skb); +extern void icmp_err(struct sk_buff *, u32 info); extern int icmp_init(void); extern void icmp_out_count(struct net *net, unsigned char type); diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h index 7ca75cb..fd4ee01 100644 --- a/include/net/inet6_hashtables.h +++ b/include/net/inet6_hashtables.h @@ -28,16 +28,16 @@ struct inet_hashinfo; -/* I have no idea if this is a good hash for v6 or not. -DaveM */ static inline unsigned int inet6_ehashfn(struct net *net, const struct in6_addr *laddr, const u16 lport, const struct in6_addr *faddr, const __be16 fport) { - u32 ports = (lport ^ (__force u16)fport); + u32 ports = (((u32)lport) << 16) | (__force u32)fport; return jhash_3words((__force u32)laddr->s6_addr32[3], - (__force u32)faddr->s6_addr32[3], - ports, inet_ehash_secret + net_hash_mix(net)); + ipv6_addr_jhash(faddr), + ports, + inet_ehash_secret + net_hash_mix(net)); } static inline int inet6_sk_ehashfn(const struct sock *sk) diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h index 3f237db..76c3fe5 100644 --- a/include/net/inet_frag.h +++ b/include/net/inet_frag.h @@ -114,7 +114,13 @@ static inline void init_frag_mem_limit(struct netns_frags *nf) static inline int sum_frag_mem_limit(struct netns_frags *nf) { - return percpu_counter_sum_positive(&nf->mem); + int res; + + local_bh_disable(); + res = percpu_counter_sum_positive(&nf->mem); + local_bh_enable(); + + return res; } static inline void inet_frag_lru_move(struct inet_frag_queue *q) diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index a4196cb..7235ae7 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -203,6 +203,7 @@ static inline void inet_sk_copy_descendant(struct sock *sk_to, extern int inet_sk_rebuild_header(struct sock *sk); extern u32 inet_ehash_secret; +extern u32 ipv6_hash_secret; extern void build_ehash_secret(void); static inline unsigned int inet_ehashfn(struct net *net, diff --git a/include/net/ipip.h b/include/net/ipip.h index 21947cf..fd19625 100644 --- a/include/net/ipip.h +++ b/include/net/ipip.h @@ -71,4 +71,21 @@ static inline void iptunnel_xmit(struct sk_buff *skb, struct net_device *dev) } } +static inline void tunnel_ip_select_ident(struct sk_buff *skb, + const struct iphdr *old_iph, + struct dst_entry *dst) +{ + struct iphdr *iph = ip_hdr(skb); + + if (iph->frag_off & htons(IP_DF)) + iph->id = 0; + else { + /* Use inner packet iph-id if possible. */ + if (skb->protocol == htons(ETH_P_IP) && old_iph->id) + iph->id = old_iph->id; + else + __ip_select_ident(iph, dst, + (skb_shinfo(skb)->gso_segs ?: 1) - 1); + } +} #endif diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 851d541..64d12e7 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -15,6 +15,7 @@ #include <linux/ipv6.h> #include <linux/hardirq.h> +#include <linux/jhash.h> #include <net/if_inet6.h> #include <net/ndisc.h> #include <net/flow.h> @@ -514,6 +515,17 @@ static inline u32 ipv6_addr_hash(const struct in6_addr *a) #endif } +/* more secured version of ipv6_addr_hash() */ +static inline u32 ipv6_addr_jhash(const struct in6_addr *a) +{ + u32 v = (__force u32)a->s6_addr32[0] ^ (__force u32)a->s6_addr32[1]; + + return jhash_3words(v, + (__force u32)a->s6_addr32[2], + (__force u32)a->s6_addr32[3], + ipv6_hash_secret); +} + static inline bool ipv6_addr_loopback(const struct in6_addr *a) { #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 diff --git a/net/core/dev.c b/net/core/dev.c index 17bc535..18d8b5a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1882,8 +1882,10 @@ int netif_set_xps_queue(struct net_device *dev, struct cpumask *mask, u16 index) if (!new_dev_maps) new_dev_maps = kzalloc(maps_sz, GFP_KERNEL); - if (!new_dev_maps) + if (!new_dev_maps) { + mutex_unlock(&xps_map_mutex); return -ENOMEM; + } map = dev_maps ? xmap_dereference(dev_maps->cpu_map[cpu]) : NULL; diff --git a/net/core/sock.c b/net/core/sock.c index fe96c5d..b261a79 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -186,8 +186,10 @@ void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg) static struct lock_class_key af_family_keys[AF_MAX]; static struct lock_class_key af_family_slock_keys[AF_MAX]; +#if defined(CONFIG_MEMCG_KMEM) struct static_key memcg_socket_limit_enabled; EXPORT_SYMBOL(memcg_socket_limit_enabled); +#endif /* * Make lock validator output more readable. (we pre-construct these diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index 602cd63..a29e90c 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c @@ -97,21 +97,6 @@ void sock_diag_unregister(const struct sock_diag_handler *hnld) } EXPORT_SYMBOL_GPL(sock_diag_unregister); -static const inline struct sock_diag_handler *sock_diag_lock_handler(int family) -{ - if (sock_diag_handlers[family] == NULL) - request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK, - NETLINK_SOCK_DIAG, family); - - mutex_lock(&sock_diag_table_mutex); - return sock_diag_handlers[family]; -} - -static inline void sock_diag_unlock_handler(const struct sock_diag_handler *h) -{ - mutex_unlock(&sock_diag_table_mutex); -} - static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) { int err; @@ -121,12 +106,20 @@ static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (nlmsg_len(nlh) < sizeof(*req)) return -EINVAL; - hndl = sock_diag_lock_handler(req->sdiag_family); + if (req->sdiag_family >= AF_MAX) + return -EINVAL; + + if (sock_diag_handlers[req->sdiag_family] == NULL) + request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK, + NETLINK_SOCK_DIAG, req->sdiag_family); + + mutex_lock(&sock_diag_table_mutex); + hndl = sock_diag_handlers[req->sdiag_family]; if (hndl == NULL) err = -ENOENT; else err = hndl->dump(skb, nlh); - sock_diag_unlock_handler(hndl); + mutex_unlock(&sock_diag_table_mutex); return err; } diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index e225a4e..68f6a94 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -248,8 +248,12 @@ EXPORT_SYMBOL(inet_listen); u32 inet_ehash_secret __read_mostly; EXPORT_SYMBOL(inet_ehash_secret); +u32 ipv6_hash_secret __read_mostly; +EXPORT_SYMBOL(ipv6_hash_secret); + /* - * inet_ehash_secret must be set exactly once + * inet_ehash_secret must be set exactly once, and to a non nul value + * ipv6_hash_secret must be set exactly once. */ void build_ehash_secret(void) { @@ -259,7 +263,8 @@ void build_ehash_secret(void) get_random_bytes(&rnd, sizeof(rnd)); } while (rnd == 0); - cmpxchg(&inet_ehash_secret, 0, rnd); + if (cmpxchg(&inet_ehash_secret, 0, rnd) == 0) + get_random_bytes(&ipv6_hash_secret, sizeof(ipv6_hash_secret)); } EXPORT_SYMBOL(build_ehash_secret); @@ -1327,8 +1332,10 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, if (skb->next != NULL) iph->frag_off |= htons(IP_MF); offset += (skb->len - skb->mac_len - iph->ihl * 4); - } else - iph->id = htons(id++); + } else { + if (!(iph->frag_off & htons(IP_DF))) + iph->id = htons(id++); + } iph->tot_len = htons(skb->len - skb->mac_len); iph->check = 0; iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl); @@ -1572,7 +1579,7 @@ static const struct net_offload udp_offload = { static const struct net_protocol icmp_protocol = { .handler = icmp_rcv, - .err_handler = ping_err, + .err_handler = icmp_err, .no_policy = 1, .netns_ok = 1, }; diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 17ff9fd..3ac5dff 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -934,6 +934,29 @@ error: goto drop; } +void icmp_err(struct sk_buff *skb, u32 info) +{ + struct iphdr *iph = (struct iphdr *)skb->data; + struct icmphdr *icmph = (struct icmphdr *)(skb->data+(iph->ihl<<2)); + int type = icmp_hdr(skb)->type; + int code = icmp_hdr(skb)->code; + struct net *net = dev_net(skb->dev); + + /* + * Use ping_err to handle all icmp errors except those + * triggered by ICMP_ECHOREPLY which sent from kernel. + */ + if (icmph->type != ICMP_ECHOREPLY) { + ping_err(skb, info); + return; + } + + if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) + ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_ICMP, 0); + else if (type == ICMP_REDIRECT) + ipv4_redirect(skb, net, 0, 0, IPPROTO_ICMP, 0); +} + /* * This table is the definition of how we handle ICMP. */ diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 5ef4da7..d0ef0e6 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -735,7 +735,7 @@ drop: return 0; } -static struct sk_buff *handle_offloads(struct sk_buff *skb) +static struct sk_buff *handle_offloads(struct ip_tunnel *tunnel, struct sk_buff *skb) { int err; @@ -745,8 +745,12 @@ static struct sk_buff *handle_offloads(struct sk_buff *skb) goto error; skb_shinfo(skb)->gso_type |= SKB_GSO_GRE; return skb; - } - if (skb->ip_summed != CHECKSUM_PARTIAL) + } else if (skb->ip_summed == CHECKSUM_PARTIAL && + tunnel->parms.o_flags&GRE_CSUM) { + err = skb_checksum_help(skb); + if (unlikely(err)) + goto error; + } else if (skb->ip_summed != CHECKSUM_PARTIAL) skb->ip_summed = CHECKSUM_NONE; return skb; @@ -776,7 +780,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev int err; int pkt_len; - skb = handle_offloads(skb); + skb = handle_offloads(tunnel, skb); if (IS_ERR(skb)) { dev->stats.tx_dropped++; return NETDEV_TX_OK; @@ -970,7 +974,8 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev iph->daddr = fl4.daddr; iph->saddr = fl4.saddr; iph->ttl = ttl; - iph->id = 0; + + tunnel_ip_select_ident(skb, old_iph, &rt->dst); if (ttl == 0) { if (skb->protocol == htons(ETH_P_IP)) @@ -1101,14 +1106,8 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev) tunnel->hlen = addend; /* TCP offload with GRE SEQ is not supported. */ if (!(tunnel->parms.o_flags & GRE_SEQ)) { - /* device supports enc gso offload*/ - if (tdev->hw_enc_features & NETIF_F_GRE_GSO) { - dev->features |= NETIF_F_TSO; - dev->hw_features |= NETIF_F_TSO; - } else { - dev->features |= NETIF_F_GSO_SOFTWARE; - dev->hw_features |= NETIF_F_GSO_SOFTWARE; - } + dev->features |= NETIF_F_GSO_SOFTWARE; + dev->hw_features |= NETIF_F_GSO_SOFTWARE; } return mtu; diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 55c4ee1..2e91006 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -322,8 +322,8 @@ void ping_err(struct sk_buff *skb, u32 info) struct iphdr *iph = (struct iphdr *)skb->data; struct icmphdr *icmph = (struct icmphdr *)(skb->data+(iph->ihl<<2)); struct inet_sock *inet_sock; - int type = icmph->type; - int code = icmph->code; + int type = icmp_hdr(skb)->type; + int code = icmp_hdr(skb)->code; struct net *net = dev_net(skb->dev); struct sock *sk; int harderr; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index fd0cea1..e2b4461 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1351,8 +1351,8 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len) return 0; } -/* Calculate MSS. Not accounting for SACKs here. */ -int tcp_mtu_to_mss(struct sock *sk, int pmtu) +/* Calculate MSS not accounting any TCP options. */ +static inline int __tcp_mtu_to_mss(struct sock *sk, int pmtu) { const struct tcp_sock *tp = tcp_sk(sk); const struct inet_connection_sock *icsk = inet_csk(sk); @@ -1381,13 +1381,17 @@ int tcp_mtu_to_mss(struct sock *sk, int pmtu) /* Then reserve room for full set of TCP options and 8 bytes of data */ if (mss_now < 48) mss_now = 48; - - /* Now subtract TCP options size, not including SACKs */ - mss_now -= tp->tcp_header_len - sizeof(struct tcphdr); - return mss_now; } +/* Calculate MSS. Not accounting for SACKs here. */ +int tcp_mtu_to_mss(struct sock *sk, int pmtu) +{ + /* Subtract TCP options size, not including SACKs */ + return __tcp_mtu_to_mss(sk, pmtu) - + (tcp_sk(sk)->tcp_header_len - sizeof(struct tcphdr)); +} + /* Inverse of above */ int tcp_mss_to_mtu(struct sock *sk, int mss) { @@ -2930,7 +2934,7 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn) */ if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < tp->rx_opt.mss_clamp) tp->rx_opt.mss_clamp = tp->rx_opt.user_mss; - space = tcp_mtu_to_mss(sk, inet_csk(sk)->icsk_pmtu_cookie) - + space = __tcp_mtu_to_mss(sk, inet_csk(sk)->icsk_pmtu_cookie) - MAX_TCP_OPTION_SPACE; syn_data = skb_copy_expand(syn, skb_headroom(syn), space, |