- In ieee80211_setmode(), don't mark basic rates on ieee80211com.ic_sup_rates.
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Mon, 1 Jan 2007 08:51:45 +0000 (08:51 +0000)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Mon, 1 Jan 2007 08:51:45 +0000 (08:51 +0000)
  The basic rates will be marked on ieee80211com.ic_sup_rates once we get the
  BSS' basic rate set, in ieee80211_sta_join().
- Rename ieee80211_set11gbasicrates() to ieee80211_set_basicrates().  Add
  additional parameter to indicate whether we are using Pure G or not.
- In ieee80211_set_basicrates():
  o  Extend basic rate set array by adding items for Turbo G mode (mixed 11B/G
     basic rates) and Turbo A mode (11A mandatory rates).
  o  Add an assertion to make sure we will not go beyond the end of the basic
     rate set array.
  o  Use a seperate constant for Pure G basic rate set.
  o  If 'mode' is 11G or Turbo G, and Pure G is required, use Pure G's basic
     rate set, instead of mixed 11B/G basic rate set.  This makes a standard
     conforming 11B STA not try joining a Pure G BSS created by us.
- In ieee80211_recv_mgmt():
  o  Send probe response even if rate negotiation fails.  According to
     IEEE Std 802.11, 1999 Edition, subclause 11.1.3.2.1:
     ....
     STAs, subject to criteria below, receiving Probe Request frames shall
     respond with a probe response only if the SSID in the probe request is
     the broadcast SSID or matches the specific SSID of the STA.  ... ...
     An AP shall respond to all probe requests meeting the above criteria.
     In an IBSS, the STA that generated the last beacon shall be the STA that
     responds to a probe request.
     ....

     If we reach the rate negotiation step, then the "criteria" outlined by
     the standard is already met.
  o  Don't do rate negotiation for temporary nodes, which are created just for
     sending probe responses.  This may save us some cpu time.
- Reset NIC for Pure G change, only if opmode is HOSTAP or IBSS(*), and phy
  mode is either Turbo G or 11G.
- Don't allocate TX rate control data for temporary nodes, since they will be
  reclaimed immediately after management frames are sent.

# (*) Actually, for IBSS opmode, we need to reset the NIC iff we are the only
#     member of the current IBSS.

sys/netproto/802_11/ieee80211_proto.h
sys/netproto/802_11/wlan/ieee80211.c
sys/netproto/802_11/wlan/ieee80211_input.c
sys/netproto/802_11/wlan/ieee80211_ioctl.c
sys/netproto/802_11/wlan/ieee80211_node.c
sys/netproto/802_11/wlan/ieee80211_output.c
sys/netproto/802_11/wlan/ieee80211_proto.c

index 06f55b5..9a985b2 100644 (file)
@@ -30,7 +30,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/net80211/ieee80211_proto.h,v 1.11.2.5 2006/02/12 19:00:39 sam Exp $
- * $DragonFly: src/sys/netproto/802_11/ieee80211_proto.h,v 1.7 2006/12/23 09:14:02 sephe Exp $
+ * $DragonFly: src/sys/netproto/802_11/ieee80211_proto.h,v 1.8 2007/01/01 08:51:45 sephe Exp $
  */
 #ifndef _NET80211_IEEE80211_PROTO_H_
 #define _NET80211_IEEE80211_PROTO_H_
@@ -87,8 +87,8 @@ void  ieee80211_set_shortslottime(struct ieee80211com *, int);
 void   ieee80211_set_shortpreamble(struct ieee80211com *, int);
 int    ieee80211_iserp_rateset(struct ieee80211com *,
                struct ieee80211_rateset *);
-void   ieee80211_set11gbasicrates(struct ieee80211_rateset *,
-               enum ieee80211_phymode);
+void   ieee80211_set_basicrates(struct ieee80211_rateset *,
+               enum ieee80211_phymode, int);
 int    ieee80211_copy_basicrates(struct ieee80211_rateset *,
                const struct ieee80211_rateset *);
 
