/** @file  moal_priv.c
  *
  * @brief This file contains standard ioctl functions
  *
  * Copyright (C) 2008-2009, Marvell International Ltd.
  *
  * This software file (the "File") is distributed by Marvell International
  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
  * (the "License").  You may use, redistribute and/or modify this File in
  * accordance with the terms and conditions of the License, a copy of which
  * is available by writing to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
  *
  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
  * this warranty disclaimer.
  *
  */

/************************************************************************
Change log:
    10/30/2008: initial version
************************************************************************/

#include	"moal_main.h"
#include	"moal_sdio.h"

/********************************************************
                Local Variables
********************************************************/
/** Bands supported in Infra mode */
static t_u8 SupportedInfraBand[] = {
    BAND_B, BAND_B | BAND_G, BAND_G,
    BAND_GN, BAND_B | BAND_G | BAND_GN, BAND_G | BAND_GN,
    BAND_A, BAND_B | BAND_A, BAND_B | BAND_G | BAND_A, BAND_G | BAND_A,
    BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN,
        BAND_A | BAND_G | BAND_AN | BAND_GN, BAND_A | BAND_AN,
};

/** Bands supported in Ad-Hoc mode */
static t_u8 SupportedAdhocBand[] = {
    BAND_B, BAND_B | BAND_G, BAND_G,
    BAND_GN, BAND_B | BAND_G | BAND_GN, BAND_G | BAND_GN,
    BAND_A,
    BAND_AN, BAND_A | BAND_AN,
};

/********************************************************
		Global Variables
********************************************************/

/** Macro for maximum size of scan response buffer */
#define MAX_SCAN_RSP_BUF (16 * 1024)

/********************************************************
		Local Functions
********************************************************/
/** 
 *  @brief Handle get info resp 
 *   
 *  @param priv 	Pointer to moal_private structure
 *  @param info 	Pointer to mlan_ds_get_info structure
 *
 *  @return    		N/A
 */
void
woal_ioctl_get_info_resp(moal_private * priv, mlan_ds_get_info * info)
{
    ENTER();
    switch (info->sub_command) {
    case MLAN_OID_GET_STATS:
        priv->w_stats.discard.fragment = info->param.stats.fcs_error;
        priv->w_stats.discard.retries = info->param.stats.retry;
        priv->w_stats.discard.misc = info->param.stats.ack_failure;
        break;
    case MLAN_OID_GET_SIGNAL:
        if (info->param.signal.selector & BCN_RSSI_AVG_MASK)
            priv->w_stats.qual.level = info->param.signal.bcn_rssi_avg;
        if (info->param.signal.selector & BCN_NF_AVG_MASK)
            priv->w_stats.qual.noise = info->param.signal.bcn_nf_avg;
        break;
    default:
        break;
    }
    LEAVE();
}

/** 
 *  @brief Handle get BSS resp 
 *   
 *  @param priv 	Pointer to moal_private structure
 *  @param bss 		Pointer to mlan_ds_bss structure
 *
 *  @return    		N/A
 */
void
woal_ioctl_get_bss_resp(moal_private * priv, mlan_ds_bss * bss)
{
    t_u32 mode = 0;

    ENTER();

    switch (bss->sub_command) {
    case MLAN_OID_BSS_MODE:
        if (bss->param.bss_mode == MLAN_BSS_MODE_INFRA)
            mode = IW_MODE_INFRA;
        else if (bss->param.bss_mode == MLAN_BSS_MODE_IBSS)
            mode = IW_MODE_ADHOC;
        else
            mode = IW_MODE_AUTO;
        priv->w_stats.status = mode;
        break;
    default:
        break;
    }

    LEAVE();
    return;
}

/** 
 *  @brief Copy Rates
 *   
 *  @param dest    A pointer to destination buffer
 *  @param pos     The position for copy
 *  @param src     A pointer to source buffer
 *  @param len     Length of the source buffer
 *
 *  @return        Number of rates copied 
 */
static inline int
woal_copy_rates(t_u8 * dest, int pos, t_u8 * src, int len)
{
    int i;

    for (i = 0; i < len && src[i]; i++, pos++) {
        if (pos >= MLAN_SUPPORTED_RATES)
            break;
        dest[pos] = src[i];
    }
    return pos;
}

/**
 *  @brief Get Driver Version
 *
 *  @param priv         A pointer to moal_private structure
 *  @param req          A pointer to ifreq structure
 *
 *  @return             0 --success, otherwise fail
 */
static int
woal_get_driver_version(moal_private * priv, struct ifreq *req)
{
    struct iwreq *wrq = (struct iwreq *) req;
    int len;
    char buf[MLAN_MAX_VER_STR_LEN];
    ENTER();

    woal_get_version(priv->phandle, buf, sizeof(buf) - 1);

    len = strlen(buf);
    if (wrq->u.data.pointer) {
        if (copy_to_user(wrq->u.data.pointer, buf, len)) {
            PRINTM(MERROR, "Copy to user failed\n");
            LEAVE();
            return -EFAULT;
        }
        wrq->u.data.length = len;
    }
    PRINTM(MINFO, "MOAL VERSION: %s\n", buf);
    LEAVE();
    return 0;
}

/**
 *  @brief Get extended driver version
 *
 *  @param priv         A pointer to moal_private structure
 *  @param ireq         A pointer to ifreq structure
 *
 *  @return             0 --success, otherwise fail  
 */
static int
woal_get_driver_verext(moal_private * priv, struct ifreq *ireq)
{
    struct iwreq *wrq = (struct iwreq *) ireq;
    mlan_ds_get_info *info = NULL;
    mlan_ioctl_req *req = NULL;

    ENTER();

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
    if (req == NULL) {
        LEAVE();
        return -ENOMEM;
    }

    info = (mlan_ds_get_info *) req->pbuf;
    info->sub_command = MLAN_OID_GET_VER_EXT;
    req->req_id = MLAN_IOCTL_GET_INFO;
    req->action = MLAN_ACT_GET;

    if (!wrq->u.data.flags) {
        info->param.ver_ext.version_str_sel =
            *((int *) (wrq->u.name + SUBCMD_OFFSET));
    } else {
        if (copy_from_user
            (&info->param.ver_ext.version_str_sel, wrq->u.data.pointer,
             sizeof(info->param.ver_ext.version_str_sel))) {
            PRINTM(MERROR, "Copy from user failed\n");
            LEAVE();
            return -EFAULT;
        } else {
            if (info->param.ver_ext.version_str_sel < 0) {
                PRINTM(MERROR, "Invalid arguments!\n");
                LEAVE();
                return -EINVAL;
            }
        }
    }

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        LEAVE();
        return -EFAULT;
    }

    if (wrq->u.data.pointer) {
        if (copy_to_user(wrq->u.data.pointer, info->param.ver_ext.version_str,
                         strlen(info->param.ver_ext.version_str))) {
            PRINTM(MERROR, "Copy to user failed\n");
            LEAVE();
            return -EFAULT;
        }
        wrq->u.data.length = strlen(info->param.ver_ext.version_str);
    }

    PRINTM(MINFO, "MOAL EXTENDED VERSION: %s\n",
           info->param.ver_ext.version_str);

    LEAVE();
    return 0;
}

/**
 *  @brief Set Deep Sleep
 *
 *  @param priv         Pointer to the moal_private driver data struct
 *  @param wait_option  wait option
 *  @param bdeep_sleep  TRUE--enalbe deepsleep, FALSE--disable deepsleep
 *  @param idletime     Idle time for optimized PS API
 *
 *  @return             0 --success, otherwise fail
 */
int
woal_set_deep_sleep(moal_private * priv, t_u8 wait_option, BOOLEAN bdeep_sleep,
                    t_u16 idletime)
{
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_pm_cfg *pm = NULL;

    ENTER();

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
    if (req == NULL) {
        LEAVE();
        return -ENOMEM;
    }
    pm = (mlan_ds_pm_cfg *) req->pbuf;
    pm->sub_command = MLAN_OID_PM_CFG_DEEP_SLEEP;
    req->req_id = MLAN_IOCTL_PM_CFG;

    req->action = MLAN_ACT_SET;
    if (bdeep_sleep == MTRUE) {
        PRINTM(MCMND, "Deep Sleep: sleep\n");
        pm->param.auto_deep_sleep.auto_ds = DEEP_SLEEP_ON;
        if (idletime) {
            pm->param.auto_deep_sleep.idletime = idletime;
        }
        if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, wait_option)) {
            ret = -EFAULT;
            goto done;
        }
    } else {
        PRINTM(MCMND, "%lu : Deep Sleep: wakeup\n", jiffies);
        pm->param.auto_deep_sleep.auto_ds = DEEP_SLEEP_OFF;

        if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, wait_option)) {
            ret = -EFAULT;
            goto done;
        }
    }

  done:
    if (req)
        kfree(req);

    LEAVE();
    return ret;
}

/**
 *  @brief Performs warm reset
 *
 *  @param priv         A pointer to moal_private structure
 *
 *  @return             0 --success, otherwise fail  
 */
static int
woal_warm_reset(moal_private * priv)
{
    int ret = 0;
    int intf_num;
    moal_handle *handle = priv->phandle;
    mlan_ioctl_req *req = NULL;
    mlan_ds_misc_cfg *misc = NULL;
    mlan_bss_info bss_info;

    ENTER();

    /* Disable interfaces */
    for (intf_num = 0; intf_num < handle->priv_num; intf_num++) {
        netif_stop_queue(handle->priv[intf_num]->netdev);
        netif_device_detach(handle->priv[intf_num]->netdev);
    }

    /* Exit deep sleep */
    woal_set_deep_sleep(priv, MOAL_IOCTL_WAIT, MFALSE, 0);

    memset(&bss_info, 0, sizeof(bss_info));
    woal_get_bss_info(priv, MOAL_PROC_WAIT, &bss_info);
    if (bss_info.is_hs_configured) {
        if (MLAN_STATUS_SUCCESS != woal_hs_cfg_cancel(priv, MOAL_IOCTL_WAIT)) {
            ret = -EFAULT;
            goto done;
        }
    }

    /* Disconnect from network */
    for (intf_num = 0; intf_num < handle->priv_num; intf_num++) {
        if (handle->priv[intf_num]->media_connected == MTRUE) {
            woal_disconnect(handle->priv[intf_num], MOAL_IOCTL_WAIT, NULL);
        }
    }

    /* Initialize private structures */
    for (intf_num = 0; intf_num < handle->priv_num; intf_num++)
        woal_init_priv(handle->priv[intf_num]);

#ifdef REASSOCIATION
    /* Reset the reassoc timer and status */
    handle->reassoc_on = MFALSE;
    if (handle->is_reassoc_timer_set == MTRUE) {
        woal_cancel_timer(&handle->reassoc_timer);
        handle->is_reassoc_timer_set = MFALSE;
    }
#endif

    /* Restart the firmware */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
    if (req) {
        misc = (mlan_ds_misc_cfg *) req->pbuf;
        misc->sub_command = MLAN_OID_MISC_WARM_RESET;
        req->req_id = MLAN_IOCTL_MISC_CFG;
        req->action = MLAN_ACT_SET;
        if (MLAN_STATUS_SUCCESS !=
            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
            ret = -EFAULT;
            kfree(req);
            goto done;
        }
        kfree(req);
    }

    /* Enable interfaces */
    for (intf_num = 0; intf_num < handle->priv_num; intf_num++) {
        netif_device_attach(handle->priv[intf_num]->netdev);
        netif_start_queue(handle->priv[intf_num]->netdev);
    }

  done:
    LEAVE();
    return ret;
}

/**
 *  @brief Get signal
 *
 *  @param priv         A pointer to moal_private structure
 *  @param wrq	        A pointer to iwreq structure
 *
 *  @return 	  	0 --success, otherwise fail
 */
static int
woal_get_signal(moal_private * priv, struct iwreq *wrq)
{
/** Input data size */
#define IN_DATA_SIZE	2
/** Output data size */
#define OUT_DATA_SIZE	12
    int ret = 0;
    int in_data[IN_DATA_SIZE];
    int out_data[OUT_DATA_SIZE];
    mlan_ds_get_signal signal;
    int data_length = 0;

    ENTER();

    memset(in_data, 0, sizeof(in_data));
    memset(out_data, 0, sizeof(out_data));

    if (priv->media_connected == MFALSE) {
        PRINTM(MERROR, "Can not get RSSI in disconnected state\n");
        ret = -ENOTSUPP;
        goto done;
    }

    if (wrq->u.data.length) {
        if (copy_from_user
            (in_data, wrq->u.data.pointer,
             sizeof(int) * MIN(wrq->u.data.length, sizeof(in_data)))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
    }

    switch (wrq->u.data.length) {
    case 0:                    /* No checking, get everything */
        break;
    case 2:                    /* Check subtype range */
        if (in_data[1] < 1 || in_data[1] > 4) {
            ret = -EINVAL;
            goto done;
        }
        /* Fall through */
    case 1:                    /* Check type range */
        if (in_data[0] < 1 || in_data[0] > 3) {
            ret = -EINVAL;
            goto done;
        }
        break;
    default:
        ret = -EINVAL;
        goto done;
    }

    memset(&signal, 0, sizeof(mlan_ds_get_signal));
    if (MLAN_STATUS_SUCCESS !=
        woal_get_signal_info(priv, MOAL_IOCTL_WAIT, &signal)) {
        ret = -EFAULT;
        goto done;
    }
    PRINTM(MINFO, "RSSI Beacon Last   : %d\n", (int) signal.bcn_rssi_last);
    PRINTM(MINFO, "RSSI Beacon Average: %d\n", (int) signal.bcn_rssi_avg);
    PRINTM(MINFO, "RSSI Data Last     : %d\n", (int) signal.data_rssi_last);
    PRINTM(MINFO, "RSSI Data Average  : %d\n", (int) signal.data_rssi_avg);
    PRINTM(MINFO, "SNR Beacon Last    : %d\n", (int) signal.bcn_snr_last);
    PRINTM(MINFO, "SNR Beacon Average : %d\n", (int) signal.bcn_snr_avg);
    PRINTM(MINFO, "SNR Data Last      : %d\n", (int) signal.data_snr_last);
    PRINTM(MINFO, "SNR Data Average   : %d\n", (int) signal.data_snr_avg);
    PRINTM(MINFO, "NF Beacon Last     : %d\n", (int) signal.bcn_nf_last);
    PRINTM(MINFO, "NF Beacon Average  : %d\n", (int) signal.bcn_nf_avg);
    PRINTM(MINFO, "NF Data Last       : %d\n", (int) signal.data_nf_last);
    PRINTM(MINFO, "NF Data Average    : %d\n", (int) signal.data_nf_avg);

    /* Check type */
    switch (in_data[0]) {
    case 0:                    /* Send everything */
        out_data[data_length++] = signal.bcn_rssi_last;
        out_data[data_length++] = signal.bcn_rssi_avg;
        out_data[data_length++] = signal.data_rssi_last;
        out_data[data_length++] = signal.data_rssi_avg;
        out_data[data_length++] = signal.bcn_snr_last;
        out_data[data_length++] = signal.bcn_snr_avg;
        out_data[data_length++] = signal.data_snr_last;
        out_data[data_length++] = signal.data_snr_avg;
        out_data[data_length++] = signal.bcn_nf_last;
        out_data[data_length++] = signal.bcn_nf_avg;
        out_data[data_length++] = signal.data_nf_last;
        out_data[data_length++] = signal.data_nf_avg;
        break;
    case 1:                    /* RSSI */
        /* Check subtype */
        switch (in_data[1]) {
        case 0:                /* Everything */
            out_data[data_length++] = signal.bcn_rssi_last;
            out_data[data_length++] = signal.bcn_rssi_avg;
            out_data[data_length++] = signal.data_rssi_last;
            out_data[data_length++] = signal.data_rssi_avg;
            break;
        case 1:                /* bcn last */
            out_data[data_length++] = signal.bcn_rssi_last;
            break;
        case 2:                /* bcn avg */
            out_data[data_length++] = signal.bcn_rssi_avg;
            break;
        case 3:                /* data last */
            out_data[data_length++] = signal.data_rssi_last;
            break;
        case 4:                /* data avg */
            out_data[data_length++] = signal.data_rssi_avg;
            break;
        default:
            break;
        }
        break;
    case 2:                    /* SNR */
        /* Check subtype */
        switch (in_data[1]) {
        case 0:                /* Everything */
            out_data[data_length++] = signal.bcn_snr_last;
            out_data[data_length++] = signal.bcn_snr_avg;
            out_data[data_length++] = signal.data_snr_last;
            out_data[data_length++] = signal.data_snr_avg;
            break;
        case 1:                /* bcn last */
            out_data[data_length++] = signal.bcn_snr_last;
            break;
        case 2:                /* bcn avg */
            out_data[data_length++] = signal.bcn_snr_avg;
            break;
        case 3:                /* data last */
            out_data[data_length++] = signal.data_snr_last;
            break;
        case 4:                /* data avg */
            out_data[data_length++] = signal.data_snr_avg;
            break;
        default:
            break;
        }
        break;
    case 3:                    /* NF */
        /* Check subtype */
        switch (in_data[1]) {
        case 0:                /* Everything */
            out_data[data_length++] = signal.bcn_nf_last;
            out_data[data_length++] = signal.bcn_nf_avg;
            out_data[data_length++] = signal.data_nf_last;
            out_data[data_length++] = signal.data_nf_avg;
            break;
        case 1:                /* bcn last */
            out_data[data_length++] = signal.bcn_nf_last;
            break;
        case 2:                /* bcn avg */
            out_data[data_length++] = signal.bcn_nf_avg;
            break;
        case 3:                /* data last */
            out_data[data_length++] = signal.data_nf_last;
            break;
        case 4:                /* data avg */
            out_data[data_length++] = signal.data_nf_avg;
            break;
        default:
            break;
        }
        break;
    default:
        break;
    }

    wrq->u.data.length = data_length;
    if (copy_to_user(wrq->u.data.pointer, out_data,
                     wrq->u.data.length * sizeof(out_data[0]))) {
        PRINTM(MERROR, "Copy to user failed\n");
        ret = -EFAULT;
        goto done;
    }
  done:
    LEAVE();
    return ret;
}

/**
 *  @brief Get Deep Sleep
 *
 *  @param priv         Pointer to the moal_private driver data struct
 *  @param deep_sleep   Pointer to return deep_sleep setting
 *
 *  @return          0 --success, otherwise fail
 */
static int
woal_get_deep_sleep(moal_private * priv, t_u32 * deep_sleep)
{
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_pm_cfg *pm = NULL;

    ENTER();

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
    if (req == NULL) {
        LEAVE();
        return -ENOMEM;
    }
    pm = (mlan_ds_pm_cfg *) req->pbuf;
    pm->sub_command = MLAN_OID_PM_CFG_DEEP_SLEEP;
    req->req_id = MLAN_IOCTL_PM_CFG;

    req->action = MLAN_ACT_GET;
    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }
    *deep_sleep = pm->param.auto_deep_sleep.auto_ds;

  done:
    if (req)
        kfree(req);

    LEAVE();
    return ret;
}

/**
 *  @brief Get/Set DeepSleep mode
 *
 *  @param priv     Pointer to the moal_private driver data struct
 *  @param wreq	    A pointer to iwreq structure
 *
 *  @return          0 --success, otherwise fail
 */
static int
woal_deep_sleep_ioctl(moal_private * priv, struct iwreq *wrq)
{
    t_u32 deep_sleep = DEEP_SLEEP_OFF;
    static t_u16 idletime = DEEP_SLEEP_ILDE_TIME;
    t_u32 data[2];

    ENTER();

    if (wrq->u.data.length == 1 || wrq->u.data.length == 2) {
        if (copy_from_user
            (&data, wrq->u.data.pointer, wrq->u.data.length * sizeof(int))) {
            PRINTM(MERROR, "Copy from user failed\n");
            LEAVE();
            return -EFAULT;
        }
        deep_sleep = data[0];
        if (deep_sleep == DEEP_SLEEP_OFF) {
            PRINTM(MINFO, "Exit Deep Sleep Mode\n");
            woal_set_deep_sleep(priv, MOAL_IOCTL_WAIT, MFALSE, 0);
        } else if (deep_sleep == DEEP_SLEEP_ON) {
            PRINTM(MINFO, "Enter Deep Sleep Mode\n");
            if (wrq->u.data.length == 2)
                idletime = data[1];
            woal_set_deep_sleep(priv, MOAL_IOCTL_WAIT, MTRUE, idletime);
        } else {
            PRINTM(MERROR, "Unknown option = %lu\n", deep_sleep);
            LEAVE();
            return -EINVAL;
        }
    } else if (wrq->u.data.length > 2) {
        PRINTM(MERROR, "Invalid number of arguments %d\n", wrq->u.data.length);
        LEAVE();
        return -EINVAL;
    } else {                    /* Display Deep Sleep settings */
        PRINTM(MINFO, "Get Deep Sleep Mode\n");
        if (MLAN_STATUS_SUCCESS != woal_get_deep_sleep(priv, &deep_sleep)) {
            LEAVE();
            return -EFAULT;
        }
    }

    /* Copy the Deep Sleep setting to user */
    if (copy_to_user(wrq->u.data.pointer, &deep_sleep, sizeof(int))) {
        PRINTM(MERROR, "Copy to user failed\n");
        LEAVE();
        return -EINVAL;
    }
    wrq->u.data.length = 1;

    LEAVE();
    return 0;
}

/**
 *  @brief Set/Get Usr 11n configuration request
 *
 *  @param priv     Pointer to the moal_private driver data struct
 *  @param wrq	    A pointer to iwreq structure
 *
 *  @return          0 --success, otherwise fail
 */
static int
woal_11n_htcap_cfg(moal_private * priv, struct iwreq *wrq)
{
    int data;
    mlan_ioctl_req *req = NULL;
    mlan_ds_11n_cfg *cfg_11n = NULL;
    int ret = 0;

    ENTER();

    if (wrq->u.data.length > 1) {
        PRINTM(MERROR, "Invalid number of arguments\n");
        ret = -EINVAL;
        goto done;
    }

    if (((req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg))) == NULL)) {
        ret = -ENOMEM;
        goto done;
    }

    cfg_11n = (mlan_ds_11n_cfg *) req->pbuf;
    cfg_11n->sub_command = MLAN_OID_11N_HTCAP_CFG;
    req->req_id = MLAN_IOCTL_11N_CFG;

    if (wrq->u.data.length == 0) {
        /* Get 11n tx parameters from MLAN */
        req->action = MLAN_ACT_GET;
    } else if (wrq->u.data.length == 1) {
        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }

        cfg_11n->param.htcap_cfg = data;
        PRINTM(MINFO, "SET: htusrcap:0x%x\n", data);
        /* Update 11n tx parameters in MLAN */
        req->action = MLAN_ACT_SET;
    }

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

    data = cfg_11n->param.htcap_cfg;
    PRINTM(MINFO, "GET: httxcap:0x%x\n", data);

    if (copy_to_user(wrq->u.data.pointer, &data, sizeof(data))) {
        PRINTM(MERROR, "Copy to user failed\n");
        ret = -EFAULT;
        goto done;
    }

    wrq->u.data.length = 1;

  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Enable/Disable amsdu_aggr_ctrl
 *
 *  @param priv     Pointer to the moal_private driver data struct
 *  @param wrq	    A pointer to iwreq structure
 *
 *  @return          0 --success, otherwise fail
 */
