static int parseRsnKeyDesc(tAniPacket *packet, tAniEapolRsnKeyDesc **rsnDescPtr) { int retVal = ANI_OK; int len; v_U8_t *bytes; tAniEapolRsnKeyDesc *rsnDesc = NULL; do { aniAsfPacketTruncateFromFront(packet, 1); // Desc-Type rsnDesc = (tAniEapolRsnKeyDesc *) vos_mem_malloc( sizeof(tAniEapolRsnKeyDesc) ); if (rsnDesc == NULL) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Supp could not malloc EAPOL-Key Descriptor for RSN\n"); retVal = ANI_E_MALLOC_FAILED; break; } retVal = parseRsnKeyInfo(packet, &rsnDesc->info); if (retVal != ANI_OK) break; retVal = aniAsfPacketGet16(packet, &rsnDesc->keyLen); if (retVal != ANI_OK) { break; } len = sizeof(rsnDesc->replayCounter); retVal = aniAsfPacketGetN(packet, len, &bytes); if (retVal != ANI_OK) { break; } vos_mem_copy(rsnDesc->replayCounter, bytes, len); len = sizeof(rsnDesc->keyNonce); retVal = aniAsfPacketGetN(packet, len, &bytes); if (retVal != ANI_OK) { break; } vos_mem_copy(rsnDesc->keyNonce, bytes, len); len = sizeof(rsnDesc->keyIv); retVal = aniAsfPacketGetN(packet, len, &bytes); if (retVal != ANI_OK) { break; } vos_mem_copy(rsnDesc->keyIv, bytes, len); len = sizeof(rsnDesc->keyRecvSeqCounter); retVal = aniAsfPacketGetN(packet, len, &bytes); if (retVal != ANI_OK) { break; } vos_mem_copy(rsnDesc->keyRecvSeqCounter, bytes, len); len = sizeof(rsnDesc->keyId); retVal = aniAsfPacketGetN(packet, len, &bytes); if (retVal != ANI_OK) { break; } vos_mem_copy(rsnDesc->keyId, bytes, len); len = sizeof(rsnDesc->keyMic); retVal = aniAsfPacketGetN(packet, len, &bytes); if (retVal != ANI_OK) { break; } vos_mem_copy(rsnDesc->keyMic, bytes, len); retVal = aniAsfPacketGet16(packet, &rsnDesc->keyDataLen); if (retVal != ANI_OK) { break; } len = rsnDesc->keyDataLen; if (len > 0) { // We have a key retVal = aniAsfPacketGetN(packet, len, &bytes); if (retVal != ANI_OK) { break; } rsnDesc->keyData = (v_U8_t*)vos_mem_malloc(len); if (rsnDesc->keyData == NULL) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Could not allocate RSN key bytes!\n"); VOS_ASSERT( 0 ); retVal = ANI_E_MALLOC_FAILED; break; } vos_mem_copy(rsnDesc->keyData, bytes, len); } else { rsnDesc->keyData = NULL; } *rsnDescPtr = rsnDesc; }while( 0 ); if( !ANI_IS_STATUS_SUCCESS( retVal ) ) { vos_mem_free(rsnDesc); } return retVal; }
/** * __wcnss_patterngen_write() - write pattern * @file: file pointer * @buf: buffer * @count: count * @ppos: position pointer * * Return: 0 on success, error number otherwise */ static ssize_t __wcnss_patterngen_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { hdd_adapter_t *pAdapter; hdd_context_t *pHddCtx; tSirAddPeriodicTxPtrn *addPeriodicTxPtrnParams; tSirDelPeriodicTxPtrn *delPeriodicTxPtrnParams; char *cmd, *sptr, *token; v_U8_t pattern_idx = 0; v_U8_t pattern_duration = 0; char *pattern_buf; v_U16_t pattern_len = 0; v_U16_t i = 0; int ret; ENTER(); pAdapter = (hdd_adapter_t *)file->private_data; if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s: Invalid adapter or adapter has invalid magic.", __func__); return -EINVAL; } pHddCtx = WLAN_HDD_GET_CTX(pAdapter); ret = wlan_hdd_validate_context(pHddCtx); if (0 != ret) return ret; if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN)) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Periodic Tx Pattern Offload feature is not supported " "in firmware!", __func__); return -EINVAL; } /* Get command from user */ if (count <= MAX_USER_COMMAND_SIZE_FRAME) cmd = vos_mem_malloc(count + 1); else { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Command length is larger than %d bytes.", __func__, MAX_USER_COMMAND_SIZE_FRAME); return -EINVAL; } if (!cmd) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Memory allocation for cmd failed!", __func__); return -EFAULT; } if (copy_from_user(cmd, buf, count)) { vos_mem_free(cmd); return -EFAULT; } cmd[count] = '\0'; sptr = cmd; /* Get pattern idx */ token = strsep(&sptr, " "); if (!token) goto failure; if (kstrtou8(token, 0, &pattern_idx)) goto failure; if (pattern_idx > (MAXNUM_PERIODIC_TX_PTRNS - 1)) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Pattern index %d is not in the range (0 ~ %d).", __func__, pattern_idx, MAXNUM_PERIODIC_TX_PTRNS - 1); goto failure; } /* Get pattern duration */ token = strsep(&sptr, " "); if (!token) goto failure; if (kstrtou8(token, 0, &pattern_duration)) goto failure; /* Delete pattern using index if duration is 0 */ if (!pattern_duration) { delPeriodicTxPtrnParams = vos_mem_malloc(sizeof(tSirDelPeriodicTxPtrn)); if (!delPeriodicTxPtrnParams) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Memory allocation for delPeriodicTxPtrnParams " "failed!", __func__); vos_mem_free(cmd); return -EFAULT; } delPeriodicTxPtrnParams->ucPtrnId = pattern_idx; delPeriodicTxPtrnParams->ucPatternIdBitmap = 1 << pattern_idx; vos_mem_copy(delPeriodicTxPtrnParams->macAddress, pAdapter->macAddressCurrent.bytes, 6); /* Delete pattern */ if (eHAL_STATUS_SUCCESS != sme_DelPeriodicTxPtrn(pHddCtx->hHal, delPeriodicTxPtrnParams)) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: sme_DelPeriodicTxPtrn() failed!", __func__); vos_mem_free(delPeriodicTxPtrnParams); goto failure; } vos_mem_free(cmd); vos_mem_free(delPeriodicTxPtrnParams); return count; } /* Check if it's in connected state only when adding patterns */ if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Not in Connected state!", __func__); goto failure; } /* Get pattern */ token = strsep(&sptr, " "); if (!token) goto failure; pattern_buf = token; pattern_buf[strlen(pattern_buf) - 1] = '\0'; pattern_len = strlen(pattern_buf); /* Since the pattern is a hex string, 2 characters represent 1 byte. */ if (pattern_len % 2) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Malformed pattern!", __func__); goto failure; } else pattern_len >>= 1; if (pattern_len < 14 || pattern_len > PERIODIC_TX_PTRN_MAX_SIZE) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Not an 802.3 frame!", __func__); goto failure; } addPeriodicTxPtrnParams = vos_mem_malloc(sizeof(tSirAddPeriodicTxPtrn)); if (!addPeriodicTxPtrnParams) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Memory allocation for addPeriodicTxPtrnParams " "failed!", __func__); vos_mem_free(cmd); return -EFAULT; } addPeriodicTxPtrnParams->ucPtrnId = pattern_idx; addPeriodicTxPtrnParams->usPtrnIntervalMs = pattern_duration * 500; addPeriodicTxPtrnParams->ucPtrnSize = pattern_len; vos_mem_copy(addPeriodicTxPtrnParams->macAddress, pAdapter->macAddressCurrent.bytes, 6); /* Extract the pattern */ for(i = 0; i < addPeriodicTxPtrnParams->ucPtrnSize; i++) { addPeriodicTxPtrnParams->ucPattern[i] = (hdd_parse_hex(pattern_buf[0]) << 4) + hdd_parse_hex(pattern_buf[1]); /* Skip to next byte */ pattern_buf += 2; } /* Add pattern */ if (eHAL_STATUS_SUCCESS != sme_AddPeriodicTxPtrn(pHddCtx->hHal, addPeriodicTxPtrnParams)) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: sme_AddPeriodicTxPtrn() failed!", __func__); vos_mem_free(addPeriodicTxPtrnParams); goto failure; } vos_mem_free(cmd); vos_mem_free(addPeriodicTxPtrnParams); EXIT(); return count; failure: vos_mem_free(cmd); return -EINVAL; }
eHalStatus sme_FTSendUpdateKeyInd(tHalHandle hHal, tANI_U32 sessionId, tCsrRoamSetKey * pFTKeyInfo) { tSirFTUpdateKeyInfo *pMsg; tANI_U16 msgLen; eHalStatus status = eHAL_STATUS_FAILURE; tAniEdType tmpEdType; tSirKeyMaterial *keymaterial = NULL; tAniEdType edType; tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG int i = 0; smsLog(pMac, LOG1, FL("keyLength %d"), pFTKeyInfo->keyLength); for (i=0; i<pFTKeyInfo->keyLength; i++) smsLog(pMac, LOG1, FL("%02x"), pFTKeyInfo->Key[i]); #endif if(pFTKeyInfo->keyLength > CSR_MAX_KEY_LEN) { smsLog( pMac, LOGE, "%s: invalid keyLength %d", __func__,pFTKeyInfo->keyLength); return eHAL_STATUS_FAILURE; } msgLen = sizeof(tSirFTUpdateKeyInfo); pMsg = vos_mem_malloc(msgLen); if ( NULL == pMsg ) { return eHAL_STATUS_FAILURE; } vos_mem_set(pMsg, msgLen, 0); pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_FT_UPDATE_KEY); pMsg->length = pal_cpu_to_be16(msgLen); keymaterial = &pMsg->keyMaterial; keymaterial->length = pFTKeyInfo->keyLength; edType = csrTranslateEncryptTypeToEdType( pFTKeyInfo->encType ); tmpEdType = pal_cpu_to_be32(edType); keymaterial->edType = tmpEdType; // Set the pMsg->keyMaterial.length field (this length is defined as all // data that follows the edType field // in the tSirKeyMaterial keyMaterial; field). // // !!NOTE: This keyMaterial.length contains the length of a MAX size key, // though the keyLength can be // shorter than this max size. Is LIM interpreting this ok ? keymaterial->numKeys = 1; keymaterial->key[ 0 ].keyId = pFTKeyInfo->keyId; keymaterial->key[ 0 ].unicast = (tANI_U8)eANI_BOOLEAN_TRUE; keymaterial->key[ 0 ].keyDirection = pFTKeyInfo->keyDirection; vos_mem_copy(&keymaterial->key[ 0 ].keyRsc, pFTKeyInfo->keyRsc, CSR_MAX_RSC_LEN); keymaterial->key[ 0 ].paeRole = pFTKeyInfo->paeRole; keymaterial->key[ 0 ].keyLength = pFTKeyInfo->keyLength; if (pFTKeyInfo->keyLength) { vos_mem_copy(&keymaterial->key[ 0 ].key, pFTKeyInfo->Key, pFTKeyInfo->keyLength); if(pFTKeyInfo->keyLength == 16) { smsLog(pMac, LOG1, "SME Set Update Ind keyIdx (%d) encType(%d) key = " "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X", pMsg->keyMaterial.key[0].keyId, (tAniEdType)pMsg->keyMaterial.edType, pMsg->keyMaterial.key[0].key[0], pMsg->keyMaterial.key[0].key[1], pMsg->keyMaterial.key[0].key[2], pMsg->keyMaterial.key[0].key[3], pMsg->keyMaterial.key[0].key[4], pMsg->keyMaterial.key[0].key[5], pMsg->keyMaterial.key[0].key[6], pMsg->keyMaterial.key[0].key[7], pMsg->keyMaterial.key[0].key[8], pMsg->keyMaterial.key[0].key[9], pMsg->keyMaterial.key[0].key[10], pMsg->keyMaterial.key[0].key[11], pMsg->keyMaterial.key[0].key[12], pMsg->keyMaterial.key[0].key[13], pMsg->keyMaterial.key[0].key[14], pMsg->keyMaterial.key[0].key[15]); } } vos_mem_copy( &pMsg->bssId[ 0 ], &pFTKeyInfo->peerMac[ 0 ], sizeof(tCsrBssid) ); pMsg->smeSessionId = sessionId; smsLog(pMac, LOG1, "BSSID = "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pMsg->bssId)); status = palSendMBMessage(pMac->hHdd, pMsg); return( status ); }
VOS_STATUS WLANBAP_InitLinkSupervision ( ptBtampHandle btampHandle ) { VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; vos_pkt_t *pLSReqPacket; vos_pkt_t *pLSRepPacket; v_U16_t lsPktln; if ( NULL == pBtampCtx) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Invalid BAP handle value in %s", __FUNCTION__); return VOS_STATUS_E_FAULT; } #if 0 /* Initialize Link supervision data structure */ vos_mem_set(pLsInfo, sizeof(tBtampLS),0); /* Allocate memory for Static Tx Data */ pLsInfo->pTxPktData = vos_mem_malloc(sizeof(tBtampLsPktData)+TX_LS_DATALEN); /* Initialize Static data for LS pkt Tx */ pLsInfo->pTxPktData->BufLen = TX_LS_DATALEN; vos_mem_copy (&pLsInfo->pTxPktData->pBuf, LsTxData, pLsInfo->pTxPktData->BufLen); #endif pBtampCtx->lsReqPktPending = VOS_FALSE; pBtampCtx->retries = 0; vosStatus = WLANBAP_AcquireLSPacket( pBtampCtx, &pLSReqPacket,32, TRUE ); if( VOS_IS_STATUS_SUCCESS( vosStatus ) ) { pBtampCtx->lsReqPacket = pLSReqPacket; } else { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, "%s:AcquireLSPacket failed\n",__FUNCTION__); pBtampCtx->lsReqPacket = NULL; return vosStatus; } vosStatus = WLANBAP_AcquireLSPacket( pBtampCtx, &pLSRepPacket,32,FALSE ); if( VOS_IS_STATUS_SUCCESS( vosStatus ) ) { pBtampCtx->lsRepPacket = pLSRepPacket; } else { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, "%s:AcquireLSPacket failed\n",__FUNCTION__); pBtampCtx->lsRepPacket = NULL; return vosStatus; } vosStatus = vos_pkt_get_packet_length(pBtampCtx->lsRepPacket,&lsPktln); if ( VOS_STATUS_SUCCESS != vosStatus ) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, "%s:vos_pkt_get_length error",__FUNCTION__); return VOS_STATUS_E_FAULT; } pBtampCtx->lsPktln = lsPktln; /* Start Link Supervision Timer if not configured for infinite */ if (pBtampCtx->bapLinkSupervisionTimerInterval) { vosStatus = WLANBAP_StartLinkSupervisionTimer (pBtampCtx, pBtampCtx->bapLinkSupervisionTimerInterval * WLANBAP_BREDR_BASEBAND_SLOT_TIME); } else { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, "%s:No LS configured for infinite",__FUNCTION__); } return vosStatus; }
/* --------------------------------------------------------------------------- \fn oemData_OemDataReq \brief Request an OEM DATA RSP \param sessionId - Id of session to be used \param pOemDataReqID - pointer to an object to get back the request ID \param callback - a callback function that is called upon finish \param pContext - a pointer passed in for the callback \return eHalStatus -------------------------------------------------------------------------------*/ eHalStatus oemData_OemDataReq(tHalHandle hHal, tANI_U8 sessionId, tOemDataReqConfig *oemDataReqConfig, tANI_U32 *pOemDataReqID, oemData_OemDataReqCompleteCallback callback, void *pContext) { eHalStatus status = eHAL_STATUS_SUCCESS; tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); tSmeCmd *pOemDataCmd = NULL; do { if( !CSR_IS_SESSION_VALID( pMac, sessionId ) ) { status = eHAL_STATUS_FAILURE; break; } pMac->oemData.oemDataReqConfig.sessionId = sessionId; pMac->oemData.callback = callback; pMac->oemData.pContext = pContext; pMac->oemData.oemDataReqID = *(pOemDataReqID); vos_mem_copy((v_VOID_t*)(pMac->oemData.oemDataReqConfig.oemDataReq), (v_VOID_t*)(oemDataReqConfig->oemDataReq), OEM_DATA_REQ_SIZE); pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE; pOemDataCmd = smeGetCommandBuffer(pMac); //fill up the command before posting it. if(pOemDataCmd) { pOemDataCmd->command = eSmeCommandOemDataReq; pOemDataCmd->u.oemDataCmd.callback = callback; pOemDataCmd->u.oemDataCmd.pContext = pContext; pOemDataCmd->u.oemDataCmd.oemDataReqID = pMac->oemData.oemDataReqID; //set the oem data request pOemDataCmd->u.oemDataCmd.oemDataReq.sessionId = pMac->oemData.oemDataReqConfig.sessionId; vos_mem_copy((v_VOID_t*)(pOemDataCmd->u.oemDataCmd.oemDataReq.oemDataReq), (v_VOID_t*)(pMac->oemData.oemDataReqConfig.oemDataReq), OEM_DATA_REQ_SIZE); } else { status = eHAL_STATUS_FAILURE; break; } //now queue this command in the sme command queue //Here since this is not interacting with the csr just push the command //into the sme queue. Also push this command with the normal priority smePushCommand(pMac, pOemDataCmd, eANI_BOOLEAN_FALSE); } while(0); if(!HAL_STATUS_SUCCESS(status) && pOemDataCmd) { oemData_ReleaseOemDataReqCommand(pMac, pOemDataCmd, eOEM_DATA_REQ_FAILURE); pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE; } return status; }
int wlan_log_to_user(VOS_TRACE_LEVEL log_level, char *to_be_sent, int length) { /* Add the current time stamp */ char *ptr; char tbuf[100]; int tlen; int total_log_len; unsigned int *pfilled_length; bool wake_up_thread = false; unsigned long flags; struct timeval tv; struct rtc_time tm; unsigned long local_time; u64 qtimer_ticks; if (!vos_is_multicast_logging()) { /* * This is to make sure that we print the logs to kmsg console * when no logger app is running. This is also needed to * log the initial messages during loading of driver where even * if app is running it will not be able to * register with driver immediately and start logging all the * messages. */ pr_err("%s\n", to_be_sent); } else { /* Format the Log time [hr:min:sec.microsec] */ do_gettimeofday(&tv); /* Convert rtc to local time */ local_time = (u32)(tv.tv_sec - (sys_tz.tz_minuteswest * 60)); rtc_time_to_tm(local_time, &tm); /* Firmware Time Stamp */ qtimer_ticks = arch_counter_get_cntpct(); tlen = snprintf(tbuf, sizeof(tbuf), "[%02d:%02d:%02d.%06lu] [%016llX]" " [%.5s] ", tm.tm_hour, tm.tm_min, tm.tm_sec, tv.tv_usec, qtimer_ticks, current->comm); /* 1+1 indicate '\n'+'\0' */ total_log_len = length + tlen + 1 + 1; spin_lock_irqsave(&gwlan_logging.spin_lock, flags); // wlan logging svc resources are not yet initialized if (!gwlan_logging.pcur_node) { spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); return -EIO; } pfilled_length = &gwlan_logging.pcur_node->filled_length; /* Check if we can accomodate more log into current node/buffer */ if (MAX_LOGMSG_LENGTH < (*pfilled_length + sizeof(tAniNlHdr) + total_log_len)) { wake_up_thread = true; wlan_queue_logmsg_for_app(); pfilled_length = &gwlan_logging.pcur_node->filled_length; } ptr = &gwlan_logging.pcur_node->logbuf[sizeof(tAniHdr)]; /* Assumption here is that we receive logs which is always less than * MAX_LOGMSG_LENGTH, where we can accomodate the * tAniNlHdr + [context][timestamp] + log * VOS_ASSERT if we cannot accomodate the the complete log into * the available buffer. * * Continue and copy logs to the available length and discard the rest. */ if (MAX_LOGMSG_LENGTH < (sizeof(tAniNlHdr) + total_log_len)) { VOS_ASSERT(0); total_log_len = MAX_LOGMSG_LENGTH - sizeof(tAniNlHdr) - 2; } vos_mem_copy(&ptr[*pfilled_length], tbuf, tlen); vos_mem_copy(&ptr[*pfilled_length + tlen], to_be_sent, min(length, (total_log_len - tlen))); *pfilled_length += tlen + min(length, total_log_len - tlen); ptr[*pfilled_length] = '\n'; *pfilled_length += 1; spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); /* Wakeup logger thread */ if ((true == wake_up_thread)) { /* If there is logger app registered wakeup the logging * thread */ set_bit(HOST_LOG_POST, &gwlan_logging.event_flag); wake_up_interruptible(&gwlan_logging.wait_queue); } if (gwlan_logging.log_fe_to_console && ((VOS_TRACE_LEVEL_FATAL == log_level) || (VOS_TRACE_LEVEL_ERROR == log_level))) { pr_err("%s %s\n",tbuf, to_be_sent); } } return 0; }
static int send_filled_buffers_to_user(void) { int ret = -1; struct log_msg *plog_msg; int payload_len; int tot_msg_len; tAniNlHdr *wnl; struct sk_buff *skb = NULL; struct nlmsghdr *nlh; static int nlmsg_seq; unsigned long flags; static int rate_limit; while (!list_empty(&gwlan_logging.filled_list) && !gwlan_logging.exit) { skb = dev_alloc_skb(MAX_LOGMSG_LENGTH); if (skb == NULL) { if (!rate_limit) { pr_err("%s: dev_alloc_skb() failed for msg size[%d] drop count = %u\n", __func__, MAX_LOGMSG_LENGTH, gwlan_logging.drop_count); } rate_limit = 1; ret = -ENOMEM; break; } rate_limit = 0; spin_lock_irqsave(&gwlan_logging.spin_lock, flags); plog_msg = (struct log_msg *) (gwlan_logging.filled_list.next); list_del_init(gwlan_logging.filled_list.next); spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); /* 4 extra bytes for the radio idx */ payload_len = plog_msg->filled_length + sizeof(wnl->radio) + sizeof(tAniHdr); tot_msg_len = NLMSG_SPACE(payload_len); nlh = nlmsg_put(skb, 0, nlmsg_seq++, ANI_NL_MSG_LOG, payload_len, NLM_F_REQUEST); if (NULL == nlh) { spin_lock_irqsave(&gwlan_logging.spin_lock, flags); list_add_tail(&plog_msg->node, &gwlan_logging.free_list); spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); pr_err("%s: drop_count = %u\n", __func__, ++gwlan_logging.drop_count); pr_err("%s: nlmsg_put() failed for msg size[%d]\n", __func__, tot_msg_len); dev_kfree_skb(skb); skb = NULL; ret = -EINVAL; continue; } wnl = (tAniNlHdr *) nlh; wnl->radio = plog_msg->radio; vos_mem_copy(&wnl->wmsg, plog_msg->logbuf, plog_msg->filled_length + sizeof(tAniHdr)); spin_lock_irqsave(&gwlan_logging.spin_lock, flags); list_add_tail(&plog_msg->node, &gwlan_logging.free_list); spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); ret = nl_srv_bcast(skb); if (ret < 0) { if (__ratelimit(&errCnt)) { pr_info("%s: Send Failed %d drop_count = %u\n", __func__, ret, gwlan_logging.drop_count); } gwlan_logging.drop_count++; skb = NULL; break; } else { skb = NULL; ret = 0; } } return ret; }
int iw_set_cscan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ; hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); tCsrScanRequest scanRequest; v_U32_t scanId = 0; eHalStatus status = eHAL_STATUS_SUCCESS; v_U8_t channelIdx; ENTER(); VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter !!!",__func__); #ifdef WLAN_BTAMP_FEATURE //Scan not supported when AMP traffic is on. if( VOS_TRUE == WLANBAP_AmpSessionOn() ) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: No scanning when AMP is on",__func__); return eHAL_STATUS_SUCCESS; } #endif if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__); return eHAL_STATUS_SUCCESS; } vos_mem_zero( &scanRequest, sizeof(scanRequest)); if (NULL != wrqu->data.pointer) { char *str_ptr = NULL; tCsrSSIDInfo *SsidInfo = NULL; int num_ssid = 0; int i, j, ssid_start; hdd_scan_pending_option_e scanPendingOption = WEXT_SCAN_PENDING_GIVEUP; str_ptr = extra; i = WEXT_CSCAN_HEADER_SIZE; if( WEXT_CSCAN_PENDING_SECTION == str_ptr[i] ) { scanPendingOption = (hdd_scan_pending_option_e)str_ptr[++i]; ++i; } pHddCtx->scan_info.scan_pending_option = scanPendingOption; if(pHddCtx->scan_info.mScanPending == TRUE) { hddLog(LOG1,"%s: mScanPending is TRUE",__func__); /* If any scan is pending, just giveup this scan request */ if(WEXT_SCAN_PENDING_GIVEUP == scanPendingOption) { pHddCtx->scan_info.waitScanResult = FALSE; return eHAL_STATUS_SUCCESS; } /* If any scan pending, wait till finish current scan, and try this scan request when previous scan finish */ else if(WEXT_SCAN_PENDING_DELAY == scanPendingOption) { pHddCtx->scan_info.waitScanResult = TRUE; vos_event_reset(&pHddCtx->scan_info.scan_finished_event); if(vos_wait_single_event(&pHddCtx->scan_info.scan_finished_event, WEXT_CSCAN_SCAN_DONE_WAIT_TIME)) { hddLog(LOG1,"%s: Previous SCAN does not finished on time",__func__); return eHAL_STATUS_SUCCESS; } } /* Piggyback previous scan result */ else if(WEXT_SCAN_PENDING_PIGGYBACK == scanPendingOption) { pHddCtx->scan_info.waitScanResult = TRUE; return eHAL_STATUS_SUCCESS; } } pHddCtx->scan_info.waitScanResult = FALSE; /* Check for scan IE */ while( WEXT_CSCAN_SSID_SECTION == str_ptr[i] ) { /* ssid_len */ if(str_ptr[++i] != WEXT_CSCAN_CHANNEL_SECTION) { /* total number of ssid's */ num_ssid++; /* increment length filed */ i += str_ptr[i] + 1; } /* i should be saved and it will be pointing to 'C' */ } VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: numSsid %d !!!",__func__, num_ssid); if( num_ssid ) { /* To be fixed in SME and PE: override the number of ssid with 1, * as SME and PE does not handle multiple SSID in scan request * */ scanRequest.SSIDs.numOfSSIDs = num_ssid; /* Allocate num_ssid tCsrSSIDInfo structure */ SsidInfo = scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(num_ssid*sizeof(tCsrSSIDInfo)); if(NULL == scanRequest.SSIDs.SSIDList) { hddLog(VOS_TRACE_LEVEL_ERROR, "memory alloc failed SSIDInfo buffer"); return -ENOMEM; } /* copy all the ssid's and their length */ ssid_start = WEXT_CSCAN_HEADER_SIZE + 1;/* skipping 'S' */ for(j = 0; j < num_ssid; j++) { if( SIR_MAC_MAX_SSID_LENGTH < str_ptr[ssid_start]){ scanRequest.SSIDs.numOfSSIDs -= 1; } else{ /* get the ssid length */ SsidInfo->SSID.length = str_ptr[ssid_start++]; vos_mem_copy(SsidInfo->SSID.ssId, &str_ptr[ssid_start], SsidInfo->SSID.length); hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s\n", j, SsidInfo->SSID.ssId); } /* skipping length */ ssid_start += str_ptr[ssid_start - 1] + 1; /* Store next ssid info */ SsidInfo++; } } /* Check for Channel IE */ if ( WEXT_CSCAN_CHANNEL_SECTION == str_ptr[i]) { if( str_ptr[++i] == 0 ) { scanRequest.ChannelInfo.numOfChannels = 0; scanRequest.ChannelInfo.ChannelList = NULL; i++; } else { /* increment the counter */ scanRequest.ChannelInfo.numOfChannels = str_ptr[i++]; /* store temp channel list */ /* SME expects 1 byte channel content */ scanRequest.ChannelInfo.ChannelList = vos_mem_malloc(scanRequest.ChannelInfo.numOfChannels * sizeof(v_U8_t)); if(NULL == scanRequest.ChannelInfo.ChannelList) { hddLog(LOGE, "memory alloc failed for channel list creation"); status = -ENOMEM; goto exit_point; } for(channelIdx = 0; channelIdx < scanRequest.ChannelInfo.numOfChannels; channelIdx++) { /* SCAN request from upper layer has 2 bytes channel */ scanRequest.ChannelInfo.ChannelList[channelIdx] = (v_U8_t)str_ptr[i]; i += sizeof(v_U16_t); } } } /* Set default */ scanRequest.scanType = eSIR_ACTIVE_SCAN; scanRequest.minChnTime = 0; scanRequest.maxChnTime = 0; /* Now i is pointing to passive dwell dwell time */ /* 'P',min dwell time, max dwell time */ /* next two offsets contain min and max channel time */ if( WEXT_CSCAN_PASV_DWELL_SECTION == (str_ptr[i]) ) { /* No SSID specified, num_ssid == 0, then start paasive scan */ if (!num_ssid || (eSIR_PASSIVE_SCAN == pHddCtx->scan_info.scan_mode)) { scanRequest.scanType = eSIR_PASSIVE_SCAN; scanRequest.minChnTime = (v_U8_t)str_ptr[++i];//scanReq->min_channel_time; scanRequest.maxChnTime = (v_U8_t)str_ptr[++i];//scanReq->max_channel_time; i++; } else { i += 3; } } /* H indicates active channel time */ if( WEXT_CSCAN_HOME_DWELL_SECTION == (str_ptr[i]) ) { if (num_ssid || (eSIR_ACTIVE_SCAN == pHddCtx->scan_info.scan_mode)) { scanRequest.scanType = eSIR_ACTIVE_SCAN; scanRequest.minChnTime = str_ptr[++i];//scanReq->min_channel_time; scanRequest.maxChnTime = str_ptr[++i];//scanReq->max_channel_time; i++; } else { i +=3; } } scanRequest.BSSType = eCSR_BSS_TYPE_ANY; /* set requestType to full scan */ scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN; pHddCtx->scan_info.mScanPending = TRUE; /* if previous genIE is not NULL, update ScanIE */ if(0 != pwextBuf->genIE.length) { memset( &pHddCtx->scan_info.scanAddIE, 0, sizeof(pHddCtx->scan_info.scanAddIE) ); memcpy( pHddCtx->scan_info.scanAddIE.addIEdata, pwextBuf->genIE.addIEdata, pwextBuf->genIE.length ); pHddCtx->scan_info.scanAddIE.length = pwextBuf->genIE.length; pwextBuf->roamProfile.pAddIEScan = pHddCtx->scan_info.scanAddIE.addIEdata; pwextBuf->roamProfile.nAddIEScanLength = pHddCtx->scan_info.scanAddIE.length; /* clear previous genIE after use it */ memset( &pwextBuf->genIE, 0, sizeof(pwextBuf->genIE) ); } /* push addIEScan in scanRequset if exist */ if (pHddCtx->scan_info.scanAddIE.addIEdata && pHddCtx->scan_info.scanAddIE.length) { scanRequest.uIEFieldLen = pHddCtx->scan_info.scanAddIE.length; scanRequest.pIEField = pHddCtx->scan_info.scanAddIE.addIEdata; } status = sme_ScanRequest( (WLAN_HDD_GET_CTX(pAdapter))->hHal, pAdapter->sessionId,&scanRequest, &scanId, &hdd_ScanRequestCallback, dev ); if( !HAL_STATUS_SUCCESS(status) ) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s: SME scan fail status %d !!!",__func__, status); pHddCtx->scan_info.mScanPending = FALSE; status = -EINVAL; goto exit_point; } pHddCtx->scan_info.scanId = scanId; } //end of data->pointer else { status = -1; } exit_point: /* free ssidlist */ if (scanRequest.SSIDs.SSIDList) { vos_mem_free(scanRequest.SSIDs.SSIDList); } /* free the channel list */ if(scanRequest.ChannelInfo.ChannelList) { vos_mem_free((void*)scanRequest.ChannelInfo.ChannelList); } EXIT(); VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__); return status; }
/** * @brief wpalMemoryCopy - copy memory * @param dest address which data is copied to * @param src address which data is copied from * @param size number of bytes to copy * * @return wpt_status * eWLAN_PAL_STATUS_SUCCESS * eWLAN_PAL_STATUS_INVALID_PARAM */ wpt_status wpalMemoryCopy(void * dest, void * src, wpt_uint32 size) { vos_mem_copy( dest, src, size ); return eWLAN_PAL_STATUS_SUCCESS; }
static eHalStatus hdd_IndicateScanResult(hdd_scan_info_t *scanInfo, tCsrScanResultInfo *scan_result) { hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(scanInfo->dev) ; tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); tSirBssDescription *descriptor = &scan_result->BssDescriptor; struct iw_event event; char *current_event = scanInfo->start; char *end = scanInfo->end; char *last_event; char *current_pad; v_U16_t ie_length = 0; v_U16_t capabilityInfo; char *modestr; int error; char custom[MAX_CUSTOM_LEN]; char *p; hddLog( LOG1, "hdd_IndicateScanResult " MAC_ADDRESS_STR, MAC_ADDR_ARRAY(descriptor->bssId)); error = 0; last_event = current_event; vos_mem_zero(&event, sizeof (event)); /* BSSID */ event.cmd = SIOCGIWAP; event.u.ap_addr.sa_family = ARPHRD_ETHER; vos_mem_copy (event.u.ap_addr.sa_data, descriptor->bssId, sizeof (descriptor->bssId)); current_event = iwe_stream_add_event(scanInfo->info,current_event, end, &event, IW_EV_ADDR_LEN); if (last_event == current_event) { /* no space to add event */ /* Error code may be E2BIG */ hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWAP "); return -E2BIG; } last_event = current_event; vos_mem_zero(&event, sizeof (struct iw_event)); /* Protocol Name */ event.cmd = SIOCGIWNAME; switch (descriptor->nwType) { case eSIR_11A_NW_TYPE: modestr = "a"; break; case eSIR_11B_NW_TYPE: modestr = "b"; break; case eSIR_11G_NW_TYPE: modestr = "g"; break; case eSIR_11N_NW_TYPE: modestr = "n"; break; default: hddLog( LOGW, "%s: Unknown network type [%d]", __func__, descriptor->nwType); modestr = "?"; break; } snprintf(event.u.name, IFNAMSIZ, "IEEE 802.11%s", modestr); current_event = iwe_stream_add_event(scanInfo->info,current_event, end, &event, IW_EV_CHAR_LEN); if (last_event == current_event) { /* no space to add event */ hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWNAME"); /* Error code, may be E2BIG */ return -E2BIG; } last_event = current_event; vos_mem_zero( &event, sizeof (struct iw_event)); /*Freq*/ event.cmd = SIOCGIWFREQ; event.u.freq.m = descriptor->channelId; event.u.freq.e = 0; event.u.freq.i = 0; current_event = iwe_stream_add_event(scanInfo->info,current_event, end, &event, IW_EV_FREQ_LEN); if (last_event == current_event) { /* no space to add event */ hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWFREQ"); return -E2BIG; } last_event = current_event; vos_mem_zero( &event, sizeof (struct iw_event)); /* BSS Mode */ event.cmd = SIOCGIWMODE; capabilityInfo = descriptor->capabilityInfo; if (SIR_MAC_GET_ESS(capabilityInfo)) { event.u.mode = IW_MODE_INFRA; } else if (SIR_MAC_GET_IBSS(capabilityInfo)) { event.u.mode = IW_MODE_ADHOC; } else { /* neither ESS or IBSS */ event.u.mode = IW_MODE_AUTO; } current_event = iwe_stream_add_event(scanInfo->info,current_event, end, &event, IW_EV_UINT_LEN); if (last_event == current_event) { /* no space to add event */ hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWMODE"); return -E2BIG; } /* To extract SSID */ ie_length = GET_IE_LEN_IN_BSS( descriptor->length ); if (ie_length > 0) { /* dot11BeaconIEs is a large struct, so we make it static to avoid stack overflow. This API is only invoked via ioctl, so it is serialized by the kernel rtnl_lock and hence does not need to be reentrant */ static tDot11fBeaconIEs dot11BeaconIEs; tDot11fIESSID *pDot11SSID; tDot11fIESuppRates *pDot11SuppRates; tDot11fIEExtSuppRates *pDot11ExtSuppRates; tDot11fIEHTCaps *pDot11IEHTCaps; int numBasicRates = 0; int maxNumRates = 0; pDot11IEHTCaps = NULL; dot11fUnpackBeaconIEs ((tpAniSirGlobal) hHal, (tANI_U8 *) descriptor->ieFields, ie_length, &dot11BeaconIEs); pDot11SSID = &dot11BeaconIEs.SSID; if (pDot11SSID->present ) { last_event = current_event; vos_mem_zero (&event, sizeof (struct iw_event)); event.cmd = SIOCGIWESSID; event.u.data.flags = 1; event.u.data.length = scan_result->ssId.length; current_event = iwe_stream_add_point (scanInfo->info,current_event, end, &event, (char *)scan_result->ssId.ssId); if(last_event == current_event) { /* no space to add event */ hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWESSID"); return -E2BIG; } } if( hdd_GetWPARSNIEs( ( tANI_U8 *) descriptor->ieFields, ie_length, &last_event, ¤t_event, scanInfo ) < 0 ) { hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWESSID"); return -E2BIG; } last_event = current_event; current_pad = current_event + IW_EV_LCP_LEN; vos_mem_zero( &event, sizeof (struct iw_event)); /*Rates*/ event.cmd = SIOCGIWRATE; pDot11SuppRates = &dot11BeaconIEs.SuppRates; if (pDot11SuppRates->present ) { int i; numBasicRates = pDot11SuppRates->num_rates; for (i=0; i<pDot11SuppRates->num_rates; i++) { if (0 != (pDot11SuppRates->rates[i] & 0x7F)) { event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate ( &pDot11SuppRates->rates[i]); current_pad = iwe_stream_add_value (scanInfo->info,current_event, current_pad, end, &event, IW_EV_PARAM_LEN); } } } pDot11ExtSuppRates = &dot11BeaconIEs.ExtSuppRates; if (pDot11ExtSuppRates->present ) { int i,no_of_rates; maxNumRates = numBasicRates + pDot11ExtSuppRates->num_rates; /* Check to make sure the total number of rates doesn't exceed IW_MAX_BITRATES */ maxNumRates = VOS_MIN(maxNumRates , IW_MAX_BITRATES); if((maxNumRates - numBasicRates) > MAX_RATES) { no_of_rates = MAX_RATES; hddLog( LOGW, "Accessing array out of bound that array is pDot11ExtSuppRates->rates "); } else { no_of_rates = maxNumRates - numBasicRates; } for ( i=0; i< no_of_rates ; i++ ) { if (0 != (pDot11ExtSuppRates->rates[i] & 0x7F)) { event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate ( &pDot11ExtSuppRates->rates[i]); current_pad = iwe_stream_add_value (scanInfo->info,current_event, current_pad, end, &event, IW_EV_PARAM_LEN); } } } if ((current_pad - current_event) >= IW_EV_LCP_LEN) { current_event = current_pad; } else { if (last_event == current_event) { /* no space to add event */ hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWRATE"); return -E2BIG; } } last_event = current_event; vos_mem_zero (&event, sizeof (struct iw_event)); event.cmd = SIOCGIWENCODE; if (SIR_MAC_GET_PRIVACY(capabilityInfo)) { event.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; } else { event.u.data.flags = IW_ENCODE_DISABLED; } event.u.data.length = 0; current_event = iwe_stream_add_point(scanInfo->info,current_event, end, &event, (char *)pDot11SSID->ssid); if(last_event == current_event) { /* no space to add event Error code, may be E2BIG */ hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWENCODE"); return -E2BIG; } } last_event = current_event; vos_mem_zero( &event, sizeof (struct iw_event)); /*RSSI*/ event.cmd = IWEVQUAL; event.u.qual.qual = descriptor->rssi; event.u.qual.noise = descriptor->sinr; /*To keep the rssi icon of the connected AP in the scan window *and the rssi icon of the wireless networks in sync */ if (( eConnectionState_Associated == pAdapter->sessionCtx.station.conn_info.connState ) && ( VOS_TRUE == vos_mem_compare(descriptor->bssId, pAdapter->sessionCtx.station.conn_info.bssId, WNI_CFG_BSSID_LEN))) { event.u.qual.level = pAdapter->rssi; } else { event.u.qual.level = VOS_MIN ((descriptor->rssi + descriptor->sinr), 0); } event.u.qual.updated = IW_QUAL_ALL_UPDATED; current_event = iwe_stream_add_event(scanInfo->info,current_event, end, &event, IW_EV_QUAL_LEN); if(last_event == current_event) { /* no space to add event */ hddLog( LOGW, "hdd_IndicateScanResult: no space for IWEVQUAL"); return -E2BIG; } /* AGE */ event.cmd = IWEVCUSTOM; p = custom; p += scnprintf(p, MAX_CUSTOM_LEN, " Age: %lu", vos_timer_get_system_ticks() - descriptor->nReceivedTime); event.u.data.length = p - custom; current_event = iwe_stream_add_point (scanInfo->info,current_event, end, &event, custom); if(last_event == current_event) { /* no space to add event */ hddLog( LOGW, "hdd_IndicateScanResult: no space for IWEVCUSTOM (age)"); return -E2BIG; } scanInfo->start = current_event; return 0; }
int iw_set_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ; hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); tCsrScanRequest scanRequest; v_U32_t scanId = 0; eHalStatus status = eHAL_STATUS_SUCCESS; struct iw_scan_req *scanReq = (struct iw_scan_req *)extra; ENTER(); VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter !!!",__func__); #ifdef WLAN_BTAMP_FEATURE //Scan not supported when AMP traffic is on. if( VOS_TRUE == WLANBAP_AmpSessionOn() ) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: No scanning when AMP is on",__func__); return eHAL_STATUS_SUCCESS; } #endif if(pHddCtx->scan_info.mScanPending == TRUE) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:mScanPending is TRUE !!!",__func__); return eHAL_STATUS_SUCCESS; } if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__); return eHAL_STATUS_SUCCESS; } vos_mem_zero( &scanRequest, sizeof(scanRequest)); if (NULL != wrqu->data.pointer) { /* set scanType, active or passive */ if ((IW_SCAN_TYPE_ACTIVE == scanReq->scan_type) || (eSIR_ACTIVE_SCAN == pHddCtx->scan_info.scan_mode)) { scanRequest.scanType = eSIR_ACTIVE_SCAN; } else { scanRequest.scanType = eSIR_PASSIVE_SCAN; } /* set bssid using sockaddr from iw_scan_req */ vos_mem_copy(scanRequest.bssid, &scanReq->bssid.sa_data, sizeof(scanRequest.bssid) ); if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { if(scanReq->essid_len) { scanRequest.SSIDs.numOfSSIDs = 1; scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo)); if(scanRequest.SSIDs.SSIDList) { scanRequest.SSIDs.SSIDList->SSID.length = scanReq->essid_len; vos_mem_copy(scanRequest.SSIDs.SSIDList-> SSID.ssId,scanReq->essid,scanReq->essid_len); } else { scanRequest.SSIDs.numOfSSIDs = 0; VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Unable to allocate memory",__func__); VOS_ASSERT(0); } } } /* set min and max channel time */ scanRequest.minChnTime = scanReq->min_channel_time; scanRequest.maxChnTime = scanReq->max_channel_time; } else { if(pHddCtx->scan_info.scan_mode == eSIR_ACTIVE_SCAN) { /* set the scan type to active */ scanRequest.scanType = eSIR_ACTIVE_SCAN; } else { scanRequest.scanType = eSIR_PASSIVE_SCAN; } vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff ); /* set min and max channel time to zero */ scanRequest.minChnTime = 0; scanRequest.maxChnTime = 0; } /* set BSSType to default type */ scanRequest.BSSType = eCSR_BSS_TYPE_ANY; /*Scan all the channels */ scanRequest.ChannelInfo.numOfChannels = 0; scanRequest.ChannelInfo.ChannelList = NULL; /* set requestType to full scan */ scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN; /* if previous genIE is not NULL, update ScanIE */ if (0 != pwextBuf->genIE.length) { memset( &pHddCtx->scan_info.scanAddIE, 0, sizeof(pHddCtx->scan_info.scanAddIE) ); memcpy( pHddCtx->scan_info.scanAddIE.addIEdata, pwextBuf->genIE.addIEdata, pwextBuf->genIE.length ); pHddCtx->scan_info.scanAddIE.length = pwextBuf->genIE.length; pwextBuf->roamProfile.pAddIEScan = pHddCtx->scan_info.scanAddIE.addIEdata; pwextBuf->roamProfile.nAddIEScanLength = pHddCtx->scan_info.scanAddIE.length; /* clear previous genIE after use it */ memset( &pwextBuf->genIE, 0, sizeof(pwextBuf->genIE) ); } /* push addIEScan in scanRequset if exist */ if (pHddCtx->scan_info.scanAddIE.addIEdata && pHddCtx->scan_info.scanAddIE.length) { scanRequest.uIEFieldLen = pHddCtx->scan_info.scanAddIE.length; scanRequest.pIEField = pHddCtx->scan_info.scanAddIE.addIEdata; } status = sme_ScanRequest( (WLAN_HDD_GET_CTX(pAdapter))->hHal, pAdapter->sessionId,&scanRequest, &scanId, &hdd_ScanRequestCallback, dev ); if (!HAL_STATUS_SUCCESS(status)) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:sme_ScanRequest fail %d!!!",__func__, status); goto error; } pHddCtx->scan_info.mScanPending = TRUE; pHddCtx->scan_info.scanId = scanId; error: if ((wrqu->data.flags & IW_SCAN_THIS_ESSID) && (scanReq->essid_len)) vos_mem_free(scanRequest.SSIDs.SSIDList); EXIT(); VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__); return status; }
tSirRetStatus schAppendAddnIE(tpAniSirGlobal pMac, tpPESession psessionEntry, tANI_U8 *pFrame, tANI_U32 maxBeaconSize, tANI_U32 *nBytes) { tSirRetStatus status = eSIR_FAILURE; tANI_U32 present, len; tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN]; if((status = wlan_cfgGetInt(pMac, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, &present)) != eSIR_SUCCESS) { limLog(pMac, LOGP, FL("Unable to get WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG")); return status; } if(present) { if((status = wlan_cfgGetStrLen(pMac, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS) { limLog(pMac, LOGP, FL("Unable to get WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA length")); return status; } if(len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len && ((len + *nBytes) <= maxBeaconSize)) { if((status = wlan_cfgGetStr(pMac, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0], &len)) == eSIR_SUCCESS) { #ifdef WLAN_FEATURE_P2P tANI_U8* pP2pIe = limGetP2pIEPtr(pMac, &addIE[0], len); if(pP2pIe != NULL) { tANI_U8 noaLen = 0; tANI_U8 noaStream[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN]; //get NoA attribute stream P2P IE noaLen = limGetNoaAttrStream(pMac, noaStream, psessionEntry); if(noaLen) { if(noaLen + len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN) { vos_mem_copy(&addIE[len], noaStream, noaLen); len += noaLen; /* Update IE Len */ pP2pIe[1] += noaLen; } else { limLog(pMac, LOGE, FL("Not able to insert NoA because of length constraint")); } } } #endif vos_mem_copy(pFrame, &addIE[0], len); *nBytes = *nBytes + len; } } } return status; }
void hddDevTmLevelChangedHandler(struct device *dev, int changedTmLevel) { hdd_context_t *pHddCtx = NULL; WLAN_TmLevelEnumType newTmLevel = changedTmLevel; hdd_adapter_t *staAdapater; pHddCtx = (hdd_context_t*)wcnss_wlan_get_drvdata(dev); if ((pHddCtx->tmInfo.currentTmLevel == newTmLevel) || (!pHddCtx->cfg_ini->thermalMitigationEnable)) { VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_WARN, "%s: TM Not enabled %d or Level does not changed %d", __func__, pHddCtx->cfg_ini->thermalMitigationEnable, newTmLevel); return; } if (~VOS_STA & pHddCtx->concurrency_mode) { VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR, "%s: CMODE 0x%x, TM disable", __func__, pHddCtx->concurrency_mode); newTmLevel = WLAN_HDD_TM_LEVEL_0; } if ((newTmLevel < WLAN_HDD_TM_LEVEL_0) || (newTmLevel >= WLAN_HDD_TM_LEVEL_MAX)) { VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR, "%s: TM level %d out of range", __func__, newTmLevel); return; } if (newTmLevel != WLAN_HDD_TM_LEVEL_4) sme_SetTmLevel(pHddCtx->hHal, newTmLevel, 0); if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock)) { VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR, "%s: Acquire lock fail", __func__); return; } pHddCtx->tmInfo.currentTmLevel = newTmLevel; pHddCtx->tmInfo.txFrameCount = 0; vos_mem_copy(&pHddCtx->tmInfo.tmAction, &thermalMigrationAction[newTmLevel], sizeof(hdd_tmLevelAction_t)); if (pHddCtx->tmInfo.tmAction.enterImps) { staAdapater = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); if (staAdapater) { if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(staAdapater))) { sme_RoamDisconnect(pHddCtx->hHal, staAdapater->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED); } } } mutex_unlock(&pHddCtx->tmInfo.tmOperationLock); return; }
static int writeRsnKeyMic(v_U32_t cryptHandle, tAniPacket *eapolFrame, tAniEapolRsnKeyDesc *rsnDesc, v_U8_t *micKey, v_U32_t micKeyLen) { int retVal = ANI_OK; int len; v_U8_t *ptr = NULL; v_U8_t *micPos = NULL; v_U8_t result[VOS_DIGEST_SHA1_SIZE]; // Larger of the two // Sanity check the arguments and return if no MIC generation is // needed if (micKey != NULL) { if (micKeyLen == 0 || !rsnDesc->info.micFlag) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Supp MIC key provided but micKeyLen or micFlag is not set!\n"); VOS_ASSERT( 0 ); return ANI_E_ILLEGAL_ARG; } } else { if (rsnDesc->info.micFlag) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Supp micFlag is set but MIC key not provided!\n"); VOS_ASSERT( 0 ); return ANI_E_ILLEGAL_ARG; } // Normal condition where MIC is not desired by the caller return ANI_OK; } len = aniAsfPacketGetBytes(eapolFrame, &ptr); if( !ANI_IS_STATUS_SUCCESS( len ) ) { return len; } micPos = ptr + ANI_SSM_RSN_KEY_MIC_OFFSET + SNAP_HEADER_SIZE; // Clear the MIC field in the packet before the MIC computation vos_mem_zero( micPos, VOS_DIGEST_MD5_SIZE); // Skip to the EAPOL version field for MIC computation ptr += EAPOL_VERSION_POS + SNAP_HEADER_SIZE; len -= (EAPOL_VERSION_POS + SNAP_HEADER_SIZE); if (rsnDesc->info.keyDescVers == ANI_EAPOL_KEY_DESC_VERS_AES) { if( VOS_IS_STATUS_SUCCESS( vos_sha1_hmac_str(cryptHandle, ptr, len, micKey, micKeyLen, result) ) ) { retVal = ANI_OK; } else { retVal = ANI_ERROR; } } else { VOS_ASSERT( 0 ); retVal = ANI_E_ILLEGAL_ARG; } if (retVal == ANI_OK) { // Copy only 16B which is the smaller of the two and the same as // ANI_EAPOL_KEY_RSN_MIC_SIZE vos_mem_copy(micPos, result, VOS_DIGEST_MD5_SIZE); } return retVal; }
static void ibss_peer_collect( tpAniSirGlobal pMac, tpSchBeaconStruct pBeacon, tpSirMacMgmtHdr pHdr, tLimIbssPeerNode *pPeer, tpPESession psessionEntry) { vos_mem_copy(pPeer->peerMacAddr, pHdr->sa, sizeof(tSirMacAddr)); pPeer->capabilityInfo = pBeacon->capabilityInfo; pPeer->extendedRatesPresent = pBeacon->extendedRatesPresent; pPeer->edcaPresent = pBeacon->edcaPresent; pPeer->wmeEdcaPresent = pBeacon->wmeEdcaPresent; pPeer->wmeInfoPresent = pBeacon->wmeInfoPresent; if(IS_DOT11_MODE_HT(psessionEntry->dot11mode) && (pBeacon->HTCaps.present)) { pPeer->htCapable = pBeacon->HTCaps.present; vos_mem_copy((tANI_U8 *)pPeer->supportedMCSSet, (tANI_U8 *)pBeacon->HTCaps.supportedMCSSet, sizeof(pPeer->supportedMCSSet)); pPeer->htGreenfield = (tANI_U8)pBeacon->HTCaps.greenField; pPeer->htSupportedChannelWidthSet = ( tANI_U8 ) pBeacon->HTCaps.supportedChannelWidthSet; pPeer->htMIMOPSState = (tSirMacHTMIMOPowerSaveState)pBeacon->HTCaps.mimoPowerSave; pPeer->htMaxAmsduLength = ( tANI_U8 ) pBeacon->HTCaps.maximalAMSDUsize; pPeer->htAMpduDensity = pBeacon->HTCaps.mpduDensity; pPeer->htDsssCckRate40MHzSupport = (tANI_U8)pBeacon->HTCaps.dsssCckMode40MHz; pPeer->htShortGI20Mhz = (tANI_U8)pBeacon->HTCaps.shortGI20MHz; pPeer->htShortGI40Mhz = (tANI_U8)pBeacon->HTCaps.shortGI40MHz; pPeer->htMaxRxAMpduFactor = pBeacon->HTCaps.maxRxAMPDUFactor; pPeer->htSecondaryChannelOffset = pBeacon->HTInfo.secondaryChannelOffset; } #ifdef WLAN_FEATURE_11AC if ( pBeacon->VHTCaps.present ) { pPeer->vhtSupportedChannelWidthSet = pBeacon->VHTOperation.chanWidth; pPeer->vhtCapable = pBeacon->VHTCaps.present; vos_mem_copy((tANI_U8 *) &pPeer->VHTCaps, (tANI_U8 *) &pBeacon->VHTCaps, sizeof(tDot11fIEVHTCaps)); } #endif pPeer->erpIePresent = pBeacon->erpPresent; vos_mem_copy((tANI_U8 *) &pPeer->supportedRates, (tANI_U8 *) &pBeacon->supportedRates, pBeacon->supportedRates.numRates + 1); if (pPeer->extendedRatesPresent) vos_mem_copy((tANI_U8 *) &pPeer->extendedRates, (tANI_U8 *) &pBeacon->extendedRates, pBeacon->extendedRates.numRates + 1); else pPeer->extendedRates.numRates = 0; pPeer->next = NULL; }
/** * Implements the AES Key Unwrap algorithm described in RFC 3394. * If (n+1) is the number of blocks in cipherText, of size * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, then the output value is (n+1) * blocks. The actual plaintext consists of n blocks that start at the * second block. Note: It is the caller's responsibility to free the * returned value. * * @param cipherText the cipertext data to unwrap * @param len the length of the ciphertext, which must be a multiple of * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE. * @param keyEncKey the encryption key * @param keyEncKeyLen the length of keyEncKey * @param plainTextPtr is set to a newly allocated array containing * the result if the operation succeeds. It is the caller's * responsibility to free this. * * @return ANI_OK if the operation succeeds */ int aniSsmAesKeyUnwrap(v_U32_t cryptHandle, tANI_U8 *cipherText, tANI_U32 len, tANI_U8 *keyEncKey, tANI_U32 keyEncKeyLen, tANI_U8 **plainTextPtr) { int i, j; int retVal; tANI_U8 a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE]; tANI_U8 *r = NULL; tANI_U32 n; tANI_U32 t; tANI_U8 b[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE*2]; n = len / ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE - 1; if ((len % ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE) != 0) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Illegal number of input bytes to AES Key Unwrap!"); return ANI_E_ILLEGAL_ARG; } // Allocate enough storage for 'A' as well as 'R' r = vos_mem_malloc((n + 1) * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); if (r == NULL) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Could not allocate space for R"); return ANI_E_MALLOC_FAILED; } vos_mem_copy(a, cipherText, sizeof(a)); vos_mem_copy(r + ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, cipherText + ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, len - ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); for (j = 5; j >= 0; j--) { for (i = n; i >= 1; i--) { t = n*j + i; xor(a, t); retVal = aes_1(cryptHandle, keyEncKey, keyEncKeyLen, a, r + i*ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, b); if( !ANI_IS_STATUS_SUCCESS( retVal) ) goto error; vos_mem_copy(a, b, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); vos_mem_copy(r + i*ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, b + sizeof(b) - ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); } } if (vos_mem_compare2(a, gAniSsmAesKeyWrapIv, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE) != 0) { retVal = ANI_E_MIC_FAILED; goto error; } *plainTextPtr = r; return ANI_OK; error: if (r != NULL) vos_mem_free(r); return retVal; }
eHalStatus limCollectBssDescription(tpAniSirGlobal pMac, tSirBssDescription *pBssDescr, tpSirProbeRespBeacon pBPR, tANI_U8 *pRxPacketInfo) #endif { tANI_U8 *pBody; tANI_U32 ieLen = 0; tpSirMacMgmtHdr pHdr; tANI_U8 channelNum; tANI_U8 rxChannel; tANI_U8 rfBand = 0; pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); VOS_ASSERT(WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) >= SIR_MAC_B_PR_SSID_OFFSET); ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) - SIR_MAC_B_PR_SSID_OFFSET; rxChannel = WDA_GET_RX_CH(pRxPacketInfo); pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); rfBand = WDA_GET_RX_RFBAND(pRxPacketInfo); /** * Drop all the beacons and probe response without P2P IE during P2P search */ if (NULL != pMac->lim.gpLimMlmScanReq && pMac->lim.gpLimMlmScanReq->p2pSearch) { if (NULL == limGetP2pIEPtr(pMac, (pBody + SIR_MAC_B_PR_SSID_OFFSET), ieLen)) { limLog( pMac, LOG3, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pHdr->bssId)); return eHAL_STATUS_FAILURE; } } /** * Length of BSS desription is without length of * length itself and length of pointer * that holds the next BSS description */ pBssDescr->length = (tANI_U16)( sizeof(tSirBssDescription) - sizeof(tANI_U16) - sizeof(tANI_U32) + ieLen); // Copy BSS Id vos_mem_copy((tANI_U8 *) &pBssDescr->bssId, (tANI_U8 *) pHdr->bssId, sizeof(tSirMacAddr)); // Copy Timestamp, Beacon Interval and Capability Info pBssDescr->scanSysTimeMsec = vos_timer_get_system_time(); pBssDescr->timeStamp[0] = pBPR->timeStamp[0]; pBssDescr->timeStamp[1] = pBPR->timeStamp[1]; pBssDescr->beaconInterval = pBPR->beaconInterval; pBssDescr->capabilityInfo = limGetU16((tANI_U8 *) &pBPR->capabilityInfo); if(!pBssDescr->beaconInterval ) { limLog(pMac, LOGW, FL("Beacon Interval is ZERO, making it to default 100 " MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->bssId)); pBssDescr->beaconInterval= 100; } /* * There is a narrow window after Channel Switch msg is sent to HAL and before the AGC is shut * down and beacons/Probe Rsps can trickle in and we may report the incorrect channel in 5Ghz * band, so not relying on the 'last Scanned Channel' stored in LIM. * Instead use the value returned by RXP in BD. This the the same value which HAL programs into * RXP before every channel switch. * Right now there is a problem in 5Ghz, where we are receiving beacons from a channel different from * the currently scanned channel. so incorrect channel is reported to CSR and association does not happen. * So for now we keep on looking for the channel info in the beacon (DSParamSet IE OR HT Info IE), and only if it * is not present in the beacon, we go for the channel info present in RXP. * This fix will work for 5Ghz 11n devices, but for 11a devices, we have to rely on RXP routing flag to get the correct channel. * So The problem of incorrect channel reporting in 5Ghz will still remain for 11a devices. */ pBssDescr->channelId = limGetChannelFromBeacon(pMac, pBPR); if (pBssDescr->channelId == 0) { /* If the channel Id is not retrieved from Beacon, extract the channel from BD */ /* Unmapped the channel.This We have to do since we have done mapping in the hal to overcome the limitation of RXBD of not able to accomodate the bigger channel number.*/ if ((!rfBand) || IS_5G_BAND(rfBand)) { rxChannel = limUnmapChannel(rxChannel); } if (!rxChannel) { rxChannel = pMac->lim.gLimCurrentScanChannelId; } pBssDescr->channelId = rxChannel; } pBssDescr->channelIdSelf = pBssDescr->channelId; //set the network type in bss description channelNum = pBssDescr->channelId; pBssDescr->nwType = limGetNwType(pMac, channelNum, SIR_MAC_MGMT_FRAME, pBPR); pBssDescr->aniIndicator = pBPR->propIEinfo.aniIndicator; // Copy RSSI & SINR from BD PELOG4(limLog(pMac, LOG4, "***********BSS Description for BSSID:*********** "); sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, pBssDescr->bssId, 6 ); sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG4, (tANI_U8*)pRxPacketInfo, 36 );)
/* * TDLS Message processor, will be called after TDLS message recieved from * PE */ eHalStatus tdlsMsgProcessor(tpAniSirGlobal pMac, v_U16_t msgType, void *pMsgBuf) { switch(msgType) { case eWNI_SME_TDLS_SEND_MGMT_RSP: { /* remove pending eSmeCommandTdlsDiscovery command */ csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsSendMgmt) ; } break; case eWNI_SME_TDLS_ADD_STA_RSP: { tSirTdlsAddStaRsp *addStaRsp = (tSirTdlsAddStaRsp *) pMsgBuf ; eCsrRoamResult roamResult ; tCsrRoamInfo roamInfo = {0} ; vos_mem_copy( &roamInfo.peerMac, addStaRsp->peerMac, sizeof(tSirMacAddr)) ; roamInfo.staId = addStaRsp->staId ; roamInfo.ucastSig = addStaRsp->ucastSig ; roamInfo.bcastSig = addStaRsp->bcastSig ; roamInfo.statusCode = addStaRsp->statusCode ; /* * register peer with TL, we have to go through HDD as this is * the only way to register any STA with TL. */ if (addStaRsp->tdlsAddOper == TDLS_OPER_ADD) roamResult = eCSR_ROAM_RESULT_ADD_TDLS_PEER; else /* addStaRsp->tdlsAddOper must be TDLS_OPER_UPDATE */ roamResult = eCSR_ROAM_RESULT_UPDATE_TDLS_PEER; csrRoamCallCallback(pMac, addStaRsp->sessionId, &roamInfo, 0, eCSR_ROAM_TDLS_STATUS_UPDATE, roamResult); /* remove pending eSmeCommandTdlsDiscovery command */ csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsAddPeer) ; } break; case eWNI_SME_TDLS_DEL_STA_RSP: { tSirTdlsDelStaRsp *delStaRsp = (tSirTdlsDelStaRsp *) pMsgBuf ; tCsrRoamInfo roamInfo = {0} ; vos_mem_copy( &roamInfo.peerMac, delStaRsp->peerMac, sizeof(tSirMacAddr)) ; roamInfo.staId = delStaRsp->staId ; roamInfo.statusCode = delStaRsp->statusCode ; /* * register peer with TL, we have to go through HDD as this is * the only way to register any STA with TL. */ csrRoamCallCallback(pMac, delStaRsp->sessionId, &roamInfo, 0, eCSR_ROAM_TDLS_STATUS_UPDATE, eCSR_ROAM_RESULT_DELETE_TDLS_PEER); csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsDelPeer) ; } break; case eWNI_SME_TDLS_DEL_STA_IND: { tpSirTdlsDelStaInd pSirTdlsDelStaInd = (tpSirTdlsDelStaInd) pMsgBuf ; tCsrRoamInfo roamInfo = {0} ; vos_mem_copy( &roamInfo.peerMac, pSirTdlsDelStaInd->peerMac, sizeof(tSirMacAddr)) ; roamInfo.staId = pSirTdlsDelStaInd->staId ; roamInfo.reasonCode = pSirTdlsDelStaInd->reasonCode ; /* Sending the TEARDOWN indication to HDD. */ csrRoamCallCallback(pMac, pSirTdlsDelStaInd->sessionId, &roamInfo, 0, eCSR_ROAM_TDLS_STATUS_UPDATE, eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND); break ; } case eWNI_SME_TDLS_DEL_ALL_PEER_IND: { tpSirTdlsDelAllPeerInd pSirTdlsDelAllPeerInd = (tpSirTdlsDelAllPeerInd) pMsgBuf ; tCsrRoamInfo roamInfo = {0} ; /* Sending the TEARDOWN indication to HDD. */ csrRoamCallCallback(pMac, pSirTdlsDelAllPeerInd->sessionId, &roamInfo, 0, eCSR_ROAM_TDLS_STATUS_UPDATE, eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND); break ; } case eWNI_SME_MGMT_FRM_TX_COMPLETION_IND: { tpSirMgmtTxCompletionInd pSirTdlsDelAllPeerInd = (tpSirMgmtTxCompletionInd) pMsgBuf ; tCsrRoamInfo roamInfo = {0} ; roamInfo.reasonCode = pSirTdlsDelAllPeerInd->txCompleteStatus; csrRoamCallCallback(pMac, pSirTdlsDelAllPeerInd->sessionId, &roamInfo, 0, eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND, 0); break; } case eWNI_SME_TDLS_LINK_ESTABLISH_RSP: { tSirTdlsLinkEstablishReqRsp *linkEstablishReqRsp = (tSirTdlsLinkEstablishReqRsp *) pMsgBuf ; tCsrRoamInfo roamInfo = {0} ; #if 0 vos_mem_copy(&roamInfo.peerMac, delStaRsp->peerMac, sizeof(tSirMacAddr)) ; roamInfo.staId = delStaRsp->staId ; roamInfo.statusCode = delStaRsp->statusCode ; #endif csrRoamCallCallback(pMac, linkEstablishReqRsp->sessionId, &roamInfo, 0, eCSR_ROAM_TDLS_STATUS_UPDATE, eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP); /* remove pending eSmeCommandTdlsLinkEstablish command */ csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsLinkEstablish); break; } #ifdef FEATURE_WLAN_TDLS_INTERNAL case eWNI_SME_TDLS_DISCOVERY_START_RSP: { /* remove pending eSmeCommandTdlsDiscovery command */ csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsDiscovery) ; } /* fall through .. */ case eWNI_SME_TDLS_DISCOVERY_START_IND: { tSirTdlsDisRsp *disRsp = (tSirTdlsDisRsp *)pMsgBuf ; if(eSIR_SME_SUCCESS == disRsp->statusCode) { tCsrTdlsCtxStruct *disInfo = &pMac->tdlsCtx ; tANI_U16 disStaCount = disRsp->numDisSta ; tCsrTdlsPeerLinkinfo *peerLinkInfo = NULL ; tANI_U8 i = 0 ; VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, ("DIS START RSP/IND recieved sta count = %d"), disStaCount) ; for( ; i < disStaCount ; i++) { tSirTdlsPeerInfo *peerInfo = &disRsp->tdlsDisPeerInfo[i] ; VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, ("SME, peer MAC: "MAC_ADDRESS_STR), MAC_ADDR_ARRAY(peerInfo->peerMac)); peerLinkInfo = findTdlsPeer(pMac, &disInfo->tdlsPotentialPeerList, peerInfo->peerMac) ; if(NULL == peerLinkInfo) { /* update discovery data base, if this is new entry */ tdlsSaveTdlsPeerInfo(pMac, peerInfo) ; } else { /* update RSSI of existing peer */ tSirTdlsPeerInfo *newPeerInfo = &peerLinkInfo->tdlsDisPeerInfo ; newPeerInfo->tdlsPeerRssi = peerInfo->tdlsPeerRssi ; } } if(0 == i) { smsLog( pMac, LOGW, "there is no tdls client \ discovered .." ) ; } } else {
static int send_data_mgmt_log_pkt_to_user(void) { int ret = -1; int extra_header_len, nl_payload_len; struct sk_buff *skb = NULL; static int nlmsg_seq; vos_pkt_t *current_pkt; vos_pkt_t *next_pkt; VOS_STATUS status = VOS_STATUS_E_FAILURE; unsigned long flags; tAniNlLogHdr msg_header; do { spin_lock_irqsave(&gwlan_logging.data_mgmt_pkt_lock, flags); if (!gwlan_logging.data_mgmt_pkt_queue) { spin_unlock_irqrestore( &gwlan_logging.data_mgmt_pkt_lock, flags); return -EIO; } /* pick first pkt from queued chain */ current_pkt = gwlan_logging.data_mgmt_pkt_queue; /* get the pointer to the next packet in the chain */ status = vos_pkt_walk_packet_chain(current_pkt, &next_pkt, TRUE); /* both "success" and "empty" are acceptable results */ if (!((status == VOS_STATUS_SUCCESS) || (status == VOS_STATUS_E_EMPTY))) { ++gwlan_logging.pkt_drop_cnt; spin_unlock_irqrestore( &gwlan_logging.data_mgmt_pkt_lock, flags); pr_err("%s: Failure walking packet chain", __func__); return -EIO; } /* update queue head with next pkt ptr which could be NULL */ gwlan_logging.data_mgmt_pkt_queue = next_pkt; --gwlan_logging.data_mgmt_pkt_qcnt; spin_unlock_irqrestore(&gwlan_logging.data_mgmt_pkt_lock, flags); status = vos_pkt_get_os_packet(current_pkt, (v_VOID_t **)&skb, TRUE); if (!VOS_IS_STATUS_SUCCESS(status)) { ++gwlan_logging.pkt_drop_cnt; pr_err("%s: Failure extracting skb from vos pkt", __func__); return -EIO; } /*return vos pkt since skb is already detached */ vos_pkt_return_packet(current_pkt); extra_header_len = sizeof(msg_header.radio) + sizeof(tAniHdr) + sizeof(msg_header.frameSize); nl_payload_len = NLMSG_ALIGN(extra_header_len + skb->len); msg_header.nlh.nlmsg_type = ANI_NL_MSG_LOG; msg_header.nlh.nlmsg_len = nl_payload_len; msg_header.nlh.nlmsg_flags = NLM_F_REQUEST; msg_header.nlh.nlmsg_pid = 0; msg_header.nlh.nlmsg_seq = nlmsg_seq++; msg_header.radio = 0; msg_header.wmsg.type = ANI_NL_MSG_LOG_PKT_TYPE; msg_header.wmsg.length = skb->len + sizeof(uint32); msg_header.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES; if (unlikely(skb_headroom(skb) < sizeof(msg_header))) { pr_err("VPKT [%d]: Insufficient headroom, head[%p]," " data[%p], req[%zu]", __LINE__, skb->head, skb->data, sizeof(msg_header)); return -EIO; } vos_mem_copy(skb_push(skb, sizeof(msg_header)), &msg_header, sizeof(msg_header)); ret = nl_srv_bcast(skb); if (ret < 0) { pr_info("%s: Send Failed %d drop_count = %u\n", __func__, ret, ++gwlan_logging.pkt_drop_cnt); } else { ret = 0; } } while (next_pkt); return ret; }
/* * TDLS request API, called from HDD to modify an existing TDLS peer */ eHalStatus csrTdlsChangePeerSta(tHalHandle hHal, tANI_U8 sessionId, tSirMacAddr peerMac, tCsrStaParams *pstaParams) { tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); tSmeCmd *tdlsAddStaCmd ; eHalStatus status = eHAL_STATUS_FAILURE ; if (NULL == pstaParams) return status; //If connected and in Infra. Only then allow this if (CSR_IS_SESSION_VALID( pMac, sessionId ) && csrIsConnStateConnectedInfra( pMac, sessionId ) && (NULL != peerMac)){ tdlsAddStaCmd = csrGetCommandBuffer(pMac) ; if (tdlsAddStaCmd) { tTdlsAddStaCmdInfo *tdlsAddStaCmdInfo = &tdlsAddStaCmd->u.tdlsCmd.u.tdlsAddStaCmdInfo ; tdlsAddStaCmdInfo->tdlsAddOper = TDLS_OPER_UPDATE; tdlsAddStaCmd->sessionId = sessionId; vos_mem_copy(tdlsAddStaCmdInfo->peerMac, peerMac, sizeof(tSirMacAddr)) ; tdlsAddStaCmdInfo->capability = pstaParams->capability; tdlsAddStaCmdInfo->uapsdQueues = pstaParams->uapsd_queues; tdlsAddStaCmdInfo->maxSp = pstaParams->max_sp; vos_mem_copy(tdlsAddStaCmdInfo->extnCapability, pstaParams->extn_capability, sizeof(pstaParams->extn_capability)); tdlsAddStaCmdInfo->htcap_present = pstaParams->htcap_present; if(pstaParams->htcap_present) vos_mem_copy( &tdlsAddStaCmdInfo->HTCap, &pstaParams->HTCap, sizeof(pstaParams->HTCap)); else vos_mem_set(&tdlsAddStaCmdInfo->HTCap, sizeof(pstaParams->HTCap), 0); tdlsAddStaCmdInfo->vhtcap_present = pstaParams->vhtcap_present; if(pstaParams->vhtcap_present) vos_mem_copy( &tdlsAddStaCmdInfo->VHTCap, &pstaParams->VHTCap, sizeof(pstaParams->VHTCap)); else vos_mem_set(&tdlsAddStaCmdInfo->VHTCap, sizeof(pstaParams->VHTCap), 0); tdlsAddStaCmdInfo->supportedRatesLen = pstaParams->supported_rates_len; if (0 != pstaParams->supported_rates_len) vos_mem_copy( &tdlsAddStaCmdInfo->supportedRates, pstaParams->supported_rates, pstaParams->supported_rates_len); tdlsAddStaCmd->command = eSmeCommandTdlsAddPeer; tdlsAddStaCmd->u.tdlsCmd.size = sizeof(tTdlsAddStaCmdInfo) ; smePushCommand(pMac, tdlsAddStaCmd, FALSE) ; status = eHAL_STATUS_SUCCESS ; } } return status ; }
/*---------------------------------------------------------------------------- * Function Declarations and Documentation * -------------------------------------------------------------------------*/ VOS_STATUS WLANBAP_AcquireLSPacket( ptBtampContext pBtampCtx, vos_pkt_t **ppPacket, v_U16_t size, tANI_BOOLEAN isLsReq ) { VOS_STATUS vosStatus; vos_pkt_t *pPacket; WLANBAP_8023HeaderType w8023Header; v_U8_t aucLLCHeader[WLANBAP_LLC_HEADER_LEN]; v_U16_t headerLength; /* The 802.3 frame length*/ v_U16_t protoType; v_U8_t *pData = NULL; if(isLsReq) { protoType = WLANTL_BT_AMP_TYPE_LS_REQ; } else { protoType = WLANTL_BT_AMP_TYPE_LS_REP; } //If success, vosTxLsPacket is the packet and pData points to the head. vosStatus = vos_pkt_get_packet( &pPacket, VOS_PKT_TYPE_TX_802_11_MGMT,size, 1, VOS_TRUE, NULL, NULL ); if( VOS_IS_STATUS_SUCCESS( vosStatus ) ) { vosStatus = vos_pkt_reserve_head( pPacket, (v_VOID_t *)&pData, size ); if( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "%s: failed to reserve size = %d\n",__FUNCTION__, size ); vos_pkt_return_packet( pPacket ); } } if( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_LinkSupervisionTimerHandler failed to get vos_pkt\n" ); return vosStatus; } // Form the 802.3 header vos_mem_copy( w8023Header.vDA, pBtampCtx->peer_mac_addr, VOS_MAC_ADDR_SIZE); vos_mem_copy( w8023Header.vSA, pBtampCtx->self_mac_addr, VOS_MAC_ADDR_SIZE); headerLength = WLANBAP_LLC_HEADER_LEN; /* Now the 802.3 length field is big-endian?! */ w8023Header.usLenType = vos_cpu_to_be16(headerLength); /* Now adjust the protocol type bytes*/ protoType = vos_cpu_to_be16( protoType); /* Now form the LLC header */ vos_mem_copy(aucLLCHeader, WLANBAP_LLC_HEADER, sizeof(WLANBAP_LLC_HEADER)); vos_mem_copy(&aucLLCHeader[WLANBAP_LLC_OUI_OFFSET], WLANBAP_BT_AMP_OUI, WLANBAP_LLC_OUI_SIZE); vos_mem_copy(&aucLLCHeader[WLANBAP_LLC_PROTO_TYPE_OFFSET], &protoType, //WLANBAP_BT_AMP_TYPE_LS_REQ WLANBAP_LLC_PROTO_TYPE_SIZE); /* Push on the LLC header */ vos_pkt_push_head(pPacket, aucLLCHeader, WLANBAP_LLC_HEADER_LEN); /* Push on the 802.3 header */ vos_pkt_push_head(pPacket, &w8023Header, sizeof(w8023Header)); *ppPacket = pPacket; return vosStatus; }
eHalStatus csrTdlsProcessSendMgmt( tpAniSirGlobal pMac, tSmeCmd *cmd ) { tTdlsSendMgmtCmdInfo *tdlsSendMgmtCmdInfo = &cmd->u.tdlsCmd.u.tdlsSendMgmtCmdInfo ; tSirTdlsSendMgmtReq *tdlsSendMgmtReq = NULL ; tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, cmd->sessionId ); eHalStatus status = eHAL_STATUS_FAILURE; if (NULL == pSession) { smsLog( pMac, LOGE, FL("pSession is NULL")); return eHAL_STATUS_FAILURE; } if (NULL == pSession->pConnectBssDesc) { smsLog( pMac, LOGE, FL("BSS Description is not present") ); return eHAL_STATUS_FAILURE; } tdlsSendMgmtReq = vos_mem_malloc( sizeof(tSirTdlsSendMgmtReq) + tdlsSendMgmtCmdInfo->len); if ( NULL == tdlsSendMgmtReq ) status = eHAL_STATUS_FAILURE; else status = eHAL_STATUS_SUCCESS; if (!HAL_STATUS_SUCCESS( status ) ) { smsLog( pMac, LOGE, FL("alloc failed") ); VOS_ASSERT(0) ; return status ; } tdlsSendMgmtReq->sessionId = cmd->sessionId; //Using dialog as transactionId. This can be used to match response with request tdlsSendMgmtReq->transactionId = tdlsSendMgmtCmdInfo->dialog; tdlsSendMgmtReq->reqType = tdlsSendMgmtCmdInfo->frameType ; tdlsSendMgmtReq->dialog = tdlsSendMgmtCmdInfo->dialog ; tdlsSendMgmtReq->statusCode = tdlsSendMgmtCmdInfo->statusCode ; tdlsSendMgmtReq->responder = tdlsSendMgmtCmdInfo->responder; tdlsSendMgmtReq->peerCapability = tdlsSendMgmtCmdInfo->peerCapability; vos_mem_copy(tdlsSendMgmtReq->bssid, pSession->pConnectBssDesc->bssId, sizeof (tSirMacAddr)); vos_mem_copy(tdlsSendMgmtReq->peerMac, tdlsSendMgmtCmdInfo->peerMac, sizeof(tSirMacAddr)) ; if(tdlsSendMgmtCmdInfo->len && tdlsSendMgmtCmdInfo->buf) { vos_mem_copy(tdlsSendMgmtReq->addIe, tdlsSendMgmtCmdInfo->buf, tdlsSendMgmtCmdInfo->len); } // Send the request to PE. smsLog( pMac, LOG1, "sending TDLS Mgmt Frame req to PE " ); status = tdlsSendMessage(pMac, eWNI_SME_TDLS_SEND_MGMT_REQ, (void *)tdlsSendMgmtReq , sizeof(tSirTdlsSendMgmtReq)+tdlsSendMgmtCmdInfo->len) ; if(!HAL_STATUS_SUCCESS( status ) ) { smsLog( pMac, LOGE, FL("Failed to send request to MAC")); } if(tdlsSendMgmtCmdInfo->len && tdlsSendMgmtCmdInfo->buf) { //Done with the buf. Free it. vos_mem_free( tdlsSendMgmtCmdInfo->buf ); tdlsSendMgmtCmdInfo->buf = NULL; tdlsSendMgmtCmdInfo->len = 0; } return status; }
tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb) { tSirMsgQ msg; tpAniSirGlobal pMac = (tpAniSirGlobal)pSirGlobal; tSirMbMsg* pMbLocal; msg.type = pMb->type; msg.bodyval = 0; WDALOG3(wdaLog(pMac, LOG3, FL("msgType %d, msgLen %d" ), pMb->type, pMb->msgLen)); // copy the message from host buffer to firmware buffer // this will make sure that firmware allocates, uses and frees // it's own buffers for mailbox message instead of working on // host buffer // second parameter, 'wait option', to palAllocateMemory is ignored on Windows pMbLocal = vos_mem_malloc(pMb->msgLen); if ( NULL == pMbLocal ) { WDALOGE( wdaLog(pMac, LOGE, FL("Buffer Allocation failed!"))); return eSIR_FAILURE; } vos_mem_copy((void *)pMbLocal, (void *)pMb, pMb->msgLen); msg.bodyptr = pMbLocal; switch (msg.type & HAL_MMH_MB_MSG_TYPE_MASK) { case WDA_MSG_TYPES_BEGIN: // Posts a message to the HAL MsgQ wdaPostCtrlMsg(pMac, &msg); break; case SIR_LIM_MSG_TYPES_BEGIN: // Posts a message to the LIM MsgQ limPostMsgApi(pMac, &msg); break; case SIR_CFG_MSG_TYPES_BEGIN: // Posts a message to the CFG MsgQ wdaPostCfgMsg(pMac, &msg); break; case SIR_PMM_MSG_TYPES_BEGIN: // Posts a message to the PMM MsgQ pmmPostMessage(pMac, &msg); break; case SIR_PTT_MSG_TYPES_BEGIN: WDALOGW( wdaLog(pMac, LOGW, FL("%s:%d: message type = 0x%X"), __func__, __LINE__, msg.type)); vos_mem_free(msg.bodyptr); break; default: WDALOGW( wdaLog(pMac, LOGW, FL("Unknown message type = " "0x%X"), msg.type)); // Release the memory. vos_mem_free(msg.bodyptr); break; } return eSIR_SUCCESS; } // uMacPostCtrlMsg()
eHalStatus csrTdlsProcessAddSta( tpAniSirGlobal pMac, tSmeCmd *cmd ) { tTdlsAddStaCmdInfo *tdlsAddStaCmdInfo = &cmd->u.tdlsCmd.u.tdlsAddStaCmdInfo ; tSirTdlsAddStaReq *tdlsAddStaReq = NULL ; tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, cmd->sessionId ); eHalStatus status = eHAL_STATUS_FAILURE; if (NULL == pSession) { smsLog( pMac, LOGE, FL("pSession is NULL")); return eHAL_STATUS_FAILURE; } if (NULL == pSession->pConnectBssDesc) { smsLog( pMac, LOGE, FL("BSS description is not present") ); return eHAL_STATUS_FAILURE; } tdlsAddStaReq = vos_mem_malloc(sizeof(tSirTdlsAddStaReq)); if ( NULL == tdlsAddStaReq ) status = eHAL_STATUS_FAILURE; else status = eHAL_STATUS_SUCCESS; if (!HAL_STATUS_SUCCESS( status ) ) { smsLog( pMac, LOGE, FL("alloc failed") ); VOS_ASSERT(0) ; return status ; } tdlsAddStaReq->sessionId = cmd->sessionId; tdlsAddStaReq->tdlsAddOper = tdlsAddStaCmdInfo->tdlsAddOper; //Using dialog as transactionId. This can be used to match response with request tdlsAddStaReq->transactionId = 0; vos_mem_copy( tdlsAddStaReq->bssid, pSession->pConnectBssDesc->bssId, sizeof (tSirMacAddr)); vos_mem_copy( tdlsAddStaReq->peerMac, tdlsAddStaCmdInfo->peerMac, sizeof(tSirMacAddr)) ; tdlsAddStaReq->capability = tdlsAddStaCmdInfo->capability; tdlsAddStaReq->uapsd_queues = tdlsAddStaCmdInfo->uapsdQueues; tdlsAddStaReq->max_sp = tdlsAddStaCmdInfo->maxSp; vos_mem_copy( tdlsAddStaReq->extn_capability, tdlsAddStaCmdInfo->extnCapability, SIR_MAC_MAX_EXTN_CAP); tdlsAddStaReq->htcap_present = tdlsAddStaCmdInfo->htcap_present; vos_mem_copy( &tdlsAddStaReq->htCap, &tdlsAddStaCmdInfo->HTCap, sizeof(tdlsAddStaCmdInfo->HTCap)); tdlsAddStaReq->vhtcap_present = tdlsAddStaCmdInfo->vhtcap_present; vos_mem_copy( &tdlsAddStaReq->vhtCap, &tdlsAddStaCmdInfo->VHTCap, sizeof(tdlsAddStaCmdInfo->VHTCap)); tdlsAddStaReq->supported_rates_length = tdlsAddStaCmdInfo->supportedRatesLen; vos_mem_copy( &tdlsAddStaReq->supported_rates, tdlsAddStaCmdInfo->supportedRates, tdlsAddStaCmdInfo->supportedRatesLen); // Send the request to PE. smsLog( pMac, LOGE, "sending TDLS Add Sta req to PE " ); status = tdlsSendMessage(pMac, eWNI_SME_TDLS_ADD_STA_REQ, (void *)tdlsAddStaReq , sizeof(tSirTdlsAddStaReq)) ; if(!HAL_STATUS_SUCCESS( status ) ) { smsLog( pMac, LOGE, FL("Failed to send request to MAC")); } return status; }
/* --------------------------------------------------------------------------- \fn sme_HandleOemDataRsp \brief This function processes the oem data response obtained from the PE \param pMsg - Pointer to the pSirOemDataRsp \return eHalStatus -------------------------------------------------------------------------------*/ eHalStatus sme_HandleOemDataRsp(tHalHandle hHal, tANI_U8* pMsg) { eHalStatus status = eHAL_STATUS_SUCCESS; tpAniSirGlobal pMac; tListElem *pEntry = NULL; tSmeCmd *pCommand = NULL; tSirOemDataRsp* pOemDataRsp = NULL; pMac = PMAC_STRUCT(hHal); smsLog(pMac, LOG1, "%s: OEM_DATA Entering", __func__); do { if(pMsg == NULL) { smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__); status = eHAL_STATUS_FAILURE; break; } pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); if(pEntry) { pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); if(eSmeCommandOemDataReq == pCommand->command) { pOemDataRsp = (tSirOemDataRsp*)pMsg; //make sure to acquire the lock before modifying the data status = sme_AcquireGlobalLock(&pMac->sme); if(!HAL_STATUS_SUCCESS(status)) { break; } if(pMac->oemData.pOemDataRsp != NULL) { vos_mem_free(pMac->oemData.pOemDataRsp); } pMac->oemData.pOemDataRsp = (tOemDataRsp*)vos_mem_malloc(sizeof(tOemDataRsp)); if(pMac->oemData.pOemDataRsp == NULL) { sme_ReleaseGlobalLock(&pMac->sme); smsLog(pMac, LOGE, "in %s vos_mem_malloc failed for pMac->oemData.pOemDataRsp", __func__); status = eHAL_STATUS_FAILURE; break; } smsLog(pMac, LOGE, "Before memory copy"); vos_mem_copy((v_VOID_t*)(pMac->oemData.pOemDataRsp), (v_VOID_t*)(&pOemDataRsp->oemDataRsp), sizeof(tOemDataRsp)); smsLog(pMac, LOGE, "after memory copy"); sme_ReleaseGlobalLock(&pMac->sme); } else { smsLog(pMac, LOGE, "in %s eWNI_SME_OEM_DATA_RSP Received but NO REQs are ACTIVE ...", __func__); status = eHAL_STATUS_FAILURE; break; } } else { smsLog(pMac, LOGE, "in %s eWNI_SME_OEM_DATA_RSP Received but NO commands are ACTIVE ...", __func__); status = eHAL_STATUS_FAILURE; break; } oemData_ReleaseOemDataReqCommand(pMac, pCommand, eHAL_STATUS_SUCCESS); pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE; } while(0); return status; }
/* * commands received from CSR */ eHalStatus csrTdlsProcessCmd(tpAniSirGlobal pMac, tSmeCmd *cmd) { eSmeCommandType cmdType = cmd->command ; #ifdef FEATURE_WLAN_TDLS_INTERNAL tTdlsCmd tdlsCmd = cmd->u.tdlsCmd ; #endif tANI_BOOLEAN status = eANI_BOOLEAN_TRUE; switch(cmdType) { case eSmeCommandTdlsSendMgmt: { status = csrTdlsProcessSendMgmt( pMac, cmd ); if(HAL_STATUS_SUCCESS( status ) ) { status = eANI_BOOLEAN_FALSE ; } } break ; case eSmeCommandTdlsAddPeer: { status = csrTdlsProcessAddSta( pMac, cmd ); if(HAL_STATUS_SUCCESS( status ) ) { status = eANI_BOOLEAN_FALSE ; } } break; case eSmeCommandTdlsDelPeer: { status = csrTdlsProcessDelSta( pMac, cmd ); if(HAL_STATUS_SUCCESS( status ) ) { status = eANI_BOOLEAN_FALSE ; } } break; case eSmeCommandTdlsLinkEstablish: { status = csrTdlsProcessLinkEstablish( pMac, cmd ); if(HAL_STATUS_SUCCESS( status ) ) { status = eANI_BOOLEAN_FALSE ; } } break; #ifdef FEATURE_WLAN_TDLS_INTERNAL case eSmeCommandTdlsDiscovery: { tTdlsDisReqCmdinfo *disReqCmdInfo = &tdlsCmd.u.tdlsDisReqCmdInfo ; tSirTdlsDisReq *disReq = NULL ; tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, cmd->sessionId ); disReq = vos_mem_malloc(sizeof(tSirTdlsDisReq)); if ( NULL == disReq ) status = eHAL_STATUS_FAILURE; else status = eHAL_STATUS_SUCCESS; if(!HAL_STATUS_SUCCESS( status ) ) { smsLog( pMac, LOGE, "dis Req alloc failed " ); VOS_ASSERT(0) ; break ; } disReq->sessionId = cmd->sessionId; disReq->transactionId = 0; /* TODO ? */ disReq->reqType = disReqCmdInfo->tdlsDisType ; vos_mem_copy( disReq->bssid, pSession->pConnectBssDesc->bssId, sizeof (tSirMacAddr)); vos_mem_copy( disReq->peerMac, disReqCmdInfo->peerMac, sizeof(tSirMacAddr)) ; smsLog( pMac, LOGE, "sending TDLS discovery to PE " ); status = tdlsSendMessage(pMac, eWNI_SME_TDLS_DISCOVERY_START_REQ, (void *)disReq , sizeof(tSirTdlsDisReq)) ; if(HAL_STATUS_SUCCESS( status ) ) { status = eANI_BOOLEAN_FALSE ; } /* TODO: Add error handling */ break ; } case eSmeCommandTdlsLinkSetup: { tTdlsLinkSetupReqCmdinfo *linkSetupReqCmdInfo = &tdlsCmd.u.tdlsLinkSetupReqCmdInfo ; tSirTdlsSetupReq *setupReq = NULL ; tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, cmd->sessionId ); setupReq = vos_mem_malloc(sizeof(tSirTdlsSetupReq)); if ( NULL == setupReq ) status = eHAL_STATUS_FAILURE; else status = eHAL_STATUS_SUCCESS; if(!HAL_STATUS_SUCCESS( status ) ) { smsLog( pMac, LOGE, "dis Req alloc failed " ); VOS_ASSERT(0) ; break ; } setupReq->sessionId = cmd->sessionId; setupReq->transactionId = 0; /* TODO ? */ vos_mem_copy( setupReq->bssid, pSession->pConnectBssDesc->bssId, sizeof (tSirMacAddr)); vos_mem_copy( setupReq->peerMac, linkSetupReqCmdInfo->peerMac, sizeof(tSirMacAddr)) ; VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, ("sending TDLS link setup to PE ")); status = tdlsSendMessage(pMac, eWNI_SME_TDLS_LINK_START_REQ, (void *)setupReq , sizeof(tSirTdlsSetupReq) ) ; if(HAL_STATUS_SUCCESS( status ) ) { status = eANI_BOOLEAN_FALSE ; } /* TODO: Add error handling */ break ; } case eSmeCommandTdlsLinkTear: { tTdlsLinkTeardownCmdinfo *linkTeardownCmdInfo = &tdlsCmd.u.tdlsLinkTeardownCmdInfo ; tSirTdlsTeardownReq *teardownReq = NULL ; tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, cmd->sessionId ); teardownReq = vos_mem_malloc(sizeof(tSirTdlsTeardownReq)); if ( NULL == teardownReq ) status = eHAL_STATUS_FAILURE; else status = eHAL_STATUS_SUCCESS; if(!HAL_STATUS_SUCCESS( status ) ) { smsLog( pMac, LOGE, "teardown Req alloc failed " ); VOS_ASSERT(0) ; break ; } teardownReq->sessionId = cmd->sessionId; teardownReq->transactionId = 0; /* TODO ? */ vos_mem_copy( teardownReq->bssid, pSession->pConnectBssDesc->bssId, sizeof (tSirMacAddr)); vos_mem_copy( &teardownReq->peerMac, linkTeardownCmdInfo->peerMac, sizeof(tSirMacAddr)) ; VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, ("teardown request..")) ; status = tdlsSendMessage(pMac, eWNI_SME_TDLS_TEARDOWN_REQ, (void *)teardownReq , sizeof(tSirTdlsTeardownReq)) ; if(HAL_STATUS_SUCCESS( status ) ) { status = eANI_BOOLEAN_FALSE ; } /* TODO: Add error handling */ break ; } #endif default: { /* TODO: Add defualt handling */ break ; } } return status ; }
/*-------------------------------------------------------------------------- Each time the supplicant sends down the FT IEs to the driver. This function is called in SME. This function packages and sends the FT IEs to PE. ------------------------------------------------------------------------*/ void sme_SetFTIEs(tHalHandle hHal, tANI_U32 sessionId, const tANI_U8 *ft_ies, tANI_U16 ft_ies_length ) { tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); eHalStatus status = eHAL_STATUS_FAILURE; if (NULL == pSession || NULL == ft_ies) { smsLog( pMac, LOGE, FL(" ft ies or pSession is NULL")); return; } status = sme_AcquireGlobalLock( &pMac->sme ); if (!( HAL_STATUS_SUCCESS( status ))) return; #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG smsLog( pMac, LOG1, "FT IEs Req is received in state %d", pSession->ftSmeContext.FTState); #endif // Global Station FT State switch(pSession->ftSmeContext.FTState) { case eFT_START_READY: case eFT_AUTH_REQ_READY: if ((pSession->ftSmeContext.auth_ft_ies) && (pSession->ftSmeContext.auth_ft_ies_length)) { // Free the one we received last from the supplicant vos_mem_free(pSession->ftSmeContext.auth_ft_ies); pSession->ftSmeContext.auth_ft_ies_length = 0; pSession->ftSmeContext.auth_ft_ies = NULL; } // Save the FT IEs pSession->ftSmeContext.auth_ft_ies = vos_mem_malloc(ft_ies_length); if ( NULL == pSession->ftSmeContext.auth_ft_ies ) { smsLog( pMac, LOGE, FL("Memory allocation failed for " "auth_ft_ies")); sme_ReleaseGlobalLock( &pMac->sme ); return; } pSession->ftSmeContext.auth_ft_ies_length = ft_ies_length; vos_mem_copy((tANI_U8 *)pSession->ftSmeContext.auth_ft_ies, ft_ies,ft_ies_length); pSession->ftSmeContext.FTState = eFT_AUTH_REQ_READY; #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG smsLog( pMac, LOG1, "ft_ies_length=%d", ft_ies_length); #endif break; case eFT_AUTH_COMPLETE: // We will need to re-start preauth. If we received FT IEs in // eFT_PRE_AUTH_DONE state, it implies there was a rekey in // our pre-auth state. Hence this implies we need Pre-auth again. // OK now inform SME we have no pre-auth list. // Delete the pre-auth node locally. Set your self back to restart pre-auth // TBD #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG smsLog( pMac, LOG1, "Pre-auth done and now receiving---> AUTH REQ <---- in state %d", pSession->ftSmeContext.FTState); smsLog( pMac, LOG1, "Unhandled reception of FT IES in state %d", pSession->ftSmeContext.FTState); #endif break; case eFT_REASSOC_REQ_WAIT: // We are done with pre-auth, hence now waiting for // reassoc req. This is the new FT Roaming in place // At this juncture we are ready to start sending Re-Assoc Req. #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG smsLog( pMac, LOG1, "New Reassoc Req=%p in state %d", ft_ies, pSession->ftSmeContext.FTState); #endif if ((pSession->ftSmeContext.reassoc_ft_ies) && (pSession->ftSmeContext.reassoc_ft_ies_length)) { // Free the one we received last from the supplicant vos_mem_free(pSession->ftSmeContext.reassoc_ft_ies); pSession->ftSmeContext.reassoc_ft_ies_length = 0; } // Save the FT IEs pSession->ftSmeContext.reassoc_ft_ies = vos_mem_malloc(ft_ies_length); if ( NULL == pSession->ftSmeContext.reassoc_ft_ies ) { smsLog( pMac, LOGE, FL("Memory allocation failed for " "reassoc_ft_ies")); sme_ReleaseGlobalLock( &pMac->sme ); return; } pSession->ftSmeContext.reassoc_ft_ies_length = ft_ies_length; vos_mem_copy((tANI_U8 *)pSession->ftSmeContext.reassoc_ft_ies, ft_ies, ft_ies_length); pSession->ftSmeContext.FTState = eFT_SET_KEY_WAIT; #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG smsLog( pMac, LOG1, "ft_ies_length=%d state=%d", ft_ies_length, pSession->ftSmeContext.FTState); #endif break; default: smsLog( pMac, LOGE, FL(" Unhandled state=%d"), pSession->ftSmeContext.FTState); break; } sme_ReleaseGlobalLock( &pMac->sme ); }
/*---------------------------------------------------------------------------- * * The function limSendRemainOnChannelDebugMarkerFrame, prepares Marker frame * for Start and End of remain on channel with RemainOnChannelMsg as Vendor * Specific information element of the frame. * *----------------------------------------------------------------------------*/ tSirRetStatus limSendRemainOnChannelDebugMarkerFrame(tpAniSirGlobal pMac, tANI_U8 *remainOnChannelMsg) { tSirMacAddr magicMacAddr= {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; tANI_U32 nBytes, nPayload; tSirRetStatus nSirStatus; tANI_U8 *pFrame; void *pPacket; eHalStatus halstatus; tANI_U8 txFlag = 0; publicVendorSpecific *pPublicVendorSpecific; pPublicVendorSpecific = vos_mem_malloc(sizeof(publicVendorSpecific)); if( pPublicVendorSpecific == NULL ) { limLog( pMac, LOGE, FL( "Unable to allocate memory for Vendor specific information" " element" ) ); return eSIR_MEM_ALLOC_FAILED; } // Assigning Action category code as unknown as this is debug marker frame pPublicVendorSpecific->category = REMAIN_ON_CHANNEL_UNKNOWN_ACTION_CATEGORY; pPublicVendorSpecific->elementid = VENDOR_SPECIFIC_ELEMENT_ID; pPublicVendorSpecific->length = strlen(remainOnChannelMsg); nPayload = sizeof(publicVendorSpecific) + pPublicVendorSpecific->length; nBytes = nPayload + sizeof( tSirMacMgmtHdr ); halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) { limLog( pMac, LOGE, FL("Failed to allocate %d bytes for a Remain" " on channel action frame."), nBytes ); nSirStatus = eSIR_MEM_ALLOC_FAILED; goto end; } vos_mem_zero( pFrame, nBytes ); // Populate frame with MAC header nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, SIR_MAC_MGMT_ACTION, magicMacAddr, pMac->lim.gSelfMacAddr); if ( eSIR_SUCCESS != nSirStatus ) { limLog( pMac, LOGE, FL("Failed to populate the buffer descriptor for a" " Action frame for remain on channel.") ); palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); goto end; } // Copy Public Vendor specific fields to frame's information element vos_mem_copy( (pFrame + (sizeof( tSirMacMgmtHdr ))), pPublicVendorSpecific, sizeof(publicVendorSpecific) ); // Copy Remain On channel message to Vendor Specific information field vos_mem_copy( (pFrame + (nBytes - pPublicVendorSpecific->length)), remainOnChannelMsg, pPublicVendorSpecific->length ); halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) sizeof(tSirMacMgmtHdr) + nPayload, HAL_TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, limTxComplete, pFrame, txFlag ); if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) { limLog( pMac, LOGE, FL("could not send marker frame for" " remain on channel!" )); //Pkt will be freed up by the callback nSirStatus = eSIR_FAILURE; goto end; } nSirStatus = eSIR_SUCCESS; end: vos_mem_free( pPublicVendorSpecific ); return nSirStatus; }
v_VOID_t * vos_mem_malloc_debug( v_SIZE_t size, char* fileName, v_U32_t lineNum) { struct s_vos_mem_struct* memStruct; v_VOID_t* memPtr = NULL; v_SIZE_t new_size; int flags = GFP_KERNEL; unsigned long IrqFlags; if (size > (1024*1024)) { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: called with arg > 1024K; passed in %d !!!", __func__,size); return NULL; } if (in_interrupt()) { flags = GFP_ATOMIC; } if (!memory_dbug_flag) { #ifdef CONFIG_WCNSS_MEM_PRE_ALLOC v_VOID_t* pmem; if (size > WCNSS_PRE_ALLOC_GET_THRESHOLD) { pmem = wcnss_prealloc_get(size); if (NULL != pmem) return pmem; } #endif return kmalloc(size, flags); } new_size = size + sizeof(struct s_vos_mem_struct) + 8; memStruct = (struct s_vos_mem_struct*)kmalloc(new_size, flags); if(memStruct != NULL) { VOS_STATUS vosStatus; memStruct->fileName = fileName; memStruct->lineNum = lineNum; memStruct->size = size; vos_mem_copy(&memStruct->header[0], &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER)); vos_mem_copy( (v_U8_t*)(memStruct + 1) + size, &WLAN_MEM_TAIL[0], sizeof(WLAN_MEM_TAIL)); spin_lock_irqsave(&vosMemList.lock, IrqFlags); vosStatus = hdd_list_insert_front(&vosMemList, &memStruct->pNode); spin_unlock_irqrestore(&vosMemList.lock, IrqFlags); if(VOS_STATUS_SUCCESS != vosStatus) { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: Unable to insert node into List vosStatus %d", __func__, vosStatus); } memPtr = (v_VOID_t*)(memStruct + 1); } return memPtr; }
VOS_STATUS vos_rx_mq_serialize( VOS_MQ_ID msgQueueId, vos_msg_t *pMsg ) { pVosMqType pTargetMq = NULL; pVosMsgWrapper pMsgWrapper = NULL; if ((gpVosContext == NULL) || (pMsg == NULL)) { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: Null params or global vos context is null", __func__); VOS_ASSERT(0); return VOS_STATUS_E_FAILURE; } switch (msgQueueId) { case VOS_MQ_ID_SYS: { pTargetMq = &(gpVosContext->vosSched.sysRxMq); break; } case VOS_MQ_ID_WDI: { pTargetMq = &(gpVosContext->vosSched.wdiRxMq); break; } default: VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: Trying to queue msg into unknown Rx Msg queue ID %d", __func__, msgQueueId); return VOS_STATUS_E_FAILURE; } if (pTargetMq == NULL) { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: pTargetMq == NULL", __func__); return VOS_STATUS_E_FAILURE; } pMsgWrapper = vos_mq_get(&gpVosContext->freeVosMq); if (NULL == pMsgWrapper) { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: VOS Core run out of message wrapper", __func__); return VOS_STATUS_E_RESOURCES; } vos_mem_copy( (v_VOID_t*)pMsgWrapper->pVosMsg, (v_VOID_t*)pMsg, sizeof(vos_msg_t)); vos_mq_put(pTargetMq, pMsgWrapper); set_bit(RX_POST_EVENT_MASK, &gpVosContext->vosSched.rxEventFlag); wake_up_interruptible(&gpVosContext->vosSched.rxWaitQueue); return VOS_STATUS_SUCCESS; }