From cace2ba154790fd3de5869905b8de59f1e3f6d52 Mon Sep 17 00:00:00 2001 From: Damien Bergamini Date: Tue, 3 Jul 2007 20:25:34 +0000 Subject: maintain the traffic-indication (TIM) virtual bitmap by defining a default ieee80211_set_tim() function that drivers can override by setting ic_set_tim. --- sys/net80211/ieee80211.c | 3 ++- sys/net80211/ieee80211_input.c | 21 +++++++++------------ sys/net80211/ieee80211_node.c | 18 +++++++++++++++--- sys/net80211/ieee80211_output.c | 28 +++++++++++----------------- sys/net80211/ieee80211_var.h | 4 ++-- 5 files changed, 39 insertions(+), 35 deletions(-) (limited to 'sys') diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c index 605e7f9b219..235cfd47c30 100644 --- a/sys/net80211/ieee80211.c +++ b/sys/net80211/ieee80211.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211.c,v 1.23 2007/06/16 13:17:05 damien Exp $ */ +/* $OpenBSD: ieee80211.c,v 1.24 2007/07/03 20:25:32 damien Exp $ */ /* $NetBSD: ieee80211.c,v 1.19 2004/06/06 05:45:29 dyoung Exp $ */ /*- @@ -146,6 +146,7 @@ ieee80211_ifattach(struct ifnet *ifp) if (ic->ic_lintval == 0) ic->ic_lintval = 100; /* default sleep */ ic->ic_bmisstimeout = 7*ic->ic_lintval; /* default 7 beacons */ + ic->ic_dtim_period = 1; /* all TIMs are DTIMs */ LIST_INSERT_HEAD(&ieee80211com_head, ic, ic_list); ieee80211_node_attach(ifp); diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c index 1b595d7dc8d..0b25d676310 100644 --- a/sys/net80211/ieee80211_input.c +++ b/sys/net80211/ieee80211_input.c @@ -1,5 +1,5 @@ /* $NetBSD: ieee80211_input.c,v 1.24 2004/05/31 11:12:24 dyoung Exp $ */ -/* $OpenBSD: ieee80211_input.c,v 1.34 2007/07/03 17:04:13 damien Exp $ */ +/* $OpenBSD: ieee80211_input.c,v 1.35 2007/07/03 20:25:32 damien Exp $ */ /*- * Copyright (c) 2001 Atsushi Onoe * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting @@ -186,8 +186,8 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni, } if (ic->ic_set_tim != NULL && - (wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) - && ni->ni_pwrsave == 0) { + (wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) && + ni->ni_pwrsave == 0) { /* turn on power save mode */ if (ifp->if_flags & IFF_DEBUG) @@ -197,13 +197,12 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni, ni->ni_pwrsave = IEEE80211_PS_SLEEP; } if (ic->ic_set_tim != NULL && - (wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) == 0 && + !(wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) && ni->ni_pwrsave != 0) { /* turn off power save mode, dequeue stored packets */ ni->ni_pwrsave = 0; - if (ic->ic_set_tim) - ic->ic_set_tim(ic, ni->ni_associd, 0); + (*ic->ic_set_tim)(ic, ni->ni_associd, 0); if (ifp->if_flags & IFF_DEBUG) printf("%s: power save mode off for %s\n", @@ -2008,7 +2007,7 @@ ieee80211_recv_pspoll(struct ieee80211com *ic, struct mbuf *m0, int rssi, struct mbuf *m; u_int16_t aid; - if (ic->ic_set_tim == NULL) /* No powersaving functionality */ + if (ic->ic_set_tim == NULL) /* no powersaving functionality */ return; wh = mtod(m0, struct ieee80211_frame *); @@ -2053,12 +2052,10 @@ ieee80211_recv_pspoll(struct ieee80211com *ic, struct mbuf *m0, int rssi, * If there are more packets, set the more packets bit. */ - if (IF_IS_EMPTY(&ni->ni_savedq)) { - if (ic->ic_set_tim) - ic->ic_set_tim(ic, ni->ni_associd, 0); - } else { + if (IF_IS_EMPTY(&ni->ni_savedq)) + (*ic->ic_set_tim)(ic, ni->ni_associd, 0); + else wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA; - } if (ifp->if_flags & IFF_DEBUG) printf("%s: enqueued power saving packet for station %s\n", diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index de4ee19c471..d8ef5c76e30 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_node.c,v 1.25 2007/07/02 16:46:44 damien Exp $ */ +/* $OpenBSD: ieee80211_node.c,v 1.26 2007/07/03 20:25:32 damien Exp $ */ /* $NetBSD: ieee80211_node.c,v 1.14 2004/05/09 09:18:47 dyoung Exp $ */ /*- @@ -81,6 +81,7 @@ struct ieee80211_node *ieee80211_alloc_node_helper(struct ieee80211com *); void ieee80211_node_cleanup(struct ieee80211com *, struct ieee80211_node *); void ieee80211_node_join_11g(struct ieee80211com *, struct ieee80211_node *); void ieee80211_node_leave_11g(struct ieee80211com *, struct ieee80211_node *); +void ieee80211_set_tim(struct ieee80211com *, int, int); #define M_80211_NODE M_DEVBUF @@ -118,8 +119,10 @@ ieee80211_node_attach(struct ifnet *ifp) if (ic->ic_tim_bitmap == NULL) { printf("%s: no memory for TIM bitmap!\n", __func__); ic->ic_tim_len = 0; - } else + } else { memset(ic->ic_tim_bitmap, 0, ic->ic_tim_len); + ic->ic_set_tim = ieee80211_set_tim; + } } } @@ -833,7 +836,7 @@ ieee80211_free_node(struct ieee80211com *ic, struct ieee80211_node *ni) ic->ic_nnodes--; if (!IF_IS_EMPTY(&ni->ni_savedq)) { IF_PURGE(&ni->ni_savedq); - if (ic->ic_set_tim) + if (ic->ic_set_tim != NULL) (*ic->ic_set_tim)(ic, ni->ni_associd, 0); } if (RB_EMPTY(&ic->ic_tree)) @@ -1139,6 +1142,15 @@ ieee80211_node_leave(struct ieee80211com *ic, struct ieee80211_node *ni) #endif } +void +ieee80211_set_tim(struct ieee80211com *ic, int aid, int set) +{ + if (set) + setbit(ic->ic_tim_bitmap, aid & ~0xc000); + else + clrbit(ic->ic_tim_bitmap, aid & ~0xc000); +} + /* * Compare nodes in the tree by lladdr */ diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c index 953b44f94fc..1af78c664aa 100644 --- a/sys/net80211/ieee80211_output.c +++ b/sys/net80211/ieee80211_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_output.c,v 1.38 2007/07/03 19:44:54 damien Exp $ */ +/* $OpenBSD: ieee80211_output.c,v 1.39 2007/07/03 20:25:32 damien Exp $ */ /* $NetBSD: ieee80211_output.c,v 1.13 2004/05/31 11:02:55 dyoung Exp $ */ /*- @@ -1421,7 +1421,7 @@ ieee80211_beacon_alloc(struct ieee80211com *ic, struct ieee80211_node *ni) 2 + ni->ni_esslen + /* ssid */ 2 + IEEE80211_RATE_SIZE + /* supported rates */ 2 + 1 + /* parameter set (DS) */ - 6 + /* parameter set (IBSS/TIM) */ + 2 + 254 + /* parameter set (IBSS/TIM) */ 2 + 1 + /* extended rate phy (ERP) */ 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) + 2 + 18); /* parameter set (EDCA) */ @@ -1457,17 +1457,11 @@ ieee80211_beacon_alloc(struct ieee80211com *ic, struct ieee80211_node *ni) else frm = ieee80211_add_ds_params(frm, ic, ni); - if (ic->ic_opmode == IEEE80211_M_IBSS) { + if (ic->ic_opmode == IEEE80211_M_IBSS) frm = ieee80211_add_ibss_params(frm, ni); - } else { - /* TODO: TIM */ - *frm++ = IEEE80211_ELEMID_TIM; - *frm++ = 4; /* length */ - *frm++ = 0; /* DTIM count */ - *frm++ = 1; /* DTIM period */ - *frm++ = 0; /* bitmap control */ - *frm++ = 0; /* Partial Virtual Bitmap (variable length) */ - } + else + frm = ieee80211_add_tim(frm, ic); + if (ic->ic_curmode == IEEE80211_MODE_11G) frm = ieee80211_add_erp(frm, ic); frm = ieee80211_add_xrates(frm, rs); @@ -1484,11 +1478,10 @@ void ieee80211_pwrsave(struct ieee80211com *ic, struct ieee80211_node *ni, struct mbuf *m) { - /* Store the new packet on our queue, changing the TIM if necessary */ + /* store the new packet on our queue, changing the TIM if necessary */ + if (IF_IS_EMPTY(&ni->ni_savedq)) + (*ic->ic_set_tim)(ic, ni->ni_associd, 1); - if (IF_IS_EMPTY(&ni->ni_savedq)) { - ic->ic_set_tim(ic, ni->ni_associd, 1); - } if (ni->ni_savedq.ifq_len >= IEEE80211_PS_MAX_QUEUE) { IF_DROP(&ni->ni_savedq); m_freem(m); @@ -1500,7 +1493,8 @@ ieee80211_pwrsave(struct ieee80211com *ic, struct ieee80211_node *ni, IEEE80211_PS_MAX_QUEUE, ni->ni_savedq.ifq_drops); } else { - /* Similar to ieee80211_mgmt_output, store the node in + /* + * Similar to ieee80211_mgmt_output, store the node in * the rcvif field. */ IF_ENQUEUE(&ni->ni_savedq, m); diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index 12ca583d61a..bdfb86236f5 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_var.h,v 1.26 2007/07/02 16:46:44 damien Exp $ */ +/* $OpenBSD: ieee80211_var.h,v 1.27 2007/07/03 20:25:33 damien Exp $ */ /* $NetBSD: ieee80211_var.h,v 1.7 2004/05/06 03:07:10 dyoung Exp $ */ /*- @@ -187,7 +187,7 @@ struct ieee80211com { struct ieee80211_node *, int); void (*ic_updateslot)(struct ieee80211com *); void (*ic_updateedca)(struct ieee80211com *); - int (*ic_set_tim)(struct ieee80211com *, int, int); + void (*ic_set_tim)(struct ieee80211com *, int, int); u_int8_t ic_myaddr[IEEE80211_ADDR_LEN]; struct ieee80211_rateset ic_sup_rates[IEEE80211_MODE_MAX]; struct ieee80211_channel ic_channels[IEEE80211_CHAN_MAX+1]; -- cgit v1.2.3