software/drivers/sd8887/src/wlan/mlinux/moal_priv.c
/**
 *  @brief Private IOCTL entry to send an ADDTS TSPEC
 *
 *  Receive a ADDTS command from the application.  The command structure
 *    contains a TSPEC and timeout in milliseconds.  The timeout is performed
 *    in the firmware after the ADDTS command frame is sent.
 *
 *  The TSPEC is received in the API as an opaque block. The firmware will
 *    send the entire data block, including the bytes after the TSPEC.  This
 *    is done to allow extra IEs to be packaged with the TSPEC in the ADDTS
 *    action frame.
 *
 *  The IOCTL structure contains two return fields:
 *    - The firmware command result, which indicates failure and timeouts
 *    - The IEEE Status code which contains the corresponding value from
 *      any ADDTS response frame received.
 *
 *  In addition, the opaque TSPEC data block passed in is replaced with the
 *    TSPEC received in the ADDTS response frame.  In case of failure, the
 *    AP may modify the TSPEC on return and in the case of success, the
 *    medium time is returned as calculated by the AP.  Along with the TSPEC,
 *    any IEs that are sent in the ADDTS response are also returned and can be
 *    parsed using the IOCTL length as an indicator of extra elements.
 *
 *  The return value to the application layer indicates a driver execution
 *    success or failure.  A successful return could still indicate a firmware
 *    failure or AP negotiation failure via the commandResult field copied
 *    back to the application.
 *
 *  @param priv    Pointer to the mlan_private driver data struct
 *  @param wrq     A pointer to iwreq structure containing the
 *                 wlan_ioctl_wmm_addts_req_t struct for this ADDTS request
 *
 *  @return        0 if successful; IOCTL error code otherwise
 */
@brief Private IOCTL entry to send an ADDTS TSPEC
Receive a ADDTS command from the application.  The command structure
contains a TSPEC and timeout in milliseconds.  The timeout is performed
in the firmware after the ADDTS command frame is sent.

The TSPEC is received in the API as an opaque block. The firmware will
send the entire data block, including the bytes after the TSPEC.  This
is done to allow extra IEs to be packaged with the TSPEC in the ADDTS
action frame.

The IOCTL structure contains two return fields:
- The firmware command result, which indicates failure and timeouts
- The IEEE Status code which contains the corresponding value from
any ADDTS response frame received.

In addition, the opaque TSPEC data block passed in is replaced with the
TSPEC received in the ADDTS response frame.  In case of failure, the
AP may modify the TSPEC on return and in the case of success, the
medium time is returned as calculated by the AP.  Along with the TSPEC,
any IEs that are sent in the ADDTS response are also returned and can be
parsed using the IOCTL length as an indicator of extra elements.

The return value to the application layer indicates a driver execution
success or failure.  A successful return could still indicate a firmware
failure or AP negotiation failure via the commandResult field copied
back to the application.

@param priv    Pointer to the mlan_private driver data struct
@param wrq     A pointer to iwreq structure containing the
wlan_ioctl_wmm_addts_req_t struct for this ADDTS request

