1 /* SPDX-License-Identifier: BSD-3-Clause
2 *
3 * Copyright(c) 2019-2020 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 /* There is one RSS context per function */
123 encp->enc_rx_scale_max_exclusive_contexts = 1;
124
125 encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_LFSR);
126 encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_TOEPLITZ);
127
128 /*
129 * It is always possible to use port numbers
130 * as the input data for hash computation.
131 */
132 encp->enc_rx_scale_l4_hash_supported = B_TRUE;
133
134 /* There is no support for additional RSS modes */
135 encp->enc_rx_scale_additional_modes_supported = B_FALSE;
136 #endif /* EFSYS_OPT_RX_SCALE */
137
138 /*
139 * Event queue creation is complete when an
140 * EVQ_INIT_DONE_EV event is received.
141 */
142 encp->enc_evq_init_done_ev_supported = B_TRUE;
143
144 encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT);
145 /* Fragments must not span 4k boundaries. */
146 encp->enc_tx_dma_desc_boundary = 4096;
147
148 /* Resource limits */
149 rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
150 if (rc != 0) {
151 if (rc != ENOTSUP)
152 goto fail2;
153
154 nevq = 1024;
155 nrxq = EFX_RXQ_LIMIT_TARGET;
156 ntxq = EFX_TXQ_LIMIT_TARGET;
157 }
158 encp->enc_evq_limit = nevq;
159 encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
160 encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
161
162 encp->enc_evq_max_nevs = SIENA_EVQ_MAXNEVS;
163 encp->enc_evq_min_nevs = SIENA_EVQ_MINNEVS;
164
165 encp->enc_rxq_max_ndescs = EF10_RXQ_MAXNDESCS;
166 encp->enc_rxq_min_ndescs = EF10_RXQ_MINNDESCS;
167
168 encp->enc_txq_max_ndescs = SIENA_TXQ_MAXNDESCS;
169 encp->enc_txq_min_ndescs = SIENA_TXQ_MINNDESCS;
170
171 encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
172 (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
173 (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
174
175 encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
176 encp->enc_fw_assisted_tso_enabled = B_FALSE;
177 encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
178 encp->enc_fw_assisted_tso_v2_n_contexts = 0;
179 encp->enc_tso_v3_enabled = B_FALSE;
180 encp->enc_rx_scatter_max = -1;
181 encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
182 encp->enc_rx_packed_stream_supported = B_FALSE;
183 encp->enc_rx_var_packed_stream_supported = B_FALSE;
184 encp->enc_rx_es_super_buffer_supported = B_FALSE;
185 encp->enc_fw_subvariant_no_tx_csum_supported = B_FALSE;
186
187 /* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */
188 encp->enc_required_pcie_bandwidth_mbps = 2 * 10000;
189 encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2;
190
191 encp->enc_nvram_update_verify_result_supported = B_FALSE;
192
193 encp->enc_mac_stats_nstats = MC_CMD_MAC_NSTATS;
194
195 encp->enc_filter_action_flag_supported = B_FALSE;
196 encp->enc_filter_action_mark_supported = B_FALSE;
197 encp->enc_filter_action_mark_max = 0;
198
199 encp->enc_mae_supported = B_FALSE;
200
201 return (0);
202
203 fail2:
204 EFSYS_PROBE(fail2);
205 fail1:
206 EFSYS_PROBE1(fail1, efx_rc_t, rc);
207
208 return (rc);
209 }
210
211 static __checkReturn efx_rc_t
siena_phy_cfg(__in efx_nic_t * enp)212 siena_phy_cfg(
213 __in efx_nic_t *enp)
214 {
215 #if EFSYS_OPT_PHY_STATS
216 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
217 #endif /* EFSYS_OPT_PHY_STATS */
218 efx_rc_t rc;
219
220 /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
221 if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
222 goto fail1;
223
224 #if EFSYS_OPT_PHY_STATS
225 /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
226 siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
227 NULL, &encp->enc_phy_stat_mask, NULL);
228 #endif /* EFSYS_OPT_PHY_STATS */
229
230 return (0);
231
232 fail1:
233 EFSYS_PROBE1(fail1, efx_rc_t, rc);
234
235 return (rc);
236 }
237
238 #define SIENA_BIU_MAGIC0 0x01234567
239 #define SIENA_BIU_MAGIC1 0xfedcba98
240
241 static __checkReturn efx_rc_t
siena_nic_biu_test(__in efx_nic_t * enp)242 siena_nic_biu_test(
243 __in efx_nic_t *enp)
244 {
245 efx_oword_t oword;
246 efx_rc_t rc;
247
248 /*
249 * Write magic values to scratch registers 0 and 1, then
250 * verify that the values were written correctly. Interleave
251 * the accesses to ensure that the BIU is not just reading
252 * back the cached value that was last written.
253 */
254 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC0);
255 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
256
257 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC1);
258 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
259
260 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
261 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC0) {
262 rc = EIO;
263 goto fail1;
264 }
265
266 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
267 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC1) {
268 rc = EIO;
269 goto fail2;
270 }
271
272 /*
273 * Perform the same test, with the values swapped. This
274 * ensures that subsequent tests don't start with the correct
275 * values already written into the scratch registers.
276 */
277 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC1);
278 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
279
280 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC0);
281 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
282
283 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
284 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC1) {
285 rc = EIO;
286 goto fail3;
287 }
288
289 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
290 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC0) {
291 rc = EIO;
292 goto fail4;
293 }
294
295 return (0);
296
297 fail4:
298 EFSYS_PROBE(fail4);
299 fail3:
300 EFSYS_PROBE(fail3);
301 fail2:
302 EFSYS_PROBE(fail2);
303 fail1:
304 EFSYS_PROBE1(fail1, efx_rc_t, rc);
305
306 return (rc);
307 }
308
309 __checkReturn efx_rc_t
siena_nic_probe(__in efx_nic_t * enp)310 siena_nic_probe(
311 __in efx_nic_t *enp)
312 {
313 efx_port_t *epp = &(enp->en_port);
314 siena_link_state_t sls;
315 unsigned int mask;
316 efx_oword_t oword;
317 efx_rc_t rc;
318
319 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
320
321 /* Test BIU */
322 if ((rc = siena_nic_biu_test(enp)) != 0)
323 goto fail1;
324
325 /* Clear the region register */
326 EFX_POPULATE_OWORD_4(oword,
327 FRF_AZ_ADR_REGION0, 0,
328 FRF_AZ_ADR_REGION1, (1 << 16),
329 FRF_AZ_ADR_REGION2, (2 << 16),
330 FRF_AZ_ADR_REGION3, (3 << 16));
331 EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
332
333 /* Read clear any assertion state */
334 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
335 goto fail2;
336
337 /* Exit the assertion handler */
338 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
339 goto fail3;
340
341 /* Wrestle control from the BMC */
342 if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
343 goto fail4;
344
345 if ((rc = siena_board_cfg(enp)) != 0)
346 goto fail5;
347
348 if ((rc = siena_phy_cfg(enp)) != 0)
349 goto fail6;
350
351 /* Obtain the default PHY advertised capabilities */
352 if ((rc = siena_nic_reset(enp)) != 0)
353 goto fail7;
354 if ((rc = siena_phy_get_link(enp, &sls)) != 0)
355 goto fail8;
356 epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
357 epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
358
359 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
360 if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
361 goto fail9;
362 enp->en_u.siena.enu_partn_mask = mask;
363 #endif
364
365 #if EFSYS_OPT_MAC_STATS
366 /* Wipe the MAC statistics */
367 if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
368 goto fail10;
369 #endif
370
371 #if EFSYS_OPT_LOOPBACK
372 if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
373 goto fail11;
374 #endif
375
376 #if EFSYS_OPT_MON_STATS
377 if ((rc = mcdi_mon_cfg_build(enp)) != 0)
378 goto fail12;
379 #endif
380
381 return (0);
382
383 #if EFSYS_OPT_MON_STATS
384 fail12:
385 EFSYS_PROBE(fail12);
386 #endif
387 #if EFSYS_OPT_LOOPBACK
388 fail11:
389 EFSYS_PROBE(fail11);
390 #endif
391 #if EFSYS_OPT_MAC_STATS
392 fail10:
393 EFSYS_PROBE(fail10);
394 #endif
395 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
396 fail9:
397 EFSYS_PROBE(fail9);
398 #endif
399 fail8:
400 EFSYS_PROBE(fail8);
401 fail7:
402 EFSYS_PROBE(fail7);
403 fail6:
404 EFSYS_PROBE(fail6);
405 fail5:
406 EFSYS_PROBE(fail5);
407 fail4:
408 EFSYS_PROBE(fail4);
409 fail3:
410 EFSYS_PROBE(fail3);
411 fail2:
412 EFSYS_PROBE(fail2);
413 fail1:
414 EFSYS_PROBE1(fail1, efx_rc_t, rc);
415
416 return (rc);
417 }
418
419 __checkReturn efx_rc_t
siena_nic_reset(__in efx_nic_t * enp)420 siena_nic_reset(
421 __in efx_nic_t *enp)
422 {
423 efx_mcdi_req_t req;
424 efx_rc_t rc;
425
426 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
427
428 /* siena_nic_reset() is called to recover from BADASSERT failures. */
429 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
430 goto fail1;
431 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
432 goto fail2;
433
434 /*
435 * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
436 * for backwards compatibility with PORT_RESET_IN_LEN.
437 */
438 EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
439
440 req.emr_cmd = MC_CMD_ENTITY_RESET;
441 req.emr_in_buf = NULL;
442 req.emr_in_length = 0;
443 req.emr_out_buf = NULL;
444 req.emr_out_length = 0;
445
446 efx_mcdi_execute(enp, &req);
447
448 if (req.emr_rc != 0) {
449 rc = req.emr_rc;
450 goto fail3;
451 }
452
453 return (0);
454
455 fail3:
456 EFSYS_PROBE(fail3);
457 fail2:
458 EFSYS_PROBE(fail2);
459 fail1:
460 EFSYS_PROBE1(fail1, efx_rc_t, rc);
461
462 return (0);
463 }
464
465 static void
siena_nic_rx_cfg(__in efx_nic_t * enp)466 siena_nic_rx_cfg(
467 __in efx_nic_t *enp)
468 {
469 efx_oword_t oword;
470
471 /*
472 * RX_INGR_EN is always enabled on Siena, because we rely on
473 * the RX parser to be resiliant to missing SOP/EOP.
474 */
475 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
476 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
477 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
478
479 /* Disable parsing of additional 802.1Q in Q packets */
480 EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
481 EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
482 EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
483 }
484
485 static void
siena_nic_usrev_dis(__in efx_nic_t * enp)486 siena_nic_usrev_dis(
487 __in efx_nic_t *enp)
488 {
489 efx_oword_t oword;
490
491 EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
492 EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
493 }
494
495 __checkReturn efx_rc_t
siena_nic_init(__in efx_nic_t * enp)496 siena_nic_init(
497 __in efx_nic_t *enp)
498 {
499 efx_rc_t rc;
500
501 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
502
503 /* Enable reporting of some events (e.g. link change) */
504 if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
505 goto fail1;
506
507 siena_sram_init(enp);
508
509 /* Configure Siena's RX block */
510 siena_nic_rx_cfg(enp);
511
512 /* Disable USR_EVents for now */
513 siena_nic_usrev_dis(enp);
514
515 /* bug17057: Ensure set_link is called */
516 if ((rc = siena_phy_reconfigure(enp)) != 0)
517 goto fail2;
518
519 enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;
520
521 return (0);
522
523 fail2:
524 EFSYS_PROBE(fail2);
525 fail1:
526 EFSYS_PROBE1(fail1, efx_rc_t, rc);
527
528 return (rc);
529 }
530
531 void
siena_nic_fini(__in efx_nic_t * enp)532 siena_nic_fini(
533 __in efx_nic_t *enp)
534 {
535 _NOTE(ARGUNUSED(enp))
536 }
537
538 void
siena_nic_unprobe(__in efx_nic_t * enp)539 siena_nic_unprobe(
540 __in efx_nic_t *enp)
541 {
542 #if EFSYS_OPT_MON_STATS
543 mcdi_mon_cfg_free(enp);
544 #endif /* EFSYS_OPT_MON_STATS */
545 (void) efx_mcdi_drv_attach(enp, B_FALSE);
546 }
547
548 #if EFSYS_OPT_DIAG
549
550 static siena_register_set_t __siena_registers[] = {
551 { FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
552 { FR_CZ_USR_EV_CFG_OFST, 0, 1 },
553 { FR_AZ_RX_CFG_REG_OFST, 0, 1 },
554 { FR_AZ_TX_CFG_REG_OFST, 0, 1 },
555 { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
556 { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
557 { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
558 { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
559 { FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
560 { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
561 { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
562 { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
563 { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
564 };
565
566 static const uint32_t __siena_register_masks[] = {
567 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
568 0x000103FF, 0x00000000, 0x00000000, 0x00000000,
569 0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
570 0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
571 0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
572 0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
573 0x00000003, 0x00000000, 0x00000000, 0x00000000,
574 0x000003FF, 0x00000000, 0x00000000, 0x00000000,
575 0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
576 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
577 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
578 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
579 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
580 };
581
582 static siena_register_set_t __siena_tables[] = {
583 { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
584 FR_AZ_RX_FILTER_TBL0_ROWS },
585 { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
586 FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
587 { FR_AZ_RX_DESC_PTR_TBL_OFST,
588 FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
589 { FR_AZ_TX_DESC_PTR_TBL_OFST,
590 FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
591 { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
592 { FR_CZ_TX_FILTER_TBL0_OFST,
593 FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
594 { FR_CZ_TX_MAC_FILTER_TBL0_OFST,
595 FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
596 };
597
598 static const uint32_t __siena_table_masks[] = {
599 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
600 0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
601 0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
602 0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
603 0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
604 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
605 0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
606 };
607
608 __checkReturn efx_rc_t
siena_nic_test_registers(__in efx_nic_t * enp,__in siena_register_set_t * rsp,__in size_t count)609 siena_nic_test_registers(
610 __in efx_nic_t *enp,
611 __in siena_register_set_t *rsp,
612 __in size_t count)
613 {
614 unsigned int bit;
615 efx_oword_t original;
616 efx_oword_t reg;
617 efx_oword_t buf;
618 efx_rc_t rc;
619
620 while (count > 0) {
621 /* This function is only suitable for registers */
622 EFSYS_ASSERT(rsp->rows == 1);
623
624 /* bit sweep on and off */
625 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &original,
626 B_TRUE);
627 for (bit = 0; bit < 128; bit++) {
628 /* Is this bit in the mask? */
629 if (~(rsp->mask.eo_u32[bit >> 5]) & (1 << bit))
630 continue;
631
632 /* Test this bit can be set in isolation */
633 reg = original;
634 EFX_AND_OWORD(reg, rsp->mask);
635 EFX_SET_OWORD_BIT(reg, bit);
636
637 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, ®,
638 B_TRUE);
639 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
640 B_TRUE);
641
642 EFX_AND_OWORD(buf, rsp->mask);
643 if (memcmp(®, &buf, sizeof (reg))) {
644 rc = EIO;
645 goto fail1;
646 }
647
648 /* Test this bit can be cleared in isolation */
649 EFX_OR_OWORD(reg, rsp->mask);
650 EFX_CLEAR_OWORD_BIT(reg, bit);
651
652 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, ®,
653 B_TRUE);
654 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
655 B_TRUE);
656
657 EFX_AND_OWORD(buf, rsp->mask);
658 if (memcmp(®, &buf, sizeof (reg))) {
659 rc = EIO;
660 goto fail2;
661 }
662 }
663
664 /* Restore the old value */
665 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original,
666 B_TRUE);
667
668 --count;
669 ++rsp;
670 }
671
672 return (0);
673
674 fail2:
675 EFSYS_PROBE(fail2);
676 fail1:
677 EFSYS_PROBE1(fail1, efx_rc_t, rc);
678
679 /* Restore the old value */
680 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, B_TRUE);
681
682 return (rc);
683 }
684
685 __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)686 siena_nic_test_tables(
687 __in efx_nic_t *enp,
688 __in siena_register_set_t *rsp,
689 __in efx_pattern_type_t pattern,
690 __in size_t count)
691 {
692 efx_sram_pattern_fn_t func;
693 unsigned int index;
694 unsigned int address;
695 efx_oword_t reg;
696 efx_oword_t buf;
697 efx_rc_t rc;
698
699 EFSYS_ASSERT(pattern < EFX_PATTERN_NTYPES);
700 func = __efx_sram_pattern_fns[pattern];
701
702 while (count > 0) {
703 /* Write */
704 address = rsp->address;
705 for (index = 0; index < rsp->rows; ++index) {
706 func(2 * index + 0, B_FALSE, ®.eo_qword[0]);
707 func(2 * index + 1, B_FALSE, ®.eo_qword[1]);
708 EFX_AND_OWORD(reg, rsp->mask);
709 EFSYS_BAR_WRITEO(enp->en_esbp, address, ®, B_TRUE);
710
711 address += rsp->step;
712 }
713
714 /* Read */
715 address = rsp->address;
716 for (index = 0; index < rsp->rows; ++index) {
717 func(2 * index + 0, B_FALSE, ®.eo_qword[0]);
718 func(2 * index + 1, B_FALSE, ®.eo_qword[1]);
719 EFX_AND_OWORD(reg, rsp->mask);
720 EFSYS_BAR_READO(enp->en_esbp, address, &buf, B_TRUE);
721 if (memcmp(®, &buf, sizeof (reg))) {
722 rc = EIO;
723 goto fail1;
724 }
725
726 address += rsp->step;
727 }
728
729 ++rsp;
730 --count;
731 }
732
733 return (0);
734
735 fail1:
736 EFSYS_PROBE1(fail1, efx_rc_t, rc);
737
738 return (rc);
739 }
740
741
742 __checkReturn efx_rc_t
siena_nic_register_test(__in efx_nic_t * enp)743 siena_nic_register_test(
744 __in efx_nic_t *enp)
745 {
746 siena_register_set_t *rsp;
747 const uint32_t *dwordp;
748 unsigned int nitems;
749 unsigned int count;
750 efx_rc_t rc;
751
752 /* Fill out the register mask entries */
753 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
754 == EFX_ARRAY_SIZE(__siena_registers) * 4);
755
756 nitems = EFX_ARRAY_SIZE(__siena_registers);
757 dwordp = __siena_register_masks;
758 for (count = 0; count < nitems; ++count) {
759 rsp = __siena_registers + count;
760 rsp->mask.eo_u32[0] = *dwordp++;
761 rsp->mask.eo_u32[1] = *dwordp++;
762 rsp->mask.eo_u32[2] = *dwordp++;
763 rsp->mask.eo_u32[3] = *dwordp++;
764 }
765
766 /* Fill out the register table entries */
767 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
768 == EFX_ARRAY_SIZE(__siena_tables) * 4);
769
770 nitems = EFX_ARRAY_SIZE(__siena_tables);
771 dwordp = __siena_table_masks;
772 for (count = 0; count < nitems; ++count) {
773 rsp = __siena_tables + count;
774 rsp->mask.eo_u32[0] = *dwordp++;
775 rsp->mask.eo_u32[1] = *dwordp++;
776 rsp->mask.eo_u32[2] = *dwordp++;
777 rsp->mask.eo_u32[3] = *dwordp++;
778 }
779
780 if ((rc = siena_nic_test_registers(enp, __siena_registers,
781 EFX_ARRAY_SIZE(__siena_registers))) != 0)
782 goto fail1;
783
784 if ((rc = siena_nic_test_tables(enp, __siena_tables,
785 EFX_PATTERN_BYTE_ALTERNATE,
786 EFX_ARRAY_SIZE(__siena_tables))) != 0)
787 goto fail2;
788
789 if ((rc = siena_nic_test_tables(enp, __siena_tables,
790 EFX_PATTERN_BYTE_CHANGING,
791 EFX_ARRAY_SIZE(__siena_tables))) != 0)
792 goto fail3;
793
794 if ((rc = siena_nic_test_tables(enp, __siena_tables,
795 EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
796 goto fail4;
797
798 return (0);
799
800 fail4:
801 EFSYS_PROBE(fail4);
802 fail3:
803 EFSYS_PROBE(fail3);
804 fail2:
805 EFSYS_PROBE(fail2);
806 fail1:
807 EFSYS_PROBE1(fail1, efx_rc_t, rc);
808
809 return (rc);
810 }
811
812 #endif /* EFSYS_OPT_DIAG */
813
814 #endif /* EFSYS_OPT_SIENA */
815