aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/debugfs_key.c15
-rw-r--r--net/mac80211/iface.c9
-rw-r--r--net/mac80211/mesh.c2
-rw-r--r--net/mac80211/mesh_hwmp.c2
-rw-r--r--net/mac80211/mesh_pathtbl.c17
-rw-r--r--net/mac80211/mlme.c64
-rw-r--r--net/mac80211/rx.c12
-rw-r--r--net/mac80211/tx.c5
-rw-r--r--net/mac80211/util.c10
-rw-r--r--net/mac80211/wme.c3
10 files changed, 101 insertions, 38 deletions
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 879e7210458a..19efc3a6a932 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -255,14 +255,23 @@ void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
255void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata) 255void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
256{ 256{
257 char buf[50]; 257 char buf[50];
258 struct ieee80211_key *key;
258 259
259 if (!sdata->debugfsdir) 260 if (!sdata->debugfsdir)
260 return; 261 return;
261 262
262 sprintf(buf, "../keys/%d", sdata->default_key->debugfs.cnt); 263 /* this is running under the key lock */
263 sdata->debugfs.default_key = 264
264 debugfs_create_symlink("default_key", sdata->debugfsdir, buf); 265 key = sdata->default_key;
266 if (key) {
267 sprintf(buf, "../keys/%d", key->debugfs.cnt);
268 sdata->debugfs.default_key =
269 debugfs_create_symlink("default_key",
270 sdata->debugfsdir, buf);
271 } else
272 ieee80211_debugfs_key_remove_default(sdata);
265} 273}
274
266void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata) 275void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata)
267{ 276{
268 if (!sdata) 277 if (!sdata)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 80954a512185..06e88a5a036d 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -54,6 +54,15 @@ int ieee80211_if_add(struct net_device *dev, const char *name,
54 if (!ndev) 54 if (!ndev)
55 return -ENOMEM; 55 return -ENOMEM;
56 56
57 ndev->needed_headroom = local->tx_headroom +
58 4*6 /* four MAC addresses */
59 + 2 + 2 + 2 + 2 /* ctl, dur, seq, qos */
60 + 6 /* mesh */
61 + 8 /* rfc1042/bridge tunnel */
62 - ETH_HLEN /* ethernet hard_header_len */
63 + IEEE80211_ENCRYPT_HEADROOM;
64 ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM;
65
57 ret = dev_alloc_name(ndev, ndev->name); 66 ret = dev_alloc_name(ndev, ndev->name);
58 if (ret < 0) 67 if (ret < 0)
59 goto fail; 68 goto fail;
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index f76bc26ae4d2..697ef67f96b6 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -397,7 +397,7 @@ int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
397 put_unaligned(cpu_to_le32(sdata->u.sta.mesh_seqnum), &meshhdr->seqnum); 397 put_unaligned(cpu_to_le32(sdata->u.sta.mesh_seqnum), &meshhdr->seqnum);
398 sdata->u.sta.mesh_seqnum++; 398 sdata->u.sta.mesh_seqnum++;
399 399
400 return 5; 400 return 6;
401} 401}
402 402
403void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) 403void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 3df809222d1c..af0cd1e3e213 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -120,7 +120,7 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
120 *pos++ = WLAN_EID_PREP; 120 *pos++ = WLAN_EID_PREP;
121 break; 121 break;
122 default: 122 default:
123 kfree(skb); 123 kfree_skb(skb);
124 return -ENOTSUPP; 124 return -ENOTSUPP;
125 break; 125 break;
126 } 126 }
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 5845dc21ce85..99c2d360888e 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -158,19 +158,25 @@ int mesh_path_add(u8 *dst, struct net_device *dev)
158 if (atomic_add_unless(&sdata->u.sta.mpaths, 1, MESH_MAX_MPATHS) == 0) 158 if (atomic_add_unless(&sdata->u.sta.mpaths, 1, MESH_MAX_MPATHS) == 0)
159 return -ENOSPC; 159 return -ENOSPC;
160 160
161 read_lock(&pathtbl_resize_lock);
162
163 new_mpath = kzalloc(sizeof(struct mesh_path), GFP_KERNEL); 161 new_mpath = kzalloc(sizeof(struct mesh_path), GFP_KERNEL);
164 if (!new_mpath) { 162 if (!new_mpath) {
165 atomic_dec(&sdata->u.sta.mpaths); 163 atomic_dec(&sdata->u.sta.mpaths);
166 err = -ENOMEM; 164 err = -ENOMEM;
167 goto endadd2; 165 goto endadd2;
168 } 166 }
167 new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL);
168 if (!new_node) {
169 kfree(new_mpath);
170 atomic_dec(&sdata->u.sta.mpaths);
171 err = -ENOMEM;
172 goto endadd2;
173 }
174
175 read_lock(&pathtbl_resize_lock);
169 memcpy(new_mpath->dst, dst, ETH_ALEN); 176 memcpy(new_mpath->dst, dst, ETH_ALEN);
170 new_mpath->dev = dev; 177 new_mpath->dev = dev;
171 new_mpath->flags = 0; 178 new_mpath->flags = 0;
172 skb_queue_head_init(&new_mpath->frame_queue); 179 skb_queue_head_init(&new_mpath->frame_queue);
173 new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL);
174 new_node->mpath = new_mpath; 180 new_node->mpath = new_mpath;
175 new_mpath->timer.data = (unsigned long) new_mpath; 181 new_mpath->timer.data = (unsigned long) new_mpath;
176 new_mpath->timer.function = mesh_path_timer; 182 new_mpath->timer.function = mesh_path_timer;
@@ -202,7 +208,6 @@ int mesh_path_add(u8 *dst, struct net_device *dev)
202 208
203endadd: 209endadd:
204 spin_unlock(&mesh_paths->hashwlock[hash_idx]); 210 spin_unlock(&mesh_paths->hashwlock[hash_idx]);
205endadd2:
206 read_unlock(&pathtbl_resize_lock); 211 read_unlock(&pathtbl_resize_lock);
207 if (!err && grow) { 212 if (!err && grow) {
208 struct mesh_table *oldtbl, *newtbl; 213 struct mesh_table *oldtbl, *newtbl;
@@ -215,10 +220,12 @@ endadd2:
215 return -ENOMEM; 220 return -ENOMEM;
216 } 221 }
217 rcu_assign_pointer(mesh_paths, newtbl); 222 rcu_assign_pointer(mesh_paths, newtbl);
223 write_unlock(&pathtbl_resize_lock);
224
218 synchronize_rcu(); 225 synchronize_rcu();
219 mesh_table_free(oldtbl, false); 226 mesh_table_free(oldtbl, false);
220 write_unlock(&pathtbl_resize_lock);
221 } 227 }
228endadd2:
222 return err; 229 return err;
223} 230}
224 231
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a5e5c31c23ab..4adba09e80ca 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -665,6 +665,26 @@ static void ieee80211_authenticate(struct net_device *dev,
665 mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT); 665 mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT);
666} 666}
667 667
668static int ieee80211_compatible_rates(struct ieee80211_sta_bss *bss,
669 struct ieee80211_supported_band *sband,
670 u64 *rates)
671{
672 int i, j, count;
673 *rates = 0;
674 count = 0;
675 for (i = 0; i < bss->supp_rates_len; i++) {
676 int rate = (bss->supp_rates[i] & 0x7F) * 5;
677
678 for (j = 0; j < sband->n_bitrates; j++)
679 if (sband->bitrates[j].bitrate == rate) {
680 *rates |= BIT(j);
681 count++;
682 break;
683 }
684 }
685
686 return count;
687}
668 688
669static void ieee80211_send_assoc(struct net_device *dev, 689static void ieee80211_send_assoc(struct net_device *dev,
670 struct ieee80211_if_sta *ifsta) 690 struct ieee80211_if_sta *ifsta)
@@ -673,11 +693,12 @@ static void ieee80211_send_assoc(struct net_device *dev,
673 struct sk_buff *skb; 693 struct sk_buff *skb;
674 struct ieee80211_mgmt *mgmt; 694 struct ieee80211_mgmt *mgmt;
675 u8 *pos, *ies; 695 u8 *pos, *ies;
676 int i, len; 696 int i, len, count, rates_len, supp_rates_len;
677 u16 capab; 697 u16 capab;
678 struct ieee80211_sta_bss *bss; 698 struct ieee80211_sta_bss *bss;
679 int wmm = 0; 699 int wmm = 0;
680 struct ieee80211_supported_band *sband; 700 struct ieee80211_supported_band *sband;
701 u64 rates = 0;
681 702
682 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 703 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
683 sizeof(*mgmt) + 200 + ifsta->extra_ie_len + 704 sizeof(*mgmt) + 200 + ifsta->extra_ie_len +
@@ -740,24 +761,39 @@ static void ieee80211_send_assoc(struct net_device *dev,
740 *pos++ = ifsta->ssid_len; 761 *pos++ = ifsta->ssid_len;
741 memcpy(pos, ifsta->ssid, ifsta->ssid_len); 762 memcpy(pos, ifsta->ssid, ifsta->ssid_len);
742 763
764 /* all supported rates should be added here but some APs
765 * (e.g. D-Link DAP 1353 in b-only mode) don't like that
766 * Therefore only add rates the AP supports */
767 rates_len = ieee80211_compatible_rates(bss, sband, &rates);
768 supp_rates_len = rates_len;
769 if (supp_rates_len > 8)
770 supp_rates_len = 8;
771
743 len = sband->n_bitrates; 772 len = sband->n_bitrates;
744 if (len > 8) 773 pos = skb_put(skb, supp_rates_len + 2);
745 len = 8;
746 pos = skb_put(skb, len + 2);
747 *pos++ = WLAN_EID_SUPP_RATES; 774 *pos++ = WLAN_EID_SUPP_RATES;
748 *pos++ = len; 775 *pos++ = supp_rates_len;
749 for (i = 0; i < len; i++) {
750 int rate = sband->bitrates[i].bitrate;
751 *pos++ = (u8) (rate / 5);
752 }
753 776
754 if (sband->n_bitrates > len) { 777 count = 0;
755 pos = skb_put(skb, sband->n_bitrates - len + 2); 778 for (i = 0; i < sband->n_bitrates; i++) {
756 *pos++ = WLAN_EID_EXT_SUPP_RATES; 779 if (BIT(i) & rates) {
757 *pos++ = sband->n_bitrates - len;
758 for (i = len; i < sband->n_bitrates; i++) {
759 int rate = sband->bitrates[i].bitrate; 780 int rate = sband->bitrates[i].bitrate;
760 *pos++ = (u8) (rate / 5); 781 *pos++ = (u8) (rate / 5);
782 if (++count == 8)
783 break;
784 }
785 }
786
787 if (count == 8) {
788 pos = skb_put(skb, rates_len - count + 2);
789 *pos++ = WLAN_EID_EXT_SUPP_RATES;
790 *pos++ = rates_len - count;
791
792 for (i++; i < sband->n_bitrates; i++) {
793 if (BIT(i) & rates) {
794 int rate = sband->bitrates[i].bitrate;
795 *pos++ = (u8) (rate / 5);
796 }
761 } 797 }
762 } 798 }
763 799
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 02f436a86061..1958bfb361c6 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1305,11 +1305,11 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
1305 if (is_multicast_ether_addr(skb->data)) { 1305 if (is_multicast_ether_addr(skb->data)) {
1306 if (*mesh_ttl > 0) { 1306 if (*mesh_ttl > 0) {
1307 xmit_skb = skb_copy(skb, GFP_ATOMIC); 1307 xmit_skb = skb_copy(skb, GFP_ATOMIC);
1308 if (!xmit_skb && net_ratelimit()) 1308 if (xmit_skb)
1309 xmit_skb->pkt_type = PACKET_OTHERHOST;
1310 else if (net_ratelimit())
1309 printk(KERN_DEBUG "%s: failed to clone " 1311 printk(KERN_DEBUG "%s: failed to clone "
1310 "multicast frame\n", dev->name); 1312 "multicast frame\n", dev->name);
1311 else
1312 xmit_skb->pkt_type = PACKET_OTHERHOST;
1313 } else 1313 } else
1314 IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.sta, 1314 IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.sta,
1315 dropped_frames_ttl); 1315 dropped_frames_ttl);
@@ -1395,7 +1395,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
1395 padding = ((4 - subframe_len) & 0x3); 1395 padding = ((4 - subframe_len) & 0x3);
1396 /* the last MSDU has no padding */ 1396 /* the last MSDU has no padding */
1397 if (subframe_len > remaining) { 1397 if (subframe_len > remaining) {
1398 printk(KERN_DEBUG "%s: wrong buffer size", dev->name); 1398 printk(KERN_DEBUG "%s: wrong buffer size\n", dev->name);
1399 return RX_DROP_UNUSABLE; 1399 return RX_DROP_UNUSABLE;
1400 } 1400 }
1401 1401
@@ -1418,7 +1418,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
1418 eth = (struct ethhdr *) skb_pull(skb, ntohs(len) + 1418 eth = (struct ethhdr *) skb_pull(skb, ntohs(len) +
1419 padding); 1419 padding);
1420 if (!eth) { 1420 if (!eth) {
1421 printk(KERN_DEBUG "%s: wrong buffer size ", 1421 printk(KERN_DEBUG "%s: wrong buffer size\n",
1422 dev->name); 1422 dev->name);
1423 dev_kfree_skb(frame); 1423 dev_kfree_skb(frame);
1424 return RX_DROP_UNUSABLE; 1424 return RX_DROP_UNUSABLE;
@@ -1952,7 +1952,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
1952 if (!skb_new) { 1952 if (!skb_new) {
1953 if (net_ratelimit()) 1953 if (net_ratelimit())
1954 printk(KERN_DEBUG "%s: failed to copy " 1954 printk(KERN_DEBUG "%s: failed to copy "
1955 "multicast frame for %s", 1955 "multicast frame for %s\n",
1956 wiphy_name(local->hw.wiphy), 1956 wiphy_name(local->hw.wiphy),
1957 prev->dev->name); 1957 prev->dev->name);
1958 continue; 1958 continue;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index f35eaea98e73..1d7dd54aacef 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1562,13 +1562,13 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1562 * be cloned. This could happen, e.g., with Linux bridge code passing 1562 * be cloned. This could happen, e.g., with Linux bridge code passing
1563 * us broadcast frames. */ 1563 * us broadcast frames. */
1564 1564
1565 if (head_need > 0 || skb_cloned(skb)) { 1565 if (head_need > 0 || skb_header_cloned(skb)) {
1566#if 0 1566#if 0
1567 printk(KERN_DEBUG "%s: need to reallocate buffer for %d bytes " 1567 printk(KERN_DEBUG "%s: need to reallocate buffer for %d bytes "
1568 "of headroom\n", dev->name, head_need); 1568 "of headroom\n", dev->name, head_need);
1569#endif 1569#endif
1570 1570
1571 if (skb_cloned(skb)) 1571 if (skb_header_cloned(skb))
1572 I802_DEBUG_INC(local->tx_expand_skb_head_cloned); 1572 I802_DEBUG_INC(local->tx_expand_skb_head_cloned);
1573 else 1573 else
1574 I802_DEBUG_INC(local->tx_expand_skb_head); 1574 I802_DEBUG_INC(local->tx_expand_skb_head);
@@ -1898,6 +1898,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1898 control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; 1898 control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE;
1899 control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; 1899 control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
1900 control->flags |= IEEE80211_TXCTL_NO_ACK; 1900 control->flags |= IEEE80211_TXCTL_NO_ACK;
1901 control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
1901 control->retry_limit = 1; 1902 control->retry_limit = 1;
1902 control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; 1903 control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT;
1903 } 1904 }
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index cc9f715c7bfc..24a465c4df09 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -153,15 +153,15 @@ int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
153 /* 7.1.3.5a.2 */ 153 /* 7.1.3.5a.2 */
154 switch (ae) { 154 switch (ae) {
155 case 0: 155 case 0:
156 return 5; 156 return 6;
157 case 1: 157 case 1:
158 return 11; 158 return 12;
159 case 2: 159 case 2:
160 return 17; 160 return 18;
161 case 3: 161 case 3:
162 return 23; 162 return 24;
163 default: 163 default:
164 return 5; 164 return 6;
165 } 165 }
166} 166}
167 167
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 64faa3dc488f..dc1598b86004 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -394,7 +394,8 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt)
394 qd->handle); 394 qd->handle);
395 if (!q->queues[i]) { 395 if (!q->queues[i]) {
396 q->queues[i] = &noop_qdisc; 396 q->queues[i] = &noop_qdisc;
397 printk(KERN_ERR "%s child qdisc %i creation failed", dev->name, i); 397 printk(KERN_ERR "%s child qdisc %i creation failed\n",
398 dev->name, i);
398 } 399 }
399 } 400 }
400 401