qtnfmac: add support for Topaz chipsets

This patch adds support for QSR1000/QSR2000 family of chipsets
to qtnfmac_pcie platform driver.

QSR1000/QSR2000 (aka Topaz) is a family of 80MHz, 11ac Wave2,
4x4/2x4/2x2 chips, including single and dual band devices.
Depending on specific chip model and firmware in use, either
STA or both STA and AP modes are supported.

Patch adds Topaz support to qtnfmac_pcie driver. Proper platform
bus will be selected on probing based on chip ID.

Signed-off-by: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com>
Signed-off-by: Andrey Shevchenko <ashevchenko@quantenna.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
Sergey Matyukevich 2018-10-16 10:23:58 +00:00 committed by Kalle Valo
parent b7da53cd6c
commit e401fa25cf
9 changed files with 1373 additions and 5 deletions

View file

@ -5,7 +5,7 @@ config QTNFMAC
default y if QTNFMAC_PCIE=y
config QTNFMAC_PCIE
tristate "Quantenna QSR10g PCIe support"
tristate "Quantenna QSR1000/QSR2000/QSR10g PCIe support"
default n
depends on PCI && CFG80211
select QTNFMAC
@ -13,7 +13,8 @@ config QTNFMAC_PCIE
select CRC32
help
This option adds support for wireless adapters based on Quantenna
802.11ac QSR10g (aka Pearl) FullMAC chipset running over PCIe.
802.11ac QSR10g (aka Pearl) and QSR1000/QSR2000 (aka Topaz)
FullMAC chipsets running over PCIe.
If you choose to build it as a module, two modules will be built:
qtnfmac.ko and qtnfmac_pcie.ko.

View file

@ -24,6 +24,7 @@ obj-$(CONFIG_QTNFMAC_PCIE) += qtnfmac_pcie.o
qtnfmac_pcie-objs += \
shm_ipc.o \
pcie/pcie.o \
pcie/pearl_pcie.o
pcie/pearl_pcie.o \
pcie/topaz_pcie.o
qtnfmac_pcie-$(CONFIG_DEBUG_FS) += debug.o

View file

