int ccci_df_to_ccci_callback(unsigned int rxq_no) { int ret, hc_ret; bool is_xcmd = false; struct sk_buff * skb = NULL; CCCI_BUFF_T *ccci_h = NULL; XBOOT_CMD *p_xcmd = NULL; KAL_UINT32 port_id = CCCI_PORT_CTRL; static KAL_UINT32 rx_err_cnt[CCCI_PORT_NUM_MAX] = {0}; #ifdef __EEMCS_EXPT_SUPPORT__ EEMCS_EXCEPTION_STATE mode = EEMCS_EX_INVALID; #endif #if defined (DBG_FEATURE_ADD_CCCI_SEQNO) KAL_INT16 channel, seq_num, assert_bit; #endif DEBUG_LOG_FUNCTION_ENTRY; /* Step 1. read skb from swq */ skb = hif_dl_read_swq(rxq_no); if(skb == NULL) { DBGLOG(CCCI, DBG, "ccci_df_to_ccci_callback read NULL skb on %d", rxq_no); if(is_exception_mode(&mode)) return KAL_FAIL; else KAL_ASSERT(NULL != skb); } /* Step 2. call handle complete */ hc_ret = hif_dl_pkt_handle_complete(rxq_no); KAL_ASSERT(0 == hc_ret); wake_lock_timeout(&eemcs_wake_lock, HZ/2); // Using 0.5s wake lock /* Step 3. buffer type */ if (rxq_no == RXQ_Q0) { //is_xcmd = is_xboot_command(skb); p_xcmd = (XBOOT_CMD *)skb->data; if (p_xcmd->magic == (KAL_UINT32)MAGIC_MD_CMD) { if (check_device_state() >= EEMCS_MOLY_HS_P1) { DBGLOG(CCCI, ERR, "can't recv xBoot cmd when EEMCS state=%d", check_device_state()); } else { is_xcmd = true; } } } if (is_xcmd) { /* Step 4. callback to xBoot */ CDEV_LOG(port_id, CCCI, INF, "XBOOT_CMD: 0x%08X, 0x%08X, 0x%08X, 0x%08X",\ p_xcmd->magic, p_xcmd->msg_id, p_xcmd->status, p_xcmd->reserved[0]); ret = ccci_port_info[port_id].ch.rx_cb(skb, 0); } else { ccci_h = (CCCI_BUFF_T *)skb->data; port_id = ccci_ch_to_port(ccci_h->channel); CDEV_LOG(port_id, CCCI, INF, "CCCI_H: 0x%08X, 0x%08X, 0x%08X, 0x%08X",\ ccci_h->data[0],ccci_h->data[1],ccci_h->channel, ccci_h->reserved); /*check rx sequence number for expect*/ #if defined (DBG_FEATURE_ADD_CCCI_SEQNO) channel = ccci_h->channel; seq_num = ccci_h->seq_num; assert_bit = ccci_h->assert_bit; DBGLOG(CCCI, DBG, "Port%d CCCI_H: data[0]=0x%08X, data[1]=0x%08X, ch=0x%02X, seqno=0x%02X, assert=%d, resv=0x%08X(0x%08X, 0x%08X, 0x%08X)",\ port_id, ccci_h->data[0],ccci_h->data[1],ccci_h->channel, ccci_h->seq_num, \ ccci_h->assert_bit, ccci_h->reserved, channel, seq_num, assert_bit); if(((seq_num - ccci_seqno_tbl[channel].seqno[RX]) & 0x7FFF) != 1 && assert_bit) { DBGLOG(CCCI, ERR, "Port%d seqno out-of-order(0x%02X->0x%02X): data[0]=0x%08X, data[1]=0x%08X, ch=0x%02X, seqno=0x%02X, assert=%d, resv=0x%08X", \ port_id, seq_num, ccci_seqno_tbl[channel].seqno[RX], ccci_h->data[0], ccci_h->data[1], \ ccci_h->channel, ccci_h->seq_num, ccci_h->assert_bit, ccci_h->reserved); hif_force_md_assert_swint(); } ccci_seqno_tbl[channel].seqno[RX] = seq_num; #endif /* Step 4. callback to CCCI device */ if(NULL != ccci_port_info[port_id].ch.rx_cb){ #ifdef __EEMCS_EXPT_SUPPORT__ if(is_exception_mode(&mode)) { if(!is_valid_exception_port(port_id, true)) { ret = KAL_FAIL; dev_kfree_skb(skb); eemcs_ccci_release_rx_skb(port_id, 1, skb); eemcs_expt_ccci_rx_drop(port_id); DBGLOG(CCCI, ERR, "PKT DROP when PORT%d(rxq=%d) at md exception", \ port_id, rxq_no); goto _end; } else { ret = ccci_port_info[port_id].ch.rx_cb(skb, 0); } } else #endif { ret = ccci_port_info[port_id].ch.rx_cb(skb, 0); } rx_err_cnt[port_id] = 0; } else { ret = KAL_FAIL; dev_kfree_skb(skb); eemcs_ccci_release_rx_skb(port_id, 1, skb); if (rx_err_cnt[port_id]%20 == 0) { DBGLOG(CCCI, ERR, "PKT DROP when PORT%d rx callback(ch=%d) not registered", \ port_id, ccci_h->channel); } rx_err_cnt[port_id]++; eemcs_update_statistics(0, port_id, RX, DROP); } eemcs_update_statistics(0, port_id, RX, NORMAL); } _end: DEBUG_LOG_FUNCTION_LEAVE; return ret; }
/* * @brief Flush all packets in exception instance to files for debugging * @param * None * @return * This function returns KAL_SUCCESS always. */ KAL_INT32 eemcs_expt_flush() { KAL_UINT32 pkts = 0; KAL_UINT32 i = 0; // struct sk_buff *skb = NULL; /* Flush all port skb from expt skb list */ for (i = 0; i < CCCI_PORT_NUM; i++) { pkts = atomic_read(&g_except_inst.port[i].pkt_cnt); /* No data in port */ if (pkts == 0) continue; DBGLOG(EXPT, DBG, "free %d skb in port%d expt list", pkts, i); skb_queue_purge(&g_except_inst.port[i].skb_list); atomic_set(&g_except_inst.port[i].pkt_cnt, 0); } /* Flush all rx skb from expt skb list */ for (i = 0; i < SDIO_RX_Q_NUM; i++) { pkts = atomic_read(&g_except_inst.rxq[i].pkt_cnt); /* No data in port */ if (pkts == 0) continue; DBGLOG(EXPT, DBG, "free %d skb in rxq%d expt list", pkts, i); skb_queue_purge(&g_except_inst.rxq[i].skb_list); atomic_set(&g_except_inst.rxq[i].pkt_cnt, 0); } /* Flush all tx skb from expt skb list */ for (i = 0; i < SDIO_TX_Q_NUM; i++) { pkts = atomic_read(&g_except_inst.txq[i].pkt_cnt); /* No data in port */ if (pkts == 0) continue; DBGLOG(EXPT, DBG, "free %d skb in txq%d expt list", pkts, i); skb_queue_purge(&g_except_inst.txq[i].skb_list); atomic_set(&g_except_inst.txq[i].pkt_cnt, 0); } #if 0 char log_file[NAME_MAX] = {0}; struct file *fp = NULL; KAL_UINT32 pkts = 0; KAL_UINT32 i = 0, j = 0; struct sk_buff *skb = NULL; DEBUG_LOG_FUNCTION_ENTRY; /* Flush all DL packets to a file */ for (i = 0; i < SDIO_RX_Q_NUM; i++) { pkts = atomic_read(&g_except_inst.rxq[i].pkt_cnt); DBGLOG(EXPT, DBG, "[EXPT] %d packets in DL SWQ %d", pkts, i); /* No data in Rx Q */ if (pkts == 0) continue; sprintf(log_file, "%s/eemcs_expt_rx-%02d_%d.bak", EEMCS_EXCEPTION_LOG_PATH, g_except_inst.rxq[i].id, pkts); fp = file_open(log_file, O_RDWR | O_CREAT | O_TRUNC, 0777); if (fp == NULL) { DBGLOG(EXPT, ERR, "[EXPT] Failed to open file %s", log_file); continue; } // Write packets number file_write(fp, (char*)&pkts, sizeof(KAL_UINT32)); /* Write each skb in list */ for (j = 0; j < pkts; j++) { skb = skb_dequeue(&g_except_inst.rxq[i].skb_list); if (skb == NULL) { DBGLOG(EXPT, WAR, "[EXPT] Failed to read skb from RX list %d", i); } else { hif_dl_pkt_handle_complete(i); // Write skb data length file_write(fp, (char*)&skb->len, sizeof(unsigned int)); // Write skb data file_write(fp, skb->data, skb->len); atomic_dec(&g_except_inst.rxq[i].pkt_cnt); } } file_close(fp); DBGLOG(EXPT, TRA, "[EXPT] All unhandled DL packets in Q are saved to %s", log_file); } /* Flush all UL packets to a file */ for (i = 0; i < SDIO_TX_Q_NUM; i++) { pkts = atomic_read(&g_except_inst.txq[i].pkt_cnt); DBGLOG(EXPT, DBG, "[EXPT] %d packets in UL SWQ %d", pkts, i); /* No data in Tx Q */ if (pkts == 0) continue; sprintf(log_file, "%s/eemcs_expt_tx-%02d_%d.bak", EEMCS_EXCEPTION_LOG_PATH, g_except_inst.txq[i].id, pkts); fp = file_open(log_file, O_RDWR | O_CREAT | O_TRUNC, 0777); if (fp == NULL) { DBGLOG(EXPT, ERR, "[EXPT] Failed to open file %s", log_file); continue; } // Write packets number file_write(fp, (char*)&pkts, sizeof(KAL_UINT32)); /* Write each skb in list */ for (j = 0; j < pkts; j++) { skb = skb_dequeue(&g_except_inst.txq[i].skb_list); if (skb == NULL) { DBGLOG(EXPT, WAR, "[EXPT] Failed to read skb from TX list %d", i); } else { // Write skb data length file_write(fp, (char*)&skb->len, sizeof(unsigned int)); // Write skb data file_write(fp, skb->data, skb->len); atomic_dec(&g_except_inst.txq[i].pkt_cnt); } } file_close(fp); DBGLOG(EXPT, TRA, "[EXPT] All unhandled UL packets in Q are saved to %s", log_file); } /* Flush all port packets to a file */ for (i = 0; i < CCCI_CDEV_NUM; i++) { pkts = atomic_read(&g_except_inst.port[i].pkt_cnt); DBGLOG(EXPT, DBG, "[EXPT] %d packets in port %d", pkts, i); /* No data in port */ if (pkts == 0) continue; sprintf(log_file, "%s/eemcs_expt_port-%02d_%d.bak", EEMCS_EXCEPTION_LOG_PATH, i, pkts); fp = file_open(log_file, O_RDWR | O_CREAT, 0777); if (fp == NULL) { DBGLOG(EXPT, ERR, "[EXPT] Failed to open file %s", log_file); continue; } // Write packets number file_write(fp, (char*)&pkts, sizeof(KAL_UINT32)); /* Write each skb in list */ for (j = 0; j < pkts; j++) { skb = skb_dequeue(&g_except_inst.port[i].skb_list); if (skb == NULL) { DBGLOG(EXPT, WAR, "[EXPT] Failed to read skb from port list %d", i); } else { // Write skb data length file_write(fp, (char*)&skb->len, sizeof(unsigned int)); // Write skb data file_write(fp, skb->data, skb->len); atomic_dec(&g_except_inst.port[i].pkt_cnt); } } file_close(fp); DBGLOG(EXPT, TRA, "[EXPT] All unhandled UL packets in port are saved to %s", log_file); } DBGLOG(EXPT, TRA, "[EXPT] eemcs_expt_flush() Finished !!"); DEBUG_LOG_FUNCTION_LEAVE; #else DEBUG_LOG_FUNCTION_ENTRY; DEBUG_LOG_FUNCTION_LEAVE; #endif return KAL_SUCCESS; }
int ccci_df_to_ccci_callback(unsigned int rxq_no) { int ret, hc_ret, is_xcmd; struct sk_buff * skb = NULL; CCCI_BUFF_T *ccci_h = NULL; XBOOT_CMD *p_xcmd = NULL; KAL_UINT32 port_id = 0; #ifdef __EEMCS_EXPT_SUPPORT__ EEMCS_EXCEPTION_STATE mode = EEMCS_EX_INVALID; #endif DEBUG_LOG_FUNCTION_ENTRY; /* Step 1. read skb from swq */ skb = hif_dl_read_swq(rxq_no); if(skb == NULL) { DBGLOG(CCCI, DBG, "ccci_df_to_ccci_callback read NULL skb on %d", rxq_no); if(is_exception_mode(&mode)) return KAL_FAIL; else KAL_ASSERT(NULL != skb); } /* Step 2. call handle complete */ hc_ret = hif_dl_pkt_handle_complete(rxq_no); KAL_ASSERT(0 == hc_ret); DBGLOG(CCCI, DBG, "ccci_df_to_ccci_callback() rxq_no = %d", rxq_no); /* Step 3. buffer type */ if (rxq_no == RXQ_Q0) { is_xcmd = is_xboot_command(skb); } else { is_xcmd = false; } wake_lock_timeout(&eemcs_wake_lock, HZ); // Using 1s wake lock if (is_xcmd == true) { /* Step 4. callback to xBoot */ p_xcmd = (XBOOT_CMD *)skb->data; KAL_ASSERT(p_xcmd->magic == (KAL_UINT32)MAGIC_MD_CMD); if (NULL != ccci_port_info[CCCI_PORT_CTRL].ch.rx_cb){ DBGLOG(CCCI, DBG, "[CCCI][DF CALLBACK] XBOOT_CMD (0x%X)(0x%X)(0x%X)(0x%X)",\ p_xcmd->magic, p_xcmd->msg_id, p_xcmd->status, p_xcmd->reserved[0]); #ifdef __EEMCS_EXPT_SUPPORT__ if(is_exception_mode(&mode)) { if(!is_valid_exception_port(CCCI_PORT_CTRL, true)) { ret = KAL_FAIL; dev_kfree_skb(skb); eemcs_expt_ccci_rx_drop(port_id); DBGLOG(CCCI, ERR, "[CCCI] [DF CALLBACK] EXCEPTION MODE PKT DROPPED !! Q(%d) PORT(%d)", rxq_no, CCCI_PORT_CTRL); goto _end; } else { ret = ccci_port_info[CCCI_PORT_CTRL].ch.rx_cb(skb, 0); } } else #endif { ret = ccci_port_info[CCCI_PORT_CTRL].ch.rx_cb(skb, 0); } } else { ret = KAL_FAIL; dev_kfree_skb(skb); DBGLOG(CCCI, ERR, "[CCCI] !!! PKT DROP !!! ccci_df_to_ccci_callback xBoot not registered"); } } else { /* Step 4. callback to CCCI device */ ccci_h = (CCCI_BUFF_T *)skb->data; KAL_ASSERT(ccci_h->channel < CH_NUM_MAX); port_id = ccci_ch_to_port(ccci_h->channel); if(NULL != ccci_port_info[port_id].ch.rx_cb){ DBGLOG(CCCI,DBG,"ccci_df_to_ccci_callback Rx packet CCCI_H(0x%x)(0x%x)(0x%x)(0x%x)",\ ccci_h->data[0],ccci_h->data[1],ccci_h->channel, ccci_h->reserved ); #ifdef __EEMCS_EXPT_SUPPORT__ if(is_exception_mode(&mode)) { if(!is_valid_exception_port(port_id, true)) { ret = KAL_FAIL; dev_kfree_skb(skb); eemcs_expt_ccci_rx_drop(port_id); DBGLOG(CCCI, ERR, "[CCCI] [DF CALLBACK] EXCEPTION MODE PKT DROPPED !! Q(%d) PORT(%d)", rxq_no, port_id); goto _end; } else { ret = ccci_port_info[port_id].ch.rx_cb(skb, 0); } } else #endif { ret = ccci_port_info[port_id].ch.rx_cb(skb, 0); } }else{ ret = KAL_FAIL; dev_kfree_skb(skb); DBGLOG(CCCI,ERR, "[CCCI] !!! PKT DROP !!! ccci_df_to_ccci_callback ccci_port(%d) channel Rx(%d) not registered", port_id, ccci_h->channel); eemcs_update_statistics(0, port_id, RX, DROP); } eemcs_update_statistics(0, port_id, RX, NORMAL); } _end: DEBUG_LOG_FUNCTION_LEAVE; return ret; }