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.
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
40 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
42 static __checkReturn efx_rc_t
43 siena_nic_get_partn_mask(
45 __out unsigned int *maskp)
48 uint8_t payload[MAX(MC_CMD_NVRAM_TYPES_IN_LEN,
49 MC_CMD_NVRAM_TYPES_OUT_LEN)];
52 (void) memset(payload, 0, sizeof (payload));
53 req.emr_cmd = MC_CMD_NVRAM_TYPES;
54 req.emr_in_buf = payload;
55 req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN;
56 req.emr_out_buf = payload;
57 req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN;
59 efx_mcdi_execute(enp, &req);
61 if (req.emr_rc != 0) {
66 if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) {
71 *maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES);
78 EFSYS_PROBE1(fail1, efx_rc_t, rc);
83 #endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
85 static __checkReturn efx_rc_t
89 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
91 efx_dword_t capabilities;
93 uint32_t nevq, nrxq, ntxq;
96 /* External port identifier using one-based port numbering */
97 encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port;
99 /* Board configuration */
100 if ((rc = efx_mcdi_get_board_cfg(enp, &board_type,
101 &capabilities, mac_addr)) != 0)
104 EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
106 encp->enc_board_type = board_type;
109 * There is no possibility to determine the number of PFs on Siena
110 * by issuing MCDI request, and it is not an easy task to find the
111 * value based on the board type, so 'enc_hw_pf_count' is set to 1
113 encp->enc_hw_pf_count = 1;
115 /* Additional capabilities */
116 encp->enc_clk_mult = 1;
117 if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) {
118 enp->en_features |= EFX_FEATURE_TURBO;
120 if (EFX_DWORD_FIELD(capabilities,
121 MC_CMD_CAPABILITIES_TURBO_ACTIVE)) {
122 encp->enc_clk_mult = 2;
126 encp->enc_evq_timer_quantum_ns =
127 EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult;
128 encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
129 FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
131 /* When hash header insertion is enabled, Siena inserts 16 bytes */
132 encp->enc_rx_prefix_size = 16;
134 /* Alignment for receive packet DMA buffers */
135 encp->enc_rx_buf_align_start = 1;
136 encp->enc_rx_buf_align_end = 1;
138 /* Alignment for WPTR updates */
139 encp->enc_rx_push_align = 1;
141 /* Resource limits */
142 rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
148 nrxq = EFX_RXQ_LIMIT_TARGET;
149 ntxq = EFX_TXQ_LIMIT_TARGET;
151 encp->enc_evq_limit = nevq;
152 encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
153 encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
155 encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
156 (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
157 (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
159 encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
160 encp->enc_fw_assisted_tso_enabled = B_FALSE;
161 encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
162 encp->enc_fw_assisted_tso_v2_n_contexts = 0;
163 encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
165 /* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */
166 encp->enc_required_pcie_bandwidth_mbps = 2 * 10000;
167 encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2;
169 encp->enc_fw_verified_nvram_update_required = B_FALSE;
176 EFSYS_PROBE1(fail1, efx_rc_t, rc);
181 static __checkReturn efx_rc_t
185 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
188 /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
189 if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
192 #if EFSYS_OPT_PHY_STATS
193 /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
194 siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
195 NULL, &encp->enc_phy_stat_mask, NULL);
196 #endif /* EFSYS_OPT_PHY_STATS */
201 EFSYS_PROBE1(fail1, efx_rc_t, rc);
206 __checkReturn efx_rc_t
210 efx_port_t *epp = &(enp->en_port);
211 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
212 siena_link_state_t sls;
217 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
220 if ((rc = efx_nic_biu_test(enp)) != 0)
223 /* Clear the region register */
224 EFX_POPULATE_OWORD_4(oword,
225 FRF_AZ_ADR_REGION0, 0,
226 FRF_AZ_ADR_REGION1, (1 << 16),
227 FRF_AZ_ADR_REGION2, (2 << 16),
228 FRF_AZ_ADR_REGION3, (3 << 16));
229 EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
231 /* Read clear any assertion state */
232 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
235 /* Exit the assertion handler */
236 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
239 /* Wrestle control from the BMC */
240 if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
243 if ((rc = siena_board_cfg(enp)) != 0)
246 if ((rc = siena_phy_cfg(enp)) != 0)
249 /* Obtain the default PHY advertised capabilities */
250 if ((rc = siena_nic_reset(enp)) != 0)
252 if ((rc = siena_phy_get_link(enp, &sls)) != 0)
254 epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
255 epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
257 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
258 if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
260 enp->en_u.siena.enu_partn_mask = mask;
263 #if EFSYS_OPT_MAC_STATS
264 /* Wipe the MAC statistics */
265 if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
269 #if EFSYS_OPT_LOOPBACK
270 if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
274 #if EFSYS_OPT_MON_STATS
275 if ((rc = mcdi_mon_cfg_build(enp)) != 0)
279 encp->enc_features = enp->en_features;
283 #if EFSYS_OPT_MON_STATS
287 #if EFSYS_OPT_LOOPBACK
291 #if EFSYS_OPT_MAC_STATS
295 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
314 EFSYS_PROBE1(fail1, efx_rc_t, rc);
319 __checkReturn efx_rc_t
326 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
328 /* siena_nic_reset() is called to recover from BADASSERT failures. */
329 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
331 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
335 * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
336 * for backwards compatibility with PORT_RESET_IN_LEN.
338 EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
340 req.emr_cmd = MC_CMD_ENTITY_RESET;
341 req.emr_in_buf = NULL;
342 req.emr_in_length = 0;
343 req.emr_out_buf = NULL;
344 req.emr_out_length = 0;
346 efx_mcdi_execute(enp, &req);
348 if (req.emr_rc != 0) {
360 EFSYS_PROBE1(fail1, efx_rc_t, rc);
372 * RX_INGR_EN is always enabled on Siena, because we rely on
373 * the RX parser to be resiliant to missing SOP/EOP.
375 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
376 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
377 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
379 /* Disable parsing of additional 802.1Q in Q packets */
380 EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
381 EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
382 EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
391 EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
392 EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
395 __checkReturn efx_rc_t
401 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
403 /* Enable reporting of some events (e.g. link change) */
404 if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
407 siena_sram_init(enp);
409 /* Configure Siena's RX block */
410 siena_nic_rx_cfg(enp);
412 /* Disable USR_EVents for now */
413 siena_nic_usrev_dis(enp);
415 /* bug17057: Ensure set_link is called */
416 if ((rc = siena_phy_reconfigure(enp)) != 0)
419 enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;
426 EFSYS_PROBE1(fail1, efx_rc_t, rc);
435 _NOTE(ARGUNUSED(enp))
442 #if EFSYS_OPT_MON_STATS
443 mcdi_mon_cfg_free(enp);
444 #endif /* EFSYS_OPT_MON_STATS */
445 (void) efx_mcdi_drv_attach(enp, B_FALSE);
450 static efx_register_set_t __siena_registers[] = {
451 { FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
452 { FR_CZ_USR_EV_CFG_OFST, 0, 1 },
453 { FR_AZ_RX_CFG_REG_OFST, 0, 1 },
454 { FR_AZ_TX_CFG_REG_OFST, 0, 1 },
455 { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
456 { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
457 { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
458 { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
459 { FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
460 { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
461 { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
462 { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
463 { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
466 static const uint32_t __siena_register_masks[] = {
467 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
468 0x000103FF, 0x00000000, 0x00000000, 0x00000000,
469 0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
470 0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
471 0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
472 0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
473 0x00000003, 0x00000000, 0x00000000, 0x00000000,
474 0x000003FF, 0x00000000, 0x00000000, 0x00000000,
475 0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
476 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
477 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
478 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
479 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
482 static efx_register_set_t __siena_tables[] = {
483 { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
484 FR_AZ_RX_FILTER_TBL0_ROWS },
485 { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
486 FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
487 { FR_AZ_RX_DESC_PTR_TBL_OFST,
488 FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
489 { FR_AZ_TX_DESC_PTR_TBL_OFST,
490 FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
491 { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
492 { FR_CZ_TX_FILTER_TBL0_OFST,
493 FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
494 { FR_CZ_TX_MAC_FILTER_TBL0_OFST,
495 FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
498 static const uint32_t __siena_table_masks[] = {
499 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
500 0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
501 0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
502 0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
503 0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
504 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
505 0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
508 __checkReturn efx_rc_t
509 siena_nic_register_test(
512 efx_register_set_t *rsp;
513 const uint32_t *dwordp;
518 /* Fill out the register mask entries */
519 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
520 == EFX_ARRAY_SIZE(__siena_registers) * 4);
522 nitems = EFX_ARRAY_SIZE(__siena_registers);
523 dwordp = __siena_register_masks;
524 for (count = 0; count < nitems; ++count) {
525 rsp = __siena_registers + count;
526 rsp->mask.eo_u32[0] = *dwordp++;
527 rsp->mask.eo_u32[1] = *dwordp++;
528 rsp->mask.eo_u32[2] = *dwordp++;
529 rsp->mask.eo_u32[3] = *dwordp++;
532 /* Fill out the register table entries */
533 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
534 == EFX_ARRAY_SIZE(__siena_tables) * 4);
536 nitems = EFX_ARRAY_SIZE(__siena_tables);
537 dwordp = __siena_table_masks;
538 for (count = 0; count < nitems; ++count) {
539 rsp = __siena_tables + count;
540 rsp->mask.eo_u32[0] = *dwordp++;
541 rsp->mask.eo_u32[1] = *dwordp++;
542 rsp->mask.eo_u32[2] = *dwordp++;
543 rsp->mask.eo_u32[3] = *dwordp++;
546 if ((rc = efx_nic_test_registers(enp, __siena_registers,
547 EFX_ARRAY_SIZE(__siena_registers))) != 0)
550 if ((rc = efx_nic_test_tables(enp, __siena_tables,
551 EFX_PATTERN_BYTE_ALTERNATE,
552 EFX_ARRAY_SIZE(__siena_tables))) != 0)
555 if ((rc = efx_nic_test_tables(enp, __siena_tables,
556 EFX_PATTERN_BYTE_CHANGING,
557 EFX_ARRAY_SIZE(__siena_tables))) != 0)
560 if ((rc = efx_nic_test_tables(enp, __siena_tables,
561 EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
573 EFSYS_PROBE1(fail1, efx_rc_t, rc);
578 #endif /* EFSYS_OPT_DIAG */
580 #endif /* EFSYS_OPT_SIENA */