public inbox for linux-wireless@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] mac80211: introduce ieee80211_beacon_get_tim()
@ 2009-10-29  7:30 Johannes Berg
  0 siblings, 0 replies; only message in thread
From: Johannes Berg @ 2009-10-29  7:30 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

Compared to ieee80211_beacon_get(), the new function
ieee80211_beacon_get_tim() returns information on the
location and length of the TIM IE, which some drivers
need in order to generate the TIM on the device. The
old function, ieee80211_beacon_get(), becomes a small
static inline wrapper around the new one to not break
all drivers.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
Will allow a cleanup of a number of drivers ... that parsing code has
irked me for a while now. But for now I'll leave it to the driver
maintainers to use this new function :)

 include/net/mac80211.h |   42 ++++++++++++++++++++++++++++++++++--------
 net/mac80211/tx.c      |   17 ++++++++++++++---
 2 files changed, 48 insertions(+), 11 deletions(-)

--- wireless-testing.orig/include/net/mac80211.h	2009-10-29 08:26:31.000000000 +0100
+++ wireless-testing/include/net/mac80211.h	2009-10-29 08:27:27.000000000 +0100
@@ -1743,19 +1743,45 @@ void ieee80211_tx_status_irqsafe(struct 
 				 struct sk_buff *skb);
 
 /**
- * ieee80211_beacon_get - beacon generation function
+ * ieee80211_beacon_get_tim - beacon generation function
  * @hw: pointer obtained from ieee80211_alloc_hw().
  * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
+ * @tim_offset: pointer to variable that will receive the TIM IE offset.
+ *	Set to 0 if invalid (in non-AP modes).
+ * @tim_length: pointer to variable that will receive the TIM IE length,
+ *	(including the ID and length bytes!).
+ *	Set to 0 if invalid (in non-AP modes).
+ *
+ * If the driver implements beaconing modes, it must use this function to
+ * obtain the beacon frame/template.
  *
  * If the beacon frames are generated by the host system (i.e., not in
- * hardware/firmware), the low-level driver uses this function to receive
- * the next beacon frame from the 802.11 code. The low-level is responsible
- * for calling this function before beacon data is needed (e.g., based on
- * hardware interrupt). Returned skb is used only once and low-level driver
- * is responsible for freeing it.
+ * hardware/firmware), the driver uses this function to get each beacon
+ * frame from mac80211 -- it is responsible for calling this function
+ * before the beacon is needed (e.g. based on hardware interrupt).
+ *
+ * If the beacon frames are generated by the device, then the driver
+ * must use the returned beacon as the template and change the TIM IE
+ * according to the current DTIM parameters/TIM bitmap.
+ *
+ * The driver is responsible for freeing the returned skb.
+ */
+struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
+					 struct ieee80211_vif *vif,
+					 u16 *tim_offset, u16 *tim_length);
+
+/**
+ * ieee80211_beacon_get - beacon generation function
+ * @hw: pointer obtained from ieee80211_alloc_hw().
+ * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
+ *
+ * See ieee80211_beacon_get_tim().
  */
-struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
-				     struct ieee80211_vif *vif);
+static inline struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
+						   struct ieee80211_vif *vif)
+{
+	return ieee80211_beacon_get_tim(hw, vif, NULL, NULL);
+}
 
 /**
  * ieee80211_rts_get - RTS frame generation function
--- wireless-testing.orig/net/mac80211/tx.c	2009-10-29 08:26:31.000000000 +0100
+++ wireless-testing/net/mac80211/tx.c	2009-10-29 08:27:27.000000000 +0100
@@ -2012,8 +2012,9 @@ static void ieee80211_beacon_add_tim(str
 	}
 }
 
-struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
-				     struct ieee80211_vif *vif)
+struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
+					 struct ieee80211_vif *vif,
+					 u16 *tim_offset, u16 *tim_length)
 {
 	struct ieee80211_local *local = hw_to_local(hw);
 	struct sk_buff *skb = NULL;
@@ -2030,6 +2031,11 @@ struct sk_buff *ieee80211_beacon_get(str
 
 	sdata = vif_to_sdata(vif);
 
+	if (tim_offset)
+		*tim_offset = 0;
+	if (tim_length)
+		*tim_length = 0;
+
 	if (sdata->vif.type == NL80211_IFTYPE_AP) {
 		ap = &sdata->u.ap;
 		beacon = rcu_dereference(ap->beacon);
@@ -2065,6 +2071,11 @@ struct sk_buff *ieee80211_beacon_get(str
 				spin_unlock_irqrestore(&local->sta_lock, flags);
 			}
 
+			if (tim_offset)
+				*tim_offset = beacon->head_len;
+			if (tim_length)
+				*tim_length = skb->len - beacon->head_len;
+
 			if (beacon->tail)
 				memcpy(skb_put(skb, beacon->tail_len),
 				       beacon->tail, beacon->tail_len);
@@ -2141,7 +2152,7 @@ struct sk_buff *ieee80211_beacon_get(str
 	rcu_read_unlock();
 	return skb;
 }
-EXPORT_SYMBOL(ieee80211_beacon_get);
+EXPORT_SYMBOL(ieee80211_beacon_get_tim);
 
 void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		       const void *frame, size_t frame_len,



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2009-10-29  7:31 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-10-29  7:30 [PATCH] mac80211: introduce ieee80211_beacon_get_tim() Johannes Berg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox