All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/4] ath9k patches
@ 2014-10-08  3:13 Sujith Manoharan
  2014-10-08  3:13 ` [PATCH v3 1/4] ath9k: Fix sequence number assignment Sujith Manoharan
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Sujith Manoharan @ 2014-10-08  3:13 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless, ath9k-devel

From: Sujith Manoharan <c_manoha@qca.qualcomm.com>

v3: Fix compilation error when TX99 is enabled.

Sujith Manoharan (4):
  ath9k: Fix sequence number assignment
  ath9k: Use sta_state() callback
  ath9k: Enable multi-channel properly
  ath9k: Process beacons properly

 drivers/net/wireless/ath/ath9k/ath9k.h   |  6 +++--
 drivers/net/wireless/ath/ath9k/beacon.c  | 12 ++--------
 drivers/net/wireless/ath/ath9k/channel.c | 11 ++++++---
 drivers/net/wireless/ath/ath9k/main.c    | 41 +++++++++++++++++++++++++-------
 drivers/net/wireless/ath/ath9k/tx99.c    |  8 ++++++-
 drivers/net/wireless/ath/ath9k/xmit.c    | 34 +++++++++++++++++---------
 6 files changed, 77 insertions(+), 35 deletions(-)

-- 
2.1.2


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v3 1/4] ath9k: Fix sequence number assignment
  2014-10-08  3:13 [PATCH v3 0/4] ath9k patches Sujith Manoharan
@ 2014-10-08  3:13 ` Sujith Manoharan
  2014-10-08  3:13 ` [PATCH v3 2/4] ath9k: Use sta_state() callback Sujith Manoharan
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Sujith Manoharan @ 2014-10-08  3:13 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless, ath9k-devel

From: Sujith Manoharan <c_manoha@qca.qualcomm.com>

Currently, ath9k uses a global counter for all
frames that need to be assigned a sequence number.
QoS-data frames are handled properly since they
have a per-tid counter. But, beacons and other
management frames use the same counter even if
multiple interfaces or contexts are present.

Fix this issue by making the counter per-interface
and using it when mac80211 sets IEEE80211_TX_CTL_ASSIGN_SEQ.

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h  |  4 +++-
 drivers/net/wireless/ath/ath9k/beacon.c | 12 ++----------
 drivers/net/wireless/ath/ath9k/tx99.c   |  8 +++++++-
 drivers/net/wireless/ath/ath9k/xmit.c   | 34 ++++++++++++++++++++++-----------
 4 files changed, 35 insertions(+), 23 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index bfa0b15..01a7db0 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -294,7 +294,6 @@ struct ath_tx_control {
  *  (axq_qnum).
  */
 struct ath_tx {
-	u16 seq_no;
 	u32 txqsetup;
 	spinlock_t txbuflock;
 	struct list_head txbuf;
@@ -563,6 +562,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs);
 int ath_txq_update(struct ath_softc *sc, int qnum,
 		   struct ath9k_tx_queue_info *q);
 void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop);
+void ath_assign_seq(struct ath_common *common, struct sk_buff *skb);
 int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
 		 struct ath_tx_control *txctl);
 void ath_tx_cabq(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
@@ -592,6 +592,8 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
 struct ath_vif {
 	struct list_head list;
 
+	u16 seq_no;
+
 	/* BSS info */
 	u8 bssid[ETH_ALEN];
 	u16 aid;
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index a6af855..ecb783b 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -144,16 +144,8 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,
 	mgmt_hdr->u.beacon.timestamp = avp->tsf_adjust;
 
 	info = IEEE80211_SKB_CB(skb);
-	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-		/*
-		 * TODO: make sure the seq# gets assigned properly (vs. other
-		 * TX frames)
-		 */
-		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-		sc->tx.seq_no += 0x10;
-		hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
-		hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
-	}
+
+	ath_assign_seq(common, skb);
 
 	if (vif->p2p)
 		ath9k_beacon_add_noa(sc, avp, skb);
diff --git a/drivers/net/wireless/ath/ath9k/tx99.c b/drivers/net/wireless/ath/ath9k/tx99.c
index 8a69d08..40ab65e 100644
--- a/drivers/net/wireless/ath/ath9k/tx99.c
+++ b/drivers/net/wireless/ath/ath9k/tx99.c
@@ -54,6 +54,12 @@ static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc)
 	struct ieee80211_hdr *hdr;
 	struct ieee80211_tx_info *tx_info;
 	struct sk_buff *skb;
+	struct ath_vif *avp;
+
+	if (!sc->tx99_vif)
+		return NULL;
+
+	avp = (struct ath_vif *)sc->tx99_vif->drv_priv;
 
 	skb = alloc_skb(len, GFP_KERNEL);
 	if (!skb)
@@ -71,7 +77,7 @@ static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc)
 	memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
 	memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
 
-	hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
+	hdr->seq_ctrl |= cpu_to_le16(avp->seq_no);
 
 	tx_info = IEEE80211_SKB_CB(skb);
 	memset(tx_info, 0, sizeof(*tx_info));
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 151ae49..493a183 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -2139,6 +2139,28 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
 	return bf;
 }
 
+void ath_assign_seq(struct ath_common *common, struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_vif *vif = info->control.vif;
+	struct ath_vif *avp;
+
+	if (!(info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ))
+		return;
+
+	if (!vif)
+		return;
+
+	avp = (struct ath_vif *)vif->drv_priv;
+
+	if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
+		avp->seq_no += 0x10;
+
+	hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+	hdr->seq_ctrl |= cpu_to_le16(avp->seq_no);
+}
+
 static int ath_tx_prepare(struct ieee80211_hw *hw, struct sk_buff *skb,
 			  struct ath_tx_control *txctl)
 {
@@ -2162,17 +2184,7 @@ static int ath_tx_prepare(struct ieee80211_hw *hw, struct sk_buff *skb,
 	if (info->control.hw_key)
 		frmlen += info->control.hw_key->icv_len;
 
-	/*
-	 * As a temporary workaround, assign seq# here; this will likely need
-	 * to be cleaned up to work better with Beacon transmission and virtual
-	 * BSSes.
-	 */
-	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-		if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
-			sc->tx.seq_no += 0x10;
-		hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
-		hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
-	}
+	ath_assign_seq(ath9k_hw_common(sc->sc_ah), skb);
 
 	if ((vif && vif->type != NL80211_IFTYPE_AP &&
 	            vif->type != NL80211_IFTYPE_AP_VLAN) ||
-- 
2.1.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v3 2/4] ath9k: Use sta_state() callback
  2014-10-08  3:13 [PATCH v3 0/4] ath9k patches Sujith Manoharan
  2014-10-08  3:13 ` [PATCH v3 1/4] ath9k: Fix sequence number assignment Sujith Manoharan
