Topic: Lantiq XWAY WAVE300

Is this some own SIP by Lantiq for 802.11 or is it from another company?

What is the name of the FOSS Linux driver for this WNIC?
Here: http://en.wikipedia.org/wiki/Comparison_of_open-source_wireless_drivers

Re: Lantiq XWAY WAVE300

AFAIK there aren't sources for this wireless chip.

3 (edited by scapi 2013-07-05 13:47:40)

Re: Lantiq XWAY WAVE300

Actiontec PK5001A - openwrt source (only modification found was hostapd driver_mtlk patch)
BT HomeHub 4 - OpenRG (hostapd different driver_mtlk variant)
Livebox 2.1 - unknown
W921V - unknown
TD-W8980 - Full source hostapd + driver

These devices use Wave300 wireless chip.

Actiontec hostapd patch - hostapd as custom feed :

diff -Nur hostap-78debc7/.gitignore hostapd08/.gitignore
--- hostap-78debc7/.gitignore    2012-02-13 17:42:24.000000000 +0200
+++ hostapd08/.gitignore    1970-01-01 02:00:00.000000000 +0200
@@ -1,21 +0,0 @@
-*.o
-*.d
-*~
-.config
-wpa_supplicant/eapol_test
-wpa_supplicant/preauth_test
-wpa_supplicant/wpa_cli
-wpa_supplicant/wpa_passphrase
-wpa_supplicant/wpa_supplicant
-wpa_supplicant/wpa_priv
-wpa_supplicant/wpa_gui/Makefile
-wpa_supplicant/wpa_gui/wpa_gui
-wpa_supplicant/wpa_gui-qt4/Makefile
-wpa_supplicant/wpa_gui-qt4/wpa_gui
-hostapd/hostapd
-hostapd/hostapd_cli
-hostapd/hlr_auc_gw
-hostapd/nt_password_hash
-wlantest/libwlantest.a
-wlantest/wlantest
-wlantest/wlantest_cli
diff -Nur hostap-78debc7/hostapd/.config hostapd08/hostapd/.config
--- hostap-78debc7/hostapd/.config    1970-01-01 02:00:00.000000000 +0200
+++ hostapd08/hostapd/.config    2012-02-13 17:44:05.000000000 +0200
@@ -0,0 +1,213 @@
+# Example hostapd build time configuration
+#
+# This file lists the configuration options that are used when building the
+# hostapd binary. All lines starting with # are ignored. Configuration option
+# lines must be commented out complete, if they are not to be included, i.e.,
+# just setting VARIABLE=n is not disabling that variable.
+#
+# This file is included in Makefile, so variables like CFLAGS and LIBS can also
+# be modified from here. In most cass, these lines should use += in order not
+# to override previous values of the variables.
+
+# Driver interface for Host AP driver
+#CONFIG_DRIVER_HOSTAP=y
+
+# Driver interface for Metalink driver
+CONFIG_DRIVER_MTLK=y
+
+# Driver interface for wired authenticator
+#CONFIG_DRIVER_WIRED=y
+
+# Driver interface for madwifi driver
+#CONFIG_DRIVER_MADWIFI=y
+#CFLAGS += -I../../madwifi # change to the madwifi source directory
+
+# Driver interface for drivers using the nl80211 kernel interface
+#CONFIG_DRIVER_NL80211=y
+
+# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
+#CONFIG_DRIVER_BSD=y
+#CFLAGS += -I/usr/local/include
+#LIBS += -L/usr/local/lib
+#LIBS_p += -L/usr/local/lib
+#LIBS_c += -L/usr/local/lib
+
+# Driver interface for no driver (e.g., RADIUS server only)
+#CONFIG_DRIVER_NONE=y
+
+# IEEE 802.11F/IAPP
+CONFIG_IAPP=y
+
+# WPA2/IEEE 802.11i RSN pre-authentication
+CONFIG_RSN_PREAUTH=y
+
+# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
+CONFIG_PEERKEY=y
+
+# IEEE 802.11w (management frame protection)
+# This version is an experimental implementation based on IEEE 802.11w/D1.0
+# draft and is subject to change since the standard has not yet been finalized.
+# Driver support is also needed for IEEE 802.11w.
+#CONFIG_IEEE80211W=y
+
+# Integrated EAP server
+CONFIG_EAP=y
+
+# EAP-MD5 for the integrated EAP server
+CONFIG_EAP_MD5=y
+
+# EAP-TLS for the integrated EAP server
+CONFIG_EAP_TLS=y
+
+# EAP-MSCHAPv2 for the integrated EAP server
+CONFIG_EAP_MSCHAPV2=y
+
+# EAP-PEAP for the integrated EAP server
+CONFIG_EAP_PEAP=y
+
+# EAP-GTC for the integrated EAP server
+CONFIG_EAP_GTC=y
+
+# EAP-TTLS for the integrated EAP server
+CONFIG_EAP_TTLS=y
+
+# EAP-SIM for the integrated EAP server
+#CONFIG_EAP_SIM=y
+
+# EAP-AKA for the integrated EAP server
+#CONFIG_EAP_AKA=y
+
+# EAP-AKA' for the integrated EAP server
+# This requires CONFIG_EAP_AKA to be enabled, too.
+#CONFIG_EAP_AKA_PRIME=y
+
+# EAP-PAX for the integrated EAP server
+#CONFIG_EAP_PAX=y
+
+# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK)
+#CONFIG_EAP_PSK=y
+
+# EAP-SAKE for the integrated EAP server
+#CONFIG_EAP_SAKE=y
+
+# EAP-GPSK for the integrated EAP server
+#CONFIG_EAP_GPSK=y
+# Include support for optional SHA256 cipher suite in EAP-GPSK
+#CONFIG_EAP_GPSK_SHA256=y
+
+# EAP-FAST for the integrated EAP server
+# Note: Default OpenSSL package does not include support for all the
+# functionality needed for EAP-FAST. If EAP-FAST is enabled with OpenSSL,
+# the OpenSSL library must be patched (openssl-0.9.9-session-ticket.patch)
+# to add the needed functions.
+#CONFIG_EAP_FAST=y
+
+# Wi-Fi Protected Setup (WPS)
+CONFIG_WPS=y
+# Enable WSC 2.0 support
+CONFIG_WPS2=y
+# Enable UPnP support for external WPS Registrars
+CONFIG_WPS_UPNP=y
+
+# EAP-IKEv2
+#CONFIG_EAP_IKEV2=y
+
+# Trusted Network Connect (EAP-TNC)
+#CONFIG_EAP_TNC=y
+
+# PKCS#12 (PFX) support (used to read private key and certificate file from
+# a file that usually has extension .p12 or .pfx)
+#CONFIG_PKCS12=y
+
+# RADIUS authentication server. This provides access to the integrated EAP
+# server from external hosts using RADIUS.
+#CONFIG_RADIUS_SERVER=y
+
+# Build IPv6 support for RADIUS operations
+#CONFIG_IPV6=y
+
+# IEEE Std 802.11r-2008 (Fast BSS Transition)
+#CONFIG_IEEE80211R=y
+
+# Use the hostapd's IEEE 802.11 authentication (ACL), but without
+# the IEEE 802.11 Management capability (e.g., madwifi or FreeBSD/net80211)
+#CONFIG_DRIVER_RADIUS_ACL=y
+
+# IEEE 802.11n (High Throughput) support
+#CONFIG_IEEE80211N=y
+
+# Remove debugging code that is printing out debug messages to stdout.
+# This can be used to reduce the size of the hostapd considerably if debugging
+# code is not needed.
+#CONFIG_NO_STDOUT_DEBUG=y
+
+# Add support for writing debug log to a file: -f /tmp/hostapd.log
+# Disabled by default.
+#CONFIG_DEBUG_FILE=y
+
+# Remove support for RADIUS accounting
+#CONFIG_NO_ACCOUNTING=y
+
+# Remove support for RADIUS
+#CONFIG_NO_RADIUS=y
+
+# Remove support for VLANs
+#CONFIG_NO_VLAN=y
+
+# Enable support for fully dynamic VLANs. This enables hostapd to
+# automatically create bridge and VLAN interfaces if necessary.
+#CONFIG_FULL_DYNAMIC_VLAN=y
+
+# Remove support for dumping state into a file on SIGUSR1 signal
+# This can be used to reduce binary size at the cost of disabling a debugging
+# option.
+#CONFIG_NO_DUMP_STATE=y
+
+# Enable tracing code for developer debugging
+# This tracks use of memory allocations and other registrations and reports
+# incorrect use with a backtrace of call (or allocation) location.
+#CONFIG_WPA_TRACE=y
+# For BSD, comment out these.
+#LIBS += -lexecinfo
+#LIBS_p += -lexecinfo
+#LIBS_c += -lexecinfo
+
+# Use libbfd to get more details for developer debugging
+# This enables use of libbfd to get more detailed symbols for the backtraces
+# generated by CONFIG_WPA_TRACE=y.
+#CONFIG_WPA_TRACE_BFD=y
+# For BSD, comment out these.
+#LIBS += -lbfd -liberty -lz
+#LIBS_p += -lbfd -liberty -lz
+#LIBS_c += -lbfd -liberty -lz
+
+# hostapd depends on strong random number generation being available from the
+# operating system. os_get_random() function is used to fetch random data when
+# needed, e.g., for key generation. On Linux and BSD systems, this works by
+# reading /dev/urandom. It should be noted that the OS entropy pool needs to be
+# properly initialized before hostapd is started. This is important especially
+# on embedded devices that do not have a hardware random number generator and
+# may by default start up with minimal entropy available for random number
+# generation.
+#
+# As a safety net, hostapd is by default trying to internally collect
+# additional entropy for generating random data to mix in with the data
+# fetched from the OS. This by itself is not considered to be very strong, but
+# it may help in cases where the system pool is not initialized properly.
+# However, it is very strongly recommended that the system pool is initialized
+# with enough entropy either by using hardware assisted random number
+# generator or by storing state over device reboots.
+#
+# hostapd can be configured to maintain its own entropy store over restarts to
+# enhance random number generation. This is not perfect, but it is much more
+# secure than using the same sequence of random numbers after every reboot.
+# This can be enabled with -e<entropy file> command line option. The specified
+# file needs to be readable and writable by hostapd.
+#
+# If the os_get_random() is known to provide strong random data (e.g., on
+# Linux/BSD, the board in question is known to have reliable source of random
+# data from /dev/urandom), the internal hostapd random pool can be disabled.
+# This will save some in binary size and CPU use. However, this should only be
+# considered for builds that are known to be used on devices that meet the
+# requirements described above.
+#CONFIG_NO_RANDOM_POOL=y
diff -Nur hostap-78debc7/src/drivers/driver_mtlk.c hostapd08/src/drivers/driver_mtlk.c
--- hostap-78debc7/src/drivers/driver_mtlk.c    1970-01-01 02:00:00.000000000 +0200
+++ hostapd08/src/drivers/driver_mtlk.c    2012-02-13 17:44:48.000000000 +0200
@@ -0,0 +1,805 @@
+/*
+ * hostapd / Driver interaction with Lantiq Wave300/400 driver
+ * Copyright (c) 2006-2008 Metalink Broadband (Israel)
+ * Copyright (c) 2011      Lantiq (Israel)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+#include <sys/ioctl.h>
+#include <net/if_arp.h>
+
+#include "common.h"
+#include "driver.h"
+#include "driver_wext.h"
+#include "eloop.h"
+#include "common/ieee802_11_defs.h"
+#include "linux_wext.h"
+
+#include "priv_netlink.h"
+#include "netlink.h"
+#include "l2_packet/l2_packet.h"
+#include "radius/radius.h"
+
+
+enum ietypes {
+    IE_WSC_BEACON     = 0,
+    IE_WSC_PROBE_REQ  = 1,
+    IE_WSC_PROBE_RESP = 2,
+    IE_WSC_ASSOC_REQ  = 3,
+    IE_WSC_ASSOC_RESP = 4
+};
+
+struct mtlk_driver_data {
+    struct hostapd_data *hapd;        /* back pointer */
+
+    char    iface[IFNAMSIZ + 1];
+    int     ifindex;
+    struct l2_packet_data *sock_xmit;    /* raw packet xmit socket */
+    struct l2_packet_data *sock_recv;    /* raw packet recv socket */
+    int    ioctl_sock;            /* socket for ioctl() use */
+    struct netlink_data *netlink;
+    int    we_version;
+    u8    acct_mac[ETH_ALEN];
+    struct hostap_sta_driver_data acct_data;
+};
+
+static const char *
+ether_sprintf(const u8 *addr)
+{
+    static char buf[sizeof(MACSTR)];
+
+    if (addr != NULL)
+        snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
+    else
+        snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0);
+    return buf;
+}
+
+int
+mtlk_set_iface_flags(void *priv, int dev_up)
+{
+    struct mtlk_driver_data *drv = priv;
+    struct ifreq ifr;
+
+    wpa_printf(MSG_DEBUG, "%s: dev_up=%d", __func__, dev_up);
+
+    if (drv->ioctl_sock < 0)
+        return -1;
+
+    memset(&ifr, 0, sizeof(ifr));
+    snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->iface);
+
+    if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) {
+        perror("ioctl[SIOCGIFFLAGS]");
+        return -1;
+    }
+
+    if (dev_up)
+        ifr.ifr_flags |= IFF_UP;
+    else
+        ifr.ifr_flags &= ~IFF_UP;
+
+    if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, &ifr) != 0) {
+        perror("ioctl[SIOCSIFFLAGS]");
+        return -1;
+    }
+
+    return 0;
+}
+
+static int
+mtlk_set_encryption(const char *ifname, void *priv, enum wpa_alg alg,
+         const u8 *addr, int key_idx, int txkey,
+         const u8 *seq, size_t seq_len,
+         const u8 *key, size_t key_len)
+{
+    struct mtlk_driver_data *drv = priv;
+    struct iwreq iwr;
+    struct iw_encode_ext *ext;
+    int ret=0;
+
+    wpa_printf(MSG_DEBUG,
+        "%s: alg=%d addr=%s key_idx=%d txkey=%d",
+        __func__, alg, ether_sprintf(addr), key_idx, txkey);
+
+    ext = malloc(sizeof(*ext) + key_len);
+    if (ext == NULL)
+        return -1;
+    memset(ext, 0, sizeof(*ext) + key_len);
+    memset(&iwr, 0, sizeof(iwr));
+    strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
+    iwr.u.encoding.flags = key_idx + 1;
+    iwr.u.encoding.pointer = (caddr_t) ext;
+    iwr.u.encoding.length = sizeof(*ext) + key_len;
+
+    if (addr == NULL ||
+        memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0)
+        ext->ext_flags |= IW_ENCODE_EXT_GROUP_KEY;
+    if (txkey)
+        ext->ext_flags |= IW_ENCODE_EXT_SET_TX_KEY;
+    
+    ext->addr.sa_family = ARPHRD_ETHER;
+    if (addr)
+        memcpy(ext->addr.sa_data, addr, ETH_ALEN);
+    else
+        memset(ext->addr.sa_data, 0xff, ETH_ALEN);
+    if (key && key_len) {
+        memcpy(ext + 1, key, key_len);
+        ext->key_len = key_len;
+    }
+
+    if (alg == WPA_ALG_NONE)
+        ext->alg = IW_ENCODE_ALG_NONE;
+    else if (alg == WPA_ALG_WEP)
+        ext->alg = IW_ENCODE_ALG_WEP;
+    else if (alg == WPA_ALG_TKIP)
+        ext->alg = IW_ENCODE_ALG_TKIP;
+    else if (alg == WPA_ALG_CCMP)
+        ext->alg = IW_ENCODE_ALG_CCMP;
+    else {
+        printf("%s: unknown/unsupported algorithm %d\n",
+            __func__, alg);
+        return -1;
+    }
+
+    if (ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr) < 0) {
+        ret = errno == EOPNOTSUPP ? -2 : -1;
+        perror("ioctl[SIOCSIWENCODEEXT]");
+    }
+
+    free(ext);
+    return ret;
+}
+
+
+static int
+mtlk_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx, u8 *seq)
+{
+    struct mtlk_driver_data *drv = priv;
+    struct iwreq iwr;
+    struct iw_encode_ext *ext;
+    int ret=0;
+
+    wpa_printf(MSG_DEBUG,
+        "%s: addr=%s idx=%d", __func__, ether_sprintf(addr), idx);
+
+    ext = malloc(sizeof(*ext));
+    if (ext == NULL)
+        return -1;
+    memset(ext, 0, sizeof(*ext));
+    memset(&iwr, 0, sizeof(iwr));
+    strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
+    iwr.u.encoding.pointer = (caddr_t) ext;
+    iwr.u.encoding.length = sizeof(*ext);
+
+    if (addr == NULL ||
+        memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0)
+        iwr.u.encoding.flags |= IW_ENCODE_EXT_GROUP_KEY;
+
+    if (ioctl(drv->ioctl_sock, SIOCGIWENCODEEXT, &iwr) < 0) {
+        ret = errno == EOPNOTSUPP ? -2 : -1;
+        perror("ioctl[SIOCGIWENCODEEXT]");
+        goto err;
+    }
+
+    memcpy(seq, ext->rx_seq, 6);
+err:
+    free(ext);
+    return ret;
+}
+
+
+static int 
+mtlk_flush(void *priv)
+{
+    return 0;        /* XXX */
+}
+
+
+
+static int
+mtlk_sta_clear_stats(void *priv, const u8 *addr)
+{
+    return 0; /* FIX */
+}
+
+
+static int
+mtlk_set_generic_elem(void *priv, const u8 *ie, size_t ie_len)
+{
+    struct mtlk_driver_data *drv = priv;
+    struct iwreq iwr;
+    int ret = 0;
+
+    memset(&iwr, 0, sizeof(iwr));
+    strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
+    iwr.u.data.pointer = (caddr_t) ie;
+    iwr.u.data.length = ie_len;
+
+    if (ioctl(drv->ioctl_sock, SIOCSIWGENIE, &iwr) < 0) {
+        perror("ioctl[SIOCSIWGENIE]");
+        ret = -1;
+    }
+
+    return ret;
+}
+
+static int
+mtlk_mlme(struct mtlk_driver_data *drv,
+    const u8 *addr, int cmd, int reason_code)
+{
+    struct iwreq iwr;
+    struct iw_mlme mlme;
+    int ret = 0;
+
+    memset(&iwr, 0, sizeof(iwr));
+    strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
+    memset(&mlme, 0, sizeof(mlme));
+    mlme.cmd = cmd;
+    mlme.reason_code = reason_code;
+    mlme.addr.sa_family = ARPHRD_ETHER;
+    memcpy(mlme.addr.sa_data, addr, ETH_ALEN);
+    iwr.u.data.pointer = (caddr_t) &mlme;
+    iwr.u.data.length = sizeof(mlme);
+
+    if (ioctl(drv->ioctl_sock, SIOCSIWMLME, &iwr) < 0) {
+        perror("ioctl[SIOCSIWMLME]");
+        ret = -1;
+    }
+
+    return ret;
+}
+
+static int
+mtlk_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, int reason_code)
+{
+    struct mtlk_driver_data *drv = priv;
+    wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
+    return mtlk_mlme(drv, addr, IW_MLME_DEAUTH, reason_code);
+}
+
+static int
+mtlk_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, int reason_code)
+{
+    struct mtlk_driver_data *drv = priv;
+    wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
+    return mtlk_mlme(drv, addr, IW_MLME_DISASSOC, reason_code);
+}
+
+static void
+mtlk_michael_mic_failure(struct hostapd_data *hapd, const u8 *addr)
+{
+    union wpa_event_data data;
+    os_memset(&data, 0, sizeof(data));
+    data.michael_mic_failure.unicast = 1;
+    data.michael_mic_failure.src = addr;
+    wpa_supplicant_event(hapd, EVENT_MICHAEL_MIC_FAILURE, &data);
+}
+
+static int
+mtlk_wireless_michaelmicfailure(struct mtlk_driver_data *drv,
+                const char *ev, int len)
+{
+    const struct iw_michaelmicfailure *mic;
+    u8 *addr;
+
+    if (len < sizeof(*mic)) {
+        wpa_printf(MSG_DEBUG,
+            "Invalid MIC Failure data from driver");
+        return -1;
+    }
+
+    mic = (const struct iw_michaelmicfailure *) ev;
+
+    addr = (u8*) mic->src_addr.sa_data;
+    wpa_printf(MSG_DEBUG,
+        "Michael MIC failure wireless event: "
+        "flags=0x%x src_addr=" MACSTR, mic->flags, MAC2STR(addr));
+
+    mtlk_michael_mic_failure(drv->hapd, addr);
+
+    return 0;
+}
+
+static void
+mtlk_wireless_event_wireless_custom(struct mtlk_driver_data *drv,
+                       char *custom)
+{
+    const char newsta_tag[] = "NEWSTA ";
+    const char rsnie_tag[]  = "RSNIE_LEN ";
+
+    wpa_printf(MSG_DEBUG, "Custom wireless event: '%s'",
+              custom);
+
+    if (strncmp(custom, newsta_tag, strlen(newsta_tag)) == 0) {
+        char *pos = custom;
+        u8 addr[ETH_ALEN];
+        u8 *rsnie, ielen;
+        pos += strlen(newsta_tag);
+        if (hwaddr_aton(pos, addr) != 0) {
+            wpa_printf(MSG_DEBUG,
+                "NEWSTA with invalid MAC address");
+            return;
+        }
+        pos = strstr(pos, rsnie_tag);
+        pos += strlen(rsnie_tag);
+        ielen = atoi(pos);
+        if (!ielen) {
+            wpa_printf(MSG_DEBUG,
+                "NEWSTA with zero RSNIE length?");
+            return;
+        }
+        rsnie = malloc(ielen);
+        if (!rsnie) {
+            printf("ERROR: can't allocate buffer "
+                "of %i bytes for RSNIE", ielen);
+            return;
+        }
+        pos = strstr(pos, " : ");
+        pos += 3;
+        hexstr2bin(pos, rsnie, ielen);
+        drv_event_assoc(drv->hapd, addr, rsnie, ielen, 0);
+        free(rsnie);
+    } else
+    if (strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) {
+        char *pos;
+        u8 addr[ETH_ALEN];
+        pos = strstr(custom, "addr=");
+        if (pos == NULL) {
+            wpa_printf(MSG_DEBUG,
+                      "MLME-MICHAELMICFAILURE.indication "
+                      "without sender address ignored");
+            return;
+        }
+        pos += 5;
+        if (hwaddr_aton(pos, addr) == 0) {
+            mtlk_michael_mic_failure(drv->hapd, addr);
+        } else {
+            wpa_printf(MSG_DEBUG,
+                      "MLME-MICHAELMICFAILURE.indication "
+                      "with invalid MAC address");
+        }
+    } else if (strncmp(custom, "STA-TRAFFIC-STAT", 16) == 0) {
+        char *key, *value;
+        u32 val;
+        key = custom;
+        while ((key = strchr(key, '\n')) != NULL) {
+            key++;
+            value = strchr(key, '=');
+            if (value == NULL)
+                continue;
+            *value++ = '\0';
+            val = strtoul(value, NULL, 10);
+            if (strcmp(key, "mac") == 0)
+                hwaddr_aton(value, drv->acct_mac);
+            else if (strcmp(key, "rx_packets") == 0)
+                drv->acct_data.rx_packets = val;
+            else if (strcmp(key, "tx_packets") == 0)
+                drv->acct_data.tx_packets = val;
+            else if (strcmp(key, "rx_bytes") == 0)
+                drv->acct_data.rx_bytes = val;
+            else if (strcmp(key, "tx_bytes") == 0)
+                drv->acct_data.tx_bytes = val;
+            key = value;
+        }
+    }
+}
+
+static void
+mtlk_wireless_event_wireless(struct mtlk_driver_data *drv,
+                        char *data, int len)
+{
+    struct iw_event iwe_buf, *iwe = &iwe_buf;
+    char *pos, *end, *custom, *buf;
+
+    pos = data;
+    end = data + len;
+
+    while (pos + IW_EV_LCP_LEN <= end) {
+        /* Event data may be unaligned, so make a local, aligned copy
+         * before processing. */
+        memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);
+        wpa_printf(MSG_DEBUG, "Wireless event: "
+                  "cmd=0x%x len=%d", iwe->cmd, iwe->len);
+        if (iwe->len <= IW_EV_LCP_LEN)
+            return;
+
+        custom = pos + IW_EV_POINT_LEN;
+        iwe->u.data.pointer = custom;
+        if (drv->we_version > 18 &&
+            (iwe->cmd == IWEVMICHAELMICFAILURE ||
+             iwe->cmd == IWEVCUSTOM)) {
+            /* WE-19 removed the pointer from struct iw_point */
+            char *dpos = (char *) &iwe_buf.u.data.length;
+            int dlen = dpos - (char *) &iwe_buf;
+            memcpy(dpos, pos + IW_EV_LCP_LEN,
+                   sizeof(struct iw_event) - dlen);
+        } else {
+            memcpy(&iwe_buf, pos, sizeof(struct iw_event));
+            custom += IW_EV_POINT_OFF;
+        }
+
+        switch (iwe->cmd) {
+        case IWEVEXPIRED:
+            drv_event_disassoc(drv->hapd, (u8*)iwe->u.addr.sa_data);
+            break;
+        case IWEVREGISTERED:
+            drv_event_assoc(drv->hapd, (u8*)iwe->u.addr.sa_data, NULL, 0, 0);
+            break;
+        case IWEVMICHAELMICFAILURE:
+            mtlk_wireless_michaelmicfailure(drv, custom,
+                            iwe->u.data.length);
+            break;
+        case IWEVCUSTOM:
+            if (custom + iwe->u.data.length > end)
+                return;
+            buf = malloc(iwe->u.data.length + 1);
+            if (buf == NULL)
+                return;        /* XXX */
+            memcpy(buf, custom, iwe->u.data.length);
+            buf[iwe->u.data.length] = '\0';
+            mtlk_wireless_event_wireless_custom(drv, buf);
+            free(buf);
+            break;
+        }
+
+        pos += iwe->len;
+    }
+}
+
+
+static void
+mtlk_wireless_event_rtm_newlink(void *ctx, struct ifinfomsg *ifi,
+                u8 *buf, size_t len)
+{
+    struct mtlk_driver_data *drv = ctx;
+    int attrlen, rta_len;
+    struct rtattr *attr;
+
+    if (ifi->ifi_index != drv->ifindex)
+        return;
+
+    attrlen = len;
+    attr = (struct rtattr *) buf;
+
+    rta_len = RTA_ALIGN(sizeof(struct rtattr));
+    while (RTA_OK(attr, attrlen)) {
+        if (attr->rta_type == IFLA_WIRELESS) {
+            mtlk_wireless_event_wireless(
+                drv, ((char *) attr) + rta_len,
+                attr->rta_len - rta_len);
+        }
+        attr = RTA_NEXT(attr, attrlen);
+    }
+}
+
+
+static int
+mtlk_get_we_version(struct mtlk_driver_data *drv)
+{
+    struct iw_range *range;
+    struct iwreq iwr;
+    int minlen;
+    size_t buflen;
+
+    drv->we_version = 0;
+
+    /*
+     * Use larger buffer than struct iw_range in order to allow the
+     * structure to grow in the future.
+     */
+    buflen = sizeof(struct iw_range) + 500;
+    range = malloc(buflen);
+    if (range == NULL)
+        return -1;
+    memset(range, 0, buflen);
+
+    memset(&iwr, 0, sizeof(iwr));
+    strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
+    iwr.u.data.pointer = (caddr_t) range;
+    iwr.u.data.length = buflen;
+
+    minlen = ((char *) &range->enc_capa) - (char *) range +
+        sizeof(range->enc_capa);
+
+    if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) {
+        perror("ioctl[SIOCGIWRANGE]");
+        free(range);
+        return -1;
+    } else if (iwr.u.data.length >= minlen &&
+           range->we_version_compiled >= 18) {
+        wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d "
+               "WE(source)=%d enc_capa=0x%x",
+               range->we_version_compiled,
+               range->we_version_source,
+               range->enc_capa);
+        drv->we_version = range->we_version_compiled;
+    }
+
+    free(range);
+    return 0;
+}
+
+
+static int
+mtlk_wireless_event_init(struct mtlk_driver_data *drv)
+{
+    struct netlink_config *cfg;
+
+    mtlk_get_we_version(drv);
+
+    cfg = os_zalloc(sizeof(*cfg));
+    if (cfg == NULL)
+        return -1;
+    cfg->ctx = drv;
+    cfg->newlink_cb = mtlk_wireless_event_rtm_newlink;
+    drv->netlink = netlink_init(cfg);
+    if (drv->netlink == NULL) {
+        os_free(cfg);
+        return -1;
+    }
+
+    return 0;
+}
+
+
+static int
+mtlk_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,
+                int encrypt, const u8 *own_addr, u32 flags)
+{
+    struct mtlk_driver_data *drv = priv;
+    unsigned char buf[3000];
+    unsigned char *bp = buf;
+    struct l2_ethhdr *eth;
+    size_t len;
+    int status;
+
+    /*
+     * Prepend the Ethernet header.  If the caller left us
+     * space at the front we could just insert it but since
+     * we don't know we copy to a local buffer.  Given the frequency
+     * and size of frames this probably doesn't matter.
+     */
+    len = data_len + sizeof(struct l2_ethhdr);
+    if (len > sizeof(buf)) {
+        bp = malloc(len);
+        if (bp == NULL) {
+            printf("EAPOL frame discarded, cannot malloc temp "
+                   "buffer of size %lu!\n", (unsigned long) len);
+            return -1;
+        }
+    }
+    eth = (struct l2_ethhdr *) bp;
+    memcpy(eth->h_dest, addr, ETH_ALEN);
+    memcpy(eth->h_source, own_addr, ETH_ALEN);
+    eth->h_proto = htons(ETH_P_EAPOL);
+    memcpy(eth+1, data, data_len);
+
+    status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len);
+
+    if (bp != buf)
+        free(bp);
+    return status;
+}
+
+static void
+handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
+{
+    struct mtlk_driver_data *drv = ctx;
+
+    drv_event_eapol_rx(drv->hapd, src_addr, buf + sizeof(struct l2_ethhdr),
+               len - sizeof(struct l2_ethhdr));
+}
+
+static void *
+mtlk_init(struct hostapd_data *hapd, struct wpa_init_params *params)
+{
+    struct mtlk_driver_data *drv;
+    struct ifreq ifr;
+    struct iwreq iwr;
+
+    drv = os_zalloc(sizeof(struct mtlk_driver_data));
+    if (drv == NULL) {
+        printf("Could not allocate memory for mtlk driver data\n");
+        goto bad;
+    }
+
+    drv->hapd = hapd;
+    drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
+    if (drv->ioctl_sock < 0) {
+        perror("socket[PF_INET,SOCK_DGRAM]");
+        goto bad;
+    }
+    memcpy(drv->iface, params->ifname, sizeof(drv->iface));
+
+    memset(&ifr, 0, sizeof(ifr));
+    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", drv->iface);
+    if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) {
+        perror("ioctl(SIOCGIFINDEX)");
+        goto bad;
+    }
+    drv->ifindex = ifr.ifr_ifindex;
+
+    drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL,
+                    handle_read, drv, 1);
+    if (drv->sock_xmit == NULL)
+        goto bad;
+    if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr))
+        goto bad;
+    if (params->bridge[0]) {
+        wpa_printf(MSG_DEBUG,
+            "Configure bridge %s for EAPOL traffic.",
+            params->bridge[0]);
+        drv->sock_recv = l2_packet_init(params->bridge[0], NULL,
+                        ETH_P_EAPOL, handle_read, drv,
+                        1);
+        if (drv->sock_recv == NULL)
+            goto bad;
+    } else
+        drv->sock_recv = drv->sock_xmit;
+
+    memset(&iwr, 0, sizeof(iwr));
+    strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
+
+    iwr.u.mode = IW_MODE_MASTER;
+
+    if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) {
+        perror("ioctl[SIOCSIWMODE]");
+        printf("Could not set interface to master mode!\n");
+        goto bad;
+    }
+
+    mtlk_set_iface_flags(drv, 0);    /* mark down during setup */
+
+    if (mtlk_wireless_event_init(drv))
+        goto bad;
+
+    return drv;
+bad:
+    if (drv->sock_xmit != NULL)
+        l2_packet_deinit(drv->sock_xmit);
+    if (drv->ioctl_sock >= 0)
+        close(drv->ioctl_sock);
+    if (drv != NULL)
+        free(drv);
+    return NULL;
+}
+
+
+static void
+mtlk_deinit(void *priv)
+{
+    struct mtlk_driver_data *drv = priv;
+
+    netlink_deinit(drv->netlink);
+    (void) mtlk_set_iface_flags(drv, 0);
+    if (drv->ioctl_sock >= 0)
+        close(drv->ioctl_sock);
+    if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)
+        l2_packet_deinit(drv->sock_recv);
+    if (drv->sock_xmit != NULL)
+        l2_packet_deinit(drv->sock_xmit);
+    free(drv);
+}
+
+static int
+mtlk_set_ssid(void *priv, const u8 *buf, int len)
+{
+    struct mtlk_driver_data *drv = priv;
+    struct iwreq iwr;
+
+    memset(&iwr, 0, sizeof(iwr));
+    strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
+    iwr.u.essid.flags = 1; /* SSID active */
+    iwr.u.essid.pointer = (caddr_t) buf;
+    iwr.u.essid.length = len + 1;
+
+    if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) {
+        perror("ioctl[SIOCSIWESSID]");
+        printf("len=%d\n", len);
+        return -1;
+    }
+    return 0;
+}
+
+static int
+mtlk_get_ssid(void *priv, u8 *buf, int len)
+{
+    struct mtlk_driver_data *drv = priv;
+    struct iwreq iwr;
+    int ret = 0;
+
+    memset(&iwr, 0, sizeof(iwr));
+    strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
+    iwr.u.essid.pointer = (caddr_t) buf;
+    iwr.u.essid.length = len;
+
+    if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) {
+        perror("ioctl[SIOCGIWESSID]");
+        ret = -1;
+    } else
+        ret = iwr.u.essid.length;
+
+    return ret;
+}
+
+static int
+mtlk_commit(void *priv)
+{
+    return mtlk_set_iface_flags(priv, 1);
+}
+
+#ifdef CONFIG_WPS
+static int
+mtlk_set_wps_ie(void *priv, const u8 *ie, size_t ie_len, u16 ie_type)
+{
+    struct mtlk_driver_data *drv = priv;
+    struct iwreq iwr;
+    int ret = 0;
+
+    memset(&iwr, 0, sizeof(iwr));
+    strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
+    iwr.u.data.pointer = (caddr_t) ie;
+    iwr.u.data.length = ie_len;
+    iwr.u.data.flags = ie_type;
+
+    if (ioctl(drv->ioctl_sock, SIOCSIWGENIE, &iwr) < 0) {
+        perror("ioctl[SIOCSIWGENIE]");
+        ret = -1;
+    }
+
+    return ret;
+}
+
+static int
+mtlk_set_ap_wps_ie(void *priv, const struct wpabuf *beacon,
+            const struct wpabuf *proberesp,
+            const struct wpabuf *assocresp)
+{
+    int ret;
+    ret = mtlk_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL,
+                beacon ? wpabuf_len(beacon) : 0,
+                IE_WSC_BEACON);
+    if (ret < 0)
+        return ret;
+    ret = mtlk_set_wps_ie(priv, proberesp ? wpabuf_head(proberesp) : NULL,
+                proberesp ? wpabuf_len(proberesp) : 0,
+                IE_WSC_PROBE_RESP);
+    if (ret < 0)
+        return ret;
+    ret = mtlk_set_wps_ie(priv, assocresp ? wpabuf_head(assocresp) : NULL,
+                assocresp ? wpabuf_len(assocresp) : 0,
+                IE_WSC_ASSOC_RESP);
+    return ret;
+}
+
+#else
+#define mtlk_set_ap_wps_ie NULL
+#endif
+
+const struct wpa_driver_ops wpa_driver_mtlk_ops = {
+    .name            = "mtlk",
+    .hapd_init        = mtlk_init,
+    .deinit            = mtlk_deinit,
+    .set_key        = mtlk_set_encryption,
+    .get_seqnum        = mtlk_get_seqnum,
+    .flush            = mtlk_flush,
+    .set_generic_elem    = mtlk_set_generic_elem,
+    .hapd_send_eapol    = mtlk_send_eapol,
+    .sta_disassoc        = mtlk_sta_disassoc,
+    .sta_deauth        = mtlk_sta_deauth,
+    .hapd_set_ssid        = mtlk_set_ssid,
+    .hapd_get_ssid        = mtlk_get_ssid,
+    .sta_clear_stats    = mtlk_sta_clear_stats,
+    .commit            = mtlk_commit,
+    .set_ap_wps_ie        = mtlk_set_ap_wps_ie,
+};
diff -Nur hostap-78debc7/src/drivers/drivers.c hostapd08/src/drivers/drivers.c
--- hostap-78debc7/src/drivers/drivers.c    2012-02-13 17:42:25.000000000 +0200
+++ hostapd08/src/drivers/drivers.c    2012-02-13 17:46:07.000000000 +0200
@@ -46,6 +46,9 @@
 #ifdef CONFIG_DRIVER_ATHEROS
 extern struct wpa_driver_ops wpa_driver_atheros_ops; /* driver_atheros.c */
 #endif /* CONFIG_DRIVER_ATHEROS */
