~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to net/wireless/core.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
46
46
/* for the cleanup, scan and event works */
47
47
struct workqueue_struct *cfg80211_wq;
48
48
 
 
49
static bool cfg80211_disable_40mhz_24ghz;
 
50
module_param(cfg80211_disable_40mhz_24ghz, bool, 0644);
 
51
MODULE_PARM_DESC(cfg80211_disable_40mhz_24ghz,
 
52
                 "Disable 40MHz support in the 2.4GHz band");
 
53
 
49
54
/* requires cfg80211_mutex to be held! */
50
55
struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx)
51
56
{
361
366
 
362
367
        mutex_init(&rdev->mtx);
363
368
        mutex_init(&rdev->devlist_mtx);
 
369
        mutex_init(&rdev->sched_scan_mtx);
364
370
        INIT_LIST_HEAD(&rdev->netdev_list);
365
371
        spin_lock_init(&rdev->bss_lock);
366
372
        INIT_LIST_HEAD(&rdev->bss_list);
367
373
        INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
368
 
 
 
374
        INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results);
369
375
#ifdef CONFIG_CFG80211_WEXT
370
376
        rdev->wiphy.wext = &cfg80211_wext_handler;
371
377
#endif
411
417
}
412
418
EXPORT_SYMBOL(wiphy_new);
413
419
 
 
420
static int wiphy_verify_combinations(struct wiphy *wiphy)
 
421
{
 
422
        const struct ieee80211_iface_combination *c;
 
423
        int i, j;
 
424
 
 
425
        /* If we have combinations enforce them */
 
426
        if (wiphy->n_iface_combinations)
 
427
                wiphy->flags |= WIPHY_FLAG_ENFORCE_COMBINATIONS;
 
428
 
 
429
        for (i = 0; i < wiphy->n_iface_combinations; i++) {
 
430
                u32 cnt = 0;
 
431
                u16 all_iftypes = 0;
 
432
 
 
433
                c = &wiphy->iface_combinations[i];
 
434
 
 
435
                /* Combinations with just one interface aren't real */
 
436
                if (WARN_ON(c->max_interfaces < 2))
 
437
                        return -EINVAL;
 
438
 
 
439
                /* Need at least one channel */
 
440
                if (WARN_ON(!c->num_different_channels))
 
441
                        return -EINVAL;
 
442
 
 
443
                if (WARN_ON(!c->n_limits))
 
444
                        return -EINVAL;
 
445
 
 
446
                for (j = 0; j < c->n_limits; j++) {
 
447
                        u16 types = c->limits[j].types;
 
448
 
 
449
                        /*
 
450
                         * interface types shouldn't overlap, this is
 
451
                         * used in cfg80211_can_change_interface()
 
452
                         */
 
453
                        if (WARN_ON(types & all_iftypes))
 
454
                                return -EINVAL;
 
455
                        all_iftypes |= types;
 
456
 
 
457
                        if (WARN_ON(!c->limits[j].max))
 
458
                                return -EINVAL;
 
459
 
 
460
                        /* Shouldn't list software iftypes in combinations! */
 
461
                        if (WARN_ON(wiphy->software_iftypes & types))
 
462
                                return -EINVAL;
 
463
 
 
464
                        cnt += c->limits[j].max;
 
465
                        /*
 
466
                         * Don't advertise an unsupported type
 
467
                         * in a combination.
 
468
                         */
 
469
                        if (WARN_ON((wiphy->interface_modes & types) != types))
 
470
                                return -EINVAL;
 
471
                }
 
472
 
 
473
                /* You can't even choose that many! */
 
474
                if (WARN_ON(cnt < c->max_interfaces))
 
475
                        return -EINVAL;
 
476
        }
 
477
 
 
478
        return 0;
 
479
}
 
480
 
414
481
int wiphy_register(struct wiphy *wiphy)
415
482
{
416
483
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
439
506
        if (WARN_ON(ifmodes != wiphy->interface_modes))
440
507
                wiphy->interface_modes = ifmodes;
441
508
 
 
509
        res = wiphy_verify_combinations(wiphy);
 
510
        if (res)
 
511
                return res;
 
512
 
442
513
        /* sanity check supported bands/channels */
443
514
        for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
444
515
                sband = wiphy->bands[band];
451
522
                        return -EINVAL;
452
523
 
453
524
                /*
 
525
                 * Since cfg80211_disable_40mhz_24ghz is global, we can
 
526
                 * modify the sband's ht data even if the driver uses a
 
527
                 * global structure for that.
 
528
                 */
 
529
                if (cfg80211_disable_40mhz_24ghz &&
 
530
                    band == IEEE80211_BAND_2GHZ &&
 
531
                    sband->ht_cap.ht_supported) {
 
532
                        sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
 
533
                        sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
 
534
                }
 
535
 
 
536
                /*
454
537
                 * Since we use a u32 for rate bitmaps in
455
538
                 * ieee80211_get_response_rate, we cannot
456
539
                 * have more than 32 legacy rates.
476
559
                return -EINVAL;
477
560
        }
478
561
 
 
562
        if (rdev->wiphy.wowlan.n_patterns) {
 
563
                if (WARN_ON(!rdev->wiphy.wowlan.pattern_min_len ||
 
564
                            rdev->wiphy.wowlan.pattern_min_len >
 
565
                            rdev->wiphy.wowlan.pattern_max_len))
 
566
                        return -EINVAL;
 
567
        }
 
568
 
479
569
        /* check and set up bitrates */
480
570
        ieee80211_set_bitrate_flags(wiphy);
481
571
 
612
702
        rfkill_destroy(rdev->rfkill);
613
703
        mutex_destroy(&rdev->mtx);
614
704
        mutex_destroy(&rdev->devlist_mtx);
 
705
        mutex_destroy(&rdev->sched_scan_mtx);
615
706
        list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list)
