Skip to content

Commit

Permalink
ath9k: move btcoex core driver info to its own struct
Browse files Browse the repository at this point in the history
There is some bluetooth coexistance data which is driver
specific, stuff that into its own structure.

Cc: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Luis R. Rodriguez authored and John W. Linville committed Oct 7, 2009
1 parent 4d6b228 commit 2e20250
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 49 deletions.
11 changes: 11 additions & 0 deletions drivers/net/wireless/ath/ath9k/ath9k.h
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,16 @@ struct ath_ani {
struct timer_list timer;
};

struct ath_btcoex {
bool hw_timer_enabled;
spinlock_t btcoex_lock;
struct timer_list period_timer; /* Timer for BT period */
u32 bt_priority_cnt;
unsigned long bt_priority_time;
u32 btcoex_no_stomp; /* in usec */
u32 btcoex_period; /* in usec */
};

/********************/
/* LED Control */
/********************/
Expand Down Expand Up @@ -613,6 +623,7 @@ struct ath_softc {
struct ath_beacon_config cur_beacon_conf;
struct delayed_work tx_complete_work;
struct ath_btcoex_info btcoex_info;
struct ath_btcoex btcoex;
};

struct ath_wiphy {
Expand Down
73 changes: 38 additions & 35 deletions drivers/net/wireless/ath/ath9k/btcoex.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,23 +48,23 @@ bool ath_btcoex_supported(u16 subsysid)
*/
static void ath_detect_bt_priority(struct ath_softc *sc)
{
struct ath_btcoex_info *btinfo = &sc->btcoex_info;
struct ath_btcoex *btcoex = &sc->btcoex;

if (ath9k_hw_gpio_get(sc->sc_ah, btinfo->btpriority_gpio))
btinfo->bt_priority_cnt++;
if (ath9k_hw_gpio_get(sc->sc_ah, sc->btcoex_info.btpriority_gpio))
btcoex->bt_priority_cnt++;

if (time_after(jiffies, btinfo->bt_priority_time +
if (time_after(jiffies, btcoex->bt_priority_time +
msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) {
if (btinfo->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
DPRINTF(sc->sc_ah, ATH_DBG_BTCOEX,
"BT priority traffic detected");
sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED;
} else {
sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
}

btinfo->bt_priority_cnt = 0;
btinfo->bt_priority_time = jiffies;
btcoex->bt_priority_cnt = 0;
btcoex->bt_priority_time = jiffies;
}
}

Expand Down Expand Up @@ -106,29 +106,30 @@ static void ath_btcoex_bt_stomp(struct ath_softc *sc,
static void ath_btcoex_period_timer(unsigned long data)
{
struct ath_softc *sc = (struct ath_softc *) data;
struct ath_btcoex *btcoex = &sc->btcoex;
struct ath_btcoex_info *btinfo = &sc->btcoex_info;

ath_detect_bt_priority(sc);

spin_lock_bh(&btinfo->btcoex_lock);
spin_lock_bh(&btcoex->btcoex_lock);

ath_btcoex_bt_stomp(sc, btinfo, btinfo->bt_stomp_type);

spin_unlock_bh(&btinfo->btcoex_lock);
spin_unlock_bh(&btcoex->btcoex_lock);

if (btinfo->btcoex_period != btinfo->btcoex_no_stomp) {
if (btinfo->hw_timer_enabled)
if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) {
if (btcoex->hw_timer_enabled)
ath_gen_timer_stop(sc->sc_ah, btinfo->no_stomp_timer);

ath_gen_timer_start(sc->sc_ah,
btinfo->no_stomp_timer,
(ath9k_hw_gettsf32(sc->sc_ah) +
btinfo->btcoex_no_stomp),
btinfo->btcoex_no_stomp * 10);
btinfo->hw_timer_enabled = true;
btcoex->btcoex_no_stomp),
btcoex->btcoex_no_stomp * 10);
btcoex->hw_timer_enabled = true;
}

mod_timer(&btinfo->period_timer, jiffies +
mod_timer(&btcoex->period_timer, jiffies +
msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
}

Expand All @@ -140,23 +141,25 @@ static void ath_btcoex_period_timer(unsigned long data)
static void ath_btcoex_no_stomp_timer(void *arg)
{
struct ath_softc *sc = (struct ath_softc *)arg;
struct ath_btcoex *btcoex = &sc->btcoex;
struct ath_btcoex_info *btinfo = &sc->btcoex_info;

DPRINTF(sc->sc_ah, ATH_DBG_BTCOEX, "no stomp timer running \n");

spin_lock_bh(&btinfo->btcoex_lock);
spin_lock_bh(&btcoex->btcoex_lock);

if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_LOW)
ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_NONE);
else if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_LOW);

spin_unlock_bh(&btinfo->btcoex_lock);
spin_unlock_bh(&btcoex->btcoex_lock);
}

static int ath_init_btcoex_info(struct ath_hw *hw,
struct ath_btcoex_info *btcoex_info)
{
struct ath_btcoex *btcoex = &hw->ah_sc->btcoex;
u32 i;
int qnum;

Expand All @@ -181,15 +184,15 @@ static int ath_init_btcoex_info(struct ath_hw *hw,

btcoex_info->bt_stomp_type = ATH_BTCOEX_STOMP_LOW;

btcoex_info->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;

btcoex_info->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
btcoex_info->btcoex_period / 100;
btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
btcoex->btcoex_period / 100;

for (i = 0; i < 32; i++)
hw->hw_gen_timers.gen_timer_index[(debruijn32 << i) >> 27] = i;

setup_timer(&btcoex_info->period_timer, ath_btcoex_period_timer,
setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
(unsigned long) hw->ah_sc);

btcoex_info->no_stomp_timer = ath_gen_timer_alloc(hw,
Expand All @@ -200,7 +203,7 @@ static int ath_init_btcoex_info(struct ath_hw *hw,
if (btcoex_info->no_stomp_timer == NULL)
return -ENOMEM;

spin_lock_init(&btcoex_info->btcoex_lock);
spin_lock_init(&btcoex->btcoex_lock);

return 0;
}
Expand Down Expand Up @@ -307,34 +310,34 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
/*
* Pause btcoex timer and bt duty cycle timer
*/
void ath_btcoex_timer_pause(struct ath_softc *sc,
struct ath_btcoex_info *btinfo)
void ath_btcoex_timer_pause(struct ath_softc *sc)
{
struct ath_btcoex *btcoex = &sc->btcoex;

del_timer_sync(&btinfo->period_timer);
del_timer_sync(&btcoex->period_timer);

if (btinfo->hw_timer_enabled)
ath_gen_timer_stop(sc->sc_ah, btinfo->no_stomp_timer);
if (btcoex->hw_timer_enabled)
ath_gen_timer_stop(sc->sc_ah, sc->btcoex_info.no_stomp_timer);

btinfo->hw_timer_enabled = false;
btcoex->hw_timer_enabled = false;
}

/*
* (Re)start btcoex timers
*/
void ath_btcoex_timer_resume(struct ath_softc *sc,
struct ath_btcoex_info *btinfo)
void ath_btcoex_timer_resume(struct ath_softc *sc)
{
struct ath_btcoex *btcoex = &sc->btcoex;

DPRINTF(sc->sc_ah, ATH_DBG_BTCOEX, "Starting btcoex timers");

/* make sure duty cycle timer is also stopped when resuming */
if (btinfo->hw_timer_enabled)
ath_gen_timer_stop(sc->sc_ah, btinfo->no_stomp_timer);
if (btcoex->hw_timer_enabled)
ath_gen_timer_stop(sc->sc_ah, sc->btcoex_info.no_stomp_timer);

btinfo->bt_priority_cnt = 0;
btinfo->bt_priority_time = jiffies;
btcoex->bt_priority_cnt = 0;
btcoex->bt_priority_time = jiffies;
sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;

mod_timer(&btinfo->period_timer, jiffies);
mod_timer(&btcoex->period_timer, jiffies);
}
16 changes: 4 additions & 12 deletions drivers/net/wireless/ath/ath9k/btcoex.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,30 +70,22 @@ struct ath_btcoex_info {
u32 bt_coex_mode; /* Register setting for AR_BT_COEX_MODE */
u32 bt_coex_weights; /* Register setting for AR_BT_COEX_WEIGHT */
u32 bt_coex_mode2; /* Register setting for AR_BT_COEX_MODE2 */
u32 btcoex_no_stomp; /* in usec */
u32 btcoex_period; /* in usec */
u32 bt_priority_cnt;
unsigned long bt_priority_time;
bool hw_timer_enabled;
spinlock_t btcoex_lock;
struct timer_list period_timer; /* Timer for BT period */
struct ath_gen_timer *no_stomp_timer; /*Timer for no BT stomping*/
};

bool ath_btcoex_supported(u16 subsysid);
int ath9k_hw_btcoex_init(struct ath_hw *ah);
void ath9k_hw_btcoex_enable(struct ath_hw *ah);
void ath9k_hw_btcoex_disable(struct ath_hw *ah);
void ath_btcoex_timer_resume(struct ath_softc *sc,
struct ath_btcoex_info *btinfo);
void ath_btcoex_timer_pause(struct ath_softc *sc,
struct ath_btcoex_info *btinfo);

void ath_btcoex_timer_resume(struct ath_softc *sc);
void ath_btcoex_timer_pause(struct ath_softc *sc);

static inline void ath_btcoex_set_weight(struct ath_btcoex_info *btcoex_info,
u32 bt_weight,
u32 wlan_weight)
{
btcoex_info->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) |
btcoex_info->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) |
SM(wlan_weight, AR_BTCOEX_WL_WGHT);
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/net/wireless/ath/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2013,7 +2013,7 @@ static int ath9k_start(struct ieee80211_hw *hw)

ath_pcie_aspm_disable(sc);
if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
ath_btcoex_timer_resume(sc, &sc->btcoex_info);
ath_btcoex_timer_resume(sc);
}

mutex_unlock:
Expand Down Expand Up @@ -2152,7 +2152,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
if (sc->sc_flags & SC_OP_BTCOEX_ENABLED) {
ath9k_hw_btcoex_disable(sc->sc_ah);
if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
ath_btcoex_timer_pause(sc, &sc->btcoex_info);
ath_btcoex_timer_pause(sc);
}

/* make sure h/w will not generate any interrupt
Expand Down

0 comments on commit 2e20250

Please sign in to comment.