static int
woal_11n_amsdu_aggr_ctrl(moal_private * priv, struct iwreq *wrq)
{
    int data[2];
    mlan_ioctl_req *req = NULL;
    mlan_ds_11n_cfg *cfg_11n = NULL;
    int ret = 0;

    ENTER();

    if ((wrq->u.data.length != 0) && (wrq->u.data.length != 1)) {
        PRINTM(MERROR, "Invalid number of arguments\n");
        ret = -EINVAL;
        goto done;
    }
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    cfg_11n = (mlan_ds_11n_cfg *) req->pbuf;
    cfg_11n->sub_command = MLAN_OID_11N_CFG_AMSDU_AGGR_CTRL;
    req->req_id = MLAN_IOCTL_11N_CFG;

    if (wrq->u.data.length == 0) {
        /* Get 11n tx parameters from MLAN */
        req->action = MLAN_ACT_GET;
    } else if (wrq->u.data.length == 1) {
        if (copy_from_user(data, wrq->u.data.pointer,
                           wrq->u.data.length * sizeof(int))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        cfg_11n->param.amsdu_aggr_ctrl.enable = data[0];
        /* Update 11n tx parameters in MLAN */
        req->action = MLAN_ACT_SET;
    }
    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }
    data[0] = cfg_11n->param.amsdu_aggr_ctrl.enable;
    data[1] = cfg_11n->param.amsdu_aggr_ctrl.curr_buf_size;

    if (copy_to_user(wrq->u.data.pointer, data, sizeof(data))) {
        PRINTM(MERROR, "Copy to user failed\n");
        ret = -EFAULT;
        goto done;
    }
    wrq->u.data.length = 2;
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Set/Get 11n configuration request
 *
 *  @param priv     Pointer to the moal_private driver data struct
 *  @param wrq	    A pointer to iwreq structure
 *
 *  @return          0 --success, otherwise fail
 */
static int
woal_11n_tx_cfg(moal_private * priv, struct iwreq *wrq)
{
    int data;
    mlan_ioctl_req *req = NULL;
    mlan_ds_11n_cfg *cfg_11n = NULL;
    int ret = 0;

    ENTER();

    if ((wrq->u.data.length != 0) && (wrq->u.data.length != 1)) {
        PRINTM(MERROR, "Invalid number of arguments\n");
        ret = -EINVAL;
        goto done;
    }
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    cfg_11n = (mlan_ds_11n_cfg *) req->pbuf;
    cfg_11n->sub_command = MLAN_OID_11N_CFG_TX;
    req->req_id = MLAN_IOCTL_11N_CFG;

    if (wrq->u.data.length == 0) {
        /* Get 11n tx parameters from MLAN */
        req->action = MLAN_ACT_GET;
    } else if (wrq->u.data.length == 1) {
        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(data))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        cfg_11n->param.tx_cfg.httxcap = data;
        PRINTM(MINFO, "SET: httxcap:%d\n", data);
        /* Update 11n tx parameters in MLAN */
        req->action = MLAN_ACT_SET;
    }
    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }
    data = cfg_11n->param.tx_cfg.httxcap;
    PRINTM(MINFO, "GET: httxcap:%d\n", data);
    if (copy_to_user(wrq->u.data.pointer, &data, sizeof(data))) {
        PRINTM(MERROR, "Copy to user failed\n");
        ret = -EFAULT;
        goto done;
    }
    wrq->u.data.length = 1;
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Enable/Disable TX Aggregation
 *
 *  @param priv     Pointer to the moal_private driver data struct
 *  @param wrq	    A pointer to iwreq structure
 *
 *  @return          0 --success, otherwise fail
 */
static int
woal_11n_prio_tbl(moal_private * priv, struct iwreq *wrq)
{
    int data[MAX_NUM_TID * 2], i, j;
    mlan_ioctl_req *req = NULL;
    mlan_ds_11n_cfg *cfg_11n = NULL;
    int ret = 0;

    ENTER();

    if ((wrq->u.data.pointer == NULL)) {
        LEAVE();
        return -EINVAL;
    }

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
    if (req == NULL) {
        LEAVE();
        return -ENOMEM;
    }
    cfg_11n = (mlan_ds_11n_cfg *) req->pbuf;
    cfg_11n->sub_command = MLAN_OID_11N_CFG_AGGR_PRIO_TBL;
    req->req_id = MLAN_IOCTL_11N_CFG;

    if (wrq->u.data.length == 0) {
        /* Get aggr priority table from MLAN */
        req->action = MLAN_ACT_GET;
        if (MLAN_STATUS_SUCCESS !=
            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
            ret = -EFAULT;
            goto error;
        }
        wrq->u.data.length = MAX_NUM_TID * 2;
        for (i = 0, j = 0; i < (wrq->u.data.length); i = i + 2, ++j) {
            data[i] = cfg_11n->param.aggr_prio_tbl.ampdu[j];
            data[i + 1] = cfg_11n->param.aggr_prio_tbl.amsdu[j];
        }

        if (copy_to_user(wrq->u.data.pointer, data,
                         sizeof(int) * wrq->u.data.length)) {
            PRINTM(MERROR, "Copy to user failed\n");
            ret = -EFAULT;
            goto error;
        }
    } else if (wrq->u.data.length == 16) {
        if (copy_from_user(data, wrq->u.data.pointer,
                           sizeof(int) * wrq->u.data.length)) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto error;
        }
        for (i = 0, j = 0; i < (wrq->u.data.length); i = i + 2, ++j) {
            cfg_11n->param.aggr_prio_tbl.ampdu[j] = data[i];
            cfg_11n->param.aggr_prio_tbl.amsdu[j] = data[i + 1];
        }

        /* Update aggr priority table in MLAN */
        req->action = MLAN_ACT_SET;
        if (MLAN_STATUS_SUCCESS !=
            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
            ret = -EFAULT;
            goto error;
        }
    } else {
        PRINTM(MERROR, "Invalid number of arguments\n");
        ret = -EINVAL;
        goto error;
    }

  error:
    if (req)
        kfree(req);

    LEAVE();
    return ret;
}

/**
 *  @brief Set/Get add BA Reject paramters
 *
 *  @param priv     Pointer to the moal_private driver data struct
 *  @param wrq	    A pointer to iwreq structure
 *
 *  @return          0 --success, otherwise fail
 */
static int
woal_addba_reject(moal_private * priv, struct iwreq *wrq)
{
    int data[MAX_NUM_TID], ret = 0, i;
    mlan_ioctl_req *req = NULL;
    mlan_ds_11n_cfg *cfg_11n = NULL;

    ENTER();

    PRINTM(MERROR, "%s\n", __FUNCTION__);
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
    if (req == NULL) {
        LEAVE();
        return -ENOMEM;
    }
    cfg_11n = (mlan_ds_11n_cfg *) req->pbuf;
    cfg_11n->sub_command = MLAN_OID_11N_CFG_ADDBA_REJECT;
    req->req_id = MLAN_IOCTL_11N_CFG;

    if (wrq->u.data.length == 0) {
        PRINTM(MERROR, "Addba reject moal\n");
        /* Get aggr priority table from MLAN */
        req->action = MLAN_ACT_GET;
        if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req,
                                                      MOAL_IOCTL_WAIT)) {
            ret = -EFAULT;
            goto error;
        }

        wrq->u.data.length = MAX_NUM_TID;
        for (i = 0; i < (wrq->u.data.length); ++i) {
            data[i] = cfg_11n->param.addba_reject[i];
        }

        if (copy_to_user(wrq->u.data.pointer, data,
                         sizeof(int) * wrq->u.data.length)) {
            PRINTM(MERROR, "Copy to user failed\n");
            ret = -EFAULT;
            goto error;
        }
    } else if (wrq->u.data.length == 8) {
        if (copy_from_user(data, wrq->u.data.pointer,
                           sizeof(int) * wrq->u.data.length)) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto error;
        }
        for (i = 0; i < (wrq->u.data.length); ++i) {
            cfg_11n->param.addba_reject[i] = data[i];
        }

        /* Update aggr priority table in MLAN */
        req->action = MLAN_ACT_SET;
        if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req,
                                                      MOAL_IOCTL_WAIT)) {
            ret = -EFAULT;
            goto error;
        }
    } else {
        PRINTM(MERROR, "Invalid number of arguments\n");
        ret = -EINVAL;
        goto error;
    }
  error:
    if (req)
        kfree(req);

    LEAVE();
    return ret;
}

/**
 *  @brief Set/Get add BA paramters
 *
 *  @param priv     Pointer to the moal_private driver data struct
 *  @param wrq	    A pointer to iwreq structure
 *
 *  @return          0 --success, otherwise fail
 */
static int
woal_addba_para_updt(moal_private * priv, struct iwreq *wrq)
{
    int data[3], ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_11n_cfg *cfg_11n = NULL;

    ENTER();

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
    if (req == NULL) {
        LEAVE();
        return -ENOMEM;
    }
    cfg_11n = (mlan_ds_11n_cfg *) req->pbuf;
    cfg_11n->sub_command = MLAN_OID_11N_CFG_ADDBA_PARAM;
    req->req_id = MLAN_IOCTL_11N_CFG;

    if (wrq->u.data.length == 0) {
        /* Get Add BA parameters from MLAN */
        req->action = MLAN_ACT_GET;
        if (MLAN_STATUS_SUCCESS !=
            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
            ret = -EFAULT;
            goto error;
        }
        data[0] = cfg_11n->param.addba_param.timeout;
        data[1] = cfg_11n->param.addba_param.txwinsize;
        data[2] = cfg_11n->param.addba_param.rxwinsize;
        PRINTM(MINFO, "GET: timeout:%d txwinsize:%d rxwinsize:%d\n", data[0],
               data[1], data[2]);

        wrq->u.data.length = 3;
        if (copy_to_user(wrq->u.data.pointer, data,
                         wrq->u.data.length * sizeof(int))) {
            PRINTM(MERROR, "Copy to user failed\n");
            ret = -EFAULT;
            goto error;
        }
    } else if (wrq->u.data.length == 3) {
        if (copy_from_user
            (data, wrq->u.data.pointer, wrq->u.data.length * sizeof(int))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto error;
        }
        cfg_11n->param.addba_param.timeout = data[0];
        cfg_11n->param.addba_param.txwinsize = data[1];
        cfg_11n->param.addba_param.rxwinsize = data[2];
        PRINTM(MINFO, "SET: timeout:%d txwinsize:%d rxwinsize:%d\n", data[0],
               data[1], data[2]);

        /* Update Add BA parameters in MLAN */
        req->action = MLAN_ACT_SET;
        if (MLAN_STATUS_SUCCESS !=
            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
            ret = MLAN_STATUS_FAILURE;
            goto error;
        }
    } else {
        PRINTM(MERROR, "Invalid number of arguments\n");
        ret = -EINVAL;
        goto error;
    }

  error:
    if (req)
        kfree(req);

    LEAVE();
    return ret;
}

/**
 *  @brief Set/Get Transmit buffer size
 *
 *  @param priv     Pointer to the moal_private driver data struct
 *  @param wrq	    A pointer to iwreq structure
 *
 *  @return          0 --success, otherwise fail
 */
static int
woal_txbuf_cfg(moal_private * priv, struct iwreq *wrq)
{
    int buf_size;
    mlan_ioctl_req *req = NULL;
    mlan_ds_11n_cfg *cfg_11n = NULL;
    int ret = 0;

    ENTER();
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    cfg_11n = (mlan_ds_11n_cfg *) req->pbuf;
    cfg_11n->sub_command = MLAN_OID_11N_CFG_MAX_TX_BUF_SIZE;
    req->req_id = MLAN_IOCTL_11N_CFG;

    if (wrq->u.data.length == 0) {
        /* Get Tx buffer size from MLAN */
        req->action = MLAN_ACT_GET;
    } else {
        if (copy_from_user(&buf_size, wrq->u.data.pointer, sizeof(buf_size))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        PRINTM(MINFO, "SET: Tx buffer size %d\n", buf_size);
        /* Update Tx buffer size in MLAN */
        req->action = MLAN_ACT_SET;
        cfg_11n->param.tx_buf_size = buf_size;
    }
    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }
    buf_size = cfg_11n->param.tx_buf_size;
    if (copy_to_user(wrq->u.data.pointer, &buf_size, sizeof(buf_size))) {
        PRINTM(MERROR, "Copy to user failed\n");
        ret = -EFAULT;
        goto done;
    }
    wrq->u.data.length = 1;
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Set/Get Host Sleep configuration
 *
 *  @param priv             A pointer to moal_private structure
 *  @param wrq	            A pointer to iwreq structure
 *  @param invoke_hostcmd	MTRUE --invoke HostCmd, otherwise MFALSE
 *
 *  @return             0 --success, otherwise fail
 */
static int
woal_hs_cfg(moal_private * priv, struct iwreq *wrq, BOOLEAN invoke_hostcmd)
{
    int data[3];
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_pm_cfg *pmcfg = NULL;
    mlan_ds_hs_cfg hscfg;
    int data_length = wrq->u.data.length;

    ENTER();

    memset(data, 0, sizeof(data));
    memset(&hscfg, 0, sizeof(mlan_ds_hs_cfg));

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    pmcfg = (mlan_ds_pm_cfg *) req->pbuf;
    pmcfg->sub_command = MLAN_OID_PM_CFG_HS_CFG;
    req->req_id = MLAN_IOCTL_PM_CFG;

    if (data_length == 0) {
        req->action = MLAN_ACT_GET;
    } else {
        req->action = MLAN_ACT_SET;
        if (data_length >= 1 && data_length <= 3) {
            if (copy_from_user
                (data, wrq->u.data.pointer, sizeof(int) * data_length)) {
                PRINTM(MERROR, "Copy from user failed\n");
                ret = -EFAULT;
                goto done;
            }
        } else {
            PRINTM(MERROR, "Invalid arguments\n");
            ret = -EINVAL;
            goto done;
        }
    }

    /* Do a GET first if all arguments are not available */
    if (data_length >= 1 && data_length < 3) {
        woal_get_hs_params(priv, MOAL_IOCTL_WAIT, &hscfg);
    }

    switch (data_length) {
    case 3:                    /* Conditions, GPIO, GAP provided */
        pmcfg->param.hs_cfg.conditions = data[0];
        pmcfg->param.hs_cfg.gpio = data[1];
        pmcfg->param.hs_cfg.gap = data[2];
        break;
    case 2:                    /* Conditions, GPIO provided */
        pmcfg->param.hs_cfg.conditions = data[0];
        pmcfg->param.hs_cfg.gpio = data[1];
        pmcfg->param.hs_cfg.gap = hscfg.gap;
        break;
    case 1:                    /* Conditions provided */
        pmcfg->param.hs_cfg.conditions = data[0];
        pmcfg->param.hs_cfg.gpio = hscfg.gpio;
        pmcfg->param.hs_cfg.gap = hscfg.gap;
        break;
    case 0:
        break;
    default:
        break;
    }

    pmcfg->param.hs_cfg.is_invoke_hostcmd = invoke_hostcmd;
    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

    if (req->action == MLAN_ACT_GET) {
        data[0] = pmcfg->param.hs_cfg.conditions;
        data[1] = pmcfg->param.hs_cfg.gpio;
        data[2] = pmcfg->param.hs_cfg.gap;
        wrq->u.data.length = 3;
        if (copy_to_user
            (wrq->u.data.pointer, data, sizeof(int) * wrq->u.data.length)) {
            PRINTM(MERROR, "Copy to user failed\n");
            ret = -EFAULT;
            goto done;
        }
    }
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Set Host Sleep parameters
 *
 *  @param priv         A pointer to moal_private structure
 *  @param wrq	        A pointer to iwreq structure
 *
 *  @return             0 --success, otherwise fail
 */
static int
woal_hs_setpara(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    int data_length = wrq->u.data.length;

    ENTER();

    if (data_length >= 1 && data_length <= 3) {
        ret = woal_hs_cfg(priv, wrq, MFALSE);
        goto done;
    } else {
        PRINTM(MERROR, "Invalid arguments\n");
        ret = -EINVAL;
        goto done;
    }
  done:
    LEAVE();
    return ret;
}

/**
 *  @brief Get/Set inactivity timeout extend
 *
 *  @param priv         A pointer to moal_private structure
 *  @param wrq	        A pointer to iwreq structure
 *
 *  @return             0 --success, otherwise fail
 */
static int
woal_inactivity_timeout_ext(moal_private * priv, struct iwreq *wrq)
{
    int data[4];
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_pm_cfg *pmcfg = NULL;
    pmlan_ds_inactivity_to inac_to = NULL;
    int data_length = wrq->u.data.length;

    ENTER();

    memset(data, 0, sizeof(data));
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    pmcfg = (mlan_ds_pm_cfg *) req->pbuf;
    inac_to = &pmcfg->param.inactivity_to;
    pmcfg->sub_command = MLAN_OID_PM_CFG_INACTIVITY_TO;
    req->req_id = MLAN_IOCTL_PM_CFG;

    if ((data_length != 0) && (data_length != 3) && (data_length != 4)) {
        ret = -EINVAL;
        goto done;
    }

    req->action = MLAN_ACT_GET;
    if (data_length) {
        if (copy_from_user
            (data, wrq->u.data.pointer, sizeof(int) * data_length)) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        req->action = MLAN_ACT_SET;
        inac_to->timeout_unit = data[0];
        inac_to->unicast_timeout = data[1];
        inac_to->mcast_timeout = data[2];
        inac_to->ps_entry_timeout = data[3];
    }

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

    /* Copy back current values regardless of GET/SET */
    data[0] = inac_to->timeout_unit;
    data[1] = inac_to->unicast_timeout;
    data[2] = inac_to->mcast_timeout;
    data[3] = inac_to->ps_entry_timeout;

    if (req->action == MLAN_ACT_GET) {
        wrq->u.data.length = 4;
        if (copy_to_user
            (wrq->u.data.pointer, data, wrq->u.data.length * sizeof(int))) {
            PRINTM(MERROR, "Copy to user failed\n");
            ret = -EFAULT;
            goto done;
        }
    }

  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Set/Get system clock
 *
 *  @param priv         A pointer to moal_private structure
 *  @param wrq	        A pointer to iwreq structure
 *
 *  @return             0 --success, otherwise fail
 */
static int
woal_ecl_sys_clock(moal_private * priv, struct iwreq *wrq)
{
    int data[64];
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_misc_cfg *cfg = NULL;
    int data_length = wrq->u.data.length;
    int i = 0;

    ENTER();

    memset(data, 0, sizeof(data));

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    cfg = (mlan_ds_misc_cfg *) req->pbuf;
    cfg->sub_command = MLAN_OID_MISC_SYS_CLOCK;
    req->req_id = MLAN_IOCTL_MISC_CFG;

    if (!data_length)
        req->action = MLAN_ACT_GET;
    else if (data_length <= MLAN_MAX_CLK_NUM) {
        req->action = MLAN_ACT_SET;
        if (copy_from_user
            (data, wrq->u.data.pointer, sizeof(int) * data_length)) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
    } else {
        PRINTM(MERROR, "Invalid arguments\n");
        ret = -EINVAL;
        goto done;
    }

    if (req->action == MLAN_ACT_GET) {
        /* Get configurable clocks */
        cfg->param.sys_clock.sys_clk_type = MLAN_CLK_CONFIGURABLE;
        if (MLAN_STATUS_SUCCESS !=
            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
            ret = -EFAULT;
            goto done;
        }

        /* Current system clock */
        data[0] = (int) cfg->param.sys_clock.cur_sys_clk;
        wrq->u.data.length = 1;

        data_length = MIN(cfg->param.sys_clock.sys_clk_num, MLAN_MAX_CLK_NUM);

        /* Configurable clocks */
        for (i = 0; i < data_length; i++) {
            data[i + wrq->u.data.length] =
                (int) cfg->param.sys_clock.sys_clk[i];
        }
        wrq->u.data.length += data_length;

        /* Get supported clocks */
        cfg->param.sys_clock.sys_clk_type = MLAN_CLK_SUPPORTED;
        if (MLAN_STATUS_SUCCESS !=
            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
            ret = -EFAULT;
            goto done;
        }

        data_length = MIN(cfg->param.sys_clock.sys_clk_num, MLAN_MAX_CLK_NUM);

        /* Supported clocks */
        for (i = 0; i < data_length; i++) {
            data[i + wrq->u.data.length] =
                (int) cfg->param.sys_clock.sys_clk[i];
        }

        wrq->u.data.length += data_length;

        if (copy_to_user
            (wrq->u.data.pointer, data, sizeof(int) * wrq->u.data.length)) {
            PRINTM(MERROR, "Copy to user failed\n");
            ret = -EFAULT;
            goto done;
        }
    } else {
        /* Set configurable clocks */
        cfg->param.sys_clock.sys_clk_type = MLAN_CLK_CONFIGURABLE;
        cfg->param.sys_clock.sys_clk_num = MIN(MLAN_MAX_CLK_NUM, data_length);
        for (i = 0; i < cfg->param.sys_clock.sys_clk_num; i++) {
            cfg->param.sys_clock.sys_clk[i] = (t_u16) data[i];
        }

        if (MLAN_STATUS_SUCCESS !=
            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
            ret = -EFAULT;
            goto done;
        }
    }
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Set/Get Band and Adhoc-band setting
 *
 *  @param priv         A pointer to moal_private structure
 *  @param wrq	        A pointer to iwreq structure
 *
 *  @return             0 --success, otherwise fail
 */
static int
woal_band_cfg(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0, i;
    int data[3];
    int user_data_len = wrq->u.data.length;
    t_u32 infra_band = 0;
    t_u32 adhoc_band = 0;
    t_u32 adhoc_channel = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_radio_cfg *radio_cfg = NULL;

    ENTER();

    if (user_data_len > 3) {
        LEAVE();
        return -EINVAL;
    }

    if (user_data_len > 0) {
        if (priv->media_connected == MTRUE) {
            LEAVE();
            return -EOPNOTSUPP;
        }
    }

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_radio_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto error;
    }
    radio_cfg = (mlan_ds_radio_cfg *) req->pbuf;
    radio_cfg->sub_command = MLAN_OID_BAND_CFG;
    req->req_id = MLAN_IOCTL_RADIO_CFG;

    if (wrq->u.data.length == 0) {
        /* Get config_bands, adhoc_start_band and adhoc_channnel values from
           MLAN */
        req->action = MLAN_ACT_GET;
        if (MLAN_STATUS_SUCCESS !=
            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
            ret = -EFAULT;
            goto error;
        }
        data[0] = radio_cfg->param.band_cfg.config_bands;       /* Infra Band */
        data[1] = radio_cfg->param.band_cfg.adhoc_start_band;   /* Adhoc Band */
        data[2] = radio_cfg->param.band_cfg.adhoc_channel;      /* Adhoc
                                                                   Channel */

        wrq->u.data.length = 3;
        if (copy_to_user
            (wrq->u.data.pointer, data, sizeof(int) * wrq->u.data.length)) {
            ret = -EFAULT;
            goto error;
        }
    } else {
        if (copy_from_user
            (data, wrq->u.data.pointer, sizeof(int) * wrq->u.data.length)) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto error;
        }

        /* To support only <b/bg/bgn/n> */
        infra_band = data[0];
        for (i = 0; i < sizeof(SupportedInfraBand); i++)
            if (infra_band == SupportedInfraBand[i])
                break;
        if (i == sizeof(SupportedInfraBand)) {
            ret = -EINVAL;
            goto error;
        }

        /* Set Adhoc band */
        if (user_data_len >= 2) {
            adhoc_band = data[1];
            for (i = 0; i < sizeof(SupportedAdhocBand); i++)
                if (adhoc_band == SupportedAdhocBand[i])
                    break;
            if (i == sizeof(SupportedAdhocBand)) {
                ret = -EINVAL;
                goto error;
            }
        }

        /* Set Adhoc channel */
        if (user_data_len == 3) {
            adhoc_channel = data[2];
            if (adhoc_channel == 0) {
                /* Check if specified adhoc channel is non-zero */
                ret = -EINVAL;
                goto error;
            }
        }

        /* Set config_bands and adhoc_start_band values to MLAN */
        req->action = MLAN_ACT_SET;
        radio_cfg->param.band_cfg.config_bands = infra_band;
        radio_cfg->param.band_cfg.adhoc_start_band = adhoc_band;
        radio_cfg->param.band_cfg.adhoc_channel = adhoc_channel;
        if (MLAN_STATUS_SUCCESS !=
            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
            ret = -EFAULT;
            goto error;
        }
    }

  error:
    if (req)
        kfree(req);

    LEAVE();
    return ret;
}

/** 
 *  @brief Set/Get BCA timeshare
 *  
 *  @param priv         A pointer to moal_private structure
 *  @param wrq          A pointer to iwreq structure
 *
 *  @return             0 --success, otherwise fail
 */
static int
woal_bca_time_share(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    int data[3];
    int user_data_len = wrq->u.data.length;
    mlan_ioctl_req *req = NULL;
    mlan_ds_bca_cfg *bca_cfg = NULL;

    ENTER();

    if (user_data_len != 1 && user_data_len != 3) {
        PRINTM(MERROR, "Invalid number of parameters\n");
        LEAVE();
        return -EINVAL;
    }

    if (copy_from_user(data, wrq->u.data.pointer, sizeof(int) * user_data_len)) {
        PRINTM(MERROR, "Copy from user failed\n");
        LEAVE();
        return -EFAULT;
    }

    if ((data[0] > TRAFFIC_TYPE_MEDIUMHIGH) && (data[0] != TRAFFIC_TYPE_RESET)) {
        PRINTM(MERROR, "Invalid traffic_type\n");
        LEAVE();
        return -EINVAL;
    }

    if (user_data_len == 3) {
        /* Valid Range for timeshare_interval: < 20 ... 60_000 > ms */
        if (data[1] < MIN_TIMESHARE_INTERVAL ||
            data[1] > MAX_TIMESHARE_INTERVAL) {
            PRINTM(MERROR,
                   "Invalid timeshare_interval Range: < 20 ... 60000 > ms\n");
            LEAVE();
            return -EINVAL;
        }
        data[1] -= (data[1] % 10);      /* If value is not multiple of 10 then
                                           take the floor value */

        /* If value is not multiple of 10 then take the floor value */
        data[2] -= (data[2] % 10);
        /* Valid Range for timeshare_interval: < 0 ... bt_time > */
        if (data[2] < 0 || data[2] > data[1]) {
            PRINTM(MERROR,
                   "Invalid bt_time  Range: < 0 ... timeshare_interval > ms\n");
            LEAVE();
            return -EINVAL;
        }
    }

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bca_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto error;
    }
    bca_cfg = (mlan_ds_bca_cfg *) req->pbuf;
    bca_cfg->sub_command = MLAN_OID_BCA_TS;
    req->req_id = MLAN_IOCTL_BCA_CFG;
    req->action = MLAN_ACT_GET;

    if (user_data_len > 0)
        bca_cfg->param.bca_ts.traffic_type = data[0];
    if (user_data_len == 3) {
        req->action = MLAN_ACT_SET;
        bca_cfg->param.bca_ts.timeshare_interval = data[1];
        bca_cfg->param.bca_ts.bt_time = data[2];
    }

    PRINTM(MINFO, "traffic_type=0x%x", data[0]);
    if (user_data_len == 3)
        PRINTM(MINFO, " timeshare_interval=0x%x bt_time=0x%x\n", data[1],
               data[2]);

    /* Set/Get BCA time share values from MLAN */
    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto error;
    }

    if (user_data_len < 3) {
        data[0] = bca_cfg->param.bca_ts.traffic_type;
        data[1] = bca_cfg->param.bca_ts.timeshare_interval;
        data[2] = bca_cfg->param.bca_ts.bt_time;

        wrq->u.data.length = 3;
        if (copy_to_user(wrq->u.data.pointer, data, sizeof(data))) {
            PRINTM(MERROR, "Copy to user failed\n");
            ret = -EFAULT;
            goto error;
        }
    }

  error:
    if (req)
        kfree(req);

    LEAVE();
    return ret;
}

