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 | }; |
