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