616
707
                cfg80211_put_bss(&scan->pub);
 
708
        cfg80211_rdev_free_wowlan(rdev);
617
709
        kfree(rdev);
618
710
}
619
711
 
649
741
 
650
742
        cfg80211_unlock_rdev(rdev);
651
743
 
 
744
        mutex_lock(&rdev->sched_scan_mtx);
 
745
 
 
746
        if (WARN_ON(rdev->sched_scan_req &&
 
747
                    rdev->sched_scan_req->dev == wdev->netdev)) {
 
748
                __cfg80211_stop_sched_scan(rdev, false);
 
749
        }
 
750
 
 
751
        mutex_unlock(&rdev->sched_scan_mtx);
 
752
 
652
753
        mutex_lock(&rdev->devlist_mtx);
653
754
        rdev->opencount--;
654
755
        mutex_unlock(&rdev->devlist_mtx);
668
769
        struct net_device *dev = ndev;
669
770
        struct wireless_dev *wdev = dev->ieee80211_ptr;
670
771
        struct cfg80211_registered_device *rdev;
 
772
        int ret;
671
773
 
672
774
        if (!wdev)
673
775
                return NOTIFY_DONE;
718
820
                        wdev->ps = false;
719
821
                /* allow mac80211 to determine the timeout */
720
822
                wdev->ps_timeout = -1;
721
 
                if (rdev->ops->set_power_mgmt)
722
 
                        if (rdev->ops->set_power_mgmt(wdev->wiphy, dev,
723
 
                                                      wdev->ps,
724
 
                                                      wdev->ps_timeout)) {
725
 
                                /* assume this means it's off */
726
 
                                wdev->ps = false;
727
 
                        }
728
823
 
729
824
                if (!dev->ethtool_ops)
730
825
                        dev->ethtool_ops = &cfg80211_ethtool_ops;
741
836
                        break;
742
837
                case NL80211_IFTYPE_P2P_CLIENT:
743
838
                case NL80211_IFTYPE_STATION:
 
839
                        mutex_lock(&rdev->sched_scan_mtx);
 
840
                        __cfg80211_stop_sched_scan(rdev, false);
 
841
                        mutex_unlock(&rdev->sched_scan_mtx);
 
842
 
744
843
                        wdev_lock(wdev);
745
844
#ifdef CONFIG_CFG80211_WEXT
746
845
                        kfree(wdev->wext.ie);
759
858
                default:
760
859
                        break;
761
860
                }
 
861
                wdev->beacon_interval = 0;
762
862
                break;
763
863
        case NETDEV_DOWN:
764
864
                dev_hold(dev);
813
913
                rdev->opencount++;
814
914
                mutex_unlock(&rdev->devlist_mtx);
815
915
                cfg80211_unlock_rdev(rdev);
 
916
 
 
917
                /*
 
918
                 * Configure power management to the driver here so that its
 
919
                 * correctly set also after interface type changes etc.
 
920
                 */
 
921
                if (wdev->iftype == NL80211_IFTYPE_STATION &&
 
922
                    rdev->ops->set_power_mgmt)
 
923
                        if (rdev->ops->set_power_mgmt(wdev->wiphy, dev,
 
924
                                                      wdev->ps,
 
925
                                                      wdev->ps_timeout)) {
 
926
                                /* assume this means it's off */
 
927
                                wdev->ps = false;
 
928
                        }
816
929
                break;
817
930
        case NETDEV_UNREGISTER:
818
931
                /*
852
965
                        return notifier_from_errno(-EOPNOTSUPP);
853
966
                if (rfkill_blocked(rdev->rfkill))
854
967
                        return notifier_from_errno(-ERFKILL);
 
968
                ret = cfg80211_can_add_interface(rdev, wdev->iftype);
 
969
                if (ret)
 
970
                        return notifier_from_errno(ret);
855
971
                break;
856
972
        }
857
973