[ath9k-devel] [RFC] ath9k: use more than one slot per bss for multicast in staggered mode

2014-03-10 Thread Michael Braun
Before, ath9k divided time in ATH_BCBUF many equally sized slots.
Each bss then was assigned to a single slot, leaving some or more slots empty.
The beacons of a bss were sent at the beginning of the slot for this bss,
and then the buffered multicast packets might be sent out.

As multicast packets are sent a lowest bitrate, wireless throughput
of multicast packets is very limited, and thus the time available
is crucial to avoid buffer overflow, which I frequently observed.

This patch changes the behaviour of ath9k in two ways:
 1. the time available when processing a slot is increased
to cover all subsequent unoccupied slots as well.
This size is tracked in the variable named slotwidth.
 2. during each slot, buffered packets from *all* bss are
sent out in a round-robin fashing, skipping those
bss where stations are currently not listing.
That could be either due to
  - last dtim did not containt the relevant flag or
  - a multicast packet not containing the more data
flag was sent out.
The state is tracked in multicastWakeup, which is
true iff the stations in this bss should already
be woken up.

I currently don't know whether a non-buffered multicast packet
can slip between buffered packets (or between dtim notification
and the first buffered packet), so that an STA receives a
multicast packet without MOREDATA set while there a still
buffered packets to be received and just short before being
delivered on-air.

Signed-off-by: Michael Braun michael-...@fami-braun.de
Cc: projekt-w...@fem.tu-ilmenau.de
Cc: ath9k-devel@lists.ath9k.org
Cc: linux-wirel...@vger.kernel.org
---
 drivers/net/wireless/ath/ath9k/ath9k.h  |  3 +-
 drivers/net/wireless/ath/ath9k/beacon.c | 39 --
 drivers/net/wireless/ath/ath9k/xmit.c   | 71 +++--
 3 files changed, 87 insertions(+), 26 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h 
b/drivers/net/wireless/ath/ath9k/ath9k.h
index f995c374a9b4..8af688225392 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -345,7 +345,7 @@ void ath_update_max_aggr_framelen(struct ath_softc *sc, int 
queue, int txop);
 int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
 struct ath_tx_control *txctl);
 void ath_tx_cabq(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-struct sk_buff *skb);
+const int slotwidth);
 void ath_tx_tasklet(struct ath_softc *sc);
 void ath_tx_edma_tasklet(struct ath_softc *sc);
 int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
@@ -369,6 +369,7 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
 struct ath_vif {
struct ath_node mcast_node;
int av_bslot;
+   bool multicastWakeup; /* all stations in this bss should be listening */
bool primary_sta_vif;
__le64 tsf_adjust; /* TSF adjustment for staggered beacons */
struct ath_buf *av_bcbuf;
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c 
b/drivers/net/wireless/ath/ath9k/beacon.c
index 02eb4f10332b..ac482498464d 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -109,7 +109,8 @@ static void ath9k_beacon_setup(struct ath_softc *sc, struct 
ieee80211_vif *vif,
 }
 
 static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,
-struct ieee80211_vif *vif)
+struct ieee80211_vif *vif,
+const int slotwidth)
 {
struct ath_softc *sc = hw-priv;
struct ath_common *common = ath9k_hw_common(sc-sc_ah);
@@ -165,8 +166,6 @@ static struct ath_buf *ath9k_beacon_generate(struct 
ieee80211_hw *hw,
return NULL;
}
 
-   skb = ieee80211_get_buffered_bc(hw, vif);
-
/*
 * if the CABQ traffic from previous DTIM is pending and the current
 *  beacon is also a DTIM.
@@ -189,8 +188,7 @@ static struct ath_buf *ath9k_beacon_generate(struct 
ieee80211_hw *hw,
 
ath9k_beacon_setup(sc, vif, bf, info-control.rates[0].idx);
 
-   if (skb)
-   ath_tx_cabq(hw, vif, skb);
+   ath_tx_cabq(hw, vif, slotwidth);
 
return bf;
 }
@@ -201,6 +199,7 @@ void ath9k_beacon_assign_slot(struct ath_softc *sc, struct 
ieee80211_vif *vif)
struct ath_vif *avp = (void *)vif-drv_priv;
int slot;
 
+   avp-multicastWakeup = 0;
avp-av_bcbuf = list_first_entry(sc-beacon.bbuf, struct ath_buf, 
list);
list_del(avp-av_bcbuf-list);
 
@@ -327,6 +326,8 @@ void ath9k_beacon_tasklet(unsigned long data)
struct ieee80211_vif *vif;
bool edma = !!(ah-caps.hw_caps  ATH9K_HW_CAP_EDMA);
int slot;
+   int slotwidth;
+   int i;
 
if (test_bit(SC_OP_HW_RESET, sc-sc_flags)) {
ath_dbg(common, RESET,
@@ -334,6 +335,16 @@ void 

Re: [ath9k-devel] [RFC] ath9k: use more than one slot per bss for multicast in staggered mode

2014-03-10 Thread Felix Fietkau
On 2014-03-10 15:40, Michael Braun wrote:
 Before, ath9k divided time in ATH_BCBUF many equally sized slots.
 Each bss then was assigned to a single slot, leaving some or more slots empty.
 The beacons of a bss were sent at the beginning of the slot for this bss,
 and then the buffered multicast packets might be sent out.
 
 As multicast packets are sent a lowest bitrate, wireless throughput
 of multicast packets is very limited, and thus the time available
 is crucial to avoid buffer overflow, which I frequently observed.
I think in setups where you need to be able to send more multicast
packets, you should consider increasing the multicast rate.

 This patch changes the behaviour of ath9k in two ways:
  1. the time available when processing a slot is increased
 to cover all subsequent unoccupied slots as well.
 This size is tracked in the variable named slotwidth.
I think we should not allow multicast transmission to eat up too much
airtime during the beacon interval. If APs are flooded with multicast
packets, it must not drown out useful unicast traffic.

  2. during each slot, buffered packets from *all* bss are
 sent out in a round-robin fashing, skipping those
 bss where stations are currently not listing.
 That could be either due to
   - last dtim did not containt the relevant flag or
   - a multicast packet not containing the more data
 flag was sent out.
 The state is tracked in multicastWakeup, which is
 true iff the stations in this bss should already
 be woken up.
That does not seem like a good idea to me. Powersave clients waking up
to receive multicast packets should be allowed to go to sleep again as
soon as possible. Keeping them awake unnecessarily by not clearing the
more data bit at the last packet make them eat more power.

 I currently don't know whether a non-buffered multicast packet
 can slip between buffered packets (or between dtim notification
 and the first buffered packet), so that an STA receives a
 multicast packet without MOREDATA set while there a still
 buffered packets to be received and just short before being
 delivered on-air.
The CAB queue gets enabled after a beacon and then takes priority over
all other queues. No packets will slip in between once its transmission
starts.

- Felix
___
ath9k-devel mailing list
ath9k-devel@lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel