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