aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c85
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
793static 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
793static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata, 835static 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
3841static int
3842ieee80211_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
3768const struct cfg80211_ops mac80211_config_ops = { 3852const 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};