static P_OSAL_OP _stp_btm_get_op ( MTKSTP_BTM_T *stp_btm, P_OSAL_OP_Q pOpQ ) { P_OSAL_OP pOp; INT32 ret = 0; if (!pOpQ) { STP_BTM_WARN_FUNC("!pOpQ \n"); return NULL; } osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); if (ret) { STP_BTM_WARN_FUNC("mutex_lock_interruptible (%d) \n", ret); return NULL; } /* acquire lock success */ RB_GET(pOpQ, pOp); osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); if (!pOp) { //STP_BTM_WARN_FUNC("RB_GET fail\n"); } return pOp; }
static INT32 _stp_dbg_dmp_in (MTKSTP_DBG_T *stp_dbg, CHAR *buf, INT32 len) { UINT32 internalFlag = stp_dbg->logsys->size < STP_DBG_LOG_ENTRY_NUM; #ifdef CONFIG_LOG_STP_INTERNAL internalFlag = 1; #endif osal_lock_unsleepable_lock(&(stp_dbg->logsys->lock)); if (internalFlag){ stp_dbg->logsys->queue[stp_dbg->logsys->in].id = 0; stp_dbg->logsys->queue[stp_dbg->logsys->in].len = len; osal_memcpy(&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]),buf, ((len >= STP_DBG_LOG_ENTRY_SZ)? (STP_DBG_LOG_ENTRY_SZ):(len))); stp_dbg->logsys->size++; stp_dbg->logsys->size = (stp_dbg->logsys->size > STP_DBG_LOG_ENTRY_NUM) ? STP_DBG_LOG_ENTRY_NUM : stp_dbg->logsys->size; stp_dbg->logsys->in = (stp_dbg->logsys->in >= (STP_DBG_LOG_ENTRY_NUM - 1))?(0):(stp_dbg->logsys->in + 1); STP_DBG_DBG_FUNC("logsys size = %d, in = %d\n", stp_dbg->logsys->size, stp_dbg->logsys->in); } else { STP_DBG_WARN_FUNC("logsys FULL!\n"); } osal_unlock_unsleepable_lock(&(stp_dbg->logsys->lock)); return 0; }
static INT32 _stp_btm_put_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) { INT32 ret; if (!pOpQ || !pOp) { STP_BTM_WARN_FUNC("invalid input param: 0x%p, 0x%p\n", pOpQ, pOp); return 0; /* ;MTK_WCN_BOOL_FALSE; */ } ret = 0; osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); /* acquire lock success */ if (!RB_FULL(pOpQ)) RB_PUT(pOpQ, pOp); else ret = -1; osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); if (ret) { STP_BTM_WARN_FUNC("RB_FULL(0x%p) %d ,rFreeOpQ = %p, rActiveOpQ = %p\n", pOpQ, RB_COUNT(pOpQ), &stp_btm->rFreeOpQ, &stp_btm->rActiveOpQ); return 0; } else { /* STP_BTM_WARN_FUNC("RB_COUNT = %d\n",RB_COUNT(pOpQ)); */ return 1; } }
static INT32 _stp_dbg_enable (MTKSTP_DBG_T *stp_dbg) { osal_lock_unsleepable_lock(&(stp_dbg->logsys->lock)); stp_dbg->pkt_trace_no = 0; stp_dbg->is_enable = 1; osal_unlock_unsleepable_lock(&(stp_dbg->logsys->lock)); return 0; }
INT32 stp_btm_reset_btm_wq(MTKSTP_BTM_T *stp_btm) { UINT32 i = 0; osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE); RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE); osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); /* Put all to free Q */ for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++) { osal_signal_init(&(stp_btm->arQue[i].signal)); _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i])); } return 0; }
INT32 stp_dbg_dmp_printk (MTKSTP_DBG_T *stp_dbg) { CHAR *pBuf = NULL; INT32 len = 0; STP_DBG_HDR_T *pHdr = NULL; osal_lock_unsleepable_lock(&(stp_dbg->logsys->lock)); if (STP_DBG_LOG_ENTRY_NUM == stp_dbg->logsys->size) { stp_dbg->logsys->out = stp_dbg->logsys->in; } else { stp_dbg->logsys->out = ((stp_dbg->logsys->in + STP_DBG_LOG_ENTRY_NUM) - stp_dbg->logsys->size) % STP_DBG_LOG_ENTRY_NUM; } STP_DBG_INFO_FUNC("loged packet size = %d, in(%d), out(%d)\n", stp_dbg->logsys->size, stp_dbg->logsys->in, stp_dbg->logsys->out); while(stp_dbg->logsys->size > 0){ pHdr = (STP_DBG_HDR_T *)&(stp_dbg->logsys->queue[stp_dbg->logsys->out].buffer[0]); STP_DBG_INFO_FUNC("%d.%ds, %s:pT%sn(%d)l(%d)s(%d)a(%d)\n", \ pHdr->sec, pHdr->usec, pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", gStpDbgType[pHdr->type], pHdr->no, pHdr->len, pHdr->seq, pHdr->ack ); pBuf = &(stp_dbg->logsys->queue[stp_dbg->logsys->out].buffer[0]) + sizeof (STP_DBG_HDR_T); len = stp_dbg->logsys->queue[stp_dbg->logsys->out].len - sizeof (STP_DBG_HDR_T); if (0 < len){ stp_dbg_dump_data(pBuf, pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", len); } stp_dbg->logsys->out = (stp_dbg->logsys->out >= (STP_DBG_LOG_ENTRY_NUM - 1))?(0):(stp_dbg->logsys->out + 1); stp_dbg->logsys->size--; } osal_unlock_unsleepable_lock(&(stp_dbg->logsys->lock)); return 0; }
static P_OSAL_OP _stp_btm_get_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP_Q pOpQ) { P_OSAL_OP pOp; /* INT32 ret = 0; */ if (!pOpQ) { STP_BTM_WARN_FUNC("!pOpQ\n"); return NULL; } osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); /* acquire lock success */ RB_GET(pOpQ, pOp); osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); if (!pOp) STP_BTM_WARN_FUNC("RB_GET fail\n"); return pOp; }
static INT32 _stp_dbg_disable (MTKSTP_DBG_T *stp_dbg) { osal_lock_unsleepable_lock(&(stp_dbg->logsys->lock)); stp_dbg->pkt_trace_no = 0; /* [FIXME][George] DANGEROUS CODING to MEMSET A STRUCTURE in a NON-INIT * or a NON-DEINIT CONTEXT!!! */ #if 0 osal_memset(stp_dbg->logsys,0,osal_sizeof(MTKSTP_LOG_SYS_T)); #else osal_memset(&stp_dbg->logsys->queue[0], 0x0, sizeof(stp_dbg->logsys->queue)); stp_dbg->logsys->size = 0; stp_dbg->logsys->in = 0; stp_dbg->logsys->out = 0; #endif stp_dbg->is_enable = 0; osal_unlock_unsleepable_lock(&(stp_dbg->logsys->lock)); return 0; }
INT32 stp_dbg_dmp_out (MTKSTP_DBG_T *stp_dbg, CHAR *buf, INT32 *len) { INT32 remaining = 0; osal_lock_unsleepable_lock(&(stp_dbg->logsys->lock)); if (stp_dbg->logsys->size > 0){ osal_memcmp(buf, &(stp_dbg->logsys->queue[stp_dbg->logsys->out].buffer[0]), stp_dbg->logsys->queue[stp_dbg->logsys->out].len); (*len) = stp_dbg->logsys->queue[stp_dbg->logsys->out].len; stp_dbg->logsys->out = (stp_dbg->logsys->out >= (STP_DBG_LOG_ENTRY_NUM - 1))?(0):(stp_dbg->logsys->out + 1); stp_dbg->logsys->size--; STP_DBG_DBG_FUNC("logsys size = %d, out = %d\n", stp_dbg->logsys->size, stp_dbg->logsys->out); } else { STP_DBG_LOUD_FUNC("logsys EMPTY!\n"); } remaining = (stp_dbg->logsys->size == 0)?(0):(1); osal_unlock_unsleepable_lock(&(stp_dbg->logsys->lock)); return remaining; }
INT32 wmt_plat_eirq_ctrl ( ENUM_PIN_ID id, ENUM_PIN_STATE state ) { INT32 iret; // TODO: [ChangeFeature][GeorgeKuo]: use another function to handle this, as done in gpio_ctrls if ( (PIN_STA_INIT != state ) && (PIN_STA_DEINIT != state ) && (PIN_STA_EINT_EN != state ) && (PIN_STA_EINT_DIS != state ) ) { WMT_WARN_FUNC("WMT-PLAT:invalid PIN_STATE(%d) in eirq_ctrl for PIN(%d)\n", state, id); return -1; } iret = -2; switch (id) { case PIN_BGF_EINT: #if 1 if (PIN_STA_INIT == state) { iret = request_irq(MT_CONN2AP_BTIF_WAKEUP_IRQ_ID, (irq_handler_t)wmt_plat_bgf_irq_isr, IRQF_TRIGGER_LOW, "BTIF_WAKEUP_IRQ", NULL); if(iret) { WMT_ERR_FUNC("request_irq fail,irq_no(%d),iret(%d)\n",MT_CONN2AP_BTIF_WAKEUP_IRQ_ID,iret); return iret; } gbgfIrqBle.counter = 1; } else if (PIN_STA_EINT_EN == state) { osal_lock_unsleepable_lock(&gbgfIrqBle.lock); if(gbgfIrqBle.counter) { WMT_DBG_FUNC("BGF INT has been enabled,counter(%d)\n",gbgfIrqBle.counter);; } else { enable_irq(MT_CONN2AP_BTIF_WAKEUP_IRQ_ID); gbgfIrqBle.counter++; } WMT_DBG_FUNC("WMT-PLAT:BGFInt (en) \n"); osal_unlock_unsleepable_lock(&gbgfIrqBle.lock); } else if (PIN_STA_EINT_DIS == state) { osal_lock_unsleepable_lock(&gbgfIrqBle.lock); if(!gbgfIrqBle.counter) { WMT_INFO_FUNC("BGF INT has been disabled,counter(%d)\n",gbgfIrqBle.counter);; } else { disable_irq_nosync(MT_CONN2AP_BTIF_WAKEUP_IRQ_ID); gbgfIrqBle.counter--; } WMT_DBG_FUNC("WMT-PLAT:BGFInt (dis) \n"); osal_unlock_unsleepable_lock(&gbgfIrqBle.lock); } else { free_irq(MT_CONN2AP_BTIF_WAKEUP_IRQ_ID,NULL); /* de-init: nothing to do in ALPS, such as un-registration... */ } #else WMT_INFO_FUNC("WMT-PLAT:BGF EINT not defined\n", state); #endif iret = 0; break; default: WMT_WARN_FUNC("WMT-PLAT:unsupported EIRQ(PIN_ID:%d) in eirq_ctrl\n", id); iret = -1; break; } return iret; }
static INT32 _stp_btm_proc(PVOID pvData) { MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *) pvData; P_OSAL_OP pOp; INT32 id; INT32 result; if (!stp_btm) { STP_BTM_WARN_FUNC("!stp_btm\n"); return -1; } for (;;) { pOp = NULL; osal_wait_for_event(&stp_btm->STPd_event, _stp_btm_wait_for_msg, (PVOID)stp_btm); if (osal_thread_should_stop(&stp_btm->BTMd)) { STP_BTM_INFO_FUNC("should stop now...\n"); /* TODO: clean up active opQ */ break; } #if 1 if (gDumplogflag) { /* pr_warn("enter place1\n"); */ if (mtk_wcn_stp_is_uart_mand_mode() || mtk_wcn_stp_is_uart_fullset_mode()) dump_uart_history(); gDumplogflag = 0; continue; } #endif /* get Op from activeQ */ pOp = _stp_btm_get_op(stp_btm, &stp_btm->rActiveOpQ); if (!pOp) { STP_BTM_WARN_FUNC("get_lxop activeQ fail\n"); continue; } id = osal_op_get_id(pOp); STP_BTM_DBG_FUNC("======> lxop_get_opid = %d, %s, remaining count = *%d*\n", id, (id >= 4) ? ("???") : (g_btm_op_name[id]), RB_COUNT(&stp_btm->rActiveOpQ)); if (id >= STP_OPID_BTM_NUM) { STP_BTM_WARN_FUNC("abnormal opid id: 0x%x\n", id); result = -1; goto handler_done; } osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); stp_btm_set_current_op(stp_btm, pOp); osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); result = _stp_btm_handler(stp_btm, &pOp->op); osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); stp_btm_set_current_op(stp_btm, NULL); osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); handler_done: if (result) { STP_BTM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n", id, (id >= 4) ? ("???") : (g_btm_op_name[id]), result); } if (osal_op_is_wait_for_signal(pOp)) { osal_op_raise_signal(pOp, result); } else { /* put Op back to freeQ */ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp); } if (STP_OPID_BTM_EXIT == id) { break; } else if (STP_OPID_BTM_RST == id) { /* prevent multi reset case */ stp_btm_reset_btm_wq(stp_btm); } } STP_BTM_INFO_FUNC("exits\n"); return 0; };
static INT32 _stp_btm_put_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) { INT32 ret; P_OSAL_OP pOp_latest; P_OSAL_OP pOp_current; INT32 flag_latest = 1; INT32 flag_current = 1; if (!pOpQ || !pOp) { STP_BTM_WARN_FUNC("invalid input param: 0x%p, 0x%p\n", pOpQ, pOp); return 0; /* ;MTK_WCN_BOOL_FALSE; */ } ret = 0; osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); /* acquire lock success */ if (&stp_btm->rFreeOpQ == pOpQ) { if (!RB_FULL(pOpQ)) RB_PUT(pOpQ, pOp); else ret = -1; } else if (pOp->op.opId == STP_OPID_BTM_RST || pOp->op.opId == STP_OPID_BTM_DUMP_TIMEOUT) { if (!RB_FULL(pOpQ)) { RB_PUT(pOpQ, pOp); STP_BTM_ERR_FUNC("RB_PUT: 0x%d\n", pOp->op.opId); } else ret = -1; } else { pOp_current = stp_btm_get_current_op(stp_btm); if (pOp_current) { if (pOp_current->op.opId == STP_OPID_BTM_RST || pOp_current->op.opId == STP_OPID_BTM_DUMP_TIMEOUT) { STP_BTM_ERR_FUNC("current: 0x%d\n", pOp_current->op.opId); flag_current = 0; } } RB_GET_LATEST(pOpQ, pOp_latest); if (pOp_latest) { if (pOp_latest->op.opId == STP_OPID_BTM_RST || pOp_latest->op.opId == STP_OPID_BTM_DUMP_TIMEOUT) { STP_BTM_ERR_FUNC("latest: 0x%d\n", pOp_latest->op.opId); flag_latest = 0; } if (pOp_latest->op.opId == pOp->op.opId) { flag_latest = 0; STP_BTM_DBG_FUNC("With the latest a command repeat: latest 0x%d,current 0x%d\n", pOp_latest->op.opId, pOp->op.opId); } } if (flag_current && flag_latest) { if (!RB_FULL(pOpQ)) { RB_PUT(pOpQ, pOp); STP_BTM_ERR_FUNC("RB_PUT: 0x%d\n", pOp->op.opId); } else ret = -1; } else ret = -1; } osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); if (ret) { STP_BTM_DBG_FUNC("RB_FULL(0x%p) %d ,rFreeOpQ = %p, rActiveOpQ = %p\n", pOpQ, RB_COUNT(pOpQ), &stp_btm->rFreeOpQ, &stp_btm->rActiveOpQ); return 0; } else { /* STP_BTM_WARN_FUNC("RB_COUNT = %d\n",RB_COUNT(pOpQ)); */ return 1; } }