xref: /OK3568_Linux_fs/kernel/drivers/net/ethernet/sfc/falcon/io.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /****************************************************************************
3*4882a593Smuzhiyun  * Driver for Solarflare network controllers and boards
4*4882a593Smuzhiyun  * Copyright 2005-2006 Fen Systems Ltd.
5*4882a593Smuzhiyun  * Copyright 2006-2013 Solarflare Communications Inc.
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #ifndef EF4_IO_H
9*4882a593Smuzhiyun #define EF4_IO_H
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include <linux/io.h>
12*4882a593Smuzhiyun #include <linux/spinlock.h>
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun /**************************************************************************
15*4882a593Smuzhiyun  *
16*4882a593Smuzhiyun  * NIC register I/O
17*4882a593Smuzhiyun  *
18*4882a593Smuzhiyun  **************************************************************************
19*4882a593Smuzhiyun  *
20*4882a593Smuzhiyun  * Notes on locking strategy for the Falcon architecture:
21*4882a593Smuzhiyun  *
22*4882a593Smuzhiyun  * Many CSRs are very wide and cannot be read or written atomically.
23*4882a593Smuzhiyun  * Writes from the host are buffered by the Bus Interface Unit (BIU)
24*4882a593Smuzhiyun  * up to 128 bits.  Whenever the host writes part of such a register,
25*4882a593Smuzhiyun  * the BIU collects the written value and does not write to the
26*4882a593Smuzhiyun  * underlying register until all 4 dwords have been written.  A
27*4882a593Smuzhiyun  * similar buffering scheme applies to host access to the NIC's 64-bit
28*4882a593Smuzhiyun  * SRAM.
29*4882a593Smuzhiyun  *
30*4882a593Smuzhiyun  * Writes to different CSRs and 64-bit SRAM words must be serialised,
31*4882a593Smuzhiyun  * since interleaved access can result in lost writes.  We use
32*4882a593Smuzhiyun  * ef4_nic::biu_lock for this.
33*4882a593Smuzhiyun  *
34*4882a593Smuzhiyun  * We also serialise reads from 128-bit CSRs and SRAM with the same
35*4882a593Smuzhiyun  * spinlock.  This may not be necessary, but it doesn't really matter
36*4882a593Smuzhiyun  * as there are no such reads on the fast path.
37*4882a593Smuzhiyun  *
38*4882a593Smuzhiyun  * The DMA descriptor pointers (RX_DESC_UPD and TX_DESC_UPD) are
39*4882a593Smuzhiyun  * 128-bit but are special-cased in the BIU to avoid the need for
40*4882a593Smuzhiyun  * locking in the host:
41*4882a593Smuzhiyun  *
42*4882a593Smuzhiyun  * - They are write-only.
43*4882a593Smuzhiyun  * - The semantics of writing to these registers are such that
44*4882a593Smuzhiyun  *   replacing the low 96 bits with zero does not affect functionality.
45*4882a593Smuzhiyun  * - If the host writes to the last dword address of such a register
46*4882a593Smuzhiyun  *   (i.e. the high 32 bits) the underlying register will always be
47*4882a593Smuzhiyun  *   written.  If the collector and the current write together do not
48*4882a593Smuzhiyun  *   provide values for all 128 bits of the register, the low 96 bits
49*4882a593Smuzhiyun  *   will be written as zero.
50*4882a593Smuzhiyun  * - If the host writes to the address of any other part of such a
51*4882a593Smuzhiyun  *   register while the collector already holds values for some other
52*4882a593Smuzhiyun  *   register, the write is discarded and the collector maintains its
53*4882a593Smuzhiyun  *   current state.
54*4882a593Smuzhiyun  *
55*4882a593Smuzhiyun  * The EF10 architecture exposes very few registers to the host and
56*4882a593Smuzhiyun  * most of them are only 32 bits wide.  The only exceptions are the MC
57*4882a593Smuzhiyun  * doorbell register pair, which has its own latching, and
58*4882a593Smuzhiyun  * TX_DESC_UPD, which works in a similar way to the Falcon
59*4882a593Smuzhiyun  * architecture.
60*4882a593Smuzhiyun  */
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun #if BITS_PER_LONG == 64
63*4882a593Smuzhiyun #define EF4_USE_QWORD_IO 1
64*4882a593Smuzhiyun #endif
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun #ifdef EF4_USE_QWORD_IO
_ef4_writeq(struct ef4_nic * efx,__le64 value,unsigned int reg)67*4882a593Smuzhiyun static inline void _ef4_writeq(struct ef4_nic *efx, __le64 value,
68*4882a593Smuzhiyun 				  unsigned int reg)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun 	__raw_writeq((__force u64)value, efx->membase + reg);
71*4882a593Smuzhiyun }
_ef4_readq(struct ef4_nic * efx,unsigned int reg)72*4882a593Smuzhiyun static inline __le64 _ef4_readq(struct ef4_nic *efx, unsigned int reg)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun 	return (__force __le64)__raw_readq(efx->membase + reg);
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun #endif
77*4882a593Smuzhiyun 
_ef4_writed(struct ef4_nic * efx,__le32 value,unsigned int reg)78*4882a593Smuzhiyun static inline void _ef4_writed(struct ef4_nic *efx, __le32 value,
79*4882a593Smuzhiyun 				  unsigned int reg)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun 	__raw_writel((__force u32)value, efx->membase + reg);
82*4882a593Smuzhiyun }
_ef4_readd(struct ef4_nic * efx,unsigned int reg)83*4882a593Smuzhiyun static inline __le32 _ef4_readd(struct ef4_nic *efx, unsigned int reg)
84*4882a593Smuzhiyun {
85*4882a593Smuzhiyun 	return (__force __le32)__raw_readl(efx->membase + reg);
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun /* Write a normal 128-bit CSR, locking as appropriate. */
ef4_writeo(struct ef4_nic * efx,const ef4_oword_t * value,unsigned int reg)89*4882a593Smuzhiyun static inline void ef4_writeo(struct ef4_nic *efx, const ef4_oword_t *value,
90*4882a593Smuzhiyun 			      unsigned int reg)
91*4882a593Smuzhiyun {
92*4882a593Smuzhiyun 	unsigned long flags __attribute__ ((unused));
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	netif_vdbg(efx, hw, efx->net_dev,
95*4882a593Smuzhiyun 		   "writing register %x with " EF4_OWORD_FMT "\n", reg,
96*4882a593Smuzhiyun 		   EF4_OWORD_VAL(*value));
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 	spin_lock_irqsave(&efx->biu_lock, flags);
99*4882a593Smuzhiyun #ifdef EF4_USE_QWORD_IO
100*4882a593Smuzhiyun 	_ef4_writeq(efx, value->u64[0], reg + 0);
101*4882a593Smuzhiyun 	_ef4_writeq(efx, value->u64[1], reg + 8);
102*4882a593Smuzhiyun #else
103*4882a593Smuzhiyun 	_ef4_writed(efx, value->u32[0], reg + 0);
104*4882a593Smuzhiyun 	_ef4_writed(efx, value->u32[1], reg + 4);
105*4882a593Smuzhiyun 	_ef4_writed(efx, value->u32[2], reg + 8);
106*4882a593Smuzhiyun 	_ef4_writed(efx, value->u32[3], reg + 12);
107*4882a593Smuzhiyun #endif
108*4882a593Smuzhiyun 	spin_unlock_irqrestore(&efx->biu_lock, flags);
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun /* Write 64-bit SRAM through the supplied mapping, locking as appropriate. */
ef4_sram_writeq(struct ef4_nic * efx,void __iomem * membase,const ef4_qword_t * value,unsigned int index)112*4882a593Smuzhiyun static inline void ef4_sram_writeq(struct ef4_nic *efx, void __iomem *membase,
113*4882a593Smuzhiyun 				   const ef4_qword_t *value, unsigned int index)
114*4882a593Smuzhiyun {
115*4882a593Smuzhiyun 	unsigned int addr = index * sizeof(*value);
116*4882a593Smuzhiyun 	unsigned long flags __attribute__ ((unused));
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 	netif_vdbg(efx, hw, efx->net_dev,
119*4882a593Smuzhiyun 		   "writing SRAM address %x with " EF4_QWORD_FMT "\n",
120*4882a593Smuzhiyun 		   addr, EF4_QWORD_VAL(*value));
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	spin_lock_irqsave(&efx->biu_lock, flags);
123*4882a593Smuzhiyun #ifdef EF4_USE_QWORD_IO
124*4882a593Smuzhiyun 	__raw_writeq((__force u64)value->u64[0], membase + addr);
125*4882a593Smuzhiyun #else
126*4882a593Smuzhiyun 	__raw_writel((__force u32)value->u32[0], membase + addr);
127*4882a593Smuzhiyun 	__raw_writel((__force u32)value->u32[1], membase + addr + 4);
128*4882a593Smuzhiyun #endif
129*4882a593Smuzhiyun 	spin_unlock_irqrestore(&efx->biu_lock, flags);
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun /* Write a 32-bit CSR or the last dword of a special 128-bit CSR */
ef4_writed(struct ef4_nic * efx,const ef4_dword_t * value,unsigned int reg)133*4882a593Smuzhiyun static inline void ef4_writed(struct ef4_nic *efx, const ef4_dword_t *value,
134*4882a593Smuzhiyun 			      unsigned int reg)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun 	netif_vdbg(efx, hw, efx->net_dev,
137*4882a593Smuzhiyun 		   "writing register %x with "EF4_DWORD_FMT"\n",
138*4882a593Smuzhiyun 		   reg, EF4_DWORD_VAL(*value));
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	/* No lock required */
141*4882a593Smuzhiyun 	_ef4_writed(efx, value->u32[0], reg);
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun /* Read a 128-bit CSR, locking as appropriate. */
ef4_reado(struct ef4_nic * efx,ef4_oword_t * value,unsigned int reg)145*4882a593Smuzhiyun static inline void ef4_reado(struct ef4_nic *efx, ef4_oword_t *value,
146*4882a593Smuzhiyun 			     unsigned int reg)
147*4882a593Smuzhiyun {
148*4882a593Smuzhiyun 	unsigned long flags __attribute__ ((unused));
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	spin_lock_irqsave(&efx->biu_lock, flags);
151*4882a593Smuzhiyun 	value->u32[0] = _ef4_readd(efx, reg + 0);
152*4882a593Smuzhiyun 	value->u32[1] = _ef4_readd(efx, reg + 4);
153*4882a593Smuzhiyun 	value->u32[2] = _ef4_readd(efx, reg + 8);
154*4882a593Smuzhiyun 	value->u32[3] = _ef4_readd(efx, reg + 12);
155*4882a593Smuzhiyun 	spin_unlock_irqrestore(&efx->biu_lock, flags);
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	netif_vdbg(efx, hw, efx->net_dev,
158*4882a593Smuzhiyun 		   "read from register %x, got " EF4_OWORD_FMT "\n", reg,
159*4882a593Smuzhiyun 		   EF4_OWORD_VAL(*value));
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun /* Read 64-bit SRAM through the supplied mapping, locking as appropriate. */
ef4_sram_readq(struct ef4_nic * efx,void __iomem * membase,ef4_qword_t * value,unsigned int index)163*4882a593Smuzhiyun static inline void ef4_sram_readq(struct ef4_nic *efx, void __iomem *membase,
164*4882a593Smuzhiyun 				  ef4_qword_t *value, unsigned int index)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun 	unsigned int addr = index * sizeof(*value);
167*4882a593Smuzhiyun 	unsigned long flags __attribute__ ((unused));
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	spin_lock_irqsave(&efx->biu_lock, flags);
170*4882a593Smuzhiyun #ifdef EF4_USE_QWORD_IO
171*4882a593Smuzhiyun 	value->u64[0] = (__force __le64)__raw_readq(membase + addr);
172*4882a593Smuzhiyun #else
173*4882a593Smuzhiyun 	value->u32[0] = (__force __le32)__raw_readl(membase + addr);
174*4882a593Smuzhiyun 	value->u32[1] = (__force __le32)__raw_readl(membase + addr + 4);
175*4882a593Smuzhiyun #endif
176*4882a593Smuzhiyun 	spin_unlock_irqrestore(&efx->biu_lock, flags);
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun 	netif_vdbg(efx, hw, efx->net_dev,
179*4882a593Smuzhiyun 		   "read from SRAM address %x, got "EF4_QWORD_FMT"\n",
180*4882a593Smuzhiyun 		   addr, EF4_QWORD_VAL(*value));
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun /* Read a 32-bit CSR or SRAM */
ef4_readd(struct ef4_nic * efx,ef4_dword_t * value,unsigned int reg)184*4882a593Smuzhiyun static inline void ef4_readd(struct ef4_nic *efx, ef4_dword_t *value,
185*4882a593Smuzhiyun 				unsigned int reg)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun 	value->u32[0] = _ef4_readd(efx, reg);
188*4882a593Smuzhiyun 	netif_vdbg(efx, hw, efx->net_dev,
189*4882a593Smuzhiyun 		   "read from register %x, got "EF4_DWORD_FMT"\n",
190*4882a593Smuzhiyun 		   reg, EF4_DWORD_VAL(*value));
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun /* Write a 128-bit CSR forming part of a table */
194*4882a593Smuzhiyun static inline void
ef4_writeo_table(struct ef4_nic * efx,const ef4_oword_t * value,unsigned int reg,unsigned int index)195*4882a593Smuzhiyun ef4_writeo_table(struct ef4_nic *efx, const ef4_oword_t *value,
196*4882a593Smuzhiyun 		 unsigned int reg, unsigned int index)
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun 	ef4_writeo(efx, value, reg + index * sizeof(ef4_oword_t));
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun /* Read a 128-bit CSR forming part of a table */
ef4_reado_table(struct ef4_nic * efx,ef4_oword_t * value,unsigned int reg,unsigned int index)202*4882a593Smuzhiyun static inline void ef4_reado_table(struct ef4_nic *efx, ef4_oword_t *value,
203*4882a593Smuzhiyun 				     unsigned int reg, unsigned int index)
204*4882a593Smuzhiyun {
205*4882a593Smuzhiyun 	ef4_reado(efx, value, reg + index * sizeof(ef4_oword_t));
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun /* Page size used as step between per-VI registers */
209*4882a593Smuzhiyun #define EF4_VI_PAGE_SIZE 0x2000
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun /* Calculate offset to page-mapped register */
212*4882a593Smuzhiyun #define EF4_PAGED_REG(page, reg) \
213*4882a593Smuzhiyun 	((page) * EF4_VI_PAGE_SIZE + (reg))
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun /* Write the whole of RX_DESC_UPD or TX_DESC_UPD */
_ef4_writeo_page(struct ef4_nic * efx,ef4_oword_t * value,unsigned int reg,unsigned int page)216*4882a593Smuzhiyun static inline void _ef4_writeo_page(struct ef4_nic *efx, ef4_oword_t *value,
217*4882a593Smuzhiyun 				    unsigned int reg, unsigned int page)
218*4882a593Smuzhiyun {
219*4882a593Smuzhiyun 	reg = EF4_PAGED_REG(page, reg);
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun 	netif_vdbg(efx, hw, efx->net_dev,
222*4882a593Smuzhiyun 		   "writing register %x with " EF4_OWORD_FMT "\n", reg,
223*4882a593Smuzhiyun 		   EF4_OWORD_VAL(*value));
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun #ifdef EF4_USE_QWORD_IO
226*4882a593Smuzhiyun 	_ef4_writeq(efx, value->u64[0], reg + 0);
227*4882a593Smuzhiyun 	_ef4_writeq(efx, value->u64[1], reg + 8);
228*4882a593Smuzhiyun #else
229*4882a593Smuzhiyun 	_ef4_writed(efx, value->u32[0], reg + 0);
230*4882a593Smuzhiyun 	_ef4_writed(efx, value->u32[1], reg + 4);
231*4882a593Smuzhiyun 	_ef4_writed(efx, value->u32[2], reg + 8);
232*4882a593Smuzhiyun 	_ef4_writed(efx, value->u32[3], reg + 12);
233*4882a593Smuzhiyun #endif
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun #define ef4_writeo_page(efx, value, reg, page)				\
236*4882a593Smuzhiyun 	_ef4_writeo_page(efx, value,					\
237*4882a593Smuzhiyun 			 reg +						\
238*4882a593Smuzhiyun 			 BUILD_BUG_ON_ZERO((reg) != 0x830 && (reg) != 0xa10), \
239*4882a593Smuzhiyun 			 page)
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun /* Write a page-mapped 32-bit CSR (EVQ_RPTR, EVQ_TMR (EF10), or the
242*4882a593Smuzhiyun  * high bits of RX_DESC_UPD or TX_DESC_UPD)
243*4882a593Smuzhiyun  */
244*4882a593Smuzhiyun static inline void
_ef4_writed_page(struct ef4_nic * efx,const ef4_dword_t * value,unsigned int reg,unsigned int page)245*4882a593Smuzhiyun _ef4_writed_page(struct ef4_nic *efx, const ef4_dword_t *value,
246*4882a593Smuzhiyun 		 unsigned int reg, unsigned int page)
247*4882a593Smuzhiyun {
248*4882a593Smuzhiyun 	ef4_writed(efx, value, EF4_PAGED_REG(page, reg));
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun #define ef4_writed_page(efx, value, reg, page)				\
251*4882a593Smuzhiyun 	_ef4_writed_page(efx, value,					\
252*4882a593Smuzhiyun 			 reg +						\
253*4882a593Smuzhiyun 			 BUILD_BUG_ON_ZERO((reg) != 0x400 &&		\
254*4882a593Smuzhiyun 					   (reg) != 0x420 &&		\
255*4882a593Smuzhiyun 					   (reg) != 0x830 &&		\
256*4882a593Smuzhiyun 					   (reg) != 0x83c &&		\
257*4882a593Smuzhiyun 					   (reg) != 0xa18 &&		\
258*4882a593Smuzhiyun 					   (reg) != 0xa1c),		\
259*4882a593Smuzhiyun 			 page)
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun /* Write TIMER_COMMAND.  This is a page-mapped 32-bit CSR, but a bug
262*4882a593Smuzhiyun  * in the BIU means that writes to TIMER_COMMAND[0] invalidate the
263*4882a593Smuzhiyun  * collector register.
264*4882a593Smuzhiyun  */
_ef4_writed_page_locked(struct ef4_nic * efx,const ef4_dword_t * value,unsigned int reg,unsigned int page)265*4882a593Smuzhiyun static inline void _ef4_writed_page_locked(struct ef4_nic *efx,
266*4882a593Smuzhiyun 					   const ef4_dword_t *value,
267*4882a593Smuzhiyun 					   unsigned int reg,
268*4882a593Smuzhiyun 					   unsigned int page)
269*4882a593Smuzhiyun {
270*4882a593Smuzhiyun 	unsigned long flags __attribute__ ((unused));
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	if (page == 0) {
273*4882a593Smuzhiyun 		spin_lock_irqsave(&efx->biu_lock, flags);
274*4882a593Smuzhiyun 		ef4_writed(efx, value, EF4_PAGED_REG(page, reg));
275*4882a593Smuzhiyun 		spin_unlock_irqrestore(&efx->biu_lock, flags);
276*4882a593Smuzhiyun 	} else {
277*4882a593Smuzhiyun 		ef4_writed(efx, value, EF4_PAGED_REG(page, reg));
278*4882a593Smuzhiyun 	}
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun #define ef4_writed_page_locked(efx, value, reg, page)			\
281*4882a593Smuzhiyun 	_ef4_writed_page_locked(efx, value,				\
282*4882a593Smuzhiyun 				reg + BUILD_BUG_ON_ZERO((reg) != 0x420), \
283*4882a593Smuzhiyun 				page)
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun #endif /* EF4_IO_H */
286