diff options
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r-- | net/mac80211/cfg.c | 122 |
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 | ||
413 | static 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 | |||
414 | static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, | 424 | static 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 | ||
1143 | static int ieee80211_set_channel(struct wiphy *wiphy, | 1164 | static 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, | |||
1193 | static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev, | 1238 | static 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, | |||
1215 | static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, | 1274 | static 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 | ||
1479 | static 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 | |||
1406 | static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, | 1508 | static 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 | }; |