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