/* * @brief Callback function which is registerd to DF layer * @param * msg_id [in] Exception ID * @return * None */ void ccci_df_to_ccci_exception_callback(KAL_UINT32 msg_id) { DEBUG_LOG_FUNCTION_ENTRY; DBGLOG(EXPT, TRA, "CCCI Exception Callback (%d)", msg_id); switch (msg_id) { case EX_INIT: { //reset exception statistics eemcs_expt_reset_statistics(); //set eemcs state to EEMCS_EXCEPTION change_device_state(EEMCS_EXCEPTION); //set a 5s timer to check if exception flow complete mod_timer(&g_except_inst.md_ex_monitor, jiffies+EE_INIT_TIMER); //update eemcs_exception state : EEMCS_EX_NONE -> EEMCS_EX_INIT or EEMCS_EX_INIT_DONE-> EEMCS_EX_INIT set_exception_mode(EEMCS_EX_INIT); //indicate state change to upper layer eemcs_exec_expt_callback(EEMCS_EX_INIT); //Send message to mdinit eemcs_cdev_msg(CCCI_PORT_CTRL, CCCI_MD_MSG_EXCEPTION, 0); //snapeshot traffic eemcs_ccci_expt_log_df_q_pkts(); break; } case EX_DHL_DL_RDY: //1. update eemcs_exception state : EEMCS_EX_INIT -> EEMCS_EX_DHL_DL_RDY set_exception_mode(EEMCS_EX_DHL_DL_RDY); //2. indicate state change to upper layer eemcs_exec_expt_callback(EEMCS_EX_DHL_DL_RDY); break; case EX_INIT_DONE: //1. update eemcs_exception state : EEMCS_EX_DHL_DL_RDY -> EEMCS_EX_INIT_DONE set_exception_mode(EEMCS_EX_INIT_DONE); //2. set up timer for waiting MD_EX msg mod_timer(&g_except_inst.md_ex_monitor, jiffies+EE_HS1_TIMER); //3. flush all pkts in exception list eemcs_expt_flush(); //4. indicate state change to upper layer eemcs_exec_expt_callback(EEMCS_EX_INIT_DONE); break; default: DBGLOG(EXPT, ERR, "Unknown exception callback id %d", msg_id); } DEBUG_LOG_FUNCTION_LEAVE; return; }
/* * @brief Initialization of exception handling * @param * None * @return * This function returns KAL_SUCCESS always. */ KAL_INT32 eemcs_expt_mod_init(void) { KAL_UINT32 i = 0; //KAL_UINT32 except_txq = 0, except_rxq = 0; //KAL_UINT32 nonstop_rxq = 0; /* for Log path to output as much as possible */ KAL_INT32 ret; ccci_port_cfg *log_queue_config; DEBUG_LOG_FUNCTION_ENTRY; //Init md exception type g_except_inst.md_ex_type = 0; /* init expt_cb and expt_cb_lock*/ spin_lock_init(&g_except_inst.expt_cb_lock); for(i = 0; i < CCCI_PORT_NUM_MAX; i++) { g_except_inst.expt_cb[i] = NULL; if(TR_Q_INVALID != ccci_expt_port_info[i].expt_txq_id) { set_bit(SDIO_TXQ(ccci_expt_port_info[i].expt_txq_id), (unsigned long *)&except_txq); } if(TR_Q_INVALID != ccci_expt_port_info[i].expt_rxq_id) { set_bit(SDIO_RXQ(ccci_expt_port_info[i].expt_rxq_id), (unsigned long *)&except_rxq); } } eemcs_expt_ut_init(); log_queue_config = ccci_get_port_info(CCCI_PORT_MD_LOG); set_bit(SDIO_RXQ(log_queue_config->rxq_id), (unsigned long *)&nonstop_rxq); hif_except_init(nonstop_rxq, (except_txq << 16) | except_rxq); ret = hif_reg_expt_cb(ccci_df_to_ccci_exception_callback); KAL_ASSERT(ret == KAL_SUCCESS); DBGLOG(EXPT, TRA, "nonstop_txq=%d, nonstop_rxq=%d, exp_txq=%d, exp_rxq=%d", 0, nonstop_rxq, except_txq, except_rxq); /* Init Tx Q list */ for (i = 0; i < SDIO_TX_Q_NUM; i++) { g_except_inst.txq[i].id = -1; atomic_set(&g_except_inst.txq[i].pkt_cnt, 0); skb_queue_head_init(&g_except_inst.txq[i].skb_list); } /* Init Rx Q list */ for (i = 0; i < SDIO_RX_Q_NUM; i++) { g_except_inst.rxq[i].id = -1; atomic_set(&g_except_inst.rxq[i].pkt_cnt, 0); skb_queue_head_init(&g_except_inst.rxq[i].skb_list); } /* Init port list */ for (i = 0; i < CCCI_PORT_NUM; i++) { atomic_set(&g_except_inst.port[i].pkt_cnt, 0); skb_queue_head_init(&g_except_inst.port[i].skb_list); } /* initialize drop count */ eemcs_expt_reset_statistics(); /* initialize exception*/ eemcs_exception_state = EEMCS_EX_NONE; /* initialize exception timer*/ init_timer(&g_except_inst.md_ex_monitor); g_except_inst.md_ex_monitor.function = ex_monitor_func; g_except_inst.md_ex_monitor.data = (unsigned long)&g_except_inst; #ifdef ENABLE_MD_WDT_PROCESS eemcs_ccci_register_WDT_callback(eemcs_wdt_reset_callback); #endif DEBUG_LOG_FUNCTION_LEAVE; return KAL_SUCCESS; }