static void wlan_hdd_cancel_existing_remain_on_channel(hdd_adapter_t *pAdapter) { hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); int status = 0; if(cfgState->remain_on_chan_ctx != NULL) { hddLog( LOG1, "Cancel Existing Remain on Channel"); /* Wait till remain on channel ready indication before issuing cancel * remain on channel request, otherwise if remain on channel not * received and if the driver issues cancel remain on channel then lim * will be in unknown state. */ status = wait_for_completion_interruptible_timeout(&pAdapter->rem_on_chan_ready_event, msecs_to_jiffies(WAIT_REM_CHAN_READY)); if (!status) { hddLog( LOGE, "%s: timeout waiting for remain on channel ready indication", __func__); } INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var); /* Issue abort remain on chan request to sme. * The remain on channel callback will make sure the remain_on_chan * expired event is sent. */ if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) || ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) || ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ) ) { sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter ), pAdapter->sessionId ); } else if ( (WLAN_HDD_SOFTAP== pAdapter->device_mode) || (WLAN_HDD_P2P_GO == pAdapter->device_mode) ) { WLANSAP_CancelRemainOnChannel( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext); } status = wait_for_completion_interruptible_timeout(&pAdapter->cancel_rem_on_chan_var, msecs_to_jiffies(WAIT_CANCEL_REM_CHAN)); if (!status) { hddLog( LOGE, "%s: timeout waiting for cancel remain on channel ready indication", __func__); } } }
/**-------------------------------------------------------------------------------------------- \brief __iw_get_oem_data_rsp() - This function gets the oem data response. This invokes the respective sme functionality. Function for handling the oem data rsp IOCTL \param - dev - Pointer to the net device - info - Pointer to the iw_oem_data_req - wrqu - Pointer to the iwreq data - extra - Pointer to the data \return - 0 for success, non zero for failure -----------------------------------------------------------------------------------------------*/ int __iw_get_oem_data_rsp( struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { int rc = 0; eHalStatus status; struct iw_oem_data_rsp* pHddOemDataRsp; tOemDataRsp* pSmeOemDataRsp; hdd_adapter_t *pAdapter; hdd_context_t *pHddCtx; ENTER(); pAdapter = (netdev_priv(dev)); if (NULL == pAdapter) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL",__func__); return -EINVAL; } pHddCtx = WLAN_HDD_GET_CTX(pAdapter); rc = wlan_hdd_validate_context(pHddCtx); if (0 != rc) { return rc; } do { //get the oem data response from sme status = sme_getOemDataRsp(WLAN_HDD_GET_HAL_CTX(pAdapter), &pSmeOemDataRsp); if (status != eHAL_STATUS_SUCCESS) { hddLog(LOGE, "%s: failed in sme_getOemDataRsp", __func__); rc = -EIO; break; } else { if (pSmeOemDataRsp != NULL) { pHddOemDataRsp = (struct iw_oem_data_rsp*)(extra); vos_mem_copy(pHddOemDataRsp->oemDataRsp, pSmeOemDataRsp->oemDataRsp, OEM_DATA_RSP_SIZE); } else { hddLog(LOGE, "%s: pSmeOemDataRsp = NULL", __func__); rc = -EIO; break; } } } while(0); EXIT(); return rc; }
static eHalStatus hdd_ScanRequestCallback(tHalHandle halHandle, void *pContext, tANI_U32 scanId, eCsrScanStatus status) { struct net_device *dev = (struct net_device *) pContext; hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ; hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); union iwreq_data wrqu; int we_event; char *msg; ENTER(); hddLog(LOGW,"%s called with halHandle = %p, pContext = %p, scanID = %d," " returned status = %d", __func__, halHandle, pContext, (int) scanId, (int) status); /* if there is a scan request pending when the wlan driver is unloaded we may be invoked as SME flushes its pending queue. If that is the case, the underlying net_device may have already been destroyed, so do some quick sanity before proceeding */ if (pAdapter->dev != dev) { hddLog(LOGW, "%s: device mismatch %p vs %p", __func__, pAdapter->dev, dev); return eHAL_STATUS_SUCCESS; } /* Check the scanId */ if (pHddCtx->scan_info.scanId != scanId) { hddLog(LOGW, "%s called with mismatched scanId pHddCtx->scan_info.scanId = %d " "scanId = %d ", __func__, (int) pHddCtx->scan_info.scanId, (int) scanId); } /* Scan is no longer pending */ pHddCtx->scan_info.mScanPending = VOS_FALSE; // notify any applications that may be interested memset(&wrqu, '\0', sizeof(wrqu)); we_event = SIOCGIWSCAN; msg = NULL; wireless_send_event(dev, we_event, &wrqu, msg); EXIT(); VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__); return eHAL_STATUS_SUCCESS; }
void hdd_sendActionCnf( hdd_adapter_t *pAdapter, tANI_BOOLEAN actionSendSuccess ) { hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); cfgState->actionFrmState = HDD_IDLE; hddLog( LOG1, "Send Action cnf, actionSendSuccess %d", actionSendSuccess); if( NULL == cfgState->buf ) { return; } /* If skb is NULL it means this packet was received on CFG80211 interface * else it was received on Monitor interface */ if( cfgState->skb == NULL ) { /* * buf is the same pointer it passed us to send. Since we are sending * it through control path, we use different buffers. * In case of mac80211, they just push it to the skb and pass the same * data while sending tx ack status. * */ cfg80211_mgmt_tx_status( pAdapter->dev, cfgState->action_cookie, cfgState->buf, cfgState->len, actionSendSuccess, GFP_KERNEL ); vos_mem_free( cfgState->buf ); cfgState->buf = NULL; } else { hdd_adapter_t* pMonAdapter = hdd_get_adapter( pAdapter->pHddCtx, WLAN_HDD_MONITOR ); if( pMonAdapter == NULL ) { hddLog( LOGE, "Not able to get Monitor Adapter"); cfgState->skb = NULL; vos_mem_free( cfgState->buf ); cfgState->buf = NULL; complete(&pAdapter->tx_action_cnf_event); return; } /* Send TX completion feedback over monitor interface. */ hdd_wlan_tx_complete( pMonAdapter, cfgState, actionSendSuccess ); cfgState->skb = NULL; vos_mem_free( cfgState->buf ); cfgState->buf = NULL; /* Look for the next Mgmt packet to TX */ hdd_mon_tx_mgmt_pkt(pAdapter); } complete(&pAdapter->tx_action_cnf_event); }
void hddTraceDump(void *pMac, tpvosTraceRecord pRecord, tANI_U16 recIndex) { if (TRACE_CODE_HDD_RX_SME_MSG == pRecord->code) { hddLog(LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", recIndex, pRecord->time, pRecord->session, "RX SME MSG:", get_eRoamCmdStatus_str(pRecord->data), pRecord->data); } else { hddLog(LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", recIndex, pRecord->time, pRecord->session, "HDD Event:", hddTraceGetEventString(pRecord->code), pRecord->data); } }
int iw_get_oem_data_rsp( struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { int rc = 0; eHalStatus status; struct iw_oem_data_rsp* pHddOemDataRsp; tOemDataRsp* pSmeOemDataRsp; hdd_adapter_t *pAdapter = (netdev_priv(dev)); if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__); return -EBUSY; } do { status = sme_getOemDataRsp(WLAN_HDD_GET_HAL_CTX(pAdapter), &pSmeOemDataRsp); if (status != eHAL_STATUS_SUCCESS) { hddLog(LOGE, "%s: failed in sme_getOemDataRsp", __func__); rc = -EIO; break; } else { if (pSmeOemDataRsp != NULL) { pHddOemDataRsp = (struct iw_oem_data_rsp*)(extra); vos_mem_copy(pHddOemDataRsp->oemDataRsp, pSmeOemDataRsp->oemDataRsp, OEM_DATA_RSP_SIZE); } else { hddLog(LOGE, "%s: pSmeOemDataRsp = NULL", __func__); rc = -EIO; break; } } } while(0); return rc; }
int iw_set_oem_data_req( struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { eHalStatus status = eHAL_STATUS_SUCCESS; struct iw_oem_data_req *pOemDataReq = NULL; tOemDataReqConfig oemDataReqConfig; tANI_U32 oemDataReqID = 0; hdd_adapter_t *pAdapter = (netdev_priv(dev)); hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__); return -EBUSY; } do { if(NULL != wrqu->data.pointer) { pOemDataReq = (struct iw_oem_data_req *)wrqu->data.pointer; } if(pOemDataReq == NULL) { hddLog(LOGE, "in %s oemDataReq == NULL", __func__); status = eHAL_STATUS_FAILURE; break; } vos_mem_zero(&oemDataReqConfig, sizeof(tOemDataReqConfig)); if (copy_from_user((&oemDataReqConfig)->oemDataReq, pOemDataReq->oemDataReq, OEM_DATA_REQ_SIZE)) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s: copy_from_user() failed!", __func__); return -EFAULT; } status = sme_OemDataReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, &oemDataReqConfig, &oemDataReqID, &hdd_OemDataReqCallback, dev); pwextBuf->oemDataReqID = oemDataReqID; pwextBuf->oemDataReqInProgress = TRUE; } while(0); return status; }
int wlan_hdd_check_remain_on_channel(hdd_adapter_t *pAdapter) { int status = 0; hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); if(WLAN_HDD_P2P_GO != pAdapter->device_mode) { //Cancel Existing Remain On Channel //If no action frame is pending if( cfgState->remain_on_chan_ctx != NULL) { //Check whether Action Frame is pending or not if( cfgState->buf == NULL) { wlan_hdd_cancel_existing_remain_on_channel(pAdapter); } else { hddLog( LOG1, "Cannot Cancel Existing Remain on Channel"); status = -EBUSY; } } } return status; }
/** * hdd_state_info_dump() - prints state information of hdd layer */ static void hdd_state_info_dump(void) { v_CONTEXT_t vos_ctx_ptr; hdd_context_t *hdd_ctx_ptr = NULL; hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL; VOS_STATUS status; hdd_station_ctx_t *hdd_sta_ctx = NULL; hdd_adapter_t *adapter =NULL; /* get the global voss context */ vos_ctx_ptr = vos_get_global_context(VOS_MODULE_ID_VOSS, NULL); if (NULL != vos_ctx_ptr) { hdd_ctx_ptr = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx_ptr); } else { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Invalid Global VOSS Context", __func__); VOS_ASSERT(0); return; } hddLog(LOG1, FL("mScanPending %d isWlanSuspended %d disable_dfs_flag %d"), hdd_ctx_ptr->scan_info.mScanPending, hdd_ctx_ptr->isWlanSuspended, hdd_ctx_ptr->disable_dfs_flag); status = hdd_get_front_adapter(hdd_ctx_ptr, &adapter_node); while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) { adapter = adapter_node->pAdapter; if (adapter->dev) hddLog(LOG1, FL("device name: %s"), adapter->dev->name); switch (adapter->device_mode) { case WLAN_HDD_INFRA_STATION: case WLAN_HDD_P2P_CLIENT: hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); hddLog(LOG1, FL("connState: %d device_mode: %d"), hdd_sta_ctx->conn_info.connState, adapter->device_mode); break; default: break; } status = hdd_get_next_adapter(hdd_ctx_ptr, adapter_node, &next); adapter_node = next; } }
static eHalStatus hdd_ScanRequestCallback(tHalHandle halHandle, void *pContext, tANI_U32 scanId, eCsrScanStatus status) { struct net_device *dev = (struct net_device *) pContext; hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ; hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); union iwreq_data wrqu; int we_event; char *msg; ENTER(); hddLog(LOGW,"%s called with halHandle = %p, pContext = %p, scanID = %d," " returned status = %d", __func__, halHandle, pContext, (int) scanId, (int) status); if (pAdapter->dev != dev) { hddLog(LOGW, "%s: device mismatch %p vs %p", __func__, pAdapter->dev, dev); return eHAL_STATUS_SUCCESS; } if (pHddCtx->scan_info.scanId != scanId) { hddLog(LOGW, "%s called with mismatched scanId pHddCtx->scan_info.scanId = %d " "scanId = %d ", __func__, (int) pHddCtx->scan_info.scanId, (int) scanId); } pHddCtx->scan_info.mScanPending = VOS_FALSE; memset(&wrqu, '\0', sizeof(wrqu)); we_event = SIOCGIWSCAN; msg = NULL; wireless_send_event(dev, we_event, &wrqu, msg); EXIT(); VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__); return eHAL_STATUS_SUCCESS; }
static eHalStatus hdd_CscanRequestCallback(tHalHandle halHandle, void *pContext, tANI_U32 scanId, eCsrScanStatus status) { struct net_device *dev = (struct net_device *) pContext; hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ; hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); union iwreq_data wrqu; int we_event; char *msg; VOS_STATUS vos_status = VOS_STATUS_SUCCESS; ENTER(); hddLog(LOG1,"%s called with halHandle = %p, pContext = %p, scanID = %d," " returned status = %d", __func__, halHandle, pContext, (int) scanId, (int) status); if (pwextBuf->scanId != scanId) { hddLog(LOGW, "%s called with mismatched scanId pWextState->scanId = %d " "scanId = %d ", __func__, (int) pwextBuf->scanId, (int) scanId); } pwextBuf->mScanPending = VOS_FALSE; memset(&wrqu, '\0', sizeof(wrqu)); we_event = SIOCGIWSCAN; msg = NULL; wireless_send_event(dev, we_event, &wrqu, msg); vos_status = vos_event_set(&pwextBuf->vosevent); if (!VOS_IS_STATUS_SUCCESS(vos_status)) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD vos_event_set failed!!")); return VOS_STATUS_E_FAILURE; } EXIT(); VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__); return eHAL_STATUS_SUCCESS; }
static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter, enum nl80211_auth_type auth_type) { hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); ENTER(); /*set authentication type*/ switch (auth_type) { case NL80211_AUTHTYPE_OPEN_SYSTEM: case NL80211_AUTHTYPE_AUTOMATIC: hddLog(VOS_TRACE_LEVEL_INFO, "%s: set authentication type to OPEN", __func__); pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM; break; case NL80211_AUTHTYPE_SHARED_KEY: hddLog(VOS_TRACE_LEVEL_INFO, "%s: set authentication type to SHARED", __func__); pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY; break; #ifdef FEATURE_WLAN_CCX case NL80211_AUTHTYPE_NETWORK_EAP: hddLog(VOS_TRACE_LEVEL_INFO, "%s: set authentication type to CCKM WPA", __func__); pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required. break; #endif default: hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported authentication type %d", __func__, auth_type); pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN; return -EINVAL; } pWextState->roamProfile.AuthType.authType[0] = pHddStaCtx->conn_info.authType; return 0; }
/**-------------------------------------------------------------------------------------------- \brief iw_get_oem_data_rsp() - This function gets the oem data response. This invokes the respective sme functionality. Function for handling the oem data rsp IOCTL \param - dev - Pointer to the net device - info - Pointer to the iw_oem_data_req - wrqu - Pointer to the iwreq data - extra - Pointer to the data \return - 0 for success, non zero for failure -----------------------------------------------------------------------------------------------*/ int iw_get_oem_data_rsp( struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { eHalStatus status = eHAL_STATUS_SUCCESS; struct iw_oem_data_rsp* pHddOemDataRsp; tOemDataRsp* pSmeOemDataRsp; hdd_adapter_t *pAdapter = (netdev_priv(dev)); do { //get the oem data response from sme status = sme_getOemDataRsp(WLAN_HDD_GET_HAL_CTX(pAdapter), &pSmeOemDataRsp); if(status != eHAL_STATUS_SUCCESS) { hddLog(LOGE, "%s: failed in sme_getOemDataRsp\n", __FUNCTION__); break; } else { if(pSmeOemDataRsp != NULL) { pHddOemDataRsp = (struct iw_oem_data_rsp*)(extra); vos_mem_copy(pHddOemDataRsp->oemDataRsp, pSmeOemDataRsp->oemDataRsp, OEM_DATA_RSP_SIZE); } else { hddLog(LOGE, "%s: pSmeOemDataRsp = NULL\n", __FUNCTION__); status = eHAL_STATUS_FAILURE; break; } } } while(0); return eHAL_STATUS_SUCCESS; }
/*--------------------------------------------------------------------------------------------- \brief hdd_OemDataReqCallback() - This function also reports the results to the user space \return - eHalStatus enumeration -----------------------------------------------------------------------------------------------*/ static eHalStatus hdd_OemDataReqCallback(tHalHandle hHal, void *pContext, tANI_U32 oemDataReqID, eOemDataReqStatus oemDataReqStatus) { eHalStatus status = eHAL_STATUS_SUCCESS; struct net_device *dev = (struct net_device *) pContext; union iwreq_data wrqu; char buffer[IW_CUSTOM_MAX+1]; memset(&wrqu, '\0', sizeof(wrqu)); memset(buffer, '\0', sizeof(buffer)); //now if the status is success, then send an event up //so that the application can request for the data //else no need to send the event up if(oemDataReqStatus == eOEM_DATA_REQ_FAILURE) { snprintf(buffer, IW_CUSTOM_MAX, "QCOM: OEM-DATA-REQ-FAILED"); hddLog(LOGW, "%s: oem data req %d failed", __func__, oemDataReqID); } else if(oemDataReqStatus == eOEM_DATA_REQ_INVALID_MODE) { snprintf(buffer, IW_CUSTOM_MAX, "QCOM: OEM-DATA-REQ-INVALID-MODE"); hddLog(LOGW, "%s: oem data req %d failed because the driver is in invalid mode (IBSS|BTAMP|AP)", __func__, oemDataReqID); } else { snprintf(buffer, IW_CUSTOM_MAX, "QCOM: OEM-DATA-REQ-SUCCESS"); //everything went alright } wrqu.data.pointer = buffer; wrqu.data.length = strlen(buffer); wireless_send_event(dev, IWEVCUSTOM, &wrqu, buffer); return status; }
void vos_abort_mac_scan(void) { hdd_context_t *pHddCtx = NULL; v_CONTEXT_t pVosContext = NULL; pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); if(!pVosContext) { hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Global VOS context is Null", __func__); return; } pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); if(!pHddCtx) { hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD context is Null", __func__); return; } hdd_abort_mac_scan(pHddCtx, eCSR_SCAN_ABORT_DEFAULT); return; }
/**-------------------------------------------------------------------------------------------- \brief iw_set_oem_data_req() - This function sets the oem data req configuration. This invokes the respective sme oem data req functionality. Function for handling the set IOCTL for the oem data req configuration \param - dev - Pointer to the net device - info - Pointer to the iw_oem_data_req - wrqu - Pointer to the iwreq data - extra - Pointer to the data \return - 0 for success, non zero for failure -----------------------------------------------------------------------------------------------*/ int iw_set_oem_data_req( struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { eHalStatus status = eHAL_STATUS_SUCCESS; struct iw_oem_data_req *pOemDataReq = NULL; tOemDataReqConfig oemDataReqConfig; tANI_U32 oemDataReqID = 0; hdd_adapter_t *pAdapter = (netdev_priv(dev)); hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); do { if(NULL != wrqu->data.pointer) { pOemDataReq = (struct iw_oem_data_req *)wrqu->data.pointer; } if(pOemDataReq == NULL) { hddLog(LOGE, "in %s oemDataReq == NULL\n", __FUNCTION__); status = eHAL_STATUS_FAILURE; break; } vos_mem_zero(&oemDataReqConfig, sizeof(tOemDataReqConfig)); vos_mem_copy((&oemDataReqConfig)->oemDataReq, pOemDataReq->oemDataReq, OEM_DATA_REQ_SIZE); status = sme_OemDataReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, &oemDataReqConfig, &oemDataReqID, &hdd_OemDataReqCallback, dev); pwextBuf->oemDataReqID = oemDataReqID; pwextBuf->oemDataReqInProgress = TRUE; } while(0); return status; }
void wlan_hdd_one_connection_scenario(hdd_context_t *hdd_ctx) { enum cds_con_mode sub_type; enum cds_conc_priority_mode system_pref = hdd_ctx->config->conc_system_pref; uint8_t pcl[MAX_NUM_CHAN] = {0}; uint32_t pcl_len = 0; bool status = false; enum cds_pcl_type pcl_type; char reason[20] = {0}; CDF_STATUS ret; /* flush the entire table first */ ret = cds_init_policy_mgr(hdd_ctx); if (!CDF_IS_STATUS_SUCCESS(ret)) { hdd_err("Policy manager initialization failed"); return; } for (sub_type = 0; sub_type < CDS_MAX_NUM_OF_MODE; sub_type++) { /* validate one connection is created or no */ if (cds_get_connection_count(hdd_ctx) != 0) { hddLog(LOGE, FL("Test failed - No. of connection is not 0")); return; } cdf_mem_zero(pcl, sizeof(pcl)); pcl_len = 0; pcl_type = get_pcl_from_first_conn_table(sub_type, system_pref); /* check PCL value for second connection is correct or no */ cds_get_pcl(hdd_ctx, sub_type, pcl, &pcl_len); status = wlan_hdd_validate_pcl(hdd_ctx, pcl_type, pcl, pcl_len, 0, 0, reason, sizeof(reason)); if ((pcl_type == CDS_MAX_PCL_TYPE) && (pcl[0] == 0)) continue; fill_report(hdd_ctx, "1 connection", sub_type, CDS_MAX_NUM_OF_MODE, CDS_MAX_NUM_OF_MODE, 0, 0, 0, status, pcl_type, reason, pcl); } }
static eHalStatus hdd_AddIwStreamEvent(int cmd, int length, char* data, hdd_scan_info_t *pscanInfo, char **last_event, char **current_event ) { struct iw_event event; *last_event = *current_event; vos_mem_zero(&event, sizeof (struct iw_event)); event.cmd = cmd; event.u.data.flags = 1; event.u.data.length = length; *current_event = iwe_stream_add_point (pscanInfo->info,*current_event, pscanInfo->end, &event, data); if(*last_event == *current_event) { /* no space to add event */ hddLog( LOGE, "%s: no space left to add event", __func__); return -E2BIG; /* Error code, may be E2BIG */ } return 0; }
int wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct net_device *dev ) { hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy); hdd_adapter_t *pVirtAdapter = WLAN_HDD_GET_PRIV_PTR(dev); ENTER(); hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d", __func__,pVirtAdapter->device_mode); if (pHddCtx->isLogpInProgress) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:LOGP in Progress. Ignore!!!", __func__); return -EAGAIN; } wlan_hdd_release_intf_addr( pHddCtx, pVirtAdapter->macAddressCurrent.bytes ); hdd_stop_adapter( pHddCtx, pVirtAdapter ); hdd_close_adapter( pHddCtx, pVirtAdapter, TRUE ); EXIT(); return 0; }
int wlan_hdd_action( struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type, bool channel_type_valid, const u8 *buf, size_t len, u64 *cookie ) #endif //LINUX_VERSION_CODE { hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); tANI_U16 extendedWait = 0; tANI_U8 type = WLAN_HDD_GET_TYPE_FRM_FC(buf[0]); tANI_U8 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(buf[0]); tActionFrmType actionFrmType; bool noack = 0; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) hdd_adapter_t *goAdapter; #endif #ifdef WLAN_FEATURE_P2P_DEBUG if ((type == SIR_MAC_MGMT_FRAME) && (subType == SIR_MAC_MGMT_ACTION) && (buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME)) { actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET]; if(actionFrmType > MAX_P2P_ACTION_FRAME_TYPE) { hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] unknown[%d] ---> OTA", actionFrmType); } else { hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] %s ---> OTA", p2p_action_frame_type[actionFrmType]); if( (actionFrmType == WLAN_HDD_PROV_DIS_REQ) && (globalP2PConnectionStatus == P2P_NOT_ACTIVE) ) { globalP2PConnectionStatus = P2P_GO_NEG_PROCESS; hddLog(LOGE,"[P2P State]Inactive state to " "GO negotation progress state"); } else if( (actionFrmType == WLAN_HDD_GO_NEG_CNF) && (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS) ) { globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED; hddLog(LOGE,"[P2P State]GO nego progress to GO nego" " completed state"); } } } #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) noack = dont_wait_for_ack; #endif //If the wait is coming as 0 with off channel set //then set the wait to 200 ms if (offchan && !wait) wait = ACTION_FRAME_DEFAULT_WAIT; hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d", __func__,pAdapter->device_mode); //Call sme API to send out a action frame. // OR can we send it directly through data path?? // After tx completion send tx status back. if ( ( WLAN_HDD_SOFTAP == pAdapter->device_mode ) || ( WLAN_HDD_P2P_GO == pAdapter->device_mode ) ) { if (type == SIR_MAC_MGMT_FRAME) { if (subType == SIR_MAC_MGMT_PROBE_RSP) { /* Drop Probe response recieved from supplicant, as for GO and SAP PE itself sends probe response */ goto err_rem_channel; } else if ((subType == SIR_MAC_MGMT_DISASSOC) || (subType == SIR_MAC_MGMT_DEAUTH)) { /* During EAP failure or P2P Group Remove supplicant * is sending del_station command to driver. From * del_station function, Driver will send deauth frame to * p2p client. No need to send disassoc frame from here. * so Drop the frame here and send tx indication back to * supplicant. */ tANI_U8 dstMac[ETH_ALEN] = {0}; memcpy(&dstMac, &buf[WLAN_HDD_80211_FRM_DA_OFFSET], ETH_ALEN); hddLog(VOS_TRACE_LEVEL_INFO, "%s: Deauth/Disassoc received for STA:" "%02x:%02x:%02x:%02x:%02x:%02x", __func__, dstMac[0], dstMac[1], dstMac[2], dstMac[3], dstMac[4], dstMac[5]); goto err_rem_channel; } } } if( NULL != cfgState->buf ) return -EBUSY; hddLog( LOG1, "Action frame tx request"); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) goAdapter = hdd_get_adapter( pAdapter->pHddCtx, WLAN_HDD_P2P_GO ); //If GO adapter exists and operating on same frequency //then we will not request remain on channel if( goAdapter && ( ieee80211_frequency_to_channel(chan->center_freq) == goAdapter->sessionCtx.ap.operatingChannel ) ) { goto send_frame; } #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) if( offchan && wait) { int status; // In case of P2P Client mode if we are already // on the same channel then send the frame directly if((cfgState->remain_on_chan_ctx != NULL) && (cfgState->current_freq == chan->center_freq) ) { hddLog(LOG1,"action frame: extending the wait time\n"); extendedWait = (tANI_U16)wait; goto send_frame; } INIT_COMPLETION(pAdapter->offchannel_tx_event); status = wlan_hdd_request_remain_on_channel(wiphy, dev, chan, channel_type, wait, cookie, OFF_CHANNEL_ACTION_TX); if(0 != status) { if( (-EBUSY == status) && (cfgState->current_freq == chan->center_freq) ) { goto send_frame; } goto err_rem_channel; } /* Wait for driver to be ready on the requested channel */ status = wait_for_completion_interruptible_timeout( &pAdapter->offchannel_tx_event, msecs_to_jiffies(WAIT_CHANGE_CHANNEL_FOR_OFFCHANNEL_TX)); if(!status) { hddLog( LOGE, "Not able to complete remain on channel request" " within timeout period"); goto err_rem_channel; } } else if ( offchan ) { /* Check before sending action frame whether we already remain on channel */ if(NULL == cfgState->remain_on_chan_ctx) { goto err_rem_channel; } } send_frame: #endif if(!noack) { cfgState->buf = vos_mem_malloc( len ); //buf; if( cfgState->buf == NULL ) return -ENOMEM; cfgState->len = len; vos_mem_copy( cfgState->buf, buf, len); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) if( cfgState->remain_on_chan_ctx ) { cfgState->action_cookie = cfgState->remain_on_chan_ctx->cookie; *cookie = cfgState->action_cookie; } else { #endif *cookie = (tANI_U32) cfgState->buf; cfgState->action_cookie = *cookie; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) } #endif } if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) || ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ) ) { tANI_U8 sessionId = pAdapter->sessionId; if ((type == SIR_MAC_MGMT_FRAME) && (subType == SIR_MAC_MGMT_ACTION) && (buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME)) { actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET]; hddLog(LOG1, "Tx Action Frame %u \n", actionFrmType); if (actionFrmType == WLAN_HDD_PROV_DIS_REQ) { cfgState->actionFrmState = HDD_PD_REQ_ACK_PENDING; hddLog(LOG1, "%s: HDD_PD_REQ_ACK_PENDING \n", __func__); } else if (actionFrmType == WLAN_HDD_GO_NEG_REQ) { cfgState->actionFrmState = HDD_GO_NEG_REQ_ACK_PENDING; hddLog(LOG1, "%s: HDD_GO_NEG_REQ_ACK_PENDING \n", __func__); } } if (eHAL_STATUS_SUCCESS != sme_sendAction( WLAN_HDD_GET_HAL_CTX(pAdapter), sessionId, buf, len, extendedWait, noack)) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: sme_sendAction returned fail", __func__); goto err; } } else if( ( WLAN_HDD_SOFTAP== pAdapter->device_mode ) || ( WLAN_HDD_P2P_GO == pAdapter->device_mode ) ) { if( VOS_STATUS_SUCCESS != WLANSAP_SendAction( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, buf, len, 0 ) ) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: WLANSAP_SendAction returned fail", __func__); goto err; } } return 0; err: if(!noack) { hdd_sendActionCnf( pAdapter, FALSE ); } return 0; err_rem_channel: *cookie = (tANI_U32)cfgState; cfg80211_mgmt_tx_status( pAdapter->dev, *cookie, buf, len, FALSE, GFP_KERNEL ); return 0; }
int wlan_hdd_cfg80211_cancel_remain_on_channel( struct wiphy *wiphy, struct net_device *dev, u64 cookie ) { hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); int status = 0; hddLog( LOG1, "Cancel remain on channel req"); if (((hdd_context_t*)pAdapter->pHddCtx)->isLogpInProgress) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:LOGP in Progress. Ignore!!!", __func__); return -EAGAIN; } /* FIXME cancel currently running remain on chan. * Need to check cookie and cancel accordingly */ if( (cfgState->remain_on_chan_ctx == NULL) || (cfgState->remain_on_chan_ctx->cookie != cookie) ) { hddLog( LOGE, "%s: No Remain on channel pending with specified cookie value", __func__); return -EINVAL; } /* wait until remain on channel ready event received * for already issued remain on channel request */ status = wait_for_completion_interruptible_timeout(&pAdapter->rem_on_chan_ready_event, msecs_to_jiffies(WAIT_REM_CHAN_READY)); if (!status) { hddLog( LOGE, "%s: timeout waiting for remain on channel ready indication", __func__); } INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var); /* Issue abort remain on chan request to sme. * The remain on channel callback will make sure the remain_on_chan * expired event is sent. */ if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) || ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) || ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ) ) { tANI_U8 sessionId = pAdapter->sessionId; sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter ), sessionId ); } else if ( (WLAN_HDD_SOFTAP== pAdapter->device_mode) || (WLAN_HDD_P2P_GO == pAdapter->device_mode) ) { WLANSAP_CancelRemainOnChannel( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext); } else { hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid device_mode = %d", __func__, pAdapter->device_mode); return -EIO; } wait_for_completion_interruptible_timeout(&pAdapter->cancel_rem_on_chan_var, msecs_to_jiffies(WAIT_CANCEL_REM_CHAN)); return 0; }
static int wlan_hdd_request_remain_on_channel( struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type, unsigned int duration, u64 *cookie, rem_on_channel_request_type_t request_type ) { hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); hdd_remain_on_chan_ctx_t *pRemainChanCtx; hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d", __func__,pAdapter->device_mode); hddLog( LOG1, "chan(hw_val)0x%x chan(centerfreq) %d chan type 0x%x, duration %d", chan->hw_value, chan->center_freq, channel_type, duration ); //Cancel existing remain On Channel if any wlan_hdd_cancel_existing_remain_on_channel(pAdapter); /* When P2P-GO and if we are trying to unload the driver then * wlan driver is keep on receiving the remain on channel command * and which is resulting in crash. So not allowing any remain on * channel requets when Load/Unload is in progress*/ if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress) { hddLog( LOGE, "%s: Wlan Load/Unload is in progress", __func__); return -EBUSY; } if (((hdd_context_t*)pAdapter->pHddCtx)->isLogpInProgress) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:LOGP in Progress. Ignore!!!", __func__); return -EAGAIN; } pRemainChanCtx = vos_mem_malloc( sizeof(hdd_remain_on_chan_ctx_t) ); if( NULL == pRemainChanCtx ) { hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not able to allocate memory for Channel context", __func__); return -ENOMEM; } vos_mem_copy( &pRemainChanCtx->chan, chan, sizeof(struct ieee80211_channel) ); pRemainChanCtx->chan_type = channel_type; pRemainChanCtx->duration = duration; pRemainChanCtx->dev = dev; *cookie = (tANI_U32) pRemainChanCtx; pRemainChanCtx->cookie = *cookie; pRemainChanCtx->rem_on_chan_request = request_type; cfgState->remain_on_chan_ctx = pRemainChanCtx; cfgState->current_freq = chan->center_freq; INIT_COMPLETION(pAdapter->rem_on_chan_ready_event); //call sme API to start remain on channel. if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) || ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) || ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ) ) { tANI_U8 sessionId = pAdapter->sessionId; //call sme API to start remain on channel. sme_RemainOnChannel( WLAN_HDD_GET_HAL_CTX(pAdapter), sessionId, chan->hw_value, duration, wlan_hdd_remain_on_channel_callback, pAdapter ); sme_RegisterMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), sessionId, (SIR_MAC_MGMT_FRAME << 2) | (SIR_MAC_MGMT_PROBE_REQ << 4), NULL, 0 ); } else if ( ( WLAN_HDD_SOFTAP== pAdapter->device_mode ) || ( WLAN_HDD_P2P_GO == pAdapter->device_mode ) ) { //call sme API to start remain on channel. if (VOS_STATUS_SUCCESS != WLANSAP_RemainOnChannel( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, chan->hw_value, duration, wlan_hdd_remain_on_channel_callback, pAdapter )) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: WLANSAP_RemainOnChannel returned fail", __func__); cfgState->remain_on_chan_ctx = NULL; vos_mem_free (pRemainChanCtx); return -EINVAL; } if (VOS_STATUS_SUCCESS != WLANSAP_RegisterMgmtFrame( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4), NULL, 0 )) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: WLANSAP_RegisterMgmtFrame returned fail", __func__); WLANSAP_CancelRemainOnChannel( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext); return -EINVAL; } } return 0; }
static void hdd_wlan_tx_complete( hdd_adapter_t* pAdapter, hdd_cfg80211_state_t* cfgState, tANI_BOOLEAN actionSendSuccess ) { struct ieee80211_radiotap_header *rthdr; unsigned char *pos; struct sk_buff *skb = cfgState->skb; #ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK hdd_context_t *pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx); #endif /* 2 Byte for TX flags and 1 Byte for Retry count */ u32 rtHdrLen = sizeof(*rthdr) + 3; u8 *data; /* We have to return skb with Data starting with MAC header. We have * copied SKB data starting with MAC header to cfgState->buf. We will pull * entire skb->len from skb and then we will push cfgState->buf to skb * */ if( NULL == skb_pull(skb, skb->len) ) { hddLog( LOGE, FL("Not Able to Pull %d byte from skb"), skb->len); kfree_skb(cfgState->skb); return; } data = skb_push( skb, cfgState->len ); if (data == NULL) { hddLog( LOGE, FL("Not Able to Push %d byte to skb"), cfgState->len); kfree_skb( cfgState->skb ); return; } memcpy( data, cfgState->buf, cfgState->len ); /* send frame to monitor interfaces now */ if( skb_headroom(skb) < rtHdrLen ) { hddLog( LOGE, FL("No headroom for rtap header")); kfree_skb(cfgState->skb); return; } rthdr = (struct ieee80211_radiotap_header*) skb_push( skb, rtHdrLen ); memset( rthdr, 0, rtHdrLen ); rthdr->it_len = cpu_to_le16( rtHdrLen ); rthdr->it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | (1 << IEEE80211_RADIOTAP_DATA_RETRIES) ); pos = (unsigned char *)( rthdr+1 ); // Fill TX flags *pos = actionSendSuccess; pos += 2; // Fill retry count *pos = 0; pos++; skb_set_mac_header( skb, 0 ); skb->ip_summed = CHECKSUM_NONE; skb->pkt_type = PACKET_OTHERHOST; skb->protocol = htons(ETH_P_802_2); memset( skb->cb, 0, sizeof( skb->cb ) ); #ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK wake_lock_timeout(&pHddCtx->rx_wake_lock, HDD_WAKE_LOCK_DURATION); #endif if (in_interrupt()) netif_rx( skb ); else netif_rx_ni( skb ); /* Enable Queues which we have disabled earlier */ netif_tx_start_all_queues( pAdapter->dev ); }
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 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(WEXT_SCAN_PENDING_GIVEUP == scanPendingOption) { pHddCtx->scan_info.waitScanResult = FALSE; return eHAL_STATUS_SUCCESS; } 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; } } else if(WEXT_SCAN_PENDING_PIGGYBACK == scanPendingOption) { pHddCtx->scan_info.waitScanResult = TRUE; return eHAL_STATUS_SUCCESS; } } pHddCtx->scan_info.waitScanResult = FALSE; while( WEXT_CSCAN_SSID_SECTION == str_ptr[i] ) { if(str_ptr[++i] != WEXT_CSCAN_CHANNEL_SECTION) { num_ssid++; i += str_ptr[i] + 1; } } VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: numSsid %d !!!",__func__, num_ssid); if( num_ssid ) { scanRequest.SSIDs.numOfSSIDs = num_ssid; 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; } ssid_start = WEXT_CSCAN_HEADER_SIZE + 1; for(j = 0; j < num_ssid; j++) { if( SIR_MAC_MAX_SSID_LENGTH < str_ptr[ssid_start]){ scanRequest.SSIDs.numOfSSIDs -= 1; } else{ 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); } ssid_start += str_ptr[ssid_start - 1] + 1; SsidInfo++; } } if ( WEXT_CSCAN_CHANNEL_SECTION == str_ptr[i]) { if( str_ptr[++i] == 0 ) { scanRequest.ChannelInfo.numOfChannels = 0; scanRequest.ChannelInfo.ChannelList = NULL; i++; } else { scanRequest.ChannelInfo.numOfChannels = str_ptr[i++]; scanRequest.ChannelInfo.ChannelList = vos_mem_malloc(scanRequest.ChannelInfo.numOfChannels * sizeof(v_U8_t)); if(NULL == scanRequest.ChannelInfo.ChannelList) { hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "memory alloc failed for channel list creation"); status = -ENOMEM; goto exit_point; } for(channelIdx = 0; channelIdx < scanRequest.ChannelInfo.numOfChannels; channelIdx++) { scanRequest.ChannelInfo.ChannelList[channelIdx] = (v_U8_t)str_ptr[i]; i += sizeof(v_U16_t); } } } scanRequest.scanType = eSIR_ACTIVE_SCAN; scanRequest.minChnTime = 0; scanRequest.maxChnTime = 0; if( WEXT_CSCAN_PASV_DWELL_SECTION == (str_ptr[i]) ) { if (!num_ssid || (eSIR_PASSIVE_SCAN == pHddCtx->scan_info.scan_mode)) { scanRequest.scanType = eSIR_PASSIVE_SCAN; scanRequest.minChnTime = (v_U8_t)str_ptr[++i]; scanRequest.maxChnTime = (v_U8_t)str_ptr[++i]; i++; } else { i += 3; } } 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]; scanRequest.maxChnTime = str_ptr[++i]; i++; } else { i +=3; } } scanRequest.BSSType = eCSR_BSS_TYPE_ANY; scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN; pHddCtx->scan_info.mScanPending = TRUE; 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; if (SIR_MAC_MAX_IE_LENGTH >= pwextBuf->genIE.length) { memcpy( pwextBuf->roamProfile.addIEScan, pHddCtx->scan_info.scanAddIE.addIEdata, pHddCtx->scan_info.scanAddIE.length); pwextBuf->roamProfile.nAddIEScanLength = pHddCtx->scan_info.scanAddIE.length; } else { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "Invalid ScanIE, Length is %d", pwextBuf->genIE.length); } memset( &pwextBuf->genIE, 0, sizeof(pwextBuf->genIE) ); } 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; } else { status = -1; } exit_point: if (scanRequest.SSIDs.SSIDList) { vos_mem_free(scanRequest.SSIDs.SSIDList); } 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; }
void hdd_sendMgmtFrameOverMonitorIface( hdd_adapter_t *pMonAdapter, tANI_U32 nFrameLength, tANI_U8* pbFrames, tANI_U8 frameType ) { //Indicate a Frame over Monitor Intf. int rxstat; struct sk_buff *skb = NULL; int needed_headroom = 0; int flag = HDD_RX_FLAG_IV_STRIPPED | HDD_RX_FLAG_DECRYPTED | HDD_RX_FLAG_MMIC_STRIPPED; #ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK hdd_context_t* pHddCtx = (hdd_context_t*)(pMonAdapter->pHddCtx); #endif hddLog( LOG1, FL("Indicate Frame over Monitor Intf")); VOS_ASSERT( (pbFrames != NULL) ); /* room for the radiotap header based on driver features * 1 Byte for RADIO TAP Flag, 1 Byte padding and 2 Byte for * RX flags. * */ needed_headroom = sizeof(struct ieee80211_radiotap_header) + 4; //alloc skb here skb = alloc_skb(VPKT_SIZE_BUFFER, GFP_ATOMIC); if (unlikely(NULL == skb)) { hddLog( LOGW, FL("Unable to allocate skb")); return; } skb_reserve(skb, VPKT_SIZE_BUFFER); if (unlikely(skb_headroom(skb) < nFrameLength)) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "HDD [%d]: Insufficient headroom, " "head[%p], data[%p], req[%d]", __LINE__, skb->head, skb->data, nFrameLength); kfree_skb(skb); return ; } // actually push the data memcpy(skb_push(skb, nFrameLength), pbFrames, nFrameLength); /* prepend radiotap information */ if( 0 != hdd_wlan_add_rx_radiotap_hdr( skb, needed_headroom, flag ) ) { hddLog( LOGE, FL("Not Able Add Radio Tap")); //free skb kfree_skb(skb); return ; } skb_reset_mac_header( skb ); skb->dev = pMonAdapter->dev; skb->protocol = eth_type_trans( skb, skb->dev ); skb->ip_summed = CHECKSUM_NONE; #ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK wake_lock_timeout(&pHddCtx->rx_wake_lock, HDD_WAKE_LOCK_DURATION); #endif rxstat = netif_rx_ni(skb); if( NET_RX_SUCCESS == rxstat ) { hddLog( LOG1, FL("Success")); } else hddLog( LOGE, FL("Failed %d"), rxstat); return ; }
int wlan_hdd_add_virtual_intf( struct wiphy *wiphy, char *name, enum nl80211_iftype type, u32 *flags, struct vif_params *params ) #endif { hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy); hdd_adapter_t* pAdapter = NULL; ENTER(); if(hdd_get_adapter(pHddCtx, wlan_hdd_get_session_type(type)) != NULL) { hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Interface type %d already exists. Two" "interfaces of same type are not supported currently.",__func__, type); return NULL; } if (pHddCtx->isLogpInProgress) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:LOGP in Progress. Ignore!!!", __func__); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) return NULL; #else return -EAGAIN; #endif } if ( pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated ) { if( (NL80211_IFTYPE_P2P_GO == type) || (NL80211_IFTYPE_P2P_CLIENT == type) ) { /* Generate the P2P Interface Address. this address must be * different from the P2P Device Address. */ v_MACADDR_t p2pDeviceAddress = pHddCtx->p2pDeviceAddress; p2pDeviceAddress.bytes[4] ^= 0x80; pAdapter = hdd_open_adapter( pHddCtx, wlan_hdd_get_session_type(type), name, p2pDeviceAddress.bytes, VOS_TRUE ); } } else { pAdapter = hdd_open_adapter( pHddCtx, wlan_hdd_get_session_type(type), name, wlan_hdd_get_intf_addr(pHddCtx), VOS_TRUE ); } if( NULL == pAdapter) { hddLog(VOS_TRACE_LEVEL_ERROR,"%s: hdd_open_adapter failed",__func__); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) return NULL; #else return -EINVAL; #endif } EXIT(); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) return pAdapter->dev; #else return 0; #endif }
/**-------------------------------------------------------------------------------------------- \brief __iw_set_oem_data_req() - This function sets the oem data req configuration. This invokes the respective sme oem data req functionality. Function for handling the set IOCTL for the oem data req configuration \param - dev - Pointer to the net device - info - Pointer to the iw_oem_data_req - wrqu - Pointer to the iwreq data - extra - Pointer to the data \return - 0 for success, non zero for failure -----------------------------------------------------------------------------------------------*/ int __iw_set_oem_data_req( struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { int rc = 0; eHalStatus status = eHAL_STATUS_SUCCESS; struct iw_oem_data_req *pOemDataReq = NULL; tOemDataReqConfig oemDataReqConfig; tANI_U32 oemDataReqID = 0; hdd_adapter_t *pAdapter; hdd_context_t *pHddCtx; hdd_wext_state_t *pwextBuf; ENTER(); pAdapter = (netdev_priv(dev)); if (NULL == pAdapter) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL",__func__); return -EINVAL; } pHddCtx = WLAN_HDD_GET_CTX(pAdapter); rc = wlan_hdd_validate_context(pHddCtx); if (0 != rc) { return rc; } pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); if (NULL == pwextBuf) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: pwextBuf is NULL",__func__); return -EINVAL; } do { if (NULL != wrqu->data.pointer) { pOemDataReq = (struct iw_oem_data_req *)wrqu->data.pointer; } if (pOemDataReq == NULL) { hddLog(LOGE, "in %s oemDataReq == NULL", __func__); rc = -EIO; break; } vos_mem_zero(&oemDataReqConfig, sizeof(tOemDataReqConfig)); if (copy_from_user((&oemDataReqConfig)->oemDataReq, pOemDataReq->oemDataReq, OEM_DATA_REQ_SIZE)) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s: copy_from_user() failed!", __func__); rc = -EFAULT; break; } status = sme_OemDataReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, &oemDataReqConfig, &oemDataReqID, &hdd_OemDataReqCallback, dev); if (status != eHAL_STATUS_SUCCESS) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: sme_OemDataReq status %d", __func__, status); rc = -EFAULT; break; } pwextBuf->oemDataReqID = oemDataReqID; pwextBuf->oemDataReqInProgress = TRUE; } while(0); EXIT(); return rc; }
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 %02x:%02x:%02x:%02x:%02x:%02x", descriptor->bssId[0], descriptor->bssId[1], descriptor->bssId[2], descriptor->bssId[3], descriptor->bssId[4], descriptor->bssId[5]); error = 0; last_event = current_event; vos_mem_zero(&event, sizeof (event)); 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) { hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWAP "); return -E2BIG; } last_event = current_event; vos_mem_zero(&event, sizeof (struct iw_event)); 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) { hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWNAME"); return -E2BIG; } last_event = current_event; vos_mem_zero( &event, sizeof (struct iw_event)); 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) { return -E2BIG; } last_event = current_event; vos_mem_zero( &event, sizeof (struct iw_event)); 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 { 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) { hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWMODE"); return -E2BIG; } ie_length = GET_IE_LEN_IN_BSS( descriptor->length ); if (ie_length > 0) { 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) { 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)); 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; 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) { 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) { return -E2BIG; } } last_event = current_event; vos_mem_zero( &event, sizeof (struct iw_event)); event.cmd = IWEVQUAL; event.u.qual.qual = descriptor->rssi; event.u.qual.noise = descriptor->sinr; 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) { hddLog( LOGW, "hdd_IndicateScanResult: no space for IWEVQUAL"); return -E2BIG; } 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) { hddLog( LOGW, "hdd_IndicateScanResult: no space for IWEVCUSTOM (age)"); return -E2BIG; } scanInfo->start = current_event; return 0; }
void hdd_indicateMgmtFrame( hdd_adapter_t *pAdapter, tANI_U32 nFrameLength, tANI_U8* pbFrames, tANI_U8 frameType, tANI_U32 rxChan ) { tANI_U16 freq; tANI_U8 type = 0; tANI_U8 subType = 0; tActionFrmType actionFrmType; hdd_cfg80211_state_t *cfgState = NULL; hddLog(VOS_TRACE_LEVEL_INFO, "%s: Frame Type = %d Frame Length = %d\n", __func__, frameType, nFrameLength); if (NULL == pAdapter) { hddLog( LOGE, FL("pAdapter is NULL")); return; } if (NULL == pAdapter->dev) { hddLog( LOGE, FL("pAdapter->dev is NULL")); return; } if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) { hddLog( LOGE, FL("pAdapter has invalid magic")); return; } if( !nFrameLength ) { hddLog( LOGE, FL("Frame Length is Invalid ZERO")); return; } if (NULL == pbFrames) { hddLog( LOGE, FL("pbFrames is NULL")); return; } if( ( WLAN_HDD_SOFTAP == pAdapter->device_mode ) || ( WLAN_HDD_P2P_GO == pAdapter->device_mode ) ) { hdd_adapter_t *pMonAdapter = hdd_get_mon_adapter( WLAN_HDD_GET_CTX(pAdapter) ); if( NULL != pMonAdapter ) { hddLog( LOG1, FL("Indicate Frame over Monitor Interface")); hdd_sendMgmtFrameOverMonitorIface( pMonAdapter, nFrameLength, pbFrames, frameType); return; } } //Channel indicated may be wrong. TODO //Indicate an action frame. if( rxChan <= MAX_NO_OF_2_4_CHANNELS ) { freq = ieee80211_channel_to_frequency( rxChan, IEEE80211_BAND_2GHZ); } else { freq = ieee80211_channel_to_frequency( rxChan, IEEE80211_BAND_5GHZ); } type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]); subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]); cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); if ((type == SIR_MAC_MGMT_FRAME) && (subType == SIR_MAC_MGMT_ACTION) && (pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME)) { actionFrmType = pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET]; hddLog(LOG1, "Rx Action Frame %u \n", actionFrmType); #ifdef WLAN_FEATURE_P2P_DEBUG if(actionFrmType > MAX_P2P_ACTION_FRAME_TYPE) { hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] unknown[%d] <--- OTA", actionFrmType); } else { hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] %s <--- OTA", p2p_action_frame_type[actionFrmType]); if( (actionFrmType == WLAN_HDD_PROV_DIS_REQ) && (globalP2PConnectionStatus == P2P_NOT_ACTIVE) ) { globalP2PConnectionStatus = P2P_GO_NEG_PROCESS; hddLog(LOGE,"[P2P State]Inactive state to " "GO negotation progress state"); } else if( (actionFrmType == WLAN_HDD_GO_NEG_CNF) && (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS) ) { globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED; hddLog(LOGE,"[P2P State]GO nego progress to GO nego" " completed state"); } else if( (actionFrmType == WLAN_HDD_INVITATION_REQ) && (globalP2PConnectionStatus == P2P_NOT_ACTIVE) ) { globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED; hddLog(LOGE,"[P2P State]Inactive state to GO nego" " completed state Autonomus GO fromation"); } } #endif if (((actionFrmType == WLAN_HDD_PROV_DIS_RESP) && (cfgState->actionFrmState == HDD_PD_REQ_ACK_PENDING)) || ((actionFrmType == WLAN_HDD_GO_NEG_RESP) && (cfgState->actionFrmState == HDD_GO_NEG_REQ_ACK_PENDING))) { hddLog(LOG1, "%s: ACK_PENDING and But received RESP for Action frame ", __func__); hdd_sendActionCnf(pAdapter, TRUE); } } //Indicate Frame Over Normal Interface hddLog( LOG1, FL("Indicate Frame over NL80211 Interface")); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) cfg80211_rx_mgmt( pAdapter->dev, freq, 0, pbFrames, nFrameLength, GFP_ATOMIC ); #else cfg80211_rx_mgmt( pAdapter->dev, freq, pbFrames, nFrameLength, GFP_ATOMIC ); #endif //LINUX_VERSION_CODE }
int iw_get_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); tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); tCsrScanResultInfo *pScanResult; eHalStatus status = eHAL_STATUS_SUCCESS; hdd_scan_info_t scanInfo; tScanResultHandle pResult; int i = 0; VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter buffer length %d!!!", __func__, (wrqu->data.length)?wrqu->data.length:IW_SCAN_MAX_DATA); ENTER(); if (TRUE == pHddCtx->scan_info.mScanPending) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:mScanPending is TRUE !!!",__func__); return -EAGAIN; } if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__); return -EAGAIN; } scanInfo.dev = dev; scanInfo.start = extra; scanInfo.info = info; if (0 == wrqu->data.length) { scanInfo.end = extra + IW_SCAN_MAX_DATA; } else { scanInfo.end = extra + wrqu->data.length; } status = sme_ScanGetResult(hHal,pAdapter->sessionId,NULL,&pResult); if (NULL == pResult) { hddLog(LOG1,"iw_get_scan: NULL Scan Result "); return 0; } pScanResult = sme_ScanResultGetFirst(hHal, pResult); while (pScanResult) { status = hdd_IndicateScanResult(&scanInfo, pScanResult); if (0 != status) { break; } i++; pScanResult = sme_ScanResultGetNext(hHal, pResult); } sme_ScanResultPurge(hHal, pResult); EXIT(); VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit total %d BSS reported !!!",__func__, i); return status; }