2013-02-04 10:09:40

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 1/3] ath9k: Print the negotiated HT capabilities

From: Sujith Manoharan <[email protected]>

Also, reduce the memory allocated for each row.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/rc.c | 12 +++++++++++-
drivers/net/wireless/ath/ath9k/rc.h | 6 ++++++
2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 714558d..62abd70 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -1364,7 +1364,7 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
if (rc->rate_table == NULL)
return 0;

- max = 80 + rc->rate_table_size * 1024 + 1;
+ max = 80 + rc->rate_table_size * 256 + 1;
buf = kmalloc(max, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
@@ -1410,6 +1410,16 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
stats->per);
}

+ if (rc->ht_cap & WLAN_RC_HT_FLAG) {
+ len += snprintf(buf + len, max - len, "\nNegotiated HT caps: ");
+ PR_HT_CAP((rc->ht_cap & WLAN_RC_HT_FLAG), "[HT20]");
+ PR_HT_CAP((rc->ht_cap & WLAN_RC_40_FLAG), "[HT40]");
+ PR_HT_CAP((rc->ht_cap & WLAN_RC_DS_FLAG), "[2-Stream]");
+ PR_HT_CAP((rc->ht_cap & WLAN_RC_TS_FLAG), "[3-Stream]");
+ PR_HT_CAP((rc->ht_cap & WLAN_RC_SGI_FLAG), "[SGI]");
+ len += snprintf(buf + len, max - len, "\n");
+ }
+
if (len > max)
len = max;

diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index 267dbfc..d9089b9 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -131,6 +131,12 @@ enum {
#define WLAN_RC_SGI_FLAG (0x08)
#define WLAN_RC_HT_FLAG (0x10)

+#define PR_HT_CAP(_cond, _str) \
+ do { \
+ if (_cond) \
+ len += snprintf(buf + len, max - len, _str); \
+ } while (0)
+
/**
* struct ath_rate_table - Rate Control table
* @rate_cnt: total number of rates for the given wireless mode
--
1.8.1.2



2013-02-08 20:00:28

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 1/3] ath9k: Print the negotiated HT capabilities

On Fri, Feb 08, 2013 at 07:38:59PM +0530, Sujith Manoharan wrote:
> Sujith Manoharan wrote:
> > From: Sujith Manoharan <[email protected]>
> >
> > Also, reduce the memory allocated for each row.
> >
> > Signed-off-by: Sujith Manoharan <[email protected]>
>
> John, please drop this patch.

Just the "1/3" one? Or the whole series?

John
--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.

2013-02-08 14:10:17

by Sujith Manoharan

[permalink] [raw]
Subject: Re: [PATCH 1/3] ath9k: Print the negotiated HT capabilities

Sujith Manoharan wrote:
> From: Sujith Manoharan <[email protected]>
>
> Also, reduce the memory allocated for each row.
>
> Signed-off-by: Sujith Manoharan <[email protected]>

John, please drop this patch.

Sujith

2013-02-12 09:24:29

by Nicolas Cavallari

[permalink] [raw]
Subject: Re: [PATCH 3/3] ath9k: Fix IBSS joiner mode

On 04/02/2013 11:08, Sujith Manoharan wrote:
> From: Sujith Manoharan <[email protected]>
>
> On joining an existing IBSS network, beaconing has to start
> only after a TSF sync has happened by receiving a beacon from
> the BSS. In creator mode, beaconing can start immediately after
> a HW reset has been done.
>
> Now that mac80211 notifies the driver of the mode type (creator/joiner)
> via ieee80211_bss_conf->ibss_creator, make use of it to properly setup
> the HW beacon timers.
>
> Signed-off-by: Sujith Manoharan <[email protected]>
> ---

Even though my IBSS network isn't as large as it was when i experienced
the most severe problems, i see no stuck beacon now; the network is much
more reliable.

Thanks.

Tested-by: Nicolas Cavallari <[email protected]>

2013-02-04 10:09:41

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 3/3] ath9k: Fix IBSS joiner mode

From: Sujith Manoharan <[email protected]>

On joining an existing IBSS network, beaconing has to start
only after a TSF sync has happened by receiving a beacon from
the BSS. In creator mode, beaconing can start immediately after
a HW reset has been done.

Now that mac80211 notifies the driver of the mode type (creator/joiner)
via ieee80211_bss_conf->ibss_creator, make use of it to properly setup
the HW beacon timers.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ath9k.h | 1 +
drivers/net/wireless/ath/ath9k/beacon.c | 113 ++++++++++++++++++++++++--------
drivers/net/wireless/ath/ath9k/recv.c | 2 +-
3 files changed, 89 insertions(+), 27 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 97c90b2..a56b241 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -389,6 +389,7 @@ struct ath_beacon_config {
u16 bmiss_timeout;
u8 dtim_count;
bool enable_beacon;
+ bool ibss_creator;
};

struct ath_beacon {
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index dd37719..5f05c26 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -407,12 +407,17 @@ void ath9k_beacon_tasklet(unsigned long data)
}
}

-static void ath9k_beacon_init(struct ath_softc *sc, u32 nexttbtt, u32 intval)
+/*
+ * Both nexttbtt and intval have to be in usecs.
+ */
+static void ath9k_beacon_init(struct ath_softc *sc, u32 nexttbtt,
+ u32 intval, bool reset_tsf)
{
struct ath_hw *ah = sc->sc_ah;

ath9k_hw_disable_interrupts(ah);
- ath9k_hw_reset_tsf(ah);
+ if (reset_tsf)
+ ath9k_hw_reset_tsf(ah);
ath9k_beaconq_config(sc);
ath9k_hw_beaconinit(ah, nexttbtt, intval);
sc->beacon.bmisscnt = 0;
@@ -442,10 +447,12 @@ static void ath9k_beacon_config_ap(struct ath_softc *sc,
else
ah->imask &= ~ATH9K_INT_SWBA;

- ath_dbg(common, BEACON, "AP nexttbtt: %u intval: %u conf_intval: %u\n",
+ ath_dbg(common, BEACON,
+ "AP (%s) nexttbtt: %u intval: %u conf_intval: %u\n",
+ (conf->enable_beacon) ? "Enable" : "Disable",
nexttbtt, intval, conf->beacon_interval);

- ath9k_beacon_init(sc, nexttbtt, intval);
+ ath9k_beacon_init(sc, nexttbtt, intval, true);
}

/*
@@ -586,17 +593,45 @@ static void ath9k_beacon_config_adhoc(struct ath_softc *sc,
ath9k_reset_beacon_status(sc);

intval = TU_TO_USEC(conf->beacon_interval);
- nexttbtt = intval;
+
+ if (conf->ibss_creator) {
+ nexttbtt = intval;
+ } else {
+ u32 tbtt, offset, tsftu;
+ u64 tsf;
+
+ /*
+ * Pull nexttbtt forward to reflect the current
+ * sync'd TSF.
+ */
+ tsf = ath9k_hw_gettsf64(ah);
+ tsftu = TSF_TO_TU(tsf >> 32, tsf) + FUDGE;
+ offset = tsftu % conf->beacon_interval;
+ tbtt = tsftu - offset;
+ if (offset)
+ tbtt += conf->beacon_interval;
+
+ nexttbtt = TU_TO_USEC(tbtt);
+ }

if (conf->enable_beacon)
ah->imask |= ATH9K_INT_SWBA;
else
ah->imask &= ~ATH9K_INT_SWBA;

- ath_dbg(common, BEACON, "IBSS nexttbtt: %u intval: %u conf_intval: %u\n",
+ ath_dbg(common, BEACON,
+ "IBSS (%s) nexttbtt: %u intval: %u conf_intval: %u\n",
+ (conf->enable_beacon) ? "Enable" : "Disable",
nexttbtt, intval, conf->beacon_interval);

- ath9k_beacon_init(sc, nexttbtt, intval);
+ ath9k_beacon_init(sc, nexttbtt, intval, conf->ibss_creator);
+
+ /*
+ * Set the global 'beacon has been configured' flag for the
+ * joiner case in IBSS mode.
+ */
+ if (!conf->ibss_creator && conf->enable_beacon)
+ set_bit(SC_OP_BEACONS, &sc->sc_flags);
}

bool ath9k_allow_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
@@ -639,6 +674,7 @@ static void ath9k_cache_beacon_config(struct ath_softc *sc,
cur_conf->dtim_period = bss_conf->dtim_period;
cur_conf->listen_interval = 1;
cur_conf->dtim_count = 1;
+ cur_conf->ibss_creator = bss_conf->ibss_creator;
cur_conf->bmiss_timeout =
ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;

@@ -666,34 +702,59 @@ void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif,
{
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
+ unsigned long flags;
+ bool skip_beacon = false;

if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) {
ath9k_cache_beacon_config(sc, bss_conf);
ath9k_set_beacon(sc);
set_bit(SC_OP_BEACONS, &sc->sc_flags);
- } else {
- /*
- * Take care of multiple interfaces when
- * 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, bss_conf);
- }
+ return;
+
+ }
+
+ /*
+ * Take care of multiple interfaces when
+ * 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, bss_conf);
}
+ }

- if (cur_conf->beacon_interval) {
+ /*
+ * Configure the HW beacon registers only when we have a valid
+ * beacon interval.
+ */
+ if (cur_conf->beacon_interval) {
+ /*
+ * If we are joining an existing IBSS network, start beaconing
+ * only after a TSF-sync has taken place. Ensure that this
+ * happens by setting the appropriate flags.
+ */
+ if ((changed & BSS_CHANGED_IBSS) && !bss_conf->ibss_creator &&
+ bss_conf->enable_beacon) {
+ spin_lock_irqsave(&sc->sc_pm_lock, flags);
+ sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
+ spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
+ skip_beacon = true;
+ } else {
ath9k_set_beacon(sc);
-
- if (cur_conf->enable_beacon)
- set_bit(SC_OP_BEACONS, &sc->sc_flags);
- else
- clear_bit(SC_OP_BEACONS, &sc->sc_flags);
}
+
+ /*
+ * Do not set the SC_OP_BEACONS flag for IBSS joiner mode
+ * here, it is done in ath9k_beacon_config_adhoc().
+ */
+ if (cur_conf->enable_beacon && !skip_beacon)
+ set_bit(SC_OP_BEACONS, &sc->sc_flags);
+ else
+ clear_bit(SC_OP_BEACONS, &sc->sc_flags);
}
}

diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 2d0fd17..ee156e5 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -533,7 +533,7 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
if (sc->ps_flags & PS_BEACON_SYNC) {
sc->ps_flags &= ~PS_BEACON_SYNC;
ath_dbg(common, PS,
- "Reconfigure Beacon timers based on timestamp from the AP\n");
+ "Reconfigure beacon timers based on synchronized timestamp\n");
ath9k_set_beacon(sc);
}

--
1.8.1.2


2013-02-12 09:57:21

by Sujith Manoharan

[permalink] [raw]
Subject: Re: [PATCH 3/3] ath9k: Fix IBSS joiner mode

Nicolas Cavallari wrote:
> Even though my IBSS network isn't as large as it was when i experienced
> the most severe problems, i see no stuck beacon now; the network is much
> more reliable.
>
> Thanks.
>
> Tested-by: Nicolas Cavallari <[email protected]>

Thanks for testing !

Sujith

2013-02-04 10:09:40

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 2/3] ath9k: Fix ATH9K_HW_CAP_HT usage

From: Sujith Manoharan <[email protected]>

There are a few places where the station's HT capabilities
should be checked instead of ATH9K_HW_CAP_HT, which is a global
feature for the driver. Fix this.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/main.c | 13 +++++--------
drivers/net/wireless/ath/ath9k/xmit.c | 5 ++---
2 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 5432f12..6e66f9c 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -320,28 +320,25 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
struct ieee80211_vif *vif)
{
struct ath_node *an;
- u8 density;
an = (struct ath_node *)sta->drv_priv;

an->sc = sc;
an->sta = sta;
an->vif = vif;

- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
- ath_tx_node_init(sc, an);
+ ath_tx_node_init(sc, an);
+
+ if (sta->ht_cap.ht_supported) {
an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
sta->ht_cap.ampdu_factor);
- density = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density);
- an->mpdudensity = density;
+ an->mpdudensity = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density);
}
}

