aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c94
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c13
4 files changed, 115 insertions, 3 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index aadb5de9ac7..d4640117fa8 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -254,7 +254,10 @@ struct ath_atx_tid {
254}; 254};
255 255
256struct ath_node { 256struct ath_node {
257 struct ath_common *common; 257#ifdef CONFIG_ATH9K_DEBUGFS
258 struct list_head list; /* for sc->nodes */
259 struct ieee80211_sta *sta; /* station struct we're part of */
260#endif
258 struct ath_atx_tid tid[WME_NUM_TID]; 261 struct ath_atx_tid tid[WME_NUM_TID];
259 struct ath_atx_ac ac[WME_NUM_AC]; 262 struct ath_atx_ac ac[WME_NUM_AC];
260 u16 maxampdu; 263 u16 maxampdu;
@@ -638,6 +641,8 @@ struct ath_softc {
638 641
639#ifdef CONFIG_ATH9K_DEBUGFS 642#ifdef CONFIG_ATH9K_DEBUGFS
640 struct ath9k_debug debug; 643 struct ath9k_debug debug;
644 spinlock_t nodes_lock;
645 struct list_head nodes; /* basically, stations */
641#endif 646#endif
642 struct ath_beacon_config cur_beacon_conf; 647 struct ath_beacon_config cur_beacon_conf;
643 struct delayed_work tx_complete_work; 648 struct delayed_work tx_complete_work;
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index faf84e499c8..650f00f59d7 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -587,6 +587,8 @@ static const struct file_operations fops_wiphy = {
587 sc->debug.stats.txstats[WME_AC_BK].elem, \ 587 sc->debug.stats.txstats[WME_AC_BK].elem, \
588 sc->debug.stats.txstats[WME_AC_VI].elem, \ 588 sc->debug.stats.txstats[WME_AC_VI].elem, \
589 sc->debug.stats.txstats[WME_AC_VO].elem); \ 589 sc->debug.stats.txstats[WME_AC_VO].elem); \
590 if (len >= size) \
591 goto done; \
590} while(0) 592} while(0)
591 593
592#define PRX(str, elem) \ 594#define PRX(str, elem) \
@@ -597,6 +599,8 @@ do { \
597 (unsigned int)(sc->tx.txq[WME_AC_BK].elem), \ 599 (unsigned int)(sc->tx.txq[WME_AC_BK].elem), \
598 (unsigned int)(sc->tx.txq[WME_AC_VI].elem), \ 600 (unsigned int)(sc->tx.txq[WME_AC_VI].elem), \
599 (unsigned int)(sc->tx.txq[WME_AC_VO].elem)); \ 601 (unsigned int)(sc->tx.txq[WME_AC_VO].elem)); \
602 if (len >= size) \
603 goto done; \
600} while(0) 604} while(0)
601 605
602#define PRQLE(str, elem) \ 606#define PRQLE(str, elem) \
@@ -607,6 +611,8 @@ do { \
607 list_empty(&sc->tx.txq[WME_AC_BK].elem), \ 611 list_empty(&sc->tx.txq[WME_AC_BK].elem), \
608 list_empty(&sc->tx.txq[WME_AC_VI].elem), \ 612 list_empty(&sc->tx.txq[WME_AC_VI].elem), \
609 list_empty(&sc->tx.txq[WME_AC_VO].elem)); \ 613 list_empty(&sc->tx.txq[WME_AC_VO].elem)); \
614 if (len >= size) \
615 goto done; \
610} while (0) 616} while (0)
611 617
612static ssize_t read_file_xmit(struct file *file, char __user *user_buf, 618static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
@@ -614,7 +620,7 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
614{ 620{
615 struct ath_softc *sc = file->private_data; 621 struct ath_softc *sc = file->private_data;
616 char *buf; 622 char *buf;
617 unsigned int len = 0, size = 4000; 623 unsigned int len = 0, size = 8000;
618 int i; 624 int i;
619 ssize_t retval = 0; 625 ssize_t retval = 0;
620 char tmp[32]; 626 char tmp[32];
@@ -623,7 +629,10 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
623 if (buf == NULL) 629 if (buf == NULL)
624 return -ENOMEM; 630 return -ENOMEM;
625 631
626 len += sprintf(buf, "%30s %10s%10s%10s\n\n", "BE", "BK", "VI", "VO"); 632 len += sprintf(buf, "Num-Tx-Queues: %i tx-queues-setup: 0x%x\n"
633 "%30s %10s%10s%10s\n\n",
634 ATH9K_NUM_TX_QUEUES, sc->tx.txqsetup,
635 "BE", "BK", "VI", "VO");
627 636
628 PR("MPDUs Queued: ", queued); 637 PR("MPDUs Queued: ", queued);
629 PR("MPDUs Completed: ", completed); 638 PR("MPDUs Completed: ", completed);
@@ -644,6 +653,14 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
644 PR("hw-put-tx-buf: ", puttxbuf); 653 PR("hw-put-tx-buf: ", puttxbuf);
645 PR("hw-tx-start: ", txstart); 654 PR("hw-tx-start: ", txstart);
646 PR("hw-tx-proc-desc: ", txprocdesc); 655 PR("hw-tx-proc-desc: ", txprocdesc);
656 len += snprintf(buf + len, size - len,
657 "%s%11p%11p%10p%10p\n", "txq-memory-address:",
658 &(sc->tx.txq[WME_AC_BE]),
659 &(sc->tx.txq[WME_AC_BK]),
660 &(sc->tx.txq[WME_AC_VI]),
661 &(sc->tx.txq[WME_AC_VO]));
662 if (len >= size)
663 goto done;
647 664
648 PRX("axq-qnum: ", axq_qnum); 665 PRX("axq-qnum: ", axq_qnum);
649 PRX("axq-depth: ", axq_depth); 666 PRX("axq-depth: ", axq_depth);
@@ -661,6 +678,68 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
661 snprintf(tmp, sizeof(tmp) - 1, "txq_fifo[%i] empty: ", i); 678 snprintf(tmp, sizeof(tmp) - 1, "txq_fifo[%i] empty: ", i);
662 PRQLE(tmp, txq_fifo[i]); 679 PRQLE(tmp, txq_fifo[i]);
663 } 680 }
681
682done:
683 if (len > size)
684 len = size;
685
686 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
687 kfree(buf);
688
689 return retval;
690}
691
692static ssize_t read_file_stations(struct file *file, char __user *user_buf,
693 size_t count, loff_t *ppos)
694{
695 struct ath_softc *sc = file->private_data;
696 char *buf;
697 unsigned int len = 0, size = 64000;
698 struct ath_node *an = NULL;
699 ssize_t retval = 0;
700 int q;
701
702 buf = kzalloc(size, GFP_KERNEL);
703 if (buf == NULL)
704 return -ENOMEM;
705
706 len += snprintf(buf + len, size - len,
707 "Stations:\n"
708 " tid: addr sched paused buf_q-empty an ac\n"
709 " ac: addr sched tid_q-empty txq\n");
710
711 spin_lock(&sc->nodes_lock);
712 list_for_each_entry(an, &sc->nodes, list) {
713 len += snprintf(buf + len, size - len,
714 "%pM\n", an->sta->addr);
715 if (len >= size)
716 goto done;
717
718 for (q = 0; q < WME_NUM_TID; q++) {
719 struct ath_atx_tid *tid = &(an->tid[q]);
720 len += snprintf(buf + len, size - len,
721 " tid: %p %s %s %i %p %p\n",
722 tid, tid->sched ? "sched" : "idle",
723 tid->paused ? "paused" : "running",
724 list_empty(&tid->buf_q),
725 tid->an, tid->ac);
726 if (len >= size)
727 goto done;
728 }
729
730 for (q = 0; q < WME_NUM_AC; q++) {
731 struct ath_atx_ac *ac = &(an->ac[q]);
732 len += snprintf(buf + len, size - len,
733 " ac: %p %s %i %p\n",
734 ac, ac->sched ? "sched" : "idle",
735 list_empty(&ac->tid_q), ac->txq);
736 if (len >= size)
737 goto done;
738 }
739 }
740
741done:
742 spin_unlock(&sc->nodes_lock);
664 if (len > size) 743 if (len > size)
665 len = size; 744 len = size;
666 745
@@ -708,6 +787,13 @@ static const struct file_operations fops_xmit = {
708 .llseek = default_llseek, 787 .llseek = default_llseek,
709}; 788};
710 789
790static const struct file_operations fops_stations = {
791 .read = read_file_stations,
792 .open = ath9k_debugfs_open,
793 .owner = THIS_MODULE,
794 .llseek = default_llseek,
795};
796
711static ssize_t read_file_recv(struct file *file, char __user *user_buf, 797static ssize_t read_file_recv(struct file *file, char __user *user_buf,
712 size_t count, loff_t *ppos) 798 size_t count, loff_t *ppos)
713{ 799{
@@ -945,6 +1031,10 @@ int ath9k_init_debug(struct ath_hw *ah)
945 sc, &fops_xmit)) 1031 sc, &fops_xmit))
946 goto err; 1032 goto err;
947 1033
1034 if (!debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy,
1035 sc, &fops_stations))
1036 goto err;
1037
948 if (!debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, 1038 if (!debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy,
949 sc, &fops_recv)) 1039 sc, &fops_recv))
950 goto err; 1040 goto err;
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 23b299818b1..59c01ca4379 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -559,6 +559,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
559 spin_lock_init(&sc->sc_serial_rw); 559 spin_lock_init(&sc->sc_serial_rw);
560 spin_lock_init(&sc->sc_pm_lock); 560 spin_lock_init(&sc->sc_pm_lock);
561 mutex_init(&sc->mutex); 561 mutex_init(&sc->mutex);
562#ifdef CONFIG_ATH9K_DEBUGFS
563 spin_lock_init(&sc->nodes_lock);
564 INIT_LIST_HEAD(&sc->nodes);
565#endif
562 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); 566 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
563 tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, 567 tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
564 (unsigned long)sc); 568 (unsigned long)sc);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index c03184e7bff..bed6eb97fac 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -548,6 +548,12 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
548 struct ath_hw *ah = sc->sc_ah; 548 struct ath_hw *ah = sc->sc_ah;
549 an = (struct ath_node *)sta->drv_priv; 549 an = (struct ath_node *)sta->drv_priv;
550 550
551#ifdef CONFIG_ATH9K_DEBUGFS
552 spin_lock(&sc->nodes_lock);
553 list_add(&an->list, &sc->nodes);
554 spin_unlock(&sc->nodes_lock);
555 an->sta = sta;
556#endif
551 if ((ah->caps.hw_caps) & ATH9K_HW_CAP_APM) 557 if ((ah->caps.hw_caps) & ATH9K_HW_CAP_APM)
552 sc->sc_flags |= SC_OP_ENABLE_APM; 558 sc->sc_flags |= SC_OP_ENABLE_APM;
553 559
@@ -563,6 +569,13 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
563{ 569{
564 struct ath_node *an = (struct ath_node *)sta->drv_priv; 570 struct ath_node *an = (struct ath_node *)sta->drv_priv;
565 571
572#ifdef CONFIG_ATH9K_DEBUGFS
573 spin_lock(&sc->nodes_lock);
574 list_del(&an->list);
575 spin_unlock(&sc->nodes_lock);
576 an->sta = NULL;
577#endif
578
566 if (sc->sc_flags & SC_OP_TXAGGR) 579 if (sc->sc_flags & SC_OP_TXAGGR)
567 ath_tx_node_cleanup(sc, an); 580 ath_tx_node_cleanup(sc, an);
568} 581}