コード例 #1
0
/**
 * __wcnss_debugfs_open() - open debugfs
 * @inode: inode pointer
 * @file: file pointer
 *
 * Return: 0 on success, error number otherwise
 */
static int __wcnss_debugfs_open(struct inode *inode, struct file *file)
{
	hdd_adapter_t *adapter;
	hdd_context_t *hdd_ctx;
	int ret;

	ENTER();

	if (inode->i_private)
		file->private_data = inode->i_private;

	adapter = (hdd_adapter_t *)file->private_data;
	if ((NULL == adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
		VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
			   "%s: Invalid adapter or adapter has invalid magic.",
			   __func__);
		return -EINVAL;
	}

	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	ret = wlan_hdd_validate_context(hdd_ctx);
	if (0 != ret)
		return ret;

	EXIT();
	return 0;
}
コード例 #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;
}
コード例 #3
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;
}
コード例 #4
0
ファイル: wlan_hdd_scan.c プロジェクト: Tkkg1994/qcacld-2.0
/**
 * __iw_get_scan() - get scan results
 * @dev: Pointer to the net device.
 * @info: Pointer to the iw_request_info.
 * @wrqu: Pointer to the iwreq_data.
 * @extra: Pointer to the data.
 *
 * This function returns the scan results to the wpa_supplicant
 *
 * Return: 0 on success, error number otherwise
 */
static 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) ;
   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;
   hdd_context_t *hdd_ctx;
   int ret;

   ENTER();

   hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
   ret = wlan_hdd_validate_context(hdd_ctx);
   if (0 != ret)
       return ret;

   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);

   if (TRUE == pAdapter->scan_info.mScanPending)
   {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:mScanPending is TRUE !!!",__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)
   {
       // no scan results
       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);

   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit total %d BSS reported !!!",__func__, i);
   EXIT();
   return status;
}
コード例 #5
0
ファイル: wlan_hdd_scan.c プロジェクト: Tkkg1994/qcacld-2.0
/**
 * __iw_set_scan() - set scan request
 * @dev: Pointer to the net device.
 * @info: Pointer to the iw_request_info.
 * @wrqu: Pointer to the iwreq_data.
 * @extra: Pointer to the data.
 *
 * This function process the scan request from the wpa_supplicant
 * and set the scan request to the SME
 *
 * Return: 0 on success, error number otherwise
 */
static int __iw_set_scan(struct net_device *dev, struct iw_request_info *info,
			 union iwreq_data *wrqu, char *extra)
{
   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
   hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
   hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
   tCsrScanRequest scanRequest;
   v_U32_t scanId = 0;
   eHalStatus status = eHAL_STATUS_SUCCESS;
   struct iw_scan_req *scanReq = (struct iw_scan_req *)extra;
   hdd_adapter_t *con_sap_adapter;
   uint16_t con_dfs_ch;
   int ret;

   ENTER();

   ret = wlan_hdd_validate_context(pHddCtx);
   if (0 != ret)
       return ret;

   /* Block All Scan during DFS operation and send null scan result */
   con_sap_adapter = hdd_get_con_sap_adapter(pAdapter, true);
   if (con_sap_adapter) {
       con_dfs_ch = con_sap_adapter->sessionCtx.ap.operatingChannel;

       if (VOS_IS_DFS_CH(con_dfs_ch)) {
           hddLog(LOGW, "%s:##In DFS Master mode. Scan aborted", __func__);
           return -EOPNOTSUPP;
       }
   }


   if(pAdapter->scan_info.mScanPending == TRUE)
   {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:mScanPending is TRUE !!!",__func__);
       return eHAL_STATUS_SUCCESS;
   }

   vos_mem_zero( &scanRequest, sizeof(scanRequest));

