diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 01:02:30 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 01:02:30 +0000 |
commit | 76cb841cb886eef6b3bee341a2266c76578724ad (patch) | |
tree | f5892e5ba6cc11949952a6ce4ecbe6d516d6ce58 /drivers/net/ethernet/qualcomm/qca_7k.c | |
parent | Initial commit. (diff) | |
download | linux-76cb841cb886eef6b3bee341a2266c76578724ad.tar.xz linux-76cb841cb886eef6b3bee341a2266c76578724ad.zip |
Adding upstream version 4.19.249.upstream/4.19.249
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/net/ethernet/qualcomm/qca_7k.c')
-rw-r--r-- | drivers/net/ethernet/qualcomm/qca_7k.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/drivers/net/ethernet/qualcomm/qca_7k.c b/drivers/net/ethernet/qualcomm/qca_7k.c new file mode 100644 index 000000000..6c8543fb9 --- /dev/null +++ b/drivers/net/ethernet/qualcomm/qca_7k.c @@ -0,0 +1,119 @@ +/* + * + * 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 + * kernel-based SPI device. + */ + +#include <linux/kernel.h> +#include <linux/netdevice.h> +#include <linux/spi/spi.h> + +#include "qca_7k.h" + +void +qcaspi_spi_error(struct qcaspi *qca) +{ + if (qca->sync != QCASPI_SYNC_READY) + return; + + netdev_err(qca->net_dev, "spi error\n"); + qca->sync = QCASPI_SYNC_UNKNOWN; + qca->stats.spi_err++; +} + +int +qcaspi_read_register(struct qcaspi *qca, u16 reg, u16 *result) +{ + __be16 rx_data; + __be16 tx_data; + struct spi_transfer transfer[2]; + struct spi_message msg; + int ret; + + memset(transfer, 0, sizeof(transfer)); + + spi_message_init(&msg); + + tx_data = cpu_to_be16(QCA7K_SPI_READ | QCA7K_SPI_INTERNAL | reg); + *result = 0; + + transfer[0].tx_buf = &tx_data; + transfer[0].len = QCASPI_CMD_LEN; + transfer[1].rx_buf = &rx_data; + transfer[1].len = QCASPI_CMD_LEN; + + spi_message_add_tail(&transfer[0], &msg); + + if (qca->legacy_mode) { + spi_sync(qca->spi_dev, &msg); + spi_message_init(&msg); + } + spi_message_add_tail(&transfer[1], &msg); + ret = spi_sync(qca->spi_dev, &msg); + + if (!ret) + ret = msg.status; + + if (ret) + qcaspi_spi_error(qca); + else + *result = be16_to_cpu(rx_data); + + return ret; +} + +int +qcaspi_write_register(struct qcaspi *qca, u16 reg, u16 value) +{ + __be16 tx_data[2]; + struct spi_transfer transfer[2]; + struct spi_message msg; + int ret; + + memset(&transfer, 0, sizeof(transfer)); + + spi_message_init(&msg); + + tx_data[0] = cpu_to_be16(QCA7K_SPI_WRITE | QCA7K_SPI_INTERNAL | reg); + tx_data[1] = cpu_to_be16(value); + + transfer[0].tx_buf = &tx_data[0]; + transfer[0].len = QCASPI_CMD_LEN; + transfer[1].tx_buf = &tx_data[1]; + transfer[1].len = QCASPI_CMD_LEN; + + spi_message_add_tail(&transfer[0], &msg); + if (qca->legacy_mode) { + spi_sync(qca->spi_dev, &msg); + spi_message_init(&msg); + } + spi_message_add_tail(&transfer[1], &msg); + ret = spi_sync(qca->spi_dev, &msg); + + if (!ret) + ret = msg.status; + + if (ret) + qcaspi_spi_error(qca); + + return ret; +} |