if (p_hwfn->mcp_info) {
struct ecore_mcp_cmd_elem *p_cmd_elem = OSAL_NULL, *p_tmp;
+ OSAL_FREE(p_hwfn->p_dev, p_hwfn->mcp_info->mfw_mb_cur);
+ OSAL_FREE(p_hwfn->p_dev, p_hwfn->mcp_info->mfw_mb_shadow);
+
OSAL_SPIN_LOCK(&p_hwfn->mcp_info->cmd_lock);
OSAL_LIST_FOR_EACH_ENTRY_SAFE(p_cmd_elem, p_tmp,
&p_hwfn->mcp_info->cmd_list, list,
}
OSAL_SPIN_UNLOCK(&p_hwfn->mcp_info->cmd_lock);
- OSAL_FREE(p_hwfn->p_dev, p_hwfn->mcp_info->mfw_mb_cur);
- OSAL_FREE(p_hwfn->p_dev, p_hwfn->mcp_info->mfw_mb_shadow);
#ifdef CONFIG_ECORE_LOCK_ALLOC
OSAL_SPIN_LOCK_DEALLOC(&p_hwfn->mcp_info->cmd_lock);
OSAL_SPIN_LOCK_DEALLOC(&p_hwfn->mcp_info->link_lock);
goto err;
p_info = p_hwfn->mcp_info;
+ /* Initialize the MFW spinlocks */
+#ifdef CONFIG_ECORE_LOCK_ALLOC
+ OSAL_SPIN_LOCK_ALLOC(p_hwfn, &p_info->cmd_lock);
+ OSAL_SPIN_LOCK_ALLOC(p_hwfn, &p_info->link_lock);
+#endif
+ OSAL_SPIN_LOCK_INIT(&p_info->cmd_lock);
+ OSAL_SPIN_LOCK_INIT(&p_info->link_lock);
+
+ OSAL_LIST_INIT(&p_info->cmd_list);
+
if (ecore_load_mcp_offsets(p_hwfn, p_ptt) != ECORE_SUCCESS) {
DP_NOTICE(p_hwfn, false, "MCP is not initialized\n");
/* Do not free mcp_info here, since public_base indicate that
if (!p_info->mfw_mb_shadow || !p_info->mfw_mb_addr)
goto err;
- /* Initialize the MFW spinlocks */
-#ifdef CONFIG_ECORE_LOCK_ALLOC
- OSAL_SPIN_LOCK_ALLOC(p_hwfn, &p_info->cmd_lock);
- OSAL_SPIN_LOCK_ALLOC(p_hwfn, &p_info->link_lock);
-#endif
- OSAL_SPIN_LOCK_INIT(&p_info->cmd_lock);
- OSAL_SPIN_LOCK_INIT(&p_info->link_lock);
-
- OSAL_LIST_INIT(&p_info->cmd_list);
-
return ECORE_SUCCESS;
err:
block_cmd ? "Block" : "Unblock");
}
+void ecore_mcp_print_cpu_info(struct ecore_hwfn *p_hwfn,
+ struct ecore_ptt *p_ptt)
+{
+ u32 cpu_mode, cpu_state, cpu_pc_0, cpu_pc_1, cpu_pc_2;
+
+ cpu_mode = ecore_rd(p_hwfn, p_ptt, MCP_REG_CPU_MODE);
+ cpu_state = ecore_rd(p_hwfn, p_ptt, MCP_REG_CPU_STATE);
+ cpu_pc_0 = ecore_rd(p_hwfn, p_ptt, MCP_REG_CPU_PROGRAM_COUNTER);
+ OSAL_UDELAY(CHIP_MCP_RESP_ITER_US);
+ cpu_pc_1 = ecore_rd(p_hwfn, p_ptt, MCP_REG_CPU_PROGRAM_COUNTER);
+ OSAL_UDELAY(CHIP_MCP_RESP_ITER_US);
+ cpu_pc_2 = ecore_rd(p_hwfn, p_ptt, MCP_REG_CPU_PROGRAM_COUNTER);
+
+ DP_NOTICE(p_hwfn, false,
+ "MCP CPU info: mode 0x%08x, state 0x%08x, pc {0x%08x, 0x%08x, 0x%08x}\n",
+ cpu_mode, cpu_state, cpu_pc_0, cpu_pc_1, cpu_pc_2);
+}
+
static enum _ecore_status_t
_ecore_mcp_cmd_and_union(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
struct ecore_mcp_mb_params *p_mb_params,
OSAL_SPIN_UNLOCK(&p_hwfn->mcp_info->cmd_lock);
OSAL_UDELAY(delay);
+ OSAL_MFW_CMD_PREEMPT(p_hwfn);
} while (++cnt < max_retries);
if (cnt >= max_retries) {
goto err;
OSAL_SPIN_UNLOCK(&p_hwfn->mcp_info->cmd_lock);
+ OSAL_MFW_CMD_PREEMPT(p_hwfn);
} while (++cnt < max_retries);
if (cnt >= max_retries) {
DP_NOTICE(p_hwfn, false,
"The MFW failed to respond to command 0x%08x [param 0x%08x].\n",
p_mb_params->cmd, p_mb_params->param);
+ ecore_mcp_print_cpu_info(p_hwfn, p_ptt);
OSAL_SPIN_LOCK(&p_hwfn->mcp_info->cmd_lock);
ecore_mcp_cmd_del_elem(p_hwfn, p_cmd_elem);
return rc;
}
-#define FW_MB_PARAM_LOAD_DONE_DID_EFUSE_ERROR (1 << 0)
-
/* Check if there is a DID mismatch between nvm-cfg/efuse */
if (param & FW_MB_PARAM_LOAD_DONE_DID_EFUSE_ERROR)
DP_NOTICE(p_hwfn, false,
DP_NOTICE(p_hwfn, false, "Transceiver is present.\n");
else
DP_NOTICE(p_hwfn, false, "Transceiver is unplugged.\n");
+
+ OSAL_TRANSCEIVER_UPDATE(p_hwfn);
}
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)
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)) {
__ecore_configure_pf_max_bandwidth(p_hwfn, p_ptt,
p_link, max_bw);
- /* Mintz bandwidth configuration */
+ /* Min bandwidth configuration */
__ecore_configure_pf_min_bandwidth(p_hwfn, p_ptt,
p_link, min_bw);
ecore_configure_vp_wfq_on_link_change(p_hwfn->p_dev, p_ptt,
if (p_hwfn->mcp_info->capabilities & FW_MB_PARAM_FEATURE_SUPPORT_EEE)
ecore_mcp_read_eee_config(p_hwfn, p_ptt, p_link);
- OSAL_LINK_UPDATE(p_hwfn, p_ptt);
+ OSAL_LINK_UPDATE(p_hwfn);
out:
OSAL_SPIN_UNLOCK(&p_hwfn->mcp_info->link_lock);
}
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;
}
}
}
-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)
{
case MFW_DRV_MSG_DCBX_OPERATIONAL_MIB_UPDATED:
ecore_dcbx_mib_update_event(p_hwfn, p_ptt,
ECORE_DCBX_OPERATIONAL_MIB);
+ /* clear the user-config cache */
+ OSAL_MEMSET(&p_hwfn->p_dcbx_info->set, 0,
+ sizeof(struct ecore_dcbx_set));
+ break;
+ case MFW_DRV_MSG_LLDP_RECEIVED_TLVS_UPDATED:
+ ecore_lldp_mib_update_event(p_hwfn, p_ptt);
break;
case MFW_DRV_MSG_OEM_CFG_UPDATE:
ecore_mcp_handle_ufp_event(p_hwfn, p_ptt);
struct ecore_ptt *p_ptt,
enum ecore_ov_client client)
{
- enum _ecore_status_t rc;
u32 resp = 0, param = 0;
u32 drv_mb_param;
+ enum _ecore_status_t rc;
switch (client) {
case ECORE_OV_CLIENT_DRV:
struct ecore_ptt *p_ptt,
enum ecore_ov_driver_state drv_state)
{
- enum _ecore_status_t rc;
u32 resp = 0, param = 0;
u32 drv_mb_param;
+ enum _ecore_status_t rc;
switch (drv_state) {
case ECORE_OV_DRIVER_STATE_NOT_LOADED:
DRV_MSG_CODE_TRANSCEIVER_READ,
nvm_offset, &resp, ¶m, &buf_size,
(u32 *)(p_buf + offset));
- if ((resp & FW_MSG_CODE_MASK) ==
- FW_MSG_CODE_TRANSCEIVER_NOT_PRESENT) {
+ if (rc != ECORE_SUCCESS) {
+ DP_NOTICE(p_hwfn, false,
+ "Failed to send a transceiver read command to the MFW. rc = %d.\n",
+ rc);
+ return rc;
+ }
+
+ if (resp == FW_MSG_CODE_TRANSCEIVER_NOT_PRESENT)
return ECORE_NODEV;
- } else if ((resp & FW_MSG_CODE_MASK) !=
- FW_MSG_CODE_TRANSCEIVER_DIAG_OK)
+ else if (resp != FW_MSG_CODE_TRANSCEIVER_DIAG_OK)
return ECORE_UNKNOWN_ERROR;
offset += buf_size;
DRV_MSG_CODE_TRANSCEIVER_WRITE,
nvm_offset, &resp, ¶m, buf_size,
(u32 *)&p_buf[buf_idx]);
- if ((resp & FW_MSG_CODE_MASK) ==
- FW_MSG_CODE_TRANSCEIVER_NOT_PRESENT) {
+ if (rc != ECORE_SUCCESS) {
+ DP_NOTICE(p_hwfn, false,
+ "Failed to send a transceiver write command to the MFW. rc = %d.\n",
+ rc);
+ return rc;
+ }
+
+ if (resp == FW_MSG_CODE_TRANSCEIVER_NOT_PRESENT)
return ECORE_NODEV;
- } else if ((resp & FW_MSG_CODE_MASK) !=
- FW_MSG_CODE_TRANSCEIVER_DIAG_OK)
+ else if (resp != FW_MSG_CODE_TRANSCEIVER_DIAG_OK)
return ECORE_UNKNOWN_ERROR;
buf_idx += buf_size;
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);
return ECORE_SUCCESS;
}
+
+void ecore_mcp_wol_wr(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
+ u32 offset, u32 val)
+{
+ struct ecore_mcp_mb_params mb_params = {0};
+ enum _ecore_status_t rc = ECORE_SUCCESS;
+ u32 dword = val;
+
+ mb_params.cmd = DRV_MSG_CODE_WRITE_WOL_REG;
+ mb_params.param = offset;
+ mb_params.p_data_src = &dword;
+ mb_params.data_src_size = sizeof(dword);
+
+ rc = ecore_mcp_cmd_and_union(p_hwfn, p_ptt, &mb_params);
+ if (rc != ECORE_SUCCESS) {
+ DP_NOTICE(p_hwfn, false,
+ "Failed to wol write request, rc = %d\n", rc);
+ }
+
+ if (mb_params.mcp_resp != FW_MSG_CODE_WOL_READ_WRITE_OK) {
+ DP_NOTICE(p_hwfn, false,
+ "Failed to write value 0x%x to offset 0x%x [mcp_resp 0x%x]\n",
+ val, offset, mb_params.mcp_resp);
+ rc = ECORE_UNKNOWN_ERROR;
+ }
+}