aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/nl80211.h8
-rw-r--r--include/net/cfg80211.h26
-rw-r--r--net/mac80211/cfg.c86
-rw-r--r--net/mac80211/ieee80211_i.h15
-rw-r--r--net/mac80211/iface.c7
-rw-r--r--net/mac80211/mlme.c36
-rw-r--r--net/mac80211/util.c29
-rw-r--r--net/wireless/nl80211.c47
8 files changed, 14 insertions, 240 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 9685eaab40a9..cbe8ce3bf486 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -142,6 +142,12 @@
142 * %NL80211_ATTR_IE. If the command succeeds, the requested data will be 142 * %NL80211_ATTR_IE. If the command succeeds, the requested data will be
143 * added to all specified management frames generated by 143 * added to all specified management frames generated by
144 * kernel/firmware/driver. 144 * kernel/firmware/driver.
145 * Note: This command has been removed and it is only reserved at this
146 * point to avoid re-using existing command number. The functionality this
147 * command was planned for has been provided with cleaner design with the
148 * option to specify additional IEs in NL80211_CMD_TRIGGER_SCAN,
149 * NL80211_CMD_AUTHENTICATE, NL80211_CMD_ASSOCIATE,
150 * NL80211_CMD_DEAUTHENTICATE, and NL80211_CMD_DISASSOCIATE.
145 * 151 *
146 * @NL80211_CMD_GET_SCAN: get scan results 152 * @NL80211_CMD_GET_SCAN: get scan results
147 * @NL80211_CMD_TRIGGER_SCAN: trigger a new scan with the given parameters 153 * @NL80211_CMD_TRIGGER_SCAN: trigger a new scan with the given parameters
@@ -238,7 +244,7 @@ enum nl80211_commands {
238 NL80211_CMD_GET_MESH_PARAMS, 244 NL80211_CMD_GET_MESH_PARAMS,
239 NL80211_CMD_SET_MESH_PARAMS, 245 NL80211_CMD_SET_MESH_PARAMS,
240 246
241 NL80211_CMD_SET_MGMT_EXTRA_IE, 247 NL80211_CMD_SET_MGMT_EXTRA_IE /* reserved; not used */,
242 248
243 NL80211_CMD_GET_REG, 249 NL80211_CMD_GET_REG,
244 250
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0da9a55881a1..dca4a6b0461b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -471,26 +471,6 @@ struct ieee80211_txq_params {
471 u8 aifs; 471 u8 aifs;
472}; 472};
473 473
474/**
475 * struct mgmt_extra_ie_params - Extra management frame IE parameters
476 *
477 * Used to add extra IE(s) into management frames. If the driver cannot add the
478 * requested data into all management frames of the specified subtype that are
479 * generated in kernel or firmware/hardware, it must reject the configuration
480 * call. The IE data buffer is added to the end of the specified management
481 * frame body after all other IEs. This addition is not applied to frames that
482 * are injected through a monitor interface.
483 *
484 * @subtype: Management frame subtype
485 * @ies: IE data buffer or %NULL to remove previous data
486 * @ies_len: Length of @ies in octets
487 */
488struct mgmt_extra_ie_params {
489 u8 subtype;
490 u8 *ies;
491 int ies_len;
492};
493
494/* from net/wireless.h */ 474/* from net/wireless.h */
495struct wiphy; 475struct wiphy;
496 476
@@ -743,8 +723,6 @@ struct cfg80211_disassoc_request {
743 * 723 *
744 * @set_channel: Set channel 724 * @set_channel: Set channel
745 * 725 *
746 * @set_mgmt_extra_ie: Set extra IE data for management frames
747 *
748 * @scan: Request to do a scan. If returning zero, the scan request is given 726 * @scan: Request to do a scan. If returning zero, the scan request is given
749 * the driver, and will be valid until passed to cfg80211_scan_done(). 727 * the driver, and will be valid until passed to cfg80211_scan_done().
750 * For scan results, call cfg80211_inform_bss(); you can call this outside 728 * For scan results, call cfg80211_inform_bss(); you can call this outside
@@ -828,10 +806,6 @@ struct cfg80211_ops {
828 struct ieee80211_channel *chan, 806 struct ieee80211_channel *chan,
829 enum nl80211_channel_type channel_type); 807 enum nl80211_channel_type channel_type);
830 808
831 int (*set_mgmt_extra_ie)(struct wiphy *wiphy,
832 struct net_device *dev,
833 struct mgmt_extra_ie_params *params);
834
835 int (*scan)(struct wiphy *wiphy, struct net_device *dev, 809 int (*scan)(struct wiphy *wiphy, struct net_device *dev,
836 struct cfg80211_scan_request *request); 810 struct cfg80211_scan_request *request);
837 811
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 223e536e8426..f5c15c9a00ce 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1181,91 +1181,6 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
1181 return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 1181 return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
1182} 1182}
1183 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 1184#ifdef CONFIG_PM
1270static int ieee80211_suspend(struct wiphy *wiphy) 1185static int ieee80211_suspend(struct wiphy *wiphy)
1271{ 1186{
@@ -1465,7 +1380,6 @@ struct cfg80211_ops mac80211_config_ops = {
1465 .change_bss = ieee80211_change_bss, 1380 .change_bss = ieee80211_change_bss,
1466 .set_txq_params = ieee80211_set_txq_params, 1381 .set_txq_params = ieee80211_set_txq_params,
1467 .set_channel = ieee80211_set_channel, 1382 .set_channel = ieee80211_set_channel,
1468 .set_mgmt_extra_ie = ieee80211_set_mgmt_extra_ie,
1469 .suspend = ieee80211_suspend, 1383 .suspend = ieee80211_suspend,
1470 .resume = ieee80211_resume, 1384 .resume = ieee80211_resume,
1471 .scan = ieee80211_scan, 1385 .scan = ieee80211_scan,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 547cfac218ee..f69e84ab9617 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -323,21 +323,6 @@ struct ieee80211_if_managed {
323 int wmm_last_param_set; 323 int wmm_last_param_set;
324 324
325 /* Extra IE data for management frames */ 325 /* Extra IE data for management frames */
326 u8 *ie_probereq;
327 size_t ie_probereq_len;
328 u8 *ie_proberesp;
329 size_t ie_proberesp_len;
330 u8 *ie_auth;
331 size_t ie_auth_len;
332 u8 *ie_assocreq;
333 size_t ie_assocreq_len;
334 u8 *ie_reassocreq;
335 size_t ie_reassocreq_len;
336 u8 *ie_deauth;
337 size_t ie_deauth_len;
338 u8 *ie_disassoc;
339 size_t ie_disassoc_len;
340
341 u8 *sme_auth_ie; 326 u8 *sme_auth_ie;
342 size_t sme_auth_ie_len; 327 size_t sme_auth_ie_len;
343}; 328};
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 6b56dc2208e7..34f4798a98f7 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -653,13 +653,6 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
653 kfree(sdata->u.mgd.extra_ie); 653 kfree(sdata->u.mgd.extra_ie);
654 kfree(sdata->u.mgd.assocreq_ies); 654 kfree(sdata->u.mgd.assocreq_ies);
655 kfree(sdata->u.mgd.assocresp_ies); 655 kfree(sdata->u.mgd.assocresp_ies);
656 kfree(sdata->u.mgd.ie_probereq);
657 kfree(sdata->u.mgd.ie_proberesp);
658 kfree(sdata->u.mgd.ie_auth);
659 kfree(sdata->u.mgd.ie_assocreq);
660 kfree(sdata->u.mgd.ie_reassocreq);
661 kfree(sdata->u.mgd.ie_deauth);
662 kfree(sdata->u.mgd.ie_disassoc);
663 kfree(sdata->u.mgd.sme_auth_ie); 656 kfree(sdata->u.mgd.sme_auth_ie);
664 break; 657 break;
665 case NL80211_IFTYPE_WDS: 658 case NL80211_IFTYPE_WDS:
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index d1bcc8438772..b0808efcedf6 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -82,38 +82,23 @@ static int ieee80211_compatible_rates(struct ieee80211_bss *bss,
82 82
83/* frame sending functions */ 83/* frame sending functions */
84 84
85static void add_extra_ies(struct sk_buff *skb, u8 *ies, size_t ies_len)
86{
87 if (ies)
88 memcpy(skb_put(skb, ies_len), ies, ies_len);
89}
90
91static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) 85static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
92{ 86{
93 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 87 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
94 struct ieee80211_local *local = sdata->local; 88 struct ieee80211_local *local = sdata->local;
95 struct sk_buff *skb; 89 struct sk_buff *skb;
96 struct ieee80211_mgmt *mgmt; 90 struct ieee80211_mgmt *mgmt;
97 u8 *pos, *ies, *ht_ie, *e_ies; 91 u8 *pos, *ies, *ht_ie;
98 int i, len, count, rates_len, supp_rates_len; 92 int i, len, count, rates_len, supp_rates_len;
99 u16 capab; 93 u16 capab;
100 struct ieee80211_bss *bss; 94 struct ieee80211_bss *bss;
101 int wmm = 0; 95 int wmm = 0;
102 struct ieee80211_supported_band *sband; 96 struct ieee80211_supported_band *sband;
103 u32 rates = 0; 97 u32 rates = 0;
104 size_t e_ies_len;
105
106 if (ifmgd->flags & IEEE80211_STA_PREV_BSSID_SET) {
107 e_ies = sdata->u.mgd.ie_reassocreq;
108 e_ies_len = sdata->u.mgd.ie_reassocreq_len;
109 } else {
110 e_ies = sdata->u.mgd.ie_assocreq;
111 e_ies_len = sdata->u.mgd.ie_assocreq_len;
112 }
113 98
114 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 99 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
115 sizeof(*mgmt) + 200 + ifmgd->extra_ie_len + 100 sizeof(*mgmt) + 200 + ifmgd->extra_ie_len +
116 ifmgd->ssid_len + e_ies_len); 101 ifmgd->ssid_len);
117 if (!skb) { 102 if (!skb) {
118 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc " 103 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc "
119 "frame\n", sdata->dev->name); 104 "frame\n", sdata->dev->name);
@@ -304,8 +289,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
304 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); 289 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
305 } 290 }
306 291
307 add_extra_ies(skb, e_ies, e_ies_len);
308
309 kfree(ifmgd->assocreq_ies); 292 kfree(ifmgd->assocreq_ies);
310 ifmgd->assocreq_ies_len = (skb->data + skb->len) - ies; 293 ifmgd->assocreq_ies_len = (skb->data + skb->len) - ies;
311 ifmgd->assocreq_ies = kmalloc(ifmgd->assocreq_ies_len, GFP_KERNEL); 294 ifmgd->assocreq_ies = kmalloc(ifmgd->assocreq_ies_len, GFP_KERNEL);
@@ -323,19 +306,8 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
323 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 306 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
324 struct sk_buff *skb; 307 struct sk_buff *skb;
325 struct ieee80211_mgmt *mgmt; 308 struct ieee80211_mgmt *mgmt;
326 u8 *ies;
327 size_t ies_len;
328 309
329 if (stype == IEEE80211_STYPE_DEAUTH) { 310 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt));
330 ies = sdata->u.mgd.ie_deauth;
331 ies_len = sdata->u.mgd.ie_deauth_len;
332 } else {
333 ies = sdata->u.mgd.ie_disassoc;
334 ies_len = sdata->u.mgd.ie_disassoc_len;
335 }
336
337 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) +
338 ies_len);
339 if (!skb) { 311 if (!skb) {
340 printk(KERN_DEBUG "%s: failed to allocate buffer for " 312 printk(KERN_DEBUG "%s: failed to allocate buffer for "
341 "deauth/disassoc frame\n", sdata->dev->name); 313 "deauth/disassoc frame\n", sdata->dev->name);
@@ -353,8 +325,6 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
353 /* u.deauth.reason_code == u.disassoc.reason_code */ 325 /* u.deauth.reason_code == u.disassoc.reason_code */
354 mgmt->u.deauth.reason_code = cpu_to_le16(reason); 326 mgmt->u.deauth.reason_code = cpu_to_le16(reason);
355 327
356 add_extra_ies(skb, ies, ies_len);
357
358 ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED); 328 ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED);
359} 329}
360 330
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index e0431a1d218b..444bb14c95e1 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -846,16 +846,9 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
846 struct ieee80211_local *local = sdata->local; 846 struct ieee80211_local *local = sdata->local;
847 struct sk_buff *skb; 847 struct sk_buff *skb;
848 struct ieee80211_mgmt *mgmt; 848 struct ieee80211_mgmt *mgmt;
849 const u8 *ie_auth = NULL;
850 int ie_auth_len = 0;
851
852 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
853 ie_auth_len = sdata->u.mgd.ie_auth_len;
854 ie_auth = sdata->u.mgd.ie_auth;
855 }
856 849
857 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 850 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
858 sizeof(*mgmt) + 6 + extra_len + ie_auth_len); 851 sizeof(*mgmt) + 6 + extra_len);
859 if (!skb) { 852 if (!skb) {
860 printk(KERN_DEBUG "%s: failed to allocate buffer for auth " 853 printk(KERN_DEBUG "%s: failed to allocate buffer for auth "
861 "frame\n", sdata->dev->name); 854 "frame\n", sdata->dev->name);
@@ -877,8 +870,6 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
877 mgmt->u.auth.status_code = cpu_to_le16(0); 870 mgmt->u.auth.status_code = cpu_to_le16(0);
878 if (extra) 871 if (extra)
879 memcpy(skb_put(skb, extra_len), extra, extra_len); 872 memcpy(skb_put(skb, extra_len), extra, extra_len);
880 if (ie_auth)
881 memcpy(skb_put(skb, ie_auth_len), ie_auth, ie_auth_len);
882 873
883 ieee80211_tx_skb(sdata, skb, encrypt); 874 ieee80211_tx_skb(sdata, skb, encrypt);
884} 875}
@@ -891,20 +882,11 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
891 struct ieee80211_supported_band *sband; 882 struct ieee80211_supported_band *sband;
892 struct sk_buff *skb; 883 struct sk_buff *skb;
893 struct ieee80211_mgmt *mgmt; 884 struct ieee80211_mgmt *mgmt;
894 u8 *pos, *supp_rates, *esupp_rates = NULL, *extra_preq_ie = NULL; 885 u8 *pos, *supp_rates, *esupp_rates = NULL;
895 int i, extra_preq_ie_len = 0; 886 int i;
896
897 switch (sdata->vif.type) {
898 case NL80211_IFTYPE_STATION:
899 extra_preq_ie_len = sdata->u.mgd.ie_probereq_len;
900 extra_preq_ie = sdata->u.mgd.ie_probereq;
901 break;
902 default:
903 break;
904 }
905 887
906 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 + 888 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 +
907 ie_len + extra_preq_ie_len); 889 ie_len);
908 if (!skb) { 890 if (!skb) {
909 printk(KERN_DEBUG "%s: failed to allocate buffer for probe " 891 printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
910 "request\n", sdata->dev->name); 892 "request\n", sdata->dev->name);
@@ -953,9 +935,6 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
953 935
954 if (ie) 936 if (ie)
955 memcpy(skb_put(skb, ie_len), ie, ie_len); 937 memcpy(skb_put(skb, ie_len), ie, ie_len);
956 if (extra_preq_ie)
957 memcpy(skb_put(skb, extra_preq_ie_len), extra_preq_ie,
958 extra_preq_ie_len);
959 938
960 ieee80211_tx_skb(sdata, skb, 0); 939 ieee80211_tx_skb(sdata, skb, 0);
961} 940}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 9e1318d1d4bb..44c79972be57 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -269,7 +269,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
269 CMD(add_mpath, NEW_MPATH); 269 CMD(add_mpath, NEW_MPATH);
270 CMD(set_mesh_params, SET_MESH_PARAMS); 270 CMD(set_mesh_params, SET_MESH_PARAMS);
271 CMD(change_bss, SET_BSS); 271 CMD(change_bss, SET_BSS);
272 CMD(set_mgmt_extra_ie, SET_MGMT_EXTRA_IE);
273 CMD(auth, AUTHENTICATE); 272 CMD(auth, AUTHENTICATE);
274 CMD(assoc, ASSOCIATE); 273 CMD(assoc, ASSOCIATE);
275 CMD(deauth, DEAUTHENTICATE); 274 CMD(deauth, DEAUTHENTICATE);
@@ -2355,46 +2354,6 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
2355 return -EINVAL; 2354 return -EINVAL;
2356} 2355}
2357 2356
2358static int nl80211_set_mgmt_extra_ie(struct sk_buff *skb,
2359 struct genl_info *info)
2360{
2361 struct cfg80211_registered_device *drv;
2362 int err;
2363 struct net_device *dev;
2364 struct mgmt_extra_ie_params params;
2365
2366 memset(&params, 0, sizeof(params));
2367
2368 if (!info->attrs[NL80211_ATTR_MGMT_SUBTYPE])
2369 return -EINVAL;
2370 params.subtype = nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
2371 if (params.subtype > 15)
2372 return -EINVAL; /* FC Subtype field is 4 bits (0..15) */
2373
2374 if (info->attrs[NL80211_ATTR_IE]) {
2375 params.ies = nla_data(info->attrs[NL80211_ATTR_IE]);
2376 params.ies_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2377 }
2378
2379 rtnl_lock();
2380
2381 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2382 if (err)
2383 goto out_rtnl;
2384
2385 if (drv->ops->set_mgmt_extra_ie)
2386 err = drv->ops->set_mgmt_extra_ie(&drv->wiphy, dev, &params);
2387 else
2388 err = -EOPNOTSUPP;
2389
2390 cfg80211_put_dev(drv);
2391 dev_put(dev);
2392 out_rtnl:
2393 rtnl_unlock();
2394
2395 return err;
2396}
2397
2398static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) 2357static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2399{ 2358{
2400 struct cfg80211_registered_device *drv; 2359 struct cfg80211_registered_device *drv;
@@ -3044,12 +3003,6 @@ static struct genl_ops nl80211_ops[] = {
3044 .flags = GENL_ADMIN_PERM, 3003 .flags = GENL_ADMIN_PERM,
3045 }, 3004 },
3046 { 3005 {
3047 .cmd = NL80211_CMD_SET_MGMT_EXTRA_IE,
3048 .doit = nl80211_set_mgmt_extra_ie,
3049 .policy = nl80211_policy,
3050 .flags = GENL_ADMIN_PERM,
3051 },
3052 {
3053 .cmd = NL80211_CMD_TRIGGER_SCAN, 3006 .cmd = NL80211_CMD_TRIGGER_SCAN,
3054 .doit = nl80211_trigger_scan, 3007 .doit = nl80211_trigger_scan,
3055 .policy = nl80211_policy, 3008 .policy = nl80211_policy,