aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h15
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.c3
-rw-r--r--drivers/net/wireless/ath/ath6kl/init.c13
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c75
-rw-r--r--drivers/net/wireless/ath/ath6kl/target.h14
5 files changed, 107 insertions, 13 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index c5213d509093..65d0d84b4767 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -26,6 +26,7 @@
26#include "htc.h" 26#include "htc.h"
27#include "wmi.h" 27#include "wmi.h"
28#include "bmi.h" 28#include "bmi.h"
29#include "target.h"
29 30
30#define MAX_ATH6KL 1 31#define MAX_ATH6KL 1
31#define ATH6KL_MAX_RX_BUFFERS 16 32#define ATH6KL_MAX_RX_BUFFERS 16
@@ -494,6 +495,19 @@ static inline void ath6kl_deposit_credit_to_ep(struct htc_credit_state_info
494 cred_info->cur_free_credits -= credits; 495 cred_info->cur_free_credits -= credits;
495} 496}
496 497
498static inline u32 ath6kl_get_hi_item_addr(struct ath6kl *ar,
499 u32 item_offset)
500{
501 u32 addr = 0;
502
503 if (ar->target_type == TARGET_TYPE_AR6003)
504 addr = ATH6KL_AR6003_HI_START_ADDR + item_offset;
505 else if (ar->target_type == TARGET_TYPE_AR6004)
506 addr = ATH6KL_AR6004_HI_START_ADDR + item_offset;
507
508 return addr;
509}
510
497void ath6kl_destroy(struct net_device *dev, unsigned int unregister); 511void ath6kl_destroy(struct net_device *dev, unsigned int unregister);
498int ath6kl_configure_target(struct ath6kl *ar); 512int ath6kl_configure_target(struct ath6kl *ar);
499void ath6kl_detect_error(unsigned long ptr); 513void ath6kl_detect_error(unsigned long ptr);
@@ -510,6 +524,7 @@ void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar);
510int ath6kl_diag_write(struct ath6kl *ar, u32 address, void *data, u32 length); 524int ath6kl_diag_write(struct ath6kl *ar, u32 address, void *data, u32 length);
511int ath6kl_diag_read32(struct ath6kl *ar, u32 address, u32 *value); 525int ath6kl_diag_read32(struct ath6kl *ar, u32 address, u32 *value);
512int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length); 526int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length);
527int ath6kl_read_fwlogs(struct ath6kl *ar);
513void ath6kl_init_profile_info(struct ath6kl *ar); 528void ath6kl_init_profile_info(struct ath6kl *ar);
514void ath6kl_tx_data_cleanup(struct ath6kl *ar); 529void ath6kl_tx_data_cleanup(struct ath6kl *ar);
515void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile, 530void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index 239c092d3e11..87de44d0ee33 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -247,6 +247,9 @@ static ssize_t ath6kl_fwlog_read(struct file *file, char __user *user_buf,
247 if (!buf) 247 if (!buf)
248 return -ENOMEM; 248 return -ENOMEM;
249 249
250 /* read undelivered logs from firmware */
251 ath6kl_read_fwlogs(ar);
252
250 spin_lock_bh(&ar->debug.fwlog_lock); 253 spin_lock_bh(&ar->debug.fwlog_lock);
251 254
252 while (len < buf_len && !ath6kl_debug_fwlog_empty(ar)) { 255 while (len < buf_len && !ath6kl_debug_fwlog_empty(ar)) {
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 60baf448f548..d234dc22e709 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -110,19 +110,6 @@ static u8 ath6kl_get_fw_iftype(struct ath6kl *ar)
110 } 110 }
111} 111}
112 112
113static inline u32 ath6kl_get_hi_item_addr(struct ath6kl *ar,
114 u32 item_offset)
115{
116 u32 addr = 0;
117
118 if (ar->target_type == TARGET_TYPE_AR6003)
119 addr = ATH6KL_AR6003_HI_START_ADDR + item_offset;
120 else if (ar->target_type == TARGET_TYPE_AR6004)
121 addr = ATH6KL_AR6004_HI_START_ADDR + item_offset;
122
123 return addr;
124}
125
126static int ath6kl_set_host_app_area(struct ath6kl *ar) 113static int ath6kl_set_host_app_area(struct ath6kl *ar)
127{ 114{
128 u32 address, data; 115 u32 address, data;
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index e346f835e779..937c7a238c12 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -309,6 +309,81 @@ int ath6kl_diag_write(struct ath6kl *ar, u32 address, void *data, u32 length)
309 return 0; 309 return 0;
310} 310}
311 311
312int ath6kl_read_fwlogs(struct ath6kl *ar)
313{
314 struct ath6kl_dbglog_hdr debug_hdr;
315 struct ath6kl_dbglog_buf debug_buf;
316 u32 address, length, dropped, firstbuf, debug_hdr_addr;
317 int ret = 0, loop;
318 u8 *buf;
319
320 buf = kmalloc(ATH6KL_FWLOG_PAYLOAD_SIZE, GFP_KERNEL);
321 if (!buf)
322 return -ENOMEM;
323
324 address = TARG_VTOP(ar->target_type,
325 ath6kl_get_hi_item_addr(ar,
326 HI_ITEM(hi_dbglog_hdr)));
327
328 ret = ath6kl_diag_read32(ar, address, &debug_hdr_addr);
329 if (ret)
330 goto out;
331
332 /* Get the contents of the ring buffer */
333 if (debug_hdr_addr == 0) {
334 ath6kl_warn("Invalid address for debug_hdr_addr\n");
335 ret = -EINVAL;
336 goto out;
337 }
338
339 address = TARG_VTOP(ar->target_type, debug_hdr_addr);
340 ath6kl_diag_read(ar, address, &debug_hdr, sizeof(debug_hdr));
341
342 address = TARG_VTOP(ar->target_type,
343 le32_to_cpu(debug_hdr.dbuf_addr));
344 firstbuf = address;
345 dropped = le32_to_cpu(debug_hdr.dropped);
346 ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf));
347
348 loop = 100;
349
350 do {
351 address = TARG_VTOP(ar->target_type,
352 le32_to_cpu(debug_buf.buffer_addr));
353 length = le32_to_cpu(debug_buf.length);
354
355 if (length != 0 && (le32_to_cpu(debug_buf.length) <=
356 le32_to_cpu(debug_buf.bufsize))) {
357 length = ALIGN(length, 4);
358
359 ret = ath6kl_diag_read(ar, address,
360 buf, length);
361 if (ret)
362 goto out;
363
364 ath6kl_debug_fwlog_event(ar, buf, length);
365 }
366
367 address = TARG_VTOP(ar->target_type,
368 le32_to_cpu(debug_buf.next));
369 ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf));
370 if (ret)
371 goto out;
372
373 loop--;
374
375 if (WARN_ON(loop == 0)) {
376 ret = -ETIMEDOUT;
377 goto out;
378 }
379 } while (address != firstbuf);
380
381out:
382 kfree(buf);
383
384 return ret;
385}
386
312/* FIXME: move to a better place, target.h? */ 387/* FIXME: move to a better place, target.h? */
313#define AR6003_RESET_CONTROL_ADDRESS 0x00004000 388#define AR6003_RESET_CONTROL_ADDRESS 0x00004000
314#define AR6004_RESET_CONTROL_ADDRESS 0x00004000 389#define AR6004_RESET_CONTROL_ADDRESS 0x00004000
diff --git a/drivers/net/wireless/ath/ath6kl/target.h b/drivers/net/wireless/ath/ath6kl/target.h
index 6c66a08e1793..dd8b953cbfc0 100644
--- a/drivers/net/wireless/ath/ath6kl/target.h
+++ b/drivers/net/wireless/ath/ath6kl/target.h
@@ -343,4 +343,18 @@ struct host_interest {
343 343
344#define ATH6KL_FWLOG_PAYLOAD_SIZE 1500 344#define ATH6KL_FWLOG_PAYLOAD_SIZE 1500
345 345
346struct ath6kl_dbglog_buf {
347 __le32 next;
348 __le32 buffer_addr;
349 __le32 bufsize;
350 __le32 length;
351 __le32 count;
352 __le32 free;
353} __packed;
354
355struct ath6kl_dbglog_hdr {
356 __le32 dbuf_addr;
357 __le32 dropped;
358} __packed;
359
346#endif 360#endif