+#ifdef CONFIG_DRIVER_MTLK
+extern struct wpa_driver_ops wpa_driver_mtlk_ops; /* driver_mtlk.c */
+#endif /* CONFIG_DRIVER_MTLK */
 #ifdef CONFIG_DRIVER_NONE
 extern struct wpa_driver_ops wpa_driver_none_ops; /* driver_none.c */
 #endif /* CONFIG_DRIVER_NONE */
@@ -83,6 +86,9 @@
 #ifdef CONFIG_DRIVER_ATHEROS
     &wpa_driver_atheros_ops,
 #endif /* CONFIG_DRIVER_ATHEROS */
+#ifdef CONFIG_DRIVER_MTLK
+    &wpa_driver_mtlk_ops,
+#endif /* CONFIG_DRIVER_MTLK */
 #ifdef CONFIG_DRIVER_NONE
     &wpa_driver_none_ops,
 #endif /* CONFIG_DRIVER_NONE */
diff -Nur hostap-78debc7/src/drivers/drivers.mak hostapd08/src/drivers/drivers.mak
--- hostap-78debc7/src/drivers/drivers.mak    2012-02-13 17:42:25.000000000 +0200
+++ hostapd08/src/drivers/drivers.mak    2012-02-13 17:46:39.000000000 +0200
@@ -94,6 +94,15 @@
 NEED_LINUX_IOCTL=y
 endif
 
