blob: e0051b5c6ad7b16980a697b68fd40f1972f2c83e [file] [log] [blame]
From 410e3c08cd5f7bd85e3ca3965fcbf79b9eb6d1e4 Mon Sep 17 00:00:00 2001
From: Shayne Chen <shayne.chen@mediatek.com>
Date: Tue, 12 Mar 2024 11:26:26 +0800
Subject: [PATCH 03/61] sync backports patches/ath5k
---
drivers/net/wireless/ath/ath5k/ath5k.h | 1 +
drivers/net/wireless/ath/ath5k/base.c | 8 +-
drivers/net/wireless/ath/ath5k/debug.c | 93 +++++++++++++++++++
drivers/net/wireless/ath/ath5k/dma.c | 8 ++
drivers/net/wireless/ath/ath5k/initvals.c | 6 ++
drivers/net/wireless/ath/ath5k/mac80211-ops.c | 9 +-
drivers/net/wireless/ath/ath5k/pci.c | 2 +
drivers/net/wireless/ath/ath5k/reset.c | 2 +
include/linux/ath5k_platform.h | 30 ++++++
9 files changed, 150 insertions(+), 9 deletions(-)
create mode 100644 include/linux/ath5k_platform.h
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 308a429..0e6d184 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1372,6 +1372,7 @@ struct ath5k_hw {
u8 ah_coverage_class;
bool ah_ack_bitrate_high;
u8 ah_bwmode;
+ u8 ah_bwmode_debug;
bool ah_short_slot;
/* Antenna Control */
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index bad83fd..fb0366c 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -465,6 +465,9 @@ ath5k_chan_set(struct ath5k_hw *ah, struct cfg80211_chan_def *chandef)
return -EINVAL;
}
+ if (ah->ah_bwmode_debug != AR5K_BWMODE_DEFAULT)
+ ah->ah_bwmode = ah->ah_bwmode_debug;
+
/*
* To switch channels clear any pending DMA operations;
* wait long enough for the RX fifo to drain, reset the
@@ -2009,7 +2012,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
}
if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs +
- ah->num_mesh_vifs > 1) ||
+ ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) ||
ah->opmode == NL80211_IFTYPE_MESH_POINT) {
u64 tsf = ath5k_hw_get_tsf64(ah);
u32 tsftu = TSF_TO_TU(tsf);
@@ -2095,7 +2098,7 @@ ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf)
intval = ah->bintval & AR5K_BEACON_PERIOD;
if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs
- + ah->num_mesh_vifs > 1) {
+ + ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) {
intval /= ATH_BCBUF; /* staggered multi-bss beacons */
if (intval < 15)
ATH5K_WARN(ah, "intval %u is too low, min 15\n",
@@ -2561,6 +2564,7 @@ static const struct ieee80211_iface_limit if_limits[] = {
BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
BIT(NL80211_IFTYPE_AP) },
+ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
};
static const struct ieee80211_iface_combination if_comb = {
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index ec13051..239d789 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -803,6 +803,97 @@ static const struct file_operations fops_ani = {
.llseek = default_llseek,
};
+/* debugfs: bwmode */
+
+static ssize_t read_file_bwmode(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath5k_hw *ah = file->private_data;
+ char buf[15];
+ unsigned int len = 0;
+
+ int cur_ah_bwmode = ah->ah_bwmode_debug;
+
+#define print_selected(MODE, LABEL) \
+ if (cur_ah_bwmode == MODE) \
+ len += snprintf(buf+len, sizeof(buf)-len, "[%s]", LABEL); \
+ else \
+ len += snprintf(buf+len, sizeof(buf)-len, "%s", LABEL); \
+ len += snprintf(buf+len, sizeof(buf)-len, " ");
+
+ print_selected(AR5K_BWMODE_5MHZ, "5");
+ print_selected(AR5K_BWMODE_10MHZ, "10");
+ print_selected(AR5K_BWMODE_DEFAULT, "20");
+ print_selected(AR5K_BWMODE_40MHZ, "40");
+#undef print_selected
+
+ len += snprintf(buf+len, sizeof(buf)-len, "\n");
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_bwmode(struct file *file,
+ const char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct ath5k_hw *ah = file->private_data;
+ char buf[3];
+ int bw = 20;
+ int tobwmode = AR5K_BWMODE_DEFAULT;
+
+ if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+ return -EFAULT;
+
+ /* TODO: Add check for active interface */
+
+ if(strncmp(buf, "5", 1) == 0 ) {
+ tobwmode = AR5K_BWMODE_5MHZ;
+ bw = 5;
+ } else if ( strncmp(buf, "10", 2) == 0 ) {
+ tobwmode = AR5K_BWMODE_10MHZ;
+ bw = 10;
+ } else if ( strncmp(buf, "20", 2) == 0 ) {
+ tobwmode = AR5K_BWMODE_DEFAULT;
+ bw = 20;
+ } else if ( strncmp(buf, "40", 2) == 0 ) {
+ tobwmode = AR5K_BWMODE_40MHZ;
+ bw = 40;
+ } else
+ return -EINVAL;
+
+ ATH5K_INFO(ah, "Changing to %imhz channel width[%i]\n",
+ bw, tobwmode);
+
+ switch (ah->ah_radio) {
+ /* TODO: only define radios that actually support 5/10mhz channels */
+ case AR5K_RF5413:
+ case AR5K_RF5110:
+ case AR5K_RF5111:
+ case AR5K_RF5112:
+ case AR5K_RF2413:
+ case AR5K_RF2316:
+ case AR5K_RF2317:
+ case AR5K_RF2425:
+ if(ah->ah_bwmode_debug != tobwmode) {
+ mutex_lock(&ah->lock);
+ ah->ah_bwmode = tobwmode;
+ ah->ah_bwmode_debug = tobwmode;
+ mutex_unlock(&ah->lock);
+ }
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+ return count;
+}
+
+static const struct file_operations fops_bwmode = {
+ .read = read_file_bwmode,
+ .write = write_file_bwmode,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
/* debugfs: queues etc */
@@ -995,6 +1086,8 @@ ath5k_debug_init_device(struct ath5k_hw *ah)
debugfs_create_file("queue", 0600, phydir, ah, &fops_queue);
debugfs_create_bool("32khz_clock", 0600, phydir,
&ah->ah_use_32khz_clock);
+ debugfs_create_file("bwmode", S_IWUSR | S_IRUSR, phydir, ah,
+ &fops_bwmode);
}
/* functions used in other places */
diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c
index d9e376e..db06ff8 100644
--- a/drivers/net/wireless/ath/ath5k/dma.c
+++ b/drivers/net/wireless/ath/ath5k/dma.c
@@ -854,10 +854,18 @@ ath5k_hw_dma_init(struct ath5k_hw *ah)
* guess we can tweak it and see how it goes ;-)
*/
if (ah->ah_version != AR5K_AR5210) {
+#if !defined(CONFIG_ATHEROS_AR71XX) && !defined(CONFIG_ATH79)
AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
+#else
+ /* WAR for AR71xx PCI bug */
+ AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
+ AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
+ AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
+ AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_4B);
+#endif
}
/* Pre-enable interrupts on 5211/5212*/
diff --git a/drivers/net/wireless/ath/ath5k/initvals.c b/drivers/net/wireless/ath/ath5k/initvals.c
index ee1c2fa..122fe1c 100644
--- a/drivers/net/wireless/ath/ath5k/initvals.c
+++ b/drivers/net/wireless/ath/ath5k/initvals.c
@@ -62,8 +62,14 @@ static const struct ath5k_ini ar5210_ini[] = {
{ AR5K_IMR, 0 },
{ AR5K_IER, AR5K_IER_DISABLE },
{ AR5K_BSR, 0, AR5K_INI_READ },
+#if !defined(CONFIG_ATHEROS_AR71XX) && !defined(CONFIG_ATH79)
{ AR5K_TXCFG, AR5K_DMASIZE_128B },
{ AR5K_RXCFG, AR5K_DMASIZE_128B },
+#else
+ /* WAR for AR71xx PCI bug */
+ { AR5K_TXCFG, AR5K_DMASIZE_128B },
+ { AR5K_RXCFG, AR5K_DMASIZE_4B },
+#endif
{ AR5K_CFG, AR5K_INIT_CFG },
{ AR5K_TOPS, 8 },
{ AR5K_RXNOFRM, 8 },
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index da9dc62..2fb37d3 100644
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -86,13 +86,8 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
goto end;
}
- /* Don't allow other interfaces if one ad-hoc is configured.
- * TODO: Fix the problems with ad-hoc and multiple other interfaces.
- * We would need to operate the HW in ad-hoc mode to allow TSF updates
- * for the IBSS, but this breaks with additional AP or STA interfaces
- * at the moment. */
- if (ah->num_adhoc_vifs ||
- (ah->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
+ /* Don't allow more than one ad-hoc interface */
+ if (ah->num_adhoc_vifs && vif->type == NL80211_IFTYPE_ADHOC) {
ATH5K_ERR(ah, "Only one single ad-hoc interface is allowed.\n");
ret = -ELNRNG;
goto end;
diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c
index c4315dd..2aae4de 100644
--- a/drivers/net/wireless/ath/ath5k/pci.c
+++ b/drivers/net/wireless/ath/ath5k/pci.c
@@ -47,6 +47,8 @@ static const struct pci_device_id ath5k_pci_id_table[] = {
{ PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */
{ PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */
{ PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */
+ { PCI_VDEVICE(ATHEROS, 0xff16) }, /* 2413,2414 sx76x on lantiq_danube */
+ { PCI_VDEVICE(ATHEROS, 0xff1a) }, /* 2417 arv45xx on lantiq_danube */
{ PCI_VDEVICE(ATHEROS, 0xff1b) }, /* AR5BXB63 */
{ 0 }
};
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 9fdb528..eabf225 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -1154,6 +1154,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
tsf_lo = 0;
mode = 0;
+#if 0
/*
* Sanity check for fast flag
* Fast channel change only available
@@ -1161,6 +1162,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
*/
if (fast && (ah->ah_radio != AR5K_RF2413) &&
(ah->ah_radio != AR5K_RF5413))
+#endif
fast = false;
/* Disable sleep clock operation
diff --git a/include/linux/ath5k_platform.h b/include/linux/ath5k_platform.h
new file mode 100644
index 0000000..ec85224
--- /dev/null
+++ b/include/linux/ath5k_platform.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (c) 2010 Daniel Golle <daniel.golle@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _LINUX_ATH5K_PLATFORM_H
+#define _LINUX_ATH5K_PLATFORM_H
+
+#define ATH5K_PLAT_EEP_MAX_WORDS 2048
+
+struct ath5k_platform_data {
+ u16 *eeprom_data;
+ u8 *macaddr;
+};
+
+#endif /* _LINUX_ATH5K_PLATFORM_H */
--
2.39.2