diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2012-12-24 07:27:11 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-01-03 09:30:19 -0500 |
commit | 4fd442db98dadf33ecce6d489bbbc95f6e8d3b31 (patch) | |
tree | 9eff5b52f5533a4864050a2829b9e849879b990a /drivers/net/wireless/iwlwifi/pcie | |
parent | 7a65d17053c758109477f420e813ba2d826b0eae (diff) |
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) | |||
820 | mmiowb(); | 820 | mmiowb(); |
821 | } | 821 | } |
822 | 822 | ||
823 | static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, | ||
824 | void *buf, int dwords) | ||
825 | { | ||
826 | unsigned long flags; | ||
827 | int offs, ret = 0; | ||
828 | u32 *vals = buf; | ||
829 | |||
830 | spin_lock_irqsave(&trans->reg_lock, flags); | ||
831 | if (likely(iwl_trans_grab_nic_access(trans, false))) { | ||
832 | iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); | ||
833 | for (offs = 0; offs < dwords; offs++) | ||
834 | vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); | ||
835 | iwl_trans_release_nic_access(trans); | ||
836 | } else { | ||
837 | ret = -EBUSY; | ||
838 | } | ||
839 | spin_unlock_irqrestore(&trans->reg_lock, flags); | ||
840 | return ret; | ||
841 | } | ||
842 | |||
843 | static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr, | ||
844 | void *buf, int dwords) | ||
845 | { | ||
846 | unsigned long flags; | ||
847 | int offs, ret = 0; | ||
848 | u32 *vals = buf; | ||
849 | |||
850 | spin_lock_irqsave(&trans->reg_lock, flags); | ||
851 | if (likely(iwl_trans_grab_nic_access(trans, false))) { | ||
852 | iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); | ||
853 | for (offs = 0; offs < dwords; offs++) | ||
854 | iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); | ||
855 | iwl_trans_release_nic_access(trans); | ||
856 | } else { | ||
857 | ret = -EBUSY; | ||
858 | } | ||
859 | spin_unlock_irqrestore(&trans->reg_lock, flags); | ||
860 | return ret; | ||
861 | } | ||
823 | 862 | ||
824 | #define IWL_FLUSH_WAIT_MS 2000 | 863 | #define IWL_FLUSH_WAIT_MS 2000 |
825 | 864 | ||
@@ -1298,6 +1337,8 @@ static const struct iwl_trans_ops trans_ops_pcie = { | |||
1298 | .read32 = iwl_trans_pcie_read32, | 1337 | .read32 = iwl_trans_pcie_read32, |
1299 | .read_prph = iwl_trans_pcie_read_prph, | 1338 | .read_prph = iwl_trans_pcie_read_prph, |
1300 | .write_prph = iwl_trans_pcie_write_prph, | 1339 | .write_prph = iwl_trans_pcie_write_prph, |
1340 | .read_mem = iwl_trans_pcie_read_mem, | ||
1341 | .write_mem = iwl_trans_pcie_write_mem, | ||
1301 | .configure = iwl_trans_pcie_configure, | 1342 | .configure = iwl_trans_pcie_configure, |
1302 | .set_pmi = iwl_trans_pcie_set_pmi, | 1343 | .set_pmi = iwl_trans_pcie_set_pmi, |
1303 | .grab_nic_access = iwl_trans_pcie_grab_nic_access, | 1344 | .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) | |||
160 | IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", | 160 | IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", |
161 | txq->q.read_ptr, txq->q.write_ptr); | 161 | txq->q.read_ptr, txq->q.write_ptr); |
162 | 162 | ||
163 | iwl_read_targ_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf)); | 163 | iwl_trans_read_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf)); |
164 | 164 | ||
165 | iwl_print_hex_error(trans, buf, sizeof(buf)); | 165 | iwl_print_hex_error(trans, buf, sizeof(buf)); |
166 | 166 | ||
@@ -173,9 +173,9 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data) | |||
173 | u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7; | 173 | u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7; |
174 | bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE)); | 174 | bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE)); |
175 | u32 tbl_dw = | 175 | u32 tbl_dw = |
176 | iwl_read_targ_mem(trans, | 176 | iwl_trans_read_mem32(trans, |
177 | trans_pcie->scd_base_addr + | 177 | trans_pcie->scd_base_addr + |
178 | SCD_TRANS_TBL_OFFSET_QUEUE(i)); | 178 | SCD_TRANS_TBL_OFFSET_QUEUE(i)); |
179 | 179 | ||
180 | if (i & 0x1) | 180 | if (i & 0x1) |
181 | tbl_dw = (tbl_dw & 0xFFFF0000) >> 16; | 181 | tbl_dw = (tbl_dw & 0xFFFF0000) >> 16; |
@@ -659,16 +659,16 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) | |||
659 | /* reset conext data memory */ | 659 | /* reset conext data memory */ |
660 | for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND; | 660 | for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND; |
661 | a += 4) | 661 | a += 4) |
662 | iwl_write_targ_mem(trans, a, 0); | 662 | iwl_trans_write_mem32(trans, a, 0); |
663 | /* reset tx status memory */ | 663 | /* reset tx status memory */ |
664 | for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND; | 664 | for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND; |
665 | a += 4) | 665 | a += 4) |
666 | iwl_write_targ_mem(trans, a, 0); | 666 | iwl_trans_write_mem32(trans, a, 0); |
667 | for (; a < trans_pcie->scd_base_addr + | 667 | for (; a < trans_pcie->scd_base_addr + |
668 | SCD_TRANS_TBL_OFFSET_QUEUE( | 668 | SCD_TRANS_TBL_OFFSET_QUEUE( |
669 | trans->cfg->base_params->num_of_queues); | 669 | trans->cfg->base_params->num_of_queues); |
670 | a += 4) | 670 | a += 4) |
671 | iwl_write_targ_mem(trans, a, 0); | 671 | iwl_trans_write_mem32(trans, a, 0); |
672 | 672 | ||
673 | iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, | 673 | iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, |
674 | trans_pcie->scd_bc_tbls.dma >> 10); | 674 | 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, | |||
1005 | tbl_dw_addr = trans_pcie->scd_base_addr + | 1005 | tbl_dw_addr = trans_pcie->scd_base_addr + |
1006 | SCD_TRANS_TBL_OFFSET_QUEUE(txq_id); | 1006 | SCD_TRANS_TBL_OFFSET_QUEUE(txq_id); |
1007 | 1007 | ||
1008 | tbl_dw = iwl_read_targ_mem(trans, tbl_dw_addr); | 1008 | tbl_dw = iwl_trans_read_mem32(trans, tbl_dw_addr); |
1009 | 1009 | ||
1010 | if (txq_id & 0x1) | 1010 | if (txq_id & 0x1) |
1011 | tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); | 1011 | tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); |
1012 | else | 1012 | else |
1013 | tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); | 1013 | tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); |
1014 | 1014 | ||
1015 | iwl_write_targ_mem(trans, tbl_dw_addr, tbl_dw); | 1015 | iwl_trans_write_mem32(trans, tbl_dw_addr, tbl_dw); |
1016 | 1016 | ||
1017 | return 0; | 1017 | return 0; |
1018 | } | 1018 | } |
@@ -1071,9 +1071,9 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | |||
1071 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); | 1071 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); |
1072 | 1072 | ||
1073 | /* Set up Tx window size and frame limit for this queue */ | 1073 | /* Set up Tx window size and frame limit for this queue */ |
1074 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + | 1074 | iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + |
1075 | SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); | 1075 | SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); |
1076 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + | 1076 | iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + |
1077 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), | 1077 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), |
1078 | ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & | 1078 | ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & |
1079 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | | 1079 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | |
@@ -1104,8 +1104,8 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) | |||
1104 | 1104 | ||
1105 | iwl_pcie_txq_set_inactive(trans, txq_id); | 1105 | iwl_pcie_txq_set_inactive(trans, txq_id); |
1106 | 1106 | ||
1107 | _iwl_write_targ_mem_dwords(trans, stts_addr, | 1107 | iwl_trans_write_mem(trans, stts_addr, (void *)zero_val, |
1108 | zero_val, ARRAY_SIZE(zero_val)); | 1108 | ARRAY_SIZE(zero_val)); |
1109 | 1109 | ||
1110 | iwl_pcie_txq_unmap(trans, txq_id); | 1110 | iwl_pcie_txq_unmap(trans, txq_id); |
1111 | 1111 | ||