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(const char *ifname
, void *priv
,
192 enum wpa_alg alg
, const u8
*addr
,
193 int key_idx
, int set_tx
,
194 const u8
*seq
, size_t seq_len
,
195 const u8
*key
, size_t key_len
)
197 struct wpa_driver_atmel_data
*drv
= priv
;
199 struct atmel_param
*param
;
227 wpa_printf(MSG_DEBUG
, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu "
228 "key_len=%lu", __FUNCTION__
, alg_name
, key_idx
, set_tx
,
229 (unsigned long) seq_len
, (unsigned long) key_len
);
234 blen
= sizeof(*param
) + key_len
;
235 buf
= os_zalloc(blen
);
239 param
= (struct atmel_param
*) buf
;
241 param
->cmd
= SET_WPA_ENCRYPTION
;
244 os_memset(param
->sta_addr
, 0xff, ETH_ALEN
);
246 os_memcpy(param
->sta_addr
, addr
, ETH_ALEN
);
248 param
->alg
= alg_type
;
249 param
->key_idx
= key_idx
;
250 param
->set_tx
= set_tx
;
251 os_memcpy(param
->seq
, seq
, seq_len
);
252 param
->seq_len
= seq_len
;
253 param
->key_len
= key_len
;
254 os_memcpy((u8
*)param
->key
, key
, key_len
);
256 if (atmel_ioctl(drv
, param
, blen
, 1)) {
257 wpa_printf(MSG_WARNING
, "Failed to set encryption.");
258 /* TODO: show key error*/
267 static int wpa_driver_atmel_set_countermeasures(void *priv
,
271 printf("wpa_driver_atmel_set_countermeasures - not yet "
277 static int wpa_driver_atmel_mlme(void *priv
, const u8
*addr
, int cmd
,
280 struct wpa_driver_atmel_data
*drv
= priv
;
281 struct atmel_param param
;
283 int mgmt_error
= 0xaa;
285 os_memset(¶m
, 0, sizeof(param
));
286 os_memcpy(param
.sta_addr
, addr
, ETH_ALEN
);
288 param
.mlme
.reason_code
= reason_code
;
289 param
.mlme
.state
= mgmt_error
;
290 ret
= atmel_ioctl(drv
, ¶m
, sizeof(param
), 1);
296 static int wpa_driver_atmel_set_suites(struct wpa_driver_atmel_data
*drv
,
297 u8 pairwise_suite
, u8 group_suite
,
300 struct atmel_param param
;
303 os_memset(¶m
, 0, sizeof(param
));
304 param
.cmd
= SET_CIPHER_SUITES
;
305 param
.pairwise_suite
= pairwise_suite
;
306 param
.group_suite
= group_suite
;
307 param
.key_mgmt_suite
= key_mgmt_suite
;
309 ret
= atmel_ioctl(drv
, ¶m
, sizeof(param
), 1);
315 static int wpa_driver_atmel_deauthenticate(void *priv
, const u8
*addr
,
318 struct wpa_driver_atmel_data
*drv
= priv
;
319 printf("wpa_driver_atmel_deauthenticate\n");
320 wpa_printf(MSG_DEBUG
, "%s", __FUNCTION__
);
321 return wpa_driver_atmel_mlme(drv
, addr
, MLME_STA_DEAUTH
,
327 static int wpa_driver_atmel_disassociate(void *priv
, const u8
*addr
,
330 struct wpa_driver_atmel_data
*drv
= priv
;
331 printf("wpa_driver_atmel_disassociate\n");
332 wpa_printf(MSG_DEBUG
, "%s", __FUNCTION__
);
333 return wpa_driver_atmel_mlme(drv
, addr
, MLME_STA_DISASSOC
,
340 /* Atmel driver uses specific values for each cipher suite */
341 static int convertSuiteToDriver(enum wpa_cipher suite
)
371 wpa_driver_atmel_associate(void *priv
,
372 struct wpa_driver_associate_params
*params
)
374 struct wpa_driver_atmel_data
*drv
= priv
;
377 u8 pairwise_suite_driver
;
378 u8 group_suite_driver
;
379 u8 key_mgmt_suite_driver
;
381 pairwise_suite_driver
= convertSuiteToDriver(params
->pairwise_suite
);
382 group_suite_driver
= convertSuiteToDriver(params
->group_suite
);
383 key_mgmt_suite_driver
= convertSuiteToDriver(params
->key_mgmt_suite
);
385 if (wpa_driver_atmel_set_suites(drv
, pairwise_suite_driver
,
387 key_mgmt_suite_driver
) < 0){
388 printf("wpa_driver_atmel_set_suites.\n");
391 if (wpa_driver_wext_set_freq(drv
->wext
, params
->freq
) < 0) {
392 printf("wpa_driver_atmel_set_freq.\n");
396 if (wpa_driver_wext_set_ssid(drv
->wext
, params
->ssid
, params
->ssid_len
)
398 printf("FAILED : wpa_driver_atmel_set_ssid.\n");
401 if (wpa_driver_wext_set_bssid(drv
->wext
, params
->bssid
) < 0) {
402 printf("FAILED : wpa_driver_atmel_set_bssid.\n");
410 static int wpa_driver_atmel_get_bssid(void *priv
, u8
*bssid
)
412 struct wpa_driver_atmel_data
*drv
= priv
;
413 return wpa_driver_wext_get_bssid(drv
->wext
, bssid
);
417 static int wpa_driver_atmel_get_ssid(void *priv
, u8
*ssid
)
419 struct wpa_driver_atmel_data
*drv
= priv
;
420 return wpa_driver_wext_get_ssid(drv
->wext
, ssid
);
424 static int wpa_driver_atmel_scan(void *priv
,
425 struct wpa_driver_scan_params
*params
)
427 struct wpa_driver_atmel_data
*drv
= priv
;
428 return wpa_driver_wext_scan(drv
->wext
, params
);
432 static struct wpa_scan_results
* wpa_driver_atmel_get_scan_results(void *priv
)
434 struct wpa_driver_atmel_data
*drv
= priv
;
435 return wpa_driver_wext_get_scan_results(drv
->wext
);
439 static int wpa_driver_atmel_set_operstate(void *priv
, int state
)
441 struct wpa_driver_atmel_data
*drv
= priv
;
442 return wpa_driver_wext_set_operstate(drv
->wext
, state
);
446 static void * wpa_driver_atmel_init(void *ctx
, const char *ifname
)
448 struct wpa_driver_atmel_data
*drv
;
450 drv
= os_zalloc(sizeof(*drv
));
453 drv
->wext
= wpa_driver_wext_init(ctx
, ifname
);
454 if (drv
->wext
== NULL
) {
460 os_strlcpy(drv
->ifname
, ifname
, sizeof(drv
->ifname
));
461 drv
->sock
= socket(PF_INET
, SOCK_DGRAM
, 0);
463 wpa_driver_wext_deinit(drv
->wext
);
468 wpa_driver_atmel_set_wpa(drv
, 1);
474 static void wpa_driver_atmel_deinit(void *priv
)
476 struct wpa_driver_atmel_data
*drv
= priv
;
477 wpa_driver_atmel_set_wpa(drv
, 0);
478 wpa_driver_wext_deinit(drv
->wext
);
484 const struct wpa_driver_ops wpa_driver_atmel_ops
= {
486 .desc
= "ATMEL AT76C5XXx (USB, PCMCIA)",
487 .get_bssid
= wpa_driver_atmel_get_bssid
,
488 .get_ssid
= wpa_driver_atmel_get_ssid
,
489 .set_key
= wpa_driver_atmel_set_key
,
490 .init
= wpa_driver_atmel_init
,
491 .deinit
= wpa_driver_atmel_deinit
,
492 .set_countermeasures
= wpa_driver_atmel_set_countermeasures
,
493 .scan2
= wpa_driver_atmel_scan
,
494 .get_scan_results2
= wpa_driver_atmel_get_scan_results
,
495 .deauthenticate
= wpa_driver_atmel_deauthenticate
,
496 .disassociate
= wpa_driver_atmel_disassociate
,
497 .associate
= wpa_driver_atmel_associate
,
498 .set_operstate
= wpa_driver_atmel_set_operstate
,