00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <linux/config.h>
00025 #include <linux/version.h>
00026 #include <linux/module.h>
00027 #include <linux/init.h>
00028 #include <linux/delay.h>
00029 #include <linux/netdevice.h>
00030 #include <linux/random.h>
00031 #include <linux/cache.h>
00032 #include <linux/if_arp.h>
00033 #include <linux/proc_fs.h>
00034 #include <asm/uaccess.h>
00035 #include <asm/io.h>
00036 #include "_ieee80211.h"
00037 #include "ieee80211_regdomain.h"
00038 #include "ah.h"
00039 #include "ar5212reg.h"
00040 #include "ar5212var.h"
00041
00042
00043 #define AR5K_PRINT_REGISTER(_x) \
00044 printk("(%s: %08x)\n", #_x, AR5K_REG_READ(AR5K_AR5212_##_x));
00045
00046
00047
00048
00049 HAL_BOOL ar5k_ar5212_nic_reset(struct ath_hal *, u_int32_t);
00050 HAL_BOOL ar5k_ar5212_nic_wakeup(struct ath_hal *, u_int16_t);
00051 u_int16_t ar5k_ar5212_radio_revision(struct ath_hal *, HAL_CHIP);
00052 const void ar5k_ar5212_fill(struct ath_hal *);
00053 HAL_BOOL ar5k_ar5212_txpower(struct ath_hal *, HAL_CHANNEL *, u_int);
00054 HAL_BOOL ar5k_ar5212_setup_tx_queueprops(struct ath_hal *, int queue,
00055 const HAL_TXQ_INFO *queue_info);
00056 HAL_BOOL ar5k_ar5212_reset_tx_queue(struct ath_hal *, u_int queue);
00057 void ar5k_ar5212_get_lladdr(struct ath_hal *, u_int8_t *mac);
00058 void ar5k_ar5212_set_associd(struct ath_hal *, const u_int8_t *bssid,
00059 u_int16_t assoc_id);
00060 HAL_BOOL ar5k_ar5212_set_gpio_output(struct ath_hal *hal, u_int32_t gpio);
00061 HAL_BOOL ar5k_ar5212_set_gpio_input(struct ath_hal *hal, u_int32_t gpio);
00062 u_int32_t ar5k_ar5212_get_gpio(struct ath_hal *hal, u_int32_t gpio);
00063 HAL_BOOL ar5k_ar5212_set_gpio_input(struct ath_hal *hal, u_int32_t gpio);
00064 void ar5k_ar5212_set_gpio_intr(struct ath_hal *hal, u_int gpio,
00065 u_int32_t interrupt_level);
00066 HAL_RFGAIN ar5k_ar5212_get_rf_gain(struct ath_hal *hal);
00067 HAL_BOOL ar5k_ar5212_set_key_lladdr(struct ath_hal *hal, u_int16_t entry,
00068 const u_int8_t *mac);
00069 HAL_BOOL ar5k_ar5212_set_power(struct ath_hal *hal, HAL_POWER_MODE mode,
00070 int set_chip, u_int16_t sleep_duration);
00071 HAL_BOOL ar5k_ar5212_enable_pspoll(struct ath_hal *hal, u_int8_t *bssid,
00072 u_int16_t assoc_id);
00073 HAL_BOOL ar5k_ar5212_disable_pspoll(struct ath_hal *hal);
00074 HAL_INT ar5k_ar5212_set_intr(struct ath_hal *hal, HAL_INT new_mask);
00075 HAL_BOOL ar5k_ar5212_phy_disable(struct ath_hal *hal);
00076 HAL_BOOL ar5k_ar5212_is_key_valid(struct ath_hal *hal, u_int16_t entry);
00077 HAL_BOOL ar5k_ar5212_reset_key(struct ath_hal *hal, u_int16_t entry);
00078 HAL_BOOL ar5k_ar5212_set_regdomain(struct ath_hal *hal, u_int16_t regdomain,
00079 HAL_STATUS *status);
00080 struct ath_hal * ar5k_ar5212_attach(u_int16_t device, void *sc, HAL_BUS_TAG st,
00081 HAL_BUS_HANDLE sh, HAL_STATUS *status);
00082 void ar5k_ar5212_set_opmode(struct ath_hal *hal);
00083 static int ar5k_ar5212_proc_read_reg(struct ath_hal *hal, char *buf, int);
00084
00085
00086
00087
00088 static const struct ar5k_ar5212_ini ar5212_ini[] =
00089 AR5K_AR5212_INI;
00090 static const struct ar5k_ar5212_ini_mode ar5212_mode[] =
00091 AR5K_AR5212_INI_MODE;
00092
00093
00094
00095
00096
00097 struct proc_dir_entry *proc_hal = NULL;
00098 struct proc_dir_entry *proc_hal_reg = NULL;
00099
00100 struct proc_ar5k_ar5212_priv {
00101 int rlen;
00102 int max_rlen;
00103 char *rbuf;
00104
00105 int wlen;
00106 int max_wlen;
00107 char *wbuf;
00108 };
00109
00110 static int
00111 proc_ar5k_ar5212_read(struct file *file, char *buf, size_t len, loff_t *offset)
00112 {
00113 loff_t pos = *offset;
00114 struct proc_ar5k_ar5212_priv *pv = (struct proc_ar5k_ar5212_priv *) file->private_data;
00115
00116 if (!pv->rbuf)
00117 return -EINVAL;
00118 if (pos < 0)
00119 return -EINVAL;
00120 if (pos >= pv->rlen)
00121 return 0;
00122 if (len > pv->rlen - pos)
00123 len = pv->rlen - pos;
00124 if (copy_to_user(buf, pv->rbuf + pos, len))
00125 return -EFAULT;
00126 *offset = pos + len;
00127 return len;
00128 }
00129
00130 #define MAX_PROC_AR5K_AR5212_SIZE 16383
00131 #define PROC_AR5K_AR5212_PERM 0644
00132 static int proc_ar5k_ar5212_open(struct inode *inode, struct file *file) {
00133 struct proc_ar5k_ar5212_priv *pv = 0;
00134 struct proc_dir_entry *dp = PDE(inode);
00135 struct ath_hal *hal = dp->data;
00136
00137 if (!(file->private_data = kmalloc(sizeof(struct proc_ar5k_ar5212_priv), GFP_KERNEL)))
00138 return -ENOMEM;
00139
00140 pv = (struct proc_ar5k_ar5212_priv *) file->private_data;
00141 memset(pv, 0, sizeof(struct proc_ar5k_ar5212_priv));
00142 pv->rbuf = vmalloc(MAX_PROC_AR5K_AR5212_SIZE);
00143 if (!pv->rbuf) {
00144 vfree(pv);
00145 return -ENOMEM;
00146 }
00147 pv->wbuf = vmalloc(MAX_PROC_AR5K_AR5212_SIZE);
00148 if (!pv->wbuf) {
00149 vfree(pv->rbuf);
00150 kfree(pv);
00151 return -ENOMEM;
00152 }
00153 memset(pv->wbuf, 0, MAX_PROC_AR5K_AR5212_SIZE);
00154 memset(pv->rbuf, 0, MAX_PROC_AR5K_AR5212_SIZE);
00155 pv->max_wlen = MAX_PROC_AR5K_AR5212_SIZE;
00156 pv->max_rlen = MAX_PROC_AR5K_AR5212_SIZE;
00157
00158 pv->rlen = ar5k_ar5212_proc_read_reg(hal, pv->rbuf, MAX_PROC_AR5K_AR5212_SIZE);
00159 return 0;
00160 }
00161
00162 static int
00163 proc_ar5k_ar5212_write(struct file *file, const char *buf, size_t len, loff_t *offset)
00164 {
00165 loff_t pos = *offset;
00166 struct proc_ar5k_ar5212_priv *pv = (struct proc_ar5k_ar5212_priv *) file->private_data;
00167
00168 if (!pv->wbuf)
00169 return -EINVAL;
00170 if (pos < 0)
00171 return -EINVAL;
00172 if (pos >= pv->max_wlen)
00173 return 0;
00174 if (len > pv->max_wlen - pos)
00175 len = pv->max_wlen - pos;
00176 if (copy_from_user(pv->wbuf + pos, buf, len))
00177 return -EFAULT;
00178 if (pos + len > pv->wlen)
00179 pv->wlen = pos + len;
00180 *offset = pos + len;
00181
00182 return len;
00183 }
00184
00185 static int proc_ar5k_ar5212_close(struct inode *inode, struct file *file) {
00186
00187 struct proc_ar5k_ar5212_priv *pv = (struct proc_ar5k_ar5212_priv *) file->private_data;
00188 struct proc_dir_entry *dp = PDE(inode);
00189 struct ath_hal *hal = (struct ath_hal *) dp->data;
00190 char *p = pv->wbuf;
00191
00192 if (pv->wlen) {
00193
00194 while (p[0] && p >= pv->wbuf && p < pv->wbuf + pv->max_wlen) {
00195 u_int32_t reg;
00196 u_int32_t value;
00197 reg = simple_strtol(p, NULL, 0);
00198
00199
00200 while (p[0] && p[0] != '\n' && p[0] != 32)
00201 p++;
00202
00203
00204 while (p[0] && p[0] == 32) {
00205 p++;
00206 }
00207
00208 value = simple_strtol(p, NULL, 0);
00209
00210 AR5K_REG_WRITE(reg, value);
00211
00212 while (p[0] && p[0] != '\n')
00213 p++;
00214 if (p[0])
00215 p++;
00216 }
00217 }
00218 if (pv->rbuf)
00219 vfree(pv->rbuf);
00220 if (pv->wbuf)
00221 vfree(pv->wbuf);
00222 kfree(pv);
00223 return 0;
00224
00225 }
00226
00227 static struct file_operations proc_sib_ops = {
00228 .read = proc_ar5k_ar5212_read,
00229 .write = proc_ar5k_ar5212_write,
00230 .open = proc_ar5k_ar5212_open,
00231 .release = proc_ar5k_ar5212_close,
00232 };
00233
00234
00235 struct ath_hal *
00236 ar5k_ar5212_attach(u_int16_t device, void *sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status)
00237 {
00238 struct ath_hal *hal = (struct ath_hal*) sc;
00239 u_int8_t mac[IEEE80211_ADDR_LEN];
00240 u_int32_t srev;
00241
00242 AR5K_TRACE;
00243
00244 ar5k_ar5212_fill(hal);
00245
00246
00247 if (ar5k_ar5212_nic_wakeup(hal, AR5K_INIT_MODE) != AH_TRUE)
00248 return (0);
00249
00250
00251 srev = AR5K_REG_READ(AR5K_AR5212_SREV);
00252 hal->ah_macVersion = AR5K_REG_MS(srev, AR5K_AR5212_SREV_VER);
00253 hal->ah_macRev = AR5K_REG_MS(srev, AR5K_AR5212_SREV_REV);
00254 hal->ah_phyRev = AR5K_REG_READ(AR5K_AR5212_PHY_CHIP_ID) &
00255 0x00ffffffff;
00256
00257 hal->ah_analog5GhzRev =
00258 ar5k_ar5212_radio_revision(hal, HAL_CHIP_5GHZ);
00259
00260
00261 if (hal->ah_macVersion >= AR5K_SREV_VER_AR5211)
00262 hal->ah_analog2GhzRev =
00263 ar5k_ar5212_radio_revision(hal, HAL_CHIP_2GHZ);
00264
00265
00266 hal->ah_version = AR5K_AR5212;
00267 hal->ah_radio = hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112 ?
00268 AR5K_AR5111 : AR5K_AR5112;
00269 hal->ah_phy = AR5K_AR5212_PHY(0);
00270
00271 memset(mac, 0xff, IEEE80211_ADDR_LEN);
00272 ar5k_ar5212_set_associd(hal, mac, 0);
00273 ar5k_ar5212_get_lladdr(hal, mac);
00274 ar5k_ar5212_set_opmode(hal);
00275
00276 if (!proc_hal) {
00277 if ((proc_hal = proc_mkdir ("hal", NULL)) == NULL) {
00278 printk("unable to create /proc/net/hal\n");
00279 } else {
00280 proc_hal_reg = create_proc_entry("reg", 0644, proc_hal);
00281 proc_hal_reg->data = hal;
00282 proc_hal_reg->proc_fops = &proc_sib_ops;
00283 }
00284 }
00285 return (hal);
00286 }
00287
00288 HAL_BOOL
00289 ar5k_ar5212_nic_reset(struct ath_hal *hal, u_int32_t val)
00290 {
00291 HAL_BOOL ret = AH_FALSE;
00292 u_int32_t mask = val ? val : ~0;
00293 AR5K_TRACE;
00294
00295
00296 AR5K_REG_READ(AR5K_AR5212_RXDP);
00297
00298
00299
00300
00301 AR5K_REG_WRITE(AR5K_AR5212_RC, val);
00302
00303
00304 AR5K_DELAY(15);
00305
00306 val &=
00307 AR5K_AR5212_RC_PCU | AR5K_AR5212_RC_BB;
00308
00309 mask &=
00310 AR5K_AR5212_RC_PCU | AR5K_AR5212_RC_BB;
00311
00312 ret = ar5k_register_timeout(hal, AR5K_AR5212_RC, mask, val, AH_FALSE);
00313
00314
00315
00316
00317 if ((val & AR5K_AR5212_RC_PCU) == 0)
00318 AR5K_REG_WRITE(AR5K_AR5212_CFG, AR5K_AR5212_INIT_CFG);
00319
00320 return (ret);
00321 }
00322
00323 HAL_BOOL
00324 ar5k_ar5212_nic_wakeup(struct ath_hal *hal, u_int16_t flags)
00325 {
00326 u_int32_t turbo, mode, clock;
00327
00328 turbo = 0;
00329 mode = 0;
00330 clock = 0;
00331
00332
00333
00334
00335
00336 if (hal->ah_radio >= AR5K_AR5112) {
00337 mode = AR5K_AR5212_PHY_MODE_RAD_AR5112;
00338 clock = AR5K_AR5212_PHY_PLL_AR5112;
00339 } else {
00340 mode = AR5K_AR5212_PHY_MODE_RAD_AR5111;
00341 clock = AR5K_AR5212_PHY_PLL_AR5111;
00342 }
00343
00344 if (flags & IEEE80211_CHAN_2GHZ) {
00345 mode |= AR5K_AR5212_PHY_MODE_FREQ_2GHZ;
00346 clock |= AR5K_AR5212_PHY_PLL_44MHZ;
00347 } else if (flags & IEEE80211_CHAN_5GHZ) {
00348 mode |= AR5K_AR5212_PHY_MODE_FREQ_5GHZ;
00349 clock |= AR5K_AR5212_PHY_PLL_40MHZ;
00350 } else {
00351 AR5K_PRINT("invalid radio frequency mode\n");
00352 return (AH_FALSE);
00353 }
00354
00355 if (flags & IEEE80211_CHAN_CCK) {
00356 mode |= AR5K_AR5212_PHY_MODE_MOD_CCK;
00357 } else if (flags & IEEE80211_CHAN_OFDM) {
00358 mode |= AR5K_AR5212_PHY_MODE_MOD_OFDM;
00359 } else if (flags & IEEE80211_CHAN_DYN) {
00360 mode |= AR5K_AR5212_PHY_MODE_MOD_DYN;
00361 } else {
00362 AR5K_PRINT("invalid radio frequency mode\n");
00363 return (AH_FALSE);
00364 }
00365
00366 if (flags & IEEE80211_CHAN_TURBO) {
00367 turbo = AR5K_AR5212_PHY_TURBO_MODE |
00368 AR5K_AR5212_PHY_TURBO_SHORT;
00369 }
00370
00371
00372
00373
00374
00375
00376 if (ar5k_ar5212_nic_reset(hal,
00377 AR5K_AR5212_RC_CHIP | AR5K_AR5212_RC_PCI) == AH_FALSE) {
00378 AR5K_PRINT("failed to reset the AR5212 + PCI chipset\n");
00379 return (AH_FALSE);
00380 }
00381
00382
00383 if (ar5k_ar5212_set_power(hal,
00384 HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) {
00385 AR5K_PRINT("failed to resume the AR5212 (again)\n");
00386 return (AH_FALSE);
00387 }
00388
00389
00390 if (ar5k_ar5212_nic_reset(hal, 0) == AH_FALSE) {
00391 AR5K_PRINT("failed to warm reset the AR5212\n");
00392 return (AH_FALSE);
00393 }
00394
00395
00396 AR5K_REG_WRITE(AR5K_AR5212_PHY_PLL, clock);
00397 AR5K_DELAY(300);
00398
00399 AR5K_REG_WRITE(AR5K_AR5212_PHY_MODE, mode);
00400 AR5K_REG_WRITE(AR5K_AR5212_PHY_TURBO, turbo);
00401
00402 return (AH_TRUE);
00403 }
00404
00405 u_int16_t
00406 ar5k_ar5212_radio_revision(struct ath_hal *hal, HAL_CHIP chip)
00407 {
00408 int i;
00409 u_int32_t srev;
00410 u_int16_t ret;
00411 AR5K_TRACE;
00412
00413
00414
00415
00416 switch (chip) {
00417 case HAL_CHIP_2GHZ:
00418 AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_2GHZ);
00419 break;
00420 case HAL_CHIP_5GHZ:
00421 AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);
00422 break;
00423 default:
00424 printk("%s: bad radio revision?\n", __func__);
00425 return (0);
00426 }
00427
00428 AR5K_DELAY(2000);
00429
00430
00431 AR5K_REG_WRITE(AR5K_AR5212_PHY(0x34), 0x00001c16);
00432
00433 for (i = 0; i < 8; i++)
00434 AR5K_REG_WRITE(AR5K_AR5212_PHY(0x20), 0x00010000);
00435 srev = (AR5K_REG_READ(AR5K_AR5212_PHY(0x100)) >> 24) & 0xff;
00436
00437 ret = ar5k_bitswap(((srev & 0xf0) >> 4) | ((srev & 0x0f) << 4), 8);
00438
00439
00440 AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);
00441
00442 return (ret);
00443 }
00444
00445 const HAL_RATE_TABLE *
00446 ar5k_ar5212_get_rate_table(struct ath_hal *hal, u_int mode)
00447 {
00448 AR5K_TRACE;
00449
00450 switch (mode) {
00451 case HAL_MODE_11A:
00452 return (&hal->ah_rt_11a);
00453 case HAL_MODE_TURBO:
00454 return (&hal->ah_rt_turbo);
00455 case HAL_MODE_11B:
00456 return (&hal->ah_rt_11b);
00457 case HAL_MODE_11G:
00458 return (&hal->ah_rt_11g);
00459 case HAL_MODE_108G:
00460 return (&hal->ah_rt_turbo);
00461 case HAL_MODE_XR:
00462 return (&hal->ah_rt_xr);
00463 default:
00464 return (NULL);
00465 }
00466
00467 return (NULL);
00468 }
00469
00470 void
00471 ar5k_ar5212_detach(struct ath_hal *hal)
00472 {
00473 AR5K_TRACE;
00474 if (proc_hal != NULL) {
00475 remove_proc_entry("reg", proc_hal);
00476 remove_proc_entry("hal", NULL);
00477 proc_hal = NULL;
00478 }
00479 if (hal->ah_rf_banks != 0)
00480 kfree(hal->ah_rf_banks);
00481
00482
00483
00484 kfree(hal);
00485 }
00486
00487 HAL_BOOL
00488 ar5k_ar5212_reset(struct ath_hal *hal,
00489 HAL_OPMODE op_mode,
00490 HAL_CHANNEL *channel,
00491 HAL_BOOL change_channel,
00492 HAL_STATUS *status)
00493 {
00494 AR5K_TRACE;
00495 struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
00496 u_int8_t mac[IEEE80211_ADDR_LEN];
00497 u_int32_t data, s_seq, s_ant, s_led[3];
00498 u_int i, phy, mode, freq, off, ee_mode, ant[2];
00499 const HAL_RATE_TABLE *rt;
00500 AR5K_TRACE;
00501
00502 *status = 0;
00503 if (!channel) {
00504 AR5K_TRACE;
00505 printk("%s: no channel!\n", __func__);
00506 }
00507
00508
00509
00510
00511 if (change_channel == AH_TRUE) {
00512 s_seq = AR5K_REG_READ(AR5K_AR5212_DCU_SEQNUM(0));
00513 s_ant = AR5K_REG_READ(AR5K_AR5212_DEFAULT_ANTENNA);
00514 } else {
00515 s_seq = 0;
00516 s_ant = 1;
00517 }
00518
00519 s_led[0] = AR5K_REG_READ(AR5K_AR5212_PCICFG) &
00520 AR5K_AR5212_PCICFG_LEDSTATE;
00521 s_led[1] = AR5K_REG_READ(AR5K_AR5212_GPIOCR);
00522 s_led[2] = AR5K_REG_READ(AR5K_AR5212_GPIODO);
00523
00524 if (change_channel == AH_TRUE && hal->ah_rf_banks != NULL)
00525 ar5k_ar5212_get_rf_gain(hal);
00526
00527 if (ar5k_ar5212_nic_wakeup(hal, channel->channelFlags) == AH_FALSE) {
00528 AR5K_TRACE;
00529 return (AH_FALSE);
00530 }
00531
00532
00533
00534
00535 hal->ah_op_mode = op_mode;
00536
00537 if (hal->ah_radio == AR5K_AR5111) {
00538 phy = AR5K_INI_PHY_5111;
00539 } else if (hal->ah_radio == AR5K_AR5112) {
00540 phy = AR5K_INI_PHY_5112;
00541 } else {
00542 AR5K_PRINTF("invalid phy radio: %u\n", hal->ah_radio);
00543 return (AH_FALSE);
00544 }
00545
00546 if (channel->channelFlags & IEEE80211_CHAN_A) {
00547 mode = AR5K_INI_VAL_11A;
00548 freq = AR5K_INI_RFGAIN_5GHZ;
00549 ee_mode = AR5K_EEPROM_MODE_11A;
00550 } else if (channel->channelFlags & IEEE80211_CHAN_T) {
00551 mode = AR5K_INI_VAL_11A_TURBO;
00552 freq = AR5K_INI_RFGAIN_5GHZ;
00553 ee_mode = AR5K_EEPROM_MODE_11A;
00554 } else if (channel->channelFlags & IEEE80211_CHAN_B) {
00555 mode = AR5K_INI_VAL_11B;
00556 freq = AR5K_INI_RFGAIN_2GHZ;
00557 ee_mode = AR5K_EEPROM_MODE_11B;
00558 } else if (channel->channelFlags & IEEE80211_CHAN_G) {
00559 mode = AR5K_INI_VAL_11G;
00560 freq = AR5K_INI_RFGAIN_2GHZ;
00561 ee_mode = AR5K_EEPROM_MODE_11G;
00562 } else if (channel->channelFlags & IEEE80211_CHAN_108G) {
00563 mode = AR5K_INI_VAL_11G_TURBO;
00564 freq = AR5K_INI_RFGAIN_2GHZ;
00565 ee_mode = AR5K_EEPROM_MODE_11G;
00566 } else if (channel->channelFlags & IEEE80211_CHAN_XR) {
00567 mode = AR5K_INI_VAL_XR;
00568 freq = AR5K_INI_RFGAIN_5GHZ;
00569 ee_mode = AR5K_EEPROM_MODE_11A;
00570 } else {
00571 AR5K_PRINTF("invalid channel: %d\n", channel->channel);
00572 *status = HAL_EINVAL;
00573 return (AH_FALSE);
00574 }
00575
00576
00577 AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);
00578
00579
00580
00581
00582 for (i = 0; i < AR5K_ELEMENTS(ar5212_mode); i++) {
00583 if (ar5212_mode[i].mode_flags == AR5K_INI_FLAG_511X)
00584 off = AR5K_INI_PHY_511X;
00585 else if (ar5212_mode[i].mode_flags & AR5K_INI_FLAG_5111 &&
00586 hal->ah_radio == AR5K_AR5111)
00587 off = AR5K_INI_PHY_5111;
00588 else if (ar5212_mode[i].mode_flags & AR5K_INI_FLAG_5112 &&
00589 hal->ah_radio == AR5K_AR5112)
00590 off = AR5K_INI_PHY_5112;
00591 else
00592 continue;
00593
00594 AR5K_REG_WAIT(i);
00595 AR5K_REG_WRITE((u_int32_t)ar5212_mode[i].mode_register,
00596 ar5212_mode[i].mode_value[off][mode]);
00597 }
00598
00599
00600
00601
00602 for (i = 0; i < AR5K_ELEMENTS(ar5212_ini); i++) {
00603 if (change_channel == AH_TRUE &&
00604 ar5212_ini[i].ini_register >= AR5K_AR5212_PCU_MIN &&
00605 ar5212_ini[i].ini_register <= AR5K_AR5212_PCU_MAX)
00606 continue;
00607
00608 if ((hal->ah_radio == AR5K_AR5111 &&
00609 ar5212_ini[i].ini_flags & AR5K_INI_FLAG_5111) ||
00610 (hal->ah_radio == AR5K_AR5112 &&
00611 ar5212_ini[i].ini_flags & AR5K_INI_FLAG_5112)) {
00612 AR5K_REG_WAIT(i);
00613 AR5K_REG_WRITE((u_int32_t)ar5212_ini[i].ini_register,
00614 ar5212_ini[i].ini_value);
00615 }
00616 }
00617
00618
00619
00620
00621 if (ar5k_rfgain(hal, phy, freq) == AH_FALSE) {
00622 *status = HAL_EINVAL;
00623 return (AH_FALSE);
00624 }
00625
00626 AR5K_DELAY(1000);
00627
00628
00629
00630
00631 rt = ar5k_ar5212_get_rate_table(hal,
00632 channel->c_channel_flags & IEEE80211_CHAN_TURBO ?
00633 HAL_MODE_TURBO : HAL_MODE_XR);
00634
00635 if (!rt) {
00636 AR5K_TRACE;
00637 printk("%s: no rate table!\n", __func__);
00638 *status = HAL_EINVAL;
00639 return (AH_FALSE);
00640 }
00641 for (i = 0; i < rt->rateCount; i++) {
00642 AR5K_REG_WRITE(AR5K_AR5212_RATE_DUR(rt->info[i].r_rate_code),
00643 ath_hal_computetxtime(hal, rt, 14,
00644 rt->info[i].r_control_rate, AH_FALSE));
00645 }
00646
00647 if (!(channel->channelFlags & IEEE80211_CHAN_TURBO)) {
00648 rt = ar5k_ar5212_get_rate_table(hal, HAL_MODE_11B);
00649 for (i = 0; i < rt->rateCount; i++) {
00650 data = AR5K_AR5212_RATE_DUR(rt->info[i].r_rate_code);
00651 AR5K_REG_WRITE(data,
00652 ath_hal_computetxtime(hal, rt, 14,
00653 rt->info[i].r_control_rate, AH_FALSE));
00654 if (rt->info[i].r_short_preamble) {
00655 AR5K_REG_WRITE(data +
00656 (rt->info[i].r_short_preamble << 2),
00657 ath_hal_computetxtime(hal, rt, 14,
00658 rt->info[i].r_control_rate, AH_FALSE));
00659 }
00660 }
00661 }
00662
00663
00664
00665
00666 if (ar5k_ar5212_txpower(hal, channel,
00667 AR5K_TUNE_DEFAULT_TXPOWER) == AH_FALSE) {
00668 *status = HAL_EINVAL;
00669 return (AH_FALSE);
00670 }
00671
00672
00673
00674
00675 if (ar5k_rfregs(hal, channel, mode) == AH_FALSE) {
00676 *status = HAL_EINVAL;
00677 return (AH_FALSE);
00678 }
00679
00680
00681
00682
00683
00684
00685 if (channel->channelFlags & IEEE80211_CHAN_OFDM) {
00686 u_int32_t coef_scaled, coef_exp, coef_man, ds_coef_exp,
00687 ds_coef_man, clock;
00688
00689 clock = channel->channelFlags & IEEE80211_CHAN_T ? 80 : 40;
00690 coef_scaled = ((5 * (clock << 24)) / 2) / channel->channel;
00691
00692 for (coef_exp = 31; coef_exp > 0; coef_exp--)
00693 if ((coef_scaled >> coef_exp) & 0x1)
00694 break;
00695
00696 if (!coef_exp) {
00697 *status = HAL_EINVAL;
00698 return (AH_FALSE);
00699 }
00700
00701 coef_exp = 14 - (coef_exp - 24);
00702 coef_man = coef_scaled + (1 << (24 - coef_exp - 1));
00703 ds_coef_man = coef_man >> (24 - coef_exp);
00704 ds_coef_exp = coef_exp - 16;
00705
00706 AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_TIMING_3,
00707 AR5K_AR5212_PHY_TIMING_3_DSC_MAN, ds_coef_man);
00708 AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_TIMING_3,
00709 AR5K_AR5212_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
00710 }
00711
00712 if (hal->ah_radio == AR5K_AR5111) {
00713 if (channel->channelFlags & IEEE80211_CHAN_B)
00714 AR5K_REG_ENABLE_BITS(AR5K_AR5212_TXCFG,
00715 AR5K_AR5212_TXCFG_B_MODE);
00716 else
00717 AR5K_REG_DISABLE_BITS(AR5K_AR5212_TXCFG,
00718 AR5K_AR5212_TXCFG_B_MODE);
00719 }
00720
00721
00722 AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x44),
00723 hal->ah_antenna[ee_mode][0], 0xfffffc06);
00724
00725 ant[0] = HAL_ANT_FIXED_A;
00726 ant[1] = HAL_ANT_FIXED_B;
00727
00728 if (hal->ah_ant_diversity == AH_FALSE) {
00729 if (freq == AR5K_INI_RFGAIN_2GHZ)
00730 ant[0] = HAL_ANT_FIXED_B;
00731 else
00732 ant[1] = HAL_ANT_FIXED_A;
00733 }
00734
00735 AR5K_REG_WRITE(AR5K_AR5212_PHY_ANT_SWITCH_TABLE_0,
00736 hal->ah_antenna[ee_mode][ant[0]]);
00737 AR5K_REG_WRITE(AR5K_AR5212_PHY_ANT_SWITCH_TABLE_1,
00738 hal->ah_antenna[ee_mode][ant[1]]);
00739
00740
00741 if (hal->ah_radio == AR5K_AR5111)
00742 AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_FC,
00743 AR5K_AR5212_PHY_FC_TX_CLIP, ee->ee_tx_clip);
00744
00745 AR5K_REG_WRITE(AR5K_AR5212_PHY(0x5a),
00746 AR5K_AR5212_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]));
00747
00748 AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x11),
00749 (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80, 0xffffc07f);
00750 AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x12),
00751 (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000, 0xfffc0fff);
00752 AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x14),
00753 (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
00754 ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00), 0xffff0000);
00755
00756 AR5K_REG_WRITE(AR5K_AR5212_PHY(0x0d),
00757 (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
00758 (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
00759 (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
00760 (ee->ee_tx_frm2xpa_enable[ee_mode]));
00761
00762 AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x0a),
00763 ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
00764 AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x19),
00765 (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
00766 AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x49), 4, 0xffffff01);
00767
00768 AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_IQ,
00769 AR5K_AR5212_PHY_IQ_CORR_ENABLE |
00770 (ee->ee_i_cal[ee_mode] << AR5K_AR5212_PHY_IQ_CORR_Q_I_COFF_S) |
00771 ee->ee_q_cal[ee_mode]);
00772
00773 if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
00774 AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_GAIN_2GHZ,
00775 AR5K_AR5212_PHY_GAIN_2GHZ_MARGIN_TXRX,
00776 ee->ee_margin_tx_rx[ee_mode]);
00777 }
00778
00779
00780
00781
00782 AR5K_REG_WRITE(AR5K_AR5212_DCU_SEQNUM(0), s_seq);
00783 AR5K_REG_WRITE(AR5K_AR5212_DEFAULT_ANTENNA, s_ant);
00784 AR5K_REG_ENABLE_BITS(AR5K_AR5212_PCICFG, s_led[0]);
00785 AR5K_REG_WRITE(AR5K_AR5212_GPIOCR, s_led[1]);
00786 AR5K_REG_WRITE(AR5K_AR5212_GPIODO, s_led[2]);
00787
00788
00789
00790
00791 memset(mac, 0xff, IEEE80211_ADDR_LEN);
00792 ar5k_ar5212_set_associd(hal, mac, 0);
00793 ar5k_ar5212_set_opmode(hal);
00794 AR5K_REG_WRITE(AR5K_AR5212_PISR, 0xffffffff);
00795 AR5K_REG_WRITE(AR5K_AR5212_RSSI_THR, AR5K_TUNE_RSSI_THRES);
00796
00797
00798
00799
00800 AR5K_REG_WRITE_BITS(AR5K_AR5212_TXCFG, AR5K_AR5212_TXCFG_SDMAMR,
00801 AR5K_AR5212_DMASIZE_512B | AR5K_AR5212_TXCFG_DMASIZE);
00802 AR5K_REG_WRITE_BITS(AR5K_AR5212_RXCFG, AR5K_AR5212_RXCFG_SDMAMW,
00803 AR5K_AR5212_DMASIZE_512B);
00804
00805
00806
00807
00808 if (ar5k_channel(hal, channel) == AH_FALSE)
00809 return (AH_FALSE);
00810
00811
00812
00813
00814 AR5K_REG_WRITE(AR5K_AR5212_PHY_ACTIVE, AR5K_AR5212_PHY_ENABLE);
00815
00816 data = AR5K_REG_READ(AR5K_AR5212_PHY_RX_DELAY) &
00817 AR5K_AR5212_PHY_RX_DELAY_M;
00818 data = (channel->channelFlags & IEEE80211_CHAN_CCK) ?
00819 ((data << 2) / 22) : (data / 10);
00820
00821 AR5K_DELAY(100 + data);
00822
00823
00824
00825
00826 AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_AGCCTL,
00827 AR5K_AR5212_PHY_AGCCTL_NF |
00828 AR5K_AR5212_PHY_AGCCTL_CAL);
00829
00830 if (channel->channelFlags & IEEE80211_CHAN_B) {
00831 hal->ah_calibration = AH_FALSE;
00832 } else {
00833 hal->ah_calibration = AH_TRUE;
00834 AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_IQ,
00835 AR5K_AR5212_PHY_IQ_CAL_NUM_LOG_MAX, 15);
00836 AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_IQ,
00837 AR5K_AR5212_PHY_IQ_RUN);
00838 }
00839
00840
00841
00842
00843 for (i = 0; i < hal->ah_capabilities.cap_queues.q_tx_num; i++) {
00844 AR5K_REG_WRITE_Q(AR5K_AR5212_DCU_QCUMASK(i), i);
00845 if (ar5k_ar5212_reset_tx_queue(hal, i) == AH_FALSE) {
00846 AR5K_PRINTF("failed to reset TX queue #%d\n", i);
00847 *status = HAL_EINVAL;
00848 return (AH_FALSE);
00849 }
00850 }
00851
00852
00853 ar5k_ar5212_set_intr(hal, HAL_INT_RX | HAL_INT_TX | HAL_INT_FATAL);
00854
00855
00856
00857
00858 if (AR5K_EEPROM_HDR_RFKILL(hal->ah_capabilities.cap_eeprom.ee_header)) {
00859 ar5k_ar5212_set_gpio_input(hal, 0);
00860 if ((hal->ah_gpio[0] = ar5k_ar5212_get_gpio(hal, 0)) == 0)
00861 ar5k_ar5212_set_gpio_intr(hal, 0, 1);
00862 else
00863 ar5k_ar5212_set_gpio_intr(hal, 0, 0);
00864 }
00865
00866
00867
00868
00869 AR5K_REG_WRITE(AR5K_AR5212_PHY_SCR, AR5K_AR5212_PHY_SCR_32MHZ);
00870 AR5K_REG_WRITE(AR5K_AR5212_PHY_SLMT, AR5K_AR5212_PHY_SLMT_32MHZ);
00871 AR5K_REG_WRITE(AR5K_AR5212_PHY_SCAL, AR5K_AR5212_PHY_SCAL_32MHZ);
00872 AR5K_REG_WRITE(AR5K_AR5212_PHY_SCLOCK, AR5K_AR5212_PHY_SCLOCK_32MHZ);
00873 AR5K_REG_WRITE(AR5K_AR5212_PHY_SDELAY, AR5K_AR5212_PHY_SDELAY_32MHZ);
00874 AR5K_REG_WRITE(AR5K_AR5212_PHY_SPENDING, hal->ah_radio == AR5K_AR5111 ?
00875 AR5K_AR5212_PHY_SPENDING_AR5111 : AR5K_AR5212_PHY_SPENDING_AR5112);
00876
00877
00878
00879
00880 AR5K_REG_DISABLE_BITS(AR5K_AR5212_BEACON,
00881 AR5K_AR5212_BEACON_ENABLE | AR5K_AR5212_BEACON_RESET_TSF);
00882
00883 return (AH_TRUE);
00884 }
00885
00886 HAL_BOOL
00887 ar5k_ar5212_phy_disable(struct ath_hal *hal)
00888 {
00889 AR5K_TRACE;
00890
00891 return AH_TRUE;
00892 }
00893
00894 void
00895 ar5k_ar5212_set_opmode(struct ath_hal *hal)
00896 {
00897 u_int32_t pcu_reg, low_id, high_id;
00898 AR5K_TRACE;
00899
00900 pcu_reg = 0;
00901
00902 switch (hal->ah_op_mode) {
00903 case IEEE80211_M_IBSS:
00904 pcu_reg |= AR5K_AR5212_STA_ID1_ADHOC |
00905 AR5K_AR5212_STA_ID1_DESC_ANTENNA;
00906 break;
00907
00908 case IEEE80211_M_HOSTAP:
00909 pcu_reg |= AR5K_AR5212_STA_ID1_AP |
00910 AR5K_AR5212_STA_ID1_RTS_DEFAULT_ANTENNA;
00911 break;
00912
00913 case IEEE80211_M_STA:
00914 case IEEE80211_M_MONITOR:
00915 pcu_reg |= AR5K_AR5212_STA_ID1_DEFAULT_ANTENNA;
00916 break;
00917
00918 default:
00919 return;
00920 }
00921
00922
00923
00924
00925 bcopy(&(hal->ah_sta_id[0]), &low_id, 4);
00926 bcopy(&(hal->ah_sta_id[4]), &high_id, 2);
00927 AR5K_REG_WRITE(AR5K_AR5212_STA_ID0, low_id);
00928 AR5K_REG_WRITE(AR5K_AR5212_STA_ID1, pcu_reg | high_id);
00929
00930 return;
00931 }
00932
00933 HAL_BOOL
00934 ar5k_ar5212_calibrate(struct ath_hal *hal,
00935 HAL_CHANNEL *channel)
00936 {
00937 u_int32_t i_pwr, q_pwr;
00938 int32_t iq_corr, i_coff, i_coffd, q_coff, q_coffd;
00939 AR5K_TRACE;
00940
00941 if (hal->ah_calibration == AH_FALSE ||
00942 AR5K_REG_READ(AR5K_AR5212_PHY_IQ) & AR5K_AR5212_PHY_IQ_RUN)
00943 goto done;
00944
00945 hal->ah_calibration = AH_FALSE;
00946
00947 iq_corr = AR5K_REG_READ(AR5K_AR5212_PHY_IQRES_CAL_CORR);
00948 i_pwr = AR5K_REG_READ(AR5K_AR5212_PHY_IQRES_CAL_PWR_I);
00949 q_pwr = AR5K_REG_READ(AR5K_AR5212_PHY_IQRES_CAL_PWR_Q);
00950 i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
00951 q_coffd = q_pwr >> 6;
00952
00953 if (i_coffd == 0 || q_coffd == 0)
00954 goto done;
00955
00956 i_coff = ((-iq_corr) / i_coffd) & 0x3f;
00957 q_coff = (((int32_t)i_pwr / q_coffd) - 64) & 0x1f;
00958
00959
00960 AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_IQ,
00961 AR5K_AR5212_PHY_IQ_CORR_ENABLE |
00962 ((u_int32_t)q_coff) |
00963 ((u_int32_t)i_coff << AR5K_AR5212_PHY_IQ_CORR_Q_I_COFF_S));
00964
00965 done:
00966
00967 AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_AGCCTL,
00968 AR5K_AR5212_PHY_AGCCTL_NF);
00969
00970
00971 if (channel->channelFlags & IEEE80211_CHAN_5GHZ) {
00972 AR5K_REG_WRITE(AR5K_AR5212_PHY_PAPD_PROBE,
00973 AR5K_REG_SM(hal->ah_txpower.txp_max,
00974 AR5K_AR5212_PHY_PAPD_PROBE_TXPOWER) |
00975 AR5K_AR5212_PHY_PAPD_PROBE_TX_NEXT);
00976 hal->ah_rf_gain = HAL_RFGAIN_READ_REQUESTED;
00977 }
00978
00979 return (AH_TRUE);
00980 }
00981
00982 HAL_BOOL
00983 ar5k_ar5212_set_txpower_limit(struct ath_hal *hal, u_int32_t power)
00984 {
00985 AR5K_TRACE;
00986
00987
00988 return (AH_FALSE);
00989 }
00990
00991
00992
00993
00994
00995 HAL_BOOL
00996 ar5k_ar5212_update_tx_triglevel(struct ath_hal *hal, HAL_BOOL increase)
00997 {
00998 u_int32_t trigger_level, imr;
00999 HAL_BOOL status = AH_FALSE;
01000 AR5K_TRACE;
01001
01002
01003
01004
01005 imr = ar5k_ar5212_set_intr(hal, hal->ah_imr & ~HAL_INT_GLOBAL);
01006
01007 trigger_level = AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5212_TXCFG),
01008 AR5K_AR5212_TXCFG_TXFULL);
01009
01010 if (increase == AH_FALSE) {
01011 if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
01012 goto done;
01013 } else
01014 trigger_level +=
01015 ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
01016
01017
01018
01019
01020 AR5K_REG_WRITE_BITS(AR5K_AR5212_TXCFG,
01021 AR5K_AR5212_TXCFG_TXFULL, trigger_level);
01022 status = AH_TRUE;
01023
01024 done:
01025
01026
01027
01028 ar5k_ar5212_set_intr(hal, imr);
01029
01030 return (status);
01031 }
01032
01033 int
01034 ar5k_ar5212_setup_tx_queue(struct ath_hal *hal,
01035 HAL_TX_QUEUE queue_type,
01036 const HAL_TXQ_INFO *queue_info)
01037 {
01038 u_int queue;
01039 AR5K_TRACE;
01040
01041
01042
01043
01044 if (queue_type == HAL_TX_QUEUE_DATA) {
01045 for (queue = HAL_TX_QUEUE_ID_DATA_MIN;
01046 hal->ah_txq[queue].tqi_type != HAL_TX_QUEUE_INACTIVE;
01047 queue++)
01048 if (queue > HAL_TX_QUEUE_ID_DATA_MAX)
01049 return (-1);
01050 } else if (queue_type == HAL_TX_QUEUE_PSPOLL) {
01051 queue = HAL_TX_QUEUE_ID_PSPOLL;
01052 } else if (queue_type == HAL_TX_QUEUE_BEACON) {
01053 queue = HAL_TX_QUEUE_ID_BEACON;
01054 } else if (queue_type == HAL_TX_QUEUE_CAB) {
01055 queue = HAL_TX_QUEUE_ID_CAB;
01056 } else
01057 return (-1);
01058
01059
01060
01061
01062 bzero(&hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));
01063 hal->ah_txq[queue].tqi_type = queue_type;
01064
01065 if (queue_info != NULL) {
01066 if (ar5k_ar5212_setup_tx_queueprops(hal, queue, queue_info)
01067 != AH_TRUE)
01068 return (-1);
01069 }
01070
01071 AR5K_Q_ENABLE_BITS(hal->ah_txq_interrupts, queue);
01072
01073 return (queue);
01074 }
01075
01076 HAL_BOOL
01077 ar5k_ar5212_setup_tx_queueprops(struct ath_hal *hal,
01078 int queue,
01079 const HAL_TXQ_INFO *queue_info)
01080 {
01081 AR5K_TRACE;
01082 AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
01083
01084 if (hal->ah_txq[queue].tqi_type == HAL_TX_QUEUE_INACTIVE)
01085 return (AH_FALSE);
01086
01087 int type = hal->ah_txq[queue].tqi_type;
01088 bcopy(queue_info, &hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));
01089 hal->ah_txq[queue].tqi_type = type;
01090
01091 if (queue_info->tqi_type == HAL_TX_QUEUE_DATA &&
01092 (queue_info->tqi_subtype >= HAL_WME_AC_VI) &&
01093 (queue_info->tqi_subtype <= HAL_WME_UPSD))
01094 hal->ah_txq[queue].tqi_qflags |=
01095 TXQ_FLAG_POST_FR_BKOFF_DIS;
01096
01097 return (AH_TRUE);
01098 }
01099
01100 HAL_BOOL
01101 ar5k_ar5212_get_tx_queueprops(struct ath_hal *hal, int queue, HAL_TXQ_INFO *queue_info)
01102 {
01103 HAL_TXQ_INFO *tq = &hal->ah_txq[queue];
01104 AR5K_TRACE;
01105 memcpy(queue_info, tq, sizeof(HAL_TXQ_INFO));
01106 return (AH_TRUE);
01107 }
01108
01109 HAL_BOOL
01110 ar5k_ar5212_release_tx_queue(struct ath_hal *hal, u_int queue)
01111 {
01112
01113 AR5K_TRACE;
01114
01115 AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
01116
01117
01118 hal->ah_txq[queue].tqi_type = HAL_TX_QUEUE_INACTIVE;
01119 AR5K_Q_DISABLE_BITS(hal->ah_txq_interrupts, queue);
01120
01121 return (AH_FALSE);
01122 }
01123
01124 HAL_BOOL
01125 ar5k_ar5212_reset_tx_queue(struct ath_hal *hal, u_int queue)
01126 {
01127 u_int32_t cw_min = 0, cw_max = 0, retry_lg, retry_sh;
01128 struct ieee80211_channel *channel = (struct ieee80211_channel*)
01129 &hal->ah_current_channel;
01130 HAL_TXQ_INFO *tq;
01131
01132 AR5K_TRACE;
01133 AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
01134
01135 tq = &hal->ah_txq[queue];
01136
01137
01138 if (tq->tqi_type == HAL_TX_QUEUE_INACTIVE) {
01139 return AH_TRUE;
01140 }
01141
01142
01143
01144 if (0 ) {
01145 hal->ah_cw_min = AR5K_TUNE_CWMIN_XR;
01146 cw_max = hal->ah_cw_max = AR5K_TUNE_CWMAX_XR;
01147 hal->ah_aifs = AR5K_TUNE_AIFS_XR;
01148 } else if (IEEE80211_IS_CHAN_B(channel)) {
01149 hal->ah_cw_min = AR5K_TUNE_CWMIN_11B;
01150 cw_max = hal->ah_cw_max = AR5K_TUNE_CWMAX_11B;
01151 hal->ah_aifs = AR5K_TUNE_AIFS_11B;
01152 } else {
01153 hal->ah_cw_min = AR5K_TUNE_CWMIN;
01154 hal->ah_cw_max = AR5K_TUNE_CWMAX;
01155 hal->ah_aifs = AR5K_TUNE_AIFS;
01156 }
01157
01158
01159
01160
01161 if (hal->ah_software_retry == AH_TRUE) {
01162
01163 retry_lg = hal->ah_limit_tx_retries;
01164 retry_sh = retry_lg =
01165 retry_lg > AR5K_AR5212_DCU_RETRY_LMT_SH_RETRY ?
01166 AR5K_AR5212_DCU_RETRY_LMT_SH_RETRY : retry_lg;
01167 } else {
01168 retry_lg = AR5K_INIT_LG_RETRY;
01169 retry_sh = AR5K_INIT_SH_RETRY;
01170 }
01171
01172 AR5K_REG_WRITE(AR5K_AR5212_DCU_RETRY_LMT(queue),
01173 AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
01174 AR5K_AR5212_DCU_RETRY_LMT_SLG_RETRY) |
01175 AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
01176 AR5K_AR5212_DCU_RETRY_LMT_SSH_RETRY) |
01177 AR5K_REG_SM(retry_lg, AR5K_AR5212_DCU_RETRY_LMT_LG_RETRY) |
01178 AR5K_REG_SM(retry_sh, AR5K_AR5212_DCU_RETRY_LMT_SH_RETRY));
01179
01180
01181
01182
01183 cw_min = hal->ah_cw_min;
01184 cw_max = hal->ah_cw_max;
01185 if (0) {
01186 while (cw_min < hal->ah_cw_min)
01187 cw_min = (cw_min << 1) | 1;
01188
01189 cw_min = tq->tqi_cwmin < 0 ?
01190 (cw_min >> (-tq->tqi_cwmin)) :
01191 ((cw_min << tq->tqi_cwmin) + (1 << tq->tqi_cwmin) - 1);
01192 cw_max = tq->tqi_cwmax < 0 ?
01193 (cw_max >> (-tq->tqi_cwmax)) :
01194 ((cw_max << tq->tqi_cwmax) + (1 << tq->tqi_cwmax) - 1);
01195 }
01196 AR5K_REG_WRITE(AR5K_AR5212_DCU_LCL_IFS(queue),
01197 AR5K_REG_SM(cw_min, AR5K_AR5212_DCU_LCL_IFS_CW_MIN) |
01198 AR5K_REG_SM(cw_max, AR5K_AR5212_DCU_LCL_IFS_CW_MAX) |
01199 AR5K_REG_SM(hal->ah_aifs + tq->tqi_aifs,
01200 AR5K_AR5212_DCU_LCL_IFS_AIFS));
01201
01202
01203
01204
01205 AR5K_REG_WRITE(AR5K_AR5212_QCU_MISC(queue),
01206 AR5K_AR5212_QCU_MISC_DCU_EARLY);
01207
01208 if (tq->tqi_cbrPeriod) {
01209 AR5K_REG_WRITE(AR5K_AR5212_QCU_CBRCFG(queue),
01210 AR5K_REG_SM(tq->tqi_cbrPeriod,
01211 AR5K_AR5212_QCU_CBRCFG_INTVAL) |
01212 AR5K_REG_SM(tq->tqi_cbrOverflowLimit,
01213 AR5K_AR5212_QCU_CBRCFG_ORN_THRES));
01214 AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
01215 AR5K_AR5212_QCU_MISC_FRSHED_CBR);
01216 if (tq->tqi_cbrOverflowLimit)
01217 AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
01218 AR5K_AR5212_QCU_MISC_CBR_THRES_ENABLE);
01219 }
01220
01221 if (tq->tqi_readyTime) {
01222 AR5K_REG_WRITE(AR5K_AR5212_QCU_RDYTIMECFG(queue),
01223 AR5K_REG_SM(tq->tqi_readyTime,
01224 AR5K_AR5212_QCU_RDYTIMECFG_INTVAL) |
01225 AR5K_AR5212_QCU_RDYTIMECFG_ENABLE);
01226 }
01227
01228 if (tq->tqi_burstTime) {
01229 AR5K_REG_WRITE(AR5K_AR5212_DCU_CHAN_TIME(queue),
01230 AR5K_REG_SM(tq->tqi_burstTime,
01231 AR5K_AR5212_DCU_CHAN_TIME_DUR) |
01232 AR5K_AR5212_DCU_CHAN_TIME_ENABLE);
01233
01234 if (tq->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE) {
01235 AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
01236 AR5K_AR5212_QCU_MISC_TXE);
01237 }
01238 }
01239
01240 if (tq->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
01241 AR5K_REG_WRITE(AR5K_AR5212_DCU_MISC(queue),
01242 AR5K_AR5212_DCU_MISC_POST_FR_BKOFF_DIS);
01243 }
01244
01245 if (tq->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
01246 AR5K_REG_WRITE(AR5K_AR5212_DCU_MISC(queue),
01247 AR5K_AR5212_DCU_MISC_BACKOFF_FRAG);
01248 }
01249
01250
01251
01252
01253 switch (tq->tqi_type) {
01254 case HAL_TX_QUEUE_BEACON:
01255 AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
01256 AR5K_AR5212_QCU_MISC_FRSHED_DBA_GT |
01257 AR5K_AR5212_QCU_MISC_CBREXP_BCN |
01258 AR5K_AR5212_QCU_MISC_BCN_ENABLE);
01259
01260 AR5K_REG_ENABLE_BITS(AR5K_AR5212_DCU_MISC(queue),
01261 (AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
01262 AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL) |
01263 AR5K_AR5212_DCU_MISC_POST_FR_BKOFF_DIS |
01264 AR5K_AR5212_DCU_MISC_BCN_ENABLE);
01265
01266 AR5K_REG_WRITE(AR5K_AR5212_QCU_RDYTIMECFG(queue),
01267 ((AR5K_TUNE_BEACON_INTERVAL -
01268 (AR5K_TUNE_SW_BEACON_RESP - AR5K_TUNE_DMA_BEACON_RESP) -
01269 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
01270 AR5K_AR5212_QCU_RDYTIMECFG_ENABLE);
01271 break;
01272
01273 case HAL_TX_QUEUE_CAB:
01274 AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
01275 AR5K_AR5212_QCU_MISC_FRSHED_DBA_GT |
01276 AR5K_AR5212_QCU_MISC_CBREXP |
01277 AR5K_AR5212_QCU_MISC_CBREXP_BCN);
01278
01279 AR5K_REG_ENABLE_BITS(AR5K_AR5212_DCU_MISC(queue),
01280 (AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
01281 AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL));
01282 break;
01283
01284 case HAL_TX_QUEUE_PSPOLL:
01285 AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
01286 AR5K_AR5212_QCU_MISC_CBREXP);
01287 break;
01288
01289 case HAL_TX_QUEUE_DATA:
01290 default:
01291 break;
01292 }
01293
01294
01295
01296
01297 AR5K_REG_WRITE(AR5K_AR5212_SIMR0,
01298 AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR0_QCU_TXOK) |
01299 AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR0_QCU_TXDESC));
01300 AR5K_REG_WRITE(AR5K_AR5212_SIMR1,
01301 AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR1_QCU_TXERR));
01302 AR5K_REG_WRITE(AR5K_AR5212_SIMR2,
01303 AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR2_QCU_TXURN));
01304
01305 return (AH_TRUE);
01306 }
01307
01308 u_int32_t
01309 ar5k_ar5212_get_tx_buf(struct ath_hal *hal, u_int queue)
01310 {
01311 AR5K_TRACE;
01312 AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
01313
01314
01315
01316
01317 return (AR5K_REG_READ(AR5K_AR5212_QCU_TXDP(queue)));
01318 }
01319
01320 HAL_BOOL
01321 ar5k_ar5212_put_tx_buf(struct ath_hal *hal,
01322 u_int queue,
01323 u_int32_t phys_addr)
01324 {
01325 AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
01326 AR5K_TRACE;
01327
01328
01329
01330
01331
01332 if (AR5K_REG_READ_Q(AR5K_AR5212_QCU_TXE, queue)) {
01333 printk("%s: ???1\n", __func__);
01334 return (AH_FALSE);
01335 }
01336
01337 if (AR5K_REG_READ_Q(AR5K_AR5212_QCU_TXD, queue)) {
01338 printk("%s: ???2\n", __func__);
01339 return (AH_FALSE);
01340 }
01341
01342 AR5K_REG_WRITE(AR5K_AR5212_QCU_TXDP(queue), phys_addr);
01343
01344 return (AH_TRUE);
01345 }
01346
01347 u_int32_t
01348 ar5k_ar5212_num_tx_pending(struct ath_hal *hal, u_int queue) {
01349 AR5K_TRACE;
01350 AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
01351 return (AR5K_AR5212_QCU_STS(queue) & AR5K_AR5212_QCU_STS_FRMPENDCNT);
01352 }
01353
01354 HAL_BOOL
01355 ar5k_ar5212_tx_start(struct ath_hal *hal, u_int queue)
01356 {
01357 AR5K_TRACE;
01358 AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
01359
01360
01361 if (AR5K_REG_READ_Q(AR5K_AR5212_QCU_TXD, queue)) {
01362 printk("%s: q disabled?\n", __func__);
01363 return (AH_FALSE);
01364 }
01365
01366 AR5K_REG_WRITE_Q(AR5K_AR5212_QCU_TXE, queue);
01367 return (AH_TRUE);
01368 }
01369
01370 HAL_BOOL
01371 ar5k_ar5212_stop_tx_dma(struct ath_hal *hal, u_int queue)
01372 {
01373
01374 int i = 100, pending;
01375
01376 AR5K_TRACE;
01377 AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
01378
01379
01380
01381 AR5K_REG_WRITE_Q(AR5K_AR5212_QCU_TXD, queue);
01382
01383 do {
01384 pending = AR5K_REG_READ(AR5K_AR5212_QCU_STS(queue)) &
01385 AR5K_AR5212_QCU_STS_FRMPENDCNT;
01386 AR5K_DELAY(100);
01387 } while (--i && pending);
01388
01389
01390 AR5K_REG_WRITE(AR5K_AR5212_QCU_TXD, 0);
01391
01392 return (AH_TRUE);
01393 }
01394
01395 HAL_BOOL
01396 ar5k_ar5212_setup_tx_desc(
01397 struct ath_hal *hal,
01398 struct ath_desc *desc,
01399 u_int packet_length,
01400 u_int header_length,
01401 HAL_PKT_TYPE type,
01402 u_int tx_power,
01403 u_int tx_rate0,
01404 u_int tx_tries0,
01405 u_int key_index,
01406 u_int antenna_mode,
01407 u_int flags,
01408 u_int rtscts_rate,
01409 u_int rtscts_duration)
01410 {
01411 struct ar5k_ar5212_tx_desc *tx_desc;
01412
01413 if (flags & HAL_TXDESC_NOACK) {
01414 tx_tries0 = 1;
01415 }
01416 AR5K_TRACE;
01417 tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
01418
01419
01420 tx_desc->tx_control_0 = 0;
01421 tx_desc->tx_control_1 = 0;
01422 desc->ds_hw[0] = 0;
01423 desc->ds_hw[1] = 0;
01424 desc->ds_hw[2] = 0;
01425 desc->ds_hw[3] = 0;
01426 desc->ds_hw[4] = 0;
01427
01428
01429
01430
01431 if (tx_tries0 == 0) {
01432 printk("%s: zero tries?\n", __func__);
01433 return (AH_FALSE);
01434 }
01435
01436 if ((tx_desc->tx_control_0 = (packet_length &
01437 AR5K_AR5212_DESC_TX_CTL0_FRAME_LEN)) != packet_length) {
01438 printk("%s: bad length?\n", __func__);
01439 return (AH_FALSE);
01440 }
01441
01442
01443 tx_desc->tx_control_0 |=
01444 AR5K_REG_SM(tx_power, AR5K_AR5212_DESC_TX_CTL0_XMIT_POWER) |
01445 AR5K_REG_SM(antenna_mode, AR5K_AR5212_DESC_TX_CTL0_ANT_MODE_XMIT);
01446 tx_desc->tx_control_1 =
01447 AR5K_REG_SM(type, AR5K_AR5212_DESC_TX_CTL1_FRAME_TYPE);
01448 tx_desc->tx_control_2 =
01449 AR5K_REG_SM(tx_tries0,
01450 AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES0);
01451 tx_desc->tx_control_3 =
01452 tx_rate0 & AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE0;
01453
01454
01455 #define _TX_FLAGS(_c, _flag) \
01456 if (flags & HAL_TXDESC_##_flag) \
01457 tx_desc->tx_control_##_c |= \
01458 AR5K_AR5212_DESC_TX_CTL##_c##_##_flag
01459
01460 _TX_FLAGS(0, CLRDMASK);
01461 _TX_FLAGS(0, VEOL);
01462 _TX_FLAGS(0, INTREQ);
01463 _TX_FLAGS(0, RTSENA);
01464 _TX_FLAGS(0, CTSENA);
01465 _TX_FLAGS(1, NOACK);
01466
01467 #undef _TX_FLAGS
01468
01469
01470
01471
01472 if (key_index != HAL_TXKEYIX_INVALID) {
01473 tx_desc->tx_control_0 |=
01474 AR5K_AR5212_DESC_TX_CTL0_ENCRYPT_KEY_VALID;
01475 tx_desc->tx_control_1 |=
01476 AR5K_REG_SM(key_index,
01477 AR5K_AR5212_DESC_TX_CTL1_ENCRYPT_KEY_INDEX);
01478 }
01479
01480
01481
01482
01483 if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) {
01484 if ((flags & HAL_TXDESC_RTSENA) &&
01485 (flags & HAL_TXDESC_CTSENA))
01486 return (AH_FALSE);
01487 tx_desc->tx_control_2 |=
01488 rtscts_duration & AR5K_AR5212_DESC_TX_CTL2_RTS_DURATION;
01489 tx_desc->tx_control_3 |=
01490 AR5K_REG_SM(rtscts_rate,
01491 AR5K_AR5212_DESC_TX_CTL3_RTS_CTS_RATE);
01492 }
01493
01494 return (AH_TRUE);
01495 }
01496
01497 HAL_BOOL
01498 ar5k_ar5212_fill_tx_desc(struct ath_hal *hal,
01499 struct ath_desc *desc,
01500 u_int segment_length,
01501 HAL_BOOL first_segment,
01502 HAL_BOOL last_segment,
01503 struct ath_desc *last_desc)
01504 {
01505 struct ar5k_ar5212_tx_desc *tx_desc;
01506 AR5K_TRACE;
01507 if (!desc) {
01508 printk("%s: %d\n", __func__, __LINE__);
01509 return (AH_FALSE);
01510 }
01511
01512 tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
01513
01514 if (segment_length > AR5K_AR5212_DESC_TX_CTL1_BUF_LEN) {
01515 printk("%s: bad len %d vs %d\n", __func__, segment_length,
01516 AR5K_AR5212_DESC_TX_CTL1_BUF_LEN);
01517 return (AH_FALSE);
01518 }
01519
01520 tx_desc->tx_control_1 &= ~AR5K_AR5212_DESC_TX_CTL1_BUF_LEN;
01521 tx_desc->tx_control_1 |= (segment_length & AR5K_AR5212_DESC_TX_CTL1_BUF_LEN);
01522
01523 if (first_segment != AH_TRUE)
01524 tx_desc->tx_control_0 &= ~AR5K_AR5212_DESC_TX_CTL0_FRAME_LEN;
01525
01526 if (last_segment != AH_TRUE)
01527 tx_desc->tx_control_1 |= AR5K_AR5212_DESC_TX_CTL1_MORE;
01528
01529 return (AH_TRUE);
01530 }
01531
01532 HAL_BOOL
01533 ar5k_ar5212_setup_xtx_desc(
01534 struct ath_hal *hal,
01535 struct ath_desc *desc,
01536 u_int tx_rate1,
01537 u_int tx_tries1,
01538 u_int tx_rate2,
01539 u_int tx_tries2,
01540 u_int tx_rate3,
01541 u_int tx_tries3)
01542 {
01543 struct ar5k_ar5212_tx_desc *tx_desc;
01544 AR5K_TRACE;
01545 if (!desc)
01546 return (AH_TRUE);
01547
01548 tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
01549
01550 #define _XTX_TRIES(_n) \
01551 if (tx_tries##_n) { \
01552 tx_desc->tx_control_2 |= \
01553 AR5K_REG_SM(tx_tries##_n, \
01554 AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES##_n); \
01555 tx_desc->tx_control_3 |= \
01556 AR5K_REG_SM(tx_rate##_n, \
01557 AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE##_n); \
01558 }
01559
01560 _XTX_TRIES(1);
01561 _XTX_TRIES(2);
01562 _XTX_TRIES(3);
01563
01564 #undef _XTX_TRIES
01565
01566 return (AH_TRUE);
01567 }
01568
01569 HAL_STATUS
01570 ar5k_ar5212_proc_tx_desc(struct ath_hal *hal, struct ath_desc *desc)
01571 {
01572 struct ar5k_ar5212_tx_status *tx_status;
01573 struct ar5k_ar5212_tx_desc *tx_desc;
01574 AR5K_TRACE;
01575 tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
01576 tx_status = (struct ar5k_ar5212_tx_status*)&desc->ds_hw[2];
01577
01578
01579 if ((tx_status->tx_status_1 & AR5K_AR5212_DESC_TX_STATUS1_DONE) == 0) {
01580 return (HAL_EINPROGRESS);
01581 }
01582
01583
01584
01585
01586 desc->ds_us.tx.ts_tstamp =
01587 AR5K_REG_MS(tx_status->tx_status_0,
01588 AR5K_AR5212_DESC_TX_STATUS0_SEND_TIMESTAMP);
01589 desc->ds_us.tx.ts_shortretry =
01590 AR5K_REG_MS(tx_status->tx_status_0,
01591 AR5K_AR5212_DESC_TX_STATUS0_RTS_FAIL_COUNT);
01592 desc->ds_us.tx.ts_longretry =
01593 AR5K_REG_MS(tx_status->tx_status_0,
01594 AR5K_AR5212_DESC_TX_STATUS0_DATA_FAIL_COUNT);
01595 desc->ds_us.tx.ts_seqnum =
01596 AR5K_REG_MS(tx_status->tx_status_1,
01597 AR5K_AR5212_DESC_TX_STATUS1_SEQ_NUM);
01598 desc->ds_us.tx.ts_rssi =
01599 AR5K_REG_MS(tx_status->tx_status_1,
01600 AR5K_AR5212_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
01601 desc->ds_us.tx.ts_antenna = (tx_status->tx_status_1 &
01602 AR5K_AR5212_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
01603 desc->ds_us.tx.ts_status = 0;
01604
01605 switch (AR5K_REG_MS(tx_status->tx_status_1,
01606 AR5K_AR5212_DESC_TX_STATUS1_FINAL_TS_INDEX)) {
01607 case 0:
01608 desc->ds_us.tx.ts_rate = tx_desc->tx_control_3 &
01609 AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE0;
01610 break;
01611 case 1:
01612 desc->ds_us.tx.ts_rate =
01613 AR5K_REG_MS(tx_desc->tx_control_3,
01614 AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE1);
01615 desc->ds_us.tx.ts_longretry +=
01616 AR5K_REG_MS(tx_desc->tx_control_2,
01617 AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES1);
01618 break;
01619 case 2:
01620 desc->ds_us.tx.ts_rate =
01621 AR5K_REG_MS(tx_desc->tx_control_3,
01622 AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE2);
01623 desc->ds_us.tx.ts_longretry +=
01624 AR5K_REG_MS(tx_desc->tx_control_2,
01625 AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES2);
01626 break;
01627 case 3:
01628 desc->ds_us.tx.ts_rate =
01629 AR5K_REG_MS(tx_desc->tx_control_3,
01630 AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE3);
01631 desc->ds_us.tx.ts_longretry +=
01632 AR5K_REG_MS(tx_desc->tx_control_2,
01633 AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES3);
01634 break;
01635 }
01636
01637 if ((tx_status->tx_status_0 &
01638 AR5K_AR5212_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0) {
01639 if (tx_status->tx_status_0 &
01640 AR5K_AR5212_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
01641 desc->ds_us.tx.ts_status |= HAL_TXERR_XRETRY;
01642
01643 if (tx_status->tx_status_0 &
01644 AR5K_AR5212_DESC_TX_STATUS0_FIFO_UNDERRUN)
01645 desc->ds_us.tx.ts_status |= HAL_TXERR_FIFO;
01646
01647 if (tx_status->tx_status_0 &
01648 AR5K_AR5212_DESC_TX_STATUS0_FILTERED)
01649 desc->ds_us.tx.ts_status |= HAL_TXERR_FILT;
01650 }
01651
01652 return (HAL_OK);
01653 }
01654
01655
01656 void
01657 ar5k_ar5212_get_tx_inter_queue(struct ath_hal *hal, u_int32_t *i)
01658 {
01659 AR5K_TRACE;
01660 return;
01661 }
01662 HAL_BOOL
01663 ar5k_ar5212_has_veol(struct ath_hal *hal)
01664 {
01665 AR5K_TRACE;
01666 return (AH_TRUE);
01667 }
01668
01669
01670
01671
01672
01673 u_int32_t
01674 ar5k_ar5212_get_rx_buf(struct ath_hal *hal)
01675 {
01676 return AR5K_REG_READ(AR5K_AR5212_RXDP);
01677 }
01678
01679 void
01680 ar5k_ar5212_put_rx_buf(struct ath_hal *hal,u_int32_t phys_addr)
01681 {
01682 if (AR5K_REG_READ(AR5K_AR5212_CR) & AR5K_AR5212_CR_RXE) {
01683 printk("%s: ????\n", __func__);
01684 }
01685 AR5K_REG_WRITE(AR5K_AR5212_RXDP, phys_addr);
01686 if (!AR5K_REG_READ(AR5K_AR5212_RXDP) == phys_addr) {
01687 printk("%s: error!\n", __func__);
01688 }
01689 }
01690
01691 void
01692 ar5k_ar5212_start_rx(struct ath_hal *hal)
01693 {
01694 AR5K_TRACE;
01695 AR5K_REG_WRITE(AR5K_AR5212_CR, AR5K_AR5212_CR_RXE);
01696 }
01697
01698 HAL_BOOL
01699 ar5k_ar5212_stop_rx_dma(struct ath_hal *hal)
01700 {
01701
01702 int i;
01703 AR5K_TRACE;
01704 AR5K_REG_WRITE(AR5K_AR5212_CR, AR5K_AR5212_CR_RXD);
01705
01706
01707
01708
01709 for (i = 2000;
01710 i > 0 && (AR5K_REG_READ(AR5K_AR5212_CR) & AR5K_AR5212_CR_RXE) != 0;
01711 i--)
01712 AR5K_DELAY(10);
01713
01714 return (i > 0 ? AH_TRUE : AH_FALSE);
01715 }
01716
01717 void
01718 ar5k_ar5212_start_rx_pcu(struct ath_hal *hal)
01719 {
01720 AR5K_TRACE;
01721 AR5K_REG_DISABLE_BITS(AR5K_AR5212_DIAG_SW, AR5K_AR5212_DIAG_SW_DIS_RX);
01722 }
01723
01724 void
01725 ar5k_ar5212_stop_pcu_recv(struct ath_hal *hal)
01726 {
01727 AR5K_TRACE;
01728 AR5K_REG_ENABLE_BITS(AR5K_AR5212_DIAG_SW, AR5K_AR5212_DIAG_SW_DIS_RX);
01729 }
01730
01731 void
01732 ar5k_ar5212_set_mcast_filter(
01733 struct ath_hal *hal,
01734 u_int32_t filter0,
01735 u_int32_t filter1)
01736 {
01737 AR5K_TRACE;
01738
01739 AR5K_REG_WRITE(AR5K_AR5212_MCAST_FIL0, filter0);
01740 AR5K_REG_WRITE(AR5K_AR5212_MCAST_FIL1, filter1);
01741 }
01742
01743 HAL_BOOL
01744 ar5k_ar5212_set_mcast_filterindex(struct ath_hal *hal,u_int32_t index)
01745 {
01746
01747 AR5K_TRACE;
01748 if (index >= 64) {
01749 return (AH_FALSE);
01750 } else if (index >= 32) {
01751 AR5K_REG_ENABLE_BITS(AR5K_AR5212_MCAST_FIL1,
01752 (1 << (index - 32)));
01753 } else {
01754 AR5K_REG_ENABLE_BITS(AR5K_AR5212_MCAST_FIL0,
01755 (1 << index));
01756 }
01757
01758 return (AH_TRUE);
01759 }
01760
01761 HAL_BOOL
01762 ar5k_ar5212_clear_mcast_filter_idx(struct ath_hal *hal, u_int32_t index)
01763 {
01764 AR5K_TRACE;
01765 if (index >= 64) {
01766 return (AH_FALSE);
01767 } else if (index >= 32) {
01768 AR5K_REG_DISABLE_BITS(AR5K_AR5212_MCAST_FIL1,
01769 (1 << (index - 32)));
01770 } else {
01771 AR5K_REG_DISABLE_BITS(AR5K_AR5212_MCAST_FIL0,
01772 (1 << index));
01773 }
01774
01775 return (AH_TRUE);
01776 }
01777
01778 u_int32_t
01779 ar5k_ar5212_get_rx_filter(struct ath_hal *hal)
01780 {
01781 u_int32_t data, filter = 0;
01782 AR5K_TRACE;
01783
01784 filter = AR5K_REG_READ(AR5K_AR5212_RX_FILTER);
01785 data = AR5K_REG_READ(AR5K_AR5212_PHY_ERR_FIL);
01786
01787 if (data & AR5K_AR5212_PHY_ERR_FIL_RADAR)
01788 filter |= HAL_RX_FILTER_PHYRADAR;
01789 if (data & (AR5K_AR5212_PHY_ERR_FIL_OFDM |
01790 AR5K_AR5212_PHY_ERR_FIL_CCK))
01791 filter |= HAL_RX_FILTER_PHYERR;
01792
01793 return (filter);
01794 }
01795
01796 void
01797 ar5k_ar5212_set_rx_filter(struct ath_hal *hal, u_int32_t filter)
01798 {
01799 u_int32_t data = 0;
01800
01801 if (filter & HAL_RX_FILTER_PHYRADAR)
01802 data |= AR5K_AR5212_PHY_ERR_FIL_RADAR;
01803 if (filter & HAL_RX_FILTER_PHYERR)
01804 data |= AR5K_AR5212_PHY_ERR_FIL_OFDM |
01805 AR5K_AR5212_PHY_ERR_FIL_CCK;
01806
01807 if (data) {
01808 AR5K_REG_ENABLE_BITS(AR5K_AR5212_RXCFG,
01809 AR5K_AR5212_RXCFG_ZLFDMA);
01810 } else {
01811 AR5K_REG_DISABLE_BITS(AR5K_AR5212_RXCFG,
01812 AR5K_AR5212_RXCFG_ZLFDMA);
01813 }
01814
01815 AR5K_REG_WRITE(AR5K_AR5212_RX_FILTER, filter & 0xff);
01816 AR5K_REG_WRITE(AR5K_AR5212_PHY_ERR_FIL, data);
01817 }
01818
01819 HAL_BOOL
01820 ar5k_ar5212_setup_rx_desc(struct ath_hal *hal,
01821 struct ath_desc *desc,
01822 u_int32_t size,
01823 u_int flags)
01824 {
01825 struct ar5k_ar5212_rx_desc *rx_desc;
01826 AR5K_TRACE;
01827
01828 rx_desc = (struct ar5k_ar5212_rx_desc*)&desc->ds_ctl0;
01829 rx_desc->rx_control_0 = 0;
01830 rx_desc->rx_control_1 = 0;
01831 desc->ds_hw[0] = 0;
01832 desc->ds_hw[1] = 0;
01833 desc->ds_hw[2] = 0;
01834 desc->ds_hw[3] = 0;
01835 if ((rx_desc->rx_control_1 = (size &
01836 AR5K_AR5212_DESC_RX_CTL1_BUF_LEN)) != size)
01837 return (AH_FALSE);
01838
01839 if (flags & HAL_RXDESC_INTREQ)
01840 rx_desc->rx_control_1 |= AR5K_AR5212_DESC_RX_CTL1_INTREQ;
01841
01842 return (AH_TRUE);
01843 }
01844
01845 HAL_STATUS
01846 ar5k_ar5212_proc_rx_desc(
01847 struct ath_hal *hal,
01848 struct ath_desc *desc,
01849 u_int32_t phys_addr,
01850 struct ath_desc *next)
01851 {
01852 struct ar5k_ar5212_rx_status *rx_status;
01853 struct ar5k_ar5212_rx_error *rx_err;
01854
01855 rx_status = (struct ar5k_ar5212_rx_status*)&desc->ds_hw[0];
01856
01857
01858 rx_err = (struct ar5k_ar5212_rx_error*)&desc->ds_hw[0];
01859
01860
01861 if ((rx_status->rx_status_1 & AR5K_AR5212_DESC_RX_STATUS1_DONE) == 0) {
01862 AR5K_TRACE;
01863 return (HAL_EINPROGRESS);
01864 }
01865
01866
01867 if (AR5K_REG_READ(AR5K_AR5212_RXDP) == phys_addr) {
01868 AR5K_TRACE;
01869 return (HAL_EINPROGRESS);
01870 }
01871
01872
01873
01874 desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 &
01875 AR5K_AR5212_DESC_RX_STATUS0_DATA_LEN;
01876 desc->ds_us.rx.rs_rssi =
01877 AR5K_REG_MS(rx_status->rx_status_0,
01878 AR5K_AR5212_DESC_RX_STATUS0_RECEIVE_SIGNAL);
01879 desc->ds_us.rx.rs_rate =
01880 AR5K_REG_MS(rx_status->rx_status_0,
01881 AR5K_AR5212_DESC_RX_STATUS0_RECEIVE_RATE);
01882 desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 &
01883 AR5K_AR5212_DESC_RX_STATUS0_RECEIVE_ANTENNA;
01884 desc->ds_us.rx.rs_more = rx_status->rx_status_0 &
01885 AR5K_AR5212_DESC_RX_STATUS0_MORE;
01886 desc->ds_us.rx.rs_tstamp =
01887 AR5K_REG_MS(rx_status->rx_status_1,
01888 AR5K_AR5212_DESC_RX_STATUS1_RECEIVE_TIMESTAMP);
01889 desc->ds_us.rx.rs_status = 0;
01890
01891
01892
01893
01894 if (rx_status->rx_status_1 &
01895 AR5K_AR5212_DESC_RX_STATUS1_KEY_INDEX_VALID) {
01896 desc->ds_us.rx.rs_keyix =
01897 AR5K_REG_MS(rx_status->rx_status_1,
01898 AR5K_AR5212_DESC_RX_STATUS1_KEY_INDEX);
01899 } else {
01900 desc->ds_us.rx.rs_keyix = HAL_RXKEYIX_INVALID;
01901 }
01902
01903
01904
01905
01906 if ((rx_status->rx_status_1 &
01907 AR5K_AR5212_DESC_RX_STATUS1_FRAME_RECEIVE_OK) == 0) {
01908 if (rx_status->rx_status_1 &
01909 AR5K_AR5212_DESC_RX_STATUS1_CRC_ERROR)
01910 desc->ds_us.rx.rs_status |= HAL_RXERR_CRC;
01911
01912 if (rx_status->rx_status_1 &
01913 AR5K_AR5212_DESC_RX_STATUS1_PHY_ERROR) {
01914 desc->ds_us.rx.rs_status |= HAL_RXERR_PHY;
01915 desc->ds_us.rx.rs_phyerr =
01916 AR5K_REG_MS(rx_err->rx_error_1,
01917 AR5K_AR5212_DESC_RX_ERROR1_PHY_ERROR_CODE);
01918 }
01919
01920 if (rx_status->rx_status_1 &
01921 AR5K_AR5212_DESC_RX_STATUS1_DECRYPT_CRC_ERROR)
01922 desc->ds_us.rx.rs_status |= HAL_RXERR_DECRYPT;
01923
01924 if (rx_status->rx_status_1 &
01925 AR5K_AR5212_DESC_RX_STATUS1_MIC_ERROR)
01926 desc->ds_us.rx.rs_status |= HAL_RXERR_MIC;
01927 }
01928
01929 return (HAL_OK);
01930 }
01931
01932 void
01933 ar5k_ar5212_set_rx_signal(struct ath_hal *hal, HAL_NODE_STATS *stats)
01934 {
01935
01936 AR5K_TRACE;
01937
01938 }
01939
01940
01941 void
01942 ar5k_ar5212_proc_mib_event(struct ath_hal *hal, const HAL_NODE_STATS *stats)
01943 {
01944
01945 AR5K_TRACE;
01946 return;
01947 }
01948
01949
01950
01951
01952 HAL_STATUS
01953 ar5k_ar5212_get_capability(struct ath_hal *hal, HAL_CAPABILITY_TYPE cap_type,
01954 u_int32_t capability, u_int32_t *result)
01955 {
01956
01957 AR5K_TRACE;
01958
01959 switch (cap_type) {
01960 case HAL_CAP_NUM_TXQUEUES:
01961 if (result) {
01962 *result = AR5K_AR5212_TX_NUM_QUEUES;
01963 goto yes;
01964 }
01965 case HAL_CAP_CIPHER: {
01966 switch (capability) {
01967 case HAL_CIPHER_WEP: goto yes;
01968 default: goto no;
01969 }
01970 case HAL_CAP_TPC:
01971 goto yes;
01972 default:
01973 goto no;
01974 }
01975
01976 }
01977
01978 no:
01979 return (HAL_EINVAL);
01980 yes:
01981 return HAL_OK;
01982
01983 }
01984
01985 HAL_BOOL
01986 ar5k_ar5212_set_capability(struct ath_hal *hal, HAL_CAPABILITY_TYPE cap_type,
01987 u_int32_t capability, u_int32_t setting, HAL_STATUS *status)
01988 {
01989
01990 AR5K_TRACE;
01991 if (status) {
01992 *status = HAL_OK;
01993 }
01994 return (AH_FALSE);
01995 }
01996
01997 void
01998 ar5k_ar5212_dump_state(struct ath_hal *hal)
01999 {
02000 AR5K_TRACE;
02001
02002 #ifdef AR5K_DEBUG
02003 printk("MAC registers:\n");
02004 AR5K_PRINT_REGISTER(CR);
02005 AR5K_PRINT_REGISTER(CFG);
02006 AR5K_PRINT_REGISTER(IER);
02007 AR5K_PRINT_REGISTER(TXCFG);
02008 AR5K_PRINT_REGISTER(RXCFG);
02009 AR5K_PRINT_REGISTER(MIBC);
02010 AR5K_PRINT_REGISTER(TOPS);
02011 AR5K_PRINT_REGISTER(RXNOFRM);
02012 AR5K_PRINT_REGISTER(RPGTO);
02013 AR5K_PRINT_REGISTER(RFCNT);
02014 AR5K_PRINT_REGISTER(MISC);
02015 AR5K_PRINT_REGISTER(PISR);
02016 AR5K_PRINT_REGISTER(SISR0);
02017 AR5K_PRINT_REGISTER(SISR1);
02018 AR5K_PRINT_REGISTER(SISR3);
02019 AR5K_PRINT_REGISTER(SISR4);
02020 AR5K_PRINT_REGISTER(DCM_ADDR);
02021 AR5K_PRINT_REGISTER(DCM_DATA);
02022 AR5K_PRINT_REGISTER(DCCFG);
02023 AR5K_PRINT_REGISTER(CCFG);
02024 AR5K_PRINT_REGISTER(CCFG_CUP);
02025 AR5K_PRINT_REGISTER(CPC0);
02026 AR5K_PRINT_REGISTER(CPC1);
02027 AR5K_PRINT_REGISTER(CPC2);
02028 AR5K_PRINT_REGISTER(CPCORN);
02029 AR5K_PRINT_REGISTER(QCU_TXE);
02030 AR5K_PRINT_REGISTER(QCU_TXD);
02031 AR5K_PRINT_REGISTER(DCU_GBL_IFS_SIFS);
02032 AR5K_PRINT_REGISTER(DCU_GBL_IFS_SLOT);
02033 AR5K_PRINT_REGISTER(DCU_FP);
02034 AR5K_PRINT_REGISTER(DCU_TXP);
02035 AR5K_PRINT_REGISTER(DCU_TX_FILTER);
02036 AR5K_PRINT_REGISTER(RC);
02037 AR5K_PRINT_REGISTER(SCR);
02038 AR5K_PRINT_REGISTER(INTPEND);
02039 AR5K_PRINT_REGISTER(PCICFG);
02040 AR5K_PRINT_REGISTER(GPIOCR);
02041 AR5K_PRINT_REGISTER(GPIODO);
02042 AR5K_PRINT_REGISTER(SREV);
02043 AR5K_PRINT_REGISTER(EEPROM_BASE);
02044 AR5K_PRINT_REGISTER(EEPROM_DATA);
02045 AR5K_PRINT_REGISTER(EEPROM_CMD);
02046 AR5K_PRINT_REGISTER(EEPROM_STATUS);
02047 AR5K_PRINT_REGISTER(EEPROM_CFG);
02048 AR5K_PRINT_REGISTER(PCU_MIN);
02049 AR5K_PRINT_REGISTER(STA_ID0);
02050 AR5K_PRINT_REGISTER(STA_ID1);
02051 AR5K_PRINT_REGISTER(BSS_ID0);
02052 AR5K_PRINT_REGISTER(SLOT_TIME);
02053 AR5K_PRINT_REGISTER(TIME_OUT);
02054 AR5K_PRINT_REGISTER(RSSI_THR);
02055 AR5K_PRINT_REGISTER(BEACON);
02056 AR5K_PRINT_REGISTER(CFP_PERIOD);
02057 AR5K_PRINT_REGISTER(TIMER0);
02058 AR5K_PRINT_REGISTER(TIMER2);
02059 AR5K_PRINT_REGISTER(TIMER3);
02060 AR5K_PRINT_REGISTER(CFP_DUR);
02061 AR5K_PRINT_REGISTER(MCAST_FIL0);
02062 AR5K_PRINT_REGISTER(MCAST_FIL1);
02063 AR5K_PRINT_REGISTER(DIAG_SW);
02064 AR5K_PRINT_REGISTER(TSF_U32);
02065 AR5K_PRINT_REGISTER(ADDAC_TEST);
02066 AR5K_PRINT_REGISTER(DEFAULT_ANTENNA);
02067 AR5K_PRINT_REGISTER(LAST_TSTP);
02068 AR5K_PRINT_REGISTER(NAV);
02069 AR5K_PRINT_REGISTER(RTS_OK);
02070 AR5K_PRINT_REGISTER(ACK_FAIL);
02071 AR5K_PRINT_REGISTER(FCS_FAIL);
02072 AR5K_PRINT_REGISTER(BEACON_CNT);
02073 AR5K_PRINT_REGISTER(TSF_PARM);
02074 AR5K_PRINT_REGISTER(RATE_DUR_0);
02075 AR5K_PRINT_REGISTER(KEYTABLE_0);
02076 printf("\n");
02077
02078 printf("PHY registers:\n");
02079 AR5K_PRINT_REGISTER(PHY_TURBO);
02080 AR5K_PRINT_REGISTER(PHY_AGC);
02081 AR5K_PRINT_REGISTER(PHY_TIMING_3);
02082 AR5K_PRINT_REGISTER(PHY_CHIP_ID);
02083 AR5K_PRINT_REGISTER(PHY_AGCCTL);
02084 AR5K_PRINT_REGISTER(PHY_NF);
02085 AR5K_PRINT_REGISTER(PHY_SCR);
02086 AR5K_PRINT_REGISTER(PHY_SLMT);
02087 AR5K_PRINT_REGISTER(PHY_SCAL);
02088 AR5K_PRINT_REGISTER(PHY_RX_DELAY);
02089 AR5K_PRINT_REGISTER(PHY_IQ);
02090 AR5K_PRINT_REGISTER(PHY_PAPD_PROBE);
02091 AR5K_PRINT_REGISTER(PHY_TXPOWER_RATE1);
02092 AR5K_PRINT_REGISTER(PHY_TXPOWER_RATE2);
02093 AR5K_PRINT_REGISTER(PHY_FC);
02094 AR5K_PRINT_REGISTER(PHY_RADAR);
02095 AR5K_PRINT_REGISTER(PHY_ANT_SWITCH_TABLE_0);
02096 AR5K_PRINT_REGISTER(PHY_ANT_SWITCH_TABLE_1);
02097 printf("\n");
02098 #endif
02099 }
02100
02101 static int
02102 ar5k_ar5212_proc_read_reg(struct ath_hal *hal, char *buf, int size)
02103 {
02104 char *p = buf;
02105 int x;
02106 #define AR5K_PRINT_REGISTER2(_x) \
02107 do { \
02108 p += sprintf(p, "0x%08x 0x%08x %s\n", AR5K_AR5212_##_x, AR5K_REG_READ(AR5K_AR5212_##_x), #_x); \
02109 } while (0)
02110
02111
02112 AR5K_PRINT_REGISTER2(CR);
02113 AR5K_PRINT_REGISTER2(RXDP);
02114 AR5K_PRINT_REGISTER2(CFG);
02115 AR5K_PRINT_REGISTER2(IER);
02116 AR5K_PRINT_REGISTER2(TXCFG);
02117 AR5K_PRINT_REGISTER2(RXCFG);
02118 AR5K_PRINT_REGISTER2(MIBC);
02119 AR5K_PRINT_REGISTER2(TOPS);
02120 AR5K_PRINT_REGISTER2(RXNOFRM);
02121 AR5K_PRINT_REGISTER2(RPGTO);
02122 AR5K_PRINT_REGISTER2(RFCNT);
02123 AR5K_PRINT_REGISTER2(MISC);
02124 AR5K_PRINT_REGISTER2(PISR);
02125 AR5K_PRINT_REGISTER2(SISR0);
02126 AR5K_PRINT_REGISTER2(SISR1);
02127 AR5K_PRINT_REGISTER2(SISR3);
02128 AR5K_PRINT_REGISTER2(SISR4);
02129 AR5K_PRINT_REGISTER2(PIMR);
02130 AR5K_PRINT_REGISTER2(SIMR0);
02131 AR5K_PRINT_REGISTER2(SIMR1);
02132 AR5K_PRINT_REGISTER2(SIMR2);
02133 AR5K_PRINT_REGISTER2(SIMR3);
02134 AR5K_PRINT_REGISTER2(SIMR4);
02135 AR5K_PRINT_REGISTER2(DCM_ADDR);
02136 AR5K_PRINT_REGISTER2(DCM_DATA);
02137 AR5K_PRINT_REGISTER2(DCCFG);
02138 AR5K_PRINT_REGISTER2(CCFG);
02139 AR5K_PRINT_REGISTER2(CCFG_CUP);
02140 AR5K_PRINT_REGISTER2(CPC0);
02141 AR5K_PRINT_REGISTER2(CPC1);
02142 AR5K_PRINT_REGISTER2(CPC2);
02143 AR5K_PRINT_REGISTER2(CPCORN);
02144 AR5K_PRINT_REGISTER2(QCU_TXE);
02145 AR5K_PRINT_REGISTER2(QCU_TXD);
02146 AR5K_PRINT_REGISTER2(DCU_GBL_IFS_SIFS);
02147 AR5K_PRINT_REGISTER2(DCU_GBL_IFS_SLOT);
02148 AR5K_PRINT_REGISTER2(DCU_FP);
02149 AR5K_PRINT_REGISTER2(DCU_TXP);
02150 AR5K_PRINT_REGISTER2(DCU_TX_FILTER);
02151 AR5K_PRINT_REGISTER2(RC);
02152 AR5K_PRINT_REGISTER2(SCR);
02153 AR5K_PRINT_REGISTER2(INTPEND);
02154 AR5K_PRINT_REGISTER2(PCICFG);
02155 AR5K_PRINT_REGISTER2(GPIOCR);
02156 AR5K_PRINT_REGISTER2(GPIODO);
02157 AR5K_PRINT_REGISTER2(SREV);
02158 AR5K_PRINT_REGISTER2(EEPROM_BASE);
02159 AR5K_PRINT_REGISTER2(EEPROM_DATA);
02160 AR5K_PRINT_REGISTER2(EEPROM_CMD);
02161 AR5K_PRINT_REGISTER2(EEPROM_STATUS);
02162 AR5K_PRINT_REGISTER2(EEPROM_CFG);
02163 AR5K_PRINT_REGISTER2(PCU_MIN);
02164 AR5K_PRINT_REGISTER2(STA_ID0);
02165 AR5K_PRINT_REGISTER2(STA_ID1);
02166 AR5K_PRINT_REGISTER2(BSS_ID0);
02167 AR5K_PRINT_REGISTER2(BSS_ID1);
02168 AR5K_PRINT_REGISTER2(SLOT_TIME);
02169 AR5K_PRINT_REGISTER2(TIME_OUT);
02170 AR5K_PRINT_REGISTER2(RSSI_THR);
02171 AR5K_PRINT_REGISTER2(USEC);
02172 AR5K_PRINT_REGISTER2(BEACON);
02173 AR5K_PRINT_REGISTER2(CFP_PERIOD);
02174 AR5K_PRINT_REGISTER2(TIMER0);
02175 AR5K_PRINT_REGISTER2(TIMER2);
02176 AR5K_PRINT_REGISTER2(TIMER3);
02177 AR5K_PRINT_REGISTER2(CFP_DUR);
02178 AR5K_PRINT_REGISTER2(RX_FILTER);
02179 AR5K_PRINT_REGISTER2(MCAST_FIL0);
02180 AR5K_PRINT_REGISTER2(MCAST_FIL1);
02181 AR5K_PRINT_REGISTER2(DIAG_SW);
02182 AR5K_PRINT_REGISTER2(TSF_L32);
02183 AR5K_PRINT_REGISTER2(TSF_U32);
02184 AR5K_PRINT_REGISTER2(ADDAC_TEST);
02185 AR5K_PRINT_REGISTER2(DEFAULT_ANTENNA);
02186 AR5K_PRINT_REGISTER2(LAST_TSTP);
02187 AR5K_PRINT_REGISTER2(NAV);
02188 AR5K_PRINT_REGISTER2(RTS_OK);
02189 AR5K_PRINT_REGISTER2(RTS_FAIL);
02190 AR5K_PRINT_REGISTER2(ACK_FAIL);
02191 AR5K_PRINT_REGISTER2(FCS_FAIL);
02192 AR5K_PRINT_REGISTER2(BEACON_CNT);
02193 AR5K_PRINT_REGISTER2(XRMODE);
02194 AR5K_PRINT_REGISTER2(XRDELAY);
02195 AR5K_PRINT_REGISTER2(XRTIMEOUT);
02196 AR5K_PRINT_REGISTER2(XRCHIRP);
02197 AR5K_PRINT_REGISTER2(XRSTOMP);
02198 AR5K_PRINT_REGISTER2(SLEEP0);
02199 AR5K_PRINT_REGISTER2(SLEEP1);
02200 AR5K_PRINT_REGISTER2(SLEEP2);
02201 AR5K_PRINT_REGISTER2(BSS_IDM0);
02202 AR5K_PRINT_REGISTER2(BSS_IDM1);
02203 AR5K_PRINT_REGISTER2(TXPC);
02204 AR5K_PRINT_REGISTER2(PROFCNT_TX);
02205 AR5K_PRINT_REGISTER2(PROFCNT_RX);
02206 AR5K_PRINT_REGISTER2(PROFCNT_RXCLR);
02207 AR5K_PRINT_REGISTER2(PROFCNT_CYCLE);
02208 AR5K_PRINT_REGISTER2(TSF_PARM);
02209 AR5K_PRINT_REGISTER2(PHY_ERR_FIL);
02210 AR5K_PRINT_REGISTER2(RATE_DUR_0);
02211 AR5K_PRINT_REGISTER2(KEYTABLE_0);
02212 p += sprintf(p, "\n");
02213
02214 AR5K_PRINT_REGISTER2(PHY_TURBO);
02215 AR5K_PRINT_REGISTER2(PHY_AGC);
02216 AR5K_PRINT_REGISTER2(PHY_TIMING_3);
02217 AR5K_PRINT_REGISTER2(PHY_ACTIVE);
02218 AR5K_PRINT_REGISTER2(PHY_CHIP_ID);
02219 AR5K_PRINT_REGISTER2(PHY_AGCCTL);
02220 AR5K_PRINT_REGISTER2(PHY_NF);
02221 AR5K_PRINT_REGISTER2(PHY_SCR);
02222 AR5K_PRINT_REGISTER2(PHY_SLMT);
02223 AR5K_PRINT_REGISTER2(PHY_SCAL);
02224 AR5K_PRINT_REGISTER2(PHY_PLL);
02225 AR5K_PRINT_REGISTER2(PHY_RX_DELAY);
02226 AR5K_PRINT_REGISTER2(PHY_IQ);
02227 AR5K_PRINT_REGISTER2(PHY_PAPD_PROBE);
02228 AR5K_PRINT_REGISTER2(PHY_TXPOWER_RATE1);
02229 AR5K_PRINT_REGISTER2(PHY_TXPOWER_RATE2);
02230 AR5K_PRINT_REGISTER2(PHY_TXPOWER_RATE3);
02231 AR5K_PRINT_REGISTER2(PHY_TXPOWER_RATE4);
02232 AR5K_PRINT_REGISTER2(PHY_TXPOWER_RATE_MAX);
02233 AR5K_PRINT_REGISTER2(PHY_FC);
02234 AR5K_PRINT_REGISTER2(PHY_RADAR);
02235 AR5K_PRINT_REGISTER2(PHY_ANT_SWITCH_TABLE_0);
02236 AR5K_PRINT_REGISTER2(PHY_ANT_SWITCH_TABLE_1);
02237 AR5K_PRINT_REGISTER2(PHY_SCLOCK);
02238 AR5K_PRINT_REGISTER2(PHY_SDELAY);
02239 AR5K_PRINT_REGISTER2(PHY_SPENDING);
02240 AR5K_PRINT_REGISTER2(PHY_IQRES_CAL_PWR_I);
02241 AR5K_PRINT_REGISTER2(PHY_IQRES_CAL_PWR_Q);
02242 AR5K_PRINT_REGISTER2(PHY_IQRES_CAL_CORR);
02243 AR5K_PRINT_REGISTER2(PHY_CURRENT_RSSI);
02244 AR5K_PRINT_REGISTER2(PHY_MODE);
02245 AR5K_PRINT_REGISTER2(PHY_GAIN_2GHZ);
02246 p += sprintf(p, "\n");
02247
02248
02249 for (x = 0; x < 10; x++) {
02250 p += sprintf(p, "0x%08x 0x%08x QCU_%d_TXDP\n", AR5K_AR5212_QCU_TXDP(x), AR5K_REG_READ(AR5K_AR5212_QCU_TXDP(x)), x);
02251 p += sprintf(p, "0x%08x 0x%08x QCU_%d_STS\n", AR5K_AR5212_QCU_STS(x), AR5K_REG_READ(AR5K_AR5212_QCU_STS(x)), x);
02252 p += sprintf(p, "0x%08x 0x%08x QCU_%d_MISC\n", AR5K_AR5212_QCU_MISC(x), AR5K_REG_READ(AR5K_AR5212_QCU_MISC(x)), x);
02253 p += sprintf(p, "0x%08x 0x%08x QCU_%d_CBRCFG\n", AR5K_AR5212_QCU_CBRCFG(x), AR5K_REG_READ(AR5K_AR5212_QCU_CBRCFG(x)), x);
02254 p += sprintf(p, "0x%08x 0x%08x QCU_%d_RDYTIMECFG\n", AR5K_AR5212_QCU_RDYTIMECFG(x), AR5K_REG_READ(AR5K_AR5212_QCU_RDYTIMECFG(x)), x);
02255 p += sprintf(p, "0x%08x 0x%08x DCU_%d_QCUMASK\n", AR5K_AR5212_DCU_QCUMASK(x), AR5K_REG_READ(AR5K_AR5212_DCU_QCUMASK(x)), x);
02256 p += sprintf(p, "0x%08x 0x%08x DCU_%d_LCL_IFS\n", AR5K_AR5212_DCU_LCL_IFS(x), AR5K_REG_READ(AR5K_AR5212_DCU_LCL_IFS(x)), x);
02257 p += sprintf(p, "0x%08x 0x%08x DCU_%d_RETRY_LMT\n", AR5K_AR5212_DCU_RETRY_LMT(x), AR5K_REG_READ(AR5K_AR5212_DCU_RETRY_LMT(x)), x);
02258 p += sprintf(p, "0x%08x 0x%08x DCU_%d_MISC\n", AR5K_AR5212_DCU_MISC(x), AR5K_REG_READ(AR5K_AR5212_DCU_MISC(x)), x);
02259 p += sprintf(p, "0x%08x 0x%08x DCU_%d_SEQNUM\n", AR5K_AR5212_DCU_SEQNUM(x), AR5K_REG_READ(AR5K_AR5212_DCU_SEQNUM(x)), x);
02260 p += sprintf(p, "\n");
02261 }
02262 return (p - buf);
02263 }
02264
02265
02266 HAL_BOOL
02267 ar5k_ar5212_get_diag_state(struct ath_hal *hal,
02268 int request, const void *args, u_int32_t argsize,
02269 void **result, u_int32_t *resultsize)
02270
02271 {
02272 AR5K_TRACE;
02273
02274
02275
02276
02277 return (AH_FALSE);
02278 }
02279
02280 void
02281 ar5k_ar5212_get_lladdr(struct ath_hal *hal,
02282 u_int8_t *mac)
02283 {
02284 bcopy(hal->ah_sta_id, mac, IEEE80211_ADDR_LEN);
02285 }
02286
02287 HAL_BOOL
02288 ar5k_ar5212_set_lladdr(struct ath_hal *hal,
02289 const u_int8_t *mac)
02290 {
02291 u_int32_t low_id, high_id;
02292
02293
02294 bcopy(mac, hal->ah_sta_id, IEEE80211_ADDR_LEN);
02295
02296 bcopy(mac, &low_id, 4);
02297 bcopy(mac + 4, &high_id, 2);
02298 high_id = 0x0000ffff & high_id;
02299
02300 AR5K_REG_WRITE(AR5K_AR5212_STA_ID0, low_id);
02301 AR5K_REG_WRITE(AR5K_AR5212_STA_ID1, high_id);
02302
02303 return (AH_TRUE);
02304 }
02305
02306 HAL_BOOL
02307 ar5k_ar5212_set_regdomain(struct ath_hal *hal,
02308 u_int16_t regdomain,
02309 HAL_STATUS *status)
02310
02311 {
02312 u_int32_t ieee_regdomain;
02313 AR5K_TRACE;
02314 ieee_regdomain = ar5k_regdomain_to_ieee(regdomain);
02315
02316 if (ar5k_eeprom_regulation_domain(hal, AH_TRUE,
02317 &ieee_regdomain) == AH_TRUE) {
02318 *status = HAL_OK;
02319 return (AH_TRUE);
02320 }
02321
02322 *status = EIO;
02323
02324 return (AH_FALSE);
02325 }
02326
02327 void
02328 ar5k_ar5212_set_ledstate(struct ath_hal *hal,
02329 int state)
02330 {
02331 u_int32_t led;
02332 AR5K_TRACE;
02333
02334 AR5K_REG_DISABLE_BITS(AR5K_AR5212_PCICFG,
02335 AR5K_AR5212_PCICFG_LEDMODE | AR5K_AR5212_PCICFG_LED);
02336
02337
02338
02339
02340 switch (state) {
02341 case 0:
02342 case 1:
02343 led = AR5K_AR5212_PCICFG_LEDMODE_PROP |
02344 AR5K_AR5212_PCICFG_LED_PEND;
02345 break;
02346
02347 case 2:
02348 led = AR5K_AR5212_PCICFG_LEDMODE_PROP |
02349 AR5K_AR5212_PCICFG_LED_NONE;
02350 break;
02351
02352 case 3:
02353 case 4:
02354 led = AR5K_AR5212_PCICFG_LEDMODE_PROP |
02355 AR5K_AR5212_PCICFG_LED_ASSOC;
02356 break;
02357
02358 default:
02359 led = AR5K_AR5212_PCICFG_LEDMODE_PROM |
02360 AR5K_AR5212_PCICFG_LED_NONE;
02361 break;
02362 }
02363
02364 AR5K_REG_ENABLE_BITS(AR5K_AR5212_PCICFG, led);
02365 }
02366
02367 void
02368 ar5k_ar5212_set_associd(struct ath_hal *hal,
02369 const u_int8_t *bssid,
02370 u_int16_t assoc_id)
02371 {
02372 u_int32_t low_id, high_id;
02373 u_int16_t tim_offset = 0 ;
02374
02375 AR5K_TRACE;
02376
02377
02378
02379
02380 AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM0, 0xfffffff);
02381 AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM1, 0xfffffff);
02382
02383
02384
02385
02386 bcopy(bssid, &low_id, 4);
02387 bcopy(bssid + 4, &high_id, 2);
02388
02389 memcpy(&low_id, bssid, 4);
02390 memcpy(&high_id, bssid + 4, 2);
02391 AR5K_REG_WRITE(AR5K_AR5212_BSS_ID0, low_id);
02392 AR5K_REG_WRITE(AR5K_AR5212_BSS_ID1, high_id |
02393 ((assoc_id & 0x3fff) << AR5K_AR5212_BSS_ID1_AID_S));
02394 bcopy(bssid, &hal->ah_bssid, IEEE80211_ADDR_LEN);
02395
02396 if (assoc_id == 0) {
02397 ar5k_ar5212_disable_pspoll(hal);
02398 return;
02399 }
02400
02401 AR5K_REG_WRITE(AR5K_AR5212_BEACON,
02402 (AR5K_REG_READ(AR5K_AR5212_BEACON) &
02403 ~AR5K_AR5212_BEACON_TIM) |
02404 (((tim_offset ? tim_offset + 4 : 0) <<
02405 AR5K_AR5212_BEACON_TIM_S) &
02406 AR5K_AR5212_BEACON_TIM));
02407
02408 ar5k_ar5212_enable_pspoll(hal, NULL, 0);
02409 }
02410
02411 HAL_BOOL
02412 ar5k_ar5212_set_gpio_output(struct ath_hal *hal,
02413 u_int32_t gpio)
02414 {
02415 AR5K_TRACE;
02416 if (gpio > AR5K_AR5212_NUM_GPIO)
02417 return (AH_FALSE);
02418
02419 AR5K_REG_WRITE(AR5K_AR5212_GPIOCR,
02420 (AR5K_REG_READ(AR5K_AR5212_GPIOCR) &~ AR5K_AR5212_GPIOCR_ALL(gpio))
02421 | AR5K_AR5212_GPIOCR_ALL(gpio));
02422
02423 return (AH_TRUE);
02424 }
02425
02426 HAL_BOOL
02427 ar5k_ar5212_set_gpio_input(struct ath_hal *hal,
02428 u_int32_t gpio)
02429 {
02430 AR5K_TRACE;
02431 if (gpio > AR5K_AR5212_NUM_GPIO)
02432 return (AH_FALSE);
02433
02434 AR5K_REG_WRITE(AR5K_AR5212_GPIOCR,
02435 (AR5K_REG_READ(AR5K_AR5212_GPIOCR) &~ AR5K_AR5212_GPIOCR_ALL(gpio))
02436 | AR5K_AR5212_GPIOCR_NONE(gpio));
02437
02438 return (AH_TRUE);
02439 }
02440
02441 u_int32_t
02442 ar5k_ar5212_get_gpio(struct ath_hal *hal,
02443 u_int32_t gpio)
02444 {
02445 AR5K_TRACE;
02446 if (gpio > AR5K_AR5212_NUM_GPIO) {
02447 AR5K_TRACE;
02448 return (0xffffffff);
02449 }
02450
02451
02452 return (((AR5K_REG_READ(AR5K_AR5212_GPIODI) &
02453 AR5K_AR5212_GPIODI_M) >> gpio) & 0x1);
02454 }
02455
02456 HAL_BOOL
02457 ar5k_ar5212_set_gpio(struct ath_hal *hal,
02458 u_int32_t gpio,
02459 u_int32_t val)
02460 {
02461 u_int32_t data;
02462
02463 AR5K_TRACE;
02464 if (gpio > AR5K_AR5212_NUM_GPIO)
02465 return AH_FALSE;
02466
02467
02468 data = AR5K_REG_READ(AR5K_AR5212_GPIODO);
02469
02470 data &= ~(1 << gpio);
02471 data |= (val&1) << gpio;
02472
02473 AR5K_REG_WRITE(AR5K_AR5212_GPIODO, data);
02474
02475 return (AH_TRUE);
02476 }
02477
02478 void
02479 ar5k_ar5212_set_gpio_intr(struct ath_hal *hal,
02480 u_int gpio,
02481 u_int32_t interrupt_level)
02482 {
02483 u_int32_t data;
02484 AR5K_TRACE;
02485 if (gpio > AR5K_AR5212_NUM_GPIO)
02486 return;
02487
02488
02489
02490
02491 data = (AR5K_REG_READ(AR5K_AR5212_GPIOCR) &
02492 ~(AR5K_AR5212_GPIOCR_INT_SEL(gpio) | AR5K_AR5212_GPIOCR_INT_SELH |
02493 AR5K_AR5212_GPIOCR_INT_ENA | AR5K_AR5212_GPIOCR_ALL(gpio))) |
02494 (AR5K_AR5212_GPIOCR_INT_SEL(gpio) | AR5K_AR5212_GPIOCR_INT_ENA);
02495
02496 AR5K_REG_WRITE(AR5K_AR5212_GPIOCR,
02497 interrupt_level ? data : (data | AR5K_AR5212_GPIOCR_INT_SELH));
02498
02499 hal->ah_imr |= AR5K_AR5212_PIMR_GPIO;
02500
02501
02502 AR5K_REG_ENABLE_BITS(AR5K_AR5212_PIMR, AR5K_AR5212_PIMR_GPIO);
02503 }
02504
02505 u_int32_t
02506 ar5k_ar5212_get_tsf32(struct ath_hal *hal)
02507 {
02508 AR5K_TRACE;
02509 return (AR5K_REG_READ(AR5K_AR5212_TSF_L32));
02510 }
02511
02512 u_int64_t
02513 ar5k_ar5212_get_tsf64(struct ath_hal *hal)
02514 {
02515 AR5K_TRACE;
02516 u_int64_t tsf = AR5K_REG_READ(AR5K_AR5212_TSF_U32);
02517
02518 return (AR5K_REG_READ(AR5K_AR5212_TSF_L32) | (tsf << 32));
02519 }
02520
02521 void
02522 ar5k_ar5212_reset_tsf(struct ath_hal *hal)
02523 {
02524 AR5K_TRACE;
02525 AR5K_REG_ENABLE_BITS(AR5K_AR5212_BEACON,
02526 AR5K_AR5212_BEACON_RESET_TSF);
02527 }
02528
02529 u_int16_t
02530 ar5k_ar5212_get_regdomain(struct ath_hal *hal)
02531 {
02532 AR5K_TRACE;
02533 return (ar5k_get_regdomain(hal));
02534 }
02535
02536 HAL_BOOL
02537 ar5k_ar5212_detect_card_present(struct ath_hal *hal)
02538 {
02539 u_int16_t magic;
02540 AR5K_TRACE;
02541
02542
02543
02544
02545
02546 if (hal->ah_eeprom_read(hal, AR5K_EEPROM_MAGIC, &magic) != 0)
02547 return (AH_FALSE);
02548
02549 return (magic == AR5K_EEPROM_MAGIC_VALUE ? AH_TRUE : AH_FALSE);
02550 }
02551
02552 void
02553 ar5k_ar5212_update_mib_counters(struct ath_hal *hal, HAL_MIB_STATS *statistics)
02554 {
02555 AR5K_TRACE;
02556
02557 statistics->ackrcv_bad += AR5K_REG_READ(AR5K_AR5212_ACK_FAIL);
02558 statistics->rts_bad += AR5K_REG_READ(AR5K_AR5212_RTS_FAIL);
02559 statistics->rts_good += AR5K_REG_READ(AR5K_AR5212_RTS_OK);
02560 statistics->fcs_bad += AR5K_REG_READ(AR5K_AR5212_FCS_FAIL);
02561 statistics->beacons += AR5K_REG_READ(AR5K_AR5212_BEACON_CNT);
02562
02563
02564 AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_TX, 0);
02565 AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_RX, 0);
02566 AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_RXCLR, 0);
02567 AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_CYCLE, 0);
02568 }
02569
02570 HAL_RFGAIN
02571 ar5k_ar5212_get_rf_gain(struct ath_hal *hal)
02572 {
02573 u_int32_t data, type;
02574 AR5K_TRACE;
02575 if ((hal->ah_rf_banks == NULL) || (!hal->ah_gain.g_active))
02576 return (HAL_RFGAIN_INACTIVE);
02577
02578 if (hal->ah_rf_gain != HAL_RFGAIN_READ_REQUESTED)
02579 goto done;
02580
02581 data = AR5K_REG_READ(AR5K_AR5212_PHY_PAPD_PROBE);
02582
02583 if (!(data & AR5K_AR5212_PHY_PAPD_PROBE_TX_NEXT)) {
02584 hal->ah_gain.g_current =
02585 data >> AR5K_AR5212_PHY_PAPD_PROBE_GAINF_S;
02586 type = AR5K_REG_MS(data, AR5K_AR5212_PHY_PAPD_PROBE_TYPE);
02587
02588 if (type == AR5K_AR5212_PHY_PAPD_PROBE_TYPE_CCK)
02589 hal->ah_gain.g_current += AR5K_GAIN_CCK_PROBE_CORR;
02590
02591 if (hal->ah_radio == AR5K_AR5112) {
02592 ar5k_rfregs_gainf_corr(hal);
02593 hal->ah_gain.g_current =
02594 hal->ah_gain.g_current >= hal->ah_gain.g_f_corr ?
02595 (hal->ah_gain.g_current - hal->ah_gain.g_f_corr) :
02596 0;
02597 }
02598
02599 if (ar5k_rfregs_gain_readback(hal) &&
02600 AR5K_GAIN_CHECK_ADJUST(&hal->ah_gain) &&
02601 ar5k_rfregs_gain_adjust(hal))
02602 hal->ah_rf_gain = HAL_RFGAIN_NEED_CHANGE;
02603 }
02604
02605 done:
02606 return (hal->ah_rf_gain);
02607 }
02608
02609 void
02610 ar5k_ar5212_set_def_antenna(struct ath_hal *hal, u_int ant)
02611 {
02612 AR5K_TRACE;
02613 return;
02614 }
02615 u_int
02616 ar5k_ar5212_get_def_antenna(struct ath_hal *hal)
02617 {
02618 AR5K_TRACE;
02619 return 0;
02620 }
02621 HAL_BOOL
02622 ar5k_ar5212_set_slot_time(struct ath_hal *hal, u_int slot_time)
02623 {
02624 AR5K_TRACE;
02625 if (slot_time < HAL_SLOT_TIME_9 || slot_time > HAL_SLOT_TIME_MAX)
02626 return (AH_FALSE);
02627
02628 AR5K_REG_WRITE(AR5K_AR5212_DCU_GBL_IFS_SLOT, slot_time);
02629
02630 return (AH_TRUE);
02631 }
02632
02633 u_int
02634 ar5k_ar5212_get_slot_time(struct ath_hal *hal)
02635 {
02636 AR5K_TRACE;
02637 return (AR5K_REG_READ(AR5K_AR5212_DCU_GBL_IFS_SLOT) & 0xffff);
02638 }
02639
02640 HAL_BOOL
02641 ar5k_ar5212_set_ack_timeout(struct ath_hal *hal, u_int timeout)
02642 {
02643 AR5K_TRACE;
02644 if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5212_TIME_OUT_ACK),
02645 hal->ah_turbo) <= timeout)
02646 return (AH_FALSE);
02647
02648 AR5K_REG_WRITE_BITS(AR5K_AR5212_TIME_OUT, AR5K_AR5212_TIME_OUT_ACK,
02649 ar5k_htoclock(timeout, hal->ah_turbo));
02650
02651 return (AH_TRUE);
02652 }
02653
02654 u_int
02655 ar5k_ar5212_get_ack_timeout(struct ath_hal *hal)
02656 {
02657 return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5212_TIME_OUT),
02658 AR5K_AR5212_TIME_OUT_ACK), hal->ah_turbo));
02659 }
02660
02661 HAL_BOOL
02662 ar5k_ar5212_set_cts_timeout(struct ath_hal *hal, u_int timeout)
02663 {
02664 AR5K_TRACE;
02665 if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5212_TIME_OUT_CTS),
02666 hal->ah_turbo) <= timeout)
02667 return (AH_FALSE);
02668
02669 AR5K_REG_WRITE_BITS(AR5K_AR5212_TIME_OUT, AR5K_AR5212_TIME_OUT_CTS,
02670 ar5k_htoclock(timeout, hal->ah_turbo));
02671
02672 return (AH_TRUE);
02673 }
02674
02675 u_int
02676 ar5k_ar5212_get_cts_timeout(struct ath_hal *hal)
02677 {
02678 AR5K_TRACE;
02679 return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5212_TIME_OUT),
02680 AR5K_AR5212_TIME_OUT_CTS), hal->ah_turbo));
02681 }
02682
02683
02684
02685
02686
02687 u_int32_t
02688 ar5k_ar5212_get_keycache_size(struct ath_hal *hal)
02689 {
02690 AR5K_TRACE;
02691 return (AR5K_AR5212_KEYCACHE_SIZE);
02692 }
02693
02694 HAL_BOOL
02695 ar5k_ar5212_reset_key(struct ath_hal *hal, u_int16_t entry)
02696 {
02697 int i;
02698 AR5K_TRACE;
02699 AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
02700
02701 for (i = 0; i < AR5K_AR5212_KEYCACHE_SIZE; i++)
02702 AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_OFF(entry, i), 0);
02703
02704
02705 AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_TYPE(entry),
02706 AR5K_AR5212_KEYTABLE_TYPE_NULL);
02707
02708 return (AH_FALSE);
02709 }
02710
02711 HAL_BOOL
02712 ar5k_ar5212_is_key_valid(struct ath_hal *hal,
02713 u_int16_t entry)
02714 {
02715 AR5K_TRACE;
02716 AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
02717
02718
02719
02720
02721 if (AR5K_REG_READ(AR5K_AR5212_KEYTABLE_MAC1(entry)) &
02722 AR5K_AR5212_KEYTABLE_VALID)
02723 return (AH_TRUE);
02724
02725 return (AH_FALSE);
02726 }
02727
02728 HAL_BOOL
02729 ar5k_ar5212_set_key(
02730 struct ath_hal *hal,
02731 u_int16_t entry,
02732 const HAL_KEYVAL *keyval,
02733 const u_int8_t *mac,
02734 int xor_notused)
02735 {
02736 int i;
02737 u_int32_t key_v[AR5K_AR5212_KEYCACHE_SIZE - 2];
02738
02739 AR5K_TRACE;
02740 AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
02741
02742 memset(&key_v, 0, sizeof(key_v));
02743
02744 switch (keyval->kv_len) {
02745 case AR5K_KEYVAL_LENGTH_40:
02746 bcopy(keyval->kv_val, &key_v[0], 4);
02747 bcopy(keyval->kv_val + 4, &key_v[1], 1);
02748 key_v[5] = AR5K_AR5212_KEYTABLE_TYPE_40;
02749 break;
02750
02751 case AR5K_KEYVAL_LENGTH_104:
02752 bcopy(keyval->kv_val, &key_v[0], 4);
02753 bcopy(keyval->kv_val + 4, &key_v[1], 2);
02754 bcopy(keyval->kv_val + 6, &key_v[2], 4);
02755 bcopy(keyval->kv_val + 10, &key_v[3], 2);
02756 bcopy(keyval->kv_val + 12, &key_v[4], 1);
02757 key_v[5] = AR5K_AR5212_KEYTABLE_TYPE_104;
02758 break;
02759
02760 case AR5K_KEYVAL_LENGTH_128:
02761 bcopy(keyval->kv_val, &key_v[0], 4);
02762 bcopy(keyval->kv_val + 4, &key_v[1], 2);
02763 bcopy(keyval->kv_val + 6, &key_v[2], 4);
02764 bcopy(keyval->kv_val + 10, &key_v[3], 2);
02765 bcopy(keyval->kv_val + 12, &key_v[4], 4);
02766 key_v[5] = AR5K_AR5212_KEYTABLE_TYPE_128;
02767 break;
02768
02769 default:
02770 printk("%s:%d bad key len\n", __func__, __LINE__);
02771
02772 return (AH_FALSE);
02773 }
02774
02775 for (i = 0; i < AR5K_ELEMENTS(key_v); i++)
02776 AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_OFF(entry, i), key_v[i]);
02777
02778 return (ar5k_ar5212_set_key_lladdr(hal, entry, mac));
02779 }
02780
02781 HAL_BOOL
02782 ar5k_ar5212_set_key_lladdr(struct ath_hal *hal,
02783 u_int16_t entry,
02784 const u_int8_t *mac)
02785 {
02786 u_int32_t low_id, high_id;
02787 const u_int8_t *mac_v;
02788 AR5K_TRACE;
02789
02790
02791
02792
02793 AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
02794
02795
02796
02797 mac_v = mac;
02798
02799 bcopy(mac_v, &low_id, 4);
02800 bcopy(mac_v + 4, &high_id, 2);
02801 high_id |= AR5K_AR5212_KEYTABLE_VALID;
02802
02803 AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_MAC0(entry), low_id);
02804 AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_MAC1(entry), high_id);
02805
02806 return (AH_TRUE);
02807 }
02808
02809
02810
02811
02812
02813 HAL_BOOL
02814 ar5k_ar5212_set_power(struct ath_hal *hal,
02815 HAL_POWER_MODE mode,
02816 int set_chip,
02817 u_int16_t sleep_duration)
02818 {
02819 u_int32_t staid;
02820 int i;
02821 AR5K_TRACE;
02822 staid = AR5K_REG_READ(AR5K_AR5212_STA_ID1);
02823
02824 switch (mode) {
02825 case HAL_PM_AUTO:
02826 staid &= ~AR5K_AR5212_STA_ID1_DEFAULT_ANTENNA;
02827
02828 case HAL_PM_NETWORK_SLEEP:
02829 if (set_chip == AH_TRUE) {
02830 AR5K_REG_WRITE(AR5K_AR5212_SCR,
02831 AR5K_AR5212_SCR_SLE | sleep_duration);
02832 }
02833 staid |= AR5K_AR5212_STA_ID1_PWR_SV;
02834 break;
02835
02836 case HAL_PM_FULL_SLEEP:
02837 if (set_chip == AH_TRUE) {
02838 AR5K_REG_WRITE(AR5K_AR5212_SCR,
02839 AR5K_AR5212_SCR_SLE_SLP);
02840 }
02841 staid |= AR5K_AR5212_STA_ID1_PWR_SV;
02842 break;
02843
02844 case HAL_PM_AWAKE:
02845 if (set_chip == AH_FALSE)
02846 goto commit;
02847
02848 AR5K_REG_WRITE(AR5K_AR5212_SCR, AR5K_AR5212_SCR_SLE_WAKE);
02849
02850 for (i = 5000; i > 0; i--) {
02851
02852 if ((AR5K_REG_READ(AR5K_AR5212_PCICFG) &
02853 AR5K_AR5212_PCICFG_SPWR_DN) == 0)
02854 break;
02855
02856
02857 AR5K_DELAY(200);
02858 AR5K_REG_WRITE(AR5K_AR5212_SCR,
02859 AR5K_AR5212_SCR_SLE_WAKE);
02860 }
02861
02862
02863 if (i <= 0)
02864 return (AH_FALSE);
02865
02866 staid &= ~AR5K_AR5212_STA_ID1_PWR_SV;
02867 break;
02868
02869 default:
02870 return (AH_FALSE);
02871 }
02872
02873 commit:
02874 hal->ah_power_mode = mode;
02875
02876 AR5K_REG_WRITE(AR5K_AR5212_STA_ID1, staid);
02877
02878 return (AH_TRUE);
02879 }
02880
02881 HAL_POWER_MODE
02882 ar5k_ar5212_get_power_mode(struct ath_hal *hal)
02883 {
02884 AR5K_TRACE;
02885 return (hal->ah_power_mode);
02886 }
02887
02888 HAL_BOOL
02889 ar5k_ar5212_query_pspoll_support(struct ath_hal *hal)
02890 {
02891 AR5K_TRACE;
02892
02893 return (AH_FALSE);
02894 }
02895
02896 HAL_BOOL
02897 ar5k_ar5212_init_pspoll(struct ath_hal *hal)
02898 {
02899 AR5K_TRACE;
02900
02901
02902
02903 return (AH_FALSE);
02904 }
02905
02906 HAL_BOOL
02907 ar5k_ar5212_enable_pspoll(struct ath_hal *hal,
02908 u_int8_t *bssid,
02909 u_int16_t assoc_id)
02910 {
02911 AR5K_TRACE;
02912 return (AH_FALSE);
02913 }
02914
02915 HAL_BOOL
02916 ar5k_ar5212_disable_pspoll(struct ath_hal *hal)
02917 {
02918 AR5K_TRACE;
02919 return (AH_FALSE);
02920 }
02921
02922
02923
02924
02925
02926 void
02927 ar5k_ar5212_init_beacon(struct ath_hal *hal,
02928 u_int32_t next_beacon,
02929 u_int32_t interval)
02930 {
02931 u_int32_t timer1, timer2, timer3;
02932 AR5K_TRACE;
02933
02934
02935
02936
02937 switch (hal->ah_op_mode) {
02938 case HAL_M_STA:
02939 timer1 = 0x0000ffff;
02940 timer2 = 0x0007ffff;
02941 break;
02942
02943 default:
02944 timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) <<
02945 0x00000003;
02946 timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) <<
02947 0x00000003;
02948 }
02949
02950 timer3 = next_beacon +
02951 (hal->ah_atim_window ? hal->ah_atim_window : 1);
02952
02953
02954
02955
02956
02957 AR5K_REG_WRITE(AR5K_AR5212_TIMER0, next_beacon);
02958 AR5K_REG_WRITE(AR5K_AR5212_TIMER1, timer1);
02959 AR5K_REG_WRITE(AR5K_AR5212_TIMER2, timer2);
02960 AR5K_REG_WRITE(AR5K_AR5212_TIMER3, timer3);
02961
02962 AR5K_REG_WRITE(AR5K_AR5212_BEACON, interval &
02963 (AR5K_AR5212_BEACON_PERIOD | AR5K_AR5212_BEACON_RESET_TSF |
02964 AR5K_AR5212_BEACON_ENABLE));
02965 }
02966
02967 void
02968 ar5k_ar5212_set_beacon_timers(struct ath_hal *hal,
02969 const HAL_BEACON_STATE *state)
02970
02971
02972 {
02973 u_int32_t cfp_period, next_cfp, dtim, interval, next_beacon;
02974
02975 u_int32_t dtim_count = 0;
02976 u_int32_t cfp_count = 0;
02977 u_int32_t tsf = 0;
02978 AR5K_TRACE;
02979
02980
02981 if (state->bs_intval < 1)
02982 return;
02983
02984 interval = state->bs_intval;
02985 dtim = state->bs_dtimperiod;
02986
02987
02988
02989
02990 if (state->bs_cfpperiod > 0) {
02991
02992 cfp_period = state->bs_cfpperiod * state->bs_dtimperiod *
02993 state->bs_intval;
02994 next_cfp = (cfp_count * state->bs_dtimperiod + dtim_count) *
02995 state->bs_intval;
02996
02997 AR5K_REG_ENABLE_BITS(AR5K_AR5212_STA_ID1,
02998 AR5K_AR5212_STA_ID1_PCF);
02999 AR5K_REG_WRITE(AR5K_AR5212_CFP_PERIOD, cfp_period);
03000 AR5K_REG_WRITE(AR5K_AR5212_CFP_DUR, state->bs_cfpmaxduration);
03001 AR5K_REG_WRITE(AR5K_AR5212_TIMER2,
03002 (tsf + (next_cfp == 0 ? cfp_period : next_cfp)) << 3);
03003 } else {
03004
03005 AR5K_REG_DISABLE_BITS(AR5K_AR5212_STA_ID1,
03006 AR5K_AR5212_STA_ID1_PCF);
03007 }
03008
03009
03010
03011
03012 AR5K_REG_WRITE(AR5K_AR5212_TIMER0, state->bs_nexttbtt);
03013
03014
03015
03016
03017 AR5K_REG_WRITE(AR5K_AR5212_BEACON,
03018 (AR5K_REG_READ(AR5K_AR5212_BEACON) &~
03019 (AR5K_AR5212_BEACON_PERIOD | AR5K_AR5212_BEACON_TIM)) |
03020 AR5K_REG_SM(state->bs_timoffset ? state->bs_timoffset + 4 : 0,
03021 AR5K_AR5212_BEACON_TIM) | AR5K_REG_SM(state->bs_intval,
03022 AR5K_AR5212_BEACON_PERIOD));
03023
03024
03025
03026
03027 if ((AR5K_AR5212_RSSI_THR_BMISS >> AR5K_AR5212_RSSI_THR_BMISS_S) <
03028 state->bs_bmissthreshold)
03029 return;
03030
03031 AR5K_REG_WRITE_BITS(AR5K_AR5212_RSSI_THR_M,
03032 AR5K_AR5212_RSSI_THR_BMISS, state->bs_bmissthreshold);
03033
03034
03035
03036
03037 if ((state->bs_sleepduration > state->bs_intval) &&
03038 (roundup(state->bs_sleepduration, interval) ==
03039 state->bs_sleepduration))
03040 interval = state->bs_sleepduration;
03041
03042 if (state->bs_sleepduration > dtim &&
03043 (dtim == 0 || roundup(state->bs_sleepduration, dtim) ==
03044 state->bs_sleepduration))
03045 dtim = state->bs_sleepduration;
03046
03047 if (interval > dtim)
03048 return;
03049
03050 next_beacon = interval == dtim ?
03051 state->bs_nextdtim: state->bs_nexttbtt;
03052
03053 AR5K_REG_WRITE(AR5K_AR5212_SLEEP0,
03054 AR5K_REG_SM((state->bs_nextdtim - 3) << 3,
03055 AR5K_AR5212_SLEEP0_NEXT_DTIM) |
03056 AR5K_REG_SM(10, AR5K_AR5212_SLEEP0_CABTO) |
03057 AR5K_AR5212_SLEEP0_ENH_SLEEP_EN |
03058 AR5K_AR5212_SLEEP0_ASSUME_DTIM);
03059 AR5K_REG_WRITE(AR5K_AR5212_SLEEP1,
03060 AR5K_REG_SM((next_beacon - 3) << 3,
03061 AR5K_AR5212_SLEEP1_NEXT_TIM) |
03062 AR5K_REG_SM(10, AR5K_AR5212_SLEEP1_BEACON_TO));
03063 AR5K_REG_WRITE(AR5K_AR5212_SLEEP2,
03064 AR5K_REG_SM(interval, AR5K_AR5212_SLEEP2_TIM_PER) |
03065 AR5K_REG_SM(dtim, AR5K_AR5212_SLEEP2_DTIM_PER));
03066 }
03067
03068 void
03069 ar5k_ar5212_reset_beacon(struct ath_hal *hal)
03070 {
03071 AR5K_TRACE;
03072
03073
03074
03075 AR5K_REG_WRITE(AR5K_AR5212_TIMER0, 0);
03076
03077
03078
03079
03080 AR5K_REG_DISABLE_BITS(AR5K_AR5212_STA_ID1,
03081 AR5K_AR5212_STA_ID1_DEFAULT_ANTENNA | AR5K_AR5212_STA_ID1_PCF);
03082 AR5K_REG_WRITE(AR5K_AR5212_BEACON, AR5K_AR5212_BEACON_PERIOD);
03083 }
03084
03085 HAL_BOOL
03086 ar5k_ar5212_wait_for_beacon(struct ath_hal *hal,
03087 u_int32_t phys_addr)
03088 {
03089 HAL_BOOL ret;
03090 AR5K_TRACE;
03091
03092
03093
03094
03095 ret = ar5k_register_timeout(hal,
03096 AR5K_AR5212_QCU_STS(HAL_TX_QUEUE_ID_BEACON),
03097 AR5K_AR5212_QCU_STS_FRMPENDCNT, 0, AH_FALSE);
03098
03099 if (AR5K_REG_READ_Q(AR5K_AR5212_QCU_TXE, HAL_TX_QUEUE_ID_BEACON))
03100 return (AH_FALSE);
03101
03102 return (ret);
03103 }
03104
03105
03106
03107
03108
03109 HAL_BOOL
03110 ar5k_ar5212_is_intr_pending(struct ath_hal *hal)
03111 {
03112 return (AR5K_REG_READ(AR5K_AR5212_INTPEND) == 0 ? AH_FALSE : AH_TRUE);
03113 }
03114
03115 HAL_BOOL
03116 ar5k_ar5212_get_isr(struct ath_hal *hal,
03117 u_int32_t *interrupt_mask)
03118 {
03119 u_int32_t data;
03120
03121
03122
03123
03124 data = AR5K_REG_READ(AR5K_AR5212_RAC_PISR);
03125
03126
03127
03128
03129 *interrupt_mask = (data & HAL_INT_COMMON) & hal->ah_imr;
03130
03131 if (data == HAL_INT_NOCARD) {
03132 printk("%s: card not present!\n", __func__);
03133 return (AH_FALSE);
03134 }
03135
03136 if (data & (AR5K_AR5212_PISR_RXOK | AR5K_AR5212_PISR_RXERR))
03137 *interrupt_mask |= HAL_INT_RX;
03138
03139 if (data & (AR5K_AR5212_PISR_TXOK | AR5K_AR5212_PISR_TXERR))
03140 *interrupt_mask |= HAL_INT_TX;
03141
03142 if (data & (AR5K_AR5212_PISR_HIUERR))
03143 *interrupt_mask |= HAL_INT_FATAL;
03144
03145
03146
03147
03148 if (((*interrupt_mask) & AR5K_AR5212_PISR_RXPHY) &&
03149 hal->ah_radar.r_enabled == AH_TRUE)
03150 ar5k_radar_alert(hal);
03151
03152 if (*interrupt_mask == 0)
03153 AR5K_PRINTF("0x%08x\n", data);
03154
03155 return (AH_TRUE);
03156 }
03157
03158 u_int32_t
03159 ar5k_ar5212_get_intr(struct ath_hal *hal)
03160 {
03161 AR5K_TRACE;
03162
03163 return (hal->ah_imr);
03164 }
03165
03166 HAL_INT
03167 ar5k_ar5212_set_intr(struct ath_hal *hal,
03168 HAL_INT new_mask)
03169 {
03170 HAL_INT old_mask, int_mask;
03171
03172
03173
03174
03175
03176 AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_DISABLE);
03177
03178 old_mask = hal->ah_imr;
03179
03180
03181
03182
03183
03184 int_mask = new_mask & HAL_INT_COMMON;
03185
03186 if (new_mask & HAL_INT_RX)
03187 int_mask |=
03188 AR5K_AR5212_PIMR_RXOK |
03189 AR5K_AR5212_PIMR_RXERR |
03190 AR5K_AR5212_PIMR_RXORN |
03191 AR5K_AR5212_PIMR_RXDESC;
03192
03193 if (new_mask & HAL_INT_TX)
03194 int_mask |=
03195 AR5K_AR5212_PIMR_TXOK |
03196 AR5K_AR5212_PIMR_TXERR |
03197 AR5K_AR5212_PIMR_TXDESC |
03198 AR5K_AR5212_PIMR_TXURN;
03199
03200 if (new_mask & HAL_INT_FATAL) {
03201 int_mask |= AR5K_AR5212_PIMR_HIUERR;
03202 AR5K_REG_ENABLE_BITS(AR5K_AR5212_SIMR2,
03203 AR5K_AR5212_SIMR2_MCABT |
03204 AR5K_AR5212_SIMR2_SSERR |
03205 AR5K_AR5212_SIMR2_DPERR);
03206 }
03207
03208 AR5K_REG_WRITE(AR5K_AR5212_PIMR, int_mask);
03209
03210
03211 hal->ah_imr = new_mask;
03212
03213
03214 AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_ENABLE);
03215
03216 return (old_mask);
03217 }
03218
03219
03220
03221
03222
03223 HAL_BOOL
03224 ar5k_ar5212_get_capabilities(struct ath_hal *hal)
03225 {
03226 u_int16_t ee_header;
03227
03228
03229 ee_header = hal->ah_capabilities.cap_eeprom.ee_header;
03230
03231
03232
03233
03234
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244
03245 if (AR5K_EEPROM_HDR_11A(ee_header)) {
03246 hal->ah_capabilities.cap_range.range_5ghz_min = 5005;
03247 hal->ah_capabilities.cap_range.range_5ghz_max = 6100;
03248
03249
03250 hal->ah_capabilities.cap_mode =
03251 HAL_MODE_11A | HAL_MODE_TURBO;
03252 }
03253
03254
03255 if (AR5K_EEPROM_HDR_11B(ee_header) || AR5K_EEPROM_HDR_11G(ee_header)) {
03256 hal->ah_capabilities.cap_range.range_2ghz_min = 2412;
03257 hal->ah_capabilities.cap_range.range_2ghz_max = 2732;
03258 hal->ah_capabilities.cap_mode |= HAL_MODE_11B;
03259
03260 if (AR5K_EEPROM_HDR_11B(ee_header))
03261 hal->ah_capabilities.cap_mode |= HAL_MODE_11B;
03262 if (AR5K_EEPROM_HDR_11G(ee_header))
03263 hal->ah_capabilities.cap_mode |= HAL_MODE_11G;
03264 }
03265
03266
03267 hal->ah_gpio_npins = AR5K_AR5212_NUM_GPIO;
03268
03269
03270 hal->ah_capabilities.cap_queues.q_tx_num = AR5K_AR5212_TX_NUM_QUEUES;
03271
03272 return (AH_TRUE);
03273 }
03274
03275 void
03276 ar5k_ar5212_radar_alert(struct ath_hal *hal,
03277 HAL_BOOL enable)
03278 {
03279 AR5K_TRACE;
03280
03281
03282
03283 AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_DISABLE);
03284
03285 if (enable == AH_TRUE) {
03286 AR5K_REG_WRITE(AR5K_AR5212_PHY_RADAR,
03287 AR5K_AR5212_PHY_RADAR_ENABLE);
03288 AR5K_REG_ENABLE_BITS(AR5K_AR5212_PIMR,
03289 AR5K_AR5212_PIMR_RXPHY);
03290 } else {
03291 AR5K_REG_WRITE(AR5K_AR5212_PHY_RADAR,
03292 AR5K_AR5212_PHY_RADAR_DISABLE);
03293 AR5K_REG_DISABLE_BITS(AR5K_AR5212_PIMR,
03294 AR5K_AR5212_PIMR_RXPHY);
03295 }
03296
03297 AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_ENABLE);
03298 }
03299
03300
03301
03302
03303
03304 HAL_BOOL
03305 ar5k_ar5212_eeprom_is_busy(struct ath_hal *hal)
03306 {
03307 AR5K_TRACE;
03308 return (AR5K_REG_READ(AR5K_AR5212_CFG) & AR5K_AR5212_CFG_EEBS ?
03309 AH_TRUE : AH_FALSE);
03310 }
03311
03312 int
03313 ar5k_ar5212_eeprom_read(struct ath_hal *hal,
03314 u_int32_t offset,
03315 u_int16_t *data)
03316 {
03317 u_int32_t status, i;
03318
03319
03320
03321
03322 AR5K_REG_WRITE(AR5K_AR5212_EEPROM_BASE, (u_int8_t)offset);
03323 AR5K_REG_ENABLE_BITS(AR5K_AR5212_EEPROM_CMD,
03324 AR5K_AR5212_EEPROM_CMD_READ);
03325
03326 for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
03327 status = AR5K_REG_READ(AR5K_AR5212_EEPROM_STATUS);
03328 if (status & AR5K_AR5212_EEPROM_STAT_RDDONE) {
03329 if (status & AR5K_AR5212_EEPROM_STAT_RDERR)
03330 return (EIO);
03331 *data = (u_int16_t)
03332 (AR5K_REG_READ(AR5K_AR5212_EEPROM_DATA) & 0xffff);
03333 return (0);
03334 }
03335 AR5K_DELAY(15);
03336 }
03337
03338 return (ETIMEDOUT);
03339 }
03340
03341 int
03342 ar5k_ar5212_eeprom_write(struct ath_hal *hal,
03343 u_int32_t offset,
03344 u_int16_t data)
03345 {
03346 u_int32_t status, timeout;
03347 AR5K_TRACE;
03348
03349
03350 AR5K_REG_ENABLE_BITS(AR5K_AR5212_EEPROM_CMD,
03351 AR5K_AR5212_EEPROM_CMD_RESET);
03352 AR5K_REG_ENABLE_BITS(AR5K_AR5212_EEPROM_CMD,
03353 AR5K_AR5212_EEPROM_CMD_WRITE);
03354
03355
03356
03357
03358 AR5K_REG_WRITE(AR5K_AR5212_EEPROM_BASE, (u_int8_t)offset - 1);
03359
03360 for (timeout = 10000; timeout > 0; timeout--) {
03361 AR5K_DELAY(1);
03362 status = AR5K_REG_READ(AR5K_AR5212_EEPROM_STATUS);
03363 if (status & AR5K_AR5212_EEPROM_STAT_WRDONE) {
03364 if (status & AR5K_AR5212_EEPROM_STAT_WRERR)
03365 return (EIO);
03366 return (0);
03367 }
03368 }
03369
03370 return (ETIMEDOUT);
03371 }
03372
03373
03374
03375
03376
03377 HAL_BOOL
03378 ar5k_ar5212_txpower(struct ath_hal *hal,
03379 HAL_CHANNEL *channel,
03380 u_int txpower)
03381 {
03382 HAL_BOOL tpc = hal->ah_txpower.txp_tpc;
03383 int i;
03384 AR5K_TRACE;
03385
03386 if (txpower > AR5K_TUNE_MAX_TXPOWER) {
03387 AR5K_PRINTF("invalid tx power: %u\n", txpower);
03388 return (AH_FALSE);
03389 }
03390
03391
03392 bzero(&hal->ah_txpower, sizeof(hal->ah_txpower));
03393 hal->ah_txpower.txp_tpc = tpc;
03394
03395
03396 ar5k_txpower_table(hal, channel, txpower);
03397
03398
03399
03400
03401 for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
03402 AR5K_REG_WRITE(AR5K_AR5212_PHY_PCDAC_TXPOWER(i),
03403 ((((hal->ah_txpower.txp_pcdac[(i << 1) + 1] << 8) | 0xff) &
03404 0xffff) << 16) | (((hal->ah_txpower.txp_pcdac[i << 1] << 8)
03405 | 0xff) & 0xffff));
03406 }
03407
03408 AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE1,
03409 AR5K_TXPOWER_OFDM(3, 24) | AR5K_TXPOWER_OFDM(2, 16)
03410 | AR5K_TXPOWER_OFDM(1, 8) | AR5K_TXPOWER_OFDM(0, 0));
03411
03412 AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE2,
03413 AR5K_TXPOWER_OFDM(7, 24) | AR5K_TXPOWER_OFDM(6, 16)
03414 | AR5K_TXPOWER_OFDM(5, 8) | AR5K_TXPOWER_OFDM(4, 0));
03415
03416 AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE3,
03417 AR5K_TXPOWER_CCK(10, 24) | AR5K_TXPOWER_CCK(9, 16)
03418 | AR5K_TXPOWER_CCK(15, 8) | AR5K_TXPOWER_CCK(8, 0));
03419
03420 AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE4,
03421 AR5K_TXPOWER_CCK(14, 24) | AR5K_TXPOWER_CCK(13, 16)
03422 | AR5K_TXPOWER_CCK(12, 8) | AR5K_TXPOWER_CCK(11, 0));
03423
03424 if (hal->ah_txpower.txp_tpc == AH_TRUE) {
03425 AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE_MAX,
03426 AR5K_AR5212_PHY_TXPOWER_RATE_MAX_TPC_ENABLE |
03427 AR5K_TUNE_MAX_TXPOWER);
03428 } else {
03429 AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE_MAX,
03430 AR5K_AR5212_PHY_TXPOWER_RATE_MAX |
03431 AR5K_TUNE_MAX_TXPOWER);
03432 }
03433
03434 return (AH_TRUE);
03435 }
03436
03437
03438
03439 const void
03440 ar5k_ar5212_fill(struct ath_hal *hal)
03441 {
03442
03443 AR5K_TRACE;
03444
03445
03446 hal->ah_magic = AR5K_AR5212_MAGIC;
03447
03448
03449
03450
03451 hal->ah_getRateTable = ar5k_ar5212_get_rate_table;
03452 hal->ah_detach = ar5k_ar5212_detach;
03453
03454
03455
03456
03457 hal->ah_reset = ar5k_ar5212_reset;
03458 hal->ah_phyDisable = ar5k_ar5212_phy_disable;
03459
03460 hal->ah_perCalibration = ar5k_ar5212_calibrate;
03461 hal->ah_setPCUConfig = ar5k_ar5212_set_opmode;
03462 hal->ah_setTxPowerLimit = ar5k_ar5212_set_txpower_limit;
03463
03464
03465
03466
03467 hal->ah_updateTxTrigLevel = ar5k_ar5212_update_tx_triglevel;
03468 hal->ah_setupTxQueue = ar5k_ar5212_setup_tx_queue;
03469 hal->ah_setTxQueueProps = ar5k_ar5212_setup_tx_queueprops;
03470 hal->ah_getTxQueueProps = ar5k_ar5212_get_tx_queueprops;
03471 hal->ah_releaseTxQueue = ar5k_ar5212_release_tx_queue;
03472 hal->ah_resetTxQueue = ar5k_ar5212_reset_tx_queue;
03473 hal->ah_getTxDP = ar5k_ar5212_get_tx_buf;
03474 hal->ah_setTxDP = ar5k_ar5212_put_tx_buf;
03475 hal->ah_numTxPending = ar5k_ar5212_num_tx_pending;
03476
03477 hal->ah_startTxDma = ar5k_ar5212_tx_start;
03478 hal->ah_stopTxDma = ar5k_ar5212_stop_tx_dma;
03479 hal->ah_updateCTSForBursting = NULL;
03480 hal->ah_setupTxDesc = ar5k_ar5212_setup_tx_desc;
03481 hal->ah_setupXTxDesc = ar5k_ar5212_setup_xtx_desc;
03482 hal->ah_fillTxDesc = ar5k_ar5212_fill_tx_desc;
03483 hal->ah_procTxDesc = ar5k_ar5212_proc_tx_desc;
03484 hal->ah_getTxIntrQueue = ar5k_ar5212_get_tx_inter_queue;
03485
03486
03487
03488
03489 hal->ah_getRxDP = ar5k_ar5212_get_rx_buf;
03490 hal->ah_setRxDP = ar5k_ar5212_put_rx_buf;
03491 hal->ah_enableReceive = ar5k_ar5212_start_rx;
03492 hal->ah_stopDmaReceive = ar5k_ar5212_stop_rx_dma;
03493
03494 hal->ah_startPcuReceive = ar5k_ar5212_start_rx_pcu;
03495 hal->ah_stopPcuReceive = ar5k_ar5212_stop_pcu_recv;
03496 hal->ah_setMulticastFilter = ar5k_ar5212_set_mcast_filter;
03497 hal->ah_setMulticastFilterIndex = ar5k_ar5212_set_mcast_filterindex;
03498 hal->ah_clrMulticastFilterIndex = ar5k_ar5212_clear_mcast_filter_idx;
03499 hal->ah_getRxFilter = ar5k_ar5212_get_rx_filter;
03500 hal->ah_setRxFilter = ar5k_ar5212_set_rx_filter;
03501 hal->ah_setupRxDesc = ar5k_ar5212_setup_rx_desc;
03502 hal->ah_procRxDesc = ar5k_ar5212_proc_rx_desc;
03503 hal->ah_rxMonitor = ar5k_ar5212_set_rx_signal;
03504 hal->ah_procMibEvent = ar5k_ar5212_proc_mib_event;
03505
03506
03507
03508
03509 hal->ah_getCapability = ar5k_ar5212_get_capability;
03510 hal->ah_setCapability = ar5k_ar5212_set_capability;
03511 hal->ah_getDiagState = ar5k_ar5212_get_diag_state;
03512 hal->ah_getMacAddress = ar5k_ar5212_get_lladdr;
03513 hal->ah_setMacAddress = ar5k_ar5212_set_lladdr;
03514 hal->ah_setRegulatoryDomain = ar5k_ar5212_set_regdomain;
03515 hal->ah_setLedState = ar5k_ar5212_set_ledstate;
03516 hal->ah_writeAssocid = ar5k_ar5212_set_associd;
03517 hal->ah_gpioCfgInput = ar5k_ar5212_set_gpio_input;
03518 hal->ah_gpioCfgOutput= ar5k_ar5212_set_gpio_output;
03519 hal->ah_gpioGet = ar5k_ar5212_get_gpio;
03520 hal->ah_gpioSet = ar5k_ar5212_set_gpio;
03521 hal->ah_gpioSetIntr = ar5k_ar5212_set_gpio_intr;
03522 hal->ah_getTsf32 = ar5k_ar5212_get_tsf32;
03523 hal->ah_getTsf64 = ar5k_ar5212_get_tsf64;
03524 hal->ah_resetTsf = ar5k_ar5212_reset_tsf;
03525 hal->ah_detectCardPresent = ar5k_ar5212_detect_card_present;
03526 hal->ah_updateMibCounters = ar5k_ar5212_update_mib_counters;
03527 hal->ah_getRfGain = ar5k_ar5212_get_rf_gain;
03528 hal->ah_getDefAntenna = ar5k_ar5212_get_def_antenna;
03529 hal->ah_setDefAntenna = ar5k_ar5212_set_def_antenna;
03530 hal->ah_setSlotTime = ar5k_ar5212_set_slot_time;
03531 hal->ah_getSlotTime = ar5k_ar5212_get_slot_time;
03532 hal->ah_setAckTimeout = ar5k_ar5212_set_ack_timeout;
03533 hal->ah_getAckTimeout = ar5k_ar5212_get_ack_timeout;
03534 hal->ah_setCTSTimeout = ar5k_ar5212_set_cts_timeout;
03535 hal->ah_getCTSTimeout = ar5k_ar5212_get_cts_timeout;
03536
03537
03538
03539
03540 hal->ah_getKeyCacheSize = ar5k_ar5212_get_keycache_size;
03541 hal->ah_resetKeyCacheEntry = ar5k_ar5212_reset_key;
03542 hal->ah_isKeyCacheEntryValid = ar5k_ar5212_is_key_valid;
03543 hal->ah_setKeyCacheEntry = ar5k_ar5212_set_key;
03544 hal->ah_setKeyCacheEntryMac = ar5k_ar5212_set_key_lladdr;
03545
03546
03547
03548
03549 hal->ah_setPowerMode = ar5k_ar5212_set_power;
03550 hal->ah_getPowerMode = ar5k_ar5212_get_power_mode;
03551 hal->ah_initPSPoll = ar5k_ar5212_init_pspoll;
03552 hal->ah_enablePSPoll = ar5k_ar5212_enable_pspoll;
03553 hal->ah_disablePSPoll = ar5k_ar5212_disable_pspoll;
03554
03555
03556
03557
03558 hal->ah_beaconInit = ar5k_ar5212_init_beacon;
03559 hal->ah_setStationBeaconTimers = ar5k_ar5212_set_beacon_timers;
03560 hal->ah_resetStationBeaconTimers = ar5k_ar5212_reset_beacon;
03561 hal->ah_waitForBeaconDone = ar5k_ar5212_wait_for_beacon;
03562
03563
03564
03565
03566 hal->ah_isInterruptPending = ar5k_ar5212_is_intr_pending;
03567 hal->ah_getPendingInterrupts = ar5k_ar5212_get_isr;
03568 hal->ah_getInterrupts = ar5k_ar5212_get_intr;
03569 hal->ah_setInterrupts = ar5k_ar5212_set_intr;
03570
03571
03572
03573
03574 hal->ah_get_capabilities = ar5k_ar5212_get_capabilities;
03575 hal->ah_radarlert = ar5k_ar5212_radar_alert;
03576
03577
03578
03579
03580 hal->ah_eeprom_is_busy = ar5k_ar5212_eeprom_is_busy;
03581 hal->ah_eeprom_read = ar5k_ar5212_eeprom_read;
03582 hal->ah_eeprom_write = ar5k_ar5212_eeprom_write;
03583
03584 hal->ah_dump_state = ar5k_ar5212_dump_state;
03585 }
03586