+ifdef CONFIG_DRIVER_MTLK
+DRV_AP_CFLAGS += -DCONFIG_DRIVER_MTLK
+DRV_AP_OBJS += ../src/drivers/driver_mtlk.o
+CONFIG_WIRELESS_EXTENSION=y
+CONFIG_L2_PACKET=linux
+NEED_NETLINK=y
+NEED_LINUX_IOCTL=y
+endif
+
 ##### PURE CLIENT DRIVERS
 
 ifdef CONFIG_DRIVER_WEXT
diff -Nur hostap-78debc7/wpa_supplicant/.config hostapd08/wpa_supplicant/.config
--- hostap-78debc7/wpa_supplicant/.config    1970-01-01 02:00:00.000000000 +0200
+++ hostapd08/wpa_supplicant/.config    2012-02-13 17:47:00.000000000 +0200
@@ -0,0 +1,461 @@
+# Example wpa_supplicant build time configuration
+#
+# This file lists the configuration options that are used when building the
+# hostapd binary. All lines starting with # are ignored. Configuration option
+# lines must be commented out complete, if they are not to be included, i.e.,
+# just setting VARIABLE=n is not disabling that variable.
+#
+# This file is included in Makefile, so variables like CFLAGS and LIBS can also
+# be modified from here. In most cases, these lines should use += in order not
+# to override previous values of the variables.
+
+
+# Uncomment following two lines and fix the paths if you have installed OpenSSL
+# or GnuTLS in non-default location
+#CFLAGS += -I/usr/local/openssl/include
+#LIBS += -L/usr/local/openssl/lib
+
+# Some Red Hat versions seem to include kerberos header files from OpenSSL, but
+# the kerberos files are not in the default include path. Following line can be
+# used to fix build issues on such systems (krb5.h not found).
+#CFLAGS += -I/usr/include/kerberos
+
+# Example configuration for various cross-compilation platforms
+
+#### sveasoft (e.g., for Linksys WRT54G) ######################################
+#CC=mipsel-uclibc-gcc
+#CC=/opt/brcm/hndtools-mipsel-uclibc/bin/mipsel-uclibc-gcc
+#CFLAGS += -Os
+#CPPFLAGS += -I../src/include -I../../src/router/openssl/include
+#LIBS += -L/opt/brcm/hndtools-mipsel-uclibc-0.9.19/lib -lssl
+###############################################################################
+
+#### openwrt (e.g., for Linksys WRT54G) #######################################
+#CC=mipsel-uclibc-gcc
+#CC=/opt/brcm/hndtools-mipsel-uclibc/bin/mipsel-uclibc-gcc
+#CFLAGS += -Os
+#CPPFLAGS=-I../src/include -I../openssl-0.9.7d/include \
+#    -I../WRT54GS/release/src/include
+#LIBS = -lssl
+###############################################################################
+
+
+# Driver interface for Host AP driver
+#CONFIG_DRIVER_HOSTAP=y
+
+# Driver interface for Agere driver
+#CONFIG_DRIVER_HERMES=y
+# Change include directories to match with the local setup
+#CFLAGS += -I../../hcf -I../../include -I../../include/hcf
+#CFLAGS += -I../../include/wireless
+
+# Driver interface for madwifi driver
+# Deprecated; use CONFIG_DRIVER_WEXT=y instead.
+#CONFIG_DRIVER_MADWIFI=y
+# Set include directory to the madwifi source tree
+#CFLAGS += -I../../madwifi
+
+# Driver interface for ndiswrapper
+# Deprecated; use CONFIG_DRIVER_WEXT=y instead.
+#CONFIG_DRIVER_NDISWRAPPER=y
+
+# Driver interface for Atmel driver
+#CONFIG_DRIVER_ATMEL=y
+
+# Driver interface for old Broadcom driver
+# Please note that the newer Broadcom driver ("hybrid Linux driver") supports
+# Linux wireless extensions and does not need (or even work) with the old
+# driver wrapper. Use CONFIG_DRIVER_WEXT=y with that driver.
+#CONFIG_DRIVER_BROADCOM=y
+# Example path for wlioctl.h; change to match your configuration
+#CFLAGS += -I/opt/WRT54GS/release/src/include
+
+# Driver interface for Intel ipw2100/2200 driver
+# Deprecated; use CONFIG_DRIVER_WEXT=y instead.
+#CONFIG_DRIVER_IPW=y
+
+# Driver interface for Ralink driver
+#CONFIG_DRIVER_RALINK=y
+
+# Driver interface for generic Linux wireless extensions
+# Note: WEXT is deprecated in the current Linux kernel version and no new
+# functionality is added to it. nl80211-based interface is the new
+# replacement for WEXT and its use allows wpa_supplicant to properly control
+# the driver to improve existing functionality like roaming and to support new
+# functionality.
+CONFIG_DRIVER_WEXT=y
+
+# Driver interface for Linux drivers using the nl80211 kernel interface
+#CONFIG_DRIVER_NL80211=y
+
+# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
+#CONFIG_DRIVER_BSD=y
+#CFLAGS += -I/usr/local/include
+#LIBS += -L/usr/local/lib
+#LIBS_p += -L/usr/local/lib
+#LIBS_c += -L/usr/local/lib
+
+# Driver interface for Windows NDIS
+#CONFIG_DRIVER_NDIS=y
+#CFLAGS += -I/usr/include/w32api/ddk
+#LIBS += -L/usr/local/lib
+# For native build using mingw
+#CONFIG_NATIVE_WINDOWS=y
+# Additional directories for cross-compilation on Linux host for mingw target
+#CFLAGS += -I/opt/mingw/mingw32/include/ddk
+#LIBS += -L/opt/mingw/mingw32/lib
+#CC=mingw32-gcc
+# By default, driver_ndis uses WinPcap for low-level operations. This can be
+# replaced with the following option which replaces WinPcap calls with NDISUIO.
+# However, this requires that WZC is disabled (net stop wzcsvc) before starting
+# wpa_supplicant.
+# CONFIG_USE_NDISUIO=y
+
+# Driver interface for development testing
+#CONFIG_DRIVER_TEST=y
+
+# Include client MLME (management frame processing) for test driver
+# This can be used to test MLME operations in hostapd with the test interface.
+# space.
+#CONFIG_CLIENT_MLME=y
+
+# Driver interface for wired Ethernet drivers
+#CONFIG_DRIVER_WIRED=y
+
+# Driver interface for the Broadcom RoboSwitch family
+#CONFIG_DRIVER_ROBOSWITCH=y
+
+# Driver interface for no driver (e.g., WPS ER only)
+#CONFIG_DRIVER_NONE=y
+
+# Solaris libraries
+#LIBS += -lsocket -ldlpi -lnsl
+#LIBS_c += -lsocket
+
+# Enable IEEE 802.1X Supplicant (automatically included if any EAP method is
+# included)
+CONFIG_IEEE8021X_EAPOL=y
+
+# EAP-MD5
+CONFIG_EAP_MD5=y
+
+# EAP-MSCHAPv2
+CONFIG_EAP_MSCHAPV2=y
+
+# EAP-TLS
+CONFIG_EAP_TLS=y
+
+# EAL-PEAP
+CONFIG_EAP_PEAP=y
+
+# EAP-TTLS
+CONFIG_EAP_TTLS=y
+
+# EAP-FAST
+# Note: Default OpenSSL package does not include support for all the
+# functionality needed for EAP-FAST. If EAP-FAST is enabled with OpenSSL,
+# the OpenSSL library must be patched (openssl-0.9.8d-tls-extensions.patch)
+# to add the needed functions.
+#CONFIG_EAP_FAST=y
+
+# EAP-GTC
+CONFIG_EAP_GTC=y
+
+# EAP-OTP
+CONFIG_EAP_OTP=y
+
+# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used)
+#CONFIG_EAP_SIM=y
+
+# EAP-PSK (experimental; this is _not_ needed for WPA-PSK)
+#CONFIG_EAP_PSK=y
+
+# EAP-PAX
+#CONFIG_EAP_PAX=y
+
+# LEAP
+CONFIG_EAP_LEAP=y
+
+# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used)
+#CONFIG_EAP_AKA=y
+
+# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used).
+# This requires CONFIG_EAP_AKA to be enabled, too.
+#CONFIG_EAP_AKA_PRIME=y
+
+# Enable USIM simulator (Milenage) for EAP-AKA
+#CONFIG_USIM_SIMULATOR=y
+
+# EAP-SAKE
+#CONFIG_EAP_SAKE=y
+
+# EAP-GPSK
+#CONFIG_EAP_GPSK=y
+# Include support for optional SHA256 cipher suite in EAP-GPSK
+#CONFIG_EAP_GPSK_SHA256=y
+
+# EAP-TNC and related Trusted Network Connect support (experimental)
+#CONFIG_EAP_TNC=y
+
+# Wi-Fi Protected Setup (WPS)
+CONFIG_WPS=y
+# Enable WSC 2.0 support
+CONFIG_WPS2=y
+# Enable WPS external registrar functionality
+#CONFIG_WPS_ER=y
+
+# EAP-IKEv2
+#CONFIG_EAP_IKEV2=y
+
+# PKCS#12 (PFX) support (used to read private key and certificate file from
+# a file that usually has extension .p12 or .pfx)
+CONFIG_PKCS12=y
+
+# Smartcard support (i.e., private key on a smartcard), e.g., with openssl
+# engine.
+CONFIG_SMARTCARD=y
+
+# PC/SC interface for smartcards (USIM, GSM SIM)
+# Enable this if EAP-SIM or EAP-AKA is included
+#CONFIG_PCSC=y
+
+# Development testing
+#CONFIG_EAPOL_TEST=y
+
+# Select control interface backend for external programs, e.g, wpa_cli:
+# unix = UNIX domain sockets (default for Linux/*BSD)
+# udp = UDP sockets using localhost (127.0.0.1)
+# named_pipe = Windows Named Pipe (default for Windows)
+# y = use default (backwards compatibility)
+# If this option is commented out, control interface is not included in the
+# build.
+CONFIG_CTRL_IFACE=y
+
+# Include support for GNU Readline and History Libraries in wpa_cli.
+# When building a wpa_cli binary for distribution, please note that these
+# libraries are licensed under GPL and as such, BSD license may not apply for
+# the resulting binary.
+#CONFIG_READLINE=y
+
+# Include internal line edit mode in wpa_cli. This can be used as a replacement
+# for GNU Readline to provide limited command line editing and history support.
+#CONFIG_WPA_CLI_EDIT=y
+
+# Remove debugging code that is printing out debug message to stdout.
+# This can be used to reduce the size of the wpa_supplicant considerably
+# if debugging code is not needed. The size reduction can be around 35%
+# (e.g., 90 kB).
+#CONFIG_NO_STDOUT_DEBUG=y
+
+# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save
+# 35-50 kB in code size.
+#CONFIG_NO_WPA=y
+
+# Remove WPA2 support. This allows WPA to be used, but removes WPA2 code to
+# save about 1 kB in code size when building only WPA-Personal (no EAP support)
+# or 6 kB if building for WPA-Enterprise.
+#CONFIG_NO_WPA2=y
+
+# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support
+# This option can be used to reduce code size by removing support for
+# converting ASCII passphrases into PSK. If this functionality is removed, the
+# PSK can only be configured as the 64-octet hexstring (e.g., from
+# wpa_passphrase). This saves about 0.5 kB in code size.
+#CONFIG_NO_WPA_PASSPHRASE=y
+
+# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
+# This can be used if ap_scan=1 mode is never enabled.
+#CONFIG_NO_SCAN_PROCESSING=y
+
+# Select configuration backend:
+# file = text file (e.g., wpa_supplicant.conf; note: the configuration file
+#    path is given on command line, not here; this option is just used to
+#    select the backend that allows configuration files to be used)
+# winreg = Windows registry (see win_example.reg for an example)
+CONFIG_BACKEND=file
+
+# Remove configuration write functionality (i.e., to allow the configuration
+# file to be updated based on runtime configuration changes). The runtime
+# configuration can still be changed, the changes are just not going to be
+# persistent over restarts. This option can be used to reduce code size by
+# about 3.5 kB.
+#CONFIG_NO_CONFIG_WRITE=y
+
+# Remove support for configuration blobs to reduce code size by about 1.5 kB.
+#CONFIG_NO_CONFIG_BLOBS=y
+
+# Select program entry point implementation:
+# main = UNIX/POSIX like main() function (default)
+# main_winsvc = Windows service (read parameters from registry)
+# main_none = Very basic example (development use only)
+#CONFIG_MAIN=main
+
+# Select wrapper for operatins system and C library specific functions
+# unix = UNIX/POSIX like systems (default)
+# win32 = Windows systems
+# none = Empty template
+#CONFIG_OS=unix
+
+# Select event loop implementation
+# eloop = select() loop (default)
+# eloop_win = Windows events and WaitForMultipleObject() loop
+# eloop_none = Empty template
+#CONFIG_ELOOP=eloop
+
+# Select layer 2 packet implementation
+# linux = Linux packet socket (default)
+# pcap = libpcap/libdnet/WinPcap
+# freebsd = FreeBSD libpcap
+# winpcap = WinPcap with receive thread
+# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y)
+# none = Empty template
+#CONFIG_L2_PACKET=linux
+
+# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
+CONFIG_PEERKEY=y
+
+# IEEE 802.11w (management frame protection)
+# This version is an experimental implementation based on IEEE 802.11w/D1.0
+# draft and is subject to change since the standard has not yet been finalized.
+# Driver support is also needed for IEEE 802.11w.
+#CONFIG_IEEE80211W=y
+
+# Select TLS implementation
+# openssl = OpenSSL (default)
+# gnutls = GnuTLS (needed for TLS/IA, see also CONFIG_GNUTLS_EXTRA)
+# internal = Internal TLSv1 implementation (experimental)
+# none = Empty template
+#CONFIG_TLS=openssl
+CONFIG_TLS=internal
+
+# Whether to enable TLS/IA support, which is required for EAP-TTLSv1.
+# You need CONFIG_TLS=gnutls for this to have any effect. Please note that
+# even though the core GnuTLS library is released under LGPL, this extra
+# library uses GPL and as such, the terms of GPL apply to the combination
+# of wpa_supplicant and GnuTLS if this option is enabled. BSD license may not
+# apply for distribution of the resulting binary.
+#CONFIG_GNUTLS_EXTRA=y
+
+# If CONFIG_TLS=internal is used, additional library and include paths are
+# needed for LibTomMath. Alternatively, an integrated, minimal version of
+# LibTomMath can be used. See beginning of libtommath.c for details on benefits
+# and drawbacks of this option.
+CONFIG_INTERNAL_LIBTOMMATH=y
+#ifndef CONFIG_INTERNAL_LIBTOMMATH
+#LTM_PATH=/usr/src/libtommath-0.39
+#CFLAGS += -I$(LTM_PATH)
+#LIBS += -L$(LTM_PATH)
+#LIBS_p += -L$(LTM_PATH)
+#endif
+# At the cost of about 4 kB of additional binary size, the internal LibTomMath
+# can be configured to include faster routines for exptmod, sqr, and div to
+# speed up DH and RSA calculation considerably
+CONFIG_INTERNAL_LIBTOMMATH_FAST=y
+
+# Include NDIS event processing through WMI into wpa_supplicant/wpasvc.
+# This is only for Windows builds and requires WMI-related header files and
+# WbemUuid.Lib from Platform SDK even when building with MinGW.
+#CONFIG_NDIS_EVENTS_INTEGRATED=y
+#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
+
+# Add support for old DBus control interface
+# (fi.epitest.hostap.WPASupplicant)
+#CONFIG_CTRL_IFACE_DBUS=y
+
+# Add support for new DBus control interface
+# (fi.w1.hostap.wpa_supplicant1)
+#CONFIG_CTRL_IFACE_DBUS_NEW=y
+
+# Add introspection support for new DBus control interface
+#CONFIG_CTRL_IFACE_DBUS_INTRO=y
+
+# Add support for loading EAP methods dynamically as shared libraries.
+# When this option is enabled, each EAP method can be either included
+# statically (CONFIG_EAP_<method>=y) or dynamically (CONFIG_EAP_<method>=dyn).
+# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to
+# be loaded in the beginning of the wpa_supplicant configuration file
+# (see load_dynamic_eap parameter in the example file) before being used in
+# the network blocks.
+#
+# Note that some shared parts of EAP methods are included in the main program
+# and in order to be able to use dynamic EAP methods using these parts, the
+# main program must have been build with the EAP method enabled (=y or =dyn).
+# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries
+# unless at least one of them was included in the main build to force inclusion
+# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included
+# in the main build to be able to load these methods dynamically.
+#
+# Please also note that using dynamic libraries will increase the total binary
+# size. Thus, it may not be the best option for targets that have limited
+# amount of memory/flash.
+#CONFIG_DYNAMIC_EAP_METHODS=y
+
+# IEEE Std 802.11r-2008 (Fast BSS Transition)
+#CONFIG_IEEE80211R=y
+
+# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
+#CONFIG_DEBUG_FILE=y
+
+# Send debug messages to syslog instead of stdout
+#CONFIG_DEBUG_SYSLOG=y
+# Set syslog facility for debug messages
+#CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
+
+# Enable privilege separation (see README 'Privilege separation' for details)
+#CONFIG_PRIVSEP=y
+
+# Enable mitigation against certain attacks against TKIP by delaying Michael
+# MIC error reports by a random amount of time between 0 and 60 seconds
+#CONFIG_DELAYED_MIC_ERROR_REPORT=y
+
+# Enable tracing code for developer debugging
+# This tracks use of memory allocations and other registrations and reports
+# incorrect use with a backtrace of call (or allocation) location.
+#CONFIG_WPA_TRACE=y
+# For BSD, comment out these.
+#LIBS += -lexecinfo
+#LIBS_p += -lexecinfo
+#LIBS_c += -lexecinfo
+
+# Use libbfd to get more details for developer debugging
+# This enables use of libbfd to get more detailed symbols for the backtraces
+# generated by CONFIG_WPA_TRACE=y.
+#CONFIG_WPA_TRACE_BFD=y
+# For BSD, comment out these.
+#LIBS += -lbfd -liberty -lz
+#LIBS_p += -lbfd -liberty -lz
+#LIBS_c += -lbfd -liberty -lz
+
+# wpa_supplicant depends on strong random number generation being available
+# from the operating system. os_get_random() function is used to fetch random
+# data when needed, e.g., for key generation. On Linux and BSD systems, this
+# works by reading /dev/urandom. It should be noted that the OS entropy pool
+# needs to be properly initialized before wpa_supplicant is started. This is
+# important especially on embedded devices that do not have a hardware random
+# number generator and may by default start up with minimal entropy available
+# for random number generation.
+#
+# As a safety net, wpa_supplicant is by default trying to internally collect
+# additional entropy for generating random data to mix in with the data fetched
+# from the OS. This by itself is not considered to be very strong, but it may
+# help in cases where the system pool is not initialized properly. However, it
+# is very strongly recommended that the system pool is initialized with enough
+# entropy either by using hardware assisted random number generator or by
+# storing state over device reboots.
+#
+# wpa_supplicant can be configured to maintain its own entropy store over
+# restarts to enhance random number generation. This is not perfect, but it is
+# much more secure than using the same sequence of random numbers after every
+# reboot. This can be enabled with -e<entropy file> command line option. The
+# specified file needs to be readable and writable by wpa_supplicant.
+#
+# If the os_get_random() is known to provide strong random data (e.g., on
+# Linux/BSD, the board in question is known to have reliable source of random
+# data from /dev/urandom), the internal wpa_supplicant random pool can be
+# disabled. This will save some in binary size and CPU use. However, this
+# should only be considered for builds that are known to be used on devices
+# that meet the requirements described above.
+#CONFIG_NO_RANDOM_POOL=y
+
+# IEEE 802.11n (High Throughput) support (mainly for AP mode)
+#CONFIG_IEEE80211N=y

