From 70559a06657c55aeefe2f06619d3592a08cc68ac Mon Sep 17 00:00:00 2001 From: Shahar Levi Date: Sun, 22 May 2011 16:10:22 +0300 Subject: wl12xx: Stop BA session event from device Adding new event that close RX BA session in case of periodic BT activity limiting WLAN activity. Signed-off-by: Shahar Levi Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/event.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers/net/wireless/wl12xx/event.c') diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index c3c554cd6580..94bbd00ec31b 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c @@ -168,6 +168,21 @@ static void wl1271_event_rssi_trigger(struct wl1271 *wl, wl->last_rssi_event = event; } +static void wl1271_stop_ba_event(struct wl1271 *wl, u8 ba_allowed) +{ + /* Convert the value to bool */ + wl->ba_allowed = !!ba_allowed; + + /* + * Return in case: + * there are not BA open or the event indication is to allowed BA + */ + if ((!wl->ba_rx_bitmap) || (wl->ba_allowed)) + return; + + ieee80211_stop_rx_ba_session(wl->vif, wl->ba_rx_bitmap, wl->bssid); +} + static void wl1271_event_mbox_dump(struct event_mailbox *mbox) { wl1271_debug(DEBUG_EVENT, "MBOX DUMP:"); @@ -252,6 +267,14 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) wl1271_event_rssi_trigger(wl, mbox); } + if ((vector & BA_SESSION_RX_CONSTRAINT_EVENT_ID) && !is_ap) { + wl1271_debug(DEBUG_EVENT, "BA_SESSION_RX_CONSTRAINT_EVENT_ID. " + "ba_allowed = 0x%x", mbox->ba_allowed); + + if (wl->vif) + wl1271_stop_ba_event(wl, mbox->ba_allowed); + } + if ((vector & DUMMY_PACKET_EVENT_ID) && !is_ap) { wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID"); if (wl->vif) -- cgit v1.2.3 From 77ddaa108f727b5ef3be004b952d2c3d3ffc48e5 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 15 May 2011 11:10:29 +0300 Subject: wl12xx: add automatic rx streaming triggers When rx_streaming.interval is non-zero, use automatic rx streaming. Enable rx streaming on the each rx/tx packet, and disable it rx_streaming.duration msecs later. When rx_streaming.always=0 (default), rx streaming is enabled only when there is a coex operation. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/event.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'drivers/net/wireless/wl12xx/event.c') diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index 94bbd00ec31b..0c60ffea414d 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c @@ -183,6 +183,21 @@ static void wl1271_stop_ba_event(struct wl1271 *wl, u8 ba_allowed) ieee80211_stop_rx_ba_session(wl->vif, wl->ba_rx_bitmap, wl->bssid); } +static void wl12xx_event_soft_gemini_sense(struct wl1271 *wl, + u8 enable) +{ + if (enable) { + /* disable dynamic PS when requested by the firmware */ + ieee80211_disable_dyn_ps(wl->vif); + set_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags); + } else { + ieee80211_enable_dyn_ps(wl->vif); + clear_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags); + wl1271_recalc_rx_streaming(wl); + } + +} + static void wl1271_event_mbox_dump(struct event_mailbox *mbox) { wl1271_debug(DEBUG_EVENT, "MBOX DUMP:"); @@ -226,14 +241,10 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) } } - /* disable dynamic PS when requested by the firmware */ if (vector & SOFT_GEMINI_SENSE_EVENT_ID && - wl->bss_type == BSS_TYPE_STA_BSS) { - if (mbox->soft_gemini_sense_info) - ieee80211_disable_dyn_ps(wl->vif); - else - ieee80211_enable_dyn_ps(wl->vif); - } + wl->bss_type == BSS_TYPE_STA_BSS) + wl12xx_event_soft_gemini_sense(wl, + mbox->soft_gemini_sense_info); /* * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon -- cgit v1.2.3 From 0e44eb209343663ad7041ebf9f5d4c393bd89ae9 Mon Sep 17 00:00:00 2001 From: Shahar Levi Date: Mon, 16 May 2011 15:35:30 +0300 Subject: wl12xx: Enable beacon early termination in 2.4GHz band only Beacon early termination doesn't help much in the 5GHz band and masks channel switch IE Beacons. Thus, change the code to use BET only in 2.4GHz. [Reworded the commit log slightly -- Luca.] Signed-off-by: Shahar Levi Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/event.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers/net/wireless/wl12xx/event.c') diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index 0c60ffea414d..a16dee58a664 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c @@ -133,10 +133,13 @@ static int wl1271_event_ps_report(struct wl1271 *wl, if (ret < 0) break; - /* enable beacon early termination */ - ret = wl1271_acx_bet_enable(wl, true); - if (ret < 0) - break; + /* + * BET has only a minor effect in 5GHz and masks + * channel switch IEs, so we only enable BET on 2.4GHz + */ + if (wl->band == IEEE80211_BAND_2GHZ) + /* enable beacon early termination */ + ret = wl1271_acx_bet_enable(wl, true); if (wl->ps_compl) { complete(wl->ps_compl); -- cgit v1.2.3 From 3618f30f307841dba19f22d9c602a5c59cab30c7 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 26 Jun 2011 10:36:03 +0300 Subject: wl12xx: AP mode - support FW TX inactivity triggers In AP mode we register for the MAX_TX_RETRY and INACTIVE_STA events. Both are reported to the upper layers as a TX failure in the offending stations. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/event.c | 42 +++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'drivers/net/wireless/wl12xx/event.c') diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index a16dee58a664..304aaa2ee011 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c @@ -214,6 +214,8 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) u32 vector; bool beacon_loss = false; bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); + bool disconnect_sta = false; + unsigned long sta_bitmap = 0; wl1271_event_mbox_dump(mbox); @@ -295,6 +297,46 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) wl1271_tx_dummy_packet(wl); } + /* + * "TX retries exceeded" has a different meaning according to mode. + * In AP mode the offending station is disconnected. + */ + if ((vector & MAX_TX_RETRY_EVENT_ID) && is_ap) { + wl1271_debug(DEBUG_EVENT, "MAX_TX_RETRY_EVENT_ID"); + sta_bitmap |= le16_to_cpu(mbox->sta_tx_retry_exceeded); + disconnect_sta = true; + } + + if ((vector & INACTIVE_STA_EVENT_ID) && is_ap) { + wl1271_debug(DEBUG_EVENT, "INACTIVE_STA_EVENT_ID"); + sta_bitmap |= le16_to_cpu(mbox->sta_aging_status); + disconnect_sta = true; + } + + if (is_ap && disconnect_sta) { + u32 num_packets = wl->conf.tx.max_tx_retries; + struct ieee80211_sta *sta; + const u8 *addr; + int h; + + for (h = find_first_bit(&sta_bitmap, AP_MAX_LINKS); + h < AP_MAX_LINKS; + h = find_next_bit(&sta_bitmap, AP_MAX_LINKS, h+1)) { + if (!wl1271_is_active_sta(wl, h)) + continue; + + addr = wl->links[h].addr; + + rcu_read_lock(); + sta = ieee80211_find_sta(wl->vif, addr); + if (sta) { + wl1271_debug(DEBUG_EVENT, "remove sta %d", h); + ieee80211_report_low_ack(sta, num_packets); + } + rcu_read_unlock(); + } + } + if (wl->vif && beacon_loss) ieee80211_connection_loss(wl->vif); -- cgit v1.2.3