/**
 *  @brief Read/Write adapter registers value 
 *
 *  @param priv         A pointer to moal_private structure
 *  @param wrq	        A pointer to iwreq structure
 *
 *  @return             0 --success, otherwise fail
 */
static int
woal_reg_read_write(moal_private * priv, struct iwreq *wrq)
{
    int data[3];
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_reg_mem *reg = NULL;
    int data_length = wrq->u.data.length;

    ENTER();

    memset(data, 0, sizeof(data));

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_reg_mem));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    reg = (mlan_ds_reg_mem *) req->pbuf;
    reg->sub_command = MLAN_OID_REG_RW;
    req->req_id = MLAN_IOCTL_REG_MEM;

    if (data_length == 2) {
        req->action = MLAN_ACT_GET;
    } else if (data_length == 3) {
        req->action = MLAN_ACT_SET;
    } else {
        ret = -EINVAL;
        goto done;
    }
    if (copy_from_user(data, wrq->u.data.pointer, sizeof(int) * data_length)) {
        PRINTM(MERROR, "Copy from user failed\n");
        ret = -EFAULT;
        goto done;
    }
    reg->param.reg_rw.type = (t_u32) data[0];
    reg->param.reg_rw.offset = (t_u32) data[1];
    if (data_length == 3)
        reg->param.reg_rw.value = (t_u32) data[2];

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

    if (req->action == MLAN_ACT_GET) {
        if (copy_to_user
            (wrq->u.data.pointer, &reg->param.reg_rw.value, sizeof(int))) {
            PRINTM(MERROR, "Copy to user failed\n");
            ret = -EFAULT;
            goto done;
        }
        wrq->u.data.length = 1;
    }

  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Read the EEPROM contents of the card 
 *
 *  @param priv         A pointer to moal_private structure
 *  @param wrq	        A pointer to iwreq structure
 *
 *  @return             0 --success, otherwise fail
 */
static int
woal_read_eeprom(moal_private * priv, struct iwreq *wrq)
{
    int data[2];
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_reg_mem *reg = NULL;
    int data_length = wrq->u.data.length;

    ENTER();

    memset(data, 0, sizeof(data));

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_reg_mem));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    reg = (mlan_ds_reg_mem *) req->pbuf;
    reg->sub_command = MLAN_OID_EEPROM_RD;
    req->req_id = MLAN_IOCTL_REG_MEM;

    if (data_length == 2) {
        req->action = MLAN_ACT_GET;
    } else {
        ret = -EINVAL;
        goto done;
    }
    if (copy_from_user(data, wrq->u.data.pointer, sizeof(int) * data_length)) {
        PRINTM(MERROR, "Copy from user failed\n");
        ret = -EFAULT;
        goto done;
    }

    reg->param.rd_eeprom.offset = (t_u16) data[0];
    reg->param.rd_eeprom.byte_count = (t_u16) data[1];

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

    if (req->action == MLAN_ACT_GET) {
        wrq->u.data.length = reg->param.rd_eeprom.byte_count;
        if (copy_to_user
            (wrq->u.data.pointer, reg->param.rd_eeprom.value,
             wrq->u.data.length)) {
            PRINTM(MERROR, "Copy to user failed\n");
            ret = -EFAULT;
            goto done;
        }
    }

  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Read/Write device memory value 
 *
 *  @param priv         A pointer to moal_private structure
 *  @param wrq	        A pointer to iwreq structure
 *
 *  @return             0 --success, otherwise fail
 */
static int
woal_mem_read_write(moal_private * priv, struct iwreq *wrq)
{
    t_u32 data[2];
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_reg_mem *reg_mem = NULL;
    int data_length = wrq->u.data.length;

    ENTER();

    memset(data, 0, sizeof(data));

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_reg_mem));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    reg_mem = (mlan_ds_reg_mem *) req->pbuf;
    reg_mem->sub_command = MLAN_OID_MEM_RW;
    req->req_id = MLAN_IOCTL_REG_MEM;

    if (data_length == 1) {
        PRINTM(MINFO, "MEM_RW: GET\n");
        req->action = MLAN_ACT_GET;
    } else if (data_length == 2) {
        PRINTM(MINFO, "MEM_RW: SET\n");
        req->action = MLAN_ACT_SET;
    } else {
        ret = -EINVAL;
        goto done;
    }
    if (copy_from_user(data, wrq->u.data.pointer, sizeof(int) * data_length)) {
        PRINTM(MERROR, "Copy from user failed\n");
        ret = -EFAULT;
        goto done;
    }

    reg_mem->param.mem_rw.addr = (t_u32) data[0];
    if (data_length == 2)
        reg_mem->param.mem_rw.value = (t_u32) data[1];

    PRINTM(MINFO, "MEM_RW: Addr=0x%x, Value=0x%x\n",
           (int) reg_mem->param.mem_rw.addr, (int) reg_mem->param.mem_rw.value);

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

    if (req->action == MLAN_ACT_GET) {
        if (copy_to_user
            (wrq->u.data.pointer, &reg_mem->param.mem_rw.value, sizeof(int))) {
            PRINTM(MERROR, "Copy to user failed\n");
            ret = -EFAULT;
            goto done;
        }
        wrq->u.data.length = 1;
    }

  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Get LOG
 *
 *  @param priv                 A pointer to moal_private structure
 *  @param wrq			A pointer to iwreq structure
 *
 *  @return 	   	 	0 --success, otherwise fail
 */
static int
woal_get_log(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_ds_get_stats stats;
    char *buf = NULL;

    ENTER();

    PRINTM(MINFO, " GET STATS\n");
    if (!(buf = kmalloc(GETLOG_BUFSIZE, GFP_ATOMIC))) {
        PRINTM(MERROR, "kmalloc failed!\n");
        ret = -ENOMEM;
        goto done;
    }

    memset(&stats, 0, sizeof(mlan_ds_get_stats));
    if (MLAN_STATUS_SUCCESS !=
        woal_get_stats_info(priv, MOAL_IOCTL_WAIT, &stats)) {
        ret = -EFAULT;
        goto done;
    }

    if (wrq->u.data.pointer) {
        sprintf(buf, "\n"
                "mcasttxframe     %lu\n"
                "failed           %lu\n"
                "retry            %lu\n"
                "multiretry       %lu\n"
                "framedup         %lu\n"
                "rtssuccess       %lu\n"
                "rtsfailure       %lu\n"
                "ackfailure       %lu\n"
                "rxfrag           %lu\n"
                "mcastrxframe     %lu\n"
                "fcserror         %lu\n"
                "txframe          %lu\n"
                "wepicverrcnt-1   %lu\n"
                "wepicverrcnt-2   %lu\n"
                "wepicverrcnt-3   %lu\n"
                "wepicverrcnt-4   %lu\n",
                stats.mcast_tx_frame,
                stats.failed,
                stats.retry,
                stats.multi_retry,
                stats.frame_dup,
                stats.rts_success,
                stats.rts_failure,
                stats.ack_failure,
                stats.rx_frag,
                stats.mcast_rx_frame,
                stats.fcs_error,
                stats.tx_frame,
                stats.wep_icv_error[0],
                stats.wep_icv_error[1],
                stats.wep_icv_error[2], stats.wep_icv_error[3]);
        wrq->u.data.length = strlen(buf) + 1;
        if (copy_to_user(wrq->u.data.pointer, buf, wrq->u.data.length)) {
            PRINTM(MERROR, "Copy to user failed\n");
            ret = -EFAULT;
        }
    }
  done:
    if (buf)
        kfree(buf);
    LEAVE();
    return ret;
}

/**
 *  @brief Deauthenticate
 *
 *  @param priv                 A pointer to moal_private structure
 *  @param wrq			A pointer to iwreq structure
 *
 *  @return 	   	 	0 --success, otherwise fail
 */
static int
woal_deauth(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    struct sockaddr saddr;

    ENTER();
    if (wrq->u.data.length) {
        /* Deauth mentioned BSSID */
        if (copy_from_user(&saddr, wrq->u.data.pointer, sizeof(saddr))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        if (MLAN_STATUS_SUCCESS !=
            woal_disconnect(priv, MOAL_IOCTL_WAIT, (t_u8 *) saddr.sa_data))
            ret = -EFAULT;
    } else {
        if (MLAN_STATUS_SUCCESS != woal_disconnect(priv, MOAL_IOCTL_WAIT, NULL))
            ret = -EFAULT;
    }
  done:
    LEAVE();
    return ret;
}

/**
 *  @brief Set/Get TX power configurations
 *  
 *  @param priv     A pointer to moal_private structure
 *  @param wrq      A pointer to iwreq structure
 *  
 *  @return         0 --success, otherwise fail
 */
static int
woal_tx_power_cfg(moal_private * priv, struct iwreq *wrq)
{
    int data[5], user_data_len;
    int ret = 0;
    mlan_bss_info bss_info;
    mlan_ds_power_cfg *pcfg = NULL;
    mlan_ioctl_req *req = NULL;
    ENTER();

    memset(&bss_info, 0, sizeof(bss_info));
    woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);

    memset(data, 0, sizeof(data));
    user_data_len = wrq->u.data.length;

    if (user_data_len) {
        if (copy_from_user
            (data, wrq->u.data.pointer, sizeof(int) * user_data_len)) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        switch (user_data_len) {
        case 1:
            if (data[0] != 0xFF)
                ret = -EINVAL;
            break;
        case 2:
        case 4:
            if (data[0] == 0xFF) {
                ret = -EINVAL;
                break;
            }
            if (data[1] < bss_info.min_power_level) {
                PRINTM(MERROR,
                       "The set powercfg rate value %d dBm is out of range (%d dBm-%d dBm)!\n",
                       data[1], (int) bss_info.min_power_level,
                       (int) bss_info.max_power_level);
                ret = -EINVAL;
                break;
            }
            if (user_data_len == 4) {
                if (data[1] > data[2]) {
                    PRINTM(MERROR, "Min power should be less than maximum!\n");
                    ret = -EINVAL;
                    break;
                }
                if (data[3] < 0) {
                    PRINTM(MERROR, "Step should not less than 0!\n");
                    ret = -EINVAL;
                    break;
                }
                if (data[2] > bss_info.max_power_level) {
                    PRINTM(MERROR,
                           "The set powercfg rate value %d dBm is out of range (%d dBm-%d dBm)!\n",
                           data[2], (int) bss_info.min_power_level,
                           (int) bss_info.max_power_level);
                    ret = -EINVAL;
                    break;
                }
                if (data[3] > data[2] - data[1]) {
                    PRINTM(MERROR,
                           "Step should not greater than power difference!\n");
                    ret = -EINVAL;
                    break;
                }
            }
            break;
        default:
            ret = -EINVAL;
            break;
        }
        if (ret)
            goto done;
    }

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_power_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    pcfg = (mlan_ds_power_cfg *) req->pbuf;
    pcfg->sub_command = MLAN_OID_POWER_CFG_EXT;
    req->req_id = MLAN_IOCTL_POWER_CFG;
    if (!user_data_len)
        req->action = MLAN_ACT_GET;
    else {
        req->action = MLAN_ACT_SET;
        pcfg->param.power_ext.len = user_data_len;
        memcpy((t_u8 *) & pcfg->param.power_ext.power_data, (t_u8 *) data,
               sizeof(data));
    }
    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }
    if (!user_data_len) {
        if (copy_to_user
            (wrq->u.data.pointer, (t_u8 *) & pcfg->param.power_ext.power_data,
             sizeof(int) * pcfg->param.power_ext.len)) {
            ret = -EFAULT;
            goto done;
        }
        wrq->u.data.length = pcfg->param.power_ext.len;
    }
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Get Tx/Rx data rates
 *  
 *  @param priv     A pointer to moal_private structure
 *  @param wrq      A pointer to iwreq structure
 *  
 *  @return         0 --success, otherwise fail
 */
static int
woal_get_txrx_rate(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_ds_rate *rate = NULL;
    mlan_ioctl_req *req = NULL;

    ENTER();

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_rate));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    rate = (mlan_ds_rate *) req->pbuf;
    rate->sub_command = MLAN_OID_GET_DATA_RATE;
    req->req_id = MLAN_IOCTL_RATE;
    req->action = MLAN_ACT_GET;

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

    if (copy_to_user
        (wrq->u.data.pointer, (t_u8 *) & rate->param.data_rate,
         sizeof(int) * 2)) {
        ret = -EFAULT;
        goto done;
    }
    wrq->u.data.length = 2;
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Turn on/off the sdio clock
 *  
 *  @param priv     A pointer to moal_private structure
 *  @param wrq      A pointer to iwreq structure
 *  
 *  @return         0 --success, otherwise fail
 */
static int
woal_sdio_clock_ioctl(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    int data = 2;
    /* Initialize the clock state as on */
    static int clock_state = 1;

    ENTER();

    if (wrq->u.data.length) {
        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
    } else {
        wrq->u.data.length = sizeof(clock_state) / sizeof(int);
        if (copy_to_user(wrq->u.data.pointer, &clock_state, sizeof(int))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }

        goto done;
    }
    switch (data) {
    case CMD_DISABLED:
        PRINTM(MINFO, "SDIO clock is turned off\n");
        ret = woal_sdio_set_bus_clock(priv->phandle, MFALSE);
        clock_state = data;
        break;
    case CMD_ENABLED:
        PRINTM(MINFO, "SDIO clock is turned on\n");
        ret = woal_sdio_set_bus_clock(priv->phandle, MTRUE);
        clock_state = data;
        break;
    default:
        ret = -EINVAL;
        PRINTM(MINFO, "sdioclock: wrong parameter\n");
        break;
    }
  done:
    return ret;
}

/**
 *  @brief Set/Get beacon interval
 *  
 *  @param priv     A pointer to moal_private structure
 *  @param wrq      A pointer to iwreq structure
 *  
 *  @return         0 --success, otherwise fail
 */
static int
woal_beacon_interval(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_ds_bss *bss = NULL;
    mlan_ioctl_req *req = NULL;
    int bcn = 0;

    ENTER();

    if (wrq->u.data.length) {
        if (copy_from_user(&bcn, wrq->u.data.pointer, sizeof(int))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        if ((bcn < MLAN_MIN_BEACON_INTERVAL) ||
            (bcn > MLAN_MAX_BEACON_INTERVAL)) {
            ret = -EINVAL;
            goto done;
        }
    }

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    bss = (mlan_ds_bss *) req->pbuf;
    bss->sub_command = MLAN_OID_IBSS_BCN_INTERVAL;
    req->req_id = MLAN_IOCTL_BSS;
    if (!wrq->u.data.length)
        req->action = MLAN_ACT_GET;
    else {
        req->action = MLAN_ACT_SET;
        bss->param.bcn_interval = bcn;
    }

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

    if (copy_to_user
        (wrq->u.data.pointer, (t_u8 *) & bss->param.bcn_interval,
         sizeof(int))) {
        ret = -EFAULT;
        goto done;
    }
    wrq->u.data.length = 1;
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Set/Get ATIM window
 *  
 *  @param priv     A pointer to moal_private structure
 *  @param wrq      A pointer to iwreq structure
 *  
 *  @return         0 --success, otherwise fail
 */
static int
woal_atim_window(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_ds_bss *bss = NULL;
    mlan_ioctl_req *req = NULL;
    int atim = 0;

    ENTER();

    if (wrq->u.data.length) {
        if (copy_from_user(&atim, wrq->u.data.pointer, sizeof(int))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        if ((atim < 0) || (atim > MLAN_MAX_ATIM_WINDOW)) {
            ret = -EINVAL;
            goto done;
        }
    }

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    bss = (mlan_ds_bss *) req->pbuf;
    bss->sub_command = MLAN_OID_IBSS_ATIM_WINDOW;
    req->req_id = MLAN_IOCTL_BSS;
    if (!wrq->u.data.length)
        req->action = MLAN_ACT_GET;
    else {
        req->action = MLAN_ACT_SET;
        bss->param.atim_window = atim;
    }

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

    if (copy_to_user
        (wrq->u.data.pointer, (t_u8 *) & bss->param.atim_window, sizeof(int))) {
        ret = -EFAULT;
        goto done;
    }
    wrq->u.data.length = 1;
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 * @brief Set/Get TX data rate
 * 
 * @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_txrate(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_ds_rate *rate = NULL;
    mlan_ioctl_req *req = NULL;
    int rateindex = 0;

    ENTER();
    if (wrq->u.data.length) {
        if (copy_from_user(&rateindex, wrq->u.data.pointer, sizeof(int))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
    }
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_rate));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    rate = (mlan_ds_rate *) req->pbuf;
    rate->param.rate_cfg.rate_type = MLAN_RATE_INDEX;
    rate->sub_command = MLAN_OID_RATE_CFG;
    req->req_id = MLAN_IOCTL_RATE;
    if (!wrq->u.data.length)
        req->action = MLAN_ACT_GET;
    else {
        req->action = MLAN_ACT_SET;
        if (rateindex == AUTO_RATE)
            rate->param.rate_cfg.is_rate_auto = 1;
        else {
            if ((rateindex != MLAN_RATE_INDEX_MCS32) &&
                ((rateindex < 0) || (rateindex > MLAN_RATE_INDEX_MCS7))) {
                ret = -EINVAL;
                goto done;
            }
        }
        rate->param.rate_cfg.rate = rateindex;
    }

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    } else {
        if (wrq->u.data.length)
            priv->rate_index = rateindex;
    }
    if (!wrq->u.data.length) {
        if (rate->param.rate_cfg.is_rate_auto)
            rateindex = AUTO_RATE;
        else
            rateindex = rate->param.rate_cfg.rate;
        wrq->u.data.length = 1;
        if (copy_to_user(wrq->u.data.pointer, &rateindex, sizeof(int))) {
            ret = -EFAULT;
        }
    }
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 * @brief Set/Get region code
 * 
 * @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_regioncode(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_ds_misc_cfg *cfg = NULL;
    mlan_ioctl_req *req = NULL;
    int region = 0;

    ENTER();

    if (wrq->u.data.length) {
        if (copy_from_user(&region, wrq->u.data.pointer, sizeof(int))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
    }

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    cfg = (mlan_ds_misc_cfg *) req->pbuf;
    cfg->sub_command = MLAN_OID_MISC_REGION;
    req->req_id = MLAN_IOCTL_MISC_CFG;
    if (!wrq->u.data.length)
        req->action = MLAN_ACT_GET;
    else {
        req->action = MLAN_ACT_SET;
        cfg->param.region_code = region;
    }

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

    if (!wrq->u.data.length) {
        wrq->u.data.length = 1;
        if (copy_to_user
            (wrq->u.data.pointer, &cfg->param.region_code, sizeof(int)))
            ret = -EFAULT;
    }
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 * @brief Set/Get radio
 * 
 * @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_radio(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_bss_info bss_info;
    int option = 0;

    ENTER();

    memset(&bss_info, 0, sizeof(bss_info));

    if (wrq->u.data.length) {
        /* Set radio */
        if (copy_from_user(&option, wrq->u.data.pointer, sizeof(int))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        if (MLAN_STATUS_SUCCESS != woal_set_radio(priv, (t_u8) option))
            ret = -EFAULT;
    } else {
        /* Get radio status */
        woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);
        wrq->u.data.length = 1;
        if (copy_to_user
            (wrq->u.data.pointer, &bss_info.radio_on,
             sizeof(bss_info.radio_on))) {
            PRINTM(MERROR, "Copy to user failed\n");
            ret = -EFAULT;
        }
    }
  done:
    LEAVE();
    return ret;
}

#ifdef DEBUG_LEVEL1
/** 
 *  @brief Get/Set the bit mask of driver debug message control
 *
 *  @param priv			A pointer to moal_private structure
 *  @param wrq			A pointer to wrq structure
 *
 *  @return             0 --success, otherwise fail
 */
static int
woal_drv_dbg(moal_private * priv, struct iwreq *wrq)
{
    int data[4];
    int ret = 0;

    ENTER();

    if (!wrq->u.data.length) {
        data[0] = drvdbg;
        data[1] = ifdbg;
        /* Return the current driver debug bit masks */
        if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 2)) {
            PRINTM(MERROR, "Copy to user failed\n");
            ret = -EFAULT;
            goto drvdbgexit;
        }
        wrq->u.data.length = 2;
    } else if (wrq->u.data.length < 3) {
        /* Get the driver debug bit masks */
        if (copy_from_user
            (data, wrq->u.data.pointer, sizeof(int) * wrq->u.data.length)) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto drvdbgexit;
        }
        drvdbg = data[0];
        if (wrq->u.data.length == 2)
            ifdbg = data[1];
    } else {
        PRINTM(MERROR, "Invalid parameter number\n");
        goto drvdbgexit;
    }

    printk(KERN_ALERT "drvdbg = 0x%08lx\n", drvdbg);
#ifdef DEBUG_LEVEL2
    printk(KERN_ALERT "MINFO  (%08lx) %s\n", MINFO,
           (drvdbg & MINFO) ? "X" : "");
    printk(KERN_ALERT "MWARN  (%08lx) %s\n", MWARN,
           (drvdbg & MWARN) ? "X" : "");
    printk(KERN_ALERT "MENTRY (%08lx) %s\n", MENTRY,
           (drvdbg & MENTRY) ? "X" : "");
#endif
    printk(KERN_ALERT "MFW_D  (%08lx) %s\n", MFW_D,
           (drvdbg & MFW_D) ? "X" : "");
    printk(KERN_ALERT "MCMD_D (%08lx) %s\n", MCMD_D,
           (drvdbg & MCMD_D) ? "X" : "");
    printk(KERN_ALERT "MDAT_D (%08lx) %s\n", MDAT_D,
           (drvdbg & MDAT_D) ? "X" : "");
    printk(KERN_ALERT "MINTR  (%08lx) %s\n", MINTR,
           (drvdbg & MINTR) ? "X" : "");
    printk(KERN_ALERT "MEVENT (%08lx) %s\n", MEVENT,
           (drvdbg & MEVENT) ? "X" : "");
    printk(KERN_ALERT "MCMND  (%08lx) %s\n", MCMND,
           (drvdbg & MCMND) ? "X" : "");
    printk(KERN_ALERT "MDATA  (%08lx) %s\n", MDATA,
           (drvdbg & MDATA) ? "X" : "");
    printk(KERN_ALERT "MERROR (%08lx) %s\n", MERROR,
           (drvdbg & MERROR) ? "X" : "");
    printk(KERN_ALERT "MFATAL (%08lx) %s\n", MFATAL,
           (drvdbg & MFATAL) ? "X" : "");
    printk(KERN_ALERT "MMSG   (%08lx) %s\n", MMSG, (drvdbg & MMSG) ? "X" : "");
    printk(KERN_ALERT "ifdbg = 0x%08lx\n", ifdbg);
    printk(KERN_ALERT "MIF_D  (%08lx) %s\n", MIF_D, (ifdbg & MIF_D) ? "X" : "");

  drvdbgexit:
    LEAVE();
    return ret;
}
#endif /* DEBUG_LEVEL1 */

/**
 * @brief Set/Get Tx/Rx antenna
 * 
 * @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_tx_rx_ant(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_ds_radio_cfg *radio = NULL;
    mlan_ioctl_req *req = NULL;
    int data = 0;

    ENTER();
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_radio_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    radio = (mlan_ds_radio_cfg *) req->pbuf;
    radio->sub_command = MLAN_OID_ANT_CFG;
    req->req_id = MLAN_IOCTL_RADIO_CFG;
    if (wrq->u.data.length) {
        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        req->action = MLAN_ACT_SET;
        radio->param.antenna = data;
    } else
        req->action = MLAN_ACT_GET;
    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }
    if (!wrq->u.data.length) {
        data = radio->param.antenna;
        if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
            ret = -EFAULT;
            goto done;
        }
        wrq->u.data.length = 1;
    }
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 * @brief Set/Get QoS configuration
 * 
 * @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_qos_cfg(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_ds_wmm_cfg *cfg = NULL;
    mlan_ioctl_req *req = NULL;
    int data = 0;

    ENTER();
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    cfg = (mlan_ds_wmm_cfg *) req->pbuf;
    cfg->sub_command = MLAN_OID_WMM_CFG_QOS;
    req->req_id = MLAN_IOCTL_WMM_CFG;
    if (wrq->u.data.length) {
        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        req->action = MLAN_ACT_SET;
        cfg->param.qos_cfg = (t_u8) data;
    } else
        req->action = MLAN_ACT_GET;
    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }
    if (!wrq->u.data.length) {
        data = (int) cfg->param.qos_cfg;
        if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
            ret = -EFAULT;
            goto done;
        }
        wrq->u.data.length = 1;
    }
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 * @brief Set/Get LDO configuration
 * 
 * @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_ldo_cfg(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_ds_misc_cfg *cfg = NULL;
    mlan_ioctl_req *req = NULL;
    int data = 0;

    ENTER();
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    cfg = (mlan_ds_misc_cfg *) req->pbuf;
    cfg->sub_command = MLAN_OID_MISC_LDO;
    req->req_id = MLAN_IOCTL_MISC_CFG;
    if (wrq->u.data.length) {
        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        if (data != LDO_INTERNAL && data != LDO_EXTERNAL) {
            PRINTM(MERROR, "Invalid parameter, LDO config not changed\n");
            ret = -EINVAL;
            goto done;
        }
        req->action = MLAN_ACT_SET;
        cfg->param.ldo_cfg = (t_u16) data;
    } else
        req->action = MLAN_ACT_GET;
    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }
    if (!wrq->u.data.length) {
        data = (int) cfg->param.ldo_cfg;
        if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
            ret = -EFAULT;
            goto done;
        }
        wrq->u.data.length = 1;
    }
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 * @brief Set/Get WWS mode
 * 
 * @param priv     A pointer to moal_private structure
 * @param wrq      A pointer to iwreq structure
 * 
 * @return         0 --success, otherwise fail
 */
static int
woal_wws_cfg(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_ds_misc_cfg *wws = NULL;
    mlan_ioctl_req *req = NULL;
    int data = 0;

    ENTER();
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    wws = (mlan_ds_misc_cfg *) req->pbuf;
    wws->sub_command = MLAN_OID_MISC_WWS;
    req->req_id = MLAN_IOCTL_MISC_CFG;
    if (wrq->u.data.length) {
        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        if (data != CMD_DISABLED && data != CMD_ENABLED) {
            ret = -EINVAL;
            goto done;
        }
        req->action = MLAN_ACT_SET;
        wws->param.wws_cfg = data;
    } else
        req->action = MLAN_ACT_GET;
    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }
    if (!wrq->u.data.length) {
        data = wws->param.wws_cfg;
        if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
            ret = -EFAULT;
            goto done;
        }
        wrq->u.data.length = 1;
    }
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 * @brief Set/Get sleep period
 * 
 * @param priv     A pointer to moal_private structure
 * @param wrq      A pointer to iwreq structure
 * 
 * @return         0 --success, otherwise fail
 */
static int
woal_sleep_pd(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_ds_pm_cfg *pm_cfg = NULL;
    mlan_ioctl_req *req = NULL;
    int data = 0;

    ENTER();

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    pm_cfg = (mlan_ds_pm_cfg *) req->pbuf;
    pm_cfg->sub_command = MLAN_OID_PM_CFG_SLEEP_PD;
    req->req_id = MLAN_IOCTL_PM_CFG;
    if (wrq->u.data.length) {
        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        if ((data <= MAX_SLEEP_PERIOD && data >= MIN_SLEEP_PERIOD) ||
            (data == 0)
            || (data == SLEEP_PERIOD_RESERVED_FF)
            ) {
            req->action = MLAN_ACT_SET;
            pm_cfg->param.sleep_period = data;
        } else {
            ret = -EINVAL;
            goto done;
        }
    } else
        req->action = MLAN_ACT_GET;

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }
    if (!wrq->u.data.length) {
        data = pm_cfg->param.sleep_period;
        if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
            ret = -EFAULT;
            goto done;
        }
        wrq->u.data.length = 1;
    }

  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 * @brief Configuer sleep parameters
 *
 * @param priv         A pointer to moal_private structure
 * @param req          A pointer to ifreq structure
 *
 * @return             0 --success, otherwise fail  
 */
