aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorSimon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de>2011-11-18 08:20:44 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-11-28 14:36:21 -0500
commitb53be7920bd9bb1bb99fecc2ff537bc79d24082f (patch)
treede46261ba26859086fed002694ee4693ad45bd40 /net/mac80211
parent1d9d9213d526f2f4ef9a3aa198a29a0b1a670fa1 (diff)
mac80211: Add NoAck per tid support
This patch contains the processing changes in mac80211. Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de> Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c11
-rw-r--r--net/mac80211/ieee80211_i.h3
-rw-r--r--net/mac80211/iface.c2
-rw-r--r--net/mac80211/wme.c7
4 files changed, 22 insertions, 1 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 2577c45069e..f947ac6bb67 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -102,6 +102,16 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
102 return 0; 102 return 0;
103} 103}
104 104
105static int ieee80211_set_noack_map(struct wiphy *wiphy,
106 struct net_device *dev,
107 u16 noack_map)
108{
109 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
110
111 sdata->noack_map = noack_map;
112 return 0;
113}
114
105static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, 115static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
106 u8 key_idx, bool pairwise, const u8 *mac_addr, 116 u8 key_idx, bool pairwise, const u8 *mac_addr,
107 struct key_params *params) 117 struct key_params *params)
@@ -2698,4 +2708,5 @@ struct cfg80211_ops mac80211_config_ops = {
2698 .tdls_mgmt = ieee80211_tdls_mgmt, 2708 .tdls_mgmt = ieee80211_tdls_mgmt,
2699 .probe_client = ieee80211_probe_client, 2709 .probe_client = ieee80211_probe_client,
2700 .get_channel = ieee80211_wiphy_get_channel, 2710 .get_channel = ieee80211_wiphy_get_channel,
2711 .set_noack_map = ieee80211_set_noack_map,
2701}; 2712};
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index b1aa2e172d1..7a757a97ba3 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -611,6 +611,9 @@ struct ieee80211_sub_if_data {
611 struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; 611 struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
612 unsigned int fragment_next; 612 unsigned int fragment_next;
613 613
614 /* TID bitmap for NoAck policy */
615 u16 noack_map;
616
614 struct ieee80211_key __rcu *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; 617 struct ieee80211_key __rcu *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
615 struct ieee80211_key __rcu *default_unicast_key; 618 struct ieee80211_key __rcu *default_unicast_key;
616 struct ieee80211_key __rcu *default_multicast_key; 619 struct ieee80211_key __rcu *default_multicast_key;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index b34ca0cbdf6..be1d61e76e9 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -866,6 +866,8 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
866 sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE); 866 sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE);
867 sdata->control_port_no_encrypt = false; 867 sdata->control_port_no_encrypt = false;
868 868
869 sdata->noack_map = 0;
870
869 /* only monitor differs */ 871 /* only monitor differs */
870 sdata->dev->type = ARPHRD_ETHER; 872 sdata->dev->type = ARPHRD_ETHER;
871 873
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 74b3d100844..a98f24ac936 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -139,6 +139,7 @@ void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata,
139 struct sk_buff *skb) 139 struct sk_buff *skb)
140{ 140{
141 struct ieee80211_hdr *hdr = (void *)skb->data; 141 struct ieee80211_hdr *hdr = (void *)skb->data;
142 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
142 143
143 /* Fill in the QoS header if there is one. */ 144 /* Fill in the QoS header if there is one. */
144 if (ieee80211_is_data_qos(hdr->frame_control)) { 145 if (ieee80211_is_data_qos(hdr->frame_control)) {
@@ -150,8 +151,12 @@ void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata,
150 /* preserve EOSP bit */ 151 /* preserve EOSP bit */
151 ack_policy = *p & IEEE80211_QOS_CTL_EOSP; 152 ack_policy = *p & IEEE80211_QOS_CTL_EOSP;
152 153
153 if (is_multicast_ether_addr(hdr->addr1)) 154 if (is_multicast_ether_addr(hdr->addr1) ||
155 sdata->noack_map & BIT(tid)) {
154 ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK; 156 ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK;
157 info->flags |= IEEE80211_TX_CTL_NO_ACK;
158 }
159
155 /* qos header is 2 bytes */ 160 /* qos header is 2 bytes */
156 *p++ = ack_policy | tid; 161 *p++ = ack_policy | tid;
157 *p = ieee80211_vif_is_mesh(&sdata->vif) ? 162 *p = ieee80211_vif_is_mesh(&sdata->vif) ?