diff options
Diffstat (limited to 'net/wireless/util.c')
-rw-r--r-- | net/wireless/util.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/net/wireless/util.c b/net/wireless/util.c index 693275a16a26..3fc2df86278f 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -574,3 +574,111 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev) | |||
574 | kfree(wdev->connect_keys); | 574 | kfree(wdev->connect_keys); |
575 | wdev->connect_keys = NULL; | 575 | wdev->connect_keys = NULL; |
576 | } | 576 | } |
577 | |||
578 | static void cfg80211_process_wdev_events(struct wireless_dev *wdev) | ||
579 | { | ||
580 | struct cfg80211_event *ev; | ||
581 | unsigned long flags; | ||
582 | const u8 *bssid = NULL; | ||
583 | |||
584 | spin_lock_irqsave(&wdev->event_lock, flags); | ||
585 | while (!list_empty(&wdev->event_list)) { | ||
586 | ev = list_first_entry(&wdev->event_list, | ||
587 | struct cfg80211_event, list); | ||
588 | list_del(&ev->list); | ||
589 | spin_unlock_irqrestore(&wdev->event_lock, flags); | ||
590 | |||
591 | wdev_lock(wdev); | ||
592 | switch (ev->type) { | ||
593 | case EVENT_CONNECT_RESULT: | ||
594 | if (!is_zero_ether_addr(ev->cr.bssid)) | ||
595 | bssid = ev->cr.bssid; | ||
596 | __cfg80211_connect_result( | ||
597 | wdev->netdev, bssid, | ||
598 | ev->cr.req_ie, ev->cr.req_ie_len, | ||
599 | ev->cr.resp_ie, ev->cr.resp_ie_len, | ||
600 | ev->cr.status, | ||
601 | ev->cr.status == WLAN_STATUS_SUCCESS, | ||
602 | NULL); | ||
603 | break; | ||
604 | case EVENT_ROAMED: | ||
605 | __cfg80211_roamed(wdev, ev->rm.bssid, | ||
606 | ev->rm.req_ie, ev->rm.req_ie_len, | ||
607 | ev->rm.resp_ie, ev->rm.resp_ie_len); | ||
608 | break; | ||
609 | case EVENT_DISCONNECTED: | ||
610 | __cfg80211_disconnected(wdev->netdev, | ||
611 | ev->dc.ie, ev->dc.ie_len, | ||
612 | ev->dc.reason, true); | ||
613 | break; | ||
614 | case EVENT_IBSS_JOINED: | ||
615 | __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid); | ||
616 | break; | ||
617 | } | ||
618 | wdev_unlock(wdev); | ||
619 | |||
620 | kfree(ev); | ||
621 | |||
622 | spin_lock_irqsave(&wdev->event_lock, flags); | ||
623 | } | ||
624 | spin_unlock_irqrestore(&wdev->event_lock, flags); | ||
625 | } | ||
626 | |||
627 | void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev) | ||
628 | { | ||
629 | struct wireless_dev *wdev; | ||
630 | |||
631 | ASSERT_RTNL(); | ||
632 | ASSERT_RDEV_LOCK(rdev); | ||
633 | |||
634 | mutex_lock(&rdev->devlist_mtx); | ||
635 | |||
636 | list_for_each_entry(wdev, &rdev->netdev_list, list) | ||
637 | cfg80211_process_wdev_events(wdev); | ||
638 | |||
639 | mutex_unlock(&rdev->devlist_mtx); | ||
640 | } | ||
641 | |||
642 | int cfg80211_change_iface(struct cfg80211_registered_device *rdev, | ||
643 | struct net_device *dev, enum nl80211_iftype ntype, | ||
644 | u32 *flags, struct vif_params *params) | ||
645 | { | ||
646 | int err; | ||
647 | enum nl80211_iftype otype = dev->ieee80211_ptr->iftype; | ||
648 | |||
649 | ASSERT_RDEV_LOCK(rdev); | ||
650 | |||
651 | /* don't support changing VLANs, you just re-create them */ | ||
652 | if (otype == NL80211_IFTYPE_AP_VLAN) | ||
653 | return -EOPNOTSUPP; | ||
654 | |||
655 | if (!rdev->ops->change_virtual_intf || | ||
656 | !(rdev->wiphy.interface_modes & (1 << ntype))) | ||
657 | return -EOPNOTSUPP; | ||
658 | |||
659 | if (ntype != otype) { | ||
660 | switch (otype) { | ||
661 | case NL80211_IFTYPE_ADHOC: | ||
662 | cfg80211_leave_ibss(rdev, dev, false); | ||
663 | break; | ||
664 | case NL80211_IFTYPE_STATION: | ||
665 | cfg80211_disconnect(rdev, dev, | ||
666 | WLAN_REASON_DEAUTH_LEAVING, true); | ||
667 | break; | ||
668 | case NL80211_IFTYPE_MESH_POINT: | ||
669 | /* mesh should be handled? */ | ||
670 | break; | ||
671 | default: | ||
672 | break; | ||
673 | } | ||
674 | |||
675 | cfg80211_process_rdev_events(rdev); | ||
676 | } | ||
677 | |||
678 | err = rdev->ops->change_virtual_intf(&rdev->wiphy, dev, | ||
679 | ntype, flags, params); | ||
680 | |||
681 | WARN_ON(!err && dev->ieee80211_ptr->iftype != ntype); | ||
682 | |||
683 | return err; | ||
684 | } | ||