diff options
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index d3a44812f8bf..055b45b146d9 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -2200,6 +2200,84 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2200 | } | 2200 | } |
2201 | EXPORT_SYMBOL(ieee80211_beacon_get_tim); | 2201 | EXPORT_SYMBOL(ieee80211_beacon_get_tim); |
2202 | 2202 | ||
2203 | struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw, | ||
2204 | struct ieee80211_vif *vif) | ||
2205 | { | ||
2206 | struct ieee80211_sub_if_data *sdata; | ||
2207 | struct ieee80211_if_managed *ifmgd; | ||
2208 | struct ieee80211_pspoll *pspoll; | ||
2209 | struct ieee80211_local *local; | ||
2210 | struct sk_buff *skb; | ||
2211 | |||
2212 | if (WARN_ON(vif->type != NL80211_IFTYPE_STATION)) | ||
2213 | return NULL; | ||
2214 | |||
2215 | sdata = vif_to_sdata(vif); | ||
2216 | ifmgd = &sdata->u.mgd; | ||
2217 | local = sdata->local; | ||
2218 | |||
2219 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*pspoll)); | ||
2220 | if (!skb) { | ||
2221 | printk(KERN_DEBUG "%s: failed to allocate buffer for " | ||
2222 | "pspoll template\n", sdata->name); | ||
2223 | return NULL; | ||
2224 | } | ||
2225 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
2226 | |||
2227 | pspoll = (struct ieee80211_pspoll *) skb_put(skb, sizeof(*pspoll)); | ||
2228 | memset(pspoll, 0, sizeof(*pspoll)); | ||
2229 | pspoll->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | | ||
2230 | IEEE80211_STYPE_PSPOLL); | ||
2231 | pspoll->aid = cpu_to_le16(ifmgd->aid); | ||
2232 | |||
2233 | /* aid in PS-Poll has its two MSBs each set to 1 */ | ||
2234 | pspoll->aid |= cpu_to_le16(1 << 15 | 1 << 14); | ||
2235 | |||
2236 | memcpy(pspoll->bssid, ifmgd->bssid, ETH_ALEN); | ||
2237 | memcpy(pspoll->ta, vif->addr, ETH_ALEN); | ||
2238 | |||
2239 | return skb; | ||
2240 | } | ||
2241 | EXPORT_SYMBOL(ieee80211_pspoll_get); | ||
2242 | |||
2243 | struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw, | ||
2244 | struct ieee80211_vif *vif) | ||
2245 | { | ||
2246 | struct ieee80211_hdr_3addr *nullfunc; | ||
2247 | struct ieee80211_sub_if_data *sdata; | ||
2248 | struct ieee80211_if_managed *ifmgd; | ||
2249 | struct ieee80211_local *local; | ||
2250 | struct sk_buff *skb; | ||
2251 | |||
2252 | if (WARN_ON(vif->type != NL80211_IFTYPE_STATION)) | ||
2253 | return NULL; | ||
2254 | |||
2255 | sdata = vif_to_sdata(vif); | ||
2256 | ifmgd = &sdata->u.mgd; | ||
2257 | local = sdata->local; | ||
2258 | |||
2259 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*nullfunc)); | ||
2260 | if (!skb) { | ||
2261 | printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc " | ||
2262 | "template\n", sdata->name); | ||
2263 | return NULL; | ||
2264 | } | ||
2265 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
2266 | |||
2267 | nullfunc = (struct ieee80211_hdr_3addr *) skb_put(skb, | ||
2268 | sizeof(*nullfunc)); | ||
2269 | memset(nullfunc, 0, sizeof(*nullfunc)); | ||
2270 | nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | | ||
2271 | IEEE80211_STYPE_NULLFUNC | | ||
2272 | IEEE80211_FCTL_TODS); | ||
2273 | memcpy(nullfunc->addr1, ifmgd->bssid, ETH_ALEN); | ||
2274 | memcpy(nullfunc->addr2, vif->addr, ETH_ALEN); | ||
2275 | memcpy(nullfunc->addr3, ifmgd->bssid, ETH_ALEN); | ||
2276 | |||
2277 | return skb; | ||
2278 | } | ||
2279 | EXPORT_SYMBOL(ieee80211_nullfunc_get); | ||
2280 | |||
2203 | void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 2281 | void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
2204 | const void *frame, size_t frame_len, | 2282 | const void *frame, size_t frame_len, |
2205 | const struct ieee80211_tx_info *frame_txctl, | 2283 | const struct ieee80211_tx_info *frame_txctl, |