static void sendQueuedReqToMacSw(tpAniSirGlobal pMac, tHddHandle hHdd) { tCfgReq *req ; /* Send the head req */ req = pMac->ccm.reqQ.head ; if (req) { if (req->state == eCCM_REQ_QUEUED) { /* Send WNI_CFG_SET_REQ */ req->state = eCCM_REQ_SENT; if (sendCfg(pMac, hHdd, req, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS) { smsLog( pMac, LOGW, FL("sendCfg() failed")); palSpinLockTake(hHdd, pMac->ccm.lock); del_req(req, &pMac->ccm.reqQ) ; palSpinLockGive(hHdd, pMac->ccm.lock); if (req->callback) { req->callback((tHalHandle)pMac, WNI_CFG_OTHER_ERROR) ; } #ifdef CCM_DEBUG smsLog(pMac, LOGW, FL("ccmComplete(%p)"), req->done); #endif ccmComplete(hHdd, req->done); freeCfgReq(hHdd, req); } } else { smsLog( pMac, LOGW, FL("reqState is not eCCM_REQ_QUEUED, is %d"), req->state ); } } return ; }
static void purgeReqQ(tHalHandle hHal) { tHddHandle hHdd = halHandle2HddHandle(hHal); tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); tCfgReq *req, *tmp ; for (req = pMac->ccm.reqQ.head; req; req = tmp) { /* loop thru reqQ and invoke callback to return failure */ smsLog(pMac, LOGW, FL("deleting cfgReq, cfgid=%d"), (int)req->cfgId); tmp = req->next ; if (req->callback) { req->callback(hHal, eHAL_STATUS_FAILURE); } palSpinLockTake(hHdd, pMac->ccm.lock); del_req(req, &pMac->ccm.reqQ); palSpinLockGive(hHdd, pMac->ccm.lock); freeCfgReq(hHdd, req); } return ; }
/* * Loop thru comp[] and form an ANI message which contains all completed cfgIds. * The message begins with an INTEGER parameter (cfgId=CFG_UPDATE_MAGIC_DWORD) * to mark the start of the message. */ static eHalStatus cfgUpdate(tpAniSirGlobal pMac, tHddHandle hHdd, tCcmCfgSetCallback callback) { tANI_U32 i, *pl ; tCfgReq *req ; tSirMbMsg *msg ; eHalStatus status ; tANI_S16 msgLen = 4 + /* 4 bytes for msg header */ /* for CFG_UPDATE_MAGIC_DWORD */ CFGOBJ_ID_SIZE + CFGOBJ_LEN_SIZE + CFGOBJ_INTEGER_VALUE_SIZE ; if (pMac->ccm.state == eCCM_STOPPED || pMac->ccm.replay.started) { status = eHAL_STATUS_FAILURE ; goto end ; } palSpinLockTake(hHdd, pMac->ccm.lock); pMac->ccm.replay.started = 1 ; pMac->ccm.replay.nr_param = 0 ; palSpinLockGive(hHdd, pMac->ccm.lock); /* Calculate message length */ for (i = 0 ; i < CFG_PARAM_MAX_NUM ; ++i) { if ((req = pMac->ccm.comp[i]) != NULL) { msgLen += (tANI_S16)(CFGOBJ_ID_SIZE + CFGOBJ_LEN_SIZE + CFGOBJ_ALIGN(req->length)) ; pMac->ccm.replay.nr_param += 1 ; #ifdef CCM_DEBUG smsLog(pMac, LOGW, FL("cfgId=%d"), req->cfgId); #endif } } if (pMac->ccm.replay.nr_param == 0) { if (callback) { callback((tHalHandle)pMac, WNI_CFG_SUCCESS) ; } status = eHAL_STATUS_SUCCESS ; goto end ; } pMac->ccm.replay.in_progress = 0 ; pMac->ccm.replay.result = WNI_CFG_SUCCESS ; pMac->ccm.replay.callback = callback ; pMac->ccm.replay.done = NULL ; msg = vos_mem_malloc(msgLen); if ( NULL == msg ) { pMac->ccm.replay.started = 0 ; status = eHAL_STATUS_FAILURE; goto end; } msg->type = pal_cpu_to_be16(WNI_CFG_SET_REQ); msg->msgLen = pal_cpu_to_be16(msgLen); /* Encode the starting cfgId */ pl = encodeCfgReq(hHdd, msg->data, CFG_UPDATE_MAGIC_DWORD, 4, NULL, 0, CCM_INTEGER_TYPE) ; /* Encode the saved cfg requests */ for (i = 0 ; i < CFG_PARAM_MAX_NUM ; ++i) { if ((req = pMac->ccm.comp[i]) != NULL) { pl = encodeCfgReq(hHdd, pl, req->cfgId, req->length, req->ccmPtr, req->ccmValue, req->type) ; } } status = palSendMBMessage(hHdd, msg) ; if (status != eHAL_STATUS_SUCCESS) { smsLog(pMac, LOGW, FL("palSendMBMessage() failed. status=%d"), status); pMac->ccm.replay.started = 0 ; //No need to free msg. palSendMBMessage frees it. goto end ; } end: return status ; }
/* This function executes in (Linux) softirq context */ void ccmCfgCnfMsgHandler(tHalHandle hHal, void *m) { tHddHandle hHdd = halHandle2HddHandle(hHal); tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); tSirMbMsg *msg = (tSirMbMsg *)m ; tANI_U32 result, cfgId ; tCfgReq *req, *old ; #if 0 if (pMac->ccm.state != eCCM_STARTED) { return ; } #endif result = pal_be32_to_cpu(msg->data[0]); cfgId = pal_be32_to_cpu(msg->data[1]); if (pMac->ccm.replay.started && cfgId == CFG_UPDATE_MAGIC_DWORD) { pMac->ccm.replay.in_progress = 1 ; return ; } if (pMac->ccm.replay.in_progress) { /* save error code */ if (!CCM_IS_RESULT_SUCCESS(result)) { pMac->ccm.replay.result = result ; } if (--pMac->ccm.replay.nr_param == 0) { pMac->ccm.replay.in_progress = 0 ; if (pMac->ccm.replay.callback) { pMac->ccm.replay.callback(hHal, pMac->ccm.replay.result); } pMac->ccm.replay.started = 0 ; /* Wake up the sleeping process */ #ifdef CCM_DEBUG smsLog(pMac, LOGW, FL("ccmComplete(%p)"), pMac->ccm.replay.done); #endif ccmComplete(hHdd, pMac->ccm.replay.done); //Let go with the rest of the set CFGs waiting. sendQueuedReqToMacSw(pMac, hHdd); } } else { /* * Try to match this response with the request. * What if i could not find the req entry ??? */ req = pMac->ccm.reqQ.head ; if (req) { if (req->cfgId == cfgId && req->state == eCCM_REQ_SENT) { palSpinLockTake(hHdd, pMac->ccm.lock); del_req(req, &pMac->ccm.reqQ); palSpinLockGive(hHdd, pMac->ccm.lock); req->state = eCCM_REQ_DONE ; if (result == WNI_CFG_NEED_RESTART || result == WNI_CFG_NEED_RELOAD) { #ifdef CCM_DEBUG smsLog(pMac, LOGW, FL("need restart/reload, cfgId=%d"), req->cfgId) ; #endif //purgeReqQ(hHal); } /* invoke callback */ if (req->callback) { #ifdef CCM_DEBUG req->callback(hHal, cfgId) ; #else req->callback(hHal, result) ; #endif } /* Wake up the sleeping process */ #ifdef CCM_DEBUG smsLog(pMac, LOGW, FL("cfgId=%ld, calling ccmComplete(%p)"), cfgId, req->done); #endif ccmComplete(hHdd, req->done); /* move the completed req from reqQ to comp[] */ if (req->toBeSaved && (CCM_IS_RESULT_SUCCESS(result))) { if (cfgId < CFG_PARAM_MAX_NUM) { if ((old = pMac->ccm.comp[cfgId]) != NULL) { freeCfgReq(hHdd, old) ; } pMac->ccm.comp[cfgId] = req ; } } else { freeCfgReq(hHdd, req) ; } sendQueuedReqToMacSw(pMac, hHdd); } else { smsLog( pMac, LOGW, FL("can not match RSP with REQ, rspcfgid=%d result=%d reqcfgid=%d reqstate=%d"), (int)cfgId, (int)result, req->cfgId, req->state); #ifdef CCM_DEBUG smsLog(pMac, LOGW, FL("ccmComplete(%p)"), req->done); #endif } } } return ; }
static eHalStatus cfgSetSub(tpAniSirGlobal pMac, tHddHandle hHdd, tANI_U32 cfgId, tANI_U32 type, tANI_S32 length, void *ccmPtr, tANI_U32 ccmValue, tCcmCfgSetCallback callback, eAniBoolean toBeSaved, void *sem, tCfgReq **r) { eHalStatus status = eHAL_STATUS_SUCCESS; tCfgReq *req ; do { *r = NULL ; if (pMac->ccm.state == eCCM_STOPPED) { status = eHAL_STATUS_FAILURE ; break ; } req = allocateCfgReq(hHdd, type, length); if (req == NULL) { status = eHAL_STATUS_FAILED_ALLOC ; break ; } req->next = NULL ; req->cfgId = (tANI_U16)cfgId ; req->type = (tANI_U8)type ; req->state = eCCM_REQ_QUEUED ; req->toBeSaved = !!toBeSaved ; req->length = length ; req->done = sem ; req->callback = callback ; if (type == CCM_INTEGER_TYPE) { req->ccmValue = ccmValue ; } else { vos_mem_copy((void *)req->ccmPtr, (void *)ccmPtr, length); } palSpinLockTake(hHdd, pMac->ccm.lock); add_req_tail(req, &pMac->ccm.reqQ); /* If this is the first req on the queue, send it to MAC SW */ if ((pMac->ccm.replay.started == 0) && (pMac->ccm.reqQ.head == req)) { /* Send WNI_CFG_SET_REQ */ req->state = eCCM_REQ_SENT; palSpinLockGive(hHdd, pMac->ccm.lock); status = sendCfg(pMac, hHdd, req, eANI_BOOLEAN_TRUE) ; if (status != eHAL_STATUS_SUCCESS) { smsLog( pMac, LOGW, FL("sendCfg() failed")); palSpinLockTake(hHdd, pMac->ccm.lock); del_req(req, &pMac->ccm.reqQ); palSpinLockGive(hHdd, pMac->ccm.lock); freeCfgReq(hHdd, req); break ; } else { palSpinLockTake(hHdd, pMac->ccm.lock); if(req != pMac->ccm.reqQ.head) { //We send the request and it must be done already req = NULL; } palSpinLockGive(hHdd, pMac->ccm.lock); } } else { palSpinLockGive(hHdd, pMac->ccm.lock); } *r = req ; } while(0) ; return status; }
void ccmCfgCnfMsgHandler(tHalHandle hHal, void *m) { tHddHandle hHdd = halHandle2HddHandle(hHal); tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); tSirMbMsg *msg = (tSirMbMsg *)m ; tANI_U32 result, cfgId ; tCfgReq *req, *old ; #if 0 if (pMac->ccm.state != eCCM_STARTED) { return ; } #endif result = pal_be32_to_cpu(msg->data[0]); cfgId = pal_be32_to_cpu(msg->data[1]); if (pMac->ccm.replay.started && cfgId == CFG_UPDATE_MAGIC_DWORD) { pMac->ccm.replay.in_progress = 1 ; return ; } if (pMac->ccm.replay.in_progress) { if (!CCM_IS_RESULT_SUCCESS(result)) { pMac->ccm.replay.result = result ; } if (--pMac->ccm.replay.nr_param == 0) { pMac->ccm.replay.in_progress = 0 ; if (pMac->ccm.replay.callback) { pMac->ccm.replay.callback(hHal, pMac->ccm.replay.result); } pMac->ccm.replay.started = 0 ; #ifdef CCM_DEBUG smsLog(pMac, LOGW, FL("ccmComplete(%p)"), pMac->ccm.replay.done); #endif ccmComplete(hHdd, pMac->ccm.replay.done); sendQueuedReqToMacSw(pMac, hHdd); } } else { req = pMac->ccm.reqQ.head ; if (req) { if (req->cfgId == cfgId && req->state == eCCM_REQ_SENT) { palSpinLockTake(hHdd, pMac->ccm.lock); del_req(req, &pMac->ccm.reqQ); palSpinLockGive(hHdd, pMac->ccm.lock); req->state = eCCM_REQ_DONE ; if (result == WNI_CFG_NEED_RESTART || result == WNI_CFG_NEED_RELOAD) { #ifdef CCM_DEBUG smsLog(pMac, LOGW, FL("need restart/reload, cfgId=%d"), req->cfgId) ; #endif } if (req->callback) { #ifdef CCM_DEBUG req->callback(hHal, cfgId) ; #else req->callback(hHal, result) ; #endif } #ifdef CCM_DEBUG smsLog(pMac, LOGW, FL("cfgId=%ld, calling ccmComplete(%p)"), cfgId, req->done); #endif ccmComplete(hHdd, req->done); if (req->toBeSaved && (CCM_IS_RESULT_SUCCESS(result))) { if (cfgId < CFG_PARAM_MAX_NUM) { if ((old = pMac->ccm.comp[cfgId]) != NULL) { freeCfgReq(hHdd, old) ; } pMac->ccm.comp[cfgId] = req ; } } else { freeCfgReq(hHdd, req) ; } sendQueuedReqToMacSw(pMac, hHdd); } else { smsLog( pMac, LOGW, FL("can not match RSP with REQ, rspcfgid=%d result=%d reqcfgid=%d reqstate=%d"), (int)cfgId, (int)result, req->cfgId, req->state); #ifdef CCM_DEBUG smsLog(pMac, LOGW, FL("ccmComplete(%p)"), req->done); #endif } } } return ; }