ath10k-firmware: remove dependency on kmod-ath10k so that it can be selected instead
[15.05/openwrt.git] / package / kernel / mac80211 / patches / 370-0003-brcmfmac-Fix-set-and-get-tx-power-functions.patch
1 From: Hante Meuleman <meuleman@broadcom.com>
2 Date: Fri, 18 Sep 2015 22:08:06 +0200
3 Subject: [PATCH] brcmfmac: Fix set and get tx-power functions.
4
5 Implementation of tx-power (get and set) related functions are
6 still assuming mW interface. This is wrong as functions use dbm
7 (or mbm) nowadays. As a result a tx power configuration could
8 result in wrong power configuration.
9
10 Reviewed-by: Arend Van Spriel <arend@broadcom.com>
11 Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
12 Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
13 Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
14 Signed-off-by: Arend van Spriel <arend@broadcom.com>
15 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
16 ---
17
18 --- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
19 +++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
20 @@ -236,89 +236,6 @@ static int brcmf_roamoff;
21  module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
22  MODULE_PARM_DESC(roamoff, "do not use internal roaming engine");
23  
24 -/* Quarter dBm units to mW
25 - * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
26 - * Table is offset so the last entry is largest mW value that fits in
27 - * a u16.
28 - */
29 -
30 -#define QDBM_OFFSET 153                /* Offset for first entry */
31 -#define QDBM_TABLE_LEN 40      /* Table size */
32 -
33 -/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
34 - * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
35 - */
36 -#define QDBM_TABLE_LOW_BOUND 6493      /* Low bound */
37 -
38 -/* Largest mW value that will round down to the last table entry,
39 - * QDBM_OFFSET + QDBM_TABLE_LEN-1.
40 - * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
41 - * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
42 - */
43 -#define QDBM_TABLE_HIGH_BOUND 64938    /* High bound */
44 -
45 -static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
46 -/* qdBm:       +0      +1      +2      +3      +4      +5      +6      +7 */
47 -/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
48 -/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
49 -/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
50 -/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
51 -/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
52 -};
53 -
54 -static u16 brcmf_qdbm_to_mw(u8 qdbm)
55 -{
56 -       uint factor = 1;
57 -       int idx = qdbm - QDBM_OFFSET;
58 -
59 -       if (idx >= QDBM_TABLE_LEN)
60 -               /* clamp to max u16 mW value */
61 -               return 0xFFFF;
62 -
63 -       /* scale the qdBm index up to the range of the table 0-40
64 -        * where an offset of 40 qdBm equals a factor of 10 mW.
65 -        */
66 -       while (idx < 0) {
67 -               idx += 40;
68 -               factor *= 10;
69 -       }
70 -
71 -       /* return the mW value scaled down to the correct factor of 10,
72 -        * adding in factor/2 to get proper rounding.
73 -        */
74 -       return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
75 -}
76 -
77 -static u8 brcmf_mw_to_qdbm(u16 mw)
78 -{
79 -       u8 qdbm;
80 -       int offset;
81 -       uint mw_uint = mw;
82 -       uint boundary;
83 -
84 -       /* handle boundary case */
85 -       if (mw_uint <= 1)
86 -               return 0;
87 -
88 -       offset = QDBM_OFFSET;
89 -
90 -       /* move mw into the range of the table */
91 -       while (mw_uint < QDBM_TABLE_LOW_BOUND) {
92 -               mw_uint *= 10;
93 -               offset -= 40;
94 -       }
95 -
96 -       for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
97 -               boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
98 -                                                   nqdBm_to_mW_map[qdbm]) / 2;
99 -               if (mw_uint < boundary)
100 -                       break;
101 -       }
102 -
103 -       qdbm += (u8) offset;
104 -
105 -       return qdbm;
106 -}
107  
108  static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
109                                struct cfg80211_chan_def *ch)
110 @@ -2016,16 +1933,14 @@ static s32
111  brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
112                             enum nl80211_tx_power_setting type, s32 mbm)
113  {
114 -
115         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
116         struct net_device *ndev = cfg_to_ndev(cfg);
117         struct brcmf_if *ifp = netdev_priv(ndev);
118 -       u16 txpwrmw;
119 -       s32 err = 0;
120 -       s32 disable = 0;
121 -       s32 dbm = MBM_TO_DBM(mbm);
122 +       s32 err;
123 +       s32 disable;
124 +       u32 qdbm = 127;
125  
126 -       brcmf_dbg(TRACE, "Enter\n");
127 +       brcmf_dbg(TRACE, "Enter %d %d\n", type, mbm);
128         if (!check_vif_up(ifp->vif))
129                 return -EIO;
130  
131 @@ -2034,12 +1949,20 @@ brcmf_cfg80211_set_tx_power(struct wiphy
132                 break;
133         case NL80211_TX_POWER_LIMITED:
134         case NL80211_TX_POWER_FIXED:
135 -               if (dbm < 0) {
136 +               if (mbm < 0) {
137                         brcmf_err("TX_POWER_FIXED - dbm is negative\n");
138                         err = -EINVAL;
139                         goto done;
140                 }
141 +               qdbm =  MBM_TO_DBM(4 * mbm);
142 +               if (qdbm > 127)
143 +                       qdbm = 127;
144 +               qdbm |= WL_TXPWR_OVERRIDE;
145                 break;
146 +       default:
147 +               brcmf_err("Unsupported type %d\n", type);
148 +               err = -EINVAL;
149 +               goto done;
150         }
151         /* Make sure radio is off or on as far as software is concerned */
152         disable = WL_RADIO_SW_DISABLE << 16;
153 @@ -2047,52 +1970,44 @@ brcmf_cfg80211_set_tx_power(struct wiphy
154         if (err)
155                 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
156  
157 -       if (dbm > 0xffff)
158 -               txpwrmw = 0xffff;
159 -       else
160 -               txpwrmw = (u16) dbm;
161 -       err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
162 -                                     (s32)brcmf_mw_to_qdbm(txpwrmw));
163 +       err = brcmf_fil_iovar_int_set(ifp, "qtxpower", qdbm);
164         if (err)
165                 brcmf_err("qtxpower error (%d)\n", err);
166 -       cfg->conf->tx_power = dbm;
167  
168  done:
169 -       brcmf_dbg(TRACE, "Exit\n");
170 +       brcmf_dbg(TRACE, "Exit %d (qdbm)\n", qdbm & ~WL_TXPWR_OVERRIDE);
171         return err;
172  }
173  
174 -static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
175 -                                      struct wireless_dev *wdev,
176 -                                      s32 *dbm)
177 +static s32
178 +brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
179 +                           s32 *dbm)
180  {
181         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
182 -       struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
183 -       s32 txpwrdbm;
184 -       u8 result;
185 -       s32 err = 0;
186 +       struct net_device *ndev = cfg_to_ndev(cfg);
187 +       struct brcmf_if *ifp = netdev_priv(ndev);
188 +       s32 qdbm = 0;
189 +       s32 err;
190  
191         brcmf_dbg(TRACE, "Enter\n");
192         if (!check_vif_up(ifp->vif))
193                 return -EIO;
194  
195 -       err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
196 +       err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &qdbm);
197         if (err) {
198                 brcmf_err("error (%d)\n", err);
199                 goto done;
200         }
201 -
202 -       result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
203 -       *dbm = (s32) brcmf_qdbm_to_mw(result);
204 +       *dbm = (qdbm & ~WL_TXPWR_OVERRIDE) / 4;
205  
206  done:
207 -       brcmf_dbg(TRACE, "Exit\n");
208 +       brcmf_dbg(TRACE, "Exit (0x%x %d)\n", qdbm, *dbm);
209         return err;
210  }
211  
212  static s32
213  brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
214 -                              u8 key_idx, bool unicast, bool multicast)
215 +                                 u8 key_idx, bool unicast, bool multicast)
216  {
217         struct brcmf_if *ifp = netdev_priv(ndev);
218         u32 index;