diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r-- | drivers/net/wireless/iwlwifi/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 18 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-debug.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-eeprom.c | 36 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-io.c | 274 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-io.h | 489 |
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 @@ | |||
2 | obj-$(CONFIG_IWLAGN) += iwlagn.o | 2 | obj-$(CONFIG_IWLAGN) += iwlagn.o |
3 | iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o | 3 | iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o |
4 | iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o | 4 | iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o |
5 | iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o | 5 | iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o |
6 | iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o | 6 | iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o |
7 | 7 | ||
8 | iwlagn-objs += iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o | 8 | iwlagn-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 | ||
3695 | static int iwl_set_hw_params(struct iwl_priv *priv) | 3695 | static 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 | |||
33 | static 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 | |||
38 | static 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 | |||
43 | void 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 | |||
52 | void 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 | |||
61 | int 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 | |||
76 | int 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 | |||
120 | void 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 | |||
127 | u32 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 | |||
141 | void 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 | |||
153 | int 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 | |||
168 | static 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 | |||
175 | static 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 | |||
183 | u32 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 | |||
196 | void 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 | |||
208 | void 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 | |||
219 | void 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 | |||
232 | void 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 | |||
245 | u32 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 | |||
262 | void 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 | /* | 38 | static 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 | |||
66 | static 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 | 44 | static inline void iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val) |
73 | static 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 | |||
86 | static 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 | 50 | static inline u32 iwl_read32(struct iwl_priv *priv, u32 ofs) |
93 | static 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 | |||
105 | static 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 | 57 | void iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask); |
113 | static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *priv, u32 ofs) | 58 | void 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 */ | ||
124 | static 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 | ||
139 | static 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 | |||
155 | static 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 | ||
160 | static 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 | } | ||
167 | static 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 | ||
176 | static 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 | |||
186 | static 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 | ||
191 | static 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 | } | ||
198 | static 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 | ||
207 | static 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 | |||
217 | static 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 | ||
259 | static 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 | |||
272 | static 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 | ||
278 | static 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 | |||
292 | static inline u32 _iwl_read_direct32(struct iwl_priv *priv, u32 reg) | ||
293 | { | ||
294 | return _iwl_read32(priv, reg); | ||
295 | } | ||
296 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
297 | static 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 | } | ||
305 | static 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 | ||
319 | static 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 | |||
334 | static inline void _iwl_write_direct32(struct iwl_priv *priv, | ||
335 | u32 reg, u32 value) | ||
336 | { | ||
337 | _iwl_write32(priv, reg, value); | ||
338 | } | ||
339 | static 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 | |||
351 | static 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 | |||
362 | static 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 | ||
378 | static 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 | |||
398 | static 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 | } | ||
404 | static 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 | |||
417 | static 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 | |||
426 | static 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); | 60 | int 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); | 62 | int 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) \ | 65 | int iwl_grab_nic_access(struct iwl_priv *priv); |
439 | _iwl_write_prph(priv, reg, (_iwl_read_prph(priv, reg) | mask)) | 66 | void iwl_release_nic_access(struct iwl_priv *priv); |
440 | 67 | ||
441 | static inline void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask) | 68 | u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg); |
442 | { | 69 | void 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) \ | 72 | u32 iwl_read_prph(struct iwl_priv *priv, u32 reg); |
453 | _iwl_write_prph(priv, reg, ((_iwl_read_prph(priv, reg) & mask) | bits)) | 73 | void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val); |
74 | void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask); | ||
75 | void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg, | ||
76 | u32 bits, u32 mask); | ||
77 | void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask); | ||
454 | 78 | ||
455 | static inline void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg, | 79 | u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr); |
456 | u32 bits, u32 mask) | 80 | void 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 | |||
467 | static 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 | |||
481 | static 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 | |||
498 | static 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 | |||
512 | static 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 |