162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
262306a36Sopenharmony_ci/* Copyright(c) 2018-2019  Realtek Corporation
362306a36Sopenharmony_ci */
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#ifndef __RTK_PCI_H_
662306a36Sopenharmony_ci#define __RTK_PCI_H_
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include "main.h"
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#define RTK_DEFAULT_TX_DESC_NUM 128
1162306a36Sopenharmony_ci#define RTK_BEQ_TX_DESC_NUM	256
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#define RTK_MAX_RX_DESC_NUM	512
1462306a36Sopenharmony_ci/* 11K + rx desc size */
1562306a36Sopenharmony_ci#define RTK_PCI_RX_BUF_SIZE	(11454 + 24)
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#define RTK_PCI_CTRL		0x300
1862306a36Sopenharmony_ci#define BIT_RST_TRXDMA_INTF	BIT(20)
1962306a36Sopenharmony_ci#define BIT_RX_TAG_EN		BIT(15)
2062306a36Sopenharmony_ci#define REG_DBI_WDATA_V1	0x03E8
2162306a36Sopenharmony_ci#define REG_DBI_RDATA_V1	0x03EC
2262306a36Sopenharmony_ci#define REG_DBI_FLAG_V1		0x03F0
2362306a36Sopenharmony_ci#define BIT_DBI_RFLAG		BIT(17)
2462306a36Sopenharmony_ci#define BIT_DBI_WFLAG		BIT(16)
2562306a36Sopenharmony_ci#define BITS_DBI_WREN		GENMASK(15, 12)
2662306a36Sopenharmony_ci#define BITS_DBI_ADDR_MASK	GENMASK(11, 2)
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci#define REG_MDIO_V1		0x03F4
2962306a36Sopenharmony_ci#define REG_PCIE_MIX_CFG	0x03F8
3062306a36Sopenharmony_ci#define BITS_MDIO_ADDR_MASK	GENMASK(4, 0)
3162306a36Sopenharmony_ci#define BIT_MDIO_WFLAG_V1	BIT(5)
3262306a36Sopenharmony_ci#define RTW_PCI_MDIO_PG_SZ	BIT(5)
3362306a36Sopenharmony_ci#define RTW_PCI_MDIO_PG_OFFS_G1	0
3462306a36Sopenharmony_ci#define RTW_PCI_MDIO_PG_OFFS_G2	2
3562306a36Sopenharmony_ci#define RTW_PCI_WR_RETRY_CNT	20
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#define RTK_PCIE_LINK_CFG	0x0719
3862306a36Sopenharmony_ci#define BIT_CLKREQ_SW_EN	BIT(4)
3962306a36Sopenharmony_ci#define BIT_L1_SW_EN		BIT(3)
4062306a36Sopenharmony_ci#define BIT_CLKREQ_N_PAD	BIT(0)
4162306a36Sopenharmony_ci#define RTK_PCIE_CLKDLY_CTRL	0x0725
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci#define BIT_PCI_BCNQ_FLAG	BIT(4)
4462306a36Sopenharmony_ci#define RTK_PCI_TXBD_DESA_BCNQ	0x308
4562306a36Sopenharmony_ci#define RTK_PCI_TXBD_DESA_H2CQ	0x1320
4662306a36Sopenharmony_ci#define RTK_PCI_TXBD_DESA_MGMTQ	0x310
4762306a36Sopenharmony_ci#define RTK_PCI_TXBD_DESA_BKQ	0x330
4862306a36Sopenharmony_ci#define RTK_PCI_TXBD_DESA_BEQ	0x328
4962306a36Sopenharmony_ci#define RTK_PCI_TXBD_DESA_VIQ	0x320
5062306a36Sopenharmony_ci#define RTK_PCI_TXBD_DESA_VOQ	0x318
5162306a36Sopenharmony_ci#define RTK_PCI_TXBD_DESA_HI0Q	0x340
5262306a36Sopenharmony_ci#define RTK_PCI_RXBD_DESA_MPDUQ	0x338
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci#define TRX_BD_IDX_MASK		GENMASK(11, 0)
5562306a36Sopenharmony_ci#define TRX_BD_HW_IDX_MASK	GENMASK(27, 16)
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci/* BCNQ is specialized for rsvd page, does not need to specify a number */
5862306a36Sopenharmony_ci#define RTK_PCI_TXBD_NUM_H2CQ	0x1328
5962306a36Sopenharmony_ci#define RTK_PCI_TXBD_NUM_MGMTQ	0x380
6062306a36Sopenharmony_ci#define RTK_PCI_TXBD_NUM_BKQ	0x38A
6162306a36Sopenharmony_ci#define RTK_PCI_TXBD_NUM_BEQ	0x388
6262306a36Sopenharmony_ci#define RTK_PCI_TXBD_NUM_VIQ	0x386
6362306a36Sopenharmony_ci#define RTK_PCI_TXBD_NUM_VOQ	0x384
6462306a36Sopenharmony_ci#define RTK_PCI_TXBD_NUM_HI0Q	0x38C
6562306a36Sopenharmony_ci#define RTK_PCI_RXBD_NUM_MPDUQ	0x382
6662306a36Sopenharmony_ci#define RTK_PCI_TXBD_IDX_H2CQ	0x132C
6762306a36Sopenharmony_ci#define RTK_PCI_TXBD_IDX_MGMTQ	0x3B0
6862306a36Sopenharmony_ci#define RTK_PCI_TXBD_IDX_BKQ	0x3AC
6962306a36Sopenharmony_ci#define RTK_PCI_TXBD_IDX_BEQ	0x3A8
7062306a36Sopenharmony_ci#define RTK_PCI_TXBD_IDX_VIQ	0x3A4
7162306a36Sopenharmony_ci#define RTK_PCI_TXBD_IDX_VOQ	0x3A0
7262306a36Sopenharmony_ci#define RTK_PCI_TXBD_IDX_HI0Q	0x3B8
7362306a36Sopenharmony_ci#define RTK_PCI_RXBD_IDX_MPDUQ	0x3B4
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci#define RTK_PCI_TXBD_RWPTR_CLR	0x39C
7662306a36Sopenharmony_ci#define RTK_PCI_TXBD_H2CQ_CSR	0x1330
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci#define BIT_CLR_H2CQ_HOST_IDX	BIT(16)
7962306a36Sopenharmony_ci#define BIT_CLR_H2CQ_HW_IDX	BIT(8)
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci#define RTK_PCI_HIMR0		0x0B0
8262306a36Sopenharmony_ci#define RTK_PCI_HISR0		0x0B4
8362306a36Sopenharmony_ci#define RTK_PCI_HIMR1		0x0B8
8462306a36Sopenharmony_ci#define RTK_PCI_HISR1		0x0BC
8562306a36Sopenharmony_ci#define RTK_PCI_HIMR2		0x10B0
8662306a36Sopenharmony_ci#define RTK_PCI_HISR2		0x10B4
8762306a36Sopenharmony_ci#define RTK_PCI_HIMR3		0x10B8
8862306a36Sopenharmony_ci#define RTK_PCI_HISR3		0x10BC
8962306a36Sopenharmony_ci/* IMR 0 */
9062306a36Sopenharmony_ci#define IMR_TIMER2		BIT(31)
9162306a36Sopenharmony_ci#define IMR_TIMER1		BIT(30)
9262306a36Sopenharmony_ci#define IMR_PSTIMEOUT		BIT(29)
9362306a36Sopenharmony_ci#define IMR_GTINT4		BIT(28)
9462306a36Sopenharmony_ci#define IMR_GTINT3		BIT(27)
9562306a36Sopenharmony_ci#define IMR_TBDER		BIT(26)
9662306a36Sopenharmony_ci#define IMR_TBDOK		BIT(25)
9762306a36Sopenharmony_ci#define IMR_TSF_BIT32_TOGGLE	BIT(24)
9862306a36Sopenharmony_ci#define IMR_BCNDMAINT0		BIT(20)
9962306a36Sopenharmony_ci#define IMR_BCNDOK0		BIT(16)
10062306a36Sopenharmony_ci#define IMR_HSISR_IND_ON_INT	BIT(15)
10162306a36Sopenharmony_ci#define IMR_BCNDMAINT_E		BIT(14)
10262306a36Sopenharmony_ci#define IMR_ATIMEND		BIT(12)
10362306a36Sopenharmony_ci#define IMR_HISR1_IND_INT	BIT(11)
10462306a36Sopenharmony_ci#define IMR_C2HCMD		BIT(10)
10562306a36Sopenharmony_ci#define IMR_CPWM2		BIT(9)
10662306a36Sopenharmony_ci#define IMR_CPWM		BIT(8)
10762306a36Sopenharmony_ci#define IMR_HIGHDOK		BIT(7)
10862306a36Sopenharmony_ci#define IMR_MGNTDOK		BIT(6)
10962306a36Sopenharmony_ci#define IMR_BKDOK		BIT(5)
11062306a36Sopenharmony_ci#define IMR_BEDOK		BIT(4)
11162306a36Sopenharmony_ci#define IMR_VIDOK		BIT(3)
11262306a36Sopenharmony_ci#define IMR_VODOK		BIT(2)
11362306a36Sopenharmony_ci#define IMR_RDU			BIT(1)
11462306a36Sopenharmony_ci#define IMR_ROK			BIT(0)
11562306a36Sopenharmony_ci/* IMR 1 */
11662306a36Sopenharmony_ci#define IMR_TXFIFO_TH_INT	BIT(30)
11762306a36Sopenharmony_ci#define IMR_BTON_STS_UPDATE	BIT(29)
11862306a36Sopenharmony_ci#define IMR_MCUERR		BIT(28)
11962306a36Sopenharmony_ci#define IMR_BCNDMAINT7		BIT(27)
12062306a36Sopenharmony_ci#define IMR_BCNDMAINT6		BIT(26)
12162306a36Sopenharmony_ci#define IMR_BCNDMAINT5		BIT(25)
12262306a36Sopenharmony_ci#define IMR_BCNDMAINT4		BIT(24)
12362306a36Sopenharmony_ci#define IMR_BCNDMAINT3		BIT(23)
12462306a36Sopenharmony_ci#define IMR_BCNDMAINT2		BIT(22)
12562306a36Sopenharmony_ci#define IMR_BCNDMAINT1		BIT(21)
12662306a36Sopenharmony_ci#define IMR_BCNDOK7		BIT(20)
12762306a36Sopenharmony_ci#define IMR_BCNDOK6		BIT(19)
12862306a36Sopenharmony_ci#define IMR_BCNDOK5		BIT(18)
12962306a36Sopenharmony_ci#define IMR_BCNDOK4		BIT(17)
13062306a36Sopenharmony_ci#define IMR_BCNDOK3		BIT(16)
13162306a36Sopenharmony_ci#define IMR_BCNDOK2		BIT(15)
13262306a36Sopenharmony_ci#define IMR_BCNDOK1		BIT(14)
13362306a36Sopenharmony_ci#define IMR_ATIMEND_E		BIT(13)
13462306a36Sopenharmony_ci#define IMR_ATIMEND		BIT(12)
13562306a36Sopenharmony_ci#define IMR_TXERR		BIT(11)
13662306a36Sopenharmony_ci#define IMR_RXERR		BIT(10)
13762306a36Sopenharmony_ci#define IMR_TXFOVW		BIT(9)
13862306a36Sopenharmony_ci#define IMR_RXFOVW		BIT(8)
13962306a36Sopenharmony_ci#define IMR_CPU_MGQ_TXDONE	BIT(5)
14062306a36Sopenharmony_ci#define IMR_PS_TIMER_C		BIT(4)
14162306a36Sopenharmony_ci#define IMR_PS_TIMER_B		BIT(3)
14262306a36Sopenharmony_ci#define IMR_PS_TIMER_A		BIT(2)
14362306a36Sopenharmony_ci#define IMR_CPUMGQ_TX_TIMER	BIT(1)
14462306a36Sopenharmony_ci/* IMR 3 */
14562306a36Sopenharmony_ci#define IMR_H2CDOK		BIT(16)
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_cienum rtw_pci_flags {
14862306a36Sopenharmony_ci	RTW_PCI_FLAG_NAPI_RUNNING,
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci	NUM_OF_RTW_PCI_FLAGS,
15162306a36Sopenharmony_ci};
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci/* one element is reserved to know if the ring is closed */
15462306a36Sopenharmony_cistatic inline int avail_desc(u32 wp, u32 rp, u32 len)
15562306a36Sopenharmony_ci{
15662306a36Sopenharmony_ci	if (rp > wp)
15762306a36Sopenharmony_ci		return rp - wp - 1;
15862306a36Sopenharmony_ci	else
15962306a36Sopenharmony_ci		return len - wp + rp - 1;
16062306a36Sopenharmony_ci}
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci#define RTK_PCI_TXBD_OWN_OFFSET 15
16362306a36Sopenharmony_ci#define RTK_PCI_TXBD_BCN_WORK	0x383
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_cistruct rtw_pci_tx_buffer_desc {
16662306a36Sopenharmony_ci	__le16 buf_size;
16762306a36Sopenharmony_ci	__le16 psb_len;
16862306a36Sopenharmony_ci	__le32 dma;
16962306a36Sopenharmony_ci};
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_cistruct rtw_pci_tx_data {
17262306a36Sopenharmony_ci	dma_addr_t dma;
17362306a36Sopenharmony_ci	u8 sn;
17462306a36Sopenharmony_ci};
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_cistruct rtw_pci_ring {
17762306a36Sopenharmony_ci	u8 *head;
17862306a36Sopenharmony_ci	dma_addr_t dma;
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci	u8 desc_size;
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci	u32 len;
18362306a36Sopenharmony_ci	u32 wp;
18462306a36Sopenharmony_ci	u32 rp;
18562306a36Sopenharmony_ci};
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_cistruct rtw_pci_tx_ring {
18862306a36Sopenharmony_ci	struct rtw_pci_ring r;
18962306a36Sopenharmony_ci	struct sk_buff_head queue;
19062306a36Sopenharmony_ci	bool queue_stopped;
19162306a36Sopenharmony_ci};
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_cistruct rtw_pci_rx_buffer_desc {
19462306a36Sopenharmony_ci	__le16 buf_size;
19562306a36Sopenharmony_ci	__le16 total_pkt_size;
19662306a36Sopenharmony_ci	__le32 dma;
19762306a36Sopenharmony_ci};
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_cistruct rtw_pci_rx_ring {
20062306a36Sopenharmony_ci	struct rtw_pci_ring r;
20162306a36Sopenharmony_ci	struct sk_buff *buf[RTK_MAX_RX_DESC_NUM];
20262306a36Sopenharmony_ci};
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci#define RX_TAG_MAX	8192
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_cistruct rtw_pci {
20762306a36Sopenharmony_ci	struct pci_dev *pdev;
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci	/* Used for PCI interrupt. */
21062306a36Sopenharmony_ci	spinlock_t hwirq_lock;
21162306a36Sopenharmony_ci	/* Used for PCI TX ring/queueing, and enable INT. */
21262306a36Sopenharmony_ci	spinlock_t irq_lock;
21362306a36Sopenharmony_ci	u32 irq_mask[4];
21462306a36Sopenharmony_ci	bool irq_enabled;
21562306a36Sopenharmony_ci	bool running;
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci	/* napi structure */
21862306a36Sopenharmony_ci	struct net_device netdev;
21962306a36Sopenharmony_ci	struct napi_struct napi;
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci	u16 rx_tag;
22262306a36Sopenharmony_ci	DECLARE_BITMAP(tx_queued, RTK_MAX_TX_QUEUE_NUM);
22362306a36Sopenharmony_ci	struct rtw_pci_tx_ring tx_rings[RTK_MAX_TX_QUEUE_NUM];
22462306a36Sopenharmony_ci	struct rtw_pci_rx_ring rx_rings[RTK_MAX_RX_QUEUE_NUM];
22562306a36Sopenharmony_ci	u16 link_ctrl;
22662306a36Sopenharmony_ci	atomic_t link_usage;
22762306a36Sopenharmony_ci	bool rx_no_aspm;
22862306a36Sopenharmony_ci	DECLARE_BITMAP(flags, NUM_OF_RTW_PCI_FLAGS);
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	void __iomem *mmap;
23162306a36Sopenharmony_ci};
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ciextern const struct dev_pm_ops rtw_pm_ops;
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ciint rtw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id);
23662306a36Sopenharmony_civoid rtw_pci_remove(struct pci_dev *pdev);
23762306a36Sopenharmony_civoid rtw_pci_shutdown(struct pci_dev *pdev);
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_cistatic inline u32 max_num_of_tx_queue(u8 queue)
24062306a36Sopenharmony_ci{
24162306a36Sopenharmony_ci	u32 max_num;
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci	switch (queue) {
24462306a36Sopenharmony_ci	case RTW_TX_QUEUE_BE:
24562306a36Sopenharmony_ci		max_num = RTK_BEQ_TX_DESC_NUM;
24662306a36Sopenharmony_ci		break;
24762306a36Sopenharmony_ci	case RTW_TX_QUEUE_BCN:
24862306a36Sopenharmony_ci		max_num = 1;
24962306a36Sopenharmony_ci		break;
25062306a36Sopenharmony_ci	default:
25162306a36Sopenharmony_ci		max_num = RTK_DEFAULT_TX_DESC_NUM;
25262306a36Sopenharmony_ci		break;
25362306a36Sopenharmony_ci	}
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	return max_num;
25662306a36Sopenharmony_ci}
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_cistatic inline struct
25962306a36Sopenharmony_cirtw_pci_tx_data *rtw_pci_get_tx_data(struct sk_buff *skb)
26062306a36Sopenharmony_ci{
26162306a36Sopenharmony_ci	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	BUILD_BUG_ON(sizeof(struct rtw_pci_tx_data) >
26462306a36Sopenharmony_ci		     sizeof(info->status.status_driver_data));
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci	return (struct rtw_pci_tx_data *)info->status.status_driver_data;
26762306a36Sopenharmony_ci}
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_cistatic inline
27062306a36Sopenharmony_cistruct rtw_pci_tx_buffer_desc *get_tx_buffer_desc(struct rtw_pci_tx_ring *ring,
27162306a36Sopenharmony_ci						  u32 size)
27262306a36Sopenharmony_ci{
27362306a36Sopenharmony_ci	u8 *buf_desc;
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	buf_desc = ring->r.head + ring->r.wp * size;
27662306a36Sopenharmony_ci	return (struct rtw_pci_tx_buffer_desc *)buf_desc;
27762306a36Sopenharmony_ci}
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci#endif
280