   if (NULL != wrqu->data.pointer)
   {
       /* set scanType, active or passive */
       if ((IW_SCAN_TYPE_ACTIVE ==  scanReq->scan_type) ||
           (eSIR_ACTIVE_SCAN == pHddCtx->ioctl_scan_mode))
       {
           scanRequest.scanType = eSIR_ACTIVE_SCAN;
       }
       else
       {
           scanRequest.scanType = eSIR_PASSIVE_SCAN;
       }

       /* set bssid using sockaddr from iw_scan_req */
       vos_mem_copy(scanRequest.bssid,
                       &scanReq->bssid.sa_data, sizeof(scanRequest.bssid) );

      if (wrqu->data.flags & IW_SCAN_THIS_ESSID)  {

          if(scanReq->essid_len &&
              (scanReq->essid_len <= SIR_MAC_MAX_SSID_LENGTH)) {
              scanRequest.SSIDs.numOfSSIDs = 1;
              scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo));
              if(scanRequest.SSIDs.SSIDList) {
                 scanRequest.SSIDs.SSIDList->SSID.length =             scanReq->essid_len;
                 vos_mem_copy(scanRequest.SSIDs.SSIDList->  SSID.ssId,scanReq->essid,scanReq->essid_len);
              }
              else
              {
                scanRequest.SSIDs.numOfSSIDs = 0;
                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Unable to allocate memory",__func__);
                VOS_ASSERT(0);
              }
          }
          else
          {
            hddLog(LOGE, FL("Invalid essid length : %d"), scanReq->essid_len);
          }
      }

       /* set min and max channel time */
       scanRequest.minChnTime = scanReq->min_channel_time;
       scanRequest.maxChnTime = scanReq->max_channel_time;

   }
   else
   {
       if (pHddCtx->ioctl_scan_mode == eSIR_ACTIVE_SCAN) {
           /* set the scan type to active */
           scanRequest.scanType = eSIR_ACTIVE_SCAN;
       } else {
           scanRequest.scanType = eSIR_PASSIVE_SCAN;
       }

       vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );

       /* set min and max channel time to zero */
       scanRequest.minChnTime = 0;
       scanRequest.maxChnTime = 0;
   }

   /* set BSSType to default type */
   scanRequest.BSSType = eCSR_BSS_TYPE_ANY;

   /*Scan all the channels */
   scanRequest.ChannelInfo.numOfChannels = 0;

   scanRequest.ChannelInfo.ChannelList = NULL;

   /* set requestType to full scan */
   scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;

   /* if previous genIE is not NULL, update ScanIE */
   if (0 != pwextBuf->genIE.length)
   {
       memset( &pAdapter->scan_info.scanAddIE, 0, sizeof(pAdapter->scan_info.scanAddIE) );
       memcpy( pAdapter->scan_info.scanAddIE.addIEdata, pwextBuf->genIE.addIEdata,
           pwextBuf->genIE.length );
       pAdapter->scan_info.scanAddIE.length = pwextBuf->genIE.length;

       pwextBuf->roamProfile.pAddIEScan = pAdapter->scan_info.scanAddIE.addIEdata;
       pwextBuf->roamProfile.nAddIEScanLength = pAdapter->scan_info.scanAddIE.length;

       /* clear previous genIE after use it */
       memset( &pwextBuf->genIE, 0, sizeof(pwextBuf->genIE) );
   }

   /* push addIEScan in scanRequset if exist */
   if (pAdapter->scan_info.scanAddIE.addIEdata &&
       pAdapter->scan_info.scanAddIE.length)
   {
       scanRequest.uIEFieldLen = pAdapter->scan_info.scanAddIE.length;
       scanRequest.pIEField = pAdapter->scan_info.scanAddIE.addIEdata;
   }

   status = sme_ScanRequest((WLAN_HDD_GET_CTX(pAdapter))->hHal,
                             pAdapter->sessionId, &scanRequest, &scanId,
                             &hdd_ScanRequestCallback, dev);
   if (!HAL_STATUS_SUCCESS(status))
   {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:sme_ScanRequest  fail %d!!!",__func__, status);
       goto error;
   }

   pAdapter->scan_info.mScanPending = TRUE;

   pAdapter->scan_info.scanId = scanId;

