2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2009-2016 Solarflare Communications Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
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.
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.
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.
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
42 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
44 static __checkReturn efx_rc_t
45 siena_nic_get_partn_mask(
47 __out unsigned int *maskp)
50 uint8_t payload[MAX(MC_CMD_NVRAM_TYPES_IN_LEN,
51 MC_CMD_NVRAM_TYPES_OUT_LEN)];
54 (void) memset(payload, 0, sizeof (payload));
55 req.emr_cmd = MC_CMD_NVRAM_TYPES;
56 req.emr_in_buf = payload;
57 req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN;
58 req.emr_out_buf = payload;
59 req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN;
61 efx_mcdi_execute(enp, &req);
63 if (req.emr_rc != 0) {
68 if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) {
73 *maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES);
80 EFSYS_PROBE1(fail1, efx_rc_t, rc);
85 #endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
87 static __checkReturn efx_rc_t
91 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
93 efx_dword_t capabilities;
95 uint32_t nevq, nrxq, ntxq;
98 /* External port identifier using one-based port numbering */
99 encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port;
101 /* Board configuration */
102 if ((rc = efx_mcdi_get_board_cfg(enp, &board_type,
103 &capabilities, mac_addr)) != 0)
106 EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
108 encp->enc_board_type = board_type;
111 * There is no possibility to determine the number of PFs on Siena
112 * by issuing MCDI request, and it is not an easy task to find the
113 * value based on the board type, so 'enc_hw_pf_count' is set to 1
115 encp->enc_hw_pf_count = 1;
117 /* Additional capabilities */
118 encp->enc_clk_mult = 1;
119 if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) {
120 enp->en_features |= EFX_FEATURE_TURBO;
122 if (EFX_DWORD_FIELD(capabilities,
123 MC_CMD_CAPABILITIES_TURBO_ACTIVE)) {
124 encp->enc_clk_mult = 2;
128 encp->enc_evq_timer_quantum_ns =
129 EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult;
130 encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
131 FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
133 /* When hash header insertion is enabled, Siena inserts 16 bytes */
134 encp->enc_rx_prefix_size = 16;
136 /* Alignment for receive packet DMA buffers */
137 encp->enc_rx_buf_align_start = 1;
138 encp->enc_rx_buf_align_end = 1;
140 /* Alignment for WPTR updates */
141 encp->enc_rx_push_align = 1;
143 encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT);
144 /* Fragments must not span 4k boundaries. */
145 encp->enc_tx_dma_desc_boundary = 4096;
147 /* Resource limits */
148 rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
154 nrxq = EFX_RXQ_LIMIT_TARGET;
155 ntxq = EFX_TXQ_LIMIT_TARGET;
157 encp->enc_evq_limit = nevq;
158 encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
159 encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
161 encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
162 (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
163 (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
165 encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
166 encp->enc_fw_assisted_tso_enabled = B_FALSE;
167 encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
168 encp->enc_fw_assisted_tso_v2_n_contexts = 0;
169 encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
171 /* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */
172 encp->enc_required_pcie_bandwidth_mbps = 2 * 10000;
173 encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2;
175 encp->enc_fw_verified_nvram_update_required = B_FALSE;
182 EFSYS_PROBE1(fail1, efx_rc_t, rc);
187 static __checkReturn efx_rc_t
191 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
194 /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
195 if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
198 #if EFSYS_OPT_PHY_STATS
199 /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
200 siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
201 NULL, &encp->enc_phy_stat_mask, NULL);
202 #endif /* EFSYS_OPT_PHY_STATS */
207 EFSYS_PROBE1(fail1, efx_rc_t, rc);
212 __checkReturn efx_rc_t
216 efx_port_t *epp = &(enp->en_port);
217 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
218 siena_link_state_t sls;
223 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
226 if ((rc = efx_nic_biu_test(enp)) != 0)
229 /* Clear the region register */
230 EFX_POPULATE_OWORD_4(oword,
231 FRF_AZ_ADR_REGION0, 0,
232 FRF_AZ_ADR_REGION1, (1 << 16),
233 FRF_AZ_ADR_REGION2, (2 << 16),
234 FRF_AZ_ADR_REGION3, (3 << 16));
235 EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
237 /* Read clear any assertion state */
238 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
241 /* Exit the assertion handler */
242 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
245 /* Wrestle control from the BMC */
246 if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
249 if ((rc = siena_board_cfg(enp)) != 0)
252 if ((rc = siena_phy_cfg(enp)) != 0)
255 /* Obtain the default PHY advertised capabilities */
256 if ((rc = siena_nic_reset(enp)) != 0)
258 if ((rc = siena_phy_get_link(enp, &sls)) != 0)
260 epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
261 epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
263 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
264 if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
266 enp->en_u.siena.enu_partn_mask = mask;
269 #if EFSYS_OPT_MAC_STATS
270 /* Wipe the MAC statistics */
271 if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
275 #if EFSYS_OPT_LOOPBACK
276 if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
280 #if EFSYS_OPT_MON_STATS
281 if ((rc = mcdi_mon_cfg_build(enp)) != 0)
285 encp->enc_features = enp->en_features;
289 #if EFSYS_OPT_MON_STATS
293 #if EFSYS_OPT_LOOPBACK
297 #if EFSYS_OPT_MAC_STATS
301 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
320 EFSYS_PROBE1(fail1, efx_rc_t, rc);
325 __checkReturn efx_rc_t
332 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
334 /* siena_nic_reset() is called to recover from BADASSERT failures. */
335 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
337 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
341 * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
342 * for backwards compatibility with PORT_RESET_IN_LEN.
344 EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
346 req.emr_cmd = MC_CMD_ENTITY_RESET;
347 req.emr_in_buf = NULL;
348 req.emr_in_length = 0;
349 req.emr_out_buf = NULL;
350 req.emr_out_length = 0;
352 efx_mcdi_execute(enp, &req);
354 if (req.emr_rc != 0) {
366 EFSYS_PROBE1(fail1, efx_rc_t, rc);
378 * RX_INGR_EN is always enabled on Siena, because we rely on
379 * the RX parser to be resiliant to missing SOP/EOP.
381 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
382 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
383 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
385 /* Disable parsing of additional 802.1Q in Q packets */
386 EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
387 EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
388 EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
397 EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
398 EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
401 __checkReturn efx_rc_t
407 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
409 /* Enable reporting of some events (e.g. link change) */
410 if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
413 siena_sram_init(enp);
415 /* Configure Siena's RX block */
416 siena_nic_rx_cfg(enp);
418 /* Disable USR_EVents for now */
419 siena_nic_usrev_dis(enp);
421 /* bug17057: Ensure set_link is called */
422 if ((rc = siena_phy_reconfigure(enp)) != 0)
425 enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;
432 EFSYS_PROBE1(fail1, efx_rc_t, rc);
441 _NOTE(ARGUNUSED(enp))
448 #if EFSYS_OPT_MON_STATS
449 mcdi_mon_cfg_free(enp);
450 #endif /* EFSYS_OPT_MON_STATS */
451 (void) efx_mcdi_drv_attach(enp, B_FALSE);
456 static efx_register_set_t __siena_registers[] = {
457 { FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
458 { FR_CZ_USR_EV_CFG_OFST, 0, 1 },
459 { FR_AZ_RX_CFG_REG_OFST, 0, 1 },
460 { FR_AZ_TX_CFG_REG_OFST, 0, 1 },
461 { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
462 { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
463 { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
464 { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
465 { FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
466 { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
467 { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
468 { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
469 { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
472 static const uint32_t __siena_register_masks[] = {
473 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
474 0x000103FF, 0x00000000, 0x00000000, 0x00000000,
475 0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
476 0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
477 0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
478 0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
479 0x00000003, 0x00000000, 0x00000000, 0x00000000,
480 0x000003FF, 0x00000000, 0x00000000, 0x00000000,
481 0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
482 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
483 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
484 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
485 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
488 static efx_register_set_t __siena_tables[] = {
489 { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
490 FR_AZ_RX_FILTER_TBL0_ROWS },
491 { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
492 FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
493 { FR_AZ_RX_DESC_PTR_TBL_OFST,
494 FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
495 { FR_AZ_TX_DESC_PTR_TBL_OFST,
496 FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
497 { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
498 { FR_CZ_TX_FILTER_TBL0_OFST,
499 FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
500 { FR_CZ_TX_MAC_FILTER_TBL0_OFST,
501 FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
504 static const uint32_t __siena_table_masks[] = {
505 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
506 0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
507 0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
508 0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
509 0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
510 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
511 0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
514 __checkReturn efx_rc_t
515 siena_nic_register_test(
518 efx_register_set_t *rsp;
519 const uint32_t *dwordp;
524 /* Fill out the register mask entries */
525 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
526 == EFX_ARRAY_SIZE(__siena_registers) * 4);
528 nitems = EFX_ARRAY_SIZE(__siena_registers);
529 dwordp = __siena_register_masks;
530 for (count = 0; count < nitems; ++count) {
531 rsp = __siena_registers + count;
532 rsp->mask.eo_u32[0] = *dwordp++;
533 rsp->mask.eo_u32[1] = *dwordp++;
534 rsp->mask.eo_u32[2] = *dwordp++;
535 rsp->mask.eo_u32[3] = *dwordp++;
538 /* Fill out the register table entries */
539 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
540 == EFX_ARRAY_SIZE(__siena_tables) * 4);
542 nitems = EFX_ARRAY_SIZE(__siena_tables);
543 dwordp = __siena_table_masks;
544 for (count = 0; count < nitems; ++count) {
545 rsp = __siena_tables + count;
546 rsp->mask.eo_u32[0] = *dwordp++;
547 rsp->mask.eo_u32[1] = *dwordp++;
548 rsp->mask.eo_u32[2] = *dwordp++;
549 rsp->mask.eo_u32[3] = *dwordp++;
552 if ((rc = efx_nic_test_registers(enp, __siena_registers,
553 EFX_ARRAY_SIZE(__siena_registers))) != 0)
556 if ((rc = efx_nic_test_tables(enp, __siena_tables,
557 EFX_PATTERN_BYTE_ALTERNATE,
558 EFX_ARRAY_SIZE(__siena_tables))) != 0)
561 if ((rc = efx_nic_test_tables(enp, __siena_tables,
562 EFX_PATTERN_BYTE_CHANGING,
563 EFX_ARRAY_SIZE(__siena_tables))) != 0)
566 if ((rc = efx_nic_test_tables(enp, __siena_tables,
567 EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
579 EFSYS_PROBE1(fail1, efx_rc_t, rc);
584 #endif /* EFSYS_OPT_DIAG */
586 #endif /* EFSYS_OPT_SIENA */