aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlegacy/common.c
diff options
context:
space:
mode:
authorStanislaw Gruszka <sgruszka@redhat.com>2011-12-23 02:13:43 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-01-04 14:30:44 -0500
commit17d4eca6432bb1d4753d7894b824271673a1640a (patch)
treec8ad71a2202b7ff618fe8dd5c38fec07c31980f1 /drivers/net/wireless/iwlegacy/common.c
parentd71be937202853eda76562e9678073465d5c0fa8 (diff)
iwlegacy: move some i/o helpers out of inline
This save us about 20k of text size, and should have no impact on performance as hot paths do not use much I/O. Before: text data bss dec hex filename 108512 1784 168 110464 1af80 drivers/net/wireless/iwlegacy/iwl3945.ko 165730 2164 156 168050 29072 drivers/net/wireless/iwlegacy/iwl4965.ko 91942 328 48 92318 1689e drivers/net/wireless/iwlegacy/iwlegacy.ko After: text data bss dec hex filename 95556 1784 168 97508 17ce4 drivers/net/wireless/iwlegacy/iwl3945.ko 154853 2164 156 157173 265f5 drivers/net/wireless/iwlegacy/iwl4965.ko 91634 328 48 92010 1676a drivers/net/wireless/iwlegacy/iwlegacy.ko Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlegacy/common.c')
-rw-r--r--drivers/net/wireless/iwlegacy/common.c161
1 files changed, 161 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index 881ba043770..36454d0bbee 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -42,6 +42,167 @@
42 42
43#include "common.h" 43#include "common.h"
44 44
45int
46_il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout)
47{
48 const int interval = 10; /* microseconds */
49 int t = 0;
50
51 do {
52 if ((_il_rd(il, addr) & mask) == (bits & mask))
53 return t;
54 udelay(interval);
55 t += interval;
56 } while (t < timeout);
57
58 return -ETIMEDOUT;
59}
60EXPORT_SYMBOL(_il_poll_bit);
61
62void
63il_set_bit(struct il_priv *p, u32 r, u32 m)
64{
65 unsigned long reg_flags;
66
67 spin_lock_irqsave(&p->reg_lock, reg_flags);
68 _il_set_bit(p, r, m);
69 spin_unlock_irqrestore(&p->reg_lock, reg_flags);
70}
71EXPORT_SYMBOL(il_set_bit);
72
73void
74il_clear_bit(struct il_priv *p, u32 r, u32 m)
75{
76 unsigned long reg_flags;
77
78 spin_lock_irqsave(&p->reg_lock, reg_flags);
79 _il_clear_bit(p, r, m);
80 spin_unlock_irqrestore(&p->reg_lock, reg_flags);
81}
82EXPORT_SYMBOL(il_clear_bit);
83
84int
85_il_grab_nic_access(struct il_priv *il)
86{
87 int ret;
88 u32 val;
89
90 /* this bit wakes up the NIC */
91 _il_set_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
92
93 /*
94 * These bits say the device is running, and should keep running for
95 * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
96 * but they do not indicate that embedded SRAM is restored yet;
97 * 3945 and 4965 have volatile SRAM, and must save/restore contents
98 * to/from host DRAM when sleeping/waking for power-saving.
99 * Each direction takes approximately 1/4 millisecond; with this
100 * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
101 * series of register accesses are expected (e.g. reading Event Log),
102 * to keep device from sleeping.
103 *
104 * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
105 * SRAM is okay/restored. We don't check that here because this call
106 * is just for hardware register access; but GP1 MAC_SLEEP check is a
107 * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
108 *
109 */
110 ret =
111 _il_poll_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
112 (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
113 CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
114 if (ret < 0) {
115 val = _il_rd(il, CSR_GP_CNTRL);
116 IL_ERR("MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
117 _il_wr(il, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
118 return -EIO;
119 }
120
121 return 0;
122}
123EXPORT_SYMBOL_GPL(_il_grab_nic_access);
124
125int
126il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout)
127{
128 const int interval = 10; /* microseconds */
129 int t = 0;
130
131 do {
132 if ((il_rd(il, addr) & mask) == mask)
133 return t;
134 udelay(interval);
135 t += interval;
136 } while (t < timeout);
137
138 return -ETIMEDOUT;
139}
140EXPORT_SYMBOL(il_poll_bit);
141
142u32
143il_rd_prph(struct il_priv *il, u32 reg)
144{
145 unsigned long reg_flags;
146 u32 val;
147
148 spin_lock_irqsave(&il->reg_lock, reg_flags);
149 _il_grab_nic_access(il);
150 val = _il_rd_prph(il, reg);
151 _il_release_nic_access(il);
152 spin_unlock_irqrestore(&il->reg_lock, reg_flags);
153 return val;
154}
155EXPORT_SYMBOL(il_rd_prph);
156
157void
158il_wr_prph(struct il_priv *il, u32 addr, u32 val)
159{
160 unsigned long reg_flags;
161
162 spin_lock_irqsave(&il->reg_lock, reg_flags);
163 if (!_il_grab_nic_access(il)) {
164 _il_wr_prph(il, addr, val);
165 _il_release_nic_access(il);
166 }
167 spin_unlock_irqrestore(&il->reg_lock, reg_flags);
168}
169EXPORT_SYMBOL(il_wr_prph);
170
171u32
172il_read_targ_mem(struct il_priv *il, u32 addr)
173{
174 unsigned long reg_flags;
175 u32 value;
176
177 spin_lock_irqsave(&il->reg_lock, reg_flags);
178 _il_grab_nic_access(il);
179
180 _il_wr(il, HBUS_TARG_MEM_RADDR, addr);
181 rmb();
182 value = _il_rd(il, HBUS_TARG_MEM_RDAT);
183
184 _il_release_nic_access(il);
185 spin_unlock_irqrestore(&il->reg_lock, reg_flags);
186 return value;
187}
188EXPORT_SYMBOL(il_read_targ_mem);
189
190void
191il_write_targ_mem(struct il_priv *il, u32 addr, u32 val)
192{
193 unsigned long reg_flags;
194
195 spin_lock_irqsave(&il->reg_lock, reg_flags);
196 if (!_il_grab_nic_access(il)) {
197 _il_wr(il, HBUS_TARG_MEM_WADDR, addr);
198 wmb();
199 _il_wr(il, HBUS_TARG_MEM_WDAT, val);
200 _il_release_nic_access(il);
201 }
202 spin_unlock_irqrestore(&il->reg_lock, reg_flags);
203}
204EXPORT_SYMBOL(il_write_targ_mem);
205
45const char * 206const char *
46il_get_cmd_string(u8 cmd) 207il_get_cmd_string(u8 cmd)
47{ 208{