From patchwork Fri Jul 14 14:56:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amitkumar Karwar X-Patchwork-Id: 788573 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 3x8G7x2ZCYz9t1y; Sat, 15 Jul 2017 01:00:13 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="lMkjKfg2"; dkim-atps=neutral Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1dW24f-0007JP-Ks; Fri, 14 Jul 2017 15:00:09 +0000 Received: from mail-pf0-f193.google.com ([209.85.192.193]) by huckleberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1dW24a-0007Iq-CI for kernel-team@lists.ubuntu.com; Fri, 14 Jul 2017 15:00:04 +0000 Received: by mail-pf0-f193.google.com with SMTP id q85so11271873pfq.2 for ; Fri, 14 Jul 2017 08:00:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=GnvhI6VbU9zuINMkNFgr60Gpli68UgXs3Mox4zL8zSk=; b=lMkjKfg2mKaFOGWbz4vMPiVmYQV3X7ezif2ArMI8RSTUqOf27FR3nkSBIYnNyw74jv UPAM2cdmieh6Bk1O+j7y40fsbmILnH3yffroXs2+DAsSOs/1p6+IEY1ZoTr/qy1GrUEL OFSyas98ZEmnLPjnUefLVii4P3PAp/BZNl+hpIs/xzw1wOSZ5XwQWt0VAmLvOOysmYyq yXXPfR1Tn3mziszBCLFU19MAQqgExP8bp58313X09mFyU2fMRJCP00X1iL+QdfDEyn+/ j7YTivDwtMkXQyaM4dYHFRp7CgD5G6Ria+DE8iF9hFvk6hC00wt2brM56iaRbh3V/4ED bQPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=GnvhI6VbU9zuINMkNFgr60Gpli68UgXs3Mox4zL8zSk=; b=bkMeYWovRXdNZ+ut0W5liZz8udbeyoR/mTthoptSbnr05Y5obvAhlVR6aTGJFqmQrx slGkZuvPU0Q4oi0PKQB6L/7V2gvR5v/2In4UkmTHGWlaWk0OQCUef7rJ7sYJjVXmRSeB tbujnX/cM39IPQbuBDXx0++4LOWFZE97wyOfgQPz8Yxl7Jrg1+XtZ06VKIwKAMFEqr8F c9NvbYSLvzo+FOiuciohsiVoCdEgfCshcvAtgdyJRIdc5B5tWfwL2gV6zYoDNEZAQXTe 3C+btZeXs51KZb8MuYq/g5tpwDBWfDGZsJb+IkQJyoK7xTG1aOTuSM0JmdXfX+kU6pnP QJNw== X-Gm-Message-State: AIVw1109ylDbKgBtthrfuklkCrWZnyb0swvl1zQjudXuexnG/d39NUJk mOjArRclG7YdyIBy X-Received: by 10.98.159.16 with SMTP id g16mr5665059pfe.21.1500044401486; Fri, 14 Jul 2017 08:00:01 -0700 (PDT) Received: from cpu185.redpinesignals.com ([203.196.161.90]) by smtp.gmail.com with ESMTPSA id o13sm16459605pgr.40.2017.07.14.07.59.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 14 Jul 2017 08:00:00 -0700 (PDT) From: Amitkumar Karwar To: kernel-team@lists.ubuntu.com Subject: [PATCH] UBUNTU: SAUCE: Redpine: Upgrade to version 1.2 Date: Fri, 14 Jul 2017 20:26:33 +0530 Message-Id: <1500044194-3851-1-git-send-email-amitkarwar@gmail.com> X-Mailer: git-send-email 2.7.4 Cc: Amitkumar Karwar , Prameela Rani Garnepudi X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com From: Amitkumar Karwar BugLink: https://bugs.launchpad.net/bugs/1697829 Vendor release ver: 1.2 Changelog: 1.2 - WLAN Supported Features: ------------------------ 1) Station mode 2) 802.11bgn 3) Secutiry modes: Open, WEP, WPA, WPA2 4) AP mode 5) Bgscan and roaming 6) Legacy and UAPSD power save 7) Regulatory support 8) WoWLAN 9) Management frame protection 10) Wi-Fi direct mode WLAN Bug Fixes: --------------- 1) WoWLAN from S5 fails (lp: #1686283) 2) After wifi-ap is set, system will kernel panic (lp: #1699753) 3) Connect to "n" AP will cause system kernel panic (lp: #1699686) 4) Low throughput observed in some channels for TCP downlink traffic in Coex mode. WLAN Limitations/Features NOT Supported: ---------------------------------------- 1) For GTK rekey, wakeup trigger send to host. BT Supported Features: ---------------------- 1) BT EDR mode 2) BT LE mode 3) BT Coex mode * WLAN STA + BT EDR * WLAN STA + BT LE * WLAN STA + BT EDR + BT LE * WLAN AP + BT EDR * WLAN AP + BT EDR + BT LE 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.RC16 - WLAN Bug Fixes: --------------- 1. WoWLAN from S5 fails (lp: #1686283) 2. After wifi-ap is set, system will kernel panic (lp: #1699753) 3. Connect to "n" AP will cause system kernel panic (lp: #1699686) WLAN Limitations/Features NOT Supported: ---------------------------------------- 1) For GTK rekey, wakeup trigger send to host. 2) Low throughput observed for TCP downlink traffic in Coex mode 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.RC15 - WLAN Bug Fixes: --------------- 1) Coverity scan fixes (lp: #1694733) 2) Avoid driver reload at S4 resume 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.RC14 - WLAN Bug Fixes: --------------- 1) Low throughput with 40MHz issue resolved. WLAN Limitations/Features NOT Supported: ---------------------------------------- 1) S5 with WoWLAN does not work. 2) For GTK rekey, wakeup trigger send to host. 3) Low throughput observed for TCP downlink traffic in Coex mode 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. Signed-off-by: Amitkumar Karwar --- ubuntu/rsi/rsi_91x_coex.c | 1 + ubuntu/rsi/rsi_91x_core.c | 16 +-- ubuntu/rsi/rsi_91x_hal.c | 6 +- ubuntu/rsi/rsi_91x_hci.c | 19 ++-- ubuntu/rsi/rsi_91x_mac80211.c | 193 +++++++++++++++++++---------------- ubuntu/rsi/rsi_91x_mgmt.c | 56 +++++------ ubuntu/rsi/rsi_91x_sdio.c | 228 +++++++++++++++++++++++++----------------- ubuntu/rsi/rsi_91x_sdio_ops.c | 71 ++++++++++--- ubuntu/rsi/rsi_91x_usb.c | 58 ++++++----- ubuntu/rsi/rsi_91x_usb_ops.c | 34 +++---- ubuntu/rsi/rsi_common.h | 3 + ubuntu/rsi/rsi_main.h | 26 ++--- ubuntu/rsi/rsi_mgmt.h | 12 +-- ubuntu/rsi/rsi_sdio.h | 9 ++ ubuntu/rsi/rsi_usb.h | 6 +- 15 files changed, 440 insertions(+), 298 deletions(-) diff --git a/ubuntu/rsi/rsi_91x_coex.c b/ubuntu/rsi/rsi_91x_coex.c index 5b3b3ac..51ec270 100644 --- a/ubuntu/rsi/rsi_91x_coex.c +++ b/ubuntu/rsi/rsi_91x_coex.c @@ -105,6 +105,7 @@ int rsi_coex_recv_pkt(struct rsi_common *common, u8 *msg) u16 msg_type = msg[2]; if (msg_type == COMMON_CARD_READY_IND) { + common->hibernate_resume = false; ven_rsi_dbg(INFO_ZONE, "COMMON CARD READY RECEIVED\n"); rsi_handle_card_ready(common, msg); } else if (msg_type == SLEEP_NOTIFY_IND) { diff --git a/ubuntu/rsi/rsi_91x_core.c b/ubuntu/rsi/rsi_91x_core.c index db320e2..049f6ea 100644 --- a/ubuntu/rsi/rsi_91x_core.c +++ b/ubuntu/rsi/rsi_91x_core.c @@ -303,8 +303,8 @@ void rsi_core_qos_processor(struct rsi_common *common) if ((q_num < MGMT_SOFT_Q) || ((!adapter->peer_notify) && (q_num == MGMT_SOFT_Q))) { - mutex_unlock(&common->tx_lock); - break; + mutex_unlock(&common->tx_lock); + break; } } @@ -321,16 +321,16 @@ 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); break; } + if ((adapter->peer_notify) && + (skb->data[2] == PEER_NOTIFY)) { + adapter->peer_notify = false; + ven_rsi_dbg(INFO_ZONE, "%s RESET PEER_NOTIFY\n", __func__); + } #ifdef CONFIG_VEN_RSI_COEX if (q_num == MGMT_BEACON_Q) { status = rsi_send_pkt(common, skb); @@ -343,7 +343,7 @@ void rsi_core_qos_processor(struct rsi_common *common) else if(q_num == MGMT_BEACON_Q) { status = rsi_send_pkt(common, skb); dev_kfree_skb(skb); - } else + } else status = rsi_send_data_pkt(common, skb); #endif diff --git a/ubuntu/rsi/rsi_91x_hal.c b/ubuntu/rsi/rsi_91x_hal.c index 6b2be02..cccedaf 100644 --- a/ubuntu/rsi/rsi_91x_hal.c +++ b/ubuntu/rsi/rsi_91x_hal.c @@ -247,7 +247,7 @@ int rsi_prepare_mgmt_desc(struct rsi_common *common,struct sk_buff *skb) struct rsi_hw *adapter = common->priv; struct ieee80211_hdr *wh = NULL; struct ieee80211_tx_info *info; - struct ieee80211_conf *conf = &adapter->hw->conf; + struct ieee80211_conf *conf;// = &adapter->hw->conf; struct ieee80211_vif *vif = NULL; struct skb_info *tx_params; int status = -EINVAL; @@ -257,6 +257,9 @@ int rsi_prepare_mgmt_desc(struct rsi_common *common,struct sk_buff *skb) u8 vap_id = 0; u32 dword_align_bytes = 0; + if (!adapter->hw) + goto err; + conf = &adapter->hw->conf; info = IEEE80211_SKB_CB(skb); tx_params = (struct skb_info *)info->driver_data; @@ -1272,6 +1275,7 @@ int rsi_hal_device_init(struct rsi_hw *adapter) return -EINVAL; } adapter->common_hal_fsm = COMMAN_HAL_WAIT_FOR_CARD_READY; + common->fsm_state = FSM_CARD_NOT_READY; #if defined(CONFIG_VEN_RSI_BT_ALONE) || defined(CONFIG_VEN_RSI_COEX) adapter->priv->bt_fsm_state = BT_DEVICE_NOT_READY; diff --git a/ubuntu/rsi/rsi_91x_hci.c b/ubuntu/rsi/rsi_91x_hci.c index 5599622..d5f99fa 100644 --- a/ubuntu/rsi/rsi_91x_hci.c +++ b/ubuntu/rsi/rsi_91x_hci.c @@ -227,6 +227,7 @@ int rsi_send_rfmode_frame(struct rsi_common *common) { struct sk_buff *skb; struct rsi_bt_rfmode_frame *cmd_frame; + int status; ven_rsi_dbg(MGMT_TX_ZONE, "%s: Sending BT RF mode frame\n", __func__); @@ -246,7 +247,11 @@ int rsi_send_rfmode_frame(struct rsi_common *common) 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); + status = common->priv->host_intf_ops->write_pkt(common->priv, + skb->data, + skb->len); + dev_kfree_skb(skb); + return status; } EXPORT_SYMBOL_GPL(rsi_send_rfmode_frame); @@ -254,6 +259,7 @@ int rsi_deregister_bt(struct rsi_common *common) { struct sk_buff *skb; struct rsi_bt_cmd_frame *cmd_frame; + int status; ven_rsi_dbg(MGMT_TX_ZONE, "%s: Sending BT register frame\n", __func__); @@ -271,7 +277,11 @@ int rsi_deregister_bt(struct rsi_common *common) 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); + status = common->priv->host_intf_ops->write_pkt(common->priv, + skb->data, + skb->len); + dev_kfree_skb(skb); + return status; } EXPORT_SYMBOL_GPL(rsi_deregister_bt); @@ -304,7 +314,7 @@ int rsi_hci_recv_pkt(struct rsi_common *common, u8 *pkt) return 0; } - + if (common->bt_fsm_state != BT_DEVICE_READY) { ven_rsi_dbg(INFO_ZONE, "BT Device not ready\n"); return 0; @@ -578,9 +588,6 @@ 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); diff --git a/ubuntu/rsi/rsi_91x_mac80211.c b/ubuntu/rsi/rsi_91x_mac80211.c index 75aaa08..bc6f1bd 100644 --- a/ubuntu/rsi/rsi_91x_mac80211.c +++ b/ubuntu/rsi/rsi_91x_mac80211.c @@ -456,6 +456,9 @@ static void rsi_mac80211_hw_scan_cancel(struct ieee80211_hw *hw, void ven_rsi_mac80211_detach(struct rsi_hw *adapter) { struct ieee80211_hw *hw = adapter->hw; +#ifdef CONFIG_HW_SCAN_OFFLOAD + struct rsi_common *common = adapter->priv; +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) enum nl80211_band band; #else @@ -464,11 +467,15 @@ void ven_rsi_mac80211_detach(struct rsi_hw *adapter) ven_rsi_dbg(INFO_ZONE, "Detach mac80211...\n"); +#ifdef CONFIG_HW_SCAN_OFFLOAD + flush_workqueue(common->scan_workqueue); +#endif if (hw) { ieee80211_stop_queues(hw); ieee80211_unregister_hw(hw); ieee80211_free_hw(hw); adapter->hw = NULL; + adapter->sc_nvifs = 0; } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) @@ -536,7 +543,7 @@ static void rsi_mac80211_tx(struct ieee80211_hw *hw, struct rsi_hw *adapter = hw->priv; struct rsi_common *common = adapter->priv; struct ieee80211_hdr *wlh = (struct ieee80211_hdr *)skb->data; - struct ieee80211_vif *vif = adapter->vifs[adapter->sc_nvifs - 1]; + struct ieee80211_vif *vif = adapter->vifs[adapter->sc_nvifs - 1]; #ifdef CONFIG_VEN_RSI_WOW if (common->wow_flags & RSI_WOW_ENABLED) { @@ -549,15 +556,15 @@ static void rsi_mac80211_tx(struct ieee80211_hw *hw, return; } - if ((common->coex_mode == 4) && - (vif->type == NL80211_IFTYPE_STATION) && - ((ieee80211_is_probe_req(wlh->frame_control) || - (ieee80211_is_auth(wlh->frame_control))))) { - ven_rsi_dbg(ERR_ZONE, - "Dropping Station packets in AP+BT dual mode\n"); - ieee80211_free_txskb(common->priv->hw, skb); - return; - } + if ((common->coex_mode == 4) && + (vif->type == NL80211_IFTYPE_STATION) && + ((ieee80211_is_probe_req(wlh->frame_control) || + (ieee80211_is_auth(wlh->frame_control))))) { + ven_rsi_dbg(ERR_ZONE, + "Dropping Station packets in AP+BT dual mode\n"); + ieee80211_free_txskb(common->priv->hw, skb); + return; + } #ifndef CONFIG_VEN_RSI_BT_ALONE rsi_core_xmit(common, skb); @@ -606,14 +613,9 @@ static void rsi_mac80211_stop(struct ieee80211_hw *hw) { struct rsi_hw *adapter = hw->priv; struct rsi_common *common = adapter->priv; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) - struct cfg80211_scan_info info; -#endif + ven_rsi_dbg(ERR_ZONE, "===> Interface DOWN <===\n"); - if (common->fsm_state != FSM_MAC_INIT_DONE) - return; - mutex_lock(&common->mutex); common->iface_down = true; @@ -625,7 +627,8 @@ static void rsi_mac80211_stop(struct ieee80211_hw *hw) wiphy_rfkill_stop_polling(hw->wiphy); /* Block all rx frames */ - rsi_send_rx_filter_frame(common, 0xffff); + if (common->fsm_state == FSM_MAC_INIT_DONE) + rsi_send_rx_filter_frame(common, 0xffff); mutex_unlock(&common->mutex); } @@ -862,26 +865,26 @@ static int rsi_mac80211_change_interface(struct ieee80211_hw *hw, goto out; } // if (intf_mode == AP_OPMODE) { - rsi_set_vap_capabilities(common, + rsi_set_vap_capabilities(common, //STA_OPMODE, common->last_vap_type, - vif->addr, - vif_info->vap_id, - VAP_DELETE); - status = rsi_set_vap_capabilities(common, - intf_mode, - vif->addr, - vif_info->vap_id, - VAP_ADD); + vif->addr, + vif_info->vap_id, + VAP_DELETE); + status = rsi_set_vap_capabilities(common, + intf_mode, + vif->addr, + vif_info->vap_id, + VAP_ADD); #if 0 - } else if ((intf_mode != common->last_vap_type) || - (!ether_addr_equal(vif->addr, common->last_vap_addr))) { - status = rsi_set_vap_capabilities(common, - intf_mode, - vif->addr, - vif_info->vap_id, - VAP_UPDATE); - } + } else if ((intf_mode != common->last_vap_type) || + (!ether_addr_equal(vif->addr, common->last_vap_addr))) { + status = rsi_set_vap_capabilities(common, + intf_mode, + vif->addr, + vif_info->vap_id, + VAP_UPDATE); + } #endif if ((vif->type == NL80211_IFTYPE_AP) || (vif->type == NL80211_IFTYPE_P2P_GO)) { @@ -1460,7 +1463,7 @@ static int rsi_mac80211_set_key(struct ieee80211_hw *hw, case DISABLE_KEY: if ((vif->type == NL80211_IFTYPE_STATION) || (vif->type == NL80211_IFTYPE_P2P_CLIENT)) - secinfo->security_enable = false; + secinfo->security_enable = false; ven_rsi_dbg(ERR_ZONE, "%s: RSI del key\n", __func__); memset(key, 0, sizeof(struct ieee80211_key_conf)); status = rsi_hal_key_config(hw, vif, key, sta); @@ -1489,6 +1492,7 @@ static int rsi_mac80211_set_key(struct ieee80211_hw *hw, * * Return: status: 0 on success, negative error code on failure. */ +#ifndef CONFIG_CARACALLA_BOARD #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)) static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -1511,6 +1515,12 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_ampdu_params *params) #endif +#else +static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_ampdu_params *params) +#endif + { int status = 1; struct rsi_hw *adapter = hw->priv; @@ -1520,7 +1530,7 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw, u8 ii = 0; u8 sta_id = 0; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)) +#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)) || defined(CONFIG_CARACALLA_BOARD)) u16 tid = params->tid; u8 buf_size = params->buf_size; enum ieee80211_ampdu_mlme_action action = params->action; @@ -1534,7 +1544,7 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw, mutex_lock(&common->mutex); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)) +#if ((LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)) && !(defined(CONFIG_CARACALLA_BOARD))) if (ssn != NULL) seq_no = *ssn; #else @@ -1886,12 +1896,12 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw, ((common->key->cipher == WLAN_CIPHER_SUITE_WEP104) || (common->key->cipher == WLAN_CIPHER_SUITE_WEP40))) { rsi_load_key(adapter->priv, - common->key->key, - common->key->keylen, - RSI_PAIRWISE_KEY, - common->key->keyidx, - common->key->cipher, - i); + common->key->key, + common->key->keylen, + RSI_PAIRWISE_KEY, + common->key->keyidx, + common->key->cipher, + i); } for (j = 0; j < IEEE80211_NUM_ACS; j++) common->stations[i].seq_no[j] = 1; @@ -2026,7 +2036,7 @@ static void rsi_mac80211_sw_scan_start(struct ieee80211_hw *hw, struct ieee80211_bss_conf *bss = &adapter->vifs[0]->bss_conf; if (common->fsm_state != FSM_MAC_INIT_DONE) - return -ENODEV; + return; if (common->p2p_enabled) return; @@ -2367,41 +2377,31 @@ static u16 rsi_wow_map_triggers(struct rsi_common *common, } #endif -#ifdef CONFIG_PM -int rsi_mac80211_suspend(struct ieee80211_hw *hw, - struct cfg80211_wowlan *wowlan) -{ #ifdef CONFIG_VEN_RSI_WOW - struct rsi_hw *adapter = hw->priv; +int rsi_config_wowlan(struct rsi_hw *adapter, struct cfg80211_wowlan *wowlan) +{ struct rsi_common *common = adapter->priv; u16 triggers = 0; - u16 rx_filter_word = 0; + u16 rx_filter_word = 0; struct ieee80211_bss_conf *bss = &adapter->vifs[0]->bss_conf; -#endif - int ret = 0; - ven_rsi_dbg(INFO_ZONE, "***** mac80211 suspend called ******\n"); + ven_rsi_dbg(INFO_ZONE, "Config WoWLAN to device\n"); -#ifdef CONFIG_VEN_RSI_WOW if (WARN_ON(!wowlan)) { - ven_rsi_dbg(ERR_ZONE, - "##### WoW triggers not enabled #####\n"); - ret = -EINVAL; - goto fail_wow; + ven_rsi_dbg(ERR_ZONE, "WoW triggers not enabled\n"); + return -EINVAL; } triggers = rsi_wow_map_triggers(common, wowlan); if (!triggers) { ven_rsi_dbg(ERR_ZONE, "%s:No valid WoW triggers\n",__func__); - ret = -EINVAL; - goto fail_wow; + return -EINVAL; } if (!bss->assoc) { ven_rsi_dbg(ERR_ZONE, "Cannot configure WoWLAN (Station not connected)\n"); common->wow_flags |= RSI_WOW_NO_CONNECTION; - ret = 0; - goto fail_wow; + return 0; } ven_rsi_dbg(INFO_ZONE, "TRIGGERS %x\n", triggers); rsi_send_wowlan_request(common, triggers, 1); @@ -2415,9 +2415,29 @@ int rsi_mac80211_suspend(struct ieee80211_hw *hw, rsi_send_rx_filter_frame(common, rx_filter_word); common->wow_flags |= RSI_WOW_ENABLED; -fail_wow: + + return 0; +} +EXPORT_SYMBOL_GPL(rsi_config_wowlan); +#endif + +#ifdef CONFIG_PM +static int rsi_mac80211_suspend(struct ieee80211_hw *hw, + struct cfg80211_wowlan *wowlan) +{ +#ifdef CONFIG_VEN_RSI_WOW + struct rsi_hw *adapter = hw->priv; + struct rsi_common *common = adapter->priv; + + mutex_lock(&common->mutex); + if (rsi_config_wowlan(adapter, wowlan)) { + ven_rsi_dbg(ERR_ZONE, "Failed to configure WoWLAN\n"); + mutex_unlock(&common->mutex); + return 1; + } + mutex_unlock(&common->mutex); #endif - return (ret ? 1 : 0); + return 0; } static int rsi_mac80211_resume(struct ieee80211_hw *hw) @@ -2426,9 +2446,9 @@ static int rsi_mac80211_resume(struct ieee80211_hw *hw) struct rsi_common *common = adapter->priv; #ifdef CONFIG_VEN_RSI_WOW u16 rx_filter_word = 0; -#endif adapter->priv->wow_flags = 0; +#endif ven_rsi_dbg(INFO_ZONE, "%s: mac80211 resume\n", __func__); @@ -2436,6 +2456,7 @@ static int rsi_mac80211_resume(struct ieee80211_hw *hw) return 0; #ifdef CONFIG_VEN_RSI_WOW + mutex_lock(&common->mutex); rsi_send_wowlan_request(common, 0, 0); rx_filter_word = (ALLOW_DATA_ASSOC_PEER | @@ -2443,7 +2464,9 @@ static int rsi_mac80211_resume(struct ieee80211_hw *hw) ALLOW_MGMT_ASSOC_PEER | 0); rsi_send_rx_filter_frame(common, rx_filter_word); + mutex_unlock(&common->mutex); #endif + return 0; } #endif @@ -2502,14 +2525,12 @@ void rsi_roc_timeout(unsigned long data) struct rsi_common *common = (struct rsi_common *)data; struct ieee80211_vif *vif = common->roc_vif; struct vif_priv *vif_info = (struct vif_priv *)vif->drv_priv; - enum opmode intf_mode; - - ven_rsi_dbg(INFO_ZONE, "Remain on channel expired\n"); + enum opmode intf_mode; mutex_lock(&common->mutex); - + ieee80211_remain_on_channel_expired(common->priv->hw); - + if (timer_pending(&common->roc_timer)) del_timer(&common->roc_timer); @@ -2540,8 +2561,8 @@ static int rsi_mac80211_cancel_roc(struct ieee80211_hw *hw) struct rsi_common *common = adapter->priv; struct ieee80211_vif *vif = common->roc_vif; struct vif_priv *vif_info = (struct vif_priv *)vif->drv_priv; - enum opmode intf_mode; - + enum opmode intf_mode; + ven_rsi_dbg(INFO_ZONE, "Cancel remain on channel\n"); mutex_lock(&common->mutex); @@ -2569,7 +2590,7 @@ static int rsi_mac80211_cancel_roc(struct ieee80211_hw *hw) } mutex_unlock(&common->mutex); - + return 0; } @@ -2741,7 +2762,7 @@ int rsi_mac80211_attach(struct rsi_common *common) hw->uapsd_queues = IEEE80211_MARKALL_UAPSD_QUEUES; hw->uapsd_max_sp_len = IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL; hw->max_tx_aggregation_subframes = 8; -// hw->max_rx_aggregation_subframes = 8; + hw->max_rx_aggregation_subframes = 8; rsi_register_rates_channels(adapter, NL80211_BAND_2GHZ); wiphy->bands[NL80211_BAND_2GHZ] = @@ -2758,18 +2779,18 @@ int rsi_mac80211_attach(struct rsi_common *common) SET_IEEE80211_PERM_ADDR(hw, common->mac_addr); ether_addr_copy(hw->wiphy->addr_mask, addr_mask); - if (common->coex_mode == 4) { - wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_AP); - } else if (common->coex_mode == 2) { - wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); - } else { - wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_P2P_DEVICE) | - BIT(NL80211_IFTYPE_P2P_CLIENT) | - BIT(NL80211_IFTYPE_P2P_GO); - } + if (common->coex_mode == 4) { + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP); + } else if (common->coex_mode == 2) { + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + } else { + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_DEVICE) | + BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO); + } wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; wiphy->retry_short = RETRY_SHORT; wiphy->retry_long = RETRY_LONG; diff --git a/ubuntu/rsi/rsi_91x_mgmt.c b/ubuntu/rsi/rsi_91x_mgmt.c index 2cd37bd..3cb2b20 100644 --- a/ubuntu/rsi/rsi_91x_mgmt.c +++ b/ubuntu/rsi/rsi_91x_mgmt.c @@ -429,7 +429,7 @@ static int rsi_send_internal_mgmt_frame(struct rsi_common *common, 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); + skb_queue_tail(&common->tx_queue[MGMT_SOFT_Q], skb); rsi_set_event(&common->tx_thread.event); return 0; } @@ -1207,7 +1207,7 @@ void rsi_apply_carcalla_power_values(struct rsi_hw *adapter, if (channel->hw_value == 12) max_power = 15; else if (channel->hw_value == 13) - max_power = 7; + max_power = 7; else return; } else { @@ -1222,7 +1222,7 @@ void rsi_apply_carcalla_power_values(struct rsi_hw *adapter, if (channel->hw_value == 12) max_power = 7; else if (channel->hw_value == 13) - max_power = 5; + max_power = 5; else return; } else { @@ -1231,7 +1231,7 @@ void rsi_apply_carcalla_power_values(struct rsi_hw *adapter, else if (channel->hw_value == 9) max_power = 5; else if (channel->hw_value == 10) - max_power = 4; + max_power = 4; else return; } @@ -2166,28 +2166,28 @@ int rsi_set_antenna(struct rsi_common *common, int rsi_send_wowlan_request(struct rsi_common *common, u16 flags, u16 sleep_status) { - struct rsi_wowlan_req *cmd_frame; - struct sk_buff *skb; - u8 length; - u8 sourceid[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - ven_rsi_dbg(ERR_ZONE, "%s: Sending wowlan request frame\n", __func__); - - skb = dev_alloc_skb(sizeof(*cmd_frame)); - if (!skb) { - ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n", - __func__); - return -ENOMEM; - } - memset(skb->data, 0, sizeof(*cmd_frame)); - cmd_frame = (struct rsi_wowlan_req *)skb->data; - - cmd_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12); - cmd_frame->desc_word[1] |= cpu_to_le16(WOWLAN_CONFIG_PARAMS); - - memcpy(cmd_frame->sourceid, &sourceid, IEEE80211_ADDR_LEN); - - cmd_frame->host_sleep_status = sleep_status; + struct rsi_wowlan_req *cmd_frame; + struct sk_buff *skb; + u8 length; + u8 sourceid[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + ven_rsi_dbg(ERR_ZONE, "%s: Sending wowlan request frame\n", __func__); + + skb = dev_alloc_skb(sizeof(*cmd_frame)); + if (!skb) { + ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n", + __func__); + return -ENOMEM; + } + memset(skb->data, 0, sizeof(*cmd_frame)); + cmd_frame = (struct rsi_wowlan_req *)skb->data; + + cmd_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12); + cmd_frame->desc_word[1] |= cpu_to_le16(WOWLAN_CONFIG_PARAMS); + + memcpy(cmd_frame->sourceid, &sourceid, IEEE80211_ADDR_LEN); + + cmd_frame->host_sleep_status = sleep_status; if ((common->secinfo.security_enable) && (common->secinfo.gtk_cipher)) flags |= RSI_WOW_GTK_REKEY; @@ -2666,8 +2666,8 @@ static int rsi_handle_ta_confirm(struct rsi_common *common, u8 *msg) ven_rsi_dbg(INFO_ZONE, "BG scan complete event\n"); if (common->bgscan_en) { if (!rsi_send_bgscan_params(common, 0)) - common->bgscan_en = 0; - } + common->bgscan_en = 0; + } #ifdef CONFIG_HW_SCAN_OFFLOAD #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) info.aborted = false; diff --git a/ubuntu/rsi/rsi_91x_sdio.c b/ubuntu/rsi/rsi_91x_sdio.c index eb7821b..af9f096 100644 --- a/ubuntu/rsi/rsi_91x_sdio.c +++ b/ubuntu/rsi/rsi_91x_sdio.c @@ -37,12 +37,12 @@ /* Default operating mode is Wi-Fi alone */ #ifdef CONFIG_CARACALLA_BOARD #if defined (CONFIG_VEN_RSI_COEX) || defined(CONFIG_VEN_RSI_BT_ALONE) -u16 dev_oper_mode = DEV_OPMODE_STA_BT_DUAL; +static u16 dev_oper_mode = DEV_OPMODE_STA_BT_DUAL; #else -u16 dev_oper_mode = DEV_OPMODE_WIFI_ALONE; +static u16 dev_oper_mode = DEV_OPMODE_WIFI_ALONE; #endif #else -u16 dev_oper_mode = DEV_OPMODE_WIFI_ALONE; +static u16 dev_oper_mode = DEV_OPMODE_WIFI_ALONE; #endif module_param(dev_oper_mode, ushort, S_IRUGO); MODULE_PARM_DESC(dev_oper_mode, @@ -164,11 +164,6 @@ static int rsi_issue_sdiocommand(struct sdio_func *func, return err; } -static void rsi_dummy_isr(struct sdio_func *function) -{ - return; -} - /** * rsi_handle_interrupt() - This function is called upon the occurrence * of an interrupt. @@ -182,6 +177,8 @@ static void rsi_handle_interrupt(struct sdio_func *function) struct rsi_91x_sdiodev *dev = (struct rsi_91x_sdiodev *)adapter->rsi_dev; + if (adapter->priv->fsm_state == FSM_FW_NOT_LOADED) + return; dev->sdio_irq_task = current; rsi_interrupt_handler(adapter); dev->sdio_irq_task = NULL; @@ -1066,6 +1063,8 @@ static int rsi_probe(struct sdio_func *pfunction, const struct sdio_device_id *id) { struct rsi_hw *adapter; + struct rsi_91x_sdiodev *sdev; + int status; ven_rsi_dbg(INIT_ZONE, "%s: Init function called\n", __func__); @@ -1084,48 +1083,54 @@ static int rsi_probe(struct sdio_func *pfunction, __func__); goto fail; } + + /* Initialize receive path */ + sdev = adapter->rsi_dev; + rsi_init_event(&sdev->rx_thread.event); + status = rsi_create_kthread(adapter->priv, &sdev->rx_thread, + rsi_sdio_rx_thread, "SDIO-RX-Thread"); + if (status) { + ven_rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__); + goto fail; + } + skb_queue_head_init(&sdev->rx_q.head); + sdev->rx_q.num_rx_pkts = 0; + #ifdef CONFIG_SDIO_INTR_POLL init_sdio_intr_status_poll_thread(adapter->priv); #endif sdio_claim_host(pfunction); -// if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) { - if (sdio_claim_irq(pfunction, rsi_dummy_isr)) { + if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) { ven_rsi_dbg(ERR_ZONE, "%s: Failed to request IRQ\n", __func__); sdio_release_host(pfunction); - goto fail; + goto fail1; } sdio_release_host(pfunction); ven_rsi_dbg(INIT_ZONE, "%s: Registered Interrupt handler\n", __func__); if (rsi_hal_device_init(adapter)) { ven_rsi_dbg(ERR_ZONE, "%s: Failed in device init\n", __func__); - sdio_claim_host(pfunction); - sdio_release_irq(pfunction); - sdio_disable_func(pfunction); - sdio_release_host(pfunction); - goto fail; + goto fail1; } ven_rsi_dbg(INFO_ZONE, "===> RSI Device Init Done <===\n"); if (rsi_sdio_master_access_msword(adapter, MISC_CFG_BASE_ADDR)) { ven_rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n", __func__); - return -EIO; + goto fail2; } ven_rsi_dbg(INIT_ZONE, "%s: Setting ms word to 0x41050000\n", __func__); - sdio_claim_host(pfunction); - sdio_release_irq(pfunction); - mdelay(10); - if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) { - ven_rsi_dbg(ERR_ZONE, "%s: Failed to request IRQ\n", __func__); - sdio_release_host(pfunction); - goto fail; - } - sdio_release_host(pfunction); adapter->priv->hibernate_resume = false; return 0; +fail2: + sdio_claim_host(pfunction); + sdio_release_irq(pfunction); + sdio_disable_func(pfunction); + sdio_release_host(pfunction); +fail1: + rsi_kill_thread(&sdev->rx_thread); fail: #ifdef CONFIG_SDIO_INTR_POLL rsi_kill_thread(&adapter->priv->sdio_intr_poll_thread); @@ -1154,6 +1159,8 @@ static void rsi_disconnect(struct sdio_func *pfunction) #ifdef CONFIG_SDIO_INTR_POLL rsi_kill_thread(&adapter->priv->sdio_intr_poll_thread); #endif + rsi_kill_thread(&dev->rx_thread); + sdio_claim_host(pfunction); sdio_release_irq(pfunction); sdio_release_host(pfunction); @@ -1164,17 +1171,15 @@ static void rsi_disconnect(struct sdio_func *pfunction) rsi_hci_detach(adapter->priv); #endif - if (!adapter->priv->hibernate_resume) { - /* Reset Chip */ - rsi_reset_chip(adapter); + /* Reset Chip */ + 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); - } + /* 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); dev->write_fail = 2; ven_rsi_91x_deinit(adapter); ven_rsi_dbg(ERR_ZONE, "##### RSI SDIO device disconnected #####\n"); @@ -1210,7 +1215,7 @@ static int rsi_sdio_disable_interrupts(struct sdio_func *pfunction) RSI_FN1_INT_REGISTER, &isr_status); ven_rsi_dbg(ERR_ZONE, "."); - } while (isr_status); + } while (isr_status); ven_rsi_dbg(ERR_ZONE, "\nInterrupts cleared"); sdio_claim_host(pfunction); @@ -1246,7 +1251,7 @@ static int rsi_sdio_disable_interrupts(struct sdio_func *pfunction) ven_rsi_dbg(INFO_ZONE, "INTR_EN reg content. = %x\n", data); sdio_release_host(pfunction); - + return 0; } @@ -1308,20 +1313,10 @@ static int rsi_suspend(struct device *dev) 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 0 -#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 - } + if ((common->wow_flags & RSI_WOW_ENABLED) && + (common->wow_flags & RSI_WOW_NO_CONNECTION)) + ven_rsi_dbg(ERR_ZONE, + "##### Device can not wake up through WLAN\n"); #endif ret = rsi_sdio_disable_interrupts(pfunction); @@ -1335,7 +1330,7 @@ static int rsi_suspend(struct device *dev) "Setting power management caps failed\n"); common->fsm_state = FSM_CARD_NOT_READY; - ven_rsi_dbg(INFO_ZONE, "***** SDIO BUS SUSPEND DONE ******\n"); + ven_rsi_dbg(INFO_ZONE, "***** RSI module suspended ******\n"); return 0; } @@ -1347,27 +1342,15 @@ int rsi_resume(struct device *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, "SDIO Bus resume =====>\n"); common->suspend_in_prog = false; common->fsm_state = FSM_MAC_INIT_DONE; ret = rsi_sdio_enable_interrupts(pfunction); -#if 0 -#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 -#endif - ven_rsi_dbg(INFO_ZONE, "***** RSI module resumed *****\n"); + return 0; } @@ -1376,9 +1359,8 @@ 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; - struct rsi_91x_sdiodev *sdev = - (struct rsi_91x_sdiodev *)adapter->rsi_dev; + struct rsi_common *common; + struct rsi_91x_sdiodev *sdev; ven_rsi_dbg(INFO_ZONE, "SDIO Bus freeze ===>\n"); @@ -1387,22 +1369,18 @@ static int rsi_freeze(struct device *dev) return -ENODEV; } + common = adapter->priv; + sdev = (struct rsi_91x_sdiodev *)adapter->rsi_dev; + 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 0 -#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 + if ((common->wow_flags & RSI_WOW_ENABLED) && + (common->wow_flags & RSI_WOW_NO_CONNECTION)) + ven_rsi_dbg(ERR_ZONE, + "##### Device can not wake up through WLAN\n"); #endif - } +#if defined(CONFIG_VEN_RSI_BT_ALONE) || defined(CONFIG_VEN_RSI_COEX) + rsi_hci_detach(common); #endif ret = rsi_sdio_disable_interrupts(pfunction); @@ -1414,6 +1392,8 @@ static int rsi_freeze(struct device *dev) if (ret) ven_rsi_dbg(INFO_ZONE, "Setting power management caps failed\n"); + ven_rsi_dbg(INFO_ZONE, "***** RSI module freezed *****\n"); + return 0; } @@ -1421,10 +1401,9 @@ int rsi_thaw(struct device *dev) { struct sdio_func *pfunction = dev_to_sdio_func(dev); struct rsi_hw *adapter = sdio_get_drvdata(pfunction); + + ven_rsi_dbg(ERR_ZONE, "SDIO Bus thaw =====>\n"); - ven_rsi_dbg(ERR_ZONE, "***** BUS THAW ******\n"); - -// adapter->priv->suspend_in_prog = false; adapter->priv->hibernate_resume = true; adapter->priv->fsm_state = FSM_CARD_NOT_READY; adapter->priv->bt_fsm_state = BT_DEVICE_NOT_READY; @@ -1432,7 +1411,8 @@ int rsi_thaw(struct device *dev) rsi_sdio_enable_interrupts(pfunction); - ven_rsi_dbg(INFO_ZONE, "RSI module resumed\n"); + ven_rsi_dbg(INFO_ZONE, "***** RSI module thaw done *****\n"); + return 0; } @@ -1443,7 +1423,67 @@ static int rsi_poweroff(struct device *dev) static void rsi_shutdown(struct device *dev) { - rsi_freeze(dev); + struct sdio_func *pfunction = dev_to_sdio_func(dev); + struct rsi_hw *adapter = sdio_get_drvdata(pfunction); + struct rsi_91x_sdiodev *sdev = + (struct rsi_91x_sdiodev *)adapter->rsi_dev; +#ifdef CONFIG_VEN_RSI_WOW + struct ieee80211_hw *hw = adapter->hw; + struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config; +#endif + + ven_rsi_dbg(ERR_ZONE, "SDIO Bus shutdown =====>\n"); + + adapter->priv->suspend_in_prog = true; + +#ifdef CONFIG_VEN_RSI_WOW + if (rsi_config_wowlan(adapter, wowlan)) + ven_rsi_dbg(ERR_ZONE, "Failed to configure WoWLAN\n"); +#endif + +#if defined(CONFIG_VEN_RSI_BT_ALONE) || defined(CONFIG_VEN_RSI_COEX) + rsi_hci_detach(adapter->priv); +#endif + + rsi_sdio_disable_interrupts(sdev->pfunction); + + if (sdev->write_fail) + ven_rsi_dbg(INFO_ZONE, "###### Device is not ready #######\n"); + + if (rsi_set_sdio_pm_caps(adapter)) + ven_rsi_dbg(INFO_ZONE, "Setting power management caps failed\n"); + + ven_rsi_dbg(INFO_ZONE, "***** RSI module shut down *****\n"); +} + +static int rsi_sdio_reinit_device(struct rsi_hw *adapter) +{ + struct rsi_91x_sdiodev *sdev = adapter->rsi_dev; + struct sdio_func *pfunction = sdev->pfunction; + int ii; + + /* Flush soft queues */ + for (ii = 0; ii < NUM_SOFT_QUEUES; ii++) + skb_queue_purge(&adapter->priv->tx_queue[ii]); + + /* Detach MAC */ + ven_rsi_mac80211_detach(adapter); + + /* Initialize device again */ + sdio_claim_host(pfunction); + + sdio_release_irq(pfunction); + rsi_reset_card(pfunction); + + sdio_enable_func(pfunction); + rsi_setupcard(adapter); + rsi_init_sdio_slave_regs(adapter); + sdio_claim_irq(pfunction, rsi_handle_interrupt); + rsi_hal_device_init(adapter); + + sdio_release_host(pfunction); + + return 0; } int rsi_restore(struct device *dev) @@ -1451,12 +1491,22 @@ int rsi_restore(struct device *dev) struct sdio_func *pfunction = dev_to_sdio_func(dev); struct rsi_hw *adapter = sdio_get_drvdata(pfunction); + ven_rsi_dbg(INFO_ZONE, "SDIO Bus restore ======>\n"); + adapter->priv->suspend_in_prog = false; adapter->priv->hibernate_resume = true; - adapter->priv->fsm_state = FSM_CARD_NOT_READY; + adapter->priv->fsm_state = FSM_FW_NOT_LOADED; adapter->priv->bt_fsm_state = BT_DEVICE_NOT_READY; adapter->priv->iface_down = true; + /* Initialize device again */ + rsi_sdio_reinit_device(adapter); + +#ifdef CONFIG_VEN_RSI_WOW + adapter->priv->wow_flags = 0; +#endif + adapter->priv->iface_down = false; + ven_rsi_dbg(INFO_ZONE, "RSI module restored\n"); return 0; diff --git a/ubuntu/rsi/rsi_91x_sdio_ops.c b/ubuntu/rsi/rsi_91x_sdio_ops.c index d575567..608afef 100644 --- a/ubuntu/rsi/rsi_91x_sdio_ops.c +++ b/ubuntu/rsi/rsi_91x_sdio_ops.c @@ -74,6 +74,50 @@ int rsi_sdio_master_access_msword(struct rsi_hw *adapter, return status; } +void rsi_sdio_rx_thread(struct rsi_common *common) +{ + struct rsi_hw *adapter = common->priv; + struct rsi_91x_sdiodev *sdev = adapter->rsi_dev; + struct sk_buff *skb; + int status; + bool done = false; + + do { + rsi_wait_event(&sdev->rx_thread.event, EVENT_WAIT_FOREVER); + + if (atomic_read(&sdev->rx_thread.thread_done)) + break; + + while (true) { + skb = skb_dequeue(&sdev->rx_q.head); + if (!skb) + break; + status = ven_rsi_read_pkt(common, skb->data, skb->len); + if (status) { + ven_rsi_dbg(ERR_ZONE, "Failed to read the packet\n"); + dev_kfree_skb(skb); + return; + } + dev_kfree_skb(skb); + if (sdev->rx_q.num_rx_pkts > 0) + sdev->rx_q.num_rx_pkts--; + + if (atomic_read(&sdev->rx_thread.thread_done)) { + done = true; + break; + } + } + rsi_reset_event(&sdev->rx_thread.event); + if (done) + break; + } while (1); + + ven_rsi_dbg(INFO_ZONE, "%s: Terminated SDIO RX thread\n", __func__); + skb_queue_purge(&sdev->rx_q.head); + atomic_inc(&sdev->rx_thread.thread_done); + complete_and_exit(&sdev->rx_thread.completion, 0); +} + /** * rsi_process_pkt() - This Function reads rx_blocks register and figures out * the size of the rx pkt. @@ -91,6 +135,7 @@ static int rsi_process_pkt(struct rsi_common *common) int status = 0; u8 value = 0; u8 protocol = 0, unaggr_pkt = 0; + struct sk_buff *skb; #define COEX_PKT 0 #define WLAN_PKT 3 @@ -128,28 +173,30 @@ static int rsi_process_pkt(struct rsi_common *common) unaggr_pkt = 1; rcv_pkt_len = (num_blks * 256); + + if (dev->rx_q.num_rx_pkts >= RSI_SDIO_MAX_RX_PKTS) + return -EINVAL; - common->rx_data_pkt = kmalloc(rcv_pkt_len, GFP_KERNEL); - if (!common->rx_data_pkt) { - ven_rsi_dbg(ERR_ZONE, "%s: Failed in memory allocation\n", + skb = dev_alloc_skb(rcv_pkt_len); + if (!skb) { + ven_rsi_dbg(ERR_ZONE, "%s: Failed to allocate rx packet\n", __func__); return -ENOMEM; } + skb_put(skb, rcv_pkt_len); - status = rsi_sdio_host_intf_read_pkt(adapter, - common->rx_data_pkt, - rcv_pkt_len); + status = rsi_sdio_host_intf_read_pkt(adapter, skb->data, skb->len); if (status) { ven_rsi_dbg(ERR_ZONE, "%s: Failed to read packet from card\n", __func__); - goto fail; + dev_kfree_skb(skb); + return status; } + skb_queue_tail(&dev->rx_q.head, skb); + dev->rx_q.num_rx_pkts++; + rsi_set_event(&dev->rx_thread.event); - status = ven_rsi_read_pkt(common, common->rx_data_pkt, rcv_pkt_len); - -fail: - kfree(common->rx_data_pkt); - return status; + return 0; } /** diff --git a/ubuntu/rsi/rsi_91x_usb.c b/ubuntu/rsi/rsi_91x_usb.c index bdc26aa..5876bc0 100644 --- a/ubuntu/rsi/rsi_91x_usb.c +++ b/ubuntu/rsi/rsi_91x_usb.c @@ -36,12 +36,12 @@ /* Default operating mode is Wi-Fi alone */ #ifdef CONFIG_CARACALLA_BOARD #if defined (CONFIG_VEN_RSI_COEX) || defined(CONFIG_VEN_RSI_BT_ALONE) -u16 dev_oper_mode = DEV_OPMODE_STA_BT_DUAL; +static u16 dev_oper_mode = DEV_OPMODE_STA_BT_DUAL; #else -u16 dev_oper_mode = DEV_OPMODE_WIFI_ALONE; +static u16 dev_oper_mode = DEV_OPMODE_WIFI_ALONE; #endif #else -u16 dev_oper_mode = DEV_OPMODE_WIFI_ALONE; +static u16 dev_oper_mode = DEV_OPMODE_WIFI_ALONE; #endif module_param(dev_oper_mode, ushort, S_IRUGO); MODULE_PARM_DESC(dev_oper_mode, @@ -359,9 +359,14 @@ static void rsi_rx_done_handler(struct urb *urb) ven_rsi_dbg(INFO_ZONE, "%s: Zero length packet\n", __func__); return; } - rx_cb->pend = 1; + skb_put(rx_cb->rx_skb, urb->actual_length); + skb_queue_tail(&dev->rx_q[rx_cb->ep_num - 1], rx_cb->rx_skb); rsi_set_event(&dev->rx_thread.event); + + if (rsi_rx_urb_submit(dev->priv, rx_cb->ep_num)) + ven_rsi_dbg(ERR_ZONE, "%s: Failed in urb submission", __func__); + } /** @@ -370,12 +375,24 @@ static void rsi_rx_done_handler(struct urb *urb) * * Return: 0 on success, a negative error code on failure. */ -static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num) +int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num) { struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; struct rx_usb_ctrl_block *rx_cb = &dev->rx_cb[ep_num - 1]; struct urb *urb = rx_cb->rx_urb; int status; + struct sk_buff *skb; + u8 dword_align_bytes; + + skb = dev_alloc_skb(3000); + if (!skb) + return -ENOMEM; + skb_reserve(skb, 64); /* For dword alignment */ + dword_align_bytes = (unsigned long)skb->data & 0x3f; + if (dword_align_bytes) + skb_push(skb, dword_align_bytes); + urb->transfer_buffer = skb->data; + rx_cb->rx_skb = skb; usb_fill_bulk_urb(urb, dev->usbdev, @@ -488,12 +505,13 @@ int rsi_usb_load_data_master_write(struct rsi_hw *adapter, int rsi_usb_check_queue_status(struct rsi_hw *adapter, u8 q_num) { + return QUEUE_NOT_FULL; + +#if 0 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; @@ -534,6 +552,7 @@ int rsi_usb_check_queue_status(struct rsi_hw *adapter, u8 q_num) return QUEUE_FULL; return QUEUE_NOT_FULL; +#endif } /** @@ -549,10 +568,11 @@ static void rsi_deinit_usb_interface(struct rsi_hw *adapter) ven_rsi_dbg(INFO_ZONE, "Deinitializing USB interface...\n"); rsi_kill_thread(&dev->rx_thread); - kfree(dev->rx_cb[0].rx_buffer); + //kfree(dev->rx_cb[0].rx_buffer); + skb_queue_purge(&dev->rx_q[0]); usb_free_urb(dev->rx_cb[0].rx_urb); #if defined (CONFIG_VEN_RSI_BT_ALONE) || defined(CONFIG_VEN_RSI_COEX) - kfree(dev->rx_cb[1].rx_buffer); + //kfree(dev->rx_cb[1].rx_buffer); usb_free_urb(dev->rx_cb[1].rx_urb); #endif kfree(dev->saved_tx_buffer); @@ -621,36 +641,26 @@ static int rsi_usb_init_rx(struct rsi_hw *adapter) { struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; struct rx_usb_ctrl_block *rx_cb; - u8 dword_align_bytes = 0, idx; + u8 idx; for (idx = 0; idx < MAX_RX_URBS; idx++) { rx_cb = &dev->rx_cb[idx]; - rx_cb->rx_buffer = kzalloc(2000 * 4, GFP_KERNEL | GFP_DMA); - if (!rx_cb->rx_buffer) - return -ENOMEM - ; - rx_cb->orig_rx_buffer = rx_cb->rx_buffer; - dword_align_bytes = (unsigned long)rx_cb->rx_buffer & 0x3f; - if (dword_align_bytes) - rx_cb->rx_buffer = rx_cb->rx_buffer + - (64 - dword_align_bytes); rx_cb->rx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!rx_cb->rx_urb) { ven_rsi_dbg(ERR_ZONE, "Failed alloc rx urb[%d]\n", idx); goto err; } - rx_cb->rx_urb->transfer_buffer = rx_cb->rx_buffer; rx_cb->ep_num = idx + 1; rx_cb->data = (void *)dev; + + skb_queue_head_init(&dev->rx_q[idx]); } return 0; err: - kfree(rx_cb[0].rx_buffer); kfree(rx_cb[0].rx_urb); - kfree(rx_cb[1].rx_buffer); kfree(rx_cb[1].rx_urb); return -1; } @@ -676,6 +686,7 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter, adapter->rsi_dev = rsi_dev; rsi_dev->usbdev = interface_to_usbdev(pfunction); + rsi_dev->priv = (void *)adapter; if (rsi_find_bulk_in_and_out_endpoints(pfunction, adapter)) return -EINVAL; @@ -708,11 +719,10 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter, adapter->check_hw_queue_status = rsi_usb_check_queue_status; adapter->determine_event_timeout = rsi_usb_event_timeout; adapter->host_intf_ops = &usb_host_intf_ops; - rsi_dev->priv = (void *)adapter; rsi_init_event(&rsi_dev->rx_thread.event); status = rsi_create_kthread(common, &rsi_dev->rx_thread, - rsi_usb_rx_thread, "RX-Thread"); + rsi_usb_rx_thread, "USB-RX-Thread"); if (status) { ven_rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__); goto fail_2; diff --git a/ubuntu/rsi/rsi_91x_usb_ops.c b/ubuntu/rsi/rsi_91x_usb_ops.c index 2f4c43e..e97a774 100644 --- a/ubuntu/rsi/rsi_91x_usb_ops.c +++ b/ubuntu/rsi/rsi_91x_usb_ops.c @@ -42,7 +42,7 @@ void rsi_usb_rx_thread(struct rsi_common *common) { struct rsi_hw *adapter = common->priv; struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; - struct rx_usb_ctrl_block *rx_cb; + struct sk_buff *skb; int status, idx; do { @@ -52,28 +52,18 @@ void rsi_usb_rx_thread(struct rsi_common *common) break; for (idx = 0; idx < MAX_RX_URBS; idx++) { - rx_cb = &dev->rx_cb[idx]; - if (!rx_cb->pend) - continue; - - mutex_lock(&common->rx_lock); - status = ven_rsi_read_pkt(common, rx_cb->rx_buffer, 0); - if (status) { - ven_rsi_dbg(ERR_ZONE, "%s: Failed To read data", - __func__); - mutex_unlock(&common->rx_lock); - break; - } - rx_cb->pend = 0; - mutex_unlock(&common->rx_lock); - - if (adapter->rx_urb_submit(adapter, rx_cb->ep_num)) { - ven_rsi_dbg(ERR_ZONE, - "%s: Failed in urb submission", __func__); - break; + while (true) { + skb = skb_dequeue(&dev->rx_q[idx]); + if (!skb) + break; + + status = ven_rsi_read_pkt(common, skb->data, 0); + if (status) { + ven_rsi_dbg(ERR_ZONE, "%s: Failed To read data", + __func__); + } + dev_kfree_skb(skb); } - /* Update TX buffer status */ - //rsi_usb_check_queue_status(adapter, 0); } rsi_reset_event(&dev->rx_thread.event); } while (1); diff --git a/ubuntu/rsi/rsi_common.h b/ubuntu/rsi/rsi_common.h index afd0e6d..d4385de 100644 --- a/ubuntu/rsi/rsi_common.h +++ b/ubuntu/rsi/rsi_common.h @@ -112,4 +112,7 @@ void init_sdio_intr_status_poll_thread(struct rsi_common *common); #endif void rsi_roc_timeout(unsigned long data); struct ieee80211_vif *rsi_get_vif(struct rsi_hw *adapter, u8 *mac); +#ifdef CONFIG_VEN_RSI_WOW +int rsi_config_wowlan(struct rsi_hw *adapter, struct cfg80211_wowlan *wowlan); +#endif #endif diff --git a/ubuntu/rsi/rsi_main.h b/ubuntu/rsi/rsi_main.h index eb1afbb..3f55e36 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.RC12" +#define DRV_VER "RS9113.NB0.NL.GNU.LNX.1.2" #define ERR_ZONE BIT(0) /* Error Msgs */ #define INFO_ZONE BIT(1) /* Generic Debug Msgs */ @@ -53,15 +53,16 @@ struct rsi_hw; #define FSM_ZONE BIT(7) /* State Machine Msgs */ #define ISR_ZONE BIT(8) /* Interrupt Msgs */ -#define FSM_CARD_NOT_READY 0 -#define FSM_COMMON_DEV_PARAMS_SENT 1 -#define FSM_BOOT_PARAMS_SENT 2 -#define FSM_EEPROM_READ_MAC_ADDR 3 -#define FSM_EEPROM_READ_RF_TYPE 4 -#define FSM_RESET_MAC_SENT 5 -#define FSM_RADIO_CAPS_SENT 6 -#define FSM_BB_RF_PROG_SENT 7 -#define FSM_MAC_INIT_DONE 8 +#define FSM_FW_NOT_LOADED 0 +#define FSM_CARD_NOT_READY 1 +#define FSM_COMMON_DEV_PARAMS_SENT 2 +#define FSM_BOOT_PARAMS_SENT 3 +#define FSM_EEPROM_READ_MAC_ADDR 4 +#define FSM_EEPROM_READ_RF_TYPE 5 +#define FSM_RESET_MAC_SENT 6 +#define FSM_RADIO_CAPS_SENT 7 +#define FSM_BB_RF_PROG_SENT 8 +#define FSM_MAC_INIT_DONE 9 extern u16 ven_rsi_zone_enabled; extern __printf(2, 3) void ven_rsi_dbg(u32 zone, const char *fmt, ...); @@ -179,8 +180,8 @@ struct wmm_qinfo { }; struct transmit_q_stats { - u32 total_tx_pkt_send[NUM_EDCA_QUEUES + 1]; - u32 total_tx_pkt_freed[NUM_EDCA_QUEUES + 1]; + u32 total_tx_pkt_send[NUM_EDCA_QUEUES + 2]; + u32 total_tx_pkt_freed[NUM_EDCA_QUEUES + 2]; }; struct vif_priv { @@ -285,7 +286,6 @@ struct rsi_common { /* Generic */ u8 channel; - u8 *rx_data_pkt; u8 *saved_rx_data_pkt; u8 mac_id; u8 radio_id; diff --git a/ubuntu/rsi/rsi_mgmt.h b/ubuntu/rsi/rsi_mgmt.h index 8965f23..01bcfc5 100644 --- a/ubuntu/rsi/rsi_mgmt.h +++ b/ubuntu/rsi/rsi_mgmt.h @@ -60,11 +60,11 @@ #define WLAN_EEPROM_RFTYPE_ADDR 424 /*WOWLAN RESUME WAKEUP TYPES*/ -#define UNICAST_MAGIC_PKT BIT(0) -#define BROADCAST_MAGICPKT BIT(1) -#define EAPOL_PKT BIT(2) -#define DISCONNECT_PKT BIT(3) -#define HW_BMISS_PKT BIT(4) +#define UNICAST_MAGIC_PKT BIT(0) +#define BROADCAST_MAGICPKT BIT(1) +#define EAPOL_PKT BIT(2) +#define DISCONNECT_PKT BIT(3) +#define HW_BMISS_PKT BIT(4) #define INSERT_SEQ_IN_FW BIT(2) /* Receive Frame Types */ @@ -596,7 +596,7 @@ int rsi_send_wowlan_request(struct rsi_common *common, u16 flags, #endif void rsi_scan_start(struct work_struct *data); #ifdef CONFIG_HW_SCAN_OFFLOAD -int rsi_send_probe_request(struct rsi_common *common, +int rsi_send_probe_request(struct rsi_common *common, struct cfg80211_scan_request *scan_req, u8 n_ssid, u8 channel, u8 scan_type); #endif diff --git a/ubuntu/rsi/rsi_sdio.h b/ubuntu/rsi/rsi_sdio.h index f2ce060..4d9978d 100644 --- a/ubuntu/rsi/rsi_sdio.h +++ b/ubuntu/rsi/rsi_sdio.h @@ -116,6 +116,12 @@ struct receive_info { u32 buf_available_counter; }; +#define RSI_SDIO_MAX_RX_PKTS 32 +struct rsi_sdio_rx_q { + u8 num_rx_pkts; + struct sk_buff_head head; +}; + struct rsi_91x_sdiodev { struct sdio_func *pfunction; struct task_struct *sdio_irq_task; @@ -128,6 +134,8 @@ struct rsi_91x_sdiodev { u32 tx_blk_size; u8 write_fail; u8 buff_status_updated; + struct rsi_sdio_rx_q rx_q; + struct rsi_thread rx_thread; }; void rsi_interrupt_handler(struct rsi_hw *adapter); @@ -157,4 +165,5 @@ 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_check_buffer_status(struct rsi_hw *adapter, u8 q_num); int rsi_read_intr_status_reg(struct rsi_hw *adapter); +void rsi_sdio_rx_thread(struct rsi_common *common); #endif diff --git a/ubuntu/rsi/rsi_usb.h b/ubuntu/rsi/rsi_usb.h index c08ba6c..d2dd097 100644 --- a/ubuntu/rsi/rsi_usb.h +++ b/ubuntu/rsi/rsi_usb.h @@ -54,10 +54,8 @@ struct rx_usb_ctrl_block { u8 *data; struct urb *rx_urb; - u8 *rx_buffer; - u8 *orig_rx_buffer; + struct sk_buff *rx_skb; u8 ep_num; - u8 pend; }; struct receive_info { @@ -87,6 +85,7 @@ struct rsi_91x_usbdev { u8 bulkout_endpoint_addr[MAX_BULK_EP]; u32 tx_blk_size; u8 write_fail; + struct sk_buff_head rx_q[MAX_RX_URBS]; }; static inline int rsi_usb_event_timeout(struct rsi_hw *adapter) @@ -111,4 +110,5 @@ int rsi_usb_load_data_master_write(struct rsi_hw *adapter, u32 base_address, u16 block_size, u8 *ta_firmware); int rsi_usb_check_queue_status(struct rsi_hw *adapter, u8 q_num); +int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num); #endif