diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-03-11 14:11:11 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-03-11 14:11:11 -0500 |
commit | 409ec36c320d580a036045e603f96286c362c609 (patch) | |
tree | 3dd9b3569799f7962b523a068052445e2d2c51aa /drivers/net/wireless/ath | |
parent | 1b7fe59322bef9e7a2c05b64a07a66b875299736 (diff) | |
parent | 8d5eab5aa676378b4c9daa62d10d08a0bca04677 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/ahb.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/ath5k.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.c | 52 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.h | 13 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/mac80211-ops.c | 19 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ahb.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_phy.c | 37 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.c | 62 |
8 files changed, 133 insertions, 56 deletions
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index ae84b86c3bf2..82324e98efef 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c | |||
@@ -93,7 +93,7 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
93 | goto err_out; | 93 | goto err_out; |
94 | } | 94 | } |
95 | 95 | ||
96 | mem = ioremap_nocache(res->start, res->end - res->start + 1); | 96 | mem = ioremap_nocache(res->start, resource_size(res)); |
97 | if (mem == NULL) { | 97 | if (mem == NULL) { |
98 | dev_err(&pdev->dev, "ioremap failed\n"); | 98 | dev_err(&pdev->dev, "ioremap failed\n"); |
99 | ret = -ENOMEM; | 99 | ret = -ENOMEM; |
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 0ee54eb333de..8a06dbd39629 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -513,7 +513,7 @@ enum ath5k_tx_queue_id { | |||
513 | AR5K_TX_QUEUE_ID_NOQCU_DATA = 0, | 513 | AR5K_TX_QUEUE_ID_NOQCU_DATA = 0, |
514 | AR5K_TX_QUEUE_ID_NOQCU_BEACON = 1, | 514 | AR5K_TX_QUEUE_ID_NOQCU_BEACON = 1, |
515 | AR5K_TX_QUEUE_ID_DATA_MIN = 0, /*IEEE80211_TX_QUEUE_DATA0*/ | 515 | AR5K_TX_QUEUE_ID_DATA_MIN = 0, /*IEEE80211_TX_QUEUE_DATA0*/ |
516 | AR5K_TX_QUEUE_ID_DATA_MAX = 4, /*IEEE80211_TX_QUEUE_DATA4*/ | 516 | AR5K_TX_QUEUE_ID_DATA_MAX = 3, /*IEEE80211_TX_QUEUE_DATA3*/ |
517 | AR5K_TX_QUEUE_ID_DATA_SVP = 5, /*IEEE80211_TX_QUEUE_SVP - Spectralink Voice Protocol*/ | 517 | AR5K_TX_QUEUE_ID_DATA_SVP = 5, /*IEEE80211_TX_QUEUE_SVP - Spectralink Voice Protocol*/ |
518 | AR5K_TX_QUEUE_ID_CAB = 6, /*IEEE80211_TX_QUEUE_AFTER_BEACON*/ | 518 | AR5K_TX_QUEUE_ID_CAB = 6, /*IEEE80211_TX_QUEUE_AFTER_BEACON*/ |
519 | AR5K_TX_QUEUE_ID_BEACON = 7, /*IEEE80211_TX_QUEUE_BEACON*/ | 519 | AR5K_TX_QUEUE_ID_BEACON = 7, /*IEEE80211_TX_QUEUE_BEACON*/ |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 91411e9b4b68..e6ff62e60a79 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -442,19 +442,9 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) | |||
442 | return ath5k_reset(sc, chan, true); | 442 | return ath5k_reset(sc, chan, true); |
443 | } | 443 | } |
444 | 444 | ||
445 | struct ath_vif_iter_data { | 445 | void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) |
446 | const u8 *hw_macaddr; | ||
447 | u8 mask[ETH_ALEN]; | ||
448 | u8 active_mac[ETH_ALEN]; /* first active MAC */ | ||
449 | bool need_set_hw_addr; | ||
450 | bool found_active; | ||
451 | bool any_assoc; | ||
452 | enum nl80211_iftype opmode; | ||
453 | }; | ||
454 | |||
455 | static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | ||
456 | { | 446 | { |
457 | struct ath_vif_iter_data *iter_data = data; | 447 | struct ath5k_vif_iter_data *iter_data = data; |
458 | int i; | 448 | int i; |
459 | struct ath5k_vif *avf = (void *)vif->drv_priv; | 449 | struct ath5k_vif *avf = (void *)vif->drv_priv; |
460 | 450 | ||
@@ -484,9 +474,12 @@ static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
484 | */ | 474 | */ |
485 | if (avf->opmode == NL80211_IFTYPE_AP) | 475 | if (avf->opmode == NL80211_IFTYPE_AP) |
486 | iter_data->opmode = NL80211_IFTYPE_AP; | 476 | iter_data->opmode = NL80211_IFTYPE_AP; |
487 | else | 477 | else { |
478 | if (avf->opmode == NL80211_IFTYPE_STATION) | ||
479 | iter_data->n_stas++; | ||
488 | if (iter_data->opmode == NL80211_IFTYPE_UNSPECIFIED) | 480 | if (iter_data->opmode == NL80211_IFTYPE_UNSPECIFIED) |
489 | iter_data->opmode = avf->opmode; | 481 | iter_data->opmode = avf->opmode; |
482 | } | ||
490 | } | 483 | } |
491 | 484 | ||
492 | void | 485 | void |
@@ -494,7 +487,8 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, | |||
494 | struct ieee80211_vif *vif) | 487 | struct ieee80211_vif *vif) |
495 | { | 488 | { |
496 | struct ath_common *common = ath5k_hw_common(sc->ah); | 489 | struct ath_common *common = ath5k_hw_common(sc->ah); |
497 | struct ath_vif_iter_data iter_data; | 490 | struct ath5k_vif_iter_data iter_data; |
491 | u32 rfilt; | ||
498 | 492 | ||
499 | /* | 493 | /* |
500 | * Use the hardware MAC address as reference, the hardware uses it | 494 | * Use the hardware MAC address as reference, the hardware uses it |
@@ -505,12 +499,13 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, | |||
505 | iter_data.found_active = false; | 499 | iter_data.found_active = false; |
506 | iter_data.need_set_hw_addr = true; | 500 | iter_data.need_set_hw_addr = true; |
507 | iter_data.opmode = NL80211_IFTYPE_UNSPECIFIED; | 501 | iter_data.opmode = NL80211_IFTYPE_UNSPECIFIED; |
502 | iter_data.n_stas = 0; | ||
508 | 503 | ||
509 | if (vif) | 504 | if (vif) |
510 | ath_vif_iter(&iter_data, vif->addr, vif); | 505 | ath5k_vif_iter(&iter_data, vif->addr, vif); |
511 | 506 | ||
512 | /* Get list of all active MAC addresses */ | 507 | /* Get list of all active MAC addresses */ |
513 | ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter, | 508 | ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter, |
514 | &iter_data); | 509 | &iter_data); |
515 | memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN); | 510 | memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN); |
516 | 511 | ||
@@ -528,20 +523,19 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, | |||
528 | 523 | ||
529 | if (ath5k_hw_hasbssidmask(sc->ah)) | 524 | if (ath5k_hw_hasbssidmask(sc->ah)) |
530 | ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); | 525 | ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); |
531 | } | ||
532 | 526 | ||
533 | void | 527 | /* Set up RX Filter */ |
534 | ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif) | 528 | if (iter_data.n_stas > 1) { |
535 | { | 529 | /* If you have multiple STA interfaces connected to |
536 | struct ath5k_hw *ah = sc->ah; | 530 | * different APs, ARPs are not received (most of the time?) |
537 | u32 rfilt; | 531 | * Enabling PROMISC appears to fix that probem. |
532 | */ | ||
533 | sc->filter_flags |= AR5K_RX_FILTER_PROM; | ||
534 | } | ||
538 | 535 | ||
539 | /* configure rx filter */ | ||
540 | rfilt = sc->filter_flags; | 536 | rfilt = sc->filter_flags; |
541 | ath5k_hw_set_rx_filter(ah, rfilt); | 537 | ath5k_hw_set_rx_filter(sc->ah, rfilt); |
542 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); | 538 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); |
543 | |||
544 | ath5k_update_bssid_mask_and_opmode(sc, vif); | ||
545 | } | 539 | } |
546 | 540 | ||
547 | static inline int | 541 | static inline int |
@@ -1117,7 +1111,7 @@ ath5k_rx_start(struct ath5k_softc *sc) | |||
1117 | spin_unlock_bh(&sc->rxbuflock); | 1111 | spin_unlock_bh(&sc->rxbuflock); |
1118 | 1112 | ||
1119 | ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ | 1113 | ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ |
1120 | ath5k_mode_setup(sc, NULL); /* set filters, etc. */ | 1114 | ath5k_update_bssid_mask_and_opmode(sc, NULL); /* set filters, etc. */ |
1121 | ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ | 1115 | ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ |
1122 | 1116 | ||
1123 | return 0; | 1117 | return 0; |
@@ -2923,13 +2917,13 @@ ath5k_deinit_softc(struct ath5k_softc *sc) | |||
2923 | bool | 2917 | bool |
2924 | ath_any_vif_assoc(struct ath5k_softc *sc) | 2918 | ath_any_vif_assoc(struct ath5k_softc *sc) |
2925 | { | 2919 | { |
2926 | struct ath_vif_iter_data iter_data; | 2920 | struct ath5k_vif_iter_data iter_data; |
2927 | iter_data.hw_macaddr = NULL; | 2921 | iter_data.hw_macaddr = NULL; |
2928 | iter_data.any_assoc = false; | 2922 | iter_data.any_assoc = false; |
2929 | iter_data.need_set_hw_addr = false; | 2923 | iter_data.need_set_hw_addr = false; |
2930 | iter_data.found_active = true; | 2924 | iter_data.found_active = true; |
2931 | 2925 | ||
2932 | ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter, | 2926 | ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter, |
2933 | &iter_data); | 2927 | &iter_data); |
2934 | return iter_data.any_assoc; | 2928 | return iter_data.any_assoc; |
2935 | } | 2929 | } |
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 8f919dca95f1..8d1df1fa2351 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h | |||
@@ -259,6 +259,19 @@ struct ath5k_softc { | |||
259 | struct survey_info survey; /* collected survey info */ | 259 | struct survey_info survey; /* collected survey info */ |
260 | }; | 260 | }; |
261 | 261 | ||
262 | struct ath5k_vif_iter_data { | ||
263 | const u8 *hw_macaddr; | ||
264 | u8 mask[ETH_ALEN]; | ||
265 | u8 active_mac[ETH_ALEN]; /* first active MAC */ | ||
266 | bool need_set_hw_addr; | ||
267 | bool found_active; | ||
268 | bool any_assoc; | ||
269 | enum nl80211_iftype opmode; | ||
270 | int n_stas; | ||
271 | }; | ||
272 | void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif); | ||
273 | |||
274 | |||
262 | #define ath5k_hw_hasbssidmask(_ah) \ | 275 | #define ath5k_hw_hasbssidmask(_ah) \ |
263 | (ath5k_hw_get_capability(_ah, AR5K_CAP_BSSIDMASK, 0, NULL) == 0) | 276 | (ath5k_hw_get_capability(_ah, AR5K_CAP_BSSIDMASK, 0, NULL) == 0) |
264 | #define ath5k_hw_hasveol(_ah) \ | 277 | #define ath5k_hw_hasveol(_ah) \ |
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 1fbe3c0b9f08..c9b0b676adda 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c | |||
@@ -158,8 +158,7 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
158 | 158 | ||
159 | memcpy(&avf->lladdr, vif->addr, ETH_ALEN); | 159 | memcpy(&avf->lladdr, vif->addr, ETH_ALEN); |
160 | 160 | ||
161 | ath5k_mode_setup(sc, vif); | 161 | ath5k_update_bssid_mask_and_opmode(sc, vif); |
162 | |||
163 | ret = 0; | 162 | ret = 0; |
164 | end: | 163 | end: |
165 | mutex_unlock(&sc->lock); | 164 | mutex_unlock(&sc->lock); |
@@ -381,6 +380,7 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, | |||
381 | struct ath5k_softc *sc = hw->priv; | 380 | struct ath5k_softc *sc = hw->priv; |
382 | struct ath5k_hw *ah = sc->ah; | 381 | struct ath5k_hw *ah = sc->ah; |
383 | u32 mfilt[2], rfilt; | 382 | u32 mfilt[2], rfilt; |
383 | struct ath5k_vif_iter_data iter_data; /* to count STA interfaces */ | ||
384 | 384 | ||
385 | mutex_lock(&sc->lock); | 385 | mutex_lock(&sc->lock); |
386 | 386 | ||
@@ -454,6 +454,21 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, | |||
454 | break; | 454 | break; |
455 | } | 455 | } |
456 | 456 | ||
457 | iter_data.hw_macaddr = NULL; | ||
458 | iter_data.n_stas = 0; | ||
459 | iter_data.need_set_hw_addr = false; | ||
460 | ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter, | ||
461 | &iter_data); | ||
462 | |||
463 | /* Set up RX Filter */ | ||
464 | if (iter_data.n_stas > 1) { | ||
465 | /* If you have multiple STA interfaces connected to | ||
466 | * different APs, ARPs are not received (most of the time?) | ||
467 | * Enabling PROMISC appears to fix that probem. | ||
468 | */ | ||
469 | rfilt |= AR5K_RX_FILTER_PROM; | ||
470 | } | ||
471 | |||
457 | /* Set filters */ | 472 | /* Set filters */ |
458 | ath5k_hw_set_rx_filter(ah, rfilt); | 473 | ath5k_hw_set_rx_filter(ah, rfilt); |
459 | 474 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 993672105963..9cb0efa9b4c0 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c | |||
@@ -75,7 +75,7 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
75 | goto err_out; | 75 | goto err_out; |
76 | } | 76 | } |
77 | 77 | ||
78 | mem = ioremap_nocache(res->start, res->end - res->start + 1); | 78 | mem = ioremap_nocache(res->start, resource_size(res)); |
79 | if (mem == NULL) { | 79 | if (mem == NULL) { |
80 | dev_err(&pdev->dev, "ioremap failed\n"); | 80 | dev_err(&pdev->dev, "ioremap failed\n"); |
81 | ret = -ENOMEM; | 81 | ret = -ENOMEM; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 8d60f4f09acc..eb250d6b8038 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -1020,28 +1020,29 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, | |||
1020 | static void ar9003_hw_do_getnf(struct ath_hw *ah, | 1020 | static void ar9003_hw_do_getnf(struct ath_hw *ah, |
1021 | int16_t nfarray[NUM_NF_READINGS]) | 1021 | int16_t nfarray[NUM_NF_READINGS]) |
1022 | { | 1022 | { |
1023 | int16_t nf; | 1023 | #define AR_PHY_CH_MINCCA_PWR 0x1FF00000 |
1024 | 1024 | #define AR_PHY_CH_MINCCA_PWR_S 20 | |
1025 | nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR); | 1025 | #define AR_PHY_CH_EXT_MINCCA_PWR 0x01FF0000 |
1026 | nfarray[0] = sign_extend32(nf, 8); | 1026 | #define AR_PHY_CH_EXT_MINCCA_PWR_S 16 |
1027 | |||
1028 | nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR); | ||
1029 | nfarray[1] = sign_extend32(nf, 8); | ||
1030 | 1027 | ||
1031 | nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR); | 1028 | int16_t nf; |
1032 | nfarray[2] = sign_extend32(nf, 8); | 1029 | int i; |
1033 | |||
1034 | if (!IS_CHAN_HT40(ah->curchan)) | ||
1035 | return; | ||
1036 | 1030 | ||
1037 | nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); | 1031 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { |
1038 | nfarray[3] = sign_extend32(nf, 8); | 1032 | if (ah->rxchainmask & BIT(i)) { |
1033 | nf = MS(REG_READ(ah, ah->nf_regs[i]), | ||
1034 | AR_PHY_CH_MINCCA_PWR); | ||
1035 | nfarray[i] = sign_extend32(nf, 8); | ||
1039 | 1036 | ||
1040 | nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR); | 1037 | if (IS_CHAN_HT40(ah->curchan)) { |
1041 | nfarray[4] = sign_extend32(nf, 8); | 1038 | u8 ext_idx = AR9300_MAX_CHAINS + i; |
1042 | 1039 | ||
1043 | nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR); | 1040 | nf = MS(REG_READ(ah, ah->nf_regs[ext_idx]), |
1044 | nfarray[5] = sign_extend32(nf, 8); | 1041 | AR_PHY_CH_EXT_MINCCA_PWR); |
1042 | nfarray[ext_idx] = sign_extend32(nf, 8); | ||
1043 | } | ||
1044 | } | ||
1045 | } | ||
1045 | } | 1046 | } |
1046 | 1047 | ||
1047 | static void ar9003_hw_set_nf_limits(struct ath_hw *ah) | 1048 | static void ar9003_hw_set_nf_limits(struct ath_hw *ah) |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 5cfcf8c235a4..8df5a92a20f1 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -15,6 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/vmalloc.h> | ||
18 | #include <asm/unaligned.h> | 19 | #include <asm/unaligned.h> |
19 | 20 | ||
20 | #include "ath9k.h" | 21 | #include "ath9k.h" |
@@ -30,6 +31,19 @@ static int ath9k_debugfs_open(struct inode *inode, struct file *file) | |||
30 | return 0; | 31 | return 0; |
31 | } | 32 | } |
32 | 33 | ||
34 | static ssize_t ath9k_debugfs_read_buf(struct file *file, char __user *user_buf, | ||
35 | size_t count, loff_t *ppos) | ||
36 | { | ||
37 | u8 *buf = file->private_data; | ||
38 | return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); | ||
39 | } | ||
40 | |||
41 | static int ath9k_debugfs_release_buf(struct inode *inode, struct file *file) | ||
42 | { | ||
43 | vfree(file->private_data); | ||
44 | return 0; | ||
45 | } | ||
46 | |||
33 | #ifdef CONFIG_ATH_DEBUG | 47 | #ifdef CONFIG_ATH_DEBUG |
34 | 48 | ||
35 | static ssize_t read_file_debug(struct file *file, char __user *user_buf, | 49 | static ssize_t read_file_debug(struct file *file, char __user *user_buf, |
@@ -548,10 +562,10 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | |||
548 | PR("hw-tx-proc-desc: ", txprocdesc); | 562 | PR("hw-tx-proc-desc: ", txprocdesc); |
549 | len += snprintf(buf + len, size - len, | 563 | len += snprintf(buf + len, size - len, |
550 | "%s%11p%11p%10p%10p\n", "txq-memory-address:", | 564 | "%s%11p%11p%10p%10p\n", "txq-memory-address:", |
551 | &(sc->tx.txq_map[WME_AC_BE]), | 565 | sc->tx.txq_map[WME_AC_BE], |
552 | &(sc->tx.txq_map[WME_AC_BK]), | 566 | sc->tx.txq_map[WME_AC_BK], |
553 | &(sc->tx.txq_map[WME_AC_VI]), | 567 | sc->tx.txq_map[WME_AC_VI], |
554 | &(sc->tx.txq_map[WME_AC_VO])); | 568 | sc->tx.txq_map[WME_AC_VO]); |
555 | if (len >= size) | 569 | if (len >= size) |
556 | goto done; | 570 | goto done; |
557 | 571 | ||
@@ -1027,6 +1041,42 @@ static const struct file_operations fops_regval = { | |||
1027 | .llseek = default_llseek, | 1041 | .llseek = default_llseek, |
1028 | }; | 1042 | }; |
1029 | 1043 | ||
1044 | #define REGDUMP_LINE_SIZE 20 | ||
1045 | |||
1046 | static int open_file_regdump(struct inode *inode, struct file *file) | ||
1047 | { | ||
1048 | struct ath_softc *sc = inode->i_private; | ||
1049 | unsigned int len = 0; | ||
1050 | u8 *buf; | ||
1051 | int i; | ||
1052 | unsigned long num_regs, regdump_len, max_reg_offset; | ||
1053 | |||
1054 | max_reg_offset = AR_SREV_9300_20_OR_LATER(sc->sc_ah) ? 0x16bd4 : 0xb500; | ||
1055 | num_regs = max_reg_offset / 4 + 1; | ||
1056 | regdump_len = num_regs * REGDUMP_LINE_SIZE + 1; | ||
1057 | buf = vmalloc(regdump_len); | ||
1058 | if (!buf) | ||
1059 | return -ENOMEM; | ||
1060 | |||
1061 | ath9k_ps_wakeup(sc); | ||
1062 | for (i = 0; i < num_regs; i++) | ||
1063 | len += scnprintf(buf + len, regdump_len - len, | ||
1064 | "0x%06x 0x%08x\n", i << 2, REG_READ(sc->sc_ah, i << 2)); | ||
1065 | ath9k_ps_restore(sc); | ||
1066 | |||
1067 | file->private_data = buf; | ||
1068 | |||
1069 | return 0; | ||
1070 | } | ||
1071 | |||
1072 | static const struct file_operations fops_regdump = { | ||
1073 | .open = open_file_regdump, | ||
1074 | .read = ath9k_debugfs_read_buf, | ||
1075 | .release = ath9k_debugfs_release_buf, | ||
1076 | .owner = THIS_MODULE, | ||
1077 | .llseek = default_llseek,/* read accesses f_pos */ | ||
1078 | }; | ||
1079 | |||
1030 | int ath9k_init_debug(struct ath_hw *ah) | 1080 | int ath9k_init_debug(struct ath_hw *ah) |
1031 | { | 1081 | { |
1032 | struct ath_common *common = ath9k_hw_common(ah); | 1082 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -1091,6 +1141,10 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
1091 | sc->debug.debugfs_phy, &ah->config.cwm_ignore_extcca)) | 1141 | sc->debug.debugfs_phy, &ah->config.cwm_ignore_extcca)) |
1092 | goto err; | 1142 | goto err; |
1093 | 1143 | ||
1144 | if (!debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, | ||
1145 | sc, &fops_regdump)) | ||
1146 | goto err; | ||
1147 | |||
1094 | sc->debug.regidx = 0; | 1148 | sc->debug.regidx = 0; |
1095 | return 0; | 1149 | return 0; |
1096 | err: | 1150 | err: |