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 FILE_SECBOOT ( FORBIDDEN );
21 
22 #include <ipxe/io.h>
23 
24 #include "ath9k.h"
25 
26 static 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 
37 static 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 
56 static 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) {
63  survey->filled |= SURVEY_INFO_NOISE_DBM;
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  */
73 static 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) {
90  survey->filled |= SURVEY_INFO_CHANNEL_TIME |
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 */
118 int 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;
122  struct ath_common *common = ath9k_hw_common(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;
134  sc->tx_complete_work_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 
152  if (!ath9k_hw_check_alive(ah))
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);
183  ath9k_hw_set_interrupts(ah, ah->imask);
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  */
202 void ath_ani_calibrate(struct ath_softc *sc)
203 {
204  struct ath_hw *ah = sc->sc_ah;
205  struct ath_common *common = ath9k_hw_common(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 
273 set_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 
289 void ath_hw_check(struct ath_softc *sc)
290 {
291  int busy;
292 
293  if (ath9k_hw_check_alive(sc->sc_ah))
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 
306 out:
307  return;
308 }
309 
310 static 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 
327 void ath_hw_pll_work(struct ath_softc *sc)
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 
341 void 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;
386  struct ath_common *common = ath9k_hw_common(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)
402  ath_ani_calibrate(sc);
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 
446  if (status & ATH9K_INT_TXURN)
448 
449  if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
450  if (status & ATH9K_INT_TIM_TIMER) {
451  if (sc->ps_idle)
452  goto chip_reset;
453  /* Clear RxAbort bit so that we can
454  * receive frames */
456  ath9k_hw_setrxabort(sc->sc_ah, 0);
458  }
459 
460 chip_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 
513 int ath_reset(struct ath_softc *sc, int retry_tx)
514 {
515  struct ath_hw *ah = sc->sc_ah;
516  struct ath_common *common = ath9k_hw_common(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 
546  ath9k_hw_set_interrupts(ah, ah->imask);
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 
567 static int ath9k_start(struct net80211_device *dev)
568 {
569  struct ath_softc *sc = dev->priv;
570  struct ath_hw *ah = sc->sc_ah;
571  struct ath_common *common = ath9k_hw_common(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 
630  sc->sc_flags &= ~SC_OP_INVALID;
631  sc->sc_ah->is_monitoring = 0;
632 
633  ath9k_hw_set_interrupts(ah, ah->imask);
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 
640 mutex_unlock:
641  return r;
642 }
643 
644 static 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;
662 exit:
663  free_iob(iob);
664  return ret;
665 }
666 
667 static void ath9k_stop(struct net80211_device *dev)
668 {
669  struct ath_softc *sc = dev->priv;
670  struct ath_hw *ah = sc->sc_ah;
671 
672  sc->tx_complete_work_timer = 0;
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 
703  ath_radio_disable(sc, dev);
704 
705  sc->sc_flags |= SC_OP_INVALID;
706 
707  DBG("ath9k: Driver halt\n");
708 }
709 
710 static 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 
743  sc->sc_flags &= ~SC_OP_OFFCHANNEL;
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 
799 static 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 
827 static 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 */
851  sc->sc_flags &= ~SC_OP_ANI_RUN;
852  common->ani.timer = 0;
853  }
854 }
855 
856 static void ath9k_bss_info_changed(struct net80211_device *dev,
857  u32 changed)
858 {
859  struct ath_softc *sc = dev->priv;
860  struct ath_hw *ah = sc->sc_ah;
861  struct ath_common *common = ath9k_hw_common(ah);
862  int slottime;
863 
864  if (changed & NET80211_CFG_ASSOC) {
865  ath9k_config_bss(sc);
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",
889  (dev->channels + dev->channel)->band != NET80211_BAND_5GHZ)
891  else
893  }
894 }
895 
896 static void ath9k_poll(struct net80211_device *dev)
897 {
898  ath_isr(dev);
899 }
900 
901 static 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 
908  ath9k_hw_set_interrupts(ah, ah->imask);
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 };
uint16_t u16
Definition: stdint.h:22
#define EINVAL
Invalid argument.
Definition: errno.h:429
int ath9k_hw_disable(struct ath_hw *ah)
Definition: ath9k_hw.c:1927
static int ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
Definition: hw-ops.h:58
void ath9k_hw_write_associd(struct ath_hw *ah)
Definition: ath9k_hw.c:1966
u16 channel
Definition: hw.h:350
iPXE I/O API
s8 noise
Definition: ath9k.h:418
#define SC_OP_PRIM_STA_VIF
Definition: ath9k.h:378
Definition: hw.h:657
u64 channel_time
Definition: ath9k.h:412
int ath9k_hw_setrxabort(struct ath_hw *ah, int set)
Definition: ath9k_mac.c:492
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:16
unsigned long tx_complete_work_timer
Definition: ath9k.h:486
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
u32 enable_ani
Definition: hw.h:232
void ath9k_hw_enable_interrupts(struct ath_hw *ah)
Definition: ath9k_mac.c:618
int ath_rx_tasklet(struct ath_softc *sc, int flush, int hp)
Definition: ath9k_recv.c:432
int ps_idle
Definition: ath9k.h:470
#define ATH_STA_SHORT_CALINTERVAL
Definition: ath9k.h:335
struct ath9k_channel * curchan
Definition: hw.h:666
void ath_tx_tasklet(struct ath_softc *sc)
Definition: ath9k_xmit.c:773
struct survey_info * cur_survey
Definition: ath9k.h:451
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:814
u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
Definition: ath9k_hw.c:611
#define ATH_RESTART_CALINTERVAL
Definition: ath9k.h:341
u16 ps_flags
Definition: ath9k.h:467
u64 channel_time_rx
Definition: ath9k.h:415
u32 avgbrssi
Definition: ani.h:159
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
uint16_t mode
Acceleration mode.
Definition: ena.h:26
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:56
ath9k_int
Definition: hw.h:252
#define min(x, y)
Definition: ath.h:36
enum ath9k_power_mode power_mode
Definition: hw.h:692
#define PS_BEACON_SYNC
Definition: ath9k.h:385
struct ath_txq * txq
Definition: ath9k.h:267
#define ATH_TXQ_SETUP(sc, i)
Definition: ath9k.h:63
#define AR_SREV_9485(_ah)
Definition: reg.h:868
#define SC_OP_ANI_RUN
Definition: ath9k.h:376
struct net80211_device_operations ath9k_ops
Definition: ath9k_main.c:911
int ath_tx_start(struct net80211_device *dev, struct io_buffer *iob, struct ath_tx_control *txctl)
Definition: ath9k_xmit.c:571
int is_monitoring
Definition: hw.h:678
static void ath_start_ani(struct ath_common *common)
Definition: ath9k_main.c:37
struct ath_txq txq[ATH9K_NUM_TX_QUEUES]
Definition: ath9k.h:286
void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow, u16 new_txpow, u16 *txpower)
Definition: ath9k_common.c:63
int ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
Definition: ath9k_main.c:28
static void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off)
Definition: hw-ops.h:27
struct net80211_channel * chan
Definition: hw.h:348
int ath_drain_all_txq(struct ath_softc *sc, int retry_tx)
Definition: ath9k_xmit.c:218
__be32 out[4]
Definition: CIB_PRM.h:36
void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan __unused)
Definition: ath9k_ani.c:599
#define SC_OP_PREAMBLE_SHORT
Definition: ath9k.h:368
#define AR_IER_ENABLE
Definition: reg.h:56
static int ath9k_start(struct net80211_device *dev)
Definition: ath9k_main.c:567
void ath9k_tasklet(struct ath_softc *sc)
Definition: ath9k_main.c:341
u64 channel_time_busy
Definition: ath9k.h:413
struct net80211_device * dev
Definition: ath9k.h:446
static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
Definition: ath9k_main.c:310
#define SC_OP_OFFCHANNEL
Definition: ath9k.h:367
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:139
void * memcpy(void *dest, const void *src, size_t len) __nonnull
int ath9k_hw_reset_calvalid(struct ath_hw *ah)
Definition: ath9k_calib.c:175
u16 hw_value
Hardware channel value.
Definition: net80211.h:414
struct ar5416Stats stats
Definition: hw.h:696
void(* tx_complete_work)(struct ath_softc *sc)
Definition: ath9k.h:485
void ath_ani_calibrate(struct ath_softc *sc)
Definition: ath9k_main.c:202
u8 maxpower
Maximum allowable transmit power, in dBm.
Definition: net80211.h:425
struct ath_hw * sc_ah
Definition: ath9k.h:455
ath9k_power_mode
Definition: hw.h:379
static void ath9k_irq(struct net80211_device *dev, int enable)
Definition: ath9k_main.c:901
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
struct ath_config config
Definition: ath9k.h:475
#define SCHED_INTR
#define ATH_LONG_CALINTERVAL_INT
Definition: ath9k.h:339
void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
Definition: ath9k_hw.c:1852
void ath_radio_disable(struct ath_softc *sc, struct net80211_device *dev)
Definition: ath9k_main.c:473
int ath9k_hw_intrpend(struct ath_hw *ah)
Definition: ath9k_mac.c:585
void ath9k_hw_set_interrupts(struct ath_hw *ah, unsigned int ints)
Definition: ath9k_mac.c:643
static unsigned int count
Number of entries.
Definition: dwmac.h:225
void(* hw_pll_work)(struct ath_softc *sc)
Definition: ath9k.h:487
struct ath9k_ops_config config
Definition: hw.h:663
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
uint64_t timestamp
Timestamp.
Definition: ena.h:20
int last_rssi
Definition: ath9k.h:483
struct ath9k_channel * ath9k_cmn_get_curchannel(struct net80211_device *dev, struct ath_hw *ah)
Definition: ath9k_common.c:49
int ath9k_hw_phy_disable(struct ath_hw *ah)
Definition: ath9k_hw.c:1918
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:604
#define DBGIO(...)
Definition: compiler.h:549
#define ATH_RSSI_DUMMY_MARKER
Definition: common.h:38
#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:417
static int ath_update_survey_stats(struct ath_softc *sc)
Definition: ath9k_main.c:73
struct ath_rx rx
Definition: ath9k.h:476
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:31
#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:307
#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:1785
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:513
static void ath9k_poll(struct net80211_device *dev)
Definition: ath9k_main.c:896
u32 * rxlink
Definition: ath9k.h:300
An 802.11 RF channel.
Definition: net80211.h:385
#define ATH9K_NUM_TX_QUEUES
Definition: mac.h:581
static struct ath_common * ath9k_hw_common(struct ath_hw *ah)
Definition: hw.h:870
int hw_rix
Definition: ath9k.h:480
u16 curtxpow
Definition: ath9k.h:468
struct ath_tx tx
Definition: ath9k.h:477
static int ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, u8 rxchainmask, int longcal)
Definition: hw-ops.h:50
int ath9k_hw_updatetxtriglevel(struct ath_hw *ah, int bIncTrigLevel)
ath9k_hw_updatetxtriglevel - adjusts the frame trigger level
Definition: ath9k_mac.c:103
unsigned int hw_busy_count
Definition: ath9k.h:463
#define ETH_ALEN
Definition: if_ether.h:9
static int ath9k_config(struct net80211_device *dev, int changed)
Definition: ath9k_main.c:710
struct ib_cm_common common
Definition: ib_mad.h:12
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:466
#define SC_OP_INVALID
Definition: ath9k.h:363
unsigned long hw_pll_work_timer
Definition: ath9k.h:488
#define ATH_LONG_CALINTERVAL
Definition: ath9k.h:340
struct net80211_device * dev
Definition: hw.h:660
int phy_flags
Physical layer options.
Definition: net80211.h:983
uint8_t status
Status.
Definition: ena.h:16
static void ath9k_bss_iter(struct ath_softc *sc)
Definition: ath9k_main.c:799
#define PS_WAIT_FOR_BEACON
Definition: ath9k.h:381
s16 noisefloor
Definition: hw.h:353
int ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
Definition: ath9k_hw.c:1534
static int ath9k_tx(struct net80211_device *dev, struct io_buffer *iob)
Definition: ath9k_main.c:644
int ath_startrecv(struct ath_softc *sc)
Definition: ath9k_recv.c:196
#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:416
int ath_set_channel(struct ath_softc *sc, struct net80211_device *dev, struct ath9k_channel *hchan)
Definition: ath9k_main.c:118
struct ath9k_hw_cal_data caldata
Definition: ath9k.h:482
#define AR_IER_DISABLE
Definition: reg.h:57
void ath_hw_check(struct ath_softc *sc)
Definition: ath9k_main.c:289
#define EIO
Input/output error.
Definition: errno.h:434
void ath_hw_pll_work(struct ath_softc *sc)
Definition: ath9k_main.c:327
struct net80211_channel channels[NET80211_MAX_CHANNELS]
A list of all possible channels we might use.
Definition: net80211.h:806
void ath_flushrecv(struct ath_softc *sc)
Definition: ath9k_recv.c:244
u32 intrstatus
Definition: ath9k.h:465
int ath9k_hw_check_alive(struct ath_hw *ah)
Definition: ath9k_hw.c:1191
#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:452
void(* intr_tq)(struct ath_softc *sc)
Definition: ath9k.h:454
static void ath9k_stop(struct net80211_device *dev)
Definition: ath9k_main.c:667
u16 txpowlimit
Definition: ath9k.h:66
uint8_t ah
Definition: registers.h:85
FILE_SECBOOT(FORBIDDEN)
#define NET80211_CFG_CHANNEL
Channel choice (dev->channel) or regulatory parameters have changed.
Definition: net80211.h:81
int chan_idx
Definition: ath9k.h:449
struct ath9k_legacy_rate rates[NET80211_MAX_RATES]
Definition: ath9k.h:479
struct net80211_device * dev
Definition: ath.h:199
#define SC_OP_PROTECT_ENABLE
Definition: ath9k.h:369
struct ath9k_channel channels[ATH9K_NUM_CHANNELS]
Definition: hw.h:665
u16 state
State of our association to the network.
Definition: net80211.h:921
int ath_stoprecv(struct ath_softc *sc)
Definition: ath9k_recv.c:224
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:43
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
struct ath_txq * txq_map[WME_NUM_AC]
Definition: ath9k.h:288
#define SC_OP_BEACONS
Definition: ath9k.h:364
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
void ath_isr(struct net80211_device *dev)
Definition: ath9k_main.c:368
static void ath9k_bss_info_changed(struct net80211_device *dev, u32 changed)
Definition: ath9k_main.c:856
#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:24
#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:827
static const uint8_t r[3][4]
MD4 shift amounts.
Definition: md4.c:54
A persistent I/O buffer.
Definition: iobuf.h:38