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 static __checkReturn efx_rc_t
41 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
43 efx_dword_t capabilities;
45 uint32_t nevq, nrxq, ntxq;
48 /* External port identifier using one-based port numbering */
49 encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port;
51 /* Board configuration */
52 if ((rc = efx_mcdi_get_board_cfg(enp, &board_type,
53 &capabilities, mac_addr)) != 0)
56 EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
58 encp->enc_board_type = board_type;
61 * There is no possibility to determine the number of PFs on Siena
62 * by issuing MCDI request, and it is not an easy task to find the
63 * value based on the board type, so 'enc_hw_pf_count' is set to 1
65 encp->enc_hw_pf_count = 1;
67 /* Additional capabilities */
68 encp->enc_clk_mult = 1;
69 if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) {
70 enp->en_features |= EFX_FEATURE_TURBO;
72 if (EFX_DWORD_FIELD(capabilities,
73 MC_CMD_CAPABILITIES_TURBO_ACTIVE)) {
74 encp->enc_clk_mult = 2;
78 encp->enc_evq_timer_quantum_ns =
79 EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult;
80 encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
81 FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
83 /* When hash header insertion is enabled, Siena inserts 16 bytes */
84 encp->enc_rx_prefix_size = 16;
86 /* Alignment for receive packet DMA buffers */
87 encp->enc_rx_buf_align_start = 1;
88 encp->enc_rx_buf_align_end = 1;
90 /* Alignment for WPTR updates */
91 encp->enc_rx_push_align = 1;
94 rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
100 nrxq = EFX_RXQ_LIMIT_TARGET;
101 ntxq = EFX_TXQ_LIMIT_TARGET;
103 encp->enc_evq_limit = nevq;
104 encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
105 encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
107 encp->enc_txq_max_ndescs = 4096;
109 encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
110 (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
111 (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
113 encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
114 encp->enc_fw_assisted_tso_enabled = B_FALSE;
115 encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
116 encp->enc_fw_assisted_tso_v2_n_contexts = 0;
117 encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
118 encp->enc_rx_packed_stream_supported = B_FALSE;
119 encp->enc_rx_var_packed_stream_supported = B_FALSE;
121 /* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */
122 encp->enc_required_pcie_bandwidth_mbps = 2 * 10000;
123 encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2;
125 encp->enc_fw_verified_nvram_update_required = B_FALSE;
132 EFSYS_PROBE1(fail1, efx_rc_t, rc);
137 static __checkReturn efx_rc_t
141 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
144 /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
145 if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
148 #if EFSYS_OPT_PHY_STATS
149 /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
150 siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
151 NULL, &encp->enc_phy_stat_mask, NULL);
152 #endif /* EFSYS_OPT_PHY_STATS */
157 EFSYS_PROBE1(fail1, efx_rc_t, rc);
162 __checkReturn efx_rc_t
166 efx_port_t *epp = &(enp->en_port);
167 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
168 siena_link_state_t sls;
173 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
176 if ((rc = efx_nic_biu_test(enp)) != 0)
179 /* Clear the region register */
180 EFX_POPULATE_OWORD_4(oword,
181 FRF_AZ_ADR_REGION0, 0,
182 FRF_AZ_ADR_REGION1, (1 << 16),
183 FRF_AZ_ADR_REGION2, (2 << 16),
184 FRF_AZ_ADR_REGION3, (3 << 16));
185 EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
187 /* Read clear any assertion state */
188 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
191 /* Exit the assertion handler */
192 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
195 /* Wrestle control from the BMC */
196 if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
199 if ((rc = siena_board_cfg(enp)) != 0)
202 if ((rc = siena_phy_cfg(enp)) != 0)
205 /* Obtain the default PHY advertised capabilities */
206 if ((rc = siena_nic_reset(enp)) != 0)
208 if ((rc = siena_phy_get_link(enp, &sls)) != 0)
210 epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
211 epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
213 #if EFSYS_OPT_MAC_STATS
214 /* Wipe the MAC statistics */
215 if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
219 #if EFSYS_OPT_LOOPBACK
220 if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
224 #if EFSYS_OPT_MON_STATS
225 if ((rc = mcdi_mon_cfg_build(enp)) != 0)
229 encp->enc_features = enp->en_features;
233 #if EFSYS_OPT_MON_STATS
237 #if EFSYS_OPT_LOOPBACK
241 #if EFSYS_OPT_MAC_STATS
260 EFSYS_PROBE1(fail1, efx_rc_t, rc);
265 __checkReturn efx_rc_t
272 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
274 /* siena_nic_reset() is called to recover from BADASSERT failures. */
275 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
277 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
281 * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
282 * for backwards compatibility with PORT_RESET_IN_LEN.
284 EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
286 req.emr_cmd = MC_CMD_ENTITY_RESET;
287 req.emr_in_buf = NULL;
288 req.emr_in_length = 0;
289 req.emr_out_buf = NULL;
290 req.emr_out_length = 0;
292 efx_mcdi_execute(enp, &req);
294 if (req.emr_rc != 0) {
306 EFSYS_PROBE1(fail1, efx_rc_t, rc);
318 * RX_INGR_EN is always enabled on Siena, because we rely on
319 * the RX parser to be resiliant to missing SOP/EOP.
321 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
322 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
323 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
325 /* Disable parsing of additional 802.1Q in Q packets */
326 EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
327 EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
328 EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
337 EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
338 EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
341 __checkReturn efx_rc_t
347 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
349 /* Enable reporting of some events (e.g. link change) */
350 if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
353 siena_sram_init(enp);
355 /* Configure Siena's RX block */
356 siena_nic_rx_cfg(enp);
358 /* Disable USR_EVents for now */
359 siena_nic_usrev_dis(enp);
361 /* bug17057: Ensure set_link is called */
362 if ((rc = siena_phy_reconfigure(enp)) != 0)
365 enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;
372 EFSYS_PROBE1(fail1, efx_rc_t, rc);
381 _NOTE(ARGUNUSED(enp))
388 #if EFSYS_OPT_MON_STATS
389 mcdi_mon_cfg_free(enp);
390 #endif /* EFSYS_OPT_MON_STATS */
391 (void) efx_mcdi_drv_attach(enp, B_FALSE);
396 static efx_register_set_t __siena_registers[] = {
397 { FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
398 { FR_CZ_USR_EV_CFG_OFST, 0, 1 },
399 { FR_AZ_RX_CFG_REG_OFST, 0, 1 },
400 { FR_AZ_TX_CFG_REG_OFST, 0, 1 },
401 { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
402 { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
403 { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
404 { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
405 { FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
406 { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
407 { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
408 { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
409 { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
412 static const uint32_t __siena_register_masks[] = {
413 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
414 0x000103FF, 0x00000000, 0x00000000, 0x00000000,
415 0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
416 0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
417 0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
418 0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
419 0x00000003, 0x00000000, 0x00000000, 0x00000000,
420 0x000003FF, 0x00000000, 0x00000000, 0x00000000,
421 0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
422 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
423 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
424 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
425 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
428 static efx_register_set_t __siena_tables[] = {
429 { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
430 FR_AZ_RX_FILTER_TBL0_ROWS },
431 { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
432 FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
433 { FR_AZ_RX_DESC_PTR_TBL_OFST,
434 FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
435 { FR_AZ_TX_DESC_PTR_TBL_OFST,
436 FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
437 { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
438 { FR_CZ_TX_FILTER_TBL0_OFST,
439 FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
440 { FR_CZ_TX_MAC_FILTER_TBL0_OFST,
441 FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
444 static const uint32_t __siena_table_masks[] = {
445 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
446 0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
447 0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
448 0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
449 0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
450 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
451 0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
454 __checkReturn efx_rc_t
455 siena_nic_register_test(
458 efx_register_set_t *rsp;
459 const uint32_t *dwordp;
464 /* Fill out the register mask entries */
465 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
466 == EFX_ARRAY_SIZE(__siena_registers) * 4);
468 nitems = EFX_ARRAY_SIZE(__siena_registers);
469 dwordp = __siena_register_masks;
470 for (count = 0; count < nitems; ++count) {
471 rsp = __siena_registers + count;
472 rsp->mask.eo_u32[0] = *dwordp++;
473 rsp->mask.eo_u32[1] = *dwordp++;
474 rsp->mask.eo_u32[2] = *dwordp++;
475 rsp->mask.eo_u32[3] = *dwordp++;
478 /* Fill out the register table entries */
479 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
480 == EFX_ARRAY_SIZE(__siena_tables) * 4);
482 nitems = EFX_ARRAY_SIZE(__siena_tables);
483 dwordp = __siena_table_masks;
484 for (count = 0; count < nitems; ++count) {
485 rsp = __siena_tables + count;
486 rsp->mask.eo_u32[0] = *dwordp++;
487 rsp->mask.eo_u32[1] = *dwordp++;
488 rsp->mask.eo_u32[2] = *dwordp++;
489 rsp->mask.eo_u32[3] = *dwordp++;
492 if ((rc = efx_nic_test_registers(enp, __siena_registers,
493 EFX_ARRAY_SIZE(__siena_registers))) != 0)
496 if ((rc = efx_nic_test_tables(enp, __siena_tables,
497 EFX_PATTERN_BYTE_ALTERNATE,
498 EFX_ARRAY_SIZE(__siena_tables))) != 0)
501 if ((rc = efx_nic_test_tables(enp, __siena_tables,
502 EFX_PATTERN_BYTE_CHANGING,
503 EFX_ARRAY_SIZE(__siena_tables))) != 0)
506 if ((rc = efx_nic_test_tables(enp, __siena_tables,
507 EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
519 EFSYS_PROBE1(fail1, efx_rc_t, rc);
524 #endif /* EFSYS_OPT_DIAG */
526 #endif /* EFSYS_OPT_SIENA */