software/drivers/sd8887/src/wlan/mlinux/moal_priv.c
/**
 * @brief Set/Get PS configuration parameters
 *
 * @param priv     A pointer to moal_private structure
 * @param wrq      A pointer to iwreq structure
 *
 * @return         0 --success, otherwise fail
 */
@brief Set/Get PS configuration parameters
@param priv     A pointer to moal_private structure
@param wrq      A pointer to iwreq structure

@return         0 --success, otherwise fail
@brief Set / Get PS configuration parameters @param priv A pointer to moal_private structure @param wrq A pointer to iwreq structure @return 0 -- success otherwise fail
static int
woal_set_get_ps_cfg(moal_private *priv, struct iwreq *wrq)
{
	int data[7], copy_len, ret = 0;
	mlan_ds_pm_cfg *pm_cfg = NULL;
	mlan_ioctl_req *req = NULL;
	int allowed = 3;
	int i = 3;
	int data_length = wrq->u.data.length;
	mlan_status status = MLAN_STATUS_SUCCESS;
	ENTER();
	allowed++;		
	allowed += 2;		
	copy_len = MIN(sizeof(data), sizeof(int) * data_length);
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	if (data_length > allowed) {
		ret = -EINVAL;
		goto done;
	}
	pm_cfg = (mlan_ds_pm_cfg *)req->pbuf;
	pm_cfg->sub_command = MLAN_OID_PM_CFG_PS_CFG;
	req->req_id = MLAN_IOCTL_PM_CFG;
	memset(data, 0, sizeof(data));
	if (data_length) {
		if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
			PRINTM(MERROR, "Copy from user failed\n");
			ret = -EFAULT;
			goto done;
		}
		if ((data[0] < PS_NULL_DISABLE)) {
			PRINTM(MERROR,
			       "Invalid argument for PS null interval\n");
			ret = -EINVAL;
			goto done;
		}
		if ((data[1] != MRVDRV_IGNORE_MULTIPLE_DTIM)
		    && (data[1] != MRVDRV_MATCH_CLOSEST_DTIM)
		    && ((data[1] < MRVDRV_MIN_MULTIPLE_DTIM)
			|| (data[1] > MRVDRV_MAX_MULTIPLE_DTIM))) {
			PRINTM(MERROR, "Invalid argument for multiple DTIM\n");
			ret = -EINVAL;
			goto done;
		}
		if ((data[2] < MRVDRV_MIN_LISTEN_INTERVAL)
		    && (data[2] != MRVDRV_LISTEN_INTERVAL_DISABLE)) {
			PRINTM(MERROR,
			       "Invalid argument for listen interval\n");
			ret = -EINVAL;
			goto done;
		}
		if ((data[i] != DISABLE_BCN_MISS_TO) &&
		    ((data[i] < MIN_BCN_MISS_TO) ||
		     (data[i] > MAX_BCN_MISS_TO))) {
			PRINTM(MERROR,
			       "Invalid argument for beacon miss timeout\n");
			ret = -EINVAL;
			goto done;
		}
		i++;
		if (data_length < allowed - 1)
			data[i] = DELAY_TO_PS_UNCHANGED;
		else if ((data[i] < MIN_DELAY_TO_PS) ||
			 (data[i] > MAX_DELAY_TO_PS)) {
			PRINTM(MERROR, "Invalid argument for delay to PS\n");
			ret = -EINVAL;
			goto done;
		}
		i++;
		if ((data[i] != PS_MODE_UNCHANGED) && (data[i] != PS_MODE_AUTO)
		    && (data[i] != PS_MODE_POLL) && (data[i] != PS_MODE_NULL)) {
			PRINTM(MERROR, "Invalid argument for PS mode\n");
			ret = -EINVAL;
			goto done;
		}
		i++;
		req->action = MLAN_ACT_SET;
		memcpy(&pm_cfg->param.ps_cfg, data,
		       MIN(sizeof(pm_cfg->param.ps_cfg), sizeof(data)));
	} else
		req->action = MLAN_ACT_GET;
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	memcpy(data, &pm_cfg->param.ps_cfg,
	       MIN((sizeof(int) * allowed), sizeof(pm_cfg->param.ps_cfg)));
	if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * allowed)) {
		ret = -EFAULT;
		goto done;
	}
	wrq->u.data.length = allowed;
	if (req->action == MLAN_ACT_SET) {
		pm_cfg = (mlan_ds_pm_cfg *)req->pbuf;
		pm_cfg->sub_command = MLAN_OID_PM_CFG_IEEE_PS;
		pm_cfg->param.ps_mode = 1;
		req->req_id = MLAN_IOCTL_PM_CFG;
		req->action = MLAN_ACT_SET;
		status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	}
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}
static int woal_set_get_ps_cfg ( moal_private * priv , struct iwreq * wrq ) { int data [ 7 ] , copy_len , ret = 0 ; mlan_ds_pm_cfg * pm_cfg = NULL ; mlan_ioctl_req * req = NULL ; int allowed = 3 ; int i = 3 ; int data_length = wrq -> u . data . length ; mlan_status status = MLAN_STATUS_SUCCESS ; ENTER ( ) ; allowed ++ ; allowed += 2 ; copy_len = MIN ( sizeof ( data ) , sizeof ( int ) * data_length ) ; req = woal_alloc_mlan_ioctl_req ( sizeof ( mlan_ds_pm_cfg ) ) ; if ( req == NULL ) { ret = - ENOMEM ; goto done ; } if ( data_length > allowed ) { ret = - EINVAL ; goto done ; } pm_cfg = ( mlan_ds_pm_cfg * ) req -> pbuf ; pm_cfg -> sub_command = MLAN_OID_PM_CFG_PS_CFG ; req -> req_id = MLAN_IOCTL_PM_CFG ; memset ( data , 0 , sizeof ( data ) ) ; if ( data_length ) { if ( copy_from_user ( data , wrq -> u . data . pointer , copy_len ) ) { PRINTM ( MERROR , " \n " ) ; ret = - EFAULT ; goto done ; } if ( ( data [ 0 ] < PS_NULL_DISABLE ) ) { PRINTM ( MERROR , " \n " ) ; ret = - EINVAL ; goto done ; } if ( ( data [ 1 ] != MRVDRV_IGNORE_MULTIPLE_DTIM ) && ( data [ 1 ] != MRVDRV_MATCH_CLOSEST_DTIM ) && ( ( data [ 1 ] < MRVDRV_MIN_MULTIPLE_DTIM ) || ( data [ 1 ] > MRVDRV_MAX_MULTIPLE_DTIM ) ) ) { PRINTM ( MERROR , " \n " ) ; ret = - EINVAL ; goto done ; } if ( ( data [ 2 ] < MRVDRV_MIN_LISTEN_INTERVAL ) && ( data [ 2 ] != MRVDRV_LISTEN_INTERVAL_DISABLE ) ) { PRINTM ( MERROR , " \n " ) ; ret = - EINVAL ; goto done ; } if ( ( data [ i ] != DISABLE_BCN_MISS_TO ) && ( ( data [ i ] < MIN_BCN_MISS_TO ) || ( data [ i ] > MAX_BCN_MISS_TO ) ) ) { PRINTM ( MERROR , " \n " ) ; ret = - EINVAL ; goto done ; } i ++ ; if ( data_length < allowed - 1 ) data [ i ] = DELAY_TO_PS_UNCHANGED ; else if ( ( data [ i ] < MIN_DELAY_TO_PS ) || ( data [ i ] > MAX_DELAY_TO_PS ) ) { PRINTM ( MERROR , " \n " ) ; ret = - EINVAL ; goto done ; } i ++ ; if ( ( data [ i ] != PS_MODE_UNCHANGED ) && ( data [ i ] != PS_MODE_AUTO ) && ( data [ i ] != PS_MODE_POLL ) && ( data [ i ] != PS_MODE_NULL ) ) { PRINTM ( MERROR , " \n " ) ; ret = - EINVAL ; goto done ; } i ++ ; req -> action = MLAN_ACT_SET ; memcpy ( & pm_cfg -> param . ps_cfg , data , MIN ( sizeof ( pm_cfg -> param . ps_cfg ) , sizeof ( data ) ) ) ; } else req -> action = MLAN_ACT_GET ; status = woal_request_ioctl ( priv , req , MOAL_IOCTL_WAIT ) ; if ( status != MLAN_STATUS_SUCCESS ) { ret = - EFAULT ; goto done ; } memcpy ( data , & pm_cfg -> param . ps_cfg , MIN ( ( sizeof ( int ) * allowed ) , sizeof ( pm_cfg -> param . ps_cfg ) ) ) ; if ( copy_to_user ( wrq -> u . data . pointer , data , sizeof ( int ) * allowed ) ) { ret = - EFAULT ; goto done ; } wrq -> u . data . length = allowed ; if ( req -> action == MLAN_ACT_SET ) { pm_cfg = ( mlan_ds_pm_cfg * ) req -> pbuf ; pm_cfg -> sub_command = MLAN_OID_PM_CFG_IEEE_PS ; pm_cfg -> param . ps_mode = 1 ; req -> req_id = MLAN_IOCTL_PM_CFG ; req -> action = MLAN_ACT_SET ; status = woal_request_ioctl ( priv , req , MOAL_IOCTL_WAIT ) ; } done : if ( status != MLAN_STATUS_PENDING ) kfree ( req ) ; LEAVE ( ) ; return ret ; }
@brief Set/Get PS configuration parameters
 @param priv     A pointer to moal_private structure
 @param wrq      A pointer to iwreq structure
@brief Set / Get PS configuration parameters @param priv A pointer to moal_private structure @param wrq A pointer to iwreq structure
/* For beacon missing timeout parameter */ /* For delay to PS and PS mode parameters */