static int
woal_sleep_params_ioctl(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_pm_cfg *pm = NULL;
    mlan_ds_sleep_params *psleep_params = NULL;
    int data[6] = { 0 }, i;
#ifdef DEBUG_LEVEL1
    char err_str[][35] = { {"sleep clock error in ppm"},
    {"wakeup offset in usec"},
    {"clock stabilization time in usec"},
    {"value of reserved for debug"}
    };
#endif

    ENTER();

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
    if (req == NULL) {
        LEAVE();
        return -ENOMEM;
    }

    pm = (mlan_ds_pm_cfg *) req->pbuf;
    pm->sub_command = MLAN_OID_PM_CFG_SLEEP_PARAMS;
    req->req_id = MLAN_IOCTL_PM_CFG;
    psleep_params = (pmlan_ds_sleep_params) & pm->param.sleep_params;

    if (wrq->u.data.length == 0) {
        req->action = MLAN_ACT_GET;
    } else if (wrq->u.data.length == 6) {
        if (copy_from_user(data, wrq->u.data.pointer, sizeof(int) *
                           wrq->u.data.length)) {
            /* copy_from_user failed */
            PRINTM(MERROR, "S_PARAMS: copy from user failed\n");
            return -EINVAL;
        }
#define MIN_VAL 0x0000
#define MAX_VAL 0xFFFF
        for (i = 0; i < 6; i++) {
            if ((i == 3) || (i == 4)) {
                /* These two cases are handled below the loop */
                continue;
            }
            if (data[i] < MIN_VAL || data[i] > MAX_VAL) {
                PRINTM(MERROR, "Invalid %s (0-65535)!\n", err_str[i]);
                ret = -EINVAL;
                goto done;
            }
        }
        if (data[3] < 0 || data[3] > 2) {
            PRINTM(MERROR, "Invalid control periodic calibration (0-2)!\n");
            ret = -EINVAL;
            goto done;
        }
        if (data[4] < 0 || data[4] > 2) {
            PRINTM(MERROR, "Invalid control of external sleep clock (0-2)!\n");
            ret = -EINVAL;
            goto done;
        }
        req->action = MLAN_ACT_SET;
        psleep_params->error = data[0];
        psleep_params->offset = data[1];
        psleep_params->stable_time = data[2];
        psleep_params->cal_control = data[3];
        psleep_params->ext_sleep_clk = data[4];
        psleep_params->reserved = data[5];
    } else {
        ret = -EINVAL;
        goto done;
    }

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

    data[0] = psleep_params->error;
    data[1] = psleep_params->offset;
    data[2] = psleep_params->stable_time;
    data[3] = psleep_params->cal_control;
    data[4] = psleep_params->ext_sleep_clk;
    data[5] = psleep_params->reserved;
    wrq->u.data.length = 6;

    if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) *
                     wrq->u.data.length)) {
        PRINTM(MERROR, "QCONFIG: copy to user failed\n");
        ret = -EFAULT;
        goto done;
    }

  done:
    if (req)
        kfree(req);

    LEAVE();
    return ret;
}

#ifdef REASSOCIATION
/**
 * @brief Set/Get reassociation settings
 * 
 * @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_reassoc(moal_private * priv, struct iwreq *wrq)
{
    moal_handle *handle = priv->phandle;
    int ret = 0;
    int data = 0;

    ENTER();

    if (wrq->u.data.length) {
        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        if (data == 0) {
            handle->reassoc_on = MFALSE;
            if (handle->is_reassoc_timer_set == MTRUE) {
                woal_cancel_timer(&handle->reassoc_timer);
                handle->is_reassoc_timer_set = MFALSE;
            }
        } else
            handle->reassoc_on = MTRUE;
    } else {
        data = (int) handle->reassoc_on;
        if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
            ret = -EFAULT;
            goto done;
        }
        wrq->u.data.length = 1;
    }

  done:
    LEAVE();
    return ret;
}
#endif /* REASSOCIATION */

/**
 *  @brief implement WMM enable command
 *
 *  @param priv     Pointer to the moal_private driver data struct
 *  @param wrq      Pointer to user data
 *
 *  @return          0 --success, otherwise fail
 */
