2 * WPA Supplicant - Driver interaction with Atmel Wireless LAN drivers
3 * Copyright (c) 2000-2005, ATMEL Corporation
4 * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * Alternatively, this software may be distributed under the terms of BSD
13 * See README and COPYING for more details.
16 /******************************************************************************
17 Copyright 2000-2001 ATMEL Corporation.
19 WPA Supplicant - driver interaction with Atmel Wireless lan drivers.
21 This is free software; you can redistribute it and/or modify
22 it under the terms of the GNU General Public License as published by
23 the Free Software Foundation; either version 2 of the License, or
24 (at your option) any later version.
26 This program is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 GNU General Public License for more details.
31 You should have received a copy of the GNU General Public License
32 along with Atmel wireless lan drivers; if not, write to the Free Software
33 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
35 ******************************************************************************/
38 * Alternatively, this software may be distributed under the terms of BSD
43 #include <sys/ioctl.h>
45 #include "wireless_copy.h"
48 #include "driver_wext.h"
50 struct wpa_driver_atmel_data
{
51 void *wext
; /* private data for driver_wext */
53 char ifname
[IFNAMSIZ
+ 1];
58 #define ATMEL_WPA_IOCTL (SIOCIWFIRSTPRIV + 2)
59 #define ATMEL_WPA_IOCTL_PARAM (SIOCIWFIRSTPRIV + 3)
60 #define ATMEL_WPA_IOCTL_GET_PARAM (SIOCIWFIRSTPRIV + 4)
63 /* ATMEL_WPA_IOCTL ioctl() cmd: */
65 SET_WPA_ENCRYPTION
= 1,
66 SET_CIPHER_SUITES
= 2,
71 /* ATMEL_WPA_IOCTL_PARAM ioctl() cmd: */
74 ATMEL_PARAM_PRIVACY_INVOKED
= 2,
75 ATMEL_PARAM_WPA_TYPE
= 3
78 #define MAX_KEY_LENGTH 40
81 unsigned char sta_addr
[6];
89 u8 key
[MAX_KEY_LENGTH
];
101 static int atmel_ioctl(struct wpa_driver_atmel_data
*drv
,
102 struct atmel_param
*param
,
103 int len
, int show_err
)
107 os_memset(&iwr
, 0, sizeof(iwr
));
108 os_strlcpy(iwr
.ifr_name
, drv
->ifname
, IFNAMSIZ
);
109 iwr
.u
.data
.pointer
= (caddr_t
) param
;
110 iwr
.u
.data
.length
= len
;
112 if (ioctl(drv
->sock
, ATMEL_WPA_IOCTL
, &iwr
) < 0) {
116 perror("ioctl[ATMEL_WPA_IOCTL]");
124 static int atmel2param(struct wpa_driver_atmel_data
*drv
, int param
, int value
)
129 os_memset(&iwr
, 0, sizeof(iwr
));
130 os_strlcpy(iwr
.ifr_name
, drv
->ifname
, IFNAMSIZ
);
131 i
= (int *) iwr
.u
.name
;
135 if (ioctl(drv
->sock
, ATMEL_WPA_IOCTL_PARAM
, &iwr
) < 0) {
136 perror("ioctl[ATMEL_WPA_IOCTL_PARAM]");
144 static int wpa_driver_atmel_set_wpa_ie(struct wpa_driver_atmel_data
*drv
,
145 const char *wpa_ie
, size_t wpa_ie_len
)
147 struct atmel_param
*param
;
149 size_t blen
= ATMEL_GENERIC_ELEMENT_HDR_LEN
+ wpa_ie_len
;
150 if (blen
< sizeof(*param
))
151 blen
= sizeof(*param
);
153 param
= os_zalloc(blen
);
157 param
->cmd
= ATMEL_SET_GENERIC_ELEMENT
;
158 param
->u
.generic_elem
.len
= wpa_ie_len
;
159 os_memcpy(param
->u
.generic_elem
.data
, wpa_ie
, wpa_ie_len
);
160 res
= atmel_ioctl(drv
, param
, blen
, 1);
169 static int wpa_driver_atmel_set_wpa(void *priv
, int enabled
)
171 struct wpa_driver_atmel_data
*drv
= priv
;
174 printf("wpa_driver_atmel_set_wpa %s\n", drv
->ifname
);
176 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __FUNCTION__
, enabled
);
179 if (!enabled
&& wpa_driver_atmel_set_wpa_ie(drv
, NULL
, 0) < 0)
182 if (atmel2param(drv
, ATMEL_PARAM_PRIVACY_INVOKED
, enabled
) < 0)
184 if (atmel2param(drv
, ATMEL_PARAM_WPA
, enabled
) < 0)
191 static int wpa_driver_atmel_set_key(void *priv
, wpa_alg alg
,
192 const u8
*addr
, int key_idx
,
193 int set_tx
, const u8
*seq
, size_t seq_len
,
194 const u8
*key
, size_t key_len
)
196 struct wpa_driver_atmel_data
*drv
= priv
;
198 struct atmel_param
*param
;
226 wpa_printf(MSG_DEBUG
, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu "
227 "key_len=%lu", __FUNCTION__
, alg_name
, key_idx
, set_tx
,
228 (unsigned long) seq_len
, (unsigned long) key_len
);
233 blen
= sizeof(*param
) + key_len
;
234 buf
= os_zalloc(blen
);
238 param
= (struct atmel_param
*) buf
;
240 param
->cmd
= SET_WPA_ENCRYPTION
;
243 os_memset(param
->sta_addr
, 0xff, ETH_ALEN
);
245 os_memcpy(param
->sta_addr
, addr
, ETH_ALEN
);
247 param
->alg
= alg_type
;
248 param
->key_idx
= key_idx
;
249 param
->set_tx
= set_tx
;
250 os_memcpy(param
->seq
, seq
, seq_len
);
251 param
->seq_len
= seq_len
;
252 param
->key_len
= key_len
;
253 os_memcpy((u8
*)param
->key
, key
, key_len
);
255 if (atmel_ioctl(drv
, param
, blen
, 1)) {
256 wpa_printf(MSG_WARNING
, "Failed to set encryption.");
257 /* TODO: show key error*/
266 static int wpa_driver_atmel_set_countermeasures(void *priv
,
270 printf("wpa_driver_atmel_set_countermeasures - not yet "
276 static int wpa_driver_atmel_set_drop_unencrypted(void *priv
,
280 printf("wpa_driver_atmel_set_drop_unencrypted - not yet "
286 static int wpa_driver_atmel_mlme(void *priv
, const u8
*addr
, int cmd
,
289 struct wpa_driver_atmel_data
*drv
= priv
;
290 struct atmel_param param
;
292 int mgmt_error
= 0xaa;
294 os_memset(¶m
, 0, sizeof(param
));
295 os_memcpy(param
.sta_addr
, addr
, ETH_ALEN
);
297 param
.mlme
.reason_code
= reason_code
;
298 param
.mlme
.state
= mgmt_error
;
299 ret
= atmel_ioctl(drv
, ¶m
, sizeof(param
), 1);
305 static int wpa_driver_atmel_set_suites(struct wpa_driver_atmel_data
*drv
,
306 u8 pairwise_suite
, u8 group_suite
,
309 struct atmel_param param
;
312 os_memset(¶m
, 0, sizeof(param
));
313 param
.cmd
= SET_CIPHER_SUITES
;
314 param
.pairwise_suite
= pairwise_suite
;
315 param
.group_suite
= group_suite
;
316 param
.key_mgmt_suite
= key_mgmt_suite
;
318 ret
= atmel_ioctl(drv
, ¶m
, sizeof(param
), 1);
324 static int wpa_driver_atmel_deauthenticate(void *priv
, const u8
*addr
,
327 struct wpa_driver_atmel_data
*drv
= priv
;
328 printf("wpa_driver_atmel_deauthenticate\n");
329 wpa_printf(MSG_DEBUG
, "%s", __FUNCTION__
);
330 return wpa_driver_atmel_mlme(drv
, addr
, MLME_STA_DEAUTH
,
336 static int wpa_driver_atmel_disassociate(void *priv
, const u8
*addr
,
339 struct wpa_driver_atmel_data
*drv
= priv
;
340 printf("wpa_driver_atmel_disassociate\n");
341 wpa_printf(MSG_DEBUG
, "%s", __FUNCTION__
);
342 return wpa_driver_atmel_mlme(drv
, addr
, MLME_STA_DISASSOC
,
349 /* Atmel driver uses specific values for each cipher suite */
350 static int convertSuiteToDriver(wpa_cipher suite
)
380 wpa_driver_atmel_associate(void *priv
,
381 struct wpa_driver_associate_params
*params
)
383 struct wpa_driver_atmel_data
*drv
= priv
;
386 u8 pairwise_suite_driver
;
387 u8 group_suite_driver
;
388 u8 key_mgmt_suite_driver
;
390 pairwise_suite_driver
= convertSuiteToDriver(params
->pairwise_suite
);
391 group_suite_driver
= convertSuiteToDriver(params
->group_suite
);
392 key_mgmt_suite_driver
= convertSuiteToDriver(params
->key_mgmt_suite
);
394 if (wpa_driver_atmel_set_suites(drv
, pairwise_suite_driver
,
396 key_mgmt_suite_driver
) < 0){
397 printf("wpa_driver_atmel_set_suites.\n");
400 if (wpa_driver_wext_set_freq(drv
->wext
, params
->freq
) < 0) {
401 printf("wpa_driver_atmel_set_freq.\n");
405 if (wpa_driver_wext_set_ssid(drv
->wext
, params
->ssid
, params
->ssid_len
)
407 printf("FAILED : wpa_driver_atmel_set_ssid.\n");
410 if (wpa_driver_wext_set_bssid(drv
->wext
, params
->bssid
) < 0) {
411 printf("FAILED : wpa_driver_atmel_set_bssid.\n");
419 static int wpa_driver_atmel_get_bssid(void *priv
, u8
*bssid
)
421 struct wpa_driver_atmel_data
*drv
= priv
;
422 return wpa_driver_wext_get_bssid(drv
->wext
, bssid
);
426 static int wpa_driver_atmel_get_ssid(void *priv
, u8
*ssid
)
428 struct wpa_driver_atmel_data
*drv
= priv
;
429 return wpa_driver_wext_get_ssid(drv
->wext
, ssid
);
433 static int wpa_driver_atmel_scan(void *priv
, const u8
*ssid
, size_t ssid_len
)
435 struct wpa_driver_atmel_data
*drv
= priv
;
436 return wpa_driver_wext_scan(drv
->wext
, ssid
, ssid_len
);
440 static struct wpa_scan_results
* wpa_driver_atmel_get_scan_results(void *priv
)
442 struct wpa_driver_atmel_data
*drv
= priv
;
443 return wpa_driver_wext_get_scan_results(drv
->wext
);
447 static int wpa_driver_atmel_set_operstate(void *priv
, int state
)
449 struct wpa_driver_atmel_data
*drv
= priv
;
450 return wpa_driver_wext_set_operstate(drv
->wext
, state
);
454 static void * wpa_driver_atmel_init(void *ctx
, const char *ifname
)
456 struct wpa_driver_atmel_data
*drv
;
458 drv
= os_zalloc(sizeof(*drv
));
461 drv
->wext
= wpa_driver_wext_init(ctx
, ifname
);
462 if (drv
->wext
== NULL
) {
468 os_strlcpy(drv
->ifname
, ifname
, sizeof(drv
->ifname
));
469 drv
->sock
= socket(PF_INET
, SOCK_DGRAM
, 0);
471 wpa_driver_wext_deinit(drv
->wext
);
480 static void wpa_driver_atmel_deinit(void *priv
)
482 struct wpa_driver_atmel_data
*drv
= priv
;
483 wpa_driver_wext_deinit(drv
->wext
);
489 const struct wpa_driver_ops wpa_driver_atmel_ops
= {
491 .desc
= "ATMEL AT76C5XXx (USB, PCMCIA)",
492 .get_bssid
= wpa_driver_atmel_get_bssid
,
493 .get_ssid
= wpa_driver_atmel_get_ssid
,
494 .set_wpa
= wpa_driver_atmel_set_wpa
,
495 .set_key
= wpa_driver_atmel_set_key
,
496 .init
= wpa_driver_atmel_init
,
497 .deinit
= wpa_driver_atmel_deinit
,
498 .set_countermeasures
= wpa_driver_atmel_set_countermeasures
,
499 .set_drop_unencrypted
= wpa_driver_atmel_set_drop_unencrypted
,
500 .scan
= wpa_driver_atmel_scan
,
501 .get_scan_results2
= wpa_driver_atmel_get_scan_results
,
502 .deauthenticate
= wpa_driver_atmel_deauthenticate
,
503 .disassociate
= wpa_driver_atmel_disassociate
,
504 .associate
= wpa_driver_atmel_associate
,
505 .set_operstate
= wpa_driver_atmel_set_operstate
,