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

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

1.1       nbrk        1: /*     $OpenBSD: ar5212.c,v 1.40 2007/04/10 17:47:55 miod 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 the Atheros AR5001 Wireless LAN chipset
                     21:  * (AR5212 + AR5111/AR5112).
                     22:  */
                     23:
                     24: #include <dev/ic/ar5xxx.h>
                     25: #include <dev/ic/ar5212reg.h>
                     26: #include <dev/ic/ar5212var.h>
                     27:
                     28: HAL_BOOL        ar5k_ar5212_nic_reset(struct ath_hal *, u_int32_t);
                     29: HAL_BOOL        ar5k_ar5212_nic_wakeup(struct ath_hal *, u_int16_t);
                     30: u_int16_t       ar5k_ar5212_radio_revision(struct ath_hal *, HAL_CHIP);
                     31: const void      ar5k_ar5212_fill(struct ath_hal *);
                     32: HAL_BOOL        ar5k_ar5212_txpower(struct ath_hal *, HAL_CHANNEL *, u_int);
                     33:
                     34: /*
                     35:  * Initial register setting for the AR5212
                     36:  */
                     37: static const struct ar5k_ar5212_ini ar5212_ini[] =
                     38:     AR5K_AR5212_INI;
                     39: static const struct ar5k_ar5212_ini_mode ar5212_mode[] =
                     40:     AR5K_AR5212_INI_MODE;
                     41:
                     42: AR5K_HAL_FUNCTIONS(extern, ar5k_ar5212,);
                     43:
                     44: const void
                     45: ar5k_ar5212_fill(struct ath_hal *hal)
                     46: {
                     47:        hal->ah_magic = AR5K_AR5212_MAGIC;
                     48:
                     49:        /*
                     50:         * Init/Exit functions
                     51:         */
                     52:        AR5K_HAL_FUNCTION(hal, ar5212, get_rate_table);
                     53:        AR5K_HAL_FUNCTION(hal, ar5212, detach);
                     54:
                     55:        /*
                     56:         * Reset functions
                     57:         */
                     58:        AR5K_HAL_FUNCTION(hal, ar5212, reset);
                     59:        AR5K_HAL_FUNCTION(hal, ar5212, set_opmode);
                     60:        AR5K_HAL_FUNCTION(hal, ar5212, calibrate);
                     61:
                     62:        /*
                     63:         * TX functions
                     64:         */
                     65:        AR5K_HAL_FUNCTION(hal, ar5212, update_tx_triglevel);
                     66:        AR5K_HAL_FUNCTION(hal, ar5212, setup_tx_queue);
                     67:        AR5K_HAL_FUNCTION(hal, ar5212, setup_tx_queueprops);
                     68:        AR5K_HAL_FUNCTION(hal, ar5212, release_tx_queue);
                     69:        AR5K_HAL_FUNCTION(hal, ar5212, reset_tx_queue);
                     70:        AR5K_HAL_FUNCTION(hal, ar5212, get_tx_buf);
                     71:        AR5K_HAL_FUNCTION(hal, ar5212, put_tx_buf);
                     72:        AR5K_HAL_FUNCTION(hal, ar5212, tx_start);
                     73:        AR5K_HAL_FUNCTION(hal, ar5212, stop_tx_dma);
                     74:        AR5K_HAL_FUNCTION(hal, ar5212, setup_tx_desc);
                     75:        AR5K_HAL_FUNCTION(hal, ar5212, setup_xtx_desc);
                     76:        AR5K_HAL_FUNCTION(hal, ar5212, fill_tx_desc);
                     77:        AR5K_HAL_FUNCTION(hal, ar5212, proc_tx_desc);
                     78:        AR5K_HAL_FUNCTION(hal, ar5212, has_veol);
                     79:
                     80:        /*
                     81:         * RX functions
                     82:         */
                     83:        AR5K_HAL_FUNCTION(hal, ar5212, get_rx_buf);
                     84:        AR5K_HAL_FUNCTION(hal, ar5212, put_rx_buf);
                     85:        AR5K_HAL_FUNCTION(hal, ar5212, start_rx);
                     86:        AR5K_HAL_FUNCTION(hal, ar5212, stop_rx_dma);
                     87:        AR5K_HAL_FUNCTION(hal, ar5212, start_rx_pcu);
                     88:        AR5K_HAL_FUNCTION(hal, ar5212, stop_pcu_recv);
                     89:        AR5K_HAL_FUNCTION(hal, ar5212, set_mcast_filter);
                     90:        AR5K_HAL_FUNCTION(hal, ar5212, set_mcast_filterindex);
                     91:        AR5K_HAL_FUNCTION(hal, ar5212, clear_mcast_filter_idx);
                     92:        AR5K_HAL_FUNCTION(hal, ar5212, get_rx_filter);
                     93:        AR5K_HAL_FUNCTION(hal, ar5212, set_rx_filter);
                     94:        AR5K_HAL_FUNCTION(hal, ar5212, setup_rx_desc);
                     95:        AR5K_HAL_FUNCTION(hal, ar5212, proc_rx_desc);
                     96:        AR5K_HAL_FUNCTION(hal, ar5212, set_rx_signal);
                     97:
                     98:        /*
                     99:         * Misc functions
                    100:         */
                    101:        AR5K_HAL_FUNCTION(hal, ar5212, dump_state);
                    102:        AR5K_HAL_FUNCTION(hal, ar5212, get_diag_state);
                    103:        AR5K_HAL_FUNCTION(hal, ar5212, get_lladdr);
                    104:        AR5K_HAL_FUNCTION(hal, ar5212, set_lladdr);
                    105:        AR5K_HAL_FUNCTION(hal, ar5212, set_regdomain);
                    106:        AR5K_HAL_FUNCTION(hal, ar5212, set_ledstate);
                    107:        AR5K_HAL_FUNCTION(hal, ar5212, set_associd);
                    108:        AR5K_HAL_FUNCTION(hal, ar5212, set_gpio_input);
                    109:        AR5K_HAL_FUNCTION(hal, ar5212, set_gpio_output);
                    110:        AR5K_HAL_FUNCTION(hal, ar5212, get_gpio);
                    111:        AR5K_HAL_FUNCTION(hal, ar5212, set_gpio);
                    112:        AR5K_HAL_FUNCTION(hal, ar5212, set_gpio_intr);
                    113:        AR5K_HAL_FUNCTION(hal, ar5212, get_tsf32);
                    114:        AR5K_HAL_FUNCTION(hal, ar5212, get_tsf64);
                    115:        AR5K_HAL_FUNCTION(hal, ar5212, reset_tsf);
                    116:        AR5K_HAL_FUNCTION(hal, ar5212, get_regdomain);
                    117:        AR5K_HAL_FUNCTION(hal, ar5212, detect_card_present);
                    118:        AR5K_HAL_FUNCTION(hal, ar5212, update_mib_counters);
                    119:        AR5K_HAL_FUNCTION(hal, ar5212, get_rf_gain);
                    120:        AR5K_HAL_FUNCTION(hal, ar5212, set_slot_time);
                    121:        AR5K_HAL_FUNCTION(hal, ar5212, get_slot_time);
                    122:        AR5K_HAL_FUNCTION(hal, ar5212, set_ack_timeout);
                    123:        AR5K_HAL_FUNCTION(hal, ar5212, get_ack_timeout);
                    124:        AR5K_HAL_FUNCTION(hal, ar5212, set_cts_timeout);
                    125:        AR5K_HAL_FUNCTION(hal, ar5212, get_cts_timeout);
                    126:
                    127:        /*
                    128:         * Key table (WEP) functions
                    129:         */
                    130:        AR5K_HAL_FUNCTION(hal, ar5212, is_cipher_supported);
                    131:        AR5K_HAL_FUNCTION(hal, ar5212, get_keycache_size);
                    132:        AR5K_HAL_FUNCTION(hal, ar5212, reset_key);
                    133:        AR5K_HAL_FUNCTION(hal, ar5212, is_key_valid);
                    134:        AR5K_HAL_FUNCTION(hal, ar5212, set_key);
                    135:        AR5K_HAL_FUNCTION(hal, ar5212, set_key_lladdr);
                    136:
                    137:        /*
                    138:         * Power management functions
                    139:         */
                    140:        AR5K_HAL_FUNCTION(hal, ar5212, set_power);
                    141:        AR5K_HAL_FUNCTION(hal, ar5212, get_power_mode);
                    142:        AR5K_HAL_FUNCTION(hal, ar5212, query_pspoll_support);
                    143:        AR5K_HAL_FUNCTION(hal, ar5212, init_pspoll);
                    144:        AR5K_HAL_FUNCTION(hal, ar5212, enable_pspoll);
                    145:        AR5K_HAL_FUNCTION(hal, ar5212, disable_pspoll);
                    146:
                    147:        /*
                    148:         * Beacon functions
                    149:         */
                    150:        AR5K_HAL_FUNCTION(hal, ar5212, init_beacon);
                    151:        AR5K_HAL_FUNCTION(hal, ar5212, set_beacon_timers);
                    152:        AR5K_HAL_FUNCTION(hal, ar5212, reset_beacon);
                    153:        AR5K_HAL_FUNCTION(hal, ar5212, wait_for_beacon);
                    154:
                    155:        /*
                    156:         * Interrupt functions
                    157:         */
                    158:        AR5K_HAL_FUNCTION(hal, ar5212, is_intr_pending);
                    159:        AR5K_HAL_FUNCTION(hal, ar5212, get_isr);
                    160:        AR5K_HAL_FUNCTION(hal, ar5212, get_intr);
                    161:        AR5K_HAL_FUNCTION(hal, ar5212, set_intr);
                    162:
                    163:        /*
                    164:         * Chipset functions (ar5k-specific, non-HAL)
                    165:         */
                    166:        AR5K_HAL_FUNCTION(hal, ar5212, get_capabilities);
                    167:        AR5K_HAL_FUNCTION(hal, ar5212, radar_alert);
                    168:
                    169:        /*
                    170:         * EEPROM access
                    171:         */
                    172:        AR5K_HAL_FUNCTION(hal, ar5212, eeprom_is_busy);
                    173:        AR5K_HAL_FUNCTION(hal, ar5212, eeprom_read);
                    174:        AR5K_HAL_FUNCTION(hal, ar5212, eeprom_write);
                    175:
                    176:        /*
                    177:         * Unused functions or functions not implemented
                    178:         */
                    179:        AR5K_HAL_FUNCTION(hal, ar5212, set_bssid_mask);
                    180:        AR5K_HAL_FUNCTION(hal, ar5212, get_tx_queueprops);
                    181:        AR5K_HAL_FUNCTION(hal, ar5212, num_tx_pending);
                    182:        AR5K_HAL_FUNCTION(hal, ar5212, phy_disable);
                    183:        AR5K_HAL_FUNCTION(hal, ar5212, set_txpower_limit);
                    184:        AR5K_HAL_FUNCTION(hal, ar5212, set_def_antenna);
                    185:        AR5K_HAL_FUNCTION(hal, ar5212, get_def_antenna);
                    186: #ifdef notyet
                    187:        AR5K_HAL_FUNCTION(hal, ar5212, set_capability);
                    188:        AR5K_HAL_FUNCTION(hal, ar5212, proc_mib_event);
                    189:        AR5K_HAL_FUNCTION(hal, ar5212, get_tx_inter_queue);
                    190: #endif
                    191: }
                    192:
                    193: struct ath_hal *
                    194: ar5k_ar5212_attach(u_int16_t device, void *sc, bus_space_tag_t st,
                    195:     bus_space_handle_t sh, int *status)
                    196: {
                    197:        struct ath_hal *hal = (struct ath_hal*) sc;
                    198:        u_int8_t mac[IEEE80211_ADDR_LEN];
                    199:        u_int32_t srev;
                    200:
                    201:        ar5k_ar5212_fill(hal);
                    202:
                    203:        /* Bring device out of sleep and reset its units */
                    204:        if (ar5k_ar5212_nic_wakeup(hal, AR5K_INIT_MODE) != AH_TRUE)
                    205:                return (NULL);
                    206:
                    207:        /* Get MAC, PHY and RADIO revisions */
                    208:        srev = AR5K_REG_READ(AR5K_AR5212_SREV);
                    209:        hal->ah_mac_srev = srev;
                    210:        hal->ah_mac_version = AR5K_REG_MS(srev, AR5K_AR5212_SREV_VER);
                    211:        hal->ah_mac_revision = AR5K_REG_MS(srev, AR5K_AR5212_SREV_REV);
                    212:        hal->ah_phy_revision = AR5K_REG_READ(AR5K_AR5212_PHY_CHIP_ID) &
                    213:            0x00ffffffff;
                    214:        hal->ah_radio_5ghz_revision =
                    215:            ar5k_ar5212_radio_revision(hal, HAL_CHIP_5GHZ);
                    216:        hal->ah_radio_2ghz_revision =
                    217:            ar5k_ar5212_radio_revision(hal, HAL_CHIP_2GHZ);
                    218:
                    219:        /* Single chip radio */
                    220:        if (hal->ah_radio_2ghz_revision == hal->ah_radio_5ghz_revision)
                    221:                hal->ah_radio_2ghz_revision = 0;
                    222:
                    223:        /* Identify the chipset (this has to be done in an early step) */
                    224:        hal->ah_version = AR5K_AR5212;
                    225:        hal->ah_radio = hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112 ?
                    226:            AR5K_AR5111 : AR5K_AR5112;
                    227:        hal->ah_phy = AR5K_AR5212_PHY(0);
                    228:
                    229:        bcopy(etherbroadcastaddr, mac, IEEE80211_ADDR_LEN);
                    230:        ar5k_ar5212_set_associd(hal, mac, 0, 0);
                    231:        ar5k_ar5212_get_lladdr(hal, mac);
                    232:        ar5k_ar5212_set_opmode(hal);
                    233:
                    234:        return (hal);
                    235: }
                    236:
                    237: HAL_BOOL
                    238: ar5k_ar5212_nic_reset(struct ath_hal *hal, u_int32_t val)
                    239: {
                    240:        HAL_BOOL ret = AH_FALSE;
                    241:        u_int32_t mask = val ? val : ~0;
                    242:
                    243:        /* Read-and-clear */
                    244:        AR5K_REG_READ(AR5K_AR5212_RXDP);
                    245:
                    246:        /*
                    247:         * Reset the device and wait until success
                    248:         */
                    249:        AR5K_REG_WRITE(AR5K_AR5212_RC, val);
                    250:
                    251:        /* Wait at least 128 PCI clocks */
                    252:        AR5K_DELAY(15);
                    253:
                    254:        val &=
                    255:            AR5K_AR5212_RC_PCU | AR5K_AR5212_RC_BB;
                    256:
                    257:        mask &=
                    258:            AR5K_AR5212_RC_PCU | AR5K_AR5212_RC_BB;
                    259:
                    260:        ret = ar5k_register_timeout(hal, AR5K_AR5212_RC, mask, val, AH_FALSE);
                    261:
                    262:        /*
                    263:         * Reset configuration register
                    264:         */
                    265:        if ((val & AR5K_AR5212_RC_PCU) == 0)
                    266:                AR5K_REG_WRITE(AR5K_AR5212_CFG, AR5K_AR5212_INIT_CFG);
                    267:
                    268:        return (ret);
                    269: }
                    270:
                    271: HAL_BOOL
                    272: ar5k_ar5212_nic_wakeup(struct ath_hal *hal, u_int16_t flags)
                    273: {
                    274:        u_int32_t turbo, mode, clock;
                    275:
                    276:        turbo = 0;
                    277:        mode = 0;
                    278:        clock = 0;
                    279:
                    280:        /*
                    281:         * Get channel mode flags
                    282:         */
                    283:
                    284:        if (hal->ah_radio >= AR5K_AR5112) {
                    285:                mode = AR5K_AR5212_PHY_MODE_RAD_AR5112;
                    286:                clock = AR5K_AR5212_PHY_PLL_AR5112;
                    287:        } else {
                    288:                mode = AR5K_AR5212_PHY_MODE_RAD_AR5111;
                    289:                clock = AR5K_AR5212_PHY_PLL_AR5111;
                    290:        }
                    291:
                    292:        if (flags & IEEE80211_CHAN_2GHZ) {
                    293:                mode |= AR5K_AR5212_PHY_MODE_FREQ_2GHZ;
                    294:                clock |= AR5K_AR5212_PHY_PLL_44MHZ;
                    295:        } else if (flags & IEEE80211_CHAN_5GHZ) {
                    296:                mode |= AR5K_AR5212_PHY_MODE_FREQ_5GHZ;
                    297:                clock |= AR5K_AR5212_PHY_PLL_40MHZ;
                    298:        } else {
                    299:                AR5K_PRINT("invalid radio frequency mode\n");
                    300:                return (AH_FALSE);
                    301:        }
                    302:
                    303:        if (flags & IEEE80211_CHAN_CCK) {
                    304:                mode |= AR5K_AR5212_PHY_MODE_MOD_CCK;
                    305:        } else if (flags & IEEE80211_CHAN_OFDM) {
                    306:                mode |= AR5K_AR5212_PHY_MODE_MOD_OFDM;
                    307:        } else if (flags & IEEE80211_CHAN_DYN) {
                    308:                mode |= AR5K_AR5212_PHY_MODE_MOD_DYN;
                    309:        } else {
                    310:                AR5K_PRINT("invalid radio frequency mode\n");
                    311:                return (AH_FALSE);
                    312:        }
                    313:
                    314:        if (flags & IEEE80211_CHAN_TURBO) {
                    315:                turbo = AR5K_AR5212_PHY_TURBO_MODE |
                    316:                    AR5K_AR5212_PHY_TURBO_SHORT;
                    317:        }
                    318:
                    319:        /*
                    320:         * Reset and wakeup the device
                    321:         */
                    322:
                    323:        /* ...reset chipset and PCI device */
                    324:        if (hal->ah_single_chip == AH_FALSE &&
                    325:            ar5k_ar5212_nic_reset(hal,
                    326:            AR5K_AR5212_RC_CHIP | AR5K_AR5212_RC_PCI) == AH_FALSE) {
                    327:                AR5K_PRINT("failed to reset the AR5212 + PCI chipset\n");
                    328:                return (AH_FALSE);
                    329:        }
                    330:
                    331:        /* ...wakeup */
                    332:        if (ar5k_ar5212_set_power(hal,
                    333:                HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) {
                    334:                AR5K_PRINT("failed to resume the AR5212 (again)\n");
                    335:                return (AH_FALSE);
                    336:        }
                    337:
                    338:        /* ...final warm reset */
                    339:        if (ar5k_ar5212_nic_reset(hal, 0) == AH_FALSE) {
                    340:                AR5K_PRINT("failed to warm reset the AR5212\n");
                    341:                return (AH_FALSE);
                    342:        }
                    343:
                    344:        /* ...set the PHY operating mode */
                    345:        AR5K_REG_WRITE(AR5K_AR5212_PHY_PLL, clock);
                    346:        AR5K_DELAY(300);
                    347:
                    348:        AR5K_REG_WRITE(AR5K_AR5212_PHY_MODE, mode);
                    349:        AR5K_REG_WRITE(AR5K_AR5212_PHY_TURBO, turbo);
                    350:
                    351:        return (AH_TRUE);
                    352: }
                    353:
                    354: u_int16_t
                    355: ar5k_ar5212_radio_revision(struct ath_hal *hal, HAL_CHIP chip)
                    356: {
                    357:        int i;
                    358:        u_int32_t srev;
                    359:        u_int16_t ret;
                    360:
                    361:        /*
                    362:         * Set the radio chip access register
                    363:         */
                    364:        switch (chip) {
                    365:        case HAL_CHIP_2GHZ:
                    366:                AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_2GHZ);
                    367:                break;
                    368:        case HAL_CHIP_5GHZ:
                    369:                AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);
                    370:                break;
                    371:        default:
                    372:                return (0);
                    373:        }
                    374:
                    375:        AR5K_DELAY(2000);
                    376:
                    377:        /* ...wait until PHY is ready and read the selected radio revision */
                    378:        AR5K_REG_WRITE(AR5K_AR5212_PHY(0x34), 0x00001c16);
                    379:
                    380:        for (i = 0; i < 8; i++)
                    381:                AR5K_REG_WRITE(AR5K_AR5212_PHY(0x20), 0x00010000);
                    382:        srev = (AR5K_REG_READ(AR5K_AR5212_PHY(0x100)) >> 24) & 0xff;
                    383:
                    384:        ret = ar5k_bitswap(((srev & 0xf0) >> 4) | ((srev & 0x0f) << 4), 8);
                    385:
                    386:        /* Reset to the 5GHz mode */
                    387:        AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);
                    388:
                    389:        return (ret);
                    390: }
                    391:
                    392: const HAL_RATE_TABLE *
                    393: ar5k_ar5212_get_rate_table(struct ath_hal *hal, u_int mode)
                    394: {
                    395:        switch (mode) {
                    396:        case HAL_MODE_11A:
                    397:                return (&hal->ah_rt_11a);
                    398:        case HAL_MODE_TURBO:
                    399:                return (&hal->ah_rt_turbo);
                    400:        case HAL_MODE_11B:
                    401:                return (&hal->ah_rt_11b);
                    402:        case HAL_MODE_11G:
                    403:        case HAL_MODE_PUREG:
                    404:                return (&hal->ah_rt_11g);
                    405:        case HAL_MODE_XR:
                    406:                return (&hal->ah_rt_xr);
                    407:        default:
                    408:                return (NULL);
                    409:        }
                    410:
                    411:        return (NULL);
                    412: }
                    413:
                    414: void
                    415: ar5k_ar5212_detach(struct ath_hal *hal)
                    416: {
                    417:        if (hal->ah_rf_banks != NULL)
                    418:                free(hal->ah_rf_banks, M_DEVBUF);
                    419:
                    420:        /*
                    421:         * Free HAL structure, assume interrupts are down
                    422:         */
                    423:        free(hal, M_DEVBUF);
                    424: }
                    425:
                    426: HAL_BOOL
                    427: ar5k_ar5212_phy_disable(struct ath_hal *hal)
                    428: {
                    429:        AR5K_REG_WRITE(AR5K_AR5212_PHY_ACTIVE, AR5K_AR5212_PHY_DISABLE);
                    430:        return (AH_TRUE);
                    431: }
                    432:
                    433: HAL_BOOL
                    434: ar5k_ar5212_reset(struct ath_hal *hal, HAL_OPMODE op_mode, HAL_CHANNEL *channel,
                    435:     HAL_BOOL change_channel, HAL_STATUS *status)
                    436: {
                    437:        struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
                    438:        u_int8_t mac[IEEE80211_ADDR_LEN];
                    439:        u_int32_t data, s_seq, s_ant, s_led[3];
                    440:        u_int i, phy, mode, freq, off, ee_mode, ant[2];
                    441:        const HAL_RATE_TABLE *rt;
                    442:
                    443:        /*
                    444:         * Save some registers before a reset
                    445:         */
                    446:        if (change_channel == AH_TRUE) {
                    447:                s_seq = AR5K_REG_READ(AR5K_AR5212_DCU_SEQNUM(0));
                    448:                s_ant = AR5K_REG_READ(AR5K_AR5212_DEFAULT_ANTENNA);
                    449:        } else {
                    450:                s_seq = 0;
                    451:                s_ant = 1;
                    452:        }
                    453:
                    454:        s_led[0] = AR5K_REG_READ(AR5K_AR5212_PCICFG) &
                    455:            AR5K_AR5212_PCICFG_LEDSTATE;
                    456:        s_led[1] = AR5K_REG_READ(AR5K_AR5212_GPIOCR);
                    457:        s_led[2] = AR5K_REG_READ(AR5K_AR5212_GPIODO);
                    458:
                    459:        if (change_channel == AH_TRUE && hal->ah_rf_banks != NULL)
                    460:                ar5k_ar5212_get_rf_gain(hal);
                    461:
                    462:        if (ar5k_ar5212_nic_wakeup(hal, channel->c_channel_flags) == AH_FALSE)
                    463:                return (AH_FALSE);
                    464:
                    465:        /*
                    466:         * Initialize operating mode
                    467:         */
                    468:        hal->ah_op_mode = op_mode;
                    469:
                    470:        if (hal->ah_radio == AR5K_AR5111) {
                    471:                phy = AR5K_INI_PHY_5111;
                    472:        } else if (hal->ah_radio == AR5K_AR5112) {
                    473:                phy = AR5K_INI_PHY_5112;
                    474:        } else {
                    475:                AR5K_PRINTF("invalid phy radio: %u\n", hal->ah_radio);
                    476:                return (AH_FALSE);
                    477:        }
                    478:
                    479:        switch (channel->c_channel_flags & CHANNEL_MODES) {
                    480:        case CHANNEL_A:
                    481:                mode = AR5K_INI_VAL_11A;
                    482:                freq = AR5K_INI_RFGAIN_5GHZ;
                    483:                ee_mode = AR5K_EEPROM_MODE_11A;
                    484:                break;
                    485:        case CHANNEL_B:
                    486:                mode = AR5K_INI_VAL_11B;
                    487:                freq = AR5K_INI_RFGAIN_2GHZ;
                    488:                ee_mode = AR5K_EEPROM_MODE_11B;
                    489:                break;
                    490:        case CHANNEL_G:
                    491:        case CHANNEL_PUREG:
                    492:                mode = AR5K_INI_VAL_11G;
                    493:                freq = AR5K_INI_RFGAIN_2GHZ;
                    494:                ee_mode = AR5K_EEPROM_MODE_11G;
                    495:                break;
                    496:        case CHANNEL_T:
                    497:                mode = AR5K_INI_VAL_11A_TURBO;
                    498:                freq = AR5K_INI_RFGAIN_5GHZ;
                    499:                ee_mode = AR5K_EEPROM_MODE_11A;
                    500:                break;
                    501:        case CHANNEL_TG:
                    502:                mode = AR5K_INI_VAL_11G_TURBO;
                    503:                freq = AR5K_INI_RFGAIN_2GHZ;
                    504:                ee_mode = AR5K_EEPROM_MODE_11G;
                    505:                break;
                    506:        case CHANNEL_XR:
                    507:                mode = AR5K_INI_VAL_XR;
                    508:                freq = AR5K_INI_RFGAIN_5GHZ;
                    509:                ee_mode = AR5K_EEPROM_MODE_11A;
                    510:                break;
                    511:        default:
                    512:                AR5K_PRINTF("invalid channel: %d\n", channel->c_channel);
                    513:                return (AH_FALSE);
                    514:        }
                    515:
                    516:        /* PHY access enable */
                    517:        AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);
                    518:
                    519:        /*
                    520:         * Write initial mode settings
                    521:         */
                    522:        for (i = 0; i < AR5K_ELEMENTS(ar5212_mode); i++) {
                    523:                if (ar5212_mode[i].mode_flags == AR5K_INI_FLAG_511X)
                    524:                        off = AR5K_INI_PHY_511X;
                    525:                else if (ar5212_mode[i].mode_flags & AR5K_INI_FLAG_5111 &&
                    526:                    hal->ah_radio == AR5K_AR5111)
                    527:                        off = AR5K_INI_PHY_5111;
                    528:                else if (ar5212_mode[i].mode_flags & AR5K_INI_FLAG_5112 &&
                    529:                    hal->ah_radio == AR5K_AR5112)
                    530:                        off = AR5K_INI_PHY_5112;
                    531:                else
                    532:                        continue;
                    533:
                    534:                AR5K_REG_WAIT(i);
                    535:                AR5K_REG_WRITE((u_int32_t)ar5212_mode[i].mode_register,
                    536:                    ar5212_mode[i].mode_value[off][mode]);
                    537:        }
                    538:
                    539:        /*
                    540:         * Write initial register settings
                    541:         */
                    542:        for (i = 0; i < AR5K_ELEMENTS(ar5212_ini); i++) {
                    543:                if (change_channel == AH_TRUE &&
                    544:                    ar5212_ini[i].ini_register >= AR5K_AR5212_PCU_MIN &&
                    545:                    ar5212_ini[i].ini_register <= AR5K_AR5212_PCU_MAX)
                    546:                        continue;
                    547:
                    548:                if ((hal->ah_radio == AR5K_AR5111 &&
                    549:                    ar5212_ini[i].ini_flags & AR5K_INI_FLAG_5111) ||
                    550:                    (hal->ah_radio == AR5K_AR5112 &&
                    551:                    ar5212_ini[i].ini_flags & AR5K_INI_FLAG_5112)) {
                    552:                        AR5K_REG_WAIT(i);
                    553:                        AR5K_REG_WRITE((u_int32_t)ar5212_ini[i].ini_register,
                    554:                            ar5212_ini[i].ini_value);
                    555:                }
                    556:        }
                    557:
                    558:        /*
                    559:         * Write initial RF gain settings
                    560:         */
                    561:        if (ar5k_rfgain(hal, phy, freq) == AH_FALSE)
                    562:                return (AH_FALSE);
                    563:
                    564:        AR5K_DELAY(1000);
                    565:
                    566:        /*
                    567:         * Set rate duration table
                    568:         */
                    569:        rt = ar5k_ar5212_get_rate_table(hal,
                    570:            channel->c_channel_flags & IEEE80211_CHAN_TURBO ?
                    571:            HAL_MODE_TURBO : HAL_MODE_XR);
                    572:
                    573:        for (i = 0; i < rt->rt_rate_count; i++) {
                    574:                AR5K_REG_WRITE(AR5K_AR5212_RATE_DUR(rt->rt_info[i].r_rate_code),
                    575:                    ath_hal_computetxtime(hal, rt, 14,
                    576:                    rt->rt_info[i].r_control_rate, AH_FALSE));
                    577:        }
                    578:
                    579:        if ((channel->c_channel_flags & IEEE80211_CHAN_TURBO) == 0) {
                    580:                rt = ar5k_ar5212_get_rate_table(hal, HAL_MODE_11B);
                    581:                for (i = 0; i < rt->rt_rate_count; i++) {
                    582:                        data = AR5K_AR5212_RATE_DUR(rt->rt_info[i].r_rate_code);
                    583:                        AR5K_REG_WRITE(data,
                    584:                            ath_hal_computetxtime(hal, rt, 14,
                    585:                            rt->rt_info[i].r_control_rate, AH_FALSE));
                    586:                        if (rt->rt_info[i].r_short_preamble) {
                    587:                                AR5K_REG_WRITE(data +
                    588:                                    (rt->rt_info[i].r_short_preamble << 2),
                    589:                                    ath_hal_computetxtime(hal, rt, 14,
                    590:                                    rt->rt_info[i].r_control_rate, AH_FALSE));
                    591:                        }
                    592:                }
                    593:        }
                    594:
                    595:        /* Fix for first revision of the AR5112 RF chipset */
                    596:        if (hal->ah_radio >= AR5K_AR5112 &&
                    597:            hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
                    598:                AR5K_REG_WRITE(AR5K_AR5212_PHY_CCKTXCTL,
                    599:                    AR5K_AR5212_PHY_CCKTXCTL_WORLD);
                    600:                if (channel->c_channel_flags & IEEE80211_CHAN_OFDM)
                    601:                        data = 0xffb81020;
                    602:                else
                    603:                        data = 0xffb80d20;
                    604:                AR5K_REG_WRITE(AR5K_AR5212_PHY_FC, data);
                    605:        }
                    606:
                    607:        /*
                    608:         * Set TX power (XXX use txpower from net80211)
                    609:         */
                    610:        if (ar5k_ar5212_txpower(hal, channel,
                    611:                AR5K_TUNE_DEFAULT_TXPOWER) == AH_FALSE)
                    612:                return (AH_FALSE);
                    613:
                    614:        /*
                    615:         * Write RF registers
                    616:         */
                    617:        if (ar5k_rfregs(hal, channel, mode) == AH_FALSE)
                    618:                return (AH_FALSE);
                    619:
                    620:        /*
                    621:         * Configure additional registers
                    622:         */
                    623:
                    624:        /* OFDM timings */
                    625:        if (channel->c_channel_flags & IEEE80211_CHAN_OFDM) {
                    626:                u_int32_t coef_scaled, coef_exp, coef_man, ds_coef_exp,
                    627:                    ds_coef_man, clock;
                    628:
                    629:                clock = channel->c_channel_flags & IEEE80211_CHAN_T ? 80 : 40;
                    630:                coef_scaled = ((5 * (clock << 24)) / 2) / channel->c_channel;
                    631:
                    632:                for (coef_exp = 31; coef_exp > 0; coef_exp--)
                    633:                        if ((coef_scaled >> coef_exp) & 0x1)
                    634:                                break;
                    635:
                    636:                if (!coef_exp)
                    637:                        return (AH_FALSE);
                    638:
                    639:                coef_exp = 14 - (coef_exp - 24);
                    640:                coef_man = coef_scaled + (1 << (24 - coef_exp - 1));
                    641:                ds_coef_man = coef_man >> (24 - coef_exp);
                    642:                ds_coef_exp = coef_exp - 16;
                    643:
                    644:                AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_TIMING_3,
                    645:                    AR5K_AR5212_PHY_TIMING_3_DSC_MAN, ds_coef_man);
                    646:                AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_TIMING_3,
                    647:                    AR5K_AR5212_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
                    648:        }
                    649:
                    650:        if (hal->ah_radio == AR5K_AR5111) {
                    651:                if (channel->c_channel_flags & IEEE80211_CHAN_B)
                    652:                        AR5K_REG_ENABLE_BITS(AR5K_AR5212_TXCFG,
                    653:                            AR5K_AR5212_TXCFG_B_MODE);
                    654:                else
                    655:                        AR5K_REG_DISABLE_BITS(AR5K_AR5212_TXCFG,
                    656:                            AR5K_AR5212_TXCFG_B_MODE);
                    657:        }
                    658:
                    659:        /* Set antenna mode */
                    660:        AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x44),
                    661:            hal->ah_antenna[ee_mode][0], 0xfffffc06);
                    662:
                    663:        if (freq == AR5K_INI_RFGAIN_2GHZ)
                    664:                ant[0] = ant[1] = HAL_ANT_FIXED_B;
                    665:        else
                    666:                ant[0] = ant[1] = HAL_ANT_FIXED_A;
                    667:
                    668:        AR5K_REG_WRITE(AR5K_AR5212_PHY_ANT_SWITCH_TABLE_0,
                    669:            hal->ah_antenna[ee_mode][ant[0]]);
                    670:        AR5K_REG_WRITE(AR5K_AR5212_PHY_ANT_SWITCH_TABLE_1,
                    671:            hal->ah_antenna[ee_mode][ant[1]]);
                    672:
                    673:        /* Commit values from EEPROM */
                    674:        if (hal->ah_radio == AR5K_AR5111)
                    675:                AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_FC,
                    676:                    AR5K_AR5212_PHY_FC_TX_CLIP, ee->ee_tx_clip);
                    677:
                    678:        AR5K_REG_WRITE(AR5K_AR5212_PHY(0x5a),
                    679:            AR5K_AR5212_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]));
                    680:
                    681:        AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x11),
                    682:            (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80, 0xffffc07f);
                    683:        AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x12),
                    684:            (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000, 0xfffc0fff);
                    685:        AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x14),
                    686:            (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
                    687:            ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00), 0xffff0000);
                    688:
                    689:        AR5K_REG_WRITE(AR5K_AR5212_PHY(0x0d),
                    690:            (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
                    691:            (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
                    692:            (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
                    693:            (ee->ee_tx_frm2xpa_enable[ee_mode]));
                    694:
                    695:        AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x0a),
                    696:            ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
                    697:        AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x19),
                    698:            (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
                    699:        AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x49), 4, 0xffffff01);
                    700:
                    701:        AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_IQ,
                    702:            AR5K_AR5212_PHY_IQ_CORR_ENABLE |
                    703:            (ee->ee_i_cal[ee_mode] << AR5K_AR5212_PHY_IQ_CORR_Q_I_COFF_S) |
                    704:            ee->ee_q_cal[ee_mode]);
                    705:
                    706:        if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
                    707:                AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_GAIN_2GHZ,
                    708:                    AR5K_AR5212_PHY_GAIN_2GHZ_MARGIN_TXRX,
                    709:                    ee->ee_margin_tx_rx[ee_mode]);
                    710:        }
                    711:
                    712:        /*
                    713:         * Restore saved values
                    714:         */
                    715:        AR5K_REG_WRITE(AR5K_AR5212_DCU_SEQNUM(0), s_seq);
                    716:        AR5K_REG_WRITE(AR5K_AR5212_DEFAULT_ANTENNA, s_ant);
                    717:        AR5K_REG_ENABLE_BITS(AR5K_AR5212_PCICFG, s_led[0]);
                    718:        AR5K_REG_WRITE(AR5K_AR5212_GPIOCR, s_led[1]);
                    719:        AR5K_REG_WRITE(AR5K_AR5212_GPIODO, s_led[2]);
                    720:
                    721:        /*
                    722:         * Misc
                    723:         */
                    724:        bcopy(etherbroadcastaddr, mac, IEEE80211_ADDR_LEN);
                    725:        ar5k_ar5212_set_associd(hal, mac, 0, 0);
                    726:        ar5k_ar5212_set_opmode(hal);
                    727:        AR5K_REG_WRITE(AR5K_AR5212_PISR, 0xffffffff);
                    728:        AR5K_REG_WRITE(AR5K_AR5212_RSSI_THR, AR5K_TUNE_RSSI_THRES);
                    729:
                    730:        /*
                    731:         * Set Rx/Tx DMA Configuration
                    732:         */
                    733:        AR5K_REG_WRITE_BITS(AR5K_AR5212_TXCFG, AR5K_AR5212_TXCFG_SDMAMR,
                    734:            AR5K_AR5212_DMASIZE_512B | AR5K_AR5212_TXCFG_DMASIZE);
                    735:        AR5K_REG_WRITE_BITS(AR5K_AR5212_RXCFG, AR5K_AR5212_RXCFG_SDMAMW,
                    736:            AR5K_AR5212_DMASIZE_512B);
                    737:
                    738:        /*
                    739:         * Set channel and calibrate the PHY
                    740:         */
                    741:        if (ar5k_channel(hal, channel) == AH_FALSE)
                    742:                return (AH_FALSE);
                    743:
                    744:        /*
                    745:         * Enable the PHY and wait until completion
                    746:         */
                    747:        AR5K_REG_WRITE(AR5K_AR5212_PHY_ACTIVE, AR5K_AR5212_PHY_ENABLE);
                    748:
                    749:        data = AR5K_REG_READ(AR5K_AR5212_PHY_RX_DELAY) &
                    750:            AR5K_AR5212_PHY_RX_DELAY_M;
                    751:        data = (channel->c_channel_flags & IEEE80211_CHAN_CCK) ?
                    752:            ((data << 2) / 22) : (data / 10);
                    753:
                    754:        AR5K_DELAY(100 + data);
                    755:
                    756:        /*
                    757:         * Start calibration
                    758:         */
                    759:        AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_AGCCTL,
                    760:            AR5K_AR5212_PHY_AGCCTL_NF |
                    761:            AR5K_AR5212_PHY_AGCCTL_CAL);
                    762:
                    763:        hal->ah_calibration = AH_FALSE;
                    764:        if ((channel->c_channel_flags & IEEE80211_CHAN_B) == 0) {
                    765:                hal->ah_calibration = AH_TRUE;
                    766:                AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_IQ,
                    767:                    AR5K_AR5212_PHY_IQ_CAL_NUM_LOG_MAX, 15);
                    768:                AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_IQ,
                    769:                    AR5K_AR5212_PHY_IQ_RUN);
                    770:        }
                    771:
                    772:        /*
                    773:         * Reset queues and start beacon timers at the end of the reset routine
                    774:         */
                    775:        for (i = 0; i < hal->ah_capabilities.cap_queues.q_tx_num; i++) {
                    776:                AR5K_REG_WRITE_Q(AR5K_AR5212_DCU_QCUMASK(i), i);
                    777:                if (ar5k_ar5212_reset_tx_queue(hal, i) == AH_FALSE) {
                    778:                        AR5K_PRINTF("failed to reset TX queue #%d\n", i);
                    779:                        return (AH_FALSE);
                    780:                }
                    781:        }
                    782:
                    783:        /* Pre-enable interrupts */
                    784:        ar5k_ar5212_set_intr(hal, HAL_INT_RX | HAL_INT_TX | HAL_INT_FATAL);
                    785:
                    786:        /*
                    787:         * Set RF kill flags if supported by the device (read from the EEPROM)
                    788:         */
                    789:        if (AR5K_EEPROM_HDR_RFKILL(hal->ah_capabilities.cap_eeprom.ee_header)) {
                    790:                ar5k_ar5212_set_gpio_input(hal, 0);
                    791:                if ((hal->ah_gpio[0] = ar5k_ar5212_get_gpio(hal, 0)) == 0)
                    792:                        ar5k_ar5212_set_gpio_intr(hal, 0, 1);
                    793:                else
                    794:                        ar5k_ar5212_set_gpio_intr(hal, 0, 0);
                    795:        }
                    796:
                    797:        /*
                    798:         * Set the 32MHz reference clock
                    799:         */
                    800:        AR5K_REG_WRITE(AR5K_AR5212_PHY_SCR, AR5K_AR5212_PHY_SCR_32MHZ);
                    801:        AR5K_REG_WRITE(AR5K_AR5212_PHY_SLMT, AR5K_AR5212_PHY_SLMT_32MHZ);
                    802:        AR5K_REG_WRITE(AR5K_AR5212_PHY_SCAL, AR5K_AR5212_PHY_SCAL_32MHZ);
                    803:        AR5K_REG_WRITE(AR5K_AR5212_PHY_SCLOCK, AR5K_AR5212_PHY_SCLOCK_32MHZ);
                    804:        AR5K_REG_WRITE(AR5K_AR5212_PHY_SDELAY, AR5K_AR5212_PHY_SDELAY_32MHZ);
                    805:        AR5K_REG_WRITE(AR5K_AR5212_PHY_SPENDING, hal->ah_radio == AR5K_AR5111 ?
                    806:            AR5K_AR5212_PHY_SPENDING_AR5111 : AR5K_AR5212_PHY_SPENDING_AR5112);
                    807:
                    808:        /*
                    809:         * Disable beacons and reset the register
                    810:         */
                    811:        AR5K_REG_DISABLE_BITS(AR5K_AR5212_BEACON,
                    812:            AR5K_AR5212_BEACON_ENABLE | AR5K_AR5212_BEACON_RESET_TSF);
                    813:
                    814:        return (AH_TRUE);
                    815: }
                    816:
                    817: void
                    818: ar5k_ar5212_set_def_antenna(struct ath_hal *hal, u_int ant)
                    819: {
                    820:        AR5K_REG_WRITE(AR5K_AR5212_DEFAULT_ANTENNA, ant);
                    821: }
                    822:
                    823: u_int
                    824: ar5k_ar5212_get_def_antenna(struct ath_hal *hal)
                    825: {
                    826:        return AR5K_REG_READ(AR5K_AR5212_DEFAULT_ANTENNA);
                    827: }
                    828:
                    829: void
                    830: ar5k_ar5212_set_opmode(struct ath_hal *hal)
                    831: {
                    832:        u_int32_t pcu_reg, low_id, high_id;
                    833:
                    834:        pcu_reg = 0;
                    835:
                    836:        switch (hal->ah_op_mode) {
                    837:        case IEEE80211_M_IBSS:
                    838:                pcu_reg |= AR5K_AR5212_STA_ID1_ADHOC |
                    839:                    AR5K_AR5212_STA_ID1_DESC_ANTENNA;
                    840:                break;
                    841:
                    842:        case IEEE80211_M_HOSTAP:
                    843:                pcu_reg |= AR5K_AR5212_STA_ID1_AP |
                    844:                    AR5K_AR5212_STA_ID1_RTS_DEFAULT_ANTENNA;
                    845:                break;
                    846:
                    847:        case IEEE80211_M_STA:
                    848:        case IEEE80211_M_MONITOR:
                    849:                pcu_reg |= AR5K_AR5212_STA_ID1_DEFAULT_ANTENNA;
                    850:                break;
                    851:
                    852:        default:
                    853:                return;
                    854:        }
                    855:
                    856:        /*
                    857:         * Set PCU registers
                    858:         */
                    859:        low_id = AR5K_LOW_ID(hal->ah_sta_id);
                    860:        high_id = AR5K_HIGH_ID(hal->ah_sta_id);
                    861:        AR5K_REG_WRITE(AR5K_AR5212_STA_ID0, low_id);
                    862:        AR5K_REG_WRITE(AR5K_AR5212_STA_ID1, pcu_reg | high_id);
                    863:
                    864:        return;
                    865: }
                    866:
                    867: HAL_BOOL
                    868: ar5k_ar5212_calibrate(struct ath_hal *hal, HAL_CHANNEL *channel)
                    869: {
                    870:        u_int32_t i_pwr, q_pwr;
                    871:        int32_t iq_corr, i_coff, i_coffd, q_coff, q_coffd;
                    872:
                    873:        if (hal->ah_calibration == AH_FALSE ||
                    874:            AR5K_REG_READ(AR5K_AR5212_PHY_IQ) & AR5K_AR5212_PHY_IQ_RUN)
                    875:                goto done;
                    876:
                    877:        hal->ah_calibration = AH_FALSE;
                    878:
                    879:        iq_corr = AR5K_REG_READ(AR5K_AR5212_PHY_IQRES_CAL_CORR);
                    880:        i_pwr = AR5K_REG_READ(AR5K_AR5212_PHY_IQRES_CAL_PWR_I);
                    881:        q_pwr = AR5K_REG_READ(AR5K_AR5212_PHY_IQRES_CAL_PWR_Q);
                    882:        i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
                    883:        q_coffd = q_pwr >> 6;
                    884:
                    885:        if (i_coffd == 0 || q_coffd == 0)
                    886:                goto done;
                    887:
                    888:        i_coff = ((-iq_corr) / i_coffd) & 0x3f;
                    889:        q_coff = (((int32_t)i_pwr / q_coffd) - 64) & 0x1f;
                    890:
                    891:        /* Commit new IQ value */
                    892:        AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_IQ,
                    893:            AR5K_AR5212_PHY_IQ_CORR_ENABLE |
                    894:            ((u_int32_t)q_coff) |
                    895:            ((u_int32_t)i_coff << AR5K_AR5212_PHY_IQ_CORR_Q_I_COFF_S));
                    896:
                    897:  done:
                    898:        /* Start noise floor calibration */
                    899:        AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_AGCCTL,
                    900:            AR5K_AR5212_PHY_AGCCTL_NF);
                    901:
                    902:        /* Request RF gain */
                    903:        if (channel->c_channel_flags & IEEE80211_CHAN_5GHZ) {
                    904:                AR5K_REG_WRITE(AR5K_AR5212_PHY_PAPD_PROBE,
                    905:                    AR5K_REG_SM(hal->ah_txpower.txp_max,
                    906:                    AR5K_AR5212_PHY_PAPD_PROBE_TXPOWER) |
                    907:                    AR5K_AR5212_PHY_PAPD_PROBE_TX_NEXT);
                    908:                hal->ah_rf_gain = HAL_RFGAIN_READ_REQUESTED;
                    909:        }
                    910:
                    911:        return (AH_TRUE);
                    912: }
                    913:
                    914: /*
                    915:  * Transmit functions
                    916:  */
                    917:
                    918: HAL_BOOL
                    919: ar5k_ar5212_update_tx_triglevel(struct ath_hal *hal, HAL_BOOL increase)
                    920: {
                    921:        u_int32_t trigger_level, imr;
                    922:        HAL_BOOL status = AH_FALSE;
                    923:
                    924:        /*
                    925:         * Disable interrupts by setting the mask
                    926:         */
                    927:        imr = ar5k_ar5212_set_intr(hal, hal->ah_imr & ~HAL_INT_GLOBAL);
                    928:
                    929:        trigger_level = AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5212_TXCFG),
                    930:            AR5K_AR5212_TXCFG_TXFULL);
                    931:
                    932:        if (increase == AH_FALSE) {
                    933:                if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
                    934:                        goto done;
                    935:        } else
                    936:                trigger_level +=
                    937:                    ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
                    938:
                    939:        /*
                    940:         * Update trigger level on success
                    941:         */
                    942:        AR5K_REG_WRITE_BITS(AR5K_AR5212_TXCFG,
                    943:            AR5K_AR5212_TXCFG_TXFULL, trigger_level);
                    944:        status = AH_TRUE;
                    945:
                    946:  done:
                    947:        /*
                    948:         * Restore interrupt mask
                    949:         */
                    950:        ar5k_ar5212_set_intr(hal, imr);
                    951:
                    952:        return (status);
                    953: }
                    954:
                    955: int
                    956: ar5k_ar5212_setup_tx_queue(struct ath_hal *hal, HAL_TX_QUEUE queue_type,
                    957:     const HAL_TXQ_INFO *queue_info)
                    958: {
                    959:        u_int queue;
                    960:
                    961:        /*
                    962:         * Get queue by type
                    963:         */
                    964:        if (queue_type == HAL_TX_QUEUE_DATA) {
                    965:                for (queue = HAL_TX_QUEUE_ID_DATA_MIN;
                    966:                     hal->ah_txq[queue].tqi_type != HAL_TX_QUEUE_INACTIVE;
                    967:                     queue++)
                    968:                        if (queue > HAL_TX_QUEUE_ID_DATA_MAX)
                    969:                                return (-1);
                    970:        } else if (queue_type == HAL_TX_QUEUE_PSPOLL) {
                    971:                queue = HAL_TX_QUEUE_ID_PSPOLL;
                    972:        } else if (queue_type == HAL_TX_QUEUE_BEACON) {
                    973:                queue = HAL_TX_QUEUE_ID_BEACON;
                    974:        } else if (queue_type == HAL_TX_QUEUE_CAB) {
                    975:                queue = HAL_TX_QUEUE_ID_CAB;
                    976:        } else
                    977:                return (-1);
                    978:
                    979:        /*
                    980:         * Setup internal queue structure
                    981:         */
                    982:        bzero(&hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));
                    983:        if (queue_info != NULL) {
                    984:                if (ar5k_ar5212_setup_tx_queueprops(hal, queue, queue_info)
                    985:                    != AH_TRUE)
                    986:                        return (-1);
                    987:        }
                    988:        hal->ah_txq[queue].tqi_type = queue_type;
                    989:
                    990:        AR5K_Q_ENABLE_BITS(hal->ah_txq_interrupts, queue);
                    991:
                    992:        return (queue);
                    993: }
                    994:
                    995: HAL_BOOL
                    996: ar5k_ar5212_setup_tx_queueprops(struct ath_hal *hal, int queue,
                    997:     const HAL_TXQ_INFO *queue_info)
                    998: {
                    999:        AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
                   1000:
                   1001:        if (hal->ah_txq[queue].tqi_type != HAL_TX_QUEUE_INACTIVE)
                   1002:                return (AH_FALSE);
                   1003:
                   1004:        bcopy(queue_info, &hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));
                   1005:
                   1006:        if (queue_info->tqi_type == HAL_TX_QUEUE_DATA &&
                   1007:            (queue_info->tqi_subtype >= HAL_WME_AC_VI) &&
                   1008:            (queue_info->tqi_subtype <= HAL_WME_UPSD))
                   1009:                hal->ah_txq[queue].tqi_flags |=
                   1010:                    AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
                   1011:
                   1012:        return (AH_TRUE);
                   1013: }
                   1014:
                   1015: HAL_BOOL
                   1016: ar5k_ar5212_get_tx_queueprops(struct ath_hal *hal, int queue,
                   1017:     HAL_TXQ_INFO *queue_info)
                   1018: {
                   1019:        AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
                   1020:        bcopy(&hal->ah_txq[queue], queue_info, sizeof(HAL_TXQ_INFO));
                   1021:        return (AH_TRUE);
                   1022: }
                   1023:
                   1024: HAL_BOOL
                   1025: ar5k_ar5212_release_tx_queue(struct ath_hal *hal, u_int queue)
                   1026: {
                   1027:        AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
                   1028:
                   1029:        /* This queue will be skipped in further operations */
                   1030:        hal->ah_txq[queue].tqi_type = HAL_TX_QUEUE_INACTIVE;
                   1031:        AR5K_Q_DISABLE_BITS(hal->ah_txq_interrupts, queue);
                   1032:
                   1033:        return (AH_FALSE);
                   1034: }
                   1035:
                   1036: HAL_BOOL
                   1037: ar5k_ar5212_reset_tx_queue(struct ath_hal *hal, u_int queue)
                   1038: {
                   1039:        u_int32_t cw_min, cw_max, retry_lg, retry_sh;
                   1040:        struct ieee80211_channel *channel = (struct ieee80211_channel*)
                   1041:            &hal->ah_current_channel;
                   1042:        HAL_TXQ_INFO *tq;
                   1043:
                   1044:        AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
                   1045:
                   1046:        tq = &hal->ah_txq[queue];
                   1047:
                   1048:        if (tq->tqi_type == HAL_TX_QUEUE_INACTIVE)
                   1049:                return (AH_TRUE);
                   1050:
                   1051:        /*
                   1052:         * Set registers by channel mode
                   1053:         */
                   1054:        cw_min = hal->ah_cw_min = AR5K_TUNE_CWMIN;
                   1055:        cw_max = hal->ah_cw_max = AR5K_TUNE_CWMAX;
                   1056:        hal->ah_aifs = AR5K_TUNE_AIFS;
                   1057:        if (IEEE80211_IS_CHAN_XR(channel)) {
                   1058:                cw_min = hal->ah_cw_min = AR5K_TUNE_CWMIN_XR;
                   1059:                cw_max = hal->ah_cw_max = AR5K_TUNE_CWMAX_XR;
                   1060:                hal->ah_aifs = AR5K_TUNE_AIFS_XR;
                   1061:        } else if (IEEE80211_IS_CHAN_B(channel)) {
                   1062:                cw_min = hal->ah_cw_min = AR5K_TUNE_CWMIN_11B;
                   1063:                cw_max = hal->ah_cw_max = AR5K_TUNE_CWMAX_11B;
                   1064:                hal->ah_aifs = AR5K_TUNE_AIFS_11B;
                   1065:        }
                   1066:
                   1067:        /*
                   1068:         * Set retry limits
                   1069:         */
                   1070:        if (hal->ah_software_retry == AH_TRUE) {
                   1071:                /* XXX Need to test this */
                   1072:                retry_lg = hal->ah_limit_tx_retries;
                   1073:                retry_sh = retry_lg =
                   1074:                    retry_lg > AR5K_AR5212_DCU_RETRY_LMT_SH_RETRY ?
                   1075:                    AR5K_AR5212_DCU_RETRY_LMT_SH_RETRY : retry_lg;
                   1076:        } else {
                   1077:                retry_lg = AR5K_INIT_LG_RETRY;
                   1078:                retry_sh = AR5K_INIT_SH_RETRY;
                   1079:        }
                   1080:
                   1081:        AR5K_REG_WRITE(AR5K_AR5212_DCU_RETRY_LMT(queue),
                   1082:            AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
                   1083:            AR5K_AR5212_DCU_RETRY_LMT_SLG_RETRY) |
                   1084:            AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
                   1085:            AR5K_AR5212_DCU_RETRY_LMT_SSH_RETRY) |
                   1086:            AR5K_REG_SM(retry_lg, AR5K_AR5212_DCU_RETRY_LMT_LG_RETRY) |
                   1087:            AR5K_REG_SM(retry_sh, AR5K_AR5212_DCU_RETRY_LMT_SH_RETRY));
                   1088:
                   1089:        /*
                   1090:         * Set initial content window (cw_min/cw_max)
                   1091:         */
                   1092:        cw_min = 1;
                   1093:        while (cw_min < hal->ah_cw_min)
                   1094:                cw_min = (cw_min << 1) | 1;
                   1095:
                   1096:        cw_min = tq->tqi_cw_min < 0 ?
                   1097:            (cw_min >> (-tq->tqi_cw_min)) :
                   1098:            ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
                   1099:        cw_max = tq->tqi_cw_max < 0 ?
                   1100:            (cw_max >> (-tq->tqi_cw_max)) :
                   1101:            ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
                   1102:
                   1103:        AR5K_REG_WRITE(AR5K_AR5212_DCU_LCL_IFS(queue),
                   1104:            AR5K_REG_SM(cw_min, AR5K_AR5212_DCU_LCL_IFS_CW_MIN) |
                   1105:            AR5K_REG_SM(cw_max, AR5K_AR5212_DCU_LCL_IFS_CW_MAX) |
                   1106:            AR5K_REG_SM(hal->ah_aifs + tq->tqi_aifs,
                   1107:            AR5K_AR5212_DCU_LCL_IFS_AIFS));
                   1108:
                   1109:        /*
                   1110:         * Set misc registers
                   1111:         */
                   1112:        AR5K_REG_WRITE(AR5K_AR5212_QCU_MISC(queue),
                   1113:            AR5K_AR5212_QCU_MISC_DCU_EARLY);
                   1114:
                   1115:        if (tq->tqi_cbr_period) {
                   1116:                AR5K_REG_WRITE(AR5K_AR5212_QCU_CBRCFG(queue),
                   1117:                    AR5K_REG_SM(tq->tqi_cbr_period,
                   1118:                    AR5K_AR5212_QCU_CBRCFG_INTVAL) |
                   1119:                    AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
                   1120:                    AR5K_AR5212_QCU_CBRCFG_ORN_THRES));
                   1121:                AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
                   1122:                    AR5K_AR5212_QCU_MISC_FRSHED_CBR);
                   1123:                if (tq->tqi_cbr_overflow_limit)
                   1124:                        AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
                   1125:                            AR5K_AR5212_QCU_MISC_CBR_THRES_ENABLE);
                   1126:        }
                   1127:
                   1128:        if (tq->tqi_ready_time) {
                   1129:                AR5K_REG_WRITE(AR5K_AR5212_QCU_RDYTIMECFG(queue),
                   1130:                    AR5K_REG_SM(tq->tqi_ready_time,
                   1131:                    AR5K_AR5212_QCU_RDYTIMECFG_INTVAL) |
                   1132:                    AR5K_AR5212_QCU_RDYTIMECFG_ENABLE);
                   1133:        }
                   1134:
                   1135:        if (tq->tqi_burst_time) {
                   1136:                AR5K_REG_WRITE(AR5K_AR5212_DCU_CHAN_TIME(queue),
                   1137:                    AR5K_REG_SM(tq->tqi_burst_time,
                   1138:                    AR5K_AR5212_DCU_CHAN_TIME_DUR) |
                   1139:                    AR5K_AR5212_DCU_CHAN_TIME_ENABLE);
                   1140:
                   1141:                if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE) {
                   1142:                        AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
                   1143:                            AR5K_AR5212_QCU_MISC_TXE);
                   1144:                }
                   1145:        }
                   1146:
                   1147:        if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE) {
                   1148:                AR5K_REG_WRITE(AR5K_AR5212_DCU_MISC(queue),
                   1149:                    AR5K_AR5212_DCU_MISC_POST_FR_BKOFF_DIS);
                   1150:        }
                   1151:
                   1152:        if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
                   1153:                AR5K_REG_WRITE(AR5K_AR5212_DCU_MISC(queue),
                   1154:                    AR5K_AR5212_DCU_MISC_BACKOFF_FRAG);
                   1155:        }
                   1156:
                   1157:        /*
                   1158:         * Set registers by queue type
                   1159:         */
                   1160:        switch (tq->tqi_type) {
                   1161:        case HAL_TX_QUEUE_BEACON:
                   1162:                AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
                   1163:                    AR5K_AR5212_QCU_MISC_FRSHED_DBA_GT |
                   1164:                    AR5K_AR5212_QCU_MISC_CBREXP_BCN |
                   1165:                    AR5K_AR5212_QCU_MISC_BCN_ENABLE);
                   1166:
                   1167:                AR5K_REG_ENABLE_BITS(AR5K_AR5212_DCU_MISC(queue),
                   1168:                    (AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
                   1169:                    AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL) |
                   1170:                    AR5K_AR5212_DCU_MISC_POST_FR_BKOFF_DIS |
                   1171:                    AR5K_AR5212_DCU_MISC_BCN_ENABLE);
                   1172:
                   1173:                AR5K_REG_WRITE(AR5K_AR5212_QCU_RDYTIMECFG(queue),
                   1174:                    ((AR5K_TUNE_BEACON_INTERVAL -
                   1175:                    (AR5K_TUNE_SW_BEACON_RESP - AR5K_TUNE_DMA_BEACON_RESP) -
                   1176:                    AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
                   1177:                    AR5K_AR5212_QCU_RDYTIMECFG_ENABLE);
                   1178:                break;
                   1179:
                   1180:        case HAL_TX_QUEUE_CAB:
                   1181:                AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
                   1182:                    AR5K_AR5212_QCU_MISC_FRSHED_DBA_GT |
                   1183:                    AR5K_AR5212_QCU_MISC_CBREXP |
                   1184:                    AR5K_AR5212_QCU_MISC_CBREXP_BCN);
                   1185:
                   1186:                AR5K_REG_ENABLE_BITS(AR5K_AR5212_DCU_MISC(queue),
                   1187:                    (AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
                   1188:                    AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL));
                   1189:                break;
                   1190:
                   1191:        case HAL_TX_QUEUE_PSPOLL:
                   1192:                AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
                   1193:                    AR5K_AR5212_QCU_MISC_CBREXP);
                   1194:                break;
                   1195:
                   1196:        case HAL_TX_QUEUE_DATA:
                   1197:        default:
                   1198:                break;
                   1199:        }
                   1200:
                   1201:        /*
                   1202:         * Enable tx queue in the secondary interrupt mask registers
                   1203:         */
                   1204:        AR5K_REG_WRITE(AR5K_AR5212_SIMR0,
                   1205:            AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR0_QCU_TXOK) |
                   1206:            AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR0_QCU_TXDESC));
                   1207:        AR5K_REG_WRITE(AR5K_AR5212_SIMR1,
                   1208:            AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR1_QCU_TXERR));
                   1209:        AR5K_REG_WRITE(AR5K_AR5212_SIMR2,
                   1210:            AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR2_QCU_TXURN));
                   1211:
                   1212:        return (AH_TRUE);
                   1213: }
                   1214:
                   1215: u_int32_t
                   1216: ar5k_ar5212_get_tx_buf(struct ath_hal *hal, u_int queue)
                   1217: {
                   1218:        AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
                   1219:
                   1220:        /*
                   1221:         * Get the transmit queue descriptor pointer from the selected queue
                   1222:         */
                   1223:        return (AR5K_REG_READ(AR5K_AR5212_QCU_TXDP(queue)));
                   1224: }
                   1225:
                   1226: HAL_BOOL
                   1227: ar5k_ar5212_put_tx_buf(struct ath_hal *hal, u_int queue, u_int32_t phys_addr)
                   1228: {
                   1229:        AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
                   1230:
                   1231:        /*
                   1232:         * Set the transmit queue descriptor pointer for the selected queue
                   1233:         * (this won't work if the queue is still active)
                   1234:         */
                   1235:        if (AR5K_REG_READ_Q(AR5K_AR5212_QCU_TXE, queue))
                   1236:                return (AH_FALSE);
                   1237:
                   1238:        AR5K_REG_WRITE(AR5K_AR5212_QCU_TXDP(queue), phys_addr);
                   1239:
                   1240:        return (AH_TRUE);
                   1241: }
                   1242:
                   1243: u_int32_t
                   1244: ar5k_ar5212_num_tx_pending(struct ath_hal *hal, u_int queue)
                   1245: {
                   1246:        AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
                   1247:        return (AR5K_AR5212_QCU_STS(queue) & AR5K_AR5212_QCU_STS_FRMPENDCNT);
                   1248: }
                   1249:
                   1250: HAL_BOOL
                   1251: ar5k_ar5212_tx_start(struct ath_hal *hal, u_int queue)
                   1252: {
                   1253:        AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
                   1254:
                   1255:        /* Return if queue is disabled */
                   1256:        if (AR5K_REG_READ_Q(AR5K_AR5212_QCU_TXD, queue))
                   1257:                return (AH_FALSE);
                   1258:
                   1259:        /* Start queue */
                   1260:        AR5K_REG_WRITE_Q(AR5K_AR5212_QCU_TXE, queue);
                   1261:
                   1262:        return (AH_TRUE);
                   1263: }
                   1264:
                   1265: HAL_BOOL
                   1266: ar5k_ar5212_stop_tx_dma(struct ath_hal *hal, u_int queue)
                   1267: {
                   1268:        int i = 100, pending;
                   1269:
                   1270:        AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
                   1271:
                   1272:        /*
                   1273:         * Schedule TX disable and wait until queue is empty
                   1274:         */
                   1275:        AR5K_REG_WRITE_Q(AR5K_AR5212_QCU_TXD, queue);
                   1276:
                   1277:        do {
                   1278:                pending = AR5K_REG_READ(AR5K_AR5212_QCU_STS(queue)) &
                   1279:                     AR5K_AR5212_QCU_STS_FRMPENDCNT;
                   1280:                delay(100);
                   1281:        } while (--i && pending);
                   1282:
                   1283:        /* Clear register */
                   1284:        AR5K_REG_WRITE(AR5K_AR5212_QCU_TXD, 0);
                   1285:
                   1286:        return (AH_TRUE);
                   1287: }
                   1288:
                   1289: HAL_BOOL
                   1290: ar5k_ar5212_setup_tx_desc(struct ath_hal *hal, struct ath_desc *desc,
                   1291:     u_int packet_length, u_int header_length, HAL_PKT_TYPE type, u_int tx_power,
                   1292:     u_int tx_rate0, u_int tx_tries0, u_int key_index, u_int antenna_mode,
                   1293:     u_int flags, u_int rtscts_rate, u_int rtscts_duration)
                   1294: {
                   1295:        struct ar5k_ar5212_tx_desc *tx_desc;
                   1296:
                   1297:        tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
                   1298:
                   1299:        /*
                   1300:         * Validate input
                   1301:         */
                   1302:        if (tx_tries0 == 0)
                   1303:                return (AH_FALSE);
                   1304:
                   1305:        if ((tx_desc->tx_control_0 = (packet_length &
                   1306:            AR5K_AR5212_DESC_TX_CTL0_FRAME_LEN)) != packet_length)
                   1307:                return (AH_FALSE);
                   1308:
                   1309:        tx_desc->tx_control_0 |=
                   1310:            AR5K_REG_SM(tx_power, AR5K_AR5212_DESC_TX_CTL0_XMIT_POWER) |
                   1311:            AR5K_REG_SM(antenna_mode, AR5K_AR5212_DESC_TX_CTL0_ANT_MODE_XMIT);
                   1312:        tx_desc->tx_control_1 =
                   1313:            AR5K_REG_SM(type, AR5K_AR5212_DESC_TX_CTL1_FRAME_TYPE);
                   1314:        tx_desc->tx_control_2 =
                   1315:            AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES,
                   1316:            AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES0);
                   1317:        tx_desc->tx_control_3 =
                   1318:            tx_rate0 & AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE0;
                   1319:
                   1320: #define _TX_FLAGS(_c, _flag)                                           \
                   1321:        if (flags & HAL_TXDESC_##_flag)                                 \
                   1322:                tx_desc->tx_control_##_c |=                             \
                   1323:                        AR5K_AR5212_DESC_TX_CTL##_c##_##_flag
                   1324:
                   1325:        _TX_FLAGS(0, CLRDMASK);
                   1326:        _TX_FLAGS(0, VEOL);
                   1327:        _TX_FLAGS(0, INTREQ);
                   1328:        _TX_FLAGS(0, RTSENA);
                   1329:        _TX_FLAGS(0, CTSENA);
                   1330:        _TX_FLAGS(1, NOACK);
                   1331:
                   1332: #undef _TX_FLAGS
                   1333:
                   1334:        /*
                   1335:         * WEP crap
                   1336:         */
                   1337:        if (key_index != HAL_TXKEYIX_INVALID) {
                   1338:                tx_desc->tx_control_0 |=
                   1339:                    AR5K_AR5212_DESC_TX_CTL0_ENCRYPT_KEY_VALID;
                   1340:                tx_desc->tx_control_1 |=
                   1341:                    AR5K_REG_SM(key_index,
                   1342:                    AR5K_AR5212_DESC_TX_CTL1_ENCRYPT_KEY_INDEX);
                   1343:        }
                   1344:
                   1345:        /*
                   1346:         * RTS/CTS
                   1347:         */
                   1348:        if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) {
                   1349:                if ((flags & HAL_TXDESC_RTSENA) &&
                   1350:                    (flags & HAL_TXDESC_CTSENA))
                   1351:                        return (AH_FALSE);
                   1352:                tx_desc->tx_control_2 |=
                   1353:                    rtscts_duration & AR5K_AR5212_DESC_TX_CTL2_RTS_DURATION;
                   1354:                tx_desc->tx_control_3 |=
                   1355:                    AR5K_REG_SM(rtscts_rate,
                   1356:                    AR5K_AR5212_DESC_TX_CTL3_RTS_CTS_RATE);
                   1357:        }
                   1358:
                   1359:        return (AH_TRUE);
                   1360: }
                   1361:
                   1362: HAL_BOOL
                   1363: ar5k_ar5212_fill_tx_desc(struct ath_hal *hal, struct ath_desc *desc,
                   1364:     u_int segment_length, HAL_BOOL first_segment, HAL_BOOL last_segment)
                   1365: {
                   1366:        struct ar5k_ar5212_tx_desc *tx_desc;
                   1367:        struct ar5k_ar5212_tx_status *tx_status;
                   1368:
                   1369:        tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
                   1370:        tx_status = (struct ar5k_ar5212_tx_status*)&desc->ds_hw[2];
                   1371:
                   1372:        /* Clear status descriptor */
                   1373:        bzero(tx_status, sizeof(struct ar5k_ar5212_tx_status));
                   1374:
                   1375:        /* Validate segment length and initialize the descriptor */
                   1376:        if ((tx_desc->tx_control_1 = (segment_length &
                   1377:            AR5K_AR5212_DESC_TX_CTL1_BUF_LEN)) != segment_length)
                   1378:                return (AH_FALSE);
                   1379:
                   1380:        if (first_segment != AH_TRUE)
                   1381:                tx_desc->tx_control_0 &= ~AR5K_AR5212_DESC_TX_CTL0_FRAME_LEN;
                   1382:
                   1383:        if (last_segment != AH_TRUE)
                   1384:                tx_desc->tx_control_1 |= AR5K_AR5212_DESC_TX_CTL1_MORE;
                   1385:
                   1386:        return (AH_TRUE);
                   1387: }
                   1388:
                   1389: HAL_BOOL
                   1390: ar5k_ar5212_setup_xtx_desc(struct ath_hal *hal, struct ath_desc *desc,
                   1391:     u_int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2,
                   1392:     u_int tx_rate3, u_int tx_tries3)
                   1393: {
                   1394:        struct ar5k_ar5212_tx_desc *tx_desc;
                   1395:
                   1396:        tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
                   1397:
                   1398: #define _XTX_TRIES(_n)                                                 \
                   1399:        if (tx_tries##_n) {                                             \
                   1400:                tx_desc->tx_control_2 |=                                \
                   1401:                    AR5K_REG_SM(tx_tries##_n,                           \
                   1402:                    AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES##_n);           \
                   1403:                tx_desc->tx_control_3 |=                                \
                   1404:                    AR5K_REG_SM(tx_rate##_n,                            \
                   1405:                    AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE##_n);            \
                   1406:        }
                   1407:
                   1408:        _XTX_TRIES(1);
                   1409:        _XTX_TRIES(2);
                   1410:        _XTX_TRIES(3);
                   1411:
                   1412: #undef _XTX_TRIES
                   1413:
                   1414:        return (AH_TRUE);
                   1415: }
                   1416:
                   1417: HAL_STATUS
                   1418: ar5k_ar5212_proc_tx_desc(struct ath_hal *hal, struct ath_desc *desc)
                   1419: {
                   1420:        struct ar5k_ar5212_tx_status *tx_status;
                   1421:        struct ar5k_ar5212_tx_desc *tx_desc;
                   1422:
                   1423:        tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
                   1424:        tx_status = (struct ar5k_ar5212_tx_status*)&desc->ds_hw[2];
                   1425:
                   1426:        /* No frame has been send or error */
                   1427:        if ((tx_status->tx_status_1 & AR5K_AR5212_DESC_TX_STATUS1_DONE) == 0)
                   1428:                return (HAL_EINPROGRESS);
                   1429:
                   1430:        /*
                   1431:         * Get descriptor status
                   1432:         */
                   1433:        desc->ds_us.tx.ts_tstamp =
                   1434:            AR5K_REG_MS(tx_status->tx_status_0,
                   1435:            AR5K_AR5212_DESC_TX_STATUS0_SEND_TIMESTAMP);
                   1436:        desc->ds_us.tx.ts_shortretry =
                   1437:            AR5K_REG_MS(tx_status->tx_status_0,
                   1438:            AR5K_AR5212_DESC_TX_STATUS0_RTS_FAIL_COUNT);
                   1439:        desc->ds_us.tx.ts_longretry =
                   1440:            AR5K_REG_MS(tx_status->tx_status_0,
                   1441:            AR5K_AR5212_DESC_TX_STATUS0_DATA_FAIL_COUNT);
                   1442:        desc->ds_us.tx.ts_seqnum =
                   1443:            AR5K_REG_MS(tx_status->tx_status_1,
                   1444:            AR5K_AR5212_DESC_TX_STATUS1_SEQ_NUM);
                   1445:        desc->ds_us.tx.ts_rssi =
                   1446:            AR5K_REG_MS(tx_status->tx_status_1,
                   1447:            AR5K_AR5212_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
                   1448:        desc->ds_us.tx.ts_antenna = (tx_status->tx_status_1 &
                   1449:            AR5K_AR5212_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
                   1450:        desc->ds_us.tx.ts_status = 0;
                   1451:
                   1452:        switch (AR5K_REG_MS(tx_status->tx_status_1,
                   1453:            AR5K_AR5212_DESC_TX_STATUS1_FINAL_TS_INDEX)) {
                   1454:        case 0:
                   1455:                desc->ds_us.tx.ts_rate = tx_desc->tx_control_3 &
                   1456:                    AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE0;
                   1457:                break;
                   1458:        case 1:
                   1459:                desc->ds_us.tx.ts_rate =
                   1460:                    AR5K_REG_MS(tx_desc->tx_control_3,
                   1461:                    AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE1);
                   1462:                desc->ds_us.tx.ts_longretry +=
                   1463:                    AR5K_REG_MS(tx_desc->tx_control_2,
                   1464:                    AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES1);
                   1465:                break;
                   1466:        case 2:
                   1467:                desc->ds_us.tx.ts_rate =
                   1468:                    AR5K_REG_MS(tx_desc->tx_control_3,
                   1469:                    AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE2);
                   1470:                desc->ds_us.tx.ts_longretry +=
                   1471:                    AR5K_REG_MS(tx_desc->tx_control_2,
                   1472:                    AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES2);
                   1473:                break;
                   1474:        case 3:
                   1475:                desc->ds_us.tx.ts_rate =
                   1476:                    AR5K_REG_MS(tx_desc->tx_control_3,
                   1477:                    AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE3);
                   1478:                desc->ds_us.tx.ts_longretry +=
                   1479:                    AR5K_REG_MS(tx_desc->tx_control_2,
                   1480:                    AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES3);
                   1481:                break;
                   1482:        }
                   1483:
                   1484:        if ((tx_status->tx_status_0 &
                   1485:            AR5K_AR5212_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0) {
                   1486:                if (tx_status->tx_status_0 &
                   1487:                    AR5K_AR5212_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
                   1488:                        desc->ds_us.tx.ts_status |= HAL_TXERR_XRETRY;
                   1489:
                   1490:                if (tx_status->tx_status_0 &
                   1491:                    AR5K_AR5212_DESC_TX_STATUS0_FIFO_UNDERRUN)
                   1492:                        desc->ds_us.tx.ts_status |= HAL_TXERR_FIFO;
                   1493:
                   1494:                if (tx_status->tx_status_0 &
                   1495:                    AR5K_AR5212_DESC_TX_STATUS0_FILTERED)
                   1496:                        desc->ds_us.tx.ts_status |= HAL_TXERR_FILT;
                   1497:        }
                   1498:
                   1499:        return (HAL_OK);
                   1500: }
                   1501:
                   1502: HAL_BOOL
                   1503: ar5k_ar5212_has_veol(struct ath_hal *hal)
                   1504: {
                   1505:        return (AH_TRUE);
                   1506: }
                   1507:
                   1508: /*
                   1509:  * Receive functions
                   1510:  */
                   1511:
                   1512: u_int32_t
                   1513: ar5k_ar5212_get_rx_buf(struct ath_hal *hal)
                   1514: {
                   1515:        return (AR5K_REG_READ(AR5K_AR5212_RXDP));
                   1516: }
                   1517:
                   1518: void
                   1519: ar5k_ar5212_put_rx_buf(struct ath_hal *hal, u_int32_t phys_addr)
                   1520: {
                   1521:        AR5K_REG_WRITE(AR5K_AR5212_RXDP, phys_addr);
                   1522: }
                   1523:
                   1524: void
                   1525: ar5k_ar5212_start_rx(struct ath_hal *hal)
                   1526: {
                   1527:        AR5K_REG_WRITE(AR5K_AR5212_CR, AR5K_AR5212_CR_RXE);
                   1528: }
                   1529:
                   1530: HAL_BOOL
                   1531: ar5k_ar5212_stop_rx_dma(struct ath_hal *hal)
                   1532: {
                   1533:        int i;
                   1534:
                   1535:        AR5K_REG_WRITE(AR5K_AR5212_CR, AR5K_AR5212_CR_RXD);
                   1536:
                   1537:        /*
                   1538:         * It may take some time to disable the DMA receive unit
                   1539:         */
                   1540:        for (i = 2000;
                   1541:             i > 0 && (AR5K_REG_READ(AR5K_AR5212_CR) & AR5K_AR5212_CR_RXE) != 0;
                   1542:             i--)
                   1543:                AR5K_DELAY(10);
                   1544:
                   1545:        return (i > 0 ? AH_TRUE : AH_FALSE);
                   1546: }
                   1547:
                   1548: void
                   1549: ar5k_ar5212_start_rx_pcu(struct ath_hal *hal)
                   1550: {
                   1551:        AR5K_REG_DISABLE_BITS(AR5K_AR5212_DIAG_SW, AR5K_AR5212_DIAG_SW_DIS_RX);
                   1552: }
                   1553:
                   1554: void
                   1555: ar5k_ar5212_stop_pcu_recv(struct ath_hal *hal)
                   1556: {
                   1557:        AR5K_REG_ENABLE_BITS(AR5K_AR5212_DIAG_SW, AR5K_AR5212_DIAG_SW_DIS_RX);
                   1558: }
                   1559:
                   1560: void
                   1561: ar5k_ar5212_set_mcast_filter(struct ath_hal *hal, u_int32_t filter0,
                   1562:     u_int32_t filter1)
                   1563: {
                   1564:        /* Set the multicat filter */
                   1565:        AR5K_REG_WRITE(AR5K_AR5212_MCAST_FIL0, filter0);
                   1566:        AR5K_REG_WRITE(AR5K_AR5212_MCAST_FIL1, filter1);
                   1567: }
                   1568:
                   1569: HAL_BOOL
                   1570: ar5k_ar5212_set_mcast_filterindex(struct ath_hal *hal, u_int32_t index)
                   1571: {
                   1572:        if (index >= 64) {
                   1573:            return (AH_FALSE);
                   1574:        } else if (index >= 32) {
                   1575:            AR5K_REG_ENABLE_BITS(AR5K_AR5212_MCAST_FIL1,
                   1576:                (1 << (index - 32)));
                   1577:        } else {
                   1578:            AR5K_REG_ENABLE_BITS(AR5K_AR5212_MCAST_FIL0,
                   1579:                (1 << index));
                   1580:        }
                   1581:
                   1582:        return (AH_TRUE);
                   1583: }
                   1584:
                   1585: HAL_BOOL
                   1586: ar5k_ar5212_clear_mcast_filter_idx(struct ath_hal *hal, u_int32_t index)
                   1587: {
                   1588:
                   1589:        if (index >= 64) {
                   1590:            return (AH_FALSE);
                   1591:        } else if (index >= 32) {
                   1592:            AR5K_REG_DISABLE_BITS(AR5K_AR5212_MCAST_FIL1,
                   1593:                (1 << (index - 32)));
                   1594:        } else {
                   1595:            AR5K_REG_DISABLE_BITS(AR5K_AR5212_MCAST_FIL0,
                   1596:                (1 << index));
                   1597:        }
                   1598:
                   1599:        return (AH_TRUE);
                   1600: }
                   1601:
                   1602: u_int32_t
                   1603: ar5k_ar5212_get_rx_filter(struct ath_hal *hal)
                   1604: {
                   1605:        u_int32_t data, filter = 0;
                   1606:
                   1607:        filter = AR5K_REG_READ(AR5K_AR5212_RX_FILTER);
                   1608:        data = AR5K_REG_READ(AR5K_AR5212_PHY_ERR_FIL);
                   1609:
                   1610:        if (data & AR5K_AR5212_PHY_ERR_FIL_RADAR)
                   1611:                filter |= HAL_RX_FILTER_PHYRADAR;
                   1612:        if (data & (AR5K_AR5212_PHY_ERR_FIL_OFDM |
                   1613:            AR5K_AR5212_PHY_ERR_FIL_CCK))
                   1614:                filter |= HAL_RX_FILTER_PHYERR;
                   1615:
                   1616:        return (filter);
                   1617: }
                   1618:
                   1619: void
                   1620: ar5k_ar5212_set_rx_filter(struct ath_hal *hal, u_int32_t filter)
                   1621: {
                   1622:        u_int32_t data = 0;
                   1623:
                   1624:        if (filter & HAL_RX_FILTER_PHYRADAR)
                   1625:                data |= AR5K_AR5212_PHY_ERR_FIL_RADAR;
                   1626:        if (filter & HAL_RX_FILTER_PHYERR)
                   1627:                data |= AR5K_AR5212_PHY_ERR_FIL_OFDM |
                   1628:                    AR5K_AR5212_PHY_ERR_FIL_CCK;
                   1629:
                   1630:        if (data) {
                   1631:                AR5K_REG_ENABLE_BITS(AR5K_AR5212_RXCFG,
                   1632:                    AR5K_AR5212_RXCFG_ZLFDMA);
                   1633:        } else {
                   1634:                AR5K_REG_DISABLE_BITS(AR5K_AR5212_RXCFG,
                   1635:                    AR5K_AR5212_RXCFG_ZLFDMA);
                   1636:        }
                   1637:
                   1638:        AR5K_REG_WRITE(AR5K_AR5212_RX_FILTER, filter & 0xff);
                   1639:        AR5K_REG_WRITE(AR5K_AR5212_PHY_ERR_FIL, data);
                   1640: }
                   1641:
                   1642: HAL_BOOL
                   1643: ar5k_ar5212_setup_rx_desc(struct ath_hal *hal, struct ath_desc *desc,
                   1644:     u_int32_t size, u_int flags)
                   1645: {
                   1646:        struct ar5k_ar5212_rx_desc *rx_desc;
                   1647:
                   1648:        rx_desc = (struct ar5k_ar5212_rx_desc*)&desc->ds_ctl0;
                   1649:
                   1650:        if ((rx_desc->rx_control_1 = (size &
                   1651:            AR5K_AR5212_DESC_RX_CTL1_BUF_LEN)) != size)
                   1652:                return (AH_FALSE);
                   1653:
                   1654:        if (flags & HAL_RXDESC_INTREQ)
                   1655:                rx_desc->rx_control_1 |= AR5K_AR5212_DESC_RX_CTL1_INTREQ;
                   1656:
                   1657:        return (AH_TRUE);
                   1658: }
                   1659:
                   1660: HAL_STATUS
                   1661: ar5k_ar5212_proc_rx_desc(struct ath_hal *hal, struct ath_desc *desc,
                   1662:     u_int32_t phys_addr, struct ath_desc *next)
                   1663: {
                   1664:        struct ar5k_ar5212_rx_status *rx_status;
                   1665:        struct ar5k_ar5212_rx_error *rx_err;
                   1666:
                   1667:        rx_status = (struct ar5k_ar5212_rx_status*)&desc->ds_hw[0];
                   1668:
                   1669:        /* Overlay on error */
                   1670:        rx_err = (struct ar5k_ar5212_rx_error*)&desc->ds_hw[0];
                   1671:
                   1672:        /* No frame received / not ready */
                   1673:        if ((rx_status->rx_status_1 & AR5K_AR5212_DESC_RX_STATUS1_DONE) == 0)
                   1674:                return (HAL_EINPROGRESS);
                   1675:
                   1676:        /*
                   1677:         * Frame receive status
                   1678:         */
                   1679:        desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 &
                   1680:            AR5K_AR5212_DESC_RX_STATUS0_DATA_LEN;
                   1681:        desc->ds_us.rx.rs_rssi =
                   1682:            AR5K_REG_MS(rx_status->rx_status_0,
                   1683:            AR5K_AR5212_DESC_RX_STATUS0_RECEIVE_SIGNAL);
                   1684:        desc->ds_us.rx.rs_rate =
                   1685:            AR5K_REG_MS(rx_status->rx_status_0,
                   1686:            AR5K_AR5212_DESC_RX_STATUS0_RECEIVE_RATE);
                   1687:        desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 &
                   1688:            AR5K_AR5212_DESC_RX_STATUS0_RECEIVE_ANTENNA;
                   1689:        desc->ds_us.rx.rs_more = rx_status->rx_status_0 &
                   1690:            AR5K_AR5212_DESC_RX_STATUS0_MORE;
                   1691:        desc->ds_us.rx.rs_tstamp =
                   1692:            AR5K_REG_MS(rx_status->rx_status_1,
                   1693:            AR5K_AR5212_DESC_RX_STATUS1_RECEIVE_TIMESTAMP);
                   1694:        desc->ds_us.rx.rs_status = 0;
                   1695:
                   1696:        /*
                   1697:         * Key table status
                   1698:         */
                   1699:        if (rx_status->rx_status_1 &
                   1700:            AR5K_AR5212_DESC_RX_STATUS1_KEY_INDEX_VALID) {
                   1701:                desc->ds_us.rx.rs_keyix =
                   1702:                    AR5K_REG_MS(rx_status->rx_status_1,
                   1703:                    AR5K_AR5212_DESC_RX_STATUS1_KEY_INDEX);
                   1704:        } else {
                   1705:                desc->ds_us.rx.rs_keyix = HAL_RXKEYIX_INVALID;
                   1706:        }
                   1707:
                   1708:        /*
                   1709:         * Receive/descriptor errors
                   1710:         */
                   1711:        if ((rx_status->rx_status_1 &
                   1712:            AR5K_AR5212_DESC_RX_STATUS1_FRAME_RECEIVE_OK) == 0) {
                   1713:                if (rx_status->rx_status_1 &
                   1714:                    AR5K_AR5212_DESC_RX_STATUS1_CRC_ERROR)
                   1715:                        desc->ds_us.rx.rs_status |= HAL_RXERR_CRC;
                   1716:
                   1717:                if (rx_status->rx_status_1 &
                   1718:                    AR5K_AR5212_DESC_RX_STATUS1_PHY_ERROR) {
                   1719:                        desc->ds_us.rx.rs_status |= HAL_RXERR_PHY;
                   1720:                        desc->ds_us.rx.rs_phyerr =
                   1721:                            AR5K_REG_MS(rx_err->rx_error_1,
                   1722:                            AR5K_AR5212_DESC_RX_ERROR1_PHY_ERROR_CODE);
                   1723:                }
                   1724:
                   1725:                if (rx_status->rx_status_1 &
                   1726:                    AR5K_AR5212_DESC_RX_STATUS1_DECRYPT_CRC_ERROR)
                   1727:                        desc->ds_us.rx.rs_status |= HAL_RXERR_DECRYPT;
                   1728:
                   1729:                if (rx_status->rx_status_1 &
                   1730:                    AR5K_AR5212_DESC_RX_STATUS1_MIC_ERROR)
                   1731:                        desc->ds_us.rx.rs_status |= HAL_RXERR_MIC;
                   1732:        }
                   1733:
                   1734:        return (HAL_OK);
                   1735: }
                   1736:
                   1737: void
                   1738: ar5k_ar5212_set_rx_signal(struct ath_hal *hal)
                   1739: {
                   1740:        /* Signal state monitoring is not yet supported */
                   1741: }
                   1742:
                   1743: /*
                   1744:  * Misc functions
                   1745:  */
                   1746:
                   1747: void
                   1748: ar5k_ar5212_dump_state(struct ath_hal *hal)
                   1749: {
                   1750: #ifdef AR5K_DEBUG
                   1751: #define AR5K_PRINT_REGISTER(_x)                                                \
                   1752:        printf("(%s: %08x) ", #_x, AR5K_REG_READ(AR5K_AR5212_##_x));
                   1753:
                   1754:        printf("MAC registers:\n");
                   1755:        AR5K_PRINT_REGISTER(CR);
                   1756:        AR5K_PRINT_REGISTER(CFG);
                   1757:        AR5K_PRINT_REGISTER(IER);
                   1758:        AR5K_PRINT_REGISTER(TXCFG);
                   1759:        AR5K_PRINT_REGISTER(RXCFG);
                   1760:        AR5K_PRINT_REGISTER(MIBC);
                   1761:        AR5K_PRINT_REGISTER(TOPS);
                   1762:        AR5K_PRINT_REGISTER(RXNOFRM);
                   1763:        AR5K_PRINT_REGISTER(RPGTO);
                   1764:        AR5K_PRINT_REGISTER(RFCNT);
                   1765:        AR5K_PRINT_REGISTER(MISC);
                   1766:        AR5K_PRINT_REGISTER(PISR);
                   1767:        AR5K_PRINT_REGISTER(SISR0);
                   1768:        AR5K_PRINT_REGISTER(SISR1);
                   1769:        AR5K_PRINT_REGISTER(SISR3);
                   1770:        AR5K_PRINT_REGISTER(SISR4);
                   1771:        AR5K_PRINT_REGISTER(DCM_ADDR);
                   1772:        AR5K_PRINT_REGISTER(DCM_DATA);
                   1773:        AR5K_PRINT_REGISTER(DCCFG);
                   1774:        AR5K_PRINT_REGISTER(CCFG);
                   1775:        AR5K_PRINT_REGISTER(CCFG_CUP);
                   1776:        AR5K_PRINT_REGISTER(CPC0);
                   1777:        AR5K_PRINT_REGISTER(CPC1);
                   1778:        AR5K_PRINT_REGISTER(CPC2);
                   1779:        AR5K_PRINT_REGISTER(CPCORN);
                   1780:        AR5K_PRINT_REGISTER(QCU_TXE);
                   1781:        AR5K_PRINT_REGISTER(QCU_TXD);
                   1782:        AR5K_PRINT_REGISTER(DCU_GBL_IFS_SIFS);
                   1783:        AR5K_PRINT_REGISTER(DCU_GBL_IFS_SLOT);
                   1784:        AR5K_PRINT_REGISTER(DCU_FP);
                   1785:        AR5K_PRINT_REGISTER(DCU_TXP);
                   1786:        AR5K_PRINT_REGISTER(DCU_TX_FILTER);
                   1787:        AR5K_PRINT_REGISTER(RC);
                   1788:        AR5K_PRINT_REGISTER(SCR);
                   1789:        AR5K_PRINT_REGISTER(INTPEND);
                   1790:        AR5K_PRINT_REGISTER(PCICFG);
                   1791:        AR5K_PRINT_REGISTER(GPIOCR);
                   1792:        AR5K_PRINT_REGISTER(GPIODO);
                   1793:        AR5K_PRINT_REGISTER(SREV);
                   1794:        AR5K_PRINT_REGISTER(EEPROM_BASE);
                   1795:        AR5K_PRINT_REGISTER(EEPROM_DATA);
                   1796:        AR5K_PRINT_REGISTER(EEPROM_CMD);
                   1797:        AR5K_PRINT_REGISTER(EEPROM_CFG);
                   1798:        AR5K_PRINT_REGISTER(PCU_MIN);
                   1799:        AR5K_PRINT_REGISTER(STA_ID0);
                   1800:        AR5K_PRINT_REGISTER(STA_ID1);
                   1801:        AR5K_PRINT_REGISTER(BSS_ID0);
                   1802:        AR5K_PRINT_REGISTER(SLOT_TIME);
                   1803:        AR5K_PRINT_REGISTER(TIME_OUT);
                   1804:        AR5K_PRINT_REGISTER(RSSI_THR);
                   1805:        AR5K_PRINT_REGISTER(BEACON);
                   1806:        AR5K_PRINT_REGISTER(CFP_PERIOD);
                   1807:        AR5K_PRINT_REGISTER(TIMER0);
                   1808:        AR5K_PRINT_REGISTER(TIMER2);
                   1809:        AR5K_PRINT_REGISTER(TIMER3);
                   1810:        AR5K_PRINT_REGISTER(CFP_DUR);
                   1811:        AR5K_PRINT_REGISTER(MCAST_FIL0);
                   1812:        AR5K_PRINT_REGISTER(MCAST_FIL1);
                   1813:        AR5K_PRINT_REGISTER(DIAG_SW);
                   1814:        AR5K_PRINT_REGISTER(TSF_U32);
                   1815:        AR5K_PRINT_REGISTER(ADDAC_TEST);
                   1816:        AR5K_PRINT_REGISTER(DEFAULT_ANTENNA);
                   1817:        AR5K_PRINT_REGISTER(LAST_TSTP);
                   1818:        AR5K_PRINT_REGISTER(NAV);
                   1819:        AR5K_PRINT_REGISTER(RTS_OK);
                   1820:        AR5K_PRINT_REGISTER(ACK_FAIL);
                   1821:        AR5K_PRINT_REGISTER(FCS_FAIL);
                   1822:        AR5K_PRINT_REGISTER(BEACON_CNT);
                   1823:        AR5K_PRINT_REGISTER(TSF_PARM);
                   1824:        AR5K_PRINT_REGISTER(RATE_DUR_0);
                   1825:        AR5K_PRINT_REGISTER(KEYTABLE_0);
                   1826:        printf("\n");
                   1827:
                   1828:        printf("PHY registers:\n");
                   1829:        AR5K_PRINT_REGISTER(PHY_TURBO);
                   1830:        AR5K_PRINT_REGISTER(PHY_AGC);
                   1831:        AR5K_PRINT_REGISTER(PHY_TIMING_3);
                   1832:        AR5K_PRINT_REGISTER(PHY_CHIP_ID);
                   1833:        AR5K_PRINT_REGISTER(PHY_AGCCTL);
                   1834:        AR5K_PRINT_REGISTER(PHY_NF);
                   1835:        AR5K_PRINT_REGISTER(PHY_SCR);
                   1836:        AR5K_PRINT_REGISTER(PHY_SLMT);
                   1837:        AR5K_PRINT_REGISTER(PHY_SCAL);
                   1838:        AR5K_PRINT_REGISTER(PHY_RX_DELAY);
                   1839:        AR5K_PRINT_REGISTER(PHY_IQ);
                   1840:        AR5K_PRINT_REGISTER(PHY_PAPD_PROBE);
                   1841:        AR5K_PRINT_REGISTER(PHY_TXPOWER_RATE1);
                   1842:        AR5K_PRINT_REGISTER(PHY_TXPOWER_RATE2);
                   1843:        AR5K_PRINT_REGISTER(PHY_FC);
                   1844:        AR5K_PRINT_REGISTER(PHY_RADAR);
                   1845:        AR5K_PRINT_REGISTER(PHY_ANT_SWITCH_TABLE_0);
                   1846:        AR5K_PRINT_REGISTER(PHY_ANT_SWITCH_TABLE_1);
                   1847:        printf("\n");
                   1848: #endif
                   1849: }
                   1850:
                   1851: HAL_BOOL
                   1852: ar5k_ar5212_get_diag_state(struct ath_hal *hal, int id, void **device,
                   1853:     u_int *size)
                   1854: {
                   1855:        /*
                   1856:         * We'll ignore this right now. This seems to be some kind of an obscure
                   1857:         * debugging interface for the binary-only HAL.
                   1858:         */
                   1859:        return (AH_FALSE);
                   1860: }
                   1861:
                   1862: void
                   1863: ar5k_ar5212_get_lladdr(struct ath_hal *hal, u_int8_t *mac)
                   1864: {
                   1865:        bcopy(hal->ah_sta_id, mac, IEEE80211_ADDR_LEN);
                   1866: }
                   1867:
                   1868: HAL_BOOL
                   1869: ar5k_ar5212_set_lladdr(struct ath_hal *hal, const u_int8_t *mac)
                   1870: {
                   1871:        u_int32_t low_id, high_id;
                   1872:
                   1873:        /* Set new station ID */
                   1874:        bcopy(mac, hal->ah_sta_id, IEEE80211_ADDR_LEN);
                   1875:
                   1876:        low_id = AR5K_LOW_ID(mac);
                   1877:        high_id = 0x0000ffff & AR5K_HIGH_ID(mac);
                   1878:
                   1879:        AR5K_REG_WRITE(AR5K_AR5212_STA_ID0, low_id);
                   1880:        AR5K_REG_WRITE(AR5K_AR5212_STA_ID1, high_id);
                   1881:
                   1882:        return (AH_TRUE);
                   1883: }
                   1884:
                   1885: HAL_BOOL
                   1886: ar5k_ar5212_set_regdomain(struct ath_hal *hal, u_int16_t regdomain,
                   1887:     HAL_STATUS *status)
                   1888: {
                   1889:        ieee80211_regdomain_t ieee_regdomain;
                   1890:
                   1891:        ieee_regdomain = ar5k_regdomain_to_ieee(regdomain);
                   1892:
                   1893:        if (ar5k_eeprom_regulation_domain(hal, AH_TRUE,
                   1894:                &ieee_regdomain) == AH_TRUE) {
                   1895:                *status = HAL_OK;
                   1896:                return (AH_TRUE);
                   1897:        }
                   1898:
                   1899:        *status = EIO;
                   1900:
                   1901:        return (AH_FALSE);
                   1902: }
                   1903:
                   1904: void
                   1905: ar5k_ar5212_set_ledstate(struct ath_hal *hal, HAL_LED_STATE state)
                   1906: {
                   1907:        u_int32_t led;
                   1908:
                   1909:        AR5K_REG_DISABLE_BITS(AR5K_AR5212_PCICFG,
                   1910:            AR5K_AR5212_PCICFG_LEDMODE |  AR5K_AR5212_PCICFG_LED);
                   1911:
                   1912:        /*
                   1913:         * Some blinking values, define at your wish
                   1914:         */
                   1915:        switch (state) {
                   1916:        case IEEE80211_S_SCAN:
                   1917:        case IEEE80211_S_AUTH:
                   1918:                led = AR5K_AR5212_PCICFG_LEDMODE_PROP |
                   1919:                    AR5K_AR5212_PCICFG_LED_PEND;
                   1920:                break;
                   1921:
                   1922:        case IEEE80211_S_INIT:
                   1923:                led = AR5K_AR5212_PCICFG_LEDMODE_PROP |
                   1924:                    AR5K_AR5212_PCICFG_LED_NONE;
                   1925:                break;
                   1926:
                   1927:        case IEEE80211_S_ASSOC:
                   1928:        case IEEE80211_S_RUN:
                   1929:                led = AR5K_AR5212_PCICFG_LEDMODE_PROP |
                   1930:                    AR5K_AR5212_PCICFG_LED_ASSOC;
                   1931:                break;
                   1932:
                   1933:        default:
                   1934:                led = AR5K_AR5212_PCICFG_LEDMODE_PROM |
                   1935:                    AR5K_AR5212_PCICFG_LED_NONE;
                   1936:                break;
                   1937:        }
                   1938:
                   1939:        AR5K_REG_ENABLE_BITS(AR5K_AR5212_PCICFG, led);
                   1940: }
                   1941:
                   1942: void
                   1943: ar5k_ar5212_set_associd(struct ath_hal *hal, const u_int8_t *bssid,
                   1944:     u_int16_t assoc_id, u_int16_t tim_offset)
                   1945: {
                   1946:        u_int32_t low_id, high_id;
                   1947:
                   1948:        /*
                   1949:         * Set simple BSSID mask
                   1950:         */
                   1951:        AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM0, 0xfffffff);
                   1952:        AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM1, 0xfffffff);
                   1953:
                   1954:        /*
                   1955:         * Set BSSID which triggers the "SME Join" operation
                   1956:         */
                   1957:        low_id = AR5K_LOW_ID(bssid);
                   1958:        high_id = AR5K_HIGH_ID(bssid);
                   1959:        AR5K_REG_WRITE(AR5K_AR5212_BSS_ID0, low_id);
                   1960:        AR5K_REG_WRITE(AR5K_AR5212_BSS_ID1, high_id |
                   1961:            ((assoc_id & 0x3fff) << AR5K_AR5212_BSS_ID1_AID_S));
                   1962:        bcopy(bssid, &hal->ah_bssid, IEEE80211_ADDR_LEN);
                   1963:
                   1964:        if (assoc_id == 0) {
                   1965:                ar5k_ar5212_disable_pspoll(hal);
                   1966:                return;
                   1967:        }
                   1968:
                   1969:        AR5K_REG_WRITE(AR5K_AR5212_BEACON,
                   1970:            (AR5K_REG_READ(AR5K_AR5212_BEACON) &
                   1971:            ~AR5K_AR5212_BEACON_TIM) |
                   1972:            (((tim_offset ? tim_offset + 4 : 0) <<
                   1973:            AR5K_AR5212_BEACON_TIM_S) &
                   1974:            AR5K_AR5212_BEACON_TIM));
                   1975:
                   1976:        ar5k_ar5212_enable_pspoll(hal, NULL, 0);
                   1977: }
                   1978:
                   1979: HAL_BOOL
                   1980: ar5k_ar5212_set_bssid_mask(struct ath_hal *hal, const u_int8_t* mask)
                   1981: {
                   1982:        u_int32_t low_id, high_id;
                   1983:
                   1984:        low_id = AR5K_LOW_ID(mask);
                   1985:        high_id = 0x0000ffff & AR5K_HIGH_ID(mask);
                   1986:
                   1987:        AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM0, low_id);
                   1988:        AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM1, high_id);
                   1989:
                   1990:        return (AH_TRUE);
                   1991: }
                   1992:
                   1993: HAL_BOOL
                   1994: ar5k_ar5212_set_gpio_output(struct ath_hal *hal, u_int32_t gpio)
                   1995: {
                   1996:        if (gpio > AR5K_AR5212_NUM_GPIO)
                   1997:                return (AH_FALSE);
                   1998:
                   1999:        AR5K_REG_WRITE(AR5K_AR5212_GPIOCR,
                   2000:            (AR5K_REG_READ(AR5K_AR5212_GPIOCR) &~ AR5K_AR5212_GPIOCR_ALL(gpio))
                   2001:            | AR5K_AR5212_GPIOCR_ALL(gpio));
                   2002:
                   2003:        return (AH_TRUE);
                   2004: }
                   2005:
                   2006: HAL_BOOL
                   2007: ar5k_ar5212_set_gpio_input(struct ath_hal *hal, u_int32_t gpio)
                   2008: {
                   2009:        if (gpio > AR5K_AR5212_NUM_GPIO)
                   2010:                return (AH_FALSE);
                   2011:
                   2012:        AR5K_REG_WRITE(AR5K_AR5212_GPIOCR,
                   2013:            (AR5K_REG_READ(AR5K_AR5212_GPIOCR) &~ AR5K_AR5212_GPIOCR_ALL(gpio))
                   2014:            | AR5K_AR5212_GPIOCR_NONE(gpio));
                   2015:
                   2016:        return (AH_TRUE);
                   2017: }
                   2018:
                   2019: u_int32_t
                   2020: ar5k_ar5212_get_gpio(struct ath_hal *hal, u_int32_t gpio)
                   2021: {
                   2022:        if (gpio > AR5K_AR5212_NUM_GPIO)
                   2023:                return (0xffffffff);
                   2024:
                   2025:        /* GPIO input magic */
                   2026:        return (((AR5K_REG_READ(AR5K_AR5212_GPIODI) &
                   2027:            AR5K_AR5212_GPIODI_M) >> gpio) & 0x1);
                   2028: }
                   2029:
                   2030: HAL_BOOL
                   2031: ar5k_ar5212_set_gpio(struct ath_hal *hal, u_int32_t gpio, u_int32_t val)
                   2032: {
                   2033:        u_int32_t data;
                   2034:
                   2035:        if (gpio > AR5K_AR5212_NUM_GPIO)
                   2036:                return (0xffffffff);
                   2037:
                   2038:        /* GPIO output magic */
                   2039:        data =  AR5K_REG_READ(AR5K_AR5212_GPIODO);
                   2040:
                   2041:        data &= ~(1 << gpio);
                   2042:        data |= (val&1) << gpio;
                   2043:
                   2044:        AR5K_REG_WRITE(AR5K_AR5212_GPIODO, data);
                   2045:
                   2046:        return (AH_TRUE);
                   2047: }
                   2048:
                   2049: void
                   2050: ar5k_ar5212_set_gpio_intr(struct ath_hal *hal, u_int gpio,
                   2051:     u_int32_t interrupt_level)
                   2052: {
                   2053:        u_int32_t data;
                   2054:
                   2055:        if (gpio > AR5K_AR5212_NUM_GPIO)
                   2056:                return;
                   2057:
                   2058:        /*
                   2059:         * Set the GPIO interrupt
                   2060:         */
                   2061:        data = (AR5K_REG_READ(AR5K_AR5212_GPIOCR) &
                   2062:            ~(AR5K_AR5212_GPIOCR_INT_SEL(gpio) | AR5K_AR5212_GPIOCR_INT_SELH |
                   2063:            AR5K_AR5212_GPIOCR_INT_ENA | AR5K_AR5212_GPIOCR_ALL(gpio))) |
                   2064:            (AR5K_AR5212_GPIOCR_INT_SEL(gpio) | AR5K_AR5212_GPIOCR_INT_ENA);
                   2065:
                   2066:        AR5K_REG_WRITE(AR5K_AR5212_GPIOCR,
                   2067:            interrupt_level ? data : (data | AR5K_AR5212_GPIOCR_INT_SELH));
                   2068:
                   2069:        hal->ah_imr |= AR5K_AR5212_PIMR_GPIO;
                   2070:
                   2071:        /* Enable GPIO interrupts */
                   2072:        AR5K_REG_ENABLE_BITS(AR5K_AR5212_PIMR, AR5K_AR5212_PIMR_GPIO);
                   2073: }
                   2074:
                   2075: u_int32_t
                   2076: ar5k_ar5212_get_tsf32(struct ath_hal *hal)
                   2077: {
                   2078:        return (AR5K_REG_READ(AR5K_AR5212_TSF_L32));
                   2079: }
                   2080:
                   2081: u_int64_t
                   2082: ar5k_ar5212_get_tsf64(struct ath_hal *hal)
                   2083: {
                   2084:        u_int64_t tsf = AR5K_REG_READ(AR5K_AR5212_TSF_U32);
                   2085:
                   2086:        return (AR5K_REG_READ(AR5K_AR5212_TSF_L32) | (tsf << 32));
                   2087: }
                   2088:
                   2089: void
                   2090: ar5k_ar5212_reset_tsf(struct ath_hal *hal)
                   2091: {
                   2092:        AR5K_REG_ENABLE_BITS(AR5K_AR5212_BEACON,
                   2093:            AR5K_AR5212_BEACON_RESET_TSF);
                   2094: }
                   2095:
                   2096: u_int16_t
                   2097: ar5k_ar5212_get_regdomain(struct ath_hal *hal)
                   2098: {
                   2099:        return (ar5k_get_regdomain(hal));
                   2100: }
                   2101:
                   2102: HAL_BOOL
                   2103: ar5k_ar5212_detect_card_present(struct ath_hal *hal)
                   2104: {
                   2105:        u_int16_t magic;
                   2106:
                   2107:        /*
                   2108:         * Checking the EEPROM's magic value could be an indication
                   2109:         * if the card is still present. I didn't find another suitable
                   2110:         * way to do this.
                   2111:         */
                   2112:        if (ar5k_ar5212_eeprom_read(hal, AR5K_EEPROM_MAGIC, &magic) != 0)
                   2113:                return (AH_FALSE);
                   2114:
                   2115:        return (magic == AR5K_EEPROM_MAGIC_VALUE ? AH_TRUE : AH_FALSE);
                   2116: }
                   2117:
                   2118: void
                   2119: ar5k_ar5212_update_mib_counters(struct ath_hal *hal, HAL_MIB_STATS *statistics)
                   2120: {
                   2121:        /* Read-And-Clear */
                   2122:        statistics->ackrcv_bad += AR5K_REG_READ(AR5K_AR5212_ACK_FAIL);
                   2123:        statistics->rts_bad += AR5K_REG_READ(AR5K_AR5212_RTS_FAIL);
                   2124:        statistics->rts_good += AR5K_REG_READ(AR5K_AR5212_RTS_OK);
                   2125:        statistics->fcs_bad += AR5K_REG_READ(AR5K_AR5212_FCS_FAIL);
                   2126:        statistics->beacons += AR5K_REG_READ(AR5K_AR5212_BEACON_CNT);
                   2127:
                   2128:        /* Reset profile count registers */
                   2129:        AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_TX, 0);
                   2130:        AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_RX, 0);
                   2131:        AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_RXCLR, 0);
                   2132:        AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_CYCLE, 0);
                   2133: }
                   2134:
                   2135: HAL_RFGAIN
                   2136: ar5k_ar5212_get_rf_gain(struct ath_hal *hal)
                   2137: {
                   2138:        u_int32_t data, type;
                   2139:
                   2140:        if ((hal->ah_rf_banks == NULL) || (!hal->ah_gain.g_active))
                   2141:                return (HAL_RFGAIN_INACTIVE);
                   2142:
                   2143:        if (hal->ah_rf_gain != HAL_RFGAIN_READ_REQUESTED)
                   2144:                goto done;
                   2145:
                   2146:        data = AR5K_REG_READ(AR5K_AR5212_PHY_PAPD_PROBE);
                   2147:
                   2148:        if (!(data & AR5K_AR5212_PHY_PAPD_PROBE_TX_NEXT)) {
                   2149:                hal->ah_gain.g_current =
                   2150:                    data >> AR5K_AR5212_PHY_PAPD_PROBE_GAINF_S;
                   2151:                type = AR5K_REG_MS(data, AR5K_AR5212_PHY_PAPD_PROBE_TYPE);
                   2152:
                   2153:                if (type == AR5K_AR5212_PHY_PAPD_PROBE_TYPE_CCK)
                   2154:                        hal->ah_gain.g_current += AR5K_GAIN_CCK_PROBE_CORR;
                   2155:
                   2156:                if (hal->ah_radio == AR5K_AR5112) {
                   2157:                        ar5k_rfregs_gainf_corr(hal);
                   2158:                        hal->ah_gain.g_current =
                   2159:                            hal->ah_gain.g_current >= hal->ah_gain.g_f_corr ?
                   2160:                            (hal->ah_gain.g_current - hal->ah_gain.g_f_corr) :
                   2161:                            0;
                   2162:                }
                   2163:
                   2164:                if (ar5k_rfregs_gain_readback(hal) &&
                   2165:                    AR5K_GAIN_CHECK_ADJUST(&hal->ah_gain) &&
                   2166:                    ar5k_rfregs_gain_adjust(hal))
                   2167:                        hal->ah_rf_gain = HAL_RFGAIN_NEED_CHANGE;
                   2168:        }
                   2169:
                   2170:  done:
                   2171:        return (hal->ah_rf_gain);
                   2172: }
                   2173:
                   2174: HAL_BOOL
                   2175: ar5k_ar5212_set_slot_time(struct ath_hal *hal, u_int slot_time)
                   2176: {
                   2177:        if (slot_time < HAL_SLOT_TIME_9 || slot_time > HAL_SLOT_TIME_MAX)
                   2178:                return (AH_FALSE);
                   2179:
                   2180:        AR5K_REG_WRITE(AR5K_AR5212_DCU_GBL_IFS_SLOT, slot_time);
                   2181:
                   2182:        return (AH_TRUE);
                   2183: }
                   2184:
                   2185: u_int
                   2186: ar5k_ar5212_get_slot_time(struct ath_hal *hal)
                   2187: {
                   2188:        return (AR5K_REG_READ(AR5K_AR5212_DCU_GBL_IFS_SLOT) & 0xffff);
                   2189: }
                   2190:
                   2191: HAL_BOOL
                   2192: ar5k_ar5212_set_ack_timeout(struct ath_hal *hal, u_int timeout)
                   2193: {
                   2194:        if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5212_TIME_OUT_ACK),
                   2195:            hal->ah_turbo) <= timeout)
                   2196:                return (AH_FALSE);
                   2197:
                   2198:        AR5K_REG_WRITE_BITS(AR5K_AR5212_TIME_OUT, AR5K_AR5212_TIME_OUT_ACK,
                   2199:            ar5k_htoclock(timeout, hal->ah_turbo));
                   2200:
                   2201:        return (AH_TRUE);
                   2202: }
                   2203:
                   2204: u_int
                   2205: ar5k_ar5212_get_ack_timeout(struct ath_hal *hal)
                   2206: {
                   2207:        return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5212_TIME_OUT),
                   2208:            AR5K_AR5212_TIME_OUT_ACK), hal->ah_turbo));
                   2209: }
                   2210:
                   2211: HAL_BOOL
                   2212: ar5k_ar5212_set_cts_timeout(struct ath_hal *hal, u_int timeout)
                   2213: {
                   2214:        if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5212_TIME_OUT_CTS),
                   2215:            hal->ah_turbo) <= timeout)
                   2216:                return (AH_FALSE);
                   2217:
                   2218:        AR5K_REG_WRITE_BITS(AR5K_AR5212_TIME_OUT, AR5K_AR5212_TIME_OUT_CTS,
                   2219:            ar5k_htoclock(timeout, hal->ah_turbo));
                   2220:
                   2221:        return (AH_TRUE);
                   2222: }
                   2223:
                   2224: u_int
                   2225: ar5k_ar5212_get_cts_timeout(struct ath_hal *hal)
                   2226: {
                   2227:        return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5212_TIME_OUT),
                   2228:            AR5K_AR5212_TIME_OUT_CTS), hal->ah_turbo));
                   2229: }
                   2230:
                   2231: /*
                   2232:  * Key table (WEP) functions
                   2233:  */
                   2234:
                   2235: HAL_BOOL
                   2236: ar5k_ar5212_is_cipher_supported(struct ath_hal *hal, HAL_CIPHER cipher)
                   2237: {
                   2238:        /*
                   2239:         * The AR5212 only supports WEP
                   2240:         */
                   2241:        if (cipher == HAL_CIPHER_WEP)
                   2242:                return (AH_TRUE);
                   2243:
                   2244:        return (AH_FALSE);
                   2245: }
                   2246:
                   2247: u_int32_t
                   2248: ar5k_ar5212_get_keycache_size(struct ath_hal *hal)
                   2249: {
                   2250:        return (AR5K_AR5212_KEYCACHE_SIZE);
                   2251: }
                   2252:
                   2253: HAL_BOOL
                   2254: ar5k_ar5212_reset_key(struct ath_hal *hal, u_int16_t entry)
                   2255: {
                   2256:        int i;
                   2257:
                   2258:        AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
                   2259:
                   2260:        for (i = 0; i < AR5K_AR5212_KEYCACHE_SIZE; i++)
                   2261:                AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_OFF(entry, i), 0);
                   2262:
                   2263:        /* Set NULL encryption */
                   2264:        AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_TYPE(entry),
                   2265:            AR5K_AR5212_KEYTABLE_TYPE_NULL);
                   2266:
                   2267:        return (AH_FALSE);
                   2268: }
                   2269:
                   2270: HAL_BOOL
                   2271: ar5k_ar5212_is_key_valid(struct ath_hal *hal, u_int16_t entry)
                   2272: {
                   2273:        AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
                   2274:
                   2275:        /*
                   2276:         * Check the validation flag at the end of the entry
                   2277:         */
                   2278:        if (AR5K_REG_READ(AR5K_AR5212_KEYTABLE_MAC1(entry)) &
                   2279:            AR5K_AR5212_KEYTABLE_VALID)
                   2280:                return (AH_TRUE);
                   2281:
                   2282:        return (AH_FALSE);
                   2283: }
                   2284:
                   2285: HAL_BOOL
                   2286: ar5k_ar5212_set_key(struct ath_hal *hal, u_int16_t entry,
                   2287:     const HAL_KEYVAL *keyval, const u_int8_t *mac, int xor_notused)
                   2288: {
                   2289:        int i;
                   2290:        u_int32_t key_v[AR5K_AR5212_KEYCACHE_SIZE - 2];
                   2291:
                   2292:        AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
                   2293:
                   2294:        bzero(&key_v, sizeof(key_v));
                   2295:
                   2296:        switch (keyval->wk_len) {
                   2297:        case AR5K_KEYVAL_LENGTH_40:
                   2298:                bcopy(keyval->wk_key, &key_v[0], 4);
                   2299:                bcopy(keyval->wk_key + 4, &key_v[1], 1);
                   2300:                key_v[5] = AR5K_AR5212_KEYTABLE_TYPE_40;
                   2301:                break;
                   2302:
                   2303:        case AR5K_KEYVAL_LENGTH_104:
                   2304:                bcopy(keyval->wk_key, &key_v[0], 4);
                   2305:                bcopy(keyval->wk_key + 4, &key_v[1], 2);
                   2306:                bcopy(keyval->wk_key + 6, &key_v[2], 4);
                   2307:                bcopy(keyval->wk_key + 10, &key_v[3], 2);
                   2308:                bcopy(keyval->wk_key + 12, &key_v[4], 1);
                   2309:                key_v[5] = AR5K_AR5212_KEYTABLE_TYPE_104;
                   2310:                break;
                   2311:
                   2312:        case AR5K_KEYVAL_LENGTH_128:
                   2313:                bcopy(keyval->wk_key, &key_v[0], 4);
                   2314:                bcopy(keyval->wk_key + 4, &key_v[1], 2);
                   2315:                bcopy(keyval->wk_key + 6, &key_v[2], 4);
                   2316:                bcopy(keyval->wk_key + 10, &key_v[3], 2);
                   2317:                bcopy(keyval->wk_key + 12, &key_v[4], 4);
                   2318:                key_v[5] = AR5K_AR5212_KEYTABLE_TYPE_128;
                   2319:                break;
                   2320:
                   2321:        default:
                   2322:                /* Unsupported key length (not WEP40/104/128) */
                   2323:                return (AH_FALSE);
                   2324:        }
                   2325:
                   2326:        for (i = 0; i < AR5K_ELEMENTS(key_v); i++)
                   2327:                AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_OFF(entry, i), key_v[i]);
                   2328:
                   2329:        return (ar5k_ar5212_set_key_lladdr(hal, entry, mac));
                   2330: }
                   2331:
                   2332: HAL_BOOL
                   2333: ar5k_ar5212_set_key_lladdr(struct ath_hal *hal, u_int16_t entry,
                   2334:     const u_int8_t *mac)
                   2335: {
                   2336:        u_int32_t low_id, high_id;
                   2337:        const u_int8_t *mac_v;
                   2338:
                   2339:        /*
                   2340:         * Invalid entry (key table overflow)
                   2341:         */
                   2342:        AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
                   2343:
                   2344:        /* MAC may be NULL if it's a broadcast key */
                   2345:        mac_v = mac == NULL ? etherbroadcastaddr : mac;
                   2346:
                   2347:        low_id = AR5K_LOW_ID(mac_v);
                   2348:        high_id = AR5K_HIGH_ID(mac_v) | AR5K_AR5212_KEYTABLE_VALID;
                   2349:
                   2350:        AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_MAC0(entry), low_id);
                   2351:        AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_MAC1(entry), high_id);
                   2352:
                   2353:        return (AH_TRUE);
                   2354: }
                   2355:
                   2356: /*
                   2357:  * Power management functions
                   2358:  */
                   2359:
                   2360: HAL_BOOL
                   2361: ar5k_ar5212_set_power(struct ath_hal *hal, HAL_POWER_MODE mode,
                   2362:     HAL_BOOL set_chip, u_int16_t sleep_duration)
                   2363: {
                   2364:        u_int32_t staid;
                   2365:        int i;
                   2366:
                   2367:        staid = AR5K_REG_READ(AR5K_AR5212_STA_ID1);
                   2368:
                   2369:        switch (mode) {
                   2370:        case HAL_PM_AUTO:
                   2371:                staid &= ~AR5K_AR5212_STA_ID1_DEFAULT_ANTENNA;
                   2372:                /* FALLTHROUGH */
                   2373:        case HAL_PM_NETWORK_SLEEP:
                   2374:                if (set_chip == AH_TRUE) {
                   2375:                        AR5K_REG_WRITE(AR5K_AR5212_SCR,
                   2376:                            AR5K_AR5212_SCR_SLE | sleep_duration);
                   2377:                }
                   2378:                staid |= AR5K_AR5212_STA_ID1_PWR_SV;
                   2379:                break;
                   2380:
                   2381:        case HAL_PM_FULL_SLEEP:
                   2382:                if (set_chip == AH_TRUE) {
                   2383:                        AR5K_REG_WRITE(AR5K_AR5212_SCR,
                   2384:                            AR5K_AR5212_SCR_SLE_SLP);
                   2385:                }
                   2386:                staid |= AR5K_AR5212_STA_ID1_PWR_SV;
                   2387:                break;
                   2388:
                   2389:        case HAL_PM_AWAKE:
                   2390:                if (set_chip == AH_FALSE)
                   2391:                        goto commit;
                   2392:
                   2393:                AR5K_REG_WRITE(AR5K_AR5212_SCR, AR5K_AR5212_SCR_SLE_WAKE);
                   2394:
                   2395:                for (i = 5000; i > 0; i--) {
                   2396:                        /* Check if the AR5212 did wake up */
                   2397:                        if ((AR5K_REG_READ(AR5K_AR5212_PCICFG) &
                   2398:                            AR5K_AR5212_PCICFG_SPWR_DN) == 0)
                   2399:                                break;
                   2400:
                   2401:                        /* Wait a bit and retry */
                   2402:                        AR5K_DELAY(200);
                   2403:                        AR5K_REG_WRITE(AR5K_AR5212_SCR,
                   2404:                            AR5K_AR5212_SCR_SLE_WAKE);
                   2405:                }
                   2406:
                   2407:                /* Fail if the AR5212 didn't wake up */
                   2408:                if (i <= 0)
                   2409:                        return (AH_FALSE);
                   2410:
                   2411:                staid &= ~AR5K_AR5212_STA_ID1_PWR_SV;
                   2412:                break;
                   2413:
                   2414:        default:
                   2415:                return (AH_FALSE);
                   2416:        }
                   2417:
                   2418:  commit:
                   2419:        hal->ah_power_mode = mode;
                   2420:
                   2421:        AR5K_REG_WRITE(AR5K_AR5212_STA_ID1, staid);
                   2422:
                   2423:        return (AH_TRUE);
                   2424: }
                   2425:
                   2426: HAL_POWER_MODE
                   2427: ar5k_ar5212_get_power_mode(struct ath_hal *hal)
                   2428: {
                   2429:        return (hal->ah_power_mode);
                   2430: }
                   2431:
                   2432: HAL_BOOL
                   2433: ar5k_ar5212_query_pspoll_support(struct ath_hal *hal)
                   2434: {
                   2435:        /* nope */
                   2436:        return (AH_FALSE);
                   2437: }
                   2438:
                   2439: HAL_BOOL
                   2440: ar5k_ar5212_init_pspoll(struct ath_hal *hal)
                   2441: {
                   2442:        /*
                   2443:         * Not used on the AR5212
                   2444:         */
                   2445:        return (AH_FALSE);
                   2446: }
                   2447:
                   2448: HAL_BOOL
                   2449: ar5k_ar5212_enable_pspoll(struct ath_hal *hal, u_int8_t *bssid,
                   2450:     u_int16_t assoc_id)
                   2451: {
                   2452:        return (AH_FALSE);
                   2453: }
                   2454:
                   2455: HAL_BOOL
                   2456: ar5k_ar5212_disable_pspoll(struct ath_hal *hal)
                   2457: {
                   2458:        return (AH_FALSE);
                   2459: }
                   2460:
                   2461: /*
                   2462:  * Beacon functions
                   2463:  */
                   2464:
                   2465: void
                   2466: ar5k_ar5212_init_beacon(struct ath_hal *hal, u_int32_t next_beacon,
                   2467:     u_int32_t interval)
                   2468: {
                   2469:        u_int32_t timer1, timer2, timer3;
                   2470:
                   2471:        /*
                   2472:         * Set the additional timers by mode
                   2473:         */
                   2474:        switch (hal->ah_op_mode) {
                   2475:        case HAL_M_STA:
                   2476:                timer1 = 0x0000ffff;
                   2477:                timer2 = 0x0007ffff;
                   2478:                break;
                   2479:
                   2480:        default:
                   2481:                timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) <<
                   2482:                    0x00000003;
                   2483:                timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) <<
                   2484:                    0x00000003;
                   2485:        }
                   2486:
                   2487:        timer3 = next_beacon +
                   2488:            (hal->ah_atim_window ? hal->ah_atim_window : 1);
                   2489:
                   2490:        /*
                   2491:         * Enable all timers and set the beacon register
                   2492:         * (next beacon, DMA beacon, software beacon, ATIM window time)
                   2493:         */
                   2494:        AR5K_REG_WRITE(AR5K_AR5212_TIMER0, next_beacon);
                   2495:        AR5K_REG_WRITE(AR5K_AR5212_TIMER1, timer1);
                   2496:        AR5K_REG_WRITE(AR5K_AR5212_TIMER2, timer2);
                   2497:        AR5K_REG_WRITE(AR5K_AR5212_TIMER3, timer3);
                   2498:
                   2499:        AR5K_REG_WRITE(AR5K_AR5212_BEACON, interval &
                   2500:            (AR5K_AR5212_BEACON_PERIOD | AR5K_AR5212_BEACON_RESET_TSF |
                   2501:            AR5K_AR5212_BEACON_ENABLE));
                   2502: }
                   2503:
                   2504: void
                   2505: ar5k_ar5212_set_beacon_timers(struct ath_hal *hal,
                   2506:     const HAL_BEACON_STATE *state, u_int32_t tsf, u_int32_t dtim_count,
                   2507:     u_int32_t cfp_count)
                   2508: {
                   2509:        u_int32_t cfp_period, next_cfp, dtim, interval, next_beacon;
                   2510:
                   2511:        /* Return on an invalid beacon state */
                   2512:        if (state->bs_interval < 1)
                   2513:                return;
                   2514:
                   2515:        interval = state->bs_intval;
                   2516:        dtim = state->bs_dtimperiod;
                   2517:
                   2518:        /*
                   2519:         * PCF support?
                   2520:         */
                   2521:        if (state->bs_cfp_period > 0) {
                   2522:                /* Enable CFP mode and set the CFP and timer registers */
                   2523:                cfp_period = state->bs_cfp_period * state->bs_dtim_period *
                   2524:                    state->bs_interval;
                   2525:                next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
                   2526:                    state->bs_interval;
                   2527:
                   2528:                AR5K_REG_ENABLE_BITS(AR5K_AR5212_STA_ID1,
                   2529:                    AR5K_AR5212_STA_ID1_PCF);
                   2530:                AR5K_REG_WRITE(AR5K_AR5212_CFP_PERIOD, cfp_period);
                   2531:                AR5K_REG_WRITE(AR5K_AR5212_CFP_DUR, state->bs_cfp_max_duration);
                   2532:                AR5K_REG_WRITE(AR5K_AR5212_TIMER2,
                   2533:                    (tsf + (next_cfp == 0 ? cfp_period : next_cfp)) << 3);
                   2534:        } else {
                   2535:                /* Disable PCF mode */
                   2536:                AR5K_REG_DISABLE_BITS(AR5K_AR5212_STA_ID1,
                   2537:                    AR5K_AR5212_STA_ID1_PCF);
                   2538:        }
                   2539:
                   2540:        /*
                   2541:         * Enable the beacon timer register
                   2542:         */
                   2543:        AR5K_REG_WRITE(AR5K_AR5212_TIMER0, state->bs_next_beacon);
                   2544:
                   2545:        /*
                   2546:         * Start the beacon timers
                   2547:         */
                   2548:        AR5K_REG_WRITE(AR5K_AR5212_BEACON,
                   2549:            (AR5K_REG_READ(AR5K_AR5212_BEACON) &~
                   2550:            (AR5K_AR5212_BEACON_PERIOD | AR5K_AR5212_BEACON_TIM)) |
                   2551:            AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
                   2552:            AR5K_AR5212_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
                   2553:            AR5K_AR5212_BEACON_PERIOD));
                   2554:
                   2555:        /*
                   2556:         * Write new beacon miss threshold, if it appears to be valid
                   2557:         */
                   2558:        if ((AR5K_AR5212_RSSI_THR_BMISS >> AR5K_AR5212_RSSI_THR_BMISS_S) <
                   2559:            state->bs_bmiss_threshold)
                   2560:                return;
                   2561:
                   2562:        AR5K_REG_WRITE_BITS(AR5K_AR5212_RSSI_THR_M,
                   2563:            AR5K_AR5212_RSSI_THR_BMISS, state->bs_bmiss_threshold);
                   2564:
                   2565:        /*
                   2566:         * Set sleep registers
                   2567:         */
                   2568:        if ((state->bs_sleepduration > state->bs_interval) &&
                   2569:            (roundup(state->bs_sleepduration, interval) ==
                   2570:            state->bs_sleepduration))
                   2571:                interval = state->bs_sleepduration;
                   2572:
                   2573:        if (state->bs_sleepduration > dtim &&
                   2574:            (dtim == 0 || roundup(state->bs_sleepduration, dtim) ==
                   2575:            state->bs_sleepduration))
                   2576:                dtim = state->bs_sleepduration;
                   2577:
                   2578:        if (interval > dtim)
                   2579:                return;
                   2580:
                   2581:        next_beacon = interval == dtim ?
                   2582:            state->bs_nextdtim: state->bs_nexttbtt;
                   2583:
                   2584:        AR5K_REG_WRITE(AR5K_AR5212_SLEEP0,
                   2585:            AR5K_REG_SM((state->bs_nextdtim - 3) << 3,
                   2586:            AR5K_AR5212_SLEEP0_NEXT_DTIM) |
                   2587:            AR5K_REG_SM(10, AR5K_AR5212_SLEEP0_CABTO) |
                   2588:            AR5K_AR5212_SLEEP0_ENH_SLEEP_EN |
                   2589:            AR5K_AR5212_SLEEP0_ASSUME_DTIM);
                   2590:        AR5K_REG_WRITE(AR5K_AR5212_SLEEP1,
                   2591:            AR5K_REG_SM((next_beacon - 3) << 3,
                   2592:            AR5K_AR5212_SLEEP1_NEXT_TIM) |
                   2593:            AR5K_REG_SM(10, AR5K_AR5212_SLEEP1_BEACON_TO));
                   2594:        AR5K_REG_WRITE(AR5K_AR5212_SLEEP2,
                   2595:            AR5K_REG_SM(interval, AR5K_AR5212_SLEEP2_TIM_PER) |
                   2596:            AR5K_REG_SM(dtim, AR5K_AR5212_SLEEP2_DTIM_PER));
                   2597: }
                   2598:
                   2599: void
                   2600: ar5k_ar5212_reset_beacon(struct ath_hal *hal)
                   2601: {
                   2602:        /*
                   2603:         * Disable beacon timer
                   2604:         */
                   2605:        AR5K_REG_WRITE(AR5K_AR5212_TIMER0, 0);
                   2606:
                   2607:        /*
                   2608:         * Disable some beacon register values
                   2609:         */
                   2610:        AR5K_REG_DISABLE_BITS(AR5K_AR5212_STA_ID1,
                   2611:            AR5K_AR5212_STA_ID1_DEFAULT_ANTENNA | AR5K_AR5212_STA_ID1_PCF);
                   2612:        AR5K_REG_WRITE(AR5K_AR5212_BEACON, AR5K_AR5212_BEACON_PERIOD);
                   2613: }
                   2614:
                   2615: HAL_BOOL
                   2616: ar5k_ar5212_wait_for_beacon(struct ath_hal *hal, bus_addr_t phys_addr)
                   2617: {
                   2618:        HAL_BOOL ret;
                   2619:
                   2620:        /*
                   2621:         * Wait for beaconn queue to be done
                   2622:         */
                   2623:        ret = ar5k_register_timeout(hal,
                   2624:            AR5K_AR5212_QCU_STS(HAL_TX_QUEUE_ID_BEACON),
                   2625:            AR5K_AR5212_QCU_STS_FRMPENDCNT, 0, AH_FALSE);
                   2626:
                   2627:        if (AR5K_REG_READ_Q(AR5K_AR5212_QCU_TXE, HAL_TX_QUEUE_ID_BEACON))
                   2628:                return (AH_FALSE);
                   2629:
                   2630:        return (ret);
                   2631: }
                   2632:
                   2633: /*
                   2634:  * Interrupt handling
                   2635:  */
                   2636:
                   2637: HAL_BOOL
                   2638: ar5k_ar5212_is_intr_pending(struct ath_hal *hal)
                   2639: {
                   2640:        return (AR5K_REG_READ(AR5K_AR5212_INTPEND) == 0 ? AH_FALSE : AH_TRUE);
                   2641: }
                   2642:
                   2643: HAL_BOOL
                   2644: ar5k_ar5212_get_isr(struct ath_hal *hal, u_int32_t *interrupt_mask)
                   2645: {
                   2646:        u_int32_t data;
                   2647:
                   2648:        /*
                   2649:         * Read interrupt status from the Read-And-Clear shadow register
                   2650:         */
                   2651:        data = AR5K_REG_READ(AR5K_AR5212_RAC_PISR);
                   2652:
                   2653:        /*
                   2654:         * Get abstract interrupt mask (HAL-compatible)
                   2655:         */
                   2656:        *interrupt_mask = (data & HAL_INT_COMMON) & hal->ah_imr;
                   2657:
                   2658:        if (data == HAL_INT_NOCARD)
                   2659:                return (AH_FALSE);
                   2660:
                   2661:        if (data & (AR5K_AR5212_PISR_RXOK | AR5K_AR5212_PISR_RXERR))
                   2662:                *interrupt_mask |= HAL_INT_RX;
                   2663:
                   2664:        if (data & (AR5K_AR5212_PISR_TXOK | AR5K_AR5212_PISR_TXERR))
                   2665:                *interrupt_mask |= HAL_INT_TX;
                   2666:
                   2667:        if (data & (AR5K_AR5212_PISR_HIUERR))
                   2668:                *interrupt_mask |= HAL_INT_FATAL;
                   2669:
                   2670:        /*
                   2671:         * Special interrupt handling (not caught by the driver)
                   2672:         */
                   2673:        if (((*interrupt_mask) & AR5K_AR5212_PISR_RXPHY) &&
                   2674:            hal->ah_radar.r_enabled == AH_TRUE)
                   2675:                ar5k_radar_alert(hal);
                   2676:
                   2677:        if (*interrupt_mask == 0)
                   2678:                AR5K_PRINTF("0x%08x\n", data);
                   2679:
                   2680:        return (AH_TRUE);
                   2681: }
                   2682:
                   2683: u_int32_t
                   2684: ar5k_ar5212_get_intr(struct ath_hal *hal)
                   2685: {
                   2686:        /* Return the interrupt mask stored previously */
                   2687:        return (hal->ah_imr);
                   2688: }
                   2689:
                   2690: HAL_INT
                   2691: ar5k_ar5212_set_intr(struct ath_hal *hal, HAL_INT new_mask)
                   2692: {
                   2693:        HAL_INT old_mask, int_mask;
                   2694:
                   2695:        /*
                   2696:         * Disable card interrupts to prevent any race conditions
                   2697:         * (they will be re-enabled afterwards).
                   2698:         */
                   2699:        AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_DISABLE);
                   2700:
                   2701:        old_mask = hal->ah_imr;
                   2702:
                   2703:        /*
                   2704:         * Add additional, chipset-dependent interrupt mask flags
                   2705:         * and write them to the IMR (interrupt mask register).
                   2706:         */
                   2707:        int_mask = new_mask & HAL_INT_COMMON;
                   2708:
                   2709:        if (new_mask & HAL_INT_RX)
                   2710:                int_mask |=
                   2711:                    AR5K_AR5212_PIMR_RXOK |
                   2712:                    AR5K_AR5212_PIMR_RXERR |
                   2713:                    AR5K_AR5212_PIMR_RXORN |
                   2714:                    AR5K_AR5212_PIMR_RXDESC;
                   2715:
                   2716:        if (new_mask & HAL_INT_TX)
                   2717:                int_mask |=
                   2718:                    AR5K_AR5212_PIMR_TXOK |
                   2719:                    AR5K_AR5212_PIMR_TXERR |
                   2720:                    AR5K_AR5212_PIMR_TXDESC |
                   2721:                    AR5K_AR5212_PIMR_TXURN;
                   2722:
                   2723:        if (new_mask & HAL_INT_FATAL) {
                   2724:                int_mask |= AR5K_AR5212_PIMR_HIUERR;
                   2725:                AR5K_REG_ENABLE_BITS(AR5K_AR5212_SIMR2,
                   2726:                    AR5K_AR5212_SIMR2_MCABT |
                   2727:                    AR5K_AR5212_SIMR2_SSERR |
                   2728:                    AR5K_AR5212_SIMR2_DPERR);
                   2729:        }
                   2730:
                   2731:        AR5K_REG_WRITE(AR5K_AR5212_PIMR, int_mask);
                   2732:
                   2733:        /* Store new interrupt mask */
                   2734:        hal->ah_imr = new_mask;
                   2735:
                   2736:        /* ..re-enable interrupts */
                   2737:        AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_ENABLE);
                   2738:
                   2739:        return (old_mask);
                   2740: }
                   2741:
                   2742: /*
                   2743:  * Misc internal functions
                   2744:  */
                   2745:
                   2746: HAL_BOOL
                   2747: ar5k_ar5212_get_capabilities(struct ath_hal *hal)
                   2748: {
                   2749:        u_int16_t ee_header;
                   2750:
                   2751:        /* Capabilities stored in the EEPROM */
                   2752:        ee_header = hal->ah_capabilities.cap_eeprom.ee_header;
                   2753:
                   2754:        /*
                   2755:         * XXX The AR5212 tranceiver supports frequencies from 4920 to 6100GHz
                   2756:         * XXX and from 2312 to 2732GHz. There are problems with the current
                   2757:         * XXX ieee80211 implementation because the IEEE channel mapping
                   2758:         * XXX does not support negative channel numbers (2312MHz is channel
                   2759:         * XXX -19). Of course, this doesn't matter because these channels
                   2760:         * XXX are out of range but some regulation domains like MKK (Japan)
                   2761:         * XXX will support frequencies somewhere around 4.8GHz.
                   2762:         */
                   2763:
                   2764:        /*
                   2765:         * Set radio capabilities
                   2766:         */
                   2767:
                   2768:        if (AR5K_EEPROM_HDR_11A(ee_header)) {
                   2769:                hal->ah_capabilities.cap_range.range_5ghz_min = 5005; /* 4920 */
                   2770:                hal->ah_capabilities.cap_range.range_5ghz_max = 6100;
                   2771:
                   2772:                /* Set supported modes */
                   2773:                hal->ah_capabilities.cap_mode =
                   2774:                    HAL_MODE_11A | HAL_MODE_TURBO | HAL_MODE_XR;
                   2775:        }
                   2776:
                   2777:        /* This chip will support 802.11b if the 2GHz radio is connected */
                   2778:        if (AR5K_EEPROM_HDR_11B(ee_header) || AR5K_EEPROM_HDR_11G(ee_header)) {
                   2779:                hal->ah_capabilities.cap_range.range_2ghz_min = 2412; /* 2312 */
                   2780:                hal->ah_capabilities.cap_range.range_2ghz_max = 2732;
                   2781:
                   2782:                if (AR5K_EEPROM_HDR_11B(ee_header))
                   2783:                        hal->ah_capabilities.cap_mode |= HAL_MODE_11B;
                   2784: #if 0
                   2785:                if (AR5K_EEPROM_HDR_11G(ee_header))
                   2786:                        hal->ah_capabilities.cap_mode |= HAL_MODE_11G;
                   2787: #endif
                   2788:        }
                   2789:
                   2790:        /* GPIO */
                   2791:        hal->ah_gpio_npins = AR5K_AR5212_NUM_GPIO;
                   2792:
                   2793:        /* Set number of supported TX queues */
                   2794:        hal->ah_capabilities.cap_queues.q_tx_num = AR5K_AR5212_TX_NUM_QUEUES;
                   2795:
                   2796:        return (AH_TRUE);
                   2797: }
                   2798:
                   2799: void
                   2800: ar5k_ar5212_radar_alert(struct ath_hal *hal, HAL_BOOL enable)
                   2801: {
                   2802:        /*
                   2803:         * Enable radar detection
                   2804:         */
                   2805:        AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_DISABLE);
                   2806:
                   2807:        if (enable == AH_TRUE) {
                   2808:                AR5K_REG_WRITE(AR5K_AR5212_PHY_RADAR,
                   2809:                    AR5K_AR5212_PHY_RADAR_ENABLE);
                   2810:                AR5K_REG_ENABLE_BITS(AR5K_AR5212_PIMR,
                   2811:                    AR5K_AR5212_PIMR_RXPHY);
                   2812:        } else {
                   2813:                AR5K_REG_WRITE(AR5K_AR5212_PHY_RADAR,
                   2814:                    AR5K_AR5212_PHY_RADAR_DISABLE);
                   2815:                AR5K_REG_DISABLE_BITS(AR5K_AR5212_PIMR,
                   2816:                    AR5K_AR5212_PIMR_RXPHY);
                   2817:        }
                   2818:
                   2819:        AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_ENABLE);
                   2820: }
                   2821:
                   2822: /*
                   2823:  * EEPROM access functions
                   2824:  */
                   2825:
                   2826: HAL_BOOL
                   2827: ar5k_ar5212_eeprom_is_busy(struct ath_hal *hal)
                   2828: {
                   2829:        return (AR5K_REG_READ(AR5K_AR5212_CFG) & AR5K_AR5212_CFG_EEBS ?
                   2830:            AH_TRUE : AH_FALSE);
                   2831: }
                   2832:
                   2833: int
                   2834: ar5k_ar5212_eeprom_read(struct ath_hal *hal, u_int32_t offset, u_int16_t *data)
                   2835: {
                   2836:        u_int32_t status, i;
                   2837:
                   2838:        /*
                   2839:         * Initialize EEPROM access
                   2840:         */
                   2841:        AR5K_REG_WRITE(AR5K_AR5212_EEPROM_BASE, (u_int8_t)offset);
                   2842:        AR5K_REG_ENABLE_BITS(AR5K_AR5212_EEPROM_CMD,
                   2843:            AR5K_AR5212_EEPROM_CMD_READ);
                   2844:
                   2845:        for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
                   2846:                status = AR5K_REG_READ(AR5K_AR5212_EEPROM_STATUS);
                   2847:                if (status & AR5K_AR5212_EEPROM_STAT_RDDONE) {
                   2848:                        if (status & AR5K_AR5212_EEPROM_STAT_RDERR)
                   2849:                                return (EIO);
                   2850:                        *data = (u_int16_t)
                   2851:                            (AR5K_REG_READ(AR5K_AR5212_EEPROM_DATA) & 0xffff);
                   2852:                        return (0);
                   2853:                }
                   2854:                AR5K_DELAY(15);
                   2855:        }
                   2856:
                   2857:        return (ETIMEDOUT);
                   2858: }
                   2859:
                   2860: int
                   2861: ar5k_ar5212_eeprom_write(struct ath_hal *hal, u_int32_t offset, u_int16_t data)
                   2862: {
                   2863:        u_int32_t status, timeout;
                   2864:
                   2865:        /* Enable eeprom access */
                   2866:        AR5K_REG_ENABLE_BITS(AR5K_AR5212_EEPROM_CMD,
                   2867:            AR5K_AR5212_EEPROM_CMD_RESET);
                   2868:        AR5K_REG_ENABLE_BITS(AR5K_AR5212_EEPROM_CMD,
                   2869:            AR5K_AR5212_EEPROM_CMD_WRITE);
                   2870:
                   2871:        /*
                   2872:         * Prime write pump
                   2873:         */
                   2874:        AR5K_REG_WRITE(AR5K_AR5212_EEPROM_BASE, (u_int8_t)offset - 1);
                   2875:
                   2876:        for (timeout = 10000; timeout > 0; timeout--) {
                   2877:                AR5K_DELAY(1);
                   2878:                status = AR5K_REG_READ(AR5K_AR5212_EEPROM_STATUS);
                   2879:                if (status & AR5K_AR5212_EEPROM_STAT_WRDONE) {
                   2880:                        if (status & AR5K_AR5212_EEPROM_STAT_WRERR)
                   2881:                                return (EIO);
                   2882:                        return (0);
                   2883:                }
                   2884:        }
                   2885:
                   2886:        return (ETIMEDOUT);
                   2887: }
                   2888:
                   2889: /*
                   2890:  * TX power setup
                   2891:  */
                   2892:
                   2893: HAL_BOOL
                   2894: ar5k_ar5212_txpower(struct ath_hal *hal, HAL_CHANNEL *channel, u_int txpower)
                   2895: {
                   2896:        HAL_BOOL tpc = hal->ah_txpower.txp_tpc;
                   2897:        int i;
                   2898:
                   2899:        if (txpower > AR5K_TUNE_MAX_TXPOWER) {
                   2900:                AR5K_PRINTF("invalid tx power: %u\n", txpower);
                   2901:                return (AH_FALSE);
                   2902:        }
                   2903:
                   2904:        /* Reset TX power values */
                   2905:        bzero(&hal->ah_txpower, sizeof(hal->ah_txpower));
                   2906:        hal->ah_txpower.txp_tpc = tpc;
                   2907:
                   2908:        /* Initialize TX power table */
                   2909:        ar5k_txpower_table(hal, channel, txpower);
                   2910:
                   2911:        /*
                   2912:         * Write TX power values
                   2913:         */
                   2914:        for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
                   2915:                AR5K_REG_WRITE(AR5K_AR5212_PHY_PCDAC_TXPOWER(i),
                   2916:                    ((((hal->ah_txpower.txp_pcdac[(i << 1) + 1] << 8) | 0xff) &
                   2917:                    0xffff) << 16) | (((hal->ah_txpower.txp_pcdac[i << 1] << 8)
                   2918:                    | 0xff) & 0xffff));
                   2919:        }
                   2920:
                   2921:        AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE1,
                   2922:            AR5K_TXPOWER_OFDM(3, 24) | AR5K_TXPOWER_OFDM(2, 16)
                   2923:            | AR5K_TXPOWER_OFDM(1, 8) | AR5K_TXPOWER_OFDM(0, 0));
                   2924:
                   2925:        AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE2,
                   2926:            AR5K_TXPOWER_OFDM(7, 24) | AR5K_TXPOWER_OFDM(6, 16)
                   2927:            | AR5K_TXPOWER_OFDM(5, 8) | AR5K_TXPOWER_OFDM(4, 0));
                   2928:
                   2929:        AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE3,
                   2930:            AR5K_TXPOWER_CCK(10, 24) | AR5K_TXPOWER_CCK(9, 16)
                   2931:            | AR5K_TXPOWER_CCK(15, 8) | AR5K_TXPOWER_CCK(8, 0));
                   2932:
                   2933:        AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE4,
                   2934:            AR5K_TXPOWER_CCK(14, 24) | AR5K_TXPOWER_CCK(13, 16)
                   2935:            | AR5K_TXPOWER_CCK(12, 8) | AR5K_TXPOWER_CCK(11, 0));
                   2936:
                   2937:        if (hal->ah_txpower.txp_tpc == AH_TRUE) {
                   2938:                AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE_MAX,
                   2939:                    AR5K_AR5212_PHY_TXPOWER_RATE_MAX_TPC_ENABLE |
                   2940:                    AR5K_TUNE_MAX_TXPOWER);
                   2941:        } else {
                   2942:                AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE_MAX,
                   2943:                    AR5K_AR5212_PHY_TXPOWER_RATE_MAX |
                   2944:                    AR5K_TUNE_MAX_TXPOWER);
                   2945:        }
                   2946:
                   2947:        return (AH_TRUE);
                   2948: }
                   2949:
                   2950: HAL_BOOL
                   2951: ar5k_ar5212_set_txpower_limit(struct ath_hal *hal, u_int power)
                   2952: {
                   2953:        HAL_CHANNEL *channel = &hal->ah_current_channel;
                   2954:
                   2955:        AR5K_PRINTF("changing txpower to %d\n", power);
                   2956:        return (ar5k_ar5212_txpower(hal, channel, power));
                   2957: }

CVSweb