net: wireless: Update SD8897 WLAN/BT driver to 463
Marc Yang [Fri, 20 Dec 2013 22:43:00 +0000 (14:43 -0800)]
Signed-off-by: Marc Yang <yangyang@marvell.com>

- update SD8897 driver to 463

Bug 1318052

Change-Id: I00f81bc5219c670b2cf35e5ca5b57096dc7ca244
Signed-off-by: Manikanta <mmaddireddy@nvidia.com>
Reviewed-on: http://git-master/r/355988
Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>

84 files changed:
drivers/bluetooth/sd8897/bt/bt_drv.h
drivers/bluetooth/sd8897/bt/bt_init.c
drivers/bluetooth/sd8897/bt/bt_main.c
drivers/bluetooth/sd8897/bt/bt_proc.c
drivers/bluetooth/sd8897/bt/bt_sdio.h
drivers/bluetooth/sd8897/bt/bt_sdiommc.c
drivers/bluetooth/sd8897/bt/hci_wrapper.h
drivers/bluetooth/sd8897/bt/mbt_char.c
drivers/bluetooth/sd8897/bt/mbt_char.h
drivers/net/wireless/sd8897/mlan/mlan.h
drivers/net/wireless/sd8897/mlan/mlan_11ac.c
drivers/net/wireless/sd8897/mlan/mlan_11ac.h
drivers/net/wireless/sd8897/mlan/mlan_11d.c
drivers/net/wireless/sd8897/mlan/mlan_11h.c
drivers/net/wireless/sd8897/mlan/mlan_11h.h
drivers/net/wireless/sd8897/mlan/mlan_11n.c
drivers/net/wireless/sd8897/mlan/mlan_11n.h
drivers/net/wireless/sd8897/mlan/mlan_11n_aggr.c
drivers/net/wireless/sd8897/mlan/mlan_11n_aggr.h
drivers/net/wireless/sd8897/mlan/mlan_11n_rxreorder.c
drivers/net/wireless/sd8897/mlan/mlan_11n_rxreorder.h
drivers/net/wireless/sd8897/mlan/mlan_cfp.c
drivers/net/wireless/sd8897/mlan/mlan_cmdevt.c
drivers/net/wireless/sd8897/mlan/mlan_decl.h
drivers/net/wireless/sd8897/mlan/mlan_fw.h
drivers/net/wireless/sd8897/mlan/mlan_ieee.h
drivers/net/wireless/sd8897/mlan/mlan_init.c
drivers/net/wireless/sd8897/mlan/mlan_init.h
drivers/net/wireless/sd8897/mlan/mlan_ioctl.h
drivers/net/wireless/sd8897/mlan/mlan_join.c
drivers/net/wireless/sd8897/mlan/mlan_join.h
drivers/net/wireless/sd8897/mlan/mlan_main.h
drivers/net/wireless/sd8897/mlan/mlan_meas.c
drivers/net/wireless/sd8897/mlan/mlan_meas.h
drivers/net/wireless/sd8897/mlan/mlan_misc.c
drivers/net/wireless/sd8897/mlan/mlan_module.c
drivers/net/wireless/sd8897/mlan/mlan_scan.c
drivers/net/wireless/sd8897/mlan/mlan_sdio.c
drivers/net/wireless/sd8897/mlan/mlan_sdio.h
drivers/net/wireless/sd8897/mlan/mlan_shim.c
drivers/net/wireless/sd8897/mlan/mlan_sta_cmd.c
drivers/net/wireless/sd8897/mlan/mlan_sta_cmdresp.c
drivers/net/wireless/sd8897/mlan/mlan_sta_event.c
drivers/net/wireless/sd8897/mlan/mlan_sta_ioctl.c
drivers/net/wireless/sd8897/mlan/mlan_sta_rx.c
drivers/net/wireless/sd8897/mlan/mlan_sta_tx.c
drivers/net/wireless/sd8897/mlan/mlan_txrx.c
drivers/net/wireless/sd8897/mlan/mlan_uap.h
drivers/net/wireless/sd8897/mlan/mlan_uap_cmdevent.c
drivers/net/wireless/sd8897/mlan/mlan_uap_ioctl.c
drivers/net/wireless/sd8897/mlan/mlan_uap_txrx.c
drivers/net/wireless/sd8897/mlan/mlan_util.h
drivers/net/wireless/sd8897/mlan/mlan_wmm.c
drivers/net/wireless/sd8897/mlan/mlan_wmm.h
drivers/net/wireless/sd8897/mlinux/mlan.h
drivers/net/wireless/sd8897/mlinux/mlan_decl.h
drivers/net/wireless/sd8897/mlinux/mlan_ieee.h
drivers/net/wireless/sd8897/mlinux/mlan_ioctl.h
drivers/net/wireless/sd8897/mlinux/moal_cfg80211.c
drivers/net/wireless/sd8897/mlinux/moal_cfg80211.h
drivers/net/wireless/sd8897/mlinux/moal_debug.c
drivers/net/wireless/sd8897/mlinux/moal_eth_ioctl.c
drivers/net/wireless/sd8897/mlinux/moal_eth_ioctl.h
drivers/net/wireless/sd8897/mlinux/moal_ioctl.c
drivers/net/wireless/sd8897/mlinux/moal_main.c
drivers/net/wireless/sd8897/mlinux/moal_main.h
drivers/net/wireless/sd8897/mlinux/moal_priv.c
drivers/net/wireless/sd8897/mlinux/moal_priv.h
drivers/net/wireless/sd8897/mlinux/moal_proc.c
drivers/net/wireless/sd8897/mlinux/moal_sdio.h
drivers/net/wireless/sd8897/mlinux/moal_sdio_mmc.c
drivers/net/wireless/sd8897/mlinux/moal_shim.c
drivers/net/wireless/sd8897/mlinux/moal_shim.h
drivers/net/wireless/sd8897/mlinux/moal_sta_cfg80211.c
drivers/net/wireless/sd8897/mlinux/moal_sta_cfg80211.h
drivers/net/wireless/sd8897/mlinux/moal_uap.c
drivers/net/wireless/sd8897/mlinux/moal_uap.h
drivers/net/wireless/sd8897/mlinux/moal_uap_cfg80211.c
drivers/net/wireless/sd8897/mlinux/moal_uap_cfg80211.h
drivers/net/wireless/sd8897/mlinux/moal_uap_priv.c
drivers/net/wireless/sd8897/mlinux/moal_uap_priv.h
drivers/net/wireless/sd8897/mlinux/moal_uap_wext.c
drivers/net/wireless/sd8897/mlinux/moal_wext.c
drivers/net/wireless/sd8897/mlinux/moal_wext.h

index 2a8f8f5..2b416a8 100644 (file)
@@ -2,7 +2,7 @@
  *  @brief This header file contains global constant/enum definitions,
  *  global variable declaration.
  *
- *  Copyright (C) 2007-2012, Marvell International Ltd.
+ *  Copyright (C) 2007-2013, 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
index 13d7ed3..942cf0d 100644 (file)
@@ -3,7 +3,7 @@
   * @brief This file contains the init functions for BlueTooth
   * driver.
   *
-  * Copyright (C) 2011-2012, Marvell International Ltd.
+  * Copyright (C) 2011-2013, 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
index 7e79962..086ca4b 100644 (file)
@@ -4,7 +4,7 @@
   * driver. It includes init, exit, open, close and main
   * thread etc..
   *
-  * Copyright (C) 2007-2012, Marvell International Ltd.
+  * Copyright (C) 2007-2013, 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
@@ -29,7 +29,7 @@
   *
   * @section copyright_sec Copyright
   *
-  * Copyright (C) 2007-2012, Marvell International Ltd.
+  * Copyright (C) 2007-2013, Marvell International Ltd.
   *
   */
 
@@ -245,7 +245,7 @@ check_evtpkt(bt_private * priv, struct sk_buff *skb)
        struct hci_event_hdr *hdr = (struct hci_event_hdr *)skb->data;
        struct hci_ev_cmd_complete *ec;
        u16 opcode, ocf;
