diff options
-rw-r--r-- | package/hostap-driver/Makefile | 11 | ||||
-rwxr-xr-x | package/hostap-driver/files/lib/wifi/hostap.sh | 112 | ||||
-rw-r--r-- | package/hostap-driver/patches/001-fix-txpower.patch | 175 | ||||
-rw-r--r-- | target/linux/generic-2.6/patches/903-hostap_txpower.patch | 160 |
4 files changed, 457 insertions, 1 deletions
diff --git a/package/hostap-driver/Makefile b/package/hostap-driver/Makefile index 5be9f9eb59..3a170f6b00 100644 --- a/package/hostap-driver/Makefile +++ b/package/hostap-driver/Makefile @@ -46,7 +46,7 @@ endef define KernelPackage/hostap $(call KernelPackage/hostap/Default) TITLE:=Host AP support for Prism2/2.5/3 - DEPENDS:=@PCI_SUPPORT||PCMCIA_SUPPORT +kmod-ieee80211 + DEPENDS:=@PCI_SUPPORT||PCMCIA_SUPPORT +kmod-ieee80211 +wireless-tools KCONFIG:=CONFIG_HOSTAP endef @@ -174,6 +174,15 @@ else endef endif +define KernelPackage/hostap-pci/install + $(INSTALL_DIR) $(1)/lib/wifi + $(INSTALL_DATA) ./files/lib/wifi/hostap.sh $(1)/lib/wifi +endef + +define KernelPackage/hostap-plx/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)) 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 0000000000..964a504180 --- /dev/null +++ b/package/hostap-driver/files/lib/wifi/hostap.sh @@ -0,0 +1,112 @@ +#!/bin/sh +append DRIVERS "prism2" + +scan_prism2() { + local device="$1" + + config_get mode "$device" mode + case "$mode" in + ad-hoc|managed|master) + ;; + *) echo "$device: Invalid mode, ignored."; continue;; + esac + +} + +disable_prism2() ( + local device="$1" + + set_wifi_down "$device" + + include /lib/network + ifconfig "$device" down + unbridge "$device" + return 0 +) + +enable_prism2() { + local irqdevs + + config_get prifw "$device" prifw + config_get stafw "$device" stafw + config_get mode "$device" mode + config_get rate "$device" rate + config_get channel "$device" channel + config_get txpower "$device" txpower + config_get ssid "$device" ssid + config_get maclist "$device" maclist + config_get macpolicy "$device" macpolicy + [ -x /usr/sbin/prism2_srec ] && { + irqdevs=$(cat /proc/interrupts | grep wifi${device##wlan} | cut -b 37- | tr -d ",") + for dev in "$irqdevs"; do + [ "$(config_get "$dev" type)" = "atheros" ] && wifi down "$dev" + done + [ -f "$prifw" ] && prism2_srec -g $device $prifw + [ -f "$stafw" ] && prism2_srec -r $device $stafw + for dev in "$irqdevs"; do + [ "$(config_get "$dev" type)" = "atheros" ] && wifi up "$dev" + done + } + [ -n "$mode" ] && iwconfig $device mode $mode + [ -n "$rate" ] && iwconfig $device rate $rate + [ -n "$channel" ] && iwconfig $device channel $channel + [ -n "$ssid" ] && iwconfig $device essid $ssid + [ -n "$txpower" ] && iwconfig $device txpower $txpower + [ -n "$maclist" ] && { + # flush MAC list + iwpriv $device maccmd 3 + for mac in $maclist; do + iwpriv $device addmac $mac + done + } + case "$macpolicy" in + open) + iwpriv $device maccmd 0 + ;; + allow) + iwpriv $device maccmd 1 + ;; + deny) + iwpriv $device maccmd 2 + ;; + *) + # default deny policy if mac list exists + [ -n "$maclist" ] && iwpriv $device maccmd 2 + ;; + esac + # kick all stations if we have policy explicitly set + [ -n "$macpolicy" ] && iwpriv $device maccmd 4 + local net_cfg bridge + net_cfg="$(find_net_config "$device")" + [ -z "$net_cfg" ] || { + bridge="$(bridge_interface "$net_cfg")" + config_set "$device" bridge "$bridge" + start_net "$device" "$net_cfg" + } + set_wifi_up "$vif" "$ifname" +} + + +detect_prism2() { + cd /proc/net/hostap + [ -d wlan0 ] || return + for dev in wlan*; do + config_get type "$dev" type + [ "$type" = prism2 ] && continue + cat <<EOF + +config wifi-device $dev + option type prism2 +# option rate 11M + option channel 5 + option txpower 127 + option mode managed + option ssid OpenWrt +# option macpolicy deny +# option maclist '12:34:56:78:90:12 +# 09:87:65:43:21:09' + +EOF + 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 0000000000..94ca344943 --- /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; + } diff --git a/target/linux/generic-2.6/patches/903-hostap_txpower.patch b/target/linux/generic-2.6/patches/903-hostap_txpower.patch new file mode 100644 index 0000000000..6f82cdb033 --- /dev/null +++ b/target/linux/generic-2.6/patches/903-hostap_txpower.patch @@ -0,0 +1,160 @@ +diff -Nur linux-2.6.17/drivers/net/wireless/hostap/hostap_ap.c linux-2.6.17-patched/drivers/net/wireless/hostap/hostap_ap.c +--- linux-2.6.17/drivers/net/wireless/hostap/hostap_ap.c 2006-06-18 04:49:35.000000000 +0300 ++++ linux-2.6.17-patched/drivers/net/wireless/hostap/hostap_ap.c 2006-12-10 19:13:33.000000000 +0200 +@@ -2345,13 +2345,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 = IW_QUAL_DBM; +@@ -2416,13 +2416,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 -Nur linux-2.6.17/drivers/net/wireless/hostap/hostap_config.h linux-2.6.17-patched/drivers/net/wireless/hostap/hostap_config.h +--- linux-2.6.17/drivers/net/wireless/hostap/hostap_config.h 2006-06-18 04:49:35.000000000 +0300 ++++ linux-2.6.17-patched/drivers/net/wireless/hostap/hostap_config.h 2006-12-10 19:13:33.000000000 +0200 +@@ -47,4 +47,9 @@ + */ + /* #define PRISM2_NO_STATION_MODES */ + ++/* Enable TX power Setting functions ++ * (min att = -128 , max att = 127) ++ */ ++#define RAW_TXPOWER_SETTING ++ + #endif /* HOSTAP_CONFIG_H */ +diff -Nur linux-2.6.17/drivers/net/wireless/hostap/hostap.h linux-2.6.17-patched/drivers/net/wireless/hostap/hostap.h +--- linux-2.6.17/drivers/net/wireless/hostap/hostap.h 2006-06-18 04:49:35.000000000 +0300 ++++ linux-2.6.17-patched/drivers/net/wireless/hostap/hostap.h 2006-12-10 19:20:00.000000000 +0200 +@@ -89,6 +89,7 @@ + extern struct ethtool_ops prism2_ethtool_ops; + + int hostap_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); ++int hostap_restore_power(struct net_device *dev); + + + #endif /* HOSTAP_H */ +diff -Nur linux-2.6.17/drivers/net/wireless/hostap/hostap_hw.c linux-2.6.17-patched/drivers/net/wireless/hostap/hostap_hw.c +--- linux-2.6.17/drivers/net/wireless/hostap/hostap_hw.c 2006-06-18 04:49:35.000000000 +0300 ++++ linux-2.6.17-patched/drivers/net/wireless/hostap/hostap_hw.c 2006-12-10 19:13:33.000000000 +0200 +@@ -1043,6 +1043,7 @@ + dev->name, local->fragm_threshold); + } + ++ hostap_restore_power(dev); + return res; + } + +diff -Nur linux-2.6.17/drivers/net/wireless/hostap/hostap_info.c linux-2.6.17-patched/drivers/net/wireless/hostap/hostap_info.c +--- linux-2.6.17/drivers/net/wireless/hostap/hostap_info.c 2006-06-18 04:49:35.000000000 +0300 ++++ linux-2.6.17-patched/drivers/net/wireless/hostap/hostap_info.c 2006-12-10 19:13:33.000000000 +0200 +@@ -429,6 +429,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 -Nur linux-2.6.17/drivers/net/wireless/hostap/hostap_ioctl.c linux-2.6.17-patched/drivers/net/wireless/hostap/hostap_ioctl.c +--- linux-2.6.17/drivers/net/wireless/hostap/hostap_ioctl.c 2006-06-18 04:49:35.000000000 +0300 ++++ linux-2.6.17-patched/drivers/net/wireless/hostap/hostap_ioctl.c 2006-12-10 21:21:03.000000000 +0200 +@@ -1506,23 +1506,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; + } +@@ -4086,3 +4083,35 @@ + + 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); ++} ++ ++EXPORT_SYMBOL(hostap_restore_power); |