Re: [ath9k-devel] ath9k: Fix beacon configuration assertion failure

2017-01-07 Thread Benjamin Berg
On Fr, 2016-08-19 at 13:03 +0300, Kalle Valo wrote:
> Actually, I see two patches which might be related but not identical:
> 
> ath9k: fix client mode beacon configuration
> https://patchwork.kernel.org/patch/9247699/
> 
> ath9k: Fix beacon configuration assertion failure
> https://patchwork.kernel.org/patch/9281191/
> 
> Felix (CCed) & Benjamin: please take a look and advice which one I
> should take.

Yes, both patches are designed to fix the same issue in my patch.

Felix solution looks entirely correct to me, the second solution seems
slightly wrong because it prevents the call to ath9k_beacon_config from
happening instead of ensuring the correct parameter value.
ath9k_beacon_config needs to be called even if iter_data.beaconsĀ is
false as it disables the interrupts.

Benjamin
___
ath9k-devel mailing list
ath9k-devel@lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel


[ath9k-devel] [PATCH] ath9k: Prevent radar detection and spectral scan to be used concurrently

2016-11-21 Thread Benjamin Berg
In the case that a spectral scan is enabled the PHY errors sent by the
hardware as part of the scanning might trigger the radar detection and
channels might be marked as 'unusable' incorrectly. This patch fixes
the issue by preventing the spectral scan to be enabled if DFS is used
and only analysing the PHY errors for DFS if radar detection is enabled.

Signed-off-by: Mathias Kretschmer <mathias.kretsch...@fit.fraunhofer.de>
Signed-off-by: Benjamin Berg <benja...@sipsolutions.net>
Signed-off-by: Simon Wunderlich <s...@simonwunderlich.de>
---
 drivers/net/wireless/ath/ath9k/common-spectral.c | 23 +++
 drivers/net/wireless/ath/ath9k/main.c|  6 ++
 drivers/net/wireless/ath/ath9k/recv.c|  7 +--
 3 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/common-spectral.c 
b/drivers/net/wireless/ath/ath9k/common-spectral.c
index e2512d5..8444d6d 100644
--- a/drivers/net/wireless/ath/ath9k/common-spectral.c
+++ b/drivers/net/wireless/ath/ath9k/common-spectral.c
@@ -802,16 +802,27 @@ static ssize_t write_file_spec_scan_ctl(struct file *file,
size_t count, loff_t *ppos)
 {
struct ath_spec_scan_priv *spec_priv = file->private_data;
+   struct ath_hw *ah = spec_priv->ah;
+   struct ath_softc *sc = ah->hw->priv;
struct ath_common *common = ath9k_hw_common(spec_priv->ah);
char buf[32];
ssize_t len;
+   ssize_t result = count;
 
if (IS_ENABLED(CONFIG_ATH9K_TX99))
return -EOPNOTSUPP;
 
+   mutex_lock(>mutex);
+   if (ah->hw->conf.radar_enabled) {
+   result = -EINVAL;
+   goto unlock;
+   }
+
len = min(count, sizeof(buf) - 1);
-   if (copy_from_user(buf, user_buf, len))
-   return -EFAULT;
+   if (copy_from_user(buf, user_buf, len)) {
+   result = -EFAULT;
+   goto unlock;
+   }
 
buf[len] = '\0';
 
@@ -830,10 +841,14 @@ static ssize_t write_file_spec_scan_ctl(struct file *file,
ath9k_cmn_spectral_scan_config(common, spec_priv, 
SPECTRAL_DISABLED);
ath_dbg(common, CONFIG, "spectral scan: disabled\n");
} else {
-   return -EINVAL;
+   result = -EINVAL;
+   goto unlock;
}
 
-   return count;
+unlock:
+   mutex_unlock(>mutex);
+
+   return result;
 }
 
 static const struct file_operations fops_spec_scan_ctl = {
diff --git a/drivers/net/wireless/ath/ath9k/main.c 
b/drivers/net/wireless/ath/ath9k/main.c
index e9f32b5..62b86fb 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1459,6 +1459,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 
changed)
if (!ath9k_is_chanctx_enabled() && (changed & 
IEEE80211_CONF_CHANGE_CHANNEL)) {
ctx->offchannel = !!(conf->flags & IEEE80211_CONF_OFFCHANNEL);
ath_chanctx_set_channel(sc, ctx, >conf.chandef);
+
+   /* We need to ensure that spectral scan is disabled. */
+   if (conf->radar_enabled &&
+   sc->spec_priv.spectral_mode != SPECTRAL_DISABLED)
+   ath9k_cmn_spectral_scan_config(common, >spec_priv,
+  SPECTRAL_DISABLED);
}
 
mutex_unlock(>mutex);
diff --git a/drivers/net/wireless/ath/ath9k/recv.c 
b/drivers/net/wireless/ath/ath9k/recv.c
index 6697342..ce34add 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -867,8 +867,11 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
 * can be dropped.
 */
