aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ieee80211_sta.c
diff options
context:
space:
mode:
authorRon Rindjunsky <ron.rindjunsky@intel.com>2008-03-26 14:36:03 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-03-27 16:03:20 -0400
commitcee24a3e580f1062c8bb8b1692b95014d882bc7d (patch)
treee7df5e0f987a817ff0c9b14142a4efc583d39fa2 /net/mac80211/ieee80211_sta.c
parent6c507cd0400cb51dd2ee251c1b8756b9375a1128 (diff)
mac80211: A-MPDU MLME use dynamic allocation
This patch alters the A-MPDU MLME in sta_info to use dynamic allocation, thus drastically improving memory usage - from a constant ~2 Kbyte in the previous (static) allocation to a lower limit of ~200 Byte and an upper limit of ~2 Kbyte. Signed-off-by: Ron Rindjunsky <ron.rindjunsky@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/ieee80211_sta.c')
-rw-r--r--net/mac80211/ieee80211_sta.c84
1 files changed, 53 insertions, 31 deletions
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index cf51ca6804dd..f9cf2f187893 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -1216,12 +1216,11 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev,
1216 buf_size = buf_size << sband->ht_info.ampdu_factor; 1216 buf_size = buf_size << sband->ht_info.ampdu_factor;
1217 } 1217 }
1218 1218
1219 tid_agg_rx = &sta->ampdu_mlme.tid_rx[tid];
1220 1219
1221 /* examine state machine */ 1220 /* examine state machine */
1222 spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); 1221 spin_lock_bh(&sta->ampdu_mlme.ampdu_rx);
1223 1222
1224 if (tid_agg_rx->state != HT_AGG_STATE_IDLE) { 1223 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) {
1225#ifdef CONFIG_MAC80211_HT_DEBUG 1224#ifdef CONFIG_MAC80211_HT_DEBUG
1226 if (net_ratelimit()) 1225 if (net_ratelimit())
1227 printk(KERN_DEBUG "unexpected AddBA Req from " 1226 printk(KERN_DEBUG "unexpected AddBA Req from "
@@ -1231,6 +1230,24 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev,
1231 goto end; 1230 goto end;
1232 } 1231 }
1233 1232
1233 /* prepare A-MPDU MLME for Rx aggregation */
1234 sta->ampdu_mlme.tid_rx[tid] =
1235 kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC);
1236 if (!sta->ampdu_mlme.tid_rx[tid]) {
1237 if (net_ratelimit())
1238 printk(KERN_ERR "allocate rx mlme to tid %d failed\n",
1239 tid);
1240 goto end;
1241 }
1242 /* rx timer */
1243 sta->ampdu_mlme.tid_rx[tid]->session_timer.function =
1244 sta_rx_agg_session_timer_expired;
1245 sta->ampdu_mlme.tid_rx[tid]->session_timer.data =
1246 (unsigned long)&sta->timer_to_tid[tid];
1247 init_timer(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
1248
1249 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
1250
1234 /* prepare reordering buffer */ 1251 /* prepare reordering buffer */
1235 tid_agg_rx->reorder_buf = 1252 tid_agg_rx->reorder_buf =
1236 kmalloc(buf_size * sizeof(struct sk_buf *), GFP_ATOMIC); 1253 kmalloc(buf_size * sizeof(struct sk_buf *), GFP_ATOMIC);
@@ -1238,6 +1255,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev,
1238 if (net_ratelimit()) 1255 if (net_ratelimit())
1239 printk(KERN_ERR "can not allocate reordering buffer " 1256 printk(KERN_ERR "can not allocate reordering buffer "
1240 "to tid %d\n", tid); 1257 "to tid %d\n", tid);
1258 kfree(sta->ampdu_mlme.tid_rx[tid]);
1241 goto end; 1259 goto end;
1242 } 1260 }
1243 memset(tid_agg_rx->reorder_buf, 0, 1261 memset(tid_agg_rx->reorder_buf, 0,
@@ -1252,11 +1270,13 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev,
1252 1270
1253 if (ret) { 1271 if (ret) {
1254 kfree(tid_agg_rx->reorder_buf); 1272 kfree(tid_agg_rx->reorder_buf);
1273 kfree(tid_agg_rx);
1274 sta->ampdu_mlme.tid_rx[tid] = NULL;
1255 goto end; 1275 goto end;
1256 } 1276 }
1257 1277
1258 /* change state and send addba resp */ 1278 /* change state and send addba resp */
1259 tid_agg_rx->state = HT_AGG_STATE_OPERATIONAL; 1279 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_OPERATIONAL;
1260 tid_agg_rx->dialog_token = dialog_token; 1280 tid_agg_rx->dialog_token = dialog_token;
1261 tid_agg_rx->ssn = start_seq_num; 1281 tid_agg_rx->ssn = start_seq_num;
1262 tid_agg_rx->head_seq_num = start_seq_num; 1282 tid_agg_rx->head_seq_num = start_seq_num;
@@ -1295,39 +1315,37 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
1295 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); 1315 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
1296 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; 1316 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
1297 1317
1298 state = &sta->ampdu_mlme.tid_tx[tid].state; 1318 state = &sta->ampdu_mlme.tid_state_tx[tid];
1299 1319
1300 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 1320 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
1301 1321
1322 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
1323 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
1324 printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:"
1325 "%d\n", *state);
1326 goto addba_resp_exit;
1327 }
1328
1302 if (mgmt->u.action.u.addba_resp.dialog_token != 1329 if (mgmt->u.action.u.addba_resp.dialog_token !=
1303 sta->ampdu_mlme.tid_tx[tid].dialog_token) { 1330 sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
1304 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1331 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
1305#ifdef CONFIG_MAC80211_HT_DEBUG 1332#ifdef CONFIG_MAC80211_HT_DEBUG
1306 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); 1333 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
1307#endif /* CONFIG_MAC80211_HT_DEBUG */ 1334#endif /* CONFIG_MAC80211_HT_DEBUG */
1308 rcu_read_unlock(); 1335 goto addba_resp_exit;
1309 return;
1310 } 1336 }
1311 1337
1312 del_timer_sync(&sta->ampdu_mlme.tid_tx[tid].addba_resp_timer); 1338 del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
1313#ifdef CONFIG_MAC80211_HT_DEBUG 1339#ifdef CONFIG_MAC80211_HT_DEBUG
1314 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); 1340 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
1315#endif /* CONFIG_MAC80211_HT_DEBUG */ 1341#endif /* CONFIG_MAC80211_HT_DEBUG */
1316 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) 1342 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
1317 == WLAN_STATUS_SUCCESS) { 1343 == WLAN_STATUS_SUCCESS) {
1318 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
1319 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
1320 printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:"
1321 "%d\n", *state);
1322 rcu_read_unlock();
1323 return;
1324 }
1325
1326 if (*state & HT_ADDBA_RECEIVED_MSK) 1344 if (*state & HT_ADDBA_RECEIVED_MSK)
1327 printk(KERN_DEBUG "double addBA response\n"); 1345 printk(KERN_DEBUG "double addBA response\n");
1328 1346
1329 *state |= HT_ADDBA_RECEIVED_MSK; 1347 *state |= HT_ADDBA_RECEIVED_MSK;
1330 sta->ampdu_mlme.tid_tx[tid].addba_req_num = 0; 1348 sta->ampdu_mlme.addba_req_num[tid] = 0;
1331 1349
1332 if (*state == HT_AGG_STATE_OPERATIONAL) { 1350 if (*state == HT_AGG_STATE_OPERATIONAL) {
1333 printk(KERN_DEBUG "Aggregation on for tid %d \n", tid); 1351 printk(KERN_DEBUG "Aggregation on for tid %d \n", tid);
@@ -1339,13 +1357,15 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
1339 } else { 1357 } else {
1340 printk(KERN_DEBUG "recipient rejected agg: tid %d \n", tid); 1358 printk(KERN_DEBUG "recipient rejected agg: tid %d \n", tid);
1341 1359
1342 sta->ampdu_mlme.tid_tx[tid].addba_req_num++; 1360 sta->ampdu_mlme.addba_req_num[tid]++;
1343 /* this will allow the state check in stop_BA_session */ 1361 /* this will allow the state check in stop_BA_session */
1344 *state = HT_AGG_STATE_OPERATIONAL; 1362 *state = HT_AGG_STATE_OPERATIONAL;
1345 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1363 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
1346 ieee80211_stop_tx_ba_session(hw, sta->addr, tid, 1364 ieee80211_stop_tx_ba_session(hw, sta->addr, tid,
1347 WLAN_BACK_INITIATOR); 1365 WLAN_BACK_INITIATOR);
1348 } 1366 }
1367
1368addba_resp_exit:
1349 rcu_read_unlock(); 1369 rcu_read_unlock();
1350} 1370}
1351 1371
@@ -1411,13 +1431,13 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid,
1411 1431
1412 /* check if TID is in operational state */ 1432 /* check if TID is in operational state */
1413 spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); 1433 spin_lock_bh(&sta->ampdu_mlme.ampdu_rx);
1414 if (sta->ampdu_mlme.tid_rx[tid].state 1434 if (sta->ampdu_mlme.tid_state_rx[tid]
1415 != HT_AGG_STATE_OPERATIONAL) { 1435 != HT_AGG_STATE_OPERATIONAL) {
1416 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); 1436 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
1417 rcu_read_unlock(); 1437 rcu_read_unlock();
1418 return; 1438 return;
1419 } 1439 }
1420 sta->ampdu_mlme.tid_rx[tid].state = 1440 sta->ampdu_mlme.tid_state_rx[tid] =
1421 HT_AGG_STATE_REQ_STOP_BA_MSK | 1441 HT_AGG_STATE_REQ_STOP_BA_MSK |
1422 (initiator << HT_AGG_STATE_INITIATOR_SHIFT); 1442 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
1423 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); 1443 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
@@ -1434,25 +1454,27 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid,
1434 1454
1435 /* shutdown timer has not expired */ 1455 /* shutdown timer has not expired */
1436 if (initiator != WLAN_BACK_TIMER) 1456 if (initiator != WLAN_BACK_TIMER)
1437 del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]. 1457 del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
1438 session_timer);
1439 1458
1440 /* check if this is a self generated aggregation halt */ 1459 /* check if this is a self generated aggregation halt */
1441 if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER) 1460 if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER)
1442 ieee80211_send_delba(dev, ra, tid, 0, reason); 1461 ieee80211_send_delba(dev, ra, tid, 0, reason);
1443 1462
1444 /* free the reordering buffer */ 1463 /* free the reordering buffer */
1445 for (i = 0; i < sta->ampdu_mlme.tid_rx[tid].buf_size; i++) { 1464 for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) {
1446 if (sta->ampdu_mlme.tid_rx[tid].reorder_buf[i]) { 1465 if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) {
1447 /* release the reordered frames */ 1466 /* release the reordered frames */
1448 dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid].reorder_buf[i]); 1467 dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]);
1449 sta->ampdu_mlme.tid_rx[tid].stored_mpdu_num--; 1468 sta->ampdu_mlme.tid_rx[tid]->stored_mpdu_num--;
1450 sta->ampdu_mlme.tid_rx[tid].reorder_buf[i] = NULL; 1469 sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i] = NULL;
1451 } 1470 }
1452 } 1471 }
1453 kfree(sta->ampdu_mlme.tid_rx[tid].reorder_buf); 1472 /* free resources */
1473 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf);
1474 kfree(sta->ampdu_mlme.tid_rx[tid]);
1475 sta->ampdu_mlme.tid_rx[tid] = NULL;
1476 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_IDLE;
1454 1477
1455 sta->ampdu_mlme.tid_rx[tid].state = HT_AGG_STATE_IDLE;
1456 rcu_read_unlock(); 1478 rcu_read_unlock();
1457} 1479}
1458 1480
@@ -1491,7 +1513,7 @@ static void ieee80211_sta_process_delba(struct net_device *dev,
1491 WLAN_BACK_INITIATOR, 0); 1513 WLAN_BACK_INITIATOR, 0);
1492 else { /* WLAN_BACK_RECIPIENT */ 1514 else { /* WLAN_BACK_RECIPIENT */
1493 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 1515 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
1494 sta->ampdu_mlme.tid_tx[tid].state = 1516 sta->ampdu_mlme.tid_state_tx[tid] =
1495 HT_AGG_STATE_OPERATIONAL; 1517 HT_AGG_STATE_OPERATIONAL;
1496 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1518 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
1497 ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid, 1519 ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid,
@@ -1528,7 +1550,7 @@ void sta_addba_resp_timer_expired(unsigned long data)
1528 return; 1550 return;
1529 } 1551 }
1530 1552
1531 state = &sta->ampdu_mlme.tid_tx[tid].state; 1553 state = &sta->ampdu_mlme.tid_state_tx[tid];
1532 /* check if the TID waits for addBA response */ 1554 /* check if the TID waits for addBA response */
1533 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 1555 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
1534 if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 1556 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {