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 "falcon_nvram.h"
29 #include "efx_types.h"
30 #include "efx_regs.h"
31 #include "efx_regs_pci.h"
32 #include "efx_impl.h"
33
34 #if EFSYS_OPT_FALCON
35
36 #if EFSYS_OPT_MAC_FALCON_XMAC
37 #include "falcon_xmac.h"
38 #endif
39
40 #if EFSYS_OPT_MAC_FALCON_GMAC
41 #include "falcon_gmac.h"
42 #endif
43
44 #if EFSYS_OPT_MON_LM87
45 #include "lm87.h"
46 #endif
47
48 #if EFSYS_OPT_MON_MAX6647
49 #include "max6647.h"
50 #endif
51
52 #if EFSYS_OPT_PHY_NULL
53 #include "nullphy.h"
54 #endif
55
56 #if EFSYS_OPT_PHY_QT2022C2
57 #include "qt2022c2.h"
58 #endif
59
60 #if EFSYS_OPT_PHY_SFX7101
61 #include "sfx7101.h"
62 #endif
63
64 #if EFSYS_OPT_PHY_TXC43128
65 #include "txc43128.h"
66 #endif
67
68 #if EFSYS_OPT_PHY_SFT9001
69 #include "sft9001.h"
70 #endif
71
72 #if EFSYS_OPT_PHY_QT2025C
73 #include "qt2025c.h"
74 #endif
75
76 static __checkReturn int
77 falcon_nic_cfg_raw_read(
78 __in efx_nic_t *enp,
79 __in uint32_t offset,
80 __in uint32_t size,
81 __out void *cfg)
82 {
83 EFSYS_ASSERT3U(offset + size, <=, FALCON_NIC_CFG_RAW_SZ);
84
85 #if EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE
86 if (enp->en_u.falcon.enu_forced_cfg != NULL) {
87 memcpy(cfg, enp->en_u.falcon.enu_forced_cfg + offset, size);
88 return (0);
89 }
90 #endif /* EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE */
91
92 return falcon_spi_dev_read(enp, FALCON_SPI_FLASH, offset,
93 (caddr_t)cfg, size);
94 }
95
96 __checkReturn int
97 falcon_nic_cfg_raw_read_verify(
98 __in efx_nic_t *enp,
99 __in uint32_t offset,
100 __in uint32_t size,
101 __out uint8_t *cfg)
102 {
103 uint32_t csum_offset;
104 uint16_t magic, version, cksum;
105 int rc;
106 efx_word_t word;
107
108 if ((rc = falcon_nic_cfg_raw_read(enp, CFG_MAGIC_REG_SF_OFST,
109 sizeof (word), &word)) != 0)
110 goto fail1;
111
112 magic = EFX_WORD_FIELD(word, MAGIC);
113
114 if ((rc = falcon_nic_cfg_raw_read(enp, CFG_VERSION_REG_SF_OFST,
115 sizeof (word), &word)) != 0)
116 goto fail2;
117
118 version = EFX_WORD_FIELD(word, VERSION);
119
120 cksum = 0;
121 for (csum_offset = (version < 4) ? CFG_MAGIC_REG_SF_OFST : 0;
122 csum_offset < FALCON_NIC_CFG_RAW_SZ;
123 csum_offset += sizeof (efx_word_t)) {
124
125 if ((rc = falcon_nic_cfg_raw_read(enp, csum_offset,
126 sizeof (word), &word)) != 0)
127 goto fail3;
128
129 cksum += EFX_WORD_FIELD(word, EFX_WORD_0);
130 }
131 if (magic != MAGIC_DECODE || version < 2 || cksum != 0xffff) {
132 rc = EINVAL;
133 goto fail4;
134 }
135
136 if ((rc = falcon_nic_cfg_raw_read(enp, offset, size, cfg)) != 0)
137 goto fail5;
138
139 return (0);
140
141 fail5:
142 EFSYS_PROBE(fail5);
143 fail4:
144 EFSYS_PROBE(fail4);
145 fail3:
146 EFSYS_PROBE(fail3);
147 fail2:
148 EFSYS_PROBE(fail2);
149 fail1:
150 EFSYS_PROBE1(fail1, int, rc);
151
152 return (rc);
153 }
154
155 __checkReturn int
156 falcon_nic_probe(
157 __in efx_nic_t *enp)
158 {
159 efx_port_t *epp = &(enp->en_port);
160 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
161 int rc;
162
163 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
164
165 /* Initialise the nvram */
166 if ((rc = falcon_nvram_init(enp)) != 0)
167 goto fail1;
168
169 /* Probe the board configuration */
170 if ((rc = falcon_nic_cfg_build(enp, encp)) != 0)
171 goto fail2;
172 epp->ep_adv_cap_mask = epp->ep_default_adv_cap_mask;
173
174 return (0);
175
176 fail2:
177 EFSYS_PROBE(fail2);
178 fail1:
179 EFSYS_PROBE1(fail1, int, rc);
180
181 return (rc);
182 }
183
184 #define FALCON_NIC_CFG_BUILD_LOWEST_REG \
185 MIN(CFG_BOARD_REV_REG_SF_OFST, \
186 MIN(CFG_BOARD_TYPE_REG_SF_OFST, \
187 MIN(CFG_PHY_PORT_REG_SF_OFST, \
188 MIN(CFG_PHY_TYPE_REG_SF_OFST, \
189 MIN(MAC_ADDRESS_SF_OFST, \
190 MIN(NIC_STAT_SF_OFST, \
191 SRAM_CFG_SF_OFST))))))
192
193
194 #define FALCON_NIC_CFG_BUILD_HIGHEST_REG \
195 MAX(CFG_BOARD_REV_REG_SF_OFST + 1, \
196 MAX(CFG_BOARD_TYPE_REG_SF_OFST + 1, \
197 MAX(CFG_PHY_PORT_REG_SF_OFST + 1, \
198 MAX(CFG_PHY_TYPE_REG_SF_OFST + 1, \
199 MAX(MAC_ADDRESS_SF_OFST + 6, \
200 MAX(NIC_STAT_SF_OFST + 16, \
201 SRAM_CFG_SF_OFST + 16))))))
202
203 #define FALCON_NIC_CFG_BUILD_NEEDED_CFG_SIZE \
204 (FALCON_NIC_CFG_BUILD_HIGHEST_REG - \
205 FALCON_NIC_CFG_BUILD_LOWEST_REG)
206
207 __checkReturn int
208 falcon_nic_cfg_build(
209 __in efx_nic_t *enp,
210 __out efx_nic_cfg_t *encp)
211 {
212 efx_port_t *epp = &(enp->en_port);
213 uint8_t cfg[FALCON_NIC_CFG_BUILD_NEEDED_CFG_SIZE];
214 uint8_t *origin = cfg - FALCON_NIC_CFG_BUILD_LOWEST_REG;
215 efx_oword_t *owordp;
216 uint8_t major;
217 uint8_t minor;
218 int rc;
219
220 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
221
222 (void) memset(encp, 0, sizeof (efx_nic_cfg_t));
223
224 if ((rc = falcon_nic_cfg_raw_read_verify(enp,
225 FALCON_NIC_CFG_BUILD_LOWEST_REG,
226 FALCON_NIC_CFG_BUILD_NEEDED_CFG_SIZE, cfg)) != 0)
227 goto fail1;
228
229 encp->enc_board_type = EFX_BYTE_FIELD(
230 ((efx_byte_t *)origin)[CFG_BOARD_TYPE_REG_SF_OFST],
231 EFX_BYTE_0);
232
233 /* Read board revision */
234 major = EFX_BYTE_FIELD(
235 ((efx_byte_t *)origin)[CFG_BOARD_REV_REG_SF_OFST],
236 BOARD_REV_MAJOR);
237 minor = EFX_BYTE_FIELD(
238 ((efx_byte_t *)origin)[CFG_BOARD_REV_REG_SF_OFST],
239 BOARD_REV_MINOR);
240 enp->en_u.falcon.enu_board_rev = (major << 4) | minor;
241
242 /* Sram mode */
243 owordp = (efx_oword_t *)(origin + NIC_STAT_SF_OFST);
244 enp->en_u.falcon.enu_internal_sram =
245 EFX_OWORD_FIELD(*owordp, FRF_AB_ONCHIP_SRAM) != 0;
246 if (enp->en_u.falcon.enu_internal_sram) {
247 enp->en_u.falcon.enu_sram_num_bank = 0;
248 enp->en_u.falcon.enu_sram_bank_size = 0;
249
250 /* Resource limits */
251 encp->enc_evq_limit = 64; /* Interrupt-capable */
252 encp->enc_txq_limit = 512;
253 encp->enc_rxq_limit = 384;
254 encp->enc_buftbl_limit = 4096;
255 } else {
256 uint32_t sram_rows;
257
258 owordp = (efx_oword_t *)(origin + SRAM_CFG_SF_OFST);
259 enp->en_u.falcon.enu_sram_num_bank =
260 (uint8_t)EFX_OWORD_FIELD(*owordp, FRF_AZ_SRM_NUM_BANK);
261 enp->en_u.falcon.enu_sram_bank_size =
262 (uint8_t)EFX_OWORD_FIELD(*owordp, FRF_AZ_SRM_BANK_SIZE);
263 sram_rows = (enp->en_u.falcon.enu_sram_num_bank + 1)
264 << (18 + enp->en_u.falcon.enu_sram_bank_size);
265
266 /* Resource limits */
267 encp->enc_evq_limit = 64; /* Interrupt-capable */
268 encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET;
269 encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET;
270 encp->enc_buftbl_limit = sram_rows -
271 (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE) +
272 encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
273 }
274
275 encp->enc_clk_mult = 1;
276 encp->enc_evq_timer_quantum_ns =
277 EFX_EVQ_FALCON_TIMER_QUANTUM_NS / encp->enc_clk_mult;
278 encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
279 FRF_AB_TIMER_VAL_WIDTH) / 1000;
280
281 /* Determine system monitor configuration */
282 switch (encp->enc_board_type) {
283 #if EFSYS_OPT_MON_LM87
284 case BOARD_TYPE_SFE4002_DECODE:
285 case BOARD_TYPE_SFE4003_DECODE:
286 case BOARD_TYPE_SFE4005_DECODE:
287 case BOARD_TYPE_SFN4112F_DECODE:
288 encp->enc_mon_type = EFX_MON_LM87;
289 enp->en_u.falcon.enu_mon_devid = LM87_DEVID;
290 #if EFSYS_OPT_MON_STATS
291 encp->enc_mon_stat_mask = LM87_STAT_MASK;
292 #endif
293 break;
294 #endif /* EFSYS_OPT_MON_LM87 */
295
296 #if EFSYS_OPT_MON_MAX6647
297 case BOARD_TYPE_SFE4001_DECODE:
298 encp->enc_mon_type = EFX_MON_MAX6647;
299 enp->en_u.falcon.enu_mon_devid = MAX6647_DEVID;
300 #if EFSYS_OPT_MON_STATS
301 encp->enc_mon_stat_mask = MAX6647_STAT_MASK;
302 #endif
303 break;
304 #endif /* EFSYS_OPT_MON_MAX6647 */
305
306 #if EFSYS_OPT_MON_MAX6647
307 case BOARD_TYPE_SFN4111T_DECODE:
308 encp->enc_mon_type = EFX_MON_MAX6647;
309 #if EFSYS_OPT_MON_STATS
310 encp->enc_mon_stat_mask = MAX6647_STAT_MASK;
311 #endif
312 /*
313 * MAX6646 chips are identical to MAX6647 chips in every way
314 * that matters to the driver so we pretend that the chip
315 * is always a MAX6647, but adjust the identifier accordingly
316 */
317 enp->en_u.falcon.enu_mon_devid = (major == 0 && minor < 5) ?
318 MAX6647_DEVID : MAX6646_DEVID;
319 break;
320 #endif /* EFSYS_OPT_MON_MAX6647 */
321
322 default:
323 encp->enc_mon_type = EFX_MON_NULL;
324 enp->en_u.falcon.enu_mon_devid = 0;
325 #if EFSYS_OPT_MON_STATS
326 encp->enc_mon_stat_mask = 0;
327 #endif
328 break;
329 }
330
331 /* Copy the feature flags */
332 encp->enc_features = enp->en_features;
333
334 /* Read PHY MII prt and type, and mac address */
335 encp->enc_port = EFX_BYTE_FIELD(
336 ((efx_byte_t *)origin)[CFG_PHY_PORT_REG_SF_OFST], EFX_BYTE_0);
337 encp->enc_phy_type = EFX_BYTE_FIELD(
338 ((efx_byte_t *)origin)[CFG_PHY_TYPE_REG_SF_OFST], EFX_BYTE_0);
339
340 EFX_MAC_ADDR_COPY(encp->enc_mac_addr, origin + MAC_ADDRESS_SF_OFST);
341
342 /* Populate phy capabalities */
343 EFX_STATIC_ASSERT(EFX_PHY_NULL == PHY_TYPE_NONE_DECODE);
344 EFX_STATIC_ASSERT(EFX_PHY_TXC43128 == PHY_TYPE_TXC43128_DECODE);
345 EFX_STATIC_ASSERT(EFX_PHY_SFX7101 == PHY_TYPE_SFX7101_DECODE);
346 EFX_STATIC_ASSERT(EFX_PHY_QT2022C2 == PHY_TYPE_QT2022C2_DECODE);
347 EFX_STATIC_ASSERT(EFX_PHY_SFT9001A == PHY_TYPE_SFT9001A_DECODE);
348 EFX_STATIC_ASSERT(EFX_PHY_QT2025C == PHY_TYPE_QT2025C_DECODE);
349 EFX_STATIC_ASSERT(EFX_PHY_SFT9001B == PHY_TYPE_SFT9001B_DECODE);
350
351 switch (encp->enc_phy_type) {
352 #if EFSYS_OPT_PHY_NULL
353 case PHY_TYPE_NONE_DECODE:
354 epp->ep_fixed_port_type = EFX_PHY_MEDIA_XAUI;
355 epp->ep_default_adv_cap_mask = NULLPHY_ADV_CAP_MASK;
356 epp->ep_phy_cap_mask =
357 NULLPHY_ADV_CAP_MASK | NULLPHY_ADV_CAP_PERM;
358 #if EFSYS_OPT_NAMES
359 (void) strncpy(encp->enc_phy_name, "nullphy",
360 sizeof (encp->enc_phy_name));
361 #endif /* EFSYS_OPT_NAMES */
362 #if EFSYS_OPT_PHY_LED_CONTROL
363 encp->enc_led_mask = NULLPHY_LED_MASK;
364 #endif /* EFSYS_OPT_PHY_LED_CONTROL */
365 #if EFSYS_OPT_LOOPBACK
366 encp->enc_loopback_types[EFX_LINK_10000FDX] =
367 NULLPHY_LOOPBACK_MASK;
368 #endif /* EFSYS_OPT_LOOPBACK */
369 #if EFSYS_OPT_PHY_STATS
370 encp->enc_phy_stat_mask = NULLPHY_STAT_MASK;
371 #endif /* EFSYS_OPT_PHY_STATS */
372 #if EFSYS_OPT_PHY_PROPS
373 encp->enc_phy_nprops = NULLPHY_NPROPS;
374 #endif /* EFSYS_OPT_PHY_PROPS */
375 #if EFSYS_OPT_PHY_BIST
376 encp->enc_bist_mask = NULLPHY_BIST_MASK;
377 #endif /* EFSYS_OPT_PHY_BIST */
378 break;
379 #endif /* EFSYS_OPT_PHY_NULL */
380
381 #if EFSYS_OPT_PHY_QT2022C2
382 case PHY_TYPE_QT2022C2_DECODE:
383 epp->ep_fixed_port_type = EFX_PHY_MEDIA_XFP;
384 epp->ep_default_adv_cap_mask = QT2022C2_ADV_CAP_MASK;
385 epp->ep_phy_cap_mask =
386 QT2022C2_ADV_CAP_MASK | QT2022C2_ADV_CAP_PERM;
387 #if EFSYS_OPT_NAMES
388 (void) strncpy(encp->enc_phy_name, "qt2022c2",
389 sizeof (encp->enc_phy_name));
390 #endif /* EFSYS_OPT_NAMES */
391 #if EFSYS_OPT_PHY_LED_CONTROL
392 encp->enc_led_mask = QT2022C2_LED_MASK;
393 #endif /* EFSYS_OPT_PHY_LED_CONTROL */
394 #if EFSYS_OPT_LOOPBACK
395 encp->enc_loopback_types[EFX_LINK_10000FDX] =
396 QT2022C2_LOOPBACK_MASK;
397 #endif /* EFSYS_OPT_LOOPBACK */
398 #if EFSYS_OPT_PHY_STATS
399 encp->enc_phy_stat_mask = QT2022C2_STAT_MASK;
400 #endif /* EFSYS_OPT_PHY_STATS */
401 #if EFSYS_OPT_PHY_PROPS
402 encp->enc_phy_nprops = QT2022C2_NPROPS;
403 #endif /* EFSYS_OPT_PHY_PROPS */
404 #if EFSYS_OPT_PHY_BIST
405 encp->enc_bist_mask = QT2022C2_BIST_MASK;
406 #endif /* EFSYS_OPT_PHY_BIST */
407 break;
408 #endif /* EFSYS_OPT_PHY_QT2022C2 */
409
410 #if EFSYS_OPT_PHY_SFX7101
411 case PHY_TYPE_SFX7101_DECODE:
412 epp->ep_fixed_port_type = EFX_PHY_MEDIA_BASE_T;
413 epp->ep_default_adv_cap_mask = SFX7101_ADV_CAP_MASK;
414 epp->ep_phy_cap_mask =
415 SFX7101_ADV_CAP_MASK | SFX7101_ADV_CAP_PERM;
416 #if EFSYS_OPT_NAMES
417 (void) strncpy(encp->enc_phy_name, "sfx7101",
418 sizeof (encp->enc_phy_name));
419 #endif /* EFSYS_OPT_NAMES */
420 #if EFSYS_OPT_PHY_LED_CONTROL
421 encp->enc_led_mask = SFX7101_LED_MASK;
422 #endif /* EFSYS_OPT_PHY_LED_CONTROL */
423 #if EFSYS_OPT_LOOPBACK
424 encp->enc_loopback_types[EFX_LINK_10000FDX] =
425 SFX7101_LOOPBACK_MASK;
426 #endif /* EFSYS_OPT_LOOPBACK */
427 #if EFSYS_OPT_PHY_STATS
428 encp->enc_phy_stat_mask = SFX7101_STAT_MASK;
429 #endif /* EFSYS_OPT_PHY_STATS */
430 #if EFSYS_OPT_PHY_PROPS
431 encp->enc_phy_nprops = SFX7101_NPROPS;
432 #endif /* EFSYS_OPT_PHY_PROPS */
433 #if EFSYS_OPT_PHY_BIST
434 encp->enc_bist_mask = SFX7101_BIST_MASK;
435 #endif /* EFSYS_OPT_PHY_BIST */
436 break;
437 #endif /* EFSYS_OPT_PHY_SFX7101 */
438
439 #if EFSYS_OPT_PHY_TXC43128
440 case PHY_TYPE_TXC43128_DECODE:
441 epp->ep_fixed_port_type = EFX_PHY_MEDIA_CX4;
442 epp->ep_default_adv_cap_mask = TXC43128_ADV_CAP_MASK;
443 epp->ep_phy_cap_mask =
444 TXC43128_ADV_CAP_MASK | TXC43128_ADV_CAP_PERM;
445 #if EFSYS_OPT_NAMES
446 (void) strncpy(encp->enc_phy_name, "txc43128",
447 sizeof (encp->enc_phy_name));
448 #endif /* EFSYS_OPT_NAMES */
449 #if EFSYS_OPT_PHY_LED_CONTROL
450 encp->enc_led_mask = TXC43128_LED_MASK;
451 #endif /* EFSYS_OPT_PHY_LED_CONTROL */
452 #if EFSYS_OPT_LOOPBACK
453 encp->enc_loopback_types[EFX_LINK_10000FDX] =
454 TXC43128_LOOPBACK_MASK;
455 #endif /* EFSYS_OPT_LOOPBACK */
456 #if EFSYS_OPT_PHY_STATS
457 encp->enc_phy_stat_mask = TXC43128_STAT_MASK;
458 #endif /* EFSYS_OPT_PHY_STATS */
459 #if EFSYS_OPT_PHY_PROPS
460 encp->enc_phy_nprops = TXC43128_NPROPS;
461 #endif /* EFSYS_OPT_PHY_PROPS */
462 #if EFSYS_OPT_PHY_BIST
463 encp->enc_bist_mask = TXC43128_BIST_MASK;
464 #endif /* EFSYS_OPT_PHY_BIST */
465 break;
466 #endif /* EFSYS_OPT_PHY_TXC43128 */
467
468 #if EFSYS_OPT_PHY_SFT9001
469 case PHY_TYPE_SFT9001A_DECODE:
470 case PHY_TYPE_SFT9001B_DECODE:
471 epp->ep_fixed_port_type = EFX_PHY_MEDIA_BASE_T;
472 epp->ep_default_adv_cap_mask = SFT9001_ADV_CAP_MASK;
473 epp->ep_phy_cap_mask =
474 SFT9001_ADV_CAP_MASK | SFT9001_ADV_CAP_PERM;
475 #if EFSYS_OPT_NAMES
476 (void) strncpy(encp->enc_phy_name, "sft9001",
477 sizeof (encp->enc_phy_name));
478 #endif /* EFSYS_OPT_NAMES */
479 #if EFSYS_OPT_PHY_LED_CONTROL
480 encp->enc_led_mask = SFT9001_LED_MASK;
481 #endif /* EFSYS_OPT_PHY_LED_CONTROL */
482 #if EFSYS_OPT_LOOPBACK
483 encp->enc_loopback_types[EFX_LINK_10000FDX] =
484 SFT9001_10G_LOOPBACK_MASK;
485 encp->enc_loopback_types[EFX_LINK_1000FDX] =
486 SFT9001_1G_LOOPBACK_MASK;
487 #endif /* EFSYS_OPT_LOOPBACK */
488 #if EFSYS_OPT_PHY_STATS
489 encp->enc_phy_stat_mask = SFT9001_STAT_MASK;
490 #endif /* EFSYS_OPT_PHY_STATS */
491 #if EFSYS_OPT_PHY_PROPS
492 encp->enc_phy_nprops = SFT9001_NPROPS;
493 #endif /* EFSYS_OPT_PHY_PROPS */
494 #if EFSYS_OPT_PHY_BIST
495 encp->enc_bist_mask = SFT9001_BIST_MASK;
496 #endif /* EFSYS_OPT_PHY_BIST */
497 break;
498 #endif /* EFSYS_OPT_PHY_SFT9001 */
499
500 #if EFSYS_OPT_PHY_QT2025C
501 case EFX_PHY_QT2025C:
502 epp->ep_fixed_port_type = EFX_PHY_MEDIA_SFP_PLUS;
503 epp->ep_default_adv_cap_mask = QT2025C_ADV_CAP_MASK;
504 epp->ep_phy_cap_mask =
505 QT2025C_ADV_CAP_MASK | QT2025C_ADV_CAP_PERM;
506 #if EFSYS_OPT_NAMES
507 (void) strncpy(encp->enc_phy_name, "qt2025c",
508 sizeof (encp->enc_phy_name));
509 #endif /* EFSYS_OPT_NAMES */
510 #if EFSYS_OPT_PHY_LED_CONTROL
511 encp->enc_led_mask = QT2025C_LED_MASK;
512 #endif /* EFSYS_OPT_PHY_LED_CONTROL */
513 #if EFSYS_OPT_LOOPBACK
514 encp->enc_loopback_types[EFX_LINK_10000FDX] =
515 QT2025C_LOOPBACK_MASK;
516 #endif /* EFSYS_OPT_LOOPBACK */
517 #if EFSYS_OPT_PHY_STATS
518 encp->enc_phy_stat_mask = QT2025C_STAT_MASK;
519 #endif /* EFSYS_OPT_PHY_STATS */
520 #if EFSYS_OPT_PHY_PROPS
521 encp->enc_phy_nprops = QT2025C_NPROPS;
522 #endif /* EFSYS_OPT_PHY_PROPS */
523 #if EFSYS_OPT_PHY_BIST
524 encp->enc_bist_mask = QT2025C_BIST_MASK;
525 #endif /* EFSYS_OPT_PHY_BIST */
526 break;
527 #endif /* EFSYS_OPT_PHY_QT2025C */
528
529 default:
530 rc = ENOTSUP;
531 goto fail2;
532 }
533
534 #if EFSYS_OPT_LOOPBACK
535 encp->enc_loopback_types[EFX_LINK_UNKNOWN] =
536 (1 << EFX_LOOPBACK_OFF) |
537 encp->enc_loopback_types[EFX_LINK_1000FDX] |
538 encp->enc_loopback_types[EFX_LINK_10000FDX];
539 #endif /* EFSYS_OPT_LOOPBACK */
540
541 return (0);
542
543 fail2:
544 EFSYS_PROBE(fail2);
545 fail1:
546 EFSYS_PROBE1(fail1, int, rc);
547
548 return (rc);
549 }
550
551 #if EFSYS_OPT_PCIE_TUNE
552
553 static void
554 falcon_nic_pcie_core_read(
555 __in efx_nic_t *enp,
556 __in uint32_t addr,
557 __out efx_dword_t *edp)
558 {
559 int lstate;
560 efx_oword_t oword;
561 uint32_t val;
562
563 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
564
565 EFSYS_LOCK(enp->en_eslp, lstate);
566
567 EFX_POPULATE_OWORD_2(oword, FRF_BB_PCIE_CORE_TARGET_REG_ADRS, addr,
568 FRF_BB_PCIE_CORE_INDIRECT_ACCESS_DIR, 0);
569 EFX_BAR_WRITEO(enp, FR_BB_PCIE_CORE_INDIRECT_REG, &oword);
570
571 EFSYS_SPIN(10);
572
573 EFX_BAR_READO(enp, FR_BB_PCIE_CORE_INDIRECT_REG, &oword);
574 val = EFX_OWORD_FIELD(oword, FRF_BB_PCIE_CORE_TARGET_DATA);
575
576 EFX_POPULATE_DWORD_1(*edp, EFX_DWORD_0, val);
577
578 EFSYS_UNLOCK(enp->en_eslp, lstate);
579 }
580
581 static void
582 falcon_nic_pcie_core_write(
583 __in efx_nic_t *enp,
584 __in uint32_t addr,
585 __out efx_dword_t *edp)
586 {
587 int lstate;
588 efx_oword_t oword;
589 uint32_t val;
590
591 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
592
593 EFSYS_LOCK(enp->en_eslp, lstate);
594
595 val = EFX_DWORD_FIELD(*edp, EFX_DWORD_0);
596
597 EFX_POPULATE_OWORD_3(oword, FRF_BB_PCIE_CORE_TARGET_REG_ADRS, addr,
598 FRF_BB_PCIE_CORE_TARGET_DATA, val,
599 FRF_BB_PCIE_CORE_INDIRECT_ACCESS_DIR, 0);
600 EFX_BAR_WRITEO(enp, FR_BB_PCIE_CORE_INDIRECT_REG, &oword);
601
602 EFSYS_UNLOCK(enp->en_eslp, lstate);
603 }
604 #endif /* EFSYS_OPT_PCIE_TUNE || EFSYS_OPT_DIAG */
605
606 #if EFSYS_OPT_PCIE_TUNE
607
608 typedef struct falcon_pcie_rpl_s {
609 size_t fpr_tlp_size;
610 uint32_t fpr_value[4];
611 } falcon_pcie_rpl_t;
612
613 /* TLP 1x 2x 4x 8x */
614 static falcon_pcie_rpl_t __cs falcon_nic_pcie_rpl[] = {
615 { 128, { 421, 257, 174, 166 } },
616 { 256, { 698, 391, 241, 225 } },
617 { 512, { 903, 498, 295, 193 } },
618 { 1024, { 1670, 881, 487, 290 } }
619 };
620
621 static void
622 falcon_nic_pcie_rpl_tl_set(
623 __in efx_nic_t *enp,
624 __in unsigned int nlanes)
625 {
626 uint32_t index;
627 uint32_t current;
628 falcon_pcie_rpl_t *fprp;
629 uint32_t expected;
630 efx_dword_t dword;
631
632 EFSYS_ASSERT3U(nlanes, >, 0);
633 EFSYS_ASSERT3U(nlanes, <=, 8);
634 EFSYS_ASSERT(ISP2(nlanes));
635
636 /* Get the appropriate set of replay timer values */
637 falcon_nic_pcie_core_read(enp, PCR_AB_DEV_CTL_REG, &dword);
638
639 index = EFX_DWORD_FIELD(dword, PCRF_AZ_MAX_PAYL_SIZE);
640 if (index >= 4) {
641 EFSYS_PROBE1(fail1, int, EIO);
642 return;
643 }
644
645 fprp = (falcon_pcie_rpl_t *)&(falcon_nic_pcie_rpl[index]);
646
647 EFSYS_PROBE1(pcie_tlp_size, size_t, fprp->fpr_tlp_size);
648
649 for (index = 0; index < 4; index++)
650 if ((1 << index) == nlanes)
651 break;
652
653 /* Get the current replay timer value */
654 falcon_nic_pcie_core_read(enp, PCR_AC_ACK_LAT_TMR_REG, &dword);
655 current = EFX_DWORD_FIELD(dword, PCRF_AC_RT);
656
657 /* Get the appropriate replay timer value from the set */
658 expected = fprp->fpr_value[index];
659
660 EFSYS_PROBE2(pcie_rpl_tl, uint32_t, current, uint32_t, expected);
661
662 EFSYS_PROBE1(pcie_ack_tl,
663 uint32_t, EFX_DWORD_FIELD(dword, PCRF_AC_ALT));
664
665 if (expected > current) {
666 EFX_SET_DWORD_FIELD(dword, PCRF_AC_RT, expected);
667 falcon_nic_pcie_core_write(enp, PCR_AC_ACK_LAT_TMR_REG,
668 &dword);
669 }
670 }
671
672 static void
673 falcon_nic_pcie_ack_freq_set(
674 __in efx_nic_t *enp,
675 __in uint32_t freq)
676 {
677 efx_dword_t dword;
678
679 falcon_nic_pcie_core_read(enp, PCR_AC_ACK_FREQ_REG, &dword);
680
681 EFSYS_PROBE2(pcie_ack_freq,
682 uint32_t, EFX_DWORD_FIELD(dword, PCRF_AC_ACK_FREQ),
683 uint32_t, freq);
684
685 /* Set to zero to ensure that we always ACK after timeout */
686 EFX_SET_DWORD_FIELD(dword, PCRF_AC_ACK_FREQ, freq);
687 falcon_nic_pcie_core_write(enp, PCR_AC_ACK_FREQ_REG, &dword);
688 }
689
690 int
691 falcon_nic_pcie_tune(
692 __in efx_nic_t *enp,
693 __in unsigned int nlanes)
694 {
695 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
696
697 enp->en_u.falcon.enu_nlanes = nlanes;
698 return (0);
699 }
700
701 #endif /* EFSYS_OPT_PCIE_TUNE */
702
703 __checkReturn int
704 falcon_nic_reset(
705 __in efx_nic_t *enp)
706 {
707 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
708 falcon_i2c_t *fip = &(enp->en_u.falcon.enu_fip);
709 efx_oword_t oword;
710 unsigned int count;
711 int rc;
712
713 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
714
715 /* Check the reset register */
716 EFX_BAR_READO(enp, FR_AB_GLB_CTL_REG, &oword);
717
718 /* Select units for reset */
719 EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_CS, 1);
720 EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_TX, 1);
721 EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_XGTX, 1);
722 EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_RX, 1);
723 EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_XGRX, 1);
724 EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_SR, 1);
725 EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_EV, 1);
726 EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_EM, 1);
727 EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_PCIE_STKY, 1);
728 EFX_SET_OWORD_FIELD(oword, FRF_BB_RST_BIU, 1);
729 EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_XAUI_SD, 1);
730
731 /* Initiate reset */
732 EFX_BAR_WRITEO(enp, FR_AB_GLB_CTL_REG, &oword);
733
734 /* Wait for the reset to complete */
735 count = 0;
736 do {
737 EFSYS_PROBE1(wait, unsigned int, count);
738
739 /* Spin for 10 us */
740 EFSYS_SPIN(10);
741
742 /* Test for reset complete */
743 EFX_BAR_READO(enp, FR_AB_GLB_CTL_REG, &oword);
744 if (EFX_OWORD_FIELD(oword, FRF_AB_RST_CS) == 0 &&
745 EFX_OWORD_FIELD(oword, FRF_AB_RST_TX) == 0 &&
746 EFX_OWORD_FIELD(oword, FRF_AB_RST_XGTX) == 0 &&
747 EFX_OWORD_FIELD(oword, FRF_AB_RST_RX) == 0 &&
748 EFX_OWORD_FIELD(oword, FRF_AB_RST_XGRX) == 0 &&
749 EFX_OWORD_FIELD(oword, FRF_AB_RST_SR) == 0 &&
750 EFX_OWORD_FIELD(oword, FRF_AB_RST_EV) == 0 &&
751 EFX_OWORD_FIELD(oword, FRF_AB_RST_EM) == 0 &&
752 EFX_OWORD_FIELD(oword, FRF_AB_RST_PCIE_STKY) == 0 &&
753 EFX_OWORD_FIELD(oword, FRF_BB_RST_BIU) == 0 &&
754 EFX_OWORD_FIELD(oword, FRF_AB_RST_XAUI_SD) == 0)
755 goto done;
756 } while (++count < 1000);
757
758 rc = ETIMEDOUT;
759 goto fail1;
760
761 done:
762 /* GPIO initialization */
763 EFX_BAR_READO(enp, FR_AB_GPIO_CTL_REG, &oword);
764
765 /* Set I2C SCL to 1 */
766 EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO0_OUT, 1);
767 EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO0_OEN, 1);
768
769 /* Select external 1G MAC clock if it is available */
770 EFX_SET_OWORD_FIELD(oword, FRF_BB_USE_NIC_CLK,
771 (encp->enc_board_type == BOARD_TYPE_SFN4111T_DECODE));
772
773 EFX_BAR_WRITEO(enp, FR_AB_GPIO_CTL_REG, &oword);
774
775 fip->fi_sda = B_TRUE;
776 fip->fi_scl = B_TRUE;
777
778 return (0);
779
780 fail1:
781 EFSYS_PROBE1(fail1, int, rc);
782
783 return (rc);
784 }
785
786 static void
787 falcon_nic_timer_tbl_watchdog(
788 __in efx_nic_t *enp)
789 {
790 efx_oword_t oword;
791
792 if (enp->en_family != EFX_FAMILY_FALCON)
793 return;
794
795 /*
796 * Ensure that PCI writes to the event queue read pointers are spaced
797 * out far enough to avoid write loss.
798 */
799 EFX_BAR_READO(enp, FR_AZ_HW_INIT_REG, &oword);
800 EFX_SET_OWORD_FIELD(oword, FRF_AZ_POST_WR_MASK, 0xf);
801 EFX_SET_OWORD_FIELD(oword, FRF_AZ_WD_TIMER, 0x10);
802 EFX_BAR_WRITEO(enp, FR_AZ_HW_INIT_REG, &oword);
803 }
804
805 static void
806 falcon_rx_reset_recovery_enable(
807 __in efx_nic_t *enp)
808 {
809 efx_oword_t oword;
810
811 /*
812 * Set number of channels for receive path and also set filter table
813 * search limits to 8, to reduce the frequency of RX_RECOVERY events
814 */
815 EFX_POPULATE_OWORD_4(oword,
816 FRF_AZ_UDP_FULL_SRCH_LIMIT, 8,
817 FRF_AZ_UDP_WILD_SRCH_LIMIT, 8,
818 FRF_AZ_TCP_FULL_SRCH_LIMIT, 8,
819 FRF_AZ_TCP_WILD_SRCH_LIMIT, 8);
820 EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
821
822 /*
823 * Enable RX Self-Reset functionality.
824 * Disable ISCSI digest to reduce RX_RECOVERY frequency
825 */
826 EFX_BAR_READO(enp, FR_AZ_RX_SELF_RST_REG, &oword);
827 EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_ISCSI_DIS, 1);
828 EFX_SET_OWORD_FIELD(oword, FRF_AB_RX_SW_RST_REG, 1);
829 EFX_BAR_WRITEO(enp, FR_AZ_RX_SELF_RST_REG, &oword);
830 }
831
832 __checkReturn int
833 falcon_nic_init(
834 __in efx_nic_t *enp)
835 {
836 int rc;
837
838 if ((rc = falcon_sram_init(enp)) != 0)
839 goto fail1;
840
841 #if EFSYS_OPT_PCIE_TUNE
842 /* Tune up the PCIe core */
843 if (enp->en_u.falcon.enu_nlanes > 0) {
844 falcon_nic_pcie_rpl_tl_set(enp, enp->en_u.falcon.enu_nlanes);
845 falcon_nic_pcie_ack_freq_set(enp, 0);
846 }
847 #endif
848 /* Fix NMI's due to premature timer_tbl biu watchdog */
849 falcon_nic_timer_tbl_watchdog(enp);
850
851 /* Enable RX_RECOVERY feature */
852 falcon_rx_reset_recovery_enable(enp);
853
854 return (0);
855
856 fail1:
857 EFSYS_PROBE1(fail1, int, rc);
858
859 return (rc);
860 }
861
862 __checkReturn int
863 falcon_nic_mac_reset(
864 __in efx_nic_t *enp)
865 {
866 efx_oword_t oword;
867 unsigned int count;
868 int rc;
869
870 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
871
872 EFX_BAR_READO(enp, FR_AB_MAC_CTRL_REG, &oword);
873 EFX_SET_OWORD_FIELD(oword, FRF_BB_TXFIFO_DRAIN_EN, 1);
874 EFX_BAR_WRITEO(enp, FR_AB_MAC_CTRL_REG, &oword);
875
876 /* Reset the MAC and EM units */
877 EFX_BAR_READO(enp, FR_AB_GLB_CTL_REG, &oword);
878
879 EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_EM, 1);
880 EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_XGRX, 1);
881 EFX_SET_OWORD_FIELD(oword, FRF_AB_RST_XGTX, 1);
882
883 /* Initiate reset */
884 EFX_BAR_WRITEO(enp, FR_AB_GLB_CTL_REG, &oword);
885
886 /* Wait for the reset to complete */
887 count = 0;
888 do {
889 EFSYS_PROBE1(wait, unsigned int, count);
890
891 /* Spin for 10 us */
892 EFSYS_SPIN(10);
893
894 /* Test for reset complete */
895 EFX_BAR_READO(enp, FR_AB_GLB_CTL_REG, &oword);
896 if (EFX_OWORD_FIELD(oword, FRF_AB_RST_EM) == 0 &&
897 EFX_OWORD_FIELD(oword, FRF_AB_RST_XGRX) == 0 &&
898 EFX_OWORD_FIELD(oword, FRF_AB_RST_XGTX) == 0)
899 goto done;
900 } while (++count < 1000);
901
902 rc = ETIMEDOUT;
903 goto fail1;
904
905 done:
906 enp->en_reset_flags |= EFX_RESET_MAC;
907
908 return (0);
909
910 fail1:
911 EFSYS_PROBE1(fail1, int, rc);
912 return (rc);
913 }
914
915 void
916 falcon_nic_phy_reset(
917 __in efx_nic_t *enp)
918 {
919 efx_oword_t oword;
920 int state;
921
922 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
923
924 /* Set PHY_RSTn to 0 */
925 EFSYS_LOCK(enp->en_eslp, state);
926 EFX_BAR_READO(enp, FR_AB_GPIO_CTL_REG, &oword);
927 EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO2_OUT, 0);
928 EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO2_OEN, 1);
929 EFX_BAR_WRITEO(enp, FR_AB_GPIO_CTL_REG, &oword);
930 EFSYS_UNLOCK(enp->en_eslp, state);
931
932 EFSYS_SLEEP(500000);
933
934 EFSYS_LOCK(enp->en_eslp, state);
935 EFX_BAR_READO(enp, FR_AB_GPIO_CTL_REG, &oword);
936 EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO2_OEN, 0);
937 EFX_BAR_WRITEO(enp, FR_AB_GPIO_CTL_REG, &oword);
938 EFSYS_UNLOCK(enp->en_eslp, state);
939
940 EFSYS_SLEEP(100000);
941
942 enp->en_reset_flags |= EFX_RESET_PHY;
943 }
944
945 void
946 falcon_nic_fini(
947 __in efx_nic_t *enp)
948 {
949 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
950
951 #if EFSYS_OPT_PCIE_TUNE
952 falcon_nic_pcie_ack_freq_set(enp, 1);
953 #endif /* EFSYS_OPT_PCIE_TUNE */
954
955 falcon_sram_fini(enp);
956 }
957
958 void
959 falcon_nic_unprobe(
960 __in efx_nic_t *enp)
961 {
962 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
963
964 falcon_nvram_fini(enp);
965 }
966
967 #if EFSYS_OPT_DIAG
968
969 static efx_register_set_t __cs __falcon_b0_registers[] = {
970 { FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
971 { FR_AZ_RX_CFG_REG_OFST, 0, 1 },
972 { FR_AZ_TX_CFG_REG_OFST, 0, 1 },
973 { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
974 { FR_AB_MAC_CTRL_REG_OFST, 0, 1 },
975 { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
976 { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
977 { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
978 { FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
979 { FR_AB_GM_CFG2_REG_OFST, 0, 1 },
980 { FR_AB_GMF_CFG0_REG_OFST, 0, 1 },
981 { FR_AB_XM_GLB_CFG_REG_OFST, 0, 1 },
982 { FR_AB_XM_TX_CFG_REG_OFST, 0, 1 },
983 { FR_AB_XM_RX_CFG_REG_OFST, 0, 1 },
984 { FR_AB_XM_RX_PARAM_REG_OFST, 0, 1 },
985 { FR_AB_XM_FC_REG_OFST, 0, 1 },
986 { FR_AB_XM_ADR_LO_REG_OFST, 0, 1 },
987 { FR_AB_XX_SD_CTL_REG_OFST, 0, 1 },
988 };
989
990 static const uint32_t __cs __falcon_b0_register_masks[] = {
991 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
992 0xFFFFFFFE, 0x00017FFF, 0x00000000, 0x00000000,
993 0x7FFF0037, 0x00000000, 0x00000000, 0x00000000,
994 0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
995 0xFFFF0000, 0x00000000, 0x00000000, 0x00000000,
996 0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
997 0x0000000F, 0x00000000, 0x00000000, 0x00000000,
998 0x000003FF, 0x00000000, 0x00000000, 0x00000000,
999 0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
1000 0x00007337, 0x00000000, 0x00000000, 0x00000000,
1001 0x00001F1F, 0x00000000, 0x00000000, 0x00000000,
1002 0x00000C68, 0x00000000, 0x00000000, 0x00000000,
1003 0x00080164, 0x00000000, 0x00000000, 0x00000000,
1004 0x07100A0C, 0x00000000, 0x00000000, 0x00000000,
1005 0x00001FF8, 0x00000000, 0x00000000, 0x00000000,
1006 0xFFFF0001, 0x00000000, 0x00000000, 0x00000000,
1007 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,
1008 0x0003FF0F, 0x00000000, 0x00000000, 0x00000000,
1009 };
1010
1011 static efx_register_set_t __cs __falcon_b0_tables[] = {
1012 { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
1013 FR_AZ_RX_FILTER_TBL0_ROWS },
1014 { FR_AB_RX_FILTER_TBL1_OFST, FR_AB_RX_FILTER_TBL1_STEP,
1015 FR_AB_RX_FILTER_TBL1_ROWS },
1016 { FR_AZ_RX_DESC_PTR_TBL_OFST,
1017 FR_AZ_RX_DESC_PTR_TBL_STEP, FR_AB_RX_DESC_PTR_TBL_ROWS },
1018 { FR_AZ_TX_DESC_PTR_TBL_OFST,
1019 FR_AZ_TX_DESC_PTR_TBL_STEP, FR_AB_TX_DESC_PTR_TBL_ROWS },
1020 };
1021
1022 static const uint32_t __cs __falcon_b0_table_masks[] = {
1023 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
1024 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
1025 0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
1026 0x3FFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
1027 };
1028
1029 __checkReturn int
1030 falcon_nic_register_test(
1031 __in efx_nic_t *enp)
1032 {
1033 efx_register_set_t *rsp;
1034 const uint32_t *dwordp;
1035 unsigned int nitems;
1036 unsigned int count;
1037 int rc;
1038
1039 /* Fill out the register mask entries */
1040 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__falcon_b0_register_masks)
1041 == EFX_ARRAY_SIZE(__falcon_b0_registers) * 4);
1042
1043 nitems = EFX_ARRAY_SIZE(__falcon_b0_registers);
1044 dwordp = __falcon_b0_register_masks;
1045 for (count = 0; count < nitems; ++count) {
1046 rsp = __falcon_b0_registers + count;
1047 rsp->mask.eo_u32[0] = *dwordp++;
1048 rsp->mask.eo_u32[1] = *dwordp++;
1049 rsp->mask.eo_u32[2] = *dwordp++;
1050 rsp->mask.eo_u32[3] = *dwordp++;
1051 }
1052
1053 /* Fill out the register table entries */
1054 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__falcon_b0_table_masks)
1055 == EFX_ARRAY_SIZE(__falcon_b0_tables) * 4);
1056
1057 nitems = EFX_ARRAY_SIZE(__falcon_b0_tables);
1058 dwordp = __falcon_b0_table_masks;
1059 for (count = 0; count < nitems; ++count) {
1060 rsp = __falcon_b0_tables + count;
1061 rsp->mask.eo_u32[0] = *dwordp++;
1062 rsp->mask.eo_u32[1] = *dwordp++;
1063 rsp->mask.eo_u32[2] = *dwordp++;
1064 rsp->mask.eo_u32[3] = *dwordp++;
1065 }
1066
1067 if ((rc = efx_nic_test_registers(enp, __falcon_b0_registers,
1068 EFX_ARRAY_SIZE(__falcon_b0_registers))) != 0)
1069 goto fail1;
1070
1071 if ((rc = efx_nic_test_tables(enp, __falcon_b0_tables,
1072 EFX_PATTERN_BYTE_ALTERNATE,
1073 EFX_ARRAY_SIZE(__falcon_b0_tables))) != 0)
1074 goto fail2;
1075
1076 if ((rc = efx_nic_test_tables(enp, __falcon_b0_tables,
1077 EFX_PATTERN_BYTE_CHANGING,
1078 EFX_ARRAY_SIZE(__falcon_b0_tables))) != 0)
1079 goto fail3;
1080
1081 if ((rc = efx_nic_test_tables(enp, __falcon_b0_tables,
1082 EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__falcon_b0_tables))) != 0)
1083 goto fail4;
1084
1085 return (0);
1086
1087 fail4:
1088 EFSYS_PROBE(fail4);
1089 fail3:
1090 EFSYS_PROBE(fail3);
1091 fail2:
1092 EFSYS_PROBE(fail2);
1093 fail1:
1094 EFSYS_PROBE1(fail1, int, rc);
1095
1096 return (rc);
1097 }
1098
1099 #endif /* EFSYS_OPT_DIAG */
1100
1101 #endif /* EFSYS_OPT_FALCON */