index d8c9340..0042aca 100644 (file)
@@ -30,7 +30,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/net80211/ieee80211.c,v 1.19.2.7 2006/03/11 19:25:23 sam Exp $
- * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211.c,v 1.10 2006/12/22 23:57:53 swildner Exp $
+ * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211.c,v 1.11 2007/01/01 08:51:45 sephe Exp $
  */
 
 /*
@@ -894,22 +894,6 @@ ieee80211_setmode(struct ieee80211com *ic, enum ieee80211_phymode mode)
            isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, ic->ic_des_chan)))
                ic->ic_des_chan = IEEE80211_CHAN_ANYC;
 
-       /*
-        * Do mode-specific rate setup.
-        */
-       if (mode == IEEE80211_MODE_11G) {
-               /*
-                * Use a mixed 11b/11g rate set.
-                */
-               ieee80211_set11gbasicrates(&ic->ic_sup_rates[mode],
-                       IEEE80211_MODE_11G);
-       } else if (mode == IEEE80211_MODE_11B) {
-               /*
-                * Force pure 11b rate set.
-                */
-               ieee80211_set11gbasicrates(&ic->ic_sup_rates[mode],
-                       IEEE80211_MODE_11B);
-       }
        /*
         * Setup an initial rate set according to the
         * current/default channel selected above.  This
index 45e6f1f..66e41b7 100644 (file)
@@ -30,7 +30,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.62.2.14 2006/09/02 15:16:12 sam Exp $
- * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_input.c,v 1.13 2006/12/23 09:14:02 sephe Exp $
+ * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_input.c,v 1.14 2007/01/01 08:51:45 sephe Exp $
  */
 
 #include <sys/param.h>
@@ -1786,7 +1786,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
        struct ieee80211_frame *wh;
        uint8_t *frm, *efrm;
        uint8_t *ssid, *rates, *xrates, *wpa, *wme;
-       int reassoc, resp, allocbs;
+       int reassoc, resp;
        uint8_t rate;
 
        wh = mtod(m0, struct ieee80211_frame *);
@@ -2075,7 +2075,9 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
                break;
        }
 
-       case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
+       case IEEE80211_FC0_SUBTYPE_PROBE_REQ: {
+               int is_tmpnode;
+
                if (ic->ic_opmode == IEEE80211_M_STA ||
                    ic->ic_state != IEEE80211_S_RUN) {
                        ic->ic_stats.is_rx_mgtdiscard++;
@@ -2121,11 +2123,11 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
                        return;
                }
 
-               allocbs = 0;
+               is_tmpnode = 0;
                if (ni == ic->ic_bss) {
                        if (ic->ic_opmode != IEEE80211_M_IBSS) {
                                ni = ieee80211_tmp_node(ic, wh->i_addr2);
-                               allocbs = 1;
+                               is_tmpnode = 1;
                        } else if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
                                /*
                                 * XXX Cannot tell if the sender is operating
@@ -2143,19 +2145,20 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
                    "[%6D] recv probe req\n", wh->i_addr2, ":");
                ni->ni_rssi = rssi;
                ni->ni_rstamp = rstamp;
-               rate = ieee80211_setup_rates(ni, rates, xrates,
-                         IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE
-                       | IEEE80211_F_DONEGO | IEEE80211_F_DODEL, 0);
-               if (rate & IEEE80211_RATE_BASIC) {
-                       IEEE80211_DISCARD(ic, IEEE80211_MSG_XRATE,
-                           wh, ieee80211_mgt_subtype_name[subtype >>
-                               IEEE80211_FC0_SUBTYPE_SHIFT],
-                           "%s", "recv'd rate set invalid");
-               } else {
-                       IEEE80211_SEND_MGMT(ic, ni,
-                               IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0);
+
+               /*
+                * Since temporary node's rate set will not be used,
+                * there is no need to do rate negotiation for it.
+                */
+               if (!is_tmpnode) {
+                       ieee80211_setup_rates(ni, rates, xrates,
+                               IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
+                               IEEE80211_F_DONEGO | IEEE80211_F_DODEL, 0);
                }
-               if (allocbs) {
+
+               IEEE80211_SEND_MGMT(ic, ni,
+                       IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0);
+               if (is_tmpnode) {
                        /*
                         * Temporary node created just to send a
                         * response, reclaim immediately.
@@ -2163,6 +2166,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
                        ieee80211_free_node(ni);
                }
                break;
+       }
 
        case IEEE80211_FC0_SUBTYPE_AUTH: {
                uint16_t algo, seq, status;
index cf3fc3b..468bff4 100644 (file)
@@ -30,7 +30,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/net80211/ieee80211_ioctl.c,v 1.25.2.15 2006/09/02 17:09:26 sam Exp $
- * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_ioctl.c,v 1.9 2006/12/01 04:42:53 sephe Exp $
+ * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_ioctl.c,v 1.10 2007/01/01 08:51:45 sephe Exp $
  */
 
 /*
@@ -2481,8 +2481,15 @@ ieee80211_ioctl_set80211(struct ieee80211com *ic, u_long cmd, struct ieee80211re
                        ic->ic_flags |= IEEE80211_F_PUREG;
                else
                        ic->ic_flags &= ~IEEE80211_F_PUREG;
-               /* NB: reset only if we're operating on an 11g channel */
-               if (ic->ic_curmode == IEEE80211_MODE_11G)
+
+               /*
+                * NB: reset only if we're operating on an 11g channel
+                *     and we act as AP or we are a member of an IBSS.
+                */
+               if ((ic->ic_curmode == IEEE80211_MODE_11G ||
+                    ic->ic_curmode == IEEE80211_MODE_TURBO_G) &&
+                   (ic->ic_opmode == IEEE80211_M_HOSTAP ||
+                    ic->ic_opmode == IEEE80211_M_IBSS))
                        error = ENETRESET;
                break;
        case IEEE80211_IOC_MCAST_RATE:
index a84ffde..0f5e868 100644 (file)
@@ -30,7 +30,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/net80211/ieee80211_node.c,v 1.48.2.12 2006/07/10 00:46:27 sam Exp $
- * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_node.c,v 1.14 2006/12/23 09:14:02 sephe Exp $
+ * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_node.c,v 1.15 2007/01/01 08:51:45 sephe Exp $
  */
 
 #include <sys/param.h>
@@ -446,17 +446,8 @@ ieee80211_create_ibss(struct ieee80211com* ic, struct ieee80211_channel *chan)
        /*
         * Do mode-specific rate setup.
         */
-       if (ic->ic_curmode == IEEE80211_MODE_11G) {
-               /*
-                * Use a mixed 11b/11g rate set.
-                */
-               ieee80211_set11gbasicrates(&ni->ni_rates, IEEE80211_MODE_11G);
-       } else if (ic->ic_curmode == IEEE80211_MODE_11B) {
-               /*
-                * Force pure 11b rate set.
-                */
-               ieee80211_set11gbasicrates(&ni->ni_rates, IEEE80211_MODE_11B);
-       }
+       ieee80211_set_basicrates(&ni->ni_rates, ic->ic_curmode,
+                                ic->ic_flags & IEEE80211_F_PUREG);
 
        ieee80211_sta_join(ic, ieee80211_ref_node(ni));
 }
@@ -1045,8 +1036,6 @@ ieee80211_tmp_node(struct ieee80211com *ic, const uint8_t *macaddr)
 
                ni->ni_table = NULL;            /* NB: pedantic */
                ni->ni_ic = ic;
-
-               ieee80211_ratectl_data_alloc(ni);
        } else {
                /* XXX msg */
                ic->ic_stats.is_rx_nodealloc++;
@@ -1723,8 +1712,6 @@ node_reclaim(struct ieee80211_node_table *nt, struct ieee80211_node *ni)
                __func__, ni, ni->ni_macaddr, ":",
                nt->nt_name, ieee80211_node_refcnt(ni)-1);
 
-       ieee80211_ratectl_data_free(ni);
-
        /*
         * Clear any entry in the unicast key mapping table.
         * We need to do it here so rx lookups don't find it
@@ -1751,6 +1738,15 @@ node_reclaim(struct ieee80211_node_table *nt, struct ieee80211_node *ni)
                TAILQ_REMOVE(&nt->nt_node, ni, ni_list);
                LIST_REMOVE(ni, ni_hash);
                ni->ni_table = NULL;            /* clear reference */
+
+               /*
+                * XXX
+                * We may want to put reclaimed node on <gone> table
+                * so that ratectl modules can find them and free
+                * the resources in their detach routines instead of
+                * freeing the resources here.
+                */
+               ieee80211_ratectl_data_free(ni);
        } else
                _ieee80211_free_node(ni);
 }