@ 2014-10-08  3:13 ` Sujith Manoharan
  2014-10-08  3:13 ` [PATCH v3 3/4] ath9k: Enable multi-channel properly Sujith Manoharan
  2014-10-08  3:13 ` [PATCH v3 4/4] ath9k: Process beacons properly Sujith Manoharan
  3 siblings, 0 replies; 5+ messages in thread
From: Sujith Manoharan @ 2014-10-08  3:13 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless, ath9k-devel

From: Sujith Manoharan <c_manoha@qca.qualcomm.com>

Instead of using the sta_add()/sta_remove() callbacks,
use the sta_state() callback since this gives
more fine-grained control.

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/main.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 6f6a974..902807e 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1547,6 +1547,31 @@ static int ath9k_sta_remove(struct ieee80211_hw *hw,
 	return 0;
 }
 
+static int ath9k_sta_state(struct ieee80211_hw *hw,
+			   struct ieee80211_vif *vif,
+			   struct ieee80211_sta *sta,
+			   enum ieee80211_sta_state old_state,
+			   enum ieee80211_sta_state new_state)
+{
+	struct ath_softc *sc = hw->priv;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	int ret = 0;
+
+	if (old_state == IEEE80211_STA_AUTH &&
+	    new_state == IEEE80211_STA_ASSOC) {
+		ret = ath9k_sta_add(hw, vif, sta);
+		ath_dbg(common, CONFIG,
+			"Add station: %pM\n", sta->addr);
+	} else if (old_state == IEEE80211_STA_ASSOC &&
+		   new_state == IEEE80211_STA_AUTH) {
+		ret = ath9k_sta_remove(hw, vif, sta);
+		ath_dbg(common, CONFIG,
+			"Remove station: %pM\n", sta->addr);
+	}
+
+	return ret;
+}
+
 static void ath9k_sta_set_tx_filter(struct ath_hw *ah,
 				    struct ath_node *an,
 				    bool set)
@@ -2471,8 +2496,7 @@ struct ieee80211_ops ath9k_ops = {
 	.remove_interface   = ath9k_remove_interface,
 	.config 	    = ath9k_config,
 	.configure_filter   = ath9k_configure_filter,
-	.sta_add	    = ath9k_sta_add,
-	.sta_remove	    = ath9k_sta_remove,
+	.sta_state          = ath9k_sta_state,
 	.sta_notify         = ath9k_sta_notify,
 	.conf_tx 	    = ath9k_conf_tx,
 	.bss_info_changed   = ath9k_bss_info_changed,
-- 
2.1.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v3 3/4] ath9k: Enable multi-channel properly
  2014-10-08  3:13 [PATCH v3 0/4] ath9k patches Sujith Manoharan
  2014-10-08  3:13 ` [PATCH v3 1/4] ath9k: Fix sequence number assignment Sujith Manoharan
  2014-10-08  3:13 ` [PATCH v3 2/4] ath9k: Use sta_state() callback Sujith Manoharan
@ 2014-10-08  3:13 ` Sujith Manoharan
  2014-10-08  3:13 ` [PATCH v3 4/4] ath9k: Process beacons properly Sujith Manoharan
  3 siblings, 0 replies; 5+ messages in thread
From: Sujith Manoharan @ 2014-10-08  3:13 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless, ath9k-devel

From: Sujith Manoharan <c_manoha@qca.qualcomm.com>

In MCC mode, currently the decision to enable
the multi-channel state machine is done
based on the association status if one of
the interfaces assigned to a context is in
station mode.

This allows the driver to switch to the other
context before the current station is able to
complete the 4-way handshake in case it is
required and this causes problems.

Instead, enable multi-channel mode when the
station moves to the authorized state. This
disallows an early switch to the other channel.

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h   |  2 +-
 drivers/net/wireless/ath/ath9k/channel.c |  4 ++--
 drivers/net/wireless/ath/ath9k/main.c    | 13 +++++++------
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 01a7db0..aff5e4c 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -362,7 +362,7 @@ enum ath_chanctx_event {
 	ATH_CHANCTX_EVENT_BEACON_SENT,
 	ATH_CHANCTX_EVENT_TSF_TIMER,
 	ATH_CHANCTX_EVENT_BEACON_RECEIVED,
-	ATH_CHANCTX_EVENT_ASSOC,
+	ATH_CHANCTX_EVENT_AUTHORIZED,
 	ATH_CHANCTX_EVENT_SWITCH,
 	ATH_CHANCTX_EVENT_ASSIGN,
 	ATH_CHANCTX_EVENT_UNASSIGN,
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
index 945c898..16bed6a 100644
--- a/drivers/net/wireless/ath/ath9k/channel.c
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -171,7 +171,7 @@ static const char *chanctx_event_string(enum ath_chanctx_event ev)
 		case_rtn_string(ATH_CHANCTX_EVENT_BEACON_SENT);
 		case_rtn_string(ATH_CHANCTX_EVENT_TSF_TIMER);
 		case_rtn_string(ATH_CHANCTX_EVENT_BEACON_RECEIVED);
-		case_rtn_string(ATH_CHANCTX_EVENT_ASSOC);
+		case_rtn_string(ATH_CHANCTX_EVENT_AUTHORIZED);
 		case_rtn_string(ATH_CHANCTX_EVENT_SWITCH);
 		case_rtn_string(ATH_CHANCTX_EVENT_ASSIGN);
 		case_rtn_string(ATH_CHANCTX_EVENT_UNASSIGN);
@@ -510,7 +510,7 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif,
 
 		ath_chanctx_setup_timer(sc, tsf_time);
 		break;
-	case ATH_CHANCTX_EVENT_ASSOC:
+	case ATH_CHANCTX_EVENT_AUTHORIZED:
 		if (sc->sched.state != ATH_CHANCTX_STATE_FORCE_ACTIVE ||
 		    avp->chanctx != sc->cur_chan)
 			break;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 902807e..446bc46 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1569,6 +1569,13 @@ static int ath9k_sta_state(struct ieee80211_hw *hw,
 			"Remove station: %pM\n", sta->addr);
 	}
 
+	if (ath9k_is_chanctx_enabled()) {
+		if (old_state == IEEE80211_STA_ASSOC &&
+		    new_state == IEEE80211_STA_AUTHORIZED)
+			ath_chanctx_event(sc, vif,
+					  ATH_CHANCTX_EVENT_AUTHORIZED);
+	}
+
 	return ret;
 }
 
@@ -1761,12 +1768,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
 		avp->assoc = bss_conf->assoc;
 
 		ath9k_calculate_summary_state(sc, avp->chanctx);
-
-		if (ath9k_is_chanctx_enabled()) {
-			if (bss_conf->assoc)
-				ath_chanctx_event(sc, vif,
-						  ATH_CHANCTX_EVENT_ASSOC);
-		}
 	}
 
 	if (changed & BSS_CHANGED_IBSS) {
-- 
2.1.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v3 4/4] ath9k: Process beacons properly
  2014-10-08  3:13 [PATCH v3 0/4] ath9k patches Sujith Manoharan
                   ` (2 preceding siblings ...)
  2014-10-08  3:13 ` [PATCH v3 3/4] ath9k: Enable multi-channel properly Sujith Manoharan
@ 2014-10-08  3:13 ` Sujith Manoharan
  3 siblings, 0 replies; 5+ messages in thread
