if (vector & BSS_LOSE_EVENT_ID) {
wl1251_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
+ wl1251_no_ps_event(wl);
wl->bss_lost = 1;
ieee80211_queue_delayed_work(wl->hw, &wl->ps_work, 0);
}
if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID) {
wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT");
+ wl1251_no_ps_event(wl);
/* indicate to the stack, that beacons have been lost */
if (wl->vif && wl->vif->type == NL80211_IFTYPE_STATION)
if (ret < 0)
wl1251_warning("join timeout");
+ wl1251_no_ps_event(wl);
+
out:
return ret;
}
if (need_ps) {
wait = 0;
+ diff = jiffies - wl->last_no_ps_jiffies[1];
+ if (diff < msecs_to_jiffies(1000))
+ wait = msecs_to_jiffies(1000) - diff + 1;
+
+ diff = jiffies - wl->last_no_ps_jiffies[0];
+ if (diff < msecs_to_jiffies(3000))
+ wait += msecs_to_jiffies(1000);
+
diff = jiffies - wl->last_io_jiffies;
if (diff < msecs_to_jiffies(150)) {
//wl1251_info("ps: postponed psm, j %ld", diff);
- wait = msecs_to_jiffies(150) - diff + 1;
+ if (wait < msecs_to_jiffies(150) - diff + 1)
+ wait = msecs_to_jiffies(150) - diff + 1;
}
for (i = 0; i < ARRAY_SIZE(wl->tx_frames); i++) {
wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
IEEE80211_HW_BEACON_FILTER |
IEEE80211_HW_SUPPORTS_UAPSD |
IEEE80211_HW_SUPPORTS_CQM_RSSI;
/* PS hacks.. */
unsigned long ps_change_jiffies;
unsigned long last_io_jiffies;
+ /* when we had PS "unfriendly" event like sync loss */
+ unsigned long last_no_ps_jiffies[2];
struct delayed_work ps_work;
bool bss_lost;
bool ps_transitioning;
void wl1251_disable_interrupts(struct wl1251 *wl);
irqreturn_t wl1251_irq(int irq, void *cookie);
+static inline void wl1251_no_ps_event(struct wl1251 *wl)
+{
+ wl->last_no_ps_jiffies[0] = wl->last_no_ps_jiffies[1];
+ wl->last_no_ps_jiffies[1] = jiffies;
+}
+
#define DEFAULT_HW_GEN_MODULATION_TYPE CCK_LONG /* Long Preamble */
#define DEFAULT_HW_GEN_TX_RATE RATE_2MBPS
#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */