diff options
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/core.h | 15 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/debug.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/init.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/main.c | 75 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/target.h | 14 |
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 | ||
498 | static 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 | |||
497 | void ath6kl_destroy(struct net_device *dev, unsigned int unregister); | 511 | void ath6kl_destroy(struct net_device *dev, unsigned int unregister); |
498 | int ath6kl_configure_target(struct ath6kl *ar); | 512 | int ath6kl_configure_target(struct ath6kl *ar); |
499 | void ath6kl_detect_error(unsigned long ptr); | 513 | void ath6kl_detect_error(unsigned long ptr); |
@@ -510,6 +524,7 @@ void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar); | |||
510 | int ath6kl_diag_write(struct ath6kl *ar, u32 address, void *data, u32 length); | 524 | int ath6kl_diag_write(struct ath6kl *ar, u32 address, void *data, u32 length); |
511 | int ath6kl_diag_read32(struct ath6kl *ar, u32 address, u32 *value); | 525 | int ath6kl_diag_read32(struct ath6kl *ar, u32 address, u32 *value); |
512 | int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length); | 526 | int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length); |
527 | int ath6kl_read_fwlogs(struct ath6kl *ar); | ||
513 | void ath6kl_init_profile_info(struct ath6kl *ar); | 528 | void ath6kl_init_profile_info(struct ath6kl *ar); |
514 | void ath6kl_tx_data_cleanup(struct ath6kl *ar); | 529 | void ath6kl_tx_data_cleanup(struct ath6kl *ar); |
515 | void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile, | 530 | void 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 | ||
113 | static 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 | |||
126 | static int ath6kl_set_host_app_area(struct ath6kl *ar) | 113 | static 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 | ||
312 | int 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 | |||
381 | out: | ||
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 | ||
346 | struct 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 | |||
355 | struct ath6kl_dbglog_hdr { | ||
356 | __le32 dbuf_addr; | ||
357 | __le32 dropped; | ||
358 | } __packed; | ||
359 | |||
346 | #endif | 360 | #endif |