agg-rx.c (06e65cb322f91dc20fbcfc1a7ee2fb105ecc417b) agg-rx.c (e87cc4728f0e2fb663e592a1141742b1d6c63256)
1/*
2 * HT handling
3 *
4 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
5 * Copyright 2002-2005, Instant802 Networks, Inc.
6 * Copyright 2005-2006, Devicescape Software, Inc.
7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>

--- 128 unchanged lines hidden (view full) ---

137 /* not an elegant detour, but there is no choice as the timer passes
138 * only one argument, and various sta_info are needed here, so init
139 * flow in sta_info_create gives the TID as data, while the timer_to_id
140 * array gives the sta through container_of */
141 u8 *ptid = (u8 *)data;
142 u8 *timer_to_id = ptid - *ptid;
143 struct sta_info *sta = container_of(timer_to_id, struct sta_info,
144 timer_to_tid[0]);
1/*
2 * HT handling
3 *
4 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
5 * Copyright 2002-2005, Instant802 Networks, Inc.
6 * Copyright 2005-2006, Devicescape Software, Inc.
7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>

--- 128 unchanged lines hidden (view full) ---

137 /* not an elegant detour, but there is no choice as the timer passes
138 * only one argument, and various sta_info are needed here, so init
139 * flow in sta_info_create gives the TID as data, while the timer_to_id
140 * array gives the sta through container_of */
141 u8 *ptid = (u8 *)data;
142 u8 *timer_to_id = ptid - *ptid;
143 struct sta_info *sta = container_of(timer_to_id, struct sta_info,
144 timer_to_tid[0]);
145 struct tid_ampdu_rx *tid_rx;
146 unsigned long timeout;
145
147
148 tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[*ptid]);
149 if (!tid_rx)
150 return;
151
152 timeout = tid_rx->last_rx + TU_TO_JIFFIES(tid_rx->timeout);
153 if (time_is_after_jiffies(timeout)) {
154 mod_timer(&tid_rx->session_timer, timeout);
155 return;
156 }
157
146#ifdef CONFIG_MAC80211_HT_DEBUG
147 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
148#endif
149 set_bit(*ptid, sta->ampdu_mlme.tid_rx_timer_expired);
150 ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work);
151}
152
153static void sta_rx_agg_reorder_timer_expired(unsigned long data)

--- 89 unchanged lines hidden (view full) ---

243 * check if configuration can support the BA policy
244 * and if buffer size does not exceeds max value */
245 /* XXX: check own ht delayed BA capability?? */
246 if (((ba_policy != 1) &&
247 (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA))) ||
248 (buf_size > IEEE80211_MAX_AMPDU_BUF)) {
249 status = WLAN_STATUS_INVALID_QOS_PARAM;
250#ifdef CONFIG_MAC80211_HT_DEBUG
158#ifdef CONFIG_MAC80211_HT_DEBUG
159 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
160#endif
161 set_bit(*ptid, sta->ampdu_mlme.tid_rx_timer_expired);
162 ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work);
163}
164
165static void sta_rx_agg_reorder_timer_expired(unsigned long data)

--- 89 unchanged lines hidden (view full) ---

