00001 #include "ah.h"
00002 #include <errno.h>
00003 #include "ar5xxx.h"
00004
00005 #define AR5K_DELAY(_n) delay(_n)
00006 #define AR5K_ELEMENTS(_array) (sizeof(_array) / sizeof(_array[0]))
00007
00008
00009
00010
00011 #define AR5K_RATES_11A { 8, { \
00012 255, 255, 255, 255, 255, 255, 255, 255, 6, 4, 2, 0, \
00013 7, 5, 3, 1, 255, 255, 255, 255, 255, 255, 255, 255, \
00014 255, 255, 255, 255, 255, 255, 255, 255 }, { \
00015 { 1, IEEE80211_T_OFDM, 6000, 11, 0, 140, 0 }, \
00016 { 1, IEEE80211_T_OFDM, 9000, 15, 0, 18, 0 }, \
00017 { 1, IEEE80211_T_OFDM, 12000, 10, 0, 152, 2 }, \
00018 { 1, IEEE80211_T_OFDM, 18000, 14, 0, 36, 2 }, \
00019 { 1, IEEE80211_T_OFDM, 24000, 9, 0, 176, 4 }, \
00020 { 1, IEEE80211_T_OFDM, 36000, 13, 0, 72, 4 }, \
00021 { 1, IEEE80211_T_OFDM, 48000, 8, 0, 96, 4 }, \
00022 { 1, IEEE80211_T_OFDM, 54000, 12, 0, 108, 4 } } \
00023 }
00024
00025 #define AR5K_RATES_11B { 4, { \
00026 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, \
00027 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, \
00028 3, 2, 1, 0, 255, 255, 255, 255 }, { \
00029 { 1, IEEE80211_T_CCK, 1000, 27, 0x00, 130, 0 }, \
00030 { 1, IEEE80211_T_CCK, 2000, 26, 0x04, 132, 1 }, \
00031 { 1, IEEE80211_T_CCK, 5500, 25, 0x04, 139, 1 }, \
00032 { 1, IEEE80211_T_CCK, 11000, 24, 0x04, 150, 1 } } \
00033 }
00034
00035 #define AR5K_RATES_11G { 12, { \
00036 255, 255, 255, 255, 255, 255, 255, 255, 10, 8, 6, 4, \
00037 11, 9, 7, 5, 255, 255, 255, 255, 255, 255, 255, 255, \
00038 3, 2, 1, 0, 255, 255, 255, 255 }, { \
00039 { 1, IEEE80211_T_CCK, 1000, 27, 0x00, 2, 0 }, \
00040 { 1, IEEE80211_T_CCK, 2000, 26, 0x04, 4, 1 }, \
00041 { 1, IEEE80211_T_CCK, 5500, 25, 0x04, 11, 1 }, \
00042 { 1, IEEE80211_T_CCK, 11000, 24, 0x04, 22, 1 }, \
00043 { 0, IEEE80211_T_OFDM, 6000, 11, 0, 12, 4 }, \
00044 { 0, IEEE80211_T_OFDM, 9000, 15, 0, 18, 4 }, \
00045 { 1, IEEE80211_T_OFDM, 12000, 10, 0, 24, 6 }, \
00046 { 1, IEEE80211_T_OFDM, 18000, 14, 0, 36, 6 }, \
00047 { 1, IEEE80211_T_OFDM, 24000, 9, 0, 48, 8 }, \
00048 { 1, IEEE80211_T_OFDM, 36000, 13, 0, 72, 8 }, \
00049 { 1, IEEE80211_T_OFDM, 48000, 8, 0, 96, 8 }, \
00050 { 1, IEEE80211_T_OFDM, 54000, 12, 0, 108, 8 } } \
00051 }
00052
00053 #define AR5K_RATES_TURBO { 8, { \
00054 255, 255, 255, 255, 255, 255, 255, 255, 6, 4, 2, 0, \
00055 7, 5, 3, 1, 255, 255, 255, 255, 255, 255, 255, 255, \
00056 255, 255, 255, 255, 255, 255, 255, 255 }, { \
00057 { 1, IEEE80211_T_TURBO, 6000, 11, 0, 140, 0 }, \
00058 { 1, IEEE80211_T_TURBO, 9000, 15, 0, 18, 0 }, \
00059 { 1, IEEE80211_T_TURBO, 12000, 10, 0, 152, 2 }, \
00060 { 1, IEEE80211_T_TURBO, 18000, 14, 0, 36, 2 }, \
00061 { 1, IEEE80211_T_TURBO, 24000, 9, 0, 176, 4 }, \
00062 { 1, IEEE80211_T_TURBO, 36000, 13, 0, 72, 4 }, \
00063 { 1, IEEE80211_T_TURBO, 48000, 8, 0, 96, 4 }, \
00064 { 1, IEEE80211_T_TURBO, 54000, 12, 0, 108, 4 } } \
00065 }
00066
00067 #define AR5K_RATES_XR { 12, { \
00068 255, 3, 1, 255, 255, 255, 2, 0, 10, 8, 6, 4, \
00069 11, 9, 7, 5, 255, 255, 255, 255, 255, 255, 255, 255, \
00070 255, 255, 255, 255, 255, 255, 255, 255 }, { \
00071 { 1, IEEE80211_T_XR, 500, 7, 0, 129, 0 }, \
00072 { 1, IEEE80211_T_XR, 1000, 2, 0, 139, 1 }, \
00073 { 1, IEEE80211_T_XR, 2000, 6, 0, 150, 2 }, \
00074 { 1, IEEE80211_T_XR, 3000, 1, 0, 150, 3 }, \
00075 { 1, IEEE80211_T_OFDM, 6000, 11, 0, 140, 4 }, \
00076 { 1, IEEE80211_T_OFDM, 9000, 15, 0, 18, 4 }, \
00077 { 1, IEEE80211_T_OFDM, 12000, 10, 0, 152, 6 }, \
00078 { 1, IEEE80211_T_OFDM, 18000, 14, 0, 36, 6 }, \
00079 { 1, IEEE80211_T_OFDM, 24000, 9, 0, 176, 8 }, \
00080 { 1, IEEE80211_T_OFDM, 36000, 13, 0, 72, 8 }, \
00081 { 1, IEEE80211_T_OFDM, 48000, 8, 0, 96, 8 }, \
00082 { 1, IEEE80211_T_OFDM, 54000, 12, 0, 108, 8 } } \
00083 }
00084
00085
00086
00087
00088 static const HAL_RATE_TABLE ar5k_rt_11a = AR5K_RATES_11A;
00089 static const HAL_RATE_TABLE ar5k_rt_11b = AR5K_RATES_11B;
00090 static const HAL_RATE_TABLE ar5k_rt_11g = AR5K_RATES_11G;
00091 static const HAL_RATE_TABLE ar5k_rt_turbo = AR5K_RATES_TURBO;
00092 static const HAL_RATE_TABLE ar5k_rt_xr = AR5K_RATES_XR;
00093
00094
00095
00096
00097
00098 struct ath_hal *
00099 ath_hal_attach(device, sc, st, sh, status)
00100 u_int16_t device;
00101 HAL_SOFTC sc;
00102 HAL_BUS_TAG st;
00103 HAL_BUS_HANDLE sh;
00104 HAL_STATUS *status;
00105 {
00106 u_int32_t ieee_regdomain;
00107 u_int32_t regdomain;
00108 struct ath_hal *hal = 0;
00109 ar5k_attach_t *attach = 0;
00110 u_int8_t mac[6];
00111 int i;
00112
00113 *status = EINVAL;
00114
00115
00116
00117
00118 for (i = 0; i < AR5K_ELEMENTS(ar5k_known_products); i++) {
00119 if (device == ar5k_known_products[i].device &&
00120 ar5k_known_products[i].attach != 0)
00121 attach = ar5k_known_products[i].attach;
00122 }
00123
00124 if (attach == 0) {
00125 *status = ENXIO;
00126
00127 return (0);
00128 }
00129
00130 if ((hal = (struct ath_hal *) malloc(sizeof(struct ath_hal))) == 0) {
00131 *status = ENOMEM;
00132 AR5K_PRINT("out of memory\n");
00133 return (0);
00134 }
00135
00136 bzero(hal, sizeof(struct ath_hal));
00137
00138 hal->ah_sc = sc;
00139 hal->ah_st = st;
00140 hal->ah_sh = sh;
00141 hal->ah_device = device;
00142
00143
00144
00145
00146
00147 hal->ah_abi = HAL_ABI_VERSION;
00148 hal->ah_country_code = CTRY_DEFAULT;
00149 hal->ah_capabilities.cap_regdomain.reg_current = 0x10;
00150 hal->ah_op_mode = HAL_M_STA;
00151 hal->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
00152 hal->ah_turbo = AH_FALSE;
00153 hal->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
00154 hal->ah_imr = 0;
00155 hal->ah_atim_window = 0;
00156 hal->ah_aifs = AR5K_TUNE_AIFS;
00157 hal->ah_cw_min = AR5K_TUNE_CWMIN;
00158 hal->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
00159 hal->ah_software_retry = AH_FALSE;
00160 hal->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
00161
00162 if ((attach)(device, hal, st, sh, status) == 0)
00163 goto failed;
00164
00165 #ifdef AR5K_DEBUG
00166 hal->ah_dump_state(hal);
00167 #endif
00168
00169
00170
00171
00172
00173 if (ar5k_eeprom_init(hal) != 0) {
00174 AR5K_PRINT("unable to init EEPROM\n");
00175 goto failed;
00176 }
00177
00178
00179 if ((regdomain =
00180 hal->ah_capabilities.cap_eeprom.ee_regdomain) != 0) {
00181 hal->ah_capabilities.cap_regdomain.reg_current =
00182 ieee_regdomain = ar5k_regdomain_to_ieee(regdomain);
00183 } else {
00184 ieee_regdomain =
00185 hal->ah_capabilities.cap_regdomain.reg_current;
00186
00187
00188 ar5k_eeprom_regulation_domain(hal, AH_TRUE, &ieee_regdomain);
00189 }
00190
00191 hal->ah_capabilities.cap_regdomain.reg_hw = ieee_regdomain;
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 if ((*status = ar5k_eeprom_read_mac(hal, mac)) != 0) {
00202 AR5K_PRINTF("unable to read address from EEPROM: 0x%04x\n",
00203 device);
00204 goto failed;
00205 }
00206
00207
00208
00209
00210 if (hal->ah_capabilities.cap_mode & HAL_MODE_11A)
00211 ar5k_rt_copy(&hal->ah_rt_11a, &ar5k_rt_11a);
00212 if (hal->ah_capabilities.cap_mode & HAL_MODE_11B)
00213 ar5k_rt_copy(&hal->ah_rt_11b, &ar5k_rt_11b);
00214 if (hal->ah_capabilities.cap_mode & HAL_MODE_11G)
00215 ar5k_rt_copy(&hal->ah_rt_11g, &ar5k_rt_11g);
00216 if (hal->ah_capabilities.cap_mode & HAL_MODE_TURBO)
00217 ar5k_rt_copy(&hal->ah_rt_turbo, &ar5k_rt_turbo);
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 *status = HAL_OK;
00241
00242 return (hal);
00243
00244 failed:
00245 free(hal);
00246 return (0);
00247 }