diff options
Diffstat (limited to 'drivers/net/ethernet/qualcomm')
-rw-r--r-- | drivers/net/ethernet/qualcomm/emac/emac-sgmii.c | 22 | ||||
-rw-r--r-- | drivers/net/ethernet/qualcomm/emac/emac.c | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/qualcomm/qca_7k.c | 17 | ||||
-rw-r--r-- | drivers/net/ethernet/qualcomm/qca_7k.h | 16 | ||||
-rw-r--r-- | drivers/net/ethernet/qualcomm/qca_7k_common.c | 17 | ||||
-rw-r--r-- | drivers/net/ethernet/qualcomm/qca_7k_common.h | 29 | ||||
-rw-r--r-- | drivers/net/ethernet/qualcomm/qca_debug.c | 27 | ||||
-rw-r--r-- | drivers/net/ethernet/qualcomm/qca_debug.h | 15 | ||||
-rw-r--r-- | drivers/net/ethernet/qualcomm/qca_spi.c | 131 | ||||
-rw-r--r-- | drivers/net/ethernet/qualcomm/qca_spi.h | 26 | ||||
-rw-r--r-- | drivers/net/ethernet/qualcomm/qca_uart.c | 19 | ||||
-rw-r--r-- | drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c | 6 |
13 files changed, 109 insertions, 222 deletions
diff --git a/drivers/net/ethernet/qualcomm/emac/emac-sgmii.c b/drivers/net/ethernet/qualcomm/emac/emac-sgmii.c index e4bc18009d08..a508ebc4b206 100644 --- a/drivers/net/ethernet/qualcomm/emac/emac-sgmii.c +++ b/drivers/net/ethernet/qualcomm/emac/emac-sgmii.c @@ -293,6 +293,11 @@ static struct sgmii_ops qdf2400_ops = { }; #endif +struct emac_match_data { + struct sgmii_ops **sgmii_ops; + struct device *target_device; +}; + static int emac_sgmii_acpi_match(struct device *dev, void *data) { #ifdef CONFIG_ACPI @@ -303,7 +308,7 @@ static int emac_sgmii_acpi_match(struct device *dev, void *data) {} }; const struct acpi_device_id *id = acpi_match_device(match_table, dev); - struct sgmii_ops **ops = data; + struct emac_match_data *match_data = data; if (id) { acpi_handle handle = ACPI_HANDLE(dev); @@ -324,10 +329,12 @@ static int emac_sgmii_acpi_match(struct device *dev, void *data) switch (hrv) { case 1: - *ops = &qdf2432_ops; + *match_data->sgmii_ops = &qdf2432_ops; + match_data->target_device = dev; return 1; case 2: - *ops = &qdf2400_ops; + *match_data->sgmii_ops = &qdf2400_ops; + match_data->target_device = dev; return 1; } } @@ -356,16 +363,21 @@ int emac_sgmii_config(struct platform_device *pdev, struct emac_adapter *adpt) int ret; if (has_acpi_companion(&pdev->dev)) { + struct emac_match_data match_data = { + .sgmii_ops = &phy->sgmii_ops, + .target_device = NULL, + }; struct device *dev; - dev = device_find_child(&pdev->dev, &phy->sgmii_ops, - emac_sgmii_acpi_match); + device_for_each_child(&pdev->dev, &match_data, emac_sgmii_acpi_match); + dev = match_data.target_device; if (!dev) { dev_warn(&pdev->dev, "cannot find internal phy node\n"); return 0; } + get_device(dev); sgmii_pdev = to_platform_device(dev); } else { const struct of_device_id *match; diff --git a/drivers/net/ethernet/qualcomm/emac/emac.c b/drivers/net/ethernet/qualcomm/emac/emac.c index 3270df72541b..699a8afc214a 100644 --- a/drivers/net/ethernet/qualcomm/emac/emac.c +++ b/drivers/net/ethernet/qualcomm/emac/emac.c @@ -216,7 +216,7 @@ static int emac_change_mtu(struct net_device *netdev, int new_mtu) netif_dbg(adpt, hw, adpt->netdev, "changing MTU from %d to %d\n", netdev->mtu, new_mtu); - netdev->mtu = new_mtu; + WRITE_ONCE(netdev->mtu, new_mtu); if (netif_running(netdev)) return emac_reinit_locked(adpt); @@ -760,7 +760,7 @@ static void emac_shutdown(struct platform_device *pdev) static struct platform_driver emac_platform_driver = { .probe = emac_probe, - .remove_new = emac_remove, + .remove = emac_remove, .driver = { .name = "qcom-emac", .of_match_table = emac_dt_match, @@ -771,5 +771,6 @@ static struct platform_driver emac_platform_driver = { module_platform_driver(emac_platform_driver); +MODULE_DESCRIPTION("Qualcomm EMAC Gigabit Ethernet driver"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:qcom-emac"); diff --git a/drivers/net/ethernet/qualcomm/qca_7k.c b/drivers/net/ethernet/qualcomm/qca_7k.c index 4292c89bd35c..6263e4cf47fa 100644 --- a/drivers/net/ethernet/qualcomm/qca_7k.c +++ b/drivers/net/ethernet/qualcomm/qca_7k.c @@ -1,22 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause /* - * * Copyright (c) 2011, 2012, Qualcomm Atheros Communications Inc. * Copyright (c) 2014, I2SE GmbH - * - * Permission to use, copy, modify, and/or distribute this software - * for any purpose with or without fee is hereby granted, provided - * that the above copyright notice and this permission notice appear - * in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * */ /* This module implements the Qualcomm Atheros SPI protocol for diff --git a/drivers/net/ethernet/qualcomm/qca_7k.h b/drivers/net/ethernet/qualcomm/qca_7k.h index 356de8ec5d48..828ee9c27578 100644 --- a/drivers/net/ethernet/qualcomm/qca_7k.h +++ b/drivers/net/ethernet/qualcomm/qca_7k.h @@ -1,21 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ /* * Copyright (c) 2011, 2012, Qualcomm Atheros Communications Inc. * Copyright (c) 2014, I2SE GmbH - * - * Permission to use, copy, modify, and/or distribute this software - * for any purpose with or without fee is hereby granted, provided - * that the above copyright notice and this permission notice appear - * in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * */ /* Qualcomm Atheros SPI register definition. diff --git a/drivers/net/ethernet/qualcomm/qca_7k_common.c b/drivers/net/ethernet/qualcomm/qca_7k_common.c index 6b511f05df61..5302da587620 100644 --- a/drivers/net/ethernet/qualcomm/qca_7k_common.c +++ b/drivers/net/ethernet/qualcomm/qca_7k_common.c @@ -1,20 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause /* * Copyright (c) 2011, 2012, Atheros Communications Inc. * Copyright (c) 2014, I2SE GmbH - * - * Permission to use, copy, modify, and/or distribute this software - * for any purpose with or without fee is hereby granted, provided - * that the above copyright notice and this permission notice appear - * in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* Atheros ethernet framing. Every Ethernet frame is surrounded @@ -162,5 +149,5 @@ EXPORT_SYMBOL_GPL(qcafrm_fsm_decode); MODULE_DESCRIPTION("Qualcomm Atheros QCA7000 common"); MODULE_AUTHOR("Qualcomm Atheros Communications"); -MODULE_AUTHOR("Stefan Wahren <stefan.wahren@i2se.com>"); +MODULE_AUTHOR("Stefan Wahren <wahrenst@gmx.net>"); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/ethernet/qualcomm/qca_7k_common.h b/drivers/net/ethernet/qualcomm/qca_7k_common.h index 928554f11e35..44ed66fdb407 100644 --- a/drivers/net/ethernet/qualcomm/qca_7k_common.h +++ b/drivers/net/ethernet/qualcomm/qca_7k_common.h @@ -1,20 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ /* * Copyright (c) 2011, 2012, Atheros Communications Inc. * Copyright (c) 2014, I2SE GmbH - * - * Permission to use, copy, modify, and/or distribute this software - * for any purpose with or without fee is hereby granted, provided - * that the above copyright notice and this permission notice appear - * in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* Atheros Ethernet framing. Every Ethernet frame is surrounded by an atheros @@ -107,9 +94,6 @@ struct qcafrm_handle { /* Offset in buffer (borrowed for length too) */ u16 offset; - - /* Frame length as kept by this module */ - u16 len; }; u16 qcafrm_create_header(u8 *buf, u16 len); @@ -128,17 +112,6 @@ static inline void qcafrm_fsm_init_uart(struct qcafrm_handle *handle) handle->state = handle->init; } -/* Gather received bytes and try to extract a full Ethernet frame - * by following a simple state machine. - * - * Return: QCAFRM_GATHER No Ethernet frame fully received yet. - * QCAFRM_NOHEAD Header expected but not found. - * QCAFRM_INVLEN QCA7K frame length is invalid - * QCAFRM_NOTAIL Footer expected but not found. - * > 0 Number of byte in the fully received - * Ethernet frame - */ - s32 qcafrm_fsm_decode(struct qcafrm_handle *handle, u8 *buf, u16 buf_len, u8 recv_byte); #endif /* _QCA_FRAMING_H */ diff --git a/drivers/net/ethernet/qualcomm/qca_debug.c b/drivers/net/ethernet/qualcomm/qca_debug.c index 1822f2ad8f0d..13deb3da4a64 100644 --- a/drivers/net/ethernet/qualcomm/qca_debug.c +++ b/drivers/net/ethernet/qualcomm/qca_debug.c @@ -1,20 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause /* * Copyright (c) 2011, 2012, Qualcomm Atheros Communications Inc. * Copyright (c) 2014, I2SE GmbH - * - * Permission to use, copy, modify, and/or distribute this software - * for any purpose with or without fee is hereby granted, provided - * that the above copyright notice and this permission notice appear - * in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* This file contains debugging routines for use in the QCA7K driver. @@ -111,10 +98,8 @@ qcaspi_info_show(struct seq_file *s, void *what) seq_printf(s, "IRQ : %d\n", qca->spi_dev->irq); - seq_printf(s, "INTR REQ : %u\n", - qca->intr_req); - seq_printf(s, "INTR SVC : %u\n", - qca->intr_svc); + seq_printf(s, "FLAGS : %lx\n", + qca->flags); seq_printf(s, "SPI max speed : %lu\n", (unsigned long)qca->spi_dev->max_speed_hz); @@ -255,7 +240,7 @@ qcaspi_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring, struct qcaspi *qca = netdev_priv(dev); ring->rx_max_pending = QCASPI_RX_MAX_FRAMES; - ring->tx_max_pending = TX_RING_MAX_LEN; + ring->tx_max_pending = QCASPI_TX_RING_MAX_LEN; ring->rx_pending = QCASPI_RX_MAX_FRAMES; ring->tx_pending = qca->txr.count; } @@ -275,8 +260,8 @@ qcaspi_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring, if (qca->spi_thread) kthread_park(qca->spi_thread); - qca->txr.count = max_t(u32, ring->tx_pending, TX_RING_MIN_LEN); - qca->txr.count = min_t(u16, qca->txr.count, TX_RING_MAX_LEN); + qca->txr.count = max_t(u32, ring->tx_pending, QCASPI_TX_RING_MIN_LEN); + qca->txr.count = min_t(u16, qca->txr.count, QCASPI_TX_RING_MAX_LEN); if (qca->spi_thread) kthread_unpark(qca->spi_thread); diff --git a/drivers/net/ethernet/qualcomm/qca_debug.h b/drivers/net/ethernet/qualcomm/qca_debug.h index 46a785844421..0d98cef3abc4 100644 --- a/drivers/net/ethernet/qualcomm/qca_debug.h +++ b/drivers/net/ethernet/qualcomm/qca_debug.h @@ -1,20 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ /* * Copyright (c) 2011, 2012, Qualcomm Atheros Communications Inc. * Copyright (c) 2014, I2SE GmbH - * - * Permission to use, copy, modify, and/or distribute this software - * for any purpose with or without fee is hereby granted, provided - * that the above copyright notice and this permission notice appear - * in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* This file contains debugging routines for use in the QCA7K driver. diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c index 5f3c11fb3fa2..38a779f4b866 100644 --- a/drivers/net/ethernet/qualcomm/qca_spi.c +++ b/drivers/net/ethernet/qualcomm/qca_spi.c @@ -1,20 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause /* * Copyright (c) 2011, 2012, Qualcomm Atheros Communications Inc. * Copyright (c) 2014, I2SE GmbH - * - * Permission to use, copy, modify, and/or distribute this software - * for any purpose with or without fee is hereby granted, provided - * that the above copyright notice and this permission notice appear - * in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* This module implements the Qualcomm Atheros SPI protocol for @@ -48,6 +35,9 @@ #define MAX_DMA_BURST_LEN 5000 +#define SPI_INTR 0 +#define SPI_RESET 1 + /* Modules parameters */ #define QCASPI_CLK_SPEED_MIN 1000000 #define QCASPI_CLK_SPEED_MAX 16000000 @@ -64,7 +54,7 @@ MODULE_PARM_DESC(qcaspi_burst_len, "Number of data bytes per burst. Use 1-5000." #define QCASPI_PLUGGABLE_MIN 0 #define QCASPI_PLUGGABLE_MAX 1 -static int qcaspi_pluggable = QCASPI_PLUGGABLE_MIN; +static int qcaspi_pluggable = QCASPI_PLUGGABLE_MAX; module_param(qcaspi_pluggable, int, 0); MODULE_PARM_DESC(qcaspi_pluggable, "Pluggable SPI connection (yes/no)."); @@ -359,7 +349,7 @@ qcaspi_receive(struct qcaspi *qca) /* Read the packet size. */ qcaspi_read_register(qca, SPI_REG_RDBUF_BYTE_AVA, &available); - netdev_dbg(net_dev, "qcaspi_receive: SPI_REG_RDBUF_BYTE_AVA: Value: %08x\n", + netdev_dbg(net_dev, "qcaspi_receive: SPI_REG_RDBUF_BYTE_AVA: Value: %04x\n", available); if (available > QCASPI_HW_BUF_LEN + QCASPI_HW_PKT_LEN) { @@ -476,7 +466,7 @@ qcaspi_flush_tx_ring(struct qcaspi *qca) * has been replaced by netif_tx_lock_bh() and so on. */ netif_tx_lock_bh(qca->net_dev); - for (i = 0; i < TX_RING_MAX_LEN; i++) { + for (i = 0; i < QCASPI_TX_RING_MAX_LEN; i++) { if (qca->txr.skb[i]) { dev_kfree_skb(qca->txr.skb[i]); qca->txr.skb[i] = NULL; @@ -506,7 +496,7 @@ qcaspi_qca7k_sync(struct qcaspi *qca, int event) if (qca->sync == QCASPI_SYNC_READY) qca->stats.bad_signature++; - qca->sync = QCASPI_SYNC_UNKNOWN; + set_bit(SPI_RESET, &qca->flags); netdev_dbg(qca->net_dev, "sync: got CPU on, but signature was invalid, restart\n"); return; } else { @@ -516,12 +506,17 @@ qcaspi_qca7k_sync(struct qcaspi *qca, int event) if (wrbuf_space != QCASPI_HW_BUF_LEN) { netdev_dbg(qca->net_dev, "sync: got CPU on, but wrbuf not empty. reset!\n"); qca->sync = QCASPI_SYNC_UNKNOWN; + qca->stats.buf_avail_err++; } else { netdev_dbg(qca->net_dev, "sync: got CPU on, now in sync\n"); qca->sync = QCASPI_SYNC_READY; return; } } + } else { + /* Handle reset only on QCASPI_EVENT_UPDATE */ + if (test_and_clear_bit(SPI_RESET, &qca->flags)) + qca->sync = QCASPI_SYNC_UNKNOWN; } switch (qca->sync) { @@ -532,7 +527,7 @@ qcaspi_qca7k_sync(struct qcaspi *qca, int event) qcaspi_read_register(qca, SPI_REG_SIGNATURE, &signature); if (signature != QCASPI_GOOD_SIGNATURE) { - qca->sync = QCASPI_SYNC_UNKNOWN; + set_bit(SPI_RESET, &qca->flags); qca->stats.bad_signature++; netdev_dbg(qca->net_dev, "sync: bad signature, restart\n"); /* don't reset right away */ @@ -563,7 +558,7 @@ qcaspi_qca7k_sync(struct qcaspi *qca, int event) qca->reset_count); if (qca->reset_count >= QCASPI_RESET_TIMEOUT) { /* reset did not seem to take place, try again */ - qca->sync = QCASPI_SYNC_UNKNOWN; + set_bit(SPI_RESET, &qca->flags); qca->stats.reset_timeout++; netdev_dbg(qca->net_dev, "sync: reset timeout, restarting process.\n"); } @@ -592,14 +587,14 @@ qcaspi_spi_thread(void *data) continue; } - if ((qca->intr_req == qca->intr_svc) && + if (!qca->flags && !qca->txr.skb[qca->txr.head]) schedule(); set_current_state(TASK_RUNNING); - netdev_dbg(qca->net_dev, "have work to do. int: %d, tx_skb: %p\n", - qca->intr_req - qca->intr_svc, + netdev_dbg(qca->net_dev, "have work to do. int: %lu, tx_skb: %p\n", + qca->flags, qca->txr.skb[qca->txr.head]); qcaspi_qca7k_sync(qca, QCASPI_EVENT_UPDATE); @@ -613,8 +608,7 @@ qcaspi_spi_thread(void *data) msleep(QCASPI_QCA7K_REBOOT_TIME_MS); } - if (qca->intr_svc != qca->intr_req) { - qca->intr_svc = qca->intr_req; + if (test_and_clear_bit(SPI_INTR, &qca->flags)) { start_spi_intr_handling(qca, &intr_cause); if (intr_cause & SPI_INT_CPU_ON) { @@ -639,7 +633,7 @@ qcaspi_spi_thread(void *data) /* restart sync */ netdev_dbg(qca->net_dev, "===> rdbuf error!\n"); qca->stats.read_buf_err++; - qca->sync = QCASPI_SYNC_UNKNOWN; + set_bit(SPI_RESET, &qca->flags); continue; } @@ -647,7 +641,7 @@ qcaspi_spi_thread(void *data) /* restart sync */ netdev_dbg(qca->net_dev, "===> wrbuf error!\n"); qca->stats.write_buf_err++; - qca->sync = QCASPI_SYNC_UNKNOWN; + set_bit(SPI_RESET, &qca->flags); continue; } @@ -676,7 +670,7 @@ qcaspi_intr_handler(int irq, void *data) { struct qcaspi *qca = data; - qca->intr_req++; + set_bit(SPI_INTR, &qca->flags); if (qca->spi_thread) wake_up_process(qca->spi_thread); @@ -687,33 +681,27 @@ static int qcaspi_netdev_open(struct net_device *dev) { struct qcaspi *qca = netdev_priv(dev); - int ret = 0; + struct task_struct *thread; if (!qca) return -EINVAL; - qca->intr_req = 1; - qca->intr_svc = 0; + set_bit(SPI_INTR, &qca->flags); qca->sync = QCASPI_SYNC_UNKNOWN; qcafrm_fsm_init_spi(&qca->frm_handle); - qca->spi_thread = kthread_run((void *)qcaspi_spi_thread, - qca, "%s", dev->name); + thread = kthread_run((void *)qcaspi_spi_thread, + qca, "%s", dev->name); - if (IS_ERR(qca->spi_thread)) { + if (IS_ERR(thread)) { netdev_err(dev, "%s: unable to start kernel thread.\n", QCASPI_DRV_NAME); - return PTR_ERR(qca->spi_thread); + return PTR_ERR(thread); } - ret = request_irq(qca->spi_dev->irq, qcaspi_intr_handler, 0, - dev->name, qca); - if (ret) { - netdev_err(dev, "%s: unable to get IRQ %d (irqval=%d).\n", - QCASPI_DRV_NAME, qca->spi_dev->irq, ret); - kthread_stop(qca->spi_thread); - return ret; - } + qca->spi_thread = thread; + + enable_irq(qca->spi_dev->irq); /* SPI thread takes care of TX queue */ @@ -728,10 +716,12 @@ qcaspi_netdev_close(struct net_device *dev) netif_stop_queue(dev); qcaspi_write_register(qca, SPI_REG_INTR_ENABLE, 0, wr_verify); - free_irq(qca->spi_dev->irq, qca); + disable_irq(qca->spi_dev->irq); - kthread_stop(qca->spi_thread); - qca->spi_thread = NULL; + if (qca->spi_thread) { + kthread_stop(qca->spi_thread); + qca->spi_thread = NULL; + } qcaspi_flush_tx_ring(qca); return 0; @@ -815,7 +805,7 @@ qcaspi_netdev_tx_timeout(struct net_device *dev, unsigned int txqueue) jiffies, jiffies - dev_trans_start(dev)); qca->net_dev->stats.tx_errors++; /* Trigger tx queue flush and QCA7000 reset */ - qca->sync = QCASPI_SYNC_UNKNOWN; + set_bit(SPI_RESET, &qca->flags); if (qca->spi_thread) wake_up_process(qca->spi_thread); @@ -828,11 +818,10 @@ qcaspi_netdev_init(struct net_device *dev) dev->mtu = QCAFRM_MAX_MTU; dev->type = ARPHRD_ETHER; - qca->clkspeed = qcaspi_clkspeed; qca->burst_len = qcaspi_burst_len; qca->spi_thread = NULL; - qca->buffer_size = (dev->mtu + VLAN_ETH_HLEN + QCAFRM_HEADER_LEN + - QCAFRM_FOOTER_LEN + 4) * 4; + qca->buffer_size = (QCAFRM_MAX_MTU + VLAN_ETH_HLEN + QCAFRM_HEADER_LEN + + QCAFRM_FOOTER_LEN + QCASPI_HW_PKT_LEN) * QCASPI_RX_MAX_FRAMES; memset(&qca->stats, 0, sizeof(struct qcaspi_stats)); @@ -881,6 +870,8 @@ qcaspi_netdev_setup(struct net_device *dev) qcaspi_set_ethtool_ops(dev); dev->watchdog_timeo = QCASPI_TX_TIMEOUT; dev->priv_flags &= ~IFF_TX_SKB_SHARING; + dev->needed_tailroom = ALIGN(QCAFRM_FOOTER_LEN + QCAFRM_MIN_LEN, 4); + dev->needed_headroom = ALIGN(QCAFRM_HEADER_LEN, 4); dev->tx_queue_len = 100; /* MTU range: 46 - 1500 */ @@ -891,7 +882,7 @@ qcaspi_netdev_setup(struct net_device *dev) memset(qca, 0, sizeof(struct qcaspi)); memset(&qca->txr, 0, sizeof(qca->txr)); - qca->txr.count = TX_RING_MAX_LEN; + qca->txr.count = QCASPI_TX_RING_MAX_LEN; } static const struct of_device_id qca_spi_of_match[] = { @@ -917,17 +908,15 @@ qca_spi_probe(struct spi_device *spi) legacy_mode = of_property_read_bool(spi->dev.of_node, "qca,legacy-mode"); - if (qcaspi_clkspeed == 0) { - if (spi->max_speed_hz) - qcaspi_clkspeed = spi->max_speed_hz; - else - qcaspi_clkspeed = QCASPI_CLK_SPEED; - } + if (qcaspi_clkspeed) + spi->max_speed_hz = qcaspi_clkspeed; + else if (!spi->max_speed_hz) + spi->max_speed_hz = QCASPI_CLK_SPEED; - if ((qcaspi_clkspeed < QCASPI_CLK_SPEED_MIN) || - (qcaspi_clkspeed > QCASPI_CLK_SPEED_MAX)) { - dev_err(&spi->dev, "Invalid clkspeed: %d\n", - qcaspi_clkspeed); + if (spi->max_speed_hz < QCASPI_CLK_SPEED_MIN || + spi->max_speed_hz > QCASPI_CLK_SPEED_MAX) { + dev_err(&spi->dev, "Invalid clkspeed: %u\n", + spi->max_speed_hz); return -EINVAL; } @@ -952,14 +941,13 @@ qca_spi_probe(struct spi_device *spi) return -EINVAL; } - dev_info(&spi->dev, "ver=%s, clkspeed=%d, burst_len=%d, pluggable=%d\n", + dev_info(&spi->dev, "ver=%s, clkspeed=%u, burst_len=%d, pluggable=%d\n", QCASPI_DRV_VERSION, - qcaspi_clkspeed, + spi->max_speed_hz, qcaspi_burst_len, qcaspi_pluggable); spi->mode = SPI_MODE_3; - spi->max_speed_hz = qcaspi_clkspeed; if (spi_setup(spi) < 0) { dev_err(&spi->dev, "Unable to setup SPI device\n"); return -EFAULT; @@ -984,6 +972,15 @@ qca_spi_probe(struct spi_device *spi) spi_set_drvdata(spi, qcaspi_devs); + ret = devm_request_irq(&spi->dev, spi->irq, qcaspi_intr_handler, + IRQF_NO_AUTOEN, qca->net_dev->name, qca); + if (ret) { + dev_err(&spi->dev, "Unable to get IRQ %d (irqval=%d).\n", + spi->irq, ret); + free_netdev(qcaspi_devs); + return ret; + } + ret = of_get_ethdev_address(spi->dev.of_node, qca->net_dev); if (ret) { eth_hw_addr_random(qca->net_dev); @@ -998,8 +995,8 @@ qca_spi_probe(struct spi_device *spi) qcaspi_read_register(qca, SPI_REG_SIGNATURE, &signature); if (signature != QCASPI_GOOD_SIGNATURE) { - dev_err(&spi->dev, "Invalid signature (0x%04X)\n", - signature); + dev_err(&spi->dev, "Invalid signature (expected 0x%04x, read 0x%04x)\n", + QCASPI_GOOD_SIGNATURE, signature); free_netdev(qcaspi_devs); return -EFAULT; } @@ -1048,6 +1045,6 @@ module_spi_driver(qca_spi_driver); MODULE_DESCRIPTION("Qualcomm Atheros QCA7000 SPI Driver"); MODULE_AUTHOR("Qualcomm Atheros Communications"); -MODULE_AUTHOR("Stefan Wahren <stefan.wahren@i2se.com>"); +MODULE_AUTHOR("Stefan Wahren <wahrenst@gmx.net>"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(QCASPI_DRV_VERSION); diff --git a/drivers/net/ethernet/qualcomm/qca_spi.h b/drivers/net/ethernet/qualcomm/qca_spi.h index 3067356106f0..90b290f94c27 100644 --- a/drivers/net/ethernet/qualcomm/qca_spi.h +++ b/drivers/net/ethernet/qualcomm/qca_spi.h @@ -1,20 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ /* * Copyright (c) 2011, 2012, Qualcomm Atheros Communications Inc. * Copyright (c) 2014, I2SE GmbH - * - * Permission to use, copy, modify, and/or distribute this software - * for any purpose with or without fee is hereby granted, provided - * that the above copyright notice and this permission notice appear - * in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* Qualcomm Atheros SPI register definition. @@ -39,8 +26,9 @@ #define QCASPI_GOOD_SIGNATURE 0xAA55 -#define TX_RING_MAX_LEN 10 -#define TX_RING_MIN_LEN 2 +#define QCASPI_TX_RING_MAX_LEN 10 +#define QCASPI_TX_RING_MIN_LEN 2 +#define QCASPI_RX_MAX_FRAMES 4 /* sync related constants */ #define QCASPI_SYNC_UNKNOWN 0 @@ -54,7 +42,7 @@ #define QCASPI_EVENT_CPUON 1 struct tx_ring { - struct sk_buff *skb[TX_RING_MAX_LEN]; + struct sk_buff *skb[QCASPI_TX_RING_MAX_LEN]; u16 head; u16 tail; u16 size; @@ -93,8 +81,7 @@ struct qcaspi { struct qcafrm_handle frm_handle; struct sk_buff *rx_skb; - unsigned int intr_req; - unsigned int intr_svc; + unsigned long flags; u16 reset_count; #ifdef CONFIG_DEBUG_FS @@ -102,7 +89,6 @@ struct qcaspi { #endif /* user configurable options */ - u32 clkspeed; u8 legacy_mode; u16 burst_len; }; diff --git a/drivers/net/ethernet/qualcomm/qca_uart.c b/drivers/net/ethernet/qualcomm/qca_uart.c index 223321897b96..37efb1ea9fcd 100644 --- a/drivers/net/ethernet/qualcomm/qca_uart.c +++ b/drivers/net/ethernet/qualcomm/qca_uart.c @@ -1,20 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause /* * Copyright (c) 2011, 2012, Qualcomm Atheros Communications Inc. * Copyright (c) 2017, I2SE GmbH - * - * Permission to use, copy, modify, and/or distribute this software - * for any purpose with or without fee is hereby granted, provided - * that the above copyright notice and this permission notice appear - * in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* This module implements the Qualcomm Atheros UART protocol for @@ -58,7 +45,7 @@ struct qcauart { unsigned char *tx_buffer; }; -static ssize_t +static size_t qca_tty_receive(struct serdev_device *serdev, const u8 *data, size_t count) { struct qcauart *qca = serdev_device_get_drvdata(serdev); @@ -410,6 +397,6 @@ module_serdev_device_driver(qca_uart_driver); MODULE_DESCRIPTION("Qualcomm Atheros QCA7000 UART Driver"); MODULE_AUTHOR("Qualcomm Atheros Communications"); -MODULE_AUTHOR("Stefan Wahren <stefan.wahren@i2se.com>"); +MODULE_AUTHOR("Stefan Wahren <wahrenst@gmx.net>"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(QCAUART_DRV_VERSION); diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c index 5b69b9268c75..f3bea196a8f9 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c @@ -520,4 +520,5 @@ static void __exit rmnet_exit(void) module_init(rmnet_init) module_exit(rmnet_exit) MODULE_ALIAS_RTNL_LINK("rmnet"); +MODULE_DESCRIPTION("Qualcomm RmNet MAP driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c index 046b5f7d8e7c..4f0ddcedfa97 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c @@ -90,7 +90,7 @@ static int rmnet_vnd_change_mtu(struct net_device *rmnet_dev, int new_mtu) new_mtu > (priv->real_dev->mtu - headroom)) return -EINVAL; - rmnet_dev->mtu = new_mtu; + WRITE_ONCE(rmnet_dev->mtu, new_mtu); return 0; } @@ -98,7 +98,7 @@ static int rmnet_vnd_get_iflink(const struct net_device *dev) { struct rmnet_priv *priv = netdev_priv(dev); - return priv->real_dev->ifindex; + return READ_ONCE(priv->real_dev->ifindex); } static int rmnet_vnd_init(struct net_device *dev) @@ -286,7 +286,7 @@ void rmnet_vnd_setup(struct net_device *rmnet_dev) rmnet_dev->needs_free_netdev = true; rmnet_dev->ethtool_ops = &rmnet_ethtool_ops; - rmnet_dev->features |= NETIF_F_LLTX; + rmnet_dev->lltx = true; /* This perm addr will be used as interface identifier by IPv6 */ rmnet_dev->addr_assign_type = NET_ADDR_RANDOM; |