Skip to content

Commit

Permalink
iwlwifi: cleanup/fix memory barriers
Browse files Browse the repository at this point in the history
wmb(), rmb() are not needed when writel(), readl() are used as
accessors for MMIO. We use them indirectly via iowrite32(),
ioread32().

What is needed mmiowb(), for synchronizing writes coming from
different CPUs on PCIe bridge (see in patch comments). This
fortunately is not needed on x86, where mmiowb() is just
defined as compiler barrier. As iwlwifi devices are most likely
not used on anything other than x86, this is not so important
fix.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Stanislaw Gruszka authored and John W. Linville committed Mar 8, 2012
1 parent bfe4b80 commit 3a73a30
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 7 deletions.
1 change: 0 additions & 1 deletion drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,6 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,

/* Set starting address; reads will auto-increment */
iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, ptr);
rmb();

/*
* Refuse to read more than would have fit into the log from
Expand Down
12 changes: 7 additions & 5 deletions drivers/net/wireless/iwlwifi/iwl-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@ void iwl_release_nic_access(struct iwl_trans *trans)
lockdep_assert_held(&trans->reg_lock);
__iwl_clear_bit(trans, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
/*
* Above we read the CSR_GP_CNTRL register, which will flush
* any previous writes, but we need the write that clears the
* MAC_ACCESS_REQ bit to be performed before any other writes
* scheduled on different CPUs (after we drop reg_lock).
*/
mmiowb();
}

u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg)
Expand Down Expand Up @@ -182,15 +189,13 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 reg)
{
iwl_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
rmb();
return iwl_read32(trans, HBUS_TARG_PRPH_RDAT);
}

static inline void __iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val)
{
iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
((addr & 0x0000FFFF) | (3 << 24)));
wmb();
iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
}

Expand Down Expand Up @@ -270,7 +275,6 @@ void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr,
spin_lock_irqsave(&trans->reg_lock, flags);
if (likely(iwl_grab_nic_access(trans))) {
iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr);
rmb();
for (offs = 0; offs < words; offs++)
vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
iwl_release_nic_access(trans);
Expand All @@ -297,8 +301,6 @@ int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr,
spin_lock_irqsave(&trans->reg_lock, flags);
if (likely(iwl_grab_nic_access(trans))) {
iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
wmb();

for (offs = 0; offs < words; offs++)
iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]);
iwl_release_nic_access(trans);
Expand Down
1 change: 0 additions & 1 deletion drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,6 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,

/* Set starting address; reads will auto-increment */
iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr);
rmb();

/* "time" is actually "data" for mode 0 (no timestamp).
* place event id # at far right for easier visual parsing. */
Expand Down

0 comments on commit 3a73a30

Please sign in to comment.