iPXE
ath9k_main.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 *
4 * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5 * Original from Linux kernel 3.0.1
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20FILE_SECBOOT ( FORBIDDEN );
21
22#include <ipxe/io.h>
23
24#include "ath9k.h"
25
26static void ath9k_bss_info_changed(struct net80211_device *dev, u32 changed);
27
29{
30 int ret;
31
32 ret = ath9k_hw_setpower(sc->sc_ah, mode);
33
34 return ret;
35}
36
37static void ath_start_ani(struct ath_common *common)
38{
39 struct ath_hw *ah = common->ah;
40 unsigned long timestamp = ( currticks() * 1000 ) / TICKS_PER_SEC;
41 struct ath_softc *sc = (struct ath_softc *) common->priv;
42
43 if (!(sc->sc_flags & SC_OP_ANI_RUN))
44 return;
45
46 if (sc->sc_flags & SC_OP_OFFCHANNEL)
47 return;
48
49 common->ani.longcal_timer = timestamp;
50 common->ani.shortcal_timer = timestamp;
51 common->ani.checkani_timer = timestamp;
52
53 common->ani.timer = timestamp + ah->config.ani_poll_interval;
54}
55
56static void ath_update_survey_nf(struct ath_softc *sc, int channel)
57{
58 struct ath_hw *ah = sc->sc_ah;
59 struct ath9k_channel *chan = &ah->channels[channel];
60 struct survey_info *survey = &sc->survey[channel];
61
62 if (chan->noisefloor) {
64 survey->noise = chan->noisefloor;
65 }
66}
67
68/*
69 * Updates the survey statistics and returns the busy time since last
70 * update in %, if the measurement duration was long enough for the
71 * result to be useful, -1 otherwise.
72 */
73static int ath_update_survey_stats(struct ath_softc *sc)
74{
75 struct ath_hw *ah = sc->sc_ah;
77 int pos = ah->curchan - &ah->channels[0];
78 struct survey_info *survey = &sc->survey[pos];
79 struct ath_cycle_counters *cc = &common->cc_survey;
80 unsigned int div = common->clockrate * 1000;
81 int ret = 0;
82
83 if (!ah->curchan)
84 return -1;
85
86 if (ah->power_mode == ATH9K_PM_AWAKE)
88
89 if (cc->cycles > 0) {
94 survey->channel_time += cc->cycles / div;
95 survey->channel_time_busy += cc->rx_busy / div;
96 survey->channel_time_rx += cc->rx_frame / div;
97 survey->channel_time_tx += cc->tx_frame / div;
98 }
99
100 if (cc->cycles < div)
101 return -1;
102
103 if (cc->cycles > 0)
104 ret = cc->rx_busy * 100 / cc->cycles;
105
106 memset(cc, 0, sizeof(*cc));
107
108 ath_update_survey_nf(sc, pos);
109
110 return ret;
111}
112
113/*
114 * Set/change channels. If the channel is really being changed, it's done
115 * by reseting the chip. To accomplish this we must first cleanup any pending
116 * DMA, then restart stuff.
117*/
118int ath_set_channel(struct ath_softc *sc, struct net80211_device *dev,
119 struct ath9k_channel *hchan)
120{
121 struct ath_hw *ah = sc->sc_ah;
123 int fastcc __unused = 1, stopped __unused;
124 struct net80211_channel *channel = dev->channels + dev->channel;
125 struct ath9k_hw_cal_data *caldata = NULL;
126 int r;
127
128 if (sc->sc_flags & SC_OP_INVALID)
129 return -EIO;
130
131 sc->hw_busy_count = 0;
132
133 common->ani.timer = 0;
135 sc->hw_pll_work_timer = 0;
136
137 /*
138 * This is only performed if the channel settings have
139 * actually changed.
140 *
141 * To switch channels clear any pending DMA operations;
142 * wait long enough for the RX fifo to drain, reset the
143 * hardware at the new frequency, and then re-enable
144 * the relevant bits of the h/w.
145 */
147 stopped = ath_drain_all_txq(sc, 0);
148
149 if (!ath_stoprecv(sc))
150 stopped = 0;
151
153 stopped = 0;
154
155 /* XXX: do not flush receive queue here. We don't want
156 * to flush data frames already in queue because of
157 * changing channel. */
158
159 if (!(sc->sc_flags & SC_OP_OFFCHANNEL))
160 caldata = &sc->caldata;
161
162 DBG2("ath9k: "
163 "(%d MHz) -> (%d MHz)\n",
164 sc->sc_ah->curchan->channel,
165 channel->center_freq);
166
167 r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
168 if (r) {
169 DBG("ath9k: "
170 "Unable to reset channel (%d MHz), reset status %d\n",
171 channel->center_freq, r);
172 goto ps_restore;
173 }
174
175 if (ath_startrecv(sc) != 0) {
176 DBG("ath9k: Unable to restart recv logic\n");
177 r = -EIO;
178 goto ps_restore;
179 }
180
182 sc->config.txpowlimit, &sc->curtxpow);
184
185 if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) {
186 sc->tx_complete_work(sc);
187 sc->hw_pll_work_timer = (currticks() * 1000 ) / TICKS_PER_SEC + 500;
189 }
190
191 ps_restore:
192 return r;
193}
194
195/*
196 * This routine performs the periodic noise floor calibration function
197 * that is used to adjust and optimize the chip performance. This
198 * takes environmental changes (location, temperature) into account.
199 * When the task is complete, it reschedules itself depending on the
200 * appropriate interval that was calculated.
201 */
203{
204 struct ath_hw *ah = sc->sc_ah;
206 int longcal = 0;
207 int shortcal = 0;
208 int aniflag = 0;
209 unsigned int timestamp = (currticks() * 1000 ) / TICKS_PER_SEC;
210 u32 cal_interval, short_cal_interval, long_cal_interval;
211
212 if (ah->caldata && ah->caldata->nfcal_interference)
213 long_cal_interval = ATH_LONG_CALINTERVAL_INT;
214 else
215 long_cal_interval = ATH_LONG_CALINTERVAL;
216
217 short_cal_interval = ATH_STA_SHORT_CALINTERVAL;
218
219 /* Only calibrate if awake */
220 if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE)
221 goto set_timer;
222
223 /* Long calibration runs independently of short calibration. */
224 if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) {
225 longcal = 1;
226 DBG2("ath9k: longcal @%d\n", timestamp);
227 common->ani.longcal_timer = timestamp;
228 }
229
230 /* Short calibration applies only while caldone is false */
231 if (!common->ani.caldone) {
232 if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) {
233 shortcal = 1;
234 DBG2("ath9k: "
235 "shortcal @%d\n", timestamp);
236 common->ani.shortcal_timer = timestamp;
237 common->ani.resetcal_timer = timestamp;
238 }
239 } else {
240 if ((timestamp - common->ani.resetcal_timer) >=
242 common->ani.caldone = ath9k_hw_reset_calvalid(ah);
243 if (common->ani.caldone)
244 common->ani.resetcal_timer = timestamp;
245 }
246 }
247
248 /* Verify whether we must check ANI */
249 if ((timestamp - common->ani.checkani_timer) >=
250 ah->config.ani_poll_interval) {
251 aniflag = 1;
252 common->ani.checkani_timer = timestamp;
253 }
254
255 /* Skip all processing if there's nothing to do. */
256 if (longcal || shortcal || aniflag) {
257 /* Call ANI routine if necessary */
258 if (aniflag) {
259 ath9k_hw_ani_monitor(ah, ah->curchan);
261 }
262
263 /* Perform calibration if necessary */
264 if (longcal || shortcal) {
265 common->ani.caldone =
267 ah->curchan,
268 common->rx_chainmask,
269 longcal);
270 }
271 }
272
273set_timer:
274 /*
275 * Set timer interval based on previous results.
276 * The interval must be the shortest necessary to satisfy ANI,
277 * short calibration and long calibration.
278 */
279 cal_interval = ATH_LONG_CALINTERVAL;
280 if (sc->sc_ah->config.enable_ani)
281 cal_interval = min(cal_interval,
282 (u32)ah->config.ani_poll_interval);
283 if (!common->ani.caldone)
284 cal_interval = min(cal_interval, (u32)short_cal_interval);
285
286 common->ani.timer = timestamp + cal_interval;
287}
288
289void ath_hw_check(struct ath_softc *sc)
290{
291 int busy;
292
294 goto out;
295
296 busy = ath_update_survey_stats(sc);
297
298 DBG("ath9k: Possible baseband hang, "
299 "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1);
300 if (busy >= 99) {
301 if (++sc->hw_busy_count >= 3)
302 ath_reset(sc, 1);
303 } else if (busy >= 0)
304 sc->hw_busy_count = 0;
305
306out:
307 return;
308}
309
310static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
311{
312 static int count;
313
314 if (pll_sqsum >= 0x40000) {
315 count++;
316 if (count == 3) {
317 /* Rx is hung for more than 500ms. Reset it */
318 DBG("ath9k: "
319 "Possible RX hang, resetting");
320 ath_reset(sc, 1);
321 count = 0;
322 }
323 } else
324 count = 0;
325}
326
328{
329 u32 pll_sqsum;
330
331 if (AR_SREV_9485(sc->sc_ah)) {
332 pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah);
333
334 ath_hw_pll_rx_hang_check(sc, pll_sqsum);
335
336 sc->hw_pll_work_timer = (currticks() * 1000 ) / TICKS_PER_SEC + 200;
337 }
338}
339
340
341void ath9k_tasklet(struct ath_softc *sc)
342{
343 struct ath_hw *ah = sc->sc_ah;
344
345 u32 status = sc->intrstatus;
346 u32 rxmask;
347
348 if ((status & ATH9K_INT_FATAL) ||
350 ath_reset(sc, 1);
351 return;
352 }
353
355
356 if (status & rxmask) {
357 ath_rx_tasklet(sc, 0, 0);
358 }
359
360 if (status & ATH9K_INT_TX) {
361 ath_tx_tasklet(sc);
362 }
363
364 /* re-enable hardware interrupt */
366}
367
369{
370#define SCHED_INTR ( \
371 ATH9K_INT_FATAL | \
372 ATH9K_INT_BB_WATCHDOG | \
373 ATH9K_INT_RXORN | \
374 ATH9K_INT_RXEOL | \
375 ATH9K_INT_RX | \
376 ATH9K_INT_RXLP | \
377 ATH9K_INT_RXHP | \
378 ATH9K_INT_TX | \
379 ATH9K_INT_BMISS | \
380 ATH9K_INT_CST | \
381 ATH9K_INT_TSFOOR | \
382 ATH9K_INT_GENTIMER)
383
384 struct ath_softc *sc = dev->priv;
385 struct ath_hw *ah = sc->sc_ah;
387 enum ath9k_int status;
388 unsigned long timestamp = (currticks() * 1000 ) / TICKS_PER_SEC;
389 int sched = 0;
390
391 /*
392 * The hardware is not ready/present, don't
393 * touch anything. Note this can happen early
394 * on if the IRQ is shared.
395 */
396 if (sc->sc_flags & SC_OP_INVALID)
397 return;
398
399
400 /* Check calibration */
401 if(timestamp >= (unsigned int)common->ani.timer && common->ani.timer)
403
404 /* Check tx_complete_work */
405 if(timestamp >= (unsigned int)sc->tx_complete_work_timer && sc->tx_complete_work_timer)
406 sc->tx_complete_work(sc);
407
408 /* Check hw_pll_work */
409 if(timestamp >= (unsigned int)sc->hw_pll_work_timer && sc->hw_pll_work_timer)
410 sc->hw_pll_work(sc);
411
412 /* shared irq, not for us */
413
414 if (!ath9k_hw_intrpend(ah))
415 return;
416
417 /*
418 * Figure out the reason(s) for the interrupt. Note
419 * that the hal returns a pseudo-ISR that may include
420 * bits we haven't explicitly enabled so we mask the
421 * value to insure we only process bits we requested.
422 */
423 ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */
424 status &= ah->imask; /* discard unasked-for bits */
425
426 /*
427 * If there are no status bits set, then this interrupt was not
428 * for me (should have been caught above).
429 */
430 if (!status)
431 return;
432
433 /* Cache the status */
434 sc->intrstatus = status;
435
436 if (status & SCHED_INTR)
437 sched = 1;
438
439 /*
440 * If a FATAL or RXORN interrupt is received, we have to reset the
441 * chip immediately.
442 */
444 goto chip_reset;
445
448
449 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
451 if (sc->ps_idle)
452 goto chip_reset;
453 /* Clear RxAbort bit so that we can
454 * receive frames */
458 }
459
460chip_reset:
461
462 if (sched) {
463 /* turn off every interrupt */
465 sc->intr_tq(sc);
466 }
467
468 return;
469
470#undef SCHED_INTR
471}
472
474{
475 struct ath_hw *ah = sc->sc_ah;
476 struct net80211_channel *channel = dev->channels + dev->channel;
477 int r;
478
479 sc->hw_pll_work_timer = 0;
480
481 /*
482 * Keep the LED on when the radio is disabled
483 * during idle unassociated state.
484 */
485 if (!sc->ps_idle) {
486 ath9k_hw_set_gpio(ah, ah->led_pin, 1);
487 ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
488 }
489
490 /* Disable interrupts */
492
493 ath_drain_all_txq(sc, 0); /* clear pending tx frames */
494
495 ath_stoprecv(sc); /* turn off frame recv */
496 ath_flushrecv(sc); /* flush recv queue */
497
498 if (!ah->curchan)
499 ah->curchan = ath9k_cmn_get_curchannel(dev, ah);
500
501 r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, 0);
502 if (r) {
503 DBG("ath9k: "
504 "Unable to reset channel (%d MHz), reset status %d\n",
505 channel->center_freq, r);
506 }
507
509
511}
512
513int ath_reset(struct ath_softc *sc, int retry_tx)
514{
515 struct ath_hw *ah = sc->sc_ah;
517 int r;
518
519 sc->hw_busy_count = 0;
520
521 /* Stop ANI */
522 common->ani.timer = 0;
523
525 ath_drain_all_txq(sc, retry_tx);
526
527 ath_stoprecv(sc);
528 ath_flushrecv(sc);
529
530 r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, 0);
531 if (r)
532 DBG("ath9k: "
533 "Unable to reset hardware; reset status %d\n", r);
534
535 if (ath_startrecv(sc) != 0)
536 DBG("ath9k: Unable to start recv logic\n");
537
538 /*
539 * We may be doing a reset in response to a request
540 * that changes the channel so update any state that
541 * might change as a result.
542 */
544 sc->config.txpowlimit, &sc->curtxpow);
545
547
548 if (retry_tx) {
549 int i;
550 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
551 if (ATH_TXQ_SETUP(sc, i)) {
552 ath_txq_schedule(sc, &sc->tx.txq[i]);
553 }
554 }
555 }
556
557 /* Start ANI */
559
560 return r;
561}
562
563/**********************/
564/* mac80211 callbacks */
565/**********************/
566
567static int ath9k_start(struct net80211_device *dev)
568{
569 struct ath_softc *sc = dev->priv;
570 struct ath_hw *ah = sc->sc_ah;
572 struct net80211_channel *curchan = dev->channels + dev->channel;
573 struct ath9k_channel *init_channel;
574 int r;
575
576 DBG("ath9k: "
577 "Starting driver with initial channel: %d MHz\n",
578 curchan->center_freq);
579
580 /* setup initial channel */
581 sc->chan_idx = curchan->hw_value;
582
583 init_channel = ath9k_cmn_get_curchannel(dev, ah);
584
585 /* Reset SERDES registers */
587
588 /*
589 * The basic interface to setting the hardware in a good
590 * state is ``reset''. On return the hardware is known to
591 * be powered up and with interrupts disabled. This must
592 * be followed by initialization of the appropriate bits
593 * and then setup of the interrupt mask.
594 */
595 r = ath9k_hw_reset(ah, init_channel, ah->caldata, 0);
596 if (r) {
597 DBG("ath9k: "
598 "Unable to reset hardware; reset status %d (freq %d MHz)\n",
599 r, curchan->center_freq);
600 goto mutex_unlock;
601 }
602
603 /*
604 * This is needed only to setup initial state
605 * but it's best done after a reset.
606 */
608 sc->config.txpowlimit, &sc->curtxpow);
609
610 /*
611 * Setup the hardware after reset:
612 * The receive engine is set going.
613 * Frame transmit is handled entirely
614 * in the frame output path; there's nothing to do
615 * here except setup the interrupt mask.
616 */
617 if (ath_startrecv(sc) != 0) {
618 DBG("ath9k: Unable to start recv logic\n");
619 r = -EIO;
620 goto mutex_unlock;
621 }
622
623 /* Setup our intr mask. */
624 ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL |
627
628 ah->imask |= ATH9K_INT_RX;
629
631 sc->sc_ah->is_monitoring = 0;
632
634
635 sc->tx_complete_work(sc);
636
637 if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
638 common->bus_ops->extn_synch_en(common);
639
640mutex_unlock:
641 return r;
642}
643
644static int ath9k_tx(struct net80211_device *dev, struct io_buffer *iob)
645{
646 struct ath_softc *sc = dev->priv;
647 struct ath_tx_control txctl;
648 int ret = 0;
649
650 memset(&txctl, 0, sizeof(struct ath_tx_control));
651 txctl.txq = sc->tx.txq_map[0];
652
653 DBGIO("ath9k: transmitting packet, iob: %p\n", iob);
654
655 ret = ath_tx_start(dev, iob, &txctl);
656 if (ret) {
657 DBG("ath9k: TX failed\n");
658 goto exit;
659 }
660
661 return ret;
662exit:
663 free_iob(iob);
664 return ret;
665}
666
667static void ath9k_stop(struct net80211_device *dev)
668{
669 struct ath_softc *sc = dev->priv;
670 struct ath_hw *ah = sc->sc_ah;
671
673 sc->hw_pll_work_timer = 0;
674
675 if (sc->sc_flags & SC_OP_INVALID) {
676 DBG("ath9k: Device not present\n");
677 return;
678 }
679
680 /* prevent tasklets to enable interrupts once we disable them */
681 ah->imask &= ~ATH9K_INT_GLOBAL;
682
683 /* make sure h/w will not generate any interrupt
684 * before setting the invalid flag. */
686
687 if (!(sc->sc_flags & SC_OP_INVALID)) {
688 ath_drain_all_txq(sc, 0);
689 ath_stoprecv(sc);
691 } else
692 sc->rx.rxlink = NULL;
693
694 if (sc->rx.frag) {
695 free_iob(sc->rx.frag);
696 sc->rx.frag = NULL;
697 }
698
699 /* disable HAL and put h/w to sleep */
702
704
705 sc->sc_flags |= SC_OP_INVALID;
706
707 DBG("ath9k: Driver halt\n");
708}
709
710static int ath9k_config(struct net80211_device *dev, int changed)
711{
712 struct ath_softc *sc = dev->priv;
713 struct ath_hw *ah = sc->sc_ah;
714
715 if ((changed & NET80211_CFG_RATE) ||
716 (changed & NET80211_CFG_PHY_PARAMS)) {
718 u16 rate = dev->rates[dev->rate];
719 u16 slowrate = dev->rates[dev->rtscts_rate];
720 int i;
721
722 for (i = 0; i < NET80211_MAX_RATES; i++) {
723 if (sc->rates[i].bitrate == rate &&
724 (sc->rates[i].flags & spmbl))
725 sc->hw_rix = i;
726
727 if (sc->rates[i].bitrate == slowrate &&
728 (sc->rates[i].flags & spmbl))
729 sc->hw_rix = i;
730 }
731 }
732
733 ath9k_bss_info_changed(dev, changed);
734
735 if (changed & NET80211_CFG_CHANNEL) {
736 struct net80211_channel *curchan = dev->channels + dev->channel;
737 int pos = curchan->hw_value;
738 int old_pos = -1;
739
740 if (ah->curchan)
741 old_pos = ah->curchan - &ah->channels[0];
742
744
745 DBG2("ath9k: "
746 "Set channel: %d MHz\n",
747 curchan->center_freq);
748
750 curchan);
751
752 /* update survey stats for the old channel before switching */
754
755 /*
756 * If the operating channel changes, change the survey in-use flags
757 * along with it.
758 * Reset the survey data for the new channel, unless we're switching
759 * back to the operating channel from an off-channel operation.
760 */
761 if (sc->cur_survey != &sc->survey[pos]) {
762
763 if (sc->cur_survey)
765
766 sc->cur_survey = &sc->survey[pos];
767
768 memset(sc->cur_survey, 0, sizeof(struct survey_info));
770 } else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
771 memset(&sc->survey[pos], 0, sizeof(struct survey_info));
772 }
773
774 if (ath_set_channel(sc, dev, &sc->sc_ah->channels[pos]) < 0) {
775 DBG("ath9k: Unable to set channel\n");
776 return -EINVAL;
777 }
778
779 /*
780 * The most recent snapshot of channel->noisefloor for the old
781 * channel is only available after the hardware reset. Copy it to
782 * the survey stats now.
783 */
784 if (old_pos >= 0)
785 ath_update_survey_nf(sc, old_pos);
786 }
787
788 if (changed & NET80211_CFG_CHANNEL) {
789 DBG2("ath9k: "
790 "Set power: %d\n", (dev->channels + dev->channel)->maxpower);
791 sc->config.txpowlimit = 2 * (dev->channels + dev->channel)->maxpower;
793 sc->config.txpowlimit, &sc->curtxpow);
794 }
795
796 return 0;
797}
798
799static void ath9k_bss_iter(struct ath_softc *sc)
800{
801 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
802
803 if (common->dev->state & NET80211_ASSOCIATED) {
805 memcpy(common->curbssid, common->dev->bssid, ETH_ALEN);
806 common->curaid = common->dev->aid;
808 DBG("ath9k: "
809 "Bss Info ASSOC %d, bssid: %pM\n",
810 common->dev->aid, common->curbssid);
811
812 /*
813 * Request a re-configuration of Beacon related timers
814 * on the receipt of the first Beacon frame (i.e.,
815 * after time sync with the AP).
816 */
818 /* Reset rssi stats */
821
822 sc->sc_flags |= SC_OP_ANI_RUN;
824 }
825}
826
827static void ath9k_config_bss(struct ath_softc *sc)
828{
829 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
830 struct net80211_device *dev = common->dev;
831
832 /* Reconfigure bss info */
833 if (!(dev->state & NET80211_ASSOCIATED)) {
834 DBG2("ath9k: "
835 "ath9k: Bss Info DISASSOC %d, bssid %pM\n",
836 common->curaid, common->curbssid);
838 memset(common->curbssid, 0, ETH_ALEN);
839 common->curaid = 0;
840 }
841
842 ath9k_bss_iter(sc);
843
844 /*
845 * None of station vifs are associated.
846 * Clear bssid & aid
847 */
848 if (!(sc->sc_flags & SC_OP_PRIM_STA_VIF)) {
850 /* Stop ANI */
852 common->ani.timer = 0;
853 }
854}
855
857 u32 changed)
858{
859 struct ath_softc *sc = dev->priv;
860 struct ath_hw *ah = sc->sc_ah;
862 int slottime;
863
864 if (changed & NET80211_CFG_ASSOC) {
866
867 DBG2("ath9k: BSSID: %pM aid: 0x%x\n",
868 common->curbssid, common->curaid);
869 }
870
871 if (changed & NET80211_CFG_PHY_PARAMS) {
873 slottime = 9;
874 else
875 slottime = 20;
876 ah->slottime = slottime;
878
879 DBG2("ath9k: BSS Changed PREAMBLE %d\n",
883 else
885
886 DBG2("ath9k: BSS Changed CTS PROT %d\n",
891 else
893 }
894}
895
896static void ath9k_poll(struct net80211_device *dev)
897{
898 ath_isr(dev);
899}
900
901static void ath9k_irq(struct net80211_device *dev, int enable)
902{
903 struct ath_softc *sc = dev->priv;
904 struct ath_hw *ah = sc->sc_ah;
905
906 ah->ah_ier = enable ? AR_IER_ENABLE : AR_IER_DISABLE;
907
909}
910
912 .transmit = ath9k_tx,
913 .open = ath9k_start,
914 .close = ath9k_stop,
915 .config = ath9k_config,
916 .poll = ath9k_poll,
917 .irq = ath9k_irq,
918};
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
__be32 out[4]
Definition CIB_PRM.h:8
#define AR_IER_ENABLE
Definition reg.h:56
#define AR_SREV_9485(_ah)
Definition reg.h:868
#define AR_IER_DISABLE
Definition reg.h:57
@ SURVEY_INFO_CHANNEL_TIME_BUSY
Definition ath9k.h:425
@ SURVEY_INFO_IN_USE
Definition ath9k.h:423
@ SURVEY_INFO_CHANNEL_TIME_RX
Definition ath9k.h:427
@ SURVEY_INFO_CHANNEL_TIME
Definition ath9k.h:424
@ SURVEY_INFO_NOISE_DBM
Definition ath9k.h:422
@ SURVEY_INFO_CHANNEL_TIME_TX
Definition ath9k.h:428
void ath_tx_tasklet(struct ath_softc *sc)
Definition ath9k_xmit.c:773
#define SC_OP_PRIM_STA_VIF
Definition ath9k.h:378
int ath_stoprecv(struct ath_softc *sc)
Definition ath9k_recv.c:224
#define PS_BEACON_SYNC
Definition ath9k.h:385
#define ATH_TXQ_SETUP(sc, i)
Definition ath9k.h:63
#define SC_OP_ANI_RUN
Definition ath9k.h:376
#define PS_WAIT_FOR_BEACON
Definition ath9k.h:381
#define SC_OP_PREAMBLE_SHORT
Definition ath9k.h:368
#define ATH_STA_SHORT_CALINTERVAL
Definition ath9k.h:335
@ IEEE80211_TX_RC_USE_SHORT_PREAMBLE
Definition ath9k.h:400
#define SC_OP_OFFCHANNEL
Definition ath9k.h:367
int ath_drain_all_txq(struct ath_softc *sc, int retry_tx)
Definition ath9k_xmit.c:218
#define ATH_LONG_CALINTERVAL
Definition ath9k.h:340
#define SC_OP_PROTECT_ENABLE
Definition ath9k.h:369
#define ATH_RESTART_CALINTERVAL
Definition ath9k.h:341
#define SC_OP_INVALID
Definition ath9k.h:363
int ath_tx_start(struct net80211_device *dev, struct io_buffer *iob, struct ath_tx_control *txctl)
Definition ath9k_xmit.c:571
void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
struct net80211_device_operations ath9k_ops
Definition ath9k_main.c:911
#define SC_OP_BEACONS
Definition ath9k.h:364
void ath_flushrecv(struct ath_softc *sc)
Definition ath9k_recv.c:244
int ath_rx_tasklet(struct ath_softc *sc, int flush, int hp)
Definition ath9k_recv.c:432
int ath_startrecv(struct ath_softc *sc)
Definition ath9k_recv.c:196
#define ATH_LONG_CALINTERVAL_INT
Definition ath9k.h:339
void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan __unused)
Definition ath9k_ani.c:599
int ath9k_hw_reset_calvalid(struct ath_hw *ah)
void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, struct net80211_channel *chan)
struct ath9k_channel * ath9k_cmn_get_curchannel(struct net80211_device *dev, struct ath_hw *ah)
void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow, u16 new_txpow, u16 *txpower)
int ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
Definition ath9k_hw.c:1534
void ath9k_hw_init_global_settings(struct ath_hw *ah)
Definition ath9k_hw.c:814
int ath9k_hw_disable(struct ath_hw *ah)
Definition ath9k_hw.c:1927
int ath9k_hw_phy_disable(struct ath_hw *ah)
Definition ath9k_hw.c:1918
void ath9k_hw_write_associd(struct ath_hw *ah)
Definition ath9k_hw.c:1966
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, struct ath9k_hw_cal_data *caldata, int bChannelChange)
Definition ath9k_hw.c:1218
void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio)
Definition ath9k_hw.c:1785
u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
Definition ath9k_hw.c:611
void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
Definition ath9k_hw.c:1852
int ath9k_hw_check_alive(struct ath_hw *ah)
Definition ath9k_hw.c:1191
int ath9k_hw_intrpend(struct ath_hw *ah)
Definition ath9k_mac.c:585
void ath9k_hw_enable_interrupts(struct ath_hw *ah)
Definition ath9k_mac.c:618
void ath9k_hw_set_interrupts(struct ath_hw *ah, unsigned int ints)
Definition ath9k_mac.c:643
void ath9k_hw_disable_interrupts(struct ath_hw *ah)
Definition ath9k_mac.c:604
int ath9k_hw_updatetxtriglevel(struct ath_hw *ah, int bIncTrigLevel)
ath9k_hw_updatetxtriglevel - adjusts the frame trigger level
Definition ath9k_mac.c:103
int ath9k_hw_setrxabort(struct ath_hw *ah, int set)
Definition ath9k_mac.c:492
int ath_reset(struct ath_softc *sc, int retry_tx)
Definition ath9k_main.c:513
void ath9k_tasklet(struct ath_softc *sc)
Definition ath9k_main.c:341
int ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
Definition ath9k_main.c:28
void ath_radio_disable(struct ath_softc *sc, struct net80211_device *dev)
Definition ath9k_main.c:473
static void ath9k_poll(struct net80211_device *dev)
Definition ath9k_main.c:896
void ath_isr(struct net80211_device *dev)
Definition ath9k_main.c:368
#define SCHED_INTR
static void ath_update_survey_nf(struct ath_softc *sc, int channel)
Definition ath9k_main.c:56
static void ath9k_config_bss(struct ath_softc *sc)
Definition ath9k_main.c:827
static void ath9k_bss_info_changed(struct net80211_device *dev, u32 changed)
Definition ath9k_main.c:856
void ath_hw_pll_work(struct ath_softc *sc)
Definition ath9k_main.c:327
static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
Definition ath9k_main.c:310
static int ath9k_start(struct net80211_device *dev)
Definition ath9k_main.c:567
static int ath9k_config(struct net80211_device *dev, int changed)
Definition ath9k_main.c:710
static int ath_update_survey_stats(struct ath_softc *sc)
Definition ath9k_main.c:73
void ath_hw_check(struct ath_softc *sc)
Definition ath9k_main.c:289
static void ath_start_ani(struct ath_common *common)
Definition ath9k_main.c:37
static void ath9k_irq(struct net80211_device *dev, int enable)
Definition ath9k_main.c:901
int ath_set_channel(struct ath_softc *sc, struct net80211_device *dev, struct ath9k_channel *hchan)
Definition ath9k_main.c:118
static int ath9k_tx(struct net80211_device *dev, struct io_buffer *iob)
Definition ath9k_main.c:644
void ath_ani_calibrate(struct ath_softc *sc)
Definition ath9k_main.c:202
static void ath9k_bss_iter(struct ath_softc *sc)
Definition ath9k_main.c:799
static void ath9k_stop(struct net80211_device *dev)
Definition ath9k_main.c:667
void ath_hw_cycle_counters_update(struct ath_common *common)
ath_hw_cycle_counters_update - common function to update cycle counters
Definition ath_hw.c:139
#define min(x, y)
Definition ath.h:36
#define ATH_RSSI_DUMMY_MARKER
Definition common.h:38
uint64_t timestamp
Timestamp.
Definition ena.h:9
uint8_t status
Status.
Definition ena.h:5
uint16_t mode
Acceleration mode.
Definition ena.h:15
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define DBG2(...)
Definition compiler.h:515
#define DBGIO(...)
Definition compiler.h:549
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define NET80211_BAND_5GHZ
The band from 4.9 GHz to 5.7 GHz, which tends to be more restricted.
Definition net80211.h:47
#define NET80211_CFG_ASSOC
Association has been established with a new BSS (dev->bssid)
Definition net80211.h:87
#define NET80211_CFG_CHANNEL
Channel choice (dev->channel) or regulatory parameters have changed.
Definition net80211.h:81
#define NET80211_CFG_RATE
Requested transmission rate (dev->rate) has changed.
Definition net80211.h:84
#define NET80211_CFG_PHY_PARAMS
Low-level link parameters (short preamble, protection, etc) have changed.
Definition net80211.h:90
#define NET80211_PHY_USE_PROTECTION
Whether to use RTS/CTS or CTS-to-self protection for transmissions.
Definition net80211.h:251
#define NET80211_PHY_USE_SHORT_PREAMBLE
Whether to use 802.11b short preamble operation.
Definition net80211.h:260
#define NET80211_ASSOCIATED
Whether we have successfully associated with the network.
Definition net80211.h:201
#define EINVAL
Invalid argument.
Definition errno.h:429
#define EIO
Input/output error.
Definition errno.h:434
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
static int ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, u8 rxchainmask, int longcal)
Definition hw-ops.h:50
static void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off)
Definition hw-ops.h:27
static int ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
Definition hw-ops.h:58
@ ATH9K_HW_CAP_AUTOSLEEP
Definition hw.h:185
ath9k_power_mode
Definition hw.h:379
@ ATH9K_PM_AWAKE
Definition hw.h:380
static struct ath_common * ath9k_hw_common(struct ath_hw *ah)
Definition hw.h:870
ath9k_int
Definition hw.h:252
@ ATH9K_INT_RX
Definition hw.h:253
@ ATH9K_INT_TX
Definition hw.h:260
@ ATH9K_INT_TXURN
Definition hw.h:264
@ ATH9K_INT_RXEOL
Definition hw.h:258
@ ATH9K_INT_TIM_TIMER
Definition hw.h:262
@ ATH9K_INT_BB_WATCHDOG
Definition hw.h:263
@ ATH9K_INT_GLOBAL
Definition hw.h:281
@ ATH9K_INT_RXORN
Definition hw.h:259
@ ATH9K_INT_FATAL
Definition hw.h:280
struct ib_cm_common common
Definition ib_mad.h:0
#define ETH_ALEN
Definition if_ether.h:9
iPXE I/O API
#define TICKS_PER_SEC
Number of ticks per second.
Definition timer.h:16
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
#define ATH9K_NUM_TX_QUEUES
Definition mac.h:581
static const uint8_t r[3][4]
MD4 shift amounts.
Definition md4.c:54
#define NET80211_MAX_RATES
The maximum number of TX rates we allow to be configured simultaneously.
Definition net80211.h:272
uint32_t channel
RNDIS channel.
Definition netvsc.h:3
uint8_t ah
Definition registers.h:1
u32 avgbrssi
Definition ani.h:159
u16 channel
Definition hw.h:350
struct net80211_channel * chan
Definition hw.h:348
s16 noisefloor
Definition hw.h:353
u32 enable_ani
Definition hw.h:232
struct net80211_device * dev
Definition ath.h:199
u16 txpowlimit
Definition ath9k.h:66
Definition hw.h:657
struct ath9k_ops_config config
Definition hw.h:663
struct net80211_device * dev
Definition hw.h:660
struct ar5416Stats stats
Definition hw.h:696
struct ath9k_channel channels[ATH9K_NUM_CHANNELS]
Definition hw.h:665
enum ath9k_power_mode power_mode
Definition hw.h:692
int is_monitoring
Definition hw.h:678
struct ath9k_channel * curchan
Definition hw.h:666
u32 * rxlink
Definition ath9k.h:300
struct io_buffer * frag
Definition ath9k.h:307
void(* tx_complete_work)(struct ath_softc *sc)
Definition ath9k.h:485
void(* intr_tq)(struct ath_softc *sc)
Definition ath9k.h:454
void(* hw_pll_work)(struct ath_softc *sc)
Definition ath9k.h:487
struct net80211_device * dev
Definition ath9k.h:446
struct ath9k_hw_cal_data caldata
Definition ath9k.h:482
unsigned long hw_pll_work_timer
Definition ath9k.h:488
int hw_rix
Definition ath9k.h:480
int ps_idle
Definition ath9k.h:470
int last_rssi
Definition ath9k.h:483
u16 curtxpow
Definition ath9k.h:468
u32 sc_flags
Definition ath9k.h:466
unsigned int hw_busy_count
Definition ath9k.h:463
struct survey_info survey[ATH9K_NUM_CHANNELS]
Definition ath9k.h:452
struct ath_tx tx
Definition ath9k.h:477
struct ath_rx rx
Definition ath9k.h:476
struct ath_config config
Definition ath9k.h:475
unsigned long tx_complete_work_timer
Definition ath9k.h:486
struct ath_hw * sc_ah
Definition ath9k.h:455
struct ath9k_legacy_rate rates[NET80211_MAX_RATES]
Definition ath9k.h:479
u32 intrstatus
Definition ath9k.h:465
u16 ps_flags
Definition ath9k.h:467
int chan_idx
Definition ath9k.h:449
struct survey_info * cur_survey
Definition ath9k.h:451
struct ath_txq * txq
Definition ath9k.h:267
struct ath_txq txq[ATH9K_NUM_TX_QUEUES]
Definition ath9k.h:286
struct ath_txq * txq_map[WME_NUM_AC]
Definition ath9k.h:288
A persistent I/O buffer.
Definition iobuf.h:38
An 802.11 RF channel.
Definition net80211.h:386
u16 hw_value
Hardware channel value.
Definition net80211.h:414
u8 maxpower
Maximum allowable transmit power, in dBm.
Definition net80211.h:425
u16 center_freq
The center frequency for this channel.
Definition net80211.h:411
Operations that must be implemented by an 802.11 driver.
Definition net80211.h:293
Structure encapsulating the complete state of an 802.11 device.
Definition net80211.h:787
u16 rates[NET80211_MAX_RATES]
A list of all possible TX rates we might use.
Definition net80211.h:818
struct net80211_channel channels[NET80211_MAX_CHANNELS]
A list of all possible channels we might use.
Definition net80211.h:806
void * priv
Driver private data.
Definition net80211.h:798
u8 rtscts_rate
The rate to use for RTS/CTS transmissions.
Definition net80211.h:831
u16 state
State of our association to the network.
Definition net80211.h:921
u8 channel
The channel currently in use, as an index into the channels array.
Definition net80211.h:812
int phy_flags
Physical layer options.
Definition net80211.h:983
u8 rate
The rate currently in use, as an index into the rates array.
Definition net80211.h:824
u64 channel_time
Definition ath9k.h:412
u32 filled
Definition ath9k.h:417
u64 channel_time_rx
Definition ath9k.h:415
u64 channel_time_busy
Definition ath9k.h:413
u64 channel_time_tx
Definition ath9k.h:416
unsigned long currticks(void)
Get current system time in ticks.
Definition timer.c:43
#define u16
Definition vga.h:20
#define u32
Definition vga.h:21