Пример #1
0
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__);
        }
    }
}
Пример #2
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)
{
    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;
}
Пример #4
0
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);
}
Пример #5
0
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);
    }
}
Пример #6
0
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;
}
Пример #8
0
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;
}
Пример #9
0
/**
 * 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;
}
Пример #12
0
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;
}
Пример #13
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;
}
Пример #14
0
/*---------------------------------------------------------------------------------------------

  \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;
}
Пример #15
0
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;
}
Пример #16
0
/**--------------------------------------------------------------------------------------------

  \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;
}
Пример #17
0
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);
    }
}
Пример #18
0
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;
}
Пример #19
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;
}
Пример #20
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;
}
Пример #21
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;
}
Пример #22
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;

}
Пример #23
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;
}
Пример #25
0
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 ;
}
Пример #26
0
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
}
Пример #27
0
/**--------------------------------------------------------------------------------------------

  \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, &current_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;
}
Пример #29
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;
}