Merge branch 'org.openembedded.dev' of git://git.openembedded.net/openembedded into...
[vuplus_openembedded] / packages / mamona / cx3110x-chinooke-2.0.15 / cx3110x.patch
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
4 @@ -88,8 +88,8 @@
5         kfree(wrqu.data.pointer);
6  }
7  
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)
12  {
13         union iwreq_data wrqu;
14         uint32_t we_event;
15 @@ -111,15 +111,12 @@
16                 return;
17         }
18  
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)
22                 return;
23  
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);
27 -       
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;
31  
32         wireless_send_event(dev, we_event, &wrqu, wrqu.data.pointer);
33         kfree(wrqu.data.pointer);
34 @@ -478,7 +475,7 @@
35         if ((lp->link_state == DOT11_STATE_ASSOCING
36              || lp->link_state == DOT11_STATE_ASSOC)  
37             && event)
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);
40                         
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));
45  }
46  
47 +static int sm_drv_set_auth(struct net_device *dev,
48 +                          struct iw_request_info *info,
49 +                          union iwreq_data *wrqu, char *extra)
50 +{
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;
55 +       u32 old_wpa;
56 +       int ret = 0;
57 +
58 +       DEBUG(DBG_IOCTL, "SET AUTH\n");
59 +
60 +       /* first get the flags */
61 +       down(&priv->wpa_sem);
62 +       wpa = old_wpa = priv->wpa;
63 +       up(&priv->wpa_sem);
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));
72 +
73 +       if (ret < 0)
74 +               goto out;
75 +
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:
80 +               break;
81 +
82 +       case IW_AUTH_WPA_ENABLED:
83 +               /* Do the same thing as IW_AUTH_WPA_VERSION */
84 +               if (param->value) {
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 */
90 +               } else {
91 +                       wpa = DOT11_PRIV_INV_NONE;
92 +                       privinvoked = 0;
93 +                       exunencrypt = 0; /* Do not filter un-encrypted data */
94 +                       dot1x = 0;
95 +               }
96 +               break;
97 +
98 +       case IW_AUTH_WPA_VERSION:
99 +               if (param->value & IW_AUTH_WPA_VERSION_DISABLED) {
100 +                       wpa = DOT11_PRIV_INV_NONE;
101 +                       privinvoked = 0;
102 +                       exunencrypt = 0; /* Do not filter un-encrypted data */
103 +                       dot1x = 0;
104 +               } else {
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 */
113 +               }
114 +               break;
115 +
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
120 +                */
121 +               dot1x = param->value ? 0 : 0x01;
122 +               break;
123 +
124 +       case IW_AUTH_PRIVACY_INVOKED:
125 +               privinvoked = param->value ? 1 : 0;
126 +               break;
127 +
128 +       case IW_AUTH_DROP_UNENCRYPTED:
129 +               exunencrypt = param->value ? 1 : 0;
130 +               break;
131 +
132 +       case IW_AUTH_80211_AUTH_ALG:
133 +               if (param->value & IW_AUTH_ALG_SHARED_KEY) {
134 +                       /* Only WEP uses _SK and _BOTH */
135 +                       if (wpa > 0) {
136 +                               ret = -EINVAL;
137 +                               goto out;
138 +                       }
139 +                       authen = DOT11_AUTH_SK;
140 +               } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
141 +                       authen = DOT11_AUTH_OS;
142 +               } else {
143 +                       ret = -EINVAL;
144 +                       goto out;
145 +               }
146 +               break;
147 +
148 +       default:
149 +               return -EOPNOTSUPP;
150 +       }
151 +
152 +       /* Set all the values */
153 +       down(&priv->wpa_sem);
154 +       priv->wpa = wpa;
155 +       up(&priv->wpa_sem);
156 +
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));
165 +
166 + out:
167 +       return ret;
168 +}
169 +
170 +static int sm_drv_get_auth(struct net_device *dev,
171 +                          struct iw_request_info *info,
172 +                          union iwreq_data *wrqu, char *extra)
173 +{
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;
178 +       int ret = 0;
179 +
180 +       DEBUG(DBG_IOCTL, "GET AUTH\n");
181 +
182 +       /* first get the flags */
183 +       down(&priv->wpa_sem);
184 +       wpa = priv->wpa;
185 +       up(&priv->wpa_sem);
186 +
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:
191 +               /*
192 +                * wpa_supplicant will control these internally
193 +                */
194 +               ret = -EOPNOTSUPP;
195 +               break;
196 +
197 +       case IW_AUTH_WPA_VERSION:
198 +               switch (wpa) {
199 +               case DOT11_PRIV_INV_TKIP:
200 +                       param->value = IW_AUTH_WPA_VERSION_WPA;
201 +                       break;
202 +               case DOT11_PRIV_INV_AES_CCMP:
203 +                       param->value = IW_AUTH_WPA_VERSION_WPA2;
204 +                       break;
205 +               default:
206 +                       param->value = IW_AUTH_WPA_VERSION_DISABLED;
207 +                       break;
208 +               }
209 +               break;
210 +
211 +       case IW_AUTH_DROP_UNENCRYPTED:
212 +               ret = sm_drv_oid_get(dev, DOT11_OID_EXUNENCRYPTED,
213 +                                    (void *)&exunencrypt, sizeof(uint32_t));
214 +               if (ret >= 0)
215 +                       param->value = exunencrypt > 0 ? 1 : 0;
216 +               break;
217 +
218 +       case IW_AUTH_80211_AUTH_ALG:
219 +               ret = sm_drv_oid_get(dev, DOT11_OID_AUTHENABLE,
220 +                                    (void *)&authen, sizeof(uint32_t));
221 +               if (ret >= 0) {
222 +                       switch (authen) {
223 +                       case DOT11_AUTH_OS:
224 +                               param->value = IW_AUTH_ALG_OPEN_SYSTEM;
225 +                               break;
226 +                       case DOT11_AUTH_BOTH:
227 +                       case DOT11_AUTH_SK:
228 +                               param->value = IW_AUTH_ALG_SHARED_KEY;
229 +                       case DOT11_AUTH_NONE:
230 +                       default:
231 +                               param->value = 0;
232 +                               break;
233 +                       }
234 +               }
235 +               break;
236 +
237 +       case IW_AUTH_WPA_ENABLED:
238 +               param->value = wpa > 0 ? 1 : 0;
239 +               break;
240 +
241 +       case IW_AUTH_RX_UNENCRYPTED_EAPOL:
242 +               ret = sm_drv_oid_get(dev, DOT11_OID_DOT1XENABLE,
243 +                                    (void *)&dot1x, sizeof(uint32_t));
244 +               if (ret >= 0)
245 +                       param->value = dot1x > 0 ? 1 : 0;
246 +               break;
247 +
248 +       case IW_AUTH_PRIVACY_INVOKED:
249 +               ret = sm_drv_oid_get(dev, DOT11_OID_PRIVACYINVOKED,
250 +                                    (void *)&privinvoked, sizeof(uint32_t));
251 +               if (ret >= 0)
252 +                       param->value = privinvoked > 0 ? 1 : 0;
253 +               break;
254 +
255 +       default:
256 +               return -EOPNOTSUPP;
257 +       }
258 +       return ret;
259 +}
260 +
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 */
264 +
265 +static int sm_drv_set_encodeext(struct net_device *dev,
266 +                               struct iw_request_info *info,
267 +                               union iwreq_data *wrqu,
268 +                               char *extra)
269 +{
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;
274 +       int ret = 0;
275 +
276 +       DEBUG(DBG_IOCTL, "SET ENCODEEXT\n");
277 +
278 +       /* Determine and validate the key index */
279 +       idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
280 +       if (idx) {
281 +               if (idx < 0 || idx > 3)
282 +                       return -EINVAL;
283 +       } else {
284 +               ret = sm_drv_oid_get(dev, DOT11_OID_DEFKEYID,
285 +                                    (void *)&idx, sizeof(uint32_t));
286 +               if (ret < 0)
287 +                       goto out;
288 +       }
289 +
290 +       if (encoding->flags & IW_ENCODE_DISABLED)
291 +               alg = IW_ENCODE_ALG_NONE;
292 +
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.
296 +                */
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;
300 +       }
301 +
302 +       if (set_key) {
303 +               switch (alg) {
304 +               case IW_ENCODE_ALG_NONE:
305 +                       break;
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) {
310 +                               ret = -EINVAL;
311 +                               goto out;
312 +                       }
313 +                       if (ext->key_len > KEY_SIZE_WEP40)
314 +                               key.length = KEY_SIZE_WEP104;
315 +                       else
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,
319 +                                            (void *)&key,
320 +                                            sizeof(struct obj_key));
321 +                       break;
322 +               }
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;
329 +                       else
330 +                               key.type = DOT11_PRIV_AES_CCMP;
331 +                       memcpy(key.address, ext->addr.sa_data, ETH_ALEN);
332 +                       key.length = ext->key_len;
333 +                       key.keyid = idx;
334 +                       key.ext = 0;
335 +                       memcpy(key.key, ext->key, ext->key_len);
336 +                       ret = sm_drv_oid_set(dev, DOT11_OID_STAKEY,
337 +                                            (void *)&key,
338 +                                            sizeof(struct obj_stakey));
339 +                       break;
340 +               }
341 +               default:
342 +                       return -EINVAL;
343 +               }
344 +
345 +               if (ret < 0)
346 +                       goto out;
347 +
348 +       }
349 +
350 +       /* Read the flags */
351 +       if (encoding->flags & IW_ENCODE_DISABLED) {
352 +               /* Encoding disabled,
353 +                * authen = DOT11_AUTH_OS;
354 +                * invoke = 0;
355 +                * exunencrypt = 0; */
356 +       }
357 +       if (encoding->flags & IW_ENCODE_OPEN) {
358 +               /* Encode but accept non-encoded packets. No auth */
359 +               invoke = 1;
360 +       }
361 +       if (encoding->flags & IW_ENCODE_RESTRICTED) {
362 +               /* Refuse non-encoded packets. Auth */
363 +               authen = DOT11_AUTH_BOTH;
364 +               invoke = 1;
365 +               exunencrypt = 1;
366 +       }
367 +
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));
376 +       }
377 +
378 + out:
379 +       return ret;
380 +}
381 +
382 +
383 +static int sm_drv_get_encodeext(struct net_device *dev,
384 +                               struct iw_request_info *info,
385 +                               union iwreq_data *wrqu,
386 +                               char *extra)
387 +{
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;
393 +       int ret = 0;
394 +
395 +       DEBUG(DBG_IOCTL, "GET ENCODEEXT\n");
396 +
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));
404 +       if (ret < 0)
405 +               goto out;
406 +
407 +       max_key_len = encoding->length - sizeof(*ext);
408 +       if (max_key_len < 0)
409 +               return -EINVAL;
410 +
411 +       idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
412 +       if (idx) {
413 +               if (idx < 0 || idx > 3)
414 +                       return -EINVAL;
415 +       } else {
416 +               ret = sm_drv_oid_get(dev, DOT11_OID_DEFKEYID,
417 +                                    (void *)&idx, sizeof(uint32_t));
418 +               if (ret < 0)
419 +                       goto out;
420 +       }
421 +
422 +       encoding->flags = idx + 1;
423 +       memset(ext, 0, sizeof(*ext));
424 +
425 +       switch (authen) {
426 +       case DOT11_AUTH_BOTH:
427 +       case DOT11_AUTH_SK:
428 +               wrqu->encoding.flags |= IW_ENCODE_RESTRICTED;
429 +       case DOT11_AUTH_OS:
430 +       default:
431 +               wrqu->encoding.flags |= IW_ENCODE_OPEN;
432 +               break;
433 +       }
434 +
435 +       down(&priv->wpa_sem);
436 +       wpa = priv->wpa;
437 +       up(&priv->wpa_sem);
438 +
439 +       if (authen == DOT11_AUTH_OS && !exunencrypt && !invoke && !wpa) {
440 +               /* No encryption */
441 +               ext->alg = IW_ENCODE_ALG_NONE;
442 +               ext->key_len = 0;
443 +               wrqu->encoding.flags |= IW_ENCODE_DISABLED;
444 +       } else {
445 +               struct obj_key *key;
446 +
447 +               ret = sm_drv_oid_get(dev, DOT11_OID_DEFKEYID + idx + 1,
448 +                                    (void *)&key, sizeof(struct obj_key));
449 +               if (ret < 0)
450 +                       goto out;
451 +               if (max_key_len < key->length) {
452 +                       ret = -E2BIG;
453 +                       goto out;
454 +               }
455 +               memcpy(ext->key, key->key, key->length);
456 +               ext->key_len = key->length;
457 +
458 +               switch (key->type) {
459 +               case DOT11_PRIV_TKIP:
460 +                       ext->alg = IW_ENCODE_ALG_TKIP;
461 +                       break;
462 +               case DOT11_PRIV_AES_CCMP:
463 +                       ext->alg = IW_ENCODE_ALG_CCMP;
464 +                       break;
465 +               default:
466 +               case DOT11_PRIV_WEP:
467 +                       ext->alg = IW_ENCODE_ALG_WEP;
468 +                       break;
469 +               }
470 +               wrqu->encoding.flags |= IW_ENCODE_ENABLED;
471 +       }
472 +
473 + out:
474 +       return ret;
475 +}
476  
477  /* Private handlers */
478  
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 */
492  };