diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2012-12-24 16:27:11 +0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-01-03 18:30:19 +0400 |
commit | 4fd442db98dadf33ecce6d489bbbc95f6e8d3b31 (patch) | |
tree | 9eff5b52f5533a4864050a2829b9e849879b990a /drivers/net/wireless/iwlwifi/pcie | |
parent | 7a65d17053c758109477f420e813ba2d826b0eae (diff) | |
download | linux-4fd442db98dadf33ecce6d489bbbc95f6e8d3b31.tar.xz |
iwlwifi: virtualize SRAM access
Different transports implement the access to the SRAM in
different ways. Virtualize it.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/pcie')
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/trans.c | 41 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/tx.c | 26 |
2 files changed, 54 insertions, 13 deletions
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 80b05d821688..3a40607ed542 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -820,6 +820,45 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans) mmiowb(); } +static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, + void *buf, int dwords) +{ + unsigned long flags; + int offs, ret = 0; + u32 *vals = buf; + + spin_lock_irqsave(&trans->reg_lock, flags); + if (likely(iwl_trans_grab_nic_access(trans, false))) { + iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); + for (offs = 0; offs < dwords; offs++) + vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); + iwl_trans_release_nic_access(trans); + } else { + ret = -EBUSY; + } + spin_unlock_irqrestore(&trans->reg_lock, flags); + return ret; +} + +static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr, + void *buf, int dwords) +{ + unsigned long flags; + int offs, ret = 0; + u32 *vals = buf; + + spin_lock_irqsave(&trans->reg_lock, flags); + if (likely(iwl_trans_grab_nic_access(trans, false))) { + iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); + for (offs = 0; offs < dwords; offs++) + iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); + iwl_trans_release_nic_access(trans); + } else { + ret = -EBUSY; + } + spin_unlock_irqrestore(&trans->reg_lock, flags); + return ret; +} #define IWL_FLUSH_WAIT_MS 2000 @@ -1298,6 +1337,8 @@ static const struct iwl_trans_ops trans_ops_pcie = { .read32 = iwl_trans_pcie_read32, .read_prph = iwl_trans_pcie_read_prph, .write_prph = iwl_trans_pcie_write_prph, + .read_mem = iwl_trans_pcie_read_mem, + .write_mem = iwl_trans_pcie_write_mem, .configure = iwl_trans_pcie_configure, .set_pmi = iwl_trans_pcie_set_pmi, .grab_nic_access = iwl_trans_pcie_grab_nic_access, diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 7af8f0b55d2d..d25fc8aaccc6 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -160,7 +160,7 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data) IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", txq->q.read_ptr, txq->q.write_ptr); - iwl_read_targ_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf)); + iwl_trans_read_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf)); iwl_print_hex_error(trans, buf, sizeof(buf)); @@ -173,9 +173,9 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data) u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7; bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE)); u32 tbl_dw = - iwl_read_targ_mem(trans, - trans_pcie->scd_base_addr + - SCD_TRANS_TBL_OFFSET_QUEUE(i)); + iwl_trans_read_mem32(trans, + trans_pcie->scd_base_addr + + SCD_TRANS_TBL_OFFSET_QUEUE(i)); if (i & 0x1) tbl_dw = (tbl_dw & 0xFFFF0000) >> 16; @@ -659,16 +659,16 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) /* reset conext data memory */ for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND; a += 4) - iwl_write_targ_mem(trans, a, 0); + iwl_trans_write_mem32(trans, a, 0); /* reset tx status memory */ for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND; a += 4) - iwl_write_targ_mem(trans, a, 0); + iwl_trans_write_mem32(trans, a, 0); for (; a < trans_pcie->scd_base_addr + SCD_TRANS_TBL_OFFSET_QUEUE( trans->cfg->base_params->num_of_queues); a += 4) - iwl_write_targ_mem(trans, a, 0); + iwl_trans_write_mem32(trans, a, 0); iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, trans_pcie->scd_bc_tbls.dma >> 10); @@ -1005,14 +1005,14 @@ static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, tbl_dw_addr = trans_pcie->scd_base_addr + SCD_TRANS_TBL_OFFSET_QUEUE(txq_id); - tbl_dw = iwl_read_targ_mem(trans, tbl_dw_addr); + tbl_dw = iwl_trans_read_mem32(trans, tbl_dw_addr); if (txq_id & 0x1) tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); else tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); - iwl_write_targ_mem(trans, tbl_dw_addr, tbl_dw); + iwl_trans_write_mem32(trans, tbl_dw_addr, tbl_dw); return 0; } @@ -1071,9 +1071,9 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); /* Set up Tx window size and frame limit for this queue */ - iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + + iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); - iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + + iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | @@ -1104,8 +1104,8 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) iwl_pcie_txq_set_inactive(trans, txq_id); - _iwl_write_targ_mem_dwords(trans, stts_addr, - zero_val, ARRAY_SIZE(zero_val)); + iwl_trans_write_mem(trans, stts_addr, (void *)zero_val, + ARRAY_SIZE(zero_val)); iwl_pcie_txq_unmap(trans, txq_id); |