diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-10-29 03:30:35 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-10-30 16:50:39 -0400 |
commit | eddcbb94f75c3e8944503e9f13c1d29acd0d7052 (patch) | |
tree | b5e4786dbafccea91d7ec42cb9e84af655414aca | |
parent | 750266646befe42ee8a3a9f9b6f692174635c5b8 (diff) |
mac80211: introduce ieee80211_beacon_get_tim()
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>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | include/net/mac80211.h | 42 | ||||
-rw-r--r-- | net/mac80211/tx.c | 17 |
2 files changed, 48 insertions, 11 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 2c9d3c719d8a..bd0bbc37a1ae 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -1743,19 +1743,45 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, | |||
1743 | struct sk_buff *skb); | 1743 | struct sk_buff *skb); |
1744 | 1744 | ||
1745 | /** | 1745 | /** |
1746 | * ieee80211_beacon_get - beacon generation function | 1746 | * ieee80211_beacon_get_tim - beacon generation function |
1747 | * @hw: pointer obtained from ieee80211_alloc_hw(). | 1747 | * @hw: pointer obtained from ieee80211_alloc_hw(). |
1748 | * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf. | 1748 | * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf. |
1749 | * @tim_offset: pointer to variable that will receive the TIM IE offset. | ||
1750 | * Set to 0 if invalid (in non-AP modes). | ||
1751 | * @tim_length: pointer to variable that will receive the TIM IE length, | ||
1752 | * (including the ID and length bytes!). | ||
1753 | * Set to 0 if invalid (in non-AP modes). | ||
1754 | * | ||
1755 | * If the driver implements beaconing modes, it must use this function to | ||
1756 | * obtain the beacon frame/template. | ||
1749 | * | 1757 | * |
1750 | * If the beacon frames are generated by the host system (i.e., not in | 1758 | * If the beacon frames are generated by the host system (i.e., not in |
1751 | * hardware/firmware), the low-level driver uses this function to receive | 1759 | * hardware/firmware), the driver uses this function to get each beacon |
1752 | * the next beacon frame from the 802.11 code. The low-level is responsible | 1760 | * frame from mac80211 -- it is responsible for calling this function |
1753 | * for calling this function before beacon data is needed (e.g., based on | 1761 | * before the beacon is needed (e.g. based on hardware interrupt). |
1754 | * hardware interrupt). Returned skb is used only once and low-level driver | 1762 | * |
1755 | * is responsible for freeing it. | 1763 | * If the beacon frames are generated by the device, then the driver |
1764 | * must use the returned beacon as the template and change the TIM IE | ||
1765 | * according to the current DTIM parameters/TIM bitmap. | ||
1766 | * | ||
1767 | * The driver is responsible for freeing the returned skb. | ||
1768 | */ | ||
1769 | struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | ||
1770 | struct ieee80211_vif *vif, | ||
1771 | u16 *tim_offset, u16 *tim_length); | ||
1772 | |||
1773 | /** | ||
1774 | * ieee80211_beacon_get - beacon generation function | ||
1775 | * @hw: pointer obtained from ieee80211_alloc_hw(). | ||
1776 | * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf. | ||
1777 | * | ||
1778 | * See ieee80211_beacon_get_tim(). | ||
1756 | */ | 1779 | */ |
1757 | struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | 1780 | static inline struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, |
1758 | struct ieee80211_vif *vif); | 1781 | struct ieee80211_vif *vif) |
1782 | { | ||
1783 | return ieee80211_beacon_get_tim(hw, vif, NULL, NULL); | ||
1784 | } | ||
1759 | 1785 | ||
1760 | /** | 1786 | /** |
1761 | * ieee80211_rts_get - RTS frame generation function | 1787 | * ieee80211_rts_get - RTS frame generation function |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index cb06d8e56496..8595d14c774c 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -2012,8 +2012,9 @@ static void ieee80211_beacon_add_tim(struct ieee80211_if_ap *bss, | |||
2012 | } | 2012 | } |
2013 | } | 2013 | } |
2014 | 2014 | ||
2015 | struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | 2015 | struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, |
2016 | struct ieee80211_vif *vif) | 2016 | struct ieee80211_vif *vif, |
2017 | u16 *tim_offset, u16 *tim_length) | ||
2017 | { | 2018 | { |
2018 | struct ieee80211_local *local = hw_to_local(hw); | 2019 | struct ieee80211_local *local = hw_to_local(hw); |
2019 | struct sk_buff *skb = NULL; | 2020 | struct sk_buff *skb = NULL; |
@@ -2030,6 +2031,11 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
2030 | 2031 | ||
2031 | sdata = vif_to_sdata(vif); | 2032 | sdata = vif_to_sdata(vif); |
2032 | 2033 | ||
2034 | if (tim_offset) | ||
2035 | *tim_offset = 0; | ||
2036 | if (tim_length) | ||
2037 | *tim_length = 0; | ||
2038 | |||
2033 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | 2039 | if (sdata->vif.type == NL80211_IFTYPE_AP) { |
2034 | ap = &sdata->u.ap; | 2040 | ap = &sdata->u.ap; |
2035 | beacon = rcu_dereference(ap->beacon); | 2041 | beacon = rcu_dereference(ap->beacon); |
@@ -2065,6 +2071,11 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
2065 | spin_unlock_irqrestore(&local->sta_lock, flags); | 2071 | spin_unlock_irqrestore(&local->sta_lock, flags); |
2066 | } | 2072 | } |
2067 | 2073 | ||
2074 | if (tim_offset) | ||
2075 | *tim_offset = beacon->head_len; | ||
2076 | if (tim_length) | ||
2077 | *tim_length = skb->len - beacon->head_len; | ||
2078 | |||
2068 | if (beacon->tail) | 2079 | if (beacon->tail) |
2069 | memcpy(skb_put(skb, beacon->tail_len), | 2080 | memcpy(skb_put(skb, beacon->tail_len), |
2070 | beacon->tail, beacon->tail_len); | 2081 | beacon->tail, beacon->tail_len); |
@@ -2141,7 +2152,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
2141 | rcu_read_unlock(); | 2152 | rcu_read_unlock(); |
2142 | return skb; | 2153 | return skb; |
2143 | } | 2154 | } |
2144 | EXPORT_SYMBOL(ieee80211_beacon_get); | 2155 | EXPORT_SYMBOL(ieee80211_beacon_get_tim); |
2145 | 2156 | ||
2146 | void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 2157 | void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
2147 | const void *frame, size_t frame_len, | 2158 | const void *frame, size_t frame_len, |