- Use ieee80211_probe_resp_alloc() to setup probe response template.
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 9 Dec 2006 08:10:04 +0000 (08:10 +0000)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 9 Dec 2006 08:10:04 +0000 (08:10 +0000)
- Check the return value of ieee80211_probe_resp_alloc() and
  ieee80211_beacon_alloc().  Since these two functions use MB_DONTWAIT
  to allocate mbuf, it is quite possible they will return NULL.
- Turn on IEEE80211_FC0_VERSION_0 when setup null data and probe request
  templates as what we do in netproto/802_11.
- Don't transmit probe responses injected by netproto/802_11 layer,
  firmware will handle them for us.
- Move acx100's TIM ie template setup into common templates initialization
  routine, so acx111 will get its TIM ie template properly set up.
  This makes firmware add well formatted TIM ies to the end of the beacons
  instead of junked ones.
Reported-by: Marcus Glocker <mglocker@openbsd.org>
- Obey DTIM period set in netproto/802_11, i.e. use ieee80211com.ic_dtim_period
- Reduce the length of Partial Virtual Bitmap in TIM template.

sys/dev/netif/acx/acx100.c
sys/dev/netif/acx/acxcmd.c
sys/dev/netif/acx/acxcmd.h
sys/dev/netif/acx/if_acx.c

index ba9edfc..7f27ea2 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/dev/netif/acx/acx100.c,v 1.5 2006/10/25 20:55:55 dillon Exp $
+ * $DragonFly: src/sys/dev/netif/acx/acx100.c,v 1.6 2006/12/09 08:10:04 sephe Exp $
  */
 
 #include <sys/param.h>
@@ -376,7 +376,6 @@ static int
 acx100_init_tmplt(struct acx_softc *sc)
 {
        struct acx_conf_mmap mem_map;
-       struct acx_tmplt_tim tim;
 
        /* Set templates start address */
        if (acx_get_mmap_conf(sc, &mem_map) != 0) {
@@ -395,16 +394,6 @@ acx100_init_tmplt(struct acx_softc *sc)
                if_printf(&sc->sc_ic.ic_if, "can't init tmplt\n");
                return 1;
        }
-
-       /* Setup TIM template */
-       bzero(&tim, sizeof(tim));
-       tim.tim_eid = IEEE80211_ELEMID_TIM;
-       tim.tim_len = ACX_TIM_LEN(ACX_TIM_BITMAP_LEN);
-       if (_acx_set_tim_tmplt(sc, &tim,
-                              ACX_TMPLT_TIM_SIZ(ACX_TIM_BITMAP_LEN)) != 0) {
-               if_printf(&sc->sc_ic.ic_if, "can't set tim tmplt\n");
-               return 1;
-       }
        return 0;
 }
 
index 248cdef..eae123e 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/dev/netif/acx/acxcmd.c,v 1.3 2006/10/25 20:55:55 dillon Exp $
+ * $DragonFly: src/sys/dev/netif/acx/acxcmd.c,v 1.4 2006/12/09 08:10:04 sephe Exp $
  */
 
 #include <sys/param.h>
@@ -141,8 +141,7 @@ acx_join_bss(struct acx_softc *sc, uint8_t mode, struct ieee80211_node *node)
 
        bj->beacon_intvl = htole16(acx_beacon_intvl);
 
-       /* TODO tunable */
-       dtim_intvl = sc->sc_ic.ic_opmode == IEEE80211_M_IBSS ? 1 : 10;
+       dtim_intvl = sc->sc_ic.ic_dtim_period;
        sc->chip_set_bss_join_param(sc, bj->chip_spec, dtim_intvl);
 
        bj->ndata_txrate = ACX_NDATA_TXRATE_2;
index f65f3e1..c05db97 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/dev/netif/acx/acxcmd.h,v 1.2 2006/09/01 15:13:15 sephe Exp $
+ * $DragonFly: src/sys/dev/netif/acx/acxcmd.h,v 1.3 2006/12/09 08:10:04 sephe Exp $
  */
 
 #ifndef _ACXCMD_H
