1 /*-
2 * Copyright 2009 Solarflare Communications Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
28
29 #include "efsys.h"
30 #include "efx.h"
31 #include "efx_impl.h"
32
33 #if EFSYS_OPT_SIENA
34
35 void
siena_sram_init(__in efx_nic_t * enp)36 siena_sram_init(
37 __in efx_nic_t *enp)
38 {
39 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
40 efx_oword_t oword;
41 uint32_t rx_base, tx_base;
42
43 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
44 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
45
46 rx_base = encp->enc_buftbl_limit;
47 tx_base = rx_base + (encp->enc_rxq_limit *
48 EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
49
50 /* Initialize the transmit descriptor cache */
51 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_TX_DC_BASE_ADR, tx_base);
52 EFX_BAR_WRITEO(enp, FR_AZ_SRM_TX_DC_CFG_REG, &oword);
53
54 EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DC_SIZE, EFX_TXQ_DC_SIZE);
55 EFX_BAR_WRITEO(enp, FR_AZ_TX_DC_CFG_REG, &oword);
56
57 /* Initialize the receive descriptor cache */
58 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_RX_DC_BASE_ADR, rx_base);
59 EFX_BAR_WRITEO(enp, FR_AZ_SRM_RX_DC_CFG_REG, &oword);
60
61 EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_SIZE, EFX_RXQ_DC_SIZE);
62 EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_CFG_REG, &oword);
63
64 /* Set receive descriptor pre-fetch low water mark */
65 EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_PF_LWM, 56);
66 EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_PF_WM_REG, &oword);
67
68 /* Set the event queue to use for SRAM updates */
69 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_UPD_EVQ_ID, 0);
70 EFX_BAR_WRITEO(enp, FR_AZ_SRM_UPD_EVQ_REG, &oword);
71 }
72
73 #if EFSYS_OPT_DIAG
74
75 __checkReturn int
siena_sram_test(__in efx_nic_t * enp,__in efx_sram_pattern_fn_t func)76 siena_sram_test(
77 __in efx_nic_t *enp,
78 __in efx_sram_pattern_fn_t func)
79 {
80 efx_oword_t oword;
81 efx_qword_t qword;
82 efx_qword_t verify;
83 size_t rows;
84 unsigned int wptr;
85 unsigned int rptr;
86 int rc;
87
88 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
89
90 /* Reconfigure into HALF buffer table mode */
91 EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 0);
92 EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword);
93
94 /*
95 * Move the descriptor caches up to the top of SRAM, and test
96 * all of SRAM below them. We only miss out one row here.
97 */
98 rows = SIENA_SRAM_ROWS - 1;
99 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_RX_DC_BASE_ADR, rows);
100 EFX_BAR_WRITEO(enp, FR_AZ_SRM_RX_DC_CFG_REG, &oword);
101
102 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_TX_DC_BASE_ADR, rows + 1);
103 EFX_BAR_WRITEO(enp, FR_AZ_SRM_TX_DC_CFG_REG, &oword);
104
105 /*
106 * Write the pattern through BUF_HALF_TBL. Write
107 * in 64 entry batches, waiting 1us in between each batch
108 * to guarantee not to overflow the SRAM fifo
109 */
110 for (wptr = 0, rptr = 0; wptr < rows; ++wptr) {
111 func(wptr, B_FALSE, &qword);
112 EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_HALF_TBL, wptr, &qword);
113
114 if ((wptr - rptr) < 64 && wptr < rows - 1)
115 continue;
116
117 EFSYS_SPIN(1);
118
119 for (; rptr <= wptr; ++rptr) {
120 func(rptr, B_FALSE, &qword);
121 EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_HALF_TBL, rptr,
122 &verify);
123
124 if (!EFX_QWORD_IS_EQUAL(verify, qword)) {
125 rc = EFAULT;
126 goto fail1;
127 }
128 }
129 }
130
131 /* And do the same negated */
132 for (wptr = 0, rptr = 0; wptr < rows; ++wptr) {
133 func(wptr, B_TRUE, &qword);
134 EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_HALF_TBL, wptr, &qword);
135
136 if ((wptr - rptr) < 64 && wptr < rows - 1)
137 continue;
138
139 EFSYS_SPIN(1);
140
141 for (; rptr <= wptr; ++rptr) {
142 func(rptr, B_TRUE, &qword);
143 EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_HALF_TBL, rptr,
144 &verify);
145
146 if (!EFX_QWORD_IS_EQUAL(verify, qword)) {
147 rc = EFAULT;
148 goto fail2;
149 }
150 }
151 }
152
153 /* Restore back to FULL buffer table mode */
154 EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 1);
155 EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword);
156
157 /*
158 * We don't need to reconfigure SRAM again because the API
159 * requires efx_nic_fini() to be called after an sram test.
160 */
161 return (0);
162
163 fail2:
164 EFSYS_PROBE(fail2);
165 fail1:
166 EFSYS_PROBE1(fail1, int, rc);
167
168 /* Restore back to FULL buffer table mode */
169 EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 1);
170 EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword);
171
172 return (rc);
173 }
174
175 #endif /* EFSYS_OPT_DIAG */
176
177 #endif /* EFSYS_OPT_SIENA */
178