/****************************************************************************** * * Copyright(c) 2019 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * ******************************************************************************/ #include "ser.h" static void dump_err_status_dispatcher(struct mac_ax_adapter *adapter); static void dump_err_status_dmac(struct mac_ax_adapter *adapter); static void dump_err_status_cmac(struct mac_ax_adapter *adapter, u8 band); u32 mac_trigger_cmac_err(struct mac_ax_adapter *adapter) { struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter); u8 val8; u16 val16; u32 ret; ret = check_mac_en(adapter, MAC_AX_BAND_0, MAC_AX_CMAC_SEL); if (ret != MACSUCCESS) return ret; val8 = MAC_REG_R8(R_AX_CMAC_FUNC_EN); MAC_REG_W8(R_AX_CMAC_FUNC_EN, val8 & (~B_AX_TMAC_EN)); PLTFM_DELAY_MS(1); MAC_REG_W8(R_AX_CMAC_FUNC_EN, val8); val16 = MAC_REG_R16(R_AX_PTCL_IMR0) | B_AX_F2PCMD_EMPTY_ERR_INT_EN; MAC_REG_W16(R_AX_PTCL_IMR0, val16); MAC_REG_W16(R_AX_PTCL_IMR0, val16 & ~B_AX_F2PCMD_EMPTY_ERR_INT_EN); return MACSUCCESS; } u32 mac_trigger_cmac1_err(struct mac_ax_adapter *adapter) { struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter); u8 val8; u16 val16; u32 ret; ret = check_mac_en(adapter, MAC_AX_BAND_1, MAC_AX_CMAC_SEL); if (ret != MACSUCCESS) return ret; val8 = MAC_REG_R8(R_AX_CMAC_FUNC_EN_C1); MAC_REG_W8(R_AX_CMAC_FUNC_EN_C1, val8 & (~B_AX_TMAC_EN)); PLTFM_DELAY_MS(1); MAC_REG_W8(R_AX_CMAC_FUNC_EN_C1, val8); val16 = MAC_REG_R16(R_AX_PTCL_IMR0_C1) | B_AX_F2PCMD_EMPTY_ERR_INT_EN; MAC_REG_W16(R_AX_PTCL_IMR0_C1, val16); MAC_REG_W16(R_AX_PTCL_IMR0_C1, val16 & ~B_AX_F2PCMD_EMPTY_ERR_INT_EN); return MACSUCCESS; } u32 mac_trigger_dmac_err(struct mac_ax_adapter *adapter) { struct cpuio_buf_req_t buf_req; struct cpuio_ctrl_t ctrl_para; u32 ret; // Use CPUIO to enqueue packet. //WD buf_req.len = 0x20; ret = mac_dle_buf_req_wd(adapter, &buf_req); if (ret != MACSUCCESS) { PLTFM_MSG_ERR("[ERR]WDE DLE buf req\n"); return ret; } // Enqueue two pkt_id, but only has one pkt_id. PLTFM_MEMSET((void *)&ctrl_para, 0, sizeof(ctrl_para)); ctrl_para.cmd_type = CPUIO_OP_CMD_ENQ_TO_HEAD; ctrl_para.start_pktid = buf_req.pktid; ctrl_para.end_pktid = buf_req.pktid; ctrl_para.pkt_num = 1; ctrl_para.dst_pid = WDE_DLE_PORT_ID_WDRLS; ctrl_para.dst_qid = 4; ret = mac_set_cpuio_wd(adapter, &ctrl_para); if (ret != MACSUCCESS) { PLTFM_MSG_ERR("[ERR]WDE DLE enqueue to head\n"); return ret; } return MACSUCCESS; } u32 mac_dump_err_status(struct mac_ax_adapter *adapter, enum mac_ax_err_info err) { struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter); PLTFM_MSG_ERR("--->\n err=0x%x\n", err); if (err == MAC_AX_ERR_L1_ERR_DMAC || err == MAC_AX_ERR_L0_PROMOTE_TO_L1 || err == MAC_AX_ERR_L0_ERR_CMAC0 || err == MAC_AX_ERR_L0_ERR_CMAC1) { PLTFM_MSG_ERR("R_AX_SER_DBG_INFO =0x%08x\n", MAC_REG_R32(R_AX_SER_DBG_INFO)); dump_err_status_dmac(adapter); dump_err_status_cmac(adapter, MAC_AX_BAND_0); dump_err_status_cmac(adapter, MAC_AX_BAND_1); if (adapter->hw_info->intf == MAC_AX_INTF_PCIE) { PLTFM_MSG_ERR("R_AX_DBG_ERR_FLAG=0x%08x\n", MAC_REG_R32(R_AX_DBG_ERR_FLAG)); PLTFM_MSG_ERR("R_AX_LBC_WATCHDOG=0x%08x\n", MAC_REG_R32(R_AX_LBC_WATCHDOG)); } } PLTFM_MSG_ERR("<---\n"); return MACSUCCESS; } u32 mac_set_err_status(struct mac_ax_adapter *adapter, enum mac_ax_err_info err) { struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter); u32 cnt = MAC_SET_ERR_DLY_CNT; u32 ret = MACSUCCESS; if (err > MAC_AX_SET_ERR_MAX) { PLTFM_MSG_ERR("Bad set-err-status value\n"); return MACFUNCINPUT; } PLTFM_MUTEX_LOCK(&adapter->hw_info->err_set_lock); while (--cnt) { if (!MAC_REG_R32(R_AX_HALT_H2C_CTRL)) break; PLTFM_DELAY_US(MAC_SET_ERR_DLY_US); } if (!cnt) { PLTFM_MSG_ERR("FW does not receive previous msg\n"); ret = MACPOLLTO; goto end; } if (err == MAC_AX_ERR_L1_DISABLE_EN) adapter->sm.fw_rst = MAC_AX_FW_RESET_RECV_DONE; MAC_REG_W32(R_AX_HALT_H2C, err); MAC_REG_W32(R_AX_HALT_H2C_CTRL, B_AX_HALT_H2C_TRIGGER); end: PLTFM_MUTEX_UNLOCK(&adapter->hw_info->err_set_lock); return ret; } u32 mac_get_err_status(struct mac_ax_adapter *adapter, enum mac_ax_err_info *err) { struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter); u32 cnt = MAC_SET_ERR_DLY_CNT; u32 ret = MACSUCCESS; u32 error_senario = 0; PLTFM_MUTEX_LOCK(&adapter->hw_info->err_get_lock); adapter->sm.l2_st = MAC_AX_L2_DIS; while (--cnt) { if (MAC_REG_R32(R_AX_HALT_C2H_CTRL)) break; PLTFM_DELAY_US(MAC_SET_ERR_DLY_US); } if (!cnt) { PLTFM_MSG_ERR("Polling FW err status fail\n"); ret = MACPOLLTO; goto end; } *err = (enum mac_ax_err_info)MAC_REG_R32(R_AX_HALT_C2H); MAC_REG_W32(R_AX_HALT_C2H_CTRL, 0); switch (*err) { case MAC_AX_ERR_L1_ERR_DMAC: case MAC_AX_ERR_L0_PROMOTE_TO_L1: adapter->sm.fw_rst = MAC_AX_FW_RESET_RECV; break; case MAC_AX_ERR_L1_RESET_DISABLE_DMAC_DONE: adapter->sm.fw_rst = MAC_AX_FW_RESET_PROCESS; break; case MAC_AX_ERR_L1_RESET_RECOVERY_DONE: adapter->sm.fw_rst = MAC_AX_FW_RESET_IDLE; break; default: break; } /* Decode the error status from halc2h */ error_senario = (*err) >> DBG_SENARIO_SH; if (!(MAC_REG_R32(R_AX_UDM0) & (1 << B_AX_UDM0_DBG_MODE_SH))) { if (error_senario == CPU_EXCEPTION) *err = MAC_AX_ERR_CPU_EXCEPTION; else if (error_senario == ASSERTION) *err = MAC_AX_ERR_ASSERTION; } //3 3. Execute Recode Normal Debug Register if (*err == MAC_AX_ERR_L0_ERR_CMAC0 || *err == MAC_AX_ERR_L0_ERR_CMAC1) { pltfm_dbg_dump(adapter); } fw_st_dbg_dump(adapter); mac_dump_err_status(adapter, *err); if (*err == MAC_AX_ERR_L0_ERR_CMAC0 || *err == MAC_AX_ERR_L0_ERR_CMAC1) { pltfm_dbg_dump(adapter); } //3 4. Execute Recode Share memory debug information if (MAC_REG_R32(R_AX_UDM0) & (1 << B_AX_UDM0_DBG_MODE_SH)) { /* if debug mode =1 , dump share buffer */ if (error_senario) { *err = (enum mac_ax_err_info)MAC_AX_DUMP_SHAREBUFF_INDICATOR; //notify phl to print share buffer } } end: adapter->sm.l2_st = MAC_AX_L2_EN; PLTFM_MUTEX_UNLOCK(&adapter->hw_info->err_get_lock); return ret; } u32 mac_lv1_rcvy(struct mac_ax_adapter *adapter, enum mac_ax_lv1_rcvy_step step) { u32 ret = MACSUCCESS; #if MAC_AX_PCIE_SUPPORT u8 val8; #endif switch (step) { case MAC_AX_LV1_RCVY_STEP_1: if (adapter->sm.fw_rst != MAC_AX_FW_RESET_RECV) { PLTFM_MSG_ERR("The rst-flow state is wrong\n"); return MACPROCERR; } #if MAC_AX_PCIE_SUPPORT if (adapter->hw_info->intf == MAC_AX_INTF_PCIE) { val8 = 0; ret = lv1rst_stop_dma_pcie(adapter, val8); if (ret) { PLTFM_MSG_ERR("lv1 rcvy pcie stop dma fail\n"); return ret; } } #endif #if MAC_AX_USB_SUPPORT if (adapter->hw_info->intf == MAC_AX_INTF_USB) { ret = usb_flush_mode(adapter, MAC_AX_FUNC_EN); if (ret) { PLTFM_MSG_ERR("lv1 rcvy USB flush mode fail\n"); return ret; } PLTFM_DELAY_MS(30); } #endif break; case MAC_AX_LV1_RCVY_STEP_2: if (adapter->sm.fw_rst != MAC_AX_FW_RESET_PROCESS) { PLTFM_MSG_ERR("The rst-flow state is wrong\n"); return MACPROCERR; } #if MAC_AX_PCIE_SUPPORT if (adapter->hw_info->intf == MAC_AX_INTF_PCIE) { val8 = 0; ret = lv1rst_start_dma_pcie(adapter, val8); if (ret) { PLTFM_MSG_ERR("lv1 rcvy pcie start dma fail\n"); return ret; } } #endif #if MAC_AX_USB_SUPPORT if (adapter->hw_info->intf == MAC_AX_INTF_USB) { ret = 0; ret = usb_flush_mode(adapter, MAC_AX_FUNC_DIS); if (ret) { PLTFM_MSG_ERR("lv1 rcvy USB norm mode fail\n"); return ret; } } #endif break; default: return MACLV1STEPERR; } return ret; } u32 mac_err_imr_ctrl(struct mac_ax_adapter *adapter, enum mac_ax_func_sw sw) { struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter); u32 v32_dmac, v32_cmac0, v32_cmac1; u32 ret = MACSUCCESS; u8 is_dbcc; v32_dmac = sw != MAC_AX_FUNC_DIS ? DMAC_ERR_IMR_EN : DMAC_ERR_IMR_DIS; v32_cmac0 = sw != MAC_AX_FUNC_DIS ? CMAC0_ERR_IMR_EN : CMAC0_ERR_IMR_DIS; v32_cmac1 = sw != MAC_AX_FUNC_DIS ? CMAC1_ERR_IMR_EN : CMAC1_ERR_IMR_DIS; is_dbcc = is_curr_dbcc(adapter); #if MAC_AX_FW_REG_OFLD if (adapter->sm.fwdl == MAC_AX_FWDL_INIT_RDY) { ret = MAC_REG_W_OFLD((u16)R_AX_DMAC_ERR_IMR, DMAC_ERR_IMR_MASK, v32_dmac, 0); if (ret != MACSUCCESS) { PLTFM_MSG_ERR("dmac err imr w ofld fail\n"); return ret; } ret = MAC_REG_W_OFLD((u16)R_AX_CMAC_ERR_IMR, CMAC0_ERR_IMR_MASK, v32_cmac0, (is_dbcc ? 0 : 1)); if (ret != MACSUCCESS) { PLTFM_MSG_ERR("cmac0 err imr w ofld fail\n"); return ret; } if (is_dbcc) { ret = MAC_REG_W_OFLD((u16)R_AX_CMAC_ERR_IMR_C1, CMAC1_ERR_IMR_MASK, v32_cmac1, 1); if (ret != MACSUCCESS) { PLTFM_MSG_ERR("cmac1 err imr w ofld fail\n"); return ret; } } return ret; } #endif MAC_REG_W32(R_AX_DMAC_ERR_IMR, v32_dmac); MAC_REG_W32(R_AX_CMAC_ERR_IMR, v32_cmac0); if (is_dbcc) MAC_REG_W32(R_AX_CMAC_ERR_IMR_C1, v32_cmac1); return ret; } static void dump_err_status_dispatcher(struct mac_ax_adapter *adapter) { struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter); PLTFM_MSG_ERR("R_AX_HOST_DISPATCHER_ERR_IMR=0x%08x\n", MAC_REG_R32(R_AX_HOST_DISPATCHER_ERR_IMR)); PLTFM_MSG_ERR("R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n", MAC_REG_R32(R_AX_HOST_DISPATCHER_ERR_ISR)); PLTFM_MSG_ERR("R_AX_CPU_DISPATCHER_ERR_IMR=0x%08x\n", MAC_REG_R32(R_AX_CPU_DISPATCHER_ERR_IMR)); PLTFM_MSG_ERR("R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n", MAC_REG_R32(R_AX_CPU_DISPATCHER_ERR_ISR)); PLTFM_MSG_ERR("R_AX_OTHER_DISPATCHER_ERR_IMR=0x%08x ", MAC_REG_R32(R_AX_OTHER_DISPATCHER_ERR_IMR)); PLTFM_MSG_ERR("R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n", MAC_REG_R32(R_AX_OTHER_DISPATCHER_ERR_ISR)); } static void dump_err_status_dmac(struct mac_ax_adapter *adapter) { struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter); u32 dmac_err; dmac_err = MAC_REG_R32(R_AX_DMAC_ERR_ISR); PLTFM_MSG_ERR("R_AX_DMAC_ERR_ISR =0x%08x\n", dmac_err); PLTFM_MSG_ERR("R_AX_DMAC_FUNC_EN =0x%08x\n", MAC_REG_R32(R_AX_DMAC_FUNC_EN)); PLTFM_MSG_ERR("R_AX_DMAC_CLK_EN =0x%08x\n", MAC_REG_R32(R_AX_DMAC_CLK_EN)); if (dmac_err) { PLTFM_MSG_ERR("R_AX_WDE_ERR_FLAG_CFG =0x%08x\n", MAC_REG_R32(R_AX_WDE_ERR_FLAG_CFG)); PLTFM_MSG_ERR("R_AX_PLE_ERR_FLAG_CFG =0x%08x\n", MAC_REG_R32(R_AX_PLE_ERR_FLAG_CFG)); } if (dmac_err & B_AX_WDRLS_ERR_FLAG) { PLTFM_MSG_ERR("R_AX_WDRLS_ERR_IMR =0x%08x\n", MAC_REG_R32(R_AX_WDRLS_ERR_IMR)); PLTFM_MSG_ERR("R_AX_WDRLS_ERR_ISR =0x%08x\n", MAC_REG_R32(R_AX_WDRLS_ERR_ISR)); PLTFM_MSG_ERR("R_AX_RPQ_RXBD_IDX =0x%08x\n", MAC_REG_R32(R_AX_RPQ_RXBD_IDX)); } if (dmac_err & B_AX_WSEC_ERR_FLAG) { PLTFM_MSG_ERR("R_AX_SEC_ERR_IMR_ISR =0x%08x\n", MAC_REG_R32(R_AX_SEC_DEBUG)); PLTFM_MSG_ERR("SEC_local_Register 0x9D00 =0x%08x\n", MAC_REG_R32(R_AX_SEC_ENG_CTRL)); PLTFM_MSG_ERR("SEC_local_Register 0x9D04 =0x%08x\n", MAC_REG_R32(R_AX_SEC_MPDU_PROC)); PLTFM_MSG_ERR("SEC_local_Register 0x9D10 =0x%08x\n", MAC_REG_R32(R_AX_SEC_CAM_ACCESS)); PLTFM_MSG_ERR("SEC_local_Register 0x9D14 =0x%08x\n", MAC_REG_R32(R_AX_SEC_CAM_RDATA)); PLTFM_MSG_ERR("SEC_local_Register 0x9D18 =0x%08x\n", MAC_REG_R32(R_AX_SEC_CAM_WDATA)); PLTFM_MSG_ERR("SEC_local_Register 0x9D20 =0x%08x\n", MAC_REG_R32(R_AX_SEC_TX_DEBUG)); PLTFM_MSG_ERR("SEC_local_Register 0x9D24 =0x%08x\n", MAC_REG_R32(R_AX_SEC_RX_DEBUG)); PLTFM_MSG_ERR("SEC_local_Register 0x9D28 =0x%08x\n", MAC_REG_R32(R_AX_SEC_TRX_PKT_CNT)); PLTFM_MSG_ERR("SEC_local_Register 0x9D2C =0x%08x\n", MAC_REG_R32(R_AX_SEC_TRX_BLK_CNT)); } if (dmac_err & B_AX_MPDU_ERR_FLAG) { PLTFM_MSG_ERR("R_AX_MPDU_TX_ERR_IMR =0x%08x\n", MAC_REG_R32(R_AX_MPDU_TX_ERR_IMR)); PLTFM_MSG_ERR("R_AX_MPDU_TX_ERR_ISR =0x%08x\n", MAC_REG_R32(R_AX_MPDU_TX_ERR_ISR)); PLTFM_MSG_ERR("R_AX_MPDU_RX_ERR_IMR =0x%08x\n", MAC_REG_R32(R_AX_MPDU_RX_ERR_IMR)); PLTFM_MSG_ERR("R_AX_MPDU_RX_ERR_ISR =0x%08x\n", MAC_REG_R32(R_AX_MPDU_RX_ERR_ISR)); } if (dmac_err & B_AX_STA_SCHEDULER_ERR_FLAG) { PLTFM_MSG_ERR("R_AX_STA_SCHEDULER_ERR_IMR =0x%08x\n", MAC_REG_R32(R_AX_STA_SCHEDULER_ERR_IMR)); PLTFM_MSG_ERR("R_AX_STA_SCHEDULER_ERR_ISR= 0x%08x\n", MAC_REG_R32(R_AX_STA_SCHEDULER_ERR_ISR)); } if (dmac_err & B_AX_WDE_DLE_ERR_FLAG) { PLTFM_MSG_ERR("R_AX_WDE_ERR_IMR=0x%08x\n", MAC_REG_R32(R_AX_WDE_ERR_IMR)); PLTFM_MSG_ERR("R_AX_WDE_ERR_ISR=0x%08x\n", MAC_REG_R32(R_AX_WDE_ERR_ISR)); PLTFM_MSG_ERR("R_AX_PLE_ERR_IMR=0x%08x\n", MAC_REG_R32(R_AX_PLE_ERR_IMR)); PLTFM_MSG_ERR("R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", MAC_REG_R32(R_AX_PLE_ERR_FLAG_ISR)); } if (dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) { PLTFM_MSG_ERR("R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n", MAC_REG_R32(R_AX_TXPKTCTL_ERR_IMR_ISR)); PLTFM_MSG_ERR("R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n", MAC_REG_R32(R_AX_TXPKTCTL_ERR_IMR_ISR_B1)); } if (dmac_err & B_AX_PLE_DLE_ERR_FLAG) { PLTFM_MSG_ERR("R_AX_WDE_ERR_IMR=0x%08x\n", MAC_REG_R32(R_AX_WDE_ERR_IMR)); PLTFM_MSG_ERR("R_AX_WDE_ERR_ISR=0x%08x\n", MAC_REG_R32(R_AX_WDE_ERR_ISR)); PLTFM_MSG_ERR("R_AX_PLE_ERR_IMR=0x%08x\n", MAC_REG_R32(R_AX_PLE_ERR_IMR)); PLTFM_MSG_ERR("R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", MAC_REG_R32(R_AX_PLE_ERR_FLAG_ISR)); PLTFM_MSG_ERR("R_AX_WD_CPUQ_OP_0=0x%08x\n", MAC_REG_R32(R_AX_WD_CPUQ_OP_0)); PLTFM_MSG_ERR("R_AX_WD_CPUQ_OP_1=0x%08x\n", MAC_REG_R32(R_AX_WD_CPUQ_OP_1)); PLTFM_MSG_ERR("R_AX_WD_CPUQ_OP_2=0x%08x\n", MAC_REG_R32(R_AX_WD_CPUQ_OP_2)); PLTFM_MSG_ERR("R_AX_WD_CPUQ_OP_STATUS=0x%08x\n", MAC_REG_R32(R_AX_WD_CPUQ_OP_STATUS)); PLTFM_MSG_ERR("R_AX_PL_CPUQ_OP_0=0x%08x\n", MAC_REG_R32(R_AX_PL_CPUQ_OP_0)); PLTFM_MSG_ERR("R_AX_PL_CPUQ_OP_1=0x%08x\n", MAC_REG_R32(R_AX_PL_CPUQ_OP_1)); PLTFM_MSG_ERR("R_AX_PL_CPUQ_OP_2=0x%08x\n", MAC_REG_R32(R_AX_PL_CPUQ_OP_2)); PLTFM_MSG_ERR("R_AX_PL_CPUQ_OP_STATUS=0x%08x\n", MAC_REG_R32(R_AX_PL_CPUQ_OP_STATUS)); PLTFM_MSG_ERR("R_AX_RXDMA_PKT_INFO_0=0x%08x\n", MAC_REG_R32(R_AX_RXDMA_PKT_INFO_0)); PLTFM_MSG_ERR("R_AX_RXDMA_PKT_INFO_1=0x%08x\n", MAC_REG_R32(R_AX_RXDMA_PKT_INFO_1)); PLTFM_MSG_ERR("R_AX_RXDMA_PKT_INFO_2=0x%08x\n", MAC_REG_R32(R_AX_RXDMA_PKT_INFO_2)); dump_err_status_dispatcher(adapter); } if (dmac_err & B_AX_PKTIN_ERR_FLAG) { PLTFM_MSG_ERR("R_AX_PKTIN_ERR_IMR =0x%08x\n", MAC_REG_R32(R_AX_PKTIN_ERR_IMR)); PLTFM_MSG_ERR("R_AX_PKTIN_ERR_ISR =0x%08x\n", MAC_REG_R32(R_AX_PKTIN_ERR_ISR)); PLTFM_MSG_ERR("R_AX_PKTIN_ERR_IMR =0x%08x ", MAC_REG_R32(R_AX_PKTIN_ERR_IMR)); PLTFM_MSG_ERR("R_AX_PKTIN_ERR_ISR =0x%08x\n", MAC_REG_R32(R_AX_PKTIN_ERR_ISR)); } if (dmac_err & B_AX_DISPATCH_ERR_FLAG) dump_err_status_dispatcher(adapter); if (dmac_err & B_AX_DLE_CPUIO_ERR_FLAG) { PLTFM_MSG_ERR("R_AX_CPUIO_ERR_IMR=0x%08x\n", MAC_REG_R32(R_AX_CPUIO_ERR_IMR)); PLTFM_MSG_ERR("R_AX_CPUIO_ERR_ISR=0x%08x\n", MAC_REG_R32(R_AX_CPUIO_ERR_ISR)); } if (dmac_err & BIT(11)) { PLTFM_MSG_ERR("R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n", MAC_REG_R32(R_AX_BBRPT_COM_ERR_IMR_ISR)); } } static void dump_err_status_cmac(struct mac_ax_adapter *adapter, u8 band) { struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter); u32 cmac_err; u32 ret; ret = check_mac_en(adapter, band, MAC_AX_CMAC_SEL); if (ret != MACSUCCESS) return; PLTFM_MSG_ERR("CMAC Band =0x%02x\n", band); cmac_err = MAC_REG_R32(band == MAC_AX_BAND_0 ? R_AX_CMAC_ERR_ISR : R_AX_CMAC_ERR_ISR_C1); PLTFM_MSG_ERR("R_AX_CMAC_ERR_ISR =0x%08x\n", cmac_err); PLTFM_MSG_ERR("R_AX_CMAC_FUNC_EN =0x%08x\n", MAC_REG_R32(band == MAC_AX_BAND_0 ? R_AX_CMAC_FUNC_EN : R_AX_CMAC_FUNC_EN_C1)); PLTFM_MSG_ERR("R_AX_CK_EN =0x%08x\n", MAC_REG_R32(band == MAC_AX_BAND_0 ? R_AX_CK_EN : R_AX_CK_EN_C1)); if (cmac_err & B_AX_SCHEDULE_TOP_ERR_IND) { PLTFM_MSG_ERR("R_AX_SCHEDULE_ERR_IMR=0x%08x\n", MAC_REG_R32(band == MAC_AX_BAND_0 ? R_AX_SCHEDULE_ERR_IMR : R_AX_SCHEDULE_ERR_IMR_C1)); PLTFM_MSG_ERR("R_AX_SCHEDULE_ERR_ISR=0x%04x\n", MAC_REG_R16(band == MAC_AX_BAND_0 ? R_AX_SCHEDULE_ERR_ISR : R_AX_SCHEDULE_ERR_ISR_C1)); } if (cmac_err & B_AX_PTCL_TOP_ERR_IND) { PLTFM_MSG_ERR("R_AX_PTCL_IMR0=0x%08x\n", MAC_REG_R32(band == MAC_AX_BAND_0 ? R_AX_PTCL_IMR0 : R_AX_PTCL_IMR0_C1)); PLTFM_MSG_ERR("R_AX_PTCL_ISR0=0x%08x\n", MAC_REG_R32(band == MAC_AX_BAND_0 ? R_AX_PTCL_ISR0 : R_AX_PTCL_ISR0_C1)); } if (cmac_err & B_AX_DMA_TOP_ERR_IND) { PLTFM_MSG_ERR("R_AX_DLE_CTRL=0x%08x\n", MAC_REG_R32(band == MAC_AX_BAND_0 ? R_AX_DLE_CTRL : R_AX_DLE_CTRL_C1)); } if (cmac_err & B_AX_PHYINTF_ERR_IND) { PLTFM_MSG_ERR("R_AX_PHYINFO_ERR_IMR=0x%04x\n", MAC_REG_R16(band == MAC_AX_BAND_0 ? R_AX_PHYINFO_ERR_IMR : R_AX_PHYINFO_ERR_IMR_C1)); } if (cmac_err & B_AX_TXPWR_CTRL_ERR_IND) { PLTFM_MSG_ERR("R_AX_TXPWR_IMR=0x%08x\n", MAC_REG_R32(band == MAC_AX_BAND_0 ? R_AX_TXPWR_IMR : R_AX_TXPWR_IMR_C1)); PLTFM_MSG_ERR("R_AX_TXPWR_ISR=0x%08x\n", MAC_REG_R32(band == MAC_AX_BAND_0 ? R_AX_TXPWR_ISR : R_AX_TXPWR_ISR_C1)); } if (cmac_err & B_AX_WMAC_RX_ERR_IND) { PLTFM_MSG_ERR("R_AX_DBGSEL_TRXPTCL=0x%08x\n", MAC_REG_R32(band == MAC_AX_BAND_0 ? R_AX_DBGSEL_TRXPTCL : R_AX_DBGSEL_TRXPTCL_C1)); PLTFM_MSG_ERR("R_AX_PHYINFO_ERR_ISR=0x%08x\n", MAC_REG_R32(band == MAC_AX_BAND_0 ? R_AX_PHYINFO_ERR_ISR : R_AX_PHYINFO_ERR_ISR_C1)); } if (cmac_err & B_AX_WMAC_TX_ERR_IND) { PLTFM_MSG_ERR("R_AX_TMAC_ERR_IMR_ISR=0x%08x\n", MAC_REG_R32(band == MAC_AX_BAND_0 ? R_AX_TMAC_ERR_IMR_ISR : R_AX_TMAC_ERR_IMR_ISR_C1)); PLTFM_MSG_ERR("R_AX_DBGSEL_TRXPTCL=0x%08x\n", MAC_REG_R32(band == MAC_AX_BAND_0 ? R_AX_DBGSEL_TRXPTCL : R_AX_DBGSEL_TRXPTCL_C1)); } } u32 mac_ser_ctrl(struct mac_ax_adapter *adapter, enum mac_ax_func_sw sw) { struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter); enum mac_ax_err_info err_info; u32 val32, ret, cnt; if (is_chip_id(adapter, MAC_AX_CHIP_ID_8852B) && is_cv(adapter, CAV)) { PLTFM_MSG_WARN("[WARN]SER ctrl not support\n"); return MACSUCCESS; } if (sw == MAC_AX_FUNC_EN) { err_info = MAC_AX_ERR_L1_RCVY_START_REQ; adapter->sm.ser_ctrl_st = MAC_AX_SER_CTRL_SRT; } else if (sw == MAC_AX_FUNC_DIS) { err_info = MAC_AX_ERR_L1_RCVY_STOP_REQ; adapter->sm.ser_ctrl_st = MAC_AX_SER_CTRL_STOP; } else { adapter->sm.ser_ctrl_st = MAC_AX_SER_CTRL_ERR; PLTFM_MSG_ERR("[ERR]SER ctrl input err %d\n", sw); return MACFUNCINPUT; } ret = mac_set_err_status(adapter, err_info); if (ret != MACSUCCESS) { adapter->sm.ser_ctrl_st = MAC_AX_SER_CTRL_ERR; PLTFM_MSG_ERR("[ERR]set err for stop ser %d\n", ret); return ret; } cnt = MAC_SET_ERR_DLY_CNT; while (cnt) { val32 = MAC_REG_R32(R_AX_HALT_H2C_CTRL); if (!(val32 & B_AX_HALT_H2C_TRIGGER)) break; PLTFM_DELAY_US(MAC_SET_ERR_DLY_US); cnt--; } if (!cnt) { adapter->sm.ser_ctrl_st = MAC_AX_SER_CTRL_ERR; PLTFM_MSG_ERR("[ERR]FW not handle haltH2C req\n"); ret = MACPOLLTO; return ret; } if (sw == MAC_AX_FUNC_EN) return MACSUCCESS; cnt = MAC_SER_STOP_DLY_CNT; while (cnt) { PLTFM_DELAY_US(MAC_SER_STOP_DLY_US); val32 = MAC_REG_R32(R_AX_UDM0); val32 = GET_FIELD(val32, FW_ST); if (val32 != FW_ST_ERR_IN) break; cnt--; } if (!cnt) { adapter->sm.ser_ctrl_st = MAC_AX_SER_CTRL_ERR; PLTFM_MSG_ERR("[ERR]stop ser polling FW ST timeout\n"); return MACPOLLTO; } return ret; }