6f82cdb0330ae236108ceddced60bd58b1cb7ce5
[openwrt.git] / target / linux / generic-2.6 / patches-2.6.25 / 903-hostap_txpower.patch
1 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
2 --- linux-2.6.17/drivers/net/wireless/hostap/hostap_ap.c        2006-06-18 04:49:35.000000000 +0300
3 +++ linux-2.6.17-patched/drivers/net/wireless/hostap/hostap_ap.c        2006-12-10 19:13:33.000000000 +0200
4 @@ -2345,13 +2345,13 @@
5                 addr[count].sa_family = ARPHRD_ETHER;
6                 memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
7                 if (sta->last_rx_silence == 0)
8 -                       qual[count].qual = sta->last_rx_signal < 27 ?
9 -                               0 : (sta->last_rx_signal - 27) * 92 / 127;
10 +                        qual[count].qual = (sta->last_rx_signal - 156) == 0 ?
11 +                                0 : (sta->last_rx_signal - 156) * 92 / 64;
12                 else
13 -                       qual[count].qual = sta->last_rx_signal -
14 -                               sta->last_rx_silence - 35;
15 -               qual[count].level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal);
16 -               qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
17 +                        qual[count].qual = (sta->last_rx_signal -
18 +                                sta->last_rx_silence) * 92 / 64;
19 +                qual[count].level = sta->last_rx_signal;
20 +                qual[count].noise = sta->last_rx_silence;
21                 qual[count].updated = sta->last_rx_updated;
22  
23                 sta->last_rx_updated = IW_QUAL_DBM;
24 @@ -2416,13 +2416,13 @@
25                 memset(&iwe, 0, sizeof(iwe));
26                 iwe.cmd = IWEVQUAL;
27                 if (sta->last_rx_silence == 0)
28 -                       iwe.u.qual.qual = sta->last_rx_signal < 27 ?
29 -                               0 : (sta->last_rx_signal - 27) * 92 / 127;
30 +                       iwe.u.qual.qual = (sta->last_rx_signal -156) == 0 ?
31 +                               0 : (sta->last_rx_signal - 156) * 92 / 64;
32                 else
33 -                       iwe.u.qual.qual = sta->last_rx_signal -
34 -                               sta->last_rx_silence - 35;
35 -               iwe.u.qual.level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal);
36 -               iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
37 +                        iwe.u.qual.qual = (sta->last_rx_signal -
38 +                                sta->last_rx_silence) * 92 / 64;
39 +                iwe.u.qual.level = sta->last_rx_signal;
40 +                iwe.u.qual.noise = sta->last_rx_silence;
41                 iwe.u.qual.updated = sta->last_rx_updated;
42                 iwe.len = IW_EV_QUAL_LEN;
43                 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
44 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
45 --- linux-2.6.17/drivers/net/wireless/hostap/hostap_config.h    2006-06-18 04:49:35.000000000 +0300
46 +++ linux-2.6.17-patched/drivers/net/wireless/hostap/hostap_config.h    2006-12-10 19:13:33.000000000 +0200
47 @@ -47,4 +47,9 @@
48   */
49  /* #define PRISM2_NO_STATION_MODES */
50  
51 +/* Enable TX power Setting functions
52 + * (min att = -128 , max att =  127)
53 + */
54 +#define RAW_TXPOWER_SETTING
55 +
56  #endif /* HOSTAP_CONFIG_H */
57 diff -Nur linux-2.6.17/drivers/net/wireless/hostap/hostap.h linux-2.6.17-patched/drivers/net/wireless/hostap/hostap.h
58 --- linux-2.6.17/drivers/net/wireless/hostap/hostap.h   2006-06-18 04:49:35.000000000 +0300
59 +++ linux-2.6.17-patched/drivers/net/wireless/hostap/hostap.h   2006-12-10 19:20:00.000000000 +0200
60 @@ -89,6 +89,7 @@
61  extern struct ethtool_ops prism2_ethtool_ops;
62  
63  int hostap_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
64 +int hostap_restore_power(struct net_device *dev);
65  
66  
67  #endif /* HOSTAP_H */
68 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
69 --- linux-2.6.17/drivers/net/wireless/hostap/hostap_hw.c        2006-06-18 04:49:35.000000000 +0300
70 +++ linux-2.6.17-patched/drivers/net/wireless/hostap/hostap_hw.c        2006-12-10 19:13:33.000000000 +0200
71 @@ -1043,6 +1043,7 @@
72                        dev->name, local->fragm_threshold);
73         }
74  
75 +       hostap_restore_power(dev);
76         return res;
77  }
78  
79 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
80 --- linux-2.6.17/drivers/net/wireless/hostap/hostap_info.c      2006-06-18 04:49:35.000000000 +0300
81 +++ linux-2.6.17-patched/drivers/net/wireless/hostap/hostap_info.c      2006-12-10 19:13:33.000000000 +0200
82 @@ -429,6 +429,11 @@
83         }
84  
85         /* Get BSSID if we have a valid AP address */
86 +
87 +       if ( val == HFA384X_LINKSTATUS_CONNECTED ||
88 +            val == HFA384X_LINKSTATUS_DISCONNECTED ) 
89 +                       hostap_restore_power(local->dev);
90 +
91         if (connected) {
92                 netif_carrier_on(local->dev);
93                 netif_carrier_on(local->ddev);
94 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
95 --- linux-2.6.17/drivers/net/wireless/hostap/hostap_ioctl.c     2006-06-18 04:49:35.000000000 +0300
96 +++ linux-2.6.17-patched/drivers/net/wireless/hostap/hostap_ioctl.c     2006-12-10 21:21:03.000000000 +0200
97 @@ -1506,23 +1506,20 @@
98                 val = 255;
99  
100         tmp = val;
101 -       tmp >>= 2;
102  
103 -       return -12 - tmp;
104 +       return tmp;
105  }
106  
107  static u16 prism2_txpower_dBm_to_hfa386x(int val)
108  {
109         signed char tmp;
110  
111 -       if (val > 20)
112 -               return 128;
113 -       else if (val < -43)
114 +       if (val > 127)
115                 return 127;
116 +       else if (val < -128)
117 +               return 128;
118  
119         tmp = val;
120 -       tmp = -12 - tmp;
121 -       tmp <<= 2;
122  
123         return (unsigned char) tmp;
124  }
125 @@ -4086,3 +4083,35 @@
126  
127         return ret;
128  }
129 +
130 +/* BUG FIX: Restore power setting value when lost due to F/W bug */
131 +
132 +int hostap_restore_power(struct net_device *dev)
133 +{
134 +        struct hostap_interface *iface = dev->priv;
135 +       local_info_t *local = iface->local;
136 +               
137 +       u16 val;
138 +       int ret = 0;
139 +
140 +       if (local->txpower_type == PRISM2_TXPOWER_OFF) {
141 +                       val = 0xff; /* use all standby and sleep modes */
142 +                       ret = local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
143 +                                              HFA386X_CR_A_D_TEST_MODES2,
144 +                                              &val, NULL);
145 +       }
146 +
147 +#ifdef RAW_TXPOWER_SETTING
148 +       if (local->txpower_type == PRISM2_TXPOWER_FIXED) {
149 +               val = HFA384X_TEST_CFG_BIT_ALC;
150 +               local->func->cmd(dev, HFA384X_CMDCODE_TEST |
151 +                                (HFA384X_TEST_CFG_BITS << 8), 0, &val, NULL);
152 +               val = prism2_txpower_dBm_to_hfa386x(local->txpower);
153 +               ret = (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
154 +                            HFA386X_CR_MANUAL_TX_POWER, &val, NULL));
155 +       }
156 +#endif /* RAW_TXPOWER_SETTING */
157 +       return (ret ? -EOPNOTSUPP : 0);
158 +}
159 +
160 +EXPORT_SYMBOL(hostap_restore_power);