[BACK]Return to ar5xxx.c CVS log [TXT][DIR] Up to [local] / sys / dev / ic

Annotation of sys/dev/ic/ar5xxx.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: ar5xxx.c,v 1.42 2007/06/26 10:53:01 tom Exp $ */
                      2:
                      3: /*
                      4:  * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org>
                      5:  *
                      6:  * Permission to use, copy, modify, and distribute this software for any
                      7:  * purpose with or without fee is hereby granted, provided that the above
                      8:  * copyright notice and this permission notice appear in all copies.
                      9:  *
                     10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     14:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     15:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     16:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     17:  */
                     18:
                     19: /*
                     20:  * HAL interface for Atheros Wireless LAN devices.
                     21:  * (Please have a look at ar5xxx.h for further information)
                     22:  */
                     23:
                     24: #include <dev/pci/pcidevs.h>
                     25: #include <dev/ic/ar5xxx.h>
                     26:
                     27: extern ar5k_attach_t ar5k_ar5210_attach;
                     28: extern ar5k_attach_t ar5k_ar5211_attach;
                     29: extern ar5k_attach_t ar5k_ar5212_attach;
                     30:
                     31: static const struct {
                     32:        u_int16_t       vendor;
                     33:        u_int16_t       device;
                     34:        ar5k_attach_t   (*attach);
                     35: } ar5k_known_products[] = {
                     36:        /*
                     37:         * From pcidevs_data.h
                     38:         */
                     39:        { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5210,
                     40:            ar5k_ar5210_attach },
                     41:        { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5210_AP,
                     42:            ar5k_ar5210_attach },
                     43:        { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5210_DEFAULT,
                     44:            ar5k_ar5210_attach },
                     45:        { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5211,
                     46:            ar5k_ar5211_attach },
                     47:        { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5211_DEFAULT,
                     48:            ar5k_ar5211_attach },
                     49:        { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5311,
                     50:            ar5k_ar5211_attach },
                     51:        { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5211_FPGA11B,
                     52:            ar5k_ar5211_attach },
                     53:        { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5211_LEGACY,
                     54:            ar5k_ar5211_attach },
                     55:        { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212,
                     56:            ar5k_ar5212_attach },
                     57:        { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_DEFAULT,
                     58:            ar5k_ar5212_attach },
                     59:        { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_FPGA,
                     60:            ar5k_ar5212_attach },
                     61:        { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_IBM,
                     62:            ar5k_ar5212_attach },
                     63:        { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR2413,
                     64:            ar5k_ar5212_attach },
                     65:        { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5413,
                     66:            ar5k_ar5212_attach },
                     67:        { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5424,
                     68:            ar5k_ar5212_attach },
                     69:        { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3CRDAG675,
                     70:            ar5k_ar5212_attach },
                     71:        { PCI_VENDOR_3COM2, PCI_PRODUCT_3COM2_3CRPAG175,
                     72:            ar5k_ar5212_attach }
                     73: };
                     74:
                     75: static const HAL_RATE_TABLE ar5k_rt_11a = AR5K_RATES_11A;
                     76: static const HAL_RATE_TABLE ar5k_rt_11b = AR5K_RATES_11B;
                     77: static const HAL_RATE_TABLE ar5k_rt_11g = AR5K_RATES_11G;
                     78: static const HAL_RATE_TABLE ar5k_rt_turbo = AR5K_RATES_TURBO;
                     79: static const HAL_RATE_TABLE ar5k_rt_xr = AR5K_RATES_XR;
                     80:
                     81: int             ar5k_eeprom_read_ants(struct ath_hal *, u_int32_t *, u_int);
                     82: int             ar5k_eeprom_read_modes(struct ath_hal *, u_int32_t *, u_int);
                     83: u_int16_t       ar5k_eeprom_bin2freq(struct ath_hal *, u_int16_t, u_int);
                     84:
                     85: HAL_BOOL        ar5k_ar5110_channel(struct ath_hal *, HAL_CHANNEL *);
                     86: u_int32_t       ar5k_ar5110_chan2athchan(HAL_CHANNEL *);
                     87: HAL_BOOL        ar5k_ar5111_channel(struct ath_hal *, HAL_CHANNEL *);
                     88: HAL_BOOL        ar5k_ar5111_chan2athchan(u_int, struct ar5k_athchan_2ghz *);
                     89: HAL_BOOL        ar5k_ar5112_channel(struct ath_hal *, HAL_CHANNEL *);
                     90: HAL_BOOL        ar5k_check_channel(struct ath_hal *, u_int16_t, u_int flags);
                     91:
                     92: HAL_BOOL        ar5k_ar5111_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int);
                     93: HAL_BOOL        ar5k_ar5112_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int);
                     94: u_int           ar5k_rfregs_op(u_int32_t *, u_int32_t, u_int32_t, u_int32_t,
                     95:     u_int32_t, u_int32_t, HAL_BOOL);
                     96:
                     97: /*
                     98:  * Supported channels
                     99:  */
                    100: static const struct
                    101: ieee80211_regchannel ar5k_5ghz_channels[] = IEEE80211_CHANNELS_5GHZ;
                    102: static const struct
                    103: ieee80211_regchannel ar5k_2ghz_channels[] = IEEE80211_CHANNELS_2GHZ;
                    104:
                    105: /*
                    106:  * Initial gain optimization values
                    107:  */
                    108: static const struct ar5k_gain_opt ar5111_gain_opt = AR5K_AR5111_GAIN_OPT;
                    109: static const struct ar5k_gain_opt ar5112_gain_opt = AR5K_AR5112_GAIN_OPT;
                    110:
                    111: /*
                    112:  * Initial register for the radio chipsets
                    113:  */
                    114: static const struct ar5k_ini_rf ar5111_rf[] = AR5K_AR5111_INI_RF;
                    115: static const struct ar5k_ini_rf ar5112_rf[] = AR5K_AR5112_INI_RF;
                    116: static const struct ar5k_ini_rf ar5112a_rf[] = AR5K_AR5112A_INI_RF;
                    117: static const struct ar5k_ini_rfgain ar5k_rfg[] = AR5K_INI_RFGAIN;
                    118:
                    119: /*
                    120:  * Enable to overwrite the country code (use "00" for debug)
                    121:  */
                    122: #if 0
                    123: #define COUNTRYCODE "00"
                    124: #endif
                    125:
                    126: /*
                    127:  * Perform a lookup if the device is supported by the HAL
                    128:  */
                    129: const char *
                    130: ath_hal_probe(u_int16_t vendor, u_int16_t device)
                    131: {
                    132:        int i;
                    133:
                    134:        /*
                    135:         * Perform a linear search on the table of supported devices
                    136:         */
                    137:        for (i = 0; i < AR5K_ELEMENTS(ar5k_known_products); i++) {
                    138:                if (vendor == ar5k_known_products[i].vendor &&
                    139:                    device == ar5k_known_products[i].device)
                    140:                        return ("");
                    141:        }
                    142:
                    143:        return (NULL);
                    144: }
                    145:
                    146: /*
                    147:  * Fills in the HAL structure and initialises the device
                    148:  */
                    149: struct ath_hal *
                    150: ath_hal_attach(u_int16_t device, void *arg, bus_space_tag_t st,
                    151:     bus_space_handle_t sh, u_int is_64bit, int *status)
                    152: {
                    153:        struct ath_softc *sc = (struct ath_softc *)arg;
                    154:        struct ath_hal *hal = NULL;
                    155:        ar5k_attach_t *attach = NULL;
                    156:        u_int8_t mac[IEEE80211_ADDR_LEN];
                    157:        int i;
                    158:
                    159:        *status = EINVAL;
                    160:
                    161:        /*
                    162:         * Call the chipset-dependent attach routine by device id
                    163:         */
                    164:        for (i = 0; i < AR5K_ELEMENTS(ar5k_known_products); i++) {
                    165:                if (device == ar5k_known_products[i].device &&
                    166:                    ar5k_known_products[i].attach != NULL)
                    167:                        attach = ar5k_known_products[i].attach;
                    168:        }
                    169:
                    170:        if (attach == NULL) {
                    171:                *status = ENXIO;
                    172:                AR5K_PRINTF("device not supported: 0x%04x\n", device);
                    173:                return (NULL);
                    174:        }
                    175:
                    176:        if ((hal = malloc(sizeof(struct ath_hal),
                    177:                 M_DEVBUF, M_NOWAIT)) == NULL) {
                    178:                *status = ENOMEM;
                    179:                AR5K_PRINT("out of memory\n");
                    180:                return (NULL);
                    181:        }
                    182:
                    183:        bzero(hal, sizeof(struct ath_hal));
                    184:
                    185:        hal->ah_sc = sc;
                    186:        hal->ah_st = st;
                    187:        hal->ah_sh = sh;
                    188:        hal->ah_device = device;
                    189:        hal->ah_sub_vendor = 0; /* XXX unknown?! */
                    190:
                    191:        /*
                    192:         * HAL information
                    193:         */
                    194:        hal->ah_abi = HAL_ABI_VERSION;
                    195:        hal->ah_op_mode = HAL_M_STA;
                    196:        hal->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
                    197:        hal->ah_turbo = AH_FALSE;
                    198:        hal->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
                    199:        hal->ah_imr = 0;
                    200:        hal->ah_atim_window = 0;
                    201:        hal->ah_aifs = AR5K_TUNE_AIFS;
                    202:        hal->ah_cw_min = AR5K_TUNE_CWMIN;
                    203:        hal->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
                    204:        hal->ah_software_retry = AH_FALSE;
                    205:        hal->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
                    206:
                    207:        switch (device) {
                    208:        case PCI_PRODUCT_ATHEROS_AR2413:
                    209:        case PCI_PRODUCT_ATHEROS_AR5413:
                    210:        case PCI_PRODUCT_ATHEROS_AR5424:
                    211:                /*
                    212:                 * Known single chip solutions
                    213:                 */
                    214:                hal->ah_single_chip = AH_TRUE;
                    215:                break;
                    216:        case PCI_PRODUCT_ATHEROS_AR5212_IBM:
                    217:                /*
                    218:                 * IBM ThinkPads use the same device ID for different
                    219:                 * chipset versions. Ugh.
                    220:                 */
                    221:                if (is_64bit) {
                    222:                        /*
                    223:                         * PCI Express "Mini Card" interface based on the
                    224:                         * AR5424 chipset
                    225:                         */
                    226:                        hal->ah_single_chip = AH_TRUE;
                    227:                } else {
                    228:                        /* Classic Mini PCI interface based on AR5212 */
                    229:                        hal->ah_single_chip = AH_FALSE;
                    230:                }
                    231:                break;
                    232:        default:
                    233:                /*
                    234:                 * Multi chip solutions
                    235:                 */
                    236:                hal->ah_single_chip = AH_FALSE;
                    237:                break;
                    238:        }
                    239:
                    240:        if ((attach)(device, hal, st, sh, status) == NULL)
                    241:                goto failed;
                    242:
                    243: #ifdef AR5K_DEBUG
                    244:        hal->ah_dump_state(hal);
                    245: #endif
                    246:
                    247:        /*
                    248:         * Get card capabilities, values, ...
                    249:         */
                    250:
                    251:        if (ar5k_eeprom_init(hal) != 0) {
                    252:                AR5K_PRINT("unable to init EEPROM\n");
                    253:                goto failed;
                    254:        }
                    255:
                    256:        /* Get misc capabilities */
                    257:        if (hal->ah_get_capabilities(hal) != AH_TRUE) {
                    258:                AR5K_PRINTF("unable to get device capabilities: 0x%04x\n",
                    259:                    device);
                    260:                goto failed;
                    261:        }
                    262:
                    263:        /* Get MAC address */
                    264:        if ((*status = ar5k_eeprom_read_mac(hal, mac)) != 0) {
                    265:                AR5K_PRINTF("unable to read address from EEPROM: 0x%04x\n",
                    266:                    device);
                    267:                goto failed;
                    268:        }
                    269:
                    270:        hal->ah_set_lladdr(hal, mac);
                    271:
                    272:        /* Get rate tables */
                    273:        if (hal->ah_capabilities.cap_mode & HAL_MODE_11A)
                    274:                ar5k_rt_copy(&hal->ah_rt_11a, &ar5k_rt_11a);
                    275:        if (hal->ah_capabilities.cap_mode & HAL_MODE_11B)
                    276:                ar5k_rt_copy(&hal->ah_rt_11b, &ar5k_rt_11b);
                    277:        if (hal->ah_capabilities.cap_mode & HAL_MODE_11G)
                    278:                ar5k_rt_copy(&hal->ah_rt_11g, &ar5k_rt_11g);
                    279:        if (hal->ah_capabilities.cap_mode & HAL_MODE_TURBO)
                    280:                ar5k_rt_copy(&hal->ah_rt_turbo, &ar5k_rt_turbo);
                    281:        if (hal->ah_capabilities.cap_mode & HAL_MODE_XR)
                    282:                ar5k_rt_copy(&hal->ah_rt_xr, &ar5k_rt_xr);
                    283:
                    284:        /* Initialize the gain optimization values */
                    285:        if (hal->ah_radio == AR5K_AR5111) {
                    286:                hal->ah_gain.g_step_idx = ar5111_gain_opt.go_default;
                    287:                hal->ah_gain.g_step =
                    288:                    &ar5111_gain_opt.go_step[hal->ah_gain.g_step_idx];
                    289:                hal->ah_gain.g_low = 20;
                    290:                hal->ah_gain.g_high = 35;
                    291:                hal->ah_gain.g_active = 1;
                    292:        } else if (hal->ah_radio == AR5K_AR5112) {
                    293:                hal->ah_gain.g_step_idx = ar5112_gain_opt.go_default;
                    294:                hal->ah_gain.g_step =
                    295:                    &ar5111_gain_opt.go_step[hal->ah_gain.g_step_idx];
                    296:                hal->ah_gain.g_low = 20;
                    297:                hal->ah_gain.g_high = 85;
                    298:                hal->ah_gain.g_active = 1;
                    299:        }
                    300:
                    301:        *status = HAL_OK;
                    302:
                    303:        return (hal);
                    304:
                    305:  failed:
                    306:        free(hal, M_DEVBUF);
                    307:        return (NULL);
                    308: }
                    309:
                    310: u_int16_t
                    311: ath_hal_computetxtime(struct ath_hal *hal, const HAL_RATE_TABLE *rates,
                    312:     u_int32_t frame_length, u_int16_t rate_index, HAL_BOOL short_preamble)
                    313: {
                    314:        const HAL_RATE *rate;
                    315:        u_int32_t value;
                    316:
                    317:        AR5K_ASSERT_ENTRY(rate_index, rates->rateCount);
                    318:
                    319:        /*
                    320:         * Get rate by index
                    321:         */
                    322:        rate = &rates->info[rate_index];
                    323:
                    324:        /*
                    325:         * Calculate the transmission time by operation (PHY) mode
                    326:         */
                    327:        switch (rate->phy) {
                    328:        case IEEE80211_T_CCK:
                    329:                /*
                    330:                 * CCK / DS mode (802.11b)
                    331:                 */
                    332:                value = AR5K_CCK_TX_TIME(rate->rateKbps, frame_length,
                    333:                    (short_preamble && rate->shortPreamble));
                    334:                break;
                    335:
                    336:        case IEEE80211_T_OFDM:
                    337:                /*
                    338:                 * Orthogonal Frequency Division Multiplexing
                    339:                 */
                    340:                if (AR5K_OFDM_NUM_BITS_PER_SYM(rate->rateKbps) == 0)
                    341:                        return (0);
                    342:                value = AR5K_OFDM_TX_TIME(rate->rateKbps, frame_length);
                    343:                break;
                    344:
                    345:        case IEEE80211_T_TURBO:
                    346:                /*
                    347:                 * Orthogonal Frequency Division Multiplexing
                    348:                 * Atheros "Turbo Mode" (doubled rates)
                    349:                 */
                    350:                if (AR5K_TURBO_NUM_BITS_PER_SYM(rate->rateKbps) == 0)
                    351:                        return (0);
                    352:                value = AR5K_TURBO_TX_TIME(rate->rateKbps, frame_length);
                    353:                break;
                    354:
                    355:        case IEEE80211_T_XR:
                    356:                /*
                    357:                 * Orthogonal Frequency Division Multiplexing
                    358:                 * Atheros "eXtended Range" (XR)
                    359:                 */
                    360:                if (AR5K_XR_NUM_BITS_PER_SYM(rate->rateKbps) == 0)
                    361:                        return (0);
                    362:                value = AR5K_XR_TX_TIME(rate->rateKbps, frame_length);
                    363:                break;
                    364:
                    365:        default:
                    366:                return (0);
                    367:        }
                    368:
                    369:        return (value);
                    370: }
                    371:
                    372: HAL_BOOL
                    373: ar5k_check_channel(struct ath_hal *hal, u_int16_t freq, u_int flags)
                    374: {
                    375:        /* Check if the channel is in our supported range */
                    376:        if (flags & IEEE80211_CHAN_2GHZ) {
                    377:                if ((freq >= hal->ah_capabilities.cap_range.range_2ghz_min) &&
                    378:                    (freq <= hal->ah_capabilities.cap_range.range_2ghz_max))
                    379:                        return (AH_TRUE);
                    380:        } else if (flags & IEEE80211_CHAN_5GHZ) {
                    381:                if ((freq >= hal->ah_capabilities.cap_range.range_5ghz_min) &&
                    382:                    (freq <= hal->ah_capabilities.cap_range.range_5ghz_max))
                    383:                        return (AH_TRUE);
                    384:        }
                    385:
                    386:        return (AH_FALSE);
                    387: }
                    388:
                    389: HAL_BOOL
                    390: ath_hal_init_channels(struct ath_hal *hal, HAL_CHANNEL *channels,
                    391:     u_int max_channels, u_int *channels_size, u_int16_t mode,
                    392:     HAL_BOOL outdoor, HAL_BOOL extended)
                    393: {
                    394:        u_int i, c;
                    395:        u_int32_t domain_current;
                    396:        u_int domain_5ghz, domain_2ghz;
                    397:        HAL_CHANNEL *all_channels;
                    398:
                    399:        if ((all_channels = malloc(sizeof(HAL_CHANNEL) * max_channels,
                    400:            M_TEMP, M_NOWAIT)) == NULL)
                    401:                return (AH_FALSE);
                    402:
                    403:        i = c = 0;
                    404:        domain_current = hal->ah_regdomain;
                    405:
                    406:        /*
                    407:         * In debugging mode, enable all channels supported by the chipset
                    408:         */
                    409:        if (domain_current == DMN_DEFAULT) {
                    410:                int min, max, freq;
                    411:                u_int flags;
                    412:
                    413:                min = ieee80211_mhz2ieee(IEEE80211_CHANNELS_2GHZ_MIN,
                    414:                    IEEE80211_CHAN_2GHZ);
                    415:                max = ieee80211_mhz2ieee(IEEE80211_CHANNELS_2GHZ_MAX,
                    416:                    IEEE80211_CHAN_2GHZ);
                    417:                flags = CHANNEL_B | CHANNEL_TG |
                    418:                    (hal->ah_version == AR5K_AR5211 ?
                    419:                    CHANNEL_PUREG : CHANNEL_G);
                    420:
                    421:  debugchan:
                    422:                for (i = min; i <= max && c < max_channels; i++) {
                    423:                        freq = ieee80211_ieee2mhz(i, flags);
                    424:                        if (ar5k_check_channel(hal, freq, flags) == AH_FALSE)
                    425:                                continue;
                    426:                        all_channels[c].c_channel = freq;
                    427:                        all_channels[c++].c_channel_flags = flags;
                    428:                }
                    429:
                    430:                if (flags & IEEE80211_CHAN_2GHZ) {
                    431:                        min = ieee80211_mhz2ieee(IEEE80211_CHANNELS_5GHZ_MIN,
                    432:                            IEEE80211_CHAN_5GHZ);
                    433:                        max = ieee80211_mhz2ieee(IEEE80211_CHANNELS_5GHZ_MAX,
                    434:                            IEEE80211_CHAN_5GHZ);
                    435:                        flags = CHANNEL_A | CHANNEL_T | CHANNEL_XR;
                    436:                        goto debugchan;
                    437:                }
                    438:
                    439:                goto done;
                    440:        }
                    441:
                    442:        domain_5ghz = ieee80211_regdomain2flag(domain_current,
                    443:            IEEE80211_CHANNELS_5GHZ_MIN);
                    444:        domain_2ghz = ieee80211_regdomain2flag(domain_current,
                    445:            IEEE80211_CHANNELS_2GHZ_MIN);
                    446:
                    447:        /*
                    448:         * Create channel list based on chipset capabilities, regulation domain
                    449:         * and mode. 5GHz...
                    450:         */
                    451:        for (i = 0; (hal->ah_capabilities.cap_range.range_5ghz_max > 0) &&
                    452:                 (i < AR5K_ELEMENTS(ar5k_5ghz_channels)) &&
                    453:                 (c < max_channels); i++) {
                    454:                /* Check if channel is supported by the chipset */
                    455:                if (ar5k_check_channel(hal,
                    456:                    ar5k_5ghz_channels[i].rc_channel,
                    457:                    IEEE80211_CHAN_5GHZ) == AH_FALSE)
                    458:                        continue;
                    459:
                    460:                /* Match regulation domain */
                    461:                if ((IEEE80211_DMN(ar5k_5ghz_channels[i].rc_domain) &
                    462:                        IEEE80211_DMN(domain_5ghz)) == 0)
                    463:                        continue;
                    464:
                    465:                /* Match modes */
                    466:                if (ar5k_5ghz_channels[i].rc_mode & IEEE80211_CHAN_TURBO) {
                    467:                        all_channels[c].c_channel_flags = CHANNEL_T;
                    468:                } else if (ar5k_5ghz_channels[i].rc_mode &
                    469:                    IEEE80211_CHAN_OFDM) {
                    470:                        all_channels[c].c_channel_flags = CHANNEL_A;
                    471:                } else
                    472:                        continue;
                    473:
                    474:                /* Write channel and increment counter */
                    475:                all_channels[c++].channel = ar5k_5ghz_channels[i].rc_channel;
                    476:        }
                    477:
                    478:        /*
                    479:         * ...and 2GHz.
                    480:         */
                    481:        for (i = 0; (hal->ah_capabilities.cap_range.range_2ghz_max > 0) &&
                    482:                 (i < AR5K_ELEMENTS(ar5k_2ghz_channels)) &&
                    483:                 (c < max_channels); i++) {
                    484:                /* Check if channel is supported by the chipset */
                    485:                if (ar5k_check_channel(hal,
                    486:                    ar5k_2ghz_channels[i].rc_channel,
                    487:                    IEEE80211_CHAN_2GHZ) == AH_FALSE)
                    488:                        continue;
                    489:
                    490:                /* Match regulation domain */
                    491:                if ((IEEE80211_DMN(ar5k_2ghz_channels[i].rc_domain) &
                    492:                        IEEE80211_DMN(domain_2ghz)) == 0)
                    493:                        continue;
                    494:
                    495:                /* Match modes */
                    496:                if ((hal->ah_capabilities.cap_mode & HAL_MODE_11B) &&
                    497:                    (ar5k_2ghz_channels[i].rc_mode & IEEE80211_CHAN_CCK))
                    498:                        all_channels[c].c_channel_flags = CHANNEL_B;
                    499:
                    500:                if ((hal->ah_capabilities.cap_mode & HAL_MODE_11G) &&
                    501:                    (ar5k_2ghz_channels[i].rc_mode & IEEE80211_CHAN_OFDM)) {
                    502:                        all_channels[c].c_channel_flags |=
                    503:                            hal->ah_version == AR5K_AR5211 ?
                    504:                            CHANNEL_PUREG : CHANNEL_G;
                    505:                        if (ar5k_2ghz_channels[i].rc_mode &
                    506:                            IEEE80211_CHAN_TURBO)
                    507:                                all_channels[c].c_channel_flags |= CHANNEL_TG;
                    508:                }
                    509:
                    510:                /* Write channel and increment counter */
                    511:                all_channels[c++].channel = ar5k_2ghz_channels[i].rc_channel;
                    512:        }
                    513:
                    514:  done:
                    515:        bcopy(all_channels, channels, sizeof(HAL_CHANNEL) * max_channels);
                    516:        *channels_size = c;
                    517:        free(all_channels, M_TEMP);
                    518:        return (AH_TRUE);
                    519: }
                    520:
                    521: /*
                    522:  * Common internal functions
                    523:  */
                    524:
                    525: const char *
                    526: ar5k_printver(enum ar5k_srev_type type, u_int32_t val)
                    527: {
                    528:        struct ar5k_srev_name names[] = AR5K_SREV_NAME;
                    529:        const char *name = "xxxx";
                    530:        int i;
                    531:
                    532:        for (i = 0; i < AR5K_ELEMENTS(names); i++) {
                    533:                if (type == AR5K_VERSION_DEV) {
                    534:                        if (names[i].sr_type == type &&
                    535:                            names[i].sr_val == val) {
                    536:                                name = names[i].sr_name;
                    537:                                break;
                    538:                        }
                    539:                        continue;
                    540:                }
                    541:                if (names[i].sr_type != type ||
                    542:                    names[i].sr_val == AR5K_SREV_UNKNOWN)
                    543:                        continue;
                    544:                if ((val & 0xff) < names[i + 1].sr_val) {
                    545:                        name = names[i].sr_name;
                    546:                        break;
                    547:                }
                    548:        }
                    549:
                    550:        return (name);
                    551: }
                    552:
                    553: void
                    554: ar5k_radar_alert(struct ath_hal *hal)
                    555: {
                    556:        /*
                    557:         * Limit ~1/s
                    558:         */
                    559:        if (hal->ah_radar.r_last_channel.channel ==
                    560:            hal->ah_current_channel.channel &&
                    561:            tick < (hal->ah_radar.r_last_alert + hz))
                    562:                return;
                    563:
                    564:        hal->ah_radar.r_last_channel.channel =
                    565:            hal->ah_current_channel.channel;
                    566:        hal->ah_radar.r_last_channel.c_channel_flags =
                    567:            hal->ah_current_channel.c_channel_flags;
                    568:        hal->ah_radar.r_last_alert = tick;
                    569:
                    570:        AR5K_PRINTF("Possible radar activity detected at %u MHz (tick %u)\n",
                    571:            hal->ah_radar.r_last_alert, hal->ah_current_channel.channel);
                    572: }
                    573:
                    574: u_int16_t
                    575: ar5k_regdomain_from_ieee(ieee80211_regdomain_t ieee)
                    576: {
                    577:        u_int32_t regdomain = (u_int32_t)ieee;
                    578:
                    579:        /*
                    580:         * Use the default regulation domain if the value is empty
                    581:         * or not supported by the net80211 regulation code.
                    582:         */
                    583:        if (ieee80211_regdomain2flag(regdomain,
                    584:            IEEE80211_CHANNELS_5GHZ_MIN) == DMN_DEBUG)
                    585:                return ((u_int16_t)AR5K_TUNE_REGDOMAIN);
                    586:
                    587:        /* It is supported, just return the value */
                    588:        return (regdomain);
                    589: }
                    590:
                    591: ieee80211_regdomain_t
                    592: ar5k_regdomain_to_ieee(u_int16_t regdomain)
                    593: {
                    594:        ieee80211_regdomain_t ieee = (ieee80211_regdomain_t)regdomain;
                    595:
                    596:        return (ieee);
                    597: }
                    598:
                    599: u_int16_t
                    600: ar5k_get_regdomain(struct ath_hal *hal)
                    601: {
                    602:        u_int16_t regdomain;
                    603:        ieee80211_regdomain_t ieee_regdomain;
                    604: #ifdef COUNTRYCODE
                    605:        u_int16_t code;
                    606: #endif
                    607:
                    608:        ar5k_eeprom_regulation_domain(hal, AH_FALSE, &ieee_regdomain);
                    609:        hal->ah_capabilities.cap_regdomain.reg_hw = ieee_regdomain;
                    610:
                    611: #ifdef COUNTRYCODE
                    612:        /*
                    613:         * Get the regulation domain by country code. This will ignore
                    614:         * the settings found in the EEPROM.
                    615:         */
                    616:        code = ieee80211_name2countrycode(COUNTRYCODE);
                    617:        ieee_regdomain = ieee80211_countrycode2regdomain(code);
                    618: #endif
                    619:
                    620:        regdomain = ar5k_regdomain_from_ieee(ieee_regdomain);
                    621:        hal->ah_capabilities.cap_regdomain.reg_current = regdomain;
                    622:
                    623:        return (regdomain);
                    624: }
                    625:
                    626: u_int32_t
                    627: ar5k_bitswap(u_int32_t val, u_int bits)
                    628: {
                    629:        if (bits == 8) {
                    630:                val = ((val & 0xF0) >>  4) | ((val & 0x0F) <<  4);
                    631:                val = ((val & 0xCC) >>  2) | ((val & 0x33) <<  2);
                    632:                val = ((val & 0xAA) >>  1) | ((val & 0x55) <<  1);
                    633:
                    634:                return val;
                    635:        } else {
                    636:                u_int32_t retval = 0, bit, i;
                    637:
                    638:                for (i = 0; i < bits; i++) {
                    639:                        bit = (val >> i) & 1;
                    640:                        retval = (retval << 1) | bit;
                    641:                }
                    642:
                    643:                return retval;
                    644:        }
                    645: }
                    646:
                    647: u_int
                    648: ar5k_htoclock(u_int usec, HAL_BOOL turbo)
                    649: {
                    650:        return (turbo == AH_TRUE ? (usec * 80) : (usec * 40));
                    651: }
                    652:
                    653: u_int
                    654: ar5k_clocktoh(u_int clock, HAL_BOOL turbo)
                    655: {
                    656:        return (turbo == AH_TRUE ? (clock / 80) : (clock / 40));
                    657: }
                    658:
                    659: void
                    660: ar5k_rt_copy(HAL_RATE_TABLE *dst, const HAL_RATE_TABLE *src)
                    661: {
                    662:        bzero(dst, sizeof(HAL_RATE_TABLE));
                    663:        dst->rateCount = src->rateCount;
                    664:        bcopy(src->info, dst->info, sizeof(dst->info));
                    665: }
                    666:
                    667: HAL_BOOL
                    668: ar5k_register_timeout(struct ath_hal *hal, u_int32_t reg, u_int32_t flag,
                    669:     u_int32_t val, HAL_BOOL is_set)
                    670: {
                    671:        int i;
                    672:        u_int32_t data;
                    673:
                    674:        for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
                    675:                data = AR5K_REG_READ(reg);
                    676:                if ((is_set == AH_TRUE) && (data & flag))
                    677:                        break;
                    678:                else if ((data & flag) == val)
                    679:                        break;
                    680:                AR5K_DELAY(15);
                    681:        }
                    682:
                    683:        if (i <= 0)
                    684:                return (AH_FALSE);
                    685:
                    686:        return (AH_TRUE);
                    687: }
                    688:
                    689: /*
                    690:  * Common ar5xx EEPROM access functions
                    691:  */
                    692:
                    693: u_int16_t
                    694: ar5k_eeprom_bin2freq(struct ath_hal *hal, u_int16_t bin, u_int mode)
                    695: {
                    696:        u_int16_t val;
                    697:
                    698:        if (bin == AR5K_EEPROM_CHANNEL_DIS)
                    699:                return (bin);
                    700:
                    701:        if (mode == AR5K_EEPROM_MODE_11A) {
                    702:                if (hal->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
                    703:                        val = (5 * bin) + 4800;
                    704:                else
                    705:                        val = bin > 62 ?
                    706:                            (10 * 62) + (5 * (bin - 62)) + 5100 :
                    707:                            (bin * 10) + 5100;
                    708:        } else {
                    709:                if (hal->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
                    710:                        val = bin + 2300;
                    711:                else
                    712:                        val = bin + 2400;
                    713:        }
                    714:
                    715:        return (val);
                    716: }
                    717:
                    718: int
                    719: ar5k_eeprom_read_ants(struct ath_hal *hal, u_int32_t *offset, u_int mode)
                    720: {
                    721:        struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
                    722:        u_int32_t o = *offset;
                    723:        u_int16_t val;
                    724:        int ret, i = 0;
                    725:
                    726:        AR5K_EEPROM_READ(o++, val);
                    727:        ee->ee_switch_settling[mode]    = (val >> 8) & 0x7f;
                    728:        ee->ee_ant_tx_rx[mode]          = (val >> 2) & 0x3f;
                    729:        ee->ee_ant_control[mode][i]     = (val << 4) & 0x3f;
                    730:
                    731:        AR5K_EEPROM_READ(o++, val);
                    732:        ee->ee_ant_control[mode][i++]   |= (val >> 12) & 0xf;
                    733:        ee->ee_ant_control[mode][i++]   = (val >> 6) & 0x3f;
                    734:        ee->ee_ant_control[mode][i++]   = val & 0x3f;
                    735:
                    736:        AR5K_EEPROM_READ(o++, val);
                    737:        ee->ee_ant_control[mode][i++]   = (val >> 10) & 0x3f;
                    738:        ee->ee_ant_control[mode][i++]   = (val >> 4) & 0x3f;
                    739:        ee->ee_ant_control[mode][i]     = (val << 2) & 0x3f;
                    740:
                    741:        AR5K_EEPROM_READ(o++, val);
                    742:        ee->ee_ant_control[mode][i++]   |= (val >> 14) & 0x3;
                    743:        ee->ee_ant_control[mode][i++]   = (val >> 8) & 0x3f;
                    744:        ee->ee_ant_control[mode][i++]   = (val >> 2) & 0x3f;
                    745:        ee->ee_ant_control[mode][i]     = (val << 4) & 0x3f;
                    746:
                    747:        AR5K_EEPROM_READ(o++, val);
                    748:        ee->ee_ant_control[mode][i++]   |= (val >> 12) & 0xf;
                    749:        ee->ee_ant_control[mode][i++]   = (val >> 6) & 0x3f;
                    750:        ee->ee_ant_control[mode][i++]   = val & 0x3f;
                    751:
                    752:        /* Get antenna modes */
                    753:        hal->ah_antenna[mode][0] =
                    754:            (ee->ee_ant_control[mode][0] << 4) | 0x1;
                    755:        hal->ah_antenna[mode][HAL_ANT_FIXED_A] =
                    756:            ee->ee_ant_control[mode][1] |
                    757:            (ee->ee_ant_control[mode][2] << 6) |
                    758:            (ee->ee_ant_control[mode][3] << 12) |
                    759:            (ee->ee_ant_control[mode][4] << 18) |
                    760:            (ee->ee_ant_control[mode][5] << 24);
                    761:        hal->ah_antenna[mode][HAL_ANT_FIXED_B] =
                    762:            ee->ee_ant_control[mode][6] |
                    763:            (ee->ee_ant_control[mode][7] << 6) |
                    764:            (ee->ee_ant_control[mode][8] << 12) |
                    765:            (ee->ee_ant_control[mode][9] << 18) |
                    766:            (ee->ee_ant_control[mode][10] << 24);
                    767:
                    768:        /* return new offset */
                    769:        *offset = o;
                    770:
                    771:        return (0);
                    772: }
                    773:
                    774: int
                    775: ar5k_eeprom_read_modes(struct ath_hal *hal, u_int32_t *offset, u_int mode)
                    776: {
                    777:        struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
                    778:        u_int32_t o = *offset;
                    779:        u_int16_t val;
                    780:        int ret;
                    781:
                    782:        AR5K_EEPROM_READ(o++, val);
                    783:        ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
                    784:        ee->ee_thr_62[mode]             = val & 0xff;
                    785:
                    786:        if (hal->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
                    787:                ee->ee_thr_62[mode] =
                    788:                    mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
                    789:
                    790:        AR5K_EEPROM_READ(o++, val);
                    791:        ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff;
                    792:        ee->ee_tx_frm2xpa_enable[mode]  = val & 0xff;
                    793:
                    794:        AR5K_EEPROM_READ(o++, val);
                    795:        ee->ee_pga_desired_size[mode]   = (val >> 8) & 0xff;
                    796:
                    797:        if ((val & 0xff) & 0x80)
                    798:                ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
                    799:        else
                    800:                ee->ee_noise_floor_thr[mode] = val & 0xff;
                    801:
                    802:        if (hal->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
                    803:                ee->ee_noise_floor_thr[mode] =
                    804:                    mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
                    805:
                    806:        AR5K_EEPROM_READ(o++, val);
                    807:        ee->ee_xlna_gain[mode]          = (val >> 5) & 0xff;
                    808:        ee->ee_x_gain[mode]             = (val >> 1) & 0xf;
                    809:        ee->ee_xpd[mode]                = val & 0x1;
                    810:
                    811:        if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0)
                    812:                ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
                    813:
                    814:        if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
                    815:                AR5K_EEPROM_READ(o++, val);
                    816:                ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
                    817:
                    818:                if (mode == AR5K_EEPROM_MODE_11A)
                    819:                        ee->ee_xr_power[mode] = val & 0x3f;
                    820:                else {
                    821:                        ee->ee_ob[mode][0] = val & 0x7;
                    822:                        ee->ee_db[mode][0] = (val >> 3) & 0x7;
                    823:                }
                    824:        }
                    825:
                    826:        if (hal->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
                    827:                ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
                    828:                ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
                    829:        } else {
                    830:                ee->ee_i_gain[mode] = (val >> 13) & 0x7;
                    831:
                    832:                AR5K_EEPROM_READ(o++, val);
                    833:                ee->ee_i_gain[mode] |= (val << 3) & 0x38;
                    834:
                    835:                if (mode == AR5K_EEPROM_MODE_11G)
                    836:                        ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
                    837:        }
                    838:
                    839:        if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
                    840:            mode == AR5K_EEPROM_MODE_11A) {
                    841:                ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
                    842:                ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
                    843:        }
                    844:
                    845:        if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_6 &&
                    846:            mode == AR5K_EEPROM_MODE_11G)
                    847:                ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
                    848:
                    849:        /* return new offset */
                    850:        *offset = o;
                    851:
                    852:        return (0);
                    853: }
                    854:
                    855: int
                    856: ar5k_eeprom_init(struct ath_hal *hal)
                    857: {
                    858:        struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
                    859:        u_int32_t offset;
                    860:        u_int16_t val;
                    861:        int ret, i;
                    862:        u_int mode;
                    863:
                    864:        /* Initial TX thermal adjustment values */
                    865:        ee->ee_tx_clip = 4;
                    866:        ee->ee_pwd_84 = ee->ee_pwd_90 = 1;
                    867:        ee->ee_gain_select = 1;
                    868:
                    869:        /*
                    870:         * Read values from EEPROM and store them in the capability structure
                    871:         */
                    872:        AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic);
                    873:        AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect);
                    874:        AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain);
                    875:        AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version);
                    876:        AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header);
                    877:
                    878:        /* Return if we have an old EEPROM */
                    879:        if (hal->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
                    880:                return (0);
                    881:
                    882: #ifdef notyet
                    883:        /*
                    884:         * Validate the checksum of the EEPROM date. There are some
                    885:         * devices with invalid EEPROMs.
                    886:         */
                    887:        for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
                    888:                AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
                    889:                cksum ^= val;
                    890:        }
                    891:        if (cksum != AR5K_EEPROM_INFO_CKSUM) {
                    892:                AR5K_PRINTF("Invalid EEPROM checksum 0x%04x\n", cksum);
                    893:                return (EINVAL);
                    894:        }
                    895: #endif
                    896:
                    897:        AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(hal->ah_ee_version),
                    898:            ee_ant_gain);
                    899:
                    900:        if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
                    901:                AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
                    902:                AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
                    903:        }
                    904:
                    905:        if (hal->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
                    906:                AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
                    907:                ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
                    908:                ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
                    909:
                    910:                AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
                    911:                ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
                    912:                ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
                    913:        }
                    914:
                    915:        /*
                    916:         * Get conformance test limit values
                    917:         */
                    918:        offset = AR5K_EEPROM_CTL(hal->ah_ee_version);
                    919:        ee->ee_ctls = AR5K_EEPROM_N_CTLS(hal->ah_ee_version);
                    920:
                    921:        for (i = 0; i < ee->ee_ctls; i++) {
                    922:                AR5K_EEPROM_READ(offset++, val);
                    923:                ee->ee_ctl[i] = (val >> 8) & 0xff;
                    924:                ee->ee_ctl[i + 1] = val & 0xff;
                    925:        }
                    926:
                    927:        /*
                    928:         * Get values for 802.11a (5GHz)
                    929:         */
                    930:        mode = AR5K_EEPROM_MODE_11A;
                    931:
                    932:        ee->ee_turbo_max_power[mode] =
                    933:            AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
                    934:
                    935:        offset = AR5K_EEPROM_MODES_11A(hal->ah_ee_version);
                    936:
                    937:        if ((ret = ar5k_eeprom_read_ants(hal, &offset, mode)) != 0)
                    938:                return (ret);
                    939:
                    940:        AR5K_EEPROM_READ(offset++, val);
                    941:        ee->ee_adc_desired_size[mode]   = (int8_t)((val >> 8) & 0xff);
                    942:        ee->ee_ob[mode][3]              = (val >> 5) & 0x7;
                    943:        ee->ee_db[mode][3]              = (val >> 2) & 0x7;
                    944:        ee->ee_ob[mode][2]              = (val << 1) & 0x7;
                    945:
                    946:        AR5K_EEPROM_READ(offset++, val);
                    947:        ee->ee_ob[mode][2]              |= (val >> 15) & 0x1;
                    948:        ee->ee_db[mode][2]              = (val >> 12) & 0x7;
                    949:        ee->ee_ob[mode][1]              = (val >> 9) & 0x7;
                    950:        ee->ee_db[mode][1]              = (val >> 6) & 0x7;
                    951:        ee->ee_ob[mode][0]              = (val >> 3) & 0x7;
                    952:        ee->ee_db[mode][0]              = val & 0x7;
                    953:
                    954:        if ((ret = ar5k_eeprom_read_modes(hal, &offset, mode)) != 0)
                    955:                return (ret);
                    956:
                    957:        if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
                    958:                AR5K_EEPROM_READ(offset++, val);
                    959:                ee->ee_margin_tx_rx[mode] = val & 0x3f;
                    960:        }
                    961:
                    962:        /*
                    963:         * Get values for 802.11b (2.4GHz)
                    964:         */
                    965:        mode = AR5K_EEPROM_MODE_11B;
                    966:        offset = AR5K_EEPROM_MODES_11B(hal->ah_ee_version);
                    967:
                    968:        if ((ret = ar5k_eeprom_read_ants(hal, &offset, mode)) != 0)
                    969:                return (ret);
                    970:
                    971:        AR5K_EEPROM_READ(offset++, val);
                    972:        ee->ee_adc_desired_size[mode]   = (int8_t)((val >> 8) & 0xff);
                    973:        ee->ee_ob[mode][1]              = (val >> 4) & 0x7;
                    974:        ee->ee_db[mode][1]              = val & 0x7;
                    975:
                    976:        if ((ret = ar5k_eeprom_read_modes(hal, &offset, mode)) != 0)
                    977:                return (ret);
                    978:
                    979:        if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
                    980:                AR5K_EEPROM_READ(offset++, val);
                    981:                ee->ee_cal_pier[mode][0] =
                    982:                    ar5k_eeprom_bin2freq(hal, val & 0xff, mode);
                    983:                ee->ee_cal_pier[mode][1] =
                    984:                    ar5k_eeprom_bin2freq(hal, (val >> 8) & 0xff, mode);
                    985:
                    986:                AR5K_EEPROM_READ(offset++, val);
                    987:                ee->ee_cal_pier[mode][2] =
                    988:                    ar5k_eeprom_bin2freq(hal, val & 0xff, mode);
                    989:        }
                    990:
                    991:        if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
                    992:                ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
                    993:        }
                    994:
                    995:        /*
                    996:         * Get values for 802.11g (2.4GHz)
                    997:         */
                    998:        mode = AR5K_EEPROM_MODE_11G;
                    999:        offset = AR5K_EEPROM_MODES_11G(hal->ah_ee_version);
                   1000:
                   1001:        if ((ret = ar5k_eeprom_read_ants(hal, &offset, mode)) != 0)
                   1002:                return (ret);
                   1003:
                   1004:        AR5K_EEPROM_READ(offset++, val);
                   1005:        ee->ee_adc_desired_size[mode]   = (int8_t)((val >> 8) & 0xff);
                   1006:        ee->ee_ob[mode][1]              = (val >> 4) & 0x7;
                   1007:        ee->ee_db[mode][1]              = val & 0x7;
                   1008:
                   1009:        if ((ret = ar5k_eeprom_read_modes(hal, &offset, mode)) != 0)
                   1010:                return (ret);
                   1011:
                   1012:        if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
                   1013:                AR5K_EEPROM_READ(offset++, val);
                   1014:                ee->ee_cal_pier[mode][0] =
                   1015:                    ar5k_eeprom_bin2freq(hal, val & 0xff, mode);
                   1016:                ee->ee_cal_pier[mode][1] =
                   1017:                    ar5k_eeprom_bin2freq(hal, (val >> 8) & 0xff, mode);
                   1018:
                   1019:                AR5K_EEPROM_READ(offset++, val);
                   1020:                ee->ee_turbo_max_power[mode] = val & 0x7f;
                   1021:                ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
                   1022:
                   1023:                AR5K_EEPROM_READ(offset++, val);
                   1024:                ee->ee_cal_pier[mode][2] =
                   1025:                    ar5k_eeprom_bin2freq(hal, val & 0xff, mode);
                   1026:
                   1027:                if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
                   1028:                        ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
                   1029:                }
                   1030:
                   1031:                AR5K_EEPROM_READ(offset++, val);
                   1032:                ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
                   1033:                ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
                   1034:
                   1035:                if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
                   1036:                        AR5K_EEPROM_READ(offset++, val);
                   1037:                        ee->ee_cck_ofdm_gain_delta = val & 0xff;
                   1038:                }
                   1039:        }
                   1040:
                   1041:        /*
                   1042:         * Read 5GHz EEPROM channels
                   1043:         */
                   1044:
                   1045:        return (0);
                   1046: }
                   1047:
                   1048: int
                   1049: ar5k_eeprom_read_mac(struct ath_hal *hal, u_int8_t *mac)
                   1050: {
                   1051:        u_int32_t total, offset;
                   1052:        u_int16_t data;
                   1053:        int octet;
                   1054:        u_int8_t mac_d[IEEE80211_ADDR_LEN];
                   1055:
                   1056:        bzero(mac, IEEE80211_ADDR_LEN);
                   1057:        bzero(&mac_d, IEEE80211_ADDR_LEN);
                   1058:
                   1059:        if (hal->ah_eeprom_read(hal, 0x20, &data) != 0)
                   1060:                return (EIO);
                   1061:
                   1062:        for (offset = 0x1f, octet = 0, total = 0;
                   1063:             offset >= 0x1d; offset--) {
                   1064:                if (hal->ah_eeprom_read(hal, offset, &data) != 0)
                   1065:                        return (EIO);
                   1066:
                   1067:                total += data;
                   1068:                mac_d[octet + 1] = data & 0xff;
                   1069:                mac_d[octet] = data >> 8;
                   1070:                octet += 2;
                   1071:        }
                   1072:
                   1073:        bcopy(mac_d, mac, IEEE80211_ADDR_LEN);
                   1074:
                   1075:        if ((!total) || total == (3 * 0xffff))
                   1076:                return (EINVAL);
                   1077:
                   1078:        return (0);
                   1079: }
                   1080:
                   1081: HAL_BOOL
                   1082: ar5k_eeprom_regulation_domain(struct ath_hal *hal, HAL_BOOL write,
                   1083:     ieee80211_regdomain_t *regdomain)
                   1084: {
                   1085:        u_int16_t ee_regdomain;
                   1086:
                   1087:        /* Read current value */
                   1088:        if (write != AH_TRUE) {
                   1089:                ee_regdomain = hal->ah_capabilities.cap_eeprom.ee_regdomain;
                   1090:                *regdomain = ar5k_regdomain_to_ieee(ee_regdomain);
                   1091:                return (AH_TRUE);
                   1092:        }
                   1093:
                   1094:        ee_regdomain = ar5k_regdomain_from_ieee(*regdomain);
                   1095:
                   1096:        /* Try to write a new value */
                   1097:        if (hal->ah_capabilities.cap_eeprom.ee_protect &
                   1098:            AR5K_EEPROM_PROTECT_WR_128_191)
                   1099:                return (AH_FALSE);
                   1100:        if (hal->ah_eeprom_write(hal, AR5K_EEPROM_REG_DOMAIN,
                   1101:            ee_regdomain) != 0)
                   1102:                return (AH_FALSE);
                   1103:
                   1104:        hal->ah_capabilities.cap_eeprom.ee_regdomain = ee_regdomain;
                   1105:
                   1106:        return (AH_TRUE);
                   1107: }
                   1108:
                   1109: /*
                   1110:  * PHY/RF access functions
                   1111:  */
                   1112:
                   1113: HAL_BOOL
                   1114: ar5k_channel(struct ath_hal *hal, HAL_CHANNEL *channel)
                   1115: {
                   1116:        HAL_BOOL ret;
                   1117:
                   1118:        /*
                   1119:         * Check bounds supported by the PHY
                   1120:         * (don't care about regulation restrictions at this point)
                   1121:         */
                   1122:        if ((channel->channel < hal->ah_capabilities.cap_range.range_2ghz_min ||
                   1123:            channel->channel > hal->ah_capabilities.cap_range.range_2ghz_max) &&
                   1124:            (channel->channel < hal->ah_capabilities.cap_range.range_5ghz_min ||
                   1125:            channel->channel > hal->ah_capabilities.cap_range.range_5ghz_max)) {
                   1126:                AR5K_PRINTF("channel out of supported range (%u MHz)\n",
                   1127:                    channel->channel);
                   1128:                return (AH_FALSE);
                   1129:        }
                   1130:
                   1131:        /*
                   1132:         * Set the channel and wait
                   1133:         */
                   1134:        if (hal->ah_radio == AR5K_AR5110)
                   1135:                ret = ar5k_ar5110_channel(hal, channel);
                   1136:        else if (hal->ah_radio == AR5K_AR5111)
                   1137:                ret = ar5k_ar5111_channel(hal, channel);
                   1138:        else
                   1139:                ret = ar5k_ar5112_channel(hal, channel);
                   1140:
                   1141:        if (ret == AH_FALSE)
                   1142:                return (ret);
                   1143:
                   1144:        hal->ah_current_channel.c_channel = channel->c_channel;
                   1145:        hal->ah_current_channel.c_channel_flags = channel->c_channel_flags;
                   1146:        hal->ah_turbo = channel->c_channel_flags == CHANNEL_T ?
                   1147:            AH_TRUE : AH_FALSE;
                   1148:
                   1149:        return (AH_TRUE);
                   1150: }
                   1151:
                   1152: u_int32_t
                   1153: ar5k_ar5110_chan2athchan(HAL_CHANNEL *channel)
                   1154: {
                   1155:        u_int32_t athchan;
                   1156:
                   1157:        /*
                   1158:         * Convert IEEE channel/MHz to an internal channel value used
                   1159:         * by the AR5210 chipset. This has not been verified with
                   1160:         * newer chipsets like the AR5212A who have a completely
                   1161:         * different RF/PHY part.
                   1162:         */
                   1163:        athchan = (ar5k_bitswap((ieee80211_mhz2ieee(channel->c_channel,
                   1164:            channel->c_channel_flags) - 24) / 2, 5) << 1) |
                   1165:            (1 << 6) | 0x1;
                   1166:
                   1167:        return (athchan);
                   1168: }
                   1169:
                   1170: HAL_BOOL
                   1171: ar5k_ar5110_channel(struct ath_hal *hal, HAL_CHANNEL *channel)
                   1172: {
                   1173:        u_int32_t data;
                   1174:
                   1175:        /*
                   1176:         * Set the channel and wait
                   1177:         */
                   1178:        data = ar5k_ar5110_chan2athchan(channel);
                   1179:        AR5K_PHY_WRITE(0x27, data);
                   1180:        AR5K_PHY_WRITE(0x30, 0);
                   1181:        AR5K_DELAY(1000);
                   1182:
                   1183:        return (AH_TRUE);
                   1184: }
                   1185:
                   1186: HAL_BOOL
                   1187: ar5k_ar5111_chan2athchan(u_int ieee, struct ar5k_athchan_2ghz *athchan)
                   1188: {
                   1189:        int channel;
                   1190:
                   1191:        /* Cast this value to catch negative channel numbers (>= -19) */
                   1192:        channel = (int)ieee;
                   1193:
                   1194:        /*
                   1195:         * Map 2GHz IEEE channel to 5GHz Atheros channel
                   1196:         */
                   1197:        if (channel <= 13) {
                   1198:                athchan->a2_athchan = 115 + channel;
                   1199:                athchan->a2_flags = 0x46;
                   1200:        } else if (channel == 14) {
                   1201:                athchan->a2_athchan = 124;
                   1202:                athchan->a2_flags = 0x44;
                   1203:        } else if (channel >= 15 && channel <= 26) {
                   1204:                athchan->a2_athchan = ((channel - 14) * 4) + 132;
                   1205:                athchan->a2_flags = 0x46;
                   1206:        } else
                   1207:                return (AH_FALSE);
                   1208:
                   1209:        return (AH_TRUE);
                   1210: }
                   1211:
                   1212: HAL_BOOL
                   1213: ar5k_ar5111_channel(struct ath_hal *hal, HAL_CHANNEL *channel)
                   1214: {
                   1215:        u_int ieee_channel, ath_channel;
                   1216:        u_int32_t data0, data1, clock;
                   1217:        struct ar5k_athchan_2ghz ath_channel_2ghz;
                   1218:
                   1219:        /*
                   1220:         * Set the channel on the AR5111 radio
                   1221:         */
                   1222:        data0 = data1 = 0;
                   1223:        ath_channel = ieee_channel = ieee80211_mhz2ieee(channel->c_channel,
                   1224:            channel->c_channel_flags);
                   1225:
                   1226:        if (channel->c_channel_flags & IEEE80211_CHAN_2GHZ) {
                   1227:                /* Map 2GHz channel to 5GHz Atheros channel ID */
                   1228:                if (ar5k_ar5111_chan2athchan(ieee_channel,
                   1229:                        &ath_channel_2ghz) == AH_FALSE)
                   1230:                        return (AH_FALSE);
                   1231:
                   1232:                ath_channel = ath_channel_2ghz.a2_athchan;
                   1233:                data0 = ((ar5k_bitswap(ath_channel_2ghz.a2_flags, 8) & 0xff)
                   1234:                    << 5) | (1 << 4);
                   1235:        }
                   1236:
                   1237:        if (ath_channel < 145 || !(ath_channel & 1)) {
                   1238:                clock = 1;
                   1239:                data1 = ((ar5k_bitswap(ath_channel - 24, 8) & 0xff) << 2)
                   1240:                    | (clock << 1) | (1 << 10) | 1;
                   1241:        } else {
                   1242:                clock = 0;
                   1243:                data1 = ((ar5k_bitswap((ath_channel - 24) / 2, 8) & 0xff) << 2)
                   1244:                    | (clock << 1) | (1 << 10) | 1;
                   1245:        }
                   1246:
                   1247:        AR5K_PHY_WRITE(0x27, (data1 & 0xff) | ((data0 & 0xff) << 8));
                   1248:        AR5K_PHY_WRITE(0x34, ((data1 >> 8) & 0xff) | (data0 & 0xff00));
                   1249:
                   1250:        return (AH_TRUE);
                   1251: }
                   1252:
                   1253: HAL_BOOL
                   1254: ar5k_ar5112_channel(struct ath_hal *hal, HAL_CHANNEL *channel)
                   1255: {
                   1256:        u_int32_t data, data0, data1, data2;
                   1257:        u_int16_t c;
                   1258:
                   1259:        data = data0 = data1 = data2 = 0;
                   1260:        c = channel->c_channel;
                   1261:
                   1262:        /*
                   1263:         * Set the channel on the AR5112 or newer
                   1264:         */
                   1265:        if (c < 4800) {
                   1266:                if (!((c - 2224) % 5)) {
                   1267:                        data0 = ((2 * (c - 704)) - 3040) / 10;
                   1268:                        data1 = 1;
                   1269:                } else if (!((c - 2192) % 5)) {
                   1270:                        data0 = ((2 * (c - 672)) - 3040) / 10;
                   1271:                        data1 = 0;
                   1272:                } else
                   1273:                        return (AH_FALSE);
                   1274:
                   1275:                data0 = ar5k_bitswap((data0 << 2) & 0xff, 8);
                   1276:        } else {
                   1277:                if (!(c % 20) && c >= 5120) {
                   1278:                        data0 = ar5k_bitswap(((c - 4800) / 20 << 2), 8);
                   1279:                        data2 = ar5k_bitswap(3, 2);
                   1280:                } else if (!(c % 10)) {
                   1281:                        data0 = ar5k_bitswap(((c - 4800) / 10 << 1), 8);
                   1282:                        data2 = ar5k_bitswap(2, 2);
                   1283:                } else if (!(c % 5)) {
                   1284:                        data0 = ar5k_bitswap((c - 4800) / 5, 8);
                   1285:                        data2 = ar5k_bitswap(1, 2);
                   1286:                } else
                   1287:                        return (AH_FALSE);
                   1288:        }
                   1289:
                   1290:        data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001;
                   1291:
                   1292:        AR5K_PHY_WRITE(0x27, data & 0xff);
                   1293:        AR5K_PHY_WRITE(0x36, (data >> 8) & 0x7f);
                   1294:
                   1295:        return (AH_TRUE);
                   1296: }
                   1297:
                   1298: u_int
                   1299: ar5k_rfregs_op(u_int32_t *rf, u_int32_t offset, u_int32_t reg, u_int32_t bits,
                   1300:     u_int32_t first, u_int32_t col, HAL_BOOL set)
                   1301: {
                   1302:        u_int32_t mask, entry, last, data, shift, position;
                   1303:        int32_t left;
                   1304:        int i;
                   1305:
                   1306:        if (rf == NULL) {
                   1307:                /* should not happen */
                   1308:                return (0);
                   1309:        }
                   1310:
                   1311:        if (!(col <= 3 && bits <= 32 && first + bits <= 319)) {
                   1312:                AR5K_PRINTF("invalid values at offset %u\n", offset);
                   1313:                return (0);
                   1314:        }
                   1315:
                   1316:        entry = ((first - 1) / 8) + offset;
                   1317:        position = (first - 1) % 8;
                   1318:
                   1319:        if (set == AH_TRUE)
                   1320:                data = ar5k_bitswap(reg, bits);
                   1321:
                   1322:        for (i = shift = 0, left = bits; left > 0; position = 0, entry++, i++) {
                   1323:                last = (position + left > 8) ? 8 : position + left;
                   1324:                mask = (((1 << last) - 1) ^ ((1 << position) - 1)) <<
                   1325:                    (col * 8);
                   1326:
                   1327:                if (set == AH_TRUE) {
                   1328:                        rf[entry] &= ~mask;
                   1329:                        rf[entry] |= ((data << position) << (col * 8)) & mask;
                   1330:                        data >>= (8 - position);
                   1331:                } else {
                   1332:                        data = (((rf[entry] & mask) >> (col * 8)) >>
                   1333:                            position) << shift;
                   1334:                        shift += last - position;
                   1335:                }
                   1336:
                   1337:                left -= 8 - position;
                   1338:        }
                   1339:
                   1340:        data = set == AH_TRUE ? 1 : ar5k_bitswap(data, bits);
                   1341:
                   1342:        return (data);
                   1343: }
                   1344:
                   1345: u_int32_t
                   1346: ar5k_rfregs_gainf_corr(struct ath_hal *hal)
                   1347: {
                   1348:        u_int32_t mix, step;
                   1349:        u_int32_t *rf;
                   1350:
                   1351:        if (hal->ah_rf_banks == NULL)
                   1352:                return (0);
                   1353:
                   1354:        rf = hal->ah_rf_banks;
                   1355:        hal->ah_gain.g_f_corr = 0;
                   1356:
                   1357:        if (ar5k_rfregs_op(rf, hal->ah_offset[7], 0, 1, 36, 0, AH_FALSE) != 1)
                   1358:                return (0);
                   1359:
                   1360:        step = ar5k_rfregs_op(rf, hal->ah_offset[7], 0, 4, 32, 0, AH_FALSE);
                   1361:        mix = hal->ah_gain.g_step->gos_param[0];
                   1362:
                   1363:        switch (mix) {
                   1364:        case 3:
                   1365:                hal->ah_gain.g_f_corr = step * 2;
                   1366:                break;
                   1367:        case 2:
                   1368:                hal->ah_gain.g_f_corr = (step - 5) * 2;
                   1369:                break;
                   1370:        case 1:
                   1371:                hal->ah_gain.g_f_corr = step;
                   1372:                break;
                   1373:        default:
                   1374:                hal->ah_gain.g_f_corr = 0;
                   1375:                break;
                   1376:        }
                   1377:
                   1378:        return (hal->ah_gain.g_f_corr);
                   1379: }
                   1380:
                   1381: HAL_BOOL
                   1382: ar5k_rfregs_gain_readback(struct ath_hal *hal)
                   1383: {
                   1384:        u_int32_t step, mix, level[4];
                   1385:        u_int32_t *rf;
                   1386:
                   1387:        if (hal->ah_rf_banks == NULL)
                   1388:                return (0);
                   1389:
                   1390:        rf = hal->ah_rf_banks;
                   1391:
                   1392:        if (hal->ah_radio == AR5K_AR5111) {
                   1393:                step = ar5k_rfregs_op(rf, hal->ah_offset[7],
                   1394:                    0, 6, 37, 0, AH_FALSE);
                   1395:                level[0] = 0;
                   1396:                level[1] = (step == 0x3f) ? 0x32 : step + 4;
                   1397:                level[2] = (step != 0x3f) ? 0x40 : level[0];
                   1398:                level[3] = level[2] + 0x32;
                   1399:
                   1400:                hal->ah_gain.g_high = level[3] -
                   1401:                    (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
                   1402:                hal->ah_gain.g_low = level[0] +
                   1403:                    (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
                   1404:        } else {
                   1405:                mix = ar5k_rfregs_op(rf, hal->ah_offset[7],
                   1406:                    0, 1, 36, 0, AH_FALSE);
                   1407:                level[0] = level[2] = 0;
                   1408:
                   1409:                if (mix == 1) {
                   1410:                        level[1] = level[3] = 83;
                   1411:                } else {
                   1412:                        level[1] = level[3] = 107;
                   1413:                        hal->ah_gain.g_high = 55;
                   1414:                }
                   1415:        }
                   1416:
                   1417:        return ((hal->ah_gain.g_current >= level[0] &&
                   1418:            hal->ah_gain.g_current <= level[1]) ||
                   1419:            (hal->ah_gain.g_current >= level[2] &&
                   1420:            hal->ah_gain.g_current <= level[3]));
                   1421: }
                   1422:
                   1423: int32_t
                   1424: ar5k_rfregs_gain_adjust(struct ath_hal *hal)
                   1425: {
                   1426:        int ret = 0;
                   1427:        const struct ar5k_gain_opt *go;
                   1428:
                   1429:        go = hal->ah_radio == AR5K_AR5111 ?
                   1430:            &ar5111_gain_opt : &ar5112_gain_opt;
                   1431:
                   1432:        hal->ah_gain.g_step = &go->go_step[hal->ah_gain.g_step_idx];
                   1433:
                   1434:        if (hal->ah_gain.g_current >= hal->ah_gain.g_high) {
                   1435:                if (hal->ah_gain.g_step_idx == 0)
                   1436:                        return (-1);
                   1437:                for (hal->ah_gain.g_target = hal->ah_gain.g_current;
                   1438:                    hal->ah_gain.g_target >=  hal->ah_gain.g_high &&
                   1439:                    hal->ah_gain.g_step_idx > 0;
                   1440:                    hal->ah_gain.g_step =
                   1441:                    &go->go_step[hal->ah_gain.g_step_idx]) {
                   1442:                        hal->ah_gain.g_target -= 2 *
                   1443:                            (go->go_step[--(hal->ah_gain.g_step_idx)].gos_gain -
                   1444:                            hal->ah_gain.g_step->gos_gain);
                   1445:                }
                   1446:
                   1447:                ret = 1;
                   1448:                goto done;
                   1449:        }
                   1450:
                   1451:        if (hal->ah_gain.g_current <= hal->ah_gain.g_low) {
                   1452:                if (hal->ah_gain.g_step_idx == (go->go_steps_count - 1))
                   1453:                        return (-2);
                   1454:                for (hal->ah_gain.g_target = hal->ah_gain.g_current;
                   1455:                    hal->ah_gain.g_target <=  hal->ah_gain.g_low &&
                   1456:                    hal->ah_gain.g_step_idx < (go->go_steps_count - 1);
                   1457:                    hal->ah_gain.g_step =
                   1458:                    &go->go_step[hal->ah_gain.g_step_idx]) {
                   1459:                        hal->ah_gain.g_target -= 2 *
                   1460:                            (go->go_step[++(hal->ah_gain.g_step_idx)].gos_gain -
                   1461:                            hal->ah_gain.g_step->gos_gain);
                   1462:                }
                   1463:
                   1464:                ret = 2;
                   1465:                goto done;
                   1466:        }
                   1467:
                   1468:  done:
                   1469: #ifdef AR5K_DEBUG
                   1470:        AR5K_PRINTF("ret %d, gain step %u, current gain %u, target gain %u\n",
                   1471:            ret,
                   1472:            hal->ah_gain.g_step_idx,
                   1473:            hal->ah_gain.g_current,
                   1474:            hal->ah_gain.g_target);
                   1475: #endif
                   1476:
                   1477:        return (ret);
                   1478: }
                   1479:
                   1480: HAL_BOOL
                   1481: ar5k_rfregs(struct ath_hal *hal, HAL_CHANNEL *channel, u_int mode)
                   1482: {
                   1483:        ar5k_rfgain_t *func = NULL;
                   1484:        HAL_BOOL ret;
                   1485:
                   1486:        if (hal->ah_radio == AR5K_AR5111) {
                   1487:                hal->ah_rf_banks_size = sizeof(ar5111_rf);
                   1488:                func = ar5k_ar5111_rfregs;
                   1489:        } else if (hal->ah_radio == AR5K_AR5112) {
                   1490:                if (hal->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
                   1491:                        hal->ah_rf_banks_size = sizeof(ar5112a_rf);
                   1492:                else
                   1493:                        hal->ah_rf_banks_size = sizeof(ar5112_rf);
                   1494:                func = ar5k_ar5112_rfregs;
                   1495:        } else
                   1496:                return (AH_FALSE);
                   1497:
                   1498:        if (hal->ah_rf_banks == NULL) {
                   1499:                /* XXX do extra checks? */
                   1500:                if ((hal->ah_rf_banks = malloc(hal->ah_rf_banks_size,
                   1501:                    M_DEVBUF, M_NOWAIT)) == NULL) {
                   1502:                        AR5K_PRINT("out of memory\n");
                   1503:                        return (AH_FALSE);
                   1504:                }
                   1505:        }
                   1506:
                   1507:        ret = (func)(hal, channel, mode);
                   1508:
                   1509:        if (ret == AH_TRUE)
                   1510:                hal->ah_rf_gain = HAL_RFGAIN_INACTIVE;
                   1511:
                   1512:        return (ret);
                   1513: }
                   1514:
                   1515: HAL_BOOL
                   1516: ar5k_ar5111_rfregs(struct ath_hal *hal, HAL_CHANNEL *channel, u_int mode)
                   1517: {
                   1518:        struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
                   1519:        const u_int rf_size = AR5K_ELEMENTS(ar5111_rf);
                   1520:        u_int32_t *rf;
                   1521:        int i, obdb = -1, bank = -1;
                   1522:        u_int32_t ee_mode;
                   1523:
                   1524:        AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
                   1525:
                   1526:        rf = hal->ah_rf_banks;
                   1527:
                   1528:        /* Copy values to modify them */
                   1529:        for (i = 0; i < rf_size; i++) {
                   1530:                if (ar5111_rf[i].rf_bank >=
                   1531:                    AR5K_AR5111_INI_RF_MAX_BANKS) {
                   1532:                        AR5K_PRINT("invalid bank\n");
                   1533:                        return (AH_FALSE);
                   1534:                }
                   1535:
                   1536:                if (bank != ar5111_rf[i].rf_bank) {
                   1537:                        bank = ar5111_rf[i].rf_bank;
                   1538:                        hal->ah_offset[bank] = i;
                   1539:                }
                   1540:
                   1541:                rf[i] = ar5111_rf[i].rf_value[mode];
                   1542:        }
                   1543:
                   1544:        if (channel->c_channel_flags & IEEE80211_CHAN_2GHZ) {
                   1545:                if (channel->c_channel_flags & IEEE80211_CHAN_B)
                   1546:                        ee_mode = AR5K_EEPROM_MODE_11B;
                   1547:                else
                   1548:                        ee_mode = AR5K_EEPROM_MODE_11G;
                   1549:                obdb = 0;
                   1550:
                   1551:                if (!ar5k_rfregs_op(rf, hal->ah_offset[0],
                   1552:                        ee->ee_ob[ee_mode][obdb], 3, 119, 0, AH_TRUE))
                   1553:                        return (AH_FALSE);
                   1554:
                   1555:                if (!ar5k_rfregs_op(rf, hal->ah_offset[0],
                   1556:                        ee->ee_ob[ee_mode][obdb], 3, 122, 0, AH_TRUE))
                   1557:                        return (AH_FALSE);
                   1558:
                   1559:                obdb = 1;
                   1560:        } else {
                   1561:                /* For 11a, Turbo and XR */
                   1562:                ee_mode = AR5K_EEPROM_MODE_11A;
                   1563:                obdb = channel->c_channel >= 5725 ? 3 :
                   1564:                    (channel->c_channel >= 5500 ? 2 :
                   1565:                        (channel->c_channel >= 5260 ? 1 :
                   1566:                            (channel->c_channel > 4000 ? 0 : -1)));
                   1567:
                   1568:                if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
                   1569:                        ee->ee_pwd_84, 1, 51, 3, AH_TRUE))
                   1570:                        return (AH_FALSE);
                   1571:
                   1572:                if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
                   1573:                        ee->ee_pwd_90, 1, 45, 3, AH_TRUE))
                   1574:                        return (AH_FALSE);
                   1575:        }
                   1576:
                   1577:        if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
                   1578:                !ee->ee_xpd[ee_mode], 1, 95, 0, AH_TRUE))
                   1579:                return (AH_FALSE);
                   1580:
                   1581:        if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
                   1582:                ee->ee_x_gain[ee_mode], 4, 96, 0, AH_TRUE))
                   1583:                return (AH_FALSE);
                   1584:
                   1585:        if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
                   1586:                obdb >= 0 ? ee->ee_ob[ee_mode][obdb] : 0, 3, 104, 0, AH_TRUE))
                   1587:                return (AH_FALSE);
                   1588:
                   1589:        if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
                   1590:                obdb >= 0 ? ee->ee_db[ee_mode][obdb] : 0, 3, 107, 0, AH_TRUE))
                   1591:                return (AH_FALSE);
                   1592:
                   1593:        if (!ar5k_rfregs_op(rf, hal->ah_offset[7],
                   1594:                ee->ee_i_gain[ee_mode], 6, 29, 0, AH_TRUE))
                   1595:                return (AH_FALSE);
                   1596:
                   1597:        if (!ar5k_rfregs_op(rf, hal->ah_offset[7],
                   1598:                ee->ee_xpd[ee_mode], 1, 4, 0, AH_TRUE))
                   1599:                return (AH_FALSE);
                   1600:
                   1601:        /* Write RF values */
                   1602:        for (i = 0; i < rf_size; i++) {
                   1603:                AR5K_REG_WAIT(i);
                   1604:                AR5K_REG_WRITE(ar5111_rf[i].rf_register, rf[i]);
                   1605:        }
                   1606:
                   1607:        return (AH_TRUE);
                   1608: }
                   1609:
                   1610: HAL_BOOL
                   1611: ar5k_ar5112_rfregs(struct ath_hal *hal, HAL_CHANNEL *channel, u_int mode)
                   1612: {
                   1613:        struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
                   1614:        u_int rf_size;
                   1615:        u_int32_t *rf;
                   1616:        int i, obdb = -1, bank = -1;
                   1617:        u_int32_t ee_mode;
                   1618:        const struct ar5k_ini_rf *rf_ini;
                   1619:
                   1620:        AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
                   1621:
                   1622:        rf = hal->ah_rf_banks;
                   1623:
                   1624:        if (hal->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
                   1625:                rf_ini = ar5112a_rf;
                   1626:                rf_size = AR5K_ELEMENTS(ar5112a_rf);
                   1627:        } else {
                   1628:                rf_ini = ar5112_rf;
                   1629:                rf_size = AR5K_ELEMENTS(ar5112_rf);
                   1630:        }
                   1631:
                   1632:        /* Copy values to modify them */
                   1633:        for (i = 0; i < rf_size; i++) {
                   1634:                if (rf_ini[i].rf_bank >=
                   1635:                    AR5K_AR5112_INI_RF_MAX_BANKS) {
                   1636:                        AR5K_PRINT("invalid bank\n");
                   1637:                        return (AH_FALSE);
                   1638:                }
                   1639:
                   1640:                if (bank != rf_ini[i].rf_bank) {
                   1641:                        bank = rf_ini[i].rf_bank;
                   1642:                        hal->ah_offset[bank] = i;
                   1643:                }
                   1644:
                   1645:                rf[i] = rf_ini[i].rf_value[mode];
                   1646:        }
                   1647:
                   1648:        if (channel->c_channel_flags & IEEE80211_CHAN_2GHZ) {
                   1649:                if (channel->c_channel_flags & IEEE80211_CHAN_B)
                   1650:                        ee_mode = AR5K_EEPROM_MODE_11B;
                   1651:                else
                   1652:                        ee_mode = AR5K_EEPROM_MODE_11G;
                   1653:                obdb = 0;
                   1654:
                   1655:                if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
                   1656:                        ee->ee_ob[ee_mode][obdb], 3, 287, 0, AH_TRUE))
                   1657:                        return (AH_FALSE);
                   1658:
                   1659:                if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
                   1660:                        ee->ee_ob[ee_mode][obdb], 3, 290, 0, AH_TRUE))
                   1661:                        return (AH_FALSE);
                   1662:        } else {
                   1663:                /* For 11a, Turbo and XR */
                   1664:                ee_mode = AR5K_EEPROM_MODE_11A;
                   1665:                obdb = channel->c_channel >= 5725 ? 3 :
                   1666:                    (channel->c_channel >= 5500 ? 2 :
                   1667:                        (channel->c_channel >= 5260 ? 1 :
                   1668:                            (channel->c_channel > 4000 ? 0 : -1)));
                   1669:
                   1670:                if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
                   1671:                        ee->ee_ob[ee_mode][obdb], 3, 279, 0, AH_TRUE))
                   1672:                        return (AH_FALSE);
                   1673:
                   1674:                if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
                   1675:                        ee->ee_ob[ee_mode][obdb], 3, 282, 0, AH_TRUE))
                   1676:                        return (AH_FALSE);
                   1677:        }
                   1678:
                   1679: #ifdef notyet
                   1680:        ar5k_rfregs_op(rf, hal->ah_offset[6],
                   1681:            ee->ee_x_gain[ee_mode], 2, 270, 0, AH_TRUE);
                   1682:        ar5k_rfregs_op(rf, hal->ah_offset[6],
                   1683:            ee->ee_x_gain[ee_mode], 2, 257, 0, AH_TRUE);
                   1684: #endif
                   1685:
                   1686:        if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
                   1687:                ee->ee_xpd[ee_mode], 1, 302, 0, AH_TRUE))
                   1688:                return (AH_FALSE);
                   1689:
                   1690:        if (!ar5k_rfregs_op(rf, hal->ah_offset[7],
                   1691:                ee->ee_i_gain[ee_mode], 6, 14, 0, AH_TRUE))
                   1692:                return (AH_FALSE);
                   1693:
                   1694:        /* Write RF values */
                   1695:        for (i = 0; i < rf_size; i++)
                   1696:                AR5K_REG_WRITE(ar5112_rf[i].rf_register, rf[i]);
                   1697:
                   1698:        return (AH_TRUE);
                   1699: }
                   1700:
                   1701: HAL_BOOL
                   1702: ar5k_rfgain(struct ath_hal *hal, u_int phy, u_int freq)
                   1703: {
                   1704:        int i;
                   1705:
                   1706:        switch (phy) {
                   1707:        case AR5K_INI_PHY_5111:
                   1708:        case AR5K_INI_PHY_5112:
                   1709:                break;
                   1710:        default:
                   1711:                return (AH_FALSE);
                   1712:        }
                   1713:
                   1714:        switch (freq) {
                   1715:        case AR5K_INI_RFGAIN_2GHZ:
                   1716:        case AR5K_INI_RFGAIN_5GHZ:
                   1717:                break;
                   1718:        default:
                   1719:                return (AH_FALSE);
                   1720:        }
                   1721:
                   1722:        for (i = 0; i < AR5K_ELEMENTS(ar5k_rfg); i++) {
                   1723:                AR5K_REG_WAIT(i);
                   1724:                AR5K_REG_WRITE((u_int32_t)ar5k_rfg[i].rfg_register,
                   1725:                    ar5k_rfg[i].rfg_value[phy][freq]);
                   1726:        }
                   1727:
                   1728:        return (AH_TRUE);
                   1729: }
                   1730:
                   1731: /*
                   1732:  * Common TX power setup
                   1733:  */
                   1734: void
                   1735: ar5k_txpower_table(struct ath_hal *hal, HAL_CHANNEL *channel, int16_t max_power)
                   1736: {
                   1737:        u_int16_t txpower, *rates;
                   1738:        int i, min, max, n;
                   1739:
                   1740:        rates = hal->ah_txpower.txp_rates;
                   1741:
                   1742:        txpower = AR5K_TUNE_DEFAULT_TXPOWER * 2;
                   1743:        if (max_power > txpower) {
                   1744:                txpower = max_power > AR5K_TUNE_MAX_TXPOWER ?
                   1745:                    AR5K_TUNE_MAX_TXPOWER : max_power;
                   1746:        }
                   1747:
                   1748:        for (i = 0; i < AR5K_MAX_RATES; i++)
                   1749:                rates[i] = txpower;
                   1750:
                   1751:        /* XXX setup target powers by rate */
                   1752:
                   1753:        hal->ah_txpower.txp_min = rates[7];
                   1754:        hal->ah_txpower.txp_max = rates[0];
                   1755:        hal->ah_txpower.txp_ofdm = rates[0];
                   1756:
                   1757:        /* Calculate the power table */
                   1758:        n = AR5K_ELEMENTS(hal->ah_txpower.txp_pcdac);
                   1759:        min = AR5K_EEPROM_PCDAC_START;
                   1760:        max = AR5K_EEPROM_PCDAC_STOP;
                   1761:        for (i = 0; i < n; i += AR5K_EEPROM_PCDAC_STEP)
                   1762:                hal->ah_txpower.txp_pcdac[i] =
                   1763: #ifdef notyet
                   1764:                    min + ((i * (max - min)) / n);
                   1765: #else
                   1766:                    min;
                   1767: #endif
                   1768: }

CVSweb