diff options
Diffstat (limited to 'package/mac80211/patches/860-brcmsmac-implement-ieee80211_ops-get_tsf-and-set_tsf.patch')
-rw-r--r-- | package/mac80211/patches/860-brcmsmac-implement-ieee80211_ops-get_tsf-and-set_tsf.patch | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/package/mac80211/patches/860-brcmsmac-implement-ieee80211_ops-get_tsf-and-set_tsf.patch b/package/mac80211/patches/860-brcmsmac-implement-ieee80211_ops-get_tsf-and-set_tsf.patch new file mode 100644 index 0000000..33991bc --- /dev/null +++ b/package/mac80211/patches/860-brcmsmac-implement-ieee80211_ops-get_tsf-and-set_tsf.patch @@ -0,0 +1,121 @@ +--- a/drivers/net/wireless/brcm80211/brcmsmac/d11.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/d11.h +@@ -457,6 +457,7 @@ struct d11regs { + /*== maccontrol register ==*/ + #define MCTL_GMODE (1U << 31) + #define MCTL_DISCARD_PMQ (1 << 30) ++#define MCTL_TBTTHOLD (1 << 28) + #define MCTL_WAKE (1 << 26) + #define MCTL_HPS (1 << 25) + #define MCTL_PROMISC (1 << 24) +--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +@@ -741,6 +741,28 @@ static void brcms_ops_flush(struct ieee8 + "ret=%d\n", jiffies_to_msecs(ret)); + } + ++static u64 brcms_ops_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ++{ ++ struct brcms_info *wl = hw->priv; ++ u64 tsf; ++ ++ spin_lock_bh(&wl->lock); ++ tsf = brcms_c_tsf_get(wl->wlc); ++ spin_unlock_bh(&wl->lock); ++ ++ return tsf; ++} ++ ++static void brcms_ops_set_tsf(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, u64 tsf) ++{ ++ struct brcms_info *wl = hw->priv; ++ ++ spin_lock_bh(&wl->lock); ++ brcms_c_tsf_set(wl->wlc, tsf); ++ spin_unlock_bh(&wl->lock); ++} ++ + static const struct ieee80211_ops brcms_ops = { + .tx = brcms_ops_tx, + .start = brcms_ops_start, +@@ -757,6 +779,8 @@ static const struct ieee80211_ops brcms_ + .ampdu_action = brcms_ops_ampdu_action, + .rfkill_poll = brcms_ops_rfkill_poll, + .flush = brcms_ops_flush, ++ .get_tsf = brcms_ops_get_tsf, ++ .set_tsf = brcms_ops_set_tsf, + }; + + void brcms_dpc(unsigned long data) +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -5545,6 +5545,20 @@ int brcms_c_set_rateset(struct brcms_c_i + return bcmerror; + } + ++static void brcms_c_time_lock(struct brcms_c_info *wlc) ++{ ++ bcma_set32(wlc->hw->d11core, D11REGOFFS(maccontrol), MCTL_TBTTHOLD); ++ /* Commit the write */ ++ bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol)); ++} ++ ++static void brcms_c_time_unlock(struct brcms_c_info *wlc) ++{ ++ bcma_mask32(wlc->hw->d11core, D11REGOFFS(maccontrol), ~MCTL_TBTTHOLD); ++ /* Commit the write */ ++ bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol)); ++} ++ + int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period) + { + if (period == 0) +@@ -7530,6 +7544,36 @@ void brcms_c_set_beacon_listen_interval( + brcms_c_bcn_li_upd(wlc); + } + ++u64 brcms_c_tsf_get(struct brcms_c_info *wlc) ++{ ++ u32 tsf_h, tsf_l; ++ u64 tsf; ++ ++ brcms_b_read_tsf(wlc->hw, &tsf_l, &tsf_h); ++ ++ tsf = tsf_h; ++ tsf <<= 32; ++ tsf |= tsf_l; ++ ++ return tsf; ++} ++ ++void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf) ++{ ++ u32 tsf_h, tsf_l; ++ ++ brcms_c_time_lock(wlc); ++ ++ tsf_l = tsf; ++ tsf_h = (tsf >> 32); ++ ++ /* read the tsf timer low, then high to get an atomic read */ ++ bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_timerlow), tsf_l); ++ bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_timerhigh), tsf_h); ++ ++ brcms_c_time_unlock(wlc); ++} ++ + int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr) + { + uint qdbm; +--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h +@@ -326,6 +326,8 @@ extern void brcms_c_set_shortslot_overri + s8 sslot_override); + extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, + u8 interval); ++extern u64 brcms_c_tsf_get(struct brcms_c_info *wlc); ++extern void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf); + extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr); + extern int brcms_c_get_tx_power(struct brcms_c_info *wlc); + extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc); |