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 uint8_t payload[MAX(MC_CMD_NVRAM_TYPES_IN_LEN,
46 MC_CMD_NVRAM_TYPES_OUT_LEN)];
49 (void) memset(payload, 0, sizeof (payload));
50 req.emr_cmd = MC_CMD_NVRAM_TYPES;
51 req.emr_in_buf = payload;
52 req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN;
53 req.emr_out_buf = payload;
54 req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN;
56 efx_mcdi_execute(enp, &req);
58 if (req.emr_rc != 0) {
63 if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) {
68 *maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES);
75 EFSYS_PROBE1(fail1, efx_rc_t, rc);
80 #endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
82 static __checkReturn efx_rc_t
86 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
88 efx_dword_t capabilities;
90 uint32_t nevq, nrxq, ntxq;
93 /* External port identifier using one-based port numbering */
94 encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port;
96 /* Board configuration */
97 if ((rc = efx_mcdi_get_board_cfg(enp, &board_type,
98 &capabilities, mac_addr)) != 0)
101 EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
103 encp->enc_board_type = board_type;
106 * There is no possibility to determine the number of PFs on Siena
107 * by issuing MCDI request, and it is not an easy task to find the
108 * value based on the board type, so 'enc_hw_pf_count' is set to 1
110 encp->enc_hw_pf_count = 1;
112 /* Additional capabilities */
113 encp->enc_clk_mult = 1;
114 if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) {
115 enp->en_features |= EFX_FEATURE_TURBO;
117 if (EFX_DWORD_FIELD(capabilities,
118 MC_CMD_CAPABILITIES_TURBO_ACTIVE)) {
119 encp->enc_clk_mult = 2;
123 encp->enc_evq_timer_quantum_ns =
124 EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult;
125 encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
126 FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
128 /* When hash header insertion is enabled, Siena inserts 16 bytes */
129 encp->enc_rx_prefix_size = 16;
131 /* Alignment for receive packet DMA buffers */
132 encp->enc_rx_buf_align_start = 1;
133 encp->enc_rx_buf_align_end = 1;
135 /* Alignment for WPTR updates */
136 encp->enc_rx_push_align = 1;
138 /* There is one RSS context per function */
139 encp->enc_rx_scale_max_exclusive_contexts = 1;
141 encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT);
142 /* Fragments must not span 4k boundaries. */
143 encp->enc_tx_dma_desc_boundary = 4096;
145 /* Resource limits */
146 rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
152 nrxq = EFX_RXQ_LIMIT_TARGET;
153 ntxq = EFX_TXQ_LIMIT_TARGET;
155 encp->enc_evq_limit = nevq;
156 encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
157 encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
159 encp->enc_txq_max_ndescs = 4096;
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;
170 encp->enc_rx_packed_stream_supported = B_FALSE;
171 encp->enc_rx_var_packed_stream_supported = B_FALSE;
173 /* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */
174 encp->enc_required_pcie_bandwidth_mbps = 2 * 10000;
175 encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2;
177 encp->enc_nvram_update_verify_result_supported = B_FALSE;
184 EFSYS_PROBE1(fail1, efx_rc_t, rc);
189 static __checkReturn efx_rc_t
193 #if EFSYS_OPT_PHY_STATS
194 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
195 #endif /* EFSYS_OPT_PHY_STATS */
198 /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
199 if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
202 #if EFSYS_OPT_PHY_STATS
203 /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
204 siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
205 NULL, &encp->enc_phy_stat_mask, NULL);
206 #endif /* EFSYS_OPT_PHY_STATS */
211 EFSYS_PROBE1(fail1, efx_rc_t, rc);
216 __checkReturn efx_rc_t
220 efx_port_t *epp = &(enp->en_port);
221 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
222 siena_link_state_t sls;
227 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
230 if ((rc = efx_nic_biu_test(enp)) != 0)
233 /* Clear the region register */
234 EFX_POPULATE_OWORD_4(oword,
235 FRF_AZ_ADR_REGION0, 0,
236 FRF_AZ_ADR_REGION1, (1 << 16),
237 FRF_AZ_ADR_REGION2, (2 << 16),
238 FRF_AZ_ADR_REGION3, (3 << 16));
239 EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
241 /* Read clear any assertion state */
242 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
245 /* Exit the assertion handler */
246 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
249 /* Wrestle control from the BMC */
250 if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
253 if ((rc = siena_board_cfg(enp)) != 0)
256 if ((rc = siena_phy_cfg(enp)) != 0)
259 /* Obtain the default PHY advertised capabilities */
260 if ((rc = siena_nic_reset(enp)) != 0)
262 if ((rc = siena_phy_get_link(enp, &sls)) != 0)
264 epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
265 epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
267 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
268 if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
270 enp->en_u.siena.enu_partn_mask = mask;
273 #if EFSYS_OPT_MAC_STATS
274 /* Wipe the MAC statistics */
275 if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
279 #if EFSYS_OPT_LOOPBACK
280 if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
284 #if EFSYS_OPT_MON_STATS
285 if ((rc = mcdi_mon_cfg_build(enp)) != 0)
289 encp->enc_features = enp->en_features;
293 #if EFSYS_OPT_MON_STATS
297 #if EFSYS_OPT_LOOPBACK
301 #if EFSYS_OPT_MAC_STATS
305 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
324 EFSYS_PROBE1(fail1, efx_rc_t, rc);
329 __checkReturn efx_rc_t
336 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
338 /* siena_nic_reset() is called to recover from BADASSERT failures. */
339 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
341 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
345 * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
346 * for backwards compatibility with PORT_RESET_IN_LEN.
348 EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
350 req.emr_cmd = MC_CMD_ENTITY_RESET;
351 req.emr_in_buf = NULL;
352 req.emr_in_length = 0;
353 req.emr_out_buf = NULL;
354 req.emr_out_length = 0;
356 efx_mcdi_execute(enp, &req);
358 if (req.emr_rc != 0) {
370 EFSYS_PROBE1(fail1, efx_rc_t, rc);
382 * RX_INGR_EN is always enabled on Siena, because we rely on
383 * the RX parser to be resiliant to missing SOP/EOP.
385 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
386 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
387 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
389 /* Disable parsing of additional 802.1Q in Q packets */
390 EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
391 EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
392 EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
401 EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
402 EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
405 __checkReturn efx_rc_t
411 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
413 /* Enable reporting of some events (e.g. link change) */
414 if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
417 siena_sram_init(enp);
419 /* Configure Siena's RX block */
420 siena_nic_rx_cfg(enp);
422 /* Disable USR_EVents for now */
423 siena_nic_usrev_dis(enp);
425 /* bug17057: Ensure set_link is called */
426 if ((rc = siena_phy_reconfigure(enp)) != 0)
429 enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;
436 EFSYS_PROBE1(fail1, efx_rc_t, rc);
445 _NOTE(ARGUNUSED(enp))
452 #if EFSYS_OPT_MON_STATS
453 mcdi_mon_cfg_free(enp);
454 #endif /* EFSYS_OPT_MON_STATS */
455 (void) efx_mcdi_drv_attach(enp, B_FALSE);
460 static efx_register_set_t __siena_registers[] = {
461 { FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
462 { FR_CZ_USR_EV_CFG_OFST, 0, 1 },
463 { FR_AZ_RX_CFG_REG_OFST, 0, 1 },
464 { FR_AZ_TX_CFG_REG_OFST, 0, 1 },
465 { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
466 { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
467 { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
468 { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
469 { FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
470 { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
471 { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
472 { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
473 { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
476 static const uint32_t __siena_register_masks[] = {
477 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
478 0x000103FF, 0x00000000, 0x00000000, 0x00000000,
479 0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
480 0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
481 0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
482 0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
483 0x00000003, 0x00000000, 0x00000000, 0x00000000,
484 0x000003FF, 0x00000000, 0x00000000, 0x00000000,
485 0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
486 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
487 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
488 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
489 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
492 static efx_register_set_t __siena_tables[] = {
493 { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
494 FR_AZ_RX_FILTER_TBL0_ROWS },
495 { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
496 FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
497 { FR_AZ_RX_DESC_PTR_TBL_OFST,
498 FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
499 { FR_AZ_TX_DESC_PTR_TBL_OFST,
500 FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
501 { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
502 { FR_CZ_TX_FILTER_TBL0_OFST,
503 FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
504 { FR_CZ_TX_MAC_FILTER_TBL0_OFST,
505 FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
508 static const uint32_t __siena_table_masks[] = {
509 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
510 0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
511 0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
512 0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
513 0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
514 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
515 0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
518 __checkReturn efx_rc_t
519 siena_nic_register_test(
522 efx_register_set_t *rsp;
523 const uint32_t *dwordp;
528 /* Fill out the register mask entries */
529 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
530 == EFX_ARRAY_SIZE(__siena_registers) * 4);
532 nitems = EFX_ARRAY_SIZE(__siena_registers);
533 dwordp = __siena_register_masks;
534 for (count = 0; count < nitems; ++count) {
535 rsp = __siena_registers + count;
536 rsp->mask.eo_u32[0] = *dwordp++;
537 rsp->mask.eo_u32[1] = *dwordp++;
538 rsp->mask.eo_u32[2] = *dwordp++;
539 rsp->mask.eo_u32[3] = *dwordp++;
542 /* Fill out the register table entries */
543 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
544 == EFX_ARRAY_SIZE(__siena_tables) * 4);
546 nitems = EFX_ARRAY_SIZE(__siena_tables);
547 dwordp = __siena_table_masks;
548 for (count = 0; count < nitems; ++count) {
549 rsp = __siena_tables + count;
550 rsp->mask.eo_u32[0] = *dwordp++;
551 rsp->mask.eo_u32[1] = *dwordp++;
552 rsp->mask.eo_u32[2] = *dwordp++;
553 rsp->mask.eo_u32[3] = *dwordp++;
556 if ((rc = efx_nic_test_registers(enp, __siena_registers,
557 EFX_ARRAY_SIZE(__siena_registers))) != 0)
560 if ((rc = efx_nic_test_tables(enp, __siena_tables,
561 EFX_PATTERN_BYTE_ALTERNATE,
562 EFX_ARRAY_SIZE(__siena_tables))) != 0)
565 if ((rc = efx_nic_test_tables(enp, __siena_tables,
566 EFX_PATTERN_BYTE_CHANGING,
567 EFX_ARRAY_SIZE(__siena_tables))) != 0)
570 if ((rc = efx_nic_test_tables(enp, __siena_tables,
571 EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
583 EFSYS_PROBE1(fail1, efx_rc_t, rc);
588 #endif /* EFSYS_OPT_DIAG */
590 #endif /* EFSYS_OPT_SIENA */