aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/patches-2.6.36/903-hostap_txpower.patch
blob: ad44715411263c97fc2b187c8fffd5e1dba7adae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -2335,13 +2335,13 @@ int prism2_ap_get_sta_qual(local_info_t 
 		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;
@@ -2407,13 +2407,13 @@ int prism2_ap_translate_scan(struct net_
 		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(info, current_ev, end_buf,
--- a/drivers/net/wireless/hostap/hostap_config.h
+++ b/drivers/net/wireless/hostap/hostap_config.h
@@ -45,4 +45,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 */
--- a/drivers/net/wireless/hostap/hostap.h
+++ b/drivers/net/wireless/hostap/hostap.h
@@ -90,6 +90,7 @@ extern const struct iw_handler_def hosta
 extern const 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 */
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -932,6 +932,7 @@ static int hfa384x_set_rid(struct net_de
 			prism2_hw_reset(dev);
 	}
 
+	hostap_restore_power(dev);
 	return res;
 }
 
--- a/drivers/net/wireless/hostap/hostap_info.c
+++ b/drivers/net/wireless/hostap/hostap_info.c
@@ -433,6 +433,11 @@ static void handle_info_queue_linkstatus
 	}
 
 	/* 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);
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -1477,23 +1477,20 @@ static int prism2_txpower_hfa386x_to_dBm
 		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;
 }
@@ -4056,3 +4053,35 @@ int hostap_ioctl(struct net_device *dev,
 
 	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 = netdev_priv(dev);
+       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);
lass="s2">" local minor="${devid##*:}" mknod "$dev" c $major $minor } nand_find_volume() { local ubidevdir ubivoldir ubidevdir="/sys/devices/virtual/ubi/$1" [ ! -d "$ubidevdir" ] && return 1 for ubivoldir in $ubidevdir/${1}_*; do [ ! -d "$ubivoldir" ] && continue if [ "$( cat $ubivoldir/name )" = "$2" ]; then basename $ubivoldir ubi_mknod "$ubivoldir" return 0 fi done } nand_find_ubi() { local ubidevdir ubidev mtdnum mtdnum="$( find_mtd_index $1 )" [ ! "$mtdnum" ] && return 1 for ubidevdir in /sys/devices/virtual/ubi/ubi*; do [ ! -d "$ubidevdir" ] && continue cmtdnum="$( cat $ubidevdir/mtd_num )" [ ! "$mtdnum" ] && continue if [ "$mtdnum" = "$cmtdnum" ]; then ubidev=$( basename $ubidevdir ) ubi_mknod "$ubidevdir" echo $ubidev return 0 fi done } nand_get_magic_long() { dd if="$1" skip=$2 bs=4 count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' } get_magic_long_tar() { ( tar xf $1 $2 -O | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2> /dev/null } identify_magic() { local magic=$1 case "$magic" in "55424923") echo "ubi" ;; "31181006") echo "ubifs" ;; "68737173") echo "squashfs" ;; "d00dfeed") echo "fit" ;; "4349"*) echo "combined" ;; *) echo "unknown $magic" ;; esac } identify() { identify_magic $(nand_get_magic_long "$1" "${2:-0}") } identify_tar() { identify_magic $(get_magic_long_tar "$1" "$2") } nand_restore_config() { sync local ubidev=$( nand_find_ubi $CI_UBIPART ) local ubivol="$( nand_find_volume $ubidev rootfs_data )" [ ! "$ubivol" ] && ubivol="$( nand_find_volume $ubidev rootfs )" mkdir /tmp/new_root if ! mount -t ubifs /dev/$ubivol /tmp/new_root; then echo "mounting ubifs $ubivol failed" rmdir /tmp/new_root return 1 fi mv "$1" "/tmp/new_root/sysupgrade.tgz" umount /tmp/new_root sync rmdir /tmp/new_root } nand_upgrade_prepare_ubi() { local rootfs_length="$1" local rootfs_type="$2" local has_kernel="${3:-0}" local has_env="${4:-0}" local mtdnum="$( find_mtd_index "$CI_UBIPART" )" if [ ! "$mtdnum" ]; then echo "cannot find ubi mtd partition $CI_UBIPART" return 1 fi local ubidev="$( nand_find_ubi "$CI_UBIPART" )" if [ ! "$ubidev" ]; then ubiattach -m "$mtdnum" sync ubidev="$( nand_find_ubi "$CI_UBIPART" )" fi if [ ! "$ubidev" ]; then ubiformat /dev/mtd$mtdnum -y ubiattach -m "$mtdnum" sync ubidev="$( nand_find_ubi "$CI_UBIPART" )" [ "$has_env" -gt 0 ] && { ubimkvol /dev/$ubidev -n 0 -N ubootenv -s 1MiB ubimkvol /dev/$ubidev -n 1 -N ubootenv2 -s 1MiB } fi local kern_ubivol="$( nand_find_volume $ubidev $CI_KERNPART )" local root_ubivol="$( nand_find_volume $ubidev rootfs )" local data_ubivol="$( nand_find_volume $ubidev rootfs_data )" # remove ubiblock device of rootfs local root_ubiblk="ubiblock${root_ubivol:3}" if [ "$root_ubivol" -a -e "/dev/$root_ubiblk" ]; then echo "removing $root_ubiblk" if ! ubiblock -r /dev/$root_ubivol; then echo "cannot remove $root_ubiblk" return 1; fi fi # kill volumes [ "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_KERNPART || true [ "$root_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs || true [ "$data_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs_data || true # update kernel if [ "$has_kernel" = "1" ]; then if ! ubimkvol /dev/$ubidev -N $CI_KERNPART -s $kernel_length; then echo "cannot create kernel volume" return 1; fi fi # update rootfs local root_size_param if [ "$rootfs_type" = "ubifs" ]; then root_size_param="-m" else root_size_param="-s $rootfs_length" fi if ! ubimkvol /dev/$ubidev -N rootfs $root_size_param; then echo "cannot create rootfs volume" return 1; fi # create rootfs_data for non-ubifs rootfs if [ "$rootfs_type" != "ubifs" ]; then if ! ubimkvol /dev/$ubidev -N rootfs_data -m; then echo "cannot initialize rootfs_data volume" return 1 fi fi sync return 0 } nand_do_upgrade_success() { local conf_tar="/tmp/sysupgrade.tgz" sync [ -f "$conf_tar" ] && nand_restore_config "$conf_tar" echo "sysupgrade successful" umount -a reboot -f } # Flash the UBI image to MTD partition nand_upgrade_ubinized() { local ubi_file="$1" local mtdnum="$(find_mtd_index "$CI_UBIPART")" [ ! "$mtdnum" ] && { CI_UBIPART="rootfs" mtdnum="$(find_mtd_index "$CI_UBIPART")" } if [ ! "$mtdnum" ]; then echo "cannot find mtd device $CI_UBIPART" umount -a reboot -f fi local mtddev="/dev/mtd${mtdnum}" ubidetach -p "${mtddev}" || true sync ubiformat "${mtddev}" -y -f "${ubi_file}" ubiattach -p "${mtddev}" nand_do_upgrade_success } # Write the UBIFS image to UBI volume nand_upgrade_ubifs() { local rootfs_length=`(cat $1 | wc -c) 2> /dev/null` nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "0" "0" local ubidev="$( nand_find_ubi "$CI_UBIPART" )" local root_ubivol="$(nand_find_volume $ubidev rootfs)" ubiupdatevol /dev/$root_ubivol -s $rootfs_length $1 nand_do_upgrade_success } nand_board_name() { if type 'platform_nand_board_name' >/dev/null 2>/dev/null; then platform_nand_board_name return fi cat /tmp/sysinfo/board_name } nand_upgrade_tar() { local tar_file="$1" local board_name="$(nand_board_name)" local kernel_mtd="$(find_mtd_index $CI_KERNPART)" local kernel_length=`(tar xf $tar_file sysupgrade-$board_name/kernel -O | wc -c) 2> /dev/null` local rootfs_length=`(tar xf $tar_file sysupgrade-$board_name/root -O | wc -c) 2> /dev/null` local rootfs_type="$(identify_tar "$tar_file" sysupgrade-$board_name/root)" local has_kernel=1 local has_env=0 [ "$kernel_length" != 0 -a -n "$kernel_mtd" ] && { tar xf $tar_file sysupgrade-$board_name/kernel -O | mtd write - $CI_KERNPART } [ "$kernel_length" = 0 -o ! -z "$kernel_mtd" ] && has_kernel=0 nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "$has_kernel" "$has_env" local ubidev="$( nand_find_ubi "$CI_UBIPART" )" [ "$has_kernel" = "1" ] && { local kern_ubivol="$(nand_find_volume $ubidev $CI_KERNPART)" tar xf $tar_file sysupgrade-$board_name/kernel -O | \ ubiupdatevol /dev/$kern_ubivol -s $kernel_length - } local root_ubivol="$(nand_find_volume $ubidev rootfs)" tar xf $tar_file sysupgrade-$board_name/root -O | \ ubiupdatevol /dev/$root_ubivol -s $rootfs_length - nand_do_upgrade_success } # Recognize type of passed file and start the upgrade process nand_do_upgrade() { if [ -n "$IS_PRE_UPGRADE" ]; then # Previously, nand_do_upgrade was called from the platform_pre_upgrade # hook; this piece of code handles scripts that haven't been # updated. All scripts should gradually move to call nand_do_upgrade # from platform_do_upgrade instead. export do_upgrade=nand_do_upgrade return fi local file_type=$(identify $1) if type 'platform_nand_pre_upgrade' >/dev/null 2>/dev/null; then platform_nand_pre_upgrade "$1" fi [ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs" case "$file_type" in "ubi") nand_upgrade_ubinized $1;; "ubifs") nand_upgrade_ubifs $1;; *) nand_upgrade_tar $1;; esac } # Check if passed file is a valid one for NAND sysupgrade. Currently it accepts # 3 types of files: # 1) UBI - should contain an ubinized image, header is checked for the proper # MAGIC # 2) UBIFS - should contain UBIFS partition that will replace "rootfs" volume, # header is checked for the proper MAGIC # 3) TAR - archive has to include "sysupgrade-BOARD" directory with a non-empty # "CONTROL" file (at this point its content isn't verified) # # You usually want to call this function in platform_check_image. # # $(1): board name, used in case of passing TAR file # $(2): file to be checked nand_do_platform_check() { local board_name="$1" local tar_file="$2" local control_length=`(tar xf $tar_file sysupgrade-$board_name/CONTROL -O | wc -c) 2> /dev/null` local file_type="$(identify $2)" [ "$control_length" = 0 -a "$file_type" != "ubi" -a "$file_type" != "ubifs" ] && { echo "Invalid sysupgrade file." return 1 } return 0 }