static int
woal_wmm_enable_ioctl(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_ds_wmm_cfg *wmm = NULL;
    mlan_ioctl_req *req = NULL;
    int data = 0;

    ENTER();

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    wmm = (mlan_ds_wmm_cfg *) req->pbuf;
    req->req_id = MLAN_IOCTL_WMM_CFG;
    wmm->sub_command = MLAN_OID_WMM_CFG_ENABLE;

    if (wrq->u.data.length) {
        /* Set WMM configuration */
        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        if ((data < CMD_DISABLED) || (data > CMD_ENABLED)) {
            ret = -EINVAL;
            goto done;
        }
        req->action = MLAN_ACT_SET;
        if (data == CMD_DISABLED)
            wmm->param.wmm_enable = MFALSE;
        else
            wmm->param.wmm_enable = MTRUE;
    } else {
        /* Get WMM status */
        req->action = MLAN_ACT_GET;
    }

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

    if (wrq->u.data.pointer) {
        if (copy_to_user
            (wrq->u.data.pointer, &wmm->param.wmm_enable,
             sizeof(wmm->param.wmm_enable))) {
            PRINTM(MERROR, "Copy to user failed\n");
            ret = -EFAULT;
            goto done;
        }
        wrq->u.data.length = 1;
    }
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Implement 802.11D enable command
 *
 *  @param priv     Pointer to the moal_private driver data struct
 *  @param wrq      Pointer to user data
 *
 *  @return         0 --success, otherwise fail
 */
static int
woal_11d_enable_ioctl(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_ds_11d_cfg *pcfg_11d = NULL;
    mlan_ioctl_req *req = NULL;
    int data = 0;

    ENTER();

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11d_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    pcfg_11d = (mlan_ds_11d_cfg *) req->pbuf;
    req->req_id = MLAN_IOCTL_11D_CFG;
    pcfg_11d->sub_command = MLAN_OID_11D_CFG_ENABLE;
    if (wrq->u.data.length) {
        /* Set 11D configuration */
        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        if ((data < CMD_DISABLED) || (data > CMD_ENABLED)) {
            ret = -EINVAL;
            goto done;
        }
        if (data == CMD_DISABLED)
            pcfg_11d->param.enable_11d = MFALSE;
        else
            pcfg_11d->param.enable_11d = MTRUE;
        req->action = MLAN_ACT_SET;
    } else {
        req->action = MLAN_ACT_GET;
    }

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

    if (wrq->u.data.pointer) {
        if (copy_to_user
            (wrq->u.data.pointer, &pcfg_11d->param.enable_11d,
             sizeof(pcfg_11d->param.enable_11d))) {
            PRINTM(MERROR, "Copy to user failed\n");
            ret = -EFAULT;
            goto done;
        }
        wrq->u.data.length = 1;
    }
  done:
    if (req)
        kfree(req);

    LEAVE();
    return ret;
}

/**
 *  @brief Control WPS Session Enable/Disable
 *
 *  @param priv     Pointer to the moal_private driver data struct
 *  @param wrq      Pointer to user data
 *
 *  @return          0 --success, otherwise fail
 */
static int
woal_wps_cfg_ioctl(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_ds_wps_cfg *pwps = NULL;
    mlan_ioctl_req *req = NULL;
    char buf[8];
    struct iwreq *wreq = (struct iwreq *) wrq;

    ENTER();

    PRINTM(MINFO, "WOAL_WPS_SESSION\n");

    memset(buf, 0, sizeof(buf));
    if (copy_from_user(buf, wreq->u.data.pointer,
                       MIN(sizeof(buf) - 1, wreq->u.data.length))) {
        PRINTM(MERROR, "Copy from user failed\n");
        ret = -EFAULT;
        goto done;
    }

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wps_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    pwps = (mlan_ds_wps_cfg *) req->pbuf;
    req->req_id = MLAN_IOCTL_WPS_CFG;
    req->action = MLAN_ACT_SET;
    pwps->sub_command = MLAN_OID_WPS_CFG_SESSION;
    if (buf[0] == 1)
        pwps->param.wps_session = MLAN_WPS_CFG_SESSION_START;
    else
        pwps->param.wps_session = MLAN_WPS_CFG_SESSION_END;

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/** 
 *  @brief Convert ascii string to Hex integer
 *     
 *  @param d                    A pointer to integer buf
 *  @param s			A pointer to ascii string 
 *  @param dlen			The length o fascii string
 *
 *  @return 	   	        Number of integer  
 */
static int
woal_ascii2hex(t_u8 * d, char *s, t_u32 dlen)
{
    int i;
    t_u8 n;

    ENTER();

    memset(d, 0x00, dlen);

    for (i = 0; i < dlen * 2; i++) {
        if ((s[i] >= 48) && (s[i] <= 57))
            n = s[i] - 48;
        else if ((s[i] >= 65) && (s[i] <= 70))
            n = s[i] - 55;
        else if ((s[i] >= 97) && (s[i] <= 102))
            n = s[i] - 87;
        else
            break;
        if (!(i % 2))
            n = n * 16;
        d[i / 2] += n;
    }

    LEAVE();
    return i;
}

/** 
 *  @brief Return hex value of a give character
 *
 *  @param chr	    Character to be converted
 *
 *  @return 	    The converted chanrater if chr is a valid hex, else 0
 */
static int
woal_hexval(char chr)
{
    ENTER();

    if (chr >= '0' && chr <= '9')
        return chr - '0';
    if (chr >= 'A' && chr <= 'F')
        return chr - 'A' + 10;
    if (chr >= 'a' && chr <= 'f')
        return chr - 'a' + 10;

    LEAVE();
    return 0;
}

/**
 *  @brief Return hex value of a given ascii string
 *
 *  @param a	    String to be converted to ascii
 *
 *  @return 	    The converted chanrater if a is a valid hex, else 0
 */
static int
woal_atox(char *a)
{
    int i = 0;

    ENTER();

    while (isxdigit(*a))
        i = i * 16 + woal_hexval(*a++);

    LEAVE();
    return i;
}

/** 
 *  @brief Extension of strsep lib command. This function will also take care
 *	   escape character
 *
 *  @param s         A pointer to array of chars to process
 *  @param delim     The delimiter character to end the string
 *  @param esc       The escape character to ignore for delimiter
 *
 *  @return          Pointer to the seperated string if delim found, else NULL
 */
static char *
woal_strsep(char **s, char delim, char esc)
{
    char *se = *s, *sb;

    ENTER();

    if (!(*s) || (*se == '\0')) {
        LEAVE();
        return NULL;
    }

    for (sb = *s; *sb != '\0'; ++sb) {
        if (*sb == esc && *(sb + 1) == esc) {
            /* 
             * We get a esc + esc seq then keep the one esc
             * and chop off the other esc character
             */
            memmove(sb, sb + 1, strlen(sb));
            continue;
        }
        if (*sb == esc && *(sb + 1) == delim) {
            /* 
             * We get a delim + esc seq then keep the delim
             * and chop off the esc character
             */
            memmove(sb, sb + 1, strlen(sb));
            continue;
        }
        if (*sb == delim)
            break;
    }

    if (*sb == '\0')
        sb = NULL;
    else
        *sb++ = '\0';

    *s = sb;

    LEAVE();
    return se;
}

/**
 *  @brief Convert mac address from string to t_u8 buffer.
 *
 *  @param mac_addr The buffer to store the mac address in.	    
 *  @param buf      The source of mac address which is a string.	    
 *
 *  @return 	    N/A
 */
static void
woal_mac2u8(t_u8 * mac_addr, char *buf)
{
    char *begin = buf, *end;
    int i;

    ENTER();

    for (i = 0; i < ETH_ALEN; ++i) {
        end = woal_strsep(&begin, ':', '/');
        if (end)
            mac_addr[i] = woal_atox(end);
    }

    LEAVE();
}

/**
 *  @brief Set WPA passphrase and SSID
 *
 *  @param priv	    A pointer to moal_private structure
 *  @param wrq	    A pointer to user data
 *
 *  @return          0 --success, otherwise fail
 */
static int
woal_passphrase(moal_private * priv, struct iwreq *wrq)
{
    t_u16 len = 0;
    static char buf[256];
    char *begin, *end, *opt;
    int ret = 0, action = -1, i;
    mlan_ds_sec_cfg *sec = NULL;
    mlan_ioctl_req *req = NULL;
    t_u8 zero_mac[] = { 0, 0, 0, 0, 0, 0 };
    t_u8 *mac = NULL;

    ENTER();

    if (!wrq->u.data.length) {
        PRINTM(MERROR, "Argument missing for setpassphrase\n");
        ret = -EINVAL;
        goto done;
    }

    if (copy_from_user(buf, wrq->u.data.pointer, wrq->u.data.length)) {
        PRINTM(MERROR, "Copy from user failed\n");
        ret = -EFAULT;
        goto done;
    }
    buf[wrq->u.data.length] = '\0';

    if (wrq->u.data.length <= 1) {
        PRINTM(MERROR, "No valid arguments\n");
        ret = -EINVAL;
        goto done;
    }
    /* Parse the buf to get the cmd_action */
    begin = buf;
    end = woal_strsep(&begin, ';', '/');
    if (end)
        action = woal_atox(end);
    if (action < 0 || action > 2 || end[1] != '\0') {
        PRINTM(MERROR, "Invalid action argument %s\n", end);
        ret = -EINVAL;
        goto done;
    }
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    sec = (mlan_ds_sec_cfg *) req->pbuf;
    sec->sub_command = MLAN_OID_SEC_CFG_PASSPHRASE;
    req->req_id = MLAN_IOCTL_SEC_CFG;
    if (action == 0)
        req->action = MLAN_ACT_GET;
    else
        req->action = MLAN_ACT_SET;
    while (begin) {
        end = woal_strsep(&begin, ';', '/');
        opt = woal_strsep(&end, '=', '/');
        if (!opt || !end || !end[0]) {
            PRINTM(MERROR, "Invalid option\n");
            ret = -EINVAL;
            break;
        } else if (!strnicmp(opt, "ssid", strlen(opt))) {
            if (strlen(end) > MLAN_MAX_SSID_LENGTH) {
                PRINTM(MERROR, "SSID length exceeds max length\n");
                ret = -EFAULT;
                break;
            }
            sec->param.passphrase.ssid.ssid_len = strlen(end);
            strcpy((char *) sec->param.passphrase.ssid.ssid, end);
            PRINTM(MINFO, "ssid=%s, len=%d\n", sec->param.passphrase.ssid.ssid,
                   (int) sec->param.passphrase.ssid.ssid_len);
        } else if (!strnicmp(opt, "bssid", strlen(opt))) {
            woal_mac2u8((t_u8 *) & sec->param.passphrase.bssid, end);
        } else if (!strnicmp(opt, "psk", strlen(opt)) &&
                   req->action == MLAN_ACT_SET) {
            if (strlen(end) != (MLAN_MAX_PMK_LENGTH * 2)) {
                PRINTM(MERROR, "Invalid PMK length\n");
                ret = -EINVAL;
                break;
            }
            woal_ascii2hex(sec->param.passphrase.psk.pmk.pmk, end,
                           MLAN_MAX_PMK_LENGTH * 2);
            sec->param.passphrase.psk_type = MLAN_PSK_PMK;
        } else if (!strnicmp(opt, "passphrase", strlen(opt)) &&
                   req->action == MLAN_ACT_SET) {
            if (strlen(end) < MLAN_MIN_PASSPHRASE_LENGTH ||
                strlen(end) > MLAN_MAX_PASSPHRASE_LENGTH) {
                PRINTM(MERROR, "Invalid length for passphrase\n");
                ret = -EINVAL;
                break;
            }
            sec->param.passphrase.psk_type = MLAN_PSK_PASSPHRASE;
            strcpy(sec->param.passphrase.psk.passphrase.passphrase, end);
            sec->param.passphrase.psk.passphrase.passphrase_len = strlen(end);
            PRINTM(MINFO, "passphrase=%s, len=%d\n",
                   sec->param.passphrase.psk.passphrase.passphrase,
                   (int) sec->param.passphrase.psk.passphrase.passphrase_len);
        } else {
            PRINTM(MERROR, "Invalid option %s\n", opt);
            ret = -EINVAL;
            break;
        }
    }
    if (ret)
        goto done;

    if (action == 2)
        sec->param.passphrase.psk_type = MLAN_PSK_CLEAR;
    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }
    if (action == 0) {
        memset(buf, 0, sizeof(buf));
        if (sec->param.passphrase.ssid.ssid_len) {
            len += sprintf(buf + len, "ssid:");
            memcpy(buf + len, sec->param.passphrase.ssid.ssid,
                   sec->param.passphrase.ssid.ssid_len);
            len += sec->param.passphrase.ssid.ssid_len;
            len += sprintf(buf + len, " ");
        }
        if (memcmp(&sec->param.passphrase.bssid, zero_mac, sizeof(zero_mac))) {
            mac = (t_u8 *) & sec->param.passphrase.bssid;
            len += sprintf(buf + len, "bssid:");
            for (i = 0; i < ETH_ALEN - 1; ++i)
                len += sprintf(buf + len, "%02x:", mac[i]);
            len += sprintf(buf + len, "%02x ", mac[i]);
        }
        if (sec->param.passphrase.psk_type == MLAN_PSK_PMK) {
            len += sprintf(buf + len, "psk:");
            for (i = 0; i < MLAN_MAX_PMK_LENGTH; ++i)
                len +=
                    sprintf(buf + len, "%02x",
                            sec->param.passphrase.psk.pmk.pmk[i]);
            len += sprintf(buf + len, "\n");
        }
        if (sec->param.passphrase.psk_type == MLAN_PSK_PASSPHRASE) {
            len +=
                sprintf(buf + len, "passphrase:%s \n",
                        sec->param.passphrase.psk.passphrase.passphrase);
        }
        if (wrq->u.data.pointer) {
            if (copy_to_user(wrq->u.data.pointer, buf, len)) {
                PRINTM(MERROR, "Copy to user failed, len %d\n", len);
                ret = -EFAULT;
                goto done;
            }
            wrq->u.data.length = len;
        }

    }
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Get esupp mode
 *  
 *  @param priv     A pointer to moal_private structure
 *  @param wrq      A pointer to iwreq structure
 *  
 *  @return         0 --success, otherwise fail
 */
static int
woal_get_esupp_mode(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_ds_sec_cfg *sec = NULL;
    mlan_ioctl_req *req = NULL;

    ENTER();

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    sec = (mlan_ds_sec_cfg *) req->pbuf;
    sec->sub_command = MLAN_OID_SEC_CFG_ESUPP_MODE;
    req->req_id = MLAN_IOCTL_SEC_CFG;
    req->action = MLAN_ACT_GET;

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

    if (copy_to_user
        (wrq->u.data.pointer, (t_u8 *) & sec->param.esupp_mode,
         sizeof(int) * 3)) {
        ret = -EFAULT;
        goto done;
    }
    wrq->u.data.length = 3;
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/** AES key length */
#define AES_KEY_LEN 16
/**
 *  @brief Adhoc AES control 
 *
 *  @param priv	    A pointer to moal_private structure
 *  @param wrq	    A pointer to user data
 *
 *  @return 	    0 --success, otherwise fail
 */
static int
woal_adhoc_aes_ioctl(moal_private * priv, struct iwreq *wrq)
{
    static char buf[256];
    int ret = 0, action = -1, i;
    t_u8 key_ascii[32];
    t_u8 key_hex[16];
    t_u8 *tmp;
    mlan_bss_info bss_info;
    mlan_ds_sec_cfg *sec = NULL;
    mlan_ioctl_req *req = NULL;

    ENTER();

    memset(key_ascii, 0x00, sizeof(key_ascii));
    memset(key_hex, 0x00, sizeof(key_hex));

    /* Get current BSS information */
    memset(&bss_info, 0, sizeof(bss_info));
    woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);
    if (bss_info.bss_mode != MLAN_BSS_MODE_IBSS ||
        bss_info.media_connected == MTRUE) {
        PRINTM(MERROR, "STA is connected or not in IBSS mode.\n");
        ret = -EOPNOTSUPP;
        goto done;
    }

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    if (wrq->u.data.length) {
        if (copy_from_user(buf, wrq->u.data.pointer, wrq->u.data.length)) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        buf[wrq->u.data.length] = '\0';

        if (wrq->u.data.length == 1) {
            /* Get Adhoc AES Key */
            req->req_id = MLAN_IOCTL_SEC_CFG;
            req->action = MLAN_ACT_GET;
            sec = (mlan_ds_sec_cfg *) req->pbuf;
            sec->sub_command = MLAN_OID_SEC_CFG_ENCRYPT_KEY;
            sec->param.encrypt_key.key_len = AES_KEY_LEN;
            sec->param.encrypt_key.key_index = 0x40000000;
            if (MLAN_STATUS_SUCCESS !=
                woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
                ret = -EFAULT;
                goto done;
            }

            memcpy(key_hex, sec->param.encrypt_key.key_material,
                   sizeof(key_hex));
            HEXDUMP("Adhoc AES Key (HEX)", key_hex, sizeof(key_hex));

            wrq->u.data.length = sizeof(key_ascii) + 1;

            tmp = key_ascii;
            for (i = 0; i < sizeof(key_hex); i++)
                tmp += sprintf((char *) tmp, "%02x", key_hex[i]);
        } else if (wrq->u.data.length >= 2) {
            /* Parse the buf to get the cmd_action */
            action = woal_atox(&buf[0]);
            if (action < 1 || action > 2) {
                PRINTM(MERROR, "Invalid action argument %d\n", action);
                ret = -EINVAL;
                goto done;
            }

            req->req_id = MLAN_IOCTL_SEC_CFG;
            req->action = MLAN_ACT_SET;
            sec = (mlan_ds_sec_cfg *) req->pbuf;
            sec->sub_command = MLAN_OID_SEC_CFG_ENCRYPT_KEY;

            if (action == 1) {
                /* Set Adhoc AES Key */
                memcpy(key_ascii, &buf[2], sizeof(key_ascii));
                woal_ascii2hex(key_hex, (char *) key_ascii, sizeof(key_hex));
                HEXDUMP("Adhoc AES Key (HEX)", key_hex, sizeof(key_hex));

                sec->param.encrypt_key.key_len = AES_KEY_LEN;
                sec->param.encrypt_key.key_index = 0x40000000;
                memcpy(sec->param.encrypt_key.key_material,
                       key_hex, sec->param.encrypt_key.key_len);

                if (MLAN_STATUS_SUCCESS !=
                    woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
                    ret = -EFAULT;
                    goto done;
                }
            } else if (action == 2) {
                /* Clear Adhoc AES Key */
                sec->param.encrypt_key.key_len = AES_KEY_LEN;
                sec->param.encrypt_key.key_index = 0x40000000;
                memset(sec->param.encrypt_key.key_material, 0,
                       sizeof(sec->param.encrypt_key.key_material));

                if (MLAN_STATUS_SUCCESS !=
                    woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
                    ret = -EFAULT;
                    goto done;
                }
            } else {
                PRINTM(MERROR, "Invalid argument\n");
                ret = -EINVAL;
                goto done;
            }
        }

        HEXDUMP("Adhoc AES Key (ASCII)", key_ascii, sizeof(key_ascii));
        wrq->u.data.length = sizeof(key_ascii);
        if (wrq->u.data.pointer) {
            if (copy_to_user(wrq->u.data.pointer, &key_ascii,
                             sizeof(key_ascii))) {
                PRINTM(MERROR, "copy_to_user failed\n");
                ret = -EFAULT;
                goto done;
            }
        }
    }

  done:
    if (req)
        kfree(req);

    LEAVE();
    return ret;
}

#ifdef MFG_CMD_SUPPORT
/** 
 *  @brief Manufacturing command ioctl function
 *   
 *  @param priv		A pointer to moal_private structure
 *  @param wrq 		A pointer to iwreq structure
 *  @return    		0 --success, otherwise fail
 */
static int
woal_mfg_command(moal_private * priv, struct iwreq *wrq)
{
    HostCmd_Header cmd_header;
    int ret = 0;
    mlan_ds_misc_cfg *misc = NULL;
    mlan_ioctl_req *req = NULL;

    ENTER();

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    misc = (mlan_ds_misc_cfg *) req->pbuf;
    memset(&cmd_header, 0, sizeof(cmd_header));

    /* get MFG command header */
    if (copy_from_user
        (&cmd_header, wrq->u.data.pointer, sizeof(HostCmd_Header))) {
        PRINTM(MERROR, "copy from user failed: MFG command header\n");
        ret = -EFAULT;
        goto done;
    }
    misc->param.mfgcmd.len = cmd_header.size;

    PRINTM(MINFO, "MFG command len = %lu\n", misc->param.mfgcmd.len);

    if (cmd_header.size > MLAN_SIZE_OF_CMD_BUFFER) {
        ret = -EINVAL;
        goto done;
    }

    /* get the whole command from user */
    if (copy_from_user
        (misc->param.mfgcmd.cmd, wrq->u.data.pointer, cmd_header.size)) {
        PRINTM(MERROR, "copy from user failed: MFG command\n");
        ret = -EFAULT;
        goto done;
    }
    misc->sub_command = MLAN_OID_MISC_MFG_CMD;
    req->req_id = MLAN_IOCTL_MISC_CFG;
    req->action = MLAN_ACT_SET;

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }
    if (copy_to_user
        (wrq->u.data.pointer, (t_u8 *) misc->param.mfgcmd.cmd,
         MIN(cmd_header.size, misc->param.mfgcmd.len))) {
        ret = -EFAULT;
        goto done;
    }
    wrq->u.data.length = MIN(cmd_header.size, misc->param.mfgcmd.len);
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}
#endif /* MFG_CMD_SUPPORT */

/** 
 *  @brief host command ioctl function
 *   
 *  @param priv		A pointer to moal_private structure
 *  @param wrq 		A pointer to iwreq structure
 *  @return    		0 --success, otherwise fail
 */
static int
woal_host_command(moal_private * priv, struct iwreq *wrq)
{
    HostCmd_Header cmd_header;
    int ret = 0;
    mlan_ds_misc_cfg *misc = NULL;
    mlan_ioctl_req *req = NULL;

    ENTER();

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    misc = (mlan_ds_misc_cfg *) req->pbuf;
    memset(&cmd_header, 0, sizeof(cmd_header));

    /* get command header */
    if (copy_from_user
        (&cmd_header, wrq->u.data.pointer, sizeof(HostCmd_Header))) {
        PRINTM(MERROR, "copy from user failed: Host command header\n");
        ret = -EFAULT;
        goto done;
    }
    misc->param.hostcmd.len = woal_le16_to_cpu(cmd_header.size);

    PRINTM(MINFO, "Host command len = %lu\n", misc->param.hostcmd.len);

    if (woal_le16_to_cpu(cmd_header.size) > MLAN_SIZE_OF_CMD_BUFFER) {
        ret = -EINVAL;
        goto done;
    }

    /* get the whole command from user */
    if (copy_from_user
        (misc->param.hostcmd.cmd, wrq->u.data.pointer,
         woal_le16_to_cpu(cmd_header.size))) {
        PRINTM(MERROR, "copy from user failed\n");
        ret = -EFAULT;
        goto done;
    }
    misc->sub_command = MLAN_OID_MISC_HOST_CMD;
    req->req_id = MLAN_IOCTL_MISC_CFG;

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }
    if (copy_to_user
        (wrq->u.data.pointer, (t_u8 *) misc->param.hostcmd.cmd,
         misc->param.hostcmd.len)) {
        ret = -EFAULT;
        goto done;
    }
    wrq->u.data.length = misc->param.hostcmd.len;
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/** 
 *  @brief arpfilter ioctl function
 *   
 *  @param priv		A pointer to moal_private structure
 *  @param wrq 		A pointer to iwreq structure
 *  @return    		0 --success, otherwise fail
 */
static int
woal_arp_filter(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_ds_misc_cfg *misc = NULL;
    mlan_ioctl_req *req = NULL;

    ENTER();

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    misc = (mlan_ds_misc_cfg *) req->pbuf;
    misc->sub_command = MLAN_OID_MISC_GEN_IE;
    req->req_id = MLAN_IOCTL_MISC_CFG;
    req->action = MLAN_ACT_SET;
    misc->param.gen_ie.type = MLAN_IE_TYPE_ARP_FILTER;
    misc->param.gen_ie.len = wrq->u.data.length;

    /* get the whole command from user */
    if (copy_from_user
        (misc->param.gen_ie.ie_data, wrq->u.data.pointer, wrq->u.data.length)) {
        PRINTM(MERROR, "copy from user failed\n");
        ret = -EFAULT;
        goto done;
    }

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Create a brief scan resp to relay basic BSS info to the app layer
 *
 *  When the beacon/probe response has not been buffered, use the saved BSS
 *    information available to provide a minimum response for the application
 *    ioctl retrieval routines.  Include:
 *        - Timestamp
 *        - Beacon Period
 *        - Capabilities (including WMM Element if available)
 *        - SSID
 *
 *  @param ppbuffer  Output parameter: Buffer used to create basic scan rsp
 *  @param pbss_desc Pointer to a BSS entry in the scan table to create
 *                   scan response from for delivery to the application layer
 *
 *  @return          void
 */
static void
wlan_scan_create_brief_table_entry(t_u8 ** ppbuffer,
                                   BSSDescriptor_t * pbss_desc)
{
    t_u8 *ptmp_buf = *ppbuffer;
    t_u8 tmp_ssid_hdr[2];
    t_u8 ie_len = 0;

    if (copy_to_user(ptmp_buf, pbss_desc->time_stamp,
                     sizeof(pbss_desc->time_stamp))) {
        PRINTM(MINFO, "Copy to user failed\n");
        return;
    }
    ptmp_buf += sizeof(pbss_desc->time_stamp);

    if (copy_to_user(ptmp_buf, &pbss_desc->beacon_period,
                     sizeof(pbss_desc->beacon_period))) {
        PRINTM(MINFO, "Copy to user failed\n");
        return;
    }
    ptmp_buf += sizeof(pbss_desc->beacon_period);

    if (copy_to_user
        (ptmp_buf, &pbss_desc->cap_info, sizeof(pbss_desc->cap_info))) {
        PRINTM(MINFO, "Copy to user failed\n");
        return;
    }
    ptmp_buf += sizeof(pbss_desc->cap_info);

    tmp_ssid_hdr[0] = 0;        /* Element ID for SSID is zero */
    tmp_ssid_hdr[1] = pbss_desc->ssid.ssid_len;
    if (copy_to_user(ptmp_buf, tmp_ssid_hdr, sizeof(tmp_ssid_hdr))) {
        PRINTM(MINFO, "Copy to user failed\n");
        return;
    }
    ptmp_buf += sizeof(tmp_ssid_hdr);

    if (copy_to_user(ptmp_buf, pbss_desc->ssid.ssid, pbss_desc->ssid.ssid_len)) {
        PRINTM(MINFO, "Copy to user failed\n");
        return;
    }
    ptmp_buf += pbss_desc->ssid.ssid_len;

    if (pbss_desc->wmm_ie.vend_hdr.element_id == WMM_IE) {
        ie_len = sizeof(IEEEtypes_Header_t) + pbss_desc->wmm_ie.vend_hdr.len;
        if (copy_to_user(ptmp_buf, &pbss_desc->wmm_ie, ie_len)) {
            PRINTM(MINFO, "Copy to user failed\n");
            return;
        }

        ptmp_buf += ie_len;
    }

    if (pbss_desc->pwpa_ie) {
        if ((*(pbss_desc->pwpa_ie)).vend_hdr.element_id == WPA_IE) {
            ie_len =
                sizeof(IEEEtypes_Header_t) +
                (*(pbss_desc->pwpa_ie)).vend_hdr.len;
            if (copy_to_user(ptmp_buf, pbss_desc->pwpa_ie, ie_len)) {
                PRINTM(MINFO, "Copy to user failed\n");
                return;
            }
        }

        ptmp_buf += ie_len;
    }

    if (pbss_desc->prsn_ie) {
        if ((*(pbss_desc->prsn_ie)).ieee_hdr.element_id == RSN_IE) {
            ie_len =
                sizeof(IEEEtypes_Header_t) +
                (*(pbss_desc->prsn_ie)).ieee_hdr.len;
            if (copy_to_user(ptmp_buf, pbss_desc->prsn_ie, ie_len)) {
                PRINTM(MINFO, "Copy to user failed\n");
                return;
            }
        }

        ptmp_buf += ie_len;
    }

    *ppbuffer = ptmp_buf;
}

/** 
 *  @brief Create a wlan_ioctl_get_scan_table_entry for a given BSS 
 *         Descriptor for inclusion in the ioctl response to the user space
 *         application.
 *
 *
 *  @param pbss_desc   Pointer to a BSS entry in the scan table to form
 *                     scan response from for delivery to the application layer
 *  @param ppbuffer    Output parameter: Buffer used to output scan return struct
 *  @param pspace_left Output parameter: Number of bytes available in the 
 *                     response buffer.
 *
 *  @return MLAN_STATUS_SUCCESS, or < 0 with IOCTL error code
 */
static int
wlan_get_scan_table_ret_entry(BSSDescriptor_t * pbss_desc,
                              t_u8 ** ppbuffer, int *pspace_left)
{
    wlan_ioctl_get_scan_table_entry *prsp_entry;
    wlan_ioctl_get_scan_table_entry tmp_rsp_entry;
    int space_needed;
    t_u8 *pcurrent;
    int variable_size;

    const int fixed_size = (sizeof(tmp_rsp_entry.fixed_field_length)
                            + sizeof(tmp_rsp_entry.fixed_fields)
                            + sizeof(tmp_rsp_entry.bss_info_length));

    ENTER();

    pcurrent = *ppbuffer;

    /* The variable size returned is the stored beacon size */
    variable_size = pbss_desc->beacon_buf_size;

    /* If we stored a beacon and its size was zero, set the variable size
       return value to the size of the brief scan response
       wlan_scan_create_brief_table_entry creates.  Also used if we are not
       configured to store beacons in the first place */
    if (!variable_size) {
        variable_size = pbss_desc->ssid.ssid_len + 2;
        variable_size += (sizeof(pbss_desc->beacon_period)
                          + sizeof(pbss_desc->time_stamp)
                          + sizeof(pbss_desc->cap_info));
        if (pbss_desc->wmm_ie.vend_hdr.element_id == WMM_IE) {
            variable_size += (sizeof(IEEEtypes_Header_t)
                              + pbss_desc->wmm_ie.vend_hdr.len);
        }

        if (pbss_desc->pwpa_ie) {
            if ((*(pbss_desc->pwpa_ie)).vend_hdr.element_id == WPA_IE) {
                variable_size += (sizeof(IEEEtypes_Header_t)
                                  + (*(pbss_desc->pwpa_ie)).vend_hdr.len);
            }
        }

        if (pbss_desc->prsn_ie) {
            if ((*(pbss_desc->prsn_ie)).ieee_hdr.element_id == RSN_IE) {
                variable_size += (sizeof(IEEEtypes_Header_t)
                                  + (*(pbss_desc->prsn_ie)).ieee_hdr.len);
            }
        }
    }

    space_needed = fixed_size + variable_size;

    PRINTM(MINFO, "GetScanTable: need(%d), left(%d)\n",
           space_needed, *pspace_left);

    if (space_needed >= *pspace_left) {
        *pspace_left = 0;
        LEAVE();
        return -E2BIG;
    }

    *pspace_left -= space_needed;

    tmp_rsp_entry.fixed_field_length = sizeof(prsp_entry->fixed_fields);

    memcpy(tmp_rsp_entry.fixed_fields.bssid,
           pbss_desc->mac_address, sizeof(prsp_entry->fixed_fields.bssid));

    tmp_rsp_entry.fixed_fields.rssi = pbss_desc->rssi;
    tmp_rsp_entry.fixed_fields.channel = pbss_desc->channel;
    tmp_rsp_entry.fixed_fields.network_tsf = pbss_desc->network_tsf;
    tmp_rsp_entry.bss_info_length = variable_size;

    /* 
     *  Copy fixed fields to user space
     */
    if (copy_to_user(pcurrent, &tmp_rsp_entry, fixed_size)) {
        PRINTM(MINFO, "Copy to user failed\n");
        LEAVE();
        return -EFAULT;
    }

    pcurrent += fixed_size;

    if (pbss_desc->pbeacon_buf) {
        /* 
         *  Copy variable length elements to user space
         */
        if (copy_to_user(pcurrent, pbss_desc->pbeacon_buf,
                         pbss_desc->beacon_buf_size)) {
            PRINTM(MINFO, "Copy to user failed\n");
            LEAVE();
            return -EFAULT;
        }

        pcurrent += pbss_desc->beacon_buf_size;
    } else {
        wlan_scan_create_brief_table_entry(&pcurrent, pbss_desc);
    }

    *ppbuffer = pcurrent;

    LEAVE();

    return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief Retrieve the scan response/beacon table
 *
 *  @param wrq          A pointer to iwreq structure
 *  @param scan_resp    A pointer to mlan_scan_resp structure
 *  @param scan_start   argument
 *
 *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static int
moal_ret_get_scan_table_ioctl(struct iwreq *wrq, mlan_scan_resp * scan_resp,
                              t_u32 scan_start)
{
    pBSSDescriptor_t pbss_desc, scan_table;
    mlan_scan_resp *prsp_info;
    int ret_code;
    int ret_len;
    int space_left;
    t_u8 *pcurrent;
    t_u8 *pbuffer_end;
    t_u32 num_scans_done;

    ENTER();

    num_scans_done = 0;
    ret_code = MLAN_STATUS_SUCCESS;

    prsp_info = (mlan_scan_resp *) wrq->u.data.pointer;
    prsp_info->pscan_table =
        (t_u8 *) prsp_info + sizeof(prsp_info->num_in_scan_table);
    pcurrent = prsp_info->pscan_table;

    pbuffer_end = wrq->u.data.pointer + wrq->u.data.length - 1;
    space_left = pbuffer_end - pcurrent;
    scan_table = (BSSDescriptor_t *) (scan_resp->pscan_table);

    PRINTM(MINFO, "GetScanTable: scan_start req = %ld\n", scan_start);
    PRINTM(MINFO, "GetScanTable: length avail = %d\n", wrq->u.data.length);

    if (!scan_start) {
        PRINTM(MINFO, "GetScanTable: get current BSS Descriptor\n");

        /* Use to get current association saved descriptor */
        pbss_desc = scan_table;

        ret_code = wlan_get_scan_table_ret_entry(pbss_desc,
                                                 &pcurrent, &space_left);

        if (ret_code == MLAN_STATUS_SUCCESS) {
            num_scans_done = 1;
        }
    } else {
        scan_start--;

        while (space_left
               && (scan_start + num_scans_done < scan_resp->num_in_scan_table)
               && (ret_code == MLAN_STATUS_SUCCESS)) {

            pbss_desc = (scan_table + (scan_start + num_scans_done));

            PRINTM(MINFO, "GetScanTable: get current BSS Descriptor [%ld]\n",
                   scan_start + num_scans_done);

            ret_code = wlan_get_scan_table_ret_entry(pbss_desc,
                                                     &pcurrent, &space_left);

            if (ret_code == MLAN_STATUS_SUCCESS) {
                num_scans_done++;
            }
        }
    }

    prsp_info->num_in_scan_table = num_scans_done;
    ret_len = pcurrent - (t_u8 *) wrq->u.data.pointer;

    wrq->u.data.length = ret_len;

    /* Return ret_code (EFAULT or E2BIG) in the case where no scan results were 
       successfully encoded. */
    LEAVE();
    return (num_scans_done ? MLAN_STATUS_SUCCESS : ret_code);
}

/** 
 *  @brief Get scan table ioctl
 *
 *  @param priv     A pointer to moal_private structure
 *  @param wrq 		A pointer to iwreq structure
 *
 *  @return         MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
static mlan_status
woal_get_scan_table_ioctl(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_scan *scan = NULL;
    t_u32 scan_start;
    mlan_status status = MLAN_STATUS_SUCCESS;

    ENTER();

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_scan));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    /* Fill request buffer */
    scan = (mlan_ds_scan *) req->pbuf;
    req->req_id = MLAN_IOCTL_SCAN;
    req->action = MLAN_ACT_GET;

    /* get the whole command from user */
    if (copy_from_user(&scan_start, wrq->u.data.pointer, sizeof(scan_start))) {
        PRINTM(MERROR, "copy from user failed\n");
        ret = -EFAULT;
        goto done;
    }
    if (scan_start) {
        scan->sub_command = MLAN_OID_SCAN_NORMAL;
    } else {
        scan->sub_command = MLAN_OID_SCAN_SPECIFIC_SSID;
    }
    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
    if (status == MLAN_STATUS_SUCCESS) {
        status = moal_ret_get_scan_table_ioctl(wrq,
                                               &scan->param.scan_resp,
                                               scan_start);
    }
  done:
    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);
    LEAVE();
    return status;
}

/** 
 *  @brief Set user scan
 *
 *  @param priv     A pointer to moal_private structure
 *  @param wrq 		A pointer to iwreq structure
 *
 *  @return         MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
static mlan_status
woal_set_user_scan_ioctl(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_scan *scan = NULL;
    union iwreq_data wrqu;
    mlan_status status = MLAN_STATUS_SUCCESS;

    ENTER();

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_scan) + wrq->u.data.length);
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    /* Fill request buffer */
    scan = (mlan_ds_scan *) req->pbuf;
    scan->sub_command = MLAN_OID_SCAN_USER_CONFIG;
    req->req_id = MLAN_IOCTL_SCAN;
    req->action = MLAN_ACT_SET;

    if (copy_from_user(scan->param.user_scan.scan_cfg_buf,
                       wrq->u.data.pointer, wrq->u.data.length)) {
        PRINTM(MINFO, "Copy from user failed\n");
        LEAVE();
        return -EFAULT;
    }

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
    if (status == MLAN_STATUS_SUCCESS) {
        memset(&wrqu, 0, sizeof(union iwreq_data));
        wireless_send_event(priv->netdev, SIOCGIWSCAN, &wrqu, NULL);
    } else {
    }

  done:
    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);
    LEAVE();
    return status;
}