if (rx_stats->rs_status & ATH9K_RXERR_PHY) {
-   ath9k_dfs_process_phyerr(sc, hdr, rx_stats, rx_status->mactime);
-   if (ath_cmn_process_fft(>spec_priv, hdr, rx_stats, 
rx_status->mactime))
+   if (hw->conf.radar_enabled)
+   ath9k_dfs_process_phyerr(sc, hdr, rx_stats,
+rx_status->mactime);
+   else if (ath_cmn_process_fft(>spec_priv, hdr, rx_stats,
+rx_status->mactime))
RX_STAT_INC(rx_spectral);
 
return -EINVAL;
-- 
2.10.2

___
ath9k-devel mailing list
ath9k-devel@lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel


[ath9k-devel] [PATCH v2 3/6] ath9k: Use tsf offset helper in ath9k_hw_reset

2016-07-04 Thread Benjamin Berg
From: Benjamin Berg <benjamin.b...@open-mesh.com>

These changes make ath9k_hw_reset more consistent with other places that
handle the TSF value by using the same helper routine.

A slight improvement is to not assume that a fixed time of 1.5ms has
passed for the initval writes when compared to the first write attempt.
Instead the TSF value is re-calculated which will yield a higher accuracy
of the restored TSF timer.

Signed-off-by: Benjamin Berg <benjamin.b...@open-mesh.com>
---
 drivers/net/wireless/ath/ath9k/hw.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c 
b/drivers/net/wireless/ath/ath9k/hw.c
index 8b2895f..1c27e2d 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1832,8 +1832,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct 
ath9k_channel *chan,
u32 saveLedState;
u32 saveDefAntenna;
u32 macStaId1;
+   struct timespec tsf_ts;
+   u32 tsf_offset;
u64 tsf = 0;
-   s64 usec = 0;
int r;
bool start_mci_reset = false;
bool save_fullsleep = ah->chip_fullsleep;
@@ -1877,8 +1878,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct 
ath9k_channel *chan,
macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
 
/* Save TSF before chip reset, a cold reset clears it */
+   getrawmonotonic(_ts);
tsf = ath9k_hw_gettsf64(ah);
-   usec = ktime_to_us(ktime_get_raw());
 
saveLedState = REG_READ(ah, AR_CFG_LED) &
(AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
@@ -1911,8 +1912,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct 
ath9k_channel *chan,
}
 
/* Restore TSF */
-   usec = ktime_to_us(ktime_get_raw()) - usec;
-   ath9k_hw_settsf64(ah, tsf + usec);
+   tsf_offset = ath9k_hw_get_tsf_offset(_ts, NULL);
+   ath9k_hw_settsf64(ah, tsf + tsf_offset);
 
if (AR_SREV_9280_20_OR_LATER(ah))
REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
@@ -1932,12 +1933,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct 
ath9k_channel *chan,
/*
 * Some AR91xx SoC devices frequently fail to accept TSF writes
 * right after the chip reset. When that happens, write a new
-* value after the initvals have been applied, with an offset
-* based on measured time difference
+* value after the initvals have been applied.
 */
if (AR_SREV_9100(ah) && (ath9k_hw_gettsf64(ah) < tsf)) {
-   tsf += 1500;
-   ath9k_hw_settsf64(ah, tsf);
+   tsf_offset = ath9k_hw_get_tsf_offset(_ts, NULL);
+   ath9k_hw_settsf64(ah, tsf + tsf_offset);
}
 
ath9k_hw_init_mfp(ah);
-- 
2.8.1

___
ath9k-devel mailing list
ath9k-devel@lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel


[ath9k-devel] [PATCH v2 1/6] ath9k: Correct TSF adjustment to align the beacon time correctly

2016-07-04 Thread Benjamin Berg
From: Benjamin Berg <benjamin.b...@open-mesh.com>

Beacons were not send out at (timestamp % beacon_time == 0) for interfaces
other than the primary one. To send out beacons with the correct timestamp
according to 10.1.3.2 of the 802.11 standard the tsf_adjustment has to be
set to the negative time difference instead of positive. This way the
later beacons get corrected to have a lower (and similar) timestamp with
regard to the beacon from slot 0.

I am not aware about any issues that have been caused by this.

Signed-off-by: Benjamin Berg <benjamin.b...@open-mesh.com>
---
 drivers/net/wireless/ath/ath9k/beacon.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/beacon.c 
b/drivers/net/wireless/ath/ath9k/beacon.c
index 5cf0cd7..800c96b 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -279,17 +279,21 @@ static void ath9k_set_tsfadjust(struct ath_softc *sc, 
struct ieee80211_vif *vif)
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_vif *avp = (void *)vif->drv_priv;
struct ath_beacon_config *cur_conf = >chanctx->beacon;
-   u32 tsfadjust;
+   s64 tsfadjust;
 
if (avp->av_bslot == 0)
return;
 
+   /* tsf_adjust is added to the TSF value. We send out the beacon late,
+* so need to adjust the TSF starting point to be later in time (i.e.
+* the theoretical first beacon has a TSF of 0 after correction).
+*/
tsfadjust = cur_conf->beacon_interval * avp->av_bslot;
-   tsfadjust = TU_TO_USEC(tsfadjust) / ATH_BCBUF;
+   tsfadjust = -TU_TO_USEC(tsfadjust) / ATH_BCBUF;
avp->tsf_adjust = cpu_to_le64(tsfadjust);
 
-   ath_dbg(common, CONFIG, "tsfadjust is: %llu for bslot: %d\n",
-   (unsigned long long)tsfadjust, avp->av_bslot);
+   ath_dbg(common, CONFIG, "tsfadjust is: %lld for bslot: %d\n",
+   (signed long long)tsfadjust, avp->av_bslot);
 }
 
 bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif)
-- 
2.8.1

___
ath9k-devel mailing list
ath9k-devel@lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel


[ath9k-devel] [PATCH v2 2/6] ath9k: Handle channel context in get_/set_/reset_tsf

2016-07-04 Thread Benjamin Berg
From: Benjamin Berg <benjamin.b...@open-mesh.com>

The ath9k TSF handling routines need to be aware of the channel context that
is being modified. With this change the TSF related values that are stored
in each channel context will be correctly tracked and the harware will only
be updated if the modified context is currently the active one.

Without this change the TSF modifications done using these routines would
for example be lost during a hardware reset as done by ath_complete_reset.

Signed-off-by: Benjamin Berg <benjamin.b...@open-mesh.com>
---
 drivers/net/wireless/ath/ath9k/main.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c 
