From fe0deb21d423bb55fd660d41903e7941e10ee851 Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Mon, 18 Sep 2017 18:51:37 -0700 Subject: [PATCH] net/qede/base: add feature support for per-PF virtual link Add per-PF virtual link support. This feature adds a logical layer over the physical link to reflect the control of OEM management protocols either thru' sideband or a switch. For example, a switch could send a link-down tlv for a PF and this will put down logical link and virtual link in shared mem (SHMEM) for that PF inspite of physical link being up for that port. Signed-off-by: Rasesh Mody --- drivers/net/qede/base/ecore_mcp.c | 70 ++++++++++++++++++------------ drivers/net/qede/base/mcp_public.h | 8 +++- 2 files changed, 50 insertions(+), 28 deletions(-) diff --git a/drivers/net/qede/base/ecore_mcp.c b/drivers/net/qede/base/ecore_mcp.c index 019e092314..8a8670d11d 100644 --- a/drivers/net/qede/base/ecore_mcp.c +++ b/drivers/net/qede/base/ecore_mcp.c @@ -1220,6 +1220,28 @@ static void ecore_mcp_read_eee_config(struct ecore_hwfn *p_hwfn, p_link->eee_lp_adv_caps |= ECORE_EEE_10G_ADV; } +static u32 ecore_mcp_get_shmem_func(struct ecore_hwfn *p_hwfn, + struct ecore_ptt *p_ptt, + struct public_func *p_data, + int pfid) +{ + u32 addr = SECTION_OFFSIZE_ADDR(p_hwfn->mcp_info->public_base, + PUBLIC_FUNC); + u32 mfw_path_offsize = ecore_rd(p_hwfn, p_ptt, addr); + u32 func_addr = SECTION_ADDR(mfw_path_offsize, pfid); + u32 i, size; + + OSAL_MEM_ZERO(p_data, sizeof(*p_data)); + + size = OSAL_MIN_T(u32, sizeof(*p_data), + SECTION_SIZE(mfw_path_offsize)); + for (i = 0; i < size / sizeof(u32); i++) + ((u32 *)p_data)[i] = ecore_rd(p_hwfn, p_ptt, + func_addr + (i << 2)); + + return size; +} + static void ecore_mcp_handle_link_change(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, bool b_reset) @@ -1249,10 +1271,24 @@ static void ecore_mcp_handle_link_change(struct ecore_hwfn *p_hwfn, goto out; } - if (p_hwfn->b_drv_link_init) - p_link->link_up = !!(status & LINK_STATUS_LINK_UP); - else + if (p_hwfn->b_drv_link_init) { + /* Link indication with modern MFW arrives as per-PF + * indication. + */ + if (p_hwfn->mcp_info->capabilities & + FW_MB_PARAM_FEATURE_SUPPORT_VLINK) { + struct public_func shmem_info; + + ecore_mcp_get_shmem_func(p_hwfn, p_ptt, &shmem_info, + MCP_PF_ID(p_hwfn)); + p_link->link_up = !!(shmem_info.status & + FUNC_STATUS_VIRTUAL_LINK_UP); + } else { + p_link->link_up = !!(status & LINK_STATUS_LINK_UP); + } + } else { p_link->link_up = false; + } p_link->full_duplex = true; switch ((status & LINK_STATUS_SPEED_AND_DUPLEX_MASK)) { @@ -1515,7 +1551,8 @@ static void ecore_mcp_send_protocol_stats(struct ecore_hwfn *p_hwfn, hsi_param = DRV_MSG_CODE_STATS_TYPE_LAN; break; default: - DP_INFO(p_hwfn, "Invalid protocol type %d\n", type); + DP_VERBOSE(p_hwfn, ECORE_MSG_SP, + "Invalid protocol type %d\n", type); return; } @@ -1565,28 +1602,6 @@ static void ecore_read_pf_bandwidth(struct ecore_hwfn *p_hwfn, } } -static u32 ecore_mcp_get_shmem_func(struct ecore_hwfn *p_hwfn, - struct ecore_ptt *p_ptt, - struct public_func *p_data, - int pfid) -{ - u32 addr = SECTION_OFFSIZE_ADDR(p_hwfn->mcp_info->public_base, - PUBLIC_FUNC); - u32 mfw_path_offsize = ecore_rd(p_hwfn, p_ptt, addr); - u32 func_addr = SECTION_ADDR(mfw_path_offsize, pfid); - u32 i, size; - - OSAL_MEM_ZERO(p_data, sizeof(*p_data)); - - size = OSAL_MIN_T(u32, sizeof(*p_data), - SECTION_SIZE(mfw_path_offsize)); - for (i = 0; i < size / sizeof(u32); i++) - ((u32 *)p_data)[i] = ecore_rd(p_hwfn, p_ptt, - func_addr + (i << 2)); - - return size; -} - static void ecore_mcp_update_bw(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt) { @@ -3667,7 +3682,8 @@ enum _ecore_status_t ecore_mcp_set_capabilities(struct ecore_hwfn *p_hwfn, u32 mcp_resp, mcp_param, features; features = DRV_MB_PARAM_FEATURE_SUPPORT_PORT_SMARTLINQ | - DRV_MB_PARAM_FEATURE_SUPPORT_PORT_EEE; + DRV_MB_PARAM_FEATURE_SUPPORT_PORT_EEE | + DRV_MB_PARAM_FEATURE_SUPPORT_FUNC_VLINK; return ecore_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_FEATURE_SUPPORT, features, &mcp_resp, &mcp_param); diff --git a/drivers/net/qede/base/mcp_public.h b/drivers/net/qede/base/mcp_public.h index 8b0c22069a..d568179b3a 100644 --- a/drivers/net/qede/base/mcp_public.h +++ b/drivers/net/qede/base/mcp_public.h @@ -896,7 +896,9 @@ struct public_func { #define FUNC_MF_CFG_MAX_BW_DEFAULT 0x00640000 u32 status; -#define FUNC_STATUS_VLINK_DOWN 0x00000001 +#define FUNC_STATUS_VIRTUAL_LINK_UP 0x00000001 +#define FUNC_STATUS_LOGICAL_LINK_UP 0x00000002 +#define FUNC_STATUS_FORCED_LINK 0x00000004 u32 mac_upper; /* MAC */ #define FUNC_MF_CFG_UPPERMAC_MASK 0x0000ffff @@ -1594,6 +1596,8 @@ struct public_drv_mb { #define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_EEE 0x00000002 #define DRV_MB_PARAM_FEATURE_SUPPORT_FUNC_MASK 0xFFFF0000 #define DRV_MB_PARAM_FEATURE_SUPPORT_FUNC_OFFSET 16 +/* driver supports virtual link parameter */ +#define DRV_MB_PARAM_FEATURE_SUPPORT_FUNC_VLINK 0x00010000 /* Driver attributes params */ #define DRV_MB_PARAM_ATTRIBUTE_KEY_OFFSET 0 #define DRV_MB_PARAM_ATTRIBUTE_KEY_MASK 0x00FFFFFF @@ -1727,6 +1731,8 @@ struct public_drv_mb { #define FW_MB_PARAM_FEATURE_SUPPORT_SMARTLINQ 0x00000001 /* MFW supports EEE */ #define FW_MB_PARAM_FEATURE_SUPPORT_EEE 0x00000002 +/* MFW supports virtual link */ +#define FW_MB_PARAM_FEATURE_SUPPORT_VLINK 0x00010000 #define FW_MB_PARAM_LOAD_DONE_DID_EFUSE_ERROR (1 << 0)