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