diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2010-12-06 17:55:00 -0500 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2010-12-06 17:55:00 -0500 |
commit | 9f2f6cd07a09bc0af1f2950189e426569561d1e6 (patch) | |
tree | 366f7284f2362a413ddde7bf9f01cfd5f4e7fab4 /drivers/net/sfc/io.h | |
parent | 51c56f40ef41ca780ff001d59727eda03fa39374 (diff) |
sfc: Expand/correct comments on collector behaviour and function usage
Document exactly which registers and functions have special behaviour,
and why races on writes to descriptor pointers are safe.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/sfc/io.h')
-rw-r--r-- | drivers/net/sfc/io.h | 98 |
1 files changed, 49 insertions, 49 deletions
diff --git a/drivers/net/sfc/io.h b/drivers/net/sfc/io.h index 85a99fe87437..0764e84ecc41 100644 --- a/drivers/net/sfc/io.h +++ b/drivers/net/sfc/io.h | |||
@@ -22,28 +22,39 @@ | |||
22 | * | 22 | * |
23 | * Notes on locking strategy: | 23 | * Notes on locking strategy: |
24 | * | 24 | * |
25 | * Most NIC registers require 16-byte (or 8-byte, for SRAM) atomic writes | 25 | * Most CSRs are 128-bit (oword) and therefore cannot be read or |
26 | * which necessitates locking. | 26 | * written atomically. Access from the host is buffered by the Bus |
27 | * Under normal operation few writes to NIC registers are made and these | 27 | * Interface Unit (BIU). Whenever the host reads from the lowest |
28 | * registers (EVQ_RPTR_REG, RX_DESC_UPD_REG and TX_DESC_UPD_REG) are special | 28 | * address of such a register, or from the address of a different such |
29 | * cased to allow 4-byte (hence lockless) accesses. | 29 | * register, the BIU latches the register's value. Subsequent reads |
30 | * from higher addresses of the same register will read the latched | ||
31 | * value. Whenever the host writes part of such a register, the BIU | ||
32 | * collects the written value and does not write to the underlying | ||
33 | * register until all 4 dwords have been written. A similar buffering | ||
34 | * scheme applies to host access to the NIC's 64-bit SRAM. | ||
30 | * | 35 | * |
31 | * It *is* safe to write to these 4-byte registers in the middle of an | 36 | * Access to different CSRs and 64-bit SRAM words must be serialised, |
32 | * access to an 8-byte or 16-byte register. We therefore use a | 37 | * since interleaved access can result in lost writes or lost |
33 | * spinlock to protect accesses to the larger registers, but no locks | 38 | * information from read-to-clear fields. We use efx_nic::biu_lock |
34 | * for the 4-byte registers. | 39 | * for this. (We could use separate locks for read and write, but |
40 | * this is not normally a performance bottleneck.) | ||
35 | * | 41 | * |
36 | * A write barrier is needed to ensure that DW3 is written after DW0/1/2 | 42 | * The DMA descriptor pointers (RX_DESC_UPD and TX_DESC_UPD) are |
37 | * due to the way the 16byte registers are "collected" in the BIU. | 43 | * 128-bit but are special-cased in the BIU to avoid the need for |
44 | * locking in the host: | ||
38 | * | 45 | * |
39 | * We also lock when carrying out reads, to ensure consistency of the | 46 | * - They are write-only. |
40 | * data (made possible since the BIU reads all 128 bits into a cache). | 47 | * - The semantics of writing to these registers are such that |
41 | * Reads are very rare, so this isn't a significant performance | 48 | * replacing the low 96 bits with zero does not affect functionality. |
42 | * impact. (Most data transferred from NIC to host is DMAed directly | 49 | * - If the host writes to the last dword address of such a register |
43 | * into host memory). | 50 | * (i.e. the high 32 bits) the underlying register will always be |
44 | * | 51 | * written. If the collector does not hold values for the low 96 |
45 | * I/O BAR access uses locks for both reads and writes (but is only provided | 52 | * bits of the register, they will be written as zero. Writing to |
46 | * for testing purposes). | 53 | * the last qword does not have this effect and must not be done. |
54 | * - If the host writes to the address of any other part of such a | ||
55 | * register while the collector already holds values for some other | ||
56 | * register, the write is discarded and the collector maintains its | ||
57 | * current state. | ||
47 | */ | 58 | */ |
48 | 59 | ||
49 | #if BITS_PER_LONG == 64 | 60 | #if BITS_PER_LONG == 64 |
@@ -72,7 +83,7 @@ static inline __le32 _efx_readd(struct efx_nic *efx, unsigned int reg) | |||
72 | return (__force __le32)__raw_readl(efx->membase + reg); | 83 | return (__force __le32)__raw_readl(efx->membase + reg); |
73 | } | 84 | } |
74 | 85 | ||
75 | /* Writes to a normal 16-byte Efx register, locking as appropriate. */ | 86 | /* Write a normal 128-bit CSR, locking as appropriate. */ |
76 | static inline void efx_writeo(struct efx_nic *efx, efx_oword_t *value, | 87 | static inline void efx_writeo(struct efx_nic *efx, efx_oword_t *value, |
77 | unsigned int reg) | 88 | unsigned int reg) |
78 | { | 89 | { |
@@ -98,8 +109,7 @@ static inline void efx_writeo(struct efx_nic *efx, efx_oword_t *value, | |||
98 | spin_unlock_irqrestore(&efx->biu_lock, flags); | 109 | spin_unlock_irqrestore(&efx->biu_lock, flags); |
99 | } | 110 | } |
100 | 111 | ||
101 | /* Write an 8-byte NIC SRAM entry through the supplied mapping, | 112 | /* Write 64-bit SRAM through the supplied mapping, locking as appropriate. */ |
102 | * locking as appropriate. */ | ||
103 | static inline void efx_sram_writeq(struct efx_nic *efx, void __iomem *membase, | 113 | static inline void efx_sram_writeq(struct efx_nic *efx, void __iomem *membase, |
104 | efx_qword_t *value, unsigned int index) | 114 | efx_qword_t *value, unsigned int index) |
105 | { | 115 | { |
@@ -122,29 +132,19 @@ static inline void efx_sram_writeq(struct efx_nic *efx, void __iomem *membase, | |||
122 | spin_unlock_irqrestore(&efx->biu_lock, flags); | 132 | spin_unlock_irqrestore(&efx->biu_lock, flags); |
123 | } | 133 | } |
124 | 134 | ||
125 | /* Write dword to NIC register that allows partial writes | 135 | /* Write a 32-bit CSR or the last dword of a special 128-bit CSR */ |
126 | * | ||
127 | * Some registers (EVQ_RPTR_REG, RX_DESC_UPD_REG and | ||
128 | * TX_DESC_UPD_REG) can be written to as a single dword. This allows | ||
129 | * for lockless writes. | ||
130 | */ | ||
131 | static inline void efx_writed(struct efx_nic *efx, efx_dword_t *value, | 136 | static inline void efx_writed(struct efx_nic *efx, efx_dword_t *value, |
132 | unsigned int reg) | 137 | unsigned int reg) |
133 | { | 138 | { |
134 | netif_vdbg(efx, hw, efx->net_dev, | 139 | netif_vdbg(efx, hw, efx->net_dev, |
135 | "writing partial register %x with "EFX_DWORD_FMT"\n", | 140 | "writing register %x with "EFX_DWORD_FMT"\n", |
136 | reg, EFX_DWORD_VAL(*value)); | 141 | reg, EFX_DWORD_VAL(*value)); |
137 | 142 | ||
138 | /* No lock required */ | 143 | /* No lock required */ |
139 | _efx_writed(efx, value->u32[0], reg); | 144 | _efx_writed(efx, value->u32[0], reg); |
140 | } | 145 | } |
141 | 146 | ||
142 | /* Read from a NIC register | 147 | /* Read a 128-bit CSR, locking as appropriate. */ |
143 | * | ||
144 | * This reads an entire 16-byte register in one go, locking as | ||
145 | * appropriate. It is essential to read the first dword first, as this | ||
146 | * prompts the NIC to load the current value into the shadow register. | ||
147 | */ | ||
148 | static inline void efx_reado(struct efx_nic *efx, efx_oword_t *value, | 148 | static inline void efx_reado(struct efx_nic *efx, efx_oword_t *value, |
149 | unsigned int reg) | 149 | unsigned int reg) |
150 | { | 150 | { |
@@ -163,8 +163,7 @@ static inline void efx_reado(struct efx_nic *efx, efx_oword_t *value, | |||
163 | EFX_OWORD_VAL(*value)); | 163 | EFX_OWORD_VAL(*value)); |
164 | } | 164 | } |
165 | 165 | ||
166 | /* Read an 8-byte SRAM entry through supplied mapping, | 166 | /* Read 64-bit SRAM through the supplied mapping, locking as appropriate. */ |
167 | * locking as appropriate. */ | ||
168 | static inline void efx_sram_readq(struct efx_nic *efx, void __iomem *membase, | 167 | static inline void efx_sram_readq(struct efx_nic *efx, void __iomem *membase, |
169 | efx_qword_t *value, unsigned int index) | 168 | efx_qword_t *value, unsigned int index) |
170 | { | 169 | { |
@@ -186,7 +185,7 @@ static inline void efx_sram_readq(struct efx_nic *efx, void __iomem *membase, | |||
186 | addr, EFX_QWORD_VAL(*value)); | 185 | addr, EFX_QWORD_VAL(*value)); |
187 | } | 186 | } |
188 | 187 | ||
189 | /* Read dword from register that allows partial writes (sic) */ | 188 | /* Read a 32-bit CSR or SRAM */ |
190 | static inline void efx_readd(struct efx_nic *efx, efx_dword_t *value, | 189 | static inline void efx_readd(struct efx_nic *efx, efx_dword_t *value, |
191 | unsigned int reg) | 190 | unsigned int reg) |
192 | { | 191 | { |
@@ -196,28 +195,28 @@ static inline void efx_readd(struct efx_nic *efx, efx_dword_t *value, | |||
196 | reg, EFX_DWORD_VAL(*value)); | 195 | reg, EFX_DWORD_VAL(*value)); |
197 | } | 196 | } |
198 | 197 | ||
199 | /* Write to a register forming part of a table */ | 198 | /* Write a 128-bit CSR forming part of a table */ |
200 | static inline void efx_writeo_table(struct efx_nic *efx, efx_oword_t *value, | 199 | static inline void efx_writeo_table(struct efx_nic *efx, efx_oword_t *value, |
201 | unsigned int reg, unsigned int index) | 200 | unsigned int reg, unsigned int index) |
202 | { | 201 | { |
203 | efx_writeo(efx, value, reg + index * sizeof(efx_oword_t)); | 202 | efx_writeo(efx, value, reg + index * sizeof(efx_oword_t)); |
204 | } | 203 | } |
205 | 204 | ||
206 | /* Read to a register forming part of a table */ | 205 | /* Read a 128-bit CSR forming part of a table */ |
207 | static inline void efx_reado_table(struct efx_nic *efx, efx_oword_t *value, | 206 | static inline void efx_reado_table(struct efx_nic *efx, efx_oword_t *value, |
208 | unsigned int reg, unsigned int index) | 207 | unsigned int reg, unsigned int index) |
209 | { | 208 | { |
210 | efx_reado(efx, value, reg + index * sizeof(efx_oword_t)); | 209 | efx_reado(efx, value, reg + index * sizeof(efx_oword_t)); |
211 | } | 210 | } |
212 | 211 | ||
213 | /* Write to a dword register forming part of a table */ | 212 | /* Write a 32-bit CSR forming part of a table, or 32-bit SRAM */ |
214 | static inline void efx_writed_table(struct efx_nic *efx, efx_dword_t *value, | 213 | static inline void efx_writed_table(struct efx_nic *efx, efx_dword_t *value, |
215 | unsigned int reg, unsigned int index) | 214 | unsigned int reg, unsigned int index) |
216 | { | 215 | { |
217 | efx_writed(efx, value, reg + index * sizeof(efx_oword_t)); | 216 | efx_writed(efx, value, reg + index * sizeof(efx_oword_t)); |
218 | } | 217 | } |
219 | 218 | ||
220 | /* Read from a dword register forming part of a table */ | 219 | /* Read a 32-bit CSR forming part of a table, or 32-bit SRAM */ |
221 | static inline void efx_readd_table(struct efx_nic *efx, efx_dword_t *value, | 220 | static inline void efx_readd_table(struct efx_nic *efx, efx_dword_t *value, |
222 | unsigned int reg, unsigned int index) | 221 | unsigned int reg, unsigned int index) |
223 | { | 222 | { |
@@ -231,25 +230,26 @@ static inline void efx_readd_table(struct efx_nic *efx, efx_dword_t *value, | |||
231 | #define EFX_PAGED_REG(page, reg) \ | 230 | #define EFX_PAGED_REG(page, reg) \ |
232 | ((page) * EFX_PAGE_BLOCK_SIZE + (reg)) | 231 | ((page) * EFX_PAGE_BLOCK_SIZE + (reg)) |
233 | 232 | ||
234 | /* As for efx_writeo(), but for a page-mapped register. */ | 233 | /* Write the whole of RX_DESC_UPD or TX_DESC_UPD */ |
235 | static inline void efx_writeo_page(struct efx_nic *efx, efx_oword_t *value, | 234 | static inline void efx_writeo_page(struct efx_nic *efx, efx_oword_t *value, |
236 | unsigned int reg, unsigned int page) | 235 | unsigned int reg, unsigned int page) |
237 | { | 236 | { |
238 | efx_writeo(efx, value, EFX_PAGED_REG(page, reg)); | 237 | efx_writeo(efx, value, EFX_PAGED_REG(page, reg)); |
239 | } | 238 | } |
240 | 239 | ||
241 | /* As for efx_writed(), but for a page-mapped register. */ | 240 | /* Write a page-mapped 32-bit CSR (EVQ_RPTR or the high bits of |
241 | * RX_DESC_UPD or TX_DESC_UPD) | ||
242 | */ | ||
242 | static inline void efx_writed_page(struct efx_nic *efx, efx_dword_t *value, | 243 | static inline void efx_writed_page(struct efx_nic *efx, efx_dword_t *value, |
243 | unsigned int reg, unsigned int page) | 244 | unsigned int reg, unsigned int page) |
244 | { | 245 | { |
245 | efx_writed(efx, value, EFX_PAGED_REG(page, reg)); | 246 | efx_writed(efx, value, EFX_PAGED_REG(page, reg)); |
246 | } | 247 | } |
247 | 248 | ||
248 | /* Write dword to page-mapped register with an extra lock. | 249 | /* Write TIMER_COMMAND. This is a page-mapped 32-bit CSR, but a bug |
249 | * | 250 | * in the BIU means that writes to TIMER_COMMAND[0] invalidate the |
250 | * As for efx_writed_page(), but for a register that suffers from | 251 | * collector register. |
251 | * SFC bug 3181. Take out a lock so the BIU collector cannot be | 252 | */ |
252 | * confused. */ | ||
253 | static inline void efx_writed_page_locked(struct efx_nic *efx, | 253 | static inline void efx_writed_page_locked(struct efx_nic *efx, |
254 | efx_dword_t *value, | 254 | efx_dword_t *value, |
255 | unsigned int reg, | 255 | unsigned int reg, |