aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-11-10 14:34:59 -0500
committerDavid S. Miller <davem@davemloft.net>2014-11-10 14:34:59 -0500
commitb92172661e63c1f3528015bb378954c1a9e5bf4a (patch)
tree5794874cfe80a3bfc4c1038faafdbec14d412ee1 /net
parente344458fc011bf4bea52a090895c38c4634ab402 (diff)
parentbf515fb11ab539c76d04f0e3c5216ed41f41d81f (diff)
Merge tag 'master-2014-11-04' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
John W. Linville says: ==================== pull request: wireless-next 2014-11-07 Please pull this batch of updates intended for the 3.19 stream! For the mac80211 bits, Johannes says: "This relatively large batch of changes is comprised of the following: * large mac80211-hwsim changes from Ben, Jukka and a bit myself * OCB/WAVE/11p support from Rostislav on behalf of the Czech Technical University in Prague and Volkswagen Group Research * minstrel VHT work from Karl * more CSA work from Luca * WMM admission control support in mac80211 (myself) * various smaller fixes, spelling corrections, and minor API additions" For the Bluetooth bits, Johan says: "Here's the first bluetooth-next pull request for 3.19. The vast majority of patches are for ieee802154 from Alexander Aring with various fixes and cleanups. There are also several LE/SMP fixes as well as improved support for handling LE devices that have lost their pairing information (the patches from Alfonso). Jukka provides a couple of stability fixes for 6lowpan and Szymon conformance fixes for RFCOMM. For the HCI drivers we have one new USB ID for an Acer controller as well as a reset handling fix for H5." For the Atheros bits, Kalle says: "Major changes are: o ethtool support (Ben) o print dev string prefix with debug hex buffers dump (Michal) o debugfs file to read calibration data from the firmware verification purposes (me) o fix fw_stats debugfs file, now results are more reliable (Michal) o firmware crash counters via debugfs (Ben&me) o various tracing points to debug firmware (Rajkumar) o make it possible to provide firmware calibration data via a file (me) And we have quite a lot of smaller fixes and clean up." For the iwlwifi bits, Emmanuel says: "The big new thing here is netdetect which allows the firmware to wake up the platform when a specific network is detected. Along with that I have fixes for d3 operation. The usual amount of rate scaling stuff - we now support STBC. The other commit that stands out is Johannes's work on devcoredump. He basically starts to use the standard infrastructure he built." Along with that are the usual sort of updates and such for ath9k, brcmfmac, wil6210, and a handful of other bits here and there... Please let me know if there are problems! ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/6lowpan/iphc.c71
-rw-r--r--net/bluetooth/6lowpan.c284
-rw-r--r--net/bluetooth/hci_conn.c14
-rw-r--r--net/bluetooth/hci_core.c16
-rw-r--r--net/bluetooth/hci_event.c50
-rw-r--r--net/bluetooth/hci_sock.c2
-rw-r--r--net/bluetooth/l2cap_core.c7
-rw-r--r--net/bluetooth/mgmt.c83
-rw-r--r--net/bluetooth/rfcomm/core.c6
-rw-r--r--net/bluetooth/smp.c34
-rw-r--r--net/ieee802154/6lowpan_rtnl.c108
-rw-r--r--net/ieee802154/Makefile4
-rw-r--r--net/ieee802154/af802154.h4
-rw-r--r--net/ieee802154/af_ieee802154.c4
-rw-r--r--net/ieee802154/core.c (renamed from net/ieee802154/wpan-class.c)79
-rw-r--r--net/ieee802154/dgram.c6
-rw-r--r--net/ieee802154/header_ops.c3
-rw-r--r--net/ieee802154/ieee802154.h4
-rw-r--r--net/ieee802154/netlink.c4
-rw-r--r--net/ieee802154/nl-mac.c27
-rw-r--r--net/ieee802154/nl-phy.c6
-rw-r--r--net/ieee802154/nl_policy.c4
-rw-r--r--net/ieee802154/raw.c4
-rw-r--r--net/ieee802154/reassembly.c8
-rw-r--r--net/ieee802154/reassembly.h4
-rw-r--r--net/ieee802154/sysfs.c94
-rw-r--r--net/ieee802154/sysfs.h9
-rw-r--r--net/mac80211/Kconfig18
-rw-r--r--net/mac80211/Makefile3
-rw-r--r--net/mac80211/agg-tx.c5
-rw-r--r--net/mac80211/cfg.c178
-rw-r--r--net/mac80211/chan.c5
-rw-r--r--net/mac80211/debug.h10
-rw-r--r--net/mac80211/debugfs_key.c12
-rw-r--r--net/mac80211/driver-ops.h74
-rw-r--r--net/mac80211/ieee80211_i.h80
-rw-r--r--net/mac80211/iface.c30
-rw-r--r--net/mac80211/key.c11
-rw-r--r--net/mac80211/main.c38
-rw-r--r--net/mac80211/mesh.h3
-rw-r--r--net/mac80211/mesh_pathtbl.c31
-rw-r--r--net/mac80211/mlme.c281
-rw-r--r--net/mac80211/ocb.c250
-rw-r--r--net/mac80211/rc80211_minstrel.c2
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c313
-rw-r--r--net/mac80211/rc80211_minstrel_ht.h40
-rw-r--r--net/mac80211/rc80211_minstrel_ht_debugfs.c43
-rw-r--r--net/mac80211/rx.c35
-rw-r--r--net/mac80211/sta_info.c4
-rw-r--r--net/mac80211/status.c3
-rw-r--r--net/mac80211/tdls.c8
-rw-r--r--net/mac80211/trace.h100
-rw-r--r--net/mac80211/tx.c15
-rw-r--r--net/mac80211/util.c132
-rw-r--r--net/mac80211/wep.c2
-rw-r--r--net/mac80211/wme.c33
-rw-r--r--net/mac80211/wme.h2
-rw-r--r--net/mac80211/wpa.c5
-rw-r--r--net/mac802154/Kconfig2
-rw-r--r--net/mac802154/Makefile4
-rw-r--r--net/mac802154/driver-ops.h226
-rw-r--r--net/mac802154/ieee802154_dev.c415
-rw-r--r--net/mac802154/ieee802154_i.h (renamed from net/mac802154/mac802154.h)87
-rw-r--r--net/mac802154/iface.c466
-rw-r--r--net/mac802154/llsec.c4
-rw-r--r--net/mac802154/mac_cmd.c36
-rw-r--r--net/mac802154/main.c265
-rw-r--r--net/mac802154/mib.c240
-rw-r--r--net/mac802154/monitor.c117
-rw-r--r--net/mac802154/rx.c311
-rw-r--r--net/mac802154/tx.c154
-rw-r--r--net/mac802154/util.c55
-rw-r--r--net/mac802154/wpan.c599
-rw-r--r--net/wireless/Makefile2
-rw-r--r--net/wireless/chan.c10
-rw-r--r--net/wireless/core.c77
-rw-r--r--net/wireless/core.h12
-rw-r--r--net/wireless/nl80211.c196
-rw-r--r--net/wireless/ocb.c88
-rw-r--r--net/wireless/rdev-ops.h55
-rw-r--r--net/wireless/sme.c13
-rw-r--r--net/wireless/trace.h97
-rw-r--r--net/wireless/util.c5
83 files changed, 4065 insertions, 2176 deletions
diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c
index 142eef55c9e2..73a7065f0c6b 100644
--- a/net/6lowpan/iphc.c
+++ b/net/6lowpan/iphc.c
@@ -171,37 +171,6 @@ static int uncompress_context_based_src_addr(struct sk_buff *skb,
171 return 0; 171 return 0;
172} 172}
173 173
174static int skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr,
175 struct net_device *dev, skb_delivery_cb deliver_skb)
176{
177 struct sk_buff *new;
178 int stat;
179
180 new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb),
181 GFP_ATOMIC);
182 kfree_skb(skb);
183
184 if (!new)
185 return -ENOMEM;
186
187 skb_push(new, sizeof(struct ipv6hdr));
188 skb_reset_network_header(new);
189 skb_copy_to_linear_data(new, hdr, sizeof(struct ipv6hdr));
190
191 new->protocol = htons(ETH_P_IPV6);
192 new->pkt_type = PACKET_HOST;
193 new->dev = dev;
194
195 raw_dump_table(__func__, "raw skb data dump before receiving",
196 new->data, new->len);
197
198 stat = deliver_skb(new, dev);
199
200 kfree_skb(new);
201
202 return stat;
203}
204
205/* Uncompress function for multicast destination address, 174/* Uncompress function for multicast destination address,
206 * when M bit is set. 175 * when M bit is set.
207 */ 176 */
@@ -332,10 +301,12 @@ err:
332/* TTL uncompression values */ 301/* TTL uncompression values */
333static const u8 lowpan_ttl_values[] = { 0, 1, 64, 255 }; 302static const u8 lowpan_ttl_values[] = { 0, 1, 64, 255 };
334 303
335int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, 304int
336 const u8 *saddr, const u8 saddr_type, const u8 saddr_len, 305lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
337 const u8 *daddr, const u8 daddr_type, const u8 daddr_len, 306 const u8 *saddr, const u8 saddr_type,
338 u8 iphc0, u8 iphc1, skb_delivery_cb deliver_skb) 307 const u8 saddr_len, const u8 *daddr,
308 const u8 daddr_type, const u8 daddr_len,
309 u8 iphc0, u8 iphc1)
339{ 310{
340 struct ipv6hdr hdr = {}; 311 struct ipv6hdr hdr = {};
341 u8 tmp, num_context = 0; 312 u8 tmp, num_context = 0;
@@ -460,7 +431,7 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
460 /* UDP data uncompression */ 431 /* UDP data uncompression */
461 if (iphc0 & LOWPAN_IPHC_NH_C) { 432 if (iphc0 & LOWPAN_IPHC_NH_C) {
462 struct udphdr uh; 433 struct udphdr uh;
463 struct sk_buff *new; 434 const int needed = sizeof(struct udphdr) + sizeof(hdr);
464 435
465 if (uncompress_udp_header(skb, &uh)) 436 if (uncompress_udp_header(skb, &uh))
466 goto drop; 437 goto drop;
@@ -468,14 +439,11 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
468 /* replace the compressed UDP head by the uncompressed UDP 439 /* replace the compressed UDP head by the uncompressed UDP
469 * header 440 * header
470 */ 441 */
471 new = skb_copy_expand(skb, sizeof(struct udphdr), 442 err = skb_cow(skb, needed);
472 skb_tailroom(skb), GFP_ATOMIC); 443 if (unlikely(err)) {
473 kfree_skb(skb); 444 kfree_skb(skb);
474 445 return err;
475 if (!new) 446 }
476 return -ENOMEM;
477
478 skb = new;
479 447
480 skb_push(skb, sizeof(struct udphdr)); 448 skb_push(skb, sizeof(struct udphdr));
481 skb_reset_transport_header(skb); 449 skb_reset_transport_header(skb);
@@ -485,6 +453,12 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
485 (u8 *)&uh, sizeof(uh)); 453 (u8 *)&uh, sizeof(uh));
486 454
487 hdr.nexthdr = UIP_PROTO_UDP; 455 hdr.nexthdr = UIP_PROTO_UDP;
456 } else {
457 err = skb_cow(skb, sizeof(hdr));
458 if (unlikely(err)) {
459 kfree_skb(skb);
460 return err;
461 }
488 } 462 }
489 463
490 hdr.payload_len = htons(skb->len); 464 hdr.payload_len = htons(skb->len);
@@ -497,15 +471,18 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
497 hdr.version, ntohs(hdr.payload_len), hdr.nexthdr, 471 hdr.version, ntohs(hdr.payload_len), hdr.nexthdr,
498 hdr.hop_limit, &hdr.daddr); 472 hdr.hop_limit, &hdr.daddr);
499 473
500 raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr)); 474 skb_push(skb, sizeof(hdr));
475 skb_reset_network_header(skb);
476 skb_copy_to_linear_data(skb, &hdr, sizeof(hdr));
501 477
502 return skb_deliver(skb, &hdr, dev, deliver_skb); 478 raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr));
503 479
480 return 0;
504drop: 481drop:
505 kfree_skb(skb); 482 kfree_skb(skb);
506 return -EINVAL; 483 return -EINVAL;
507} 484}
508EXPORT_SYMBOL_GPL(lowpan_process_data); 485EXPORT_SYMBOL_GPL(lowpan_header_decompress);
509 486
510static u8 lowpan_compress_addr_64(u8 **hc_ptr, u8 shift, 487static u8 lowpan_compress_addr_64(u8 **hc_ptr, u8 shift,
511 const struct in6_addr *ipaddr, 488 const struct in6_addr *ipaddr,
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index c2e0d14433df..eef298d17452 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -53,7 +53,7 @@ struct skb_cb {
53 * The list contains struct lowpan_dev elements. 53 * The list contains struct lowpan_dev elements.
54 */ 54 */
55static LIST_HEAD(bt_6lowpan_devices); 55static LIST_HEAD(bt_6lowpan_devices);
56static DEFINE_RWLOCK(devices_lock); 56static DEFINE_SPINLOCK(devices_lock);
57 57
58/* If psm is set to 0 (default value), then 6lowpan is disabled. 58/* If psm is set to 0 (default value), then 6lowpan is disabled.
59 * Other values are used to indicate a Protocol Service Multiplexer 59 * Other values are used to indicate a Protocol Service Multiplexer
@@ -67,6 +67,7 @@ static struct l2cap_chan *listen_chan;
67 67
68struct lowpan_peer { 68struct lowpan_peer {
69 struct list_head list; 69 struct list_head list;
70 struct rcu_head rcu;
70 struct l2cap_chan *chan; 71 struct l2cap_chan *chan;
71 72
72 /* peer addresses in various formats */ 73 /* peer addresses in various formats */
@@ -86,6 +87,13 @@ struct lowpan_dev {
86 struct delayed_work notify_peers; 87 struct delayed_work notify_peers;
87}; 88};
88 89
90static inline void peer_free(struct rcu_head *head)
91{
92 struct lowpan_peer *e = container_of(head, struct lowpan_peer, rcu);
93
94 kfree(e);
95}
96
89static inline struct lowpan_dev *lowpan_dev(const struct net_device *netdev) 97static inline struct lowpan_dev *lowpan_dev(const struct net_device *netdev)
90{ 98{
91 return netdev_priv(netdev); 99 return netdev_priv(netdev);
@@ -93,13 +101,14 @@ static inline struct lowpan_dev *lowpan_dev(const struct net_device *netdev)
93 101
94static inline void peer_add(struct lowpan_dev *dev, struct lowpan_peer *peer) 102static inline void peer_add(struct lowpan_dev *dev, struct lowpan_peer *peer)
95{ 103{
96 list_add(&peer->list, &dev->peers); 104 list_add_rcu(&peer->list, &dev->peers);
97 atomic_inc(&dev->peer_count); 105 atomic_inc(&dev->peer_count);
98} 106}
99 107
100static inline bool peer_del(struct lowpan_dev *dev, struct lowpan_peer *peer) 108static inline bool peer_del(struct lowpan_dev *dev, struct lowpan_peer *peer)
101{ 109{
102 list_del(&peer->list); 110 list_del_rcu(&peer->list);
111 call_rcu(&peer->rcu, peer_free);
103 112
104 module_put(THIS_MODULE); 113 module_put(THIS_MODULE);
105 114
@@ -114,31 +123,37 @@ static inline bool peer_del(struct lowpan_dev *dev, struct lowpan_peer *peer)
114static inline struct lowpan_peer *peer_lookup_ba(struct lowpan_dev *dev, 123static inline struct lowpan_peer *peer_lookup_ba(struct lowpan_dev *dev,
115 bdaddr_t *ba, __u8 type) 124 bdaddr_t *ba, __u8 type)
116{ 125{
117 struct lowpan_peer *peer, *tmp; 126 struct lowpan_peer *peer;
118 127
119 BT_DBG("peers %d addr %pMR type %d", atomic_read(&dev->peer_count), 128 BT_DBG("peers %d addr %pMR type %d", atomic_read(&dev->peer_count),
120 ba, type); 129 ba, type);
121 130
122 list_for_each_entry_safe(peer, tmp, &dev->peers, list) { 131 rcu_read_lock();
132
133 list_for_each_entry_rcu(peer, &dev->peers, list) {
123 BT_DBG("dst addr %pMR dst type %d", 134 BT_DBG("dst addr %pMR dst type %d",
124 &peer->chan->dst, peer->chan->dst_type); 135 &peer->chan->dst, peer->chan->dst_type);
125 136
126 if (bacmp(&peer->chan->dst, ba)) 137 if (bacmp(&peer->chan->dst, ba))
127 continue; 138 continue;
128 139
129 if (type == peer->chan->dst_type) 140 if (type == peer->chan->dst_type) {
141 rcu_read_unlock();
130 return peer; 142 return peer;
143 }
131 } 144 }
132 145
146 rcu_read_unlock();
147
133 return NULL; 148 return NULL;
134} 149}
135 150
136static inline struct lowpan_peer *peer_lookup_chan(struct lowpan_dev *dev, 151static inline struct lowpan_peer *__peer_lookup_chan(struct lowpan_dev *dev,
137 struct l2cap_chan *chan) 152 struct l2cap_chan *chan)
138{ 153{
139 struct lowpan_peer *peer, *tmp; 154 struct lowpan_peer *peer;
140 155
141 list_for_each_entry_safe(peer, tmp, &dev->peers, list) { 156 list_for_each_entry_rcu(peer, &dev->peers, list) {
142 if (peer->chan == chan) 157 if (peer->chan == chan)
143 return peer; 158 return peer;
144 } 159 }
@@ -146,12 +161,12 @@ static inline struct lowpan_peer *peer_lookup_chan(struct lowpan_dev *dev,
146 return NULL; 161 return NULL;
147} 162}
148 163
149static inline struct lowpan_peer *peer_lookup_conn(struct lowpan_dev *dev, 164static inline struct lowpan_peer *__peer_lookup_conn(struct lowpan_dev *dev,
150 struct l2cap_conn *conn) 165 struct l2cap_conn *conn)
151{ 166{
152 struct lowpan_peer *peer, *tmp; 167 struct lowpan_peer *peer;
153 168
154 list_for_each_entry_safe(peer, tmp, &dev->peers, list) { 169 list_for_each_entry_rcu(peer, &dev->peers, list) {
155 if (peer->chan->conn == conn) 170 if (peer->chan->conn == conn)
156 return peer; 171 return peer;
157 } 172 }
@@ -163,7 +178,7 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_dev *dev,
163 struct in6_addr *daddr, 178 struct in6_addr *daddr,
164 struct sk_buff *skb) 179 struct sk_buff *skb)
165{ 180{
166 struct lowpan_peer *peer, *tmp; 181 struct lowpan_peer *peer;
167 struct in6_addr *nexthop; 182 struct in6_addr *nexthop;
168 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb); 183 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
169 int count = atomic_read(&dev->peer_count); 184 int count = atomic_read(&dev->peer_count);
@@ -174,9 +189,13 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_dev *dev,
174 * send the packet. If only one peer exists, then we can send the 189 * send the packet. If only one peer exists, then we can send the
175 * packet right away. 190 * packet right away.
176 */ 191 */
177 if (count == 1) 192 if (count == 1) {
178 return list_first_entry(&dev->peers, struct lowpan_peer, 193 rcu_read_lock();
179 list); 194 peer = list_first_or_null_rcu(&dev->peers, struct lowpan_peer,
195 list);
196 rcu_read_unlock();
197 return peer;
198 }
180 199
181 if (!rt) { 200 if (!rt) {
182 nexthop = &lowpan_cb(skb)->gw; 201 nexthop = &lowpan_cb(skb)->gw;
@@ -195,53 +214,57 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_dev *dev,
195 214
196 BT_DBG("gw %pI6c", nexthop); 215 BT_DBG("gw %pI6c", nexthop);
197 216
198 list_for_each_entry_safe(peer, tmp, &dev->peers, list) { 217 rcu_read_lock();
218
219 list_for_each_entry_rcu(peer, &dev->peers, list) {
199 BT_DBG("dst addr %pMR dst type %d ip %pI6c", 220 BT_DBG("dst addr %pMR dst type %d ip %pI6c",
200 &peer->chan->dst, peer->chan->dst_type, 221 &peer->chan->dst, peer->chan->dst_type,
201 &peer->peer_addr); 222 &peer->peer_addr);
202 223
203 if (!ipv6_addr_cmp(&peer->peer_addr, nexthop)) 224 if (!ipv6_addr_cmp(&peer->peer_addr, nexthop)) {
225 rcu_read_unlock();
204 return peer; 226 return peer;
227 }
205 } 228 }
206 229
230 rcu_read_unlock();
231
207 return NULL; 232 return NULL;
208} 233}
209 234
210static struct lowpan_peer *lookup_peer(struct l2cap_conn *conn) 235static struct lowpan_peer *lookup_peer(struct l2cap_conn *conn)
211{ 236{
212 struct lowpan_dev *entry, *tmp; 237 struct lowpan_dev *entry;
213 struct lowpan_peer *peer = NULL; 238 struct lowpan_peer *peer = NULL;
214 unsigned long flags;
215 239
216 read_lock_irqsave(&devices_lock, flags); 240 rcu_read_lock();
217 241
218 list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) { 242 list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
219 peer = peer_lookup_conn(entry, conn); 243 peer = __peer_lookup_conn(entry, conn);
220 if (peer) 244 if (peer)
221 break; 245 break;
222 } 246 }
223 247
224 read_unlock_irqrestore(&devices_lock, flags); 248 rcu_read_unlock();
225 249
226 return peer; 250 return peer;
227} 251}
228 252
229static struct lowpan_dev *lookup_dev(struct l2cap_conn *conn) 253static struct lowpan_dev *lookup_dev(struct l2cap_conn *conn)
230{ 254{
231 struct lowpan_dev *entry, *tmp; 255 struct lowpan_dev *entry;
232 struct lowpan_dev *dev = NULL; 256 struct lowpan_dev *dev = NULL;
233 unsigned long flags;
234 257
235 read_lock_irqsave(&devices_lock, flags); 258 rcu_read_lock();
236 259
237 list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) { 260 list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
238 if (conn->hcon->hdev == entry->hdev) { 261 if (conn->hcon->hdev == entry->hdev) {
239 dev = entry; 262 dev = entry;
240 break; 263 break;
241 } 264 }
242 } 265 }
243 266
244 read_unlock_irqrestore(&devices_lock, flags); 267 rcu_read_unlock();
245 268
246 return dev; 269 return dev;
247} 270}
@@ -249,35 +272,27 @@ static struct lowpan_dev *lookup_dev(struct l2cap_conn *conn)
249static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev) 272static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev)
250{ 273{
251 struct sk_buff *skb_cp; 274 struct sk_buff *skb_cp;
252 int ret;
253 275
254 skb_cp = skb_copy(skb, GFP_ATOMIC); 276 skb_cp = skb_copy(skb, GFP_ATOMIC);
255 if (!skb_cp) 277 if (!skb_cp)
256 return -ENOMEM;
257
258 ret = netif_rx(skb_cp);
259 if (ret < 0) {
260 BT_DBG("receive skb %d", ret);
261 return NET_RX_DROP; 278 return NET_RX_DROP;
262 }
263 279
264 return ret; 280 return netif_rx(skb_cp);
265} 281}
266 282
267static int process_data(struct sk_buff *skb, struct net_device *netdev, 283static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev,
268 struct l2cap_chan *chan) 284 struct l2cap_chan *chan)
269{ 285{
270 const u8 *saddr, *daddr; 286 const u8 *saddr, *daddr;
271 u8 iphc0, iphc1; 287 u8 iphc0, iphc1;
272 struct lowpan_dev *dev; 288 struct lowpan_dev *dev;
273 struct lowpan_peer *peer; 289 struct lowpan_peer *peer;
274 unsigned long flags;
275 290
276 dev = lowpan_dev(netdev); 291 dev = lowpan_dev(netdev);
277 292
278 read_lock_irqsave(&devices_lock, flags); 293 rcu_read_lock();
279 peer = peer_lookup_chan(dev, chan); 294 peer = __peer_lookup_chan(dev, chan);
280 read_unlock_irqrestore(&devices_lock, flags); 295 rcu_read_unlock();
281 if (!peer) 296 if (!peer)
282 goto drop; 297 goto drop;
283 298
@@ -294,10 +309,11 @@ static int process_data(struct sk_buff *skb, struct net_device *netdev,
294 if (lowpan_fetch_skb_u8(skb, &iphc1)) 309 if (lowpan_fetch_skb_u8(skb, &iphc1))
295 goto drop; 310 goto drop;
296 311
297 return lowpan_process_data(skb, netdev, 312 return lowpan_header_decompress(skb, netdev,
298 saddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, 313 saddr, IEEE802154_ADDR_LONG,
299 daddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, 314 EUI64_ADDR_LEN, daddr,
300 iphc0, iphc1, give_skb_to_upper); 315 IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
316 iphc0, iphc1);
301 317
302drop: 318drop:
303 kfree_skb(skb); 319 kfree_skb(skb);
@@ -316,6 +332,10 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
316 if (dev->type != ARPHRD_6LOWPAN) 332 if (dev->type != ARPHRD_6LOWPAN)
317 goto drop; 333 goto drop;
318 334
335 skb = skb_share_check(skb, GFP_ATOMIC);
336 if (!skb)
337 goto drop;
338
319 /* check that it's our buffer */ 339 /* check that it's our buffer */
320 if (skb->data[0] == LOWPAN_DISPATCH_IPV6) { 340 if (skb->data[0] == LOWPAN_DISPATCH_IPV6) {
321 /* Copy the packet so that the IPv6 header is 341 /* Copy the packet so that the IPv6 header is
@@ -340,8 +360,8 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
340 dev->stats.rx_bytes += skb->len; 360 dev->stats.rx_bytes += skb->len;
341 dev->stats.rx_packets++; 361 dev->stats.rx_packets++;
342 362
343 kfree_skb(local_skb); 363 consume_skb(local_skb);
344 kfree_skb(skb); 364 consume_skb(skb);
345 } else { 365 } else {
346 switch (skb->data[0] & 0xe0) { 366 switch (skb->data[0] & 0xe0) {
347 case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ 367 case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */
@@ -349,14 +369,25 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
349 if (!local_skb) 369 if (!local_skb)
350 goto drop; 370 goto drop;
351 371
352 ret = process_data(local_skb, dev, chan); 372 ret = iphc_decompress(local_skb, dev, chan);
353 if (ret != NET_RX_SUCCESS) 373 if (ret < 0)
354 goto drop; 374 goto drop;
355 375
376 local_skb->protocol = htons(ETH_P_IPV6);
377 local_skb->pkt_type = PACKET_HOST;
378 local_skb->dev = dev;
379
380 if (give_skb_to_upper(local_skb, dev)
381 != NET_RX_SUCCESS) {
382 kfree_skb(local_skb);
383 goto drop;
384 }
385
356 dev->stats.rx_bytes += skb->len; 386 dev->stats.rx_bytes += skb->len;
357 dev->stats.rx_packets++; 387 dev->stats.rx_packets++;
358 388
359 kfree_skb(skb); 389 consume_skb(local_skb);
390 consume_skb(skb);
360 break; 391 break;
361 default: 392 default:
362 break; 393 break;
@@ -443,7 +474,6 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev,
443 if (ipv6_addr_is_multicast(&ipv6_daddr)) { 474 if (ipv6_addr_is_multicast(&ipv6_daddr)) {
444 lowpan_cb(skb)->chan = NULL; 475 lowpan_cb(skb)->chan = NULL;
445 } else { 476 } else {
446 unsigned long flags;
447 u8 addr_type; 477 u8 addr_type;
448 478
449 /* Get destination BT device from skb. 479 /* Get destination BT device from skb.
@@ -454,19 +484,14 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev,
454 BT_DBG("dest addr %pMR type %d IP %pI6c", &addr, 484 BT_DBG("dest addr %pMR type %d IP %pI6c", &addr,
455 addr_type, &ipv6_daddr); 485 addr_type, &ipv6_daddr);
456 486
457 read_lock_irqsave(&devices_lock, flags);
458 peer = peer_lookup_ba(dev, &addr, addr_type); 487 peer = peer_lookup_ba(dev, &addr, addr_type);
459 read_unlock_irqrestore(&devices_lock, flags);
460
461 if (!peer) { 488 if (!peer) {
462 /* The packet might be sent to 6lowpan interface 489 /* The packet might be sent to 6lowpan interface
463 * because of routing (either via default route 490 * because of routing (either via default route
464 * or user set route) so get peer according to 491 * or user set route) so get peer according to
465 * the destination address. 492 * the destination address.
466 */ 493 */
467 read_lock_irqsave(&devices_lock, flags);
468 peer = peer_lookup_dst(dev, &ipv6_daddr, skb); 494 peer = peer_lookup_dst(dev, &ipv6_daddr, skb);
469 read_unlock_irqrestore(&devices_lock, flags);
470 if (!peer) { 495 if (!peer) {
471 BT_DBG("no such peer %pMR found", &addr); 496 BT_DBG("no such peer %pMR found", &addr);
472 return -ENOENT; 497 return -ENOENT;
@@ -549,14 +574,13 @@ static int send_pkt(struct l2cap_chan *chan, struct sk_buff *skb,
549static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev) 574static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
550{ 575{
551 struct sk_buff *local_skb; 576 struct sk_buff *local_skb;
552 struct lowpan_dev *entry, *tmp; 577 struct lowpan_dev *entry;
553 unsigned long flags;
554 int err = 0; 578 int err = 0;
555 579
556 read_lock_irqsave(&devices_lock, flags); 580 rcu_read_lock();
557 581
558 list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) { 582 list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
559 struct lowpan_peer *pentry, *ptmp; 583 struct lowpan_peer *pentry;
560 struct lowpan_dev *dev; 584 struct lowpan_dev *dev;
561 585
562 if (entry->netdev != netdev) 586 if (entry->netdev != netdev)
@@ -564,7 +588,7 @@ static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
564 588
565 dev = lowpan_dev(entry->netdev); 589 dev = lowpan_dev(entry->netdev);
566 590
567 list_for_each_entry_safe(pentry, ptmp, &dev->peers, list) { 591 list_for_each_entry_rcu(pentry, &dev->peers, list) {
568 int ret; 592 int ret;
569 593
570 local_skb = skb_clone(skb, GFP_ATOMIC); 594 local_skb = skb_clone(skb, GFP_ATOMIC);
@@ -581,7 +605,7 @@ static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
581 } 605 }
582 } 606 }
583 607
584 read_unlock_irqrestore(&devices_lock, flags); 608 rcu_read_unlock();
585 609
586 return err; 610 return err;
587} 611}
@@ -638,7 +662,26 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev)
638 return err < 0 ? NET_XMIT_DROP : err; 662 return err < 0 ? NET_XMIT_DROP : err;
639} 663}
640 664
665static struct lock_class_key bt_tx_busylock;
666static struct lock_class_key bt_netdev_xmit_lock_key;
667
668static void bt_set_lockdep_class_one(struct net_device *dev,
669 struct netdev_queue *txq,
670 void *_unused)
671{
672 lockdep_set_class(&txq->_xmit_lock, &bt_netdev_xmit_lock_key);
673}
674
675static int bt_dev_init(struct net_device *dev)
676{
677 netdev_for_each_tx_queue(dev, bt_set_lockdep_class_one, NULL);
678 dev->qdisc_tx_busylock = &bt_tx_busylock;
679
680 return 0;
681}
682
641static const struct net_device_ops netdev_ops = { 683static const struct net_device_ops netdev_ops = {
684 .ndo_init = bt_dev_init,
642 .ndo_start_xmit = bt_xmit, 685 .ndo_start_xmit = bt_xmit,
643}; 686};
644 687
@@ -783,7 +826,6 @@ static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan,
783 struct lowpan_dev *dev) 826 struct lowpan_dev *dev)
784{ 827{
785 struct lowpan_peer *peer; 828 struct lowpan_peer *peer;
786 unsigned long flags;
787 829
788 peer = kzalloc(sizeof(*peer), GFP_ATOMIC); 830 peer = kzalloc(sizeof(*peer), GFP_ATOMIC);
789 if (!peer) 831 if (!peer)
@@ -806,10 +848,10 @@ static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan,
806 */ 848 */
807 set_ip_addr_bits(chan->dst_type, (u8 *)&peer->peer_addr.s6_addr + 8); 849 set_ip_addr_bits(chan->dst_type, (u8 *)&peer->peer_addr.s6_addr + 8);
808 850
809 write_lock_irqsave(&devices_lock, flags); 851 spin_lock(&devices_lock);
810 INIT_LIST_HEAD(&peer->list); 852 INIT_LIST_HEAD(&peer->list);
811 peer_add(dev, peer); 853 peer_add(dev, peer);
812 write_unlock_irqrestore(&devices_lock, flags); 854 spin_unlock(&devices_lock);
813 855
814 /* Notifying peers about us needs to be done without locks held */ 856 /* Notifying peers about us needs to be done without locks held */
815 INIT_DELAYED_WORK(&dev->notify_peers, do_notify_peers); 857 INIT_DELAYED_WORK(&dev->notify_peers, do_notify_peers);
@@ -822,7 +864,6 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev)
822{ 864{
823 struct net_device *netdev; 865 struct net_device *netdev;
824 int err = 0; 866 int err = 0;
825 unsigned long flags;
826 867
827 netdev = alloc_netdev(sizeof(struct lowpan_dev), IFACE_NAME_TEMPLATE, 868 netdev = alloc_netdev(sizeof(struct lowpan_dev), IFACE_NAME_TEMPLATE,
828 NET_NAME_UNKNOWN, netdev_setup); 869 NET_NAME_UNKNOWN, netdev_setup);
@@ -852,10 +893,10 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev)
852 (*dev)->hdev = chan->conn->hcon->hdev; 893 (*dev)->hdev = chan->conn->hcon->hdev;
853 INIT_LIST_HEAD(&(*dev)->peers); 894 INIT_LIST_HEAD(&(*dev)->peers);
854 895
855 write_lock_irqsave(&devices_lock, flags); 896 spin_lock(&devices_lock);
856 INIT_LIST_HEAD(&(*dev)->list); 897 INIT_LIST_HEAD(&(*dev)->list);
857 list_add(&(*dev)->list, &bt_6lowpan_devices); 898 list_add_rcu(&(*dev)->list, &bt_6lowpan_devices);
858 write_unlock_irqrestore(&devices_lock, flags); 899 spin_unlock(&devices_lock);
859 900
860 return 0; 901 return 0;
861 902
@@ -909,11 +950,10 @@ static void delete_netdev(struct work_struct *work)
909 950
910static void chan_close_cb(struct l2cap_chan *chan) 951static void chan_close_cb(struct l2cap_chan *chan)
911{ 952{
912 struct lowpan_dev *entry, *tmp; 953 struct lowpan_dev *entry;
913 struct lowpan_dev *dev = NULL; 954 struct lowpan_dev *dev = NULL;
914 struct lowpan_peer *peer; 955 struct lowpan_peer *peer;
915 int err = -ENOENT; 956 int err = -ENOENT;
916 unsigned long flags;
917 bool last = false, removed = true; 957 bool last = false, removed = true;
918 958
919 BT_DBG("chan %p conn %p", chan, chan->conn); 959 BT_DBG("chan %p conn %p", chan, chan->conn);
@@ -928,11 +968,11 @@ static void chan_close_cb(struct l2cap_chan *chan)
928 removed = false; 968 removed = false;
929 } 969 }
930 970
931 write_lock_irqsave(&devices_lock, flags); 971 spin_lock(&devices_lock);
932 972
933 list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) { 973 list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
934 dev = lowpan_dev(entry->netdev); 974 dev = lowpan_dev(entry->netdev);
935 peer = peer_lookup_chan(dev, chan); 975 peer = __peer_lookup_chan(dev, chan);
936 if (peer) { 976 if (peer) {
937 last = peer_del(dev, peer); 977 last = peer_del(dev, peer);
938 err = 0; 978 err = 0;
@@ -943,13 +983,12 @@ static void chan_close_cb(struct l2cap_chan *chan)
943 atomic_read(&chan->kref.refcount)); 983 atomic_read(&chan->kref.refcount));
944 984
945 l2cap_chan_put(chan); 985 l2cap_chan_put(chan);
946 kfree(peer);
947 break; 986 break;
948 } 987 }
949 } 988 }
950 989
951 if (!err && last && dev && !atomic_read(&dev->peer_count)) { 990 if (!err && last && dev && !atomic_read(&dev->peer_count)) {
952 write_unlock_irqrestore(&devices_lock, flags); 991 spin_unlock(&devices_lock);
953 992
954 cancel_delayed_work_sync(&dev->notify_peers); 993 cancel_delayed_work_sync(&dev->notify_peers);
955 994
@@ -960,7 +999,7 @@ static void chan_close_cb(struct l2cap_chan *chan)
960 schedule_work(&entry->delete_netdev); 999 schedule_work(&entry->delete_netdev);
961 } 1000 }
962 } else { 1001 } else {
963 write_unlock_irqrestore(&devices_lock, flags); 1002 spin_unlock(&devices_lock);
964 } 1003 }
965 1004
966 return; 1005 return;
@@ -1152,10 +1191,9 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
1152 1191
1153static void disconnect_all_peers(void) 1192static void disconnect_all_peers(void)
1154{ 1193{
1155 struct lowpan_dev *entry, *tmp_dev; 1194 struct lowpan_dev *entry;
1156 struct lowpan_peer *peer, *tmp_peer, *new_peer; 1195 struct lowpan_peer *peer, *tmp_peer, *new_peer;
1157 struct list_head peers; 1196 struct list_head peers;
1158 unsigned long flags;
1159 1197
1160 INIT_LIST_HEAD(&peers); 1198 INIT_LIST_HEAD(&peers);
1161 1199
@@ -1164,10 +1202,10 @@ static void disconnect_all_peers(void)
1164 * with the same list at the same time. 1202 * with the same list at the same time.
1165 */ 1203 */
1166 1204
1167 read_lock_irqsave(&devices_lock, flags); 1205 rcu_read_lock();
1168 1206
1169 list_for_each_entry_safe(entry, tmp_dev, &bt_6lowpan_devices, list) { 1207 list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
1170 list_for_each_entry_safe(peer, tmp_peer, &entry->peers, list) { 1208 list_for_each_entry_rcu(peer, &entry->peers, list) {
1171 new_peer = kmalloc(sizeof(*new_peer), GFP_ATOMIC); 1209 new_peer = kmalloc(sizeof(*new_peer), GFP_ATOMIC);
1172 if (!new_peer) 1210 if (!new_peer)
1173 break; 1211 break;
@@ -1179,26 +1217,36 @@ static void disconnect_all_peers(void)
1179 } 1217 }
1180 } 1218 }
1181 1219
1182 read_unlock_irqrestore(&devices_lock, flags); 1220 rcu_read_unlock();
1183 1221
1222 spin_lock(&devices_lock);
1184 list_for_each_entry_safe(peer, tmp_peer, &peers, list) { 1223 list_for_each_entry_safe(peer, tmp_peer, &peers, list) {
1185 l2cap_chan_close(peer->chan, ENOENT); 1224 l2cap_chan_close(peer->chan, ENOENT);
1186 kfree(peer); 1225
1226 list_del_rcu(&peer->list);
1227 call_rcu(&peer->rcu, peer_free);
1228
1229 module_put(THIS_MODULE);
1187 } 1230 }
1231 spin_unlock(&devices_lock);
1188} 1232}
1189 1233
1190static int lowpan_psm_set(void *data, u64 val) 1234struct set_psm {
1191{ 1235 struct work_struct work;
1192 u16 psm; 1236 u16 psm;
1237};
1238
1239static void do_psm_set(struct work_struct *work)
1240{
1241 struct set_psm *set_psm = container_of(work, struct set_psm, work);
1193 1242
1194 psm = val; 1243 if (set_psm->psm == 0 || psm_6lowpan != set_psm->psm)
1195 if (psm == 0 || psm_6lowpan != psm)
1196 /* Disconnect existing connections if 6lowpan is 1244 /* Disconnect existing connections if 6lowpan is
1197 * disabled (psm = 0), or if psm changes. 1245 * disabled (psm = 0), or if psm changes.
1198 */ 1246 */
1199 disconnect_all_peers(); 1247 disconnect_all_peers();
1200 1248
1201 psm_6lowpan = psm; 1249 psm_6lowpan = set_psm->psm;
1202 1250
1203 if (listen_chan) { 1251 if (listen_chan) {
1204 l2cap_chan_close(listen_chan, 0); 1252 l2cap_chan_close(listen_chan, 0);
@@ -1207,6 +1255,22 @@ static int lowpan_psm_set(void *data, u64 val)
1207 1255
1208 listen_chan = bt_6lowpan_listen(); 1256 listen_chan = bt_6lowpan_listen();
1209 1257
1258 kfree(set_psm);
1259}
1260
1261static int lowpan_psm_set(void *data, u64 val)
1262{
1263 struct set_psm *set_psm;
1264
1265 set_psm = kzalloc(sizeof(*set_psm), GFP_KERNEL);
1266 if (!set_psm)
1267 return -ENOMEM;
1268
1269 set_psm->psm = val;
1270 INIT_WORK(&set_psm->work, do_psm_set);
1271
1272 schedule_work(&set_psm->work);
1273
1210 return 0; 1274 return 0;
1211} 1275}
1212 1276
@@ -1288,19 +1352,18 @@ static ssize_t lowpan_control_write(struct file *fp,
1288 1352
1289static int lowpan_control_show(struct seq_file *f, void *ptr) 1353static int lowpan_control_show(struct seq_file *f, void *ptr)
1290{ 1354{
1291 struct lowpan_dev *entry, *tmp_dev; 1355 struct lowpan_dev *entry;
1292 struct lowpan_peer *peer, *tmp_peer; 1356 struct lowpan_peer *peer;
1293 unsigned long flags;
1294 1357
1295 read_lock_irqsave(&devices_lock, flags); 1358 spin_lock(&devices_lock);
1296 1359
1297 list_for_each_entry_safe(entry, tmp_dev, &bt_6lowpan_devices, list) { 1360 list_for_each_entry(entry, &bt_6lowpan_devices, list) {
1298 list_for_each_entry_safe(peer, tmp_peer, &entry->peers, list) 1361 list_for_each_entry(peer, &entry->peers, list)
1299 seq_printf(f, "%pMR (type %u)\n", 1362 seq_printf(f, "%pMR (type %u)\n",
1300 &peer->chan->dst, peer->chan->dst_type); 1363 &peer->chan->dst, peer->chan->dst_type);
1301 } 1364 }
1302 1365
1303 read_unlock_irqrestore(&devices_lock, flags); 1366 spin_unlock(&devices_lock);
1304 1367
1305 return 0; 1368 return 0;
1306} 1369}
@@ -1322,7 +1385,6 @@ static void disconnect_devices(void)
1322{ 1385{
1323 struct lowpan_dev *entry, *tmp, *new_dev; 1386 struct lowpan_dev *entry, *tmp, *new_dev;
1324 struct list_head devices; 1387 struct list_head devices;
1325 unsigned long flags;
1326 1388
1327 INIT_LIST_HEAD(&devices); 1389 INIT_LIST_HEAD(&devices);
1328 1390
@@ -1331,9 +1393,9 @@ static void disconnect_devices(void)
1331 * devices list. 1393 * devices list.
1332 */ 1394 */
1333 1395
1334 read_lock_irqsave(&devices_lock, flags); 1396 rcu_read_lock();
1335 1397
1336 list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) { 1398 list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
1337 new_dev = kmalloc(sizeof(*new_dev), GFP_ATOMIC); 1399 new_dev = kmalloc(sizeof(*new_dev), GFP_ATOMIC);
1338 if (!new_dev) 1400 if (!new_dev)
1339 break; 1401 break;
@@ -1341,10 +1403,10 @@ static void disconnect_devices(void)
1341 new_dev->netdev = entry->netdev; 1403 new_dev->netdev = entry->netdev;
1342 INIT_LIST_HEAD(&new_dev->list); 1404 INIT_LIST_HEAD(&new_dev->list);
1343 1405
1344 list_add(&new_dev->list, &devices); 1406 list_add_rcu(&new_dev->list, &devices);
1345 } 1407 }
1346 1408
1347 read_unlock_irqrestore(&devices_lock, flags); 1409 rcu_read_unlock();
1348 1410
1349 list_for_each_entry_safe(entry, tmp, &devices, list) { 1411 list_for_each_entry_safe(entry, tmp, &devices, list) {
1350 ifdown(entry->netdev); 1412 ifdown(entry->netdev);
@@ -1359,17 +1421,15 @@ static int device_event(struct notifier_block *unused,
1359 unsigned long event, void *ptr) 1421 unsigned long event, void *ptr)
1360{ 1422{
1361 struct net_device *netdev = netdev_notifier_info_to_dev(ptr); 1423 struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
1362 struct lowpan_dev *entry, *tmp; 1424 struct lowpan_dev *entry;
1363 unsigned long flags;
1364 1425
1365 if (netdev->type != ARPHRD_6LOWPAN) 1426 if (netdev->type != ARPHRD_6LOWPAN)
1366 return NOTIFY_DONE; 1427 return NOTIFY_DONE;
1367 1428
1368 switch (event) { 1429 switch (event) {
1369 case NETDEV_UNREGISTER: 1430 case NETDEV_UNREGISTER:
1370 write_lock_irqsave(&devices_lock, flags); 1431 spin_lock(&devices_lock);
1371 list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, 1432 list_for_each_entry(entry, &bt_6lowpan_devices, list) {
1372 list) {
1373 if (entry->netdev == netdev) { 1433 if (entry->netdev == netdev) {
1374 BT_DBG("Unregistered netdev %s %p", 1434 BT_DBG("Unregistered netdev %s %p",
1375 netdev->name, netdev); 1435 netdev->name, netdev);
@@ -1378,7 +1438,7 @@ static int device_event(struct notifier_block *unused,
1378 break; 1438 break;
1379 } 1439 }
1380 } 1440 }
1381 write_unlock_irqrestore(&devices_lock, flags); 1441 spin_unlock(&devices_lock);
1382 break; 1442 break;
1383 } 1443 }
1384 1444
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index b9517bd17190..96887ae8375b 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -141,10 +141,11 @@ int hci_disconnect(struct hci_conn *conn, __u8 reason)
141 */ 141 */
142 if (conn->type == ACL_LINK && conn->role == HCI_ROLE_MASTER) { 142 if (conn->type == ACL_LINK && conn->role == HCI_ROLE_MASTER) {
143 struct hci_dev *hdev = conn->hdev; 143 struct hci_dev *hdev = conn->hdev;
144 struct hci_cp_read_clock_offset cp; 144 struct hci_cp_read_clock_offset clkoff_cp;
145 145
146 cp.handle = cpu_to_le16(conn->handle); 146 clkoff_cp.handle = cpu_to_le16(conn->handle);
147 hci_send_cmd(hdev, HCI_OP_READ_CLOCK_OFFSET, sizeof(cp), &cp); 147 hci_send_cmd(hdev, HCI_OP_READ_CLOCK_OFFSET, sizeof(clkoff_cp),
148 &clkoff_cp);
148 } 149 }
149 150
150 conn->state = BT_DISCONN; 151 conn->state = BT_DISCONN;
@@ -415,7 +416,7 @@ static void le_conn_timeout(struct work_struct *work)
415 * happen with broken hardware or if low duty cycle was used 416 * happen with broken hardware or if low duty cycle was used
416 * (which doesn't have a timeout of its own). 417 * (which doesn't have a timeout of its own).
417 */ 418 */
418 if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) { 419 if (conn->role == HCI_ROLE_SLAVE) {
419 u8 enable = 0x00; 420 u8 enable = 0x00;
420 hci_send_cmd(hdev, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), 421 hci_send_cmd(hdev, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable),
421 &enable); 422 &enable);
@@ -517,7 +518,7 @@ int hci_conn_del(struct hci_conn *conn)
517 /* Unacked frames */ 518 /* Unacked frames */
518 hdev->acl_cnt += conn->sent; 519 hdev->acl_cnt += conn->sent;
519 } else if (conn->type == LE_LINK) { 520 } else if (conn->type == LE_LINK) {
520 cancel_delayed_work_sync(&conn->le_conn_timeout); 521 cancel_delayed_work(&conn->le_conn_timeout);
521 522
522 if (hdev->le_pkts) 523 if (hdev->le_pkts)
523 hdev->le_cnt += conn->sent; 524 hdev->le_cnt += conn->sent;
@@ -544,6 +545,9 @@ int hci_conn_del(struct hci_conn *conn)
544 545
545 hci_conn_del_sysfs(conn); 546 hci_conn_del_sysfs(conn);
546 547
548 if (test_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags))
549 hci_conn_params_del(conn->hdev, &conn->dst, conn->dst_type);
550
547 hci_dev_put(hdev); 551 hci_dev_put(hdev);
548 552
549 hci_conn_put(conn); 553 hci_conn_put(conn);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index cb05d7f16a34..91995f8ab0a0 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -4477,7 +4477,7 @@ int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
4477 4477
4478 BT_DBG("length %u", skb_queue_len(&req->cmd_q)); 4478 BT_DBG("length %u", skb_queue_len(&req->cmd_q));
4479 4479
4480 /* If an error occured during request building, remove all HCI 4480 /* If an error occurred during request building, remove all HCI
4481 * commands queued on the HCI request queue. 4481 * commands queued on the HCI request queue.
4482 */ 4482 */
4483 if (req->err) { 4483 if (req->err) {
@@ -4546,7 +4546,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
4546 return -ENOMEM; 4546 return -ENOMEM;
4547 } 4547 }
4548 4548
4549 /* Stand-alone HCI commands must be flaged as 4549 /* Stand-alone HCI commands must be flagged as
4550 * single-command requests. 4550 * single-command requests.
4551 */ 4551 */
4552 bt_cb(skb)->req.start = true; 4552 bt_cb(skb)->req.start = true;
@@ -4566,7 +4566,7 @@ void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
4566 4566
4567 BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 4567 BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
4568 4568
4569 /* If an error occured during request building, there is no point in 4569 /* If an error occurred during request building, there is no point in
4570 * queueing the HCI command. We can simply return. 4570 * queueing the HCI command. We can simply return.
4571 */ 4571 */
4572 if (req->err) 4572 if (req->err)
@@ -4661,8 +4661,12 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
4661 4661
4662 skb_shinfo(skb)->frag_list = NULL; 4662 skb_shinfo(skb)->frag_list = NULL;
4663 4663
4664 /* Queue all fragments atomically */ 4664 /* Queue all fragments atomically. We need to use spin_lock_bh
4665 spin_lock(&queue->lock); 4665 * here because of 6LoWPAN links, as there this function is
4666 * called from softirq and using normal spin lock could cause
4667 * deadlocks.
4668 */
4669 spin_lock_bh(&queue->lock);
4666 4670
4667 __skb_queue_tail(queue, skb); 4671 __skb_queue_tail(queue, skb);
4668 4672
@@ -4679,7 +4683,7 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
4679 __skb_queue_tail(queue, skb); 4683 __skb_queue_tail(queue, skb);
4680 } while (list); 4684 } while (list);
4681 4685
4682 spin_unlock(&queue->lock); 4686 spin_unlock_bh(&queue->lock);
4683 } 4687 }
4684} 4688}
4685 4689
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 8b0a2a6de419..aa152140c3e2 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -205,6 +205,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
205 hdev->le_scan_type = LE_SCAN_PASSIVE; 205 hdev->le_scan_type = LE_SCAN_PASSIVE;
206 206
207 hdev->ssp_debug_mode = 0; 207 hdev->ssp_debug_mode = 0;
208
209 hci_bdaddr_list_clear(&hdev->le_white_list);
208} 210}
209 211
210static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) 212static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
@@ -1045,7 +1047,7 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
1045 1047
1046 hci_dev_lock(hdev); 1048 hci_dev_lock(hdev);
1047 1049
1048 /* If we're doing connection initation as peripheral. Set a 1050 /* If we're doing connection initiation as peripheral. Set a
1049 * timeout in case something goes wrong. 1051 * timeout in case something goes wrong.
1050 */ 1052 */
1051 if (*sent) { 1053 if (*sent) {
@@ -1577,8 +1579,7 @@ static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
1577 struct inquiry_entry *e; 1579 struct inquiry_entry *e;
1578 1580
1579 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 1581 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
1580 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name, 1582 mgmt_device_connected(hdev, conn, 0, name, name_len);
1581 name_len, conn->dev_class);
1582 1583
1583 if (discov->state == DISCOVERY_STOPPED) 1584 if (discov->state == DISCOVERY_STOPPED)
1584 return; 1585 return;
@@ -2536,9 +2537,7 @@ static void hci_remote_features_evt(struct hci_dev *hdev,
2536 cp.pscan_rep_mode = 0x02; 2537 cp.pscan_rep_mode = 0x02;
2537 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 2538 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
2538 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 2539 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2539 mgmt_device_connected(hdev, &conn->dst, conn->type, 2540 mgmt_device_connected(hdev, conn, 0, NULL, 0);
2540 conn->dst_type, 0, NULL, 0,
2541 conn->dev_class);
2542 2541
2543 if (!hci_outgoing_auth_needed(hdev, conn)) { 2542 if (!hci_outgoing_auth_needed(hdev, conn)) {
2544 conn->state = BT_CONNECTED; 2543 conn->state = BT_CONNECTED;
@@ -3434,9 +3433,7 @@ static void hci_remote_ext_features_evt(struct hci_dev *hdev,
3434 cp.pscan_rep_mode = 0x02; 3433 cp.pscan_rep_mode = 0x02;
3435 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 3434 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
3436 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 3435 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3437 mgmt_device_connected(hdev, &conn->dst, conn->type, 3436 mgmt_device_connected(hdev, conn, 0, NULL, 0);
3438 conn->dst_type, 0, NULL, 0,
3439 conn->dev_class);
3440 3437
3441 if (!hci_outgoing_auth_needed(hdev, conn)) { 3438 if (!hci_outgoing_auth_needed(hdev, conn)) {
3442 conn->state = BT_CONNECTED; 3439 conn->state = BT_CONNECTED;
@@ -4214,8 +4211,7 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
4214 } 4211 }
4215 4212
4216 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 4213 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
4217 mgmt_device_connected(hdev, &conn->dst, conn->type, 4214 mgmt_device_connected(hdev, conn, 0, NULL, 0);
4218 conn->dst_type, 0, NULL, 0, NULL);
4219 4215
4220 conn->sec_level = BT_SECURITY_LOW; 4216 conn->sec_level = BT_SECURITY_LOW;
4221 conn->handle = __le16_to_cpu(ev->handle); 4217 conn->handle = __le16_to_cpu(ev->handle);
@@ -4269,25 +4265,26 @@ static void hci_le_conn_update_complete_evt(struct hci_dev *hdev,
4269} 4265}
4270 4266
4271/* This function requires the caller holds hdev->lock */ 4267/* This function requires the caller holds hdev->lock */
4272static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, 4268static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
4273 u8 addr_type, u8 adv_type) 4269 bdaddr_t *addr,
4270 u8 addr_type, u8 adv_type)
4274{ 4271{
4275 struct hci_conn *conn; 4272 struct hci_conn *conn;
4276 struct hci_conn_params *params; 4273 struct hci_conn_params *params;
4277 4274
4278 /* If the event is not connectable don't proceed further */ 4275 /* If the event is not connectable don't proceed further */
4279 if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND) 4276 if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND)
4280 return; 4277 return NULL;
4281 4278
4282 /* Ignore if the device is blocked */ 4279 /* Ignore if the device is blocked */
4283 if (hci_bdaddr_list_lookup(&hdev->blacklist, addr, addr_type)) 4280 if (hci_bdaddr_list_lookup(&hdev->blacklist, addr, addr_type))
4284 return; 4281 return NULL;
4285 4282
4286 /* Most controller will fail if we try to create new connections 4283 /* Most controller will fail if we try to create new connections
4287 * while we have an existing one in slave role. 4284 * while we have an existing one in slave role.
4288 */ 4285 */
4289 if (hdev->conn_hash.le_num_slave > 0) 4286 if (hdev->conn_hash.le_num_slave > 0)
4290 return; 4287 return NULL;
4291 4288
4292 /* If we're not connectable only connect devices that we have in 4289 /* If we're not connectable only connect devices that we have in
4293 * our pend_le_conns list. 4290 * our pend_le_conns list.
@@ -4295,7 +4292,7 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
4295 params = hci_pend_le_action_lookup(&hdev->pend_le_conns, 4292 params = hci_pend_le_action_lookup(&hdev->pend_le_conns,
4296 addr, addr_type); 4293 addr, addr_type);
4297 if (!params) 4294 if (!params)
4298 return; 4295 return NULL;
4299 4296
4300 switch (params->auto_connect) { 4297 switch (params->auto_connect) {
4301 case HCI_AUTO_CONN_DIRECT: 4298 case HCI_AUTO_CONN_DIRECT:
@@ -4304,7 +4301,7 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
4304 * incoming connections from slave devices. 4301 * incoming connections from slave devices.
4305 */ 4302 */
4306 if (adv_type != LE_ADV_DIRECT_IND) 4303 if (adv_type != LE_ADV_DIRECT_IND)
4307 return; 4304 return NULL;
4308 break; 4305 break;
4309 case HCI_AUTO_CONN_ALWAYS: 4306 case HCI_AUTO_CONN_ALWAYS:
4310 /* Devices advertising with ADV_IND or ADV_DIRECT_IND 4307 /* Devices advertising with ADV_IND or ADV_DIRECT_IND
@@ -4315,7 +4312,7 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
4315 */ 4312 */
4316 break; 4313 break;
4317 default: 4314 default:
4318 return; 4315 return NULL;
4319 } 4316 }
4320 4317
4321 conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW, 4318 conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
@@ -4328,7 +4325,7 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
4328 * count consistent once the connection is established. 4325 * count consistent once the connection is established.
4329 */ 4326 */
4330 params->conn = hci_conn_get(conn); 4327 params->conn = hci_conn_get(conn);
4331 return; 4328 return conn;
4332 } 4329 }
4333 4330
4334 switch (PTR_ERR(conn)) { 4331 switch (PTR_ERR(conn)) {
@@ -4341,7 +4338,10 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
4341 break; 4338 break;
4342 default: 4339 default:
4343 BT_DBG("Failed to connect: err %ld", PTR_ERR(conn)); 4340 BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
4341 return NULL;
4344 } 4342 }
4343
4344 return NULL;
4345} 4345}
4346 4346
4347static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, 4347static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
@@ -4349,6 +4349,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
4349{ 4349{
4350 struct discovery_state *d = &hdev->discovery; 4350 struct discovery_state *d = &hdev->discovery;
4351 struct smp_irk *irk; 4351 struct smp_irk *irk;
4352 struct hci_conn *conn;
4352 bool match; 4353 bool match;
4353 u32 flags; 4354 u32 flags;
4354 4355
@@ -4360,7 +4361,14 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
4360 } 4361 }
4361 4362
4362 /* Check if we have been requested to connect to this device */ 4363 /* Check if we have been requested to connect to this device */
4363 check_pending_le_conn(hdev, bdaddr, bdaddr_type, type); 4364 conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, type);
4365 if (conn && type == LE_ADV_IND) {
4366 /* Store report for later inclusion by
4367 * mgmt_device_connected
4368 */
4369 memcpy(conn->le_adv_data, data, len);
4370 conn->le_adv_data_len = len;
4371 }
4364 4372
4365 /* Passive scanning shouldn't trigger any device found events, 4373 /* Passive scanning shouldn't trigger any device found events,
4366 * except for devices marked as CONN_REPORT for which we do send 4374 * except for devices marked as CONN_REPORT for which we do send
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 29e1ec7189bd..5e2cd2535978 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -987,7 +987,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
987 skb_queue_tail(&hdev->raw_q, skb); 987 skb_queue_tail(&hdev->raw_q, skb);
988 queue_work(hdev->workqueue, &hdev->tx_work); 988 queue_work(hdev->workqueue, &hdev->tx_work);
989 } else { 989 } else {
990 /* Stand-alone HCI commands must be flaged as 990 /* Stand-alone HCI commands must be flagged as
991 * single-command requests. 991 * single-command requests.
992 */ 992 */
993 bt_cb(skb)->req.start = true; 993 bt_cb(skb)->req.start = true;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index b6f9777e057d..fc15174c612c 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3873,9 +3873,7 @@ static int l2cap_connect_req(struct l2cap_conn *conn,
3873 hci_dev_lock(hdev); 3873 hci_dev_lock(hdev);
3874 if (test_bit(HCI_MGMT, &hdev->dev_flags) && 3874 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3875 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags)) 3875 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3876 mgmt_device_connected(hdev, &hcon->dst, hcon->type, 3876 mgmt_device_connected(hdev, hcon, 0, NULL, 0);
3877 hcon->dst_type, 0, NULL, 0,
3878 hcon->dev_class);
3879 hci_dev_unlock(hdev); 3877 hci_dev_unlock(hdev);
3880 3878
3881 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0); 3879 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
@@ -4084,7 +4082,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
4084 chan->num_conf_req++; 4082 chan->num_conf_req++;
4085 } 4083 }
4086 4084
4087 /* Got Conf Rsp PENDING from remote side and asume we sent 4085 /* Got Conf Rsp PENDING from remote side and assume we sent
4088 Conf Rsp PENDING in the code above */ 4086 Conf Rsp PENDING in the code above */
4089 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) && 4087 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
4090 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) { 4088 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
@@ -5494,6 +5492,7 @@ static inline int l2cap_le_credits(struct l2cap_conn *conn,
5494 if (credits > max_credits) { 5492 if (credits > max_credits) {
5495 BT_ERR("LE credits overflow"); 5493 BT_ERR("LE credits overflow");
5496 l2cap_send_disconn_req(chan, ECONNRESET); 5494 l2cap_send_disconn_req(chan, ECONNRESET);
5495 l2cap_chan_unlock(chan);
5497 5496
5498 /* Return 0 so that we don't trigger an unnecessary 5497 /* Return 0 so that we don't trigger an unnecessary
5499 * command reject packet. 5498 * command reject packet.
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index efb71b022ab6..9c4daf715cf8 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2725,10 +2725,40 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data,
2725 } 2725 }
2726 2726
2727 if (cp->addr.type == BDADDR_BREDR) { 2727 if (cp->addr.type == BDADDR_BREDR) {
2728 /* If disconnection is requested, then look up the
2729 * connection. If the remote device is connected, it
2730 * will be later used to terminate the link.
2731 *
2732 * Setting it to NULL explicitly will cause no
2733 * termination of the link.
2734 */
2735 if (cp->disconnect)
2736 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
2737 &cp->addr.bdaddr);
2738 else
2739 conn = NULL;
2740
2728 err = hci_remove_link_key(hdev, &cp->addr.bdaddr); 2741 err = hci_remove_link_key(hdev, &cp->addr.bdaddr);
2729 } else { 2742 } else {
2730 u8 addr_type; 2743 u8 addr_type;
2731 2744
2745 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK,
2746 &cp->addr.bdaddr);
2747 if (conn) {
2748 /* Defer clearing up the connection parameters
2749 * until closing to give a chance of keeping
2750 * them if a repairing happens.
2751 */
2752 set_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags);
2753
2754 /* If disconnection is not requested, then
2755 * clear the connection variable so that the
2756 * link is not terminated.
2757 */
2758 if (!cp->disconnect)
2759 conn = NULL;
2760 }
2761
2732 if (cp->addr.type == BDADDR_LE_PUBLIC) 2762 if (cp->addr.type == BDADDR_LE_PUBLIC)
2733 addr_type = ADDR_LE_DEV_PUBLIC; 2763 addr_type = ADDR_LE_DEV_PUBLIC;
2734 else 2764 else
@@ -2736,8 +2766,6 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data,
2736 2766
2737 hci_remove_irk(hdev, &cp->addr.bdaddr, addr_type); 2767 hci_remove_irk(hdev, &cp->addr.bdaddr, addr_type);
2738 2768
2739 hci_conn_params_del(hdev, &cp->addr.bdaddr, addr_type);
2740
2741 err = hci_remove_ltk(hdev, &cp->addr.bdaddr, addr_type); 2769 err = hci_remove_ltk(hdev, &cp->addr.bdaddr, addr_type);
2742 } 2770 }
2743 2771
@@ -2747,17 +2775,9 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data,
2747 goto unlock; 2775 goto unlock;
2748 } 2776 }
2749 2777
2750 if (cp->disconnect) { 2778 /* If the connection variable is set, then termination of the
2751 if (cp->addr.type == BDADDR_BREDR) 2779 * link is requested.
2752 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, 2780 */
2753 &cp->addr.bdaddr);
2754 else
2755 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK,
2756 &cp->addr.bdaddr);
2757 } else {
2758 conn = NULL;
2759 }
2760
2761 if (!conn) { 2781 if (!conn) {
2762 err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, 0, 2782 err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, 0,
2763 &rp, sizeof(rp)); 2783 &rp, sizeof(rp));
@@ -3062,6 +3082,11 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status)
3062 hci_conn_put(conn); 3082 hci_conn_put(conn);
3063 3083
3064 mgmt_pending_remove(cmd); 3084 mgmt_pending_remove(cmd);
3085
3086 /* The device is paired so there is no need to remove
3087 * its connection parameters anymore.
3088 */
3089 clear_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags);
3065} 3090}
3066 3091
3067void mgmt_smp_complete(struct hci_conn *conn, bool complete) 3092void mgmt_smp_complete(struct hci_conn *conn, bool complete)
@@ -6171,26 +6196,36 @@ static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
6171 return eir_len; 6196 return eir_len;
6172} 6197}
6173 6198
6174void mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 6199void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn,
6175 u8 addr_type, u32 flags, u8 *name, u8 name_len, 6200 u32 flags, u8 *name, u8 name_len)
6176 u8 *dev_class)
6177{ 6201{
6178 char buf[512]; 6202 char buf[512];
6179 struct mgmt_ev_device_connected *ev = (void *) buf; 6203 struct mgmt_ev_device_connected *ev = (void *) buf;
6180 u16 eir_len = 0; 6204 u16 eir_len = 0;
6181 6205
6182 bacpy(&ev->addr.bdaddr, bdaddr); 6206 bacpy(&ev->addr.bdaddr, &conn->dst);
6183 ev->addr.type = link_to_bdaddr(link_type, addr_type); 6207 ev->addr.type = link_to_bdaddr(conn->type, conn->dst_type);
6184 6208
6185 ev->flags = __cpu_to_le32(flags); 6209 ev->flags = __cpu_to_le32(flags);
6186 6210
6187 if (name_len > 0) 6211 /* We must ensure that the EIR Data fields are ordered and
6188 eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, 6212 * unique. Keep it simple for now and avoid the problem by not
6189 name, name_len); 6213 * adding any BR/EDR data to the LE adv.
6214 */
6215 if (conn->le_adv_data_len > 0) {
6216 memcpy(&ev->eir[eir_len],
6217 conn->le_adv_data, conn->le_adv_data_len);
6218 eir_len = conn->le_adv_data_len;
6219 } else {
6220 if (name_len > 0)
6221 eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE,
6222 name, name_len);
6190 6223
6191 if (dev_class && memcmp(dev_class, "\0\0\0", 3) != 0) 6224 if (memcmp(conn->dev_class, "\0\0\0", 3) != 0)
6192 eir_len = eir_append_data(ev->eir, eir_len, 6225 eir_len = eir_append_data(ev->eir, eir_len,
6193 EIR_CLASS_OF_DEV, dev_class, 3); 6226 EIR_CLASS_OF_DEV,
6227 conn->dev_class, 3);
6228 }
6194 6229
6195 ev->eir_len = cpu_to_le16(eir_len); 6230 ev->eir_len = cpu_to_le16(eir_len);
6196 6231
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index af73bc3acb40..bce9c3d39324 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -78,8 +78,8 @@ static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s);
78#define __get_type(b) ((b & 0xef)) 78#define __get_type(b) ((b & 0xef))
79 79
80#define __test_ea(b) ((b & 0x01)) 80#define __test_ea(b) ((b & 0x01))
81#define __test_cr(b) ((b & 0x02)) 81#define __test_cr(b) (!!(b & 0x02))
82#define __test_pf(b) ((b & 0x10)) 82#define __test_pf(b) (!!(b & 0x10))
83 83
84#define __addr(cr, dlci) (((dlci & 0x3f) << 2) | (cr << 1) | 0x01) 84#define __addr(cr, dlci) (((dlci & 0x3f) << 2) | (cr << 1) | 0x01)
85#define __ctrl(type, pf) (((type & 0xef) | (pf << 4))) 85#define __ctrl(type, pf) (((type & 0xef) | (pf << 4)))
@@ -904,7 +904,7 @@ static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type)
904 hdr->len = __len8(sizeof(*mcc) + 1); 904 hdr->len = __len8(sizeof(*mcc) + 1);
905 905
906 mcc = (void *) ptr; ptr += sizeof(*mcc); 906 mcc = (void *) ptr; ptr += sizeof(*mcc);
907 mcc->type = __mcc_type(cr, RFCOMM_NSC); 907 mcc->type = __mcc_type(0, RFCOMM_NSC);
908 mcc->len = __len8(1); 908 mcc->len = __len8(1);
909 909
910 /* Type that we didn't like */ 910 /* Type that we didn't like */
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index f09b6b65cf6b..3ebf65b50881 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -191,16 +191,13 @@ int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa)
191 return 0; 191 return 0;
192} 192}
193 193
194static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7], 194static int smp_c1(struct crypto_blkcipher *tfm_aes, u8 k[16], u8 r[16],
195 u8 pres[7], u8 _iat, bdaddr_t *ia, u8 _rat, bdaddr_t *ra, 195 u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia, u8 _rat,
196 u8 res[16]) 196 bdaddr_t *ra, u8 res[16])
197{ 197{
198 struct hci_dev *hdev = smp->conn->hcon->hdev;
199 u8 p1[16], p2[16]; 198 u8 p1[16], p2[16];
200 int err; 199 int err;
201 200
202 BT_DBG("%s", hdev->name);
203
204 memset(p1, 0, 16); 201 memset(p1, 0, 16);
205 202
206 /* p1 = pres || preq || _rat || _iat */ 203 /* p1 = pres || preq || _rat || _iat */
@@ -218,7 +215,7 @@ static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7],
218 u128_xor((u128 *) res, (u128 *) r, (u128 *) p1); 215 u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
219 216
220 /* res = e(k, res) */ 217 /* res = e(k, res) */
221 err = smp_e(smp->tfm_aes, k, res); 218 err = smp_e(tfm_aes, k, res);
222 if (err) { 219 if (err) {
223 BT_ERR("Encrypt data error"); 220 BT_ERR("Encrypt data error");
224 return err; 221 return err;
@@ -228,26 +225,23 @@ static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7],
228 u128_xor((u128 *) res, (u128 *) res, (u128 *) p2); 225 u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
229 226
230 /* res = e(k, res) */ 227 /* res = e(k, res) */
231 err = smp_e(smp->tfm_aes, k, res); 228 err = smp_e(tfm_aes, k, res);
232 if (err) 229 if (err)
233 BT_ERR("Encrypt data error"); 230 BT_ERR("Encrypt data error");
234 231
235 return err; 232 return err;
236} 233}
237 234
238static int smp_s1(struct smp_chan *smp, u8 k[16], u8 r1[16], u8 r2[16], 235static int smp_s1(struct crypto_blkcipher *tfm_aes, u8 k[16], u8 r1[16],
239 u8 _r[16]) 236 u8 r2[16], u8 _r[16])
240{ 237{
241 struct hci_dev *hdev = smp->conn->hcon->hdev;
242 int err; 238 int err;
243 239
244 BT_DBG("%s", hdev->name);
245
246 /* Just least significant octets from r1 and r2 are considered */ 240 /* Just least significant octets from r1 and r2 are considered */
247 memcpy(_r, r2, 8); 241 memcpy(_r, r2, 8);
248 memcpy(_r + 8, r1, 8); 242 memcpy(_r + 8, r1, 8);
249 243
250 err = smp_e(smp->tfm_aes, k, _r); 244 err = smp_e(tfm_aes, k, _r);
251 if (err) 245 if (err)
252 BT_ERR("Encrypt data error"); 246 BT_ERR("Encrypt data error");
253 247
@@ -547,7 +541,7 @@ static u8 smp_confirm(struct smp_chan *smp)
547 541
548 BT_DBG("conn %p", conn); 542 BT_DBG("conn %p", conn);
549 543
550 ret = smp_c1(smp, smp->tk, smp->prnd, smp->preq, smp->prsp, 544 ret = smp_c1(smp->tfm_aes, smp->tk, smp->prnd, smp->preq, smp->prsp,
551 conn->hcon->init_addr_type, &conn->hcon->init_addr, 545 conn->hcon->init_addr_type, &conn->hcon->init_addr,
552 conn->hcon->resp_addr_type, &conn->hcon->resp_addr, 546 conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
553 cp.confirm_val); 547 cp.confirm_val);
@@ -578,7 +572,7 @@ static u8 smp_random(struct smp_chan *smp)
578 572
579 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); 573 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
580 574
581 ret = smp_c1(smp, smp->tk, smp->rrnd, smp->preq, smp->prsp, 575 ret = smp_c1(smp->tfm_aes, smp->tk, smp->rrnd, smp->preq, smp->prsp,
582 hcon->init_addr_type, &hcon->init_addr, 576 hcon->init_addr_type, &hcon->init_addr,
583 hcon->resp_addr_type, &hcon->resp_addr, confirm); 577 hcon->resp_addr_type, &hcon->resp_addr, confirm);
584 if (ret) 578 if (ret)
@@ -594,7 +588,7 @@ static u8 smp_random(struct smp_chan *smp)
594 __le64 rand = 0; 588 __le64 rand = 0;
595 __le16 ediv = 0; 589 __le16 ediv = 0;
596 590
597 smp_s1(smp, smp->tk, smp->rrnd, smp->prnd, stk); 591 smp_s1(smp->tfm_aes, smp->tk, smp->rrnd, smp->prnd, stk);
598 592
599 memset(stk + smp->enc_key_size, 0, 593 memset(stk + smp->enc_key_size, 0,
600 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); 594 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
@@ -613,7 +607,7 @@ static u8 smp_random(struct smp_chan *smp)
613 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), 607 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
614 smp->prnd); 608 smp->prnd);
615 609
616 smp_s1(smp, smp->tk, smp->prnd, smp->rrnd, stk); 610 smp_s1(smp->tfm_aes, smp->tk, smp->prnd, smp->rrnd, stk);
617 611
618 memset(stk + smp->enc_key_size, 0, 612 memset(stk + smp->enc_key_size, 0,
619 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); 613 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
@@ -970,7 +964,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
970 if (sec_level > conn->hcon->pending_sec_level) 964 if (sec_level > conn->hcon->pending_sec_level)
971 conn->hcon->pending_sec_level = sec_level; 965 conn->hcon->pending_sec_level = sec_level;
972 966
973 /* If we need MITM check that it can be acheived */ 967 /* If we need MITM check that it can be achieved */
974 if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { 968 if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
975 u8 method; 969 u8 method;
976 970
@@ -1028,7 +1022,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
1028 1022
1029 auth = rsp->auth_req & AUTH_REQ_MASK; 1023 auth = rsp->auth_req & AUTH_REQ_MASK;
1030 1024
1031 /* If we need MITM check that it can be acheived */ 1025 /* If we need MITM check that it can be achieved */
1032 if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { 1026 if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
1033 u8 method; 1027 u8 method;
1034 1028
diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c
index 44136297b673..519a65452d90 100644
--- a/net/ieee802154/6lowpan_rtnl.c
+++ b/net/ieee802154/6lowpan_rtnl.c
@@ -49,8 +49,8 @@
49#include <linux/module.h> 49#include <linux/module.h>
50#include <linux/moduleparam.h> 50#include <linux/moduleparam.h>
51#include <linux/netdevice.h> 51#include <linux/netdevice.h>
52#include <linux/ieee802154.h>
52#include <net/af_ieee802154.h> 53#include <net/af_ieee802154.h>
53#include <net/ieee802154.h>
54#include <net/ieee802154_netdev.h> 54#include <net/ieee802154_netdev.h>
55#include <net/6lowpan.h> 55#include <net/6lowpan.h>
56#include <net/ipv6.h> 56#include <net/ipv6.h>
@@ -58,12 +58,13 @@
58#include "reassembly.h" 58#include "reassembly.h"
59 59
60static LIST_HEAD(lowpan_devices); 60static LIST_HEAD(lowpan_devices);
61static int lowpan_open_count;
61 62
62/* private device info */ 63/* private device info */
63struct lowpan_dev_info { 64struct lowpan_dev_info {
64 struct net_device *real_dev; /* real WPAN device ptr */ 65 struct net_device *real_dev; /* real WPAN device ptr */
65 struct mutex dev_list_mtx; /* mutex for list ops */ 66 struct mutex dev_list_mtx; /* mutex for list ops */
66 __be16 fragment_tag; 67 u16 fragment_tag;
67}; 68};
68 69
69struct lowpan_dev_record { 70struct lowpan_dev_record {
@@ -140,24 +141,33 @@ static int lowpan_give_skb_to_devices(struct sk_buff *skb,
140 struct sk_buff *skb_cp; 141 struct sk_buff *skb_cp;
141 int stat = NET_RX_SUCCESS; 142 int stat = NET_RX_SUCCESS;
142 143
144 skb->protocol = htons(ETH_P_IPV6);
145 skb->pkt_type = PACKET_HOST;
146
143 rcu_read_lock(); 147 rcu_read_lock();
144 list_for_each_entry_rcu(entry, &lowpan_devices, list) 148 list_for_each_entry_rcu(entry, &lowpan_devices, list)
145 if (lowpan_dev_info(entry->ldev)->real_dev == skb->dev) { 149 if (lowpan_dev_info(entry->ldev)->real_dev == skb->dev) {
146 skb_cp = skb_copy(skb, GFP_ATOMIC); 150 skb_cp = skb_copy(skb, GFP_ATOMIC);
147 if (!skb_cp) { 151 if (!skb_cp) {
148 stat = -ENOMEM; 152 kfree_skb(skb);
149 break; 153 rcu_read_unlock();
154 return NET_RX_DROP;
150 } 155 }
151 156
152 skb_cp->dev = entry->ldev; 157 skb_cp->dev = entry->ldev;
153 stat = netif_rx(skb_cp); 158 stat = netif_rx(skb_cp);
159 if (stat == NET_RX_DROP)
160 break;
154 } 161 }
155 rcu_read_unlock(); 162 rcu_read_unlock();
156 163
164 consume_skb(skb);
165
157 return stat; 166 return stat;
158} 167}
159 168
160static int process_data(struct sk_buff *skb, const struct ieee802154_hdr *hdr) 169static int
170iphc_decompress(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
161{ 171{
162 u8 iphc0, iphc1; 172 u8 iphc0, iphc1;
163 struct ieee802154_addr_sa sa, da; 173 struct ieee802154_addr_sa sa, da;
@@ -187,10 +197,9 @@ static int process_data(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
187 else 197 else
188 dap = &da.hwaddr; 198 dap = &da.hwaddr;
189 199
190 return lowpan_process_data(skb, skb->dev, sap, sa.addr_type, 200 return lowpan_header_decompress(skb, skb->dev, sap, sa.addr_type,
191 IEEE802154_ADDR_LEN, dap, da.addr_type, 201 IEEE802154_ADDR_LEN, dap, da.addr_type,
192 IEEE802154_ADDR_LEN, iphc0, iphc1, 202 IEEE802154_ADDR_LEN, iphc0, iphc1);
193 lowpan_give_skb_to_devices);
194 203
195drop: 204drop:
196 kfree_skb(skb); 205 kfree_skb(skb);
@@ -233,7 +242,7 @@ lowpan_alloc_frag(struct sk_buff *skb, int size,
233 &master_hdr->source, size); 242 &master_hdr->source, size);
234 if (rc < 0) { 243 if (rc < 0) {
235 kfree_skb(frag); 244 kfree_skb(frag);
236 return ERR_PTR(-rc); 245 return ERR_PTR(rc);
237 } 246 }
238 } else { 247 } else {
239 frag = ERR_PTR(-ENOMEM); 248 frag = ERR_PTR(-ENOMEM);
@@ -275,7 +284,8 @@ lowpan_xmit_fragmented(struct sk_buff *skb, struct net_device *dev,
275 284
276 dgram_size = lowpan_uncompress_size(skb, &dgram_offset) - 285 dgram_size = lowpan_uncompress_size(skb, &dgram_offset) -
277 skb->mac_len; 286 skb->mac_len;
278 frag_tag = lowpan_dev_info(dev)->fragment_tag++; 287 frag_tag = htons(lowpan_dev_info(dev)->fragment_tag);
288 lowpan_dev_info(dev)->fragment_tag++;
279 289
280 frag_hdr[0] = LOWPAN_DISPATCH_FRAG1 | ((dgram_size >> 8) & 0x07); 290 frag_hdr[0] = LOWPAN_DISPATCH_FRAG1 | ((dgram_size >> 8) & 0x07);
281 frag_hdr[1] = dgram_size & 0xff; 291 frag_hdr[1] = dgram_size & 0xff;
@@ -294,7 +304,7 @@ lowpan_xmit_fragmented(struct sk_buff *skb, struct net_device *dev,
294 frag_len + skb_network_header_len(skb)); 304 frag_len + skb_network_header_len(skb));
295 if (rc) { 305 if (rc) {
296 pr_debug("%s unable to send FRAG1 packet (tag: %d)", 306 pr_debug("%s unable to send FRAG1 packet (tag: %d)",
297 __func__, frag_tag); 307 __func__, ntohs(frag_tag));
298 goto err; 308 goto err;
299 } 309 }
300 310
@@ -315,7 +325,7 @@ lowpan_xmit_fragmented(struct sk_buff *skb, struct net_device *dev,
315 frag_len); 325 frag_len);
316 if (rc) { 326 if (rc) {
317 pr_debug("%s unable to send a FRAGN packet. (tag: %d, offset: %d)\n", 327 pr_debug("%s unable to send a FRAGN packet. (tag: %d, offset: %d)\n",
318 __func__, frag_tag, skb_offset); 328 __func__, ntohs(frag_tag), skb_offset);
319 goto err; 329 goto err;
320 } 330 }
321 } while (skb_unprocessed > frag_cap); 331 } while (skb_unprocessed > frag_cap);
@@ -515,6 +525,9 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
515 if (!netif_running(dev)) 525 if (!netif_running(dev))
516 goto drop_skb; 526 goto drop_skb;
517 527
528 if (skb->pkt_type == PACKET_OTHERHOST)
529 goto drop_skb;
530
518 if (dev->type != ARPHRD_IEEE802154) 531 if (dev->type != ARPHRD_IEEE802154)
519 goto drop_skb; 532 goto drop_skb;
520 533
@@ -523,55 +536,67 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
523 536
524 /* check that it's our buffer */ 537 /* check that it's our buffer */
525 if (skb->data[0] == LOWPAN_DISPATCH_IPV6) { 538 if (skb->data[0] == LOWPAN_DISPATCH_IPV6) {
526 skb->protocol = htons(ETH_P_IPV6);
527 skb->pkt_type = PACKET_HOST;
528
529 /* Pull off the 1-byte of 6lowpan header. */ 539 /* Pull off the 1-byte of 6lowpan header. */
530 skb_pull(skb, 1); 540 skb_pull(skb, 1);
531 541 return lowpan_give_skb_to_devices(skb, NULL);
532 ret = lowpan_give_skb_to_devices(skb, NULL);
533 if (ret == NET_RX_DROP)
534 goto drop;
535 } else { 542 } else {
536 switch (skb->data[0] & 0xe0) { 543 switch (skb->data[0] & 0xe0) {
537 case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ 544 case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */
538 ret = process_data(skb, &hdr); 545 ret = iphc_decompress(skb, &hdr);
539 if (ret == NET_RX_DROP) 546 if (ret < 0)
540 goto drop; 547 goto drop;
541 break; 548
549 return lowpan_give_skb_to_devices(skb, NULL);
542 case LOWPAN_DISPATCH_FRAG1: /* first fragment header */ 550 case LOWPAN_DISPATCH_FRAG1: /* first fragment header */
543 ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1); 551 ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1);
544 if (ret == 1) { 552 if (ret == 1) {
545 ret = process_data(skb, &hdr); 553 ret = iphc_decompress(skb, &hdr);
546 if (ret == NET_RX_DROP) 554 if (ret < 0)
547 goto drop; 555 goto drop;
556
557 return lowpan_give_skb_to_devices(skb, NULL);
558 } else if (ret == -1) {
559 return NET_RX_DROP;
560 } else {
561 return NET_RX_SUCCESS;
548 } 562 }
549 break;
550 case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */ 563 case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */
551 ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN); 564 ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN);
552 if (ret == 1) { 565 if (ret == 1) {
553 ret = process_data(skb, &hdr); 566 ret = iphc_decompress(skb, &hdr);
554 if (ret == NET_RX_DROP) 567 if (ret < 0)
555 goto drop; 568 goto drop;
569
570 return lowpan_give_skb_to_devices(skb, NULL);
571 } else if (ret == -1) {
572 return NET_RX_DROP;
573 } else {
574 return NET_RX_SUCCESS;
556 } 575 }
557 break;
558 default: 576 default:
559 break; 577 break;
560 } 578 }
561 } 579 }
562 580
563 return NET_RX_SUCCESS;
564drop_skb: 581drop_skb:
565 kfree_skb(skb); 582 kfree_skb(skb);
566drop: 583drop:
567 return NET_RX_DROP; 584 return NET_RX_DROP;
568} 585}
569 586
587static struct packet_type lowpan_packet_type = {
588 .type = htons(ETH_P_IEEE802154),
589 .func = lowpan_rcv,
590};
591
570static int lowpan_newlink(struct net *src_net, struct net_device *dev, 592static int lowpan_newlink(struct net *src_net, struct net_device *dev,
571 struct nlattr *tb[], struct nlattr *data[]) 593 struct nlattr *tb[], struct nlattr *data[])
572{ 594{
573 struct net_device *real_dev; 595 struct net_device *real_dev;
574 struct lowpan_dev_record *entry; 596 struct lowpan_dev_record *entry;
597 int ret;
598
599 ASSERT_RTNL();
575 600
576 pr_debug("adding new link\n"); 601 pr_debug("adding new link\n");
577 602
@@ -606,9 +631,14 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev,
606 list_add_tail(&entry->list, &lowpan_devices); 631 list_add_tail(&entry->list, &lowpan_devices);
607 mutex_unlock(&lowpan_dev_info(dev)->dev_list_mtx); 632 mutex_unlock(&lowpan_dev_info(dev)->dev_list_mtx);
608 633
609 register_netdevice(dev); 634 ret = register_netdevice(dev);
635 if (ret >= 0) {
636 if (!lowpan_open_count)
637 dev_add_pack(&lowpan_packet_type);
638 lowpan_open_count++;
639 }
610 640
611 return 0; 641 return ret;
612} 642}
613 643
614static void lowpan_dellink(struct net_device *dev, struct list_head *head) 644static void lowpan_dellink(struct net_device *dev, struct list_head *head)
@@ -619,6 +649,10 @@ static void lowpan_dellink(struct net_device *dev, struct list_head *head)
619 649
620 ASSERT_RTNL(); 650 ASSERT_RTNL();
621 651
652 lowpan_open_count--;
653 if (!lowpan_open_count)
654 dev_remove_pack(&lowpan_packet_type);
655
622 mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx); 656 mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx);
623 list_for_each_entry_safe(entry, tmp, &lowpan_devices, list) { 657 list_for_each_entry_safe(entry, tmp, &lowpan_devices, list) {
624 if (entry->ldev == dev) { 658 if (entry->ldev == dev) {
@@ -681,11 +715,6 @@ static struct notifier_block lowpan_dev_notifier = {
681 .notifier_call = lowpan_device_event, 715 .notifier_call = lowpan_device_event,
682}; 716};
683 717
684static struct packet_type lowpan_packet_type = {
685 .type = htons(ETH_P_IEEE802154),
686 .func = lowpan_rcv,
687};
688
689static int __init lowpan_init_module(void) 718static int __init lowpan_init_module(void)
690{ 719{
691 int err = 0; 720 int err = 0;
@@ -698,8 +727,6 @@ static int __init lowpan_init_module(void)
698 if (err < 0) 727 if (err < 0)
699 goto out_frag; 728 goto out_frag;
700 729
701 dev_add_pack(&lowpan_packet_type);
702
703 err = register_netdevice_notifier(&lowpan_dev_notifier); 730 err = register_netdevice_notifier(&lowpan_dev_notifier);
704 if (err < 0) 731 if (err < 0)
705 goto out_pack; 732 goto out_pack;
@@ -707,7 +734,6 @@ static int __init lowpan_init_module(void)
707 return 0; 734 return 0;
708 735
709out_pack: 736out_pack:
710 dev_remove_pack(&lowpan_packet_type);
711 lowpan_netlink_fini(); 737 lowpan_netlink_fini();
712out_frag: 738out_frag:
713 lowpan_net_frag_exit(); 739 lowpan_net_frag_exit();
@@ -719,8 +745,6 @@ static void __exit lowpan_cleanup_module(void)
719{ 745{
720 lowpan_netlink_fini(); 746 lowpan_netlink_fini();
721 747
722 dev_remove_pack(&lowpan_packet_type);
723
724 lowpan_net_frag_exit(); 748 lowpan_net_frag_exit();
725 749
726 unregister_netdevice_notifier(&lowpan_dev_notifier); 750 unregister_netdevice_notifier(&lowpan_dev_notifier);
diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile
index 3914b1ed4274..38354d4a70cb 100644
--- a/net/ieee802154/Makefile
+++ b/net/ieee802154/Makefile
@@ -2,8 +2,8 @@ obj-$(CONFIG_IEEE802154) += ieee802154.o af_802154.o
2obj-$(CONFIG_IEEE802154_6LOWPAN) += ieee802154_6lowpan.o 2obj-$(CONFIG_IEEE802154_6LOWPAN) += ieee802154_6lowpan.o
3 3
4ieee802154_6lowpan-y := 6lowpan_rtnl.o reassembly.o 4ieee802154_6lowpan-y := 6lowpan_rtnl.o reassembly.o
5ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o wpan-class.o \ 5ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o core.o \
6 header_ops.o 6 header_ops.o sysfs.o
7af_802154-y := af_ieee802154.o raw.o dgram.o 7af_802154-y := af_ieee802154.o raw.o dgram.o
8 8
9ccflags-y += -D__CHECK_ENDIAN__ 9ccflags-y += -D__CHECK_ENDIAN__
diff --git a/net/ieee802154/af802154.h b/net/ieee802154/af802154.h
index 8330a09bfc95..343b63e6f953 100644
--- a/net/ieee802154/af802154.h
+++ b/net/ieee802154/af802154.h
@@ -12,10 +12,6 @@
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Written by: 15 * Written by:
20 * Sergey Lapin <slapin@ossfans.org> 16 * Sergey Lapin <slapin@ossfans.org>
21 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> 17 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c
index 29e0de63001b..26da1e179737 100644
--- a/net/ieee802154/af_ieee802154.c
+++ b/net/ieee802154/af_ieee802154.c
@@ -12,10 +12,6 @@
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Written by: 15 * Written by:
20 * Sergey Lapin <slapin@ossfans.org> 16 * Sergey Lapin <slapin@ossfans.org>
21 * Maxim Gorbachyov <maxim.gorbachev@siemens.com> 17 * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/core.c
index 4955e0fe5883..620abc2ba5fc 100644
--- a/net/ieee802154/wpan-class.c
+++ b/net/ieee802154/core.c
@@ -10,10 +10,6 @@
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details. 11 * GNU General Public License for more details.
12 * 12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 */ 13 */
18 14
19#include <linux/slab.h> 15#include <linux/slab.h>
@@ -21,75 +17,10 @@
21#include <linux/module.h> 17#include <linux/module.h>
22#include <linux/device.h> 18#include <linux/device.h>
23 19
24#include <net/wpan-phy.h> 20#include <net/cfg802154.h>
25 21
26#include "ieee802154.h" 22#include "ieee802154.h"
27 23#include "sysfs.h"
28#define MASTER_SHOW_COMPLEX(name, format_string, args...) \
29static ssize_t name ## _show(struct device *dev, \
30 struct device_attribute *attr, char *buf) \
31{ \
32 struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); \
33 int ret; \
34 \
35 mutex_lock(&phy->pib_lock); \
36 ret = snprintf(buf, PAGE_SIZE, format_string "\n", args); \
37 mutex_unlock(&phy->pib_lock); \
38 return ret; \
39} \
40static DEVICE_ATTR_RO(name);
41
42#define MASTER_SHOW(field, format_string) \
43 MASTER_SHOW_COMPLEX(field, format_string, phy->field)
44
45MASTER_SHOW(current_channel, "%d");
46MASTER_SHOW(current_page, "%d");
47MASTER_SHOW(transmit_power, "%d +- 1 dB");
48MASTER_SHOW(cca_mode, "%d");
49
50static ssize_t channels_supported_show(struct device *dev,
51 struct device_attribute *attr,
52 char *buf)
53{
54 struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev);
55 int ret;
56 int i, len = 0;
57
58 mutex_lock(&phy->pib_lock);
59 for (i = 0; i < 32; i++) {
60 ret = snprintf(buf + len, PAGE_SIZE - len,
61 "%#09x\n", phy->channels_supported[i]);
62 if (ret < 0)
63 break;
64 len += ret;
65 }
66 mutex_unlock(&phy->pib_lock);
67 return len;
68}
69static DEVICE_ATTR_RO(channels_supported);
70
71static struct attribute *pmib_attrs[] = {
72 &dev_attr_current_channel.attr,
73 &dev_attr_current_page.attr,
74 &dev_attr_channels_supported.attr,
75 &dev_attr_transmit_power.attr,
76 &dev_attr_cca_mode.attr,
77 NULL,
78};
79ATTRIBUTE_GROUPS(pmib);
80
81static void wpan_phy_release(struct device *d)
82{
83 struct wpan_phy *phy = container_of(d, struct wpan_phy, dev);
84
85 kfree(phy);
86}
87
88static struct class wpan_phy_class = {
89 .name = "ieee802154",
90 .dev_release = wpan_phy_release,
91 .dev_groups = pmib_groups,
92};
93 24
94static DEFINE_MUTEX(wpan_phy_mutex); 25static DEFINE_MUTEX(wpan_phy_mutex);
95static int wpan_phy_idx; 26static int wpan_phy_idx;
@@ -201,7 +132,7 @@ static int __init wpan_phy_class_init(void)
201{ 132{
202 int rc; 133 int rc;
203 134
204 rc = class_register(&wpan_phy_class); 135 rc = wpan_phy_sysfs_init();
205 if (rc) 136 if (rc)
206 goto err; 137 goto err;
207 138
@@ -211,7 +142,7 @@ static int __init wpan_phy_class_init(void)
211 142
212 return 0; 143 return 0;
213err_nl: 144err_nl:
214 class_unregister(&wpan_phy_class); 145 wpan_phy_sysfs_exit();
215err: 146err:
216 return rc; 147 return rc;
217} 148}
@@ -220,7 +151,7 @@ subsys_initcall(wpan_phy_class_init);
220static void __exit wpan_phy_class_exit(void) 151static void __exit wpan_phy_class_exit(void)
221{ 152{
222 ieee802154_nl_exit(); 153 ieee802154_nl_exit();
223 class_unregister(&wpan_phy_class); 154 wpan_phy_sysfs_exit();
224} 155}
225module_exit(wpan_phy_class_exit); 156module_exit(wpan_phy_class_exit);
226 157
diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c
index fc9193eabd41..b8555ec71387 100644
--- a/net/ieee802154/dgram.c
+++ b/net/ieee802154/dgram.c
@@ -12,10 +12,6 @@
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Written by: 15 * Written by:
20 * Sergey Lapin <slapin@ossfans.org> 16 * Sergey Lapin <slapin@ossfans.org>
21 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> 17 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
@@ -27,9 +23,9 @@
27#include <linux/if_arp.h> 23#include <linux/if_arp.h>
28#include <linux/list.h> 24#include <linux/list.h>
29#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/ieee802154.h>
30#include <net/sock.h> 27#include <net/sock.h>
31#include <net/af_ieee802154.h> 28#include <net/af_ieee802154.h>
32#include <net/ieee802154.h>
33#include <net/ieee802154_netdev.h> 29#include <net/ieee802154_netdev.h>
34 30
35#include <asm/ioctls.h> 31#include <asm/ioctls.h>
diff --git a/net/ieee802154/header_ops.c b/net/ieee802154/header_ops.c
index c09294e39ca6..a051b6993177 100644
--- a/net/ieee802154/header_ops.c
+++ b/net/ieee802154/header_ops.c
@@ -14,8 +14,9 @@
14 * Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de> 14 * Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de>
15 */ 15 */
16 16
17#include <linux/ieee802154.h>
18
17#include <net/mac802154.h> 19#include <net/mac802154.h>
18#include <net/ieee802154.h>
19#include <net/ieee802154_netdev.h> 20#include <net/ieee802154_netdev.h>
20 21
21static int 22static int
diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h
index 5d352f86979e..42ae63a345ab 100644
--- a/net/ieee802154/ieee802154.h
+++ b/net/ieee802154/ieee802154.h
@@ -10,10 +10,6 @@
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details. 11 * GNU General Public License for more details.
12 * 12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 */ 13 */
18#ifndef IEEE_802154_LOCAL_H 14#ifndef IEEE_802154_LOCAL_H
19#define IEEE_802154_LOCAL_H 15#define IEEE_802154_LOCAL_H
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 9222966f5e6d..6c3c2595a201 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -12,10 +12,6 @@
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Written by: 15 * Written by:
20 * Sergey Lapin <slapin@ossfans.org> 16 * Sergey Lapin <slapin@ossfans.org>
21 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> 17 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index c6bfe22bfa5e..abd0f31bdc66 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -12,10 +12,6 @@
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Written by: 15 * Written by:
20 * Sergey Lapin <slapin@ossfans.org> 16 * Sergey Lapin <slapin@ossfans.org>
21 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> 17 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
@@ -26,6 +22,7 @@
26#include <linux/kernel.h> 22#include <linux/kernel.h>
27#include <linux/if_arp.h> 23#include <linux/if_arp.h>
28#include <linux/netdevice.h> 24#include <linux/netdevice.h>
25#include <linux/ieee802154.h>
29#include <net/netlink.h> 26#include <net/netlink.h>
30#include <net/genetlink.h> 27#include <net/genetlink.h>
31#include <net/sock.h> 28#include <net/sock.h>
@@ -33,9 +30,8 @@
33#include <linux/export.h> 30#include <linux/export.h>
34#include <net/af_ieee802154.h> 31#include <net/af_ieee802154.h>
35#include <net/nl802154.h> 32#include <net/nl802154.h>
36#include <net/ieee802154.h>
37#include <net/ieee802154_netdev.h> 33#include <net/ieee802154_netdev.h>
38#include <net/wpan-phy.h> 34#include <net/cfg802154.h>
39 35
40#include "ieee802154.h" 36#include "ieee802154.h"
41 37
@@ -668,20 +664,6 @@ int ieee802154_set_macparams(struct sk_buff *skb, struct genl_info *info)
668 664
669 phy = ops->get_phy(dev); 665 phy = ops->get_phy(dev);
670 666
671 if ((!phy->set_lbt && info->attrs[IEEE802154_ATTR_LBT_ENABLED]) ||
672 (!phy->set_cca_mode && info->attrs[IEEE802154_ATTR_CCA_MODE]) ||
673 (!phy->set_cca_ed_level &&
674 info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL]) ||
675 (!phy->set_csma_params &&
676 (info->attrs[IEEE802154_ATTR_CSMA_RETRIES] ||
677 info->attrs[IEEE802154_ATTR_CSMA_MIN_BE] ||
678 info->attrs[IEEE802154_ATTR_CSMA_MAX_BE])) ||
679 (!phy->set_frame_retries &&
680 info->attrs[IEEE802154_ATTR_FRAME_RETRIES])) {
681 rc = -EOPNOTSUPP;
682 goto out_phy;
683 }
684
685 ops->get_mac_params(dev, &params); 667 ops->get_mac_params(dev, &params);
686 668
687 if (info->attrs[IEEE802154_ATTR_TXPOWER]) 669 if (info->attrs[IEEE802154_ATTR_TXPOWER])
@@ -712,10 +694,9 @@ int ieee802154_set_macparams(struct sk_buff *skb, struct genl_info *info)
712 694
713 wpan_phy_put(phy); 695 wpan_phy_put(phy);
714 dev_put(dev); 696 dev_put(dev);
715 return rc;
716 697
717out_phy: 698 return 0;
718 wpan_phy_put(phy); 699
719out: 700out:
720 dev_put(dev); 701 dev_put(dev);
721 return rc; 702 return rc;
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
index 972baf83411a..0afe760ff512 100644
--- a/net/ieee802154/nl-phy.c
+++ b/net/ieee802154/nl-phy.c
@@ -12,10 +12,6 @@
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Written by: 15 * Written by:
20 * Sergey Lapin <slapin@ossfans.org> 16 * Sergey Lapin <slapin@ossfans.org>
21 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> 17 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
@@ -27,7 +23,7 @@
27#include <linux/if_arp.h> 23#include <linux/if_arp.h>
28#include <net/netlink.h> 24#include <net/netlink.h>
29#include <net/genetlink.h> 25#include <net/genetlink.h>
30#include <net/wpan-phy.h> 26#include <net/cfg802154.h>
31#include <net/af_ieee802154.h> 27#include <net/af_ieee802154.h>
32#include <net/ieee802154_netdev.h> 28#include <net/ieee802154_netdev.h>
33#include <net/rtnetlink.h> /* for rtnl_{un,}lock */ 29#include <net/rtnetlink.h> /* for rtnl_{un,}lock */
diff --git a/net/ieee802154/nl_policy.c b/net/ieee802154/nl_policy.c
index 3a703ab88348..35c432668454 100644
--- a/net/ieee802154/nl_policy.c
+++ b/net/ieee802154/nl_policy.c
@@ -12,10 +12,6 @@
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 */ 15 */
20 16
21#include <linux/kernel.h> 17#include <linux/kernel.h>
diff --git a/net/ieee802154/raw.c b/net/ieee802154/raw.c
index 73a4d53463de..21c38945ab8b 100644
--- a/net/ieee802154/raw.c
+++ b/net/ieee802154/raw.c
@@ -12,10 +12,6 @@
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Written by: 15 * Written by:
20 * Sergey Lapin <slapin@ossfans.org> 16 * Sergey Lapin <slapin@ossfans.org>
21 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> 17 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
diff --git a/net/ieee802154/reassembly.c b/net/ieee802154/reassembly.c
index 7cfcd6885225..9d980ed3ffe2 100644
--- a/net/ieee802154/reassembly.c
+++ b/net/ieee802154/reassembly.c
@@ -33,7 +33,7 @@
33static const char lowpan_frags_cache_name[] = "lowpan-frags"; 33static const char lowpan_frags_cache_name[] = "lowpan-frags";
34 34
35struct lowpan_frag_info { 35struct lowpan_frag_info {
36 __be16 d_tag; 36 u16 d_tag;
37 u16 d_size; 37 u16 d_size;
38 u8 d_offset; 38 u8 d_offset;
39}; 39};
@@ -48,7 +48,7 @@ static struct inet_frags lowpan_frags;
48static int lowpan_frag_reasm(struct lowpan_frag_queue *fq, 48static int lowpan_frag_reasm(struct lowpan_frag_queue *fq,
49 struct sk_buff *prev, struct net_device *dev); 49 struct sk_buff *prev, struct net_device *dev);
50 50
51static unsigned int lowpan_hash_frag(__be16 tag, u16 d_size, 51static unsigned int lowpan_hash_frag(u16 tag, u16 d_size,
52 const struct ieee802154_addr *saddr, 52 const struct ieee802154_addr *saddr,
53 const struct ieee802154_addr *daddr) 53 const struct ieee802154_addr *daddr)
54{ 54{
@@ -330,11 +330,13 @@ static int lowpan_get_frag_info(struct sk_buff *skb, const u8 frag_type,
330{ 330{
331 bool fail; 331 bool fail;
332 u8 pattern = 0, low = 0; 332 u8 pattern = 0, low = 0;
333 __be16 d_tag = 0;
333 334
334 fail = lowpan_fetch_skb(skb, &pattern, 1); 335 fail = lowpan_fetch_skb(skb, &pattern, 1);
335 fail |= lowpan_fetch_skb(skb, &low, 1); 336 fail |= lowpan_fetch_skb(skb, &low, 1);
336 frag_info->d_size = (pattern & 7) << 8 | low; 337 frag_info->d_size = (pattern & 7) << 8 | low;
337 fail |= lowpan_fetch_skb(skb, &frag_info->d_tag, 2); 338 fail |= lowpan_fetch_skb(skb, &d_tag, 2);
339 frag_info->d_tag = ntohs(d_tag);
338 340
339 if (frag_type == LOWPAN_DISPATCH_FRAGN) { 341 if (frag_type == LOWPAN_DISPATCH_FRAGN) {
340 fail |= lowpan_fetch_skb(skb, &frag_info->d_offset, 1); 342 fail |= lowpan_fetch_skb(skb, &frag_info->d_offset, 1);
diff --git a/net/ieee802154/reassembly.h b/net/ieee802154/reassembly.h
index 74e4a7c98191..836b16fa001f 100644
--- a/net/ieee802154/reassembly.h
+++ b/net/ieee802154/reassembly.h
@@ -4,7 +4,7 @@
4#include <net/inet_frag.h> 4#include <net/inet_frag.h>
5 5
6struct lowpan_create_arg { 6struct lowpan_create_arg {
7 __be16 tag; 7 u16 tag;
8 u16 d_size; 8 u16 d_size;
9 const struct ieee802154_addr *src; 9 const struct ieee802154_addr *src;
10 const struct ieee802154_addr *dst; 10 const struct ieee802154_addr *dst;
@@ -15,7 +15,7 @@ struct lowpan_create_arg {
15struct lowpan_frag_queue { 15struct lowpan_frag_queue {
16 struct inet_frag_queue q; 16 struct inet_frag_queue q;
17 17
18 __be16 tag; 18 u16 tag;
19 u16 d_size; 19 u16 d_size;
20 struct ieee802154_addr saddr; 20 struct ieee802154_addr saddr;
21 struct ieee802154_addr daddr; 21 struct ieee802154_addr daddr;
diff --git a/net/ieee802154/sysfs.c b/net/ieee802154/sysfs.c
new file mode 100644
index 000000000000..eb9ca6f99122
--- /dev/null
+++ b/net/ieee802154/sysfs.c
@@ -0,0 +1,94 @@
1/* This program is free software; you can redistribute it and/or modify
2 * it under the terms of the GNU General Public License version 2
3 * as published by the Free Software Foundation.
4 *
5 * This program is distributed in the hope that it will be useful,
6 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8 * GNU General Public License for more details.
9 *
10 * Authors:
11 * Alexander Aring <aar@pengutronix.de>
12 *
13 * Based on: net/wireless/sysfs.c
14 */
15
16#include <linux/device.h>
17
18#include <net/cfg802154.h>
19
20#define MASTER_SHOW_COMPLEX(name, format_string, args...) \
21static ssize_t name ## _show(struct device *dev, \
22 struct device_attribute *attr, char *buf) \
23{ \
24 struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); \
25 int ret; \
26 \
27 mutex_lock(&phy->pib_lock); \
28 ret = snprintf(buf, PAGE_SIZE, format_string "\n", args); \
29 mutex_unlock(&phy->pib_lock); \
30 return ret; \
31} \
32static DEVICE_ATTR_RO(name)
33
34#define MASTER_SHOW(field, format_string) \
35 MASTER_SHOW_COMPLEX(field, format_string, phy->field)
36
37MASTER_SHOW(current_channel, "%d");
38MASTER_SHOW(current_page, "%d");
39MASTER_SHOW(transmit_power, "%d +- 1 dB");
40MASTER_SHOW(cca_mode, "%d");
41
42static ssize_t channels_supported_show(struct device *dev,
43 struct device_attribute *attr,
44 char *buf)
45{
46 struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev);
47 int ret;
48 int i, len = 0;
49
50 mutex_lock(&phy->pib_lock);
51 for (i = 0; i < 32; i++) {
52 ret = snprintf(buf + len, PAGE_SIZE - len,
53 "%#09x\n", phy->channels_supported[i]);
54 if (ret < 0)
55 break;
56 len += ret;
57 }
58 mutex_unlock(&phy->pib_lock);
59 return len;
60}
61static DEVICE_ATTR_RO(channels_supported);
62
63static void wpan_phy_release(struct device *d)
64{
65 struct wpan_phy *phy = container_of(d, struct wpan_phy, dev);
66
67 kfree(phy);
68}
69
70static struct attribute *pmib_attrs[] = {
71 &dev_attr_current_channel.attr,
72 &dev_attr_current_page.attr,
73 &dev_attr_channels_supported.attr,
74 &dev_attr_transmit_power.attr,
75 &dev_attr_cca_mode.attr,
76 NULL,
77};
78ATTRIBUTE_GROUPS(pmib);
79
80struct class wpan_phy_class = {
81 .name = "ieee802154",
82 .dev_release = wpan_phy_release,
83 .dev_groups = pmib_groups,
84};
85
86int wpan_phy_sysfs_init(void)
87{
88 return class_register(&wpan_phy_class);
89}
90
91void wpan_phy_sysfs_exit(void)
92{
93 class_unregister(&wpan_phy_class);
94}
diff --git a/net/ieee802154/sysfs.h b/net/ieee802154/sysfs.h
new file mode 100644
index 000000000000..aa42e39ecbec
--- /dev/null
+++ b/net/ieee802154/sysfs.h
@@ -0,0 +1,9 @@
1#ifndef __IEEE802154_SYSFS_H
2#define __IEEE802154_SYSFS_H
3
4int wpan_phy_sysfs_init(void);
5void wpan_phy_sysfs_exit(void);
6
7extern struct class wpan_phy_class;
8
9#endif /* __IEEE802154_SYSFS_H */
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index aeb6a483b3bc..75cc6801a431 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -33,6 +33,13 @@ config MAC80211_RC_MINSTREL_HT
33 ---help--- 33 ---help---
34 This option enables the 'minstrel_ht' TX rate control algorithm 34 This option enables the 'minstrel_ht' TX rate control algorithm
35 35
36config MAC80211_RC_MINSTREL_VHT
37 bool "Minstrel 802.11ac support" if EXPERT
38 depends on MAC80211_RC_MINSTREL_HT
39 default n
40 ---help---
41 This option enables VHT in the 'minstrel_ht' TX rate control algorithm
42
36choice 43choice
37 prompt "Default rate control algorithm" 44 prompt "Default rate control algorithm"
38 depends on MAC80211_HAS_RC 45 depends on MAC80211_HAS_RC
@@ -169,6 +176,17 @@ config MAC80211_HT_DEBUG
169 176
170 Do not select this option. 177 Do not select this option.
171 178
179config MAC80211_OCB_DEBUG
180 bool "Verbose OCB debugging"
181 depends on MAC80211_DEBUG_MENU
182 ---help---
183 Selecting this option causes mac80211 to print out
184 very verbose OCB debugging messages. It should not
185 be selected on production systems as those messages
186 are remotely triggerable.
187
188 Do not select this option.
189
172config MAC80211_IBSS_DEBUG 190config MAC80211_IBSS_DEBUG
173 bool "Verbose IBSS debugging" 191 bool "Verbose IBSS debugging"
174 depends on MAC80211_DEBUG_MENU 192 depends on MAC80211_DEBUG_MENU
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 7273d2796dd1..e53671b1105e 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -27,7 +27,8 @@ mac80211-y := \
27 event.o \ 27 event.o \
28 chan.o \ 28 chan.o \
29 trace.o mlme.o \ 29 trace.o mlme.o \
30 tdls.o 30 tdls.o \
31 ocb.o
31 32
32mac80211-$(CONFIG_MAC80211_LEDS) += led.o 33mac80211-$(CONFIG_MAC80211_LEDS) += led.o
33mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ 34mac80211-$(CONFIG_MAC80211_DEBUGFS) += \
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index d6986f3aa5c4..9242c60048cf 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -149,11 +149,6 @@ void ieee80211_assign_tid_tx(struct sta_info *sta, int tid,
149 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], tid_tx); 149 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], tid_tx);
150} 150}
151 151
152static inline int ieee80211_ac_from_tid(int tid)
153{
154 return ieee802_1d_to_ac[tid & 7];
155}
156
157/* 152/*
158 * When multiple aggregation sessions on multiple stations 153 * When multiple aggregation sessions on multiple stations
159 * are being created/destroyed simultaneously, we need to 154 * are being created/destroyed simultaneously, we need to
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 343da1e35025..06185940cbb6 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -20,6 +20,7 @@
20#include "cfg.h" 20#include "cfg.h"
21#include "rate.h" 21#include "rate.h"
22#include "mesh.h" 22#include "mesh.h"
23#include "wme.h"
23 24
24static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, 25static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy,
25 const char *name, 26 const char *name,
@@ -190,7 +191,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
190 * receive the key. When wpa_supplicant has roamed 191 * receive the key. When wpa_supplicant has roamed
191 * using FT, it attempts to set the key before 192 * using FT, it attempts to set the key before
192 * association has completed, this rejects that attempt 193 * association has completed, this rejects that attempt
193 * so it will set the key again after assocation. 194 * so it will set the key again after association.
194 * 195 *
195 * TODO: accept the key if we have a station entry and 196 * TODO: accept the key if we have a station entry and
196 * add it to the device after the station. 197 * add it to the device after the station.
@@ -229,6 +230,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
229 case NUM_NL80211_IFTYPES: 230 case NUM_NL80211_IFTYPES:
230 case NL80211_IFTYPE_P2P_CLIENT: 231 case NL80211_IFTYPE_P2P_CLIENT:
231 case NL80211_IFTYPE_P2P_GO: 232 case NL80211_IFTYPE_P2P_GO:
233 case NL80211_IFTYPE_OCB:
232 /* shouldn't happen */ 234 /* shouldn't happen */
233 WARN_ON_ONCE(1); 235 WARN_ON_ONCE(1);
234 break; 236 break;
@@ -1225,14 +1227,14 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
1225} 1227}
1226 1228
1227static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev, 1229static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
1228 const u8 *mac) 1230 struct station_del_parameters *params)
1229{ 1231{
1230 struct ieee80211_sub_if_data *sdata; 1232 struct ieee80211_sub_if_data *sdata;
1231 1233
1232 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1234 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1233 1235
1234 if (mac) 1236 if (params->mac)
1235 return sta_info_destroy_addr_bss(sdata, mac); 1237 return sta_info_destroy_addr_bss(sdata, params->mac);
1236 1238
1237 sta_info_flush(sdata); 1239 sta_info_flush(sdata);
1238 return 0; 1240 return 0;
@@ -1516,6 +1518,57 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
1516 return 0; 1518 return 0;
1517} 1519}
1518 1520
1521static void mpp_set_pinfo(struct mesh_path *mpath, u8 *mpp,
1522 struct mpath_info *pinfo)
1523{
1524 memset(pinfo, 0, sizeof(*pinfo));
1525 memcpy(mpp, mpath->mpp, ETH_ALEN);
1526
1527 pinfo->generation = mpp_paths_generation;
1528}
1529
1530static int ieee80211_get_mpp(struct wiphy *wiphy, struct net_device *dev,
1531 u8 *dst, u8 *mpp, struct mpath_info *pinfo)
1532
1533{
1534 struct ieee80211_sub_if_data *sdata;
1535 struct mesh_path *mpath;
1536
1537 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1538
1539 rcu_read_lock();
1540 mpath = mpp_path_lookup(sdata, dst);
1541 if (!mpath) {
1542 rcu_read_unlock();
1543 return -ENOENT;
1544 }
1545 memcpy(dst, mpath->dst, ETH_ALEN);
1546 mpp_set_pinfo(mpath, mpp, pinfo);
1547 rcu_read_unlock();
1548 return 0;
1549}
1550
1551static int ieee80211_dump_mpp(struct wiphy *wiphy, struct net_device *dev,
1552 int idx, u8 *dst, u8 *mpp,
1553 struct mpath_info *pinfo)
1554{
1555 struct ieee80211_sub_if_data *sdata;
1556 struct mesh_path *mpath;
1557
1558 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1559
1560 rcu_read_lock();
1561 mpath = mpp_path_lookup_by_idx(sdata, idx);
1562 if (!mpath) {
1563 rcu_read_unlock();
1564 return -ENOENT;
1565 }
1566 memcpy(dst, mpath->dst, ETH_ALEN);
1567 mpp_set_pinfo(mpath, mpp, pinfo);
1568 rcu_read_unlock();
1569 return 0;
1570}
1571
1519static int ieee80211_get_mesh_config(struct wiphy *wiphy, 1572static int ieee80211_get_mesh_config(struct wiphy *wiphy,
1520 struct net_device *dev, 1573 struct net_device *dev,
1521 struct mesh_config *conf) 1574 struct mesh_config *conf)
@@ -1966,6 +2019,17 @@ static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1966 return ieee80211_ibss_leave(IEEE80211_DEV_TO_SUB_IF(dev)); 2019 return ieee80211_ibss_leave(IEEE80211_DEV_TO_SUB_IF(dev));
1967} 2020}
1968 2021
2022static int ieee80211_join_ocb(struct wiphy *wiphy, struct net_device *dev,
2023 struct ocb_setup *setup)
2024{
2025 return ieee80211_ocb_join(IEEE80211_DEV_TO_SUB_IF(dev), setup);
2026}
2027
2028static int ieee80211_leave_ocb(struct wiphy *wiphy, struct net_device *dev)
2029{
2030 return ieee80211_ocb_leave(IEEE80211_DEV_TO_SUB_IF(dev));
2031}
2032
1969static int ieee80211_set_mcast_rate(struct wiphy *wiphy, struct net_device *dev, 2033static int ieee80211_set_mcast_rate(struct wiphy *wiphy, struct net_device *dev,
1970 int rate[IEEE80211_NUM_BANDS]) 2034 int rate[IEEE80211_NUM_BANDS])
1971{ 2035{
@@ -2081,6 +2145,9 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy,
2081 struct ieee80211_local *local = wiphy_priv(wiphy); 2145 struct ieee80211_local *local = wiphy_priv(wiphy);
2082 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 2146 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
2083 2147
2148 if (local->ops->get_txpower)
2149 return drv_get_txpower(local, sdata, dbm);
2150
2084 if (!local->use_chanctx) 2151 if (!local->use_chanctx)
2085 *dbm = local->hw.conf.power_level; 2152 *dbm = local->hw.conf.power_level;
2086 else 2153 else
@@ -2850,11 +2917,7 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
2850 if (sdata->reserved_ready) 2917 if (sdata->reserved_ready)
2851 return 0; 2918 return 0;
2852 2919
2853 err = ieee80211_vif_use_reserved_context(sdata); 2920 return ieee80211_vif_use_reserved_context(sdata);
2854 if (err)
2855 return err;
2856
2857 return 0;
2858 } 2921 }
2859 2922
2860 if (!cfg80211_chandef_identical(&sdata->vif.bss_conf.chandef, 2923 if (!cfg80211_chandef_identical(&sdata->vif.bss_conf.chandef,
@@ -2868,7 +2931,6 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
2868 return err; 2931 return err;
2869 2932
2870 ieee80211_bss_info_change_notify(sdata, changed); 2933 ieee80211_bss_info_change_notify(sdata, changed);
2871 cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef);
2872 2934
2873 if (sdata->csa_block_tx) { 2935 if (sdata->csa_block_tx) {
2874 ieee80211_wake_vif_queues(local, sdata, 2936 ieee80211_wake_vif_queues(local, sdata,
@@ -2876,6 +2938,12 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
2876 sdata->csa_block_tx = false; 2938 sdata->csa_block_tx = false;
2877 } 2939 }
2878 2940
2941 err = drv_post_channel_switch(sdata);
2942 if (err)
2943 return err;
2944
2945 cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef);
2946
2879 return 0; 2947 return 0;
2880} 2948}
2881 2949
@@ -3053,9 +3121,11 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3053{ 3121{
3054 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 3122 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3055 struct ieee80211_local *local = sdata->local; 3123 struct ieee80211_local *local = sdata->local;
3124 struct ieee80211_channel_switch ch_switch;
3056 struct ieee80211_chanctx_conf *conf; 3125 struct ieee80211_chanctx_conf *conf;
3057 struct ieee80211_chanctx *chanctx; 3126 struct ieee80211_chanctx *chanctx;
3058 int err, changed = 0; 3127 u32 changed = 0;
3128 int err;
3059 3129
3060 sdata_assert_lock(sdata); 3130 sdata_assert_lock(sdata);
3061 lockdep_assert_held(&local->mtx); 3131 lockdep_assert_held(&local->mtx);
@@ -3088,6 +3158,10 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3088 goto out; 3158 goto out;
3089 } 3159 }
3090 3160
3161 err = drv_pre_channel_switch(sdata, &ch_switch);
3162 if (err)
3163 goto out;
3164
3091 err = ieee80211_vif_reserve_chanctx(sdata, &params->chandef, 3165 err = ieee80211_vif_reserve_chanctx(sdata, &params->chandef,
3092 chanctx->mode, 3166 chanctx->mode,
3093 params->radar_required); 3167 params->radar_required);
@@ -3101,6 +3175,12 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3101 goto out; 3175 goto out;
3102 } 3176 }
3103 3177
3178 ch_switch.timestamp = 0;
3179 ch_switch.device_timestamp = 0;
3180 ch_switch.block_tx = params->block_tx;
3181 ch_switch.chandef = params->chandef;
3182 ch_switch.count = params->count;
3183
3104 err = ieee80211_set_csa_beacon(sdata, params, &changed); 3184 err = ieee80211_set_csa_beacon(sdata, params, &changed);
3105 if (err) { 3185 if (err) {
3106 ieee80211_vif_unreserve_chanctx(sdata); 3186 ieee80211_vif_unreserve_chanctx(sdata);
@@ -3521,6 +3601,76 @@ static int ieee80211_set_ap_chanwidth(struct wiphy *wiphy,
3521 return ret; 3601 return ret;
3522} 3602}
3523 3603
3604static int ieee80211_add_tx_ts(struct wiphy *wiphy, struct net_device *dev,
3605 u8 tsid, const u8 *peer, u8 up,
3606 u16 admitted_time)
3607{
3608 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3609 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3610 int ac = ieee802_1d_to_ac[up];
3611
3612 if (sdata->vif.type != NL80211_IFTYPE_STATION)
3613 return -EOPNOTSUPP;
3614
3615 if (!(sdata->wmm_acm & BIT(up)))
3616 return -EINVAL;
3617
3618 if (ifmgd->tx_tspec[ac].admitted_time)
3619 return -EBUSY;
3620
3621 if (admitted_time) {
3622 ifmgd->tx_tspec[ac].admitted_time = 32 * admitted_time;
3623 ifmgd->tx_tspec[ac].tsid = tsid;
3624 ifmgd->tx_tspec[ac].up = up;
3625 }
3626
3627 return 0;
3628}
3629
3630static int ieee80211_del_tx_ts(struct wiphy *wiphy, struct net_device *dev,
3631 u8 tsid, const u8 *peer)
3632{
3633 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3634 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3635 struct ieee80211_local *local = wiphy_priv(wiphy);
3636 int ac;
3637
3638 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
3639 struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac];
3640
3641 /* skip unused entries */
3642 if (!tx_tspec->admitted_time)
3643 continue;
3644
3645 if (tx_tspec->tsid != tsid)
3646 continue;
3647
3648 /* due to this new packets will be reassigned to non-ACM ACs */
3649 tx_tspec->up = -1;
3650
3651 /* Make sure that all packets have been sent to avoid to
3652 * restore the QoS params on packets that are still on the
3653 * queues.
3654 */
3655 synchronize_net();
3656 ieee80211_flush_queues(local, sdata);
3657
3658 /* restore the normal QoS parameters
3659 * (unconditionally to avoid races)
3660 */
3661 tx_tspec->action = TX_TSPEC_ACTION_STOP_DOWNGRADE;
3662 tx_tspec->downgraded = false;
3663 ieee80211_sta_handle_tspec_ac_params(sdata);
3664
3665 /* finally clear all the data */
3666 memset(tx_tspec, 0, sizeof(*tx_tspec));
3667
3668 return 0;
3669 }
3670
3671 return -ENOENT;
3672}
3673
3524const struct cfg80211_ops mac80211_config_ops = { 3674const struct cfg80211_ops mac80211_config_ops = {
3525 .add_virtual_intf = ieee80211_add_iface, 3675 .add_virtual_intf = ieee80211_add_iface,
3526 .del_virtual_intf = ieee80211_del_iface, 3676 .del_virtual_intf = ieee80211_del_iface,
@@ -3547,11 +3697,15 @@ const struct cfg80211_ops mac80211_config_ops = {
3547 .change_mpath = ieee80211_change_mpath, 3697 .change_mpath = ieee80211_change_mpath,
3548 .get_mpath = ieee80211_get_mpath, 3698 .get_mpath = ieee80211_get_mpath,
3549 .dump_mpath = ieee80211_dump_mpath, 3699 .dump_mpath = ieee80211_dump_mpath,
3700 .get_mpp = ieee80211_get_mpp,
3701 .dump_mpp = ieee80211_dump_mpp,
3550 .update_mesh_config = ieee80211_update_mesh_config, 3702 .update_mesh_config = ieee80211_update_mesh_config,
3551 .get_mesh_config = ieee80211_get_mesh_config, 3703 .get_mesh_config = ieee80211_get_mesh_config,
3552 .join_mesh = ieee80211_join_mesh, 3704 .join_mesh = ieee80211_join_mesh,
3553 .leave_mesh = ieee80211_leave_mesh, 3705 .leave_mesh = ieee80211_leave_mesh,
3554#endif 3706#endif
3707 .join_ocb = ieee80211_join_ocb,
3708 .leave_ocb = ieee80211_leave_ocb,
3555 .change_bss = ieee80211_change_bss, 3709 .change_bss = ieee80211_change_bss,
3556 .set_txq_params = ieee80211_set_txq_params, 3710 .set_txq_params = ieee80211_set_txq_params,
3557 .set_monitor_channel = ieee80211_set_monitor_channel, 3711 .set_monitor_channel = ieee80211_set_monitor_channel,
@@ -3597,4 +3751,6 @@ const struct cfg80211_ops mac80211_config_ops = {
3597 .channel_switch = ieee80211_channel_switch, 3751 .channel_switch = ieee80211_channel_switch,
3598 .set_qos_map = ieee80211_set_qos_map, 3752 .set_qos_map = ieee80211_set_qos_map,
3599 .set_ap_chanwidth = ieee80211_set_ap_chanwidth, 3753 .set_ap_chanwidth = ieee80211_set_ap_chanwidth,
3754 .add_tx_ts = ieee80211_add_tx_ts,
3755 .del_tx_ts = ieee80211_del_tx_ts,
3600}; 3756};
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 4c74e8da64b9..c7c514220298 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -270,6 +270,7 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
270 case NL80211_IFTYPE_ADHOC: 270 case NL80211_IFTYPE_ADHOC:
271 case NL80211_IFTYPE_WDS: 271 case NL80211_IFTYPE_WDS:
272 case NL80211_IFTYPE_MESH_POINT: 272 case NL80211_IFTYPE_MESH_POINT:
273 case NL80211_IFTYPE_OCB:
273 width = vif->bss_conf.chandef.width; 274 width = vif->bss_conf.chandef.width;
274 break; 275 break;
275 case NL80211_IFTYPE_UNSPECIFIED: 276 case NL80211_IFTYPE_UNSPECIFIED:
@@ -674,6 +675,7 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
674 case NL80211_IFTYPE_ADHOC: 675 case NL80211_IFTYPE_ADHOC:
675 case NL80211_IFTYPE_WDS: 676 case NL80211_IFTYPE_WDS:
676 case NL80211_IFTYPE_MESH_POINT: 677 case NL80211_IFTYPE_MESH_POINT:
678 case NL80211_IFTYPE_OCB:
677 break; 679 break;
678 default: 680 default:
679 WARN_ON_ONCE(1); 681 WARN_ON_ONCE(1);
@@ -909,6 +911,7 @@ ieee80211_vif_chanctx_reservation_complete(struct ieee80211_sub_if_data *sdata)
909 case NL80211_IFTYPE_ADHOC: 911 case NL80211_IFTYPE_ADHOC:
910 case NL80211_IFTYPE_AP: 912 case NL80211_IFTYPE_AP:
911 case NL80211_IFTYPE_MESH_POINT: 913 case NL80211_IFTYPE_MESH_POINT:
914 case NL80211_IFTYPE_OCB:
912 ieee80211_queue_work(&sdata->local->hw, 915 ieee80211_queue_work(&sdata->local->hw,
913 &sdata->csa_finalize_work); 916 &sdata->csa_finalize_work);
914 break; 917 break;
@@ -1634,7 +1637,7 @@ int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
1634 } 1637 }
1635 break; 1638 break;
1636 case IEEE80211_CHANCTX_WILL_BE_REPLACED: 1639 case IEEE80211_CHANCTX_WILL_BE_REPLACED:
1637 /* TODO: Perhaps the bandwith change could be treated as a 1640 /* TODO: Perhaps the bandwidth change could be treated as a
1638 * reservation itself? */ 1641 * reservation itself? */
1639 ret = -EBUSY; 1642 ret = -EBUSY;
1640 goto out; 1643 goto out;
diff --git a/net/mac80211/debug.h b/net/mac80211/debug.h
index 493d68061f0c..1956b3115dd5 100644
--- a/net/mac80211/debug.h
+++ b/net/mac80211/debug.h
@@ -2,6 +2,12 @@
2#define __MAC80211_DEBUG_H 2#define __MAC80211_DEBUG_H
3#include <net/cfg80211.h> 3#include <net/cfg80211.h>
4 4
5#ifdef CONFIG_MAC80211_OCB_DEBUG
6#define MAC80211_OCB_DEBUG 1
7#else
8#define MAC80211_OCB_DEBUG 0
9#endif
10
5#ifdef CONFIG_MAC80211_IBSS_DEBUG 11#ifdef CONFIG_MAC80211_IBSS_DEBUG
6#define MAC80211_IBSS_DEBUG 1 12#define MAC80211_IBSS_DEBUG 1
7#else 13#else
@@ -131,6 +137,10 @@ do { \
131 _sdata_dbg(MAC80211_HT_DEBUG && net_ratelimit(), \ 137 _sdata_dbg(MAC80211_HT_DEBUG && net_ratelimit(), \
132 sdata, fmt, ##__VA_ARGS__) 138 sdata, fmt, ##__VA_ARGS__)
133 139
140#define ocb_dbg(sdata, fmt, ...) \
141 _sdata_dbg(MAC80211_OCB_DEBUG, \
142 sdata, fmt, ##__VA_ARGS__)
143
134#define ibss_dbg(sdata, fmt, ...) \ 144#define ibss_dbg(sdata, fmt, ...) \
135 _sdata_dbg(MAC80211_IBSS_DEBUG, \ 145 _sdata_dbg(MAC80211_IBSS_DEBUG, \
136 sdata, fmt, ##__VA_ARGS__) 146 sdata, fmt, ##__VA_ARGS__)
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 1521cabad3d6..5523b94c7c90 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -300,10 +300,8 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
300 300
301 lockdep_assert_held(&sdata->local->key_mtx); 301 lockdep_assert_held(&sdata->local->key_mtx);
302 302
303 if (sdata->debugfs.default_unicast_key) { 303 debugfs_remove(sdata->debugfs.default_unicast_key);
304 debugfs_remove(sdata->debugfs.default_unicast_key); 304 sdata->debugfs.default_unicast_key = NULL;
305 sdata->debugfs.default_unicast_key = NULL;
306 }
307 305
308 if (sdata->default_unicast_key) { 306 if (sdata->default_unicast_key) {
309 key = key_mtx_dereference(sdata->local, 307 key = key_mtx_dereference(sdata->local,
@@ -314,10 +312,8 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
314 sdata->vif.debugfs_dir, buf); 312 sdata->vif.debugfs_dir, buf);
315 } 313 }
316 314
317 if (sdata->debugfs.default_multicast_key) { 315 debugfs_remove(sdata->debugfs.default_multicast_key);
318 debugfs_remove(sdata->debugfs.default_multicast_key); 316 sdata->debugfs.default_multicast_key = NULL;
319 sdata->debugfs.default_multicast_key = NULL;
320 }
321 317
322 if (sdata->default_multicast_key) { 318 if (sdata->default_multicast_key) {
323 key = key_mtx_dereference(sdata->local, 319 key = key_mtx_dereference(sdata->local,
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 196d48c68134..9759dd1f0734 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -214,7 +214,8 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
214 BSS_CHANGED_BEACON_ENABLED) && 214 BSS_CHANGED_BEACON_ENABLED) &&
215 sdata->vif.type != NL80211_IFTYPE_AP && 215 sdata->vif.type != NL80211_IFTYPE_AP &&
216 sdata->vif.type != NL80211_IFTYPE_ADHOC && 216 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
217 sdata->vif.type != NL80211_IFTYPE_MESH_POINT)) 217 sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
218 sdata->vif.type != NL80211_IFTYPE_OCB))
218 return; 219 return;
219 220
220 if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE || 221 if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE ||
@@ -631,6 +632,12 @@ static inline int drv_conf_tx(struct ieee80211_local *local,
631 if (!check_sdata_in_driver(sdata)) 632 if (!check_sdata_in_driver(sdata))
632 return -EIO; 633 return -EIO;
633 634
635 if (WARN_ONCE(params->cw_min == 0 ||
636 params->cw_min > params->cw_max,
637 "%s: invalid CW_min/CW_max: %d/%d\n",
638 sdata->name, params->cw_min, params->cw_max))
639 return -EINVAL;
640
634 trace_drv_conf_tx(local, sdata, ac, params); 641 trace_drv_conf_tx(local, sdata, ac, params);
635 if (local->ops->conf_tx) 642 if (local->ops->conf_tx)
636 ret = local->ops->conf_tx(&local->hw, &sdata->vif, 643 ret = local->ops->conf_tx(&local->hw, &sdata->vif,
@@ -764,12 +771,13 @@ static inline void drv_flush(struct ieee80211_local *local,
764} 771}
765 772
766static inline void drv_channel_switch(struct ieee80211_local *local, 773static inline void drv_channel_switch(struct ieee80211_local *local,
767 struct ieee80211_channel_switch *ch_switch) 774 struct ieee80211_sub_if_data *sdata,
775 struct ieee80211_channel_switch *ch_switch)
768{ 776{
769 might_sleep(); 777 might_sleep();
770 778
771 trace_drv_channel_switch(local, ch_switch); 779 trace_drv_channel_switch(local, sdata, ch_switch);
772 local->ops->channel_switch(&local->hw, ch_switch); 780 local->ops->channel_switch(&local->hw, &sdata->vif, ch_switch);
773 trace_drv_return_void(local); 781 trace_drv_return_void(local);
774} 782}
775 783
@@ -1144,13 +1152,15 @@ static inline void drv_stop_ap(struct ieee80211_local *local,
1144 trace_drv_return_void(local); 1152 trace_drv_return_void(local);
1145} 1153}
1146 1154
1147static inline void drv_restart_complete(struct ieee80211_local *local) 1155static inline void
1156drv_reconfig_complete(struct ieee80211_local *local,
1157 enum ieee80211_reconfig_type reconfig_type)
1148{ 1158{
1149 might_sleep(); 1159 might_sleep();
1150 1160
1151 trace_drv_restart_complete(local); 1161 trace_drv_reconfig_complete(local, reconfig_type);
1152 if (local->ops->restart_complete) 1162 if (local->ops->reconfig_complete)
1153 local->ops->restart_complete(&local->hw); 1163 local->ops->reconfig_complete(&local->hw, reconfig_type);
1154 trace_drv_return_void(local); 1164 trace_drv_return_void(local);
1155} 1165}
1156 1166
@@ -1196,6 +1206,40 @@ drv_channel_switch_beacon(struct ieee80211_sub_if_data *sdata,
1196 } 1206 }
1197} 1207}
1198 1208
1209static inline int
1210drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata,
1211 struct ieee80211_channel_switch *ch_switch)
1212{
1213 struct ieee80211_local *local = sdata->local;
1214 int ret = 0;
1215
1216 if (!check_sdata_in_driver(sdata))
1217 return -EIO;
1218
1219 trace_drv_pre_channel_switch(local, sdata, ch_switch);
1220 if (local->ops->pre_channel_switch)
1221 ret = local->ops->pre_channel_switch(&local->hw, &sdata->vif,
1222 ch_switch);
1223 trace_drv_return_int(local, ret);
1224 return ret;
1225}
1226
1227static inline int
1228drv_post_channel_switch(struct ieee80211_sub_if_data *sdata)
1229{
1230 struct ieee80211_local *local = sdata->local;
1231 int ret = 0;
1232
1233 if (!check_sdata_in_driver(sdata))
1234 return -EIO;
1235
1236 trace_drv_post_channel_switch(local, sdata);
1237 if (local->ops->post_channel_switch)
1238 ret = local->ops->post_channel_switch(&local->hw, &sdata->vif);
1239 trace_drv_return_int(local, ret);
1240 return ret;
1241}
1242
1199static inline int drv_join_ibss(struct ieee80211_local *local, 1243static inline int drv_join_ibss(struct ieee80211_local *local,
1200 struct ieee80211_sub_if_data *sdata) 1244 struct ieee80211_sub_if_data *sdata)
1201{ 1245{
@@ -1238,4 +1282,18 @@ static inline u32 drv_get_expected_throughput(struct ieee80211_local *local,
1238 return ret; 1282 return ret;
1239} 1283}
1240 1284
1285static inline int drv_get_txpower(struct ieee80211_local *local,
1286 struct ieee80211_sub_if_data *sdata, int *dbm)
1287{
1288 int ret;
1289
1290 if (!local->ops->get_txpower)
1291 return -EOPNOTSUPP;
1292
1293 ret = local->ops->get_txpower(&local->hw, &sdata->vif, dbm);
1294 trace_drv_get_txpower(local, sdata, *dbm, ret);
1295
1296 return ret;
1297}
1298
1241#endif /* __MAC80211_DRIVER_OPS */ 1299#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index c2aaec4dfcf0..a51c993ece73 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -131,7 +131,7 @@ enum ieee80211_bss_corrupt_data_flags {
131 * 131 *
132 * These are bss flags that are attached to a bss in the 132 * These are bss flags that are attached to a bss in the
133 * @valid_data field of &struct ieee80211_bss. They show which parts 133 * @valid_data field of &struct ieee80211_bss. They show which parts
134 * of the data structure were recieved as a result of an un-corrupted 134 * of the data structure were received as a result of an un-corrupted
135 * beacon/probe response. 135 * beacon/probe response.
136 */ 136 */
137enum ieee80211_bss_valid_data_flags { 137enum ieee80211_bss_valid_data_flags {
@@ -399,6 +399,24 @@ struct ieee80211_mgd_assoc_data {
399 u8 ie[]; 399 u8 ie[];
400}; 400};
401 401
402struct ieee80211_sta_tx_tspec {
403 /* timestamp of the first packet in the time slice */
404 unsigned long time_slice_start;
405
406 u32 admitted_time; /* in usecs, unlike over the air */
407 u8 tsid;
408 s8 up; /* signed to be able to invalidate with -1 during teardown */
409
410 /* consumed TX time in microseconds in the time slice */
411 u32 consumed_tx_time;
412 enum {
413 TX_TSPEC_ACTION_NONE = 0,
414 TX_TSPEC_ACTION_DOWNGRADE,
415 TX_TSPEC_ACTION_STOP_DOWNGRADE,
416 } action;
417 bool downgraded;
418};
419
402struct ieee80211_if_managed { 420struct ieee80211_if_managed {
403 struct timer_list timer; 421 struct timer_list timer;
404 struct timer_list conn_mon_timer; 422 struct timer_list conn_mon_timer;
@@ -434,6 +452,8 @@ struct ieee80211_if_managed {
434 452
435 unsigned int flags; 453 unsigned int flags;
436 454
455 bool csa_waiting_bcn;
456
437 bool beacon_crc_valid; 457 bool beacon_crc_valid;
438 u32 beacon_crc; 458 u32 beacon_crc;
439 459
@@ -507,6 +527,16 @@ struct ieee80211_if_managed {
507 527
508 u8 tdls_peer[ETH_ALEN] __aligned(2); 528 u8 tdls_peer[ETH_ALEN] __aligned(2);
509 struct delayed_work tdls_peer_del_work; 529 struct delayed_work tdls_peer_del_work;
530
531 /* WMM-AC TSPEC support */
532 struct ieee80211_sta_tx_tspec tx_tspec[IEEE80211_NUM_ACS];
533 /* Use a separate work struct so that we can do something here
534 * while the sdata->work is flushing the queues, for example.
535 * otherwise, in scenarios where we hardly get any traffic out
536 * on the BE queue, but there's a lot of VO traffic, we might
537 * get stuck in a downgraded situation and flush takes forever.
538 */
539 struct delayed_work tx_tspec_wk;
510}; 540};
511 541
512struct ieee80211_if_ibss { 542struct ieee80211_if_ibss {
@@ -547,6 +577,25 @@ struct ieee80211_if_ibss {
547}; 577};
548 578
549/** 579/**
580 * struct ieee80211_if_ocb - OCB mode state
581 *
582 * @housekeeping_timer: timer for periodic invocation of a housekeeping task
583 * @wrkq_flags: OCB deferred task action
584 * @incomplete_lock: delayed STA insertion lock
585 * @incomplete_stations: list of STAs waiting for delayed insertion
586 * @joined: indication if the interface is connected to an OCB network
587 */
588struct ieee80211_if_ocb {
589 struct timer_list housekeeping_timer;
590 unsigned long wrkq_flags;
591
592 spinlock_t incomplete_lock;
593 struct list_head incomplete_stations;
594
595 bool joined;
596};
597
598/**
550 * struct ieee80211_mesh_sync_ops - Extensible synchronization framework interface 599 * struct ieee80211_mesh_sync_ops - Extensible synchronization framework interface
551 * 600 *
552 * these declarations define the interface, which enables 601 * these declarations define the interface, which enables
@@ -839,6 +888,7 @@ struct ieee80211_sub_if_data {
839 struct ieee80211_if_managed mgd; 888 struct ieee80211_if_managed mgd;
840 struct ieee80211_if_ibss ibss; 889 struct ieee80211_if_ibss ibss;
841 struct ieee80211_if_mesh mesh; 890 struct ieee80211_if_mesh mesh;
891 struct ieee80211_if_ocb ocb;
842 u32 mntr_flags; 892 u32 mntr_flags;
843 } u; 893 } u;
844 894
@@ -1307,6 +1357,9 @@ struct ieee80211_local {
1307 /* virtual monitor interface */ 1357 /* virtual monitor interface */
1308 struct ieee80211_sub_if_data __rcu *monitor_sdata; 1358 struct ieee80211_sub_if_data __rcu *monitor_sdata;
1309 struct cfg80211_chan_def monitor_chandef; 1359 struct cfg80211_chan_def monitor_chandef;
1360
1361 /* extended capabilities provided by mac80211 */
1362 u8 ext_capa[8];
1310}; 1363};
1311 1364
1312static inline struct ieee80211_sub_if_data * 1365static inline struct ieee80211_sub_if_data *
@@ -1454,6 +1507,7 @@ void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata,
1454 __le16 fc, bool acked); 1507 __le16 fc, bool acked);
1455void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata); 1508void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata);
1456void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); 1509void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);
1510void ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata);
1457 1511
1458/* IBSS code */ 1512/* IBSS code */
1459void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); 1513void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
@@ -1471,6 +1525,15 @@ int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata,
1471int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata); 1525int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata);
1472void ieee80211_ibss_stop(struct ieee80211_sub_if_data *sdata); 1526void ieee80211_ibss_stop(struct ieee80211_sub_if_data *sdata);
1473 1527
1528/* OCB code */
1529void ieee80211_ocb_work(struct ieee80211_sub_if_data *sdata);
1530void ieee80211_ocb_rx_no_sta(struct ieee80211_sub_if_data *sdata,
1531 const u8 *bssid, const u8 *addr, u32 supp_rates);
1532void ieee80211_ocb_setup_sdata(struct ieee80211_sub_if_data *sdata);
1533int ieee80211_ocb_join(struct ieee80211_sub_if_data *sdata,
1534 struct ocb_setup *setup);
1535int ieee80211_ocb_leave(struct ieee80211_sub_if_data *sdata);
1536
1474/* mesh code */ 1537/* mesh code */
1475void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata); 1538void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata);
1476void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, 1539void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
@@ -1758,6 +1821,13 @@ static inline bool ieee80211_rx_reorder_ready(struct sk_buff_head *frames)
1758 return true; 1821 return true;
1759} 1822}
1760 1823
1824extern const int ieee802_1d_to_ac[8];
1825
1826static inline int ieee80211_ac_from_tid(int tid)
1827{
1828 return ieee802_1d_to_ac[tid & 7];
1829}
1830
1761void ieee80211_dynamic_ps_enable_work(struct work_struct *work); 1831void ieee80211_dynamic_ps_enable_work(struct work_struct *work);
1762void ieee80211_dynamic_ps_disable_work(struct work_struct *work); 1832void ieee80211_dynamic_ps_disable_work(struct work_struct *work);
1763void ieee80211_dynamic_ps_timer(unsigned long data); 1833void ieee80211_dynamic_ps_timer(unsigned long data);
@@ -1767,7 +1837,7 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
1767void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 1837void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
1768 struct ieee80211_hdr *hdr); 1838 struct ieee80211_hdr *hdr);
1769void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, 1839void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
1770 struct ieee80211_hdr *hdr, bool ack); 1840 struct ieee80211_hdr *hdr, bool ack, u16 tx_time);
1771 1841
1772void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, 1842void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
1773 unsigned long queues, 1843 unsigned long queues,
@@ -1833,8 +1903,10 @@ int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata,
1833void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata); 1903void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata);
1834void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata); 1904void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata);
1835 1905
1836size_t ieee80211_ie_split(const u8 *ies, size_t ielen, 1906size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen,
1837 const u8 *ids, int n_ids, size_t offset); 1907 const u8 *ids, int n_ids,
1908 const u8 *after_ric, int n_after_ric,
1909 size_t offset);
1838size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset); 1910size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset);
1839u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, 1911u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1840 u16 cap); 1912 u16 cap);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index af237223a8cd..6b631c049eba 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -259,6 +259,15 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
259 list_for_each_entry(nsdata, &local->interfaces, list) { 259 list_for_each_entry(nsdata, &local->interfaces, list) {
260 if (nsdata != sdata && ieee80211_sdata_running(nsdata)) { 260 if (nsdata != sdata && ieee80211_sdata_running(nsdata)) {
261 /* 261 /*
262 * Only OCB and monitor mode may coexist
263 */
264 if ((sdata->vif.type == NL80211_IFTYPE_OCB &&
265 nsdata->vif.type != NL80211_IFTYPE_MONITOR) ||
266 (sdata->vif.type != NL80211_IFTYPE_MONITOR &&
267 nsdata->vif.type == NL80211_IFTYPE_OCB))
268 return -EBUSY;
269
270 /*
262 * Allow only a single IBSS interface to be up at any 271 * Allow only a single IBSS interface to be up at any
263 * time. This is restricted because beacon distribution 272 * time. This is restricted because beacon distribution
264 * cannot work properly if both are in the same IBSS. 273 * cannot work properly if both are in the same IBSS.
@@ -521,6 +530,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
521 case NL80211_IFTYPE_MONITOR: 530 case NL80211_IFTYPE_MONITOR:
522 case NL80211_IFTYPE_ADHOC: 531 case NL80211_IFTYPE_ADHOC:
523 case NL80211_IFTYPE_P2P_DEVICE: 532 case NL80211_IFTYPE_P2P_DEVICE:
533 case NL80211_IFTYPE_OCB:
524 /* no special treatment */ 534 /* no special treatment */
525 break; 535 break;
526 case NL80211_IFTYPE_UNSPECIFIED: 536 case NL80211_IFTYPE_UNSPECIFIED:
@@ -631,6 +641,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
631 case NL80211_IFTYPE_ADHOC: 641 case NL80211_IFTYPE_ADHOC:
632 case NL80211_IFTYPE_AP: 642 case NL80211_IFTYPE_AP:
633 case NL80211_IFTYPE_MESH_POINT: 643 case NL80211_IFTYPE_MESH_POINT:
644 case NL80211_IFTYPE_OCB:
634 netif_carrier_off(dev); 645 netif_carrier_off(dev);
635 break; 646 break;
636 case NL80211_IFTYPE_WDS: 647 case NL80211_IFTYPE_WDS:
@@ -842,6 +853,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
842 sdata_lock(sdata); 853 sdata_lock(sdata);
843 mutex_lock(&local->mtx); 854 mutex_lock(&local->mtx);
844 sdata->vif.csa_active = false; 855 sdata->vif.csa_active = false;
856 if (sdata->vif.type == NL80211_IFTYPE_STATION)
857 sdata->u.mgd.csa_waiting_bcn = false;
845 if (sdata->csa_block_tx) { 858 if (sdata->csa_block_tx) {
846 ieee80211_wake_vif_queues(local, sdata, 859 ieee80211_wake_vif_queues(local, sdata,
847 IEEE80211_QUEUE_STOP_REASON_CSA); 860 IEEE80211_QUEUE_STOP_REASON_CSA);
@@ -1279,6 +1292,9 @@ static void ieee80211_iface_work(struct work_struct *work)
1279 break; 1292 break;
1280 ieee80211_mesh_work(sdata); 1293 ieee80211_mesh_work(sdata);
1281 break; 1294 break;
1295 case NL80211_IFTYPE_OCB:
1296 ieee80211_ocb_work(sdata);
1297 break;
1282 default: 1298 default:
1283 break; 1299 break;
1284 } 1300 }
@@ -1298,6 +1314,9 @@ static void ieee80211_recalc_smps_work(struct work_struct *work)
1298static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, 1314static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
1299 enum nl80211_iftype type) 1315 enum nl80211_iftype type)
1300{ 1316{
1317 static const u8 bssid_wildcard[ETH_ALEN] = {0xff, 0xff, 0xff,
1318 0xff, 0xff, 0xff};
1319
1301 /* clear type-dependent union */ 1320 /* clear type-dependent union */
1302 memset(&sdata->u, 0, sizeof(sdata->u)); 1321 memset(&sdata->u, 0, sizeof(sdata->u));
1303 1322
@@ -1349,6 +1368,10 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
1349 sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid; 1368 sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
1350 ieee80211_sta_setup_sdata(sdata); 1369 ieee80211_sta_setup_sdata(sdata);
1351 break; 1370 break;
1371 case NL80211_IFTYPE_OCB:
1372 sdata->vif.bss_conf.bssid = bssid_wildcard;
1373 ieee80211_ocb_setup_sdata(sdata);
1374 break;
1352 case NL80211_IFTYPE_ADHOC: 1375 case NL80211_IFTYPE_ADHOC:
1353 sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; 1376 sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
1354 ieee80211_ibss_setup_sdata(sdata); 1377 ieee80211_ibss_setup_sdata(sdata);
@@ -1396,6 +1419,7 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata,
1396 case NL80211_IFTYPE_AP: 1419 case NL80211_IFTYPE_AP:
1397 case NL80211_IFTYPE_STATION: 1420 case NL80211_IFTYPE_STATION:
1398 case NL80211_IFTYPE_ADHOC: 1421 case NL80211_IFTYPE_ADHOC:
1422 case NL80211_IFTYPE_OCB:
1399 /* 1423 /*
1400 * Could maybe also all others here? 1424 * Could maybe also all others here?
1401 * Just not sure how that interacts 1425 * Just not sure how that interacts
@@ -1411,6 +1435,7 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata,
1411 case NL80211_IFTYPE_AP: 1435 case NL80211_IFTYPE_AP:
1412 case NL80211_IFTYPE_STATION: 1436 case NL80211_IFTYPE_STATION:
1413 case NL80211_IFTYPE_ADHOC: 1437 case NL80211_IFTYPE_ADHOC:
1438 case NL80211_IFTYPE_OCB:
1414 /* 1439 /*
1415 * Could probably support everything 1440 * Could probably support everything
1416 * but WDS here (WDS do_open can fail 1441 * but WDS here (WDS do_open can fail
@@ -1669,7 +1694,10 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
1669 } 1694 }
1670 1695
1671 ieee80211_assign_perm_addr(local, ndev->perm_addr, type); 1696 ieee80211_assign_perm_addr(local, ndev->perm_addr, type);
1672 memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); 1697 if (params && is_valid_ether_addr(params->macaddr))
1698 memcpy(ndev->dev_addr, params->macaddr, ETH_ALEN);
1699 else
1700 memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN);
1673 SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); 1701 SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy));
1674 1702
1675 /* don't use IEEE80211_DEV_TO_SUB_IF -- it checks too much */ 1703 /* don't use IEEE80211_DEV_TO_SUB_IF -- it checks too much */
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 4712150dc210..434a91ad12c8 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -94,8 +94,17 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
94 94
95 might_sleep(); 95 might_sleep();
96 96
97 if (key->flags & KEY_FLAG_TAINTED) 97 if (key->flags & KEY_FLAG_TAINTED) {
98 /* If we get here, it's during resume and the key is
99 * tainted so shouldn't be used/programmed any more.
100 * However, its flags may still indicate that it was
101 * programmed into the device (since we're in resume)
102 * so clear that flag now to avoid trying to remove
103 * it again later.
104 */
105 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
98 return -EINVAL; 106 return -EINVAL;
107 }
99 108
100 if (!key->local->ops->set_key) 109 if (!key->local->ops->set_key)
101 goto out_unsupported; 110 goto out_unsupported;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0de7c93bf62b..282a4f36eb92 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -478,13 +478,9 @@ static const struct ieee80211_vht_cap mac80211_vht_capa_mod_mask = {
478 }, 478 },
479}; 479};
480 480
481static const u8 extended_capabilities[] = { 481struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
482 0, 0, 0, 0, 0, 0, 0, 482 const struct ieee80211_ops *ops,
483 WLAN_EXT_CAPA8_OPMODE_NOTIF, 483 const char *requested_name)
484};
485
486struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
487 const struct ieee80211_ops *ops)
488{ 484{
489 struct ieee80211_local *local; 485 struct ieee80211_local *local;
490 int priv_size, i; 486 int priv_size, i;
@@ -524,7 +520,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
524 */ 520 */
525 priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len; 521 priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len;
526 522
527 wiphy = wiphy_new(&mac80211_config_ops, priv_size); 523 wiphy = wiphy_new_nm(&mac80211_config_ops, priv_size, requested_name);
528 524
529 if (!wiphy) 525 if (!wiphy)
530 return NULL; 526 return NULL;
@@ -539,10 +535,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
539 WIPHY_FLAG_REPORTS_OBSS | 535 WIPHY_FLAG_REPORTS_OBSS |
540 WIPHY_FLAG_OFFCHAN_TX; 536 WIPHY_FLAG_OFFCHAN_TX;
541 537
542 wiphy->extended_capabilities = extended_capabilities;
543 wiphy->extended_capabilities_mask = extended_capabilities;
544 wiphy->extended_capabilities_len = ARRAY_SIZE(extended_capabilities);
545
546 if (ops->remain_on_channel) 538 if (ops->remain_on_channel)
547 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 539 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
548 540
@@ -550,6 +542,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
550 NL80211_FEATURE_SAE | 542 NL80211_FEATURE_SAE |
551 NL80211_FEATURE_HT_IBSS | 543 NL80211_FEATURE_HT_IBSS |
552 NL80211_FEATURE_VIF_TXPOWER | 544 NL80211_FEATURE_VIF_TXPOWER |
545 NL80211_FEATURE_MAC_ON_CREATE |
553 NL80211_FEATURE_USERSPACE_MPM; 546 NL80211_FEATURE_USERSPACE_MPM;
554 547
555 if (!ops->hw_scan) 548 if (!ops->hw_scan)
@@ -591,6 +584,13 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
591 wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; 584 wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask;
592 wiphy->vht_capa_mod_mask = &mac80211_vht_capa_mod_mask; 585 wiphy->vht_capa_mod_mask = &mac80211_vht_capa_mod_mask;
593 586
587 local->ext_capa[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF;
588
589 wiphy->extended_capabilities = local->ext_capa;
590 wiphy->extended_capabilities_mask = local->ext_capa;
591 wiphy->extended_capabilities_len =
592 ARRAY_SIZE(local->ext_capa);
593
594 INIT_LIST_HEAD(&local->interfaces); 594 INIT_LIST_HEAD(&local->interfaces);
595 595
596 __hw_addr_init(&local->mc_list); 596 __hw_addr_init(&local->mc_list);
@@ -651,7 +651,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
651 651
652 return &local->hw; 652 return &local->hw;
653} 653}
654EXPORT_SYMBOL(ieee80211_alloc_hw); 654EXPORT_SYMBOL(ieee80211_alloc_hw_nm);
655 655
656static int ieee80211_init_cipher_suites(struct ieee80211_local *local) 656static int ieee80211_init_cipher_suites(struct ieee80211_local *local)
657{ 657{
@@ -787,13 +787,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
787 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_WDS)) 787 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_WDS))
788 return -EINVAL; 788 return -EINVAL;
789 789
790 /* DFS currently not supported with channel context drivers */ 790 /* DFS is not supported with multi-channel combinations yet */
791 for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) { 791 for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) {
792 const struct ieee80211_iface_combination *comb; 792 const struct ieee80211_iface_combination *comb;
793 793
794 comb = &local->hw.wiphy->iface_combinations[i]; 794 comb = &local->hw.wiphy->iface_combinations[i];
795 795
796 if (comb->radar_detect_widths) 796 if (comb->radar_detect_widths &&
797 comb->num_different_channels > 1)
797 return -EINVAL; 798 return -EINVAL;
798 } 799 }
799 } 800 }
@@ -958,6 +959,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
958 if (local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) 959 if (local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)
959 local->hw.wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; 960 local->hw.wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
960 961
962 /* mac80211 supports eCSA, if the driver supports STA CSA at all */
963 if (local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)
964 local->ext_capa[0] |= WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING;
965
961 local->hw.wiphy->max_num_csa_counters = IEEE80211_MAX_CSA_COUNTERS_NUM; 966 local->hw.wiphy->max_num_csa_counters = IEEE80211_MAX_CSA_COUNTERS_NUM;
962 967
963 result = wiphy_register(local->hw.wiphy); 968 result = wiphy_register(local->hw.wiphy);
@@ -1019,7 +1024,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1019 } 1024 }
1020 1025
1021 /* add one default STA interface if supported */ 1026 /* add one default STA interface if supported */
1022 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) { 1027 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION) &&
1028 !(hw->flags & IEEE80211_HW_NO_AUTO_VIF)) {
1023 result = ieee80211_if_add(local, "wlan%d", NULL, 1029 result = ieee80211_if_add(local, "wlan%d", NULL,
1024 NL80211_IFTYPE_STATION, NULL); 1030 NL80211_IFTYPE_STATION, NULL);
1025 if (result) 1031 if (result)
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index f39a19f9090f..50c8473cf9dc 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -270,6 +270,8 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata,
270 const u8 *dst, const u8 *mpp); 270 const u8 *dst, const u8 *mpp);
271struct mesh_path * 271struct mesh_path *
272mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx); 272mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx);
273struct mesh_path *
274mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx);
273void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop); 275void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop);
274void mesh_path_expire(struct ieee80211_sub_if_data *sdata); 276void mesh_path_expire(struct ieee80211_sub_if_data *sdata);
275void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, 277void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
@@ -317,6 +319,7 @@ void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);
317 319
318bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt); 320bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt);
319extern int mesh_paths_generation; 321extern int mesh_paths_generation;
322extern int mpp_paths_generation;
320 323
321#ifdef CONFIG_MAC80211_MESH 324#ifdef CONFIG_MAC80211_MESH
322static inline 325static inline
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index a6699dceae7c..b890e225a8f1 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -44,6 +44,7 @@ static struct mesh_table __rcu *mesh_paths;
44static struct mesh_table __rcu *mpp_paths; /* Store paths for MPP&MAP */ 44static struct mesh_table __rcu *mpp_paths; /* Store paths for MPP&MAP */
45 45
46int mesh_paths_generation; 46int mesh_paths_generation;
47int mpp_paths_generation;
47 48
48/* This lock will have the grow table function as writer and add / delete nodes 49/* This lock will have the grow table function as writer and add / delete nodes
49 * as readers. RCU provides sufficient protection only when reading the table 50 * as readers. RCU provides sufficient protection only when reading the table
@@ -410,6 +411,33 @@ mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
410} 411}
411 412
412/** 413/**
414 * mpp_path_lookup_by_idx - look up a path in the proxy path table by its index
415 * @idx: index
416 * @sdata: local subif, or NULL for all entries
417 *
418 * Returns: pointer to the proxy path structure, or NULL if not found.
419 *
420 * Locking: must be called within a read rcu section.
421 */
422struct mesh_path *
423mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
424{
425 struct mesh_table *tbl = rcu_dereference(mpp_paths);
426 struct mpath_node *node;
427 int i;
428 int j = 0;
429
430 for_each_mesh_entry(tbl, node, i) {
431 if (sdata && node->mpath->sdata != sdata)
432 continue;
433 if (j++ == idx)
434 return node->mpath;
435 }
436
437 return NULL;
438}
439
440/**
413 * mesh_path_add_gate - add the given mpath to a mesh gate to our path table 441 * mesh_path_add_gate - add the given mpath to a mesh gate to our path table
414 * @mpath: gate path to add to table 442 * @mpath: gate path to add to table
415 */ 443 */
@@ -691,6 +719,9 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata,
691 719
692 spin_unlock(&tbl->hashwlock[hash_idx]); 720 spin_unlock(&tbl->hashwlock[hash_idx]);
693 read_unlock_bh(&pathtbl_resize_lock); 721 read_unlock_bh(&pathtbl_resize_lock);
722
723 mpp_paths_generation++;
724
694 if (grow) { 725 if (grow) {
695 set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags); 726 set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags);
696 ieee80211_queue_work(&local->hw, &sdata->work); 727 ieee80211_queue_work(&local->hw, &sdata->work);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 2de88704278b..213a420704a6 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -775,11 +775,30 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
775 WLAN_EID_QOS_CAPA, 775 WLAN_EID_QOS_CAPA,
776 WLAN_EID_RRM_ENABLED_CAPABILITIES, 776 WLAN_EID_RRM_ENABLED_CAPABILITIES,
777 WLAN_EID_MOBILITY_DOMAIN, 777 WLAN_EID_MOBILITY_DOMAIN,
778 WLAN_EID_FAST_BSS_TRANSITION, /* reassoc only */
779 WLAN_EID_RIC_DATA, /* reassoc only */
778 WLAN_EID_SUPPORTED_REGULATORY_CLASSES, 780 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
779 }; 781 };
780 noffset = ieee80211_ie_split(assoc_data->ie, assoc_data->ie_len, 782 static const u8 after_ric[] = {
781 before_ht, ARRAY_SIZE(before_ht), 783 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
782 offset); 784 WLAN_EID_HT_CAPABILITY,
785 WLAN_EID_BSS_COEX_2040,
786 WLAN_EID_EXT_CAPABILITY,
787 WLAN_EID_QOS_TRAFFIC_CAPA,
788 WLAN_EID_TIM_BCAST_REQ,
789 WLAN_EID_INTERWORKING,
790 /* 60GHz doesn't happen right now */
791 WLAN_EID_VHT_CAPABILITY,
792 WLAN_EID_OPMODE_NOTIF,
793 };
794
795 noffset = ieee80211_ie_split_ric(assoc_data->ie,
796 assoc_data->ie_len,
797 before_ht,
798 ARRAY_SIZE(before_ht),
799 after_ric,
800 ARRAY_SIZE(after_ric),
801 offset);
783 pos = skb_put(skb, noffset - offset); 802 pos = skb_put(skb, noffset - offset);
784 memcpy(pos, assoc_data->ie + offset, noffset - offset); 803 memcpy(pos, assoc_data->ie + offset, noffset - offset);
785 offset = noffset; 804 offset = noffset;
@@ -813,6 +832,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
813 WLAN_EID_TIM_BCAST_REQ, 832 WLAN_EID_TIM_BCAST_REQ,
814 WLAN_EID_INTERWORKING, 833 WLAN_EID_INTERWORKING,
815 }; 834 };
835
836 /* RIC already taken above, so no need to handle here anymore */
816 noffset = ieee80211_ie_split(assoc_data->ie, assoc_data->ie_len, 837 noffset = ieee80211_ie_split(assoc_data->ie, assoc_data->ie_len,
817 before_vht, ARRAY_SIZE(before_vht), 838 before_vht, ARRAY_SIZE(before_vht),
818 offset); 839 offset);
@@ -1001,14 +1022,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
1001 /* XXX: shouldn't really modify cfg80211-owned data! */ 1022 /* XXX: shouldn't really modify cfg80211-owned data! */
1002 ifmgd->associated->channel = sdata->csa_chandef.chan; 1023 ifmgd->associated->channel = sdata->csa_chandef.chan;
1003 1024
1004 sdata->vif.csa_active = false; 1025 ifmgd->csa_waiting_bcn = true;
1005
1006 /* XXX: wait for a beacon first? */
1007 if (sdata->csa_block_tx) {
1008 ieee80211_wake_vif_queues(local, sdata,
1009 IEEE80211_QUEUE_STOP_REASON_CSA);
1010 sdata->csa_block_tx = false;
1011 }
1012 1026
1013 ieee80211_sta_reset_beacon_monitor(sdata); 1027 ieee80211_sta_reset_beacon_monitor(sdata);
1014 ieee80211_sta_reset_conn_monitor(sdata); 1028 ieee80211_sta_reset_conn_monitor(sdata);
@@ -1019,6 +1033,35 @@ out:
1019 sdata_unlock(sdata); 1033 sdata_unlock(sdata);
1020} 1034}
1021 1035
1036static void ieee80211_chswitch_post_beacon(struct ieee80211_sub_if_data *sdata)
1037{
1038 struct ieee80211_local *local = sdata->local;
1039 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1040 int ret;
1041
1042 sdata_assert_lock(sdata);
1043
1044 WARN_ON(!sdata->vif.csa_active);
1045
1046 if (sdata->csa_block_tx) {
1047 ieee80211_wake_vif_queues(local, sdata,
1048 IEEE80211_QUEUE_STOP_REASON_CSA);
1049 sdata->csa_block_tx = false;
1050 }
1051
1052 sdata->vif.csa_active = false;
1053 ifmgd->csa_waiting_bcn = false;
1054
1055 ret = drv_post_channel_switch(sdata);
1056 if (ret) {
1057 sdata_info(sdata,
1058 "driver post channel switch failed, disconnecting\n");
1059 ieee80211_queue_work(&local->hw,
1060 &ifmgd->csa_connection_drop_work);
1061 return;
1062 }
1063}
1064
1022void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success) 1065void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
1023{ 1066{
1024 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 1067 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
@@ -1046,7 +1089,8 @@ static void ieee80211_chswitch_timer(unsigned long data)
1046 1089
1047static void 1090static void
1048ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, 1091ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1049 u64 timestamp, struct ieee802_11_elems *elems, 1092 u64 timestamp, u32 device_timestamp,
1093 struct ieee802_11_elems *elems,
1050 bool beacon) 1094 bool beacon)
1051{ 1095{
1052 struct ieee80211_local *local = sdata->local; 1096 struct ieee80211_local *local = sdata->local;
@@ -1056,6 +1100,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1056 struct ieee80211_chanctx *chanctx; 1100 struct ieee80211_chanctx *chanctx;
1057 enum ieee80211_band current_band; 1101 enum ieee80211_band current_band;
1058 struct ieee80211_csa_ie csa_ie; 1102 struct ieee80211_csa_ie csa_ie;
1103 struct ieee80211_channel_switch ch_switch;
1059 int res; 1104 int res;
1060 1105
1061 sdata_assert_lock(sdata); 1106 sdata_assert_lock(sdata);
@@ -1110,21 +1155,31 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1110 1155
1111 chanctx = container_of(conf, struct ieee80211_chanctx, conf); 1156 chanctx = container_of(conf, struct ieee80211_chanctx, conf);
1112 1157
1113 if (local->use_chanctx) { 1158 if (local->use_chanctx &&
1114 u32 num_chanctx = 0; 1159 !(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) {
1115 list_for_each_entry(chanctx, &local->chanctx_list, list) 1160 sdata_info(sdata,
1116 num_chanctx++; 1161 "driver doesn't support chan-switch with channel contexts\n");
1162 ieee80211_queue_work(&local->hw,
1163 &ifmgd->csa_connection_drop_work);
1164 mutex_unlock(&local->chanctx_mtx);
1165 mutex_unlock(&local->mtx);
1166 return;
1167 }
1117 1168
1118 if (num_chanctx > 1 || 1169 ch_switch.timestamp = timestamp;
1119 !(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) { 1170 ch_switch.device_timestamp = device_timestamp;
1120 sdata_info(sdata, 1171 ch_switch.block_tx = csa_ie.mode;
1121 "not handling chan-switch with channel contexts\n"); 1172 ch_switch.chandef = csa_ie.chandef;
1122 ieee80211_queue_work(&local->hw, 1173 ch_switch.count = csa_ie.count;
1123 &ifmgd->csa_connection_drop_work); 1174
1124 mutex_unlock(&local->chanctx_mtx); 1175 if (drv_pre_channel_switch(sdata, &ch_switch)) {
1125 mutex_unlock(&local->mtx); 1176 sdata_info(sdata,
1126 return; 1177 "preparing for channel switch failed, disconnecting\n");
1127 } 1178 ieee80211_queue_work(&local->hw,
1179 &ifmgd->csa_connection_drop_work);
1180 mutex_unlock(&local->chanctx_mtx);
1181 mutex_unlock(&local->mtx);
1182 return;
1128 } 1183 }
1129 1184
1130 res = ieee80211_vif_reserve_chanctx(sdata, &csa_ie.chandef, 1185 res = ieee80211_vif_reserve_chanctx(sdata, &csa_ie.chandef,
@@ -1152,14 +1207,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1152 1207
1153 if (local->ops->channel_switch) { 1208 if (local->ops->channel_switch) {
1154 /* use driver's channel switch callback */ 1209 /* use driver's channel switch callback */
1155 struct ieee80211_channel_switch ch_switch = { 1210 drv_channel_switch(local, sdata, &ch_switch);
1156 .timestamp = timestamp,
1157 .block_tx = csa_ie.mode,
1158 .chandef = csa_ie.chandef,
1159 .count = csa_ie.count,
1160 };
1161
1162 drv_channel_switch(local, &ch_switch);
1163 return; 1211 return;
1164 } 1212 }
1165 1213
@@ -1579,6 +1627,95 @@ void ieee80211_dfs_cac_timer_work(struct work_struct *work)
1579 mutex_unlock(&sdata->local->mtx); 1627 mutex_unlock(&sdata->local->mtx);
1580} 1628}
1581 1629
1630static bool
1631__ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata)
1632{
1633 struct ieee80211_local *local = sdata->local;
1634 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1635 bool ret;
1636 int ac;
1637
1638 if (local->hw.queues < IEEE80211_NUM_ACS)
1639 return false;
1640
1641 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
1642 struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac];
1643 int non_acm_ac;
1644 unsigned long now = jiffies;
1645
1646 if (tx_tspec->action == TX_TSPEC_ACTION_NONE &&
1647 tx_tspec->admitted_time &&
1648 time_after(now, tx_tspec->time_slice_start + HZ)) {
1649 tx_tspec->consumed_tx_time = 0;
1650 tx_tspec->time_slice_start = now;
1651
1652 if (tx_tspec->downgraded)
1653 tx_tspec->action =
1654 TX_TSPEC_ACTION_STOP_DOWNGRADE;
1655 }
1656
1657 switch (tx_tspec->action) {
1658 case TX_TSPEC_ACTION_STOP_DOWNGRADE:
1659 /* take the original parameters */
1660 if (drv_conf_tx(local, sdata, ac, &sdata->tx_conf[ac]))
1661 sdata_err(sdata,
1662 "failed to set TX queue parameters for queue %d\n",
1663 ac);
1664 tx_tspec->action = TX_TSPEC_ACTION_NONE;
1665 tx_tspec->downgraded = false;
1666 ret = true;
1667 break;
1668 case TX_TSPEC_ACTION_DOWNGRADE:
1669 if (time_after(now, tx_tspec->time_slice_start + HZ)) {
1670 tx_tspec->action = TX_TSPEC_ACTION_NONE;
1671 ret = true;
1672 break;
1673 }
1674 /* downgrade next lower non-ACM AC */
1675 for (non_acm_ac = ac + 1;
1676 non_acm_ac < IEEE80211_NUM_ACS;
1677 non_acm_ac++)
1678 if (!(sdata->wmm_acm & BIT(7 - 2 * non_acm_ac)))
1679 break;
1680 /* The loop will result in using BK even if it requires
1681 * admission control, such configuration makes no sense
1682 * and we have to transmit somehow - the AC selection
1683 * does the same thing.
1684 */
1685 if (drv_conf_tx(local, sdata, ac,
1686 &sdata->tx_conf[non_acm_ac]))
1687 sdata_err(sdata,
1688 "failed to set TX queue parameters for queue %d\n",
1689 ac);
1690 tx_tspec->action = TX_TSPEC_ACTION_NONE;
1691 ret = true;
1692 schedule_delayed_work(&ifmgd->tx_tspec_wk,
1693 tx_tspec->time_slice_start + HZ - now + 1);
1694 break;
1695 case TX_TSPEC_ACTION_NONE:
1696 /* nothing now */
1697 break;
1698 }
1699 }
1700
1701 return ret;
1702}
1703
1704void ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata)
1705{
1706 if (__ieee80211_sta_handle_tspec_ac_params(sdata))
1707 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS);
1708}
1709
1710static void ieee80211_sta_handle_tspec_ac_params_wk(struct work_struct *work)
1711{
1712 struct ieee80211_sub_if_data *sdata;
1713
1714 sdata = container_of(work, struct ieee80211_sub_if_data,
1715 u.mgd.tx_tspec_wk.work);
1716 ieee80211_sta_handle_tspec_ac_params(sdata);
1717}
1718
1582/* MLME */ 1719/* MLME */
1583static bool ieee80211_sta_wmm_params(struct ieee80211_local *local, 1720static bool ieee80211_sta_wmm_params(struct ieee80211_local *local,
1584 struct ieee80211_sub_if_data *sdata, 1721 struct ieee80211_sub_if_data *sdata,
@@ -1663,12 +1800,14 @@ static bool ieee80211_sta_wmm_params(struct ieee80211_local *local,
1663 params.uapsd = uapsd; 1800 params.uapsd = uapsd;
1664 1801
1665 mlme_dbg(sdata, 1802 mlme_dbg(sdata,
1666 "WMM queue=%d aci=%d acm=%d aifs=%d cWmin=%d cWmax=%d txop=%d uapsd=%d\n", 1803 "WMM queue=%d aci=%d acm=%d aifs=%d cWmin=%d cWmax=%d txop=%d uapsd=%d, downgraded=%d\n",
1667 queue, aci, acm, 1804 queue, aci, acm,
1668 params.aifs, params.cw_min, params.cw_max, 1805 params.aifs, params.cw_min, params.cw_max,
1669 params.txop, params.uapsd); 1806 params.txop, params.uapsd,
1807 ifmgd->tx_tspec[queue].downgraded);
1670 sdata->tx_conf[queue] = params; 1808 sdata->tx_conf[queue] = params;
1671 if (drv_conf_tx(local, sdata, queue, &params)) 1809 if (!ifmgd->tx_tspec[queue].downgraded &&
1810 drv_conf_tx(local, sdata, queue, &params))
1672 sdata_err(sdata, 1811 sdata_err(sdata,
1673 "failed to set TX queue parameters for queue %d\n", 1812 "failed to set TX queue parameters for queue %d\n",
1674 queue); 1813 queue);
@@ -1923,6 +2062,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1923 ieee80211_vif_release_channel(sdata); 2062 ieee80211_vif_release_channel(sdata);
1924 2063
1925 sdata->vif.csa_active = false; 2064 sdata->vif.csa_active = false;
2065 ifmgd->csa_waiting_bcn = false;
1926 if (sdata->csa_block_tx) { 2066 if (sdata->csa_block_tx) {
1927 ieee80211_wake_vif_queues(local, sdata, 2067 ieee80211_wake_vif_queues(local, sdata,
1928 IEEE80211_QUEUE_STOP_REASON_CSA); 2068 IEEE80211_QUEUE_STOP_REASON_CSA);
@@ -1930,6 +2070,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1930 } 2070 }
1931 mutex_unlock(&local->mtx); 2071 mutex_unlock(&local->mtx);
1932 2072
2073 /* existing TX TSPEC sessions no longer exist */
2074 memset(ifmgd->tx_tspec, 0, sizeof(ifmgd->tx_tspec));
2075 cancel_delayed_work_sync(&ifmgd->tx_tspec_wk);
2076
1933 sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; 2077 sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
1934} 2078}
1935 2079
@@ -1982,9 +2126,46 @@ out:
1982 mutex_unlock(&local->mtx); 2126 mutex_unlock(&local->mtx);
1983} 2127}
1984 2128
2129static void ieee80211_sta_tx_wmm_ac_notify(struct ieee80211_sub_if_data *sdata,
2130 struct ieee80211_hdr *hdr,
2131 u16 tx_time)
2132{
2133 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2134 u16 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
2135 int ac = ieee80211_ac_from_tid(tid);
2136 struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac];
2137 unsigned long now = jiffies;
2138
2139 if (likely(!tx_tspec->admitted_time))
2140 return;
2141
2142 if (time_after(now, tx_tspec->time_slice_start + HZ)) {
2143 tx_tspec->consumed_tx_time = 0;
2144 tx_tspec->time_slice_start = now;
2145
2146 if (tx_tspec->downgraded) {
2147 tx_tspec->action = TX_TSPEC_ACTION_STOP_DOWNGRADE;
2148 schedule_delayed_work(&ifmgd->tx_tspec_wk, 0);
2149 }
2150 }
2151
2152 if (tx_tspec->downgraded)
2153 return;
2154
2155 tx_tspec->consumed_tx_time += tx_time;
2156
2157 if (tx_tspec->consumed_tx_time >= tx_tspec->admitted_time) {
2158 tx_tspec->downgraded = true;
2159 tx_tspec->action = TX_TSPEC_ACTION_DOWNGRADE;
2160 schedule_delayed_work(&ifmgd->tx_tspec_wk, 0);
2161 }
2162}
2163
1985void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, 2164void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
1986 struct ieee80211_hdr *hdr, bool ack) 2165 struct ieee80211_hdr *hdr, bool ack, u16 tx_time)
1987{ 2166{
2167 ieee80211_sta_tx_wmm_ac_notify(sdata, hdr, tx_time);
2168
1988 if (!ieee80211_is_data(hdr->frame_control)) 2169 if (!ieee80211_is_data(hdr->frame_control))
1989 return; 2170 return;
1990 2171
@@ -2047,8 +2228,6 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
2047 2228
2048 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); 2229 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms);
2049 run_again(sdata, ifmgd->probe_timeout); 2230 run_again(sdata, ifmgd->probe_timeout);
2050 if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
2051 ieee80211_flush_queues(sdata->local, sdata);
2052} 2231}
2053 2232
2054static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, 2233static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
@@ -2171,6 +2350,7 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
2171 true, frame_buf); 2350 true, frame_buf);
2172 mutex_lock(&local->mtx); 2351 mutex_lock(&local->mtx);
2173 sdata->vif.csa_active = false; 2352 sdata->vif.csa_active = false;
2353 ifmgd->csa_waiting_bcn = false;
2174 if (sdata->csa_block_tx) { 2354 if (sdata->csa_block_tx) {
2175 ieee80211_wake_vif_queues(local, sdata, 2355 ieee80211_wake_vif_queues(local, sdata,
2176 IEEE80211_QUEUE_STOP_REASON_CSA); 2356 IEEE80211_QUEUE_STOP_REASON_CSA);
@@ -3195,6 +3375,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3195 } 3375 }
3196 } 3376 }
3197 3377
3378 if (ifmgd->csa_waiting_bcn)
3379 ieee80211_chswitch_post_beacon(sdata);
3380
3198 if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) 3381 if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid)
3199 return; 3382 return;
3200 ifmgd->beacon_crc = ncrc; 3383 ifmgd->beacon_crc = ncrc;
@@ -3203,6 +3386,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3203 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); 3386 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
3204 3387
3205 ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, 3388 ieee80211_sta_process_chanswitch(sdata, rx_status->mactime,
3389 rx_status->device_timestamp,
3206 &elems, true); 3390 &elems, true);
3207 3391
3208 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM) && 3392 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM) &&
@@ -3334,8 +3518,9 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
3334 break; 3518 break;
3335 3519
3336 ieee80211_sta_process_chanswitch(sdata, 3520 ieee80211_sta_process_chanswitch(sdata,
3337 rx_status->mactime, 3521 rx_status->mactime,
3338 &elems, false); 3522 rx_status->device_timestamp,
3523 &elems, false);
3339 } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) { 3524 } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) {
3340 ies_len = skb->len - 3525 ies_len = skb->len -
3341 offsetof(struct ieee80211_mgmt, 3526 offsetof(struct ieee80211_mgmt,
@@ -3356,8 +3541,9 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
3356 &mgmt->u.action.u.ext_chan_switch.data; 3541 &mgmt->u.action.u.ext_chan_switch.data;
3357 3542
3358 ieee80211_sta_process_chanswitch(sdata, 3543 ieee80211_sta_process_chanswitch(sdata,
3359 rx_status->mactime, 3544 rx_status->mactime,
3360 &elems, false); 3545 rx_status->device_timestamp,
3546 &elems, false);
3361 } 3547 }
3362 break; 3548 break;
3363 } 3549 }
@@ -3664,11 +3850,12 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data)
3664 struct ieee80211_sub_if_data *sdata = 3850 struct ieee80211_sub_if_data *sdata =
3665 (struct ieee80211_sub_if_data *) data; 3851 (struct ieee80211_sub_if_data *) data;
3666 struct ieee80211_local *local = sdata->local; 3852 struct ieee80211_local *local = sdata->local;
3853 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3667 3854
3668 if (local->quiescing) 3855 if (local->quiescing)
3669 return; 3856 return;
3670 3857
3671 if (sdata->vif.csa_active) 3858 if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn)
3672 return; 3859 return;
3673 3860
3674 sdata->u.mgd.connection_loss = false; 3861 sdata->u.mgd.connection_loss = false;
@@ -3686,7 +3873,7 @@ static void ieee80211_sta_conn_mon_timer(unsigned long data)
3686 if (local->quiescing) 3873 if (local->quiescing)
3687 return; 3874 return;
3688 3875
3689 if (sdata->vif.csa_active) 3876 if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn)
3690 return; 3877 return;
3691 3878
3692 ieee80211_queue_work(&local->hw, &ifmgd->monitor_work); 3879 ieee80211_queue_work(&local->hw, &ifmgd->monitor_work);
@@ -3798,6 +3985,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
3798 (unsigned long) sdata); 3985 (unsigned long) sdata);
3799 setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer, 3986 setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer,
3800 (unsigned long) sdata); 3987 (unsigned long) sdata);
3988 INIT_DELAYED_WORK(&ifmgd->tx_tspec_wk,
3989 ieee80211_sta_handle_tspec_ac_params_wk);
3801 3990
3802 ifmgd->flags = 0; 3991 ifmgd->flags = 0;
3803 ifmgd->powersave = sdata->wdev.ps; 3992 ifmgd->powersave = sdata->wdev.ps;
diff --git a/net/mac80211/ocb.c b/net/mac80211/ocb.c
new file mode 100644
index 000000000000..358d5f9d8207
--- /dev/null
+++ b/net/mac80211/ocb.c
@@ -0,0 +1,250 @@
1/*
2 * OCB mode implementation
3 *
4 * Copyright: (c) 2014 Czech Technical University in Prague
5 * (c) 2014 Volkswagen Group Research
6 * Author: Rostislav Lisovy <rostislav.lisovy@fel.cvut.cz>
7 * Funded by: Volkswagen Group Research
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/delay.h>
15#include <linux/if_ether.h>
16#include <linux/skbuff.h>
17#include <linux/if_arp.h>
18#include <linux/etherdevice.h>
19#include <linux/rtnetlink.h>
20#include <net/mac80211.h>
21#include <asm/unaligned.h>
22
23#include "ieee80211_i.h"
24#include "driver-ops.h"
25#include "rate.h"
26
27#define IEEE80211_OCB_HOUSEKEEPING_INTERVAL (60 * HZ)
28#define IEEE80211_OCB_PEER_INACTIVITY_LIMIT (240 * HZ)
29#define IEEE80211_OCB_MAX_STA_ENTRIES 128
30
31/**
32 * enum ocb_deferred_task_flags - mac80211 OCB deferred tasks
33 * @OCB_WORK_HOUSEKEEPING: run the periodic OCB housekeeping tasks
34 *
35 * These flags are used in @wrkq_flags field of &struct ieee80211_if_ocb
36 */
37enum ocb_deferred_task_flags {
38 OCB_WORK_HOUSEKEEPING,
39};
40
41void ieee80211_ocb_rx_no_sta(struct ieee80211_sub_if_data *sdata,
42 const u8 *bssid, const u8 *addr,
43 u32 supp_rates)
44{
45 struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
46 struct ieee80211_local *local = sdata->local;
47 struct ieee80211_chanctx_conf *chanctx_conf;
48 struct ieee80211_supported_band *sband;
49 enum nl80211_bss_scan_width scan_width;
50 struct sta_info *sta;
51 int band;
52
53 /* XXX: Consider removing the least recently used entry and
54 * allow new one to be added.
55 */
56 if (local->num_sta >= IEEE80211_OCB_MAX_STA_ENTRIES) {
57 net_info_ratelimited("%s: No room for a new OCB STA entry %pM\n",
58 sdata->name, addr);
59 return;
60 }
61
62 ocb_dbg(sdata, "Adding new OCB station %pM\n", addr);
63
64 rcu_read_lock();
65 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
66 if (WARN_ON_ONCE(!chanctx_conf)) {
67 rcu_read_unlock();
68 return;
69 }
70 band = chanctx_conf->def.chan->band;
71 scan_width = cfg80211_chandef_to_scan_width(&chanctx_conf->def);
72 rcu_read_unlock();
73
74 sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
75 if (!sta)
76 return;
77
78 sta->last_rx = jiffies;
79
80 /* Add only mandatory rates for now */
81 sband = local->hw.wiphy->bands[band];
82 sta->sta.supp_rates[band] =
83 ieee80211_mandatory_rates(sband, scan_width);
84
85 spin_lock(&ifocb->incomplete_lock);
86 list_add(&sta->list, &ifocb->incomplete_stations);
87 spin_unlock(&ifocb->incomplete_lock);
88 ieee80211_queue_work(&local->hw, &sdata->work);
89}
90
91static struct sta_info *ieee80211_ocb_finish_sta(struct sta_info *sta)
92 __acquires(RCU)
93{
94 struct ieee80211_sub_if_data *sdata = sta->sdata;
95 u8 addr[ETH_ALEN];
96
97 memcpy(addr, sta->sta.addr, ETH_ALEN);
98
99 ocb_dbg(sdata, "Adding new IBSS station %pM (dev=%s)\n",
100 addr, sdata->name);
101
102 sta_info_move_state(sta, IEEE80211_STA_AUTH);
103 sta_info_move_state(sta, IEEE80211_STA_ASSOC);
104 sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
105
106 rate_control_rate_init(sta);
107
108 /* If it fails, maybe we raced another insertion? */
109 if (sta_info_insert_rcu(sta))
110 return sta_info_get(sdata, addr);
111 return sta;
112}
113
114static void ieee80211_ocb_housekeeping(struct ieee80211_sub_if_data *sdata)
115{
116 struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
117
118 ocb_dbg(sdata, "Running ocb housekeeping\n");
119
120 ieee80211_sta_expire(sdata, IEEE80211_OCB_PEER_INACTIVITY_LIMIT);
121
122 mod_timer(&ifocb->housekeeping_timer,
123 round_jiffies(jiffies + IEEE80211_OCB_HOUSEKEEPING_INTERVAL));
124}
125
126void ieee80211_ocb_work(struct ieee80211_sub_if_data *sdata)
127{
128 struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
129 struct sta_info *sta;
130
131 if (ifocb->joined != true)
132 return;
133
134 sdata_lock(sdata);
135
136 spin_lock_bh(&ifocb->incomplete_lock);
137 while (!list_empty(&ifocb->incomplete_stations)) {
138 sta = list_first_entry(&ifocb->incomplete_stations,
139 struct sta_info, list);
140 list_del(&sta->list);
141 spin_unlock_bh(&ifocb->incomplete_lock);
142
143 ieee80211_ocb_finish_sta(sta);
144 rcu_read_unlock();
145 spin_lock_bh(&ifocb->incomplete_lock);
146 }
147 spin_unlock_bh(&ifocb->incomplete_lock);
148
149 if (test_and_clear_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags))
150 ieee80211_ocb_housekeeping(sdata);
151
152 sdata_unlock(sdata);
153}
154
155static void ieee80211_ocb_housekeeping_timer(unsigned long data)
156{
157 struct ieee80211_sub_if_data *sdata = (void *)data;
158 struct ieee80211_local *local = sdata->local;
159 struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
160
161 set_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags);
162
163 ieee80211_queue_work(&local->hw, &sdata->work);
164}
165
166void ieee80211_ocb_setup_sdata(struct ieee80211_sub_if_data *sdata)
167{
168 struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
169
170 setup_timer(&ifocb->housekeeping_timer,
171 ieee80211_ocb_housekeeping_timer,
172 (unsigned long)sdata);
173 INIT_LIST_HEAD(&ifocb->incomplete_stations);
174 spin_lock_init(&ifocb->incomplete_lock);
175}
176
177int ieee80211_ocb_join(struct ieee80211_sub_if_data *sdata,
178 struct ocb_setup *setup)
179{
180 struct ieee80211_local *local = sdata->local;
181 struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
182 u32 changed = BSS_CHANGED_OCB;
183 int err;
184
185 if (ifocb->joined == true)
186 return -EINVAL;
187
188 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
189 sdata->smps_mode = IEEE80211_SMPS_OFF;
190 sdata->needed_rx_chains = sdata->local->rx_chains;
191
192 mutex_lock(&sdata->local->mtx);
193 err = ieee80211_vif_use_channel(sdata, &setup->chandef,
194 IEEE80211_CHANCTX_SHARED);
195 mutex_unlock(&sdata->local->mtx);
196 if (err)
197 return err;
198
199 ieee80211_bss_info_change_notify(sdata, changed);
200
201 ifocb->joined = true;
202
203 set_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags);
204 ieee80211_queue_work(&local->hw, &sdata->work);
205
206 netif_carrier_on(sdata->dev);
207 return 0;
208}
209
210int ieee80211_ocb_leave(struct ieee80211_sub_if_data *sdata)
211{
212 struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
213 struct ieee80211_local *local = sdata->local;
214 struct sta_info *sta;
215
216 ifocb->joined = false;
217 sta_info_flush(sdata);
218
219 spin_lock_bh(&ifocb->incomplete_lock);
220 while (!list_empty(&ifocb->incomplete_stations)) {
221 sta = list_first_entry(&ifocb->incomplete_stations,
222 struct sta_info, list);
223 list_del(&sta->list);
224 spin_unlock_bh(&ifocb->incomplete_lock);
225
226 sta_info_free(local, sta);
227 spin_lock_bh(&ifocb->incomplete_lock);
228 }
229 spin_unlock_bh(&ifocb->incomplete_lock);
230
231 netif_carrier_off(sdata->dev);
232 clear_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
233 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_OCB);
234
235 mutex_lock(&sdata->local->mtx);
236 ieee80211_vif_release_channel(sdata);
237 mutex_unlock(&sdata->local->mtx);
238
239 skb_queue_purge(&sdata->skb_queue);
240
241 del_timer_sync(&sdata->u.ocb.housekeeping_timer);
242 /* If the timer fired while we waited for it, it will have
243 * requeued the work. Now the work will be running again
244 * but will not rearm the timer again because it checks
245 * whether we are connected to the network or not -- at this
246 * point we shouldn't be anymore.
247 */
248
249 return 0;
250}
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 2baa7ed8789d..c2b91bf47f6d 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -191,7 +191,7 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
191 * (1) if any success probabilitiy >= 95%, out of those rates 191 * (1) if any success probabilitiy >= 95%, out of those rates
192 * choose the maximum throughput rate as max_prob_rate 192 * choose the maximum throughput rate as max_prob_rate
193 * (2) if all success probabilities < 95%, the rate with 193 * (2) if all success probabilities < 95%, the rate with
194 * highest success probability is choosen as max_prob_rate */ 194 * highest success probability is chosen as max_prob_rate */
195 if (mrs->probability >= MINSTREL_FRAC(95, 100)) { 195 if (mrs->probability >= MINSTREL_FRAC(95, 100)) {
196 if (mrs->cur_tp >= mi->r[tmp_prob_rate].stats.cur_tp) 196 if (mrs->cur_tp >= mi->r[tmp_prob_rate].stats.cur_tp)
197 tmp_prob_rate = i; 197 tmp_prob_rate = i;
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index df90ce2db00c..c50fd94d2aef 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -10,6 +10,7 @@
10#include <linux/skbuff.h> 10#include <linux/skbuff.h>
11#include <linux/debugfs.h> 11#include <linux/debugfs.h>
12#include <linux/random.h> 12#include <linux/random.h>
13#include <linux/moduleparam.h>
13#include <linux/ieee80211.h> 14#include <linux/ieee80211.h>
14#include <net/mac80211.h> 15#include <net/mac80211.h>
15#include "rate.h" 16#include "rate.h"
@@ -34,12 +35,17 @@
34/* Transmit duration for the raw data part of an average sized packet */ 35/* Transmit duration for the raw data part of an average sized packet */
35#define MCS_DURATION(streams, sgi, bps) MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps))) 36#define MCS_DURATION(streams, sgi, bps) MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps)))
36 37
38#define BW_20 0
39#define BW_40 1
40#define BW_80 2
41
37/* 42/*
38 * Define group sort order: HT40 -> SGI -> #streams 43 * Define group sort order: HT40 -> SGI -> #streams
39 */ 44 */
40#define GROUP_IDX(_streams, _sgi, _ht40) \ 45#define GROUP_IDX(_streams, _sgi, _ht40) \
46 MINSTREL_HT_GROUP_0 + \
41 MINSTREL_MAX_STREAMS * 2 * _ht40 + \ 47 MINSTREL_MAX_STREAMS * 2 * _ht40 + \
42 MINSTREL_MAX_STREAMS * _sgi + \ 48 MINSTREL_MAX_STREAMS * _sgi + \
43 _streams - 1 49 _streams - 1
44 50
45/* MCS rate information for an MCS group */ 51/* MCS rate information for an MCS group */
@@ -47,6 +53,7 @@
47 [GROUP_IDX(_streams, _sgi, _ht40)] = { \ 53 [GROUP_IDX(_streams, _sgi, _ht40)] = { \
48 .streams = _streams, \ 54 .streams = _streams, \
49 .flags = \ 55 .flags = \
56 IEEE80211_TX_RC_MCS | \
50 (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ 57 (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \
51 (_ht40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \ 58 (_ht40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \
52 .duration = { \ 59 .duration = { \
@@ -61,6 +68,47 @@
61 } \ 68 } \
62} 69}
63 70
71#define VHT_GROUP_IDX(_streams, _sgi, _bw) \
72 (MINSTREL_VHT_GROUP_0 + \
73 MINSTREL_MAX_STREAMS * 2 * (_bw) + \
74 MINSTREL_MAX_STREAMS * (_sgi) + \
75 (_streams) - 1)
76
77#define BW2VBPS(_bw, r3, r2, r1) \
78 (_bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1)
79
80#define VHT_GROUP(_streams, _sgi, _bw) \
81 [VHT_GROUP_IDX(_streams, _sgi, _bw)] = { \
82 .streams = _streams, \
83 .flags = \
84 IEEE80211_TX_RC_VHT_MCS | \
85 (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \
86 (_bw == BW_80 ? IEEE80211_TX_RC_80_MHZ_WIDTH : \
87 _bw == BW_40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \
88 .duration = { \
89 MCS_DURATION(_streams, _sgi, \
90 BW2VBPS(_bw, 117, 54, 26)), \
91 MCS_DURATION(_streams, _sgi, \
92 BW2VBPS(_bw, 234, 108, 52)), \
93 MCS_DURATION(_streams, _sgi, \
94 BW2VBPS(_bw, 351, 162, 78)), \
95 MCS_DURATION(_streams, _sgi, \
96 BW2VBPS(_bw, 468, 216, 104)), \
97 MCS_DURATION(_streams, _sgi, \
98 BW2VBPS(_bw, 702, 324, 156)), \
99 MCS_DURATION(_streams, _sgi, \
100 BW2VBPS(_bw, 936, 432, 208)), \
101 MCS_DURATION(_streams, _sgi, \
102 BW2VBPS(_bw, 1053, 486, 234)), \
103 MCS_DURATION(_streams, _sgi, \
104 BW2VBPS(_bw, 1170, 540, 260)), \
105 MCS_DURATION(_streams, _sgi, \
106 BW2VBPS(_bw, 1404, 648, 312)), \
107 MCS_DURATION(_streams, _sgi, \
108 BW2VBPS(_bw, 1560, 720, 346)) \
109 } \
110}
111
64#define CCK_DURATION(_bitrate, _short, _len) \ 112#define CCK_DURATION(_bitrate, _short, _len) \
65 (1000 * (10 /* SIFS */ + \ 113 (1000 * (10 /* SIFS */ + \
66 (_short ? 72 + 24 : 144 + 48) + \ 114 (_short ? 72 + 24 : 144 + 48) + \
@@ -76,53 +124,96 @@
76 CCK_ACK_DURATION(55, _short), \ 124 CCK_ACK_DURATION(55, _short), \
77 CCK_ACK_DURATION(110, _short) 125 CCK_ACK_DURATION(110, _short)
78 126
79#define CCK_GROUP \ 127#define CCK_GROUP \
80 [MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS] = { \ 128 [MINSTREL_CCK_GROUP] = { \
81 .streams = 0, \ 129 .streams = 0, \
82 .duration = { \ 130 .flags = 0, \
83 CCK_DURATION_LIST(false), \ 131 .duration = { \
84 CCK_DURATION_LIST(true) \ 132 CCK_DURATION_LIST(false), \
85 } \ 133 CCK_DURATION_LIST(true) \
134 } \
86 } 135 }
87 136
137#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
138static bool minstrel_vht_only = true;
139module_param(minstrel_vht_only, bool, 0644);
140MODULE_PARM_DESC(minstrel_vht_only,
141 "Use only VHT rates when VHT is supported by sta.");
142#endif
143
88/* 144/*
89 * To enable sufficiently targeted rate sampling, MCS rates are divided into 145 * To enable sufficiently targeted rate sampling, MCS rates are divided into
90 * groups, based on the number of streams and flags (HT40, SGI) that they 146 * groups, based on the number of streams and flags (HT40, SGI) that they
91 * use. 147 * use.
92 * 148 *
93 * Sortorder has to be fixed for GROUP_IDX macro to be applicable: 149 * Sortorder has to be fixed for GROUP_IDX macro to be applicable:
94 * HT40 -> SGI -> #streams 150 * BW -> SGI -> #streams
95 */ 151 */
96const struct mcs_group minstrel_mcs_groups[] = { 152const struct mcs_group minstrel_mcs_groups[] = {
97 MCS_GROUP(1, 0, 0), 153 MCS_GROUP(1, 0, BW_20),
98 MCS_GROUP(2, 0, 0), 154 MCS_GROUP(2, 0, BW_20),
99#if MINSTREL_MAX_STREAMS >= 3 155#if MINSTREL_MAX_STREAMS >= 3
100 MCS_GROUP(3, 0, 0), 156 MCS_GROUP(3, 0, BW_20),
101#endif 157#endif
102 158
103 MCS_GROUP(1, 1, 0), 159 MCS_GROUP(1, 1, BW_20),
104 MCS_GROUP(2, 1, 0), 160 MCS_GROUP(2, 1, BW_20),
105#if MINSTREL_MAX_STREAMS >= 3 161#if MINSTREL_MAX_STREAMS >= 3
106 MCS_GROUP(3, 1, 0), 162 MCS_GROUP(3, 1, BW_20),
107#endif 163#endif
108 164
109 MCS_GROUP(1, 0, 1), 165 MCS_GROUP(1, 0, BW_40),
110 MCS_GROUP(2, 0, 1), 166 MCS_GROUP(2, 0, BW_40),
111#if MINSTREL_MAX_STREAMS >= 3 167#if MINSTREL_MAX_STREAMS >= 3
112 MCS_GROUP(3, 0, 1), 168 MCS_GROUP(3, 0, BW_40),
113#endif 169#endif
114 170
115 MCS_GROUP(1, 1, 1), 171 MCS_GROUP(1, 1, BW_40),
116 MCS_GROUP(2, 1, 1), 172 MCS_GROUP(2, 1, BW_40),
117#if MINSTREL_MAX_STREAMS >= 3 173#if MINSTREL_MAX_STREAMS >= 3
118 MCS_GROUP(3, 1, 1), 174 MCS_GROUP(3, 1, BW_40),
119#endif 175#endif
120 176
121 /* must be last */ 177 CCK_GROUP,
122 CCK_GROUP
123};
124 178
125#define MINSTREL_CCK_GROUP (ARRAY_SIZE(minstrel_mcs_groups) - 1) 179#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
180 VHT_GROUP(1, 0, BW_20),
181 VHT_GROUP(2, 0, BW_20),
182#if MINSTREL_MAX_STREAMS >= 3
183 VHT_GROUP(3, 0, BW_20),
184#endif
185
186 VHT_GROUP(1, 1, BW_20),
187 VHT_GROUP(2, 1, BW_20),
188#if MINSTREL_MAX_STREAMS >= 3
189 VHT_GROUP(3, 1, BW_20),
190#endif
191
192 VHT_GROUP(1, 0, BW_40),
193 VHT_GROUP(2, 0, BW_40),
194#if MINSTREL_MAX_STREAMS >= 3
195 VHT_GROUP(3, 0, BW_40),
196#endif
197
198 VHT_GROUP(1, 1, BW_40),
199 VHT_GROUP(2, 1, BW_40),
200#if MINSTREL_MAX_STREAMS >= 3
201 VHT_GROUP(3, 1, BW_40),
202#endif
203
204 VHT_GROUP(1, 0, BW_80),
205 VHT_GROUP(2, 0, BW_80),
206#if MINSTREL_MAX_STREAMS >= 3
207 VHT_GROUP(3, 0, BW_80),
208#endif
209
210 VHT_GROUP(1, 1, BW_80),
211 VHT_GROUP(2, 1, BW_80),
212#if MINSTREL_MAX_STREAMS >= 3
213 VHT_GROUP(3, 1, BW_80),
214#endif
215#endif
216};
126 217
127static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly; 218static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly;
128 219
@@ -130,16 +221,64 @@ static void
130minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi); 221minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi);
131 222
132/* 223/*
224 * Some VHT MCSes are invalid (when Ndbps / Nes is not an integer)
225 * e.g for MCS9@20MHzx1Nss: Ndbps=8x52*(5/6) Nes=1
226 *
227 * Returns the valid mcs map for struct minstrel_mcs_group_data.supported
228 */
229static u16
230minstrel_get_valid_vht_rates(int bw, int nss, __le16 mcs_map)
231{
232 u16 mask = 0;
233
234 if (bw == BW_20) {
235 if (nss != 3 && nss != 6)
236 mask = BIT(9);
237 } else if (bw == BW_80) {
238 if (nss == 3 || nss == 7)
239 mask = BIT(6);
240 else if (nss == 6)
241 mask = BIT(9);
242 } else {
243 WARN_ON(bw != BW_40);
244 }
245
246 switch ((le16_to_cpu(mcs_map) >> (2 * (nss - 1))) & 3) {
247 case IEEE80211_VHT_MCS_SUPPORT_0_7:
248 mask |= 0x300;
249 break;
250 case IEEE80211_VHT_MCS_SUPPORT_0_8:
251 mask |= 0x200;
252 break;
253 case IEEE80211_VHT_MCS_SUPPORT_0_9:
254 break;
255 default:
256 mask = 0x3ff;
257 }
258
259 return 0x3ff & ~mask;
260}
261
262/*
133 * Look up an MCS group index based on mac80211 rate information 263 * Look up an MCS group index based on mac80211 rate information
134 */ 264 */
135static int 265static int
136minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate) 266minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate)
137{ 267{
138 return GROUP_IDX((rate->idx / MCS_GROUP_RATES) + 1, 268 return GROUP_IDX((rate->idx / 8) + 1,
139 !!(rate->flags & IEEE80211_TX_RC_SHORT_GI), 269 !!(rate->flags & IEEE80211_TX_RC_SHORT_GI),
140 !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)); 270 !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH));
141} 271}
142 272
273static int
274minstrel_vht_get_group_idx(struct ieee80211_tx_rate *rate)
275{
276 return VHT_GROUP_IDX(ieee80211_rate_get_vht_nss(rate),
277 !!(rate->flags & IEEE80211_TX_RC_SHORT_GI),
278 !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) +
279 2*!!(rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH));
280}
281
143static struct minstrel_rate_stats * 282static struct minstrel_rate_stats *
144minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, 283minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
145 struct ieee80211_tx_rate *rate) 284 struct ieee80211_tx_rate *rate)
@@ -149,6 +288,9 @@ minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
149 if (rate->flags & IEEE80211_TX_RC_MCS) { 288 if (rate->flags & IEEE80211_TX_RC_MCS) {
150 group = minstrel_ht_get_group_idx(rate); 289 group = minstrel_ht_get_group_idx(rate);
151 idx = rate->idx % 8; 290 idx = rate->idx % 8;
291 } else if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
292 group = minstrel_vht_get_group_idx(rate);
293 idx = ieee80211_rate_get_vht_mcs(rate);
152 } else { 294 } else {
153 group = MINSTREL_CCK_GROUP; 295 group = MINSTREL_CCK_GROUP;
154 296
@@ -240,8 +382,8 @@ minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate)
240 * MCS groups, CCK rates do not provide aggregation and are therefore at last. 382 * MCS groups, CCK rates do not provide aggregation and are therefore at last.
241 */ 383 */
242static void 384static void
243minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u8 index, 385minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u16 index,
244 u8 *tp_list) 386 u16 *tp_list)
245{ 387{
246 int cur_group, cur_idx, cur_thr, cur_prob; 388 int cur_group, cur_idx, cur_thr, cur_prob;
247 int tmp_group, tmp_idx, tmp_thr, tmp_prob; 389 int tmp_group, tmp_idx, tmp_thr, tmp_prob;
@@ -278,7 +420,7 @@ minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u8 index,
278 * Find and set the topmost probability rate per sta and per group 420 * Find and set the topmost probability rate per sta and per group
279 */ 421 */
280static void 422static void
281minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u8 index) 423minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 index)
282{ 424{
283 struct minstrel_mcs_group_data *mg; 425 struct minstrel_mcs_group_data *mg;
284 struct minstrel_rate_stats *mr; 426 struct minstrel_rate_stats *mr;
@@ -321,8 +463,8 @@ minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u8 index)
321 */ 463 */
322static void 464static void
323minstrel_ht_assign_best_tp_rates(struct minstrel_ht_sta *mi, 465minstrel_ht_assign_best_tp_rates(struct minstrel_ht_sta *mi,
324 u8 tmp_mcs_tp_rate[MAX_THR_RATES], 466 u16 tmp_mcs_tp_rate[MAX_THR_RATES],
325 u8 tmp_cck_tp_rate[MAX_THR_RATES]) 467 u16 tmp_cck_tp_rate[MAX_THR_RATES])
326{ 468{
327 unsigned int tmp_group, tmp_idx, tmp_cck_tp, tmp_mcs_tp; 469 unsigned int tmp_group, tmp_idx, tmp_cck_tp, tmp_mcs_tp;
328 int i; 470 int i;
@@ -386,8 +528,8 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
386 struct minstrel_mcs_group_data *mg; 528 struct minstrel_mcs_group_data *mg;
387 struct minstrel_rate_stats *mr; 529 struct minstrel_rate_stats *mr;
388 int group, i, j; 530 int group, i, j;
389 u8 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES]; 531 u16 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES];
390 u8 tmp_cck_tp_rate[MAX_THR_RATES], index; 532 u16 tmp_cck_tp_rate[MAX_THR_RATES], index;
391 533
392 if (mi->ampdu_packets > 0) { 534 if (mi->ampdu_packets > 0) {
393 mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, 535 mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len,
@@ -485,7 +627,8 @@ minstrel_ht_txstat_valid(struct minstrel_priv *mp, struct ieee80211_tx_rate *rat
485 if (!rate->count) 627 if (!rate->count)
486 return false; 628 return false;
487 629
488 if (rate->flags & IEEE80211_TX_RC_MCS) 630 if (rate->flags & IEEE80211_TX_RC_MCS ||
631 rate->flags & IEEE80211_TX_RC_VHT_MCS)
489 return true; 632 return true;
490 633
491 return rate->idx == mp->cck_rates[0] || 634 return rate->idx == mp->cck_rates[0] ||
@@ -517,7 +660,7 @@ minstrel_next_sample_idx(struct minstrel_ht_sta *mi)
517} 660}
518 661
519static void 662static void
520minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u8 *idx, bool primary) 663minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary)
521{ 664{
522 int group, orig_group; 665 int group, orig_group;
523 666
@@ -714,7 +857,7 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
714 const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; 857 const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
715 struct minstrel_rate_stats *mr; 858 struct minstrel_rate_stats *mr;
716 u8 idx; 859 u8 idx;
717 u16 flags; 860 u16 flags = group->flags;
718 861
719 mr = minstrel_get_ratestats(mi, index); 862 mr = minstrel_get_ratestats(mi, index);
720 if (!mr->retry_updated) 863 if (!mr->retry_updated)
@@ -730,13 +873,13 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
730 ratetbl->rate[offset].count_rts = mr->retry_count_rtscts; 873 ratetbl->rate[offset].count_rts = mr->retry_count_rtscts;
731 } 874 }
732 875
733 if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { 876 if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP)
734 idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; 877 idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)];
735 flags = 0; 878 else if (flags & IEEE80211_TX_RC_VHT_MCS)
736 } else { 879 idx = ((group->streams - 1) << 4) |
880 ((index % MCS_GROUP_RATES) & 0xF);
881 else
737 idx = index % MCS_GROUP_RATES + (group->streams - 1) * 8; 882 idx = index % MCS_GROUP_RATES + (group->streams - 1) * 8;
738 flags = IEEE80211_TX_RC_MCS | group->flags;
739 }
740 883
741 if (offset > 0) { 884 if (offset > 0) {
742 ratetbl->rate[offset].count = ratetbl->rate[offset].count_rts; 885 ratetbl->rate[offset].count = ratetbl->rate[offset].count_rts;
@@ -916,13 +1059,15 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
916 if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { 1059 if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) {
917 int idx = sample_idx % ARRAY_SIZE(mp->cck_rates); 1060 int idx = sample_idx % ARRAY_SIZE(mp->cck_rates);
918 rate->idx = mp->cck_rates[idx]; 1061 rate->idx = mp->cck_rates[idx];
919 rate->flags = 0; 1062 } else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) {
920 return; 1063 ieee80211_rate_set_vht(rate, sample_idx % MCS_GROUP_RATES,
1064 sample_group->streams);
1065 } else {
1066 rate->idx = sample_idx % MCS_GROUP_RATES +
1067 (sample_group->streams - 1) * 8;
921 } 1068 }
922 1069
923 rate->idx = sample_idx % MCS_GROUP_RATES + 1070 rate->flags = sample_group->flags;
924 (sample_group->streams - 1) * 8;
925 rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags;
926} 1071}
927 1072
928static void 1073static void
@@ -962,6 +1107,8 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
962 struct minstrel_ht_sta *mi = &msp->ht; 1107 struct minstrel_ht_sta *mi = &msp->ht;
963 struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; 1108 struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs;
964 u16 sta_cap = sta->ht_cap.cap; 1109 u16 sta_cap = sta->ht_cap.cap;
1110 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
1111 int use_vht;
965 int n_supported = 0; 1112 int n_supported = 0;
966 int ack_dur; 1113 int ack_dur;
967 int stbc; 1114 int stbc;
@@ -971,8 +1118,14 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
971 if (!sta->ht_cap.ht_supported) 1118 if (!sta->ht_cap.ht_supported)
972 goto use_legacy; 1119 goto use_legacy;
973 1120
974 BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != 1121 BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != MINSTREL_GROUPS_NB);
975 MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS + 1); 1122
1123#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
1124 if (vht_cap->vht_supported)
1125 use_vht = vht_cap->vht_mcs.tx_mcs_map != cpu_to_le16(~0);
1126 else
1127#endif
1128 use_vht = 0;
976 1129
977 msp->is_ht = true; 1130 msp->is_ht = true;
978 memset(mi, 0, sizeof(*mi)); 1131 memset(mi, 0, sizeof(*mi));
@@ -997,22 +1150,28 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
997 } 1150 }
998 mi->sample_tries = 4; 1151 mi->sample_tries = 4;
999 1152
1000 stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >> 1153 /* TODO tx_flags for vht - ATM the RC API is not fine-grained enough */
1001 IEEE80211_HT_CAP_RX_STBC_SHIFT; 1154 if (!use_vht) {
1002 mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; 1155 stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >>
1156 IEEE80211_HT_CAP_RX_STBC_SHIFT;
1157 mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT;
1003 1158
1004 if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING) 1159 if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING)
1005 mi->tx_flags |= IEEE80211_TX_CTL_LDPC; 1160 mi->tx_flags |= IEEE80211_TX_CTL_LDPC;
1161 }
1006 1162
1007 for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { 1163 for (i = 0; i < ARRAY_SIZE(mi->groups); i++) {
1164 u32 gflags = minstrel_mcs_groups[i].flags;
1165 int bw, nss;
1166
1008 mi->groups[i].supported = 0; 1167 mi->groups[i].supported = 0;
1009 if (i == MINSTREL_CCK_GROUP) { 1168 if (i == MINSTREL_CCK_GROUP) {
1010 minstrel_ht_update_cck(mp, mi, sband, sta); 1169 minstrel_ht_update_cck(mp, mi, sband, sta);
1011 continue; 1170 continue;
1012 } 1171 }
1013 1172
1014 if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_SHORT_GI) { 1173 if (gflags & IEEE80211_TX_RC_SHORT_GI) {
1015 if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) { 1174 if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
1016 if (!(sta_cap & IEEE80211_HT_CAP_SGI_40)) 1175 if (!(sta_cap & IEEE80211_HT_CAP_SGI_40))
1017 continue; 1176 continue;
1018 } else { 1177 } else {
@@ -1021,17 +1180,51 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
1021 } 1180 }
1022 } 1181 }
1023 1182
1024 if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH && 1183 if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH &&
1025 sta->bandwidth < IEEE80211_STA_RX_BW_40) 1184 sta->bandwidth < IEEE80211_STA_RX_BW_40)
1026 continue; 1185 continue;
1027 1186
1187 nss = minstrel_mcs_groups[i].streams;
1188
1028 /* Mark MCS > 7 as unsupported if STA is in static SMPS mode */ 1189 /* Mark MCS > 7 as unsupported if STA is in static SMPS mode */
1029 if (sta->smps_mode == IEEE80211_SMPS_STATIC && 1190 if (sta->smps_mode == IEEE80211_SMPS_STATIC && nss > 1)
1030 minstrel_mcs_groups[i].streams > 1) 1191 continue;
1192
1193 /* HT rate */
1194 if (gflags & IEEE80211_TX_RC_MCS) {
1195#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
1196 if (use_vht && minstrel_vht_only)
1197 continue;
1198#endif
1199 mi->groups[i].supported = mcs->rx_mask[nss - 1];
1200 if (mi->groups[i].supported)
1201 n_supported++;
1031 continue; 1202 continue;
1203 }
1204
1205 /* VHT rate */
1206 if (!vht_cap->vht_supported ||
1207 WARN_ON(!(gflags & IEEE80211_TX_RC_VHT_MCS)) ||
1208 WARN_ON(gflags & IEEE80211_TX_RC_160_MHZ_WIDTH))
1209 continue;
1210
1211 if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH) {
1212 if (sta->bandwidth < IEEE80211_STA_RX_BW_80 ||
1213 ((gflags & IEEE80211_TX_RC_SHORT_GI) &&
1214 !(vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_80))) {
1215 continue;
1216 }
1217 }
1218
1219 if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1220 bw = BW_40;
1221 else if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH)
1222 bw = BW_80;
1223 else
1224 bw = BW_20;
1032 1225
1033 mi->groups[i].supported = 1226 mi->groups[i].supported = minstrel_get_valid_vht_rates(bw, nss,
1034 mcs->rx_mask[minstrel_mcs_groups[i].streams - 1]; 1227 vht_cap->vht_mcs.tx_mcs_map);
1035 1228
1036 if (mi->groups[i].supported) 1229 if (mi->groups[i].supported)
1037 n_supported++; 1230 n_supported++;
diff --git a/net/mac80211/rc80211_minstrel_ht.h b/net/mac80211/rc80211_minstrel_ht.h
index 01570e0e014b..f2217d6aa0c2 100644
--- a/net/mac80211/rc80211_minstrel_ht.h
+++ b/net/mac80211/rc80211_minstrel_ht.h
@@ -13,10 +13,32 @@
13 * The number of streams can be changed to 2 to reduce code 13 * The number of streams can be changed to 2 to reduce code
14 * size and memory footprint. 14 * size and memory footprint.
15 */ 15 */
16#define MINSTREL_MAX_STREAMS 3 16#define MINSTREL_MAX_STREAMS 3
17#define MINSTREL_STREAM_GROUPS 4 17#define MINSTREL_HT_STREAM_GROUPS 4 /* BW(=2) * SGI(=2) */
18#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
19#define MINSTREL_VHT_STREAM_GROUPS 6 /* BW(=3) * SGI(=2) */
20#else
21#define MINSTREL_VHT_STREAM_GROUPS 0
22#endif
18 23
19#define MCS_GROUP_RATES 8 24#define MINSTREL_HT_GROUPS_NB (MINSTREL_MAX_STREAMS * \
25 MINSTREL_HT_STREAM_GROUPS)
26#define MINSTREL_VHT_GROUPS_NB (MINSTREL_MAX_STREAMS * \
27 MINSTREL_VHT_STREAM_GROUPS)
28#define MINSTREL_CCK_GROUPS_NB 1
29#define MINSTREL_GROUPS_NB (MINSTREL_HT_GROUPS_NB + \
30 MINSTREL_VHT_GROUPS_NB + \
31 MINSTREL_CCK_GROUPS_NB)
32
33#define MINSTREL_HT_GROUP_0 0
34#define MINSTREL_CCK_GROUP (MINSTREL_HT_GROUP_0 + MINSTREL_HT_GROUPS_NB)
35#define MINSTREL_VHT_GROUP_0 (MINSTREL_CCK_GROUP + 1)
36
37#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
38#define MCS_GROUP_RATES 10
39#else
40#define MCS_GROUP_RATES 8
41#endif
20 42
21struct mcs_group { 43struct mcs_group {
22 u32 flags; 44 u32 flags;
@@ -31,11 +53,11 @@ struct minstrel_mcs_group_data {
31 u8 column; 53 u8 column;
32 54
33 /* bitfield of supported MCS rates of this group */ 55 /* bitfield of supported MCS rates of this group */
34 u8 supported; 56 u16 supported;
35 57
36 /* sorted rate set within a MCS group*/ 58 /* sorted rate set within a MCS group*/
37 u8 max_group_tp_rate[MAX_THR_RATES]; 59 u16 max_group_tp_rate[MAX_THR_RATES];
38 u8 max_group_prob_rate; 60 u16 max_group_prob_rate;
39 61
40 /* MCS rate statistics */ 62 /* MCS rate statistics */
41 struct minstrel_rate_stats rates[MCS_GROUP_RATES]; 63 struct minstrel_rate_stats rates[MCS_GROUP_RATES];
@@ -52,8 +74,8 @@ struct minstrel_ht_sta {
52 unsigned int avg_ampdu_len; 74 unsigned int avg_ampdu_len;
53 75
54 /* overall sorted rate set */ 76 /* overall sorted rate set */
55 u8 max_tp_rate[MAX_THR_RATES]; 77 u16 max_tp_rate[MAX_THR_RATES];
56 u8 max_prob_rate; 78 u16 max_prob_rate;
57 79
58 /* time of last status update */ 80 /* time of last status update */
59 unsigned long stats_update; 81 unsigned long stats_update;
@@ -80,7 +102,7 @@ struct minstrel_ht_sta {
80 u8 cck_supported_short; 102 u8 cck_supported_short;
81 103
82 /* MCS rate group info and statistics */ 104 /* MCS rate group info and statistics */
83 struct minstrel_mcs_group_data groups[MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS + 1]; 105 struct minstrel_mcs_group_data groups[MINSTREL_GROUPS_NB];
84}; 106};
85 107
86struct minstrel_ht_sta_priv { 108struct minstrel_ht_sta_priv {
diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c b/net/mac80211/rc80211_minstrel_ht_debugfs.c
index d537bec93754..20c676b8e5b6 100644
--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
@@ -18,19 +18,23 @@
18static char * 18static char *
19minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) 19minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
20{ 20{
21 unsigned int max_mcs = MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS;
22 const struct mcs_group *mg; 21 const struct mcs_group *mg;
23 unsigned int j, tp, prob, eprob; 22 unsigned int j, tp, prob, eprob;
24 char htmode = '2'; 23 char htmode = '2';
25 char gimode = 'L'; 24 char gimode = 'L';
25 u32 gflags;
26 26
27 if (!mi->groups[i].supported) 27 if (!mi->groups[i].supported)
28 return p; 28 return p;
29 29
30 mg = &minstrel_mcs_groups[i]; 30 mg = &minstrel_mcs_groups[i];
31 if (mg->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 31 gflags = mg->flags;
32
33 if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH)
32 htmode = '4'; 34 htmode = '4';
33 if (mg->flags & IEEE80211_TX_RC_SHORT_GI) 35 else if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH)
36 htmode = '8';
37 if (gflags & IEEE80211_TX_RC_SHORT_GI)
34 gimode = 'S'; 38 gimode = 'S';
35 39
36 for (j = 0; j < MCS_GROUP_RATES; j++) { 40 for (j = 0; j < MCS_GROUP_RATES; j++) {
@@ -41,10 +45,12 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
41 if (!(mi->groups[i].supported & BIT(j))) 45 if (!(mi->groups[i].supported & BIT(j)))
42 continue; 46 continue;
43 47
44 if (i == max_mcs) 48 if (gflags & IEEE80211_TX_RC_MCS)
45 p += sprintf(p, "CCK/%cP ", j < 4 ? 'L' : 'S'); 49 p += sprintf(p, " HT%c0/%cGI ", htmode, gimode);
50 else if (gflags & IEEE80211_TX_RC_VHT_MCS)
51 p += sprintf(p, "VHT%c0/%cGI ", htmode, gimode);
46 else 52 else
47 p += sprintf(p, "HT%c0/%cGI ", htmode, gimode); 53 p += sprintf(p, " CCK/%cP ", j < 4 ? 'L' : 'S');
48 54
49 *(p++) = (idx == mi->max_tp_rate[0]) ? 'A' : ' '; 55 *(p++) = (idx == mi->max_tp_rate[0]) ? 'A' : ' ';
50 *(p++) = (idx == mi->max_tp_rate[1]) ? 'B' : ' '; 56 *(p++) = (idx == mi->max_tp_rate[1]) ? 'B' : ' ';
@@ -52,11 +58,14 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
52 *(p++) = (idx == mi->max_tp_rate[3]) ? 'D' : ' '; 58 *(p++) = (idx == mi->max_tp_rate[3]) ? 'D' : ' ';
53 *(p++) = (idx == mi->max_prob_rate) ? 'P' : ' '; 59 *(p++) = (idx == mi->max_prob_rate) ? 'P' : ' ';
54 60
55 if (i == max_mcs) { 61 if (gflags & IEEE80211_TX_RC_MCS) {
56 int r = bitrates[j % 4]; 62 p += sprintf(p, " MCS%-2u ", (mg->streams - 1) * 8 + j);
57 p += sprintf(p, " %2u.%1uM", r / 10, r % 10); 63 } else if (gflags & IEEE80211_TX_RC_VHT_MCS) {
64 p += sprintf(p, " MCS%-1u/%1u", j, mg->streams);
58 } else { 65 } else {
59 p += sprintf(p, " MCS%-2u", (mg->streams - 1) * 8 + j); 66 int r = bitrates[j % 4];
67
68 p += sprintf(p, " %2u.%1uM ", r / 10, r % 10);
60 } 69 }
61 70
62 tp = mr->cur_tp / 10; 71 tp = mr->cur_tp / 10;
@@ -85,7 +94,6 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file)
85 struct minstrel_ht_sta *mi = &msp->ht; 94 struct minstrel_ht_sta *mi = &msp->ht;
86 struct minstrel_debugfs_info *ms; 95 struct minstrel_debugfs_info *ms;
87 unsigned int i; 96 unsigned int i;
88 unsigned int max_mcs = MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS;
89 char *p; 97 char *p;
90 int ret; 98 int ret;
91 99
@@ -96,18 +104,19 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file)
96 return ret; 104 return ret;
97 } 105 }
98 106
99 ms = kmalloc(8192, GFP_KERNEL); 107 ms = kmalloc(32768, GFP_KERNEL);
100 if (!ms) 108 if (!ms)
101 return -ENOMEM; 109 return -ENOMEM;
102 110
103 file->private_data = ms; 111 file->private_data = ms;
104 p = ms->buf; 112 p = ms->buf;
105 p += sprintf(p, "type rate tpt eprob *prob " 113 p += sprintf(p, " type rate tpt eprob *prob "
106 "ret *ok(*cum) ok( cum)\n"); 114 "ret *ok(*cum) ok( cum)\n");
107 115
108 116 p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p);
109 p = minstrel_ht_stats_dump(mi, max_mcs, p); 117 for (i = 0; i < MINSTREL_CCK_GROUP; i++)
110 for (i = 0; i < max_mcs; i++) 118 p = minstrel_ht_stats_dump(mi, i, p);
119 for (i++; i < ARRAY_SIZE(mi->groups); i++)
111 p = minstrel_ht_stats_dump(mi, i, p); 120 p = minstrel_ht_stats_dump(mi, i, p);
112 121
113 p += sprintf(p, "\nTotal packet count:: ideal %d " 122 p += sprintf(p, "\nTotal packet count:: ideal %d "
@@ -119,7 +128,7 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file)
119 MINSTREL_TRUNC(mi->avg_ampdu_len * 10) % 10); 128 MINSTREL_TRUNC(mi->avg_ampdu_len * 10) % 10);
120 ms->len = p - ms->buf; 129 ms->len = p - ms->buf;
121 130
122 WARN_ON(ms->len + sizeof(*ms) > 8192); 131 WARN_ON(ms->len + sizeof(*ms) > 32768);
123 132
124 return nonseekable_open(inode, file); 133 return nonseekable_open(inode, file);
125} 134}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b04ca4049c95..bc63aa0c5401 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1032,6 +1032,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
1032 ieee80211_is_pspoll(hdr->frame_control)) && 1032 ieee80211_is_pspoll(hdr->frame_control)) &&
1033 rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && 1033 rx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
1034 rx->sdata->vif.type != NL80211_IFTYPE_WDS && 1034 rx->sdata->vif.type != NL80211_IFTYPE_WDS &&
1035 rx->sdata->vif.type != NL80211_IFTYPE_OCB &&
1035 (!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_ASSOC)))) { 1036 (!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_ASSOC)))) {
1036 /* 1037 /*
1037 * accept port control frames from the AP even when it's not 1038 * accept port control frames from the AP even when it's not
@@ -1272,6 +1273,12 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1272 sta->last_rx_rate_vht_nss = status->vht_nss; 1273 sta->last_rx_rate_vht_nss = status->vht_nss;
1273 } 1274 }
1274 } 1275 }
1276 } else if (rx->sdata->vif.type == NL80211_IFTYPE_OCB) {
1277 u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len,
1278 NL80211_IFTYPE_OCB);
1279 /* OCB uses wild-card BSSID */
1280 if (is_broadcast_ether_addr(bssid))
1281 sta->last_rx = jiffies;
1275 } else if (!is_multicast_ether_addr(hdr->addr1)) { 1282 } else if (!is_multicast_ether_addr(hdr->addr1)) {
1276 /* 1283 /*
1277 * Mesh beacons will update last_rx when if they are found to 1284 * Mesh beacons will update last_rx when if they are found to
@@ -2820,6 +2827,7 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
2820 2827
2821 if (!ieee80211_vif_is_mesh(&sdata->vif) && 2828 if (!ieee80211_vif_is_mesh(&sdata->vif) &&
2822 sdata->vif.type != NL80211_IFTYPE_ADHOC && 2829 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
2830 sdata->vif.type != NL80211_IFTYPE_OCB &&
2823 sdata->vif.type != NL80211_IFTYPE_STATION) 2831 sdata->vif.type != NL80211_IFTYPE_STATION)
2824 return RX_DROP_MONITOR; 2832 return RX_DROP_MONITOR;
2825 2833
@@ -3130,6 +3138,33 @@ static bool prepare_for_handlers(struct ieee80211_rx_data *rx,
3130 BIT(rate_idx)); 3138 BIT(rate_idx));
3131 } 3139 }
3132 break; 3140 break;
3141 case NL80211_IFTYPE_OCB:
3142 if (!bssid)
3143 return false;
3144 if (ieee80211_is_beacon(hdr->frame_control)) {
3145 return false;
3146 } else if (!is_broadcast_ether_addr(bssid)) {
3147 ocb_dbg(sdata, "BSSID mismatch in OCB mode!\n");
3148 return false;
3149 } else if (!multicast &&
3150 !ether_addr_equal(sdata->dev->dev_addr,
3151 hdr->addr1)) {
3152 /* if we are in promisc mode we also accept
3153 * packets not destined for us
3154 */
3155 if (!(sdata->dev->flags & IFF_PROMISC))
3156 return false;
3157 rx->flags &= ~IEEE80211_RX_RA_MATCH;
3158 } else if (!rx->sta) {
3159 int rate_idx;
3160 if (status->flag & RX_FLAG_HT)
3161 rate_idx = 0; /* TODO: HT rates */
3162 else
3163 rate_idx = status->rate_idx;
3164 ieee80211_ocb_rx_no_sta(sdata, bssid, hdr->addr2,
3165 BIT(rate_idx));
3166 }
3167 break;
3133 case NL80211_IFTYPE_MESH_POINT: 3168 case NL80211_IFTYPE_MESH_POINT:
3134 if (!multicast && 3169 if (!multicast &&
3135 !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { 3170 !ether_addr_equal(sdata->vif.addr, hdr->addr1)) {
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index de494df3bab8..adc25371b171 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -501,7 +501,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
501 /* make the station visible */ 501 /* make the station visible */
502 sta_info_hash_add(local, sta); 502 sta_info_hash_add(local, sta);
503 503
504 list_add_rcu(&sta->list, &local->sta_list); 504 list_add_tail_rcu(&sta->list, &local->sta_list);
505 505
506 /* notify driver */ 506 /* notify driver */
507 err = sta_info_insert_drv_state(local, sdata, sta); 507 err = sta_info_insert_drv_state(local, sdata, sta);
@@ -1531,7 +1531,7 @@ void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta)
1531 break; 1531 break;
1532 case 0: 1532 case 0:
1533 /* XXX: what is a good value? */ 1533 /* XXX: what is a good value? */
1534 n_frames = 8; 1534 n_frames = 128;
1535 break; 1535 break;
1536 } 1536 }
1537 1537
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 89290e33dafe..9612d89fad56 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -704,7 +704,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
704 704
705 if ((sta->sdata->vif.type == NL80211_IFTYPE_STATION) && 705 if ((sta->sdata->vif.type == NL80211_IFTYPE_STATION) &&
706 (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) 706 (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS))
707 ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data, acked); 707 ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data,
708 acked, info->status.tx_time);
708 709
709 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { 710 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
710 if (info->flags & IEEE80211_TX_STAT_ACK) { 711 if (info->flags & IEEE80211_TX_STAT_ACK) {
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c
index 4ea25dec0698..b4f368e2cb3b 100644
--- a/net/mac80211/tdls.c
+++ b/net/mac80211/tdls.c
@@ -562,8 +562,10 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
562 /* infer the initiator if we can, to support old userspace */ 562 /* infer the initiator if we can, to support old userspace */
563 switch (action_code) { 563 switch (action_code) {
564 case WLAN_TDLS_SETUP_REQUEST: 564 case WLAN_TDLS_SETUP_REQUEST:
565 if (sta) 565 if (sta) {
566 set_sta_flag(sta, WLAN_STA_TDLS_INITIATOR); 566 set_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
567 sta->sta.tdls_initiator = false;
568 }
567 /* fall-through */ 569 /* fall-through */
568 case WLAN_TDLS_SETUP_CONFIRM: 570 case WLAN_TDLS_SETUP_CONFIRM:
569 case WLAN_TDLS_DISCOVERY_REQUEST: 571 case WLAN_TDLS_DISCOVERY_REQUEST:
@@ -575,8 +577,10 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
575 * Make the last packet sent take effect for the initiator 577 * Make the last packet sent take effect for the initiator
576 * value. 578 * value.
577 */ 579 */
578 if (sta) 580 if (sta) {
579 clear_sta_flag(sta, WLAN_STA_TDLS_INITIATOR); 581 clear_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
582 sta->sta.tdls_initiator = true;
583 }
580 /* fall-through */ 584 /* fall-through */
581 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: 585 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
582 initiator = false; 586 initiator = false;
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 38fae7ebe984..809a4983eb4a 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -987,29 +987,34 @@ TRACE_EVENT(drv_flush,
987 987
988TRACE_EVENT(drv_channel_switch, 988TRACE_EVENT(drv_channel_switch,
989 TP_PROTO(struct ieee80211_local *local, 989 TP_PROTO(struct ieee80211_local *local,
990 struct ieee80211_sub_if_data *sdata,
990 struct ieee80211_channel_switch *ch_switch), 991 struct ieee80211_channel_switch *ch_switch),
991 992
992 TP_ARGS(local, ch_switch), 993 TP_ARGS(local, sdata, ch_switch),
993 994
994 TP_STRUCT__entry( 995 TP_STRUCT__entry(
995 LOCAL_ENTRY 996 LOCAL_ENTRY
997 VIF_ENTRY
996 CHANDEF_ENTRY 998 CHANDEF_ENTRY
997 __field(u64, timestamp) 999 __field(u64, timestamp)
1000 __field(u32, device_timestamp)
998 __field(bool, block_tx) 1001 __field(bool, block_tx)
999 __field(u8, count) 1002 __field(u8, count)
1000 ), 1003 ),
1001 1004
1002 TP_fast_assign( 1005 TP_fast_assign(
1003 LOCAL_ASSIGN; 1006 LOCAL_ASSIGN;
1007 VIF_ASSIGN;
1004 CHANDEF_ASSIGN(&ch_switch->chandef) 1008 CHANDEF_ASSIGN(&ch_switch->chandef)
1005 __entry->timestamp = ch_switch->timestamp; 1009 __entry->timestamp = ch_switch->timestamp;
1010 __entry->device_timestamp = ch_switch->device_timestamp;
1006 __entry->block_tx = ch_switch->block_tx; 1011 __entry->block_tx = ch_switch->block_tx;
1007 __entry->count = ch_switch->count; 1012 __entry->count = ch_switch->count;
1008 ), 1013 ),
1009 1014
1010 TP_printk( 1015 TP_printk(
1011 LOCAL_PR_FMT " new " CHANDEF_PR_FMT " count:%d", 1016 LOCAL_PR_FMT VIF_PR_FMT " new " CHANDEF_PR_FMT " count:%d",
1012 LOCAL_PR_ARG, CHANDEF_PR_ARG, __entry->count 1017 LOCAL_PR_ARG, VIF_PR_ARG, CHANDEF_PR_ARG, __entry->count
1013 ) 1018 )
1014); 1019);
1015 1020
@@ -1557,9 +1562,26 @@ DEFINE_EVENT(local_sdata_evt, drv_stop_ap,
1557 TP_ARGS(local, sdata) 1562 TP_ARGS(local, sdata)
1558); 1563);
1559 1564
1560DEFINE_EVENT(local_only_evt, drv_restart_complete, 1565TRACE_EVENT(drv_reconfig_complete,
1561 TP_PROTO(struct ieee80211_local *local), 1566 TP_PROTO(struct ieee80211_local *local,
1562 TP_ARGS(local) 1567 enum ieee80211_reconfig_type reconfig_type),
1568 TP_ARGS(local, reconfig_type),
1569
1570 TP_STRUCT__entry(
1571 LOCAL_ENTRY
1572 __field(u8, reconfig_type)
1573 ),
1574
1575 TP_fast_assign(
1576 LOCAL_ASSIGN;
1577 __entry->reconfig_type = reconfig_type;
1578 ),
1579
1580 TP_printk(
1581 LOCAL_PR_FMT " reconfig_type:%d",
1582 LOCAL_PR_ARG, __entry->reconfig_type
1583 )
1584
1563); 1585);
1564 1586
1565#if IS_ENABLED(CONFIG_IPV6) 1587#if IS_ENABLED(CONFIG_IPV6)
@@ -2106,6 +2128,72 @@ TRACE_EVENT(drv_channel_switch_beacon,
2106 ) 2128 )
2107); 2129);
2108 2130
2131TRACE_EVENT(drv_pre_channel_switch,
2132 TP_PROTO(struct ieee80211_local *local,
2133 struct ieee80211_sub_if_data *sdata,
2134 struct ieee80211_channel_switch *ch_switch),
2135
2136 TP_ARGS(local, sdata, ch_switch),
2137
2138 TP_STRUCT__entry(
2139 LOCAL_ENTRY
2140 VIF_ENTRY
2141 CHANDEF_ENTRY
2142 __field(u64, timestamp)
2143 __field(bool, block_tx)
2144 __field(u8, count)
2145 ),
2146
2147 TP_fast_assign(
2148 LOCAL_ASSIGN;
2149 VIF_ASSIGN;
2150 CHANDEF_ASSIGN(&ch_switch->chandef)
2151 __entry->timestamp = ch_switch->timestamp;
2152 __entry->block_tx = ch_switch->block_tx;
2153 __entry->count = ch_switch->count;
2154 ),
2155
2156 TP_printk(
2157 LOCAL_PR_FMT VIF_PR_FMT " prepare channel switch to "
2158 CHANDEF_PR_FMT " count:%d block_tx:%d timestamp:%llu",
2159 LOCAL_PR_ARG, VIF_PR_ARG, CHANDEF_PR_ARG, __entry->count,
2160 __entry->block_tx, __entry->timestamp
2161 )
2162);
2163
2164DEFINE_EVENT(local_sdata_evt, drv_post_channel_switch,
2165 TP_PROTO(struct ieee80211_local *local,
2166 struct ieee80211_sub_if_data *sdata),
2167 TP_ARGS(local, sdata)
2168);
2169
2170TRACE_EVENT(drv_get_txpower,
2171 TP_PROTO(struct ieee80211_local *local,
2172 struct ieee80211_sub_if_data *sdata,
2173 int dbm, int ret),
2174
2175 TP_ARGS(local, sdata, dbm, ret),
2176
2177 TP_STRUCT__entry(
2178 LOCAL_ENTRY
2179 VIF_ENTRY
2180 __field(int, dbm)
2181 __field(int, ret)
2182 ),
2183
2184 TP_fast_assign(
2185 LOCAL_ASSIGN;
2186 VIF_ASSIGN;
2187 __entry->dbm = dbm;
2188 __entry->ret = ret;
2189 ),
2190
2191 TP_printk(
2192 LOCAL_PR_FMT VIF_PR_FMT " dbm:%d ret:%d",
2193 LOCAL_PR_ARG, VIF_PR_ARG, __entry->dbm, __entry->ret
2194 )
2195);
2196
2109 2197
2110#ifdef CONFIG_MAC80211_MESSAGE_TRACING 2198#ifdef CONFIG_MAC80211_MESSAGE_TRACING
2111#undef TRACE_SYSTEM 2199#undef TRACE_SYSTEM
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 900632a250ec..3ffd91f295a6 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -296,6 +296,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
296 */ 296 */
297 return TX_DROP; 297 return TX_DROP;
298 298
299 if (tx->sdata->vif.type == NL80211_IFTYPE_OCB)
300 return TX_CONTINUE;
301
299 if (tx->sdata->vif.type == NL80211_IFTYPE_WDS) 302 if (tx->sdata->vif.type == NL80211_IFTYPE_WDS)
300 return TX_CONTINUE; 303 return TX_CONTINUE;
301 304
@@ -2013,6 +2016,17 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
2013 goto fail_rcu; 2016 goto fail_rcu;
2014 band = chanctx_conf->def.chan->band; 2017 band = chanctx_conf->def.chan->band;
2015 break; 2018 break;
2019 case NL80211_IFTYPE_OCB:
2020 /* DA SA BSSID */
2021 memcpy(hdr.addr1, skb->data, ETH_ALEN);
2022 memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
2023 eth_broadcast_addr(hdr.addr3);
2024 hdrlen = 24;
2025 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
2026 if (!chanctx_conf)
2027 goto fail_rcu;
2028 band = chanctx_conf->def.chan->band;
2029 break;
2016 case NL80211_IFTYPE_ADHOC: 2030 case NL80211_IFTYPE_ADHOC:
2017 /* DA SA BSSID */ 2031 /* DA SA BSSID */
2018 memcpy(hdr.addr1, skb->data, ETH_ALEN); 2032 memcpy(hdr.addr1, skb->data, ETH_ALEN);
@@ -2057,6 +2071,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
2057 * EAPOL frames from the local station. 2071 * EAPOL frames from the local station.
2058 */ 2072 */
2059 if (unlikely(!ieee80211_vif_is_mesh(&sdata->vif) && 2073 if (unlikely(!ieee80211_vif_is_mesh(&sdata->vif) &&
2074 (sdata->vif.type != NL80211_IFTYPE_OCB) &&
2060 !multicast && !authorized && 2075 !multicast && !authorized &&
2061 (cpu_to_be16(ethertype) != sdata->control_port_protocol || 2076 (cpu_to_be16(ethertype) != sdata->control_port_protocol ||
2062 !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) { 2077 !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) {
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 3c61060a4d2b..f9319a5dca64 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -693,6 +693,34 @@ void ieee80211_iterate_active_interfaces_rtnl(
693} 693}
694EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_rtnl); 694EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_rtnl);
695 695
696static void __iterate_stations(struct ieee80211_local *local,
697 void (*iterator)(void *data,
698 struct ieee80211_sta *sta),
699 void *data)
700{
701 struct sta_info *sta;
702
703 list_for_each_entry_rcu(sta, &local->sta_list, list) {
704 if (!sta->uploaded)
705 continue;
706
707 iterator(data, &sta->sta);
708 }
709}
710
711void ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw,
712 void (*iterator)(void *data,
713 struct ieee80211_sta *sta),
714 void *data)
715{
716 struct ieee80211_local *local = hw_to_local(hw);
717
718 rcu_read_lock();
719 __iterate_stations(local, iterator, data);
720 rcu_read_unlock();
721}
722EXPORT_SYMBOL_GPL(ieee80211_iterate_stations_atomic);
723
696struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev) 724struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev)
697{ 725{
698 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 726 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
@@ -1073,6 +1101,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
1073 struct ieee80211_chanctx_conf *chanctx_conf; 1101 struct ieee80211_chanctx_conf *chanctx_conf;
1074 int ac; 1102 int ac;
1075 bool use_11b, enable_qos; 1103 bool use_11b, enable_qos;
1104 bool is_ocb; /* Use another EDCA parameters if dot11OCBActivated=true */
1076 int aCWmin, aCWmax; 1105 int aCWmin, aCWmax;
1077 1106
1078 if (!local->ops->conf_tx) 1107 if (!local->ops->conf_tx)
@@ -1097,6 +1126,8 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
1097 */ 1126 */
1098 enable_qos = (sdata->vif.type != NL80211_IFTYPE_STATION); 1127 enable_qos = (sdata->vif.type != NL80211_IFTYPE_STATION);
1099 1128
1129 is_ocb = (sdata->vif.type == NL80211_IFTYPE_OCB);
1130
1100 /* Set defaults according to 802.11-2007 Table 7-37 */ 1131 /* Set defaults according to 802.11-2007 Table 7-37 */
1101 aCWmax = 1023; 1132 aCWmax = 1023;
1102 if (use_11b) 1133 if (use_11b)
@@ -1118,7 +1149,10 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
1118 qparam.cw_max = aCWmax; 1149 qparam.cw_max = aCWmax;
1119 qparam.cw_min = aCWmin; 1150 qparam.cw_min = aCWmin;
1120 qparam.txop = 0; 1151 qparam.txop = 0;
1121 qparam.aifs = 7; 1152 if (is_ocb)
1153 qparam.aifs = 9;
1154 else
1155 qparam.aifs = 7;
1122 break; 1156 break;
1123 /* never happens but let's not leave undefined */ 1157 /* never happens but let's not leave undefined */
1124 default: 1158 default:
@@ -1126,21 +1160,32 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
1126 qparam.cw_max = aCWmax; 1160 qparam.cw_max = aCWmax;
1127 qparam.cw_min = aCWmin; 1161 qparam.cw_min = aCWmin;
1128 qparam.txop = 0; 1162 qparam.txop = 0;
1129 qparam.aifs = 3; 1163 if (is_ocb)
1164 qparam.aifs = 6;
1165 else
1166 qparam.aifs = 3;
1130 break; 1167 break;
1131 case IEEE80211_AC_VI: 1168 case IEEE80211_AC_VI:
1132 qparam.cw_max = aCWmin; 1169 qparam.cw_max = aCWmin;
1133 qparam.cw_min = (aCWmin + 1) / 2 - 1; 1170 qparam.cw_min = (aCWmin + 1) / 2 - 1;
1134 if (use_11b) 1171 if (is_ocb)
1172 qparam.txop = 0;
1173 else if (use_11b)
1135 qparam.txop = 6016/32; 1174 qparam.txop = 6016/32;
1136 else 1175 else
1137 qparam.txop = 3008/32; 1176 qparam.txop = 3008/32;
1138 qparam.aifs = 2; 1177
1178 if (is_ocb)
1179 qparam.aifs = 3;
1180 else
1181 qparam.aifs = 2;
1139 break; 1182 break;
1140 case IEEE80211_AC_VO: 1183 case IEEE80211_AC_VO:
1141 qparam.cw_max = (aCWmin + 1) / 2 - 1; 1184 qparam.cw_max = (aCWmin + 1) / 2 - 1;
1142 qparam.cw_min = (aCWmin + 1) / 4 - 1; 1185 qparam.cw_min = (aCWmin + 1) / 4 - 1;
1143 if (use_11b) 1186 if (is_ocb)
1187 qparam.txop = 0;
1188 else if (use_11b)
1144 qparam.txop = 3264/32; 1189 qparam.txop = 3264/32;
1145 else 1190 else
1146 qparam.txop = 1504/32; 1191 qparam.txop = 1504/32;
@@ -1813,6 +1858,10 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1813 ieee80211_bss_info_change_notify(sdata, changed); 1858 ieee80211_bss_info_change_notify(sdata, changed);
1814 sdata_unlock(sdata); 1859 sdata_unlock(sdata);
1815 break; 1860 break;
1861 case NL80211_IFTYPE_OCB:
1862 changed |= BSS_CHANGED_OCB;
1863 ieee80211_bss_info_change_notify(sdata, changed);
1864 break;
1816 case NL80211_IFTYPE_ADHOC: 1865 case NL80211_IFTYPE_ADHOC:
1817 changed |= BSS_CHANGED_IBSS; 1866 changed |= BSS_CHANGED_IBSS;
1818 /* fall through */ 1867 /* fall through */
@@ -1949,7 +1998,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1949 * We may want to change that later, however. 1998 * We may want to change that later, however.
1950 */ 1999 */
1951 if (!local->suspended || reconfig_due_to_wowlan) 2000 if (!local->suspended || reconfig_due_to_wowlan)
1952 drv_restart_complete(local); 2001 drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_RESTART);
1953 2002
1954 if (!local->suspended) 2003 if (!local->suspended)
1955 return 0; 2004 return 0;
@@ -1960,6 +2009,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1960 mb(); 2009 mb();
1961 local->resuming = false; 2010 local->resuming = false;
1962 2011
2012 if (!reconfig_due_to_wowlan)
2013 drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND);
2014
1963 list_for_each_entry(sdata, &local->interfaces, list) { 2015 list_for_each_entry(sdata, &local->interfaces, list) {
1964 if (!ieee80211_sdata_running(sdata)) 2016 if (!ieee80211_sdata_running(sdata))
1965 continue; 2017 continue;
@@ -2052,42 +2104,36 @@ static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id)
2052 return false; 2104 return false;
2053} 2105}
2054 2106
2055/** 2107size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen,
2056 * ieee80211_ie_split - split an IE buffer according to ordering 2108 const u8 *ids, int n_ids,
2057 * 2109 const u8 *after_ric, int n_after_ric,
2058 * @ies: the IE buffer 2110 size_t offset)
2059 * @ielen: the length of the IE buffer
2060 * @ids: an array with element IDs that are allowed before
2061 * the split
2062 * @n_ids: the size of the element ID array
2063 * @offset: offset where to start splitting in the buffer
2064 *
2065 * This function splits an IE buffer by updating the @offset
2066 * variable to point to the location where the buffer should be
2067 * split.
2068 *
2069 * It assumes that the given IE buffer is well-formed, this
2070 * has to be guaranteed by the caller!
2071 *
2072 * It also assumes that the IEs in the buffer are ordered
2073 * correctly, if not the result of using this function will not
2074 * be ordered correctly either, i.e. it does no reordering.
2075 *
2076 * The function returns the offset where the next part of the
2077 * buffer starts, which may be @ielen if the entire (remainder)
2078 * of the buffer should be used.
2079 */
2080size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
2081 const u8 *ids, int n_ids, size_t offset)
2082{ 2111{
2083 size_t pos = offset; 2112 size_t pos = offset;
2084 2113
2085 while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) 2114 while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) {
2086 pos += 2 + ies[pos + 1]; 2115 if (ies[pos] == WLAN_EID_RIC_DATA && n_after_ric) {
2116 pos += 2 + ies[pos + 1];
2117
2118 while (pos < ielen &&
2119 !ieee80211_id_in_list(after_ric, n_after_ric,
2120 ies[pos]))
2121 pos += 2 + ies[pos + 1];
2122 } else {
2123 pos += 2 + ies[pos + 1];
2124 }
2125 }
2087 2126
2088 return pos; 2127 return pos;
2089} 2128}
2090 2129
2130size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
2131 const u8 *ids, int n_ids, size_t offset)
2132{
2133 return ieee80211_ie_split_ric(ies, ielen, ids, n_ids, NULL, 0, offset);
2134}
2135EXPORT_SYMBOL(ieee80211_ie_split);
2136
2091size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset) 2137size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset)
2092{ 2138{
2093 size_t pos = offset; 2139 size_t pos = offset;
@@ -2526,11 +2572,23 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work)
2526 struct ieee80211_local *local = 2572 struct ieee80211_local *local =
2527 container_of(work, struct ieee80211_local, radar_detected_work); 2573 container_of(work, struct ieee80211_local, radar_detected_work);
2528 struct cfg80211_chan_def chandef = local->hw.conf.chandef; 2574 struct cfg80211_chan_def chandef = local->hw.conf.chandef;
2575 struct ieee80211_chanctx *ctx;
2576 int num_chanctx = 0;
2577
2578 mutex_lock(&local->chanctx_mtx);
2579 list_for_each_entry(ctx, &local->chanctx_list, list) {
2580 if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER)
2581 continue;
2582
2583 num_chanctx++;
2584 chandef = ctx->conf.def;
2585 }
2586 mutex_unlock(&local->chanctx_mtx);
2529 2587
2530 ieee80211_dfs_cac_cancel(local); 2588 ieee80211_dfs_cac_cancel(local);
2531 2589
2532 if (local->use_chanctx) 2590 if (num_chanctx > 1)
2533 /* currently not handled */ 2591 /* XXX: multi-channel is not supported yet */
2534 WARN_ON(1); 2592 WARN_ON(1);
2535 else 2593 else
2536 cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL); 2594 cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL);
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 9181fb6d6437..a4220e92f0cc 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -111,8 +111,6 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
111 (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) 111 (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))
112 return newhdr + hdrlen; 112 return newhdr + hdrlen;
113 113
114 skb_set_network_header(skb, skb_network_offset(skb) +
115 IEEE80211_WEP_IV_LEN);
116 ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen); 114 ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen);
117 return newhdr + hdrlen; 115 return newhdr + hdrlen;
118} 116}
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 3b873989992c..fdf52db95b33 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -54,10 +54,18 @@ static int wme_downgrade_ac(struct sk_buff *skb)
54} 54}
55 55
56static u16 ieee80211_downgrade_queue(struct ieee80211_sub_if_data *sdata, 56static u16 ieee80211_downgrade_queue(struct ieee80211_sub_if_data *sdata,
57 struct sk_buff *skb) 57 struct sta_info *sta, struct sk_buff *skb)
58{ 58{
59 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
60
59 /* in case we are a client verify acm is not set for this ac */ 61 /* in case we are a client verify acm is not set for this ac */
60 while (unlikely(sdata->wmm_acm & BIT(skb->priority))) { 62 while (sdata->wmm_acm & BIT(skb->priority)) {
63 int ac = ieee802_1d_to_ac[skb->priority];
64
65 if (ifmgd->tx_tspec[ac].admitted_time &&
66 skb->priority == ifmgd->tx_tspec[ac].up)
67 return ac;
68
61 if (wme_downgrade_ac(skb)) { 69 if (wme_downgrade_ac(skb)) {
62 /* 70 /*
63 * This should not really happen. The AP has marked all 71 * This should not really happen. The AP has marked all
@@ -96,7 +104,7 @@ u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
96 p = ieee80211_get_qos_ctl(hdr); 104 p = ieee80211_get_qos_ctl(hdr);
97 skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK; 105 skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK;
98 106
99 return ieee80211_downgrade_queue(sdata, skb); 107 return ieee80211_downgrade_queue(sdata, NULL, skb);
100} 108}
101 109
102/* Indicate which queue to use. */ 110/* Indicate which queue to use. */
@@ -108,6 +116,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
108 const u8 *ra = NULL; 116 const u8 *ra = NULL;
109 bool qos = false; 117 bool qos = false;
110 struct mac80211_qos_map *qos_map; 118 struct mac80211_qos_map *qos_map;
119 u16 ret;
111 120
112 if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) { 121 if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) {
113 skb->priority = 0; /* required for correct WPA/11i MIC */ 122 skb->priority = 0; /* required for correct WPA/11i MIC */
@@ -139,6 +148,10 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
139 case NL80211_IFTYPE_ADHOC: 148 case NL80211_IFTYPE_ADHOC:
140 ra = skb->data; 149 ra = skb->data;
141 break; 150 break;
151 case NL80211_IFTYPE_OCB:
152 /* all stations are required to support WME */
153 qos = true;
154 break;
142 default: 155 default:
143 break; 156 break;
144 } 157 }
@@ -148,27 +161,29 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
148 if (sta) 161 if (sta)
149 qos = sta->sta.wme; 162 qos = sta->sta.wme;
150 } 163 }
151 rcu_read_unlock();
152 164
153 if (!qos) { 165 if (!qos) {
154 skb->priority = 0; /* required for correct WPA/11i MIC */ 166 skb->priority = 0; /* required for correct WPA/11i MIC */
155 return IEEE80211_AC_BE; 167 ret = IEEE80211_AC_BE;
168 goto out;
156 } 169 }
157 170
158 if (skb->protocol == sdata->control_port_protocol) { 171 if (skb->protocol == sdata->control_port_protocol) {
159 skb->priority = 7; 172 skb->priority = 7;
160 return ieee80211_downgrade_queue(sdata, skb); 173 goto downgrade;
161 } 174 }
162 175
163 /* use the data classifier to determine what 802.1d tag the 176 /* use the data classifier to determine what 802.1d tag the
164 * data frame has */ 177 * data frame has */
165 rcu_read_lock();
166 qos_map = rcu_dereference(sdata->qos_map); 178 qos_map = rcu_dereference(sdata->qos_map);
167 skb->priority = cfg80211_classify8021d(skb, qos_map ? 179 skb->priority = cfg80211_classify8021d(skb, qos_map ?
168 &qos_map->qos_map : NULL); 180 &qos_map->qos_map : NULL);
169 rcu_read_unlock();
170 181
171 return ieee80211_downgrade_queue(sdata, skb); 182 downgrade:
183 ret = ieee80211_downgrade_queue(sdata, sta, skb);
184 out:
185 rcu_read_unlock();
186 return ret;
172} 187}
173 188
174/** 189/**
diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h
index 7fea4bb8acbc..80151edc5195 100644
--- a/net/mac80211/wme.h
+++ b/net/mac80211/wme.h
@@ -13,8 +13,6 @@
13#include <linux/netdevice.h> 13#include <linux/netdevice.h>
14#include "ieee80211_i.h" 14#include "ieee80211_i.h"
15 15
16extern const int ieee802_1d_to_ac[8];
17
18u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, 16u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
19 struct sk_buff *skb, 17 struct sk_buff *skb,
20 struct ieee80211_hdr *hdr); 18 struct ieee80211_hdr *hdr);
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 983527a4c1ab..12398fde02e8 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -209,8 +209,6 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
209 209
210 pos = skb_push(skb, IEEE80211_TKIP_IV_LEN); 210 pos = skb_push(skb, IEEE80211_TKIP_IV_LEN);
211 memmove(pos, pos + IEEE80211_TKIP_IV_LEN, hdrlen); 211 memmove(pos, pos + IEEE80211_TKIP_IV_LEN, hdrlen);
212 skb_set_network_header(skb, skb_network_offset(skb) +
213 IEEE80211_TKIP_IV_LEN);
214 pos += hdrlen; 212 pos += hdrlen;
215 213
216 /* the HW only needs room for the IV, but not the actual IV */ 214 /* the HW only needs room for the IV, but not the actual IV */
@@ -434,8 +432,6 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
434 432
435 pos = skb_push(skb, IEEE80211_CCMP_HDR_LEN); 433 pos = skb_push(skb, IEEE80211_CCMP_HDR_LEN);
436 memmove(pos, pos + IEEE80211_CCMP_HDR_LEN, hdrlen); 434 memmove(pos, pos + IEEE80211_CCMP_HDR_LEN, hdrlen);
437 skb_set_network_header(skb, skb_network_offset(skb) +
438 IEEE80211_CCMP_HDR_LEN);
439 435
440 /* the HW only needs room for the IV, but not the actual IV */ 436 /* the HW only needs room for the IV, but not the actual IV */
441 if (info->control.hw_key && 437 if (info->control.hw_key &&
@@ -575,7 +571,6 @@ ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx,
575 571
576 pos = skb_push(skb, cs->hdr_len); 572 pos = skb_push(skb, cs->hdr_len);
577 memmove(pos, pos + cs->hdr_len, hdrlen); 573 memmove(pos, pos + cs->hdr_len, hdrlen);
578 skb_set_network_header(skb, skb_network_offset(skb) + cs->hdr_len);
579 574
580 return TX_CONTINUE; 575 return TX_CONTINUE;
581} 576}
diff --git a/net/mac802154/Kconfig b/net/mac802154/Kconfig
index 1818a99b3081..aa462b480a39 100644
--- a/net/mac802154/Kconfig
+++ b/net/mac802154/Kconfig
@@ -16,5 +16,5 @@ config MAC802154
16 been tested yet! 16 been tested yet!
17 17
18 If you plan to use HardMAC IEEE 802.15.4 devices, you can 18 If you plan to use HardMAC IEEE 802.15.4 devices, you can
19 say N here. Alternatievly you can say M to compile it as 19 say N here. Alternatively you can say M to compile it as
20 module. 20 module.
diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile
index 9723d6f3f3e5..2e497d0c829a 100644
--- a/net/mac802154/Makefile
+++ b/net/mac802154/Makefile
@@ -1,5 +1,5 @@
1obj-$(CONFIG_MAC802154) += mac802154.o 1obj-$(CONFIG_MAC802154) += mac802154.o
2mac802154-objs := ieee802154_dev.o rx.o tx.o mac_cmd.o mib.o \ 2mac802154-objs := main.o rx.o tx.o mac_cmd.o mib.o \
3 monitor.o wpan.o llsec.o 3 iface.o llsec.o util.o
4 4
5ccflags-y += -D__CHECK_ENDIAN__ 5ccflags-y += -D__CHECK_ENDIAN__
diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h
new file mode 100644
index 000000000000..dfd29ffb8fee
--- /dev/null
+++ b/net/mac802154/driver-ops.h
@@ -0,0 +1,226 @@
1#ifndef __MAC802154_DRVIER_OPS
2#define __MAC802154_DRIVER_OPS
3
4#include <linux/types.h>
5#include <linux/rtnetlink.h>
6
7#include <net/mac802154.h>
8
9#include "ieee802154_i.h"
10
11static inline int
12drv_xmit_async(struct ieee802154_local *local, struct sk_buff *skb)
13{
14 return local->ops->xmit_async(&local->hw, skb);
15}
16
17static inline int
18drv_xmit_sync(struct ieee802154_local *local, struct sk_buff *skb)
19{
20 /* don't allow other operations while sync xmit */
21 ASSERT_RTNL();
22
23 might_sleep();
24
25 return local->ops->xmit_sync(&local->hw, skb);
26}
27
28static inline int drv_start(struct ieee802154_local *local)
29{
30 might_sleep();
31
32 local->started = true;
33 smp_mb();
34
35 return local->ops->start(&local->hw);
36}
37
38static inline void drv_stop(struct ieee802154_local *local)
39{
40 might_sleep();
41
42 local->ops->stop(&local->hw);
43
44 /* sync away all work on the tasklet before clearing started */
45 tasklet_disable(&local->tasklet);
46 tasklet_enable(&local->tasklet);
47
48 barrier();
49
50 local->started = false;
51}
52
53static inline int drv_set_channel(struct ieee802154_local *local,
54 const u8 page, const u8 channel)
55{
56 might_sleep();
57
58 return local->ops->set_channel(&local->hw, page, channel);
59}
60
61static inline int drv_set_tx_power(struct ieee802154_local *local,
62 const s8 dbm)
63{
64 might_sleep();
65
66 if (!local->ops->set_txpower) {
67 WARN_ON(1);
68 return -EOPNOTSUPP;
69 }
70
71 return local->ops->set_txpower(&local->hw, dbm);
72}
73
74static inline int drv_set_cca_mode(struct ieee802154_local *local,
75 const u8 cca_mode)
76{
77 might_sleep();
78
79 if (!local->ops->set_cca_mode) {
80 WARN_ON(1);
81 return -EOPNOTSUPP;
82 }
83
84 return local->ops->set_cca_mode(&local->hw, cca_mode);
85}
86
87static inline int drv_set_lbt_mode(struct ieee802154_local *local,
88 const bool mode)
89{
90 might_sleep();
91
92 if (!local->ops->set_lbt) {
93 WARN_ON(1);
94 return -EOPNOTSUPP;
95 }
96
97 return local->ops->set_lbt(&local->hw, mode);
98}
99
100static inline int drv_set_cca_ed_level(struct ieee802154_local *local,
101 const s32 ed_level)
102{
103 might_sleep();
104
105 if (!local->ops->set_cca_ed_level) {
106 WARN_ON(1);
107 return -EOPNOTSUPP;
108 }
109
110 return local->ops->set_cca_ed_level(&local->hw, ed_level);
111}
112
113static inline int drv_set_pan_id(struct ieee802154_local *local,
114 const __le16 pan_id)
115{
116 struct ieee802154_hw_addr_filt filt;
117
118 might_sleep();
119
120 if (!local->ops->set_hw_addr_filt) {
121 WARN_ON(1);
122 return -EOPNOTSUPP;
123 }
124
125 filt.pan_id = pan_id;
126
127 return local->ops->set_hw_addr_filt(&local->hw, &filt,
128 IEEE802154_AFILT_PANID_CHANGED);
129}
130
131static inline int drv_set_extended_addr(struct ieee802154_local *local,
132 const __le64 extended_addr)
133{
134 struct ieee802154_hw_addr_filt filt;
135
136 might_sleep();
137
138 if (!local->ops->set_hw_addr_filt) {
139 WARN_ON(1);
140 return -EOPNOTSUPP;
141 }
142
143 filt.ieee_addr = extended_addr;
144
145 return local->ops->set_hw_addr_filt(&local->hw, &filt,
146 IEEE802154_AFILT_IEEEADDR_CHANGED);
147}
148
149static inline int drv_set_short_addr(struct ieee802154_local *local,
150 const __le16 short_addr)
151{
152 struct ieee802154_hw_addr_filt filt;
153
154 might_sleep();
155
156 if (!local->ops->set_hw_addr_filt) {
157 WARN_ON(1);
158 return -EOPNOTSUPP;
159 }
160
161 filt.short_addr = short_addr;
162
163 return local->ops->set_hw_addr_filt(&local->hw, &filt,
164 IEEE802154_AFILT_SADDR_CHANGED);
165}
166
167static inline int drv_set_pan_coord(struct ieee802154_local *local,
168 const bool is_coord)
169{
170 struct ieee802154_hw_addr_filt filt;
171
172 might_sleep();
173
174 if (!local->ops->set_hw_addr_filt) {
175 WARN_ON(1);
176 return -EOPNOTSUPP;
177 }
178
179 filt.pan_coord = is_coord;
180
181 return local->ops->set_hw_addr_filt(&local->hw, &filt,
182 IEEE802154_AFILT_PANC_CHANGED);
183}
184
185static inline int drv_set_csma_params(struct ieee802154_local *local,
186 u8 min_be, u8 max_be,
187 u8 max_csma_backoffs)
188{
189 might_sleep();
190
191 if (!local->ops->set_csma_params) {
192 WARN_ON(1);
193 return -EOPNOTSUPP;
194 }
195
196 return local->ops->set_csma_params(&local->hw, min_be, max_be,
197 max_csma_backoffs);
198}
199
200static inline int drv_set_max_frame_retries(struct ieee802154_local *local,
201 s8 max_frame_retries)
202{
203 might_sleep();
204
205 if (!local->ops->set_frame_retries) {
206 WARN_ON(1);
207 return -EOPNOTSUPP;
208 }
209
210 return local->ops->set_frame_retries(&local->hw, max_frame_retries);
211}
212
213static inline int drv_set_promiscuous_mode(struct ieee802154_local *local,
214 const bool on)
215{
216 might_sleep();
217
218 if (!local->ops->set_promiscuous_mode) {
219 WARN_ON(1);
220 return -EOPNOTSUPP;
221 }
222
223 return local->ops->set_promiscuous_mode(&local->hw, on);
224}
225
226#endif /* __MAC802154_DRVIER_OPS */
diff --git a/net/mac802154/ieee802154_dev.c b/net/mac802154/ieee802154_dev.c
deleted file mode 100644
index b36b2b996578..000000000000
--- a/net/mac802154/ieee802154_dev.c
+++ /dev/null
@@ -1,415 +0,0 @@
1/*
2 * Copyright (C) 2007-2012 Siemens AG
3 *
4 * Written by:
5 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
6 *
7 * Based on the code from 'linux-zigbee.sourceforge.net' project.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2
11 * as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/netdevice.h>
26
27#include <net/netlink.h>
28#include <linux/nl802154.h>
29#include <net/mac802154.h>
30#include <net/ieee802154_netdev.h>
31#include <net/route.h>
32#include <net/wpan-phy.h>
33
34#include "mac802154.h"
35
36int mac802154_slave_open(struct net_device *dev)
37{
38 struct mac802154_sub_if_data *priv = netdev_priv(dev);
39 struct mac802154_sub_if_data *subif;
40 struct mac802154_priv *ipriv = priv->hw;
41 int res = 0;
42
43 ASSERT_RTNL();
44
45 if (priv->type == IEEE802154_DEV_WPAN) {
46 mutex_lock(&priv->hw->slaves_mtx);
47 list_for_each_entry(subif, &priv->hw->slaves, list) {
48 if (subif != priv && subif->type == priv->type &&
49 subif->running) {
50 mutex_unlock(&priv->hw->slaves_mtx);
51 return -EBUSY;
52 }
53 }
54 mutex_unlock(&priv->hw->slaves_mtx);
55 }
56
57 mutex_lock(&priv->hw->slaves_mtx);
58 priv->running = true;
59 mutex_unlock(&priv->hw->slaves_mtx);
60
61 if (ipriv->open_count++ == 0) {
62 res = ipriv->ops->start(&ipriv->hw);
63 WARN_ON(res);
64 if (res)
65 goto err;
66 }
67
68 if (ipriv->ops->ieee_addr) {
69 __le64 addr = ieee802154_devaddr_from_raw(dev->dev_addr);
70
71 res = ipriv->ops->ieee_addr(&ipriv->hw, addr);
72 WARN_ON(res);
73 if (res)
74 goto err;
75 mac802154_dev_set_ieee_addr(dev);
76 }
77
78 netif_start_queue(dev);
79 return 0;
80err:
81 priv->hw->open_count--;
82
83 return res;
84}
85
86int mac802154_slave_close(struct net_device *dev)
87{
88 struct mac802154_sub_if_data *priv = netdev_priv(dev);
89 struct mac802154_priv *ipriv = priv->hw;
90
91 ASSERT_RTNL();
92
93 netif_stop_queue(dev);
94
95 mutex_lock(&priv->hw->slaves_mtx);
96 priv->running = false;
97 mutex_unlock(&priv->hw->slaves_mtx);
98
99 if (!--ipriv->open_count)
100 ipriv->ops->stop(&ipriv->hw);
101
102 return 0;
103}
104
105static int
106mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev)
107{
108 struct mac802154_sub_if_data *priv;
109 struct mac802154_priv *ipriv;
110 int err;
111
112 ipriv = wpan_phy_priv(phy);
113
114 priv = netdev_priv(dev);
115 priv->dev = dev;
116 priv->hw = ipriv;
117
118 dev->needed_headroom = ipriv->hw.extra_tx_headroom;
119
120 SET_NETDEV_DEV(dev, &ipriv->phy->dev);
121
122 mutex_lock(&ipriv->slaves_mtx);
123 if (!ipriv->running) {
124 mutex_unlock(&ipriv->slaves_mtx);
125 return -ENODEV;
126 }
127 mutex_unlock(&ipriv->slaves_mtx);
128
129 err = register_netdev(dev);
130 if (err < 0)
131 return err;
132
133 rtnl_lock();
134 mutex_lock(&ipriv->slaves_mtx);
135 list_add_tail_rcu(&priv->list, &ipriv->slaves);
136 mutex_unlock(&ipriv->slaves_mtx);
137 rtnl_unlock();
138
139 return 0;
140}
141
142static void
143mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev)
144{
145 struct mac802154_sub_if_data *sdata;
146
147 ASSERT_RTNL();
148
149 sdata = netdev_priv(dev);
150
151 BUG_ON(sdata->hw->phy != phy);
152
153 mutex_lock(&sdata->hw->slaves_mtx);
154 list_del_rcu(&sdata->list);
155 mutex_unlock(&sdata->hw->slaves_mtx);
156
157 synchronize_rcu();
158 unregister_netdevice(sdata->dev);
159}
160
161static struct net_device *
162mac802154_add_iface(struct wpan_phy *phy, const char *name, int type)
163{
164 struct net_device *dev;
165 int err = -ENOMEM;
166
167 switch (type) {
168 case IEEE802154_DEV_MONITOR:
169 dev = alloc_netdev(sizeof(struct mac802154_sub_if_data),
170 name, NET_NAME_UNKNOWN,
171 mac802154_monitor_setup);
172 break;
173 case IEEE802154_DEV_WPAN:
174 dev = alloc_netdev(sizeof(struct mac802154_sub_if_data),
175 name, NET_NAME_UNKNOWN,
176 mac802154_wpan_setup);
177 break;
178 default:
179 dev = NULL;
180 err = -EINVAL;
181 break;
182 }
183 if (!dev)
184 goto err;
185
186 err = mac802154_netdev_register(phy, dev);
187 if (err)
188 goto err_free;
189
190 dev_hold(dev); /* we return an incremented device refcount */
191 return dev;
192
193err_free:
194 free_netdev(dev);
195err:
196 return ERR_PTR(err);
197}
198
199static int mac802154_set_txpower(struct wpan_phy *phy, int db)
200{
201 struct mac802154_priv *priv = wpan_phy_priv(phy);
202
203 return priv->ops->set_txpower(&priv->hw, db);
204}
205
206static int mac802154_set_lbt(struct wpan_phy *phy, bool on)
207{
208 struct mac802154_priv *priv = wpan_phy_priv(phy);
209
210 return priv->ops->set_lbt(&priv->hw, on);
211}
212
213static int mac802154_set_cca_mode(struct wpan_phy *phy, u8 mode)
214{
215 struct mac802154_priv *priv = wpan_phy_priv(phy);
216
217 return priv->ops->set_cca_mode(&priv->hw, mode);
218}
219
220static int mac802154_set_cca_ed_level(struct wpan_phy *phy, s32 level)
221{
222 struct mac802154_priv *priv = wpan_phy_priv(phy);
223
224 return priv->ops->set_cca_ed_level(&priv->hw, level);
225}
226
227static int mac802154_set_csma_params(struct wpan_phy *phy, u8 min_be,
228 u8 max_be, u8 retries)
229{
230 struct mac802154_priv *priv = wpan_phy_priv(phy);
231
232 return priv->ops->set_csma_params(&priv->hw, min_be, max_be, retries);
233}
234
235static int mac802154_set_frame_retries(struct wpan_phy *phy, s8 retries)
236{
237 struct mac802154_priv *priv = wpan_phy_priv(phy);
238
239 return priv->ops->set_frame_retries(&priv->hw, retries);
240}
241
242struct ieee802154_dev *
243ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops)
244{
245 struct wpan_phy *phy;
246 struct mac802154_priv *priv;
247 size_t priv_size;
248
249 if (!ops || !ops->xmit || !ops->ed || !ops->start ||
250 !ops->stop || !ops->set_channel) {
251 pr_err("undefined IEEE802.15.4 device operations\n");
252 return NULL;
253 }
254
255 /* Ensure 32-byte alignment of our private data and hw private data.
256 * We use the wpan_phy priv data for both our mac802154_priv and for
257 * the driver's private data
258 *
259 * in memory it'll be like this:
260 *
261 * +-----------------------+
262 * | struct wpan_phy |
263 * +-----------------------+
264 * | struct mac802154_priv |
265 * +-----------------------+
266 * | driver's private data |
267 * +-----------------------+
268 *
269 * Due to ieee802154 layer isn't aware of driver and MAC structures,
270 * so lets allign them here.
271 */
272
273 priv_size = ALIGN(sizeof(*priv), NETDEV_ALIGN) + priv_data_len;
274
275 phy = wpan_phy_alloc(priv_size);
276 if (!phy) {
277 pr_err("failure to allocate master IEEE802.15.4 device\n");
278 return NULL;
279 }
280
281 priv = wpan_phy_priv(phy);
282 priv->phy = phy;
283 priv->hw.phy = priv->phy;
284 priv->hw.priv = (char *)priv + ALIGN(sizeof(*priv), NETDEV_ALIGN);
285 priv->ops = ops;
286
287 INIT_LIST_HEAD(&priv->slaves);
288 mutex_init(&priv->slaves_mtx);
289
290 return &priv->hw;
291}
292EXPORT_SYMBOL(ieee802154_alloc_device);
293
294void ieee802154_free_device(struct ieee802154_dev *hw)
295{
296 struct mac802154_priv *priv = mac802154_to_priv(hw);
297
298 BUG_ON(!list_empty(&priv->slaves));
299
300 mutex_destroy(&priv->slaves_mtx);
301
302 wpan_phy_free(priv->phy);
303}
304EXPORT_SYMBOL(ieee802154_free_device);
305
306int ieee802154_register_device(struct ieee802154_dev *dev)
307{
308 struct mac802154_priv *priv = mac802154_to_priv(dev);
309 int rc = -ENOSYS;
310
311 if (dev->flags & IEEE802154_HW_TXPOWER) {
312 if (!priv->ops->set_txpower)
313 goto out;
314
315 priv->phy->set_txpower = mac802154_set_txpower;
316 }
317
318 if (dev->flags & IEEE802154_HW_LBT) {
319 if (!priv->ops->set_lbt)
320 goto out;
321
322 priv->phy->set_lbt = mac802154_set_lbt;
323 }
324
325 if (dev->flags & IEEE802154_HW_CCA_MODE) {
326 if (!priv->ops->set_cca_mode)
327 goto out;
328
329 priv->phy->set_cca_mode = mac802154_set_cca_mode;
330 }
331
332 if (dev->flags & IEEE802154_HW_CCA_ED_LEVEL) {
333 if (!priv->ops->set_cca_ed_level)
334 goto out;
335
336 priv->phy->set_cca_ed_level = mac802154_set_cca_ed_level;
337 }
338
339 if (dev->flags & IEEE802154_HW_CSMA_PARAMS) {
340 if (!priv->ops->set_csma_params)
341 goto out;
342
343 priv->phy->set_csma_params = mac802154_set_csma_params;
344 }
345
346 if (dev->flags & IEEE802154_HW_FRAME_RETRIES) {
347 if (!priv->ops->set_frame_retries)
348 goto out;
349
350 priv->phy->set_frame_retries = mac802154_set_frame_retries;
351 }
352
353 priv->dev_workqueue =
354 create_singlethread_workqueue(wpan_phy_name(priv->phy));
355 if (!priv->dev_workqueue) {
356 rc = -ENOMEM;
357 goto out;
358 }
359
360 wpan_phy_set_dev(priv->phy, priv->hw.parent);
361
362 priv->phy->add_iface = mac802154_add_iface;
363 priv->phy->del_iface = mac802154_del_iface;
364
365 rc = wpan_phy_register(priv->phy);
366 if (rc < 0)
367 goto out_wq;
368
369 rtnl_lock();
370
371 mutex_lock(&priv->slaves_mtx);
372 priv->running = MAC802154_DEVICE_RUN;
373 mutex_unlock(&priv->slaves_mtx);
374
375 rtnl_unlock();
376
377 return 0;
378
379out_wq:
380 destroy_workqueue(priv->dev_workqueue);
381out:
382 return rc;
383}
384EXPORT_SYMBOL(ieee802154_register_device);
385
386void ieee802154_unregister_device(struct ieee802154_dev *dev)
387{
388 struct mac802154_priv *priv = mac802154_to_priv(dev);
389 struct mac802154_sub_if_data *sdata, *next;
390
391 flush_workqueue(priv->dev_workqueue);
392 destroy_workqueue(priv->dev_workqueue);
393
394 rtnl_lock();
395
396 mutex_lock(&priv->slaves_mtx);
397 priv->running = MAC802154_DEVICE_STOPPED;
398 mutex_unlock(&priv->slaves_mtx);
399
400 list_for_each_entry_safe(sdata, next, &priv->slaves, list) {
401 mutex_lock(&sdata->hw->slaves_mtx);
402 list_del(&sdata->list);
403 mutex_unlock(&sdata->hw->slaves_mtx);
404
405 unregister_netdevice(sdata->dev);
406 }
407
408 rtnl_unlock();
409
410 wpan_phy_unregister(priv->phy);
411}
412EXPORT_SYMBOL(ieee802154_unregister_device);
413
414MODULE_DESCRIPTION("IEEE 802.15.4 implementation");
415MODULE_LICENSE("GPL v2");
diff --git a/net/mac802154/mac802154.h b/net/mac802154/ieee802154_i.h
index 762a6f849c6b..1086a9d96f8f 100644
--- a/net/mac802154/mac802154.h
+++ b/net/mac802154/ieee802154_i.h
@@ -10,18 +10,14 @@
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details. 11 * GNU General Public License for more details.
12 * 12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Written by: 13 * Written by:
18 * Pavel Smolenskiy <pavel.smolenskiy@gmail.com> 14 * Pavel Smolenskiy <pavel.smolenskiy@gmail.com>
19 * Maxim Gorbachyov <maxim.gorbachev@siemens.com> 15 * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
20 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> 16 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
21 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com> 17 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
22 */ 18 */
23#ifndef MAC802154_H 19#ifndef __IEEE802154_I_H
24#define MAC802154_H 20#define __IEEE802154_I_H
25 21
26#include <linux/mutex.h> 22#include <linux/mutex.h>
27#include <net/mac802154.h> 23#include <net/mac802154.h>
@@ -30,9 +26,9 @@
30#include "llsec.h" 26#include "llsec.h"
31 27
32/* mac802154 device private data */ 28/* mac802154 device private data */
33struct mac802154_priv { 29struct ieee802154_local {
34 struct ieee802154_dev hw; 30 struct ieee802154_hw hw;
35 struct ieee802154_ops *ops; 31 const struct ieee802154_ops *ops;
36 32
37 /* ieee802154 phy */ 33 /* ieee802154 phy */
38 struct wpan_phy *phy; 34 struct wpan_phy *phy;
@@ -46,23 +42,27 @@ struct mac802154_priv {
46 * 42 *
47 * So atomic readers can use any of this protection methods. 43 * So atomic readers can use any of this protection methods.
48 */ 44 */
49 struct list_head slaves; 45 struct list_head interfaces;
50 struct mutex slaves_mtx; 46 struct mutex iflist_mtx;
51 47
52 /* This one is used for scanning and other jobs not to be interfered 48 /* This one is used for scanning and other jobs not to be interfered
53 * with serial driver. 49 * with serial driver.
54 */ 50 */
55 struct workqueue_struct *dev_workqueue; 51 struct workqueue_struct *workqueue;
56 52
57 /* SoftMAC device is registered and running. One can add subinterfaces. 53 bool started;
58 * This flag should be modified under slaves_mtx and RTNL, so you can 54
59 * read them using any of protection methods. 55 struct tasklet_struct tasklet;
60 */ 56 struct sk_buff_head skb_queue;
61 bool running;
62}; 57};
63 58
64#define MAC802154_DEVICE_STOPPED 0x00 59enum {
65#define MAC802154_DEVICE_RUN 0x01 60 IEEE802154_RX_MSG = 1,
61};
62
63enum ieee802154_sdata_state_bits {
64 SDATA_STATE_RUNNING,
65};
66 66
67/* Slave interface definition. 67/* Slave interface definition.
68 * 68 *
@@ -70,23 +70,21 @@ struct mac802154_priv {
70 * Each ieee802154 device/transceiver may have several slaves and able 70 * Each ieee802154 device/transceiver may have several slaves and able
71 * to be associated with several networks at the same time. 71 * to be associated with several networks at the same time.
72 */ 72 */
73struct mac802154_sub_if_data { 73struct ieee802154_sub_if_data {
74 struct list_head list; /* the ieee802154_priv->slaves list */ 74 struct list_head list; /* the ieee802154_priv->slaves list */
75 75
76 struct mac802154_priv *hw; 76 struct ieee802154_local *local;
77 struct net_device *dev; 77 struct net_device *dev;
78 78
79 int type; 79 int type;
80 bool running; 80 unsigned long state;
81 81
82 spinlock_t mib_lock; 82 spinlock_t mib_lock;
83 83
84 __le16 pan_id; 84 __le16 pan_id;
85 __le16 short_addr; 85 __le16 short_addr;
86 __le64 extended_addr; 86 __le64 extended_addr;
87 87 bool promisuous_mode;
88 u8 chan;
89 u8 page;
90 88
91 struct ieee802154_mac_params mac_params; 89 struct ieee802154_mac_params mac_params;
92 90
@@ -103,24 +101,36 @@ struct mac802154_sub_if_data {
103 struct mac802154_llsec sec; 101 struct mac802154_llsec sec;
104}; 102};
105 103
106#define mac802154_to_priv(_hw) container_of(_hw, struct mac802154_priv, hw)
107
108#define MAC802154_CHAN_NONE 0xff /* No channel is assigned */ 104#define MAC802154_CHAN_NONE 0xff /* No channel is assigned */
109 105
106static inline struct ieee802154_local *
107hw_to_local(struct ieee802154_hw *hw)
108{
109 return container_of(hw, struct ieee802154_local, hw);
110}
111
112static inline struct ieee802154_sub_if_data *
113IEEE802154_DEV_TO_SUB_IF(const struct net_device *dev)
114{
115 return netdev_priv(dev);
116}
117
118static inline bool
119ieee802154_sdata_running(struct ieee802154_sub_if_data *sdata)
120{
121 return test_bit(SDATA_STATE_RUNNING, &sdata->state);
122}
123
110extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced; 124extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced;
111extern struct ieee802154_mlme_ops mac802154_mlme_wpan; 125extern struct ieee802154_mlme_ops mac802154_mlme_wpan;
112 126
113int mac802154_slave_open(struct net_device *dev);
114int mac802154_slave_close(struct net_device *dev);
115
116void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb);
117void mac802154_monitor_setup(struct net_device *dev); 127void mac802154_monitor_setup(struct net_device *dev);
128netdev_tx_t
129ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);
118 130
119void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb);
120void mac802154_wpan_setup(struct net_device *dev); 131void mac802154_wpan_setup(struct net_device *dev);
121 132netdev_tx_t
122netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, 133ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
123 u8 page, u8 chan);
124 134
125/* MIB callbacks */ 135/* MIB callbacks */
126void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val); 136void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val);
@@ -131,11 +141,6 @@ void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val);
131void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan); 141void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan);
132u8 mac802154_dev_get_dsn(const struct net_device *dev); 142u8 mac802154_dev_get_dsn(const struct net_device *dev);
133 143
134int mac802154_set_mac_params(struct net_device *dev,
135 const struct ieee802154_mac_params *params);
136void mac802154_get_mac_params(struct net_device *dev,
137 struct ieee802154_mac_params *params);
138
139int mac802154_get_params(struct net_device *dev, 144int mac802154_get_params(struct net_device *dev,
140 struct ieee802154_llsec_params *params); 145 struct ieee802154_llsec_params *params);
141int mac802154_set_params(struct net_device *dev, 146int mac802154_set_params(struct net_device *dev,
@@ -169,4 +174,4 @@ void mac802154_get_table(struct net_device *dev,
169 struct ieee802154_llsec_table **t); 174 struct ieee802154_llsec_table **t);
170void mac802154_unlock_table(struct net_device *dev); 175void mac802154_unlock_table(struct net_device *dev);
171 176
172#endif /* MAC802154_H */ 177#endif /* __IEEE802154_I_H */
diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
new file mode 100644
index 000000000000..f7a6f83301e2
--- /dev/null
+++ b/net/mac802154/iface.c
@@ -0,0 +1,466 @@
1/*
2 * Copyright 2007-2012 Siemens AG
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * Written by:
14 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
15 * Sergey Lapin <slapin@ossfans.org>
16 * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
17 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
18 */
19
20#include <linux/netdevice.h>
21#include <linux/module.h>
22#include <linux/if_arp.h>
23#include <linux/ieee802154.h>
24
25#include <net/rtnetlink.h>
26#include <linux/nl802154.h>
27#include <net/af_ieee802154.h>
28#include <net/mac802154.h>
29#include <net/ieee802154_netdev.h>
30#include <net/cfg802154.h>
31
32#include "ieee802154_i.h"
33#include "driver-ops.h"
34
35static int mac802154_wpan_update_llsec(struct net_device *dev)
36{
37 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
38 struct ieee802154_mlme_ops *ops = ieee802154_mlme_ops(dev);
39 int rc = 0;
40
41 if (ops->llsec) {
42 struct ieee802154_llsec_params params;
43 int changed = 0;
44
45 params.pan_id = sdata->pan_id;
46 changed |= IEEE802154_LLSEC_PARAM_PAN_ID;
47
48 params.hwaddr = sdata->extended_addr;
49 changed |= IEEE802154_LLSEC_PARAM_HWADDR;
50
51 rc = ops->llsec->set_params(dev, &params, changed);
52 }
53
54 return rc;
55}
56
57static int
58mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
59{
60 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
61 struct sockaddr_ieee802154 *sa =
62 (struct sockaddr_ieee802154 *)&ifr->ifr_addr;
63 int err = -ENOIOCTLCMD;
64
65 spin_lock_bh(&sdata->mib_lock);
66
67 switch (cmd) {
68 case SIOCGIFADDR:
69 {
70 u16 pan_id, short_addr;
71
72 pan_id = le16_to_cpu(sdata->pan_id);
73 short_addr = le16_to_cpu(sdata->short_addr);
74 if (pan_id == IEEE802154_PANID_BROADCAST ||
75 short_addr == IEEE802154_ADDR_BROADCAST) {
76 err = -EADDRNOTAVAIL;
77 break;
78 }
79
80 sa->family = AF_IEEE802154;
81 sa->addr.addr_type = IEEE802154_ADDR_SHORT;
82 sa->addr.pan_id = pan_id;
83 sa->addr.short_addr = short_addr;
84
85 err = 0;
86 break;
87 }
88 case SIOCSIFADDR:
89 dev_warn(&dev->dev,
90 "Using DEBUGing ioctl SIOCSIFADDR isn't recommended!\n");
91 if (sa->family != AF_IEEE802154 ||
92 sa->addr.addr_type != IEEE802154_ADDR_SHORT ||
93 sa->addr.pan_id == IEEE802154_PANID_BROADCAST ||
94 sa->addr.short_addr == IEEE802154_ADDR_BROADCAST ||
95 sa->addr.short_addr == IEEE802154_ADDR_UNDEF) {
96 err = -EINVAL;
97 break;
98 }
99
100 sdata->pan_id = cpu_to_le16(sa->addr.pan_id);
101 sdata->short_addr = cpu_to_le16(sa->addr.short_addr);
102
103 err = mac802154_wpan_update_llsec(dev);
104 break;
105 }
106
107 spin_unlock_bh(&sdata->mib_lock);
108 return err;
109}
110
111static int mac802154_wpan_mac_addr(struct net_device *dev, void *p)
112{
113 struct sockaddr *addr = p;
114
115 if (netif_running(dev))
116 return -EBUSY;
117
118 /* FIXME: validate addr */
119 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
120 mac802154_dev_set_ieee_addr(dev);
121 return mac802154_wpan_update_llsec(dev);
122}
123
124int mac802154_set_mac_params(struct net_device *dev,
125 const struct ieee802154_mac_params *params)
126{
127 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
128
129 mutex_lock(&sdata->local->iflist_mtx);
130 sdata->mac_params = *params;
131 mutex_unlock(&sdata->local->iflist_mtx);
132
133 return 0;
134}
135
136void mac802154_get_mac_params(struct net_device *dev,
137 struct ieee802154_mac_params *params)
138{
139 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
140
141 mutex_lock(&sdata->local->iflist_mtx);
142 *params = sdata->mac_params;
143 mutex_unlock(&sdata->local->iflist_mtx);
144}
145
146static int mac802154_slave_open(struct net_device *dev)
147{
148 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
149 struct ieee802154_sub_if_data *subif;
150 struct ieee802154_local *local = sdata->local;
151 int res = 0;
152
153 ASSERT_RTNL();
154
155 if (sdata->type == IEEE802154_DEV_WPAN) {
156 mutex_lock(&sdata->local->iflist_mtx);
157 list_for_each_entry(subif, &sdata->local->interfaces, list) {
158 if (subif != sdata && subif->type == sdata->type &&
159 ieee802154_sdata_running(subif)) {
160 mutex_unlock(&sdata->local->iflist_mtx);
161 return -EBUSY;
162 }
163 }
164 mutex_unlock(&sdata->local->iflist_mtx);
165 }
166
167 set_bit(SDATA_STATE_RUNNING, &sdata->state);
168
169 if (!local->open_count) {
170 res = drv_start(local);
171 WARN_ON(res);
172 if (res)
173 goto err;
174 }
175
176 local->open_count++;
177 netif_start_queue(dev);
178 return 0;
179err:
180 /* might already be clear but that doesn't matter */
181 clear_bit(SDATA_STATE_RUNNING, &sdata->state);
182
183 return res;
184}
185
186static int mac802154_wpan_open(struct net_device *dev)
187{
188 int rc;
189 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
190 struct ieee802154_local *local = sdata->local;
191 struct wpan_phy *phy = sdata->local->phy;
192
193 rc = mac802154_slave_open(dev);
194 if (rc < 0)
195 return rc;
196
197 mutex_lock(&phy->pib_lock);
198
199 if (local->hw.flags & IEEE802154_HW_PROMISCUOUS) {
200 rc = drv_set_promiscuous_mode(local, sdata->promisuous_mode);
201 if (rc < 0)
202 goto out;
203 }
204
205 if (local->hw.flags & IEEE802154_HW_TXPOWER) {
206 rc = drv_set_tx_power(local, sdata->mac_params.transmit_power);
207 if (rc < 0)
208 goto out;
209 }
210
211 if (local->hw.flags & IEEE802154_HW_LBT) {
212 rc = drv_set_lbt_mode(local, sdata->mac_params.lbt);
213 if (rc < 0)
214 goto out;
215 }
216
217 if (local->hw.flags & IEEE802154_HW_CCA_MODE) {
218 rc = drv_set_cca_mode(local, sdata->mac_params.cca_mode);
219 if (rc < 0)
220 goto out;
221 }
222
223 if (local->hw.flags & IEEE802154_HW_CCA_ED_LEVEL) {
224 rc = drv_set_cca_ed_level(local,
225 sdata->mac_params.cca_ed_level);
226 if (rc < 0)
227 goto out;
228 }
229
230 if (local->hw.flags & IEEE802154_HW_CSMA_PARAMS) {
231 rc = drv_set_csma_params(local, sdata->mac_params.min_be,
232 sdata->mac_params.max_be,
233 sdata->mac_params.csma_retries);
234 if (rc < 0)
235 goto out;
236 }
237
238 if (local->hw.flags & IEEE802154_HW_FRAME_RETRIES) {
239 rc = drv_set_max_frame_retries(local,
240 sdata->mac_params.frame_retries);
241 if (rc < 0)
242 goto out;
243 }
244
245 mutex_unlock(&phy->pib_lock);
246 return 0;
247
248out:
249 mutex_unlock(&phy->pib_lock);
250 return rc;
251}
252
253static int mac802154_slave_close(struct net_device *dev)
254{
255 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
256 struct ieee802154_local *local = sdata->local;
257
258 ASSERT_RTNL();
259
260 netif_stop_queue(dev);
261 local->open_count--;
262
263 clear_bit(SDATA_STATE_RUNNING, &sdata->state);
264
265 if (!local->open_count)
266 drv_stop(local);
267
268 return 0;
269}
270
271static int mac802154_set_header_security(struct ieee802154_sub_if_data *sdata,
272 struct ieee802154_hdr *hdr,
273 const struct ieee802154_mac_cb *cb)
274{
275 struct ieee802154_llsec_params params;
276 u8 level;
277
278 mac802154_llsec_get_params(&sdata->sec, &params);
279
280 if (!params.enabled && cb->secen_override && cb->secen)
281 return -EINVAL;
282 if (!params.enabled ||
283 (cb->secen_override && !cb->secen) ||
284 !params.out_level)
285 return 0;
286 if (cb->seclevel_override && !cb->seclevel)
287 return -EINVAL;
288
289 level = cb->seclevel_override ? cb->seclevel : params.out_level;
290
291 hdr->fc.security_enabled = 1;
292 hdr->sec.level = level;
293 hdr->sec.key_id_mode = params.out_key.mode;
294 if (params.out_key.mode == IEEE802154_SCF_KEY_SHORT_INDEX)
295 hdr->sec.short_src = params.out_key.short_source;
296 else if (params.out_key.mode == IEEE802154_SCF_KEY_HW_INDEX)
297 hdr->sec.extended_src = params.out_key.extended_source;
298 hdr->sec.key_id = params.out_key.id;
299
300 return 0;
301}
302
303static int mac802154_header_create(struct sk_buff *skb,
304 struct net_device *dev,
305 unsigned short type,
306 const void *daddr,
307 const void *saddr,
308 unsigned len)
309{
310 struct ieee802154_hdr hdr;
311 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
312 struct ieee802154_mac_cb *cb = mac_cb(skb);
313 int hlen;
314
315 if (!daddr)
316 return -EINVAL;
317
318 memset(&hdr.fc, 0, sizeof(hdr.fc));
319 hdr.fc.type = cb->type;
320 hdr.fc.security_enabled = cb->secen;
321 hdr.fc.ack_request = cb->ackreq;
322 hdr.seq = ieee802154_mlme_ops(dev)->get_dsn(dev);
323
324 if (mac802154_set_header_security(sdata, &hdr, cb) < 0)
325 return -EINVAL;
326
327 if (!saddr) {
328 spin_lock_bh(&sdata->mib_lock);
329
330 if (sdata->short_addr == cpu_to_le16(IEEE802154_ADDR_BROADCAST) ||
331 sdata->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF) ||
332 sdata->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST)) {
333 hdr.source.mode = IEEE802154_ADDR_LONG;
334 hdr.source.extended_addr = sdata->extended_addr;
335 } else {
336 hdr.source.mode = IEEE802154_ADDR_SHORT;
337 hdr.source.short_addr = sdata->short_addr;
338 }
339
340 hdr.source.pan_id = sdata->pan_id;
341
342 spin_unlock_bh(&sdata->mib_lock);
343 } else {
344 hdr.source = *(const struct ieee802154_addr *)saddr;
345 }
346
347 hdr.dest = *(const struct ieee802154_addr *)daddr;
348
349 hlen = ieee802154_hdr_push(skb, &hdr);
350 if (hlen < 0)
351 return -EINVAL;
352
353 skb_reset_mac_header(skb);
354 skb->mac_len = hlen;
355
356 if (len > ieee802154_max_payload(&hdr))
357 return -EMSGSIZE;
358
359 return hlen;
360}
361
362static int
363mac802154_header_parse(const struct sk_buff *skb, unsigned char *haddr)
364{
365 struct ieee802154_hdr hdr;
366 struct ieee802154_addr *addr = (struct ieee802154_addr *)haddr;
367
368 if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0) {
369 pr_debug("malformed packet\n");
370 return 0;
371 }
372
373 *addr = hdr.source;
374 return sizeof(*addr);
375}
376
377static struct header_ops mac802154_header_ops = {
378 .create = mac802154_header_create,
379 .parse = mac802154_header_parse,
380};
381
382static const struct net_device_ops mac802154_wpan_ops = {
383 .ndo_open = mac802154_wpan_open,
384 .ndo_stop = mac802154_slave_close,
385 .ndo_start_xmit = ieee802154_subif_start_xmit,
386 .ndo_do_ioctl = mac802154_wpan_ioctl,
387 .ndo_set_mac_address = mac802154_wpan_mac_addr,
388};
389
390static const struct net_device_ops mac802154_monitor_ops = {
391 .ndo_open = mac802154_wpan_open,
392 .ndo_stop = mac802154_slave_close,
393 .ndo_start_xmit = ieee802154_monitor_start_xmit,
394};
395
396static void mac802154_wpan_free(struct net_device *dev)
397{
398 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
399
400 mac802154_llsec_destroy(&sdata->sec);
401
402 free_netdev(dev);
403}
404
405void mac802154_wpan_setup(struct net_device *dev)
406{
407 struct ieee802154_sub_if_data *sdata;
408
409 dev->addr_len = IEEE802154_ADDR_LEN;
410 memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN);
411
412 dev->hard_header_len = MAC802154_FRAME_HARD_HEADER_LEN;
413 dev->header_ops = &mac802154_header_ops;
414 dev->needed_tailroom = 2 + 16; /* FCS + MIC */
415 dev->mtu = IEEE802154_MTU;
416 dev->tx_queue_len = 300;
417 dev->type = ARPHRD_IEEE802154;
418 dev->flags = IFF_NOARP | IFF_BROADCAST;
419
420 dev->destructor = mac802154_wpan_free;
421 dev->netdev_ops = &mac802154_wpan_ops;
422 dev->ml_priv = &mac802154_mlme_wpan;
423
424 sdata = IEEE802154_DEV_TO_SUB_IF(dev);
425 sdata->type = IEEE802154_DEV_WPAN;
426
427 spin_lock_init(&sdata->mib_lock);
428 mutex_init(&sdata->sec_mtx);
429
430 get_random_bytes(&sdata->bsn, 1);
431 get_random_bytes(&sdata->dsn, 1);
432
433 /* defaults per 802.15.4-2011 */
434 sdata->mac_params.min_be = 3;
435 sdata->mac_params.max_be = 5;
436 sdata->mac_params.csma_retries = 4;
437 /* for compatibility, actual default is 3 */
438 sdata->mac_params.frame_retries = -1;
439
440 sdata->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST);
441 sdata->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
442
443 sdata->promisuous_mode = false;
444
445 mac802154_llsec_init(&sdata->sec);
446}
447
448void mac802154_monitor_setup(struct net_device *dev)
449{
450 struct ieee802154_sub_if_data *sdata;
451
452 dev->needed_tailroom = 2; /* room for FCS */
453 dev->mtu = IEEE802154_MTU;
454 dev->tx_queue_len = 10;
455 dev->type = ARPHRD_IEEE802154_MONITOR;
456 dev->flags = IFF_NOARP | IFF_BROADCAST;
457
458 dev->destructor = free_netdev;
459 dev->netdev_ops = &mac802154_monitor_ops;
460 dev->ml_priv = &mac802154_mlme_reduced;
461
462 sdata = IEEE802154_DEV_TO_SUB_IF(dev);
463 sdata->type = IEEE802154_DEV_MONITOR;
464
465 sdata->promisuous_mode = true;
466}
diff --git a/net/mac802154/llsec.c b/net/mac802154/llsec.c
index 457058142098..fa0d5237c2e0 100644
--- a/net/mac802154/llsec.c
+++ b/net/mac802154/llsec.c
@@ -17,10 +17,10 @@
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/bug.h> 18#include <linux/bug.h>
19#include <linux/completion.h> 19#include <linux/completion.h>
20#include <net/ieee802154.h> 20#include <linux/ieee802154.h>
21#include <crypto/algapi.h> 21#include <crypto/algapi.h>
22 22
23#include "mac802154.h" 23#include "ieee802154_i.h"
24#include "llsec.h" 24#include "llsec.h"
25 25
26static void llsec_key_put(struct mac802154_llsec_key *key); 26static void llsec_key_put(struct mac802154_llsec_key *key);
diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c
index bf809131eef7..fc261ab33347 100644
--- a/net/mac802154/mac_cmd.c
+++ b/net/mac802154/mac_cmd.c
@@ -12,10 +12,6 @@
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Written by: 15 * Written by:
20 * Sergey Lapin <slapin@ossfans.org> 16 * Sergey Lapin <slapin@ossfans.org>
21 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> 17 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
@@ -24,14 +20,14 @@
24 20
25#include <linux/skbuff.h> 21#include <linux/skbuff.h>
26#include <linux/if_arp.h> 22#include <linux/if_arp.h>
23#include <linux/ieee802154.h>
27 24
28#include <net/ieee802154.h>
29#include <net/ieee802154_netdev.h> 25#include <net/ieee802154_netdev.h>
30#include <net/wpan-phy.h> 26#include <net/cfg802154.h>
31#include <net/mac802154.h> 27#include <net/mac802154.h>
32#include <net/nl802154.h> 28#include <net/nl802154.h>
33 29
34#include "mac802154.h" 30#include "ieee802154_i.h"
35 31
36static int mac802154_mlme_start_req(struct net_device *dev, 32static int mac802154_mlme_start_req(struct net_device *dev,
37 struct ieee802154_addr *addr, 33 struct ieee802154_addr *addr,
@@ -79,11 +75,33 @@ static int mac802154_mlme_start_req(struct net_device *dev,
79 75
80static struct wpan_phy *mac802154_get_phy(const struct net_device *dev) 76static struct wpan_phy *mac802154_get_phy(const struct net_device *dev)
81{ 77{
82 struct mac802154_sub_if_data *priv = netdev_priv(dev); 78 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
83 79
84 BUG_ON(dev->type != ARPHRD_IEEE802154); 80 BUG_ON(dev->type != ARPHRD_IEEE802154);
85 81
86 return to_phy(get_device(&priv->hw->phy->dev)); 82 return to_phy(get_device(&sdata->local->phy->dev));
83}
84
85static int mac802154_set_mac_params(struct net_device *dev,
86 const struct ieee802154_mac_params *params)
87{
88 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
89
90 mutex_lock(&sdata->local->iflist_mtx);
91 sdata->mac_params = *params;
92 mutex_unlock(&sdata->local->iflist_mtx);
93
94 return 0;
95}
96
97static void mac802154_get_mac_params(struct net_device *dev,
98 struct ieee802154_mac_params *params)
99{
100 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
101
102 mutex_lock(&sdata->local->iflist_mtx);
103 *params = sdata->mac_params;
104 mutex_unlock(&sdata->local->iflist_mtx);
87} 105}
88 106
89static struct ieee802154_llsec_ops mac802154_llsec_ops = { 107static struct ieee802154_llsec_ops mac802154_llsec_ops = {
diff --git a/net/mac802154/main.c b/net/mac802154/main.c
new file mode 100644
index 000000000000..86e533ed3775
--- /dev/null
+++ b/net/mac802154/main.c
@@ -0,0 +1,265 @@
1/*
2 * Copyright (C) 2007-2012 Siemens AG
3 *
4 * Written by:
5 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
6 *
7 * Based on the code from 'linux-zigbee.sourceforge.net' project.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2
11 * as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/netdevice.h>
22
23#include <net/netlink.h>
24#include <linux/nl802154.h>
25#include <net/mac802154.h>
26#include <net/ieee802154_netdev.h>
27#include <net/route.h>
28#include <net/cfg802154.h>
29
30#include "ieee802154_i.h"
31
32static int
33mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev)
34{
35 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
36 struct ieee802154_local *local;
37 int err;
38
39 local = wpan_phy_priv(phy);
40
41 sdata->dev = dev;
42 sdata->local = local;
43
44 dev->needed_headroom = local->hw.extra_tx_headroom;
45
46 SET_NETDEV_DEV(dev, &local->phy->dev);
47
48 err = register_netdev(dev);
49 if (err < 0)
50 return err;
51
52 rtnl_lock();
53 mutex_lock(&local->iflist_mtx);
54 list_add_tail_rcu(&sdata->list, &local->interfaces);
55 mutex_unlock(&local->iflist_mtx);
56 rtnl_unlock();
57
58 return 0;
59}
60
61static void
62mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev)
63{
64 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
65
66 ASSERT_RTNL();
67
68 BUG_ON(sdata->local->phy != phy);
69
70 mutex_lock(&sdata->local->iflist_mtx);
71 list_del_rcu(&sdata->list);
72 mutex_unlock(&sdata->local->iflist_mtx);
73
74 synchronize_rcu();
75 unregister_netdevice(sdata->dev);
76}
77
78static struct net_device *
79mac802154_add_iface(struct wpan_phy *phy, const char *name, int type)
80{
81 struct net_device *dev;
82 int err = -ENOMEM;
83
84 switch (type) {
85 case IEEE802154_DEV_MONITOR:
86 dev = alloc_netdev(sizeof(struct ieee802154_sub_if_data),
87 name, NET_NAME_UNKNOWN,
88 mac802154_monitor_setup);
89 break;
90 case IEEE802154_DEV_WPAN:
91 dev = alloc_netdev(sizeof(struct ieee802154_sub_if_data),
92 name, NET_NAME_UNKNOWN,
93 mac802154_wpan_setup);
94 break;
95 default:
96 dev = NULL;
97 err = -EINVAL;
98 break;
99 }
100 if (!dev)
101 goto err;
102
103 err = mac802154_netdev_register(phy, dev);
104 if (err)
105 goto err_free;
106
107 dev_hold(dev); /* we return an incremented device refcount */
108 return dev;
109
110err_free:
111 free_netdev(dev);
112err:
113 return ERR_PTR(err);
114}
115
116static void ieee802154_tasklet_handler(unsigned long data)
117{
118 struct ieee802154_local *local = (struct ieee802154_local *)data;
119 struct sk_buff *skb;
120
121 while ((skb = skb_dequeue(&local->skb_queue))) {
122 switch (skb->pkt_type) {
123 case IEEE802154_RX_MSG:
124 /* Clear skb->pkt_type in order to not confuse kernel
125 * netstack.
126 */
127 skb->pkt_type = 0;
128 ieee802154_rx(&local->hw, skb);
129 break;
130 default:
131 WARN(1, "mac802154: Packet is of unknown type %d\n",
132 skb->pkt_type);
133 kfree_skb(skb);
134 break;
135 }
136 }
137}
138
139struct ieee802154_hw *
140ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
141{
142 struct wpan_phy *phy;
143 struct ieee802154_local *local;
144 size_t priv_size;
145
146 if (!ops || !(ops->xmit_async || ops->xmit_sync) || !ops->ed ||
147 !ops->start || !ops->stop || !ops->set_channel) {
148 pr_err("undefined IEEE802.15.4 device operations\n");
149 return NULL;
150 }
151
152 /* Ensure 32-byte alignment of our private data and hw private data.
153 * We use the wpan_phy priv data for both our ieee802154_local and for
154 * the driver's private data
155 *
156 * in memory it'll be like this:
157 *
158 * +-------------------------+
159 * | struct wpan_phy |
160 * +-------------------------+
161 * | struct ieee802154_local |
162 * +-------------------------+
163 * | driver's private data |
164 * +-------------------------+
165 *
166 * Due to ieee802154 layer isn't aware of driver and MAC structures,
167 * so lets align them here.
168 */
169
170 priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len;
171
172 phy = wpan_phy_alloc(priv_size);
173 if (!phy) {
174 pr_err("failure to allocate master IEEE802.15.4 device\n");
175 return NULL;
176 }
177
178 local = wpan_phy_priv(phy);
179 local->phy = phy;
180 local->hw.phy = local->phy;
181 local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN);
182 local->ops = ops;
183
184 INIT_LIST_HEAD(&local->interfaces);
185 mutex_init(&local->iflist_mtx);
186
187 tasklet_init(&local->tasklet,
188 ieee802154_tasklet_handler,
189 (unsigned long)local);
190
191 skb_queue_head_init(&local->skb_queue);
192
193 return &local->hw;
194}
195EXPORT_SYMBOL(ieee802154_alloc_hw);
196
197void ieee802154_free_hw(struct ieee802154_hw *hw)
198{
199 struct ieee802154_local *local = hw_to_local(hw);
200
201 BUG_ON(!list_empty(&local->interfaces));
202
203 mutex_destroy(&local->iflist_mtx);
204
205 wpan_phy_free(local->phy);
206}
207EXPORT_SYMBOL(ieee802154_free_hw);
208
209int ieee802154_register_hw(struct ieee802154_hw *hw)
210{
211 struct ieee802154_local *local = hw_to_local(hw);
212 int rc = -ENOSYS;
213
214 local->workqueue =
215 create_singlethread_workqueue(wpan_phy_name(local->phy));
216 if (!local->workqueue) {
217 rc = -ENOMEM;
218 goto out;
219 }
220
221 wpan_phy_set_dev(local->phy, local->hw.parent);
222
223 local->phy->add_iface = mac802154_add_iface;
224 local->phy->del_iface = mac802154_del_iface;
225
226 rc = wpan_phy_register(local->phy);
227 if (rc < 0)
228 goto out_wq;
229
230 return 0;
231
232out_wq:
233 destroy_workqueue(local->workqueue);
234out:
235 return rc;
236}
237EXPORT_SYMBOL(ieee802154_register_hw);
238
239void ieee802154_unregister_hw(struct ieee802154_hw *hw)
240{
241 struct ieee802154_local *local = hw_to_local(hw);
242 struct ieee802154_sub_if_data *sdata, *next;
243
244 tasklet_kill(&local->tasklet);
245 flush_workqueue(local->workqueue);
246 destroy_workqueue(local->workqueue);
247
248 rtnl_lock();
249
250 list_for_each_entry_safe(sdata, next, &local->interfaces, list) {
251 mutex_lock(&sdata->local->iflist_mtx);
252 list_del(&sdata->list);
253 mutex_unlock(&sdata->local->iflist_mtx);
254
255 unregister_netdevice(sdata->dev);
256 }
257
258 rtnl_unlock();
259
260 wpan_phy_unregister(local->phy);
261}
262EXPORT_SYMBOL(ieee802154_unregister_hw);
263
264MODULE_DESCRIPTION("IEEE 802.15.4 implementation");
265MODULE_LICENSE("GPL v2");
diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c
index 868a040fd422..0184fced2f62 100644
--- a/net/mac802154/mib.c
+++ b/net/mac802154/mib.c
@@ -10,10 +10,6 @@
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details. 11 * GNU General Public License for more details.
12 * 12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Written by: 13 * Written by:
18 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> 14 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
19 * Sergey Lapin <slapin@ossfans.org> 15 * Sergey Lapin <slapin@ossfans.org>
@@ -25,14 +21,10 @@
25 21
26#include <net/mac802154.h> 22#include <net/mac802154.h>
27#include <net/ieee802154_netdev.h> 23#include <net/ieee802154_netdev.h>
28#include <net/wpan-phy.h> 24#include <net/cfg802154.h>
29
30#include "mac802154.h"
31 25
32struct phy_chan_notify_work { 26#include "ieee802154_i.h"
33 struct work_struct work; 27#include "driver-ops.h"
34 struct net_device *dev;
35};
36 28
37struct hw_addr_filt_notify_work { 29struct hw_addr_filt_notify_work {
38 struct work_struct work; 30 struct work_struct work;
@@ -40,25 +32,24 @@ struct hw_addr_filt_notify_work {
40 unsigned long changed; 32 unsigned long changed;
41}; 33};
42 34
43static struct mac802154_priv *mac802154_slave_get_priv(struct net_device *dev) 35static struct ieee802154_local *mac802154_slave_get_priv(struct net_device *dev)
44{ 36{
45 struct mac802154_sub_if_data *priv = netdev_priv(dev); 37 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
46 38
47 BUG_ON(dev->type != ARPHRD_IEEE802154); 39 BUG_ON(dev->type != ARPHRD_IEEE802154);
48 40
49 return priv->hw; 41 return sdata->local;
50} 42}
51 43
52static void hw_addr_notify(struct work_struct *work) 44static void hw_addr_notify(struct work_struct *work)
53{ 45{
54 struct hw_addr_filt_notify_work *nw = container_of(work, 46 struct hw_addr_filt_notify_work *nw = container_of(work,
55 struct hw_addr_filt_notify_work, work); 47 struct hw_addr_filt_notify_work, work);
56 struct mac802154_priv *hw = mac802154_slave_get_priv(nw->dev); 48 struct ieee802154_local *local = mac802154_slave_get_priv(nw->dev);
57 int res; 49 int res;
58 50
59 res = hw->ops->set_hw_addr_filt(&hw->hw, 51 res = local->ops->set_hw_addr_filt(&local->hw, &local->hw.hw_filt,
60 &hw->hw.hw_filt, 52 nw->changed);
61 nw->changed);
62 if (res) 53 if (res)
63 pr_debug("failed changed mask %lx\n", nw->changed); 54 pr_debug("failed changed mask %lx\n", nw->changed);
64 55
@@ -67,7 +58,7 @@ static void hw_addr_notify(struct work_struct *work)
67 58
68static void set_hw_addr_filt(struct net_device *dev, unsigned long changed) 59static void set_hw_addr_filt(struct net_device *dev, unsigned long changed)
69{ 60{
70 struct mac802154_sub_if_data *priv = netdev_priv(dev); 61 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
71 struct hw_addr_filt_notify_work *work; 62 struct hw_addr_filt_notify_work *work;
72 63
73 work = kzalloc(sizeof(*work), GFP_ATOMIC); 64 work = kzalloc(sizeof(*work), GFP_ATOMIC);
@@ -77,141 +68,110 @@ static void set_hw_addr_filt(struct net_device *dev, unsigned long changed)
77 INIT_WORK(&work->work, hw_addr_notify); 68 INIT_WORK(&work->work, hw_addr_notify);
78 work->dev = dev; 69 work->dev = dev;
79 work->changed = changed; 70 work->changed = changed;
80 queue_work(priv->hw->dev_workqueue, &work->work); 71 queue_work(sdata->local->workqueue, &work->work);
81} 72}
82 73
83void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) 74void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val)
84{ 75{
85 struct mac802154_sub_if_data *priv = netdev_priv(dev); 76 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
86 77
87 BUG_ON(dev->type != ARPHRD_IEEE802154); 78 BUG_ON(dev->type != ARPHRD_IEEE802154);
88 79
89 spin_lock_bh(&priv->mib_lock); 80 spin_lock_bh(&sdata->mib_lock);
90 priv->short_addr = val; 81 sdata->short_addr = val;
91 spin_unlock_bh(&priv->mib_lock); 82 spin_unlock_bh(&sdata->mib_lock);
92 83
93 if ((priv->hw->ops->set_hw_addr_filt) && 84 if ((sdata->local->ops->set_hw_addr_filt) &&
94 (priv->hw->hw.hw_filt.short_addr != priv->short_addr)) { 85 (sdata->local->hw.hw_filt.short_addr != sdata->short_addr)) {
95 priv->hw->hw.hw_filt.short_addr = priv->short_addr; 86 sdata->local->hw.hw_filt.short_addr = sdata->short_addr;
96 set_hw_addr_filt(dev, IEEE802515_AFILT_SADDR_CHANGED); 87 set_hw_addr_filt(dev, IEEE802154_AFILT_SADDR_CHANGED);
97 } 88 }
98} 89}
99 90
100__le16 mac802154_dev_get_short_addr(const struct net_device *dev) 91__le16 mac802154_dev_get_short_addr(const struct net_device *dev)
101{ 92{
102 struct mac802154_sub_if_data *priv = netdev_priv(dev); 93 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
103 __le16 ret; 94 __le16 ret;
104 95
105 BUG_ON(dev->type != ARPHRD_IEEE802154); 96 BUG_ON(dev->type != ARPHRD_IEEE802154);
106 97
107 spin_lock_bh(&priv->mib_lock); 98 spin_lock_bh(&sdata->mib_lock);
108 ret = priv->short_addr; 99 ret = sdata->short_addr;
109 spin_unlock_bh(&priv->mib_lock); 100 spin_unlock_bh(&sdata->mib_lock);
110 101
111 return ret; 102 return ret;
112} 103}
113 104
114void mac802154_dev_set_ieee_addr(struct net_device *dev) 105void mac802154_dev_set_ieee_addr(struct net_device *dev)
115{ 106{
116 struct mac802154_sub_if_data *priv = netdev_priv(dev); 107 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
117 struct mac802154_priv *mac = priv->hw; 108 struct ieee802154_local *local = sdata->local;
118 109
119 priv->extended_addr = ieee802154_devaddr_from_raw(dev->dev_addr); 110 sdata->extended_addr = ieee802154_devaddr_from_raw(dev->dev_addr);
120 111
121 if (mac->ops->set_hw_addr_filt && 112 if (local->ops->set_hw_addr_filt &&
122 mac->hw.hw_filt.ieee_addr != priv->extended_addr) { 113 local->hw.hw_filt.ieee_addr != sdata->extended_addr) {
123 mac->hw.hw_filt.ieee_addr = priv->extended_addr; 114 local->hw.hw_filt.ieee_addr = sdata->extended_addr;
124 set_hw_addr_filt(dev, IEEE802515_AFILT_IEEEADDR_CHANGED); 115 set_hw_addr_filt(dev, IEEE802154_AFILT_IEEEADDR_CHANGED);
125 } 116 }
126} 117}
127 118
128__le16 mac802154_dev_get_pan_id(const struct net_device *dev) 119__le16 mac802154_dev_get_pan_id(const struct net_device *dev)
129{ 120{
130 struct mac802154_sub_if_data *priv = netdev_priv(dev); 121 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
131 __le16 ret; 122 __le16 ret;
132 123
133 BUG_ON(dev->type != ARPHRD_IEEE802154); 124 BUG_ON(dev->type != ARPHRD_IEEE802154);
134 125
135 spin_lock_bh(&priv->mib_lock); 126 spin_lock_bh(&sdata->mib_lock);
136 ret = priv->pan_id; 127 ret = sdata->pan_id;
137 spin_unlock_bh(&priv->mib_lock); 128 spin_unlock_bh(&sdata->mib_lock);
138 129
139 return ret; 130 return ret;
140} 131}
141 132
142void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val) 133void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val)
143{ 134{
144 struct mac802154_sub_if_data *priv = netdev_priv(dev); 135 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
145 136
146 BUG_ON(dev->type != ARPHRD_IEEE802154); 137 BUG_ON(dev->type != ARPHRD_IEEE802154);
147 138
148 spin_lock_bh(&priv->mib_lock); 139 spin_lock_bh(&sdata->mib_lock);
149 priv->pan_id = val; 140 sdata->pan_id = val;
150 spin_unlock_bh(&priv->mib_lock); 141 spin_unlock_bh(&sdata->mib_lock);
151 142
152 if ((priv->hw->ops->set_hw_addr_filt) && 143 if ((sdata->local->ops->set_hw_addr_filt) &&
153 (priv->hw->hw.hw_filt.pan_id != priv->pan_id)) { 144 (sdata->local->hw.hw_filt.pan_id != sdata->pan_id)) {
154 priv->hw->hw.hw_filt.pan_id = priv->pan_id; 145 sdata->local->hw.hw_filt.pan_id = sdata->pan_id;
155 set_hw_addr_filt(dev, IEEE802515_AFILT_PANID_CHANGED); 146 set_hw_addr_filt(dev, IEEE802154_AFILT_PANID_CHANGED);
156 } 147 }
157} 148}
158 149
159u8 mac802154_dev_get_dsn(const struct net_device *dev) 150u8 mac802154_dev_get_dsn(const struct net_device *dev)
160{ 151{
161 struct mac802154_sub_if_data *priv = netdev_priv(dev); 152 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
162 153
163 BUG_ON(dev->type != ARPHRD_IEEE802154); 154 BUG_ON(dev->type != ARPHRD_IEEE802154);
164 155
165 return priv->dsn++; 156 return sdata->dsn++;
166}
167
168static void phy_chan_notify(struct work_struct *work)
169{
170 struct phy_chan_notify_work *nw = container_of(work,
171 struct phy_chan_notify_work, work);
172 struct mac802154_priv *hw = mac802154_slave_get_priv(nw->dev);
173 struct mac802154_sub_if_data *priv = netdev_priv(nw->dev);
174 int res;
175
176 mutex_lock(&priv->hw->phy->pib_lock);
177 res = hw->ops->set_channel(&hw->hw, priv->page, priv->chan);
178 if (res) {
179 pr_debug("set_channel failed\n");
180 } else {
181 priv->hw->phy->current_channel = priv->chan;
182 priv->hw->phy->current_page = priv->page;
183 }
184 mutex_unlock(&priv->hw->phy->pib_lock);
185
186 kfree(nw);
187} 157}
188 158
189void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) 159void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan)
190{ 160{
191 struct mac802154_sub_if_data *priv = netdev_priv(dev); 161 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
192 struct phy_chan_notify_work *work; 162 struct ieee802154_local *local = sdata->local;
163 int res;
193 164
194 BUG_ON(dev->type != ARPHRD_IEEE802154); 165 BUG_ON(dev->type != ARPHRD_IEEE802154);
195 166
196 spin_lock_bh(&priv->mib_lock); 167 res = drv_set_channel(local, page, chan);
197 priv->page = page; 168 if (res) {
198 priv->chan = chan; 169 pr_debug("set_channel failed\n");
199 spin_unlock_bh(&priv->mib_lock);
200
201 mutex_lock(&priv->hw->phy->pib_lock);
202 if (priv->hw->phy->current_channel != priv->chan ||
203 priv->hw->phy->current_page != priv->page) {
204 mutex_unlock(&priv->hw->phy->pib_lock);
205
206 work = kzalloc(sizeof(*work), GFP_ATOMIC);
207 if (!work)
208 return;
209
210 INIT_WORK(&work->work, phy_chan_notify);
211 work->dev = dev;
212 queue_work(priv->hw->dev_workqueue, &work->work);
213 } else { 170 } else {
214 mutex_unlock(&priv->hw->phy->pib_lock); 171 mutex_lock(&local->phy->pib_lock);
172 local->phy->current_channel = chan;
173 local->phy->current_page = page;
174 mutex_unlock(&local->phy->pib_lock);
215 } 175 }
216} 176}
217 177
@@ -219,14 +179,14 @@ void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan)
219int mac802154_get_params(struct net_device *dev, 179int mac802154_get_params(struct net_device *dev,
220 struct ieee802154_llsec_params *params) 180 struct ieee802154_llsec_params *params)
221{ 181{
222 struct mac802154_sub_if_data *priv = netdev_priv(dev); 182 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
223 int res; 183 int res;
224 184
225 BUG_ON(dev->type != ARPHRD_IEEE802154); 185 BUG_ON(dev->type != ARPHRD_IEEE802154);
226 186
227 mutex_lock(&priv->sec_mtx); 187 mutex_lock(&sdata->sec_mtx);
228 res = mac802154_llsec_get_params(&priv->sec, params); 188 res = mac802154_llsec_get_params(&sdata->sec, params);
229 mutex_unlock(&priv->sec_mtx); 189 mutex_unlock(&sdata->sec_mtx);
230 190
231 return res; 191 return res;
232} 192}
@@ -235,14 +195,14 @@ int mac802154_set_params(struct net_device *dev,
235 const struct ieee802154_llsec_params *params, 195 const struct ieee802154_llsec_params *params,
236 int changed) 196 int changed)
237{ 197{
238 struct mac802154_sub_if_data *priv = netdev_priv(dev); 198 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
239 int res; 199 int res;
240 200
241 BUG_ON(dev->type != ARPHRD_IEEE802154); 201 BUG_ON(dev->type != ARPHRD_IEEE802154);
242 202
243 mutex_lock(&priv->sec_mtx); 203 mutex_lock(&sdata->sec_mtx);
244 res = mac802154_llsec_set_params(&priv->sec, params, changed); 204 res = mac802154_llsec_set_params(&sdata->sec, params, changed);
245 mutex_unlock(&priv->sec_mtx); 205 mutex_unlock(&sdata->sec_mtx);
246 206
247 return res; 207 return res;
248} 208}
@@ -252,14 +212,14 @@ int mac802154_add_key(struct net_device *dev,
252 const struct ieee802154_llsec_key_id *id, 212 const struct ieee802154_llsec_key_id *id,
253 const struct ieee802154_llsec_key *key) 213 const struct ieee802154_llsec_key *key)
254{ 214{
255 struct mac802154_sub_if_data *priv = netdev_priv(dev); 215 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
256 int res; 216 int res;
257 217
258 BUG_ON(dev->type != ARPHRD_IEEE802154); 218 BUG_ON(dev->type != ARPHRD_IEEE802154);
259 219
260 mutex_lock(&priv->sec_mtx); 220 mutex_lock(&sdata->sec_mtx);
261 res = mac802154_llsec_key_add(&priv->sec, id, key); 221 res = mac802154_llsec_key_add(&sdata->sec, id, key);
262 mutex_unlock(&priv->sec_mtx); 222 mutex_unlock(&sdata->sec_mtx);
263 223
264 return res; 224 return res;
265} 225}
@@ -267,14 +227,14 @@ int mac802154_add_key(struct net_device *dev,
267int mac802154_del_key(struct net_device *dev, 227int mac802154_del_key(struct net_device *dev,
268 const struct ieee802154_llsec_key_id *id) 228 const struct ieee802154_llsec_key_id *id)
269{ 229{
270 struct mac802154_sub_if_data *priv = netdev_priv(dev); 230 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
271 int res; 231 int res;
272 232
273 BUG_ON(dev->type != ARPHRD_IEEE802154); 233 BUG_ON(dev->type != ARPHRD_IEEE802154);
274 234
275 mutex_lock(&priv->sec_mtx); 235 mutex_lock(&sdata->sec_mtx);
276 res = mac802154_llsec_key_del(&priv->sec, id); 236 res = mac802154_llsec_key_del(&sdata->sec, id);
277 mutex_unlock(&priv->sec_mtx); 237 mutex_unlock(&sdata->sec_mtx);
278 238
279 return res; 239 return res;
280} 240}
@@ -283,28 +243,28 @@ int mac802154_del_key(struct net_device *dev,
283int mac802154_add_dev(struct net_device *dev, 243int mac802154_add_dev(struct net_device *dev,
284 const struct ieee802154_llsec_device *llsec_dev) 244 const struct ieee802154_llsec_device *llsec_dev)
285{ 245{
286 struct mac802154_sub_if_data *priv = netdev_priv(dev); 246 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
287 int res; 247 int res;
288 248
289 BUG_ON(dev->type != ARPHRD_IEEE802154); 249 BUG_ON(dev->type != ARPHRD_IEEE802154);
290 250
291 mutex_lock(&priv->sec_mtx); 251 mutex_lock(&sdata->sec_mtx);
292 res = mac802154_llsec_dev_add(&priv->sec, llsec_dev); 252 res = mac802154_llsec_dev_add(&sdata->sec, llsec_dev);
293 mutex_unlock(&priv->sec_mtx); 253 mutex_unlock(&sdata->sec_mtx);
294 254
295 return res; 255 return res;
296} 256}
297 257
298int mac802154_del_dev(struct net_device *dev, __le64 dev_addr) 258int mac802154_del_dev(struct net_device *dev, __le64 dev_addr)
299{ 259{
300 struct mac802154_sub_if_data *priv = netdev_priv(dev); 260 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
301 int res; 261 int res;
302 262
303 BUG_ON(dev->type != ARPHRD_IEEE802154); 263 BUG_ON(dev->type != ARPHRD_IEEE802154);
304 264
305 mutex_lock(&priv->sec_mtx); 265 mutex_lock(&sdata->sec_mtx);
306 res = mac802154_llsec_dev_del(&priv->sec, dev_addr); 266 res = mac802154_llsec_dev_del(&sdata->sec, dev_addr);
307 mutex_unlock(&priv->sec_mtx); 267 mutex_unlock(&sdata->sec_mtx);
308 268
309 return res; 269 return res;
310} 270}
@@ -314,14 +274,14 @@ int mac802154_add_devkey(struct net_device *dev,
314 __le64 device_addr, 274 __le64 device_addr,
315 const struct ieee802154_llsec_device_key *key) 275 const struct ieee802154_llsec_device_key *key)
316{ 276{
317 struct mac802154_sub_if_data *priv = netdev_priv(dev); 277 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
318 int res; 278 int res;
319 279
320 BUG_ON(dev->type != ARPHRD_IEEE802154); 280 BUG_ON(dev->type != ARPHRD_IEEE802154);
321 281
322 mutex_lock(&priv->sec_mtx); 282 mutex_lock(&sdata->sec_mtx);
323 res = mac802154_llsec_devkey_add(&priv->sec, device_addr, key); 283 res = mac802154_llsec_devkey_add(&sdata->sec, device_addr, key);
324 mutex_unlock(&priv->sec_mtx); 284 mutex_unlock(&sdata->sec_mtx);
325 285
326 return res; 286 return res;
327} 287}
@@ -330,14 +290,14 @@ int mac802154_del_devkey(struct net_device *dev,
330 __le64 device_addr, 290 __le64 device_addr,
331 const struct ieee802154_llsec_device_key *key) 291 const struct ieee802154_llsec_device_key *key)
332{ 292{
333 struct mac802154_sub_if_data *priv = netdev_priv(dev); 293 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
334 int res; 294 int res;
335 295
336 BUG_ON(dev->type != ARPHRD_IEEE802154); 296 BUG_ON(dev->type != ARPHRD_IEEE802154);
337 297
338 mutex_lock(&priv->sec_mtx); 298 mutex_lock(&sdata->sec_mtx);
339 res = mac802154_llsec_devkey_del(&priv->sec, device_addr, key); 299 res = mac802154_llsec_devkey_del(&sdata->sec, device_addr, key);
340 mutex_unlock(&priv->sec_mtx); 300 mutex_unlock(&sdata->sec_mtx);
341 301
342 return res; 302 return res;
343} 303}
@@ -346,14 +306,14 @@ int mac802154_del_devkey(struct net_device *dev,
346int mac802154_add_seclevel(struct net_device *dev, 306int mac802154_add_seclevel(struct net_device *dev,
347 const struct ieee802154_llsec_seclevel *sl) 307 const struct ieee802154_llsec_seclevel *sl)
348{ 308{
349 struct mac802154_sub_if_data *priv = netdev_priv(dev); 309 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
350 int res; 310 int res;
351 311
352 BUG_ON(dev->type != ARPHRD_IEEE802154); 312 BUG_ON(dev->type != ARPHRD_IEEE802154);
353 313
354 mutex_lock(&priv->sec_mtx); 314 mutex_lock(&sdata->sec_mtx);
355 res = mac802154_llsec_seclevel_add(&priv->sec, sl); 315 res = mac802154_llsec_seclevel_add(&sdata->sec, sl);
356 mutex_unlock(&priv->sec_mtx); 316 mutex_unlock(&sdata->sec_mtx);
357 317
358 return res; 318 return res;
359} 319}
@@ -361,14 +321,14 @@ int mac802154_add_seclevel(struct net_device *dev,
361int mac802154_del_seclevel(struct net_device *dev, 321int mac802154_del_seclevel(struct net_device *dev,
362 const struct ieee802154_llsec_seclevel *sl) 322 const struct ieee802154_llsec_seclevel *sl)
363{ 323{
364 struct mac802154_sub_if_data *priv = netdev_priv(dev); 324 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
365 int res; 325 int res;
366 326
367 BUG_ON(dev->type != ARPHRD_IEEE802154); 327 BUG_ON(dev->type != ARPHRD_IEEE802154);
368 328
369 mutex_lock(&priv->sec_mtx); 329 mutex_lock(&sdata->sec_mtx);
370 res = mac802154_llsec_seclevel_del(&priv->sec, sl); 330 res = mac802154_llsec_seclevel_del(&sdata->sec, sl);
371 mutex_unlock(&priv->sec_mtx); 331 mutex_unlock(&sdata->sec_mtx);
372 332
373 return res; 333 return res;
374} 334}
@@ -376,28 +336,28 @@ int mac802154_del_seclevel(struct net_device *dev,
376 336
377void mac802154_lock_table(struct net_device *dev) 337void mac802154_lock_table(struct net_device *dev)
378{ 338{
379 struct mac802154_sub_if_data *priv = netdev_priv(dev); 339 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
380 340
381 BUG_ON(dev->type != ARPHRD_IEEE802154); 341 BUG_ON(dev->type != ARPHRD_IEEE802154);
382 342
383 mutex_lock(&priv->sec_mtx); 343 mutex_lock(&sdata->sec_mtx);
384} 344}
385 345
386void mac802154_get_table(struct net_device *dev, 346void mac802154_get_table(struct net_device *dev,
387 struct ieee802154_llsec_table **t) 347 struct ieee802154_llsec_table **t)
388{ 348{
389 struct mac802154_sub_if_data *priv = netdev_priv(dev); 349 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
390 350
391 BUG_ON(dev->type != ARPHRD_IEEE802154); 351 BUG_ON(dev->type != ARPHRD_IEEE802154);
392 352
393 *t = &priv->sec.table; 353 *t = &sdata->sec.table;
394} 354}
395 355
396void mac802154_unlock_table(struct net_device *dev) 356void mac802154_unlock_table(struct net_device *dev)
397{ 357{
398 struct mac802154_sub_if_data *priv = netdev_priv(dev); 358 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
399 359
400 BUG_ON(dev->type != ARPHRD_IEEE802154); 360 BUG_ON(dev->type != ARPHRD_IEEE802154);
401 361
402 mutex_unlock(&priv->sec_mtx); 362 mutex_unlock(&sdata->sec_mtx);
403} 363}
diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c
deleted file mode 100644
index a68230e2b25f..000000000000
--- a/net/mac802154/monitor.c
+++ /dev/null
@@ -1,117 +0,0 @@
1/*
2 * Copyright 2007, 2008, 2009 Siemens AG
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Written by:
18 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
19 * Sergey Lapin <slapin@ossfans.org>
20 * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
21 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
22 */
23
24#include <linux/netdevice.h>
25#include <linux/skbuff.h>
26#include <linux/if_arp.h>
27#include <linux/crc-ccitt.h>
28
29#include <net/ieee802154.h>
30#include <net/mac802154.h>
31#include <net/netlink.h>
32#include <net/wpan-phy.h>
33#include <linux/nl802154.h>
34
35#include "mac802154.h"
36
37static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb,
38 struct net_device *dev)
39{
40 struct mac802154_sub_if_data *priv;
41 u8 chan, page;
42
43 priv = netdev_priv(dev);
44
45 /* FIXME: locking */
46 chan = priv->hw->phy->current_channel;
47 page = priv->hw->phy->current_page;
48
49 if (chan == MAC802154_CHAN_NONE) /* not initialized */
50 return NETDEV_TX_OK;
51
52 if (WARN_ON(page >= WPAN_NUM_PAGES) ||
53 WARN_ON(chan >= WPAN_NUM_CHANNELS))
54 return NETDEV_TX_OK;
55
56 skb->skb_iif = dev->ifindex;
57 dev->stats.tx_packets++;
58 dev->stats.tx_bytes += skb->len;
59
60 return mac802154_tx(priv->hw, skb, page, chan);
61}
62
63
64void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb)
65{
66 struct sk_buff *skb2;
67 struct mac802154_sub_if_data *sdata;
68 u16 crc = crc_ccitt(0, skb->data, skb->len);
69 u8 *data;
70
71 rcu_read_lock();
72 list_for_each_entry_rcu(sdata, &priv->slaves, list) {
73 if (sdata->type != IEEE802154_DEV_MONITOR ||
74 !netif_running(sdata->dev))
75 continue;
76
77 skb2 = skb_clone(skb, GFP_ATOMIC);
78 skb2->dev = sdata->dev;
79 skb2->pkt_type = PACKET_HOST;
80 data = skb_put(skb2, 2);
81 data[0] = crc & 0xff;
82 data[1] = crc >> 8;
83
84 netif_rx_ni(skb2);
85 }
86 rcu_read_unlock();
87}
88
89static const struct net_device_ops mac802154_monitor_ops = {
90 .ndo_open = mac802154_slave_open,
91 .ndo_stop = mac802154_slave_close,
92 .ndo_start_xmit = mac802154_monitor_xmit,
93};
94
95void mac802154_monitor_setup(struct net_device *dev)
96{
97 struct mac802154_sub_if_data *priv;
98
99 dev->addr_len = 0;
100 dev->hard_header_len = 0;
101 dev->needed_tailroom = 2; /* room for FCS */
102 dev->mtu = IEEE802154_MTU;
103 dev->tx_queue_len = 10;
104 dev->type = ARPHRD_IEEE802154_MONITOR;
105 dev->flags = IFF_NOARP | IFF_BROADCAST;
106 dev->watchdog_timeo = 0;
107
108 dev->destructor = free_netdev;
109 dev->netdev_ops = &mac802154_monitor_ops;
110 dev->ml_priv = &mac802154_mlme_reduced;
111
112 priv = netdev_priv(dev);
113 priv->type = IEEE802154_DEV_MONITOR;
114
115 priv->chan = MAC802154_CHAN_NONE; /* not initialized */
116 priv->page = 0;
117}
diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
index a14cf9ede171..95961cccc253 100644
--- a/net/mac802154/rx.c
+++ b/net/mac802154/rx.c
@@ -10,10 +10,6 @@
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details. 11 * GNU General Public License for more details.
12 * 12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Written by: 13 * Written by:
18 * Pavel Smolenskiy <pavel.smolenskiy@gmail.com> 14 * Pavel Smolenskiy <pavel.smolenskiy@gmail.com>
19 * Maxim Gorbachyov <maxim.gorbachev@siemens.com> 15 * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
@@ -23,92 +19,285 @@
23 19
24#include <linux/kernel.h> 20#include <linux/kernel.h>
25#include <linux/module.h> 21#include <linux/module.h>
26#include <linux/workqueue.h>
27#include <linux/netdevice.h> 22#include <linux/netdevice.h>
28#include <linux/crc-ccitt.h> 23#include <linux/crc-ccitt.h>
24#include <asm/unaligned.h>
29 25
30#include <net/mac802154.h> 26#include <net/mac802154.h>
31#include <net/ieee802154_netdev.h> 27#include <net/ieee802154_netdev.h>
28#include <net/rtnetlink.h>
29#include <linux/nl802154.h>
32 30
33#include "mac802154.h" 31#include "ieee802154_i.h"
34 32
35/* The IEEE 802.15.4 standard defines 4 MAC packet types: 33static int ieee802154_deliver_skb(struct sk_buff *skb)
36 * - beacon frame 34{
37 * - MAC command frame 35 skb->ip_summed = CHECKSUM_UNNECESSARY;
38 * - acknowledgement frame 36 skb->protocol = htons(ETH_P_IEEE802154);
39 * - data frame
40 *
41 * and only the data frame should be pushed to the upper layers, other types
42 * are just internal MAC layer management information. So only data packets
43 * are going to be sent to the networking queue, all other will be processed
44 * right here by using the device workqueue.
45 */
46struct rx_work {
47 struct sk_buff *skb;
48 struct work_struct work;
49 struct ieee802154_dev *dev;
50 u8 lqi;
51};
52 37
53static void 38 return netif_receive_skb(skb);
54mac802154_subif_rx(struct ieee802154_dev *hw, struct sk_buff *skb, u8 lqi) 39}
40
41static int
42ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata,
43 struct sk_buff *skb, const struct ieee802154_hdr *hdr)
55{ 44{
56 struct mac802154_priv *priv = mac802154_to_priv(hw); 45 __le16 span, sshort;
46 int rc;
57 47
58 mac_cb(skb)->lqi = lqi; 48 pr_debug("getting packet via slave interface %s\n", sdata->dev->name);
59 skb->protocol = htons(ETH_P_IEEE802154);
60 skb_reset_mac_header(skb);
61 49
62 if (!(priv->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { 50 spin_lock_bh(&sdata->mib_lock);
63 u16 crc;
64 51
65 if (skb->len < 2) { 52 span = sdata->pan_id;
66 pr_debug("got invalid frame\n"); 53 sshort = sdata->short_addr;
67 goto fail; 54
68 } 55 switch (mac_cb(skb)->dest.mode) {
69 crc = crc_ccitt(0, skb->data, skb->len); 56 case IEEE802154_ADDR_NONE:
70 if (crc) { 57 if (mac_cb(skb)->dest.mode != IEEE802154_ADDR_NONE)
71 pr_debug("CRC mismatch\n"); 58 /* FIXME: check if we are PAN coordinator */
72 goto fail; 59 skb->pkt_type = PACKET_OTHERHOST;
73 } 60 else
74 skb_trim(skb, skb->len - 2); /* CRC */ 61 /* ACK comes with both addresses empty */
62 skb->pkt_type = PACKET_HOST;
63 break;
64 case IEEE802154_ADDR_LONG:
65 if (mac_cb(skb)->dest.pan_id != span &&
66 mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST))
67 skb->pkt_type = PACKET_OTHERHOST;
68 else if (mac_cb(skb)->dest.extended_addr == sdata->extended_addr)
69 skb->pkt_type = PACKET_HOST;
70 else
71 skb->pkt_type = PACKET_OTHERHOST;
72 break;
73 case IEEE802154_ADDR_SHORT:
74 if (mac_cb(skb)->dest.pan_id != span &&
75 mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST))
76 skb->pkt_type = PACKET_OTHERHOST;
77 else if (mac_cb(skb)->dest.short_addr == sshort)
78 skb->pkt_type = PACKET_HOST;
79 else if (mac_cb(skb)->dest.short_addr ==
80 cpu_to_le16(IEEE802154_ADDR_BROADCAST))
81 skb->pkt_type = PACKET_BROADCAST;
82 else
83 skb->pkt_type = PACKET_OTHERHOST;
84 break;
85 default:
86 spin_unlock_bh(&sdata->mib_lock);
87 pr_debug("invalid dest mode\n");
88 kfree_skb(skb);
89 return NET_RX_DROP;
75 } 90 }
76 91
77 mac802154_monitors_rx(priv, skb); 92 spin_unlock_bh(&sdata->mib_lock);
78 mac802154_wpans_rx(priv, skb);
79 93
80 return; 94 skb->dev = sdata->dev;
95
96 rc = mac802154_llsec_decrypt(&sdata->sec, skb);
97 if (rc) {
98 pr_debug("decryption failed: %i\n", rc);
99 goto fail;
100 }
101
102 sdata->dev->stats.rx_packets++;
103 sdata->dev->stats.rx_bytes += skb->len;
104
105 switch (mac_cb(skb)->type) {
106 case IEEE802154_FC_TYPE_DATA:
107 return ieee802154_deliver_skb(skb);
108 default:
109 pr_warn("ieee802154: bad frame received (type = %d)\n",
110 mac_cb(skb)->type);
111 goto fail;
112 }
81 113
82fail: 114fail:
83 kfree_skb(skb); 115 kfree_skb(skb);
116 return NET_RX_DROP;
84} 117}
85 118
86static void mac802154_rx_worker(struct work_struct *work) 119static void
120ieee802154_print_addr(const char *name, const struct ieee802154_addr *addr)
87{ 121{
88 struct rx_work *rw = container_of(work, struct rx_work, work); 122 if (addr->mode == IEEE802154_ADDR_NONE)
123 pr_debug("%s not present\n", name);
124
125 pr_debug("%s PAN ID: %04x\n", name, le16_to_cpu(addr->pan_id));
126 if (addr->mode == IEEE802154_ADDR_SHORT) {
127 pr_debug("%s is short: %04x\n", name,
128 le16_to_cpu(addr->short_addr));
129 } else {
130 u64 hw = swab64((__force u64)addr->extended_addr);
89 131
90 mac802154_subif_rx(rw->dev, rw->skb, rw->lqi); 132 pr_debug("%s is hardware: %8phC\n", name, &hw);
91 kfree(rw); 133 }
92} 134}
93 135
94void 136static int
95ieee802154_rx_irqsafe(struct ieee802154_dev *dev, struct sk_buff *skb, u8 lqi) 137ieee802154_parse_frame_start(struct sk_buff *skb, struct ieee802154_hdr *hdr)
96{ 138{
97 struct mac802154_priv *priv = mac802154_to_priv(dev); 139 int hlen;
98 struct rx_work *work; 140 struct ieee802154_mac_cb *cb = mac_cb_init(skb);
99 141
100 if (!skb) 142 skb_reset_mac_header(skb);
101 return; 143
144 hlen = ieee802154_hdr_pull(skb, hdr);
145 if (hlen < 0)
146 return -EINVAL;
147
148 skb->mac_len = hlen;
149
150 pr_debug("fc: %04x dsn: %02x\n", le16_to_cpup((__le16 *)&hdr->fc),
151 hdr->seq);
152
153 cb->type = hdr->fc.type;
154 cb->ackreq = hdr->fc.ack_request;
155 cb->secen = hdr->fc.security_enabled;
156
157 ieee802154_print_addr("destination", &hdr->dest);
158 ieee802154_print_addr("source", &hdr->source);
159
160 cb->source = hdr->source;
161 cb->dest = hdr->dest;
162
163 if (hdr->fc.security_enabled) {
164 u64 key;
165
166 pr_debug("seclevel %i\n", hdr->sec.level);
167
168 switch (hdr->sec.key_id_mode) {
169 case IEEE802154_SCF_KEY_IMPLICIT:
170 pr_debug("implicit key\n");
171 break;
172
173 case IEEE802154_SCF_KEY_INDEX:
174 pr_debug("key %02x\n", hdr->sec.key_id);
175 break;
176
177 case IEEE802154_SCF_KEY_SHORT_INDEX:
178 pr_debug("key %04x:%04x %02x\n",
179 le32_to_cpu(hdr->sec.short_src) >> 16,
180 le32_to_cpu(hdr->sec.short_src) & 0xffff,
181 hdr->sec.key_id);
182 break;
183
184 case IEEE802154_SCF_KEY_HW_INDEX:
185 key = swab64((__force u64)hdr->sec.extended_src);
186 pr_debug("key source %8phC %02x\n", &key,
187 hdr->sec.key_id);
188 break;
189 }
190 }
191
192 return 0;
193}
194
195static void
196__ieee802154_rx_handle_packet(struct ieee802154_local *local,
197 struct sk_buff *skb)
198{
199 int ret;
200 struct ieee802154_sub_if_data *sdata;
201 struct ieee802154_hdr hdr;
102 202
103 work = kzalloc(sizeof(*work), GFP_ATOMIC); 203 ret = ieee802154_parse_frame_start(skb, &hdr);
104 if (!work) 204 if (ret) {
205 pr_debug("got invalid frame\n");
206 kfree_skb(skb);
105 return; 207 return;
208 }
209
210 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
211 if (sdata->type != IEEE802154_DEV_WPAN ||
212 !netif_running(sdata->dev))
213 continue;
214
215 ieee802154_subif_frame(sdata, skb, &hdr);
216 skb = NULL;
217 break;
218 }
219
220 if (skb)
221 kfree_skb(skb);
222}
223
224static void
225ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb)
226{
227 struct sk_buff *skb2;
228 struct ieee802154_sub_if_data *sdata;
229
230 skb_reset_mac_header(skb);
231 skb->ip_summed = CHECKSUM_UNNECESSARY;
232 skb->pkt_type = PACKET_OTHERHOST;
233 skb->protocol = htons(ETH_P_IEEE802154);
234
235 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
236 if (sdata->type != IEEE802154_DEV_MONITOR)
237 continue;
238
239 if (!ieee802154_sdata_running(sdata))
240 continue;
241
242 skb2 = skb_clone(skb, GFP_ATOMIC);
243 if (skb2) {
244 skb2->dev = sdata->dev;
245 ieee802154_deliver_skb(skb2);
246
247 sdata->dev->stats.rx_packets++;
248 sdata->dev->stats.rx_bytes += skb->len;
249 }
250 }
251}
252
253void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb)
254{
255 struct ieee802154_local *local = hw_to_local(hw);
256 u16 crc;
106 257
107 INIT_WORK(&work->work, mac802154_rx_worker); 258 WARN_ON_ONCE(softirq_count() == 0);
108 work->skb = skb;
109 work->dev = dev;
110 work->lqi = lqi;
111 259
112 queue_work(priv->dev_workqueue, &work->work); 260 /* TODO: When a transceiver omits the checksum here, we
261 * add an own calculated one. This is currently an ugly
262 * solution because the monitor needs a crc here.
263 */
264 if (local->hw.flags & IEEE802154_HW_RX_OMIT_CKSUM) {
265 crc = crc_ccitt(0, skb->data, skb->len);
266 put_unaligned_le16(crc, skb_put(skb, 2));
267 }
268
269 rcu_read_lock();
270
271 ieee802154_monitors_rx(local, skb);
272
273 /* Check if transceiver doesn't validate the checksum.
274 * If not we validate the checksum here.
275 */
276 if (local->hw.flags & IEEE802154_HW_RX_DROP_BAD_CKSUM) {
277 crc = crc_ccitt(0, skb->data, skb->len);
278 if (crc) {
279 rcu_read_unlock();
280 kfree_skb(skb);
281 return;
282 }
283 }
284 /* remove crc */
285 skb_trim(skb, skb->len - 2);
286
287 __ieee802154_rx_handle_packet(local, skb);
288
289 rcu_read_unlock();
290}
291EXPORT_SYMBOL(ieee802154_rx);
292
293void
294ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi)
295{
296 struct ieee802154_local *local = hw_to_local(hw);
297
298 mac_cb(skb)->lqi = lqi;
299 skb->pkt_type = IEEE802154_RX_MSG;
300 skb_queue_tail(&local->skb_queue, skb);
301 tasklet_schedule(&local->tasklet);
113} 302}
114EXPORT_SYMBOL(ieee802154_rx_irqsafe); 303EXPORT_SYMBOL(ieee802154_rx_irqsafe);
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index fdf4c0e67259..cc37b77f2632 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -10,10 +10,6 @@
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details. 11 * GNU General Public License for more details.
12 * 12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Written by: 13 * Written by:
18 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> 14 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
19 * Sergey Lapin <slapin@ossfans.org> 15 * Sergey Lapin <slapin@ossfans.org>
@@ -24,106 +20,98 @@
24#include <linux/netdevice.h> 20#include <linux/netdevice.h>
25#include <linux/if_arp.h> 21#include <linux/if_arp.h>
26#include <linux/crc-ccitt.h> 22#include <linux/crc-ccitt.h>
23#include <asm/unaligned.h>
27 24
25#include <net/rtnetlink.h>
28#include <net/ieee802154_netdev.h> 26#include <net/ieee802154_netdev.h>
29#include <net/mac802154.h> 27#include <net/mac802154.h>
30#include <net/wpan-phy.h> 28#include <net/cfg802154.h>
31 29
32#include "mac802154.h" 30#include "ieee802154_i.h"
31#include "driver-ops.h"
33 32
34/* IEEE 802.15.4 transceivers can sleep during the xmit session, so process 33/* IEEE 802.15.4 transceivers can sleep during the xmit session, so process
35 * packets through the workqueue. 34 * packets through the workqueue.
36 */ 35 */
37struct xmit_work { 36struct ieee802154_xmit_cb {
38 struct sk_buff *skb; 37 struct sk_buff *skb;
39 struct work_struct work; 38 struct work_struct work;
40 struct mac802154_priv *priv; 39 struct ieee802154_local *local;
41 u8 chan;
42 u8 page;
43}; 40};
44 41
45static void mac802154_xmit_worker(struct work_struct *work) 42static struct ieee802154_xmit_cb ieee802154_xmit_cb;
43
44static void ieee802154_xmit_worker(struct work_struct *work)
46{ 45{
47 struct xmit_work *xw = container_of(work, struct xmit_work, work); 46 struct ieee802154_xmit_cb *cb =
48 struct mac802154_sub_if_data *sdata; 47 container_of(work, struct ieee802154_xmit_cb, work);
48 struct ieee802154_local *local = cb->local;
49 struct sk_buff *skb = cb->skb;
50 struct net_device *dev = skb->dev;
49 int res; 51 int res;
50 52
51 mutex_lock(&xw->priv->phy->pib_lock); 53 rtnl_lock();
52 if (xw->priv->phy->current_channel != xw->chan ||
53 xw->priv->phy->current_page != xw->page) {
54 res = xw->priv->ops->set_channel(&xw->priv->hw,
55 xw->page,
56 xw->chan);
57 if (res) {
58 pr_debug("set_channel failed\n");
59 goto out;
60 }
61 54
62 xw->priv->phy->current_channel = xw->chan; 55 /* check if ifdown occurred while schedule */
63 xw->priv->phy->current_page = xw->page; 56 if (!netif_running(dev))
64 } 57 goto err_tx;
65 58
66 res = xw->priv->ops->xmit(&xw->priv->hw, xw->skb); 59 res = drv_xmit_sync(local, skb);
67 if (res) 60 if (res)
68 pr_debug("transmission failed\n"); 61 goto err_tx;
69 62
70out: 63 ieee802154_xmit_complete(&local->hw, skb);
71 mutex_unlock(&xw->priv->phy->pib_lock);
72 64
73 /* Restart the netif queue on each sub_if_data object. */ 65 dev->stats.tx_packets++;
74 rcu_read_lock(); 66 dev->stats.tx_bytes += skb->len;
75 list_for_each_entry_rcu(sdata, &xw->priv->slaves, list)
76 netif_wake_queue(sdata->dev);
77 rcu_read_unlock();
78 67
79 dev_kfree_skb(xw->skb); 68 rtnl_unlock();
80 69
81 kfree(xw); 70 return;
71
72err_tx:
73 /* Restart the netif queue on each sub_if_data object. */
74 ieee802154_wake_queue(&local->hw);
75 rtnl_unlock();
76 kfree_skb(skb);
77 netdev_dbg(dev, "transmission failed\n");
82} 78}
83 79
84netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, 80static netdev_tx_t
85 u8 page, u8 chan) 81ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb)
86{ 82{
87 struct xmit_work *work; 83 struct net_device *dev = skb->dev;
88 struct mac802154_sub_if_data *sdata; 84 int ret;
89
90 if (!(priv->phy->channels_supported[page] & (1 << chan))) {
91 WARN_ON(1);
92 goto err_tx;
93 }
94
95 mac802154_monitors_rx(mac802154_to_priv(&priv->hw), skb);
96 85
97 if (!(priv->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { 86 if (!(local->hw.flags & IEEE802154_HW_TX_OMIT_CKSUM)) {
98 u16 crc = crc_ccitt(0, skb->data, skb->len); 87 u16 crc = crc_ccitt(0, skb->data, skb->len);
99 u8 *data = skb_put(skb, 2);
100 88
101 data[0] = crc & 0xff; 89 put_unaligned_le16(crc, skb_put(skb, 2));
102 data[1] = crc >> 8;
103 } 90 }
104 91
105 if (skb_cow_head(skb, priv->hw.extra_tx_headroom)) 92 if (skb_cow_head(skb, local->hw.extra_tx_headroom))
106 goto err_tx; 93 goto err_tx;
107 94
108 work = kzalloc(sizeof(*work), GFP_ATOMIC);
109 if (!work) {
110 kfree_skb(skb);
111 return NETDEV_TX_BUSY;
112 }
113
114 /* Stop the netif queue on each sub_if_data object. */ 95 /* Stop the netif queue on each sub_if_data object. */
115 rcu_read_lock(); 96 ieee802154_stop_queue(&local->hw);
116 list_for_each_entry_rcu(sdata, &priv->slaves, list) 97
117 netif_stop_queue(sdata->dev); 98 /* async is priority, otherwise sync is fallback */
118 rcu_read_unlock(); 99 if (local->ops->xmit_async) {
100 ret = drv_xmit_async(local, skb);
101 if (ret) {
102 ieee802154_wake_queue(&local->hw);
103 goto err_tx;
104 }
119 105
120 INIT_WORK(&work->work, mac802154_xmit_worker); 106 dev->stats.tx_packets++;
121 work->skb = skb; 107 dev->stats.tx_bytes += skb->len;
122 work->priv = priv; 108 } else {
123 work->page = page; 109 INIT_WORK(&ieee802154_xmit_cb.work, ieee802154_xmit_worker);
124 work->chan = chan; 110 ieee802154_xmit_cb.skb = skb;
111 ieee802154_xmit_cb.local = local;
125 112
126 queue_work(priv->dev_workqueue, &work->work); 113 queue_work(local->workqueue, &ieee802154_xmit_cb.work);
114 }
127 115
128 return NETDEV_TX_OK; 116 return NETDEV_TX_OK;
129 117
@@ -131,3 +119,31 @@ err_tx:
131 kfree_skb(skb); 119 kfree_skb(skb);
132 return NETDEV_TX_OK; 120 return NETDEV_TX_OK;
133} 121}
122
123netdev_tx_t
124ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev)
125{
126 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
127
128 skb->skb_iif = dev->ifindex;
129
130 return ieee802154_tx(sdata->local, skb);
131}
132
133netdev_tx_t
134ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev)
135{
136 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
137 int rc;
138
139 rc = mac802154_llsec_encrypt(&sdata->sec, skb);
140 if (rc) {
141 netdev_warn(dev, "encryption failed: %i\n", rc);
142 kfree_skb(skb);
143 return NETDEV_TX_OK;
144 }
145
146 skb->skb_iif = dev->ifindex;
147
148 return ieee802154_tx(sdata->local, skb);
149}
diff --git a/net/mac802154/util.c b/net/mac802154/util.c
new file mode 100644
index 000000000000..117e4eff4ca8
--- /dev/null
+++ b/net/mac802154/util.c
@@ -0,0 +1,55 @@
1/* This program is free software; you can redistribute it and/or modify
2 * it under the terms of the GNU General Public License version 2
3 * as published by the Free Software Foundation.
4 *
5 * This program is distributed in the hope that it will be useful,
6 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8 * GNU General Public License for more details.
9 *
10 * Authors:
11 * Alexander Aring <aar@pengutronix.de>
12 *
13 * Based on: net/mac80211/util.c
14 */
15
16#include "ieee802154_i.h"
17
18void ieee802154_wake_queue(struct ieee802154_hw *hw)
19{
20 struct ieee802154_local *local = hw_to_local(hw);
21 struct ieee802154_sub_if_data *sdata;
22
23 rcu_read_lock();
24 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
25 if (!sdata->dev)
26 continue;
27
28 netif_wake_queue(sdata->dev);
29 }
30 rcu_read_unlock();
31}
32EXPORT_SYMBOL(ieee802154_wake_queue);
33
34void ieee802154_stop_queue(struct ieee802154_hw *hw)
35{
36 struct ieee802154_local *local = hw_to_local(hw);
37 struct ieee802154_sub_if_data *sdata;
38
39 rcu_read_lock();
40 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
41 if (!sdata->dev)
42 continue;
43
44 netif_stop_queue(sdata->dev);
45 }
46 rcu_read_unlock();
47}
48EXPORT_SYMBOL(ieee802154_stop_queue);
49
50void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb)
51{
52 ieee802154_wake_queue(hw);
53 consume_skb(skb);
54}
55EXPORT_SYMBOL(ieee802154_xmit_complete);
diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c
deleted file mode 100644
index 4ab86a57dca5..000000000000
--- a/net/mac802154/wpan.c
+++ /dev/null
@@ -1,599 +0,0 @@
1/*
2 * Copyright 2007-2012 Siemens AG
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Written by:
18 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
19 * Sergey Lapin <slapin@ossfans.org>
20 * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
21 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
22 */
23
24#include <linux/netdevice.h>
25#include <linux/module.h>
26#include <linux/if_arp.h>
27
28#include <net/rtnetlink.h>
29#include <linux/nl802154.h>
30#include <net/af_ieee802154.h>
31#include <net/mac802154.h>
32#include <net/ieee802154_netdev.h>
33#include <net/ieee802154.h>
34#include <net/wpan-phy.h>
35
36#include "mac802154.h"
37
38static int mac802154_wpan_update_llsec(struct net_device *dev)
39{
40 struct mac802154_sub_if_data *priv = netdev_priv(dev);
41 struct ieee802154_mlme_ops *ops = ieee802154_mlme_ops(dev);
42 int rc = 0;
43
44 if (ops->llsec) {
45 struct ieee802154_llsec_params params;
46 int changed = 0;
47
48 params.pan_id = priv->pan_id;
49 changed |= IEEE802154_LLSEC_PARAM_PAN_ID;
50
51 params.hwaddr = priv->extended_addr;
52 changed |= IEEE802154_LLSEC_PARAM_HWADDR;
53
54 rc = ops->llsec->set_params(dev, &params, changed);
55 }
56
57 return rc;
58}
59
60static int
61mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
62{
63 struct mac802154_sub_if_data *priv = netdev_priv(dev);
64 struct sockaddr_ieee802154 *sa =
65 (struct sockaddr_ieee802154 *)&ifr->ifr_addr;
66 int err = -ENOIOCTLCMD;
67
68 spin_lock_bh(&priv->mib_lock);
69
70 switch (cmd) {
71 case SIOCGIFADDR:
72 {
73 u16 pan_id, short_addr;
74
75 pan_id = le16_to_cpu(priv->pan_id);
76 short_addr = le16_to_cpu(priv->short_addr);
77 if (pan_id == IEEE802154_PANID_BROADCAST ||
78 short_addr == IEEE802154_ADDR_BROADCAST) {
79 err = -EADDRNOTAVAIL;
80 break;
81 }
82
83 sa->family = AF_IEEE802154;
84 sa->addr.addr_type = IEEE802154_ADDR_SHORT;
85 sa->addr.pan_id = pan_id;
86 sa->addr.short_addr = short_addr;
87
88 err = 0;
89 break;
90 }
91 case SIOCSIFADDR:
92 dev_warn(&dev->dev,
93 "Using DEBUGing ioctl SIOCSIFADDR isn't recommended!\n");
94 if (sa->family != AF_IEEE802154 ||
95 sa->addr.addr_type != IEEE802154_ADDR_SHORT ||
96 sa->addr.pan_id == IEEE802154_PANID_BROADCAST ||
97 sa->addr.short_addr == IEEE802154_ADDR_BROADCAST ||
98 sa->addr.short_addr == IEEE802154_ADDR_UNDEF) {
99 err = -EINVAL;
100 break;
101 }
102
103 priv->pan_id = cpu_to_le16(sa->addr.pan_id);
104 priv->short_addr = cpu_to_le16(sa->addr.short_addr);
105
106 err = mac802154_wpan_update_llsec(dev);
107 break;
108 }
109
110 spin_unlock_bh(&priv->mib_lock);
111 return err;
112}
113
114static int mac802154_wpan_mac_addr(struct net_device *dev, void *p)
115{
116 struct sockaddr *addr = p;
117
118 if (netif_running(dev))
119 return -EBUSY;
120
121 /* FIXME: validate addr */
122 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
123 mac802154_dev_set_ieee_addr(dev);
124 return mac802154_wpan_update_llsec(dev);
125}
126
127int mac802154_set_mac_params(struct net_device *dev,
128 const struct ieee802154_mac_params *params)
129{
130 struct mac802154_sub_if_data *priv = netdev_priv(dev);
131
132 mutex_lock(&priv->hw->slaves_mtx);
133 priv->mac_params = *params;
134 mutex_unlock(&priv->hw->slaves_mtx);
135
136 return 0;
137}
138
139void mac802154_get_mac_params(struct net_device *dev,
140 struct ieee802154_mac_params *params)
141{
142 struct mac802154_sub_if_data *priv = netdev_priv(dev);
143
144 mutex_lock(&priv->hw->slaves_mtx);
145 *params = priv->mac_params;
146 mutex_unlock(&priv->hw->slaves_mtx);
147}
148
149static int mac802154_wpan_open(struct net_device *dev)
150{
151 int rc;
152 struct mac802154_sub_if_data *priv = netdev_priv(dev);
153 struct wpan_phy *phy = priv->hw->phy;
154
155 rc = mac802154_slave_open(dev);
156 if (rc < 0)
157 return rc;
158
159 mutex_lock(&phy->pib_lock);
160
161 if (phy->set_txpower) {
162 rc = phy->set_txpower(phy, priv->mac_params.transmit_power);
163 if (rc < 0)
164 goto out;
165 }
166
167 if (phy->set_lbt) {
168 rc = phy->set_lbt(phy, priv->mac_params.lbt);
169 if (rc < 0)
170 goto out;
171 }
172
173 if (phy->set_cca_mode) {
174 rc = phy->set_cca_mode(phy, priv->mac_params.cca_mode);
175 if (rc < 0)
176 goto out;
177 }
178
179 if (phy->set_cca_ed_level) {
180 rc = phy->set_cca_ed_level(phy, priv->mac_params.cca_ed_level);
181 if (rc < 0)
182 goto out;
183 }
184
185 if (phy->set_csma_params) {
186 rc = phy->set_csma_params(phy, priv->mac_params.min_be,
187 priv->mac_params.max_be,
188 priv->mac_params.csma_retries);
189 if (rc < 0)
190 goto out;
191 }
192
193 if (phy->set_frame_retries) {
194 rc = phy->set_frame_retries(phy,
195 priv->mac_params.frame_retries);
196 if (rc < 0)
197 goto out;
198 }
199
200 mutex_unlock(&phy->pib_lock);
201 return 0;
202
203out:
204 mutex_unlock(&phy->pib_lock);
205 return rc;
206}
207
208static int mac802154_set_header_security(struct mac802154_sub_if_data *priv,
209 struct ieee802154_hdr *hdr,
210 const struct ieee802154_mac_cb *cb)
211{
212 struct ieee802154_llsec_params params;
213 u8 level;
214
215 mac802154_llsec_get_params(&priv->sec, &params);
216
217 if (!params.enabled && cb->secen_override && cb->secen)
218 return -EINVAL;
219 if (!params.enabled ||
220 (cb->secen_override && !cb->secen) ||
221 !params.out_level)
222 return 0;
223 if (cb->seclevel_override && !cb->seclevel)
224 return -EINVAL;
225
226 level = cb->seclevel_override ? cb->seclevel : params.out_level;
227
228 hdr->fc.security_enabled = 1;
229 hdr->sec.level = level;
230 hdr->sec.key_id_mode = params.out_key.mode;
231 if (params.out_key.mode == IEEE802154_SCF_KEY_SHORT_INDEX)
232 hdr->sec.short_src = params.out_key.short_source;
233 else if (params.out_key.mode == IEEE802154_SCF_KEY_HW_INDEX)
234 hdr->sec.extended_src = params.out_key.extended_source;
235 hdr->sec.key_id = params.out_key.id;
236
237 return 0;
238}
239
240static int mac802154_header_create(struct sk_buff *skb,
241 struct net_device *dev,
242 unsigned short type,
243 const void *daddr,
244 const void *saddr,
245 unsigned len)
246{
247 struct ieee802154_hdr hdr;
248 struct mac802154_sub_if_data *priv = netdev_priv(dev);
249 struct ieee802154_mac_cb *cb = mac_cb(skb);
250 int hlen;
251
252 if (!daddr)
253 return -EINVAL;
254
255 memset(&hdr.fc, 0, sizeof(hdr.fc));
256 hdr.fc.type = cb->type;
257 hdr.fc.security_enabled = cb->secen;
258 hdr.fc.ack_request = cb->ackreq;
259 hdr.seq = ieee802154_mlme_ops(dev)->get_dsn(dev);
260
261 if (mac802154_set_header_security(priv, &hdr, cb) < 0)
262 return -EINVAL;
263
264 if (!saddr) {
265 spin_lock_bh(&priv->mib_lock);
266
267 if (priv->short_addr == cpu_to_le16(IEEE802154_ADDR_BROADCAST) ||
268 priv->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF) ||
269 priv->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST)) {
270 hdr.source.mode = IEEE802154_ADDR_LONG;
271 hdr.source.extended_addr = priv->extended_addr;
272 } else {
273 hdr.source.mode = IEEE802154_ADDR_SHORT;
274 hdr.source.short_addr = priv->short_addr;
275 }
276
277 hdr.source.pan_id = priv->pan_id;
278
279 spin_unlock_bh(&priv->mib_lock);
280 } else {
281 hdr.source = *(const struct ieee802154_addr *)saddr;
282 }
283
284 hdr.dest = *(const struct ieee802154_addr *)daddr;
285
286 hlen = ieee802154_hdr_push(skb, &hdr);
287 if (hlen < 0)
288 return -EINVAL;
289
290 skb_reset_mac_header(skb);
291 skb->mac_len = hlen;
292
293 if (len > ieee802154_max_payload(&hdr))
294 return -EMSGSIZE;
295
296 return hlen;
297}
298
299static int
300mac802154_header_parse(const struct sk_buff *skb, unsigned char *haddr)
301{
302 struct ieee802154_hdr hdr;
303 struct ieee802154_addr *addr = (struct ieee802154_addr *)haddr;
304
305 if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0) {
306 pr_debug("malformed packet\n");
307 return 0;
308 }
309
310 *addr = hdr.source;
311 return sizeof(*addr);
312}
313
314static netdev_tx_t
315mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev)
316{
317 struct mac802154_sub_if_data *priv;
318 u8 chan, page;
319 int rc;
320
321 priv = netdev_priv(dev);
322
323 spin_lock_bh(&priv->mib_lock);
324 chan = priv->chan;
325 page = priv->page;
326 spin_unlock_bh(&priv->mib_lock);
327
328 if (chan == MAC802154_CHAN_NONE ||
329 page >= WPAN_NUM_PAGES ||
330 chan >= WPAN_NUM_CHANNELS) {
331 kfree_skb(skb);
332 return NETDEV_TX_OK;
333 }
334
335 rc = mac802154_llsec_encrypt(&priv->sec, skb);
336 if (rc) {
337 pr_warn("encryption failed: %i\n", rc);
338 kfree_skb(skb);
339 return NETDEV_TX_OK;
340 }
341
342 skb->skb_iif = dev->ifindex;
343 dev->stats.tx_packets++;
344 dev->stats.tx_bytes += skb->len;
345
346 return mac802154_tx(priv->hw, skb, page, chan);
347}
348
349static struct header_ops mac802154_header_ops = {
350 .create = mac802154_header_create,
351 .parse = mac802154_header_parse,
352};
353
354static const struct net_device_ops mac802154_wpan_ops = {
355 .ndo_open = mac802154_wpan_open,
356 .ndo_stop = mac802154_slave_close,
357 .ndo_start_xmit = mac802154_wpan_xmit,
358 .ndo_do_ioctl = mac802154_wpan_ioctl,
359 .ndo_set_mac_address = mac802154_wpan_mac_addr,
360};
361
362static void mac802154_wpan_free(struct net_device *dev)
363{
364 struct mac802154_sub_if_data *priv = netdev_priv(dev);
365
366 mac802154_llsec_destroy(&priv->sec);
367
368 free_netdev(dev);
369}
370
371void mac802154_wpan_setup(struct net_device *dev)
372{
373 struct mac802154_sub_if_data *priv;
374
375 dev->addr_len = IEEE802154_ADDR_LEN;
376 memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN);
377
378 dev->hard_header_len = MAC802154_FRAME_HARD_HEADER_LEN;
379 dev->header_ops = &mac802154_header_ops;
380 dev->needed_tailroom = 2 + 16; /* FCS + MIC */
381 dev->mtu = IEEE802154_MTU;
382 dev->tx_queue_len = 300;
383 dev->type = ARPHRD_IEEE802154;
384 dev->flags = IFF_NOARP | IFF_BROADCAST;
385 dev->watchdog_timeo = 0;
386
387 dev->destructor = mac802154_wpan_free;
388 dev->netdev_ops = &mac802154_wpan_ops;
389 dev->ml_priv = &mac802154_mlme_wpan;
390
391 priv = netdev_priv(dev);
392 priv->type = IEEE802154_DEV_WPAN;
393
394 priv->chan = MAC802154_CHAN_NONE;
395 priv->page = 0;
396
397 spin_lock_init(&priv->mib_lock);
398 mutex_init(&priv->sec_mtx);
399
400 get_random_bytes(&priv->bsn, 1);
401 get_random_bytes(&priv->dsn, 1);
402
403 /* defaults per 802.15.4-2011 */
404 priv->mac_params.min_be = 3;
405 priv->mac_params.max_be = 5;
406 priv->mac_params.csma_retries = 4;
407 priv->mac_params.frame_retries = -1; /* for compatibility, actual default is 3 */
408
409 priv->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST);
410 priv->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
411
412 mac802154_llsec_init(&priv->sec);
413}
414
415static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb)
416{
417 return netif_rx_ni(skb);
418}
419
420static int
421mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb,
422 const struct ieee802154_hdr *hdr)
423{
424 __le16 span, sshort;
425 int rc;
426
427 pr_debug("getting packet via slave interface %s\n", sdata->dev->name);
428
429 spin_lock_bh(&sdata->mib_lock);
430
431 span = sdata->pan_id;
432 sshort = sdata->short_addr;
433
434 switch (mac_cb(skb)->dest.mode) {
435 case IEEE802154_ADDR_NONE:
436 if (mac_cb(skb)->dest.mode != IEEE802154_ADDR_NONE)
437 /* FIXME: check if we are PAN coordinator */
438 skb->pkt_type = PACKET_OTHERHOST;
439 else
440 /* ACK comes with both addresses empty */
441 skb->pkt_type = PACKET_HOST;
442 break;
443 case IEEE802154_ADDR_LONG:
444 if (mac_cb(skb)->dest.pan_id != span &&
445 mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST))
446 skb->pkt_type = PACKET_OTHERHOST;
447 else if (mac_cb(skb)->dest.extended_addr == sdata->extended_addr)
448 skb->pkt_type = PACKET_HOST;
449 else
450 skb->pkt_type = PACKET_OTHERHOST;
451 break;
452 case IEEE802154_ADDR_SHORT:
453 if (mac_cb(skb)->dest.pan_id != span &&
454 mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST))
455 skb->pkt_type = PACKET_OTHERHOST;
456 else if (mac_cb(skb)->dest.short_addr == sshort)
457 skb->pkt_type = PACKET_HOST;
458 else if (mac_cb(skb)->dest.short_addr ==
459 cpu_to_le16(IEEE802154_ADDR_BROADCAST))
460 skb->pkt_type = PACKET_BROADCAST;
461 else
462 skb->pkt_type = PACKET_OTHERHOST;
463 break;
464 default:
465 spin_unlock_bh(&sdata->mib_lock);
466 pr_debug("invalid dest mode\n");
467 kfree_skb(skb);
468 return NET_RX_DROP;
469 }
470
471 spin_unlock_bh(&sdata->mib_lock);
472
473 skb->dev = sdata->dev;
474
475 rc = mac802154_llsec_decrypt(&sdata->sec, skb);
476 if (rc) {
477 pr_debug("decryption failed: %i\n", rc);
478 goto fail;
479 }
480
481 sdata->dev->stats.rx_packets++;
482 sdata->dev->stats.rx_bytes += skb->len;
483
484 switch (mac_cb(skb)->type) {
485 case IEEE802154_FC_TYPE_DATA:
486 return mac802154_process_data(sdata->dev, skb);
487 default:
488 pr_warn("ieee802154: bad frame received (type = %d)\n",
489 mac_cb(skb)->type);
490 goto fail;
491 }
492
493fail:
494 kfree_skb(skb);
495 return NET_RX_DROP;
496}
497
498static void mac802154_print_addr(const char *name,
499 const struct ieee802154_addr *addr)
500{
501 if (addr->mode == IEEE802154_ADDR_NONE)
502 pr_debug("%s not present\n", name);
503
504 pr_debug("%s PAN ID: %04x\n", name, le16_to_cpu(addr->pan_id));
505 if (addr->mode == IEEE802154_ADDR_SHORT) {
506 pr_debug("%s is short: %04x\n", name,
507 le16_to_cpu(addr->short_addr));
508 } else {
509 u64 hw = swab64((__force u64) addr->extended_addr);
510
511 pr_debug("%s is hardware: %8phC\n", name, &hw);
512 }
513}
514
515static int mac802154_parse_frame_start(struct sk_buff *skb,
516 struct ieee802154_hdr *hdr)
517{
518 int hlen;
519 struct ieee802154_mac_cb *cb = mac_cb_init(skb);
520
521 hlen = ieee802154_hdr_pull(skb, hdr);
522 if (hlen < 0)
523 return -EINVAL;
524
525 skb->mac_len = hlen;
526
527 pr_debug("fc: %04x dsn: %02x\n", le16_to_cpup((__le16 *)&hdr->fc),
528 hdr->seq);
529
530 cb->type = hdr->fc.type;
531 cb->ackreq = hdr->fc.ack_request;
532 cb->secen = hdr->fc.security_enabled;
533
534 mac802154_print_addr("destination", &hdr->dest);
535 mac802154_print_addr("source", &hdr->source);
536
537 cb->source = hdr->source;
538 cb->dest = hdr->dest;
539
540 if (hdr->fc.security_enabled) {
541 u64 key;
542
543 pr_debug("seclevel %i\n", hdr->sec.level);
544
545 switch (hdr->sec.key_id_mode) {
546 case IEEE802154_SCF_KEY_IMPLICIT:
547 pr_debug("implicit key\n");
548 break;
549
550 case IEEE802154_SCF_KEY_INDEX:
551 pr_debug("key %02x\n", hdr->sec.key_id);
552 break;
553
554 case IEEE802154_SCF_KEY_SHORT_INDEX:
555 pr_debug("key %04x:%04x %02x\n",
556 le32_to_cpu(hdr->sec.short_src) >> 16,
557 le32_to_cpu(hdr->sec.short_src) & 0xffff,
558 hdr->sec.key_id);
559 break;
560
561 case IEEE802154_SCF_KEY_HW_INDEX:
562 key = swab64((__force u64) hdr->sec.extended_src);
563 pr_debug("key source %8phC %02x\n", &key,
564 hdr->sec.key_id);
565 break;
566 }
567 }
568
569 return 0;
570}
571
572void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb)
573{
574 int ret;
575 struct mac802154_sub_if_data *sdata;
576 struct ieee802154_hdr hdr;
577
578 ret = mac802154_parse_frame_start(skb, &hdr);
579 if (ret) {
580 pr_debug("got invalid frame\n");
581 kfree_skb(skb);
582 return;
583 }
584
585 rcu_read_lock();
586 list_for_each_entry_rcu(sdata, &priv->slaves, list) {
587 if (sdata->type != IEEE802154_DEV_WPAN ||
588 !netif_running(sdata->dev))
589 continue;
590
591 mac802154_subif_frame(sdata, skb, &hdr);
592 skb = NULL;
593 break;
594 }
595 rcu_read_unlock();
596
597 if (skb)
598 kfree_skb(skb);
599}
diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index a761670af31d..4c9e39f04ef8 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -10,7 +10,7 @@ obj-$(CONFIG_WEXT_SPY) += wext-spy.o
10obj-$(CONFIG_WEXT_PRIV) += wext-priv.o 10obj-$(CONFIG_WEXT_PRIV) += wext-priv.o
11 11
12cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o 12cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o
13cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o 13cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o ocb.o
14cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o 14cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o
15cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o 15cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o
16cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o 16cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 72d81e2154d5..85506f1d0789 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -115,7 +115,7 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
115EXPORT_SYMBOL(cfg80211_chandef_valid); 115EXPORT_SYMBOL(cfg80211_chandef_valid);
116 116
117static void chandef_primary_freqs(const struct cfg80211_chan_def *c, 117static void chandef_primary_freqs(const struct cfg80211_chan_def *c,
118 int *pri40, int *pri80) 118 u32 *pri40, u32 *pri80)
119{ 119{
120 int tmp; 120 int tmp;
121 121
@@ -366,6 +366,7 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
366 366
367 break; 367 break;
368 case NL80211_IFTYPE_STATION: 368 case NL80211_IFTYPE_STATION:
369 case NL80211_IFTYPE_OCB:
369 case NL80211_IFTYPE_P2P_CLIENT: 370 case NL80211_IFTYPE_P2P_CLIENT:
370 case NL80211_IFTYPE_MONITOR: 371 case NL80211_IFTYPE_MONITOR:
371 case NL80211_IFTYPE_AP_VLAN: 372 case NL80211_IFTYPE_AP_VLAN:
@@ -892,6 +893,13 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
892 *radar_detect |= BIT(wdev->chandef.width); 893 *radar_detect |= BIT(wdev->chandef.width);
893 } 894 }
894 return; 895 return;
896 case NL80211_IFTYPE_OCB:
897 if (wdev->chandef.chan) {
898 *chan = wdev->chandef.chan;
899 *chanmode = CHAN_MODE_SHARED;
900 return;
901 }
902 break;
895 case NL80211_IFTYPE_MONITOR: 903 case NL80211_IFTYPE_MONITOR:
896 case NL80211_IFTYPE_AP_VLAN: 904 case NL80211_IFTYPE_AP_VLAN:
897 case NL80211_IFTYPE_WDS: 905 case NL80211_IFTYPE_WDS:
diff --git a/net/wireless/core.c b/net/wireless/core.c
index f52a4cd7017c..a4d27927aba2 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -86,11 +86,11 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx)
86 return &rdev->wiphy; 86 return &rdev->wiphy;
87} 87}
88 88
89int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, 89static int cfg80211_dev_check_name(struct cfg80211_registered_device *rdev,
90 char *newname) 90 const char *newname)
91{ 91{
92 struct cfg80211_registered_device *rdev2; 92 struct cfg80211_registered_device *rdev2;
93 int wiphy_idx, taken = -1, result, digits; 93 int wiphy_idx, taken = -1, digits;
94 94
95 ASSERT_RTNL(); 95 ASSERT_RTNL();
96 96
@@ -109,15 +109,28 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
109 return -EINVAL; 109 return -EINVAL;
110 } 110 }
111 111
112 /* Ensure another device does not already have this name. */
113 list_for_each_entry(rdev2, &cfg80211_rdev_list, list)
114 if (strcmp(newname, wiphy_name(&rdev2->wiphy)) == 0)
115 return -EINVAL;
116
117 return 0;
118}
119
120int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
121 char *newname)
122{
123 int result;
124
125 ASSERT_RTNL();
112 126
113 /* Ignore nop renames */ 127 /* Ignore nop renames */
114 if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0) 128 if (strcmp(newname, wiphy_name(&rdev->wiphy)) == 0)
115 return 0; 129 return 0;
116 130
117 /* Ensure another device does not already have this name. */ 131 result = cfg80211_dev_check_name(rdev, newname);
118 list_for_each_entry(rdev2, &cfg80211_rdev_list, list) 132 if (result < 0)
119 if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0) 133 return result;
120 return -EINVAL;
121 134
122 result = device_rename(&rdev->wiphy.dev, newname); 135 result = device_rename(&rdev->wiphy.dev, newname);
123 if (result) 136 if (result)
@@ -309,7 +322,8 @@ static void cfg80211_destroy_iface_wk(struct work_struct *work)
309 322
310/* exported functions */ 323/* exported functions */
311 324
312struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) 325struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
326 const char *requested_name)
313{ 327{
314 static atomic_t wiphy_counter = ATOMIC_INIT(0); 328 static atomic_t wiphy_counter = ATOMIC_INIT(0);
315 329
@@ -346,7 +360,31 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
346 rdev->wiphy_idx--; 360 rdev->wiphy_idx--;
347 361
348 /* give it a proper name */ 362 /* give it a proper name */
349 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); 363 if (requested_name && requested_name[0]) {
364 int rv;
365
366 rtnl_lock();
367 rv = cfg80211_dev_check_name(rdev, requested_name);
368
369 if (rv < 0) {
370 rtnl_unlock();
371 goto use_default_name;
372 }
373
374 rv = dev_set_name(&rdev->wiphy.dev, "%s", requested_name);
375 rtnl_unlock();
376 if (rv)
377 goto use_default_name;
378 } else {
379use_default_name:
380 /* NOTE: This is *probably* safe w/out holding rtnl because of
381 * the restrictions on phy names. Probably this call could
382 * fail if some other part of the kernel (re)named a device
383 * phyX. But, might should add some locking and check return
384 * value, and use a different name if this one exists?
385 */
386 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx);
387 }
350 388
351 INIT_LIST_HEAD(&rdev->wdev_list); 389 INIT_LIST_HEAD(&rdev->wdev_list);
352 INIT_LIST_HEAD(&rdev->beacon_registrations); 390 INIT_LIST_HEAD(&rdev->beacon_registrations);
@@ -406,7 +444,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
406 444
407 return &rdev->wiphy; 445 return &rdev->wiphy;
408} 446}
409EXPORT_SYMBOL(wiphy_new); 447EXPORT_SYMBOL(wiphy_new_nm);
410 448
411static int wiphy_verify_combinations(struct wiphy *wiphy) 449static int wiphy_verify_combinations(struct wiphy *wiphy)
412{ 450{
@@ -831,7 +869,22 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev,
831 case NL80211_IFTYPE_P2P_GO: 869 case NL80211_IFTYPE_P2P_GO:
832 __cfg80211_stop_ap(rdev, dev, true); 870 __cfg80211_stop_ap(rdev, dev, true);
833 break; 871 break;
834 default: 872 case NL80211_IFTYPE_OCB:
873 __cfg80211_leave_ocb(rdev, dev);
874 break;
875 case NL80211_IFTYPE_WDS:
876 /* must be handled by mac80211/driver, has no APIs */
877 break;
878 case NL80211_IFTYPE_P2P_DEVICE:
879 /* cannot happen, has no netdev */
880 break;
881 case NL80211_IFTYPE_AP_VLAN:
882 case NL80211_IFTYPE_MONITOR:
883 /* nothing to do */
884 break;
885 case NL80211_IFTYPE_UNSPECIFIED:
886 case NUM_NL80211_IFTYPES:
887 /* invalid */
835 break; 888 break;
836 } 889 }
837} 890}
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 7e3a3cef7df9..61ee664cf2bd 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -290,6 +290,18 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
290 struct wireless_dev *wdev, 290 struct wireless_dev *wdev,
291 struct cfg80211_chan_def *chandef); 291 struct cfg80211_chan_def *chandef);
292 292
293/* OCB */
294int __cfg80211_join_ocb(struct cfg80211_registered_device *rdev,
295 struct net_device *dev,
296 struct ocb_setup *setup);
297int cfg80211_join_ocb(struct cfg80211_registered_device *rdev,
298 struct net_device *dev,
299 struct ocb_setup *setup);
300int __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev,
301 struct net_device *dev);
302int cfg80211_leave_ocb(struct cfg80211_registered_device *rdev,
303 struct net_device *dev);
304
293/* AP */ 305/* AP */
294int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, 306int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
295 struct net_device *dev, bool notify); 307 struct net_device *dev, bool notify);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 5839c85075f1..1a31736914e5 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -884,7 +884,12 @@ static int nl80211_key_allowed(struct wireless_dev *wdev)
884 if (!wdev->current_bss) 884 if (!wdev->current_bss)
885 return -ENOLINK; 885 return -ENOLINK;
886 break; 886 break;
887 default: 887 case NL80211_IFTYPE_UNSPECIFIED:
888 case NL80211_IFTYPE_OCB:
889 case NL80211_IFTYPE_MONITOR:
890 case NL80211_IFTYPE_P2P_DEVICE:
891 case NL80211_IFTYPE_WDS:
892 case NUM_NL80211_IFTYPES:
888 return -EINVAL; 893 return -EINVAL;
889 } 894 }
890 895
@@ -1514,8 +1519,8 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
1514 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH) 1519 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
1515 CMD(channel_switch, CHANNEL_SWITCH); 1520 CMD(channel_switch, CHANNEL_SWITCH);
1516 CMD(set_qos_map, SET_QOS_MAP); 1521 CMD(set_qos_map, SET_QOS_MAP);
1517 if (rdev->wiphy.flags & 1522 if (rdev->wiphy.features &
1518 WIPHY_FLAG_SUPPORTS_WMM_ADMISSION) 1523 NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)
1519 CMD(add_tx_ts, ADD_TX_TS); 1524 CMD(add_tx_ts, ADD_TX_TS);
1520 } 1525 }
1521 /* add into the if now */ 1526 /* add into the if now */
@@ -2605,7 +2610,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
2605 !(rdev->wiphy.interface_modes & (1 << type))) 2610 !(rdev->wiphy.interface_modes & (1 << type)))
2606 return -EOPNOTSUPP; 2611 return -EOPNOTSUPP;
2607 2612
2608 if (type == NL80211_IFTYPE_P2P_DEVICE && info->attrs[NL80211_ATTR_MAC]) { 2613 if ((type == NL80211_IFTYPE_P2P_DEVICE ||
2614 rdev->wiphy.features & NL80211_FEATURE_MAC_ON_CREATE) &&
2615 info->attrs[NL80211_ATTR_MAC]) {
2609 nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC], 2616 nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC],
2610 ETH_ALEN); 2617 ETH_ALEN);
2611 if (!is_valid_ether_addr(params.macaddr)) 2618 if (!is_valid_ether_addr(params.macaddr))
@@ -4398,10 +4405,12 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
4398{ 4405{
4399 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 4406 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4400 struct net_device *dev = info->user_ptr[1]; 4407 struct net_device *dev = info->user_ptr[1];
4401 u8 *mac_addr = NULL; 4408 struct station_del_parameters params;
4409
4410 memset(&params, 0, sizeof(params));
4402 4411
4403 if (info->attrs[NL80211_ATTR_MAC]) 4412 if (info->attrs[NL80211_ATTR_MAC])
4404 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 4413 params.mac = nla_data(info->attrs[NL80211_ATTR_MAC]);
4405 4414
4406 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 4415 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4407 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && 4416 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
@@ -4412,7 +4421,28 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
4412 if (!rdev->ops->del_station) 4421 if (!rdev->ops->del_station)
4413 return -EOPNOTSUPP; 4422 return -EOPNOTSUPP;
4414 4423
4415 return rdev_del_station(rdev, dev, mac_addr); 4424 if (info->attrs[NL80211_ATTR_MGMT_SUBTYPE]) {
4425 params.subtype =
4426 nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
4427 if (params.subtype != IEEE80211_STYPE_DISASSOC >> 4 &&
4428 params.subtype != IEEE80211_STYPE_DEAUTH >> 4)
4429 return -EINVAL;
4430 } else {
4431 /* Default to Deauthentication frame */
4432 params.subtype = IEEE80211_STYPE_DEAUTH >> 4;
4433 }
4434
4435 if (info->attrs[NL80211_ATTR_REASON_CODE]) {
4436 params.reason_code =
4437 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
4438 if (params.reason_code == 0)
4439 return -EINVAL; /* 0 is reserved */
4440 } else {
4441 /* Default to reason code 2 */
4442 params.reason_code = WLAN_REASON_PREV_AUTH_NOT_VALID;
4443 }
4444
4445 return rdev_del_station(rdev, dev, &params);
4416} 4446}
4417 4447
4418static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq, 4448static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq,
@@ -4624,6 +4654,96 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
4624 return rdev_del_mpath(rdev, dev, dst); 4654 return rdev_del_mpath(rdev, dev, dst);
4625} 4655}
4626 4656
4657static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info)
4658{
4659 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4660 int err;
4661 struct net_device *dev = info->user_ptr[1];
4662 struct mpath_info pinfo;
4663 struct sk_buff *msg;
4664 u8 *dst = NULL;
4665 u8 mpp[ETH_ALEN];
4666
4667 memset(&pinfo, 0, sizeof(pinfo));
4668
4669 if (!info->attrs[NL80211_ATTR_MAC])
4670 return -EINVAL;
4671
4672 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
4673
4674 if (!rdev->ops->get_mpp)
4675 return -EOPNOTSUPP;
4676
4677 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
4678 return -EOPNOTSUPP;
4679
4680 err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo);
4681 if (err)
4682 return err;
4683
4684 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4685 if (!msg)
4686 return -ENOMEM;
4687
4688 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
4689 dev, dst, mpp, &pinfo) < 0) {
4690 nlmsg_free(msg);
4691 return -ENOBUFS;
4692 }
4693
4694 return genlmsg_reply(msg, info);
4695}
4696
4697static int nl80211_dump_mpp(struct sk_buff *skb,
4698 struct netlink_callback *cb)
4699{
4700 struct mpath_info pinfo;
4701 struct cfg80211_registered_device *rdev;
4702 struct wireless_dev *wdev;
4703 u8 dst[ETH_ALEN];
4704 u8 mpp[ETH_ALEN];
4705 int path_idx = cb->args[2];
4706 int err;
4707
4708 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
4709 if (err)
4710 return err;
4711
4712 if (!rdev->ops->dump_mpp) {
4713 err = -EOPNOTSUPP;
4714 goto out_err;
4715 }
4716
4717 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
4718 err = -EOPNOTSUPP;
4719 goto out_err;
4720 }
4721
4722 while (1) {
4723 err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst,
4724 mpp, &pinfo);
4725 if (err == -ENOENT)
4726 break;
4727 if (err)
4728 goto out_err;
4729
4730 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
4731 cb->nlh->nlmsg_seq, NLM_F_MULTI,
4732 wdev->netdev, dst, mpp,
4733 &pinfo) < 0)
4734 goto out;
4735
4736 path_idx++;
4737 }
4738
4739 out:
4740 cb->args[2] = path_idx;
4741 err = skb->len;
4742 out_err:
4743 nl80211_finish_wdev_dump(rdev);
4744 return err;
4745}
4746
4627static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) 4747static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
4628{ 4748{
4629 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 4749 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -5923,7 +6043,6 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
5923 * function is called under RTNL lock, so this should not be a problem. 6043 * function is called under RTNL lock, so this should not be a problem.
5924 */ 6044 */
5925 static struct nlattr *csa_attrs[NL80211_ATTR_MAX+1]; 6045 static struct nlattr *csa_attrs[NL80211_ATTR_MAX+1];
5926 u8 radar_detect_width = 0;
5927 int err; 6046 int err;
5928 bool need_new_beacon = false; 6047 bool need_new_beacon = false;
5929 int len, i; 6048 int len, i;
@@ -6059,10 +6178,8 @@ skip_beacons:
6059 if (err < 0) 6178 if (err < 0)
6060 return err; 6179 return err;
6061 6180
6062 if (err > 0) { 6181 if (err > 0)
6063 radar_detect_width = BIT(params.chandef.width);
6064 params.radar_required = true; 6182 params.radar_required = true;
6065 }
6066 6183
6067 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX]) 6184 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
6068 params.block_tx = true; 6185 params.block_tx = true;
@@ -8159,6 +8276,28 @@ static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
8159 return -EINVAL; 8276 return -EINVAL;
8160} 8277}
8161 8278
8279static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info)
8280{
8281 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8282 struct net_device *dev = info->user_ptr[1];
8283 struct ocb_setup setup = {};
8284 int err;
8285
8286 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
8287 if (err)
8288 return err;
8289
8290 return cfg80211_join_ocb(rdev, dev, &setup);
8291}
8292
8293static int nl80211_leave_ocb(struct sk_buff *skb, struct genl_info *info)
8294{
8295 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8296 struct net_device *dev = info->user_ptr[1];
8297
8298 return cfg80211_leave_ocb(rdev, dev);
8299}
8300
8162static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) 8301static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
8163{ 8302{
8164 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 8303 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -9444,7 +9583,7 @@ static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info)
9444 u16 admitted_time = 0; 9583 u16 admitted_time = 0;
9445 int err; 9584 int err;
9446 9585
9447 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_WMM_ADMISSION)) 9586 if (!(rdev->wiphy.features & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION))
9448 return -EOPNOTSUPP; 9587 return -EOPNOTSUPP;
9449 9588
9450 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] || 9589 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] ||
@@ -9460,12 +9599,10 @@ static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info)
9460 return -EINVAL; 9599 return -EINVAL;
9461 9600
9462 /* WMM uses TIDs 0-7 even for TSPEC */ 9601 /* WMM uses TIDs 0-7 even for TSPEC */
9463 if (tsid < IEEE80211_FIRST_TSPEC_TSID) { 9602 if (tsid >= IEEE80211_FIRST_TSPEC_TSID) {
9464 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_WMM_ADMISSION))
9465 return -EINVAL;
9466 } else {
9467 /* TODO: handle 802.11 TSPEC/admission control 9603 /* TODO: handle 802.11 TSPEC/admission control
9468 * need more attributes for that (e.g. BA session requirement) 9604 * need more attributes for that (e.g. BA session requirement);
9605 * change the WMM adminssion test above to allow both then
9469 */ 9606 */
9470 return -EINVAL; 9607 return -EINVAL;
9471 } 9608 }
@@ -9782,6 +9919,15 @@ static const struct genl_ops nl80211_ops[] = {
9782 NL80211_FLAG_NEED_RTNL, 9919 NL80211_FLAG_NEED_RTNL,
9783 }, 9920 },
9784 { 9921 {
9922 .cmd = NL80211_CMD_GET_MPP,
9923 .doit = nl80211_get_mpp,
9924 .dumpit = nl80211_dump_mpp,
9925 .policy = nl80211_policy,
9926 .flags = GENL_ADMIN_PERM,
9927 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
9928 NL80211_FLAG_NEED_RTNL,
9929 },
9930 {
9785 .cmd = NL80211_CMD_SET_MPATH, 9931 .cmd = NL80211_CMD_SET_MPATH,
9786 .doit = nl80211_set_mpath, 9932 .doit = nl80211_set_mpath,
9787 .policy = nl80211_policy, 9933 .policy = nl80211_policy,
@@ -10095,6 +10241,22 @@ static const struct genl_ops nl80211_ops[] = {
10095 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | 10241 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
10096 NL80211_FLAG_NEED_RTNL, 10242 NL80211_FLAG_NEED_RTNL,
10097 }, 10243 },
10244 {
10245 .cmd = NL80211_CMD_JOIN_OCB,
10246 .doit = nl80211_join_ocb,
10247 .policy = nl80211_policy,
10248 .flags = GENL_ADMIN_PERM,
10249 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
10250 NL80211_FLAG_NEED_RTNL,
10251 },
10252 {
10253 .cmd = NL80211_CMD_LEAVE_OCB,
10254 .doit = nl80211_leave_ocb,
10255 .policy = nl80211_policy,
10256 .flags = GENL_ADMIN_PERM,
10257 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
10258 NL80211_FLAG_NEED_RTNL,
10259 },
10098#ifdef CONFIG_PM 10260#ifdef CONFIG_PM
10099 { 10261 {
10100 .cmd = NL80211_CMD_GET_WOWLAN, 10262 .cmd = NL80211_CMD_GET_WOWLAN,
diff --git a/net/wireless/ocb.c b/net/wireless/ocb.c
new file mode 100644
index 000000000000..c00d4a792319
--- /dev/null
+++ b/net/wireless/ocb.c
@@ -0,0 +1,88 @@
1/*
2 * OCB mode implementation
3 *
4 * Copyright: (c) 2014 Czech Technical University in Prague
5 * (c) 2014 Volkswagen Group Research
6 * Author: Rostislav Lisovy <rostislav.lisovy@fel.cvut.cz>
7 * Funded by: Volkswagen Group Research
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/ieee80211.h>
15#include <net/cfg80211.h>
16#include "nl80211.h"
17#include "core.h"
18#include "rdev-ops.h"
19
20int __cfg80211_join_ocb(struct cfg80211_registered_device *rdev,
21 struct net_device *dev,
22 struct ocb_setup *setup)
23{
24 struct wireless_dev *wdev = dev->ieee80211_ptr;
25 int err;
26
27 ASSERT_WDEV_LOCK(wdev);
28
29 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB)
30 return -EOPNOTSUPP;
31
32 if (WARN_ON(!setup->chandef.chan))
33 return -EINVAL;
34
35 err = rdev_join_ocb(rdev, dev, setup);
36 if (!err)
37 wdev->chandef = setup->chandef;
38
39 return err;
40}
41
42int cfg80211_join_ocb(struct cfg80211_registered_device *rdev,
43 struct net_device *dev,
44 struct ocb_setup *setup)
45{
46 struct wireless_dev *wdev = dev->ieee80211_ptr;
47 int err;
48
49 wdev_lock(wdev);
50 err = __cfg80211_join_ocb(rdev, dev, setup);
51 wdev_unlock(wdev);
52
53 return err;
54}
55
56int __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev,
57 struct net_device *dev)
58{
59 struct wireless_dev *wdev = dev->ieee80211_ptr;
60 int err;
61
62 ASSERT_WDEV_LOCK(wdev);
63
64 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB)
65 return -EOPNOTSUPP;
66
67 if (!rdev->ops->leave_ocb)
68 return -EOPNOTSUPP;
69
70 err = rdev_leave_ocb(rdev, dev);
71 if (!err)
72 memset(&wdev->chandef, 0, sizeof(wdev->chandef));
73
74 return err;
75}
76
77int cfg80211_leave_ocb(struct cfg80211_registered_device *rdev,
78 struct net_device *dev)
79{
80 struct wireless_dev *wdev = dev->ieee80211_ptr;
81 int err;
82
83 wdev_lock(wdev);
84 err = __cfg80211_leave_ocb(rdev, dev);
85 wdev_unlock(wdev);
86
87 return err;
88}
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index f6d457d6a558..1b3864cd50ca 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -178,11 +178,12 @@ static inline int rdev_add_station(struct cfg80211_registered_device *rdev,
178} 178}
179 179
180static inline int rdev_del_station(struct cfg80211_registered_device *rdev, 180static inline int rdev_del_station(struct cfg80211_registered_device *rdev,
181 struct net_device *dev, u8 *mac) 181 struct net_device *dev,
182 struct station_del_parameters *params)
182{ 183{
183 int ret; 184 int ret;
184 trace_rdev_del_station(&rdev->wiphy, dev, mac); 185 trace_rdev_del_station(&rdev->wiphy, dev, params);
185 ret = rdev->ops->del_station(&rdev->wiphy, dev, mac); 186 ret = rdev->ops->del_station(&rdev->wiphy, dev, params);
186 trace_rdev_return_int(&rdev->wiphy, ret); 187 trace_rdev_return_int(&rdev->wiphy, ret);
187 return ret; 188 return ret;
188} 189}
@@ -263,6 +264,18 @@ static inline int rdev_get_mpath(struct cfg80211_registered_device *rdev,
263 264
264} 265}
265 266
267static inline int rdev_get_mpp(struct cfg80211_registered_device *rdev,
268 struct net_device *dev, u8 *dst, u8 *mpp,
269 struct mpath_info *pinfo)
270{
271 int ret;
272
273 trace_rdev_get_mpp(&rdev->wiphy, dev, dst, mpp);
274 ret = rdev->ops->get_mpp(&rdev->wiphy, dev, dst, mpp, pinfo);
275 trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo);
276 return ret;
277}
278
266static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev, 279static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev,
267 struct net_device *dev, int idx, u8 *dst, 280 struct net_device *dev, int idx, u8 *dst,
268 u8 *next_hop, struct mpath_info *pinfo) 281 u8 *next_hop, struct mpath_info *pinfo)
@@ -271,7 +284,20 @@ static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev,
271 int ret; 284 int ret;
272 trace_rdev_dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop); 285 trace_rdev_dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop);
273 ret = rdev->ops->dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop, 286 ret = rdev->ops->dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop,
274 pinfo); 287 pinfo);
288 trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo);
289 return ret;
290}
291
292static inline int rdev_dump_mpp(struct cfg80211_registered_device *rdev,
293 struct net_device *dev, int idx, u8 *dst,
294 u8 *mpp, struct mpath_info *pinfo)
295
296{
297 int ret;
298
299 trace_rdev_dump_mpp(&rdev->wiphy, dev, idx, dst, mpp);
300 ret = rdev->ops->dump_mpp(&rdev->wiphy, dev, idx, dst, mpp, pinfo);
275 trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); 301 trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo);
276 return ret; 302 return ret;
277} 303}
@@ -322,6 +348,27 @@ static inline int rdev_leave_mesh(struct cfg80211_registered_device *rdev,
322 return ret; 348 return ret;
323} 349}
324 350
351static inline int rdev_join_ocb(struct cfg80211_registered_device *rdev,
352 struct net_device *dev,
353 struct ocb_setup *setup)
354{
355 int ret;
356 trace_rdev_join_ocb(&rdev->wiphy, dev, setup);
357 ret = rdev->ops->join_ocb(&rdev->wiphy, dev, setup);
358 trace_rdev_return_int(&rdev->wiphy, ret);
359 return ret;
360}
361
362static inline int rdev_leave_ocb(struct cfg80211_registered_device *rdev,
363 struct net_device *dev)
364{
365 int ret;
366 trace_rdev_leave_ocb(&rdev->wiphy, dev);
367 ret = rdev->ops->leave_ocb(&rdev->wiphy, dev);
368 trace_rdev_return_int(&rdev->wiphy, ret);
369 return ret;
370}
371
325static inline int rdev_change_bss(struct cfg80211_registered_device *rdev, 372static inline int rdev_change_bss(struct cfg80211_registered_device *rdev,
326 struct net_device *dev, 373 struct net_device *dev,
327 struct bss_parameters *params) 374 struct bss_parameters *params)
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index dc1668ff543b..0ab3711c79a0 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -80,9 +80,18 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
80 if (!request) 80 if (!request)
81 return -ENOMEM; 81 return -ENOMEM;
82 82
83 if (wdev->conn->params.channel) 83 if (wdev->conn->params.channel) {
84 enum ieee80211_band band = wdev->conn->params.channel->band;
85 struct ieee80211_supported_band *sband =
86 wdev->wiphy->bands[band];
87
88 if (!sband) {
89 kfree(request);
90 return -EINVAL;
91 }
84 request->channels[0] = wdev->conn->params.channel; 92 request->channels[0] = wdev->conn->params.channel;
85 else { 93 request->rates[band] = (1 << sband->n_bitrates) - 1;
94 } else {
86 int i = 0, j; 95 int i = 0, j;
87 enum ieee80211_band band; 96 enum ieee80211_band band;
88 struct ieee80211_supported_band *bands; 97 struct ieee80211_supported_band *bands;
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 625a6e6d1168..277a85df910e 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -600,6 +600,11 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_leave_ibss,
600 TP_ARGS(wiphy, netdev) 600 TP_ARGS(wiphy, netdev)
601); 601);
602 602
603DEFINE_EVENT(wiphy_netdev_evt, rdev_leave_ocb,
604 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
605 TP_ARGS(wiphy, netdev)
606);
607
603DEFINE_EVENT(wiphy_netdev_evt, rdev_flush_pmksa, 608DEFINE_EVENT(wiphy_netdev_evt, rdev_flush_pmksa,
604 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), 609 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
605 TP_ARGS(wiphy, netdev) 610 TP_ARGS(wiphy, netdev)
@@ -680,9 +685,34 @@ DECLARE_EVENT_CLASS(wiphy_netdev_mac_evt,
680 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac)) 685 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac))
681); 686);
682 687
683DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_del_station, 688DECLARE_EVENT_CLASS(station_del,
684 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *mac), 689 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
685 TP_ARGS(wiphy, netdev, mac) 690 struct station_del_parameters *params),
691 TP_ARGS(wiphy, netdev, params),
692 TP_STRUCT__entry(
693 WIPHY_ENTRY
694 NETDEV_ENTRY
695 MAC_ENTRY(sta_mac)
696 __field(u8, subtype)
697 __field(u16, reason_code)
698 ),
699 TP_fast_assign(
700 WIPHY_ASSIGN;
701 NETDEV_ASSIGN;
702 MAC_ASSIGN(sta_mac, params->mac);
703 __entry->subtype = params->subtype;
704 __entry->reason_code = params->reason_code;
705 ),
706 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT
707 ", subtype: %u, reason_code: %u",
708 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac),
709 __entry->subtype, __entry->reason_code)
710);
711
712DEFINE_EVENT(station_del, rdev_del_station,
713 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
714 struct station_del_parameters *params),
715 TP_ARGS(wiphy, netdev, params)
686); 716);
687 717
688DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_get_station, 718DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_get_station,
@@ -801,6 +831,51 @@ TRACE_EVENT(rdev_dump_mpath,
801 MAC_PR_ARG(next_hop)) 831 MAC_PR_ARG(next_hop))
802); 832);
803 833
834TRACE_EVENT(rdev_get_mpp,
835 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
836 u8 *dst, u8 *mpp),
837 TP_ARGS(wiphy, netdev, dst, mpp),
838 TP_STRUCT__entry(
839 WIPHY_ENTRY
840 NETDEV_ENTRY
841 MAC_ENTRY(dst)
842 MAC_ENTRY(mpp)
843 ),
844 TP_fast_assign(
845 WIPHY_ASSIGN;
846 NETDEV_ASSIGN;
847 MAC_ASSIGN(dst, dst);
848 MAC_ASSIGN(mpp, mpp);
849 ),
850 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", destination: " MAC_PR_FMT
851 ", mpp: " MAC_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG,
852 MAC_PR_ARG(dst), MAC_PR_ARG(mpp))
853);
854
855TRACE_EVENT(rdev_dump_mpp,
856 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx,
857 u8 *dst, u8 *mpp),
858 TP_ARGS(wiphy, netdev, idx, mpp, dst),
859 TP_STRUCT__entry(
860 WIPHY_ENTRY
861 NETDEV_ENTRY
862 MAC_ENTRY(dst)
863 MAC_ENTRY(mpp)
864 __field(int, idx)
865 ),
866 TP_fast_assign(
867 WIPHY_ASSIGN;
868 NETDEV_ASSIGN;
869 MAC_ASSIGN(dst, dst);
870 MAC_ASSIGN(mpp, mpp);
871 __entry->idx = idx;
872 ),
873 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d, destination: "
874 MAC_PR_FMT ", mpp: " MAC_PR_FMT,
875 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx, MAC_PR_ARG(dst),
876 MAC_PR_ARG(mpp))
877);
878
804TRACE_EVENT(rdev_return_int_mpath_info, 879TRACE_EVENT(rdev_return_int_mpath_info,
805 TP_PROTO(struct wiphy *wiphy, int ret, struct mpath_info *pinfo), 880 TP_PROTO(struct wiphy *wiphy, int ret, struct mpath_info *pinfo),
806 TP_ARGS(wiphy, ret, pinfo), 881 TP_ARGS(wiphy, ret, pinfo),
@@ -1246,6 +1321,22 @@ TRACE_EVENT(rdev_join_ibss,
1246 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid) 1321 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid)
1247); 1322);
1248 1323
1324TRACE_EVENT(rdev_join_ocb,
1325 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
1326 const struct ocb_setup *setup),
1327 TP_ARGS(wiphy, netdev, setup),
1328 TP_STRUCT__entry(
1329 WIPHY_ENTRY
1330 NETDEV_ENTRY
1331 ),
1332 TP_fast_assign(
1333 WIPHY_ASSIGN;
1334 NETDEV_ASSIGN;
1335 ),
1336 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT,
1337 WIPHY_PR_ARG, NETDEV_PR_ARG)
1338);
1339
1249TRACE_EVENT(rdev_set_wiphy_params, 1340TRACE_EVENT(rdev_set_wiphy_params,
1250 TP_PROTO(struct wiphy *wiphy, u32 changed), 1341 TP_PROTO(struct wiphy *wiphy, u32 changed),
1251 TP_ARGS(wiphy, changed), 1342 TP_ARGS(wiphy, changed),
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 5e233a577d0f..d0ac795445b7 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -442,7 +442,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
442 break; 442 break;
443 case cpu_to_le16(0): 443 case cpu_to_le16(0):
444 if (iftype != NL80211_IFTYPE_ADHOC && 444 if (iftype != NL80211_IFTYPE_ADHOC &&
445 iftype != NL80211_IFTYPE_STATION) 445 iftype != NL80211_IFTYPE_STATION &&
446 iftype != NL80211_IFTYPE_OCB)
446 return -1; 447 return -1;
447 break; 448 break;
448 } 449 }
@@ -519,6 +520,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
519 memcpy(hdr.addr3, skb->data, ETH_ALEN); 520 memcpy(hdr.addr3, skb->data, ETH_ALEN);
520 hdrlen = 24; 521 hdrlen = 24;
521 break; 522 break;
523 case NL80211_IFTYPE_OCB:
522 case NL80211_IFTYPE_ADHOC: 524 case NL80211_IFTYPE_ADHOC:
523 /* DA SA BSSID */ 525 /* DA SA BSSID */
524 memcpy(hdr.addr1, skb->data, ETH_ALEN); 526 memcpy(hdr.addr1, skb->data, ETH_ALEN);
@@ -937,6 +939,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
937 if (dev->ieee80211_ptr->use_4addr) 939 if (dev->ieee80211_ptr->use_4addr)
938 break; 940 break;
939 /* fall through */ 941 /* fall through */
942 case NL80211_IFTYPE_OCB:
940 case NL80211_IFTYPE_P2P_CLIENT: 943 case NL80211_IFTYPE_P2P_CLIENT:
941 case NL80211_IFTYPE_ADHOC: 944 case NL80211_IFTYPE_ADHOC:
942 dev->priv_flags |= IFF_DONT_BRIDGE; 945 dev->priv_flags |= IFF_DONT_BRIDGE;