diff options
| author | Ron Rindjunsky <ron.rindjunsky@intel.com> | 2008-01-28 07:07:15 -0500 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2008-02-29 15:19:13 -0500 |
| commit | 0df3ef45a3d7b59cc53ce4e3611033c6e3b51a1b (patch) | |
| tree | 094a5340c7ded841c72c6542176568af7bd2a565 | |
| parent | 8816edcea9009b66570bef10acde5a552a9b3b3c (diff) | |
mac80211: A-MPDU Tx add session's and low level driver's API
This patch adds the API for 3 stages in A-MPDU Tx session flow:
- request mac80211 to start/stop A-MPDU Tx session for specific TID. such a
request should be issued by a load aware element, either mac80211 itself
or external element.
- requests by mac80211 to low-level driver to start/stop Tx aggregation.
notice that low level driver responds now with Starting Sequence Number.
- async feedback by low-level to mac80211 to inform that HW is ready for
next A-MPDU Tx state.
Changes in API to Rx A-MPDU were also made, reflected in iwlwifi changes as
well.
Signed-off-by: Ron Rindjunsky <ron.rindjunsky@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 4 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.h | 2 | ||||
| -rw-r--r-- | include/net/mac80211.h | 86 | ||||
| -rw-r--r-- | net/mac80211/ieee80211_sta.c | 4 |
4 files changed, 89 insertions, 7 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index d727de8b96fe..cd4f5e383e60 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
| @@ -4732,7 +4732,7 @@ static void iwl4965_sta_modify_del_ba_tid(struct iwl4965_priv *priv, | |||
| 4732 | 4732 | ||
| 4733 | int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, | 4733 | int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, |
| 4734 | enum ieee80211_ampdu_mlme_action action, | 4734 | enum ieee80211_ampdu_mlme_action action, |
| 4735 | const u8 *addr, u16 tid, u16 ssn) | 4735 | const u8 *addr, u16 tid, u16 *ssn) |
| 4736 | { | 4736 | { |
| 4737 | struct iwl4965_priv *priv = hw->priv; | 4737 | struct iwl4965_priv *priv = hw->priv; |
| 4738 | int sta_id; | 4738 | int sta_id; |
| @@ -4744,7 +4744,7 @@ int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, | |||
| 4744 | switch (action) { | 4744 | switch (action) { |
| 4745 | case IEEE80211_AMPDU_RX_START: | 4745 | case IEEE80211_AMPDU_RX_START: |
| 4746 | IWL_DEBUG_HT("start Rx\n"); | 4746 | IWL_DEBUG_HT("start Rx\n"); |
| 4747 | iwl4965_sta_modify_add_ba_tid(priv, sta_id, tid, ssn); | 4747 | iwl4965_sta_modify_add_ba_tid(priv, sta_id, tid, *ssn); |
| 4748 | break; | 4748 | break; |
| 4749 | case IEEE80211_AMPDU_RX_STOP: | 4749 | case IEEE80211_AMPDU_RX_STOP: |
| 4750 | IWL_DEBUG_HT("stop Rx\n"); | 4750 | IWL_DEBUG_HT("stop Rx\n"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index 9cb82be0ff80..6edf869d4d54 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h | |||
| @@ -777,7 +777,7 @@ extern void iwl4965_set_ht_add_station(struct iwl4965_priv *priv, u8 index, | |||
| 777 | struct ieee80211_ht_info *sta_ht_inf); | 777 | struct ieee80211_ht_info *sta_ht_inf); |
| 778 | extern int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, | 778 | extern int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, |
| 779 | enum ieee80211_ampdu_mlme_action action, | 779 | enum ieee80211_ampdu_mlme_action action, |
| 780 | const u8 *addr, u16 tid, u16 ssn); | 780 | const u8 *addr, u16 tid, u16 *ssn); |
| 781 | #ifdef CONFIG_IWL4965_HT_AGG | 781 | #ifdef CONFIG_IWL4965_HT_AGG |
| 782 | extern int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da, | 782 | extern int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da, |
| 783 | u16 tid, u16 *start_seq_num); | 783 | u16 tid, u16 *start_seq_num); |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 9083bafb63ca..3bbc33cc2b96 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
| @@ -967,10 +967,14 @@ enum ieee80211_filter_flags { | |||
| 967 | * &struct ieee80211_ops to indicate which action is needed. | 967 | * &struct ieee80211_ops to indicate which action is needed. |
| 968 | * @IEEE80211_AMPDU_RX_START: start Rx aggregation | 968 | * @IEEE80211_AMPDU_RX_START: start Rx aggregation |
| 969 | * @IEEE80211_AMPDU_RX_STOP: stop Rx aggregation | 969 | * @IEEE80211_AMPDU_RX_STOP: stop Rx aggregation |
| 970 | * @IEEE80211_AMPDU_TX_START: start Tx aggregation | ||
| 971 | * @IEEE80211_AMPDU_TX_STOP: stop Tx aggregation | ||
| 970 | */ | 972 | */ |
| 971 | enum ieee80211_ampdu_mlme_action { | 973 | enum ieee80211_ampdu_mlme_action { |
| 972 | IEEE80211_AMPDU_RX_START, | 974 | IEEE80211_AMPDU_RX_START, |
| 973 | IEEE80211_AMPDU_RX_STOP, | 975 | IEEE80211_AMPDU_RX_STOP, |
| 976 | IEEE80211_AMPDU_TX_START, | ||
| 977 | IEEE80211_AMPDU_TX_STOP, | ||
| 974 | }; | 978 | }; |
| 975 | 979 | ||
| 976 | /** | 980 | /** |
| @@ -1111,7 +1115,8 @@ enum ieee80211_ampdu_mlme_action { | |||
| 1111 | * The RA/TID combination determines the destination and TID we want | 1115 | * The RA/TID combination determines the destination and TID we want |
| 1112 | * the ampdu action to be performed for. The action is defined through | 1116 | * the ampdu action to be performed for. The action is defined through |
| 1113 | * ieee80211_ampdu_mlme_action. Starting sequence number (@ssn) | 1117 | * ieee80211_ampdu_mlme_action. Starting sequence number (@ssn) |
| 1114 | * is the first frame we expect to perform the action on. | 1118 | * is the first frame we expect to perform the action on. notice |
| 1119 | * that TX/RX_STOP can pass NULL for this parameter. | ||
| 1115 | */ | 1120 | */ |
| 1116 | struct ieee80211_ops { | 1121 | struct ieee80211_ops { |
| 1117 | int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb, | 1122 | int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb, |
| @@ -1162,7 +1167,7 @@ struct ieee80211_ops { | |||
| 1162 | int (*conf_ht)(struct ieee80211_hw *hw, struct ieee80211_conf *conf); | 1167 | int (*conf_ht)(struct ieee80211_hw *hw, struct ieee80211_conf *conf); |
| 1163 | int (*ampdu_action)(struct ieee80211_hw *hw, | 1168 | int (*ampdu_action)(struct ieee80211_hw *hw, |
| 1164 | enum ieee80211_ampdu_mlme_action action, | 1169 | enum ieee80211_ampdu_mlme_action action, |
| 1165 | const u8 *ra, u16 tid, u16 ssn); | 1170 | const u8 *addr, u16 tid, u16 *ssn); |
| 1166 | }; | 1171 | }; |
| 1167 | 1172 | ||
| 1168 | /** | 1173 | /** |
| @@ -1574,4 +1579,81 @@ void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw, | |||
| 1574 | struct ieee80211_vif *vif), | 1579 | struct ieee80211_vif *vif), |
| 1575 | void *data); | 1580 | void *data); |
| 1576 | 1581 | ||
| 1582 | /** | ||
| 1583 | * ieee80211_start_tx_ba_session - Start a tx Block Ack session. | ||
| 1584 | * @hw: pointer as obtained from ieee80211_alloc_hw(). | ||
| 1585 | * @ra: receiver address of the BA session recipient | ||
| 1586 | * @tid: the TID to BA on. | ||
| 1587 | * @return: success if addBA request was sent, failure otherwise | ||
| 1588 | * | ||
| 1589 | * Although mac80211/low level driver/user space application can estimate | ||
| 1590 | * the need to start aggregation on a certain RA/TID, the session level | ||
| 1591 | * will be managed by the mac80211. | ||
| 1592 | */ | ||
| 1593 | int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid); | ||
| 1594 | |||
| 1595 | /** | ||
| 1596 | * ieee80211_start_tx_ba_cb - low level driver ready to aggregate. | ||
| 1597 | * @hw: pointer as obtained from ieee80211_alloc_hw(). | ||
| 1598 | * @ra: receiver address of the BA session recipient. | ||
| 1599 | * @tid: the TID to BA on. | ||
| 1600 | * | ||
| 1601 | * This function must be called by low level driver once it has | ||
| 1602 | * finished with preparations for the BA session. | ||
| 1603 | */ | ||
| 1604 | void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid); | ||
| 1605 | |||
| 1606 | /** | ||
| 1607 | * ieee80211_start_tx_ba_cb_irqsafe - low level driver ready to aggregate. | ||
| 1608 | * @hw: pointer as obtained from ieee80211_alloc_hw(). | ||
| 1609 | * @ra: receiver address of the BA session recipient. | ||
| 1610 | * @tid: the TID to BA on. | ||
| 1611 | * | ||
| 1612 | * This function must be called by low level driver once it has | ||
| 1613 | * finished with preparations for the BA session. | ||
| 1614 | * This version of the function is irq safe. | ||
| 1615 | */ | ||
| 1616 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, const u8 *ra, | ||
| 1617 | u16 tid); | ||
| 1618 | |||
| 1619 | /** | ||
| 1620 | * ieee80211_stop_tx_ba_session - Stop a Block Ack session. | ||
| 1621 | * @hw: pointer as obtained from ieee80211_alloc_hw(). | ||
| 1622 | * @ra: receiver address of the BA session recipient | ||
| 1623 | * @tid: the TID to stop BA. | ||
| 1624 | * @initiator: if indicates initiator DELBA frame will be sent. | ||
| 1625 | * @return: error if no sta with matching da found, success otherwise | ||
| 1626 | * | ||
| 1627 | * Although mac80211/low level driver/user space application can estimate | ||
| 1628 | * the need to stop aggregation on a certain RA/TID, the session level | ||
| 1629 | * will be managed by the mac80211. | ||
| 1630 | */ | ||
| 1631 | int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | ||
| 1632 | u8 *ra, u16 tid, | ||
| 1633 | enum ieee80211_back_parties initiator); | ||
| 1634 | |||
| 1635 | /** | ||
| 1636 | * ieee80211_stop_tx_ba_cb - low level driver ready to stop aggregate. | ||
| 1637 | * @hw: pointer as obtained from ieee80211_alloc_hw(). | ||
| 1638 | * @ra: receiver address of the BA session recipient. | ||
| 1639 | * @tid: the desired TID to BA on. | ||
| 1640 | * | ||
| 1641 | * This function must be called by low level driver once it has | ||
| 1642 | * finished with preparations for the BA session tear down. | ||
| 1643 | */ | ||
| 1644 | void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid); | ||
| 1645 | |||
| 1646 | /** | ||
| 1647 | * ieee80211_stop_tx_ba_cb_irqsafe - low level driver ready to stop aggregate. | ||
| 1648 | * @hw: pointer as obtained from ieee80211_alloc_hw(). | ||
| 1649 | * @ra: receiver address of the BA session recipient. | ||
| 1650 | * @tid: the desired TID to BA on. | ||
| 1651 | * | ||
| 1652 | * This function must be called by low level driver once it has | ||
| 1653 | * finished with preparations for the BA session tear down. | ||
| 1654 | * This version of the function is irq safe. | ||
| 1655 | */ | ||
| 1656 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, const u8 *ra, | ||
| 1657 | u16 tid); | ||
| 1658 | |||
| 1577 | #endif /* MAC80211_H */ | 1659 | #endif /* MAC80211_H */ |
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index 79dadd2976cd..d5d5610db1bd 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c | |||
| @@ -1128,7 +1128,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
| 1128 | 1128 | ||
| 1129 | if (local->ops->ampdu_action) | 1129 | if (local->ops->ampdu_action) |
| 1130 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START, | 1130 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START, |
| 1131 | sta->addr, tid, start_seq_num); | 1131 | sta->addr, tid, &start_seq_num); |
| 1132 | #ifdef CONFIG_MAC80211_HT_DEBUG | 1132 | #ifdef CONFIG_MAC80211_HT_DEBUG |
| 1133 | printk(KERN_DEBUG "Rx A-MPDU on tid %d result %d", tid, ret); | 1133 | printk(KERN_DEBUG "Rx A-MPDU on tid %d result %d", tid, ret); |
| 1134 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 1134 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
| @@ -1230,7 +1230,7 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid, | |||
| 1230 | BUG_ON(!local->ops->ampdu_action); | 1230 | BUG_ON(!local->ops->ampdu_action); |
| 1231 | 1231 | ||
| 1232 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP, | 1232 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP, |
| 1233 | ra, tid, EINVAL); | 1233 | ra, tid, NULL); |
| 1234 | if (ret) | 1234 | if (ret) |
| 1235 | printk(KERN_DEBUG "HW problem - can not stop rx " | 1235 | printk(KERN_DEBUG "HW problem - can not stop rx " |
| 1236 | "aggergation for tid %d\n", tid); | 1236 | "aggergation for tid %d\n", tid); |