/** 
 *  @brief Cmd52 read/write register
 *   
 *  @param priv         A pointer to moal_private structure
 *  @param wrq          A pointer to iwreq structure
 *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static int
woal_cmd52rdwr_ioctl(moal_private * priv, struct iwreq *wrq)
{
    t_u8 buf[7];
    t_u8 rw, func, data = 0;
    int reg, ret = MLAN_STATUS_SUCCESS;

    ENTER();

    if (copy_from_user(buf, wrq->u.data.pointer,
                       MIN(wrq->u.data.length, sizeof(buf)))) {
        PRINTM(MINFO, "Copy from user failed\n");
        ret = -EFAULT;
        goto done;
    }

    rw = buf[0];
    func = buf[1];
    reg = buf[5];
    reg = (reg << 8) + buf[4];
    reg = (reg << 8) + buf[3];
    reg = (reg << 8) + buf[2];
    if (rw)
        data = buf[6];

    PRINTM(MINFO, "rw=%d, func=%d, reg=0x%08X, data=0x%02X\n", rw, func, reg,
           data);

    if (!rw) {
        sdio_claim_host(((struct sdio_mmc_card *) priv->phandle->card)->func);
        data =
            sdio_readb(((struct sdio_mmc_card *) priv->phandle->card)->func,
                       reg, &ret);
        sdio_release_host(((struct sdio_mmc_card *) priv->phandle->card)->func);
        if (ret) {
            PRINTM(MERROR, "sdio_readb: reading register 0x%X failed\n", reg);
            goto done;
        }
    } else {
        sdio_claim_host(((struct sdio_mmc_card *) priv->phandle->card)->func);
        sdio_writeb(((struct sdio_mmc_card *) priv->phandle->card)->func, data,
                    reg, &ret);
        sdio_release_host(((struct sdio_mmc_card *) priv->phandle->card)->func);
        if (ret) {
            PRINTM(MERROR, "sdio_writeb: writing register 0x%X failed\n", reg);
            goto done;
        }
    }

    if (copy_to_user(wrq->u.data.pointer, &data, sizeof(data))) {
        PRINTM(MINFO, "Copy to user failed\n");
        ret = -EFAULT;
        goto done;
    }

  done:
    LEAVE();
    return ret;
}

/** 
 *  @brief Cmd53 read/write register
 *     
 *  @param priv         A pointer to moal_private structure
 *  @param wrq          A pointer to iwreq structure
 *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static int
woal_cmd53rdwr_ioctl(moal_private * priv, struct iwreq *wrq)
{
    t_u8 *buf = NULL;
    t_u8 rw, func, mode;
    t_u16 blklen = 0, blknum = 0;
    int reg = 0, pattern_len = 0, total_len = 0, pos = 0, ret =
        MLAN_STATUS_SUCCESS;
    t_u8 *data = NULL;

    ENTER();

    if (!(buf = (t_u8 *) kmalloc(WOAL_2K_BYTES, GFP_ATOMIC))) {
        PRINTM(MERROR, "Cannot allocate buffer for command!\n");
        ret = -EFAULT;
        goto done;
    }
    if (!(data = (t_u8 *) kmalloc(WOAL_2K_BYTES, GFP_ATOMIC))) {
        PRINTM(MERROR, "Cannot allocate buffer for command!\n");
        ret = -EFAULT;
        goto done;
    }
    if (wrq->u.data.length > WOAL_2K_BYTES) {
        PRINTM(MERROR, "Data lengh is too large!\n");
        ret = -EINVAL;
        goto done;
    }
    if (copy_from_user(buf, wrq->u.data.pointer, wrq->u.data.length)) {
        PRINTM(MINFO, "Copy from user failed\n");
        ret = -EFAULT;
        goto done;
    }

    rw = buf[0];                /* read/write (0/1) */
    func = buf[1];              /* func (0/1/2) */
    reg = buf[5];               /* address */
    reg = (reg << 8) + buf[4];
    reg = (reg << 8) + buf[3];
    reg = (reg << 8) + buf[2];
    mode = buf[6];              /* byte mode/block mode (0/1) */
    blklen = buf[8];            /* block size */
    blklen = (blklen << 8) + buf[7];
    blknum = buf[10];           /* block number or byte number */
    blknum = (blknum << 8) + buf[9];

    if (mode != BYTE_MODE)
        mode = BLOCK_MODE;
    total_len = (mode == BLOCK_MODE) ? blknum * blklen : blknum;
    if (total_len > WOAL_2K_BYTES) {
        PRINTM(MERROR, "Total data length is too large!\n");
        ret = -EINVAL;
        goto done;
    }
    PRINTM(MINFO, "CMD53 read/write, func = %d, addr = %#x, mode = %d, "
           "block size = %d, block(byte) number = %d\n",
           func, reg, mode, blklen, blknum);

    if (!rw) {
        sdio_claim_host(((struct sdio_mmc_card *) priv->phandle->card)->func);
        if (!sdio_readsb
            (((struct sdio_mmc_card *) priv->phandle->card)->func, data, reg,
             total_len))
            PRINTM(MERROR, "sdio_readsb: reading memory 0x%x failed\n", reg);
        sdio_release_host(((struct sdio_mmc_card *) priv->phandle->card)->func);

        if (copy_to_user(wrq->u.data.pointer, data, sizeof(data))) {
            PRINTM(MINFO, "Copy to user failed\n");
            ret = -EFAULT;
            goto done;
        }
    } else {
        pattern_len = wrq->u.data.length - 11;
        if (pattern_len > total_len)
            pattern_len = total_len;
        memset(data, 0, sizeof(data));

        /* Copy/duplicate the pattern to data buffer */
        for (pos = 0; pos < total_len; pos++)
            data[pos] = buf[11 + (pos % pattern_len)];

        sdio_claim_host(((struct sdio_mmc_card *) priv->phandle->card)->func);
        if (!sdio_writesb
            (((struct sdio_mmc_card *) priv->phandle->card)->func, reg, data,
             total_len))
            PRINTM(MERROR, "sdio_writesb: writing memory 0x%x failed\n", reg);
        sdio_release_host(((struct sdio_mmc_card *) priv->phandle->card)->func);
    }

  done:
    if (buf)
        kfree(buf);
    if (data)
        kfree(data);
    LEAVE();
    return ret;
}

#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR)
/**
 * @brief Set SDIO Multi-point aggregation control parameters
 * 
 * @param priv     A pointer to moal_private structure
 * @param wrq      A pointer to iwreq structure
 * 
 * @return         0 --success, otherwise fail
 */
static int
woal_do_sdio_mpa_ctrl(moal_private * priv, struct iwreq *wrq)
{
    int data[6];
    int ret = 0;
    mlan_ds_misc_cfg *misc = NULL;
    mlan_ioctl_req *req = NULL;

    ENTER();
    PRINTM(MERROR, "mpa_ctrl: %d\n", wrq->u.data.length);

    if (wrq->u.data.length > 6) {
        PRINTM(MERROR, "Invalid number of arguments\n");
        ret = -EINVAL;
        goto done;
    }

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    misc = (mlan_ds_misc_cfg *) req->pbuf;
    memset(misc, 0, sizeof(mlan_ds_misc_cfg));

    misc->sub_command = MLAN_OID_MISC_SDIO_MPA_CTRL;
    req->req_id = MLAN_IOCTL_MISC_CFG;

    /* Get the values first, then modify these values if user had modified them 
     */

    req->action = MLAN_ACT_GET;
    if ((ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) !=
        MLAN_STATUS_SUCCESS) {
        PRINTM(MERROR, "woal_request_ioctl returned %d\n", ret);
        ret = -EFAULT;
        goto done;
    }

    if (wrq->u.data.length == 0) {
        data[0] = misc->param.mpa_ctrl.tx_enable;
        data[1] = misc->param.mpa_ctrl.rx_enable;
        data[2] = misc->param.mpa_ctrl.tx_buf_size;
        data[3] = misc->param.mpa_ctrl.rx_buf_size;
        data[4] = misc->param.mpa_ctrl.tx_max_ports;
        data[5] = misc->param.mpa_ctrl.rx_max_ports;

        PRINTM(MINFO, "Get Param: %d %d %d %d %d %d\n", data[0], data[1],
               data[2], data[3], data[4], data[5]);

        if (copy_to_user(wrq->u.data.pointer, data, sizeof(data))) {
            ret = -EFAULT;
            goto done;
        }
        wrq->u.data.length = sizeof(data) / sizeof(int);
        goto done;
    }

    if (copy_from_user(data, wrq->u.data.pointer,
                       sizeof(int) * wrq->u.data.length)) {
        PRINTM(MINFO, "Copy from user failed\n");
        ret = -EFAULT;
        goto done;
    }

    switch (wrq->u.data.length) {
    case 6:
        misc->param.mpa_ctrl.rx_max_ports = data[5];
    case 5:
        misc->param.mpa_ctrl.tx_max_ports = data[4];
    case 4:
        misc->param.mpa_ctrl.rx_buf_size = data[3];
    case 3:
        misc->param.mpa_ctrl.tx_buf_size = data[2];
    case 2:
        misc->param.mpa_ctrl.rx_enable = data[1];
    case 1:
        /* Set cmd */
        req->action = MLAN_ACT_SET;

        PRINTM(MINFO, "Set Param: %d %d %d %d %d %d\n", data[0], data[1],
               data[2], data[3], data[4], data[5]);

        misc->param.mpa_ctrl.tx_enable = data[0];
        break;
    default:
        PRINTM(MERROR, "Default case error\n");
        ret = -EINVAL;
        goto done;
    }

    if ((ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT) !=
         MLAN_STATUS_SUCCESS)) {
        PRINTM(MERROR, "woal_request_ioctl returned %d\n", ret);
        ret = -EFAULT;
        goto done;
    }

  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}
#endif /* SDIO_MULTI_PORT_TX_AGGR || SDIO_MULTI_PORT_RX_AGGR */

/**
 * @brief Set/get TID multi-port eligibility table
 * 
 * @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_tid_elig_tbl(moal_private * priv, struct iwreq *wrq)
{
    int data[8] = { 0 }, ret = 0;
    mlan_ds_wmm_cfg *cfg = NULL;
    mlan_ioctl_req *req = NULL;

    ENTER();
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    if (wrq->u.data.length > 8) {
        ret = -EINVAL;
        goto done;
    }
    cfg = (mlan_ds_wmm_cfg *) req->pbuf;
    cfg->sub_command = MLAN_OID_TID_ELIG_TBL;
    req->req_id = MLAN_IOCTL_WMM_CFG;
    if (wrq->u.data.length) {
        if (copy_from_user
            (data, wrq->u.data.pointer, (wrq->u.data.length * sizeof(int)))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        req->action = MLAN_ACT_SET;
        memcpy(cfg->param.tid_tbl, (t_u32 *) data, sizeof(data));
    } else
        req->action = MLAN_ACT_GET;
    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }
    if (!wrq->u.data.length) {
        memcpy(data, (int *) cfg->param.tid_tbl, sizeof(data));
        if (copy_to_user(wrq->u.data.pointer, data, sizeof(data))) {
            ret = -EFAULT;
            goto done;
        }
        wrq->u.data.length = sizeof(data) / sizeof(int);
    }
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/** Maximum number of probes to send on each channel */
#define MAX_PROBES  10
/**
 * @brief Set/Get scan 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_scan_cfg(moal_private * priv, struct iwreq *wrq)
{
    int data[6], ret = 0;
    mlan_ds_scan *scan = NULL;
    mlan_ioctl_req *req = NULL;

    ENTER();
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_scan));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    if (wrq->u.data.length > 6) {
        ret = -EINVAL;
        goto done;
    }
    scan = (mlan_ds_scan *) req->pbuf;
    scan->sub_command = MLAN_OID_SCAN_CONFIG;
    req->req_id = MLAN_IOCTL_SCAN;
    memset(data, 0, sizeof(data));
    if (wrq->u.data.length) {
        if (copy_from_user
            (data, wrq->u.data.pointer, (wrq->u.data.length * sizeof(int)))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        if ((data[0] < 0) || (data[0] > MLAN_SCAN_TYPE_PASSIVE)) {
            PRINTM(MERROR, "Invalid argument for scan type\n");
            ret = -EINVAL;
            goto done;
        }
        if ((data[1] < 0) || (data[1] > MLAN_SCAN_MODE_ANY)) {
            PRINTM(MERROR, "Invalid argument for scan mode\n");
            ret = -EINVAL;
            goto done;
        }
        if ((data[2] < 0) || (data[2] > MAX_PROBES)) {
            PRINTM(MERROR, "Invalid argument for scan probes\n");
            ret = -EINVAL;
            goto done;
        }
        if (((data[3] < 0) || (data[3] > MRVDRV_MAX_ACTIVE_SCAN_CHAN_TIME)) ||
            ((data[4] < 0) || (data[4] > MRVDRV_MAX_ACTIVE_SCAN_CHAN_TIME)) ||
            ((data[5] < 0) || (data[5] > MRVDRV_MAX_PASSIVE_SCAN_CHAN_TIME))) {
            PRINTM(MERROR, "Invalid argument for scan time\n");
            ret = -EINVAL;
            goto done;
        }
        req->action = MLAN_ACT_SET;
        memcpy(&scan->param.scan_cfg, (t_u32 *) data, sizeof(data));
    } else
        req->action = MLAN_ACT_GET;
    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }
    if (!wrq->u.data.length) {
        memcpy(data, (int *) &scan->param.scan_cfg, sizeof(data));
        if (copy_to_user(wrq->u.data.pointer, data, sizeof(data))) {
            ret = -EFAULT;
            goto done;
        }
        wrq->u.data.length = sizeof(data) / sizeof(int);
    }
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/** VSIE configuration buffer length */
#define VSIE_MAX_CFG_LEN    (MLAN_MAX_VSIE_LEN - 2 + 3)
/** VSIE mask to remove the IE */
#define VSIE_MASK_DISABLE   0x00
/** VSIE Action : Get */
#define VSIE_ACTION_GET     0
/** VSIE Action : Add */
#define VSIE_ACTION_ADD     1
/** VSIE Action : Delete */
#define VSIE_ACTION_DELETE  2
/** 
 *  @brief Get/Add/Remove vendor specific IE
 *   
 *  @param priv         A pointer to moal_private structure
 *  @param wrq          A pointer to iwreq structure
 *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static int
woal_vsie_cfg_ioctl(moal_private * priv, struct iwreq *wrq)
{
    int ret = 0, user_data_len = 0, ie_len = 0;
    mlan_ds_misc_cfg *misc = NULL;
    mlan_ioctl_req *req = NULL;
    t_u8 *buf = NULL;

    ENTER();

    user_data_len = wrq->u.data.length;
    if (user_data_len < 2 || user_data_len == 3 ||
        user_data_len > VSIE_MAX_CFG_LEN) {
        PRINTM(MERROR, "Invalid argument number!\n");
        LEAVE();
        return -EINVAL;
    }
    if (!(buf = (t_u8 *) kmalloc(VSIE_MAX_CFG_LEN, GFP_ATOMIC))) {
        PRINTM(MERROR, "Cannot allocate buffer for command!\n");
        LEAVE();
        return -ENOMEM;
    }
    memset(buf, 0, VSIE_MAX_CFG_LEN);
    if (copy_from_user(buf, wrq->u.data.pointer, user_data_len)) {
        PRINTM(MINFO, "Copy from user failed\n");
        ret = -EFAULT;
        goto done;
    }

    if ((buf[0] > VSIE_ACTION_DELETE) ||
        (buf[1] > MLAN_MAX_VSIE_NUM - 1) ||
        ((buf[0] == VSIE_ACTION_ADD) &&
         !(buf[2] &&
           buf[2] <=
           (MLAN_VSIE_MASK_SCAN | MLAN_VSIE_MASK_ASSOC |
            MLAN_VSIE_MASK_ADHOC)))) {
        PRINTM(MERROR, "Invalid argument!\n");
        ret = -EINVAL;
        goto done;
    }

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    req->req_id = MLAN_IOCTL_MISC_CFG;
    misc = (mlan_ds_misc_cfg *) req->pbuf;
    misc->sub_command = MLAN_OID_MISC_VS_IE;

    misc->param.vsie.id = buf[1];
    misc->param.vsie.mask = VSIE_MASK_DISABLE;
    switch (buf[0]) {
    case VSIE_ACTION_GET:
        req->action = MLAN_ACT_GET;
        break;
    case VSIE_ACTION_ADD:
        ie_len = user_data_len - 3;
        misc->param.vsie.mask = buf[2];
        misc->param.vsie.ie[1] = ie_len;
        memcpy(&misc->param.vsie.ie[2], &buf[3], ie_len);
    case VSIE_ACTION_DELETE:
        /* Set with mask 0 is remove */
        req->action = MLAN_ACT_SET;
        break;
    default:
        break;
    }

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

    wrq->u.data.length = misc->param.vsie.ie[1];
    if (wrq->u.data.length) {
        if (copy_to_user
            (wrq->u.data.pointer, &misc->param.vsie.ie[2],
             wrq->u.data.length)) {
            PRINTM(MINFO, "Copy to user failed\n");
            ret = -EFAULT;
            goto done;
        }
    }

  done:
    if (buf)
        kfree(buf);
    if (req)
        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
 * 
 * @return         0 --success, otherwise fail
 */
