xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/marvell/mwifiex/pcie.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* @file mwifiex_pcie.h
2*4882a593Smuzhiyun  *
3*4882a593Smuzhiyun  * @brief This file contains definitions for PCI-E interface.
4*4882a593Smuzhiyun  * driver.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright 2011-2020 NXP
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * This software file (the "File") is distributed by NXP
9*4882a593Smuzhiyun  * under the terms of the GNU General Public License Version 2, June 1991
10*4882a593Smuzhiyun  * (the "License").  You may use, redistribute and/or modify this File in
11*4882a593Smuzhiyun  * accordance with the terms and conditions of the License, a copy of which
12*4882a593Smuzhiyun  * is available by writing to the Free Software Foundation, Inc.,
13*4882a593Smuzhiyun  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
14*4882a593Smuzhiyun  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
15*4882a593Smuzhiyun  *
16*4882a593Smuzhiyun  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
17*4882a593Smuzhiyun  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
18*4882a593Smuzhiyun  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
19*4882a593Smuzhiyun  * this warranty disclaimer.
20*4882a593Smuzhiyun  */
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #ifndef	_MWIFIEX_PCIE_H
23*4882a593Smuzhiyun #define	_MWIFIEX_PCIE_H
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #include    <linux/completion.h>
26*4882a593Smuzhiyun #include    <linux/pci.h>
27*4882a593Smuzhiyun #include    <linux/interrupt.h>
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun #include    "decl.h"
30*4882a593Smuzhiyun #include    "main.h"
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #define PCIE8766_DEFAULT_FW_NAME "mrvl/pcie8766_uapsta.bin"
33*4882a593Smuzhiyun #define PCIE8897_DEFAULT_FW_NAME "mrvl/pcie8897_uapsta.bin"
34*4882a593Smuzhiyun #define PCIE8897_A0_FW_NAME "mrvl/pcie8897_uapsta_a0.bin"
35*4882a593Smuzhiyun #define PCIE8897_B0_FW_NAME "mrvl/pcie8897_uapsta.bin"
36*4882a593Smuzhiyun #define PCIEUART8997_FW_NAME_V4 "mrvl/pcieuart8997_combo_v4.bin"
37*4882a593Smuzhiyun #define PCIEUSB8997_FW_NAME_V4 "mrvl/pcieusb8997_combo_v4.bin"
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #define PCIE_VENDOR_ID_MARVELL              (0x11ab)
40*4882a593Smuzhiyun #define PCIE_VENDOR_ID_V2_MARVELL           (0x1b4b)
41*4882a593Smuzhiyun #define PCIE_DEVICE_ID_MARVELL_88W8766P		(0x2b30)
42*4882a593Smuzhiyun #define PCIE_DEVICE_ID_MARVELL_88W8897		(0x2b38)
43*4882a593Smuzhiyun #define PCIE_DEVICE_ID_MARVELL_88W8997		(0x2b42)
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun #define PCIE8897_A0	0x1100
46*4882a593Smuzhiyun #define PCIE8897_B0	0x1200
47*4882a593Smuzhiyun #define PCIE8997_A0	0x10
48*4882a593Smuzhiyun #define PCIE8997_A1	0x11
49*4882a593Smuzhiyun #define CHIP_VER_PCIEUART	0x3
50*4882a593Smuzhiyun #define CHIP_MAGIC_VALUE	0x24
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun /* Constants for Buffer Descriptor (BD) rings */
53*4882a593Smuzhiyun #define MWIFIEX_MAX_TXRX_BD			0x20
54*4882a593Smuzhiyun #define MWIFIEX_TXBD_MASK			0x3F
55*4882a593Smuzhiyun #define MWIFIEX_RXBD_MASK			0x3F
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun #define MWIFIEX_MAX_EVT_BD			0x08
58*4882a593Smuzhiyun #define MWIFIEX_EVTBD_MASK			0x0f
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun /* PCIE INTERNAL REGISTERS */
61*4882a593Smuzhiyun #define PCIE_SCRATCH_0_REG				0xC10
62*4882a593Smuzhiyun #define PCIE_SCRATCH_1_REG				0xC14
63*4882a593Smuzhiyun #define PCIE_CPU_INT_EVENT				0xC18
64*4882a593Smuzhiyun #define PCIE_CPU_INT_STATUS				0xC1C
65*4882a593Smuzhiyun #define PCIE_HOST_INT_STATUS				0xC30
66*4882a593Smuzhiyun #define PCIE_HOST_INT_MASK				0xC34
67*4882a593Smuzhiyun #define PCIE_HOST_INT_STATUS_MASK			0xC3C
68*4882a593Smuzhiyun #define PCIE_SCRATCH_2_REG				0xC40
69*4882a593Smuzhiyun #define PCIE_SCRATCH_3_REG				0xC44
70*4882a593Smuzhiyun #define PCIE_SCRATCH_4_REG				0xCD0
71*4882a593Smuzhiyun #define PCIE_SCRATCH_5_REG				0xCD4
72*4882a593Smuzhiyun #define PCIE_SCRATCH_6_REG				0xCD8
73*4882a593Smuzhiyun #define PCIE_SCRATCH_7_REG				0xCDC
74*4882a593Smuzhiyun #define PCIE_SCRATCH_8_REG				0xCE0
75*4882a593Smuzhiyun #define PCIE_SCRATCH_9_REG				0xCE4
76*4882a593Smuzhiyun #define PCIE_SCRATCH_10_REG				0xCE8
77*4882a593Smuzhiyun #define PCIE_SCRATCH_11_REG				0xCEC
78*4882a593Smuzhiyun #define PCIE_SCRATCH_12_REG				0xCF0
79*4882a593Smuzhiyun #define PCIE_SCRATCH_13_REG				0xCF4
80*4882a593Smuzhiyun #define PCIE_SCRATCH_14_REG				0xCF8
81*4882a593Smuzhiyun #define PCIE_SCRATCH_15_REG				0xCFC
82*4882a593Smuzhiyun #define PCIE_RD_DATA_PTR_Q0_Q1                          0xC08C
83*4882a593Smuzhiyun #define PCIE_WR_DATA_PTR_Q0_Q1                          0xC05C
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun #define CPU_INTR_DNLD_RDY				BIT(0)
86*4882a593Smuzhiyun #define CPU_INTR_DOOR_BELL				BIT(1)
87*4882a593Smuzhiyun #define CPU_INTR_SLEEP_CFM_DONE			BIT(2)
88*4882a593Smuzhiyun #define CPU_INTR_RESET					BIT(3)
89*4882a593Smuzhiyun #define CPU_INTR_EVENT_DONE				BIT(5)
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun #define HOST_INTR_DNLD_DONE				BIT(0)
92*4882a593Smuzhiyun #define HOST_INTR_UPLD_RDY				BIT(1)
93*4882a593Smuzhiyun #define HOST_INTR_CMD_DONE				BIT(2)
94*4882a593Smuzhiyun #define HOST_INTR_EVENT_RDY				BIT(3)
95*4882a593Smuzhiyun #define HOST_INTR_MASK					(HOST_INTR_DNLD_DONE | \
96*4882a593Smuzhiyun 							 HOST_INTR_UPLD_RDY  | \
97*4882a593Smuzhiyun 							 HOST_INTR_CMD_DONE  | \
98*4882a593Smuzhiyun 							 HOST_INTR_EVENT_RDY)
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun #define MWIFIEX_BD_FLAG_ROLLOVER_IND			BIT(7)
101*4882a593Smuzhiyun #define MWIFIEX_BD_FLAG_FIRST_DESC			BIT(0)
102*4882a593Smuzhiyun #define MWIFIEX_BD_FLAG_LAST_DESC			BIT(1)
103*4882a593Smuzhiyun #define MWIFIEX_BD_FLAG_SOP				BIT(0)
104*4882a593Smuzhiyun #define MWIFIEX_BD_FLAG_EOP				BIT(1)
105*4882a593Smuzhiyun #define MWIFIEX_BD_FLAG_XS_SOP				BIT(2)
106*4882a593Smuzhiyun #define MWIFIEX_BD_FLAG_XS_EOP				BIT(3)
107*4882a593Smuzhiyun #define MWIFIEX_BD_FLAG_EVT_ROLLOVER_IND		BIT(7)
108*4882a593Smuzhiyun #define MWIFIEX_BD_FLAG_RX_ROLLOVER_IND			BIT(10)
109*4882a593Smuzhiyun #define MWIFIEX_BD_FLAG_TX_START_PTR			BIT(16)
110*4882a593Smuzhiyun #define MWIFIEX_BD_FLAG_TX_ROLLOVER_IND			BIT(26)
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun /* Max retry number of command write */
113*4882a593Smuzhiyun #define MAX_WRITE_IOMEM_RETRY				2
114*4882a593Smuzhiyun /* Define PCIE block size for firmware download */
115*4882a593Smuzhiyun #define MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD		256
116*4882a593Smuzhiyun /* FW awake cookie after FW ready */
117*4882a593Smuzhiyun #define FW_AWAKE_COOKIE						(0xAA55AA55)
118*4882a593Smuzhiyun #define MWIFIEX_DEF_SLEEP_COOKIE			0xBEEFBEEF
119*4882a593Smuzhiyun #define MWIFIEX_SLEEP_COOKIE_SIZE			4
120*4882a593Smuzhiyun #define MWIFIEX_MAX_DELAY_COUNT				100
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun #define MWIFIEX_PCIE_FLR_HAPPENS 0xFEDCBABA
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun struct mwifiex_pcie_card_reg {
125*4882a593Smuzhiyun 	u16 cmd_addr_lo;
126*4882a593Smuzhiyun 	u16 cmd_addr_hi;
127*4882a593Smuzhiyun 	u16 fw_status;
128*4882a593Smuzhiyun 	u16 cmd_size;
129*4882a593Smuzhiyun 	u16 cmdrsp_addr_lo;
130*4882a593Smuzhiyun 	u16 cmdrsp_addr_hi;
131*4882a593Smuzhiyun 	u16 tx_rdptr;
132*4882a593Smuzhiyun 	u16 tx_wrptr;
133*4882a593Smuzhiyun 	u16 rx_rdptr;
134*4882a593Smuzhiyun 	u16 rx_wrptr;
135*4882a593Smuzhiyun 	u16 evt_rdptr;
136*4882a593Smuzhiyun 	u16 evt_wrptr;
137*4882a593Smuzhiyun 	u16 drv_rdy;
138*4882a593Smuzhiyun 	u16 tx_start_ptr;
139*4882a593Smuzhiyun 	u32 tx_mask;
140*4882a593Smuzhiyun 	u32 tx_wrap_mask;
141*4882a593Smuzhiyun 	u32 rx_mask;
142*4882a593Smuzhiyun 	u32 rx_wrap_mask;
143*4882a593Smuzhiyun 	u32 tx_rollover_ind;
144*4882a593Smuzhiyun 	u32 rx_rollover_ind;
145*4882a593Smuzhiyun 	u32 evt_rollover_ind;
146*4882a593Smuzhiyun 	u8 ring_flag_sop;
147*4882a593Smuzhiyun 	u8 ring_flag_eop;
148*4882a593Smuzhiyun 	u8 ring_flag_xs_sop;
149*4882a593Smuzhiyun 	u8 ring_flag_xs_eop;
150*4882a593Smuzhiyun 	u32 ring_tx_start_ptr;
151*4882a593Smuzhiyun 	u8 pfu_enabled;
152*4882a593Smuzhiyun 	u8 sleep_cookie;
153*4882a593Smuzhiyun 	u16 fw_dump_ctrl;
154*4882a593Smuzhiyun 	u16 fw_dump_start;
155*4882a593Smuzhiyun 	u16 fw_dump_end;
156*4882a593Smuzhiyun 	u8 fw_dump_host_ready;
157*4882a593Smuzhiyun 	u8 fw_dump_read_done;
158*4882a593Smuzhiyun 	u8 msix_support;
159*4882a593Smuzhiyun };
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun struct mwifiex_pcie_device {
162*4882a593Smuzhiyun 	const struct mwifiex_pcie_card_reg *reg;
163*4882a593Smuzhiyun 	u16 blksz_fw_dl;
164*4882a593Smuzhiyun 	u16 tx_buf_size;
165*4882a593Smuzhiyun 	bool can_dump_fw;
166*4882a593Smuzhiyun 	struct memory_type_mapping *mem_type_mapping_tbl;
167*4882a593Smuzhiyun 	u8 num_mem_types;
168*4882a593Smuzhiyun 	bool can_ext_scan;
169*4882a593Smuzhiyun };
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun struct mwifiex_evt_buf_desc {
172*4882a593Smuzhiyun 	u64 paddr;
173*4882a593Smuzhiyun 	u16 len;
174*4882a593Smuzhiyun 	u16 flags;
175*4882a593Smuzhiyun } __packed;
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun struct mwifiex_pcie_buf_desc {
178*4882a593Smuzhiyun 	u64 paddr;
179*4882a593Smuzhiyun 	u16 len;
180*4882a593Smuzhiyun 	u16 flags;
181*4882a593Smuzhiyun } __packed;
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun struct mwifiex_pfu_buf_desc {
184*4882a593Smuzhiyun 	u16 flags;
185*4882a593Smuzhiyun 	u16 offset;
186*4882a593Smuzhiyun 	u16 frag_len;
187*4882a593Smuzhiyun 	u16 len;
188*4882a593Smuzhiyun 	u64 paddr;
189*4882a593Smuzhiyun 	u32 reserved;
190*4882a593Smuzhiyun } __packed;
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun #define MWIFIEX_NUM_MSIX_VECTORS   4
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun struct mwifiex_msix_context {
195*4882a593Smuzhiyun 	struct pci_dev *dev;
196*4882a593Smuzhiyun 	u16 msg_id;
197*4882a593Smuzhiyun };
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun struct pcie_service_card {
200*4882a593Smuzhiyun 	struct pci_dev *dev;
201*4882a593Smuzhiyun 	struct mwifiex_adapter *adapter;
202*4882a593Smuzhiyun 	struct mwifiex_pcie_device pcie;
203*4882a593Smuzhiyun 	struct completion fw_done;
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 	u8 txbd_flush;
206*4882a593Smuzhiyun 	u32 txbd_wrptr;
207*4882a593Smuzhiyun 	u32 txbd_rdptr;
208*4882a593Smuzhiyun 	u32 txbd_ring_size;
209*4882a593Smuzhiyun 	u8 *txbd_ring_vbase;
210*4882a593Smuzhiyun 	dma_addr_t txbd_ring_pbase;
211*4882a593Smuzhiyun 	void *txbd_ring[MWIFIEX_MAX_TXRX_BD];
212*4882a593Smuzhiyun 	struct sk_buff *tx_buf_list[MWIFIEX_MAX_TXRX_BD];
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 	u32 rxbd_wrptr;
215*4882a593Smuzhiyun 	u32 rxbd_rdptr;
216*4882a593Smuzhiyun 	u32 rxbd_ring_size;
217*4882a593Smuzhiyun 	u8 *rxbd_ring_vbase;
218*4882a593Smuzhiyun 	dma_addr_t rxbd_ring_pbase;
219*4882a593Smuzhiyun 	void *rxbd_ring[MWIFIEX_MAX_TXRX_BD];
220*4882a593Smuzhiyun 	struct sk_buff *rx_buf_list[MWIFIEX_MAX_TXRX_BD];
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	u32 evtbd_wrptr;
223*4882a593Smuzhiyun 	u32 evtbd_rdptr;
224*4882a593Smuzhiyun 	u32 evtbd_ring_size;
225*4882a593Smuzhiyun 	u8 *evtbd_ring_vbase;
226*4882a593Smuzhiyun 	dma_addr_t evtbd_ring_pbase;
227*4882a593Smuzhiyun 	void *evtbd_ring[MWIFIEX_MAX_EVT_BD];
228*4882a593Smuzhiyun 	struct sk_buff *evt_buf_list[MWIFIEX_MAX_EVT_BD];
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	struct sk_buff *cmd_buf;
231*4882a593Smuzhiyun 	struct sk_buff *cmdrsp_buf;
232*4882a593Smuzhiyun 	u8 *sleep_cookie_vbase;
233*4882a593Smuzhiyun 	dma_addr_t sleep_cookie_pbase;
234*4882a593Smuzhiyun 	void __iomem *pci_mmap;
235*4882a593Smuzhiyun 	void __iomem *pci_mmap1;
236*4882a593Smuzhiyun 	int msi_enable;
237*4882a593Smuzhiyun 	int msix_enable;
238*4882a593Smuzhiyun #ifdef CONFIG_PCI
239*4882a593Smuzhiyun 	struct msix_entry msix_entries[MWIFIEX_NUM_MSIX_VECTORS];
240*4882a593Smuzhiyun #endif
241*4882a593Smuzhiyun 	struct mwifiex_msix_context msix_ctx[MWIFIEX_NUM_MSIX_VECTORS];
242*4882a593Smuzhiyun 	struct mwifiex_msix_context share_irq_ctx;
243*4882a593Smuzhiyun 	struct work_struct work;
244*4882a593Smuzhiyun 	unsigned long work_flags;
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun 	bool pci_reset_ongoing;
247*4882a593Smuzhiyun };
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun static inline int
mwifiex_pcie_txbd_empty(struct pcie_service_card * card,u32 rdptr)250*4882a593Smuzhiyun mwifiex_pcie_txbd_empty(struct pcie_service_card *card, u32 rdptr)
251*4882a593Smuzhiyun {
252*4882a593Smuzhiyun 	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	switch (card->dev->device) {
255*4882a593Smuzhiyun 	case PCIE_DEVICE_ID_MARVELL_88W8766P:
256*4882a593Smuzhiyun 		if (((card->txbd_wrptr & reg->tx_mask) ==
257*4882a593Smuzhiyun 		     (rdptr & reg->tx_mask)) &&
258*4882a593Smuzhiyun 		    ((card->txbd_wrptr & reg->tx_rollover_ind) !=
259*4882a593Smuzhiyun 		     (rdptr & reg->tx_rollover_ind)))
260*4882a593Smuzhiyun 			return 1;
261*4882a593Smuzhiyun 		break;
262*4882a593Smuzhiyun 	case PCIE_DEVICE_ID_MARVELL_88W8897:
263*4882a593Smuzhiyun 	case PCIE_DEVICE_ID_MARVELL_88W8997:
264*4882a593Smuzhiyun 		if (((card->txbd_wrptr & reg->tx_mask) ==
265*4882a593Smuzhiyun 		     (rdptr & reg->tx_mask)) &&
266*4882a593Smuzhiyun 		    ((card->txbd_wrptr & reg->tx_rollover_ind) ==
267*4882a593Smuzhiyun 			(rdptr & reg->tx_rollover_ind)))
268*4882a593Smuzhiyun 			return 1;
269*4882a593Smuzhiyun 		break;
270*4882a593Smuzhiyun 	}
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	return 0;
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun static inline int
mwifiex_pcie_txbd_not_full(struct pcie_service_card * card)276*4882a593Smuzhiyun mwifiex_pcie_txbd_not_full(struct pcie_service_card *card)
277*4882a593Smuzhiyun {
278*4882a593Smuzhiyun 	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	switch (card->dev->device) {
281*4882a593Smuzhiyun 	case PCIE_DEVICE_ID_MARVELL_88W8766P:
282*4882a593Smuzhiyun 		if (((card->txbd_wrptr & reg->tx_mask) !=
283*4882a593Smuzhiyun 		     (card->txbd_rdptr & reg->tx_mask)) ||
284*4882a593Smuzhiyun 		    ((card->txbd_wrptr & reg->tx_rollover_ind) !=
285*4882a593Smuzhiyun 		     (card->txbd_rdptr & reg->tx_rollover_ind)))
286*4882a593Smuzhiyun 			return 1;
287*4882a593Smuzhiyun 		break;
288*4882a593Smuzhiyun 	case PCIE_DEVICE_ID_MARVELL_88W8897:
289*4882a593Smuzhiyun 	case PCIE_DEVICE_ID_MARVELL_88W8997:
290*4882a593Smuzhiyun 		if (((card->txbd_wrptr & reg->tx_mask) !=
291*4882a593Smuzhiyun 		     (card->txbd_rdptr & reg->tx_mask)) ||
292*4882a593Smuzhiyun 		    ((card->txbd_wrptr & reg->tx_rollover_ind) ==
293*4882a593Smuzhiyun 		     (card->txbd_rdptr & reg->tx_rollover_ind)))
294*4882a593Smuzhiyun 			return 1;
295*4882a593Smuzhiyun 		break;
296*4882a593Smuzhiyun 	}
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 	return 0;
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun #endif /* _MWIFIEX_PCIE_H */
302