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

if_ath.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2004 Massachusetts Institute of Technology
00003  * John Bicket
00004  */
00005 
00006 /*
00007  * Originally derived from the following.
00008  */
00009 /*-
00010  * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions
00015  * are met:
00016  * 1. Redistributions of source code must retain the above copyright
00017  *    notice, this list of conditions and the following disclaimer,
00018  *    without modification.
00019  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
00020  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
00021  *    redistribution must be conditioned upon including a substantially
00022  *    similar Disclaimer requirement for further binary redistribution.
00023  * 3. Neither the names of the above-listed copyright holders nor the names
00024  *    of any contributors may be used to endorse or promote products derived
00025  *    from this software without specific prior written permission.
00026  *
00027  * Alternatively, this software may be distributed under the terms of the
00028  * GNU General Public License ("GPL") version 2 as published by the Free
00029  * Software Foundation.
00030  *
00031  * NO WARRANTY
00032  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00033  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00034  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
00035  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
00036  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
00037  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00038  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00039  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00040  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00041  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
00042  * THE POSSIBILITY OF SUCH DAMAGES.
00043  *
00044  * $Id: if_ath.c,v 1.59 2005/04/19 14:38:23 biswas Exp $
00045  */
00046 
00047 /*
00048  * Driver for the Atheros Wireless LAN controller.
00049  *
00050  * This software is derived from work of Atsushi Onoe; his contribution
00051  * is greatly appreciated.
00052  */
00053 #include <linux/config.h>
00054 #include <linux/version.h>
00055 #include <linux/module.h>
00056 #include <linux/init.h>
00057 #include <linux/skbuff.h>
00058 #include <linux/netdevice.h>
00059 #include <linux/random.h>
00060 
00061 #include <linux/delay.h>
00062 #include <linux/cache.h>
00063 #include <linux/sysctl.h>
00064 #include <linux/proc_fs.h>
00065 #include <linux/if_arp.h>
00066 #include <linux/wait.h>
00067 #include <linux/timer.h>
00068 
00069 
00070 #include <linux/netdevice.h>
00071 #include <linux/etherdevice.h>
00072 #include <linux/if_ether.h>
00073 #include <asm/uaccess.h>
00074 #include "../../click_wifi/packet_anno.h"
00075 
00076 #define AR_DEBUG
00077 #include "if_athvar.h"
00078 #include "ah_desc.h"
00079 #include "ah_devid.h"                   /* XXX to identify IBM cards */
00080 #include "if_llc.h"
00081 //#include "ah_osdep.h"
00082 #include "if_ath_bus.h"
00083 #include "if_ethersubr.h"
00084 
00085 
00086 #ifndef timeradd
00087 # define timeradd(a, b, result)                                               \
00088   do {                                                                        \
00089     (result)->tv_sec = (a)->tv_sec + (b)->tv_sec;                             \
00090     (result)->tv_usec = (a)->tv_usec + (b)->tv_usec;                          \
00091     if ((result)->tv_usec >= 1000000)                                         \
00092       {                                                                       \
00093         ++(result)->tv_sec;                                                   \
00094         (result)->tv_usec -= 1000000;                                         \
00095       }                                                                       \
00096   } while (0)
00097 #endif
00098 
00099 #ifndef timersub
00100 # define timersub(a, b, result)                                               \
00101   do {                                                                        \
00102     (result)->tv_sec = (a)->tv_sec - (b)->tv_sec;                             \
00103     (result)->tv_usec = (a)->tv_usec - (b)->tv_usec;                          \
00104     if ((result)->tv_usec < 0) {                                              \
00105       --(result)->tv_sec;                                                     \
00106       (result)->tv_usec += 1000000;                                           \
00107     }                                                                         \
00108   } while (0)
00109 #endif
00110 /* unalligned little endian access */     
00111 #define LE_READ_2(p)                                                    \
00112         ((u_int16_t)                                                    \
00113          ((((u_int8_t *)(p))[0]      ) | (((u_int8_t *)(p))[1] <<  8)))
00114 #define LE_READ_4(p)                                                    \
00115         ((u_int32_t)                                                    \
00116          ((((u_int8_t *)(p))[0]      ) | (((u_int8_t *)(p))[1] <<  8) | \
00117           (((u_int8_t *)(p))[2] << 16) | (((u_int8_t *)(p))[3] << 24)))
00118 
00119 static int      ath_init(struct net_device *);
00120 static int      ath_reset(struct net_device *);
00121 static void     ath_fatal_tasklet(TQUEUE_ARG);
00122 static void     ath_rxorn_tasklet(TQUEUE_ARG);
00123 static int      ath_stop(struct net_device *);
00124 static void     ath_initkeytable(struct net_device *);
00125 static void     ath_mode_init(struct net_device *);
00126 static int      ath_desc_alloc(struct ath_softc *);
00127 static void     ath_desc_free(struct ath_softc *);
00128 static int      ath_rxbuf_init(struct ath_softc *, struct ath_buf *);
00129 static void     ath_rx_tasklet(TQUEUE_ARG data);
00130 static int      ath_tx_setup(struct ath_softc *, int ac, int txq);
00131 static int      ath_hardstart(struct sk_buff *, struct net_device *);
00132 static int      ath_tx_start(struct net_device *, 
00133                              struct ath_buf *, struct sk_buff *);
00134 static void     ath_tx_tasklet(TQUEUE_ARG data);
00135 static void     ath_tx_timeout(struct net_device *);
00136 static void     ath_draintxq(struct ath_softc *);
00137 static void     ath_stoprecv(struct ath_softc *);
00138 static int      ath_startrecv(struct net_device *);
00139 static void     ath_calibrate(unsigned long);
00140 static struct net_device_stats *ath_getstats(struct net_device *);
00141 static int      ath_getchannels(struct net_device *, u_int cc,
00142                         HAL_BOOL outdoor, HAL_BOOL xchanmode);
00143 static void ath_update_led(struct ath_softc *, u_int16_t);
00144 
00145 static int      ath_set_mac_address(struct net_device *, void *);
00146 static int      ath_change_mtu(struct net_device *, int);
00147 static int      ath_ioctl(struct net_device *, struct ifreq *, int);
00148 
00149 static int      ath_setchannel(struct ath_softc *, struct ieee80211channel *channel);
00150 
00151 #ifdef CONFIG_SYSCTL
00152 static void     ath_dynamic_sysctl_register(struct ath_softc *);
00153 static void     ath_dynamic_sysctl_unregister(struct ath_softc *);
00154 #endif /* CONFIG_SYSCTL */
00155 static void ath_announce(struct net_device *);
00156 
00157 static int ath_rate_setup(struct net_device *dev, u_int mode);
00158 static  int     ath_dwelltime = 200;            /* 5 channels/second */
00159 static  int     ath_calinterval = 30;           /* calibrate every 30 secs */
00160 static  int     ath_countrycode = CTRY_DEFAULT; /* country code */
00161 static  int     ath_regdomain = 0;              /* regulatory domain */
00162 static  int     ath_outdoor = AH_TRUE;         /* enable outdoor use */
00163 static  int     ath_xchanmode = AH_TRUE;        /* enable extended channels */
00164 static  int     ath_phyerr = AH_FALSE;
00165 
00166 #ifdef AR_DEBUG
00167 int     ath_debug = 0;
00168 #define IFF_DUMPPKTS(_ic)       (ath_debug)
00169 static  void ath_printrxbuf(struct ath_buf *bf, int);
00170 static  void ath_printtxbuf(struct ath_buf *bf, int);
00171 enum {
00172   ATH_DEBUG_ANY = 0xffffffff
00173 };
00174 
00175 #else
00176 #define IFF_DUMPPKTS(_ic)       (0)
00177 #endif
00178 
00179 
00180 /*
00181  * Format an Ethernet MAC for printing.
00182  */
00183 const char*
00184 ether_sprintf(const u_int8_t *mac)
00185 {
00186         static char etherbuf[18];
00187         snprintf(etherbuf, sizeof(etherbuf), "%02x:%02x:%02x:%02x:%02x:%02x",
00188                 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
00189         return etherbuf;
00190 }
00191 
00192 
00193 /*
00194  * Convert channel to IEEE channel number.
00195  */
00196 u_int
00197 chan2ieee(struct ath_softc *sc, struct ieee80211channel *c)
00198 {
00199         if (sc->ic_channels <= c && c <= &sc->ic_channels[IEEE80211_CHAN_MAX])
00200                 return c - sc->ic_channels;
00201         else if (c == IEEE80211_CHAN_ANYC)
00202                 return IEEE80211_CHAN_ANY;
00203         else {
00204                 printk(KERN_ERR "wlan: invalid channel freq %u flags %x\n",
00205                         c->ic_freq, c->ic_flags);
00206                 return 0;               /* XXX */
00207         }
00208 }
00209 
00210 
00211 void dump_pkt(struct sk_buff *skb)
00212 {
00213   u_int8_t *buf = skb->data;
00214   int i = 0;
00215 
00216   if (!skb) {
00217     printk("NULL dump_pkt\n");
00218   }
00219   printk("len %d ", skb->len);
00220   
00221   if (skb->len > 0) {
00222     for (i = 0; i < skb->len; i++) {
00223       if ((i & 1) == 0)
00224         printk(" ");
00225       printk("%02x", buf[i]);
00226     }
00227     printk("\n");
00228   }
00229 
00230 }
00231 void
00232 ieee80211_dump_pkt(u_int8_t *buf, int len, int rate, int rssi)
00233 {
00234         struct ieee80211_frame *wh;
00235         int i;
00236 
00237         wh = (struct ieee80211_frame *)buf;
00238         switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
00239         case IEEE80211_FC1_DIR_NODS:
00240                 printk("NODS %s", ether_sprintf(wh->i_addr2));
00241                 printk("->%s", ether_sprintf(wh->i_addr1));
00242                 printk("(%s)", ether_sprintf(wh->i_addr3));
00243                 break;
00244         case IEEE80211_FC1_DIR_TODS:
00245                 printk("TODS %s", ether_sprintf(wh->i_addr2));
00246                 printk("->%s", ether_sprintf(wh->i_addr3));
00247                 printk("(%s)", ether_sprintf(wh->i_addr1));
00248                 break;
00249         case IEEE80211_FC1_DIR_FROMDS:
00250                 printk("FRDS %s", ether_sprintf(wh->i_addr3));
00251                 printk("->%s", ether_sprintf(wh->i_addr1));
00252                 printk("(%s)", ether_sprintf(wh->i_addr2));
00253                 break;
00254         case IEEE80211_FC1_DIR_DSTODS:
00255                 printk("DSDS %s", ether_sprintf((u_int8_t *)&wh[1]));
00256                 printk("->%s", ether_sprintf(wh->i_addr3));
00257                 printk("(%s", ether_sprintf(wh->i_addr2));
00258                 printk("->%s)", ether_sprintf(wh->i_addr1));
00259                 break;
00260         }
00261         switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
00262         case IEEE80211_FC0_TYPE_DATA:
00263                 printk(" data");
00264                 break;
00265         case IEEE80211_FC0_TYPE_MGT:
00266           printk(" mgt");
00267                 break;
00268         default:
00269                 printk(" type#%d", wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK);
00270                 break;
00271         }
00272         if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
00273                 int i;
00274                 printk(" WEP [IV");
00275                 for (i = 0; i < IEEE80211_WEP_IVLEN; i++)
00276                         printk(" %.02x", buf[sizeof(*wh)+i]);
00277                 printk(" KID %u]", buf[sizeof(*wh)+i] >> 6);
00278         }
00279         if (rate >= 0)
00280                 printk(" %dM", rate / 2);
00281         if (rssi >= 0)
00282                 printk(" +%d", rssi);
00283 
00284         printk(" len %d", len);
00285         printk("\n");
00286         
00287         if (0 && len > 0) {
00288                 for (i = 0; i < len; i++) {
00289                         if ((i & 1) == 0)
00290                                 printk(" ");
00291                         printk("%02x", buf[i]);
00292                 }
00293                 printk("\n");
00294         }
00295 }
00296 
00297 
00298 struct sk_buff *
00299 ieee80211_encap(struct net_device *dev, struct sk_buff *skb)
00300 {
00301   struct ath_softc *sc = dev->priv;
00302         struct ether_header eh;
00303         struct ieee80211_frame *wh;
00304         struct llc *llc;
00305         u_int8_t fc0;
00306         u_int8_t qospri = 0;
00307         u_int8_t isqos = 0;
00308         u_int8_t acc = 0;
00309         u_int16_t headersize = 0;
00310         u_int16_t  padbytes = 0;
00311 
00312         memcpy(&eh, skb->data, sizeof(struct ether_header));
00313         skb_pull(skb, sizeof(struct ether_header));
00314 
00315         qospri = 0; acc = WME_AC_BE;
00316 
00317         llc = (struct llc *) skb_push(skb, sizeof(struct llc));
00318         llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
00319         llc->llc_control = LLC_UI;
00320         llc->llc_snap.org_code[0] = 0;
00321         llc->llc_snap.org_code[1] = 0;
00322         llc->llc_snap.org_code[2] = 0;
00323         llc->llc_snap.ether_type = eh.ether_type;
00324 
00325         /* compute headersize and any padbytes */
00326         headersize += sizeof(struct ieee80211_frame) + isqos;
00327         if (sc->ic_flags & IEEE80211_F_DATAPAD) {
00328                 padbytes = roundup(headersize, 4) - headersize;
00329         }
00330 
00331         /*
00332          * XXX If we're loaded as a module the system may not be
00333          * configured to leave enough headroom for us to push the
00334          * 802.11 frame.  In that case fallback on reallocating
00335          * the frame with enough space.  Alternatively we can carry
00336          * the frame separately and use s/g support in the hardware.
00337          */
00338         if ((skb_headroom(skb) < (headersize+padbytes)) &&
00339             pskb_expand_head(skb, sizeof(*wh), 0, GFP_ATOMIC)) {
00340                 dev_kfree_skb_any(skb);
00341                 return NULL;
00342         }
00343         /* add padding if needed */
00344         if (padbytes) {
00345                 unsigned char *p;
00346 
00347                 p = skb_push(skb, padbytes);
00348         }
00349 
00350         fc0 = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA;
00351 
00352         /* add qos cntl field, setting only the priority field for now */
00353         if (isqos) {
00354                 u_int8_t *q;
00355 
00356                 q = (u_int8_t *) skb_push(skb, sizeof(struct ieee80211_qoscntl));
00357                 q[0] = qospri;
00358                 q[1] = 0;
00359                 skb->priority = acc;
00360                 fc0 |= IEEE80211_FC0_SUBTYPE_QOS;
00361         }
00362 
00363         wh = (struct ieee80211_frame *) skb_push(skb, sizeof(struct ieee80211_frame));
00364         wh->i_fc[0] = fc0;
00365         *(u_int16_t *)wh->i_dur = 0;
00366         *(u_int16_t *)wh->i_seq =
00367           cpu_to_le16(sc->txseq << IEEE80211_SEQ_SEQ_SHIFT);
00368         sc->txseq++;
00369         switch (sc->ic_opmode) {
00370         case IEEE80211_M_STA:
00371                 wh->i_fc[1] = IEEE80211_FC1_DIR_TODS;
00372                 IEEE80211_ADDR_COPY(wh->i_addr1, sc->bssid);
00373                 IEEE80211_ADDR_COPY(wh->i_addr2, eh.ether_shost);
00374                 IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_dhost);
00375                 break;
00376         case IEEE80211_M_IBSS:
00377         case IEEE80211_M_AHDEMO:
00378                 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
00379                 IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost);
00380                 IEEE80211_ADDR_COPY(wh->i_addr2, eh.ether_shost);
00381                 IEEE80211_ADDR_COPY(wh->i_addr3, sc->bssid);
00382                 break;
00383         case IEEE80211_M_HOSTAP:
00384                 wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS;
00385                 IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost);
00386                 IEEE80211_ADDR_COPY(wh->i_addr2, sc->bssid);
00387                 IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_shost);
00388                 break;
00389         case IEEE80211_M_MONITOR:
00390                 printk("%s: invalid mode\n", __func__);
00391                 break;
00392         }
00393         /* NB: PAE frames have their own encryption policy */
00394         if (sc->ic_flags & IEEE80211_F_WEPON && 
00395             eh.ether_type != __constant_htons(ETHERTYPE_PAE))
00396                 wh->i_fc[1] |= IEEE80211_FC1_WEP;
00397 
00398         return skb;
00399 }
00400 
00401 /*
00402  * Return the phy mode for with the specified channel so the
00403  * caller can select a rate set.  This is problematic and the
00404  * work here assumes how things work elsewhere in this code.
00405  */
00406 enum ieee80211_phymode
00407 chan2mode(struct ath_softc *sc, struct ieee80211channel *chan)
00408 {
00409         /*
00410          * In autoselect mode; deduce a mode based on the channel
00411          * characteristics.  We assume that turbo-only channels
00412          * are not considered when the channel set is constructed.
00413          */
00414         if (IEEE80211_IS_CHAN_5GHZ(chan))
00415                 return IEEE80211_MODE_11A;
00416         else if (chan->ic_flags & (IEEE80211_CHAN_OFDM|IEEE80211_CHAN_DYN))
00417                 return IEEE80211_MODE_11G;
00418         else
00419                 return IEEE80211_MODE_11B;
00420 }
00421 
00422 
00423 extern        struct iw_statistics *ath_iw_getstats(struct net_device *);
00424 extern  const struct iw_handler_def ath_iw_handler_def;
00425 
00426 #define DPRINTF(sc, _m, _fmt, ...) do {                         \
00427         if (sc->sc_debug & _m)                                  \
00428                 printk(_fmt, __VA_ARGS__);                      \
00429 } while (0)
00430 
00431 
00432 
00433 static  int countrycode = -1;
00434 MODULE_PARM(countrycode, "i");
00435 MODULE_PARM_DESC(countrycode, "Override default country code");
00436 static  int outdoor = -1;
00437 MODULE_PARM(outdoor, "i");
00438 MODULE_PARM_DESC(outdoor, "Enable/disable outdoor use");
00439 static  int xchanmode = -1;
00440 MODULE_PARM(xchanmode, "i");
00441 MODULE_PARM_DESC(xchanmode, "Enable/disable extended channel mode");
00442 
00443 static const char *acnames[] = {
00444         "WME_AC_BE",
00445         "WME_AC_BK",
00446         "WME_AC_VI",
00447         "WME_AC_VO",
00448         "WME_UPSD",
00449 };
00450 
00451 
00452 int
00453 ath_attach(u_int16_t devid, struct net_device *dev)
00454 {
00455         struct ath_softc *sc = dev->priv;
00456         struct ath_hal *ah;
00457         int error = 0;
00458         u_int8_t csz;
00459         HAL_STATUS status;
00460         int i;
00461         u_int32_t result;
00462         int channels_printed;
00463 
00464         DPRINTF(sc, ATH_DEBUG_ANY, "ath_attach: devid 0x%x\n", devid);
00465         /*
00466          * Cache line size is used to size and align various
00467          * structures used to communicate with the hardware.
00468          */
00469         bus_read_cachesize(sc, &csz);
00470         /* XXX assert csz is non-zero */
00471         sc->sc_cachelsz = csz << 2;             /* convert to bytes */
00472 
00473         ATH_LOCK_INIT(sc);
00474         ATH_TXBUF_LOCK_INIT(sc);
00475 
00476         ATH_INIT_TQUEUE(&sc->sc_rxtq,   ath_rx_tasklet,         dev);
00477         ATH_INIT_TQUEUE(&sc->sc_txtq,   ath_tx_tasklet,         dev);
00478 
00479         ATH_INIT_TQUEUE(&sc->sc_rxorntq,ath_rxorn_tasklet,      dev);
00480         ATH_INIT_TQUEUE(&sc->sc_fataltq,ath_fatal_tasklet,      dev);
00481 
00482         ah = _ath_hal_attach(devid, sc, 0, (void *) dev->mem_start, &status);
00483         if (ah == NULL) {
00484                 printk(KERN_ERR "%s: unable to attach hardware; HAL status %u\n",
00485                         dev->name, status);
00486                 error = ENXIO;
00487                 goto bad;
00488         }
00489         if (ah->ah_abi != HAL_ABI_VERSION) {
00490                 printk(KERN_ERR "%s: HAL ABI msmatch; "
00491                         "driver expects 0x%x, HAL reports 0x%x\n",
00492                         dev->name, HAL_ABI_VERSION, ah->ah_abi);
00493                 error = ENXIO;          /* XXX */
00494                 goto bad;
00495         }
00496         sc->sc_ah = ah;
00497 
00498 
00499         /*
00500          * Check if the MAC has multi-rate retry support.
00501          * We do this by trying to setup a fake extended
00502          * descriptor.  MAC's that don't have support will
00503          * return false w/o doing anything.  MAC's that do
00504          * support it will return true w/o doing anything.
00505          */
00506 
00507         if (AH_TRUE !=  ath_hal_setupxtxdesc(ah, NULL, 0,0, 0,0, 0,0)) {
00508           printk(KERN_WARNING "%s: no multi-rate retry support\n",
00509                  dev->name);
00510           goto bad;
00511         }
00512 
00513         /*
00514          * Reset the key cache since some parts do not
00515          * reset the contents on initial power up.
00516          */
00517         sc->sc_keymax = ath_hal_keycachesize(ah);
00518         for (i = 0; i < sc->sc_keymax; i++)
00519                 ath_hal_keyreset(ah, i);
00520         /*
00521          * Collect the channel list using the default country
00522          * code and including outdoor channels.  The 802.11 layer
00523          * is resposible for filtering this list based on settings
00524          * like the phy mode.
00525          */
00526         if (countrycode != -1)
00527                 ath_countrycode = countrycode;
00528         if (outdoor != -1)
00529                 ath_outdoor = outdoor;
00530         if (xchanmode != -1)
00531                 ath_xchanmode = xchanmode;
00532         error = ath_getchannels(dev, ath_countrycode,
00533                         ath_outdoor, ath_xchanmode);
00534         if (error != 0)
00535                 goto bad;
00536 
00537         /*
00538          * Setup rate tables for all potential media types.
00539          */
00540         ath_rate_setup(dev, IEEE80211_MODE_11A);
00541         ath_rate_setup(dev, IEEE80211_MODE_11B);
00542         ath_rate_setup(dev, IEEE80211_MODE_11G);
00543         ath_rate_setup(dev, IEEE80211_MODE_TURBO);
00544 
00545 
00546         /*
00547          * Copy these back; they are set as a side effect
00548          * of constructing the channel list.
00549          */
00550         ath_hal_getregdomain(ah, &ath_regdomain);
00551         ath_hal_getcountrycode(ah, &ath_countrycode);
00552 
00553         error = ath_desc_alloc(sc);
00554         if (error != 0) {
00555                 printk("%s: failed to allocate descriptors: %d\n",
00556                         dev->name, error);
00557                 goto bad;
00558         }
00559 
00560 
00561         /*
00562          * Allocate hardware transmit queues: one queue for
00563          * beacon frames and one data queue for each QoS
00564          * priority.  Note that the hal handles reseting
00565          * these queues at the needed time.
00566          *
00567          * XXX PS-Poll
00568          */
00569 
00570         /* NB: insure BK queue is h/w queue 0 */
00571         if (!ath_tx_setup(sc, WME_AC_BE, HAL_WME_AC_BK) ||
00572             !ath_tx_setup(sc, WME_AC_BK, HAL_WME_AC_BE) ||
00573             !ath_tx_setup(sc, WME_AC_VI, HAL_WME_AC_VI) ||
00574             !ath_tx_setup(sc, WME_AC_VO, HAL_WME_AC_VO)) {
00575                 error = EIO;
00576                 goto bad2;
00577         }
00578 
00579         init_timer(&sc->sc_cal_ch);
00580         sc->sc_cal_ch.function = ath_calibrate;
00581         sc->sc_cal_ch.data = (unsigned long) dev;
00582 
00583 
00584         sc->sc_ledstate = 1;
00585         /*
00586          * Auto-enable soft led processing for IBM cards and for
00587          * 5211 minipci cards.  Users can also manually enable/disable
00588          * support with a sysctl.
00589          */
00590         sc->sc_softled = (devid == AR5212_DEVID_IBM || devid == AR5211_DEVID);
00591         if (sc->sc_softled) {
00592                 ath_hal_gpioCfgOutput(ah, sc->sc_ledpin);
00593                 ath_hal_gpioset(ah, sc->sc_ledpin, 0);
00594         }
00595 
00596         dev->open = ath_init;
00597         dev->stop = ath_stop;
00598         dev->hard_start_xmit = ath_hardstart;
00599         dev->tx_timeout = ath_tx_timeout;
00600         dev->watchdog_timeo = 5 * HZ;                   /* XXX */
00601         dev->set_multicast_list = ath_mode_init;
00602         dev->do_ioctl = ath_ioctl;
00603         dev->get_stats = ath_getstats;
00604 
00605 #ifdef CONFIG_NET_WIRELESS
00606         dev->get_wireless_stats = ath_iw_getstats;
00607         dev->wireless_handlers = (struct iw_handler_def *) &ath_iw_handler_def;
00608 #endif
00609 
00610         sc->dev_type = ARPHRD_ETHER;
00611         ether_setup(dev);
00612         dev->set_mac_address = ath_set_mac_address;
00613         dev->change_mtu = &ath_change_mtu;
00614         dev->mtu = 2000;
00615         dev->tx_queue_len = ATH_TXBUF;          /* 1 for mgmt frame */
00616 
00617         if (register_netdev(&sc->dev)) {
00618           printk(KERN_WARNING "%s: unable to register device\n",
00619                  sc->dev.name);
00620           goto bad3;
00621         }
00622         
00623 
00624 
00625         /* XXX not right but it's not used anywhere important */
00626         sc->ic_phytype = IEEE80211_T_OFDM;
00627         sc->ic_opmode = IEEE80211_M_STA;
00628         sc->ic_caps = IEEE80211_C_WEP           /* wep supported */
00629                 | IEEE80211_C_IBSS              /* ibss, nee adhoc, mode */
00630                 | IEEE80211_C_HOSTAP            /* hostap mode */
00631                 | IEEE80211_C_MONITOR           /* monitor mode */
00632                 | IEEE80211_C_TXPMGT            /* transmit power control */
00633                 | IEEE80211_C_SHPREAMBLE;       /* short preamble supported */
00634         sc->ic_flags |= IEEE80211_F_DATAPAD;
00635         sc->ic_rts_threshold = IEEE80211_RTS_MAX;
00636 
00637 
00638         /*
00639          * Query the hal about antenna support.
00640          */
00641         if (ath_hal_hasdiversity(ah)) {
00642                 sc->sc_hasdiversity = 1;
00643                 sc->sc_diversity = ath_hal_getdiversity(ah);
00644         }
00645         sc->sc_defant = ath_hal_getdefantenna(ah);
00646         sc->sc_txantenna = 0;
00647         sc->sc_debug = ath_debug;
00648         sc->sc_rxotherant = 0;
00649 
00650         /* get mac address from hardware */
00651         ath_hal_getmac(ah, dev->dev_addr);
00652 
00653         if (1) {
00654           u_int modes = ath_hal_getwirelessmodes(ah, ath_countrycode);
00655           printk(KERN_WARNING "%s: modes: 0x%02x\n",
00656                  sc->dev.name,
00657                  modes);
00658         }
00659 
00660         result = 0;
00661         if (HAL_OK != ath_hal_getcapability(ah, HAL_CAP_TXPOW, 0, &result)) {
00662           printk(KERN_WARNING "%s: couldn't get capability\n",
00663                  sc->dev.name);
00664         } else {
00665           printk(KERN_WARNING "%s: TXPOW %d\n", 
00666                  sc->dev.name, result);
00667         }
00668         result = 0;
00669         if (HAL_OK != ath_hal_getcapability(ah, HAL_CAP_TPC, 0, &result)) {
00670           printk(KERN_WARNING "%s: couldn't get capability\n",
00671                  sc->dev.name);
00672         } else {
00673           printk(KERN_WARNING "%s: TXPC %d\n", 
00674                  sc->dev.name, result);
00675         }
00676         /* call MI attach routine. */
00677         //ieee80211_ifattach(dev);
00678         {
00679         /*
00680          * Fill in 802.11 available channel set, mark
00681          * all available channels as active, and pick
00682          * a default channel if not already specified.
00683          */
00684           memset(sc->ic_chan_avail, 0, sizeof(sc->ic_chan_avail));
00685           sc->ic_modecaps |= 1<<IEEE80211_MODE_AUTO;
00686           sc->current_channel = NULL;
00687           channels_printed = 0;
00688           for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
00689             struct ieee80211channel *c = &sc->ic_channels[i];
00690             if (c->ic_flags) {
00691               /*
00692                * Verify driver passed us valid data.
00693                */
00694               if (i != chan2ieee(sc, c)) {
00695                 printk(KERN_WARNING "%s: bad channel ignored; "
00696                        "freq %u flags %x number %u\n",
00697                        dev->name, c->ic_freq, c->ic_flags, i);
00698                 c->ic_flags = 0;        /* NB: remove */
00699                 continue;
00700               }
00701               if (sc->current_channel == NULL) {
00702                 sc->current_channel = c;
00703               }
00704               setbit(sc->ic_chan_avail, i);
00705 
00706               if (channels_printed % 3 == 0) {
00707                 if (channels_printed) {
00708                   printk("\n");
00709                 }
00710                 printk("%s: available channels:", dev->name);
00711               }
00712               channels_printed++;
00713 
00714               printk(" %d (%1d.%3dGHz/", i, 
00715                      c->ic_freq / 1000, 
00716                      c->ic_freq % 1000);
00717 
00718               /*
00719                * Identify mode capabilities.
00720                */
00721               if (IEEE80211_IS_CHAN_A(c)) {
00722                 sc->ic_modecaps |= 1<<IEEE80211_MODE_11A;
00723                 printk("a");
00724               }
00725               if (IEEE80211_IS_CHAN_B(c)) {
00726                 sc->ic_modecaps |= 1<<IEEE80211_MODE_11B;
00727                 printk("b");
00728               }
00729               if (IEEE80211_IS_CHAN_PUREG(c)) {
00730                 sc->ic_modecaps |= 1<<IEEE80211_MODE_11G;
00731                 printk("g");
00732               }
00733               if (IEEE80211_IS_CHAN_T(c)) {
00734                 sc->ic_modecaps |= 1<<IEEE80211_MODE_TURBO;
00735                 printk("t");
00736               }
00737 
00738               if (IEEE80211_IS_CHAN_X(c)) {
00739                 printk("x");
00740               }
00741               //printk(" 0x%x", c->ic_flags);
00742               printk(")");
00743             }
00744           }
00745           if (channels_printed) {
00746             printk("\n");
00747           }
00748         }
00749         if (!sc->current_channel) {
00750           printk("no channels?\n");
00751           return 0;
00752           //goto bad;
00753         }
00754 
00755         /*
00756          * Attach dynamic MIB vars and announce support
00757          * now that we have a device name with unit number.
00758          */
00759 #ifdef CONFIG_SYSCTL
00760         ath_dynamic_sysctl_register(sc);
00761 #endif /* CONFIG_SYSCTL */
00762         ath_announce(dev);
00763 
00764         printk("%s: 802.11 address: %s\n",
00765                 dev->name, ether_sprintf(dev->dev_addr));
00766 
00767         return ath_init(dev);
00768 
00769 bad3:
00770 bad2:
00771         if (sc->sc_txq[WME_AC_BK].axq_qnum != (u_int) -1)
00772                 ATH_TXQ_LOCK_DESTROY(&sc->sc_txq[WME_AC_BK]);
00773         if (sc->sc_txq[WME_AC_BE].axq_qnum != (u_int) -1)
00774                 ATH_TXQ_LOCK_DESTROY(&sc->sc_txq[WME_AC_BE]);
00775         if (sc->sc_txq[WME_AC_VI].axq_qnum != (u_int) -1)
00776                 ATH_TXQ_LOCK_DESTROY(&sc->sc_txq[WME_AC_VI]);
00777         if (sc->sc_txq[WME_AC_VO].axq_qnum != (u_int) -1)
00778                 ATH_TXQ_LOCK_DESTROY(&sc->sc_txq[WME_AC_VO]);
00779         ath_desc_free(sc);
00780 bad:
00781         if (ah)
00782                 ath_hal_detach(ah);
00783         ATH_TXBUF_LOCK_DESTROY(sc);
00784         ATH_LOCK_DESTROY(sc);
00785         sc->sc_invalid = 1;
00786         return error;
00787 }
00788 
00789 int
00790 ath_detach(struct net_device *dev)
00791 {
00792         struct ath_softc *sc = dev->priv;
00793         int i = 0;
00794 
00795         DPRINTF(sc, ATH_DEBUG_ANY, "ath_detach flags %x\n", dev->flags);
00796 
00797         ath_stop(dev);
00798         sc->sc_invalid = 1;
00799         ath_desc_free(sc);
00800         ath_hal_detach(sc->sc_ah);
00801 
00802         ATH_TXBUF_LOCK_DESTROY(sc);
00803         for (i = 0; i < HAL_NUM_TX_QUEUES; i++)
00804                 if (ATH_TXQ_SETUP(sc, i))
00805                         ATH_TXQ_LOCK_DESTROY(&sc->sc_txq[i]);
00806 
00807 #ifdef CONFIG_SYSCTL
00808         ath_dynamic_sysctl_unregister(sc);
00809 #endif /* CONFIG_SYSCTL */
00810         ATH_LOCK_DESTROY(sc);
00811         unregister_netdev(&sc->dev);
00812         //ieee80211_ifdetach(dev);
00813 
00814         return 0;
00815 }
00816 
00817 void
00818 ath_suspend(struct net_device *dev)
00819 {
00820   struct ath_softc *sc = dev->priv;
00821   DPRINTF(sc, ATH_DEBUG_ANY, "ath_suspend flags %x\n", dev->flags);
00822   ath_stop(dev);
00823 }
00824 
00825 void
00826 ath_resume(struct net_device *dev)
00827 {
00828   struct ath_softc *sc = dev->priv;
00829   DPRINTF(sc, ATH_DEBUG_ANY, "ath_resume %x\n", dev->flags);
00830   ath_init(dev);
00831 }
00832 
00833 void
00834 ath_shutdown(struct net_device *dev)
00835 {
00836   struct ath_softc *sc = dev->priv;
00837   DPRINTF(sc, ATH_DEBUG_ANY, "ath_shutdown %x\n", dev->flags);
00838   ath_stop(dev);
00839 }
00840 
00841 /*
00842  * Interrupt handler.  Most of the actual processing is
00843  * deferred to tasklets.
00844  */
00845 irqreturn_t
00846 ath_intr(int irq, void *dev_id, struct pt_regs *regs)
00847 {
00848         struct net_device *dev = dev_id;
00849         struct ath_softc *sc = dev->priv;
00850         struct ath_hal *ah = sc->sc_ah;
00851         HAL_INT status;
00852         int needmark;
00853 
00854         if (sc->sc_invalid) {
00855                 /*
00856                  * The hardware is not ready/present, don't touch anything.
00857                  * Note this can happen early on if the IRQ is shared.
00858                  */
00859                 return IRQ_NONE;
00860         }
00861         if (!ath_hal_intrpend(ah)) {            /* shared irq, not for us */
00862                 return IRQ_NONE;
00863         }
00864         if ((dev->flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) {
00865           printk("%s: %s: flags 0x%x\n", dev->name, __func__, dev->flags);
00866           ath_hal_getisr(ah, &status);  /* clear ISR */
00867           ath_hal_intrset(ah, 0);               /* disable further intr's */
00868           return IRQ_HANDLED;
00869         }
00870         needmark = 0;
00871         ath_hal_getisr(ah, &status);
00872         DPRINTF(sc, ATH_DEBUG_ANY, "%s: interrupt, status 0x%x\n", dev->name, status);
00873 #ifdef AR_DEBUG
00874         if (ath_debug &&
00875             (status & (HAL_INT_FATAL|HAL_INT_RXORN|HAL_INT_BMISS))) {
00876                 printk("%s: ath_intr: status 0x%x\n", dev->name, status);
00877                 //ath_hal_dumpstate(ah);
00878         }
00879 #endif /* AR_DEBUG */
00880         status &= sc->sc_imask;                 /* discard unasked for bits */
00881         if (status & HAL_INT_FATAL) {
00882           printk("%s: %s: FATAL\n", dev->name, __func__);
00883                 sc->sc_stats.ast_hardware++;
00884                 ath_hal_intrset(ah, 0);         /* disable intr's until reset */
00885                 ATH_SCHEDULE_TQUEUE(&sc->sc_fataltq, &needmark);
00886         } else if (status & HAL_INT_RXORN) {
00887           printk("%s: %s: RXORN\n", dev->name, __func__);
00888                 sc->sc_stats.ast_rxorn++;
00889                 ath_hal_intrset(ah, 0);         /* disable intr's until reset */
00890                 ATH_SCHEDULE_TQUEUE(&sc->sc_rxorntq, &needmark);
00891         } else {
00892                 if (status & HAL_INT_RXEOL) {
00893                   DPRINTF(sc, ATH_DEBUG_ANY, "%s: ath_intr: RXEOL\n", dev->name);
00894                         /*
00895                          * NB: the hardware should re-read the link when
00896                          *     RXE bit is written, but it doesn't work at
00897                          *     least on older hardware revs.
00898                          */
00899                         sc->sc_stats.ast_rxeol++;
00900                         sc->sc_rxlink = NULL;
00901                 }
00902                 if (status & HAL_INT_TXURN) {
00903                   DPRINTF(sc, ATH_DEBUG_ANY, "%s: ath_intr: TXURN\n", dev->name);
00904                         sc->sc_stats.ast_txurn++;
00905                         /* bump tx trigger level */
00906                         ath_hal_updatetxtriglevel(ah, AH_TRUE);
00907                 }
00908                 if (status & HAL_INT_RX) {
00909                   DPRINTF(sc, ATH_DEBUG_ANY, "%s: ath_intr: RX\n", dev->name);
00910                   ATH_SCHEDULE_TQUEUE(&sc->sc_rxtq, &needmark);
00911                 }
00912                 if (status & HAL_INT_TX) {
00913                   DPRINTF(sc, ATH_DEBUG_ANY, "%s: ath_intr: TX\n", dev->name);
00914                   ATH_SCHEDULE_TQUEUE(&sc->sc_txtq, &needmark);
00915 
00916                 }
00917                 if (status & HAL_INT_SWBA) {
00918                   DPRINTF(sc, ATH_DEBUG_ANY, "%s: ath_intr: SWBA?\n", dev->name);
00919                         /*
00920                          * Handle beacon transmission directly; deferring
00921                          * this is too slow to meet timing constraints
00922                          * under load.
00923                          */
00924                   //ath_beacon_tasklet(dev);
00925                 }
00926                 if (status & HAL_INT_BMISS) {
00927                   DPRINTF(sc, ATH_DEBUG_ANY, "%s: ath_intr: BMISS?\n", dev->name);
00928                         sc->sc_stats.ast_bmiss++;
00929                         //needmark |= queue_task(&sc->sc_bmisstq, &tq_immediate);
00930                 }
00931         }
00932         if (needmark)
00933                 mark_bh(IMMEDIATE_BH);
00934         return IRQ_HANDLED;
00935 }
00936 
00937 static void
00938 ath_fatal_tasklet(TQUEUE_ARG data)
00939 {
00940         struct net_device *dev = (struct net_device *) data;
00941 
00942         printk("%s: hardware error; resetting\n", dev->name);
00943         ath_reset(dev);
00944 }
00945 
00946 static void
00947 ath_rxorn_tasklet(TQUEUE_ARG data)
00948 {
00949         struct net_device *dev = (struct net_device *) data;
00950 
00951         printk("%s: rx FIFO overrun; resetting\n", dev->name);
00952         ath_reset(dev);
00953 }
00954 
00955 
00956 static u_int
00957 ath_chan2flags(struct ath_softc *sc, struct ieee80211channel *chan)
00958 {
00959         static const u_int modeflags[] = {
00960                 0,                      /* IEEE80211_MODE_AUTO */
00961                 CHANNEL_A,              /* IEEE80211_MODE_11A */
00962                 CHANNEL_B,              /* IEEE80211_MODE_11B */
00963                 CHANNEL_PUREG,          /* IEEE80211_MODE_11G */
00964                 CHANNEL_T               /* IEEE80211_MODE_TURBO */
00965         };
00966         return modeflags[chan2mode(sc, chan)];
00967 }
00968 
00969 static int
00970 ath_init(struct net_device *dev)
00971 {
00972         struct ath_softc *sc = dev->priv;
00973         struct ath_hal *ah = sc->sc_ah;
00974         HAL_STATUS status;
00975         HAL_CHANNEL hchan;
00976 
00977         DPRINTF(sc, ATH_DEBUG_ANY, "ath_init: mode=%d\n",sc->ic_opmode);
00978         /*
00979          * Stop anything previously setup.  This is safe
00980          * whether this is the first time through or not.
00981          */
00982         ath_stop(dev);
00983         
00984         /*
00985          * Resize receive skb's if changing to or from monitor mode
00986          */
00987         if (sc->ic_opmode == IEEE80211_M_MONITOR) {
00988                 struct ath_buf *bf;
00989                 STAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list)
00990                         if (bf->bf_skb != NULL) {
00991                                 bus_unmap_single(sc->sc_bdev,
00992                                                  bf->bf_skbaddr, sc->sc_rxbufsize,
00993                                                  BUS_DMA_FROMDEVICE);
00994                                 dev_kfree_skb_any(bf->bf_skb);
00995                                 bf->bf_skb = NULL;
00996                         }
00997         }
00998 
00999         /*
01000          * Change our interface type if we are in monitor mode.
01001          */
01002         dev->addr_len = ETH_ALEN;
01003         dev->type = sc->dev_type;
01004 
01005 
01006         if (sc->current_channel == NULL) {
01007           printk("%s: current_channel == NULL\n", dev->name);
01008           return EIO;
01009         }
01010         
01011         /*
01012          * The basic interface to setting the hardware in a good
01013          * state is ``reset''.  On return the hardware is known to
01014          * be powered up and with interrupts disabled.  This must
01015          * be followed by initialization of the appropriate bits
01016          * and then setup of the interrupt mask.
01017          */
01018         if (ath_setchannel(sc, sc->current_channel) != 0) {
01019           return EIO;
01020         }
01021 
01022         hchan.channel = sc->current_channel->ic_freq;
01023         hchan.channelFlags = ath_chan2flags(sc, sc->current_channel);
01024 
01025 
01026         if (!ath_hal_reset(ah, sc->ic_opmode, &hchan, AH_FALSE, &status)) {
01027           printk("%s: unable to reset hardware; hal status %u\n",
01028                  dev->name, status);
01029           return EIO;
01030         }
01031         
01032 
01033         /*
01034          * Setup the hardware after reset: the key cache
01035          * is filled as needed and the receive engine is
01036          * set going.  Frame transmit is handled entirely
01037          * in the frame output path; there's nothing to do
01038          * here except setup the interrupt mask.
01039          */
01040         ath_initkeytable(dev);
01041         if (ath_startrecv(dev) != 0) {
01042                 printk("%s: unable to start recv logic\n", dev->name);
01043                 return EIO;
01044         }
01045 
01046 
01047         if (chan2mode(sc, sc->current_channel) != sc->ic_curmode) {
01048           printk (KERN_EMERG "%s: mode incorrect!\n",
01049                   __func__);
01050           return -EIO;
01051         }
01052         
01053 
01054         dev->flags |= IFF_RUNNING;
01055 
01056         /*
01057          * Enable interrupts.
01058          */
01059         sc->sc_imask = HAL_INT_RX | HAL_INT_TX
01060                   | HAL_INT_RXEOL | HAL_INT_RXORN
01061                   | HAL_INT_FATAL | HAL_INT_GLOBAL;
01062         ath_hal_intrset(ah, sc->sc_imask);
01063 
01064         netif_start_queue(dev);
01065         //ath_hal_setassocid(ah, sc->bssid, 0);
01066         return 0;
01067 }
01068 
01069 static int
01070 ath_stop_locked(struct net_device *dev)
01071 {
01072         struct ath_softc *sc = dev->priv;
01073         struct ath_hal *ah = sc->sc_ah;
01074 
01075         DPRINTF(sc, ATH_DEBUG_ANY, "%s: invalid %u flags 0x%x\n",
01076                 __func__, sc->sc_invalid, dev->flags);
01077 
01078         if (dev->flags & IFF_RUNNING) {
01079                 /*
01080                  * Shutdown the hardware and driver:
01081                  *    reset 802.11 state machine (do first so
01082                  *      station deassoc/deauth frames can be sent)
01083                  *    stop output from above
01084                  *    disable interrupts
01085                  *    turn off timers
01086                  *    turn off the radio
01087                  *    clear transmit machinery
01088                  *    clear receive machinery
01089                  *    reclaim beacon resources
01090                  *    power down hardware
01091                  *
01092                  * Note that some of this work is not possible if the
01093                  * hardware is gone (invalid).
01094                  */
01095                 netif_stop_queue(dev);
01096                 dev->flags &= ~IFF_RUNNING;
01097                 if (!sc->sc_invalid) {
01098                         if (sc->sc_softled)
01099                                 ath_hal_gpioset(ah, sc->sc_ledpin, 1);
01100                         ath_hal_intrset(ah, 0);
01101                 }
01102                 ath_draintxq(sc);
01103                 if (!sc->sc_invalid) {
01104                         ath_stoprecv(sc);
01105                         ath_hal_phydisable(ah);
01106                 } else
01107                         sc->sc_rxlink = NULL;
01108         }
01109         return 0;
01110 }
01111 
01112 static int
01113 ath_stop(struct net_device *dev)
01114 {
01115         struct ath_softc *sc = dev->priv;
01116         int error;
01117 
01118         ATH_LOCK(sc);
01119         error = ath_stop_locked(dev);
01120         if (error == 0 && !sc->sc_invalid) {
01121                 /*
01122                  * Set the chip in full sleep mode.  Note that we are
01123                  * careful to do this only when bringing the interface
01124                  * completely to a stop.  When the chip is in this state
01125                  * it must be carefully woken up or references to
01126                  * registers in the PCI clock domain may freeze the bus
01127                  * (and system).  This varies by chip and is mostly an
01128                  * issue with newer parts that go to sleep more quickly.
01129                  */
01130                 ath_hal_setpower(sc->sc_ah, HAL_PM_FULL_SLEEP, 0);
01131         }
01132         ATH_UNLOCK(sc);
01133         return error;
01134 }
01135 
01136 /*
01137  * Reset the hardware w/o losing operational state.  This is
01138  * basically a more efficient way of doing ath_stop, ath_init,
01139  * followed by state transitions to the current 802.11
01140  * operational state.  Used to recover from errors rx overrun
01141  * and to reset the hardware when rf gain settings must be reset.
01142  */
01143 static int
01144 ath_reset(struct net_device *dev)
01145 {
01146         struct ath_softc *sc = dev->priv;
01147         struct ath_hal *ah = sc->sc_ah;
01148         struct ieee80211channel *c;
01149         HAL_STATUS status;
01150         HAL_CHANNEL hchan;
01151 
01152         /*
01153          * Convert to a HAL channel description with the flags
01154          * constrained to reflect the current operating mode.
01155          */
01156         c = sc->current_channel;
01157         hchan.channel = c->ic_freq;
01158         hchan.channelFlags = ath_chan2flags(sc, c);
01159 
01160         ath_hal_intrset(ah, 0);         /* disable interrupts */
01161         ath_draintxq(sc);               /* stop xmit side */
01162         ath_stoprecv(sc);               /* stop recv side */
01163         /* NB: indicate channel change so we do a full reset */
01164         if (!ath_hal_reset(ah, sc->ic_opmode, &hchan, AH_TRUE, &status))
01165                 printk("%s: %s: unable to reset hardware; hal status %u\n",
01166                         dev->name, __func__, status);
01167         if (ath_startrecv(dev) != 0)    /* restart recv */
01168                 printk("%s: %s: unable to start recv logic\n",
01169                         dev->name, __func__);
01170 
01171         ath_hal_intrset(ah, sc->sc_imask);
01172 
01173         
01174         netif_wake_queue(dev);  /* restart xmit */
01175         return 0;
01176 }
01177 
01178 /*
01179  * XXX System may not be
01180  * configured to leave enough headroom for us to push the
01181  * 802.11 frame.  In that case fallback on reallocating
01182  * the frame with enough space.  Alternatively we can carry
01183  * the frame separately and use s/g support in the hardware.
01184  */
01185 static int
01186 ath_skbhdr_adjust(struct sk_buff *skb, struct net_device *dev)
01187 {
01188         struct ath_softc *sc = (void*)dev->priv;
01189         int len = sizeof(struct ieee80211_qosframe) + sizeof(struct llc) +
01190                 IEEE80211_ADDR_LEN - sizeof(struct ether_header);
01191 
01192         if (sc->ic_flags & IEEE80211_F_WEPON)
01193                 len += IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN;
01194         if ((skb_headroom(skb) < len) &&
01195             pskb_expand_head(skb, len - skb_headroom(skb), 0, GFP_ATOMIC)) {
01196                 dev_kfree_skb_any(skb);
01197                 return -ENOMEM;
01198         }
01199         return 0;
01200 }
01201 
01202 /*
01203  * Transmit a data packet.  On failure caller is
01204  * assumed to reclaim the resources.
01205  */
01206 static int
01207 ath_hardstart(struct sk_buff *skb, struct net_device *dev)
01208 {
01209         struct ath_softc *sc = dev->priv;
01210         struct ath_buf *bf = NULL;
01211         int error;
01212 
01213 
01214         DPRINTF(sc, ATH_DEBUG_ANY, "%s: hardstart\n", dev->name);
01215 
01216         if ((dev->flags & IFF_RUNNING) == 0 || sc->sc_invalid) {
01217                 DPRINTF(sc, ATH_DEBUG_ANY, "%s: discard, invalid %d flags %x\n", __func__,
01218                         sc->sc_invalid, dev->flags);
01219                 sc->sc_stats.ast_tx_invalid++;
01220                 return -ENETDOWN;
01221         }
01222         
01223         error = ath_skbhdr_adjust(skb, dev);
01224         if (error != 0)
01225                 return error;
01226 
01227 
01228         /*
01229          * We don't need to encapsulate the packets here,
01230          * they should be ieee_80211_frames.
01231          */
01232 
01233 
01234         if (skb->len > sizeof(wlan_ng_prism2_header)) {
01235           pull_prism2_header(skb);
01236         }
01237 
01238 
01239         if (skb->len > sizeof(struct click_wifi_extra)) {
01240           pull_wifi_extra_header(skb);
01241         }
01242 
01243 
01244 
01245         /*
01246          * Grab a TX buffer and associated resources.
01247          */
01248         ATH_TXBUF_LOCK_BH(sc);
01249         bf = STAILQ_FIRST(&sc->sc_txbuf);
01250         if (bf != NULL)
01251           STAILQ_REMOVE_HEAD(&sc->sc_txbuf, bf_list);
01252         /* XXX use a counter and leave at least one for mgmt frames */
01253         if (STAILQ_EMPTY(&sc->sc_txbuf)) {
01254                 DPRINTF(sc, ATH_DEBUG_ANY, "%s: stop queue\n", __func__);
01255                 sc->sc_stats.ast_tx_qstop++;
01256                 netif_stop_queue(dev);
01257         }
01258         ATH_TXBUF_UNLOCK_BH(sc);
01259         if (bf == NULL) {               /* NB: should not happen */
01260                 printk("%s: discard, no xmit buf\n", __func__);
01261                 sc->sc_stats.ast_tx_nobuf++;
01262                 goto bad;
01263         }
01264 
01265 
01266         /*
01267          * Locate node state.  When operating
01268          * in station mode we always use ic_bss.
01269          */
01270 
01271         error = ath_tx_start(dev, bf, skb);
01272 
01273 
01274         //print_intr(sc);
01275 
01276 
01277         if (error == 0)
01278                 return 0;
01279         /* fall thru... */
01280 bad:
01281         printk("%s: %s got to bad\n", dev->name, __func__);
01282         if (bf != NULL) {
01283                 ATH_TXBUF_LOCK_BH(sc);
01284                 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
01285                 ATH_TXBUF_UNLOCK_BH(sc);
01286         }
01287         if (skb)
01288                 dev_kfree_skb_any(skb);
01289         return 0;       /* NB: return !0 only in a ``hard error condition'' */
01290 }
01291 
01292 /*
01293  * Calculate the receive filter according to the
01294  * operating mode and state:
01295  *
01296  * o always accept unicast, broadcast, and multicast traffic
01297  * o maintain current state of phy error reception
01298  * o probe request frames are accepted only when operating in
01299  *   hostap, adhoc, or monitor modes
01300  * o enable promiscuous mode according to the interface state
01301  * o accept beacons:
01302  *   - when operating in adhoc mode so the 802.11 layer creates
01303  *     node table entries for peers,
01304  *   - when operating in station mode for collecting rssi data when
01305  *     the station is otherwise quiet, or
01306  *   - when scanning
01307  */
01308 static u_int32_t
01309 ath_calcrxfilter(struct net_device *dev)
01310 {
01311         u_int32_t rfilt;
01312 
01313         rfilt = HAL_RX_FILTER_UCAST | HAL_RX_FILTER_BCAST | HAL_RX_FILTER_MCAST;
01314 
01315         rfilt |= HAL_RX_FILTER_PROBEREQ;
01316 
01317         if (dev->flags & IFF_PROMISC) {
01318         rfilt |= HAL_RX_FILTER_PROM;
01319         rfilt |= HAL_RX_FILTER_CONTROL;
01320         }
01321 
01322         if (ath_phyerr) {
01323           rfilt |= HAL_RX_FILTER_PHYERR;
01324         }
01325 
01326 
01327         rfilt |= HAL_RX_FILTER_BEACON;
01328         return rfilt;
01329 }
01330 
01331 static void
01332 ath_mode_init(struct net_device *dev)
01333 {
01334         struct ath_softc *sc = dev->priv;
01335         struct ath_hal *ah = sc->sc_ah;
01336         u_int32_t rfilt, mfilt[2], val;
01337         u_int8_t pos;
01338         struct dev_mc_list *mc;
01339 
01340         /* configure rx filter */
01341         rfilt = ath_calcrxfilter(dev);
01342         ath_hal_setrxfilter(ah, rfilt);
01343 
01344         /* configure operational mode */
01345         ath_hal_setopmode(ah);
01346 
01347         /* calculate and install multicast filter */
01348         if ((dev->flags & IFF_ALLMULTI) == 0) {
01349                 mfilt[0] = mfilt[1] = 0;
01350                 for (mc = dev->mc_list; mc; mc = mc->next) {
01351                         /* calculate XOR of eight 6bit values */
01352                         val = LE_READ_4(mc->dmi_addr + 0);
01353                         pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
01354                         val = LE_READ_4(mc->dmi_addr + 3);
01355                         pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
01356                         pos &= 0x3f;
01357                         mfilt[pos / 32] |= (1 << (pos % 32));
01358                 }
01359         } else {
01360                 mfilt[0] = mfilt[1] = ~0;
01361         }
01362         ath_hal_setmcastfilter(ah, mfilt[0], mfilt[1]);
01363         DPRINTF(sc, ATH_DEBUG_ANY, "ath_mode_init: RX filter 0x%x, MC filter %08x:%08x\n",
01364                 rfilt, mfilt[0], mfilt[1]);
01365 }
01366 
01367 static struct sk_buff *
01368 ath_alloc_skb(u_int size, u_int align)
01369 {
01370         struct sk_buff *skb;
01371         u_int off;
01372 
01373         skb = dev_alloc_skb(size + align-1);
01374         if (skb != NULL) {
01375                 off = ((unsigned long) skb->data) % align;
01376                 if (off != 0)
01377                         skb_reserve(skb, align - off);
01378         }
01379         return skb;
01380 }
01381 
01382 static int
01383 ath_desc_alloc(struct ath_softc *sc)
01384 {
01385 #define DS2PHYS(_sc, _ds) \
01386         ((_sc)->sc_desc_daddr + ((caddr_t)(_ds) - (caddr_t)(_sc)->sc_desc))
01387         int i, bsize;
01388         struct ath_desc *ds;
01389         struct ath_buf *bf;
01390 
01391         /* allocate descriptors */
01392         sc->sc_desc_len = sizeof(struct ath_desc) *
01393                 (ATH_TXBUF * ATH_TXDESC + ATH_RXBUF + 1);
01394         sc->sc_desc = bus_alloc_consistent(sc->sc_bdev,
01395                                            sc->sc_desc_len, &sc->sc_desc_daddr);
01396         if (sc->sc_desc == NULL)
01397                 return ENOMEM;
01398         ds = sc->sc_desc;
01399         DPRINTF(sc, ATH_DEBUG_ANY, "ath_desc_alloc: DMA map: %p (%d) -> %p\n",
01400             ds, sc->sc_desc_len, (caddr_t) sc->sc_desc_daddr);
01401 
01402         /* allocate buffers */
01403         bsize = sizeof(struct ath_buf) * (ATH_TXBUF + ATH_RXBUF + 1);
01404         bf = kmalloc(bsize, GFP_KERNEL);
01405         if (bf == NULL)
01406                 goto bad;
01407         memset(bf, 0, bsize);
01408         sc->sc_bufptr = bf;
01409 
01410         STAILQ_INIT(&sc->sc_rxbuf);
01411         for (i = 0; i < ATH_RXBUF; i++, bf++, ds++) {
01412                 bf->bf_desc = ds;
01413                 bf->bf_daddr = sc->sc_desc_daddr +
01414                     ((caddr_t)ds - (caddr_t)sc->sc_desc);
01415                 STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
01416         }
01417 
01418         STAILQ_INIT(&sc->sc_txbuf);
01419         for (i = 0; i < ATH_TXBUF; i++, bf++, ds += ATH_TXDESC) {
01420                 bf->bf_desc = ds;
01421                 bf->bf_daddr = sc->sc_desc_daddr +
01422                     ((caddr_t)ds - (caddr_t)sc->sc_desc);
01423                 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
01424         }
01425         /* beacon buffer */
01426         //bf->bf_desc = ds;
01427         //bf->bf_daddr = sc->sc_desc_daddr + ((caddr_t)ds - (caddr_t)sc->sc_desc);
01428         //sc->sc_bcbuf = bf;
01429         sc->sc_bcbuf = NULL;
01430         return 0;
01431 bad:
01432         bus_free_consistent(sc->sc_bdev, sc->sc_desc_len,
01433                             sc->sc_desc, sc->sc_desc_daddr);
01434         sc->sc_desc = NULL;
01435         return ENOMEM;
01436 }
01437 
01438 static void
01439 ath_desc_free(struct ath_softc *sc)
01440 {
01441         struct ath_buf *bf;
01442 
01443         /*
01444          * NB: TX queues have already been freed in ath_draintxq(),
01445          * which must be called before calling this function.
01446          */
01447 
01448         /* Free all pre-allocated RX skb */
01449         STAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list)
01450                 if (bf->bf_skb != NULL) {
01451                         bus_unmap_single(sc->sc_bdev,
01452                                          bf->bf_skbaddr, sc->sc_rxbufsize,
01453                                          BUS_DMA_FROMDEVICE);
01454                         dev_kfree_skb_any(bf->bf_skb);
01455                         bf->bf_skb = NULL;
01456                 }
01457 
01458         /* If beacon skb has not been freed yet, do it now */
01459         if (sc->sc_bcbuf != NULL) {
01460                 bf = sc->sc_bcbuf;
01461                 if (bf->bf_skb != NULL) {
01462                         bus_unmap_single(sc->sc_bdev, bf->bf_skbaddr,
01463                                          bf->bf_skb->len, BUS_DMA_TODEVICE);
01464                 }
01465                 sc->sc_bcbuf = NULL;
01466         }
01467 
01468         /* Free memory associated with all descriptors */
01469         bus_free_consistent(sc->sc_bdev, sc->sc_desc_len,
01470                             sc->sc_desc, sc->sc_desc_daddr);
01471 
01472         STAILQ_INIT(&sc->sc_rxbuf);
01473         STAILQ_INIT(&sc->sc_txbuf);
01474         kfree(sc->sc_bufptr);
01475         sc->sc_bufptr = NULL;
01476 }
01477 
01478 static int
01479 ath_rxbuf_init(struct ath_softc *sc, struct ath_buf *bf)
01480 {
01481         struct ath_hal *ah = sc->sc_ah;
01482         struct sk_buff *skb;
01483         struct ath_desc *ds;
01484 
01485         skb = bf->bf_skb;
01486         if (skb == NULL) {
01487           
01488           /*
01489            * Cache-line-align.  This is important (for the
01490            * 5210 at least) as not doing so causes bogus data
01491            * in rx'd frames.
01492            */
01493           skb = ath_alloc_skb(sc->sc_rxbufsize, sc->sc_cachelsz);
01494           if (skb == NULL) {
01495             DPRINTF(sc, ATH_DEBUG_ANY, "%s: skbuff alloc of size %u failed\n",
01496                      __func__, sc->sc_rxbufsize);
01497             sc->sc_stats.ast_rx_nobuf++;
01498             return ENOMEM;
01499           }
01500 
01501           skb_reserve(skb, sizeof(wlan_ng_prism2_header));
01502 
01503           skb->dev = &sc->dev;
01504           bf->bf_skb = skb;
01505           bf->bf_skbaddr = bus_map_single(sc->sc_bdev,
01506                                           skb->data, sc->sc_rxbufsize, BUS_DMA_FROMDEVICE);
01507         }
01508 
01509         /*
01510          * Setup descriptors.  For receive we always terminate
01511          * the descriptor list with a self-linked entry so we'll
01512          * not get overrun under high load (as can happen with a
01513          * 5212 when ANI processing enables PHY errors).
01514          *
01515          * To insure the last descriptor is self-linked we create
01516          * each descriptor as self-linked and add it to the end.  As
01517          * each additional descriptor is added the previous self-linked
01518          * entry is ``fixed'' naturally.  This should be safe even
01519          * if DMA is happening.  When processing RX interrupts we
01520          * never remove/process the last, self-linked, entry on the
01521          * descriptor list.  This insures the hardware always has
01522          * someplace to write a new frame.
01523          */
01524         ds = bf->bf_desc;
01525         ds->ds_link = bf->bf_daddr;             /* link to self */
01526         ds->ds_data = bf->bf_skbaddr;
01527         ath_hal_setuprxdesc(ah, ds
01528                 , skb_tailroom(skb)             /* buffer size */
01529                 , 0
01530         );
01531 
01532         if (sc->sc_rxlink != NULL)
01533                 *sc->sc_rxlink = bf->bf_daddr;
01534         sc->sc_rxlink = &ds->ds_link;
01535         return 0;
01536 }
01537 
01538 
01539 static void
01540 ath_update_led (struct ath_softc *sc, u_int16_t ledstate)
01541 {
01542         struct ath_hal *ah = sc->sc_ah;
01543         /*
01544          * When not associated, flash LED on for 5s, off for 200ms.
01545          * XXX this assumes 100ms beacon interval.
01546          */
01547         ath_hal_gpioCfgOutput(ah, sc->sc_ledpin);
01548         ath_hal_gpioset(ah, sc->sc_ledpin, ledstate);
01549         sc->sc_ledstate = ledstate;
01550 
01551 }
01552 
01553 struct sk_buff *
01554 ieee80211_decap(struct net_device *dev, struct sk_buff *skb)
01555 {
01556         struct ether_header *eh;
01557         struct ieee80211_frame wh;
01558         struct llc *llc;
01559         u_short ether_type = 0;
01560 
01561         memcpy(&wh, skb->data, sizeof(struct ieee80211_frame));
01562         llc = (struct llc *) skb_pull(skb, sizeof(struct ieee80211_frame));
01563         if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP &&
01564             llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 &&
01565             llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0) {
01566                 ether_type = llc->llc_un.type_snap.ether_type;
01567                 skb_pull(skb, sizeof(struct llc));
01568                 llc = NULL;
01569         }
01570         eh = (struct ether_header *) skb_push(skb, sizeof(struct ether_header));
01571         if (!eh) {
01572           return skb;
01573         }
01574         switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) {
01575         case IEEE80211_FC1_DIR_NODS:
01576                 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1);
01577                 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2);
01578                 break;
01579         case IEEE80211_FC1_DIR_TODS:
01580                 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3);
01581                 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2);
01582                 break;
01583         case IEEE80211_FC1_DIR_FROMDS:
01584                 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1);
01585                 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr3);
01586                 break;
01587         case IEEE80211_FC1_DIR_DSTODS:
01588                 /* not yet supported */
01589                 printk("%s: DS to DS\n", __func__);
01590                 dev_kfree_skb_any(skb);
01591                 return NULL;
01592         }
01593         if (!ALIGNED_POINTER(skb->data + sizeof(*eh), u_int32_t)) {
01594                 struct sk_buff *n;
01595 
01596                 /* XXX does this always work? */
01597                 n = skb_copy(skb, GFP_ATOMIC);
01598                 dev_kfree_skb_any(skb);
01599                 if (n == NULL)
01600                         return NULL;
01601                 skb = n;
01602                 eh = (struct ether_header *) skb->data;
01603         }
01604         if (llc != NULL)
01605                 eh->ether_type = htons(skb->len - sizeof(*eh));
01606         else
01607                 eh->ether_type = ether_type;
01608         return skb;
01609 }
01610 
01611 static struct timeval get_stamp(struct ath_hal *ah, u_int32_t t) {
01612   struct timeval now;
01613   struct timeval stamp;
01614   u_int32_t tsf_now;
01615   u_int32_t tsf;
01616   u_int32_t d;
01617   u_int32_t period;
01618   struct timeval diff;
01619 
01620   /*
01621    * Rx descriptor has the low 15 bits of the tsf at
01622    * the time the frame was received.  Use the current
01623    * tsf to extend this to 32 bits.
01624    */
01625   t &= 0x7fff;
01626 
01627   
01628   tsf_now = ath_hal_gettsf32(ah);
01629   tsf = tsf_now;
01630   do_gettimeofday(&now);
01631   if ((tsf & 0x7fff) < t)
01632     tsf -= 0x8000;
01633   
01634   tsf = t | (tsf &~ 0x7fff);
01635   
01636   d = (tsf_now - tsf);
01637   //printk("tsf is %d now %d d %d\n", tsf, tsf_now, d);
01638   period = 1000*1000;
01639   diff.tv_sec = d/period;
01640   diff.tv_usec = d % period;
01641   timersub(&now, &diff, &stamp);
01642   return stamp;
01643 
01644 }
01645 
01646 static void
01647 ath_setdefantenna(struct ath_softc *sc, u_int antenna)
01648 {
01649         struct ath_hal *ah = sc->sc_ah;
01650 
01651         /* XXX block beacon interrupts */
01652         ath_hal_setdefantenna(ah, antenna);
01653         sc->sc_defant = antenna;
01654         sc->sc_rxotherant = 0;
01655 }
01656 
01657 static void
01658 ath_rx_tasklet(TQUEUE_ARG data)
01659 {
01660 #define PA2DESC(_sc, _pa) \
01661         ((struct ath_desc *)((caddr_t)(_sc)->sc_desc + \
01662                 ((_pa) - (_sc)->sc_desc_daddr)))
01663         struct net_device *dev = (struct net_device *) data;
01664         struct ath_buf *bf;
01665         struct ath_softc *sc = dev->priv;
01666         struct net_device_stats *stats = &sc->ic_stats;
01667         struct ath_hal *ah = sc->sc_ah;
01668         struct ath_desc *ds;
01669         struct sk_buff *skb;
01670         struct ieee80211_frame *wh;
01671         int len;
01672         int prev_more = 0;
01673         u_int8_t phyerr;
01674         HAL_STATUS status;
01675         const HAL_RATE_TABLE *rt;
01676         u_int16_t dur = 0;
01677 
01678         DPRINTF(sc, ATH_DEBUG_ANY, "%s\n", __func__);
01679         do {
01680                 bf = STAILQ_FIRST(&sc->sc_rxbuf);
01681                 if (bf == NULL) {               /* XXX ??? can this happen */
01682                         printk("ath_rx_tasklet: no buffer\n");
01683                         break;
01684                 }
01685                 ds = bf->bf_desc;
01686                 if (ds->ds_link == bf->bf_daddr) {
01687                         /* NB: never process the self-linked entry at the end */
01688                         break;
01689                 }
01690                 skb = bf->bf_skb;
01691                 if (skb == NULL) {              /* XXX ??? can this happen */
01692                         printk("ath_rx_tasklet: no skbuff\n");
01693                         continue;
01694                 }
01695                 /* XXX sync descriptor memory */
01696                 /*
01697                  * Must provide the virtual address of the current
01698                  * descriptor, the physical address, and the virtual
01699                  * address of the next descriptor in the h/w chain.
01700                  * This allows the HAL to look ahead to see if the
01701                  * hardware is done with a descriptor by checking the
01702                  * done bit in the following descriptor and the address
01703                  * of the current descriptor the DMA engine is working
01704                  * on.  All this is necessary because of our use of
01705                  * a self-linked list to avoid rx overruns.
01706                  */
01707                 status = ath_hal_rxprocdesc(ah, ds,
01708                                 bf->bf_daddr, PA2DESC(sc, ds->ds_link));
01709 #ifdef AR_DEBUG
01710                 if (ath_debug > 1)
01711                         ath_printrxbuf(bf, status == HAL_OK); 
01712 #endif
01713                 if (status == HAL_EINPROGRESS)
01714                         break;
01715                 STAILQ_REMOVE_HEAD(&sc->sc_rxbuf, bf_list);
01716 
01717                 if (ds->ds_rxstat.rs_more) {
01718                         /*
01719                          * Frame spans multiple descriptors; this
01720                          * cannot happen yet as we don't support
01721                          * jumbograms.  If not in monitor mode,
01722                          * discard the frame.
01723                          */
01724 
01725                 } else if (ds->ds_rxstat.rs_status != 0) {
01726                         if (ds->ds_rxstat.rs_status & HAL_RXERR_CRC)
01727                                 sc->sc_stats.ast_rx_crcerr++;
01728                         if (ds->ds_rxstat.rs_status & HAL_RXERR_FIFO)
01729                                 sc->sc_stats.ast_rx_fifoerr++;
01730                         if (ds->ds_rxstat.rs_status & HAL_RXERR_DECRYPT)
01731                                 sc->sc_stats.ast_rx_badcrypt++;
01732                         if (ds->ds_rxstat.rs_status & HAL_RXERR_PHY) {
01733                                 sc->sc_stats.ast_rx_phyerr++;
01734                                 phyerr = ds->ds_rxstat.rs_phyerr & 0x1f;
01735                                 sc->sc_stats.ast_rx_phy[phyerr]++;
01736                         }
01737 
01738                         /*
01739                          * reject error frames, we normally don't want
01740                          * to see them in monitor mode.
01741                          */
01742                         if (!ath_phyerr && 
01743                             ((ds->ds_rxstat.rs_status & HAL_RXERR_DECRYPT ) ||
01744                              (ds->ds_rxstat.rs_status & HAL_RXERR_PHY))) {
01745                           goto rx_next;
01746                         }
01747                          
01748 
01749                         /*
01750                          * In monitor mode, allow through packets that
01751                          * cannot be decrypted
01752                          */
01753                         if (!ath_phyerr && 
01754                             ((ds->ds_rxstat.rs_status & ~HAL_RXERR_DECRYPT) ||
01755                             sc->ic_opmode != IEEE80211_M_MONITOR)) {
01756                           goto rx_next;
01757                         }
01758                 }
01759 
01760                 len = ds->ds_rxstat.rs_datalen;
01761                 if (len == 0) {
01762                   if (0) {
01763                     printk(KERN_WARNING "%s: ath_rx_tasklet: short packet %d\n",
01764                            dev->name, len);
01765                   }
01766                   sc->sc_stats.ast_rx_tooshort++;
01767                   goto rx_next;
01768                 }
01769                 
01770                 bus_dma_sync_single(sc->sc_bdev,
01771                         bf->bf_skbaddr, len, BUS_DMA_FROMDEVICE);
01772 
01773                 /*
01774                  * Normal receive.
01775                  */
01776                 wh = (struct ieee80211_frame *) skb->data;
01777                 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
01778                 case IEEE80211_FC0_TYPE_CTL:
01779                         sc->sc_stats.ast_rx_ctl++;
01780                 case IEEE80211_FC0_TYPE_MGT:
01781                         sc->sc_stats.ast_rx_mgt++;
01782                 }
01783                 bus_unmap_single(sc->sc_bdev, bf->bf_skbaddr,
01784                                  sc->sc_rxbufsize, BUS_DMA_FROMDEVICE);
01785                 bf->bf_skb = NULL;
01786                 skb_put(skb, len);
01787                 skb->protocol = ETH_P_CONTROL;          /* XXX */
01788                 if (IFF_DUMPPKTS(sc)) {
01789                         ieee80211_dump_pkt(skb->data, len,
01790                                    sc->sc_hwmap[ds->ds_rxstat.rs_rate] &
01791                                         IEEE80211_RATE_VAL,
01792                                    ds->ds_rxstat.rs_rssi);
01793                 }
01794                 if (!prev_more) {
01795                   skb_trim(skb, skb->len - IEEE80211_CRC_LEN);
01796                 }
01797 
01798                 prev_more = ds->ds_rxstat.rs_more;
01799 
01800                 if (0 && sc->sc_softled) {
01801                   ath_update_led(sc, sc->sc_ledstate ^= 1);
01802                 }
01803 
01804                 //skb_push(skb, 14);
01805                 //dev_kfree_skb_any(skb);
01806                 if (skb != NULL) {
01807 
01808                   struct click_wifi_extra *ceh = (struct click_wifi_extra *) (skb->cb + EXTRA_HEADER_CB_OFFSET);
01809                   memset(ceh, 0, sizeof(struct click_wifi_extra));
01810                   ceh->magic = WIFI_EXTRA_MAGIC;
01811                   ceh->flags = 0;
01812                   /* click */
01813                   if (ds->ds_rxstat.rs_status) {
01814                     ceh->flags |= WIFI_EXTRA_RX_ERR;
01815                   }
01816                   if (ds->ds_rxstat.rs_more) {
01817                     ceh->flags |= WIFI_EXTRA_RX_MORE;
01818                   }
01819                   ceh->rssi = ds->ds_rxstat.rs_rssi;
01820                   ceh->silence = 0;
01821                   ceh->rate = sc->sc_hwmap[ds->ds_rxstat.rs_rate] & IEEE80211_RATE_VAL;
01822 
01823                   skb->protocol = 0;
01824                   dev->last_rx = jiffies;
01825                   skb->dev = &sc->dev;
01826 
01827                   rt = sc->sc_currates;
01828                   if (rt) {
01829                     int index = sc->sc_rixmap[ceh->rate];
01830                     if (index >= 0 && index < rt->rateCount) {
01831                       dur = ath_hal_computetxtime(ah, rt, len, 
01832                                                   index, AH_TRUE);
01833                     }
01834                   }
01835                   skb->stamp = get_stamp(ah, ds->ds_rxstat.rs_tstamp);
01836 
01837 
01838                   
01839                   if (sc->dev_type == ARPHRD_IEEE80211_PRISM) {
01840                       /*
01841                      * Rx descriptor has the low 15 bits of the tsf at
01842                      * the time the frame was received.  Use the current
01843                      * tsf to extend this to 32 bits.
01844                      */
01845                     
01846                     u_int32_t tsf = ath_hal_gettsf32(sc->sc_ah);
01847 
01848                     if ((tsf & 0x7fff) < ds->ds_rxstat.rs_tstamp)
01849                       tsf -= 0x8000;
01850 
01851                     tsf = ds->ds_rxstat.rs_tstamp | (tsf &~ 0x7fff);
01852                     
01853                     push_prism2_header(&sc->dev, skb, 
01854                                        ds->ds_rxstat.rs_datalen,
01855                                        ds->ds_rxstat.rs_rssi,
01856                                        sc->sc_hwmap[ds->ds_rxstat.rs_rate] & 
01857                                        IEEE80211_RATE_VAL,
01858                                        0,
01859                                        tsf);
01860                   } else {
01861                     push_wifi_extra_header(skb);
01862                   }
01863                   
01864                   if (skb) {
01865                     netif_rx(skb);
01866                   }
01867 
01868 
01869                 }
01870 //rx_done:
01871                 stats->rx_packets++;
01872                 stats->rx_bytes += len;
01873 rx_next:
01874                 STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
01875         } while (ath_rxbuf_init(sc, bf) == 0);
01876 
01877         //ath_hal_rxmonitor(ah);                /* rx signal state monitoring */
01878 #undef PA2DESC
01879 }
01880 
01881 /*
01882  * Setup a hardware data transmit queue for the specified
01883  * access control.  The hal may not support all requested
01884  * queues in which case it will return a reference to a
01885  * previously setup queue.  We record the mapping from ac's
01886  * to h/w queues for use by ath_tx_start and also track
01887  * the set of h/w queues being used to optimize work in the
01888  * transmit interrupt handler and related routines.
01889  */
01890 static int
01891 ath_tx_setup(struct ath_softc *sc, int ac, int haltype)
01892 {
01893 #define N(a)    (sizeof(a)/sizeof(a[0]))
01894         struct ath_hal *ah = sc->sc_ah;
01895         HAL_TXQ_INFO qi;
01896         int qnum;
01897 
01898         if (ac >= N(sc->sc_ac2q)) {
01899                 printk("%s: AC %u out of range, max %u!\n",
01900                        sc->dev.name, ac, N(sc->sc_ac2q));
01901                 return 0;
01902         }
01903         memset(&qi, 0, sizeof(qi));
01904         qi.tqi_subtype = haltype;
01905         /*
01906          * Enable interrupts only for EOL and DESC conditions.
01907          * We mark tx descriptors to receive a DESC interrupt
01908          * when a tx queue gets deep; otherwise waiting for the
01909          * EOL to reap descriptors.  Note that this is done to
01910          * reduce interrupt load and this only defers reaping
01911          * descriptors, never transmitting frames.  Aside from
01912          * reducing interrupts this also permits more concurrency.
01913          * The only potential downside is if the tx queue backs
01914          * up in which case the top half of the kernel may backup
01915          * due to a lack of tx descriptors.
01916          */
01917         qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE | TXQ_FLAG_TXDESCINT_ENABLE;
01918         qnum = ath_hal_setuptxqueue(ah, HAL_TX_QUEUE_DATA, &qi);
01919         if (qnum == -1) {
01920                 printk("%s: Unable to setup hardware queue for %s traffic!\n",
01921                         sc->dev.name, acnames[ac]);
01922                 return 0;
01923         }
01924         if (qnum >= N(sc->sc_txq)) {
01925                 printk("%s: hal qnum %u out of range, max %u!\n",
01926                         sc->dev.name, qnum, N(sc->sc_txq));
01927                 return 0;
01928         }
01929         if (!ATH_TXQ_SETUP(sc, qnum)) {
01930                 struct ath_txq *txq = &sc->sc_txq[qnum];
01931 
01932                 txq->axq_qnum = qnum;
01933                 txq->axq_depth = 0;
01934                 txq->axq_intrcnt = 0;
01935                 txq->axq_link = NULL;
01936                 STAILQ_INIT(&txq->axq_q);
01937                 ATH_TXQ_LOCK_INIT(txq);
01938                 sc->sc_txqsetup |= 1<<qnum;
01939         }
01940         sc->sc_ac2q[ac] = &sc->sc_txq[qnum];
01941         return 1;
01942 #undef N
01943 }
01944 /*                                                                                                              
01945  * Fill the hardware key cache with key entries.                                                                
01946  */
01947 static void
01948 ath_initkeytable(struct net_device *dev)
01949 {
01950   struct ath_softc *sc = dev->priv;
01951   struct ath_hal *ah = sc->sc_ah;
01952   int i;
01953 
01954   /* XXX maybe should reset all keys when !WEPON */
01955   for (i = 0; i < IEEE80211_WEP_NKID; i++) {
01956       ath_hal_keyreset(ah, i);
01957   }
01958 }
01959 
01960 /*
01961  * XXX Size of an ACK control frame in bytes.
01962  */
01963 #define IEEE80211_ACK_SIZE      (2+2+IEEE80211_ADDR_LEN+4)
01964 
01965 static int
01966 ath_tx_start(struct net_device *dev, struct ath_buf *bf,
01967     struct sk_buff *skb)
01968 {
01969 #define MIN(a,b)        ((a) < (b) ? (a) : (b))
01970 #define MAX(a,b)        ((a) > (b) ? (a) : (b))
01971         struct ath_softc *sc = dev->priv;
01972         struct ath_hal *ah = sc->sc_ah;
01973         struct net_device_stats *stats = &sc->ic_stats;
01974         int iswep, hdrlen, pktlen, try0,isqos=0;
01975         u_int8_t rix, txrate, ctsrate;
01976         struct ath_desc *ds;
01977         struct ieee80211_frame *wh;
01978         u_int8_t acc=0;
01979         u_int flags, ctsduration, antenna;
01980         HAL_PKT_TYPE atype;
01981         HAL_BOOL shortPreamble;
01982         struct ath_txq *txq;
01983         struct click_wifi_extra *ceh = (struct click_wifi_extra *) (skb->cb + EXTRA_HEADER_CB_OFFSET);
01984         u_int8_t dot11Rate = ceh->rate;
01985         const HAL_RATE_TABLE *rt;
01986         int txrate_index;
01987         int power;
01988 
01989         
01990         wh = (struct ieee80211_frame *) skb->data;
01991         iswep = wh->i_fc[1] & IEEE80211_FC1_WEP;
01992         hdrlen = sizeof(struct ieee80211_frame);
01993         if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) {
01994                 isqos = 1;
01995                 acc = skb->priority;
01996                 hdrlen += sizeof(struct ieee80211_qoscntl);
01997         }
01998         txq = sc->sc_ac2q[acc];
01999 
02000 
02001 
02002         pktlen = skb->len;
02003 
02004         pktlen += IEEE80211_CRC_LEN;
02005 
02006         /*
02007          * Load the DMA map so any coalescing is done.  This
02008          * also calculates the number of descriptors we need.
02009          */
02010         bf->bf_skbaddr = bus_map_single(sc->sc_bdev,
02011                                         skb->data, pktlen, BUS_DMA_TODEVICE);
02012         DPRINTF(sc, ATH_DEBUG_ANY, "ath_tx_start: skb %p [data %p len %u] skbaddr %x\n",
02013                 skb, skb->data, skb->len, bf->bf_skbaddr);
02014         bf->bf_skb = skb;
02015         bf->bf_node = NULL;
02016 
02017         /* setup descriptors */
02018         ds = bf->bf_desc;
02019 
02020         /*
02021          * NB: the 802.11 layer marks whether or not we should
02022          * use short preamble based on the current mode and
02023          * negotiated parameters.
02024          */
02025         shortPreamble = AH_TRUE;
02026 
02027         /*
02028          * Calculate Atheros packet type from IEEE80211 packet header
02029          * and setup for rate calculations.
02030          */
02031         atype = HAL_PKT_TYPE_NORMAL;                    /* default */
02032         if (ceh->magic == WIFI_EXTRA_MAGIC && 
02033             (ceh->flags & WIFI_EXTRA_NO_SEQ)) {
02034           atype = HAL_PKT_TYPE_PSPOLL;
02035         }
02036         rix = 0;
02037         try0 = ATH_TXMAXTRY;
02038 
02039 
02040         if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT) {
02041           u_int subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
02042           switch (subtype) {
02043           case IEEE80211_FC0_SUBTYPE_BEACON:
02044             atype = HAL_PKT_TYPE_BEACON;
02045             break;
02046           case IEEE80211_FC0_SUBTYPE_PROBE_RESP: {
02047             /* fill time stamp */
02048             u_int64_t tsf;
02049             u_int32_t *tstamp;
02050 
02051             atype = HAL_PKT_TYPE_PROBE_RESP;
02052             tsf = ath_hal_gettsf64(ah);
02053             /* XXX: adjust 100us delay to xmit */
02054             tsf += 100;
02055             tstamp = (u_int32_t *)&wh[1];
02056             tstamp[0] = cpu_to_le32(tsf & 0xffffffff);
02057             tstamp[1] = cpu_to_le32(tsf >> 32);
02058             break;
02059           }
02060           case IEEE80211_FC0_SUBTYPE_ATIM:
02061             atype = HAL_PKT_TYPE_ATIM;
02062             break;
02063           }
02064         }
02065 
02066         /*
02067          * Calculate miscellaneous flags.
02068          */
02069         flags = HAL_TXDESC_CLRDMASK;            /* XXX needed for wep errors */
02070         if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
02071           DPRINTF(sc, ATH_DEBUG_ANY, "%s: %s: noack\n", dev->name,__func__);
02072           flags |= HAL_TXDESC_NOACK;    /* no ack on broad/multicast */
02073           sc->sc_stats.ast_tx_noack++;
02074         } else if (ceh->magic == WIFI_EXTRA_MAGIC &&
02075                    (ceh->flags & WIFI_EXTRA_DO_RTS_CTS)) {
02076           flags |= HAL_TXDESC_RTSENA;
02077           sc->sc_stats.ast_tx_rts++;
02078         } 
02079         if (ceh->magic == WIFI_EXTRA_MAGIC &&
02080             ceh->flags & WIFI_EXTRA_DO_CTS) {
02081           flags |= HAL_TXDESC_CTSENA;
02082         }
02083 
02084 
02085         rt = sc->sc_currates;
02086         KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
02087 
02088         txrate = 0;
02089         txrate_index = 0;
02090         dot11Rate = ceh->rate;
02091         if (ceh->magic == WIFI_EXTRA_MAGIC && dot11Rate) {
02092           int index = sc->sc_rixmap[dot11Rate & IEEE80211_RATE_VAL];
02093           if (index >= 0 && index < rt->rateCount) {
02094             txrate = rt->info[index].rateCode;
02095             txrate_index = index;
02096           }
02097         }
02098 
02099         if (txrate == 0) {
02100           int index;
02101           dot11Rate = sc->ic_fixed_rate;
02102           index = sc->sc_rixmap[dot11Rate & IEEE80211_RATE_VAL];
02103           if (index >= 0 && index < rt->rateCount) {
02104             txrate = rt->info[index].rateCode;
02105             txrate_index = index;
02106           } else {
02107             printk(KERN_WARNING "%s: %s: fixed rate is %d, index invalid %d rateCount %d\n",
02108                    dev->name,
02109                    __func__,
02110                    dot11Rate,
02111                    index,
02112                    rt->info[index].rateCode);
02113           }
02114         }
02115         
02116         if (txrate == 0) {
02117           printk(KERN_WARNING "%s: %s: can't find txrate! fixed rate is %d\n",
02118                  dev->name,
02119                  __func__,
02120                  sc->ic_fixed_rate);
02121           
02122           // our final attempt at finding a rate.
02123           txrate = rt->info[0].rateCode;
02124           txrate_index = 0;
02125         }
02126 
02127 
02128         /*
02129          * Calculate duration.  This logically belongs in the 802.11
02130          * layer but it lacks sufficient information to calculate it.
02131          */
02132 
02133         if ((flags & HAL_TXDESC_NOACK) == 0 &&
02134             (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL) {
02135           u_int16_t dur;
02136           // XXX not right with fragmentation.
02137           dur = ath_hal_computetxtime(ah, rt, IEEE80211_ACK_SIZE,
02138                                       txrate_index, shortPreamble);
02139           *(u_int16_t *)wh->i_dur = cpu_to_le16(dur);
02140         }
02141         
02142         /*
02143          * Calculate RTS/CTS rate and duration if needed.
02144          */
02145         ctsduration = 0;
02146         ctsrate = 0;
02147 
02148         if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) {
02149                 /*
02150                  * CTS transmit rate is derived from the transmit rate
02151                  * by looking in the h/w rate table.  We must also factor
02152                  * in whether or not a short preamble is to be used.
02153                  */
02154           u_int8_t cix = rt->info[txrate_index].controlRate;
02155                 ctsrate = rt->info[cix].rateCode;
02156                 if (shortPreamble)
02157                         ctsrate |= rt->info[cix].shortPreamble;
02158                 /*
02159                  * Compute the transmit duration based on the size
02160                  * of an ACK frame.  We call into the HAL to do the
02161                  * computation since it depends on the characteristics
02162                  * of the actual PHY being used.
02163                  */
02164                 if (flags & HAL_TXDESC_RTSENA) {        /* SIFS + CTS */
02165                         ctsduration += ath_hal_computetxtime(ah,
02166                                 rt, IEEE80211_ACK_SIZE, cix, shortPreamble);
02167                 }
02168                 /* SIFS + data */
02169                 ctsduration += ath_hal_computetxtime(ah,
02170                         rt, pktlen, rix, shortPreamble);
02171                 if ((flags & HAL_TXDESC_NOACK) == 0) {  /* SIFS + ACK */
02172                         ctsduration += ath_hal_computetxtime(ah,
02173                                 rt, IEEE80211_ACK_SIZE, cix, shortPreamble);
02174                 }
02175         }
02176 
02177 
02178 
02179 
02180 
02181 
02182 
02183 
02184         antenna = 0;
02185 
02186         if (IFF_DUMPPKTS(sc)) {
02187           ieee80211_dump_pkt(skb->data, skb->len,
02188                              0 & IEEE80211_RATE_VAL, -1);
02189         }
02190 
02191 
02192         if (1) {
02193           flags |= HAL_TXDESC_INTREQ;
02194           txq->axq_intrcnt = 0;
02195         }
02196         /* make sure values from click fall within range */
02197         try0 = (ceh->magic == WIFI_EXTRA_MAGIC && ceh->max_retries) ? ceh->max_retries : ATH_TXMAXTRY;
02198         try0 = max(0, try0);
02199         try0 = min(ATH_TXMAXTRY, try0);
02200         
02201         
02202         power = (ceh->magic == WIFI_EXTRA_MAGIC && ceh->power) ?
02203         ceh->power : ATH_TPC_MAX;
02204         power = max(0, power);
02205         power = min(ATH_TPC_MAX, power);
02206 
02207         /*
02208          * Formulate first tx descriptor with tx controls.
02209          */
02210         if (!ath_hal_setuptxdesc(ah, ds
02211                                  , pktlen               /* packet length */
02212                                  , hdrlen               /* header length */
02213                                  , atype                /* Atheros packet type */
02214                                  , MIN(60,power)        /* txpower */
02215                                  , txrate, try0         /* series 0 rate/tries */
02216                                  , HAL_TXKEYIX_INVALID
02217                                  , sc->sc_txantenna     /* antenna mode */
02218                                  , flags                /* flags */
02219                                  , ctsrate              /* rts/cts rate */
02220                                  , ctsduration          /* rts/cts duration */
02221                                  )) {
02222           printk("%s: %s ath_hal_setuptxdesc failed\n", dev->name, __func__);
02223           printk("%s: ah %d ds %d pktlen %d hrdlen %d atype %d twpower %d txrate %d tries %d wep %d antenna %d flags %d ctsrate %d ctsduration %d\n" 
02224                    , dev->name
02225                    , (int)ah
02226                    , (int)ds
02227                    , pktlen
02228                    , hdrlen
02229                    , atype
02230                    , ATH_TPC_MAX /* txpower */
02231                    , txrate, try0               /* series 0 rate/tries */
02232                    , HAL_TXKEYIX_INVALID
02233                    , antenna            /* antenna mode */
02234                    , flags                      /* flags */
02235                    , ctsrate            /* rts/cts rate */
02236                    , ctsduration                /* rts/cts duration */
02237                    );
02238 
02239           return -1;
02240         }
02241 
02242 
02243         ds->ds_link = 0;
02244         ds->ds_data = bf->bf_skbaddr;
02245 
02246 
02247         /*
02248          * Setup the multi-rate retry state only when we're
02249          * going to use it.  This assumes ath_hal_setuptxdesc
02250          * initializes the descriptors (so we don't have to)
02251          * when the hardware supports multi-rate retry and
02252          * we don't use it.
02253          */
02254         if (!(flags & HAL_TXDESC_NOACK) && 
02255             ceh->magic == WIFI_EXTRA_MAGIC && 
02256             ceh->rate1) {
02257           /* make sure values from click fall within range */
02258           int index1 = sc->sc_rixmap[ceh->rate1 & IEEE80211_RATE_VAL];
02259           int index2 = sc->sc_rixmap[ceh->rate2 & IEEE80211_RATE_VAL];
02260           int index3 = sc->sc_rixmap[ceh->rate3 & IEEE80211_RATE_VAL];
02261 
02262           u_int8_t txrate1;
02263           u_int8_t txrate2;
02264           u_int8_t txrate3;
02265           
02266           index1 = MAX(0, MIN(index1, rt->rateCount));
02267           index2 = MAX(0, MIN(index2, rt->rateCount));
02268           index3 = MAX(0, MIN(index3, rt->rateCount));
02269 
02270           txrate1 = rt->info[index1].rateCode;
02271           txrate2 = rt->info[index2].rateCode;
02272           txrate3 = rt->info[index3].rateCode;
02273           
02274             if (AH_TRUE != ath_hal_setupxtxdesc(ah, ds
02275                                                 , txrate1, ceh->max_retries1    /* series 1 */
02276                                                 , txrate2, ceh->max_retries2    /* series 2 */
02277                                                 , txrate3, ceh->max_retries3    /* series 3 */
02278                                                 )) {
02279               printk(KERN_WARNING "%s: %s: couldn't setupxtxdesc\n",
02280                      dev->name,
02281                      __func__);
02282             }
02283 
02284         }
02285 
02286         if (AH_TRUE != ath_hal_filltxdesc(ah, ds
02287                                           , roundup(skb->len,4) /* segment length */
02288                                           , AH_TRUE             /* first segment */
02289                                           , AH_TRUE             /* last segment */
02290                                           , ds
02291                                           )) {
02292           DPRINTF(sc, ATH_DEBUG_ANY, "%s: %s ath_hal_filltxdesc failed\n", dev->name, __func__);
02293         }
02294         DPRINTF(sc, ATH_DEBUG_ANY, "ath_tx_start: %d: %08x %08x %08x %08x %08x %08x\n",
02295             0, ds->ds_link, ds->ds_data, ds->ds_ctl0, ds->ds_ctl1,
02296             ds->ds_hw[0], ds->ds_hw[1]);
02297 
02298         /*
02299          * Insert the frame on the outbound list and
02300          * pass it on to the hardware.
02301          */
02302         ATH_TXQ_LOCK_BH(txq);
02303         ATH_TXQ_INSERT_TAIL(txq, bf, bf_list);
02304         DPRINTF(sc, ATH_DEBUG_ANY, "%s: txq depth = %d\n",
02305                 __func__, txq->axq_depth);
02306         if (txq->axq_link == NULL) {
02307           if (AH_TRUE != ath_hal_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr)) {
02308             printk("%s: %s ath_hal_puttxbuf failed\n",
02309                    dev->name,
02310                    __func__);
02311           }
02312         } else {
02313                 *txq->axq_link = bf->bf_daddr;
02314                 DPRINTF(sc, ATH_DEBUG_ANY, "%s: link[%u](%p)=%p (%p)\n",
02315                         __func__,
02316                     txq->axq_qnum, txq->axq_link,
02317                     (caddr_t)bf->bf_daddr, bf->bf_desc);
02318         }
02319         txq->axq_link = &ds->ds_link;
02320         ATH_TXQ_UNLOCK_BH(txq);
02321 
02322         if (0 && sc->sc_softled)
02323                 ath_update_led(sc, sc->sc_ledstate ^= 1);
02324 
02325 
02326         if (AH_TRUE != ath_hal_txstart(ah, txq->axq_qnum)) {
02327           printk("%s: %s ath_hal_txstart failed\n", dev->name, __func__);
02328         }
02329         
02330         stats->tx_packets++;
02331         stats->tx_bytes += pktlen;
02332 
02333         sc->subsequent_kicks = 0;
02334         dev->trans_start = jiffies;
02335         return 0;
02336 #undef MIN
02337 }
02338 
02339 /*
02340  * Process completed xmit descriptors from the specified queue.
02341  */
02342 static void
02343 ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
02344 {
02345   struct ath_hal *ah = sc->sc_ah;
02346   struct ath_buf *bf;
02347   struct ath_desc *ds;
02348   HAL_STATUS status;
02349   struct click_wifi_extra *ceh;
02350   struct ieee80211_frame *wh;
02351 
02352   
02353   DPRINTF(sc, ATH_DEBUG_ANY, "%s: tx queue %p, link %p\n", __func__,
02354           (caddr_t) ath_hal_gettxbuf(sc->sc_ah, txq->axq_qnum),
02355           txq->axq_link);
02356   for (;;) {
02357     ATH_TXQ_LOCK(txq);
02358     txq->axq_intrcnt = 0;
02359     bf = STAILQ_FIRST(&txq->axq_q);
02360     if (bf == NULL) {
02361       txq->axq_link = NULL;
02362       ATH_TXQ_UNLOCK(txq);
02363       break;
02364     }
02365     ds = bf->bf_desc;       /* NB: last decriptor */
02366     status = ath_hal_txprocdesc(ah, ds);
02367 
02368     if (ath_debug > 1)
02369       ath_printtxbuf(bf, status == HAL_OK);
02370 
02371     
02372     if (status == HAL_EINPROGRESS) {
02373       ATH_TXQ_UNLOCK(txq);
02374       break;
02375     }
02376 
02377     ATH_TXQ_REMOVE_HEAD(txq, bf_list);
02378     ATH_TXQ_UNLOCK(txq);
02379                                 
02380     bus_unmap_single(sc->sc_bdev,
02381                      bf->bf_skbaddr, bf->bf_skb->len, BUS_DMA_TODEVICE);
02382 
02383     ceh = (struct click_wifi_extra *) (bf->bf_skb->cb + EXTRA_HEADER_CB_OFFSET);
02384     
02385     if (1) {
02386       ceh->len = bf->bf_skb->len;
02387       if (bf->bf_skb->len > sizeof(struct ieee80211_frame)) {
02388         //skb_trim(bf->bf_skb, sizeof(struct ieee80211_frame) + sizeof(struct llc));
02389       }
02390       
02391       if (ceh->magic != WIFI_EXTRA_MAGIC) {
02392         ceh->flags = 0;
02393       }
02394       ceh->magic = WIFI_EXTRA_MAGIC;
02395       ceh->flags |= WIFI_EXTRA_TX;
02396       if (ds->ds_txstat.ts_status) {
02397         ceh->flags |= WIFI_EXTRA_TX_FAIL;
02398       }
02399       if (ds->ds_txstat.ts_rate & HAL_TXSTAT_ALTRATE) {
02400         ceh->flags |= WIFI_EXTRA_TX_USED_ALT_RATE;
02401       }
02402       if (!ceh->rate) {
02403         ceh->rate = sc->sc_hwmap[ds->ds_txstat.ts_rate] & IEEE80211_RATE_VAL;
02404       }
02405       //bf->bf_skb->stamp = get_stamp(ah, ds->ds_txstat.ts_tstamp);
02406       
02407       /* rate was already set when we trasmitted */
02408       ceh->retries = ds->ds_txstat.ts_longretry;
02409       ceh->rssi = ds->ds_txstat.ts_rssi;
02410       ceh->virt_col = ds->ds_txstat.ts_virtcol;
02411       // try extracting bits [12:4] from ds_hw[3]
02412       ceh->virt_col = ((ds->ds_hw[3] >> 16) & 0xf);
02413     }
02414     
02415     wh = (struct ieee80211_frame *) bf->bf_skb->data;
02416     if (0) {
02417       u_int16_t old_seq = le16_to_cpu(*(u_int16_t *)wh->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT;
02418       printk ("old seq %d new seq %d\n",
02419               old_seq, 
02420               ds->ds_txstat.ts_seqnum);
02421     }
02422     
02423     
02424     if (!(ceh->flags & WIFI_EXTRA_NO_SEQ) &&
02425         bf->bf_skb->len >= sizeof(struct ieee80211_frame)) {
02426       /* grab the sequence number the card assigned */
02427       *(u_int16_t *) wh->i_seq = cpu_to_le16(ds->ds_txstat.ts_seqnum << IEEE80211_SEQ_SEQ_SHIFT);
02428     }
02429     
02430     if (sc->dev_type == ARPHRD_IEEE80211_PRISM) {
02431       push_prism2_header(&sc->dev, bf->bf_skb, 
02432                          ds->ds_rxstat.rs_datalen,
02433                          ds->ds_rxstat.rs_rssi,
02434                          sc->sc_hwmap[ds->ds_txstat.ts_rate] & 
02435                          IEEE80211_RATE_VAL,
02436                          1,
02437                          0);
02438     }
02439     if (ceh->magic == WIFI_EXTRA_MAGIC && !(ceh->flags & WIFI_EXTRA_NO_TXF)) {
02440       /* need to copy before we spit it back to the device, for
02441        * some weird reason. Otherwise the sockets don't get 
02442        * empty their buffers.
02443        */       
02444       
02445       if (atomic_read(&bf->bf_skb->users) != 1) {
02446         struct sk_buff *skb2=bf->bf_skb;
02447         bf->bf_skb=skb_clone(bf->bf_skb, GFP_ATOMIC);
02448         if (bf->bf_skb == NULL) {
02449           dev_kfree_skb(skb2);
02450           bf->bf_skb = NULL;
02451         }
02452         kfree_skb(skb2);
02453       } else {
02454         skb_orphan(bf->bf_skb);
02455       }
02456       if (bf->bf_skb) {
02457         bf->bf_skb->dev = &sc->dev;
02458         bf->bf_skb = push_wifi_extra_header(bf->bf_skb);
02459         if (bf->bf_skb) {
02460           netif_rx(bf->bf_skb);
02461         }
02462       }
02463     } else {
02464       dev_kfree_skb(bf->bf_skb);
02465     }
02466     
02467     
02468     bf->bf_skb = NULL;
02469     bf->bf_node = NULL;
02470     
02471     ATH_TXBUF_LOCK(sc);
02472     STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
02473     ATH_TXBUF_UNLOCK(sc);
02474   }
02475 }
02476 
02477 
02478 static void
02479 ath_tx_tasklet(TQUEUE_ARG data)
02480 {
02481         struct net_device *dev = (struct net_device *) data;
02482         struct ath_softc *sc = dev->priv;
02483         //struct ieee80211com *ic = &sc->sc_ic;
02484         int i;
02485 
02486         DPRINTF(sc, ATH_DEBUG_ANY, "%s: %s\n", dev->name, __func__);
02487         for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
02488           if (ATH_TXQ_SETUP(sc, i))
02489             ath_tx_processq(sc, &sc->sc_txq[i]);
02490         }
02491         /*
02492          * Don't wakeup unless we're associated; this insures we don't
02493          * signal the upper layer it's ok to start sending data frames.
02494          */
02495         /* XXX use a low watermark to reduce wakeups */
02496         //if (ic->ic_state == IEEE80211_S_RUN)
02497         if (!STAILQ_EMPTY(&sc->sc_txbuf) && netif_queue_stopped(dev)) {
02498           netif_wake_queue(dev);
02499         }
02500 }
02501 
02502 static void
02503 ath_tx_timeout(struct net_device *dev)
02504 {
02505         struct ath_softc *sc = dev->priv;
02506         sc->sc_stats.ast_watchdog++;
02507         printk("%s: %s timeout at %ld, latency %ld pending %d\n",
02508                dev->name,
02509                __func__,
02510                jiffies,
02511                jiffies - dev->trans_start,
02512                ath_hal_intrpend(sc->sc_ah));
02513 
02514         sc->subsequent_kicks++;
02515         if (sc->subsequent_kicks == 1) {
02516           /* maybe we missed an interrupt? */
02517           ath_intr(dev->irq, dev, 0);
02518         } else {
02519           /* don't make me reset you! */
02520           ath_init(dev);
02521           //ath_hal_dumpstate(sc->sc_ah);
02522         }
02523 }
02524 
02525 static void
02526 ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq)
02527 {
02528         struct ath_hal *ah = sc->sc_ah;
02529         struct ath_buf *bf;
02530 
02531         /*
02532          * NB: this assumes output has been stopped and
02533          *     we do not need to block ath_tx_tasklet
02534          */
02535         for (;;) {
02536                 ATH_TXQ_LOCK(txq);
02537                 bf = STAILQ_FIRST(&txq->axq_q);
02538                 if (bf == NULL) {
02539                         txq->axq_link = NULL;
02540                         ATH_TXQ_UNLOCK(txq);
02541                         break;
02542                 }
02543                 ATH_TXQ_REMOVE_HEAD(txq, bf_list);
02544                 ATH_TXQ_UNLOCK(txq);
02545 #ifdef AR_DEBUG
02546                 if (sc->sc_debug & ATH_DEBUG_ANY)
02547                         ath_printtxbuf(bf,
02548                                 ath_hal_txprocdesc(ah, bf->bf_desc) == HAL_OK);
02549 #endif /* AR_DEBUG */
02550                 bus_unmap_single(sc->sc_bdev,
02551                         bf->bf_skbaddr, bf->bf_skb->len, BUS_DMA_TODEVICE);
02552                 dev_kfree_skb(bf->bf_skb);
02553                 bf->bf_skb = NULL;
02554                 bf->bf_node = NULL;
02555                 ATH_TXBUF_LOCK(sc);
02556                 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
02557                 ATH_TXBUF_UNLOCK(sc);
02558         }
02559 }
02560 static void
02561 ath_tx_stopdma(struct ath_softc *sc, struct ath_txq *txq)
02562 {
02563         struct ath_hal *ah = sc->sc_ah;
02564 
02565         (void) ath_hal_stoptxdma(ah, txq->axq_qnum);
02566         DPRINTF(sc, ATH_DEBUG_ANY, "%s: tx queue [%u] %p, link %p\n",
02567             __func__, txq->axq_qnum,
02568             (caddr_t) ath_hal_gettxbuf(ah, txq->axq_qnum), txq->axq_link);
02569 }
02570 /*
02571  * Drain the transmit queues and reclaim resources.
02572  */
02573 static void
02574 ath_draintxq(struct ath_softc *sc)
02575 {
02576         int i;
02577 
02578         /* XXX return value */
02579         if (!sc->sc_invalid) {
02580           for (i = 0; i < HAL_NUM_TX_QUEUES; i++)
02581             if (ATH_TXQ_SETUP(sc, i))
02582               ath_tx_stopdma(sc, &sc->sc_txq[i]);
02583         }
02584         sc->dev.trans_start = jiffies;
02585         netif_start_queue(&sc->dev);
02586         for (i = 0; i < HAL_NUM_TX_QUEUES; i++)
02587                 if (ATH_TXQ_SETUP(sc, i))
02588                         ath_tx_draintxq(sc, &sc->sc_txq[i]);
02589 }
02590 
02591 /*
02592  * Disable the receive h/w in preparation for a reset.
02593  */
02594 static void
02595 ath_stoprecv(struct ath_softc *sc)
02596 {
02597 #define PA2DESC(_sc, _pa) \
02598         ((struct ath_desc *)((caddr_t)(_sc)->sc_desc + \
02599                 ((_pa) - (_sc)->sc_desc_daddr)))
02600         struct ath_hal *ah = sc->sc_ah;
02601 
02602         ath_hal_stoppcurecv(ah);        /* disable PCU */
02603         ath_hal_setrxfilter(ah, 0);     /* clear recv filter */
02604         ath_hal_stopdmarecv(ah);        /* disable DMA engine */
02605         mdelay(3);                      /* 3ms is long enough for 1 frame */
02606 #ifdef AR_DEBUG
02607         if (ath_debug) {
02608                 struct ath_buf *bf;
02609 
02610                 printk("ath_stoprecv: rx queue %p, link %p\n",
02611                     (caddr_t) ath_hal_getrxbuf(ah), sc->sc_rxlink);
02612                 STAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) {
02613                         struct ath_desc *ds = bf->bf_desc;
02614                         HAL_STATUS status = ath_hal_rxprocdesc(ah, ds,
02615                                 bf->bf_daddr, PA2DESC(sc, ds->ds_link));
02616                         if (status == HAL_OK || (sc->sc_debug & ATH_DEBUG_ANY))
02617                                 ath_printrxbuf(bf, status == HAL_OK);
02618                 }
02619         }
02620 #endif
02621         sc->sc_rxlink = NULL;           /* just in case */
02622 #undef PA2DESC
02623 }
02624 
02625 /*
02626  * Enable the receive h/w following a reset.
02627  */
02628 static int
02629 ath_startrecv(struct net_device *dev)
02630 {
02631         struct ath_softc *sc = dev->priv;
02632         struct ath_hal *ah = sc->sc_ah;
02633         struct ath_buf *bf;
02634 
02635         //sc->sc_rxbufsize = roundup(IEEE80211_MAX_LEN, sc->sc_cachelsz);
02636         sc->sc_rxbufsize = roundup(3196, sc->sc_cachelsz);
02637         //sc->sc_rxbufsize = roundup(4100, sc->sc_cachelsz);
02638         DPRINTF(sc, ATH_DEBUG_ANY, "ath_startrecv: mtu %u cachelsz %u rxbufsize %u\n",
02639                 dev->mtu, sc->sc_cachelsz, sc->sc_rxbufsize);
02640 
02641         sc->sc_rxlink = NULL;
02642 
02643         STAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) {
02644                 int error = ath_rxbuf_init(sc, bf);
02645                 if (error != 0)
02646                         return error;
02647         }
02648 
02649         bf = STAILQ_FIRST(&sc->sc_rxbuf);
02650         ath_hal_putrxbuf(ah, bf->bf_daddr);
02651         ath_hal_rxena(ah);              /* enable recv descriptors */
02652         ath_mode_init(&sc->dev);        /* set filters, etc. */
02653         ath_hal_startpcurecv(ah);       /* re-enable PCU/DMA engine */
02654         return 0;
02655 }
02656 
02657 /*
02658  * Periodically recalibrate the PHY to account
02659  * for temperature/environment changes.
02660  */
02661 static void
02662 ath_calibrate(unsigned long arg)
02663 {
02664         struct net_device *dev = (struct net_device *) arg;
02665         struct ath_softc *sc = dev->priv;
02666         struct ath_hal *ah = sc->sc_ah;
02667         struct ieee80211channel *c;
02668         HAL_CHANNEL hchan;
02669 
02670         sc->sc_stats.ast_per_cal++;
02671 
02672         /*
02673          * Convert to a HAL channel description with the flags
02674          * constrained to reflect the current operating mode.
02675          */
02676         c = sc->current_channel;
02677         hchan.channel = c->ic_freq;
02678         hchan.channelFlags = ath_chan2flags(sc, c);
02679 
02680         //DPRINTF(sc"%s: channel %u/%x\n", __func__, c->ic_freq, c->ic_flags);
02681 
02682         if (ath_hal_getrfgain(ah) == HAL_RFGAIN_NEED_CHANGE) {
02683                 /*
02684                  * Rfgain is out of bounds, reset the chip
02685                  * to load new gain values.
02686                  */
02687                 sc->sc_stats.ast_per_rfgain++;
02688                 ath_reset(dev);
02689         }
02690         if (!ath_hal_calibrate(ah, &hchan)) {
02691                 DPRINTF(sc, ATH_DEBUG_ANY, "%s: %s: calibration of channel %u failed\n",
02692                         dev->name, __func__, c->ic_freq);
02693                 sc->sc_stats.ast_per_calfail++;
02694         }
02695         sc->sc_cal_ch.expires = jiffies + (ath_calinterval * HZ);
02696         add_timer(&sc->sc_cal_ch);
02697 }
02698 
02699 
02700 static int
02701 ath_getchannels(struct net_device *dev, u_int cc,
02702         HAL_BOOL outdoor, HAL_BOOL xchanmode)
02703 {
02704         struct ath_softc *sc = dev->priv;
02705         struct ath_hal *ah = sc->sc_ah;
02706         HAL_CHANNEL *chans;
02707         int i, ix, nchan;
02708 
02709         chans = kmalloc(IEEE80211_CHAN_MAX * sizeof(HAL_CHANNEL), GFP_KERNEL);
02710         if (chans == NULL) {
02711                 printk("%s: unable to allocate channel table\n", dev->name);
02712                 return ENOMEM;
02713         }
02714         if (!ath_hal_init_channels(ah, chans, IEEE80211_CHAN_MAX, &nchan,
02715             cc, HAL_MODE_ALL, outdoor, xchanmode)) {
02716                 u_int32_t rd;
02717 
02718                 ath_hal_getregdomain(ah, &rd);
02719                 printk("%s: unable to collect channel list from hal; "
02720                         "regdomain likely %u country code %u\n",
02721                         dev->name, rd, cc);
02722                 kfree(chans);
02723                 return 0;
02724                 //return EINVAL;
02725         }
02726 
02727 
02728         /*
02729          * Convert HAL channels to ieee80211 ones and insert
02730          * them in the table according to their channel number.
02731          */
02732         for (i = 0; i < nchan; i++) {
02733                 HAL_CHANNEL *c = &chans[i];
02734                 ix = ath_hal_mhz2ieee(c->channel, c->channelFlags);
02735                 if (ix > IEEE80211_CHAN_MAX) {
02736                         continue;
02737                 }
02738                 /* NB: flags are known to be compatible */
02739                 if (sc->ic_channels[ix].ic_freq == 0) {
02740                         sc->ic_channels[ix].ic_freq = c->channel;
02741                         sc->ic_channels[ix].ic_flags = c->channelFlags;
02742                 } else {
02743                         /* channels overlap; e.g. 11g and 11b */
02744                         sc->ic_channels[ix].ic_flags |= c->channelFlags;
02745                 }
02746         }
02747 
02748         kfree(chans);
02749         return 0;
02750 }
02751 
02752 static int
02753 ath_setchannel(struct ath_softc *sc,   struct ieee80211channel *channel)
02754 {
02755 
02756 
02757 #define N(a)    (sizeof(a) / sizeof(a[0]))
02758         static const u_int chanflags[] = {
02759                 0,                      /* IEEE80211_MODE_AUTO */
02760                 IEEE80211_CHAN_A,       /* IEEE80211_MODE_11A */
02761                 IEEE80211_CHAN_B,       /* IEEE80211_MODE_11B */
02762                 IEEE80211_CHAN_PUREG,   /* IEEE80211_MODE_11G */
02763                 IEEE80211_CHAN_T,       /* IEEE80211_MODE_TURBO */
02764         };
02765         struct ieee80211channel *c;
02766         u_int modeflags;
02767         int i;
02768         const HAL_RATE_TABLE *rt;
02769         
02770 
02771         /*
02772          * set the mode according to the channel 
02773          */
02774         enum ieee80211_phymode mode = chan2mode(sc, channel);
02775 
02776         /*
02777          * Verify at least one channel is present in the available
02778          * channel list before committing to the new mode.
02779          */
02780         KASSERT(mode < N(chanflags), ("Unexpected mode %u\n", mode));
02781         modeflags = chanflags[mode];
02782         for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
02783                 c = &sc->ic_channels[i];
02784                 if (mode == IEEE80211_MODE_AUTO) {
02785                         /* ignore turbo channels for autoselect */
02786                         if ((c->ic_flags &~ IEEE80211_CHAN_TURBO) != 0)
02787                                 break;
02788                 } else {
02789                         if ((c->ic_flags & modeflags) == modeflags)
02790                                 break;
02791                 }
02792         }
02793         if (i > IEEE80211_CHAN_MAX) {
02794           printk("%s: no channels found for mode %u\n",
02795                  __func__, mode);
02796           return -EINVAL;
02797         }
02798 
02799         /*
02800          * If no current/default channel is setup or the current
02801          * channel is wrong for the mode then pick the first
02802          * available channel from the active list.  This is likely
02803          * not the right one.
02804          */
02805         if (channel == NULL ||
02806             isclr(sc->ic_chan_avail, chan2ieee(sc, channel))) {
02807           printk("%s: %s: invalid channel %d\n", 
02808                  __func__,
02809                  sc->dev.name,
02810                  channel ? chan2ieee(sc, channel) : 0);
02811           channel = NULL;
02812           for (i = 0; i <= IEEE80211_CHAN_MAX; i++)
02813             if ((c->ic_flags & modeflags) == modeflags) {
02814               channel = &sc->ic_channels[i];
02815               break;
02816             }
02817         }
02818         
02819         if (!channel) {
02820           printk("%s: %s couldn't find valid channel\n",
02821                  __func__,
02822                  sc->dev.name);
02823           return -EINVAL;
02824         }
02825 
02826         rt = sc->sc_rates[mode];        
02827         if (!rt) {
02828           printk("%s: %s: no h/w rate set for phy mode %u", 
02829                  __func__,
02830                  sc->dev.name, 
02831                  mode);
02832           return -EINVAL;
02833         }
02834         sc->current_channel = channel;
02835         sc->ic_curmode = mode;
02836 
02837         memset(sc->sc_rixmap, 0xff, sizeof(sc->sc_rixmap));
02838 
02839 
02840 
02841         /* set the current bitrate as invalid */
02842         sc->ic_fixed_rate = 0;
02843 
02844         for (i = 0; i < rt->rateCount; i++) {
02845           sc->sc_rixmap[rt->info[i].dot11Rate & IEEE80211_RATE_VAL] = i;
02846           if (!sc->ic_fixed_rate && rt->info[i].valid) {
02847             /* set the bitrate to the first one available */
02848             sc->ic_fixed_rate = rt->info[i].dot11Rate & IEEE80211_RATE_VAL;
02849           }
02850         }
02851 
02852         memset(sc->sc_hwmap, 0, sizeof(sc->sc_hwmap));
02853         for (i = 0; i < 32; i++) {
02854                 u_int8_t ix = rt->rateCodeToIndex[i];
02855                 if (ix != 0xff)
02856                         sc->sc_hwmap[i] = rt->info[ix].dot11Rate;
02857 
02858         }
02859         sc->sc_currates = rt;
02860         return 0;
02861 }
02862 
02863 
02864 static int
02865 ath_rate_setup(struct net_device *dev, u_int mode)
02866 {
02867         struct ath_softc *sc = dev->priv;
02868         struct ath_hal *ah = sc->sc_ah;
02869         const HAL_RATE_TABLE *rt;
02870         int maxrates;
02871         int x = 0;
02872         switch (mode) {
02873         case IEEE80211_MODE_11A:
02874                 sc->sc_rates[mode] = ath_hal_getratetable(ah, HAL_MODE_11A);
02875                 break;
02876         case IEEE80211_MODE_11B:
02877                 sc->sc_rates[mode] = ath_hal_getratetable(ah, HAL_MODE_11B);
02878                 break;
02879         case IEEE80211_MODE_11G:
02880                 sc->sc_rates[mode] = ath_hal_getratetable(ah, HAL_MODE_11G);
02881                 break;
02882         case IEEE80211_MODE_TURBO:
02883                 sc->sc_rates[mode] = ath_hal_getratetable(ah, HAL_MODE_TURBO);
02884                 break;
02885         default:
02886                 DPRINTF(sc, ATH_DEBUG_ANY, "%s: invalid mode %u\n", __func__, mode);
02887                 return 0;
02888         }
02889         rt = sc->sc_rates[mode];
02890         if (rt == NULL)
02891                 return 0;
02892         if (rt->rateCount > IEEE80211_RATE_MAXSIZE) {
02893                 DPRINTF(sc, ATH_DEBUG_ANY, "%s: rate table too small (%u > %u)\n",
02894                         __func__, rt->rateCount, IEEE80211_RATE_MAXSIZE);
02895                 maxrates = IEEE80211_RATE_MAXSIZE;
02896         } else
02897                 maxrates = rt->rateCount;
02898 
02899         printk("%s: mode %d rates (in Mbps):",
02900                dev->name,
02901                mode);
02902         for ( x = 0; x < rt->rateCount; x++) {
02903           if (rt->info[x].valid) {
02904             if (rt->info[x].rateKbps % 1000) {
02905               printk(" %d.%1d", 
02906                      rt->info[x].rateKbps / 1000,
02907                      (rt->info[x].rateKbps % 1000) / 100);
02908             } else {
02909               printk(" %d", rt->info[x].rateKbps / 1000);
02910             }
02911           }
02912         }
02913         printk("\n");
02914         return 1;
02915 }
02916 
02917 #ifdef AR_DEBUG
02918 static void
02919 ath_printrxbuf(struct ath_buf *bf, int done)
02920 {
02921         struct ath_desc *ds = bf->bf_desc;
02922 
02923         printk("R (%p %p) %08x %08x %08x %08x %08x %08x %c\n",
02924             ds, (struct ath_desc *)bf->bf_daddr,
02925             ds->ds_link, ds->ds_data,
02926             ds->ds_ctl0, ds->ds_ctl1,
02927             ds->ds_hw[0], ds->ds_hw[1],
02928             !done ? ' ' : (ds->ds_rxstat.rs_status == 0) ? '*' : '!');
02929 }
02930 
02931 static void
02932 ath_printtxbuf(struct ath_buf *bf, int done)
02933 {
02934         struct ath_desc *ds = bf->bf_desc;
02935 
02936         printk("T (%p %p) %08x %08x %08x %08x %08x %08x %08x %08x %c\n",
02937             ds, (struct ath_desc *)bf->bf_daddr,
02938             ds->ds_link, ds->ds_data,
02939             ds->ds_ctl0, ds->ds_ctl1,
02940             ds->ds_hw[0], ds->ds_hw[1], ds->ds_hw[2], ds->ds_hw[3],
02941             !done ? ' ' : (ds->ds_txstat.ts_status == 0) ? '*' : '!');
02942 }
02943 #endif /* AR_DEBUG */
02944 
02945 /*
02946  * Return netdevice statistics.
02947  */
02948 static struct net_device_stats *
02949 ath_getstats(struct net_device *dev)
02950 {
02951         struct ath_softc *sc = dev->priv;
02952         struct net_device_stats *stats = &sc->ic_stats;
02953 
02954         /* update according to private statistics */
02955         stats->tx_errors = sc->sc_stats.ast_tx_encap
02956                          + sc->sc_stats.ast_tx_nonode
02957                          + sc->sc_stats.ast_tx_xretries
02958                          + sc->sc_stats.ast_tx_fifoerr
02959                          + sc->sc_stats.ast_tx_filtered
02960                          ;
02961         stats->tx_dropped = sc->sc_stats.ast_tx_nobuf
02962                         + sc->sc_stats.ast_tx_nobufmgt;
02963         stats->rx_errors = sc->sc_stats.ast_rx_tooshort
02964                         + sc->sc_stats.ast_rx_crcerr
02965                         + sc->sc_stats.ast_rx_fifoerr
02966                         + sc->sc_stats.ast_rx_badcrypt
02967                         ;
02968         stats->rx_crc_errors = sc->sc_stats.ast_rx_crcerr;
02969 
02970         return stats;
02971 }
02972 
02973 static int
02974 ath_set_mac_address(struct net_device *dev, void *addr)
02975 {
02976         struct ath_softc *sc = dev->priv;
02977         struct ath_hal *ah = sc->sc_ah;
02978         struct sockaddr *mac = addr;
02979 
02980         if (netif_running(dev)) {
02981                 DPRINTF(sc, ATH_DEBUG_ANY, "%s: cannot set address; device running\n", __func__);
02982                 return -EBUSY;
02983         }
02984         DPRINTF(sc, ATH_DEBUG_ANY, "%s: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", __func__,
02985                 mac->sa_data[0], mac->sa_data[1], mac->sa_data[2],
02986                 mac->sa_data[3], mac->sa_data[4], mac->sa_data[5]);
02987         IEEE80211_ADDR_COPY(dev->dev_addr, mac->sa_data);
02988         ath_hal_setmac(ah, dev->dev_addr);
02989         return -ath_reset(dev);
02990 }
02991 
02992 static int      
02993 ath_change_mtu(struct net_device *dev, int mtu) 
02994 {
02995         if (!(ATH_MIN_MTU < mtu && mtu <= ATH_MAX_MTU)) {
02996                 return -EINVAL;
02997         }
02998         dev->mtu = mtu;
02999         return -ath_reset(dev);
03000 }
03001 
03002 /*
03003  * Diagnostic interface to the HAL.  This is used by various
03004  * tools to do things like retrieve register contents for
03005  * debugging.  The mechanism is intentionally opaque so that
03006  * it can change frequently w/o concern for compatiblity.
03007  */
03008 static int
03009 ath_ioctl_diag(struct ath_softc *sc, struct ath_diag *ad)
03010 {
03011         struct ath_hal *ah = sc->sc_ah;
03012         u_int id = ad->ad_id & ATH_DIAG_ID;
03013         void *indata = NULL;
03014         void *outdata = NULL;
03015         u_int32_t insize = ad->ad_in_size;
03016         u_int32_t outsize = ad->ad_out_size;
03017         int error = 0;
03018 
03019         if (ad->ad_id & ATH_DIAG_IN) {
03020                 /*
03021                  * Copy in data.
03022                  */
03023                 indata = kmalloc(insize, GFP_KERNEL);
03024                 if (indata == NULL) {
03025                         error = -ENOMEM;
03026                         goto bad;
03027                 }
03028                 if (copy_from_user(indata, ad->ad_in_data, insize)) {
03029                         error = -EFAULT;
03030                         goto bad;
03031                 }
03032         }
03033         if (ad->ad_id & ATH_DIAG_DYN) {
03034                 /*
03035                  * Allocate a buffer for the results (otherwise the HAL
03036                  * returns a pointer to a buffer where we can read the
03037                  * results).  Note that we depend on the HAL leaving this
03038                  * pointer for us to use below in reclaiming the buffer;
03039                  * may want to be more defensive.
03040                  */
03041                 outdata = kmalloc(outsize, GFP_KERNEL);
03042                 if (outdata == NULL) {
03043                         error = -ENOMEM;
03044                         goto bad;
03045                 }
03046         }
03047         if (ath_hal_getdiagstate(ah, id, indata, insize, &outdata, &outsize)) {
03048                 if (outsize < ad->ad_out_size)
03049                         ad->ad_out_size = outsize;
03050                 if (outdata &&
03051                      copy_to_user(ad->ad_out_data, outdata, ad->ad_out_size))
03052                         error = -EFAULT;
03053         } else {
03054                 error = -EINVAL;
03055         }
03056 bad:
03057         if ((ad->ad_id & ATH_DIAG_IN) && indata != NULL)
03058                 kfree(indata);
03059         if ((ad->ad_id & ATH_DIAG_DYN) && outdata != NULL)
03060                 kfree(outdata);
03061         return error;
03062 }
03063 
03064 
03065 extern  int ath_ioctl_ethtool(struct ath_softc *sc, int cmd, void *addr);
03066 
03067 static int
03068 ath_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
03069 {
03070         struct ath_softc *sc = dev->priv;
03071         int error;
03072 
03073         switch (cmd) {
03074         case SIOCGATHSTATS:
03075                         error = 0;
03076                 break;
03077         case SIOCGATHDIAG:
03078                 if (!capable(CAP_NET_ADMIN))
03079                         error = -EPERM;
03080                 else
03081                         error = ath_ioctl_diag(sc, (struct ath_diag *) ifr);
03082                 break;
03083         case SIOCETHTOOL:
03084                 if (copy_from_user(&cmd, ifr->ifr_data, sizeof(cmd)))
03085                         error = -EFAULT;
03086                 else
03087                         error = ath_ioctl_ethtool(sc, cmd, ifr->ifr_data);
03088                         break;
03089         default:
03090                 error = 0;
03091                 break;
03092         }
03093         return error;
03094 }
03095 
03096 #ifdef CONFIG_SYSCTL
03097 /*
03098  * Sysctls are split into ``static'' and ``dynamic'' tables.
03099  * The former are defined at module load time and are used
03100  * control parameters common to all devices.  The latter are
03101  * tied to particular device instances and come and go with
03102  * each device.  The split is currently a bit tenuous; many of
03103  * the static ones probably should be dynamic but having them
03104  * static (e.g. debug) means they can be set after a module is
03105  * loaded and before bringing up a device.  The alternative
03106  * is to add module parameters.
03107  */
03108 
03109 /*
03110  * Dynamic (i.e. per-device) sysctls.  These are automatically
03111  * mirrored in /proc/sys.
03112  */
03113 enum {
03114         ATH_SLOTTIME    = 1,
03115         ATH_ACKTIMEOUT  = 2,
03116         ATH_CTSTIMEOUT  = 3,
03117         ATH_SOFTLED     = 4,
03118         ATH_LEDPIN      = 5,
03119         ATH_COUNTRYCODE = 6,
03120         ATH_REGDOMAIN   = 7,
03121         ATH_DEBUG       = 8,
03122         ATH_TXANTENNA   = 9,
03123         ATH_RXANTENNA   = 10,
03124         ATH_DIVERSITY   = 11,
03125         ATH_PHYERR      = 12,
03126 };
03127 
03128 static int
03129 ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl, write, filp, buffer, lenp, ppos)
03130 {
03131         struct ath_softc *sc = ctl->extra1;
03132         struct ath_hal *ah = sc->sc_ah;
03133         u_int val;
03134         int ret;
03135 
03136         ctl->data = &val;
03137         ctl->maxlen = sizeof(val);
03138         if (write) {
03139                 ret = ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer,
03140                                 lenp, ppos);
03141                 if (ret == 0) {
03142                         switch (ctl->ctl_name) {
03143                         case ATH_SLOTTIME:
03144                                 if (!ath_hal_setslottime(ah, val))
03145                                         ret = -EINVAL;
03146                                 break;
03147                         case ATH_ACKTIMEOUT:
03148                                 if (!ath_hal_setacktimeout(ah, val))
03149                                         ret = -EINVAL;
03150                                 break;
03151                         case ATH_CTSTIMEOUT:
03152                                 if (!ath_hal_setctstimeout(ah, val))
03153                                         ret = -EINVAL;
03154                                 break;
03155                         case ATH_SOFTLED:
03156                                 if (val != sc->sc_softled) {
03157                                         if (val)
03158                                                 ath_hal_gpioCfgOutput(ah,
03159                                                         sc->sc_ledpin);
03160                                         ath_hal_gpioset(ah, sc->sc_ledpin,!val);
03161                                         sc->sc_softled = val;
03162                                 }
03163                                 break;
03164                         case ATH_LEDPIN:
03165                                 sc->sc_ledpin = val;
03166                                 break;
03167                         case ATH_DEBUG:
03168                                 sc->sc_debug = val;
03169                                 break;
03170                         case ATH_TXANTENNA:
03171                                 /* XXX validate? */
03172                                 sc->sc_txantenna = val;
03173                                 break;
03174                         case ATH_RXANTENNA:
03175                                 /* XXX validate? */
03176                                 ath_setdefantenna(sc, val);
03177                                 break;
03178                         case ATH_DIVERSITY:
03179                                 /* XXX validate? */
03180                                 if (!sc->sc_hasdiversity)
03181                                         return -EINVAL;
03182                                 sc->sc_diversity = val;
03183                                 ath_hal_setdiversity(ah, val);
03184                                 break;
03185                         case ATH_PHYERR: {
03186                           uint32_t rfilt = ath_calcrxfilter(&sc->dev);
03187                           ath_phyerr = val;
03188                           ath_hal_setrxfilter(ah, rfilt);
03189                           break;
03190                         }
03191                         default:
03192                                 return -EINVAL;
03193                         }
03194                 }
03195         } else {
03196                 switch (ctl->ctl_name) {
03197                 case ATH_SLOTTIME:
03198                         val = ath_hal_getslottime(ah);
03199                         break;
03200                 case ATH_ACKTIMEOUT:
03201                         val = ath_hal_getacktimeout(ah);
03202                         break;
03203                 case ATH_CTSTIMEOUT:
03204                         val = ath_hal_getctstimeout(ah);
03205                         break;
03206                 case ATH_SOFTLED:
03207                         val = sc->sc_softled;
03208                         break;
03209                 case ATH_LEDPIN:
03210                         val = sc->sc_ledpin;
03211                         break;
03212                 case ATH_COUNTRYCODE:
03213                         ath_hal_getcountrycode(ah, &val);
03214                         break;
03215                 case ATH_REGDOMAIN:
03216                         ath_hal_getregdomain(ah, &val);
03217                         break;
03218                 case ATH_DEBUG:
03219                         val = sc->sc_debug;
03220                         break;
03221                 case ATH_TXANTENNA:
03222                         val = sc->sc_txantenna;
03223                         break;
03224                 case ATH_RXANTENNA:
03225                         val = ath_hal_getdefantenna(ah);
03226                         break;
03227                 case ATH_DIVERSITY:
03228                         val = sc->sc_diversity;
03229                         break;
03230                 case ATH_PHYERR:
03231                         val = ath_phyerr;
03232                         break;
03233                 default:
03234                         return -EINVAL;
03235                 }
03236                 ret = ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer,
03237                                 lenp, ppos);
03238         }
03239         return ret;
03240 }
03241 
03242 static  int mindwelltime = 100;                 /* 100ms */
03243 static  int mincalibrate = 1;                   /* once a second */
03244 static  int maxint = 0x7fffffff;                /* 32-bit big */
03245 
03246 #define CTL_AUTO        -2      /* cannot be CTL_ANY or CTL_NONE */
03247 
03248 static const ctl_table ath_sysctl_template[] = {
03249         { .ctl_name     = ATH_SLOTTIME,
03250           .procname     = "slottime",
03251           .mode         = 0644,
03252           .proc_handler = ath_sysctl_halparam
03253         },
03254         { .ctl_name     = ATH_ACKTIMEOUT,
03255           .procname     = "acktimeout",
03256           .mode         = 0644,
03257           .proc_handler = ath_sysctl_halparam
03258         },
03259         { .ctl_name     = ATH_CTSTIMEOUT,
03260           .procname     = "ctstimeout",
03261           .mode         = 0644,
03262           .proc_handler = ath_sysctl_halparam
03263         },
03264         { .ctl_name     = ATH_SOFTLED,
03265           .procname     = "softled",
03266           .mode         = 0644,
03267           .proc_handler = ath_sysctl_halparam
03268         },
03269         { .ctl_name     = ATH_LEDPIN,
03270           .procname     = "ledpin",
03271           .mode         = 0644,
03272           .proc_handler = ath_sysctl_halparam
03273         },
03274         { .ctl_name     = ATH_COUNTRYCODE,
03275           .procname     = "countrycode",
03276           .mode         = 0444,
03277           .proc_handler = ath_sysctl_halparam
03278         },
03279         { .ctl_name     = ATH_REGDOMAIN,
03280           .procname     = "regdomain",
03281           .mode         = 0444,
03282           .proc_handler = ath_sysctl_halparam
03283         },
03284 #ifdef AR_DEBUG
03285         { .ctl_name     = ATH_DEBUG,
03286           .procname     = "debug",
03287           .mode         = 0644,
03288           .proc_handler = ath_sysctl_halparam
03289         },
03290 #endif
03291         { .ctl_name     = ATH_TXANTENNA,
03292           .procname     = "txantenna",
03293           .mode         = 0644,
03294           .proc_handler = ath_sysctl_halparam
03295         },
03296         { .ctl_name     = ATH_RXANTENNA,
03297           .procname     = "rxantenna",
03298           .mode         = 0644,
03299           .proc_handler = ath_sysctl_halparam
03300         },
03301         { .ctl_name     = ATH_DIVERSITY,
03302           .procname     = "diversity",
03303           .mode         = 0644,
03304           .proc_handler = ath_sysctl_halparam
03305         },
03306         { .ctl_name     = ATH_PHYERR,
03307           .procname     = "phyerr",
03308           .mode         = 0644,
03309           .proc_handler = ath_sysctl_halparam
03310         },
03311         { 0 }
03312 };
03313 
03314 static void
03315 ath_dynamic_sysctl_register(struct ath_softc *sc)
03316 {
03317         int i, space;
03318 
03319         space = 5*sizeof(struct ctl_table) + sizeof(ath_sysctl_template);
03320         sc->sc_sysctls = kmalloc(space, GFP_KERNEL);
03321         if (sc->sc_sysctls == NULL) {
03322                 printk("%s: no memory for sysctl table!\n", __func__);
03323                 return;
03324         }
03325 
03326         /* setup the table */
03327         memset(sc->sc_sysctls, 0, space);
03328         sc->sc_sysctls[0].ctl_name = CTL_DEV;
03329         sc->sc_sysctls[0].procname = "dev";
03330         sc->sc_sysctls[0].mode = 0555;
03331         sc->sc_sysctls[0].child = &sc->sc_sysctls[2];
03332         /* [1] is NULL terminator */
03333         sc->sc_sysctls[2].ctl_name = CTL_AUTO;
03334         sc->sc_sysctls[2].procname = sc->dev.name;
03335         sc->sc_sysctls[2].mode = 0555;
03336         sc->sc_sysctls[2].child = &sc->sc_sysctls[4];
03337         /* [3] is NULL terminator */
03338         /* copy in pre-defined data */
03339         memcpy(&sc->sc_sysctls[4], ath_sysctl_template,
03340                 sizeof(ath_sysctl_template));
03341 
03342         /* add in dynamic data references */
03343         for (i = 4; sc->sc_sysctls[i].ctl_name; i++)
03344                 if (sc->sc_sysctls[i].extra1 == NULL)
03345                         sc->sc_sysctls[i].extra1 = sc;
03346 
03347         /* and register everything */
03348         sc->sc_sysctl_header = register_sysctl_table(sc->sc_sysctls, 1);
03349         if (!sc->sc_sysctl_header) {
03350                 printk("%s: failed to register sysctls!\n", sc->dev.name);
03351                 kfree(sc->sc_sysctls);
03352                 sc->sc_sysctls = NULL;
03353         }
03354 
03355         /* initialize values */
03356         sc->sc_debug = ath_debug;
03357         sc->sc_txantenna = 0;           /* default to auto-selection */
03358 }
03359 
03360 static void
03361 ath_dynamic_sysctl_unregister(struct ath_softc *sc)
03362 {
03363         if (sc->sc_sysctl_header) {
03364                 unregister_sysctl_table(sc->sc_sysctl_header);
03365                 sc->sc_sysctl_header = NULL;
03366         }
03367         if (sc->sc_sysctls) {
03368                 kfree(sc->sc_sysctls);
03369                 sc->sc_sysctls = NULL;
03370         }
03371 }
03372 
03373 /*
03374  * Announce various information on device/driver attach.
03375  */
03376 static void
03377 ath_announce(struct net_device *dev)
03378 {
03379 #define HAL_MODE_DUALBAND       (HAL_MODE_11A|HAL_MODE_11B)
03380         struct ath_softc *sc = dev->priv;
03381         struct ath_hal *ah = sc->sc_ah;
03382         u_int modes, cc;
03383         int i;
03384 
03385         printk("%s: mac %d.%d phy %d.%d", dev->name,
03386                 ah->ah_macVersion, ah->ah_macRev,
03387                 ah->ah_phyRev >> 4, ah->ah_phyRev & 0xf);
03388         /*
03389          * Print radio revision(s).  We check the wireless modes
03390          * to avoid falsely printing revs for inoperable parts.
03391          * Dual-band radio revs are returned in the 5Ghz rev number.
03392          */
03393         ath_hal_getcountrycode(ah, &cc);
03394         modes = ath_hal_getwirelessmodes(ah, cc);
03395         if ((modes & HAL_MODE_DUALBAND) == HAL_MODE_DUALBAND) {
03396                 if (ah->ah_analog5GhzRev && ah->ah_analog2GhzRev)
03397                         printk(" 5ghz radio %d.%d 2ghz radio %d.%d",
03398                                 ah->ah_analog5GhzRev >> 4,
03399                                 ah->ah_analog5GhzRev & 0xf,
03400                                 ah->ah_analog2GhzRev >> 4,
03401                                 ah->ah_analog2GhzRev & 0xf);
03402                 else
03403                         printk(" radio %d.%d", ah->ah_analog5GhzRev >> 4,
03404                                 ah->ah_analog5GhzRev & 0xf);
03405         } else
03406                 printk(" radio %d.%d", ah->ah_analog5GhzRev >> 4,
03407                         ah->ah_analog5GhzRev & 0xf);
03408         printk("\n");
03409         printk("%s: 802.11 address: %s\n",
03410                 dev->name, ether_sprintf(dev->dev_addr));
03411         for (i = 0; i <= WME_AC_VO; i++) {
03412                 struct ath_txq *txq = sc->sc_ac2q[i];
03413                 printk("%s: Use hw queue %u for %s traffic\n",
03414                         dev->name, txq->axq_qnum, acnames[i]);
03415         }
03416 #undef HAL_MODE_DUALBAND
03417 }
03418 
03419 /*
03420  * Static (i.e. global) sysctls.  Note that the hal sysctls
03421  * are located under ours by sharing the setting for DEV_ATH.
03422  */
03423 enum {
03424         DEV_ATH         = 9,                    /* XXX known by hal */
03425 };
03426 
03427 static ctl_table ath_static_sysctls[] = {
03428 #ifdef AR_DEBUG
03429         { .ctl_name     = CTL_AUTO,
03430            .procname    = "debug",
03431           .mode         = 0644,
03432           .data         = &ath_debug,
03433           .maxlen       = sizeof(ath_debug),
03434           .proc_handler = proc_dointvec
03435         },
03436 #endif
03437         { .ctl_name     = CTL_AUTO,
03438           .procname     = "countrycode",
03439           .mode         = 0444,
03440           .data         = &ath_countrycode,
03441           .maxlen       = sizeof(ath_countrycode),
03442           .proc_handler = proc_dointvec
03443         },
03444         { .ctl_name     = CTL_AUTO,
03445           .procname     = "regdomain",
03446           .mode         = 0444,
03447           .data         = &ath_regdomain,
03448           .maxlen       = sizeof(ath_regdomain),
03449           .proc_handler = proc_dointvec
03450         },
03451         { .ctl_name     = CTL_AUTO,
03452           .procname     = "outdoor",
03453           .mode         = 0444,
03454           .data         = &ath_outdoor,
03455           .maxlen       = sizeof(ath_outdoor),
03456           .proc_handler = proc_dointvec
03457         },
03458         { .ctl_name     = CTL_AUTO,
03459           .procname     = "xchanmode",
03460           .mode         = 0444,
03461           .data         = &ath_xchanmode,
03462           .maxlen       = sizeof(ath_xchanmode),
03463           .proc_handler = proc_dointvec
03464         },
03465         { .ctl_name     = CTL_AUTO,
03466           .procname     = "dwelltime",
03467           .mode         = 0644,
03468           .data         = &ath_dwelltime,
03469           .maxlen       = sizeof(ath_dwelltime),
03470           .extra1       = &mindwelltime,
03471           .extra2       = &maxint,
03472           .proc_handler = proc_dointvec_minmax
03473         },
03474         { .ctl_name     = CTL_AUTO,
03475           .procname     = "calibrate",
03476           .mode         = 0644,
03477           .data         = &ath_calinterval,
03478           .maxlen       = sizeof(ath_calinterval),
03479           .extra1       = &mincalibrate,
03480           .extra2       = &maxint,
03481           .proc_handler = proc_dointvec_minmax
03482         },
03483         { 0 }
03484 };
03485 static ctl_table ath_ath_table[] = {
03486         { .ctl_name     = DEV_ATH,
03487           .procname     = "ath",
03488           .mode         = 0555,
03489           .child        = ath_static_sysctls
03490         }, { 0 }
03491 };
03492 static ctl_table ath_root_table[] = {
03493         { .ctl_name     = CTL_DEV,
03494           .procname     = "dev",
03495           .mode         = 0555,
03496           .child        = ath_ath_table
03497         }, { 0 }
03498 };
03499 static struct ctl_table_header *ath_sysctl_header;
03500 
03501 void
03502 ath_sysctl_register(void)
03503 {
03504         static int initialized = 0;
03505 
03506         if (!initialized) {
03507                 ath_sysctl_header =
03508                         register_sysctl_table(ath_root_table, 1);
03509                 initialized = 1;
03510         }
03511 }
03512 
03513 void
03514 ath_sysctl_unregister(void)
03515 {
03516         if (ath_sysctl_header)
03517                 unregister_sysctl_table(ath_sysctl_header);
03518 }
03519 #endif /* CONFIG_SYSCTL */

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