b/drivers/net/wireless/ath/ath9k/main.c
index 8b63988..375c2ac 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1823,11 +1823,18 @@ static void ath9k_bss_info_changed(struct ieee80211_hw 
*hw,
 static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
struct ath_softc *sc = hw->priv;
+   struct ath_vif *avp = (void *)vif->drv_priv;
u64 tsf;
 
mutex_lock(>mutex);
ath9k_ps_wakeup(sc);
-   tsf = ath9k_hw_gettsf64(sc->sc_ah);
+   /* Get current TSF either from HW or kernel time. */
+   if (sc->cur_chan == avp->chanctx) {
+   tsf = ath9k_hw_gettsf64(sc->sc_ah);
+   } else {
+   tsf = sc->cur_chan->tsf_val +
+ ath9k_hw_get_tsf_offset(>cur_chan->tsf_ts, NULL);
+   }
ath9k_ps_restore(sc);
mutex_unlock(>mutex);
 
@@ -1839,10 +1846,14 @@ static void ath9k_set_tsf(struct ieee80211_hw *hw,
  u64 tsf)
 {
struct ath_softc *sc = hw->priv;
+   struct ath_vif *avp = (void *)vif->drv_priv;
 
mutex_lock(>mutex);
ath9k_ps_wakeup(sc);
-   ath9k_hw_settsf64(sc->sc_ah, tsf);
+   getrawmonotonic(>chanctx->tsf_ts);
+   if (sc->cur_chan == avp->chanctx)
+   ath9k_hw_settsf64(sc->sc_ah, tsf);
+   avp->chanctx->tsf_val = tsf;
ath9k_ps_restore(sc);
mutex_unlock(>mutex);
 }
@@ -1850,11 +1861,15 @@ static void ath9k_set_tsf(struct ieee80211_hw *hw,
 static void ath9k_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
struct ath_softc *sc = hw->priv;
+   struct ath_vif *avp = (void *)vif->drv_priv;
 
mutex_lock(>mutex);
 
ath9k_ps_wakeup(sc);
-   ath9k_hw_reset_tsf(sc->sc_ah);
+   getrawmonotonic(>chanctx->tsf_ts);
+   if (sc->cur_chan == avp->chanctx)
+   ath9k_hw_reset_tsf(sc->sc_ah);
+   avp->chanctx->tsf_val = 0;
ath9k_ps_restore(sc);
 
mutex_unlock(>mutex);
-- 
2.8.1

___
ath9k-devel mailing list
ath9k-devel@lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel


[ath9k-devel] [PATCH v2 6/6] ath9k: Fix beacon configuration for addition/removal of interfaces

2016-07-04 Thread Benjamin Berg
From: Benjamin Berg <benjamin.b...@open-mesh.com>

This patch fixes some issues with interface reconfiguration. It could
for example happen that an AP interface in beacon slot 0 was removed
leaving an IBSS station in one of the other slots. When this happens
the driver never sends out the beacon as it only tries to send a beacon
from slot 0.

Appart from that the tracking of required changes to the beacon config is
relatively complicated and prone to errors.

The approach taken here is to solve reconfiguration issues is to
reconfigure the beacons when any interface changes. This means that
the complexity of deciding whether an interface change may modify the
beacon configuration is gone. It also means that the beacon config will
be reliably updated when an interface is removed.

The issue that a single non-AP interface might not be in beacon
slot 0 and wouldn't be send out is solved by moving it into the
first slot. The TSF value in hardware is adjusted accordingly so
that the timestamp of the beacons stay consistent.

Signed-off-by: Benjamin Berg <benjamin.b...@open-mesh.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h  |   7 +-
 drivers/net/wireless/ath/ath9k/beacon.c | 240 ++--
 drivers/net/wireless/ath/ath9k/common.h |   1 +
 drivers/net/wireless/ath/ath9k/main.c   |  43 +++---
 4 files changed, 165 insertions(+), 126 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h 
b/drivers/net/wireless/ath/ath9k/ath9k.h
index 93b3793..26fc8ec 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -637,6 +637,8 @@ struct ath9k_vif_iter_data {
int nwds;  /* number of WDS vifs */
int nadhocs;   /* number of adhoc vifs */
int nocbs; /* number of OCB vifs */
+   int nbcnvifs;  /* number of beaconing vifs */
+   struct ieee80211_vif *primary_beacon_vif;
struct ieee80211_vif *primary_sta;
 };
 
@@ -685,10 +687,11 @@ struct ath_beacon {
 };
 
 void ath9k_beacon_tasklet(unsigned long data);
-void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif,
-u32 changed);
+void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *main_vif,
+bool beacons);
 void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif);
 void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif);
+void ath9k_beacon_ensure_primary_slot(struct ath_softc *sc);
 void ath9k_set_beacon(struct ath_softc *sc);
 bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif);
 void ath9k_csa_update(struct ath_softc *sc);
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c 
b/drivers/net/wireless/ath/ath9k/beacon.c
index d8b4971..e36f947 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -209,7 +209,6 @@ void ath9k_beacon_assign_slot(struct ath_softc *sc, struct 
ieee80211_vif *vif)
}
 
sc->beacon.bslot[avp->av_bslot] = vif;
-   sc->nbcnvifs++;
 
ath_dbg(common, CONFIG, "Added interface at beacon slot: %d\n",
avp->av_bslot);
@@ -220,15 +219,12 @@ void ath9k_beacon_remove_slot(struct ath_softc *sc, 
struct ieee80211_vif *vif)
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_vif *avp = (void *)vif->drv_priv;
struct ath_buf *bf = avp->av_bcbuf;
-   struct ath_beacon_config *cur_conf = >cur_chan->beacon;
 
ath_dbg(common, CONFIG, "Removing interface at beacon slot: %d\n",
avp->av_bslot);
 
tasklet_disable(>bcon_tasklet);
 
