summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/wl12xx/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/wl12xx/main.c')
-rw-r--r--drivers/net/wireless/wl12xx/main.c143
1 files changed, 69 insertions, 74 deletions
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 254b7daccee1..61dea73f5fdc 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -256,6 +256,7 @@ static struct conf_drv_settings default_conf = {
.bet_enable = CONF_BET_MODE_ENABLE,
.bet_max_consecutive = 10,
.psm_entry_retries = 5,
+ .psm_exit_retries = 255,
.psm_entry_nullfunc_retries = 3,
.psm_entry_hangover_period = 1,
.keep_alive_interval = 55000,
@@ -297,6 +298,16 @@ static struct conf_drv_settings default_conf = {
.tx_ba_win_size = 64,
.inactivity_timeout = 10000,
},
+ .mem = {
+ .num_stations = 1,
+ .ssid_profiles = 1,
+ .rx_block_num = 70,
+ .tx_min_block_num = 40,
+ .dynamic_memory = 0,
+ .min_req_tx_blocks = 104,
+ .min_req_rx_blocks = 22,
+ .tx_min = 27,
+ }
};
static void __wl1271_op_remove_interface(struct wl1271 *wl);
@@ -523,13 +534,19 @@ static int wl1271_plt_init(struct wl1271 *wl)
}
static void wl1271_fw_status(struct wl1271 *wl,
- struct wl1271_fw_status *status)
+ struct wl1271_fw_full_status *full_status)
{
+ struct wl1271_fw_common_status *status = &full_status->common;
struct timespec ts;
u32 total = 0;
int i;
- wl1271_raw_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false);
+ if (wl->bss_type == BSS_TYPE_AP_BSS)
+ wl1271_raw_read(wl, FW_STATUS_ADDR, status,
+ sizeof(struct wl1271_fw_ap_status), false);
+ else
+ wl1271_raw_read(wl, FW_STATUS_ADDR, status,
+ sizeof(struct wl1271_fw_sta_status), false);
wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
"drv_rx_counter = %d, tx_results_counter = %d)",
@@ -588,7 +605,7 @@ static void wl1271_irq_work(struct work_struct *work)
loopcount--;
wl1271_fw_status(wl, wl->fw_status);
- intr = le32_to_cpu(wl->fw_status->intr);
+ intr = le32_to_cpu(wl->fw_status->common.intr);
if (!intr) {
wl1271_debug(DEBUG_IRQ, "Zero interrupt received.");
spin_lock_irqsave(&wl->wl_lock, flags);
@@ -610,7 +627,7 @@ static void wl1271_irq_work(struct work_struct *work)
wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
/* check for tx results */
- if (wl->fw_status->tx_results_counter !=
+ if (wl->fw_status->common.tx_results_counter !=
(wl->tx_results_count & 0xff))
wl1271_tx_complete(wl);
@@ -624,7 +641,7 @@ static void wl1271_irq_work(struct work_struct *work)
wl1271_tx_work_locked(wl);
}
- wl1271_rx(wl, wl->fw_status);
+ wl1271_rx(wl, &wl->fw_status->common);
}
if (intr & WL1271_ACX_INTR_EVENT_A) {
@@ -961,39 +978,10 @@ int wl1271_plt_stop(struct wl1271 *wl)
static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct wl1271 *wl = hw->priv;
- struct ieee80211_conf *conf = &hw->conf;
- struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
- struct ieee80211_sta *sta = txinfo->control.sta;
unsigned long flags;
int q;
- /*
- * peek into the rates configured in the STA entry.
- * The rates set after connection stage, The first block only BG sets:
- * the compare is for bit 0-16 of sta_rate_set. The second block add
- * HT rates in case of HT supported.
- */
spin_lock_irqsave(&wl->wl_lock, flags);
- if (sta &&
- (sta->supp_rates[conf->channel->band] !=
- (wl->sta_rate_set & HW_BG_RATES_MASK)) &&
- wl->bss_type != BSS_TYPE_AP_BSS) {
- wl->sta_rate_set = sta->supp_rates[conf->channel->band];
- set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
- }
-
-#ifdef CONFIG_WL12XX_HT
- if (sta &&
- sta->ht_cap.ht_supported &&
- ((wl->sta_rate_set >> HW_HT_RATES_OFFSET) !=
- sta->ht_cap.mcs.rx_mask[0])) {
- /* Clean MCS bits before setting them */
- wl->sta_rate_set &= HW_BG_RATES_MASK;
- wl->sta_rate_set |=
- (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET);
- set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
- }
-#endif
wl->tx_queue_count++;
spin_unlock_irqrestore(&wl->wl_lock, flags);
@@ -1228,7 +1216,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
wl->time_offset = 0;
wl->session_counter = 0;
wl->rate_set = CONF_TX_RATE_MASK_BASIC;
- wl->sta_rate_set = 0;
wl->flags = 0;
wl->vif = NULL;
wl->filters = 0;
@@ -1415,7 +1402,6 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, bool idle)
goto out;
}
wl->rate_set = wl1271_tx_min_rate_get(wl);
- wl->sta_rate_set = 0;
ret = wl1271_acx_sta_rate_policies(wl);
if (ret < 0)
goto out;
@@ -2229,6 +2215,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
{
bool do_join = false, set_assoc = false;
bool is_ibss = (wl->bss_type == BSS_TYPE_IBSS);
+ u32 sta_rate_set = 0;
int ret;
struct ieee80211_sta *sta;
@@ -2294,6 +2281,49 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
}
}
+ rcu_read_lock();
+ sta = ieee80211_find_sta(vif, bss_conf->bssid);
+ if (sta) {
+ /* save the supp_rates of the ap */
+ sta_rate_set = sta->supp_rates[wl->hw->conf.channel->band];
+ if (sta->ht_cap.ht_supported)
+ sta_rate_set |=
+ (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET);
+
+ /* handle new association with HT and HT information change */
+ if ((changed & BSS_CHANGED_HT) &&
+ (bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
+ ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap,
+ true);
+ if (ret < 0) {
+ wl1271_warning("Set ht cap true failed %d",
+ ret);
+ rcu_read_unlock();
+ goto out;
+ }
+ ret = wl1271_acx_set_ht_information(wl,
+ bss_conf->ht_operation_mode);
+ if (ret < 0) {
+ wl1271_warning("Set ht information failed %d",
+ ret);
+ rcu_read_unlock();
+ goto out;
+ }
+ }
+ /* handle new association without HT and disassociation */
+ else if (changed & BSS_CHANGED_ASSOC) {
+ ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap,
+ false);
+ if (ret < 0) {
+ wl1271_warning("Set ht cap false failed %d",
+ ret);
+ rcu_read_unlock();
+ goto out;
+ }
+ }
+ }
+ rcu_read_unlock();
+
if ((changed & BSS_CHANGED_ASSOC)) {
if (bss_conf->assoc) {
u32 rates;
@@ -2311,6 +2341,9 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl,
rates);
wl->basic_rate = wl1271_tx_min_rate_get(wl);
+ if (sta_rate_set)
+ wl->rate_set = wl1271_tx_enabled_rates_get(wl,
+ sta_rate_set);
ret = wl1271_acx_sta_rate_policies(wl);
if (ret < 0)
goto out;
@@ -2389,43 +2422,6 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
if (ret < 0)
goto out;
- rcu_read_lock();
- sta = ieee80211_find_sta(vif, bss_conf->bssid);
- if (sta) {
- /* handle new association with HT and HT information change */
- if ((changed & BSS_CHANGED_HT) &&
- (bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
- ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap,
- true);
- if (ret < 0) {
- wl1271_warning("Set ht cap true failed %d",
- ret);
- rcu_read_unlock();
- goto out;
- }
- ret = wl1271_acx_set_ht_information(wl,
- bss_conf->ht_operation_mode);
- if (ret < 0) {
- wl1271_warning("Set ht information failed %d",
- ret);
- rcu_read_unlock();
- goto out;
- }
- }
- /* handle new association without HT and disassociation */
- else if (changed & BSS_CHANGED_ASSOC) {
- ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap,
- false);
- if (ret < 0) {
- wl1271_warning("Set ht cap false failed %d",
- ret);
- rcu_read_unlock();
- goto out;
- }
- }
- }
- rcu_read_unlock();
-
if (changed & BSS_CHANGED_ARP_FILTER) {
__be32 addr = bss_conf->arp_addr_list[0];
WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);
@@ -3313,7 +3309,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC;
wl->basic_rate = CONF_TX_RATE_MASK_BASIC;
wl->rate_set = CONF_TX_RATE_MASK_BASIC;
- wl->sta_rate_set = 0;
wl->band = IEEE80211_BAND_2GHZ;
wl->vif = NULL;
wl->flags = 0;