index 26e575c..8ab77ed 100644 (file)
@@ -30,7 +30,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/net80211/ieee80211_output.c,v 1.26.2.8 2006/09/02 15:06:04 sam Exp $
- * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_output.c,v 1.12 2006/12/26 14:53:21 sephe Exp $
+ * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_output.c,v 1.13 2007/01/01 08:51:45 sephe Exp $
  */
 
 #include "opt_inet.h"
@@ -1039,7 +1039,7 @@ ieee80211_send_probereq(struct ieee80211_node *ni,
         */
        mode = ieee80211_chan2mode(ic, ic->ic_curchan);
        rs = ic->ic_sup_rates[mode];
-       ieee80211_set11gbasicrates(&rs, IEEE80211_MODE_AUTO);
+       ieee80211_set_basicrates(&rs, IEEE80211_MODE_AUTO, 0);
        frm = ieee80211_add_rates(frm, &rs);
        frm = ieee80211_add_xrates(frm, &rs);
 
index b60e6bc..6133a1d 100644 (file)
@@ -30,7 +30,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/net80211/ieee80211_proto.c,v 1.17.2.9 2006/03/13 03:10:31 sam Exp $
- * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_proto.c,v 1.7 2006/12/23 09:14:02 sephe Exp $
+ * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_proto.c,v 1.8 2007/01/01 08:51:45 sephe Exp $
  */
 
 /*
@@ -556,26 +556,39 @@ ieee80211_iserp_rateset(struct ieee80211com *ic, struct ieee80211_rateset *rs)
  * the basic OFDM rates.
  */
 void
-ieee80211_set11gbasicrates(struct ieee80211_rateset *rs, enum ieee80211_phymode mode)
+ieee80211_set_basicrates(struct ieee80211_rateset *rs,
+                        enum ieee80211_phymode mode, int pureg)
 {
        static const struct ieee80211_rateset basic[] = {
-           { 0 },                      /* IEEE80211_MODE_AUTO */
-           { 3, { 12, 24, 48 } },      /* IEEE80211_MODE_11A */
-           { 2, { 2, 4 } },            /* IEEE80211_MODE_11B */
-           { 4, { 2, 4, 11, 22 } },    /* IEEE80211_MODE_11G (mixed b/g) */
-           { 0 },                      /* IEEE80211_MODE_FH */
-                                       /* IEEE80211_MODE_PUREG (not yet) */
-           { 7, { 2, 4, 11, 22, 12, 24, 48 } },
+           [IEEE80211_MODE_AUTO]       = { 0 },
+           [IEEE80211_MODE_11A]        = { 3, { 12, 24, 48 } },
+           [IEEE80211_MODE_11B]        = { 2, { 2, 4 } },
+           [IEEE80211_MODE_11G]        = { 4, { 2, 4, 11, 22 } },
+           [IEEE80211_MODE_FH]         = { 0 },
+           [IEEE80211_MODE_TURBO_A]    = { 3, { 12, 24, 48 } },
+           [IEEE80211_MODE_TURBO_G]    = { 4, { 2, 4, 11, 22 } }
        };
+       static const struct ieee80211_rateset basic_pureg =
+           { 7, { 2, 4, 11, 22, 12, 24, 48 } };
+       const struct ieee80211_rateset *basic_rs;
        int i, j;
 
+       KASSERT(mode < IEEE80211_MODE_MAX, ("invalid phymode %u\n", mode));
+
+       if ((mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_TURBO_G) &&
+           pureg)
+               basic_rs = &basic_pureg;
+       else
+               basic_rs = &basic[mode];
+
        for (i = 0; i < rs->rs_nrates; i++) {
                rs->rs_rates[i] &= IEEE80211_RATE_VAL;
-               for (j = 0; j < basic[mode].rs_nrates; j++)
-                       if (basic[mode].rs_rates[j] == rs->rs_rates[i]) {
+               for (j = 0; j < basic_rs->rs_nrates; j++) {
+                       if (basic_rs->rs_rates[j] == rs->rs_rates[i]) {
                                rs->rs_rates[i] |= IEEE80211_RATE_BASIC;
                                break;
                        }
+               }
        }
 }