error:
   if ((wrqu->data.flags & IW_SCAN_THIS_ESSID) && (scanReq->essid_len))
       vos_mem_free(scanRequest.SSIDs.SSIDList);

   EXIT();
   return status;
}
コード例 #6
0
/**
 * __wcnss_wowenable_write() - write wow enable
 * @file: file pointer
 * @buf: buffer
 * @count: count
 * @ppos: position pointer
 *
 * Return: 0 on success, error number otherwise
 */
static ssize_t __wcnss_wowenable_write(struct file *file,
               const char __user *buf, size_t count, loff_t *ppos)
{

    hdd_adapter_t *pAdapter;
    hdd_context_t *hdd_ctx;
    char cmd[MAX_USER_COMMAND_SIZE_WOWL_ENABLE + 1];
    char *sptr, *token;
    v_U8_t wow_enable = 0;
    v_U8_t wow_mp = 0;
    v_U8_t wow_pbm = 0;
    int ret;

    ENTER();

    pAdapter = (hdd_adapter_t *)file->private_data;
    if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                  "%s: Invalid adapter or adapter has invalid magic.",
                  __func__);

        return -EINVAL;
    }

    hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
        return ret;

    if (!sme_IsFeatureSupportedByFW(WOW))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Wake-on-Wireless feature is not supported "
                  "in firmware!", __func__);

        return -EINVAL;
    }

    if (count > MAX_USER_COMMAND_SIZE_WOWL_ENABLE)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Command length is larger than %d bytes.",
                  __func__, MAX_USER_COMMAND_SIZE_WOWL_ENABLE);

        return -EINVAL;
    }

    /* Get command from user */
    if (copy_from_user(cmd, buf, count))
        return -EFAULT;
    cmd[count] = '\0';
    sptr = cmd;

    /* Get enable or disable wow */
    token = strsep(&sptr, " ");
    if (!token)
        return -EINVAL;
    if (kstrtou8(token, 0, &wow_enable))
        return -EINVAL;

    /* Disable wow */
    if (!wow_enable) {
        if (!hdd_exit_wowl(pAdapter))
        {
          VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    "%s: hdd_exit_wowl failed!", __func__);

          return -EFAULT;
        }

        return count;
    }

    /* Get enable or disable magic packet mode */
    token = strsep(&sptr, " ");
    if (!token)
        return -EINVAL;
    if (kstrtou8(token, 0, &wow_mp))
        return -EINVAL;
    if (wow_mp > 1)
        wow_mp = 1;

    /* Get enable or disable pattern byte matching mode */
    token = strsep(&sptr, " ");
    if (!token)
        return -EINVAL;
    if (kstrtou8(token, 0, &wow_pbm))
        return -EINVAL;
    if (wow_pbm > 1)
        wow_pbm = 1;

    if (!hdd_enter_wowl(pAdapter, wow_mp, wow_pbm))
    {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: hdd_enter_wowl failed!", __func__);

      return -EFAULT;
    }
    EXIT();
    return count;
}
コード例 #7
0
/**
 * __wcnss_patterngen_write() - write pattern
 * @file: file pointer
 * @buf: buffer
 * @count: count
 * @ppos: position pointer
 *
 * Return: 0 on success, error number otherwise
 */
