22 #include <linux/capability.h>
23 #include <linux/module.h>
24 #include <linux/kernel.h>
25 #include <linux/if_arp.h>
26 #include <linux/slab.h>
27 #include <linux/pci.h>
29 #include <asm/uaccess.h>
39 #define KEY_SIZE_WEP104 13
40 #define KEY_SIZE_WEP40 5
42 #define KEY_SIZE_TKIP 32
45 u8 *wpa_ie,
size_t wpa_ie_len);
51 static const unsigned char scan_rate_list[] = { 2, 4, 11, 22,
75 "%s(): Sorry, Repeater mode and Secondary mode "
76 "are not yet supported by this driver.\n", __func__);
155 prism54_mib_mode_helper(priv, mode);
243 char *cwrq,
char *
extra)
259 char *cwrq,
char *extra)
274 capabilities =
"IEEE 802.11a/b/g";
277 capabilities =
"IEEE 802.11b/g - FAA Support";
281 capabilities =
"IEEE 802.11b/g";
290 struct iw_freq *fwrq,
char *extra)
310 struct iw_freq *fwrq,
char *extra)
327 __u32 * uwrq,
char *extra)
335 "%s: %s() You passed a non-valid init_mode.\n",
336 priv->
ndev->name, __func__);
342 if (prism54_mib_mode_helper(priv, *uwrq)) {
371 __u32 * uwrq,
char *extra)
496 for (i = 0; i <
m; i++) {
498 range->
freq[
i].e = 6;
575 char *current_ev,
char *end_buf,
struct obj_bss *bss,
588 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
594 iwe.u.data.length = bss->
ssid.length;
595 iwe.u.data.flags = 1;
597 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
598 &iwe, bss->
ssid.octets);
602 #define CAP_IBSS 0x02
603 #define CAP_CRYPT 0x10
610 else if (cap & CAP_IBSS)
614 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
622 iwe.u.data.length = 0;
624 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
631 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
635 iwe.u.qual.level = bss->
rssi;
636 iwe.u.qual.noise = noise;
638 iwe.u.qual.qual = bss->
rssi - noise;
640 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
644 wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->
address, wpa_ie);
645 if (wpa_ie_len > 0) {
648 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
653 char *current_val = current_ev + iwe_stream_lcp_len(info);
659 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
663 for(i = 0; i <
sizeof(scan_rate_list); i++) {
664 if(bss->
rates & mask) {
665 iwe.u.bitrate.value = (scan_rate_list[
i] * 500000);
666 current_val = iwe_stream_add_value(
667 info, current_ev, current_val,
673 if ((current_val - current_ev) > iwe_stream_lcp_len(info))
674 current_ev = current_val;
688 char *current_ev =
extra;
713 for (i = 0; i < (
int) bsslist->
nr; i++) {
714 current_ev = prism54_translate_bss(ndev, info, current_ev,
741 memset(essid.octets, 0, 33);
747 essid.length = dwrq->
length;
838 if (vwrq->
value == -1) {
850 rate = (
u32) (vwrq->
value / 500000);
855 if (rate && (data[i] == rate)) {
858 if (vwrq->
value == i) {
912 vwrq->
value =
r.u * 500000;
921 vwrq->
fixed = (data[0] != 0) && (data[1] == 0);
996 slimit = vwrq->
value;
1001 slimit = vwrq->
value;
1007 lifetime = vwrq->
value / 1024;
1025 struct iw_param *vwrq,
char *extra)
1036 vwrq->
value =
r.u * 1024;
1057 struct iw_point *dwrq,
char *extra)
1060 int rvalue = 0,
force = 0;
1076 current_index =
r.u;
1097 if ((index < 0) || (index > 3))
1099 index = current_index;
1111 if ((index == current_index) && (key.
length > 0))
1115 if ((index >= 0) && (index <= 3)) {
1158 struct iw_point *dwrq,
char *extra)
1163 u32 authen = 0, invoke = 0, exunencrypt = 0;
1190 if (index == -1 || index > 3)
1199 dwrq->
flags |= devindex + 1;
1206 struct iw_param *vwrq,
char *extra)
1226 struct iw_param *vwrq,
char *extra)
1236 "%s: %s() disabling radio is not yet supported.\n",
1237 priv->
ndev->name, __func__);
1239 }
else if (vwrq->
fixed)
1244 "%s: %s() auto power will be implemented later.\n",
1245 priv->
ndev->name, __func__);
1250 static int prism54_set_genie(
struct net_device *ndev,
1252 struct iw_point *data,
char *extra)
1270 #define WLAN_FC_TYPE_MGMT 0
1271 #define WLAN_FC_STYPE_ASSOC_REQ 0
1272 #define WLAN_FC_STYPE_REASSOC_REQ 2
1276 (WLAN_FC_STYPE_ASSOC_REQ << 4);
1285 (WLAN_FC_STYPE_REASSOC_REQ << 4);
1299 static int prism54_get_genie(
struct net_device *ndev,
1301 struct iw_point *data,
char *extra)
1320 static int prism54_set_auth(
struct net_device *ndev,
1326 u32 mlmelevel = 0, authen = 0, dot1x = 0;
1327 u32 exunencrypt = 0, privinvoked = 0, wpa = 0;
1337 wpa = old_wpa = priv->
wpa;
1402 dot1x = param->
value ? 0 : 0x01;
1406 privinvoked = param->
value ? 1 : 0;
1410 exunencrypt = param->
value ? 1 : 0;
1447 static int prism54_get_auth(
struct net_device *ndev,
1493 param->
value =
r.u > 0 ? 1 : 0;
1515 param->
value = wpa > 0 ? 1 : 0;
1521 param->
value =
r.u > 0 ? 1 : 0;
1527 param->
value =
r.u > 0 ? 1 : 0;
1536 static int prism54_set_encodeext(
struct net_device *ndev,
1555 if (idx < 0 || idx > 3)
1572 set_key = ext->
key_len > 0 ? 1 : 0;
1645 static int prism54_get_encodeext(
struct net_device *ndev,
1653 int idx, max_key_len;
1655 int authen =
DOT11_AUTH_OS, invoke = 0, exunencrypt = 0, wpa = 0;
1671 max_key_len = encoding->
length -
sizeof(*ext);
1672 if (max_key_len < 0)
1677 if (idx < 0 || idx > 3)
1686 encoding->
flags = idx + 1;
1687 memset(ext, 0,
sizeof(*ext));
1703 if (authen ==
DOT11_AUTH_OS && !exunencrypt && !invoke && !wpa) {
1715 if (max_key_len < key->
length) {
1722 switch (key->
type) {
1741 __u32 * uwrq,
char *extra)
1750 struct iw_point *dwrq,
char *extra)
1765 __u32 * uwrq,
char *extra)
1767 u32 oid = uwrq[0], u = uwrq[1];
1774 struct iw_point *dwrq,
char *extra)
1787 acl->
policy = MAC_POLICY_OPEN;
1798 if (acl->
size == 0) {
1816 prism54_clear_mac(acl);
1821 struct sockaddr *awrq,
char *extra)
1850 struct sockaddr *awrq,
char *extra)
1877 struct iw_point *dwrq,
char *extra)
1905 __u32 * uwrq,
char *extra)
1911 prism54_clear_mac(acl);
1941 __u32 * uwrq,
char *extra)
1962 if (acl->
policy == MAC_POLICY_OPEN) {
1973 res = (acl->
policy == MAC_POLICY_ACCEPT) ? !res : res;
1981 struct iw_point *dwrq,
char *extra)
2001 struct sockaddr *awrq,
char *extra)
2032 "%s %s %pM %s (%2.2X)",
2036 (error ? (mlme->
code ?
" : REJECTED " :
" : ACCEPTED ")
2044 const struct obj_mlme *mlme,
int error)
2053 wrqu.
data.length = 0;
2054 format_event(priv, memptr, str, mlme, &wrqu.
data.length,
2072 wrqu.
data.length =
n;
2091 send_simple_event(netdev_priv(ndev),
2092 "Link established");
2095 send_simple_event(netdev_priv(ndev),
"Link lost");
2106 #define WLAN_EID_GENERIC 0xdd
2107 static u8 wpa_oid[4] = { 0x00, 0x50, 0xf2, 1 };
2111 u8 *wpa_ie,
size_t wpa_ie_len)
2225 pos = (
u8 *) (hdr + 1);
2226 end = payload + len;
2228 if (pos + 2 + pos[1] > end) {
2234 memcmp(pos + 2, wpa_oid, 4) == 0) {
2235 prism54_wpa_bss_ie_add(priv, addr, pos, pos[1] + 2);
2251 mlme->
code = prism54_mac_accept(&priv->
acl,
2280 payload = pos = mlmeex->
data;
2285 prism54_process_bss_data(priv, oid, mlmeex->
address,
2293 link_changed(priv->
ndev, (
u32) *data);
2297 send_simple_event(priv,
"Mic failure");
2301 send_formatted_event(priv,
"DeAuthenticate request", mlme, 0);
2305 handle_request(priv, mlme, oid);
2306 send_formatted_event(priv,
"Authenticate request", mlme, 1);
2310 send_formatted_event(priv,
"Disassociate request", mlme, 0);
2314 handle_request(priv, mlme, oid);
2315 send_formatted_event(priv,
"Associate request", mlme, 1);
2319 handle_request(priv, mlme, oid);
2320 send_formatted_event(priv,
"ReAssociate request", mlme, 1);
2324 send_formatted_event(priv,
2325 "Received a beacon from an unknown AP",
2331 send_formatted_event(priv,
"Received a probe from client", mlme,
2340 send_formatted_event(priv,
"DeAuthenticate request", mlme, 0);
2344 handle_request(priv, mlme, oid);
2345 send_formatted_event(priv,
"Authenticate request (ex)", mlme, 1);
2363 confirm->
data[0] = 0x00;
2364 confirm->
data[1] = 0x00;
2365 confirm->
data[2] = 0x02;
2366 confirm->
data[3] = 0x00;
2367 confirm->
data[4] = 0x00;
2368 confirm->
data[5] = 0x00;
2378 send_formatted_event(priv,
"Disassociate request (ex)", mlme, 0);
2382 handle_request(priv, mlme, oid);
2383 send_formatted_event(priv,
"Associate request (ex)", mlme, 1);
2400 wpa_ie_len = prism54_wpa_bss_ie_get(priv, mlmeex->
address, wpa_ie);
2409 confirm->
size = wpa_ie_len;
2419 handle_request(priv, mlme, oid);
2420 send_formatted_event(priv,
"Reassociate request (ex)", mlme, 1);
2433 confirm->
id = mlmeex->
id;
2437 wpa_ie_len = prism54_wpa_bss_ie_get(priv, mlmeex->
address, wpa_ie);
2446 confirm->
size = wpa_ie_len;
2475 prism54_process_trap_helper(netdev_priv(ndev), n, frame->
data);
2476 islpci_mgt_release(frame);
2488 &((
struct sockaddr *) addr)->sa_data);
2491 &((
struct sockaddr *) addr)->sa_data, 6);
2496 #define PRISM54_SET_WPA SIOCIWFIRSTPRIV+12
2500 __u32 * uwrq,
char *extra)
2517 switch (priv->
wpa) {
2544 __u32 * uwrq,
char *extra)
2553 __u32 * uwrq,
char *extra)
2566 __u32 * uwrq,
char *extra)
2575 __u32 * uwrq,
char *extra)
2580 printk(
"%s: oid 0x%08X\n", ndev->
name, *uwrq);
2587 struct iw_point *data,
char *extra)
2602 if (ret || !response
2605 islpci_mgt_release(response);
2613 islpci_mgt_release(response);
2623 struct iw_point *data,
char *extra)
2638 if (ret || !response
2641 islpci_mgt_release(response);
2647 response_op = response->
header->operation;
2650 islpci_mgt_release(response);
2669 if ((uwrq->
data.length == 0) && (priv->
spy_data.spy_number > 0))
2672 else if ((uwrq->
data.length > 0) && (priv->
spy_data.spy_number == 0))
2683 static const iw_handler prism54_handler[] = {
2743 #define PRISM54_RESET SIOCIWFIRSTPRIV
2744 #define PRISM54_GET_POLICY SIOCIWFIRSTPRIV+1
2745 #define PRISM54_SET_POLICY SIOCIWFIRSTPRIV+2
2746 #define PRISM54_GET_MAC SIOCIWFIRSTPRIV+3
2747 #define PRISM54_ADD_MAC SIOCIWFIRSTPRIV+4
2749 #define PRISM54_DEL_MAC SIOCIWFIRSTPRIV+6
2751 #define PRISM54_KICK_MAC SIOCIWFIRSTPRIV+8
2753 #define PRISM54_KICK_ALL SIOCIWFIRSTPRIV+10
2755 #define PRISM54_GET_WPA SIOCIWFIRSTPRIV+11
2756 #define PRISM54_SET_WPA SIOCIWFIRSTPRIV+12
2758 #define PRISM54_DBG_OID SIOCIWFIRSTPRIV+14
2759 #define PRISM54_DBG_GET_OID SIOCIWFIRSTPRIV+15
2760 #define PRISM54_DBG_SET_OID SIOCIWFIRSTPRIV+16
2762 #define PRISM54_GET_OID SIOCIWFIRSTPRIV+17
2763 #define PRISM54_SET_OID_U32 SIOCIWFIRSTPRIV+18
2764 #define PRISM54_SET_OID_STR SIOCIWFIRSTPRIV+20
2765 #define PRISM54_SET_OID_ADDR SIOCIWFIRSTPRIV+22
2767 #define PRISM54_GET_PRISMHDR SIOCIWFIRSTPRIV+23
2768 #define PRISM54_SET_PRISMHDR SIOCIWFIRSTPRIV+24
2770 #define IWPRIV_SET_U32(n,x) { n, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "s_"x }
2771 #define IWPRIV_SET_SSID(n,x) { n, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 1, 0, "s_"x }
2772 #define IWPRIV_SET_ADDR(n,x) { n, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "s_"x }
2773 #define IWPRIV_GET(n,x) { n, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | PRIV_STR_SIZE, "g_"x }
2775 #define IWPRIV_U32(n,x) IWPRIV_SET_U32(n,x), IWPRIV_GET(n,x)
2776 #define IWPRIV_SSID(n,x) IWPRIV_SET_SSID(n,x), IWPRIV_GET(n,x)
2777 #define IWPRIV_ADDR(n,x) IWPRIV_SET_ADDR(n,x), IWPRIV_GET(n,x)
2781 static const struct iw_priv_args prism54_private_args[] = {
2873 static const iw_handler prism54_private_handler[] = {
2903 .num_private =
ARRAY_SIZE(prism54_private_handler),
2904 .num_private_args =
ARRAY_SIZE(prism54_private_args),
2906 .
private = (
iw_handler *) prism54_private_handler,
2907 .private_args = (
struct iw_priv_args *) prism54_private_args,