Subject: Re: ath(4) rate choices for 'bss' in IBSS mode
To: Greg Troxel <gdt@ir.bbn.com>
From: Sam Leffler <sam@errno.com>
List: tech-net
Date: 09/23/2004 17:52:04
On Thursday 23 September 2004 12:33 pm, Greg Troxel wrote:
> I have a 7 systems running the 2.0 branch and significant local
> changes, all with ath(4) hardware.  The systems are IBM T41s and X31s
> with IBM minipci adaptors (some a/b/g and some b/g).  I found that
> while I got decent range for unicast traffic, multicast traffic
> performed very poorly.
>
> On reading sys/dev/ath.c, I found that there is per-'node' rate
> control, and in IBSS mode a node is kept for each neighbor.  This
> seems to work pretty well.  There is also a 'node' for the 'bss', used
> in STA mode to rate adapt the link to the AP.  But, it seems that in
> IBSS mode the bss node is used to send multicast packets.  The
> existing code (as in -current) initializes the bss node to the highest
> rate.  In IBSS mode, nothing adapts this rate (other than making sure
> it is a 'supported rate' in the IBSS).
>
> I changed this to use the lowest, trading off speed for range, and now
> the range I can get with multicast packets is similar to that for
> unicast.
>
> It's not clear what should happen for multicast packets, but since in
> an IBSS there is no crisp notion of group membership, I would argue
> that any station which could be reached in unicast mode at the lowest
> rate should get multicast traffic (e.g., one generally has to ARP
> before sending unicast IP).
>
> In HOSTAP mode, arguably multicasts should get sent at the minimum
> rate of any associated STA.
>
> [Line  numbers are off because I changed a lot of other things.]
> Index: sys/dev/ic/ath.c
> ===================================================================
> RCS file: /SINEW-CVS/netbsd/src/sys/dev/ic/ath.c,v
> retrieving revision 1.1.1.4
> retrieving revision 1.9
> diff -u -r1.1.1.4 -r1.9
> --- dev/ic/ath.c	22 Aug 2004 13:37:22 -0000	1.1.1.4
> +++ dev/ic/ath.c	23 Sep 2004 17:05:46 -0000	1.9
> @@ -3400,7 +3470,7 @@
>  	ni = ic->ic_bss;
>  	an = (struct ath_node *) ni;
>  	an->an_tx_ok = an->an_tx_err = an->an_tx_retr = an->an_tx_upper = 0;
> -	if (state == IEEE80211_S_RUN) {
> +	if (state == IEEE80211_S_RUN && ic->ic_opmode != IEEE80211_M_IBSS) {
>  		/* start with highest negotiated rate */
>  		KASSERT(ni->ni_rates.rs_nrates > 0,
>  			("transition to RUN state w/ no rates!"));
>
>
> Here is the whole (patched) code snipped in ath_rate_ctl_reset:
>
> 	/*
> 	 * Reset local xmit state; this is really only meaningful
> 	 * when operating in station or adhoc mode.
> 	 */
> 	ni = ic->ic_bss;
> 	an = (struct ath_node *) ni;
> 	an->an_tx_ok = an->an_tx_err = an->an_tx_retr = an->an_tx_upper = 0;
> 	if (state == IEEE80211_S_RUN && ic->ic_opmode != IEEE80211_M_IBSS) {
> 		/* start with highest negotiated rate */
> 		KASSERT(ni->ni_rates.rs_nrates > 0,
> 			("transition to RUN state w/ no rates!"));
> 		ni->ni_txrate = ni->ni_rates.rs_nrates - 1;
> 	} else {
> 		/* use lowest rate */
> 		ni->ni_txrate = 0;
> 	}

The bug is actually that ath_tx_start should check for multicast frames and 
use a rate appropriate for control frames.

Separately the rate control code in netbsd's ath driver appears to be old.  I 
recently split rate control out in the linux version of the driver so 
alternate rate control algorithms can be used w/o changing the driver (they 
are packaged as independent modules).

	Sam