X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fcommon%2Fsfc_efx%2Fbase%2Fef10_nic.c;h=7a119302421db2167520ecb239fe6950cb8d7195;hb=798672850cfc68615b305a720f3638e643e2de2e;hp=f7c460181903ae507f085d4dca2061ed1e7c83a9;hpb=495c8fef56ead58a55394419d7f0269b09f349bb;p=dpdk.git diff --git a/drivers/common/sfc_efx/base/ef10_nic.c b/drivers/common/sfc_efx/base/ef10_nic.c index f7c4601819..7a11930242 100644 --- a/drivers/common/sfc_efx/base/ef10_nic.c +++ b/drivers/common/sfc_efx/base/ef10_nic.c @@ -10,7 +10,7 @@ #include "mcdi_mon.h" #endif -#if EFX_OPTS_EF10() +#if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() #include "ef10_tlv_layout.h" @@ -24,7 +24,7 @@ efx_mcdi_get_port_assignment( MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN); efx_rc_t rc; - EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp)); + EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp) || EFX_FAMILY_IS_EF10(enp)); req.emr_cmd = MC_CMD_GET_PORT_ASSIGNMENT; req.emr_in_buf = payload; @@ -68,7 +68,7 @@ efx_mcdi_get_port_modes( MC_CMD_GET_PORT_MODES_OUT_LEN); efx_rc_t rc; - EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp)); + EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp) || EFX_FAMILY_IS_EF10(enp)); req.emr_cmd = MC_CMD_GET_PORT_MODES; req.emr_in_buf = payload; @@ -223,6 +223,10 @@ fail1: return (rc); } +#endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */ + +#if EFX_OPTS_EF10() + __checkReturn efx_rc_t efx_mcdi_vadaptor_alloc( __in efx_nic_t *enp, @@ -292,6 +296,10 @@ fail1: return (rc); } +#endif /* EFX_OPTS_EF10() */ + +#if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() + __checkReturn efx_rc_t efx_mcdi_get_mac_address_pf( __in efx_nic_t *enp, @@ -302,7 +310,7 @@ efx_mcdi_get_mac_address_pf( MC_CMD_GET_MAC_ADDRESSES_OUT_LEN); efx_rc_t rc; - EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp)); + EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp) || EFX_FAMILY_IS_EF10(enp)); req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES; req.emr_in_buf = payload; @@ -358,7 +366,7 @@ efx_mcdi_get_mac_address_vf( MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX); efx_rc_t rc; - EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp)); + EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp) || EFX_FAMILY_IS_EF10(enp)); req.emr_cmd = MC_CMD_VPORT_GET_MAC_ADDRESSES; req.emr_in_buf = payload; @@ -420,7 +428,7 @@ efx_mcdi_get_clock( MC_CMD_GET_CLOCK_OUT_LEN); efx_rc_t rc; - EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp)); + EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp) || EFX_FAMILY_IS_EF10(enp)); req.emr_cmd = MC_CMD_GET_CLOCK; req.emr_in_buf = payload; @@ -569,7 +577,7 @@ fail1: return (rc); } -static __checkReturn efx_rc_t + __checkReturn efx_rc_t efx_mcdi_alloc_vis( __in efx_nic_t *enp, __in uint32_t min_vi_count, @@ -631,7 +639,7 @@ fail1: } -static __checkReturn efx_rc_t + __checkReturn efx_rc_t efx_mcdi_free_vis( __in efx_nic_t *enp) { @@ -663,6 +671,9 @@ fail1: return (rc); } +#endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */ + +#if EFX_OPTS_EF10() static __checkReturn efx_rc_t efx_mcdi_alloc_piobuf( @@ -978,6 +989,10 @@ ef10_nic_pio_unlink( return (efx_mcdi_unlink_piobuf(enp, vi_index)); } +#endif /* EFX_OPTS_EF10() */ + +#if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() + static __checkReturn efx_rc_t ef10_mcdi_get_pf_count( __in efx_nic_t *enp, @@ -1094,6 +1109,12 @@ ef10_get_datapath_caps( else encp->enc_fw_assisted_tso_v2_encap_enabled = B_FALSE; + /* Check if TSOv3 is supported */ + if (CAP_FLAGS2(req, TX_TSO_V3)) + encp->enc_tso_v3_enabled = B_TRUE; + else + encp->enc_tso_v3_enabled = B_FALSE; + /* Check if the firmware has vadapter/vport/vswitch support */ if (CAP_FLAGS1(req, EVB)) encp->enc_datapath_cap_evb = B_TRUE; @@ -1667,6 +1688,19 @@ static struct ef10_external_port_map_s { (1U << TLV_PORT_MODE_NA_2x2), /* mode 14 */ { EFX_EXT_PORT_NA, 0, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } }, + /* + * Modes that on Riverhead allocate each port number to a separate + * cage. + * port 0 -> cage 1 + * port 1 -> cage 2 + */ + { + EFX_FAMILY_RIVERHEAD, + (1U << TLV_PORT_MODE_1x1_NA) | /* mode 0 */ + (1U << TLV_PORT_MODE_1x4_NA) | /* mode 1 */ + (1U << TLV_PORT_MODE_1x1_1x1), /* mode 2 */ + { 0, 1, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } + }, }; static __checkReturn efx_rc_t @@ -1757,61 +1791,10 @@ fail1: return (rc); } -static __checkReturn efx_rc_t -ef10_set_workaround_bug26807( - __in efx_nic_t *enp) -{ - efx_nic_cfg_t *encp = &(enp->en_nic_cfg); - uint32_t flags; - efx_rc_t rc; - - /* - * If the bug26807 workaround is enabled, then firmware has enabled - * support for chained multicast filters. Firmware will reset (FLR) - * functions which have filters in the hardware filter table when the - * workaround is enabled/disabled. - * - * We must recheck if the workaround is enabled after inserting the - * first hardware filter, in case it has been changed since this check. - */ - rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG26807, - B_TRUE, &flags); - if (rc == 0) { - encp->enc_bug26807_workaround = B_TRUE; - if (flags & (1 << MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_LBN)) { - /* - * Other functions had installed filters before the - * workaround was enabled, and they have been reset - * by firmware. - */ - EFSYS_PROBE(bug26807_workaround_flr_done); - /* FIXME: bump MC warm boot count ? */ - } - } else if (rc == EACCES) { - /* - * Unprivileged functions cannot enable the workaround in older - * firmware. - */ - encp->enc_bug26807_workaround = B_FALSE; - } else if ((rc == ENOTSUP) || (rc == ENOENT)) { - encp->enc_bug26807_workaround = B_FALSE; - } else { - goto fail1; - } - - return (0); - -fail1: - EFSYS_PROBE1(fail1, efx_rc_t, rc); - - return (rc); -} - -static __checkReturn efx_rc_t -ef10_nic_board_cfg( + __checkReturn efx_rc_t +efx_mcdi_nic_board_cfg( __in efx_nic_t *enp) { - const efx_nic_ops_t *enop = enp->en_enop; efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); efx_nic_cfg_t *encp = &(enp->en_nic_cfg); ef10_link_state_t els; @@ -1892,7 +1875,6 @@ ef10_nic_board_cfg( } encp->enc_board_type = board_type; - encp->enc_clk_mult = 1; /* not used for EF10 */ /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */ if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0) @@ -1923,15 +1905,165 @@ ef10_nic_board_cfg( if ((rc = ef10_get_datapath_caps(enp)) != 0) goto fail9; + /* Get interrupt vector limits */ + if ((rc = efx_mcdi_get_vector_cfg(enp, &base, &nvec, NULL)) != 0) { + if (EFX_PCI_FUNCTION_IS_PF(encp)) + goto fail10; + + /* Ignore error (cannot query vector limits from a VF). */ + base = 0; + nvec = 1024; + } + encp->enc_intr_vec_base = base; + encp->enc_intr_limit = nvec; + + /* + * Get the current privilege mask. Note that this may be modified + * dynamically, so this value is informational only. DO NOT use + * the privilege mask to check for sufficient privileges, as that + * can result in time-of-check/time-of-use bugs. + */ + if ((rc = ef10_get_privilege_mask(enp, &mask)) != 0) + goto fail11; + encp->enc_privilege_mask = mask; + + return (0); + +fail11: + EFSYS_PROBE(fail11); +fail10: + EFSYS_PROBE(fail10); +fail9: + EFSYS_PROBE(fail9); +fail8: + EFSYS_PROBE(fail8); +fail7: + EFSYS_PROBE(fail7); +fail6: + EFSYS_PROBE(fail6); +fail5: + EFSYS_PROBE(fail5); +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + + __checkReturn efx_rc_t +efx_mcdi_entity_reset( + __in efx_nic_t *enp) +{ + efx_mcdi_req_t req; + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ENTITY_RESET_IN_LEN, + MC_CMD_ENTITY_RESET_OUT_LEN); + efx_rc_t rc; + + req.emr_cmd = MC_CMD_ENTITY_RESET; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_ENTITY_RESET_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_ENTITY_RESET_OUT_LEN; + + MCDI_IN_POPULATE_DWORD_1(req, ENTITY_RESET_IN_FLAG, + ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET, 1); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + +#endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */ + +#if EFX_OPTS_EF10() + +static __checkReturn efx_rc_t +ef10_set_workaround_bug26807( + __in efx_nic_t *enp) +{ + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + uint32_t flags; + efx_rc_t rc; + + /* + * If the bug26807 workaround is enabled, then firmware has enabled + * support for chained multicast filters. Firmware will reset (FLR) + * functions which have filters in the hardware filter table when the + * workaround is enabled/disabled. + * + * We must recheck if the workaround is enabled after inserting the + * first hardware filter, in case it has been changed since this check. + */ + rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG26807, + B_TRUE, &flags); + if (rc == 0) { + encp->enc_bug26807_workaround = B_TRUE; + if (flags & (1 << MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_LBN)) { + /* + * Other functions had installed filters before the + * workaround was enabled, and they have been reset + * by firmware. + */ + EFSYS_PROBE(bug26807_workaround_flr_done); + /* FIXME: bump MC warm boot count ? */ + } + } else if (rc == EACCES) { + /* + * Unprivileged functions cannot enable the workaround in older + * firmware. + */ + encp->enc_bug26807_workaround = B_FALSE; + } else if ((rc == ENOTSUP) || (rc == ENOENT)) { + encp->enc_bug26807_workaround = B_FALSE; + } else { + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + +static __checkReturn efx_rc_t +ef10_nic_board_cfg( + __in efx_nic_t *enp) +{ + const efx_nic_ops_t *enop = enp->en_enop; + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + efx_rc_t rc; + + if ((rc = efx_mcdi_nic_board_cfg(enp)) != 0) + goto fail1; + /* * Huntington RXDP firmware inserts a 0 or 14 byte prefix. * We only support the 14 byte prefix here. */ if (encp->enc_rx_prefix_size != 14) { rc = ENOTSUP; - goto fail10; + goto fail2; } + encp->enc_clk_mult = 1; /* not used for EF10 */ + /* Alignment for WPTR updates */ encp->enc_rx_push_align = EF10_RX_WPTR_ALIGN; @@ -1945,6 +2077,27 @@ ef10_nic_board_cfg( */ encp->enc_tx_tso_tcp_header_offset_limit = EF10_TCP_HEADER_OFFSET_LIMIT; + /* EF10 TSO engine demands that packet header be contiguous. */ + encp->enc_tx_tso_max_header_ndescs = 1; + + /* The overall TSO header length is not limited. */ + encp->enc_tx_tso_max_header_length = UINT32_MAX; + + /* + * There are no specific limitations on the number of + * TSO payload descriptors. + */ + encp->enc_tx_tso_max_payload_ndescs = UINT32_MAX; + + /* TSO superframe payload length is not limited. */ + encp->enc_tx_tso_max_payload_length = UINT32_MAX; + + /* + * Limitation on the maximum number of outgoing packets per + * TSO transaction described in SF-108452-SW. + */ + encp->enc_tx_tso_max_nframes = 32767; + /* * Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use * MC_CMD_GET_RESOURCE_LIMITS here as that reports the available @@ -1957,56 +2110,16 @@ ef10_nic_board_cfg( encp->enc_buftbl_limit = UINT32_MAX; - /* Get interrupt vector limits */ - if ((rc = efx_mcdi_get_vector_cfg(enp, &base, &nvec, NULL)) != 0) { - if (EFX_PCI_FUNCTION_IS_PF(encp)) - goto fail11; - - /* Ignore error (cannot query vector limits from a VF). */ - base = 0; - nvec = 1024; - } - encp->enc_intr_vec_base = base; - encp->enc_intr_limit = nvec; - - /* - * Get the current privilege mask. Note that this may be modified - * dynamically, so this value is informational only. DO NOT use - * the privilege mask to check for sufficient privileges, as that - * can result in time-of-check/time-of-use bugs. - */ - if ((rc = ef10_get_privilege_mask(enp, &mask)) != 0) - goto fail12; - encp->enc_privilege_mask = mask; - if ((rc = ef10_set_workaround_bug26807(enp)) != 0) - goto fail11; + goto fail3; /* Get remaining controller-specific board config */ if ((rc = enop->eno_board_cfg(enp)) != 0) if (rc != EACCES) - goto fail13; + goto fail4; return (0); -fail13: - EFSYS_PROBE(fail13); -fail12: - EFSYS_PROBE(fail12); -fail11: - EFSYS_PROBE(fail11); -fail10: - EFSYS_PROBE(fail10); -fail9: - EFSYS_PROBE(fail9); -fail8: - EFSYS_PROBE(fail8); -fail7: - EFSYS_PROBE(fail7); -fail6: - EFSYS_PROBE(fail6); -fail5: - EFSYS_PROBE(fail5); fail4: EFSYS_PROBE(fail4); fail3: @@ -2077,8 +2190,6 @@ ef10_nic_probe( } #endif - encp->enc_features = enp->en_features; - return (0); #if EFSYS_OPT_MON_STATS @@ -2184,9 +2295,6 @@ fail1: ef10_nic_reset( __in efx_nic_t *enp) { - efx_mcdi_req_t req; - EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ENTITY_RESET_IN_LEN, - MC_CMD_ENTITY_RESET_OUT_LEN); efx_rc_t rc; /* ef10_nic_reset() is called to recover from BADASSERT failures. */ @@ -2195,21 +2303,8 @@ ef10_nic_reset( if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) goto fail2; - req.emr_cmd = MC_CMD_ENTITY_RESET; - req.emr_in_buf = payload; - req.emr_in_length = MC_CMD_ENTITY_RESET_IN_LEN; - req.emr_out_buf = payload; - req.emr_out_length = MC_CMD_ENTITY_RESET_OUT_LEN; - - MCDI_IN_POPULATE_DWORD_1(req, ENTITY_RESET_IN_FLAG, - ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET, 1); - - efx_mcdi_execute(enp, &req); - - if (req.emr_rc != 0) { - rc = req.emr_rc; + if ((rc = efx_mcdi_entity_reset(enp)) != 0) goto fail3; - } /* Clear RX/TX DMA queue errors */ enp->en_reset_flags &= ~(EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR); @@ -2226,7 +2321,11 @@ fail1: return (rc); } -static __checkReturn efx_rc_t +#endif /* EFX_OPTS_EF10() */ + +#if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() + + __checkReturn efx_rc_t ef10_upstream_port_vadaptor_alloc( __in efx_nic_t *enp) { @@ -2278,6 +2377,10 @@ fail1: return (rc); } +#endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */ + +#if EFX_OPTS_EF10() + __checkReturn efx_rc_t ef10_nic_init( __in efx_nic_t *enp)