aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex/ie.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mwifiex/ie.c')
-rw-r--r--drivers/net/wireless/mwifiex/ie.c88
1 files changed, 55 insertions, 33 deletions
diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c
index 1d8dd003e396..e38342f86c51 100644
--- a/drivers/net/wireless/mwifiex/ie.c
+++ b/drivers/net/wireless/mwifiex/ie.c
@@ -114,9 +114,6 @@ mwifiex_update_autoindex_ies(struct mwifiex_private *priv,
114 cpu_to_le16(mask); 114 cpu_to_le16(mask);
115 115
116 ie->ie_index = cpu_to_le16(index); 116 ie->ie_index = cpu_to_le16(index);
117 ie->ie_length = priv->mgmt_ie[index].ie_length;
118 memcpy(&ie->ie_buffer, &priv->mgmt_ie[index].ie_buffer,
119 le16_to_cpu(priv->mgmt_ie[index].ie_length));
120 } else { 117 } else {
121 if (mask != MWIFIEX_DELETE_MASK) 118 if (mask != MWIFIEX_DELETE_MASK)
122 return -1; 119 return -1;
@@ -160,7 +157,7 @@ mwifiex_update_uap_custom_ie(struct mwifiex_private *priv,
160 u16 len; 157 u16 len;
161 int ret; 158 int ret;
162 159
163 ap_custom_ie = kzalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); 160 ap_custom_ie = kzalloc(sizeof(*ap_custom_ie), GFP_KERNEL);
164 if (!ap_custom_ie) 161 if (!ap_custom_ie)
165 return -ENOMEM; 162 return -ENOMEM;
166 163
@@ -214,30 +211,35 @@ mwifiex_update_uap_custom_ie(struct mwifiex_private *priv,
214 return ret; 211 return ret;
215} 212}
216 213
217/* This function checks if WPS IE is present in passed buffer and copies it to 214/* This function checks if the vendor specified IE is present in passed buffer
218 * mwifiex_ie structure. 215 * and copies it to mwifiex_ie structure.
219 * Function takes pointer to struct mwifiex_ie pointer as argument. 216 * Function takes pointer to struct mwifiex_ie pointer as argument.
220 * If WPS IE is present memory is allocated for mwifiex_ie pointer and filled 217 * If the vendor specified IE is present then memory is allocated for
221 * in with WPS IE. Caller should take care of freeing this memory. 218 * mwifiex_ie pointer and filled in with IE. Caller should take care of freeing
219 * this memory.
222 */ 220 */
223static int mwifiex_update_wps_ie(const u8 *ies, int ies_len, 221static int mwifiex_update_vs_ie(const u8 *ies, int ies_len,
224 struct mwifiex_ie **ie_ptr, u16 mask) 222 struct mwifiex_ie **ie_ptr, u16 mask,
223 unsigned int oui, u8 oui_type)
225{ 224{
226 struct ieee_types_header *wps_ie; 225 struct ieee_types_header *vs_ie;
227 struct mwifiex_ie *ie = NULL; 226 struct mwifiex_ie *ie = *ie_ptr;
228 const u8 *vendor_ie; 227 const u8 *vendor_ie;
229 228
230 vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, 229 vendor_ie = cfg80211_find_vendor_ie(oui, oui_type, ies, ies_len);
231 WLAN_OUI_TYPE_MICROSOFT_WPS,
232 ies, ies_len);
233 if (vendor_ie) { 230 if (vendor_ie) {
234 ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); 231 if (!*ie_ptr) {
235 if (!ie) 232 *ie_ptr = kzalloc(sizeof(struct mwifiex_ie),
236 return -ENOMEM; 233 GFP_KERNEL);
234 if (!*ie_ptr)
235 return -ENOMEM;
236 ie = *ie_ptr;
237 }
237 238
238 wps_ie = (struct ieee_types_header *)vendor_ie; 239 vs_ie = (struct ieee_types_header *)vendor_ie;
239 memcpy(ie->ie_buffer, wps_ie, wps_ie->len + 2); 240 memcpy(ie->ie_buffer + le16_to_cpu(ie->ie_length),
240 ie->ie_length = cpu_to_le16(wps_ie->len + 2); 241 vs_ie, vs_ie->len + 2);
242 le16_add_cpu(&ie->ie_length, vs_ie->len + 2);
241 ie->mgmt_subtype_mask = cpu_to_le16(mask); 243 ie->mgmt_subtype_mask = cpu_to_le16(mask);
242 ie->ie_index = cpu_to_le16(MWIFIEX_AUTO_IDX_MASK); 244 ie->ie_index = cpu_to_le16(MWIFIEX_AUTO_IDX_MASK);
243 } 245 }
@@ -257,20 +259,40 @@ static int mwifiex_set_mgmt_beacon_data_ies(struct mwifiex_private *priv,
257 u16 ar_idx = MWIFIEX_AUTO_IDX_MASK; 259 u16 ar_idx = MWIFIEX_AUTO_IDX_MASK;
258 int ret = 0; 260 int ret = 0;
259 261
260 if (data->beacon_ies && data->beacon_ies_len) 262 if (data->beacon_ies && data->beacon_ies_len) {
261 mwifiex_update_wps_ie(data->beacon_ies, data->beacon_ies_len, 263 mwifiex_update_vs_ie(data->beacon_ies, data->beacon_ies_len,
262 &beacon_ie, MGMT_MASK_BEACON); 264 &beacon_ie, MGMT_MASK_BEACON,
265 WLAN_OUI_MICROSOFT,
266 WLAN_OUI_TYPE_MICROSOFT_WPS);
267 mwifiex_update_vs_ie(data->beacon_ies, data->beacon_ies_len,
268 &beacon_ie, MGMT_MASK_BEACON,
269 WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P);
270 }
263 271
264 if (data->proberesp_ies && data->proberesp_ies_len) 272 if (data->proberesp_ies && data->proberesp_ies_len) {
265 mwifiex_update_wps_ie(data->proberesp_ies, 273 mwifiex_update_vs_ie(data->proberesp_ies,
266 data->proberesp_ies_len, &pr_ie, 274 data->proberesp_ies_len, &pr_ie,
267 MGMT_MASK_PROBE_RESP); 275 MGMT_MASK_PROBE_RESP, WLAN_OUI_MICROSOFT,
276 WLAN_OUI_TYPE_MICROSOFT_WPS);
277 mwifiex_update_vs_ie(data->proberesp_ies,
278 data->proberesp_ies_len, &pr_ie,
279 MGMT_MASK_PROBE_RESP,
280 WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P);
281 }
268 282
269 if (data->assocresp_ies && data->assocresp_ies_len) 283 if (data->assocresp_ies && data->assocresp_ies_len) {
270 mwifiex_update_wps_ie(data->assocresp_ies, 284 mwifiex_update_vs_ie(data->assocresp_ies,
271 data->assocresp_ies_len, &ar_ie, 285 data->assocresp_ies_len, &ar_ie,
272 MGMT_MASK_ASSOC_RESP | 286 MGMT_MASK_ASSOC_RESP |
273 MGMT_MASK_REASSOC_RESP); 287 MGMT_MASK_REASSOC_RESP,
288 WLAN_OUI_MICROSOFT,
289 WLAN_OUI_TYPE_MICROSOFT_WPS);
290 mwifiex_update_vs_ie(data->assocresp_ies,
291 data->assocresp_ies_len, &ar_ie,
292 MGMT_MASK_ASSOC_RESP |
293 MGMT_MASK_REASSOC_RESP, WLAN_OUI_WFA,
294 WLAN_OUI_TYPE_WFA_P2P);
295 }
274 296
275 if (beacon_ie || pr_ie || ar_ie) { 297 if (beacon_ie || pr_ie || ar_ie) {
276 ret = mwifiex_update_uap_custom_ie(priv, beacon_ie, 298 ret = mwifiex_update_uap_custom_ie(priv, beacon_ie,