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 #include "efsys.h"
26 #include "efx.h"
27 #include "efx_impl.h"
28
29 #if EFSYS_OPT_SIENA
30
31 void
32 siena_sram_init(
33 __in efx_nic_t *enp)
34 {
35 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
36 efx_oword_t oword;
37 uint32_t rx_base, tx_base;
38
39 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
40 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
41
42 rx_base = encp->enc_buftbl_limit;
43 tx_base = rx_base + (encp->enc_rxq_limit *
44 EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
45
46 /* Initialize the transmit descriptor cache */
47 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_TX_DC_BASE_ADR, tx_base);
48 EFX_BAR_WRITEO(enp, FR_AZ_SRM_TX_DC_CFG_REG, &oword);
49
50 EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DC_SIZE, EFX_TXQ_DC_SIZE);
51 EFX_BAR_WRITEO(enp, FR_AZ_TX_DC_CFG_REG, &oword);
52
53 /* Initialize the receive descriptor cache */
54 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_RX_DC_BASE_ADR, rx_base);
55 EFX_BAR_WRITEO(enp, FR_AZ_SRM_RX_DC_CFG_REG, &oword);
56
57 EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_SIZE, EFX_RXQ_DC_SIZE);
58 EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_CFG_REG, &oword);
59
60 /* Set receive descriptor pre-fetch low water mark */
61 EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_PF_LWM, 56);
62 EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_PF_WM_REG, &oword);
63
64 /* Set the event queue to use for SRAM updates */
65 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_UPD_EVQ_ID, 0);
66 EFX_BAR_WRITEO(enp, FR_AZ_SRM_UPD_EVQ_REG, &oword);
67 }
68
69 #if EFSYS_OPT_DIAG
70
71 __checkReturn int
72 siena_sram_test(
73 __in efx_nic_t *enp,
74 __in efx_sram_pattern_fn_t func)
75 {
76 efx_oword_t oword;
77 efx_qword_t qword;
78 efx_qword_t verify;
79 size_t rows;
80 unsigned int wptr;
81 unsigned int rptr;
82 int rc;
83
84 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
85
86 /* Reconfigure into HALF buffer table mode */
87 EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 0);
88 EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword);
89
90 /*
91 * Move the descriptor caches up to the top of SRAM, and test
92 * all of SRAM below them. We only miss out one row here.
93 */
94 rows = SIENA_SRAM_ROWS - 1;
95 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_RX_DC_BASE_ADR, rows);
96 EFX_BAR_WRITEO(enp, FR_AZ_SRM_RX_DC_CFG_REG, &oword);
97
98 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_TX_DC_BASE_ADR, rows + 1);
99 EFX_BAR_WRITEO(enp, FR_AZ_SRM_TX_DC_CFG_REG, &oword);
100
101 /*
102 * Write the pattern through BUF_HALF_TBL. Write
103 * in 64 entry batches, waiting 1us in between each batch
104 * to guarantee not to overflow the SRAM fifo
105 */
106 for (wptr = 0, rptr = 0; wptr < rows; ++wptr) {
107 func(wptr, B_FALSE, &qword);
108 EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_HALF_TBL, wptr, &qword);
109
110 if ((wptr - rptr) < 64 && wptr < rows - 1)
111 continue;
112
113 EFSYS_SPIN(1);
114
115 for (; rptr <= wptr; ++rptr) {
116 func(rptr, B_FALSE, &qword);
117 EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_HALF_TBL, rptr,
118 &verify);
119
120 if (!EFX_QWORD_IS_EQUAL(verify, qword)) {
121 rc = EFAULT;
122 goto fail1;
123 }
124 }
125 }
126
127 /* And do the same negated */
128 for (wptr = 0, rptr = 0; wptr < rows; ++wptr) {
129 func(wptr, B_TRUE, &qword);
130 EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_HALF_TBL, wptr, &qword);
131
132 if ((wptr - rptr) < 64 && wptr < rows - 1)
133 continue;
134
135 EFSYS_SPIN(1);
136
137 for (; rptr <= wptr; ++rptr) {
138 func(rptr, B_TRUE, &qword);
139 EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_HALF_TBL, rptr,
140 &verify);
141
142 if (!EFX_QWORD_IS_EQUAL(verify, qword)) {
143 rc = EFAULT;
144 goto fail2;
145 }
146 }
147 }
148
149 /* Restore back to FULL buffer table mode */
150 EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 1);
151 EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword);
152
153 /*
154 * We don't need to reconfigure SRAM again because the API
155 * requires efx_nic_fini() to be called after an sram test.
156 */
157 return (0);
158
159 fail2:
160 EFSYS_PROBE(fail2);
161 fail1:
162 EFSYS_PROBE1(fail1, int, rc);
163
164 /* Restore back to FULL buffer table mode */
165 EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 1);
166 EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword);
167
168 return (rc);
169 }
170
171 #endif /* EFSYS_OPT_DIAG */
172
173 #endif /* EFSYS_OPT_SIENA */