From 47af701989bcab5dc0c8be9bc0c46793278eb136 Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Mon, 18 Sep 2017 18:51:32 -0700 Subject: [PATCH] net/qede/base: add UFP support Add support for UFP (Unified Fabric Port) multi-function mode. It includes new APIs for reading UFP configuration, handling UFP events, retriving UFP status and UFP ramrod update etc. Signed-off-by: Rasesh Mody --- drivers/net/qede/base/ecore.h | 45 ++++++++++++- drivers/net/qede/base/ecore_dcbx.c | 16 ++++- drivers/net/qede/base/ecore_dev.c | 77 +++++++++++++++++------ drivers/net/qede/base/ecore_dev_api.h | 8 ++- drivers/net/qede/base/ecore_mcp.c | 72 +++++++++++++++++++++ drivers/net/qede/base/ecore_mcp.h | 9 +++ drivers/net/qede/base/ecore_sp_commands.c | 68 +++++++++++++++----- drivers/net/qede/base/ecore_sp_commands.h | 11 +++- drivers/net/qede/base/mcp_public.h | 30 +++++++++ drivers/net/qede/qede_if.h | 2 +- drivers/net/qede/qede_main.c | 3 +- 11 files changed, 296 insertions(+), 45 deletions(-) diff --git a/drivers/net/qede/base/ecore.h b/drivers/net/qede/base/ecore.h index 0199608fde..3bc1b201d2 100644 --- a/drivers/net/qede/base/ecore.h +++ b/drivers/net/qede/base/ecore.h @@ -507,6 +507,45 @@ struct ecore_fw_data { u32 init_ops_size; }; +enum ecore_mf_mode_bit { + /* Supports PF-classification based on tag */ + ECORE_MF_OVLAN_CLSS, + + /* Supports PF-classification based on MAC */ + ECORE_MF_LLH_MAC_CLSS, + + /* Supports PF-classification based on protocol type */ + ECORE_MF_LLH_PROTO_CLSS, + + /* Requires a default PF to be set */ + ECORE_MF_NEED_DEF_PF, + + /* Allow LL2 to multicast/broadcast */ + ECORE_MF_LL2_NON_UNICAST, + + /* Allow Cross-PF [& child VFs] Tx-switching */ + ECORE_MF_INTER_PF_SWITCH, + + /* TODO - if we ever re-utilize any of this logic, we can rename */ + ECORE_MF_UFP_SPECIFIC, +}; + +enum ecore_ufp_mode { + ECORE_UFP_MODE_ETS, + ECORE_UFP_MODE_VNIC_BW, +}; + +enum ecore_ufp_pri_type { + ECORE_UFP_PRI_OS, + ECORE_UFP_PRI_VNIC +}; + +struct ecore_ufp_info { + enum ecore_ufp_pri_type pri_type; + enum ecore_ufp_mode mode; + u8 tc; +}; + struct ecore_hwfn { struct ecore_dev *p_dev; u8 my_id; /* ID inside the PF */ @@ -588,6 +627,7 @@ struct ecore_hwfn { struct ecore_pf_iov *pf_iov_info; struct ecore_mcp_info *mcp_info; struct ecore_dcbx_info *p_dcbx_info; + struct ecore_ufp_info ufp_info; struct ecore_dmae_info dmae_info; @@ -625,13 +665,12 @@ struct ecore_hwfn { struct ecore_ptt *p_arfs_ptt; }; -#ifndef __EXTRACT__LINUX__ enum ecore_mf_mode { ECORE_MF_DEFAULT, ECORE_MF_OVLAN, ECORE_MF_NPAR, + ECORE_MF_UFP, }; -#endif /* @DPDK */ struct ecore_dbg_feature { @@ -727,6 +766,8 @@ struct ecore_dev { u8 num_funcs_in_port; u8 path_id; + + unsigned long mf_bits; enum ecore_mf_mode mf_mode; #define IS_MF_DEFAULT(_p_hwfn) \ (((_p_hwfn)->p_dev)->mf_mode == ECORE_MF_DEFAULT) diff --git a/drivers/net/qede/base/ecore_dcbx.c b/drivers/net/qede/base/ecore_dcbx.c index 66f21fbac4..ba3560a566 100644 --- a/drivers/net/qede/base/ecore_dcbx.c +++ b/drivers/net/qede/base/ecore_dcbx.c @@ -234,8 +234,8 @@ ecore_dcbx_process_tlv(struct ecore_hwfn *p_hwfn, int count, u8 dcbx_version) { enum dcbx_protocol_type type; + bool enable, ieee, eth_tlv; u8 tc, priority_map; - bool enable, ieee; u16 protocol_id; u8 priority; enum _ecore_status_t rc = ECORE_SUCCESS; @@ -246,6 +246,7 @@ ecore_dcbx_process_tlv(struct ecore_hwfn *p_hwfn, count, pri_tc_tbl, dcbx_version); ieee = (dcbx_version == DCBX_CONFIG_VERSION_IEEE); + eth_tlv = false; /* Parse APP TLV */ for (i = 0; i < count; i++) { protocol_id = GET_MFW_FIELD(p_tbl[i].entry, @@ -269,12 +270,23 @@ ecore_dcbx_process_tlv(struct ecore_hwfn *p_hwfn, * indication, but we only got here if there was an * app tlv for the protocol, so dcbx must be enabled. */ - enable = !(type == DCBX_PROTOCOL_ETH); + if (type == DCBX_PROTOCOL_ETH) { + enable = false; + eth_tlv = true; + } else { + enable = true; + } ecore_dcbx_update_app_info(p_data, p_hwfn, enable, priority, tc, type); } } + + /* If Eth TLV is not detected, use UFP TC as default TC */ + if (OSAL_TEST_BIT(ECORE_MF_UFP_SPECIFIC, + &p_hwfn->p_dev->mf_bits) && !eth_tlv) + p_data->arr[DCBX_PROTOCOL_ETH].tc = p_hwfn->ufp_info.tc; + /* Update ramrod protocol data and hw_info fields * with default info when corresponding APP TLV's are not detected. * The enabled field has a different logic for ethernet as only for diff --git a/drivers/net/qede/base/ecore_dev.c b/drivers/net/qede/base/ecore_dev.c index edf28963cb..283c65bf64 100644 --- a/drivers/net/qede/base/ecore_dev.c +++ b/drivers/net/qede/base/ecore_dev.c @@ -1455,19 +1455,11 @@ static enum _ecore_status_t ecore_calc_hw_mode(struct ecore_hwfn *p_hwfn) return ECORE_INVAL; } - switch (p_hwfn->p_dev->mf_mode) { - case ECORE_MF_DEFAULT: - case ECORE_MF_NPAR: - hw_mode |= 1 << MODE_MF_SI; - break; - case ECORE_MF_OVLAN: + if (OSAL_TEST_BIT(ECORE_MF_OVLAN_CLSS, + &p_hwfn->p_dev->mf_bits)) hw_mode |= 1 << MODE_MF_SD; - break; - default: - DP_NOTICE(p_hwfn, true, - "Unsupported MF mode, init as DEFAULT\n"); + else hw_mode |= 1 << MODE_MF_SI; - } #ifndef ASIC_ONLY if (CHIP_REV_IS_SLOW(p_hwfn->p_dev)) { @@ -2154,6 +2146,11 @@ ecore_hw_init_pf(struct ecore_hwfn *p_hwfn, STORE_RT_REG(p_hwfn, NIG_REG_LLH_FUNC_TAG_EN_RT_OFFSET, 1); STORE_RT_REG(p_hwfn, NIG_REG_LLH_FUNC_TAG_VALUE_RT_OFFSET, p_hwfn->hw_info.ovlan); + + DP_VERBOSE(p_hwfn, ECORE_MSG_HW, + "Configuring LLH_FUNC_FILTER_HDR_SEL\n"); + STORE_RT_REG(p_hwfn, NIG_REG_LLH_FUNC_FILTER_HDR_SEL_RT_OFFSET, + 1); } /* Enable classification by MAC if needed */ @@ -2214,7 +2211,6 @@ ecore_hw_init_pf(struct ecore_hwfn *p_hwfn, /* send function start command */ rc = ecore_sp_pf_start(p_hwfn, p_ptt, p_tunn, - p_hwfn->p_dev->mf_mode, allow_npar_tx_switch); if (rc) { DP_NOTICE(p_hwfn, true, @@ -3503,6 +3499,37 @@ ecore_hw_get_nvm_info(struct ecore_hwfn *p_hwfn, NVM_CFG1_GLOB_MF_MODE_OFFSET; switch (mf_mode) { + case NVM_CFG1_GLOB_MF_MODE_MF_ALLOWED: + p_hwfn->p_dev->mf_bits = 1 << ECORE_MF_OVLAN_CLSS; + break; + case NVM_CFG1_GLOB_MF_MODE_UFP: + p_hwfn->p_dev->mf_bits = 1 << ECORE_MF_OVLAN_CLSS | + 1 << ECORE_MF_UFP_SPECIFIC; + break; + + case NVM_CFG1_GLOB_MF_MODE_NPAR1_0: + p_hwfn->p_dev->mf_bits = 1 << ECORE_MF_LLH_MAC_CLSS | + 1 << ECORE_MF_LLH_PROTO_CLSS | + 1 << ECORE_MF_LL2_NON_UNICAST | + 1 << ECORE_MF_INTER_PF_SWITCH; + break; + case NVM_CFG1_GLOB_MF_MODE_DEFAULT: + p_hwfn->p_dev->mf_bits = 1 << ECORE_MF_LLH_MAC_CLSS | + 1 << ECORE_MF_LLH_PROTO_CLSS | + 1 << ECORE_MF_LL2_NON_UNICAST; + if (ECORE_IS_BB(p_hwfn->p_dev)) + p_hwfn->p_dev->mf_bits |= 1 << ECORE_MF_NEED_DEF_PF; + break; + } + DP_INFO(p_hwfn, "Multi function mode is 0x%lx\n", + p_hwfn->p_dev->mf_bits); + + /* It's funny since we have another switch, but it's easier + * to throw this away in linux this way. Long term, it might be + * better to have have getters for needed ECORE_MF_* fields, + * convert client code and eliminate this. + */ + switch (mf_mode) { case NVM_CFG1_GLOB_MF_MODE_MF_ALLOWED: p_hwfn->p_dev->mf_mode = ECORE_MF_OVLAN; break; @@ -3512,9 +3539,10 @@ ecore_hw_get_nvm_info(struct ecore_hwfn *p_hwfn, case NVM_CFG1_GLOB_MF_MODE_DEFAULT: p_hwfn->p_dev->mf_mode = ECORE_MF_DEFAULT; break; + case NVM_CFG1_GLOB_MF_MODE_UFP: + p_hwfn->p_dev->mf_mode = ECORE_MF_UFP; + break; } - DP_INFO(p_hwfn, "Multi function mode is %08x\n", - p_hwfn->p_dev->mf_mode); /* Read Multi-function information from shmem */ addr = MCP_REG_SCRATCH + nvm_cfg1_offset + @@ -3813,6 +3841,8 @@ ecore_get_hw_info(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, ecore_mcp_cmd_port_init(p_hwfn, p_ptt); ecore_mcp_get_eee_caps(p_hwfn, p_ptt); + + ecore_mcp_read_ufp_config(p_hwfn, p_ptt); } if (personality != ECORE_PCI_DEFAULT) { @@ -4609,7 +4639,8 @@ enum _ecore_status_t ecore_llh_add_mac_filter(struct ecore_hwfn *p_hwfn, u32 high, low, entry_num; enum _ecore_status_t rc; - if (!(IS_MF_SI(p_hwfn) || IS_MF_DEFAULT(p_hwfn))) + if (!OSAL_TEST_BIT(ECORE_MF_LLH_MAC_CLSS, + &p_hwfn->p_dev->mf_bits)) return ECORE_SUCCESS; high = p_filter[1] | (p_filter[0] << 8); @@ -4676,7 +4707,8 @@ void ecore_llh_remove_mac_filter(struct ecore_hwfn *p_hwfn, u32 high, low, entry_num; enum _ecore_status_t rc; - if (!(IS_MF_SI(p_hwfn) || IS_MF_DEFAULT(p_hwfn))) + if (!OSAL_TEST_BIT(ECORE_MF_LLH_MAC_CLSS, + &p_hwfn->p_dev->mf_bits)) return; high = p_filter[1] | (p_filter[0] << 8); @@ -4750,7 +4782,8 @@ ecore_llh_add_protocol_filter(struct ecore_hwfn *p_hwfn, u32 high, low, entry_num; enum _ecore_status_t rc; - if (!(IS_MF_SI(p_hwfn) || IS_MF_DEFAULT(p_hwfn))) + if (!OSAL_TEST_BIT(ECORE_MF_LLH_PROTO_CLSS, + &p_hwfn->p_dev->mf_bits)) return ECORE_SUCCESS; high = 0; @@ -4893,7 +4926,8 @@ ecore_llh_remove_protocol_filter(struct ecore_hwfn *p_hwfn, u32 high, low, entry_num; enum _ecore_status_t rc; - if (!(IS_MF_SI(p_hwfn) || IS_MF_DEFAULT(p_hwfn))) + if (!OSAL_TEST_BIT(ECORE_MF_LLH_PROTO_CLSS, + &p_hwfn->p_dev->mf_bits)) return; high = 0; @@ -4961,7 +4995,10 @@ static void ecore_llh_clear_all_filters_bb_ah(struct ecore_hwfn *p_hwfn, void ecore_llh_clear_all_filters(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt) { - if (!(IS_MF_SI(p_hwfn) || IS_MF_DEFAULT(p_hwfn))) + if (!OSAL_TEST_BIT(ECORE_MF_LLH_PROTO_CLSS, + &p_hwfn->p_dev->mf_bits) && + !OSAL_TEST_BIT(ECORE_MF_LLH_MAC_CLSS, + &p_hwfn->p_dev->mf_bits)) return; if (ECORE_IS_BB(p_hwfn->p_dev) || ECORE_IS_AH(p_hwfn->p_dev)) @@ -4972,7 +5009,7 @@ enum _ecore_status_t ecore_llh_set_function_as_default(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt) { - if (IS_MF_DEFAULT(p_hwfn) && ECORE_IS_BB(p_hwfn->p_dev)) { + if (OSAL_TEST_BIT(ECORE_MF_NEED_DEF_PF, &p_hwfn->p_dev->mf_bits)) { ecore_wr(p_hwfn, p_ptt, NIG_REG_LLH_TAGMAC_DEF_PF_VECTOR, 1 << p_hwfn->abs_pf_id / 2); diff --git a/drivers/net/qede/base/ecore_dev_api.h b/drivers/net/qede/base/ecore_dev_api.h index fd453f51ee..98bcabe878 100644 --- a/drivers/net/qede/base/ecore_dev_api.h +++ b/drivers/net/qede/base/ecore_dev_api.h @@ -194,6 +194,12 @@ enum _ecore_status_t ecore_db_recovery_add(struct ecore_dev *p_dev, enum _ecore_status_t ecore_db_recovery_del(struct ecore_dev *p_dev, void OSAL_IOMEM *db_addr, void *db_data); + +static OSAL_INLINE bool ecore_is_mf_ufp(struct ecore_hwfn *p_hwfn) +{ + return !!OSAL_TEST_BIT(ECORE_MF_UFP_SPECIFIC, &p_hwfn->p_dev->mf_bits); +} + #endif /** @@ -295,7 +301,6 @@ struct ecore_ptt *ecore_ptt_acquire(struct ecore_hwfn *p_hwfn); void ecore_ptt_release(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt); -#ifndef __EXTRACT__LINUX__ struct ecore_eth_stats_common { u64 no_buff_discards; u64 packet_too_big_discard; @@ -386,7 +391,6 @@ struct ecore_eth_stats { struct ecore_eth_stats_ah ah; }; }; -#endif enum ecore_dmae_address_type_t { ECORE_DMAE_ADDRESS_HOST_VIRT, diff --git a/drivers/net/qede/base/ecore_mcp.c b/drivers/net/qede/base/ecore_mcp.c index e6980e6968..6b5d755097 100644 --- a/drivers/net/qede/base/ecore_mcp.c +++ b/drivers/net/qede/base/ecore_mcp.c @@ -21,6 +21,7 @@ #include "ecore_iro.h" #include "ecore_dcbx.h" #include "ecore_sp_commands.h" +#include "ecore_cxt.h" #define CHIP_MCP_RESP_ITER_US 10 #define EMUL_MCP_RESP_ITER_US (1000 * 1000) @@ -1860,6 +1861,74 @@ static void ecore_mcp_handle_critical_error(struct ecore_hwfn *p_hwfn, ecore_hw_err_notify(p_hwfn, ECORE_HW_ERR_HW_ATTN); } +void +ecore_mcp_read_ufp_config(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt) +{ + struct public_func shmem_info; + u32 port_cfg, val; + + if (!OSAL_TEST_BIT(ECORE_MF_UFP_SPECIFIC, &p_hwfn->p_dev->mf_bits)) + return; + + OSAL_MEMSET(&p_hwfn->ufp_info, 0, sizeof(p_hwfn->ufp_info)); + port_cfg = ecore_rd(p_hwfn, p_ptt, p_hwfn->mcp_info->port_addr + + OFFSETOF(struct public_port, oem_cfg_port)); + val = GET_MFW_FIELD(port_cfg, OEM_CFG_CHANNEL_TYPE); + if (val != OEM_CFG_CHANNEL_TYPE_STAGGED) + DP_NOTICE(p_hwfn, false, "Incorrect UFP Channel type %d\n", + val); + + val = GET_MFW_FIELD(port_cfg, OEM_CFG_SCHED_TYPE); + if (val == OEM_CFG_SCHED_TYPE_ETS) + p_hwfn->ufp_info.mode = ECORE_UFP_MODE_ETS; + else if (val == OEM_CFG_SCHED_TYPE_VNIC_BW) + p_hwfn->ufp_info.mode = ECORE_UFP_MODE_VNIC_BW; + else + DP_NOTICE(p_hwfn, false, "Unknown UFP scheduling mode %d\n", + val); + + ecore_mcp_get_shmem_func(p_hwfn, p_ptt, &shmem_info, + MCP_PF_ID(p_hwfn)); + val = GET_MFW_FIELD(shmem_info.oem_cfg_func, OEM_CFG_FUNC_TC); + p_hwfn->ufp_info.tc = (u8)val; + val = GET_MFW_FIELD(shmem_info.oem_cfg_func, + OEM_CFG_FUNC_HOST_PRI_CTRL); + if (val == OEM_CFG_FUNC_HOST_PRI_CTRL_VNIC) + p_hwfn->ufp_info.pri_type = ECORE_UFP_PRI_VNIC; + else if (val == OEM_CFG_FUNC_HOST_PRI_CTRL_OS) + p_hwfn->ufp_info.pri_type = ECORE_UFP_PRI_OS; + else + DP_NOTICE(p_hwfn, false, "Unknown Host priority control %d\n", + val); + + DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, + "UFP shmem config: mode = %d tc = %d pri_type = %d\n", + p_hwfn->ufp_info.mode, p_hwfn->ufp_info.tc, + p_hwfn->ufp_info.pri_type); +} + +static enum _ecore_status_t +ecore_mcp_handle_ufp_event(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt) +{ + ecore_mcp_read_ufp_config(p_hwfn, p_ptt); + + if (p_hwfn->ufp_info.mode == ECORE_UFP_MODE_VNIC_BW) { + p_hwfn->qm_info.ooo_tc = p_hwfn->ufp_info.tc; + p_hwfn->hw_info.offload_tc = p_hwfn->ufp_info.tc; + + ecore_qm_reconf(p_hwfn, p_ptt); + } else { + /* Merge UFP TC with the dcbx TC data */ + ecore_dcbx_mib_update_event(p_hwfn, p_ptt, + ECORE_DCBX_OPERATIONAL_MIB); + } + + /* update storm FW with negotiation results */ + ecore_sp_pf_update_ufp(p_hwfn); + + return ECORE_SUCCESS; +} + enum _ecore_status_t ecore_mcp_handle_events(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt) { @@ -1903,6 +1972,9 @@ enum _ecore_status_t ecore_mcp_handle_events(struct ecore_hwfn *p_hwfn, ecore_dcbx_mib_update_event(p_hwfn, p_ptt, ECORE_DCBX_OPERATIONAL_MIB); break; + case MFW_DRV_MSG_OEM_CFG_UPDATE: + ecore_mcp_handle_ufp_event(p_hwfn, p_ptt); + break; case MFW_DRV_MSG_TRANSCEIVER_STATE_CHANGE: ecore_mcp_handle_transceiver_change(p_hwfn, p_ptt); break; diff --git a/drivers/net/qede/base/ecore_mcp.h b/drivers/net/qede/base/ecore_mcp.h index 569c0645c1..7f12a0aa08 100644 --- a/drivers/net/qede/base/ecore_mcp.h +++ b/drivers/net/qede/base/ecore_mcp.h @@ -521,4 +521,13 @@ enum _ecore_status_t ecore_mcp_get_capabilities(struct ecore_hwfn *p_hwfn, enum _ecore_status_t ecore_mcp_set_capabilities(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt); +/** + * @brief Read ufp config from the shared memory. + * + * @param p_hwfn + * @param p_ptt + */ +void +ecore_mcp_read_ufp_config(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt); + #endif /* __ECORE_MCP_H__ */ diff --git a/drivers/net/qede/base/ecore_sp_commands.c b/drivers/net/qede/base/ecore_sp_commands.c index dfa2ab0758..7598e7a6c0 100644 --- a/drivers/net/qede/base/ecore_sp_commands.c +++ b/drivers/net/qede/base/ecore_sp_commands.c @@ -294,10 +294,11 @@ ecore_tunn_set_pf_start_params(struct ecore_hwfn *p_hwfn, &p_tun->ip_gre); } +#define ETH_P_8021Q 0x8100 + enum _ecore_status_t ecore_sp_pf_start(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, struct ecore_tunnel_info *p_tunn, - enum ecore_mf_mode mode, bool allow_npar_tx_switch) { struct pf_start_ramrod_data *p_ramrod = OSAL_NULL; @@ -307,6 +308,7 @@ enum _ecore_status_t ecore_sp_pf_start(struct ecore_hwfn *p_hwfn, struct ecore_sp_init_data init_data; enum _ecore_status_t rc = ECORE_NOTIMPL; u8 page_cnt; + int i; /* update initial eq producer */ ecore_eq_prod_update(p_hwfn, @@ -334,20 +336,26 @@ enum _ecore_status_t ecore_sp_pf_start(struct ecore_hwfn *p_hwfn, p_ramrod->dont_log_ramrods = 0; p_ramrod->log_type_mask = OSAL_CPU_TO_LE16(0x8f); - switch (mode) { - case ECORE_MF_DEFAULT: - case ECORE_MF_NPAR: - p_ramrod->mf_mode = MF_NPAR; - break; - case ECORE_MF_OVLAN: + if (OSAL_TEST_BIT(ECORE_MF_OVLAN_CLSS, &p_hwfn->p_dev->mf_bits)) p_ramrod->mf_mode = MF_OVLAN; - break; - default: - DP_NOTICE(p_hwfn, true, - "Unsupported MF mode, init as DEFAULT\n"); + else p_ramrod->mf_mode = MF_NPAR; + + p_ramrod->outer_tag_config.outer_tag.tci = + OSAL_CPU_TO_LE16(p_hwfn->hw_info.ovlan); + + if (OSAL_TEST_BIT(ECORE_MF_UFP_SPECIFIC, &p_hwfn->p_dev->mf_bits)) { + p_ramrod->outer_tag_config.outer_tag.tpid = + OSAL_CPU_TO_LE16(ETH_P_8021Q); + if (p_hwfn->ufp_info.pri_type == ECORE_UFP_PRI_OS) + p_ramrod->outer_tag_config.enable_stag_pri_change = 1; + else + p_ramrod->outer_tag_config.enable_stag_pri_change = 0; + p_ramrod->outer_tag_config.pri_map_valid = 1; + for (i = 0; i < 8; i++) + p_ramrod->outer_tag_config.inner_to_outer_pri_map[i] = + (u8)i; } - p_ramrod->outer_tag_config.outer_tag.tpid = p_hwfn->hw_info.ovlan; /* Place EQ address in RAMROD */ DMA_REGPAIR_LE(p_ramrod->event_ring_pbl_addr, @@ -360,7 +368,8 @@ enum _ecore_status_t ecore_sp_pf_start(struct ecore_hwfn *p_hwfn, ecore_tunn_set_pf_start_params(p_hwfn, p_tunn, &p_ramrod->tunnel_config); - if (IS_MF_SI(p_hwfn)) + if (OSAL_TEST_BIT(ECORE_MF_INTER_PF_SWITCH, + &p_hwfn->p_dev->mf_bits)) p_ramrod->allow_npar_tx_switching = allow_npar_tx_switch; switch (p_hwfn->hw_info.personality) { @@ -386,8 +395,9 @@ enum _ecore_status_t ecore_sp_pf_start(struct ecore_hwfn *p_hwfn, p_ramrod->hsi_fp_ver.minor_ver_arr[ETH_VER_KEY] = ETH_HSI_VER_MINOR; DP_VERBOSE(p_hwfn, ECORE_MSG_SPQ, - "Setting event_ring_sb [id %04x index %02x], outer_tag [%d]\n", - sb, sb_index, p_ramrod->outer_tag_config.outer_tag.tpid); + "Setting event_ring_sb [id %04x index %02x], outer_tag.tpid [%d], outer_tag.tci [%d]\n", + sb, sb_index, p_ramrod->outer_tag_config.outer_tag.tpid, + p_ramrod->outer_tag_config.outer_tag.tci); rc = ecore_spq_post(p_hwfn, p_ent, OSAL_NULL); @@ -422,6 +432,34 @@ enum _ecore_status_t ecore_sp_pf_update_dcbx(struct ecore_hwfn *p_hwfn) return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL); } +enum _ecore_status_t ecore_sp_pf_update_ufp(struct ecore_hwfn *p_hwfn) +{ + struct ecore_spq_entry *p_ent = OSAL_NULL; + struct ecore_sp_init_data init_data; + enum _ecore_status_t rc = ECORE_NOTIMPL; + + /* Get SPQ entry */ + OSAL_MEMSET(&init_data, 0, sizeof(init_data)); + init_data.cid = ecore_spq_get_cid(p_hwfn); + init_data.opaque_fid = p_hwfn->hw_info.opaque_fid; + init_data.comp_mode = ECORE_SPQ_MODE_CB; + + rc = ecore_sp_init_request(p_hwfn, &p_ent, + COMMON_RAMROD_PF_UPDATE, PROTOCOLID_COMMON, + &init_data); + if (rc != ECORE_SUCCESS) + return rc; + + p_ent->ramrod.pf_update.update_enable_stag_pri_change = true; + if (p_hwfn->ufp_info.pri_type == ECORE_UFP_PRI_OS) + p_ent->ramrod.pf_update.enable_stag_pri_change = 1; + else + p_ent->ramrod.pf_update.enable_stag_pri_change = 0; + + return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL); +} + + /* QM rate limiter resolution is 1.6Mbps */ #define QM_RL_RESOLUTION(mb_val) ((mb_val) * 10 / 16) diff --git a/drivers/net/qede/base/ecore_sp_commands.h b/drivers/net/qede/base/ecore_sp_commands.h index 74f6a3475b..98009c6547 100644 --- a/drivers/net/qede/base/ecore_sp_commands.h +++ b/drivers/net/qede/base/ecore_sp_commands.h @@ -61,7 +61,6 @@ enum _ecore_status_t ecore_sp_init_request(struct ecore_hwfn *p_hwfn, * @param p_hwfn * @param p_ptt * @param p_tunn - pf start tunneling configuration - * @param mode * @param allow_npar_tx_switch - npar tx switching to be used * for vports configured for tx-switching. * @@ -71,7 +70,6 @@ enum _ecore_status_t ecore_sp_init_request(struct ecore_hwfn *p_hwfn, enum _ecore_status_t ecore_sp_pf_start(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, struct ecore_tunnel_info *p_tunn, - enum ecore_mf_mode mode, bool allow_npar_tx_switch); /** @@ -155,4 +153,13 @@ enum _ecore_status_t ecore_sp_rl_update(struct ecore_hwfn *p_hwfn, enum _ecore_status_t ecore_sp_pf_update_stag(struct ecore_hwfn *p_hwfn); +/** + * @brief ecore_sp_pf_update_ufp - PF ufp update Ramrod + * + * @param p_hwfn + * + * @return enum _ecore_status_t + */ +enum _ecore_status_t ecore_sp_pf_update_ufp(struct ecore_hwfn *p_hwfn); + #endif /*__ECORE_SP_COMMANDS_H__*/ diff --git a/drivers/net/qede/base/mcp_public.h b/drivers/net/qede/base/mcp_public.h index 7ac28202c0..5153f2595b 100644 --- a/drivers/net/qede/base/mcp_public.h +++ b/drivers/net/qede/base/mcp_public.h @@ -814,6 +814,17 @@ struct public_port { #define ETH_TRANSCEIVER_HAS_DIAGNOSTIC (1 << 6) #define ETH_TRANSCEIVER_IDENT_MASK 0x0000ff00 #define ETH_TRANSCEIVER_IDENT_OFFSET 8 + + u32 oem_cfg_port; +#define OEM_CFG_CHANNEL_TYPE_MASK 0x00000003 +#define OEM_CFG_CHANNEL_TYPE_OFFSET 0 +#define OEM_CFG_CHANNEL_TYPE_VLAN_PARTITION 0x1 +#define OEM_CFG_CHANNEL_TYPE_STAGGED 0x2 + +#define OEM_CFG_SCHED_TYPE_MASK 0x0000000C +#define OEM_CFG_SCHED_TYPE_OFFSET 2 +#define OEM_CFG_SCHED_TYPE_ETS 0x1 +#define OEM_CFG_SCHED_TYPE_VNIC_BW 0x2 }; /**************************************/ @@ -930,6 +941,23 @@ struct public_func { #define DRV_ID_DRV_INIT_HW_MASK 0x80000000 #define DRV_ID_DRV_INIT_HW_OFFSET 31 #define DRV_ID_DRV_INIT_HW_FLAG (1 << DRV_ID_DRV_INIT_HW_OFFSET) + + u32 oem_cfg_func; +#define OEM_CFG_FUNC_TC_MASK 0x0000000F +#define OEM_CFG_FUNC_TC_OFFSET 0 +#define OEM_CFG_FUNC_TC_0 0x0 +#define OEM_CFG_FUNC_TC_1 0x1 +#define OEM_CFG_FUNC_TC_2 0x2 +#define OEM_CFG_FUNC_TC_3 0x3 +#define OEM_CFG_FUNC_TC_4 0x4 +#define OEM_CFG_FUNC_TC_5 0x5 +#define OEM_CFG_FUNC_TC_6 0x6 +#define OEM_CFG_FUNC_TC_7 0x7 + +#define OEM_CFG_FUNC_HOST_PRI_CTRL_MASK 0x00000030 +#define OEM_CFG_FUNC_HOST_PRI_CTRL_OFFSET 4 +#define OEM_CFG_FUNC_HOST_PRI_CTRL_VNIC 0x1 +#define OEM_CFG_FUNC_HOST_PRI_CTRL_OS 0x2 }; /**************************************/ @@ -1735,6 +1763,8 @@ enum MFW_DRV_MSG_TYPE { MFW_DRV_MSG_TRANSCEIVER_STATE_CHANGE, MFW_DRV_MSG_CRITICAL_ERROR_OCCURRED, MFW_DRV_MSG_EEE_NEGOTIATION_COMPLETE, + MFW_DRV_MSG_GET_TLV_REQ, + MFW_DRV_MSG_OEM_CFG_UPDATE, MFW_DRV_MSG_MAX }; diff --git a/drivers/net/qede/qede_if.h b/drivers/net/qede/qede_if.h index 02af2eed77..1f97b59cff 100644 --- a/drivers/net/qede/qede_if.h +++ b/drivers/net/qede/qede_if.h @@ -40,7 +40,7 @@ struct qed_dev_info { #define QED_MFW_VERSION_3_OFFSET 24 uint32_t flash_size; - uint8_t mf_mode; + bool b_inter_pf_switch; bool tx_switching; u16 mtu; diff --git a/drivers/net/qede/qede_main.c b/drivers/net/qede/qede_main.c index 48dd3b1fe6..2f6a4dc72c 100644 --- a/drivers/net/qede/qede_main.c +++ b/drivers/net/qede/qede_main.c @@ -376,7 +376,8 @@ qed_fill_dev_info(struct ecore_dev *edev, struct qed_dev_info *dev_info) dev_info->fw_eng = FW_ENGINEERING_VERSION; if (IS_PF(edev)) { - dev_info->mf_mode = edev->mf_mode; + dev_info->b_inter_pf_switch = + OSAL_TEST_BIT(ECORE_MF_INTER_PF_SWITCH, &edev->mf_bits); dev_info->tx_switching = false; dev_info->smart_an = ecore_mcp_is_smart_an_supported(p_hwfn); -- 2.20.1