static ssize_t __wcnss_patterngen_write(struct file *file,
					const char __user *buf,
					size_t count, loff_t *ppos)
{
    hdd_adapter_t *pAdapter;
    hdd_context_t *pHddCtx;
    tSirAddPeriodicTxPtrn *addPeriodicTxPtrnParams;
    tSirDelPeriodicTxPtrn *delPeriodicTxPtrnParams;

    char *cmd, *sptr, *token;
    v_U8_t pattern_idx = 0;
    v_U8_t pattern_duration = 0;
    char *pattern_buf;
    v_U16_t pattern_len = 0;
    v_U16_t i = 0;
    int ret;

    ENTER();

    pAdapter = (hdd_adapter_t *)file->private_data;
    if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                   "%s: Invalid adapter or adapter has invalid magic.",
                   __func__);

        return -EINVAL;
    }

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret)
        return ret;

    if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: Periodic Tx Pattern Offload feature is not supported "
                   "in firmware!", __func__);
        return -EINVAL;
    }

    /* Get command from user */
    if (count <= MAX_USER_COMMAND_SIZE_FRAME)
        cmd = vos_mem_malloc(count + 1);
    else
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: Command length is larger than %d bytes.",
                   __func__, MAX_USER_COMMAND_SIZE_FRAME);

        return -EINVAL;
    }

    if (!cmd)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Memory allocation for cmd failed!", __func__);

        return -EFAULT;
    }

    if (copy_from_user(cmd, buf, count))
    {
        vos_mem_free(cmd);
        return -EFAULT;
    }
    cmd[count] = '\0';
    sptr = cmd;

    /* Get pattern idx */
    token = strsep(&sptr, " ");
    if (!token)
        goto failure;
    if (kstrtou8(token, 0, &pattern_idx))
        goto failure;

    if (pattern_idx > (MAXNUM_PERIODIC_TX_PTRNS - 1))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: Pattern index %d is not in the range (0 ~ %d).",
                   __func__, pattern_idx, MAXNUM_PERIODIC_TX_PTRNS - 1);

        goto failure;
    }

    /* Get pattern duration */
    token = strsep(&sptr, " ");
    if (!token)
        goto failure;
    if (kstrtou8(token, 0, &pattern_duration))
        goto failure;

    /* Delete pattern using index if duration is 0 */
    if (!pattern_duration)
    {
        delPeriodicTxPtrnParams =
            vos_mem_malloc(sizeof(tSirDelPeriodicTxPtrn));
        if (!delPeriodicTxPtrnParams)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: Memory allocation for delPeriodicTxPtrnParams "
                      "failed!", __func__);

            vos_mem_free(cmd);
            return -EFAULT;
        }
        delPeriodicTxPtrnParams->ucPtrnId = pattern_idx;
        delPeriodicTxPtrnParams->ucPatternIdBitmap = 1 << pattern_idx;
        vos_mem_copy(delPeriodicTxPtrnParams->macAddress,
                    pAdapter->macAddressCurrent.bytes, 6);

        /* Delete pattern */
        if (eHAL_STATUS_SUCCESS != sme_DelPeriodicTxPtrn(pHddCtx->hHal,
                                                delPeriodicTxPtrnParams))
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                       "%s: sme_DelPeriodicTxPtrn() failed!", __func__);

            vos_mem_free(delPeriodicTxPtrnParams);
            goto failure;
        }
        vos_mem_free(cmd);
        vos_mem_free(delPeriodicTxPtrnParams);
        return count;
    }

    /* Check if it's in connected state only when adding patterns */
    if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: Not in Connected state!", __func__);

        goto failure;
    }

    /* Get pattern */
    token = strsep(&sptr, " ");
    if (!token)
        goto failure;

    pattern_buf = token;
    pattern_buf[strlen(pattern_buf) - 1] = '\0';
    pattern_len = strlen(pattern_buf);

    /* Since the pattern is a hex string, 2 characters represent 1 byte. */
    if (pattern_len % 2)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: Malformed pattern!", __func__);

        goto failure;
    }
    else
        pattern_len >>= 1;

    if (pattern_len < 14 || pattern_len > PERIODIC_TX_PTRN_MAX_SIZE)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: Not an 802.3 frame!", __func__);

        goto failure;
    }

    addPeriodicTxPtrnParams = vos_mem_malloc(sizeof(tSirAddPeriodicTxPtrn));
    if (!addPeriodicTxPtrnParams)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Memory allocation for addPeriodicTxPtrnParams "
                  "failed!", __func__);

        vos_mem_free(cmd);
        return -EFAULT;
    }

    addPeriodicTxPtrnParams->ucPtrnId = pattern_idx;
    addPeriodicTxPtrnParams->usPtrnIntervalMs = pattern_duration * 500;
    addPeriodicTxPtrnParams->ucPtrnSize = pattern_len;
    vos_mem_copy(addPeriodicTxPtrnParams->macAddress,
                 pAdapter->macAddressCurrent.bytes, 6);

    /* Extract the pattern */
    for(i = 0; i < addPeriodicTxPtrnParams->ucPtrnSize; i++)
    {
        addPeriodicTxPtrnParams->ucPattern[i] =
        (hdd_parse_hex(pattern_buf[0]) << 4) + hdd_parse_hex(pattern_buf[1]);

        /* Skip to next byte */
        pattern_buf += 2;
    }

    /* Add pattern */
    if (eHAL_STATUS_SUCCESS != sme_AddPeriodicTxPtrn(pHddCtx->hHal,
                                            addPeriodicTxPtrnParams))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: sme_AddPeriodicTxPtrn() failed!", __func__);

        vos_mem_free(addPeriodicTxPtrnParams);
        goto failure;
    }
    vos_mem_free(cmd);
    vos_mem_free(addPeriodicTxPtrnParams);
    EXIT();
    return count;

