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.c79
1 files changed, 65 insertions, 14 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index c981604b71e6..ecf9b7166ed1 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -68,14 +68,42 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
68 params && params->use_4addr >= 0) 68 params && params->use_4addr >= 0)
69 sdata->u.mgd.use_4addr = params->use_4addr; 69 sdata->u.mgd.use_4addr = params->use_4addr;
70 70
71 if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) 71 if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) {
72 sdata->u.mntr_flags = *flags; 72 struct ieee80211_local *local = sdata->local;
73
74 if (ieee80211_sdata_running(sdata)) {
75 /*
76 * Prohibit MONITOR_FLAG_COOK_FRAMES to be
77 * changed while the interface is up.
78 * Else we would need to add a lot of cruft
79 * to update everything:
80 * cooked_mntrs, monitor and all fif_* counters
81 * reconfigure hardware
82 */
83 if ((*flags & MONITOR_FLAG_COOK_FRAMES) !=
84 (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES))
85 return -EBUSY;
86
87 ieee80211_adjust_monitor_flags(sdata, -1);
88 sdata->u.mntr_flags = *flags;
89 ieee80211_adjust_monitor_flags(sdata, 1);
90
91 ieee80211_configure_filter(local);
92 } else {
93 /*
94 * Because the interface is down, ieee80211_do_stop
95 * and ieee80211_do_open take care of "everything"
96 * mentioned in the comment above.
97 */
98 sdata->u.mntr_flags = *flags;
99 }
100 }
73 101
74 return 0; 102 return 0;
75} 103}
76 104
77static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, 105static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
78 u8 key_idx, const u8 *mac_addr, 106 u8 key_idx, bool pairwise, const u8 *mac_addr,
79 struct key_params *params) 107 struct key_params *params)
80{ 108{
81 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 109 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -103,6 +131,9 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
103 if (IS_ERR(key)) 131 if (IS_ERR(key))
104 return PTR_ERR(key); 132 return PTR_ERR(key);
105 133
134 if (pairwise)
135 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;
136
106 mutex_lock(&sdata->local->sta_mtx); 137 mutex_lock(&sdata->local->sta_mtx);
107 138
108 if (mac_addr) { 139 if (mac_addr) {
@@ -125,7 +156,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
125} 156}
126 157
127static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, 158static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
128 u8 key_idx, const u8 *mac_addr) 159 u8 key_idx, bool pairwise, const u8 *mac_addr)
129{ 160{
130 struct ieee80211_sub_if_data *sdata; 161 struct ieee80211_sub_if_data *sdata;
131 struct sta_info *sta; 162 struct sta_info *sta;
@@ -142,10 +173,17 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
142 if (!sta) 173 if (!sta)
143 goto out_unlock; 174 goto out_unlock;
144 175
145 if (sta->key) { 176 if (pairwise) {
146 ieee80211_key_free(sdata->local, sta->key); 177 if (sta->ptk) {
147 WARN_ON(sta->key); 178 ieee80211_key_free(sdata->local, sta->ptk);
148 ret = 0; 179 ret = 0;
180 }
181 } else {
182 if (sta->gtk[key_idx]) {
183 ieee80211_key_free(sdata->local,
184 sta->gtk[key_idx]);
185 ret = 0;
186 }
149 } 187 }
150 188
151 goto out_unlock; 189 goto out_unlock;
@@ -167,7 +205,8 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
167} 205}
168 206
169static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, 207static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
170 u8 key_idx, const u8 *mac_addr, void *cookie, 208 u8 key_idx, bool pairwise, const u8 *mac_addr,
209 void *cookie,
171 void (*callback)(void *cookie, 210 void (*callback)(void *cookie,
172 struct key_params *params)) 211 struct key_params *params))
173{ 212{
@@ -175,7 +214,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
175 struct sta_info *sta = NULL; 214 struct sta_info *sta = NULL;
176 u8 seq[6] = {0}; 215 u8 seq[6] = {0};
177 struct key_params params; 216 struct key_params params;
178 struct ieee80211_key *key; 217 struct ieee80211_key *key = NULL;
179 u32 iv32; 218 u32 iv32;
180 u16 iv16; 219 u16 iv16;
181 int err = -ENOENT; 220 int err = -ENOENT;
@@ -189,7 +228,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
189 if (!sta) 228 if (!sta)
190 goto out; 229 goto out;
191 230
192 key = sta->key; 231 if (pairwise)
232 key = sta->ptk;
233 else if (key_idx < NUM_DEFAULT_KEYS)
234 key = sta->gtk[key_idx];
193 } else 235 } else
194 key = sdata->keys[key_idx]; 236 key = sdata->keys[key_idx];
195 237
@@ -285,6 +327,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
285 STATION_INFO_TX_BYTES | 327 STATION_INFO_TX_BYTES |
286 STATION_INFO_RX_PACKETS | 328 STATION_INFO_RX_PACKETS |
287 STATION_INFO_TX_PACKETS | 329 STATION_INFO_TX_PACKETS |
330 STATION_INFO_TX_RETRIES |
331 STATION_INFO_TX_FAILED |
288 STATION_INFO_TX_BITRATE; 332 STATION_INFO_TX_BITRATE;
289 333
290 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); 334 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
@@ -292,6 +336,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
292 sinfo->tx_bytes = sta->tx_bytes; 336 sinfo->tx_bytes = sta->tx_bytes;
293 sinfo->rx_packets = sta->rx_packets; 337 sinfo->rx_packets = sta->rx_packets;
294 sinfo->tx_packets = sta->tx_packets; 338 sinfo->tx_packets = sta->tx_packets;
339 sinfo->tx_retries = sta->tx_retry_count;
340 sinfo->tx_failed = sta->tx_retry_failed;
295 341
296 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || 342 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
297 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { 343 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
@@ -1317,7 +1363,7 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm)
1317} 1363}
1318 1364
1319static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, 1365static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
1320 u8 *addr) 1366 const u8 *addr)
1321{ 1367{
1322 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1368 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1323 1369
@@ -1366,7 +1412,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
1366 if (!sdata->u.mgd.associated || 1412 if (!sdata->u.mgd.associated ||
1367 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) { 1413 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) {
1368 mutex_lock(&sdata->local->iflist_mtx); 1414 mutex_lock(&sdata->local->iflist_mtx);
1369 ieee80211_recalc_smps(sdata->local, sdata); 1415 ieee80211_recalc_smps(sdata->local);
1370 mutex_unlock(&sdata->local->iflist_mtx); 1416 mutex_unlock(&sdata->local->iflist_mtx);
1371 return 0; 1417 return 0;
1372 } 1418 }
@@ -1521,7 +1567,11 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1521 1567
1522 switch (sdata->vif.type) { 1568 switch (sdata->vif.type) {
1523 case NL80211_IFTYPE_ADHOC: 1569 case NL80211_IFTYPE_ADHOC:
1524 if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) 1570 case NL80211_IFTYPE_AP:
1571 case NL80211_IFTYPE_AP_VLAN:
1572 case NL80211_IFTYPE_P2P_GO:
1573 if (!ieee80211_is_action(mgmt->frame_control) ||
1574 mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)
1525 break; 1575 break;
1526 rcu_read_lock(); 1576 rcu_read_lock();
1527 sta = sta_info_get(sdata, mgmt->da); 1577 sta = sta_info_get(sdata, mgmt->da);
@@ -1530,6 +1580,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1530 return -ENOLINK; 1580 return -ENOLINK;
1531 break; 1581 break;
1532 case NL80211_IFTYPE_STATION: 1582 case NL80211_IFTYPE_STATION:
1583 case NL80211_IFTYPE_P2P_CLIENT:
1533 break; 1584 break;
1534 default: 1585 default:
1535 return -EOPNOTSUPP; 1586 return -EOPNOTSUPP;