aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-04-05 12:42:12 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-07 15:52:28 -0400
commit02a7fa00a6d145037d549c779ad7692deb504acc (patch)
tree29ce5519266fc3287890a34ba4f90d4afc987544 /drivers/net
parent519d8abd358afad825a1b919a2421d76779f23cd (diff)
iwlagn: move IO functions out of line
This generates a massive reduction in module size: with debug: text data bss dec hex filename 670300 13136 420 683856 a6f50 iwlagn.ko (before) 388347 13136 408 401891 621e3 iwlagn.ko (after) without debug: text data bss dec hex filename 528575 13072 420 542067 84573 iwlagn.ko (before) 294192 13072 408 307672 4b1d8 iwlagn.ko (after) This also removes all the IO debug functionality since it can easily be replaced by tracing, and makes the code unnecessarily complex. I haven't done any CPU utilisation measurements, but given that the hotpaths don't use much IO it is not likely to have a negative impact; in fact, the size reduction will reduce cache pressure which possibly improves performance. Finally, an unused function or two were removed. 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>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c36
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c274
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h489
8 files changed, 326 insertions, 503 deletions
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 9d6ee836426c..3652931753e0 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -2,7 +2,7 @@
2obj-$(CONFIG_IWLAGN) += iwlagn.o 2obj-$(CONFIG_IWLAGN) += iwlagn.o
3iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o 3iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o
4iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o 4iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o
5iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o 5iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o
6iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o 6iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o
7 7
8iwlagn-objs += iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o 8iwlagn-objs += iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
index c6dd9b755a05..3bcaa10f9929 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
@@ -103,7 +103,7 @@ int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
103 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, 103 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
104 EEPROM_SEM_TIMEOUT); 104 EEPROM_SEM_TIMEOUT);
105 if (ret >= 0) { 105 if (ret >= 0) {
106 IWL_DEBUG_IO(priv, 106 IWL_DEBUG_EEPROM(priv,
107 "Acquired semaphore after %d tries.\n", 107 "Acquired semaphore after %d tries.\n",
108 count+1); 108 count+1);
109 return ret; 109 return ret;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index 5187a2c20644..01a6d2fc795c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -561,7 +561,7 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv,
561 * if IWL_DL_IO is set */ 561 * if IWL_DL_IO is set */
562 iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, 562 iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
563 i + IWLAGN_RTC_INST_LOWER_BOUND); 563 i + IWLAGN_RTC_INST_LOWER_BOUND);
564 val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 564 val = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
565 if (val != le32_to_cpu(*image)) 565 if (val != le32_to_cpu(*image))
566 return -EIO; 566 return -EIO;
567 } 567 }
@@ -587,9 +587,7 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv,
587 offs < len && errors < 20; 587 offs < len && errors < 20;
588 offs += sizeof(u32), image++) { 588 offs += sizeof(u32), image++) {
589 /* read data comes through single port, auto-incr addr */ 589 /* read data comes through single port, auto-incr addr */
590 /* NOTE: Use the debugless read so we don't flood kernel log 590 val = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
591 * if IWL_DL_IO is set */
592 val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
593 if (val != le32_to_cpu(*image)) { 591 if (val != le32_to_cpu(*image)) {
594 IWL_ERR(priv, "uCode INST section at " 592 IWL_ERR(priv, "uCode INST section at "
595 "offset 0x%x, is 0x%x, s/b 0x%x\n", 593 "offset 0x%x, is 0x%x, s/b 0x%x\n",
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index fd3aed8ed960..60bfde75ce87 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -558,7 +558,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
558 } 558 }
559 559
560 /* Set starting address; reads will auto-increment */ 560 /* Set starting address; reads will auto-increment */
561 _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); 561 iwl_write32(priv, HBUS_TARG_MEM_RADDR, ptr);
562 rmb(); 562 rmb();
563 563
564 /* 564 /*
@@ -566,13 +566,13 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
566 * place event id # at far right for easier visual parsing. 566 * place event id # at far right for easier visual parsing.
567 */ 567 */
568 for (i = 0; i < num_events; i++) { 568 for (i = 0; i < num_events; i++) {
569 ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 569 ev = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
570 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 570 time = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
571 if (mode == 0) { 571 if (mode == 0) {
572 trace_iwlwifi_dev_ucode_cont_event(priv, 572 trace_iwlwifi_dev_ucode_cont_event(priv,
573 0, time, ev); 573 0, time, ev);
574 } else { 574 } else {
575 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 575 data = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
576 trace_iwlwifi_dev_ucode_cont_event(priv, 576 trace_iwlwifi_dev_ucode_cont_event(priv,
577 time, data, ev); 577 time, data, ev);
578 } 578 }
@@ -1963,14 +1963,14 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1963 iwl_grab_nic_access(priv); 1963 iwl_grab_nic_access(priv);
1964 1964
1965 /* Set starting address; reads will auto-increment */ 1965 /* Set starting address; reads will auto-increment */
1966 _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); 1966 iwl_write32(priv, HBUS_TARG_MEM_RADDR, ptr);
1967 rmb(); 1967 rmb();
1968 1968
1969 /* "time" is actually "data" for mode 0 (no timestamp). 1969 /* "time" is actually "data" for mode 0 (no timestamp).
1970 * place event id # at far right for easier visual parsing. */ 1970 * place event id # at far right for easier visual parsing. */
1971 for (i = 0; i < num_events; i++) { 1971 for (i = 0; i < num_events; i++) {
1972 ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1972 ev = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
1973 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1973 time = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
1974 if (mode == 0) { 1974 if (mode == 0) {
1975 /* data, ev */ 1975 /* data, ev */
1976 if (bufsz) { 1976 if (bufsz) {
@@ -1984,7 +1984,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1984 time, ev); 1984 time, ev);
1985 } 1985 }
1986 } else { 1986 } else {
1987 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1987 data = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
1988 if (bufsz) { 1988 if (bufsz) {
1989 pos += scnprintf(*buf + pos, bufsz - pos, 1989 pos += scnprintf(*buf + pos, bufsz - pos,
1990 "EVT_LOGT:%010u:0x%08x:%04u\n", 1990 "EVT_LOGT:%010u:0x%08x:%04u\n",
@@ -3689,7 +3689,7 @@ static u32 iwl_hw_detect(struct iwl_priv *priv)
3689 3689
3690 pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id); 3690 pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
3691 IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); 3691 IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
3692 return _iwl_read32(priv, CSR_HW_REV); 3692 return iwl_read32(priv, CSR_HW_REV);
3693} 3693}
3694 3694
3695static int iwl_set_hw_params(struct iwl_priv *priv) 3695static int iwl_set_hw_params(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 8489431ceb8b..2824ccbcc1fc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -146,7 +146,6 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
146#define IWL_DL_RX (1 << 24) 146#define IWL_DL_RX (1 << 24)
147#define IWL_DL_ISR (1 << 25) 147#define IWL_DL_ISR (1 << 25)
148#define IWL_DL_HT (1 << 26) 148#define IWL_DL_HT (1 << 26)
149#define IWL_DL_IO (1 << 27)
150/* 0xF0000000 - 0x10000000 */ 149/* 0xF0000000 - 0x10000000 */
151#define IWL_DL_11H (1 << 28) 150#define IWL_DL_11H (1 << 28)
152#define IWL_DL_STATS (1 << 29) 151#define IWL_DL_STATS (1 << 29)
@@ -174,7 +173,6 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
174 IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a) 173 IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a)
175#define IWL_DEBUG_AP(p, f, a...) IWL_DEBUG(p, IWL_DL_AP, f, ## a) 174#define IWL_DEBUG_AP(p, f, a...) IWL_DEBUG(p, IWL_DL_AP, f, ## a)
176#define IWL_DEBUG_TXPOWER(p, f, a...) IWL_DEBUG(p, IWL_DL_TXPOWER, f, ## a) 175#define IWL_DEBUG_TXPOWER(p, f, a...) IWL_DEBUG(p, IWL_DL_TXPOWER, f, ## a)
177#define IWL_DEBUG_IO(p, f, a...) IWL_DEBUG(p, IWL_DL_IO, f, ## a)
178#define IWL_DEBUG_RATE(p, f, a...) IWL_DEBUG(p, IWL_DL_RATE, f, ## a) 176#define IWL_DEBUG_RATE(p, f, a...) IWL_DEBUG(p, IWL_DL_RATE, f, ## a)
179#define IWL_DEBUG_RATE_LIMIT(p, f, a...) \ 177#define IWL_DEBUG_RATE_LIMIT(p, f, a...) \
180 IWL_DEBUG_LIMIT(p, IWL_DL_RATE, f, ## a) 178 IWL_DEBUG_LIMIT(p, IWL_DL_RATE, f, ## a)
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 4f8c13e9850b..859b94a12297 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -226,15 +226,15 @@ static int iwl_init_otp_access(struct iwl_priv *priv)
226 int ret; 226 int ret;
227 227
228 /* Enable 40MHz radio clock */ 228 /* Enable 40MHz radio clock */
229 _iwl_write32(priv, CSR_GP_CNTRL, 229 iwl_write32(priv, CSR_GP_CNTRL,
230 _iwl_read32(priv, CSR_GP_CNTRL) | 230 iwl_read32(priv, CSR_GP_CNTRL) |
231 CSR_GP_CNTRL_REG_FLAG_INIT_DONE); 231 CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
232 232
233 /* wait for clock to be ready */ 233 /* wait for clock to be ready */
234 ret = iwl_poll_bit(priv, CSR_GP_CNTRL, 234 ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
235 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 235 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
236 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 236 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
237 25000); 237 25000);
238 if (ret < 0) 238 if (ret < 0)
239 IWL_ERR(priv, "Time out access OTP\n"); 239 IWL_ERR(priv, "Time out access OTP\n");
240 else { 240 else {
@@ -261,17 +261,17 @@ static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, __le16 *eeprom_dat
261 u32 r; 261 u32 r;
262 u32 otpgp; 262 u32 otpgp;
263 263
264 _iwl_write32(priv, CSR_EEPROM_REG, 264 iwl_write32(priv, CSR_EEPROM_REG,
265 CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); 265 CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
266 ret = iwl_poll_bit(priv, CSR_EEPROM_REG, 266 ret = iwl_poll_bit(priv, CSR_EEPROM_REG,
267 CSR_EEPROM_REG_READ_VALID_MSK, 267 CSR_EEPROM_REG_READ_VALID_MSK,
268 CSR_EEPROM_REG_READ_VALID_MSK, 268 CSR_EEPROM_REG_READ_VALID_MSK,
269 IWL_EEPROM_ACCESS_TIMEOUT); 269 IWL_EEPROM_ACCESS_TIMEOUT);
270 if (ret < 0) { 270 if (ret < 0) {
271 IWL_ERR(priv, "Time out reading OTP[%d]\n", addr); 271 IWL_ERR(priv, "Time out reading OTP[%d]\n", addr);
272 return ret; 272 return ret;
273 } 273 }
274 r = _iwl_read_direct32(priv, CSR_EEPROM_REG); 274 r = iwl_read32(priv, CSR_EEPROM_REG);
275 /* check for ECC errors: */ 275 /* check for ECC errors: */
276 otpgp = iwl_read32(priv, CSR_OTP_GP_REG); 276 otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
277 if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { 277 if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
@@ -442,9 +442,9 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
442 ret = -ENOENT; 442 ret = -ENOENT;
443 goto done; 443 goto done;
444 } 444 }
445 _iwl_write32(priv, CSR_EEPROM_GP, 445 iwl_write32(priv, CSR_EEPROM_GP,
446 iwl_read32(priv, CSR_EEPROM_GP) & 446 iwl_read32(priv, CSR_EEPROM_GP) &
447 ~CSR_EEPROM_GP_IF_OWNER_MSK); 447 ~CSR_EEPROM_GP_IF_OWNER_MSK);
448 448
449 iwl_set_bit(priv, CSR_OTP_GP_REG, 449 iwl_set_bit(priv, CSR_OTP_GP_REG,
450 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | 450 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
@@ -471,8 +471,8 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
471 for (addr = 0; addr < sz; addr += sizeof(u16)) { 471 for (addr = 0; addr < sz; addr += sizeof(u16)) {
472 u32 r; 472 u32 r;
473 473
474 _iwl_write32(priv, CSR_EEPROM_REG, 474 iwl_write32(priv, CSR_EEPROM_REG,
475 CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); 475 CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
476 476
477 ret = iwl_poll_bit(priv, CSR_EEPROM_REG, 477 ret = iwl_poll_bit(priv, CSR_EEPROM_REG,
478 CSR_EEPROM_REG_READ_VALID_MSK, 478 CSR_EEPROM_REG_READ_VALID_MSK,
@@ -482,7 +482,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
482 IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr); 482 IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr);
483 goto done; 483 goto done;
484 } 484 }
485 r = _iwl_read_direct32(priv, CSR_EEPROM_REG); 485 r = iwl_read32(priv, CSR_EEPROM_REG);
486 e[addr / 2] = cpu_to_le16(r >> 16); 486 e[addr / 2] = cpu_to_le16(r >> 16);
487 } 487 }
488 } 488 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
new file mode 100644
index 000000000000..51337416e4ca
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -0,0 +1,274 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 *
5 * Portions of this file are derived from the ipw3945 project.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 *
20 * The full GNU General Public License is included in this distribution in the
21 * file called LICENSE.
22 *
23 * Contact Information:
24 * Intel Linux Wireless <ilw@linux.intel.com>
25 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
26 *
27 *****************************************************************************/
28
29#include "iwl-io.h"
30
31#define IWL_POLL_INTERVAL 10 /* microseconds */
32
33static inline void __iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask)
34{
35 iwl_write32(priv, reg, iwl_read32(priv, reg) | mask);
36}
37
38static inline void __iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
39{
40 iwl_write32(priv, reg, iwl_read32(priv, reg) & ~mask);
41}
42
43void iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask)
44{
45 unsigned long flags;
46
47 spin_lock_irqsave(&priv->reg_lock, flags);
48 __iwl_set_bit(priv, reg, mask);
49 spin_unlock_irqrestore(&priv->reg_lock, flags);
50}
51
52void iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
53{
54 unsigned long flags;
55
56 spin_lock_irqsave(&priv->reg_lock, flags);
57 __iwl_clear_bit(priv, reg, mask);
58 spin_unlock_irqrestore(&priv->reg_lock, flags);
59}
60
61int iwl_poll_bit(struct iwl_priv *priv, u32 addr,
62 u32 bits, u32 mask, int timeout)
63{
64 int t = 0;
65
66 do {
67 if ((iwl_read32(priv, addr) & mask) == (bits & mask))
68 return t;
69 udelay(IWL_POLL_INTERVAL);
70 t += IWL_POLL_INTERVAL;
71 } while (t < timeout);
72
73 return -ETIMEDOUT;
74}
75
76int iwl_grab_nic_access(struct iwl_priv *priv)
77{
78 int ret;
79 u32 val;
80
81 lockdep_assert_held(&priv->reg_lock);
82
83 /* this bit wakes up the NIC */
84 __iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
85
86 /*
87 * These bits say the device is running, and should keep running for
88 * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
89 * but they do not indicate that embedded SRAM is restored yet;
90 * 3945 and 4965 have volatile SRAM, and must save/restore contents
91 * to/from host DRAM when sleeping/waking for power-saving.
92 * Each direction takes approximately 1/4 millisecond; with this
93 * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
94 * series of register accesses are expected (e.g. reading Event Log),
95 * to keep device from sleeping.
96 *
97 * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
98 * SRAM is okay/restored. We don't check that here because this call
99 * is just for hardware register access; but GP1 MAC_SLEEP check is a
100 * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
101 *
102 * 5000 series and later (including 1000 series) have non-volatile SRAM,
103 * and do not save/restore SRAM when power cycling.
104 */
105 ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
106 CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
107 (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
108 CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
109 if (ret < 0) {
110 val = iwl_read32(priv, CSR_GP_CNTRL);
111 IWL_ERR(priv,
112 "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
113 iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
114 return -EIO;
115 }
116
117 return 0;
118}
119
120void iwl_release_nic_access(struct iwl_priv *priv)
121{
122 lockdep_assert_held(&priv->reg_lock);
123 __iwl_clear_bit(priv, CSR_GP_CNTRL,
124 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
125}
126
127u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
128{
129 u32 value;
130 unsigned long flags;
131
132 spin_lock_irqsave(&priv->reg_lock, flags);
133 iwl_grab_nic_access(priv);
134 value = iwl_read32(priv, reg);
135 iwl_release_nic_access(priv);
136 spin_unlock_irqrestore(&priv->reg_lock, flags);
137
138 return value;
139}
140
141void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value)
142{
143 unsigned long flags;
144
145 spin_lock_irqsave(&priv->reg_lock, flags);
146 if (!iwl_grab_nic_access(priv)) {
147 iwl_write32(priv, reg, value);
148 iwl_release_nic_access(priv);
149 }
150 spin_unlock_irqrestore(&priv->reg_lock, flags);
151}
152
153int iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr, u32 mask,
154 int timeout)
155{
156 int t = 0;
157
158 do {
159 if ((iwl_read_direct32(priv, addr) & mask) == mask)
160 return t;
161 udelay(IWL_POLL_INTERVAL);
162 t += IWL_POLL_INTERVAL;
163 } while (t < timeout);
164
165 return -ETIMEDOUT;
166}
167
168static inline u32 __iwl_read_prph(struct iwl_priv *priv, u32 reg)
169{
170 iwl_write32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
171 rmb();
172 return iwl_read32(priv, HBUS_TARG_PRPH_RDAT);
173}
174
175static inline void __iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val)
176{
177 iwl_write32(priv, HBUS_TARG_PRPH_WADDR,
178 ((addr & 0x0000FFFF) | (3 << 24)));
179 wmb();
180 iwl_write32(priv, HBUS_TARG_PRPH_WDAT, val);
181}
182
183u32 iwl_read_prph(struct iwl_priv *priv, u32 reg)
184{
185 unsigned long flags;
186 u32 val;
187
188 spin_lock_irqsave(&priv->reg_lock, flags);
189 iwl_grab_nic_access(priv);
190 val = __iwl_read_prph(priv, reg);
191 iwl_release_nic_access(priv);
192 spin_unlock_irqrestore(&priv->reg_lock, flags);
193 return val;
194}
195
196void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val)
197{
198 unsigned long flags;
199
200 spin_lock_irqsave(&priv->reg_lock, flags);
201 if (!iwl_grab_nic_access(priv)) {
202 __iwl_write_prph(priv, addr, val);
203 iwl_release_nic_access(priv);
204 }
205 spin_unlock_irqrestore(&priv->reg_lock, flags);
206}
207
208void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask)
209{
210 unsigned long flags;
211
212 spin_lock_irqsave(&priv->reg_lock, flags);
213 iwl_grab_nic_access(priv);
214 __iwl_write_prph(priv, reg, __iwl_read_prph(priv, reg) | mask);
215 iwl_release_nic_access(priv);
216 spin_unlock_irqrestore(&priv->reg_lock, flags);
217}
218
219void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg,
220 u32 bits, u32 mask)
221{
222 unsigned long flags;
223
224 spin_lock_irqsave(&priv->reg_lock, flags);
225 iwl_grab_nic_access(priv);
226 __iwl_write_prph(priv, reg,
227 (__iwl_read_prph(priv, reg) & mask) | bits);
228 iwl_release_nic_access(priv);
229 spin_unlock_irqrestore(&priv->reg_lock, flags);
230}
231
232void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask)
233{
234 unsigned long flags;
235 u32 val;
236
237 spin_lock_irqsave(&priv->reg_lock, flags);
238 iwl_grab_nic_access(priv);
239 val = __iwl_read_prph(priv, reg);
240 __iwl_write_prph(priv, reg, (val & ~mask));
241 iwl_release_nic_access(priv);
242 spin_unlock_irqrestore(&priv->reg_lock, flags);
243}
244
245u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr)
246{
247 unsigned long flags;
248 u32 value;
249
250 spin_lock_irqsave(&priv->reg_lock, flags);
251 iwl_grab_nic_access(priv);
252
253 iwl_write32(priv, HBUS_TARG_MEM_RADDR, addr);
254 rmb();
255 value = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
256
257 iwl_release_nic_access(priv);
258 spin_unlock_irqrestore(&priv->reg_lock, flags);
259 return value;
260}
261
262void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val)
263{
264 unsigned long flags;
265
266 spin_lock_irqsave(&priv->reg_lock, flags);
267 if (!iwl_grab_nic_access(priv)) {
268 iwl_write32(priv, HBUS_TARG_MEM_WADDR, addr);
269 wmb();
270 iwl_write32(priv, HBUS_TARG_MEM_WDAT, val);
271 iwl_release_nic_access(priv);
272 }
273 spin_unlock_irqrestore(&priv->reg_lock, flags);
274}
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index 3ddb2fbe12f9..ab632baf49d5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -35,494 +35,47 @@
35#include "iwl-debug.h" 35#include "iwl-debug.h"
36#include "iwl-devtrace.h" 36#include "iwl-devtrace.h"
37 37
38/* 38static inline void iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val)
39 * IO, register, and NIC memory access functions
40 *
41 * NOTE on naming convention and macro usage for these
42 *
43 * A single _ prefix before a an access function means that no state
44 * check or debug information is printed when that function is called.
45 *
46 * A double __ prefix before an access function means that state is checked
47 * and the current line number and caller function name are printed in addition
48 * to any other debug output.
49 *
50 * The non-prefixed name is the #define that maps the caller into a
51 * #define that provides the caller's name and __LINE__ to the double
52 * prefix version.
53 *
54 * If you wish to call the function without any debug or state checking,
55 * you should use the single _ prefix version (as is used by dependent IO
56 * routines, for example _iwl_read_direct32 calls the non-check version of
57 * _iwl_read32.)
58 *
59 * These declarations are *extremely* useful in quickly isolating code deltas
60 * which result in misconfiguration of the hardware I/O. In combination with
61 * git-bisect and the IO debug level you can quickly determine the specific
62 * commit which breaks the IO sequence to the hardware.
63 *
64 */
65
66static inline void _iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val)
67{ 39{
68 trace_iwlwifi_dev_iowrite8(priv, ofs, val); 40 trace_iwlwifi_dev_iowrite8(priv, ofs, val);
69 iowrite8(val, priv->hw_base + ofs); 41 iowrite8(val, priv->hw_base + ofs);
70} 42}
71 43
72#ifdef CONFIG_IWLWIFI_DEBUG 44static inline void iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val)
73static inline void __iwl_write8(const char *f, u32 l, struct iwl_priv *priv,
74 u32 ofs, u8 val)
75{
76 IWL_DEBUG_IO(priv, "write8(0x%08X, 0x%02X) - %s %d\n", ofs, val, f, l);
77 _iwl_write8(priv, ofs, val);
78}
79#define iwl_write8(priv, ofs, val) \
80 __iwl_write8(__FILE__, __LINE__, priv, ofs, val)
81#else
82#define iwl_write8(priv, ofs, val) _iwl_write8(priv, ofs, val)
83#endif
84
85
86static inline void _iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val)
87{ 45{
88 trace_iwlwifi_dev_iowrite32(priv, ofs, val); 46 trace_iwlwifi_dev_iowrite32(priv, ofs, val);
89 iowrite32(val, priv->hw_base + ofs); 47 iowrite32(val, priv->hw_base + ofs);
90} 48}
91 49
92#ifdef CONFIG_IWLWIFI_DEBUG 50static inline u32 iwl_read32(struct iwl_priv *priv, u32 ofs)
93static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *priv,
94 u32 ofs, u32 val)
95{
96 IWL_DEBUG_IO(priv, "write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
97 _iwl_write32(priv, ofs, val);
98}
99#define iwl_write32(priv, ofs, val) \
100 __iwl_write32(__FILE__, __LINE__, priv, ofs, val)
101#else
102#define iwl_write32(priv, ofs, val) _iwl_write32(priv, ofs, val)
103#endif
104
105static inline u32 _iwl_read32(struct iwl_priv *priv, u32 ofs)
106{ 51{
107 u32 val = ioread32(priv->hw_base + ofs); 52 u32 val = ioread32(priv->hw_base + ofs);
108 trace_iwlwifi_dev_ioread32(priv, ofs, val); 53 trace_iwlwifi_dev_ioread32(priv, ofs, val);
109 return val; 54 return val;
110} 55}
111 56
112#ifdef CONFIG_IWLWIFI_DEBUG 57void iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask);
113static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *priv, u32 ofs) 58void iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask);
114{
115 IWL_DEBUG_IO(priv, "read_direct32(0x%08X) - %s %d\n", ofs, f, l);
116 return _iwl_read32(priv, ofs);
117}
118#define iwl_read32(priv, ofs) __iwl_read32(__FILE__, __LINE__, priv, ofs)
119#else
120#define iwl_read32(p, o) _iwl_read32(p, o)
121#endif
122
123#define IWL_POLL_INTERVAL 10 /* microseconds */
124static inline int _iwl_poll_bit(struct iwl_priv *priv, u32 addr,
125 u32 bits, u32 mask, int timeout)
126{
127 int t = 0;
128
129 do {
130 if ((_iwl_read32(priv, addr) & mask) == (bits & mask))
131 return t;
132 udelay(IWL_POLL_INTERVAL);
133 t += IWL_POLL_INTERVAL;
134 } while (t < timeout);
135
136 return -ETIMEDOUT;
137}
138#ifdef CONFIG_IWLWIFI_DEBUG
139static inline int __iwl_poll_bit(const char *f, u32 l,
140 struct iwl_priv *priv, u32 addr,
141 u32 bits, u32 mask, int timeout)
142{
143 int ret = _iwl_poll_bit(priv, addr, bits, mask, timeout);
144 IWL_DEBUG_IO(priv, "poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n",
145 addr, bits, mask,
146 unlikely(ret == -ETIMEDOUT) ? "timeout" : "", f, l);
147 return ret;
148}
149#define iwl_poll_bit(priv, addr, bits, mask, timeout) \
150 __iwl_poll_bit(__FILE__, __LINE__, priv, addr, bits, mask, timeout)
151#else
152#define iwl_poll_bit(p, a, b, m, t) _iwl_poll_bit(p, a, b, m, t)
153#endif
154
155static inline void _iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask)
156{
157 _iwl_write32(priv, reg, _iwl_read32(priv, reg) | mask);
158}
159#ifdef CONFIG_IWLWIFI_DEBUG
160static inline void __iwl_set_bit(const char *f, u32 l,
161 struct iwl_priv *priv, u32 reg, u32 mask)
162{
163 u32 val = _iwl_read32(priv, reg) | mask;
164 IWL_DEBUG_IO(priv, "set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
165 _iwl_write32(priv, reg, val);
166}
167static inline void iwl_set_bit(struct iwl_priv *p, u32 r, u32 m)
168{
169 unsigned long reg_flags;
170
171 spin_lock_irqsave(&p->reg_lock, reg_flags);
172 __iwl_set_bit(__FILE__, __LINE__, p, r, m);
173 spin_unlock_irqrestore(&p->reg_lock, reg_flags);
174}
175#else
176static inline void iwl_set_bit(struct iwl_priv *p, u32 r, u32 m)
177{
178 unsigned long reg_flags;
179
180 spin_lock_irqsave(&p->reg_lock, reg_flags);
181 _iwl_set_bit(p, r, m);
182 spin_unlock_irqrestore(&p->reg_lock, reg_flags);
183}
184#endif
185
186static inline void _iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
187{
188 _iwl_write32(priv, reg, _iwl_read32(priv, reg) & ~mask);
189}
190#ifdef CONFIG_IWLWIFI_DEBUG
191static inline void __iwl_clear_bit(const char *f, u32 l,
192 struct iwl_priv *priv, u32 reg, u32 mask)
193{
194 u32 val = _iwl_read32(priv, reg) & ~mask;
195 IWL_DEBUG_IO(priv, "clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
196 _iwl_write32(priv, reg, val);
197}
198static inline void iwl_clear_bit(struct iwl_priv *p, u32 r, u32 m)
199{
200 unsigned long reg_flags;
201
202 spin_lock_irqsave(&p->reg_lock, reg_flags);
203 __iwl_clear_bit(__FILE__, __LINE__, p, r, m);
204 spin_unlock_irqrestore(&p->reg_lock, reg_flags);
205}
206#else
207static inline void iwl_clear_bit(struct iwl_priv *p, u32 r, u32 m)
208{
209 unsigned long reg_flags;
210
211 spin_lock_irqsave(&p->reg_lock, reg_flags);
212 _iwl_clear_bit(p, r, m);
213 spin_unlock_irqrestore(&p->reg_lock, reg_flags);
214}
215#endif
216
217static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
218{
219 int ret;
220 u32 val;
221
222 /* this bit wakes up the NIC */
223 _iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
224
225 /*
226 * These bits say the device is running, and should keep running for
227 * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
228 * but they do not indicate that embedded SRAM is restored yet;
229 * 3945 and 4965 have volatile SRAM, and must save/restore contents
230 * to/from host DRAM when sleeping/waking for power-saving.
231 * Each direction takes approximately 1/4 millisecond; with this
232 * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
233 * series of register accesses are expected (e.g. reading Event Log),
234 * to keep device from sleeping.
235 *
236 * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
237 * SRAM is okay/restored. We don't check that here because this call
238 * is just for hardware register access; but GP1 MAC_SLEEP check is a
239 * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
240 *
241 * 5000 series and later (including 1000 series) have non-volatile SRAM,
242 * and do not save/restore SRAM when power cycling.
243 */
244 ret = _iwl_poll_bit(priv, CSR_GP_CNTRL,
245 CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
246 (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
247 CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
248 if (ret < 0) {
249 val = _iwl_read32(priv, CSR_GP_CNTRL);
250 IWL_ERR(priv, "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
251 _iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
252 return -EIO;
253 }
254
255 return 0;
256}
257
258#ifdef CONFIG_IWLWIFI_DEBUG
259static inline int __iwl_grab_nic_access(const char *f, u32 l,
260 struct iwl_priv *priv)
261{
262 IWL_DEBUG_IO(priv, "grabbing nic access - %s %d\n", f, l);
263 return _iwl_grab_nic_access(priv);
264}
265#define iwl_grab_nic_access(priv) \
266 __iwl_grab_nic_access(__FILE__, __LINE__, priv)
267#else
268#define iwl_grab_nic_access(priv) \
269 _iwl_grab_nic_access(priv)
270#endif
271
272static inline void _iwl_release_nic_access(struct iwl_priv *priv)
273{
274 _iwl_clear_bit(priv, CSR_GP_CNTRL,
275 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
276}
277#ifdef CONFIG_IWLWIFI_DEBUG
278static inline void __iwl_release_nic_access(const char *f, u32 l,
279 struct iwl_priv *priv)
280{
281
282 IWL_DEBUG_IO(priv, "releasing nic access - %s %d\n", f, l);
283 _iwl_release_nic_access(priv);
284}
285#define iwl_release_nic_access(priv) \
286 __iwl_release_nic_access(__FILE__, __LINE__, priv)
287#else
288#define iwl_release_nic_access(priv) \
289 _iwl_release_nic_access(priv)
290#endif
291
292static inline u32 _iwl_read_direct32(struct iwl_priv *priv, u32 reg)
293{
294 return _iwl_read32(priv, reg);
295}
296#ifdef CONFIG_IWLWIFI_DEBUG
297static inline u32 __iwl_read_direct32(const char *f, u32 l,
298 struct iwl_priv *priv, u32 reg)
299{
300 u32 value = _iwl_read_direct32(priv, reg);
301 IWL_DEBUG_IO(priv, "read_direct32(0x%4X) = 0x%08x - %s %d\n", reg, value,
302 f, l);
303 return value;
304}
305static inline u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
306{
307 u32 value;
308 unsigned long reg_flags;
309
310 spin_lock_irqsave(&priv->reg_lock, reg_flags);
311 iwl_grab_nic_access(priv);
312 value = __iwl_read_direct32(__FILE__, __LINE__, priv, reg);
313 iwl_release_nic_access(priv);
314 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
315 return value;
316}
317
318#else
319static inline u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
320{
321 u32 value;
322 unsigned long reg_flags;
323
324 spin_lock_irqsave(&priv->reg_lock, reg_flags);
325 iwl_grab_nic_access(priv);
326 value = _iwl_read_direct32(priv, reg);
327 iwl_release_nic_access(priv);
328 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
329 return value;
330
331}
332#endif
333
334static inline void _iwl_write_direct32(struct iwl_priv *priv,
335 u32 reg, u32 value)
336{
337 _iwl_write32(priv, reg, value);
338}
339static inline void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value)
340{
341 unsigned long reg_flags;
342
343 spin_lock_irqsave(&priv->reg_lock, reg_flags);
344 if (!iwl_grab_nic_access(priv)) {
345 _iwl_write_direct32(priv, reg, value);
346 iwl_release_nic_access(priv);
347 }
348 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
349}
350
351static inline void iwl_write_reg_buf(struct iwl_priv *priv,
352 u32 reg, u32 len, u32 *values)
353{
354 u32 count = sizeof(u32);
355
356 if ((priv != NULL) && (values != NULL)) {
357 for (; 0 < len; len -= count, reg += count, values++)
358 iwl_write_direct32(priv, reg, *values);
359 }
360}
361
362static inline int _iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr,
363 u32 mask, int timeout)
364{
365 int t = 0;
366
367 do {
368 if ((iwl_read_direct32(priv, addr) & mask) == mask)
369 return t;
370 udelay(IWL_POLL_INTERVAL);
371 t += IWL_POLL_INTERVAL;
372 } while (t < timeout);
373
374 return -ETIMEDOUT;
375}
376
377#ifdef CONFIG_IWLWIFI_DEBUG
378static inline int __iwl_poll_direct_bit(const char *f, u32 l,
379 struct iwl_priv *priv,
380 u32 addr, u32 mask, int timeout)
381{
382 int ret = _iwl_poll_direct_bit(priv, addr, mask, timeout);
383
384 if (unlikely(ret == -ETIMEDOUT))
385 IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) - "
386 "timedout - %s %d\n", addr, mask, f, l);
387 else
388 IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
389 "- %s %d\n", addr, mask, ret, f, l);
390 return ret;
391}
392#define iwl_poll_direct_bit(priv, addr, mask, timeout) \
393 __iwl_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout)
394#else
395#define iwl_poll_direct_bit _iwl_poll_direct_bit
396#endif
397
398static inline u32 _iwl_read_prph(struct iwl_priv *priv, u32 reg)
399{
400 _iwl_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
401 rmb();
402 return _iwl_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
403}
404static inline u32 iwl_read_prph(struct iwl_priv *priv, u32 reg)
405{
406 unsigned long reg_flags;
407 u32 val;
408
409 spin_lock_irqsave(&priv->reg_lock, reg_flags);
410 iwl_grab_nic_access(priv);
411 val = _iwl_read_prph(priv, reg);
412 iwl_release_nic_access(priv);
413 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
414 return val;
415}
416
417static inline void _iwl_write_prph(struct iwl_priv *priv,
418 u32 addr, u32 val)
419{
420 _iwl_write_direct32(priv, HBUS_TARG_PRPH_WADDR,
421 ((addr & 0x0000FFFF) | (3 << 24)));
422 wmb();
423 _iwl_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
424}
425
426static inline void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val)
427{
428 unsigned long reg_flags;
429 59
430 spin_lock_irqsave(&priv->reg_lock, reg_flags); 60int iwl_poll_bit(struct iwl_priv *priv, u32 addr,
431 if (!iwl_grab_nic_access(priv)) { 61 u32 bits, u32 mask, int timeout);
432 _iwl_write_prph(priv, addr, val); 62int iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr, u32 mask,
433 iwl_release_nic_access(priv); 63 int timeout);
434 }
435 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
436}
437 64
438#define _iwl_set_bits_prph(priv, reg, mask) \ 65int iwl_grab_nic_access(struct iwl_priv *priv);
439 _iwl_write_prph(priv, reg, (_iwl_read_prph(priv, reg) | mask)) 66void iwl_release_nic_access(struct iwl_priv *priv);
440 67
441static inline void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask) 68u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg);
442{ 69void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value);
443 unsigned long reg_flags;
444 70
445 spin_lock_irqsave(&priv->reg_lock, reg_flags);
446 iwl_grab_nic_access(priv);
447 _iwl_set_bits_prph(priv, reg, mask);
448 iwl_release_nic_access(priv);
449 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
450}
451 71
452#define _iwl_set_bits_mask_prph(priv, reg, bits, mask) \ 72u32 iwl_read_prph(struct iwl_priv *priv, u32 reg);
453 _iwl_write_prph(priv, reg, ((_iwl_read_prph(priv, reg) & mask) | bits)) 73void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val);
74void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask);
75void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg,
76 u32 bits, u32 mask);
77void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask);
454 78
455static inline void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg, 79u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr);
456 u32 bits, u32 mask) 80void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val);
457{
458 unsigned long reg_flags;
459
460 spin_lock_irqsave(&priv->reg_lock, reg_flags);
461 iwl_grab_nic_access(priv);
462 _iwl_set_bits_mask_prph(priv, reg, bits, mask);
463 iwl_release_nic_access(priv);
464 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
465}
466
467static inline void iwl_clear_bits_prph(struct iwl_priv
468 *priv, u32 reg, u32 mask)
469{
470 unsigned long reg_flags;
471 u32 val;
472
473 spin_lock_irqsave(&priv->reg_lock, reg_flags);
474 iwl_grab_nic_access(priv);
475 val = _iwl_read_prph(priv, reg);
476 _iwl_write_prph(priv, reg, (val & ~mask));
477 iwl_release_nic_access(priv);
478 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
479}
480
481static inline u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr)
482{
483 unsigned long reg_flags;
484 u32 value;
485
486 spin_lock_irqsave(&priv->reg_lock, reg_flags);
487 iwl_grab_nic_access(priv);
488
489 _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
490 rmb();
491 value = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
492
493 iwl_release_nic_access(priv);
494 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
495 return value;
496}
497
498static inline void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val)
499{
500 unsigned long reg_flags;
501
502 spin_lock_irqsave(&priv->reg_lock, reg_flags);
503 if (!iwl_grab_nic_access(priv)) {
504 _iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
505 wmb();
506 _iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
507 iwl_release_nic_access(priv);
508 }
509 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
510}
511
512static inline void iwl_write_targ_mem_buf(struct iwl_priv *priv, u32 addr,
513 u32 len, u32 *values)
514{
515 unsigned long reg_flags;
516
517 spin_lock_irqsave(&priv->reg_lock, reg_flags);
518 if (!iwl_grab_nic_access(priv)) {
519 _iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
520 wmb();
521 for (; 0 < len; len -= sizeof(u32), values++)
522 _iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
523
524 iwl_release_nic_access(priv);
525 }
526 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
527}
528#endif 81#endif