rsi: add support for U-APSD power save
authorKarun Eagalapati <karun256@gmail.com>
Thu, 3 Aug 2017 14:29:00 +0000 (19:59 +0530)
committerKalle Valo <kvalo@codeaurora.org>
Tue, 8 Aug 2017 11:46:02 +0000 (14:46 +0300)
This patch adds support for U-APSD power save. Configuration
frame is downloaded to firmware with default settings and
support is advertised to mac80211

Signed-off-by: Karun Eagalapati <karun256@gmail.com>
Signed-off-by: Amitkumar Karwar <amit.karwar@redpinesignals.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/rsi/rsi_91x_mac80211.c
drivers/net/wireless/rsi/rsi_91x_mgmt.c
drivers/net/wireless/rsi/rsi_91x_ps.c
drivers/net/wireless/rsi/rsi_main.h
drivers/net/wireless/rsi/rsi_mgmt.h

index 16a0fd0f519ac2488fa4a321c72e4516251d5cfc..6b833c424b182731e01102b30f7b5a10f99a7007 100644 (file)
@@ -327,6 +327,7 @@ static int rsi_mac80211_add_interface(struct ieee80211_hw *hw,
        struct rsi_common *common = adapter->priv;
        int ret = -EOPNOTSUPP;
 
+       vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
        mutex_lock(&common->mutex);
        switch (vif->type) {
        case NL80211_IFTYPE_STATION:
@@ -560,6 +561,16 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
                                      bss_conf->aid);
                adapter->ps_info.dtim_interval_duration = bss->dtim_period;
                adapter->ps_info.listen_interval = conf->listen_interval;
+
+       /* If U-APSD is updated, send ps parameters to firmware */
+       if (bss->assoc) {
+               if (common->uapsd_bitmap) {
+                       rsi_dbg(INFO_ZONE, "Configuring UAPSD\n");
+                       rsi_conf_uapsd(adapter);
+               }
+       } else {
+               common->uapsd_bitmap = 0;
+       }
        }
 
        if (changed & BSS_CHANGED_CQM) {
@@ -641,6 +652,12 @@ static int rsi_mac80211_conf_tx(struct ieee80211_hw *hw,
        memcpy(&common->edca_params[idx],
               params,
               sizeof(struct ieee80211_tx_queue_params));
+
+       if (params->uapsd)
+               common->uapsd_bitmap |= idx;
+       else
+               common->uapsd_bitmap &= (~idx);
+
        mutex_unlock(&common->mutex);
 
        return 0;
@@ -1311,6 +1328,8 @@ int rsi_mac80211_attach(struct rsi_common *common)
 
        hw->max_rates = 1;
        hw->max_rate_tries = MAX_RETRIES;
+       hw->uapsd_queues = RSI_IEEE80211_UAPSD_QUEUES;
+       hw->uapsd_max_sp_len = IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL;
 
        hw->max_tx_aggregation_subframes = 6;
        rsi_register_rates_channels(adapter, NL80211_BAND_2GHZ);
index f76b34679df83309fa51ef878870449b434e9e13..e5fe443ddfb686a692c599993b5b912d268d07a5 100644 (file)
@@ -1425,6 +1425,9 @@ int rsi_send_ps_request(struct rsi_hw *adapter, bool enable)
                ps->desc.desc_dword0.len_qno |= cpu_to_le16(RSI_PS_DISABLE_IND);
                ps->desc.desc_dword3.token = cpu_to_le16(RSI_WAKEUP_REQUEST);
        }
+
+       ps->ps_uapsd_acs = common->uapsd_bitmap;
+
        ps->ps_sleep.sleep_type = ps_info->sleep_type;
        ps->ps_sleep.num_bcns_per_lis_int =
                cpu_to_le16(ps_info->num_bcns_per_lis_int);
index 25e8f853837b9a70f356a84e6b1ff4fe3a1bbfe6..48c79f035c593c85faa0c1d1b6bf1acd7c451e0c 100644 (file)
@@ -105,6 +105,22 @@ void rsi_disable_ps(struct rsi_hw *adapter)
        rsi_modify_ps_state(adapter, PS_DISABLE_REQ_SENT);
 }
 
+void rsi_conf_uapsd(struct rsi_hw *adapter)
+{
+       int ret;
+
+       if (adapter->ps_state != PS_ENABLED)
+               return;
+
+       ret = rsi_send_ps_request(adapter, false);
+       if (!ret)
+               ret = rsi_send_ps_request(adapter, true);
+       if (ret)
+               rsi_dbg(ERR_ZONE,
+                       "%s: Failed to send PS request to device\n",
+                       __func__);
+}
+
 int rsi_handle_ps_confirm(struct rsi_hw *adapter, u8 *msg)
 {
        u16 cfm_type = get_unaligned_le16(msg + PS_CONFIRM_INDEX);
@@ -127,3 +143,4 @@ int rsi_handle_ps_confirm(struct rsi_hw *adapter, u8 *msg)
 
        return 0;
 }
+
index 9aada0b7310888febcdb21cbddafda6f117fa00a..d2cc47e98639fc685cda93043c0da36d288a883f 100644 (file)
@@ -243,6 +243,7 @@ struct rsi_common {
        u16 oper_mode;
        u8 lp_ps_handshake_mode;
        u8 ulp_ps_handshake_mode;
+       u8 uapsd_bitmap;
        u8 rf_power_val;
        u8 wlan_rf_power_mode;
        u8 obm_ant_sel_val;
index c5d114d67c83afca526e23591c0d85eba2909b8c..b22103fd6c810baf4e77082bc4cc9f2ed9435ba3 100644 (file)
 #define RSI_SLEEP_REQUEST              1
 #define RSI_WAKEUP_REQUEST             2
 
+#define RSI_IEEE80211_UAPSD_QUEUES \
+       (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO | \
+        IEEE80211_WMM_IE_STA_QOSINFO_AC_VI | \
+        IEEE80211_WMM_IE_STA_QOSINFO_AC_BE | \
+        IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
+
 enum opmode {
        STA_OPMODE = 1,
        AP_OPMODE = 2