From: Sujith Manoharan @ 2014-10-08  3:13 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless, ath9k-devel

From: Sujith Manoharan <c_manoha@qca.qualcomm.com>

When the current operating channel context has
been marked as ATH_CHANCTX_STATE_FORCE_ACTIVE,
do not process beacons that might be received,
since we have to wait for the station to become
authorized.

Also, since the cached TSF value will be zero
initially do not rearm the timer in this
case when a beacon is received, since it results
in spurious values.

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/channel.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
index 16bed6a..135f74c 100644
--- a/drivers/net/wireless/ath/ath9k/channel.c
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -495,10 +495,15 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif,
 		    sc->cur_chan == &sc->offchannel.chan)
 			break;
 
-		ath_chanctx_adjust_tbtt_delta(sc);
 		sc->sched.beacon_pending = false;
 		sc->sched.beacon_miss = 0;
 
+		if (sc->sched.state == ATH_CHANCTX_STATE_FORCE_ACTIVE ||
+		    !sc->cur_chan->tsf_val)
+			break;
+
+		ath_chanctx_adjust_tbtt_delta(sc);
+
 		/* TSF time might have been updated by the incoming beacon,
 		 * need update the channel switch timer to reflect the change.
 		 */
-- 
2.1.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-10-08  3:12 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-08  3:13 [PATCH v3 0/4] ath9k patches Sujith Manoharan
2014-10-08  3:13 ` [PATCH v3 1/4] ath9k: Fix sequence number assignment Sujith Manoharan
2014-10-08  3:13 ` [PATCH v3 2/4] ath9k: Use sta_state() callback Sujith Manoharan
2014-10-08  3:13 ` [PATCH v3 3/4] ath9k: Enable multi-channel properly Sujith Manoharan
2014-10-08  3:13 ` [PATCH v3 4/4] ath9k: Process beacons properly Sujith Manoharan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.