aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2007-07-27 09:43:23 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:47:35 -0400
commitb2c258fb11b3fc77a73f8b0453ff1256de812bc6 (patch)
tree5b0e7cd774d43c33644a8510019e4f114ccacd5b /net/mac80211
parentff6880892990aece71a3271425dfde35344d51bb (diff)
[MAC80211]: reorder interface related functions
This patch groups a whole bunch of functions together to make ieee80211.c more maintainable. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Jiri Benc <jbenc@suse.cz> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ieee80211.c1205
1 files changed, 599 insertions, 606 deletions
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 2b15505a6e48..f240f9706081 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -61,6 +61,605 @@ struct ieee80211_tx_status_rtap_hdr {
61 u8 data_retries; 61 u8 data_retries;
62} __attribute__ ((packed)); 62} __attribute__ ((packed));
63 63
64/* common interface routines */
65
66static struct net_device_stats *ieee80211_get_stats(struct net_device *dev)
67{
68 struct ieee80211_sub_if_data *sdata;
69 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
70 return &(sdata->stats);
71}
72
73static int header_parse_80211(struct sk_buff *skb, unsigned char *haddr)
74{
75 memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */
76 return ETH_ALEN;
77}
78
79/* master interface */
80
81static int ieee80211_master_open(struct net_device *dev)
82{
83 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
84 struct ieee80211_sub_if_data *sdata;
85 int res = -EOPNOTSUPP;
86
87 read_lock(&local->sub_if_lock);
88 list_for_each_entry(sdata, &local->sub_if_list, list) {
89 if (sdata->dev != dev && netif_running(sdata->dev)) {
90 res = 0;
91 break;
92 }
93 }
94 read_unlock(&local->sub_if_lock);
95 return res;
96}
97
98static int ieee80211_master_stop(struct net_device *dev)
99{
100 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
101 struct ieee80211_sub_if_data *sdata;
102
103 read_lock(&local->sub_if_lock);
104 list_for_each_entry(sdata, &local->sub_if_list, list)
105 if (sdata->dev != dev && netif_running(sdata->dev))
106 dev_close(sdata->dev);
107 read_unlock(&local->sub_if_lock);
108
109 return 0;
110}
111
112/* management interface */
113
114static void
115ieee80211_fill_frame_info(struct ieee80211_local *local,
116 struct ieee80211_frame_info *fi,
117 struct ieee80211_rx_status *status)
118{
119 if (status) {
120 struct timespec ts;
121 struct ieee80211_rate *rate;
122
123 jiffies_to_timespec(jiffies, &ts);
124 fi->hosttime = cpu_to_be64((u64) ts.tv_sec * 1000000 +
125 ts.tv_nsec / 1000);
126 fi->mactime = cpu_to_be64(status->mactime);
127 switch (status->phymode) {
128 case MODE_IEEE80211A:
129 fi->phytype = htonl(ieee80211_phytype_ofdm_dot11_a);
130 break;
131 case MODE_IEEE80211B:
132 fi->phytype = htonl(ieee80211_phytype_dsss_dot11_b);
133 break;
134 case MODE_IEEE80211G:
135 fi->phytype = htonl(ieee80211_phytype_pbcc_dot11_g);
136 break;
137 case MODE_ATHEROS_TURBO:
138 fi->phytype =
139 htonl(ieee80211_phytype_dsss_dot11_turbo);
140 break;
141 default:
142 fi->phytype = htonl(0xAAAAAAAA);
143 break;
144 }
145 fi->channel = htonl(status->channel);
146 rate = ieee80211_get_rate(local, status->phymode,
147 status->rate);
148 if (rate) {
149 fi->datarate = htonl(rate->rate);
150 if (rate->flags & IEEE80211_RATE_PREAMBLE2) {
151 if (status->rate == rate->val)
152 fi->preamble = htonl(2); /* long */
153 else if (status->rate == rate->val2)
154 fi->preamble = htonl(1); /* short */
155 } else
156 fi->preamble = htonl(0);
157 } else {
158 fi->datarate = htonl(0);
159 fi->preamble = htonl(0);
160 }
161
162 fi->antenna = htonl(status->antenna);
163 fi->priority = htonl(0xffffffff); /* no clue */
164 fi->ssi_type = htonl(ieee80211_ssi_raw);
165 fi->ssi_signal = htonl(status->ssi);
166 fi->ssi_noise = 0x00000000;
167 fi->encoding = 0;
168 } else {
169 /* clear everything because we really don't know.
170 * the msg_type field isn't present on monitor frames
171 * so we don't know whether it will be present or not,
172 * but it's ok to not clear it since it'll be assigned
173 * anyway */
174 memset(fi, 0, sizeof(*fi) - sizeof(fi->msg_type));
175
176 fi->ssi_type = htonl(ieee80211_ssi_none);
177 }
178 fi->version = htonl(IEEE80211_FI_VERSION);
179 fi->length = cpu_to_be32(sizeof(*fi) - sizeof(fi->msg_type));
180}
181
182/* this routine is actually not just for this, but also
183 * for pushing fake 'management' frames into userspace.
184 * it shall be replaced by a netlink-based system. */
185void
186ieee80211_rx_mgmt(struct ieee80211_local *local, struct sk_buff *skb,
187 struct ieee80211_rx_status *status, u32 msg_type)
188{
189 struct ieee80211_frame_info *fi;
190 const size_t hlen = sizeof(struct ieee80211_frame_info);
191 struct ieee80211_sub_if_data *sdata;
192
193 skb->dev = local->apdev;
194
195 sdata = IEEE80211_DEV_TO_SUB_IF(local->apdev);
196
197 if (skb_headroom(skb) < hlen) {
198 I802_DEBUG_INC(local->rx_expand_skb_head);
199 if (pskb_expand_head(skb, hlen, 0, GFP_ATOMIC)) {
200 dev_kfree_skb(skb);
201 return;
202 }
203 }
204
205 fi = (struct ieee80211_frame_info *) skb_push(skb, hlen);
206
207 ieee80211_fill_frame_info(local, fi, status);
208 fi->msg_type = htonl(msg_type);
209
210 sdata->stats.rx_packets++;
211 sdata->stats.rx_bytes += skb->len;
212
213 skb_set_mac_header(skb, 0);
214 skb->ip_summed = CHECKSUM_UNNECESSARY;
215 skb->pkt_type = PACKET_OTHERHOST;
216 skb->protocol = htons(ETH_P_802_2);
217 memset(skb->cb, 0, sizeof(skb->cb));
218 netif_rx(skb);
219}
220
221int ieee80211_radar_status(struct ieee80211_hw *hw, int channel,
222 int radar, int radar_type)
223{
224 struct sk_buff *skb;
225 struct ieee80211_radar_info *msg;
226 struct ieee80211_local *local = hw_to_local(hw);
227
228 if (!local->apdev)
229 return 0;
230
231 skb = dev_alloc_skb(sizeof(struct ieee80211_frame_info) +
232 sizeof(struct ieee80211_radar_info));
233
234 if (!skb)
235 return -ENOMEM;
236 skb_reserve(skb, sizeof(struct ieee80211_frame_info));
237
238 msg = (struct ieee80211_radar_info *)
239 skb_put(skb, sizeof(struct ieee80211_radar_info));
240 msg->channel = channel;
241 msg->radar = radar;
242 msg->radar_type = radar_type;
243
244 ieee80211_rx_mgmt(local, skb, NULL, ieee80211_msg_radar);
245 return 0;
246}
247EXPORT_SYMBOL(ieee80211_radar_status);
248
249void ieee80211_key_threshold_notify(struct net_device *dev,
250 struct ieee80211_key *key,
251 struct sta_info *sta)
252{
253 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
254 struct sk_buff *skb;
255 struct ieee80211_msg_key_notification *msg;
256
257 /* if no one will get it anyway, don't even allocate it.
258 * unlikely because this is only relevant for APs
259 * where the device must be open... */
260 if (unlikely(!local->apdev))
261 return;
262
263 skb = dev_alloc_skb(sizeof(struct ieee80211_frame_info) +
264 sizeof(struct ieee80211_msg_key_notification));
265 if (!skb)
266 return;
267
268 skb_reserve(skb, sizeof(struct ieee80211_frame_info));
269 msg = (struct ieee80211_msg_key_notification *)
270 skb_put(skb, sizeof(struct ieee80211_msg_key_notification));
271 msg->tx_rx_count = key->tx_rx_count;
272 memcpy(msg->ifname, dev->name, IFNAMSIZ);
273 if (sta)
274 memcpy(msg->addr, sta->addr, ETH_ALEN);
275 else
276 memset(msg->addr, 0xff, ETH_ALEN);
277
278 key->tx_rx_count = 0;
279
280 ieee80211_rx_mgmt(local, skb, NULL,
281 ieee80211_msg_key_threshold_notification);
282}
283
284static int ieee80211_mgmt_open(struct net_device *dev)
285{
286 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
287
288 if (!netif_running(local->mdev))
289 return -EOPNOTSUPP;
290 return 0;
291}
292
293static int ieee80211_mgmt_stop(struct net_device *dev)
294{
295 return 0;
296}
297
298static int ieee80211_change_mtu_apdev(struct net_device *dev, int new_mtu)
299{
300 /* FIX: what would be proper limits for MTU?
301 * This interface uses 802.11 frames. */
302 if (new_mtu < 256 || new_mtu > IEEE80211_MAX_DATA_LEN) {
303 printk(KERN_WARNING "%s: invalid MTU %d\n",
304 dev->name, new_mtu);
305 return -EINVAL;
306 }
307
308#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
309 printk(KERN_DEBUG "%s: setting MTU %d\n", dev->name, new_mtu);
310#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
311 dev->mtu = new_mtu;
312 return 0;
313}
314
315void ieee80211_if_mgmt_setup(struct net_device *dev)
316{
317 ether_setup(dev);
318 dev->hard_start_xmit = ieee80211_mgmt_start_xmit;
319 dev->change_mtu = ieee80211_change_mtu_apdev;
320 dev->get_stats = ieee80211_get_stats;
321 dev->open = ieee80211_mgmt_open;
322 dev->stop = ieee80211_mgmt_stop;
323 dev->type = ARPHRD_IEEE80211_PRISM;
324 dev->hard_header_parse = header_parse_80211;
325 dev->uninit = ieee80211_if_reinit;
326 dev->destructor = ieee80211_if_free;
327}
328
329/* regular interfaces */
330
331static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
332{
333 /* FIX: what would be proper limits for MTU?
334 * This interface uses 802.3 frames. */
335 if (new_mtu < 256 || new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6) {
336 printk(KERN_WARNING "%s: invalid MTU %d\n",
337 dev->name, new_mtu);
338 return -EINVAL;
339 }
340
341#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
342 printk(KERN_DEBUG "%s: setting MTU %d\n", dev->name, new_mtu);
343#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
344 dev->mtu = new_mtu;
345 return 0;
346}
347
348static inline int identical_mac_addr_allowed(int type1, int type2)
349{
350 return (type1 == IEEE80211_IF_TYPE_MNTR ||
351 type2 == IEEE80211_IF_TYPE_MNTR ||
352 (type1 == IEEE80211_IF_TYPE_AP &&
353 type2 == IEEE80211_IF_TYPE_WDS) ||
354 (type1 == IEEE80211_IF_TYPE_WDS &&
355 (type2 == IEEE80211_IF_TYPE_WDS ||
356 type2 == IEEE80211_IF_TYPE_AP)) ||
357 (type1 == IEEE80211_IF_TYPE_AP &&
358 type2 == IEEE80211_IF_TYPE_VLAN) ||
359 (type1 == IEEE80211_IF_TYPE_VLAN &&
360 (type2 == IEEE80211_IF_TYPE_AP ||
361 type2 == IEEE80211_IF_TYPE_VLAN)));
362}
363
364/* Check if running monitor interfaces should go to a "soft monitor" mode
365 * and switch them if necessary. */
366static inline void ieee80211_start_soft_monitor(struct ieee80211_local *local)
367{
368 struct ieee80211_if_init_conf conf;
369
370 if (local->open_count && local->open_count == local->monitors &&
371 !(local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER) &&
372 local->ops->remove_interface) {
373 conf.if_id = -1;
374 conf.type = IEEE80211_IF_TYPE_MNTR;
375 conf.mac_addr = NULL;
376 local->ops->remove_interface(local_to_hw(local), &conf);
377 }
378}
379
380/* Check if running monitor interfaces should go to a "hard monitor" mode
381 * and switch them if necessary. */
382static void ieee80211_start_hard_monitor(struct ieee80211_local *local)
383{
384 struct ieee80211_if_init_conf conf;
385
386 if (local->open_count && local->open_count == local->monitors &&
387 !(local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER)) {
388 conf.if_id = -1;
389 conf.type = IEEE80211_IF_TYPE_MNTR;
390 conf.mac_addr = NULL;
391 local->ops->add_interface(local_to_hw(local), &conf);
392 }
393}
394
395static int ieee80211_open(struct net_device *dev)
396{
397 struct ieee80211_sub_if_data *sdata, *nsdata;
398 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
399 struct ieee80211_if_init_conf conf;
400 int res;
401
402 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
403 read_lock(&local->sub_if_lock);
404 list_for_each_entry(nsdata, &local->sub_if_list, list) {
405 struct net_device *ndev = nsdata->dev;
406
407 if (ndev != dev && ndev != local->mdev && netif_running(ndev) &&
408 compare_ether_addr(dev->dev_addr, ndev->dev_addr) == 0 &&
409 !identical_mac_addr_allowed(sdata->type, nsdata->type)) {
410 read_unlock(&local->sub_if_lock);
411 return -ENOTUNIQ;
412 }
413 }
414 read_unlock(&local->sub_if_lock);
415
416 if (sdata->type == IEEE80211_IF_TYPE_WDS &&
417 is_zero_ether_addr(sdata->u.wds.remote_addr))
418 return -ENOLINK;
419
420 if (sdata->type == IEEE80211_IF_TYPE_MNTR && local->open_count &&
421 !(local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER)) {
422 /* run the interface in a "soft monitor" mode */
423 local->monitors++;
424 local->open_count++;
425 local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP;
426 return 0;
427 }
428 ieee80211_start_soft_monitor(local);
429
430 conf.if_id = dev->ifindex;
431 conf.type = sdata->type;
432 conf.mac_addr = dev->dev_addr;
433 res = local->ops->add_interface(local_to_hw(local), &conf);
434 if (res) {
435 if (sdata->type == IEEE80211_IF_TYPE_MNTR)
436 ieee80211_start_hard_monitor(local);
437 return res;
438 }
439
440 if (local->open_count == 0) {
441 res = 0;
442 tasklet_enable(&local->tx_pending_tasklet);
443 tasklet_enable(&local->tasklet);
444 if (local->ops->open)
445 res = local->ops->open(local_to_hw(local));
446 if (res == 0) {
447 res = dev_open(local->mdev);
448 if (res) {
449 if (local->ops->stop)
450 local->ops->stop(local_to_hw(local));
451 } else {
452 res = ieee80211_hw_config(local);
453 if (res && local->ops->stop)
454 local->ops->stop(local_to_hw(local));
455 else if (!res && local->apdev)
456 dev_open(local->apdev);
457 }
458 }
459 if (res) {
460 if (local->ops->remove_interface)
461 local->ops->remove_interface(local_to_hw(local),
462 &conf);
463 return res;
464 }
465 }
466 local->open_count++;
467
468 if (sdata->type == IEEE80211_IF_TYPE_MNTR) {
469 local->monitors++;
470 local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP;
471 } else
472 ieee80211_if_config(dev);
473
474 if (sdata->type == IEEE80211_IF_TYPE_STA &&
475 !local->user_space_mlme)
476 netif_carrier_off(dev);
477 else
478 netif_carrier_on(dev);
479
480 netif_start_queue(dev);
481 return 0;
482}
483
484static void ieee80211_if_shutdown(struct net_device *dev)
485{
486 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
487 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
488
489 ASSERT_RTNL();
490 switch (sdata->type) {
491 case IEEE80211_IF_TYPE_STA:
492 case IEEE80211_IF_TYPE_IBSS:
493 sdata->u.sta.state = IEEE80211_DISABLED;
494 del_timer_sync(&sdata->u.sta.timer);
495 skb_queue_purge(&sdata->u.sta.skb_queue);
496 if (!local->ops->hw_scan &&
497 local->scan_dev == sdata->dev) {
498 local->sta_scanning = 0;
499 cancel_delayed_work(&local->scan_work);
500 }
501 flush_workqueue(local->hw.workqueue);
502 break;
503 }
504}
505
506static int ieee80211_stop(struct net_device *dev)
507{
508 struct ieee80211_sub_if_data *sdata;
509 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
510
511 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
512
513 if (sdata->type == IEEE80211_IF_TYPE_MNTR &&
514 local->open_count > 1 &&
515 !(local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER)) {
516 /* remove "soft monitor" interface */
517 local->open_count--;
518 local->monitors--;
519 if (!local->monitors)
520 local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP;
521 return 0;
522 }
523
524 netif_stop_queue(dev);
525 ieee80211_if_shutdown(dev);
526
527 if (sdata->type == IEEE80211_IF_TYPE_MNTR) {
528 local->monitors--;
529 if (!local->monitors)
530 local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP;
531 }
532
533 local->open_count--;
534 if (local->open_count == 0) {
535 if (netif_running(local->mdev))
536 dev_close(local->mdev);
537 if (local->apdev)
538 dev_close(local->apdev);
539 if (local->ops->stop)
540 local->ops->stop(local_to_hw(local));
541 tasklet_disable(&local->tx_pending_tasklet);
542 tasklet_disable(&local->tasklet);
543 }
544 if (local->ops->remove_interface) {
545 struct ieee80211_if_init_conf conf;
546
547 conf.if_id = dev->ifindex;
548 conf.type = sdata->type;
549 conf.mac_addr = dev->dev_addr;
550 local->ops->remove_interface(local_to_hw(local), &conf);
551 }
552
553 ieee80211_start_hard_monitor(local);
554
555 return 0;
556}
557
558enum netif_tx_lock_class {
559 TX_LOCK_NORMAL,
560 TX_LOCK_MASTER,
561};
562
563static inline void netif_tx_lock_nested(struct net_device *dev, int subclass)
564{
565 spin_lock_nested(&dev->_xmit_lock, subclass);
566 dev->xmit_lock_owner = smp_processor_id();
567}
568
569static void ieee80211_set_multicast_list(struct net_device *dev)
570{
571 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
572 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
573 unsigned short flags;
574
575 netif_tx_lock_nested(local->mdev, TX_LOCK_MASTER);
576 if (((dev->flags & IFF_ALLMULTI) != 0) ^ (sdata->allmulti != 0)) {
577 if (sdata->allmulti) {
578 sdata->allmulti = 0;
579 local->iff_allmultis--;
580 } else {
581 sdata->allmulti = 1;
582 local->iff_allmultis++;
583 }
584 }
585 if (((dev->flags & IFF_PROMISC) != 0) ^ (sdata->promisc != 0)) {
586 if (sdata->promisc) {
587 sdata->promisc = 0;
588 local->iff_promiscs--;
589 } else {
590 sdata->promisc = 1;
591 local->iff_promiscs++;
592 }
593 }
594 if (dev->mc_count != sdata->mc_count) {
595 local->mc_count = local->mc_count - sdata->mc_count +
596 dev->mc_count;
597 sdata->mc_count = dev->mc_count;
598 }
599 if (local->ops->set_multicast_list) {
600 flags = local->mdev->flags;
601 if (local->iff_allmultis)
602 flags |= IFF_ALLMULTI;
603 if (local->iff_promiscs)
604 flags |= IFF_PROMISC;
605 read_lock(&local->sub_if_lock);
606 local->ops->set_multicast_list(local_to_hw(local), flags,
607 local->mc_count);
608 read_unlock(&local->sub_if_lock);
609 }
610 netif_tx_unlock(local->mdev);
611}
612
613/* Must not be called for mdev and apdev */
614void ieee80211_if_setup(struct net_device *dev)
615{
616 ether_setup(dev);
617 dev->hard_start_xmit = ieee80211_subif_start_xmit;
618 dev->wireless_handlers = &ieee80211_iw_handler_def;
619 dev->set_multicast_list = ieee80211_set_multicast_list;
620 dev->change_mtu = ieee80211_change_mtu;
621 dev->get_stats = ieee80211_get_stats;
622 dev->open = ieee80211_open;
623 dev->stop = ieee80211_stop;
624 dev->uninit = ieee80211_if_reinit;
625 dev->destructor = ieee80211_if_free;
626}
627
628/* WDS specialties */
629
630int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr)
631{
632 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
633 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
634 struct sta_info *sta;
635
636 if (compare_ether_addr(remote_addr, sdata->u.wds.remote_addr) == 0)
637 return 0;
638
639 /* Create STA entry for the new peer */
640 sta = sta_info_add(local, dev, remote_addr, GFP_KERNEL);
641 if (!sta)
642 return -ENOMEM;
643 sta_info_put(sta);
644
645 /* Remove STA entry for the old peer */
646 sta = sta_info_get(local, sdata->u.wds.remote_addr);
647 if (sta) {
648 sta_info_put(sta);
649 sta_info_free(sta, 0);
650 } else {
651 printk(KERN_DEBUG "%s: could not find STA entry for WDS link "
652 "peer " MAC_FMT "\n",
653 dev->name, MAC_ARG(sdata->u.wds.remote_addr));
654 }
655
656 /* Update WDS link data */
657 memcpy(&sdata->u.wds.remote_addr, remote_addr, ETH_ALEN);
658
659 return 0;
660}
661
662/* everything else */
64 663
65static int rate_list_match(const int *rate_list, int rate) 664static int rate_list_match(const int *rate_list, int rate)
66{ 665{
@@ -76,7 +675,6 @@ static int rate_list_match(const int *rate_list, int rate)
76 return 0; 675 return 0;
77} 676}
78 677
79
80void ieee80211_prepare_rates(struct ieee80211_local *local, 678void ieee80211_prepare_rates(struct ieee80211_local *local,
81 struct ieee80211_hw_mode *mode) 679 struct ieee80211_hw_mode *mode)
82{ 680{
@@ -150,43 +748,6 @@ void ieee80211_prepare_rates(struct ieee80211_local *local,
150 } 748 }
151} 749}
152 750
153
154void ieee80211_key_threshold_notify(struct net_device *dev,
155 struct ieee80211_key *key,
156 struct sta_info *sta)
157{
158 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
159 struct sk_buff *skb;
160 struct ieee80211_msg_key_notification *msg;
161
162 /* if no one will get it anyway, don't even allocate it.
163 * unlikely because this is only relevant for APs
164 * where the device must be open... */
165 if (unlikely(!local->apdev))
166 return;
167
168 skb = dev_alloc_skb(sizeof(struct ieee80211_frame_info) +
169 sizeof(struct ieee80211_msg_key_notification));
170 if (!skb)
171 return;
172
173 skb_reserve(skb, sizeof(struct ieee80211_frame_info));
174 msg = (struct ieee80211_msg_key_notification *)
175 skb_put(skb, sizeof(struct ieee80211_msg_key_notification));
176 msg->tx_rx_count = key->tx_rx_count;
177 memcpy(msg->ifname, dev->name, IFNAMSIZ);
178 if (sta)
179 memcpy(msg->addr, sta->addr, ETH_ALEN);
180 else
181 memset(msg->addr, 0xff, ETH_ALEN);
182
183 key->tx_rx_count = 0;
184
185 ieee80211_rx_mgmt(local, skb, NULL,
186 ieee80211_msg_key_threshold_notification);
187}
188
189
190u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len) 751u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len)
191{ 752{
192 u16 fc; 753 u16 fc;
@@ -300,7 +861,6 @@ int ieee80211_is_eapol(const struct sk_buff *skb)
300 return 0; 861 return 0;
301} 862}
302 863
303
304void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx) 864void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx)
305{ 865{
306 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; 866 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
@@ -317,7 +877,6 @@ void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx)
317 } 877 }
318} 878}
319 879
320
321static int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, 880static int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
322 int rate, int erp, int short_preamble) 881 int rate, int erp, int short_preamble)
323{ 882{
@@ -373,7 +932,6 @@ static int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
373 return dur; 932 return dur;
374} 933}
375 934
376
377/* Exported duration function for driver use */ 935/* Exported duration function for driver use */
378__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, 936__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
379 size_t frame_len, int rate) 937 size_t frame_len, int rate)
@@ -390,7 +948,6 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
390} 948}
391EXPORT_SYMBOL(ieee80211_generic_frame_duration); 949EXPORT_SYMBOL(ieee80211_generic_frame_duration);
392 950
393
394__le16 ieee80211_rts_duration(struct ieee80211_hw *hw, 951__le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
395 size_t frame_len, 952 size_t frame_len,
396 const struct ieee80211_tx_control *frame_txctl) 953 const struct ieee80211_tx_control *frame_txctl)
@@ -418,7 +975,6 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
418} 975}
419EXPORT_SYMBOL(ieee80211_rts_duration); 976EXPORT_SYMBOL(ieee80211_rts_duration);
420 977
421
422__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, 978__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
423 size_t frame_len, 979 size_t frame_len,
424 const struct ieee80211_tx_control *frame_txctl) 980 const struct ieee80211_tx_control *frame_txctl)
@@ -536,97 +1092,6 @@ int ieee80211_hw_config(struct ieee80211_local *local)
536 return ret; 1092 return ret;
537} 1093}
538 1094
539
540static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
541{
542 /* FIX: what would be proper limits for MTU?
543 * This interface uses 802.3 frames. */
544 if (new_mtu < 256 || new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6) {
545 printk(KERN_WARNING "%s: invalid MTU %d\n",
546 dev->name, new_mtu);
547 return -EINVAL;
548 }
549
550#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
551 printk(KERN_DEBUG "%s: setting MTU %d\n", dev->name, new_mtu);
552#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
553 dev->mtu = new_mtu;
554 return 0;
555}
556
557
558static int ieee80211_change_mtu_apdev(struct net_device *dev, int new_mtu)
559{
560 /* FIX: what would be proper limits for MTU?
561 * This interface uses 802.11 frames. */
562 if (new_mtu < 256 || new_mtu > IEEE80211_MAX_DATA_LEN) {
563 printk(KERN_WARNING "%s: invalid MTU %d\n",
564 dev->name, new_mtu);
565 return -EINVAL;
566 }
567
568#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
569 printk(KERN_DEBUG "%s: setting MTU %d\n", dev->name, new_mtu);
570#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
571 dev->mtu = new_mtu;
572 return 0;
573}
574
575enum netif_tx_lock_class {
576 TX_LOCK_NORMAL,
577 TX_LOCK_MASTER,
578};
579
580static inline void netif_tx_lock_nested(struct net_device *dev, int subclass)
581{
582 spin_lock_nested(&dev->_xmit_lock, subclass);
583 dev->xmit_lock_owner = smp_processor_id();
584}
585
586static void ieee80211_set_multicast_list(struct net_device *dev)
587{
588 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
589 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
590 unsigned short flags;
591
592 netif_tx_lock_nested(local->mdev, TX_LOCK_MASTER);
593 if (((dev->flags & IFF_ALLMULTI) != 0) ^ (sdata->allmulti != 0)) {
594 if (sdata->allmulti) {
595 sdata->allmulti = 0;
596 local->iff_allmultis--;
597 } else {
598 sdata->allmulti = 1;
599 local->iff_allmultis++;
600 }
601 }
602 if (((dev->flags & IFF_PROMISC) != 0) ^ (sdata->promisc != 0)) {
603 if (sdata->promisc) {
604 sdata->promisc = 0;
605 local->iff_promiscs--;
606 } else {
607 sdata->promisc = 1;
608 local->iff_promiscs++;
609 }
610 }
611 if (dev->mc_count != sdata->mc_count) {
612 local->mc_count = local->mc_count - sdata->mc_count +
613 dev->mc_count;
614 sdata->mc_count = dev->mc_count;
615 }
616 if (local->ops->set_multicast_list) {
617 flags = local->mdev->flags;
618 if (local->iff_allmultis)
619 flags |= IFF_ALLMULTI;
620 if (local->iff_promiscs)
621 flags |= IFF_PROMISC;
622 read_lock(&local->sub_if_lock);
623 local->ops->set_multicast_list(local_to_hw(local), flags,
624 local->mc_count);
625 read_unlock(&local->sub_if_lock);
626 }
627 netif_tx_unlock(local->mdev);
628}
629
630struct dev_mc_list *ieee80211_get_mc_list_item(struct ieee80211_hw *hw, 1095struct dev_mc_list *ieee80211_get_mc_list_item(struct ieee80211_hw *hw,
631 struct dev_mc_list *prev, 1096 struct dev_mc_list *prev,
632 void **ptr) 1097 void **ptr)
@@ -658,276 +1123,6 @@ struct dev_mc_list *ieee80211_get_mc_list_item(struct ieee80211_hw *hw,
658} 1123}
659EXPORT_SYMBOL(ieee80211_get_mc_list_item); 1124EXPORT_SYMBOL(ieee80211_get_mc_list_item);
660 1125
661static struct net_device_stats *ieee80211_get_stats(struct net_device *dev)
662{
663 struct ieee80211_sub_if_data *sdata;
664 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
665 return &(sdata->stats);
666}
667
668static void ieee80211_if_shutdown(struct net_device *dev)
669{
670 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
671 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
672
673 ASSERT_RTNL();
674 switch (sdata->type) {
675 case IEEE80211_IF_TYPE_STA:
676 case IEEE80211_IF_TYPE_IBSS:
677 sdata->u.sta.state = IEEE80211_DISABLED;
678 del_timer_sync(&sdata->u.sta.timer);
679 skb_queue_purge(&sdata->u.sta.skb_queue);
680 if (!local->ops->hw_scan &&
681 local->scan_dev == sdata->dev) {
682 local->sta_scanning = 0;
683 cancel_delayed_work(&local->scan_work);
684 }
685 flush_workqueue(local->hw.workqueue);
686 break;
687 }
688}
689
690static inline int identical_mac_addr_allowed(int type1, int type2)
691{
692 return (type1 == IEEE80211_IF_TYPE_MNTR ||
693 type2 == IEEE80211_IF_TYPE_MNTR ||
694 (type1 == IEEE80211_IF_TYPE_AP &&
695 type2 == IEEE80211_IF_TYPE_WDS) ||
696 (type1 == IEEE80211_IF_TYPE_WDS &&
697 (type2 == IEEE80211_IF_TYPE_WDS ||
698 type2 == IEEE80211_IF_TYPE_AP)) ||
699 (type1 == IEEE80211_IF_TYPE_AP &&
700 type2 == IEEE80211_IF_TYPE_VLAN) ||
701 (type1 == IEEE80211_IF_TYPE_VLAN &&
702 (type2 == IEEE80211_IF_TYPE_AP ||
703 type2 == IEEE80211_IF_TYPE_VLAN)));
704}
705
706static int ieee80211_master_open(struct net_device *dev)
707{
708 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
709 struct ieee80211_sub_if_data *sdata;
710 int res = -EOPNOTSUPP;
711
712 read_lock(&local->sub_if_lock);
713 list_for_each_entry(sdata, &local->sub_if_list, list) {
714 if (sdata->dev != dev && netif_running(sdata->dev)) {
715 res = 0;
716 break;
717 }
718 }
719 read_unlock(&local->sub_if_lock);
720 return res;
721}
722
723static int ieee80211_master_stop(struct net_device *dev)
724{
725 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
726 struct ieee80211_sub_if_data *sdata;
727
728 read_lock(&local->sub_if_lock);
729 list_for_each_entry(sdata, &local->sub_if_list, list)
730 if (sdata->dev != dev && netif_running(sdata->dev))
731 dev_close(sdata->dev);
732 read_unlock(&local->sub_if_lock);
733
734 return 0;
735}
736
737static int ieee80211_mgmt_open(struct net_device *dev)
738{
739 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
740
741 if (!netif_running(local->mdev))
742 return -EOPNOTSUPP;
743 return 0;
744}
745
746static int ieee80211_mgmt_stop(struct net_device *dev)
747{
748 return 0;
749}
750
751/* Check if running monitor interfaces should go to a "soft monitor" mode
752 * and switch them if necessary. */
753static inline void ieee80211_start_soft_monitor(struct ieee80211_local *local)
754{
755 struct ieee80211_if_init_conf conf;
756
757 if (local->open_count && local->open_count == local->monitors &&
758 !(local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER) &&
759 local->ops->remove_interface) {
760 conf.if_id = -1;
761 conf.type = IEEE80211_IF_TYPE_MNTR;
762 conf.mac_addr = NULL;
763 local->ops->remove_interface(local_to_hw(local), &conf);
764 }
765}
766
767/* Check if running monitor interfaces should go to a "hard monitor" mode
768 * and switch them if necessary. */
769static void ieee80211_start_hard_monitor(struct ieee80211_local *local)
770{
771 struct ieee80211_if_init_conf conf;
772
773 if (local->open_count && local->open_count == local->monitors &&
774 !(local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER)) {
775 conf.if_id = -1;
776 conf.type = IEEE80211_IF_TYPE_MNTR;
777 conf.mac_addr = NULL;
778 local->ops->add_interface(local_to_hw(local), &conf);
779 }
780}
781
782static int ieee80211_open(struct net_device *dev)
783{
784 struct ieee80211_sub_if_data *sdata, *nsdata;
785 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
786 struct ieee80211_if_init_conf conf;
787 int res;
788
789 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
790 read_lock(&local->sub_if_lock);
791 list_for_each_entry(nsdata, &local->sub_if_list, list) {
792 struct net_device *ndev = nsdata->dev;
793
794 if (ndev != dev && ndev != local->mdev && netif_running(ndev) &&
795 compare_ether_addr(dev->dev_addr, ndev->dev_addr) == 0 &&
796 !identical_mac_addr_allowed(sdata->type, nsdata->type)) {
797 read_unlock(&local->sub_if_lock);
798 return -ENOTUNIQ;
799 }
800 }
801 read_unlock(&local->sub_if_lock);
802
803 if (sdata->type == IEEE80211_IF_TYPE_WDS &&
804 is_zero_ether_addr(sdata->u.wds.remote_addr))
805 return -ENOLINK;
806
807 if (sdata->type == IEEE80211_IF_TYPE_MNTR && local->open_count &&
808 !(local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER)) {
809 /* run the interface in a "soft monitor" mode */
810 local->monitors++;
811 local->open_count++;
812 local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP;
813 return 0;
814 }
815 ieee80211_start_soft_monitor(local);
816
817 conf.if_id = dev->ifindex;
818 conf.type = sdata->type;
819 conf.mac_addr = dev->dev_addr;
820 res = local->ops->add_interface(local_to_hw(local), &conf);
821 if (res) {
822 if (sdata->type == IEEE80211_IF_TYPE_MNTR)
823 ieee80211_start_hard_monitor(local);
824 return res;
825 }
826
827 if (local->open_count == 0) {
828 res = 0;
829 tasklet_enable(&local->tx_pending_tasklet);
830 tasklet_enable(&local->tasklet);
831 if (local->ops->open)
832 res = local->ops->open(local_to_hw(local));
833 if (res == 0) {
834 res = dev_open(local->mdev);
835 if (res) {
836 if (local->ops->stop)
837 local->ops->stop(local_to_hw(local));
838 } else {
839 res = ieee80211_hw_config(local);
840 if (res && local->ops->stop)
841 local->ops->stop(local_to_hw(local));
842 else if (!res && local->apdev)
843 dev_open(local->apdev);
844 }
845 }
846 if (res) {
847 if (local->ops->remove_interface)
848 local->ops->remove_interface(local_to_hw(local),
849 &conf);
850 return res;
851 }
852 }
853 local->open_count++;
854
855 if (sdata->type == IEEE80211_IF_TYPE_MNTR) {
856 local->monitors++;
857 local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP;
858 } else
859 ieee80211_if_config(dev);
860
861 if (sdata->type == IEEE80211_IF_TYPE_STA &&
862 !local->user_space_mlme)
863 netif_carrier_off(dev);
864 else
865 netif_carrier_on(dev);
866
867 netif_start_queue(dev);
868 return 0;
869}
870
871
872static int ieee80211_stop(struct net_device *dev)
873{
874 struct ieee80211_sub_if_data *sdata;
875 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
876
877 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
878
879 if (sdata->type == IEEE80211_IF_TYPE_MNTR &&
880 local->open_count > 1 &&
881 !(local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER)) {
882 /* remove "soft monitor" interface */
883 local->open_count--;
884 local->monitors--;
885 if (!local->monitors)
886 local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP;
887 return 0;
888 }
889
890 netif_stop_queue(dev);
891 ieee80211_if_shutdown(dev);
892
893 if (sdata->type == IEEE80211_IF_TYPE_MNTR) {
894 local->monitors--;
895 if (!local->monitors)
896 local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP;
897 }
898
899 local->open_count--;
900 if (local->open_count == 0) {
901 if (netif_running(local->mdev))
902 dev_close(local->mdev);
903 if (local->apdev)
904 dev_close(local->apdev);
905 if (local->ops->stop)
906 local->ops->stop(local_to_hw(local));
907 tasklet_disable(&local->tx_pending_tasklet);
908 tasklet_disable(&local->tasklet);
909 }
910 if (local->ops->remove_interface) {
911 struct ieee80211_if_init_conf conf;
912
913 conf.if_id = dev->ifindex;
914 conf.type = sdata->type;
915 conf.mac_addr = dev->dev_addr;
916 local->ops->remove_interface(local_to_hw(local), &conf);
917 }
918
919 ieee80211_start_hard_monitor(local);
920
921 return 0;
922}
923
924
925static int header_parse_80211(struct sk_buff *skb, unsigned char *haddr)
926{
927 memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */
928 return ETH_ALEN;
929}
930
931struct ieee80211_rate * 1126struct ieee80211_rate *
932ieee80211_get_rate(struct ieee80211_local *local, int phymode, int hw_rate) 1127ieee80211_get_rate(struct ieee80211_local *local, int phymode, int hw_rate)
933{ 1128{
@@ -949,142 +1144,6 @@ ieee80211_get_rate(struct ieee80211_local *local, int phymode, int hw_rate)
949 return NULL; 1144 return NULL;
950} 1145}
951 1146
952static void
953ieee80211_fill_frame_info(struct ieee80211_local *local,
954 struct ieee80211_frame_info *fi,
955 struct ieee80211_rx_status *status)
956{
957 if (status) {
958 struct timespec ts;
959 struct ieee80211_rate *rate;
960
961 jiffies_to_timespec(jiffies, &ts);
962 fi->hosttime = cpu_to_be64((u64) ts.tv_sec * 1000000 +
963 ts.tv_nsec / 1000);
964 fi->mactime = cpu_to_be64(status->mactime);
965 switch (status->phymode) {
966 case MODE_IEEE80211A:
967 fi->phytype = htonl(ieee80211_phytype_ofdm_dot11_a);
968 break;
969 case MODE_IEEE80211B:
970 fi->phytype = htonl(ieee80211_phytype_dsss_dot11_b);
971 break;
972 case MODE_IEEE80211G:
973 fi->phytype = htonl(ieee80211_phytype_pbcc_dot11_g);
974 break;
975 case MODE_ATHEROS_TURBO:
976 fi->phytype =
977 htonl(ieee80211_phytype_dsss_dot11_turbo);
978 break;
979 default:
980 fi->phytype = htonl(0xAAAAAAAA);
981 break;
982 }
983 fi->channel = htonl(status->channel);
984 rate = ieee80211_get_rate(local, status->phymode,
985 status->rate);
986 if (rate) {
987 fi->datarate = htonl(rate->rate);
988 if (rate->flags & IEEE80211_RATE_PREAMBLE2) {
989 if (status->rate == rate->val)
990 fi->preamble = htonl(2); /* long */
991 else if (status->rate == rate->val2)
992 fi->preamble = htonl(1); /* short */
993 } else
994 fi->preamble = htonl(0);
995 } else {
996 fi->datarate = htonl(0);
997 fi->preamble = htonl(0);
998 }
999
1000 fi->antenna = htonl(status->antenna);
1001 fi->priority = htonl(0xffffffff); /* no clue */
1002 fi->ssi_type = htonl(ieee80211_ssi_raw);
1003 fi->ssi_signal = htonl(status->ssi);
1004 fi->ssi_noise = 0x00000000;
1005 fi->encoding = 0;
1006 } else {
1007 /* clear everything because we really don't know.
1008 * the msg_type field isn't present on monitor frames
1009 * so we don't know whether it will be present or not,
1010 * but it's ok to not clear it since it'll be assigned
1011 * anyway */
1012 memset(fi, 0, sizeof(*fi) - sizeof(fi->msg_type));
1013
1014 fi->ssi_type = htonl(ieee80211_ssi_none);
1015 }
1016 fi->version = htonl(IEEE80211_FI_VERSION);
1017 fi->length = cpu_to_be32(sizeof(*fi) - sizeof(fi->msg_type));
1018}
1019
1020/* this routine is actually not just for this, but also
1021 * for pushing fake 'management' frames into userspace.
1022 * it shall be replaced by a netlink-based system. */
1023void
1024ieee80211_rx_mgmt(struct ieee80211_local *local, struct sk_buff *skb,
1025 struct ieee80211_rx_status *status, u32 msg_type)
1026{
1027 struct ieee80211_frame_info *fi;
1028 const size_t hlen = sizeof(struct ieee80211_frame_info);
1029 struct ieee80211_sub_if_data *sdata;
1030
1031 skb->dev = local->apdev;
1032
1033 sdata = IEEE80211_DEV_TO_SUB_IF(local->apdev);
1034
1035 if (skb_headroom(skb) < hlen) {
1036 I802_DEBUG_INC(local->rx_expand_skb_head);
1037 if (pskb_expand_head(skb, hlen, 0, GFP_ATOMIC)) {
1038 dev_kfree_skb(skb);
1039 return;
1040 }
1041 }
1042
1043 fi = (struct ieee80211_frame_info *) skb_push(skb, hlen);
1044
1045 ieee80211_fill_frame_info(local, fi, status);
1046 fi->msg_type = htonl(msg_type);
1047
1048 sdata->stats.rx_packets++;
1049 sdata->stats.rx_bytes += skb->len;
1050
1051 skb_set_mac_header(skb, 0);
1052 skb->ip_summed = CHECKSUM_UNNECESSARY;
1053 skb->pkt_type = PACKET_OTHERHOST;
1054 skb->protocol = htons(ETH_P_802_2);
1055 memset(skb->cb, 0, sizeof(skb->cb));
1056 netif_rx(skb);
1057}
1058
1059int ieee80211_radar_status(struct ieee80211_hw *hw, int channel,
1060 int radar, int radar_type)
1061{
1062 struct sk_buff *skb;
1063 struct ieee80211_radar_info *msg;
1064 struct ieee80211_local *local = hw_to_local(hw);
1065
1066 if (!local->apdev)
1067 return 0;
1068
1069 skb = dev_alloc_skb(sizeof(struct ieee80211_frame_info) +
1070 sizeof(struct ieee80211_radar_info));
1071
1072 if (!skb)
1073 return -ENOMEM;
1074 skb_reserve(skb, sizeof(struct ieee80211_frame_info));
1075
1076 msg = (struct ieee80211_radar_info *)
1077 skb_put(skb, sizeof(struct ieee80211_radar_info));
1078 msg->channel = channel;
1079 msg->radar = radar;
1080 msg->radar_type = radar_type;
1081
1082 ieee80211_rx_mgmt(local, skb, NULL, ieee80211_msg_radar);
1083 return 0;
1084}
1085EXPORT_SYMBOL(ieee80211_radar_status);
1086
1087
1088static void ieee80211_stat_refresh(unsigned long data) 1147static void ieee80211_stat_refresh(unsigned long data)
1089{ 1148{
1090 struct ieee80211_local *local = (struct ieee80211_local *) data; 1149 struct ieee80211_local *local = (struct ieee80211_local *) data;
@@ -1121,7 +1180,6 @@ static void ieee80211_stat_refresh(unsigned long data)
1121 add_timer(&local->stat_timer); 1180 add_timer(&local->stat_timer);
1122} 1181}
1123 1182
1124
1125void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, 1183void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
1126 struct sk_buff *skb, 1184 struct sk_buff *skb,
1127 struct ieee80211_tx_status *status) 1185 struct ieee80211_tx_status *status)
@@ -1198,7 +1256,6 @@ static void ieee80211_tasklet_handler(unsigned long data)
1198 } 1256 }
1199} 1257}
1200 1258
1201
1202/* Remove added headers (e.g., QoS control), encryption header/MIC, etc. to 1259/* Remove added headers (e.g., QoS control), encryption header/MIC, etc. to
1203 * make a prepared TX frame (one that has been given to hw) to look like brand 1260 * make a prepared TX frame (one that has been given to hw) to look like brand
1204 * new IEEE 802.11 frame that is ready to go through TX processing again. 1261 * new IEEE 802.11 frame that is ready to go through TX processing again.
@@ -1261,7 +1318,6 @@ no_key:
1261 } 1318 }
1262} 1319}
1263 1320
1264
1265void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, 1321void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
1266 struct ieee80211_tx_status *status) 1322 struct ieee80211_tx_status *status)
1267{ 1323{
@@ -1480,68 +1536,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
1480} 1536}
1481EXPORT_SYMBOL(ieee80211_tx_status); 1537EXPORT_SYMBOL(ieee80211_tx_status);
1482 1538
1483
1484int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr)
1485{
1486 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1487 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1488 struct sta_info *sta;
1489
1490 if (compare_ether_addr(remote_addr, sdata->u.wds.remote_addr) == 0)
1491 return 0;
1492
1493 /* Create STA entry for the new peer */
1494 sta = sta_info_add(local, dev, remote_addr, GFP_KERNEL);
1495 if (!sta)
1496 return -ENOMEM;
1497 sta_info_put(sta);
1498
1499 /* Remove STA entry for the old peer */
1500 sta = sta_info_get(local, sdata->u.wds.remote_addr);
1501 if (sta) {
1502 sta_info_put(sta);
1503 sta_info_free(sta, 0);
1504 } else {
1505 printk(KERN_DEBUG "%s: could not find STA entry for WDS link "
1506 "peer " MAC_FMT "\n",
1507 dev->name, MAC_ARG(sdata->u.wds.remote_addr));
1508 }
1509
1510 /* Update WDS link data */
1511 memcpy(&sdata->u.wds.remote_addr, remote_addr, ETH_ALEN);
1512
1513 return 0;
1514}
1515
1516/* Must not be called for mdev and apdev */
1517void ieee80211_if_setup(struct net_device *dev)
1518{
1519 ether_setup(dev);
1520 dev->hard_start_xmit = ieee80211_subif_start_xmit;
1521 dev->wireless_handlers = &ieee80211_iw_handler_def;
1522 dev->set_multicast_list = ieee80211_set_multicast_list;
1523 dev->change_mtu = ieee80211_change_mtu;
1524 dev->get_stats = ieee80211_get_stats;
1525 dev->open = ieee80211_open;
1526 dev->stop = ieee80211_stop;
1527 dev->uninit = ieee80211_if_reinit;
1528 dev->destructor = ieee80211_if_free;
1529}
1530
1531void ieee80211_if_mgmt_setup(struct net_device *dev)
1532{
1533 ether_setup(dev);
1534 dev->hard_start_xmit = ieee80211_mgmt_start_xmit;
1535 dev->change_mtu = ieee80211_change_mtu_apdev;
1536 dev->get_stats = ieee80211_get_stats;
1537 dev->open = ieee80211_mgmt_open;
1538 dev->stop = ieee80211_mgmt_stop;
1539 dev->type = ARPHRD_IEEE80211_PRISM;
1540 dev->hard_header_parse = header_parse_80211;
1541 dev->uninit = ieee80211_if_reinit;
1542 dev->destructor = ieee80211_if_free;
1543}
1544
1545struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, 1539struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
1546 const struct ieee80211_ops *ops) 1540 const struct ieee80211_ops *ops)
1547{ 1541{
@@ -1948,7 +1942,6 @@ static int __init ieee80211_init(void)
1948 return 0; 1942 return 0;
1949} 1943}
1950 1944
1951
1952static void __exit ieee80211_exit(void) 1945static void __exit ieee80211_exit(void)
1953{ 1946{
1954 ieee80211_wme_unregister(); 1947 ieee80211_wme_unregister();