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.c170
1 files changed, 167 insertions, 3 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 9d4e4d846ec1..58693e52d458 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -133,6 +133,9 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
133 case WLAN_CIPHER_SUITE_CCMP: 133 case WLAN_CIPHER_SUITE_CCMP:
134 alg = ALG_CCMP; 134 alg = ALG_CCMP;
135 break; 135 break;
136 case WLAN_CIPHER_SUITE_AES_CMAC:
137 alg = ALG_AES_CMAC;
138 break;
136 default: 139 default:
137 return -EINVAL; 140 return -EINVAL;
138 } 141 }
@@ -275,6 +278,17 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
275 else 278 else
276 params.cipher = WLAN_CIPHER_SUITE_WEP104; 279 params.cipher = WLAN_CIPHER_SUITE_WEP104;
277 break; 280 break;
281 case ALG_AES_CMAC:
282 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
283 seq[0] = key->u.aes_cmac.tx_pn[5];
284 seq[1] = key->u.aes_cmac.tx_pn[4];
285 seq[2] = key->u.aes_cmac.tx_pn[3];
286 seq[3] = key->u.aes_cmac.tx_pn[2];
287 seq[4] = key->u.aes_cmac.tx_pn[1];
288 seq[5] = key->u.aes_cmac.tx_pn[0];
289 params.seq = seq;
290 params.seq_len = 6;
291 break;
278 } 292 }
279 293
280 params.key = key->conf.key; 294 params.key = key->conf.key;
@@ -304,6 +318,22 @@ static int ieee80211_config_default_key(struct wiphy *wiphy,
304 return 0; 318 return 0;
305} 319}
306 320
321static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
322 struct net_device *dev,
323 u8 key_idx)
324{
325 struct ieee80211_sub_if_data *sdata;
326
327 rcu_read_lock();
328
329 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
330 ieee80211_set_default_mgmt_key(sdata, key_idx);
331
332 rcu_read_unlock();
333
334 return 0;
335}
336
307static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) 337static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
308{ 338{
309 struct ieee80211_sub_if_data *sdata = sta->sdata; 339 struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -311,11 +341,15 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
311 sinfo->filled = STATION_INFO_INACTIVE_TIME | 341 sinfo->filled = STATION_INFO_INACTIVE_TIME |
312 STATION_INFO_RX_BYTES | 342 STATION_INFO_RX_BYTES |
313 STATION_INFO_TX_BYTES | 343 STATION_INFO_TX_BYTES |
344 STATION_INFO_RX_PACKETS |
345 STATION_INFO_TX_PACKETS |
314 STATION_INFO_TX_BITRATE; 346 STATION_INFO_TX_BITRATE;
315 347
316 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); 348 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
317 sinfo->rx_bytes = sta->rx_bytes; 349 sinfo->rx_bytes = sta->rx_bytes;
318 sinfo->tx_bytes = sta->tx_bytes; 350 sinfo->tx_bytes = sta->tx_bytes;
351 sinfo->rx_packets = sta->rx_packets;
352 sinfo->tx_packets = sta->tx_packets;
319 353
320 if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { 354 if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
321 sinfo->filled |= STATION_INFO_SIGNAL; 355 sinfo->filled |= STATION_INFO_SIGNAL;
@@ -417,7 +451,8 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
417 * This is a kludge. beacon interval should really be part 451 * This is a kludge. beacon interval should really be part
418 * of the beacon information. 452 * of the beacon information.
419 */ 453 */
420 if (params->interval) { 454 if (params->interval && (sdata->local->hw.conf.beacon_int !=
455 params->interval)) {
421 sdata->local->hw.conf.beacon_int = params->interval; 456 sdata->local->hw.conf.beacon_int = params->interval;
422 err = ieee80211_hw_config(sdata->local, 457 err = ieee80211_hw_config(sdata->local,
423 IEEE80211_CONF_CHANGE_BEACON_INTERVAL); 458 IEEE80211_CONF_CHANGE_BEACON_INTERVAL);
@@ -493,7 +528,8 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
493 528
494 kfree(old); 529 kfree(old);
495 530
496 return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); 531 return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON |
532 IEEE80211_IFCC_BEACON_ENABLED);
497} 533}
498 534
499static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, 535static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
@@ -553,7 +589,7 @@ static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
553 synchronize_rcu(); 589 synchronize_rcu();
554 kfree(old); 590 kfree(old);
555 591
556 return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); 592 return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON_ENABLED);
557} 593}
558 594
559/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */ 595/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
@@ -630,6 +666,10 @@ static void sta_apply_parameters(struct ieee80211_local *local,
630 sta->flags &= ~WLAN_STA_WME; 666 sta->flags &= ~WLAN_STA_WME;
631 if (params->station_flags & STATION_FLAG_WME) 667 if (params->station_flags & STATION_FLAG_WME)
632 sta->flags |= WLAN_STA_WME; 668 sta->flags |= WLAN_STA_WME;
669
670 sta->flags &= ~WLAN_STA_MFP;
671 if (params->station_flags & STATION_FLAG_MFP)
672 sta->flags |= WLAN_STA_MFP;
633 spin_unlock_bh(&sta->lock); 673 spin_unlock_bh(&sta->lock);
634 } 674 }
635 675
@@ -1141,6 +1181,125 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
1141 return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 1181 return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
1142} 1182}
1143 1183
1184static int set_mgmt_extra_ie_sta(struct ieee80211_sub_if_data *sdata,
1185 u8 subtype, u8 *ies, size_t ies_len)
1186{
1187 struct ieee80211_local *local = sdata->local;
1188 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1189
1190 switch (subtype) {
1191 case IEEE80211_STYPE_PROBE_REQ >> 4:
1192 if (local->ops->hw_scan)
1193 break;
1194 kfree(ifmgd->ie_probereq);
1195 ifmgd->ie_probereq = ies;
1196 ifmgd->ie_probereq_len = ies_len;
1197 return 0;
1198 case IEEE80211_STYPE_PROBE_RESP >> 4:
1199 kfree(ifmgd->ie_proberesp);
1200 ifmgd->ie_proberesp = ies;
1201 ifmgd->ie_proberesp_len = ies_len;
1202 return 0;
1203 case IEEE80211_STYPE_AUTH >> 4:
1204 kfree(ifmgd->ie_auth);
1205 ifmgd->ie_auth = ies;
1206 ifmgd->ie_auth_len = ies_len;
1207 return 0;
1208 case IEEE80211_STYPE_ASSOC_REQ >> 4:
1209 kfree(ifmgd->ie_assocreq);
1210 ifmgd->ie_assocreq = ies;
1211 ifmgd->ie_assocreq_len = ies_len;
1212 return 0;
1213 case IEEE80211_STYPE_REASSOC_REQ >> 4:
1214 kfree(ifmgd->ie_reassocreq);
1215 ifmgd->ie_reassocreq = ies;
1216 ifmgd->ie_reassocreq_len = ies_len;
1217 return 0;
1218 case IEEE80211_STYPE_DEAUTH >> 4:
1219 kfree(ifmgd->ie_deauth);
1220 ifmgd->ie_deauth = ies;
1221 ifmgd->ie_deauth_len = ies_len;
1222 return 0;
1223 case IEEE80211_STYPE_DISASSOC >> 4:
1224 kfree(ifmgd->ie_disassoc);
1225 ifmgd->ie_disassoc = ies;
1226 ifmgd->ie_disassoc_len = ies_len;
1227 return 0;
1228 }
1229
1230 return -EOPNOTSUPP;
1231}
1232
1233static int ieee80211_set_mgmt_extra_ie(struct wiphy *wiphy,
1234 struct net_device *dev,
1235 struct mgmt_extra_ie_params *params)
1236{
1237 struct ieee80211_sub_if_data *sdata;
1238 u8 *ies;
1239 size_t ies_len;
1240 int ret = -EOPNOTSUPP;
1241
1242 if (params->ies) {
1243 ies = kmemdup(params->ies, params->ies_len, GFP_KERNEL);
1244 if (ies == NULL)
1245 return -ENOMEM;
1246 ies_len = params->ies_len;
1247 } else {
1248 ies = NULL;
1249 ies_len = 0;
1250 }
1251
1252 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1253
1254 switch (sdata->vif.type) {
1255 case NL80211_IFTYPE_STATION:
1256 ret = set_mgmt_extra_ie_sta(sdata, params->subtype,
1257 ies, ies_len);
1258 break;
1259 default:
1260 ret = -EOPNOTSUPP;
1261 break;
1262 }
1263
1264 if (ret)
1265 kfree(ies);
1266 return ret;
1267}
1268
1269#ifdef CONFIG_PM
1270static int ieee80211_suspend(struct wiphy *wiphy)
1271{
1272 return __ieee80211_suspend(wiphy_priv(wiphy));
1273}
1274
1275static int ieee80211_resume(struct wiphy *wiphy)
1276{
1277 return __ieee80211_resume(wiphy_priv(wiphy));
1278}
1279#else
1280#define ieee80211_suspend NULL
1281#define ieee80211_resume NULL
1282#endif
1283
1284static int ieee80211_scan(struct wiphy *wiphy,
1285 struct net_device *dev,
1286 struct cfg80211_scan_request *req)
1287{
1288 struct ieee80211_sub_if_data *sdata;
1289
1290 if (!netif_running(dev))
1291 return -ENETDOWN;
1292
1293 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1294
1295 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
1296 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
1297 sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
1298 return -EOPNOTSUPP;
1299
1300 return ieee80211_request_scan(sdata, req);
1301}
1302
1144struct cfg80211_ops mac80211_config_ops = { 1303struct cfg80211_ops mac80211_config_ops = {
1145 .add_virtual_intf = ieee80211_add_iface, 1304 .add_virtual_intf = ieee80211_add_iface,
1146 .del_virtual_intf = ieee80211_del_iface, 1305 .del_virtual_intf = ieee80211_del_iface,
@@ -1149,6 +1308,7 @@ struct cfg80211_ops mac80211_config_ops = {
1149 .del_key = ieee80211_del_key, 1308 .del_key = ieee80211_del_key,
1150 .get_key = ieee80211_get_key, 1309 .get_key = ieee80211_get_key,
1151 .set_default_key = ieee80211_config_default_key, 1310 .set_default_key = ieee80211_config_default_key,
1311 .set_default_mgmt_key = ieee80211_config_default_mgmt_key,
1152 .add_beacon = ieee80211_add_beacon, 1312 .add_beacon = ieee80211_add_beacon,
1153 .set_beacon = ieee80211_set_beacon, 1313 .set_beacon = ieee80211_set_beacon,
1154 .del_beacon = ieee80211_del_beacon, 1314 .del_beacon = ieee80211_del_beacon,
@@ -1169,4 +1329,8 @@ struct cfg80211_ops mac80211_config_ops = {
1169 .change_bss = ieee80211_change_bss, 1329 .change_bss = ieee80211_change_bss,
1170 .set_txq_params = ieee80211_set_txq_params, 1330 .set_txq_params = ieee80211_set_txq_params,
1171 .set_channel = ieee80211_set_channel, 1331 .set_channel = ieee80211_set_channel,
1332 .set_mgmt_extra_ie = ieee80211_set_mgmt_extra_ie,
1333 .suspend = ieee80211_suspend,
1334 .resume = ieee80211_resume,
1335 .scan = ieee80211_scan,
1172}; 1336};