Commit | Line | Data |
---|---|---|
02a7fa00 | 1 | /****************************************************************************** |
cefec29e JB |
2 | * |
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | |
4 | * redistributing this file, you may do so under either license. | |
5 | * | |
6 | * GPL LICENSE SUMMARY | |
02a7fa00 | 7 | * |
51368bf7 | 8 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
f65ebd88 | 9 | * Copyright(c) 2015 - 2016 Intel Deutschland GmbH |
02a7fa00 | 10 | * |
02a7fa00 JB |
11 | * This program is free software; you can redistribute it and/or modify it |
12 | * under the terms of version 2 of the GNU General Public License as | |
13 | * published by the Free Software Foundation. | |
14 | * | |
15 | * This program is distributed in the hope that it will be useful, but WITHOUT | |
16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
18 | * more details. | |
19 | * | |
02a7fa00 | 20 | * The full GNU General Public License is included in this distribution in the |
cefec29e | 21 | * file called COPYING. |
02a7fa00 JB |
22 | * |
23 | * Contact Information: | |
cb2f8277 | 24 | * Intel Linux Wireless <linuxwifi@intel.com> |
02a7fa00 JB |
25 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 |
26 | * | |
cefec29e JB |
27 | * BSD LICENSE |
28 | * | |
29 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. | |
30 | * Copyright(c) 2015 - 2016 Intel Deutschland GmbH | |
31 | * All rights reserved. | |
32 | * | |
33 | * Redistribution and use in source and binary forms, with or without | |
34 | * modification, are permitted provided that the following conditions | |
35 | * are met: | |
36 | * | |
37 | * * Redistributions of source code must retain the above copyright | |
38 | * notice, this list of conditions and the following disclaimer. | |
39 | * * Redistributions in binary form must reproduce the above copyright | |
40 | * notice, this list of conditions and the following disclaimer in | |
41 | * the documentation and/or other materials provided with the | |
42 | * distribution. | |
43 | * * Neither the name Intel Corporation nor the names of its | |
44 | * contributors may be used to endorse or promote products derived | |
45 | * from this software without specific prior written permission. | |
46 | * | |
47 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
48 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
49 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
50 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
51 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
52 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
53 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
54 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
55 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
56 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
57 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
58 | * | |
02a7fa00 | 59 | *****************************************************************************/ |
83ed9015 EG |
60 | #include <linux/delay.h> |
61 | #include <linux/device.h> | |
cc5f7e39 | 62 | #include <linux/export.h> |
02a7fa00 | 63 | |
48e29340 | 64 | #include "iwl-drv.h" |
02a7fa00 | 65 | #include "iwl-io.h" |
6ac7d115 | 66 | #include "iwl-csr.h" |
83ed9015 | 67 | #include "iwl-debug.h" |
4c9706dc | 68 | #include "iwl-prph.h" |
313b0a29 | 69 | #include "iwl-fh.h" |
02a7fa00 | 70 | |
a73a2cea EG |
71 | void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val) |
72 | { | |
73 | trace_iwlwifi_dev_iowrite8(trans->dev, ofs, val); | |
74 | iwl_trans_write8(trans, ofs, val); | |
75 | } | |
76 | IWL_EXPORT_SYMBOL(iwl_write8); | |
77 | ||
78 | void iwl_write32(struct iwl_trans *trans, u32 ofs, u32 val) | |
79 | { | |
80 | trace_iwlwifi_dev_iowrite32(trans->dev, ofs, val); | |
81 | iwl_trans_write32(trans, ofs, val); | |
82 | } | |
83 | IWL_EXPORT_SYMBOL(iwl_write32); | |
84 | ||
12a17458 SS |
85 | void iwl_write64(struct iwl_trans *trans, u64 ofs, u64 val) |
86 | { | |
87 | trace_iwlwifi_dev_iowrite64(trans->dev, ofs, val); | |
bd31dd9d JB |
88 | iwl_trans_write32(trans, ofs, lower_32_bits(val)); |
89 | iwl_trans_write32(trans, ofs + 4, upper_32_bits(val)); | |
12a17458 SS |
90 | } |
91 | IWL_EXPORT_SYMBOL(iwl_write64); | |
92 | ||
a73a2cea EG |
93 | u32 iwl_read32(struct iwl_trans *trans, u32 ofs) |
94 | { | |
95 | u32 val = iwl_trans_read32(trans, ofs); | |
89ced540 | 96 | |
a73a2cea EG |
97 | trace_iwlwifi_dev_ioread32(trans->dev, ofs, val); |
98 | return val; | |
99 | } | |
100 | IWL_EXPORT_SYMBOL(iwl_read32); | |
101 | ||
02a7fa00 JB |
102 | #define IWL_POLL_INTERVAL 10 /* microseconds */ |
103 | ||
1042db2a | 104 | int iwl_poll_bit(struct iwl_trans *trans, u32 addr, |
02a7fa00 JB |
105 | u32 bits, u32 mask, int timeout) |
106 | { | |
107 | int t = 0; | |
108 | ||
109 | do { | |
1042db2a | 110 | if ((iwl_read32(trans, addr) & mask) == (bits & mask)) |
02a7fa00 JB |
111 | return t; |
112 | udelay(IWL_POLL_INTERVAL); | |
113 | t += IWL_POLL_INTERVAL; | |
114 | } while (t < timeout); | |
115 | ||
116 | return -ETIMEDOUT; | |
117 | } | |
48e29340 | 118 | IWL_EXPORT_SYMBOL(iwl_poll_bit); |
02a7fa00 | 119 | |
1042db2a | 120 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) |
02a7fa00 | 121 | { |
abae2386 | 122 | u32 value = 0x5a5a5a5a; |
02a7fa00 | 123 | unsigned long flags; |
23ba9340 | 124 | if (iwl_trans_grab_nic_access(trans, &flags)) { |
abae2386 | 125 | value = iwl_read32(trans, reg); |
e56b04ef | 126 | iwl_trans_release_nic_access(trans, &flags); |
abae2386 | 127 | } |
02a7fa00 JB |
128 | |
129 | return value; | |
130 | } | |
48e29340 | 131 | IWL_EXPORT_SYMBOL(iwl_read_direct32); |
02a7fa00 | 132 | |
1042db2a | 133 | void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) |
02a7fa00 JB |
134 | { |
135 | unsigned long flags; | |
136 | ||
23ba9340 | 137 | if (iwl_trans_grab_nic_access(trans, &flags)) { |
1042db2a | 138 | iwl_write32(trans, reg, value); |
e56b04ef | 139 | iwl_trans_release_nic_access(trans, &flags); |
02a7fa00 | 140 | } |
02a7fa00 | 141 | } |
48e29340 | 142 | IWL_EXPORT_SYMBOL(iwl_write_direct32); |
02a7fa00 | 143 | |
12a17458 SS |
144 | void iwl_write_direct64(struct iwl_trans *trans, u64 reg, u64 value) |
145 | { | |
146 | unsigned long flags; | |
147 | ||
148 | if (iwl_trans_grab_nic_access(trans, &flags)) { | |
149 | iwl_write64(trans, reg, value); | |
150 | iwl_trans_release_nic_access(trans, &flags); | |
151 | } | |
152 | } | |
153 | IWL_EXPORT_SYMBOL(iwl_write_direct64); | |
154 | ||
1042db2a | 155 | int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, |
02a7fa00 JB |
156 | int timeout) |
157 | { | |
158 | int t = 0; | |
159 | ||
160 | do { | |
1042db2a | 161 | if ((iwl_read_direct32(trans, addr) & mask) == mask) |
02a7fa00 JB |
162 | return t; |
163 | udelay(IWL_POLL_INTERVAL); | |
164 | t += IWL_POLL_INTERVAL; | |
165 | } while (t < timeout); | |
166 | ||
167 | return -ETIMEDOUT; | |
168 | } | |
48e29340 | 169 | IWL_EXPORT_SYMBOL(iwl_poll_direct_bit); |
02a7fa00 | 170 | |
14ef1b43 | 171 | u32 iwl_read_prph_no_grab(struct iwl_trans *trans, u32 ofs) |
02a7fa00 | 172 | { |
6a06b6c1 EG |
173 | u32 val = iwl_trans_read_prph(trans, ofs); |
174 | trace_iwlwifi_dev_ioread_prph32(trans->dev, ofs, val); | |
175 | return val; | |
02a7fa00 | 176 | } |
14ef1b43 | 177 | IWL_EXPORT_SYMBOL(iwl_read_prph_no_grab); |
02a7fa00 | 178 | |
14ef1b43 | 179 | void iwl_write_prph_no_grab(struct iwl_trans *trans, u32 ofs, u32 val) |
02a7fa00 | 180 | { |
6a06b6c1 EG |
181 | trace_iwlwifi_dev_iowrite_prph32(trans->dev, ofs, val); |
182 | iwl_trans_write_prph(trans, ofs, val); | |
02a7fa00 | 183 | } |
14ef1b43 | 184 | IWL_EXPORT_SYMBOL(iwl_write_prph_no_grab); |
02a7fa00 | 185 | |
12a17458 SS |
186 | void iwl_write_prph64_no_grab(struct iwl_trans *trans, u64 ofs, u64 val) |
187 | { | |
188 | trace_iwlwifi_dev_iowrite_prph64(trans->dev, ofs, val); | |
189 | iwl_write_prph_no_grab(trans, ofs, val & 0xffffffff); | |
190 | iwl_write_prph_no_grab(trans, ofs + 4, val >> 32); | |
191 | } | |
192 | IWL_EXPORT_SYMBOL(iwl_write_prph64_no_grab); | |
193 | ||
6a06b6c1 | 194 | u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs) |
02a7fa00 JB |
195 | { |
196 | unsigned long flags; | |
abae2386 | 197 | u32 val = 0x5a5a5a5a; |
02a7fa00 | 198 | |
23ba9340 | 199 | if (iwl_trans_grab_nic_access(trans, &flags)) { |
14ef1b43 | 200 | val = iwl_read_prph_no_grab(trans, ofs); |
e56b04ef | 201 | iwl_trans_release_nic_access(trans, &flags); |
abae2386 | 202 | } |
02a7fa00 JB |
203 | return val; |
204 | } | |
48e29340 | 205 | IWL_EXPORT_SYMBOL(iwl_read_prph); |
02a7fa00 | 206 | |
6a06b6c1 | 207 | void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) |
02a7fa00 JB |
208 | { |
209 | unsigned long flags; | |
210 | ||
23ba9340 | 211 | if (iwl_trans_grab_nic_access(trans, &flags)) { |
14ef1b43 | 212 | iwl_write_prph_no_grab(trans, ofs, val); |
e56b04ef | 213 | iwl_trans_release_nic_access(trans, &flags); |
02a7fa00 | 214 | } |
02a7fa00 | 215 | } |
48e29340 | 216 | IWL_EXPORT_SYMBOL(iwl_write_prph); |
02a7fa00 | 217 | |
189fa2fa EH |
218 | int iwl_poll_prph_bit(struct iwl_trans *trans, u32 addr, |
219 | u32 bits, u32 mask, int timeout) | |
220 | { | |
221 | int t = 0; | |
222 | ||
223 | do { | |
224 | if ((iwl_read_prph(trans, addr) & mask) == (bits & mask)) | |
225 | return t; | |
226 | udelay(IWL_POLL_INTERVAL); | |
227 | t += IWL_POLL_INTERVAL; | |
228 | } while (t < timeout); | |
229 | ||
230 | return -ETIMEDOUT; | |
231 | } | |
232 | ||
6a06b6c1 | 233 | void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) |
02a7fa00 JB |
234 | { |
235 | unsigned long flags; | |
236 | ||
23ba9340 | 237 | if (iwl_trans_grab_nic_access(trans, &flags)) { |
14ef1b43 GBA |
238 | iwl_write_prph_no_grab(trans, ofs, |
239 | iwl_read_prph_no_grab(trans, ofs) | | |
240 | mask); | |
e56b04ef | 241 | iwl_trans_release_nic_access(trans, &flags); |
bfe4b80e | 242 | } |
02a7fa00 | 243 | } |
48e29340 | 244 | IWL_EXPORT_SYMBOL(iwl_set_bits_prph); |
02a7fa00 | 245 | |
6a06b6c1 | 246 | void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, |
02a7fa00 JB |
247 | u32 bits, u32 mask) |
248 | { | |
249 | unsigned long flags; | |
250 | ||
23ba9340 | 251 | if (iwl_trans_grab_nic_access(trans, &flags)) { |
14ef1b43 GBA |
252 | iwl_write_prph_no_grab(trans, ofs, |
253 | (iwl_read_prph_no_grab(trans, ofs) & | |
254 | mask) | bits); | |
e56b04ef | 255 | iwl_trans_release_nic_access(trans, &flags); |
bfe4b80e | 256 | } |
02a7fa00 | 257 | } |
48e29340 | 258 | IWL_EXPORT_SYMBOL(iwl_set_bits_mask_prph); |
02a7fa00 | 259 | |
6a06b6c1 | 260 | void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) |
02a7fa00 JB |
261 | { |
262 | unsigned long flags; | |
263 | u32 val; | |
264 | ||
23ba9340 | 265 | if (iwl_trans_grab_nic_access(trans, &flags)) { |
14ef1b43 GBA |
266 | val = iwl_read_prph_no_grab(trans, ofs); |
267 | iwl_write_prph_no_grab(trans, ofs, (val & ~mask)); | |
e56b04ef | 268 | iwl_trans_release_nic_access(trans, &flags); |
bfe4b80e | 269 | } |
02a7fa00 | 270 | } |
48e29340 | 271 | IWL_EXPORT_SYMBOL(iwl_clear_bits_prph); |
313b0a29 | 272 | |
4c9706dc LK |
273 | void iwl_force_nmi(struct iwl_trans *trans) |
274 | { | |
f4ca70ef | 275 | if (trans->cfg->device_family < IWL_DEVICE_FAMILY_9000) |
66396583 EG |
276 | iwl_write_prph(trans, DEVICE_SET_NMI_REG, |
277 | DEVICE_SET_NMI_VAL_DRV); | |
f4ca70ef | 278 | else |
b9410b18 | 279 | iwl_write_prph(trans, UREG_NIC_SET_NMI_DRIVER, |
f4ca70ef | 280 | UREG_NIC_SET_NMI_DRIVER_NMI_FROM_DRIVER_MSK); |
4c9706dc LK |
281 | } |
282 | IWL_EXPORT_SYMBOL(iwl_force_nmi); | |
283 | ||
f65ebd88 | 284 | static const char *get_rfh_string(int cmd) |
313b0a29 IH |
285 | { |
286 | #define IWL_CMD(x) case x: return #x | |
f65ebd88 SS |
287 | #define IWL_CMD_MQ(arg, reg, q) { if (arg == reg(q)) return #reg; } |
288 | ||
289 | int i; | |
290 | ||
291 | for (i = 0; i < IWL_MAX_RX_HW_QUEUES; i++) { | |
292 | IWL_CMD_MQ(cmd, RFH_Q_FRBDCB_BA_LSB, i); | |
293 | IWL_CMD_MQ(cmd, RFH_Q_FRBDCB_WIDX, i); | |
294 | IWL_CMD_MQ(cmd, RFH_Q_FRBDCB_RIDX, i); | |
295 | IWL_CMD_MQ(cmd, RFH_Q_URBD_STTS_WPTR_LSB, i); | |
c0ed8aa4 | 296 | } |
f65ebd88 SS |
297 | |
298 | switch (cmd) { | |
299 | IWL_CMD(RFH_RXF_DMA_CFG); | |
300 | IWL_CMD(RFH_GEN_CFG); | |
301 | IWL_CMD(RFH_GEN_STATUS); | |
302 | IWL_CMD(FH_TSSR_TX_STATUS_REG); | |
303 | IWL_CMD(FH_TSSR_TX_ERROR_REG); | |
304 | default: | |
305 | return "UNKNOWN"; | |
306 | } | |
307 | #undef IWL_CMD_MQ | |
308 | } | |
309 | ||
310 | struct reg { | |
311 | u32 addr; | |
312 | bool is64; | |
313 | }; | |
314 | ||
315 | static int iwl_dump_rfh(struct iwl_trans *trans, char **buf) | |
316 | { | |
317 | int i, q; | |
318 | int num_q = trans->num_rx_queues; | |
319 | static const u32 rfh_tbl[] = { | |
320 | RFH_RXF_DMA_CFG, | |
321 | RFH_GEN_CFG, | |
322 | RFH_GEN_STATUS, | |
323 | FH_TSSR_TX_STATUS_REG, | |
324 | FH_TSSR_TX_ERROR_REG, | |
325 | }; | |
326 | static const struct reg rfh_mq_tbl[] = { | |
327 | { RFH_Q0_FRBDCB_BA_LSB, true }, | |
328 | { RFH_Q0_FRBDCB_WIDX, false }, | |
329 | { RFH_Q0_FRBDCB_RIDX, false }, | |
330 | { RFH_Q0_URBD_STTS_WPTR_LSB, true }, | |
331 | }; | |
332 | ||
333 | #ifdef CONFIG_IWLWIFI_DEBUGFS | |
334 | if (buf) { | |
335 | int pos = 0; | |
336 | /* | |
337 | * Register (up to 34 for name + 8 blank/q for MQ): 40 chars | |
338 | * Colon + space: 2 characters | |
339 | * 0X%08x: 10 characters | |
340 | * New line: 1 character | |
341 | * Total of 53 characters | |
342 | */ | |
343 | size_t bufsz = ARRAY_SIZE(rfh_tbl) * 53 + | |
344 | ARRAY_SIZE(rfh_mq_tbl) * 53 * num_q + 40; | |
345 | ||
346 | *buf = kmalloc(bufsz, GFP_KERNEL); | |
347 | if (!*buf) | |
348 | return -ENOMEM; | |
349 | ||
350 | pos += scnprintf(*buf + pos, bufsz - pos, | |
351 | "RFH register values:\n"); | |
352 | ||
353 | for (i = 0; i < ARRAY_SIZE(rfh_tbl); i++) | |
354 | pos += scnprintf(*buf + pos, bufsz - pos, | |
355 | "%40s: 0X%08x\n", | |
356 | get_rfh_string(rfh_tbl[i]), | |
357 | iwl_read_prph(trans, rfh_tbl[i])); | |
358 | ||
359 | for (i = 0; i < ARRAY_SIZE(rfh_mq_tbl); i++) | |
360 | for (q = 0; q < num_q; q++) { | |
361 | u32 addr = rfh_mq_tbl[i].addr; | |
362 | ||
363 | addr += q * (rfh_mq_tbl[i].is64 ? 8 : 4); | |
364 | pos += scnprintf(*buf + pos, bufsz - pos, | |
365 | "%34s(q %2d): 0X%08x\n", | |
366 | get_rfh_string(addr), q, | |
367 | iwl_read_prph(trans, addr)); | |
368 | } | |
369 | ||
370 | return pos; | |
371 | } | |
372 | #endif | |
373 | ||
374 | IWL_ERR(trans, "RFH register values:\n"); | |
375 | for (i = 0; i < ARRAY_SIZE(rfh_tbl); i++) | |
376 | IWL_ERR(trans, " %34s: 0X%08x\n", | |
377 | get_rfh_string(rfh_tbl[i]), | |
378 | iwl_read_prph(trans, rfh_tbl[i])); | |
379 | ||
380 | for (i = 0; i < ARRAY_SIZE(rfh_mq_tbl); i++) | |
381 | for (q = 0; q < num_q; q++) { | |
382 | u32 addr = rfh_mq_tbl[i].addr; | |
383 | ||
384 | addr += q * (rfh_mq_tbl[i].is64 ? 8 : 4); | |
385 | IWL_ERR(trans, " %34s(q %d): 0X%08x\n", | |
386 | get_rfh_string(addr), q, | |
387 | iwl_read_prph(trans, addr)); | |
388 | } | |
389 | ||
390 | return 0; | |
391 | } | |
392 | ||
393 | static const char *get_fh_string(int cmd) | |
394 | { | |
313b0a29 IH |
395 | switch (cmd) { |
396 | IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG); | |
397 | IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG); | |
398 | IWL_CMD(FH_RSCSR_CHNL0_WPTR); | |
399 | IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG); | |
400 | IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG); | |
401 | IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG); | |
402 | IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV); | |
403 | IWL_CMD(FH_TSSR_TX_STATUS_REG); | |
404 | IWL_CMD(FH_TSSR_TX_ERROR_REG); | |
405 | default: | |
406 | return "UNKNOWN"; | |
407 | } | |
408 | #undef IWL_CMD | |
409 | } | |
410 | ||
411 | int iwl_dump_fh(struct iwl_trans *trans, char **buf) | |
412 | { | |
413 | int i; | |
414 | static const u32 fh_tbl[] = { | |
415 | FH_RSCSR_CHNL0_STTS_WPTR_REG, | |
416 | FH_RSCSR_CHNL0_RBDCB_BASE_REG, | |
417 | FH_RSCSR_CHNL0_WPTR, | |
418 | FH_MEM_RCSR_CHNL0_CONFIG_REG, | |
419 | FH_MEM_RSSR_SHARED_CTRL_REG, | |
420 | FH_MEM_RSSR_RX_STATUS_REG, | |
421 | FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV, | |
422 | FH_TSSR_TX_STATUS_REG, | |
423 | FH_TSSR_TX_ERROR_REG | |
424 | }; | |
425 | ||
f65ebd88 SS |
426 | if (trans->cfg->mq_rx_supported) |
427 | return iwl_dump_rfh(trans, buf); | |
428 | ||
313b0a29 IH |
429 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
430 | if (buf) { | |
431 | int pos = 0; | |
432 | size_t bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; | |
433 | ||
434 | *buf = kmalloc(bufsz, GFP_KERNEL); | |
435 | if (!*buf) | |
436 | return -ENOMEM; | |
437 | ||
438 | pos += scnprintf(*buf + pos, bufsz - pos, | |
439 | "FH register values:\n"); | |
440 | ||
441 | for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) | |
442 | pos += scnprintf(*buf + pos, bufsz - pos, | |
443 | " %34s: 0X%08x\n", | |
444 | get_fh_string(fh_tbl[i]), | |
445 | iwl_read_direct32(trans, fh_tbl[i])); | |
446 | ||
447 | return pos; | |
448 | } | |
449 | #endif | |
450 | ||
451 | IWL_ERR(trans, "FH register values:\n"); | |
452 | for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) | |
453 | IWL_ERR(trans, " %34s: 0X%08x\n", | |
454 | get_fh_string(fh_tbl[i]), | |
455 | iwl_read_direct32(trans, fh_tbl[i])); | |
456 | ||
457 | return 0; | |
458 | } |