1 diff -rup src.orig/sm_drv_ioctl_umac.c src/sm_drv_ioctl_umac.c
2 --- src.orig/sm_drv_ioctl_umac.c 2009-02-16 23:51:34.000000000 +0100
3 +++ src/sm_drv_ioctl_umac.c 2009-02-23 00:19:10.000000000 +0100
4 @@ -1928,6 +1928,435 @@ static int sm_drv_set_pmk(struct net_dev
5 (void *)&key, sizeof(struct obj_stakey));
8 +static int sm_drv_set_auth(struct net_device *dev,
9 + struct iw_request_info *info,
10 + union iwreq_data *wrqu, char *extra)
12 + struct net_local *priv = netdev_priv(dev);
13 + struct iw_param *param = &wrqu->param;
14 + u32 authen = 0, dot1x = 0;
15 + u32 exunencrypt = 0, privinvoked = 0, wpa = 0;
19 + DEBUG(DBG_IOCTL, "SET AUTH\n");
21 + /* first get the flags */
22 + down(&priv->wpa_sem);
23 + wpa = old_wpa = priv->wpa;
25 + ret = sm_drv_oid_get(dev, DOT11_OID_AUTHENABLE,
26 + (void *)&authen, sizeof(uint32_t));
27 + ret |= sm_drv_oid_get(dev, DOT11_OID_PRIVACYINVOKED,
28 + (void *)&privinvoked, sizeof(uint32_t));
29 + ret |= sm_drv_oid_get(dev, DOT11_OID_EXUNENCRYPTED,
30 + (void *)&exunencrypt, sizeof(uint32_t));
31 + ret |= sm_drv_oid_get(dev, DOT11_OID_DOT1XENABLE,
32 + (void *)&dot1x, sizeof(uint32_t));
37 + switch (param->flags & IW_AUTH_INDEX) {
38 + case IW_AUTH_CIPHER_PAIRWISE:
39 + case IW_AUTH_CIPHER_GROUP:
40 + case IW_AUTH_KEY_MGMT:
43 + case IW_AUTH_WPA_ENABLED:
44 + /* Do the same thing as IW_AUTH_WPA_VERSION */
46 + wpa = DOT11_PRIV_INV_TKIP;
47 + privinvoked = 1; /* For privacy invoked */
48 + exunencrypt = 1; /* Filter out all unencrypted frames */
49 + dot1x = 0x01; /* To enable eap filter */
50 + authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
52 + wpa = DOT11_PRIV_INV_NONE;
54 + exunencrypt = 0; /* Do not filter un-encrypted data */
59 + case IW_AUTH_WPA_VERSION:
60 + if (param->value & IW_AUTH_WPA_VERSION_DISABLED) {
61 + wpa = DOT11_PRIV_INV_NONE;
63 + exunencrypt = 0; /* Do not filter un-encrypted data */
66 + if (param->value & IW_AUTH_WPA_VERSION_WPA)
67 + wpa = DOT11_PRIV_INV_TKIP;
68 + else if (param->value & IW_AUTH_WPA_VERSION_WPA2)
69 + wpa = DOT11_PRIV_INV_AES_CCMP;
70 + privinvoked = 1; /* For privacy invoked */
71 + exunencrypt = 1; /* Filter out all unencrypted frames */
72 + dot1x = 0x01; /* To enable eap filter */
73 + authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
77 + case IW_AUTH_RX_UNENCRYPTED_EAPOL:
78 + /* dot1x should be the opposite of RX_UNENCRYPTED_EAPOL;
79 + * turn off dot1x when allowing receipt of unencrypted EAPOL
80 + * frames, turn on dot1x when receipt should be disallowed
82 + dot1x = param->value ? 0 : 0x01;
85 + case IW_AUTH_PRIVACY_INVOKED:
86 + privinvoked = param->value ? 1 : 0;
89 + case IW_AUTH_DROP_UNENCRYPTED:
90 + exunencrypt = param->value ? 1 : 0;
93 + case IW_AUTH_80211_AUTH_ALG:
94 + if (param->value & IW_AUTH_ALG_SHARED_KEY) {
95 + /* Only WEP uses _SK and _BOTH */
100 + authen = DOT11_AUTH_SK;
101 + } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
102 + authen = DOT11_AUTH_OS;
110 + return -EOPNOTSUPP;
113 + /* Set all the values */
114 + down(&priv->wpa_sem);
116 + up(&priv->wpa_sem);
118 + sm_drv_oid_set(dev, DOT11_OID_AUTHENABLE,
119 + (void *)&authen, sizeof(uint32_t));
120 + sm_drv_oid_set(dev, DOT11_OID_PRIVACYINVOKED,
121 + (void *)&privinvoked, sizeof(uint32_t));
122 + sm_drv_oid_set(dev, DOT11_OID_EXUNENCRYPTED,
123 + (void *)&exunencrypt, sizeof(uint32_t));
124 + sm_drv_oid_set(dev, DOT11_OID_DOT1XENABLE,
125 + (void *)&dot1x, sizeof(uint32_t));
131 +static int sm_drv_get_auth(struct net_device *dev,
132 + struct iw_request_info *info,
133 + union iwreq_data *wrqu, char *extra)
135 + struct net_local *priv = netdev_priv(dev);
136 + struct iw_param *param = &wrqu->param;
137 + u32 authen = 0, dot1x = 0;
138 + u32 exunencrypt = 0, privinvoked = 0, wpa = 0;
141 + DEBUG(DBG_IOCTL, "GET AUTH\n");
143 + /* first get the flags */
144 + down(&priv->wpa_sem);
146 + up(&priv->wpa_sem);
148 + switch (param->flags & IW_AUTH_INDEX) {
149 + case IW_AUTH_CIPHER_PAIRWISE:
150 + case IW_AUTH_CIPHER_GROUP:
151 + case IW_AUTH_KEY_MGMT:
153 + * wpa_supplicant will control these internally
158 + case IW_AUTH_WPA_VERSION:
160 + case DOT11_PRIV_INV_TKIP:
161 + param->value = IW_AUTH_WPA_VERSION_WPA;
163 + case DOT11_PRIV_INV_AES_CCMP:
164 + param->value = IW_AUTH_WPA_VERSION_WPA2;
167 + param->value = IW_AUTH_WPA_VERSION_DISABLED;
172 + case IW_AUTH_DROP_UNENCRYPTED:
173 + ret = sm_drv_oid_get(dev, DOT11_OID_EXUNENCRYPTED,
174 + (void *)&exunencrypt, sizeof(uint32_t));
176 + param->value = exunencrypt > 0 ? 1 : 0;
179 + case IW_AUTH_80211_AUTH_ALG:
180 + ret = sm_drv_oid_get(dev, DOT11_OID_AUTHENABLE,
181 + (void *)&authen, sizeof(uint32_t));
184 + case DOT11_AUTH_OS:
185 + param->value = IW_AUTH_ALG_OPEN_SYSTEM;
187 + case DOT11_AUTH_BOTH:
188 + case DOT11_AUTH_SK:
189 + param->value = IW_AUTH_ALG_SHARED_KEY;
190 + case DOT11_AUTH_NONE:
198 + case IW_AUTH_WPA_ENABLED:
199 + param->value = wpa > 0 ? 1 : 0;
202 + case IW_AUTH_RX_UNENCRYPTED_EAPOL:
203 + ret = sm_drv_oid_get(dev, DOT11_OID_DOT1XENABLE,
204 + (void *)&dot1x, sizeof(uint32_t));
206 + param->value = dot1x > 0 ? 1 : 0;
209 + case IW_AUTH_PRIVACY_INVOKED:
210 + ret = sm_drv_oid_get(dev, DOT11_OID_PRIVACYINVOKED,
211 + (void *)&privinvoked, sizeof(uint32_t));
213 + param->value = privinvoked > 0 ? 1 : 0;
217 + return -EOPNOTSUPP;
222 +#define KEY_SIZE_WEP104 13 /* 104/128-bit WEP keys */
223 +#define KEY_SIZE_WEP40 5 /* 40/64-bit WEP keys */
224 +#define KEY_SIZE_TKIP 32 /* TKIP keys */
226 +static int sm_drv_set_encodeext(struct net_device *dev,
227 + struct iw_request_info *info,
228 + union iwreq_data *wrqu,
231 + struct iw_point *encoding = &wrqu->encoding;
232 + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
233 + int idx, alg = ext->alg, set_key = 1;
234 + int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
237 + DEBUG(DBG_IOCTL, "SET ENCODEEXT\n");
239 + /* Determine and validate the key index */
240 + idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
242 + if (idx < 0 || idx > 3)
245 + ret = sm_drv_oid_get(dev, DOT11_OID_DEFKEYID,
246 + (void *)&idx, sizeof(uint32_t));
251 + if (encoding->flags & IW_ENCODE_DISABLED)
252 + alg = IW_ENCODE_ALG_NONE;
254 + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
255 + /* Only set transmit key index here, actual
256 + * key is set below if needed.
258 + ret = sm_drv_oid_set(dev, DOT11_OID_DEFKEYID,
259 + (void *)&idx, sizeof(uint32_t));
260 + set_key = ext->key_len > 0 ? 1 : 0;
265 + case IW_ENCODE_ALG_NONE:
267 + case IW_ENCODE_ALG_WEP: {
268 + struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
269 + memset(key.key, 0, sizeof(key.key));
270 + if (ext->key_len > KEY_SIZE_WEP104) {
274 + if (ext->key_len > KEY_SIZE_WEP40)
275 + key.length = KEY_SIZE_WEP104;
277 + key.length = KEY_SIZE_WEP40;
278 + memcpy(key.key, ext->key, ext->key_len);
279 + ret = sm_drv_oid_set(dev, DOT11_OID_DEFKEYID + idx + 1,
281 + sizeof(struct obj_key));
284 + case IW_ENCODE_ALG_TKIP:
285 + case IW_ENCODE_ALG_CCMP: {
286 + struct obj_stakey key;
287 + memset(key.key, 0, sizeof(key.key));
288 + if (alg == IW_ENCODE_ALG_TKIP)
289 + key.type = DOT11_PRIV_TKIP;
291 + key.type = DOT11_PRIV_AES_CCMP;
292 + memcpy(key.address, ext->addr.sa_data, ETH_ALEN);
293 + key.length = ext->key_len;
296 + memcpy(key.key, ext->key, ext->key_len);
297 + ret = sm_drv_oid_set(dev, DOT11_OID_STAKEY,
299 + sizeof(struct obj_stakey));
311 + /* Read the flags */
312 + if (encoding->flags & IW_ENCODE_DISABLED) {
313 + /* Encoding disabled,
314 + * authen = DOT11_AUTH_OS;
316 + * exunencrypt = 0; */
318 + if (encoding->flags & IW_ENCODE_OPEN) {
319 + /* Encode but accept non-encoded packets. No auth */
322 + if (encoding->flags & IW_ENCODE_RESTRICTED) {
323 + /* Refuse non-encoded packets. Auth */
324 + authen = DOT11_AUTH_BOTH;
329 + /* do the change if requested */
330 + if (encoding->flags & IW_ENCODE_MODE) {
331 + sm_drv_oid_set(dev, DOT11_OID_AUTHENABLE,
332 + (void *)&authen, sizeof(uint32_t));
333 + sm_drv_oid_set(dev, DOT11_OID_PRIVACYINVOKED,
334 + (void *)&invoke, sizeof(uint32_t));
335 + sm_drv_oid_set(dev, DOT11_OID_EXUNENCRYPTED,
336 + (void *)&exunencrypt, sizeof(uint32_t));
344 +static int sm_drv_get_encodeext(struct net_device *dev,
345 + struct iw_request_info *info,
346 + union iwreq_data *wrqu,
349 + struct net_local *priv = netdev_priv(dev);
350 + struct iw_point *encoding = &wrqu->encoding;
351 + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
352 + int idx, max_key_len;
353 + int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0, wpa = 0;
356 + DEBUG(DBG_IOCTL, "GET ENCODEEXT\n");
358 + /* first get the flags */
359 + ret = sm_drv_oid_get(dev, DOT11_OID_AUTHENABLE,
360 + (void *)&authen, sizeof(uint32_t));
361 + ret |= sm_drv_oid_get(dev, DOT11_OID_PRIVACYINVOKED,
362 + (void *)&invoke, sizeof(uint32_t));
363 + ret |= sm_drv_oid_get(dev, DOT11_OID_EXUNENCRYPTED,
364 + (void *)&exunencrypt, sizeof(uint32_t));
368 + max_key_len = encoding->length - sizeof(*ext);
369 + if (max_key_len < 0)
372 + idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
374 + if (idx < 0 || idx > 3)
377 + ret = sm_drv_oid_get(dev, DOT11_OID_DEFKEYID,
378 + (void *)&idx, sizeof(uint32_t));
383 + encoding->flags = idx + 1;
384 + memset(ext, 0, sizeof(*ext));
387 + case DOT11_AUTH_BOTH:
388 + case DOT11_AUTH_SK:
389 + wrqu->encoding.flags |= IW_ENCODE_RESTRICTED;
390 + case DOT11_AUTH_OS:
392 + wrqu->encoding.flags |= IW_ENCODE_OPEN;
396 + down(&priv->wpa_sem);
398 + up(&priv->wpa_sem);
400 + if (authen == DOT11_AUTH_OS && !exunencrypt && !invoke && !wpa) {
401 + /* No encryption */
402 + ext->alg = IW_ENCODE_ALG_NONE;
404 + wrqu->encoding.flags |= IW_ENCODE_DISABLED;
406 + struct obj_key *key;
408 + ret = sm_drv_oid_get(dev, DOT11_OID_DEFKEYID + idx + 1,
409 + (void *)&key, sizeof(struct obj_key));
412 + if (max_key_len < key->length) {
416 + memcpy(ext->key, key->key, key->length);
417 + ext->key_len = key->length;
419 + switch (key->type) {
420 + case DOT11_PRIV_TKIP:
421 + ext->alg = IW_ENCODE_ALG_TKIP;
423 + case DOT11_PRIV_AES_CCMP:
424 + ext->alg = IW_ENCODE_ALG_CCMP;
427 + case DOT11_PRIV_WEP:
428 + ext->alg = IW_ENCODE_ALG_WEP;
431 + wrqu->encoding.flags |= IW_ENCODE_ENABLED;
438 /* Private handlers */
440 @@ -2473,10 +2902,10 @@ const iw_handler sm_drv_we_handler[] = {
441 (iw_handler) NULL, /* -- hole -- */
442 (iw_handler) sm_drv_set_genie, /* SIOCSIWGENIE*/
443 (iw_handler) NULL, /* SIOCGIWGENIE */
444 - (iw_handler) NULL, /* SIOCSIWAUTH */
445 - (iw_handler) NULL, /* SIOCGIWAUTH */
446 - (iw_handler) NULL, /* SIOCSIWENCODEEXT */
447 - (iw_handler) NULL, /* SIOCGIWENCODEEXT */
448 + (iw_handler) sm_drv_set_auth, /* SIOCSIWAUTH */
449 + (iw_handler) sm_drv_get_auth, /* SIOCGIWAUTH */
450 + (iw_handler) sm_drv_set_encodeext, /* SIOCSIWENCODEEXT */
451 + (iw_handler) sm_drv_get_encodeext, /* SIOCGIWENCODEEXT */
452 (iw_handler) sm_drv_set_pmk, /* SIOCSIWPMKSA */