failure:
    vos_mem_free(cmd);
    return -EINVAL;
}
コード例 #8
0
/**
 * __wcnss_wowpattern_write() - write wow pattern
 * @file: file pointer
 * @buf: buffer
 * @count: count
 * @ppos: position pointer
 *
 * Return: 0 on success, error number otherwise
 */
static ssize_t __wcnss_wowpattern_write(struct file *file,
               const char __user *buf, size_t count, loff_t *ppos)
{
    hdd_adapter_t *pAdapter = (hdd_adapter_t *)file->private_data;
    hdd_context_t *hdd_ctx;
    char cmd[MAX_USER_COMMAND_SIZE_WOWL_PATTERN + 1];
    char *sptr, *token;
    v_U8_t pattern_idx = 0;
    v_U8_t pattern_offset = 0;
    char *pattern_buf;
    char *pattern_mask;
    int ret;

    if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                   "%s: Invalid adapter or adapter has invalid magic.",
                   __func__);

        return -EINVAL;
    }

    hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
        return ret;

    if (!sme_IsFeatureSupportedByFW(WOW))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: Wake-on-Wireless feature is not supported "
                   "in firmware!", __func__);

        return -EINVAL;
    }

    if (count > MAX_USER_COMMAND_SIZE_WOWL_PATTERN)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: Command length is larger than %d bytes.",
                   __func__, MAX_USER_COMMAND_SIZE_WOWL_PATTERN);

        return -EINVAL;
    }

    /* Get command from user */
    if (copy_from_user(cmd, buf, count))
        return -EFAULT;
    cmd[count] = '\0';
    sptr = cmd;

    /* Get pattern idx */
    token = strsep(&sptr, " ");
    if (!token)
        return -EINVAL;

    if (kstrtou8(token, 0, &pattern_idx))
        return -EINVAL;

    /* Get pattern offset */
    token = strsep(&sptr, " ");

    /* Delete pattern if no further argument */
    if (!token) {
        hdd_del_wowl_ptrn_debugfs(pAdapter, pattern_idx);

        return count;
    }

    if (kstrtou8(token, 0, &pattern_offset))
        return -EINVAL;

    /* Get pattern */
    token = strsep(&sptr, " ");
    if (!token)
        return -EINVAL;

    pattern_buf = token;

    /* Get pattern mask */
    token = strsep(&sptr, " ");
    if (!token)
        return -EINVAL;

    pattern_mask = token;
    pattern_mask[strlen(pattern_mask) - 1] = '\0';

    hdd_add_wowl_ptrn_debugfs(pAdapter, pattern_idx, pattern_offset,
                              pattern_buf, pattern_mask);
    EXIT();
    return count;
}