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.c122
1 files changed, 113 insertions, 9 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index edc872e22c9b..c7000a6ca379 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -97,9 +97,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
97 params->mesh_id_len, 97 params->mesh_id_len,
98 params->mesh_id); 98 params->mesh_id);
99 99
100 if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags)
101 return 0;
102
103 if (type == NL80211_IFTYPE_AP_VLAN && 100 if (type == NL80211_IFTYPE_AP_VLAN &&
104 params && params->use_4addr == 0) 101 params && params->use_4addr == 0)
105 rcu_assign_pointer(sdata->u.vlan.sta, NULL); 102 rcu_assign_pointer(sdata->u.vlan.sta, NULL);
@@ -107,7 +104,9 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
107 params && params->use_4addr >= 0) 104 params && params->use_4addr >= 0)
108 sdata->u.mgd.use_4addr = params->use_4addr; 105 sdata->u.mgd.use_4addr = params->use_4addr;
109 106
110 sdata->u.mntr_flags = *flags; 107 if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags)
108 sdata->u.mntr_flags = *flags;
109
111 return 0; 110 return 0;
112} 111}
113 112
@@ -411,6 +410,17 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
411 return ret; 410 return ret;
412} 411}
413 412
413static int ieee80211_dump_survey(struct wiphy *wiphy, struct net_device *dev,
414 int idx, struct survey_info *survey)
415{
416 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
417
418 if (!local->ops->get_survey)
419 return -EOPNOTSUPP;
420
421 return drv_get_survey(local, idx, survey);
422}
423
414static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, 424static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
415 u8 *mac, struct station_info *sinfo) 425 u8 *mac, struct station_info *sinfo)
416{ 426{
@@ -1104,6 +1114,13 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
1104 changed |= BSS_CHANGED_BASIC_RATES; 1114 changed |= BSS_CHANGED_BASIC_RATES;
1105 } 1115 }
1106 1116
1117 if (params->ap_isolate >= 0) {
1118 if (params->ap_isolate)
1119 sdata->flags |= IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
1120 else
1121 sdata->flags &= ~IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
1122 }
1123
1107 ieee80211_bss_info_change_notify(sdata, changed); 1124 ieee80211_bss_info_change_notify(sdata, changed);
1108 1125
1109 return 0; 1126 return 0;
@@ -1137,19 +1154,47 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
1137 return -EINVAL; 1154 return -EINVAL;
1138 } 1155 }
1139 1156
1157 /* enable WMM or activate new settings */
1158 local->hw.conf.flags |= IEEE80211_CONF_QOS;
1159 drv_config(local, IEEE80211_CONF_CHANGE_QOS);
1160
1140 return 0; 1161 return 0;
1141} 1162}
1142 1163
1143static int ieee80211_set_channel(struct wiphy *wiphy, 1164static int ieee80211_set_channel(struct wiphy *wiphy,
1165 struct net_device *netdev,
1144 struct ieee80211_channel *chan, 1166 struct ieee80211_channel *chan,
1145 enum nl80211_channel_type channel_type) 1167 enum nl80211_channel_type channel_type)
1146{ 1168{
1147 struct ieee80211_local *local = wiphy_priv(wiphy); 1169 struct ieee80211_local *local = wiphy_priv(wiphy);
1170 struct ieee80211_sub_if_data *sdata = NULL;
1171
1172 if (netdev)
1173 sdata = IEEE80211_DEV_TO_SUB_IF(netdev);
1174
1175 switch (ieee80211_get_channel_mode(local, NULL)) {
1176 case CHAN_MODE_HOPPING:
1177 return -EBUSY;
1178 case CHAN_MODE_FIXED:
1179 if (local->oper_channel != chan)
1180 return -EBUSY;
1181 if (!sdata && local->_oper_channel_type == channel_type)
1182 return 0;
1183 break;
1184 case CHAN_MODE_UNDEFINED:
1185 break;
1186 }
1148 1187
1149 local->oper_channel = chan; 1188 local->oper_channel = chan;
1150 local->oper_channel_type = channel_type;
1151 1189
1152 return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 1190 if (!ieee80211_set_channel_type(local, sdata, channel_type))
1191 return -EBUSY;
1192
1193 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
1194 if (sdata && sdata->vif.type != NL80211_IFTYPE_MONITOR)
1195 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT);
1196
1197 return 0;
1153} 1198}
1154 1199
1155#ifdef CONFIG_PM 1200#ifdef CONFIG_PM
@@ -1193,6 +1238,20 @@ static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev,
1193static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev, 1238static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
1194 struct cfg80211_assoc_request *req) 1239 struct cfg80211_assoc_request *req)
1195{ 1240{
1241 struct ieee80211_local *local = wiphy_priv(wiphy);
1242 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1243
1244 switch (ieee80211_get_channel_mode(local, sdata)) {
1245 case CHAN_MODE_HOPPING:
1246 return -EBUSY;
1247 case CHAN_MODE_FIXED:
1248 if (local->oper_channel == req->bss->channel)
1249 break;
1250 return -EBUSY;
1251 case CHAN_MODE_UNDEFINED:
1252 break;
1253 }
1254
1196 return ieee80211_mgd_assoc(IEEE80211_DEV_TO_SUB_IF(dev), req); 1255 return ieee80211_mgd_assoc(IEEE80211_DEV_TO_SUB_IF(dev), req);
1197} 1256}
1198 1257
@@ -1215,8 +1274,22 @@ static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev,
1215static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, 1274static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1216 struct cfg80211_ibss_params *params) 1275 struct cfg80211_ibss_params *params)
1217{ 1276{
1277 struct ieee80211_local *local = wiphy_priv(wiphy);
1218 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1278 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1219 1279
1280 switch (ieee80211_get_channel_mode(local, sdata)) {
1281 case CHAN_MODE_HOPPING:
1282 return -EBUSY;
1283 case CHAN_MODE_FIXED:
1284 if (!params->channel_fixed)
1285 return -EBUSY;
1286 if (local->oper_channel == params->channel)
1287 break;
1288 return -EBUSY;
1289 case CHAN_MODE_UNDEFINED:
1290 break;
1291 }
1292
1220 return ieee80211_ibss_join(sdata, params); 1293 return ieee80211_ibss_join(sdata, params);
1221} 1294}
1222 1295
@@ -1345,7 +1418,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
1345 * association, there's no need to send an action frame. 1418 * association, there's no need to send an action frame.
1346 */ 1419 */
1347 if (!sdata->u.mgd.associated || 1420 if (!sdata->u.mgd.associated ||
1348 sdata->local->oper_channel_type == NL80211_CHAN_NO_HT) { 1421 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) {
1349 mutex_lock(&sdata->local->iflist_mtx); 1422 mutex_lock(&sdata->local->iflist_mtx);
1350 ieee80211_recalc_smps(sdata->local, sdata); 1423 ieee80211_recalc_smps(sdata->local, sdata);
1351 mutex_unlock(&sdata->local->iflist_mtx); 1424 mutex_unlock(&sdata->local->iflist_mtx);
@@ -1384,11 +1457,11 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1384 return -EOPNOTSUPP; 1457 return -EOPNOTSUPP;
1385 1458
1386 if (enabled == sdata->u.mgd.powersave && 1459 if (enabled == sdata->u.mgd.powersave &&
1387 timeout == conf->dynamic_ps_timeout) 1460 timeout == conf->dynamic_ps_forced_timeout)
1388 return 0; 1461 return 0;
1389 1462
1390 sdata->u.mgd.powersave = enabled; 1463 sdata->u.mgd.powersave = enabled;
1391 conf->dynamic_ps_timeout = timeout; 1464 conf->dynamic_ps_forced_timeout = timeout;
1392 1465
1393 /* no change, but if automatic follow powersave */ 1466 /* no change, but if automatic follow powersave */
1394 mutex_lock(&sdata->u.mgd.mtx); 1467 mutex_lock(&sdata->u.mgd.mtx);
@@ -1403,6 +1476,35 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1403 return 0; 1476 return 0;
1404} 1477}
1405 1478
1479static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy,
1480 struct net_device *dev,
1481 s32 rssi_thold, u32 rssi_hyst)
1482{
1483 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1484 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1485 struct ieee80211_vif *vif = &sdata->vif;
1486 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1487
1488 if (rssi_thold == bss_conf->cqm_rssi_thold &&
1489 rssi_hyst == bss_conf->cqm_rssi_hyst)
1490 return 0;
1491
1492 bss_conf->cqm_rssi_thold = rssi_thold;
1493 bss_conf->cqm_rssi_hyst = rssi_hyst;
1494
1495 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
1496 if (sdata->vif.type != NL80211_IFTYPE_STATION)
1497 return -EOPNOTSUPP;
1498 return 0;
1499 }
1500
1501 /* tell the driver upon association, unless already associated */
1502 if (sdata->u.mgd.associated)
1503 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_CQM);
1504
1505 return 0;
1506}
1507
1406static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, 1508static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
1407 struct net_device *dev, 1509 struct net_device *dev,
1408 const u8 *addr, 1510 const u8 *addr,
@@ -1475,6 +1577,7 @@ struct cfg80211_ops mac80211_config_ops = {
1475 .change_station = ieee80211_change_station, 1577 .change_station = ieee80211_change_station,
1476 .get_station = ieee80211_get_station, 1578 .get_station = ieee80211_get_station,
1477 .dump_station = ieee80211_dump_station, 1579 .dump_station = ieee80211_dump_station,
1580 .dump_survey = ieee80211_dump_survey,
1478#ifdef CONFIG_MAC80211_MESH 1581#ifdef CONFIG_MAC80211_MESH
1479 .add_mpath = ieee80211_add_mpath, 1582 .add_mpath = ieee80211_add_mpath,
1480 .del_mpath = ieee80211_del_mpath, 1583 .del_mpath = ieee80211_del_mpath,
@@ -1507,4 +1610,5 @@ struct cfg80211_ops mac80211_config_ops = {
1507 .remain_on_channel = ieee80211_remain_on_channel, 1610 .remain_on_channel = ieee80211_remain_on_channel,
1508 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel, 1611 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
1509 .action = ieee80211_action, 1612 .action = ieee80211_action,
1613 .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
1510}; 1614};