diff options
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r-- | net/mac80211/cfg.c | 141 |
1 files changed, 124 insertions, 17 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 855126a3039d..16423f94801b 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -17,13 +17,6 @@ | |||
17 | #include "rate.h" | 17 | #include "rate.h" |
18 | #include "mesh.h" | 18 | #include "mesh.h" |
19 | 19 | ||
20 | struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy) | ||
21 | { | ||
22 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
23 | return &local->hw; | ||
24 | } | ||
25 | EXPORT_SYMBOL(wiphy_to_hw); | ||
26 | |||
27 | static bool nl80211_type_check(enum nl80211_iftype type) | 20 | static bool nl80211_type_check(enum nl80211_iftype type) |
28 | { | 21 | { |
29 | switch (type) { | 22 | switch (type) { |
@@ -33,6 +26,8 @@ static bool nl80211_type_check(enum nl80211_iftype type) | |||
33 | #ifdef CONFIG_MAC80211_MESH | 26 | #ifdef CONFIG_MAC80211_MESH |
34 | case NL80211_IFTYPE_MESH_POINT: | 27 | case NL80211_IFTYPE_MESH_POINT: |
35 | #endif | 28 | #endif |
29 | case NL80211_IFTYPE_AP: | ||
30 | case NL80211_IFTYPE_AP_VLAN: | ||
36 | case NL80211_IFTYPE_WDS: | 31 | case NL80211_IFTYPE_WDS: |
37 | return true; | 32 | return true; |
38 | default: | 33 | default: |
@@ -401,8 +396,8 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata, | |||
401 | */ | 396 | */ |
402 | if (params->interval) { | 397 | if (params->interval) { |
403 | sdata->local->hw.conf.beacon_int = params->interval; | 398 | sdata->local->hw.conf.beacon_int = params->interval; |
404 | if (ieee80211_hw_config(sdata->local)) | 399 | ieee80211_hw_config(sdata->local, |
405 | return -EINVAL; | 400 | IEEE80211_CONF_CHANGE_BEACON_INTERVAL); |
406 | /* | 401 | /* |
407 | * We updated some parameter so if below bails out | 402 | * We updated some parameter so if below bails out |
408 | * it's not an error. | 403 | * it's not an error. |
@@ -589,6 +584,8 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
589 | struct ieee80211_supported_band *sband; | 584 | struct ieee80211_supported_band *sband; |
590 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 585 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
591 | 586 | ||
587 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | ||
588 | |||
592 | /* | 589 | /* |
593 | * FIXME: updating the flags is racy when this function is | 590 | * FIXME: updating the flags is racy when this function is |
594 | * called from ieee80211_change_station(), this will | 591 | * called from ieee80211_change_station(), this will |
@@ -629,7 +626,6 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
629 | 626 | ||
630 | if (params->supported_rates) { | 627 | if (params->supported_rates) { |
631 | rates = 0; | 628 | rates = 0; |
632 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | ||
633 | 629 | ||
634 | for (i = 0; i < params->supported_rates_len; i++) { | 630 | for (i = 0; i < params->supported_rates_len; i++) { |
635 | int rate = (params->supported_rates[i] & 0x7f) * 5; | 631 | int rate = (params->supported_rates[i] & 0x7f) * 5; |
@@ -641,10 +637,10 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
641 | sta->sta.supp_rates[local->oper_channel->band] = rates; | 637 | sta->sta.supp_rates[local->oper_channel->band] = rates; |
642 | } | 638 | } |
643 | 639 | ||
644 | if (params->ht_capa) { | 640 | if (params->ht_capa) |
645 | ieee80211_ht_cap_ie_to_ht_info(params->ht_capa, | 641 | ieee80211_ht_cap_ie_to_sta_ht_cap(sband, |
646 | &sta->sta.ht_info); | 642 | params->ht_capa, |
647 | } | 643 | &sta->sta.ht_cap); |
648 | 644 | ||
649 | if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { | 645 | if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { |
650 | switch (params->plink_action) { | 646 | switch (params->plink_action) { |
@@ -957,6 +953,72 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev, | |||
957 | rcu_read_unlock(); | 953 | rcu_read_unlock(); |
958 | return 0; | 954 | return 0; |
959 | } | 955 | } |
956 | |||
957 | static int ieee80211_get_mesh_params(struct wiphy *wiphy, | ||
958 | struct net_device *dev, | ||
959 | struct mesh_config *conf) | ||
960 | { | ||
961 | struct ieee80211_sub_if_data *sdata; | ||
962 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
963 | |||
964 | if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT) | ||
965 | return -ENOTSUPP; | ||
966 | memcpy(conf, &(sdata->u.mesh.mshcfg), sizeof(struct mesh_config)); | ||
967 | return 0; | ||
968 | } | ||
969 | |||
970 | static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask) | ||
971 | { | ||
972 | return (mask >> (parm-1)) & 0x1; | ||
973 | } | ||
974 | |||
975 | static int ieee80211_set_mesh_params(struct wiphy *wiphy, | ||
976 | struct net_device *dev, | ||
977 | const struct mesh_config *nconf, u32 mask) | ||
978 | { | ||
979 | struct mesh_config *conf; | ||
980 | struct ieee80211_sub_if_data *sdata; | ||
981 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
982 | |||
983 | if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT) | ||
984 | return -ENOTSUPP; | ||
985 | |||
986 | /* Set the config options which we are interested in setting */ | ||
987 | conf = &(sdata->u.mesh.mshcfg); | ||
988 | if (_chg_mesh_attr(NL80211_MESHCONF_RETRY_TIMEOUT, mask)) | ||
989 | conf->dot11MeshRetryTimeout = nconf->dot11MeshRetryTimeout; | ||
990 | if (_chg_mesh_attr(NL80211_MESHCONF_CONFIRM_TIMEOUT, mask)) | ||
991 | conf->dot11MeshConfirmTimeout = nconf->dot11MeshConfirmTimeout; | ||
992 | if (_chg_mesh_attr(NL80211_MESHCONF_HOLDING_TIMEOUT, mask)) | ||
993 | conf->dot11MeshHoldingTimeout = nconf->dot11MeshHoldingTimeout; | ||
994 | if (_chg_mesh_attr(NL80211_MESHCONF_MAX_PEER_LINKS, mask)) | ||
995 | conf->dot11MeshMaxPeerLinks = nconf->dot11MeshMaxPeerLinks; | ||
996 | if (_chg_mesh_attr(NL80211_MESHCONF_MAX_RETRIES, mask)) | ||
997 | conf->dot11MeshMaxRetries = nconf->dot11MeshMaxRetries; | ||
998 | if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask)) | ||
999 | conf->dot11MeshTTL = nconf->dot11MeshTTL; | ||
1000 | if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask)) | ||
1001 | conf->auto_open_plinks = nconf->auto_open_plinks; | ||
1002 | if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, mask)) | ||
1003 | conf->dot11MeshHWMPmaxPREQretries = | ||
1004 | nconf->dot11MeshHWMPmaxPREQretries; | ||
1005 | if (_chg_mesh_attr(NL80211_MESHCONF_PATH_REFRESH_TIME, mask)) | ||
1006 | conf->path_refresh_time = nconf->path_refresh_time; | ||
1007 | if (_chg_mesh_attr(NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, mask)) | ||
1008 | conf->min_discovery_timeout = nconf->min_discovery_timeout; | ||
1009 | if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, mask)) | ||
1010 | conf->dot11MeshHWMPactivePathTimeout = | ||
1011 | nconf->dot11MeshHWMPactivePathTimeout; | ||
1012 | if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, mask)) | ||
1013 | conf->dot11MeshHWMPpreqMinInterval = | ||
1014 | nconf->dot11MeshHWMPpreqMinInterval; | ||
1015 | if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, | ||
1016 | mask)) | ||
1017 | conf->dot11MeshHWMPnetDiameterTraversalTime = | ||
1018 | nconf->dot11MeshHWMPnetDiameterTraversalTime; | ||
1019 | return 0; | ||
1020 | } | ||
1021 | |||
960 | #endif | 1022 | #endif |
961 | 1023 | ||
962 | static int ieee80211_change_bss(struct wiphy *wiphy, | 1024 | static int ieee80211_change_bss(struct wiphy *wiphy, |
@@ -972,25 +1034,67 @@ static int ieee80211_change_bss(struct wiphy *wiphy, | |||
972 | return -EINVAL; | 1034 | return -EINVAL; |
973 | 1035 | ||
974 | if (params->use_cts_prot >= 0) { | 1036 | if (params->use_cts_prot >= 0) { |
975 | sdata->bss_conf.use_cts_prot = params->use_cts_prot; | 1037 | sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot; |
976 | changed |= BSS_CHANGED_ERP_CTS_PROT; | 1038 | changed |= BSS_CHANGED_ERP_CTS_PROT; |
977 | } | 1039 | } |
978 | if (params->use_short_preamble >= 0) { | 1040 | if (params->use_short_preamble >= 0) { |
979 | sdata->bss_conf.use_short_preamble = | 1041 | sdata->vif.bss_conf.use_short_preamble = |
980 | params->use_short_preamble; | 1042 | params->use_short_preamble; |
981 | changed |= BSS_CHANGED_ERP_PREAMBLE; | 1043 | changed |= BSS_CHANGED_ERP_PREAMBLE; |
982 | } | 1044 | } |
983 | if (params->use_short_slot_time >= 0) { | 1045 | if (params->use_short_slot_time >= 0) { |
984 | sdata->bss_conf.use_short_slot = | 1046 | sdata->vif.bss_conf.use_short_slot = |
985 | params->use_short_slot_time; | 1047 | params->use_short_slot_time; |
986 | changed |= BSS_CHANGED_ERP_SLOT; | 1048 | changed |= BSS_CHANGED_ERP_SLOT; |
987 | } | 1049 | } |
988 | 1050 | ||
1051 | if (params->basic_rates) { | ||
1052 | int i, j; | ||
1053 | u32 rates = 0; | ||
1054 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
1055 | struct ieee80211_supported_band *sband = | ||
1056 | wiphy->bands[local->oper_channel->band]; | ||
1057 | |||
1058 | for (i = 0; i < params->basic_rates_len; i++) { | ||
1059 | int rate = (params->basic_rates[i] & 0x7f) * 5; | ||
1060 | for (j = 0; j < sband->n_bitrates; j++) { | ||
1061 | if (sband->bitrates[j].bitrate == rate) | ||
1062 | rates |= BIT(j); | ||
1063 | } | ||
1064 | } | ||
1065 | sdata->vif.bss_conf.basic_rates = rates; | ||
1066 | changed |= BSS_CHANGED_BASIC_RATES; | ||
1067 | } | ||
1068 | |||
989 | ieee80211_bss_info_change_notify(sdata, changed); | 1069 | ieee80211_bss_info_change_notify(sdata, changed); |
990 | 1070 | ||
991 | return 0; | 1071 | return 0; |
992 | } | 1072 | } |
993 | 1073 | ||
1074 | static int ieee80211_set_txq_params(struct wiphy *wiphy, | ||
1075 | struct ieee80211_txq_params *params) | ||
1076 | { | ||
1077 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
1078 | struct ieee80211_tx_queue_params p; | ||
1079 | |||
1080 | if (!local->ops->conf_tx) | ||
1081 | return -EOPNOTSUPP; | ||
1082 | |||
1083 | memset(&p, 0, sizeof(p)); | ||
1084 | p.aifs = params->aifs; | ||
1085 | p.cw_max = params->cwmax; | ||
1086 | p.cw_min = params->cwmin; | ||
1087 | p.txop = params->txop; | ||
1088 | if (local->ops->conf_tx(local_to_hw(local), params->queue, &p)) { | ||
1089 | printk(KERN_DEBUG "%s: failed to set TX queue " | ||
1090 | "parameters for queue %d\n", local->mdev->name, | ||
1091 | params->queue); | ||
1092 | return -EINVAL; | ||
1093 | } | ||
1094 | |||
1095 | return 0; | ||
1096 | } | ||
1097 | |||
994 | struct cfg80211_ops mac80211_config_ops = { | 1098 | struct cfg80211_ops mac80211_config_ops = { |
995 | .add_virtual_intf = ieee80211_add_iface, | 1099 | .add_virtual_intf = ieee80211_add_iface, |
996 | .del_virtual_intf = ieee80211_del_iface, | 1100 | .del_virtual_intf = ieee80211_del_iface, |
@@ -1013,6 +1117,9 @@ struct cfg80211_ops mac80211_config_ops = { | |||
1013 | .change_mpath = ieee80211_change_mpath, | 1117 | .change_mpath = ieee80211_change_mpath, |
1014 | .get_mpath = ieee80211_get_mpath, | 1118 | .get_mpath = ieee80211_get_mpath, |
1015 | .dump_mpath = ieee80211_dump_mpath, | 1119 | .dump_mpath = ieee80211_dump_mpath, |
1120 | .set_mesh_params = ieee80211_set_mesh_params, | ||
1121 | .get_mesh_params = ieee80211_get_mesh_params, | ||
1016 | #endif | 1122 | #endif |
1017 | .change_bss = ieee80211_change_bss, | 1123 | .change_bss = ieee80211_change_bss, |
1124 | .set_txq_params = ieee80211_set_txq_params, | ||
1018 | }; | 1125 | }; |