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