aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile3
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h18
-rw-r--r--drivers/net/wireless/ath/ath9k/channel.c133
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/link.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c111
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c4
7 files changed, 169 insertions, 103 deletions
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 8fcd586d1c39..6b4020a57984 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -5,7 +5,8 @@ ath9k-y += beacon.o \
5 recv.o \ 5 recv.o \
6 xmit.o \ 6 xmit.o \
7 link.o \ 7 link.o \
8 antenna.o 8 antenna.o \
9 channel.o
9 10
10ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o 11ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o
11ath9k-$(CONFIG_ATH9K_PCI) += pci.o 12ath9k-$(CONFIG_ATH9K_PCI) += pci.o
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 {
325 u32 ampdu_ref; 325 u32 ampdu_ref;
326}; 326};
327 327
328struct ath_chanctx {
329 struct cfg80211_chan_def chandef;
330 struct list_head vifs;
331 bool offchannel;
332};
333
334void ath_chanctx_init(struct ath_softc *sc);
335int ath_chanctx_set_channel(struct ath_softc *sc, struct ath_chanctx *ctx,
336 struct cfg80211_chan_def *chandef);
337int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan);
328int ath_startrecv(struct ath_softc *sc); 338int ath_startrecv(struct ath_softc *sc);
329bool ath_stoprecv(struct ath_softc *sc); 339bool ath_stoprecv(struct ath_softc *sc);
330u32 ath_calcrxfilter(struct ath_softc *sc); 340u32 ath_calcrxfilter(struct ath_softc *sc);
@@ -370,12 +380,15 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
370/********/ 380/********/
371 381
372struct ath_vif { 382struct ath_vif {
383 struct list_head list;
384
373 struct ieee80211_vif *vif; 385 struct ieee80211_vif *vif;
374 struct ath_node mcast_node; 386 struct ath_node mcast_node;
375 int av_bslot; 387 int av_bslot;
376 bool primary_sta_vif; 388 bool primary_sta_vif;
377 __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ 389 __le64 tsf_adjust; /* TSF adjustment for staggered beacons */
378 struct ath_buf *av_bcbuf; 390 struct ath_buf *av_bcbuf;
391 struct ath_chanctx *chanctx;
379 392
380 /* P2P Client */ 393 /* P2P Client */
381 struct ieee80211_noa_data noa; 394 struct ieee80211_noa_data noa;
@@ -702,6 +715,8 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs);
702#define PS_BEACON_SYNC BIT(4) 715#define PS_BEACON_SYNC BIT(4)
703#define PS_WAIT_FOR_ANI BIT(5) 716#define PS_WAIT_FOR_ANI BIT(5)
704 717
718#define ATH9K_NUM_CHANCTX 2 /* supports 2 operating channels */
719
705struct ath_softc { 720struct ath_softc {
706 struct ieee80211_hw *hw; 721 struct ieee80211_hw *hw;
707 struct device *dev; 722 struct device *dev;
@@ -743,6 +758,9 @@ struct ath_softc {
743 struct ath_tx tx; 758 struct ath_tx tx;
744 struct ath_beacon beacon; 759 struct ath_beacon beacon;
745 760
761 struct ath_chanctx chanctx[ATH9K_NUM_CHANCTX];
762 struct ath_chanctx *cur_chan;
763
746#ifdef CONFIG_MAC80211_LEDS 764#ifdef CONFIG_MAC80211_LEDS
747 bool led_registered; 765 bool led_registered;
748 char led_name[32]; 766 char led_name[32];
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
new file mode 100644
index 000000000000..aee6cdb4975b
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -0,0 +1,133 @@
1/*
2 * Copyright (c) 2014 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "ath9k.h"
18
19/* Set/change channels. If the channel is really being changed, it's done
20 * by reseting the chip. To accomplish this we must first cleanup any pending
21 * DMA, then restart stuff.
22 */
23static int ath_set_channel(struct ath_softc *sc)
24{
25 struct ath_hw *ah = sc->sc_ah;
26 struct ath_common *common = ath9k_hw_common(ah);
27 struct ieee80211_hw *hw = sc->hw;
28 struct ath9k_channel *hchan;
29 struct cfg80211_chan_def *chandef = &sc->cur_chan->chandef;
30 struct ieee80211_channel *chan = chandef->chan;
31 int pos = chan->hw_value;
32 int old_pos = -1;
33 int r;
34
35 if (test_bit(ATH_OP_INVALID, &common->op_flags))
36 return -EIO;
37
38 if (ah->curchan)
39 old_pos = ah->curchan - &ah->channels[0];
40
41 ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",
42 chan->center_freq, chandef->width);
43
44 /* update survey stats for the old channel before switching */
45 spin_lock_bh(&common->cc_lock);
46 ath_update_survey_stats(sc);
47 spin_unlock_bh(&common->cc_lock);
48
49 ath9k_cmn_get_channel(hw, ah, chandef);
50
51 /* If the operating channel changes, change the survey in-use flags
52 * along with it.
53 * Reset the survey data for the new channel, unless we're switching
54 * back to the operating channel from an off-channel operation.
55 */
56 if (!sc->cur_chan->offchannel && sc->cur_survey != &sc->survey[pos]) {
57 if (sc->cur_survey)
58 sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
59
60 sc->cur_survey = &sc->survey[pos];
61
62 memset(sc->cur_survey, 0, sizeof(struct survey_info));
63 sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
64 } else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
65 memset(&sc->survey[pos], 0, sizeof(struct survey_info));
66 }
67
68 hchan = &sc->sc_ah->channels[pos];
69 r = ath_reset_internal(sc, hchan);
70 if (r)
71 return r;
72
73 /* The most recent snapshot of channel->noisefloor for the old
74 * channel is only available after the hardware reset. Copy it to
75 * the survey stats now.
76 */
77 if (old_pos >= 0)
78 ath_update_survey_nf(sc, old_pos);
79
80 /* Enable radar pulse detection if on a DFS channel. Spectral
81 * scanning and radar detection can not be used concurrently.
82 */
83 if (hw->conf.radar_enabled) {
84 u32 rxfilter;
85
86 /* set HW specific DFS configuration */
87 ath9k_hw_set_radar_params(ah);
88 rxfilter = ath9k_hw_getrxfilter(ah);
89 rxfilter |= ATH9K_RX_FILTER_PHYRADAR |
90 ATH9K_RX_FILTER_PHYERR;
91 ath9k_hw_setrxfilter(ah, rxfilter);
92 ath_dbg(common, DFS, "DFS enabled at freq %d\n",
93 chan->center_freq);
94 } else {
95 /* perform spectral scan if requested. */
96 if (test_bit(ATH_OP_SCANNING, &common->op_flags) &&
97 sc->spectral_mode == SPECTRAL_CHANSCAN)
98 ath9k_spectral_scan_trigger(hw);
99 }
100
101 return 0;
102}
103
104void ath_chanctx_init(struct ath_softc *sc)
105{
106 struct ath_chanctx *ctx;
107 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
108 struct ieee80211_supported_band *sband;
109 struct ieee80211_channel *chan;
110 int i;
111
112 sband = &common->sbands[IEEE80211_BAND_2GHZ];
113 if (!sband->n_channels)
114 sband = &common->sbands[IEEE80211_BAND_5GHZ];
115
116 chan = &sband->channels[0];
117 for (i = 0; i < ATH9K_NUM_CHANCTX; i++) {
118 ctx = &sc->chanctx[i];
119 cfg80211_chandef_create(&ctx->chandef, chan, NL80211_CHAN_HT20);
120 INIT_LIST_HEAD(&ctx->vifs);
121 }
122 sc->cur_chan = &sc->chanctx[0];
123}
124
125int ath_chanctx_set_channel(struct ath_softc *sc, struct ath_chanctx *ctx,
126 struct cfg80211_chan_def *chandef)
127{
128 memcpy(&ctx->chandef, chandef, sizeof(ctx->chandef));
129 if (ctx != sc->cur_chan)
130 return 0;
131
132 return ath_set_channel(sc);
133}
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 0246b990fe87..32d954275d47 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -599,6 +599,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
599 ath9k_cmn_init_crypto(sc->sc_ah); 599 ath9k_cmn_init_crypto(sc->sc_ah);
600 ath9k_init_misc(sc); 600 ath9k_init_misc(sc);
601 ath_fill_led_pin(sc); 601 ath_fill_led_pin(sc);
602 ath_chanctx_init(sc);
602 603
603 if (common->bus_ops->aspm_init) 604 if (common->bus_ops->aspm_init)
604 common->bus_ops->aspm_init(common); 605 common->bus_ops->aspm_init(common);
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index 72a715fe8f24..6f91974c7b08 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -416,7 +416,7 @@ void ath_start_ani(struct ath_softc *sc)
416 416
417 if (common->disable_ani || 417 if (common->disable_ani ||
418 !test_bit(ATH_OP_ANI_RUN, &common->op_flags) || 418 !test_bit(ATH_OP_ANI_RUN, &common->op_flags) ||
419 (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) 419 sc->cur_chan->offchannel)
420 return; 420 return;
421 421
422 common->ani.longcal_timer = timestamp; 422 common->ani.longcal_timer = timestamp;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 62ac95d6bb9d..2e7cce7b1238 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -233,7 +233,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
233 ath9k_hw_set_interrupts(ah); 233 ath9k_hw_set_interrupts(ah);
234 ath9k_hw_enable_interrupts(ah); 234 ath9k_hw_enable_interrupts(ah);
235 235
236 if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) && start) { 236 if (!sc->cur_chan->offchannel && start) {
237 if (!test_bit(ATH_OP_BEACONS, &common->op_flags)) 237 if (!test_bit(ATH_OP_BEACONS, &common->op_flags))
238 goto work; 238 goto work;
239 239
@@ -266,7 +266,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
266 return true; 266 return true;
267} 267}
268 268
269static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) 269int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
270{ 270{
271 struct ath_hw *ah = sc->sc_ah; 271 struct ath_hw *ah = sc->sc_ah;
272 struct ath_common *common = ath9k_hw_common(ah); 272 struct ath_common *common = ath9k_hw_common(ah);
@@ -279,7 +279,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
279 tasklet_disable(&sc->intr_tq); 279 tasklet_disable(&sc->intr_tq);
280 spin_lock_bh(&sc->sc_pcu_lock); 280 spin_lock_bh(&sc->sc_pcu_lock);
281 281
282 if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) { 282 if (!sc->cur_chan->offchannel) {
283 fastcc = false; 283 fastcc = false;
284 caldata = &sc->caldata; 284 caldata = &sc->caldata;
285 } 285 }
@@ -307,7 +307,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
307 } 307 }
308 308
309 if (ath9k_hw_mci_is_enabled(sc->sc_ah) && 309 if (ath9k_hw_mci_is_enabled(sc->sc_ah) &&
310 (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) 310 sc->cur_chan->offchannel)
311 ath9k_mci_set_txpower(sc, true, false); 311 ath9k_mci_set_txpower(sc, true, false);
312 312
313 if (!ath_complete_reset(sc, true)) 313 if (!ath_complete_reset(sc, true))
@@ -320,98 +320,6 @@ out:
320 return r; 320 return r;
321} 321}
322 322
323
324/*
325 * Set/change channels. If the channel is really being changed, it's done
326 * by reseting the chip. To accomplish this we must first cleanup any pending
327 * DMA, then restart stuff.
328*/
329static int ath_set_channel(struct ath_softc *sc, struct cfg80211_chan_def *chandef)
330{
331 struct ath_hw *ah = sc->sc_ah;
332 struct ath_common *common = ath9k_hw_common(ah);
333 struct ieee80211_hw *hw = sc->hw;
334 struct ath9k_channel *hchan;
335 struct ieee80211_channel *chan = chandef->chan;
336 bool offchannel;
337 int pos = chan->hw_value;
338 int old_pos = -1;
339 int r;
340
341 if (test_bit(ATH_OP_INVALID, &common->op_flags))
342 return -EIO;
343
344 offchannel = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL);
345
346 if (ah->curchan)
347 old_pos = ah->curchan - &ah->channels[0];
348
349 ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",
350 chan->center_freq, chandef->width);
351
352 /* update survey stats for the old channel before switching */
353 spin_lock_bh(&common->cc_lock);
354 ath_update_survey_stats(sc);
355 spin_unlock_bh(&common->cc_lock);
356
357 ath9k_cmn_get_channel(hw, ah, chandef);
358
359 /*
360 * If the operating channel changes, change the survey in-use flags
361 * along with it.
362 * Reset the survey data for the new channel, unless we're switching
363 * back to the operating channel from an off-channel operation.
364 */
365 if (!offchannel && sc->cur_survey != &sc->survey[pos]) {
366 if (sc->cur_survey)
367 sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
368
369 sc->cur_survey = &sc->survey[pos];
370
371 memset(sc->cur_survey, 0, sizeof(struct survey_info));
372 sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
373 } else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
374 memset(&sc->survey[pos], 0, sizeof(struct survey_info));
375 }
376
377 hchan = &sc->sc_ah->channels[pos];
378 r = ath_reset_internal(sc, hchan);
379 if (r)
380 return r;
381
382 /*
383 * The most recent snapshot of channel->noisefloor for the old
384 * channel is only available after the hardware reset. Copy it to
385 * the survey stats now.
386 */
387 if (old_pos >= 0)
388 ath_update_survey_nf(sc, old_pos);
389
390 /*
391 * Enable radar pulse detection if on a DFS channel. Spectral
392 * scanning and radar detection can not be used concurrently.
393 */
394 if (hw->conf.radar_enabled) {
395 u32 rxfilter;
396
397 /* set HW specific DFS configuration */
398 ath9k_hw_set_radar_params(ah);
399 rxfilter = ath9k_hw_getrxfilter(ah);
400 rxfilter |= ATH9K_RX_FILTER_PHYRADAR |
401 ATH9K_RX_FILTER_PHYERR;
402 ath9k_hw_setrxfilter(ah, rxfilter);
403 ath_dbg(common, DFS, "DFS enabled at freq %d\n",
404 chan->center_freq);
405 } else {
406 /* perform spectral scan if requested. */
407 if (test_bit(ATH_OP_SCANNING, &common->op_flags) &&
408 sc->spectral_mode == SPECTRAL_CHANSCAN)
409 ath9k_spectral_scan_trigger(hw);
410 }
411
412 return 0;
413}
414
415static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, 323static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
416 struct ieee80211_vif *vif) 324 struct ieee80211_vif *vif)
417{ 325{
@@ -713,6 +621,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
713 struct ath_hw *ah = sc->sc_ah; 621 struct ath_hw *ah = sc->sc_ah;
714 struct ath_common *common = ath9k_hw_common(ah); 622 struct ath_common *common = ath9k_hw_common(ah);
715 struct ieee80211_channel *curchan = hw->conf.chandef.chan; 623 struct ieee80211_channel *curchan = hw->conf.chandef.chan;
624 struct ath_chanctx *ctx = sc->cur_chan;
716 struct ath9k_channel *init_channel; 625 struct ath9k_channel *init_channel;
717 int r; 626 int r;
718 627
@@ -723,7 +632,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
723 ath9k_ps_wakeup(sc); 632 ath9k_ps_wakeup(sc);
724 mutex_lock(&sc->mutex); 633 mutex_lock(&sc->mutex);
725 634
726 init_channel = ath9k_cmn_get_channel(hw, ah, &hw->conf.chandef); 635 memcpy(&ctx->chandef, &hw->conf.chandef, sizeof(ctx->chandef));
636 init_channel = ath9k_cmn_get_channel(hw, ah, &ctx->chandef);
727 637
728 /* Reset SERDES registers */ 638 /* Reset SERDES registers */
729 ath9k_hw_configpcipowersave(ah, false); 639 ath9k_hw_configpcipowersave(ah, false);
@@ -934,7 +844,8 @@ static void ath9k_stop(struct ieee80211_hw *hw)
934 } 844 }
935 845
936 if (!ah->curchan) 846 if (!ah->curchan)
937 ah->curchan = ath9k_cmn_get_channel(hw, ah, &hw->conf.chandef); 847 ah->curchan = ath9k_cmn_get_channel(hw, ah,
848 &sc->cur_chan->chandef);
938 849
939 ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); 850 ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
940 ath9k_hw_phy_disable(ah); 851 ath9k_hw_phy_disable(ah);
@@ -1345,6 +1256,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1345 struct ath_hw *ah = sc->sc_ah; 1256 struct ath_hw *ah = sc->sc_ah;
1346 struct ath_common *common = ath9k_hw_common(ah); 1257 struct ath_common *common = ath9k_hw_common(ah);
1347 struct ieee80211_conf *conf = &hw->conf; 1258 struct ieee80211_conf *conf = &hw->conf;
1259 struct ath_chanctx *ctx = sc->cur_chan;
1348 bool reset_channel = false; 1260 bool reset_channel = false;
1349 1261
1350 ath9k_ps_wakeup(sc); 1262 ath9k_ps_wakeup(sc);
@@ -1392,7 +1304,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1392 } 1304 }
1393 1305
1394 if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) { 1306 if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) {
1395 if (ath_set_channel(sc, &hw->conf.chandef) < 0) { 1307 ctx->offchannel = !!(conf->flags & IEEE80211_CONF_OFFCHANNEL);
1308 if (ath_chanctx_set_channel(sc, ctx, &hw->conf.chandef) < 0) {
1396 ath_err(common, "Unable to set channel\n"); 1309 ath_err(common, "Unable to set channel\n");
1397 mutex_unlock(&sc->mutex); 1310 mutex_unlock(&sc->mutex);
1398 ath9k_ps_restore(sc); 1311 ath9k_ps_restore(sc);
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 9105a92364f7..de5684a33dd7 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -259,7 +259,7 @@ static void ath_edma_start_recv(struct ath_softc *sc)
259 ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP); 259 ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP);
260 ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP); 260 ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP);
261 ath_opmode_init(sc); 261 ath_opmode_init(sc);
262 ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); 262 ath9k_hw_startpcureceive(sc->sc_ah, sc->cur_chan->offchannel);
263} 263}
264 264
265static void ath_edma_stop_recv(struct ath_softc *sc) 265static void ath_edma_stop_recv(struct ath_softc *sc)
@@ -457,7 +457,7 @@ int ath_startrecv(struct ath_softc *sc)
457 457
458start_recv: 458start_recv:
459 ath_opmode_init(sc); 459 ath_opmode_init(sc);
460 ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); 460 ath9k_hw_startpcureceive(ah, sc->cur_chan->offchannel);
461 461
462 return 0; 462 return 0;
463} 463}