2 * Copyright 2009 Solarflare Communications Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
35 static __checkReturn int
36 siena_nic_get_partn_mask(
38 __out unsigned int *maskp)
41 uint8_t outbuf[MC_CMD_NVRAM_TYPES_OUT_LEN];
44 req.emr_cmd = MC_CMD_NVRAM_TYPES;
45 EFX_STATIC_ASSERT(MC_CMD_NVRAM_TYPES_IN_LEN == 0);
46 req.emr_in_buf = NULL;
47 req.emr_in_length = 0;
48 req.emr_out_buf = outbuf;
49 req.emr_out_length = sizeof (outbuf);
51 efx_mcdi_execute(enp, &req);
53 if (req.emr_rc != 0) {
58 if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) {
63 *maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES);
70 EFSYS_PROBE1(fail1, int, rc);
75 static __checkReturn int
76 siena_nic_exit_assertion_handler(
80 uint8_t payload[MC_CMD_REBOOT_IN_LEN];
83 req.emr_cmd = MC_CMD_REBOOT;
84 req.emr_in_buf = payload;
85 req.emr_in_length = MC_CMD_REBOOT_IN_LEN;
86 EFX_STATIC_ASSERT(MC_CMD_REBOOT_OUT_LEN == 0);
87 req.emr_out_buf = NULL;
88 req.emr_out_length = 0;
90 MCDI_IN_SET_DWORD(req, REBOOT_IN_FLAGS,
91 MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION);
93 efx_mcdi_execute(enp, &req);
95 if (req.emr_rc != 0 && req.emr_rc != EIO) {
103 EFSYS_PROBE1(fail1, int, rc);
108 static __checkReturn int
109 siena_nic_read_assertion(
113 uint8_t payload[MAX(MC_CMD_GET_ASSERTS_IN_LEN,
114 MC_CMD_GET_ASSERTS_OUT_LEN)];
123 * Before we attempt to chat to the MC, we should verify that the MC
124 * isn't in it's assertion handler, either due to a previous reboot,
125 * or because we're reinitializing due to an eec_exception().
127 * Use GET_ASSERTS to read any assertion state that may be present.
128 * Retry this command twice. Once because a boot-time assertion failure
129 * might cause the 1st MCDI request to fail. And once again because
130 * we might race with siena_nic_exit_assertion_handler() running on the
135 req.emr_cmd = MC_CMD_GET_ASSERTS;
136 req.emr_in_buf = payload;
137 req.emr_in_length = MC_CMD_GET_ASSERTS_IN_LEN;
138 req.emr_out_buf = payload;
139 req.emr_out_length = MC_CMD_GET_ASSERTS_OUT_LEN;
141 MCDI_IN_SET_DWORD(req, GET_ASSERTS_IN_CLEAR, 1);
142 efx_mcdi_execute(enp, &req);
144 } while ((req.emr_rc == EINTR || req.emr_rc == EIO) && retry-- > 0);
146 if (req.emr_rc != 0) {
151 if (req.emr_out_length_used < MC_CMD_GET_ASSERTS_OUT_LEN) {
156 /* Print out any assertion state recorded */
157 flags = MCDI_OUT_DWORD(req, GET_ASSERTS_OUT_GLOBAL_FLAGS);
158 if (flags == MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS)
161 reason = (flags == MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL)
162 ? "system-level assertion"
163 : (flags == MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL)
164 ? "thread-level assertion"
165 : (flags == MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED)
167 : "unknown assertion";
168 EFSYS_PROBE3(mcpu_assertion,
169 const char *, reason, unsigned int,
170 MCDI_OUT_DWORD(req, GET_ASSERTS_OUT_SAVED_PC_OFFS),
172 MCDI_OUT_DWORD(req, GET_ASSERTS_OUT_THREAD_OFFS));
174 /* Print out the registers */
175 ofst = MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST;
176 for (index = 1; index < 32; index++) {
177 EFSYS_PROBE2(mcpu_register, unsigned int, index, unsigned int,
178 EFX_DWORD_FIELD(*MCDI_OUT(req, efx_dword_t, ofst),
180 ofst += sizeof (efx_dword_t);
182 EFSYS_ASSERT(ofst <= MC_CMD_GET_ASSERTS_OUT_LEN);
189 EFSYS_PROBE1(fail1, int, rc);
194 static __checkReturn int
197 __in boolean_t attach)
200 uint8_t payload[MC_CMD_DRV_ATTACH_IN_LEN];
203 req.emr_cmd = MC_CMD_DRV_ATTACH;
204 req.emr_in_buf = payload;
205 req.emr_in_length = MC_CMD_DRV_ATTACH_IN_LEN;
206 req.emr_out_buf = NULL;
207 req.emr_out_length = 0;
209 MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_NEW_STATE, attach ? 1 : 0);
210 MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_UPDATE, 1);
212 efx_mcdi_execute(enp, &req);
214 if (req.emr_rc != 0) {
219 if (req.emr_out_length_used < MC_CMD_DRV_ATTACH_OUT_LEN) {
229 EFSYS_PROBE1(fail1, int, rc);
234 #if EFSYS_OPT_PCIE_TUNE
237 siena_nic_pcie_extended_sync(
240 uint8_t inbuf[MC_CMD_WORKAROUND_IN_LEN];
244 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
246 req.emr_cmd = MC_CMD_WORKAROUND;
247 req.emr_in_buf = inbuf;
248 req.emr_in_length = sizeof (inbuf);
249 EFX_STATIC_ASSERT(MC_CMD_WORKAROUND_OUT_LEN == 0);
250 req.emr_out_buf = NULL;
251 req.emr_out_length = 0;
253 MCDI_IN_SET_DWORD(req, WORKAROUND_IN_TYPE, MC_CMD_WORKAROUND_BUG17230);
254 MCDI_IN_SET_DWORD(req, WORKAROUND_IN_ENABLED, 1);
256 efx_mcdi_execute(enp, &req);
258 if (req.emr_rc != 0) {
266 EFSYS_PROBE1(fail1, int, rc);
271 #endif /* EFSYS_OPT_PCIE_TUNE */
273 static __checkReturn int
277 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
278 efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
279 uint8_t outbuf[MAX(MC_CMD_GET_BOARD_CFG_OUT_LENMIN,
280 MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN)];
283 efx_dword_t *capabilities;
286 /* Board configuration */
287 req.emr_cmd = MC_CMD_GET_BOARD_CFG;
288 EFX_STATIC_ASSERT(MC_CMD_GET_BOARD_CFG_IN_LEN == 0);
289 req.emr_in_buf = NULL;
290 req.emr_in_length = 0;
291 req.emr_out_buf = outbuf;
292 req.emr_out_length = MC_CMD_GET_BOARD_CFG_OUT_LENMIN;
294 efx_mcdi_execute(enp, &req);
296 if (req.emr_rc != 0) {
301 if (req.emr_out_length_used < MC_CMD_GET_BOARD_CFG_OUT_LENMIN) {
306 if (emip->emi_port == 1) {
307 mac_addr = MCDI_OUT2(req, uint8_t,
308 GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0);
309 capabilities = MCDI_OUT2(req, efx_dword_t,
310 GET_BOARD_CFG_OUT_CAPABILITIES_PORT0);
312 mac_addr = MCDI_OUT2(req, uint8_t,
313 GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1);
314 capabilities = MCDI_OUT2(req, efx_dword_t,
315 GET_BOARD_CFG_OUT_CAPABILITIES_PORT1);
317 EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
319 encp->enc_board_type = MCDI_OUT_DWORD(req,
320 GET_BOARD_CFG_OUT_BOARD_TYPE);
322 /* Additional capabilities */
323 encp->enc_clk_mult = 1;
324 if (MCDI_CMD_DWORD_FIELD(capabilities, CAPABILITIES_TURBO)) {
325 enp->en_features |= EFX_FEATURE_TURBO;
327 if (MCDI_CMD_DWORD_FIELD(capabilities,
328 CAPABILITIES_TURBO_ACTIVE))
329 encp->enc_clk_mult = 2;
332 encp->enc_evq_moderation_max = EFX_EV_TIMER_QUANTUM <<
333 FRF_AB_TIMER_VAL_WIDTH / encp->enc_clk_mult;
335 /* Resource limits */
336 req.emr_cmd = MC_CMD_GET_RESOURCE_LIMITS;
337 EFX_STATIC_ASSERT(MC_CMD_GET_RESOURCE_LIMITS_IN_LEN == 0);
338 req.emr_in_buf = NULL;
339 req.emr_in_length = 0;
340 req.emr_out_buf = outbuf;
341 req.emr_out_length = MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN;
343 efx_mcdi_execute(enp, &req);
345 if (req.emr_rc == 0) {
346 if (req.emr_out_length_used <
347 MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN) {
352 encp->enc_evq_limit = MCDI_OUT_DWORD(req,
353 GET_RESOURCE_LIMITS_OUT_EVQ);
354 encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET,
355 MCDI_OUT_DWORD(req, GET_RESOURCE_LIMITS_OUT_TXQ));
356 encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET,
357 MCDI_OUT_DWORD(req, GET_RESOURCE_LIMITS_OUT_RXQ));
358 } else if (req.emr_rc == ENOTSUP) {
359 encp->enc_evq_limit = 1024;
360 encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET;
361 encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET;
367 encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
368 (encp->enc_txq_limit * 16) - (encp->enc_rxq_limit * 64);
379 EFSYS_PROBE1(fail1, int, rc);
384 static __checkReturn int
388 efx_port_t *epp = &(enp->en_port);
389 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
391 uint8_t outbuf[MC_CMD_GET_PHY_CFG_OUT_LEN];
394 req.emr_cmd = MC_CMD_GET_PHY_CFG;
395 EFX_STATIC_ASSERT(MC_CMD_GET_PHY_CFG_IN_LEN == 0);
396 req.emr_in_buf = NULL;
397 req.emr_in_length = 0;
398 req.emr_out_buf = outbuf;
399 req.emr_out_length = sizeof (outbuf);
401 efx_mcdi_execute(enp, &req);
403 if (req.emr_rc != 0) {
408 if (req.emr_out_length_used < MC_CMD_GET_PHY_CFG_OUT_LEN) {
413 encp->enc_phy_type = MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_TYPE);
415 (void) strncpy(encp->enc_phy_name,
416 MCDI_OUT2(req, char, GET_PHY_CFG_OUT_NAME),
417 MIN(sizeof (encp->enc_phy_name) - 1,
418 MC_CMD_GET_PHY_CFG_OUT_NAME_LEN));
419 #endif /* EFSYS_OPT_NAMES */
420 (void) memset(encp->enc_phy_revision, 0,
421 sizeof (encp->enc_phy_revision));
422 memcpy(encp->enc_phy_revision,
423 MCDI_OUT2(req, char, GET_PHY_CFG_OUT_REVISION),
424 MIN(sizeof (encp->enc_phy_revision) - 1,
425 MC_CMD_GET_PHY_CFG_OUT_REVISION_LEN));
426 #if EFSYS_OPT_PHY_LED_CONTROL
427 encp->enc_led_mask = ((1 << EFX_PHY_LED_DEFAULT) |
428 (1 << EFX_PHY_LED_OFF) |
429 (1 << EFX_PHY_LED_ON));
430 #endif /* EFSYS_OPT_PHY_LED_CONTROL */
432 #if EFSYS_OPT_PHY_PROPS
433 encp->enc_phy_nprops = 0;
434 #endif /* EFSYS_OPT_PHY_PROPS */
436 /* Get the media type of the fixed port, if recognised. */
437 EFX_STATIC_ASSERT(MC_CMD_MEDIA_XAUI == EFX_PHY_MEDIA_XAUI);
438 EFX_STATIC_ASSERT(MC_CMD_MEDIA_CX4 == EFX_PHY_MEDIA_CX4);
439 EFX_STATIC_ASSERT(MC_CMD_MEDIA_KX4 == EFX_PHY_MEDIA_KX4);
440 EFX_STATIC_ASSERT(MC_CMD_MEDIA_XFP == EFX_PHY_MEDIA_XFP);
441 EFX_STATIC_ASSERT(MC_CMD_MEDIA_SFP_PLUS == EFX_PHY_MEDIA_SFP_PLUS);
442 EFX_STATIC_ASSERT(MC_CMD_MEDIA_BASE_T == EFX_PHY_MEDIA_BASE_T);
443 epp->ep_fixed_port_type =
444 MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_MEDIA_TYPE);
445 if (epp->ep_fixed_port_type >= EFX_PHY_MEDIA_NTYPES)
446 epp->ep_fixed_port_type = EFX_PHY_MEDIA_INVALID;
448 epp->ep_phy_cap_mask =
449 MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_SUPPORTED_CAP);
450 #if EFSYS_OPT_PHY_FLAGS
451 encp->enc_phy_flags_mask = MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_FLAGS);
452 #endif /* EFSYS_OPT_PHY_FLAGS */
454 encp->enc_port = (uint8_t)MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_PRT);
456 /* Populate internal state */
457 encp->enc_siena_channel =
458 (uint8_t)MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_CHANNEL);
460 #if EFSYS_OPT_PHY_STATS
461 encp->enc_siena_phy_stat_mask =
462 MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_STATS_MASK);
464 /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
465 siena_phy_decode_stats(enp, encp->enc_siena_phy_stat_mask,
466 NULL, &encp->enc_phy_stat_mask, NULL);
467 #endif /* EFSYS_OPT_PHY_STATS */
469 #if EFSYS_OPT_PHY_BIST
470 encp->enc_bist_mask = 0;
471 if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
472 GET_PHY_CFG_OUT_BIST_CABLE_SHORT))
473 encp->enc_bist_mask |= (1 << EFX_PHY_BIST_TYPE_CABLE_SHORT);
474 if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
475 GET_PHY_CFG_OUT_BIST_CABLE_LONG))
476 encp->enc_bist_mask |= (1 << EFX_PHY_BIST_TYPE_CABLE_LONG);
477 if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
478 GET_PHY_CFG_OUT_BIST))
479 encp->enc_bist_mask |= (1 << EFX_PHY_BIST_TYPE_NORMAL);
480 #endif /* EFSYS_OPT_BIST */
487 EFSYS_PROBE1(fail1, int, rc);
492 #if EFSYS_OPT_LOOPBACK
494 static __checkReturn int
498 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
500 uint8_t outbuf[MC_CMD_GET_LOOPBACK_MODES_OUT_LEN];
503 req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
504 EFX_STATIC_ASSERT(MC_CMD_GET_LOOPBACK_MODES_IN_LEN == 0);
505 req.emr_in_buf = NULL;
506 req.emr_in_length = 0;
507 req.emr_out_buf = outbuf;
508 req.emr_out_length = sizeof (outbuf);
510 efx_mcdi_execute(enp, &req);
512 if (req.emr_rc != 0) {
517 if (req.emr_out_length_used < MC_CMD_GET_LOOPBACK_MODES_OUT_LEN) {
523 * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree
524 * in siena_phy.c:siena_phy_get_link()
526 encp->enc_loopback_types[EFX_LINK_100FDX] = EFX_LOOPBACK_MASK &
527 MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_100M) &
528 MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_SUGGESTED);
529 encp->enc_loopback_types[EFX_LINK_1000FDX] = EFX_LOOPBACK_MASK &
530 MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_1G) &
531 MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_SUGGESTED);
532 encp->enc_loopback_types[EFX_LINK_10000FDX] = EFX_LOOPBACK_MASK &
533 MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_10G) &
534 MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_SUGGESTED);
535 encp->enc_loopback_types[EFX_LINK_UNKNOWN] =
536 (1 << EFX_LOOPBACK_OFF) |
537 encp->enc_loopback_types[EFX_LINK_100FDX] |
538 encp->enc_loopback_types[EFX_LINK_1000FDX] |
539 encp->enc_loopback_types[EFX_LINK_10000FDX];
546 EFSYS_PROBE1(fail1, int, rc);
551 #endif /* EFSYS_OPT_LOOPBACK */
553 #if EFSYS_OPT_MON_STATS
555 static __checkReturn int
559 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
561 uint8_t outbuf[MCDI_CTL_SDU_LEN_MAX];
564 req.emr_cmd = MC_CMD_SENSOR_INFO;
565 EFX_STATIC_ASSERT(MC_CMD_SENSOR_INFO_IN_LEN == 0);
566 req.emr_in_buf = NULL;
567 req.emr_in_length = 0;
568 req.emr_out_buf = outbuf;
569 req.emr_out_length = sizeof (outbuf);
571 efx_mcdi_execute(enp, &req);
573 if (req.emr_rc != 0) {
578 if (req.emr_out_length_used < MC_CMD_SENSOR_INFO_OUT_MASK_OFST + 4) {
583 encp->enc_siena_mon_stat_mask =
584 MCDI_OUT_DWORD(req, SENSOR_INFO_OUT_MASK);
585 encp->enc_mon_type = EFX_MON_SFC90X0;
587 siena_mon_decode_stats(enp, encp->enc_siena_mon_stat_mask,
588 NULL, &(encp->enc_mon_stat_mask), NULL);
595 EFSYS_PROBE1(fail1, int, rc);
600 #endif /* EFSYS_OPT_MON_STATS */
606 efx_port_t *epp = &(enp->en_port);
607 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
608 siena_link_state_t sls;
612 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
614 /* Read clear any assertion state */
615 if ((rc = siena_nic_read_assertion(enp)) != 0)
618 /* Exit the assertion handler */
619 if ((rc = siena_nic_exit_assertion_handler(enp)) != 0)
622 /* Wrestle control from the BMC */
623 if ((rc = siena_nic_attach(enp, B_TRUE)) != 0)
626 if ((rc = siena_board_cfg(enp)) != 0)
629 if ((rc = siena_phy_cfg(enp)) != 0)
632 /* Obtain the default PHY advertised capabilities */
633 if ((rc = siena_nic_reset(enp)) != 0)
635 if ((rc = siena_phy_get_link(enp, &sls)) != 0)
637 epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
638 epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
640 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
641 if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
643 enp->en_u.siena.enu_partn_mask = mask;
646 #if EFSYS_OPT_MAC_STATS
647 /* Wipe the MAC statistics */
648 if ((rc = siena_mac_stats_clear(enp)) != 0)
652 #if EFSYS_OPT_LOOPBACK
653 if ((rc = siena_loopback_cfg(enp)) != 0)
657 #if EFSYS_OPT_MON_STATS
658 if ((rc = siena_monitor_cfg(enp)) != 0)
662 encp->enc_features = enp->en_features;
666 #if EFSYS_OPT_MON_STATS
670 #if EFSYS_OPT_LOOPBACK
674 #if EFSYS_OPT_MAC_STATS
678 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
695 EFSYS_PROBE1(fail1, int, rc);
707 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
709 /* siena_nic_reset() is called to recover from BADASSERT failures. */
710 if ((rc = siena_nic_read_assertion(enp)) != 0)
712 if ((rc = siena_nic_exit_assertion_handler(enp)) != 0)
715 req.emr_cmd = MC_CMD_PORT_RESET;
716 EFX_STATIC_ASSERT(MC_CMD_PORT_RESET_IN_LEN == 0);
717 req.emr_in_buf = NULL;
718 req.emr_in_length = 0;
719 EFX_STATIC_ASSERT(MC_CMD_PORT_RESET_OUT_LEN == 0);
720 req.emr_out_buf = NULL;
721 req.emr_out_length = 0;
723 efx_mcdi_execute(enp, &req);
725 if (req.emr_rc != 0) {
737 EFSYS_PROBE1(fail1, int, rc);
742 static __checkReturn int
747 uint8_t payload[MC_CMD_LOG_CTRL_IN_LEN];
750 req.emr_cmd = MC_CMD_LOG_CTRL;
751 req.emr_in_buf = payload;
752 req.emr_in_length = MC_CMD_LOG_CTRL_IN_LEN;
753 EFX_STATIC_ASSERT(MC_CMD_LOG_CTRL_OUT_LEN == 0);
754 req.emr_out_buf = NULL;
755 req.emr_out_length = 0;
757 MCDI_IN_SET_DWORD(req, LOG_CTRL_IN_LOG_DEST,
758 MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ);
759 MCDI_IN_SET_DWORD(req, LOG_CTRL_IN_LOG_DEST_EVQ, 0);
761 efx_mcdi_execute(enp, &req);
763 if (req.emr_rc != 0) {
771 EFSYS_PROBE1(fail1, int, rc);
783 * RX_INGR_EN is always enabled on Siena, because we rely on
784 * the RX parser to be resiliant to missing SOP/EOP.
786 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
787 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
788 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
790 /* Disable parsing of additional 802.1Q in Q packets */
791 EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
792 EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
793 EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
802 EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
803 EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
812 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
814 if ((rc = siena_nic_logging(enp)) != 0)
817 siena_sram_init(enp);
819 /* Configure Siena's RX block */
820 siena_nic_rx_cfg(enp);
822 /* Disable USR_EVents for now */
823 siena_nic_usrev_dis(enp);
825 /* bug17057: Ensure set_link is called */
826 if ((rc = siena_phy_reconfigure(enp)) != 0)
834 EFSYS_PROBE1(fail1, int, rc);
843 _NOTE(ARGUNUSED(enp))
850 (void) siena_nic_attach(enp, B_FALSE);
855 static efx_register_set_t __cs __siena_registers[] = {
856 { FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
857 { FR_CZ_USR_EV_CFG_OFST, 0, 1 },
858 { FR_AZ_RX_CFG_REG_OFST, 0, 1 },
859 { FR_AZ_TX_CFG_REG_OFST, 0, 1 },
860 { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
861 { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
862 { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
863 { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
864 { FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
865 { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
866 { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
867 { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
868 { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
871 static const uint32_t __cs __siena_register_masks[] = {
872 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
873 0x000103FF, 0x00000000, 0x00000000, 0x00000000,
874 0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
875 0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
876 0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
877 0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
878 0x00000003, 0x00000000, 0x00000000, 0x00000000,
879 0x000003FF, 0x00000000, 0x00000000, 0x00000000,
880 0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
881 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
882 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
883 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
884 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
887 static efx_register_set_t __cs __siena_tables[] = {
888 { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
889 FR_AZ_RX_FILTER_TBL0_ROWS },
890 { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
891 FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
892 { FR_AZ_RX_DESC_PTR_TBL_OFST,
893 FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
894 { FR_AZ_TX_DESC_PTR_TBL_OFST,
895 FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
896 { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
897 { FR_CZ_TX_FILTER_TBL0_OFST,
898 FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
899 { FR_CZ_TX_MAC_FILTER_TBL0_OFST,
900 FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
903 static const uint32_t __cs __siena_table_masks[] = {
904 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
905 0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
906 0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
907 0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
908 0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
909 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
910 0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
914 siena_nic_register_test(
917 efx_register_set_t *rsp;
918 const uint32_t *dwordp;
923 /* Fill out the register mask entries */
924 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
925 == EFX_ARRAY_SIZE(__siena_registers) * 4);
927 nitems = EFX_ARRAY_SIZE(__siena_registers);
928 dwordp = __siena_register_masks;
929 for (count = 0; count < nitems; ++count) {
930 rsp = __siena_registers + count;
931 rsp->mask.eo_u32[0] = *dwordp++;
932 rsp->mask.eo_u32[1] = *dwordp++;
933 rsp->mask.eo_u32[2] = *dwordp++;
934 rsp->mask.eo_u32[3] = *dwordp++;
937 /* Fill out the register table entries */
938 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
939 == EFX_ARRAY_SIZE(__siena_tables) * 4);
941 nitems = EFX_ARRAY_SIZE(__siena_tables);
942 dwordp = __siena_table_masks;
943 for (count = 0; count < nitems; ++count) {
944 rsp = __siena_tables + count;
945 rsp->mask.eo_u32[0] = *dwordp++;
946 rsp->mask.eo_u32[1] = *dwordp++;
947 rsp->mask.eo_u32[2] = *dwordp++;
948 rsp->mask.eo_u32[3] = *dwordp++;
951 if ((rc = efx_nic_test_registers(enp, __siena_registers,
952 EFX_ARRAY_SIZE(__siena_registers))) != 0)
955 if ((rc = efx_nic_test_tables(enp, __siena_tables,
956 EFX_PATTERN_BYTE_ALTERNATE,
957 EFX_ARRAY_SIZE(__siena_tables))) != 0)
960 if ((rc = efx_nic_test_tables(enp, __siena_tables,
961 EFX_PATTERN_BYTE_CHANGING,
962 EFX_ARRAY_SIZE(__siena_tables))) != 0)
965 if ((rc = efx_nic_test_tables(enp, __siena_tables,
966 EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
978 EFSYS_PROBE1(fail1, int, rc);
983 #endif /* EFSYS_OPT_DIAG */
985 #endif /* EFSYS_OPT_SIENA */