-       u8 ret = BT_STATUS_SUCCESS;
+       int ret = BT_STATUS_SUCCESS;
        ENTER();
        if (!priv->bt_dev.sendcmdflag) {
                ret = BT_STATUS_FAILURE;
@@ -339,7 +339,7 @@ exit:
 int
 bt_process_event(bt_private * priv, struct sk_buff *skb)
 {
-       u8 ret = BT_STATUS_SUCCESS;
+       int ret = BT_STATUS_SUCCESS;
        struct m_dev *m_dev = &(priv->bt_dev.m_dev[BT_SEQ]);
        BT_EVENT *pevent;
 
@@ -525,7 +525,7 @@ int
 bt_send_reset_command(bt_private * priv)
 {
        struct sk_buff *skb = NULL;
-       u8 ret = BT_STATUS_SUCCESS;
+       int ret = BT_STATUS_SUCCESS;
        BT_HCI_CMD *pcmd;
        ENTER();
        skb = bt_skb_alloc(sizeof(BT_HCI_CMD), GFP_ATOMIC);
@@ -579,7 +579,7 @@ int
 bt_send_module_cfg_cmd(bt_private * priv, int subcmd)
 {
        struct sk_buff *skb = NULL;
-       u8 ret = BT_STATUS_SUCCESS;
+       int ret = BT_STATUS_SUCCESS;
        BT_CMD *pcmd;
        ENTER();
        skb = bt_skb_alloc(sizeof(BT_CMD), GFP_ATOMIC);
@@ -633,7 +633,7 @@ int
 bt_enable_ps(bt_private * priv)
 {
        struct sk_buff *skb = NULL;
-       u8 ret = BT_STATUS_SUCCESS;
+       int ret = BT_STATUS_SUCCESS;
        BT_CMD *pcmd;
        ENTER();
        skb = bt_skb_alloc(sizeof(BT_CMD), GFP_ATOMIC);
@@ -687,7 +687,7 @@ int
 bt_send_hscfg_cmd(bt_private * priv)
 {
        struct sk_buff *skb = NULL;
-       u8 ret = BT_STATUS_SUCCESS;
+       int ret = BT_STATUS_SUCCESS;
        BT_CMD *pcmd;
        ENTER();
        skb = bt_skb_alloc(sizeof(BT_CMD), GFP_ATOMIC);
@@ -733,7 +733,7 @@ int
 bt_send_sdio_pull_ctrl_cmd(bt_private * priv)
 {
        struct sk_buff *skb = NULL;
-       u8 ret = BT_STATUS_SUCCESS;
+       int ret = BT_STATUS_SUCCESS;
        BT_CMD *pcmd;
        ENTER();
        skb = bt_skb_alloc(sizeof(BT_CMD), GFP_ATOMIC);
@@ -787,7 +787,7 @@ int
 fm_set_intr_mask(bt_private * priv, u32 mask)
 {
        struct sk_buff *skb = NULL;
-       u8 ret = BT_STATUS_SUCCESS;
+       int ret = BT_STATUS_SUCCESS;
        BT_CMD *pcmd;
 
        ENTER();
@@ -834,7 +834,7 @@ int
 bt_enable_hs(bt_private * priv)
 {
        struct sk_buff *skb = NULL;
-       u8 ret = BT_STATUS_SUCCESS;
+       int ret = BT_STATUS_SUCCESS;
        BT_CMD *pcmd;
        ENTER();
        skb = bt_skb_alloc(sizeof(BT_CMD), GFP_ATOMIC);
@@ -895,7 +895,7 @@ int
 bt_set_ble_deepsleep(bt_private * priv, int mode)
 {
        struct sk_buff *skb = NULL;
-       u8 ret = BT_STATUS_SUCCESS;
+       int ret = BT_STATUS_SUCCESS;
        BT_BLE_CMD *pcmd;
        ENTER();
        skb = bt_skb_alloc(sizeof(BT_BLE_CMD), GFP_ATOMIC);
@@ -940,7 +940,7 @@ int
 bt_get_fw_version(bt_private * priv)
 {
        struct sk_buff *skb = NULL;
-       u8 ret = BT_STATUS_SUCCESS;
+       int ret = BT_STATUS_SUCCESS;
        BT_HCI_CMD *pcmd;
        ENTER();
        skb = bt_skb_alloc(sizeof(BT_HCI_CMD), GFP_ATOMIC);
@@ -985,7 +985,7 @@ int
 bt_set_mac_address(bt_private * priv, u8 * mac)
 {
        struct sk_buff *skb = NULL;
-       u8 ret = BT_STATUS_SUCCESS;
+       int ret = BT_STATUS_SUCCESS;
        BT_HCI_CMD *pcmd;
        int i = 0;
        ENTER();
@@ -1037,7 +1037,7 @@ int
 bt_load_cal_data(bt_private * priv, u8 * config_data, u8 * mac)
 {
        struct sk_buff *skb = NULL;
-       u8 ret = BT_STATUS_SUCCESS;
+       int ret = BT_STATUS_SUCCESS;
        BT_CMD *pcmd;
        int i = 0;
        /* u8 config_data[28] = {0x37 0x01 0x1c 0x00 0xFF 0xFF 0xFF 0xFF 0x01
@@ -1101,7 +1101,7 @@ int
 bt_load_cal_data_ext(bt_private * priv, u8 * config_data, u32 cfg_data_len)
 {
        struct sk_buff *skb = NULL;
-       u8 ret = BT_STATUS_SUCCESS;
+       int ret = BT_STATUS_SUCCESS;
        BT_CMD *pcmd;
 
        ENTER();
@@ -1151,7 +1151,7 @@ int
 bt_write_reg(bt_private * priv, u8 type, u32 offset, u16 value)
 {
        struct sk_buff *skb = NULL;
-       u8 ret = BT_STATUS_SUCCESS;
+       int ret = BT_STATUS_SUCCESS;
        BT_CSU_CMD *pcmd;
        ENTER();
        skb = bt_skb_alloc(sizeof(BT_CSU_CMD), GFP_ATOMIC);
@@ -1226,7 +1226,7 @@ bt_restore_tx_queue(bt_private * priv)
 int
 bt_prepare_command(bt_private * priv)
 {
-       u8 ret = BT_STATUS_SUCCESS;
+       int ret = BT_STATUS_SUCCESS;
        ENTER();
        if (priv->bt_dev.hscfgcmd) {
                priv->bt_dev.hscfgcmd = 0;
@@ -1825,8 +1825,7 @@ sbi_register_conf_dpc(bt_private * priv)
                }
        }
 #ifdef SDIO_SUSPEND_RESUME
-
-       priv->bt_dev.gpio_gap = 0x0464;
+       priv->bt_dev.gpio_gap = 0x0864;
        ret = bt_send_hscfg_cmd(priv);
        if (ret < 0) {
                PRINTM(FATAL, "Send HSCFG failed!\n");
@@ -1891,7 +1890,7 @@ sbi_register_conf_dpc(bt_private * priv)
 
                /** chmod & chown for BT char device */
                mbtchar_chown(dev_file, AID_SYSTEM, AID_BLUETOOTH);
-               mbtchar_chmod(dev_file, 0666);
+               mbtchar_chmod(dev_file, 0660);
 
                /** create proc device */
                snprintf(priv->bt_dev.m_dev[BT_SEQ].name,
@@ -1949,7 +1948,7 @@ sbi_register_conf_dpc(bt_private * priv)
                                  MODULE_NAME, fm_dev->name);
 
                /** chmod for FM char device */
-               mbtchar_chmod(dev_file, 0666);
+               mbtchar_chmod(dev_file, 0660);
 
                /** create proc device */
                snprintf(priv->bt_dev.m_dev[FM_SEQ].name,
index ad9a6e9..7fd419b 100644 (file)
@@ -2,7 +2,7 @@
   *
   * @brief This file handle the functions for proc files
   *
-  * Copyright (C) 2007-2012, Marvell International Ltd.
+  * Copyright (C) 2007-2013, 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
index e222779..0eede2e 100644 (file)
@@ -2,7 +2,7 @@
  *  @brief This file contains SDIO (interface) module
  *  related macros, enum, and structure.
  *
- *  Copyright (C) 2007-2012, Marvell International Ltd.
+ *  Copyright (C) 2007-2013, 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
index 0d9f82e..59515f7 100644 (file)
@@ -2,7 +2,7 @@
  *  @brief This file contains SDIO IF (interface) module
  *  related functions.
  *
- * Copyright (C) 2007-2012, Marvell International Ltd.
+ * Copyright (C) 2007-2013, 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
@@ -35,6 +35,7 @@ static char *fw_name;
 /** request firmware nowait */
 static int req_fw_nowait;
 static int multi_fn = BIT(2);
+
 #define DEFAULT_FW_NAME "mrvl/sd8897_uapsta.bin"
 
 /** Function number 2 */
@@ -411,14 +412,16 @@ sd_verify_fw_download(bt_private * priv, int pollnum)
  *  @brief Transfers firmware to card
  *
  *  @param priv      A Pointer to bt_private structure
+ *  @param fw        A Pointer to fw image
+ *  @param fw_len    fw image len
  *  @return          BT_STATUS_SUCCESS/BT_STATUS_FAILURE or other error no.
  */
 static int
-sd_init_fw_dpc(bt_private * priv)
+sd_init_fw_dpc(bt_private * priv, u8 * fw, int fw_len)
 {
        struct sdio_mmc_card *card = (struct sdio_mmc_card *)priv->bt_dev.card;
-       u8 *firmware = NULL;
-       int firmwarelen;
+       u8 *firmware = fw;
+       int firmwarelen = fw_len;
        u8 base0;
        u8 base1;
        int ret = BT_STATUS_SUCCESS;
@@ -433,8 +436,6 @@ sd_init_fw_dpc(bt_private * priv)
        int tries = 0;
 
        ENTER();
-       firmware = (u8 *) priv->firmware->data;
-       firmwarelen = priv->firmware->size;
 
        PRINTM(INFO, "BT: Downloading FW image (%d bytes)\n", firmwarelen);
 
@@ -554,7 +555,7 @@ sd_init_fw_dpc(bt_private * priv)
                offset += txlen;
        } while (TRUE);
 
-       PRINTM(INFO, "\nBT: FW download over, size %d bytes\n", offset);
+       PRINTM(MSG, "BT: FW download over, size %d bytes\n", offset);
 
        ret = BT_STATUS_SUCCESS;
 done:
@@ -614,7 +615,10 @@ sd_request_fw_dpc(const struct firmware *fw_firmware, void *context)
        }
 
        priv->firmware = fw_firmware;
-       if (BT_STATUS_FAILURE == sd_init_fw_dpc(priv)) {
+
+       if (BT_STATUS_FAILURE ==
+           sd_init_fw_dpc(priv, (u8 *) priv->firmware->data,
+                          priv->firmware->size)) {
                PRINTM(ERROR,
                       "BT: sd_init_fw_dpc failed (download fw with nowait: %d). Terminating download\n",
                       req_fw_nowait);
@@ -1611,7 +1615,6 @@ sbi_download_fw(bt_private * priv)
        struct m_dev *m_dev_bt = &(priv->bt_dev.m_dev[BT_SEQ]);
        struct m_dev *m_dev_fm = &(priv->bt_dev.m_dev[FM_SEQ]);
        struct m_dev *m_dev_nfc = &(priv->bt_dev.m_dev[NFC_SEQ]);
-       int poll_num = MAX_FIRMWARE_POLL_TRIES;
        u8 winner = 0;
 
        ENTER();
@@ -1644,9 +1647,8 @@ sbi_download_fw(bt_private * priv)
        if (winner) {
                PRINTM(MSG, "BT is not the winner (0x%x). Skip FW download\n",
                       winner);
-               poll_num = MAX_MULTI_INTERFACE_POLL_TRIES;
                /* check if the fimware is downloaded successfully or not */
-               if (sd_verify_fw_download(priv, poll_num)) {
+               if (sd_verify_fw_download(priv, MAX_MULTI_INTERFACE_POLL_TRIES)) {
                        PRINTM(FATAL, "BT: FW failed to be active in time!\n");
                        ret = BT_STATUS_FAILURE;
                        goto done;
index b887035..d81c91b 100644 (file)
@@ -1,7 +1,7 @@
 /** @file hci_wrapper.h
  *  @brief This file contains HCI related definitions
  *
- *  Copyright (C) 2011-2012, Marvell International Ltd.
+ *  Copyright (C) 2011-2013, 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
index 27afcf9..e0b8a1b 100644 (file)
@@ -2,7 +2,7 @@
   *
   * @brief This file contains the char device function calls
   *
-  * Copyright (C) 2010-2012, Marvell International Ltd.
+  * Copyright (C) 2010-2013, 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
index a6918f1..ef48a3a 100644 (file)
@@ -2,7 +2,7 @@
   *
   * @brief This file contains mbtchar driver specific defines etc
   *
-  * Copyright (C) 2010-2012, Marvell International Ltd.
+  * Copyright (C) 2010-2013, 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
index 27743d4..6536ada 100644 (file)
@@ -3,7 +3,7 @@
  *  @brief This file declares all APIs that will be called from MOAL module.
  *  It also defines the data structures used for APIs between MLAN and MOAL.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index f16ebb6..f93c25b 100644 (file)
@@ -4,7 +4,7 @@
  *  structures and declares global function prototypes used
  *  in MLAN module.
  *
- *  (C) Copyright 2011-2012 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2011-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index be4a0ed..b0809a5 100644 (file)
@@ -4,7 +4,7 @@
  *  structures and declares global function prototypes used
  *  in MLAN module.
  *
- *  (C) Copyright 2011-2012 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2011-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index a68f4f3..a06cb00 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  @brief This file contains functions for 802.11D.
  *
- *  (C) Copyright 2008-2012 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index f3b7f74..06e1fcb 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  @brief This file contains functions for 802.11H.
  *
- *  (C) Copyright 2008-2012 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index 03d6042..3bf6fa9 100644 (file)
@@ -3,7 +3,7 @@
  *  @brief This header file contains data structures and
  *  function declarations of 802.11h
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index 3ce42da..864bab8 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  @brief This file contains functions for 11n handling.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index a0b2bf3..e40d6bc 100644 (file)
@@ -5,7 +5,7 @@
  *  Driver interface functions and type declarations for the 11n module
  *    implemented in mlan_11n.c.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index 76600d3..8b4786c 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  @brief This file contains functions for 11n Aggregation.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index 99e28f0..cd73565 100644 (file)
@@ -3,7 +3,7 @@
  *  @brief This file contains related macros, enum, and struct
  *  of 11n aggregation functionalities
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index 863de4b..9371688 100644 (file)
@@ -3,7 +3,7 @@
  *  @brief This file contains the handling of RxReordering in wlan
  *  driver.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index 301511a..0aea813 100644 (file)
@@ -3,7 +3,7 @@
  *  @brief This file contains related macros, enum, and struct
  *  of 11n RxReordering functionalities
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index c20fa63..d43f82b 100644 (file)
@@ -4,7 +4,7 @@
  *  @brief This file contains WLAN client mode channel, frequency and power
  *  related code
  *
- *  (C) Copyright 2009-2012 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2009-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index 84b809b..e51051c 100644 (file)
@@ -3,7 +3,7 @@
  *
  *  @brief This file contains the handling of CMD/EVENT in MLAN
  *
- *  (C) Copyright 2009-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2009-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
@@ -1658,15 +1658,9 @@ wlan_process_cmdresp(mlan_adapter * pmadapter)
            (pmadapter->last_init_cmd == cmdresp_no)) {
                i = pmpriv->bss_index + 1;
                while (i < pmadapter->priv_num &&
-                      !(pmpriv_next = pmadapter->priv[i]))
+                      (!(pmpriv_next = pmadapter->priv[i])
+                       || pmpriv_next->bss_virtual))
                        i++;
-               if (pmpriv_next && pmpriv_next->bss_virtual) {
-                       i = pmpriv_next->bss_index + 1;
-           /** skip virtual interface */
-                       while (i < pmadapter->priv_num &&
-                              !(pmpriv_next = pmadapter->priv[i]))
-                               i++;
-               }
                if (!pmpriv_next || i >= pmadapter->priv_num) {
 #if defined(STA_SUPPORT)
                        if (pmadapter->pwarm_reset_ioctl_req) {
index 3948910..81f40be 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  @brief This file declares the generic data structures and APIs.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
@@ -32,7 +32,7 @@ Change log:
 #define _MLAN_DECL_H_
 
 /** MLAN release version */
-#define MLAN_RELEASE_VERSION           "457"
+#define MLAN_RELEASE_VERSION           "463"
 
 /** Re-define generic data types for MLAN/MOAL */
 /** Signed char (1-byte) */
index 6de9399..b6836eb 100644 (file)
@@ -4,7 +4,7 @@
  *  structures and declares global function prototypes used
  *  in MLAN module.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
@@ -877,6 +877,13 @@ typedef enum _WLAN_802_11_WEP_STATUS {
 #define TLV_TYPE_IEEE_ACTION_FRAME   (PROPRIETARY_TLV_BASE_ID + 0x8c)  /* 0x018c
                                                                         */
 
+/** TLV type : SCAN channel gap */
+#define TLV_TYPE_SCAN_CHANNEL_GAP    (PROPRIETARY_TLV_BASE_ID + 0xc5)  /* 0x01c5
+                                                                        */
+/** TLV type : Channel statistics */
+#define TLV_TYPE_CHANNEL_STATS       (PROPRIETARY_TLV_BASE_ID + 0xc6)  /* 0x01c6
+                                                                        */
+
 /** Firmware Host Command ID Constants */
 /** Host Command ID : Get hardware specifications */
 #define HostCmd_CMD_GET_HW_SPEC               0x0003
@@ -2060,6 +2067,22 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_AuthType_t {
        t_u16 auth_type;
 } MLAN_PACK_END MrvlIEtypes_AuthType_t;
 
+/** MrvlIEtypes_ScanChanGap_t */
+typedef MLAN_PACK_START struct _MrvlIEtypes_ScanChanGap_t {
+    /** Header */
+       MrvlIEtypesHeader_t header;
+    /** Time gap in units to TUs to be used between two consecutive channels scan */
+       t_u16 gap;
+} MLAN_PACK_END MrvlIEtypes_ScanChanGap_t;
+
+/** channel statictics tlv */
+typedef MLAN_PACK_START struct _MrvlIEtypes_ChannelStats_t {
+    /** Header */
+       MrvlIEtypesHeader_t header;
+    /** channel statictics */
+       ChanStatistics_t chanStat[0];
+} MLAN_PACK_END MrvlIEtypes_ChannelStats_t;
+
 /** MrvlIETypes_ActionFrame_t */
 typedef MLAN_PACK_START struct {
        MrvlIEtypesHeader_t header;
index aa1d31f..0379036 100644 (file)
@@ -3,7 +3,7 @@
  *  @brief This file contains IEEE information element related
  *  definitions used in MLAN and MOAL module.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
@@ -1430,6 +1430,24 @@ typedef MLAN_PACK_START struct _wlan_user_scan_chan {
        t_u32 scan_time;
 } MLAN_PACK_END wlan_user_scan_chan;
 
+/** channel statictics */
+typedef MLAN_PACK_START struct _ChanStatistics_t {
+    /** channle number */
+       t_u8 chan_num;
+       /** band info */
+       t_u8 bandconfig;
+       /** flags */
+       t_u8 flags;
+       /** noise */
+       t_s8 noise;
+       /** total network */
+       t_u16 total_networks;
+       /** scan duration */
+       t_u16 cca_scan_duration;
+       /** busy duration */
+       t_u16 cca_busy_duration;
+} MLAN_PACK_END ChanStatistics_t;
+
 /**
  *  Input structure to configure an immediate scan cmd to firmware
  *
@@ -1476,6 +1494,8 @@ typedef MLAN_PACK_START struct {
      *  Variable number (fixed maximum) of channels to scan up
      */
        wlan_user_scan_chan chan_list[WLAN_USER_SCAN_CHAN_MAX];
+    /** scan channel gap */
+       t_u16 scan_chan_gap;
 } MLAN_PACK_END wlan_user_scan_cfg;
 
 /** Default scan interval in millisecond*/
@@ -1535,6 +1555,8 @@ typedef MLAN_PACK_START struct {
        wlan_user_scan_ssid ssid_list[MRVDRV_MAX_SSID_LIST_LENGTH];
     /** Variable number (fixed maximum) of channels to scan up */
        wlan_user_scan_chan chan_list[WLAN_BG_SCAN_CHAN_MAX];
+    /** scan channel gap */
+       t_u16 scan_chan_gap;
 } MLAN_PACK_END wlan_bgscan_cfg;
 #endif /* STA_SUPPORT */
 
index f12f3c0..558e002 100644 (file)
@@ -3,7 +3,7 @@
  *  @brief This file contains the initialization for FW
  *  and HW.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
@@ -180,6 +180,14 @@ wlan_allocate_adapter(pmlan_adapter pmadapter)
 #ifdef STA_SUPPORT
        t_u32 buf_size;
        BSSDescriptor_t *ptemp_scan_table = MNULL;
+       t_u8 i = 0;
+       t_u8 chan_2g[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
+       t_u8 chan_5g[] =
+               { 12, 16, 34, 38, 42, 46, 36, 40, 44, 48, 52, 56, 60, 64, 100,
+              104, 108,
+               112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161,
+                       165
+       };
 #endif
 
        ENTER();
@@ -222,6 +230,33 @@ wlan_allocate_adapter(pmlan_adapter pmadapter)
                return MLAN_STATUS_FAILURE;
        }
        pmadapter->bcn_buf_size = DEFAULT_SCAN_BEACON_BUFFER;
+
+       pmadapter->num_in_chan_stats = sizeof(chan_2g);
+       pmadapter->num_in_chan_stats += sizeof(chan_5g);
+       buf_size = sizeof(ChanStatistics_t) * pmadapter->num_in_chan_stats;
+       if (pmadapter->callbacks.moal_vmalloc &&
+           pmadapter->callbacks.moal_vfree)
+               ret = pmadapter->callbacks.moal_vmalloc(pmadapter->pmoal_handle,
+                                                       buf_size,
+                                                       (t_u8 **) & pmadapter->
+                                                       pchan_stats);
+       else
+               ret = pmadapter->callbacks.moal_malloc(pmadapter->pmoal_handle,
+                                                      buf_size, MLAN_MEM_DEF,
+                                                      (t_u8 **) & pmadapter->
+                                                      pchan_stats);
+       if (ret != MLAN_STATUS_SUCCESS || !pmadapter->pchan_stats) {
+               PRINTM(MERROR, "Failed to allocate channel statistics\n");
+               LEAVE();
+               return MLAN_STATUS_FAILURE;
+       }
+       for (i = 0; i < pmadapter->num_in_chan_stats; i++) {
+               if (i < sizeof(chan_2g))
+                       pmadapter->pchan_stats[i].chan_num = chan_2g[i];
+               else
+                       pmadapter->pchan_stats[i].chan_num =
+                               chan_5g[i - sizeof(chan_2g)];
+       }
 #endif
 
        /* Allocate command buffer */
@@ -1064,6 +1099,15 @@ wlan_free_adapter(pmlan_adapter pmadapter)
                                        (t_u8 *) pmadapter->pscan_table);
                pmadapter->pscan_table = MNULL;
        }
+       if (pmadapter->pchan_stats) {
+               if (pcb->moal_vmalloc && pcb->moal_vfree) {
+                       pcb->moal_vfree(pmadapter->pmoal_handle,
+                                       (t_u8 *) pmadapter->pchan_stats);
+               } else
+                       pcb->moal_mfree(pmadapter->pmoal_handle,
+                                       (t_u8 *) pmadapter->pchan_stats);
+               pmadapter->pchan_stats = MNULL;
+       }
        if (pmadapter->bcn_buf) {
                if (pcb->moal_vmalloc && pcb->moal_vfree)
                        pcb->moal_vfree(pmadapter->pmoal_handle,
index b983195..c63ee0e 100644 (file)
@@ -3,7 +3,7 @@
  *  @brief This file defines the FW initialization data
  *  structures.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index 797eb08..e57bf4a 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  @brief This file declares the IOCTL data structures and APIs.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
@@ -416,6 +416,10 @@ typedef struct _mlan_scan_resp {
        t_u8 *pscan_table;
        /* Age in seconds */
        t_u32 age_in_secs;
+    /** channel statstics */
+       t_u8 *pchan_stats;
+    /** Number of records in the chan_stats */
+       t_u32 num_in_chan_stats;
 } mlan_scan_resp, *pmlan_scan_resp;
 
 /** Type definition of mlan_scan_cfg */
@@ -1972,7 +1976,7 @@ typedef struct _mlan_ds_power_cfg {
 /** Host sleep config conditions: Default */
 #define HOST_SLEEP_DEF_COND     (HOST_SLEEP_COND_BROADCAST_DATA | HOST_SLEEP_COND_UNICAST_DATA | HOST_SLEEP_COND_MAC_EVENT)
 /** Host sleep config GPIO : Default */
-#define HOST_SLEEP_DEF_GPIO     0x10
+#define HOST_SLEEP_DEF_GPIO     0x08
 /** Host sleep config gap : Default */
 #define HOST_SLEEP_DEF_GAP      100
 /** Host sleep config min wake holdoff */
index 4a5d9f0..986639b 100644 (file)
@@ -6,7 +6,7 @@
  *  for sending adhoc start, adhoc join, and association commands
  *  to the firmware.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index 8e7e492..917df2a 100644 (file)
@@ -7,7 +7,7 @@
  *  implemented in mlan_join.c.  Process all start/join requests for
  *  both adhoc and infrastructure networks
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index d2c58e1..9d40cab 100644 (file)
@@ -4,7 +4,7 @@
  *  structures and declares global function prototypes used
  *  in MLAN module.
  *
- *  (C) Copyright 2008-2012 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
@@ -1789,6 +1789,10 @@ typedef struct _mlan_adapter {
        BSSDescriptor_t *pscan_table;
     /** scan age in secs */
        t_u32 age_in_secs;
+    /** channel statstics */
+       ChanStatistics_t *pchan_stats;
+    /** Number of records in the chan_stats */
+       t_u32 num_in_chan_stats;
        t_u8 bgscan_reported;
 
     /** Number of records in the scan table */
index 019eea0..f368ef1 100644 (file)
@@ -11,7 +11,7 @@
  *  Requires use of the following preprocessor define:
  *    - ENABLE_MEAS
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index c39ccc3..ef723a8 100644 (file)
@@ -8,7 +8,7 @@
  *
  *  @sa mlan_meas.c
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index bfbede8..aeeaa41 100644 (file)
@@ -3,7 +3,7 @@
  *
  *  @brief This file include Miscellaneous functions for MLAN module
  *
- *  (C) Copyright 2009-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2009-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index cce1d02..d5fa56f 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  @brief This file declares the exported symbols from MLAN.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index 15f71ab..623aa2c 100644 (file)
@@ -5,7 +5,7 @@
  *  IOCTL handlers as well as command preparation and response routines
  *  for sending scan commands to the firmware.
  *
- *  (C) Copyright 2008-2012 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
@@ -125,6 +125,60 @@ static t_u8 rsn_oui[CIPHER_SUITE_MAX][4] = {
 };
 
 /**
+ *  @brief This function will update the channel statistics from scan result
+ *
+ *  @param pmpriv           A pointer to mlan_private structure
+ *  @param pchanstats_tlv   A pointer to MrvlIEtypes_ChannelStats_t tlv
+ *
+ *  @return                NA
+ */
+void
+wlan_update_chan_statistics(mlan_private * pmpriv,
+                           MrvlIEtypes_ChannelStats_t * pchanstats_tlv)
+{
+       mlan_adapter *pmadapter = pmpriv->adapter;
+       t_u8 i, j;
+       ChanStatistics_t *pchan_stats =
+               (ChanStatistics_t *) ((t_u8 *) pchanstats_tlv +
+                                     sizeof(MrvlIEtypesHeader_t));
+       t_u8 num_chan =
+               wlan_le16_to_cpu(pchanstats_tlv->header.len) /
+               sizeof(ChanStatistics_t);
+
+       ENTER();
+
+       for (j = 0; j < num_chan; j++) {
+               for (i = 0; i < pmadapter->num_in_chan_stats; i++) {
+                       if (pmadapter->pchan_stats[i].chan_num ==
+                           pchan_stats->chan_num) {
+                               pchan_stats->total_networks =
+                                       wlan_le16_to_cpu(pchan_stats->
+                                                        total_networks);
+                               pchan_stats->cca_scan_duration =
+                                       wlan_le16_to_cpu(pchan_stats->
+                                                        cca_scan_duration);
+                               pchan_stats->cca_busy_duration =
+                                       wlan_le16_to_cpu(pchan_stats->
+                                                        cca_busy_duration);
+                               PRINTM(MCMND,
+                                      "chan=%d, noise=%d, total_network=%d scan_duration=%d, busy_duration=%d\n",
+                                      pchan_stats->chan_num,
+                                      pchan_stats->noise,
+                                      pchan_stats->total_networks,
+                                      pchan_stats->cca_scan_duration,
+                                      pchan_stats->cca_busy_duration);
+                               memcpy(pmadapter, &pmadapter->pchan_stats[i],
+                                      pchan_stats, sizeof(ChanStatistics_t));
+                               break;
+                       }
+               }
+               pchan_stats++;
+       }
+       LEAVE();
+       return;
+}
+
+/**
  *  @brief This function will parse a given IE for a given OUI
  *
  *  Parse a given WPA/RSN IE to find if it has a given oui in PTK,
@@ -951,6 +1005,7 @@ wlan_scan_setup_scan_config(IN mlan_private * pmpriv,
        MrvlIETypes_HTCap_t *pht_cap;
 
        MrvlIETypes_VHTCap_t *pvht_cap;
+       MrvlIEtypes_ScanChanGap_t *pscan_gap_tlv;
        ENTER();
 
        /* The tlv_buf_len is calculated for each scan command.  The TLVs added
@@ -1077,6 +1132,22 @@ wlan_scan_setup_scan_config(IN mlan_private * pmpriv,
        else
                *pmax_chan_per_scan = MRVDRV_CHANNELS_PER_SCAN_CMD;
 
+       if (puser_scan_in && puser_scan_in->scan_chan_gap) {
+               *pmax_chan_per_scan = MRVDRV_MAX_CHANNELS_PER_SPECIFIC_SCAN;
+               PRINTM(MINFO, "Scan: channel gap = %d\n",
+                      puser_scan_in->scan_chan_gap);
+               pscan_gap_tlv = (MrvlIEtypes_ScanChanGap_t *) ptlv_pos;
+               pscan_gap_tlv->header.type =
+                       wlan_cpu_to_le16(TLV_TYPE_SCAN_CHANNEL_GAP);
+               pscan_gap_tlv->header.len = sizeof(pscan_gap_tlv->gap);
+               pscan_gap_tlv->gap =
+                       wlan_cpu_to_le16((t_u16) puser_scan_in->scan_chan_gap);
+               ptlv_pos +=
+                       sizeof(pscan_gap_tlv->header) +
+                       pscan_gap_tlv->header.len;
+               pscan_gap_tlv->header.len =
+                       wlan_cpu_to_le16(pscan_gap_tlv->header.len);
+       }
        /* If the input config or adapter has the number of Probes set, add tlv
         */
        if (num_probes) {
@@ -1317,6 +1388,12 @@ wlan_ret_802_11_scan_get_tlv_ptrs(IN pmlan_adapter pmadapter,
                                       tlv_len);
                                *pptlv = (MrvlIEtypes_Data_t *) pcurrent_tlv;
                                break;
+                       case TLV_TYPE_CHANNEL_STATS:
+                               PRINTM(MINFO,
+                                      "SCAN_RESP: CHANNEL STATS TLV, len = %d\n",
+                                      tlv_len);
+                               *pptlv = (MrvlIEtypes_Data_t *) pcurrent_tlv;
+                               break;
                        default:
                                PRINTM(MERROR,
                                       "SCAN_RESP: Unhandled TLV = %d\n",
@@ -3317,6 +3394,7 @@ wlan_is_network_compatible(IN mlan_private * pmpriv,
 mlan_status
 wlan_flush_scan_table(IN pmlan_adapter pmadapter)
 {
+       t_u8 i = 0;
        ENTER();
 
        PRINTM(MINFO, "Flushing scan table\n");
@@ -3328,6 +3406,9 @@ wlan_flush_scan_table(IN pmlan_adapter pmadapter)
        memset(pmadapter, pmadapter->bcn_buf, 0, pmadapter->bcn_buf_size);
        pmadapter->pbcn_buf_end = pmadapter->bcn_buf;
 
+       for (i = 0; i < pmadapter->num_in_chan_stats; i++)
+               pmadapter->pchan_stats[i].cca_scan_duration = 0;
+
        LEAVE();
        return MLAN_STATUS_SUCCESS;
 }
@@ -3366,6 +3447,7 @@ wlan_scan_networks(IN mlan_private * pmpriv,
        t_u8 filtered_scan;
        t_u8 scan_current_chan_only;
        t_u8 max_chan_per_scan;
+       t_u8 i;
 
        ENTER();
 
@@ -3431,6 +3513,8 @@ wlan_scan_networks(IN mlan_private * pmpriv,
                       sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST);
                pmadapter->num_in_scan_table = 0;
                pmadapter->pbcn_buf_end = pmadapter->bcn_buf;
+               for (i = 0; i < pmadapter->num_in_chan_stats; i++)
+                       pmadapter->pchan_stats[i].cca_scan_duration = 0;
        }
 
        ret = wlan_scan_channel_list(pmpriv,
@@ -3560,6 +3644,7 @@ wlan_ret_802_11_scan(IN mlan_private * pmpriv,
        BSSDescriptor_t *bss_new_entry = MNULL;
        MrvlIEtypes_Data_t *ptlv;
        MrvlIEtypes_TsfTimestamp_t *ptsf_tlv = MNULL;
+       MrvlIEtypes_ChannelStats_t *pchanstats_tlv = MNULL;
        t_u8 *pbss_info;
        t_u32 scan_resp_size;
        t_u32 bytes_left;
@@ -3639,6 +3724,13 @@ wlan_ret_802_11_scan(IN mlan_private * pmpriv,
                                          TLV_TYPE_CHANNELBANDLIST,
                                          (MrvlIEtypes_Data_t **) &
                                          pchan_band_tlv);
+       wlan_ret_802_11_scan_get_tlv_ptrs(pmadapter, ptlv, tlv_buf_size,
+                                         TLV_TYPE_CHANNEL_STATS,
+                                         (MrvlIEtypes_Data_t **) &
+                                         pchanstats_tlv);
+
+       if (pchanstats_tlv)
+               wlan_update_chan_statistics(pmpriv, pchanstats_tlv);
 
        /*
         *  Process each scan response returned (pscan_rsp->number_of_sets).  Save
@@ -3951,10 +4043,39 @@ mlan_status
 wlan_ret_802_11_scan_ext(IN mlan_private * pmpriv,
                         IN HostCmd_DS_COMMAND * resp, IN t_void * pioctl_buf)
 {
+       HostCmd_DS_802_11_SCAN_EXT *pext_scan_cmd = &(resp->params.ext_scan);
+       MrvlIEtypesHeader_t *tlv = MNULL;
+       MrvlIEtypes_ChannelStats_t *tlv_chanstats = MNULL;
+       t_u16 tlv_buf_left = 0;
+       t_u16 tlv_type = 0;
+       t_u16 tlv_len = 0;
        ENTER();
 
        PRINTM(MINFO, "EXT scan returns successfully\n");
-
+       tlv = (MrvlIEtypesHeader_t *) pext_scan_cmd->tlv_buffer;
+       tlv_buf_left =
+               resp->size - (sizeof(HostCmd_DS_802_11_SCAN_EXT) - 1 +
+                             S_DS_GEN);
+       while (tlv_buf_left >= sizeof(MrvlIEtypesHeader_t)) {
+               tlv_type = wlan_le16_to_cpu(tlv->type);
+               tlv_len = wlan_le16_to_cpu(tlv->len);
+               if (tlv_buf_left < (tlv_len + sizeof(MrvlIEtypesHeader_t))) {
+                       PRINTM(MERROR,
+                              "Error processing uAP sys config TLVs, bytes left < TLV length\n");
+                       break;
+               }
+               switch (tlv_type) {
+               case TLV_TYPE_CHANNEL_STATS:
+                       tlv_chanstats = (MrvlIEtypes_ChannelStats_t *) tlv;
+                       wlan_update_chan_statistics(pmpriv, tlv_chanstats);
+                       break;
+               default:
+                       break;
+               }
+               tlv_buf_left -= tlv_len + sizeof(MrvlIEtypesHeader_t);
+               tlv = (MrvlIEtypesHeader_t *) ((t_u8 *) tlv + tlv_len +
+                                              sizeof(MrvlIEtypesHeader_t));
+       }
        LEAVE();
        return MLAN_STATUS_SUCCESS;
 }
@@ -4865,6 +4986,11 @@ wlan_ret_802_11_bgscan_query(IN mlan_private * pmpriv,
                pscan->param.scan_resp.num_in_scan_table =
                        pmadapter->num_in_scan_table;
                pscan->param.scan_resp.age_in_secs = pmadapter->age_in_secs;
+               pscan->param.scan_resp.pchan_stats =
+                       (t_u8 *) pmadapter->pchan_stats;
+               pscan->param.scan_resp.num_in_chan_stats =
+                       pmadapter->num_in_chan_stats;
+
                pioctl_buf->data_read_written = sizeof(mlan_scan_resp) +
                        MLAN_SUB_COMMAND_SIZE;
 
index 3664b80..9302e63 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  @brief This file contains SDIO specific code
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
@@ -464,17 +464,18 @@ exit:
  *  @brief  This function downloads FW blocks to device
  *
  *  @param pmadapter   A pointer to mlan_adapter
- *  @param pmfw                        A pointer to firmware image
+ *  @param firmware     A pointer to firmware image
+ *  @param firmwarelen  firmware len
  *
  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
  */
 static mlan_status
-wlan_prog_fw_w_helper(IN pmlan_adapter pmadapter, IN pmlan_fw_image pmfw)
+wlan_prog_fw_w_helper(IN pmlan_adapter pmadapter, t_u8 * fw, t_u32 fw_len)
 {
        mlan_status ret = MLAN_STATUS_SUCCESS;
        pmlan_callbacks pcb = &pmadapter->callbacks;
-       t_u8 *firmware = pmfw->pfw_buf;
-       t_u32 firmwarelen = pmfw->fw_len;
+       t_u8 *firmware = fw;
+       t_u32 firmwarelen = fw_len;
        t_u32 offset = 0;
        t_u32 base0, base1;
        t_void *tmpfwbuf = MNULL;
@@ -1382,7 +1383,7 @@ wlan_dnld_fw(IN pmlan_adapter pmadapter, IN pmlan_fw_image pmfw)
        ENTER();
 
        /* Download the firmware image via helper */
-       ret = wlan_prog_fw_w_helper(pmadapter, pmfw);
+       ret = wlan_prog_fw_w_helper(pmadapter, pmfw->pfw_buf, pmfw->fw_len);
        if (ret != MLAN_STATUS_SUCCESS) {
                LEAVE();
                return MLAN_STATUS_FAILURE;
index 409b0a2..62b4395 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  @brief This file contains definitions for SDIO interface.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
@@ -385,6 +385,7 @@ mlan_status wlan_enable_host_int(pmlan_adapter pmadapter);
 mlan_status wlan_sdio_probe(pmlan_adapter pmadapter);
 /** multi interface download check */
 mlan_status wlan_check_winner_status(mlan_adapter * pmadapter, t_u32 * val);
+
 /** Firmware status check */
 mlan_status wlan_check_fw_status(mlan_adapter * pmadapter, t_u32 pollnum);
 /** Read interrupt status */
index 2bbf48c..d26dff1 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  @brief This file contains APIs to MOAL module.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
@@ -33,7 +33,7 @@
  *
  *  @section copyright_sec Copyright
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
@@ -798,13 +798,9 @@ mlan_main_process(IN t_void * pmlan_adapter)
                goto exit_main_proc;
        } else {
                pmadapter->mlan_processing = MTRUE;
-               pcb->moal_spin_unlock(pmadapter->pmoal_handle,
-                                     pmadapter->pmain_proc_lock);
        }
 process_start:
        do {
-               pcb->moal_spin_lock(pmadapter->pmoal_handle,
-                                   pmadapter->pmain_proc_lock);
                pmadapter->more_task_flag = MFALSE;
                pcb->moal_spin_unlock(pmadapter->pmoal_handle,
                                      pmadapter->pmain_proc_lock);
@@ -848,6 +844,8 @@ process_start:
                    )) {
                        wlan_pm_wakeup_card(pmadapter);
                        pmadapter->pm_wakeup_fw_try = MTRUE;
+                       pcb->moal_spin_lock(pmadapter->pmoal_handle,
+                                           pmadapter->pmain_proc_lock);
                        continue;
                }
                if (IS_CARD_RX_RCVD(pmadapter)) {
@@ -870,8 +868,7 @@ process_start:
                            (pmadapter->tx_lock_flag == MTRUE))
                                break;
 
-                       if (pmadapter->scan_processing
-                           || pmadapter->data_sent
+                       if (pmadapter->data_sent
                            || wlan_is_tdls_link_chan_switching(pmadapter->
                                                                tdls_status)
                            || (wlan_bypass_tx_list_empty(pmadapter) &&
@@ -925,8 +922,11 @@ process_start:
                    || (pmadapter->ps_state == PS_STATE_PRE_SLEEP)
                    || (pmadapter->ps_state == PS_STATE_SLEEP_CFM)
                    || (pmadapter->tx_lock_flag == MTRUE)
-                       )
+                       ) {
+                       pcb->moal_spin_lock(pmadapter->pmoal_handle,
+                                           pmadapter->pmain_proc_lock);
                        continue;
+               }
 
                if (!pmadapter->cmd_sent && !pmadapter->curr_cmd
                    && wlan_is_send_cmd_allowed(pmadapter->tdls_status)
@@ -938,8 +938,7 @@ process_start:
                        }
                }
 
-               if (!pmadapter->scan_processing
-                   && !pmadapter->data_sent &&
+               if (!pmadapter->data_sent &&
                    !wlan_11h_radar_detected_tx_blocked(pmadapter) &&
                    !wlan_is_tdls_link_chan_switching(pmadapter->tdls_status) &&
                    !wlan_bypass_tx_list_empty(pmadapter)) {
@@ -954,8 +953,7 @@ process_start:
                        }
                }
 
-               if (!pmadapter->scan_processing
-                   && !pmadapter->data_sent && !wlan_wmm_lists_empty(pmadapter)
+               if (!pmadapter->data_sent && !wlan_wmm_lists_empty(pmadapter)
                    && !wlan_11h_radar_detected_tx_blocked(pmadapter)
                    && !wlan_is_tdls_link_chan_switching(pmadapter->tdls_status)
                        ) {
@@ -985,15 +983,15 @@ process_start:
                }
 #endif
 
+               pcb->moal_spin_lock(pmadapter->pmoal_handle,
+                                   pmadapter->pmain_proc_lock);
        } while (MTRUE);
 
        pcb->moal_spin_lock(pmadapter->pmoal_handle,
                            pmadapter->pmain_proc_lock);
-       if (pmadapter->more_task_flag == MTRUE) {
-               pcb->moal_spin_unlock(pmadapter->pmoal_handle,
-                                     pmadapter->pmain_proc_lock);
+       if (pmadapter->more_task_flag == MTRUE)
                goto process_start;
-       }
+
        pmadapter->mlan_processing = MFALSE;
        pcb->moal_spin_unlock(pmadapter->pmoal_handle,
                              pmadapter->pmain_proc_lock);
index d1d2537..77630ce 100644 (file)
@@ -4,7 +4,7 @@
  *  it prepares command and sends it to firmware when
  *  it is ready.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index 8d0c7e2..ffd840f 100644 (file)
@@ -3,7 +3,7 @@
  *  @brief This file contains the handling of command
  *  responses generated by firmware.
  *
- *  (C) Copyright 2008-2012 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
@@ -115,6 +115,8 @@ wlan_process_cmdresp_error(mlan_private * pmpriv, HostCmd_DS_COMMAND * resp,
                           mlan_ioctl_req * pioctl_buf)
 {
        mlan_adapter *pmadapter = pmpriv->adapter;
+       pmlan_ioctl_req pscan_ioctl_req = MNULL;
+       mlan_callbacks *pcb = MNULL;
        tdls_all_config *tdls_all_cfg = MNULL;
        HostCmd_DS_TDLS_CONFIG *ptdls_config_data =
                &(resp->params.tdls_config_data);
@@ -148,6 +150,23 @@ wlan_process_cmdresp_error(mlan_private * pmpriv, HostCmd_DS_COMMAND * resp,
        case HostCmd_CMD_802_11_SCAN:
                /* Cancel all pending scan command */
                wlan_flush_scan_queue(pmadapter);
+
+               pcb = (pmlan_callbacks) & pmadapter->callbacks;
+
+               wlan_request_cmd_lock(pmadapter);
+               pmadapter->scan_processing = MFALSE;
+               pscan_ioctl_req = pmadapter->pscan_ioctl_req;
+               pmadapter->pscan_ioctl_req = MNULL;
+               /* Need to indicate IOCTL complete */
+               if (pscan_ioctl_req) {
+                       pscan_ioctl_req->status_code = MLAN_ERROR_CMD_SCAN_FAIL;
+                       /* Indicate ioctl complete */
+                       pcb->moal_ioctl_complete(pmadapter->pmoal_handle,
+                                                (pmlan_ioctl_req)
+                                                pscan_ioctl_req,
+                                                MLAN_STATUS_FAILURE);
+               }
+               wlan_release_cmd_lock(pmadapter);
                wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_SCAN_REPORT, MNULL);
                break;
 
index 0cde72b..ebf2843 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  @brief This file contains MLAN event handling.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index 4a343f5..e257bdb 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  @brief This file contains the functions for station ioctl.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
@@ -5184,6 +5184,10 @@ start_config:
                                pioctl_req->data_read_written =
                                        sizeof(mlan_scan_resp) +
                                        MLAN_SUB_COMMAND_SIZE;
+                               pscan->param.scan_resp.pchan_stats =
+                                       (t_u8 *) pmadapter->pchan_stats;
+                               pscan->param.scan_resp.num_in_chan_stats =
+                                       pmadapter->num_in_chan_stats;
                        }
                }
        }
index 97655f5..ccb5020 100644 (file)
@@ -3,7 +3,7 @@
  *  @brief This file contains the handling of RX in MLAN
  *  module.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index a766e77..224d73c 100644 (file)
@@ -3,7 +3,7 @@
  *  @brief This file contains the handling of data packet
  *  transmission in MLAN module.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index de29c3e..ab3a87d 100644 (file)
@@ -3,7 +3,7 @@
  *
  *  @brief This file contains the handling of TX/RX in MLAN
  *
- *  (C) Copyright 2009-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2009-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index bec39fa..36173e3 100644 (file)
@@ -3,7 +3,7 @@
  *  @brief This file contains related macros, enum, and struct
  *  of uap functionalities
  *
- *  (C) Copyright 2009-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2009-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index 284563a..488bd69 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  @brief This file contains the handling of AP mode command and event
  *
- *  (C) Copyright 2009-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2009-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index 00fc8fe..222bcf0 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  @brief This file contains the handling of AP mode ioctls
  *
- *  (C) Copyright 2009-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2009-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
@@ -1298,6 +1298,9 @@ wlan_ops_uap_ioctl(t_void * adapter, pmlan_ioctl_req pioctl_req)
        mlan_ds_rate *rate = MNULL;
        mlan_ds_reg_mem *reg_mem = MNULL;
        mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
+#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
+       mlan_ds_scan *pscan;
+#endif
 
        ENTER();
 
@@ -1334,6 +1337,27 @@ wlan_ops_uap_ioctl(t_void * adapter, pmlan_ioctl_req pioctl_req)
                        status = wlan_bss_ioctl_bss_remove(pmadapter,
                                                           pioctl_req);
                break;
+#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
+       case MLAN_IOCTL_SCAN:
+               pscan = (mlan_ds_scan *) pioctl_req->pbuf;
+               if ((pscan->sub_command == MLAN_OID_SCAN_NORMAL) &&
+                   (pioctl_req->action == MLAN_ACT_GET)) {
+                       PRINTM(MIOCTL, "Get scan table in uap\n");
+                       pscan->param.scan_resp.pscan_table =
+                               (t_u8 *) pmadapter->pscan_table;
+                       pscan->param.scan_resp.num_in_scan_table =
+                               pmadapter->num_in_scan_table;
+                       pscan->param.scan_resp.age_in_secs =
+                               pmadapter->age_in_secs;
+                       pioctl_req->data_read_written =
+                               sizeof(mlan_scan_resp) + MLAN_SUB_COMMAND_SIZE;
+                       pscan->param.scan_resp.pchan_stats =
+                               (t_u8 *) pmadapter->pchan_stats;
+                       pscan->param.scan_resp.num_in_chan_stats =
+                               pmadapter->num_in_chan_stats;
+               }
+               break;
+#endif
        case MLAN_IOCTL_GET_INFO:
                pget_info = (mlan_ds_get_info *) pioctl_req->pbuf;
                if (pget_info->sub_command == MLAN_OID_GET_VER_EXT)
index 6333bd2..d3d2572 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  @brief This file contains AP mode transmit and receive functions
  *
- *  (C) Copyright 2009-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2009-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index caced4d..aa03b1c 100644 (file)
@@ -3,7 +3,7 @@
  *  @brief This file contains wrappers for linked-list,
  *  spinlock and timer defines.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index 9ccb89b..ede77a7 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  @brief This file contains functions for WMM.
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index a30f26e..0dae0fb 100644 (file)
@@ -3,7 +3,7 @@
  *  @brief This file contains related macros, enum, and struct
  *  of wmm functionalities
  *
- *  (C) Copyright 2008-2011 Marvell International Ltd. All Rights Reserved
+ *  (C) Copyright 2008-2013 Marvell International Ltd. All Rights Reserved
  *
  *  MARVELL CONFIDENTIAL
  *  The source code contained or described herein and all documents related to
index d0db901..611f414 100644 (file)
@@ -3,7 +3,7 @@
  *  @brief This file declares all APIs that will be called from MOAL module.
  *  It also defines the data structures used for APIs between MLAN and MOAL.
  *
- * Copyright (C) 2008-2011, Marvell International Ltd.
+ * Copyright (C) 2008-2013, 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
index eaf81a8..b3deac6 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  @brief This file declares the generic data structures and APIs.
  *
- *  Copyright (C) 2008-2011, Marvell International Ltd.
+ *  Copyright (C) 2008-2013, 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
@@ -27,7 +27,7 @@ Change log:
 #define _MLAN_DECL_H_
 
 /** MLAN release version */
-#define MLAN_RELEASE_VERSION           "457"
+#define MLAN_RELEASE_VERSION           "463"
 
 /** Re-define generic data types for MLAN/MOAL */
 /** Signed char (1-byte) */
index 2a0b7b8..5993fb4 100644 (file)
@@ -3,7 +3,7 @@
  *  @brief This file contains IEEE information element related
  *  definitions used in MLAN and MOAL module.
  *
- *  Copyright (C) 2008-2011, Marvell International Ltd.
+ *  Copyright (C) 2008-2013, 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
@@ -1425,6 +1425,24 @@ typedef MLAN_PACK_START struct _wlan_user_scan_chan {
        t_u32 scan_time;
 } MLAN_PACK_END wlan_user_scan_chan;
 
+/** channel statictics */
+typedef MLAN_PACK_START struct _ChanStatistics_t {
+    /** channle number */
+       t_u8 chan_num;
+       /** band info */
+       t_u8 bandconfig;
+       /** flags */
+       t_u8 flags;
+       /** noise */
+       t_s8 noise;
+       /** total network */
+       t_u16 total_networks;
+       /** scan duration */
+       t_u16 cca_scan_duration;
+       /** busy duration */
+       t_u16 cca_busy_duration;
+} MLAN_PACK_END ChanStatistics_t;
+
 /**
  *  Input structure to configure an immediate scan cmd to firmware
  *
@@ -1471,6 +1489,8 @@ typedef MLAN_PACK_START struct {
      *  Variable number (fixed maximum) of channels to scan up
      */
        wlan_user_scan_chan chan_list[WLAN_USER_SCAN_CHAN_MAX];
+    /** scan channel gap */
+       t_u16 scan_chan_gap;
 } MLAN_PACK_END wlan_user_scan_cfg;
 
 /** Default scan interval in millisecond*/
@@ -1530,6 +1550,8 @@ typedef MLAN_PACK_START struct {
        wlan_user_scan_ssid ssid_list[MRVDRV_MAX_SSID_LIST_LENGTH];
     /** Variable number (fixed maximum) of channels to scan up */
        wlan_user_scan_chan chan_list[WLAN_BG_SCAN_CHAN_MAX];
+    /** scan channel gap */
+       t_u16 scan_chan_gap;
 } MLAN_PACK_END wlan_bgscan_cfg;
 #endif /* STA_SUPPORT */
 
index 4f498d0..3863285 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  @brief This file declares the IOCTL data structures and APIs.
  *
- *  Copyright (C) 2008-2011, Marvell International Ltd.
+ *  Copyright (C) 2008-2013, 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
@@ -411,6 +411,10 @@ typedef struct _mlan_scan_resp {
        t_u8 *pscan_table;
        /* Age in seconds */
        t_u32 age_in_secs;
+    /** channel statstics */
+       t_u8 *pchan_stats;
+    /** Number of records in the chan_stats */
+       t_u32 num_in_chan_stats;
 } mlan_scan_resp, *pmlan_scan_resp;
 
 /** Type definition of mlan_scan_cfg */
@@ -1967,7 +1971,7 @@ typedef struct _mlan_ds_power_cfg {
 /** Host sleep config conditions: Default */
 #define HOST_SLEEP_DEF_COND     (HOST_SLEEP_COND_BROADCAST_DATA | HOST_SLEEP_COND_UNICAST_DATA | HOST_SLEEP_COND_MAC_EVENT)
 /** Host sleep config GPIO : Default */
-#define HOST_SLEEP_DEF_GPIO     0x10
+#define HOST_SLEEP_DEF_GPIO     0x08
 /** Host sleep config gap : Default */
 #define HOST_SLEEP_DEF_GAP      100
 /** Host sleep config min wake holdoff */
index f5d9e11..008d3d5 100644 (file)
@@ -2,7 +2,7 @@
   *
   * @brief This file contains the functions for CFG80211.
   *
-  * Copyright (C) 2011-2012, Marvell International Ltd.
+  * Copyright (C) 2011-2013, 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
@@ -1842,11 +1842,15 @@ woal_cfg80211_mgmt_tx(struct wiphy *wiphy,
                                                    remain_bss_index];
                /** cancel previous remain on channel */
                if (priv->phandle->remain_on_channel && remain_priv) {
-                       if (woal_cfg80211_remain_on_channel_cfg
-                           (remain_priv, MOAL_IOCTL_WAIT, MTRUE,
-                            &channel_status, NULL, 0, 0))
-                               PRINTM(MERROR,
-                                      "mgmt_tx:Fail to cancel remain on channel\n");
+                       if ((priv->phandle->chan.center_freq !=
+                            chan->center_freq)
+                               ) {
+                               if (woal_cfg80211_remain_on_channel_cfg
+                                   (remain_priv, MOAL_IOCTL_WAIT, MTRUE,
+                                    &channel_status, NULL, 0, 0))
+                                       PRINTM(MERROR,
+                                              "mgmt_tx:Fail to cancel remain on channel\n");
+                       }
                        if (priv->phandle->cookie) {
                                cfg80211_remain_on_channel_expired(
 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)
@@ -2781,6 +2785,7 @@ woal_cfg80211_setup_vht_cap(moal_private * priv,
 
        req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11ac_cfg));
        if (req == NULL) {
+               status = MLAN_STATUS_FAILURE;
                PRINTM(MERROR, "Fail to allocate buf for setup vht_cap\n");
                goto done;
        }
index 8e49c7c..580858e 100644 (file)
@@ -2,7 +2,7 @@
   *
   * @brief This file contains the CFG80211 specific defines.
   *
-  * Copyright (C) 2011-2012, Marvell International Ltd.
+  * Copyright (C) 2011-2013, 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
index 426442e..c3fe334 100644 (file)
@@ -2,7 +2,7 @@
   *
   * @brief This file contains functions for debug proc file.
   *
-  * Copyright (C) 2008-2011, Marvell International Ltd.
+  * Copyright (C) 2008-2013, 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
index 6e38cf2..6df4c7f 100644 (file)
@@ -2,7 +2,7 @@
   *
   * @brief This file contains private ioctl functions
   *
-  * Copyright (C) 2012, Marvell International Ltd.
+  * Copyright (C) 2013, 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
@@ -208,6 +208,8 @@ done:
 }
 #endif
 
+#ifdef WIFI_DIRECT_SUPPORT
+#if defined(STA_CFG80211) || defined(UAP_CFG80211)
 /**
  *  @brief Set miracast mode
  *
@@ -233,13 +235,16 @@ woal_set_miracast_mode(moal_private * priv, t_u8 * pdata, size_t len)
                pos++;
        switch (*pos) {
        case '0':
-               /* TODO: disabled */
+               /* disable miracast mode */
+               priv->phandle->miracast_mode = 0;
                break;
        case '1':
-               /* TODO: source */
+               /* Source */
+               priv->phandle->miracast_mode = 1;
                break;
        case '2':
-               /* TODO: sink */
+               /* Sink */
+               priv->phandle->miracast_mode = 2;
                break;
        default:
                PRINTM(MERROR, "%s: Unknown miracast mode (%c)\n",
@@ -251,6 +256,8 @@ done:
        LEAVE();
        return ret;
 }
+#endif
+#endif
 
 /**
  *  @brief Get Driver Version
@@ -313,6 +320,7 @@ woal_priv_hostcmd(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        HostCmd_Header cmd_header;
        mlan_ioctl_req *req = NULL;
        mlan_ds_misc_cfg *misc_cfg = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -341,8 +349,8 @@ woal_priv_hostcmd(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        memcpy(misc_cfg->param.hostcmd.cmd, data_ptr + sizeof(buf_len),
               misc_cfg->param.hostcmd.len);
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto error;
        }
@@ -353,7 +361,8 @@ woal_priv_hostcmd(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        memcpy(data_ptr, (t_u8 *) & ret, sizeof(t_u32));
 
 error:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
 
        LEAVE();
        return ret;
@@ -376,6 +385,7 @@ woal_priv_customie(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ioctl_req *ioctl_req = NULL;
        mlan_ds_misc_cfg *misc = NULL;
        mlan_ds_misc_custom_ie *custom_ie = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
        data_ptr = respbuf + (strlen(CMD_MARVELL) + strlen(PRIV_CMD_CUSTOMIE));
@@ -398,8 +408,8 @@ woal_priv_customie(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
 
        memcpy(&misc->param.cust_ie, custom_ie, sizeof(mlan_ds_misc_custom_ie));
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -411,7 +421,8 @@ woal_priv_customie(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                ret = EFAULT;
        }
 done:
-       kfree(ioctl_req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(ioctl_req);
        LEAVE();
        return ret;
 }
@@ -439,6 +450,7 @@ woal_setget_priv_bandcfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ioctl_req *req = NULL;
        mlan_ds_radio_cfg *radio_cfg = NULL;
        mlan_ds_band_cfg *band_cfg = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -551,8 +563,8 @@ woal_setget_priv_bandcfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                        adhoc_chan_bandwidth;
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto error;
        }
@@ -564,7 +576,8 @@ woal_setget_priv_bandcfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ret = sizeof(mlan_ds_band_cfg);
 
 error:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
 
        LEAVE();
        return ret;
@@ -587,6 +600,7 @@ woal_setget_priv_httxcfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ds_11n_cfg *cfg_11n = NULL;
        int ret = 0;
        int user_data_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -638,8 +652,8 @@ woal_setget_priv_httxcfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                /* Update 11n tx parameters in MLAN */
                req->action = MLAN_ACT_SET;
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -649,8 +663,8 @@ woal_setget_priv_httxcfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        if (req->action == MLAN_ACT_GET) {
                cfg_11n->param.tx_cfg.httxcap = 0;
                cfg_11n->param.tx_cfg.misc_cfg = BAND_SELECT_A;
-               if (MLAN_STATUS_SUCCESS !=
-                   woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto done;
                }
@@ -662,7 +676,8 @@ woal_setget_priv_httxcfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ret = sizeof(data);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -686,6 +701,7 @@ woal_setget_priv_htcapinfo(moal_private * priv, t_u8 * respbuf,
        woal_ht_cap_info *ht_cap = NULL;
        int ret = 0;
        int user_data_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -738,8 +754,8 @@ woal_setget_priv_htcapinfo(moal_private * priv, t_u8 * respbuf,
                /* Update 11n tx parameters in MLAN */
                req->action = MLAN_ACT_SET;
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -749,8 +765,8 @@ woal_setget_priv_htcapinfo(moal_private * priv, t_u8 * respbuf,
        if (req->action == MLAN_ACT_GET) {
                cfg_11n->param.htcap_cfg.htcap = 0;
                cfg_11n->param.htcap_cfg.misc_cfg = BAND_SELECT_A;
-               if (MLAN_STATUS_SUCCESS !=
-                   woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto done;
                }
@@ -764,7 +780,8 @@ woal_setget_priv_htcapinfo(moal_private * priv, t_u8 * respbuf,
        ret = sizeof(woal_ht_cap_info);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -788,6 +805,7 @@ woal_setget_priv_addbapara(moal_private * priv, t_u8 * respbuf,
        woal_addba *addba = NULL;
        int ret = 0;
        int user_data_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -849,8 +867,8 @@ woal_setget_priv_addbapara(moal_private * priv, t_u8 * respbuf,
                /* Update add BA parameters in MLAN */
                req->action = MLAN_ACT_SET;
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -870,7 +888,8 @@ woal_setget_priv_addbapara(moal_private * priv, t_u8 * respbuf,
        ret = sizeof(woal_addba);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 
@@ -967,7 +986,8 @@ woal_priv_delba(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ret = sprintf(respbuf, "OK. BA deleted successfully.\n") + 1;
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -989,6 +1009,7 @@ woal_priv_rejectaddbareq(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ds_11n_cfg *cfg_11n = NULL;
        int ret = 0;
        int user_data_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -1030,8 +1051,8 @@ woal_priv_rejectaddbareq(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
 
        /* Send IOCTL request to MLAN */
-       if (woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT) !=
-           MLAN_STATUS_SUCCESS) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -1044,7 +1065,8 @@ woal_priv_rejectaddbareq(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 
@@ -1376,6 +1398,7 @@ woal_setget_priv_aggrpriotbl(moal_private * priv, t_u8 * respbuf,
        mlan_ds_11n_cfg *cfg_11n = NULL;
        int ret = 0;
        int user_data_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -1426,8 +1449,8 @@ woal_setget_priv_aggrpriotbl(moal_private * priv, t_u8 * respbuf,
                /* Update aggr priority table in MLAN */
                req->action = MLAN_ACT_SET;
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -1440,7 +1463,8 @@ woal_setget_priv_aggrpriotbl(moal_private * priv, t_u8 * respbuf,
        ret = sizeof(data);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 
@@ -1464,6 +1488,7 @@ woal_setget_priv_addbareject(moal_private * priv, t_u8 * respbuf,
        mlan_ds_11n_cfg *cfg_11n = NULL;
        int ret = 0;
        int user_data_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -1512,8 +1537,8 @@ woal_setget_priv_addbareject(moal_private * priv, t_u8 * respbuf,
                /* Update add BA reject configuration in MLAN */
                req->action = MLAN_ACT_SET;
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -1525,7 +1550,8 @@ woal_setget_priv_addbareject(moal_private * priv, t_u8 * respbuf,
        ret = sizeof(data);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 
@@ -1549,6 +1575,7 @@ woal_setget_priv_vhtcfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ds_11ac_vht_cfg *vhtcfg = NULL;
        int ret = 0;
        int user_data_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -1646,8 +1673,8 @@ woal_setget_priv_vhtcfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                /* Update 11AC parameters in MLAN */
                req->action = MLAN_ACT_SET;
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -1660,8 +1687,8 @@ woal_setget_priv_vhtcfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
 
        if ((req->action == MLAN_ACT_GET) && (data[0] == BAND_SELECT_BOTH)) {
                cfg_11ac->param.vht_cfg.band = BAND_SELECT_A;
-               if (MLAN_STATUS_SUCCESS !=
-                   woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto done;
                }
@@ -1674,7 +1701,8 @@ woal_setget_priv_vhtcfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 
@@ -1696,6 +1724,7 @@ woal_get_priv_datarate(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ds_rate *rate = NULL;
        mlan_data_rate *data_rate = NULL;
        int ret = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -1710,8 +1739,8 @@ woal_get_priv_datarate(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        req->req_id = MLAN_IOCTL_RATE;
        req->action = MLAN_ACT_GET;
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -1723,7 +1752,8 @@ woal_get_priv_datarate(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ret = sizeof(mlan_data_rate);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 
@@ -1748,6 +1778,7 @@ woal_setget_priv_txratecfg(moal_private * priv, t_u8 * respbuf,
        woal_tx_rate_cfg *ratecfg = NULL;
        int ret = 0;
        int user_data_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -1840,8 +1871,8 @@ woal_setget_priv_txratecfg(moal_private * priv, t_u8 * respbuf,
                }
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -1861,7 +1892,8 @@ woal_setget_priv_txratecfg(moal_private * priv, t_u8 * respbuf,
        ret = sizeof(woal_tx_rate_cfg);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 
@@ -1976,6 +2008,7 @@ woal_setget_priv_esuppmode(moal_private * priv, t_u8 * respbuf,
        woal_esuppmode_cfg *esupp_mode = NULL;
        int ret = 0;
        int user_data_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -2021,8 +2054,8 @@ woal_setget_priv_esuppmode(moal_private * priv, t_u8 * respbuf,
                sec->param.esupp_mode.act_groupcipher = (data[2] & 0xFF);
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -2037,7 +2070,8 @@ woal_setget_priv_esuppmode(moal_private * priv, t_u8 * respbuf,
 
        ret = sizeof(woal_esuppmode_cfg);
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 
@@ -2063,6 +2097,7 @@ woal_setget_priv_passphrase(moal_private * priv, t_u8 * respbuf,
        t_u16 len = 0;
        t_u8 zero_mac[] = { 0, 0, 0, 0, 0, 0 };
        t_u8 *mac = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -2164,8 +2199,8 @@ woal_setget_priv_passphrase(moal_private * priv, t_u8 * respbuf,
        if (action == 2)
                sec->param.passphrase.psk_type = MLAN_PSK_CLEAR;
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -2199,7 +2234,8 @@ woal_setget_priv_passphrase(moal_private * priv, t_u8 * respbuf,
 
        ret = len;
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 
@@ -2261,6 +2297,7 @@ woal_priv_ap_deauth(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ds_bss *bss = NULL;
        mlan_deauth_param deauth_param;
        int ret = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -2284,8 +2321,8 @@ woal_priv_ap_deauth(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
 
        memcpy(&bss->param.deauth_param, &deauth_param,
               sizeof(mlan_deauth_param));
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -2293,7 +2330,8 @@ woal_priv_ap_deauth(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        memcpy(data_ptr, &ioctl_req->status_code, sizeof(t_u32));
        ret = sizeof(t_u32);
 done:
-       kfree(ioctl_req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(ioctl_req);
        LEAVE();
        return ret;
 }
@@ -2312,6 +2350,7 @@ woal_priv_get_sta_list(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ds_get_info *info = NULL;
        mlan_ds_sta_list *sta_list = NULL;
        mlan_ioctl_req *ioctl_req = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -2329,8 +2368,8 @@ woal_priv_get_sta_list(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ioctl_req->req_id = MLAN_IOCTL_GET_INFO;
        ioctl_req->action = MLAN_ACT_GET;
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -2341,7 +2380,8 @@ woal_priv_get_sta_list(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        memcpy(sta_list, &info->param.sta_list, sizeof(mlan_ds_sta_list));
        ret = sizeof(mlan_ds_sta_list);
 done:
-       kfree(ioctl_req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(ioctl_req);
        LEAVE();
        return ret;
 }
@@ -2361,6 +2401,7 @@ woal_priv_bss_config(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ioctl_req *ioctl_req = NULL;
        t_u32 action = 0;
        int offset = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -2389,8 +2430,8 @@ woal_priv_bss_config(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                ioctl_req->action = MLAN_ACT_GET;
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -2401,7 +2442,8 @@ woal_priv_bss_config(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
        ret = sizeof(mlan_uap_bss_param);
 done:
-       kfree(ioctl_req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(ioctl_req);
        LEAVE();
        return ret;
 }
@@ -2686,6 +2728,7 @@ woal_priv_extcapcfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ioctl_req *req = NULL;
        mlan_ds_misc_cfg *cfg = NULL;
        IEEEtypes_Header_t *ie;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -2721,8 +2764,8 @@ woal_priv_extcapcfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                memcpy(&cfg->param.ext_cap, ie + 1, ie->len);
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -2736,7 +2779,8 @@ woal_priv_extcapcfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ret = sizeof(IEEEtypes_Header_t) + ie->len;
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -2833,6 +2877,7 @@ woal_priv_setgetipaddr(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ioctl_req *req = NULL;
        mlan_ds_misc_cfg *misc = NULL;
        int ret = 0, op_code = 0, data_length = 0, header = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -2886,8 +2931,8 @@ woal_priv_setgetipaddr(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        req->req_id = MLAN_IOCTL_MISC_CFG;
        misc->sub_command = MLAN_OID_MISC_IP_ADDR;
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -2905,7 +2950,8 @@ woal_priv_setgetipaddr(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -2927,6 +2973,7 @@ woal_priv_setwpssession(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        t_u32 data[1];
        int ret = 0;
        int user_data_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -2964,15 +3011,16 @@ woal_priv_setwpssession(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        else
                pwps->param.wps_session = MLAN_WPS_CFG_SESSION_END;
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
 
        ret = sprintf(respbuf, "OK\n") + 1;
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -2995,6 +3043,7 @@ woal_priv_otpuserdata(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ds_misc_cfg *misc = NULL;
        mlan_ds_misc_otp_user_data *otp = NULL;
        int ret = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -3021,8 +3070,8 @@ woal_priv_otpuserdata(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        misc->sub_command = MLAN_OID_MISC_OTP_USER_DATA;
        misc->param.otp_user_data.user_data_length = data[0];
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -3034,7 +3083,8 @@ woal_priv_otpuserdata(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -3058,6 +3108,7 @@ woal_priv_set_get_countrycode(moal_private * priv, t_u8 * respbuf,
        mlan_ioctl_req *req = NULL;
        mlan_ds_misc_cfg *pcfg_misc = NULL;
        mlan_ds_misc_country_code *country_code = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -3093,8 +3144,8 @@ woal_priv_set_get_countrycode(moal_private * priv, t_u8 * respbuf,
        }
 
        /* Send IOCTL request to MLAN */
-       if (woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT) !=
-           MLAN_STATUS_SUCCESS) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -3106,7 +3157,8 @@ woal_priv_set_get_countrycode(moal_private * priv, t_u8 * respbuf,
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
 
        LEAVE();
        return ret;
@@ -3287,6 +3339,7 @@ woal_priv_getwakeupreason(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ds_pm_cfg *pm_cfg = NULL;
        t_u32 data;
        int ret = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -3304,10 +3357,11 @@ woal_priv_getwakeupreason(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                req->req_id = MLAN_IOCTL_PM_CFG;
                req->action = MLAN_ACT_GET;
 
-               if (MLAN_STATUS_SUCCESS !=
-                   woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
-                       kfree(req);
+                       if (status != MLAN_STATUS_PENDING)
+                               kfree(req);
                        goto done;
                } else {
                        data = pm_cfg->param.wakeup_reason.hs_wakeup_reason;
@@ -3346,6 +3400,7 @@ woal_priv_set_get_listeninterval(moal_private * priv, t_u8 * respbuf,
        int ret = 0;
        mlan_ioctl_req *req = NULL;
        mlan_ds_bss *pcfg_bss = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -3387,8 +3442,8 @@ woal_priv_set_get_listeninterval(moal_private * priv, t_u8 * respbuf,
        }
 
        /* Send IOCTL request to MLAN */
-       if (woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT) !=
-           MLAN_STATUS_SUCCESS) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -3400,7 +3455,8 @@ woal_priv_set_get_listeninterval(moal_private * priv, t_u8 * respbuf,
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
 
        LEAVE();
        return ret;
@@ -3686,6 +3742,7 @@ woal_priv_set_get_scancfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        int data[arg_len];
        mlan_ds_scan *scan = NULL;
        mlan_ioctl_req *req = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -3752,8 +3809,8 @@ woal_priv_set_get_scancfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        } else
                req->action = MLAN_ACT_GET;
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -3762,7 +3819,8 @@ woal_priv_set_get_scancfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                ret = sizeof(mlan_scan_cfg);
        }
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -3888,6 +3946,7 @@ woal_priv_set_bss_mode(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        struct mwreq *mwr;
        t_u8 *data_ptr;
        t_u32 mode;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -3922,13 +3981,14 @@ woal_priv_set_bss_mode(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
        if (ret)
                goto done;
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -4393,6 +4453,7 @@ woal_priv_warmreset(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
 #endif
 #endif
 #endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -4431,10 +4492,11 @@ woal_priv_warmreset(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                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)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
-                       kfree(req);
+                       if (status != MLAN_STATUS_PENDING)
+                               kfree(req);
                        goto done;
                }
                kfree(req);
@@ -4470,6 +4532,7 @@ woal_priv_txpowercfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ds_power_cfg *pcfg = NULL;
        mlan_ioctl_req *req = NULL;
        t_u8 *arguments = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
        ENTER();
 
        memset(data, 0, sizeof(data));
@@ -4618,8 +4681,8 @@ woal_priv_txpowercfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                if (ret)
                        goto done;
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -4630,7 +4693,8 @@ woal_priv_txpowercfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                ret = sizeof(pcfg->param.power_ext);
        }
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -4655,6 +4719,7 @@ woal_priv_pscfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        int user_data_len = 0, header_len = 0;
        t_u8 *arguments = NULL, *space_ind = NULL;
        t_u32 is_negative_1 = MFALSE, is_negative_2 = MFALSE;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -4777,8 +4842,8 @@ woal_priv_pscfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        } else
                req->action = MLAN_ACT_GET;
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -4792,11 +4857,12 @@ woal_priv_pscfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                pm_cfg->param.ps_mode = 1;
                req->req_id = MLAN_IOCTL_PM_CFG;
                req->action = MLAN_ACT_SET;
-               woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        kfree(arguments);
        LEAVE();
        return ret;
@@ -4819,6 +4885,7 @@ woal_priv_sleeppd(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ioctl_req *req = NULL;
        int data = 0;
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -4862,8 +4929,8 @@ woal_priv_sleeppd(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        } else
                req->action = MLAN_ACT_GET;
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -4874,7 +4941,8 @@ woal_priv_sleeppd(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -4896,6 +4964,7 @@ woal_priv_txcontrol(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ioctl_req *req = NULL;
        int data = 0;
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -4932,8 +5001,8 @@ woal_priv_txcontrol(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                req->action = MLAN_ACT_GET;
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -4944,7 +5013,8 @@ woal_priv_txcontrol(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -4968,6 +5038,7 @@ woal_priv_regrdwr(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        int user_data_len = 0, header_len = 0;
        t_u8 *arguments = NULL, *space_ind = NULL;
        t_u32 is_negative_val = MFALSE;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -5020,8 +5091,8 @@ woal_priv_regrdwr(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        if (user_data_len == 3)
                reg_mem->param.reg_rw.value = (t_u32) data[2];
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -5033,7 +5104,8 @@ woal_priv_regrdwr(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        kfree(arguments);
        LEAVE();
        return ret;
@@ -5056,6 +5128,7 @@ woal_priv_rdeeprom(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ioctl_req *req = NULL;
        mlan_ds_reg_mem *reg_mem = NULL;
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -5086,8 +5159,8 @@ woal_priv_rdeeprom(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        reg_mem->param.rd_eeprom.offset = (t_u16) data[0];
        reg_mem->param.rd_eeprom.byte_count = (t_u16) data[1];
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -5099,7 +5172,8 @@ woal_priv_rdeeprom(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -5123,6 +5197,7 @@ woal_priv_memrdwr(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        int user_data_len = 0, header_len = 0;
        t_u8 *arguments = NULL, *space_ind = NULL;
        t_u32 is_negative_1 = MFALSE, is_negative_2 = MFALSE;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -5180,8 +5255,8 @@ woal_priv_memrdwr(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        if (user_data_len == 2)
                reg_mem->param.mem_rw.value = (t_u32) data[1];
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -5193,7 +5268,8 @@ woal_priv_memrdwr(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        kfree(arguments);
        LEAVE();
        return ret;
@@ -5312,6 +5388,7 @@ woal_priv_arpfilter(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ioctl_req *req = NULL;
        t_u8 *data_ptr = NULL;
        t_u32 buf_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -5332,13 +5409,14 @@ woal_priv_arpfilter(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        memcpy((void *)(misc->param.gen_ie.ie_data), data_ptr + sizeof(buf_len),
               buf_len);
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -5362,6 +5440,7 @@ woal_priv_mgmt_frame_passthru_ctrl(moal_private * priv, t_u8 * respbuf,
        int user_data_len = 0, header_len = 0;
        mlan_ioctl_req *req = NULL;
        mlan_ds_misc_cfg *mgmt_cfg = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
        header_len = strlen(CMD_MARVELL) + strlen(PRIV_CMD_MGMT_FRAME_CTRL);
@@ -5395,8 +5474,8 @@ woal_priv_mgmt_frame_passthru_ctrl(moal_private * priv, t_u8 * respbuf,
                }
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -5406,7 +5485,8 @@ woal_priv_mgmt_frame_passthru_ctrl(moal_private * priv, t_u8 * respbuf,
        ret = sizeof(data);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 
@@ -5456,6 +5536,7 @@ woal_priv_wmm_addts_req_ioctl(moal_private * priv, t_u8 * respbuf,
        wlan_ioctl_wmm_addts_req_t addts_ioctl;
        int ret = 0, header_len = 0, copy_len = sizeof(addts_ioctl);
        t_u8 *data_ptr;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -5481,8 +5562,8 @@ woal_priv_wmm_addts_req_ioctl(moal_private * priv, t_u8 * respbuf,
        memcpy(cfg->param.addts.ie_data,
               addts_ioctl.ie_data, cfg->param.addts.ie_data_len);
 
-       if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req,
-                                                     MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -5501,7 +5582,8 @@ woal_priv_wmm_addts_req_ioctl(moal_private * priv, t_u8 * respbuf,
        ret = copy_len;
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -5536,6 +5618,7 @@ woal_priv_wmm_delts_req_ioctl(moal_private * priv, t_u8 * respbuf,
        wlan_ioctl_wmm_delts_req_t delts_ioctl;
        int ret = 0, header_len = 0, copy_len = 0;
        t_u8 *data_ptr;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -5564,9 +5647,8 @@ woal_priv_wmm_delts_req_ioctl(moal_private * priv, t_u8 * respbuf,
                memcpy(cfg->param.delts.ie_data,
                       delts_ioctl.ie_data, cfg->param.delts.ie_data_len);
 
-               if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req,
-                                                             MOAL_IOCTL_WAIT))
-               {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto done;
                }
@@ -5580,7 +5662,8 @@ woal_priv_wmm_delts_req_ioctl(moal_private * priv, t_u8 * respbuf,
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -5606,6 +5689,7 @@ woal_priv_qconfig(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        wlan_ioctl_wmm_queue_config_t qcfg_ioctl;
        t_u8 *data_ptr;
        int ret = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -5628,8 +5712,8 @@ woal_priv_qconfig(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        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)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -5641,7 +5725,8 @@ woal_priv_qconfig(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ret = strlen(CMD_MARVELL) + strlen(PRIV_CMD_QCONFIG) +
                sizeof(qcfg_ioctl);
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -5671,6 +5756,7 @@ woal_priv_wmm_queue_status_ioctl(moal_private * priv, t_u8 * respbuf,
        mlan_ds_wmm_cfg *pwmm = NULL;
        wlan_ioctl_wmm_queue_status_t qstatus_ioctl;
        int ret = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -5686,8 +5772,8 @@ woal_priv_wmm_queue_status_ioctl(moal_private * priv, t_u8 * respbuf,
        pwmm->sub_command = MLAN_OID_WMM_CFG_QUEUE_STATUS;
 
        if (strlen(respbuf) == header_len) {
-               if (MLAN_STATUS_SUCCESS !=
-                   woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto done;
                }
@@ -5701,7 +5787,8 @@ woal_priv_wmm_queue_status_ioctl(moal_private * priv, t_u8 * respbuf,
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -5724,6 +5811,7 @@ woal_priv_wmm_ts_status_ioctl(moal_private * priv, t_u8 * respbuf,
        wlan_ioctl_wmm_ts_status_t ts_status_ioctl;
        int ret = 0, header_len = 0;
        t_u8 *data_ptr;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -5746,8 +5834,8 @@ woal_priv_wmm_ts_status_ioctl(moal_private * priv, t_u8 * respbuf,
        memset(&pwmm->param.ts_status, 0x00, 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)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -5759,7 +5847,8 @@ woal_priv_wmm_ts_status_ioctl(moal_private * priv, t_u8 * respbuf,
        ret = sizeof(ts_status_ioctl);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -5781,6 +5870,7 @@ woal_priv_macctrl(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ds_misc_cfg *cfg = NULL;
        int ret = 0;
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -5815,8 +5905,8 @@ woal_priv_macctrl(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                req->action = MLAN_ACT_SET;
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -5825,7 +5915,8 @@ woal_priv_macctrl(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ret = sizeof(data);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -5895,6 +5986,7 @@ woal_priv_region_code(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ds_misc_cfg *cfg = NULL;
        int ret = 0;
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -5929,8 +6021,8 @@ woal_priv_region_code(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                req->action = MLAN_ACT_SET;
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -5939,7 +6031,8 @@ woal_priv_region_code(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ret = sizeof(data);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -5962,6 +6055,7 @@ woal_priv_multi_chan_config(moal_private * priv, t_u8 * respbuf,
        t_u8 *data_ptr;
        int ret = 0;
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -5994,8 +6088,8 @@ woal_priv_multi_chan_config(moal_private * priv, t_u8 * respbuf,
                       sizeof(mlan_ds_multi_chan_cfg));
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -6005,7 +6099,8 @@ woal_priv_multi_chan_config(moal_private * priv, t_u8 * respbuf,
        ret = req->buf_len;
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -6083,6 +6178,7 @@ woal_priv_fwmacaddr(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        int header_len = 0;
        mlan_ioctl_req *req = NULL;
        mlan_ds_bss *bss = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -6111,8 +6207,8 @@ woal_priv_fwmacaddr(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
 
        /* Send IOCTL request to MLAN */
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -6122,7 +6218,8 @@ woal_priv_fwmacaddr(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        HEXDUMP("FW MAC Addr:", respbuf, ETH_ALEN);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -6282,6 +6379,7 @@ woal_priv_get_driver_verext(moal_private * priv, t_u8 * respbuf,
        int ret = 0;
        int copy_size = 0;
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -6318,8 +6416,8 @@ woal_priv_get_driver_verext(moal_private * priv, t_u8 * respbuf,
                goto done;
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -6335,7 +6433,8 @@ woal_priv_get_driver_verext(moal_private * priv, t_u8 * respbuf,
               info->param.ver_ext.version_str);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -6357,6 +6456,7 @@ woal_priv_wmm_cfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ioctl_req *req = NULL;
        int ret = 0;
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -6397,8 +6497,8 @@ woal_priv_wmm_cfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                        goto done;
                }
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -6407,7 +6507,8 @@ woal_priv_wmm_cfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ret = sizeof(wmm->param.wmm_enable);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -6430,10 +6531,11 @@ woal_priv_11d_cfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ioctl_req *req = NULL;
        int ret = 0;
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
-       req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
+       req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11d_cfg));
        if (req == NULL) {
                ret = ENOMEM;
                goto done;
@@ -6469,8 +6571,8 @@ woal_priv_11d_cfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                        goto done;
                }
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -6480,7 +6582,8 @@ woal_priv_11d_cfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ret = sizeof(pcfg_11d->param.enable_11d);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -6502,6 +6605,7 @@ woal_priv_11d_clr_chan_tbl(moal_private * priv, t_u8 * respbuf,
        mlan_ioctl_req *req = NULL;
        int ret = 0;
        int header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -6523,14 +6627,15 @@ woal_priv_11d_clr_chan_tbl(moal_private * priv, t_u8 * respbuf,
        req->req_id = MLAN_IOCTL_11D_CFG;
        req->action = MLAN_ACT_SET;
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -6553,6 +6658,7 @@ woal_priv_wws_cfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ioctl_req *req = NULL;
        int ret = 0;
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -6590,8 +6696,8 @@ woal_priv_wws_cfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                        goto done;
                }
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -6600,7 +6706,8 @@ woal_priv_wws_cfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ret = sizeof(wws->param.wws_cfg);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -6681,6 +6788,7 @@ woal_priv_txbuf_cfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ioctl_req *req = NULL;
        int ret = 0;
        int buf_size = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -6705,8 +6813,8 @@ woal_priv_txbuf_cfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                /* Get Tx buffer size from MLAN */
                req->action = MLAN_ACT_GET;
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -6716,7 +6824,8 @@ woal_priv_txbuf_cfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ret = sizeof(buf_size);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -6804,6 +6913,7 @@ woal_priv_11h_local_pwr_constraint(moal_private * priv, t_u8 * respbuf,
        mlan_ioctl_req *req = NULL;
        int ret = 0;
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -6836,8 +6946,8 @@ woal_priv_11h_local_pwr_constraint(moal_private * priv, t_u8 * respbuf,
                        goto done;
                }
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -6849,7 +6959,8 @@ woal_priv_11h_local_pwr_constraint(moal_private * priv, t_u8 * respbuf,
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -6871,6 +6982,7 @@ woal_priv_ht_stream_cfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ioctl_req *req = NULL;
        int ret = 0;
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -6908,8 +7020,8 @@ woal_priv_ht_stream_cfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                        goto done;
                }
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -6919,7 +7031,8 @@ woal_priv_ht_stream_cfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ret = sizeof(data);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -6939,6 +7052,7 @@ woal_priv_thermal(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ds_misc_cfg *cfg = NULL;
        mlan_ioctl_req *req = NULL;
        int ret = 0, header_len = 0, data = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -6961,8 +7075,8 @@ woal_priv_thermal(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
        req->action = MLAN_ACT_GET;
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -6972,7 +7086,8 @@ woal_priv_thermal(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ret = sizeof(data);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -6994,6 +7109,7 @@ woal_priv_beacon_interval(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ioctl_req *req = NULL;
        int ret = 0;
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -7031,8 +7147,8 @@ woal_priv_beacon_interval(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                        goto done;
                }
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -7042,7 +7158,8 @@ woal_priv_beacon_interval(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ret = sizeof(data);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -7259,6 +7376,7 @@ woal_priv_set_get_pmfcfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ds_misc_pmfcfg *pmfcfg;
        int ret = 0;
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -7296,8 +7414,8 @@ woal_priv_set_get_pmfcfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                req->action = MLAN_ACT_SET;
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -7307,7 +7425,8 @@ woal_priv_set_get_pmfcfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ret = sizeof(mlan_ds_misc_pmfcfg);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -7331,6 +7450,7 @@ woal_priv_inactivity_timeout_ext(moal_private * priv, t_u8 * respbuf,
        pmlan_ds_inactivity_to inac_to = NULL;
        int ret = 0;
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -7362,8 +7482,8 @@ woal_priv_inactivity_timeout_ext(moal_private * priv, t_u8 * respbuf,
        req->req_id = MLAN_IOCTL_PM_CFG;
        req->action = MLAN_ACT_GET;
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -7376,8 +7496,8 @@ woal_priv_inactivity_timeout_ext(moal_private * priv, t_u8 * respbuf,
                        inac_to->ps_entry_timeout = data[3];
                req->action = MLAN_ACT_SET;
 
-               if (MLAN_STATUS_SUCCESS !=
-                   woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto done;
                }
@@ -7392,7 +7512,8 @@ woal_priv_inactivity_timeout_ext(moal_private * priv, t_u8 * respbuf,
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -7412,6 +7533,7 @@ woal_priv_atim_window(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ds_bss *bss = NULL;
        int ret = 0, atim = 0;
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -7443,8 +7565,8 @@ woal_priv_atim_window(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                bss->param.atim_window = atim;
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -7453,7 +7575,8 @@ woal_priv_atim_window(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ret = sizeof(int);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -7475,6 +7598,7 @@ woal_priv_11n_amsdu_aggr_ctrl(moal_private * priv, t_u8 * respbuf,
        mlan_ds_11n_cfg *cfg_11n = NULL;
        int ret = 0, data[2];
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -7506,8 +7630,8 @@ woal_priv_11n_amsdu_aggr_ctrl(moal_private * priv, t_u8 * respbuf,
                cfg_11n->param.amsdu_aggr_ctrl.enable = data[0];
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -7519,7 +7643,8 @@ woal_priv_11n_amsdu_aggr_ctrl(moal_private * priv, t_u8 * respbuf,
        ret = sizeof(data);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -7540,6 +7665,7 @@ woal_priv_tx_bf_cap_ioctl(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ds_11n_cfg *bf_cfg = NULL;
        int ret = 0, bf_cap = 0;
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -7572,8 +7698,8 @@ woal_priv_tx_bf_cap_ioctl(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                bf_cfg->param.tx_bf_cap = bf_cap;
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -7584,7 +7710,8 @@ woal_priv_tx_bf_cap_ioctl(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ret = sizeof(bf_cap);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -7664,6 +7791,7 @@ woal_priv_sdio_mpa_ctrl(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ds_misc_cfg *misc = NULL;
        int ret = 0, data[6];
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -7696,8 +7824,8 @@ woal_priv_sdio_mpa_ctrl(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        /* Get the values first, then modify these values if user had modified
           them */
 
-       ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
-       if (ret != MLAN_STATUS_SUCCESS) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                PRINTM(MERROR, "woal_request_ioctl returned %d\n", ret);
                ret = -EFAULT;
                goto done;
@@ -7745,14 +7873,15 @@ woal_priv_sdio_mpa_ctrl(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                goto done;
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -7782,6 +7911,7 @@ woal_priv_sleep_params_ioctl(moal_private * priv, t_u8 * respbuf,
        {"clock stabilization time in usec"},
        {"value of reserved for debug"}
        };
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -7845,8 +7975,8 @@ woal_priv_sleep_params_ioctl(moal_private * priv, t_u8 * respbuf,
                psleep_params->reserved = data[5];
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -7862,7 +7992,8 @@ woal_priv_sleep_params_ioctl(moal_private * priv, t_u8 * respbuf,
        ret = sizeof(data);
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
 
        LEAVE();
        return ret;
@@ -7886,6 +8017,7 @@ woal_priv_dfs_testing(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        int ret = 0;
        int data[4];
        int user_data_len = 0, header_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -7944,8 +8076,8 @@ woal_priv_dfs_testing(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
 
        /* Send IOCTL request to MLAN */
-       if (woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT) !=
-           MLAN_STATUS_SUCCESS) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -7960,7 +8092,8 @@ woal_priv_dfs_testing(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
 
        LEAVE();
        return ret;
@@ -7985,6 +8118,7 @@ woal_priv_cfp_code(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ioctl_req *req = NULL;
        mlan_ds_misc_cfg *misc_cfg = NULL;
        mlan_ds_misc_cfp_code *cfp_code = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -8023,8 +8157,8 @@ woal_priv_cfp_code(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
 
        /* Send IOCTL request to MLAN */
-       if (woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT) !=
-           MLAN_STATUS_SUCCESS) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -8037,7 +8171,8 @@ woal_priv_cfp_code(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
 
        LEAVE();
        return ret;
@@ -8061,6 +8196,7 @@ woal_priv_set_get_tx_rx_ant(moal_private * priv, t_u8 * respbuf,
        mlan_ds_radio_cfg *radio = NULL;
        mlan_ioctl_req *req = NULL;
        int data[2] = { 0 };
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -8092,8 +8228,8 @@ woal_priv_set_get_tx_rx_ant(moal_private * priv, t_u8 * respbuf,
                        radio->param.ant_cfg.rx_antenna = data[1];
                req->action = MLAN_ACT_SET;
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -8107,7 +8243,8 @@ woal_priv_set_get_tx_rx_ant(moal_private * priv, t_u8 * respbuf,
                memcpy(respbuf, (t_u8 *) data, sizeof(data));
        }
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -8129,6 +8266,7 @@ woal_priv_sysclock(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        int ret = 0, i = 0;
        int user_data_len = 0, header_len = 0;
        int data_length = 0, length_index = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -8170,8 +8308,8 @@ woal_priv_sysclock(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                        cfg->param.sys_clock.sys_clk[i] = (t_u16) data[i];
                }
 
-               if (MLAN_STATUS_SUCCESS !=
-                   woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto done;
                }
@@ -8181,8 +8319,8 @@ woal_priv_sysclock(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
 
                /* 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)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto done;
                }
@@ -8203,8 +8341,8 @@ woal_priv_sysclock(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
 
                /* 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)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto done;
                }
@@ -8229,7 +8367,8 @@ woal_priv_sysclock(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -8259,6 +8398,7 @@ woal_priv_adhoc_aes(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        t_u8 bcast_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
        int header_len = 0;
        int copy_len = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -8290,8 +8430,8 @@ woal_priv_adhoc_aes(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                sec->sub_command = MLAN_OID_SEC_CFG_ENCRYPT_KEY;
                sec->param.encrypt_key.key_len = AES_KEY_LEN;
                sec->param.encrypt_key.key_index = MLAN_KEY_INDEX_UNICAST;
-               if (MLAN_STATUS_SUCCESS !=
-                   woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto done;
                }
@@ -8344,8 +8484,8 @@ woal_priv_adhoc_aes(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                        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)) {
+                       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+                       if (status != MLAN_STATUS_SUCCESS) {
                                ret = -EFAULT;
                                goto done;
                        }
@@ -8360,8 +8500,8 @@ woal_priv_adhoc_aes(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
                        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)) {
+                       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+                       if (status != MLAN_STATUS_SUCCESS) {
                                ret = -EFAULT;
                                goto done;
                        }
@@ -8374,7 +8514,8 @@ woal_priv_adhoc_aes(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        ret = copy_len;
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
 
        LEAVE();
        return ret;
@@ -8943,6 +9084,7 @@ woal_priv_port_ctrl(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        mlan_ioctl_req *req = NULL;
        mlan_ds_sec_cfg *sec = NULL;
        int ret = 0, data = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
        ENTER();
 
        /* Allocate an IOCTL request buffer */
@@ -8977,8 +9119,8 @@ woal_priv_port_ctrl(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
 
        /* Send IOCTL request to MLAN */
-       if (woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT) !=
-           MLAN_STATUS_SUCCESS) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -8989,7 +9131,8 @@ woal_priv_port_ctrl(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
 
        LEAVE();
        return ret;
@@ -9046,6 +9189,111 @@ woal_priv_bypassed_packet(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
 #if defined(WIFI_DIRECT_SUPPORT)
 #endif
 
+#ifdef WIFI_DIRECT_SUPPORT
+#if defined(STA_CFG80211) || defined(UAP_CFG80211)
+/**
+ * @brief               Set/Get MIRACAST configuration parameters
+ *
+ * @param priv          Pointer to moal_private structure
+ * @param respbuf       Pointer to response buffer
+ * @param resplen       Response buffer length
+ *
+ *  @return             Number of bytes written, negative for failure.
+ */
+static int
+woal_priv_miracast_cfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
+{
+       int ret = 0;
+       int user_data_len = 0, header_len = 0, data[3] = { 0, 0, 0 };
+
+       ENTER();
+
+       if (!priv || !priv->phandle) {
+               PRINTM(MERROR, "priv or handle is null\n");
+               ret = -EFAULT;
+               goto done;
+       }
+
+       header_len = strlen(CMD_MARVELL) + strlen(PRIV_CMD_MIRACAST_CFG);
+
+       if (strlen(respbuf) == header_len) {
+               /* GET operation */
+               data[0] = priv->phandle->miracast_mode;
+               data[1] = priv->phandle->miracast_scan_time;
+               data[2] = priv->phandle->scan_chan_gap;
+
+               memcpy(respbuf, (t_u8 *) data, sizeof(data));
+               ret = sizeof(data);
+       } else {
+               /* SET operation */
+               memset(data, 0, sizeof(data));
+               parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
+                               &user_data_len);
+
+               if (user_data_len > 3) {
+                       PRINTM(MERROR, "Too many arguments\n");
+                       ret = -EINVAL;
+                       goto done;
+               }
+               if (data[0] < 0 || data[0] > 2 || data[1] < 0 || data[2] < 0) {
+                       PRINTM(MERROR, "Invalid argument\n");
+                       ret = -EINVAL;
+                       goto done;
+               }
+       }
+
+       if (user_data_len >= 1)
+               priv->phandle->miracast_mode = (t_u8) data[0];
+       if (user_data_len >= 2)
+               priv->phandle->miracast_scan_time = (t_u16) data[1];
+       if (user_data_len == 3)
+               priv->phandle->scan_chan_gap = (t_u16) data[2];
+
+done:
+       LEAVE();
+       return ret;
+}
+
+/**
+ *   @brief Configuring scan gap for miracast mode
+ *
+ *  @param priv         A pointer to moal_private structure
+ *  @param respbuf      A pointer to response buffer
+ *  @param respbuflen   Available length of response buffer
+ *
+ *  @return             0 --success, otherwise failure
+ */
+int
+woal_set_scan_chan_gap(moal_private * priv, t_u8 * respbuf, int respbuflen)
+{
+       t_u32 data[2];
+       int ret = 0;
+       int user_data_len = 0;
+
+       ENTER();
+       if (strlen(respbuf) == strlen("SCAN_TIMING")) {
+               user_data_len = 0;
+       } else {
+               memset((char *)data, 0, sizeof(data));
+               parse_arguments(respbuf + strlen("SCAN_TIMING") + 1, data,
+                               ARRAY_SIZE(data), &user_data_len);
+       }
+
+       if (user_data_len != 2) {
+               PRINTM(MERROR, "Invalid arguments for scan timing\n");
+               ret = -EINVAL;
+               goto done;
+       }
+       priv->phandle->miracast_scan_time = (t_u16) data[0];
+       priv->phandle->scan_chan_gap = (t_u16) data[1];
+done:
+       LEAVE();
+       return ret;
+
+}
+#endif
+#endif
+
 /**
  *  @brief Set priv command for Android
  *  @param dev          A pointer to net_device structure
@@ -9071,7 +9319,6 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
        t_u8 country_code[COUNTRY_CODE_LEN];
 #endif
        int len = 0;
-       int buf_len = 0;
 
        ENTER();
        if (!priv || !priv->phandle) {
@@ -9085,18 +9332,28 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
                goto done;
        }
 #define CMD_BUF_LEN   2048
-       buf_len = MAX(CMD_BUF_LEN, priv_cmd.total_len);
-       buf = kzalloc(buf_len, GFP_KERNEL);
+       if (priv_cmd.used_len < 0 || priv_cmd.total_len <= 0 ||
+           priv_cmd.used_len > priv_cmd.total_len) {
+               PRINTM(MERROR,
+                      "Invalid Android priv cmd len. used_len: %d, total_len: %d\n",
+                      priv_cmd.used_len, priv_cmd.total_len);
+               ret = -EINVAL;
+               goto done;
+       }
+       if (priv_cmd.total_len + 1 > CMD_BUF_LEN)
+               priv_cmd.total_len = CMD_BUF_LEN - 1;
+
+       buf = kzalloc(priv_cmd.total_len + 1, GFP_KERNEL);
        if (!buf) {
                PRINTM(MERROR, "%s: failed to allocate memory\n", __FUNCTION__);
                ret = -ENOMEM;
                goto done;
        }
-       if (copy_from_user
-           (buf, priv_cmd.buf, MIN((CMD_BUF_LEN - 1), priv_cmd.total_len))) {
+       if (copy_from_user(buf, priv_cmd.buf, priv_cmd.total_len)) {
                ret = -EFAULT;
                goto done;
        }
+       buf[priv_cmd.total_len] = '\0';
 
        PRINTM(MIOCTL, "Android priv cmd: [%s] on [%s]\n", buf, req->ifr_name);
 
@@ -9257,7 +9514,8 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
                           (buf + strlen(CMD_MARVELL), PRIV_CMD_BSSROLE,
                            strlen(PRIV_CMD_BSSROLE)) == 0) {
                        /* BSS Role */
-                       len = woal_priv_bssrole(priv, buf, priv_cmd.total_len);
+                       len = woal_priv_bssrole(priv, buf,
+                                               (t_u32) priv_cmd.total_len);
                        goto handled;
 #endif
 #endif
@@ -9281,7 +9539,7 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
                            strlen(PRIV_CMD_EXTCAPCFG)) == 0) {
                        /* Extended capabilities configure */
                        len = woal_priv_extcapcfg(priv, buf,
-                                                 priv_cmd.total_len);
+                                                 (t_u32) priv_cmd.total_len);
                        goto handled;
 #endif
                } else if (strnicmp
@@ -9296,7 +9554,8 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
                            strlen(PRIV_CMD_IPADDR)) == 0) {
                        /* IP address */
                        len = woal_priv_setgetipaddr(priv, buf,
-                                                    priv_cmd.total_len);
+                                                    (t_u32) priv_cmd.
+                                                    total_len);
                        goto handled;
                } else if (strnicmp
                           (buf + strlen(CMD_MARVELL), PRIV_CMD_WPSSESSION,
@@ -9859,6 +10118,17 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
                        goto handled;
 #if defined(WIFI_DIRECT_SUPPORT)
 #endif
+#ifdef WIFI_DIRECT_SUPPORT
+#if defined(STA_CFG80211) || defined(UAP_CFG80211)
+               } else if (strnicmp
+                          (buf + strlen(CMD_MARVELL), PRIV_CMD_MIRACAST_CFG,
+                           strlen(PRIV_CMD_MIRACAST_CFG)) == 0) {
+                       /* Set/Get MIRACAST configuration parameters */
+                       len = woal_priv_miracast_cfg(priv, buf,
+                                                    priv_cmd.total_len);
+                       goto handled;
+#endif
+#endif
                } else {
                        /* Fall through, after stripping off the custom header */
                        buf += strlen(CMD_MARVELL);
@@ -10190,18 +10460,20 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
        }
 #endif
        else if (strncmp(buf, "P2P_DEV_ADDR", strlen("P2P_DEV_ADDR")) == 0) {
-               memset(buf, 0x0, priv_cmd.total_len);
+               memset(buf, 0x0, (size_t) priv_cmd.total_len);
                memcpy(buf, priv->current_addr, ETH_ALEN);
                len = ETH_ALEN;
        } else if (strncmp(buf, ("P2P_GET_NOA"), strlen("P2P_GET_NOA")) == 0) {
                /* TODO Just return '\0' */
-               memset(buf, 0x0, priv_cmd.total_len);
+               memset(buf, 0x0, (size_t) priv_cmd.total_len);
                *buf = 0;
                len = 1;
        } else if (strnicmp(buf, "MIRACAST", strlen("MIRACAST")) == 0) {
                pdata = buf + strlen("MIRACAST");
                /* Android cmd format: "MIRACAST 0" -- disabled "MIRACAST 1" --
                   operating as source "MIRACAST 2" -- operating as sink */
+#ifdef WIFI_DIRECT_SUPPORT
+#if defined(STA_CFG80211) || defined(UAP_CFG80211)
                if (MLAN_STATUS_SUCCESS !=
                    woal_set_miracast_mode(priv, (t_u8 *) pdata,
                                           priv_cmd.used_len -
@@ -10209,6 +10481,19 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
                        ret = -EFAULT;
                        goto done;
                }
+#endif
+#endif
+               len = sprintf(buf, "OK\n") + 1;
+       } else if (strnicmp(buf, "SCAN_TIMING", strlen("SCAN_TIMING")) == 0) {
+#ifdef WIFI_DIRECT_SUPPORT
+#if defined(STA_CFG80211) || defined(UAP_CFG80211)
+               if (MLAN_STATUS_SUCCESS !=
+                   woal_set_scan_chan_gap(priv, buf, priv_cmd.total_len)) {
+                       ret = -EFAULT;
+                       goto done;
+               }
+#endif
+#endif
                len = sprintf(buf, "OK\n") + 1;
        } else if (strnicmp(buf, "BA_WSIZE_RX", strlen("BA_WSIZE_RX")) == 0) {
                pdata = buf + strlen("BA_WSIZE_RX") + 1;
@@ -10255,7 +10540,8 @@ handled:
                priv_cmd.used_len = len;
                if (priv_cmd.used_len <= priv_cmd.total_len) {
                        memset(priv_cmd.buf + priv_cmd.used_len, 0,
-                              priv_cmd.total_len - priv_cmd.used_len);
+                              (size_t) (priv_cmd.total_len -
+                                        priv_cmd.used_len));
                        if (copy_to_user(priv_cmd.buf, buf, priv_cmd.used_len)) {
                                PRINTM(MERROR,
                                       "%s: failed to copy data to user buffer\n",
index 2135b80..1c157c5 100644 (file)
@@ -2,7 +2,7 @@
  *
  * @brief This file contains definition for private IOCTL call.
  *
- * Copyright (C) 2012, Marvell International Ltd.
+ * Copyright (C) 2013, 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
@@ -191,6 +191,11 @@ Change log:
 #define PRIV_CMD_MULTI_CHAN_POLICY "mc_policy"
 #if defined(WIFI_DIRECT_SUPPORT)
 #endif
+#ifdef WIFI_DIRECT_SUPPORT
+#if defined(STA_CFG80211) || defined(UAP_CFG80211)
+#define PRIV_CMD_MIRACAST_CFG       "miracastcfg"
+#endif
+#endif
 
 /** Private command ID for Android default commands */
 #define        WOAL_ANDROID_DEF_CMD        (SIOCDEVPRIVATE + 1)
index d0efaaa..a7ede6c 100644 (file)
@@ -2,7 +2,7 @@
   *
   * @brief This file contains ioctl function to MLAN
   *
-  * Copyright (C) 2008-2012, Marvell International Ltd.
+  * Copyright (C) 2008-2013, 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
@@ -319,12 +319,13 @@ woal_fill_wait_queue(moal_private * priv, wait_queue * wait, t_u8 wait_option)
  *
  *  @return             N/A
  */
-static inline void
+static inline mlan_status
 woal_wait_ioctl_complete(moal_private * priv, mlan_ioctl_req * req,
                         t_u8 wait_option)
 {
        mlan_status status;
        wait_queue *wait = (wait_queue *) req->reserved_1;
+       unsigned long flags;
 
        ENTER();
 
@@ -357,16 +358,21 @@ woal_wait_ioctl_complete(moal_private * priv, mlan_ioctl_req * req,
                break;
 #endif
        }
+       spin_lock_irqsave(&priv->phandle->driver_lock, flags);
        if (wait->condition == MFALSE) {
-               req->action = MLAN_ACT_CANCEL;
                PRINTM(MMSG,
-                      "wlan: IOCTL cancel %p id=0x%x, sub_id=0x%x, wait_option=%d, action=%d\n",
+                      "wlan: IOCTL by signal %p id=0x%x, sub_id=0x%x, wait_option=%d, action=%d\n",
                       req, req->req_id, (*(t_u32 *) req->pbuf), wait_option,
                       (int)req->action);
-               status = mlan_ioctl(priv->phandle->pmlan_adapter, req);
+               req->reserved_1 = 0;
+               status = MLAN_STATUS_PENDING;
+       } else {
+               status = wait->status;
        }
+       spin_unlock_irqrestore(&priv->phandle->driver_lock, flags);
+
        LEAVE();
-       return;
+       return status;
 }
 
 /**
@@ -595,9 +601,9 @@ woal_request_ioctl(moal_private * priv, mlan_ioctl_req * req, t_u8 wait_option)
 
        /* Call MLAN ioctl handle */
        atomic_inc(&priv->phandle->ioctl_pending);
-       spin_lock_irqsave(&priv->phandle->driver_lock, flags);
+       spin_lock_irqsave(&priv->phandle->ioctl_lock, flags);
        status = mlan_ioctl(priv->phandle->pmlan_adapter, req);
-       spin_unlock_irqrestore(&priv->phandle->driver_lock, flags);
+       spin_unlock_irqrestore(&priv->phandle->ioctl_lock, flags);
        switch (status) {
        case MLAN_STATUS_PENDING:
                PRINTM(MIOCTL,
@@ -608,10 +614,9 @@ woal_request_ioctl(moal_private * priv, mlan_ioctl_req * req, t_u8 wait_option)
                queue_work(priv->phandle->workqueue, &priv->phandle->main_work);
 
                /* Wait for completion */
-               if (wait_option) {
-                       woal_wait_ioctl_complete(priv, req, wait_option);
-                       status = wait->status;
-               }
+               if (wait_option)
+                       status = woal_wait_ioctl_complete(priv, req,
+                                                         wait_option);
                break;
        case MLAN_STATUS_SUCCESS:
        case MLAN_STATUS_FAILURE:
@@ -674,7 +679,8 @@ woal_request_set_mac_address(moal_private * priv)
                       status, req->status_code);
        }
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return status;
 }
@@ -770,7 +776,7 @@ woal_disconnect(moal_private * priv, t_u8 wait_option, t_u8 * mac)
        status = woal_request_ioctl(priv, req, wait_option);
 
 done:
-       if (wait_option || status != MLAN_STATUS_PENDING)
+       if (status != MLAN_STATUS_PENDING)
                kfree(req);
 #ifdef REASSOCIATION
        priv->reassoc_required = MFALSE;
@@ -829,7 +835,8 @@ woal_bss_start(moal_private * priv, t_u8 wait_option,
 #endif
 #endif
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return status;
 }
@@ -1112,11 +1119,9 @@ woal_set_get_gen_ie(moal_private * priv, t_u32 action, t_u8 * ie, int *ie_len)
                        memcpy(misc->param.gen_ie.ie_data, ie, *ie_len);
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
-               ret = MLAN_STATUS_FAILURE;
+       ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (ret != MLAN_STATUS_SUCCESS)
                goto done;
-       }
 
        if (action == MLAN_ACT_GET) {
                *ie_len = misc->param.gen_ie.len;
@@ -1125,7 +1130,8 @@ woal_set_get_gen_ie(moal_private * priv, t_u32 action, t_u8 * ie, int *ie_len)
        }
 
 done:
-       kfree(req);
+       if (ret != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -1161,9 +1167,9 @@ woal_set_get_tx_power(moal_private * priv,
                memcpy(&pcfg->param.power_cfg, power_cfg,
                       sizeof(mlan_power_cfg_t));
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT))
-               ret = MLAN_STATUS_FAILURE;
+       ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (ret != MLAN_STATUS_SUCCESS)
+               goto done;
 
        if (ret == MLAN_STATUS_SUCCESS && power_cfg)
                memcpy(power_cfg, &pcfg->param.power_cfg,
@@ -1232,10 +1238,9 @@ woal_set_get_power_mgmt(moal_private * priv,
                }
        }
 
-       if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, wait_option)) {
-               ret = MLAN_STATUS_FAILURE;
+       ret = woal_request_ioctl(priv, req, wait_option);
+       if (ret != MLAN_STATUS_SUCCESS)
                goto done;
-       }
 
        if (ret == MLAN_STATUS_SUCCESS && action == MLAN_ACT_GET)
                *disabled = pm_cfg->param.ps_mode;
@@ -1254,7 +1259,8 @@ woal_set_get_power_mgmt(moal_private * priv,
 #endif
 
 done:
-       kfree(req);
+       if (ret != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -1288,7 +1294,8 @@ woal_set_region_code(moal_private * priv, char *region)
        ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
 
 done:
-       kfree(req);
+       if (ret != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -1328,17 +1335,14 @@ woal_set_get_data_rate(moal_private * priv,
                memcpy(&rate->param.rate_cfg, datarate,
                       sizeof(mlan_rate_cfg_t));
 
-       if (MLAN_STATUS_SUCCESS ==
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
-               if (datarate && (action == MLAN_ACT_GET))
-                       memcpy(datarate, &rate->param.rate_cfg,
-                              sizeof(mlan_rate_cfg_t));
-       } else {
-               ret = MLAN_STATUS_FAILURE;
-       }
+       ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (ret == MLAN_STATUS_SUCCESS && datarate && action == MLAN_ACT_GET)
+               memcpy(datarate, &rate->param.rate_cfg,
+                      sizeof(mlan_rate_cfg_t));
 
 done:
-       kfree(req);
+       if (ret != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -1372,16 +1376,14 @@ woal_get_assoc_rsp(moal_private * priv, mlan_ds_misc_assoc_rsp * assoc_rsp)
        misc->sub_command = MLAN_OID_MISC_ASSOC_RSP;
        req->action = MLAN_ACT_GET;
 
-       if (MLAN_STATUS_SUCCESS ==
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
-               if (assoc_rsp)
-                       memcpy(assoc_rsp, &misc->param.assoc_resp,
-                              sizeof(mlan_ds_misc_assoc_rsp));
-       } else {
-               ret = MLAN_STATUS_FAILURE;
-       }
+       ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (ret == MLAN_STATUS_SUCCESS && assoc_rsp)
+               memcpy(assoc_rsp, &misc->param.assoc_resp,
+                      sizeof(mlan_ds_misc_assoc_rsp));
+
 done:
-       kfree(req);
+       if (ret != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -1437,7 +1439,8 @@ woal_request_get_fw_info(moal_private * priv, t_u8 wait_option,
                       "get fw info failed! status=%d, error_code=0x%x\n",
                       status, req->status_code);
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return status;
 }
@@ -1557,6 +1560,7 @@ woal_host_command(moal_private * priv, struct iwreq *wrq)
        int ret = 0;
        mlan_ds_misc_cfg *misc = NULL;
        mlan_ioctl_req *req = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -1603,8 +1607,8 @@ woal_host_command(moal_private * priv, struct iwreq *wrq)
        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)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -1616,7 +1620,8 @@ woal_host_command(moal_private * priv, struct iwreq *wrq)
        }
        wrq->u.data.length = misc->param.hostcmd.len;
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -1647,6 +1652,7 @@ woal_hostcmd_ioctl(struct net_device *dev, struct ifreq *req)
        int ret = 0;
        mlan_ds_misc_cfg *misc = NULL;
        mlan_ioctl_req *ioctl_req = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -1702,8 +1708,8 @@ woal_hostcmd_ioctl(struct net_device *dev, struct ifreq *req)
        misc->sub_command = MLAN_OID_MISC_HOST_CMD;
        ioctl_req->req_id = MLAN_IOCTL_MISC_CFG;
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -1721,7 +1727,8 @@ woal_hostcmd_ioctl(struct net_device *dev, struct ifreq *req)
                goto done;
        }
 done:
-       kfree(ioctl_req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(ioctl_req);
        LEAVE();
        return ret;
 }
@@ -1742,6 +1749,7 @@ woal_custom_ie_ioctl(struct net_device *dev, struct ifreq *req)
        mlan_ds_misc_cfg *misc = NULL;
        mlan_ds_misc_custom_ie *custom_ie = NULL;
        int ret = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -1783,8 +1791,8 @@ woal_custom_ie_ioctl(struct net_device *dev, struct ifreq *req)
 
        memcpy(&misc->param.cust_ie, custom_ie, sizeof(mlan_ds_misc_custom_ie));
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -1803,7 +1811,8 @@ woal_custom_ie_ioctl(struct net_device *dev, struct ifreq *req)
        }
 
 done:
-       kfree(ioctl_req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(ioctl_req);
        kfree(custom_ie);
        LEAVE();
        return ret;
@@ -1915,6 +1924,7 @@ woal_set_get_custom_ie(moal_private * priv, t_u16 mask, t_u8 * ie, int ie_len)
        mlan_ds_misc_custom_ie *misc_ie = NULL;
        int ret = 0;
        custom_ie *pcust_bcn_ie = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -1941,12 +1951,12 @@ woal_set_get_custom_ie(moal_private * priv, t_u16 mask, t_u8 * ie, int ie_len)
        pcust_bcn_ie->ie_length = ie_len;
        memcpy(pcust_bcn_ie->ie_buffer, ie, ie_len);
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS)
                ret = -EFAULT;
-       }
 
-       kfree(ioctl_req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(ioctl_req);
        LEAVE();
        return ret;
 }
@@ -1967,6 +1977,7 @@ woal_tdls_config_ioctl(struct net_device *dev, struct ifreq *req)
        mlan_ds_misc_cfg *misc = NULL;
        mlan_ds_misc_tdls_config *tdls_data = NULL;
        int ret = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -2009,8 +2020,8 @@ woal_tdls_config_ioctl(struct net_device *dev, struct ifreq *req)
        memcpy(&misc->param.tdls_config, tdls_data,
               sizeof(mlan_ds_misc_tdls_config));
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -2026,7 +2037,8 @@ woal_tdls_config_ioctl(struct net_device *dev, struct ifreq *req)
        }
 
 done:
-       kfree(ioctl_req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(ioctl_req);
        kfree(tdls_data);
        LEAVE();
        return ret;
@@ -2077,6 +2089,7 @@ woal_bss_role_cfg(moal_private * priv, t_u8 action,
        mlan_ds_bss *bss = NULL;
        mlan_ioctl_req *req = NULL;
        struct net_device *dev = priv->netdev;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -2097,7 +2110,8 @@ woal_bss_role_cfg(moal_private * priv, t_u8 action,
                        bss->param.bss_role = *bss_role;
                }
        }
-       if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, wait_option)) {
+       status = woal_request_ioctl(priv, req, wait_option);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -2158,7 +2172,8 @@ woal_bss_role_cfg(moal_private * priv, t_u8 action,
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -2547,7 +2562,8 @@ woal_request_soft_reset(moal_handle * handle)
 
        handle->surprise_removed = MTRUE;
        woal_sched_timeout(5);
-       kfree(req);
+       if (ret != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -2671,6 +2687,7 @@ woal_get_driver_verext(moal_private * priv, struct ifreq *ireq)
        mlan_ds_get_info *info = NULL;
        mlan_ioctl_req *req = NULL;
        int ret = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -2704,8 +2721,8 @@ woal_get_driver_verext(moal_private * priv, struct ifreq *ireq)
                }
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -2724,7 +2741,8 @@ woal_get_driver_verext(moal_private * priv, struct ifreq *ireq)
        PRINTM(MINFO, "MOAL EXTENDED VERSION: %s\n",
               info->param.ver_ext.version_str);
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
 
        LEAVE();
        return ret;
@@ -2861,18 +2879,17 @@ woal_set_get_tx_bf_cfg(moal_private * priv, t_u16 action,
        memcpy(&bf_cfg->param.tx_bf, tx_bf_cfg, sizeof(mlan_ds_11n_tx_bf_cfg));
 
        /* Send IOCTL request to MLAN */
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
-               ret = MLAN_STATUS_FAILURE;
+       ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (ret != MLAN_STATUS_SUCCESS)
                goto done;
-       }
 
        if (action == MLAN_ACT_GET)
                memcpy(tx_bf_cfg, &bf_cfg->param.tx_bf,
                       sizeof(mlan_ds_11n_tx_bf_cfg));
 
 done:
-       kfree(req);
+       if (ret != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -2993,6 +3010,7 @@ woal_get_deep_sleep(moal_private * priv, t_u32 * data)
        int ret = 0;
        mlan_ioctl_req *req = NULL;
        mlan_ds_pm_cfg *pm = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -3006,8 +3024,8 @@ woal_get_deep_sleep(moal_private * priv, t_u32 * data)
        req->req_id = MLAN_IOCTL_PM_CFG;
 
        req->action = MLAN_ACT_GET;
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -3015,7 +3033,8 @@ woal_get_deep_sleep(moal_private * priv, t_u32 * data)
        *(data + 1) = pm->param.auto_deep_sleep.idletime;
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -3116,6 +3135,7 @@ woal_11h_channel_check_ioctl(moal_private * priv)
        int ret = 0;
        mlan_ioctl_req *req = NULL;
        mlan_ds_11h_cfg *ds_11hcfg = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -3130,8 +3150,8 @@ woal_11h_channel_check_ioctl(moal_private * priv)
        req->req_id = MLAN_IOCTL_11H_CFG;
        req->action = MLAN_ACT_SET;
        /* Send Channel Check command and wait until the report is ready */
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -3141,7 +3161,8 @@ woal_11h_channel_check_ioctl(moal_private * priv)
        priv->phandle->meas_start_jiffies = jiffies;
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -3182,7 +3203,8 @@ woal_wifi_direct_mode_cfg(moal_private * priv, t_u16 action, t_u16 * mode)
                PRINTM(MIOCTL, "ACT=%d, wifi_direct_mode=%d\n", action, *mode);
        }
 done:
-       kfree(req);
+       if (ret == MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -3504,11 +3526,10 @@ woal_change_adhoc_chan(moal_private * priv, int channel)
        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;
+       ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (ret != MLAN_STATUS_SUCCESS)
                goto done;
-       }
+
        if (bss->param.bss_chan.channel == (unsigned int)channel) {
                ret = MLAN_STATUS_SUCCESS;
                goto done;
@@ -3526,11 +3547,9 @@ woal_change_adhoc_chan(moal_private * priv, int channel)
        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;
+       ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (ret != MLAN_STATUS_SUCCESS)
                goto done;
-       }
 
        /* Do specific SSID scanning */
        if (MLAN_STATUS_SUCCESS !=
@@ -3545,13 +3564,11 @@ woal_change_adhoc_chan(moal_private * priv, int channel)
               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;
-       }
+       ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
 
 done:
-       kfree(req);
+       if (ret != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -3608,7 +3625,8 @@ woal_find_best_network(moal_private * priv, t_u8 wait_option,
        }
 
 done:
-       kfree(req);
+       if (ret != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -3995,17 +4013,13 @@ woal_get_scan_config(moal_private * priv, mlan_scan_cfg * scan_cfg)
        req->req_id = MLAN_IOCTL_SCAN;
        req->action = MLAN_ACT_GET;
        memset(&scan->param.scan_cfg, 0, sizeof(mlan_scan_cfg));
-       if (MLAN_STATUS_SUCCESS ==
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
-               if (scan_cfg) {
-                       memcpy(scan_cfg, &scan->param.scan_cfg,
-                              sizeof(mlan_scan_cfg));
-               }
-       } else {
-               ret = MLAN_STATUS_FAILURE;
-       }
+       ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (ret == MLAN_STATUS_SUCCESS && scan_cfg)
+               memcpy(scan_cfg, &scan->param.scan_cfg, sizeof(mlan_scan_cfg));
+
 done:
-       kfree(req);
+       if (ret != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -4053,11 +4067,11 @@ woal_set_scan_time(moal_private * priv, t_u16 active_scan_time,
               (int)active_scan_time, (int)passive_scan_time,
               (int)specific_scan_time);
        memcpy(&scan->param.scan_cfg, &scan_cfg, sizeof(mlan_scan_cfg));
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT))
-               ret = MLAN_STATUS_FAILURE;
+       ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+
 done:
-       kfree(req);
+       if (ret != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -4116,6 +4130,7 @@ woal_cancel_scan(moal_private * priv, t_u8 wait_option)
        moal_handle *handle = priv->phandle;
 #ifdef STA_CFG80211
        int i = 0;
+       unsigned long flags;
 #endif
 
        /* If scan is in process, cancel the scan command */
@@ -4134,7 +4149,7 @@ woal_cancel_scan(moal_private * priv, t_u8 wait_option)
        MOAL_REL_SEMAPHORE(&handle->async_sem);
 #ifdef STA_CFG80211
        for (i = 0; i < handle->priv_num; i++) {
-               spin_lock(&handle->priv[i]->scan_req_lock);
+               spin_lock_irqsave(&handle->priv[i]->scan_req_lock, flags);
                if (IS_STA_CFG80211(cfg80211_wext) &&
                    handle->priv[i]->scan_request) {
                        PRINTM(MINFO, "Reporting scan results\n");
@@ -4145,11 +4160,12 @@ woal_cancel_scan(moal_private * priv, t_u8 wait_option)
                                           MFALSE);
                        handle->priv[i]->scan_request = NULL;
                }
-               spin_unlock(&handle->priv[i]->scan_req_lock);
+               spin_unlock_irqrestore(&handle->priv[i]->scan_req_lock, flags);
        }
 #endif
 done:
-       kfree(req);
+       if (ret != MLAN_STATUS_PENDING)
+               kfree(req);
        return ret;
 }
 
@@ -4645,11 +4661,11 @@ woal_set_scan_type(moal_private * priv, t_u32 scan_type)
        scan_cfg.scan_type = scan_type;
        PRINTM(MIOCTL, "Set scan_type=%d\n", (int)scan_type);
        memcpy(&scan->param.scan_cfg, &scan_cfg, sizeof(mlan_scan_cfg));
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT))
-               ret = MLAN_STATUS_FAILURE;
+       ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+
 done:
-       kfree(req);
+       if (ret != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -4690,11 +4706,11 @@ woal_enable_ext_scan(moal_private * priv, t_u8 enable)
        scan_cfg.ext_scan = enable;
        PRINTM(MIOCTL, "Set ext_scan=%d\n", (int)enable);
        memcpy(&scan->param.scan_cfg, &scan_cfg, sizeof(mlan_scan_cfg));
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT))
-               ret = MLAN_STATUS_FAILURE;
+       ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+
 done:
-       kfree(req);
+       if (ret != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -4894,11 +4910,10 @@ woal_get_band(moal_private * priv, int *band)
        /* Get config_bands, adhoc_start_band and adhoc_channel values from
           MLAN */
        req->action = MLAN_ACT_GET;
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
-               ret = MLAN_STATUS_FAILURE;
+       ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (ret != MLAN_STATUS_SUCCESS)
                goto done;
-       }
+
        if (radio_cfg->param.band_cfg.
            config_bands & (BAND_B | BAND_G | BAND_GN))
                support_band |= WIFI_FREQUENCY_BAND_2GHZ;
@@ -4908,7 +4923,8 @@ woal_get_band(moal_private * priv, int *band)
        if (support_band == WIFI_FREQUENCY_ALL_BAND)
                *band = WIFI_FREQUENCY_BAND_AUTO;
 done:
-       kfree(req);
+       if (ret != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -4941,11 +4957,10 @@ woal_set_band(moal_private * priv, char *pband)
 
        /* Get fw supported values from MLAN */
        req->action = MLAN_ACT_GET;
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
-               ret = MLAN_STATUS_FAILURE;
+       ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (ret != MLAN_STATUS_SUCCESS)
                goto done;
-       }
+
        if (*pband == '0') {
                PRINTM(MIOCTL, "Set band to AUTO\n");
                band = radio_cfg->param.band_cfg.fw_bands;
@@ -4998,13 +5013,11 @@ woal_set_band(moal_private * priv, char *pband)
        memset(&radio_cfg->param.band_cfg, 0, sizeof(mlan_ds_band_cfg));
        radio_cfg->param.band_cfg.config_bands = band;
        radio_cfg->param.band_cfg.adhoc_start_band = band;
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
-               ret = MLAN_STATUS_FAILURE;
-               goto done;
-       }
+       ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+
 done:
-       kfree(req);
+       if (ret != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -5122,13 +5135,13 @@ woal_priv_qos_cfg(moal_private * priv, t_u32 action, char *qos_cfg)
                cfg->param.qos_cfg = (t_u8) qosinfo;
                PRINTM(MIOCTL, "set qosinfo=%d\n", qosinfo);
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT))
-               ret = MLAN_STATUS_FAILURE;
+       ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+
        if (action == MLAN_ACT_GET)
                *qos_cfg = cfg->param.qos_cfg;
 done:
-       kfree(req);
+       if (ret != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -5175,13 +5188,11 @@ woal_set_sleeppd(moal_private * priv, char *psleeppd)
                goto done;
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
-               ret = MLAN_STATUS_FAILURE;
-               goto done;
-       }
+       ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+
 done:
-       kfree(req);
+       if (ret != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -5279,6 +5290,7 @@ woal_set_radio(moal_private * priv, t_u8 option)
        int ret = 0;
        mlan_ds_radio_cfg *radio = NULL;
        mlan_ioctl_req *req = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
        ENTER();
        if ((option != 0) && (option != 1)) {
                ret = -EINVAL;
@@ -5294,13 +5306,13 @@ woal_set_radio(moal_private * priv, t_u8 option)
        req->req_id = MLAN_IOCTL_RADIO_CFG;
        req->action = MLAN_ACT_SET;
        radio->param.radio_on_off = option;
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS)
                ret = -EFAULT;
-               goto done;
-       }
+
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -5346,7 +5358,7 @@ woal_mc_policy_cfg(moal_private * priv, t_u16 * enable,
                *enable = cfg->param.multi_chan_policy;
 
 done:
-       if (wait_option && status != MLAN_STATUS_PENDING)
+       if (status != MLAN_STATUS_PENDING)
                kfree(req);
        LEAVE();
        return status;
index 35f4c3f..3affe14 100644 (file)
@@ -3,7 +3,7 @@
   * @brief This file contains the major functions in WLAN
   * driver.
   *
-  * Copyright (C) 2008-2012, Marvell International Ltd.
+  * Copyright (C) 2008-2013, 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
@@ -169,10 +169,12 @@ int rx_work;
 int hw_test;
 
 #if defined(WIFI_DIRECT_SUPPORT)
+#if defined(STA_CFG80211) && defined(UAP_CFG80211)
 #if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
 int p2p_enh;
 #endif
 #endif
+#endif
 
 /** woal_callbacks */
 static mlan_callbacks woal_callbacks = {
@@ -820,6 +822,7 @@ woal_init_sw(moal_handle * handle)
        spin_lock_init(&handle->queue_lock);
 #endif
        spin_lock_init(&handle->driver_lock);
+       spin_lock_init(&handle->ioctl_lock);
 
 #if defined(SDIO_SUSPEND_RESUME)
        handle->is_suspended = MFALSE;
@@ -833,6 +836,12 @@ woal_init_sw(moal_handle * handle)
        handle->cmd52_func = 0;
        handle->cmd52_reg = 0;
        handle->cmd52_val = 0;
+#if defined(STA_CFG80211) || defined(UAP_CFG80211)
+       handle->scan_chan_gap = DEF_SCAN_CHAN_GAP;
+#ifdef WIFI_DIRECT_SUPPORT
+       handle->miracast_scan_time = DEF_MIRACAST_SCAN_TIME;
+#endif
+#endif
        init_waitqueue_head(&handle->hs_activate_wait_q);
 #endif
 
@@ -1102,15 +1111,16 @@ woal_process_regrdwr(moal_handle * handle, t_u8 * type_string,
        reg->param.reg_rw.value = value;
 
        /* request ioctl for STA */
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(handle->priv[0], ioctl_req, MOAL_IOCTL_WAIT))
+       ret = woal_request_ioctl(handle->priv[0], ioctl_req, MOAL_IOCTL_WAIT);
+       if (ret != MLAN_STATUS_SUCCESS)
                goto done;
        PRINTM(MINFO, "Register type: %d, offset: 0x%x, value: 0x%x\n", type,
               offset, value);
        ret = MLAN_STATUS_SUCCESS;
 
 done:
-       kfree(ioctl_req);
+       if (ret != MLAN_STATUS_PENDING)
+               kfree(ioctl_req);
        LEAVE();
        return ret;
 }
@@ -2366,7 +2376,8 @@ woal_shutdown_fw(moal_private * priv, t_u8 wait_option)
        /* add 100 ms delay to avoid back to back init/shutdown */
        mdelay(100);
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return status;
 }
@@ -2677,6 +2688,9 @@ int
 woal_close(struct net_device *dev)
 {
        moal_private *priv = (moal_private *) netdev_priv(dev);
+#if defined(STA_SUPPORT) && defined(STA_CFG80211)
+       unsigned long flags;
+#endif
 
        ENTER();
 #ifdef STA_SUPPORT
@@ -2684,12 +2698,12 @@ woal_close(struct net_device *dev)
        if (IS_STA_CFG80211(cfg80211_wext) &&
            (priv->bss_type == MLAN_BSS_TYPE_STA))
                woal_clear_conn_params(priv);
-       spin_lock(&priv->scan_req_lock);
+       spin_lock_irqsave(&priv->scan_req_lock, flags);
        if (IS_STA_CFG80211(cfg80211_wext) && priv->scan_request) {
                cfg80211_scan_done(priv->scan_request, MTRUE);
                priv->scan_request = NULL;
        }
-       spin_unlock(&priv->scan_req_lock);
+       spin_unlock_irqrestore(&priv->scan_req_lock, flags);
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) || defined(COMPAT_WIRELESS)
        if (IS_STA_CFG80211(cfg80211_wext) && priv->sched_scanning) {
                woal_stop_bg_scan(priv, MOAL_IOCTL_WAIT);
@@ -3179,6 +3193,8 @@ woal_process_tcp_ack(moal_private * priv, mlan_buffer * pmbuf)
                                kmalloc(sizeof(struct tcp_sess), GFP_ATOMIC);
                        if (!tcp_session) {
                                PRINTM(MERROR, "Fail to allocate tcp_sess.\n");
+                               spin_unlock_irqrestore(&priv->tcp_sess_lock,
+                                                      flags);
                                goto done;
                        }
                        tcp_session->ack_skb = pmbuf->pdesc;
@@ -4201,11 +4217,12 @@ woal_reassociation_thread(void *data)
                                        rate->param.rate_cfg.rate =
                                                priv->rate_index;
 
-                                       if (MLAN_STATUS_SUCCESS
-                                           != woal_request_ioctl(priv, req,
-                                                                 MOAL_CMD_WAIT))
-                                       {
-                                               kfree(req);
+                                       status = woal_request_ioctl(priv, req,
+                                                                   MOAL_CMD_WAIT);
+                                       if (status != MLAN_STATUS_SUCCESS) {
+                                               if (status !=
+                                                   MLAN_STATUS_PENDING)
+                                                       kfree(req);
                                                LEAVE();
                                                return MLAN_STATUS_FAILURE;
                                        }
@@ -5141,7 +5158,7 @@ woal_sdio_reg_dbg(moal_handle * phandle)
        unsigned int reg, reg_start, reg_end;
        unsigned int reg_table[] =
                { 0x4C, 0x50, 0x54, 0x55, 0x58, 0x59, 0x5c, 0x5d };
-       char buf[128], *ptr;
+       char buf[256], *ptr;
 
        sdio_claim_host(((struct sdio_mmc_card *)phandle->card)->func);
        for (loop = 0; loop < 5; loop++) {
@@ -5963,6 +5980,9 @@ woal_cleanup_module(void)
        moal_handle *handle = NULL;
        int index = 0;
        int i;
+#if defined(STA_SUPPORT) && defined(STA_CFG80211)
+       unsigned long flags;
+#endif
 
        ENTER();
 
@@ -5998,14 +6018,16 @@ woal_cleanup_module(void)
                                    (handle->priv[i]->bss_type ==
                                     MLAN_BSS_TYPE_STA))
                                        woal_clear_conn_params(handle->priv[i]);
-                               spin_lock(&handle->priv[i]->scan_req_lock);
+                               spin_lock_irqsave(&handle->priv[i]->
+                                                 scan_req_lock, flags);
                                if (IS_STA_CFG80211(cfg80211_wext) &&
                                    handle->priv[i]->scan_request) {
                                        cfg80211_scan_done(handle->priv[i]->
                                                           scan_request, MTRUE);
                                        handle->priv[i]->scan_request = NULL;
                                }
-                               spin_unlock(&handle->priv[i]->scan_req_lock);
+                               spin_unlock_irqrestore(&handle->priv[i]->
+                                                      scan_req_lock, flags);
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) || defined(COMPAT_WIRELESS)
                                if (IS_STA_CFG80211(cfg80211_wext) &&
                                    handle->priv[i]->sched_scanning) {
@@ -6193,11 +6215,13 @@ module_param(rx_work, int, 0);
 MODULE_PARM_DESC(rx_work,
                 "0: default; 1: Enable rx_work_queue; 2: Disable rx_work_queue");
 #if defined(WIFI_DIRECT_SUPPORT)
+#if defined(STA_CFG80211) && defined(UAP_CFG80211)
 #if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
 module_param(p2p_enh, int, 0);
 MODULE_PARM_DESC(p2p_enh, "1: Enable enhanced P2P; 0: Disable enhanced P2P");
 #endif
 #endif
+#endif
 
 MODULE_DESCRIPTION("M-WLAN Driver");
 MODULE_AUTHOR("Marvell International Ltd.");
index eba49e9..1e824e3 100644 (file)
@@ -2,7 +2,7 @@
   *
   * @brief This file contains wlan driver specific defines etc.
   *
-  * Copyright (C) 2008-2012, Marvell International Ltd.
+  * Copyright (C) 2008-2013, 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
@@ -519,6 +519,11 @@ out:
 /** Threshold value of number of times the Tx timeout happened */
 #define NUM_TX_TIMEOUT_THRESHOLD      5
 
+/** TDLS connected event */
+#define CUS_EVT_TDLS_CONNECTED           "EVENT=TDLS_CONNECTED"
+/** TDLS tear down event */
+#define CUS_EVT_TDLS_TEARDOWN            "EVENT=TDLS_TEARDOWN"
+
 /** AP connected event */
 #define CUS_EVT_AP_CONNECTED           "EVENT=AP_CONNECTED"
 
@@ -627,6 +632,11 @@ out:
 /** Offset for subcommand */
 #define SUBCMD_OFFSET       4
 
+/** default scan channel gap  */
+#define DEF_SCAN_CHAN_GAP   50
+/** default scan time per channel in miracast mode */
+#define DEF_MIRACAST_SCAN_TIME   40
+
 /** Macro to extract the TOS field from a skb */
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
 #define SKB_TOS(skb) (ip_hdr(skb)->tos)
@@ -712,7 +722,7 @@ typedef struct _wait_queue {
 /** Driver mode WIFIDIRECT bit */
 #define DRV_MODE_WIFIDIRECT       MBIT(2)
 /** Maximum WIFIDIRECT BSS */
-#define MAX_WIFIDIRECT_BSS        1
+#define MAX_WIFIDIRECT_BSS        2
 /** Default WIFIDIRECT BSS */
 #define DEF_WIFIDIRECT_BSS        1
 #if defined(STA_CFG80211) && defined(UAP_CFG80211)
@@ -1082,7 +1092,13 @@ struct _moal_handle {
        enum ieee80211_band band;
     /** first scan done flag */
        t_u8 first_scan_done;
+    /** scan channel gap */
+       t_u16 scan_chan_gap;
 #ifdef WIFI_DIRECT_SUPPORT
+    /** miracast mode */
+       t_u8 miracast_mode;
+       /** scan time in miracast mode */
+       t_u16 miracast_scan_time;
        /** remain on channel flag */
        t_u8 remain_on_channel;
        /** bss index for remain on channel */
@@ -1161,6 +1177,8 @@ struct _moal_handle {
 #endif
        /** Driver spin lock */
        spinlock_t driver_lock;
+       /** Driver ioctl spin lock */
+       spinlock_t ioctl_lock;
        /** Card specific driver version */
        t_s8 driver_version[MLAN_MAX_VER_STR_LEN];
        char *fwdump_fname;
index ca5e920..f51763e 100644 (file)
@@ -2,7 +2,7 @@
   *
   * @brief This file contains standard ioctl functions
   *
-  * Copyright (C) 2008-2012, Marvell International Ltd.
+  * Copyright (C) 2008-2013, 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
@@ -210,6 +210,7 @@ woal_warm_reset(moal_private * priv)
 #endif
 #endif
 #endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -248,10 +249,11 @@ woal_warm_reset(moal_private * priv)
                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)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
-                       kfree(req);
+                       if (status != MLAN_STATUS_PENDING)
+                               kfree(req);
                        goto done;
                }
                kfree(req);
@@ -561,6 +563,7 @@ woal_11n_htcap_cfg(moal_private * priv, struct iwreq *wrq)
        mlan_ds_11n_cfg *cfg_11n = NULL;
        int ret = 0;
        int data_length = wrq->u.data.length;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -610,8 +613,8 @@ woal_11n_htcap_cfg(moal_private * priv, struct iwreq *wrq)
                req->action = MLAN_ACT_SET;
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -621,8 +624,8 @@ woal_11n_htcap_cfg(moal_private * priv, struct iwreq *wrq)
                data_length = 1;
                cfg_11n->param.htcap_cfg.htcap = 0;
                cfg_11n->param.htcap_cfg.misc_cfg = BAND_SELECT_A;
-               if (MLAN_STATUS_SUCCESS !=
-                   woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto done;
                }
@@ -646,7 +649,8 @@ woal_11n_htcap_cfg(moal_private * priv, struct iwreq *wrq)
        wrq->u.data.length = data_length;
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -667,6 +671,7 @@ woal_11n_amsdu_aggr_ctrl(moal_private * priv, struct iwreq *wrq)
        mlan_ds_11n_cfg *cfg_11n = NULL;
        int ret = 0;
        int data_length = wrq->u.data.length;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -699,8 +704,8 @@ woal_11n_amsdu_aggr_ctrl(moal_private * priv, struct iwreq *wrq)
                /* Update 11n tx parameters in MLAN */
                req->action = MLAN_ACT_SET;
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -714,7 +719,8 @@ woal_11n_amsdu_aggr_ctrl(moal_private * priv, struct iwreq *wrq)
        }
        wrq->u.data.length = 2;
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -735,6 +741,7 @@ woal_11n_tx_cfg(moal_private * priv, struct iwreq *wrq)
        mlan_ds_11n_cfg *cfg_11n = NULL;
        int ret = 0;
        int data_length = wrq->u.data.length;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -782,8 +789,8 @@ woal_11n_tx_cfg(moal_private * priv, struct iwreq *wrq)
                /* Update 11n tx parameters in MLAN */
                req->action = MLAN_ACT_SET;
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -793,8 +800,8 @@ woal_11n_tx_cfg(moal_private * priv, struct iwreq *wrq)
                data_length = 1;
                cfg_11n->param.tx_cfg.httxcap = 0;
                cfg_11n->param.tx_cfg.misc_cfg = BAND_SELECT_A;
-               if (MLAN_STATUS_SUCCESS !=
-                   woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto done;
                }
@@ -816,7 +823,8 @@ woal_11n_tx_cfg(moal_private * priv, struct iwreq *wrq)
        wrq->u.data.length = data_length;
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -837,6 +845,7 @@ woal_11n_prio_tbl(moal_private * priv, struct iwreq *wrq)
        mlan_ds_11n_cfg *cfg_11n = NULL;
        int ret = 0;
        int data_length = wrq->u.data.length;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -858,8 +867,8 @@ woal_11n_prio_tbl(moal_private * priv, struct iwreq *wrq)
        if (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)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto error;
                }
@@ -895,8 +904,8 @@ woal_11n_prio_tbl(moal_private * priv, struct iwreq *wrq)
 
                /* Update aggr priority table in MLAN */
                req->action = MLAN_ACT_SET;
-               if (MLAN_STATUS_SUCCESS !=
-                   woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto error;
                }
@@ -907,7 +916,8 @@ woal_11n_prio_tbl(moal_private * priv, struct iwreq *wrq)
        }
 
 error:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -927,6 +937,7 @@ woal_addba_reject(moal_private * priv, struct iwreq *wrq)
        mlan_ioctl_req *req = NULL;
        mlan_ds_11n_cfg *cfg_11n = NULL;
        int data_length = wrq->u.data.length;
+       mlan_status status = MLAN_STATUS_SUCCESS;
        ENTER();
 
        copy_len = MIN(sizeof(data), sizeof(int) * data_length);
@@ -943,9 +954,8 @@ woal_addba_reject(moal_private * priv, struct iwreq *wrq)
                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))
-               {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto error;
                }
@@ -978,9 +988,8 @@ woal_addba_reject(moal_private * priv, struct iwreq *wrq)
 
                /* Update aggr priority table in MLAN */
                req->action = MLAN_ACT_SET;
-               if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req,
-                                                             MOAL_IOCTL_WAIT))
-               {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto error;
                }
@@ -990,7 +999,8 @@ woal_addba_reject(moal_private * priv, struct iwreq *wrq)
                goto error;
        }
 error:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -1010,6 +1020,7 @@ woal_addba_para_updt(moal_private * priv, struct iwreq *wrq)
        mlan_ioctl_req *req = NULL;
        mlan_ds_11n_cfg *cfg_11n = NULL;
        int data_length = wrq->u.data.length;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -1026,8 +1037,8 @@ woal_addba_para_updt(moal_private * priv, struct iwreq *wrq)
        if (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)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto error;
                }
@@ -1078,8 +1089,8 @@ woal_addba_para_updt(moal_private * priv, struct iwreq *wrq)
                       data[0], data[1], data[2], data[3], data[4]);
                /* Update Add BA parameters in MLAN */
                req->action = MLAN_ACT_SET;
-               if (MLAN_STATUS_SUCCESS !=
-                   woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = MLAN_STATUS_FAILURE;
                        goto error;
                }
@@ -1090,7 +1101,8 @@ woal_addba_para_updt(moal_private * priv, struct iwreq *wrq)
        }
 
 error:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -1110,6 +1122,7 @@ woal_txbuf_cfg(moal_private * priv, struct iwreq *wrq)
        mlan_ioctl_req *req = NULL;
        mlan_ds_11n_cfg *cfg_11n = NULL;
        int ret = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
        req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
@@ -1130,8 +1143,8 @@ woal_txbuf_cfg(moal_private * priv, struct iwreq *wrq)
                       "Don't support set Tx buffer size after driver loaded!\n");
                goto done;
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -1143,7 +1156,8 @@ woal_txbuf_cfg(moal_private * priv, struct iwreq *wrq)
        }
        wrq->u.data.length = 1;
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -1296,6 +1310,7 @@ woal_inactivity_timeout_ext(moal_private * priv, struct iwreq *wrq)
        mlan_ds_pm_cfg *pmcfg = NULL;
        pmlan_ds_inactivity_to inac_to = NULL;
        int data_length = wrq->u.data.length;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -1333,8 +1348,8 @@ woal_inactivity_timeout_ext(moal_private * priv, struct iwreq *wrq)
                inac_to->ps_entry_timeout = data[3];
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -1357,7 +1372,8 @@ woal_inactivity_timeout_ext(moal_private * priv, struct iwreq *wrq)
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -1379,6 +1395,7 @@ woal_ecl_sys_clock(moal_private * priv, struct iwreq *wrq)
        mlan_ds_misc_cfg *cfg = NULL;
        int data_length = wrq->u.data.length;
        int i = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -1413,8 +1430,8 @@ woal_ecl_sys_clock(moal_private * priv, struct iwreq *wrq)
        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)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto done;
                }
@@ -1435,8 +1452,8 @@ woal_ecl_sys_clock(moal_private * priv, struct iwreq *wrq)
 
                /* 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)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto done;
                }
@@ -1467,14 +1484,15 @@ woal_ecl_sys_clock(moal_private * priv, struct iwreq *wrq)
                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)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto done;
                }
        }
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -1500,6 +1518,7 @@ woal_band_cfg(moal_private * priv, struct iwreq *wrq)
        t_u32 adhoc_chan_bandwidth = 0;
        mlan_ioctl_req *req = NULL;
        mlan_ds_radio_cfg *radio_cfg = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -1530,8 +1549,8 @@ woal_band_cfg(moal_private * priv, struct iwreq *wrq)
                /* Get config_bands, adhoc_start_band and adhoc_channel values
                   from MLAN */
                req->action = MLAN_ACT_GET;
-               if (MLAN_STATUS_SUCCESS !=
-                   woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto error;
                }
@@ -1627,15 +1646,16 @@ woal_band_cfg(moal_private * priv, struct iwreq *wrq)
                radio_cfg->param.band_cfg.adhoc_channel = adhoc_channel;
                radio_cfg->param.band_cfg.adhoc_chan_bandwidth =
                        adhoc_chan_bandwidth;
-               if (MLAN_STATUS_SUCCESS !=
-                   woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+               status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+               if (status != MLAN_STATUS_SUCCESS) {
                        ret = -EFAULT;
                        goto error;
                }
        }
 
 error:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -1656,6 +1676,7 @@ woal_reg_read_write(moal_private * priv, struct iwreq *wrq)
        mlan_ioctl_req *req = NULL;
        mlan_ds_reg_mem *reg = NULL;
        int data_length = wrq->u.data.length;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -1690,8 +1711,8 @@ woal_reg_read_write(moal_private * priv, struct iwreq *wrq)
        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)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -1708,7 +1729,8 @@ woal_reg_read_write(moal_private * priv, struct iwreq *wrq)
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -1729,6 +1751,7 @@ woal_read_eeprom(moal_private * priv, struct iwreq *wrq)
        mlan_ioctl_req *req = NULL;
        mlan_ds_reg_mem *reg = NULL;
        int data_length = wrq->u.data.length;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -1760,8 +1783,8 @@ woal_read_eeprom(moal_private * priv, struct iwreq *wrq)
        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)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -1778,7 +1801,8 @@ woal_read_eeprom(moal_private * priv, struct iwreq *wrq)
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -1799,6 +1823,7 @@ woal_mem_read_write(moal_private * priv, struct iwreq *wrq)
        mlan_ioctl_req *req = NULL;
        mlan_ds_reg_mem *reg_mem = NULL;
        int data_length = wrq->u.data.length, copy_len;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -1839,8 +1864,8 @@ woal_mem_read_write(moal_private * priv, struct iwreq *wrq)
               (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)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -1857,7 +1882,8 @@ woal_mem_read_write(moal_private * priv, struct iwreq *wrq)
        }
 
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -2001,6 +2027,7 @@ woal_tx_power_cfg(moal_private * priv, struct iwreq *wrq)
        int i, power_ext_len = 0;
        int *ptr = power_data;
        mlan_power_group *pwr_grp = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
        ENTER();
 
        memset(&bss_info, 0, sizeof(bss_info));
@@ -2139,8 +2166,8 @@ woal_tx_power_cfg(moal_private * priv, struct iwreq *wrq)
                        pcfg->param.power_ext.num_pwr_grp = 1;
                }
        }
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -2183,7 +2210,8 @@ woal_tx_power_cfg(moal_private * priv, struct iwreq *wrq)
                wrq->u.data.length = power_ext_len;
        }
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -2202,6 +2230,7 @@ woal_get_txrx_rate(moal_private * priv, struct iwreq *wrq)
        int ret = 0;
        mlan_ds_rate *rate = NULL;
        mlan_ioctl_req *req = NULL;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -2215,8 +2244,8 @@ woal_get_txrx_rate(moal_private * priv, struct iwreq *wrq)
        req->req_id = MLAN_IOCTL_RATE;
        req->action = MLAN_ACT_GET;
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -2229,7 +2258,8 @@ woal_get_txrx_rate(moal_private * priv, struct iwreq *wrq)
        }
        wrq->u.data.length = 2;
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -2305,6 +2335,7 @@ woal_beacon_interval(moal_private * priv, struct iwreq *wrq)
        mlan_ds_bss *bss = NULL;
        mlan_ioctl_req *req = NULL;
        int bcn = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -2336,8 +2367,8 @@ woal_beacon_interval(moal_private * priv, struct iwreq *wrq)
                bss->param.bcn_interval = bcn;
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -2350,7 +2381,8 @@ woal_beacon_interval(moal_private * priv, struct iwreq *wrq)
        }
        wrq->u.data.length = 1;
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -2370,6 +2402,7 @@ woal_atim_window(moal_private * priv, struct iwreq *wrq)
        mlan_ds_bss *bss = NULL;
        mlan_ioctl_req *req = NULL;
        int atim = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -2400,8 +2433,8 @@ woal_atim_window(moal_private * priv, struct iwreq *wrq)
                bss->param.atim_window = atim;
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -2414,7 +2447,8 @@ woal_atim_window(moal_private * priv, struct iwreq *wrq)
        }
        wrq->u.data.length = 1;
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -2434,6 +2468,7 @@ woal_set_get_txrate(moal_private * priv, struct iwreq *wrq)
        mlan_ds_rate *rate = NULL;
        mlan_ioctl_req *req = NULL;
        int rateindex = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
        if (wrq->u.data.length) {
@@ -2471,8 +2506,8 @@ woal_set_get_txrate(moal_private * priv, struct iwreq *wrq)
                rate->param.rate_cfg.rate = rateindex;
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        } else {
@@ -2489,7 +2524,8 @@ woal_set_get_txrate(moal_private * priv, struct iwreq *wrq)
                        ret = -EFAULT;
        }
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -2509,6 +2545,7 @@ woal_set_get_regioncode(moal_private * priv, struct iwreq *wrq)
        mlan_ds_misc_cfg *cfg = NULL;
        mlan_ioctl_req *req = NULL;
        int region = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
 
@@ -2536,8 +2573,8 @@ woal_set_get_regioncode(moal_private * priv, struct iwreq *wrq)
                cfg->param.region_code = region;
        }
 
-       if (MLAN_STATUS_SUCCESS !=
-           woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -2549,7 +2586,8 @@ woal_set_get_regioncode(moal_private * priv, struct iwreq *wrq)
                        ret = -EFAULT;
        }
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -2697,6 +2735,7 @@ woal_set_get_qos_cfg(moal_private * priv, struct iwreq *wrq)
        mlan_ds_wmm_cfg *cfg = NULL;
        mlan_ioctl_req *req = NULL;
        int data = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
        req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
@@ -2717,8 +2756,8 @@ woal_set_get_qos_cfg(moal_private * priv, struct iwreq *wrq)
                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)) {
+       status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+       if (status != MLAN_STATUS_SUCCESS) {
                ret = -EFAULT;
                goto done;
        }
@@ -2731,7 +2770,8 @@ woal_set_get_qos_cfg(moal_private * priv, struct iwreq *wrq)
                wrq->u.data.length = 1;
        }
 done:
-       kfree(req);
+       if (status != MLAN_STATUS_PENDING)
+               kfree(req);
        LEAVE();
        return ret;
 }
@@ -2751,6 +2791,7 @@ woal_wws_cfg(moal_private * priv, struct iwreq *wrq)
        mlan_ds_misc_cfg *wws = NULL;
        mlan_ioctl_req *req = NULL;
        int data = 0;
+       mlan_status status = MLAN_STATUS_SUCCESS;
 
        ENTER();
        req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
@@ -2775,8 +2816,8 @@ woal_wws_cfg(moal_private * priv, struct iwreq *wrq)