aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/ieee80211_sta.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index f1edaa0c0da3..d1f7199a2083 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -63,6 +63,8 @@
63#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002 63#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
64#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C 64#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
65#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0 65#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0
66#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
67#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
66 68
67/* next values represent the buffer size for A-MPDU frame. 69/* next values represent the buffer size for A-MPDU frame.
68 * According to IEEE802.11n spec size varies from 8K to 64K (in powers of 2) */ 70 * According to IEEE802.11n spec size varies from 8K to 64K (in powers of 2) */
@@ -1264,6 +1266,36 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid,
1264 sta_info_put(sta); 1266 sta_info_put(sta);
1265} 1267}
1266 1268
1269static void ieee80211_sta_process_delba(struct net_device *dev,
1270 struct ieee80211_mgmt *mgmt, size_t len)
1271{
1272 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1273 struct sta_info *sta;
1274 u16 tid, params;
1275 u16 initiator;
1276 DECLARE_MAC_BUF(mac);
1277
1278 sta = sta_info_get(local, mgmt->sa);
1279 if (!sta)
1280 return;
1281
1282 params = le16_to_cpu(mgmt->u.action.u.delba.params);
1283 tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12;
1284 initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11;
1285
1286#ifdef CONFIG_MAC80211_HT_DEBUG
1287 if (net_ratelimit())
1288 printk(KERN_DEBUG "delba from %s on tid %d reason code %d\n",
1289 print_mac(mac, mgmt->sa), tid,
1290 mgmt->u.action.u.delba.reason_code);
1291#endif /* CONFIG_MAC80211_HT_DEBUG */
1292
1293 if (initiator == WLAN_BACK_INITIATOR)
1294 ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid,
1295 WLAN_BACK_INITIATOR, 0);
1296 sta_info_put(sta);
1297}
1298
1267/* 1299/*
1268 * After receiving Block Ack Request (BAR) we activated a 1300 * After receiving Block Ack Request (BAR) we activated a
1269 * timer after each frame arrives from the originator. 1301 * timer after each frame arrives from the originator.
@@ -2204,9 +2236,15 @@ static void ieee80211_rx_mgmt_action(struct net_device *dev,
2204 break; 2236 break;
2205 ieee80211_sta_process_addba_request(dev, mgmt, len); 2237 ieee80211_sta_process_addba_request(dev, mgmt, len);
2206 break; 2238 break;
2239 case WLAN_ACTION_DELBA:
2240 if (len < (IEEE80211_MIN_ACTION_SIZE +
2241 sizeof(mgmt->u.action.u.delba)))
2242 break;
2243 ieee80211_sta_process_delba(dev, mgmt, len);
2244 break;
2207 default: 2245 default:
2208 if (net_ratelimit()) 2246 if (net_ratelimit())
2209 printk(KERN_DEBUG "%s: received unsupported BACK\n", 2247 printk(KERN_DEBUG "%s: Rx unknown A-MPDU action\n",
2210 dev->name); 2248 dev->name);
2211 break; 2249 break;
2212 } 2250 }