[[email protected]: Power Save Mode w/ FreeBSD HostAP]
Matt Peterson <[email protected]> Wed, 2 Apr 2003 16:58:47 -0800
| Newsgroups | gmane.network.wireless.bsd.general |
|---|---|
| Message-ID | <[email protected]> |
I've been using Kevin's latest patches (against FreeBSD 4-STABLE) with
good luck against an Intel Centrino STA. If others could give these a
whirl, we can move forward with getting them committed ;)
Index: if_wavelan_ieee.h
===================================================================
RCS file: /home/ncvs/src/sys/dev/wi/if_wavelan_ieee.h,v
retrieving revision 1.12.2.2
diff -c -r1.12.2.2 if_wavelan_ieee.h
*** if_wavelan_ieee.h 2002/08/02 07:11:34 1.12.2.2
--- if_wavelan_ieee.h 2003/03/31 05:20:48
***************
*** 219,224 ****
--- 219,225 ----
#define WI_RID_WEP_MAPTABLE 0xFC29
#define WI_RID_CNFAUTHMODE 0xFC2A
#define WI_RID_ROAMING_MODE 0xFC2D
+ #define WI_RID_SET_TIM 0xFC40
#define WI_RID_CNF_DBM_ADJUST 0xFC46
#define WI_RID_BASIC_RATE 0xFCB3
#define WI_RID_SUPPORT_RATE 0xFCB4
Index: if_wi.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/wi/if_wi.c,v
retrieving revision 1.103.2.2
diff -c -r1.103.2.2 if_wi.c
*** if_wi.c 2002/08/02 07:11:34 1.103.2.2
--- if_wi.c 2003/03/31 05:20:53
***************
*** 695,701 ****
eh = mtod(m, struct ether_header *);
m->m_pkthdr.rcvif = ifp;
! if (rx_frame.wi_status == WI_STAT_MGMT &&
sc->wi_ptype == WI_PORTTYPE_AP) {
if ((WI_802_11_OFFSET_RAW + rx_frame.wi_dat_len + 2) >
MCLBYTES) {
--- 695,703 ----
eh = mtod(m, struct ether_header *);
m->m_pkthdr.rcvif = ifp;
! if ((rx_frame.wi_status == WI_STAT_MGMT ||
! (rx_frame.wi_frame_ctl & htole16(WI_FCTL_FTYPE)) ==
! htole16(WI_FTYPE_CTL)) &&
sc->wi_ptype == WI_PORTTYPE_AP) {
if ((WI_802_11_OFFSET_RAW + rx_frame.wi_dat_len + 2) >
MCLBYTES) {
***************
*** 1080,1085 ****
--- 1082,1101 ----
return;
}
+ void
+ wi_set_tim(struct wi_softc *sc, u_int16_t aid, int which)
+ {
+ if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)
+ printf("wi_set_tim: set TIM for 0x%x\n", aid);
+
+ aid &= ~0xc000;
+ if (which)
+ aid |= 0x8000;
+
+ WI_SETVAL(WI_RID_SET_TIM, aid);
+ }
+
+
/*
* Read an LTV record from the NIC.
*/
***************
*** 2248,2253 ****
--- 2264,2271 ----
struct ether_header *eh;
int id;
int s;
+ int power_save;
+ int more;
sc = ifp->if_softc;
WI_LOCK(sc, s);
***************
*** 2263,2272 ****
}
nextpkt:
! IF_DEQUEUE(&ifp->if_snd, m0);
if (m0 == NULL) {
! WI_UNLOCK(sc, s);
! return;
}
bzero((char *)&tx_frame, sizeof(tx_frame));
--- 2281,2298 ----
}
nextpkt:
! IF_DEQUEUE(&sc->wi_pwrsaveq, m0);
if (m0 == NULL) {
! IF_DEQUEUE(&ifp->if_snd, m0);
! if (m0 == NULL) {
! WI_UNLOCK(sc, s);
! return;
! }
! power_save = 0;
! more = 0;
! } else {
! power_save = 1;
! more = 0;
}
bzero((char *)&tx_frame, sizeof(tx_frame));
***************
*** 2275,2288 ****
eh = mtod(m0, struct ether_header *);
if (sc->wi_ptype == WI_PORTTYPE_AP) {
! if (!wihap_check_tx(&sc->wi_hostap_info,
! eh->ether_dhost, &tx_frame.wi_tx_rate)) {
if (ifp->if_flags & IFF_DEBUG)
! printf("wi_start: dropping unassoc "
! "dst %6D\n", eh->ether_dhost, ":");
m_freem(m0);
goto nextpkt;
}
}
/*
* Use RFC1042 encoding for IP and ARP datagrams,
--- 2301,2322 ----
eh = mtod(m0, struct ether_header *);
if (sc->wi_ptype == WI_PORTTYPE_AP) {
! if (!wihap_check_tx(&sc->wi_hostap_info, eh->ether_dhost,
! &tx_frame.wi_tx_rate)) {
if (ifp->if_flags & IFF_DEBUG)
! printf("wi_start: dropping unassoc dst %6D\n",
! eh->ether_dhost, ":");
m_freem(m0);
goto nextpkt;
}
+ if (!wihap_check_ps_queue(sc, m0, power_save, &more)) {
+ if (ifp->if_flags & IFF_DEBUG)
+ printf("wi_start: deferred for powersaving on "
+ "dst %6D\n", eh->ether_dhost, ":");
+ goto nextpkt;
+ }
+ if (more)
+ tx_frame.wi_frame_ctl |= WI_FCTL_MOREDATA;
}
/*
* Use RFC1042 encoding for IP and ARP datagrams,
Index: if_wivar.h
===================================================================
RCS file: /home/ncvs/src/sys/dev/wi/if_wivar.h,v
retrieving revision 1.8.2.3
diff -c -r1.8.2.3 if_wivar.h
*** if_wivar.h 2002/08/02 07:11:34 1.8.2.3
--- if_wivar.h 2003/03/31 05:20:54
***************
*** 193,198 ****
--- 193,199 ----
u_int16_t wi_confbits_param0;
} wi_debug;
+ struct ifqueue wi_pwrsaveq;
};
struct wi_card_ident {
***************
*** 221,224 ****
--- 222,226 ----
int wi_alloc(device_t, int);
void wi_free(device_t);
extern devclass_t wi_devclass;
+ void wi_set_tim(struct wi_softc *, u_int16_t, int);
int wi_mgmt_xmit(struct wi_softc *, caddr_t, int);
Index: wi_hostap.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/wi/Attic/wi_hostap.c,v
retrieving revision 1.7.2.4
diff -c -r1.7.2.4 wi_hostap.c
*** wi_hostap.c 2002/08/02 07:11:34 1.7.2.4
--- wi_hostap.c 2003/03/31 05:20:56
***************
*** 302,308 ****
s = splnet();
sta = LIST_FIRST(&whi->sta_list);
while (sta) {
- untimeout(wihap_sta_timeout, sta, sta->tmo);
if (!sc->wi_gone) {
/* Disassociate station. */
if (sta->flags & WI_SIFLAGS_ASSOC)
--- 302,307 ----
***************
*** 318,324 ****
if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)
printf("wihap_shutdown: FREE(sta=0x%x)\n", (int)sta);
next = LIST_NEXT(sta, list);
! FREE(sta, M_HAP_STA);
sta = next;
}
--- 317,323 ----
if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)
printf("wihap_shutdown: FREE(sta=0x%x)\n", (int)sta);
next = LIST_NEXT(sta, list);
! wihap_sta_delete(sta);
sta = next;
}
***************
*** 358,366 ****
sta->addr, ":");
/* Disassoc station. */
! wihap_sta_disassoc(sc, sta->addr,
! IEEE80211_REASON_ASSOC_EXPIRE);
! sta->flags &= ~WI_SIFLAGS_ASSOC;
sta->tmo = timeout(wihap_sta_timeout, sta,
hz * whi->inactivity_time);
--- 357,381 ----
sta->addr, ":");
/* Disassoc station. */
! if (sta->flags & WI_SIFLAGS_PS) {
! /*
! * If in powersave mode, delay sending the mgmt
! * message. This should be the only kind of mgmt
! * message that can go to an associated station
! * in powersave mode. A deauthentication message
! * is also possible, but since that is usually
! * followed by the deletion of the station
! * information, buffering the message wouldn't
! * do us any good.
! */
! wi_set_tim(sc, sta->asid, 1);
! sta->flags |= WI_SIFLAGS_DEASSOC;
! sta->reason = IEEE80211_REASON_ASSOC_EXPIRE;
! } else {
! wihap_sta_disassoc(sc, sta->addr,
! IEEE80211_REASON_ASSOC_EXPIRE);
! sta->flags &= ~WI_SIFLAGS_ASSOC;
! }
sta->tmo = timeout(wihap_sta_timeout, sta,
hz * whi->inactivity_time);
***************
*** 400,405 ****
--- 415,425 ----
LIST_REMOVE(sta, hash);
if (sta->challenge)
FREE(sta->challenge, M_TEMP);
+ if (!IF_IS_EMPTY(&sta->savedq)) {
+ IF_PURGE(&sta->savedq);
+ wi_set_tim(sc, sta->asid, 0);
+ }
+
FREE(sta, M_HAP_STA);
whi->n_stations--;
}
***************
*** 424,433 ****
bzero(sta, sizeof(struct wihap_sta_info));
! /* Allocate an ASID. */
! i=hash<<4;
! while (whi->asid_inuse_mask[i >> 4] & (1UL << (i & 0xf)))
i = (i == (WI_STA_HASH_SIZE << 4) - 1) ? 0 : (i + 1);
whi->asid_inuse_mask[i >> 4] |= (1UL << (i & 0xf));
sta->asid = 0xc001 + i;
--- 444,467 ----
bzero(sta, sizeof(struct wihap_sta_info));
! /*
! * Allocate an ASID. This originally had a clever algorithm to
! * come up with ASIDs that were related to the hash value of
! * the station. Alas, for power saving mode, we have to use
! * ASIDs that are less than 254 -- the PRISM2 firmware (I've tested
! * this up to 1.4.9) doesn't allow us to report any larger ASIDs
! * in the TIM. Bummer. In any case, we'd like to cluster the
! * ASIDs together to reduce the size of the TIM, anyway.
! */
! i=0;
! while (whi->asid_inuse_mask[i >> 4] & (1UL << (i & 0xf)) &&
! i < WIHAP_MAX_STATIONS)
i = (i == (WI_STA_HASH_SIZE << 4) - 1) ? 0 : (i + 1);
+ if (i >= WIHAP_MAX_STATIONS) {
+ FREE(sta, M_HAP_STA);
+ return(NULL);
+ }
+
whi->asid_inuse_mask[i >> 4] |= (1UL << (i & 0xf));
sta->asid = 0xc001 + i;
***************
*** 460,465 ****
--- 494,546 ----
return (NULL);
}
+ /* wihap_check_ps()
+ *
+ * Check to see if this station is going into or coming out of
+ * powersave mode.
+ */
+ static void
+ wihap_check_ps(struct wi_softc *sc, struct wi_frame *rxfrm,
+ struct wihap_sta_info *sta)
+ {
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+
+ if (!sta) {
+ sta = wihap_sta_find(&sc->wi_hostap_info, rxfrm->wi_addr2);
+ if (!sta)
+ return;
+ }
+
+ if ((rxfrm->wi_frame_ctl & htole16(WI_FCTL_PM)) &&
+ (sta->flags & WI_SIFLAGS_PS) == 0) {
+ /* turn on powersave mode */
+ sta->flags |= WI_SIFLAGS_PS;
+
+ if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)
+ printf("wihap_check_ps: Station %6D going into "
+ "powersaving mode\n", rxfrm->wi_addr2, ":");
+
+ } else if (!(rxfrm->wi_frame_ctl & htole16(WI_FCTL_PM)) &&
+ (sta->flags & WI_SIFLAGS_PS) == WI_SIFLAGS_PS) {
+ struct mbuf *m;
+
+ /* turn off powersave mode */
+ sta->flags &= ~WI_SIFLAGS_PS;
+
+ if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)
+ printf("wihap_check_ps: Station %6D leaving "
+ "powersaving mode\n", rxfrm->wi_addr2, ":");
+
+ wi_set_tim(sc, sta->asid, 0);
+ IF_DEQUEUE(&sta->savedq, m);
+ while (m != NULL) {
+ IF_ENQUEUE(&ifp->if_snd, m);
+ (ifp->if_start)(ifp);
+ IF_DEQUEUE(&sta->savedq, m);
+ }
+ }
+ }
+
static int
wihap_check_rates(struct wihap_sta_info *sta, u_int8_t rates[], int rates_len)
{
***************
*** 777,783 ****
fail:
if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)
! printf("wihap_assoc_req: returns status=0x%x\n", status);
/* Send response. */
resp_hdr = (struct wi_80211_hdr *) sc->wi_txbuf;
--- 858,865 ----
fail:
if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)
! printf("wihap_assoc_req: returns status=0x%x, asid 0x%x\n",
! status, asid);
/* Send response. */
resp_hdr = (struct wi_80211_hdr *) sc->wi_txbuf;
***************
*** 863,868 ****
--- 945,1051 ----
sta->flags &= ~WI_SIFLAGS_ASSOC;
}
+ /* wihap_pspoll()
+ *
+ * Handle power save polls. Determine if the station has
+ * any packets queued up for transmission, and send the
+ * first. If there are no packets left, clear the TIM bit
+ * for the station.
+ */
+ static void
+ wihap_pspoll(struct wi_softc *sc, struct wi_frame *rxfrm,
+ caddr_t pkt, int len)
+ {
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+ struct wihap_info *whi = &sc->wi_hostap_info;
+ struct wihap_sta_info *sta;
+ struct mbuf *m;
+ u_int16_t asid;
+
+ asid = le16toh(rxfrm->wi_id);
+
+ sta = wihap_sta_find(whi, rxfrm->wi_addr2);
+ if (sta == NULL) {
+ if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)
+ printf("wihap_pspoll: unknown station: %6D\n",
+ rxfrm->wi_addr2, ":");
+ return;
+ }
+ if (!(sta->flags & WI_SIFLAGS_AUTHEN)) {
+ /*
+ * If station is not authenticated, send deauthentication
+ * frame.
+ */
+ wihap_sta_deauth(sc, rxfrm->wi_addr2,
+ IEEE80211_REASON_NOT_AUTHED);
+ return;
+ }
+ if (asid != sta->asid) {
+ if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)
+ printf("wihap_pspoll: station %6D asid %d doesn't "
+ "match asid %d\n",
+ rxfrm->wi_addr2, ":", sta->asid, asid);
+ return;
+ }
+
+ if (sta->flags & WI_SIFLAGS_DEASSOC) {
+ wihap_sta_disassoc(sc, sta->addr,
+ sta->reason);
+ sta->flags &= ~WI_SIFLAGS_ASSOC;
+ sta->flags &= ~WI_SIFLAGS_DEASSOC;
+ if (IF_IS_EMPTY(&sta->savedq)) {
+ wi_set_tim(sc, sta->asid, 0);
+ }
+ }
+
+ IF_DEQUEUE(&sta->savedq, m);
+ if (m == NULL) {
+ if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)
+ printf("station %6D sent pspoll, but no packets are "
+ "saved\n", rxfrm->wi_addr2, ":");
+ return;
+ }
+
+ /* If this is the last packet, turn off the TIM fields. */
+ if (IF_IS_EMPTY(&sta->savedq)) {
+ wi_set_tim(sc, sta->asid, 0);
+ }
+
+ if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)
+ printf("wihap_pspoll: sending saved packet for station %6D\n",
+ sta->addr, ":");
+
+ IF_ENQUEUE(&sc->wi_pwrsaveq, m);
+ (ifp->if_start)(ifp);
+ }
+
+
+
+ /* wihap_pwrsave()
+ *
+ * Handle packets that need to be saved for this station.
+ * Set the TIM bit to ensure that they will be picked up
+ * eventually.
+ */
+ static void
+ wihap_pwrsave(struct wi_softc *sc, struct wihap_sta_info *sta, struct mbuf *m)
+ {
+ if (IF_IS_EMPTY(&sta->savedq)) {
+ wi_set_tim(sc, sta->asid, 1);
+ }
+ if (sta->savedq.ifq_len >= WIHAP_PS_BUFFER) {
+ IF_DROP(&sta->savedq);
+ m_freem(m);
+ if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)
+ printf("wihap_pspoll: station %6Ds power save queue "
+ "overflow of size %d drops %d\n",
+ sta->addr, ":", WIHAP_PS_BUFFER,
+ sta->savedq.ifq_drops);
+ } else {
+ IF_ENQUEUE(&sta->savedq, m);
+ }
+ }
+
/* wihap_debug_frame_type()
*
* Print out frame type. Used in early debugging.
***************
*** 941,946 ****
--- 1124,1132 ----
pkt = mtod(m, caddr_t) + WI_802_11_OFFSET_RAW;
len = m->m_len - WI_802_11_OFFSET_RAW;
+ /* XXX: can the powersaving bit be set on a MGMT frame!? */
+ wihap_check_ps(sc, rxfrm, NULL);
+
if ((rxfrm->wi_frame_ctl & htole16(WI_FCTL_FTYPE)) ==
htole16(WI_FTYPE_MGMT)) {
***************
*** 976,983 ****
break;
}
splx(s);
}
-
m_freem(m);
}
--- 1162,1175 ----
break;
}
splx(s);
+ } else if ((rxfrm->wi_frame_ctl & htole16(WI_FCTL_FTYPE)) ==
+ htole16(WI_FTYPE_CTL) &&
+ (rxfrm->wi_frame_ctl & htole16(WI_FCTL_STYPE)) ==
+ htole16(WI_STYPE_CTL_PSPOLL)) {
+ s = splnet();
+ wihap_pspoll(sc, rxfrm, pkt, len);
+ splx(s);
}
m_freem(m);
}
***************
*** 1009,1015 ****
/* wihap_check_tx()
*
* Determine if a station is assoc'ed, get its tx rate, and update
! * its activity.
*/
int
wihap_check_tx(struct wihap_info *whi, u_int8_t addr[], u_int8_t *txrate)
--- 1201,1214 ----
/* wihap_check_tx()
*
* Determine if a station is assoc'ed, get its tx rate, and update
! * its activity. Check to see if the station is in power saving mode,
! * in which case we need to buffer the packet rather than sending it.
! * If this is a packet being sent in responce to a power-save poll,
! * see if there are more packets buffered for this station.
! *
! * XXX: There are a ridiculous number of arguments to this function;
! * it just seemed inefficient to do a second station lookup in another
! * function to check power saving.
*/
int
wihap_check_tx(struct wihap_info *whi, u_int8_t addr[], u_int8_t *txrate)
***************
*** 1034,1043 ****
return(1);
}
splx(s);
-
return(0);
}
/*
* wihap_data_input()
*
--- 1233,1266 ----
return(1);
}
splx(s);
return(0);
}
+ int
+ wihap_check_ps_queue(struct wi_softc *sc, struct mbuf *m, int power_save,
+ int *more)
+ {
+ struct wihap_info *whi = &sc->wi_hostap_info;
+ struct wihap_sta_info *sta;
+ struct ether_header *eh = mtod(m, struct ether_header *);
+ int s;
+
+ s = splnet();
+ sta = wihap_sta_find(whi, eh->ether_dhost);
+ if (sta == NULL)
+ return 1;
+
+ if (!power_save && (sta->flags & WI_SIFLAGS_PS)) {
+ wihap_pwrsave(sc, sta, m);
+ splx(s);
+ return 0;
+ } else if (power_save && !IF_IS_EMPTY(&sta->savedq)) {
+ *more = 1; /* set "More Data" bit on packet */
+ }
+ return 1;
+ }
+
+
/*
* wihap_data_input()
*
***************
*** 1096,1101 ****
--- 1319,1327 ----
hz * whi->inactivity_time);
sta->sig_info = le16toh(rxfrm->wi_q_info);
+ /* Check to see if we should go into powersaving mode */
+ wihap_check_ps(sc, rxfrm, sta);
+
splx(s);
/* Repeat this packet to BSS? */
***************
*** 1208,1214 ****
sta = wihap_sta_alloc(sc, reqsta.addr);
sta->flags = reqsta.flags;
sta->tmo = timeout(wihap_sta_timeout, sta,
! hz * whi->inactivity_time);
splx(s);
break;
--- 1434,1440 ----
sta = wihap_sta_alloc(sc, reqsta.addr);
sta->flags = reqsta.flags;
sta->tmo = timeout(wihap_sta_timeout, sta,
! hz * whi->inactivity_time);
splx(s);
break;
Index: wi_hostap.h
===================================================================
RCS file: /home/ncvs/src/sys/dev/wi/Attic/wi_hostap.h,v
retrieving revision 1.3.2.3
diff -c -r1.3.2.3 wi_hostap.h
*** wi_hostap.h 2002/08/02 07:11:34 1.3.2.3
--- wi_hostap.h 2003/03/31 05:20:56
***************
*** 35,41 ****
#ifndef __WI_HOSTAP_H__
#define __WI_HOSTAP_H__
! #define WIHAP_MAX_STATIONS 1800
struct hostap_sta {
u_int8_t addr[6];
--- 35,41 ----
#ifndef __WI_HOSTAP_H__
#define __WI_HOSTAP_H__
! #define WIHAP_MAX_STATIONS 254
struct hostap_sta {
u_int8_t addr[6];
***************
*** 49,55 ****
#define HOSTAP_FLAGS_AUTHEN 0x0001
#define HOSTAP_FLAGS_ASSOC 0x0002
#define HOSTAP_FLAGS_PERM 0x0004
! #define HOSTAP_FLAGS_BITS "\20\01ASSOC\02AUTH\03PERM"
#define SIOCHOSTAP_GET _IOWR('i', 210, struct ifreq)
#define SIOCHOSTAP_ADD _IOWR('i', 211, struct ifreq)
--- 49,57 ----
#define HOSTAP_FLAGS_AUTHEN 0x0001
#define HOSTAP_FLAGS_ASSOC 0x0002
#define HOSTAP_FLAGS_PERM 0x0004
! #define HOSTAP_FLAGS_PS 0x0008
! #define HOSTAP_FLAGS_DEASSOC 0x0010
! #define HOSTAP_FLAGS_BITS "\33\01ASSOC\02AUTH\03PERM\04PS\05DEASSOC"
#define SIOCHOSTAP_GET _IOWR('i', 210, struct ifreq)
#define SIOCHOSTAP_ADD _IOWR('i', 211, struct ifreq)
***************
*** 91,103 ****
u_int8_t tx_max_rate;
u_int32_t *challenge;
struct callout_handle tmo;
};
#define WI_SIFLAGS_ASSOC HOSTAP_FLAGS_ASSOC
#define WI_SIFLAGS_AUTHEN HOSTAP_FLAGS_AUTHEN
#define WI_SIFLAGS_PERM HOSTAP_FLAGS_PERM
! #define WI_STA_HASH_SIZE 113
#if WI_STA_HASH_SIZE*16 >= 2007 /* will generate ASID's too large. */
#error "WI_STA_HASH_SIZE too big"
--- 93,110 ----
u_int8_t tx_max_rate;
u_int32_t *challenge;
struct callout_handle tmo;
+
+ u_int16_t reason;
+ struct ifqueue savedq;
};
#define WI_SIFLAGS_ASSOC HOSTAP_FLAGS_ASSOC
#define WI_SIFLAGS_AUTHEN HOSTAP_FLAGS_AUTHEN
#define WI_SIFLAGS_PERM HOSTAP_FLAGS_PERM
+ #define WI_SIFLAGS_PS HOSTAP_FLAGS_PS
+ #define WI_SIFLAGS_DEASSOC HOSTAP_FLAGS_DEASSOC
! #define WI_STA_HASH_SIZE 17
#if WI_STA_HASH_SIZE*16 >= 2007 /* will generate ASID's too large. */
#error "WI_STA_HASH_SIZE too big"
***************
*** 120,125 ****
--- 127,133 ----
#define WIHAP_INTERVAL 5
#define WIHAP_DFLT_INACTIVITY_TIME 120 /* 2 minutes */
+ #define WIHAP_PS_BUFFER 50
struct wi_softc;
struct wi_frame;
***************
*** 128,136 ****
--- 136,165 ----
void wihap_mgmt_input(struct wi_softc *, struct wi_frame *, struct mbuf *);
int wihap_data_input(struct wi_softc *, struct wi_frame *, struct mbuf *);
int wihap_check_tx(struct wihap_info *, u_int8_t [], u_int8_t *);
+ int wihap_check_ps_queue(struct wi_softc *, struct mbuf *, int, int *);
void wihap_init(struct wi_softc *);
void wihap_shutdown(struct wi_softc *);
int wihap_ioctl(struct wi_softc *, u_long, caddr_t);
+
+ /*
+ * KML: I used these functions from NetBSD in the interests of getting
+ * this done, pronto. I'll clean it up later...
+ */
+
+ #define IF_PURGE(ifq) \
+ do { \
+ struct mbuf *__m0; \
+ \
+ for (;;) { \
+ IF_DEQUEUE((ifq), __m0); \
+ if (__m0 == NULL) \
+ break; \
+ else \
+ m_freem(__m0); \
+ } \
+ } while (/*CONSTCOND*/ 0)
+ #define IF_IS_EMPTY(ifq) ((ifq)->ifq_len == 0)
+
#endif /* _KERNEL */
#endif /* __WI_HOSTAP_H__ */
----- End forwarded message -----
--
Matt Peterson another.geek.without.a.life
[email protected] http://matt.peterson.org/
-------------------------------------------------
--
*bsd wireless list, a bawug thing <http://www.bawug.org/>
[un]subscribe: http://lists.bawug.org/mailman/listinfo/bsd-wireless/