Author: mick Date: 2006-04-13 05:55:56 +0200 (Thu, 13 Apr 2006) New Revision: 117 Modified: KisMACng/Subprojects/AtheroJack/OpenHAL/OpenHAL.cpp KisMACng/Subprojects/AtheroJack/OpenHAL/OpenHAL5212.cpp Log: * reordering some HAL functions (this is a patch by beat zahnd) Modified: KisMACng/Subprojects/AtheroJack/OpenHAL/OpenHAL.cpp =================================================================== --- KisMACng/Subprojects/AtheroJack/OpenHAL/OpenHAL.cpp 2006-04-10 06:45:20 UTC (rev 116) +++ KisMACng/Subprojects/AtheroJack/OpenHAL/OpenHAL.cpp 2006-04-13 03:55:56 UTC (rev 117) @@ -12,6 +12,11 @@ OSDefineMetaClassAndStructors(OpenHAL, OSObject); +bool OpenHAL::init() { + ah_rf_banks = NULL; + return true; +} + /* * Supported channels */ @@ -37,11 +42,6 @@ #pragma mark - -bool OpenHAL::init() { - ah_rf_banks = NULL; - return true; -} - //implementation bool OpenHAL::ath_hal_attach(u_int16_t device, void *sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status) { @@ -224,38 +224,6 @@ return (value); } -HAL_BOOL OpenHAL::ar5k_check_channel(u_int16_t freq, u_int flags) { - /* Check if the channel is in our supported range */ - if (flags & IEEE80211_CHAN_2GHZ) { - if ((freq >= ah_capabilities.cap_range.range_2ghz_min) && - (freq <= ah_capabilities.cap_range.range_2ghz_max)) - return (AH_TRUE); - } else if (flags & IEEE80211_CHAN_5GHZ) { - if ((freq >= ah_capabilities.cap_range.range_5ghz_min) && - (freq <= ah_capabilities.cap_range.range_5ghz_max)) - return (AH_TRUE); - } - - return (AH_FALSE); -} - -u_int32_t OpenHAL::ieee80211_regdomain2flag(u_int16_t regdomain, u_int16_t mhz) { - int i; - - for(i = 0; i < (sizeof(ieee80211_r_map) / - sizeof(ieee80211_r_map[0])); i++) { - if(ieee80211_r_map[i].rm_domain == regdomain) { - if(mhz >= 2000 && mhz <= 3000) - return((u_int32_t)ieee80211_r_map[i].rm_domain_2ghz); - if(mhz >= IEEE80211_CHANNELS_5GHZ_MIN && - mhz <= IEEE80211_CHANNELS_5GHZ_MAX) - return((u_int32_t)ieee80211_r_map[i].rm_domain_5ghz); - } - } - - return((u_int32_t)DMN_DEBUG); -} - /* * Convert MHz frequency to IEEE channel number. */ @@ -304,6 +272,21 @@ } } +HAL_BOOL OpenHAL::ar5k_check_channel(u_int16_t freq, u_int flags) { + /* Check if the channel is in our supported range */ + if (flags & IEEE80211_CHAN_2GHZ) { + if ((freq >= ah_capabilities.cap_range.range_2ghz_min) && + (freq <= ah_capabilities.cap_range.range_2ghz_max)) + return (AH_TRUE); + } else if (flags & IEEE80211_CHAN_5GHZ) { + if ((freq >= ah_capabilities.cap_range.range_5ghz_min) && + (freq <= ah_capabilities.cap_range.range_5ghz_max)) + return (AH_TRUE); + } + + return (AH_FALSE); +} + HAL_BOOL OpenHAL::ath_hal_init_channels(HAL_CHANNEL *channels, u_int max_channels, u_int *channels_size, HAL_CTRY_CODE country, u_int16_t mode, HAL_BOOL outdoor, HAL_BOOL extended) { u_int i, c; u_int32_t domain_current; @@ -423,64 +406,243 @@ return (AH_TRUE); } + #pragma mark - -HAL_STATUS OpenHAL::ar5k_eeprom_read_mac(u_int8_t *mac) { - u_int32_t total, offset; - u_int16_t data; - int octet; - u_int8_t mac_d[IEEE80211_ADDR_LEN]; +u_int16_t OpenHAL::ar5k_regdomain_from_ieee(ieee80211_regdomain_t ieee) { + u_int32_t regdomain = (u_int32_t)ieee; - bzero(mac, IEEE80211_ADDR_LEN); - bzero(&mac_d, IEEE80211_ADDR_LEN); + if (regdomain & 0xf0000000) + return ((u_int16_t)AR5K_TUNE_REGDOMAIN); - if (nic_eeprom_is_busy()) - return (HAL_EELOCKED); + return (regdomain & 0xff); +} - if (nic_eeprom_read(0x20, &data) != 0) - return (HAL_EIO); +ieee80211_regdomain_t OpenHAL::ar5k_regdomain_to_ieee(u_int16_t regdomain) { + ieee80211_regdomain_t ieee = (ieee80211_regdomain_t)regdomain & 0xff; + return (ieee); +} - for (offset = 0x1f, octet = 0, total = 0; - offset >= 0x1d; offset--) { - if (nic_eeprom_read(offset, &data) != 0) - return (HAL_EIO); - total += data; - mac_d[octet + 1] = data & 0xff; - mac_d[octet] = data >> 8; - octet += 2; +u_int16_t OpenHAL::ar5k_get_regdomain() { +#ifndef COUNTRYCODE + /* + * Use the regulation domain found in the EEPROM, if not + * forced by a static country code. + */ + u_int16_t regdomain; + ieee80211_regdomain_t ieee_regdomain; + + if (ar5k_eeprom_regulation_domain(AH_FALSE, &ieee_regdomain) == AH_TRUE) { + if ((regdomain = ar5k_regdomain_from_ieee(ieee_regdomain))) + return (regdomain); } - bcopy(mac_d, mac, IEEE80211_ADDR_LEN); + return (ah_regdomain); +#else + /* + * Get the regulation domain by country code. This will ignore + * the settings found in the EEPROM. + */ + u_int16_t code; - if ((!total) || total == (3 * 0xffff)) - return (HAL_EINVAL); + code = ieee80211_name2countrycode(COUNTRYCODE); + return (ieee80211_countrycode2regdomain(code)); +#endif +} - return (HAL_OK); +u_int32_t OpenHAL::ar5k_bitswap(u_int32_t val, u_int bits) { + u_int32_t retval = 0, bit, i; + + for (i = 0; i < bits; i++) { + bit = (val >> i) & 1; + retval = (retval << 1) | bit; + } + + return (retval); } -int OpenHAL::ar5k_check_eeprom() { - u_int32_t addr; - u_int16_t data[0x400], chksum = 0; +void OpenHAL::ar5k_rt_copy(HAL_RATE_TABLE *dst, HAL_RATE_TABLE *src) { + bzero(dst, sizeof(HAL_RATE_TABLE)); + dst->rateCount = src->rateCount; + bcopy(src->info, dst->info, sizeof(dst->info)); +} + +HAL_BOOL OpenHAL::ar5k_register_timeout(u_int32_t reg, u_int32_t flag, u_int32_t val, HAL_BOOL is_set) { + int i; + u_int32_t data; + + for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) { + data = AR5K_REG_READ(reg); + if ((is_set == AH_TRUE) && (data & flag)) + break; + else if ((data & flag) == val) + break; + AR5K_DELAY(15); + } + + if (i <= 0) + return (AH_FALSE); + + return (AH_TRUE); +} + +#pragma mark - + +u_int16_t OpenHAL::ar5k_eeprom_bin2freq(u_int16_t bin, u_int mode) { + u_int16_t val; + + if (bin == AR5K_EEPROM_CHANNEL_DIS) + return (bin); + + if (mode == AR5K_EEPROM_MODE_11A) { + if (ah_ee_version > AR5K_EEPROM_VERSION_3_2) + val = (5 * bin) + 4800; + else + val = bin > 62 ? + (10 * 62) + (5 * (bin - 62)) + 5100 : + (bin * 10) + 5100; + } else { + if (ah_ee_version > AR5K_EEPROM_VERSION_3_2) + val = bin + 2300; + else + val = bin + 2400; + } + + return (val); +} + +int OpenHAL::ar5k_eeprom_read_ants(u_int32_t *offset, u_int mode) { + struct ar5k_eeprom_info *ee = &ah_capabilities.cap_eeprom; + u_int32_t o = *offset; + u_int16_t val; + int ret, i = 0; + + AR5K_EEPROM_READ(o++, val); + ee->ee_switch_settling[mode] = (val >> 8) & 0x7f; + ee->ee_ant_tx_rx[mode] = (val >> 2) & 0x3f; + ee->ee_ant_control[mode][i] = (val << 4) & 0x3f; + + AR5K_EEPROM_READ(o++, val); + ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf; + ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f; + ee->ee_ant_control[mode][i++] = val & 0x3f; + + AR5K_EEPROM_READ(o++, val); + ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f; + ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f; + ee->ee_ant_control[mode][i] = (val << 2) & 0x3f; + + AR5K_EEPROM_READ(o++, val); + ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3; + ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f; + ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f; + ee->ee_ant_control[mode][i] = (val << 4) & 0x3f; + + AR5K_EEPROM_READ(o++, val); + ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf; + ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f; + ee->ee_ant_control[mode][i++] = val & 0x3f; + + /* Get antenna modes */ + ah_antenna[mode][0] = + (ee->ee_ant_control[mode][0] << 4) | 0x1; + ah_antenna[mode][HAL_ANT_FIXED_A] = + ee->ee_ant_control[mode][1] | + (ee->ee_ant_control[mode][2] << 6) | + (ee->ee_ant_control[mode][3] << 12) | + (ee->ee_ant_control[mode][4] << 18) | + (ee->ee_ant_control[mode][5] << 24); + ah_antenna[mode][HAL_ANT_FIXED_B] = + ee->ee_ant_control[mode][6] | + (ee->ee_ant_control[mode][7] << 6) | + (ee->ee_ant_control[mode][8] << 12) | + (ee->ee_ant_control[mode][9] << 18) | + (ee->ee_ant_control[mode][10] << 24); + + /* return new offset */ + *offset = o; + + return (0); +} + +int OpenHAL::ar5k_eeprom_read_modes(u_int32_t *offset, u_int mode) { + struct ar5k_eeprom_info *ee = &ah_capabilities.cap_eeprom; + u_int32_t o = *offset; + u_int16_t val; int ret; - - for (addr = 0; addr < AR5K_EEPROM_INFO_BASE + AR5K_EEPROM_INFO_MAX; addr++) { - AR5K_EEPROM_READ(addr, data[addr]); - if (addr >= AR5K_EEPROM_INFO_BASE) chksum ^= data[addr]; - } - /*for (addr = 0; addr < AR5K_EEPROM_INFO_BASE + AR5K_EEPROM_INFO_MAX; addr+=16) { - IOLog("0x%04x %04x%04x%04x%04x %04x%04x%04x%04x %04x%04x%04x%04x %04x%04x%04x%04x\n", addr, data[addr], data[addr + 1], data[addr + 2], data[addr + 3], data[addr + 4], data[addr + 5], data[addr + 6], data[addr + 7], data[addr + 8], data[addr + 9], data[addr + 10], data[addr + 11], data[addr + 12], data[addr + 13], data[addr + 14], data[addr + 15]); - IOSleep(100); - }*/ + AR5K_EEPROM_READ(o++, val); + ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff; + ee->ee_thr_62[mode] = val & 0xff; + if (ah_ee_version <= AR5K_EEPROM_VERSION_3_2) + ee->ee_thr_62[mode] = + mode == AR5K_EEPROM_MODE_11A ? 15 : 28; - if (chksum != 0xffff) { - AR5K_PRINTF("Checksum 0x%04x != 0xffff\n", chksum); - return HAL_EEBADSUM; - } + AR5K_EEPROM_READ(o++, val); + ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff; + ee->ee_tx_frm2xpa_enable[mode] = val & 0xff; - return HAL_OK; + AR5K_EEPROM_READ(o++, val); + ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff; + + if ((val & 0xff) & 0x80) + ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1); + else + ee->ee_noise_floor_thr[mode] = val & 0xff; + + if (ah_ee_version <= AR5K_EEPROM_VERSION_3_2) + ee->ee_noise_floor_thr[mode] = + mode == AR5K_EEPROM_MODE_11A ? -54 : -1; + + AR5K_EEPROM_READ(o++, val); + ee->ee_xlna_gain[mode] = (val >> 5) & 0xff; + ee->ee_x_gain[mode] = (val >> 1) & 0xf; + ee->ee_xpd[mode] = val & 0x1; + + if (ah_ee_version >= AR5K_EEPROM_VERSION_4_0) + ee->ee_fixed_bias[mode] = (val >> 13) & 0x1; + + if (ah_ee_version >= AR5K_EEPROM_VERSION_3_3) { + AR5K_EEPROM_READ(o++, val); + ee->ee_false_detect[mode] = (val >> 6) & 0x7f; + + if (mode == AR5K_EEPROM_MODE_11A) + ee->ee_xr_power[mode] = val & 0x3f; + else { + ee->ee_ob[mode][0] = val & 0x7; + ee->ee_db[mode][0] = (val >> 3) & 0x7; + } + } + + if (ah_ee_version < AR5K_EEPROM_VERSION_3_4) { + ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN; + ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA; + } else { + ee->ee_i_gain[mode] = (val >> 13) & 0x7; + + AR5K_EEPROM_READ(o++, val); + ee->ee_i_gain[mode] |= (val << 3) & 0x38; + + if (mode == AR5K_EEPROM_MODE_11G) + ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff; + } + + if (ah_ee_version >= AR5K_EEPROM_VERSION_4_0 && + mode == AR5K_EEPROM_MODE_11A) { + ee->ee_i_cal[mode] = (val >> 8) & 0x3f; + ee->ee_q_cal[mode] = (val >> 3) & 0x1f; + } + + if (ah_ee_version >= AR5K_EEPROM_VERSION_4_6 && + mode == AR5K_EEPROM_MODE_11G) + ee->ee_scaled_cck_delta = (val >> 11) & 0x1f; + + /* return new offset */ + *offset = o; + + return (0); } int OpenHAL::ar5k_eeprom_init() { @@ -674,6 +836,40 @@ return (0); } +HAL_STATUS OpenHAL::ar5k_eeprom_read_mac(u_int8_t *mac) { + u_int32_t total, offset; + u_int16_t data; + int octet; + u_int8_t mac_d[IEEE80211_ADDR_LEN]; + + bzero(mac, IEEE80211_ADDR_LEN); + bzero(&mac_d, IEEE80211_ADDR_LEN); + + if (nic_eeprom_is_busy()) + return (HAL_EELOCKED); + + if (nic_eeprom_read(0x20, &data) != 0) + return (HAL_EIO); + + for (offset = 0x1f, octet = 0, total = 0; + offset >= 0x1d; offset--) { + if (nic_eeprom_read(offset, &data) != 0) + return (HAL_EIO); + + total += data; + mac_d[octet + 1] = data & 0xff; + mac_d[octet] = data >> 8; + octet += 2; + } + + bcopy(mac_d, mac, IEEE80211_ADDR_LEN); + + if ((!total) || total == (3 * 0xffff)) + return (HAL_EINVAL); + + return (HAL_OK); +} + HAL_BOOL OpenHAL::ar5k_eeprom_regulation_domain(HAL_BOOL write, ieee80211_regdomain_t *regdomain) { /* Read current value */ @@ -699,245 +895,32 @@ return (AH_TRUE); } -u_int16_t OpenHAL::ar5k_eeprom_bin2freq(u_int16_t bin, u_int mode) { - u_int16_t val; - - if (bin == AR5K_EEPROM_CHANNEL_DIS) - return (bin); - - if (mode == AR5K_EEPROM_MODE_11A) { - if (ah_ee_version > AR5K_EEPROM_VERSION_3_2) - val = (5 * bin) + 4800; - else - val = bin > 62 ? - (10 * 62) + (5 * (bin - 62)) + 5100 : - (bin * 10) + 5100; - } else { - if (ah_ee_version > AR5K_EEPROM_VERSION_3_2) - val = bin + 2300; - else - val = bin + 2400; - } - - return (val); -} - -int OpenHAL::ar5k_eeprom_read_ants(u_int32_t *offset, u_int mode) { - struct ar5k_eeprom_info *ee = &ah_capabilities.cap_eeprom; - u_int32_t o = *offset; - u_int16_t val; - int ret, i = 0; - - AR5K_EEPROM_READ(o++, val); - ee->ee_switch_settling[mode] = (val >> 8) & 0x7f; - ee->ee_ant_tx_rx[mode] = (val >> 2) & 0x3f; - ee->ee_ant_control[mode][i] = (val << 4) & 0x3f; - - AR5K_EEPROM_READ(o++, val); - ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf; - ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f; - ee->ee_ant_control[mode][i++] = val & 0x3f; - - AR5K_EEPROM_READ(o++, val); - ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f; - ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f; - ee->ee_ant_control[mode][i] = (val << 2) & 0x3f; - - AR5K_EEPROM_READ(o++, val); - ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3; - ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f; - ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f; - ee->ee_ant_control[mode][i] = (val << 4) & 0x3f; - - AR5K_EEPROM_READ(o++, val); - ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf; - ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f; - ee->ee_ant_control[mode][i++] = val & 0x3f; - - /* Get antenna modes */ - ah_antenna[mode][0] = - (ee->ee_ant_control[mode][0] << 4) | 0x1; - ah_antenna[mode][HAL_ANT_FIXED_A] = - ee->ee_ant_control[mode][1] | - (ee->ee_ant_control[mode][2] << 6) | - (ee->ee_ant_control[mode][3] << 12) | - (ee->ee_ant_control[mode][4] << 18) | - (ee->ee_ant_control[mode][5] << 24); - ah_antenna[mode][HAL_ANT_FIXED_B] = - ee->ee_ant_control[mode][6] | - (ee->ee_ant_control[mode][7] << 6) | - (ee->ee_ant_control[mode][8] << 12) | - (ee->ee_ant_control[mode][9] << 18) | - (ee->ee_ant_control[mode][10] << 24); - - /* return new offset */ - *offset = o; - - return (0); -} - -int OpenHAL::ar5k_eeprom_read_modes(u_int32_t *offset, u_int mode) { - struct ar5k_eeprom_info *ee = &ah_capabilities.cap_eeprom; - u_int32_t o = *offset; - u_int16_t val; +int OpenHAL::ar5k_check_eeprom() { + u_int32_t addr; + u_int16_t data[0x400], chksum = 0; int ret; + + for (addr = 0; addr < AR5K_EEPROM_INFO_BASE + AR5K_EEPROM_INFO_MAX; addr++) { + AR5K_EEPROM_READ(addr, data[addr]); + if (addr >= AR5K_EEPROM_INFO_BASE) chksum ^= data[addr]; + } - AR5K_EEPROM_READ(o++, val); - ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff; - ee->ee_thr_62[mode] = val & 0xff; + /*for (addr = 0; addr < AR5K_EEPROM_INFO_BASE + AR5K_EEPROM_INFO_MAX; addr+=16) { + IOLog("0x%04x %04x%04x%04x%04x %04x%04x%04x%04x %04x%04x%04x%04x %04x%04x%04x%04x\n", addr, data[addr], data[addr + 1], data[addr + 2], data[addr + 3], data[addr + 4], data[addr + 5], data[addr + 6], data[addr + 7], data[addr + 8], data[addr + 9], data[addr + 10], data[addr + 11], data[addr + 12], data[addr + 13], data[addr + 14], data[addr + 15]); + IOSleep(100); + }*/ - if (ah_ee_version <= AR5K_EEPROM_VERSION_3_2) - ee->ee_thr_62[mode] = - mode == AR5K_EEPROM_MODE_11A ? 15 : 28; - AR5K_EEPROM_READ(o++, val); - ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff; - ee->ee_tx_frm2xpa_enable[mode] = val & 0xff; + if (chksum != 0xffff) { + AR5K_PRINTF("Checksum 0x%04x != 0xffff\n", chksum); + return HAL_EEBADSUM; + } - AR5K_EEPROM_READ(o++, val); - ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff; - - if ((val & 0xff) & 0x80) - ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1); - else - ee->ee_noise_floor_thr[mode] = val & 0xff; - - if (ah_ee_version <= AR5K_EEPROM_VERSION_3_2) - ee->ee_noise_floor_thr[mode] = - mode == AR5K_EEPROM_MODE_11A ? -54 : -1; - - AR5K_EEPROM_READ(o++, val); - ee->ee_xlna_gain[mode] = (val >> 5) & 0xff; - ee->ee_x_gain[mode] = (val >> 1) & 0xf; - ee->ee_xpd[mode] = val & 0x1; - - if (ah_ee_version >= AR5K_EEPROM_VERSION_4_0) - ee->ee_fixed_bias[mode] = (val >> 13) & 0x1; - - if (ah_ee_version >= AR5K_EEPROM_VERSION_3_3) { - AR5K_EEPROM_READ(o++, val); - ee->ee_false_detect[mode] = (val >> 6) & 0x7f; - - if (mode == AR5K_EEPROM_MODE_11A) - ee->ee_xr_power[mode] = val & 0x3f; - else { - ee->ee_ob[mode][0] = val & 0x7; - ee->ee_db[mode][0] = (val >> 3) & 0x7; - } - } - - if (ah_ee_version < AR5K_EEPROM_VERSION_3_4) { - ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN; - ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA; - } else { - ee->ee_i_gain[mode] = (val >> 13) & 0x7; - - AR5K_EEPROM_READ(o++, val); - ee->ee_i_gain[mode] |= (val << 3) & 0x38; - - if (mode == AR5K_EEPROM_MODE_11G) - ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff; - } - - if (ah_ee_version >= AR5K_EEPROM_VERSION_4_0 && - mode == AR5K_EEPROM_MODE_11A) { - ee->ee_i_cal[mode] = (val >> 8) & 0x3f; - ee->ee_q_cal[mode] = (val >> 3) & 0x1f; - } - - if (ah_ee_version >= AR5K_EEPROM_VERSION_4_6 && - mode == AR5K_EEPROM_MODE_11G) - ee->ee_scaled_cck_delta = (val >> 11) & 0x1f; - - /* return new offset */ - *offset = o; - - return (0); + return HAL_OK; } #pragma mark - -void OpenHAL::ar5k_rt_copy(HAL_RATE_TABLE *dst, HAL_RATE_TABLE *src) { - bzero(dst, sizeof(HAL_RATE_TABLE)); - dst->rateCount = src->rateCount; - bcopy(src->info, dst->info, sizeof(dst->info)); -} - -HAL_BOOL OpenHAL::ar5k_register_timeout(u_int32_t reg, u_int32_t flag, u_int32_t val, HAL_BOOL is_set) { - int i; - u_int32_t data; - - for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) { - data = AR5K_REG_READ(reg); - if ((is_set == AH_TRUE) && (data & flag)) - break; - else if ((data & flag) == val) - break; - AR5K_DELAY(15); - } - - if (i <= 0) - return (AH_FALSE); - - return (AH_TRUE); -} - - -ieee80211_regdomain_t OpenHAL::ar5k_regdomain_to_ieee(u_int16_t regdomain) { - ieee80211_regdomain_t ieee = (ieee80211_regdomain_t)regdomain & 0xff; - return (ieee); -} - - -u_int16_t OpenHAL::ar5k_regdomain_from_ieee(ieee80211_regdomain_t ieee) { - u_int32_t regdomain = (u_int32_t)ieee; - - if (regdomain & 0xf0000000) - return ((u_int16_t)AR5K_TUNE_REGDOMAIN); - - return (regdomain & 0xff); -} - -u_int16_t OpenHAL::ar5k_get_regdomain() { -#ifndef COUNTRYCODE - /* - * Use the regulation domain found in the EEPROM, if not - * forced by a static country code. - */ - u_int16_t regdomain; - ieee80211_regdomain_t ieee_regdomain; - - if (ar5k_eeprom_regulation_domain(AH_FALSE, &ieee_regdomain) == AH_TRUE) { - if ((regdomain = ar5k_regdomain_from_ieee(ieee_regdomain))) - return (regdomain); - } - - return (ah_regdomain); -#else - /* - * Get the regulation domain by country code. This will ignore - * the settings found in the EEPROM. - */ - u_int16_t code; - - code = ieee80211_name2countrycode(COUNTRYCODE); - return (ieee80211_countrycode2regdomain(code)); -#endif -} - -u_int32_t OpenHAL::ar5k_bitswap(u_int32_t val, u_int bits) { - u_int32_t retval = 0, bit, i; - - for (i = 0; i < bits; i++) { - bit = (val >> i) & 1; - retval = (retval << 1) | bit; - } - - return (retval); -} - -#pragma mark - - HAL_BOOL OpenHAL::ar5k_channel(HAL_CHANNEL *channel) { HAL_BOOL ret; @@ -970,8 +953,6 @@ return (AH_TRUE); } -#pragma mark - - u_int OpenHAL::ar5k_rfregs_op(u_int32_t *rf, u_int32_t offset, u_int32_t reg, u_int32_t bits, u_int32_t first, u_int32_t col, HAL_BOOL set) { u_int32_t mask, entry, last, data, shift, position; int32_t left; @@ -1378,6 +1359,8 @@ return (AH_TRUE); } +#pragma mark - + void OpenHAL::ar5k_txpower_table(HAL_CHANNEL *channel, int16_t max_power) { u_int16_t txpower, *rates; int i; @@ -1403,3 +1386,21 @@ ah_txpower.txp_pcdac[i] = AR5K_EEPROM_PCDAC_START; } +#pragma mark - + +u_int32_t OpenHAL::ieee80211_regdomain2flag(u_int16_t regdomain, u_int16_t mhz) { + int i; + + for(i = 0; i < (sizeof(ieee80211_r_map) / + sizeof(ieee80211_r_map[0])); i++) { + if(ieee80211_r_map[i].rm_domain == regdomain) { + if(mhz >= 2000 && mhz <= 3000) + return((u_int32_t)ieee80211_r_map[i].rm_domain_2ghz); + if(mhz >= IEEE80211_CHANNELS_5GHZ_MIN && + mhz <= IEEE80211_CHANNELS_5GHZ_MAX) + return((u_int32_t)ieee80211_r_map[i].rm_domain_5ghz); + } + } + + return((u_int32_t)DMN_DEBUG); +} \ No newline at end of file Modified: KisMACng/Subprojects/AtheroJack/OpenHAL/OpenHAL5212.cpp =================================================================== --- KisMACng/Subprojects/AtheroJack/OpenHAL/OpenHAL5212.cpp 2006-04-10 06:45:20 UTC (rev 116) +++ KisMACng/Subprojects/AtheroJack/OpenHAL/OpenHAL5212.cpp 2006-04-13 03:55:56 UTC (rev 117) @@ -195,62 +195,152 @@ return AH_TRUE; } -void OpenHAL5212::nic_detach() { - if (ah_rf_banks != NULL) - IOFree(ah_rf_banks, sizeof(ar5112_rf_tofix)); -} +HAL_BOOL OpenHAL5212::ar5k_ar5212_nic_reset(u_int32_t val) { + HAL_BOOL ret = AH_FALSE; + u_int32_t mask = val ? val : 0xFFFFFFFF; -HAL_BOOL OpenHAL5212::nic_get_capabilities() -{ - u_int16_t ee_header; + /* Read-and-clear */ + AR5K_REG_READ(AR5K_AR5212_RXDP); - /* Capabilities stored in the EEPROM */ - ee_header = ah_capabilities.cap_eeprom.ee_header; + /* + * Reset the device and wait until success + */ + AR5K_REG_WRITE(AR5K_AR5212_RC, val); + /* Wait at least 128 PCI clocks */ + AR5K_DELAY(15); + + val &= + AR5K_AR5212_RC_PCU | AR5K_AR5212_RC_BB; + + mask &= + AR5K_AR5212_RC_PCU | AR5K_AR5212_RC_BB; + + ret = ar5k_register_timeout(AR5K_AR5212_RC, mask, val, AH_FALSE); + /* - * XXX The AR5212 tranceiver supports frequencies from 4920 to 6100GHz - * XXX and from 2312 to 2732GHz. There are problems with the current - * XXX ieee80211 implementation because the IEEE channel mapping - * XXX does not support negative channel numbers (2312MHz is channel - * XXX -19). Of course, this doesn't matter because these channels - * XXX are out of range but some regulation domains like MKK (Japan) - * XXX will support frequencies somewhere around 4.8GHz. + * Reset configuration register */ + if ((val & AR5K_AR5212_RC_PCU) == 0) + AR5K_REG_WRITE(AR5K_AR5212_CFG, AR5K_AR5212_INIT_CFG); + return (ret); +} + +HAL_BOOL OpenHAL5212::ar5k_ar5212_nic_wakeup(u_int16_t flags) { + u_int32_t turbo, mode, clock; + + turbo = 0; + mode = 0; + clock = 0; + /* - * Set radio capabilities + * Get channel mode flags */ - if (AR5K_EEPROM_HDR_11A(ee_header)) { - ah_capabilities.cap_range.range_5ghz_min = 5005; /* 4920 */ - ah_capabilities.cap_range.range_5ghz_max = 6100; + if (ah_radio >= AR5K_AR5112) { + mode = AR5K_AR5212_PHY_MODE_RAD_AR5112; + clock = AR5K_AR5212_PHY_PLL_AR5112; + } else { + mode = AR5K_AR5212_PHY_MODE_RAD_AR5111; + clock = AR5K_AR5212_PHY_PLL_AR5111; + } - /* Set supported modes */ - ah_capabilities.cap_mode = - HAL_MODE_11A | HAL_MODE_TURBO | HAL_MODE_XR; + if (flags & IEEE80211_CHAN_2GHZ) { + mode |= AR5K_AR5212_PHY_MODE_FREQ_2GHZ; + clock |= AR5K_AR5212_PHY_PLL_44MHZ; + } else if (flags & IEEE80211_CHAN_5GHZ) { + mode |= AR5K_AR5212_PHY_MODE_FREQ_5GHZ; + clock |= AR5K_AR5212_PHY_PLL_40MHZ; + } else { + AR5K_PRINT("invalid radio frequency mode\n"); + return (AH_FALSE); } - /* This chip will support 802.11b if the 2GHz radio is connected */ - if (AR5K_EEPROM_HDR_11B(ee_header) || AR5K_EEPROM_HDR_11G(ee_header)) { - ah_capabilities.cap_range.range_2ghz_min = 2412; /* 2312 */ - ah_capabilities.cap_range.range_2ghz_max = 2732; - ah_capabilities.cap_mode |= HAL_MODE_11B; + if (flags & IEEE80211_CHAN_CCK) { + mode |= AR5K_AR5212_PHY_MODE_MOD_CCK; + } else if (flags & IEEE80211_CHAN_OFDM) { + mode |= AR5K_AR5212_PHY_MODE_MOD_OFDM; + } else if (flags & IEEE80211_CHAN_DYN) { + mode |= AR5K_AR5212_PHY_MODE_MOD_DYN; + } else { + AR5K_PRINT("invalid radio frequency mode\n"); + return (AH_FALSE); + } - if (AR5K_EEPROM_HDR_11B(ee_header)) - ah_capabilities.cap_mode |= HAL_MODE_11B; - if (AR5K_EEPROM_HDR_11G(ee_header)) - ah_capabilities.cap_mode |= HAL_MODE_11G; + if (flags & IEEE80211_CHAN_TURBO) { + turbo = AR5K_AR5212_PHY_TURBO_MODE | + AR5K_AR5212_PHY_TURBO_SHORT; } - /* GPIO */ - ah_gpio_npins = AR5K_AR5212_NUM_GPIO; + /* + * Reset and wakeup the device + */ - /* Set number of supported TX queues */ - ah_capabilities.cap_queues.q_tx_num = AR5K_AR5212_TX_NUM_QUEUES; + /* ...reset chipset and PCI device */ + if (ar5k_ar5212_nic_reset(AR5K_AR5212_RC_CHIP | AR5K_AR5212_RC_PCI) == AH_FALSE) { + AR5K_PRINT("failed to reset the AR5212 + PCI chipset\n"); + return (AH_FALSE); + } + /* ...wakeup */ + if (nic_setPowerMode(HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) { + AR5K_PRINT("failed to resume the AR5212 (again)\n"); + return (AH_FALSE); + } + + /* ...final warm reset */ + if (ar5k_ar5212_nic_reset(0) == AH_FALSE) { + AR5K_PRINT("failed to warm reset the AR5212\n"); + return (AH_FALSE); + } + + /* ...set the PHY operating mode */ + AR5K_REG_WRITE(AR5K_AR5212_PHY_PLL, clock); + AR5K_DELAY(300); + + AR5K_REG_WRITE(AR5K_AR5212_PHY_MODE, mode); + AR5K_REG_WRITE(AR5K_AR5212_PHY_TURBO, turbo); + return (AH_TRUE); } +u_int16_t OpenHAL5212::ar5k_ar5212_radio_revision(HAL_CHIP chip) { + int i; + u_int32_t srev; + u_int16_t ret; + + /* + * Set the radio chip access register + */ + switch (chip) { + case HAL_CHIP_2GHZ: + AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_2GHZ); + break; + case HAL_CHIP_5GHZ: + AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ); + break; + default: + return (0); + } + + AR5K_DELAY(2000); + + /* ...wait until PHY is ready and read the selected radio revision */ + AR5K_REG_WRITE(AR5K_AR5212_PHY(0x34), 0x00001c16); + + for (i = 0; i < 8; i++) + AR5K_REG_WRITE(AR5K_AR5212_PHY(0x20), 0x00010000); + srev = (AR5K_REG_READ(AR5K_AR5212_PHY(0x100)) >> 24) & 0xff; + + ret = ar5k_bitswap(((srev & 0xf0) >> 4) | ((srev & 0x0f) << 4), 8); + + /* Reset to the 5GHz mode */ + AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ); + + return (ret); +} + const HAL_RATE_TABLE * OpenHAL5212::nic_getRateTable(u_int mode) { switch (mode) { case HAL_MODE_11A: @@ -271,6 +361,11 @@ return (NULL); } +void OpenHAL5212::nic_detach() { + if (ah_rf_banks != NULL) + IOFree(ah_rf_banks, sizeof(ar5112_rf_tofix)); +} + HAL_BOOL OpenHAL5212::nic_reset(HAL_OPMODE op_mode, HAL_CHANNEL *channel, HAL_BOOL change_channel, HAL_STATUS *status) { struct ar5k_eeprom_info *ee = &ah_capabilities.cap_eeprom; u_int8_t mac[IEEE80211_ADDR_LEN]; @@ -890,6 +985,8 @@ return (AH_TRUE); } +#pragma mark - + u_int32_t OpenHAL5212::nic_getRxDP() { return (AR5K_REG_READ(AR5K_AR5212_RXDP)); } @@ -1061,6 +1158,109 @@ AR5K_AR5212_RX_FILTER_PROMISC); } +#pragma mark - + +void OpenHAL5212::dumpState() { +#define AR5K_PRINT_REGISTER(_x) \ + IOLog("(%s: %08x) ", #_x, AR5K_REG_READ(AR5K_AR5212_##_x));\ + IOSleep(100); + + IOLog("MAC registers:\n"); + AR5K_PRINT_REGISTER(CR); + AR5K_PRINT_REGISTER(CFG); + AR5K_PRINT_REGISTER(IER); + AR5K_PRINT_REGISTER(TXCFG); + AR5K_PRINT_REGISTER(RXCFG); + AR5K_PRINT_REGISTER(MIBC); + AR5K_PRINT_REGISTER(TOPS); + AR5K_PRINT_REGISTER(RXNOFRM); + AR5K_PRINT_REGISTER(RPGTO); + AR5K_PRINT_REGISTER(RFCNT); + AR5K_PRINT_REGISTER(MISC); + AR5K_PRINT_REGISTER(PISR); + AR5K_PRINT_REGISTER(SISR0); + AR5K_PRINT_REGISTER(SISR1); + AR5K_PRINT_REGISTER(SISR3); + AR5K_PRINT_REGISTER(SISR4); + AR5K_PRINT_REGISTER(DCM_ADDR); + AR5K_PRINT_REGISTER(DCM_DATA); + AR5K_PRINT_REGISTER(DCCFG); + AR5K_PRINT_REGISTER(CCFG); + AR5K_PRINT_REGISTER(CCFG_CUP); + AR5K_PRINT_REGISTER(CPC0); + AR5K_PRINT_REGISTER(CPC1); + AR5K_PRINT_REGISTER(CPC2); + AR5K_PRINT_REGISTER(CPCORN); + AR5K_PRINT_REGISTER(QCU_TXE); + AR5K_PRINT_REGISTER(QCU_TXD); + AR5K_PRINT_REGISTER(DCU_GBL_IFS_SIFS); + AR5K_PRINT_REGISTER(DCU_GBL_IFS_SLOT); + AR5K_PRINT_REGISTER(DCU_FP); + AR5K_PRINT_REGISTER(DCU_TXP); + AR5K_PRINT_REGISTER(DCU_TX_FILTER); + AR5K_PRINT_REGISTER(RC); + AR5K_PRINT_REGISTER(SCR); + AR5K_PRINT_REGISTER(INTPEND); + AR5K_PRINT_REGISTER(PCICFG); + AR5K_PRINT_REGISTER(GPIOCR); + AR5K_PRINT_REGISTER(GPIODO); + AR5K_PRINT_REGISTER(SREV); + AR5K_PRINT_REGISTER(EEPROM_BASE); + AR5K_PRINT_REGISTER(EEPROM_DATA); + AR5K_PRINT_REGISTER(EEPROM_CMD); + AR5K_PRINT_REGISTER(EEPROM_CFG); + AR5K_PRINT_REGISTER(PCU_MIN); + AR5K_PRINT_REGISTER(STA_ID0); + AR5K_PRINT_REGISTER(STA_ID1); + AR5K_PRINT_REGISTER(BSS_ID0); + AR5K_PRINT_REGISTER(SLOT_TIME); + AR5K_PRINT_REGISTER(TIME_OUT); + AR5K_PRINT_REGISTER(RSSI_THR); + AR5K_PRINT_REGISTER(BEACON); + AR5K_PRINT_REGISTER(CFP_PERIOD); + AR5K_PRINT_REGISTER(TIMER0); + AR5K_PRINT_REGISTER(TIMER2); + AR5K_PRINT_REGISTER(TIMER3); + AR5K_PRINT_REGISTER(CFP_DUR); + AR5K_PRINT_REGISTER(MCAST_FIL0); + AR5K_PRINT_REGISTER(MCAST_FIL1); + AR5K_PRINT_REGISTER(DIAG_SW); + AR5K_PRINT_REGISTER(TSF_U32); + AR5K_PRINT_REGISTER(ADDAC_TEST); + AR5K_PRINT_REGISTER(DEFAULT_ANTENNA); + AR5K_PRINT_REGISTER(LAST_TSTP); + AR5K_PRINT_REGISTER(NAV); + AR5K_PRINT_REGISTER(RTS_OK); + AR5K_PRINT_REGISTER(ACK_FAIL); + AR5K_PRINT_REGISTER(FCS_FAIL); + AR5K_PRINT_REGISTER(BEACON_CNT); + AR5K_PRINT_REGISTER(TSF_PARM); + AR5K_PRINT_REGISTER(RATE_DUR_0); + AR5K_PRINT_REGISTER(KEYTABLE_0); + IOLog("\n"); + + IOLog("PHY registers:\n"); + AR5K_PRINT_REGISTER(PHY_TURBO); + AR5K_PRINT_REGISTER(PHY_AGC); + AR5K_PRINT_REGISTER(PHY_TIMING_3); + AR5K_PRINT_REGISTER(PHY_CHIP_ID); + AR5K_PRINT_REGISTER(PHY_AGCCTL); + AR5K_PRINT_REGISTER(PHY_NF); + AR5K_PRINT_REGISTER(PHY_SCR); + AR5K_PRINT_REGISTER(PHY_SLMT); + AR5K_PRINT_REGISTER(PHY_SCAL); + AR5K_PRINT_REGISTER(PHY_RX_DELAY); + AR5K_PRINT_REGISTER(PHY_IQ); + AR5K_PRINT_REGISTER(PHY_PAPD_PROBE); + AR5K_PRINT_REGISTER(PHY_TXPOWER_RATE1); + AR5K_PRINT_REGISTER(PHY_TXPOWER_RATE2); + AR5K_PRINT_REGISTER(PHY_FC); + AR5K_PRINT_REGISTER(PHY_RADAR); + AR5K_PRINT_REGISTER(PHY_ANT_SWITCH_TABLE_0); + AR5K_PRINT_REGISTER(PHY_ANT_SWITCH_TABLE_1); + IOLog("\n"); +} + void OpenHAL5212::nic_getMacAddress(u_int8_t *mac) { bcopy(ah_sta_id, mac, IEEE80211_ADDR_LEN); } @@ -1177,8 +1377,6 @@ nic_enablePSPoll(NULL, 0); } -#pragma mark - - HAL_BOOL OpenHAL5212::nic_gpioCfgInput(u_int32_t gpio) { if (gpio > AR5K_AR5212_NUM_GPIO) return (AH_FALSE); @@ -1222,8 +1420,6 @@ AR5K_REG_ENABLE_BITS(AR5K_AR5212_PIMR, AR5K_AR5212_PIMR_GPIO); } -#pragma mark - - HAL_RFGAIN OpenHAL5212::nic_getRfGain() { u_int32_t data, type; @@ -1261,6 +1457,8 @@ return (ah_rf_gain); } +#pragma mark - + HAL_BOOL OpenHAL5212::nic_resetKeyCacheEntry(u_int16_t entry) { int i; @@ -1276,6 +1474,8 @@ return (AH_FALSE); } +#pragma mark - + HAL_BOOL OpenHAL5212::nic_setPowerMode(HAL_POWER_MODE mode, HAL_BOOL set_chip, u_int16_t sleep_duration) { int i; @@ -1438,6 +1638,59 @@ #pragma mark - +HAL_BOOL OpenHAL5212::nic_get_capabilities() +{ + u_int16_t ee_header; + + /* Capabilities stored in the EEPROM */ + ee_header = ah_capabilities.cap_eeprom.ee_header; + + /* + * XXX The AR5212 tranceiver supports frequencies from 4920 to 6100GHz + * XXX and from 2312 to 2732GHz. There are problems with the current + * XXX ieee80211 implementation because the IEEE channel mapping + * XXX does not support negative channel numbers (2312MHz is channel + * XXX -19). Of course, this doesn't matter because these channels + * XXX are out of range but some regulation domains like MKK (Japan) + * XXX will support frequencies somewhere around 4.8GHz. + */ + + /* + * Set radio capabilities + */ + + if (AR5K_EEPROM_HDR_11A(ee_header)) { + ah_capabilities.cap_range.range_5ghz_min = 5005; /* 4920 */ + ah_capabilities.cap_range.range_5ghz_max = 6100; + + /* Set supported modes */ + ah_capabilities.cap_mode = + HAL_MODE_11A | HAL_MODE_TURBO | HAL_MODE_XR; + } + + /* This chip will support 802.11b if the 2GHz radio is connected */ + if (AR5K_EEPROM_HDR_11B(ee_header) || AR5K_EEPROM_HDR_11G(ee_header)) { + ah_capabilities.cap_range.range_2ghz_min = 2412; /* 2312 */ + ah_capabilities.cap_range.range_2ghz_max = 2732; + ah_capabilities.cap_mode |= HAL_MODE_11B; + + if (AR5K_EEPROM_HDR_11B(ee_header)) + ah_capabilities.cap_mode |= HAL_MODE_11B; + if (AR5K_EEPROM_HDR_11G(ee_header)) + ah_capabilities.cap_mode |= HAL_MODE_11G; + } + + /* GPIO */ + ah_gpio_npins = AR5K_AR5212_NUM_GPIO; + + /* Set number of supported TX queues */ + ah_capabilities.cap_queues.q_tx_num = AR5K_AR5212_TX_NUM_QUEUES; + + return (AH_TRUE); +} + +#pragma mark - + HAL_BOOL OpenHAL5212::nic_eeprom_is_busy() { return (AR5K_REG_READ(AR5K_AR5212_CFG) & AR5K_AR5212_CFG_EEBS ? AH_TRUE : AH_FALSE); @@ -1506,195 +1759,6 @@ #pragma mark - -HAL_BOOL OpenHAL5212::nic_channel(HAL_CHANNEL *channel) { - u_int32_t data, data0, data1, data2; - u_int16_t c; - - data = data0 = data1 = data2 = 0; - c = channel->c_channel; - - /* - * Set the channel on the AR5112 or newer - */ - if (c < 4800) { - if (!((c - 2224) % 5)) { - data0 = ((2 * (c - 704)) - 3040) / 10; - data1 = 1; - } else if (!((c - 2192) % 5)) { - data0 = ((2 * (c - 672)) - 3040) / 10; - data1 = 0; - } else - return (AH_FALSE); - - data0 = ar5k_bitswap((data0 << 2) & 0xff, 8); - } else { - if (!(c % 20) && c >= 5120) { - data0 = ar5k_bitswap(((c - 4800) / 20 << 2), 8); - data2 = ar5k_bitswap(3, 2); - } else if (!(c % 10)) { - data0 = ar5k_bitswap(((c - 4800) / 10 << 1), 8); - data2 = ar5k_bitswap(2, 2); - } else if (!(c % 5)) { - data0 = ar5k_bitswap((c - 4800) / 5, 8); - data2 = ar5k_bitswap(1, 2); - } else - return (AH_FALSE); - } - - data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001; - - AR5K_PHY_WRITE(0x27, data & 0xff); - AR5K_PHY_WRITE(0x36, (data >> 8) & 0x7f); - - return (AH_TRUE); -} - -HAL_BOOL OpenHAL5212::ar5k_ar5212_nic_reset(u_int32_t val) { - HAL_BOOL ret = AH_FALSE; - u_int32_t mask = val ? val : 0xFFFFFFFF; - - /* Read-and-clear */ - AR5K_REG_READ(AR5K_AR5212_RXDP); - - /* - * Reset the device and wait until success - */ - AR5K_REG_WRITE(AR5K_AR5212_RC, val); - - /* Wait at least 128 PCI clocks */ - AR5K_DELAY(15); - - val &= - AR5K_AR5212_RC_PCU | AR5K_AR5212_RC_BB; - - mask &= - AR5K_AR5212_RC_PCU | AR5K_AR5212_RC_BB; - - ret = ar5k_register_timeout(AR5K_AR5212_RC, mask, val, AH_FALSE); - - /* - * Reset configuration register - */ - if ((val & AR5K_AR5212_RC_PCU) == 0) - AR5K_REG_WRITE(AR5K_AR5212_CFG, AR5K_AR5212_INIT_CFG); - - return (ret); -} - -HAL_BOOL OpenHAL5212::ar5k_ar5212_nic_wakeup(u_int16_t flags) { - u_int32_t turbo, mode, clock; - - turbo = 0; - mode = 0; - clock = 0; - - /* - * Get channel mode flags - */ - - if (ah_radio >= AR5K_AR5112) { - mode = AR5K_AR5212_PHY_MODE_RAD_AR5112; - clock = AR5K_AR5212_PHY_PLL_AR5112; - } else { - mode = AR5K_AR5212_PHY_MODE_RAD_AR5111; - clock = AR5K_AR5212_PHY_PLL_AR5111; - } - - if (flags & IEEE80211_CHAN_2GHZ) { - mode |= AR5K_AR5212_PHY_MODE_FREQ_2GHZ; - clock |= AR5K_AR5212_PHY_PLL_44MHZ; - } else if (flags & IEEE80211_CHAN_5GHZ) { - mode |= AR5K_AR5212_PHY_MODE_FREQ_5GHZ; - clock |= AR5K_AR5212_PHY_PLL_40MHZ; - } else { - AR5K_PRINT("invalid radio frequency mode\n"); - return (AH_FALSE); - } - - if (flags & IEEE80211_CHAN_CCK) { - mode |= AR5K_AR5212_PHY_MODE_MOD_CCK; - } else if (flags & IEEE80211_CHAN_OFDM) { - mode |= AR5K_AR5212_PHY_MODE_MOD_OFDM; - } else if (flags & IEEE80211_CHAN_DYN) { - mode |= AR5K_AR5212_PHY_MODE_MOD_DYN; - } else { - AR5K_PRINT("invalid radio frequency mode\n"); - return (AH_FALSE); - } - - if (flags & IEEE80211_CHAN_TURBO) { - turbo = AR5K_AR5212_PHY_TURBO_MODE | - AR5K_AR5212_PHY_TURBO_SHORT; - } - - /* - * Reset and wakeup the device - */ - - /* ...reset chipset and PCI device */ - if (ar5k_ar5212_nic_reset(AR5K_AR5212_RC_CHIP | AR5K_AR5212_RC_PCI) == AH_FALSE) { - AR5K_PRINT("failed to reset the AR5212 + PCI chipset\n"); - return (AH_FALSE); - } - - /* ...wakeup */ - if (nic_setPowerMode(HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) { - AR5K_PRINT("failed to resume the AR5212 (again)\n"); - return (AH_FALSE); - } - - /* ...final warm reset */ - if (ar5k_ar5212_nic_reset(0) == AH_FALSE) { - AR5K_PRINT("failed to warm reset the AR5212\n"); - return (AH_FALSE); - } - - /* ...set the PHY operating mode */ - AR5K_REG_WRITE(AR5K_AR5212_PHY_PLL, clock); - AR5K_DELAY(300); - - AR5K_REG_WRITE(AR5K_AR5212_PHY_MODE, mode); - AR5K_REG_WRITE(AR5K_AR5212_PHY_TURBO, turbo); - - return (AH_TRUE); -} - -u_int16_t OpenHAL5212::ar5k_ar5212_radio_revision(HAL_CHIP chip) { - int i; - u_int32_t srev; - u_int16_t ret; - - /* - * Set the radio chip access register - */ - switch (chip) { - case HAL_CHIP_2GHZ: - AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_2GHZ); - break; - case HAL_CHIP_5GHZ: - AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ); - break; - default: - return (0); - } - - AR5K_DELAY(2000); - - /* ...wait until PHY is ready and read the selected radio revision */ - AR5K_REG_WRITE(AR5K_AR5212_PHY(0x34), 0x00001c16); - - for (i = 0; i < 8; i++) - AR5K_REG_WRITE(AR5K_AR5212_PHY(0x20), 0x00010000); - srev = (AR5K_REG_READ(AR5K_AR5212_PHY(0x100)) >> 24) & 0xff; - - ret = ar5k_bitswap(((srev & 0xf0) >> 4) | ((srev & 0x0f) << 4), 8); - - /* Reset to the 5GHz mode */ - AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ); - - return (ret); -} - HAL_BOOL OpenHAL5212::ar5k_ar5212_txpower(HAL_CHANNEL *channel, u_int txpower) { HAL_BOOL tpc = ah_txpower.txp_tpc; int i; @@ -1752,103 +1816,45 @@ #pragma mark - -void OpenHAL5212::dumpState() { -#define AR5K_PRINT_REGISTER(_x) \ - IOLog("(%s: %08x) ", #_x, AR5K_REG_READ(AR5K_AR5212_##_x));\ - IOSleep(100); +HAL_BOOL OpenHAL5212::nic_channel(HAL_CHANNEL *channel) { + u_int32_t data, data0, data1, data2; + u_int16_t c; - IOLog("MAC registers:\n"); - AR5K_PRINT_REGISTER(CR); - AR5K_PRINT_REGISTER(CFG); - AR5K_PRINT_REGISTER(IER); - AR5K_PRINT_REGISTER(TXCFG); - AR5K_PRINT_REGISTER(RXCFG); - AR5K_PRINT_REGISTER(MIBC); - AR5K_PRINT_REGISTER(TOPS); - AR5K_PRINT_REGISTER(RXNOFRM); - AR5K_PRINT_REGISTER(RPGTO); - AR5K_PRINT_REGISTER(RFCNT); - AR5K_PRINT_REGISTER(MISC); - AR5K_PRINT_REGISTER(PISR); - AR5K_PRINT_REGISTER(SISR0); - AR5K_PRINT_REGISTER(SISR1); - AR5K_PRINT_REGISTER(SISR3); - AR5K_PRINT_REGISTER(SISR4); - AR5K_PRINT_REGISTER(DCM_ADDR); - AR5K_PRINT_REGISTER(DCM_DATA); - AR5K_PRINT_REGISTER(DCCFG); - AR5K_PRINT_REGISTER(CCFG); - AR5K_PRINT_REGISTER(CCFG_CUP); - AR5K_PRINT_REGISTER(CPC0); - AR5K_PRINT_REGISTER(CPC1); - AR5K_PRINT_REGISTER(CPC2); - AR5K_PRINT_REGISTER(CPCORN); - AR5K_PRINT_REGISTER(QCU_TXE); - AR5K_PRINT_REGISTER(QCU_TXD); - AR5K_PRINT_REGISTER(DCU_GBL_IFS_SIFS); - AR5K_PRINT_REGISTER(DCU_GBL_IFS_SLOT); - AR5K_PRINT_REGISTER(DCU_FP); - AR5K_PRINT_REGISTER(DCU_TXP); - AR5K_PRINT_REGISTER(DCU_TX_FILTER); - AR5K_PRINT_REGISTER(RC); - AR5K_PRINT_REGISTER(SCR); - AR5K_PRINT_REGISTER(INTPEND); - AR5K_PRINT_REGISTER(PCICFG); - AR5K_PRINT_REGISTER(GPIOCR); - AR5K_PRINT_REGISTER(GPIODO); - AR5K_PRINT_REGISTER(SREV); - AR5K_PRINT_REGISTER(EEPROM_BASE); - AR5K_PRINT_REGISTER(EEPROM_DATA); - AR5K_PRINT_REGISTER(EEPROM_CMD); - AR5K_PRINT_REGISTER(EEPROM_CFG); - AR5K_PRINT_REGISTER(PCU_MIN); - AR5K_PRINT_REGISTER(STA_ID0); - AR5K_PRINT_REGISTER(STA_ID1); - AR5K_PRINT_REGISTER(BSS_ID0); - AR5K_PRINT_REGISTER(SLOT_TIME); - AR5K_PRINT_REGISTER(TIME_OUT); - AR5K_PRINT_REGISTER(RSSI_THR); - AR5K_PRINT_REGISTER(BEACON); - AR5K_PRINT_REGISTER(CFP_PERIOD); - AR5K_PRINT_REGISTER(TIMER0); - AR5K_PRINT_REGISTER(TIMER2); - AR5K_PRINT_REGISTER(TIMER3); - AR5K_PRINT_REGISTER(CFP_DUR); - AR5K_PRINT_REGISTER(MCAST_FIL0); - AR5K_PRINT_REGISTER(MCAST_FIL1); - AR5K_PRINT_REGISTER(DIAG_SW); - AR5K_PRINT_REGISTER(TSF_U32); - AR5K_PRINT_REGISTER(ADDAC_TEST); - AR5K_PRINT_REGISTER(DEFAULT_ANTENNA); - AR5K_PRINT_REGISTER(LAST_TSTP); - AR5K_PRINT_REGISTER(NAV); - AR5K_PRINT_REGISTER(RTS_OK); - AR5K_PRINT_REGISTER(ACK_FAIL); - AR5K_PRINT_REGISTER(FCS_FAIL); - AR5K_PRINT_REGISTER(BEACON_CNT); - AR5K_PRINT_REGISTER(TSF_PARM); - AR5K_PRINT_REGISTER(RATE_DUR_0); - AR5K_PRINT_REGISTER(KEYTABLE_0); - IOLog("\n"); + data = data0 = data1 = data2 = 0; + c = channel->c_channel; - IOLog("PHY registers:\n"); - AR5K_PRINT_REGISTER(PHY_TURBO); - AR5K_PRINT_REGISTER(PHY_AGC); - AR5K_PRINT_REGISTER(PHY_TIMING_3); - AR5K_PRINT_REGISTER(PHY_CHIP_ID); - AR5K_PRINT_REGISTER(PHY_AGCCTL); - AR5K_PRINT_REGISTER(PHY_NF); - AR5K_PRINT_REGISTER(PHY_SCR); - AR5K_PRINT_REGISTER(PHY_SLMT); - AR5K_PRINT_REGISTER(PHY_SCAL); - AR5K_PRINT_REGISTER(PHY_RX_DELAY); - AR5K_PRINT_REGISTER(PHY_IQ); - AR5K_PRINT_REGISTER(PHY_PAPD_PROBE); - AR5K_PRINT_REGISTER(PHY_TXPOWER_RATE1); - AR5K_PRINT_REGISTER(PHY_TXPOWER_RATE2); - AR5K_PRINT_REGISTER(PHY_FC); - AR5K_PRINT_REGISTER(PHY_RADAR); - AR5K_PRINT_REGISTER(PHY_ANT_SWITCH_TABLE_0); - AR5K_PRINT_REGISTER(PHY_ANT_SWITCH_TABLE_1); - IOLog("\n"); + /* + * Set the channel on the AR5112 or newer + */ + if (c < 4800) { + if (!((c - 2224) % 5)) { + data0 = ((2 * (c - 704)) - 3040) / 10; + data1 = 1; + } else if (!((c - 2192) % 5)) { + data0 = ((2 * (c - 672)) - 3040) / 10; + data1 = 0; + } else + return (AH_FALSE); + + data0 = ar5k_bitswap((data0 << 2) & 0xff, 8); + } else { + if (!(c % 20) && c >= 5120) { + data0 = ar5k_bitswap(((c - 4800) / 20 << 2), 8); + data2 = ar5k_bitswap(3, 2); + } else if (!(c % 10)) { + data0 = ar5k_bitswap(((c - 4800) / 10 << 1), 8); + data2 = ar5k_bitswap(2, 2); + } else if (!(c % 5)) { + data0 = ar5k_bitswap((c - 4800) / 5, 8); + data2 = ar5k_bitswap(1, 2); + } else + return (AH_FALSE); + } + + data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001; + + AR5K_PHY_WRITE(0x27, data & 0xff); + AR5K_PHY_WRITE(0x36, (data >> 8) & 0x7f); + + return (AH_TRUE); } \ No newline at end of file