LCOV - code coverage report
Current view: top level - dev/ic - ar9003.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 1759 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 74 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: ar9003.c,v 1.46 2017/05/19 11:42:48 stsp Exp $        */
       2             : 
       3             : /*-
       4             :  * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
       5             :  * Copyright (c) 2010 Atheros Communications Inc.
       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             : /*
      21             :  * Driver for Atheros 802.11a/g/n chipsets.
      22             :  * Routines for AR9003 family.
      23             :  */
      24             : 
      25             : #include "bpfilter.h"
      26             : 
      27             : #include <sys/param.h>
      28             : #include <sys/sockio.h>
      29             : #include <sys/mbuf.h>
      30             : #include <sys/kernel.h>
      31             : #include <sys/socket.h>
      32             : #include <sys/systm.h>
      33             : #include <sys/malloc.h>
      34             : #include <sys/queue.h>
      35             : #include <sys/timeout.h>
      36             : #include <sys/conf.h>
      37             : #include <sys/device.h>
      38             : #include <sys/stdint.h>   /* uintptr_t */
      39             : #include <sys/endian.h>
      40             : 
      41             : #include <machine/bus.h>
      42             : 
      43             : #if NBPFILTER > 0
      44             : #include <net/bpf.h>
      45             : #endif
      46             : #include <net/if.h>
      47             : #include <net/if_media.h>
      48             : 
      49             : #include <netinet/in.h>
      50             : #include <netinet/if_ether.h>
      51             : 
      52             : #include <net80211/ieee80211_var.h>
      53             : #include <net80211/ieee80211_amrr.h>
      54             : #include <net80211/ieee80211_mira.h>
      55             : #include <net80211/ieee80211_radiotap.h>
      56             : 
      57             : #include <dev/ic/athnreg.h>
      58             : #include <dev/ic/athnvar.h>
      59             : 
      60             : #include <dev/ic/ar9003reg.h>
      61             : 
      62             : int     ar9003_attach(struct athn_softc *);
      63             : int     ar9003_read_eep_word(struct athn_softc *, uint32_t, uint16_t *);
      64             : int     ar9003_read_eep_data(struct athn_softc *, uint32_t, void *, int);
      65             : int     ar9003_read_otp_word(struct athn_softc *, uint32_t, uint32_t *);
      66             : int     ar9003_read_otp_data(struct athn_softc *, uint32_t, void *, int);
      67             : int     ar9003_find_rom(struct athn_softc *);
      68             : int     ar9003_restore_rom_block(struct athn_softc *, uint8_t, uint8_t,
      69             :             const uint8_t *, int);
      70             : int     ar9003_read_rom(struct athn_softc *);
      71             : int     ar9003_gpio_read(struct athn_softc *, int);
      72             : void    ar9003_gpio_write(struct athn_softc *, int, int);
      73             : void    ar9003_gpio_config_input(struct athn_softc *, int);
      74             : void    ar9003_gpio_config_output(struct athn_softc *, int, int);
      75             : void    ar9003_rfsilent_init(struct athn_softc *);
      76             : int     ar9003_dma_alloc(struct athn_softc *);
      77             : void    ar9003_dma_free(struct athn_softc *);
      78             : int     ar9003_tx_alloc(struct athn_softc *);
      79             : void    ar9003_tx_free(struct athn_softc *);
      80             : int     ar9003_rx_alloc(struct athn_softc *, int, int);
      81             : void    ar9003_rx_free(struct athn_softc *, int);
      82             : void    ar9003_reset_txsring(struct athn_softc *);
      83             : void    ar9003_rx_enable(struct athn_softc *);
      84             : void    ar9003_rx_radiotap(struct athn_softc *, struct mbuf *,
      85             :             struct ar_rx_status *);
      86             : int     ar9003_rx_process(struct athn_softc *, int);
      87             : void    ar9003_rx_intr(struct athn_softc *, int);
      88             : int     ar9003_tx_process(struct athn_softc *);
      89             : void    ar9003_tx_intr(struct athn_softc *);
      90             : int     ar9003_swba_intr(struct athn_softc *);
      91             : int     ar9003_intr(struct athn_softc *);
      92             : int     ar9003_tx(struct athn_softc *, struct mbuf *, struct ieee80211_node *,
      93             :             int);
      94             : void    ar9003_set_rf_mode(struct athn_softc *, struct ieee80211_channel *);
      95             : int     ar9003_rf_bus_request(struct athn_softc *);
      96             : void    ar9003_rf_bus_release(struct athn_softc *);
      97             : void    ar9003_set_phy(struct athn_softc *, struct ieee80211_channel *,
      98             :             struct ieee80211_channel *);
      99             : void    ar9003_set_delta_slope(struct athn_softc *, struct ieee80211_channel *,
     100             :             struct ieee80211_channel *);
     101             : void    ar9003_enable_antenna_diversity(struct athn_softc *);
     102             : void    ar9003_init_baseband(struct athn_softc *);
     103             : void    ar9003_disable_phy(struct athn_softc *);
     104             : void    ar9003_init_chains(struct athn_softc *);
     105             : void    ar9003_set_rxchains(struct athn_softc *);
     106             : void    ar9003_read_noisefloor(struct athn_softc *, int16_t *, int16_t *);
     107             : void    ar9003_write_noisefloor(struct athn_softc *, int16_t *, int16_t *);
     108             : void    ar9003_get_noisefloor(struct athn_softc *, struct ieee80211_channel *);
     109             : void    ar9003_bb_load_noisefloor(struct athn_softc *);
     110             : void    ar9300_noisefloor_calib(struct athn_softc *);
     111             : void    ar9003_do_noisefloor_calib(struct athn_softc *);
     112             : int     ar9003_init_calib(struct athn_softc *);
     113             : void    ar9003_do_calib(struct athn_softc *);
     114             : void    ar9003_next_calib(struct athn_softc *);
     115             : void    ar9003_calib_iq(struct athn_softc *);
     116             : int     ar9003_get_iq_corr(struct athn_softc *, int32_t[], int32_t[]);
     117             : int     ar9003_calib_tx_iq(struct athn_softc *);
     118             : void    ar9003_paprd_calib(struct athn_softc *, struct ieee80211_channel *);
     119             : int     ar9003_get_desired_txgain(struct athn_softc *, int, int);
     120             : void    ar9003_force_txgain(struct athn_softc *, uint32_t);
     121             : void    ar9003_set_training_gain(struct athn_softc *, int);
     122             : int     ar9003_paprd_tx_tone(struct athn_softc *);
     123             : int     ar9003_compute_predistortion(struct athn_softc *, const uint32_t *,
     124             :             const uint32_t *);
     125             : void    ar9003_enable_predistorter(struct athn_softc *, int);
     126             : void    ar9003_paprd_enable(struct athn_softc *);
     127             : void    ar9003_paprd_tx_tone_done(struct athn_softc *);
     128             : void    ar9003_write_txpower(struct athn_softc *, int16_t power[]);
     129             : void    ar9003_reset_rx_gain(struct athn_softc *, struct ieee80211_channel *);
     130             : void    ar9003_reset_tx_gain(struct athn_softc *, struct ieee80211_channel *);
     131             : void    ar9003_hw_init(struct athn_softc *, struct ieee80211_channel *,
     132             :             struct ieee80211_channel *);
     133             : void    ar9003_get_lg_tpow(struct athn_softc *, struct ieee80211_channel *,
     134             :             uint8_t, const uint8_t *, const struct ar_cal_target_power_leg *,
     135             :             int, uint8_t[]);
     136             : void    ar9003_get_ht_tpow(struct athn_softc *, struct ieee80211_channel *,
     137             :             uint8_t, const uint8_t *, const struct ar_cal_target_power_ht *,
     138             :             int, uint8_t[]);
     139             : void    ar9003_set_noise_immunity_level(struct athn_softc *, int);
     140             : void    ar9003_enable_ofdm_weak_signal(struct athn_softc *);
     141             : void    ar9003_disable_ofdm_weak_signal(struct athn_softc *);
     142             : void    ar9003_set_cck_weak_signal(struct athn_softc *, int);
     143             : void    ar9003_set_firstep_level(struct athn_softc *, int);
     144             : void    ar9003_set_spur_immunity_level(struct athn_softc *, int);
     145             : 
     146             : /* Extern functions. */
     147             : void    athn_stop(struct ifnet *, int);
     148             : int     athn_interpolate(int, int, int, int, int);
     149             : int     athn_txtime(struct athn_softc *, int, int, u_int);
     150             : void    athn_inc_tx_trigger_level(struct athn_softc *);
     151             : int     athn_tx_pending(struct athn_softc *, int);
     152             : void    athn_stop_tx_dma(struct athn_softc *, int);
     153             : void    athn_get_delta_slope(uint32_t, uint32_t *, uint32_t *);
     154             : void    athn_config_pcie(struct athn_softc *);
     155             : void    athn_config_nonpcie(struct athn_softc *);
     156             : uint8_t athn_chan2fbin(struct ieee80211_channel *);
     157             : 
     158             : 
     159             : int
     160           0 : ar9003_attach(struct athn_softc *sc)
     161             : {
     162           0 :         struct athn_ops *ops = &sc->ops;
     163             :         int error;
     164             : 
     165             :         /* Set callbacks for AR9003 family. */
     166           0 :         ops->gpio_read = ar9003_gpio_read;
     167           0 :         ops->gpio_write = ar9003_gpio_write;
     168           0 :         ops->gpio_config_input = ar9003_gpio_config_input;
     169           0 :         ops->gpio_config_output = ar9003_gpio_config_output;
     170           0 :         ops->rfsilent_init = ar9003_rfsilent_init;
     171             : 
     172           0 :         ops->dma_alloc = ar9003_dma_alloc;
     173           0 :         ops->dma_free = ar9003_dma_free;
     174           0 :         ops->rx_enable = ar9003_rx_enable;
     175           0 :         ops->intr = ar9003_intr;
     176           0 :         ops->tx = ar9003_tx;
     177             : 
     178           0 :         ops->set_rf_mode = ar9003_set_rf_mode;
     179           0 :         ops->rf_bus_request = ar9003_rf_bus_request;
     180           0 :         ops->rf_bus_release = ar9003_rf_bus_release;
     181           0 :         ops->set_phy = ar9003_set_phy;
     182           0 :         ops->set_delta_slope = ar9003_set_delta_slope;
     183           0 :         ops->enable_antenna_diversity = ar9003_enable_antenna_diversity;
     184           0 :         ops->init_baseband = ar9003_init_baseband;
     185           0 :         ops->disable_phy = ar9003_disable_phy;
     186           0 :         ops->set_rxchains = ar9003_set_rxchains;
     187           0 :         ops->noisefloor_calib = ar9003_do_noisefloor_calib;
     188           0 :         ops->do_calib = ar9003_do_calib;
     189           0 :         ops->next_calib = ar9003_next_calib;
     190           0 :         ops->hw_init = ar9003_hw_init;
     191             : 
     192           0 :         ops->set_noise_immunity_level = ar9003_set_noise_immunity_level;
     193           0 :         ops->enable_ofdm_weak_signal = ar9003_enable_ofdm_weak_signal;
     194           0 :         ops->disable_ofdm_weak_signal = ar9003_disable_ofdm_weak_signal;
     195           0 :         ops->set_cck_weak_signal = ar9003_set_cck_weak_signal;
     196           0 :         ops->set_firstep_level = ar9003_set_firstep_level;
     197           0 :         ops->set_spur_immunity_level = ar9003_set_spur_immunity_level;
     198             : 
     199             :         /* Set MAC registers offsets. */
     200           0 :         sc->obs_off = AR_OBS;
     201           0 :         sc->gpio_input_en_off = AR_GPIO_INPUT_EN_VAL;
     202             : 
     203           0 :         if (!(sc->flags & ATHN_FLAG_PCIE))
     204           0 :                 athn_config_nonpcie(sc);
     205             :         else
     206           0 :                 athn_config_pcie(sc);
     207             : 
     208             :         /* Determine ROM type and location. */
     209           0 :         if ((error = ar9003_find_rom(sc)) != 0) {
     210           0 :                 printf("%s: could not find ROM\n", sc->sc_dev.dv_xname);
     211           0 :                 return (error);
     212             :         }
     213             :         /* Read entire ROM content in memory. */
     214           0 :         if ((error = ar9003_read_rom(sc)) != 0) {
     215           0 :                 printf("%s: could not read ROM\n", sc->sc_dev.dv_xname);
     216           0 :                 return (error);
     217             :         }
     218             : 
     219             :         /* Determine if it is a non-enterprise AR9003 card. */
     220           0 :         if (AR_READ(sc, AR_ENT_OTP) & AR_ENT_OTP_MPSD)
     221           0 :                 sc->flags |= ATHN_FLAG_NON_ENTERPRISE;
     222             : 
     223           0 :         ops->setup(sc);
     224           0 :         return (0);
     225           0 : }
     226             : 
     227             : /*
     228             :  * Read 16-bit word from EEPROM.
     229             :  */
     230             : int
     231           0 : ar9003_read_eep_word(struct athn_softc *sc, uint32_t addr, uint16_t *val)
     232             : {
     233             :         uint32_t reg;
     234             :         int ntries;
     235             : 
     236           0 :         reg = AR_READ(sc, AR_EEPROM_OFFSET(addr));
     237           0 :         for (ntries = 0; ntries < 1000; ntries++) {
     238           0 :                 reg = AR_READ(sc, AR_EEPROM_STATUS_DATA);
     239           0 :                 if (!(reg & (AR_EEPROM_STATUS_DATA_BUSY |
     240             :                     AR_EEPROM_STATUS_DATA_PROT_ACCESS))) {
     241           0 :                         *val = MS(reg, AR_EEPROM_STATUS_DATA_VAL);
     242           0 :                         return (0);
     243             :                 }
     244           0 :                 DELAY(10);
     245             :         }
     246           0 :         *val = 0xffff;
     247           0 :         return (ETIMEDOUT);
     248           0 : }
     249             : 
     250             : /*
     251             :  * Read an arbitrary number of bytes at a specified address in EEPROM.
     252             :  * NB: The address may not be 16-bit aligned.
     253             :  */
     254             : int
     255           0 : ar9003_read_eep_data(struct athn_softc *sc, uint32_t addr, void *buf, int len)
     256             : {
     257             :         uint8_t *dst = buf;
     258           0 :         uint16_t val;
     259             :         int error;
     260             : 
     261           0 :         if (len > 0 && (addr & 1)) {
     262             :                 /* Deal with non-aligned reads. */
     263           0 :                 addr >>= 1;
     264           0 :                 error = ar9003_read_eep_word(sc, addr, &val);
     265           0 :                 if (error != 0)
     266           0 :                         return (error);
     267           0 :                 *dst++ = val & 0xff;
     268           0 :                 addr--;
     269           0 :                 len--;
     270           0 :         } else
     271           0 :                 addr >>= 1;
     272           0 :         for (; len >= 2; addr--, len -= 2) {
     273           0 :                 error = ar9003_read_eep_word(sc, addr, &val);
     274           0 :                 if (error != 0)
     275           0 :                         return (error);
     276           0 :                 *dst++ = val >> 8;
     277           0 :                 *dst++ = val & 0xff;
     278             :         }
     279           0 :         if (len > 0) {
     280           0 :                 error = ar9003_read_eep_word(sc, addr, &val);
     281           0 :                 if (error != 0)
     282           0 :                         return (error);
     283           0 :                 *dst++ = val >> 8;
     284           0 :         }
     285           0 :         return (0);
     286           0 : }
     287             : 
     288             : /*
     289             :  * Read 32-bit word from OTPROM.
     290             :  */
     291             : int
     292           0 : ar9003_read_otp_word(struct athn_softc *sc, uint32_t addr, uint32_t *val)
     293             : {
     294             :         uint32_t reg;
     295             :         int ntries;
     296             : 
     297           0 :         reg = AR_READ(sc, AR_OTP_BASE(addr));
     298           0 :         for (ntries = 0; ntries < 1000; ntries++) {
     299           0 :                 reg = AR_READ(sc, AR_OTP_STATUS);
     300           0 :                 if (MS(reg, AR_OTP_STATUS_TYPE) == AR_OTP_STATUS_VALID) {
     301           0 :                         *val = AR_READ(sc, AR_OTP_READ_DATA);
     302           0 :                         return (0);
     303             :                 }
     304           0 :                 DELAY(10);
     305             :         }
     306           0 :         return (ETIMEDOUT);
     307           0 : }
     308             : 
     309             : /*
     310             :  * Read an arbitrary number of bytes at a specified address in OTPROM.
     311             :  * NB: The address may not be 32-bit aligned.
     312             :  */
     313             : int
     314           0 : ar9003_read_otp_data(struct athn_softc *sc, uint32_t addr, void *buf, int len)
     315             : {
     316             :         uint8_t *dst = buf;
     317           0 :         uint32_t val;
     318             :         int error;
     319             : 
     320             :         /* NB: not optimal for non-aligned reads, but correct. */
     321           0 :         for (; len > 0; addr--, len--) {
     322           0 :                 error = ar9003_read_otp_word(sc, addr >> 2, &val);
     323           0 :                 if (error != 0)
     324           0 :                         return (error);
     325           0 :                 *dst++ = (val >> ((addr & 3) * 8)) & 0xff;
     326             :         }
     327           0 :         return (0);
     328           0 : }
     329             : 
     330             : /*
     331             :  * Determine if the chip has an external EEPROM or an OTPROM and its size.
     332             :  */
     333             : int
     334           0 : ar9003_find_rom(struct athn_softc *sc)
     335             : {
     336           0 :         struct athn_ops *ops = &sc->ops;
     337           0 :         uint32_t hdr;
     338             :         int error;
     339             : 
     340             :         /* Try EEPROM. */
     341           0 :         ops->read_rom_data = ar9003_read_eep_data;
     342             : 
     343           0 :         sc->eep_size = AR_SREV_9485(sc) ? 4096 : 1024;
     344           0 :         sc->eep_base = sc->eep_size - 1;
     345           0 :         error = ops->read_rom_data(sc, sc->eep_base, &hdr, sizeof(hdr));
     346           0 :         if (error == 0 && hdr != 0 && hdr != 0xffffffff)
     347           0 :                 return (0);
     348             : 
     349           0 :         sc->eep_size = 512;
     350           0 :         sc->eep_base = sc->eep_size - 1;
     351           0 :         error = ops->read_rom_data(sc, sc->eep_base, &hdr, sizeof(hdr));
     352           0 :         if (error == 0 && hdr != 0 && hdr != 0xffffffff)
     353           0 :                 return (0);
     354             : 
     355             :         /* Try OTPROM. */
     356           0 :         ops->read_rom_data = ar9003_read_otp_data;
     357             : 
     358           0 :         sc->eep_size = 1024;
     359           0 :         sc->eep_base = sc->eep_size - 1;
     360           0 :         error = ops->read_rom_data(sc, sc->eep_base, &hdr, sizeof(hdr));
     361           0 :         if (error == 0 && hdr != 0 && hdr != 0xffffffff)
     362           0 :                 return (0);
     363             : 
     364           0 :         sc->eep_size = 512;
     365           0 :         sc->eep_base = sc->eep_size - 1;
     366           0 :         error = ops->read_rom_data(sc, sc->eep_base, &hdr, sizeof(hdr));
     367           0 :         if (error == 0 && hdr != 0 && hdr != 0xffffffff)
     368           0 :                 return (0);
     369             : 
     370           0 :         return (EIO);   /* Not found. */
     371           0 : }
     372             : 
     373             : int
     374           0 : ar9003_restore_rom_block(struct athn_softc *sc, uint8_t alg, uint8_t ref,
     375             :     const uint8_t *buf, int len)
     376             : {
     377             :         const uint8_t *def, *ptr, *end;
     378           0 :         uint8_t *eep = sc->eep;
     379             :         int off, clen;
     380             : 
     381           0 :         if (alg == AR_EEP_COMPRESS_BLOCK) {
     382             :                 /* Block contains chunks that shadow ROM template. */
     383           0 :                 def = sc->ops.get_rom_template(sc, ref);
     384           0 :                 if (def == NULL) {
     385             :                         DPRINTF(("unknown template image %d\n", ref));
     386           0 :                         return (EINVAL);
     387             :                 }
     388             :                 /* Start with template. */
     389           0 :                 memcpy(eep, def, sc->eep_size);
     390             :                 /* Shadow template with chunks. */
     391             :                 off = 0;        /* Offset in ROM image. */
     392             :                 ptr = buf;      /* Offset in block. */
     393           0 :                 end = buf + len;
     394             :                 /* Process chunks. */
     395           0 :                 while (ptr + 2 <= end) {
     396           0 :                         off += *ptr++;  /* Gap with previous chunk. */
     397           0 :                         clen = *ptr++;  /* Chunk length. */
     398             :                         /* Make sure block is large enough. */
     399           0 :                         if (ptr + clen > end)
     400           0 :                                 return (EINVAL);
     401             :                         /* Make sure chunk fits in ROM image. */
     402           0 :                         if (off + clen > sc->eep_size)
     403           0 :                                 return (EINVAL);
     404             :                         /* Restore chunk. */
     405             :                         DPRINTFN(2, ("ROM chunk @%d/%d\n", off, clen));
     406           0 :                         memcpy(&eep[off], ptr, clen);
     407             :                         ptr += clen;
     408             :                         off += clen;
     409             :                 }
     410           0 :         } else if (alg == AR_EEP_COMPRESS_NONE) {
     411             :                 /* Block contains full ROM image. */
     412           0 :                 if (len != sc->eep_size) {
     413             :                         DPRINTF(("block length mismatch %d\n", len));
     414           0 :                         return (EINVAL);
     415             :                 }
     416           0 :                 memcpy(eep, buf, len);
     417           0 :         }
     418           0 :         return (0);
     419           0 : }
     420             : 
     421             : int
     422           0 : ar9003_read_rom(struct athn_softc *sc)
     423             : {
     424           0 :         struct athn_ops *ops = &sc->ops;
     425             :         uint8_t *buf, *ptr, alg, ref;
     426           0 :         uint16_t sum, rsum;
     427           0 :         uint32_t hdr;
     428             :         int error, addr, len, i, j;
     429             : 
     430             :         /* Allocate space to store ROM in host memory. */
     431           0 :         sc->eep = malloc(sc->eep_size, M_DEVBUF, M_NOWAIT);
     432           0 :         if (sc->eep == NULL)
     433           0 :                 return (ENOMEM);
     434             : 
     435             :         /* Allocate temporary buffer to store ROM blocks. */
     436           0 :         buf = malloc(2048, M_DEVBUF, M_NOWAIT);
     437           0 :         if (buf == NULL)
     438           0 :                 return (ENOMEM);
     439             : 
     440             :         /* Restore vendor-specified ROM blocks. */
     441           0 :         addr = sc->eep_base;
     442           0 :         for (i = 0; i < 100; i++) {
     443             :                 /* Read block header. */
     444           0 :                 error = ops->read_rom_data(sc, addr, &hdr, sizeof(hdr));
     445           0 :                 if (error != 0)
     446             :                         break;
     447           0 :                 if (hdr == 0 || hdr == 0xffffffff)
     448             :                         break;
     449           0 :                 addr -= sizeof(hdr);
     450             : 
     451             :                 /* Extract bits from header. */
     452             :                 ptr = (uint8_t *)&hdr;
     453           0 :                 alg = (ptr[0] & 0xe0) >> 5;
     454           0 :                 ref = (ptr[1] & 0x80) >> 2 | (ptr[0] & 0x1f);
     455           0 :                 len = (ptr[1] & 0x7f) << 4 | (ptr[2] & 0xf0) >> 4;
     456             :                 DPRINTFN(2, ("ROM block %d: alg=%d ref=%d len=%d\n",
     457             :                     i, alg, ref, len));
     458             : 
     459             :                 /* Read block data (len <= 0x7ff). */
     460           0 :                 error = ops->read_rom_data(sc, addr, buf, len);
     461           0 :                 if (error != 0)
     462             :                         break;
     463           0 :                 addr -= len;
     464             : 
     465             :                 /* Read block checksum. */
     466           0 :                 error = ops->read_rom_data(sc, addr, &sum, sizeof(sum));
     467           0 :                 if (error != 0)
     468             :                         break;
     469           0 :                 addr -= sizeof(sum);
     470             : 
     471             :                 /* Compute block checksum. */
     472             :                 rsum = 0;
     473           0 :                 for (j = 0; j < len; j++)
     474           0 :                         rsum += buf[j];
     475             :                 /* Compare to that in ROM. */
     476           0 :                 if (letoh16(sum) != rsum) {
     477             :                         DPRINTF(("bad block checksum 0x%x/0x%x\n",
     478             :                             letoh16(sum), rsum));
     479             :                         continue;       /* Skip bad block. */
     480             :                 }
     481             :                 /* Checksum is correct, restore block. */
     482           0 :                 ar9003_restore_rom_block(sc, alg, ref, buf, len);
     483           0 :         }
     484             : #if BYTE_ORDER == BIG_ENDIAN
     485             :         /* NB: ROM is always little endian. */
     486             :         if (error == 0)
     487             :                 ops->swap_rom(sc);
     488             : #endif
     489           0 :         free(buf, M_DEVBUF, 0);
     490           0 :         return (error);
     491           0 : }
     492             : 
     493             : /*
     494             :  * Access to General Purpose Input/Output ports.
     495             :  */
     496             : int
     497           0 : ar9003_gpio_read(struct athn_softc *sc, int pin)
     498             : {
     499           0 :         KASSERT(pin < sc->ngpiopins);
     500           0 :         return (((AR_READ(sc, AR_GPIO_IN) & AR9300_GPIO_IN_VAL) &
     501           0 :             (1 << pin)) != 0);
     502             : }
     503             : 
     504             : void
     505           0 : ar9003_gpio_write(struct athn_softc *sc, int pin, int set)
     506             : {
     507             :         uint32_t reg;
     508             : 
     509           0 :         KASSERT(pin < sc->ngpiopins);
     510           0 :         reg = AR_READ(sc, AR_GPIO_IN_OUT);
     511           0 :         if (set)
     512           0 :                 reg |= 1 << pin;
     513             :         else
     514           0 :                 reg &= ~(1 << pin);
     515           0 :         AR_WRITE(sc, AR_GPIO_IN_OUT, reg);
     516           0 :         AR_WRITE_BARRIER(sc);
     517           0 : }
     518             : 
     519             : void
     520           0 : ar9003_gpio_config_input(struct athn_softc *sc, int pin)
     521             : {
     522             :         uint32_t reg;
     523             : 
     524           0 :         reg = AR_READ(sc, AR_GPIO_OE_OUT);
     525           0 :         reg &= ~(AR_GPIO_OE_OUT_DRV_M << (pin * 2));
     526             :         reg |= AR_GPIO_OE_OUT_DRV_NO << (pin * 2);
     527           0 :         AR_WRITE(sc, AR_GPIO_OE_OUT, reg);
     528           0 :         AR_WRITE_BARRIER(sc);
     529           0 : }
     530             : 
     531             : void
     532           0 : ar9003_gpio_config_output(struct athn_softc *sc, int pin, int type)
     533             : {
     534             :         uint32_t reg;
     535             :         int mux, off;
     536             : 
     537           0 :         mux = pin / 6;
     538           0 :         off = pin % 6;
     539             : 
     540           0 :         reg = AR_READ(sc, AR_GPIO_OUTPUT_MUX(mux));
     541           0 :         reg &= ~(0x1f << (off * 5));
     542           0 :         reg |= (type & 0x1f) << (off * 5);
     543           0 :         AR_WRITE(sc, AR_GPIO_OUTPUT_MUX(mux), reg);
     544             : 
     545           0 :         reg = AR_READ(sc, AR_GPIO_OE_OUT);
     546           0 :         reg &= ~(AR_GPIO_OE_OUT_DRV_M << (pin * 2));
     547           0 :         reg |= AR_GPIO_OE_OUT_DRV_ALL << (pin * 2);
     548           0 :         AR_WRITE(sc, AR_GPIO_OE_OUT, reg);
     549           0 :         AR_WRITE_BARRIER(sc);
     550           0 : }
     551             : 
     552             : void
     553           0 : ar9003_rfsilent_init(struct athn_softc *sc)
     554             : {
     555             :         uint32_t reg;
     556             : 
     557             :         /* Configure hardware radio switch. */
     558           0 :         AR_SETBITS(sc, AR_GPIO_INPUT_EN_VAL, AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
     559           0 :         reg = AR_READ(sc, AR_GPIO_INPUT_MUX2);
     560           0 :         reg = RW(reg, AR_GPIO_INPUT_MUX2_RFSILENT, 0);
     561           0 :         AR_WRITE(sc, AR_GPIO_INPUT_MUX2, reg);
     562           0 :         ar9003_gpio_config_input(sc, sc->rfsilent_pin);
     563           0 :         AR_SETBITS(sc, AR_PHY_TEST, AR_PHY_TEST_RFSILENT_BB);
     564           0 :         if (!(sc->flags & ATHN_FLAG_RFSILENT_REVERSED)) {
     565           0 :                 AR_SETBITS(sc, AR_GPIO_INTR_POL,
     566             :                     AR_GPIO_INTR_POL_PIN(sc->rfsilent_pin));
     567           0 :         }
     568           0 :         AR_WRITE_BARRIER(sc);
     569           0 : }
     570             : 
     571             : int
     572           0 : ar9003_dma_alloc(struct athn_softc *sc)
     573             : {
     574             :         int error;
     575             : 
     576           0 :         error = ar9003_tx_alloc(sc);
     577           0 :         if (error != 0)
     578           0 :                 return (error);
     579             : 
     580           0 :         error = ar9003_rx_alloc(sc, ATHN_QID_LP, AR9003_RX_LP_QDEPTH);
     581           0 :         if (error != 0)
     582           0 :                 return (error);
     583             : 
     584           0 :         error = ar9003_rx_alloc(sc, ATHN_QID_HP, AR9003_RX_HP_QDEPTH);
     585           0 :         if (error != 0)
     586           0 :                 return (error);
     587             : 
     588           0 :         return (0);
     589           0 : }
     590             : 
     591             : void
     592           0 : ar9003_dma_free(struct athn_softc *sc)
     593             : {
     594           0 :         ar9003_tx_free(sc);
     595           0 :         ar9003_rx_free(sc, ATHN_QID_LP);
     596           0 :         ar9003_rx_free(sc, ATHN_QID_HP);
     597           0 : }
     598             : 
     599             : int
     600           0 : ar9003_tx_alloc(struct athn_softc *sc)
     601             : {
     602             :         struct athn_tx_buf *bf;
     603             :         bus_size_t size;
     604           0 :         int error, nsegs, i;
     605             : 
     606             :         /*
     607             :          * Allocate Tx status ring.
     608             :          */
     609             :         size = AR9003_NTXSTATUS * sizeof(struct ar_tx_status);
     610             : 
     611           0 :         error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
     612             :             BUS_DMA_NOWAIT, &sc->txsmap);
     613           0 :         if (error != 0)
     614             :                 goto fail;
     615             : 
     616           0 :         error = bus_dmamem_alloc(sc->sc_dmat, size, 4, 0, &sc->txsseg, 1,
     617             :             &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO);
     618           0 :         if (error != 0)
     619             :                 goto fail;
     620             : 
     621           0 :         error = bus_dmamem_map(sc->sc_dmat, &sc->txsseg, 1, size,
     622             :             (caddr_t *)&sc->txsring, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
     623           0 :         if (error != 0)
     624             :                 goto fail;
     625             : 
     626           0 :         error = bus_dmamap_load_raw(sc->sc_dmat, sc->txsmap, &sc->txsseg,
     627             :             1, size, BUS_DMA_NOWAIT | BUS_DMA_READ);
     628           0 :         if (error != 0)
     629             :                 goto fail;
     630             : 
     631             :         /*
     632             :          * Allocate a pool of Tx descriptors shared between all Tx queues.
     633             :          */
     634             :         size = ATHN_NTXBUFS * sizeof(struct ar_tx_desc);
     635             : 
     636           0 :         error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
     637             :             BUS_DMA_NOWAIT, &sc->map);
     638           0 :         if (error != 0)
     639             :                 goto fail;
     640             : 
     641           0 :         error = bus_dmamem_alloc(sc->sc_dmat, size, 4, 0, &sc->seg, 1,
     642             :             &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO);
     643           0 :         if (error != 0)
     644             :                 goto fail;
     645             : 
     646           0 :         error = bus_dmamem_map(sc->sc_dmat, &sc->seg, 1, size,
     647             :             (caddr_t *)&sc->descs, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
     648           0 :         if (error != 0)
     649             :                 goto fail;
     650             : 
     651           0 :         error = bus_dmamap_load_raw(sc->sc_dmat, sc->map, &sc->seg, 1, size,
     652             :             BUS_DMA_NOWAIT | BUS_DMA_WRITE);
     653           0 :         if (error != 0)
     654             :                 goto fail;
     655             : 
     656           0 :         SIMPLEQ_INIT(&sc->txbufs);
     657           0 :         for (i = 0; i < ATHN_NTXBUFS; i++) {
     658           0 :                 bf = &sc->txpool[i];
     659             : 
     660           0 :                 error = bus_dmamap_create(sc->sc_dmat, ATHN_TXBUFSZ,
     661             :                     AR9003_MAX_SCATTER, ATHN_TXBUFSZ, 0, BUS_DMA_NOWAIT,
     662             :                     &bf->bf_map);
     663           0 :                 if (error != 0) {
     664           0 :                         printf("%s: could not create Tx buf DMA map\n",
     665           0 :                             sc->sc_dev.dv_xname);
     666           0 :                         goto fail;
     667             :                 }
     668             : 
     669           0 :                 bf->bf_descs = &((struct ar_tx_desc *)sc->descs)[i];
     670           0 :                 bf->bf_daddr = sc->map->dm_segs[0].ds_addr +
     671           0 :                     i * sizeof(struct ar_tx_desc);
     672             : 
     673           0 :                 SIMPLEQ_INSERT_TAIL(&sc->txbufs, bf, bf_list);
     674             :         }
     675           0 :         return (0);
     676             :  fail:
     677           0 :         ar9003_tx_free(sc);
     678           0 :         return (error);
     679           0 : }
     680             : 
     681             : void
     682           0 : ar9003_tx_free(struct athn_softc *sc)
     683             : {
     684             :         struct athn_tx_buf *bf;
     685             :         int i;
     686             : 
     687           0 :         for (i = 0; i < ATHN_NTXBUFS; i++) {
     688           0 :                 bf = &sc->txpool[i];
     689             : 
     690           0 :                 if (bf->bf_map != NULL)
     691           0 :                         bus_dmamap_destroy(sc->sc_dmat, bf->bf_map);
     692             :         }
     693             :         /* Free Tx descriptors. */
     694           0 :         if (sc->map != NULL) {
     695           0 :                 if (sc->descs != NULL) {
     696           0 :                         bus_dmamap_unload(sc->sc_dmat, sc->map);
     697           0 :                         bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->descs,
     698             :                             ATHN_NTXBUFS * sizeof(struct ar_tx_desc));
     699           0 :                         bus_dmamem_free(sc->sc_dmat, &sc->seg, 1);
     700           0 :                 }
     701           0 :                 bus_dmamap_destroy(sc->sc_dmat, sc->map);
     702           0 :         }
     703             :         /* Free Tx status ring. */
     704           0 :         if (sc->txsmap != NULL) {
     705           0 :                 if (sc->txsring != NULL) {
     706           0 :                         bus_dmamap_unload(sc->sc_dmat, sc->txsmap);
     707           0 :                         bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->txsring,
     708             :                              AR9003_NTXSTATUS * sizeof(struct ar_tx_status));
     709           0 :                         bus_dmamem_free(sc->sc_dmat, &sc->txsseg, 1);
     710           0 :                 }
     711           0 :                 bus_dmamap_destroy(sc->sc_dmat, sc->txsmap);
     712           0 :         }
     713           0 : }
     714             : 
     715             : int
     716           0 : ar9003_rx_alloc(struct athn_softc *sc, int qid, int count)
     717             : {
     718           0 :         struct athn_rxq *rxq = &sc->rxq[qid];
     719             :         struct athn_rx_buf *bf;
     720             :         struct ar_rx_status *ds;
     721             :         int error, i;
     722             : 
     723           0 :         rxq->bf = mallocarray(count, sizeof(*bf), M_DEVBUF,
     724             :             M_NOWAIT | M_ZERO);
     725           0 :         if (rxq->bf == NULL)
     726           0 :                 return (ENOMEM);
     727             : 
     728           0 :         rxq->count = count;
     729             : 
     730           0 :         for (i = 0; i < rxq->count; i++) {
     731           0 :                 bf = &rxq->bf[i];
     732             : 
     733           0 :                 error = bus_dmamap_create(sc->sc_dmat, ATHN_RXBUFSZ, 1,
     734             :                     ATHN_RXBUFSZ, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
     735             :                     &bf->bf_map);
     736           0 :                 if (error != 0) {
     737           0 :                         printf("%s: could not create Rx buf DMA map\n",
     738           0 :                             sc->sc_dev.dv_xname);
     739           0 :                         goto fail;
     740             :                 }
     741             :                 /*
     742             :                  * Assumes MCLGETI returns cache-line-size aligned buffers.
     743             :                  */
     744           0 :                 bf->bf_m = MCLGETI(NULL, M_DONTWAIT, NULL, ATHN_RXBUFSZ);
     745           0 :                 if (bf->bf_m == NULL) {
     746           0 :                         printf("%s: could not allocate Rx mbuf\n",
     747           0 :                             sc->sc_dev.dv_xname);
     748             :                         error = ENOBUFS;
     749           0 :                         goto fail;
     750             :                 }
     751             : 
     752           0 :                 error = bus_dmamap_load(sc->sc_dmat, bf->bf_map,
     753             :                     mtod(bf->bf_m, void *), ATHN_RXBUFSZ, NULL,
     754             :                     BUS_DMA_NOWAIT);
     755           0 :                 if (error != 0) {
     756           0 :                         printf("%s: could not DMA map Rx buffer\n",
     757           0 :                             sc->sc_dev.dv_xname);
     758           0 :                         goto fail;
     759             :                 }
     760             : 
     761           0 :                 ds = mtod(bf->bf_m, struct ar_rx_status *);
     762           0 :                 memset(ds, 0, sizeof(*ds));
     763           0 :                 bf->bf_desc = ds;
     764           0 :                 bf->bf_daddr = bf->bf_map->dm_segs[0].ds_addr;
     765             : 
     766           0 :                 bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, ATHN_RXBUFSZ,
     767             :                     BUS_DMASYNC_PREREAD);
     768             :         }
     769           0 :         return (0);
     770             :  fail:
     771           0 :         ar9003_rx_free(sc, qid);
     772           0 :         return (error);
     773           0 : }
     774             : 
     775             : void
     776           0 : ar9003_rx_free(struct athn_softc *sc, int qid)
     777             : {
     778           0 :         struct athn_rxq *rxq = &sc->rxq[qid];
     779             :         struct athn_rx_buf *bf;
     780             :         int i;
     781             : 
     782           0 :         if (rxq->bf == NULL)
     783           0 :                 return;
     784           0 :         for (i = 0; i < rxq->count; i++) {
     785           0 :                 bf = &rxq->bf[i];
     786             : 
     787           0 :                 if (bf->bf_map != NULL)
     788           0 :                         bus_dmamap_destroy(sc->sc_dmat, bf->bf_map);
     789           0 :                 m_freem(bf->bf_m);
     790             :         }
     791           0 :         free(rxq->bf, M_DEVBUF, 0);
     792           0 : }
     793             : 
     794             : void
     795           0 : ar9003_reset_txsring(struct athn_softc *sc)
     796             : {
     797           0 :         sc->txscur = 0;
     798           0 :         memset(sc->txsring, 0, AR9003_NTXSTATUS * sizeof(struct ar_tx_status));
     799           0 :         AR_WRITE(sc, AR_Q_STATUS_RING_START,
     800             :             sc->txsmap->dm_segs[0].ds_addr);
     801           0 :         AR_WRITE(sc, AR_Q_STATUS_RING_END,
     802             :             sc->txsmap->dm_segs[0].ds_addr + sc->txsmap->dm_segs[0].ds_len);
     803           0 :         AR_WRITE_BARRIER(sc);
     804           0 : }
     805             : 
     806             : void
     807           0 : ar9003_rx_enable(struct athn_softc *sc)
     808             : {
     809             :         struct athn_rxq *rxq;
     810             :         struct athn_rx_buf *bf;
     811             :         struct ar_rx_status *ds;
     812             :         uint32_t reg;
     813             :         int qid, i;
     814             : 
     815           0 :         reg = AR_READ(sc, AR_RXBP_THRESH);
     816           0 :         reg = RW(reg, AR_RXBP_THRESH_HP, 1);
     817           0 :         reg = RW(reg, AR_RXBP_THRESH_LP, 1);
     818           0 :         AR_WRITE(sc, AR_RXBP_THRESH, reg);
     819             : 
     820             :         /* Set Rx buffer size. */
     821           0 :         AR_WRITE(sc, AR_DATABUF_SIZE, ATHN_RXBUFSZ - sizeof(*ds));
     822             : 
     823           0 :         for (qid = 0; qid < 2; qid++) {
     824           0 :                 rxq = &sc->rxq[qid];
     825             : 
     826             :                 /* Setup Rx status descriptors. */
     827           0 :                 SIMPLEQ_INIT(&rxq->head);
     828           0 :                 for (i = 0; i < rxq->count; i++) {
     829           0 :                         bf = &rxq->bf[i];
     830           0 :                         ds = bf->bf_desc;
     831             : 
     832           0 :                         memset(ds, 0, sizeof(*ds));
     833           0 :                         if (qid == ATHN_QID_LP)
     834           0 :                                 AR_WRITE(sc, AR_LP_RXDP, bf->bf_daddr);
     835             :                         else
     836           0 :                                 AR_WRITE(sc, AR_HP_RXDP, bf->bf_daddr);
     837           0 :                         AR_WRITE_BARRIER(sc);
     838           0 :                         SIMPLEQ_INSERT_TAIL(&rxq->head, bf, bf_list);
     839             :                 }
     840             :         }
     841             :         /* Enable Rx. */
     842           0 :         AR_WRITE(sc, AR_CR, 0);
     843           0 :         AR_WRITE_BARRIER(sc);
     844           0 : }
     845             : 
     846             : #if NBPFILTER > 0
     847             : void
     848           0 : ar9003_rx_radiotap(struct athn_softc *sc, struct mbuf *m,
     849             :     struct ar_rx_status *ds)
     850             : {
     851             : #define IEEE80211_RADIOTAP_F_SHORTGI    0x80    /* XXX from FBSD */
     852             : 
     853           0 :         struct athn_rx_radiotap_header *tap = &sc->sc_rxtap;
     854           0 :         struct ieee80211com *ic = &sc->sc_ic;
     855           0 :         struct mbuf mb;
     856             :         uint64_t tsf;
     857             :         uint32_t tstamp;
     858             :         uint8_t rate;
     859             : 
     860             :         /* Extend the 15-bit timestamp from Rx status to 64-bit TSF. */
     861           0 :         tstamp = ds->ds_status3;
     862           0 :         tsf = AR_READ(sc, AR_TSF_U32);
     863           0 :         tsf = tsf << 32 | AR_READ(sc, AR_TSF_L32);
     864           0 :         if ((tsf & 0x7fff) < tstamp)
     865           0 :                 tsf -= 0x8000;
     866           0 :         tsf = (tsf & ~0x7fff) | tstamp;
     867             : 
     868           0 :         tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
     869           0 :         tap->wr_tsft = htole64(tsf);
     870           0 :         tap->wr_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
     871           0 :         tap->wr_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
     872           0 :         tap->wr_dbm_antsignal = MS(ds->ds_status5, AR_RXS5_RSSI_COMBINED);
     873             :         /* XXX noise. */
     874           0 :         tap->wr_antenna = MS(ds->ds_status4, AR_RXS4_ANTENNA);
     875           0 :         tap->wr_rate = 0;    /* In case it can't be found below. */
     876           0 :         rate = MS(ds->ds_status1, AR_RXS1_RATE);
     877           0 :         if (rate & 0x80) {          /* HT. */
     878             :                 /* Bit 7 set means HT MCS instead of rate. */
     879           0 :                 tap->wr_rate = rate;
     880           0 :                 if (!(ds->ds_status4 & AR_RXS4_GI))
     881           0 :                         tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTGI;
     882             : 
     883           0 :         } else if (rate & 0x10) {   /* CCK. */
     884           0 :                 if (rate & 0x04)
     885           0 :                         tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
     886           0 :                 switch (rate & ~0x14) {
     887           0 :                 case 0xb: tap->wr_rate =   2; break;
     888           0 :                 case 0xa: tap->wr_rate =   4; break;
     889           0 :                 case 0x9: tap->wr_rate =  11; break;
     890           0 :                 case 0x8: tap->wr_rate =  22; break;
     891             :                 }
     892             :         } else {                        /* OFDM. */
     893           0 :                 switch (rate) {
     894           0 :                 case 0xb: tap->wr_rate =  12; break;
     895           0 :                 case 0xf: tap->wr_rate =  18; break;
     896           0 :                 case 0xa: tap->wr_rate =  24; break;
     897           0 :                 case 0xe: tap->wr_rate =  36; break;
     898           0 :                 case 0x9: tap->wr_rate =  48; break;
     899           0 :                 case 0xd: tap->wr_rate =  72; break;
     900           0 :                 case 0x8: tap->wr_rate =  96; break;
     901           0 :                 case 0xc: tap->wr_rate = 108; break;
     902             :                 }
     903             :         }
     904           0 :         mb.m_data = (caddr_t)tap;
     905           0 :         mb.m_len = sc->sc_rxtap_len;
     906           0 :         mb.m_next = m;
     907           0 :         mb.m_nextpkt = NULL;
     908           0 :         mb.m_type = 0;
     909           0 :         mb.m_flags = 0;
     910           0 :         bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
     911           0 : }
     912             : #endif
     913             : 
     914             : int
     915           0 : ar9003_rx_process(struct athn_softc *sc, int qid)
     916             : {
     917           0 :         struct ieee80211com *ic = &sc->sc_ic;
     918           0 :         struct ifnet *ifp = &ic->ic_if;
     919           0 :         struct athn_rxq *rxq = &sc->rxq[qid];
     920             :         struct athn_rx_buf *bf;
     921             :         struct ar_rx_status *ds;
     922             :         struct ieee80211_frame *wh;
     923           0 :         struct ieee80211_rxinfo rxi;
     924             :         struct ieee80211_node *ni;
     925             :         struct mbuf *m, *m1;
     926             :         int error, len;
     927             : 
     928           0 :         bf = SIMPLEQ_FIRST(&rxq->head);
     929           0 :         if (__predict_false(bf == NULL)) {      /* Should not happen. */
     930           0 :                 printf("%s: Rx queue is empty!\n", sc->sc_dev.dv_xname);
     931           0 :                 return (ENOENT);
     932             :         }
     933           0 :         bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, ATHN_RXBUFSZ,
     934             :             BUS_DMASYNC_POSTREAD);
     935             : 
     936           0 :         ds = mtod(bf->bf_m, struct ar_rx_status *);
     937           0 :         if (!(ds->ds_status11 & AR_RXS11_DONE))
     938           0 :                 return (EBUSY);
     939             : 
     940             :         /* Check that it is a valid Rx status descriptor. */
     941           0 :         if ((ds->ds_info & (AR_RXI_DESC_ID_M | AR_RXI_DESC_TX |
     942           0 :             AR_RXI_CTRL_STAT)) != SM(AR_RXI_DESC_ID, AR_VENDOR_ATHEROS))
     943             :                 goto skip;
     944             : 
     945           0 :         if (!(ds->ds_status11 & AR_RXS11_FRAME_OK)) {
     946           0 :                 if (ds->ds_status11 & AR_RXS11_CRC_ERR)
     947             :                         DPRINTFN(6, ("CRC error\n"));
     948           0 :                 else if (ds->ds_status11 & AR_RXS11_PHY_ERR)
     949             :                         DPRINTFN(6, ("PHY error=0x%x\n",
     950             :                             MS(ds->ds_status11, AR_RXS11_PHY_ERR_CODE)));
     951           0 :                 else if (ds->ds_status11 & AR_RXS11_DECRYPT_CRC_ERR)
     952             :                         DPRINTFN(6, ("Decryption CRC error\n"));
     953           0 :                 else if (ds->ds_status11 & AR_RXS11_MICHAEL_ERR) {
     954             :                         DPRINTFN(2, ("Michael MIC failure\n"));
     955             :                         /* Report Michael MIC failures to net80211. */
     956           0 :                         ic->ic_stats.is_rx_locmicfail++;
     957           0 :                         ieee80211_michael_mic_failure(ic, 0);
     958             :                         /*
     959             :                          * XXX Check that it is not a control frame
     960             :                          * (invalid MIC failures on valid ctl frames).
     961             :                          */
     962           0 :                 }
     963           0 :                 ifp->if_ierrors++;
     964           0 :                 goto skip;
     965             :         }
     966             : 
     967           0 :         len = MS(ds->ds_status2, AR_RXS2_DATA_LEN);
     968           0 :         if (__predict_false(len < IEEE80211_MIN_LEN ||
     969             :             len > ATHN_RXBUFSZ - sizeof(*ds))) {
     970             :                 DPRINTF(("corrupted descriptor length=%d\n", len));
     971           0 :                 ifp->if_ierrors++;
     972           0 :                 goto skip;
     973             :         }
     974             : 
     975             :         /* Allocate a new Rx buffer. */
     976           0 :         m1 = MCLGETI(NULL, M_DONTWAIT, NULL, ATHN_RXBUFSZ);
     977           0 :         if (__predict_false(m1 == NULL)) {
     978           0 :                 ic->ic_stats.is_rx_nombuf++;
     979           0 :                 ifp->if_ierrors++;
     980           0 :                 goto skip;
     981             :         }
     982             : 
     983             :         /* Unmap the old Rx buffer. */
     984           0 :         bus_dmamap_unload(sc->sc_dmat, bf->bf_map);
     985             : 
     986             :         /* Map the new Rx buffer. */
     987           0 :         error = bus_dmamap_load(sc->sc_dmat, bf->bf_map, mtod(m1, void *),
     988             :             ATHN_RXBUFSZ, NULL, BUS_DMA_NOWAIT | BUS_DMA_READ);
     989           0 :         if (__predict_false(error != 0)) {
     990           0 :                 m_freem(m1);
     991             : 
     992             :                 /* Remap the old Rx buffer or panic. */
     993           0 :                 error = bus_dmamap_load(sc->sc_dmat, bf->bf_map,
     994             :                     mtod(bf->bf_m, void *), ATHN_RXBUFSZ, NULL,
     995             :                     BUS_DMA_NOWAIT | BUS_DMA_READ);
     996           0 :                 KASSERT(error != 0);
     997           0 :                 bf->bf_daddr = bf->bf_map->dm_segs[0].ds_addr;
     998           0 :                 ifp->if_ierrors++;
     999           0 :                 goto skip;
    1000             :         }
    1001           0 :         bf->bf_desc = mtod(m1, struct ar_rx_status *);
    1002           0 :         bf->bf_daddr = bf->bf_map->dm_segs[0].ds_addr;
    1003             : 
    1004           0 :         m = bf->bf_m;
    1005           0 :         bf->bf_m = m1;
    1006             : 
    1007             :         /* Finalize mbuf. */
    1008             :         /* Strip Rx status descriptor from head. */
    1009           0 :         m->m_data = (caddr_t)&ds[1];
    1010           0 :         m->m_pkthdr.len = m->m_len = len;
    1011             : 
    1012             :         /* Grab a reference to the source node. */
    1013           0 :         wh = mtod(m, struct ieee80211_frame *);
    1014           0 :         ni = ieee80211_find_rxnode(ic, wh);
    1015             : 
    1016             :         /* Remove any HW padding after the 802.11 header. */
    1017           0 :         if (!(wh->i_fc[0] & IEEE80211_FC0_TYPE_CTL)) {
    1018           0 :                 u_int hdrlen = ieee80211_get_hdrlen(wh);
    1019           0 :                 if (hdrlen & 3) {
    1020           0 :                         memmove((caddr_t)wh + 2, wh, hdrlen);
    1021           0 :                         m_adj(m, 2);
    1022           0 :                 }
    1023           0 :         }
    1024             : #if NBPFILTER > 0
    1025           0 :         if (__predict_false(sc->sc_drvbpf != NULL))
    1026           0 :                 ar9003_rx_radiotap(sc, m, ds);
    1027             : #endif
    1028             :         /* Trim 802.11 FCS after radiotap. */
    1029           0 :         m_adj(m, -IEEE80211_CRC_LEN);
    1030             : 
    1031             :         /* Send the frame to the 802.11 layer. */
    1032           0 :         rxi.rxi_flags = 0;      /* XXX */
    1033           0 :         rxi.rxi_rssi = MS(ds->ds_status5, AR_RXS5_RSSI_COMBINED);
    1034           0 :         rxi.rxi_tstamp = ds->ds_status3;
    1035           0 :         ieee80211_input(ifp, m, ni, &rxi);
    1036             : 
    1037             :         /* Node is no longer needed. */
    1038           0 :         ieee80211_release_node(ic, ni);
    1039             : 
    1040             :  skip:
    1041             :         /* Unlink this descriptor from head. */
    1042           0 :         SIMPLEQ_REMOVE_HEAD(&rxq->head, bf_list);
    1043           0 :         memset(bf->bf_desc, 0, sizeof(*ds));
    1044             : 
    1045             :         /* Re-use this descriptor and link it to tail. */
    1046           0 :         bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, ATHN_RXBUFSZ,
    1047             :             BUS_DMASYNC_PREREAD);
    1048             : 
    1049           0 :         if (qid == ATHN_QID_LP)
    1050           0 :                 AR_WRITE(sc, AR_LP_RXDP, bf->bf_daddr);
    1051             :         else
    1052           0 :                 AR_WRITE(sc, AR_HP_RXDP, bf->bf_daddr);
    1053           0 :         AR_WRITE_BARRIER(sc);
    1054           0 :         SIMPLEQ_INSERT_TAIL(&rxq->head, bf, bf_list);
    1055             : 
    1056             :         /* Re-enable Rx. */
    1057           0 :         AR_WRITE(sc, AR_CR, 0);
    1058           0 :         AR_WRITE_BARRIER(sc);
    1059           0 :         return (0);
    1060           0 : }
    1061             : 
    1062             : void
    1063           0 : ar9003_rx_intr(struct athn_softc *sc, int qid)
    1064             : {
    1065           0 :         while (ar9003_rx_process(sc, qid) == 0);
    1066           0 : }
    1067             : 
    1068             : int
    1069           0 : ar9003_tx_process(struct athn_softc *sc)
    1070             : {
    1071           0 :         struct ieee80211com *ic = &sc->sc_ic;
    1072           0 :         struct ifnet *ifp = &ic->ic_if;
    1073             :         struct athn_txq *txq;
    1074             :         struct athn_node *an;
    1075             :         struct athn_tx_buf *bf;
    1076             :         struct ar_tx_status *ds;
    1077             :         uint8_t qid, failcnt;
    1078             : 
    1079           0 :         ds = &((struct ar_tx_status *)sc->txsring)[sc->txscur];
    1080           0 :         if (!(ds->ds_status8 & AR_TXS8_DONE))
    1081           0 :                 return (EBUSY);
    1082             : 
    1083           0 :         sc->txscur = (sc->txscur + 1) % AR9003_NTXSTATUS;
    1084             : 
    1085             :         /* Check that it is a valid Tx status descriptor. */
    1086           0 :         if ((ds->ds_info & (AR_TXI_DESC_ID_M | AR_TXI_DESC_TX)) !=
    1087             :             (SM(AR_TXI_DESC_ID, AR_VENDOR_ATHEROS) | AR_TXI_DESC_TX)) {
    1088           0 :                 memset(ds, 0, sizeof(*ds));
    1089           0 :                 return (0);
    1090             :         }
    1091             :         /* Retrieve the queue that was used to send this PDU. */
    1092           0 :         qid = MS(ds->ds_info, AR_TXI_QCU_NUM);
    1093           0 :         txq = &sc->txq[qid];
    1094             : 
    1095           0 :         bf = SIMPLEQ_FIRST(&txq->head);
    1096           0 :         if (bf == NULL || bf == txq->wait) {
    1097           0 :                 memset(ds, 0, sizeof(*ds));
    1098           0 :                 return (0);
    1099             :         }
    1100           0 :         SIMPLEQ_REMOVE_HEAD(&txq->head, bf_list);
    1101             : 
    1102           0 :         sc->sc_tx_timer = 0;
    1103             : 
    1104           0 :         if (ds->ds_status3 & AR_TXS3_EXCESSIVE_RETRIES)
    1105           0 :                 ifp->if_oerrors++;
    1106             : 
    1107           0 :         if (ds->ds_status3 & AR_TXS3_UNDERRUN)
    1108           0 :                 athn_inc_tx_trigger_level(sc);
    1109             : 
    1110             :         /* Wakeup PA predistortion state machine. */
    1111           0 :         if (bf->bf_txflags & ATHN_TXFLAG_PAPRD)
    1112           0 :                 ar9003_paprd_tx_tone_done(sc);
    1113             : 
    1114           0 :         an = (struct athn_node *)bf->bf_ni;
    1115             :         /*
    1116             :          * NB: the data fail count contains the number of un-acked tries
    1117             :          * for the final series used.  We must add the number of tries for
    1118             :          * each series that was fully processed.
    1119             :          */
    1120           0 :         failcnt  = MS(ds->ds_status3, AR_TXS3_DATA_FAIL_CNT);
    1121             :         /* NB: Assume two tries per series. */
    1122           0 :         failcnt += MS(ds->ds_status8, AR_TXS8_FINAL_IDX) * 2;
    1123             : 
    1124             :         /* Update rate control statistics. */
    1125           0 :         an->amn.amn_txcnt++;
    1126           0 :         if (failcnt > 0)
    1127           0 :                 an->amn.amn_retrycnt++;
    1128             : 
    1129             :         DPRINTFN(5, ("Tx done qid=%d status3=%d fail count=%d\n",
    1130             :             qid, ds->ds_status3, failcnt));
    1131             : 
    1132             :         /* Reset Tx status descriptor. */
    1133           0 :         memset(ds, 0, sizeof(*ds));
    1134             : 
    1135             :         /* Unmap Tx buffer. */
    1136           0 :         bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, bf->bf_map->dm_mapsize,
    1137             :             BUS_DMASYNC_POSTWRITE);
    1138           0 :         bus_dmamap_unload(sc->sc_dmat, bf->bf_map);
    1139             : 
    1140           0 :         m_freem(bf->bf_m);
    1141           0 :         bf->bf_m = NULL;
    1142           0 :         ieee80211_release_node(ic, bf->bf_ni);
    1143           0 :         bf->bf_ni = NULL;
    1144             : 
    1145             :         /* Link Tx buffer back to global free list. */
    1146           0 :         SIMPLEQ_INSERT_TAIL(&sc->txbufs, bf, bf_list);
    1147             : 
    1148             :         /* Queue buffers that are waiting if there is new room. */
    1149           0 :         if (--txq->queued < AR9003_TX_QDEPTH && txq->wait != NULL) {
    1150           0 :                 AR_WRITE(sc, AR_QTXDP(qid), txq->wait->bf_daddr);
    1151           0 :                 AR_WRITE_BARRIER(sc);
    1152           0 :                 txq->wait = SIMPLEQ_NEXT(txq->wait, bf_list);
    1153           0 :         }
    1154           0 :         return (0);
    1155           0 : }
    1156             : 
    1157             : void
    1158           0 : ar9003_tx_intr(struct athn_softc *sc)
    1159             : {
    1160           0 :         struct ieee80211com *ic = &sc->sc_ic;
    1161           0 :         struct ifnet *ifp = &ic->ic_if;
    1162             : 
    1163           0 :         while (ar9003_tx_process(sc) == 0);
    1164             : 
    1165           0 :         if (!SIMPLEQ_EMPTY(&sc->txbufs)) {
    1166           0 :                 ifq_clr_oactive(&ifp->if_snd);
    1167           0 :                 ifp->if_start(ifp);
    1168           0 :         }
    1169           0 : }
    1170             : 
    1171             : #ifndef IEEE80211_STA_ONLY
    1172             : /*
    1173             :  * Process Software Beacon Alert interrupts.
    1174             :  */
    1175             : int
    1176           0 : ar9003_swba_intr(struct athn_softc *sc)
    1177             : {
    1178           0 :         struct ieee80211com *ic = &sc->sc_ic;
    1179           0 :         struct ifnet *ifp = &ic->ic_if;
    1180           0 :         struct ieee80211_node *ni = ic->ic_bss;
    1181           0 :         struct athn_tx_buf *bf = sc->bcnbuf;
    1182             :         struct ieee80211_frame *wh;
    1183             :         struct ar_tx_desc *ds;
    1184             :         struct mbuf *m;
    1185             :         uint32_t sum;
    1186             :         uint8_t ridx, hwrate;
    1187             :         int error, totlen;
    1188             : 
    1189           0 :         if (ic->ic_tim_mcast_pending &&
    1190           0 :             mq_empty(&ni->ni_savedq) &&
    1191           0 :             SIMPLEQ_EMPTY(&sc->txq[ATHN_QID_CAB].head))
    1192           0 :                 ic->ic_tim_mcast_pending = 0;
    1193             : 
    1194           0 :         if (ic->ic_dtim_count == 0)
    1195           0 :                 ic->ic_dtim_count = ic->ic_dtim_period - 1;
    1196             :         else
    1197           0 :                 ic->ic_dtim_count--;
    1198             : 
    1199             :         /* Make sure previous beacon has been sent. */
    1200           0 :         if (athn_tx_pending(sc, ATHN_QID_BEACON)) {
    1201             :                 DPRINTF(("beacon stuck\n"));
    1202           0 :                 return (EBUSY);
    1203             :         }
    1204             :         /* Get new beacon. */
    1205           0 :         m = ieee80211_beacon_alloc(ic, ic->ic_bss);
    1206           0 :         if (__predict_false(m == NULL))
    1207           0 :                 return (ENOBUFS);
    1208             :         /* Assign sequence number. */
    1209           0 :         wh = mtod(m, struct ieee80211_frame *);
    1210           0 :         *(uint16_t *)&wh->i_seq[0] =
    1211           0 :             htole16(ic->ic_bss->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT);
    1212           0 :         ic->ic_bss->ni_txseq++;
    1213             : 
    1214             :         /* Unmap and free old beacon if any. */
    1215           0 :         if (__predict_true(bf->bf_m != NULL)) {
    1216           0 :                 bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0,
    1217             :                     bf->bf_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
    1218           0 :                 bus_dmamap_unload(sc->sc_dmat, bf->bf_map);
    1219           0 :                 m_freem(bf->bf_m);
    1220           0 :                 bf->bf_m = NULL;
    1221           0 :         }
    1222             :         /* DMA map new beacon. */
    1223           0 :         error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_map, m,
    1224             :             BUS_DMA_NOWAIT | BUS_DMA_WRITE);
    1225           0 :         if (__predict_false(error != 0)) {
    1226           0 :                 m_freem(m);
    1227           0 :                 return (error);
    1228             :         }
    1229           0 :         bf->bf_m = m;
    1230             : 
    1231             :         /* Setup Tx descriptor (simplified ar9003_tx()). */
    1232           0 :         ds = bf->bf_descs;
    1233           0 :         memset(ds, 0, sizeof(*ds));
    1234             : 
    1235           0 :         ds->ds_info =
    1236             :             SM(AR_TXI_DESC_ID, AR_VENDOR_ATHEROS) |
    1237             :             SM(AR_TXI_DESC_NDWORDS, 23) |
    1238             :             SM(AR_TXI_QCU_NUM, ATHN_QID_BEACON) |
    1239             :             AR_TXI_DESC_TX | AR_TXI_CTRL_STAT;
    1240             : 
    1241           0 :         totlen = m->m_pkthdr.len + IEEE80211_CRC_LEN;
    1242           0 :         ds->ds_ctl11 = SM(AR_TXC11_FRAME_LEN, totlen);
    1243           0 :         ds->ds_ctl11 |= SM(AR_TXC11_XMIT_POWER, AR_MAX_RATE_POWER);
    1244           0 :         ds->ds_ctl12 = SM(AR_TXC12_FRAME_TYPE, AR_FRAME_TYPE_BEACON);
    1245           0 :         ds->ds_ctl12 |= AR_TXC12_NO_ACK;
    1246           0 :         ds->ds_ctl17 = SM(AR_TXC17_ENCR_TYPE, AR_ENCR_TYPE_CLEAR);
    1247             : 
    1248             :         /* Write number of tries. */
    1249           0 :         ds->ds_ctl13 = SM(AR_TXC13_XMIT_DATA_TRIES0, 1);
    1250             : 
    1251             :         /* Write Tx rate. */
    1252           0 :         ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
    1253             :             ATHN_RIDX_OFDM6 : ATHN_RIDX_CCK1;
    1254           0 :         hwrate = athn_rates[ridx].hwrate;
    1255           0 :         ds->ds_ctl14 = SM(AR_TXC14_XMIT_RATE0, hwrate);
    1256             : 
    1257             :         /* Write Tx chains. */
    1258           0 :         ds->ds_ctl18 = SM(AR_TXC18_CHAIN_SEL0, sc->txchainmask);
    1259             : 
    1260           0 :         ds->ds_segs[0].ds_data = bf->bf_map->dm_segs[0].ds_addr;
    1261             :         /* Segment length must be a multiple of 4. */
    1262           0 :         ds->ds_segs[0].ds_ctl |= SM(AR_TXC_BUF_LEN,
    1263             :             (bf->bf_map->dm_segs[0].ds_len + 3) & ~3);
    1264             :         /* Compute Tx descriptor checksum. */
    1265           0 :         sum = ds->ds_info;
    1266           0 :         sum += ds->ds_segs[0].ds_data;
    1267           0 :         sum += ds->ds_segs[0].ds_ctl;
    1268           0 :         sum = (sum >> 16) + (sum & 0xffff);
    1269           0 :         ds->ds_ctl10 = SM(AR_TXC10_PTR_CHK_SUM, sum);
    1270             : 
    1271           0 :         bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, bf->bf_map->dm_mapsize,
    1272             :             BUS_DMASYNC_PREWRITE);
    1273             : 
    1274             :         /* Stop Tx DMA before putting the new beacon on the queue. */
    1275           0 :         athn_stop_tx_dma(sc, ATHN_QID_BEACON);
    1276             : 
    1277           0 :         AR_WRITE(sc, AR_QTXDP(ATHN_QID_BEACON), bf->bf_daddr);
    1278             : 
    1279           0 :         for(;;) {
    1280           0 :                 if (SIMPLEQ_EMPTY(&sc->txbufs))
    1281             :                         break;
    1282             : 
    1283           0 :                 m = mq_dequeue(&ni->ni_savedq);
    1284           0 :                 if (m == NULL)
    1285             :                         break;
    1286           0 :                 if (!mq_empty(&ni->ni_savedq)) {
    1287             :                         /* more queued frames, set the more data bit */
    1288           0 :                         wh = mtod(m, struct ieee80211_frame *);
    1289           0 :                         wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
    1290           0 :                 }
    1291             :                 
    1292           0 :                 if (sc->ops.tx(sc, m, ni, ATHN_TXFLAG_CAB) != 0) {
    1293           0 :                         ieee80211_release_node(ic, ni);
    1294           0 :                         ifp->if_oerrors++;
    1295           0 :                         break;
    1296             :                 }
    1297             :         }
    1298             : 
    1299             :         /* Kick Tx. */
    1300           0 :         AR_WRITE(sc, AR_Q_TXE, 1 << ATHN_QID_BEACON);
    1301           0 :         AR_WRITE_BARRIER(sc);
    1302           0 :         return (0);
    1303           0 : }
    1304             : #endif
    1305             : 
    1306             : int
    1307           0 : ar9003_intr(struct athn_softc *sc)
    1308             : {
    1309             :         uint32_t intr, intr2, intr5, sync;
    1310             : 
    1311             :         /* Get pending interrupts. */
    1312           0 :         intr = AR_READ(sc, AR_INTR_ASYNC_CAUSE);
    1313           0 :         if (!(intr & AR_INTR_MAC_IRQ) || intr == AR_INTR_SPURIOUS) {
    1314           0 :                 intr = AR_READ(sc, AR_INTR_SYNC_CAUSE);
    1315           0 :                 if (intr == AR_INTR_SPURIOUS || (intr & sc->isync) == 0)
    1316           0 :                         return (0);     /* Not for us. */
    1317             :         }
    1318             : 
    1319           0 :         if ((AR_READ(sc, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) &&
    1320           0 :             (AR_READ(sc, AR_RTC_STATUS) & AR_RTC_STATUS_M) == AR_RTC_STATUS_ON)
    1321           0 :                 intr = AR_READ(sc, AR_ISR);
    1322             :         else
    1323             :                 intr = 0;
    1324           0 :         sync = AR_READ(sc, AR_INTR_SYNC_CAUSE) & sc->isync;
    1325           0 :         if (intr == 0 && sync == 0)
    1326           0 :                 return (0);     /* Not for us. */
    1327             : 
    1328           0 :         if (intr != 0) {
    1329           0 :                 if (intr & AR_ISR_BCNMISC) {
    1330           0 :                         intr2 = AR_READ(sc, AR_ISR_S2);
    1331           0 :                         if (intr2 & AR_ISR_S2_TIM)
    1332             :                                 /* TBD */;
    1333           0 :                         if (intr2 & AR_ISR_S2_TSFOOR)
    1334             :                                 /* TBD */;
    1335           0 :                         if (intr2 & AR_ISR_S2_BB_WATCHDOG)
    1336             :                                 /* TBD */;
    1337           0 :                 }
    1338           0 :                 intr = AR_READ(sc, AR_ISR_RAC);
    1339           0 :                 if (intr == AR_INTR_SPURIOUS)
    1340           0 :                         return (1);
    1341             : 
    1342             : #ifndef IEEE80211_STA_ONLY
    1343           0 :                 if (intr & AR_ISR_SWBA)
    1344           0 :                         ar9003_swba_intr(sc);
    1345             : #endif
    1346           0 :                 if (intr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
    1347           0 :                         ar9003_rx_intr(sc, ATHN_QID_LP);
    1348           0 :                 if (intr & (AR_ISR_LP_RXOK | AR_ISR_RXERR | AR_ISR_RXEOL))
    1349           0 :                         ar9003_rx_intr(sc, ATHN_QID_LP);
    1350           0 :                 if (intr & AR_ISR_HP_RXOK)
    1351           0 :                         ar9003_rx_intr(sc, ATHN_QID_HP);
    1352             : 
    1353           0 :                 if (intr & (AR_ISR_TXMINTR | AR_ISR_TXINTM))
    1354           0 :                         ar9003_tx_intr(sc);
    1355           0 :                 if (intr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL))
    1356           0 :                         ar9003_tx_intr(sc);
    1357             : 
    1358           0 :                 if (intr & AR_ISR_GENTMR) {
    1359           0 :                         intr5 = AR_READ(sc, AR_ISR_S5_S);
    1360             :                         DPRINTF(("GENTMR trigger=%d thresh=%d\n",
    1361             :                             MS(intr5, AR_ISR_S5_GENTIMER_TRIG),
    1362             :                             MS(intr5, AR_ISR_S5_GENTIMER_THRESH)));
    1363           0 :                 }
    1364             :         }
    1365           0 :         if (sync != 0) {
    1366           0 :                 if (sync & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
    1367           0 :                         AR_WRITE(sc, AR_RC, AR_RC_HOSTIF);
    1368           0 :                         AR_WRITE(sc, AR_RC, 0);
    1369           0 :                 }
    1370             : 
    1371           0 :                 if ((sc->flags & ATHN_FLAG_RFSILENT) &&
    1372           0 :                     (sync & AR_INTR_SYNC_GPIO_PIN(sc->rfsilent_pin))) {
    1373           0 :                         struct ifnet *ifp = &sc->sc_ic.ic_if;
    1374             : 
    1375           0 :                         printf("%s: radio switch turned off\n",
    1376           0 :                             sc->sc_dev.dv_xname);
    1377             :                         /* Turn the interface down. */
    1378           0 :                         athn_stop(ifp, 1);
    1379             :                         return (1);
    1380             :                 }
    1381             : 
    1382           0 :                 AR_WRITE(sc, AR_INTR_SYNC_CAUSE, sync);
    1383           0 :                 (void)AR_READ(sc, AR_INTR_SYNC_CAUSE);
    1384           0 :         }
    1385           0 :         return (1);
    1386           0 : }
    1387             : 
    1388             : int
    1389           0 : ar9003_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
    1390             :     int txflags)
    1391             : {
    1392           0 :         struct ieee80211com *ic = &sc->sc_ic;
    1393             :         struct ieee80211_key *k = NULL;
    1394             :         struct ieee80211_frame *wh;
    1395           0 :         struct athn_series series[4];
    1396             :         struct ar_tx_desc *ds;
    1397             :         struct athn_txq *txq;
    1398             :         struct athn_tx_buf *bf;
    1399           0 :         struct athn_node *an = (void *)ni;
    1400             :         struct mbuf *m1;
    1401             :         uintptr_t entry;
    1402             :         uint32_t sum;
    1403             :         uint16_t qos = 0;
    1404           0 :         uint8_t txpower, type, encrtype, tid, ridx[4];
    1405             :         int i, error, totlen, hasqos, qid;
    1406             : 
    1407             :         /* Grab a Tx buffer from our global free list. */
    1408           0 :         bf = SIMPLEQ_FIRST(&sc->txbufs);
    1409           0 :         KASSERT(bf != NULL);
    1410             : 
    1411             :         /* Map 802.11 frame type to hardware frame type. */
    1412           0 :         wh = mtod(m, struct ieee80211_frame *);
    1413           0 :         if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
    1414             :             IEEE80211_FC0_TYPE_MGT) {
    1415             :                 /* NB: Beacons do not use ar9003_tx(). */
    1416           0 :                 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
    1417             :                     IEEE80211_FC0_SUBTYPE_PROBE_RESP)
    1418           0 :                         type = AR_FRAME_TYPE_PROBE_RESP;
    1419           0 :                 else if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
    1420             :                     IEEE80211_FC0_SUBTYPE_ATIM)
    1421           0 :                         type = AR_FRAME_TYPE_ATIM;
    1422             :                 else
    1423             :                         type = AR_FRAME_TYPE_NORMAL;
    1424           0 :         } else if ((wh->i_fc[0] &
    1425           0 :             (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
    1426             :             (IEEE80211_FC0_TYPE_CTL  | IEEE80211_FC0_SUBTYPE_PS_POLL)) {
    1427             :                 type = AR_FRAME_TYPE_PSPOLL;
    1428           0 :         } else
    1429             :                 type = AR_FRAME_TYPE_NORMAL;
    1430             : 
    1431           0 :         if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
    1432           0 :                 k = ieee80211_get_txkey(ic, wh, ni);
    1433           0 :                 if ((m = ieee80211_encrypt(ic, m, k)) == NULL)
    1434           0 :                         return (ENOBUFS);
    1435           0 :                 wh = mtod(m, struct ieee80211_frame *);
    1436           0 :         }
    1437             : 
    1438             :         /* XXX 2-byte padding for QoS and 4-addr headers. */
    1439             : 
    1440             :         /* Select the HW Tx queue to use for this frame. */
    1441           0 :         if ((hasqos = ieee80211_has_qos(wh))) {
    1442           0 :                 qos = ieee80211_get_qos(wh);
    1443           0 :                 tid = qos & IEEE80211_QOS_TID;
    1444           0 :                 qid = athn_ac2qid[ieee80211_up_to_ac(ic, tid)];
    1445           0 :         } else if (type == AR_FRAME_TYPE_PSPOLL) {
    1446             :                 qid = ATHN_QID_PSPOLL;
    1447           0 :         } else if (txflags & ATHN_TXFLAG_CAB) {
    1448             :                 qid = ATHN_QID_CAB;
    1449           0 :         } else
    1450             :                 qid = ATHN_QID_AC_BE;
    1451           0 :         txq = &sc->txq[qid];
    1452             : 
    1453             :         /* Select the transmit rates to use for this frame. */
    1454           0 :         if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
    1455           0 :             (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) !=
    1456             :             IEEE80211_FC0_TYPE_DATA) {
    1457             :                 /* Use lowest rate for all tries. */
    1458           0 :                 ridx[0] = ridx[1] = ridx[2] = ridx[3] =
    1459           0 :                     (ic->ic_curmode == IEEE80211_MODE_11A) ?
    1460             :                         ATHN_RIDX_OFDM6 : ATHN_RIDX_CCK1;
    1461           0 :         } else if (ic->ic_fixed_rate != -1) {
    1462             :                 /* Use same fixed rate for all tries. */
    1463           0 :                 ridx[0] = ridx[1] = ridx[2] = ridx[3] =
    1464           0 :                     sc->fixed_ridx;
    1465           0 :         } else {
    1466           0 :                 int txrate = ni->ni_txrate;
    1467             :                 /* Use fallback table of the node. */
    1468           0 :                 for (i = 0; i < 4; i++) {
    1469           0 :                         ridx[i] = an->ridx[txrate];
    1470           0 :                         txrate = an->fallback[txrate];
    1471             :                 }
    1472             :         }
    1473             : 
    1474             : #if NBPFILTER > 0
    1475           0 :         if (__predict_false(sc->sc_drvbpf != NULL)) {
    1476           0 :                 struct athn_tx_radiotap_header *tap = &sc->sc_txtap;
    1477           0 :                 struct mbuf mb;
    1478             : 
    1479           0 :                 tap->wt_flags = 0;
    1480             :                 /* Use initial transmit rate. */
    1481           0 :                 tap->wt_rate = athn_rates[ridx[0]].rate;
    1482           0 :                 tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
    1483           0 :                 tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
    1484           0 :                 tap->wt_hwqueue = qid;
    1485           0 :                 if (ridx[0] != ATHN_RIDX_CCK1 &&
    1486           0 :                     (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
    1487           0 :                         tap->wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
    1488           0 :                 mb.m_data = (caddr_t)tap;
    1489           0 :                 mb.m_len = sc->sc_txtap_len;
    1490           0 :                 mb.m_next = m;
    1491           0 :                 mb.m_nextpkt = NULL;
    1492           0 :                 mb.m_type = 0;
    1493           0 :                 mb.m_flags = 0;
    1494           0 :                 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
    1495           0 :         }
    1496             : #endif
    1497             : 
    1498             :         /* DMA map mbuf. */
    1499           0 :         error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_map, m,
    1500             :             BUS_DMA_NOWAIT | BUS_DMA_WRITE);
    1501           0 :         if (__predict_false(error != 0)) {
    1502           0 :                 if (error != EFBIG) {
    1503           0 :                         printf("%s: can't map mbuf (error %d)\n",
    1504           0 :                             sc->sc_dev.dv_xname, error);
    1505           0 :                         m_freem(m);
    1506           0 :                         return (error);
    1507             :                 }
    1508             :                 /*
    1509             :                  * DMA mapping requires too many DMA segments; linearize
    1510             :                  * mbuf in kernel virtual address space and retry.
    1511             :                  */
    1512           0 :                 MGETHDR(m1, M_DONTWAIT, MT_DATA);
    1513           0 :                 if (m1 == NULL) {
    1514           0 :                         m_freem(m);
    1515           0 :                         return (ENOBUFS);
    1516             :                 }
    1517           0 :                 if (m->m_pkthdr.len > MHLEN) {
    1518           0 :                         MCLGET(m1, M_DONTWAIT);
    1519           0 :                         if (!(m1->m_flags & M_EXT)) {
    1520           0 :                                 m_freem(m);
    1521           0 :                                 m_freem(m1);
    1522           0 :                                 return (ENOBUFS);
    1523             :                         }
    1524             :                 }
    1525           0 :                 m_copydata(m, 0, m->m_pkthdr.len, mtod(m1, caddr_t));
    1526           0 :                 m1->m_pkthdr.len = m1->m_len = m->m_pkthdr.len;
    1527           0 :                 m_freem(m);
    1528             :                 m = m1;
    1529             : 
    1530           0 :                 error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_map, m,
    1531             :                     BUS_DMA_NOWAIT | BUS_DMA_WRITE);
    1532           0 :                 if (error != 0) {
    1533           0 :                         printf("%s: can't map mbuf (error %d)\n",
    1534           0 :                             sc->sc_dev.dv_xname, error);
    1535           0 :                         m_freem(m);
    1536           0 :                         return (error);
    1537             :                 }
    1538             :         }
    1539           0 :         bf->bf_m = m;
    1540           0 :         bf->bf_ni = ni;
    1541           0 :         bf->bf_txflags = txflags;
    1542             : 
    1543           0 :         wh = mtod(m, struct ieee80211_frame *);
    1544             : 
    1545           0 :         totlen = m->m_pkthdr.len + IEEE80211_CRC_LEN;
    1546             : 
    1547             :         /* Setup Tx descriptor. */
    1548           0 :         ds = bf->bf_descs;
    1549           0 :         memset(ds, 0, sizeof(*ds));
    1550             : 
    1551           0 :         ds->ds_info =
    1552             :             SM(AR_TXI_DESC_ID, AR_VENDOR_ATHEROS) |
    1553           0 :             SM(AR_TXI_DESC_NDWORDS, 23) |
    1554           0 :             SM(AR_TXI_QCU_NUM, qid) |
    1555           0 :             AR_TXI_DESC_TX | AR_TXI_CTRL_STAT;
    1556             : 
    1557           0 :         ds->ds_ctl11 = AR_TXC11_CLR_DEST_MASK;
    1558             :         txpower = AR_MAX_RATE_POWER;    /* Get from per-rate registers. */
    1559           0 :         ds->ds_ctl11 |= SM(AR_TXC11_XMIT_POWER, txpower);
    1560             : 
    1561           0 :         ds->ds_ctl12 = SM(AR_TXC12_FRAME_TYPE, type);
    1562             : 
    1563           0 :         if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
    1564           0 :             (hasqos && (qos & IEEE80211_QOS_ACK_POLICY_MASK) ==
    1565             :              IEEE80211_QOS_ACK_POLICY_NOACK))
    1566           0 :                 ds->ds_ctl12 |= AR_TXC12_NO_ACK;
    1567             : 
    1568             :         if (0 && k != NULL) {
    1569             :                 /*
    1570             :                  * Map 802.11 cipher to hardware encryption type and
    1571             :                  * compute MIC+ICV overhead.
    1572             :                  */
    1573             :                 switch (k->k_cipher) {
    1574             :                 case IEEE80211_CIPHER_WEP40:
    1575             :                 case IEEE80211_CIPHER_WEP104:
    1576             :                         encrtype = AR_ENCR_TYPE_WEP;
    1577             :                         totlen += 4;
    1578             :                         break;
    1579             :                 case IEEE80211_CIPHER_TKIP:
    1580             :                         encrtype = AR_ENCR_TYPE_TKIP;
    1581             :                         totlen += 12;
    1582             :                         break;
    1583             :                 case IEEE80211_CIPHER_CCMP:
    1584             :                         encrtype = AR_ENCR_TYPE_AES;
    1585             :                         totlen += 8;
    1586             :                         break;
    1587             :                 default:
    1588             :                         panic("unsupported cipher");
    1589             :                 }
    1590             :                 /*
    1591             :                  * NB: The key cache entry index is stored in the key
    1592             :                  * private field when the key is installed.
    1593             :                  */
    1594             :                 entry = (uintptr_t)k->k_priv;
    1595             :                 ds->ds_ctl12 |= SM(AR_TXC12_DEST_IDX, entry);
    1596             :                 ds->ds_ctl11 |= AR_TXC11_DEST_IDX_VALID;
    1597             :         } else
    1598             :                 encrtype = AR_ENCR_TYPE_CLEAR;
    1599           0 :         ds->ds_ctl17 = SM(AR_TXC17_ENCR_TYPE, encrtype);
    1600             : 
    1601             :         /* Check if frame must be protected using RTS/CTS or CTS-to-self. */
    1602           0 :         if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
    1603           0 :             (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
    1604             :             IEEE80211_FC0_TYPE_DATA) {
    1605             :                 /* NB: Group frames are sent using CCK in 802.11b/g. */
    1606           0 :                 if (totlen > ic->ic_rtsthreshold) {
    1607           0 :                         ds->ds_ctl11 |= AR_TXC11_RTS_ENABLE;
    1608           0 :                 } else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
    1609           0 :                     athn_rates[ridx[0]].phy == IEEE80211_T_OFDM) {
    1610           0 :                         if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
    1611           0 :                                 ds->ds_ctl11 |= AR_TXC11_RTS_ENABLE;
    1612           0 :                         else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
    1613           0 :                                 ds->ds_ctl11 |= AR_TXC11_CTS_ENABLE;
    1614             :                 }
    1615             :         }
    1616             :         /* 
    1617             :          * Disable multi-rate retries when protection is used.
    1618             :          * The RTS/CTS frame's duration field is fixed and won't be
    1619             :          * updated by hardware when the data rate changes.
    1620             :          */
    1621           0 :         if (ds->ds_ctl11 & (AR_TXC11_RTS_ENABLE | AR_TXC11_CTS_ENABLE)) {
    1622           0 :                 ridx[1] = ridx[2] = ridx[3] = ridx[0];
    1623           0 :         }
    1624             :         /* Setup multi-rate retries. */
    1625           0 :         for (i = 0; i < 4; i++) {
    1626           0 :                 series[i].hwrate = athn_rates[ridx[i]].hwrate;
    1627           0 :                 if (athn_rates[ridx[i]].phy == IEEE80211_T_DS &&
    1628           0 :                     ridx[i] != ATHN_RIDX_CCK1 &&
    1629           0 :                     (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
    1630           0 :                         series[i].hwrate |= 0x04;
    1631           0 :                 series[i].dur = 0;
    1632             :         }
    1633           0 :         if (!(ds->ds_ctl12 & AR_TXC12_NO_ACK)) {
    1634             :                 /* Compute duration for each series. */
    1635           0 :                 for (i = 0; i < 4; i++) {
    1636           0 :                         series[i].dur = athn_txtime(sc, IEEE80211_ACK_LEN,
    1637           0 :                             athn_rates[ridx[i]].rspridx, ic->ic_flags);
    1638             :                 }
    1639             :         }
    1640             :         /* If this is a PA training frame, select the Tx chain to use. */
    1641           0 :         if (__predict_false(txflags & ATHN_TXFLAG_PAPRD)) {
    1642           0 :                 ds->ds_ctl12 |= SM(AR_TXC12_PAPRD_CHAIN_MASK,
    1643             :                     1 << sc->paprd_curchain);
    1644           0 :         }
    1645             : 
    1646             :         /* Write number of tries for each series. */
    1647           0 :         ds->ds_ctl13 =
    1648             :             SM(AR_TXC13_XMIT_DATA_TRIES0, 2) |
    1649             :             SM(AR_TXC13_XMIT_DATA_TRIES1, 2) |
    1650             :             SM(AR_TXC13_XMIT_DATA_TRIES2, 2) |
    1651             :             SM(AR_TXC13_XMIT_DATA_TRIES3, 4);
    1652             : 
    1653             :         /* Tell HW to update duration field in 802.11 header. */
    1654           0 :         if (type != AR_FRAME_TYPE_PSPOLL)
    1655           0 :                 ds->ds_ctl13 |= AR_TXC13_DUR_UPDATE_ENA;
    1656             : 
    1657             :         /* Write Tx rate for each series. */
    1658           0 :         ds->ds_ctl14 =
    1659           0 :             SM(AR_TXC14_XMIT_RATE0, series[0].hwrate) |
    1660           0 :             SM(AR_TXC14_XMIT_RATE1, series[1].hwrate) |
    1661           0 :             SM(AR_TXC14_XMIT_RATE2, series[2].hwrate) |
    1662           0 :             SM(AR_TXC14_XMIT_RATE3, series[3].hwrate);
    1663             : 
    1664             :         /* Write duration for each series. */
    1665           0 :         ds->ds_ctl15 =
    1666           0 :             SM(AR_TXC15_PACKET_DUR0, series[0].dur) |
    1667           0 :             SM(AR_TXC15_PACKET_DUR1, series[1].dur);
    1668           0 :         ds->ds_ctl16 =
    1669           0 :             SM(AR_TXC16_PACKET_DUR2, series[2].dur) |
    1670           0 :             SM(AR_TXC16_PACKET_DUR3, series[3].dur);
    1671             : 
    1672           0 :         if ((sc->flags & ATHN_FLAG_3TREDUCE_CHAIN) &&
    1673           0 :             ic->ic_curmode == IEEE80211_MODE_11A) {
    1674             :                 /*
    1675             :                  * In order to not exceed PCIe power requirements, we only
    1676             :                  * use two Tx chains for MCS0~15 on 5GHz band on these chips.
    1677             :                  */
    1678           0 :                 ds->ds_ctl18 =
    1679           0 :                     SM(AR_TXC18_CHAIN_SEL0,
    1680           0 :                         (ridx[0] <= ATHN_RIDX_MCS15) ? 0x3 : sc->txchainmask) |
    1681           0 :                     SM(AR_TXC18_CHAIN_SEL1,
    1682           0 :                         (ridx[1] <= ATHN_RIDX_MCS15) ? 0x3 : sc->txchainmask) |
    1683           0 :                     SM(AR_TXC18_CHAIN_SEL2,
    1684           0 :                         (ridx[2] <= ATHN_RIDX_MCS15) ? 0x3 : sc->txchainmask) |
    1685           0 :                     SM(AR_TXC18_CHAIN_SEL3,
    1686             :                         (ridx[3] <= ATHN_RIDX_MCS15) ? 0x3 : sc->txchainmask);
    1687           0 :         } else {
    1688             :                 /* Use the same Tx chains for all tries. */
    1689           0 :                 ds->ds_ctl18 =
    1690           0 :                     SM(AR_TXC18_CHAIN_SEL0, sc->txchainmask) |
    1691           0 :                     SM(AR_TXC18_CHAIN_SEL1, sc->txchainmask) |
    1692           0 :                     SM(AR_TXC18_CHAIN_SEL2, sc->txchainmask) |
    1693           0 :                     SM(AR_TXC18_CHAIN_SEL3, sc->txchainmask);
    1694             :         }
    1695             : #ifdef notyet
    1696             :         /* Use the same short GI setting for all tries. */
    1697             :         if (ic->ic_flags & IEEE80211_F_SHGI)
    1698             :                 ds->ds_ctl18 |= AR_TXC18_GI0123;
    1699             :         /* Use the same channel width for all tries. */
    1700             :         if (ic->ic_flags & IEEE80211_F_CBW40)
    1701             :                 ds->ds_ctl18 |= AR_TXC18_2040_0123;
    1702             : #endif
    1703             : 
    1704           0 :         if (ds->ds_ctl11 & (AR_TXC11_RTS_ENABLE | AR_TXC11_CTS_ENABLE)) {
    1705             :                 uint8_t protridx, hwrate;
    1706             :                 uint16_t dur = 0;
    1707             : 
    1708             :                 /* Use the same protection mode for all tries. */
    1709           0 :                 if (ds->ds_ctl11 & AR_TXC11_RTS_ENABLE) {
    1710           0 :                         ds->ds_ctl15 |= AR_TXC15_RTSCTS_QUAL01;
    1711           0 :                         ds->ds_ctl16 |= AR_TXC16_RTSCTS_QUAL23;
    1712           0 :                 }
    1713             :                 /* Select protection rate (suboptimal but ok). */
    1714           0 :                 protridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
    1715             :                     ATHN_RIDX_OFDM6 : ATHN_RIDX_CCK2;
    1716           0 :                 if (ds->ds_ctl11 & AR_TXC11_RTS_ENABLE) {
    1717             :                         /* Account for CTS duration. */
    1718           0 :                         dur += athn_txtime(sc, IEEE80211_ACK_LEN,
    1719           0 :                             athn_rates[protridx].rspridx, ic->ic_flags);
    1720           0 :                 }
    1721           0 :                 dur += athn_txtime(sc, totlen, ridx[0], ic->ic_flags);
    1722           0 :                 if (!(ds->ds_ctl12 & AR_TXC12_NO_ACK)) {
    1723             :                         /* Account for ACK duration. */
    1724           0 :                         dur += athn_txtime(sc, IEEE80211_ACK_LEN,
    1725           0 :                             athn_rates[ridx[0]].rspridx, ic->ic_flags);
    1726           0 :                 }
    1727             :                 /* Write protection frame duration and rate. */
    1728           0 :                 ds->ds_ctl13 |= SM(AR_TXC13_BURST_DUR, dur);
    1729           0 :                 hwrate = athn_rates[protridx].hwrate;
    1730           0 :                 if (protridx == ATHN_RIDX_CCK2 &&
    1731           0 :                     (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
    1732           0 :                         hwrate |= 0x04;
    1733           0 :                 ds->ds_ctl18 |= SM(AR_TXC18_RTSCTS_RATE, hwrate);
    1734           0 :         }
    1735             : 
    1736           0 :         ds->ds_ctl11 |= SM(AR_TXC11_FRAME_LEN, totlen);
    1737           0 :         ds->ds_ctl19 = AR_TXC19_NOT_SOUNDING;
    1738             : 
    1739           0 :         for (i = 0; i < bf->bf_map->dm_nsegs; i++) {
    1740           0 :                 ds->ds_segs[i].ds_data = bf->bf_map->dm_segs[i].ds_addr;
    1741           0 :                 ds->ds_segs[i].ds_ctl = SM(AR_TXC_BUF_LEN,
    1742             :                     bf->bf_map->dm_segs[i].ds_len);
    1743             :         }
    1744             :         /* Compute Tx descriptor checksum. */
    1745           0 :         sum = ds->ds_info + ds->ds_link;
    1746           0 :         for (i = 0; i < 4; i++) {
    1747           0 :                 sum += ds->ds_segs[i].ds_data;
    1748           0 :                 sum += ds->ds_segs[i].ds_ctl;
    1749             :         }
    1750           0 :         sum = (sum >> 16) + (sum & 0xffff);
    1751           0 :         ds->ds_ctl10 = SM(AR_TXC10_PTR_CHK_SUM, sum);
    1752             : 
    1753           0 :         bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, bf->bf_map->dm_mapsize,
    1754             :             BUS_DMASYNC_PREWRITE);
    1755             : 
    1756             :         DPRINTFN(6, ("Tx qid=%d nsegs=%d ctl11=0x%x ctl12=0x%x ctl14=0x%x\n",
    1757             :             qid, bf->bf_map->dm_nsegs, ds->ds_ctl11, ds->ds_ctl12,
    1758             :             ds->ds_ctl14));
    1759             : 
    1760           0 :         SIMPLEQ_REMOVE_HEAD(&sc->txbufs, bf_list);
    1761           0 :         SIMPLEQ_INSERT_TAIL(&txq->head, bf, bf_list);
    1762             : 
    1763             :         /* Queue buffer unless hardware FIFO is already full. */
    1764           0 :         if (++txq->queued <= AR9003_TX_QDEPTH) {
    1765           0 :                 AR_WRITE(sc, AR_QTXDP(qid), bf->bf_daddr);
    1766           0 :                 AR_WRITE_BARRIER(sc);
    1767           0 :         } else if (txq->wait == NULL)
    1768           0 :                 txq->wait = bf;
    1769           0 :         return (0);
    1770           0 : }
    1771             : 
    1772             : void
    1773           0 : ar9003_set_rf_mode(struct athn_softc *sc, struct ieee80211_channel *c)
    1774             : {
    1775             :         uint32_t reg;
    1776             : 
    1777           0 :         reg = IEEE80211_IS_CHAN_2GHZ(c) ?
    1778             :             AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
    1779           0 :         if (IEEE80211_IS_CHAN_5GHZ(c) &&
    1780           0 :             (sc->flags & ATHN_FLAG_FAST_PLL_CLOCK)) {
    1781             :                 reg |= AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE;
    1782           0 :         }
    1783           0 :         AR_WRITE(sc, AR_PHY_MODE, reg);
    1784           0 :         AR_WRITE_BARRIER(sc);
    1785           0 : }
    1786             : 
    1787             : static __inline uint32_t
    1788           0 : ar9003_synth_delay(struct athn_softc *sc)
    1789             : {
    1790             :         uint32_t delay;
    1791             : 
    1792           0 :         delay = MS(AR_READ(sc, AR_PHY_RX_DELAY), AR_PHY_RX_DELAY_DELAY);
    1793           0 :         if (sc->sc_ic.ic_curmode == IEEE80211_MODE_11B)
    1794           0 :                 delay = (delay * 4) / 22;
    1795             :         else
    1796           0 :                 delay = delay / 10;     /* in 100ns steps */
    1797           0 :         return (delay);
    1798             : }
    1799             : 
    1800             : int
    1801           0 : ar9003_rf_bus_request(struct athn_softc *sc)
    1802             : {
    1803             :         int ntries;
    1804             : 
    1805             :         /* Request RF Bus grant. */
    1806           0 :         AR_WRITE(sc, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
    1807           0 :         for (ntries = 0; ntries < 10000; ntries++) {
    1808           0 :                 if (AR_READ(sc, AR_PHY_RFBUS_GRANT) & AR_PHY_RFBUS_GRANT_EN)
    1809           0 :                         return (0);
    1810           0 :                 DELAY(10);
    1811             :         }
    1812             :         DPRINTF(("could not kill baseband Rx"));
    1813           0 :         return (ETIMEDOUT);
    1814           0 : }
    1815             : 
    1816             : void
    1817           0 : ar9003_rf_bus_release(struct athn_softc *sc)
    1818             : {
    1819             :         /* Wait for the synthesizer to settle. */
    1820           0 :         DELAY(AR_BASE_PHY_ACTIVE_DELAY + ar9003_synth_delay(sc));
    1821             : 
    1822             :         /* Release the RF Bus grant. */
    1823           0 :         AR_WRITE(sc, AR_PHY_RFBUS_REQ, 0);
    1824           0 :         AR_WRITE_BARRIER(sc);
    1825           0 : }
    1826             : 
    1827             : void
    1828           0 : ar9003_set_phy(struct athn_softc *sc, struct ieee80211_channel *c,
    1829             :     struct ieee80211_channel *extc)
    1830             : {
    1831             :         uint32_t phy;
    1832             : 
    1833           0 :         phy = AR_READ(sc, AR_PHY_GEN_CTRL);
    1834           0 :         phy |= AR_PHY_GC_HT_EN | AR_PHY_GC_SHORT_GI_40 |
    1835             :             AR_PHY_GC_SINGLE_HT_LTF1 | AR_PHY_GC_WALSH;
    1836           0 :         if (extc != NULL) {
    1837           0 :                 phy |= AR_PHY_GC_DYN2040_EN;
    1838           0 :                 if (extc > c)        /* XXX */
    1839           0 :                         phy |= AR_PHY_GC_DYN2040_PRI_CH;
    1840             :         }
    1841             :         /* Turn off Green Field detection for now. */
    1842           0 :         phy &= ~AR_PHY_GC_GF_DETECT_EN;
    1843           0 :         AR_WRITE(sc, AR_PHY_GEN_CTRL, phy);
    1844             : 
    1845           0 :         AR_WRITE(sc, AR_2040_MODE,
    1846             :             (extc != NULL) ? AR_2040_JOINED_RX_CLEAR : 0);
    1847             : 
    1848             :         /* Set global transmit timeout. */
    1849           0 :         AR_WRITE(sc, AR_GTXTO, SM(AR_GTXTO_TIMEOUT_LIMIT, 25));
    1850             :         /* Set carrier sense timeout. */
    1851           0 :         AR_WRITE(sc, AR_CST, SM(AR_CST_TIMEOUT_LIMIT, 15));
    1852           0 :         AR_WRITE_BARRIER(sc);
    1853           0 : }
    1854             : 
    1855             : void
    1856           0 : ar9003_set_delta_slope(struct athn_softc *sc, struct ieee80211_channel *c,
    1857             :     struct ieee80211_channel *extc)
    1858             : {
    1859           0 :         uint32_t coeff, exp, man, reg;
    1860             : 
    1861             :         /* Set Delta Slope (exponent and mantissa). */
    1862           0 :         coeff = (100 << 24) / c->ic_freq;
    1863           0 :         athn_get_delta_slope(coeff, &exp, &man);
    1864             :         DPRINTFN(5, ("delta slope coeff exp=%u man=%u\n", exp, man));
    1865             : 
    1866           0 :         reg = AR_READ(sc, AR_PHY_TIMING3);
    1867           0 :         reg = RW(reg, AR_PHY_TIMING3_DSC_EXP, exp);
    1868           0 :         reg = RW(reg, AR_PHY_TIMING3_DSC_MAN, man);
    1869           0 :         AR_WRITE(sc, AR_PHY_TIMING3, reg);
    1870             : 
    1871             :         /* For Short GI, coeff is 9/10 that of normal coeff. */
    1872           0 :         coeff = (9 * coeff) / 10;
    1873           0 :         athn_get_delta_slope(coeff, &exp, &man);
    1874             :         DPRINTFN(5, ("delta slope coeff exp=%u man=%u\n", exp, man));
    1875             : 
    1876           0 :         reg = AR_READ(sc, AR_PHY_SGI_DELTA);
    1877           0 :         reg = RW(reg, AR_PHY_SGI_DSC_EXP, exp);
    1878           0 :         reg = RW(reg, AR_PHY_SGI_DSC_MAN, man);
    1879           0 :         AR_WRITE(sc, AR_PHY_SGI_DELTA, reg);
    1880           0 :         AR_WRITE_BARRIER(sc);
    1881           0 : }
    1882             : 
    1883             : void
    1884           0 : ar9003_enable_antenna_diversity(struct athn_softc *sc)
    1885             : {
    1886           0 :         AR_SETBITS(sc, AR_PHY_CCK_DETECT,
    1887             :             AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
    1888           0 :         AR_WRITE_BARRIER(sc);
    1889           0 : }
    1890             : 
    1891             : void
    1892           0 : ar9003_init_baseband(struct athn_softc *sc)
    1893             : {
    1894             :         uint32_t synth_delay;
    1895             : 
    1896           0 :         synth_delay = ar9003_synth_delay(sc);
    1897             :         /* Activate the PHY (includes baseband activate and synthesizer on). */
    1898           0 :         AR_WRITE(sc, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
    1899           0 :         AR_WRITE_BARRIER(sc);
    1900           0 :         DELAY(AR_BASE_PHY_ACTIVE_DELAY + synth_delay);
    1901           0 : }
    1902             : 
    1903             : void
    1904           0 : ar9003_disable_phy(struct athn_softc *sc)
    1905             : {
    1906           0 :         AR_WRITE(sc, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
    1907           0 :         AR_WRITE_BARRIER(sc);
    1908           0 : }
    1909             : 
    1910             : void
    1911           0 : ar9003_init_chains(struct athn_softc *sc)
    1912             : {
    1913           0 :         if (sc->rxchainmask == 0x5 || sc->txchainmask == 0x5)
    1914           0 :                 AR_SETBITS(sc, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN);
    1915             : 
    1916             :         /* Setup chain masks. */
    1917           0 :         AR_WRITE(sc, AR_PHY_RX_CHAINMASK,  sc->rxchainmask);
    1918           0 :         AR_WRITE(sc, AR_PHY_CAL_CHAINMASK, sc->rxchainmask);
    1919             : 
    1920           0 :         if (sc->flags & ATHN_FLAG_3TREDUCE_CHAIN) {
    1921             :                 /*
    1922             :                  * All self-generated frames are sent using two Tx chains
    1923             :                  * on these chips to not exceed PCIe power requirements.
    1924             :                  */
    1925           0 :                 AR_WRITE(sc, AR_SELFGEN_MASK, 0x3);
    1926           0 :         } else
    1927           0 :                 AR_WRITE(sc, AR_SELFGEN_MASK, sc->txchainmask);
    1928           0 :         AR_WRITE_BARRIER(sc);
    1929           0 : }
    1930             : 
    1931             : void
    1932           0 : ar9003_set_rxchains(struct athn_softc *sc)
    1933             : {
    1934           0 :         if (sc->rxchainmask == 0x3 || sc->rxchainmask == 0x5) {
    1935           0 :                 AR_WRITE(sc, AR_PHY_RX_CHAINMASK,  sc->rxchainmask);
    1936           0 :                 AR_WRITE(sc, AR_PHY_CAL_CHAINMASK, sc->rxchainmask);
    1937           0 :                 AR_WRITE_BARRIER(sc);
    1938           0 :         }
    1939           0 : }
    1940             : 
    1941             : void
    1942           0 : ar9003_read_noisefloor(struct athn_softc *sc, int16_t *nf, int16_t *nf_ext)
    1943             : {
    1944             : /* Sign-extends 9-bit value (assumes upper bits are zeroes). */
    1945             : #define SIGN_EXT(v)     (((v) ^ 0x100) - 0x100)
    1946             :         uint32_t reg;
    1947             :         int i;
    1948             : 
    1949           0 :         for (i = 0; i < sc->nrxchains; i++) {
    1950           0 :                 reg = AR_READ(sc, AR_PHY_CCA(i));
    1951           0 :                 nf[i] = MS(reg, AR_PHY_MINCCA_PWR);
    1952           0 :                 nf[i] = SIGN_EXT(nf[i]);
    1953             : 
    1954           0 :                 reg = AR_READ(sc, AR_PHY_EXT_CCA(i));
    1955           0 :                 nf_ext[i] = MS(reg, AR_PHY_EXT_MINCCA_PWR);
    1956           0 :                 nf_ext[i] = SIGN_EXT(nf_ext[i]);
    1957             :         }
    1958             : #undef SIGN_EXT
    1959           0 : }
    1960             : 
    1961             : void
    1962           0 : ar9003_write_noisefloor(struct athn_softc *sc, int16_t *nf, int16_t *nf_ext)
    1963             : {
    1964             :         uint32_t reg;
    1965             :         int i;
    1966             : 
    1967           0 :         for (i = 0; i < sc->nrxchains; i++) {
    1968           0 :                 reg = AR_READ(sc, AR_PHY_CCA(i));
    1969           0 :                 reg = RW(reg, AR_PHY_MAXCCA_PWR, nf[i]);
    1970           0 :                 AR_WRITE(sc, AR_PHY_CCA(i), reg);
    1971             : 
    1972           0 :                 reg = AR_READ(sc, AR_PHY_EXT_CCA(i));
    1973           0 :                 reg = RW(reg, AR_PHY_EXT_MAXCCA_PWR, nf_ext[i]);
    1974           0 :                 AR_WRITE(sc, AR_PHY_EXT_CCA(i), reg);
    1975             :         }
    1976           0 :         AR_WRITE_BARRIER(sc);
    1977           0 : }
    1978             : 
    1979             : void
    1980           0 : ar9003_get_noisefloor(struct athn_softc *sc, struct ieee80211_channel *c)
    1981             : {
    1982           0 :         int16_t nf[AR_MAX_CHAINS], nf_ext[AR_MAX_CHAINS];
    1983             :         int16_t min, max;
    1984             :         int i;
    1985             : 
    1986           0 :         if (AR_READ(sc, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
    1987             :                 /* Noisefloor calibration not finished. */
    1988           0 :                 return;
    1989             :         }
    1990             :         /* Noisefloor calibration is finished. */
    1991           0 :         ar9003_read_noisefloor(sc, nf, nf_ext);
    1992             : 
    1993           0 :         if (IEEE80211_IS_CHAN_2GHZ(c)) {
    1994           0 :                 min = sc->cca_min_2g;
    1995           0 :                 max = sc->cca_max_2g;
    1996           0 :         } else {
    1997           0 :                 min = sc->cca_min_5g;
    1998           0 :                 max = sc->cca_max_5g;
    1999             :         }
    2000             :         /* Update noisefloor history. */
    2001           0 :         for (i = 0; i < sc->nrxchains; i++) {
    2002           0 :                 if (nf[i] < min)
    2003           0 :                         nf[i] = min;
    2004           0 :                 else if (nf[i] > max)
    2005           0 :                         nf[i] = max;
    2006           0 :                 if (nf_ext[i] < min)
    2007           0 :                         nf_ext[i] = min;
    2008           0 :                 else if (nf_ext[i] > max)
    2009           0 :                         nf_ext[i] = max;
    2010             : 
    2011           0 :                 sc->nf_hist[sc->nf_hist_cur].nf[i] = nf[i];
    2012           0 :                 sc->nf_hist[sc->nf_hist_cur].nf_ext[i] = nf_ext[i];
    2013             :         }
    2014           0 :         if (++sc->nf_hist_cur >= ATHN_NF_CAL_HIST_MAX)
    2015           0 :                 sc->nf_hist_cur = 0;
    2016           0 : }
    2017             : 
    2018             : void
    2019           0 : ar9003_bb_load_noisefloor(struct athn_softc *sc)
    2020             : {
    2021           0 :         int16_t nf[AR_MAX_CHAINS], nf_ext[AR_MAX_CHAINS];
    2022             :         int i, ntries;
    2023             : 
    2024             :         /* Write filtered noisefloor values. */
    2025           0 :         for (i = 0; i < sc->nrxchains; i++) {
    2026           0 :                 nf[i] = sc->nf_priv[i] * 2;
    2027           0 :                 nf_ext[i] = sc->nf_ext_priv[i] * 2;
    2028             :         }
    2029           0 :         ar9003_write_noisefloor(sc, nf, nf_ext);
    2030             : 
    2031             :         /* Load filtered noisefloor values into baseband. */
    2032           0 :         AR_CLRBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
    2033           0 :         AR_CLRBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
    2034           0 :         AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
    2035             :         /* Wait for load to complete. */
    2036           0 :         for (ntries = 0; ntries < 1000; ntries++) {
    2037           0 :                 if (!(AR_READ(sc, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF))
    2038             :                         break;
    2039           0 :                 DELAY(10);
    2040             :         }
    2041           0 :         if (ntries == 1000) {
    2042             :                 DPRINTF(("failed to load noisefloor values\n"));
    2043           0 :                 return;
    2044             :         }
    2045             : 
    2046             :         /* Restore noisefloor values to initial (max) values. */
    2047           0 :         for (i = 0; i < AR_MAX_CHAINS; i++)
    2048           0 :                 nf[i] = nf_ext[i] = -50 * 2;
    2049           0 :         ar9003_write_noisefloor(sc, nf, nf_ext);
    2050           0 : }
    2051             : 
    2052             : void
    2053           0 : ar9300_noisefloor_calib(struct athn_softc *sc)
    2054             : {
    2055           0 :         AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
    2056           0 :         AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
    2057           0 :         AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
    2058           0 : }
    2059             : 
    2060             : void
    2061           0 : ar9003_do_noisefloor_calib(struct athn_softc *sc)
    2062             : {
    2063           0 :         AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
    2064           0 : }
    2065             : 
    2066             : int
    2067           0 : ar9003_init_calib(struct athn_softc *sc)
    2068             : {
    2069             :         uint8_t txchainmask, rxchainmask;
    2070             :         uint32_t reg;
    2071             :         int ntries;
    2072             : 
    2073             :         /* Save chains masks. */
    2074           0 :         txchainmask = sc->txchainmask;
    2075           0 :         rxchainmask = sc->rxchainmask;
    2076             :         /* Configure hardware before calibration. */
    2077           0 :         if (AR_READ(sc, AR_ENT_OTP) & AR_ENT_OTP_CHAIN2_DISABLE)
    2078           0 :                 txchainmask = rxchainmask = 0x3;
    2079             :         else
    2080             :                 txchainmask = rxchainmask = 0x7;
    2081           0 :         ar9003_init_chains(sc);
    2082             : 
    2083             :         /* Perform Tx IQ calibration. */
    2084           0 :         ar9003_calib_tx_iq(sc);
    2085             :         /* Disable and re-enable the PHY chips. */
    2086           0 :         AR_WRITE(sc, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
    2087           0 :         AR_WRITE_BARRIER(sc);
    2088           0 :         DELAY(5);
    2089           0 :         AR_WRITE(sc, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
    2090             : 
    2091             :         /* Calibrate the AGC. */
    2092           0 :         AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
    2093             :         /* Poll for offset calibration completion. */
    2094           0 :         for (ntries = 0; ntries < 10000; ntries++) {
    2095           0 :                 reg = AR_READ(sc, AR_PHY_AGC_CONTROL);
    2096           0 :                 if (!(reg & AR_PHY_AGC_CONTROL_CAL))
    2097             :                         break;
    2098           0 :                 DELAY(10);
    2099             :         }
    2100           0 :         if (ntries == 10000)
    2101           0 :                 return (ETIMEDOUT);
    2102             : 
    2103             :         /* Restore chains masks. */
    2104           0 :         sc->txchainmask = txchainmask;
    2105           0 :         sc->rxchainmask = rxchainmask;
    2106           0 :         ar9003_init_chains(sc);
    2107             : 
    2108           0 :         return (0);
    2109           0 : }
    2110             : 
    2111             : void
    2112           0 : ar9003_do_calib(struct athn_softc *sc)
    2113             : {
    2114             :         uint32_t reg;
    2115             : 
    2116           0 :         if (sc->cur_calib_mask & ATHN_CAL_IQ) {
    2117           0 :                 reg = AR_READ(sc, AR_PHY_TIMING4);
    2118           0 :                 reg = RW(reg, AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX, 10);
    2119           0 :                 AR_WRITE(sc, AR_PHY_TIMING4, reg);
    2120           0 :                 AR_WRITE(sc, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
    2121           0 :                 AR_SETBITS(sc, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
    2122           0 :                 AR_WRITE_BARRIER(sc);
    2123           0 :         } else if (sc->cur_calib_mask & ATHN_CAL_TEMP) {
    2124           0 :                 AR_SETBITS(sc, AR_PHY_65NM_CH0_THERM,
    2125             :                     AR_PHY_65NM_CH0_THERM_LOCAL);
    2126           0 :                 AR_SETBITS(sc, AR_PHY_65NM_CH0_THERM,
    2127             :                     AR_PHY_65NM_CH0_THERM_START);
    2128           0 :                 AR_WRITE_BARRIER(sc);
    2129           0 :         }
    2130           0 : }
    2131             : 
    2132             : void
    2133           0 : ar9003_next_calib(struct athn_softc *sc)
    2134             : {
    2135             :         /* Check if we have any calibration in progress. */
    2136           0 :         if (sc->cur_calib_mask != 0) {
    2137           0 :                 if (!(AR_READ(sc, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)) {
    2138             :                         /* Calibration completed for current sample. */
    2139           0 :                         ar9003_calib_iq(sc);
    2140           0 :                 }
    2141             :         }
    2142           0 : }
    2143             : 
    2144             : void
    2145           0 : ar9003_calib_iq(struct athn_softc *sc)
    2146             : {
    2147             :         struct athn_iq_cal *cal;
    2148             :         uint32_t reg, i_coff_denom, q_coff_denom;
    2149             :         int32_t i_coff, q_coff;
    2150             :         int i, iq_corr_neg;
    2151             : 
    2152           0 :         for (i = 0; i < AR_MAX_CHAINS; i++) {
    2153           0 :                 cal = &sc->calib.iq[i];
    2154             : 
    2155             :                 /* Read IQ calibration measures (clear on read). */
    2156           0 :                 cal->pwr_meas_i = AR_READ(sc, AR_PHY_IQ_ADC_MEAS_0_B(i));
    2157           0 :                 cal->pwr_meas_q = AR_READ(sc, AR_PHY_IQ_ADC_MEAS_1_B(i));
    2158           0 :                 cal->iq_corr_meas =
    2159           0 :                     (int32_t)AR_READ(sc, AR_PHY_IQ_ADC_MEAS_2_B(i));
    2160             :         }
    2161             : 
    2162           0 :         for (i = 0; i < sc->nrxchains; i++) {
    2163           0 :                 cal = &sc->calib.iq[i];
    2164             : 
    2165           0 :                 if (cal->pwr_meas_q == 0)
    2166             :                         continue;
    2167             : 
    2168           0 :                 if ((iq_corr_neg = cal->iq_corr_meas < 0))
    2169           0 :                         cal->iq_corr_meas = -cal->iq_corr_meas;
    2170             : 
    2171             :                 i_coff_denom =
    2172           0 :                     (cal->pwr_meas_i / 2 + cal->pwr_meas_q / 2) / 256;
    2173           0 :                 q_coff_denom = cal->pwr_meas_q / 64;
    2174             : 
    2175           0 :                 if (i_coff_denom == 0 || q_coff_denom == 0)
    2176             :                         continue;       /* Prevents division by zero. */
    2177             : 
    2178           0 :                 i_coff = cal->iq_corr_meas / i_coff_denom;
    2179           0 :                 q_coff = (cal->pwr_meas_i / q_coff_denom) - 64;
    2180             : 
    2181           0 :                 if (i_coff > 63)
    2182           0 :                         i_coff = 63;
    2183           0 :                 else if (i_coff < -63)
    2184           0 :                         i_coff = -63;
    2185             :                 /* Negate i_coff if iq_corr_meas is positive. */
    2186           0 :                 if (!iq_corr_neg)
    2187           0 :                         i_coff = -i_coff;
    2188           0 :                 if (q_coff > 63)
    2189           0 :                         q_coff = 63;
    2190           0 :                 else if (q_coff < -63)
    2191           0 :                         q_coff = -63;
    2192             : 
    2193             :                 DPRINTFN(2, ("IQ calibration for chain %d\n", i));
    2194           0 :                 reg = AR_READ(sc, AR_PHY_RX_IQCAL_CORR_B(i));
    2195           0 :                 reg = RW(reg, AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, i_coff);
    2196           0 :                 reg = RW(reg, AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, q_coff);
    2197           0 :                 AR_WRITE(sc, AR_PHY_RX_IQCAL_CORR_B(i), reg);
    2198           0 :         }
    2199             : 
    2200             :         /* Apply new settings. */
    2201           0 :         AR_SETBITS(sc, AR_PHY_RX_IQCAL_CORR_B(0),
    2202             :             AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE);
    2203           0 :         AR_WRITE_BARRIER(sc);
    2204             : 
    2205             :         /* IQ calibration done. */
    2206           0 :         sc->cur_calib_mask &= ~ATHN_CAL_IQ;
    2207           0 :         memset(&sc->calib, 0, sizeof(sc->calib));
    2208           0 : }
    2209             : 
    2210             : #define DELPT   32
    2211             : int
    2212           0 : ar9003_get_iq_corr(struct athn_softc *sc, int32_t res[6], int32_t coeff[2])
    2213             : {
    2214             : /* Sign-extends 12-bit value (assumes upper bits are zeroes). */
    2215             : #define SIGN_EXT(v)     (((v) ^ 0x800) - 0x800)
    2216             : #define SCALE           (1 << 15)
    2217             : #define SHIFT           (1 <<  8)
    2218           0 :         struct {
    2219             :                 int32_t m, p, c;
    2220             :         } val[2][2];
    2221           0 :         int32_t mag[2][2], phs[2][2], cos[2], sin[2];
    2222             :         int32_t min, max, div, f1, f2, f3, m, p, c;
    2223             :         int32_t txmag, txphs, rxmag, rxphs;
    2224             :         int32_t q_coff, i_coff;
    2225             :         int i, j;
    2226             : 
    2227             :         /* Extract our twelve signed 12-bit values from res[] array. */
    2228           0 :         val[0][0].m = res[0] & 0xfff;
    2229           0 :         val[0][0].p = (res[0] >> 12) & 0xfff;
    2230           0 :         val[0][0].c = ((res[0] >> 24) & 0xff) | (res[1] & 0xf) << 8;
    2231             : 
    2232           0 :         val[0][1].m = (res[1] >> 4) & 0xfff;
    2233           0 :         val[0][1].p = res[2] & 0xfff;
    2234           0 :         val[0][1].c = (res[2] >> 12) & 0xfff;
    2235             : 
    2236           0 :         val[1][0].m = ((res[2] >> 24) & 0xff) | (res[3] & 0xf) << 8;
    2237           0 :         val[1][0].p = (res[3] >> 4) & 0xfff;
    2238           0 :         val[1][0].c = res[4] & 0xfff;
    2239             : 
    2240           0 :         val[1][1].m = (res[4] >> 12) & 0xfff;
    2241           0 :         val[1][1].p = ((res[4] >> 24) & 0xff) | (res[5] & 0xf) << 8;
    2242           0 :         val[1][1].c = (res[5] >> 4) & 0xfff;
    2243             : 
    2244           0 :         for (i = 0; i < 2; i++) {
    2245           0 :                 for (j = 0; j < 2; j++) {
    2246           0 :                         m = SIGN_EXT(val[i][j].m);
    2247           0 :                         p = SIGN_EXT(val[i][j].p);
    2248           0 :                         c = SIGN_EXT(val[i][j].c);
    2249             : 
    2250           0 :                         if (p == 0)
    2251           0 :                                 return (1);     /* Prevent division by 0. */
    2252             : 
    2253           0 :                         mag[i][j] = (m * SCALE) / p;
    2254           0 :                         phs[i][j] = (c * SCALE) / p;
    2255             :                 }
    2256           0 :                 sin[i] = ((mag[i][0] - mag[i][1]) * SHIFT) / DELPT;
    2257           0 :                 cos[i] = ((phs[i][0] - phs[i][1]) * SHIFT) / DELPT;
    2258             :                 /* Find magnitude by approximation. */
    2259           0 :                 min = MIN(abs(sin[i]), abs(cos[i]));
    2260           0 :                 max = MAX(abs(sin[i]), abs(cos[i]));
    2261           0 :                 div = max - (max / 32) + (min / 8) + (min / 4);
    2262           0 :                 if (div == 0)
    2263           0 :                         return (1);     /* Prevent division by 0. */
    2264             :                 /* Normalize sin and cos by magnitude. */
    2265           0 :                 sin[i] = (sin[i] * SCALE) / div;
    2266           0 :                 cos[i] = (cos[i] * SCALE) / div;
    2267             :         }
    2268             : 
    2269             :         /* Compute IQ mismatch (solve 4x4 linear equation). */
    2270           0 :         f1 = cos[0] - cos[1];
    2271           0 :         f3 = sin[0] - sin[1];
    2272           0 :         f2 = (f1 * f1 + f3 * f3) / SCALE;
    2273           0 :         if (f2 == 0)
    2274           0 :                 return (1);     /* Prevent division by 0. */
    2275             : 
    2276             :         /* Compute Tx magnitude mismatch. */
    2277           0 :         txmag = (f1 * ( mag[0][0] - mag[1][0]) +
    2278           0 :                  f3 * ( phs[0][0] - phs[1][0])) / f2;
    2279             :         /* Compute Tx phase mismatch. */
    2280           0 :         txphs = (f3 * (-mag[0][0] + mag[1][0]) +
    2281           0 :                  f1 * ( phs[0][0] - phs[1][0])) / f2;
    2282             : 
    2283           0 :         if (txmag == SCALE)
    2284           0 :                 return (1);     /* Prevent division by 0. */
    2285             : 
    2286             :         /* Compute Rx magnitude mismatch. */
    2287           0 :         rxmag = mag[0][0] - (cos[0] * txmag + sin[0] * txphs) / SCALE;
    2288             :         /* Compute Rx phase mismatch. */
    2289           0 :         rxphs = phs[0][0] + (sin[0] * txmag - cos[0] * txphs) / SCALE;
    2290             : 
    2291           0 :         if (-rxmag == SCALE)
    2292           0 :                 return (1);     /* Prevent division by 0. */
    2293             : 
    2294           0 :         txmag = (txmag * SCALE) / (SCALE - txmag);
    2295           0 :         txphs = -txphs;
    2296             : 
    2297           0 :         q_coff = (txmag * 128) / SCALE;
    2298           0 :         if (q_coff < -63)
    2299           0 :                 q_coff = -63;
    2300           0 :         else if (q_coff > 63)
    2301           0 :                 q_coff = 63;
    2302           0 :         i_coff = (txphs * 256) / SCALE;
    2303           0 :         if (i_coff < -63)
    2304           0 :                 i_coff = -63;
    2305           0 :         else if (i_coff > 63)
    2306           0 :                 i_coff = 63;
    2307           0 :         coeff[0] = q_coff * 128 + i_coff;
    2308             : 
    2309           0 :         rxmag = (-rxmag * SCALE) / (SCALE + rxmag);
    2310           0 :         rxphs = -rxphs;
    2311             : 
    2312           0 :         q_coff = (rxmag * 128) / SCALE;
    2313           0 :         if (q_coff < -63)
    2314           0 :                 q_coff = -63;
    2315           0 :         else if (q_coff > 63)
    2316           0 :                 q_coff = 63;
    2317           0 :         i_coff = (rxphs * 256) / SCALE;
    2318           0 :         if (i_coff < -63)
    2319           0 :                 i_coff = -63;
    2320           0 :         else if (i_coff > 63)
    2321           0 :                 i_coff = 63;
    2322           0 :         coeff[1] = q_coff * 128 + i_coff;
    2323             : 
    2324           0 :         return (0);
    2325             : #undef SHIFT
    2326             : #undef SCALE
    2327             : #undef SIGN_EXT
    2328           0 : }
    2329             : 
    2330             : int
    2331           0 : ar9003_calib_tx_iq(struct athn_softc *sc)
    2332             : {
    2333             :         uint32_t reg;
    2334           0 :         int32_t res[6], coeff[2];
    2335             :         int i, j, ntries;
    2336             : 
    2337           0 :         reg = AR_READ(sc, AR_PHY_TX_IQCAL_CONTROL_1);
    2338           0 :         reg = RW(reg, AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT);
    2339           0 :         AR_WRITE(sc, AR_PHY_TX_IQCAL_CONTROL_1, reg);
    2340             : 
    2341             :         /* Start Tx IQ calibration. */
    2342           0 :         AR_SETBITS(sc, AR_PHY_TX_IQCAL_START, AR_PHY_TX_IQCAL_START_DO_CAL);
    2343             :         /* Wait for completion. */
    2344           0 :         for (ntries = 0; ntries < 10000; ntries++) {
    2345           0 :                 reg = AR_READ(sc, AR_PHY_TX_IQCAL_START);
    2346           0 :                 if (!(reg & AR_PHY_TX_IQCAL_START_DO_CAL))
    2347             :                         break;
    2348           0 :                 DELAY(10);
    2349             :         }
    2350           0 :         if (ntries == 10000)
    2351           0 :                 return (ETIMEDOUT);
    2352             : 
    2353           0 :         for (i = 0; i < sc->ntxchains; i++) {
    2354             :                 /* Read Tx IQ calibration status for this chain. */
    2355           0 :                 reg = AR_READ(sc, AR_PHY_TX_IQCAL_STATUS_B(i));
    2356           0 :                 if (reg & AR_PHY_TX_IQCAL_STATUS_FAILED)
    2357           0 :                         return (EIO);
    2358             :                 /*
    2359             :                  * Read Tx IQ calibration results for this chain.
    2360             :                  * This consists in twelve signed 12-bit values.
    2361             :                  */
    2362           0 :                 for (j = 0; j < 3; j++) {
    2363           0 :                         AR_CLRBITS(sc, AR_PHY_CHAN_INFO_MEMORY,
    2364             :                             AR_PHY_CHAN_INFO_TAB_S2_READ);
    2365           0 :                         reg = AR_READ(sc, AR_PHY_CHAN_INFO_TAB(i, j));
    2366           0 :                         res[j * 2 + 0] = reg;
    2367             : 
    2368           0 :                         AR_SETBITS(sc, AR_PHY_CHAN_INFO_MEMORY,
    2369             :                             AR_PHY_CHAN_INFO_TAB_S2_READ);
    2370           0 :                         reg = AR_READ(sc, AR_PHY_CHAN_INFO_TAB(i, j));
    2371           0 :                         res[j * 2 + 1] = reg & 0xffff;
    2372             :                 }
    2373             : 
    2374             :                 /* Compute Tx IQ correction. */
    2375           0 :                 if (ar9003_get_iq_corr(sc, res, coeff) != 0)
    2376           0 :                         return (EIO);
    2377             : 
    2378             :                 /* Write Tx IQ correction coefficients. */
    2379           0 :                 reg = AR_READ(sc, AR_PHY_TX_IQCAL_CORR_COEFF_01_B(i));
    2380           0 :                 reg = RW(reg, AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
    2381             :                     coeff[0]);
    2382           0 :                 AR_WRITE(sc, AR_PHY_TX_IQCAL_CORR_COEFF_01_B(i), reg);
    2383             : 
    2384           0 :                 reg = AR_READ(sc, AR_PHY_RX_IQCAL_CORR_B(i));
    2385           0 :                 reg = RW(reg, AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF,
    2386             :                     coeff[1] >> 7);
    2387           0 :                 reg = RW(reg, AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF,
    2388             :                     coeff[1]);
    2389           0 :                 AR_WRITE(sc, AR_PHY_RX_IQCAL_CORR_B(i), reg);
    2390           0 :                 AR_WRITE_BARRIER(sc);
    2391             :         }
    2392             : 
    2393             :         /* Enable Tx IQ correction. */
    2394           0 :         AR_SETBITS(sc, AR_PHY_TX_IQCAL_CONTROL_3,
    2395             :             AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN);
    2396           0 :         AR_SETBITS(sc, AR_PHY_RX_IQCAL_CORR_B(0),
    2397             :             AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN);
    2398           0 :         AR_WRITE_BARRIER(sc);
    2399           0 :         return (0);
    2400           0 : }
    2401             : #undef DELPT
    2402             : 
    2403             : /*-
    2404             :  * The power amplifier predistortion state machine works as follows:
    2405             :  * 1) Disable digital predistorters for all Tx chains
    2406             :  * 2) Repeat steps 3~7 for all Tx chains
    2407             :  * 3)   Force Tx gain to that of training signal
    2408             :  * 4)   Send training signal (asynchronous)
    2409             :  * 5)   Wait for training signal to complete (asynchronous)
    2410             :  * 6)   Read PA measurements (input power, output power, output phase)
    2411             :  * 7)   Compute the predistortion function that linearizes PA output
    2412             :  * 8) Write predistortion functions to hardware tables for all Tx chains
    2413             :  * 9) Enable digital predistorters for all Tx chains
    2414             :  */
    2415             : void
    2416           0 : ar9003_paprd_calib(struct athn_softc *sc, struct ieee80211_channel *c)
    2417             : {
    2418             :         static const int scaling[] = {
    2419             :                 261376, 248079, 233759, 220464,
    2420             :                 208194, 196949, 185706, 175487
    2421             :         };
    2422           0 :         struct athn_ops *ops = &sc->ops;
    2423           0 :         uint32_t reg, ht20mask, ht40mask;
    2424             :         int i;
    2425             : 
    2426             :         /* Read PA predistortion masks from ROM. */
    2427           0 :         ops->get_paprd_masks(sc, c, &ht20mask, &ht40mask);
    2428             : 
    2429             :         /* AM-to-AM: amplifier's amplitude characteristic. */
    2430           0 :         reg = AR_READ(sc, AR_PHY_PAPRD_AM2AM);
    2431           0 :         reg = RW(reg, AR_PHY_PAPRD_AM2AM_MASK, ht20mask);
    2432           0 :         AR_WRITE(sc, AR_PHY_PAPRD_AM2AM, reg);
    2433             : 
    2434             :         /* AM-to-PM: amplifier's phase transfer characteristic. */
    2435           0 :         reg = AR_READ(sc, AR_PHY_PAPRD_AM2PM);
    2436           0 :         reg = RW(reg, AR_PHY_PAPRD_AM2PM_MASK, ht20mask);
    2437           0 :         AR_WRITE(sc, AR_PHY_PAPRD_AM2PM, reg);
    2438             : 
    2439           0 :         reg = AR_READ(sc, AR_PHY_PAPRD_HT40);
    2440           0 :         reg = RW(reg, AR_PHY_PAPRD_HT40_MASK, ht40mask);
    2441           0 :         AR_WRITE(sc, AR_PHY_PAPRD_HT40, reg);
    2442             : 
    2443           0 :         for (i = 0; i < AR9003_MAX_CHAINS; i++) {
    2444           0 :                 AR_SETBITS(sc, AR_PHY_PAPRD_CTRL0_B(i),
    2445             :                     AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE);
    2446             : 
    2447           0 :                 reg = AR_READ(sc, AR_PHY_PAPRD_CTRL1_B(i));
    2448           0 :                 reg = RW(reg, AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT, 181);
    2449           0 :                 reg = RW(reg, AR_PHY_PAPRD_CTRL1_MAG_SCALE_FACT, 361);
    2450           0 :                 reg &= ~AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA;
    2451           0 :                 reg |= AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENA;
    2452           0 :                 reg |= AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENA;
    2453           0 :                 AR_WRITE(sc, AR_PHY_PAPRD_CTRL1_B(i), reg);
    2454             : 
    2455           0 :                 reg = AR_READ(sc, AR_PHY_PAPRD_CTRL0_B(i));
    2456           0 :                 reg = RW(reg, AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH, 3);
    2457           0 :                 AR_WRITE(sc, AR_PHY_PAPRD_CTRL0_B(i), reg);
    2458             :         }
    2459             : 
    2460             :         /* Disable all digital predistorters during calibration. */
    2461           0 :         for (i = 0; i < AR9003_MAX_CHAINS; i++) {
    2462           0 :                 AR_CLRBITS(sc, AR_PHY_PAPRD_CTRL0_B(i),
    2463             :                     AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE);
    2464             :         }
    2465           0 :         AR_WRITE_BARRIER(sc);
    2466             : 
    2467             :         /*
    2468             :          * Configure training signal.
    2469             :          */
    2470           0 :         reg = AR_READ(sc, AR_PHY_PAPRD_TRAINER_CNTL1);
    2471           0 :         reg = RW(reg, AR_PHY_PAPRD_TRAINER_CNTL1_AGC2_SETTLING, 28);
    2472           0 :         reg = RW(reg, AR_PHY_PAPRD_TRAINER_CNTL1_LB_SKIP, 0x30);
    2473           0 :         reg &= ~AR_PHY_PAPRD_TRAINER_CNTL1_RX_BB_GAIN_FORCE;
    2474           0 :         reg &= ~AR_PHY_PAPRD_TRAINER_CNTL1_IQCORR_ENABLE;
    2475           0 :         reg |= AR_PHY_PAPRD_TRAINER_CNTL1_LB_ENABLE;
    2476           0 :         reg |= AR_PHY_PAPRD_TRAINER_CNTL1_TX_GAIN_FORCE;
    2477           0 :         reg |= AR_PHY_PAPRD_TRAINER_CNTL1_TRAIN_ENABLE;
    2478           0 :         AR_WRITE(sc, AR_PHY_PAPRD_TRAINER_CNTL1, reg);
    2479             : 
    2480           0 :         AR_WRITE(sc, AR_PHY_PAPRD_TRAINER_CNTL2, 147);
    2481             : 
    2482           0 :         reg = AR_READ(sc, AR_PHY_PAPRD_TRAINER_CNTL3);
    2483           0 :         reg = RW(reg, AR_PHY_PAPRD_TRAINER_CNTL3_FINE_CORR_LEN, 4);
    2484           0 :         reg = RW(reg, AR_PHY_PAPRD_TRAINER_CNTL3_COARSE_CORR_LEN, 4);
    2485           0 :         reg = RW(reg, AR_PHY_PAPRD_TRAINER_CNTL3_NUM_CORR_STAGES, 7);
    2486           0 :         reg = RW(reg, AR_PHY_PAPRD_TRAINER_CNTL3_MIN_LOOPBACK_DEL, 1);
    2487           0 :         if (AR_SREV_9485(sc))
    2488           0 :                 reg = RW(reg, AR_PHY_PAPRD_TRAINER_CNTL3_QUICK_DROP, -3);
    2489             :         else
    2490           0 :                 reg = RW(reg, AR_PHY_PAPRD_TRAINER_CNTL3_QUICK_DROP, -6);
    2491           0 :         reg = RW(reg, AR_PHY_PAPRD_TRAINER_CNTL3_ADC_DESIRED_SIZE, -15);
    2492           0 :         reg |= AR_PHY_PAPRD_TRAINER_CNTL3_BBTXMIX_DISABLE;
    2493           0 :         AR_WRITE(sc, AR_PHY_PAPRD_TRAINER_CNTL3, reg);
    2494             : 
    2495           0 :         reg = AR_READ(sc, AR_PHY_PAPRD_TRAINER_CNTL4);
    2496           0 :         reg = RW(reg, AR_PHY_PAPRD_TRAINER_CNTL4_SAFETY_DELTA, 0);
    2497           0 :         reg = RW(reg, AR_PHY_PAPRD_TRAINER_CNTL4_MIN_CORR, 400);
    2498           0 :         reg = RW(reg, AR_PHY_PAPRD_TRAINER_CNTL4_NUM_TRAIN_SAMPLES, 100);
    2499           0 :         AR_WRITE(sc, AR_PHY_PAPRD_TRAINER_CNTL4, reg);
    2500             : 
    2501           0 :         for (i = 0; i < nitems(scaling); i++) {
    2502           0 :                 reg = AR_READ(sc, AR_PHY_PAPRD_PRE_POST_SCALE_B0(i));
    2503           0 :                 reg = RW(reg, AR_PHY_PAPRD_PRE_POST_SCALING, scaling[i]);
    2504           0 :                 AR_WRITE(sc, AR_PHY_PAPRD_PRE_POST_SCALE_B0(i), reg);
    2505             :         }
    2506             : 
    2507             :         /* Save Tx gain table. */
    2508           0 :         for (i = 0; i < AR9003_TX_GAIN_TABLE_SIZE; i++)
    2509           0 :                 sc->txgain[i] = AR_READ(sc, AR_PHY_TXGAIN_TABLE(i));
    2510             : 
    2511             :         /* Set Tx power of training signal (use setting for MCS0). */
    2512           0 :         sc->trainpow = MS(AR_READ(sc, AR_PHY_PWRTX_RATE5),
    2513           0 :             AR_PHY_PWRTX_RATE5_POWERTXHT20_0) - 4;
    2514             : 
    2515             :         /*
    2516             :          * Start PA predistortion calibration state machine.
    2517             :          */
    2518             :         /* Find first available Tx chain. */
    2519           0 :         sc->paprd_curchain = 0;
    2520           0 :         while (!(sc->txchainmask & (1 << sc->paprd_curchain)))
    2521           0 :                 sc->paprd_curchain++;
    2522             : 
    2523             :         /* Make sure training done bit is clear. */
    2524           0 :         AR_CLRBITS(sc, AR_PHY_PAPRD_TRAINER_STAT1,
    2525             :             AR_PHY_PAPRD_TRAINER_STAT1_TRAIN_DONE);
    2526           0 :         AR_WRITE_BARRIER(sc);
    2527             : 
    2528             :         /* Transmit training signal. */
    2529           0 :         ar9003_paprd_tx_tone(sc);
    2530           0 : }
    2531             : 
    2532             : int
    2533           0 : ar9003_get_desired_txgain(struct athn_softc *sc, int chain, int pow)
    2534             : {
    2535             :         int32_t scale, atemp, avolt, tempcal, voltcal, temp, volt;
    2536             :         int32_t tempcorr, voltcorr;
    2537             :         uint32_t reg;
    2538             :         int8_t delta;
    2539             : 
    2540           0 :         scale = MS(AR_READ(sc, AR_PHY_TPC_12),
    2541             :             AR_PHY_TPC_12_DESIRED_SCALE_HT40_5);
    2542             : 
    2543           0 :         reg = AR_READ(sc, AR_PHY_TPC_19);
    2544           0 :         atemp = MS(reg, AR_PHY_TPC_19_ALPHA_THERM);
    2545           0 :         avolt = MS(reg, AR_PHY_TPC_19_ALPHA_VOLT);
    2546             : 
    2547           0 :         reg = AR_READ(sc, AR_PHY_TPC_18);
    2548           0 :         tempcal = MS(reg, AR_PHY_TPC_18_THERM_CAL);
    2549           0 :         voltcal = MS(reg, AR_PHY_TPC_18_VOLT_CAL);
    2550             : 
    2551           0 :         reg = AR_READ(sc, AR_PHY_BB_THERM_ADC_4);
    2552           0 :         temp = MS(reg, AR_PHY_BB_THERM_ADC_4_LATEST_THERM);
    2553           0 :         volt = MS(reg, AR_PHY_BB_THERM_ADC_4_LATEST_VOLT);
    2554             : 
    2555           0 :         delta = (int8_t)MS(AR_READ(sc, AR_PHY_TPC_11_B(chain)),
    2556             :             AR_PHY_TPC_11_OLPC_GAIN_DELTA);
    2557             : 
    2558             :         /* Compute temperature and voltage correction. */
    2559           0 :         tempcorr = (atemp * (temp - tempcal) + 128) / 256;
    2560           0 :         voltcorr = (avolt * (volt - voltcal) + 64) / 128;
    2561             : 
    2562             :         /* Compute desired Tx gain. */
    2563           0 :         return (pow - delta - tempcorr - voltcorr + scale);
    2564             : }
    2565             : 
    2566             : void
    2567           0 : ar9003_force_txgain(struct athn_softc *sc, uint32_t txgain)
    2568             : {
    2569             :         uint32_t reg;
    2570             : 
    2571           0 :         reg = AR_READ(sc, AR_PHY_TX_FORCED_GAIN);
    2572           0 :         reg = RW(reg, AR_PHY_TX_FORCED_GAIN_TXBB1DBGAIN,
    2573             :             MS(txgain, AR_PHY_TXGAIN_TXBB1DBGAIN));
    2574           0 :         reg = RW(reg, AR_PHY_TX_FORCED_GAIN_TXBB6DBGAIN,
    2575             :             MS(txgain, AR_PHY_TXGAIN_TXBB6DBGAIN));
    2576           0 :         reg = RW(reg, AR_PHY_TX_FORCED_GAIN_TXMXRGAIN,
    2577             :             MS(txgain, AR_PHY_TXGAIN_TXMXRGAIN));
    2578           0 :         reg = RW(reg, AR_PHY_TX_FORCED_GAIN_PADRVGNA,
    2579             :             MS(txgain, AR_PHY_TXGAIN_PADRVGNA));
    2580           0 :         reg = RW(reg, AR_PHY_TX_FORCED_GAIN_PADRVGNB,
    2581             :             MS(txgain, AR_PHY_TXGAIN_PADRVGNB));
    2582           0 :         reg = RW(reg, AR_PHY_TX_FORCED_GAIN_PADRVGNC,
    2583             :             MS(txgain, AR_PHY_TXGAIN_PADRVGNC));
    2584           0 :         reg = RW(reg, AR_PHY_TX_FORCED_GAIN_PADRVGND,
    2585             :             MS(txgain, AR_PHY_TXGAIN_PADRVGND));
    2586           0 :         reg &= ~AR_PHY_TX_FORCED_GAIN_ENABLE_PAL;
    2587           0 :         reg &= ~AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN;
    2588           0 :         AR_WRITE(sc, AR_PHY_TX_FORCED_GAIN, reg);
    2589             : 
    2590           0 :         reg = AR_READ(sc, AR_PHY_TPC_1);
    2591           0 :         reg = RW(reg, AR_PHY_TPC_1_FORCED_DAC_GAIN, 0);
    2592           0 :         reg &= ~AR_PHY_TPC_1_FORCE_DAC_GAIN;
    2593           0 :         AR_WRITE(sc, AR_PHY_TPC_1, reg);
    2594           0 :         AR_WRITE_BARRIER(sc);
    2595           0 : }
    2596             : 
    2597             : void
    2598           0 : ar9003_set_training_gain(struct athn_softc *sc, int chain)
    2599             : {
    2600             :         int i, gain;
    2601             : 
    2602             :         /*
    2603             :          * Get desired gain for training signal power (take into account
    2604             :          * current temperature/voltage).
    2605             :          */
    2606           0 :         gain = ar9003_get_desired_txgain(sc, chain, sc->trainpow);
    2607             :         /* Find entry in table. */
    2608           0 :         for (i = 0; i < AR9003_TX_GAIN_TABLE_SIZE - 1; i++)
    2609           0 :                 if (MS(sc->txgain[i], AR_PHY_TXGAIN_INDEX) >= gain)
    2610             :                         break;
    2611           0 :         ar9003_force_txgain(sc, sc->txgain[i]);
    2612           0 : }
    2613             : 
    2614             : int
    2615           0 : ar9003_paprd_tx_tone(struct athn_softc *sc)
    2616             : {
    2617             : #define TONE_LEN        1800
    2618           0 :         struct ieee80211com *ic = &sc->sc_ic;
    2619             :         struct ieee80211_frame *wh;
    2620             :         struct ieee80211_node *ni;
    2621             :         struct mbuf *m;
    2622             :         int error;
    2623             : 
    2624             :         /* Build a Null (no data) frame of TONE_LEN bytes. */
    2625           0 :         m = MCLGETI(NULL, M_DONTWAIT, NULL, TONE_LEN);
    2626           0 :         if (m == NULL)
    2627           0 :                 return (ENOBUFS);
    2628           0 :         memset(mtod(m, caddr_t), 0, TONE_LEN);
    2629           0 :         wh = mtod(m, struct ieee80211_frame *);
    2630           0 :         wh->i_fc[0] = IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_NODATA;
    2631           0 :         wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
    2632           0 :         *(uint16_t *)wh->i_dur = htole16(10);        /* XXX */
    2633           0 :         IEEE80211_ADDR_COPY(wh->i_addr1, ic->ic_myaddr);
    2634           0 :         IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr);
    2635           0 :         IEEE80211_ADDR_COPY(wh->i_addr3, ic->ic_myaddr);
    2636           0 :         m->m_pkthdr.len = m->m_len = TONE_LEN;
    2637             : 
    2638             :         /* Set gain of training signal. */
    2639           0 :         ar9003_set_training_gain(sc, sc->paprd_curchain);
    2640             : 
    2641             :         /* Transmit training signal. */
    2642           0 :         ni = ieee80211_ref_node(ic->ic_bss);
    2643           0 :         if ((error = ar9003_tx(sc, m, ni, ATHN_TXFLAG_PAPRD)) != 0)
    2644           0 :                 ieee80211_release_node(ic, ni);
    2645           0 :         return (error);
    2646             : #undef TONE_LEN
    2647           0 : }
    2648             : 
    2649             : static __inline int
    2650           0 : get_scale(int val)
    2651             : {
    2652             :         int log = 0;
    2653             : 
    2654             :         /* Find the log base 2 (position of highest bit set). */
    2655           0 :         while (val >>= 1)
    2656           0 :                 log++;
    2657             : 
    2658           0 :         return ((log > 10) ? log - 10 : 0);
    2659             : }
    2660             : 
    2661             : /*
    2662             :  * Compute predistortion function to linearize power amplifier output based
    2663             :  * on feedback from training signal.
    2664             :  */
    2665             : int
    2666           0 : ar9003_compute_predistortion(struct athn_softc *sc, const uint32_t *lo,
    2667             :     const uint32_t *hi)
    2668             : {
    2669             : #define NBINS   23
    2670           0 :         int chain = sc->paprd_curchain;
    2671           0 :         int x[NBINS + 1], y[NBINS + 1], t[NBINS + 1];
    2672           0 :         int b1[NBINS + 1], b2[NBINS + 1], xtilde[NBINS + 1];
    2673             :         int nsamples, txsum, rxsum, rosum, maxidx;
    2674             :         int order, order5x, order5xrem, order3x, order3xrem, y5, y3;
    2675             :         int icept, G, I, L, M, angle, xnonlin, y2, y4, sumy2, sumy4;
    2676             :         int alpha, beta, scale, Qalpha, Qbeta, Qscale, Qx, Qb1, Qb2;
    2677             :         int tavg, ttilde, maxb1abs, maxb2abs, maxxtildeabs, in;
    2678             :         int tmp, i;
    2679             : 
    2680             :         /* Set values at origin. */
    2681           0 :         x[0] = y[0] = t[0] = 0;
    2682             : 
    2683             : #define SCALE   32
    2684             :         maxidx = 0;
    2685           0 :         for (i = 0; i < NBINS; i++) {
    2686           0 :                 nsamples = lo[i] & 0xffff;
    2687             :                 /* Skip bins that contain 16 or less samples. */
    2688           0 :                 if (nsamples <= 16) {
    2689           0 :                         x[i + 1] = y[i + 1] = t[i + 1] = 0;
    2690           0 :                         continue;
    2691             :                 }
    2692           0 :                 txsum = (hi[i] & 0x7ff) << 16 | lo[i] >> 16;
    2693           0 :                 rxsum = (lo[i + NBINS] & 0xffff) << 5 |
    2694           0 :                     ((hi[i] >> 11) & 0x1f);
    2695           0 :                 rosum = (hi[i + NBINS] & 0x7ff) << 16 | hi[i + NBINS] >> 16;
    2696             :                 /* Sign-extend 27-bit value. */
    2697           0 :                 rosum = (rosum ^ 0x4000000) - 0x4000000;
    2698             : 
    2699           0 :                 txsum *= SCALE;
    2700           0 :                 rxsum *= SCALE;
    2701           0 :                 rosum *= SCALE;
    2702             : 
    2703           0 :                 x[i + 1] = ((txsum + nsamples) / nsamples + SCALE) / SCALE;
    2704           0 :                 y[i + 1] = ((rxsum + nsamples) / nsamples + SCALE) / SCALE +
    2705           0 :                     SCALE * maxidx + SCALE / 2;
    2706           0 :                 t[i + 1] = (rosum + nsamples) / nsamples;
    2707           0 :                 maxidx++;
    2708           0 :         }
    2709             : #undef SCALE
    2710             : 
    2711             : #define SCALE_LOG       8
    2712             : #define SCALE           (1 << SCALE_LOG)
    2713           0 :         if (x[6] == x[3])
    2714           0 :                 return (1);     /* Prevent division by 0. */
    2715           0 :         G = ((y[6] - y[3]) * SCALE + (x[6] - x[3])) / (x[6] - x[3]);
    2716           0 :         if (G == 0)
    2717           0 :                 return (1);     /* Prevent division by 0. */
    2718             : 
    2719           0 :         sc->gain1[chain] = G;        /* Save low signal gain. */
    2720             : 
    2721             :         /* Find interception point. */
    2722           0 :         icept = (G * (x[0] - x[3]) + SCALE) / SCALE + y[3];
    2723           0 :         for (i = 0; i <= 3; i++) {
    2724           0 :                 y[i] = i * 32;
    2725           0 :                 x[i] = (y[i] * SCALE + G) / G;
    2726             :         }
    2727           0 :         for (i = 4; i <= maxidx; i++)
    2728           0 :                 y[i] -= icept;
    2729             : 
    2730           0 :         xnonlin = x[maxidx] - (y[maxidx] * SCALE + G) / G;
    2731           0 :         order = (xnonlin + y[maxidx]) / y[maxidx];
    2732           0 :         if (order == 0)
    2733           0 :                 M = 10;
    2734           0 :         else if (order == 1)
    2735           0 :                 M = 9;
    2736             :         else
    2737             :                 M = 8;
    2738             : 
    2739           0 :         I = (maxidx >= 16) ? 7 : maxidx / 2;
    2740           0 :         L = maxidx - I;
    2741             : 
    2742             :         sumy2 = sumy4 = y2 = y4 = 0;
    2743           0 :         for (i = 0; i <= L; i++) {
    2744           0 :                 if (y[i + I] == 0)
    2745           0 :                         return (1);     /* Prevent division by 0. */
    2746             : 
    2747           0 :                 xnonlin = x[i + I] - ((y[i + I] * SCALE) + G) / G;
    2748           0 :                 xtilde[i] = ((xnonlin << M) + y[i + I]) / y[i + I];
    2749           0 :                 xtilde[i] = ((xtilde[i] << M) + y[i + I]) / y[i + I];
    2750           0 :                 xtilde[i] = ((xtilde[i] << M) + y[i + I]) / y[i + I];
    2751             : 
    2752           0 :                 y2 = (y[i + I] * y[i + I] + SCALE * SCALE) / (SCALE * SCALE);
    2753             : 
    2754           0 :                 sumy2 += y2;
    2755           0 :                 sumy4 += y2 * y2;
    2756             : 
    2757           0 :                 b1[i] = y2 * (L + 1);
    2758           0 :                 b2[i] = y2;
    2759             :         }
    2760           0 :         for (i = 0; i <= L; i++) {
    2761           0 :                 b1[i] -= sumy2;
    2762           0 :                 b2[i] = sumy4 - sumy2 * b2[i];
    2763             :         }
    2764             : 
    2765             :         maxxtildeabs = maxb1abs = maxb2abs = 0;
    2766           0 :         for (i = 0; i <= L; i++) {
    2767           0 :                 tmp = abs(xtilde[i]);
    2768           0 :                 if (tmp > maxxtildeabs)
    2769           0 :                         maxxtildeabs = tmp;
    2770             : 
    2771           0 :                 tmp = abs(b1[i]);
    2772           0 :                 if (tmp > maxb1abs)
    2773           0 :                         maxb1abs = tmp;
    2774             : 
    2775           0 :                 tmp = abs(b2[i]);
    2776           0 :                 if (tmp > maxb2abs)
    2777           0 :                         maxb2abs = tmp;
    2778             :         }
    2779           0 :         Qx  = get_scale(maxxtildeabs);
    2780           0 :         Qb1 = get_scale(maxb1abs);
    2781           0 :         Qb2 = get_scale(maxb2abs);
    2782           0 :         for (i = 0; i <= L; i++) {
    2783           0 :                 xtilde[i] /= 1 << Qx;
    2784           0 :                 b1[i] /= 1 << Qb1;
    2785           0 :                 b2[i] /= 1 << Qb2;
    2786             :         }
    2787             : 
    2788             :         alpha = beta = 0;
    2789           0 :         for (i = 0; i <= L; i++) {
    2790           0 :                 alpha += b1[i] * xtilde[i];
    2791           0 :                 beta  += b2[i] * xtilde[i];
    2792             :         }
    2793             : 
    2794           0 :         scale = ((y4 / SCALE_LOG) * (L + 1) -
    2795           0 :                  (y2 / SCALE_LOG) * sumy2) * SCALE_LOG;
    2796             : 
    2797           0 :         Qscale = get_scale(abs(scale));
    2798           0 :         scale /= 1 << Qscale;
    2799           0 :         Qalpha = get_scale(abs(alpha));
    2800           0 :         alpha /= 1 << Qalpha;
    2801           0 :         Qbeta  = get_scale(abs(beta));
    2802           0 :         beta  /= 1 << Qbeta;
    2803             : 
    2804           0 :         order = 3 * M - Qx - Qb1 - Qbeta + 10 + Qscale;
    2805           0 :         order5x = 1 << (order / 5);
    2806           0 :         order5xrem = 1 << (order % 5);
    2807             : 
    2808           0 :         order = 3 * M - Qx - Qb2 - Qalpha + 10 + Qscale;
    2809           0 :         order3x = 1 << (order / 3);
    2810           0 :         order3xrem = 1 << (order % 3);
    2811             : 
    2812           0 :         for (i = 0; i < AR9003_PAPRD_MEM_TAB_SIZE; i++) {
    2813           0 :                 tmp = i * 32;
    2814             : 
    2815             :                 /* Fifth order. */
    2816           0 :                 y5 = ((beta * tmp) / 64) / order5x;
    2817           0 :                 y5 = (y5 * tmp) / order5x;
    2818           0 :                 y5 = (y5 * tmp) / order5x;
    2819           0 :                 y5 = (y5 * tmp) / order5x;
    2820           0 :                 y5 = (y5 * tmp) / order5x;
    2821           0 :                 y5 = y5 / order5xrem;
    2822             : 
    2823             :                 /* Third oder. */
    2824           0 :                 y3 = (alpha * tmp) / order3x;
    2825           0 :                 y3 = (y3 * tmp) / order3x;
    2826           0 :                 y3 = (y3 * tmp) / order3x;
    2827           0 :                 y3 = y3 / order3xrem;
    2828             : 
    2829           0 :                 in = y5 + y3 + (SCALE * tmp) / G;
    2830           0 :                 if (i >= 2 && in < sc->pa_in[chain][i - 1]) {
    2831           0 :                         in = sc->pa_in[chain][i - 1] +
    2832           0 :                             (sc->pa_in[chain][i - 1] -
    2833           0 :                              sc->pa_in[chain][i - 2]);
    2834           0 :                 }
    2835           0 :                 if (in > 1400)
    2836           0 :                         in = 1400;
    2837           0 :                 sc->pa_in[chain][i] = in;
    2838             :         }
    2839             : 
    2840             :         /* Compute average theta of first 5 bins (linear region). */
    2841             :         tavg = 0;
    2842           0 :         for (i = 1; i <= 5; i++)
    2843           0 :                 tavg += t[i];
    2844           0 :         tavg /= 5;
    2845           0 :         for (i = 1; i <= 5; i++)
    2846           0 :                 t[i] = 0;
    2847           0 :         for (i = 6; i <= maxidx; i++)
    2848           0 :                 t[i] -= tavg;
    2849             : 
    2850             :         alpha = beta = 0;
    2851           0 :         for (i = 0; i <= L; i++) {
    2852           0 :                 ttilde = ((t[i + I] << M) + y[i + I]) / y[i + I];
    2853           0 :                 ttilde = ((ttilde << M) +  y[i + I]) / y[i + I];
    2854           0 :                 ttilde = ((ttilde << M) +  y[i + I]) / y[i + I];
    2855             : 
    2856           0 :                 alpha += b2[i] * ttilde;
    2857           0 :                 beta  += b1[i] * ttilde;
    2858             :         }
    2859             : 
    2860           0 :         Qalpha = get_scale(abs(alpha));
    2861           0 :         alpha /= 1 << Qalpha;
    2862           0 :         Qbeta  = get_scale(abs(beta));
    2863           0 :         beta  /= 1 << Qbeta;
    2864             : 
    2865           0 :         order = 3 * M - Qx - Qb1 - Qbeta + 10 + Qscale + 5;
    2866           0 :         order5x = 1 << (order / 5);
    2867           0 :         order5xrem = 1 << (order % 5);
    2868             : 
    2869           0 :         order = 3 * M - Qx - Qb2 - Qalpha + 10 + Qscale + 5;
    2870           0 :         order3x = 1 << (order / 3);
    2871           0 :         order3xrem = 1 << (order % 3);
    2872             : 
    2873           0 :         for (i = 0; i <= 4; i++)
    2874           0 :                 sc->angle[chain][i] = 0;     /* Linear at that range. */
    2875           0 :         for (i = 5; i < AR9003_PAPRD_MEM_TAB_SIZE; i++) {
    2876           0 :                 tmp = i * 32;
    2877             : 
    2878             :                 /* Fifth order. */
    2879           0 :                 if (beta > 0)
    2880           0 :                         y5 = (((beta * tmp - 64) / 64) - order5x) / order5x;
    2881             :                 else
    2882           0 :                         y5 = (((beta * tmp - 64) / 64) + order5x) / order5x;
    2883           0 :                 y5 = (y5 * tmp) / order5x;
    2884           0 :                 y5 = (y5 * tmp) / order5x;
    2885           0 :                 y5 = (y5 * tmp) / order5x;
    2886           0 :                 y5 = (y5 * tmp) / order5x;
    2887           0 :                 y5 = y5 / order5xrem;
    2888             : 
    2889             :                 /* Third oder. */
    2890           0 :                 if (beta > 0)        /* XXX alpha? */
    2891           0 :                         y3 = (alpha * tmp - order3x) / order3x;
    2892             :                 else
    2893           0 :                         y3 = (alpha * tmp + order3x) / order3x;
    2894           0 :                 y3 = (y3 * tmp) / order3x;
    2895           0 :                 y3 = (y3 * tmp) / order3x;
    2896           0 :                 y3 = y3 / order3xrem;
    2897             : 
    2898           0 :                 angle = y5 + y3;
    2899           0 :                 if (angle < -150)
    2900           0 :                         angle = -150;
    2901           0 :                 else if (angle > 150)
    2902           0 :                         angle = 150;
    2903           0 :                 sc->angle[chain][i] = angle;
    2904             :         }
    2905             :         /* Angle for entry 4 is derived from angle for entry 5. */
    2906           0 :         sc->angle[chain][4] = (sc->angle[chain][5] + 2) / 2;
    2907             : 
    2908           0 :         return (0);
    2909             : #undef SCALE
    2910             : #undef SCALE_LOG
    2911             : #undef NBINS
    2912           0 : }
    2913             : 
    2914             : void
    2915           0 : ar9003_enable_predistorter(struct athn_softc *sc, int chain)
    2916             : {
    2917             :         uint32_t reg;
    2918             :         int i;
    2919             : 
    2920             :         /* Write digital predistorter lookup table. */
    2921           0 :         for (i = 0; i < AR9003_PAPRD_MEM_TAB_SIZE; i++) {
    2922           0 :                 AR_WRITE(sc, AR_PHY_PAPRD_MEM_TAB_B(chain, i),
    2923             :                     SM(AR_PHY_PAPRD_PA_IN, sc->pa_in[chain][i]) |
    2924             :                     SM(AR_PHY_PAPRD_ANGLE, sc->angle[chain][i]));
    2925             :         }
    2926             : 
    2927           0 :         reg = AR_READ(sc, AR_PHY_PA_GAIN123_B(chain));
    2928           0 :         reg = RW(reg, AR_PHY_PA_GAIN123_PA_GAIN1, sc->gain1[chain]);
    2929           0 :         AR_WRITE(sc, AR_PHY_PA_GAIN123_B(chain), reg);
    2930             : 
    2931             :         /* Indicate Tx power used for calibration (training signal). */
    2932           0 :         reg = AR_READ(sc, AR_PHY_PAPRD_CTRL1_B(chain));
    2933           0 :         reg = RW(reg, AR_PHY_PAPRD_CTRL1_POWER_AT_AM2AM_CAL, sc->trainpow);
    2934           0 :         AR_WRITE(sc, AR_PHY_PAPRD_CTRL1_B(chain), reg);
    2935             : 
    2936             :         /* Enable digital predistorter for this chain. */
    2937           0 :         AR_SETBITS(sc, AR_PHY_PAPRD_CTRL0_B(chain),
    2938             :             AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE);
    2939           0 :         AR_WRITE_BARRIER(sc);
    2940           0 : }
    2941             : 
    2942             : void
    2943           0 : ar9003_paprd_enable(struct athn_softc *sc)
    2944             : {
    2945             :         int i;
    2946             : 
    2947             :         /* Enable digital predistorters for all Tx chains. */
    2948           0 :         for (i = 0; i < AR9003_MAX_CHAINS; i++)
    2949           0 :                 if (sc->txchainmask & (1 << i))
    2950           0 :                         ar9003_enable_predistorter(sc, i);
    2951           0 : }
    2952             : 
    2953             : /*
    2954             :  * This function is called when our training signal has been sent.
    2955             :  */
    2956             : void
    2957           0 : ar9003_paprd_tx_tone_done(struct athn_softc *sc)
    2958             : {
    2959           0 :         uint32_t lo[48], hi[48];
    2960             :         int i;
    2961             : 
    2962             :         /* Make sure training is complete. */
    2963           0 :         if (!(AR_READ(sc, AR_PHY_PAPRD_TRAINER_STAT1) &
    2964             :             AR_PHY_PAPRD_TRAINER_STAT1_TRAIN_DONE))
    2965           0 :                 return;
    2966             : 
    2967             :         /* Read feedback from training signal. */
    2968           0 :         AR_CLRBITS(sc, AR_PHY_CHAN_INFO_MEMORY, AR_PHY_CHAN_INFO_TAB_S2_READ);
    2969           0 :         for (i = 0; i < nitems(lo); i++)
    2970           0 :                 lo[i] = AR_READ(sc, AR_PHY_CHAN_INFO_TAB(0, i));
    2971           0 :         AR_SETBITS(sc, AR_PHY_CHAN_INFO_MEMORY, AR_PHY_CHAN_INFO_TAB_S2_READ);
    2972           0 :         for (i = 0; i < nitems(hi); i++)
    2973           0 :                 hi[i] = AR_READ(sc, AR_PHY_CHAN_INFO_TAB(0, i));
    2974             : 
    2975           0 :         AR_CLRBITS(sc, AR_PHY_PAPRD_TRAINER_STAT1,
    2976             :             AR_PHY_PAPRD_TRAINER_STAT1_TRAIN_DONE);
    2977             : 
    2978             :         /* Compute predistortion function based on this feedback. */
    2979           0 :         if (ar9003_compute_predistortion(sc, lo, hi) != 0)
    2980           0 :                 return;
    2981             : 
    2982             :         /* Get next available Tx chain. */
    2983           0 :         while (++sc->paprd_curchain < AR9003_MAX_CHAINS)
    2984           0 :                 if (sc->txchainmask & (1 << sc->paprd_curchain))
    2985             :                         break;
    2986           0 :         if (sc->paprd_curchain == AR9003_MAX_CHAINS) {
    2987             :                 /* All Tx chains measured; enable digital predistortion. */
    2988           0 :                 ar9003_paprd_enable(sc);
    2989           0 :         } else  /* Measure next Tx chain. */
    2990           0 :                 ar9003_paprd_tx_tone(sc);
    2991           0 : }
    2992             : 
    2993             : void
    2994           0 : ar9003_write_txpower(struct athn_softc *sc, int16_t power[ATHN_POWER_COUNT])
    2995             : {
    2996             :         /* Make sure forced gain is disabled. */
    2997           0 :         AR_WRITE(sc, AR_PHY_TX_FORCED_GAIN, 0);
    2998             : 
    2999           0 :         AR_WRITE(sc, AR_PHY_PWRTX_RATE1,
    3000             :             (power[ATHN_POWER_OFDM18  ] & 0x3f) << 24 |
    3001             :             (power[ATHN_POWER_OFDM12  ] & 0x3f) << 16 |
    3002             :             (power[ATHN_POWER_OFDM9   ] & 0x3f) <<  8 |
    3003             :             (power[ATHN_POWER_OFDM6   ] & 0x3f));
    3004           0 :         AR_WRITE(sc, AR_PHY_PWRTX_RATE2,
    3005             :             (power[ATHN_POWER_OFDM54  ] & 0x3f) << 24 |
    3006             :             (power[ATHN_POWER_OFDM48  ] & 0x3f) << 16 |
    3007             :             (power[ATHN_POWER_OFDM36  ] & 0x3f) <<  8 |
    3008             :             (power[ATHN_POWER_OFDM24  ] & 0x3f));
    3009           0 :         AR_WRITE(sc, AR_PHY_PWRTX_RATE3,
    3010             :             (power[ATHN_POWER_CCK2_SP ] & 0x3f) << 24 |
    3011             :             (power[ATHN_POWER_CCK2_LP ] & 0x3f) << 16 |
    3012             :             /* NB: No eXtended Range for AR9003. */
    3013             :             (power[ATHN_POWER_CCK1_LP ] & 0x3f));
    3014           0 :         AR_WRITE(sc, AR_PHY_PWRTX_RATE4,
    3015             :             (power[ATHN_POWER_CCK11_SP] & 0x3f) << 24 |
    3016             :             (power[ATHN_POWER_CCK11_LP] & 0x3f) << 16 |
    3017             :             (power[ATHN_POWER_CCK55_SP] & 0x3f) <<  8 |
    3018             :             (power[ATHN_POWER_CCK55_LP] & 0x3f));
    3019             :         /*
    3020             :          * NB: AR_PHY_PWRTX_RATE5 needs to be written even if HT is disabled
    3021             :          * because it is read by PA predistortion functions.
    3022             :          */
    3023           0 :         AR_WRITE(sc, AR_PHY_PWRTX_RATE5,
    3024             :             (power[ATHN_POWER_HT20( 5)] & 0x3f) << 24 |
    3025             :             (power[ATHN_POWER_HT20( 4)] & 0x3f) << 16 |
    3026             :             (power[ATHN_POWER_HT20( 1)] & 0x3f) <<  8 |
    3027             :             (power[ATHN_POWER_HT20( 0)] & 0x3f));
    3028           0 :         AR_WRITE(sc, AR_PHY_PWRTX_RATE6,
    3029             :             (power[ATHN_POWER_HT20(13)] & 0x3f) << 24 |
    3030             :             (power[ATHN_POWER_HT20(12)] & 0x3f) << 16 |
    3031             :             (power[ATHN_POWER_HT20( 7)] & 0x3f) <<  8 |
    3032             :             (power[ATHN_POWER_HT20( 6)] & 0x3f));
    3033           0 :         AR_WRITE(sc, AR_PHY_PWRTX_RATE7,
    3034             :             (power[ATHN_POWER_HT40( 5)] & 0x3f) << 24 |
    3035             :             (power[ATHN_POWER_HT40( 4)] & 0x3f) << 16 |
    3036             :             (power[ATHN_POWER_HT40( 1)] & 0x3f) <<  8 |
    3037             :             (power[ATHN_POWER_HT40( 0)] & 0x3f));
    3038           0 :         AR_WRITE(sc, AR_PHY_PWRTX_RATE8,
    3039             :             (power[ATHN_POWER_HT40(13)] & 0x3f) << 24 |
    3040             :             (power[ATHN_POWER_HT40(12)] & 0x3f) << 16 |
    3041             :             (power[ATHN_POWER_HT40( 7)] & 0x3f) <<  8 |
    3042             :             (power[ATHN_POWER_HT40( 6)] & 0x3f));
    3043           0 :         AR_WRITE(sc, AR_PHY_PWRTX_RATE10,
    3044             :             (power[ATHN_POWER_HT20(21)] & 0x3f) << 24 |
    3045             :             (power[ATHN_POWER_HT20(20)] & 0x3f) << 16 |
    3046             :             (power[ATHN_POWER_HT20(15)] & 0x3f) <<  8 |
    3047             :             (power[ATHN_POWER_HT20(14)] & 0x3f));
    3048           0 :         AR_WRITE(sc, AR_PHY_PWRTX_RATE11,
    3049             :             (power[ATHN_POWER_HT40(23)] & 0x3f) << 24 |
    3050             :             (power[ATHN_POWER_HT40(22)] & 0x3f) << 16 |
    3051             :             (power[ATHN_POWER_HT20(23)] & 0x3f) <<  8 |
    3052             :             (power[ATHN_POWER_HT20(22)] & 0x3f));
    3053           0 :         AR_WRITE(sc, AR_PHY_PWRTX_RATE12,
    3054             :             (power[ATHN_POWER_HT40(21)] & 0x3f) << 24 |
    3055             :             (power[ATHN_POWER_HT40(20)] & 0x3f) << 16 |
    3056             :             (power[ATHN_POWER_HT40(15)] & 0x3f) <<  8 |
    3057             :             (power[ATHN_POWER_HT40(14)] & 0x3f));
    3058           0 :         AR_WRITE_BARRIER(sc);
    3059           0 : }
    3060             : 
    3061             : void
    3062           0 : ar9003_reset_rx_gain(struct athn_softc *sc, struct ieee80211_channel *c)
    3063             : {
    3064             : #define X(x)    ((uint32_t)(x) << 2)
    3065           0 :         const struct athn_gain *prog = sc->rx_gain;
    3066             :         const uint32_t *pvals;
    3067             :         int i;
    3068             : 
    3069           0 :         if (IEEE80211_IS_CHAN_2GHZ(c))
    3070           0 :                 pvals = prog->vals_2g;
    3071             :         else
    3072           0 :                 pvals = prog->vals_5g;
    3073           0 :         for (i = 0; i < prog->nregs; i++)
    3074           0 :                 AR_WRITE(sc, X(prog->regs[i]), pvals[i]);
    3075           0 :         AR_WRITE_BARRIER(sc);
    3076             : #undef X
    3077           0 : }
    3078             : 
    3079             : void
    3080           0 : ar9003_reset_tx_gain(struct athn_softc *sc, struct ieee80211_channel *c)
    3081             : {
    3082             : #define X(x)    ((uint32_t)(x) << 2)
    3083           0 :         const struct athn_gain *prog = sc->tx_gain;
    3084             :         const uint32_t *pvals;
    3085             :         int i;
    3086             : 
    3087           0 :         if (IEEE80211_IS_CHAN_2GHZ(c))
    3088           0 :                 pvals = prog->vals_2g;
    3089             :         else
    3090           0 :                 pvals = prog->vals_5g;
    3091           0 :         for (i = 0; i < prog->nregs; i++)
    3092           0 :                 AR_WRITE(sc, X(prog->regs[i]), pvals[i]);
    3093           0 :         AR_WRITE_BARRIER(sc);
    3094             : #undef X
    3095           0 : }
    3096             : 
    3097             : void
    3098           0 : ar9003_hw_init(struct athn_softc *sc, struct ieee80211_channel *c,
    3099             :     struct ieee80211_channel *extc)
    3100             : {
    3101             : #define X(x)    ((uint32_t)(x) << 2)
    3102           0 :         struct athn_ops *ops = &sc->ops;
    3103           0 :         const struct athn_ini *ini = sc->ini;
    3104             :         const uint32_t *pvals;
    3105             :         uint32_t reg;
    3106             :         int i;
    3107             : 
    3108             :         /*
    3109             :          * The common init values include the pre and core phases for the
    3110             :          * SoC, MAC, BB and Radio subsystems.
    3111             :          */
    3112             :         DPRINTFN(4, ("writing pre and core init vals\n"));
    3113           0 :         for (i = 0; i < ini->ncmregs; i++) {
    3114           0 :                 AR_WRITE(sc, X(ini->cmregs[i]), ini->cmvals[i]);
    3115           0 :                 if (AR_IS_ANALOG_REG(X(ini->cmregs[i])))
    3116           0 :                         DELAY(100);
    3117           0 :                 if ((i & 0x1f) == 0)
    3118           0 :                         DELAY(1);
    3119             :         }
    3120             : 
    3121             :         /*
    3122             :          * The modal init values include the post phase for the SoC, MAC,
    3123             :          * BB and Radio subsystems.
    3124             :          */
    3125           0 :         if (extc != NULL) {
    3126           0 :                 if (IEEE80211_IS_CHAN_2GHZ(c))
    3127           0 :                         pvals = ini->vals_2g40;
    3128             :                 else
    3129           0 :                         pvals = ini->vals_5g40;
    3130             :         } else {
    3131           0 :                 if (IEEE80211_IS_CHAN_2GHZ(c))
    3132           0 :                         pvals = ini->vals_2g20;
    3133             :                 else
    3134           0 :                         pvals = ini->vals_5g20;
    3135             :         }
    3136             :         DPRINTFN(4, ("writing post init vals\n"));
    3137           0 :         for (i = 0; i < ini->nregs; i++) {
    3138           0 :                 AR_WRITE(sc, X(ini->regs[i]), pvals[i]);
    3139           0 :                 if (AR_IS_ANALOG_REG(X(ini->regs[i])))
    3140           0 :                         DELAY(100);
    3141           0 :                 if ((i & 0x1f) == 0)
    3142           0 :                         DELAY(1);
    3143             :         }
    3144             : 
    3145           0 :         if (sc->rx_gain != NULL)
    3146           0 :                 ar9003_reset_rx_gain(sc, c);
    3147           0 :         if (sc->tx_gain != NULL)
    3148           0 :                 ar9003_reset_tx_gain(sc, c);
    3149             : 
    3150           0 :         if (IEEE80211_IS_CHAN_5GHZ(c) &&
    3151           0 :             (sc->flags & ATHN_FLAG_FAST_PLL_CLOCK)) {
    3152             :                 /* Update modal values for fast PLL clock. */
    3153           0 :                 if (extc != NULL)
    3154           0 :                         pvals = ini->fastvals_5g40;
    3155             :                 else
    3156           0 :                         pvals = ini->fastvals_5g20;
    3157             :                 DPRINTFN(4, ("writing fast pll clock init vals\n"));
    3158           0 :                 for (i = 0; i < ini->nfastregs; i++) {
    3159           0 :                         AR_WRITE(sc, X(ini->fastregs[i]), pvals[i]);
    3160           0 :                         if (AR_IS_ANALOG_REG(X(ini->fastregs[i])))
    3161           0 :                                 DELAY(100);
    3162           0 :                         if ((i & 0x1f) == 0)
    3163           0 :                                 DELAY(1);
    3164             :                 }
    3165             :         }
    3166             : 
    3167             :         /*
    3168             :          * Set the RX_ABORT and RX_DIS bits to prevent frames with corrupted
    3169             :          * descriptor status.
    3170             :          */
    3171           0 :         AR_SETBITS(sc, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT);
    3172             : 
    3173           0 :         reg = AR_READ(sc, AR_PCU_MISC_MODE2);
    3174           0 :         reg &= ~AR_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE;
    3175           0 :         reg |= AR_PCU_MISC_MODE2_AGG_WEP_ENABLE_FIX;
    3176           0 :         reg |= AR_PCU_MISC_MODE2_ENABLE_AGGWEP;
    3177           0 :         AR_WRITE(sc, AR_PCU_MISC_MODE2, reg);
    3178           0 :         AR_WRITE_BARRIER(sc);
    3179             : 
    3180           0 :         ar9003_set_phy(sc, c, extc);
    3181           0 :         ar9003_init_chains(sc);
    3182             : 
    3183           0 :         ops->set_txpower(sc, c, extc);
    3184             : #undef X
    3185           0 : }
    3186             : 
    3187             : void
    3188           0 : ar9003_get_lg_tpow(struct athn_softc *sc, struct ieee80211_channel *c,
    3189             :     uint8_t ctl, const uint8_t *fbins,
    3190             :     const struct ar_cal_target_power_leg *tgt, int nchans, uint8_t tpow[4])
    3191             : {
    3192             :         uint8_t fbin;
    3193             :         int i, delta, lo, hi;
    3194             : 
    3195             :         lo = hi = -1;
    3196           0 :         fbin = athn_chan2fbin(c);
    3197           0 :         for (i = 0; i < nchans; i++) {
    3198           0 :                 delta = fbin - fbins[i];
    3199             :                 /* Find the largest sample that is <= our frequency. */
    3200           0 :                 if (delta >= 0 && (lo == -1 || delta < fbin - fbins[lo]))
    3201           0 :                         lo = i;
    3202             :                 /* Find the smallest sample that is >= our frequency. */
    3203           0 :                 if (delta <= 0 && (hi == -1 || delta > fbin - fbins[hi]))
    3204           0 :                         hi = i;
    3205             :         }
    3206           0 :         if (lo == -1)
    3207           0 :                 lo = hi;
    3208           0 :         else if (hi == -1)
    3209           0 :                 hi = lo;
    3210             :         /* Interpolate values. */
    3211           0 :         for (i = 0; i < 4; i++) {
    3212           0 :                 tpow[i] = athn_interpolate(fbin,
    3213           0 :                     fbins[lo], tgt[lo].tPow2x[i],
    3214           0 :                     fbins[hi], tgt[hi].tPow2x[i]);
    3215             :         }
    3216             :         /* XXX Apply conformance test limit. */
    3217           0 : }
    3218             : 
    3219             : void
    3220           0 : ar9003_get_ht_tpow(struct athn_softc *sc, struct ieee80211_channel *c,
    3221             :     uint8_t ctl, const uint8_t *fbins,
    3222             :     const struct ar_cal_target_power_ht *tgt, int nchans, uint8_t tpow[14])
    3223             : {
    3224             :         uint8_t fbin;
    3225             :         int i, delta, lo, hi;
    3226             : 
    3227             :         lo = hi = -1;
    3228           0 :         fbin = athn_chan2fbin(c);
    3229           0 :         for (i = 0; i < nchans; i++) {
    3230           0 :                 delta = fbin - fbins[i];
    3231             :                 /* Find the largest sample that is <= our frequency. */
    3232           0 :                 if (delta >= 0 && (lo == -1 || delta < fbin - fbins[lo]))
    3233           0 :                         lo = i;
    3234             :                 /* Find the smallest sample that is >= our frequency. */
    3235           0 :                 if (delta <= 0 && (hi == -1 || delta > fbin - fbins[hi]))
    3236           0 :                         hi = i;
    3237             :         }
    3238           0 :         if (lo == -1)
    3239           0 :                 lo = hi;
    3240           0 :         else if (hi == -1)
    3241           0 :                 hi = lo;
    3242             :         /* Interpolate values. */
    3243           0 :         for (i = 0; i < 14; i++) {
    3244           0 :                 tpow[i] = athn_interpolate(fbin,
    3245           0 :                     fbins[lo], tgt[lo].tPow2x[i],
    3246           0 :                     fbins[hi], tgt[hi].tPow2x[i]);
    3247             :         }
    3248             :         /* XXX Apply conformance test limit. */
    3249           0 : }
    3250             : 
    3251             : /*
    3252             :  * Adaptive noise immunity.
    3253             :  */
    3254             : void
    3255           0 : ar9003_set_noise_immunity_level(struct athn_softc *sc, int level)
    3256             : {
    3257           0 :         int high = level == 4;
    3258             :         uint32_t reg;
    3259             : 
    3260           0 :         reg = AR_READ(sc, AR_PHY_DESIRED_SZ);
    3261           0 :         reg = RW(reg, AR_PHY_DESIRED_SZ_TOT_DES, high ? -62 : -55);
    3262           0 :         AR_WRITE(sc, AR_PHY_DESIRED_SZ, reg);
    3263             : 
    3264           0 :         reg = AR_READ(sc, AR_PHY_AGC);
    3265           0 :         reg = RW(reg, AR_PHY_AGC_COARSE_LOW, high ? -70 : -64);
    3266           0 :         reg = RW(reg, AR_PHY_AGC_COARSE_HIGH, high ? -12 : -14);
    3267           0 :         AR_WRITE(sc, AR_PHY_AGC, reg);
    3268             : 
    3269           0 :         reg = AR_READ(sc, AR_PHY_FIND_SIG);
    3270           0 :         reg = RW(reg, AR_PHY_FIND_SIG_FIRPWR, high ? -80 : -78);
    3271           0 :         AR_WRITE(sc, AR_PHY_FIND_SIG, reg);
    3272           0 :         AR_WRITE_BARRIER(sc);
    3273           0 : }
    3274             : 
    3275             : void
    3276           0 : ar9003_enable_ofdm_weak_signal(struct athn_softc *sc)
    3277             : {
    3278             :         uint32_t reg;
    3279             : 
    3280           0 :         reg = AR_READ(sc, AR_PHY_SFCORR_LOW);
    3281           0 :         reg = RW(reg, AR_PHY_SFCORR_LOW_M1_THRESH_LOW, 50);
    3282           0 :         reg = RW(reg, AR_PHY_SFCORR_LOW_M2_THRESH_LOW, 40);
    3283           0 :         reg = RW(reg, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, 48);
    3284           0 :         AR_WRITE(sc, AR_PHY_SFCORR_LOW, reg);
    3285             : 
    3286           0 :         reg = AR_READ(sc, AR_PHY_SFCORR);
    3287           0 :         reg = RW(reg, AR_PHY_SFCORR_M1_THRESH, 77);
    3288           0 :         reg = RW(reg, AR_PHY_SFCORR_M2_THRESH, 64);
    3289           0 :         reg = RW(reg, AR_PHY_SFCORR_M2COUNT_THR, 16);
    3290           0 :         AR_WRITE(sc, AR_PHY_SFCORR, reg);
    3291             : 
    3292           0 :         reg = AR_READ(sc, AR_PHY_SFCORR_EXT);
    3293           0 :         reg = RW(reg, AR_PHY_SFCORR_EXT_M1_THRESH_LOW, 50);
    3294           0 :         reg = RW(reg, AR_PHY_SFCORR_EXT_M2_THRESH_LOW, 40);
    3295           0 :         reg = RW(reg, AR_PHY_SFCORR_EXT_M1_THRESH, 77);
    3296           0 :         reg = RW(reg, AR_PHY_SFCORR_EXT_M2_THRESH, 64);
    3297           0 :         AR_WRITE(sc, AR_PHY_SFCORR_EXT, reg);
    3298             : 
    3299           0 :         AR_SETBITS(sc, AR_PHY_SFCORR_LOW,
    3300             :             AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
    3301           0 :         AR_WRITE_BARRIER(sc);
    3302           0 : }
    3303             : 
    3304             : void
    3305           0 : ar9003_disable_ofdm_weak_signal(struct athn_softc *sc)
    3306             : {
    3307             :         uint32_t reg;
    3308             : 
    3309           0 :         reg = AR_READ(sc, AR_PHY_SFCORR_LOW);
    3310           0 :         reg = RW(reg, AR_PHY_SFCORR_LOW_M1_THRESH_LOW, 127);
    3311           0 :         reg = RW(reg, AR_PHY_SFCORR_LOW_M2_THRESH_LOW, 127);
    3312           0 :         reg = RW(reg, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, 63);
    3313           0 :         AR_WRITE(sc, AR_PHY_SFCORR_LOW, reg);
    3314             : 
    3315           0 :         reg = AR_READ(sc, AR_PHY_SFCORR);
    3316           0 :         reg = RW(reg, AR_PHY_SFCORR_M1_THRESH, 127);
    3317           0 :         reg = RW(reg, AR_PHY_SFCORR_M2_THRESH, 127);
    3318           0 :         reg = RW(reg, AR_PHY_SFCORR_M2COUNT_THR, 31);
    3319           0 :         AR_WRITE(sc, AR_PHY_SFCORR, reg);
    3320             : 
    3321           0 :         reg = AR_READ(sc, AR_PHY_SFCORR_EXT);
    3322           0 :         reg = RW(reg, AR_PHY_SFCORR_EXT_M1_THRESH_LOW, 127);
    3323           0 :         reg = RW(reg, AR_PHY_SFCORR_EXT_M2_THRESH_LOW, 127);
    3324           0 :         reg = RW(reg, AR_PHY_SFCORR_EXT_M1_THRESH, 127);
    3325           0 :         reg = RW(reg, AR_PHY_SFCORR_EXT_M2_THRESH, 127);
    3326           0 :         AR_WRITE(sc, AR_PHY_SFCORR_EXT, reg);
    3327             : 
    3328           0 :         AR_CLRBITS(sc, AR_PHY_SFCORR_LOW,
    3329             :             AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
    3330           0 :         AR_WRITE_BARRIER(sc);
    3331           0 : }
    3332             : 
    3333             : void
    3334           0 : ar9003_set_cck_weak_signal(struct athn_softc *sc, int high)
    3335             : {
    3336             :         uint32_t reg;
    3337             : 
    3338           0 :         reg = AR_READ(sc, AR_PHY_CCK_DETECT);
    3339           0 :         reg = RW(reg, AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK, high ? 6 : 8);
    3340           0 :         AR_WRITE(sc, AR_PHY_CCK_DETECT, reg);
    3341           0 :         AR_WRITE_BARRIER(sc);
    3342           0 : }
    3343             : 
    3344             : void
    3345           0 : ar9003_set_firstep_level(struct athn_softc *sc, int level)
    3346             : {
    3347             :         uint32_t reg;
    3348             : 
    3349           0 :         reg = AR_READ(sc, AR_PHY_FIND_SIG);
    3350           0 :         reg = RW(reg, AR_PHY_FIND_SIG_FIRSTEP, level * 4);
    3351           0 :         AR_WRITE(sc, AR_PHY_FIND_SIG, reg);
    3352           0 :         AR_WRITE_BARRIER(sc);
    3353           0 : }
    3354             : 
    3355             : void
    3356           0 : ar9003_set_spur_immunity_level(struct athn_softc *sc, int level)
    3357             : {
    3358             :         uint32_t reg;
    3359             : 
    3360           0 :         reg = AR_READ(sc, AR_PHY_TIMING5);
    3361           0 :         reg = RW(reg, AR_PHY_TIMING5_CYCPWR_THR1, (level + 1) * 2);
    3362           0 :         AR_WRITE(sc, AR_PHY_TIMING5, reg);
    3363           0 :         AR_WRITE_BARRIER(sc);
    3364           0 : }

Generated by: LCOV version 1.13