Re: Lantiq XWAY WAVE300

I've tried to port it by my own but unfortunately my knowledge is way to small to do so.

Anyone can help ?

Re: Lantiq XWAY WAVE300

Refreshing topic.

Driver Source Code in link https://www.dropbox.com/s/0tg0krp4rwt8e7g/lq-wave-300-03.01.00.12.31.09.58ada131737d.src.tar.gz

Re: Lantiq XWAY WAVE300

Refreshing topic!

The driver ports well to 3.3.8 kernel, nedds little changes.
On newer kernels 3.8+ you have to patch /proc subsystem control.

The source needs some patching - firstly you have to link rflib.a with kernel module.

To run the radio you need firmware and calibration data,
everything is here http://speedy.sh/S3Sdg/mtlk-fw.7z

You have to select if you want to work ONLY in master or managed mode (simultaneous work is NOT possible), when loading module. Everything is controlled with wireless-tools, and driver is incompatible with mac80211.

Re: Lantiq XWAY WAVE300

lpm11 wrote:

Refreshing topic!
You have to select if you want to work ONLY in master or managed mode (simultaneous work is NOT possible), when loading module. Everything is controlled with wireless-tools, and driver is incompatible with mac80211.

The driver uses WEXT or any other API instead nl802111? Bad news...

