aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2012-09-17 20:56:50 -0400
committerBen Hutchings <bhutchings@solarflare.com>2012-11-30 19:26:11 -0500
commit778cdaf639e34288c298f1d3d3503d0724ceabc7 (patch)
tree1a88ba2e73096166ce7c3021ddd70effe34f8d1d
parentbbec969b7f57a6ab5683145b99da869f99080e2a (diff)
sfc: Remove confusing MMIO functions
efx_writed_table() uses a step of 16 bytes but efx_readd_table() uses a step of 4 bytes. Why are they different? Firstly, register access is asymmetric: - The EVQ_RPTR table and RX_INDIRECTION_TBL can (or must?) be written as dwords even though they have a step size of 16 bytes, unlike most other CSRs. - In general, a read of any width is valid for registers, so long as it does not cross register boundaries. There is also no latching behaviour in the BIU, contrary to rumour. We write to the EVQ_RPTR table with efx_writed_table() but never read it back as it's write-only. We write to the RX_INDIRECTION_TBL with efx_writed_table(), but only read it back for the register dump, where we use efx_reado_table() as for any other table with step size of 16. We read MC_TREG_SMEM with efx_readd_table() for the register dump, but normally read and write it with efx_readd() and efx_writed() using offsets calculated in bytes. Since these functions are trivial and have few callers, it's clearer to open-code them at the call sites. While we're at it, update the comments on the BIU behaviour again. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
-rw-r--r--drivers/net/ethernet/sfc/io.h43
-rw-r--r--drivers/net/ethernet/sfc/nic.c19
-rw-r--r--drivers/net/ethernet/sfc/siena_sriov.c2
3 files changed, 28 insertions, 36 deletions
diff --git a/drivers/net/ethernet/sfc/io.h b/drivers/net/ethernet/sfc/io.h
index 751d1ec112cc..96759aee1c6c 100644
--- a/drivers/net/ethernet/sfc/io.h
+++ b/drivers/net/ethernet/sfc/io.h
@@ -22,22 +22,21 @@
22 * 22 *
23 * Notes on locking strategy: 23 * Notes on locking strategy:
24 * 24 *
25 * Most CSRs are 128-bit (oword) and therefore cannot be read or 25 * Many CSRs are very wide and cannot be read or written atomically.
26 * written atomically. Access from the host is buffered by the Bus 26 * Writes from the host are buffered by the Bus Interface Unit (BIU)
27 * Interface Unit (BIU). Whenever the host reads from the lowest 27 * up to 128 bits. Whenever the host writes part of such a register,
28 * address of such a register, or from the address of a different such 28 * the BIU collects the written value and does not write to the
29 * register, the BIU latches the register's value. Subsequent reads 29 * underlying register until all 4 dwords have been written. A
30 * from higher addresses of the same register will read the latched 30 * similar buffering scheme applies to host access to the NIC's 64-bit
31 * value. Whenever the host writes part of such a register, the BIU 31 * SRAM.
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.
35 * 32 *
36 * Access to different CSRs and 64-bit SRAM words must be serialised, 33 * Writes to different CSRs and 64-bit SRAM words must be serialised,
37 * since interleaved access can result in lost writes or lost 34 * since interleaved access can result in lost writes. We use
38 * information from read-to-clear fields. We use efx_nic::biu_lock 35 * efx_nic::biu_lock for this.
39 * for this. (We could use separate locks for read and write, but 36 *
40 * this is not normally a performance bottleneck.) 37 * We also serialise reads from 128-bit CSRs and SRAM with the same
38 * spinlock. This may not be necessary, but it doesn't really matter
39 * as there are no such reads on the fast path.
41 * 40 *
42 * The DMA descriptor pointers (RX_DESC_UPD and TX_DESC_UPD) are 41 * The DMA descriptor pointers (RX_DESC_UPD and TX_DESC_UPD) are
43 * 128-bit but are special-cased in the BIU to avoid the need for 42 * 128-bit but are special-cased in the BIU to avoid the need for
@@ -204,20 +203,6 @@ static inline void efx_reado_table(struct efx_nic *efx, efx_oword_t *value,
204 efx_reado(efx, value, reg + index * sizeof(efx_oword_t)); 203 efx_reado(efx, value, reg + index * sizeof(efx_oword_t));
205} 204}
206 205
207/* Write a 32-bit CSR forming part of a table, or 32-bit SRAM */
208static inline void efx_writed_table(struct efx_nic *efx, efx_dword_t *value,
209 unsigned int reg, unsigned int index)
210{
211 efx_writed(efx, value, reg + index * sizeof(efx_oword_t));
212}
213
214/* Read a 32-bit CSR forming part of a table, or 32-bit SRAM */
215static inline void efx_readd_table(struct efx_nic *efx, efx_dword_t *value,
216 unsigned int reg, unsigned int index)
217{
218 efx_readd(efx, value, reg + index * sizeof(efx_dword_t));
219}
220
221/* Page-mapped register block size */ 206/* Page-mapped register block size */
222#define EFX_PAGE_BLOCK_SIZE 0x2000 207#define EFX_PAGE_BLOCK_SIZE 0x2000
223 208
diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c
index e10b7ec046c3..368659d6362a 100644
--- a/drivers/net/ethernet/sfc/nic.c
+++ b/drivers/net/ethernet/sfc/nic.c
@@ -765,8 +765,13 @@ void efx_nic_eventq_read_ack(struct efx_channel *channel)
765 765
766 EFX_POPULATE_DWORD_1(reg, FRF_AZ_EVQ_RPTR, 766 EFX_POPULATE_DWORD_1(reg, FRF_AZ_EVQ_RPTR,
767 channel->eventq_read_ptr & channel->eventq_mask); 767 channel->eventq_read_ptr & channel->eventq_mask);
768 efx_writed_table(efx, &reg, efx->type->evq_rptr_tbl_base, 768
769 channel->channel); 769 /* For Falcon A1, EVQ_RPTR_KER is documented as having a step size
770 * of 4 bytes, but it is really 16 bytes just like later revisions.
771 */
772 efx_writed(efx, &reg,
773 efx->type->evq_rptr_tbl_base +
774 FR_BZ_EVQ_RPTR_STEP * channel->channel);
770} 775}
771 776
772/* Use HW to insert a SW defined event */ 777/* Use HW to insert a SW defined event */
@@ -1564,7 +1569,9 @@ void efx_nic_push_rx_indir_table(struct efx_nic *efx)
1564 for (i = 0; i < FR_BZ_RX_INDIRECTION_TBL_ROWS; i++) { 1569 for (i = 0; i < FR_BZ_RX_INDIRECTION_TBL_ROWS; i++) {
1565 EFX_POPULATE_DWORD_1(dword, FRF_BZ_IT_QUEUE, 1570 EFX_POPULATE_DWORD_1(dword, FRF_BZ_IT_QUEUE,
1566 efx->rx_indir_table[i]); 1571 efx->rx_indir_table[i]);
1567 efx_writed_table(efx, &dword, FR_BZ_RX_INDIRECTION_TBL, i); 1572 efx_writed(efx, &dword,
1573 FR_BZ_RX_INDIRECTION_TBL +
1574 FR_BZ_RX_INDIRECTION_TBL_STEP * i);
1568 } 1575 }
1569} 1576}
1570 1577
@@ -2028,15 +2035,15 @@ void efx_nic_get_regs(struct efx_nic *efx, void *buf)
2028 2035
2029 for (i = 0; i < table->rows; i++) { 2036 for (i = 0; i < table->rows; i++) {
2030 switch (table->step) { 2037 switch (table->step) {
2031 case 4: /* 32-bit register or SRAM */ 2038 case 4: /* 32-bit SRAM */
2032 efx_readd_table(efx, buf, table->offset, i); 2039 efx_readd(efx, buf, table->offset + 4 * i);
2033 break; 2040 break;
2034 case 8: /* 64-bit SRAM */ 2041 case 8: /* 64-bit SRAM */
2035 efx_sram_readq(efx, 2042 efx_sram_readq(efx,
2036 efx->membase + table->offset, 2043 efx->membase + table->offset,
2037 buf, i); 2044 buf, i);
2038 break; 2045 break;
2039 case 16: /* 128-bit register */ 2046 case 16: /* 128-bit-readable register */
2040 efx_reado_table(efx, buf, table->offset, i); 2047 efx_reado_table(efx, buf, table->offset, i);
2041 break; 2048 break;
2042 case 32: /* 128-bit register, interleaved */ 2049 case 32: /* 128-bit register, interleaved */
diff --git a/drivers/net/ethernet/sfc/siena_sriov.c b/drivers/net/ethernet/sfc/siena_sriov.c
index 6e62a018ea32..90f8d1604f5f 100644
--- a/drivers/net/ethernet/sfc/siena_sriov.c
+++ b/drivers/net/ethernet/sfc/siena_sriov.c
@@ -993,7 +993,7 @@ static void efx_sriov_reset_vf(struct efx_vf *vf, struct efx_buffer *buffer)
993 FRF_AZ_EVQ_BUF_BASE_ID, buftbl); 993 FRF_AZ_EVQ_BUF_BASE_ID, buftbl);
994 efx_writeo_table(efx, &reg, FR_BZ_EVQ_PTR_TBL, abs_evq); 994 efx_writeo_table(efx, &reg, FR_BZ_EVQ_PTR_TBL, abs_evq);
995 EFX_POPULATE_DWORD_1(ptr, FRF_AZ_EVQ_RPTR, 0); 995 EFX_POPULATE_DWORD_1(ptr, FRF_AZ_EVQ_RPTR, 0);
996 efx_writed_table(efx, &ptr, FR_BZ_EVQ_RPTR, abs_evq); 996 efx_writed(efx, &ptr, FR_BZ_EVQ_RPTR + FR_BZ_EVQ_RPTR_STEP * abs_evq);
997 997
998 mutex_unlock(&vf->status_lock); 998 mutex_unlock(&vf->status_lock);
999} 999}