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; }
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; }
int hdd_setP2pNoa( struct net_device *dev, tANI_U8 *command ) { hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); VOS_STATUS status = VOS_STATUS_SUCCESS; tP2pPsConfig NoA; int count, duration, interval; char *param; param = strchr(command, ' '); if (param == NULL) return -1; param++; sscanf(param, "%d %d %d", &count, &duration, &interval); VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: P2P_SET GO NoA: count=%d duration=%d interval=%d \n", __func__, count, duration, interval); /* PS Selection * Periodic NoA (2) * Single NOA (4) */ NoA.opp_ps = 0; NoA.ctWindow = 0; if (count == 1) { NoA.duration = 0; NoA.single_noa_duration = duration; NoA.psSelection = P2P_POWER_SAVE_TYPE_SINGLE_NOA; } else { NoA.duration = duration; NoA.single_noa_duration = 0; NoA.psSelection = P2P_POWER_SAVE_TYPE_PERIODIC_NOA; } NoA.interval = interval; NoA.count = count; NoA.sessionid = pAdapter->sessionId; VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d " "interval %d count %d single noa duration %d " "PsSelection %x \n", __func__, NoA.opp_ps, NoA.ctWindow, NoA.duration, NoA.interval, NoA.count, NoA.single_noa_duration, NoA.psSelection); sme_p2pSetPs(hHal, &NoA); return status; }
/**-------------------------------------------------------------------------------------------- \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; }
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 hdd_setP2pPs( struct net_device *dev, void *msgData ) { hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); VOS_STATUS status = VOS_STATUS_SUCCESS; tP2pPsConfig NoA; p2p_app_setP2pPs_t *pappNoA = (p2p_app_setP2pPs_t *) msgData; NoA.opp_ps = pappNoA->opp_ps; NoA.ctWindow = pappNoA->ctWindow; NoA.duration = pappNoA->duration; NoA.interval = pappNoA->interval; NoA.count = pappNoA->count; NoA.single_noa_duration = pappNoA->single_noa_duration; NoA.psSelection = pappNoA->psSelection; NoA.sessionid = pAdapter->sessionId; sme_p2pSetPs(hHal, &NoA); return status; }
/**-------------------------------------------------------------------------------------------- \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; }
int hdd_setP2pOpps( struct net_device *dev, tANI_U8 *command ) { hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); VOS_STATUS status = VOS_STATUS_SUCCESS; tP2pPsConfig NoA; char *param; int legacy_ps, opp_ps, ctwindow; param = strchr(command, ' '); if (param == NULL) return -1; param++; sscanf(param, "%d %d %d", &legacy_ps, &opp_ps, &ctwindow); VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: P2P_SET GO PS: legacy_ps=%d opp_ps=%d ctwindow=%d \n", __func__, legacy_ps, opp_ps, ctwindow); /* PS Selection * Opportunistic Power Save (1) */ /* From wpa_cli user need to use separate command to set ctWindow and Opps * When user want to set ctWindow during that time other parameters * values are coming from wpa_supplicant as -1. * Example : User want to set ctWindow with 30 then wpa_cli command : * P2P_SET ctwindow 30 * Command Received at hdd_hostapd_ioctl is as below: * P2P_SET_PS -1 -1 30 (legacy_ps = -1, opp_ps = -1, ctwindow = 30) */ if (ctwindow != -1) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Opportunistic Power Save is %s \n", (TRUE == pAdapter->ops) ? "Enable" : "Disable" ); if (ctwindow != pAdapter->ctw) { pAdapter->ctw = ctwindow; if(pAdapter->ops) { NoA.opp_ps = pAdapter->ops; NoA.ctWindow = pAdapter->ctw; NoA.duration = 0; NoA.single_noa_duration = 0; NoA.interval = 0; NoA.count = 0; NoA.psSelection = P2P_POWER_SAVE_TYPE_OPPORTUNISTIC; NoA.sessionid = pAdapter->sessionId; VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d " "interval %d count %d single noa duration %d " "PsSelection %x \n", __func__, NoA.opp_ps, NoA.ctWindow, NoA.duration, NoA.interval, NoA.count, NoA.single_noa_duration, NoA.psSelection); sme_p2pSetPs(hHal, &NoA); } return 0; } } if (opp_ps != -1) { pAdapter->ops = opp_ps; if ((opp_ps != -1) && (pAdapter->ctw)) { NoA.opp_ps = opp_ps; NoA.ctWindow = pAdapter->ctw; NoA.duration = 0; NoA.single_noa_duration = 0; NoA.interval = 0; NoA.count = 0; NoA.psSelection = P2P_POWER_SAVE_TYPE_OPPORTUNISTIC; NoA.sessionid = pAdapter->sessionId; VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d " "interval %d count %d single noa duration %d " "PsSelection %x \n", __func__, NoA.opp_ps, NoA.ctWindow, NoA.duration, NoA.interval, NoA.count, NoA.single_noa_duration, NoA.psSelection); sme_p2pSetPs(hHal, &NoA); } } return status; }
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 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( LOGE, "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( LOGE, "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( LOGE, "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_MASTER; } 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( LOGE, "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( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWESSID"); return -E2BIG; } } if( hdd_GetWPARSNIEs( ( tANI_U8 *) descriptor->ieFields, ie_length, &last_event, ¤t_event, scanInfo ) < 0 ) { hddLog( LOGE, "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( LOGE, "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( LOGE, "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, VOS_MAC_ADDR_SIZE))) { 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( LOGE, "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( LOGE, "hdd_IndicateScanResult: no space for IWEVCUSTOM (age)"); return -E2BIG; } scanInfo->start = current_event; return 0; }
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; }
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; }
vos_mem_copy(&setKey.Key[0], &Keys->KeyMaterial[key_index][0], Keys->KeyLength[key_index]); setKey.keyDirection = eSIR_TX_ONLY; vos_mem_copy(setKey.peerMac, &pHddStaCtx->conn_info.bssId[0], WNI_CFG_BSSID_LEN); setKey.encType = pWextState->roamProfile.EncryptionType.encryptionType[0]; /* issue set key request */ status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, &setKey, &roamId ); if ( 0 != status ) { hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamSetKey failed, returned %d", __func__, status); return -EINVAL; } } } /* In SoftAp mode setting key direction for default mode */ else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode ) {
/**-------------------------------------------------------------------------------------------- \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; }