ACK: [PATCH][Xenial SRU] UBUNTU: SAUCE: Redpine: Upgrade to ver. 1.2.RC9

Colin Ian King colin.king at canonical.com
Thu May 18 09:48:29 UTC 2017


On 17/05/17 04:29, Shrirang Bagul wrote:
> BugLink: https://bugs.launchpad.net/bugs/1690498
> 
> Vendor release ver: 1.2.RC9
> 
> Changelog:
> 
> 1.2.RC9 -
>     WLAN Bug Fixes:
>     ---------------
>     1) BT reset added before going to S3/S4/S5 sleep when WoWLAN is enabled.
>     2) Station connection check before going to S3/S4/S5 sleep removed.
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) S5 with WoWLAN does not work.
>     2) For GTK rekey, wakeup trigger send to host.
> 
>     BT Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) To connect multiple BT slaves, connection should be initiated
>        from rsi module.
>     2) In coex mode, BT file transfer fails at times with certain mobiles.
> 
> 1.2.RC8 -
>     WLAN Bug Fixes:
>     ---------------
>     1) Added power leak fixes for S4.
>     2) S5 WoLAN issue resolved.
>     3) Wakeup short pulse issue resolved.
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) S5 with WoWLAN does not work.
>     2) For GTK rekey, wakeup trigger send to host.
> 
>     BT Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) To connect multiple BT slaves, connection should be initiated
>        from rsi module.
>     2) In coex mode, BT file transfer fails at times with certain mobiles.
> 
> 1.2.RC7 -
>     WLAN Bug Fixes:
>     ---------------
>     1) Configured host wakeup pin as active low from driver.
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) S5 with WoWLAN does not work.
>     2) For GTK rekey, wakeup trigger send to host.
> 
>     BT Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) To connect multiple BT slaves, connection should be initiated
>        from rsi module.
>     2) In coex mode, BT file transfer fails at times with certain mobiles.
> 
> 1.2.RC6 -
>     WLAN Bug Fixes:
>     ---------------
>     1) AP data throughput issue resolved.
>     2) Scan results issue resolved.
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) S5 with WoWLAN does not work.
>     2) For GTK rekey, wakeup trigger send to host.
> 
>     BT Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) To connect multiple BT slaves, connection should be initiated
>        from rsi module.
>     2) In coex mode, BT file transfer fails at times with certain mobiles.
> 
> 1.2.RC4 -
>     WLAN Bug Fixes:
>     ---------------
>     1) Buffer status interrupt handling improved.
>     2) Scan results update in sta+bt dual mode issue resolved
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) S5 with WoWLAN does not work.
>     2) For GTK rekey, wakeup trigger send to host.
> 
>     BT Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) To connect multiple BT slaves, connection should be initiated
>        from rsi module.
>     2) In coex mode, BT file transfer fails at times with certain mobiles.
> 
> 1.2.RC3 -
>     WLAN Bug Fixes:
>     ---------------
>     1) WoWLAN multiple cycles issue resolved.
>     2) Driver Version is correctly updated.
>     3) Default operating mode for Caracalla board is corrected.
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) S5 with WoWLAN does not work.
>     2) For GTK rekey, wakeup trigger send to host.
> 
>     BT New Features:
>     ----------------
>     1) Multiple slaves issue in WLAN-BT coex mode resolved.
> 
>     BT Limitations/Features NOT Supported:
>     --------------------------------------
>     1) To connect multiple BT slaves, connection should be initiated
>        from rsi module.
>     2) In coex mode, BT file transfer fails at times with certain mobiles.
> 
> 1.2.RC2 -
>     WLAN Bug Fixes:
>     ---------------
>     1) Suspend/resume issues resolved.
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) S5 with WoWLAN does not work.
>     2) For GTK rekey, wakeup trigger send to host.
>     3) EAP not tested
> 
>     BT Limitations/Features NOT Supported:
>     --------------------------------------
>     1) To connect multiple BT slaves, connection should be initiated
>        from rsi module.
>     2) In coex mode, BT file transfer fails at times with certain mobiles.
> 
> 1.2.RC1 -
>     WLAN New Features:
>     ------------------
>     1) Restrict functional modes as per device operating mode
>     2) Default operating mode for Caracalla board is 13
> 
>     WLAN Bug Fixes:
>     ---------------
>     1) Driver oops issue if more than 4 clients try to connect in
>        operating mode 14 resolved.
>     2) Issue with connecting more than max clients and disconnection
>        issue resolved.
>     3) L2 test stop when wlan interface down issue resolved.
>     4) Driver version corrected.
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) S5 with WoWLAN does not work.
>     2) For GTK rekey, wakeup trigger send to host.
>     3) EAP not tested
>     4) For channels 12 and 13 in US region max TX power is coming 0 in
>        beacons.
> 
>     BT Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) To connect multiple BT slaves, connection should be initiated
>        from rsi module.
>     2) In coex mode, BT file transfer fails at times with certain
>        mobiles.
> 
> 1.1 -
>     Generic
>     -------
>     1) Firmware file name is displayed along with version information.
>        at the driver load time.
>     2) Device operating mode is made available in the below files:
>        /sys/module/rsi_sdio/parameters/dev_oper_mode
>        /sys/module/rsi_usb/parameters/dev_oper_mode
>     3) Wi-Fi BT radio sharing has been improved.
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) S5 with WoWLAN does not work.
>     2) For GTK rekey, wakeup trigger send to host.
>     3) EAP not tested
>     4) For channels 12 and 13 in US region max TX power is coming 0 in beacons.
> 
>     BT Limitations/Features NOT Supported:
>     --------------------------------------
>     1) To connect multiple BT slaves, connection should be initiated from rsi module.
>     2) In coex mode, BT file transfer fails at times with certain mobiles.
> 
> 1.0.RC7 -
>     Generic
>     -------
>     1) Driver version, Firmware version and operating mode information is displayed
>        at the driver load time.
>     2) Driver version is made available in the below files:
>        /sys/module/rsi_91x/version
>        /sys/module/rsi_sdio/version
>        /sys/module/rsi_usb/version
> 
>     WLAN Bug Fixes:
>     ---------------
>     1) Power save latencies resolved
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) S5 with WoWLAN does not work.
>     2) For GTK rekey, wakeup trigger send to host.
>     3) EAP not tested
> 
>     BT Limitations/Features NOT Supported:
>     --------------------------------------
>     1) To connect multiple BT slaves, connection should be initiated from rsi module.
>     2) In coex mode, BT file transfer fails at times with certain mobiles.
> 
> 1.0 -
>     WLAN New Features:
>     ------------------
>     1) Station mode
>     2) All Security modes (WEP/WPA/WPA2)
>     3) Station Power save (legacy and UAPSD)
>     4) Bgscan and roaming
>     5) External antenna selection
>     6) Neighbour report request in RRM
>     7) Regulatory (802)11d) support
>     8) Management frame protection support (802)11w)
>     9) Software RF-kill
>     10) AP mode
>     11) S3, S4 suspend and resume
>     12) WoWLAN
>     13) AP Power save
>     14) Wi-Fi direct
> 
>     WLAN Bug Fixes:
>     ---------------
>     1) Allowed channels 12 and 13 in FCC region.
>     2) For the allowed channels 12 and 13 in any region, power configuration
>        updated as per Caracalla regulatory rules.
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) S5 with WoWLAN does not work.
>     2) For GTK rekey, wakeup trigger send to host.
>     3) EAP not tested
> 
>     BT New Features:
>     ----------------
>     1) BT EDR mode
>     2) BT LE mode
>     3) BT coex mode (All the coex modes))
>     4) Multi-slave mode supported)
> 
>     BT Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) To connect multiple BT slaves, connection should be initiated from rsi module.
>     2) In coex mode, BT file transfer fails at times with certain mobiles.
> 
> 1.0_RC3 -
>     Gerenic:
>     --------
>     1) Device operating mode is changed as module parameter. Please check
>        README or TRM on how to configure this while loading the modules.
>     2) Max number of stations supported in Wi-Fi AP alone mode is 32, and AP +
>        BT coex mode is 4.
>     3) AP + BT-EDR + BLE support added.
> 
>     WLAN Bug Fixes:
>     ---------------
>     1) Bgscan probe request issue resolved.
>     2) WoWLAN before association issue resolved.
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) S4 with and without WoWLAN works with the work-around implemented by Canonical.
>     2) S5 with WoWLAN does not work.
>     3) For GTK rekey, wakeup trigger send to host.
>     4) EAP not tested
>     5) To connect multiple BT slaves, connection should be initiated from rsi module.
>     6) In coex mode, BT file transfer fails at times with certain mobiles.
> 
>     BT New Features:
>     ----------------
>     1) Multi-slave mode supported.
> 
>     BT Bug Fixes:
>     -------------
>     1) Radio sharing of coex modes improved.
> 
> 1.0.RC2 -
>     WLAN Bug Fixes:
>     ---------------
>     1) PVB preparation issue in AP mode resolved.
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) EAP not supported
>     2) Issue while Resume in S4 with or without WoWLAN.
>     3) S5 with WoWLAN does not work.
>     4) For GTK rekey, wakeup trigger send to host.
> 
>     BT Bug Fixes:
>     -------------
>     1) BT dual mode disconnection issue resolved
>     2) AP BT dual mode issue resolved
> 
> 1.0_RC1 -
>     WLAN Bug Fixes:
>     ---------------
>     1) WoWLAN in Co-ex mode issue resolved.
>     2) AP beacon DTIM count update issue resolved.
>     3) Firmware assertion (0x5d) in bgscan issue is resolved.
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) EAP not supported
>     2) Issue while Resume in S4 with or without WoWLAN.
>     3) S5 with WoWLAN does not work.
>     4) For GTK rekey, wakeup trigger send to host.
> 
> 0.9.8.5_RC6 -
>     WLAN Bug Fixes:
>     ---------------
>     1) Firmware CRC check fail issue resolved
>     2) Compilation fails on 4.10.1 kernel issue resolved
>     3) BG scan issues resolved
>     4) AP mode regulatory fixes
>     5) WoWLAN issues resolved.
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) EAP not supported
>     2) Issue while Resume in S4 with or without WoWLAN.
>     3) S5 with WoWLAN does not work.
>     4) For GTK rekey, wakeup trigger send to host.
> 
> 0.9.8.5_RC4 -
>     WLAN Bug Fixes:
>     -------------------
>     1) AP mode configuration in channels 12 and 13 for EU region issue resolved.
>     2) Data latencies in AP mode issue resolved.
>     3) Roaming issues resolved.
>     4) AP WEP mode issue resolved.
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) EAP not supported
>     2) Issue while Resume in S4 with or without WoWLAN.
>     3) S5 with WoWLAN does not work.
>     4) For GTK rekey, wakeup trigger send to host.
>     5) WoWLAN does not work in WEP mode.
> 
>     Others:
>     -------
>     1) USB binds only to RS9113, let upstream kernel driver handle other RSI chips
> 
> 0.9.8.5_RC3 -
>     WLAN Bug Fixes:
>     -------------------
>     1) Power save issue in station mode (By default UAPSD is enabled on
>     Caracalla board) fixed.
>     2) WoWLAN with S3 issue resolved
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) EAP not supported
>     2) Not verified removing SDIO interrupt polling
>     3) S4/S5 sleep states not supported (with and without WoWLAN)
> 
> 0.9.8.5_RC2 -
>     WLAN Bug Fixes:
>     -------------------
>     1) Power save issue in station mode (By default UAPSD is enabled on
>     Caracalla board) fixed.
>     2) Firmware assert 0x71 (while doing bgscan) issue fixed.
>     3) Keep alive functionality in station mode issue fixed.
>     4) Data traffic stops when connected to multiple stations issue resolved
>     5) WoWLAN not working issue is resolved
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) EAP not supported
>     2) Not verified removing SDIO interrupt polling
>     3) S4/S5 sleep states not supported (with and without WoWLAN)
>     4) Wi-Fi direct testing is in progress
> 
> 0.9.8.5_RC1 -
>     WLAN Bug Fixes:
>     -------------------
>     1) Observed unicast probe requests during bgscan issue fixed
>     2) Firmware assert 0x71 (while doing bgscan) issue fixed.
>     3) Crash when doing rmmod while data traffic is going on issue resolved.
>     4) Beacons stopped after 5 minutes of data traffic issue fixed.
>     5) Keep alive functionality in station mode issue fixed
>     6) 11n data rates issue in station mode resolved.
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) EAP not supported
>     2) Not verified removing SDIO interrupt polling
>     3) S4/S5 sleep states not supported (with.without WoWLAN)
>     4) power save is not working consistently
>     5) WoWLAN is not working consistently
> 
> 0.9.8.3 -
>     WLAN New Features:
>     -----------------------------------------
>     1) AP Mode
>     2) S3, S4 suspend and resume
>     3) WoWLAN [Testing in progress]
> 
>     WLAN Bug Fixes:
>     -------------------
>     1) First EAPOL drop issue is resolved
>     2) Firmware Assert while roaming issue is resolved
>        (Provide driver bgsan should be enabled along with supplicant bgscan)
>     3) Roaming takes longer time issue is resolved
>     4) Added polling support as a work-around for the SDIO interrupt issue
>        on some platforms
> 
>     WLAN Limitations/Features NOT Supported:
>     ----------------------------------------
>     1) Wi-Fi Direct mode not supported
>     2) EAP not supported
>     3) SDIO interrupts are not being delivered to the 9113 driver
>     4) In S4 state 9113 device gets reset but device isn't getting re-enumerated.
> 
> Signed-off-by: Shrirang Bagul <shrirang.bagul at canonical.com>
> ---
>  ubuntu/rsi/rsi_91x_coex.c     |   2 +-
>  ubuntu/rsi/rsi_91x_core.c     |  57 +++++++--
>  ubuntu/rsi/rsi_91x_hal.c      |  19 ++-
>  ubuntu/rsi/rsi_91x_hci.c      |  67 ++++++++++-
>  ubuntu/rsi/rsi_91x_mac80211.c |  35 +++---
>  ubuntu/rsi/rsi_91x_main.c     |   2 +
>  ubuntu/rsi/rsi_91x_mgmt.c     |  90 ++++----------
>  ubuntu/rsi/rsi_91x_sdio.c     | 269 ++++++++++++++++++++++++++----------------
>  ubuntu/rsi/rsi_91x_sdio_ops.c |  63 +++-------
>  ubuntu/rsi/rsi_91x_usb.c      |  51 ++++++++
>  ubuntu/rsi/rsi_91x_usb_ops.c  |   3 +-
>  ubuntu/rsi/rsi_hal.h          |   8 ++
>  ubuntu/rsi/rsi_hci.h          |  29 +++++
>  ubuntu/rsi/rsi_main.h         |  18 ++-
>  ubuntu/rsi/rsi_mgmt.h         |   5 +-
>  ubuntu/rsi/rsi_sdio.h         |   8 +-
>  ubuntu/rsi/rsi_usb.h          |  19 ++-
>  17 files changed, 472 insertions(+), 273 deletions(-)
> 
> diff --git a/ubuntu/rsi/rsi_91x_coex.c b/ubuntu/rsi/rsi_91x_coex.c
> index 05a87d6b81e4..5b3b3ac3bec9 100644
> --- a/ubuntu/rsi/rsi_91x_coex.c
> +++ b/ubuntu/rsi/rsi_91x_coex.c
> @@ -106,7 +106,7 @@ int rsi_coex_recv_pkt(struct rsi_common *common, u8 *msg)
>  
>  	if (msg_type == COMMON_CARD_READY_IND) {
>  		ven_rsi_dbg(INFO_ZONE, "COMMON CARD READY RECEIVED\n");
> -		rsi_handle_card_ready(common);
> +		rsi_handle_card_ready(common, msg);
>  	} else if (msg_type == SLEEP_NOTIFY_IND) {
>  		ven_rsi_dbg(INFO_ZONE, "\n\n sleep notify RECEIVED\n");
>  		rsi_mgmt_pkt_recv(common, msg);
> diff --git a/ubuntu/rsi/rsi_91x_core.c b/ubuntu/rsi/rsi_91x_core.c
> index db365e4aa160..a349f973f0e8 100644
> --- a/ubuntu/rsi/rsi_91x_core.c
> +++ b/ubuntu/rsi/rsi_91x_core.c
> @@ -294,10 +294,15 @@ void rsi_core_qos_processor(struct rsi_common *common)
>  
>  		mutex_lock(&common->tx_lock);
>  
> -		status = adapter->check_hw_queue_status(adapter, q_num);
> +		status = adapter->host_intf_ops->check_hw_queue_status(adapter,
> +								       q_num);
>  		if (status <= 0) {
> +			if ((q_num < MGMT_SOFT_Q) ||
> +			    ((!adapter->peer_notify) &&
> +			     (q_num == MGMT_SOFT_Q))) {
>  			mutex_unlock(&common->tx_lock);
>  			break;
> +			}
>  		}
>  
>  		if ((q_num < MGMT_SOFT_Q) &&
> @@ -313,6 +318,11 @@ void rsi_core_qos_processor(struct rsi_common *common)
>  		}
>  
>  		skb = rsi_core_dequeue_pkt(common, q_num);
> +		if ((adapter->peer_notify) &&
> +		    (skb->data[2] == PEER_NOTIFY)) {
> +			adapter->peer_notify = false;
> +			ven_rsi_dbg(INFO_ZONE, "%s RESET PEER_NOTIFY\n", __func__);
> +		}
>  		if (!skb) {
>  			ven_rsi_dbg(ERR_ZONE, "skb null\n");
>  			mutex_unlock(&common->tx_lock);
> @@ -429,7 +439,7 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
>  		goto xmit_fail;
>  	}
>  #ifdef CONFIG_VEN_RSI_WOW
> -	if (common->suspend_flag) {
> +	if (common->wow_flags & RSI_WOW_ENABLED) {
>  		ven_rsi_dbg(ERR_ZONE,
>  			"%s: Blocking Tx_packets when WOWLAN is enabled\n",
>  			__func__);
> @@ -466,7 +476,7 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
>  
>  #ifdef CONFIG_VEN_RSI_WOW          
>  		if ((ieee80211_is_deauth(wlh->frame_control)) &&
> -			(common->suspend_flag)) {
> +		    (common->wow_flags & RSI_WOW_ENABLED)) {
>  			ven_rsi_dbg(ERR_ZONE,
>  				"%s: Discarding Deauth when WOWLAN is enabled\n",
>  				__func__);
> @@ -513,7 +523,6 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
>  			
>  			tid = *qos & IEEE80211_QOS_CTL_TID_MASK;
>  			skb->priority = TID_TO_WME_AC(tid);
> -
>  		} else {
>  			tid = IEEE80211_NONQOS_TID;
>  			skb->priority = BE_Q;
> @@ -539,6 +548,12 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
>  				ieee80211_sn_inc(sta->seq_no[skb->priority]);
>  #endif
>  			tx_params->sta_id = sta->sta_id;
> +			
> +			/* Start aggregation if not done for this tid */
> +			if (!sta->start_tx_aggr[tid]) {
> +				sta->start_tx_aggr[tid] = true;
> +				ieee80211_start_tx_ba_session(sta->sta, tid, 0);
> +			}
>  		} else {
>  #if 0
>  			seq = IEEE80211_SN_TO_SEQ(common->bc_mc_seqno);
> @@ -563,14 +578,32 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
>  		}
>  	}
>  
> -	if ((q_num != MGMT_SOFT_Q) &&
> -	    ((skb_queue_len(&common->tx_queue[q_num]) + 1) >=
> -	      DATA_QUEUE_WATER_MARK)) {
> -		ven_rsi_dbg(ERR_ZONE, "%s: sw queue full\n", __func__);
> -		if (!ieee80211_queue_stopped(adapter->hw, WME_AC(q_num)))
> -			ieee80211_stop_queue(adapter->hw, WME_AC(q_num));
> -		rsi_set_event(&common->tx_thread.event);
> -		goto xmit_fail;
> +	if (q_num != MGMT_SOFT_Q)  {
> +		u16 water_mark = DATA_QUEUE_WATER_MARK;
> +
> +		switch (q_num) {
> +		case BK_Q:
> +			water_mark = BK_DATA_QUEUE_WATER_MARK;
> +			break;
> +		case BE_Q:
> +			water_mark = BE_DATA_QUEUE_WATER_MARK;
> +			break;
> +		case VI_Q:
> +			water_mark = VI_DATA_QUEUE_WATER_MARK;
> +			break;
> +		case VO_Q:
> +			water_mark = VO_DATA_QUEUE_WATER_MARK;
> +			break;
> +		}
> +		if ((skb_queue_len(&common->tx_queue[q_num]) + 1) >= 
> +	   	    water_mark) {
> +			ven_rsi_dbg(ERR_ZONE, "%s: queue %d is full\n",
> +				__func__, q_num);
> +			if (!ieee80211_queue_stopped(adapter->hw, WME_AC(q_num)))
> +				ieee80211_stop_queue(adapter->hw, WME_AC(q_num));
> +			rsi_set_event(&common->tx_thread.event);
> +			goto xmit_fail;
> +		}
>  	}
>  
>  	rsi_core_queue_pkt(common, skb);
> diff --git a/ubuntu/rsi/rsi_91x_hal.c b/ubuntu/rsi/rsi_91x_hal.c
> index 51154e3088ff..6b2be0293b32 100644
> --- a/ubuntu/rsi/rsi_91x_hal.c
> +++ b/ubuntu/rsi/rsi_91x_hal.c
> @@ -476,7 +476,6 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb)
>  				goto out;
>  			}
>  		}
> -		ven_rsi_dbg(MGMT_TX_ZONE, "Sending PROBE REQUEST =====>\n");
>  	}
>  
>  	ven_rsi_dbg(MGMT_TX_ZONE,
> @@ -503,12 +502,25 @@ int rsi_send_bt_pkt(struct rsi_common *common, struct sk_buff *skb)
>  	int status = -EINVAL;
>  	u8 header_size = 0;
>  	__le16 *frame_desc;
> +	u8 queueno = ((skb->data[1] >> 4) & 0xf);
> +
> +	if (queueno == RSI_BT_MGMT_Q) {
> +		rsi_hex_dump(MGMT_TX_ZONE, "TX BT Mgmt Pkt",
> +			     skb->data, skb->len);
> +		status = adapter->host_intf_ops->write_pkt(common->priv,
> +							   skb->data,
> +							   skb->len);
> +		if (status)
> +			ven_rsi_dbg(ERR_ZONE, "%s: Failed to write bt mgmt pkt\n",
> +				__func__);
> +		goto out;
> +	}
>  
>  	header_size = FRAME_DESC_SZ;
>  	if (header_size > skb_headroom(skb)) {
>  		ven_rsi_dbg(ERR_ZONE, "%s: Not enough headroom\n", __func__);
>  		status = -ENOSPC;
> -		goto err;
> +		goto out;
>  	}
>  	skb_push(skb, header_size);
>  	frame_desc = (__le16 *)&skb->data[0];
> @@ -525,7 +537,7 @@ int rsi_send_bt_pkt(struct rsi_common *common, struct sk_buff *skb)
>  	if (status)
>  		ven_rsi_dbg(ERR_ZONE, "%s: Failed to write bt pkt\n", __func__);
>  
> -err:
> +out:
>  	dev_kfree_skb(skb);
>  	return status;
>  }
> @@ -1213,6 +1225,7 @@ int rsi_hal_device_init(struct rsi_hw *adapter)
>  	case DEV_OPMODE_STA_BT_LE:
>  	case DEV_OPMODE_BT_ALONE:
>  	case DEV_OPMODE_BT_LE_ALONE:
> +	case DEV_OPMODE_BT_DUAL:
>  		common->coex_mode = 2;
>  		break;
>  	case DEV_OPMODE_AP_BT_DUAL:
> diff --git a/ubuntu/rsi/rsi_91x_hci.c b/ubuntu/rsi/rsi_91x_hci.c
> index c74d40c0f4e1..2f982bdab470 100644
> --- a/ubuntu/rsi/rsi_91x_hci.c
> +++ b/ubuntu/rsi/rsi_91x_hci.c
> @@ -152,7 +152,7 @@ static int rsi_hci_send_pkt(struct hci_dev *hdev, struct sk_buff *skb)
>  
>  #ifdef CONFIG_VEN_RSI_WOW
>  	/* Stop here when in suspend */
> -	if (h_adapter->priv->suspend_flag) {
> +	if (h_adapter->priv->wow_flags & RSI_WOW_ENABLED) {
>  		ven_rsi_dbg(INFO_ZONE, "In suspend: Dropping the pkt\n");
>  		status = -ENETDOWN;
>  		goto fail;
> @@ -223,6 +223,58 @@ fail:
>  	return status;
>  }
>  
> +int rsi_send_rfmode_frame(struct rsi_common *common)
> +{
> +	struct sk_buff *skb;
> +	struct rsi_bt_rfmode_frame *cmd_frame;
> +
> +	ven_rsi_dbg(MGMT_TX_ZONE, "%s: Sending BT RF mode frame\n", __func__);
> +
> +	skb = dev_alloc_skb(sizeof(struct rsi_bt_rfmode_frame));
> +	if (!skb)
> +		return -ENOMEM;
> +
> +	memset(skb->data, 0, sizeof(struct rsi_bt_rfmode_frame));
> +	cmd_frame = (struct rsi_bt_rfmode_frame *)skb->data;
> +
> +	/* Length is 0 */
> +	cmd_frame->desc.q_no = RSI_BT_MGMT_Q;
> +	cmd_frame->desc.pkt_type = RSI_BT_PKT_TYPE_RFMODE;
> +	cmd_frame->bt_rf_tx_power_mode = 0;
> +	cmd_frame->bt_rf_tx_power_mode = 0;
> +
> +	skb_put(skb, sizeof(struct rsi_bt_rfmode_frame));
> +
> +//	return rsi_coex_send_pkt(common, skb, RSI_BT_Q);
> +	return common->priv->host_intf_ops->write_pkt(common->priv, skb->data, skb->len);
> +}
> +EXPORT_SYMBOL_GPL(rsi_send_rfmode_frame);
> +
> +int rsi_deregister_bt(struct rsi_common *common)
> +{
> +	struct sk_buff *skb;
> +	struct rsi_bt_cmd_frame *cmd_frame;
> +
> +	ven_rsi_dbg(MGMT_TX_ZONE, "%s: Sending BT register frame\n", __func__);
> +
> +	skb = dev_alloc_skb(sizeof(struct rsi_bt_cmd_frame));
> +	if (!skb)
> +		return -ENOMEM;
> +
> +	memset(skb->data, 0, sizeof(struct rsi_bt_cmd_frame));
> +	cmd_frame = (struct rsi_bt_cmd_frame *)skb->data;
> +
> +	/* Length is 0 */
> +	cmd_frame->q_no = RSI_BT_MGMT_Q;
> +	cmd_frame->pkt_type = RSI_BT_PKT_TYPE_DEREGISTR;
> +
> +	skb_put(skb, sizeof(struct rsi_bt_cmd_frame));
> +
> +	//return rsi_coex_send_pkt(common, skb, RSI_BT_Q);
> +	return common->priv->host_intf_ops->write_pkt(common->priv, skb->data, skb->len);
> +}
> +EXPORT_SYMBOL_GPL(rsi_deregister_bt);
> +
>  int rsi_hci_recv_pkt(struct rsi_common *common, u8 *pkt)
>  {
>  	struct rsi_hci_adapter *h_adapter =
> @@ -237,6 +289,14 @@ int rsi_hci_recv_pkt(struct rsi_common *common, u8 *pkt)
>  		ven_rsi_dbg(INIT_ZONE, "%s: ===> BT Card Ready Received <===\n",
>  			__func__);
>  
> +		if (common->suspend_in_prog) {
> +			ven_rsi_dbg(INFO_ZONE,
> +				"Suspend is in prog; Do not process\n");
> +			return 0;
> +		}
> +
> +		rsi_send_rfmode_frame(common);
> +
>  		ven_rsi_dbg(INFO_ZONE, "Attaching HCI module\n");
>  
>  		if (rsi_hci_attach(common)) {
> @@ -370,7 +430,6 @@ err:
>  	return rc;
>  }
>  
> -
>  /**
>   * rsi_hci_attach () - This function initializes HCI interface
>   *				      
> @@ -521,6 +580,9 @@ void rsi_hci_detach(struct rsi_common *common)
>  	if (!h_adapter)
>  		return;
>  
> +	if (common->suspend_in_prog)
> +		rsi_deregister_bt(common);
> +
>  	hdev = h_adapter->hdev;
>  	if (hdev) {
>                  //hci_dev_hold(hdev);
> @@ -540,6 +602,7 @@ void rsi_hci_detach(struct rsi_common *common)
>  		kfree(gcb);
>  	}
>  	kfree(h_adapter);
> +	common->bt_fsm_state = BT_DEVICE_NOT_READY;
>  
>  	return;
>  }
> diff --git a/ubuntu/rsi/rsi_91x_mac80211.c b/ubuntu/rsi/rsi_91x_mac80211.c
> index 19b851ef0978..185444f77cf9 100644
> --- a/ubuntu/rsi/rsi_91x_mac80211.c
> +++ b/ubuntu/rsi/rsi_91x_mac80211.c
> @@ -513,7 +513,7 @@ static void rsi_mac80211_tx(struct ieee80211_hw *hw,
>    struct ieee80211_vif *vif = adapter->vifs[adapter->sc_nvifs - 1];
>  
>  #ifdef CONFIG_VEN_RSI_WOW
> -	if (common->suspend_flag) {
> +	if (common->wow_flags & RSI_WOW_ENABLED) {
>  		ieee80211_free_txskb(common->priv->hw, skb);
>  		return;
>  	}
> @@ -1418,6 +1418,8 @@ static int rsi_mac80211_set_key(struct ieee80211_hw *hw,
>  		break;
>  
>  	case DISABLE_KEY:
> +		if ((vif->type == NL80211_IFTYPE_STATION) ||
> +		    (vif->type == NL80211_IFTYPE_P2P_CLIENT))
>  		secinfo->security_enable = false;
>  		ven_rsi_dbg(ERR_ZONE, "%s: RSI del key\n", __func__);
>  		memset(key, 0, sizeof(struct ieee80211_key_conf));
> @@ -1800,7 +1802,7 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
>  	struct rsi_common *common = adapter->priv;
>  	bool sta_exist = 0;
>  
> -	rsi_hex_dump(INFO_ZONE, "Station Add: ", sta->addr, ETH_ALEN);
> +	rsi_hex_dump(INFO_ZONE, "Station Add", sta->addr, ETH_ALEN);
>  
>  	mutex_lock(&common->mutex);
>  
> @@ -1853,12 +1855,16 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
>  			}
>  			for (j = 0; j < IEEE80211_NUM_ACS; j++)
>  				common->stations[i].seq_no[j] = 1;
> +			for (j = 0; j < IEEE80211_NUM_TIDS; j++)
> +				common->stations[i].start_tx_aggr[j] = false;
>  			common->num_stations++;
>  		} else {
>  			common->stations[i].sta = sta;
>  			common->stations[i].sta_id = i;
>  			for (j = 0; j < IEEE80211_NUM_ACS; j++)
>  				common->stations[i].seq_no[j] = 1;
> +			for (j = 0; j < IEEE80211_NUM_TIDS; j++)
> +				common->stations[i].start_tx_aggr[j] = false;
>  		}
>  	}
>  
> @@ -1879,7 +1885,9 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
>  		}
>  	}
>  
> -	if (sta->ht_cap.ht_supported) {
> +	if (((vif->type == NL80211_IFTYPE_STATION) ||
> +	     (vif->type == NL80211_IFTYPE_P2P_CLIENT)) &&
> +	    (sta->ht_cap.ht_supported)) {
>  		common->vif_info[0].is_ht = true;
>  		common->bitrate_mask[NL80211_BAND_2GHZ] =
>  				sta->supp_rates[NL80211_BAND_2GHZ];
> @@ -1910,9 +1918,8 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
>  	struct rsi_hw *adapter = hw->priv;
>  	struct rsi_common *common = adapter->priv;
>  	struct ieee80211_bss_conf *bss = &vif->bss_conf;
> -//		&adapter->vifs[adapter->sc_nvifs - 1]->bss_conf;
>  
> -	rsi_hex_dump(INFO_ZONE, "Station Removed: ", sta->addr, ETH_ALEN);
> +	rsi_hex_dump(INFO_ZONE, "Station Removed", sta->addr, ETH_ALEN);
>  
>  	mutex_lock(&common->mutex);
>  	if ((vif->type == NL80211_IFTYPE_AP) ||
> @@ -2325,10 +2332,12 @@ int rsi_mac80211_suspend(struct ieee80211_hw *hw,
>  	if (!bss->assoc) {
>  		ven_rsi_dbg(ERR_ZONE,
>  			"Cannot configure WoWLAN (Station not connected)\n");
> -		common->suspend_flag = STATION_NOT_CONNECTED;
> +		common->wow_flags |= RSI_WOW_NO_CONNECTION;
>  		ret = 0;
>  		goto fail_wow;
>  	}
> +	ven_rsi_dbg(INFO_ZONE, "TRIGGERS %x\n", triggers);
> +	rsi_send_wowlan_request(common, triggers, 1);
>  
>  	/* Send updated vap caps */
>  	rsi_send_vap_dynamic_update(common);
> @@ -2336,13 +2345,9 @@ int rsi_mac80211_suspend(struct ieee80211_hw *hw,
>  	rx_filter_word = (ALLOW_DATA_ASSOC_PEER |
>  			  DISALLOW_BEACONS |
>  			  0);
> -
> -
> -	rsi_send_wowlan_request(common, triggers, 1);
> -	ven_rsi_dbg(INFO_ZONE, "TRIGGERS %x\n", triggers);
>  	rsi_send_rx_filter_frame(common, rx_filter_word);
>  
> -        common->suspend_flag = 1;
> +        common->wow_flags |= RSI_WOW_ENABLED;
>  fail_wow:
>  #endif
>          return (ret ? 1 : 0);
> @@ -2355,7 +2360,7 @@ static int rsi_mac80211_resume(struct ieee80211_hw *hw)
>  	struct rsi_common *common = adapter->priv;
>  	u16 rx_filter_word = 0;
>  
> -	adapter->priv->suspend_flag = 0;
> +	adapter->priv->wow_flags = 0;
>  #endif
>  	
>  	ven_rsi_dbg(INFO_ZONE, "%s: mac80211 resume\n", __func__);
> @@ -2665,8 +2670,8 @@ int rsi_mac80211_attach(struct rsi_common *common)
>  	hw->max_rate_tries = MAX_RETRIES;
>  	hw->uapsd_queues = IEEE80211_MARKALL_UAPSD_QUEUES;
>  	hw->uapsd_max_sp_len = IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL;
> -//	hw->max_tx_aggregation_subframes = 6;
> -	hw->max_tx_aggregation_subframes = 4;
> +	hw->max_tx_aggregation_subframes = 8;
> +//	hw->max_rx_aggregation_subframes = 8;
>  
>  	rsi_register_rates_channels(adapter, NL80211_BAND_2GHZ);
>  	wiphy->bands[NL80211_BAND_2GHZ] =
> @@ -2714,6 +2719,7 @@ int rsi_mac80211_attach(struct rsi_common *common)
>  	/* AP Parameters */
>  	wiphy->flags = WIPHY_FLAG_REPORTS_OBSS;
>  	wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
> +	wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER;
>  
>  	/*wiphy->regulatory_flags = (REGULATORY_STRICT_REG |
>  				   REGULATORY_CUSTOM_REG);
> @@ -2732,7 +2738,6 @@ int rsi_mac80211_attach(struct rsi_common *common)
>  	hw->max_listen_interval = 10;
>  	wiphy->iface_combinations = rsi_iface_combinations;
>  	wiphy->n_iface_combinations = ARRAY_SIZE(rsi_iface_combinations);
> -	wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER;
>  //	wiphy->features |= (NL80211_FEATURE_P2P_GO_CTWIN |
>  //			    NL80211_FEATURE_P2P_GO_OPPPS);
>  #endif
> diff --git a/ubuntu/rsi/rsi_91x_main.c b/ubuntu/rsi/rsi_91x_main.c
> index 07cf4f4108f1..72b80ba1a878 100644
> --- a/ubuntu/rsi/rsi_91x_main.c
> +++ b/ubuntu/rsi/rsi_91x_main.c
> @@ -111,6 +111,8 @@ char *opmode_str(int oper_mode)
>  	       return "BT EDR alone";
>  	case DEV_OPMODE_BT_LE_ALONE:
>  	       return "BT LE alone";
> +	case DEV_OPMODE_BT_DUAL:
> +	       return "BT Dual";
>  	case DEV_OPMODE_STA_BT:
>  	       return "Wi-Fi STA + BT EDR";
>  	case DEV_OPMODE_STA_BT_LE:
> diff --git a/ubuntu/rsi/rsi_91x_mgmt.c b/ubuntu/rsi/rsi_91x_mgmt.c
> index b12be2ed501e..2cd37bd5a8f9 100644
> --- a/ubuntu/rsi/rsi_91x_mgmt.c
> +++ b/ubuntu/rsi/rsi_91x_mgmt.c
> @@ -286,7 +286,7 @@ struct rsi_ulp_gpio_vals unused_ulp_gpio_bitmap = {
>  struct rsi_soc_gpio_vals unused_soc_gpio_bitmap = {
>  	.pspi_csn_0		= USED_GPIO,	//GPIO_0
>  	.pspi_csn_1		= USED_GPIO,	//GPIO_1
> -	.host_wakeup_intr	= UNUSED_GPIO,	//GPIO_2
> +	.host_wakeup_intr	= USED_GPIO,	//GPIO_2
>  	.pspi_data_0		= USED_GPIO,	//GPIO_3
>  	.pspi_data_1		= USED_GPIO,	//GPIO_4
>  	.pspi_data_2		= USED_GPIO,	//GPIO_5
> @@ -426,6 +426,9 @@ static int rsi_send_internal_mgmt_frame(struct rsi_common *common,
>  	tx_params = (struct skb_info *)&IEEE80211_SKB_CB(skb)->driver_data;
>  	tx_params->flags |= INTERNAL_MGMT_PKT;
>  	skb->priority = MGMT_SOFT_Q;
> +	if (skb->data[2] == PEER_NOTIFY)
> +		skb_queue_head(&common->tx_queue[MGMT_SOFT_Q], skb);
> +	else
>  	skb_queue_tail(&common->tx_queue[MGMT_SOFT_Q], skb);
>  	rsi_set_event(&common->tx_thread.event);
>  	return 0;
> @@ -655,6 +658,7 @@ int rsi_send_sta_notify_frame(struct rsi_common *common,
>  	default:
>  		break;
>  	}
> +	adapter->peer_notify = true;
>  	peer_notify->command |= cpu_to_le16((aid & 0xfff) << 4);
>  	ether_addr_copy(peer_notify->mac_addr, bssid);
>  	peer_notify->mpdu_density = cpu_to_le16(0x08); //FIXME check this
> @@ -992,57 +996,12 @@ int rsi_load_key(struct rsi_common *common,
>  int rsi_send_common_dev_params(struct rsi_common *common)
>  {
>  	struct sk_buff *skb = NULL;
> -	u32 *soc_gpio, len;
> -	u16 *frame, *ulp_gpio, *desc;
> -
> -	ven_rsi_dbg(INFO_ZONE, "Sending common dev config params\n");
> -
> -	len = 0x20;
> -
> -	skb = dev_alloc_skb(len + FRAME_DESC_SZ);
> -	if (!skb)
> -		return -ENOMEM;
> -	memset(skb->data, 0, len + FRAME_DESC_SZ);
> -
> -	desc = (u16 *)&skb->data[0];
> -	frame = (u16 *)&skb->data[FRAME_DESC_SZ];
> -
> -	desc[0] = cpu_to_le16(len | (RSI_COEX_Q << 12));
> -	desc[1] = cpu_to_le16(COMMON_DEV_CONFIG);
> -
> -	frame[0] = (u16)common->lp_ps_handshake_mode;
> -	frame[0] |= (u16)common->ulp_ps_handshake_mode << 8;
> -
> -	ulp_gpio = (u16 *)&unused_ulp_gpio_bitmap;
> -	soc_gpio = (u32 *)&unused_soc_gpio_bitmap;
> -
> -	frame[1] |= (*ulp_gpio) << 8;
> -	*(u32 *)&frame[2] = *soc_gpio;
> -	frame[4] |= cpu_to_le16((u16)common->oper_mode << 8);
> -	frame[5] |= cpu_to_le16((u16)common->wlan_rf_power_mode);
> -	frame[5] |= cpu_to_le16((u16)common->bt_rf_power_mode << 8);
> -	frame[6] |= cpu_to_le16((u16)common->driver_mode << 8);
> -	frame[7] = cpu_to_le16(3); //((u16 )d_assets->region_code);
> -	frame[7] |= cpu_to_le16((u16)common->obm_ant_sel_val << 8);
> -
> -	skb_put(skb, len + FRAME_DESC_SZ);
> -
> -	return rsi_send_internal_mgmt_frame(common, skb);
> -}
> -
> -#if 0
> -int rsi_send_common_dev_params(struct rsi_common *common)
> -{
> -	struct sk_buff *skb = NULL;
> -	u32 *unused_soc_gpio;
>  	u32 frame_len = 0;
>  	struct rsi_config_vals *dev_cfgs = NULL;
>  
>  	frame_len = sizeof(struct rsi_config_vals);
>  
> -	ven_rsi_dbg(MGMT_TX_ZONE,
> -		"%s: Sending common device config params frame\n",
> -		__func__);
> +	ven_rsi_dbg(MGMT_TX_ZONE, "Sending common device config params\n");
>  	skb = dev_alloc_skb(frame_len);
>  	if (!skb) {
>  		ven_rsi_dbg(ERR_ZONE, "%s: Unable to allocate skb\n", __func__);
> @@ -1061,35 +1020,22 @@ int rsi_send_common_dev_params(struct rsi_common *common)
>  	dev_cfgs->lp_ps_handshake = common->lp_ps_handshake_mode;
>  	dev_cfgs->ulp_ps_handshake = common->ulp_ps_handshake_mode;
>  
> -	if (common->host_wakeup_intr_enable) {
> -		dev_cfgs->sleep_config_params |=
> -			common->host_wakeup_intr_enable;
> -		dev_cfgs->sleep_config_params |= BIT(2);
> -		if (common->host_wakeup_intr_active_high)
> -			dev_cfgs->sleep_config_params |= BIT(3);
> -	}
> -
> -	dev_config_vals[0].opermode = common->coex_mode;
> +	dev_cfgs->unused_ulp_gpio = *(u8 *)&unused_ulp_gpio_bitmap;
> +	dev_cfgs->unused_soc_gpio_bitmap =
> +		cpu_to_le32(*(u32 *)&unused_soc_gpio_bitmap);
>  
> -	if (dev_config_vals[0].ext_pa_or_bt_coex_en)
> -		dev_cfgs->ext_pa_or_bt_coex_en =
> -			dev_config_vals[0].ext_pa_or_bt_coex_en;
> -	dev_cfgs->opermode = dev_config_vals[0].opermode;
> +	dev_cfgs->opermode = common->oper_mode;
>  	dev_cfgs->wlan_rf_pwr_mode = common->wlan_rf_power_mode;
>  	dev_cfgs->driver_mode = common->driver_mode;
> -	dev_cfgs->region_code = 0; /* Default US */
> +	dev_cfgs->region_code = NL80211_DFS_FCC;
>  	dev_cfgs->antenna_sel_val = common->obm_ant_sel_val;
>  
> -	unused_soc_gpio = (u32 *)&unused_soc_gpio_bitmap;
> -	dev_cfgs->unused_soc_gpio_bitmap = *unused_soc_gpio;
> -
>  	skb_put(skb, frame_len);
>  
>  	rsi_hex_dump(ERR_ZONE, "common dev config params ",
>  		     skb->data, skb->len);
>  	return rsi_send_internal_mgmt_frame(common, skb);
>  }
> -#endif
>  
>  /*
>   * rsi_load_bootup_params() - This function send bootup params to the firmware.
> @@ -1975,7 +1921,7 @@ void rsi_inform_bss_status(struct rsi_common *common,
>  		if (opmode == STA_OPMODE)
>  			common->hw_data_qs_blocked = true;
>  #ifdef CONFIG_VEN_RSI_WOW
> -		if (!common->suspend_flag) {
> +		if (!(common->wow_flags & RSI_WOW_ENABLED)) {
>  #endif
>  		rsi_send_sta_notify_frame(common,
>  					  opmode,
> @@ -2756,7 +2702,7 @@ out:
>   *
>   *Return: 0 on success, -1 on failure.
>   */
> -int rsi_handle_card_ready(struct rsi_common *common)
> +int rsi_handle_card_ready(struct rsi_common *common, u8 *msg)
>  {
>  	switch (common->fsm_state) {
>  	case FSM_CARD_NOT_READY:
> @@ -2767,7 +2713,13 @@ int rsi_handle_card_ready(struct rsi_common *common)
>  		common->fsm_state = FSM_COMMON_DEV_PARAMS_SENT;
>  		break;
>  	case FSM_COMMON_DEV_PARAMS_SENT:
> -		ven_rsi_dbg(INIT_ZONE, "Common dev config params confirm\n");
> +		ven_rsi_dbg(INIT_ZONE, "Card ready indication from WLAN HAL\n");
> +
> +		/* Get usb buffer status register address */
> +		common->priv->usb_buffer_status_reg = *(u32 *)&msg[8];
> +		ven_rsi_dbg(INFO_ZONE, "USB buffer status register = %x\n",
> +			common->priv->usb_buffer_status_reg);
> +
>  		if (rsi_load_bootup_params(common)) {
>  			common->fsm_state = FSM_CARD_NOT_READY;
>  			return -EINVAL;
> @@ -2805,7 +2757,7 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg)
>  
>  	case CARD_READY_IND:
>  		ven_rsi_dbg(INIT_ZONE, "CARD READY INDICATION FROM WLAN.\n");
> -		return rsi_handle_card_ready(common);
> +		return rsi_handle_card_ready(common, msg);
>  
>  	case TX_STATUS_IND:
>  		if (msg[15] == PROBEREQ_CONFIRM) {
> diff --git a/ubuntu/rsi/rsi_91x_sdio.c b/ubuntu/rsi/rsi_91x_sdio.c
> index 497484849ac1..8eb939868b0b 100644
> --- a/ubuntu/rsi/rsi_91x_sdio.c
> +++ b/ubuntu/rsi/rsi_91x_sdio.c
> @@ -32,6 +32,7 @@
>  #include "rsi_sdio.h"
>  #include "rsi_common.h"
>  #include "rsi_hal.h"
> +#include "rsi_hci.h"
>  
>  /* Default operating mode is Wi-Fi alone */
>  #ifdef CONFIG_CARACALLA_BOARD
> @@ -919,7 +920,7 @@ int rsi_sdio_host_intf_write_pkt(struct rsi_hw *adapter,
>  	int status;
>  
>  	queueno = ((pkt[1] >> 4) & 0xf);
> -	if (queueno == RSI_BT_DATA_Q)
> +	if ((queueno == RSI_BT_DATA_Q) || (queueno == RSI_BT_MGMT_Q))
>  		queueno = RSI_BT_Q;
>  
>  	num_blocks = len / block_size;
> @@ -1027,7 +1028,6 @@ static int rsi_init_sdio_interface(struct rsi_hw *adapter,
>  	sdio_release_host(pfunction);
>  
>  	adapter->determine_event_timeout = rsi_sdio_determine_event_timeout;
> -	adapter->check_hw_queue_status = rsi_sdio_read_buffer_status_register;
>  	adapter->process_isr_hci = rsi_interrupt_handler;
>  	adapter->check_intr_status_reg = rsi_read_intr_status_reg;
>  	
> @@ -1050,6 +1050,7 @@ static struct rsi_host_intf_ops sdio_host_intf_ops = {
>  	.read_reg_multiple	= rsi_sdio_read_register_multiple,
>  	.write_reg_multiple	= rsi_sdio_write_register_multiple,
>  	.load_data_master_write	= rsi_sdio_load_data_master_write,
> +	.check_hw_queue_status	= rsi_sdio_check_buffer_status,
>  };
>  
>  /**
> @@ -1196,90 +1197,28 @@ int rsi_set_sdio_pm_caps(struct rsi_hw *adapter)
>  	return ret;
>  }
>  
> -static int rsi_freeze(struct device *dev)
> +static int rsi_sdio_disable_interrupts(struct sdio_func *pfunction)
>  {
> -	int ret = 0;
> -	struct sdio_func *pfunction = dev_to_sdio_func(dev);
>  	struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
> -#ifdef CONFIG_VEN_RSI_WOW
> -	struct rsi_91x_sdiodev *sdev =
> -		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
> -#endif
> -	u8 isr_status = 0;
> -
> -	ven_rsi_dbg(INFO_ZONE, "SDIO Bus freeze ===>\n");
> +	u8 isr_status = 0, data = 0;
> +	int ret;
>  
> -#ifdef CONFIG_VEN_RSI_WOW
> -	if ((adapter->priv->suspend_flag == STATION_NOT_CONNECTED) ||
> -	    (sdev->write_fail)) { 
> -		ven_rsi_dbg(ERR_ZONE,
> -			"SUSPEND Cannot proceed as Device is not ready\n");
> -		ven_rsi_dbg(ERR_ZONE,
> -			"Disable WoWLAN / Connect to AP\n");
> -		return -EBUSY;
> -	}
> -#endif
> -	ven_rsi_dbg(INFO_ZONE, "Waiting for interrupts to be cleared..");
> +	ven_rsi_dbg(ERR_ZONE, "Waiting for interrupts to be cleared..");
>  	do {
>  		rsi_sdio_read_register(adapter,
>  				       RSI_FN1_INT_REGISTER,
>  				       &isr_status);
> -		printk(".");
> +		ven_rsi_dbg(ERR_ZONE, ".");
>  	} while (isr_status);
> -	printk("\n");
> -
> -	ret = rsi_set_sdio_pm_caps(adapter);
> -	if (ret)
> -		ven_rsi_dbg(INFO_ZONE, "Setting power management caps failed\n");
> -
> -	return 0;
> -}
> -
> -static int rsi_suspend(struct device *dev)
> -{
> -	int ret = 0;
> -	struct sdio_func *pfunction = dev_to_sdio_func(dev);
> -	struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
> -#ifdef CONFIG_VEN_RSI_WOW
> -	struct rsi_91x_sdiodev *sdev =
> -		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
> -#endif
> -	u8 isr_status = 0;
> -	u8 data = 0;
> -
> -	ven_rsi_dbg(INFO_ZONE, "SDIO Bus suspend ===>\n");
> -
> -	if (!adapter) {
> -		ven_rsi_dbg(ERR_ZONE, "Device is not ready\n");
> -		return -ENODEV;
> -	}
> +	ven_rsi_dbg(ERR_ZONE, "\nInterrupts cleared");
>  
> -#ifdef CONFIG_VEN_RSI_WOW
> -	if ((adapter->priv->suspend_flag == STATION_NOT_CONNECTED) ||
> -	    (sdev->write_fail)) { 
> -		ven_rsi_dbg(ERR_ZONE,
> -			"SUSPEND Cannot proceed; Device is not ready\n");
> -		ven_rsi_dbg(ERR_ZONE,
> -			"Disable WoWLAN / Connect to AP\n");
> -		return -EBUSY;
> -	}
> -#endif
> -	printk("Waiting for interrupts to be cleared..");
> -	do {
> -		rsi_sdio_read_register(adapter,
> -				       RSI_FN1_INT_REGISTER,
> -				       &isr_status);
> -		printk(".");
> -	} while (isr_status); 
> -	printk("\n");
> -
> -	/* Release IRQ */
>  	sdio_claim_host(pfunction);
>  	ret = rsi_cmd52readbyte(pfunction->card, 0x04, &data);
>  	if (ret < 0) {
>  		ven_rsi_dbg(ERR_ZONE,
>  			"%s: Failed to read INTR_EN register\n",
>  			__func__);
> +		sdio_release_host(pfunction);
>  		return ret;
>  	}
>  	ven_rsi_dbg(INFO_ZONE, "INTR_EN reg content = %x\n", data);
> @@ -1292,6 +1231,7 @@ static int rsi_suspend(struct device *dev)
>  		ven_rsi_dbg(ERR_ZONE,
>  			"%s: Failed to Write to INTR_EN register\n",
>  			__func__);
> +		sdio_release_host(pfunction);
>  		return ret;
>  	}
>  	ret = rsi_cmd52readbyte(pfunction->card, 0x04, &data);
> @@ -1299,39 +1239,27 @@ static int rsi_suspend(struct device *dev)
>  		ven_rsi_dbg(ERR_ZONE,
>  			"%s: Failed to read INTR_EN register\n",
>  			__func__);
> +		sdio_release_host(pfunction);
>  		return ret;
>  	}
>  	ven_rsi_dbg(INFO_ZONE, "INTR_EN reg content. = %x\n", data);
>  
>  	sdio_release_host(pfunction);
> -
> -	ret = rsi_set_sdio_pm_caps(adapter);
> -	if (ret)
> -		ven_rsi_dbg(INFO_ZONE,
> -			"Setting power management caps failed\n");
> -
> -	ven_rsi_dbg(INFO_ZONE, "***** SDIO BUS SUSPEND DONE ******\n");
>  	
>  	return 0;
>  }
>  
> -int rsi_resume(struct device *dev)
> +static int rsi_sdio_enable_interrupts(struct sdio_func *pfunction)
>  {
> -	int ret = 0;
> -	u8 data = 0;
> -	struct sdio_func *pfunction = dev_to_sdio_func(dev);
> -#ifdef CONFIG_VEN_RSI_WOW
> -	struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
> -        
> -	ven_rsi_dbg(INFO_ZONE, "***** BUS RESUME ******\n");
> -        adapter->priv->suspend_flag = 0;
> -#endif
> +	u8 data;
> +	int ret;
>  
>  	sdio_claim_host(pfunction);
>  	ret = rsi_cmd52readbyte(pfunction->card, 0x04, &data);
>  	if (ret < 0) {
>  		ven_rsi_dbg(ERR_ZONE,
>  			"%s: Failed to read INTR_EN register\n", __func__);
> +		sdio_release_host(pfunction);
>  		return ret;
>  	}
>  	ven_rsi_dbg(INFO_ZONE, "INTR_EN reg content1 = %x\n", data);
> @@ -1344,6 +1272,7 @@ int rsi_resume(struct device *dev)
>  		ven_rsi_dbg(ERR_ZONE,
>  			"%s: Failed to Write to INTR_EN register\n",
>  			__func__);
> +		sdio_release_host(pfunction);
>  		return ret;
>  	}
>  	
> @@ -1351,56 +1280,187 @@ int rsi_resume(struct device *dev)
>  	if (ret < 0) {
>  		ven_rsi_dbg(ERR_ZONE,
>  			"%s: Failed to read INTR_EN register\n", __func__);
> +		sdio_release_host(pfunction);
>  		return ret;
>  	}
>  	ven_rsi_dbg(INFO_ZONE, "INTR_EN reg content1.. = %x\n", data);
>  	sdio_release_host(pfunction);
>  
> -	ven_rsi_dbg(INFO_ZONE, "***** RSI module resumed *****\n");
> -	return 0;
> +	return ret;
>  }
>  
> -int rsi_thaw(struct device *dev)
> +static int rsi_suspend(struct device *dev)
>  {
> +	int ret = 0;
> +	struct sdio_func *pfunction = dev_to_sdio_func(dev);
> +	struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
> +	struct rsi_common *common = adapter->priv;
>  #ifdef CONFIG_VEN_RSI_WOW
> +	struct rsi_91x_sdiodev *sdev =
> +		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
> +#endif
> +
> +	ven_rsi_dbg(INFO_ZONE, "SDIO Bus suspend ===>\n");
> +
> +	if (!adapter) {
> +		ven_rsi_dbg(ERR_ZONE, "Device is not ready\n");
> +		return -ENODEV;
> +	}
> +
> +	common->suspend_in_prog = true;
> +#ifdef CONFIG_VEN_RSI_WOW
> +	if (common->wow_flags & RSI_WOW_ENABLED) {
> +		if (common->wow_flags & RSI_WOW_NO_CONNECTION)
> +			ven_rsi_dbg(ERR_ZONE,
> +				"##### Device can not wake up through WLAN\n");
> +
> +#if defined(CONFIG_VEN_RSI_BT_ALONE) || defined(CONFIG_VEN_RSI_COEX)
> +		if ((common->coex_mode == 2) || (common->coex_mode == 4)) {
> +			/* Deregister BT protocol */
> +			rsi_hci_detach(common);
> +		}
> +#endif
> +	}
> +#endif
> +
> +	ret = rsi_sdio_disable_interrupts(pfunction);
> +	if (ret)
> +		return ret;
> +
> +	if (sdev->write_fail) {
> +		ven_rsi_dbg(INFO_ZONE, "###### Device is not ready #######\n");
> +		return 0;
> +	}
> +
> +	ret = rsi_set_sdio_pm_caps(adapter);
> +	if (ret)
> +		ven_rsi_dbg(INFO_ZONE,
> +			"Setting power management caps failed\n");
> +
> +	ven_rsi_dbg(INFO_ZONE, "***** SDIO BUS SUSPEND DONE ******\n");
> +
> +	return 0;
> +}
> +
> +int rsi_resume(struct device *dev)
> +{
> +	int ret = 0;
>  	struct sdio_func *pfunction = dev_to_sdio_func(dev);
>  	struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
> +	struct rsi_common *common = adapter->priv;
> +        
> +	ven_rsi_dbg(INFO_ZONE, "***** BUS RESUME ******\n");
>  
> -	ven_rsi_dbg(INFO_ZONE, "***** BUS THAW ******\n");
> -	adapter->priv->suspend_flag = 0;
> +	common->suspend_in_prog = false;
> +
> +	ret = rsi_sdio_enable_interrupts(pfunction);
> +	if (ret)
> +		return ret;
> +
> +#ifdef CONFIG_VEN_RSI_WOW
> +#if defined(CONFIG_VEN_RSI_BT_ALONE) || defined(CONFIG_VEN_RSI_COEX)
> +	if ((common->wow_flags & RSI_WOW_ENABLED) &&
> +	    ((common->coex_mode == 2) || (common->coex_mode == 4))) {
> +		/* Register BT protocol */
> +		rsi_hci_attach(common);
> +	}
> +#endif
> +        adapter->priv->wow_flags = 0;
>  #endif
>  
> -	ven_rsi_dbg(INFO_ZONE, "RSI module resumed\n");
> +	ven_rsi_dbg(INFO_ZONE, "***** RSI module resumed *****\n");
>  	return 0;
>  }
>  
> -int rsi_restore(struct device *dev)
> +static int rsi_freeze(struct device *dev)
>  {
> +	int ret = 0;
>  	struct sdio_func *pfunction = dev_to_sdio_func(dev);
>  	struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
> +	struct rsi_common *common = adapter->priv;
> +#ifdef CONFIG_VEN_RSI_WOW
> +	struct rsi_91x_sdiodev *sdev =
> +		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
> +#endif
> +
> +	ven_rsi_dbg(INFO_ZONE, "SDIO Bus freeze ===>\n");
> +
> +	if (!adapter) {
> +		ven_rsi_dbg(ERR_ZONE, "Device is not ready\n");
> +		return -ENODEV;
> +	}
>  
> +	common->suspend_in_prog = true;
>  #ifdef CONFIG_VEN_RSI_WOW
> -	ven_rsi_dbg(INFO_ZONE, "***** BUS RESTORE ******\n");
> -	adapter->priv->suspend_flag = 0;
> +	if (common->wow_flags & RSI_WOW_ENABLED) {
> +		if (common->wow_flags & RSI_WOW_NO_CONNECTION)
> +			ven_rsi_dbg(ERR_ZONE,
> +				"##### Device can not wake up through WLAN\n");
> +
> +#if defined(CONFIG_VEN_RSI_BT_ALONE) || defined(CONFIG_VEN_RSI_COEX)
> +		if ((common->coex_mode == 2) || (common->coex_mode == 4)) {
> +			/* Deregister BT protocol */
> +			rsi_deregister_bt(common);
> +		}
> +#endif
> +	}
>  #endif
> -	rsi_reset_chip(adapter);
>  
> -	/* Resetting to take care of the case, where-in driver is re-loaded */
> -	sdio_claim_host(pfunction);
> -	rsi_reset_card(pfunction);
> -	sdio_disable_func(pfunction);
> -	sdio_release_host(pfunction);
> +	ret = rsi_sdio_disable_interrupts(pfunction);
> +	if (ret)
> +		return ret;
> +
> +	if (sdev->write_fail) {
> +		ven_rsi_dbg(INFO_ZONE, "###### Device is not ready #######\n");
> +		return 0;
> +	}
> +	
> +	ret = rsi_set_sdio_pm_caps(adapter);
> +	if (ret)
> +		ven_rsi_dbg(INFO_ZONE, "Setting power management caps failed\n");
> +	
> +	return 0;
> +}
> +
> +int rsi_thaw(struct device *dev)
> +{
> +	int ret;
> +	struct sdio_func *pfunction = dev_to_sdio_func(dev);
> +	struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
> +
> +	ven_rsi_dbg(INFO_ZONE, "***** BUS THAW ******\n");
> +
> +	adapter->priv->suspend_in_prog = false;
> +
> +	ret = rsi_sdio_enable_interrupts(pfunction);
> +	if (ret)
> +		return ret;
>  
>  	ven_rsi_dbg(INFO_ZONE, "RSI module resumed\n");
>  	return 0;
>  }
>  
> +static int rsi_poweroff(struct device *dev)
> +{
> +	return rsi_suspend(dev);
> +}
> +
> +static void rsi_shutdown(struct device *dev)
> +{
> +	rsi_suspend(dev);
> +}
> +
> +int rsi_restore(struct device *dev)
> +{
> +	return rsi_thaw(dev);
> +}
> +
>  static const struct dev_pm_ops rsi_pm_ops = {
>  	.suspend = rsi_suspend,
>  	.resume = rsi_resume,
>  	.freeze = rsi_freeze,
>  	.thaw = rsi_thaw,
> -	.poweroff = rsi_suspend,
> +	.poweroff = rsi_poweroff,
>  	.restore = rsi_restore,
>  };
>  #endif
> @@ -1423,6 +1483,7 @@ static struct sdio_driver rsi_driver = {
>  #ifdef CONFIG_PM
>  	.drv = {
>  		.pm = &rsi_pm_ops,
> +	        .shutdown   = rsi_shutdown,
>  	}
>  #endif
>  };
> diff --git a/ubuntu/rsi/rsi_91x_sdio_ops.c b/ubuntu/rsi/rsi_91x_sdio_ops.c
> index 801bb57d1093..d575567ac3b8 100644
> --- a/ubuntu/rsi/rsi_91x_sdio_ops.c
> +++ b/ubuntu/rsi/rsi_91x_sdio_ops.c
> @@ -269,7 +269,6 @@ void rsi_interrupt_handler(struct rsi_hw *adapter)
>  	enum sdio_interrupt_type isr_type;
>  	u8 isr_status = 0;
>  	u8 fw_status = 0;
> -	u8 buf_status = 0;
>  
>  	dev->rx_info.sdio_int_counter++;
>  
> @@ -308,40 +307,11 @@ void rsi_interrupt_handler(struct rsi_hw *adapter)
>  
>  			switch (isr_type) {
>  			case BUFFER_AVAILABLE:
> -				status = rsi_sdio_read_register(common->priv,
> -						RSI_DEVICE_BUFFER_STATUS_REGISTER,
> -						&buf_status);
> -				if (status) {
> +				status = rsi_sdio_check_buffer_status(adapter, 0);
> +				if (status < 0)
>  					ven_rsi_dbg(ERR_ZONE,
> -						"%s: Failed to read status register\n",
> +						"%s: Failed to check buffer status\n",
>  						__func__);
> -					return;
> -				}
> -				if (buf_status & (BIT(PKT_MGMT_BUFF_FULL))) {
> -					if (!dev->rx_info.mgmt_buffer_full)
> -						dev->rx_info.mgmt_buf_full_counter++;
> -					dev->rx_info.mgmt_buffer_full = true;
> -				} else {
> -					dev->rx_info.buf_available_counter++;
> -					dev->rx_info.mgmt_buffer_full = false;
> -				}
> -				if (buf_status & (BIT(PKT_BUFF_FULL))) {
> -					if (!dev->rx_info.buffer_full)
> -						dev->rx_info.buf_full_counter++;
> -					dev->rx_info.buffer_full = true;
> -				} else {
> -					dev->rx_info.buf_available_counter++;
> -				dev->rx_info.buffer_full = false;
> -				}
> -				if (buf_status & (BIT(PKT_BUFF_SEMI_FULL))) {
> -					if (!dev->rx_info.semi_buffer_full)
> -						dev->rx_info.buf_semi_full_counter++;
> -					dev->rx_info.semi_buffer_full = true;
> -				} else {
> -					dev->rx_info.buf_available_counter++;
> -				dev->rx_info.semi_buffer_full = false;
> -				}
> -
>  				rsi_sdio_ack_intr(common->priv,
>  						  (1 << PKT_BUFF_AVAILABLE));
>  				rsi_set_event(&common->tx_thread.event);
> @@ -403,7 +373,7 @@ void rsi_interrupt_handler(struct rsi_hw *adapter)
>  }
>  
>  /**
> - * rsi_sdio_read_buffer_status_register() - This function is used to the read
> + * rsi_sdio_check_buffer_status() - This function is used to the read
>   *					    buffer status register and set
>   *					    relevant fields in
>   *					    rsi_91x_sdiodev struct.
> @@ -412,21 +382,19 @@ void rsi_interrupt_handler(struct rsi_hw *adapter)
>   *
>   * Return: status: -1 on failure or else queue full/stop is indicated.
>   */
> -int rsi_sdio_read_buffer_status_register(struct rsi_hw *adapter, u8 q_num)
> +int rsi_sdio_check_buffer_status(struct rsi_hw *adapter, u8 q_num)
>  {
>  	struct rsi_common *common = adapter->priv;
>  	struct rsi_91x_sdiodev *dev =
>  		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
>  	u8 buf_status = 0;
>  	int status = 0;
> -//	static int counter = 4;
> +	static int counter = 4;
>  
> -#if 0
> -	if ((!dev->buff_status_updated) && counter) {
> +	if (!dev->buff_status_updated && counter) {
>  		counter--;
>  		goto out;
>  	}
> -#endif
>  
>  	dev->buff_status_updated = 0;
>  	status = rsi_sdio_read_register(common->priv,
> @@ -442,28 +410,29 @@ int rsi_sdio_read_buffer_status_register(struct rsi_hw *adapter, u8 q_num)
>  		if (!dev->rx_info.mgmt_buffer_full)
>  			dev->rx_info.mgmt_buf_full_counter++;
>  		dev->rx_info.mgmt_buffer_full = true;
> -	} else {
> +	} else
>  		dev->rx_info.mgmt_buffer_full = false;
> -	}
>  
>  	if (buf_status & (BIT(PKT_BUFF_FULL))) {
>  		if (!dev->rx_info.buffer_full)
>  			dev->rx_info.buf_full_counter++;
>  		dev->rx_info.buffer_full = true;
> -	} else {
> +	} else
>  		dev->rx_info.buffer_full = false;
> -	}
>  
>  	if (buf_status & (BIT(PKT_BUFF_SEMI_FULL))) {
>  		if (!dev->rx_info.semi_buffer_full)
>  			dev->rx_info.buf_semi_full_counter++;
>  		dev->rx_info.semi_buffer_full = true;
> -	} else {
> +	} else
>  		dev->rx_info.semi_buffer_full = false;
> -	}
> -//	(dev->rx_info.semi_buffer_full ? (counter = 4) : (counter = 1));
>  
> -//out:
> +	if (dev->rx_info.mgmt_buffer_full || dev->rx_info.buf_full_counter)
> +		counter = 1;
> +	else
> +		counter = 4;
> +
> +out:
>  	if ((q_num == MGMT_SOFT_Q) && (dev->rx_info.mgmt_buffer_full))
>  		return QUEUE_FULL;
>  
> diff --git a/ubuntu/rsi/rsi_91x_usb.c b/ubuntu/rsi/rsi_91x_usb.c
> index e6de38606451..bdc26aa9fb98 100644
> --- a/ubuntu/rsi/rsi_91x_usb.c
> +++ b/ubuntu/rsi/rsi_91x_usb.c
> @@ -61,6 +61,7 @@ static struct rsi_host_intf_ops usb_host_intf_ops = {
>  	.read_reg_multiple	= rsi_usb_read_register_multiple,
>  	.write_reg_multiple	= rsi_usb_write_register_multiple,
>  	.load_data_master_write	= rsi_usb_load_data_master_write,
> +	.check_hw_queue_status	= rsi_usb_check_queue_status,
>  };
>  
>  /**
> @@ -485,6 +486,56 @@ int rsi_usb_load_data_master_write(struct rsi_hw *adapter,
>  	return 0;
>  }
>  
> +int rsi_usb_check_queue_status(struct rsi_hw *adapter, u8 q_num)
> +{
> +	struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
> +	int status;
> +	u32 buf_status = 0;
> +
> +	return QUEUE_NOT_FULL;
> +
> +	if (adapter->priv->fsm_state != FSM_MAC_INIT_DONE)
> +		return QUEUE_NOT_FULL;
> +
> +	status = rsi_usb_reg_read(dev->usbdev, adapter->usb_buffer_status_reg,
> +				  &buf_status, 2);
> +	if (status < 0)
> +		return status;
> +
> +	printk("buffer_status = %x\n", buf_status);
> +	if (buf_status & (BIT(PKT_MGMT_BUFF_FULL))) {
> +		if (!dev->rx_info.mgmt_buffer_full)
> +			dev->rx_info.mgmt_buf_full_counter++;
> +		dev->rx_info.mgmt_buffer_full = true;
> +	} else {
> +		dev->rx_info.mgmt_buffer_full = false;
> +	}
> +
> +	if (buf_status & (BIT(PKT_BUFF_FULL))) {
> +		if (!dev->rx_info.buffer_full)
> +			dev->rx_info.buf_full_counter++;
> +		dev->rx_info.buffer_full = true;
> +	} else {
> +		dev->rx_info.buffer_full = false;
> +	}
> +
> +	if (buf_status & (BIT(PKT_BUFF_SEMI_FULL))) {
> +		if (!dev->rx_info.semi_buffer_full)
> +			dev->rx_info.buf_semi_full_counter++;
> +		dev->rx_info.semi_buffer_full = true;
> +	} else {
> +		dev->rx_info.semi_buffer_full = false;
> +	}
> +
> +	if ((q_num == MGMT_SOFT_Q) && (dev->rx_info.mgmt_buffer_full))
> +		return QUEUE_FULL;
> +
> +	if ((q_num < MGMT_SOFT_Q) && (dev->rx_info.buffer_full))
> +		return QUEUE_FULL;
> +
> +	return QUEUE_NOT_FULL;
> +}
> +
>  /**
>   * rsi_deinit_usb_interface() - This function deinitializes the usb interface.
>   * @adapter: Pointer to the adapter structure.
> diff --git a/ubuntu/rsi/rsi_91x_usb_ops.c b/ubuntu/rsi/rsi_91x_usb_ops.c
> index c587bc95185f..2f4c43e8a3c0 100644
> --- a/ubuntu/rsi/rsi_91x_usb_ops.c
> +++ b/ubuntu/rsi/rsi_91x_usb_ops.c
> @@ -72,9 +72,10 @@ void rsi_usb_rx_thread(struct rsi_common *common)
>  					"%s: Failed in urb submission", __func__);
>  				break;
>  			}
> +			/* Update TX buffer status */
> +			//rsi_usb_check_queue_status(adapter, 0);
>  		}
>  		rsi_reset_event(&dev->rx_thread.event);
> -	
>  	} while (1);
>  
>  	ven_rsi_dbg(INFO_ZONE, "%s: Terminated USB RX thread\n", __func__);
> diff --git a/ubuntu/rsi/rsi_hal.h b/ubuntu/rsi/rsi_hal.h
> index 900c1b29af30..ccb0e64d5de0 100644
> --- a/ubuntu/rsi/rsi_hal.h
> +++ b/ubuntu/rsi/rsi_hal.h
> @@ -35,6 +35,7 @@
>  #define DEV_OPMODE_WIFI_ALONE		1
>  #define DEV_OPMODE_BT_ALONE		4
>  #define DEV_OPMODE_BT_LE_ALONE		8
> +#define DEV_OPMODE_BT_DUAL		12
>  #define DEV_OPMODE_STA_BT		5
>  #define DEV_OPMODE_STA_BT_LE		9
>  #define DEV_OPMODE_STA_BT_DUAL		13
> @@ -159,6 +160,12 @@
>  #define FW_FLASH_OFFSET			0x820
>  #define LMAC_VER_OFFSET			FW_FLASH_OFFSET +0x200
>  
> +/* Buffer status register related info */
> +#define PKT_BUFF_SEMI_FULL		0
> +#define PKT_BUFF_FULL			1
> +#define PKT_MGMT_BUFF_FULL		2
> +#define MSDU_PKT_PENDING		3
> +
>  struct bl_header {
>  	__le32 flags;
>  	__le32 image_no;
> @@ -178,5 +185,6 @@ int rsi_hal_device_init(struct rsi_hw *adapter);
>  int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb);
>  int rsi_send_bt_pkt(struct rsi_common *common, struct sk_buff *skb);
>  int rsi_prepare_beacon(struct rsi_common *common, struct sk_buff *skb);
> +int rsi_deregister_bt(struct rsi_common *common);
>  
>  #endif
> diff --git a/ubuntu/rsi/rsi_hci.h b/ubuntu/rsi/rsi_hci.h
> index 26f554d4e522..2b6977c8c178 100644
> --- a/ubuntu/rsi/rsi_hci.h
> +++ b/ubuntu/rsi/rsi_hci.h
> @@ -109,6 +109,35 @@ struct rsi_hci_adapter {
>  	struct sk_buff_head hci_tx_queue;
>  };
>  
> +/* TX BT command packet types */
> +#define RSI_BT_PKT_TYPE_DEREGISTR		0x11
> +#define RSI_BT_PKT_TYPE_RFMODE			0x55
> +
> +struct rsi_bt_cmd_frame {
> +#ifdef __LITTLE_ENDIAN
> +	u16 len:12;
> +	u16 q_no:4;
> +#else
> +	u16 reserved1:4;
> +	u16 q_no:12;
> +#endif
> +	__le16 reserved2[6];
> +	u8 pkt_type;
> +	u8 reserved3;
> +};
> +
> +struct rsi_bt_rfmode_frame {
> +	struct rsi_bt_cmd_frame desc;
> +#ifdef __LITTLE_ENDIAN
> +	u8 bt_rf_tx_power_mode:4;
> +	u8 bt_rf_rx_power_mode:4;
> +#else
> +	u8 bt_rf_rx_power_mode:4;
> +	u8 bt_rf_tx_power_mode:4;
> +#endif
> +	u8 reserved;
> +};
> +
>  int rsi_genl_recv (struct sk_buff *skb, struct genl_info *info);
>  int rsi_hci_attach (struct rsi_common *common);
>  void rsi_hci_detach(struct rsi_common *common);
> diff --git a/ubuntu/rsi/rsi_main.h b/ubuntu/rsi/rsi_main.h
> index 1e91db2bf1d6..0fc3ce316bf1 100644
> --- a/ubuntu/rsi/rsi_main.h
> +++ b/ubuntu/rsi/rsi_main.h
> @@ -41,7 +41,7 @@ struct rsi_hw;
>  
>  #include "rsi_ps.h"
>  
> -#define DRV_VER				"RS9113.NB0.NL.GNU.LNX.1.2.RC4"
> +#define DRV_VER				"RS9113.NB0.NL.GNU.LNX.1.2.RC9"
>  
>  #define ERR_ZONE                        BIT(0) /* Error Msgs		*/
>  #define INFO_ZONE                       BIT(1) /* Generic Debug Msgs	*/
> @@ -75,6 +75,10 @@ void rsi_hex_dump(u32 zone, char *msg_str, const u8 *msg, u32 len);
>  
>  #define DATA_QUEUE_WATER_MARK           400
>  #define MIN_DATA_QUEUE_WATER_MARK       300
> +#define BK_DATA_QUEUE_WATER_MARK	600
> +#define BE_DATA_QUEUE_WATER_MARK	3200
> +#define VI_DATA_QUEUE_WATER_MARK	3900
> +#define VO_DATA_QUEUE_WATER_MARK	4500
>  #define MULTICAST_WATER_MARK            200
>  #define MAC_80211_HDR_FRAME_CONTROL     0
>  #define WME_NUM_AC                      4
> @@ -123,7 +127,10 @@ void rsi_hex_dump(u32 zone, char *msg_str, const u8 *msg, u32 len);
>  	((_q) == VI_Q) ? IEEE80211_AC_VI : \
>  	IEEE80211_AC_VO)
>  
> -#define STATION_NOT_CONNECTED		BIT(1)
> +/* WoWLAN flags */
> +#define RSI_WOW_ENABLED			BIT(0)
> +#define RSI_WOW_NO_CONNECTION		BIT(1)
> +
>  struct version_info {
>  	u16 major;
>  	u16 minor;
> @@ -223,6 +230,7 @@ struct rsi_sta {
>  	s16 sta_id;
>  	u16 seq_no[IEEE80211_NUM_ACS];
>  	u16 seq_start[IEEE80211_NUM_ACS];
> +	bool start_tx_aggr[IEEE80211_NUM_TIDS];
>  };
>  
>  struct rsi_hw;
> @@ -318,8 +326,9 @@ struct rsi_common {
>  	u8 host_wakeup_intr_active_high;
>  	int tx_power;
>  	u8 ant_in_use;
> +	bool suspend_in_prog;
>  #ifdef CONFIG_VEN_RSI_WOW
> -	u8 suspend_flag;
> +	u8 wow_flags;
>  #endif
>  
>  #if defined (CONFIG_VEN_RSI_BT_ALONE) || defined(CONFIG_VEN_RSI_COEX)
> @@ -412,6 +421,7 @@ struct rsi_hw {
>  	struct rsi_ps_info ps_info;
>  	spinlock_t ps_lock;
>  	u32 isr_pending;
> +	u32 usb_buffer_status_reg;
>  #ifdef CONFIG_VEN_RSI_DEBUGFS
>  	struct rsi_debugfs *dfsentry;
>  	u8 num_debugfs_entries;
> @@ -429,6 +439,7 @@ struct rsi_hw {
>  
>  	u8 dfs_region;
>  	char country[2];
> +	bool peer_notify;
>  	void *rsi_dev;
>  
>  	struct rsi_host_intf_ops *host_intf_ops;
> @@ -457,6 +468,7 @@ struct rsi_host_intf_ops {
>  				      u32 instructions_size, u16 block_size,
>  				      u8 *fw);
>  	int (*rsi_check_bus_status)(struct rsi_hw *adapter);
> +	int (*check_hw_queue_status)(struct rsi_hw *adapter, u8 q_num);
>  };
>  
>  #endif
> diff --git a/ubuntu/rsi/rsi_mgmt.h b/ubuntu/rsi/rsi_mgmt.h
> index 40a046c155a8..8965f237ac2b 100644
> --- a/ubuntu/rsi/rsi_mgmt.h
> +++ b/ubuntu/rsi/rsi_mgmt.h
> @@ -501,8 +501,7 @@ struct rsi_config_vals {
>  	u8 driver_mode;
>  	u8 region_code;
>  	u8 antenna_sel_val;
> -#define EXT_PA      1
> -#define EXT_BT_COEX 2
> +	u8 reserved[16];
>  } __packed;
>  
>  struct rsi_request_ps {
> @@ -588,7 +587,7 @@ int rsi_send_radio_params_update(struct rsi_common *common);
>  void init_bgscan_params(struct rsi_common *common);
>  int rsi_set_antenna(struct rsi_common *common, u8 antenna);
>  int rsi_hci_attach(struct rsi_common *common);
> -int rsi_handle_card_ready(struct rsi_common *common);
> +int rsi_handle_card_ready(struct rsi_common *common, u8 *msg);
>  void rsi_validate_bgscan_channels(struct rsi_hw *adapter,
>  				  struct bgscan_config_params *params);
>  #ifdef CONFIG_VEN_RSI_WOW
> diff --git a/ubuntu/rsi/rsi_sdio.h b/ubuntu/rsi/rsi_sdio.h
> index 4f17d6402fd1..f2ce06099999 100644
> --- a/ubuntu/rsi/rsi_sdio.h
> +++ b/ubuntu/rsi/rsi_sdio.h
> @@ -40,12 +40,6 @@
>  #include <linux/mmc/sdio_ids.h>
>  #include "rsi_main.h"
>  
> -/* Buffer status register related info */
> -#define PKT_BUFF_SEMI_FULL		0
> -#define PKT_BUFF_FULL			1
> -#define PKT_MGMT_BUFF_FULL		2
> -#define MSDU_PKT_PENDING		3
> -
>  /* Interrupt Bit Related Macros */
>  #define PKT_BUFF_AVAILABLE		1
>  #define FW_ASSERT_IND			2
> @@ -161,6 +155,6 @@ int rsi_sdio_master_reg_write(struct rsi_hw *adapter,
>  			      u16 size);
>  void rsi_sdio_ack_intr(struct rsi_hw *adapter, u8 int_bit);
>  int rsi_sdio_determine_event_timeout(struct rsi_hw *adapter);
> -int rsi_sdio_read_buffer_status_register(struct rsi_hw *adapter, u8 q_num);
> +int rsi_sdio_check_buffer_status(struct rsi_hw *adapter, u8 q_num);
>  int rsi_read_intr_status_reg(struct rsi_hw *adapter);
>  #endif
> diff --git a/ubuntu/rsi/rsi_usb.h b/ubuntu/rsi/rsi_usb.h
> index d91cef3beff9..c08ba6c18e25 100644
> --- a/ubuntu/rsi/rsi_usb.h
> +++ b/ubuntu/rsi/rsi_usb.h
> @@ -60,8 +60,20 @@ struct rx_usb_ctrl_block {
>  	u8 pend;
>  };
>  
> +struct receive_info {
> +	bool buffer_full;
> +	bool semi_buffer_full;
> +	bool mgmt_buffer_full;
> +	u32 mgmt_buf_full_counter;
> +	u32 buf_semi_full_counter;
> +	u8 watch_bufferfull_count;
> +	u32 buf_full_counter;
> +	u32 buf_available_counter;
> +};
> +
>  struct rsi_91x_usbdev {
>  	void *priv;
> +	struct receive_info rx_info;
>  	struct rsi_thread rx_thread;
>  	u8 endpoint;
>  	struct usb_device *usbdev;
> @@ -77,12 +89,6 @@ struct rsi_91x_usbdev {
>  	u8 write_fail;
>  };
>  
> -static inline int rsi_usb_check_queue_status(struct rsi_hw *adapter, u8 q_num)
> -{
> -	/* In USB, there isn't any need to check the queue status */
> -	return QUEUE_NOT_FULL;
> -}
> -
>  static inline int rsi_usb_event_timeout(struct rsi_hw *adapter)
>  {
>  	return EVENT_WAIT_FOREVER;
> @@ -104,4 +110,5 @@ int rsi_usb_load_data_master_write(struct rsi_hw *adapter, u32 base_address,
>  				   u32 instructions_sz,
>  				   u16 block_size,
>  				   u8 *ta_firmware);
> +int rsi_usb_check_queue_status(struct rsi_hw *adapter, u8 q_num);
>  #endif
> 
Update addresses various valid issues,

Acked-by: Colin Ian King <colin.king at canonical.com>




More information about the kernel-team mailing list