-   cur_conf->enable_beacon &= ~BIT(avp->av_bslot);
-
if (bf && bf->bf_mpdu) {
struct sk_buff *skb = bf->bf_mpdu;
dma_unmap_single(sc->dev, bf->bf_buf_addr,
@@ -240,12 +236,73 @@ void ath9k_beacon_remove_slot(struct ath_softc *sc, 
struct ieee80211_vif *vif)
 
avp->av_bcbuf = NULL;
sc->beacon.bslot[avp->av_bslot] = NULL;
-   sc->nbcnvifs--;
list_add_tail(>list, >beacon.bbuf);
 
tasklet_enable(>bcon_tasklet);
 }
 
+void ath9k_beacon_ensure_primary_slot(struct ath_softc *sc)
+{
+   struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+   struct ieee80211_vif *vif;
+   struct ath_vif *avp;
+   s64 tsfadjust;
+   u32 offset;
+   int first_slot = ATH_BCBUF;
+   int slot;
+
+   tasklet_disable(>bcon_tasklet);
+
+   /* Find first taken slot. */
+   for (slot = 0; slot < ATH_BCBUF; slot++) {
+   if (sc->beacon.bslot[slot]) {
+   first_slot = slot;
+   break;
+   }
+   }
+   if (first_slot == 0)
+   goto out;
+
+   /* Re-enumarate all slots, moving them forward. */
+   for (slot = 0; slot

[ath9k-devel] [PATCH v2 5/6] ath9k: Remove some #defined constants to decrease verbosity

2016-07-04 Thread Benjamin Berg
From: Benjamin Berg <benjamin.b...@open-mesh.com>

The removed ATH9K_SLOT_TIME_X constants simply map the value in microseconds
to the same integer. These constants were not used consistently, so fix the
inconsistency issue by replacing all occurances with the integer equivalent.

Signed-off-by: Benjamin Berg <benjamin.b...@open-mesh.com>
---
 drivers/net/wireless/ath/ath9k/beacon.c | 2 +-
 drivers/net/wireless/ath/ath9k/dynack.c | 4 ++--
 drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 2 +-
 drivers/net/wireless/ath/ath9k/htc_drv_init.c   | 2 +-
 drivers/net/wireless/ath/ath9k/hw.c | 2 +-
 drivers/net/wireless/ath/ath9k/init.c   | 2 +-
 drivers/net/wireless/ath/ath9k/mac.h| 4 
 drivers/net/wireless/ath/ath9k/main.c   | 7 ---
 8 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/beacon.c 
b/drivers/net/wireless/ath/ath9k/beacon.c
index 800c96b..d8b4971 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -50,7 +50,7 @@ static void ath9k_beaconq_config(struct ath_softc *sc)
txq = sc->tx.txq_map[IEEE80211_AC_BE];
ath9k_hw_get_txq_props(ah, txq->axq_qnum, _be);
qi.tqi_aifs = qi_be.tqi_aifs;
-   if (ah->slottime == ATH9K_SLOT_TIME_20)
+   if (ah->slottime == 20)
qi.tqi_cwmin = 2*qi_be.tqi_cwmin;
else
qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
diff --git a/drivers/net/wireless/ath/ath9k/dynack.c 
b/drivers/net/wireless/ath/ath9k/dynack.c
index d2ff0fc..7334c9b0 100644
--- a/drivers/net/wireless/ath/ath9k/dynack.c
+++ b/drivers/net/wireless/ath/ath9k/dynack.c
@@ -280,7 +280,7 @@ EXPORT_SYMBOL(ath_dynack_sample_ack_ts);
 void ath_dynack_node_init(struct ath_hw *ah, struct ath_node *an)
 {
/* ackto = slottime + sifs + air delay */
-   u32 ackto = ATH9K_SLOT_TIME_9 + 16 + 64;
+   u32 ackto = 9 + 16 + 64;
struct ath_dynack *da = >dynack;
 
an->ackto = ackto;
@@ -315,7 +315,7 @@ EXPORT_SYMBOL(ath_dynack_node_deinit);
 void ath_dynack_reset(struct ath_hw *ah)
 {
/* ackto = slottime + sifs + air delay */
-   u32 ackto = ATH9K_SLOT_TIME_9 + 16 + 64;
+   u32 ackto = 9 + 16 + 64;
struct ath_dynack *da = >dynack;
 
da->lto = jiffies;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c 
b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index e6bcb4c..2c0e4d2 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -45,7 +45,7 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
 * Long slot time  : 2x cwmin
 * Short slot time : 4x cwmin
 */
-   if (ah->slottime == ATH9K_SLOT_TIME_20)
+   if (ah->slottime == 20)
qi.tqi_cwmin = 2*qi_be.tqi_cwmin;
else
qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c 
b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index c148c6c..b65c1b6 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -678,7 +678,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
 
for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++)
priv->beacon.bslot[i] = NULL;
-   priv->beacon.slottime = ATH9K_SLOT_TIME_9;
+   priv->beacon.slottime = 9;
 
ath9k_cmn_init_channels_rates(common);
ath9k_cmn_init_crypto(ah);
diff --git a/drivers/net/wireless/ath/ath9k/hw.c 
b/drivers/net/wireless/ath/ath9k/hw.c
index 1c27e2d..f091599 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -454,7 +454,7 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
if (AR_SREV_9100(ah))
ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX;
 
-   ah->slottime = ATH9K_SLOT_TIME_9;
+   ah->slottime = 9;
ah->globaltxtimeout = (u32) -1;
ah->power_mode = ATH9K_PM_UNDEFINED;
ah->htc_reset_init = true;
diff --git a/drivers/net/wireless/ath/ath9k/init.c 
b/drivers/net/wireless/ath/ath9k/init.c
index 2ee8624..89654d5 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -372,7 +372,7 @@ static void ath9k_init_misc(struct ath_softc *sc)
 
common->last_rssi = ATH_RSSI_DUMMY_MARKER;
memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
-   sc->beacon.slottime = ATH9K_SLOT_TIME_9;
+   sc->beacon.slottime = 9;
 
for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++)
sc->beacon.bslot[i] = NULL;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h 
b/drivers/net/wireless/ath/ath9k/mac.h
index 7fbf

[ath9k-devel] [PATCH 4/6] ath9k: Expose tsf_adjustment in mac80211 tsf getters and setters.

2016-06-07 Thread Benjamin Berg
From: Benjamin Berg <benjamin.b...@open-mesh.com>

Signed-off-by: Benjamin Berg <benjamin.b...@open-mesh.com>
---
 drivers/net/wireless/ath/ath9k/main.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/main.c 
b/drivers/net/wireless/ath/ath9k/main.c
index 375c2ac..f2ebc85 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1835,6 +1835,7 @@ static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif)
tsf = sc->cur_chan->tsf_val +
  ath9k_hw_get_tsf_offset(>cur_chan->tsf_ts, NULL);
}
+   tsf += le64_to_cpu(avp->tsf_adjust);
ath9k_ps_restore(sc);
mutex_unlock(>mutex);
 
@@ -1850,6 +1851,7 @@ static void ath9k_set_tsf(struct ieee80211_hw *hw,
 
mutex_lock(>mutex);
ath9k_ps_wakeup(sc);
+   tsf -= le64_to_cpu(avp->tsf_adjust);
getrawmonotonic(>chanctx->tsf_ts);
if (sc->cur_chan == avp->chanctx)
ath9k_hw_settsf64(sc->sc_ah, tsf);
-- 
2.8.1

___
ath9k-devel mailing list
ath9k-devel@lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel


[ath9k-devel] [PATCH 6/6] ath9k: Fix beacon configuration for addition/removal of interfaces

2016-06-07 Thread Benjamin Berg
From: Benjamin Berg <benjamin.b...@open-mesh.com>

This patch fixes some issues with interface reconfiguration. It could
for example happen that an AP interface in beacon slot 0 was removed
leaving an IBSS station in one of the other slots.

This patch approaches these failures by reconfiguring the beacon
configuration from calculate_summary_state instead of trying to
track whether the configuration should be modified.

The issue that a single non-AP interface might not be in beacon
slot 0 and wouldn't be send out is solved by moving it into the
first slot. The TSF value in hardware is adjusted accordingly so
that the timestamp of the beacons stay consistent.

Signed-off-by: Benjamin Berg <benjamin.b...@open-mesh.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h  |   7 +-
 drivers/net/wireless/ath/ath9k/beacon.c | 240 ++--
 drivers/net/wireless/ath/ath9k/common.h |   1 +
 drivers/net/wireless/ath/ath9k/main.c   |  43 +++---
 4 files changed, 165 insertions(+), 126 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h 
b/drivers/net/wireless/ath/ath9k/ath9k.h
index 93b3793..26fc8ec 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -637,6 +637,8 @@ struct ath9k_vif_iter_data {
int nwds;  /* number of WDS vifs */
int nadhocs;   /* number of adhoc vifs */
int nocbs; /* number of OCB vifs */
+   int nbcnvifs;  /* number of beaconing vifs */
+   struct ieee80211_vif *primary_beacon_vif;
struct ieee80211_vif *primary_sta;
 };
 
@@ -685,10 +687,11 @@ struct ath_beacon {
 };
 
 void ath9k_beacon_tasklet(unsigned long data);
-void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif,
-u32 changed);
+void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *main_vif,
+bool beacons);
 void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif);
 void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif);
