1 /*
2 * Copyright 2007-2013 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 "efsys.h"
27 #include "efx.h"
28 #include "efx_types.h"
29 #include "efx_regs.h"
30 #include "efx_impl.h"
31
32 #if EFSYS_OPT_FALCON
33
34 static __checkReturn int
35 falcon_sram_reset(
36 __in efx_nic_t *enp)
37 {
38 efx_oword_t oword;
39 unsigned int count;
40 int rc;
41
42 /* Initiate SRAM reset */
43 EFX_POPULATE_OWORD_3(oword,
44 FRF_AZ_SRM_NUM_BANK,
45 enp->en_u.falcon.enu_sram_num_bank,
46 FRF_AZ_SRM_BANK_SIZE,
47 enp->en_u.falcon.enu_sram_bank_size,
48 FRF_AZ_SRM_INIT_EN, 1);
49 EFX_BAR_WRITEO(enp, FR_AZ_SRM_CFG_REG, &oword);
50
51 /* Wait for SRAM reset to complete */
52 count = 0;
53 do {
54 EFSYS_PROBE1(wait, unsigned int, count);
55
56 /* Spin for 1 ms */
57 EFSYS_SPIN(1000);
58
59 /* Check for reset complete */
60 EFX_BAR_READO(enp, FR_AZ_SRM_CFG_REG, &oword);
61 if (EFX_OWORD_FIELD(oword, FRF_AZ_SRM_INIT_EN) == 0)
62 goto done;
63 } while (++count < 100);
64
65 rc = ETIMEDOUT;
66 goto fail1;
67
68 done:
69 return (0);
70
71 fail1:
72 EFSYS_PROBE1(fail1, int, rc);
73
74 return (rc);
75 }
76
77 __checkReturn int
78 falcon_sram_init(
79 __in efx_nic_t *enp)
80 {
81 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
82 efx_oword_t oword;
83 uint32_t tx_base, rx_base;
84 int rc;
85
86 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
87 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
88
89 /* Position the descriptor caches */
90 if (enp->en_u.falcon.enu_internal_sram) {
91 tx_base = 0x130000;
92 rx_base = 0x100000;
93 } else {
94 rx_base = encp->enc_buftbl_limit * 8;
95 tx_base = rx_base + (encp->enc_rxq_limit * 64 * 8);
96 }
97
98 /* Select internal SRAM */
99 EFX_BAR_READO(enp, FR_AB_NIC_STAT_REG, &oword);
100 EFX_SET_OWORD_FIELD(oword, FRF_AB_ONCHIP_SRAM,
101 enp->en_u.falcon.enu_internal_sram ? 1 : 0);
102 EFX_BAR_WRITEO(enp, FR_AB_NIC_STAT_REG, &oword);
103
104 /* Sleep/Wake any external SRAM */
105 EFX_BAR_READO(enp, FR_AB_GPIO_CTL_REG, &oword);
106 EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO1_OEN, 1);
107 EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO1_OUT,
108 enp->en_u.falcon.enu_internal_sram ? 1 : 0);
109 EFX_BAR_WRITEO(enp, FR_AB_GPIO_CTL_REG, &oword);
110
111 /* Clear the SRAM contents */
112 if ((rc = falcon_sram_reset(enp)) != 0)
113 goto fail1;
114
115 /* Initialize the buffer table */
116 EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 1);
117 EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword);
118
119 /* Initialize the transmit descriptor cache */
120 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_TX_DC_BASE_ADR, tx_base);
121 EFX_BAR_WRITEO(enp, FR_AZ_SRM_TX_DC_CFG_REG, &oword);
122
123 EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DC_SIZE, 1); /* 16 descriptors */
124 EFX_BAR_WRITEO(enp, FR_AZ_TX_DC_CFG_REG, &oword);
125
126 /* Initialize the receive descriptor cache */
127 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_RX_DC_BASE_ADR, rx_base);
128 EFX_BAR_WRITEO(enp, FR_AZ_SRM_RX_DC_CFG_REG, &oword);
129
130 EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_SIZE, 3); /* 64 descriptors */
131 EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_CFG_REG, &oword);
132
133 /* Set receive descriptor pre-fetch low water mark */
134 EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_PF_LWM, 56);
135 EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_PF_WM_REG, &oword);
136
137 /* Set the event queue to use for SRAM updates */
138 EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_UPD_EVQ_ID, 0);
139 EFX_BAR_WRITEO(enp, FR_AZ_SRM_UPD_EVQ_REG, &oword);
140
141 return (0);
142
143 fail1:
144 EFSYS_PROBE1(fail1, int, rc);
145
146 return (rc);
147 }
148
149 #if EFSYS_OPT_DIAG
150
151 __checkReturn int
152 falcon_sram_test(
153 __in efx_nic_t *enp,
154 __in efx_sram_pattern_fn_t func)
155 {
156 efx_qword_t qword;
157 efx_qword_t verify;
158 size_t rows = 0x1000;
159 unsigned int rptr;
160 unsigned int wptr;
161 int rc;
162
163 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
164
165 /*
166 * Write the pattern through the SRAM debug aperture. Write
167 * in 64 entry batches, waiting 1us in between each batch
168 * to guarantee not to overflow the SRAM fifo
169 */
170 for (wptr = 0, rptr = 0; wptr < rows; ++wptr) {
171 func(wptr, B_FALSE, &qword);
172 EFX_BAR_TBL_WRITEQ(enp, FR_AZ_SRM_DBG_REG, wptr, &qword);
173
174 if ((wptr - rptr) < 64 && wptr < rows - 1)
175 continue;
176
177 EFSYS_SPIN(1);
178
179 for (; rptr <= wptr; ++rptr) {
180 func(rptr, B_FALSE, &qword);
181 EFX_BAR_TBL_READQ(enp, FR_AZ_SRM_DBG_REG, rptr,
182 &verify);
183
184 if (!EFX_QWORD_IS_EQUAL(verify, qword)) {
185 rc = EFAULT;
186 goto fail1;
187 }
188 }
189 }
190
191 /* And do the same negated */
192 for (wptr = 0, rptr = 0; wptr < rows; ++wptr) {
193 func(wptr, B_TRUE, &qword);
194 EFX_BAR_TBL_WRITEQ(enp, FR_AZ_SRM_DBG_REG, wptr, &qword);
195
196 if ((wptr - rptr) < 64 && wptr < rows - 1)
197 continue;
198
199 EFSYS_SPIN(1);
200
201 for (; rptr <= wptr; ++rptr) {
202 func(rptr, B_TRUE, &qword);
203 EFX_BAR_TBL_READQ(enp, FR_AZ_SRM_DBG_REG, rptr,
204 &verify);
205
206 if (!EFX_QWORD_IS_EQUAL(verify, qword)) {
207 rc = EFAULT;
208 goto fail2;
209 }
210 }
211 }
212
213 return (0);
214
215 fail2:
216 EFSYS_PROBE(fail2);
217 fail1:
218 EFSYS_PROBE1(fail1, int, rc);
219
220 return (rc);
221 }
222
223 #endif /* EFSYS_OPT_DIAG */
224
225 void
226 falcon_sram_fini(
227 __in efx_nic_t *enp)
228 {
229 efx_oword_t oword;
230
231 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
232 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
233
234 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
235 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
236 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
237
238 /* Allow the GPIO1 pin to float */
239 EFX_BAR_READO(enp, FR_AB_GPIO_CTL_REG, &oword);
240 EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO1_OEN, 0);
241 EFX_BAR_WRITEO(enp, FR_AB_GPIO_CTL_REG, &oword);
242 }
243
244 #endif /* EFS_OPT_FALCON */