@@ -249,7 +249,7 @@ struct tim_head {
 /* For tim_head.len (tim_head - eid - len + bitmap) */
 #define ACX_TIM_LEN(bitmap_len)        \
        (sizeof(struct tim_head) - (2 * sizeof(uint8_t)) + (bitmap_len))
-#define ACX_TIM_BITMAP_LEN     5
+#define ACX_TIM_BITMAP_LEN     1
 
 struct acx_tmplt_tim {
        uint16_t        size;
index b48b1a8..1b83b57 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/dev/netif/acx/if_acx.c,v 1.10 2006/12/01 07:37:18 sephe Exp $
+ * $DragonFly: src/sys/dev/netif/acx/if_acx.c,v 1.11 2006/12/09 08:10:04 sephe Exp $
  */
 
 /*
@@ -1093,6 +1093,21 @@ acx_start(struct ifnet *ifp)
                        m->m_pkthdr.rcvif = NULL;
 
                        mgmt_pkt = 1;
+
+                       /*
+                        * Don't transmit probe response firmware will
+                        * do it for us.
+                        */
+                       f = mtod(m, struct ieee80211_frame *);
+                       if ((f->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
+                           IEEE80211_FC0_TYPE_MGT &&
+                           (f->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
+                           IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
+                               if (ni != NULL)
+                                       ieee80211_free_node(ni);
+                               m_freem(m);
+                               continue;
+                       }
                } else if (!ifq_is_empty(&ifp->if_snd)) {
                        struct ether_header *eh;
 
@@ -1916,6 +1931,8 @@ back:
 int
 acx_init_tmplt_ordered(struct acx_softc *sc)
 {
+       struct acx_tmplt_tim tim;
+
 #define INIT_TMPLT(name)                       \
 do {                                           \
        if (acx_init_##name##_tmplt(sc) != 0)   \
@@ -1938,6 +1955,17 @@ do {                                             \
        INIT_TMPLT(tim);
        INIT_TMPLT(probe_resp);
 
+       /* Setup TIM template */
+       bzero(&tim, sizeof(tim));
+       tim.tim_eid = IEEE80211_ELEMID_TIM;
+       tim.tim_len = ACX_TIM_LEN(ACX_TIM_BITMAP_LEN);
+       if (_acx_set_tim_tmplt(sc, &tim,
+                              ACX_TMPLT_TIM_SIZ(ACX_TIM_BITMAP_LEN)) != 0) {
+               if_printf(&sc->sc_ic.ic_if, "%s can't set tim tmplt\n",
+                         __func__);
+               return 1;
+       }
+
 #undef INIT_TMPLT
        return 0;
 }
@@ -2377,7 +2405,8 @@ acx_set_null_tmplt(struct acx_softc *sc)
        bzero(&n, sizeof(n));
 
        f = &n.data;
-       f->i_fc[0] = IEEE80211_FC0_SUBTYPE_NODATA | IEEE80211_FC0_TYPE_DATA;
+       f->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA |
+                    IEEE80211_FC0_SUBTYPE_NODATA;
        IEEE80211_ADDR_COPY(f->i_addr1, etherbroadcastaddr);
        IEEE80211_ADDR_COPY(f->i_addr2, IF_LLADDR(&sc->sc_ic.ic_if));
        IEEE80211_ADDR_COPY(f->i_addr3, etherbroadcastaddr);
@@ -2396,7 +2425,8 @@ acx_set_probe_req_tmplt(struct acx_softc *sc, const char *ssid, int ssid_len)
        bzero(&req, sizeof(req));
 
        f = &req.data.u_data.f;
-       f->i_fc[0] = IEEE80211_FC0_SUBTYPE_PROBE_REQ | IEEE80211_FC0_TYPE_MGT;
+       f->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
+                    IEEE80211_FC0_SUBTYPE_PROBE_REQ;
        IEEE80211_ADDR_COPY(f->i_addr1, etherbroadcastaddr);
        IEEE80211_ADDR_COPY(f->i_addr2, IF_LLADDR(&sc->sc_ic.ic_if));
        IEEE80211_ADDR_COPY(f->i_addr3, etherbroadcastaddr);
@@ -2416,17 +2446,20 @@ acx_set_probe_resp_tmplt(struct acx_softc *sc, struct ieee80211_node *ni)
 {
        struct ieee80211com *ic = &sc->sc_ic;
        struct acx_tmplt_probe_resp resp;
-       struct ieee80211_beacon_offsets bo;
+       struct ieee80211_frame *f;
        struct mbuf *m;
        int len;
 
-       bzero(&resp, sizeof(resp));
-
-       bzero(&bo, sizeof(bo));
-       m = ieee80211_beacon_alloc(ic, ni, &bo);
-       DPRINTF((&ic->ic_if, "%s alloc beacon size %d\n", __func__,
+       m = ieee80211_probe_resp_alloc(ic, ni);
+       if (m == NULL)
+               return 1;
+       DPRINTF((&ic->ic_if, "%s alloc probe resp size %d\n", __func__,
                 m->m_pkthdr.len));
 
+       f = mtod(m, struct ieee80211_frame *);
+       IEEE80211_ADDR_COPY(f->i_addr1, etherbroadcastaddr);
+
+       bzero(&resp, sizeof(resp));
        m_copydata(m, 0, m->m_pkthdr.len, (caddr_t)&resp.data);
        len = m->m_pkthdr.len + sizeof(resp.size);
        m_freem(m);
@@ -2443,13 +2476,14 @@ acx_set_beacon_tmplt(struct acx_softc *sc, struct ieee80211_node *ni)
        struct mbuf *m;
        int len;
 
-       bzero(&beacon, sizeof(beacon));
-
        bzero(&bo, sizeof(bo));
        m = ieee80211_beacon_alloc(ic, ni, &bo);
+       if (m == NULL)
+               return 1;
        DPRINTF((&ic->ic_if, "%s alloc beacon size %d\n", __func__,
                 m->m_pkthdr.len));
 
+       bzero(&beacon, sizeof(beacon));
        m_copydata(m, 0, m->m_pkthdr.len, (caddr_t)&beacon.data);
        len = m->m_pkthdr.len + sizeof(beacon.size);
        m_freem(m);