[mac80211] several patches to make OF work on rt2x00
[openwrt.git] / package / mac80211 / patches / 860-brcmsmac-implement-ieee80211_ops-get_tsf-and-set_tsf.patch
1 --- a/drivers/net/wireless/brcm80211/brcmsmac/d11.h
2 +++ b/drivers/net/wireless/brcm80211/brcmsmac/d11.h
3 @@ -457,6 +457,7 @@ struct d11regs {
4  /*== maccontrol register ==*/
5  #define        MCTL_GMODE              (1U << 31)
6  #define        MCTL_DISCARD_PMQ        (1 << 30)
7 +#define        MCTL_TBTTHOLD           (1 << 28)
8  #define        MCTL_WAKE               (1 << 26)
9  #define        MCTL_HPS                (1 << 25)
10  #define        MCTL_PROMISC            (1 << 24)
11 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
12 +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
13 @@ -741,6 +741,28 @@ static void brcms_ops_flush(struct ieee8
14                            "ret=%d\n", jiffies_to_msecs(ret));
15  }
16  
17 +static u64 brcms_ops_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
18 +{
19 +       struct brcms_info *wl = hw->priv;
20 +       u64 tsf;
21 +
22 +       spin_lock_bh(&wl->lock);
23 +       tsf = brcms_c_tsf_get(wl->wlc);
24 +       spin_unlock_bh(&wl->lock);
25 +
26 +       return tsf;
27 +}
28 +
29 +static void brcms_ops_set_tsf(struct ieee80211_hw *hw,
30 +                          struct ieee80211_vif *vif, u64 tsf)
31 +{
32 +       struct brcms_info *wl = hw->priv;
33 +
34 +       spin_lock_bh(&wl->lock);
35 +       brcms_c_tsf_set(wl->wlc, tsf);
36 +       spin_unlock_bh(&wl->lock);
37 +}
38 +
39  static const struct ieee80211_ops brcms_ops = {
40         .tx = brcms_ops_tx,
41         .start = brcms_ops_start,
42 @@ -757,6 +779,8 @@ static const struct ieee80211_ops brcms_
43         .ampdu_action = brcms_ops_ampdu_action,
44         .rfkill_poll = brcms_ops_rfkill_poll,
45         .flush = brcms_ops_flush,
46 +       .get_tsf = brcms_ops_get_tsf,
47 +       .set_tsf = brcms_ops_set_tsf,
48  };
49  
50  void brcms_dpc(unsigned long data)
51 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
52 +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
53 @@ -5545,6 +5545,20 @@ int brcms_c_set_rateset(struct brcms_c_i
54         return bcmerror;
55  }
56  
57 +static void brcms_c_time_lock(struct brcms_c_info *wlc)
58 +{
59 +       bcma_set32(wlc->hw->d11core, D11REGOFFS(maccontrol), MCTL_TBTTHOLD);
60 +       /* Commit the write */
61 +       bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol));
62 +}
63 +
64 +static void brcms_c_time_unlock(struct brcms_c_info *wlc)
65 +{
66 +       bcma_mask32(wlc->hw->d11core, D11REGOFFS(maccontrol), ~MCTL_TBTTHOLD);
67 +       /* Commit the write */
68 +       bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol));
69 +}
70 +
71  int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period)
72  {
73         if (period == 0)
74 @@ -7530,6 +7544,36 @@ void brcms_c_set_beacon_listen_interval(
75                 brcms_c_bcn_li_upd(wlc);
76  }
77  
78 +u64 brcms_c_tsf_get(struct brcms_c_info *wlc)
79 +{
80 +       u32 tsf_h, tsf_l;
81 +       u64 tsf;
82 +
83 +       brcms_b_read_tsf(wlc->hw, &tsf_l, &tsf_h);
84 +
85 +       tsf = tsf_h;
86 +       tsf <<= 32;
87 +       tsf |= tsf_l;
88 +
89 +       return tsf;
90 +}
91 +
92 +void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf)
93 +{
94 +       u32 tsf_h, tsf_l;
95 +
96 +       brcms_c_time_lock(wlc);
97 +
98 +       tsf_l = tsf;
99 +       tsf_h = (tsf >> 32);
100 +
101 +       /* read the tsf timer low, then high to get an atomic read */
102 +       bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_timerlow), tsf_l);
103 +       bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_timerhigh), tsf_h);
104 +
105 +       brcms_c_time_unlock(wlc);
106 +}
107 +
108  int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr)
109  {
110         uint qdbm;
111 --- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
112 +++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
113 @@ -326,6 +326,8 @@ extern void brcms_c_set_shortslot_overri
114                                     s8 sslot_override);
115  extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc,
116                                         u8 interval);
117 +extern u64 brcms_c_tsf_get(struct brcms_c_info *wlc);
118 +extern void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf);
119  extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr);
120  extern int brcms_c_get_tx_power(struct brcms_c_info *wlc);
121  extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);