summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_mac80211.c19
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_mgmt.c3
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_ps.c17
-rw-r--r--drivers/net/wireless/rsi/rsi_main.h1
-rw-r--r--drivers/net/wireless/rsi/rsi_mgmt.h6
5 files changed, 46 insertions, 0 deletions
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index 16a0fd0f519a..6b833c424b18 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -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);
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index f76b34679df8..e5fe443ddfb6 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -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);
diff --git a/drivers/net/wireless/rsi/rsi_91x_ps.c b/drivers/net/wireless/rsi/rsi_91x_ps.c
index 25e8f853837b..48c79f035c59 100644
--- a/drivers/net/wireless/rsi/rsi_91x_ps.c
+++ b/drivers/net/wireless/rsi/rsi_91x_ps.c
@@ -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;
}
+
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index 9aada0b73108..d2cc47e98639 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -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;
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h b/drivers/net/wireless/rsi/rsi_mgmt.h
index c5d114d67c83..b22103fd6c81 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -181,6 +181,12 @@
#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