Commit 3a73a300 authored by Stanislaw Gruszka's avatar Stanislaw Gruszka Committed by John W. Linville

iwlwifi: cleanup/fix memory barriers

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: default avatarStanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent bfe4b80e
...@@ -334,7 +334,6 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, ...@@ -334,7 +334,6 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
/* Set starting address; reads will auto-increment */ /* Set starting address; reads will auto-increment */
iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, ptr); iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, ptr);
rmb();
/* /*
* Refuse to read more than would have fit into the log from * Refuse to read more than would have fit into the log from
......
...@@ -136,6 +136,13 @@ void iwl_release_nic_access(struct iwl_trans *trans) ...@@ -136,6 +136,13 @@ void iwl_release_nic_access(struct iwl_trans *trans)
lockdep_assert_held(&trans->reg_lock); lockdep_assert_held(&trans->reg_lock);
__iwl_clear_bit(trans, CSR_GP_CNTRL, __iwl_clear_bit(trans, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 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) u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg)
...@@ -182,7 +189,6 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, ...@@ -182,7 +189,6 @@ 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) static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 reg)
{ {
iwl_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); iwl_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
rmb();
return iwl_read32(trans, HBUS_TARG_PRPH_RDAT); return iwl_read32(trans, HBUS_TARG_PRPH_RDAT);
} }
...@@ -190,7 +196,6 @@ static inline void __iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) ...@@ -190,7 +196,6 @@ static inline void __iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val)
{ {
iwl_write32(trans, HBUS_TARG_PRPH_WADDR, iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
((addr & 0x0000FFFF) | (3 << 24))); ((addr & 0x0000FFFF) | (3 << 24)));
wmb();
iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
} }
...@@ -270,7 +275,6 @@ void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, ...@@ -270,7 +275,6 @@ void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr,
spin_lock_irqsave(&trans->reg_lock, flags); spin_lock_irqsave(&trans->reg_lock, flags);
if (likely(iwl_grab_nic_access(trans))) { if (likely(iwl_grab_nic_access(trans))) {
iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr);
rmb();
for (offs = 0; offs < words; offs++) for (offs = 0; offs < words; offs++)
vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
iwl_release_nic_access(trans); iwl_release_nic_access(trans);
...@@ -297,8 +301,6 @@ int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, ...@@ -297,8 +301,6 @@ int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr,
spin_lock_irqsave(&trans->reg_lock, flags); spin_lock_irqsave(&trans->reg_lock, flags);
if (likely(iwl_grab_nic_access(trans))) { if (likely(iwl_grab_nic_access(trans))) {
iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
wmb();
for (offs = 0; offs < words; offs++) for (offs = 0; offs < words; offs++)
iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]);
iwl_release_nic_access(trans); iwl_release_nic_access(trans);
......
...@@ -750,7 +750,6 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, ...@@ -750,7 +750,6 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
/* Set starting address; reads will auto-increment */ /* Set starting address; reads will auto-increment */
iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr); iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr);
rmb();
/* "time" is actually "data" for mode 0 (no timestamp). /* "time" is actually "data" for mode 0 (no timestamp).
* place event id # at far right for easier visual parsing. */ * place event id # at far right for easier visual parsing. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment