diff options
Diffstat (limited to 'net/mac80211/ht.c')
-rw-r--r-- | net/mac80211/ht.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 45ebd062a2fb..63b8f86b7f16 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -166,3 +166,50 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | |||
166 | spin_unlock_bh(&sta->lock); | 166 | spin_unlock_bh(&sta->lock); |
167 | } | 167 | } |
168 | } | 168 | } |
169 | |||
170 | int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, | ||
171 | enum ieee80211_smps_mode smps, const u8 *da, | ||
172 | const u8 *bssid) | ||
173 | { | ||
174 | struct ieee80211_local *local = sdata->local; | ||
175 | struct sk_buff *skb; | ||
176 | struct ieee80211_mgmt *action_frame; | ||
177 | |||
178 | /* 27 = header + category + action + smps mode */ | ||
179 | skb = dev_alloc_skb(27 + local->hw.extra_tx_headroom); | ||
180 | if (!skb) | ||
181 | return -ENOMEM; | ||
182 | |||
183 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
184 | action_frame = (void *)skb_put(skb, 27); | ||
185 | memcpy(action_frame->da, da, ETH_ALEN); | ||
186 | memcpy(action_frame->sa, sdata->dev->dev_addr, ETH_ALEN); | ||
187 | memcpy(action_frame->bssid, bssid, ETH_ALEN); | ||
188 | action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | ||
189 | IEEE80211_STYPE_ACTION); | ||
190 | action_frame->u.action.category = WLAN_CATEGORY_HT; | ||
191 | action_frame->u.action.u.ht_smps.action = WLAN_HT_ACTION_SMPS; | ||
192 | switch (smps) { | ||
193 | case IEEE80211_SMPS_AUTOMATIC: | ||
194 | case IEEE80211_SMPS_NUM_MODES: | ||
195 | WARN_ON(1); | ||
196 | case IEEE80211_SMPS_OFF: | ||
197 | action_frame->u.action.u.ht_smps.smps_control = | ||
198 | WLAN_HT_SMPS_CONTROL_DISABLED; | ||
199 | break; | ||
200 | case IEEE80211_SMPS_STATIC: | ||
201 | action_frame->u.action.u.ht_smps.smps_control = | ||
202 | WLAN_HT_SMPS_CONTROL_STATIC; | ||
203 | break; | ||
204 | case IEEE80211_SMPS_DYNAMIC: | ||
205 | action_frame->u.action.u.ht_smps.smps_control = | ||
206 | WLAN_HT_SMPS_CONTROL_DYNAMIC; | ||
207 | break; | ||
208 | } | ||
209 | |||
210 | /* we'll do more on status of this frame */ | ||
211 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
212 | ieee80211_tx_skb(sdata, skb); | ||
213 | |||
214 | return 0; | ||
215 | } | ||