diff options
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r-- | net/mac80211/cfg.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 72c106915433..d1ac3ab2c515 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1175,6 +1175,87 @@ static int ieee80211_set_channel(struct wiphy *wiphy, | |||
1175 | return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | 1175 | return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
1176 | } | 1176 | } |
1177 | 1177 | ||
1178 | static int set_mgmt_extra_ie_sta(struct ieee80211_if_sta *ifsta, u8 subtype, | ||
1179 | u8 *ies, size_t ies_len) | ||
1180 | { | ||
1181 | switch (subtype) { | ||
1182 | case IEEE80211_STYPE_PROBE_REQ >> 4: | ||
1183 | kfree(ifsta->ie_probereq); | ||
1184 | ifsta->ie_probereq = ies; | ||
1185 | ifsta->ie_probereq_len = ies_len; | ||
1186 | return 0; | ||
1187 | case IEEE80211_STYPE_PROBE_RESP >> 4: | ||
1188 | kfree(ifsta->ie_proberesp); | ||
1189 | ifsta->ie_proberesp = ies; | ||
1190 | ifsta->ie_proberesp_len = ies_len; | ||
1191 | return 0; | ||
1192 | case IEEE80211_STYPE_AUTH >> 4: | ||
1193 | kfree(ifsta->ie_auth); | ||
1194 | ifsta->ie_auth = ies; | ||
1195 | ifsta->ie_auth_len = ies_len; | ||
1196 | return 0; | ||
1197 | case IEEE80211_STYPE_ASSOC_REQ >> 4: | ||
1198 | kfree(ifsta->ie_assocreq); | ||
1199 | ifsta->ie_assocreq = ies; | ||
1200 | ifsta->ie_assocreq_len = ies_len; | ||
1201 | return 0; | ||
1202 | case IEEE80211_STYPE_REASSOC_REQ >> 4: | ||
1203 | kfree(ifsta->ie_reassocreq); | ||
1204 | ifsta->ie_reassocreq = ies; | ||
1205 | ifsta->ie_reassocreq_len = ies_len; | ||
1206 | return 0; | ||
1207 | case IEEE80211_STYPE_DEAUTH >> 4: | ||
1208 | kfree(ifsta->ie_deauth); | ||
1209 | ifsta->ie_deauth = ies; | ||
1210 | ifsta->ie_deauth_len = ies_len; | ||
1211 | return 0; | ||
1212 | case IEEE80211_STYPE_DISASSOC >> 4: | ||
1213 | kfree(ifsta->ie_disassoc); | ||
1214 | ifsta->ie_disassoc = ies; | ||
1215 | ifsta->ie_disassoc_len = ies_len; | ||
1216 | return 0; | ||
1217 | } | ||
1218 | |||
1219 | return -EOPNOTSUPP; | ||
1220 | } | ||
1221 | |||
1222 | static int ieee80211_set_mgmt_extra_ie(struct wiphy *wiphy, | ||
1223 | struct net_device *dev, | ||
1224 | struct mgmt_extra_ie_params *params) | ||
1225 | { | ||
1226 | struct ieee80211_sub_if_data *sdata; | ||
1227 | u8 *ies; | ||
1228 | size_t ies_len; | ||
1229 | int ret = -EOPNOTSUPP; | ||
1230 | |||
1231 | if (params->ies) { | ||
1232 | ies = kmemdup(params->ies, params->ies_len, GFP_KERNEL); | ||
1233 | if (ies == NULL) | ||
1234 | return -ENOMEM; | ||
1235 | ies_len = params->ies_len; | ||
1236 | } else { | ||
1237 | ies = NULL; | ||
1238 | ies_len = 0; | ||
1239 | } | ||
1240 | |||
1241 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1242 | |||
1243 | switch (sdata->vif.type) { | ||
1244 | case NL80211_IFTYPE_STATION: | ||
1245 | case NL80211_IFTYPE_ADHOC: | ||
1246 | ret = set_mgmt_extra_ie_sta(&sdata->u.sta, params->subtype, | ||
1247 | ies, ies_len); | ||
1248 | break; | ||
1249 | default: | ||
1250 | ret = -EOPNOTSUPP; | ||
1251 | break; | ||
1252 | } | ||
1253 | |||
1254 | if (ret) | ||
1255 | kfree(ies); | ||
1256 | return ret; | ||
1257 | } | ||
1258 | |||
1178 | struct cfg80211_ops mac80211_config_ops = { | 1259 | struct cfg80211_ops mac80211_config_ops = { |
1179 | .add_virtual_intf = ieee80211_add_iface, | 1260 | .add_virtual_intf = ieee80211_add_iface, |
1180 | .del_virtual_intf = ieee80211_del_iface, | 1261 | .del_virtual_intf = ieee80211_del_iface, |
@@ -1204,4 +1285,5 @@ struct cfg80211_ops mac80211_config_ops = { | |||
1204 | .change_bss = ieee80211_change_bss, | 1285 | .change_bss = ieee80211_change_bss, |
1205 | .set_txq_params = ieee80211_set_txq_params, | 1286 | .set_txq_params = ieee80211_set_txq_params, |
1206 | .set_channel = ieee80211_set_channel, | 1287 | .set_channel = ieee80211_set_channel, |
1288 | .set_mgmt_extra_ie = ieee80211_set_mgmt_extra_ie, | ||
1207 | }; | 1289 | }; |