ath5k: channel change fix
[oweals/openwrt.git] / package / kernel / mac80211 / patches / 302-ath9k-add-support-for-reporting-tx-power-to-mac80211.patch
1 From: Felix Fietkau <nbd@openwrt.org>
2 Date: Wed, 22 Oct 2014 18:18:04 +0200
3 Subject: [PATCH] ath9k: add support for reporting tx power to mac80211
4
5 Track it per channel context instead of in the softc
6
7 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
8 ---
9
10 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
11 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
12 @@ -347,6 +347,7 @@ struct ath_chanctx {
13  
14         int flush_timeout;
15         u16 txpower;
16 +       u16 cur_txpower;
17         bool offchannel;
18         bool stopped;
19         bool active;
20 @@ -987,7 +988,6 @@ struct ath_softc {
21         u8 gtt_cnt;
22         u32 intrstatus;
23         u16 ps_flags; /* PS_* */
24 -       u16 curtxpow;
25         bool ps_enabled;
26         bool ps_idle;
27         short nbcnvifs;
28 --- a/drivers/net/wireless/ath/ath9k/init.c
29 +++ b/drivers/net/wireless/ath/ath9k/init.c
30 @@ -172,17 +172,20 @@ static void ath9k_reg_notifier(struct wi
31         ath_reg_notifier_apply(wiphy, request, reg);
32  
33         /* Set tx power */
34 -       if (ah->curchan) {
35 -               sc->cur_chan->txpower = 2 * ah->curchan->chan->max_power;
36 -               ath9k_ps_wakeup(sc);
37 -               ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false);
38 -               sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
39 -               /* synchronize DFS detector if regulatory domain changed */
40 -               if (sc->dfs_detector != NULL)
41 -                       sc->dfs_detector->set_dfs_domain(sc->dfs_detector,
42 -                                                        request->dfs_region);
43 -               ath9k_ps_restore(sc);
44 -       }
45 +       if (!ah->curchan)
46 +               return;
47 +
48 +       sc->cur_chan->txpower = 2 * ah->curchan->chan->max_power;
49 +       ath9k_ps_wakeup(sc);
50 +       ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false);
51 +       ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower,
52 +                              sc->cur_chan->txpower,
53 +                              &sc->cur_chan->cur_txpower);
54 +       /* synchronize DFS detector if regulatory domain changed */
55 +       if (sc->dfs_detector != NULL)
56 +               sc->dfs_detector->set_dfs_domain(sc->dfs_detector,
57 +                                                request->dfs_region);
58 +       ath9k_ps_restore(sc);
59  }
60  
61  /*
62 --- a/drivers/net/wireless/ath/ath9k/main.c
63 +++ b/drivers/net/wireless/ath/ath9k/main.c
64 @@ -233,8 +233,9 @@ static bool ath_complete_reset(struct at
65  
66         ath9k_calculate_summary_state(sc, sc->cur_chan);
67         ath_startrecv(sc);
68 -       ath9k_cmn_update_txpow(ah, sc->curtxpow,
69 -                              sc->cur_chan->txpower, &sc->curtxpow);
70 +       ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower,
71 +                              sc->cur_chan->txpower,
72 +                              &sc->cur_chan->cur_txpower);
73         clear_bit(ATH_OP_HW_RESET, &common->op_flags);
74  
75         if (!sc->cur_chan->offchannel && start) {
76 @@ -1471,8 +1472,9 @@ static int ath9k_config(struct ieee80211
77         if (changed & IEEE80211_CONF_CHANGE_POWER) {
78                 ath_dbg(common, CONFIG, "Set power: %d\n", conf->power_level);
79                 sc->cur_chan->txpower = 2 * conf->power_level;
80 -               ath9k_cmn_update_txpow(ah, sc->curtxpow,
81 -                                      sc->cur_chan->txpower, &sc->curtxpow);
82 +               ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower,
83 +                                      sc->cur_chan->txpower,
84 +                                      &sc->cur_chan->cur_txpower);
85         }
86  
87         mutex_unlock(&sc->mutex);
88 @@ -2594,6 +2596,24 @@ void ath9k_fill_chanctx_ops(void)
89  
90  #endif
91  
92 +static int ath9k_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
93 +                            int *dbm)
94 +{
95 +       struct ath_softc *sc = hw->priv;
96 +       struct ath_vif *avp = (void *)vif->drv_priv;
97 +
98 +       mutex_lock(&sc->mutex);
99 +       if (avp->chanctx)
100 +               *dbm = avp->chanctx->cur_txpower;
101 +       else
102 +               *dbm = sc->cur_chan->cur_txpower;
103 +       mutex_unlock(&sc->mutex);
104 +
105 +       *dbm /= 2;
106 +
107 +       return 0;
108 +}
109 +
110  struct ieee80211_ops ath9k_ops = {
111         .tx                 = ath9k_tx,
112         .start              = ath9k_start,
113 @@ -2640,4 +2660,5 @@ struct ieee80211_ops ath9k_ops = {
114  #endif
115         .sw_scan_start      = ath9k_sw_scan_start,
116         .sw_scan_complete   = ath9k_sw_scan_complete,
117 +       .get_txpower        = ath9k_get_txpower,
118  };