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 static __checkReturn efx_rc_t
41 siena_nic_get_partn_mask(
43 __out unsigned int *maskp)
46 uint8_t payload[MAX(MC_CMD_NVRAM_TYPES_IN_LEN,
47 MC_CMD_NVRAM_TYPES_OUT_LEN)];
50 (void) memset(payload, 0, sizeof (payload));
51 req.emr_cmd = MC_CMD_NVRAM_TYPES;
52 req.emr_in_buf = payload;
53 req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN;
54 req.emr_out_buf = payload;
55 req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN;
57 efx_mcdi_execute(enp, &req);
59 if (req.emr_rc != 0) {
64 if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) {
69 *maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES);
76 EFSYS_PROBE1(fail1, efx_rc_t, rc);
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;
104 /* Additional capabilities */
105 encp->enc_clk_mult = 1;
106 if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) {
107 enp->en_features |= EFX_FEATURE_TURBO;
109 if (EFX_DWORD_FIELD(capabilities,
110 MC_CMD_CAPABILITIES_TURBO_ACTIVE)) {
111 encp->enc_clk_mult = 2;
115 encp->enc_evq_timer_quantum_ns =
116 EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult;
117 encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
118 FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
120 /* When hash header insertion is enabled, Siena inserts 16 bytes */
121 encp->enc_rx_prefix_size = 16;
123 /* Alignment for receive packet DMA buffers */
124 encp->enc_rx_buf_align_start = 1;
125 encp->enc_rx_buf_align_end = 1;
127 /* Alignment for WPTR updates */
128 encp->enc_rx_push_align = 1;
130 /* Resource limits */
131 rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
137 nrxq = EFX_RXQ_LIMIT_TARGET;
138 ntxq = EFX_TXQ_LIMIT_TARGET;
140 encp->enc_evq_limit = nevq;
141 encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
142 encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
144 encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
145 (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
146 (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
148 encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
149 encp->enc_fw_assisted_tso_enabled = B_FALSE;
150 encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
151 encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
153 /* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */
154 encp->enc_required_pcie_bandwidth_mbps = 2 * 10000;
155 encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2;
162 EFSYS_PROBE1(fail1, efx_rc_t, rc);
167 static __checkReturn efx_rc_t
171 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
174 /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
175 if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
178 #if EFSYS_OPT_PHY_STATS
179 /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
180 siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
181 NULL, &encp->enc_phy_stat_mask, NULL);
182 #endif /* EFSYS_OPT_PHY_STATS */
187 EFSYS_PROBE1(fail1, efx_rc_t, rc);
192 __checkReturn efx_rc_t
196 efx_port_t *epp = &(enp->en_port);
197 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
198 siena_link_state_t sls;
203 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
206 if ((rc = efx_nic_biu_test(enp)) != 0)
209 /* Clear the region register */
210 EFX_POPULATE_OWORD_4(oword,
211 FRF_AZ_ADR_REGION0, 0,
212 FRF_AZ_ADR_REGION1, (1 << 16),
213 FRF_AZ_ADR_REGION2, (2 << 16),
214 FRF_AZ_ADR_REGION3, (3 << 16));
215 EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
217 /* Read clear any assertion state */
218 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
221 /* Exit the assertion handler */
222 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
225 /* Wrestle control from the BMC */
226 if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
229 if ((rc = siena_board_cfg(enp)) != 0)
232 if ((rc = siena_phy_cfg(enp)) != 0)
235 /* Obtain the default PHY advertised capabilities */
236 if ((rc = siena_nic_reset(enp)) != 0)
238 if ((rc = siena_phy_get_link(enp, &sls)) != 0)
240 epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
241 epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
243 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
244 if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
246 enp->en_u.siena.enu_partn_mask = mask;
249 #if EFSYS_OPT_MAC_STATS
250 /* Wipe the MAC statistics */
251 if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
255 #if EFSYS_OPT_LOOPBACK
256 if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
260 #if EFSYS_OPT_MON_STATS
261 if ((rc = mcdi_mon_cfg_build(enp)) != 0)
265 encp->enc_features = enp->en_features;
269 #if EFSYS_OPT_MON_STATS
273 #if EFSYS_OPT_LOOPBACK
277 #if EFSYS_OPT_MAC_STATS
281 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
300 EFSYS_PROBE1(fail1, efx_rc_t, rc);
305 __checkReturn efx_rc_t
312 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
314 /* siena_nic_reset() is called to recover from BADASSERT failures. */
315 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
317 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
321 * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
322 * for backwards compatibility with PORT_RESET_IN_LEN.
324 EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
326 req.emr_cmd = MC_CMD_ENTITY_RESET;
327 req.emr_in_buf = NULL;
328 req.emr_in_length = 0;
329 req.emr_out_buf = NULL;
330 req.emr_out_length = 0;
332 efx_mcdi_execute(enp, &req);
334 if (req.emr_rc != 0) {
346 EFSYS_PROBE1(fail1, efx_rc_t, rc);
358 * RX_INGR_EN is always enabled on Siena, because we rely on
359 * the RX parser to be resiliant to missing SOP/EOP.
361 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
362 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
363 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
365 /* Disable parsing of additional 802.1Q in Q packets */
366 EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
367 EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
368 EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
377 EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
378 EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
381 __checkReturn efx_rc_t
387 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
389 /* Enable reporting of some events (e.g. link change) */
390 if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
393 siena_sram_init(enp);
395 /* Configure Siena's RX block */
396 siena_nic_rx_cfg(enp);
398 /* Disable USR_EVents for now */
399 siena_nic_usrev_dis(enp);
401 /* bug17057: Ensure set_link is called */
402 if ((rc = siena_phy_reconfigure(enp)) != 0)
405 enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;
412 EFSYS_PROBE1(fail1, efx_rc_t, rc);
421 _NOTE(ARGUNUSED(enp))
428 #if EFSYS_OPT_MON_STATS
429 mcdi_mon_cfg_free(enp);
430 #endif /* EFSYS_OPT_MON_STATS */
431 (void) efx_mcdi_drv_attach(enp, B_FALSE);
436 static efx_register_set_t __siena_registers[] = {
437 { FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
438 { FR_CZ_USR_EV_CFG_OFST, 0, 1 },
439 { FR_AZ_RX_CFG_REG_OFST, 0, 1 },
440 { FR_AZ_TX_CFG_REG_OFST, 0, 1 },
441 { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
442 { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
443 { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
444 { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
445 { FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
446 { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
447 { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
448 { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
449 { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
452 static const uint32_t __siena_register_masks[] = {
453 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
454 0x000103FF, 0x00000000, 0x00000000, 0x00000000,
455 0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
456 0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
457 0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
458 0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
459 0x00000003, 0x00000000, 0x00000000, 0x00000000,
460 0x000003FF, 0x00000000, 0x00000000, 0x00000000,
461 0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
462 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
463 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
464 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
465 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
468 static efx_register_set_t __siena_tables[] = {
469 { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
470 FR_AZ_RX_FILTER_TBL0_ROWS },
471 { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
472 FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
473 { FR_AZ_RX_DESC_PTR_TBL_OFST,
474 FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
475 { FR_AZ_TX_DESC_PTR_TBL_OFST,
476 FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
477 { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
478 { FR_CZ_TX_FILTER_TBL0_OFST,
479 FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
480 { FR_CZ_TX_MAC_FILTER_TBL0_OFST,
481 FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
484 static const uint32_t __siena_table_masks[] = {
485 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
486 0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
487 0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
488 0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
489 0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
490 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
491 0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
494 __checkReturn efx_rc_t
495 siena_nic_register_test(
498 efx_register_set_t *rsp;
499 const uint32_t *dwordp;
504 /* Fill out the register mask entries */
505 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
506 == EFX_ARRAY_SIZE(__siena_registers) * 4);
508 nitems = EFX_ARRAY_SIZE(__siena_registers);
509 dwordp = __siena_register_masks;
510 for (count = 0; count < nitems; ++count) {
511 rsp = __siena_registers + count;
512 rsp->mask.eo_u32[0] = *dwordp++;
513 rsp->mask.eo_u32[1] = *dwordp++;
514 rsp->mask.eo_u32[2] = *dwordp++;
515 rsp->mask.eo_u32[3] = *dwordp++;
518 /* Fill out the register table entries */
519 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
520 == EFX_ARRAY_SIZE(__siena_tables) * 4);
522 nitems = EFX_ARRAY_SIZE(__siena_tables);
523 dwordp = __siena_table_masks;
524 for (count = 0; count < nitems; ++count) {
525 rsp = __siena_tables + 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 if ((rc = efx_nic_test_registers(enp, __siena_registers,
533 EFX_ARRAY_SIZE(__siena_registers))) != 0)
536 if ((rc = efx_nic_test_tables(enp, __siena_tables,
537 EFX_PATTERN_BYTE_ALTERNATE,
538 EFX_ARRAY_SIZE(__siena_tables))) != 0)
541 if ((rc = efx_nic_test_tables(enp, __siena_tables,
542 EFX_PATTERN_BYTE_CHANGING,
543 EFX_ARRAY_SIZE(__siena_tables))) != 0)
546 if ((rc = efx_nic_test_tables(enp, __siena_tables,
547 EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
559 EFSYS_PROBE1(fail1, efx_rc_t, rc);
564 #endif /* EFSYS_OPT_DIAG */
566 #endif /* EFSYS_OPT_SIENA */