+void ath9k_beacon_ensure_primary_slot(struct ath_softc *sc);
 void ath9k_set_beacon(struct ath_softc *sc);
 bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif);
 void ath9k_csa_update(struct ath_softc *sc);
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c 
b/drivers/net/wireless/ath/ath9k/beacon.c
index 800c96b..0fa7ac2 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -209,7 +209,6 @@ void ath9k_beacon_assign_slot(struct ath_softc *sc, struct 
ieee80211_vif *vif)
}
 
sc->beacon.bslot[avp->av_bslot] = vif;
-   sc->nbcnvifs++;
 
ath_dbg(common, CONFIG, "Added interface at beacon slot: %d\n",
avp->av_bslot);
@@ -220,15 +219,12 @@ void ath9k_beacon_remove_slot(struct ath_softc *sc, 
struct ieee80211_vif *vif)
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_vif *avp = (void *)vif->drv_priv;
struct ath_buf *bf = avp->av_bcbuf;
-   struct ath_beacon_config *cur_conf = >cur_chan->beacon;
 
ath_dbg(common, CONFIG, "Removing interface at beacon slot: %d\n",
avp->av_bslot);
 
tasklet_disable(>bcon_tasklet);
 
-   cur_conf->enable_beacon &= ~BIT(avp->av_bslot);
-
if (bf && bf->bf_mpdu) {
struct sk_buff *skb = bf->bf_mpdu;
dma_unmap_single(sc->dev, bf->bf_buf_addr,
@@ -240,12 +236,73 @@ void ath9k_beacon_remove_slot(struct ath_softc *sc, 
struct ieee80211_vif *vif)
 
avp->av_bcbuf = NULL;
sc->beacon.bslot[avp->av_bslot] = NULL;
-   sc->nbcnvifs--;
list_add_tail(>list, >beacon.bbuf);
 
tasklet_enable(>bcon_tasklet);
 }
 
+void ath9k_beacon_ensure_primary_slot(struct ath_softc *sc)
+{
+   struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+   struct ieee80211_vif *vif;
+   struct ath_vif *avp;
+   s64 tsfadjust;
+   u32 offset;
+   int first_slot = ATH_BCBUF;
+   int slot;
+
+   tasklet_disable(>bcon_tasklet);
+
+   /* Find first taken slot. */
+   for (slot = 0; slot < ATH_BCBUF; slot++) {
+   if (sc->beacon.bslot[slot]) {
+   first_slot = slot;
+   break;
+   }
+   }
+   if (first_slot == 0)
+   goto out;
+
+   /* Re-enumarate all slots, moving them forward. */
+   for (slot = 0; slot < ATH_BCBUF; slot++) {
+   if (slot + first_slot < ATH_BCBUF) {
+   vif = sc->beacon.bslot[slot + first_slot];
+   sc->beacon.bslot[slot] = vif;
+
+   if (vif) {
+   avp = (void *)vif->drv_priv;
+  

[ath9k-devel] [PATCH 3/6] ath9k: Use tsf offset helper in ath9k_hw_reset

2016-06-07 Thread Benjamin Berg
From: Benjamin Berg <benjamin.b...@open-mesh.com>

Not much of a change. Only small fix is that we don't assume that
exactly 1.5ms have passed for the second AR91xx SoC TSF setting.

Signed-off-by: Benjamin Berg <benjamin.b...@open-mesh.com>
---
 drivers/net/wireless/ath/ath9k/hw.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c 
b/drivers/net/wireless/ath/ath9k/hw.c
index 8b2895f..1c27e2d 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1832,8 +1832,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct 
ath9k_channel *chan,
u32 saveLedState;
u32 saveDefAntenna;
u32 macStaId1;
+   struct timespec tsf_ts;
+   u32 tsf_offset;
u64 tsf = 0;
-   s64 usec = 0;
int r;
bool start_mci_reset = false;
bool save_fullsleep = ah->chip_fullsleep;
@@ -1877,8 +1878,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct 
ath9k_channel *chan,
macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
 
/* Save TSF before chip reset, a cold reset clears it */
+   getrawmonotonic(_ts);
tsf = ath9k_hw_gettsf64(ah);
-   usec = ktime_to_us(ktime_get_raw());
 
saveLedState = REG_READ(ah, AR_CFG_LED) &
(AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
@@ -1911,8 +1912,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct 
ath9k_channel *chan,
}
 
/* Restore TSF */
-   usec = ktime_to_us(ktime_get_raw()) - usec;
-   ath9k_hw_settsf64(ah, tsf + usec);
+   tsf_offset = ath9k_hw_get_tsf_offset(_ts, NULL);
+   ath9k_hw_settsf64(ah, tsf + tsf_offset);
 
if (AR_SREV_9280_20_OR_LATER(ah))
REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
@@ -1932,12 +1933,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct 
ath9k_channel *chan,
/*
 * Some AR91xx SoC devices frequently fail to accept TSF writes
 * right after the chip reset. When that happens, write a new
-* value after the initvals have been applied, with an offset
-* based on measured time difference
+* value after the initvals have been applied.
 */
if (AR_SREV_9100(ah) && (ath9k_hw_gettsf64(ah) < tsf)) {
-   tsf += 1500;
-   ath9k_hw_settsf64(ah, tsf);
+   tsf_offset = ath9k_hw_get_tsf_offset(_ts, NULL);
+   ath9k_hw_settsf64(ah, tsf + tsf_offset);
}
 
ath9k_hw_init_mfp(ah);
-- 
2.8.1

___
ath9k-devel mailing list
ath9k-devel@lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel


[ath9k-devel] [PATCH 2/6] ath9k: Handle channel context in get_/set_/reset_tsf

2016-06-07 Thread Benjamin Berg
From: Benjamin Berg <benjamin.b...@open-mesh.com>

Signed-off-by: Benjamin Berg <benjamin.b...@open-mesh.com>
---
 drivers/net/wireless/ath/ath9k/main.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c 
b/drivers/net/wireless/ath/ath9k/main.c
index 8b63988..375c2ac 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1823,11 +1823,18 @@ static void ath9k_bss_info_changed(struct ieee80211_hw 
*hw,
 static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
struct ath_softc *sc = hw->priv;
+   struct ath_vif *avp = (void *)vif->drv_priv;
u64 tsf;
 
mutex_lock(>mutex);
ath9k_ps_wakeup(sc);
-   tsf = ath9k_hw_gettsf64(sc->sc_ah);
+   /* Get current TSF either from HW or kernel time. */
+   if (sc->cur_chan == avp->chanctx) {
+   tsf = ath9k_hw_gettsf64(sc->sc_ah);
+   } else {
+   tsf = sc->cur_chan->tsf_val +
+ ath9k_hw_get_tsf_offset(>cur_chan->tsf_ts, NULL);
+   }
ath9k_ps_restore(sc);
mutex_unlock(>mutex);
 
@@ -1839,10 +1846,14 @@ static void ath9k_set_tsf(struct ieee80211_hw *hw,
  u64 tsf)
 {
struct ath_softc *sc = hw->priv;
+   struct ath_vif *avp = (void *)vif->drv_priv;
 
mutex_lock(>mutex);
ath9k_ps_wakeup(sc);
-   ath9k_hw_settsf64(sc->sc_ah, tsf);
+   getrawmonotonic(>chanctx->tsf_ts);
+   if (sc->cur_chan == avp->chanctx)
+   ath9k_hw_settsf64(sc->sc_ah, tsf);
+   avp->chanctx->tsf_val = tsf;
ath9k_ps_restore(sc);
mutex_unlock(>mutex);
 }
@@ -1850,11 +1861,15 @@ static void ath9k_set_tsf(struct ieee80211_hw *hw,
 static void ath9k_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
struct ath_softc *sc = hw->priv;
+   struct ath_vif *avp = (void *)vif->drv_priv;
 
mutex_lock(>mutex);
 
ath9k_ps_wakeup(sc);
-   ath9k_hw_reset_tsf(sc->sc_ah);
+   getrawmonotonic(>chanctx->tsf_ts);
+   if (sc->cur_chan == avp->chanctx)
+   ath9k_hw_reset_tsf(sc->sc_ah);
+   avp->chanctx->tsf_val = 0;
ath9k_ps_restore(sc);
 
mutex_unlock(>mutex);
-- 
2.8.1

___
ath9k-devel mailing list
ath9k-devel@lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel


[ath9k-devel] [PATCH 5/6] ath9k: Use defined constants consistently.

2016-06-07 Thread Benjamin Berg
From: Benjamin Berg <benjamin.b...@open-mesh.com>

Signed-off-by: Benjamin Berg <benjamin.b...@open-mesh.com>
---
 drivers/net/wireless/ath/ath9k/main.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c 
b/drivers/net/wireless/ath/ath9k/main.c
index f2ebc85..6a81298 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1785,9 +1785,10 @@ static void ath9k_bss_info_changed(struct ieee80211_hw 
*hw,
if ((avp->chanctx == sc->cur_chan) &&
(changed & BSS_CHANGED_ERP_SLOT)) {
if (bss_conf->use_short_slot)
-   slottime = 9;
+   slottime = ATH9K_SLOT_TIME_9;
else
-   slottime = 20;
+   slottime = ATH9K_SLOT_TIME_20;
+
if (vif->type == NL80211_IFTYPE_AP) {
/*
 * Defer update, so that connected stations can adjust
-- 
2.8.1

___
ath9k-devel mailing list
ath9k-devel@lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel


Re: [ath9k-devel] ath9k hangs with recent backports

2015-09-18 Thread Benjamin Berg
On Di, 2015-08-04 at 16:33 -0400, Marty Faltesek wrote:
> We are seeing a hang on ath9k where traffic and beacons stops anywhere
> from a few minutes to half a day. Log output continues. With debug
> enabled, we see this during the hang:
> 
> ath: phy0: tx hung, resetting the chip.
> 
> The issue was not observed in backports 3.19-rc1, but in recent
> backports, the issue was first noted going as far back as
> backports-20150222 (perhaps earlier,  still checking). We still see
> the hang in linux-next as recent as next-20150729.
> 
> Configuration:
> dual-core ARM Freescale LS1024A (f.k.a. Mindspeed Comcerto 2000)
> AR9300

We seem to be seeing a similar issue here where devices become
unresponsive via wifi and the TX path hang counter keeps increasing. We
are seeing this using backports 2014-11-04 (openwrt). The hardware is
an AR9331 SoC.

Were you able to narrow down the issue any further in the meantime?

Benjamin

signature.asc
Description: This is a digitally signed message part
___
ath9k-devel mailing list
ath9k-devel@lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel


[ath9k-devel] [PATCH] ath9k: Prevent radard detection and spectral scan to be used concurrently

2015-06-01 Thread Benjamin Berg
In the case that a spectral scan is enabled the PHY errors sent by the
hardware as part of the scanning might trigger the radar detection and
channels might be marked as 'unusable' incorrectly. This patch fixes
the issue by preventing the spectral scan to be enabled if DFS is used
and only analysing the PHY errors for DFS if radar detection is enabled.

Reported-by: Mathias Kretschmer mathias.kretsch...@fokus.fraunhofer.de
Signed-off-by: Benjamin Berg benja...@sipsolutions.net
Signed-off-by: Simon Wunderlich s...@simonwunderlich.de

[v3.19+]
---

The patch does apply to 3.19+ with a bit of fuzz.


 drivers/net/wireless/ath/ath9k/common-spectral.c | 4 
 drivers/net/wireless/ath/ath9k/main.c| 6 ++
 drivers/net/wireless/ath/ath9k/recv.c| 7 +--
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/common-spectral.c 
b/drivers/net/wireless/ath/ath9k/common-spectral.c
index 5cee231..59b5ad8 100644
--- a/drivers/net/wireless/ath/ath9k/common-spectral.c
+++ b/drivers/net/wireless/ath/ath9k/common-spectral.c
@@ -312,6 +312,7 @@ static ssize_t write_file_spec_scan_ctl(struct file *file,
size_t count, loff_t *ppos)
 {
struct ath_spec_scan_priv *spec_priv = file-private_data;
+   struct ath_hw *ah = spec_priv-ah;
struct ath_common *common = ath9k_hw_common(spec_priv-ah);
char buf[32];
ssize_t len;
@@ -319,6 +320,9 @@ static ssize_t write_file_spec_scan_ctl(struct file *file,
if (config_enabled(CONFIG_ATH9K_TX99))
return -EOPNOTSUPP;
 
+   if (ah-hw-conf.radar_enabled)
+   return -EINVAL;
+
len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len))
return -EFAULT;
diff --git a/drivers/net/wireless/ath/ath9k/main.c 
b/drivers/net/wireless/ath/ath9k/main.c
index b0badef..2d63062 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1433,6 +1433,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 
changed)
if (!ath9k_is_chanctx_enabled()  (changed  
IEEE80211_CONF_CHANGE_CHANNEL)) {
ctx-offchannel = !!(conf-flags  IEEE80211_CONF_OFFCHANNEL);
ath_chanctx_set_channel(sc, ctx, hw-conf.chandef);
+
+   /* We need to ensure that spectral scan is disabled. */
+   if (conf-radar_enabled 
+   sc-spec_priv.spectral_mode != SPECTRAL_DISABLED)
+   ath9k_cmn_spectral_scan_config(common, sc-spec_priv,
+  SPECTRAL_DISABLED);
}
 
mutex_unlock(sc-mutex);
diff --git a/drivers/net/wireless/ath/ath9k/recv.c 
b/drivers/net/wireless/ath/ath9k/recv.c
index 6fb40ef..167628f 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -870,8 +870,11 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
 * can be dropped.
 */
if (rx_stats-rs_status  ATH9K_RXERR_PHY) {
-   ath9k_dfs_process_phyerr(sc, hdr, rx_stats, rx_status-mactime);
-   if (ath_cmn_process_fft(sc-spec_priv, hdr, rx_stats, 
rx_status-mactime))
+   if (hw-conf.radar_enabled)
+   ath9k_dfs_process_phyerr(sc, hdr,
+rx_stats, rx_status-mactime);
+   else if (ath_cmn_process_fft(sc-spec_priv, hdr
+rx_stats, rx_status-mactime))
RX_STAT_INC(rx_spectral);
 
return -EINVAL;
-- 
2.1.4

___
ath9k-devel mailing list
ath9k-devel@lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel


Re: [ath9k-devel] [PATCH] ath9k: Configure beacons for AP vif if this has not happened yet

2015-03-13 Thread Benjamin Berg
On Fr, 2015-03-13 at 15:27 +0100, Felix Fietkau wrote:
 I sent the following patch yesterday - I think it addresses the exact 
 same issue. Please test it to see if it works for you as well.

The patch looks a lot better. I just backported it and it is working
just fine for me.

Benjamin

 Subject: [PATCH 4.0] ath9k: fix tracking of enabled AP beacons
 
 sc-nbcnvifs tracks assigned beacon slots, not enabled beacons.
 Therefore, it cannot be used to decide if cur_conf-enable_beacon (bool)
 should be updated, or if beacons have been enabled already.
 With the current code (depending on the order of calls), beacons often
 do not get enabled in an AP+STA setup.
 To fix tracking of enabled beacons, convert cur_conf-enable_beacon to a
 bitmask of enabled beacon slots.
 
 Cc: sta...@vger.kernel.org
 Signed-off-by: Felix Fietkau n...@openwrt.org
 ---
  drivers/net/wireless/ath/ath9k/beacon.c | 20 
  drivers/net/wireless/ath/ath9k/common.h |  2 +-
  2 files changed, 13 insertions(+), 9 deletions(-)
 
 diff --git a/drivers/net/wireless/ath/ath9k/beacon.c 
 b/drivers/net/wireless/ath/ath9k/beacon.c
 index cb366ad..f50a6bc 100644
 --- a/drivers/net/wireless/ath/ath9k/beacon.c
 +++ b/drivers/net/wireless/ath/ath9k/beacon.c
 @@ -219,12 +219,15 @@ void ath9k_beacon_remove_slot(struct ath_softc *sc, 
 struct ieee80211_vif *vif)
   struct ath_common *common = ath9k_hw_common(sc-sc_ah);
   struct ath_vif *avp = (void *)vif-drv_priv;
   struct ath_buf *bf = avp-av_bcbuf;
 + struct ath_beacon_config *cur_conf = sc-cur_chan-beacon;
  
   ath_dbg(common, CONFIG, Removing interface at beacon slot: %d\n,
   avp-av_bslot);
  
   tasklet_disable(sc-bcon_tasklet);
  
 + cur_conf-enable_beacon = ~BIT(avp-av_bslot);
 +
   if (bf  bf-bf_mpdu) {
   struct sk_buff *skb = bf-bf_mpdu;
   dma_unmap_single(sc-dev, bf-bf_buf_addr,
 @@ -521,8 +524,7 @@ static bool ath9k_allow_beacon_config(struct ath_softc 
 *sc,
   }
  
   if (sc-sc_ah-opmode == NL80211_IFTYPE_AP) {
 - if ((vif-type != NL80211_IFTYPE_AP) ||
 - (sc-nbcnvifs  1)) {
 + if (vif-type != NL80211_IFTYPE_AP) {
   ath_dbg(common, CONFIG,
   An AP interface is already present !\n);
   return false;
 @@ -616,12 +618,14 @@ void ath9k_beacon_config(struct ath_softc *sc, struct 
 ieee80211_vif *vif,
* enabling/disabling SWBA.
*/
   if (changed  BSS_CHANGED_BEACON_ENABLED) {
 - if (!bss_conf-enable_beacon 
 - (sc-nbcnvifs = 1)) {
 - cur_conf-enable_beacon = false;
 - } else if (bss_conf-enable_beacon) {
 - cur_conf-enable_beacon = true;
 - ath9k_cache_beacon_config(sc, ctx, bss_conf);
 + bool enabled = cur_conf-enable_beacon;
 +
 + if (!bss_conf-enable_beacon) {
 + cur_conf-enable_beacon = ~BIT(avp-av_bslot);
 + } else {
 + cur_conf-enable_beacon |= BIT(avp-av_bslot);
 + if (!enabled)
 + ath9k_cache_beacon_config(sc, ctx, bss_conf);
   }
   }
  
 diff --git a/drivers/net/wireless/ath/ath9k/common.h 
 b/drivers/net/wireless/ath/ath9k/common.h
 index 2b79a56..d237373 100644
 --- a/drivers/net/wireless/ath/ath9k/common.h
 +++ b/drivers/net/wireless/ath/ath9k/common.h
 @@ -54,7 +54,7 @@ struct ath_beacon_config {
   u16 dtim_period;
   u16 bmiss_timeout;
   u8 dtim_count;
 - bool enable_beacon;
 + u8 enable_beacon;
   bool ibss_creator;
   u32 nexttbtt;
   u32 intval;
 -- 2.2.2 --
 



signature.asc
Description: This is a digitally signed message part
___
ath9k-devel mailing list
ath9k-devel@lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel


[ath9k-devel] [PATCH] ath9k: Configure beacons for AP vif if this has not happened yet

2015-03-13 Thread Benjamin Berg
Right now there is a bug where beaconing might not be enabled correctly
if the user has configuring multiple VIFs.
The issue surfaces if the userspace first creates the AP devices and
only then configures the first VIF (ath9k_bss_info_changed is called).
In this case the current ath9k_allow_beacon_config implementation will
not allow configuration as multiple AP VIFs are already present and
beaconing is never configured in the driver.

This issue was probably introduced back in 2012 by commit ef4ad6336
ath9k: Cleanup beacon logic. The fix in this patch simply checks
whether beaconing has been configured yet (or configuration is scheduled)
and allows the configuration in that case. This works around the issue
here, but I have no idea whether it is a sane solution.

Signed-off-by: Benjamin Berg benja...@sipsolutions.net
---
 drivers/net/wireless/ath/ath9k/beacon.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/beacon.c 
b/drivers/net/wireless/ath/ath9k/beacon.c
index cb366ad..0eb83b8 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -522,7 +522,8 @@ static bool ath9k_allow_beacon_config(struct ath_softc *sc,
 
if (sc-sc_ah-opmode == NL80211_IFTYPE_AP) {
if ((vif-type != NL80211_IFTYPE_AP) ||
-   (sc-nbcnvifs  1)) {
+   test_bit(ATH_OP_BEACONS, common-op_flags) ||
+   (sc-ps_flags  PS_BEACON_SYNC)) {
ath_dbg(common, CONFIG,
An AP interface is already present !\n);
return false;
-- 
2.1.4

___
ath9k-devel mailing list
ath9k-devel@lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel


[ath9k-devel] [RFC] ath9k: Configure beacons for AP vif if this has not happened yet

2015-03-10 Thread Benjamin Berg
Right now there is a bug where beaconing might not be enabled correctly
if the user has configuring multiple VIFs.
The issue surfaces if the userspace first creates the AP devices and
only then configures the first VIF (ath9k_bss_info_changed is called).
In this case the current ath9k_allow_beacon_config implementation will
not allow configuration as multiple AP VIFs are already present and
beaconing is never configured in the driver.

This issue was probably introduced back in 2012 by commit ef4ad6336
ath9k: Cleanup beacon logic. The fix in this patch simply checks
whether beaconing has been configured yet (or configuration is scheduled)
and allows the configuration in that case. This works around the issue
here, but I have no idea whether it is a sane solution.
---
 drivers/net/wireless/ath/ath9k/beacon.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/beacon.c 
b/drivers/net/wireless/ath/ath9k/beacon.c
index e387f0b..b41d778 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -504,7 +504,8 @@ static bool ath9k_allow_beacon_config(struct ath_softc *sc,
 
if (sc-sc_ah-opmode == NL80211_IFTYPE_AP) {
if ((vif-type != NL80211_IFTYPE_AP) ||
-   (sc-nbcnvifs  1)) {
+   test_bit(ATH_OP_BEACONS, common-op_flags) ||
+   (sc-ps_flags  PS_BEACON_SYNC)) {
ath_dbg(common, CONFIG,
An AP interface is already present !\n);
return false;
-- 
2.1.4

___
ath9k-devel mailing list
ath9k-devel@lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel