summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/ath9k
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-04-10 15:50:42 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-10 15:50:42 -0400
commite355fbbcaee83326f67bbf349324484bf3588f35 (patch)
tree1d43a5e0129709502edb631a4fd66de369ee5620 /drivers/net/wireless/ath/ath9k
parent953c96e0d85615d1ab1f100e525d376053294dc2 (diff)
parentd3641409a05dcb8e28116bb2ad638f5a42805d9d (diff)
Merge branch 'wireless'
John W. Linville says: ==================== Please accept this pull request for the 3.10 stream... Regarding the mac80211 bits, Johannes says: "Here I have a bunch of minstrel fixes from Felix, per-interface multicast filtering from Alex, set_tim debouncing from Ilan, per-interface debugfs cleanups from Stanislaw, an error return fix from Wei and a number of small improvements and fixes that I made myself." And for the iwlwifi bits, Johannes says: "Andrei changed an instance of kmalloc+memdup to kmemdup, Stanislaw removed the now unused 5ghz_disable module parameter. I also have a number of fixes from Ilan, Emmanuel and myself, Emmanuel also continued working on Bluetooth coexistence." For the sizeable batch of Bluetooth bits, Gustavo says: "This is our first batch of patches for 3.10. The biggest changes of this pull request are from Johan Hedberg, he implemented a HCI request framework to make life easier when we have to send many HCI commands and a block and wait for all of the to finish, we were able to fix a few issues in stack with the introduction of this framework. Other than that Dean Jenkins did a good work cleaning the RFCOMM code, the refcnt infrastructure was removed and now we use NULL pointer checks to know when a object was freed or not. That code was buggy and now it looks a way better. The rest of changes are clean ups, fixes and small improvements all over the Bluetooth subsystem." Regarding the wl12xx bits, Luca says: "Some patches intended for 3.10. Mostly bug fixes and other small improvements." On top of that, there are updates to brcmfmac, brcmsmac, b43, ssb and bcma, as well as mwifiex, rt2x00, and ath9k and a few others. The most notable bit is the addition of a new driver in the rtlwifi family. Please let me know if there are problems! ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_calib.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/dfs.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/dfs_debug.c20
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c36
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c31
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c7
9 files changed, 94 insertions, 21 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index c55e5bbafc46..9f589744a9f9 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -731,7 +731,8 @@ static bool ar9285_hw_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan)
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
ath_dbg(common, CALIBRATE,
- "offset calibration failed to complete in 1ms; noisy environment?\n");
+ "offset calibration failed to complete in %d ms; noisy environment?\n",
+ AH_WAIT_TIMEOUT / 1000);
return false;
}
REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
@@ -745,7 +746,8 @@ static bool ar9285_hw_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan)
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
0, AH_WAIT_TIMEOUT)) {
ath_dbg(common, CALIBRATE,
- "offset calibration failed to complete in 1ms; noisy environment?\n");
+ "offset calibration failed to complete in %d ms; noisy environment?\n",
+ AH_WAIT_TIMEOUT / 1000);
return false;
}
@@ -841,7 +843,8 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
AR_PHY_AGC_CONTROL_CAL,
0, AH_WAIT_TIMEOUT)) {
ath_dbg(common, CALIBRATE,
- "offset calibration failed to complete in 1ms; noisy environment?\n");
+ "offset calibration failed to complete in %d ms; noisy environment?\n",
+ AH_WAIT_TIMEOUT / 1000);
return false;
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index f76c3ca07a45..639ba7d18ea4 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -1126,7 +1126,8 @@ skip_tx_iqcal:
ar9003_hw_rtt_disable(ah);
ath_dbg(common, CALIBRATE,
- "offset calibration failed to complete in 1ms; noisy environment?\n");
+ "offset calibration failed to complete in %d ms; noisy environment?\n",
+ AH_WAIT_TIMEOUT / 1000);
return false;
}
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 67a2a4b3b883..e6307b86363a 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -2072,7 +2072,7 @@ int ath9k_init_debug(struct ath_hw *ah)
&fops_modal_eeprom);
sc->rfs_chan_spec_scan = relay_open("spectral_scan",
sc->debug.debugfs_phy,
- 262144, 4, &rfs_spec_scan_cb,
+ 1024, 256, &rfs_spec_scan_cb,
NULL);
debugfs_create_file("spectral_scan_ctl", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, sc,
diff --git a/drivers/net/wireless/ath/ath9k/dfs.c b/drivers/net/wireless/ath/ath9k/dfs.c
index ecc81792f2dc..508f8b33f0ef 100644
--- a/drivers/net/wireless/ath/ath9k/dfs.c
+++ b/drivers/net/wireless/ath/ath9k/dfs.c
@@ -193,9 +193,7 @@ void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data,
DFS_STAT_INC(sc, pulses_processed);
if (pd != NULL && pd->add_pulse(pd, &pe)) {
DFS_STAT_INC(sc, radar_detected);
- /*
- * TODO: forward radar event to DFS management layer
- */
+ ieee80211_radar_detected(sc->hw);
}
}
}
diff --git a/drivers/net/wireless/ath/ath9k/dfs_debug.c b/drivers/net/wireless/ath/ath9k/dfs_debug.c
index 55d28072adeb..b7611b7bbe43 100644
--- a/drivers/net/wireless/ath/ath9k/dfs_debug.c
+++ b/drivers/net/wireless/ath/ath9k/dfs_debug.c
@@ -105,6 +105,24 @@ static ssize_t write_file_dfs(struct file *file, const char __user *user_buf,
return count;
}
+static ssize_t write_file_simulate_radar(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+
+ ieee80211_radar_detected(sc->hw);
+
+ return count;
+}
+
+static const struct file_operations fops_simulate_radar = {
+ .write = write_file_simulate_radar,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
static const struct file_operations fops_dfs_stats = {
.read = read_file_dfs,
.write = write_file_dfs,
@@ -117,4 +135,6 @@ void ath9k_dfs_init_debug(struct ath_softc *sc)
{
debugfs_create_file("dfs_stats", S_IRUSR,
sc->debug.debugfs_phy, sc, &fops_dfs_stats);
+ debugfs_create_file("dfs_simulate_radar", S_IWUSR,
+ sc->debug.debugfs_phy, sc, &fops_simulate_radar);
}
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 4fa2bb167050..3473a797651a 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2380,8 +2380,11 @@ static bool ath9k_hw_dfs_tested(struct ath_hw *ah)
{
switch (ah->hw_version.macVersion) {
+ /* for temporary testing DFS with 9280 */
+ case AR_SREV_VERSION_9280:
/* AR9580 will likely be our first target to get testing on */
case AR_SREV_VERSION_9580:
+ return true;
default:
return false;
}
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index af932c9444de..3be2eb0da84a 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -319,6 +319,10 @@ static void ath9k_reg_notifier(struct wiphy *wiphy,
ath9k_ps_wakeup(sc);
ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false);
sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
+ /* synchronize DFS detector if regulatory domain changed */
+ if (sc->dfs_detector != NULL)
+ sc->dfs_detector->set_dfs_domain(sc->dfs_detector,
+ request->dfs_region);
ath9k_ps_restore(sc);
}
}
@@ -727,12 +731,28 @@ static const struct ieee80211_iface_limit if_limits[] = {
BIT(NL80211_IFTYPE_P2P_GO) },
};
-static const struct ieee80211_iface_combination if_comb = {
- .limits = if_limits,
- .n_limits = ARRAY_SIZE(if_limits),
- .max_interfaces = 2048,
- .num_different_channels = 1,
- .beacon_int_infra_match = true,
+
+static const struct ieee80211_iface_limit if_dfs_limits[] = {
+ { .max = 1, .types = BIT(NL80211_IFTYPE_AP) },
+};
+
+static const struct ieee80211_iface_combination if_comb[] = {
+ {
+ .limits = if_limits,
+ .n_limits = ARRAY_SIZE(if_limits),
+ .max_interfaces = 2048,
+ .num_different_channels = 1,
+ .beacon_int_infra_match = true,
+ },
+ {
+ .limits = if_dfs_limits,
+ .n_limits = ARRAY_SIZE(if_dfs_limits),
+ .max_interfaces = 1,
+ .num_different_channels = 1,
+ .beacon_int_infra_match = true,
+ .radar_detect_widths = BIT(NL80211_CHAN_NO_HT) |
+ BIT(NL80211_CHAN_HT20),
+ }
};
void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
@@ -763,8 +783,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_MESH_POINT);
- hw->wiphy->iface_combinations = &if_comb;
- hw->wiphy->n_iface_combinations = 1;
+ hw->wiphy->iface_combinations = if_comb;
+ hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
if (AR_SREV_5416(sc->sc_ah))
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 6e66f9c6782b..1bf52c88004a 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -280,6 +280,10 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
if (r) {
ath_err(common,
"Unable to reset channel, reset status %d\n", r);
+
+ ath9k_hw_enable_interrupts(ah);
+ ath9k_queue_reset(sc, RESET_TYPE_BB_HANG);
+
goto out;
}
@@ -1245,10 +1249,27 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
if (old_pos >= 0)
ath_update_survey_nf(sc, old_pos);
- /* perform spectral scan if requested. */
- if (sc->scanning && sc->spectral_mode == SPECTRAL_CHANSCAN)
- ath9k_spectral_scan_trigger(hw);
-
+ /*
+ * Enable radar pulse detection if on a DFS channel. Spectral
+ * scanning and radar detection can not be used concurrently.
+ */
+ if (hw->conf.radar_enabled) {
+ u32 rxfilter;
+
+ /* set HW specific DFS configuration */
+ ath9k_hw_set_radar_params(ah);
+ rxfilter = ath9k_hw_getrxfilter(ah);
+ rxfilter |= ATH9K_RX_FILTER_PHYRADAR |
+ ATH9K_RX_FILTER_PHYERR;
+ ath9k_hw_setrxfilter(ah, rxfilter);
+ ath_dbg(common, DFS, "DFS enabled at freq %d\n",
+ curchan->center_freq);
+ } else {
+ /* perform spectral scan if requested. */
+ if (sc->scanning &&
+ sc->spectral_mode == SPECTRAL_CHANSCAN)
+ ath9k_spectral_scan_trigger(hw);
+ }
}
if (changed & IEEE80211_CONF_CHANGE_POWER) {
@@ -1745,7 +1766,7 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
mutex_unlock(&sc->mutex);
}
-static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
+static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
{
struct ath_softc *sc = hw->priv;
struct ath_hw *ah = sc->sc_ah;
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index ee156e543147..ee7ca5aecdb0 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -381,6 +381,10 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
rfilt = ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
| ATH9K_RX_FILTER_MCAST;
+ /* if operating on a DFS channel, enable radar pulse detection */
+ if (sc->hw->conf.radar_enabled)
+ rfilt |= ATH9K_RX_FILTER_PHYRADAR | ATH9K_RX_FILTER_PHYERR;
+
if (sc->rx.rxfilter & FIF_PROBE_REQ)
rfilt |= ATH9K_RX_FILTER_PROBEREQ;
@@ -1228,6 +1232,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
unlikely(tsf_lower - rs.rs_tstamp > 0x10000000))
rxs->mactime += 0x100000000ULL;
+ if (rs.rs_phyerr == ATH9K_PHYERR_RADAR)
+ ath9k_dfs_process_phyerr(sc, hdr, &rs, rxs->mactime);
+
if (rs.rs_status & ATH9K_RXERR_PHY) {
if (ath_process_fft(sc, hdr, &rs, rxs->mactime)) {
RX_STAT_INC(rx_spectral);