2018-09-05 02:25:16

by Tom Psyborg

[permalink] [raw]
Subject: [PATCH v2 1/3] ath9k: use common debug for ack timeout output

Move ack debug code to common-debug and adjust
ath9k/ath9k_htc debug for common ack output.
This enables ack output in debugfs for ath9k_htc
driver too.

Signed-off-by: Tomislav Požega <[email protected]>
---
drivers/net/wireless/ath/ath9k/common-debug.c | 29 ++++++++++++++++++++++++
drivers/net/wireless/ath/ath9k/common-debug.h | 7 +++++
drivers/net/wireless/ath/ath9k/debug.c | 26 +--------------------
drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 4 +++
4 files changed, 41 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/common-debug.c b/drivers/net/wireless/ath/ath9k/common-debug.c
index 239429f..230fe55 100644
--- a/drivers/net/wireless/ath/ath9k/common-debug.c
+++ b/drivers/net/wireless/ath/ath9k/common-debug.c
@@ -258,3 +258,32 @@ void ath9k_cmn_debug_phy_err(struct dentry *debugfs_phy,
&fops_phy_err);
}
EXPORT_SYMBOL(ath9k_cmn_debug_phy_err);
+
+#ifdef CONFIG_ATH9K_DYNACK
+static ssize_t read_file_ackto(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_hw *ah = file->private_data;
+ char buf[32];
+ unsigned int len;
+
+ len = sprintf(buf, "%u %c\n", ah->dynack.ackto,
+ (ah->dynack.enabled) ? 'A' : 'S');
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_ackto = {
+ .read = read_file_ackto,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+void ath9k_cmn_debug_ack_to(struct dentry *debugfs_phy,
+ struct ath_hw *ah)
+{
+ debugfs_create_file("ack_to", 0400, debugfs_phy, ah, &fops_ackto);
+}
+EXPORT_SYMBOL(ath9k_cmn_debug_ack_to);
+#endif
diff --git a/drivers/net/wireless/ath/ath9k/common-debug.h b/drivers/net/wireless/ath/ath9k/common-debug.h
index 3376990..a4bc75f 100644
--- a/drivers/net/wireless/ath/ath9k/common-debug.h
+++ b/drivers/net/wireless/ath/ath9k/common-debug.h
@@ -71,6 +71,8 @@ void ath9k_cmn_debug_recv(struct dentry *debugfs_phy,
struct ath_rx_stats *rxstats);
void ath9k_cmn_debug_phy_err(struct dentry *debugfs_phy,
struct ath_rx_stats *rxstats);
+void ath9k_cmn_debug_ack_to(struct dentry *debugfs_phy,
+ struct ath_hw *ah);
#else
static inline void ath9k_cmn_debug_modal_eeprom(struct dentry *debugfs_phy,
struct ath_hw *ah)
@@ -96,4 +98,9 @@ static inline void ath9k_cmn_debug_phy_err(struct dentry *debugfs_phy,
struct ath_rx_stats *rxstats)
{
}
+
+static inline void ath9k_cmn_debug_ack_to(struct dentry *debugfs_phy,
+ struct ath_hw *ah)
+{
+}
#endif /* CONFIG_ATH9K_COMMON_DEBUG */
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 0a6eb8a..d2ea0b1 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1038,29 +1038,6 @@ static ssize_t read_file_btcoex(struct file *file, char __user *user_buf,
};
#endif

-#ifdef CONFIG_ATH9K_DYNACK
-static ssize_t read_file_ackto(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath_softc *sc = file->private_data;
- struct ath_hw *ah = sc->sc_ah;
- char buf[32];
- unsigned int len;
-
- len = sprintf(buf, "%u %c\n", ah->dynack.ackto,
- (ah->dynack.enabled) ? 'A' : 'S');
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static const struct file_operations fops_ackto = {
- .read = read_file_ackto,
- .open = simple_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-#endif
-
#ifdef CONFIG_ATH9K_WOW

static ssize_t read_file_wow(struct file *file, char __user *user_buf,
@@ -1451,8 +1428,7 @@ int ath9k_init_debug(struct ath_hw *ah)
#endif

#ifdef CONFIG_ATH9K_DYNACK
- debugfs_create_file("ack_to", 0400, sc->debug.debugfs_phy,
- sc, &fops_ackto);
+ ath9k_cmn_debug_ack_to(sc->debug.debugfs_phy, sc->sc_ah);
#endif
debugfs_create_file("tpc", 0600, sc->debug.debugfs_phy, sc, &fops_tpc);

diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
index b3ed65e..a345da8 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
@@ -520,5 +520,9 @@ int ath9k_htc_init_debug(struct ath_hw *ah)
ath9k_cmn_debug_base_eeprom(priv->debug.debugfs_phy, priv->ah);
ath9k_cmn_debug_modal_eeprom(priv->debug.debugfs_phy, priv->ah);

+#ifdef CONFIG_ATH9K_DYNACK
+ ath9k_cmn_debug_ack_to(priv->debug.debugfs_phy, priv->ah);
+#endif
+
return 0;
}
--
1.7.0.4


2018-09-05 02:25:18

by Tom Psyborg

[permalink] [raw]
Subject: [PATCH v2 3/3] ath9k_htc: increase number of configurable virtual interfaces

Increase driver limit for various interface combinations.
I was able to start 8 virtual APs and connect 5 clients to
these.
New firmware will be sent to linux-firmware mailing list too.
Meanwhile, take a look here for changes it includes if you wish
to build it yourself:
https://github.com/qca/open-ath9k-htc-firmware/pull/149

Signed-off-by: Tomislav Požega <[email protected]>
---
drivers/net/wireless/ath/ath9k/hif_usb.c | 4 ++--
drivers/net/wireless/ath/ath9k/htc.h | 8 ++++----
drivers/net/wireless/ath/ath9k/htc_drv_init.c | 6 +++---
3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index fb649d8..fdcf224 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -1131,10 +1131,10 @@ static int ath9k_hif_request_firmware(struct hif_device_usb *hif_dev,

/* expected fw locations:
* - ath9k_htc/htc_9271-1.dev.0.fw (development version)
- * - ath9k_htc/htc_9271-1.4.0.fw (stable version)
+ * - ath9k_htc/htc_9271-1.4.1.fw (stable version)
*/
snprintf(hif_dev->fw_name, sizeof(hif_dev->fw_name),
- "%s/htc_%s-%d.%s.0.fw", HTC_FW_PATH,
+ "%s/htc_%s-%d.%s.1.fw", HTC_FW_PATH,
chip, MAJOR_VERSION_REQ, index);
}

diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 5490c5f..b6c577b 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -197,8 +197,8 @@ struct ath9k_htc_target_rx_stats {
__be32 host_done;
} __packed;

-#define ATH9K_HTC_MAX_VIF 2
-#define ATH9K_HTC_MAX_BCN_VIF 2
+#define ATH9K_HTC_MAX_VIF 8
+#define ATH9K_HTC_MAX_BCN_VIF 8

#define INC_VIF(_priv, _type) do { \
switch (_type) { \
@@ -251,8 +251,8 @@ struct ath9k_vif_iter_data {
u8 mask[ETH_ALEN];
};

-#define ATH9K_HTC_MAX_STA 8
-#define ATH9K_HTC_MAX_TID 8
+#define ATH9K_HTC_MAX_STA 128
+#define ATH9K_HTC_MAX_TID 16

enum tid_aggr_state {
AGGR_STOP = 0,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 214c682..fa13ba9 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -697,9 +697,9 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
}

static const struct ieee80211_iface_limit if_limits[] = {
- { .max = 2, .types = BIT(NL80211_IFTYPE_STATION) |
+ { .max = 8, .types = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_P2P_CLIENT) },
- { .max = 2, .types = BIT(NL80211_IFTYPE_AP) |
+ { .max = 8, .types = BIT(NL80211_IFTYPE_AP) |
#ifdef CONFIG_MAC80211_MESH
BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
@@ -709,7 +709,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
static const struct ieee80211_iface_combination if_comb = {
.limits = if_limits,
.n_limits = ARRAY_SIZE(if_limits),
- .max_interfaces = 2,
+ .max_interfaces = 8,
.num_different_channels = 1,
};

--
1.7.0.4

2018-09-05 02:25:18

by Tom Psyborg

[permalink] [raw]
Subject: [PATCH v2 2/3] ath9k_htc: enable ANI debug output

Enable ANI output in debug file similar to how it's done on ath9k.
Disabling the entire feature is also working. Tested with ALFA
AWUS036NHA device.

Signed-off-by: Tomislav Požega <[email protected]>
---
drivers/net/wireless/ath/ath9k/htc.h | 1 +
drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 98 ++++++++++++++++++++++++
drivers/net/wireless/ath/ath9k/htc_drv_main.c | 49 ++++++++++++
3 files changed, 148 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 9f64e32..5490c5f 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -564,6 +564,7 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
u8 enable_coex);
void ath9k_htc_ani_work(struct work_struct *work);
+void ath9k_htc_check_ani(struct ath9k_htc_priv *priv);
void ath9k_htc_start_ani(struct ath9k_htc_priv *priv);
void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv);

diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
index a345da8..cfbb309 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
@@ -398,6 +398,102 @@ static ssize_t write_file_debug(struct file *file, const char __user *user_buf,
.llseek = default_llseek,
};

+static ssize_t read_file_ani(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath9k_htc_priv *priv = file->private_data;
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ struct ath_hw *ah = priv->ah;
+ unsigned int len = 0;
+ const unsigned int size = 1024;
+ ssize_t retval = 0;
+ char *buf;
+ int i;
+ struct {
+ const char *name;
+ unsigned int val;
+ } ani_info[] = {
+ { "ANI RESET", ah->stats.ast_ani_reset },
+ { "OFDM LEVEL", ah->ani.ofdmNoiseImmunityLevel },
+ { "CCK LEVEL", ah->ani.cckNoiseImmunityLevel },
+ { "SPUR UP", ah->stats.ast_ani_spurup },
+ { "SPUR DOWN", ah->stats.ast_ani_spurup },
+ { "OFDM WS-DET ON", ah->stats.ast_ani_ofdmon },
+ { "OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff },
+ { "MRC-CCK ON", ah->stats.ast_ani_ccklow },
+ { "MRC-CCK OFF", ah->stats.ast_ani_cckhigh },
+ { "FIR-STEP UP", ah->stats.ast_ani_stepup },
+ { "FIR-STEP DOWN", ah->stats.ast_ani_stepdown },
+ { "INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero },
+ { "OFDM ERRORS", ah->stats.ast_ani_ofdmerrs },
+ { "CCK ERRORS", ah->stats.ast_ani_cckerrs },
+ };
+
+ buf = kzalloc(size, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ len += scnprintf(buf + len, size - len, "%15s: %s\n", "ANI",
+ common->disable_ani ? "DISABLED" : "ENABLED");
+
+ if (common->disable_ani)
+ goto exit;
+
+ for (i = 0; i < ARRAY_SIZE(ani_info); i++)
+ len += scnprintf(buf + len, size - len, "%15s: %u\n",
+ ani_info[i].name, ani_info[i].val);
+
+exit:
+ if (len > size)
+ len = size;
+
+ retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+
+ return retval;
+}
+
+static ssize_t write_file_ani(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath9k_htc_priv *priv = file->private_data;
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ unsigned long ani;
+ char buf[32];
+ ssize_t len;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+ if (kstrtoul(buf, 0, &ani))
+ return -EINVAL;
+
+ if (ani > 1)
+ return -EINVAL;
+
+ common->disable_ani = !ani;
+
+ if (common->disable_ani) {
+ clear_bit(ATH_OP_ANI_RUN, &common->op_flags);
+ ath9k_htc_stop_ani(priv);
+ } else {
+ ath9k_htc_check_ani(priv);
+ }
+
+ return count;
+}
+
+static const struct file_operations fops_ani = {
+ .read = read_file_ani,
+ .write = write_file_ani,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
/* Ethtool support for get-stats */
#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
static const char ath9k_htc_gstrings_stats[][ETH_GSTRING_LEN] = {
@@ -524,5 +620,7 @@ int ath9k_htc_init_debug(struct ath_hw *ah)
ath9k_cmn_debug_ack_to(priv->debug.debugfs_phy, priv->ah);
#endif

+ debugfs_create_file("ani", 0600, priv->debug.debugfs_phy, priv, &fops_ani);
+
return 0;
}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index a82ad73..73f6fe1 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1505,11 +1505,55 @@ static void ath9k_htc_choose_set_bssid(struct ath9k_htc_priv *priv)
}
}

+void ath9k_htc_check_ani(struct ath9k_htc_priv *priv)
+{
+ struct ath_hw *ah = priv->ah;
+ struct ath_common *common = ath9k_hw_common(ah);
+ struct ath_beacon_config *cur_conf = &priv->cur_beacon_conf;
+
+ /*
+ * Check for the various conditions in which ANI has to
+ * be stopped.
+ */
+ if (ah->opmode == NL80211_IFTYPE_ADHOC) {
+ if (!cur_conf->enable_beacon)
+ goto stop_ani;
+ } else if (ah->opmode == NL80211_IFTYPE_AP) {
+ if (!cur_conf->enable_beacon) {
+ /*
+ * Disable ANI only when there are no
+ * associated stations.
+ */
+ if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags))
+ goto stop_ani;
+ }
+ } else if (ah->opmode == NL80211_IFTYPE_STATION) {
+ if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags))
+ goto stop_ani;
+ }
+
+ if (!test_bit(ATH_OP_ANI_RUN, &common->op_flags)) {
+ set_bit(ATH_OP_ANI_RUN, &common->op_flags);
+ ath9k_htc_start_ani(priv);
+ }
+
+ return;
+
+stop_ani:
+ clear_bit(ATH_OP_ANI_RUN, &common->op_flags);
+ ath9k_htc_stop_ani(priv);
+}
+
static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
u32 changed)
{
+#define CHECK_ANI \
+ (BSS_CHANGED_ASSOC | \
+ BSS_CHANGED_IBSS | \
+ BSS_CHANGED_BEACON_ENABLED)
+
struct ath9k_htc_priv *priv = hw->priv;
struct ath_hw *ah = priv->ah;
struct ath_common *common = ath9k_hw_common(ah);
@@ -1609,8 +1653,13 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_HT)
ath9k_htc_update_rate(priv, vif, bss_conf);

+ if (changed & CHECK_ANI)
+ ath9k_htc_check_ani(priv);
+
ath9k_htc_ps_restore(priv);
mutex_unlock(&priv->mutex);
+
+#undef CHECK_ANI
}

static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw,
--
1.7.0.4