static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
{
struct ath_node *an = (struct ath_node *)sta->drv_priv;
-
- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
- ath_tx_node_cleanup(sc, an);
+ ath_tx_node_cleanup(sc, an);
}

void ath9k_tasklet(unsigned long data)
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index feacaaf..89a6441 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1233,7 +1233,7 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
* in HT IBSS when a beacon with HT-info is received after the station
* has already been added.
*/
- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
+ if (sta->ht_cap.ht_supported) {
an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
sta->ht_cap.ampdu_factor);
density = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density);
@@ -1904,8 +1904,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
struct ath_buf *bf;
u8 tidno;

- if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) && txctl->an &&
- ieee80211_is_data_qos(hdr->frame_control)) {
+ if (txctl->an && ieee80211_is_data_qos(hdr->frame_control)) {
tidno = ieee80211_get_qos_ctl(hdr)[0] &
IEEE80211_QOS_CTL_TID_MASK;
tid = ATH_AN_2_TID(txctl->an, tidno);
--
1.8.1.2


2013-02-09 02:28:41

by Sujith Manoharan

[permalink] [raw]
Subject: Re: [PATCH 1/3] ath9k: Print the negotiated HT capabilities

John W. Linville wrote:
> > John, please drop this patch.
>
> Just the "1/3" one? Or the whole series?

Just this one, the other 2 patches can be applied.

Sujith