1 /*
2 * Copyright 2008-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 #include "falcon_gmac.h"
32 #include "falcon_stats.h"
33
34 #if EFSYS_OPT_MAC_FALCON_GMAC
35
36 __checkReturn int
37 falcon_gmac_reset(
38 __in efx_nic_t *enp)
39 {
40 efx_port_t *epp = &(enp->en_port);
41 efx_oword_t oword;
42 int rc;
43
44 EFSYS_ASSERT3U(epp->ep_mac_type, ==, EFX_MAC_FALCON_GMAC);
45
46 EFSYS_PROBE(reset);
47
48 /* Ensure that the GMAC registers are accessible */
49 EFX_BAR_READO(enp, FR_AB_NIC_STAT_REG, &oword);
50 EFX_SET_OWORD_FIELD(oword, FRF_BB_EE_STRAP_EN, 1);
51 EFX_SET_OWORD_FIELD(oword, FRF_BB_EE_STRAP, 0x3);
52 EFX_BAR_WRITEO(enp, FR_AB_NIC_STAT_REG, &oword);
53
54 if ((rc = falcon_mac_wrapper_disable(enp)) != 0)
55 goto fail1;
56
57 enp->en_reset_flags |= EFX_RESET_MAC;
58
59 return (0);
60
61 fail1:
62 EFSYS_PROBE1(fail1, int, rc);
63
64 return (rc);
65 }
66
67 static void
68 falcon_gmac_core_reconfigure(
69 __in efx_nic_t *enp)
70 {
71 efx_port_t *epp = &(enp->en_port);
72 efx_oword_t oword;
73 boolean_t full_duplex;
74 boolean_t byte_mode;
75
76 full_duplex = (epp->ep_link_mode == EFX_LINK_100FDX ||
77 epp->ep_link_mode == EFX_LINK_1000FDX);
78 byte_mode = (epp->ep_link_mode == EFX_LINK_1000HDX ||
79 epp->ep_link_mode == EFX_LINK_1000FDX);
80 #if EFSYS_OPT_LOOPBACK
81 byte_mode |= (epp->ep_loopback_type == EFX_LOOPBACK_GMAC);
82
83 EFX_POPULATE_OWORD_5(oword,
84 FRF_AB_GM_LOOP,
85 (epp->ep_loopback_type == EFX_LOOPBACK_GMAC) ? 1 : 0,
86 FRF_AB_GM_TX_EN, 1,
87 FRF_AB_GM_TX_FC_EN, (epp->ep_fcntl & EFX_FCNTL_GENERATE) ? 1 : 0,
88 FRF_AB_GM_RX_EN, 1,
89 FRF_AB_GM_RX_FC_EN, (epp->ep_fcntl & EFX_FCNTL_RESPOND) ? 1 : 0);
90
91 #else /* EFSYS_OPT_LOOPBACK */
92
93 EFX_POPULATE_OWORD_4(oword,
94 FRF_AB_GM_TX_EN, 1,
95 FRF_AB_GM_TX_FC_EN, (epp->ep_fcntl & EFX_FCNTL_GENERATE) ? 1 : 0,
96 FRF_AB_GM_RX_EN, 1,
97 FRF_AB_GM_RX_FC_EN, (epp->ep_fcntl & EFX_FCNTL_RESPOND) ? 1 : 0);
98
99 #endif /* EFSYS_OPT_LOOPBACK */
100
101 EFX_BAR_WRITEO(enp, FR_AB_GM_CFG1_REG, &oword);
102 EFSYS_SPIN(10);
103
104 EFX_POPULATE_OWORD_4(oword,
105 FRF_AB_GM_IF_MODE, (byte_mode) ?
106 FRF_AB_GM_IF_MODE_BYTE_MODE : FRF_AB_GM_IF_MODE_NIBBLE_MODE,
107 FRF_AB_GM_PAD_CRC_EN, 1,
108 FRF_AB_GM_FD, full_duplex ? 1 : 0,
109 FRF_AB_GM_PAMBL_LEN, 7);
110
111 EFX_BAR_WRITEO(enp, FR_AB_GM_CFG2_REG, &oword);
112 EFSYS_SPIN(10);
113
114 EFX_POPULATE_OWORD_1(oword, FRF_AB_GM_MAX_FLEN, epp->ep_mac_pdu);
115
116 EFX_BAR_WRITEO(enp, FR_AB_GM_MAX_FLEN_REG, &oword);
117 EFSYS_SPIN(10);
118
119 EFX_POPULATE_OWORD_5(oword,
120 FRF_AB_GMF_FTFENREQ, 1,
121 FRF_AB_GMF_STFENREQ, 1,
122 FRF_AB_GMF_FRFENREQ, 1,
123 FRF_AB_GMF_SRFENREQ, 1,
124 FRF_AB_GMF_WTMENREQ, 1);
125
126 EFX_BAR_WRITEO(enp, FR_AB_GMF_CFG0_REG, &oword);
127 EFSYS_SPIN(10);
128
129 EFX_POPULATE_OWORD_2(oword,
130 FRF_AB_GMF_CFGFRTH, 0x12,
131 FRF_AB_GMF_CFGXOFFRTX, 0xffff);
132
133 EFX_BAR_WRITEO(enp, FR_AB_GMF_CFG1_REG, &oword);
134 EFSYS_SPIN(10);
135
136 EFX_POPULATE_OWORD_2(oword,
137 FRF_AB_GMF_CFGHWM, 0x3f,
138 FRF_AB_GMF_CFGLWM, 0x0a);
139
140 EFX_BAR_WRITEO(enp, FR_AB_GMF_CFG2_REG, &oword);
141 EFSYS_SPIN(10);
142
143 EFX_POPULATE_OWORD_2(oword,
144 FRF_AB_GMF_CFGHWMFT, 0x1c,
145 FRF_AB_GMF_CFGFTTH, 0x08);
146
147 EFX_BAR_WRITEO(enp, FR_AB_GMF_CFG3_REG, &oword);
148 EFSYS_SPIN(10);
149
150 EFX_POPULATE_OWORD_1(oword, FRF_AB_GMF_HSTFLTRFRM, 0x1000);
151
152 EFX_BAR_WRITEO(enp, FR_AB_GMF_CFG4_REG, &oword);
153 EFSYS_SPIN(10);
154
155 EFX_BAR_READO(enp, FR_AB_GMF_CFG5_REG, &oword);
156 EFX_SET_OWORD_FIELD(oword, FRF_AB_GMF_CFGBYTMODE, byte_mode ? 1 : 0);
157 EFX_SET_OWORD_FIELD(oword, FRF_AB_GMF_CFGHDPLX, full_duplex ? 0 : 1);
158 EFX_SET_OWORD_FIELD(oword,
159 FRF_AB_GMF_HSTDRPLT64, full_duplex ? 0 : 1);
160 EFX_SET_OWORD_FIELD(oword, FRF_AB_GMF_HSTFLTRFRMDC, 0x3efff);
161 EFX_BAR_WRITEO(enp, FR_AB_GMF_CFG5_REG, &oword);
162 EFSYS_SPIN(10);
163
164 EFX_POPULATE_OWORD_4(oword,
165 FRF_AB_GM_ADR_B0, epp->ep_mac_addr[5],
166 FRF_AB_GM_ADR_B1, epp->ep_mac_addr[4],
167 FRF_AB_GM_ADR_B2, epp->ep_mac_addr[3],
168 FRF_AB_GM_ADR_B3, epp->ep_mac_addr[2]);
169
170 EFX_BAR_WRITEO(enp, FR_AB_GM_ADR1_REG, &oword);
171 EFSYS_SPIN(10);
172
173 EFX_POPULATE_OWORD_2(oword,
174 FRF_AB_GM_ADR_B4, epp->ep_mac_addr[1],
175 FRF_AB_GM_ADR_B5, epp->ep_mac_addr[0]);
176
177 EFX_BAR_WRITEO(enp, FR_AB_GM_ADR2_REG, &oword);
178 EFSYS_SPIN(10);
179 }
180
181 __checkReturn int
182 falcon_gmac_downlink_check(
183 __in efx_nic_t *enp,
184 __out boolean_t *upp)
185 {
186 efx_port_t *epp = &(enp->en_port);
187
188 _NOTE(ARGUNUSED(upp))
189
190 EFSYS_ASSERT3U(epp->ep_mac_type, ==, EFX_MAC_FALCON_GMAC);
191
192 return (ENOTSUP);
193 }
194
195 __checkReturn int
196 falcon_gmac_reconfigure(
197 __in efx_nic_t *enp)
198 {
199 efx_port_t *epp = &(enp->en_port);
200
201 EFSYS_ASSERT3U(epp->ep_mac_type, ==, EFX_MAC_FALCON_GMAC);
202 EFSYS_ASSERT3U(epp->ep_link_mode, !=, EFX_LINK_10000FDX);
203
204 EFSYS_PROBE(reconfigure);
205
206 falcon_gmac_core_reconfigure(enp);
207 falcon_mac_wrapper_enable(enp);
208
209 return (0);
210 }
211
212 void
213 falcon_gmac_downlink_reset(
214 __in efx_nic_t *enp,
215 __in boolean_t hold)
216 {
217 _NOTE(ARGUNUSED(enp, hold))
218 }
219
220 #if EFSYS_OPT_MAC_STATS
221 static uint32_t
222 falcon_gmac_stat_read(
223 __in efsys_mem_t *esmp,
224 __in unsigned int offset,
225 __in unsigned int width)
226 {
227 uint32_t val;
228
229 switch (width) {
230 case 2: {
231 efx_dword_t dword;
232
233 EFSYS_MEM_READD(esmp, offset, &dword);
234
235 val = (uint16_t)EFX_DWORD_FIELD(dword, EFX_WORD_0);
236 break;
237 }
238 case 4: {
239 efx_dword_t dword;
240
241 EFSYS_MEM_READD(esmp, offset, &dword);
242
243 val = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
244 break;
245 }
246 case 6: {
247 efx_qword_t qword;
248
249 EFSYS_MEM_READQ(esmp, offset, &qword);
250
251 val = EFX_QWORD_FIELD(qword, EFX_DWORD_0);
252 break;
253 }
254 default:
255 EFSYS_ASSERT(B_FALSE);
256
257 val = 0;
258 break;
259 }
260
261 return (val);
262 }
263
264 #define GMAC_STAT_READ(_esmp, _id) \
265 falcon_gmac_stat_read((_esmp), G_STAT_OFFSET(_id), \
266 G_STAT_WIDTH(_id))
267
268 #define GMAC_STAT_INCR(_esmp, _stat, _id) \
269 do { \
270 delta = GMAC_STAT_READ(_esmp, _id); \
271 EFSYS_STAT_INCR(&(_stat), delta); \
272 _NOTE(CONSTANTCONDITION) \
273 } while (0)
274
275 #define GMAC_STAT_DECR(_esmp, _stat, _id) \
276 do { \
277 delta = GMAC_STAT_READ(_esmp, _id); \
278 EFSYS_STAT_DECR(&(_stat), delta); \
279 _NOTE(CONSTANTCONDITION) \
280 } while (0)
281
282 __checkReturn int
283 falcon_gmac_stats_update(
284 __in efx_nic_t *enp,
285 __in efsys_mem_t *esmp,
286 __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat,
287 __out_opt uint32_t *generationp)
288 {
289 efx_port_t *epp = &(enp->en_port);
290 efx_oword_t oword;
291 uint32_t delta;
292
293 _NOTE(ARGUNUSED(generationp));
294 EFSYS_ASSERT3U(epp->ep_mac_type, ==, EFX_MAC_FALCON_GMAC);
295
296 /* Check the DMA flag */
297 if (GMAC_STAT_READ(esmp, DMA_DONE) != DMA_IS_DONE)
298 return (EAGAIN);
299 EFSYS_MEM_READ_BARRIER();
300
301 /* RX */
302 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_OCTETS], RX_GOOD_OCT);
303 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_OCTETS], RX_BAD_OCT);
304
305 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PKTS], RX_GOOD_LT_64_PKT);
306 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PKTS], RX_64_PKT);
307 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PKTS], RX_65_TO_127_PKT);
308 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PKTS], RX_128_TO_255_PKT);
309 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PKTS], RX_256_TO_511_PKT);
310 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PKTS], RX_512_TO_1023_PKT);
311 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PKTS], RX_1024_TO_15XX_PKT);
312 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PKTS], RX_15XX_TO_JUMBO_PKT);
313 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PKTS], RX_GT_JUMBO_PKT);
314
315 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_UNICST_PKTS], RX_UCAST_PKT);
316 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_MULTICST_PKTS], RX_MCAST_PKT);
317 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_BRDCST_PKTS], RX_BCAST_PKT);
318 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PAUSE_PKTS], RX_PAUSE_PKT);
319
320 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_LE_64_PKTS], RX_GOOD_LT_64_PKT);
321 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_LE_64_PKTS], RX_BAD_LT_64_PKT);
322 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_LE_64_PKTS], RX_64_PKT);
323 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_65_TO_127_PKTS],
324 RX_65_TO_127_PKT);
325 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_128_TO_255_PKTS],
326 RX_128_TO_255_PKT);
327 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_256_TO_511_PKTS],
328 RX_256_TO_511_PKT);
329 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_512_TO_1023_PKTS],
330 RX_512_TO_1023_PKT);
331 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_1024_TO_15XX_PKTS],
332 RX_1024_TO_15XX_PKT);
333 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_GE_15XX_PKTS],
334 RX_15XX_TO_JUMBO_PKT);
335 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_GE_15XX_PKTS], RX_GT_JUMBO_PKT);
336
337 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_ERRORS], RX_BAD_PKT);
338 GMAC_STAT_DECR(esmp, stat[EFX_MAC_RX_ERRORS], RX_PAUSE_PKT);
339 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_FCS_ERRORS],
340 RX_FCS_ERR_64_TO_15XX_PKT);
341 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_FCS_ERRORS],
342 RX_FCS_ERR_15XX_TO_JUMBO_PKT);
343 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_FCS_ERRORS],
344 RX_FCS_ERR_GT_JUMBO_PKT);
345 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_DROP_EVENTS], RX_MISS_PKT);
346 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_FALSE_CARRIER_ERRORS],
347 RX_FALSE_CRS);
348
349 EFX_BAR_READO(enp, FR_AZ_RX_NODESC_DROP_REG, &oword);
350 delta = (uint32_t)EFX_OWORD_FIELD(oword, FRF_AZ_RX_NODESC_DROP_CNT);
351 EFSYS_STAT_INCR(&(stat[EFX_MAC_RX_NODESC_DROP_CNT]), delta);
352
353 /* TX */
354 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_OCTETS], TX_GOOD_BAD_OCT);
355
356 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PKTS], TX_LT_64_PKT);
357 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PKTS], TX_64_PKT);
358 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PKTS], TX_65_TO_127_PKT);
359 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PKTS], TX_128_TO_255_PKT);
360 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PKTS], TX_256_TO_511_PKT);
361 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PKTS], TX_512_TO_1023_PKT);
362 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PKTS], TX_1024_TO_15XX_PKT);
363 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PKTS], TX_15XX_TO_JUMBO_PKT);
364 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PKTS], TX_GT_JUMBO_PKT);
365
366 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_UNICST_PKTS], TX_UCAST_PKT);
367 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_MULTICST_PKTS], TX_MCAST_PKT);
368 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_BRDCST_PKTS], TX_BCAST_PKT);
369 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PAUSE_PKTS], TX_PAUSE_PKT);
370 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_LE_64_PKTS], TX_LT_64_PKT);
371 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_LE_64_PKTS], TX_64_PKT);
372
373 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_65_TO_127_PKTS],
374 TX_65_TO_127_PKT);
375 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_128_TO_255_PKTS],
376 TX_128_TO_255_PKT);
377 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_256_TO_511_PKTS],
378 TX_256_TO_511_PKT);
379 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_512_TO_1023_PKTS],
380 TX_512_TO_1023_PKT);
381 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_1024_TO_15XX_PKTS],
382 TX_1024_TO_15XX_PKT);
383 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_GE_15XX_PKTS],
384 TX_15XX_TO_JUMBO_PKT);
385 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_GE_15XX_PKTS],
386 TX_GT_JUMBO_PKT);
387
388 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_ERRORS], TX_BAD_PKT);
389 GMAC_STAT_DECR(esmp, stat[EFX_MAC_TX_ERRORS], TX_PAUSE_PKT);
390
391 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_SGL_COL_PKTS], TX_SGL_COL_PKT);
392 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_MULT_COL_PKTS], TX_MULT_COL_PKT);
393 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_EX_COL_PKTS], TX_EX_COL_PKT);
394 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_LATE_COL_PKTS], TX_LATE_COL);
395 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_DEF_PKTS], TX_DEF_PKT);
396 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_EX_DEF_PKTS], TX_EX_DEF_PKT);
397
398 return (0);
399 }
400
401 #endif /* EFSYS_OPT_MAC_STATS */
402
403 #endif /* EFSYS_OPT_MAC_FALCON_GMAC */