diff options
Diffstat (limited to 'drivers/net/wireless/rsi/rsi_91x_mac80211.c')
-rw-r--r-- | drivers/net/wireless/rsi/rsi_91x_mac80211.c | 75 |
1 files changed, 52 insertions, 23 deletions
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c index 32f5cb46fd4f..2ca7464b7fa3 100644 --- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c +++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c @@ -245,6 +245,7 @@ void rsi_mac80211_detach(struct rsi_hw *adapter) ieee80211_stop_queues(hw); ieee80211_unregister_hw(hw); ieee80211_free_hw(hw); + adapter->hw = NULL; } for (band = 0; band < NUM_NL80211_BANDS; band++) { @@ -614,7 +615,7 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw, /* Power save parameters */ if (changed & IEEE80211_CONF_CHANGE_PS) { - struct ieee80211_vif *vif; + struct ieee80211_vif *vif, *sta_vif = NULL; unsigned long flags; int i, set_ps = 1; @@ -628,13 +629,17 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw, set_ps = 0; break; } + if ((vif->type == NL80211_IFTYPE_STATION || + vif->type == NL80211_IFTYPE_P2P_CLIENT) && + (!sta_vif || vif->bss_conf.assoc)) + sta_vif = vif; } - if (set_ps) { + if (set_ps && sta_vif) { spin_lock_irqsave(&adapter->ps_lock, flags); if (conf->flags & IEEE80211_CONF_PS) - rsi_enable_ps(adapter, vif); + rsi_enable_ps(adapter, sta_vif); else - rsi_disable_ps(adapter, vif); + rsi_disable_ps(adapter, sta_vif); spin_unlock_irqrestore(&adapter->ps_lock, flags); } } @@ -737,7 +742,8 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw, bss_conf->bssid, bss_conf->qos, bss_conf->aid, - NULL, 0, vif); + NULL, 0, + bss_conf->assoc_capability, vif); adapter->ps_info.dtim_interval_duration = bss->dtim_period; adapter->ps_info.listen_interval = conf->listen_interval; @@ -906,14 +912,25 @@ static int rsi_hal_key_config(struct ieee80211_hw *hw, } } - return rsi_hal_load_key(adapter->priv, - key->key, - key->keylen, - key_type, - key->keyidx, - key->cipher, - sta_id, - vif); + status = rsi_hal_load_key(adapter->priv, + key->key, + key->keylen, + key_type, + key->keyidx, + key->cipher, + sta_id, + vif); + if (status) + return status; + + if (vif->type == NL80211_IFTYPE_STATION && key->key && + (key->cipher == WLAN_CIPHER_SUITE_WEP104 || + key->cipher == WLAN_CIPHER_SUITE_WEP40)) { + if (!rsi_send_block_unblock_frame(adapter->priv, false)) + adapter->priv->hw_data_qs_blocked = false; + } + + return 0; } /** @@ -1086,7 +1103,7 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw, break; default: - rsi_dbg(ERR_ZONE, "%s: Uknown AMPDU action\n", __func__); + rsi_dbg(ERR_ZONE, "%s: Unknown AMPDU action\n", __func__); break; } @@ -1391,7 +1408,7 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw, rsi_dbg(INFO_ZONE, "Indicate bss status to device\n"); rsi_inform_bss_status(common, RSI_OPMODE_AP, 1, sta->addr, sta->wme, sta->aid, - sta, sta_idx, vif); + sta, sta_idx, 0, vif); if (common->key) { struct ieee80211_key_conf *key = common->key; @@ -1469,7 +1486,7 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw, rsi_inform_bss_status(common, RSI_OPMODE_AP, 0, sta->addr, sta->wme, sta->aid, sta, sta_idx, - vif); + 0, vif); rsta->sta = NULL; rsta->sta_id = -1; for (cnt = 0; cnt < IEEE80211_NUM_TIDS; cnt++) @@ -1788,15 +1805,21 @@ 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; - struct ieee80211_bss_conf *bss = &adapter->vifs[0]->bss_conf; + struct ieee80211_bss_conf *bss = NULL; rsi_dbg(INFO_ZONE, "Config WoWLAN to device\n"); + if (!adapter->vifs[0]) + return -EINVAL; + + bss = &adapter->vifs[0]->bss_conf; + if (WARN_ON(!wowlan)) { rsi_dbg(ERR_ZONE, "WoW triggers not enabled\n"); return -EINVAL; } + common->wow_flags |= RSI_WOW_ENABLED; triggers = rsi_wow_map_triggers(common, wowlan); if (!triggers) { rsi_dbg(ERR_ZONE, "%s:No valid WoW triggers\n", __func__); @@ -1819,7 +1842,6 @@ int rsi_config_wowlan(struct rsi_hw *adapter, struct cfg80211_wowlan *wowlan) rx_filter_word = (ALLOW_DATA_ASSOC_PEER | DISALLOW_BEACONS); rsi_send_rx_filter_frame(common, rx_filter_word); - common->wow_flags |= RSI_WOW_ENABLED; return 0; } @@ -1939,9 +1961,8 @@ int rsi_mac80211_attach(struct rsi_common *common) 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); - rsi_register_rates_channels(adapter, NL80211_BAND_5GHZ); + hw->max_tx_aggregation_subframes = RSI_MAX_TX_AGGR_FRMS; + hw->max_rx_aggregation_subframes = RSI_MAX_RX_AGGR_FRMS; hw->rate_control_algorithm = "AARF"; SET_IEEE80211_PERM_ADDR(hw, common->mac_addr); @@ -1962,10 +1983,15 @@ int rsi_mac80211_attach(struct rsi_common *common) wiphy->available_antennas_rx = 1; wiphy->available_antennas_tx = 1; + + rsi_register_rates_channels(adapter, NL80211_BAND_2GHZ); wiphy->bands[NL80211_BAND_2GHZ] = &adapter->sbands[NL80211_BAND_2GHZ]; - wiphy->bands[NL80211_BAND_5GHZ] = - &adapter->sbands[NL80211_BAND_5GHZ]; + if (common->num_supp_bands > 1) { + rsi_register_rates_channels(adapter, NL80211_BAND_5GHZ); + wiphy->bands[NL80211_BAND_5GHZ] = + &adapter->sbands[NL80211_BAND_5GHZ]; + } /* AP Parameters */ wiphy->max_ap_assoc_sta = rsi_max_ap_stas[common->oper_mode - 1]; @@ -1991,6 +2017,9 @@ int rsi_mac80211_attach(struct rsi_common *common) wiphy->iface_combinations = rsi_iface_combinations; wiphy->n_iface_combinations = ARRAY_SIZE(rsi_iface_combinations); + if (common->coex_mode > 1) + wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; + status = ieee80211_register_hw(hw); if (status) return status; |