static int
woal_set_get_ps_cfg(moal_private * priv, struct iwreq *wrq)
{
    int data[7], ret = 0;
    mlan_ds_pm_cfg *pm_cfg = NULL;
    mlan_ioctl_req *req = NULL;
    int allowed = 3;
    int i = 3;

    ENTER();

    allowed++;                  /* For ad-hoc awake period parameter */
    allowed++;                  /* For beacon missing timeout parameter */
    allowed += 2;               /* For delay to PS and PS mode parameters */

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    if (wrq->u.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 (wrq->u.data.length) {
        if (copy_from_user
            (data, wrq->u.data.pointer, (wrq->u.data.length * sizeof(int)))) {
            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] != IGNORE_MULTIPLE_DTIM) &&
            ((data[1] < MIN_MULTIPLE_DTIM) || (data[1] > MAX_MULTIPLE_DTIM))) {
            PRINTM(MERROR, "Invalid argument for multiple DTIM\n");
            ret = -EINVAL;
            goto done;
        }
        if (data[2] < MIN_LISTEN_INTERVAL) {
            PRINTM(MERROR, "Invalid argument for listen interval\n");
            ret = -EINVAL;
            goto done;
        }
        if ((data[i] != SPECIAL_ADHOC_AWAKE_PD) &&
            ((data[i] < MIN_ADHOC_AWAKE_PD) ||
             (data[i] > MAX_ADHOC_AWAKE_PD))) {
            PRINTM(MERROR, "Invalid argument for adhoc awake period\n");
            ret = -EINVAL;
            goto done;
        }
        i++;
        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 (wrq->u.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, (t_u32 *) data,
               sizeof(pm_cfg->param.ps_cfg));
    } else
        req->action = MLAN_ACT_GET;

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }
    memcpy(data, (int *) &pm_cfg->param.ps_cfg, 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;
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @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 whose length is
 *    calculated from the IOCTL data length.  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)
{
    static t_u8 dialog_tok = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_wmm_cfg *cfg = NULL;
    wlan_ioctl_wmm_addts_req_t addts_ioctl;
    int ret = 0;

    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, 0, 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;
        }

        if ((++dialog_tok) == 0)
            dialog_tok = 1;
        cfg->param.addts.dialog_tok = dialog_tok;
        cfg->param.addts.timeout = addts_ioctl.timeout_ms;
        cfg->param.addts.tspec_data_len = (wrq->u.data.length
                                           - sizeof(addts_ioctl.timeout_ms)
                                           - sizeof(addts_ioctl.cmd_result)
                                           -
                                           sizeof(addts_ioctl.
                                                  ieee_status_code));

        memcpy(cfg->param.addts.tspec_data,
               addts_ioctl.tspec_data, cfg->param.addts.tspec_data_len);

        if (MLAN_STATUS_SUCCESS !=
            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
            ret = -EFAULT;
            goto done;
        }
        addts_ioctl.cmd_result = cfg->param.addts.result;
        addts_ioctl.ieee_status_code = (t_u8) cfg->param.addts.status_code;
        memcpy(addts_ioctl.tspec_data,
               cfg->param.addts.tspec_data, cfg->param.addts.tspec_data_len);

        wrq->u.data.length = (sizeof(addts_ioctl.timeout_ms)
                              + sizeof(addts_ioctl.cmd_result)
                              + sizeof(addts_ioctl.ieee_status_code)
                              + cfg->param.addts.tspec_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 (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Private IOCTL entry to send a DELTS TSPEC
 *
 *  Receive a DELTS command from the application.  The command structure
 *    contains a TSPEC and reason code along with space for a command result
 *    to be returned.  The information is packaged is sent to the wlan_cmd.c
 *    firmware command prep and send routines for execution in the firmware.
 *
 *  The reason code is not used for WMM implementations but is indicated in
 *    the 802.11e specification.
 *
 *  The return value to the application layer indicates a driver execution
 *    success or failure.  A successful return could still indicate a firmware
 *    failure via the cmd_result 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_delts_req_t struct for this DELTS request
 *
 *  @return        0 if successful; IOCTL error code otherwise
 */
static int
woal_wmm_delts_req_ioctl(moal_private * priv, struct iwreq *wrq)
{
    mlan_ioctl_req *req = NULL;
    mlan_ds_wmm_cfg *cfg = NULL;
    wlan_ioctl_wmm_delts_req_t delts_ioctl;
    int ret = 0;

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

    memset(&delts_ioctl, 0, sizeof(delts_ioctl));

    if (wrq->u.data.length) {
        if (copy_from_user(&delts_ioctl, wrq->u.data.pointer,
                           MIN(wrq->u.data.length, sizeof(delts_ioctl)))) {
            PRINTM(MERROR, "TSPEC: DELTS copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }

        cfg->param.delts.status_code = (t_u32) delts_ioctl.ieee_reason_code;

        /* Calculate the length of the TSPEC */
        cfg->param.delts.tspec_data_len = (wrq->u.data.length
                                           - sizeof(delts_ioctl.cmd_result)
                                           -
                                           sizeof(delts_ioctl.
                                                  ieee_reason_code));

        memcpy(cfg->param.delts.tspec_data,
               delts_ioctl.tspec_data, cfg->param.delts.tspec_data_len);

        if (MLAN_STATUS_SUCCESS !=
            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
            ret = -EFAULT;
            goto done;
        }

        /* Return the firmware command result back to the application layer */
        delts_ioctl.cmd_result = cfg->param.delts.result;
        wrq->u.data.length = sizeof(delts_ioctl);

        if (copy_to_user(wrq->u.data.pointer, &delts_ioctl, wrq->u.data.length)) {
            PRINTM(MERROR, "TSPEC: DELTS copy to user failed\n");
            ret = -EFAULT;
            goto done;
        }
    }

  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Private IOCTL entry to get/set a specified AC Queue's parameters
 *
 *  Receive a AC Queue configuration command which is used to get, set, or
 *    default the parameters associated with a specific WMM AC Queue.
 *
 *  @param priv    Pointer to the mlan_private driver data struct
 *  @param wrq     A pointer to iwreq structure containing the
 *                 wlan_ioctl_wmm_queue_config_t struct
 *
 *  @return        0 if successful; IOCTL error code otherwise
 */
static int
woal_wmm_queue_config_ioctl(moal_private * priv, struct iwreq *wrq)
{
    mlan_ioctl_req *req = NULL;
    mlan_ds_wmm_cfg *pwmm = NULL;
    mlan_ds_wmm_queue_config *pqcfg = NULL;
    wlan_ioctl_wmm_queue_config_t qcfg_ioctl;
    int ret = 0;

    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;
    pwmm = (mlan_ds_wmm_cfg *) req->pbuf;
    pwmm->sub_command = MLAN_OID_WMM_CFG_QUEUE_CONFIG;

    memset(&qcfg_ioctl, 0, sizeof(qcfg_ioctl));
    pqcfg = (mlan_ds_wmm_queue_config *) & pwmm->param.q_cfg;

    if (wrq->u.data.length) {
        if (copy_from_user(&qcfg_ioctl, wrq->u.data.pointer,
                           MIN(wrq->u.data.length, sizeof(qcfg_ioctl)))) {
            PRINTM(MERROR, "QCONFIG: copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }

        pqcfg->action = qcfg_ioctl.action;
        pqcfg->access_category = qcfg_ioctl.access_category;
        pqcfg->msdu_lifetime_expiry = qcfg_ioctl.msdu_lifetime_expiry;

        if (MLAN_STATUS_SUCCESS !=
            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
            ret = -EFAULT;
            goto done;
        }
        memset(&qcfg_ioctl, 0, sizeof(qcfg_ioctl));
        qcfg_ioctl.action = pqcfg->action;
        qcfg_ioctl.access_category = pqcfg->access_category;
        qcfg_ioctl.msdu_lifetime_expiry = pqcfg->msdu_lifetime_expiry;
        wrq->u.data.length = sizeof(qcfg_ioctl);

        if (copy_to_user(wrq->u.data.pointer, &qcfg_ioctl, wrq->u.data.length)) {
            PRINTM(MERROR, "QCONFIG: copy to user failed\n");
            ret = -EFAULT;
            goto done;
        }
    }

  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Private IOCTL entry to get and start/stop queue stats on a WMM AC
 *
 *  Receive a AC Queue statistics command from the application for a specific
 *    WMM AC.  The command can:
 *         - Turn stats on
 *         - Turn stats off
 *         - Collect and clear the stats
 *
 *  @param priv    Pointer to the moal_private driver data struct
 *  @param wrq     A pointer to iwreq structure containing the
 *                 wlan_ioctl_wmm_queue_stats_t struct
 *
 *  @return        0 if successful; IOCTL error code otherwise
 */
static int
woal_wmm_queue_stats_ioctl(moal_private * priv, struct iwreq *wrq)
{
    mlan_ioctl_req *req = NULL;
    mlan_ds_wmm_cfg *pwmm = NULL;
    mlan_ds_wmm_queue_stats *pqstats = NULL;
    wlan_ioctl_wmm_queue_stats_t qstats_ioctl;
    int ret = 0;

    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;
    pwmm = (mlan_ds_wmm_cfg *) req->pbuf;
    pwmm->sub_command = MLAN_OID_WMM_CFG_QUEUE_STATS;

    memset(&qstats_ioctl, 0, sizeof(qstats_ioctl));
    pqstats = (mlan_ds_wmm_queue_stats *) & pwmm->param.q_stats;

    if (wrq->u.data.length) {
        if (copy_from_user(&qstats_ioctl, wrq->u.data.pointer,
                           MIN(wrq->u.data.length, sizeof(qstats_ioctl)))) {
            PRINTM(MERROR, "QSTATS: copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }

        memcpy((void *) pqstats, (void *) &qstats_ioctl, sizeof(qstats_ioctl));
        PRINTM(MINFO, "QSTATS: IOCTL [%d,%d]\n", qstats_ioctl.action,
               qstats_ioctl.access_category);

        if (MLAN_STATUS_SUCCESS !=
            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
            ret = -EFAULT;
            goto done;
        }

        memset(&qstats_ioctl, 0, sizeof(qstats_ioctl));
        memcpy((void *) &qstats_ioctl, (void *) pqstats, sizeof(qstats_ioctl));
        wrq->u.data.length = sizeof(qstats_ioctl);

        if (copy_to_user
            (wrq->u.data.pointer, &qstats_ioctl, wrq->u.data.length)) {
            PRINTM(MERROR, "QSTATS: copy to user failed\n");
            ret = -EFAULT;
            goto done;
        }
    }

  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Private IOCTL entry to get the status of the WMM queues
 *
 *  Return the following information for each WMM AC:
 *        - WMM IE Acm Required
 *        - Firmware Flow Required
 *        - Firmware Flow Established
 *        - Firmware Queue Enabled
 *        - Firmware Delivery Enabled
 *        - Firmware Trigger Enabled
 *
 *  @param priv    Pointer to the moal_private driver data struct
 *  @param wrq     A pointer to iwreq structure containing the
 *                 wlan_ioctl_wmm_queue_status_t struct for request
 *
 *  @return        0 if successful; IOCTL error code otherwise
 */
static int
woal_wmm_queue_status_ioctl(moal_private * priv, struct iwreq *wrq)
{
    mlan_ioctl_req *req = NULL;
    mlan_ds_wmm_cfg *pwmm = NULL;
    wlan_ioctl_wmm_queue_status_t qstatus_ioctl;
    int ret = 0;

    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;
    pwmm = (mlan_ds_wmm_cfg *) req->pbuf;
    pwmm->sub_command = MLAN_OID_WMM_CFG_QUEUE_STATUS;

    if (wrq->u.data.length == sizeof(qstatus_ioctl)) {
        if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_NO_WAIT)) {
            ret = -EFAULT;
            goto done;
        }

        memset(&qstatus_ioctl, 0, sizeof(qstatus_ioctl));
        memcpy((void *) &qstatus_ioctl, (void *) &pwmm->param.q_status,
               sizeof(qstatus_ioctl));
        wrq->u.data.length = sizeof(qstatus_ioctl);
    } else {
        wrq->u.data.length = 0;
    }

    if (copy_to_user(wrq->u.data.pointer, &qstatus_ioctl, wrq->u.data.length)) {
        PRINTM(MERROR, "QSTATUS: copy to user failed\n");
        ret = -EFAULT;
        goto done;
    }

  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Private IOCTL entry to get the status of the WMM Traffic Streams
 *
 *  @param priv    Pointer to the moal_private driver data struct
 *  @param wrq     A pointer to iwreq structure containing the
 *                 wlan_ioctl_wmm_ts_status_t struct for request
 *
 *  @return        0 if successful; IOCTL error code otherwise
 */
static int
woal_wmm_ts_status_ioctl(moal_private * priv, struct iwreq *wrq)
{
    mlan_ioctl_req *req = NULL;
    mlan_ds_wmm_cfg *pwmm = NULL;
    wlan_ioctl_wmm_ts_status_t ts_status_ioctl;
    int ret = 0;

    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;
    pwmm = (mlan_ds_wmm_cfg *) req->pbuf;
    pwmm->sub_command = MLAN_OID_WMM_CFG_TS_STATUS;

    memset(&ts_status_ioctl, 0, sizeof(ts_status_ioctl));

    if (wrq->u.data.length == sizeof(ts_status_ioctl)) {
        if (copy_from_user(&ts_status_ioctl, wrq->u.data.pointer,
                           MIN(wrq->u.data.length, sizeof(ts_status_ioctl)))) {
            PRINTM(MERROR, "TSTATUS: copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }

        memset(&pwmm->param.ts_status, 0, sizeof(ts_status_ioctl));
        pwmm->param.ts_status.tid = ts_status_ioctl.tid;

        if (MLAN_STATUS_SUCCESS !=
            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
            ret = -EFAULT;
            goto done;
        }

        memset(&ts_status_ioctl, 0, sizeof(ts_status_ioctl));
        memcpy((void *) &ts_status_ioctl, (void *) &pwmm->param.ts_status,
               sizeof(ts_status_ioctl));
        wrq->u.data.length = sizeof(ts_status_ioctl);
    } else {
        wrq->u.data.length = 0;
    }

    if (copy_to_user(wrq->u.data.pointer, &ts_status_ioctl, wrq->u.data.length)) {
        PRINTM(MERROR, "TSTATUS: copy to user failed\n");
        ret = -EFAULT;
        goto done;
    }

  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/**
 *  @brief Set/Get auth type
 *
 *  @param priv     Pointer to the moal_private driver data struct
 *  @param wrq	    A pointer to iwreq structure
 *
 *  @return          0 --success, otherwise fail
 */
static int
woal_auth_type(moal_private * priv, struct iwreq *wrq)
{
    int auth_type;
    t_u32 auth_mode;
    int ret = 0;

    ENTER();
    if (wrq->u.data.length == 0) {
        if (MLAN_STATUS_SUCCESS !=
            woal_get_auth_mode(priv, MOAL_IOCTL_WAIT, &auth_mode)) {
            ret = -EFAULT;
            goto done;
        }
        auth_type = auth_mode;
        if (copy_to_user(wrq->u.data.pointer, &auth_type, sizeof(auth_type))) {
            PRINTM(MERROR, "Copy to user failed\n");
            ret = -EFAULT;
            goto done;
        }
        wrq->u.data.length = 1;
    } else {
        if (copy_from_user(&auth_type, wrq->u.data.pointer, sizeof(auth_type))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
        PRINTM(MINFO, "SET: auth_type %d\n", auth_type);
        if (((auth_type < MLAN_AUTH_MODE_OPEN) ||
             (auth_type > MLAN_AUTH_MODE_SHARED))
            && (auth_type != MLAN_AUTH_MODE_AUTO)) {
            ret = -EINVAL;
            goto done;
        }
        auth_mode = auth_type;
        if (MLAN_STATUS_SUCCESS !=
            woal_set_auth_mode(priv, MOAL_IOCTL_WAIT, auth_mode)) {
            ret = -EFAULT;
            goto done;
        }
    }
  done:
    LEAVE();
    return ret;
}

/********************************************************
		Global Functions
********************************************************/

/** 
 *  @brief Get version 
 *   
 *  @param handle 		A pointer to moal_handle structure
 *  @param version		A pointer to version buffer
 *  @param max_len		max length of version buffer
 *
 *  @return 	   		N/A
 */
void
woal_get_version(moal_handle * handle, char *version, int max_len)
{
    union
    {
        t_u32 l;
        t_u8 c[4];
    } ver;
    char fw_ver[32];

    ENTER();

    ver.l = handle->fw_release_number;
    sprintf(fw_ver, "%u.%u.%u.p%u", ver.c[2], ver.c[1], ver.c[0], ver.c[3]);

    snprintf(version, max_len, driver_version, fw_ver);

    LEAVE();
}

/**
 *  @brief ioctl function - entry point
 *
 *  @param dev		A pointer to net_device structure
 *  @param req	   	A pointer to ifreq structure
 *  @param cmd 		Command
 *
 *  @return          0 --success, otherwise fail
 */
int
woal_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
{
    moal_private *priv = (moal_private *) netdev_priv(dev);
    struct iwreq *wrq = (struct iwreq *) req;
    int ret = 0;

    ENTER();

    PRINTM(MINFO, "woal_do_ioctl: ioctl cmd = 0x%x\n", cmd);
    switch (cmd) {
    case WOAL_SETONEINT_GETWORDCHAR:
        switch (wrq->u.data.flags) {
        case WOAL_VERSION:     /* Get driver version */
            ret = woal_get_driver_version(priv, req);
            break;
        case WOAL_VEREXT:      /* Get extended driver version */
            ret = woal_get_driver_verext(priv, req);
            break;
        default:
            ret = -EOPNOTSUPP;
            break;
        }
        break;
    case WOAL_SETNONE_GETNONE:
        switch (wrq->u.data.flags) {
        case WOAL_WARMRESET:
            ret = woal_warm_reset(priv);
            break;
        default:
            ret = -EOPNOTSUPP;
            break;
        }
        break;
    case WOAL_SETONEINT_GETONEINT:
        switch (wrq->u.data.flags) {
        case WOAL_SET_GET_TXRATE:
            ret = woal_set_get_txrate(priv, wrq);
            break;
        case WOAL_SET_GET_REGIONCODE:
            ret = woal_set_get_regioncode(priv, wrq);
            break;
        case WOAL_SET_RADIO:
            ret = woal_set_get_radio(priv, wrq);
            break;
        case WOAL_WMM_ENABLE:
            ret = woal_wmm_enable_ioctl(priv, wrq);
            break;
        case WOAL_11D_ENABLE:
            ret = woal_11d_enable_ioctl(priv, wrq);
            break;
        case WOAL_SET_GET_TX_RX_ANT:
            ret = woal_set_get_tx_rx_ant(priv, wrq);
            break;
        case WOAL_SET_GET_QOS_CFG:
            ret = woal_set_get_qos_cfg(priv, wrq);
            break;
        case WOAL_SET_GET_LDO_CFG:
            ret = woal_set_get_ldo_cfg(priv, wrq);
            break;
#ifdef REASSOCIATION
        case WOAL_SET_GET_REASSOC:
            ret = woal_set_get_reassoc(priv, wrq);
            break;
#endif /* REASSOCIATION */
        case WOAL_TXBUF_CFG:
            ret = woal_txbuf_cfg(priv, wrq);
            break;
        case WOAL_SET_GET_WWS_CFG:
            ret = woal_wws_cfg(priv, wrq);
            break;
        case WOAL_SLEEP_PD:
            ret = woal_sleep_pd(priv, wrq);
            break;
        case WOAL_AUTH_TYPE:
            ret = woal_auth_type(priv, wrq);
            break;

        default:
            ret = -EOPNOTSUPP;
            break;
        }
        break;

    case WOAL_SET_GET_SIXTEEN_INT:
        switch ((int) wrq->u.data.flags) {
        case WOAL_TX_POWERCFG:
            ret = woal_tx_power_cfg(priv, wrq);
            break;
#ifdef DEBUG_LEVEL1
        case WOAL_DRV_DBG:
            ret = woal_drv_dbg(priv, wrq);
            break;
#endif
        case WOAL_BEACON_INTERVAL:
            ret = woal_beacon_interval(priv, wrq);
            break;
        case WOAL_ATIM_WINDOW:
            ret = woal_atim_window(priv, wrq);
            break;
        case WOAL_SIGNAL:
            ret = woal_get_signal(priv, wrq);
            break;
        case WOAL_DEEP_SLEEP:
            ret = woal_deep_sleep_ioctl(priv, wrq);
            break;
        case WOAL_11N_TX_CFG:
            ret = woal_11n_tx_cfg(priv, wrq);
            break;
        case WOAL_11N_AMSDU_AGGR_CTRL:
            ret = woal_11n_amsdu_aggr_ctrl(priv, wrq);
            break;
        case WOAL_11N_HTCAP_CFG:
            ret = woal_11n_htcap_cfg(priv, wrq);
            break;
        case WOAL_PRIO_TBL:
            ret = woal_11n_prio_tbl(priv, wrq);
            break;
        case WOAL_ADDBA_UPDT:
            ret = woal_addba_para_updt(priv, wrq);
            break;
        case WOAL_ADDBA_REJECT:
            ret = woal_addba_reject(priv, wrq);
            break;
        case WOAL_HS_CFG:
            ret = woal_hs_cfg(priv, wrq, MTRUE);
            break;
        case WOAL_HS_SETPARA:
            ret = woal_hs_setpara(priv, wrq);
            break;
        case WOAL_REG_READ_WRITE:
            ret = woal_reg_read_write(priv, wrq);
            break;
        case WOAL_INACTIVITY_TIMEOUT_EXT:
            ret = woal_inactivity_timeout_ext(priv, wrq);
            break;
        case WOAL_SDIO_CLOCK:
            ret = woal_sdio_clock_ioctl(priv, wrq);
            break;
        case WOAL_BAND_CFG:
            ret = woal_band_cfg(priv, wrq);
            break;
        case WOAL_BCA_TIME_SHARE:
            ret = woal_bca_time_share(priv, wrq);
            break;
        case WOAL_TID_ELIG_TBL:
            ret = woal_set_get_tid_elig_tbl(priv, wrq);
            break;
        case WOAL_SCAN_CFG:
            ret = woal_set_get_scan_cfg(priv, wrq);
            break;
        case WOAL_PS_CFG:
            ret = woal_set_get_ps_cfg(priv, wrq);
            break;
        case WOAL_MEM_READ_WRITE:
            ret = woal_mem_read_write(priv, wrq);
            break;
#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR)
        case WOAL_SDIO_MPA_CTRL:
            ret = woal_do_sdio_mpa_ctrl(priv, wrq);
            break;
#endif
        case WOAL_SLEEP_PARAMS:
            ret = woal_sleep_params_ioctl(priv, wrq);
            break;
        default:
            ret = -EINVAL;
            break;
        }
        break;

    case WOALGETLOG:
        ret = woal_get_log(priv, wrq);
        break;
    case WOAL_SET_GET_256_CHAR:
        switch (wrq->u.data.flags) {
        case WOAL_PASSPHRASE:
            ret = woal_passphrase(priv, wrq);
            break;
        case WOAL_ADHOC_AES:
            ret = woal_adhoc_aes_ioctl(priv, wrq);
            break;
        case WOAL_WMM_QUEUE_STATUS:
            ret = woal_wmm_queue_status_ioctl(priv, wrq);
            break;
        case WOAL_WMM_TS_STATUS:
            ret = woal_wmm_ts_status_ioctl(priv, wrq);
            break;
        default:
            ret = -EINVAL;
            break;
        }
        break;

    case WOAL_SETADDR_GETNONE:
        switch ((int) wrq->u.data.flags) {
        case WOAL_DEAUTH:
            ret = woal_deauth(priv, wrq);
            break;
        default:
            ret = -EINVAL;
            break;
        }
        break;

    case WOAL_SETNONE_GETTWELVE_CHAR:
        /* 
         * We've not used IW_PRIV_TYPE_FIXED so sub-ioctl number is
         * in flags of iwreq structure, otherwise it will be in
         * mode member of iwreq structure.
         */
        switch ((int) wrq->u.data.flags) {
        case WOAL_WPS_SESSION:
            ret = woal_wps_cfg_ioctl(priv, wrq);
            break;
        default:
            ret = -EINVAL;
            break;
        }
        break;
    case WOAL_SETNONE_GET_FOUR_INT:
        switch ((int) wrq->u.data.flags) {
        case WOAL_DATA_RATE:
            ret = woal_get_txrx_rate(priv, wrq);
            break;
        case WOAL_ESUPP_MODE:
            ret = woal_get_esupp_mode(priv, wrq);
            break;
        default:
            ret = -EINVAL;
            break;
        }
        break;

#ifdef MFG_CMD_SUPPORT
    case WOAL_MFG_CMD:
        PRINTM(MINFO, "Entering the Manufacturing ioctl SIOCCFMFG\n");
        ret = woal_mfg_command(priv, wrq);
        PRINTM(MINFO, "Manufacturing Ioctl %s\n", (ret) ? "failed" : "success");
        break;
#endif
    case WOAL_SET_GET_64_INT:
        switch ((int) wrq->u.data.flags) {
        case WOAL_ECL_SYS_CLOCK:
            ret = woal_ecl_sys_clock(priv, wrq);
            break;
        }
        break;

    case WOAL_HOST_CMD:
        ret = woal_host_command(priv, wrq);
        break;
    case WOAL_ARP_FILTER:
        ret = woal_arp_filter(priv, wrq);
        break;
    case WOAL_SET_INTS_GET_CHARS:
        switch ((int) wrq->u.data.flags) {
        case WOAL_READ_EEPROM:
            ret = woal_read_eeprom(priv, wrq);
            break;
        }
        break;
    case WOAL_SET_GET_2K_BYTES:
        switch ((int) wrq->u.data.flags) {
        case WOAL_CMD_52RDWR:
            ret = woal_cmd52rdwr_ioctl(priv, wrq);
            break;
        case WOAL_CMD_53RDWR:
            ret = woal_cmd53rdwr_ioctl(priv, wrq);
            break;
        case WOAL_SET_USER_SCAN:
            ret = woal_set_user_scan_ioctl(priv, wrq);
            break;
        case WOAL_GET_SCAN_TABLE:
            ret = woal_get_scan_table_ioctl(priv, wrq);
            break;
        case WOAL_VSIE_CFG:
            ret = woal_vsie_cfg_ioctl(priv, wrq);
            break;
        case WOAL_WMM_ADDTS:
            ret = woal_wmm_addts_req_ioctl(priv, wrq);
            break;
        case WOAL_WMM_DELTS:
            ret = woal_wmm_delts_req_ioctl(priv, wrq);
            break;
        case WOAL_WMM_QUEUE_CONFIG:
            ret = woal_wmm_queue_config_ioctl(priv, wrq);
            break;
        case WOAL_WMM_QUEUE_STATS:
            ret = woal_wmm_queue_stats_ioctl(priv, wrq);
            break;
        default:
            ret = -EINVAL;
            break;
        }
        break;

    case WOAL_GET_BSS_TYPE:
        ret = woal_get_bss_type(dev, req);
        break;
    default:
        ret = -EINVAL;
        break;
    }

    LEAVE();
    return ret;
}

/** 
 *  @brief Send get FW info request to MLAN
 *   
 *  @param priv  A pointer to moal_private structure
 *
 *  @return      None
 */
void
woal_request_get_fw_info(moal_private * priv)
{
    mlan_ioctl_req *req = NULL;
    mlan_ds_get_info *info;
    mlan_status status;
    ENTER();
    memset(priv->current_addr, 0xff, ETH_ALEN);

    /* Allocate an IOCTL request buffer */
    req = (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
    if (req == NULL) {
        status = MLAN_STATUS_FAILURE;
        goto done;
    }

    /* Fill request buffer */
    info = (mlan_ds_get_info *) req->pbuf;
    req->req_id = MLAN_IOCTL_GET_INFO;
    req->action = MLAN_ACT_GET;
    info->sub_command = MLAN_OID_GET_FW_INFO;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, MOAL_CMD_WAIT);
    if (status == MLAN_STATUS_SUCCESS) {
        priv->phandle->fw_release_number = info->param.fw_info.fw_ver;
        if (priv->current_addr[0] == 0xff)
            memcpy(priv->current_addr, &info->param.fw_info.mac_addr,
                   sizeof(mlan_802_11_mac_addr));
        memcpy(priv->netdev->dev_addr, priv->current_addr, ETH_ALEN);
        DBG_HEXDUMP(MIF_D, "mac", priv->current_addr, 6);
    } else
        PRINTM(MERROR, "get fw info failed! status=%d, error_code=0x%lx\n",
               status, req->status_code);
  done:
    if (req)
        kfree(req);
    LEAVE();
    return;
}

/** 
 *  @brief Get mode
 *
 *  @param priv          A pointer to moal_private structure
 *  @param wait_option   Wait option (MOAL_WAIT or MOAL_NO_WAIT)   
 *
 *  @return              Wireless mode
 */
t_u32
woal_get_mode(moal_private * priv, t_u8 wait_option)
{
    int ret = 0;
    mlan_ds_bss *bss = NULL;
    mlan_ioctl_req *req = NULL;
    mlan_status status = MLAN_STATUS_SUCCESS;
    t_u32 mode = priv->w_stats.status;
    ENTER();

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    /* Fill request buffer */
    bss = (mlan_ds_bss *) req->pbuf;
    bss->sub_command = MLAN_OID_BSS_MODE;
    req->req_id = MLAN_IOCTL_BSS;
    req->action = MLAN_ACT_GET;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, wait_option);
    if (status == MLAN_STATUS_SUCCESS) {
        switch (bss->param.bss_mode) {
        case MLAN_BSS_MODE_INFRA:
            mode = IW_MODE_INFRA;
            break;
        case MLAN_BSS_MODE_IBSS:
            mode = IW_MODE_ADHOC;
            break;
        default:
            mode = IW_MODE_AUTO;
            break;
        }
    }
  done:
    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);
    LEAVE();
    return mode;
}

/** 
 *  @brief Get RSSI info
 *
 *  @param priv         A pointer to moal_private structure
 *  @param wait_option  Wait option
 *  @param signal       A pointer tp mlan_ds_get_signal structure
 *
 *  @return             MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
mlan_status
woal_get_signal_info(moal_private * priv, t_u8 wait_option,
                     mlan_ds_get_signal * signal)
{
    int ret = 0;
    mlan_ds_get_info *info = NULL;
    mlan_ioctl_req *req = NULL;
    mlan_status status = MLAN_STATUS_SUCCESS;
    ENTER();

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    /* Fill request buffer */
    info = (mlan_ds_get_info *) req->pbuf;
    info->sub_command = MLAN_OID_GET_SIGNAL;
    info->param.signal.selector = ALL_RSSI_INFO_MASK;
    req->req_id = MLAN_IOCTL_GET_INFO;
    req->action = MLAN_ACT_GET;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, wait_option);
    if (status == MLAN_STATUS_SUCCESS) {
        if (signal)
            memcpy(signal, &info->param.signal, sizeof(mlan_ds_get_signal));
        if (info->param.signal.selector & BCN_RSSI_AVG_MASK)
            priv->w_stats.qual.level = info->param.signal.bcn_rssi_avg;
        if (info->param.signal.selector & BCN_NF_AVG_MASK)
            priv->w_stats.qual.noise = info->param.signal.bcn_nf_avg;
    }
  done:
    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);
    LEAVE();
    return status;
}

/** 
 *  @brief Get statistics information
 *
 *  @param priv         A pointer to moal_private structure
 *  @param wait_option  Wait option
 *  @param stats        A pointer to mlan_ds_get_stats structure
 *
 *  @return             MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
mlan_status
woal_get_stats_info(moal_private * priv, t_u8 wait_option,
                    mlan_ds_get_stats * stats)
{
    int ret = 0;
    mlan_ds_get_info *info = NULL;
    mlan_ioctl_req *req = NULL;
    mlan_status status = MLAN_STATUS_SUCCESS;
    ENTER();

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    /* Fill request buffer */
    info = (mlan_ds_get_info *) req->pbuf;
    info->sub_command = MLAN_OID_GET_STATS;
    req->req_id = MLAN_IOCTL_GET_INFO;
    req->action = MLAN_ACT_GET;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, wait_option);
    if (status == MLAN_STATUS_SUCCESS) {
        if (stats)
            memcpy(stats, &info->param.stats, sizeof(mlan_ds_get_stats));
        priv->w_stats.discard.fragment = info->param.stats.fcs_error;
        priv->w_stats.discard.retries = info->param.stats.retry;
        priv->w_stats.discard.misc = info->param.stats.ack_failure;
    }
  done:
    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);
    LEAVE();
    return status;
}

/** 
 *  @brief Get data rates
 *
 *  @param priv          A pointer to moal_private structure
 *  @param wait_option   Wait option
 *  @param m_rates       A pointer to moal_802_11_rates structure
 *
 *  @return              MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
mlan_status
woal_get_data_rates(moal_private * priv, t_u8 wait_option,
                    moal_802_11_rates * m_rates)
{
    int ret = 0;
    mlan_ds_rate *rate = NULL;
    mlan_ioctl_req *req = NULL;
    mlan_status status = MLAN_STATUS_SUCCESS;
    ENTER();

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_rate));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    /* Fill request buffer */
    rate = (mlan_ds_rate *) req->pbuf;
    rate->sub_command = MLAN_OID_SUPPORTED_RATES;
    req->req_id = MLAN_IOCTL_RATE;
    req->action = MLAN_ACT_GET;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, wait_option);
    if (status == MLAN_STATUS_SUCCESS) {
        if (m_rates)
            m_rates->num_of_rates =
                woal_copy_rates(m_rates->rates, m_rates->num_of_rates,
                                rate->param.rates, MLAN_SUPPORTED_RATES);
    }
  done:
    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);
    LEAVE();
    return status;
}

/** 
 *  @brief Get channel list
 *
 *  @param priv            A pointer to moal_private structure
 *  @param wait_option     Wait option
 *  @param chan_list       A pointer to mlan_chan_list structure
 *
 *  @return                MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
mlan_status
woal_get_channel_list(moal_private * priv, t_u8 wait_option,
                      mlan_chan_list * chan_list)
{
    int ret = 0;
    mlan_ds_bss *bss = NULL;
    mlan_ioctl_req *req = NULL;
    mlan_status status = MLAN_STATUS_SUCCESS;
    ENTER();

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    /* Fill request buffer */
    bss = (mlan_ds_bss *) req->pbuf;
    bss->sub_command = MLAN_OID_BSS_CHANNEL_LIST;
    req->req_id = MLAN_IOCTL_BSS;
    req->action = MLAN_ACT_GET;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, wait_option);
    if (status == MLAN_STATUS_SUCCESS) {
        if (chan_list) {
            memcpy(chan_list, &bss->param.chanlist, sizeof(mlan_chan_list));
        }
    }
  done:
    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);
    LEAVE();
    return status;
}

