2 * Copyright (c) 2009-2016 Solarflare Communications Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * The views and conclusions contained in the software and documentation are
27 * those of the authors and should not be interpreted as representing official
28 * policies, either expressed or implied, of the FreeBSD Project.
37 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
39 static __checkReturn efx_rc_t
40 siena_nic_get_partn_mask(
42 __out unsigned int *maskp)
45 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_TYPES_IN_LEN,
46 MC_CMD_NVRAM_TYPES_OUT_LEN);
49 req.emr_cmd = MC_CMD_NVRAM_TYPES;
50 req.emr_in_buf = payload;
51 req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN;
52 req.emr_out_buf = payload;
53 req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN;
55 efx_mcdi_execute(enp, &req);
57 if (req.emr_rc != 0) {
62 if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) {
67 *maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES);
74 EFSYS_PROBE1(fail1, efx_rc_t, rc);
79 #endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
81 static __checkReturn efx_rc_t
85 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
87 efx_dword_t capabilities;
89 uint32_t nevq, nrxq, ntxq;
92 /* External port identifier using one-based port numbering */
93 encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port;
95 /* Board configuration */
96 if ((rc = efx_mcdi_get_board_cfg(enp, &board_type,
97 &capabilities, mac_addr)) != 0)
100 EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
102 encp->enc_board_type = board_type;
105 * There is no possibility to determine the number of PFs on Siena
106 * by issuing MCDI request, and it is not an easy task to find the
107 * value based on the board type, so 'enc_hw_pf_count' is set to 1
109 encp->enc_hw_pf_count = 1;
111 /* Additional capabilities */
112 encp->enc_clk_mult = 1;
113 if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) {
114 enp->en_features |= EFX_FEATURE_TURBO;
116 if (EFX_DWORD_FIELD(capabilities,
117 MC_CMD_CAPABILITIES_TURBO_ACTIVE)) {
118 encp->enc_clk_mult = 2;
122 encp->enc_evq_timer_quantum_ns =
123 EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult;
124 encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
125 FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
127 /* When hash header insertion is enabled, Siena inserts 16 bytes */
128 encp->enc_rx_prefix_size = 16;
130 /* Alignment for receive packet DMA buffers */
131 encp->enc_rx_buf_align_start = 1;
132 encp->enc_rx_buf_align_end = 1;
134 /* Alignment for WPTR updates */
135 encp->enc_rx_push_align = 1;
137 /* There is one RSS context per function */
138 encp->enc_rx_scale_max_exclusive_contexts = 1;
140 encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT);
141 /* Fragments must not span 4k boundaries. */
142 encp->enc_tx_dma_desc_boundary = 4096;
144 /* Resource limits */
145 rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
151 nrxq = EFX_RXQ_LIMIT_TARGET;
152 ntxq = EFX_TXQ_LIMIT_TARGET;
154 encp->enc_evq_limit = nevq;
155 encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
156 encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
158 encp->enc_txq_max_ndescs = 4096;
160 encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
161 (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
162 (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
164 encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
165 encp->enc_fw_assisted_tso_enabled = B_FALSE;
166 encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
167 encp->enc_fw_assisted_tso_v2_n_contexts = 0;
168 encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
169 encp->enc_rx_packed_stream_supported = B_FALSE;
170 encp->enc_rx_var_packed_stream_supported = B_FALSE;
172 /* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */
173 encp->enc_required_pcie_bandwidth_mbps = 2 * 10000;
174 encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2;
176 encp->enc_fw_verified_nvram_update_required = B_FALSE;
183 EFSYS_PROBE1(fail1, efx_rc_t, rc);
188 static __checkReturn efx_rc_t
192 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
195 /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
196 if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
199 #if EFSYS_OPT_PHY_STATS
200 /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
201 siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
202 NULL, &encp->enc_phy_stat_mask, NULL);
203 #endif /* EFSYS_OPT_PHY_STATS */
208 EFSYS_PROBE1(fail1, efx_rc_t, rc);
213 __checkReturn efx_rc_t
217 efx_port_t *epp = &(enp->en_port);
218 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
219 siena_link_state_t sls;
224 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
227 if ((rc = efx_nic_biu_test(enp)) != 0)
230 /* Clear the region register */
231 EFX_POPULATE_OWORD_4(oword,
232 FRF_AZ_ADR_REGION0, 0,
233 FRF_AZ_ADR_REGION1, (1 << 16),
234 FRF_AZ_ADR_REGION2, (2 << 16),
235 FRF_AZ_ADR_REGION3, (3 << 16));
236 EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
238 /* Read clear any assertion state */
239 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
242 /* Exit the assertion handler */
243 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
246 /* Wrestle control from the BMC */
247 if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
250 if ((rc = siena_board_cfg(enp)) != 0)
253 if ((rc = siena_phy_cfg(enp)) != 0)
256 /* Obtain the default PHY advertised capabilities */
257 if ((rc = siena_nic_reset(enp)) != 0)
259 if ((rc = siena_phy_get_link(enp, &sls)) != 0)
261 epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
262 epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
264 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
265 if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
267 enp->en_u.siena.enu_partn_mask = mask;
270 #if EFSYS_OPT_MAC_STATS
271 /* Wipe the MAC statistics */
272 if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
276 #if EFSYS_OPT_LOOPBACK
277 if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
281 #if EFSYS_OPT_MON_STATS
282 if ((rc = mcdi_mon_cfg_build(enp)) != 0)
286 encp->enc_features = enp->en_features;
290 #if EFSYS_OPT_MON_STATS
294 #if EFSYS_OPT_LOOPBACK
298 #if EFSYS_OPT_MAC_STATS
302 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
321 EFSYS_PROBE1(fail1, efx_rc_t, rc);
326 __checkReturn efx_rc_t
333 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
335 /* siena_nic_reset() is called to recover from BADASSERT failures. */
336 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
338 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
342 * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
343 * for backwards compatibility with PORT_RESET_IN_LEN.
345 EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
347 req.emr_cmd = MC_CMD_ENTITY_RESET;
348 req.emr_in_buf = NULL;
349 req.emr_in_length = 0;
350 req.emr_out_buf = NULL;
351 req.emr_out_length = 0;
353 efx_mcdi_execute(enp, &req);
355 if (req.emr_rc != 0) {
367 EFSYS_PROBE1(fail1, efx_rc_t, rc);
379 * RX_INGR_EN is always enabled on Siena, because we rely on
380 * the RX parser to be resiliant to missing SOP/EOP.
382 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
383 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
384 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
386 /* Disable parsing of additional 802.1Q in Q packets */
387 EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
388 EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
389 EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
398 EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
399 EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
402 __checkReturn efx_rc_t
408 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
410 /* Enable reporting of some events (e.g. link change) */
411 if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
414 siena_sram_init(enp);
416 /* Configure Siena's RX block */
417 siena_nic_rx_cfg(enp);
419 /* Disable USR_EVents for now */
420 siena_nic_usrev_dis(enp);
422 /* bug17057: Ensure set_link is called */
423 if ((rc = siena_phy_reconfigure(enp)) != 0)
426 enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;
433 EFSYS_PROBE1(fail1, efx_rc_t, rc);
442 _NOTE(ARGUNUSED(enp))
449 #if EFSYS_OPT_MON_STATS
450 mcdi_mon_cfg_free(enp);
451 #endif /* EFSYS_OPT_MON_STATS */
452 (void) efx_mcdi_drv_attach(enp, B_FALSE);
457 static efx_register_set_t __siena_registers[] = {
458 { FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
459 { FR_CZ_USR_EV_CFG_OFST, 0, 1 },
460 { FR_AZ_RX_CFG_REG_OFST, 0, 1 },
461 { FR_AZ_TX_CFG_REG_OFST, 0, 1 },
462 { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
463 { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
464 { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
465 { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
466 { FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
467 { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
468 { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
469 { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
470 { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
473 static const uint32_t __siena_register_masks[] = {
474 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
475 0x000103FF, 0x00000000, 0x00000000, 0x00000000,
476 0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
477 0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
478 0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
479 0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
480 0x00000003, 0x00000000, 0x00000000, 0x00000000,
481 0x000003FF, 0x00000000, 0x00000000, 0x00000000,
482 0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
483 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
484 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
485 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
486 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
489 static efx_register_set_t __siena_tables[] = {
490 { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
491 FR_AZ_RX_FILTER_TBL0_ROWS },
492 { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
493 FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
494 { FR_AZ_RX_DESC_PTR_TBL_OFST,
495 FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
496 { FR_AZ_TX_DESC_PTR_TBL_OFST,
497 FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
498 { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
499 { FR_CZ_TX_FILTER_TBL0_OFST,
500 FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
501 { FR_CZ_TX_MAC_FILTER_TBL0_OFST,
502 FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
505 static const uint32_t __siena_table_masks[] = {
506 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
507 0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
508 0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
509 0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
510 0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
511 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
512 0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
515 __checkReturn efx_rc_t
516 siena_nic_register_test(
519 efx_register_set_t *rsp;
520 const uint32_t *dwordp;
525 /* Fill out the register mask entries */
526 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
527 == EFX_ARRAY_SIZE(__siena_registers) * 4);
529 nitems = EFX_ARRAY_SIZE(__siena_registers);
530 dwordp = __siena_register_masks;
531 for (count = 0; count < nitems; ++count) {
532 rsp = __siena_registers + count;
533 rsp->mask.eo_u32[0] = *dwordp++;
534 rsp->mask.eo_u32[1] = *dwordp++;
535 rsp->mask.eo_u32[2] = *dwordp++;
536 rsp->mask.eo_u32[3] = *dwordp++;
539 /* Fill out the register table entries */
540 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
541 == EFX_ARRAY_SIZE(__siena_tables) * 4);
543 nitems = EFX_ARRAY_SIZE(__siena_tables);
544 dwordp = __siena_table_masks;
545 for (count = 0; count < nitems; ++count) {
546 rsp = __siena_tables + count;
547 rsp->mask.eo_u32[0] = *dwordp++;
548 rsp->mask.eo_u32[1] = *dwordp++;
549 rsp->mask.eo_u32[2] = *dwordp++;
550 rsp->mask.eo_u32[3] = *dwordp++;
553 if ((rc = efx_nic_test_registers(enp, __siena_registers,
554 EFX_ARRAY_SIZE(__siena_registers))) != 0)
557 if ((rc = efx_nic_test_tables(enp, __siena_tables,
558 EFX_PATTERN_BYTE_ALTERNATE,
559 EFX_ARRAY_SIZE(__siena_tables))) != 0)
562 if ((rc = efx_nic_test_tables(enp, __siena_tables,
563 EFX_PATTERN_BYTE_CHANGING,
564 EFX_ARRAY_SIZE(__siena_tables))) != 0)
567 if ((rc = efx_nic_test_tables(enp, __siena_tables,
568 EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
580 EFSYS_PROBE1(fail1, efx_rc_t, rc);
585 #endif /* EFSYS_OPT_DIAG */
587 #endif /* EFSYS_OPT_SIENA */