From fbbcd14690d3c42b664740d58a22af50a77d5689 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Jun 2014 16:17:49 +0530 Subject: ath9k: Add channel context structure The channel context structure is defined to enable multi-channel concurrency support. Signed-off-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 2ca8f7e06174..8c87eb7fb6de 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -325,6 +325,16 @@ struct ath_rx { u32 ampdu_ref; }; +struct ath_chanctx { + struct cfg80211_chan_def chandef; + struct list_head vifs; + bool offchannel; +}; + +void ath_chanctx_init(struct ath_softc *sc); +int ath_chanctx_set_channel(struct ath_softc *sc, struct ath_chanctx *ctx, + struct cfg80211_chan_def *chandef); +int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan); int ath_startrecv(struct ath_softc *sc); bool ath_stoprecv(struct ath_softc *sc); u32 ath_calcrxfilter(struct ath_softc *sc); @@ -370,12 +380,15 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw, /********/ struct ath_vif { + struct list_head list; + struct ieee80211_vif *vif; struct ath_node mcast_node; int av_bslot; bool primary_sta_vif; __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ struct ath_buf *av_bcbuf; + struct ath_chanctx *chanctx; /* P2P Client */ struct ieee80211_noa_data noa; @@ -702,6 +715,8 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs); #define PS_BEACON_SYNC BIT(4) #define PS_WAIT_FOR_ANI BIT(5) +#define ATH9K_NUM_CHANCTX 2 /* supports 2 operating channels */ + struct ath_softc { struct ieee80211_hw *hw; struct device *dev; @@ -743,6 +758,9 @@ struct ath_softc { struct ath_tx tx; struct ath_beacon beacon; + struct ath_chanctx chanctx[ATH9K_NUM_CHANCTX]; + struct ath_chanctx *cur_chan; + #ifdef CONFIG_MAC80211_LEDS bool led_registered; char led_name[32]; -- cgit v1.2.3 From bc7e1be70c9f1c6de622aa14baa62003342034bb Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Jun 2014 16:17:50 +0530 Subject: ath9k: Move txpower limit to channel context Signed-off-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 8c87eb7fb6de..b6f6444d109e 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -36,10 +36,6 @@ extern int ath9k_modparam_nohwcrypt; extern int led_blink; extern bool is_ath9k_unloaded; -struct ath_config { - u16 txpowlimit; -}; - /*************************/ /* Descriptor Management */ /*************************/ @@ -328,6 +324,7 @@ struct ath_rx { struct ath_chanctx { struct cfg80211_chan_def chandef; struct list_head vifs; + u16 txpower; bool offchannel; }; @@ -753,7 +750,6 @@ struct ath_softc { short nvifs; unsigned long ps_usecount; - struct ath_config config; struct ath_rx rx; struct ath_tx tx; struct ath_beacon beacon; -- cgit v1.2.3 From 0453531e2eae61c5c0a2af7b67cdafd19c0dce68 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Jun 2014 16:17:51 +0530 Subject: ath9k: Move acq to channel context Add support to maintain per-channel ACs list. Signed-off-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index b6f6444d109e..198cca38c24b 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -163,7 +163,6 @@ struct ath_txq { u32 axq_ampdu_depth; bool stopped; bool axq_tx_inprogress; - struct list_head axq_acq; struct list_head txq_fifo[ATH_TXFIFO_DEPTH]; u8 txq_headidx; u8 txq_tailidx; @@ -324,6 +323,8 @@ struct ath_rx { struct ath_chanctx { struct cfg80211_chan_def chandef; struct list_head vifs; + struct list_head acq[IEEE80211_NUM_ACS]; + u16 txpower; bool offchannel; }; @@ -348,6 +349,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq); void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an); void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); +void ath_txq_schedule_all(struct ath_softc *sc); 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); -- cgit v1.2.3 From bff117669841c04d08bd1d23617818e0030b3299 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Jun 2014 16:17:52 +0530 Subject: ath9k: Add channel context worker thread The channel context worker is used to switch to next requested channel context. Signed-off-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 198cca38c24b..8f59cea33fd6 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -327,11 +327,14 @@ struct ath_chanctx { u16 txpower; bool offchannel; + bool stopped; }; void ath_chanctx_init(struct ath_softc *sc); -int ath_chanctx_set_channel(struct ath_softc *sc, struct ath_chanctx *ctx, - struct cfg80211_chan_def *chandef); +void ath_chanctx_set_channel(struct ath_softc *sc, struct ath_chanctx *ctx, + struct cfg80211_chan_def *chandef); +void ath_chanctx_switch(struct ath_softc *sc, struct ath_chanctx *ctx, + struct cfg80211_chan_def *chandef); int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan); int ath_startrecv(struct ath_softc *sc); bool ath_stoprecv(struct ath_softc *sc); @@ -470,6 +473,7 @@ void ath9k_csa_update(struct ath_softc *sc); #define ATH_PAPRD_TIMEOUT 100 /* msecs */ #define ATH_PLL_WORK_INTERVAL 100 +void ath_chanctx_work(struct work_struct *work); void ath_tx_complete_poll_work(struct work_struct *work); void ath_reset_work(struct work_struct *work); bool ath_hw_check(struct ath_softc *sc); @@ -485,6 +489,7 @@ void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type); void ath_ps_full_sleep(unsigned long data); void ath9k_p2p_ps_timer(void *priv); void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif); +void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop); /**********/ /* BTCOEX */ @@ -734,6 +739,7 @@ struct ath_softc { struct mutex mutex; struct work_struct paprd_work; struct work_struct hw_reset_work; + struct work_struct chanctx_work; struct completion paprd_complete; wait_queue_head_t tx_wait; @@ -756,8 +762,11 @@ struct ath_softc { struct ath_tx tx; struct ath_beacon beacon; + struct cfg80211_chan_def cur_chandef; struct ath_chanctx chanctx[ATH9K_NUM_CHANCTX]; struct ath_chanctx *cur_chan; + struct ath_chanctx *next_chan; + spinlock_t chan_lock; #ifdef CONFIG_MAC80211_LEDS bool led_registered; -- cgit v1.2.3 From befcf7e70e899db62307408259c51e0435bd9b3f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Jun 2014 16:17:53 +0530 Subject: ath9k: channel context based transmission Force queueing of all frames that belong to a virtual interface on a different channel context, to ensure that they are sent on the correct channel. Signed-off-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 8f59cea33fd6..ddd2e81ccd58 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -275,8 +275,9 @@ struct ath_node { struct ath_tx_control { struct ath_txq *txq; struct ath_node *an; - u8 paprd; struct ieee80211_sta *sta; + u8 paprd; + bool force_channel; }; -- cgit v1.2.3 From c083ce9980109065297aa2171d18980a0ac92bb9 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Jun 2014 16:17:54 +0530 Subject: ath9k: send powersave frame on channel switch While leaving from or entering to active channel context, send out nullfunc frame to inform to the AP about the presence of station. Signed-off-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index ddd2e81ccd58..d5a586bbab7c 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -329,6 +329,7 @@ struct ath_chanctx { u16 txpower; bool offchannel; bool stopped; + bool active; }; void ath_chanctx_init(struct ath_softc *sc); @@ -336,6 +337,8 @@ void ath_chanctx_set_channel(struct ath_softc *sc, struct ath_chanctx *ctx, struct cfg80211_chan_def *chandef); void ath_chanctx_switch(struct ath_softc *sc, struct ath_chanctx *ctx, struct cfg80211_chan_def *chandef); +void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx); + int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan); int ath_startrecv(struct ath_softc *sc); bool ath_stoprecv(struct ath_softc *sc); -- cgit v1.2.3 From 78b21949711ee3c877f1aab5b51abe1981e1161d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Jun 2014 16:17:55 +0530 Subject: ath9k: Implement hw_scan support Implement hw_scan support for enabling multi-channel cuncurrency. Signed-off-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index d5a586bbab7c..d6b0c4e55c95 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -35,6 +35,7 @@ extern struct ieee80211_ops ath9k_ops; extern int ath9k_modparam_nohwcrypt; extern int led_blink; extern bool is_ath9k_unloaded; +extern int ath9k_use_chanctx; /*************************/ /* Descriptor Management */ @@ -332,12 +333,34 @@ struct ath_chanctx { bool active; }; +enum ath_offchannel_state { + ATH_OFFCHANNEL_IDLE, + ATH_OFFCHANNEL_PROBE_SEND, + ATH_OFFCHANNEL_PROBE_WAIT, + ATH_OFFCHANNEL_SUSPEND, +}; + +struct ath_offchannel { + struct ath_chanctx chan; + struct timer_list timer; + struct cfg80211_scan_request *scan_req; + struct ieee80211_vif *scan_vif; + int scan_idx; + enum ath_offchannel_state state; +}; + +void ath9k_fill_chanctx_ops(void); void ath_chanctx_init(struct ath_softc *sc); void ath_chanctx_set_channel(struct ath_softc *sc, struct ath_chanctx *ctx, struct cfg80211_chan_def *chandef); void ath_chanctx_switch(struct ath_softc *sc, struct ath_chanctx *ctx, struct cfg80211_chan_def *chandef); void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx); +void ath_offchannel_timer(unsigned long data); +void ath_offchannel_channel_change(struct ath_softc *sc); +void ath_chanctx_offchan_switch(struct ath_softc *sc, + struct ieee80211_channel *chan); +struct ath_chanctx *ath_chanctx_get_oper_chan(struct ath_softc *sc); int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan); int ath_startrecv(struct ath_softc *sc); @@ -771,6 +794,7 @@ struct ath_softc { struct ath_chanctx *cur_chan; struct ath_chanctx *next_chan; spinlock_t chan_lock; + struct ath_offchannel offchannel; #ifdef CONFIG_MAC80211_LEDS bool led_registered; -- cgit v1.2.3 From 405393cfde07781c21cdee28b145919d6dfe382e Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Jun 2014 16:17:56 +0530 Subject: ath9k: Implement remain-on-channal support Add remain on channel support in order to enable multi-channel concurrency. Signed-off-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index d6b0c4e55c95..a8ae3e9b49fa 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -338,6 +338,9 @@ enum ath_offchannel_state { ATH_OFFCHANNEL_PROBE_SEND, ATH_OFFCHANNEL_PROBE_WAIT, ATH_OFFCHANNEL_SUSPEND, + ATH_OFFCHANNEL_ROC_START, + ATH_OFFCHANNEL_ROC_WAIT, + ATH_OFFCHANNEL_ROC_DONE, }; struct ath_offchannel { @@ -347,6 +350,9 @@ struct ath_offchannel { struct ieee80211_vif *scan_vif; int scan_idx; enum ath_offchannel_state state; + struct ieee80211_channel *roc_chan; + struct ieee80211_vif *roc_vif; + int roc_duration; }; void ath9k_fill_chanctx_ops(void); -- cgit v1.2.3 From 3930563570d3714420a2ebe0324a917ff64e0422 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Jun 2014 16:17:57 +0530 Subject: ath9k: Implement channel context ops Add channel context operations (add, remove, change, assign and unassign) to enable support for multiple channels. Signed-off-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index a8ae3e9b49fa..eae1830ad33f 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -331,6 +331,7 @@ struct ath_chanctx { bool offchannel; bool stopped; bool active; + bool assigned; }; enum ath_offchannel_state { @@ -356,6 +357,12 @@ struct ath_offchannel { }; void ath9k_fill_chanctx_ops(void); +static inline struct ath_chanctx * +ath_chanctx_get(struct ieee80211_chanctx_conf *ctx) +{ + struct ath_chanctx **ptr = (void *) ctx->drv_priv; + return *ptr; +} void ath_chanctx_init(struct ath_softc *sc); void ath_chanctx_set_channel(struct ath_softc *sc, struct ath_chanctx *ctx, struct cfg80211_chan_def *chandef); -- cgit v1.2.3 From c4dc0d040e356efc0263e0b27181b05f9ef33e5f Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 11 Jun 2014 16:17:58 +0530 Subject: ath9k: Fetch appropriate operating channel context Retrieve appropriate operating channel context while switching between operating and off channels. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index eae1830ad33f..3db489824261 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -355,6 +355,10 @@ struct ath_offchannel { struct ieee80211_vif *roc_vif; int roc_duration; }; +#define ath_for_each_chanctx(_sc, _ctx) \ + for (ctx = &sc->chanctx[0]; \ + ctx <= &sc->chanctx[ARRAY_SIZE(sc->chanctx) - 1]; \ + ctx++) void ath9k_fill_chanctx_ops(void); static inline struct ath_chanctx * @@ -373,7 +377,8 @@ void ath_offchannel_timer(unsigned long data); void ath_offchannel_channel_change(struct ath_softc *sc); void ath_chanctx_offchan_switch(struct ath_softc *sc, struct ieee80211_channel *chan); -struct ath_chanctx *ath_chanctx_get_oper_chan(struct ath_softc *sc); +struct ath_chanctx *ath_chanctx_get_oper_chan(struct ath_softc *sc, + bool active); int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan); int ath_startrecv(struct ath_softc *sc); -- cgit v1.2.3 From b01459e856cbe9ccf64dde251aec02eae60094ce Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Jun 2014 16:17:59 +0530 Subject: ath9k: Move caldata into channel context Signed-off-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 3db489824261..ffacbf6e9f52 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -327,6 +327,8 @@ struct ath_chanctx { struct list_head vifs; struct list_head acq[IEEE80211_NUM_ACS]; + struct ath9k_hw_cal_data caldata; + u16 txpower; bool offchannel; bool stopped; @@ -820,8 +822,6 @@ struct ath_softc { struct led_classdev led_cdev; #endif - struct ath9k_hw_cal_data caldata; - #ifdef CONFIG_ATH9K_DEBUGFS struct ath9k_debug debug; #endif -- cgit v1.2.3 From 8d7e09dda8214e4154f45238b4c85ab1ecb5d89a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Jun 2014 16:18:01 +0530 Subject: ath9k: save tsf in channel context Save TSF in channel context for multiple operating channels. Signed-off-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index ffacbf6e9f52..4df412b71680 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -22,6 +22,7 @@ #include #include #include +#include #include "common.h" #include "debug.h" @@ -328,6 +329,8 @@ struct ath_chanctx { struct list_head acq[IEEE80211_NUM_ACS]; struct ath9k_hw_cal_data caldata; + struct timespec tsf_ts; + u64 tsf_val; u16 txpower; bool offchannel; -- cgit v1.2.3 From ca900ac9d9f0e38782f5a24e64b05f607fd6eb4c Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 11 Jun 2014 16:18:02 +0530 Subject: ath9k: Move beacon config to channel context Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 4df412b71680..d632f8f2a72c 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -328,6 +328,7 @@ struct ath_chanctx { struct list_head vifs; struct list_head acq[IEEE80211_NUM_ACS]; + struct ath_beacon_config beacon; struct ath9k_hw_cal_data caldata; struct timespec tsf_ts; u64 tsf_val; @@ -828,7 +829,6 @@ struct ath_softc { #ifdef CONFIG_ATH9K_DEBUGFS struct ath9k_debug debug; #endif - struct ath_beacon_config cur_beacon_conf; struct delayed_work tx_complete_work; struct delayed_work hw_pll_work; struct timer_list sleep_timer; -- cgit v1.2.3 From 9a9c4fbc3fcabc0d510600743204f890ebdbb141 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 11 Jun 2014 16:18:03 +0530 Subject: ath9k: Summarize hw state per channel context Group and set hw state (opmode, primary_sta, beacon conf) per channel context instead of whole list of vifs. This would allow each channel context to run in different mode (STA/AP). Signed-off-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index d632f8f2a72c..a0c7279e4364 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -328,6 +328,9 @@ struct ath_chanctx { struct list_head vifs; struct list_head acq[IEEE80211_NUM_ACS]; + /* do not dereference, use for comparison only */ + struct ieee80211_vif *primary_sta; + struct ath_beacon_config beacon; struct ath9k_hw_cal_data caldata; struct timespec tsf_ts; @@ -438,7 +441,6 @@ struct ath_vif { struct ieee80211_vif *vif; struct ath_node mcast_node; int av_bslot; - bool primary_sta_vif; __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ struct ath_buf *av_bcbuf; struct ath_chanctx *chanctx; @@ -451,17 +453,22 @@ struct ath9k_vif_iter_data { u8 hw_macaddr[ETH_ALEN]; /* address of the first vif */ u8 mask[ETH_ALEN]; /* bssid mask */ bool has_hw_macaddr; + u8 slottime; + bool beacons; int naps; /* number of AP vifs */ int nmeshes; /* number of mesh vifs */ int nstations; /* number of station vifs */ int nwds; /* number of WDS vifs */ int nadhocs; /* number of adhoc vifs */ + struct ieee80211_vif *primary_sta; }; -void ath9k_calculate_iter_data(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, +void ath9k_calculate_iter_data(struct ath_softc *sc, + struct ath_chanctx *ctx, struct ath9k_vif_iter_data *iter_data); +void ath9k_calculate_summary_state(struct ath_softc *sc, + struct ath_chanctx *ctx); /*******************/ /* Beacon Handling */ -- cgit v1.2.3 From 748299f27b21c23ba963df4768abb2344fe6e9a7 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Jun 2014 16:18:04 +0530 Subject: ath9k: switch channel context for beaconing Add a basic state machine for switch channel context for beacon transmission. Signed-off-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index a0c7279e4364..b657115d1eb7 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -341,6 +341,28 @@ struct ath_chanctx { bool stopped; bool active; bool assigned; + bool switch_after_beacon; +}; + +enum ath_chanctx_event { + ATH_CHANCTX_EVENT_BEACON_PREPARE, + ATH_CHANCTX_EVENT_BEACON_SENT, + ATH_CHANCTX_EVENT_TSF_TIMER, +}; + +enum ath_chanctx_state { + ATH_CHANCTX_STATE_IDLE, + ATH_CHANCTX_STATE_WAIT_FOR_BEACON, + ATH_CHANCTX_STATE_WAIT_FOR_TIMER, + ATH_CHANCTX_STATE_SWITCH, +}; + +struct ath_chanctx_sched { + bool beacon_pending; + enum ath_chanctx_state state; + + u32 next_tbtt; + unsigned int channel_switch_time; }; enum ath_offchannel_state { @@ -388,6 +410,8 @@ void ath_chanctx_offchan_switch(struct ath_softc *sc, struct ieee80211_channel *chan); struct ath_chanctx *ath_chanctx_get_oper_chan(struct ath_softc *sc, bool active); +void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, + enum ath_chanctx_event ev); int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan); int ath_startrecv(struct ath_softc *sc); @@ -826,6 +850,7 @@ struct ath_softc { struct ath_chanctx *next_chan; spinlock_t chan_lock; struct ath_offchannel offchannel; + struct ath_chanctx_sched sched; #ifdef CONFIG_MAC80211_LEDS bool led_registered; -- cgit v1.2.3 From ea6ff2de5c56f6b0c08717f6cc47281b52504e81 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 11 Jun 2014 16:18:05 +0530 Subject: ath9k: Store current offchannel duration Update current offchannel duration during scan or roc request. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index b657115d1eb7..6487c4769af4 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -385,6 +385,7 @@ struct ath_offchannel { struct ieee80211_channel *roc_chan; struct ieee80211_vif *roc_vif; int roc_duration; + int duration; }; #define ath_for_each_chanctx(_sc, _ctx) \ for (ctx = &sc->chanctx[0]; \ -- cgit v1.2.3 From 3ae07d39ea81440768427e7786c5422f3af38a94 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Jun 2014 16:18:06 +0530 Subject: ath9k: Add p2p go NoA attribute Signed-off-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 6487c4769af4..02f30980c31a 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -362,6 +362,8 @@ struct ath_chanctx_sched { enum ath_chanctx_state state; u32 next_tbtt; + u32 switch_start_time; + unsigned int offchannel_duration; unsigned int channel_switch_time; }; @@ -472,6 +474,11 @@ struct ath_vif { /* P2P Client */ struct ieee80211_noa_data noa; + + /* P2P GO */ + u8 noa_index; + u32 offchannel_start; + u32 offchannel_duration; }; struct ath9k_vif_iter_data { -- cgit v1.2.3 From 58b57375285223badddebdf8d905a864c271b87d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Jun 2014 16:18:08 +0530 Subject: ath9k: Adjust AP beacon tsf based on station context In multi channel context (AP + STA case), adjust the TSF time of the AP chanctx to keep its beacons at half beacon interval offset relative to the STA chanctx. Signed-off-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 02f30980c31a..a4646a076099 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -335,6 +335,7 @@ struct ath_chanctx { struct ath9k_hw_cal_data caldata; struct timespec tsf_ts; u64 tsf_val; + u32 last_beacon; u16 txpower; bool offchannel; @@ -348,6 +349,7 @@ enum ath_chanctx_event { ATH_CHANCTX_EVENT_BEACON_PREPARE, ATH_CHANCTX_EVENT_BEACON_SENT, ATH_CHANCTX_EVENT_TSF_TIMER, + ATH_CHANCTX_EVENT_BEACON_RECEIVED, }; enum ath_chanctx_state { -- cgit v1.2.3 From 6036c2845650d26a15b44498f8fb8f8f4518847a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Jun 2014 16:18:09 +0530 Subject: ath9k: Implement mgd_prepare_tx Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index a4646a076099..7947909918bd 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -357,6 +357,7 @@ enum ath_chanctx_state { ATH_CHANCTX_STATE_WAIT_FOR_BEACON, ATH_CHANCTX_STATE_WAIT_FOR_TIMER, ATH_CHANCTX_STATE_SWITCH, + ATH_CHANCTX_STATE_FORCE_ACTIVE, }; struct ath_chanctx_sched { @@ -397,6 +398,8 @@ struct ath_offchannel { ctx++) void ath9k_fill_chanctx_ops(void); +void ath9k_chanctx_force_active(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); static inline struct ath_chanctx * ath_chanctx_get(struct ieee80211_chanctx_conf *ctx) { -- cgit v1.2.3 From 73fa2f26d35a37034fdff9fd702887909e138926 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Jun 2014 16:18:10 +0530 Subject: ath9k: Add multi-channel scheduling support Signed-off-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 7947909918bd..0bc63bd4ec26 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -350,6 +350,10 @@ 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_SWITCH, + ATH_CHANCTX_EVENT_UNASSIGN, + ATH_CHANCTX_EVENT_ENABLE_MULTICHANNEL, }; enum ath_chanctx_state { @@ -362,6 +366,7 @@ enum ath_chanctx_state { struct ath_chanctx_sched { bool beacon_pending; + bool offchannel_pending; enum ath_chanctx_state state; u32 next_tbtt; -- cgit v1.2.3 From 7414863ed3dfa407006c92616c1e0efda481738c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Jun 2014 16:18:11 +0530 Subject: ath9k: Add periodic NoA support Signed-off-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 0bc63bd4ec26..a5afd4a7df9f 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -489,6 +489,9 @@ struct ath_vif { u8 noa_index; u32 offchannel_start; u32 offchannel_duration; + + u32 periodic_noa_start; + u32 periodic_noa_duration; }; struct ath9k_vif_iter_data { -- cgit v1.2.3 From ec70abe1f62099f8cdd5453e20098e15435706bd Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Jun 2014 16:18:12 +0530 Subject: ath9k: Handle beacon miss on multi channel context Signed-off-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index a5afd4a7df9f..ee00ddb8885d 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -368,6 +368,7 @@ struct ath_chanctx_sched { bool beacon_pending; bool offchannel_pending; enum ath_chanctx_state state; + u8 beacon_miss; u32 next_tbtt; u32 switch_start_time; -- cgit v1.2.3 From 42eda11558559104c09f0d0924bbb210edfcf487 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Jun 2014 16:18:14 +0530 Subject: ath9k: Add recovery mechanism for hw TSF timer Configure the TSF based hardware timer for a channel switch. Also set up backup software timer, in case the gen timer fails. This could be caused by a hardware reset. Signed-off-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index ee00ddb8885d..757dd602daaa 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -374,6 +374,9 @@ struct ath_chanctx_sched { u32 switch_start_time; unsigned int offchannel_duration; unsigned int channel_switch_time; + + /* backup, in case the hardware timer fails */ + struct timer_list timer; }; enum ath_offchannel_state { @@ -426,6 +429,7 @@ struct ath_chanctx *ath_chanctx_get_oper_chan(struct ath_softc *sc, bool active); void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, enum ath_chanctx_event ev); +void ath_chanctx_timer(unsigned long data); int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan); int ath_startrecv(struct ath_softc *sc); -- cgit v1.2.3 From 3ad9c3861acef2343b232d733aa288e71cc07d44 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 11 Jun 2014 16:18:15 +0530 Subject: ath9k: use separate HW queue for each channel context Use seperate tx queue for each AC in each channel context and expose these information to mac80211 to avoid stopping one channel context leads to stopping the entire traffic for that AC even on other contexts. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 757dd602daaa..11b5e4dd6294 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -327,6 +327,7 @@ struct ath_chanctx { struct cfg80211_chan_def chandef; struct list_head vifs; struct list_head acq[IEEE80211_NUM_ACS]; + int hw_queue_base; /* do not dereference, use for comparison only */ struct ieee80211_vif *primary_sta; -- cgit v1.2.3 From d954cd770051cde27a9da8f2627acd5bc709ffbb Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 16 Jul 2014 20:26:05 +0200 Subject: ath9k: fix pending tx frames accounting Packets originally buffered for the regular hardware tx queues can end up being transmitted through the U-APSD queue (via PS-Poll or U-APSD). When packets are dropped due to retransmit failures, the pending frames counter is not always updated properly. Fix this by keeping track of the queue that a frame was accounted for in the ath_frame_info struct, and using that on completion to decide whether the counter should be updated. This fixes some spurious transmit queue hangs. Cc: stable@vger.kernel.org Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 11b5e4dd6294..7fc13a8da675 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -182,7 +182,8 @@ struct ath_atx_ac { struct ath_frame_info { struct ath_buf *bf; - int framelen; + u16 framelen; + s8 txq; enum ath9k_key_type keytype; u8 keyix; u8 rtscts_rate; -- cgit v1.2.3