/** 
 *  @brief Get scan table
 *
 *  @param priv         A pointer to moal_private structure
 *  @param wait_option  Wait option
 *  @param scan_resp    A pointer to mlan_scan_resp structure
 *
 *  @return             MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
mlan_status
woal_get_scan_table(moal_private * priv, t_u8 wait_option,
                    mlan_scan_resp * scan_resp)
{
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_scan *scan = NULL;
    mlan_status status = MLAN_STATUS_SUCCESS;
    ENTER();

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_scan));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    /* Fill request buffer */
    scan = (mlan_ds_scan *) req->pbuf;
    scan->sub_command = MLAN_OID_SCAN_NORMAL;
    req->req_id = MLAN_IOCTL_SCAN;
    req->action = MLAN_ACT_GET;
    memcpy((void *) &scan->param.scan_resp, (void *) scan_resp,
           sizeof(mlan_scan_resp));

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, wait_option);
    if (status == MLAN_STATUS_SUCCESS) {
        if (scan_resp) {
            memcpy(scan_resp, &scan->param.scan_resp, sizeof(mlan_scan_resp));
        }
    }

  done:
    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);
    LEAVE();
    return status;
}

/** 
 *  @brief Set authentication mode
 *
 *  @param priv                 A pointer to moal_private structure
 *  @param wait_option          Wait option
 *  @param auth_mode            Authentication mode
 *
 *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
mlan_status
woal_set_auth_mode(moal_private * priv, t_u8 wait_option, t_u32 auth_mode)
{
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_sec_cfg *sec = NULL;
    mlan_status status = MLAN_STATUS_SUCCESS;
    ENTER();

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    /* Fill request buffer */
    sec = (mlan_ds_sec_cfg *) req->pbuf;
    sec->sub_command = MLAN_OID_SEC_CFG_AUTH_MODE;
    req->req_id = MLAN_IOCTL_SEC_CFG;
    req->action = MLAN_ACT_SET;
    sec->param.auth_mode = auth_mode;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, wait_option);
  done:
    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);
    LEAVE();
    return status;
}

/** 
 *  @brief Get authentication mode
 *
 *  @param priv                 A pointer to moal_private structure
 *  @param wait_option          Wait option
 *  @param auth_mode            A pointer to authentication mode
 *
 *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
mlan_status
woal_get_auth_mode(moal_private * priv, t_u8 wait_option, t_u32 * auth_mode)
{
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_sec_cfg *sec = NULL;
    mlan_status status = MLAN_STATUS_SUCCESS;
    ENTER();

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    /* Fill request buffer */
    sec = (mlan_ds_sec_cfg *) req->pbuf;
    sec->sub_command = MLAN_OID_SEC_CFG_AUTH_MODE;
    req->req_id = MLAN_IOCTL_SEC_CFG;
    req->action = MLAN_ACT_GET;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, wait_option);
    if (status == MLAN_STATUS_SUCCESS && auth_mode) {
        *auth_mode = sec->param.auth_mode;
    }
  done:
    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);
    LEAVE();
    return status;
}

/** 
 *  @brief Set encrypt mode
 *
 *  @param priv                 A pointer to moal_private structure
 *  @param wait_option          Wait option
 *  @param encrypt_mode         Encryption mode
 *
 *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
mlan_status
woal_set_encrypt_mode(moal_private * priv, t_u8 wait_option, t_u32 encrypt_mode)
{
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_sec_cfg *sec = NULL;
    mlan_status status = MLAN_STATUS_SUCCESS;
    ENTER();

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    /* Fill request buffer */
    sec = (mlan_ds_sec_cfg *) req->pbuf;
    sec->sub_command = MLAN_OID_SEC_CFG_ENCRYPT_MODE;
    req->req_id = MLAN_IOCTL_SEC_CFG;
    req->action = MLAN_ACT_SET;
    sec->param.encrypt_mode = encrypt_mode;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, wait_option);
  done:
    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);
    LEAVE();
    return status;
}

/** 
 *  @brief Get encrypt mode
 *
 *  @param priv                 A pointer to moal_private structure
 *  @param wait_option          Wait option
 *  @param encrypt_mode         A pointer to encrypt mode
 *
 *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
mlan_status
woal_get_encrypt_mode(moal_private * priv, t_u8 wait_option,
                      t_u32 * encrypt_mode)
{
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_sec_cfg *sec = NULL;
    mlan_status status = MLAN_STATUS_SUCCESS;

    ENTER();

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    /* Fill request buffer */
    sec = (mlan_ds_sec_cfg *) req->pbuf;
    sec->sub_command = MLAN_OID_SEC_CFG_ENCRYPT_MODE;
    req->req_id = MLAN_IOCTL_SEC_CFG;
    req->action = MLAN_ACT_GET;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, wait_option);
    if (status == MLAN_STATUS_SUCCESS && encrypt_mode) {
        *encrypt_mode = sec->param.encrypt_mode;
    }
  done:
    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);
    LEAVE();
    return status;
}

/** 
 *  @brief Set wpa enable
 *
 *  @param priv                 A pointer to moal_private structure
 *  @param wait_option          Wait option
 *  @param enable               MTRUE or MFALSE
 *
 *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
mlan_status
woal_set_wpa_enable(moal_private * priv, t_u8 wait_option, t_u32 enable)
{
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_sec_cfg *sec = NULL;
    mlan_status status = MLAN_STATUS_SUCCESS;
    ENTER();

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    /* Fill request buffer */
    sec = (mlan_ds_sec_cfg *) req->pbuf;
    sec->sub_command = MLAN_OID_SEC_CFG_WPA_ENABLED;
    req->req_id = MLAN_IOCTL_SEC_CFG;
    req->action = MLAN_ACT_SET;
    sec->param.wpa_enabled = enable;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, wait_option);
  done:
    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);
    LEAVE();
    return status;
}

/** 
 *  @brief Get WPA enable
 *
 *  @param priv                 A pointer to moal_private structure
 *  @param wait_option          Wait option
 *  @param enable               A pointer to wpa enable status
 *
 *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
mlan_status
woal_get_wpa_enable(moal_private * priv, t_u8 wait_option, t_u32 * enable)
{
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_sec_cfg *sec = NULL;
    mlan_status status = MLAN_STATUS_SUCCESS;

    ENTER();

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    /* Fill request buffer */
    sec = (mlan_ds_sec_cfg *) req->pbuf;
    sec->sub_command = MLAN_OID_SEC_CFG_WPA_ENABLED;
    req->req_id = MLAN_IOCTL_SEC_CFG;
    req->action = MLAN_ACT_GET;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, wait_option);
    if (status == MLAN_STATUS_SUCCESS && enable) {
        *enable = sec->param.wpa_enabled;
    }
  done:
    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);
    LEAVE();
    return status;
}

/** 
 *  @brief Find the best network to associate
 *
 *  @param priv                 A pointer to moal_private structure
 *  @param wait_option          Wait option  
 *  @param ssid_bssid           A pointer to mlan_ssid_bssid structure
 *
 *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
mlan_status
woal_find_best_network(moal_private * priv, t_u8 wait_option,
                       mlan_ssid_bssid * ssid_bssid)
{
    mlan_ioctl_req *req = NULL;
    mlan_ds_bss *bss = NULL;
    mlan_status ret = MLAN_STATUS_SUCCESS;
    t_u8 *mac = 0;

    ENTER();

    if (!ssid_bssid) {
        ret = MLAN_STATUS_FAILURE;
        goto done;
    }

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
    if (req == NULL) {
        ret = MLAN_STATUS_FAILURE;
        goto done;
    }

    /* Fill request buffer */
    bss = (mlan_ds_bss *) req->pbuf;
    req->req_id = MLAN_IOCTL_BSS;
    req->action = MLAN_ACT_GET;
    bss->sub_command = MLAN_OID_BSS_FIND_BSS;

    memcpy(&bss->param.ssid_bssid, ssid_bssid, sizeof(mlan_ssid_bssid));

    /* Send IOCTL request to MLAN */
    ret = woal_request_ioctl(priv, req, wait_option);
    if (ret == MLAN_STATUS_SUCCESS) {
        memcpy(ssid_bssid, &bss->param.ssid_bssid, sizeof(mlan_ssid_bssid));
        mac = (t_u8 *) & ssid_bssid->bssid;
        PRINTM(MCMND, "Find network: ssid=%s, %02x:%02x:%02x:%02x:%02x:%02x\n",
               ssid_bssid->ssid.ssid, mac[0], mac[1], mac[2], mac[3], mac[4],
               mac[5]);
    }

  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/** 
 *  @brief Request a scan
 *
 *  @param priv                 A pointer to moal_private structure
 *  @param wait_option          Wait option  
 *  @param req_ssid             A pointer to mlan_802_11_ssid structure
 *
 *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
mlan_status
woal_request_scan(moal_private * priv,
                  t_u8 wait_option, mlan_802_11_ssid * req_ssid)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    mlan_ioctl_req *ioctl_req = NULL;
    mlan_ds_scan *scan = NULL;
    mlan_status status = MLAN_STATUS_SUCCESS;
    ENTER();

    if (MOAL_ACQ_SEMAPHORE_BLOCK(&priv->async_sem)) {
        PRINTM(MERROR, "Acquire semaphore error, request_scan\n");
        LEAVE();
        return MLAN_STATUS_FAILURE;
    }
    priv->scan_pending_on_block = MTRUE;

    /* Allocate an IOCTL request buffer */
    ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_scan));
    if (ioctl_req == NULL) {
        ret = MLAN_STATUS_FAILURE;
        goto done;
    }

    scan = (mlan_ds_scan *) ioctl_req->pbuf;

    if (req_ssid && req_ssid->ssid_len != 0) {
        /* Specific SSID scan */
        ioctl_req->req_id = MLAN_IOCTL_SCAN;
        ioctl_req->action = MLAN_ACT_SET;

        scan->sub_command = MLAN_OID_SCAN_SPECIFIC_SSID;

        memcpy(scan->param.scan_req.scan_ssid.ssid,
               req_ssid->ssid, req_ssid->ssid_len);
        scan->param.scan_req.scan_ssid.ssid_len = req_ssid->ssid_len;
    } else {
        /* Normal scan */
        ioctl_req->req_id = MLAN_IOCTL_SCAN;
        ioctl_req->action = MLAN_ACT_SET;

        scan->sub_command = MLAN_OID_SCAN_NORMAL;
    }
    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, ioctl_req, wait_option);
    if (status == MLAN_STATUS_FAILURE) {
        ret = MLAN_STATUS_FAILURE;
        goto done;
    }
  done:
    if ((ioctl_req) && (status != MLAN_STATUS_PENDING))
        kfree(ioctl_req);
    if (ret == MLAN_STATUS_FAILURE) {
        priv->scan_pending_on_block = MFALSE;
        MOAL_REL_SEMAPHORE(&priv->async_sem);
    }
    LEAVE();
    return ret;
}

/** 
 *  @brief Set ewpa mode
 *
 *  @param priv                 A pointer to moal_private structure
 *  @param wait_option          Wait option
 *  @param ssid_bssid           A pointer to mlan_ssid_bssid structure
 *
 *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
mlan_status
woal_set_ewpa_mode(moal_private * priv, t_u8 wait_option,
                   mlan_ssid_bssid * ssid_bssid)
{
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_sec_cfg *sec = NULL;
    mlan_status status = MLAN_STATUS_SUCCESS;

    ENTER();

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto error;
    }
    /* Fill request buffer */
    sec = (mlan_ds_sec_cfg *) req->pbuf;
    sec->sub_command = MLAN_OID_SEC_CFG_PASSPHRASE;
    req->req_id = MLAN_IOCTL_SEC_CFG;
    req->action = MLAN_ACT_GET;

    /* Try Get All */
    memset(&sec->param.passphrase, 0, sizeof(mlan_ds_passphrase));
    memcpy(&sec->param.passphrase.ssid, &ssid_bssid->ssid,
           sizeof(sec->param.passphrase.ssid));
    memcpy(&sec->param.passphrase.bssid, &ssid_bssid->bssid,
           MLAN_MAC_ADDR_LENGTH);
    sec->param.passphrase.psk_type = MLAN_PSK_QUERY;

    /* Send IOCTL request to MLAN */
    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, wait_option))
        goto error;
    sec->param.ewpa_enabled = MFALSE;
    if (sec->param.passphrase.psk_type == MLAN_PSK_PASSPHRASE) {
        if (sec->param.passphrase.psk.passphrase.passphrase_len > 0) {
            sec->param.ewpa_enabled = MTRUE;
        }
    } else if (sec->param.passphrase.psk_type == MLAN_PSK_PMK)
        sec->param.ewpa_enabled = MTRUE;

    sec->sub_command = MLAN_OID_SEC_CFG_EWPA_ENABLED;
    req->action = MLAN_ACT_SET;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, wait_option);

  error:
    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);
    LEAVE();
    return status;
}

/** 
 *  @brief Change Adhoc Channel
 *   
 *  @param priv 		A pointer to moal_private structure
 *  @param channel		The channel to be set. 
 *
 *  @return 	   		MLAN_STATUS_SUCCESS--success, MLAN_STATUS_FAILURE--fail
 */
mlan_status
woal_change_adhoc_chan(moal_private * priv, int channel)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    mlan_bss_info bss_info;
    mlan_ds_bss *bss = NULL;
    mlan_ioctl_req *req = NULL;

    ENTER();

    memset(&bss_info, 0, sizeof(bss_info));

    /* Get BSS information */
    if (MLAN_STATUS_SUCCESS !=
        woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info)) {
        ret = MLAN_STATUS_FAILURE;
        goto done;
    }
    if (bss_info.bss_mode == MLAN_BSS_MODE_INFRA) {
        ret = MLAN_STATUS_SUCCESS;
        goto done;
    }

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
    if (req == NULL) {
        ret = MLAN_STATUS_FAILURE;
        goto done;
    }

    /* Get current channel */
    bss = (mlan_ds_bss *) req->pbuf;
    bss->sub_command = MLAN_OID_IBSS_CHANNEL;
    req->req_id = MLAN_IOCTL_BSS;
    req->action = MLAN_ACT_GET;

    /* Send IOCTL request to MLAN */
    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = MLAN_STATUS_FAILURE;
        goto done;
    }
    if (bss->param.bss_chan.channel == channel) {
        ret = MLAN_STATUS_SUCCESS;
        goto done;
    }
    PRINTM(MCMND, "Updating Channel from %d to %d\n",
           (int) bss->param.bss_chan.channel, channel);

    if (bss_info.media_connected != MTRUE) {
        ret = MLAN_STATUS_SUCCESS;
        goto done;
    }

    /* Do disonnect */
    bss->sub_command = MLAN_OID_BSS_STOP;
    memset((t_u8 *) & bss->param.bssid, 0, ETH_ALEN);

    /* Send IOCTL request to MLAN */
    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = MLAN_STATUS_FAILURE;
        goto done;
    }

    /* Do specific SSID scanning */
    if (MLAN_STATUS_SUCCESS !=
        woal_request_scan(priv, MOAL_IOCTL_WAIT, &bss_info.ssid)) {
        ret = MLAN_STATUS_FAILURE;
        goto done;
    }
    /* Start/Join Adhoc network */
    bss->sub_command = MLAN_OID_BSS_START;
    memset(&bss->param.ssid_bssid, 0, sizeof(mlan_ssid_bssid));
    memcpy(&bss->param.ssid_bssid.ssid, &bss_info.ssid,
           sizeof(mlan_802_11_ssid));

    /* Send IOCTL request to MLAN */
    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = MLAN_STATUS_FAILURE;
    }

  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}

/** 
 *  @brief enable wep key 
 *  
 *  @param priv                 A pointer to moal_private structure
 *  @param wait_option          Wait option
 *
 *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
mlan_status
woal_enable_wep_key(moal_private * priv, t_u8 wait_option)
{
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_sec_cfg *sec = NULL;
    mlan_status status = MLAN_STATUS_SUCCESS;
    ENTER();

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    /* Fill request buffer */
    sec = (mlan_ds_sec_cfg *) req->pbuf;
    sec->sub_command = MLAN_OID_SEC_CFG_ENCRYPT_KEY;
    req->req_id = MLAN_IOCTL_SEC_CFG;
    req->action = MLAN_ACT_SET;
    sec->param.encrypt_key.key_disable = MFALSE;
    sec->param.encrypt_key.key_len = 0;
    sec->param.encrypt_key.is_current_wep_key = MTRUE;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, wait_option);
  done:
    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);
    LEAVE();
    return status;
}

#if WIRELESS_EXT > 14

/** 
 *  @brief This function sends customized event to application.
 *  
 *  @param priv    A pointer to moal_private structure
 *  @param str	   A pointer to event string
 *
 *  @return 	   N/A
 */
void
woal_send_iwevcustom_event(moal_private * priv, t_s8 * str)
{
    union iwreq_data iwrq;
    char buf[50];

    ENTER();

    memset(&iwrq, 0, sizeof(union iwreq_data));
    memset(buf, 0, sizeof(buf));

    snprintf(buf, sizeof(buf) - 1, "%s", str);

    iwrq.data.pointer = buf;
    iwrq.data.length = strlen(buf) + 1 + IW_EV_LCP_LEN;

    /* Send Event to upper layer */
    wireless_send_event(priv->netdev, IWEVCUSTOM, &iwrq, buf);
    PRINTM(MINFO, "Wireless event %s is sent to application\n", str);

    LEAVE();
    return;
}
#endif

#if WIRELESS_EXT >= 18
/** 
 *  @brief This function sends mic error event to application.
 *  
 *  @param priv    A pointer to moal_private structure
 *  @param event   MIC MERROR EVENT. 
 *
 *  @return 	   N/A
 */
void
woal_send_mic_error_event(moal_private * priv, t_u32 event)
{
    union iwreq_data iwrq;
    struct iw_michaelmicfailure mic;

    ENTER();

    memset(&iwrq, 0, sizeof(iwrq));
    memset(&mic, 0, sizeof(mic));
    if (event == MLAN_EVENT_ID_FW_MIC_ERR_UNI)
        mic.flags = IW_MICFAILURE_PAIRWISE;
    else
        mic.flags = IW_MICFAILURE_GROUP;
    iwrq.data.pointer = &mic;
    iwrq.data.length = sizeof(mic);

    wireless_send_event(priv->netdev, IWEVMICHAELMICFAILURE, &iwrq,
                        (char *) &mic);

    LEAVE();
    return;
}
#endif

/** 
 *  @brief Handle ioctl resp 
 *   
 *  @param priv 	Pointer to moal_private structure
 *  @param req		Pointer to mlan_ioctl_req structure
 *
 *  @return    		N/A
 */
void
woal_process_ioctl_resp(moal_private * priv, mlan_ioctl_req * req)
{
    ENTER();

    if (priv == NULL)
        return;
    switch (req->req_id) {
    case MLAN_IOCTL_GET_INFO:
        woal_ioctl_get_info_resp(priv, (mlan_ds_get_info *) req->pbuf);
        break;
    case MLAN_IOCTL_BSS:
        woal_ioctl_get_bss_resp(priv, (mlan_ds_bss *) req->pbuf);
    default:
        break;
    }

    LEAVE();
    return;
}
