From 1dbac5c578ead0d0f20a06b036d19c109a5a4fb9 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 3 Nov 2015 15:03:33 +0100 Subject: NFC: nfcmrvl: fix SPI driver dependencies The newly added nfcmrvl_spi driver uses the spi_nci infrastructure, but does not have a Kconfig dependency on that, so we can get a link-time error: drivers/built-in.o: In function `nfcmrvl_spi_nci_send': (.text+0x1428dc): undefined reference to `nci_spi_send' drivers/built-in.o: In function `nfcmrvl_spi_probe': (.text+0x142a24): undefined reference to `nci_spi_allocate_spi' drivers/built-in.o: In function `nfcmrvl_spi_int_irq_thread_fn': (.text+0x142abc): undefined reference to `nci_spi_read' This clarifies the dependency. Signed-off-by: Arnd Bergmann Fixes: caf6e49bf6d0 ("NFC: nfcmrvl: add spi driver") Signed-off-by: Samuel Ortiz --- drivers/nfc/nfcmrvl/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/nfc/nfcmrvl/Kconfig b/drivers/nfc/nfcmrvl/Kconfig index 444ca94697d9..670af76922e0 100644 --- a/drivers/nfc/nfcmrvl/Kconfig +++ b/drivers/nfc/nfcmrvl/Kconfig @@ -44,7 +44,7 @@ config NFC_MRVL_I2C config NFC_MRVL_SPI tristate "Marvell NFC-over-SPI driver" - depends on NFC_MRVL && SPI + depends on NFC_MRVL && NFC_NCI_SPI help Marvell NFC-over-SPI driver. -- cgit v1.2.3 From feacf0024bfea807d7302d4aff83b391ac6e4077 Mon Sep 17 00:00:00 2001 From: Vincent Cuissard Date: Tue, 3 Nov 2015 19:19:32 +0100 Subject: NFC: nfcmrvl: avoid UART break control during FW download BootROM does not support any form of power management during FW download. On UART, the driver shall not try to send breaks. Signed-off-by: Vincent Cuissard Signed-off-by: Samuel Ortiz --- drivers/nfc/nfcmrvl/uart.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/nfc/nfcmrvl/uart.c b/drivers/nfc/nfcmrvl/uart.c index f3d041c4f249..b33249bec419 100644 --- a/drivers/nfc/nfcmrvl/uart.c +++ b/drivers/nfc/nfcmrvl/uart.c @@ -152,10 +152,6 @@ static int nfcmrvl_nci_uart_open(struct nci_uart *nu) nu->drv_data = priv; nu->ndev = priv->ndev; - /* Set BREAK */ - if (priv->config.break_control && nu->tty->ops->break_ctl) - nu->tty->ops->break_ctl(nu->tty, -1); - return 0; } @@ -174,6 +170,9 @@ static void nfcmrvl_nci_uart_tx_start(struct nci_uart *nu) { struct nfcmrvl_private *priv = (struct nfcmrvl_private *)nu->drv_data; + if (priv->ndev->nfc_dev->fw_download_in_progress) + return; + /* Remove BREAK to wake up the NFCC */ if (priv->config.break_control && nu->tty->ops->break_ctl) { nu->tty->ops->break_ctl(nu->tty, 0); @@ -185,6 +184,9 @@ static void nfcmrvl_nci_uart_tx_done(struct nci_uart *nu) { struct nfcmrvl_private *priv = (struct nfcmrvl_private *)nu->drv_data; + if (priv->ndev->nfc_dev->fw_download_in_progress) + return; + /* ** To ensure that if the NFCC goes in DEEP SLEEP sate we can wake him ** up. we set BREAK. Once we will be ready to send again we will remove -- cgit v1.2.3 From d2d2e6456ebccb5d31163dcc3191d83183bbd0b5 Mon Sep 17 00:00:00 2001 From: Vincent Cuissard Date: Tue, 3 Nov 2015 19:19:33 +0100 Subject: NFC: nfcmrvl: add a small wait after setting UART break A small wait is inserted to ensure that controller has enough time to handle the break character. Signed-off-by: Vincent Cuissard Signed-off-by: Samuel Ortiz --- drivers/nfc/nfcmrvl/uart.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/nfc/nfcmrvl/uart.c b/drivers/nfc/nfcmrvl/uart.c index b33249bec419..b4c4796dd23e 100644 --- a/drivers/nfc/nfcmrvl/uart.c +++ b/drivers/nfc/nfcmrvl/uart.c @@ -192,8 +192,10 @@ static void nfcmrvl_nci_uart_tx_done(struct nci_uart *nu) ** up. we set BREAK. Once we will be ready to send again we will remove ** it. */ - if (priv->config.break_control && nu->tty->ops->break_ctl) + if (priv->config.break_control && nu->tty->ops->break_ctl) { nu->tty->ops->break_ctl(nu->tty, -1); + usleep_range(1000, 3000); + } } static struct nci_uart nfcmrvl_nci_uart = { -- cgit v1.2.3 From b2fe288eac7247f83b52377b4134ecc5cd856bf2 Mon Sep 17 00:00:00 2001 From: Vincent Cuissard Date: Tue, 3 Nov 2015 19:19:34 +0100 Subject: NFC: nfcmrvl: free reset gpio Reset GPIO shall be freed by the driver since the device used in devm_ calls can be still valid on unregister. If user removes the module and inserts it again, the devm_gpio_request will fail because the underlying physical device (e.g i2c) was not removed so the device management won't have freed the gpio. Signed-off-by: Vincent Cuissard Signed-off-by: Samuel Ortiz --- drivers/nfc/nfcmrvl/main.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/nfc/nfcmrvl/main.c b/drivers/nfc/nfcmrvl/main.c index 8079ae0de21e..743c74c31cf0 100644 --- a/drivers/nfc/nfcmrvl/main.c +++ b/drivers/nfc/nfcmrvl/main.c @@ -194,6 +194,9 @@ void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv) nfcmrvl_fw_dnld_deinit(priv); + if (priv->config.reset_n_io) + devm_gpio_free(priv->dev, priv->config.reset_n_io); + nci_unregister_device(ndev); nci_free_device(ndev); kfree(priv); -- cgit v1.2.3 From 6f8c53695d6521c36052d39e29ac1e51ef37eba7 Mon Sep 17 00:00:00 2001 From: Vincent Cuissard Date: Tue, 3 Nov 2015 19:19:35 +0100 Subject: NFC: nfcmrvl: remove unneeded CONFIG_OF switches Signed-off-by: Vincent Cuissard Signed-off-by: Samuel Ortiz --- drivers/nfc/nfcmrvl/main.c | 12 ------------ drivers/nfc/nfcmrvl/uart.c | 12 ------------ 2 files changed, 24 deletions(-) (limited to 'drivers') diff --git a/drivers/nfc/nfcmrvl/main.c b/drivers/nfc/nfcmrvl/main.c index 743c74c31cf0..51c8240a1672 100644 --- a/drivers/nfc/nfcmrvl/main.c +++ b/drivers/nfc/nfcmrvl/main.c @@ -254,8 +254,6 @@ void nfcmrvl_chip_halt(struct nfcmrvl_private *priv) gpio_set_value(priv->config.reset_n_io, 0); } -#ifdef CONFIG_OF - int nfcmrvl_parse_dt(struct device_node *node, struct nfcmrvl_platform_data *pdata) { @@ -278,16 +276,6 @@ int nfcmrvl_parse_dt(struct device_node *node, return 0; } - -#else - -int nfcmrvl_parse_dt(struct device_node *node, - struct nfcmrvl_platform_data *pdata) -{ - return -ENODEV; -} - -#endif EXPORT_SYMBOL_GPL(nfcmrvl_parse_dt); MODULE_AUTHOR("Marvell International Ltd."); diff --git a/drivers/nfc/nfcmrvl/uart.c b/drivers/nfc/nfcmrvl/uart.c index b4c4796dd23e..83a99e38e7bd 100644 --- a/drivers/nfc/nfcmrvl/uart.c +++ b/drivers/nfc/nfcmrvl/uart.c @@ -67,8 +67,6 @@ static struct nfcmrvl_if_ops uart_ops = { .nci_update_config = nfcmrvl_uart_nci_update_config }; -#ifdef CONFIG_OF - static int nfcmrvl_uart_parse_dt(struct device_node *node, struct nfcmrvl_platform_data *pdata) { @@ -102,16 +100,6 @@ static int nfcmrvl_uart_parse_dt(struct device_node *node, return 0; } -#else - -static int nfcmrvl_uart_parse_dt(struct device_node *node, - struct nfcmrvl_platform_data *pdata) -{ - return -ENODEV; -} - -#endif - /* ** NCI UART OPS */ -- cgit v1.2.3 From 82aff3ea3b87892ce1476dad83de211741b3ac00 Mon Sep 17 00:00:00 2001 From: Vincent Cuissard Date: Tue, 3 Nov 2015 19:19:36 +0100 Subject: NFC: nfcmrvl: avoid being stuck on FW dnld timeout FW Download procedure can block on del_timer_sync because the timer is not running. This patch check that timer is scheduled before cancelling it. Signed-off-by: Vincent Cuissard Signed-off-by: Samuel Ortiz --- drivers/nfc/nfcmrvl/fw_dnld.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/nfc/nfcmrvl/fw_dnld.c b/drivers/nfc/nfcmrvl/fw_dnld.c index bfa771392b1f..f8dcdf4b24f6 100644 --- a/drivers/nfc/nfcmrvl/fw_dnld.c +++ b/drivers/nfc/nfcmrvl/fw_dnld.c @@ -113,9 +113,12 @@ static void fw_dnld_over(struct nfcmrvl_private *priv, u32 error) } atomic_set(&priv->ndev->cmd_cnt, 0); - del_timer_sync(&priv->ndev->cmd_timer); - del_timer_sync(&priv->fw_dnld.timer); + if (timer_pending(&priv->ndev->cmd_timer)) + del_timer_sync(&priv->ndev->cmd_timer); + + if (timer_pending(&priv->fw_dnld.timer)) + del_timer_sync(&priv->fw_dnld.timer); nfc_info(priv->dev, "FW loading over (%d)]\n", error); @@ -472,9 +475,12 @@ void nfcmrvl_fw_dnld_deinit(struct nfcmrvl_private *priv) void nfcmrvl_fw_dnld_recv_frame(struct nfcmrvl_private *priv, struct sk_buff *skb) { + /* Discard command timer */ + if (timer_pending(&priv->ndev->cmd_timer)) + del_timer_sync(&priv->ndev->cmd_timer); + /* Allow next command */ atomic_set(&priv->ndev->cmd_cnt, 1); - del_timer_sync(&priv->ndev->cmd_timer); /* Queue and trigger rx work */ skb_queue_tail(&priv->fw_dnld.rx_q, skb); -- cgit v1.2.3 From 1f71e8c96fc654724723ce987e0a8b2aeb81746d Mon Sep 17 00:00:00 2001 From: Markus Brunner Date: Tue, 3 Nov 2015 22:09:51 +0100 Subject: drivers: net: cpsw: Add support for fixed-link PHY Add support for a fixed-link devicetree sub-node in case the the cpsw MAC is directly connected to a non-mdio PHY/device. Signed-off-by: Markus Brunner Acked-by: Mugunthan V N Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/cpsw.txt | 5 +++++ drivers/net/ethernet/ti/cpsw.c | 13 +++++++++++++ 2 files changed, 18 insertions(+) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/net/cpsw.txt b/Documentation/devicetree/bindings/net/cpsw.txt index 4efca560adda..9853f8e70966 100644 --- a/Documentation/devicetree/bindings/net/cpsw.txt +++ b/Documentation/devicetree/bindings/net/cpsw.txt @@ -48,6 +48,11 @@ Optional properties: - mac-address : See ethernet.txt file in the same directory - phy-handle : See ethernet.txt file in the same directory +Slave sub-nodes: +- fixed-link : See fixed-link.txt file in the same directory + Either the properties phy_id and phy-mode, + or the sub-node fixed-link can be specified + Note: "ti,hwmods" field is used to fetch the base address and irq resources from TI, omap hwmod data base during device registration. Future plan is to migrate hwmod data base contents into device tree diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 040fbc1e5508..48b92c9de12a 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -2037,6 +2037,19 @@ static int cpsw_probe_dt(struct cpsw_priv *priv, continue; priv->phy_node = of_parse_phandle(slave_node, "phy-handle", 0); + if (of_phy_is_fixed_link(slave_node)) { + struct phy_device *pd; + + ret = of_phy_register_fixed_link(slave_node); + if (ret) + return ret; + pd = of_phy_find_device(slave_node); + if (!pd) + return -ENODEV; + snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), + PHY_ID_FMT, pd->bus->id, pd->phy_id); + goto no_phy_slave; + } parp = of_get_property(slave_node, "phy_id", &lenp); if ((parp == NULL) || (lenp != (sizeof(void *) * 2))) { dev_err(&pdev->dev, "Missing slave[%d] phy_id property\n", i); -- cgit v1.2.3 From 91d80683fc1828141e87babbd01f40e408864914 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Wed, 4 Nov 2015 00:17:08 +0300 Subject: sh_eth: kill 'ret' variable in sh_eth_ring_init() The 'ret' local variable in sh_eth_ring_init() serves no useful purpose as the only values it gets assigned are 0 and -ENOMEM both of which could be returned directly... Signed-off-by: Sergei Shtylyov Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 6150a235b72c..1477f9c7051b 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1199,7 +1199,7 @@ static void sh_eth_ring_format(struct net_device *ndev) static int sh_eth_ring_init(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); - int rx_ringsize, tx_ringsize, ret = 0; + int rx_ringsize, tx_ringsize; /* +26 gets the maximum ethernet encapsulation, +7 & ~7 because the * card needs room to do 8 byte alignment, +2 so we can reserve @@ -1214,26 +1214,20 @@ static int sh_eth_ring_init(struct net_device *ndev) /* Allocate RX and TX skb rings */ mdp->rx_skbuff = kcalloc(mdp->num_rx_ring, sizeof(*mdp->rx_skbuff), GFP_KERNEL); - if (!mdp->rx_skbuff) { - ret = -ENOMEM; - return ret; - } + if (!mdp->rx_skbuff) + return -ENOMEM; mdp->tx_skbuff = kcalloc(mdp->num_tx_ring, sizeof(*mdp->tx_skbuff), GFP_KERNEL); - if (!mdp->tx_skbuff) { - ret = -ENOMEM; + if (!mdp->tx_skbuff) goto skb_ring_free; - } /* Allocate all Rx descriptors. */ rx_ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring; mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma, GFP_KERNEL); - if (!mdp->rx_ring) { - ret = -ENOMEM; + if (!mdp->rx_ring) goto skb_ring_free; - } mdp->dirty_rx = 0; @@ -1241,11 +1235,9 @@ static int sh_eth_ring_init(struct net_device *ndev) tx_ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring; mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma, GFP_KERNEL); - if (!mdp->tx_ring) { - ret = -ENOMEM; + if (!mdp->tx_ring) goto desc_ring_free; - } - return ret; + return 0; desc_ring_free: /* free DMA buffer */ @@ -1257,7 +1249,7 @@ skb_ring_free: mdp->tx_ring = NULL; mdp->rx_ring = NULL; - return ret; + return -ENOMEM; } static void sh_eth_free_dma_buffer(struct sh_eth_private *mdp) -- cgit v1.2.3 From 8e03a5e75c517de19c26a46147b0dc28096e55ef Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Wed, 4 Nov 2015 00:55:13 +0300 Subject: sh_eth: merge sh_eth_free_dma_buffer() into sh_eth_ring_free() While the ring allocation is done by a single function, sh_eth_ring_init(), the ring deallocation was split into two functions (almost always called one after the other) for no good reason. Merge sh_eth_free_dma_buffer() into sh_eth_ring_free() which allows us to save space not only on the direct calls of the former function but also on the sh_eth_ring_init()'s simplified error path... Signed-off-by: Sergei Shtylyov Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 60 +++++++++++++---------------------- 1 file changed, 22 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 1477f9c7051b..e7bab7909ed9 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1098,7 +1098,7 @@ static struct mdiobb_ops bb_ops = { static void sh_eth_ring_free(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); - int i; + int ringsize, i; /* Free Rx skb ringbuffer */ if (mdp->rx_skbuff) { @@ -1115,6 +1115,20 @@ static void sh_eth_ring_free(struct net_device *ndev) } kfree(mdp->tx_skbuff); mdp->tx_skbuff = NULL; + + if (mdp->rx_ring) { + ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring; + dma_free_coherent(NULL, ringsize, mdp->rx_ring, + mdp->rx_desc_dma); + mdp->rx_ring = NULL; + } + + if (mdp->tx_ring) { + ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring; + dma_free_coherent(NULL, ringsize, mdp->tx_ring, + mdp->tx_desc_dma); + mdp->tx_ring = NULL; + } } /* format skb and descriptor buffer */ @@ -1220,14 +1234,14 @@ static int sh_eth_ring_init(struct net_device *ndev) mdp->tx_skbuff = kcalloc(mdp->num_tx_ring, sizeof(*mdp->tx_skbuff), GFP_KERNEL); if (!mdp->tx_skbuff) - goto skb_ring_free; + goto ring_free; /* Allocate all Rx descriptors. */ rx_ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring; mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma, GFP_KERNEL); if (!mdp->rx_ring) - goto skb_ring_free; + goto ring_free; mdp->dirty_rx = 0; @@ -1236,41 +1250,16 @@ static int sh_eth_ring_init(struct net_device *ndev) mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma, GFP_KERNEL); if (!mdp->tx_ring) - goto desc_ring_free; + goto ring_free; return 0; -desc_ring_free: - /* free DMA buffer */ - dma_free_coherent(NULL, rx_ringsize, mdp->rx_ring, mdp->rx_desc_dma); - -skb_ring_free: - /* Free Rx and Tx skb ring buffer */ +ring_free: + /* Free Rx and Tx skb ring buffer and DMA buffer */ sh_eth_ring_free(ndev); - mdp->tx_ring = NULL; - mdp->rx_ring = NULL; return -ENOMEM; } -static void sh_eth_free_dma_buffer(struct sh_eth_private *mdp) -{ - int ringsize; - - if (mdp->rx_ring) { - ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring; - dma_free_coherent(NULL, ringsize, mdp->rx_ring, - mdp->rx_desc_dma); - mdp->rx_ring = NULL; - } - - if (mdp->tx_ring) { - ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring; - dma_free_coherent(NULL, ringsize, mdp->tx_ring, - mdp->tx_desc_dma); - mdp->tx_ring = NULL; - } -} - static int sh_eth_dev_init(struct net_device *ndev, bool start) { int ret = 0; @@ -2231,10 +2220,8 @@ static int sh_eth_set_ringparam(struct net_device *ndev, sh_eth_dev_exit(ndev); - /* Free all the skbuffs in the Rx queue. */ + /* Free all the skbuffs in the Rx queue and the DMA buffers. */ sh_eth_ring_free(ndev); - /* Free DMA buffer */ - sh_eth_free_dma_buffer(mdp); } /* Set new parameters */ @@ -2479,12 +2466,9 @@ static int sh_eth_close(struct net_device *ndev) free_irq(ndev->irq, ndev); - /* Free all the skbuffs in the Rx queue. */ + /* Free all the skbuffs in the Rx queue and the DMA buffer. */ sh_eth_ring_free(ndev); - /* free DMA buffer */ - sh_eth_free_dma_buffer(mdp); - pm_runtime_put_sync(&mdp->pdev->dev); mdp->is_opened = 0; -- cgit v1.2.3 From f6fc86f2c572ff1d192e8b5d5bf339ba06ebe3e4 Mon Sep 17 00:00:00 2001 From: Kuba Pawlak Date: Wed, 28 Oct 2015 15:18:05 +0100 Subject: Bluetooth: Fix possible deadlock in btusb commit 8f9d02f470f48416444ac3a1eacecdd0f743f1a7 introduced spinlocks in btusb_work. This is run in a context of a worqueue and can be interrupted by hardware irq. If it happens while spinlock is held, we have a deadlock. Solution is to use _irqsave/_resore version of locking [ 466.460560] ================================= [ 466.460565] [ INFO: inconsistent lock state ] [ 466.460572] 4.3.0-rc6+ #1 Tainted: G W [ 466.460576] --------------------------------- [ 466.460582] inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage. [ 466.460589] kworker/0:2/94 [HC0[0]:SC0[0]:HE1:SE1] takes: [ 466.460595] (&(&data->rxlock)->rlock){?.-...}, at: [] btusb_work+0xa3/0x3fd [btusb] [ 466.460621] {IN-HARDIRQ-W} state was registered at: [ 466.460625] [] __lock_acquire+0xc45/0x1e80 [ 466.460638] [] lock_acquire+0xe5/0x1f0 [ 466.460646] [] _raw_spin_lock+0x38/0x50 [ 466.460657] [] btusb_recv_intr+0x38/0x170 [btusb] [ 466.460668] [] btusb_intr_complete+0xa6/0x130 [btusb] [ 466.460679] [] __usb_hcd_giveback_urb+0x8e/0x160 [ 466.460690] [] usb_hcd_giveback_urb+0x3f/0x120 [ 466.460698] [] uhci_giveback_urb+0xad/0x280 [ 466.460706] [] uhci_scan_schedule.part.33+0x6b4/0xbe0 [ 466.460714] [] uhci_irq+0xd0/0x180 [ 466.460722] [] usb_hcd_irq+0x26/0x40 [ 466.460729] [] handle_irq_event_percpu+0x40/0x300 [ 466.460739] [] handle_irq_event+0x40/0x60 [ 466.460746] [] handle_fasteoi_irq+0x89/0x150 [ 466.460754] [] handle_irq+0x73/0x120 [ 466.460763] [] do_IRQ+0x61/0x120 [ 466.460772] [] ret_from_intr+0x0/0x31 [ 466.460780] [] cpuidle_enter+0x17/0x20 [ 466.460790] [] call_cpuidle+0x32/0x60 [ 466.460800] [] cpu_startup_entry+0x2b8/0x3f0 [ 466.460807] [] rest_init+0x13a/0x140 [ 466.460817] [] start_kernel+0x4a3/0x4c4 [ 466.460827] [] x86_64_start_reservations+0x2a/0x2c [ 466.460837] [] x86_64_start_kernel+0x14a/0x16d [ 466.460846] irq event stamp: 754913 [ 466.460851] hardirqs last enabled at (754913): [] _raw_spin_unlock_irq+0x2c/0x40 [ 466.460861] hardirqs last disabled at (754912): [] _raw_spin_lock_irq+0x1d/0x60 [ 466.460869] softirqs last enabled at (753024): [] __do_softirq+0x380/0x490 [ 466.460880] softirqs last disabled at (753009): [] irq_exit+0x10f/0x120 [ 466.460888] other info that might help us debug this: [ 466.460894] Possible unsafe locking scenario: [ 466.460899] CPU0 [ 466.460903] ---- [ 466.460907] lock(&(&data->rxlock)->rlock); [ 466.460915] [ 466.460918] lock(&(&data->rxlock)->rlock); [ 466.460926] *** DEADLOCK *** [ 466.460935] 2 locks held by kworker/0:2/94: [ 466.460939] #0: ("events"){.+.+.+}, at: [] process_one_work+0x16b/0x660 [ 466.460958] #1: ((&data->work)){+.+...}, at: [] process_one_work+0x16b/0x660 [ 466.460974] Signed-off-by: Kuba Pawlak Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btusb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index e33dacf5bd98..92f0ee388f9e 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -1372,6 +1372,8 @@ static void btusb_work(struct work_struct *work) } if (data->isoc_altsetting != new_alts) { + unsigned long flags; + clear_bit(BTUSB_ISOC_RUNNING, &data->flags); usb_kill_anchored_urbs(&data->isoc_anchor); @@ -1384,10 +1386,10 @@ static void btusb_work(struct work_struct *work) * Clear outstanding fragment when selecting a new * alternate setting. */ - spin_lock(&data->rxlock); + spin_lock_irqsave(&data->rxlock, flags); kfree_skb(data->sco_skb); data->sco_skb = NULL; - spin_unlock(&data->rxlock); + spin_unlock_irqrestore(&data->rxlock, flags); if (__set_isoc_interface(hdev, new_alts) < 0) return; -- cgit v1.2.3 From 8c169c28f40bd78b772c4d95306735c00f8db80d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 4 Nov 2015 16:27:16 +0300 Subject: qlogic/qed: remove bogus NULL check We check if "p_hwfn" is NULL and then dereference it in the error handling code. I read the code and it isn't NULL so let's remove the check. Signed-off-by: Dan Carpenter Acked-by: Yuval Mintz Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qed/qed_int.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c b/drivers/net/ethernet/qlogic/qed/qed_int.c index 2e399b6137a2..de50e84902af 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_int.c +++ b/drivers/net/ethernet/qlogic/qed/qed_int.c @@ -251,11 +251,6 @@ void qed_int_sp_dpc(unsigned long hwfn_cookie) int arr_size; u16 rc = 0; - if (!p_hwfn) { - DP_ERR(p_hwfn->cdev, "DPC called - no hwfn!\n"); - return; - } - if (!p_hwfn->p_sp_sb) { DP_ERR(p_hwfn->cdev, "DPC called - no p_sp_sb\n"); return; -- cgit v1.2.3 From 87aec47d173ca730d014b6b0246ca6be18b0ce94 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 4 Nov 2015 16:29:11 +0300 Subject: qlogic: qed: fix a test for MODE_MF_SI MODE_MF_SI is 9. We should be testing bit 9 instead of AND 0x9. Fixes: fe56b9e6a8d9 ('qed: Add module with basic common support') Signed-off-by: Dan Carpenter Acked-by: Yuval Mintz Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qed/qed_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c index b9b7b7e6fa53..774b2231b79a 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c @@ -562,7 +562,7 @@ static int qed_hw_init_pf(struct qed_hwfn *p_hwfn, } /* Enable classification by MAC if needed */ - if (hw_mode & MODE_MF_SI) { + if (hw_mode & (1 << MODE_MF_SI)) { DP_VERBOSE(p_hwfn, NETIF_MSG_HW, "Configuring TAGMAC_CLS_TYPE\n"); STORE_RT_REG(p_hwfn, -- cgit v1.2.3 From df761ea1f39fe1c020c31327656bce7a5a406201 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 4 Nov 2015 16:00:32 +0100 Subject: bnxt_en: add VXLAN dependency VXLAN may be a loadable module, and this driver cannot be built-in in that case, or we get a link error: drivers/built-in.o: In function `__bnxt_open_nic': drivers/net/ethernet/broadcom/bnxt/bnxt.c:4581: undefined reference to `vxlan_get_rx_port' This adds a Kconfig dependency that ensures that either VXLAN is disabled (which the driver handles correctly), or we depend on VXLAN itself and disallow built-in compilation when VXLAN is a module. Signed-off-by: Arnd Bergmann Fixes: c0c050c58d84 ("bnxt_en: New Broadcom ethernet driver.") Acked-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig index 67a7d520d9f5..8550df189ceb 100644 --- a/drivers/net/ethernet/broadcom/Kconfig +++ b/drivers/net/ethernet/broadcom/Kconfig @@ -173,6 +173,7 @@ config SYSTEMPORT config BNXT tristate "Broadcom NetXtreme-C/E support" depends on PCI + depends on VXLAN || VXLAN=n select FW_LOADER select LIBCRC32C ---help--- -- cgit v1.2.3 From b3d8cf019fb9dd28389b08da7bf54ffabf453ed3 Mon Sep 17 00:00:00 2001 From: Petr Štetiar Date: Thu, 5 Nov 2015 12:55:01 +0100 Subject: USB: qmi_wwan: Add quirk for Quectel EC20 Mini PCIe module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This device has same vendor and product IDs as G2K devices, but it has different number of interfaces(4 vs 5) and also different interface layout where EC20 has QMI on interface 4 instead of 0. lsusb output: Bus 002 Device 003: ID 05c6:9215 Qualcomm, Inc. Acer Gobi 2000 Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x05c6 Qualcomm, Inc. idProduct 0x9215 Acer Gobi 2000 Wireless Modem bcdDevice 2.32 iManufacturer 1 Quectel iProduct 2 Quectel LTE Module iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 209 bNumInterfaces 5 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xa0 (Bus Powered) Remote Wakeup MaxPower 500mA Signed-off-by: Petr Štetiar Acked-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/qmi_wwan.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers') diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index c54719984c4b..34799eaace41 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -771,6 +771,7 @@ static const struct usb_device_id products[] = { {QMI_GOBI_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */ {QMI_GOBI_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */ {QMI_GOBI_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */ + {QMI_FIXED_INTF(0x05c6, 0x9215, 4)}, /* Quectel EC20 Mini PCIe */ {QMI_GOBI_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ {QMI_GOBI_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */ {QMI_GOBI_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */ @@ -802,10 +803,24 @@ static const struct usb_device_id products[] = { }; MODULE_DEVICE_TABLE(usb, products); +static bool quectel_ec20_detected(struct usb_interface *intf) +{ + struct usb_device *dev = interface_to_usbdev(intf); + + if (dev->actconfig && + le16_to_cpu(dev->descriptor.idVendor) == 0x05c6 && + le16_to_cpu(dev->descriptor.idProduct) == 0x9215 && + dev->actconfig->desc.bNumInterfaces == 5) + return true; + + return false; +} + static int qmi_wwan_probe(struct usb_interface *intf, const struct usb_device_id *prod) { struct usb_device_id *id = (struct usb_device_id *)prod; + struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc; /* Workaround to enable dynamic IDs. This disables usbnet * blacklisting functionality. Which, if required, can be @@ -817,6 +832,12 @@ static int qmi_wwan_probe(struct usb_interface *intf, id->driver_info = (unsigned long)&qmi_wwan_info; } + /* Quectel EC20 quirk where we've QMI on interface 4 instead of 0 */ + if (quectel_ec20_detected(intf) && desc->bInterfaceNumber == 0) { + dev_dbg(&intf->dev, "Quectel EC20 quirk, skipping interface 0\n"); + return -ENODEV; + } + return usbnet_probe(intf, id); } -- cgit v1.2.3 From e79a8bcb780314a555897a933d16553b80dbca1f Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Wed, 4 Nov 2015 17:23:40 -0500 Subject: net: dsa: mv88e6xxx: isolate unbridged ports The DSA documentation specifies that each port must be capable of forwarding frames to the CPU port. The last changes on bridging support for the mv88e6xxx driver broke this requirement for non-bridged ports. So as for the bridged ports, reserve a few VLANs (4000+) in the switch to isolate ports that have not been bridged yet. By default, a port will be isolated with the CPU and DSA ports. When the port joins a bridge, it will leave its reserved port. When it is removed from a bridge, it will join its reserved VLAN again. Fixes: 5fe7f68016ff ("net: dsa: mv88e6xxx: fix hardware bridging") Reported-by: Andrew Lunn Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6171.c | 2 ++ drivers/net/dsa/mv88e6352.c | 2 ++ drivers/net/dsa/mv88e6xxx.c | 42 ++++++++++++++++++++++++++++++++++++++++++ drivers/net/dsa/mv88e6xxx.h | 2 ++ 4 files changed, 48 insertions(+) (limited to 'drivers') diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index 54aa00012dd0..6e18213b9c04 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -103,6 +103,8 @@ struct dsa_switch_driver mv88e6171_switch_driver = { #endif .get_regs_len = mv88e6xxx_get_regs_len, .get_regs = mv88e6xxx_get_regs, + .port_join_bridge = mv88e6xxx_port_bridge_join, + .port_leave_bridge = mv88e6xxx_port_bridge_leave, .port_stp_update = mv88e6xxx_port_stp_update, .port_pvid_get = mv88e6xxx_port_pvid_get, .port_vlan_prepare = mv88e6xxx_port_vlan_prepare, diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index ff846d0cfceb..cc6c54553418 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -323,6 +323,8 @@ struct dsa_switch_driver mv88e6352_switch_driver = { .set_eeprom = mv88e6352_set_eeprom, .get_regs_len = mv88e6xxx_get_regs_len, .get_regs = mv88e6xxx_get_regs, + .port_join_bridge = mv88e6xxx_port_bridge_join, + .port_leave_bridge = mv88e6xxx_port_bridge_leave, .port_stp_update = mv88e6xxx_port_stp_update, .port_pvid_get = mv88e6xxx_port_pvid_get, .port_vlan_prepare = mv88e6xxx_port_vlan_prepare, diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 04cff58d771b..b06dba05594a 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -1462,6 +1462,10 @@ int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port, const struct switchdev_obj_port_vlan *vlan, struct switchdev_trans *trans) { + /* We reserve a few VLANs to isolate unbridged ports */ + if (vlan->vid_end >= 4000) + return -EOPNOTSUPP; + /* We don't need any dynamic resource from the kernel (yet), * so skip the prepare phase. */ @@ -1870,6 +1874,36 @@ unlock: return err; } +int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, u32 members) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + const u16 pvid = 4000 + ds->index * DSA_MAX_PORTS + port; + int err; + + /* The port joined a bridge, so leave its reserved VLAN */ + mutex_lock(&ps->smi_mutex); + err = _mv88e6xxx_port_vlan_del(ds, port, pvid); + if (!err) + err = _mv88e6xxx_port_pvid_set(ds, port, 0); + mutex_unlock(&ps->smi_mutex); + return err; +} + +int mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port, u32 members) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + const u16 pvid = 4000 + ds->index * DSA_MAX_PORTS + port; + int err; + + /* The port left the bridge, so join its reserved VLAN */ + mutex_lock(&ps->smi_mutex); + err = _mv88e6xxx_port_vlan_add(ds, port, pvid, true); + if (!err) + err = _mv88e6xxx_port_pvid_set(ds, port, pvid); + mutex_unlock(&ps->smi_mutex); + return err; +} + static void mv88e6xxx_bridge_work(struct work_struct *work) { struct mv88e6xxx_priv_state *ps; @@ -2140,6 +2174,14 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds) ret = mv88e6xxx_setup_port(ds, i); if (ret < 0) return ret; + + if (dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i)) + continue; + + /* setup the unbridged state */ + ret = mv88e6xxx_port_bridge_leave(ds, i, 0); + if (ret < 0) + return ret; } return 0; } diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index fb9a8739712f..21c8daa03f78 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -468,6 +468,8 @@ int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum, int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e); int mv88e6xxx_set_eee(struct dsa_switch *ds, int port, struct phy_device *phydev, struct ethtool_eee *e); +int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, u32 members); +int mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port, u32 members); int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state); int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port, const struct switchdev_obj_port_vlan *vlan, -- cgit v1.2.3 From 9b15acbfe937f9c48a81d6aa306f9fa8b53abc13 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 5 Nov 2015 11:41:28 +0300 Subject: qlogic: qed: fix error codes in qed_resc_alloc() We accidentally return success instead of -ENOMEM here. Fixes: fe56b9e6a8d9 ('qed: Add module with basic common support') Signed-off-by: Dan Carpenter Acked-by: Yuval Mintz --- drivers/net/ethernet/qlogic/qed/qed_dev.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c index 774b2231b79a..803b190ccada 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c @@ -223,6 +223,7 @@ int qed_resc_alloc(struct qed_dev *cdev) if (!p_hwfn->p_tx_cids) { DP_NOTICE(p_hwfn, "Failed to allocate memory for Tx Cids\n"); + rc = -ENOMEM; goto alloc_err; } @@ -230,6 +231,7 @@ int qed_resc_alloc(struct qed_dev *cdev) if (!p_hwfn->p_rx_cids) { DP_NOTICE(p_hwfn, "Failed to allocate memory for Rx Cids\n"); + rc = -ENOMEM; goto alloc_err; } } @@ -281,14 +283,17 @@ int qed_resc_alloc(struct qed_dev *cdev) /* EQ */ p_eq = qed_eq_alloc(p_hwfn, 256); - - if (!p_eq) + if (!p_eq) { + rc = -ENOMEM; goto alloc_err; + } p_hwfn->p_eq = p_eq; p_consq = qed_consq_alloc(p_hwfn); - if (!p_consq) + if (!p_consq) { + rc = -ENOMEM; goto alloc_err; + } p_hwfn->p_consq = p_consq; /* DMA info initialization */ @@ -303,6 +308,7 @@ int qed_resc_alloc(struct qed_dev *cdev) cdev->reset_stats = kzalloc(sizeof(*cdev->reset_stats), GFP_KERNEL); if (!cdev->reset_stats) { DP_NOTICE(cdev, "Failed to allocate reset statistics\n"); + rc = -ENOMEM; goto alloc_err; } -- cgit v1.2.3 From 428ad1bc6dd766bb44171bba43a8a3219be77d2e Mon Sep 17 00:00:00 2001 From: LABBE Corentin Date: Thu, 5 Nov 2015 10:26:46 +0100 Subject: net: stmmac: fix double-initialization of phy_iface The variable phy_iface is double-initialized to itself. This patch remove that. Reported-by: coverity (CID 1271141) Signed-off-by: LABBE Corentin Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c index 11baa4b19779..0cd3ecff768b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c @@ -354,7 +354,7 @@ static int gmac_clk_init(struct rk_priv_data *bsp_priv) static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) { - int phy_iface = phy_iface = bsp_priv->phy_iface; + int phy_iface = bsp_priv->phy_iface; if (enable) { if (!bsp_priv->clk_enabled) { -- cgit v1.2.3 From c5d7774db350e77f2506e36e1797c958d1b118c8 Mon Sep 17 00:00:00 2001 From: Jeffrey Huang Date: Thu, 5 Nov 2015 16:25:47 -0500 Subject: bnxt_en: Change sp events definitions to represent bit position. Fix the sp event bits to be bit positions instead of bit values since the bit helper functions are expecting the former. Signed-off-by: Jeffrey Huang Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 4f2267ca482d..4cae4928b27c 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -959,11 +959,11 @@ struct bnxt { #define BNXT_RX_MASK_SP_EVENT 0 #define BNXT_RX_NTP_FLTR_SP_EVENT 1 #define BNXT_LINK_CHNG_SP_EVENT 2 -#define BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT 4 -#define BNXT_VXLAN_ADD_PORT_SP_EVENT 8 -#define BNXT_VXLAN_DEL_PORT_SP_EVENT 16 -#define BNXT_RESET_TASK_SP_EVENT 32 -#define BNXT_RST_RING_SP_EVENT 64 +#define BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT 3 +#define BNXT_VXLAN_ADD_PORT_SP_EVENT 4 +#define BNXT_VXLAN_DEL_PORT_SP_EVENT 5 +#define BNXT_RESET_TASK_SP_EVENT 6 +#define BNXT_RST_RING_SP_EVENT 7 struct bnxt_pf_info pf; #ifdef CONFIG_BNXT_SRIOV -- cgit v1.2.3 From 614388ce39f3d61ad7f95db65f409d35d5943616 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 5 Nov 2015 16:25:48 -0500 Subject: bnxt_en: Determine tcp/ipv6 RSS hash type correctly. The profile ID in the completion record needs to be ANDed with the profile ID mask of 0x1f. This bug was causing the SKB hash type and the gso_type to be wrong in some cases. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 4cae4928b27c..5afe65d1316b 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -166,9 +166,11 @@ struct rx_cmp { #define RX_CMP_HASH_VALID(rxcmp) \ ((rxcmp)->rx_cmp_len_flags_type & cpu_to_le32(RX_CMP_FLAGS_RSS_VALID)) +#define RSS_PROFILE_ID_MASK 0x1f + #define RX_CMP_HASH_TYPE(rxcmp) \ - ((le32_to_cpu((rxcmp)->rx_cmp_misc_v1) & RX_CMP_RSS_HASH_TYPE) >>\ - RX_CMP_RSS_HASH_TYPE_SHIFT) + (((le32_to_cpu((rxcmp)->rx_cmp_misc_v1) & RX_CMP_RSS_HASH_TYPE) >>\ + RX_CMP_RSS_HASH_TYPE_SHIFT) & RSS_PROFILE_ID_MASK) struct rx_cmp_ext { __le32 rx_cmp_flags2; @@ -282,9 +284,9 @@ struct rx_tpa_start_cmp { cpu_to_le32(RX_TPA_START_CMP_FLAGS_RSS_VALID)) #define TPA_START_HASH_TYPE(rx_tpa_start) \ - ((le32_to_cpu((rx_tpa_start)->rx_tpa_start_cmp_misc_v1) & \ - RX_TPA_START_CMP_RSS_HASH_TYPE) >> \ - RX_TPA_START_CMP_RSS_HASH_TYPE_SHIFT) + (((le32_to_cpu((rx_tpa_start)->rx_tpa_start_cmp_misc_v1) & \ + RX_TPA_START_CMP_RSS_HASH_TYPE) >> \ + RX_TPA_START_CMP_RSS_HASH_TYPE_SHIFT) & RSS_PROFILE_ID_MASK) #define TPA_START_AGG_ID(rx_tpa_start) \ ((le32_to_cpu((rx_tpa_start)->rx_tpa_start_cmp_misc_v1) & \ -- cgit v1.2.3 From 11809490ac17810cff90c12e9f2f3e0303a72121 Mon Sep 17 00:00:00 2001 From: Jeffrey Huang Date: Thu, 5 Nov 2015 16:25:49 -0500 Subject: bnxt_en: map CAG_REG_LEGACY_INT_STATUS_MASK to GRC window #4 In order to use offset 0x4014 for reading CAG interrupt status, the actual CAG register must be mapped to GRC bar0 window #4. Otherwise, the driver is reading garbage. This patch corrects this issue. Signed-off-by: Jeffrey Huang Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 19 ++++++++++++++++--- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 4 ++++ 2 files changed, 20 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 6c2e0c622831..a62deff5a4ac 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -1292,8 +1292,6 @@ static inline int bnxt_has_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr) return TX_CMP_VALID(txcmp, raw_cons); } -#define CAG_LEGACY_INT_STATUS 0x2014 - static irqreturn_t bnxt_inta(int irq, void *dev_instance) { struct bnxt_napi *bnapi = dev_instance; @@ -1305,7 +1303,7 @@ static irqreturn_t bnxt_inta(int irq, void *dev_instance) prefetch(&cpr->cp_desc_ring[CP_RING(cons)][CP_IDX(cons)]); if (!bnxt_has_work(bp, cpr)) { - int_status = readl(bp->bar0 + CAG_LEGACY_INT_STATUS); + int_status = readl(bp->bar0 + BNXT_CAG_REG_LEGACY_INT_STATUS); /* return if erroneous interrupt */ if (!(int_status & (0x10000 << cpr->cp_ring_struct.fw_ring_id))) return IRQ_NONE; @@ -4527,10 +4525,25 @@ static int bnxt_update_phy_setting(struct bnxt *bp) return rc; } +/* Common routine to pre-map certain register block to different GRC window. + * A PF has 16 4K windows and a VF has 4 4K windows. However, only 15 windows + * in PF and 3 windows in VF that can be customized to map in different + * register blocks. + */ +static void bnxt_preset_reg_win(struct bnxt *bp) +{ + if (BNXT_PF(bp)) { + /* CAG registers map to GRC window #4 */ + writel(BNXT_CAG_REG_BASE, + bp->bar0 + BNXT_GRCPF_REG_WINDOW_BASE_OUT + 12); + } +} + static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) { int rc = 0; + bnxt_preset_reg_win(bp); netif_carrier_off(bp->dev); if (irq_re_init) { rc = bnxt_setup_int_mode(bp); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 5afe65d1316b..674bc5159b91 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -841,6 +841,10 @@ struct bnxt_queue_info { u8 queue_profile; }; +#define BNXT_GRCPF_REG_WINDOW_BASE_OUT 0x400 +#define BNXT_CAG_REG_LEGACY_INT_STATUS 0x4014 +#define BNXT_CAG_REG_BASE 0x300000 + struct bnxt { void __iomem *bar0; void __iomem *bar1; -- cgit v1.2.3 From 84e86b98f6515aaeaac053b234be158b25457184 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 5 Nov 2015 16:25:50 -0500 Subject: bnxt_en: Fix comparison of u16 sw_id against negative value. Assign the return value from bitmap_find_free_region() to an integer variable and check for negative error codes first, before assigning the bit ID to the unsigned sw_id field. Reported-by: Dan Carpenter Cc: Dan Carpenter Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index a62deff5a4ac..db15c5ee09c5 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -5307,7 +5307,7 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, struct bnxt_ntuple_filter *fltr, *new_fltr; struct flow_keys *fkeys; struct ethhdr *eth = (struct ethhdr *)skb_mac_header(skb); - int rc = 0, idx; + int rc = 0, idx, bit_id; struct hlist_head *head; if (skb->encapsulation) @@ -5345,14 +5345,15 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, rcu_read_unlock(); spin_lock_bh(&bp->ntp_fltr_lock); - new_fltr->sw_id = bitmap_find_free_region(bp->ntp_fltr_bmap, - BNXT_NTP_FLTR_MAX_FLTR, 0); - if (new_fltr->sw_id < 0) { + bit_id = bitmap_find_free_region(bp->ntp_fltr_bmap, + BNXT_NTP_FLTR_MAX_FLTR, 0); + if (bit_id < 0) { spin_unlock_bh(&bp->ntp_fltr_lock); rc = -ENOMEM; goto err_free; } + new_fltr->sw_id = (u16)bit_id; new_fltr->flow_id = flow_id; new_fltr->rxq = rxq_index; hlist_add_head_rcu(&new_fltr->hash, head); -- cgit v1.2.3 From 4bb6cdce386d620d10d2588ea5bf4093a3b21ab9 Mon Sep 17 00:00:00 2001 From: Jeffrey Huang Date: Thu, 5 Nov 2015 16:25:51 -0500 Subject: bnxt_en: More robust SRIOV cleanup sequence. Instead of always calling pci_sriov_disable() in remove_one(), the driver should detect whether VFs are currently assigned to the VMs. If the VFs are active in VMs, then it should not disable SRIOV as it is catastrophic to the VMs. Instead, it just leaves the VFs alone and continues to unload the PF. The user can then cleanup the VMs even after the PF driver has been unloaded. Signed-off-by: Jeffrey Huang Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c | 40 +++++++++++++++++-------- 1 file changed, 27 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c index 60989e7e266a..f4cf68861069 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c @@ -258,7 +258,7 @@ static int bnxt_set_vf_attr(struct bnxt *bp, int num_vfs) return 0; } -static int bnxt_hwrm_func_vf_resource_free(struct bnxt *bp) +static int bnxt_hwrm_func_vf_resource_free(struct bnxt *bp, int num_vfs) { int i, rc = 0; struct bnxt_pf_info *pf = &bp->pf; @@ -267,7 +267,7 @@ static int bnxt_hwrm_func_vf_resource_free(struct bnxt *bp) bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_VF_RESC_FREE, -1, -1); mutex_lock(&bp->hwrm_cmd_lock); - for (i = pf->first_vf_id; i < pf->first_vf_id + pf->active_vfs; i++) { + for (i = pf->first_vf_id; i < pf->first_vf_id + num_vfs; i++) { req.vf_id = cpu_to_le16(i); rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); @@ -509,7 +509,7 @@ static int bnxt_sriov_enable(struct bnxt *bp, int *num_vfs) err_out2: /* Free the resources reserved for various VF's */ - bnxt_hwrm_func_vf_resource_free(bp); + bnxt_hwrm_func_vf_resource_free(bp, *num_vfs); err_out1: bnxt_free_vf_resources(bp); @@ -519,13 +519,19 @@ err_out1: void bnxt_sriov_disable(struct bnxt *bp) { - if (!bp->pf.active_vfs) - return; + u16 num_vfs = pci_num_vf(bp->pdev); - pci_disable_sriov(bp->pdev); + if (!num_vfs) + return; - /* Free the resources reserved for various VF's */ - bnxt_hwrm_func_vf_resource_free(bp); + if (pci_vfs_assigned(bp->pdev)) { + netdev_warn(bp->dev, "Unable to free %d VFs because some are assigned to VMs.\n", + num_vfs); + } else { + pci_disable_sriov(bp->pdev); + /* Free the HW resources reserved for various VF's */ + bnxt_hwrm_func_vf_resource_free(bp, num_vfs); + } bnxt_free_vf_resources(bp); @@ -552,17 +558,25 @@ int bnxt_sriov_configure(struct pci_dev *pdev, int num_vfs) } bp->sriov_cfg = true; rtnl_unlock(); - if (!num_vfs) { - bnxt_sriov_disable(bp); - return 0; + + if (pci_vfs_assigned(bp->pdev)) { + netdev_warn(dev, "Unable to configure SRIOV since some VFs are assigned to VMs.\n"); + num_vfs = 0; + goto sriov_cfg_exit; } /* Check if enabled VFs is same as requested */ - if (num_vfs == bp->pf.active_vfs) - return 0; + if (num_vfs && num_vfs == bp->pf.active_vfs) + goto sriov_cfg_exit; + + /* if there are previous existing VFs, clean them up */ + bnxt_sriov_disable(bp); + if (!num_vfs) + goto sriov_cfg_exit; bnxt_sriov_enable(bp, &num_vfs); +sriov_cfg_exit: bp->sriov_cfg = false; wake_up(&bp->sriov_cfg_wait); -- cgit v1.2.3 From f7b5964d4d0bddf429c44b457172891be000a3d3 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 6 Nov 2015 09:30:29 +0100 Subject: fjes: Delete an unnecessary check before the function call "vfree" The vfree() function performs also input parameter validation. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: David S. Miller --- drivers/net/fjes/fjes_hw.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fjes/fjes_hw.c b/drivers/net/fjes/fjes_hw.c index 2d3848c9dc35..bb8b5304d851 100644 --- a/drivers/net/fjes/fjes_hw.c +++ b/drivers/net/fjes/fjes_hw.c @@ -143,9 +143,7 @@ static int fjes_hw_alloc_epbuf(struct epbuf_handler *epbh) static void fjes_hw_free_epbuf(struct epbuf_handler *epbh) { - if (epbh->buffer) - vfree(epbh->buffer); - + vfree(epbh->buffer); epbh->buffer = NULL; epbh->size = 0; -- cgit v1.2.3 From e824de8ae2a00ee71c5bfbadd004d12c6dd85561 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Fri, 6 Nov 2015 09:25:31 -0500 Subject: net/qlcnic: fix mac address restore in bond mode 5/6 The bonding driver saves a copy of slaves' original mac address and then assigns whatever mac as needed to the slave, depending on mode. In at least modes 5 and 6 (balance-tlb, balance-alb), it often ends up being the mac address of another slave. On release from the bond, the original mac address is supposed to get restored via a dev_set_mac_address() call in the bonding driver's __bond_release_one() function, which calls the slave's ndo_set_mac_address function, which for qlcnic, is qlcnic_set_mac(). Now, this function tries to be somewhat intelligent and exit early if you're trying to set the mac address to the same thing that is already set. The problem here is that adapter->mac_addr isn't in sync with netdev->dev_addr. The qlcnic driver still has the original mac stored in adapter->mac_addr, while the bonding driver has updated netdev->dev_addr, so qlcnic thinks we're trying to set the same address it already has. I think the way to go here, since the function updates both netdev and adapter's stored mac addresses, is to check if either of them doesn't match the newly requested mac. Simply checking netdev's value only could result in a similar mismatch and non-update, so look at both. CC: Dept-GELinuxNICDev@qlogic.com CC: netdev@vger.kernel.org CC: Manish Chopra Signed-off-by: Jarod Wilson Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index d4481454b5f8..1205f6f9c941 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -353,7 +353,8 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p) if (!is_valid_ether_addr(addr->sa_data)) return -EINVAL; - if (ether_addr_equal_unaligned(adapter->mac_addr, addr->sa_data)) + if (ether_addr_equal_unaligned(adapter->mac_addr, addr->sa_data) && + ether_addr_equal_unaligned(netdev->dev_addr, addr->sa_data)) return 0; if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) { -- cgit v1.2.3 From 40baec225765c54eefa870530dd613bad9829bb7 Mon Sep 17 00:00:00 2001 From: Jay Vosburgh Date: Fri, 6 Nov 2015 17:23:23 -0800 Subject: bonding: fix panic on non-ARPHRD_ETHER enslave failure Since commit 7d5cd2ce529b, when bond_enslave fails on devices that are not ARPHRD_ETHER, if needed, it resets the bonding device back to ARPHRD_ETHER by calling ether_setup. Unfortunately, ether_setup clobbers dev->flags, clearing IFF_UP if the bond device is up, leaving it in a quasi-down state without having actually gone through dev_close. For bonding, if any periodic work queue items are active (miimon, arp_interval, etc), those will remain running, as they are stopped by bond_close. At this point, if the bonding module is unloaded or the bond is deleted, the system will panic when the work function is called. This panic is resolved by calling dev_close on the bond itself prior to calling ether_setup. Cc: Nikolay Aleksandrov Signed-off-by: Jay Vosburgh Fixes: 7d5cd2ce5292 ("bonding: correctly handle bonding type change on enslave failure") Acked-by: Nikolay Aleksandrov Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b4351caf8e01..9e0f8a7ef8b1 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1749,6 +1749,7 @@ err_undo_flags: slave_dev->dev_addr)) eth_hw_addr_random(bond_dev); if (bond_dev->type != ARPHRD_ETHER) { + dev_close(bond_dev); ether_setup(bond_dev); bond_dev->flags |= IFF_MASTER; bond_dev->priv_flags &= ~IFF_TX_SKB_SHARING; -- cgit v1.2.3 From 3694bfbdb3bd5cf6632140c7f7fdf6f31d43ee66 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sat, 7 Nov 2015 16:30:34 +0100 Subject: dwc_eth_qos: Delete an unnecessary check before the function call "of_node_put" The of_node_put() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: David S. Miller --- drivers/net/ethernet/synopsys/dwc_eth_qos.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/synopsys/dwc_eth_qos.c b/drivers/net/ethernet/synopsys/dwc_eth_qos.c index 85b3326775b8..9066d7a8483c 100644 --- a/drivers/net/ethernet/synopsys/dwc_eth_qos.c +++ b/drivers/net/ethernet/synopsys/dwc_eth_qos.c @@ -2970,8 +2970,7 @@ err_out_unregister_netdev: err_out_clk_dis_aper: clk_disable_unprepare(lp->apb_pclk); err_out_free_netdev: - if (lp->phy_node) - of_node_put(lp->phy_node); + of_node_put(lp->phy_node); free_netdev(ndev); platform_set_drvdata(pdev, NULL); return ret; -- cgit v1.2.3 From 761d4be5cf666973db317aab944b45bb07fe0a4f Mon Sep 17 00:00:00 2001 From: Iyappan Subramanian Date: Sat, 7 Nov 2015 11:50:40 -0800 Subject: drivers: net: xgene: fix RGMII 10/100Mb mode This patch fixes the RGMII 10/100M mode by reprogramming the clock. Signed-off-by: Iyappan Subramanian Tested-by: Fushen Chen Signed-off-by: David S. Miller --- drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | 49 +++++++++++++++++++++++- drivers/net/ethernet/apm/xgene/xgene_enet_hw.h | 1 + drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 1 - 3 files changed, 48 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c index 33850a0f7e82..c31e691d11fc 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c @@ -459,6 +459,45 @@ static void xgene_gmac_reset(struct xgene_enet_pdata *pdata) xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, 0); } +static void xgene_enet_configure_clock(struct xgene_enet_pdata *pdata) +{ + struct device *dev = &pdata->pdev->dev; + + if (dev->of_node) { + struct clk *parent = clk_get_parent(pdata->clk); + + switch (pdata->phy_speed) { + case SPEED_10: + clk_set_rate(parent, 2500000); + break; + case SPEED_100: + clk_set_rate(parent, 25000000); + break; + default: + clk_set_rate(parent, 125000000); + break; + } + } +#ifdef CONFIG_ACPI + else { + switch (pdata->phy_speed) { + case SPEED_10: + acpi_evaluate_object(ACPI_HANDLE(dev), + "S10", NULL, NULL); + break; + case SPEED_100: + acpi_evaluate_object(ACPI_HANDLE(dev), + "S100", NULL, NULL); + break; + default: + acpi_evaluate_object(ACPI_HANDLE(dev), + "S1G", NULL, NULL); + break; + } + } +#endif +} + static void xgene_gmac_init(struct xgene_enet_pdata *pdata) { struct device *dev = &pdata->pdev->dev; @@ -477,12 +516,14 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata) switch (pdata->phy_speed) { case SPEED_10: ENET_INTERFACE_MODE2_SET(&mc2, 1); + intf_ctl &= ~(ENET_LHD_MODE | ENET_GHD_MODE); CFG_MACMODE_SET(&icm0, 0); CFG_WAITASYNCRD_SET(&icm2, 500); rgmii &= ~CFG_SPEED_1250; break; case SPEED_100: ENET_INTERFACE_MODE2_SET(&mc2, 1); + intf_ctl &= ~ENET_GHD_MODE; intf_ctl |= ENET_LHD_MODE; CFG_MACMODE_SET(&icm0, 1); CFG_WAITASYNCRD_SET(&icm2, 80); @@ -490,12 +531,15 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata) break; default: ENET_INTERFACE_MODE2_SET(&mc2, 2); + intf_ctl &= ~ENET_LHD_MODE; intf_ctl |= ENET_GHD_MODE; - + CFG_MACMODE_SET(&icm0, 2); + CFG_WAITASYNCRD_SET(&icm2, 0); if (dev->of_node) { CFG_TXCLK_MUXSEL0_SET(&rgmii, pdata->tx_delay); CFG_RXCLK_MUXSEL0_SET(&rgmii, pdata->rx_delay); } + rgmii |= CFG_SPEED_1250; xgene_enet_rd_csr(pdata, DEBUG_REG_ADDR, &value); value |= CFG_BYPASS_UNISEC_TX | CFG_BYPASS_UNISEC_RX; @@ -503,7 +547,7 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata) break; } - mc2 |= FULL_DUPLEX2; + mc2 |= FULL_DUPLEX2 | PAD_CRC; xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_2_ADDR, mc2); xgene_enet_wr_mcx_mac(pdata, INTERFACE_CONTROL_ADDR, intf_ctl); @@ -522,6 +566,7 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata) /* Rtype should be copied from FP */ xgene_enet_wr_csr(pdata, RSIF_RAM_DBG_REG0_ADDR, 0); xgene_enet_wr_csr(pdata, RGMII_REG_0_ADDR, rgmii); + xgene_enet_configure_clock(pdata); /* Rx-Tx traffic resume */ xgene_enet_wr_csr(pdata, CFG_LINK_AGGR_RESUME_0_ADDR, TX_PORT0); diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h index 6dee73c3c1e1..c153a1dc5ff7 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h @@ -181,6 +181,7 @@ enum xgene_enet_rm { #define ENET_LHD_MODE BIT(25) #define ENET_GHD_MODE BIT(26) #define FULL_DUPLEX2 BIT(0) +#define PAD_CRC BIT(2) #define SCAN_AUTO_INCR BIT(5) #define TBYT_ADDR 0x38 #define TPKT_ADDR 0x39 diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c index ce1068771b32..991412ce6f48 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c @@ -698,7 +698,6 @@ static int xgene_enet_open(struct net_device *ndev) else schedule_delayed_work(&pdata->link_work, PHY_POLL_LINK_OFF); - netif_carrier_off(ndev); netif_start_queue(ndev); return ret; -- cgit v1.2.3 From 3870502a66fe26c80c034db1aa915d69850854aa Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 9 Nov 2015 10:34:30 +0100 Subject: net: hisilicon: NET_VENDOR_HISILICON should depend on HAS_DMA If NO_DMA=y: ERROR: "dma_set_mask" [drivers/net/ethernet/hisilicon/hns/hns_enet_drv.ko] undefined! ERROR: "dma_unmap_single" [drivers/net/ethernet/hisilicon/hns/hns_enet_drv.ko] undefined! ERROR: "dma_unmap_page" [drivers/net/ethernet/hisilicon/hns/hns_enet_drv.ko] undefined! ERROR: "dma_mapping_error" [drivers/net/ethernet/hisilicon/hns/hns_enet_drv.ko] undefined! ERROR: "dma_map_page" [drivers/net/ethernet/hisilicon/hns/hns_enet_drv.ko] undefined! ERROR: "dma_supported" [drivers/net/ethernet/hisilicon/hns/hns_enet_drv.ko] undefined! ERROR: "dma_map_single" [drivers/net/ethernet/hisilicon/hns/hns_enet_drv.ko] undefined! ERROR: "dma_set_mask" [drivers/net/ethernet/hisilicon/hns/hns_dsaf.ko] undefined! ERROR: "dma_supported" [drivers/net/ethernet/hisilicon/hns/hns_dsaf.ko] undefined! ERROR: "dma_unmap_single" [drivers/net/ethernet/hisilicon/hns/hnae.ko] undefined! ERROR: "dma_unmap_page" [drivers/net/ethernet/hisilicon/hns/hnae.ko] undefined! ERROR: "dma_mapping_error" [drivers/net/ethernet/hisilicon/hns/hnae.ko] undefined! ERROR: "dma_map_page" [drivers/net/ethernet/hisilicon/hns/hnae.ko] undefined! ERROR: "dma_map_single" [drivers/net/ethernet/hisilicon/hns/hnae.ko] undefined! ERROR: "dma_alloc_coherent" [drivers/net/ethernet/hisilicon/hix5hd2_gmac.ko] undefined! ERROR: "dma_mapping_error" [drivers/net/ethernet/hisilicon/hix5hd2_gmac.ko] undefined! ERROR: "dma_map_single" [drivers/net/ethernet/hisilicon/hix5hd2_gmac.ko] undefined! ERROR: "dma_unmap_single" [drivers/net/ethernet/hisilicon/hix5hd2_gmac.ko] undefined! ERROR: "dma_free_coherent" [drivers/net/ethernet/hisilicon/hix5hd2_gmac.ko] undefined! ERROR: "dma_alloc_coherent" [drivers/net/ethernet/hisilicon/hip04_eth.ko] undefined! ERROR: "dma_mapping_error" [drivers/net/ethernet/hisilicon/hip04_eth.ko] undefined! ERROR: "dma_map_single" [drivers/net/ethernet/hisilicon/hip04_eth.ko] undefined! ERROR: "dma_unmap_single" [drivers/net/ethernet/hisilicon/hip04_eth.ko] undefined! ERROR: "dma_free_coherent" [drivers/net/ethernet/hisilicon/hip04_eth.ko] undefined! As this affects all of HNS_ENET, HNS_DSAF, HNS, HIX5HD2_GMAC, and HIP04_ETH, add a dependency on HAS_DMA to the main NET_VENDOR_HISILICON symbol to fix this. Signed-off-by: Geert Uytterhoeven Acked-by: Arnd Bergmann Signed-off-by: David S. Miller --- drivers/net/ethernet/hisilicon/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/hisilicon/Kconfig b/drivers/net/ethernet/hisilicon/Kconfig index f250dec488fd..74beb1867230 100644 --- a/drivers/net/ethernet/hisilicon/Kconfig +++ b/drivers/net/ethernet/hisilicon/Kconfig @@ -5,7 +5,8 @@ config NET_VENDOR_HISILICON bool "Hisilicon devices" default y - depends on OF && (ARM || ARM64 || COMPILE_TEST) + depends on OF && HAS_DMA + depends on ARM || ARM64 || COMPILE_TEST ---help--- If you have a network (Ethernet) card belonging to this class, say Y. -- cgit v1.2.3 From cfb76d77c009b38e607c8a2adc8bdd57b5081768 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Mon, 9 Nov 2015 13:19:10 +0100 Subject: net: caif: check return value of alloc_netdev I don't know if dev can actually be NULL here, but the test should be above alloc_netdev(), to avoid leaking the struct net_device in case dev is actually NULL. And of course the return value from alloc_netdev should be tested. Signed-off-by: Rasmus Villemoes Signed-off-by: David S. Miller --- drivers/net/caif/caif_spi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c index de3962014af7..4721948a92f6 100644 --- a/drivers/net/caif/caif_spi.c +++ b/drivers/net/caif/caif_spi.c @@ -730,11 +730,14 @@ int cfspi_spi_probe(struct platform_device *pdev) int res; dev = (struct cfspi_dev *)pdev->dev.platform_data; - ndev = alloc_netdev(sizeof(struct cfspi), "cfspi%d", - NET_NAME_UNKNOWN, cfspi_setup); if (!dev) return -ENODEV; + ndev = alloc_netdev(sizeof(struct cfspi), "cfspi%d", + NET_NAME_UNKNOWN, cfspi_setup); + if (!ndev) + return -ENOMEM; + cfspi = netdev_priv(ndev); netif_stop_queue(ndev); cfspi->ndev = ndev; -- cgit v1.2.3 From 4bed5395a521b475c2164510596d9af366a3d6dc Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 9 Nov 2015 15:08:57 +0100 Subject: mvneta: add FIXED_PHY dependency The fixed_phy infrastructure is done in a way that is optional, by providing 'static inline' helper functions doing nothing in include/linux/phy_fixed.h for all its APIs. However, three out of the four users (DSA, BCMGENET, and SYSTEMPORT) always 'select FIXED_PHY', presumably because they need that. MVNETA is the fourth one, and if that is built-in but FIXED_PHY is configured as a loadable module, we get a link error: drivers/built-in.o: In function `mvneta_fixed_link_update': fpga-mgr.c:(.text+0x33ed80): undefined reference to `fixed_phy_update_state' Presumably this driver has the same dependency as the others, so this patch also uses 'select' to ensure that the fixed-phy support is built-in. Signed-off-by: Arnd Bergmann Fixes: 898b2970e2c9 ("mvneta: implement SGMII-based in-band link state signaling") Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig index 80af9ffce5ea..a1c862b4664d 100644 --- a/drivers/net/ethernet/marvell/Kconfig +++ b/drivers/net/ethernet/marvell/Kconfig @@ -44,6 +44,7 @@ config MVNETA tristate "Marvell Armada 370/38x/XP network interface support" depends on PLAT_ORION select MVMDIO + select FIXED_PHY ---help--- This driver supports the network interface units in the Marvell ARMADA XP, ARMADA 370 and ARMADA 38x SoC family. -- cgit v1.2.3 From a499a2e9d9c03fd35bd9920b629e4d5b1d6cc1f0 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Mon, 9 Nov 2015 09:14:17 -0500 Subject: macvtap: Resolve possible __might_sleep warning in macvtap_do_read() macvtap_do_read code calls macvtap_put_user while it might be set up to wait for the user. This results in the following warning: Jun 23 16:25:26 galen kernel: ------------[ cut here ]------------ Jun 23 16:25:26 galen kernel: WARNING: CPU: 0 PID: 30433 at kernel/sched/core.c: 7286 __might_sleep+0x7f/0x90() Jun 23 16:25:26 galen kernel: do not call blocking ops when !TASK_RUNNING; state =1 set at [] prepare_to_wait+0x2f/0x90 Jun 23 16:25:26 galen kernel: CPU: 0 PID: 30433 Comm: cat Not tainted 4.1.0-rc6+ #11 Jun 23 16:25:26 galen kernel: Call Trace: Jun 23 16:25:26 galen kernel: [] dump_stack+0x4c/0x65 Jun 23 16:25:26 galen kernel: [] warn_slowpath_common+0x8a/0xc 0 Jun 23 16:25:26 galen kernel: [] warn_slowpath_fmt+0x46/0x50 Jun 23 16:25:26 galen kernel: [] ? prepare_to_wait+0x2f/0x90 Jun 23 16:25:26 galen kernel: [] ? prepare_to_wait+0x2f/0x90 Jun 23 16:25:26 galen kernel: [] __might_sleep+0x7f/0x90 Jun 23 16:25:26 galen kernel: [] might_fault+0x55/0xb0 Jun 23 16:25:26 galen kernel: [] ? trace_hardirqs_on_caller+0x fd/0x1c0 Jun 23 16:25:26 galen kernel: [] copy_to_iter+0x7c/0x360 Jun 23 16:25:26 galen kernel: [] macvtap_do_read+0x256/0x3d0 [macvtap] Jun 23 16:25:26 galen kernel: [] ? prepare_to_wait_event+0x110/0x110 Jun 23 16:25:26 galen kernel: [] macvtap_read_iter+0x2b/0x50 [macvtap] Jun 23 16:25:26 galen kernel: [] __vfs_read+0xae/0xe0 Jun 23 16:25:26 galen kernel: [] vfs_read+0x86/0x140 Jun 23 16:25:26 galen kernel: [] SyS_read+0x49/0xb0 Jun 23 16:25:26 galen kernel: [] system_call_fastpath+0x12/0x76 Jun 23 16:25:26 galen kernel: ---[ end trace 22e33f67e70c0c2a ]--- Make sure thet we call finish_wait() if we have the skb to process before trying to actually process it. Signed-off-by: Vladislav Yasevich Signed-off-by: David S. Miller --- drivers/net/macvtap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 197c93937c2d..54036ae0a388 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -935,6 +935,9 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q, /* Nothing to read, let's sleep */ schedule(); } + if (!noblock) + finish_wait(sk_sleep(&q->sk), &wait); + if (skb) { ret = macvtap_put_user(q, skb, to); if (unlikely(ret < 0)) @@ -942,8 +945,6 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q, else consume_skb(skb); } - if (!noblock) - finish_wait(sk_sleep(&q->sk), &wait); return ret; } -- cgit v1.2.3 From 8c94ddbc139bf8511d79153a81191b07f8e03eb4 Mon Sep 17 00:00:00 2001 From: Justin Maggard Date: Mon, 9 Nov 2015 17:21:05 -0800 Subject: net: mvneta: Fix memory use after free. After changing an interface's MTU, then bringing the interface down and back up again, I immediately saw tons of kernel messages like below. The reason for this bad behavior is mvneta_rxq_drop_pkts(), which calls dma_unmap_single() on already-freed memory. So we need to switch the order of those two operations. [ 152.388518] BUG: Bad page state in process ifconfig pfn:1b518 [ 152.388526] page:dff3dbc0 count:0 mapcount:0 mapping: (null) index:0x0 [ 152.395178] flags: 0x200(arch_1) [ 152.398441] page dumped because: PAGE_FLAGS_CHECK_AT_PREP flag set [ 152.398446] bad because of flags: [ 152.398450] flags: 0x200(arch_1) [ 152.401716] Modules linked in: [ 152.401728] CPU: 0 PID: 1453 Comm: ifconfig Tainted: P B O 4.1.12.armada.1 #1 [ 152.401733] Hardware name: Marvell Armada 370/XP (Device Tree) [ 152.401749] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [ 152.401762] [] (show_stack) from [] (dump_stack+0x74/0x90) [ 152.401772] [] (dump_stack) from [] (bad_page+0xc4/0x124) [ 152.401783] [] (bad_page) from [] (get_page_from_freelist+0x4e4/0x644) [ 152.401794] [] (get_page_from_freelist) from [] (__alloc_pages_nodemask+0x148/0x784) [ 152.401805] [] (__alloc_pages_nodemask) from [] (kmalloc_order+0x10/0x20) [ 152.401818] [] (kmalloc_order) from [] (mvneta_rx_refill+0xc4/0xe8) [ 152.401830] [] (mvneta_rx_refill) from [] (mvneta_setup_rxqs+0x298/0x39c) [ 152.401842] [] (mvneta_setup_rxqs) from [] (mvneta_open+0x3c/0x150) [ 152.401853] [] (mvneta_open) from [] (__dev_open+0xac/0x124) [ 152.401864] [] (__dev_open) from [] (__dev_change_flags+0x8c/0x148) [ 152.401875] [] (__dev_change_flags) from [] (dev_change_flags+0x18/0x48) [ 152.401886] [] (dev_change_flags) from [] (devinet_ioctl+0x620/0x6d0) [ 152.401897] [] (devinet_ioctl) from [] (sock_ioctl+0x64/0x288) [ 152.401908] [] (sock_ioctl) from [] (do_vfs_ioctl+0x78/0x608) [ 152.401918] [] (do_vfs_ioctl) from [] (SyS_ioctl+0x64/0x74) [ 152.401930] [] (SyS_ioctl) from [] (ret_fast_syscall+0x0/0x3c) Signed-off-by: Justin Maggard Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvneta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index a47496a020d9..e84c7f2634d3 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -1493,9 +1493,9 @@ static void mvneta_rxq_drop_pkts(struct mvneta_port *pp, struct mvneta_rx_desc *rx_desc = rxq->descs + i; void *data = (void *)rx_desc->buf_cookie; - mvneta_frag_free(pp, data); dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr, MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE); + mvneta_frag_free(pp, data); } if (rx_done) -- cgit v1.2.3 From 4bdb96cb69d9e4c6038a976fa9def9f8ae024ff8 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 10 Nov 2015 11:28:15 +0100 Subject: qed: select ZLIB_INFLATE The newly added qlogic qed driver uses the zlib library, but misses the dependency: drivers/built-in.o: In function `qed_alloc_stream_mem': drivers/net/ethernet/qlogic/qed/qed_main.c:707: undefined reference to `zlib_inflate_workspacesize' drivers/built-in.o: In function `qed_unzip_data': drivers/net/ethernet/qlogic/qed/qed_main.c:675: undefined reference to `zlib_inflateInit2' This changes Kconfig to always select zlib when needed. Signed-off-by: Arnd Bergmann Fixes: fe56b9e6a8d9 ("qed: Add module with basic common support") Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/Kconfig b/drivers/net/ethernet/qlogic/Kconfig index 30a6f246dfc9..ddcfcab034c2 100644 --- a/drivers/net/ethernet/qlogic/Kconfig +++ b/drivers/net/ethernet/qlogic/Kconfig @@ -94,6 +94,7 @@ config NETXEN_NIC config QED tristate "QLogic QED 25/40/100Gb core driver" depends on PCI + select ZLIB_INFLATE ---help--- This enables the support for ... -- cgit v1.2.3