diff options
Diffstat (limited to 'package/hostap-driver')
-rw-r--r-- | package/hostap-driver/Makefile | 117 | ||||
-rwxr-xr-x | package/hostap-driver/files/lib/wifi/hostap.sh | 270 | ||||
-rw-r--r-- | package/hostap-driver/patches/001-fix-txpower.patch | 175 |
3 files changed, 562 insertions, 0 deletions
diff --git a/package/hostap-driver/Makefile b/package/hostap-driver/Makefile new file mode 100644 index 000000000..d08fd9c0a --- /dev/null +++ b/package/hostap-driver/Makefile @@ -0,0 +1,117 @@ +# +# Copyright (C) 2006-2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=hostap-driver +PKG_VERSION:=0.4.9 +PKG_RELEASE:=2 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://hostap.epitest.fi/releases/ +PKG_MD5SUM:=c7534dc040ab90218257a78488ecd378 + +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/hostap/Default + VERSION:=$(LINUX_VERSION)-$(BOARD)-$(PKG_RELEASE) + SUBMENU:=Wireless Drivers + URL:=http://hostap.epitest.fi/ +endef + +define KernelPackage/hostap/Default/description + Host AP is a driver for 802.11b wireless cards based on Intersil + Prism2/2.5/3 chipset. It supports so called Host AP mode that allows the + card to act as an IEEE 802.11 access point. +endef + + +define KernelPackage/hostap +$(call KernelPackage/hostap/Default) + TITLE:=Host AP support for Prism2/2.5/3 + DEPENDS:=@PCI_SUPPORT||PCMCIA_SUPPORT +kmod-lib80211 +wireless-tools + KCONFIG:=CONFIG_HOSTAP CONFIG_HOSTAP_FIRMWARE=y CONFIG_HOSTAP_FIRMWARE_NVRAM=y + FILES:=$(LINUX_DIR)/drivers/net/wireless/hostap/hostap.ko + AUTOLOAD:=$(call AutoLoad,60,hostap) +endef + +define KernelPackage/hostap/description +$(call KernelPackage/hostap/Default/description) + This package contains the base Host AP driver code that is shared by + different hardware models. You will also need to enable support for + PLX/PCI/CS version of the driver to actually use the driver. +endef + + +define KernelPackage/hostap-cs +$(call KernelPackage/hostap/Default) + TITLE:=Host AP driver for PCMCIA adaptors + DEPENDS:=@PCMCIA_SUPPORT +kmod-hostap +kmod-pcmcia-core + KCONFIG:=CONFIG_HOSTAP_CS + FILES:=$(LINUX_DIR)/drivers/net/wireless/hostap/hostap_cs.ko + AUTOLOAD:=$(call AutoLoad,60,hostap_cs) +endef + +define KernelPackage/hostap-cs/description +$(call KernelPackage/hostap/Default/description) + This package contains the Host AP driver for Prism2/2.5/3 PC cards. +endef + + +define KernelPackage/hostap-pci +$(call KernelPackage/hostap/Default) + TITLE:=Host AP driver for PCI adaptors + DEPENDS:=@PCI_SUPPORT +kmod-hostap + KCONFIG:=CONFIG_HOSTAP_PCI + FILES:=$(LINUX_DIR)/drivers/net/wireless/hostap/hostap_pci.ko + AUTOLOAD:=$(call AutoLoad,60,hostap_pci) +endef + +define KernelPackage/hostap-pci/description +$(call KernelPackage/hostap/Default/description) + This package contains the Host AP driver for Prism2.5 PCI adaptors. +endef + + +define KernelPackage/hostap-plx +$(call KernelPackage/hostap/Default) + TITLE:=Host AP driver for PLX9052 based PCI adaptors + DEPENDS:=@PCI_SUPPORT +kmod-hostap + KCONFIG:=CONFIG_HOSTAP_PLX + FILES:=$(LINUX_DIR)/drivers/net/wireless/hostap/hostap_plx.ko + AUTOLOAD:=$(call AutoLoad,60,hostap_plx) +endef + +define KernelPackage/hostap-plx/description +$(call KernelPackage/hostap/Default/description) + This package contains the Host AP driver for Prism2/2.5/3 in PLX9052 + based PCI adaptors. +endef + + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Configure + +endef + +define Build/Compile + +endef + +define KernelPackage/hostap/install + $(INSTALL_DIR) $(1)/lib/wifi + $(INSTALL_DATA) ./files/lib/wifi/hostap.sh $(1)/lib/wifi +endef + +$(eval $(call KernelPackage,hostap)) +$(eval $(call KernelPackage,hostap-cs)) +$(eval $(call KernelPackage,hostap-pci)) +$(eval $(call KernelPackage,hostap-plx)) diff --git a/package/hostap-driver/files/lib/wifi/hostap.sh b/package/hostap-driver/files/lib/wifi/hostap.sh new file mode 100755 index 000000000..62d2e7e47 --- /dev/null +++ b/package/hostap-driver/files/lib/wifi/hostap.sh @@ -0,0 +1,270 @@ +#!/bin/sh +append DRIVERS "prism2" + +find_prism2_phy() { + local device="$1" + + local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')" + config_get phy "$device" phy + [ -z "$phy" -a -n "$macaddr" ] && { + cd /proc/net/hostap + for phy in $(ls -d wlan* 2>&-); do + [ "$macaddr" = "$(cat /sys/class/net/${phy}/address)" ] || continue + config_set "$device" phy "$phy" + break + done + config_get phy "$device" phy + } + [ -n "$phy" -a -d "/proc/net/hostap/$phy" ] || { + echo "phy for wifi device $1 not found" + return 1 + } + [ -z "$macaddr" ] && { + config_set "$device" macaddr "$(cat /sys/class/net/${phy}/address)" + } + return 0 +} + +scan_prism2() { + local device="$1" + local mainvif + local wds + + [ ${device%[0-9]} = "wlan" ] && config_set "$device" phy "$device" || find_prism2_phy "$device" || { + config_unset "$device" vifs + return 0 + } + config_get phy "$device" phy + + config_get vifs "$device" vifs + local _c=0 + for vif in $vifs; do + config_get_bool disabled "$vif" disabled 0 + [ $disabled = 0 ] || continue + + config_get mode "$vif" mode + case "$mode" in + adhoc|sta|ap|monitor) + # Only one vif is allowed on AP, station, Ad-hoc or monitor mode + [ -z "$mainvif" ] && { + mainvif="$vif" + config_set "$vif" ifname "$phy" + } + ;; + wds) + config_get ssid "$vif" ssid + [ -z "$ssid" ] && continue + config_set "$vif" ifname "${phy}wds${_c}" + _c=$(($_c + 1)) + addr="$ssid" + ${addr:+append wds "$vif"} + ;; + *) echo "$device($vif): Invalid mode, ignored."; continue;; + esac + done + config_set "$device" vifs "${mainvif:+$mainvif }${wds:+$wds}" +} + +disable_prism2() ( + local device="$1" + + find_prism2_phy "$device" || return 0 + config_get phy "$device" phy + + set_wifi_down "$device" + + include /lib/network + while read line < /proc/net/hostap/${phy}/wds; do + set $line + [ -f "/var/run/wifi-${1}.pid" ] && + kill "$(cat "/var/run/wifi-${1}.pid")" + ifconfig "$1" down + unbridge "$1" + iwpriv "$phy" wds_del "$2" + done + unbridge "$phy" + return 0 +) + +enable_prism2() { + local device="$1" + + find_prism2_phy "$device" || return 0 + config_get phy "$device" phy + + config_get rxantenna "$device" rxantenna + config_get txantenna "$device" txantenna + config_get_bool diversity "$device" diversity + [ -n "$diversity" ] && { + rxantenna="1" + txantenna="1" + } + [ -n "$rxantenna" ] && iwpriv "$phy" antsel_rx "$rxantenna" + [ -n "$txantenna" ] && iwpriv "$phy" antsel_tx "$txantenna" + + config_get channel "$device" channel + [ -n "$channel" ] && iwconfig "$phy" channel "$channel" >/dev/null 2>/dev/null + + config_get txpower "$device" txpower + [ -n "$txpower" ] && iwconfig "$phy" txpower "${txpower%%.*}" + + config_get vifs "$device" vifs + local first=1 + for vif in $vifs; do + config_get ifname "$vif" ifname + config_get ssid "$vif" ssid + config_get mode "$vif" mode + + [ "$mode" = "wds" ] || iwconfig "$phy" essid ${ssid:+-- }"${ssid:-any}" + + case "$mode" in + sta) + iwconfig "$phy" mode managed + config_get addr "$device" bssid + [ -z "$addr" ] || { + iwconfig "$phy" ap "$addr" + } + ;; + ap) iwconfig "$phy" mode master;; + wds) iwpriv "$phy" wds_add "$ssid";; + adhoc) iwconfig "$phy" mode ad-hoc;; + *) iwconfig "$phy" mode "$mode";; + esac + + [ "$first" = 1 ] && { + config_get rate "$vif" rate + [ -n "$rate" ] && iwconfig "$phy" rate "${rate%%.*}" + + config_get_bool hidden "$vif" hidden 0 + iwpriv "$phy" enh_sec "$hidden" + + config_get frag "$vif" frag + [ -n "$frag" ] && iwconfig "$phy" frag "${frag%%.*}" + + config_get rts "$vif" rts + [ -n "$rts" ] && iwconfig "$phy" rts "${rts%%.*}" + + config_get maclist "$vif" maclist + [ -n "$maclist" ] && { + # flush MAC list + iwpriv "$phy" maccmd 3 + for mac in $maclist; do + iwpriv "$phy" addmac "$mac" + done + } + config_get macpolicy "$vif" macpolicy + case "$macpolicy" in + allow) + iwpriv "$phy" maccmd 2 + ;; + deny) + iwpriv "$phy" maccmd 1 + ;; + *) + # default deny policy if mac list exists + [ -n "$maclist" ] && iwpriv "$phy" maccmd 1 + ;; + esac + # kick all stations if we have policy explicitly set + [ -n "$macpolicy" ] && iwpriv "$phy" maccmd 4 + } + + config_get enc "$vif" encryption + case "$enc" in + WEP|wep) + for idx in 1 2 3 4; do + config_get key "$vif" "key${idx}" + iwconfig "$ifname" enc "[$idx]" "${key:-off}" + done + config_get key "$vif" key + key="${key:-1}" + case "$key" in + [1234]) iwconfig "$ifname" enc "[$key]";; + *) iwconfig "$ifname" enc "$key";; + esac + ;; + psk*|wpa*) + start_hostapd=1 + config_get key "$vif" key + ;; + esac + + local net_cfg bridge + net_cfg="$(find_net_config "$vif")" + [ -z "$net_cfg" ] || { + bridge="$(bridge_interface "$net_cfg")" + config_set "$vif" bridge "$bridge" + start_net "$ifname" "$net_cfg" + } + set_wifi_up "$vif" "$ifname" + + case "$mode" in + ap) + if [ -n "$start_hostapd" ] && eval "type hostapd_setup_vif" 2>/dev/null >/dev/null; then + hostapd_setup_vif "$vif" hostap || { + echo "enable_prism2($device): Failed to set up hostapd for interface $ifname" >&2 + # make sure this wifi interface won't accidentally stay open without encryption + ifconfig "$ifname" down + continue + } + fi + ;; + wds|sta) + if eval "type wpa_supplicant_setup_vif" 2>/dev/null >/dev/null; then + wpa_supplicant_setup_vif "$vif" wext || { + echo "enable_prism2($device): Failed to set up wpa_supplicant for interface $ifname" >&2 + ifconfig "$ifname" down + continue + } + fi + ;; + esac + first=0 + done + +} + +check_prism2_device() { + [ ${1%[0-9]} = "wlan" ] && config_set "$1" phy "$1" + config_get phy "$1" phy + [ -z "$phy" ] && { + find_prism2_phy "$1" >/dev/null || return 0 + config_get phy "$1" phy + } + [ "$phy" = "$dev" ] && found=1 +} + +detect_prism2() { + devidx=0 + config_load wireless + while :; do + config_get type "radio$devidx" type + [ -n "$type" ] || break + devidx=$(($devidx + 1)) + done + cd /proc/net/hostap + [ -d wlan* ] || return + for dev in $(ls -d wlan* 2>&-); do + found=0 + config_foreach check_prism2_device wifi-device + [ "$found" -gt 0 ] && continue + cat <<EOF +config wifi-device radio$devidx + option type prism2 + option channel 11 + option macaddr $(cat /sys/class/net/${dev}/address) + + # REMOVE THIS LINE TO ENABLE WIFI: + option disabled 1 + +config wifi-iface + option device radio$devidx + option network lan + option mode ap + option ssid OpenWrt + option encryption none + +EOF + devidx=$(($devidx + 1)) + done +} diff --git a/package/hostap-driver/patches/001-fix-txpower.patch b/package/hostap-driver/patches/001-fix-txpower.patch new file mode 100644 index 000000000..94ca34494 --- /dev/null +++ b/package/hostap-driver/patches/001-fix-txpower.patch @@ -0,0 +1,175 @@ +diff -Naur hostap-driver-0.3.7/driver/modules/hostap.c hostap-driver-0.3.7-patched/driver/modules/hostap.c +--- hostap-driver-0.3.7/driver/modules/hostap.c 2004-08-28 06:26:46.000000000 +0300 ++++ hostap-driver-0.3.7-patched/driver/modules/hostap.c 2005-04-20 17:20:56.000000000 +0300 +@@ -1164,6 +1164,36 @@ + return ret; + } + ++/* BUG FIX: Restore power setting value when lost due to F/W bug */ ++ ++int hostap_restore_power(struct net_device *dev) ++{ ++ struct hostap_interface *iface = dev->priv; ++ local_info_t *local = iface->local; ++ ++ u16 val; ++ int ret = 0; ++ ++ if (local->txpower_type == PRISM2_TXPOWER_OFF) { ++ val = 0xff; /* use all standby and sleep modes */ ++ ret = local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF, ++ HFA386X_CR_A_D_TEST_MODES2, ++ &val, NULL); ++ } ++ ++#ifdef RAW_TXPOWER_SETTING ++ if (local->txpower_type == PRISM2_TXPOWER_FIXED) { ++ val = HFA384X_TEST_CFG_BIT_ALC; ++ local->func->cmd(dev, HFA384X_CMDCODE_TEST | ++ (HFA384X_TEST_CFG_BITS << 8), 0, &val, NULL); ++ val = prism2_txpower_dBm_to_hfa386x(local->txpower); ++ ret = (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF, ++ HFA386X_CR_MANUAL_TX_POWER, &val, NULL)); ++ } ++#endif /* RAW_TXPOWER_SETTING */ ++ return (ret ? -EOPNOTSUPP : 0); ++} ++ + + struct proc_dir_entry *hostap_proc; + +@@ -1214,6 +1244,7 @@ + EXPORT_SYMBOL(hostap_set_hostapd_sta); + EXPORT_SYMBOL(hostap_add_interface); + EXPORT_SYMBOL(hostap_remove_interface); ++EXPORT_SYMBOL(hostap_restore_power); + EXPORT_SYMBOL(prism2_update_comms_qual); + + module_init(hostap_init); +diff -Naur hostap-driver-0.3.7/driver/modules/hostap.h hostap-driver-0.3.7-patched/driver/modules/hostap.h +--- hostap-driver-0.3.7/driver/modules/hostap.h 2003-11-30 04:14:26.000000000 +0200 ++++ hostap-driver-0.3.7-patched/driver/modules/hostap.h 2005-04-20 17:21:23.000000000 +0300 +@@ -36,6 +36,7 @@ + const char *prefix, const char *name); + void hostap_remove_interface(struct net_device *dev, int rtnl_locked, + int remove_from_list); ++int hostap_restore_power(struct net_device *dev); + int prism2_update_comms_qual(struct net_device *dev); + int prism2_sta_send_mgmt(local_info_t *local, u8 *dst, u8 stype, + u8 *body, size_t bodylen); +diff -Naur hostap-driver-0.3.7/driver/modules/hostap_ap.c hostap-driver-0.3.7-patched/driver/modules/hostap_ap.c +--- hostap-driver-0.3.7/driver/modules/hostap_ap.c 2005-01-24 04:52:00.000000000 +0200 ++++ hostap-driver-0.3.7-patched/driver/modules/hostap_ap.c 2005-04-21 20:06:12.000000000 +0300 +@@ -2346,13 +2346,13 @@ + addr[count].sa_family = ARPHRD_ETHER; + memcpy(addr[count].sa_data, sta->addr, ETH_ALEN); + if (sta->last_rx_silence == 0) +- qual[count].qual = sta->last_rx_signal < 27 ? +- 0 : (sta->last_rx_signal - 27) * 92 / 127; ++ qual[count].qual = (sta->last_rx_signal - 156) == 0 ? ++ 0 : (sta->last_rx_signal - 156) * 92 / 64; + else +- qual[count].qual = sta->last_rx_signal - +- sta->last_rx_silence - 35; +- qual[count].level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal); +- qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence); ++ qual[count].qual = (sta->last_rx_signal - ++ sta->last_rx_silence) * 92 / 64; ++ qual[count].level = sta->last_rx_signal; ++ qual[count].noise = sta->last_rx_silence; + qual[count].updated = sta->last_rx_updated; + + sta->last_rx_updated = 0; +@@ -2413,13 +2413,13 @@ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVQUAL; + if (sta->last_rx_silence == 0) +- iwe.u.qual.qual = sta->last_rx_signal < 27 ? +- 0 : (sta->last_rx_signal - 27) * 92 / 127; ++ iwe.u.qual.qual = (sta->last_rx_signal -156) == 0 ? ++ 0 : (sta->last_rx_signal - 156) * 92 / 64; + else +- iwe.u.qual.qual = sta->last_rx_signal - +- sta->last_rx_silence - 35; +- iwe.u.qual.level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal); +- iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence); ++ iwe.u.qual.qual = (sta->last_rx_signal - ++ sta->last_rx_silence) * 92 / 64; ++ iwe.u.qual.level = sta->last_rx_signal; ++ iwe.u.qual.noise = sta->last_rx_silence; + iwe.u.qual.updated = sta->last_rx_updated; + iwe.len = IW_EV_QUAL_LEN; + current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, +diff -Naur hostap-driver-0.3.7/driver/modules/hostap_config.h hostap-driver-0.3.7-patched/driver/modules/hostap_config.h +--- hostap-driver-0.3.7/driver/modules/hostap_config.h 2005-02-12 18:12:56.000000000 +0200 ++++ hostap-driver-0.3.7-patched/driver/modules/hostap_config.h 2005-04-20 17:25:23.000000000 +0300 +@@ -94,6 +94,12 @@ + */ + /* #define PRISM2_NO_STATION_MODES */ + ++/* Enable TX power Setting functions ++ * (min att = -128 , max att = 127) ++ */ ++ ++#define RAW_TXPOWER_SETTING ++ + /* Use Linux crypto API instead of own encryption implementation whenever + * possible. */ + /* #define HOSTAP_USE_CRYPTO_API */ +diff -Naur hostap-driver-0.3.7/driver/modules/hostap_hw.c hostap-driver-0.3.7-patched/driver/modules/hostap_hw.c +--- hostap-driver-0.3.7/driver/modules/hostap_hw.c 2005-02-05 09:20:09.000000000 +0200 ++++ hostap-driver-0.3.7-patched/driver/modules/hostap_hw.c 2005-04-20 17:25:55.000000000 +0300 +@@ -1039,6 +1039,7 @@ + dev->name, local->fragm_threshold); + } + ++ hostap_restore_power(dev); + return res; + } + +diff -Naur hostap-driver-0.3.7/driver/modules/hostap_info.c hostap-driver-0.3.7-patched/driver/modules/hostap_info.c +--- hostap-driver-0.3.7/driver/modules/hostap_info.c 2004-02-29 20:05:44.000000000 +0200 ++++ hostap-driver-0.3.7-patched/driver/modules/hostap_info.c 2005-04-20 17:26:36.000000000 +0300 +@@ -418,6 +418,11 @@ + } + + /* Get BSSID if we have a valid AP address */ ++ ++ if ( val == HFA384X_LINKSTATUS_CONNECTED || ++ val == HFA384X_LINKSTATUS_DISCONNECTED ) ++ hostap_restore_power(local->dev); ++ + if (connected) { + netif_carrier_on(local->dev); + netif_carrier_on(local->ddev); +diff -Naur hostap-driver-0.3.7/driver/modules/hostap_ioctl.c hostap-driver-0.3.7-patched/driver/modules/hostap_ioctl.c +--- hostap-driver-0.3.7/driver/modules/hostap_ioctl.c 2004-11-22 08:03:05.000000000 +0200 ++++ hostap-driver-0.3.7-patched/driver/modules/hostap_ioctl.c 2005-04-20 17:42:41.000000000 +0300 +@@ -1453,23 +1453,20 @@ + val = 255; + + tmp = val; +- tmp >>= 2; + +- return -12 - tmp; ++ return tmp; + } + + static u16 prism2_txpower_dBm_to_hfa386x(int val) + { + signed char tmp; + +- if (val > 20) +- return 128; +- else if (val < -43) ++ if (val > 127) + return 127; ++ else if (val < -128) ++ return 128; + + tmp = val; +- tmp = -12 - tmp; +- tmp <<= 2; + + return (unsigned char) tmp; + } |