255 * check if configuration can support the BA policy
256 * and if buffer size does not exceeds max value */
257 /* XXX: check own ht delayed BA capability?? */
258 if (((ba_policy != 1) &&
259 (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA))) ||
260 (buf_size > IEEE80211_MAX_AMPDU_BUF)) {
261 status = WLAN_STATUS_INVALID_QOS_PARAM;
262#ifdef CONFIG_MAC80211_HT_DEBUG
251 if (net_ratelimit())
252 printk(KERN_DEBUG "AddBA Req with bad params from "
253 "%pM on tid %u. policy %d, buffer size %d\n",
254 mgmt->sa, tid, ba_policy,
255 buf_size);
263 net_dbg_ratelimited("AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d\n",
264 mgmt->sa, tid, ba_policy, buf_size);
256#endif /* CONFIG_MAC80211_HT_DEBUG */
257 goto end_no_lock;
258 }
259 /* determine default buffer size */
260 if (buf_size == 0)
261 buf_size = IEEE80211_MAX_AMPDU_BUF;
262
263 /* make sure the size doesn't exceed the maximum supported by the hw */
264 if (buf_size > local->hw.max_rx_aggregation_subframes)
265 buf_size = local->hw.max_rx_aggregation_subframes;
266
267 /* examine state machine */
268 mutex_lock(&sta->ampdu_mlme.mtx);
269
270 if (sta->ampdu_mlme.tid_rx[tid]) {
271#ifdef CONFIG_MAC80211_HT_DEBUG
265#endif /* CONFIG_MAC80211_HT_DEBUG */
266 goto end_no_lock;
267 }
268 /* determine default buffer size */
269 if (buf_size == 0)
270 buf_size = IEEE80211_MAX_AMPDU_BUF;
271
272 /* make sure the size doesn't exceed the maximum supported by the hw */
273 if (buf_size > local->hw.max_rx_aggregation_subframes)
274 buf_size = local->hw.max_rx_aggregation_subframes;
275
276 /* examine state machine */
277 mutex_lock(&sta->ampdu_mlme.mtx);
278
279 if (sta->ampdu_mlme.tid_rx[tid]) {
280#ifdef CONFIG_MAC80211_HT_DEBUG
272 if (net_ratelimit())
273 printk(KERN_DEBUG "unexpected AddBA Req from "
274 "%pM on tid %u\n",
275 mgmt->sa, tid);
281 net_dbg_ratelimited("unexpected AddBA Req from %pM on tid %u\n",
282 mgmt->sa, tid);
276#endif /* CONFIG_MAC80211_HT_DEBUG */
277
278 /* delete existing Rx BA session on the same tid */
279 ___ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
280 WLAN_STATUS_UNSPECIFIED_QOS,
281 false);
282 }
283
284 /* prepare A-MPDU MLME for Rx aggregation */
285 tid_agg_rx = kmalloc(sizeof(struct tid_ampdu_rx), GFP_KERNEL);
286 if (!tid_agg_rx)
287 goto end;
288
289 spin_lock_init(&tid_agg_rx->reorder_lock);
290
291 /* rx timer */
292 tid_agg_rx->session_timer.function = sta_rx_agg_session_timer_expired;
293 tid_agg_rx->session_timer.data = (unsigned long)&sta->timer_to_tid[tid];
283#endif /* CONFIG_MAC80211_HT_DEBUG */
284
285 /* delete existing Rx BA session on the same tid */
286 ___ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
287 WLAN_STATUS_UNSPECIFIED_QOS,
288 false);
289 }
290
291 /* prepare A-MPDU MLME for Rx aggregation */
292 tid_agg_rx = kmalloc(sizeof(struct tid_ampdu_rx), GFP_KERNEL);
293 if (!tid_agg_rx)
294 goto end;
295
296 spin_lock_init(&tid_agg_rx->reorder_lock);
297
298 /* rx timer */
299 tid_agg_rx->session_timer.function = sta_rx_agg_session_timer_expired;
300 tid_agg_rx->session_timer.data = (unsigned long)&sta->timer_to_tid[tid];
294 init_timer(&tid_agg_rx->session_timer);
301 init_timer_deferrable(&tid_agg_rx->session_timer);
295
296 /* rx reorder timer */
297 tid_agg_rx->reorder_timer.function = sta_rx_agg_reorder_timer_expired;
298 tid_agg_rx->reorder_timer.data = (unsigned long)&sta->timer_to_tid[tid];
299 init_timer(&tid_agg_rx->reorder_timer);
300
301 /* prepare reordering buffer */
302 tid_agg_rx->reorder_buf =

--- 27 unchanged lines hidden (view full) ---

330 tid_agg_rx->buf_size = buf_size;
331 tid_agg_rx->timeout = timeout;
332 tid_agg_rx->stored_mpdu_num = 0;
333 status = WLAN_STATUS_SUCCESS;
334
335 /* activate it for RX */
336 rcu_assign_pointer(sta->ampdu_mlme.tid_rx[tid], tid_agg_rx);
337
302
303 /* rx reorder timer */
304 tid_agg_rx->reorder_timer.function = sta_rx_agg_reorder_timer_expired;
305 tid_agg_rx->reorder_timer.data = (unsigned long)&sta->timer_to_tid[tid];
306 init_timer(&tid_agg_rx->reorder_timer);
307
308 /* prepare reordering buffer */
309 tid_agg_rx->reorder_buf =

--- 27 unchanged lines hidden (view full) ---

337 tid_agg_rx->buf_size = buf_size;
338 tid_agg_rx->timeout = timeout;
339 tid_agg_rx->stored_mpdu_num = 0;
340 status = WLAN_STATUS_SUCCESS;
341
342 /* activate it for RX */
343 rcu_assign_pointer(sta->ampdu_mlme.tid_rx[tid], tid_agg_rx);
344
338 if (timeout)
345 if (timeout) {
339 mod_timer(&tid_agg_rx->session_timer, TU_TO_EXP_TIME(timeout));
346 mod_timer(&tid_agg_rx->session_timer, TU_TO_EXP_TIME(timeout));
347 tid_agg_rx->last_rx = jiffies;
348 }
340
341end:
342 mutex_unlock(&sta->ampdu_mlme.mtx);
343
344end_no_lock:
345 ieee80211_send_addba_resp(sta->sdata, sta->sta.addr, tid,
346 dialog_token, status, 1, buf_size, timeout);
347}
349
350end:
351 mutex_unlock(&sta->ampdu_mlme.mtx);
352
353end_no_lock:
354 ieee80211_send_addba_resp(sta->sdata, sta->sta.addr, tid,
355 dialog_token, status, 1, buf_size, timeout);
356}