Main Page | Data Structures | Directories | File List | Data Fields | Globals

ar5212.c

Go to the documentation of this file.
00001 /*      $OpenBSD: ar5212.c,v 1.23 2005/07/30 17:13:17 reyk Exp $ */
00002 
00003 /*
00004  * Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
00005  *
00006  * Permission to use, copy, modify, and distribute this software for any
00007  * purpose with or without fee is hereby granted, provided that the above
00008  * copyright notice and this permission notice appear in all copies.
00009  *
00010  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
00011  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00012  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
00013  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00014  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00015  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00016  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00017  */
00018 
00019 /*
00020  * HAL interface for the Atheros AR5001 Wireless LAN chipset
00021  * (AR5212 + AR5111/AR5112).
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  * Initial register setting for the AR5212
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  * crap so we can read registers out of proc
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      /* intially allocate both read and write buffers */
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      /* now read the data into the buffer */
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              /* parse what whas written to the proc file */
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                      /* advance to space */
00200                      while (p[0] && p[0] != '\n' && p[0] != 32)
00201                              p++;
00202                      
00203                      /* advance past space */
00204                      while (p[0] && p[0] == 32) {
00205                              p++;
00206                      }
00207                      
00208                      value = simple_strtol(p, NULL, 0);
00209                      //printk("writing reg 0x%08x value 0x%08x\n", reg, value);
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         /* Bring device out of sleep and reset it's units */
00247         if (ar5k_ar5212_nic_wakeup(hal, AR5K_INIT_MODE) != AH_TRUE)
00248                 return (0);
00249 
00250         /* Get MAC, PHY and RADIO revisions */
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         /* Get the 2GHz radio revision if it's supported */
00261         if (hal->ah_macVersion >= AR5K_SREV_VER_AR5211)
00262                 hal->ah_analog2GhzRev =
00263                     ar5k_ar5212_radio_revision(hal, HAL_CHIP_2GHZ);
00264 
00265         /* Identify the chipset (this has to be done in an early step) */
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         /* Read-and-clear */
00296         AR5K_REG_READ(AR5K_AR5212_RXDP);
00297 
00298         /*
00299          * Reset the device and wait until success
00300          */
00301         AR5K_REG_WRITE(AR5K_AR5212_RC, val);
00302 
00303         /* Wait at least 128 PCI clocks */
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          * Reset configuration register
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          * Get channel mode flags
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          * Reset and wakeup the device
00373          */
00374 
00375         /* ...reset chipset and PCI device */
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         /* ...wakeup */
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         /* ...final warm reset */
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         /* ...set the PHY operating mode */
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          * Set the radio chip access register
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         /* ...wait until PHY is ready and read the selected radio revision */
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         /* Reset to the 5GHz mode */
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          * Free HAL structure, assume interrupts are down
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          * Save some registers before a reset
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          * Initialize operating mode
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         /* PHY access enable */
00577         AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);
00578         
00579         /*
00580          * Write initial mode settings
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          * Write initial register settings
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          * Write initial RF gain settings
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          * Set rate duration table
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          * Set TX power (XXX use txpower from net80211)
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          * Write RF registers
00674          */
00675         if (ar5k_rfregs(hal, channel, mode) == AH_FALSE) {
00676                 *status = HAL_EINVAL;
00677                 return (AH_FALSE);
00678         }
00679         
00680         /*
00681          * Configure additional registers
00682          */
00683 
00684         /* OFDM timings */
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         /* Set antenna mode */
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         /* Commit values from EEPROM */
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          * Restore saved values
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          * Misc
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          * Set Rx/Tx DMA Configuration
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          * Set channel and calibrate the PHY
00807          */
00808         if (ar5k_channel(hal, channel) == AH_FALSE)
00809                 return (AH_FALSE);
00810 
00811         /*
00812          * Enable the PHY and wait until completion
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          * Start calibration
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          * Reset queues and start beacon timers at the end of the reset routine
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         /* Pre-enable interrupts */
00853         ar5k_ar5212_set_intr(hal, HAL_INT_RX | HAL_INT_TX | HAL_INT_FATAL);
00854 
00855         /*
00856          * Set RF kill flags if supported by the device (read from the EEPROM)
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          * Set the 32MHz reference clock
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          * Disable beacons and reset the register
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         /* XXX */
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          * Set PCU registers
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         /* Commit new IQ value */
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         /* Start noise floor calibration */
00967         AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_AGCCTL,
00968             AR5K_AR5212_PHY_AGCCTL_NF);
00969 
00970         /* Request RF gain */
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  * Transmit functions
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          * Disable interrupts by setting the mask
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          * Update trigger level on success
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          * Restore interrupt mask
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          * Get queue by type
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          * Setup internal queue structure
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         /* This queue will be skipped in further operations */
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          * Set registers by channel mode
01143          */
01144         if (0 /* XXX IEEE80211_IS_CHAN_XR(channel) */) {
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          * Set retry limits
01160          */
01161         if (hal->ah_software_retry == AH_TRUE) {
01162                 /* XXX Need to test this */
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          * Set initial content window (cw_min/cw_max)
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          * Set misc registers
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          * Set registers by queue type
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          * Enable tx queue in the secondary interrupt mask registers
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          * Get the transmit queue descriptor pointer from the selected queue
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          * Set the transmit queue descriptor pointer for the selected queue
01330          * (this won't work if the queue is still active)
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         /* Return if queue is disabled */
01361         if (AR5K_REG_READ_Q(AR5K_AR5212_QCU_TXD, queue)) {
01362                 printk("%s: q disabled?\n", __func__);
01363                 return (AH_FALSE);
01364         }
01365         /* Start queue */
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          * Schedule TX disable and wait until queue is empty
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         /* Clear register */
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         /* Clear status descriptor */
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          * Validate input
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          * WEP crap
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          * RTS/CTS
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         /* Validate segment length and initialize the descriptor */
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         /* No frame has been send or error */
01579         if ((tx_status->tx_status_1 & AR5K_AR5212_DESC_TX_STATUS1_DONE) == 0) {
01580                 return (HAL_EINPROGRESS);
01581         }
01582 
01583         /*
01584          * Get descriptor status
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  * Receive functions
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          * It may take some time to disable the DMA receive unit
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         /* Set the multicat filter */
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         /* Overlay on error */
01858         rx_err = (struct ar5k_ar5212_rx_error*)&desc->ds_hw[0];
01859 
01860         /* No frame received / not ready */
01861         if ((rx_status->rx_status_1 & AR5K_AR5212_DESC_RX_STATUS1_DONE) == 0) {
01862                 AR5K_TRACE;
01863                 return (HAL_EINPROGRESS);
01864         }
01865 
01866         /* XXX */
01867         if (AR5K_REG_READ(AR5K_AR5212_RXDP) == phys_addr) {
01868                 AR5K_TRACE;
01869                 return (HAL_EINPROGRESS);
01870         }
01871         /*
01872          * Frame receive status
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          * Key table status
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          * Receive/descriptor errors
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         /* Signal state monitoring is not yet supported */
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  * Misc functions
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          * We'll ignore this right now. This seems to be some kind of an obscure
02275          * debugging interface for the binary-only HAL.
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         /* Set new station ID */
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          * Some blinking values, define at your wish
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 ; /*XXX */
02374 
02375         AR5K_TRACE;
02376 
02377         /*
02378          * Set simple BSSID mask
02379          */
02380         AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM0, 0xfffffff);
02381         AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM1, 0xfffffff);
02382 
02383         /*
02384          * Set BSSID which triggers the "SME Join" operation
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         /* GPIO input magic */
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         /* GPIO output magic */
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          * Set the GPIO interrupt
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         /* Enable GPIO interrupts */
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          * Checking the EEPROM's magic value could be an indication
02543          * if the card is still present. I didn't find another suitable
02544          * way to do this.
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         /* Read-And-Clear */
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         /* Reset profile count registers */
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  * Key table (WEP) functions
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         /* Set NULL encryption */
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          * Check the validation flag at the end of the entry
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                 /* Unsupported key length (not WEP40/104/128) */
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          * Invalid entry (key table overflow)
02792          */
02793         AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
02794 
02795         /* MAC may be NULL if it's a broadcast key */
02796         //mac_v = mac == 0 ? etherbroadcastaddr : mac;
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  * Power management functions
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                 /* fallthrough */
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                         /* Check if the AR5212 did wake up */
02852                         if ((AR5K_REG_READ(AR5K_AR5212_PCICFG) &
02853                             AR5K_AR5212_PCICFG_SPWR_DN) == 0)
02854                                 break;
02855 
02856                         /* Wait a bit and retry */
02857                         AR5K_DELAY(200);
02858                         AR5K_REG_WRITE(AR5K_AR5212_SCR,
02859                             AR5K_AR5212_SCR_SLE_WAKE);
02860                 }
02861 
02862                 /* Fail if the AR5212 didn't wake up */
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         /* nope */
02893         return (AH_FALSE);
02894 }
02895 
02896 HAL_BOOL
02897 ar5k_ar5212_init_pspoll(struct ath_hal *hal)
02898 {
02899         AR5K_TRACE;
02900         /*
02901          * Not used on the AR5212
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  * Beacon functions
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          * Set the additional timers by mode
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          * Enable all timers and set the beacon register
02955          * (next beacon, DMA beacon, software beacon, ATIM window time)
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; /* XXX */
02976         u_int32_t cfp_count = 0; /* XXX */
02977         u_int32_t tsf = 0; /* XXX */
02978         AR5K_TRACE;
02979 
02980         /* Return on an invalid beacon state */
02981         if (state->bs_intval < 1)
02982                 return;
02983 
02984         interval = state->bs_intval;
02985         dtim = state->bs_dtimperiod;
02986 
02987         /*
02988          * PCF support?
02989          */
02990         if (state->bs_cfpperiod > 0) {
02991                 /* Enable CFP mode and set the CFP and timer registers */
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                 /* Disable PCF mode */
03005                 AR5K_REG_DISABLE_BITS(AR5K_AR5212_STA_ID1,
03006                     AR5K_AR5212_STA_ID1_PCF);
03007         }
03008 
03009         /*
03010          * Enable the beacon timer register
03011          */
03012         AR5K_REG_WRITE(AR5K_AR5212_TIMER0, state->bs_nexttbtt);
03013 
03014         /*
03015          * Start the beacon timers
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          * Write new beacon miss threshold, if it appears to be valid
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          * Set sleep registers
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          * Disable beacon timer
03074          */
03075         AR5K_REG_WRITE(AR5K_AR5212_TIMER0, 0);
03076 
03077         /*
03078          * Disable some beacon register values
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          * Wait for beaconn queue to be done
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  * Interrupt handling
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          * Read interrupt status from the Read-And-Clear shadow register
03123          */
03124         data = AR5K_REG_READ(AR5K_AR5212_RAC_PISR);
03125 
03126         /*
03127          * Get abstract interrupt mask (HAL-compatible)
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          * Special interrupt handling (not caught by the driver)
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         /* Return the interrupt mask stored previously */
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          * Disable card interrupts to prevent any race conditions
03174          * (they will be re-enabled afterwards).
03175          */
03176         AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_DISABLE);
03177 
03178         old_mask = hal->ah_imr;
03179 
03180         /*
03181          * Add additional, chipset-dependent interrupt mask flags
03182          * and write them to the IMR (interrupt mask register).
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         /* Store new interrupt mask */
03211         hal->ah_imr = new_mask;
03212 
03213         /* ..re-enable interrupts */
03214         AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_ENABLE);
03215 
03216         return (old_mask);
03217 }
03218 
03219 /*
03220  * Misc internal functions
03221  */
03222 
03223 HAL_BOOL
03224 ar5k_ar5212_get_capabilities(struct ath_hal *hal)
03225 {
03226         u_int16_t ee_header;
03227 
03228         /* Capabilities stored in the EEPROM */
03229         ee_header = hal->ah_capabilities.cap_eeprom.ee_header;
03230 
03231         /*
03232          * XXX The AR5212 tranceiver supports frequencies from 4920 to 6100GHz
03233          * XXX and from 2312 to 2732GHz. There are problems with the current
03234          * XXX ieee80211 implementation because the IEEE channel mapping
03235          * XXX does not support negative channel numbers (2312MHz is channel
03236          * XXX -19). Of course, this doesn't matter because these channels
03237          * XXX are out of range but some regulation domains like MKK (Japan)
03238          * XXX will support frequencies somewhere around 4.8GHz.
03239          */
03240 
03241         /*
03242          * Set radio capabilities
03243          */
03244 
03245         if (AR5K_EEPROM_HDR_11A(ee_header)) {
03246                 hal->ah_capabilities.cap_range.range_5ghz_min = 5005; /* 4920 */
03247                 hal->ah_capabilities.cap_range.range_5ghz_max = 6100;
03248 
03249                 /* Set supported modes */
03250                 hal->ah_capabilities.cap_mode =
03251                     HAL_MODE_11A | HAL_MODE_TURBO;
03252         }
03253 
03254         /* This chip will support 802.11b if the 2GHz radio is connected */
03255         if (AR5K_EEPROM_HDR_11B(ee_header) || AR5K_EEPROM_HDR_11G(ee_header)) {
03256                 hal->ah_capabilities.cap_range.range_2ghz_min = 2412; /* 2312 */
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         /* GPIO */
03267         hal->ah_gpio_npins = AR5K_AR5212_NUM_GPIO;
03268 
03269         /* Set number of supported TX queues */
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          * Enable radar detection
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  * EEPROM access functions
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          * Initialize EEPROM access
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         /* Enable eeprom access */
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          * Prime write pump
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  * TX power setup
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         /* Reset TX power values */
03392         bzero(&hal->ah_txpower, sizeof(hal->ah_txpower));
03393         hal->ah_txpower.txp_tpc = tpc;
03394 
03395         /* Initialize TX power table */
03396         ar5k_txpower_table(hal, channel, txpower);
03397 
03398         /* 
03399          * Write TX power values
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          * Init/Exit functions
03450          */
03451         hal->ah_getRateTable = ar5k_ar5212_get_rate_table;
03452         hal->ah_detach =  ar5k_ar5212_detach;
03453 
03454         /*
03455          * Reset functions
03456          */
03457         hal->ah_reset = ar5k_ar5212_reset;
03458         hal->ah_phyDisable = ar5k_ar5212_phy_disable;
03459         //hal->ah_set_opmode = 
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          * TX functions
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          * RX functions
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          * Misc functions
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          * Key table (WEP functions
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          * Power management functions
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          * Beacon functions
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          * Interrupt functions
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          * Chipset functions (ar5k-specific, non-HAL)
03573          */
03574         hal->ah_get_capabilities = ar5k_ar5212_get_capabilities;
03575         hal->ah_radarlert = ar5k_ar5212_radar_alert;
03576 
03577         /*
03578          * EEPROM access
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 

Generated on Mon Nov 21 15:58:10 2005 for openwifi by  doxygen 1.4.1