Re: Lantiq XWAY WAVE300

More bad news:

This driver doesn't support VAPs too. It can only work as a one client or as an one AP. WDS is also possible, but not compatible with other devices. There is closed source module kernel for 2.6.21, with VAPs, 2 times bigger.

9 (edited by lpm11 2014-02-07 11:33:07)

Re: Lantiq XWAY WAVE300

Finally driver 3.1 works as AP (needed patch for hostapd was included in this topic), and original wpa_supplicant is working with wext (but this from OpenWRT does nothing - it is NOT WORKING).

Driver doesn't know what clients are connected, knows nothing about power from STA and transmit rates. It can NOT control the transmit power. If you disable Automatic Channel Selection (?) the driver will panic kernel.
mdk3 tool managed to crash the system.
Interface seems to be great (debug and memleak tools, controling parameters via iwpriv - looks good).... rather was for 2007 year. Driver is complicated: you have two firmwares, one for 802.11 low layer, some radio calibration data and closed-source RFlib. Then some abstraction layers, ioctl codes for linux and wireless tools and some other routines.
Transmit rates are funny. The maximum I got was about 16 Mb/s (20MHz bandwidth). The same for Open and WPA2
Moreover - it uses 100% CPU. You have no Ad-Hoc, mesh, nor monitor mode. You can also forget about VAP.
One of the worst drivers I have ever seen, just outdated shit produced by Israel. It seems that they have labs and (hopefully) not released many wireless chipsets.

The 3.1 driver(only one with partially released source) is a REALLY piece of shit. 3.2 driver is not released publicly, and we have only binary bloobs. Very dirty work for now. Both driver use the 100% CPU, and make device very hot. WLAN driver is crashing when you try to unload it with connected clients. After some times it denies ANY authentication. It is extremely unstable with low distance (can crash other devices), seems to be stable at larger distance - but upload speed (client -> Wave 300 AP) is about 1Mbit (Mb/s not MB/s)

Now, OpenWRT recognises this WiFi interface, and allows to set basic parameters. Patch is needed to enable WPA in LUCI web interface. The monitor secion is empty - no information at all (wireless is visible as turned off). It is NOT possible to receiver information about signal levels, only packets from associated clients. EEPROM is visible and readable, but it contains nothing (my Wave300 starts with MAC 00:**:**:00:00:00)

I can send everything needed to run on OpenWRT as I described above.