mirror of
https://github.com/pentoo/pentoo-overlay
synced 2026-01-19 06:32:15 +01:00
453 lines
13 KiB
Diff
453 lines
13 KiB
Diff
From: Benoit Papillault <benoit.papillault@free.fr>
|
|
Date: Thu, 8 Apr 2010 21:53:39 +0000 (+0200)
|
|
Subject: ath5k & ath9k: Add the ability to disable physical & virtual carrier sense.
|
|
X-Git-Url: http://git.popipo.fr/?p=rt2x00.git;a=commitdiff_plain;h=6e617aef04e78aa09fdaf029ff2095bda8509606
|
|
|
|
ath5k & ath9k: Add the ability to disable physical & virtual carrier sense.
|
|
|
|
This patch adds 2 debugfs file in ath5k and ath9k debugfs directory, called :
|
|
- physical_carrier_sense : when set to 1, physical carrier sense is disabled.
|
|
- virtual_carrier_sense : when set to 1, virtual carrier sense is disabled
|
|
|
|
Carrier sense settings are restored after a hardware reset.
|
|
---
|
|
|
|
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
|
|
index ac67f02..1f90dde 100644
|
|
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
|
|
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
|
|
@@ -1135,6 +1135,10 @@ struct ath5k_hw {
|
|
/* Software interrupt mask */
|
|
u8 ah_swi_mask;
|
|
|
|
+ /* Saved values of physical & virtual carrier sense */
|
|
+ int saved_phy_cs;
|
|
+ int saved_virt_cs;
|
|
+
|
|
/*
|
|
* Function pointers
|
|
*/
|
|
@@ -1310,6 +1314,11 @@ extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
|
|
/* TX power setup */
|
|
extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower);
|
|
extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
|
|
+/* physical & virtual carrier sense get/set methods */
|
|
+int ath5k_hw_get_phy_cs(struct ath5k_hw *ah);
|
|
+void ath5k_hw_set_phy_cs(struct ath5k_hw *ah, int val);
|
|
+int ath5k_hw_get_virt_cs(struct ath5k_hw *ah);
|
|
+void ath5k_hw_set_virt_cs(struct ath5k_hw *ah, int val);
|
|
|
|
/*
|
|
* Functions used internaly
|
|
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
|
|
index 747508c..246c62d 100644
|
|
--- a/drivers/net/wireless/ath/ath5k/debug.c
|
|
+++ b/drivers/net/wireless/ath/ath5k/debug.c
|
|
@@ -363,6 +363,90 @@ static const struct file_operations fops_debug = {
|
|
.owner = THIS_MODULE,
|
|
};
|
|
|
|
+static ssize_t read_file_phy_cs(struct file *file, char __user *user_buf,
|
|
+ size_t count, loff_t *ppos)
|
|
+{
|
|
+ struct ath5k_softc *sc = file->private_data;
|
|
+ struct ath5k_hw *ah = sc->ah;
|
|
+ char buf[32];
|
|
+ unsigned int len;
|
|
+ int val;
|
|
+
|
|
+ val = ath5k_hw_get_phy_cs(ah);
|
|
+ len = snprintf(buf, sizeof(buf), "%d\n", val);
|
|
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
|
+}
|
|
+
|
|
+static ssize_t write_file_phy_cs(struct file *file, const char __user *user_buf,
|
|
+ size_t count, loff_t *ppos)
|
|
+{
|
|
+ struct ath5k_softc *sc = file->private_data;
|
|
+ struct ath5k_hw *ah = sc->ah;
|
|
+ unsigned long val;
|
|
+ char buf[32];
|
|
+ ssize_t len;
|
|
+
|
|
+ len = min(count, sizeof(buf) - 1);
|
|
+ if (copy_from_user(buf, user_buf, len))
|
|
+ return -EINVAL;
|
|
+
|
|
+ buf[len] = '\0';
|
|
+ if (strict_strtoul(buf, 0, &val))
|
|
+ return -EINVAL;
|
|
+
|
|
+ ath5k_hw_set_phy_cs(ah, val);
|
|
+ return count;
|
|
+}
|
|
+
|
|
+static const struct file_operations fops_phy_cs = {
|
|
+ .read = read_file_phy_cs,
|
|
+ .write = write_file_phy_cs,
|
|
+ .open = ath5k_debugfs_open,
|
|
+ .owner = THIS_MODULE
|
|
+};
|
|
+
|
|
+static ssize_t read_file_virt_cs(struct file *file, char __user *user_buf,
|
|
+ size_t count, loff_t *ppos)
|
|
+{
|
|
+ struct ath5k_softc *sc = file->private_data;
|
|
+ struct ath5k_hw *ah = sc->ah;
|
|
+ char buf[32];
|
|
+ unsigned int len;
|
|
+ int val;
|
|
+
|
|
+ val = ath5k_hw_get_virt_cs(ah);
|
|
+ len = snprintf(buf, sizeof(buf), "%d\n",val);
|
|
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
|
+}
|
|
+
|
|
+static ssize_t write_file_virt_cs(struct file *file, const char __user *user_buf,
|
|
+ size_t count, loff_t *ppos)
|
|
+{
|
|
+ struct ath5k_softc *sc = file->private_data;
|
|
+ struct ath5k_hw *ah = sc->ah;
|
|
+ unsigned long val;
|
|
+ char buf[32];
|
|
+ ssize_t len;
|
|
+
|
|
+ len = min(count, sizeof(buf) - 1);
|
|
+ if (copy_from_user(buf, user_buf, len))
|
|
+ return -EINVAL;
|
|
+
|
|
+ buf[len] = '\0';
|
|
+ if (strict_strtoul(buf, 0, &val))
|
|
+ return -EINVAL;
|
|
+
|
|
+ ath5k_hw_set_virt_cs(ah, val);
|
|
+
|
|
+ return count;
|
|
+}
|
|
+
|
|
+static const struct file_operations fops_virt_cs = {
|
|
+ .read = read_file_virt_cs,
|
|
+ .write = write_file_virt_cs,
|
|
+ .open = ath5k_debugfs_open,
|
|
+ .owner = THIS_MODULE
|
|
+};
|
|
|
|
/* init */
|
|
|
|
@@ -393,6 +477,14 @@ ath5k_debug_init_device(struct ath5k_softc *sc)
|
|
|
|
sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR,
|
|
sc->debug.debugfs_phydir, sc, &fops_reset);
|
|
+
|
|
+ sc->debug.debugfs_phy_cs = debugfs_create_file("physical_carrier_sense",
|
|
+ S_IRUSR|S_IWUSR,
|
|
+ sc->debug.debugfs_phydir, sc, &fops_phy_cs);
|
|
+
|
|
+ sc->debug.debugfs_virt_cs = debugfs_create_file("virtual_carrier_sense",
|
|
+ S_IRUSR|S_IWUSR,
|
|
+ sc->debug.debugfs_phydir, sc, &fops_virt_cs);
|
|
}
|
|
|
|
void
|
|
@@ -404,6 +496,8 @@ ath5k_debug_finish(void)
|
|
void
|
|
ath5k_debug_finish_device(struct ath5k_softc *sc)
|
|
{
|
|
+ debugfs_remove(sc->debug.debugfs_virt_cs);
|
|
+ debugfs_remove(sc->debug.debugfs_phy_cs);
|
|
debugfs_remove(sc->debug.debugfs_debug);
|
|
debugfs_remove(sc->debug.debugfs_registers);
|
|
debugfs_remove(sc->debug.debugfs_beacon);
|
|
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h
|
|
index 66f69f0..070226c 100644
|
|
--- a/drivers/net/wireless/ath/ath5k/debug.h
|
|
+++ b/drivers/net/wireless/ath/ath5k/debug.h
|
|
@@ -74,6 +74,8 @@ struct ath5k_dbg_info {
|
|
struct dentry *debugfs_registers;
|
|
struct dentry *debugfs_beacon;
|
|
struct dentry *debugfs_reset;
|
|
+ struct dentry *debugfs_phy_cs;
|
|
+ struct dentry *debugfs_virt_cs;
|
|
};
|
|
|
|
/**
|
|
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
|
|
index eff3323..4604e8f 100644
|
|
--- a/drivers/net/wireless/ath/ath5k/phy.c
|
|
+++ b/drivers/net/wireless/ath/ath5k/phy.c
|
|
@@ -3145,3 +3145,41 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
|
|
}
|
|
|
|
#undef _ATH5K_PHY
|
|
+int ath5k_hw_get_phy_cs(struct ath5k_hw *ah)
|
|
+{
|
|
+ u32 regval;
|
|
+
|
|
+ regval = ath5k_hw_reg_read(ah, AR5K_DIAG_SW);
|
|
+ return !!(regval & AR5K_DIAG_SW_RX_CLEAR_HIGH);
|
|
+}
|
|
+
|
|
+void ath5k_hw_set_phy_cs(struct ath5k_hw *ah, int val)
|
|
+{
|
|
+ if (val)
|
|
+ AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW,
|
|
+ AR5K_DIAG_SW_RX_CLEAR_HIGH);
|
|
+ else
|
|
+ AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW,
|
|
+ AR5K_DIAG_SW_RX_CLEAR_HIGH);
|
|
+ ah->saved_phy_cs = val;
|
|
+}
|
|
+
|
|
+int ath5k_hw_get_virt_cs(struct ath5k_hw *ah)
|
|
+{
|
|
+ u32 regval;
|
|
+
|
|
+ regval = ath5k_hw_reg_read(ah, AR5K_DIAG_SW);
|
|
+ return !!(regval & AR5K_DIAG_SW_IGNORE_CARR_SENSE);
|
|
+}
|
|
+
|
|
+void ath5k_hw_set_virt_cs(struct ath5k_hw *ah, int val)
|
|
+{
|
|
+ if (val)
|
|
+ AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW,
|
|
+ AR5K_DIAG_SW_IGNORE_CARR_SENSE);
|
|
+ else
|
|
+ AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW,
|
|
+ AR5K_DIAG_SW_IGNORE_CARR_SENSE);
|
|
+ ah->saved_virt_cs = val;
|
|
+}
|
|
+
|
|
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
|
|
index cbf28e3..7d337f3 100644
|
|
--- a/drivers/net/wireless/ath/ath5k/reset.c
|
|
+++ b/drivers/net/wireless/ath/ath5k/reset.c
|
|
@@ -1386,6 +1386,9 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
|
|
*/
|
|
AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
|
|
ath5k_hw_reset_tsf(ah);
|
|
+
|
|
+ ath5k_hw_set_phy_cs(ah, ah->saved_phy_cs);
|
|
+ ath5k_hw_set_virt_cs(ah, ah->saved_virt_cs);
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
|
|
index 42d2a50..a65d9fc 100644
|
|
--- a/drivers/net/wireless/ath/ath9k/debug.c
|
|
+++ b/drivers/net/wireless/ath/ath9k/debug.c
|
|
@@ -699,6 +699,75 @@ static const struct file_operations fops_recv = {
|
|
.owner = THIS_MODULE
|
|
};
|
|
|
|
+static ssize_t write_file_phy_cs(struct file *file, const char __user *user_buf,
|
|
+ size_t count, loff_t *ppos)
|
|
+{
|
|
+ struct ath_softc *sc = file->private_data;
|
|
+ unsigned long val;
|
|
+ char buf[32];
|
|
+ ssize_t len;
|
|
+
|
|
+ len = min(count, sizeof(buf) - 1);
|
|
+ if (copy_from_user(buf, user_buf, len))
|
|
+ return -EINVAL;
|
|
+
|
|
+ buf[len] = '\0';
|
|
+ if (strict_strtoul(buf, 0, &val))
|
|
+ return -EINVAL;
|
|
+
|
|
+ ath9k_hw_set_phy_cs(sc->sc_ah, val);
|
|
+
|
|
+ return count;
|
|
+}
|
|
+
|
|
+static const struct file_operations fops_phy_cs = {
|
|
+ .read = read_file_phy_cs,
|
|
+ .write = write_file_phy_cs,
|
|
+ .open = ath9k_debugfs_open,
|
|
+ .owner = THIS_MODULE
|
|
+};
|
|
+
|
|
+static ssize_t read_file_virt_cs(struct file *file, char __user *user_buf,
|
|
+ size_t count, loff_t *ppos)
|
|
+{
|
|
+ struct ath_softc *sc = file->private_data;
|
|
+ char buf[32];
|
|
+ unsigned int len;
|
|
+ int val;
|
|
+
|
|
+ val = ath9k_hw_get_virt_cs(sc->sc_ah);
|
|
+ len = snprintf(buf, sizeof(buf), "%d\n", val);
|
|
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
|
+}
|
|
+
|
|
+static ssize_t write_file_virt_cs(struct file *file, const char __user *user_buf,
|
|
+ size_t count, loff_t *ppos)
|
|
+{
|
|
+ struct ath_softc *sc = file->private_data;
|
|
+ unsigned long val;
|
|
+ char buf[32];
|
|
+ ssize_t len;
|
|
+
|
|
+ len = min(count, sizeof(buf) - 1);
|
|
+ if (copy_from_user(buf, user_buf, len))
|
|
+ return -EINVAL;
|
|
+
|
|
+ buf[len] = '\0';
|
|
+ if (strict_strtoul(buf, 0, &val))
|
|
+ return -EINVAL;
|
|
+
|
|
+ ath9k_hw_set_virt_cs(sc->sc_ah, val);
|
|
+
|
|
+ return count;
|
|
+}
|
|
+
|
|
+static const struct file_operations fops_virt_cs = {
|
|
+ .read = read_file_virt_cs,
|
|
+ .write = write_file_virt_cs,
|
|
+ .open = ath9k_debugfs_open,
|
|
+ .owner = THIS_MODULE
|
|
+};
|
|
+
|
|
int ath9k_init_debug(struct ath_hw *ah)
|
|
{
|
|
struct ath_common *common = ath9k_hw_common(ah);
|
|
@@ -758,6 +827,20 @@ int ath9k_init_debug(struct ath_hw *ah)
|
|
if (!sc->debug.debugfs_recv)
|
|
goto err;
|
|
|
|
+ sc->debug.debugfs_phy_cs = debugfs_create_file("physical_carrier_sense",
|
|
+ S_IRUSR|S_IWUSR,
|
|
+ sc->debug.debugfs_phy,
|
|
+ sc, &fops_phy_cs);
|
|
+ if (!sc->debug.debugfs_phy_cs)
|
|
+ goto err;
|
|
+
|
|
+ sc->debug.debugfs_virt_cs = debugfs_create_file("virtual_carrier_sense",
|
|
+ S_IRUSR|S_IWUSR,
|
|
+ sc->debug.debugfs_phy,
|
|
+ sc, &fops_virt_cs);
|
|
+ if (!sc->debug.debugfs_virt_cs)
|
|
+ goto err;
|
|
+
|
|
return 0;
|
|
err:
|
|
ath9k_exit_debug(ah);
|
|
@@ -769,6 +852,8 @@ void ath9k_exit_debug(struct ath_hw *ah)
|
|
struct ath_common *common = ath9k_hw_common(ah);
|
|
struct ath_softc *sc = (struct ath_softc *) common->priv;
|
|
|
|
+ debugfs_remove(sc->debug.debugfs_virt_cs);
|
|
+ debugfs_remove(sc->debug.debugfs_phy_cs);
|
|
debugfs_remove(sc->debug.debugfs_recv);
|
|
debugfs_remove(sc->debug.debugfs_xmit);
|
|
debugfs_remove(sc->debug.debugfs_wiphy);
|
|
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
|
|
index 86780e6..d86bbe5 100644
|
|
--- a/drivers/net/wireless/ath/ath9k/debug.h
|
|
+++ b/drivers/net/wireless/ath/ath9k/debug.h
|
|
@@ -156,6 +156,8 @@ struct ath9k_debug {
|
|
struct dentry *debugfs_wiphy;
|
|
struct dentry *debugfs_xmit;
|
|
struct dentry *debugfs_recv;
|
|
+ struct dentry *debugfs_phy_cs;
|
|
+ struct dentry *debugfs_virt_cs;
|
|
struct ath_stats stats;
|
|
};
|
|
|
|
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
|
|
index 2e767cf..aef52aa 100644
|
|
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
|
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
|
@@ -954,6 +954,10 @@ int ath9k_hw_init(struct ath_hw *ah)
|
|
|
|
common->state = ATH_HW_INITIALIZED;
|
|
|
|
+ /* Initially, physical and virtual carrier sense are enabled */
|
|
+ ah->saved_phy_cs = 0;
|
|
+ ah->saved_virt_cs = 0;
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -1913,6 +1917,44 @@ static void ath9k_enable_rfkill(struct ath_hw *ah)
|
|
REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
|
|
}
|
|
|
|
+int ath9k_hw_get_phy_cs(struct ath_hw *ah)
|
|
+{
|
|
+ u32 regval;
|
|
+
|
|
+ regval = REG_READ(ah, AR_DIAG_SW);
|
|
+ return !!(regval & AR_DIAG_FORCE_RX_CLEAR);
|
|
+}
|
|
+EXPORT_SYMBOL(ath9k_hw_get_phy_cs);
|
|
+
|
|
+void ath9k_hw_set_phy_cs(struct ath_hw *ah, int val)
|
|
+{
|
|
+ if (val)
|
|
+ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_RX_CLEAR);
|
|
+ else
|
|
+ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_RX_CLEAR);
|
|
+ ah->saved_phy_cs = val;
|
|
+}
|
|
+EXPORT_SYMBOL(ath9k_hw_set_phy_cs);
|
|
+
|
|
+int ath9k_hw_get_virt_cs(struct ath_hw *ah)
|
|
+{
|
|
+ u32 regval;
|
|
+
|
|
+ regval = REG_READ(ah, AR_DIAG_SW);
|
|
+ return !!(regval & AR_DIAG_IGNORE_VIRT_CS);
|
|
+}
|
|
+EXPORT_SYMBOL(ath9k_hw_get_virt_cs);
|
|
+
|
|
+void ath9k_hw_set_virt_cs(struct ath_hw *ah, int val)
|
|
+{
|
|
+ if (val)
|
|
+ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_IGNORE_VIRT_CS);
|
|
+ else
|
|
+ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_IGNORE_VIRT_CS);
|
|
+ ah->saved_virt_cs = val;
|
|
+}
|
|
+EXPORT_SYMBOL(ath9k_hw_set_virt_cs);
|
|
+
|
|
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
|
bool bChannelChange)
|
|
{
|
|
@@ -2142,6 +2184,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
|
if (ah->btcoex_hw.enabled)
|
|
ath9k_hw_btcoex_enable(ah);
|
|
|
|
+ ath9k_hw_set_phy_cs(ah, ah->saved_phy_cs);
|
|
+ ath9k_hw_set_virt_cs(ah, ah->saved_virt_cs);
|
|
+
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(ath9k_hw_reset);
|
|
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
|
|
index dbbf7ca..2c1dac4 100644
|
|
--- a/drivers/net/wireless/ath/ath9k/hw.h
|
|
+++ b/drivers/net/wireless/ath/ath9k/hw.h
|
|
@@ -602,6 +602,10 @@ struct ath_hw {
|
|
u32 intr_gen_timer_trigger;
|
|
u32 intr_gen_timer_thresh;
|
|
struct ath_gen_timer_table hw_gen_timers;
|
|
+
|
|
+ /* Saved values of physical & virtual carrier sense */
|
|
+ int saved_phy_cs;
|
|
+ int saved_virt_cs;
|
|
};
|
|
|
|
static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
|
|
@@ -618,6 +622,10 @@ static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah)
|
|
const char *ath9k_hw_probe(u16 vendorid, u16 devid);
|
|
void ath9k_hw_deinit(struct ath_hw *ah);
|
|
int ath9k_hw_init(struct ath_hw *ah);
|
|
+int ath9k_hw_get_phy_cs(struct ath_hw *ah);
|
|
+void ath9k_hw_set_phy_cs(struct ath_hw *ah, int val);
|
|
+int ath9k_hw_get_virt_cs(struct ath_hw *ah);
|
|
+void ath9k_hw_set_virt_cs(struct ath_hw *ah, int val);
|
|
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
|
bool bChannelChange);
|
|
int ath9k_hw_fill_cap_info(struct ath_hw *ah);
|
|
|