diff --git a/package/mac80211/patches/520-ath9k_debugfs_chainmask.patch b/package/mac80211/patches/520-ath9k_debugfs_chainmask.patch new file mode 100644 index 00000000000..d8ca8dfbfb9 --- /dev/null +++ b/package/mac80211/patches/520-ath9k_debugfs_chainmask.patch @@ -0,0 +1,130 @@ +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -71,6 +71,90 @@ static const struct file_operations fops + .owner = THIS_MODULE + }; + ++static ssize_t read_file_tx_chainmask(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ struct ath_common *common = ath9k_hw_common(sc->sc_ah); ++ char buf[32]; ++ unsigned int len; ++ ++ len = snprintf(buf, sizeof(buf), "0x%08x\n", common->tx_chainmask); ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static ssize_t write_file_tx_chainmask(struct file *file, const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ struct ath_common *common = ath9k_hw_common(sc->sc_ah); ++ unsigned long mask; ++ 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, &mask)) ++ return -EINVAL; ++ ++ common->tx_chainmask = mask; ++ sc->sc_ah->caps.tx_chainmask = mask; ++ return count; ++} ++ ++static const struct file_operations fops_tx_chainmask = { ++ .read = read_file_tx_chainmask, ++ .write = write_file_tx_chainmask, ++ .open = ath9k_debugfs_open, ++ .owner = THIS_MODULE ++}; ++ ++ ++static ssize_t read_file_rx_chainmask(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ struct ath_common *common = ath9k_hw_common(sc->sc_ah); ++ char buf[32]; ++ unsigned int len; ++ ++ len = snprintf(buf, sizeof(buf), "0x%08x\n", common->rx_chainmask); ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static ssize_t write_file_rx_chainmask(struct file *file, const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ struct ath_common *common = ath9k_hw_common(sc->sc_ah); ++ unsigned long mask; ++ 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, &mask)) ++ return -EINVAL; ++ ++ common->rx_chainmask = mask; ++ sc->sc_ah->caps.rx_chainmask = mask; ++ return count; ++} ++ ++static const struct file_operations fops_rx_chainmask = { ++ .read = read_file_rx_chainmask, ++ .write = write_file_rx_chainmask, ++ .open = ath9k_debugfs_open, ++ .owner = THIS_MODULE ++}; ++ ++ + static ssize_t read_file_dma(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) + { +@@ -568,6 +652,16 @@ int ath9k_init_debug(struct ath_hw *ah) + if (!sc->debug.debugfs_debug) + goto err; + ++ sc->debug.debugfs_rx_chainmask = debugfs_create_file("rx_chainmask", ++ S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_rx_chainmask); ++ if (!sc->debug.debugfs_rx_chainmask) ++ goto err; ++ ++ sc->debug.debugfs_tx_chainmask = debugfs_create_file("tx_chainmask", ++ S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_tx_chainmask); ++ if (!sc->debug.debugfs_tx_chainmask) ++ goto err; ++ + sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUSR, + sc->debug.debugfs_phy, sc, &fops_dma); + if (!sc->debug.debugfs_dma) +@@ -611,6 +705,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_tx_chainmask); ++ debugfs_remove(sc->debug.debugfs_rx_chainmask); + debugfs_remove(sc->debug.debugfs_xmit); + debugfs_remove(sc->debug.debugfs_wiphy); + debugfs_remove(sc->debug.debugfs_rcstat); +--- a/drivers/net/wireless/ath/ath9k/debug.h ++++ b/drivers/net/wireless/ath/ath9k/debug.h +@@ -123,6 +123,8 @@ struct ath_stats { + }; + + struct ath9k_debug { ++ struct dentry *debugfs_rx_chainmask; ++ struct dentry *debugfs_tx_chainmask; + struct dentry *debugfs_phy; + struct dentry *debugfs_debug; + struct dentry *debugfs_dma; diff --git a/package/mac80211/patches/530-ath9k_debugfs_regaccess.patch b/package/mac80211/patches/530-ath9k_debugfs_regaccess.patch new file mode 100644 index 00000000000..b973dbb2aa7 --- /dev/null +++ b/package/mac80211/patches/530-ath9k_debugfs_regaccess.patch @@ -0,0 +1,128 @@ +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -634,6 +634,86 @@ static const struct file_operations fops + .owner = THIS_MODULE + }; + ++static ssize_t read_file_regidx(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; ++ ++ len = snprintf(buf, sizeof(buf), "0x%08x\n", sc->debug.regidx); ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static ssize_t write_file_regidx(struct file *file, const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ unsigned long regidx; ++ 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, ®idx)) ++ return -EINVAL; ++ ++ sc->debug.regidx = regidx; ++ return count; ++} ++ ++static const struct file_operations fops_regidx = { ++ .read = read_file_regidx, ++ .write = write_file_regidx, ++ .open = ath9k_debugfs_open, ++ .owner = THIS_MODULE ++}; ++ ++static ssize_t read_file_regval(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; ++ u32 regval; ++ ++ regval = REG_READ_D(ah, sc->debug.regidx); ++ len = snprintf(buf, sizeof(buf), "0x%08x\n", regval); ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static ssize_t write_file_regval(struct file *file, const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ struct ath_hw *ah = sc->sc_ah; ++ unsigned long regval; ++ 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; ++ ++ REG_WRITE_D(ah, sc->debug.regidx, regval); ++ return count; ++} ++ ++static const struct file_operations fops_regval = { ++ .read = read_file_regval, ++ .write = write_file_regval, ++ .open = ath9k_debugfs_open, ++ .owner = THIS_MODULE ++}; ++ + int ath9k_init_debug(struct ath_hw *ah) + { + struct ath_common *common = ath9k_hw_common(ah); +@@ -694,6 +774,17 @@ int ath9k_init_debug(struct ath_hw *ah) + if (!sc->debug.debugfs_xmit) + goto err; + ++ sc->debug.regidx = 0; ++ sc->debug.debugfs_regidx = debugfs_create_file("regidx", ++ S_IRUSR|S_IWUSR, sc->debug.debugfs_phy, sc, &fops_regidx); ++ if (!sc->debug.debugfs_regidx) ++ goto err; ++ ++ sc->debug.debugfs_regval = debugfs_create_file("regval", ++ S_IRUSR|S_IWUSR, sc->debug.debugfs_phy, sc, &fops_regval); ++ if (!sc->debug.debugfs_regval) ++ goto err; ++ + return 0; + err: + ath9k_exit_debug(ah); +@@ -707,6 +798,8 @@ void ath9k_exit_debug(struct ath_hw *ah) + + debugfs_remove(sc->debug.debugfs_tx_chainmask); + debugfs_remove(sc->debug.debugfs_rx_chainmask); ++ debugfs_remove(sc->debug.debugfs_regval); ++ debugfs_remove(sc->debug.debugfs_regidx); + debugfs_remove(sc->debug.debugfs_xmit); + debugfs_remove(sc->debug.debugfs_wiphy); + debugfs_remove(sc->debug.debugfs_rcstat); +--- a/drivers/net/wireless/ath/ath9k/debug.h ++++ b/drivers/net/wireless/ath/ath9k/debug.h +@@ -132,6 +132,9 @@ struct ath9k_debug { + struct dentry *debugfs_rcstat; + struct dentry *debugfs_wiphy; + struct dentry *debugfs_xmit; ++ struct dentry *debugfs_regidx; ++ struct dentry *debugfs_regval; ++ u32 regidx; + struct ath_stats stats; + }; +