From 7f7d6c282e9d9b1721fdcdeac71383b7b0b60700 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 21 Feb 2013 09:21:50 +0000 Subject: net: fec: Ensure that initialization is done prior to request_irq() Currently request_irq() is called prior to fec_enet_init() and fec_ptp_init(), which causes the following crash on a mx53qsb: Unable to handle kernel NULL pointer dereference at virtual address 00000002 pgd = 80004000 [00000002] *pgd=00000000 Internal error: Oops: 5 [#1] SMP ARM Modules linked in: CPU: 0 Not tainted (3.8.0-rc7-next-20130215+ #346) PC is at fec_enet_interrupt+0xd0/0x348 LR is at fec_enet_interrupt+0xb8/0x348 pc : [<80372b7c>] lr : [<80372b64>] psr: 60000193 sp : df855c20 ip : df855c20 fp : df855c74 r10: 00000516 r9 : 1c000000 r8 : 00000000 r7 : 00000000 r6 : 00000000 r5 : 00000000 r4 : df9b7800 r3 : df9b7df4 r2 : 00000000 r1 : 00000000 r0 : df9b7d34 Ensure that such initialization functions are called prior to requesting the interrupts, so that all necessary the data structures are in place when the irqs occur. Signed-off-by: Fabio Estevam Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 29d82cf1528..2dbb36c985c 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -1782,6 +1782,15 @@ fec_probe(struct platform_device *pdev) fep->phy_interface = ret; } + fep->bufdesc_ex = + pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX; + if (fep->bufdesc_ex) + fec_ptp_init(ndev, pdev); + + ret = fec_enet_init(ndev); + if (ret) + goto failed_init; + for (i = 0; i < FEC_IRQ_NUM; i++) { irq = platform_get_irq(pdev, i); if (irq < 0) { @@ -1819,8 +1828,6 @@ fec_probe(struct platform_device *pdev) } fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp"); - fep->bufdesc_ex = - pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX; if (IS_ERR(fep->clk_ptp)) { ret = PTR_ERR(fep->clk_ptp); fep->bufdesc_ex = 0; @@ -1843,13 +1850,6 @@ fec_probe(struct platform_device *pdev) fec_reset_phy(pdev); - if (fep->bufdesc_ex) - fec_ptp_init(ndev, pdev); - - ret = fec_enet_init(ndev); - if (ret) - goto failed_init; - ret = fec_enet_mii_init(pdev); if (ret) goto failed_mii_init; @@ -1866,7 +1866,6 @@ fec_probe(struct platform_device *pdev) failed_register: fec_enet_mii_remove(fep); failed_mii_init: -failed_init: failed_regulator: clk_disable_unprepare(fep->clk_ahb); clk_disable_unprepare(fep->clk_ipg); @@ -1881,6 +1880,7 @@ failed_clk: } failed_irq: iounmap(fep->hwp); +failed_init: failed_ioremap: free_netdev(ndev); failed_alloc_etherdev: @@ -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); -- cgit v1.2.3-70-g09d2 From d09529e6a6317801d2bbf3eeebf650b1bf2f78e8 Mon Sep 17 00:00:00 2001 From: Shahed Shaikh Date: Thu, 21 Feb 2013 11:09:46 +0000 Subject: qlcnic: Fix internal loopback test for 82xx adapter o Use correct function to clear loopback mode. Signed-off-by: Shahed Shaikh Signed-off-by: Jitendra Kalsaria Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 11c3db6daff..474b4794a94 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -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, -- cgit v1.2.3-70-g09d2 From 8e29965db68a91b992b2c84558675c7c5a932a20 Mon Sep 17 00:00:00 2001 From: Manish Chopra Date: Thu, 21 Feb 2013 11:09:47 +0000 Subject: qlcnic: Fix configure interrupts for 83xx adapter types Signed-off-by: Manish Chopra Signed-off-by: Jitendra Kalsaria Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index c53832b02b3..5c033f268ca 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); -- cgit v1.2.3-70-g09d2 From 0ab8a9f5fa94ac625c1f19acc48db299416c6d49 Mon Sep 17 00:00:00 2001 From: Jitendra Kalsaria Date: Thu, 21 Feb 2013 11:09:48 +0000 Subject: qlcnic: Bump up the version to 5.1.35 Signed-off-by: Jitendra Kalsaria Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 474b4794a94..ba3c72fce1f 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)) -- cgit v1.2.3-70-g09d2 From 1499d9fa54a41942973bfc2c4ab12ccc5f1e15de Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Tue, 19 Feb 2013 15:09:47 -0500 Subject: mwifiex: don't drop carrier flag over suspend If the system suspends with mwifiex wifi powered on, and is then woken by an ICMP ping packet, the ping response is discarded by the kernel because the kernel incorrectly thinks there is no carrier. I can't see any valid reason to want to report loss of carrier here, so remove the offending code. Fixes http://dev.laptop.org/ticket/12554 Signed-off-by: Daniel Drake Acked-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/pcie.c | 10 +--------- drivers/net/wireless/mwifiex/sdio.c | 9 --------- 2 files changed, 1 insertion(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 4b54bcf382f..22db934bd40 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); diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index e35b67a9e6a..e819a4e82ca 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); -- cgit v1.2.3-70-g09d2 From 48f4d91679c0e0b26747f8adbb18e5212eb6d621 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Wed, 20 Feb 2013 21:12:58 -0800 Subject: mwifiex: fix system freeze while reloading driver Unload sequence for mwifiex PCIE driver is as follows: 1. Invoking cleanup module from kernel results into pci_unregister_driver 2. Kernel invokes PCIE remove() handler which disconnects all interfaces. 3. One step during disconnect is to clean PCIE TX rings. During this we read txbd_rdptr from FW. While loading driver next time, we see pci_enable_device() results into system freeze. This may have happened because we accessed PCI device after unregistering from bus driver. Removing this ioread() operation resolves this bug. Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/pcie.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 22db934bd40..35c79722c36 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -908,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. -- cgit v1.2.3-70-g09d2 From dc4a787c8f52f9d6e46156953f8014a3353bcbc7 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 22 Feb 2013 21:32:20 +0800 Subject: brcmfmac: fix missing unlock on error in brcmf_notify_vif_event() Add the missing unlock before return from function brcmf_notify_vif_event() in the error handling case. Signed-off-by: Wei Yongjun Reported-by: Dan Carpenter Acked-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index cecc3eff72e..2af9c0f0798 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; -- cgit v1.2.3-70-g09d2 From e2f8d555ec04a0beb965ea76e3a150993e8f0436 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 22 Feb 2013 06:40:45 +0000 Subject: net: fec: Fix division by zero commit 7f7d6c282 (net: fec: Ensure that initialization is done prior to request_irq()) placed fec_ptp_init() into a point that ptp clock was not available, which causes a division by zero in fec_ptp_start_cyclecounter(): [ 17.895723] Division by zero in kernel. [ 17.899571] Backtrace: [ 17.902094] [<80012564>] (dump_backtrace+0x0/0x10c) from [<8056deec>] (dump_stack+0x18/0x1c) [ 17.910539] r6:bfba8500 r5:8075c950 r4:bfba8000 r3:bfbd0000 [ 17.916284] [<8056ded4>] (dump_stack+0x0/0x1c) from [<80012688>] (__div0+0x18/0x20) [ 17.923968] [<80012670>] (__div0+0x0/0x20) from [<802829c4>] (Ldiv0+0x8/0x10) [ 17.931140] [<80398534>] (fec_ptp_start_cyclecounter+0x0/0x110) from [<80394f64>] (fec_restart+0x6c8/0x754) [ 17.940898] [<8039489c>] (fec_restart+0x0/0x754) from [<803969a0>] (fec_enet_adjust_link+0xdc/0x108) [ 17.950046] [<803968c4>] (fec_enet_adjust_link+0x0/0x108) from [<80390bc4>] (phy_state_machine+0x178/0x534) ... Fix this by rearraging the code so that fec_ptp_init() is called only after the clocks have been properly acquired. Tested on both mx53 and mx6 platforms. Reported-by: Jim Baxter Signed-off-by: Fabio Estevam Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.c | 68 ++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 2dbb36c985c..fccc3bf2141 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -1782,33 +1782,6 @@ fec_probe(struct platform_device *pdev) fep->phy_interface = ret; } - fep->bufdesc_ex = - pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX; - if (fep->bufdesc_ex) - fec_ptp_init(ndev, pdev); - - ret = fec_enet_init(ndev); - 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; - } - } - pinctrl = devm_pinctrl_get_select_default(&pdev->dev); if (IS_ERR(pinctrl)) { ret = PTR_ERR(pinctrl); @@ -1828,6 +1801,8 @@ fec_probe(struct platform_device *pdev) } fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp"); + fep->bufdesc_ex = + pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX; if (IS_ERR(fep->clk_ptp)) { ret = PTR_ERR(fep->clk_ptp); fep->bufdesc_ex = 0; @@ -1850,6 +1825,31 @@ fec_probe(struct platform_device *pdev) fec_reset_phy(pdev); + if (fep->bufdesc_ex) + fec_ptp_init(ndev, pdev); + + ret = fec_enet_init(ndev); + 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; @@ -1866,6 +1866,13 @@ fec_probe(struct platform_device *pdev) 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); @@ -1873,14 +1880,7 @@ 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_init: failed_ioremap: free_netdev(ndev); failed_alloc_etherdev: -- cgit v1.2.3-70-g09d2 From 427a96252d8eee7b9bbafce15bd37fa3387ede55 Mon Sep 17 00:00:00 2001 From: Kleber Sacilotto de Souza Date: Fri, 22 Feb 2013 14:58:02 +0000 Subject: mlx4_en: fix allocation of device tx_cq The memory to hold the network device tx_cq is not being allocated with the correct size in mlx4_en_init_netdev(). It should use MAX_TX_RINGS instead of MAX_RX_RINGS. This can cause problems if the number of tx rings being used is greater than MAX_RX_RINGS. Signed-off-by: Kleber Sacilotto de Souza Acked-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 5088dc5c3d1..5944dd60b9e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -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; -- cgit v1.2.3-70-g09d2 From 3770699675dd1b8fc1e86ff369eb3cce44e10082 Mon Sep 17 00:00:00 2001 From: Kleber Sacilotto de Souza Date: Fri, 22 Feb 2013 19:14:52 +0000 Subject: mlx4_en: fix allocation of CPU affinity reverse-map The mlx4_en driver allocates the number of objects for the CPU affinity reverse-map based on the number of rx rings of the device. However, mlx4_assign_eq() calls irq_cpu_rmap_add() as many times as IRQ's are assigned to EQ's, which can be as large as mlx4_dev->caps.comp_pool. If caps.comp_pool is larger than rx_ring_num we will eventually hit the BUG_ON() in cpu_rmap_add(). Fix this problem by allocating space for the maximum number of CPU affinity reverse-map objects we might want to add. Signed-off-by: Kleber Sacilotto de Souza Acked-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 5944dd60b9e..5385474bb52 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 -- cgit v1.2.3-70-g09d2 From c9b20a5effcb29acf0f8a2a31c875073b2a0c74e Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 22 Feb 2013 21:25:38 +0000 Subject: vxlan: remove depends on CONFIG_EXPERIMENTAL The CONFIG_EXPERIMENTAL config item has not carried much meaning for a while now and is almost always enabled by default. As agreed during the Linux kernel summit, remove it from any "depends on" lines in Kconfigs. Signed-off-by: Kees Cook Cc: Stephen Hemminger Cc: David S. Miller Signed-off-by: David S. Miller --- drivers/net/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 6a70184c3f2..a02a3ad5374 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -151,7 +151,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 -- cgit v1.2.3-70-g09d2 From 62ed839dba70edfdc20a9aab92edff0451078584 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 24 Feb 2013 05:38:31 +0000 Subject: gianfar: fix compile fail for NET_POLL=y due to struct packing Commit ee873fda3bec7c668407b837fc5519eb961fcd37 ("gianfar: Pack struct gfar_priv_grp into three cachelines") moved the irq number and names off into a separate struct and created accessors for them. However it was never tested with NET_POLL enabled, and so some conversions that were simply overlooked went undetected until now. Make the netpoll ones also use the gfar_irq() accessors. Reported-by: Benjamin Herrenschmidt Cc: Benjamin Herrenschmidt Cc: Claudiu Manoil Cc: Jianhua Xie Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/gianfar.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 4b5e8a69248..d2c5441d1bf 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); } } } -- cgit v1.2.3-70-g09d2 From 732ac8cacbbbdbf9f5ba92299cc747db3abfefd0 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Fri, 22 Feb 2013 08:01:10 +0000 Subject: bnx2x: remove dead code and make local funcs static Sparse warned about several functions that were unnecessarily global. After making them static, discovered that several functions were actually never used. Compile tested only. Signed-off-by: Stephen Hemminger Acked-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 58 ------------------------ drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c | 4 +- 2 files changed, 2 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index c6da77fa9d0..1663e0b6b5a 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 36246129864..531eebf40d6 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 */ -- cgit v1.2.3-70-g09d2 From 280b74f7f957130385a0f5184b50fc5800520146 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Fri, 22 Feb 2013 08:26:29 +0000 Subject: vmxnet3: make local function static Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index ffb97b2a15a..4aad350e4da 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; -- cgit v1.2.3-70-g09d2 From 48412a7e7db656b6a1e52799c39f461a06292395 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Fri, 22 Feb 2013 10:32:24 +0000 Subject: vmxnet3: fix ethtool ring buffer size setting Noticed that vmxnet3's get_ringparam function was returning the summation of all ring buffers on a NIC, rather than just the size of any one ring. This causes problems when a vmxnet3 instance has multiple queues, as ethtool, when setting ring parameters, first gets the current ring parameters to set the existing values in the set_ringparm commannd. The result is, that unless both rx and tx ring sizes are set in a single operation, which ever ring is not set will silently have its ring count multiplied by the number of queues on the NIC until it reaches a driver defined maxiumum value. Fix it by not multiplying the rx and tx ring sizes by the number of queues in the system, like every other driver. Tested by myself successfully. Signed-off-by: Neil Horman CC: Shreyas Bhatewara CC: "VMware, Inc." CC: "David S. Miller" Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_ethtool.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c index 9bc542be293..a0feb17a023 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; } -- cgit v1.2.3-70-g09d2 From ea5cdccc46d392b73d941c723630d37094e8e8ea Mon Sep 17 00:00:00 2001 From: Syam Sidhardhan Date: Sun, 24 Feb 2013 13:01:19 +0000 Subject: net/pasemi: Fix missing coding style Fix missing () & { } Signed-off-by: Syam Sidhardhan Acked-by: Olof Johansson Signed-off-by: David S. Miller --- drivers/net/ethernet/pasemi/pasemi_mac.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/pasemi/pasemi_mac.c b/drivers/net/ethernet/pasemi/pasemi_mac.c index 0be5844d637..b1cfbb75ff1 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; -- cgit v1.2.3-70-g09d2 From 8dc98eb2e8ccfbfb90348f8dc42f4a528a8a9961 Mon Sep 17 00:00:00 2001 From: Pravin B Shelar Date: Fri, 22 Feb 2013 07:30:40 +0000 Subject: VXLAN: Use tunnel_ip_select_ident() for tunnel IP-Identification. tunnel_ip_select_ident() is more efficient when generating ip-header id given inner packet is of ipv4 type. Signed-off-by: Pravin B Shelar Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 9d70421cf3a..f736823f843 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -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)) { -- cgit v1.2.3-70-g09d2 From 63a02ce1c5c59baa40b99756492e3ec8d6b51483 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 25 Feb 2013 06:09:24 +0000 Subject: b43: Fix lockdep splat on module unload On unload, b43 produces a lockdep warning that can be summarized in the following way: ====================================================== [ INFO: possible circular locking dependency detected ] 3.8.0-wl+ #117 Not tainted ------------------------------------------------------- modprobe/5557 is trying to acquire lock: ((&wl->firmware_load)){+.+.+.}, at: [] flush_work+0x0/0x2a0 but task is already holding lock: (rtnl_mutex){+.+.+.}, at: [] rtnl_lock+0x12/0x20 which lock already depends on the new lock. [ INFO: possible circular locking dependency detected ] ====================================================== The full output is available at http://lkml.indiana.edu/hypermail/linux/kernel/1302.3/00060.html. To summarize, commit 6b6fa58 added a 'cancel_work_sync(&wl->firmware_load)' call in the wrong place. The fix is to move the cancel_work_sync() call to b43_bcma_remove() and b43_ssb_remove(). Thanks to Johannes Berg and Michael Buesch for help in diagnosing the log output. Signed-off-by: Larry Finger Cc: Stable [V3.5+] Signed-off-by: David S. Miller --- drivers/net/wireless/b43/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 806e34c1928..05682736e46 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) -- cgit v1.2.3-70-g09d2 From 70a737b795d1d2fa0c1b54b8b7870c86cedd03ac Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 25 Feb 2013 08:22:26 +0000 Subject: bgmac: fix indexing of 2nd level loops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We were using the same variable for iterating two nested loops. Reported-by: Tijs Van Buggenhout Signed-off-by: Rafał Miłecki Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 3fd32880e52..bf985c04524 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); } -- cgit v1.2.3-70-g09d2 From 7643721471117d5f62ca36f328d3dc8d84af4402 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 22 Feb 2013 03:05:03 +0000 Subject: usbnet: smsc95xx: fix suspend failure The three below functions: smsc95xx_enter_suspend0() smsc95xx_enter_suspend1() smsc95xx_enter_suspend2() return > 0 in case of success, so they will cause smsc95xx_suspend() to return > 0 and cause suspend failure. The bug is introduced in commit 3b9f7d(smsc95xx: fix error handling in suspend failure case). Cc: [3.8] Cc: Steve Glendinning Signed-off-by: Ming Lei Signed-off-by: David S. Miller --- drivers/net/usb/smsc95xx.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index ff4fa37dfd1..b2721bc8728 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -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) -- cgit v1.2.3-70-g09d2 From 42e21c01071b4406341e32aba65e40c7f9b7e973 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 22 Feb 2013 03:05:04 +0000 Subject: usbnet: smsc95xx: fix broken runtime suspend Commit b2d4b150(smsc95xx: enable dynamic autosuspend) implements autosuspend, but breaks current runtime suspend, such as: when the interface becomes down, the usb device can't be put into runtime suspend any more. This patch fixes the broken runtime suspend. Cc: Steve Glendinning Signed-off-by: Ming Lei Signed-off-by: David S. Miller --- drivers/net/usb/smsc95xx.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index b2721bc8728..7fa9622aabb 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -1418,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"); @@ -1441,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_AUTOSUSPEND)) { ret = smsc95xx_autosuspend(dev, link_up); goto done; } -- cgit v1.2.3-70-g09d2 From eb970ff07c15f13eb474f643fd165ebe3e4e24b2 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 22 Feb 2013 03:05:05 +0000 Subject: usbnet: smsc95xx: rename FEATURE_AUTOSUSPEND The name of FEATURE_AUTOSUSPEND is very misleading and the actual meaning is remote wakeup, but a device incapable of remote wakeup still can support USB autosuspend under some situations, so rename it to avoid misunderstanding. Cc: Steve Glendinning Signed-off-by: Ming Lei Signed-off-by: David S. Miller --- drivers/net/usb/smsc95xx.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 7fa9622aabb..e6d2dea1373 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; @@ -1378,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"); @@ -1433,7 +1433,7 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message) link_up = smsc95xx_link_ok_nopm(dev); if (message.event == PM_EVENT_AUTO_SUSPEND && - (pdata->features & FEATURE_AUTOSUSPEND)) { + (pdata->features & FEATURE_REMOTE_WAKEUP)) { ret = smsc95xx_autosuspend(dev, link_up); goto done; } @@ -1870,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); -- cgit v1.2.3-70-g09d2