@ -330,6 +330,9 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
case QTN_CHIP_ID_PEARL_C:
bus = qtnf_pcie_pearl_alloc(pdev);
break;
case QTN_CHIP_ID_TOPAZ:
bus = qtnf_pcie_topaz_alloc(pdev);
break;
default:
pr_err("unsupported chip ID 0x%x\n", chipid);
return -ENOTSUPP;
@ -465,7 +468,7 @@ static SIMPLE_DEV_PM_OPS(qtnf_pcie_pm_ops, qtnf_pcie_suspend,
static const struct pci_device_id qtnf_pcie_devid_table[] = {
{
PCIE_VENDOR_ID_QUANTENNA, PCIE_DEVICE_ID_QTN_PEARL,
PCIE_VENDOR_ID_QUANTENNA, PCIE_DEVICE_ID_QSR,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
},
{ },

View file

@ -76,6 +76,7 @@ void qtnf_pcie_init_shm_ipc(struct qtnf_pcie_bus_priv *priv,
struct qtnf_shm_ipc_region __iomem *ipc_rx_reg,
const struct qtnf_shm_ipc_int *ipc_int);
struct qtnf_bus *qtnf_pcie_pearl_alloc(struct pci_dev *pdev);
struct qtnf_bus *qtnf_pcie_topaz_alloc(struct pci_dev *pdev);
static inline void qtnf_non_posted_write(u32 val, void __iomem *basereg)
{

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,94 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2018 Quantenna Communications */
#ifndef _QTN_FMAC_PCIE_IPC_H_
#define _QTN_FMAC_PCIE_IPC_H_
#include <linux/types.h>
#include "shm_ipc_defs.h"
/* EP/RC status and flags */
#define QTN_BDA_PCIE_INIT 0x01
#define QTN_BDA_PCIE_RDY 0x02
#define QTN_BDA_FW_LOAD_RDY 0x03
#define QTN_BDA_FW_LOAD_DONE 0x04
#define QTN_BDA_FW_START 0x05
#define QTN_BDA_FW_RUN 0x06
#define QTN_BDA_FW_HOST_RDY 0x07
#define QTN_BDA_FW_TARGET_RDY 0x11
#define QTN_BDA_FW_TARGET_BOOT 0x12
#define QTN_BDA_FW_FLASH_BOOT 0x13
#define QTN_BDA_FW_QLINK_DONE 0x14
#define QTN_BDA_FW_HOST_LOAD 0x08
#define QTN_BDA_FW_BLOCK_DONE 0x09
#define QTN_BDA_FW_BLOCK_RDY 0x0A
#define QTN_BDA_FW_EP_RDY 0x0B
#define QTN_BDA_FW_BLOCK_END 0x0C
#define QTN_BDA_FW_CONFIG 0x0D
#define QTN_BDA_FW_RUNNING 0x0E
#define QTN_BDA_PCIE_FAIL 0x82
#define QTN_BDA_FW_LOAD_FAIL 0x85
#define QTN_BDA_RCMODE BIT(1)
#define QTN_BDA_MSI BIT(2)
#define QTN_BDA_HOST_CALCMD BIT(3)
#define QTN_BDA_FLASH_PRESENT BIT(4)
#define QTN_BDA_FLASH_BOOT BIT(5)
#define QTN_BDA_XMIT_UBOOT BIT(6)
#define QTN_BDA_HOST_QLINK_DRV BIT(7)
#define QTN_BDA_TARGET_FBOOT_ERR BIT(8)
#define QTN_BDA_TARGET_FWLOAD_ERR BIT(9)
#define QTN_BDA_HOST_NOFW_ERR BIT(12)
#define QTN_BDA_HOST_MEMALLOC_ERR BIT(13)
#define QTN_BDA_HOST_MEMMAP_ERR BIT(14)
#define QTN_BDA_VER(x) (((x) >> 4) & 0xFF)
#define QTN_BDA_ERROR_MASK 0xFF00
/* registers and shmem address macros */
#if BITS_PER_LONG == 64
#define QTN_HOST_HI32(a) ((u32)(((u64)a) >> 32))
#define QTN_HOST_LO32(a) ((u32)(((u64)a) & 0xffffffffUL))
#define QTN_HOST_ADDR(h, l) ((((u64)h) << 32) | ((u64)l))
#elif BITS_PER_LONG == 32
#define QTN_HOST_HI32(a) 0
#define QTN_HOST_LO32(a) ((u32)(((u32)a) & 0xffffffffUL))
#define QTN_HOST_ADDR(h, l) ((u32)l)
#else
#error Unexpected BITS_PER_LONG value
#endif
#define QTN_PCIE_BDA_VERSION 0x1001
#define PCIE_BDA_NAMELEN 32
#define QTN_PCIE_RC_TX_QUEUE_LEN 256
#define QTN_PCIE_TX_VALID_PKT 0x80000000
#define QTN_PCIE_PKT_LEN_MASK 0xffff
#define QTN_BD_EMPTY ((uint32_t)0x00000001)
#define QTN_BD_WRAP ((uint32_t)0x00000002)
#define QTN_BD_MASK_LEN ((uint32_t)0xFFFF0000)
#define QTN_BD_MASK_OFFSET ((uint32_t)0x0000FF00)
#define QTN_GET_LEN(x) (((x) >> 16) & 0xFFFF)
#define QTN_GET_OFFSET(x) (((x) >> 8) & 0xFF)
#define QTN_SET_LEN(len) (((len) & 0xFFFF) << 16)
#define QTN_SET_OFFSET(of) (((of) & 0xFF) << 8)
#define RX_DONE_INTR_MSK ((0x1 << 6) - 1)
#define PCIE_DMA_OFFSET_ERROR 0xFFFF
#define PCIE_DMA_OFFSET_ERROR_MASK 0xFFFF
#define QTN_PCI_ENDIAN_DETECT_DATA 0x12345678
#define QTN_PCI_ENDIAN_REVERSE_DATA 0x78563412
#define QTN_PCI_ENDIAN_VALID_STATUS 0x3c3c3c3c
#define QTN_PCI_ENDIAN_INVALID_STATUS 0
#define QTN_PCI_LITTLE_ENDIAN 0
#define QTN_PCI_BIG_ENDIAN 0xffffffff
#define NBLOCKS(size, blksize) \
((size) / (blksize) + (((size) % (blksize) > 0) ? 1 : 0))
#endif /* _QTN_FMAC_PCIE_IPC_H_ */

View file

@ -0,0 +1,45 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2018 Quantenna Communications */
#ifndef __TOPAZ_PCIE_H
#define __TOPAZ_PCIE_H
/* Topaz PCIe DMA registers */
#define PCIE_DMA_WR_INTR_STATUS(base) ((base) + 0x9bc)
#define PCIE_DMA_WR_INTR_MASK(base) ((base) + 0x9c4)
#define PCIE_DMA_WR_INTR_CLR(base) ((base) + 0x9c8)
#define PCIE_DMA_WR_ERR_STATUS(base) ((base) + 0x9cc)
#define PCIE_DMA_WR_DONE_IMWR_ADDR_LOW(base) ((base) + 0x9D0)
#define PCIE_DMA_WR_DONE_IMWR_ADDR_HIGH(base) ((base) + 0x9d4)
#define PCIE_DMA_RD_INTR_STATUS(base) ((base) + 0x310)
#define PCIE_DMA_RD_INTR_MASK(base) ((base) + 0x319)
#define PCIE_DMA_RD_INTR_CLR(base) ((base) + 0x31c)
#define PCIE_DMA_RD_ERR_STATUS_LOW(base) ((base) + 0x324)
#define PCIE_DMA_RD_ERR_STATUS_HIGH(base) ((base) + 0x328)
#define PCIE_DMA_RD_DONE_IMWR_ADDR_LOW(base) ((base) + 0x33c)
#define PCIE_DMA_RD_DONE_IMWR_ADDR_HIGH(base) ((base) + 0x340)
/* Topaz LHost IPC4 interrupt */
#define TOPAZ_LH_IPC4_INT(base) ((base) + 0x13C)
#define TOPAZ_LH_IPC4_INT_MASK(base) ((base) + 0x140)
#define TOPAZ_RC_TX_DONE_IRQ (0)
#define TOPAZ_RC_RST_EP_IRQ (1)
#define TOPAZ_RC_TX_STOP_IRQ (2)
#define TOPAZ_RC_RX_DONE_IRQ (3)
#define TOPAZ_RC_PM_EP_IRQ (4)
/* Topaz LHost M2L interrupt */
#define TOPAZ_CTL_M2L_INT(base) ((base) + 0x2C)
#define TOPAZ_CTL_M2L_INT_MASK(base) ((base) + 0x30)
#define TOPAZ_RC_CTRL_IRQ (6)
#define TOPAZ_IPC_IRQ_WORD(irq) (BIT(irq) | BIT(irq + 16))
/* PCIe legacy INTx */
#define TOPAZ_PCIE_CFG0_OFFSET (0x6C)
#define TOPAZ_ASSERT_INTX BIT(9)
#endif /* __TOPAZ_PCIE_H */

View file

@ -23,7 +23,7 @@
/* PCIE Device IDs */
#define PCIE_DEVICE_ID_QTN_PEARL (0x0008)
#define PCIE_DEVICE_ID_QSR (0x0008)
#define QTN_REG_SYS_CTRL_CSR 0x14
#define QTN_CHIP_ID_MASK 0xF0
@ -35,6 +35,8 @@
/* FW names */
#define QTN_PCI_PEARL_FW_NAME "qtn/fmac_qsr10g.img"
#define QTN_PCI_TOPAZ_FW_NAME "qtn/fmac_qsr1000.img"
#define QTN_PCI_TOPAZ_BOOTLD_NAME "qtn/uboot_qsr1000.img"
static inline unsigned int qtnf_chip_id_get(const void __iomem *regs_base)
{

View file

@ -121,6 +121,8 @@ void qtnf_sta_list_free(struct qtnf_sta_list *list)
const char *qtnf_chipid_to_string(unsigned long chip_id)
{
switch (chip_id) {
case QTN_CHIP_ID_TOPAZ:
return "Topaz";
case QTN_CHIP_ID_PEARL:
return "Pearl revA";
case QTN_CHIP_ID_PEARL_B: