📄 ar5xxx.c
字号:
#endif AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(hal->ah_ee_version), ee_ant_gain); if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0); AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1); } if (hal->ah_ee_version < AR5K_EEPROM_VERSION_3_3) { AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val); ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7; ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7; AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val); ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7; ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7; } /* * Get conformance test limit values */ offset = AR5K_EEPROM_CTL(hal->ah_ee_version); ee->ee_ctls = AR5K_EEPROM_N_CTLS(hal->ah_ee_version); for (i = 0; i < ee->ee_ctls; i++) { AR5K_EEPROM_READ(offset++, val); ee->ee_ctl[i] = (val >> 8) & 0xff; ee->ee_ctl[i + 1] = val & 0xff; } /* * Get values for 802.11a (5GHz) */ mode = AR5K_EEPROM_MODE_11A; ee->ee_turbo_max_power[mode] = AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header); offset = AR5K_EEPROM_MODES_11A(hal->ah_ee_version); if ((ret = ar5k_eeprom_read_ants(hal, &offset, mode)) != 0) return (ret); AR5K_EEPROM_READ(offset++, val); ee->ee_adc_desired_size[mode] = (int8_t)((val >> 8) & 0xff); ee->ee_ob[mode][3] = (val >> 5) & 0x7; ee->ee_db[mode][3] = (val >> 2) & 0x7; ee->ee_ob[mode][2] = (val << 1) & 0x7; AR5K_EEPROM_READ(offset++, val); ee->ee_ob[mode][2] |= (val >> 15) & 0x1; ee->ee_db[mode][2] = (val >> 12) & 0x7; ee->ee_ob[mode][1] = (val >> 9) & 0x7; ee->ee_db[mode][1] = (val >> 6) & 0x7; ee->ee_ob[mode][0] = (val >> 3) & 0x7; ee->ee_db[mode][0] = val & 0x7; if ((ret = ar5k_eeprom_read_modes(hal, &offset, mode)) != 0) return (ret); if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) { AR5K_EEPROM_READ(offset++, val); ee->ee_margin_tx_rx[mode] = val & 0x3f; } /* * Get values for 802.11b (2.4GHz) */ mode = AR5K_EEPROM_MODE_11B; offset = AR5K_EEPROM_MODES_11B(hal->ah_ee_version); if ((ret = ar5k_eeprom_read_ants(hal, &offset, mode)) != 0) return (ret); AR5K_EEPROM_READ(offset++, val); ee->ee_adc_desired_size[mode] = (int8_t)((val >> 8) & 0xff); ee->ee_ob[mode][1] = (val >> 4) & 0x7; ee->ee_db[mode][1] = val & 0x7; if ((ret = ar5k_eeprom_read_modes(hal, &offset, mode)) != 0) return (ret); if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { AR5K_EEPROM_READ(offset++, val); ee->ee_cal_pier[mode][0] = ar5k_eeprom_bin2freq(hal, val & 0xff, mode); ee->ee_cal_pier[mode][1] = ar5k_eeprom_bin2freq(hal, (val >> 8) & 0xff, mode); AR5K_EEPROM_READ(offset++, val); ee->ee_cal_pier[mode][2] = ar5k_eeprom_bin2freq(hal, val & 0xff, mode); } if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) { ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; } /* * Get values for 802.11g (2.4GHz) */ mode = AR5K_EEPROM_MODE_11G; offset = AR5K_EEPROM_MODES_11G(hal->ah_ee_version); if ((ret = ar5k_eeprom_read_ants(hal, &offset, mode)) != 0) return (ret); AR5K_EEPROM_READ(offset++, val); ee->ee_adc_desired_size[mode] = (int8_t)((val >> 8) & 0xff); ee->ee_ob[mode][1] = (val >> 4) & 0x7; ee->ee_db[mode][1] = val & 0x7; if ((ret = ar5k_eeprom_read_modes(hal, &offset, mode)) != 0) return (ret); if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { AR5K_EEPROM_READ(offset++, val); ee->ee_cal_pier[mode][0] = ar5k_eeprom_bin2freq(hal, val & 0xff, mode); ee->ee_cal_pier[mode][1] = ar5k_eeprom_bin2freq(hal, (val >> 8) & 0xff, mode); AR5K_EEPROM_READ(offset++, val); ee->ee_turbo_max_power[mode] = val & 0x7f; ee->ee_xr_power[mode] = (val >> 7) & 0x3f; AR5K_EEPROM_READ(offset++, val); ee->ee_cal_pier[mode][2] = ar5k_eeprom_bin2freq(hal, val & 0xff, mode); if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) { ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; } AR5K_EEPROM_READ(offset++, val); ee->ee_i_cal[mode] = (val >> 8) & 0x3f; ee->ee_q_cal[mode] = (val >> 3) & 0x1f; if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) { AR5K_EEPROM_READ(offset++, val); ee->ee_cck_ofdm_gain_delta = val & 0xff; } } /* * Read 5GHz EEPROM channels */ return (0);}int /*O.K.*/ar5k_eeprom_read_mac(struct ath_hal *hal, 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 (hal->ah_eeprom_read(hal, 0x20, &data) != 0) return (HAL_EIO); for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { if (hal->ah_eeprom_read(hal, 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 (0);}HAL_BOOL /*O.K*/ar5k_eeprom_regulation_domain(struct ath_hal *hal, HAL_BOOL write, ieee80211_regdomain_t *regdomain){ u_int16_t ee_regdomain; /* Read current value */ if (write != AH_TRUE) { ee_regdomain = hal->ah_capabilities.cap_eeprom.ee_regdomain; *regdomain = ar5k_regdomain_to_ieee(ee_regdomain); return (AH_TRUE); } ee_regdomain = ar5k_regdomain_from_ieee(*regdomain); /* Try to write a new value */ if (hal->ah_capabilities.cap_eeprom.ee_protect & AR5K_EEPROM_PROTECT_WR_128_191) return (AH_FALSE); if (hal->ah_eeprom_write(hal, AR5K_EEPROM_REG_DOMAIN, ee_regdomain) != 0) return (AH_FALSE); hal->ah_capabilities.cap_eeprom.ee_regdomain = ee_regdomain; return (AH_TRUE);}/* * PHY/RF access functions */HAL_BOOL /*O.K.*/ar5k_channel(struct ath_hal *hal, HAL_CHANNEL *channel){ HAL_BOOL ret; /* * Check bounds supported by the PHY * (don't care about regulation restrictions at this point) */ if ((channel->channel < hal->ah_capabilities.cap_range.range_2ghz_min || channel->channel > hal->ah_capabilities.cap_range.range_2ghz_max) && (channel->channel < hal->ah_capabilities.cap_range.range_5ghz_min || channel->channel > hal->ah_capabilities.cap_range.range_5ghz_max)) { AR5K_PRINTF("channel out of supported range (%u MHz)\n", channel->channel); return (AH_FALSE); } /* * Set the channel and wait */ if (hal->ah_radio == AR5K_AR5110) ret = ar5k_ar5110_channel(hal, channel); else if (hal->ah_radio == AR5K_AR5111) ret = ar5k_ar5111_channel(hal, channel); else ret = ar5k_ar5112_channel(hal, channel); if (ret == AH_FALSE) return (ret); hal->ah_current_channel.c_channel = channel->c_channel; hal->ah_current_channel.c_channel_flags = channel->c_channel_flags; hal->ah_turbo = channel->c_channel_flags == CHANNEL_T ? AH_TRUE : AH_FALSE; return (AH_TRUE);}u_int32_t /*O.K.*/ar5k_ar5110_chan2athchan(HAL_CHANNEL *channel){ u_int32_t athchan; /* * Convert IEEE channel/MHz to an internal channel value used * by the AR5210 chipset. This has not been verified with * newer chipsets like the AR5212A who have a completely * different RF/PHY part. */ athchan = (ar5k_bitswap((ath_hal_mhz2ieee(channel->c_channel, channel->c_channel_flags) - 24) / 2, 5) << 1) | (1 << 6) | 0x1; return (athchan);}HAL_BOOL /*O.K.*/ar5k_ar5110_channel(struct ath_hal *hal, HAL_CHANNEL *channel){ u_int32_t data; /* * Set the channel and wait */ data = ar5k_ar5110_chan2athchan(channel); AR5K_PHY_WRITE(0x27, data); AR5K_PHY_WRITE(0x30, 0); AR5K_DELAY(1000); return (AH_TRUE);}HAL_BOOL /*O.K.*/ar5k_ar5111_chan2athchan(u_int ieee, struct ar5k_athchan_2ghz *athchan){ int channel; /* Cast this value to catch negative channel numbers (>= -19) */ channel = (int)ieee; /* * Map 2GHz IEEE channel to 5GHz Atheros channel */ if (channel <= 13) { athchan->a2_athchan = 115 + channel; athchan->a2_flags = 0x46; } else if (channel == 14) { athchan->a2_athchan = 124; athchan->a2_flags = 0x44; } else if (channel >= 15 && channel <= 26) { athchan->a2_athchan = ((channel - 14) * 4) + 132; athchan->a2_flags = 0x46; } else return (AH_FALSE); return (AH_TRUE);}HAL_BOOL /*O.K.*/ar5k_ar5111_channel(struct ath_hal *hal, HAL_CHANNEL *channel){ u_int ieee_channel, ath_channel; u_int32_t data0, data1, clock; struct ar5k_athchan_2ghz ath_channel_2ghz; /* * Set the channel on the AR5111 radio */ data0 = data1 = 0; ath_channel = ieee_channel = ath_hal_mhz2ieee(channel->c_channel, channel->c_channel_flags); if (channel->c_channel_flags & IEEE80211_CHAN_2GHZ) { /* Map 2GHz channel to 5GHz Atheros channel ID */ if (ar5k_ar5111_chan2athchan(ieee_channel, &ath_channel_2ghz) == AH_FALSE) return (AH_FALSE); ath_channel = ath_channel_2ghz.a2_athchan; data0 = ((ar5k_bitswap(ath_channel_2ghz.a2_flags, 8) & 0xff) << 5) | (1 << 4); } if (ath_channel < 145 || !(ath_channel & 1)) { clock = 1; data1 = ((ar5k_bitswap(ath_channel - 24, 8) & 0xff) << 2) | (clock << 1) | (1 << 10) | 1; } else { clock = 0; data1 = ((ar5k_bitswap((ath_channel - 24) / 2, 8) & 0xff) << 2) | (clock << 1) | (1 << 10) | 1; } AR5K_PHY_WRITE(0x27, (data1 & 0xff) | ((data0 & 0xff) << 8)); AR5K_PHY_WRITE(0x34, ((data1 >> 8) & 0xff) | (data0 & 0xff00)); return (AH_TRUE);}HAL_BOOL /*O.K.*/ar5k_ar5112_channel(struct ath_hal *hal, 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);}u_int /*O.K. data initialized */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; int i; data = 0; if (rf == NULL) { /* should not happen */ return (0); } if (!(col <= 3 && bits <= 32 && first + bits <= 319)) { AR5K_PRINTF("invalid values at offset %u\n", offset); return (0); } entry = ((first - 1) / 8) + offset; position = (first - 1) % 8; if (set == AH_TRUE) data = ar5k_bitswap(reg, bits); for (i = shift = 0, left = bits; left > 0; position = 0, entry++, i++) { last = (position + left > 8) ? 8 : position + left; mask = (((1 << last) - 1) ^ ((1 << position) - 1)) << (col * 8); if (set == AH_TRUE) { rf[entry] &= ~mask; rf[entry] |= ((data << position) << (col * 8)) & mask; data >>= (8 - position); } else { data = (((rf[entry] & mask) >> (col * 8)) >> position) << shift; shift += last - position; } left -= 8 - position; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -