Restart TX rate control algorithm for a peer node, if its current TX
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 24 Dec 2006 11:39:59 +0000 (11:39 +0000)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 24 Dec 2006 11:39:59 +0000 (11:39 +0000)
rate index is beyond the number of TX rates it supports.

This could happen at least in following way:
1) Start a 11g HOSTAP, which uses TX rate control algorithm
2) Use a 11g cardbus wireless card as STA, set its mode to "auto" or
   "11g" and join the BSS created by HOSTAP
3) Transmit some packets from HOSTAP to STA and make sure that TX rate
   index for the STA reaches maximum.
4) Unplug the cardbus wireless card, so it has no chance to send out
   disassociation management frame.
5) Plug the cardbus wireless card back immediately, set its mode to
   "11b" and join the BSS created by HOSTAP again.

sys/netproto/802_11/wlan_ratectl/amrr/ieee80211_ratectl_amrr.c
sys/netproto/802_11/wlan_ratectl/onoe/ieee80211_ratectl_onoe.c

index 4ff6684..c7aac3c 100644 (file)
@@ -35,7 +35,7 @@
  * THE POSSIBILITY OF SUCH DAMAGES.
  *
  * $FreeBSD: src/sys/dev/ath/ath_rate/amrr/amrr.c,v 1.8.2.3 2006/02/24 19:51:11 sam Exp $
- * $DragonFly: src/sys/netproto/802_11/wlan_ratectl/amrr/ieee80211_ratectl_amrr.c,v 1.6 2006/12/22 23:57:53 swildner Exp $
+ * $DragonFly: src/sys/netproto/802_11/wlan_ratectl/amrr/ieee80211_ratectl_amrr.c,v 1.7 2006/12/24 11:39:59 sephe Exp $
  */
 
 /*
@@ -122,10 +122,18 @@ MALLOC_DEFINE(M_AMRR_RATECTL_DATA, "amrr_ratectl_data",
              "amrr rate control data");
 
 static int
-amrr_findrate(void *arg __unused, struct ieee80211_node *ni,
+amrr_findrate(void *arg, struct ieee80211_node *ni,
              int frame_len __unused, int rateidx[], int rateidx_len)
 {
-       int i, rate_idx = ni->ni_txrate;
+       struct amrr_softc *asc = arg;
+       int i, rate_idx;
+
+       if (ni->ni_txrate >= ni->ni_rates.rs_nrates) {
+               DPRINTF(asc, 5, "%s: number of rates changed, restart\n",
+                       __func__);
+               amrr_start(asc, ni);
+       }
+       rate_idx = ni->ni_txrate;
 
        for (i = 0; i < rateidx_len; ++i) {
                if (rate_idx < 0)
index 65d2607..5549ecb 100644 (file)
@@ -34,7 +34,7 @@
  * THE POSSIBILITY OF SUCH DAMAGES.
  *
  * $FreeBSD: src/sys/dev/ath/ath_rate/onoe/onoe.c,v 1.8.2.3 2006/02/24 19:51:11 sam Exp $
- * $DragonFly: src/sys/netproto/802_11/wlan_ratectl/onoe/ieee80211_ratectl_onoe.c,v 1.5 2006/12/22 23:57:53 swildner Exp $
+ * $DragonFly: src/sys/netproto/802_11/wlan_ratectl/onoe/ieee80211_ratectl_onoe.c,v 1.6 2006/12/24 11:39:59 sephe Exp $
  */
 
 /*
@@ -161,10 +161,18 @@ onoe_newassoc(void *arg, struct ieee80211_node *ni, int is_new)
 }
 
 static int
-onoe_findrate(void *arg __unused, struct ieee80211_node *ni,
+onoe_findrate(void *arg, struct ieee80211_node *ni,
              int frame_len __unused, int rateidx[], int rateidx_len)
 {
-       int i, rate_idx = ni->ni_txrate;
+       struct onoe_softc *osc = arg;
+       int i, rate_idx;
+
+       if (ni->ni_txrate >= ni->ni_rates.rs_nrates) {
+               DPRINTF(osc, 5, "%s: number of rates changed, restart\n",
+                       __func__);
+               onoe_start(osc, ni);
+       }
+       rate_idx = ni->ni_txrate;
 
        for (i = 0; i < rateidx_len; ++i) {
                if (rate_idx < 0)