|
@@ -770,13 +770,14 @@ static int wl1271_plt_init(struct wl1271 *wl)
|
|
|
|
|
|
static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, u8 hlid, u8 tx_pkts)
|
|
|
{
|
|
|
- bool fw_ps;
|
|
|
+ bool fw_ps, single_sta;
|
|
|
|
|
|
/* only regulate station links */
|
|
|
if (hlid < WL1271_AP_STA_HLID_START)
|
|
|
return;
|
|
|
|
|
|
fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
|
|
|
+ single_sta = (wl->active_sta_count == 1);
|
|
|
|
|
|
/*
|
|
|
* Wake up from high level PS if the STA is asleep with too little
|
|
@@ -785,8 +786,12 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, u8 hlid, u8 tx_pkts)
|
|
|
if (!fw_ps || tx_pkts < WL1271_PS_STA_MAX_PACKETS)
|
|
|
wl1271_ps_link_end(wl, hlid);
|
|
|
|
|
|
- /* Start high-level PS if the STA is asleep with enough blocks in FW */
|
|
|
- else if (fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
|
|
|
+ /*
|
|
|
+ * Start high-level PS if the STA is asleep with enough blocks in FW.
|
|
|
+ * Make an exception if this is the only connected station. In this
|
|
|
+ * case FW-memory congestion is not a problem.
|
|
|
+ */
|
|
|
+ else if (!single_sta && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
|
|
|
wl1271_ps_link_start(wl, hlid, true);
|
|
|
}
|
|
|
|
|
@@ -2093,6 +2098,7 @@ deinit:
|
|
|
memset(wl->roles_map, 0, sizeof(wl->roles_map));
|
|
|
memset(wl->links_map, 0, sizeof(wl->links_map));
|
|
|
memset(wl->roc_map, 0, sizeof(wl->roc_map));
|
|
|
+ wl->active_sta_count = 0;
|
|
|
|
|
|
/* The system link is always allocated */
|
|
|
__set_bit(WL12XX_SYSTEM_HLID, wl->links_map);
|
|
@@ -3747,6 +3753,7 @@ static int wl1271_allocate_sta(struct wl1271 *wl,
|
|
|
wl_sta->hlid = WL1271_AP_STA_HLID_START + id;
|
|
|
*hlid = wl_sta->hlid;
|
|
|
memcpy(wl->links[wl_sta->hlid].addr, sta->addr, ETH_ALEN);
|
|
|
+ wl->active_sta_count++;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -3763,6 +3770,7 @@ static void wl1271_free_sta(struct wl1271 *wl, u8 hlid)
|
|
|
wl1271_tx_reset_link_queues(wl, hlid);
|
|
|
__clear_bit(hlid, &wl->ap_ps_map);
|
|
|
__clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
|
|
|
+ wl->active_sta_count--;
|
|
|
}
|
|
|
|
|
|
static int wl1271_op_sta_add(struct ieee80211_hw *hw,
|
|
@@ -4640,6 +4648,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
|
|
|
wl->session_counter = 0;
|
|
|
wl->ap_bcast_hlid = WL12XX_INVALID_LINK_ID;
|
|
|
wl->ap_global_hlid = WL12XX_INVALID_LINK_ID;
|
|
|
+ wl->active_sta_count = 0;
|
|
|
setup_timer(&wl->rx_streaming_timer, wl1271_rx_streaming_timer,
|
|
|
(unsigned long) wl);
|
|
|
wl->fwlog_size = 0;
|