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

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

1.1       nbrk        1: /*     $OpenBSD: ar5210.c,v 1.39 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 AR5000 Wireless LAN chipset
                     21:  * (AR5210 + AR5110).
                     22:  */
                     23:
                     24: #include <dev/ic/ar5xxx.h>
                     25: #include <dev/ic/ar5210reg.h>
                     26: #include <dev/ic/ar5210var.h>
                     27:
                     28: HAL_BOOL        ar5k_ar5210_nic_reset(struct ath_hal *, u_int32_t);
                     29: HAL_BOOL        ar5k_ar5210_nic_wakeup(struct ath_hal *, HAL_BOOL, HAL_BOOL);
                     30: void            ar5k_ar5210_init_tx_queue(struct ath_hal *, u_int, HAL_BOOL);
                     31: const void      ar5k_ar5210_fill(struct ath_hal *);
                     32: HAL_BOOL        ar5k_ar5210_do_calibrate(struct ath_hal *, HAL_CHANNEL *);
                     33: HAL_BOOL        ar5k_ar5210_noise_floor(struct ath_hal *, HAL_CHANNEL *);
                     34:
                     35: /*
                     36:  * Initial register setting for the AR5210
                     37:  */
                     38: static const struct ar5k_ini ar5210_ini[] =
                     39:     AR5K_AR5210_INI;
                     40:
                     41: AR5K_HAL_FUNCTIONS(extern, ar5k_ar5210,);
                     42:
                     43: const void
                     44: ar5k_ar5210_fill(struct ath_hal *hal)
                     45: {
                     46:        hal->ah_magic = AR5K_AR5210_MAGIC;
                     47:
                     48:        /*
                     49:         * Init/Exit functions
                     50:         */
                     51:        AR5K_HAL_FUNCTION(hal, ar5210, get_rate_table);
                     52:        AR5K_HAL_FUNCTION(hal, ar5210, detach);
                     53:
                     54:        /*
                     55:         * Reset functions
                     56:         */
                     57:        AR5K_HAL_FUNCTION(hal, ar5210, reset);
                     58:        AR5K_HAL_FUNCTION(hal, ar5210, set_opmode);
                     59:        AR5K_HAL_FUNCTION(hal, ar5210, calibrate);
                     60:
                     61:        /*
                     62:         * TX functions
                     63:         */
                     64:        AR5K_HAL_FUNCTION(hal, ar5210, update_tx_triglevel);
                     65:        AR5K_HAL_FUNCTION(hal, ar5210, setup_tx_queue);
                     66:        AR5K_HAL_FUNCTION(hal, ar5210, setup_tx_queueprops);
                     67:        AR5K_HAL_FUNCTION(hal, ar5210, release_tx_queue);
                     68:        AR5K_HAL_FUNCTION(hal, ar5210, reset_tx_queue);
                     69:        AR5K_HAL_FUNCTION(hal, ar5210, get_tx_buf);
                     70:        AR5K_HAL_FUNCTION(hal, ar5210, put_tx_buf);
                     71:        AR5K_HAL_FUNCTION(hal, ar5210, tx_start);
                     72:        AR5K_HAL_FUNCTION(hal, ar5210, stop_tx_dma);
                     73:        AR5K_HAL_FUNCTION(hal, ar5210, setup_tx_desc);
                     74:        AR5K_HAL_FUNCTION(hal, ar5210, setup_xtx_desc);
                     75:        AR5K_HAL_FUNCTION(hal, ar5210, fill_tx_desc);
                     76:        AR5K_HAL_FUNCTION(hal, ar5210, proc_tx_desc);
                     77:        AR5K_HAL_FUNCTION(hal, ar5210, has_veol);
                     78:
                     79:        /*
                     80:         * RX functions
                     81:         */
                     82:        AR5K_HAL_FUNCTION(hal, ar5210, get_rx_buf);
                     83:        AR5K_HAL_FUNCTION(hal, ar5210, put_rx_buf);
                     84:        AR5K_HAL_FUNCTION(hal, ar5210, start_rx);
                     85:        AR5K_HAL_FUNCTION(hal, ar5210, stop_rx_dma);
                     86:        AR5K_HAL_FUNCTION(hal, ar5210, start_rx_pcu);
                     87:        AR5K_HAL_FUNCTION(hal, ar5210, stop_pcu_recv);
                     88:        AR5K_HAL_FUNCTION(hal, ar5210, set_mcast_filter);
                     89:        AR5K_HAL_FUNCTION(hal, ar5210, set_mcast_filterindex);
                     90:        AR5K_HAL_FUNCTION(hal, ar5210, clear_mcast_filter_idx);
                     91:        AR5K_HAL_FUNCTION(hal, ar5210, get_rx_filter);
                     92:        AR5K_HAL_FUNCTION(hal, ar5210, set_rx_filter);
                     93:        AR5K_HAL_FUNCTION(hal, ar5210, setup_rx_desc);
                     94:        AR5K_HAL_FUNCTION(hal, ar5210, proc_rx_desc);
                     95:        AR5K_HAL_FUNCTION(hal, ar5210, set_rx_signal);
                     96:
                     97:        /*
                     98:         * Misc functions
                     99:         */
                    100:        AR5K_HAL_FUNCTION(hal, ar5210, dump_state);
                    101:        AR5K_HAL_FUNCTION(hal, ar5210, get_diag_state);
                    102:        AR5K_HAL_FUNCTION(hal, ar5210, get_lladdr);
                    103:        AR5K_HAL_FUNCTION(hal, ar5210, set_lladdr);
                    104:        AR5K_HAL_FUNCTION(hal, ar5210, set_regdomain);
                    105:        AR5K_HAL_FUNCTION(hal, ar5210, set_ledstate);
                    106:        AR5K_HAL_FUNCTION(hal, ar5210, set_associd);
                    107:        AR5K_HAL_FUNCTION(hal, ar5210, set_gpio_input);
                    108:        AR5K_HAL_FUNCTION(hal, ar5210, set_gpio_output);
                    109:        AR5K_HAL_FUNCTION(hal, ar5210, get_gpio);
                    110:        AR5K_HAL_FUNCTION(hal, ar5210, set_gpio);
                    111:        AR5K_HAL_FUNCTION(hal, ar5210, set_gpio_intr);
                    112:        AR5K_HAL_FUNCTION(hal, ar5210, get_tsf32);
                    113:        AR5K_HAL_FUNCTION(hal, ar5210, get_tsf64);
                    114:        AR5K_HAL_FUNCTION(hal, ar5210, reset_tsf);
                    115:        AR5K_HAL_FUNCTION(hal, ar5210, get_regdomain);
                    116:        AR5K_HAL_FUNCTION(hal, ar5210, detect_card_present);
                    117:        AR5K_HAL_FUNCTION(hal, ar5210, update_mib_counters);
                    118:        AR5K_HAL_FUNCTION(hal, ar5210, get_rf_gain);
                    119:        AR5K_HAL_FUNCTION(hal, ar5210, set_slot_time);
                    120:        AR5K_HAL_FUNCTION(hal, ar5210, get_slot_time);
                    121:        AR5K_HAL_FUNCTION(hal, ar5210, set_ack_timeout);
                    122:        AR5K_HAL_FUNCTION(hal, ar5210, get_ack_timeout);
                    123:        AR5K_HAL_FUNCTION(hal, ar5210, set_cts_timeout);
                    124:        AR5K_HAL_FUNCTION(hal, ar5210, get_cts_timeout);
                    125:
                    126:        /*
                    127:         * Key table (WEP) functions
                    128:         */
                    129:        AR5K_HAL_FUNCTION(hal, ar5210, is_cipher_supported);
                    130:        AR5K_HAL_FUNCTION(hal, ar5210, get_keycache_size);
                    131:        AR5K_HAL_FUNCTION(hal, ar5210, reset_key);
                    132:        AR5K_HAL_FUNCTION(hal, ar5210, is_key_valid);
                    133:        AR5K_HAL_FUNCTION(hal, ar5210, set_key);
                    134:        AR5K_HAL_FUNCTION(hal, ar5210, set_key_lladdr);
                    135:
                    136:        /*
                    137:         * Power management functions
                    138:         */
                    139:        AR5K_HAL_FUNCTION(hal, ar5210, set_power);
                    140:        AR5K_HAL_FUNCTION(hal, ar5210, get_power_mode);
                    141:        AR5K_HAL_FUNCTION(hal, ar5210, query_pspoll_support);
                    142:        AR5K_HAL_FUNCTION(hal, ar5210, init_pspoll);
                    143:        AR5K_HAL_FUNCTION(hal, ar5210, enable_pspoll);
                    144:        AR5K_HAL_FUNCTION(hal, ar5210, disable_pspoll);
                    145:
                    146:        /*
                    147:         * Beacon functions
                    148:         */
                    149:        AR5K_HAL_FUNCTION(hal, ar5210, init_beacon);
                    150:        AR5K_HAL_FUNCTION(hal, ar5210, set_beacon_timers);
                    151:        AR5K_HAL_FUNCTION(hal, ar5210, reset_beacon);
                    152:        AR5K_HAL_FUNCTION(hal, ar5210, wait_for_beacon);
                    153:
                    154:        /*
                    155:         * Interrupt functions
                    156:         */
                    157:        AR5K_HAL_FUNCTION(hal, ar5210, is_intr_pending);
                    158:        AR5K_HAL_FUNCTION(hal, ar5210, get_isr);
                    159:        AR5K_HAL_FUNCTION(hal, ar5210, get_intr);
                    160:        AR5K_HAL_FUNCTION(hal, ar5210, set_intr);
                    161:
                    162:        /*
                    163:         * Chipset functions (ar5k-specific, non-HAL)
                    164:         */
                    165:        AR5K_HAL_FUNCTION(hal, ar5210, get_capabilities);
                    166:        AR5K_HAL_FUNCTION(hal, ar5210, radar_alert);
                    167:
                    168:        /*
                    169:         * EEPROM access
                    170:         */
                    171:        AR5K_HAL_FUNCTION(hal, ar5210, eeprom_is_busy);
                    172:        AR5K_HAL_FUNCTION(hal, ar5210, eeprom_read);
                    173:        AR5K_HAL_FUNCTION(hal, ar5210, eeprom_write);
                    174:
                    175:        /*
                    176:         * Unused functions or functions not implemented
                    177:         */
                    178:        AR5K_HAL_FUNCTION(hal, ar5210, set_bssid_mask);
                    179:        AR5K_HAL_FUNCTION(hal, ar5210, get_tx_queueprops);
                    180:        AR5K_HAL_FUNCTION(hal, ar5210, num_tx_pending);
                    181:        AR5K_HAL_FUNCTION(hal, ar5210, phy_disable);
                    182:        AR5K_HAL_FUNCTION(hal, ar5210, set_txpower_limit);
                    183:        AR5K_HAL_FUNCTION(hal, ar5210, set_def_antenna);
                    184:        AR5K_HAL_FUNCTION(hal, ar5210, get_def_antenna);
                    185: #ifdef notyet
                    186:        AR5K_HAL_FUNCTION(hal, ar5210, set_capability);
                    187:        AR5K_HAL_FUNCTION(hal, ar5210, proc_mib_event);
                    188:        AR5K_HAL_FUNCTION(hal, ar5210, get_tx_inter_queue);
                    189: #endif
                    190: }
                    191:
                    192: struct ath_hal *
                    193: ar5k_ar5210_attach(u_int16_t device, void *sc, bus_space_tag_t st,
                    194:     bus_space_handle_t sh, int *status)
                    195: {
                    196:        int i;
                    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_ar5210_fill(hal);
                    202:
                    203:        /* Bring device out of sleep and reset its units */
                    204:        if (ar5k_ar5210_nic_wakeup(hal, AH_FALSE, AH_TRUE) != AH_TRUE)
                    205:                return (NULL);
                    206:
                    207:        /* Get MAC, PHY and RADIO revisions */
                    208:        srev = AR5K_REG_READ(AR5K_AR5210_SREV);
                    209:        hal->ah_mac_srev = srev;
                    210:        hal->ah_mac_version = AR5K_REG_MS(srev, AR5K_AR5210_SREV_VER);
                    211:        hal->ah_mac_revision = AR5K_REG_MS(srev, AR5K_AR5210_SREV_REV);
                    212:        hal->ah_phy_revision = AR5K_REG_READ(AR5K_AR5210_PHY_CHIP_ID) &
                    213:            0x00ffffffff;
                    214:
                    215:        /* ...wait until PHY is ready and read RADIO revision */
                    216:        AR5K_REG_WRITE(AR5K_AR5210_PHY(0x34), 0x00001c16);
                    217:        for (i = 0; i < 4; i++)
                    218:                AR5K_REG_WRITE(AR5K_AR5210_PHY(0x20), 0x00010000);
                    219:        hal->ah_radio_5ghz_revision = (u_int16_t)
                    220:            (ar5k_bitswap((AR5K_REG_READ(AR5K_AR5210_PHY(256) >> 28) & 0xf), 4)
                    221:                + 1);
                    222:        hal->ah_radio_2ghz_revision = 0;
                    223:
                    224:        /* Identify the chipset */
                    225:        hal->ah_version = AR5K_AR5210;
                    226:        hal->ah_radio = AR5K_AR5110;
                    227:        hal->ah_phy = AR5K_AR5210_PHY(0);
                    228:
                    229:        bcopy(etherbroadcastaddr, mac, IEEE80211_ADDR_LEN);
                    230:        ar5k_ar5210_set_associd(hal, mac, 0, 0);
                    231:        ar5k_ar5210_get_lladdr(hal, mac);
                    232:        ar5k_ar5210_set_opmode(hal);
                    233:
                    234:        return (hal);
                    235: }
                    236:
                    237: HAL_BOOL
                    238: ar5k_ar5210_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:        /*
                    244:         * Reset the device and wait until success
                    245:         */
                    246:        AR5K_REG_WRITE(AR5K_AR5210_RC, val);
                    247:
                    248:        /* Wait at least 128 PCI clocks */
                    249:        AR5K_DELAY(15);
                    250:
                    251:        val &=
                    252:            AR5K_AR5210_RC_PCU | AR5K_AR5210_RC_MAC |
                    253:            AR5K_AR5210_RC_PHY | AR5K_AR5210_RC_DMA;
                    254:
                    255:        mask &=
                    256:            AR5K_AR5210_RC_PCU | AR5K_AR5210_RC_MAC |
                    257:            AR5K_AR5210_RC_PHY | AR5K_AR5210_RC_DMA;
                    258:
                    259:        ret = ar5k_register_timeout(hal, AR5K_AR5210_RC, mask, val, AH_FALSE);
                    260:
                    261:        /*
                    262:         * Reset configuration register
                    263:         */
                    264:        if ((val & AR5K_AR5210_RC_MAC) == 0) {
                    265:                AR5K_REG_WRITE(AR5K_AR5210_CFG, AR5K_AR5210_INIT_CFG);
                    266:        }
                    267:
                    268:        return (ret);
                    269: }
                    270:
                    271: HAL_BOOL
                    272: ar5k_ar5210_nic_wakeup(struct ath_hal *hal, HAL_BOOL turbo, HAL_BOOL initial)
                    273: {
                    274:        /*
                    275:         * Reset and wakeup the device
                    276:         */
                    277:
                    278:        if (initial == AH_TRUE) {
                    279:                /* ...reset hardware */
                    280:                if (ar5k_ar5210_nic_reset(hal,
                    281:                        AR5K_AR5210_RC_PCI) == AH_FALSE) {
                    282:                        AR5K_PRINT("failed to reset the PCI chipset\n");
                    283:                        return (AH_FALSE);
                    284:                }
                    285:
                    286:                AR5K_DELAY(1000);
                    287:        }
                    288:
                    289:        /* ...wakeup the device */
                    290:        if (ar5k_ar5210_set_power(hal,
                    291:                HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) {
                    292:                AR5K_PRINT("failed to resume the AR5210 chipset\n");
                    293:                return (AH_FALSE);
                    294:        }
                    295:
                    296:        /* ...enable Atheros turbo mode if requested */
                    297:        AR5K_REG_WRITE(AR5K_AR5210_PHY_FC,
                    298:            turbo == AH_TRUE ? AR5K_AR5210_PHY_FC_TURBO_MODE : 0);
                    299:
                    300:        /* ...reset chipset */
                    301:        if (ar5k_ar5210_nic_reset(hal, AR5K_AR5210_RC_CHIP) == AH_FALSE) {
                    302:                AR5K_PRINT("failed to reset the AR5210 chipset\n");
                    303:                return (AH_FALSE);
                    304:        }
                    305:
                    306:        AR5K_DELAY(1000);
                    307:
                    308:        /* ...reset chipset and PCI device */
                    309:        if (ar5k_ar5210_nic_reset(hal,
                    310:                AR5K_AR5210_RC_CHIP | AR5K_AR5210_RC_PCI) == AH_FALSE) {
                    311:                AR5K_PRINT("failed to reset the AR5210 + PCI chipset\n");
                    312:                return (AH_FALSE);
                    313:        }
                    314:
                    315:        AR5K_DELAY(2300);
                    316:
                    317:        /* ...wakeup (again) */
                    318:        if (ar5k_ar5210_set_power(hal,
                    319:                HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) {
                    320:                AR5K_PRINT("failed to resume the AR5210 (again)\n");
                    321:                return (AH_FALSE);
                    322:        }
                    323:
                    324:        /* ...final warm reset */
                    325:        if (ar5k_ar5210_nic_reset(hal, 0) == AH_FALSE) {
                    326:                AR5K_PRINT("failed to warm reset the AR5210\n");
                    327:                return (AH_FALSE);
                    328:        }
                    329:
                    330:        return (AH_TRUE);
                    331: }
                    332:
                    333: const HAL_RATE_TABLE *
                    334: ar5k_ar5210_get_rate_table(struct ath_hal *hal, u_int mode)
                    335: {
                    336:        switch (mode) {
                    337:        case HAL_MODE_11A:
                    338:                return (&hal->ah_rt_11a);
                    339:        case HAL_MODE_TURBO:
                    340:                return (&hal->ah_rt_turbo);
                    341:        case HAL_MODE_11B:
                    342:        case HAL_MODE_11G:
                    343:        default:
                    344:                return (NULL);
                    345:        }
                    346:
                    347:        return (NULL);
                    348: }
                    349:
                    350: void
                    351: ar5k_ar5210_detach(struct ath_hal *hal)
                    352: {
                    353:        /*
                    354:         * Free HAL structure, assume interrupts are down
                    355:         */
                    356:        free(hal, M_DEVBUF);
                    357: }
                    358:
                    359: HAL_BOOL
                    360: ar5k_ar5210_phy_disable(struct ath_hal *hal)
                    361: {
                    362:        AR5K_REG_WRITE(AR5K_AR5210_PHY_ACTIVE, AR5K_AR5210_PHY_DISABLE);
                    363:        return (AH_TRUE);
                    364: }
                    365:
                    366: HAL_BOOL
                    367: ar5k_ar5210_reset(struct ath_hal *hal, HAL_OPMODE op_mode, HAL_CHANNEL *channel,
                    368:     HAL_BOOL change_channel, HAL_STATUS *status)
                    369: {
                    370:        int i;
                    371:
                    372:        /* Not used, keep for HAL compatibility */
                    373:        *status = HAL_OK;
                    374:
                    375:        if (ar5k_ar5210_nic_wakeup(hal,
                    376:                channel->c_channel_flags & IEEE80211_CHAN_T ?
                    377:                AH_TRUE : AH_FALSE, AH_FALSE) == AH_FALSE)
                    378:                return (AH_FALSE);
                    379:
                    380:        /*
                    381:         * Initialize operating mode
                    382:         */
                    383:        hal->ah_op_mode = op_mode;
                    384:        ar5k_ar5210_set_opmode(hal);
                    385:
                    386:        /*
                    387:         * Write initial mode register settings
                    388:         */
                    389:        for (i = 0; i < AR5K_ELEMENTS(ar5210_ini); i++) {
                    390:                if (change_channel == AH_TRUE &&
                    391:                    ar5210_ini[i].ini_register >= AR5K_AR5210_PCU_MIN &&
                    392:                    ar5210_ini[i].ini_register <= AR5K_AR5210_PCU_MAX)
                    393:                        continue;
                    394:
                    395:                switch (ar5210_ini[i].ini_mode) {
                    396:                case AR5K_INI_READ:
                    397:                        /* Cleared on read */
                    398:                        AR5K_REG_READ(ar5210_ini[i].ini_register);
                    399:                        break;
                    400:
                    401:                case AR5K_INI_WRITE:
                    402:                default:
                    403:                        AR5K_REG_WRITE(ar5210_ini[i].ini_register,
                    404:                            ar5210_ini[i].ini_value);
                    405:                }
                    406:        }
                    407:
                    408:        AR5K_DELAY(1000);
                    409:
                    410:        /*
                    411:         * Set channel and calibrate the PHY
                    412:         */
                    413:
                    414:        /* Disable phy and wait */
                    415:        AR5K_REG_WRITE(AR5K_AR5210_PHY_ACTIVE, AR5K_AR5210_PHY_DISABLE);
                    416:        AR5K_DELAY(1000);
                    417:
                    418:        if (ar5k_channel(hal, channel) == AH_FALSE)
                    419:                return (AH_FALSE);
                    420:
                    421:        /*
                    422:         * Activate phy and wait
                    423:         */
                    424:        AR5K_REG_WRITE(AR5K_AR5210_PHY_ACTIVE, AR5K_AR5210_PHY_ENABLE);
                    425:        AR5K_DELAY(1000);
                    426:
                    427:        ar5k_ar5210_do_calibrate(hal, channel);
                    428:        if (ar5k_ar5210_noise_floor(hal, channel) == AH_FALSE)
                    429:                return (AH_FALSE);
                    430:
                    431:        /*
                    432:         * Set RF kill flags if supported by the device (read from the EEPROM)
                    433:         */
                    434:        if (AR5K_EEPROM_HDR_RFKILL(hal->ah_capabilities.cap_eeprom.ee_header)) {
                    435:                ar5k_ar5210_set_gpio_input(hal, 0);
                    436:                if ((hal->ah_gpio[0] = ar5k_ar5210_get_gpio(hal, 0)) == 0) {
                    437:                        ar5k_ar5210_set_gpio_intr(hal, 0, 1);
                    438:                } else {
                    439:                        ar5k_ar5210_set_gpio_intr(hal, 0, 0);
                    440:                }
                    441:        }
                    442:
                    443:        /*
                    444:         * Reset queues and start beacon timers at the end of the reset routine
                    445:         */
                    446:        for (i = 0; i < hal->ah_capabilities.cap_queues.q_tx_num; i++) {
                    447:                if (ar5k_ar5210_reset_tx_queue(hal, i) == AH_FALSE) {
                    448:                        AR5K_PRINTF("failed to reset TX queue #%d\n", i);
                    449:                        return (AH_FALSE);
                    450:                }
                    451:        }
                    452:
                    453:        AR5K_REG_DISABLE_BITS(AR5K_AR5210_BEACON,
                    454:            AR5K_AR5210_BEACON_EN | AR5K_AR5210_BEACON_RESET_TSF);
                    455:
                    456:        return (AH_TRUE);
                    457: }
                    458:
                    459: void
                    460: ar5k_ar5210_set_def_antenna(struct ath_hal *hal, u_int ant)
                    461: {
                    462:        /* Not available */
                    463:        return;
                    464: }
                    465:
                    466: u_int
                    467: ar5k_ar5210_get_def_antenna(struct ath_hal *hal)
                    468: {
                    469:        return (0);
                    470: }
                    471:
                    472: void
                    473: ar5k_ar5210_set_opmode(struct ath_hal *hal)
                    474: {
                    475:        u_int32_t pcu_reg, beacon_reg, low_id, high_id;
                    476:
                    477:        beacon_reg = 0;
                    478:        pcu_reg = 0;
                    479:
                    480:        switch (hal->ah_op_mode) {
                    481:        case IEEE80211_M_STA:
                    482:                pcu_reg |= AR5K_AR5210_STA_ID1_NO_PSPOLL |
                    483:                    AR5K_AR5210_STA_ID1_DESC_ANTENNA |
                    484:                    AR5K_AR5210_STA_ID1_PWR_SV;
                    485:                break;
                    486:
                    487:        case IEEE80211_M_IBSS:
                    488:                pcu_reg |= AR5K_AR5210_STA_ID1_ADHOC |
                    489:                    AR5K_AR5210_STA_ID1_NO_PSPOLL |
                    490:                    AR5K_AR5210_STA_ID1_DESC_ANTENNA;
                    491:                beacon_reg |= AR5K_AR5210_BCR_ADHOC;
                    492:                break;
                    493:
                    494:        case IEEE80211_M_HOSTAP:
                    495:                pcu_reg |= AR5K_AR5210_STA_ID1_AP |
                    496:                    AR5K_AR5210_STA_ID1_NO_PSPOLL |
                    497:                    AR5K_AR5210_STA_ID1_DESC_ANTENNA;
                    498:                beacon_reg |= AR5K_AR5210_BCR_AP;
                    499:                break;
                    500:
                    501:        case IEEE80211_M_MONITOR:
                    502:                pcu_reg |= AR5K_AR5210_STA_ID1_NO_PSPOLL;
                    503:                break;
                    504:
                    505:        default:
                    506:                return;
                    507:        }
                    508:
                    509:        /*
                    510:         * Set PCU and BCR registers
                    511:         */
                    512:        low_id = AR5K_LOW_ID(hal->ah_sta_id);
                    513:        high_id = AR5K_HIGH_ID(hal->ah_sta_id);
                    514:        AR5K_REG_WRITE(AR5K_AR5210_STA_ID0, low_id);
                    515:        AR5K_REG_WRITE(AR5K_AR5210_STA_ID1, pcu_reg | high_id);
                    516:        AR5K_REG_WRITE(AR5K_AR5210_BCR, beacon_reg);
                    517:
                    518:        return;
                    519: }
                    520:
                    521: HAL_BOOL
                    522: ar5k_ar5210_calibrate(struct ath_hal *hal, HAL_CHANNEL *channel)
                    523: {
                    524:        HAL_BOOL ret = AH_TRUE;
                    525:        u_int32_t phy_sig, phy_agc, phy_sat, beacon;
                    526:
                    527: #define AGC_DISABLE    {                                               \
                    528:        AR5K_REG_ENABLE_BITS(AR5K_AR5210_PHY_AGC,                       \
                    529:            AR5K_AR5210_PHY_AGC_DISABLE);                               \
                    530:        AR5K_DELAY(10);                                                 \
                    531: }
                    532:
                    533: #define AGC_ENABLE     {                                               \
                    534:        AR5K_REG_DISABLE_BITS(AR5K_AR5210_PHY_AGC,                      \
                    535:            AR5K_AR5210_PHY_AGC_DISABLE);                               \
                    536: }
                    537:
                    538:        /*
                    539:         * Disable beacons and RX/TX queues, wait
                    540:         */
                    541:        AR5K_REG_ENABLE_BITS(AR5K_AR5210_DIAG_SW,
                    542:            AR5K_AR5210_DIAG_SW_DIS_TX | AR5K_AR5210_DIAG_SW_DIS_RX);
                    543:        beacon = AR5K_REG_READ(AR5K_AR5210_BEACON);
                    544:        AR5K_REG_WRITE(AR5K_AR5210_BEACON, beacon & ~AR5K_AR5210_BEACON_EN);
                    545:
                    546:        AR5K_DELAY(2300);
                    547:
                    548:        /*
                    549:         * Set the channel (with AGC turned off)
                    550:         */
                    551:        AGC_DISABLE;
                    552:        ret = ar5k_channel(hal, channel);
                    553:
                    554:        /*
                    555:         * Activate PHY and wait
                    556:         */
                    557:        AR5K_REG_WRITE(AR5K_AR5210_PHY_ACTIVE, AR5K_AR5210_PHY_ENABLE);
                    558:        AR5K_DELAY(1000);
                    559:
                    560:        AGC_ENABLE;
                    561:
                    562:        if (ret == AH_FALSE)
                    563:                return (ret);
                    564:
                    565:        /*
                    566:         * Calibrate the radio chip
                    567:         */
                    568:
                    569:        /* Remember normal state */
                    570:        phy_sig = AR5K_REG_READ(AR5K_AR5210_PHY_SIG);
                    571:        phy_agc = AR5K_REG_READ(AR5K_AR5210_PHY_AGCCOARSE);
                    572:        phy_sat = AR5K_REG_READ(AR5K_AR5210_PHY_ADCSAT);
                    573:
                    574:        /* Update radio registers */
                    575:        AR5K_REG_WRITE(AR5K_AR5210_PHY_SIG,
                    576:            (phy_sig & ~(AR5K_AR5210_PHY_SIG_FIRPWR)) |
                    577:            AR5K_REG_SM(-1, AR5K_AR5210_PHY_SIG_FIRPWR));
                    578:
                    579:        AR5K_REG_WRITE(AR5K_AR5210_PHY_AGCCOARSE,
                    580:            (phy_agc & ~(AR5K_AR5210_PHY_AGCCOARSE_HI |
                    581:                AR5K_AR5210_PHY_AGCCOARSE_LO)) |
                    582:            AR5K_REG_SM(-1, AR5K_AR5210_PHY_AGCCOARSE_HI) |
                    583:            AR5K_REG_SM(-127, AR5K_AR5210_PHY_AGCCOARSE_LO));
                    584:
                    585:        AR5K_REG_WRITE(AR5K_AR5210_PHY_ADCSAT,
                    586:            (phy_sat & ~(AR5K_AR5210_PHY_ADCSAT_ICNT |
                    587:                AR5K_AR5210_PHY_ADCSAT_THR)) |
                    588:            AR5K_REG_SM(2, AR5K_AR5210_PHY_ADCSAT_ICNT) |
                    589:            AR5K_REG_SM(12, AR5K_AR5210_PHY_ADCSAT_THR));
                    590:
                    591:        AR5K_DELAY(20);
                    592:
                    593:        AGC_DISABLE;
                    594:        AR5K_REG_WRITE(AR5K_AR5210_PHY_RFSTG, AR5K_AR5210_PHY_RFSTG_DISABLE);
                    595:        AGC_ENABLE;
                    596:
                    597:        AR5K_DELAY(1000);
                    598:
                    599:        ret = ar5k_ar5210_do_calibrate(hal, channel);
                    600:
                    601:        /* Reset to normal state */
                    602:        AR5K_REG_WRITE(AR5K_AR5210_PHY_SIG, phy_sig);
                    603:        AR5K_REG_WRITE(AR5K_AR5210_PHY_AGCCOARSE, phy_agc);
                    604:        AR5K_REG_WRITE(AR5K_AR5210_PHY_ADCSAT, phy_sat);
                    605:
                    606:        if (ret == AH_FALSE)
                    607:                return (AH_FALSE);
                    608:
                    609:        if (ar5k_ar5210_noise_floor(hal, channel) == AH_FALSE)
                    610:                return (AH_FALSE);
                    611:
                    612:        /*
                    613:         * Re-enable RX/TX and beacons
                    614:         */
                    615:        AR5K_REG_DISABLE_BITS(AR5K_AR5210_DIAG_SW,
                    616:            AR5K_AR5210_DIAG_SW_DIS_TX | AR5K_AR5210_DIAG_SW_DIS_RX);
                    617:        AR5K_REG_WRITE(AR5K_AR5210_BEACON, beacon);
                    618:
                    619: #undef AGC_ENABLE
                    620: #undef AGC_DISABLE
                    621:
                    622:        return (AH_TRUE);
                    623: }
                    624:
                    625: HAL_BOOL
                    626: ar5k_ar5210_do_calibrate(struct ath_hal *hal, HAL_CHANNEL *channel)
                    627: {
                    628:        /*
                    629:         * Enable calibration and wait until completion
                    630:         */
                    631:        AR5K_REG_ENABLE_BITS(AR5K_AR5210_PHY_AGCCTL,
                    632:            AR5K_AR5210_PHY_AGCCTL_CAL);
                    633:
                    634:        if (ar5k_register_timeout(hal, AR5K_AR5210_PHY_AGCCTL,
                    635:                AR5K_AR5210_PHY_AGCCTL_CAL, 0, AH_FALSE) == AH_FALSE) {
                    636:                AR5K_PRINTF("calibration timeout (%uMHz)\n",
                    637:                    channel->c_channel);
                    638:                return (AH_FALSE);
                    639:        }
                    640:
                    641:        return (AH_TRUE);
                    642: }
                    643:
                    644: HAL_BOOL
                    645: ar5k_ar5210_noise_floor(struct ath_hal *hal, HAL_CHANNEL *channel)
                    646: {
                    647:        int i;
                    648:        u_int32_t noise_floor;
                    649:
                    650:        /*
                    651:         * Enable noise floor calibration and wait until completion
                    652:         */
                    653:        AR5K_REG_ENABLE_BITS(AR5K_AR5210_PHY_AGCCTL,
                    654:            AR5K_AR5210_PHY_AGCCTL_NF);
                    655:
                    656:        if (ar5k_register_timeout(hal, AR5K_AR5210_PHY_AGCCTL,
                    657:                AR5K_AR5210_PHY_AGCCTL_NF, 0, AH_FALSE) == AH_FALSE) {
                    658:                AR5K_PRINTF("noise floor calibration timeout (%uMHz)\n",
                    659:                    channel->c_channel);
                    660:                return (AH_FALSE);
                    661:        }
                    662:
                    663:        /* wait until the noise floor is calibrated */
                    664:        for (i = 20; i > 0; i--) {
                    665:                AR5K_DELAY(1000);
                    666:                noise_floor = AR5K_REG_READ(AR5K_AR5210_PHY_NF);
                    667:                if (AR5K_AR5210_PHY_NF_RVAL(noise_floor) &
                    668:                    AR5K_AR5210_PHY_NF_ACTIVE)
                    669:                        noise_floor = AR5K_AR5210_PHY_NF_AVAL(noise_floor);
                    670:                if (noise_floor <= AR5K_TUNE_NOISE_FLOOR)
                    671:                        break;
                    672:        }
                    673:
                    674:        if (noise_floor > AR5K_TUNE_NOISE_FLOOR) {
                    675:                AR5K_PRINTF("noise floor calibration failed (%uMHz)\n",
                    676:                    channel->c_channel);
                    677:                return (AH_FALSE);
                    678:        }
                    679:
                    680:        return (AH_TRUE);
                    681: }
                    682:
                    683: /*
                    684:  * Transmit functions
                    685:  */
                    686:
                    687: HAL_BOOL
                    688: ar5k_ar5210_update_tx_triglevel(struct ath_hal *hal, HAL_BOOL increase)
                    689: {
                    690:        u_int32_t trigger_level;
                    691:        HAL_BOOL status = AH_FALSE;
                    692:
                    693:        /*
                    694:         * Disable interrupts by setting the mask
                    695:         */
                    696:        AR5K_REG_DISABLE_BITS(AR5K_AR5210_IMR, HAL_INT_GLOBAL);
                    697:
                    698:        trigger_level = AR5K_REG_READ(AR5K_AR5210_TRIG_LVL);
                    699:
                    700:        if (increase == AH_FALSE) {
                    701:                if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
                    702:                        goto done;
                    703:        } else {
                    704:                trigger_level +=
                    705:                    ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
                    706:        }
                    707:
                    708:        /*
                    709:         * Update trigger level on success
                    710:         */
                    711:        AR5K_REG_WRITE(AR5K_AR5210_TRIG_LVL, trigger_level);
                    712:        status = AH_TRUE;
                    713:
                    714:  done:
                    715:        /*
                    716:         * Restore interrupt mask
                    717:         */
                    718:        AR5K_REG_ENABLE_BITS(AR5K_AR5210_IMR, HAL_INT_GLOBAL);
                    719:
                    720:        return (status);
                    721: }
                    722:
                    723: int
                    724: ar5k_ar5210_setup_tx_queue(struct ath_hal *hal, HAL_TX_QUEUE queue_type,
                    725:     const HAL_TXQ_INFO *queue_info)
                    726: {
                    727:        u_int queue;
                    728:
                    729:        /*
                    730:         * Get queue by type
                    731:         */
                    732:        switch (queue_type) {
                    733:        case HAL_TX_QUEUE_DATA:
                    734:                queue = 0;
                    735:                break;
                    736:        case HAL_TX_QUEUE_BEACON:
                    737:        case HAL_TX_QUEUE_CAB:
                    738:                queue = 1;
                    739:                break;
                    740:        default:
                    741:                return (-1);
                    742:        }
                    743:
                    744:        /*
                    745:         * Setup internal queue structure
                    746:         */
                    747:        bzero(&hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));
                    748:        hal->ah_txq[queue].tqi_type = queue_type;
                    749:
                    750:        if (queue_info != NULL) {
                    751:                if (ar5k_ar5210_setup_tx_queueprops(hal,
                    752:                        queue, queue_info) != AH_TRUE)
                    753:                        return (-1);
                    754:        }
                    755:
                    756:        return (queue);
                    757: }
                    758:
                    759: HAL_BOOL
                    760: ar5k_ar5210_setup_tx_queueprops(struct ath_hal *hal, int queue,
                    761:     const HAL_TXQ_INFO *queue_info)
                    762: {
                    763:        AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
                    764:
                    765:        if (hal->ah_txq[queue].tqi_type == HAL_TX_QUEUE_INACTIVE)
                    766:                return (AH_FALSE);
                    767:
                    768:        hal->ah_txq[queue].tqi_aifs = queue_info->tqi_aifs;
                    769:        hal->ah_txq[queue].tqi_cw_max = queue_info->tqi_cw_max;
                    770:        hal->ah_txq[queue].tqi_cw_min = queue_info->tqi_cw_min;
                    771:        hal->ah_txq[queue].tqi_flags = queue_info->tqi_flags;
                    772:
                    773:        return (AH_TRUE);
                    774: }
                    775:
                    776: HAL_BOOL
                    777: ar5k_ar5210_get_tx_queueprops(struct ath_hal *hal, int queue,
                    778:     HAL_TXQ_INFO *queue_info)
                    779: {
                    780:        AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
                    781:        bcopy(&hal->ah_txq[queue], queue_info, sizeof(HAL_TXQ_INFO));
                    782:        return (AH_TRUE);
                    783: }
                    784:
                    785: HAL_BOOL
                    786: ar5k_ar5210_release_tx_queue(struct ath_hal *hal, u_int queue)
                    787: {
                    788:        AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
                    789:
                    790:        /* This queue will be skipped in further operations */
                    791:        hal->ah_txq[queue].tqi_type = HAL_TX_QUEUE_INACTIVE;
                    792:
                    793:        return (AH_FALSE);
                    794: }
                    795:
                    796: void
                    797: ar5k_ar5210_init_tx_queue(struct ath_hal *hal, u_int aifs, HAL_BOOL turbo)
                    798: {
                    799:        int i;
                    800:        struct {
                    801:                u_int16_t mode_register;
                    802:                u_int32_t mode_base, mode_turbo;
                    803:        } initial[] = AR5K_AR5210_INI_MODE(aifs);
                    804:
                    805:        /*
                    806:         * Write initial mode register settings
                    807:         */
                    808:        for (i = 0; i < AR5K_ELEMENTS(initial); i++)
                    809:                AR5K_REG_WRITE((u_int32_t)initial[i].mode_register,
                    810:                    turbo == AH_TRUE ?
                    811:                    initial[i].mode_turbo : initial[i].mode_base);
                    812: }
                    813:
                    814: HAL_BOOL
                    815: ar5k_ar5210_reset_tx_queue(struct ath_hal *hal, u_int queue)
                    816: {
                    817:        u_int32_t cw_min, retry_lg, retry_sh;
                    818:        HAL_TXQ_INFO *tq;
                    819:
                    820:        AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
                    821:
                    822:        tq = &hal->ah_txq[queue];
                    823:
                    824:        /* Only handle data queues, others will be ignored */
                    825:        if (tq->tqi_type != HAL_TX_QUEUE_DATA)
                    826:                return (AH_TRUE);
                    827:
                    828:        /* Set turbo/base mode parameters */
                    829:        ar5k_ar5210_init_tx_queue(hal, hal->ah_aifs + tq->tqi_aifs,
                    830:            hal->ah_turbo == AH_TRUE ? AH_TRUE : AH_FALSE);
                    831:
                    832:        /*
                    833:         * Set retry limits
                    834:         */
                    835:        if (hal->ah_software_retry == AH_TRUE) {
                    836:                /* XXX Need to test this */
                    837:                retry_lg = hal->ah_limit_tx_retries;
                    838:                retry_sh = retry_lg =
                    839:                    retry_lg > AR5K_AR5210_RETRY_LMT_SH_RETRY ?
                    840:                    AR5K_AR5210_RETRY_LMT_SH_RETRY : retry_lg;
                    841:        } else {
                    842:                retry_lg = AR5K_INIT_LG_RETRY;
                    843:                retry_sh = AR5K_INIT_SH_RETRY;
                    844:        }
                    845:
                    846:        /*
                    847:         * Set initial content window (cw_min/cw_max)
                    848:         */
                    849:        cw_min = 1;
                    850:        while (cw_min < hal->ah_cw_min)
                    851:                cw_min = (cw_min << 1) | 1;
                    852:
                    853:        cw_min = tq->tqi_cw_min < 0 ?
                    854:            (cw_min >> (-tq->tqi_cw_min)) :
                    855:            ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
                    856:
                    857:        /* Commit values */
                    858:        AR5K_REG_WRITE(AR5K_AR5210_RETRY_LMT,
                    859:            (cw_min << AR5K_AR5210_RETRY_LMT_CW_MIN_S)
                    860:            | AR5K_REG_SM(AR5K_INIT_SLG_RETRY, AR5K_AR5210_RETRY_LMT_SLG_RETRY)
                    861:            | AR5K_REG_SM(AR5K_INIT_SSH_RETRY, AR5K_AR5210_RETRY_LMT_SSH_RETRY)
                    862:            | AR5K_REG_SM(retry_lg, AR5K_AR5210_RETRY_LMT_LG_RETRY)
                    863:            | AR5K_REG_SM(retry_sh, AR5K_AR5210_RETRY_LMT_SH_RETRY));
                    864:
                    865:        return (AH_TRUE);
                    866: }
                    867:
                    868: u_int32_t
                    869: ar5k_ar5210_get_tx_buf(struct ath_hal *hal, u_int queue)
                    870: {
                    871:        u_int16_t tx_reg;
                    872:
                    873:        AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
                    874:
                    875:        /*
                    876:         * Get the transmit queue descriptor pointer register by type
                    877:         */
                    878:        switch (hal->ah_txq[queue].tqi_type) {
                    879:        case HAL_TX_QUEUE_DATA:
                    880:                tx_reg = AR5K_AR5210_TXDP0;
                    881:                break;
                    882:        case HAL_TX_QUEUE_BEACON:
                    883:        case HAL_TX_QUEUE_CAB:
                    884:                tx_reg = AR5K_AR5210_TXDP1;
                    885:                break;
                    886:        default:
                    887:                return (0xffffffff);
                    888:        }
                    889:
                    890:        return (AR5K_REG_READ(tx_reg));
                    891: }
                    892:
                    893: HAL_BOOL
                    894: ar5k_ar5210_put_tx_buf(struct ath_hal *hal, u_int queue, u_int32_t phys_addr)
                    895: {
                    896:        u_int16_t tx_reg;
                    897:
                    898:        AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
                    899:
                    900:        /*
                    901:         * Get the transmit queue descriptor pointer register by type
                    902:         */
                    903:        switch (hal->ah_txq[queue].tqi_type) {
                    904:        case HAL_TX_QUEUE_DATA:
                    905:                tx_reg = AR5K_AR5210_TXDP0;
                    906:                break;
                    907:        case HAL_TX_QUEUE_BEACON:
                    908:        case HAL_TX_QUEUE_CAB:
                    909:                tx_reg = AR5K_AR5210_TXDP1;
                    910:                break;
                    911:        default:
                    912:                return (AH_FALSE);
                    913:        }
                    914:
                    915:        /* Set descriptor pointer */
                    916:        AR5K_REG_WRITE(tx_reg, phys_addr);
                    917:
                    918:        return (AH_TRUE);
                    919: }
                    920:
                    921: u_int32_t
                    922: ar5k_ar5210_num_tx_pending(struct ath_hal *hal, u_int queue)
                    923: {
                    924:        return (AH_FALSE);
                    925: }
                    926:
                    927: HAL_BOOL
                    928: ar5k_ar5210_tx_start(struct ath_hal *hal, u_int queue)
                    929: {
                    930:        u_int32_t tx_queue;
                    931:
                    932:        AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
                    933:
                    934:        tx_queue = AR5K_REG_READ(AR5K_AR5210_CR);
                    935:
                    936:        /*
                    937:         * Set the queue type
                    938:         */
                    939:        switch (hal->ah_txq[queue].tqi_type) {
                    940:        case HAL_TX_QUEUE_DATA:
                    941:                tx_queue |= AR5K_AR5210_CR_TXE0 & ~AR5K_AR5210_CR_TXD0;
                    942:                break;
                    943:
                    944:        case HAL_TX_QUEUE_BEACON:
                    945:                tx_queue |= AR5K_AR5210_CR_TXE1 & ~AR5K_AR5210_CR_TXD1;
                    946:                AR5K_REG_WRITE(AR5K_AR5210_BSR,
                    947:                    AR5K_AR5210_BCR_TQ1V | AR5K_AR5210_BCR_BDMAE);
                    948:                break;
                    949:
                    950:        case HAL_TX_QUEUE_CAB:
                    951:                tx_queue |= AR5K_AR5210_CR_TXE1 & ~AR5K_AR5210_CR_TXD1;
                    952:                AR5K_REG_WRITE(AR5K_AR5210_BSR,
                    953:                    AR5K_AR5210_BCR_TQ1FV | AR5K_AR5210_BCR_TQ1V |
                    954:                    AR5K_AR5210_BCR_BDMAE);
                    955:                break;
                    956:
                    957:        default:
                    958:                return (AH_FALSE);
                    959:        }
                    960:
                    961:        /* Start queue */
                    962:        AR5K_REG_WRITE(AR5K_AR5210_CR, tx_queue);
                    963:
                    964:        return (AH_TRUE);
                    965: }
                    966:
                    967: HAL_BOOL
                    968: ar5k_ar5210_stop_tx_dma(struct ath_hal *hal, u_int queue)
                    969: {
                    970:        u_int32_t tx_queue;
                    971:
                    972:        AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
                    973:
                    974:        tx_queue = AR5K_REG_READ(AR5K_AR5210_CR);
                    975:
                    976:        /*
                    977:         * Set by queue type
                    978:         */
                    979:        switch (hal->ah_txq[queue].tqi_type) {
                    980:        case HAL_TX_QUEUE_DATA:
                    981:                tx_queue |= AR5K_AR5210_CR_TXD0 & ~AR5K_AR5210_CR_TXE0;
                    982:                break;
                    983:
                    984:        case HAL_TX_QUEUE_BEACON:
                    985:        case HAL_TX_QUEUE_CAB:
                    986:                /* XXX Fix me... */
                    987:                tx_queue |= AR5K_AR5210_CR_TXD1 & ~AR5K_AR5210_CR_TXD1;
                    988:                AR5K_REG_WRITE(AR5K_AR5210_BSR, 0);
                    989:                break;
                    990:
                    991:        default:
                    992:                return (AH_FALSE);
                    993:        }
                    994:
                    995:        /* Stop queue */
                    996:        AR5K_REG_WRITE(AR5K_AR5210_CR, tx_queue);
                    997:
                    998:        return (AH_TRUE);
                    999: }
                   1000:
                   1001: HAL_BOOL
                   1002: ar5k_ar5210_setup_tx_desc(struct ath_hal *hal, struct ath_desc *desc,
                   1003:     u_int packet_length, u_int header_length, HAL_PKT_TYPE type, u_int tx_power,
                   1004:     u_int tx_rate0, u_int tx_tries0, u_int key_index, u_int antenna_mode,
                   1005:     u_int flags, u_int rtscts_rate, u_int rtscts_duration)
                   1006: {
                   1007:        u_int32_t frame_type;
                   1008:        struct ar5k_ar5210_tx_desc *tx_desc;
                   1009:
                   1010:        tx_desc = (struct ar5k_ar5210_tx_desc*)&desc->ds_ctl0;
                   1011:
                   1012:        /*
                   1013:         * Validate input
                   1014:         */
                   1015:        if (tx_tries0 == 0)
                   1016:                return (AH_FALSE);
                   1017:
                   1018:        if ((tx_desc->tx_control_0 = (packet_length &
                   1019:            AR5K_AR5210_DESC_TX_CTL0_FRAME_LEN)) != packet_length)
                   1020:                return (AH_FALSE);
                   1021:
                   1022:        if ((tx_desc->tx_control_0 = (header_length &
                   1023:            AR5K_AR5210_DESC_TX_CTL0_HEADER_LEN)) != header_length)
                   1024:                return (AH_FALSE);
                   1025:
                   1026:        if (type == HAL_PKT_TYPE_BEACON || type == HAL_PKT_TYPE_PROBE_RESP)
                   1027:                frame_type = AR5K_AR5210_DESC_TX_FRAME_TYPE_NO_DELAY;
                   1028:        else if (type == HAL_PKT_TYPE_PIFS)
                   1029:                frame_type = AR5K_AR5210_DESC_TX_FRAME_TYPE_PIFS;
                   1030:        else
                   1031:                frame_type = type;
                   1032:
                   1033:        tx_desc->tx_control_0 =
                   1034:            AR5K_REG_SM(frame_type, AR5K_AR5210_DESC_TX_CTL0_FRAME_TYPE);
                   1035:        tx_desc->tx_control_0 |=
                   1036:            AR5K_REG_SM(tx_rate0, AR5K_AR5210_DESC_TX_CTL0_XMIT_RATE);
                   1037:
                   1038: #define _TX_FLAGS(_c, _flag)                                           \
                   1039:        if (flags & HAL_TXDESC_##_flag)                                 \
                   1040:                tx_desc->tx_control_##_c |=                             \
                   1041:                        AR5K_AR5210_DESC_TX_CTL##_c##_##_flag
                   1042:
                   1043:        _TX_FLAGS(0, CLRDMASK);
                   1044:        _TX_FLAGS(0, INTREQ);
                   1045:        _TX_FLAGS(0, RTSENA);
                   1046:
                   1047: #undef _TX_FLAGS
                   1048:
                   1049:        /*
                   1050:         * WEP crap
                   1051:         */
                   1052:        if (key_index != HAL_TXKEYIX_INVALID) {
                   1053:                tx_desc->tx_control_0 |=
                   1054:                    AR5K_AR5210_DESC_TX_CTL0_ENCRYPT_KEY_VALID;
                   1055:                tx_desc->tx_control_1 |=
                   1056:                    AR5K_REG_SM(key_index,
                   1057:                    AR5K_AR5210_DESC_TX_CTL1_ENCRYPT_KEY_INDEX);
                   1058:        }
                   1059:
                   1060:        /*
                   1061:         * RTS/CTS
                   1062:         */
                   1063:        if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) {
                   1064:                tx_desc->tx_control_1 |=
                   1065:                    rtscts_duration & AR5K_AR5210_DESC_TX_CTL1_RTS_DURATION;
                   1066:        }
                   1067:
                   1068:        return (AH_TRUE);
                   1069: }
                   1070:
                   1071: HAL_BOOL
                   1072: ar5k_ar5210_fill_tx_desc(struct ath_hal *hal, struct ath_desc *desc,
                   1073:     u_int segment_length, HAL_BOOL first_segment, HAL_BOOL last_segment)
                   1074: {
                   1075:        struct ar5k_ar5210_tx_desc *tx_desc;
                   1076:
                   1077:        tx_desc = (struct ar5k_ar5210_tx_desc*)&desc->ds_ctl0;
                   1078:
                   1079:        /* Clear status descriptor */
                   1080:        bzero(desc->ds_hw, sizeof(desc->ds_hw));
                   1081:
                   1082:        /* Validate segment length and initialize the descriptor */
                   1083:        if ((tx_desc->tx_control_1 = (segment_length &
                   1084:            AR5K_AR5210_DESC_TX_CTL1_BUF_LEN)) != segment_length)
                   1085:                return (AH_FALSE);
                   1086:
                   1087:        if (first_segment != AH_TRUE)
                   1088:                tx_desc->tx_control_0 &= ~AR5K_AR5210_DESC_TX_CTL0_FRAME_LEN;
                   1089:
                   1090:        if (last_segment != AH_TRUE)
                   1091:                tx_desc->tx_control_1 |= AR5K_AR5210_DESC_TX_CTL1_MORE;
                   1092:
                   1093:        return (AH_TRUE);
                   1094: }
                   1095:
                   1096: HAL_BOOL
                   1097: ar5k_ar5210_setup_xtx_desc(struct ath_hal *hal, struct ath_desc *desc,
                   1098:     u_int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2,
                   1099:     u_int tx_rate3, u_int tx_tries3)
                   1100: {
                   1101:        /*
                   1102:         * Does this function is for setting up XR? Not sure...
                   1103:         * Nevertheless, I didn't find any information about XR support
                   1104:         * by the AR5210. This seems to be a slightly new feature.
                   1105:         */
                   1106:        return (AH_FALSE);
                   1107: }
                   1108:
                   1109: HAL_STATUS
                   1110: ar5k_ar5210_proc_tx_desc(struct ath_hal *hal, struct ath_desc *desc)
                   1111: {
                   1112:        struct ar5k_ar5210_tx_status *tx_status;
                   1113:        struct ar5k_ar5210_tx_desc *tx_desc;
                   1114:
                   1115:        tx_desc = (struct ar5k_ar5210_tx_desc*)&desc->ds_ctl0;
                   1116:        tx_status = (struct ar5k_ar5210_tx_status*)&desc->ds_hw[0];
                   1117:
                   1118:        /* No frame has been send or error */
                   1119:        if ((tx_status->tx_status_1 & AR5K_AR5210_DESC_TX_STATUS1_DONE) == 0)
                   1120:                return (HAL_EINPROGRESS);
                   1121:
                   1122:        /*
                   1123:         * Get descriptor status
                   1124:         */
                   1125:        desc->ds_us.tx.ts_tstamp =
                   1126:            AR5K_REG_MS(tx_status->tx_status_0,
                   1127:            AR5K_AR5210_DESC_TX_STATUS0_SEND_TIMESTAMP);
                   1128:        desc->ds_us.tx.ts_shortretry =
                   1129:            AR5K_REG_MS(tx_status->tx_status_0,
                   1130:            AR5K_AR5210_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
                   1131:        desc->ds_us.tx.ts_longretry =
                   1132:            AR5K_REG_MS(tx_status->tx_status_0,
                   1133:            AR5K_AR5210_DESC_TX_STATUS0_LONG_RETRY_COUNT);
                   1134:        desc->ds_us.tx.ts_seqnum =
                   1135:            AR5K_REG_MS(tx_status->tx_status_1,
                   1136:            AR5K_AR5210_DESC_TX_STATUS1_SEQ_NUM);
                   1137:        desc->ds_us.tx.ts_rssi =
                   1138:            AR5K_REG_MS(tx_status->tx_status_1,
                   1139:            AR5K_AR5210_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
                   1140:        desc->ds_us.tx.ts_antenna = 1;
                   1141:        desc->ds_us.tx.ts_status = 0;
                   1142:        desc->ds_us.tx.ts_rate =
                   1143:            AR5K_REG_MS(tx_desc->tx_control_0,
                   1144:            AR5K_AR5210_DESC_TX_CTL0_XMIT_RATE);
                   1145:
                   1146:        if ((tx_status->tx_status_0 &
                   1147:            AR5K_AR5210_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0) {
                   1148:                if (tx_status->tx_status_0 &
                   1149:                    AR5K_AR5210_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
                   1150:                        desc->ds_us.tx.ts_status |= HAL_TXERR_XRETRY;
                   1151:
                   1152:                if (tx_status->tx_status_0 &
                   1153:                    AR5K_AR5210_DESC_TX_STATUS0_FIFO_UNDERRUN)
                   1154:                        desc->ds_us.tx.ts_status |= HAL_TXERR_FIFO;
                   1155:
                   1156:                if (tx_status->tx_status_0 &
                   1157:                    AR5K_AR5210_DESC_TX_STATUS0_FILTERED)
                   1158:                        desc->ds_us.tx.ts_status |= HAL_TXERR_FILT;
                   1159:        }
                   1160:
                   1161:        return (HAL_OK);
                   1162: }
                   1163:
                   1164: HAL_BOOL
                   1165: ar5k_ar5210_has_veol(struct ath_hal *hal)
                   1166: {
                   1167:        return (AH_FALSE);
                   1168: }
                   1169:
                   1170: /*
                   1171:  * Receive functions
                   1172:  */
                   1173:
                   1174: u_int32_t
                   1175: ar5k_ar5210_get_rx_buf(struct ath_hal *hal)
                   1176: {
                   1177:        return (AR5K_REG_READ(AR5K_AR5210_RXDP));
                   1178: }
                   1179:
                   1180: void
                   1181: ar5k_ar5210_put_rx_buf(struct ath_hal *hal, u_int32_t phys_addr)
                   1182: {
                   1183:        AR5K_REG_WRITE(AR5K_AR5210_RXDP, phys_addr);
                   1184: }
                   1185:
                   1186: void
                   1187: ar5k_ar5210_start_rx(struct ath_hal *hal)
                   1188: {
                   1189:        AR5K_REG_WRITE(AR5K_AR5210_CR, AR5K_AR5210_CR_RXE);
                   1190: }
                   1191:
                   1192: HAL_BOOL
                   1193: ar5k_ar5210_stop_rx_dma(struct ath_hal *hal)
                   1194: {
                   1195:        int i;
                   1196:
                   1197:        AR5K_REG_WRITE(AR5K_AR5210_CR, AR5K_AR5210_CR_RXD);
                   1198:
                   1199:        /*
                   1200:         * It may take some time to disable the DMA receive unit
                   1201:         */
                   1202:        for (i = 2000;
                   1203:             i > 0 && (AR5K_REG_READ(AR5K_AR5210_CR) & AR5K_AR5210_CR_RXE) != 0;
                   1204:             i--)
                   1205:                AR5K_DELAY(10);
                   1206:
                   1207:        return (i > 0 ? AH_TRUE : AH_FALSE);
                   1208: }
                   1209:
                   1210: void
                   1211: ar5k_ar5210_start_rx_pcu(struct ath_hal *hal)
                   1212: {
                   1213:        AR5K_REG_DISABLE_BITS(AR5K_AR5210_DIAG_SW, AR5K_AR5210_DIAG_SW_DIS_RX);
                   1214: }
                   1215:
                   1216: void
                   1217: ar5k_ar5210_stop_pcu_recv(struct ath_hal *hal)
                   1218: {
                   1219:        AR5K_REG_ENABLE_BITS(AR5K_AR5210_DIAG_SW, AR5K_AR5210_DIAG_SW_DIS_RX);
                   1220: }
                   1221:
                   1222: void
                   1223: ar5k_ar5210_set_mcast_filter(struct ath_hal *hal, u_int32_t filter0,
                   1224:     u_int32_t filter1)
                   1225: {
                   1226:        /* Set the multicat filter */
                   1227:        AR5K_REG_WRITE(AR5K_AR5210_MCAST_FIL0, filter0);
                   1228:        AR5K_REG_WRITE(AR5K_AR5210_MCAST_FIL1, filter1);
                   1229: }
                   1230:
                   1231: HAL_BOOL
                   1232: ar5k_ar5210_set_mcast_filterindex(struct ath_hal *hal, u_int32_t index)
                   1233: {
                   1234:        if (index >= 64) {
                   1235:                return (AH_FALSE);
                   1236:        } else if (index >= 32) {
                   1237:                AR5K_REG_ENABLE_BITS(AR5K_AR5210_MCAST_FIL1,
                   1238:                    (1 << (index - 32)));
                   1239:        } else {
                   1240:                AR5K_REG_ENABLE_BITS(AR5K_AR5210_MCAST_FIL0,
                   1241:                    (1 << index));
                   1242:        }
                   1243:
                   1244:        return (AH_TRUE);
                   1245: }
                   1246:
                   1247: HAL_BOOL
                   1248: ar5k_ar5210_clear_mcast_filter_idx(struct ath_hal *hal, u_int32_t index)
                   1249: {
                   1250:        if (index >= 64) {
                   1251:                return (AH_FALSE);
                   1252:        } else if (index >= 32) {
                   1253:                AR5K_REG_DISABLE_BITS(AR5K_AR5210_MCAST_FIL1,
                   1254:                    (1 << (index - 32)));
                   1255:        } else {
                   1256:                AR5K_REG_DISABLE_BITS(AR5K_AR5210_MCAST_FIL0,
                   1257:                    (1 << index));
                   1258:        }
                   1259:
                   1260:        return (AH_TRUE);
                   1261: }
                   1262:
                   1263: u_int32_t
                   1264: ar5k_ar5210_get_rx_filter(struct ath_hal *hal)
                   1265: {
                   1266:        return (AR5K_REG_READ(AR5K_AR5210_RX_FILTER));
                   1267: }
                   1268:
                   1269: void
                   1270: ar5k_ar5210_set_rx_filter(struct ath_hal *hal, u_int32_t filter)
                   1271: {
                   1272:        /*
                   1273:         * The AR5210 uses promiscous mode to detect radar activity
                   1274:         */
                   1275:        if (filter & HAL_RX_FILTER_PHYRADAR) {
                   1276:                filter &= ~HAL_RX_FILTER_PHYRADAR;
                   1277:                filter |= AR5K_AR5210_RX_FILTER_PROMISC;
                   1278:        }
                   1279:
                   1280:        AR5K_REG_WRITE(AR5K_AR5210_RX_FILTER, filter);
                   1281: }
                   1282:
                   1283: HAL_BOOL
                   1284: ar5k_ar5210_setup_rx_desc(struct ath_hal *hal, struct ath_desc *desc,
                   1285:     u_int32_t size, u_int flags)
                   1286: {
                   1287:        struct ar5k_ar5210_rx_desc *rx_desc;
                   1288:
                   1289:        rx_desc = (struct ar5k_ar5210_rx_desc*)&desc->ds_ctl0;
                   1290:
                   1291:        if ((rx_desc->rx_control_1 = (size &
                   1292:            AR5K_AR5210_DESC_RX_CTL1_BUF_LEN)) != size)
                   1293:                return (AH_FALSE);
                   1294:
                   1295:        if (flags & HAL_RXDESC_INTREQ)
                   1296:                rx_desc->rx_control_1 |= AR5K_AR5210_DESC_RX_CTL1_INTREQ;
                   1297:
                   1298:        return (AH_TRUE);
                   1299: }
                   1300:
                   1301: HAL_STATUS
                   1302: ar5k_ar5210_proc_rx_desc(struct ath_hal *hal, struct ath_desc *desc,
                   1303:     u_int32_t phys_addr, struct ath_desc *next)
                   1304: {
                   1305:        struct ar5k_ar5210_rx_status *rx_status;
                   1306:
                   1307:        rx_status = (struct ar5k_ar5210_rx_status*)&desc->ds_hw[0];
                   1308:
                   1309:        /* No frame received / not ready */
                   1310:        if ((rx_status->rx_status_1 & AR5K_AR5210_DESC_RX_STATUS1_DONE) == 0)
                   1311:                return (HAL_EINPROGRESS);
                   1312:
                   1313:        /*
                   1314:         * Frame receive status
                   1315:         */
                   1316:        desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 &
                   1317:            AR5K_AR5210_DESC_RX_STATUS0_DATA_LEN;
                   1318:        desc->ds_us.rx.rs_rssi =
                   1319:            AR5K_REG_MS(rx_status->rx_status_0,
                   1320:            AR5K_AR5210_DESC_RX_STATUS0_RECEIVE_SIGNAL);
                   1321:        desc->ds_us.rx.rs_rate =
                   1322:            AR5K_REG_MS(rx_status->rx_status_0,
                   1323:            AR5K_AR5210_DESC_RX_STATUS0_RECEIVE_RATE);
                   1324:        desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 &
                   1325:            AR5K_AR5210_DESC_RX_STATUS0_RECEIVE_ANTENNA;
                   1326:        desc->ds_us.rx.rs_more = rx_status->rx_status_0 &
                   1327:            AR5K_AR5210_DESC_RX_STATUS0_MORE;
                   1328:        desc->ds_us.rx.rs_tstamp =
                   1329:            AR5K_REG_MS(rx_status->rx_status_1,
                   1330:            AR5K_AR5210_DESC_RX_STATUS1_RECEIVE_TIMESTAMP);
                   1331:        desc->ds_us.rx.rs_status = 0;
                   1332:
                   1333:        /*
                   1334:         * Key table status
                   1335:         */
                   1336:        if (rx_status->rx_status_1 &
                   1337:            AR5K_AR5210_DESC_RX_STATUS1_KEY_INDEX_VALID) {
                   1338:                desc->ds_us.rx.rs_keyix =
                   1339:                    AR5K_REG_MS(rx_status->rx_status_1,
                   1340:                    AR5K_AR5210_DESC_RX_STATUS1_KEY_INDEX);
                   1341:        } else {
                   1342:                desc->ds_us.rx.rs_keyix = HAL_RXKEYIX_INVALID;
                   1343:        }
                   1344:
                   1345:        /*
                   1346:         * Receive/descriptor errors
                   1347:         */
                   1348:        if ((rx_status->rx_status_1 &
                   1349:            AR5K_AR5210_DESC_RX_STATUS1_FRAME_RECEIVE_OK) == 0) {
                   1350:                if (rx_status->rx_status_1 &
                   1351:                    AR5K_AR5210_DESC_RX_STATUS1_CRC_ERROR)
                   1352:                        desc->ds_us.rx.rs_status |= HAL_RXERR_CRC;
                   1353:
                   1354:                if (rx_status->rx_status_1 &
                   1355:                    AR5K_AR5210_DESC_RX_STATUS1_FIFO_OVERRUN)
                   1356:                        desc->ds_us.rx.rs_status |= HAL_RXERR_FIFO;
                   1357:
                   1358:                if (rx_status->rx_status_1 &
                   1359:                    AR5K_AR5210_DESC_RX_STATUS1_PHY_ERROR) {
                   1360:                        desc->ds_us.rx.rs_status |= HAL_RXERR_PHY;
                   1361:                        desc->ds_us.rx.rs_phyerr =
                   1362:                            AR5K_REG_MS(rx_status->rx_status_1,
                   1363:                            AR5K_AR5210_DESC_RX_STATUS1_PHY_ERROR);
                   1364:                }
                   1365:
                   1366:                if (rx_status->rx_status_1 &
                   1367:                    AR5K_AR5210_DESC_RX_STATUS1_DECRYPT_CRC_ERROR)
                   1368:                        desc->ds_us.rx.rs_status |= HAL_RXERR_DECRYPT;
                   1369:        }
                   1370:
                   1371:        return (HAL_OK);
                   1372: }
                   1373:
                   1374: void
                   1375: ar5k_ar5210_set_rx_signal(struct ath_hal *hal)
                   1376: {
                   1377:        /* Signal state monitoring is not yet supported */
                   1378: }
                   1379:
                   1380: /*
                   1381:  * Misc functions
                   1382:  */
                   1383:
                   1384: void
                   1385: ar5k_ar5210_dump_state(struct ath_hal *hal)
                   1386: {
                   1387: #ifdef AR5K_DEBUG
                   1388: #define AR5K_PRINT_REGISTER(_x)                                                \
                   1389:        printf("(%s: %08x) ", #_x, AR5K_REG_READ(AR5K_AR5210_##_x));
                   1390:
                   1391:        printf("DMA registers:\n");
                   1392:        AR5K_PRINT_REGISTER(TXDP0);
                   1393:        AR5K_PRINT_REGISTER(TXDP1);
                   1394:        AR5K_PRINT_REGISTER(CR);
                   1395:        AR5K_PRINT_REGISTER(RXDP);
                   1396:        AR5K_PRINT_REGISTER(CFG);
                   1397:        AR5K_PRINT_REGISTER(ISR);
                   1398:        AR5K_PRINT_REGISTER(IMR);
                   1399:        AR5K_PRINT_REGISTER(IER);
                   1400:        AR5K_PRINT_REGISTER(BCR);
                   1401:        AR5K_PRINT_REGISTER(BSR);
                   1402:        AR5K_PRINT_REGISTER(TXCFG);
                   1403:        AR5K_PRINT_REGISTER(RXCFG);
                   1404:        AR5K_PRINT_REGISTER(MIBC);
                   1405:        AR5K_PRINT_REGISTER(TOPS);
                   1406:        AR5K_PRINT_REGISTER(RXNOFRM);
                   1407:        AR5K_PRINT_REGISTER(TXNOFRM);
                   1408:        AR5K_PRINT_REGISTER(RPGTO);
                   1409:        AR5K_PRINT_REGISTER(RFCNT);
                   1410:        AR5K_PRINT_REGISTER(MISC);
                   1411:        AR5K_PRINT_REGISTER(RC);
                   1412:        AR5K_PRINT_REGISTER(SCR);
                   1413:        AR5K_PRINT_REGISTER(INTPEND);
                   1414:        AR5K_PRINT_REGISTER(SFR);
                   1415:        AR5K_PRINT_REGISTER(PCICFG);
                   1416:        AR5K_PRINT_REGISTER(GPIOCR);
                   1417:        AR5K_PRINT_REGISTER(GPIODO);
                   1418:        AR5K_PRINT_REGISTER(GPIODI);
                   1419:        AR5K_PRINT_REGISTER(SREV);
                   1420:        printf("\n");
                   1421:
                   1422:        printf("PCU registers:\n");
                   1423:        AR5K_PRINT_REGISTER(STA_ID0);
                   1424:        AR5K_PRINT_REGISTER(STA_ID1);
                   1425:        AR5K_PRINT_REGISTER(BSS_ID0);
                   1426:        AR5K_PRINT_REGISTER(BSS_ID1);
                   1427:        AR5K_PRINT_REGISTER(SLOT_TIME);
                   1428:        AR5K_PRINT_REGISTER(TIME_OUT);
                   1429:        AR5K_PRINT_REGISTER(RSSI_THR);
                   1430:        AR5K_PRINT_REGISTER(RETRY_LMT);
                   1431:        AR5K_PRINT_REGISTER(USEC);
                   1432:        AR5K_PRINT_REGISTER(BEACON);
                   1433:        AR5K_PRINT_REGISTER(CFP_PERIOD);
                   1434:        AR5K_PRINT_REGISTER(TIMER0);
                   1435:        AR5K_PRINT_REGISTER(TIMER1);
                   1436:        AR5K_PRINT_REGISTER(TIMER2);
                   1437:        AR5K_PRINT_REGISTER(TIMER3);
                   1438:        AR5K_PRINT_REGISTER(IFS0);
                   1439:        AR5K_PRINT_REGISTER(IFS1);
                   1440:        AR5K_PRINT_REGISTER(CFP_DUR);
                   1441:        AR5K_PRINT_REGISTER(RX_FILTER);
                   1442:        AR5K_PRINT_REGISTER(MCAST_FIL0);
                   1443:        AR5K_PRINT_REGISTER(MCAST_FIL1);
                   1444:        AR5K_PRINT_REGISTER(TX_MASK0);
                   1445:        AR5K_PRINT_REGISTER(TX_MASK1);
                   1446:        AR5K_PRINT_REGISTER(CLR_TMASK);
                   1447:        AR5K_PRINT_REGISTER(TRIG_LVL);
                   1448:        AR5K_PRINT_REGISTER(DIAG_SW);
                   1449:        AR5K_PRINT_REGISTER(TSF_L32);
                   1450:        AR5K_PRINT_REGISTER(TSF_U32);
                   1451:        AR5K_PRINT_REGISTER(LAST_TSTP);
                   1452:        AR5K_PRINT_REGISTER(RETRY_CNT);
                   1453:        AR5K_PRINT_REGISTER(BACKOFF);
                   1454:        AR5K_PRINT_REGISTER(NAV);
                   1455:        AR5K_PRINT_REGISTER(RTS_OK);
                   1456:        AR5K_PRINT_REGISTER(RTS_FAIL);
                   1457:        AR5K_PRINT_REGISTER(ACK_FAIL);
                   1458:        AR5K_PRINT_REGISTER(FCS_FAIL);
                   1459:        AR5K_PRINT_REGISTER(BEACON_CNT);
                   1460:        AR5K_PRINT_REGISTER(KEYTABLE_0);
                   1461:        printf("\n");
                   1462:
                   1463:        printf("PHY registers:\n");
                   1464:        AR5K_PRINT_REGISTER(PHY(0));
                   1465:        AR5K_PRINT_REGISTER(PHY_FC);
                   1466:        AR5K_PRINT_REGISTER(PHY_AGC);
                   1467:        AR5K_PRINT_REGISTER(PHY_CHIP_ID);
                   1468:        AR5K_PRINT_REGISTER(PHY_ACTIVE);
                   1469:        AR5K_PRINT_REGISTER(PHY_AGCCTL);
                   1470:        printf("\n");
                   1471: #endif
                   1472: }
                   1473:
                   1474: HAL_BOOL
                   1475: ar5k_ar5210_get_diag_state(struct ath_hal *hal, int id, void **device,
                   1476:     u_int *size)
                   1477: {
                   1478:        /*
                   1479:         * We'll ignore this right now. This seems to be some kind of an obscure
                   1480:          * debugging interface for the binary-only HAL.
                   1481:         */
                   1482:        return (AH_FALSE);
                   1483: }
                   1484:
                   1485: void
                   1486: ar5k_ar5210_get_lladdr(struct ath_hal *hal, u_int8_t *mac)
                   1487: {
                   1488:        bcopy(hal->ah_sta_id, mac, IEEE80211_ADDR_LEN);
                   1489: }
                   1490:
                   1491: HAL_BOOL
                   1492: ar5k_ar5210_set_lladdr(struct ath_hal *hal, const u_int8_t *mac)
                   1493: {
                   1494:        u_int32_t low_id, high_id;
                   1495:
                   1496:        /* Set new station ID */
                   1497:        bcopy(mac, hal->ah_sta_id, IEEE80211_ADDR_LEN);
                   1498:
                   1499:        low_id = AR5K_LOW_ID(mac);
                   1500:        high_id = 0x0000ffff & AR5K_HIGH_ID(mac);
                   1501:
                   1502:        AR5K_REG_WRITE(AR5K_AR5210_STA_ID0, low_id);
                   1503:        AR5K_REG_WRITE(AR5K_AR5210_STA_ID1, high_id);
                   1504:
                   1505:        return (AH_TRUE);
                   1506: }
                   1507:
                   1508: HAL_BOOL
                   1509: ar5k_ar5210_set_regdomain(struct ath_hal *hal, u_int16_t regdomain,
                   1510:     HAL_STATUS *status)
                   1511: {
                   1512:        ieee80211_regdomain_t ieee_regdomain;
                   1513:
                   1514:        ieee_regdomain = ar5k_regdomain_to_ieee(regdomain);
                   1515:
                   1516:        if (ar5k_eeprom_regulation_domain(hal, AH_TRUE,
                   1517:                &ieee_regdomain) == AH_TRUE) {
                   1518:                *status = HAL_OK;
                   1519:                return (AH_TRUE);
                   1520:        }
                   1521:
                   1522:        *status = EIO;
                   1523:
                   1524:        return (AH_FALSE);
                   1525: }
                   1526:
                   1527: void
                   1528: ar5k_ar5210_set_ledstate(struct ath_hal *hal, HAL_LED_STATE state)
                   1529: {
                   1530:        u_int32_t led;
                   1531:
                   1532:        led = AR5K_REG_READ(AR5K_AR5210_PCICFG);
                   1533:
                   1534:        /*
                   1535:         * Some blinking values, define at your wish
                   1536:         */
                   1537:        switch (state) {
                   1538:        case IEEE80211_S_SCAN:
                   1539:        case IEEE80211_S_INIT:
                   1540:                led |=
                   1541:                    AR5K_AR5210_PCICFG_LED_PEND |
                   1542:                    AR5K_AR5210_PCICFG_LED_BCTL;
                   1543:                break;
                   1544:        case IEEE80211_S_RUN:
                   1545:                led |=
                   1546:                    AR5K_AR5210_PCICFG_LED_ACT;
                   1547:                break;
                   1548:        default:
                   1549:                led |=
                   1550:                    AR5K_AR5210_PCICFG_LED_ACT |
                   1551:                    AR5K_AR5210_PCICFG_LED_BCTL;
                   1552:                break;
                   1553:        }
                   1554:
                   1555:        AR5K_REG_WRITE(AR5K_AR5210_PCICFG, led);
                   1556: }
                   1557:
                   1558: void
                   1559: ar5k_ar5210_set_associd(struct ath_hal *hal, const u_int8_t *bssid,
                   1560:     u_int16_t assoc_id, u_int16_t tim_offset)
                   1561: {
                   1562:        u_int32_t low_id, high_id;
                   1563:
                   1564:        /*
                   1565:         * Set BSSID which triggers the "SME Join" operation
                   1566:         */
                   1567:        low_id = AR5K_LOW_ID(bssid);
                   1568:        high_id = AR5K_HIGH_ID(bssid);
                   1569:        AR5K_REG_WRITE(AR5K_AR5210_BSS_ID0, low_id);
                   1570:        AR5K_REG_WRITE(AR5K_AR5210_BSS_ID1, high_id |
                   1571:            ((assoc_id & 0x3fff) << AR5K_AR5210_BSS_ID1_AID_S));
                   1572:        bcopy(bssid, &hal->ah_bssid, IEEE80211_ADDR_LEN);
                   1573:
                   1574:        if (assoc_id == 0) {
                   1575:                ar5k_ar5210_disable_pspoll(hal);
                   1576:                return;
                   1577:        }
                   1578:
                   1579:        AR5K_REG_WRITE_BITS(AR5K_AR5210_BEACON, AR5K_AR5210_BEACON_TIM,
                   1580:            tim_offset ? tim_offset + 4 : 0);
                   1581:
                   1582:        ar5k_ar5210_enable_pspoll(hal, NULL, 0);
                   1583: }
                   1584:
                   1585: HAL_BOOL
                   1586: ar5k_ar5210_set_bssid_mask(struct ath_hal *hal, const u_int8_t* mask)
                   1587: {
                   1588:        /* Not supported in 5210 */
                   1589:        return (AH_FALSE);
                   1590: }
                   1591:
                   1592: HAL_BOOL
                   1593: ar5k_ar5210_set_gpio_output(struct ath_hal *hal, u_int32_t gpio)
                   1594: {
                   1595:        if (gpio > AR5K_AR5210_NUM_GPIO)
                   1596:                return (AH_FALSE);
                   1597:
                   1598:        AR5K_REG_WRITE(AR5K_AR5210_GPIOCR,
                   1599:            (AR5K_REG_READ(AR5K_AR5210_GPIOCR) &~ AR5K_AR5210_GPIOCR_ALL(gpio))
                   1600:            | AR5K_AR5210_GPIOCR_OUT1(gpio));
                   1601:
                   1602:        return (AH_TRUE);
                   1603: }
                   1604:
                   1605: HAL_BOOL
                   1606: ar5k_ar5210_set_gpio_input(struct ath_hal *hal, u_int32_t gpio)
                   1607: {
                   1608:        if (gpio > AR5K_AR5210_NUM_GPIO)
                   1609:                return (AH_FALSE);
                   1610:
                   1611:        AR5K_REG_WRITE(AR5K_AR5210_GPIOCR,
                   1612:            (AR5K_REG_READ(AR5K_AR5210_GPIOCR) &~ AR5K_AR5210_GPIOCR_ALL(gpio))
                   1613:            | AR5K_AR5210_GPIOCR_IN(gpio));
                   1614:
                   1615:        return (AH_TRUE);
                   1616: }
                   1617:
                   1618: u_int32_t
                   1619: ar5k_ar5210_get_gpio(struct ath_hal *hal, u_int32_t gpio)
                   1620: {
                   1621:        if (gpio > AR5K_AR5210_NUM_GPIO)
                   1622:                return (0xffffffff);
                   1623:
                   1624:        /* GPIO input magic */
                   1625:        return (((AR5K_REG_READ(AR5K_AR5210_GPIODI) &
                   1626:                     AR5K_AR5210_GPIOD_MASK) >> gpio) & 0x1);
                   1627: }
                   1628:
                   1629: HAL_BOOL
                   1630: ar5k_ar5210_set_gpio(struct ath_hal *hal, u_int32_t gpio, u_int32_t val)
                   1631: {
                   1632:        u_int32_t data;
                   1633:
                   1634:        if (gpio > AR5K_AR5210_NUM_GPIO)
                   1635:                return (0xffffffff);
                   1636:
                   1637:        /* GPIO output magic */
                   1638:        data =  AR5K_REG_READ(AR5K_AR5210_GPIODO);
                   1639:
                   1640:        data &= ~(1 << gpio);
                   1641:        data |= (val&1) << gpio;
                   1642:
                   1643:        AR5K_REG_WRITE(AR5K_AR5210_GPIODO, data);
                   1644:
                   1645:        return (AH_TRUE);
                   1646: }
                   1647:
                   1648: void
                   1649: ar5k_ar5210_set_gpio_intr(struct ath_hal *hal, u_int gpio,
                   1650:     u_int32_t interrupt_level)
                   1651: {
                   1652:        u_int32_t data;
                   1653:
                   1654:        if (gpio > AR5K_AR5210_NUM_GPIO)
                   1655:                return;
                   1656:
                   1657:        /*
                   1658:         * Set the GPIO interrupt
                   1659:         */
                   1660:        data = (AR5K_REG_READ(AR5K_AR5210_GPIOCR) &
                   1661:            ~(AR5K_AR5210_GPIOCR_INT_SEL(gpio) | AR5K_AR5210_GPIOCR_INT_SELH |
                   1662:                AR5K_AR5210_GPIOCR_INT_ENA | AR5K_AR5210_GPIOCR_ALL(gpio))) |
                   1663:            (AR5K_AR5210_GPIOCR_INT_SEL(gpio) | AR5K_AR5210_GPIOCR_INT_ENA);
                   1664:
                   1665:        AR5K_REG_WRITE(AR5K_AR5210_GPIOCR,
                   1666:            interrupt_level ? data : (data | AR5K_AR5210_GPIOCR_INT_SELH));
                   1667:
                   1668:        hal->ah_imr |= AR5K_AR5210_IMR_GPIO;
                   1669:
                   1670:        /* Enable GPIO interrupts */
                   1671:        AR5K_REG_ENABLE_BITS(AR5K_AR5210_IMR, AR5K_AR5210_IMR_GPIO);
                   1672: }
                   1673:
                   1674: u_int32_t
                   1675: ar5k_ar5210_get_tsf32(struct ath_hal *hal)
                   1676: {
                   1677:        return (AR5K_REG_READ(AR5K_AR5210_TSF_L32));
                   1678: }
                   1679:
                   1680: u_int64_t
                   1681: ar5k_ar5210_get_tsf64(struct ath_hal *hal)
                   1682: {
                   1683:        u_int64_t tsf = AR5K_REG_READ(AR5K_AR5210_TSF_U32);
                   1684:        return (AR5K_REG_READ(AR5K_AR5210_TSF_L32) | (tsf << 32));
                   1685: }
                   1686:
                   1687: void
                   1688: ar5k_ar5210_reset_tsf(struct ath_hal *hal)
                   1689: {
                   1690:        AR5K_REG_ENABLE_BITS(AR5K_AR5210_BEACON,
                   1691:            AR5K_AR5210_BEACON_RESET_TSF);
                   1692: }
                   1693:
                   1694: u_int16_t
                   1695: ar5k_ar5210_get_regdomain(struct ath_hal *hal)
                   1696: {
                   1697:        return (ar5k_get_regdomain(hal));
                   1698: }
                   1699:
                   1700: HAL_BOOL
                   1701: ar5k_ar5210_detect_card_present(struct ath_hal *hal)
                   1702: {
                   1703:        u_int16_t magic;
                   1704:
                   1705:        /*
                   1706:         * Checking the EEPROM's magic value could be an indication
                   1707:         * if the card is still present. I didn't find another suitable
                   1708:         * way to do this.
                   1709:         */
                   1710:        if (ar5k_ar5210_eeprom_read(hal, AR5K_EEPROM_MAGIC, &magic) != 0)
                   1711:                return (AH_FALSE);
                   1712:
                   1713:        return (magic == AR5K_EEPROM_MAGIC_VALUE ? AH_TRUE : AH_FALSE);
                   1714: }
                   1715:
                   1716: void
                   1717: ar5k_ar5210_update_mib_counters(struct ath_hal *hal, HAL_MIB_STATS *statistics)
                   1718: {
                   1719:        statistics->ackrcv_bad += AR5K_REG_READ(AR5K_AR5210_ACK_FAIL);
                   1720:        statistics->rts_bad += AR5K_REG_READ(AR5K_AR5210_RTS_FAIL);
                   1721:        statistics->rts_good += AR5K_REG_READ(AR5K_AR5210_RTS_OK);
                   1722:        statistics->fcs_bad += AR5K_REG_READ(AR5K_AR5210_FCS_FAIL);
                   1723:        statistics->beacons += AR5K_REG_READ(AR5K_AR5210_BEACON_CNT);
                   1724: }
                   1725:
                   1726: HAL_RFGAIN
                   1727: ar5k_ar5210_get_rf_gain(struct ath_hal *hal)
                   1728: {
                   1729:        return (HAL_RFGAIN_INACTIVE);
                   1730: }
                   1731:
                   1732: HAL_BOOL
                   1733: ar5k_ar5210_set_slot_time(struct ath_hal *hal, u_int slot_time)
                   1734: {
                   1735:        if (slot_time < HAL_SLOT_TIME_9 || slot_time > HAL_SLOT_TIME_MAX)
                   1736:                return (AH_FALSE);
                   1737:
                   1738:        AR5K_REG_WRITE(AR5K_AR5210_SLOT_TIME,
                   1739:            ar5k_htoclock(slot_time, hal->ah_turbo));
                   1740:
                   1741:        return (AH_TRUE);
                   1742: }
                   1743:
                   1744: u_int
                   1745: ar5k_ar5210_get_slot_time(struct ath_hal *hal)
                   1746: {
                   1747:        return (ar5k_clocktoh(AR5K_REG_READ(AR5K_AR5210_SLOT_TIME) &
                   1748:                    0xffff, hal->ah_turbo));
                   1749: }
                   1750:
                   1751: HAL_BOOL
                   1752: ar5k_ar5210_set_ack_timeout(struct ath_hal *hal, u_int timeout)
                   1753: {
                   1754:        if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5210_TIME_OUT_ACK),
                   1755:                hal->ah_turbo) <= timeout)
                   1756:                return (AH_FALSE);
                   1757:
                   1758:        AR5K_REG_WRITE_BITS(AR5K_AR5210_TIME_OUT, AR5K_AR5210_TIME_OUT_ACK,
                   1759:            ar5k_htoclock(timeout, hal->ah_turbo));
                   1760:
                   1761:        return (AH_TRUE);
                   1762: }
                   1763:
                   1764: u_int
                   1765: ar5k_ar5210_get_ack_timeout(struct ath_hal *hal)
                   1766: {
                   1767:        return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5210_TIME_OUT),
                   1768:            AR5K_AR5210_TIME_OUT_ACK), hal->ah_turbo));
                   1769: }
                   1770:
                   1771: HAL_BOOL
                   1772: ar5k_ar5210_set_cts_timeout(struct ath_hal *hal, u_int timeout)
                   1773: {
                   1774:        if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5210_TIME_OUT_CTS),
                   1775:            hal->ah_turbo) <= timeout)
                   1776:                return (AH_FALSE);
                   1777:
                   1778:        AR5K_REG_WRITE_BITS(AR5K_AR5210_TIME_OUT, AR5K_AR5210_TIME_OUT_CTS,
                   1779:            ar5k_htoclock(timeout, hal->ah_turbo));
                   1780:
                   1781:        return (AH_TRUE);
                   1782: }
                   1783:
                   1784: u_int
                   1785: ar5k_ar5210_get_cts_timeout(struct ath_hal *hal)
                   1786: {
                   1787:        return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5210_TIME_OUT),
                   1788:            AR5K_AR5210_TIME_OUT_CTS), hal->ah_turbo));
                   1789: }
                   1790:
                   1791: /*
                   1792:  * Key table (WEP) functions
                   1793:  */
                   1794:
                   1795: HAL_BOOL
                   1796: ar5k_ar5210_is_cipher_supported(struct ath_hal *hal, HAL_CIPHER cipher)
                   1797: {
                   1798:        /*
                   1799:         * The AR5210 only supports WEP
                   1800:         */
                   1801:        if (cipher == HAL_CIPHER_WEP)
                   1802:                return (AH_TRUE);
                   1803:
                   1804:        return (AH_FALSE);
                   1805: }
                   1806:
                   1807: u_int32_t
                   1808: ar5k_ar5210_get_keycache_size(struct ath_hal *hal)
                   1809: {
                   1810:        return (AR5K_AR5210_KEYCACHE_SIZE);
                   1811: }
                   1812:
                   1813: HAL_BOOL
                   1814: ar5k_ar5210_reset_key(struct ath_hal *hal, u_int16_t entry)
                   1815: {
                   1816:        int i;
                   1817:
                   1818:        AR5K_ASSERT_ENTRY(entry, AR5K_AR5210_KEYTABLE_SIZE);
                   1819:
                   1820:        for (i = 0; i < AR5K_AR5210_KEYCACHE_SIZE; i++)
                   1821:                AR5K_REG_WRITE(AR5K_AR5210_KEYTABLE_OFF(entry, i), 0);
                   1822:
                   1823:        return (AH_FALSE);
                   1824: }
                   1825:
                   1826: HAL_BOOL
                   1827: ar5k_ar5210_is_key_valid(struct ath_hal *hal, u_int16_t entry)
                   1828: {
                   1829:        AR5K_ASSERT_ENTRY(entry, AR5K_AR5210_KEYTABLE_SIZE);
                   1830:
                   1831:        /*
                   1832:         * Check the validation flag at the end of the entry
                   1833:         */
                   1834:        if (AR5K_REG_READ(AR5K_AR5210_KEYTABLE_MAC1(entry)) &
                   1835:            AR5K_AR5210_KEYTABLE_VALID)
                   1836:                return (AH_TRUE);
                   1837:
                   1838:        return (AH_FALSE);
                   1839: }
                   1840:
                   1841: HAL_BOOL
                   1842: ar5k_ar5210_set_key(struct ath_hal *hal, u_int16_t entry,
                   1843:     const HAL_KEYVAL *keyval, const u_int8_t *mac, int xor_notused)
                   1844: {
                   1845:        int i;
                   1846:        u_int32_t key_v[AR5K_AR5210_KEYCACHE_SIZE - 2];
                   1847:
                   1848:        AR5K_ASSERT_ENTRY(entry, AR5K_AR5210_KEYTABLE_SIZE);
                   1849:
                   1850:        bzero(&key_v, sizeof(key_v));
                   1851:
                   1852:        switch (keyval->wk_len) {
                   1853:        case AR5K_KEYVAL_LENGTH_40:
                   1854:                bcopy(keyval->wk_key, &key_v[0], 4);
                   1855:                bcopy(keyval->wk_key + 4, &key_v[1], 1);
                   1856:                key_v[5] = AR5K_AR5210_KEYTABLE_TYPE_40;
                   1857:                break;
                   1858:
                   1859:        case AR5K_KEYVAL_LENGTH_104:
                   1860:                bcopy(keyval->wk_key, &key_v[0], 4);
                   1861:                bcopy(keyval->wk_key + 4, &key_v[1], 2);
                   1862:                bcopy(keyval->wk_key + 6, &key_v[2], 4);
                   1863:                bcopy(keyval->wk_key + 10, &key_v[3], 2);
                   1864:                bcopy(keyval->wk_key + 12, &key_v[4], 1);
                   1865:                key_v[5] = AR5K_AR5210_KEYTABLE_TYPE_104;
                   1866:                break;
                   1867:
                   1868:        case AR5K_KEYVAL_LENGTH_128:
                   1869:                bcopy(keyval->wk_key, &key_v[0], 4);
                   1870:                bcopy(keyval->wk_key + 4, &key_v[1], 2);
                   1871:                bcopy(keyval->wk_key + 6, &key_v[2], 4);
                   1872:                bcopy(keyval->wk_key + 10, &key_v[3], 2);
                   1873:                bcopy(keyval->wk_key + 12, &key_v[4], 4);
                   1874:                key_v[5] = AR5K_AR5210_KEYTABLE_TYPE_128;
                   1875:                break;
                   1876:
                   1877:        default:
                   1878:                /* Unsupported key length (not WEP40/104/128) */
                   1879:                return (AH_FALSE);
                   1880:        }
                   1881:
                   1882:        for (i = 0; i < AR5K_ELEMENTS(key_v); i++)
                   1883:                AR5K_REG_WRITE(AR5K_AR5210_KEYTABLE_OFF(entry, i), key_v[i]);
                   1884:
                   1885:        return (ar5k_ar5210_set_key_lladdr(hal, entry, mac));
                   1886: }
                   1887:
                   1888: HAL_BOOL
                   1889: ar5k_ar5210_set_key_lladdr(struct ath_hal *hal, u_int16_t entry,
                   1890:     const u_int8_t *mac)
                   1891: {
                   1892:        u_int32_t low_id, high_id;
                   1893:        const u_int8_t *mac_v;
                   1894:
                   1895:        /*
                   1896:         * Invalid entry (key table overflow)
                   1897:         */
                   1898:        AR5K_ASSERT_ENTRY(entry, AR5K_AR5210_KEYTABLE_SIZE);
                   1899:
                   1900:        /* MAC may be NULL if it's a broadcast key */
                   1901:        mac_v = mac == NULL ? etherbroadcastaddr : mac;
                   1902:
                   1903:        low_id = AR5K_LOW_ID(mac_v);
                   1904:        high_id = AR5K_HIGH_ID(mac_v) | AR5K_AR5210_KEYTABLE_VALID;
                   1905:
                   1906:        AR5K_REG_WRITE(AR5K_AR5210_KEYTABLE_MAC0(entry), low_id);
                   1907:        AR5K_REG_WRITE(AR5K_AR5210_KEYTABLE_MAC1(entry), high_id);
                   1908:
                   1909:        return (AH_TRUE);
                   1910: }
                   1911:
                   1912: /*
                   1913:  * Power management functions
                   1914:  */
                   1915:
                   1916: HAL_BOOL
                   1917: ar5k_ar5210_set_power(struct ath_hal *hal, HAL_POWER_MODE mode,
                   1918:     HAL_BOOL set_chip, u_int16_t sleep_duration)
                   1919: {
                   1920:        u_int32_t staid;
                   1921:        int i;
                   1922:
                   1923:        staid = AR5K_REG_READ(AR5K_AR5210_STA_ID1);
                   1924:
                   1925:        switch (mode) {
                   1926:        case HAL_PM_AUTO:
                   1927:                staid &= ~AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA;
                   1928:                /* FALLTHROUGH */
                   1929:        case HAL_PM_NETWORK_SLEEP:
                   1930:                if (set_chip == AH_TRUE) {
                   1931:                        AR5K_REG_WRITE(AR5K_AR5210_SCR,
                   1932:                            AR5K_AR5210_SCR_SLE | sleep_duration);
                   1933:                }
                   1934:                staid |= AR5K_AR5210_STA_ID1_PWR_SV;
                   1935:                break;
                   1936:
                   1937:        case HAL_PM_FULL_SLEEP:
                   1938:                if (set_chip == AH_TRUE) {
                   1939:                        AR5K_REG_WRITE(AR5K_AR5210_SCR,
                   1940:                            AR5K_AR5210_SCR_SLE_SLP);
                   1941:                }
                   1942:                staid |= AR5K_AR5210_STA_ID1_PWR_SV;
                   1943:                break;
                   1944:
                   1945:        case HAL_PM_AWAKE:
                   1946:                if (set_chip == AH_FALSE)
                   1947:                        goto commit;
                   1948:
                   1949:                AR5K_REG_WRITE(AR5K_AR5210_SCR, AR5K_AR5210_SCR_SLE_WAKE);
                   1950:
                   1951:                for (i = 5000; i > 0; i--) {
                   1952:                        /* Check if the AR5210 did wake up */
                   1953:                        if ((AR5K_REG_READ(AR5K_AR5210_PCICFG) &
                   1954:                            AR5K_AR5210_PCICFG_SPWR_DN) == 0)
                   1955:                                break;
                   1956:
                   1957:                        /* Wait a bit and retry */
                   1958:                        AR5K_DELAY(200);
                   1959:                        AR5K_REG_WRITE(AR5K_AR5210_SCR,
                   1960:                            AR5K_AR5210_SCR_SLE_WAKE);
                   1961:                }
                   1962:
                   1963:                /* Fail if the AR5210 didn't wake up */
                   1964:                if (i <= 0)
                   1965:                        return (AH_FALSE);
                   1966:
                   1967:                staid &= ~AR5K_AR5210_STA_ID1_PWR_SV;
                   1968:                break;
                   1969:
                   1970:        default:
                   1971:                return (AH_FALSE);
                   1972:        }
                   1973:
                   1974:  commit:
                   1975:        hal->ah_power_mode = mode;
                   1976:
                   1977:        AR5K_REG_WRITE(AR5K_AR5210_STA_ID1, staid);
                   1978:
                   1979:        return (AH_TRUE);
                   1980: }
                   1981:
                   1982: HAL_POWER_MODE
                   1983: ar5k_ar5210_get_power_mode(struct ath_hal *hal)
                   1984: {
                   1985:        return (hal->ah_power_mode);
                   1986: }
                   1987:
                   1988: HAL_BOOL
                   1989: ar5k_ar5210_query_pspoll_support(struct ath_hal *hal)
                   1990: {
                   1991:        /* I think so, why not? */
                   1992:        return (AH_TRUE);
                   1993: }
                   1994:
                   1995: HAL_BOOL
                   1996: ar5k_ar5210_init_pspoll(struct ath_hal *hal)
                   1997: {
                   1998:        /*
                   1999:         * Not used on the AR5210
                   2000:         */
                   2001:        return (AH_FALSE);
                   2002: }
                   2003:
                   2004: HAL_BOOL
                   2005: ar5k_ar5210_enable_pspoll(struct ath_hal *hal, u_int8_t *bssid,
                   2006:     u_int16_t assoc_id)
                   2007: {
                   2008:        AR5K_REG_DISABLE_BITS(AR5K_AR5210_STA_ID1,
                   2009:            AR5K_AR5210_STA_ID1_NO_PSPOLL |
                   2010:            AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA);
                   2011:
                   2012:        return (AH_TRUE);
                   2013: }
                   2014:
                   2015: HAL_BOOL
                   2016: ar5k_ar5210_disable_pspoll(struct ath_hal *hal)
                   2017: {
                   2018:        AR5K_REG_ENABLE_BITS(AR5K_AR5210_STA_ID1,
                   2019:            AR5K_AR5210_STA_ID1_NO_PSPOLL |
                   2020:            AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA);
                   2021:
                   2022:        return (AH_TRUE);
                   2023: }
                   2024:
                   2025: /*
                   2026:  * Beacon functions
                   2027:  */
                   2028:
                   2029: void
                   2030: ar5k_ar5210_init_beacon(struct ath_hal *hal, u_int32_t next_beacon,
                   2031:     u_int32_t interval)
                   2032: {
                   2033:        u_int32_t timer1, timer2, timer3;
                   2034:
                   2035:        /*
                   2036:         * Set the additional timers by mode
                   2037:         */
                   2038:        switch (hal->ah_op_mode) {
                   2039:        case HAL_M_STA:
                   2040:                timer1 = 0xffffffff;
                   2041:                timer2 = 0xffffffff;
                   2042:                timer3 = 1;
                   2043:                break;
                   2044:
                   2045:        default:
                   2046:                timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3;
                   2047:                timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3;
                   2048:                timer3 = next_beacon + hal->ah_atim_window;
                   2049:                break;
                   2050:        }
                   2051:
                   2052:        /*
                   2053:         * Enable all timers and set the beacon register
                   2054:         * (next beacon, DMA beacon, software beacon, ATIM window time)
                   2055:         */
                   2056:        AR5K_REG_WRITE(AR5K_AR5210_TIMER0, next_beacon);
                   2057:        AR5K_REG_WRITE(AR5K_AR5210_TIMER1, timer1);
                   2058:        AR5K_REG_WRITE(AR5K_AR5210_TIMER2, timer2);
                   2059:        AR5K_REG_WRITE(AR5K_AR5210_TIMER3, timer3);
                   2060:
                   2061:        AR5K_REG_WRITE(AR5K_AR5210_BEACON, interval &
                   2062:            (AR5K_AR5210_BEACON_PERIOD | AR5K_AR5210_BEACON_RESET_TSF |
                   2063:                AR5K_AR5210_BEACON_EN));
                   2064: }
                   2065:
                   2066: void
                   2067: ar5k_ar5210_set_beacon_timers(struct ath_hal *hal,
                   2068:     const HAL_BEACON_STATE *state, u_int32_t tsf, u_int32_t dtim_count,
                   2069:     u_int32_t cfp_count)
                   2070: {
                   2071:        u_int32_t cfp_period, next_cfp;
                   2072:
                   2073:        /* Return on an invalid beacon state */
                   2074:        if (state->bs_interval < 1)
                   2075:                return;
                   2076:
                   2077:        /*
                   2078:         * PCF support?
                   2079:         */
                   2080:        if (state->bs_cfp_period > 0) {
                   2081:                /* Enable CFP mode and set the CFP and timer registers */
                   2082:                cfp_period = state->bs_cfp_period * state->bs_dtim_period *
                   2083:                    state->bs_interval;
                   2084:                next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
                   2085:                    state->bs_interval;
                   2086:
                   2087:                AR5K_REG_DISABLE_BITS(AR5K_AR5210_STA_ID1,
                   2088:                    AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA |
                   2089:                    AR5K_AR5210_STA_ID1_PCF);
                   2090:                AR5K_REG_WRITE(AR5K_AR5210_CFP_PERIOD, cfp_period);
                   2091:                AR5K_REG_WRITE(AR5K_AR5210_CFP_DUR, state->bs_cfp_max_duration);
                   2092:                AR5K_REG_WRITE(AR5K_AR5210_TIMER2,
                   2093:                    (tsf + (next_cfp == 0 ? cfp_period : next_cfp)) << 3);
                   2094:        } else {
                   2095:                /* Disable PCF mode */
                   2096:                AR5K_REG_DISABLE_BITS(AR5K_AR5210_STA_ID1,
                   2097:                    AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA |
                   2098:                    AR5K_AR5210_STA_ID1_PCF);
                   2099:        }
                   2100:
                   2101:        /*
                   2102:         * Enable the beacon timer register
                   2103:         */
                   2104:        AR5K_REG_WRITE(AR5K_AR5210_TIMER0, state->bs_next_beacon);
                   2105:
                   2106:        /*
                   2107:         * Start the beacon timers
                   2108:         */
                   2109:        AR5K_REG_WRITE(AR5K_AR5210_BEACON,
                   2110:            (AR5K_REG_READ(AR5K_AR5210_BEACON) &~
                   2111:                (AR5K_AR5210_BEACON_PERIOD | AR5K_AR5210_BEACON_TIM)) |
                   2112:            AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
                   2113:                AR5K_AR5210_BEACON_TIM) |
                   2114:            AR5K_REG_SM(state->bs_interval, AR5K_AR5210_BEACON_PERIOD));
                   2115:
                   2116:        /*
                   2117:         * Write new beacon miss threshold, if it appears to be valid
                   2118:         */
                   2119:        if (state->bs_bmiss_threshold <=
                   2120:            (AR5K_AR5210_RSSI_THR_BM_THR >> AR5K_AR5210_RSSI_THR_BM_THR_S)) {
                   2121:                AR5K_REG_WRITE_BITS(AR5K_AR5210_RSSI_THR,
                   2122:                    AR5K_AR5210_RSSI_THR_BM_THR, state->bs_bmiss_threshold);
                   2123:        }
                   2124: }
                   2125:
                   2126: void
                   2127: ar5k_ar5210_reset_beacon(struct ath_hal *hal)
                   2128: {
                   2129:        /*
                   2130:         * Disable beacon timer
                   2131:         */
                   2132:        AR5K_REG_WRITE(AR5K_AR5210_TIMER0, 0);
                   2133:
                   2134:        /*
                   2135:         * Disable some beacon register values
                   2136:         */
                   2137:        AR5K_REG_DISABLE_BITS(AR5K_AR5210_STA_ID1,
                   2138:            AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA | AR5K_AR5210_STA_ID1_PCF);
                   2139:        AR5K_REG_WRITE(AR5K_AR5210_BEACON, AR5K_AR5210_BEACON_PERIOD);
                   2140: }
                   2141:
                   2142: HAL_BOOL
                   2143: ar5k_ar5210_wait_for_beacon(struct ath_hal *hal, bus_addr_t phys_addr)
                   2144: {
                   2145:        int i;
                   2146:
                   2147:        /*
                   2148:         * Wait for beaconn queue to be done
                   2149:         */
                   2150:        for (i = (AR5K_TUNE_BEACON_INTERVAL / 2); i > 0 &&
                   2151:                 (AR5K_REG_READ(AR5K_AR5210_BSR) &
                   2152:                     AR5K_AR5210_BSR_TXQ1F) != 0 &&
                   2153:                 (AR5K_REG_READ(AR5K_AR5210_CR) &
                   2154:                     AR5K_AR5210_CR_TXE1) != 0; i--);
                   2155:
                   2156:        /* Timeout... */
                   2157:        if (i <= 0) {
                   2158:                /*
                   2159:                 * Re-schedule the beacon queue
                   2160:                 */
                   2161:                AR5K_REG_WRITE(AR5K_AR5210_TXDP1, (u_int32_t)phys_addr);
                   2162:                AR5K_REG_WRITE(AR5K_AR5210_BCR,
                   2163:                    AR5K_AR5210_BCR_TQ1V | AR5K_AR5210_BCR_BDMAE);
                   2164:
                   2165:                return (AH_FALSE);
                   2166:        }
                   2167:
                   2168:        return (AH_TRUE);
                   2169: }
                   2170:
                   2171: /*
                   2172:  * Interrupt handling
                   2173:  */
                   2174:
                   2175: HAL_BOOL
                   2176: ar5k_ar5210_is_intr_pending(struct ath_hal *hal)
                   2177: {
                   2178:        return (AR5K_REG_READ(AR5K_AR5210_INTPEND) == 0 ? AH_FALSE : AH_TRUE);
                   2179: }
                   2180:
                   2181: HAL_BOOL
                   2182: ar5k_ar5210_get_isr(struct ath_hal *hal, u_int32_t *interrupt_mask)
                   2183: {
                   2184:        u_int32_t data;
                   2185:
                   2186:        if ((data = AR5K_REG_READ(AR5K_AR5210_ISR)) == HAL_INT_NOCARD) {
                   2187:                *interrupt_mask = data;
                   2188:                return (AH_FALSE);
                   2189:        }
                   2190:
                   2191:        /*
                   2192:         * Get abstract interrupt mask (HAL-compatible)
                   2193:         */
                   2194:        *interrupt_mask = (data & HAL_INT_COMMON) & hal->ah_imr;
                   2195:
                   2196:        if (data & (AR5K_AR5210_ISR_RXOK | AR5K_AR5210_ISR_RXERR))
                   2197:                *interrupt_mask |= HAL_INT_RX;
                   2198:        if (data & (AR5K_AR5210_ISR_TXOK | AR5K_AR5210_ISR_TXERR))
                   2199:                *interrupt_mask |= HAL_INT_TX;
                   2200:        if (data & AR5K_AR5210_ISR_FATAL)
                   2201:                *interrupt_mask |= HAL_INT_FATAL;
                   2202:
                   2203:        /*
                   2204:         * Special interrupt handling (not caught by the driver)
                   2205:         */
                   2206:        if (((*interrupt_mask) & AR5K_AR5210_ISR_RXPHY) &&
                   2207:            hal->ah_radar.r_enabled == AH_TRUE)
                   2208:                ar5k_radar_alert(hal);
                   2209:
                   2210:        /* XXX BMISS interrupts may occur after association */
                   2211:        *interrupt_mask &= ~HAL_INT_BMISS;
                   2212:
                   2213:        return (AH_TRUE);
                   2214: }
                   2215:
                   2216: u_int32_t
                   2217: ar5k_ar5210_get_intr(struct ath_hal *hal)
                   2218: {
                   2219:        /* Return the interrupt mask stored previously */
                   2220:        return (hal->ah_imr);
                   2221: }
                   2222:
                   2223: HAL_INT
                   2224: ar5k_ar5210_set_intr(struct ath_hal *hal, HAL_INT new_mask)
                   2225: {
                   2226:        HAL_INT old_mask, int_mask;
                   2227:
                   2228:        /*
                   2229:         * Disable card interrupts to prevent any race conditions
                   2230:         * (they will be re-enabled afterwards).
                   2231:         */
                   2232:        AR5K_REG_WRITE(AR5K_AR5210_IER, AR5K_AR5210_IER_DISABLE);
                   2233:
                   2234:        old_mask = hal->ah_imr;
                   2235:
                   2236:        /*
                   2237:         * Add additional, chipset-dependent interrupt mask flags
                   2238:         * and write them to the IMR (interrupt mask register).
                   2239:         */
                   2240:        int_mask = new_mask & HAL_INT_COMMON;
                   2241:
                   2242:        if (new_mask & HAL_INT_RX)
                   2243:                int_mask |=
                   2244:                    AR5K_AR5210_IMR_RXOK |
                   2245:                    AR5K_AR5210_IMR_RXERR |
                   2246:                    AR5K_AR5210_IMR_RXORN;
                   2247:
                   2248:        if (new_mask & HAL_INT_TX)
                   2249:                int_mask |=
                   2250:                    AR5K_AR5210_IMR_TXOK |
                   2251:                    AR5K_AR5210_IMR_TXERR |
                   2252:                    AR5K_AR5210_IMR_TXURN;
                   2253:
                   2254:        AR5K_REG_WRITE(AR5K_AR5210_IMR, int_mask);
                   2255:
                   2256:        /* Store new interrupt mask */
                   2257:        hal->ah_imr = new_mask;
                   2258:
                   2259:        /* ..re-enable interrupts */
                   2260:        if (int_mask) {
                   2261:                AR5K_REG_WRITE(AR5K_AR5210_IER, AR5K_AR5210_IER_ENABLE);
                   2262:        }
                   2263:
                   2264:        return (old_mask);
                   2265: }
                   2266:
                   2267: /*
                   2268:  * Misc internal functions
                   2269:  */
                   2270:
                   2271: HAL_BOOL
                   2272: ar5k_ar5210_get_capabilities(struct ath_hal *hal)
                   2273: {
                   2274:        /* Set number of supported TX queues */
                   2275:        hal->ah_capabilities.cap_queues.q_tx_num = AR5K_AR5210_TX_NUM_QUEUES;
                   2276:
                   2277:        /*
                   2278:         * Set radio capabilities
                   2279:         * (The AR5210 only supports the middle 5GHz band)
                   2280:         */
                   2281:        hal->ah_capabilities.cap_range.range_5ghz_min = 5120;
                   2282:        hal->ah_capabilities.cap_range.range_5ghz_max = 5430;
                   2283:        hal->ah_capabilities.cap_range.range_2ghz_min = 0;
                   2284:        hal->ah_capabilities.cap_range.range_2ghz_max = 0;
                   2285:
                   2286:        /* Set supported modes */
                   2287:        hal->ah_capabilities.cap_mode = HAL_MODE_11A | HAL_MODE_TURBO;
                   2288:
                   2289:        /* Set number of GPIO pins */
                   2290:        hal->ah_gpio_npins = AR5K_AR5210_NUM_GPIO;
                   2291:
                   2292:        return (AH_TRUE);
                   2293: }
                   2294:
                   2295: void
                   2296: ar5k_ar5210_radar_alert(struct ath_hal *hal, HAL_BOOL enable)
                   2297: {
                   2298:        /*
                   2299:         * Set the RXPHY interrupt to be able to detect
                   2300:         * possible radar activity.
                   2301:         */
                   2302:        AR5K_REG_WRITE(AR5K_AR5210_IER, AR5K_AR5210_IER_DISABLE);
                   2303:
                   2304:        if (enable == AH_TRUE) {
                   2305:                AR5K_REG_ENABLE_BITS(AR5K_AR5210_IMR,
                   2306:                    AR5K_AR5210_IMR_RXPHY);
                   2307:        } else {
                   2308:                AR5K_REG_DISABLE_BITS(AR5K_AR5210_IMR,
                   2309:                    AR5K_AR5210_IMR_RXPHY);
                   2310:        }
                   2311:
                   2312:        AR5K_REG_WRITE(AR5K_AR5210_IER, AR5K_AR5210_IER_ENABLE);
                   2313: }
                   2314:
                   2315: /*
                   2316:  * EEPROM access functions
                   2317:  */
                   2318:
                   2319: HAL_BOOL
                   2320: ar5k_ar5210_eeprom_is_busy(struct ath_hal *hal)
                   2321: {
                   2322:        return (AR5K_REG_READ(AR5K_AR5210_CFG) & AR5K_AR5210_CFG_EEBS ?
                   2323:            AH_TRUE : AH_FALSE);
                   2324: }
                   2325:
                   2326: int
                   2327: ar5k_ar5210_eeprom_read(struct ath_hal *hal, u_int32_t offset, u_int16_t *data)
                   2328: {
                   2329:        u_int32_t status, timeout;
                   2330:
                   2331:        /* Enable eeprom access */
                   2332:        AR5K_REG_ENABLE_BITS(AR5K_AR5210_PCICFG, AR5K_AR5210_PCICFG_EEAE);
                   2333:
                   2334:        /*
                   2335:         * Prime read pump
                   2336:         */
                   2337:        (void)AR5K_REG_READ(AR5K_AR5210_EEPROM_BASE + (4 * offset));
                   2338:
                   2339:        for (timeout = 10000; timeout > 0; timeout--) {
                   2340:                AR5K_DELAY(1);
                   2341:                status = AR5K_REG_READ(AR5K_AR5210_EEPROM_STATUS);
                   2342:                if (status & AR5K_AR5210_EEPROM_STAT_RDDONE) {
                   2343:                        if (status & AR5K_AR5210_EEPROM_STAT_RDERR)
                   2344:                                return (EIO);
                   2345:                        *data = (u_int16_t)
                   2346:                            (AR5K_REG_READ(AR5K_AR5210_EEPROM_RDATA) & 0xffff);
                   2347:                        return (0);
                   2348:                }
                   2349:        }
                   2350:
                   2351:        return (ETIMEDOUT);
                   2352: }
                   2353:
                   2354: int
                   2355: ar5k_ar5210_eeprom_write(struct ath_hal *hal, u_int32_t offset, u_int16_t data)
                   2356: {
                   2357:        u_int32_t status, timeout;
                   2358:
                   2359:        /* Enable eeprom access */
                   2360:        AR5K_REG_ENABLE_BITS(AR5K_AR5210_PCICFG, AR5K_AR5210_PCICFG_EEAE);
                   2361:
                   2362:        /*
                   2363:         * Prime write pump
                   2364:         */
                   2365:        AR5K_REG_WRITE(AR5K_AR5210_EEPROM_BASE + (4 * offset), data);
                   2366:
                   2367:        for (timeout = 10000; timeout > 0; timeout--) {
                   2368:                AR5K_DELAY(1);
                   2369:                status = AR5K_REG_READ(AR5K_AR5210_EEPROM_STATUS);
                   2370:                if (status & AR5K_AR5210_EEPROM_STAT_WRDONE) {
                   2371:                        if (status & AR5K_AR5210_EEPROM_STAT_WRERR)
                   2372:                                return (EIO);
                   2373:                        return (0);
                   2374:                }
                   2375:        }
                   2376:
                   2377:        return (ETIMEDOUT);
                   2378: }
                   2379:
                   2380: HAL_BOOL
                   2381: ar5k_ar5210_set_txpower_limit(struct ath_hal *hal, u_int power)
                   2382: {
                   2383:        /* Not implemented */
                   2384:        return (AH_FALSE);
                   2385: }

CVSweb