diff options
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r-- | net/mac80211/cfg.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 914aef7e7afd..51622333d460 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -790,6 +790,48 @@ static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
790 | return 0; | 790 | return 0; |
791 | } | 791 | } |
792 | 792 | ||
793 | static int ieee80211_set_ftm_responder_params( | ||
794 | struct ieee80211_sub_if_data *sdata, | ||
795 | const u8 *lci, size_t lci_len, | ||
796 | const u8 *civicloc, size_t civicloc_len) | ||
797 | { | ||
798 | struct ieee80211_ftm_responder_params *new, *old; | ||
799 | struct ieee80211_bss_conf *bss_conf; | ||
800 | u8 *pos; | ||
801 | int len; | ||
802 | |||
803 | if ((!lci || !lci_len) && (!civicloc || !civicloc_len)) | ||
804 | return 1; | ||
805 | |||
806 | bss_conf = &sdata->vif.bss_conf; | ||
807 | old = bss_conf->ftmr_params; | ||
808 | len = lci_len + civicloc_len; | ||
809 | |||
810 | new = kzalloc(sizeof(*new) + len, GFP_KERNEL); | ||
811 | if (!new) | ||
812 | return -ENOMEM; | ||
813 | |||
814 | pos = (u8 *)(new + 1); | ||
815 | if (lci_len) { | ||
816 | new->lci_len = lci_len; | ||
817 | new->lci = pos; | ||
818 | memcpy(pos, lci, lci_len); | ||
819 | pos += lci_len; | ||
820 | } | ||
821 | |||
822 | if (civicloc_len) { | ||
823 | new->civicloc_len = civicloc_len; | ||
824 | new->civicloc = pos; | ||
825 | memcpy(pos, civicloc, civicloc_len); | ||
826 | pos += civicloc_len; | ||
827 | } | ||
828 | |||
829 | bss_conf->ftmr_params = new; | ||
830 | kfree(old); | ||
831 | |||
832 | return 0; | ||
833 | } | ||
834 | |||
793 | static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata, | 835 | static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata, |
794 | struct cfg80211_beacon_data *params, | 836 | struct cfg80211_beacon_data *params, |
795 | const struct ieee80211_csa_settings *csa) | 837 | const struct ieee80211_csa_settings *csa) |
@@ -863,6 +905,20 @@ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata, | |||
863 | if (err == 0) | 905 | if (err == 0) |
864 | changed |= BSS_CHANGED_AP_PROBE_RESP; | 906 | changed |= BSS_CHANGED_AP_PROBE_RESP; |
865 | 907 | ||
908 | if (params->ftm_responder != -1) { | ||
909 | sdata->vif.bss_conf.ftm_responder = params->ftm_responder; | ||
910 | err = ieee80211_set_ftm_responder_params(sdata, | ||
911 | params->lci, | ||
912 | params->lci_len, | ||
913 | params->civicloc, | ||
914 | params->civicloc_len); | ||
915 | |||
916 | if (err < 0) | ||
917 | return err; | ||
918 | |||
919 | changed |= BSS_CHANGED_FTM_RESPONDER; | ||
920 | } | ||
921 | |||
866 | rcu_assign_pointer(sdata->u.ap.beacon, new); | 922 | rcu_assign_pointer(sdata->u.ap.beacon, new); |
867 | 923 | ||
868 | if (old) | 924 | if (old) |
@@ -1063,6 +1119,9 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
1063 | kfree_rcu(old_probe_resp, rcu_head); | 1119 | kfree_rcu(old_probe_resp, rcu_head); |
1064 | sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF; | 1120 | sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF; |
1065 | 1121 | ||
1122 | kfree(sdata->vif.bss_conf.ftmr_params); | ||
1123 | sdata->vif.bss_conf.ftmr_params = NULL; | ||
1124 | |||
1066 | __sta_info_flush(sdata, true); | 1125 | __sta_info_flush(sdata, true); |
1067 | ieee80211_free_keys(sdata, true); | 1126 | ieee80211_free_keys(sdata, true); |
1068 | 1127 | ||
@@ -2875,6 +2934,20 @@ cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon) | |||
2875 | memcpy(pos, beacon->probe_resp, beacon->probe_resp_len); | 2934 | memcpy(pos, beacon->probe_resp, beacon->probe_resp_len); |
2876 | pos += beacon->probe_resp_len; | 2935 | pos += beacon->probe_resp_len; |
2877 | } | 2936 | } |
2937 | if (beacon->ftm_responder) | ||
2938 | new_beacon->ftm_responder = beacon->ftm_responder; | ||
2939 | if (beacon->lci) { | ||
2940 | new_beacon->lci_len = beacon->lci_len; | ||
2941 | new_beacon->lci = pos; | ||
2942 | memcpy(pos, beacon->lci, beacon->lci_len); | ||
2943 | pos += beacon->lci_len; | ||
2944 | } | ||
2945 | if (beacon->civicloc) { | ||
2946 | new_beacon->civicloc_len = beacon->civicloc_len; | ||
2947 | new_beacon->civicloc = pos; | ||
2948 | memcpy(pos, beacon->civicloc, beacon->civicloc_len); | ||
2949 | pos += beacon->civicloc_len; | ||
2950 | } | ||
2878 | 2951 | ||
2879 | return new_beacon; | 2952 | return new_beacon; |
2880 | } | 2953 | } |
@@ -3765,6 +3838,17 @@ out: | |||
3765 | return ret; | 3838 | return ret; |
3766 | } | 3839 | } |
3767 | 3840 | ||
3841 | static int | ||
3842 | ieee80211_get_ftm_responder_stats(struct wiphy *wiphy, | ||
3843 | struct net_device *dev, | ||
3844 | struct cfg80211_ftm_responder_stats *ftm_stats) | ||
3845 | { | ||
3846 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
3847 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
3848 | |||
3849 | return drv_get_ftm_responder_stats(local, sdata, ftm_stats); | ||
3850 | } | ||
3851 | |||
3768 | const struct cfg80211_ops mac80211_config_ops = { | 3852 | const struct cfg80211_ops mac80211_config_ops = { |
3769 | .add_virtual_intf = ieee80211_add_iface, | 3853 | .add_virtual_intf = ieee80211_add_iface, |
3770 | .del_virtual_intf = ieee80211_del_iface, | 3854 | .del_virtual_intf = ieee80211_del_iface, |
@@ -3859,4 +3943,5 @@ const struct cfg80211_ops mac80211_config_ops = { | |||
3859 | .set_multicast_to_unicast = ieee80211_set_multicast_to_unicast, | 3943 | .set_multicast_to_unicast = ieee80211_set_multicast_to_unicast, |
3860 | .tx_control_port = ieee80211_tx_control_port, | 3944 | .tx_control_port = ieee80211_tx_control_port, |
3861 | .get_txq_stats = ieee80211_get_txq_stats, | 3945 | .get_txq_stats = ieee80211_get_txq_stats, |
3946 | .get_ftm_responder_stats = ieee80211_get_ftm_responder_stats, | ||
3862 | }; | 3947 | }; |