aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-02-13 09:17:18 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-02-22 14:51:18 -0500
commit8860020e0be1f03d83dc9e9e93e18a4ddbe01038 (patch)
tree09fa9089770e8a42e913f6c11abbba04bec20fad /net/mac80211/cfg.c
parent4e3bc141d480661634d0fadad7dbb1ddde70b4d4 (diff)
cfg80211: restructure AP/GO mode API
The AP/GO mode API isn't very clearly defined, it has "set beacon" and "new beacon" etc. Modify the API to the following: * start AP -- all settings * change beacon -- new beacon data * stop AP -- stop AP mode operation This also reflects in the nl80211 API, rename the commands there correspondingly (but keep the old names for compatibility.) Overall, this makes it much clearer what's going on in the API. Kalle developed the ath6kl changes, I created the rest of the patch. Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c146
1 files changed, 59 insertions, 87 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index c3de921c8cfd..f7eb25aabf8f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -489,27 +489,13 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
489 return ret; 489 return ret;
490} 490}
491 491
492static void ieee80211_config_ap_ssid(struct ieee80211_sub_if_data *sdata,
493 struct beacon_parameters *params)
494{
495 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
496
497 bss_conf->ssid_len = params->ssid_len;
498
499 if (params->ssid_len)
500 memcpy(bss_conf->ssid, params->ssid, params->ssid_len);
501
502 bss_conf->hidden_ssid =
503 (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE);
504}
505
506static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, 492static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
507 u8 *resp, size_t resp_len) 493 const u8 *resp, size_t resp_len)
508{ 494{
509 struct sk_buff *new, *old; 495 struct sk_buff *new, *old;
510 496
511 if (!resp || !resp_len) 497 if (!resp || !resp_len)
512 return -EINVAL; 498 return 1;
513 499
514 old = rtnl_dereference(sdata->u.ap.probe_resp); 500 old = rtnl_dereference(sdata->u.ap.probe_resp);
515 501
@@ -520,50 +506,28 @@ static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
520 memcpy(skb_put(new, resp_len), resp, resp_len); 506 memcpy(skb_put(new, resp_len), resp, resp_len);
521 507
522 rcu_assign_pointer(sdata->u.ap.probe_resp, new); 508 rcu_assign_pointer(sdata->u.ap.probe_resp, new);
523 synchronize_rcu(); 509 if (old) {
524 510 /* TODO: use call_rcu() */
525 if (old) 511 synchronize_rcu();
526 dev_kfree_skb(old); 512 dev_kfree_skb(old);
513 }
527 514
528 return 0; 515 return 0;
529} 516}
530 517
531/* 518static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
532 * This handles both adding a beacon and setting new beacon info 519 struct cfg80211_beacon_data *params)
533 */
534static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
535 struct beacon_parameters *params)
536{ 520{
537 struct beacon_data *new, *old; 521 struct beacon_data *new, *old;
538 int new_head_len, new_tail_len; 522 int new_head_len, new_tail_len;
539 int size; 523 int size, err;
540 int err = -EINVAL; 524 u32 changed = BSS_CHANGED_BEACON;
541 u32 changed = 0;
542 525
543 old = rtnl_dereference(sdata->u.ap.beacon); 526 old = rtnl_dereference(sdata->u.ap.beacon);
544 527
545 /* head must not be zero-length */
546 if (params->head && !params->head_len)
547 return -EINVAL;
548
549 /*
550 * This is a kludge. beacon interval should really be part
551 * of the beacon information.
552 */
553 if (params->interval &&
554 (sdata->vif.bss_conf.beacon_int != params->interval)) {
555 sdata->vif.bss_conf.beacon_int = params->interval;
556 ieee80211_bss_info_change_notify(sdata,
557 BSS_CHANGED_BEACON_INT);
558 }
559
560 /* Need to have a beacon head if we don't have one yet */ 528 /* Need to have a beacon head if we don't have one yet */
561 if (!params->head && !old) 529 if (!params->head && !old)
562 return err; 530 return -EINVAL;
563
564 /* sorry, no way to start beaconing without dtim period */
565 if (!params->dtim_period && !old)
566 return err;
567 531
568 /* new or old head? */ 532 /* new or old head? */
569 if (params->head) 533 if (params->head)
@@ -586,12 +550,6 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
586 550
587 /* start filling the new info now */ 551 /* start filling the new info now */
588 552
589 /* new or old dtim period? */
590 if (params->dtim_period)
591 new->dtim_period = params->dtim_period;
592 else
593 new->dtim_period = old->dtim_period;
594
595 /* 553 /*
596 * pointers go into the block we allocated, 554 * pointers go into the block we allocated,
597 * memory is | beacon_data | head | tail | 555 * memory is | beacon_data | head | tail |
@@ -614,46 +572,37 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
614 if (old) 572 if (old)
615 memcpy(new->tail, old->tail, new_tail_len); 573 memcpy(new->tail, old->tail, new_tail_len);
616 574
617 sdata->vif.bss_conf.dtim_period = new->dtim_period;
618
619 rcu_assign_pointer(sdata->u.ap.beacon, new);
620
621 synchronize_rcu();
622
623 kfree(old);
624
625 err = ieee80211_set_probe_resp(sdata, params->probe_resp, 575 err = ieee80211_set_probe_resp(sdata, params->probe_resp,
626 params->probe_resp_len); 576 params->probe_resp_len);
627 if (!err) 577 if (err < 0)
578 return err;
579 if (err == 0)
628 changed |= BSS_CHANGED_AP_PROBE_RESP; 580 changed |= BSS_CHANGED_AP_PROBE_RESP;
629 581
630 ieee80211_config_ap_ssid(sdata, params); 582 rcu_assign_pointer(sdata->u.ap.beacon, new);
631 changed |= BSS_CHANGED_BEACON_ENABLED | 583
632 BSS_CHANGED_BEACON | 584 if (old)
633 BSS_CHANGED_SSID; 585 kfree_rcu(old, rcu_head);
634 586
635 ieee80211_bss_info_change_notify(sdata, changed); 587 return changed;
636 return 0;
637} 588}
638 589
639static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, 590static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
640 struct beacon_parameters *params) 591 struct cfg80211_ap_settings *params)
641{ 592{
642 struct ieee80211_sub_if_data *sdata; 593 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
643 struct beacon_data *old; 594 struct beacon_data *old;
644 struct ieee80211_sub_if_data *vlan; 595 struct ieee80211_sub_if_data *vlan;
645 int ret; 596 u32 changed = BSS_CHANGED_BEACON_INT |
646 597 BSS_CHANGED_BEACON_ENABLED |
647 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 598 BSS_CHANGED_BEACON |
599 BSS_CHANGED_SSID;
600 int err;
648 601
649 old = rtnl_dereference(sdata->u.ap.beacon); 602 old = rtnl_dereference(sdata->u.ap.beacon);
650 if (old) 603 if (old)
651 return -EALREADY; 604 return -EALREADY;
652 605
653 ret = ieee80211_config_beacon(sdata, params);
654 if (ret)
655 return ret;
656
657 /* 606 /*
658 * Apply control port protocol, this allows us to 607 * Apply control port protocol, this allows us to
659 * not encrypt dynamic WEP control frames. 608 * not encrypt dynamic WEP control frames.
@@ -667,14 +616,32 @@ static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
667 params->crypto.control_port_no_encrypt; 616 params->crypto.control_port_no_encrypt;
668 } 617 }
669 618
619 sdata->vif.bss_conf.beacon_int = params->beacon_interval;
620 sdata->vif.bss_conf.dtim_period = params->dtim_period;
621
622 sdata->vif.bss_conf.ssid_len = params->ssid_len;
623 if (params->ssid_len)
624 memcpy(sdata->vif.bss_conf.ssid, params->ssid,
625 params->ssid_len);
626 sdata->vif.bss_conf.hidden_ssid =
627 (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE);
628
629 err = ieee80211_assign_beacon(sdata, &params->beacon);
630 if (err < 0)
631 return err;
632 changed |= err;
633
634 ieee80211_bss_info_change_notify(sdata, changed);
635
670 return 0; 636 return 0;
671} 637}
672 638
673static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev, 639static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
674 struct beacon_parameters *params) 640 struct cfg80211_beacon_data *params)
675{ 641{
676 struct ieee80211_sub_if_data *sdata; 642 struct ieee80211_sub_if_data *sdata;
677 struct beacon_data *old; 643 struct beacon_data *old;
644 int err;
678 645
679 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 646 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
680 647
@@ -682,10 +649,14 @@ static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
682 if (!old) 649 if (!old)
683 return -ENOENT; 650 return -ENOENT;
684 651
685 return ieee80211_config_beacon(sdata, params); 652 err = ieee80211_assign_beacon(sdata, params);
653 if (err < 0)
654 return err;
655 ieee80211_bss_info_change_notify(sdata, err);
656 return 0;
686} 657}
687 658
688static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev) 659static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
689{ 660{
690 struct ieee80211_sub_if_data *sdata; 661 struct ieee80211_sub_if_data *sdata;
691 struct beacon_data *old; 662 struct beacon_data *old;
@@ -697,10 +668,11 @@ static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
697 return -ENOENT; 668 return -ENOENT;
698 669
699 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); 670 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
700 synchronize_rcu(); 671
701 kfree(old); 672 kfree_rcu(old, rcu_head);
702 673
703 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); 674 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
675
704 return 0; 676 return 0;
705} 677}
706 678
@@ -2699,9 +2671,9 @@ struct cfg80211_ops mac80211_config_ops = {
2699 .get_key = ieee80211_get_key, 2671 .get_key = ieee80211_get_key,
2700 .set_default_key = ieee80211_config_default_key, 2672 .set_default_key = ieee80211_config_default_key,
2701 .set_default_mgmt_key = ieee80211_config_default_mgmt_key, 2673 .set_default_mgmt_key = ieee80211_config_default_mgmt_key,
2702 .add_beacon = ieee80211_add_beacon, 2674 .start_ap = ieee80211_start_ap,
2703 .set_beacon = ieee80211_set_beacon, 2675 .change_beacon = ieee80211_change_beacon,
2704 .del_beacon = ieee80211_del_beacon, 2676 .stop_ap = ieee80211_stop_ap,
2705 .add_station = ieee80211_add_station, 2677 .add_station = ieee80211_add_station,
2706 .del_station = ieee80211_del_station, 2678 .del_station = ieee80211_del_station,
2707 .change_station = ieee80211_change_station, 2679 .change_station = ieee80211_change_station,