diff options
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/ahb.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/ath5k.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.c | 52 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.h | 13 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/mac80211-ops.c | 19 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ahb.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_phy.c | 37 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.c | 62 |
8 files changed, 133 insertions, 56 deletions
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index ae84b86c3bf2..82324e98efef 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -93,7 +93,7 @@ static int ath_ahb_probe(struct platform_device *pdev) goto err_out; } - mem = ioremap_nocache(res->start, res->end - res->start + 1); + mem = ioremap_nocache(res->start, resource_size(res)); if (mem == NULL) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 0ee54eb333de..8a06dbd39629 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -513,7 +513,7 @@ enum ath5k_tx_queue_id { AR5K_TX_QUEUE_ID_NOQCU_DATA = 0, AR5K_TX_QUEUE_ID_NOQCU_BEACON = 1, AR5K_TX_QUEUE_ID_DATA_MIN = 0, /*IEEE80211_TX_QUEUE_DATA0*/ - AR5K_TX_QUEUE_ID_DATA_MAX = 4, /*IEEE80211_TX_QUEUE_DATA4*/ + AR5K_TX_QUEUE_ID_DATA_MAX = 3, /*IEEE80211_TX_QUEUE_DATA3*/ AR5K_TX_QUEUE_ID_DATA_SVP = 5, /*IEEE80211_TX_QUEUE_SVP - Spectralink Voice Protocol*/ AR5K_TX_QUEUE_ID_CAB = 6, /*IEEE80211_TX_QUEUE_AFTER_BEACON*/ AR5K_TX_QUEUE_ID_BEACON = 7, /*IEEE80211_TX_QUEUE_BEACON*/ diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 91411e9b4b68..e6ff62e60a79 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -442,19 +442,9 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) return ath5k_reset(sc, chan, true); } -struct ath_vif_iter_data { - const u8 *hw_macaddr; - u8 mask[ETH_ALEN]; - u8 active_mac[ETH_ALEN]; /* first active MAC */ - bool need_set_hw_addr; - bool found_active; - bool any_assoc; - enum nl80211_iftype opmode; -}; - -static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) +void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { - struct ath_vif_iter_data *iter_data = data; + struct ath5k_vif_iter_data *iter_data = data; int i; struct ath5k_vif *avf = (void *)vif->drv_priv; @@ -484,9 +474,12 @@ static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) */ if (avf->opmode == NL80211_IFTYPE_AP) iter_data->opmode = NL80211_IFTYPE_AP; - else + else { + if (avf->opmode == NL80211_IFTYPE_STATION) + iter_data->n_stas++; if (iter_data->opmode == NL80211_IFTYPE_UNSPECIFIED) iter_data->opmode = avf->opmode; + } } void @@ -494,7 +487,8 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, struct ieee80211_vif *vif) { struct ath_common *common = ath5k_hw_common(sc->ah); - struct ath_vif_iter_data iter_data; + struct ath5k_vif_iter_data iter_data; + u32 rfilt; /* * Use the hardware MAC address as reference, the hardware uses it @@ -505,12 +499,13 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, iter_data.found_active = false; iter_data.need_set_hw_addr = true; iter_data.opmode = NL80211_IFTYPE_UNSPECIFIED; + iter_data.n_stas = 0; if (vif) - ath_vif_iter(&iter_data, vif->addr, vif); + ath5k_vif_iter(&iter_data, vif->addr, vif); /* Get list of all active MAC addresses */ - ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter, + ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter, &iter_data); memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN); @@ -528,20 +523,19 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, if (ath5k_hw_hasbssidmask(sc->ah)) ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); -} -void -ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif) -{ - struct ath5k_hw *ah = sc->ah; - u32 rfilt; + /* Set up RX Filter */ + if (iter_data.n_stas > 1) { + /* If you have multiple STA interfaces connected to + * different APs, ARPs are not received (most of the time?) + * Enabling PROMISC appears to fix that probem. + */ + sc->filter_flags |= AR5K_RX_FILTER_PROM; + } - /* configure rx filter */ rfilt = sc->filter_flags; - ath5k_hw_set_rx_filter(ah, rfilt); + ath5k_hw_set_rx_filter(sc->ah, rfilt); ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); - - ath5k_update_bssid_mask_and_opmode(sc, vif); } static inline int @@ -1117,7 +1111,7 @@ ath5k_rx_start(struct ath5k_softc *sc) spin_unlock_bh(&sc->rxbuflock); ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ - ath5k_mode_setup(sc, NULL); /* set filters, etc. */ + ath5k_update_bssid_mask_and_opmode(sc, NULL); /* set filters, etc. */ ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ return 0; @@ -2923,13 +2917,13 @@ ath5k_deinit_softc(struct ath5k_softc *sc) bool ath_any_vif_assoc(struct ath5k_softc *sc) { - struct ath_vif_iter_data iter_data; + struct ath5k_vif_iter_data iter_data; iter_data.hw_macaddr = NULL; iter_data.any_assoc = false; iter_data.need_set_hw_addr = false; iter_data.found_active = true; - ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter, + ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter, &iter_data); return iter_data.any_assoc; } diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 8f919dca95f1..8d1df1fa2351 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -259,6 +259,19 @@ struct ath5k_softc { struct survey_info survey; /* collected survey info */ }; +struct ath5k_vif_iter_data { + const u8 *hw_macaddr; + u8 mask[ETH_ALEN]; + u8 active_mac[ETH_ALEN]; /* first active MAC */ + bool need_set_hw_addr; + bool found_active; + bool any_assoc; + enum nl80211_iftype opmode; + int n_stas; +}; +void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif); + + #define ath5k_hw_hasbssidmask(_ah) \ (ath5k_hw_get_capability(_ah, AR5K_CAP_BSSIDMASK, 0, NULL) == 0) #define ath5k_hw_hasveol(_ah) \ diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 1fbe3c0b9f08..c9b0b676adda 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -158,8 +158,7 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) memcpy(&avf->lladdr, vif->addr, ETH_ALEN); - ath5k_mode_setup(sc, vif); - + ath5k_update_bssid_mask_and_opmode(sc, vif); ret = 0; end: mutex_unlock(&sc->lock); @@ -381,6 +380,7 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, struct ath5k_softc *sc = hw->priv; struct ath5k_hw *ah = sc->ah; u32 mfilt[2], rfilt; + struct ath5k_vif_iter_data iter_data; /* to count STA interfaces */ mutex_lock(&sc->lock); @@ -454,6 +454,21 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, break; } + iter_data.hw_macaddr = NULL; + iter_data.n_stas = 0; + iter_data.need_set_hw_addr = false; + ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter, + &iter_data); + + /* Set up RX Filter */ + if (iter_data.n_stas > 1) { + /* If you have multiple STA interfaces connected to + * different APs, ARPs are not received (most of the time?) + * Enabling PROMISC appears to fix that probem. + */ + rfilt |= AR5K_RX_FILTER_PROM; + } + /* Set filters */ ath5k_hw_set_rx_filter(ah, rfilt); diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 993672105963..9cb0efa9b4c0 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c @@ -75,7 +75,7 @@ static int ath_ahb_probe(struct platform_device *pdev) goto err_out; } - mem = ioremap_nocache(res->start, res->end - res->start + 1); + mem = ioremap_nocache(res->start, resource_size(res)); if (mem == NULL) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 8d60f4f09acc..eb250d6b8038 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -1020,28 +1020,29 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, static void ar9003_hw_do_getnf(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]) { - int16_t nf; - - nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR); - nfarray[0] = sign_extend32(nf, 8); - - nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR); - nfarray[1] = sign_extend32(nf, 8); +#define AR_PHY_CH_MINCCA_PWR 0x1FF00000 +#define AR_PHY_CH_MINCCA_PWR_S 20 +#define AR_PHY_CH_EXT_MINCCA_PWR 0x01FF0000 +#define AR_PHY_CH_EXT_MINCCA_PWR_S 16 - nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR); - nfarray[2] = sign_extend32(nf, 8); - - if (!IS_CHAN_HT40(ah->curchan)) - return; + int16_t nf; + int i; - nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); - nfarray[3] = sign_extend32(nf, 8); + for (i = 0; i < AR9300_MAX_CHAINS; i++) { + if (ah->rxchainmask & BIT(i)) { + nf = MS(REG_READ(ah, ah->nf_regs[i]), + AR_PHY_CH_MINCCA_PWR); + nfarray[i] = sign_extend32(nf, 8); - nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR); - nfarray[4] = sign_extend32(nf, 8); + if (IS_CHAN_HT40(ah->curchan)) { + u8 ext_idx = AR9300_MAX_CHAINS + i; - nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR); - nfarray[5] = sign_extend32(nf, 8); + nf = MS(REG_READ(ah, ah->nf_regs[ext_idx]), + AR_PHY_CH_EXT_MINCCA_PWR); + nfarray[ext_idx] = sign_extend32(nf, 8); + } + } + } } static void ar9003_hw_set_nf_limits(struct ath_hw *ah) diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 5cfcf8c235a4..8df5a92a20f1 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -15,6 +15,7 @@ */ #include <linux/slab.h> +#include <linux/vmalloc.h> #include <asm/unaligned.h> #include "ath9k.h" @@ -30,6 +31,19 @@ static int ath9k_debugfs_open(struct inode *inode, struct file *file) return 0; } +static ssize_t ath9k_debugfs_read_buf(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + u8 *buf = file->private_data; + return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); +} + +static int ath9k_debugfs_release_buf(struct inode *inode, struct file *file) +{ + vfree(file->private_data); + return 0; +} + #ifdef CONFIG_ATH_DEBUG static ssize_t read_file_debug(struct file *file, char __user *user_buf, @@ -548,10 +562,10 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, PR("hw-tx-proc-desc: ", txprocdesc); len += snprintf(buf + len, size - len, "%s%11p%11p%10p%10p\n", "txq-memory-address:", - &(sc->tx.txq_map[WME_AC_BE]), - &(sc->tx.txq_map[WME_AC_BK]), - &(sc->tx.txq_map[WME_AC_VI]), - &(sc->tx.txq_map[WME_AC_VO])); + sc->tx.txq_map[WME_AC_BE], + sc->tx.txq_map[WME_AC_BK], + sc->tx.txq_map[WME_AC_VI], + sc->tx.txq_map[WME_AC_VO]); if (len >= size) goto done; @@ -1027,6 +1041,42 @@ static const struct file_operations fops_regval = { .llseek = default_llseek, }; +#define REGDUMP_LINE_SIZE 20 + +static int open_file_regdump(struct inode *inode, struct file *file) +{ + struct ath_softc *sc = inode->i_private; + unsigned int len = 0; + u8 *buf; + int i; + unsigned long num_regs, regdump_len, max_reg_offset; + + max_reg_offset = AR_SREV_9300_20_OR_LATER(sc->sc_ah) ? 0x16bd4 : 0xb500; + num_regs = max_reg_offset / 4 + 1; + regdump_len = num_regs * REGDUMP_LINE_SIZE + 1; + buf = vmalloc(regdump_len); + if (!buf) + return -ENOMEM; + + ath9k_ps_wakeup(sc); + for (i = 0; i < num_regs; i++) + len += scnprintf(buf + len, regdump_len - len, + "0x%06x 0x%08x\n", i << 2, REG_READ(sc->sc_ah, i << 2)); + ath9k_ps_restore(sc); + + file->private_data = buf; + + return 0; +} + +static const struct file_operations fops_regdump = { + .open = open_file_regdump, + .read = ath9k_debugfs_read_buf, + .release = ath9k_debugfs_release_buf, + .owner = THIS_MODULE, + .llseek = default_llseek,/* read accesses f_pos */ +}; + int ath9k_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); @@ -1091,6 +1141,10 @@ int ath9k_init_debug(struct ath_hw *ah) sc->debug.debugfs_phy, &ah->config.cwm_ignore_extcca)) goto err; + if (!debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, + sc, &fops_regdump)) + goto err; + sc->debug.regidx = 0; return 0; err: |