@return        0 if successful; IOCTL error code otherwise
@brief Private IOCTL entry to send an ADDTS TSPEC Receive a ADDTS command from the application . The command structure contains a TSPEC and timeout in milliseconds . The timeout is performed in the firmware after the ADDTS command frame is sent . The TSPEC is received in the API as an opaque block . The firmware will send the entire data block including the bytes after the TSPEC . This is done to allow extra IEs to be packaged with the TSPEC in the ADDTS action frame . The IOCTL structure contains two return fields : - The firmware command result which indicates failure and timeouts - The IEEE Status code which contains the corresponding value from any ADDTS response frame received . In addition the opaque TSPEC data block passed in is replaced with the TSPEC received in the ADDTS response frame . In case of failure the AP may modify the TSPEC on return and in the case of success the medium time is returned as calculated by the AP . Along with the TSPEC any IEs that are sent in the ADDTS response are also returned and can be parsed using the IOCTL length as an indicator of extra elements . The return value to the application layer indicates a driver execution success or failure . A successful return could still indicate a firmware failure or AP negotiation failure via the commandResult field copied back to the application . @param priv Pointer to the mlan_private driver data struct @param wrq A pointer to iwreq structure containing the wlan_ioctl_wmm_addts_req_t struct for this ADDTS request @return 0 if successful ; IOCTL error code otherwise
static int
woal_wmm_addts_req_ioctl(moal_private *priv, struct iwreq *wrq)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_wmm_cfg *cfg = NULL;
	wlan_ioctl_wmm_addts_req_t addts_ioctl;
	int ret = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;
	ENTER();
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	req->req_id = MLAN_IOCTL_WMM_CFG;
	cfg = (mlan_ds_wmm_cfg *)req->pbuf;
	cfg->sub_command = MLAN_OID_WMM_CFG_ADDTS;
	memset(&addts_ioctl, 0x00, sizeof(addts_ioctl));
	if (wrq->u.data.length) {
		if (copy_from_user(&addts_ioctl, wrq->u.data.pointer,
				   MIN(wrq->u.data.length,
				       sizeof(addts_ioctl)))) {
			PRINTM(MERROR, "TSPEC: ADDTS copy from user failed\n");
			ret = -EFAULT;
			goto done;
		}
		cfg->param.addts.timeout = addts_ioctl.timeout_ms;
		cfg->param.addts.ie_data_len = addts_ioctl.ie_data_len;
		if (cfg->param.addts.ie_data_len >
		    sizeof(cfg->param.addts.ie_data)) {
			PRINTM(MERROR, "IE data length too large\n");
			ret = -EFAULT;
			goto done;
		}
		memcpy(cfg->param.addts.ie_data,
		       addts_ioctl.ie_data, cfg->param.addts.ie_data_len);
		status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
		if (status != MLAN_STATUS_SUCCESS) {
			ret = -EFAULT;
			goto done;
		}
		addts_ioctl.cmd_result = cfg->param.addts.result;
		addts_ioctl.ieee_status_code =
			(t_u8)cfg->param.addts.status_code;
		addts_ioctl.ie_data_len = cfg->param.addts.ie_data_len;
		memcpy(addts_ioctl.ie_data,
		       cfg->param.addts.ie_data, cfg->param.addts.ie_data_len);
		wrq->u.data.length = (sizeof(addts_ioctl)
				      - sizeof(addts_ioctl.ie_data)
				      + cfg->param.addts.ie_data_len);
		if (copy_to_user(wrq->u.data.pointer,
				 &addts_ioctl, wrq->u.data.length)) {
			PRINTM(MERROR, "TSPEC: ADDTS copy to user failed\n");
			ret = -EFAULT;
			goto done;
		}
	}
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}
static int woal_wmm_addts_req_ioctl ( moal_private * priv , struct iwreq * wrq ) { mlan_ioctl_req * req = NULL ; mlan_ds_wmm_cfg * cfg = NULL ; wlan_ioctl_wmm_addts_req_t addts_ioctl ; int ret = 0 ; mlan_status status = MLAN_STATUS_SUCCESS ; ENTER ( ) ; req = woal_alloc_mlan_ioctl_req ( sizeof ( mlan_ds_wmm_cfg ) ) ; if ( req == NULL ) { ret = - ENOMEM ; goto done ; } req -> req_id = MLAN_IOCTL_WMM_CFG ; cfg = ( mlan_ds_wmm_cfg * ) req -> pbuf ; cfg -> sub_command = MLAN_OID_WMM_CFG_ADDTS ; memset ( & addts_ioctl , 0x00 , sizeof ( addts_ioctl ) ) ; if ( wrq -> u . data . length ) { if ( copy_from_user ( & addts_ioctl , wrq -> u . data . pointer , MIN ( wrq -> u . data . length , sizeof ( addts_ioctl ) ) ) ) { PRINTM ( MERROR , " \n " ) ; ret = - EFAULT ; goto done ; } cfg -> param . addts . timeout = addts_ioctl . timeout_ms ; cfg -> param . addts . ie_data_len = addts_ioctl . ie_data_len ; if ( cfg -> param . addts . ie_data_len > sizeof ( cfg -> param . addts . ie_data ) ) { PRINTM ( MERROR , " \n " ) ; ret = - EFAULT ; goto done ; } memcpy ( cfg -> param . addts . ie_data , addts_ioctl . ie_data , cfg -> param . addts . ie_data_len ) ; status = woal_request_ioctl ( priv , req , MOAL_IOCTL_WAIT ) ; if ( status != MLAN_STATUS_SUCCESS ) { ret = - EFAULT ; goto done ; } addts_ioctl . cmd_result = cfg -> param . addts . result ; addts_ioctl . ieee_status_code = ( t_u8 ) cfg -> param . addts . status_code ; addts_ioctl . ie_data_len = cfg -> param . addts . ie_data_len ; memcpy ( addts_ioctl . ie_data , cfg -> param . addts . ie_data , cfg -> param . addts . ie_data_len ) ; wrq -> u . data . length = ( sizeof ( addts_ioctl ) - sizeof ( addts_ioctl . ie_data ) + cfg -> param . addts . ie_data_len ) ; if ( copy_to_user ( wrq -> u . data . pointer , & addts_ioctl , wrq -> u . data . length ) ) { PRINTM ( MERROR , " \n " ) ; ret = - EFAULT ; goto done ; } } done : if ( status != MLAN_STATUS_PENDING ) kfree ( req ) ; LEAVE ( ) ; return ret ; }
@brief Private IOCTL entry to send an ADDTS TSPEC
  Receive a ADDTS command from the application.
@brief Private IOCTL entry to send an ADDTS TSPEC Receive a ADDTS command from the application .