1 diff -ru cx3110x-module-src-2.0.14.orig/src/sm_drv_ioctl_umac.c cx3110x-module-src-2.0.14/src/sm_drv_ioctl_umac.c
2 --- cx3110x-module-src-2.0.14.orig/src/sm_drv_ioctl_umac.c 2007-09-25 13:02:17.000000000 -0300
3 +++ cx3110x-module-src-2.0.14/src/sm_drv_ioctl_umac.c 2007-10-09 15:32:30.000000000 -0300
5 kfree(wrqu.data.pointer);
8 -void send_wpa_ie_event(struct net_device *dev, char * bss_addr,
9 - char * wpa_ie, size_t wpa_ie_len, uint32_t event)
10 +void send_wpa_ie_event(struct net_device *dev, char * wpa_ie,
11 + size_t wpa_ie_len, uint32_t event)
13 union iwreq_data wrqu;
19 - wrqu.data.pointer = kzalloc(ETH_ALEN + 1 + wpa_ie_len, GFP_ATOMIC);
20 + wrqu.data.pointer = kzalloc(wpa_ie_len, GFP_ATOMIC);
21 if (!wrqu.data.pointer)
24 - memcpy(wrqu.data.pointer, bss_addr, ETH_ALEN);
25 - *((char *)(wrqu.data.pointer + ETH_ALEN)) = ':';
26 - memcpy(wrqu.data.pointer + ETH_ALEN + 1, wpa_ie, wpa_ie_len);
28 - wrqu.data.length = ETH_ALEN + 1 + wpa_ie_len;
29 + memcpy(wrqu.data.pointer, wpa_ie, wpa_ie_len);
30 + wrqu.data.length = wpa_ie_len;
32 wireless_send_event(dev, we_event, &wrqu, wrqu.data.pointer);
33 kfree(wrqu.data.pointer);
35 if ((lp->link_state == DOT11_STATE_ASSOCING
36 || lp->link_state == DOT11_STATE_ASSOC)
38 - send_wpa_ie_event(dev, bssid, wpa_ie, wpa_ie_len, event);
39 + send_wpa_ie_event(dev, wpa_ie, wpa_ie_len, event);
41 /* try to use existing entry */
42 list_for_each_entry_safe(bss, safe, &lp->bss_wpa_list, list) {
43 @@ -1928,6 +1925,435 @@
44 (void *)&key, sizeof(struct obj_stakey));
47 +static int sm_drv_set_auth(struct net_device *dev,
48 + struct iw_request_info *info,
49 + union iwreq_data *wrqu, char *extra)
51 + struct net_local *priv = netdev_priv(dev);
52 + struct iw_param *param = &wrqu->param;
53 + u32 authen = 0, dot1x = 0;
54 + u32 exunencrypt = 0, privinvoked = 0, wpa = 0;
58 + DEBUG(DBG_IOCTL, "SET AUTH\n");
60 + /* first get the flags */
61 + down(&priv->wpa_sem);
62 + wpa = old_wpa = priv->wpa;
64 + ret = sm_drv_oid_get(dev, DOT11_OID_AUTHENABLE,
65 + (void *)&authen, sizeof(uint32_t));
66 + ret |= sm_drv_oid_get(dev, DOT11_OID_PRIVACYINVOKED,
67 + (void *)&privinvoked, sizeof(uint32_t));
68 + ret |= sm_drv_oid_get(dev, DOT11_OID_EXUNENCRYPTED,
69 + (void *)&exunencrypt, sizeof(uint32_t));
70 + ret |= sm_drv_oid_get(dev, DOT11_OID_DOT1XENABLE,
71 + (void *)&dot1x, sizeof(uint32_t));
76 + switch (param->flags & IW_AUTH_INDEX) {
77 + case IW_AUTH_CIPHER_PAIRWISE:
78 + case IW_AUTH_CIPHER_GROUP:
79 + case IW_AUTH_KEY_MGMT:
82 + case IW_AUTH_WPA_ENABLED:
83 + /* Do the same thing as IW_AUTH_WPA_VERSION */
85 + wpa = DOT11_PRIV_INV_TKIP;
86 + privinvoked = 1; /* For privacy invoked */
87 + exunencrypt = 1; /* Filter out all unencrypted frames */
88 + dot1x = 0x01; /* To enable eap filter */
89 + authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
91 + wpa = DOT11_PRIV_INV_NONE;
93 + exunencrypt = 0; /* Do not filter un-encrypted data */
98 + case IW_AUTH_WPA_VERSION:
99 + if (param->value & IW_AUTH_WPA_VERSION_DISABLED) {
100 + wpa = DOT11_PRIV_INV_NONE;
102 + exunencrypt = 0; /* Do not filter un-encrypted data */
105 + if (param->value & IW_AUTH_WPA_VERSION_WPA)
106 + wpa = DOT11_PRIV_INV_TKIP;
107 + else if (param->value & IW_AUTH_WPA_VERSION_WPA2)
108 + wpa = DOT11_PRIV_INV_AES_CCMP;
109 + privinvoked = 1; /* For privacy invoked */
110 + exunencrypt = 1; /* Filter out all unencrypted frames */
111 + dot1x = 0x01; /* To enable eap filter */
112 + authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
116 + case IW_AUTH_RX_UNENCRYPTED_EAPOL:
117 + /* dot1x should be the opposite of RX_UNENCRYPTED_EAPOL;
118 + * turn off dot1x when allowing receipt of unencrypted EAPOL
119 + * frames, turn on dot1x when receipt should be disallowed
121 + dot1x = param->value ? 0 : 0x01;
124 + case IW_AUTH_PRIVACY_INVOKED:
125 + privinvoked = param->value ? 1 : 0;
128 + case IW_AUTH_DROP_UNENCRYPTED:
129 + exunencrypt = param->value ? 1 : 0;
132 + case IW_AUTH_80211_AUTH_ALG:
133 + if (param->value & IW_AUTH_ALG_SHARED_KEY) {
134 + /* Only WEP uses _SK and _BOTH */
139 + authen = DOT11_AUTH_SK;
140 + } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
141 + authen = DOT11_AUTH_OS;
149 + return -EOPNOTSUPP;
152 + /* Set all the values */
153 + down(&priv->wpa_sem);
155 + up(&priv->wpa_sem);
157 + sm_drv_oid_set(dev, DOT11_OID_AUTHENABLE,
158 + (void *)&authen, sizeof(uint32_t));
159 + sm_drv_oid_set(dev, DOT11_OID_PRIVACYINVOKED,
160 + (void *)&privinvoked, sizeof(uint32_t));
161 + sm_drv_oid_set(dev, DOT11_OID_EXUNENCRYPTED,
162 + (void *)&exunencrypt, sizeof(uint32_t));
163 + sm_drv_oid_set(dev, DOT11_OID_DOT1XENABLE,
164 + (void *)&dot1x, sizeof(uint32_t));
170 +static int sm_drv_get_auth(struct net_device *dev,
171 + struct iw_request_info *info,
172 + union iwreq_data *wrqu, char *extra)
174 + struct net_local *priv = netdev_priv(dev);
175 + struct iw_param *param = &wrqu->param;
176 + u32 authen = 0, dot1x = 0;
177 + u32 exunencrypt = 0, privinvoked = 0, wpa = 0;
180 + DEBUG(DBG_IOCTL, "GET AUTH\n");
182 + /* first get the flags */
183 + down(&priv->wpa_sem);
185 + up(&priv->wpa_sem);
187 + switch (param->flags & IW_AUTH_INDEX) {
188 + case IW_AUTH_CIPHER_PAIRWISE:
189 + case IW_AUTH_CIPHER_GROUP:
190 + case IW_AUTH_KEY_MGMT:
192 + * wpa_supplicant will control these internally
197 + case IW_AUTH_WPA_VERSION:
199 + case DOT11_PRIV_INV_TKIP:
200 + param->value = IW_AUTH_WPA_VERSION_WPA;
202 + case DOT11_PRIV_INV_AES_CCMP:
203 + param->value = IW_AUTH_WPA_VERSION_WPA2;
206 + param->value = IW_AUTH_WPA_VERSION_DISABLED;
211 + case IW_AUTH_DROP_UNENCRYPTED:
212 + ret = sm_drv_oid_get(dev, DOT11_OID_EXUNENCRYPTED,
213 + (void *)&exunencrypt, sizeof(uint32_t));
215 + param->value = exunencrypt > 0 ? 1 : 0;
218 + case IW_AUTH_80211_AUTH_ALG:
219 + ret = sm_drv_oid_get(dev, DOT11_OID_AUTHENABLE,
220 + (void *)&authen, sizeof(uint32_t));
223 + case DOT11_AUTH_OS:
224 + param->value = IW_AUTH_ALG_OPEN_SYSTEM;
226 + case DOT11_AUTH_BOTH:
227 + case DOT11_AUTH_SK:
228 + param->value = IW_AUTH_ALG_SHARED_KEY;
229 + case DOT11_AUTH_NONE:
237 + case IW_AUTH_WPA_ENABLED:
238 + param->value = wpa > 0 ? 1 : 0;
241 + case IW_AUTH_RX_UNENCRYPTED_EAPOL:
242 + ret = sm_drv_oid_get(dev, DOT11_OID_DOT1XENABLE,
243 + (void *)&dot1x, sizeof(uint32_t));
245 + param->value = dot1x > 0 ? 1 : 0;
248 + case IW_AUTH_PRIVACY_INVOKED:
249 + ret = sm_drv_oid_get(dev, DOT11_OID_PRIVACYINVOKED,
250 + (void *)&privinvoked, sizeof(uint32_t));
252 + param->value = privinvoked > 0 ? 1 : 0;
256 + return -EOPNOTSUPP;
261 +#define KEY_SIZE_WEP104 13 /* 104/128-bit WEP keys */
262 +#define KEY_SIZE_WEP40 5 /* 40/64-bit WEP keys */
263 +#define KEY_SIZE_TKIP 32 /* TKIP keys */
265 +static int sm_drv_set_encodeext(struct net_device *dev,
266 + struct iw_request_info *info,
267 + union iwreq_data *wrqu,
270 + struct iw_point *encoding = &wrqu->encoding;
271 + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
272 + int idx, alg = ext->alg, set_key = 1;
273 + int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
276 + DEBUG(DBG_IOCTL, "SET ENCODEEXT\n");
278 + /* Determine and validate the key index */
279 + idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
281 + if (idx < 0 || idx > 3)
284 + ret = sm_drv_oid_get(dev, DOT11_OID_DEFKEYID,
285 + (void *)&idx, sizeof(uint32_t));
290 + if (encoding->flags & IW_ENCODE_DISABLED)
291 + alg = IW_ENCODE_ALG_NONE;
293 + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
294 + /* Only set transmit key index here, actual
295 + * key is set below if needed.
297 + ret = sm_drv_oid_set(dev, DOT11_OID_DEFKEYID,
298 + (void *)&idx, sizeof(uint32_t));
299 + set_key = ext->key_len > 0 ? 1 : 0;
304 + case IW_ENCODE_ALG_NONE:
306 + case IW_ENCODE_ALG_WEP: {
307 + struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
308 + memset(key.key, 0, sizeof(key.key));
309 + if (ext->key_len > KEY_SIZE_WEP104) {
313 + if (ext->key_len > KEY_SIZE_WEP40)
314 + key.length = KEY_SIZE_WEP104;
316 + key.length = KEY_SIZE_WEP40;
317 + memcpy(key.key, ext->key, ext->key_len);
318 + ret = sm_drv_oid_set(dev, DOT11_OID_DEFKEYID + idx + 1,
320 + sizeof(struct obj_key));
323 + case IW_ENCODE_ALG_TKIP:
324 + case IW_ENCODE_ALG_CCMP: {
325 + struct obj_stakey key;
326 + memset(key.key, 0, sizeof(key.key));
327 + if (alg == IW_ENCODE_ALG_TKIP)
328 + key.type = DOT11_PRIV_TKIP;
330 + key.type = DOT11_PRIV_AES_CCMP;
331 + memcpy(key.address, ext->addr.sa_data, ETH_ALEN);
332 + key.length = ext->key_len;
335 + memcpy(key.key, ext->key, ext->key_len);
336 + ret = sm_drv_oid_set(dev, DOT11_OID_STAKEY,
338 + sizeof(struct obj_stakey));
350 + /* Read the flags */
351 + if (encoding->flags & IW_ENCODE_DISABLED) {
352 + /* Encoding disabled,
353 + * authen = DOT11_AUTH_OS;
355 + * exunencrypt = 0; */
357 + if (encoding->flags & IW_ENCODE_OPEN) {
358 + /* Encode but accept non-encoded packets. No auth */
361 + if (encoding->flags & IW_ENCODE_RESTRICTED) {
362 + /* Refuse non-encoded packets. Auth */
363 + authen = DOT11_AUTH_BOTH;
368 + /* do the change if requested */
369 + if (encoding->flags & IW_ENCODE_MODE) {
370 + sm_drv_oid_set(dev, DOT11_OID_AUTHENABLE,
371 + (void *)&authen, sizeof(uint32_t));
372 + sm_drv_oid_set(dev, DOT11_OID_PRIVACYINVOKED,
373 + (void *)&invoke, sizeof(uint32_t));
374 + sm_drv_oid_set(dev, DOT11_OID_EXUNENCRYPTED,
375 + (void *)&exunencrypt, sizeof(uint32_t));
383 +static int sm_drv_get_encodeext(struct net_device *dev,
384 + struct iw_request_info *info,
385 + union iwreq_data *wrqu,
388 + struct net_local *priv = netdev_priv(dev);
389 + struct iw_point *encoding = &wrqu->encoding;
390 + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
391 + int idx, max_key_len;
392 + int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0, wpa = 0;
395 + DEBUG(DBG_IOCTL, "GET ENCODEEXT\n");
397 + /* first get the flags */
398 + ret = sm_drv_oid_get(dev, DOT11_OID_AUTHENABLE,
399 + (void *)&authen, sizeof(uint32_t));
400 + ret |= sm_drv_oid_get(dev, DOT11_OID_PRIVACYINVOKED,
401 + (void *)&invoke, sizeof(uint32_t));
402 + ret |= sm_drv_oid_get(dev, DOT11_OID_EXUNENCRYPTED,
403 + (void *)&exunencrypt, sizeof(uint32_t));
407 + max_key_len = encoding->length - sizeof(*ext);
408 + if (max_key_len < 0)
411 + idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
413 + if (idx < 0 || idx > 3)
416 + ret = sm_drv_oid_get(dev, DOT11_OID_DEFKEYID,
417 + (void *)&idx, sizeof(uint32_t));
422 + encoding->flags = idx + 1;
423 + memset(ext, 0, sizeof(*ext));
426 + case DOT11_AUTH_BOTH:
427 + case DOT11_AUTH_SK:
428 + wrqu->encoding.flags |= IW_ENCODE_RESTRICTED;
429 + case DOT11_AUTH_OS:
431 + wrqu->encoding.flags |= IW_ENCODE_OPEN;
435 + down(&priv->wpa_sem);
437 + up(&priv->wpa_sem);
439 + if (authen == DOT11_AUTH_OS && !exunencrypt && !invoke && !wpa) {
440 + /* No encryption */
441 + ext->alg = IW_ENCODE_ALG_NONE;
443 + wrqu->encoding.flags |= IW_ENCODE_DISABLED;
445 + struct obj_key *key;
447 + ret = sm_drv_oid_get(dev, DOT11_OID_DEFKEYID + idx + 1,
448 + (void *)&key, sizeof(struct obj_key));
451 + if (max_key_len < key->length) {
455 + memcpy(ext->key, key->key, key->length);
456 + ext->key_len = key->length;
458 + switch (key->type) {
459 + case DOT11_PRIV_TKIP:
460 + ext->alg = IW_ENCODE_ALG_TKIP;
462 + case DOT11_PRIV_AES_CCMP:
463 + ext->alg = IW_ENCODE_ALG_CCMP;
466 + case DOT11_PRIV_WEP:
467 + ext->alg = IW_ENCODE_ALG_WEP;
470 + wrqu->encoding.flags |= IW_ENCODE_ENABLED;
477 /* Private handlers */
479 @@ -2473,10 +2899,10 @@
480 (iw_handler) NULL, /* -- hole -- */
481 (iw_handler) sm_drv_set_genie, /* SIOCSIWGENIE*/
482 (iw_handler) NULL, /* SIOCGIWGENIE */
483 - (iw_handler) NULL, /* SIOCSIWAUTH */
484 - (iw_handler) NULL, /* SIOCGIWAUTH */
485 - (iw_handler) NULL, /* SIOCSIWENCODEEXT */
486 - (iw_handler) NULL, /* SIOCGIWENCODEEXT */
487 + (iw_handler) sm_drv_set_auth, /* SIOCSIWAUTH */
488 + (iw_handler) sm_drv_get_auth, /* SIOCGIWAUTH */
489 + (iw_handler) sm_drv_set_encodeext, /* SIOCSIWENCODEEXT */
490 + (iw_handler) sm_drv_get_encodeext, /* SIOCGIWENCODEEXT */
491 (iw_handler) sm_drv_set_pmk, /* SIOCSIWPMKSA */