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.c141
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
20struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy)
21{
22 struct ieee80211_local *local = wiphy_priv(wiphy);
23 return &local->hw;
24}
25EXPORT_SYMBOL(wiphy_to_hw);
26
27static bool nl80211_type_check(enum nl80211_iftype type) 20static 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
957static 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
970static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
971{
972 return (mask >> (parm-1)) & 0x1;
973}
974
975static 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
962static int ieee80211_change_bss(struct wiphy *wiphy, 1024static 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
1074static 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
994struct cfg80211_ops mac80211_config_ops = { 1098struct 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};