aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-09-08 11:44:28 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-11 15:53:37 -0400
commit44d414dbff9d5bf46fc09f2e68567b5848cbbfd3 (patch)
tree9e55cb581602867a3d8365666b33dd9469ccc084 /net/mac80211/mlme.c
parent5484e23749e78d5a4f56928efaf3c4b0d862b7a6 (diff)
mac80211: move some HT code out of mlme.c
Some of the HT code in mlme.c is misplaced: * constants/definitions belong to the ieee80211.h header * code being used in other modes as well shouldn't be there Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c321
1 files changed, 0 insertions, 321 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index be3292bfabe3..f43ca7b88d57 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -48,20 +48,6 @@
48#define IEEE80211_IBSS_MAX_STA_ENTRIES 128 48#define IEEE80211_IBSS_MAX_STA_ENTRIES 128
49 49
50 50
51/* mgmt header + 1 byte category code */
52#define IEEE80211_MIN_ACTION_SIZE (24 + 1)
53
54#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
55#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
56#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0
57#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
58#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
59
60/* next values represent the buffer size for A-MPDU frame.
61 * According to IEEE802.11n spec size varies from 8K to 64K (in powers of 2) */
62#define IEEE80211_MIN_AMPDU_BUF 0x8
63#define IEEE80211_MAX_AMPDU_BUF 0x40
64
65/* utils */ 51/* utils */
66static int ecw2cw(int ecw) 52static int ecw2cw(int ecw)
67{ 53{
@@ -389,52 +375,6 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
389 return changed; 375 return changed;
390} 376}
391 377
392int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie,
393 struct ieee80211_ht_info *ht_info)
394{
395
396 if (ht_info == NULL)
397 return -EINVAL;
398
399 memset(ht_info, 0, sizeof(*ht_info));
400
401 if (ht_cap_ie) {
402 u8 ampdu_info = ht_cap_ie->ampdu_params_info;
403
404 ht_info->ht_supported = 1;
405 ht_info->cap = le16_to_cpu(ht_cap_ie->cap_info);
406 ht_info->ampdu_factor =
407 ampdu_info & IEEE80211_HT_CAP_AMPDU_FACTOR;
408 ht_info->ampdu_density =
409 (ampdu_info & IEEE80211_HT_CAP_AMPDU_DENSITY) >> 2;
410 memcpy(ht_info->supp_mcs_set, ht_cap_ie->supp_mcs_set, 16);
411 } else
412 ht_info->ht_supported = 0;
413
414 return 0;
415}
416
417int ieee80211_ht_addt_info_ie_to_ht_bss_info(
418 struct ieee80211_ht_addt_info *ht_add_info_ie,
419 struct ieee80211_ht_bss_info *bss_info)
420{
421 if (bss_info == NULL)
422 return -EINVAL;
423
424 memset(bss_info, 0, sizeof(*bss_info));
425
426 if (ht_add_info_ie) {
427 u16 op_mode;
428 op_mode = le16_to_cpu(ht_add_info_ie->operation_mode);
429
430 bss_info->primary_channel = ht_add_info_ie->control_chan;
431 bss_info->bss_cap = ht_add_info_ie->ht_param;
432 bss_info->bss_op_mode = (u8)(op_mode & 0xff);
433 }
434
435 return 0;
436}
437
438static void ieee80211_sta_send_apinfo(struct ieee80211_sub_if_data *sdata, 378static void ieee80211_sta_send_apinfo(struct ieee80211_sub_if_data *sdata,
439 struct ieee80211_if_sta *ifsta) 379 struct ieee80211_if_sta *ifsta)
440{ 380{
@@ -1118,55 +1058,6 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d
1118 return; 1058 return;
1119} 1059}
1120 1060
1121void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, const u8 *da,
1122 u16 tid, u8 dialog_token, u16 start_seq_num,
1123 u16 agg_size, u16 timeout)
1124{
1125 struct ieee80211_local *local = sdata->local;
1126 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
1127 struct sk_buff *skb;
1128 struct ieee80211_mgmt *mgmt;
1129 u16 capab;
1130
1131 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
1132
1133 if (!skb) {
1134 printk(KERN_ERR "%s: failed to allocate buffer "
1135 "for addba request frame\n", sdata->dev->name);
1136 return;
1137 }
1138 skb_reserve(skb, local->hw.extra_tx_headroom);
1139 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
1140 memset(mgmt, 0, 24);
1141 memcpy(mgmt->da, da, ETH_ALEN);
1142 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1143 if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
1144 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
1145 else
1146 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
1147
1148 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1149 IEEE80211_STYPE_ACTION);
1150
1151 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req));
1152
1153 mgmt->u.action.category = WLAN_CATEGORY_BACK;
1154 mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
1155
1156 mgmt->u.action.u.addba_req.dialog_token = dialog_token;
1157 capab = (u16)(1 << 1); /* bit 1 aggregation policy */
1158 capab |= (u16)(tid << 2); /* bit 5:2 TID number */
1159 capab |= (u16)(agg_size << 6); /* bit 15:6 max size of aggergation */
1160
1161 mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);
1162
1163 mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout);
1164 mgmt->u.action.u.addba_req.start_seq_num =
1165 cpu_to_le16(start_seq_num << 4);
1166
1167 ieee80211_sta_tx(sdata, skb, 0);
1168}
1169
1170/* 1061/*
1171 * After accepting the AddBA Request we activated a timer, 1062 * After accepting the AddBA Request we activated a timer,
1172 * resetting it after each frame that arrives from the originator. 1063 * resetting it after each frame that arrives from the originator.
@@ -1396,149 +1287,6 @@ addba_resp_exit:
1396 rcu_read_unlock(); 1287 rcu_read_unlock();
1397} 1288}
1398 1289
1399void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, const u8 *da, u16 tid,
1400 u16 initiator, u16 reason_code)
1401{
1402 struct ieee80211_local *local = sdata->local;
1403 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
1404 struct sk_buff *skb;
1405 struct ieee80211_mgmt *mgmt;
1406 u16 params;
1407
1408 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
1409
1410 if (!skb) {
1411 printk(KERN_ERR "%s: failed to allocate buffer "
1412 "for delba frame\n", sdata->dev->name);
1413 return;
1414 }
1415
1416 skb_reserve(skb, local->hw.extra_tx_headroom);
1417 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
1418 memset(mgmt, 0, 24);
1419 memcpy(mgmt->da, da, ETH_ALEN);
1420 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1421 if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
1422 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
1423 else
1424 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
1425 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1426 IEEE80211_STYPE_ACTION);
1427
1428 skb_put(skb, 1 + sizeof(mgmt->u.action.u.delba));
1429
1430 mgmt->u.action.category = WLAN_CATEGORY_BACK;
1431 mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA;
1432 params = (u16)(initiator << 11); /* bit 11 initiator */
1433 params |= (u16)(tid << 12); /* bit 15:12 TID number */
1434
1435 mgmt->u.action.u.delba.params = cpu_to_le16(params);
1436 mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code);
1437
1438 ieee80211_sta_tx(sdata, skb, 0);
1439}
1440
1441void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn)
1442{
1443 struct ieee80211_local *local = sdata->local;
1444 struct sk_buff *skb;
1445 struct ieee80211_bar *bar;
1446 u16 bar_control = 0;
1447
1448 skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom);
1449 if (!skb) {
1450 printk(KERN_ERR "%s: failed to allocate buffer for "
1451 "bar frame\n", sdata->dev->name);
1452 return;
1453 }
1454 skb_reserve(skb, local->hw.extra_tx_headroom);
1455 bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar));
1456 memset(bar, 0, sizeof(*bar));
1457 bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
1458 IEEE80211_STYPE_BACK_REQ);
1459 memcpy(bar->ra, ra, ETH_ALEN);
1460 memcpy(bar->ta, sdata->dev->dev_addr, ETH_ALEN);
1461 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
1462 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
1463 bar_control |= (u16)(tid << 12);
1464 bar->control = cpu_to_le16(bar_control);
1465 bar->start_seq_num = cpu_to_le16(ssn);
1466
1467 ieee80211_sta_tx(sdata, skb, 0);
1468}
1469
1470void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid,
1471 u16 initiator, u16 reason)
1472{
1473 struct ieee80211_local *local = sdata->local;
1474 struct ieee80211_hw *hw = &local->hw;
1475 struct sta_info *sta;
1476 int ret, i;
1477 DECLARE_MAC_BUF(mac);
1478
1479 rcu_read_lock();
1480
1481 sta = sta_info_get(local, ra);
1482 if (!sta) {
1483 rcu_read_unlock();
1484 return;
1485 }
1486
1487 /* check if TID is in operational state */
1488 spin_lock_bh(&sta->lock);
1489 if (sta->ampdu_mlme.tid_state_rx[tid]
1490 != HT_AGG_STATE_OPERATIONAL) {
1491 spin_unlock_bh(&sta->lock);
1492 rcu_read_unlock();
1493 return;
1494 }
1495 sta->ampdu_mlme.tid_state_rx[tid] =
1496 HT_AGG_STATE_REQ_STOP_BA_MSK |
1497 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
1498 spin_unlock_bh(&sta->lock);
1499
1500 /* stop HW Rx aggregation. ampdu_action existence
1501 * already verified in session init so we add the BUG_ON */
1502 BUG_ON(!local->ops->ampdu_action);
1503
1504#ifdef CONFIG_MAC80211_HT_DEBUG
1505 printk(KERN_DEBUG "Rx BA session stop requested for %s tid %u\n",
1506 print_mac(mac, ra), tid);
1507#endif /* CONFIG_MAC80211_HT_DEBUG */
1508
1509 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP,
1510 ra, tid, NULL);
1511 if (ret)
1512 printk(KERN_DEBUG "HW problem - can not stop rx "
1513 "aggregation for tid %d\n", tid);
1514
1515 /* shutdown timer has not expired */
1516 if (initiator != WLAN_BACK_TIMER)
1517 del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
1518
1519 /* check if this is a self generated aggregation halt */
1520 if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER)
1521 ieee80211_send_delba(sdata, ra, tid, 0, reason);
1522
1523 /* free the reordering buffer */
1524 for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) {
1525 if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) {
1526 /* release the reordered frames */
1527 dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]);
1528 sta->ampdu_mlme.tid_rx[tid]->stored_mpdu_num--;
1529 sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i] = NULL;
1530 }
1531 }
1532 /* free resources */
1533 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf);
1534 kfree(sta->ampdu_mlme.tid_rx[tid]);
1535 sta->ampdu_mlme.tid_rx[tid] = NULL;
1536 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_IDLE;
1537
1538 rcu_read_unlock();
1539}
1540
1541
1542static void ieee80211_sta_process_delba(struct ieee80211_sub_if_data *sdata, 1290static void ieee80211_sta_process_delba(struct ieee80211_sub_if_data *sdata,
1543 struct ieee80211_mgmt *mgmt, size_t len) 1291 struct ieee80211_mgmt *mgmt, size_t len)
1544{ 1292{
@@ -1582,75 +1330,6 @@ static void ieee80211_sta_process_delba(struct ieee80211_sub_if_data *sdata,
1582 rcu_read_unlock(); 1330 rcu_read_unlock();
1583} 1331}
1584 1332
1585/*
1586 * After sending add Block Ack request we activated a timer until
1587 * add Block Ack response will arrive from the recipient.
1588 * If this timer expires sta_addba_resp_timer_expired will be executed.
1589 */
1590void sta_addba_resp_timer_expired(unsigned long data)
1591{
1592 /* not an elegant detour, but there is no choice as the timer passes
1593 * only one argument, and both sta_info and TID are needed, so init
1594 * flow in sta_info_create gives the TID as data, while the timer_to_id
1595 * array gives the sta through container_of */
1596 u16 tid = *(u8 *)data;
1597 struct sta_info *temp_sta = container_of((void *)data,
1598 struct sta_info, timer_to_tid[tid]);
1599
1600 struct ieee80211_local *local = temp_sta->local;
1601 struct ieee80211_hw *hw = &local->hw;
1602 struct sta_info *sta;
1603 u8 *state;
1604
1605 rcu_read_lock();
1606
1607 sta = sta_info_get(local, temp_sta->addr);
1608 if (!sta) {
1609 rcu_read_unlock();
1610 return;
1611 }
1612
1613 state = &sta->ampdu_mlme.tid_state_tx[tid];
1614 /* check if the TID waits for addBA response */
1615 spin_lock_bh(&sta->lock);
1616 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
1617 spin_unlock_bh(&sta->lock);
1618 *state = HT_AGG_STATE_IDLE;
1619#ifdef CONFIG_MAC80211_HT_DEBUG
1620 printk(KERN_DEBUG "timer expired on tid %d but we are not "
1621 "expecting addBA response there", tid);
1622#endif
1623 goto timer_expired_exit;
1624 }
1625
1626#ifdef CONFIG_MAC80211_HT_DEBUG
1627 printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid);
1628#endif
1629
1630 /* go through the state check in stop_BA_session */
1631 *state = HT_AGG_STATE_OPERATIONAL;
1632 spin_unlock_bh(&sta->lock);
1633 ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid,
1634 WLAN_BACK_INITIATOR);
1635
1636timer_expired_exit:
1637 rcu_read_unlock();
1638}
1639
1640void ieee80211_sta_tear_down_BA_sessions(struct ieee80211_sub_if_data *sdata, u8 *addr)
1641{
1642 struct ieee80211_local *local = sdata->local;
1643 int i;
1644
1645 for (i = 0; i < STA_TID_NUM; i++) {
1646 ieee80211_stop_tx_ba_session(&local->hw, addr, i,
1647 WLAN_BACK_INITIATOR);
1648 ieee80211_sta_stop_rx_ba_session(sdata, addr, i,
1649 WLAN_BACK_RECIPIENT,
1650 WLAN_REASON_QSTA_LEAVE_QBSS);
1651 }
1652}
1653
1654static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_data *sdata, 1333static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_data *sdata,
1655 struct ieee80211_msrment_ie *request_ie, 1334 struct ieee80211_msrment_ie *request_ie,
1656 const u8 *da, const u8 *bssid, 1335 const u8 *da, const u8 *bssid,