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_LEN,
280 MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN)];
285 /* Board configuration */
286 req.emr_cmd = MC_CMD_GET_BOARD_CFG;
287 EFX_STATIC_ASSERT(MC_CMD_GET_BOARD_CFG_IN_LEN == 0);
288 req.emr_in_buf = NULL;
289 req.emr_in_length = 0;
290 req.emr_out_buf = outbuf;
291 req.emr_out_length = MC_CMD_GET_BOARD_CFG_OUT_LEN;
293 efx_mcdi_execute(enp, &req);
295 if (req.emr_rc != 0) {
300 if (req.emr_out_length_used < MC_CMD_GET_BOARD_CFG_OUT_LEN) {
305 if (emip->emi_port == 1)
306 src = MCDI_OUT2(req, uint8_t,
307 GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0);
309 src = MCDI_OUT2(req, uint8_t,
310 GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1);
311 EFX_MAC_ADDR_COPY(encp->enc_mac_addr, src);
313 encp->enc_board_type = MCDI_OUT_DWORD(req,
314 GET_BOARD_CFG_OUT_BOARD_TYPE);
316 /* Resource limits */
317 req.emr_cmd = MC_CMD_GET_RESOURCE_LIMITS;
318 EFX_STATIC_ASSERT(MC_CMD_GET_RESOURCE_LIMITS_IN_LEN == 0);
319 req.emr_in_buf = NULL;
320 req.emr_in_length = 0;
321 req.emr_out_buf = outbuf;
322 req.emr_out_length = MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN;
324 efx_mcdi_execute(enp, &req);
326 if (req.emr_rc == 0) {
327 if (req.emr_out_length_used <
328 MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN) {
333 encp->enc_evq_limit = MCDI_OUT_DWORD(req,
334 GET_RESOURCE_LIMITS_OUT_EVQ);
335 encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET,
336 MCDI_OUT_DWORD(req, GET_RESOURCE_LIMITS_OUT_TXQ));
337 encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET,
338 MCDI_OUT_DWORD(req, GET_RESOURCE_LIMITS_OUT_RXQ));
339 } else if (req.emr_rc == ENOTSUP) {
340 encp->enc_evq_limit = 1024;
341 encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET;
342 encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET;
348 encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
349 (encp->enc_txq_limit * 16) - (encp->enc_rxq_limit * 64);
360 EFSYS_PROBE1(fail1, int, rc);
365 static __checkReturn int
369 efx_port_t *epp = &(enp->en_port);
370 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
372 uint8_t outbuf[MC_CMD_GET_PHY_CFG_OUT_LEN];
375 req.emr_cmd = MC_CMD_GET_PHY_CFG;
376 EFX_STATIC_ASSERT(MC_CMD_GET_PHY_CFG_IN_LEN == 0);
377 req.emr_in_buf = NULL;
378 req.emr_in_length = 0;
379 req.emr_out_buf = outbuf;
380 req.emr_out_length = sizeof (outbuf);
382 efx_mcdi_execute(enp, &req);
384 if (req.emr_rc != 0) {
389 if (req.emr_out_length_used < MC_CMD_GET_PHY_CFG_OUT_LEN) {
394 encp->enc_phy_type = MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_TYPE);
396 (void) strncpy(encp->enc_phy_name,
397 MCDI_OUT2(req, char, GET_PHY_CFG_OUT_NAME),
398 MIN(sizeof (encp->enc_phy_name) - 1,
399 MC_CMD_GET_PHY_CFG_OUT_NAME_LEN));
400 #endif /* EFSYS_OPT_NAMES */
401 (void) memset(encp->enc_phy_revision, 0,
402 sizeof (encp->enc_phy_revision));
403 memcpy(encp->enc_phy_revision,
404 MCDI_OUT2(req, char, GET_PHY_CFG_OUT_REVISION),
405 MIN(sizeof (encp->enc_phy_revision) - 1,
406 MC_CMD_GET_PHY_CFG_OUT_REVISION_LEN));
407 #if EFSYS_OPT_PHY_LED_CONTROL
408 encp->enc_led_mask = ((1 << EFX_PHY_LED_DEFAULT) |
409 (1 << EFX_PHY_LED_OFF) |
410 (1 << EFX_PHY_LED_ON));
411 #endif /* EFSYS_OPT_PHY_LED_CONTROL */
413 #if EFSYS_OPT_PHY_PROPS
414 encp->enc_phy_nprops = 0;
415 #endif /* EFSYS_OPT_PHY_PROPS */
417 /* Get the media type of the fixed port, if recognised. */
418 EFX_STATIC_ASSERT(MC_CMD_MEDIA_XAUI == EFX_PHY_MEDIA_XAUI);
419 EFX_STATIC_ASSERT(MC_CMD_MEDIA_CX4 == EFX_PHY_MEDIA_CX4);
420 EFX_STATIC_ASSERT(MC_CMD_MEDIA_KX4 == EFX_PHY_MEDIA_KX4);
421 EFX_STATIC_ASSERT(MC_CMD_MEDIA_XFP == EFX_PHY_MEDIA_XFP);
422 EFX_STATIC_ASSERT(MC_CMD_MEDIA_SFP_PLUS == EFX_PHY_MEDIA_SFP_PLUS);
423 EFX_STATIC_ASSERT(MC_CMD_MEDIA_BASE_T == EFX_PHY_MEDIA_BASE_T);
424 epp->ep_fixed_port_type =
425 MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_MEDIA_TYPE);
426 if (epp->ep_fixed_port_type >= EFX_PHY_MEDIA_NTYPES)
427 epp->ep_fixed_port_type = EFX_PHY_MEDIA_INVALID;
429 epp->ep_phy_cap_mask =
430 MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_SUPPORTED_CAP);
431 #if EFSYS_OPT_PHY_FLAGS
432 encp->enc_phy_flags_mask = MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_FLAGS);
433 #endif /* EFSYS_OPT_PHY_FLAGS */
435 encp->enc_port = (uint8_t)MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_PRT);
437 /* Populate internal state */
438 encp->enc_siena_channel =
439 (uint8_t)MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_CHANNEL);
441 #if EFSYS_OPT_PHY_STATS
442 encp->enc_siena_phy_stat_mask =
443 MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_STATS_MASK);
445 /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
446 siena_phy_decode_stats(enp, encp->enc_siena_phy_stat_mask,
447 NULL, &encp->enc_phy_stat_mask, NULL);
448 #endif /* EFSYS_OPT_PHY_STATS */
450 #if EFSYS_OPT_PHY_BIST
451 encp->enc_bist_mask = 0;
452 if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
453 GET_PHY_CFG_OUT_BIST_CABLE_SHORT))
454 encp->enc_bist_mask |= (1 << EFX_PHY_BIST_TYPE_CABLE_SHORT);
455 if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
456 GET_PHY_CFG_OUT_BIST_CABLE_LONG))
457 encp->enc_bist_mask |= (1 << EFX_PHY_BIST_TYPE_CABLE_LONG);
458 if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
459 GET_PHY_CFG_OUT_BIST))
460 encp->enc_bist_mask |= (1 << EFX_PHY_BIST_TYPE_NORMAL);
461 #endif /* EFSYS_OPT_BIST */
468 EFSYS_PROBE1(fail1, int, rc);
473 #if EFSYS_OPT_LOOPBACK
475 static __checkReturn int
479 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
481 uint8_t outbuf[MC_CMD_GET_LOOPBACK_MODES_OUT_LEN];
484 req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
485 EFX_STATIC_ASSERT(MC_CMD_GET_LOOPBACK_MODES_IN_LEN == 0);
486 req.emr_in_buf = NULL;
487 req.emr_in_length = 0;
488 req.emr_out_buf = outbuf;
489 req.emr_out_length = sizeof (outbuf);
491 efx_mcdi_execute(enp, &req);
493 if (req.emr_rc != 0) {
498 if (req.emr_out_length_used < MC_CMD_GET_LOOPBACK_MODES_OUT_LEN) {
504 * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree
505 * in siena_phy.c:siena_phy_get_link()
507 encp->enc_loopback_types[EFX_LINK_100FDX] = EFX_LOOPBACK_MASK &
508 MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_100M) &
509 MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_SUGGESTED);
510 encp->enc_loopback_types[EFX_LINK_1000FDX] = EFX_LOOPBACK_MASK &
511 MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_1G) &
512 MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_SUGGESTED);
513 encp->enc_loopback_types[EFX_LINK_10000FDX] = EFX_LOOPBACK_MASK &
514 MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_10G) &
515 MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_SUGGESTED);
516 encp->enc_loopback_types[EFX_LINK_UNKNOWN] =
517 (1 << EFX_LOOPBACK_OFF) |
518 encp->enc_loopback_types[EFX_LINK_100FDX] |
519 encp->enc_loopback_types[EFX_LINK_1000FDX] |
520 encp->enc_loopback_types[EFX_LINK_10000FDX];
527 EFSYS_PROBE1(fail1, int, rc);
532 #endif /* EFSYS_OPT_LOOPBACK */
534 #if EFSYS_OPT_MON_STATS
536 static __checkReturn int
540 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
542 uint8_t outbuf[MCDI_CTL_SDU_LEN_MAX];
545 req.emr_cmd = MC_CMD_SENSOR_INFO;
546 EFX_STATIC_ASSERT(MC_CMD_SENSOR_INFO_IN_LEN == 0);
547 req.emr_in_buf = NULL;
548 req.emr_in_length = 0;
549 req.emr_out_buf = outbuf;
550 req.emr_out_length = sizeof (outbuf);
552 efx_mcdi_execute(enp, &req);
554 if (req.emr_rc != 0) {
559 if (req.emr_out_length_used < MC_CMD_SENSOR_INFO_OUT_MASK_OFST + 4) {
564 encp->enc_siena_mon_stat_mask =
565 MCDI_OUT_DWORD(req, SENSOR_INFO_OUT_MASK);
566 encp->enc_mon_type = EFX_MON_SFC90X0;
568 siena_mon_decode_stats(enp, encp->enc_siena_mon_stat_mask,
569 NULL, &(encp->enc_mon_stat_mask), NULL);
576 EFSYS_PROBE1(fail1, int, rc);
581 #endif /* EFSYS_OPT_MON_STATS */
587 efx_port_t *epp = &(enp->en_port);
588 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
589 siena_link_state_t sls;
593 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
595 /* Read clear any assertion state */
596 if ((rc = siena_nic_read_assertion(enp)) != 0)
599 /* Exit the assertion handler */
600 if ((rc = siena_nic_exit_assertion_handler(enp)) != 0)
603 /* Wrestle control from the BMC */
604 if ((rc = siena_nic_attach(enp, B_TRUE)) != 0)
607 if ((rc = siena_board_cfg(enp)) != 0)
610 encp->enc_evq_moderation_max =
611 EFX_EV_TIMER_QUANTUM << FRF_CZ_TIMER_VAL_WIDTH;
613 if ((rc = siena_phy_cfg(enp)) != 0)
616 /* Obtain the default PHY advertised capabilities */
617 if ((rc = siena_nic_reset(enp)) != 0)
619 if ((rc = siena_phy_get_link(enp, &sls)) != 0)
621 epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
622 epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
624 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
625 if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
627 enp->en_u.siena.enu_partn_mask = mask;
630 #if EFSYS_OPT_MAC_STATS
631 /* Wipe the MAC statistics */
632 if ((rc = siena_mac_stats_clear(enp)) != 0)
636 #if EFSYS_OPT_LOOPBACK
637 if ((rc = siena_loopback_cfg(enp)) != 0)
641 #if EFSYS_OPT_MON_STATS
642 if ((rc = siena_monitor_cfg(enp)) != 0)
646 encp->enc_features = enp->en_features;
650 #if EFSYS_OPT_MON_STATS
654 #if EFSYS_OPT_LOOPBACK
658 #if EFSYS_OPT_MAC_STATS
662 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
679 EFSYS_PROBE1(fail1, int, rc);
691 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
693 /* siena_nic_reset() is called to recover from BADASSERT failures. */
694 if ((rc = siena_nic_read_assertion(enp)) != 0)
696 if ((rc = siena_nic_exit_assertion_handler(enp)) != 0)
699 req.emr_cmd = MC_CMD_PORT_RESET;
700 EFX_STATIC_ASSERT(MC_CMD_PORT_RESET_IN_LEN == 0);
701 req.emr_in_buf = NULL;
702 req.emr_in_length = 0;
703 EFX_STATIC_ASSERT(MC_CMD_PORT_RESET_OUT_LEN == 0);
704 req.emr_out_buf = NULL;
705 req.emr_out_length = 0;
707 efx_mcdi_execute(enp, &req);
709 if (req.emr_rc != 0) {
721 EFSYS_PROBE1(fail1, int, rc);
726 static __checkReturn int
731 uint8_t payload[MC_CMD_LOG_CTRL_IN_LEN];
734 req.emr_cmd = MC_CMD_LOG_CTRL;
735 req.emr_in_buf = payload;
736 req.emr_in_length = MC_CMD_LOG_CTRL_IN_LEN;
737 EFX_STATIC_ASSERT(MC_CMD_LOG_CTRL_OUT_LEN == 0);
738 req.emr_out_buf = NULL;
739 req.emr_out_length = 0;
741 MCDI_IN_SET_DWORD(req, LOG_CTRL_IN_LOG_DEST,
742 MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ);
743 MCDI_IN_SET_DWORD(req, LOG_CTRL_IN_LOG_DEST_EVQ, 0);
745 efx_mcdi_execute(enp, &req);
747 if (req.emr_rc != 0) {
755 EFSYS_PROBE1(fail1, int, rc);
767 * RX_INGR_EN is always enabled on Siena, because we rely on
768 * the RX parser to be resiliant to missing SOP/EOP.
770 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
771 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
772 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
774 /* Disable parsing of additional 802.1Q in Q packets */
775 EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
776 EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
777 EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
786 EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
787 EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
796 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
798 if ((rc = siena_nic_logging(enp)) != 0)
801 siena_sram_init(enp);
803 /* Configure Siena's RX block */
804 siena_nic_rx_cfg(enp);
806 /* Disable USR_EVents for now */
807 siena_nic_usrev_dis(enp);
809 /* bug17057: Ensure set_link is called */
810 if ((rc = siena_phy_reconfigure(enp)) != 0)
818 EFSYS_PROBE1(fail1, int, rc);
827 _NOTE(ARGUNUSED(enp))
834 (void) siena_nic_attach(enp, B_FALSE);
839 static efx_register_set_t __cs __siena_registers[] = {
840 { FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
841 { FR_CZ_USR_EV_CFG_OFST, 0, 1 },
842 { FR_AZ_RX_CFG_REG_OFST, 0, 1 },
843 { FR_AZ_TX_CFG_REG_OFST, 0, 1 },
844 { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
845 { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
846 { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
847 { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
848 { FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
849 { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
850 { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
851 { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
852 { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
855 static const uint32_t __cs __siena_register_masks[] = {
856 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
857 0x000103FF, 0x00000000, 0x00000000, 0x00000000,
858 0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
859 0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
860 0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
861 0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
862 0x00000003, 0x00000000, 0x00000000, 0x00000000,
863 0x000003FF, 0x00000000, 0x00000000, 0x00000000,
864 0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
865 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
866 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
867 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
868 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
871 static efx_register_set_t __cs __siena_tables[] = {
872 { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
873 FR_AZ_RX_FILTER_TBL0_ROWS },
874 { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
875 FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
876 { FR_AZ_RX_DESC_PTR_TBL_OFST,
877 FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
878 { FR_AZ_TX_DESC_PTR_TBL_OFST,
879 FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
880 { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
881 { FR_CZ_TX_FILTER_TBL0_OFST,
882 FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
883 { FR_CZ_TX_MAC_FILTER_TBL0_OFST,
884 FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
887 static const uint32_t __cs __siena_table_masks[] = {
888 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
889 0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
890 0xFFFFFFFF, 0x0FFFFFFF, 0x01800000, 0x00000000,
891 0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
892 0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
893 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
894 0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
898 siena_nic_register_test(
901 efx_register_set_t *rsp;
902 const uint32_t *dwordp;
907 /* Fill out the register mask entries */
908 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
909 == EFX_ARRAY_SIZE(__siena_registers) * 4);
911 nitems = EFX_ARRAY_SIZE(__siena_registers);
912 dwordp = __siena_register_masks;
913 for (count = 0; count < nitems; ++count) {
914 rsp = __siena_registers + count;
915 rsp->mask.eo_u32[0] = *dwordp++;
916 rsp->mask.eo_u32[1] = *dwordp++;
917 rsp->mask.eo_u32[2] = *dwordp++;
918 rsp->mask.eo_u32[3] = *dwordp++;
921 /* Fill out the register table entries */
922 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
923 == EFX_ARRAY_SIZE(__siena_tables) * 4);
925 nitems = EFX_ARRAY_SIZE(__siena_tables);
926 dwordp = __siena_table_masks;
927 for (count = 0; count < nitems; ++count) {
928 rsp = __siena_tables + count;
929 rsp->mask.eo_u32[0] = *dwordp++;
930 rsp->mask.eo_u32[1] = *dwordp++;
931 rsp->mask.eo_u32[2] = *dwordp++;
932 rsp->mask.eo_u32[3] = *dwordp++;
935 if ((rc = efx_nic_test_registers(enp, __siena_registers,
936 EFX_ARRAY_SIZE(__siena_registers))) != 0)
939 if ((rc = efx_nic_test_tables(enp, __siena_tables,
940 EFX_PATTERN_BYTE_ALTERNATE,
941 EFX_ARRAY_SIZE(__siena_tables))) != 0)
944 if ((rc = efx_nic_test_tables(enp, __siena_tables,
945 EFX_PATTERN_BYTE_CHANGING,
946 EFX_ARRAY_SIZE(__siena_tables))) != 0)
949 if ((rc = efx_nic_test_tables(enp, __siena_tables,
950 EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
962 EFSYS_PROBE1(fail1, int, rc);
967 #endif /* EFSYS_OPT_DIAG */
969 #endif /* EFSYS_OPT_SIENA */