1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2009-2016 Solarflare Communications Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * The views and conclusions contained in the software and documentation are
29 * those of the authors and should not be interpreted as representing official
30 * policies, either expressed or implied, of the FreeBSD Project.
31 */
32
33 #include <sys/cdefs.h>
34 #include "efx.h"
35 #include "efx_impl.h"
36 #include "mcdi_mon.h"
37
38 #if EFSYS_OPT_SIENA
39
40 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
41
42 static __checkReturn efx_rc_t
siena_nic_get_partn_mask(__in efx_nic_t * enp,__out unsigned int * maskp)43 siena_nic_get_partn_mask(
44 __in efx_nic_t *enp,
45 __out unsigned int *maskp)
46 {
47 efx_mcdi_req_t req;
48 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_TYPES_IN_LEN,
49 MC_CMD_NVRAM_TYPES_OUT_LEN);
50 efx_rc_t rc;
51
52 req.emr_cmd = MC_CMD_NVRAM_TYPES;
53 req.emr_in_buf = payload;
54 req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN;
55 req.emr_out_buf = payload;
56 req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN;
57
58 efx_mcdi_execute(enp, &req);
59
60 if (req.emr_rc != 0) {
61 rc = req.emr_rc;
62 goto fail1;
63 }
64
65 if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) {
66 rc = EMSGSIZE;
67 goto fail2;
68 }
69
70 *maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES);
71
72 return (0);
73
74 fail2:
75 EFSYS_PROBE(fail2);
76 fail1:
77 EFSYS_PROBE1(fail1, efx_rc_t, rc);
78
79 return (rc);
80 }
81
82 #endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
83
84 static __checkReturn efx_rc_t
siena_board_cfg(__in efx_nic_t * enp)85 siena_board_cfg(
86 __in efx_nic_t *enp)
87 {
88 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
89 uint8_t mac_addr[6];
90 efx_dword_t capabilities;
91 uint32_t board_type;
92 uint32_t nevq, nrxq, ntxq;
93 efx_rc_t rc;
94
95 /* Siena has a fixed 8Kbyte VI window size */
96 EFX_STATIC_ASSERT(1U << EFX_VI_WINDOW_SHIFT_8K == 8192);
97 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_8K;
98
99 /* External port identifier using one-based port numbering */
100 encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port;
101
102 /* Board configuration */
103 if ((rc = efx_mcdi_get_board_cfg(enp, &board_type,
104 &capabilities, mac_addr)) != 0)
105 goto fail1;
106
107 EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
108
109 encp->enc_board_type = board_type;
110
111 /*
112 * There is no possibility to determine the number of PFs on Siena
113 * by issuing MCDI request, and it is not an easy task to find the
114 * value based on the board type, so 'enc_hw_pf_count' is set to 1
115 */
116 encp->enc_hw_pf_count = 1;
117
118 /* Additional capabilities */
119 encp->enc_clk_mult = 1;
120 if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) {
121 enp->en_features |= EFX_FEATURE_TURBO;
122
123 if (EFX_DWORD_FIELD(capabilities,
124 MC_CMD_CAPABILITIES_TURBO_ACTIVE)) {
125 encp->enc_clk_mult = 2;
126 }
127 }
128
129 encp->enc_evq_timer_quantum_ns =
130 EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult;
131 encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
132 FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
133
134 /* When hash header insertion is enabled, Siena inserts 16 bytes */
135 encp->enc_rx_prefix_size = 16;
136
137 /* Alignment for receive packet DMA buffers */
138 encp->enc_rx_buf_align_start = 1;
139 encp->enc_rx_buf_align_end = 1;
140
141 /* Alignment for WPTR updates */
142 encp->enc_rx_push_align = 1;
143
144 #if EFSYS_OPT_RX_SCALE
145 /* There is one RSS context per function */
146 encp->enc_rx_scale_max_exclusive_contexts = 1;
147
148 encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_LFSR);
149 encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_TOEPLITZ);
150
151 /*
152 * It is always possible to use port numbers
153 * as the input data for hash computation.
154 */
155 encp->enc_rx_scale_l4_hash_supported = B_TRUE;
156
157 /* There is no support for additional RSS modes */
158 encp->enc_rx_scale_additional_modes_supported = B_FALSE;
159 #endif /* EFSYS_OPT_RX_SCALE */
160
161 encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT);
162 /* Fragments must not span 4k boundaries. */
163 encp->enc_tx_dma_desc_boundary = 4096;
164
165 /* Resource limits */
166 rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
167 if (rc != 0) {
168 if (rc != ENOTSUP)
169 goto fail2;
170
171 nevq = 1024;
172 nrxq = EFX_RXQ_LIMIT_TARGET;
173 ntxq = EFX_TXQ_LIMIT_TARGET;
174 }
175 encp->enc_evq_limit = nevq;
176 encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
177 encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
178
179 encp->enc_txq_max_ndescs = 4096;
180
181 encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
182 (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
183 (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
184
185 encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
186 encp->enc_fw_assisted_tso_enabled = B_FALSE;
187 encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
188 encp->enc_fw_assisted_tso_v2_n_contexts = 0;
189 encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
190 encp->enc_rx_packed_stream_supported = B_FALSE;
191 encp->enc_rx_var_packed_stream_supported = B_FALSE;
192 encp->enc_rx_es_super_buffer_supported = B_FALSE;
193 encp->enc_fw_subvariant_no_tx_csum_supported = B_FALSE;
194
195 /* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */
196 encp->enc_required_pcie_bandwidth_mbps = 2 * 10000;
197 encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2;
198
199 encp->enc_nvram_update_verify_result_supported = B_FALSE;
200
201 encp->enc_mac_stats_nstats = MC_CMD_MAC_NSTATS;
202
203 encp->enc_filter_action_flag_supported = B_FALSE;
204 encp->enc_filter_action_mark_supported = B_FALSE;
205 encp->enc_filter_action_mark_max = 0;
206
207 return (0);
208
209 fail2:
210 EFSYS_PROBE(fail2);
211 fail1:
212 EFSYS_PROBE1(fail1, efx_rc_t, rc);
213
214 return (rc);
215 }
216
217 static __checkReturn efx_rc_t
siena_phy_cfg(__in efx_nic_t * enp)218 siena_phy_cfg(
219 __in efx_nic_t *enp)
220 {
221 #if EFSYS_OPT_PHY_STATS
222 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
223 #endif /* EFSYS_OPT_PHY_STATS */
224 efx_rc_t rc;
225
226 /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
227 if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
228 goto fail1;
229
230 #if EFSYS_OPT_PHY_STATS
231 /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
232 siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
233 NULL, &encp->enc_phy_stat_mask, NULL);
234 #endif /* EFSYS_OPT_PHY_STATS */
235
236 return (0);
237
238 fail1:
239 EFSYS_PROBE1(fail1, efx_rc_t, rc);
240
241 return (rc);
242 }
243
244 #define SIENA_BIU_MAGIC0 0x01234567
245 #define SIENA_BIU_MAGIC1 0xfedcba98
246
247 static __checkReturn efx_rc_t
siena_nic_biu_test(__in efx_nic_t * enp)248 siena_nic_biu_test(
249 __in efx_nic_t *enp)
250 {
251 efx_oword_t oword;
252 efx_rc_t rc;
253
254 /*
255 * Write magic values to scratch registers 0 and 1, then
256 * verify that the values were written correctly. Interleave
257 * the accesses to ensure that the BIU is not just reading
258 * back the cached value that was last written.
259 */
260 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC0);
261 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
262
263 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC1);
264 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
265
266 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
267 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC0) {
268 rc = EIO;
269 goto fail1;
270 }
271
272 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
273 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC1) {
274 rc = EIO;
275 goto fail2;
276 }
277
278 /*
279 * Perform the same test, with the values swapped. This
280 * ensures that subsequent tests don't start with the correct
281 * values already written into the scratch registers.
282 */
283 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC1);
284 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
285
286 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC0);
287 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
288
289 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
290 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC1) {
291 rc = EIO;
292 goto fail3;
293 }
294
295 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
296 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC0) {
297 rc = EIO;
298 goto fail4;
299 }
300
301 return (0);
302
303 fail4:
304 EFSYS_PROBE(fail4);
305 fail3:
306 EFSYS_PROBE(fail3);
307 fail2:
308 EFSYS_PROBE(fail2);
309 fail1:
310 EFSYS_PROBE1(fail1, efx_rc_t, rc);
311
312 return (rc);
313 }
314
315 __checkReturn efx_rc_t
siena_nic_probe(__in efx_nic_t * enp)316 siena_nic_probe(
317 __in efx_nic_t *enp)
318 {
319 efx_port_t *epp = &(enp->en_port);
320 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
321 siena_link_state_t sls;
322 unsigned int mask;
323 efx_oword_t oword;
324 efx_rc_t rc;
325
326 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
327
328 /* Test BIU */
329 if ((rc = siena_nic_biu_test(enp)) != 0)
330 goto fail1;
331
332 /* Clear the region register */
333 EFX_POPULATE_OWORD_4(oword,
334 FRF_AZ_ADR_REGION0, 0,
335 FRF_AZ_ADR_REGION1, (1 << 16),
336 FRF_AZ_ADR_REGION2, (2 << 16),
337 FRF_AZ_ADR_REGION3, (3 << 16));
338 EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
339
340 /* Read clear any assertion state */
341 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
342 goto fail2;
343
344 /* Exit the assertion handler */
345 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
346 goto fail3;
347
348 /* Wrestle control from the BMC */
349 if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
350 goto fail4;
351
352 if ((rc = siena_board_cfg(enp)) != 0)
353 goto fail5;
354
355 if ((rc = siena_phy_cfg(enp)) != 0)
356 goto fail6;
357
358 /* Obtain the default PHY advertised capabilities */
359 if ((rc = siena_nic_reset(enp)) != 0)
360 goto fail7;
361 if ((rc = siena_phy_get_link(enp, &sls)) != 0)
362 goto fail8;
363 epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
364 epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
365
366 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
367 if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
368 goto fail9;
369 enp->en_u.siena.enu_partn_mask = mask;
370 #endif
371
372 #if EFSYS_OPT_MAC_STATS
373 /* Wipe the MAC statistics */
374 if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
375 goto fail10;
376 #endif
377
378 #if EFSYS_OPT_LOOPBACK
379 if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
380 goto fail11;
381 #endif
382
383 #if EFSYS_OPT_MON_STATS
384 if ((rc = mcdi_mon_cfg_build(enp)) != 0)
385 goto fail12;
386 #endif
387
388 encp->enc_features = enp->en_features;
389
390 return (0);
391
392 #if EFSYS_OPT_MON_STATS
393 fail12:
394 EFSYS_PROBE(fail12);
395 #endif
396 #if EFSYS_OPT_LOOPBACK
397 fail11:
398 EFSYS_PROBE(fail11);
399 #endif
400 #if EFSYS_OPT_MAC_STATS
401 fail10:
402 EFSYS_PROBE(fail10);
403 #endif
404 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
405 fail9:
406 EFSYS_PROBE(fail9);
407 #endif
408 fail8:
409 EFSYS_PROBE(fail8);
410 fail7:
411 EFSYS_PROBE(fail7);
412 fail6:
413 EFSYS_PROBE(fail6);
414 fail5:
415 EFSYS_PROBE(fail5);
416 fail4:
417 EFSYS_PROBE(fail4);
418 fail3:
419 EFSYS_PROBE(fail3);
420 fail2:
421 EFSYS_PROBE(fail2);
422 fail1:
423 EFSYS_PROBE1(fail1, efx_rc_t, rc);
424
425 return (rc);
426 }
427
428 __checkReturn efx_rc_t
siena_nic_reset(__in efx_nic_t * enp)429 siena_nic_reset(
430 __in efx_nic_t *enp)
431 {
432 efx_mcdi_req_t req;
433 efx_rc_t rc;
434
435 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
436
437 /* siena_nic_reset() is called to recover from BADASSERT failures. */
438 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
439 goto fail1;
440 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
441 goto fail2;
442
443 /*
444 * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
445 * for backwards compatibility with PORT_RESET_IN_LEN.
446 */
447 EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
448
449 req.emr_cmd = MC_CMD_ENTITY_RESET;
450 req.emr_in_buf = NULL;
451 req.emr_in_length = 0;
452 req.emr_out_buf = NULL;
453 req.emr_out_length = 0;
454
455 efx_mcdi_execute(enp, &req);
456
457 if (req.emr_rc != 0) {
458 rc = req.emr_rc;
459 goto fail3;
460 }
461
462 return (0);
463
464 fail3:
465 EFSYS_PROBE(fail3);
466 fail2:
467 EFSYS_PROBE(fail2);
468 fail1:
469 EFSYS_PROBE1(fail1, efx_rc_t, rc);
470
471 return (0);
472 }
473
474 static void
siena_nic_rx_cfg(__in efx_nic_t * enp)475 siena_nic_rx_cfg(
476 __in efx_nic_t *enp)
477 {
478 efx_oword_t oword;
479
480 /*
481 * RX_INGR_EN is always enabled on Siena, because we rely on
482 * the RX parser to be resiliant to missing SOP/EOP.
483 */
484 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
485 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
486 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
487
488 /* Disable parsing of additional 802.1Q in Q packets */
489 EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
490 EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
491 EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
492 }
493
494 static void
siena_nic_usrev_dis(__in efx_nic_t * enp)495 siena_nic_usrev_dis(
496 __in efx_nic_t *enp)
497 {
498 efx_oword_t oword;
499
500 EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
501 EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
502 }
503
504 __checkReturn efx_rc_t
siena_nic_init(__in efx_nic_t * enp)505 siena_nic_init(
506 __in efx_nic_t *enp)
507 {
508 efx_rc_t rc;
509
510 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
511
512 /* Enable reporting of some events (e.g. link change) */
513 if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
514 goto fail1;
515
516 siena_sram_init(enp);
517
518 /* Configure Siena's RX block */
519 siena_nic_rx_cfg(enp);
520
521 /* Disable USR_EVents for now */
522 siena_nic_usrev_dis(enp);
523
524 /* bug17057: Ensure set_link is called */
525 if ((rc = siena_phy_reconfigure(enp)) != 0)
526 goto fail2;
527
528 enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;
529
530 return (0);
531
532 fail2:
533 EFSYS_PROBE(fail2);
534 fail1:
535 EFSYS_PROBE1(fail1, efx_rc_t, rc);
536
537 return (rc);
538 }
539
540 void
siena_nic_fini(__in efx_nic_t * enp)541 siena_nic_fini(
542 __in efx_nic_t *enp)
543 {
544 _NOTE(ARGUNUSED(enp))
545 }
546
547 void
siena_nic_unprobe(__in efx_nic_t * enp)548 siena_nic_unprobe(
549 __in efx_nic_t *enp)
550 {
551 #if EFSYS_OPT_MON_STATS
552 mcdi_mon_cfg_free(enp);
553 #endif /* EFSYS_OPT_MON_STATS */
554 (void) efx_mcdi_drv_attach(enp, B_FALSE);
555 }
556
557 #if EFSYS_OPT_DIAG
558
559 static siena_register_set_t __siena_registers[] = {
560 { FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
561 { FR_CZ_USR_EV_CFG_OFST, 0, 1 },
562 { FR_AZ_RX_CFG_REG_OFST, 0, 1 },
563 { FR_AZ_TX_CFG_REG_OFST, 0, 1 },
564 { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
565 { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
566 { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
567 { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
568 { FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
569 { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
570 { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
571 { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
572 { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
573 };
574
575 static const uint32_t __siena_register_masks[] = {
576 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
577 0x000103FF, 0x00000000, 0x00000000, 0x00000000,
578 0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
579 0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
580 0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
581 0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
582 0x00000003, 0x00000000, 0x00000000, 0x00000000,
583 0x000003FF, 0x00000000, 0x00000000, 0x00000000,
584 0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
585 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
586 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
587 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
588 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
589 };
590
591 static siena_register_set_t __siena_tables[] = {
592 { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
593 FR_AZ_RX_FILTER_TBL0_ROWS },
594 { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
595 FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
596 { FR_AZ_RX_DESC_PTR_TBL_OFST,
597 FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
598 { FR_AZ_TX_DESC_PTR_TBL_OFST,
599 FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
600 { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
601 { FR_CZ_TX_FILTER_TBL0_OFST,
602 FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
603 { FR_CZ_TX_MAC_FILTER_TBL0_OFST,
604 FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
605 };
606
607 static const uint32_t __siena_table_masks[] = {
608 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
609 0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
610 0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
611 0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
612 0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
613 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
614 0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
615 };
616
617 __checkReturn efx_rc_t
siena_nic_test_registers(__in efx_nic_t * enp,__in siena_register_set_t * rsp,__in size_t count)618 siena_nic_test_registers(
619 __in efx_nic_t *enp,
620 __in siena_register_set_t *rsp,
621 __in size_t count)
622 {
623 unsigned int bit;
624 efx_oword_t original;
625 efx_oword_t reg;
626 efx_oword_t buf;
627 efx_rc_t rc;
628
629 while (count > 0) {
630 /* This function is only suitable for registers */
631 EFSYS_ASSERT(rsp->rows == 1);
632
633 /* bit sweep on and off */
634 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &original,
635 B_TRUE);
636 for (bit = 0; bit < 128; bit++) {
637 /* Is this bit in the mask? */
638 if (~(rsp->mask.eo_u32[bit >> 5]) & (1 << bit))
639 continue;
640
641 /* Test this bit can be set in isolation */
642 reg = original;
643 EFX_AND_OWORD(reg, rsp->mask);
644 EFX_SET_OWORD_BIT(reg, bit);
645
646 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, ®,
647 B_TRUE);
648 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
649 B_TRUE);
650
651 EFX_AND_OWORD(buf, rsp->mask);
652 if (memcmp(®, &buf, sizeof (reg))) {
653 rc = EIO;
654 goto fail1;
655 }
656
657 /* Test this bit can be cleared in isolation */
658 EFX_OR_OWORD(reg, rsp->mask);
659 EFX_CLEAR_OWORD_BIT(reg, bit);
660
661 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, ®,
662 B_TRUE);
663 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
664 B_TRUE);
665
666 EFX_AND_OWORD(buf, rsp->mask);
667 if (memcmp(®, &buf, sizeof (reg))) {
668 rc = EIO;
669 goto fail2;
670 }
671 }
672
673 /* Restore the old value */
674 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original,
675 B_TRUE);
676
677 --count;
678 ++rsp;
679 }
680
681 return (0);
682
683 fail2:
684 EFSYS_PROBE(fail2);
685 fail1:
686 EFSYS_PROBE1(fail1, efx_rc_t, rc);
687
688 /* Restore the old value */
689 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, B_TRUE);
690
691 return (rc);
692 }
693
694 __checkReturn efx_rc_t
siena_nic_test_tables(__in efx_nic_t * enp,__in siena_register_set_t * rsp,__in efx_pattern_type_t pattern,__in size_t count)695 siena_nic_test_tables(
696 __in efx_nic_t *enp,
697 __in siena_register_set_t *rsp,
698 __in efx_pattern_type_t pattern,
699 __in size_t count)
700 {
701 efx_sram_pattern_fn_t func;
702 unsigned int index;
703 unsigned int address;
704 efx_oword_t reg;
705 efx_oword_t buf;
706 efx_rc_t rc;
707
708 EFSYS_ASSERT(pattern < EFX_PATTERN_NTYPES);
709 func = __efx_sram_pattern_fns[pattern];
710
711 while (count > 0) {
712 /* Write */
713 address = rsp->address;
714 for (index = 0; index < rsp->rows; ++index) {
715 func(2 * index + 0, B_FALSE, ®.eo_qword[0]);
716 func(2 * index + 1, B_FALSE, ®.eo_qword[1]);
717 EFX_AND_OWORD(reg, rsp->mask);
718 EFSYS_BAR_WRITEO(enp->en_esbp, address, ®, B_TRUE);
719
720 address += rsp->step;
721 }
722
723 /* Read */
724 address = rsp->address;
725 for (index = 0; index < rsp->rows; ++index) {
726 func(2 * index + 0, B_FALSE, ®.eo_qword[0]);
727 func(2 * index + 1, B_FALSE, ®.eo_qword[1]);
728 EFX_AND_OWORD(reg, rsp->mask);
729 EFSYS_BAR_READO(enp->en_esbp, address, &buf, B_TRUE);
730 if (memcmp(®, &buf, sizeof (reg))) {
731 rc = EIO;
732 goto fail1;
733 }
734
735 address += rsp->step;
736 }
737
738 ++rsp;
739 --count;
740 }
741
742 return (0);
743
744 fail1:
745 EFSYS_PROBE1(fail1, efx_rc_t, rc);
746
747 return (rc);
748 }
749
750 __checkReturn efx_rc_t
siena_nic_register_test(__in efx_nic_t * enp)751 siena_nic_register_test(
752 __in efx_nic_t *enp)
753 {
754 siena_register_set_t *rsp;
755 const uint32_t *dwordp;
756 unsigned int nitems;
757 unsigned int count;
758 efx_rc_t rc;
759
760 /* Fill out the register mask entries */
761 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
762 == EFX_ARRAY_SIZE(__siena_registers) * 4);
763
764 nitems = EFX_ARRAY_SIZE(__siena_registers);
765 dwordp = __siena_register_masks;
766 for (count = 0; count < nitems; ++count) {
767 rsp = __siena_registers + count;
768 rsp->mask.eo_u32[0] = *dwordp++;
769 rsp->mask.eo_u32[1] = *dwordp++;
770 rsp->mask.eo_u32[2] = *dwordp++;
771 rsp->mask.eo_u32[3] = *dwordp++;
772 }
773
774 /* Fill out the register table entries */
775 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
776 == EFX_ARRAY_SIZE(__siena_tables) * 4);
777
778 nitems = EFX_ARRAY_SIZE(__siena_tables);
779 dwordp = __siena_table_masks;
780 for (count = 0; count < nitems; ++count) {
781 rsp = __siena_tables + count;
782 rsp->mask.eo_u32[0] = *dwordp++;
783 rsp->mask.eo_u32[1] = *dwordp++;
784 rsp->mask.eo_u32[2] = *dwordp++;
785 rsp->mask.eo_u32[3] = *dwordp++;
786 }
787
788 if ((rc = siena_nic_test_registers(enp, __siena_registers,
789 EFX_ARRAY_SIZE(__siena_registers))) != 0)
790 goto fail1;
791
792 if ((rc = siena_nic_test_tables(enp, __siena_tables,
793 EFX_PATTERN_BYTE_ALTERNATE,
794 EFX_ARRAY_SIZE(__siena_tables))) != 0)
795 goto fail2;
796
797 if ((rc = siena_nic_test_tables(enp, __siena_tables,
798 EFX_PATTERN_BYTE_CHANGING,
799 EFX_ARRAY_SIZE(__siena_tables))) != 0)
800 goto fail3;
801
802 if ((rc = siena_nic_test_tables(enp, __siena_tables,
803 EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
804 goto fail4;
805
806 return (0);
807
808 fail4:
809 EFSYS_PROBE(fail4);
810 fail3:
811 EFSYS_PROBE(fail3);
812 fail2:
813 EFSYS_PROBE(fail2);
814 fail1:
815 EFSYS_PROBE1(fail1, efx_rc_t, rc);
816
817 return (rc);
818 }
819
820 #endif /* EFSYS_OPT_DIAG */
821
822 #endif /* EFSYS_OPT_SIENA */
823