Skip to content

Commit

Permalink
atheros/ath9k: add common read/write ops and port ath9k to use it
Browse files Browse the repository at this point in the history
In an effort to make hw code driver core agnostic read
and write operations are defined on the ath_common structure.
This patch adds that and makes ath9k use it. This allows
drivers like ath9k_htc to define its own read/write ops and
still rely on the same hw code. This also paves the way for
sharing code between ath9k/ath5k/ath9k_htc.

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 867633f commit 9e4bffd
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 47 deletions.
6 changes: 6 additions & 0 deletions drivers/net/wireless/ath/ath.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,19 @@ struct ath_regulatory {
struct reg_dmn_pair_mapping *regpair;
};

struct ath_ops {
unsigned int (*read)(void *, u32 reg_offset);
void (*write)(void *, u32 val, u32 reg_offset);
};

struct ath_common {
u16 cachelsz;
u16 curaid;
u8 macaddr[ETH_ALEN];
u8 curbssid[ETH_ALEN];
u8 bssidmask[ETH_ALEN];
struct ath_regulatory regulatory;
struct ath_ops *ops;
};

struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
Expand Down
13 changes: 0 additions & 13 deletions drivers/net/wireless/ath/ath9k/ath9k.h
Original file line number Diff line number Diff line change
Expand Up @@ -646,16 +646,6 @@ int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
int ath_cabq_update(struct ath_softc *);

static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
{
return &ah->common;
}

static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah)
{
return &(ath9k_hw_common(ah)->regulatory);
}

static inline void ath_read_cachesize(struct ath_softc *sc, int *csz)
{
sc->bus_ops->read_cachesize(sc, csz);
Expand Down Expand Up @@ -718,8 +708,5 @@ bool ath9k_wiphy_scanning(struct ath_softc *sc);
void ath9k_wiphy_work(struct work_struct *work);
bool ath9k_all_wiphys_idle(struct ath_softc *sc);

void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val);
unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset);

int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
#endif /* ATH9K_H */
32 changes: 0 additions & 32 deletions drivers/net/wireless/ath/ath9k/hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,38 +81,6 @@ static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
return ath9k_hw_mac_clks(ah, usecs);
}

/*
* Read and write, they both share the same lock. We do this to serialize
* reads and writes on Atheros 802.11n PCI devices only. This is required
* as the FIFO on these devices can only accept sanely 2 requests. After
* that the device goes bananas. Serializing the reads/writes prevents this
* from happening.
*/

void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val)
{
if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
unsigned long flags;
spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
iowrite32(val, ah->ah_sc->mem + reg_offset);
spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
} else
iowrite32(val, ah->ah_sc->mem + reg_offset);
}

unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset)
{
u32 val;
if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
unsigned long flags;
spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
val = ioread32(ah->ah_sc->mem + reg_offset);
spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
} else
val = ioread32(ah->ah_sc->mem + reg_offset);
return val;
}

bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
{
int i;
Expand Down
17 changes: 15 additions & 2 deletions drivers/net/wireless/ath/ath9k/hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,11 @@
#define AT9285_COEX3WIRE_DA_SUBSYSID 0x30ab

/* Register read/write primitives */
#define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val))
#define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg))
#define REG_WRITE(_ah, _reg, _val) \
ath9k_hw_common(_ah)->ops->write((_ah), (_val), (_reg))

#define REG_READ(_ah, _reg) \
ath9k_hw_common(_ah)->ops->read((_ah), (_reg))

#define SM(_v, _f) (((_v) << _f##_S) & _f)
#define MS(_v, _f) (((_v) & _f) >> _f##_S)
Expand Down Expand Up @@ -588,6 +591,16 @@ struct ath_hw {
struct ath_gen_timer_table hw_gen_timers;
};

static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
{
return &ah->common;
}

static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah)
{
return &(ath9k_hw_common(ah)->regulatory);
}

/* Initialization, Detach, Reset */
const char *ath9k_hw_probe(u16 vendorid, u16 devid);
void ath9k_hw_detach(struct ath_hw *ah);
Expand Down
42 changes: 42 additions & 0 deletions drivers/net/wireless/ath/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1489,6 +1489,47 @@ static int ath_init_btcoex_timer(struct ath_softc *sc)
return 0;
}

/*
* Read and write, they both share the same lock. We do this to serialize
* reads and writes on Atheros 802.11n PCI devices only. This is required
* as the FIFO on these devices can only accept sanely 2 requests. After
* that the device goes bananas. Serializing the reads/writes prevents this
* from happening.
*/

static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
{
struct ath_hw *ah = (struct ath_hw *) hw_priv;

if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
unsigned long flags;
spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
iowrite32(val, ah->ah_sc->mem + reg_offset);
spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
} else
iowrite32(val, ah->ah_sc->mem + reg_offset);
}

static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
{
struct ath_hw *ah = (struct ath_hw *) hw_priv;
u32 val;

if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
unsigned long flags;
spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
val = ioread32(ah->ah_sc->mem + reg_offset);
spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
} else
val = ioread32(ah->ah_sc->mem + reg_offset);
return val;
}

static struct ath_ops ath9k_common_ops = {
.read = ath9k_ioread32,
.write = ath9k_iowrite32,
};

/*
* Initialize and fill ath_softc, ath_sofct is the
* "Software Carrier" struct. Historically it has existed
Expand Down Expand Up @@ -1528,6 +1569,7 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid)
sc->sc_ah = ah;

common = ath9k_hw_common(ah);
common->ops = &ath9k_common_ops;

/*
* Cache line size is used to size and align various
Expand Down

0 comments on commit 9e4bffd

Please sign in to comment.