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 /* Resource limits */
139 rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
145 nrxq = EFX_RXQ_LIMIT_TARGET;
146 ntxq = EFX_TXQ_LIMIT_TARGET;
148 encp->enc_evq_limit = nevq;
149 encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
150 encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
152 encp->enc_txq_max_ndescs = 4096;
154 encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
155 (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
156 (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
158 encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
159 encp->enc_fw_assisted_tso_enabled = B_FALSE;
160 encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
161 encp->enc_fw_assisted_tso_v2_n_contexts = 0;
162 encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
163 encp->enc_rx_packed_stream_supported = B_FALSE;
164 encp->enc_rx_var_packed_stream_supported = B_FALSE;
166 /* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */
167 encp->enc_required_pcie_bandwidth_mbps = 2 * 10000;
168 encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2;
170 encp->enc_fw_verified_nvram_update_required = B_FALSE;
177 EFSYS_PROBE1(fail1, efx_rc_t, rc);
182 static __checkReturn efx_rc_t
186 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
189 /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
190 if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
193 #if EFSYS_OPT_PHY_STATS
194 /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
195 siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
196 NULL, &encp->enc_phy_stat_mask, NULL);
197 #endif /* EFSYS_OPT_PHY_STATS */
202 EFSYS_PROBE1(fail1, efx_rc_t, rc);
207 __checkReturn efx_rc_t
211 efx_port_t *epp = &(enp->en_port);
212 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
213 siena_link_state_t sls;
218 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
221 if ((rc = efx_nic_biu_test(enp)) != 0)
224 /* Clear the region register */
225 EFX_POPULATE_OWORD_4(oword,
226 FRF_AZ_ADR_REGION0, 0,
227 FRF_AZ_ADR_REGION1, (1 << 16),
228 FRF_AZ_ADR_REGION2, (2 << 16),
229 FRF_AZ_ADR_REGION3, (3 << 16));
230 EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
232 /* Read clear any assertion state */
233 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
236 /* Exit the assertion handler */
237 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
240 /* Wrestle control from the BMC */
241 if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
244 if ((rc = siena_board_cfg(enp)) != 0)
247 if ((rc = siena_phy_cfg(enp)) != 0)
250 /* Obtain the default PHY advertised capabilities */
251 if ((rc = siena_nic_reset(enp)) != 0)
253 if ((rc = siena_phy_get_link(enp, &sls)) != 0)
255 epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
256 epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
258 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
259 if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
261 enp->en_u.siena.enu_partn_mask = mask;
264 #if EFSYS_OPT_MAC_STATS
265 /* Wipe the MAC statistics */
266 if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
270 #if EFSYS_OPT_LOOPBACK
271 if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
275 #if EFSYS_OPT_MON_STATS
276 if ((rc = mcdi_mon_cfg_build(enp)) != 0)
280 encp->enc_features = enp->en_features;
284 #if EFSYS_OPT_MON_STATS
288 #if EFSYS_OPT_LOOPBACK
292 #if EFSYS_OPT_MAC_STATS
296 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
315 EFSYS_PROBE1(fail1, efx_rc_t, rc);
320 __checkReturn efx_rc_t
327 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
329 /* siena_nic_reset() is called to recover from BADASSERT failures. */
330 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
332 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
336 * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
337 * for backwards compatibility with PORT_RESET_IN_LEN.
339 EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
341 req.emr_cmd = MC_CMD_ENTITY_RESET;
342 req.emr_in_buf = NULL;
343 req.emr_in_length = 0;
344 req.emr_out_buf = NULL;
345 req.emr_out_length = 0;
347 efx_mcdi_execute(enp, &req);
349 if (req.emr_rc != 0) {
361 EFSYS_PROBE1(fail1, efx_rc_t, rc);
373 * RX_INGR_EN is always enabled on Siena, because we rely on
374 * the RX parser to be resiliant to missing SOP/EOP.
376 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
377 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
378 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
380 /* Disable parsing of additional 802.1Q in Q packets */
381 EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
382 EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
383 EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
392 EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
393 EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
396 __checkReturn efx_rc_t
402 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
404 /* Enable reporting of some events (e.g. link change) */
405 if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
408 siena_sram_init(enp);
410 /* Configure Siena's RX block */
411 siena_nic_rx_cfg(enp);
413 /* Disable USR_EVents for now */
414 siena_nic_usrev_dis(enp);
416 /* bug17057: Ensure set_link is called */
417 if ((rc = siena_phy_reconfigure(enp)) != 0)
420 enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;
427 EFSYS_PROBE1(fail1, efx_rc_t, rc);
436 _NOTE(ARGUNUSED(enp))
443 #if EFSYS_OPT_MON_STATS
444 mcdi_mon_cfg_free(enp);
445 #endif /* EFSYS_OPT_MON_STATS */
446 (void) efx_mcdi_drv_attach(enp, B_FALSE);
451 static efx_register_set_t __siena_registers[] = {
452 { FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
453 { FR_CZ_USR_EV_CFG_OFST, 0, 1 },
454 { FR_AZ_RX_CFG_REG_OFST, 0, 1 },
455 { FR_AZ_TX_CFG_REG_OFST, 0, 1 },
456 { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
457 { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
458 { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
459 { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
460 { FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
461 { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
462 { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
463 { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
464 { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
467 static const uint32_t __siena_register_masks[] = {
468 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
469 0x000103FF, 0x00000000, 0x00000000, 0x00000000,
470 0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
471 0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
472 0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
473 0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
474 0x00000003, 0x00000000, 0x00000000, 0x00000000,
475 0x000003FF, 0x00000000, 0x00000000, 0x00000000,
476 0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
477 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
478 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
479 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
480 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
483 static efx_register_set_t __siena_tables[] = {
484 { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
485 FR_AZ_RX_FILTER_TBL0_ROWS },
486 { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
487 FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
488 { FR_AZ_RX_DESC_PTR_TBL_OFST,
489 FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
490 { FR_AZ_TX_DESC_PTR_TBL_OFST,
491 FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
492 { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
493 { FR_CZ_TX_FILTER_TBL0_OFST,
494 FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
495 { FR_CZ_TX_MAC_FILTER_TBL0_OFST,
496 FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
499 static const uint32_t __siena_table_masks[] = {
500 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
501 0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
502 0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
503 0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
504 0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
505 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
506 0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
509 __checkReturn efx_rc_t
510 siena_nic_register_test(
513 efx_register_set_t *rsp;
514 const uint32_t *dwordp;
519 /* Fill out the register mask entries */
520 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
521 == EFX_ARRAY_SIZE(__siena_registers) * 4);
523 nitems = EFX_ARRAY_SIZE(__siena_registers);
524 dwordp = __siena_register_masks;
525 for (count = 0; count < nitems; ++count) {
526 rsp = __siena_registers + count;
527 rsp->mask.eo_u32[0] = *dwordp++;
528 rsp->mask.eo_u32[1] = *dwordp++;
529 rsp->mask.eo_u32[2] = *dwordp++;
530 rsp->mask.eo_u32[3] = *dwordp++;
533 /* Fill out the register table entries */
534 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
535 == EFX_ARRAY_SIZE(__siena_tables) * 4);
537 nitems = EFX_ARRAY_SIZE(__siena_tables);
538 dwordp = __siena_table_masks;
539 for (count = 0; count < nitems; ++count) {
540 rsp = __siena_tables + count;
541 rsp->mask.eo_u32[0] = *dwordp++;
542 rsp->mask.eo_u32[1] = *dwordp++;
543 rsp->mask.eo_u32[2] = *dwordp++;
544 rsp->mask.eo_u32[3] = *dwordp++;
547 if ((rc = efx_nic_test_registers(enp, __siena_registers,
548 EFX_ARRAY_SIZE(__siena_registers))) != 0)
551 if ((rc = efx_nic_test_tables(enp, __siena_tables,
552 EFX_PATTERN_BYTE_ALTERNATE,
553 EFX_ARRAY_SIZE(__siena_tables))) != 0)
556 if ((rc = efx_nic_test_tables(enp, __siena_tables,
557 EFX_PATTERN_BYTE_CHANGING,
558 EFX_ARRAY_SIZE(__siena_tables))) != 0)
561 if ((rc = efx_nic_test_tables(enp, __siena_tables,
562 EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
574 EFSYS_PROBE1(fail1, efx_rc_t, rc);
579 #endif /* EFSYS_OPT_DIAG */
581 #endif /* EFSYS_OPT_SIENA */