ath5k.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
00003  * Copyright (c) 2004-2005 Atheros Communications, Inc.
00004  * Copyright (c) 2006 Devicescape Software, Inc.
00005  * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
00006  * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
00007  *
00008  * Modified for gPXE, July 2009, by Joshua Oreman <oremanj@rwcr.net>
00009  * Original from Linux kernel 2.6.30.
00010  *
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  */
00045 
00046 FILE_LICENCE ( BSD3 );
00047 
00048 #include <stdlib.h>
00049 #include <gpxe/malloc.h>
00050 #include <gpxe/timer.h>
00051 #include <gpxe/netdevice.h>
00052 #include <gpxe/pci.h>
00053 #include <gpxe/pci_io.h>
00054 
00055 #include "base.h"
00056 #include "reg.h"
00057 
00058 #define ATH5K_CALIB_INTERVAL    10 /* Calibrate PHY every 10 seconds */
00059 #define ATH5K_RETRIES           4  /* Number of times to retry packet sends */
00060 #define ATH5K_DESC_ALIGN        16 /* Alignment for TX/RX descriptors */
00061 
00062 /******************\
00063 * Internal defines *
00064 \******************/
00065 
00066 /* Known PCI ids */
00067 static struct pci_device_id ath5k_nics[] = {
00068         PCI_ROM(0x168c, 0x0207, "ath5210e", "Atheros 5210 early", AR5K_AR5210),
00069         PCI_ROM(0x168c, 0x0007, "ath5210", "Atheros 5210", AR5K_AR5210),
00070         PCI_ROM(0x168c, 0x0011, "ath5311", "Atheros 5311 (AHB)", AR5K_AR5211),
00071         PCI_ROM(0x168c, 0x0012, "ath5211", "Atheros 5211", AR5K_AR5211),
00072         PCI_ROM(0x168c, 0x0013, "ath5212", "Atheros 5212", AR5K_AR5212),
00073         PCI_ROM(0xa727, 0x0013, "ath5212c","3com Ath 5212", AR5K_AR5212),
00074         PCI_ROM(0x10b7, 0x0013, "rdag675", "3com 3CRDAG675", AR5K_AR5212),
00075         PCI_ROM(0x168c, 0x1014, "ath5212m", "Ath 5212 miniPCI", AR5K_AR5212),
00076         PCI_ROM(0x168c, 0x0014, "ath5212x14", "Atheros 5212 x14", AR5K_AR5212),
00077         PCI_ROM(0x168c, 0x0015, "ath5212x15", "Atheros 5212 x15", AR5K_AR5212),
00078         PCI_ROM(0x168c, 0x0016, "ath5212x16", "Atheros 5212 x16", AR5K_AR5212),
00079         PCI_ROM(0x168c, 0x0017, "ath5212x17", "Atheros 5212 x17", AR5K_AR5212),
00080         PCI_ROM(0x168c, 0x0018, "ath5212x18", "Atheros 5212 x18", AR5K_AR5212),
00081         PCI_ROM(0x168c, 0x0019, "ath5212x19", "Atheros 5212 x19", AR5K_AR5212),
00082         PCI_ROM(0x168c, 0x001a, "ath2413", "Atheros 2413 Griffin", AR5K_AR5212),
00083         PCI_ROM(0x168c, 0x001b, "ath5413", "Atheros 5413 Eagle", AR5K_AR5212),
00084         PCI_ROM(0x168c, 0x001c, "ath5212e", "Atheros 5212 PCI-E", AR5K_AR5212),
00085         PCI_ROM(0x168c, 0x001d, "ath2417", "Atheros 2417 Nala", AR5K_AR5212),
00086 };
00087 
00088 /* Known SREVs */
00089 static const struct ath5k_srev_name srev_names[] = {
00090         { "5210",       AR5K_VERSION_MAC,       AR5K_SREV_AR5210 },
00091         { "5311",       AR5K_VERSION_MAC,       AR5K_SREV_AR5311 },
00092         { "5311A",      AR5K_VERSION_MAC,       AR5K_SREV_AR5311A },
00093         { "5311B",      AR5K_VERSION_MAC,       AR5K_SREV_AR5311B },
00094         { "5211",       AR5K_VERSION_MAC,       AR5K_SREV_AR5211 },
00095         { "5212",       AR5K_VERSION_MAC,       AR5K_SREV_AR5212 },
00096         { "5213",       AR5K_VERSION_MAC,       AR5K_SREV_AR5213 },
00097         { "5213A",      AR5K_VERSION_MAC,       AR5K_SREV_AR5213A },
00098         { "2413",       AR5K_VERSION_MAC,       AR5K_SREV_AR2413 },
00099         { "2414",       AR5K_VERSION_MAC,       AR5K_SREV_AR2414 },
00100         { "5424",       AR5K_VERSION_MAC,       AR5K_SREV_AR5424 },
00101         { "5413",       AR5K_VERSION_MAC,       AR5K_SREV_AR5413 },
00102         { "5414",       AR5K_VERSION_MAC,       AR5K_SREV_AR5414 },
00103         { "2415",       AR5K_VERSION_MAC,       AR5K_SREV_AR2415 },
00104         { "5416",       AR5K_VERSION_MAC,       AR5K_SREV_AR5416 },
00105         { "5418",       AR5K_VERSION_MAC,       AR5K_SREV_AR5418 },
00106         { "2425",       AR5K_VERSION_MAC,       AR5K_SREV_AR2425 },
00107         { "2417",       AR5K_VERSION_MAC,       AR5K_SREV_AR2417 },
00108         { "xxxxx",      AR5K_VERSION_MAC,       AR5K_SREV_UNKNOWN },
00109         { "5110",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5110 },
00110         { "5111",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5111 },
00111         { "5111A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5111A },
00112         { "2111",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2111 },
00113         { "5112",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112 },
00114         { "5112A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112A },
00115         { "5112B",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112B },
00116         { "2112",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112 },
00117         { "2112A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112A },
00118         { "2112B",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112B },
00119         { "2413",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2413 },
00120         { "5413",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5413 },
00121         { "2316",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2316 },
00122         { "2317",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2317 },
00123         { "5424",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5424 },
00124         { "5133",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5133 },
00125         { "xxxxx",      AR5K_VERSION_RAD,       AR5K_SREV_UNKNOWN },
00126 };
00127 
00128 #define ATH5K_SPMBL_NO   1
00129 #define ATH5K_SPMBL_YES  2
00130 #define ATH5K_SPMBL_BOTH 3
00131 
00132 static const struct {
00133         u16 bitrate;
00134         u8 short_pmbl;
00135         u8 hw_code;
00136 } ath5k_rates[] = {
00137         { 10, ATH5K_SPMBL_BOTH, ATH5K_RATE_CODE_1M },
00138         { 20, ATH5K_SPMBL_NO, ATH5K_RATE_CODE_2M },
00139         { 55, ATH5K_SPMBL_NO, ATH5K_RATE_CODE_5_5M },
00140         { 110, ATH5K_SPMBL_NO, ATH5K_RATE_CODE_11M },
00141         { 60, ATH5K_SPMBL_BOTH, ATH5K_RATE_CODE_6M },
00142         { 90, ATH5K_SPMBL_BOTH, ATH5K_RATE_CODE_9M },
00143         { 120, ATH5K_SPMBL_BOTH, ATH5K_RATE_CODE_12M },
00144         { 180, ATH5K_SPMBL_BOTH, ATH5K_RATE_CODE_18M },
00145         { 240, ATH5K_SPMBL_BOTH, ATH5K_RATE_CODE_24M },
00146         { 360, ATH5K_SPMBL_BOTH, ATH5K_RATE_CODE_36M },
00147         { 480, ATH5K_SPMBL_BOTH, ATH5K_RATE_CODE_48M },
00148         { 540, ATH5K_SPMBL_BOTH, ATH5K_RATE_CODE_54M },
00149         { 20, ATH5K_SPMBL_YES, ATH5K_RATE_CODE_2M | AR5K_SET_SHORT_PREAMBLE },
00150         { 55, ATH5K_SPMBL_YES, ATH5K_RATE_CODE_5_5M | AR5K_SET_SHORT_PREAMBLE },
00151         { 110, ATH5K_SPMBL_YES, ATH5K_RATE_CODE_11M | AR5K_SET_SHORT_PREAMBLE },
00152         { 0, 0, 0 },
00153 };
00154 
00155 #define ATH5K_NR_RATES 15
00156 
00157 /*
00158  * Prototypes - PCI stack related functions
00159  */
00160 static int              ath5k_probe(struct pci_device *pdev,
00161                                     const struct pci_device_id *id);
00162 static void             ath5k_remove(struct pci_device *pdev);
00163 
00164 struct pci_driver ath5k_pci_driver __pci_driver = {
00165         .ids            = ath5k_nics,
00166         .id_count       = sizeof(ath5k_nics) / sizeof(ath5k_nics[0]),
00167         .probe          = ath5k_probe,
00168         .remove         = ath5k_remove,
00169 };
00170 
00171 
00172 
00173 /*
00174  * Prototypes - MAC 802.11 stack related functions
00175  */
00176 static int ath5k_tx(struct net80211_device *dev, struct io_buffer *skb);
00177 static int ath5k_reset(struct ath5k_softc *sc, struct net80211_channel *chan);
00178 static int ath5k_reset_wake(struct ath5k_softc *sc);
00179 static int ath5k_start(struct net80211_device *dev);
00180 static void ath5k_stop(struct net80211_device *dev);
00181 static int ath5k_config(struct net80211_device *dev, int changed);
00182 static void ath5k_poll(struct net80211_device *dev);
00183 static void ath5k_irq(struct net80211_device *dev, int enable);
00184 
00185 static struct net80211_device_operations ath5k_ops = {
00186         .open           = ath5k_start,
00187         .close          = ath5k_stop,
00188         .transmit       = ath5k_tx,
00189         .poll           = ath5k_poll,
00190         .irq            = ath5k_irq,
00191         .config         = ath5k_config,
00192 };
00193 
00194 /*
00195  * Prototypes - Internal functions
00196  */
00197 /* Attach detach */
00198 static int      ath5k_attach(struct net80211_device *dev);
00199 static void     ath5k_detach(struct net80211_device *dev);
00200 /* Channel/mode setup */
00201 static unsigned int ath5k_copy_channels(struct ath5k_hw *ah,
00202                                 struct net80211_channel *channels,
00203                                 unsigned int mode,
00204                                 unsigned int max);
00205 static int      ath5k_setup_bands(struct net80211_device *dev);
00206 static int      ath5k_chan_set(struct ath5k_softc *sc,
00207                                 struct net80211_channel *chan);
00208 static void     ath5k_setcurmode(struct ath5k_softc *sc,
00209                                 unsigned int mode);
00210 static void     ath5k_mode_setup(struct ath5k_softc *sc);
00211 
00212 /* Descriptor setup */
00213 static int      ath5k_desc_alloc(struct ath5k_softc *sc);
00214 static void     ath5k_desc_free(struct ath5k_softc *sc);
00215 /* Buffers setup */
00216 static int      ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf);
00217 static int      ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf);
00218 
00219 static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
00220                                     struct ath5k_buf *bf)
00221 {
00222         if (!bf->iob)
00223                 return;
00224 
00225         net80211_tx_complete(sc->dev, bf->iob, 0, ECANCELED);
00226         bf->iob = NULL;
00227 }
00228 
00229 static inline void ath5k_rxbuf_free(struct ath5k_softc *sc __unused,
00230                                     struct ath5k_buf *bf)
00231 {
00232         free_iob(bf->iob);
00233         bf->iob = NULL;
00234 }
00235 
00236 /* Queues setup */
00237 static int      ath5k_txq_setup(struct ath5k_softc *sc,
00238                                            int qtype, int subtype);
00239 static void     ath5k_txq_drainq(struct ath5k_softc *sc,
00240                                  struct ath5k_txq *txq);
00241 static void     ath5k_txq_cleanup(struct ath5k_softc *sc);
00242 static void     ath5k_txq_release(struct ath5k_softc *sc);
00243 /* Rx handling */
00244 static int      ath5k_rx_start(struct ath5k_softc *sc);
00245 static void     ath5k_rx_stop(struct ath5k_softc *sc);
00246 /* Tx handling */
00247 static void     ath5k_tx_processq(struct ath5k_softc *sc,
00248                                   struct ath5k_txq *txq);
00249 
00250 /* Interrupt handling */
00251 static int      ath5k_init(struct ath5k_softc *sc);
00252 static int      ath5k_stop_hw(struct ath5k_softc *sc);
00253 
00254 static void     ath5k_calibrate(struct ath5k_softc *sc);
00255 
00256 /* Filter */
00257 static void     ath5k_configure_filter(struct ath5k_softc *sc);
00258 
00259 /********************\
00260 * PCI Initialization *
00261 \********************/
00262 
00263 #if DBGLVL_MAX
00264 static const char *
00265 ath5k_chip_name(enum ath5k_srev_type type, u16 val)
00266 {
00267         const char *name = "xxxxx";
00268         unsigned int i;
00269 
00270         for (i = 0; i < ARRAY_SIZE(srev_names); i++) {
00271                 if (srev_names[i].sr_type != type)
00272                         continue;
00273 
00274                 if ((val & 0xf0) == srev_names[i].sr_val)
00275                         name = srev_names[i].sr_name;
00276 
00277                 if ((val & 0xff) == srev_names[i].sr_val) {
00278                         name = srev_names[i].sr_name;
00279                         break;
00280                 }
00281         }
00282 
00283         return name;
00284 }
00285 #endif
00286 
00287 static int ath5k_probe(struct pci_device *pdev,
00288                        const struct pci_device_id *id)
00289 {
00290         void *mem;
00291         struct ath5k_softc *sc;
00292         struct net80211_device *dev;
00293         int ret;
00294         u8 csz;
00295 
00296         adjust_pci_device(pdev);
00297 
00298         /*
00299          * Cache line size is used to size and align various
00300          * structures used to communicate with the hardware.
00301          */
00302         pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
00303         if (csz == 0) {
00304                 /*
00305                  * We must have this setup properly for rx buffer
00306                  * DMA to work so force a reasonable value here if it
00307                  * comes up zero.
00308                  */
00309                 csz = 16;
00310                 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
00311         }
00312         /*
00313          * The default setting of latency timer yields poor results,
00314          * set it to the value used by other systems.  It may be worth
00315          * tweaking this setting more.
00316          */
00317         pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
00318 
00319         /*
00320          * Disable the RETRY_TIMEOUT register (0x41) to keep
00321          * PCI Tx retries from interfering with C3 CPU state.
00322          */
00323         pci_write_config_byte(pdev, 0x41, 0);
00324 
00325         mem = ioremap(pdev->membase, 0x10000);
00326         if (!mem) {
00327                 DBG("ath5k: cannot remap PCI memory region\n");
00328                 ret = -EIO;
00329                 goto err;
00330         }
00331 
00332         /*
00333          * Allocate dev (net80211 main struct)
00334          * and dev->priv (driver private data)
00335          */
00336         dev = net80211_alloc(sizeof(*sc));
00337         if (!dev) {
00338                 DBG("ath5k: cannot allocate 802.11 device\n");
00339                 ret = -ENOMEM;
00340                 goto err_map;
00341         }
00342 
00343         /* Initialize driver private data */
00344         sc = dev->priv;
00345         sc->dev = dev;
00346         sc->pdev = pdev;
00347 
00348         sc->hwinfo = zalloc(sizeof(*sc->hwinfo));
00349         if (!sc->hwinfo) {
00350                 DBG("ath5k: cannot allocate 802.11 hardware info structure\n");
00351                 ret = -ENOMEM;
00352                 goto err_free;
00353         }
00354 
00355         sc->hwinfo->flags = NET80211_HW_RX_HAS_FCS;
00356         sc->hwinfo->signal_type = NET80211_SIGNAL_DB;
00357         sc->hwinfo->signal_max = 40; /* 35dB should give perfect 54Mbps */
00358         sc->hwinfo->channel_change_time = 5000;
00359 
00360         /* Avoid working with the device until setup is complete */
00361         sc->status |= ATH_STAT_INVALID;
00362 
00363         sc->iobase = mem;
00364         sc->cachelsz = csz * 4; /* convert to bytes */
00365 
00366         DBG("ath5k: register base at %p (%08lx)\n", sc->iobase, pdev->membase);
00367         DBG("ath5k: cache line size %d\n", sc->cachelsz);
00368 
00369         /* Set private data */
00370         pci_set_drvdata(pdev, dev);
00371         dev->netdev->dev = (struct device *)pdev;
00372 
00373         /* Initialize device */
00374         ret = ath5k_hw_attach(sc, id->driver_data, &sc->ah);
00375         if (ret)
00376                 goto err_free_hwinfo;
00377 
00378         /* Finish private driver data initialization */
00379         ret = ath5k_attach(dev);
00380         if (ret)
00381                 goto err_ah;
00382 
00383 #if DBGLVL_MAX
00384         DBG("Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
00385             ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),
00386             sc->ah->ah_mac_srev, sc->ah->ah_phy_revision);
00387 
00388         if (!sc->ah->ah_single_chip) {
00389                 /* Single chip radio (!RF5111) */
00390                 if (sc->ah->ah_radio_5ghz_revision &&
00391                     !sc->ah->ah_radio_2ghz_revision) {
00392                         /* No 5GHz support -> report 2GHz radio */
00393                         if (!(sc->ah->ah_capabilities.cap_mode & AR5K_MODE_BIT_11A)) {
00394                                 DBG("RF%s 2GHz radio found (0x%x)\n",
00395                                     ath5k_chip_name(AR5K_VERSION_RAD,
00396                                                     sc->ah->ah_radio_5ghz_revision),
00397                                     sc->ah->ah_radio_5ghz_revision);
00398                         /* No 2GHz support (5110 and some
00399                          * 5Ghz only cards) -> report 5Ghz radio */
00400                         } else if (!(sc->ah->ah_capabilities.cap_mode & AR5K_MODE_BIT_11B)) {
00401                                 DBG("RF%s 5GHz radio found (0x%x)\n",
00402                                     ath5k_chip_name(AR5K_VERSION_RAD,
00403                                                     sc->ah->ah_radio_5ghz_revision),
00404                                     sc->ah->ah_radio_5ghz_revision);
00405                         /* Multiband radio */
00406                         } else {
00407                                 DBG("RF%s multiband radio found (0x%x)\n",
00408                                     ath5k_chip_name(AR5K_VERSION_RAD,
00409                                                     sc->ah->ah_radio_5ghz_revision),
00410                                     sc->ah->ah_radio_5ghz_revision);
00411                         }
00412                 }
00413                 /* Multi chip radio (RF5111 - RF2111) ->
00414                  * report both 2GHz/5GHz radios */
00415                 else if (sc->ah->ah_radio_5ghz_revision &&
00416                          sc->ah->ah_radio_2ghz_revision) {
00417                         DBG("RF%s 5GHz radio found (0x%x)\n",
00418                             ath5k_chip_name(AR5K_VERSION_RAD,
00419                                             sc->ah->ah_radio_5ghz_revision),
00420                             sc->ah->ah_radio_5ghz_revision);
00421                         DBG("RF%s 2GHz radio found (0x%x)\n",
00422                             ath5k_chip_name(AR5K_VERSION_RAD,
00423                                             sc->ah->ah_radio_2ghz_revision),
00424                             sc->ah->ah_radio_2ghz_revision);
00425                 }
00426         }
00427 #endif
00428 
00429         /* Ready to go */
00430         sc->status &= ~ATH_STAT_INVALID;
00431 
00432         return 0;
00433 err_ah:
00434         ath5k_hw_detach(sc->ah);
00435 err_free_hwinfo:
00436         free(sc->hwinfo);
00437 err_free:
00438         net80211_free(dev);
00439 err_map:
00440         iounmap(mem);
00441 err:
00442         return ret;
00443 }
00444 
00445 static void ath5k_remove(struct pci_device *pdev)
00446 {
00447         struct net80211_device *dev = pci_get_drvdata(pdev);
00448         struct ath5k_softc *sc = dev->priv;
00449 
00450         ath5k_detach(dev);
00451         ath5k_hw_detach(sc->ah);
00452         iounmap(sc->iobase);
00453         free(sc->hwinfo);
00454         net80211_free(dev);
00455 }
00456 
00457 
00458 /***********************\
00459 * Driver Initialization *
00460 \***********************/
00461 
00462 static int
00463 ath5k_attach(struct net80211_device *dev)
00464 {
00465         struct ath5k_softc *sc = dev->priv;
00466         struct ath5k_hw *ah = sc->ah;
00467         int ret;
00468 
00469         /*
00470          * Collect the channel list.  The 802.11 layer
00471          * is resposible for filtering this list based
00472          * on settings like the phy mode and regulatory
00473          * domain restrictions.
00474          */
00475         ret = ath5k_setup_bands(dev);
00476         if (ret) {
00477                 DBG("ath5k: can't get channels\n");
00478                 goto err;
00479         }
00480 
00481         /* NB: setup here so ath5k_rate_update is happy */
00482         if (ah->ah_modes & AR5K_MODE_BIT_11A)
00483                 ath5k_setcurmode(sc, AR5K_MODE_11A);
00484         else
00485                 ath5k_setcurmode(sc, AR5K_MODE_11B);
00486 
00487         /*
00488          * Allocate tx+rx descriptors and populate the lists.
00489          */
00490         ret = ath5k_desc_alloc(sc);
00491         if (ret) {
00492                 DBG("ath5k: can't allocate descriptors\n");
00493                 goto err;
00494         }
00495 
00496         /*
00497          * Allocate hardware transmit queues. Note that hw functions
00498          * handle reseting these queues at the needed time.
00499          */
00500         ret = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE);
00501         if (ret) {
00502                 DBG("ath5k: can't setup xmit queue\n");
00503                 goto err_desc;
00504         }
00505 
00506         sc->last_calib_ticks = currticks();
00507 
00508         ret = ath5k_eeprom_read_mac(ah, sc->hwinfo->hwaddr);
00509         if (ret) {
00510                 DBG("ath5k: unable to read address from EEPROM: 0x%04x\n",
00511                     sc->pdev->device);
00512                 goto err_queues;
00513         }
00514 
00515         memset(sc->bssidmask, 0xff, ETH_ALEN);
00516         ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
00517 
00518         ret = net80211_register(sc->dev, &ath5k_ops, sc->hwinfo);
00519         if (ret) {
00520                 DBG("ath5k: can't register ieee80211 hw\n");
00521                 goto err_queues;
00522         }
00523 
00524         return 0;
00525 err_queues:
00526         ath5k_txq_release(sc);
00527 err_desc:
00528         ath5k_desc_free(sc);
00529 err:
00530         return ret;
00531 }
00532 
00533 static void
00534 ath5k_detach(struct net80211_device *dev)
00535 {
00536         struct ath5k_softc *sc = dev->priv;
00537 
00538         net80211_unregister(dev);
00539         ath5k_desc_free(sc);
00540         ath5k_txq_release(sc);
00541 }
00542 
00543 
00544 
00545 
00546 /********************\
00547 * Channel/mode setup *
00548 \********************/
00549 
00550 /*
00551  * Convert IEEE channel number to MHz frequency.
00552  */
00553 static inline short
00554 ath5k_ieee2mhz(short chan)
00555 {
00556         if (chan < 14)
00557                 return 2407 + 5 * chan;
00558         if (chan == 14)
00559                 return 2484;
00560         if (chan < 27)
00561                 return 2212 + 20 * chan;
00562         return 5000 + 5 * chan;
00563 }
00564 
00565 static unsigned int
00566 ath5k_copy_channels(struct ath5k_hw *ah,
00567                     struct net80211_channel *channels,
00568                     unsigned int mode, unsigned int max)
00569 {
00570         unsigned int i, count, size, chfreq, freq, ch;
00571 
00572         if (!(ah->ah_modes & (1 << mode)))
00573                 return 0;
00574 
00575         switch (mode) {
00576         case AR5K_MODE_11A:
00577         case AR5K_MODE_11A_TURBO:
00578                 /* 1..220, but 2GHz frequencies are filtered by check_channel */
00579                 size = 220;
00580                 chfreq = CHANNEL_5GHZ;
00581                 break;
00582         case AR5K_MODE_11B:
00583         case AR5K_MODE_11G:
00584         case AR5K_MODE_11G_TURBO:
00585                 size = 26;
00586                 chfreq = CHANNEL_2GHZ;
00587                 break;
00588         default:
00589                 return 0;
00590         }
00591 
00592         for (i = 0, count = 0; i < size && max > 0; i++) {
00593                 ch = i + 1 ;
00594                 freq = ath5k_ieee2mhz(ch);
00595 
00596                 /* Check if channel is supported by the chipset */
00597                 if (!ath5k_channel_ok(ah, freq, chfreq))
00598                         continue;
00599 
00600                 /* Write channel info and increment counter */
00601                 channels[count].center_freq = freq;
00602                 channels[count].maxpower = 0; /* use regulatory */
00603                 channels[count].band = (chfreq == CHANNEL_2GHZ) ?
00604                         NET80211_BAND_2GHZ : NET80211_BAND_5GHZ;
00605                 switch (mode) {
00606                 case AR5K_MODE_11A:
00607                 case AR5K_MODE_11G:
00608                         channels[count].hw_value = chfreq | CHANNEL_OFDM;
00609                         break;
00610                 case AR5K_MODE_11A_TURBO:
00611                 case AR5K_MODE_11G_TURBO:
00612                         channels[count].hw_value = chfreq |
00613                                 CHANNEL_OFDM | CHANNEL_TURBO;
00614                         break;
00615                 case AR5K_MODE_11B:
00616                         channels[count].hw_value = CHANNEL_B;
00617                 }
00618 
00619                 count++;
00620                 max--;
00621         }
00622 
00623         return count;
00624 }
00625 
00626 static int
00627 ath5k_setup_bands(struct net80211_device *dev)
00628 {
00629         struct ath5k_softc *sc = dev->priv;
00630         struct ath5k_hw *ah = sc->ah;
00631         int max_c, count_c = 0;
00632         int i;
00633         int band;
00634 
00635         max_c = sizeof(sc->hwinfo->channels) / sizeof(sc->hwinfo->channels[0]);
00636 
00637         /* 2GHz band */
00638         if (sc->ah->ah_capabilities.cap_mode & AR5K_MODE_BIT_11G) {
00639                 /* G mode */
00640                 band = NET80211_BAND_2GHZ;
00641                 sc->hwinfo->bands = NET80211_BAND_BIT_2GHZ;
00642                 sc->hwinfo->modes = (NET80211_MODE_G | NET80211_MODE_B);
00643 
00644                 for (i = 0; i < 12; i++)
00645                         sc->hwinfo->rates[band][i] = ath5k_rates[i].bitrate;
00646                 sc->hwinfo->nr_rates[band] = 12;
00647 
00648                 sc->hwinfo->nr_channels =
00649                         ath5k_copy_channels(ah, sc->hwinfo->channels,
00650                                             AR5K_MODE_11G, max_c);
00651                 count_c = sc->hwinfo->nr_channels;
00652                 max_c -= count_c;
00653         } else if (sc->ah->ah_capabilities.cap_mode & AR5K_MODE_BIT_11B) {
00654                 /* B mode */
00655                 band = NET80211_BAND_2GHZ;
00656                 sc->hwinfo->bands = NET80211_BAND_BIT_2GHZ;
00657                 sc->hwinfo->modes = NET80211_MODE_B;
00658 
00659                 for (i = 0; i < 4; i++)
00660                         sc->hwinfo->rates[band][i] = ath5k_rates[i].bitrate;
00661                 sc->hwinfo->nr_rates[band] = 4;
00662 
00663                 sc->hwinfo->nr_channels =
00664                         ath5k_copy_channels(ah, sc->hwinfo->channels,
00665                                             AR5K_MODE_11B, max_c);
00666                 count_c = sc->hwinfo->nr_channels;
00667                 max_c -= count_c;
00668         }
00669 
00670         /* 5GHz band, A mode */
00671         if (sc->ah->ah_capabilities.cap_mode & AR5K_MODE_BIT_11A) {
00672                 band = NET80211_BAND_5GHZ;
00673                 sc->hwinfo->bands |= NET80211_BAND_BIT_5GHZ;
00674                 sc->hwinfo->modes |= NET80211_MODE_A;
00675 
00676                 for (i = 0; i < 8; i++)
00677                         sc->hwinfo->rates[band][i] = ath5k_rates[i+4].bitrate;
00678                 sc->hwinfo->nr_rates[band] = 8;
00679 
00680                 sc->hwinfo->nr_channels =
00681                         ath5k_copy_channels(ah, sc->hwinfo->channels,
00682                                             AR5K_MODE_11B, max_c);
00683                 count_c = sc->hwinfo->nr_channels;
00684                 max_c -= count_c;
00685         }
00686 
00687         return 0;
00688 }
00689 
00690 /*
00691  * Set/change channels.  If the channel is really being changed,
00692  * it's done by reseting the chip.  To accomplish this we must
00693  * first cleanup any pending DMA, then restart stuff after a la
00694  * ath5k_init.
00695  */
00696 static int
00697 ath5k_chan_set(struct ath5k_softc *sc, struct net80211_channel *chan)
00698 {
00699         if (chan->center_freq != sc->curchan->center_freq ||
00700             chan->hw_value != sc->curchan->hw_value) {
00701                 /*
00702                  * To switch channels clear any pending DMA operations;
00703                  * wait long enough for the RX fifo to drain, reset the
00704                  * hardware at the new frequency, and then re-enable
00705                  * the relevant bits of the h/w.
00706                  */
00707                 DBG2("ath5k: resetting for channel change (%d -> %d MHz)\n",
00708                      sc->curchan->center_freq, chan->center_freq);
00709                 return ath5k_reset(sc, chan);
00710         }
00711 
00712         return 0;
00713 }
00714 
00715 static void
00716 ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode)
00717 {
00718         sc->curmode = mode;
00719 
00720         if (mode == AR5K_MODE_11A) {
00721                 sc->curband = NET80211_BAND_5GHZ;
00722         } else {
00723                 sc->curband = NET80211_BAND_2GHZ;
00724         }
00725 }
00726 
00727 static void
00728 ath5k_mode_setup(struct ath5k_softc *sc)
00729 {
00730         struct ath5k_hw *ah = sc->ah;
00731         u32 rfilt;
00732 
00733         /* configure rx filter */
00734         rfilt = sc->filter_flags;
00735         ath5k_hw_set_rx_filter(ah, rfilt);
00736 
00737         if (ath5k_hw_hasbssidmask(ah))
00738                 ath5k_hw_set_bssid_mask(ah, sc->bssidmask);
00739 
00740         /* configure operational mode */
00741         ath5k_hw_set_opmode(ah);
00742 
00743         ath5k_hw_set_mcast_filter(ah, 0, 0);
00744 }
00745 
00746 static inline int
00747 ath5k_hw_rix_to_bitrate(int hw_rix)
00748 {
00749         int i;
00750 
00751         for (i = 0; i < ATH5K_NR_RATES; i++) {
00752                 if (ath5k_rates[i].hw_code == hw_rix)
00753                         return ath5k_rates[i].bitrate;
00754         }
00755 
00756         DBG("ath5k: invalid rix %02x\n", hw_rix);
00757         return 10;              /* use lowest rate */
00758 }
00759 
00760 int ath5k_bitrate_to_hw_rix(int bitrate)
00761 {
00762         int i;
00763 
00764         for (i = 0; i < ATH5K_NR_RATES; i++) {
00765                 if (ath5k_rates[i].bitrate == bitrate)
00766                         return ath5k_rates[i].hw_code;
00767         }
00768 
00769         DBG("ath5k: invalid bitrate %d\n", bitrate);
00770         return ATH5K_RATE_CODE_1M; /* use lowest rate */
00771 }
00772 
00773 /***************\
00774 * Buffers setup *
00775 \***************/
00776 
00777 static struct io_buffer *
00778 ath5k_rx_iob_alloc(struct ath5k_softc *sc, u32 *iob_addr)
00779 {
00780         struct io_buffer *iob;
00781         unsigned int off;
00782 
00783         /*
00784          * Allocate buffer with headroom_needed space for the
00785          * fake physical layer header at the start.
00786          */
00787         iob = alloc_iob(sc->rxbufsize + sc->cachelsz - 1);
00788 
00789         if (!iob) {
00790                 DBG("ath5k: can't alloc iobuf of size %d\n",
00791                     sc->rxbufsize + sc->cachelsz - 1);
00792                 return NULL;
00793         }
00794 
00795         *iob_addr = virt_to_bus(iob->data);
00796 
00797         /*
00798          * Cache-line-align.  This is important (for the
00799          * 5210 at least) as not doing so causes bogus data
00800          * in rx'd frames.
00801          */
00802         off = *iob_addr % sc->cachelsz;
00803         if (off != 0) {
00804                 iob_reserve(iob, sc->cachelsz - off);
00805                 *iob_addr += sc->cachelsz - off;
00806         }
00807 
00808         return iob;
00809 }
00810 
00811 static int
00812 ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
00813 {
00814         struct ath5k_hw *ah = sc->ah;
00815         struct io_buffer *iob = bf->iob;
00816         struct ath5k_desc *ds;
00817 
00818         if (!iob) {
00819                 iob = ath5k_rx_iob_alloc(sc, &bf->iobaddr);
00820                 if (!iob)
00821                         return -ENOMEM;
00822                 bf->iob = iob;
00823         }
00824 
00825         /*
00826          * Setup descriptors.  For receive we always terminate
00827          * the descriptor list with a self-linked entry so we'll
00828          * not get overrun under high load (as can happen with a
00829          * 5212 when ANI processing enables PHY error frames).
00830          *
00831          * To insure the last descriptor is self-linked we create
00832          * each descriptor as self-linked and add it to the end.  As
00833          * each additional descriptor is added the previous self-linked
00834          * entry is ``fixed'' naturally.  This should be safe even
00835          * if DMA is happening.  When processing RX interrupts we
00836          * never remove/process the last, self-linked, entry on the
00837          * descriptor list.  This insures the hardware always has
00838          * someplace to write a new frame.
00839          */
00840         ds = bf->desc;
00841         ds->ds_link = bf->daddr;        /* link to self */
00842         ds->ds_data = bf->iobaddr;
00843         if (ah->ah_setup_rx_desc(ah, ds,
00844                                  iob_tailroom(iob),     /* buffer size */
00845                                  0) != 0) {
00846                 DBG("ath5k: error setting up RX descriptor for %d bytes\n", iob_tailroom(iob));
00847                 return -EINVAL;
00848         }
00849 
00850         if (sc->rxlink != NULL)
00851                 *sc->rxlink = bf->daddr;
00852         sc->rxlink = &ds->ds_link;
00853         return 0;
00854 }
00855 
00856 static int
00857 ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
00858 {
00859         struct ath5k_hw *ah = sc->ah;
00860         struct ath5k_txq *txq = &sc->txq;
00861         struct ath5k_desc *ds = bf->desc;
00862         struct io_buffer *iob = bf->iob;
00863         unsigned int pktlen, flags;
00864         int ret;
00865         u16 duration = 0;
00866         u16 cts_rate = 0;
00867 
00868         flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
00869         bf->iobaddr = virt_to_bus(iob->data);
00870         pktlen = iob_len(iob);
00871 
00872         /* FIXME: If we are in g mode and rate is a CCK rate
00873          * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
00874          * from tx power (value is in dB units already) */
00875         if (sc->dev->phy_flags & NET80211_PHY_USE_PROTECTION) {
00876                 struct net80211_device *dev = sc->dev;
00877 
00878                 flags |= AR5K_TXDESC_CTSENA;
00879                 cts_rate = sc->hw_rtscts_rate;
00880                 duration = net80211_cts_duration(dev, pktlen);
00881         }
00882         ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
00883                                    IEEE80211_TYP_FRAME_HEADER_LEN,
00884                                    AR5K_PKT_TYPE_NORMAL, sc->power_level * 2,
00885                                    sc->hw_rate, ATH5K_RETRIES,
00886                                    AR5K_TXKEYIX_INVALID, 0, flags,
00887                                    cts_rate, duration);
00888         if (ret)
00889                 return ret;
00890 
00891         ds->ds_link = 0;
00892         ds->ds_data = bf->iobaddr;
00893 
00894         list_add_tail(&bf->list, &txq->q);
00895         if (txq->link == NULL) /* is this first packet? */
00896                 ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr);
00897         else /* no, so only link it */
00898                 *txq->link = bf->daddr;
00899 
00900         txq->link = &ds->ds_link;
00901         ath5k_hw_start_tx_dma(ah, txq->qnum);
00902         mb();
00903 
00904         return 0;
00905 }
00906 
00907 /*******************\
00908 * Descriptors setup *
00909 \*******************/
00910 
00911 static int
00912 ath5k_desc_alloc(struct ath5k_softc *sc)
00913 {
00914         struct ath5k_desc *ds;
00915         struct ath5k_buf *bf;
00916         u32 da;
00917         unsigned int i;
00918         int ret;
00919 
00920         /* allocate descriptors */
00921         sc->desc_len = sizeof(struct ath5k_desc) * (ATH_TXBUF + ATH_RXBUF + 1);
00922         sc->desc = malloc_dma(sc->desc_len, ATH5K_DESC_ALIGN);
00923         if (sc->desc == NULL) {
00924                 DBG("ath5k: can't allocate descriptors\n");
00925                 ret = -ENOMEM;
00926                 goto err;
00927         }
00928         memset(sc->desc, 0, sc->desc_len);
00929         sc->desc_daddr = virt_to_bus(sc->desc);
00930 
00931         ds = sc->desc;
00932         da = sc->desc_daddr;
00933 
00934         bf = calloc(ATH_TXBUF + ATH_RXBUF + 1, sizeof(struct ath5k_buf));
00935         if (bf == NULL) {
00936                 DBG("ath5k: can't allocate buffer pointers\n");
00937                 ret = -ENOMEM;
00938                 goto err_free;
00939         }
00940         sc->bufptr = bf;
00941 
00942         INIT_LIST_HEAD(&sc->rxbuf);
00943         for (i = 0; i < ATH_RXBUF; i++, bf++, ds++, da += sizeof(*ds)) {
00944                 bf->desc = ds;
00945                 bf->daddr = da;
00946                 list_add_tail(&bf->list, &sc->rxbuf);
00947         }
00948 
00949         INIT_LIST_HEAD(&sc->txbuf);
00950         sc->txbuf_len = ATH_TXBUF;
00951         for (i = 0; i < ATH_TXBUF; i++, bf++, ds++, da += sizeof(*ds)) {
00952                 bf->desc = ds;
00953                 bf->daddr = da;
00954                 list_add_tail(&bf->list, &sc->txbuf);
00955         }
00956 
00957         return 0;
00958 
00959 err_free:
00960         free_dma(sc->desc, sc->desc_len);
00961 err:
00962         sc->desc = NULL;
00963         return ret;
00964 }
00965 
00966 static void
00967 ath5k_desc_free(struct ath5k_softc *sc)
00968 {
00969         struct ath5k_buf *bf;
00970 
00971         list_for_each_entry(bf, &sc->txbuf, list)
00972                 ath5k_txbuf_free(sc, bf);
00973         list_for_each_entry(bf, &sc->rxbuf, list)
00974                 ath5k_rxbuf_free(sc, bf);
00975 
00976         /* Free memory associated with all descriptors */
00977         free_dma(sc->desc, sc->desc_len);
00978 
00979         free(sc->bufptr);
00980         sc->bufptr = NULL;
00981 }
00982 
00983 
00984 
00985 
00986 
00987 /**************\
00988 * Queues setup *
00989 \**************/
00990 
00991 static int
00992 ath5k_txq_setup(struct ath5k_softc *sc, int qtype, int subtype)
00993 {
00994         struct ath5k_hw *ah = sc->ah;
00995         struct ath5k_txq *txq;
00996         struct ath5k_txq_info qi = {
00997                 .tqi_subtype = subtype,
00998                 .tqi_aifs = AR5K_TXQ_USEDEFAULT,
00999                 .tqi_cw_min = AR5K_TXQ_USEDEFAULT,
01000                 .tqi_cw_max = AR5K_TXQ_USEDEFAULT
01001         };
01002         int qnum;
01003 
01004         /*
01005          * Enable interrupts only for EOL and DESC conditions.
01006          * We mark tx descriptors to receive a DESC interrupt
01007          * when a tx queue gets deep; otherwise waiting for the
01008          * EOL to reap descriptors.  Note that this is done to
01009          * reduce interrupt load and this only defers reaping
01010          * descriptors, never transmitting frames.  Aside from
01011          * reducing interrupts this also permits more concurrency.
01012          * The only potential downside is if the tx queue backs
01013          * up in which case the top half of the kernel may backup
01014          * due to a lack of tx descriptors.
01015          */
01016         qi.tqi_flags = AR5K_TXQ_FLAG_TXEOLINT_ENABLE |
01017                                 AR5K_TXQ_FLAG_TXDESCINT_ENABLE;
01018         qnum = ath5k_hw_setup_tx_queue(ah, qtype, &qi);
01019         if (qnum < 0) {
01020                 DBG("ath5k: can't set up a TX queue\n");
01021                 return -EIO;
01022         }
01023 
01024         txq = &sc->txq;
01025         if (!txq->setup) {
01026                 txq->qnum = qnum;
01027                 txq->link = NULL;
01028                 INIT_LIST_HEAD(&txq->q);
01029                 txq->setup = 1;
01030         }
01031         return 0;
01032 }
01033 
01034 static void
01035 ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)
01036 {
01037         struct ath5k_buf *bf, *bf0;
01038 
01039         list_for_each_entry_safe(bf, bf0, &txq->q, list) {
01040                 ath5k_txbuf_free(sc, bf);
01041 
01042                 list_del(&bf->list);
01043                 list_add_tail(&bf->list, &sc->txbuf);
01044                 sc->txbuf_len++;
01045         }
01046         txq->link = NULL;
01047 }
01048 
01049 /*
01050  * Drain the transmit queues and reclaim resources.
01051  */
01052 static void
01053 ath5k_txq_cleanup(struct ath5k_softc *sc)
01054 {
01055         struct ath5k_hw *ah = sc->ah;
01056 
01057         if (!(sc->status & ATH_STAT_INVALID)) {
01058                 /* don't touch the hardware if marked invalid */
01059                 if (sc->txq.setup) {
01060                         ath5k_hw_stop_tx_dma(ah, sc->txq.qnum);
01061                         DBG("ath5k: txq [%d] %x, link %p\n",
01062                             sc->txq.qnum,
01063                             ath5k_hw_get_txdp(ah, sc->txq.qnum),
01064                             sc->txq.link);
01065                 }
01066         }
01067 
01068         if (sc->txq.setup)
01069                 ath5k_txq_drainq(sc, &sc->txq);
01070 }
01071 
01072 static void
01073 ath5k_txq_release(struct ath5k_softc *sc)
01074 {
01075         if (sc->txq.setup) {
01076                 ath5k_hw_release_tx_queue(sc->ah);
01077                 sc->txq.setup = 0;
01078         }
01079 }
01080 
01081 
01082 
01083 
01084 /*************\
01085 * RX Handling *
01086 \*************/
01087 
01088 /*
01089  * Enable the receive h/w following a reset.
01090  */
01091 static int
01092 ath5k_rx_start(struct ath5k_softc *sc)
01093 {
01094         struct ath5k_hw *ah = sc->ah;
01095         struct ath5k_buf *bf;
01096         int ret;
01097 
01098         sc->rxbufsize = IEEE80211_MAX_LEN;
01099         if (sc->rxbufsize % sc->cachelsz != 0)
01100                 sc->rxbufsize += sc->cachelsz - (sc->rxbufsize % sc->cachelsz);
01101 
01102         sc->rxlink = NULL;
01103 
01104         list_for_each_entry(bf, &sc->rxbuf, list) {
01105                 ret = ath5k_rxbuf_setup(sc, bf);
01106                 if (ret != 0)
01107                         return ret;
01108         }
01109 
01110         bf = list_entry(sc->rxbuf.next, struct ath5k_buf, list);
01111 
01112         ath5k_hw_set_rxdp(ah, bf->daddr);
01113         ath5k_hw_start_rx_dma(ah);      /* enable recv descriptors */
01114         ath5k_mode_setup(sc);           /* set filters, etc. */
01115         ath5k_hw_start_rx_pcu(ah);      /* re-enable PCU/DMA engine */
01116 
01117         return 0;
01118 }
01119 
01120 /*
01121  * Disable the receive h/w in preparation for a reset.
01122  */
01123 static void
01124 ath5k_rx_stop(struct ath5k_softc *sc)
01125 {
01126         struct ath5k_hw *ah = sc->ah;
01127 
01128         ath5k_hw_stop_rx_pcu(ah);       /* disable PCU */
01129         ath5k_hw_set_rx_filter(ah, 0);  /* clear recv filter */
01130         ath5k_hw_stop_rx_dma(ah);       /* disable DMA engine */
01131 
01132         sc->rxlink = NULL;              /* just in case */
01133 }
01134 
01135 static void
01136 ath5k_handle_rx(struct ath5k_softc *sc)
01137 {
01138         struct ath5k_rx_status rs;
01139         struct io_buffer *iob, *next_iob;
01140         u32 next_iob_addr;
01141         struct ath5k_buf *bf, *bf_last;
01142         struct ath5k_desc *ds;
01143         int ret;
01144 
01145         memset(&rs, 0, sizeof(rs));
01146 
01147         if (list_empty(&sc->rxbuf)) {
01148                 DBG("ath5k: empty rx buf pool\n");
01149                 return;
01150         }
01151 
01152         bf_last = list_entry(sc->rxbuf.prev, struct ath5k_buf, list);
01153 
01154         do {
01155                 bf = list_entry(sc->rxbuf.next, struct ath5k_buf, list);
01156                 assert(bf->iob != NULL);
01157                 iob = bf->iob;
01158                 ds = bf->desc;
01159 
01160                 /*
01161                  * last buffer must not be freed to ensure proper hardware
01162                  * function. When the hardware finishes also a packet next to
01163                  * it, we are sure, it doesn't use it anymore and we can go on.
01164                  */
01165                 if (bf_last == bf)
01166                         bf->flags |= 1;
01167                 if (bf->flags) {
01168                         struct ath5k_buf *bf_next = list_entry(bf->list.next,
01169                                         struct ath5k_buf, list);
01170                         ret = sc->ah->ah_proc_rx_desc(sc->ah, bf_next->desc,
01171                                         &rs);
01172                         if (ret)
01173                                 break;
01174                         bf->flags &= ~1;
01175                         /* skip the overwritten one (even status is martian) */
01176                         goto next;
01177                 }
01178 
01179                 ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs);
01180                 if (ret) {
01181                         if (ret != -EINPROGRESS) {
01182                                 DBG("ath5k: error in processing rx desc: %s\n",
01183                                     strerror(ret));
01184                                 net80211_rx_err(sc->dev, NULL, -ret);
01185                         } else {
01186                                 /* normal return, reached end of
01187                                    available descriptors */
01188                         }
01189                         return;
01190                 }
01191 
01192                 if (rs.rs_more) {
01193                         DBG("ath5k: unsupported fragmented rx\n");
01194                         goto next;
01195                 }
01196 
01197                 if (rs.rs_status) {
01198                         if (rs.rs_status & AR5K_RXERR_PHY) {
01199                                 /* These are uncommon, and may indicate a real problem. */
01200                                 net80211_rx_err(sc->dev, NULL, EIO);
01201                                 goto next;
01202                         }
01203                         if (rs.rs_status & AR5K_RXERR_CRC) {
01204                                 /* These occur *all the time*. */
01205                                 goto next;
01206                         }
01207                         if (rs.rs_status & AR5K_RXERR_DECRYPT) {
01208                                 /*
01209                                  * Decrypt error.  If the error occurred
01210                                  * because there was no hardware key, then
01211                                  * let the frame through so the upper layers
01212                                  * can process it.  This is necessary for 5210
01213                                  * parts which have no way to setup a ``clear''
01214                                  * key cache entry.
01215                                  *
01216                                  * XXX do key cache faulting
01217                                  */
01218                                 if (rs.rs_keyix == AR5K_RXKEYIX_INVALID &&
01219                                     !(rs.rs_status & AR5K_RXERR_CRC))
01220                                         goto accept;
01221                         }
01222 
01223                         /* any other error, unhandled */
01224                         DBG("ath5k: packet rx status %x\n", rs.rs_status);
01225                         goto next;
01226                 }
01227 accept:
01228                 next_iob = ath5k_rx_iob_alloc(sc, &next_iob_addr);
01229 
01230                 /*
01231                  * If we can't replace bf->iob with a new iob under memory
01232                  * pressure, just skip this packet
01233                  */
01234                 if (!next_iob) {
01235                         DBG("ath5k: dropping packet under memory pressure\n");
01236                         goto next;
01237                 }
01238 
01239                 iob_put(iob, rs.rs_datalen);
01240 
01241                 /* The MAC header is padded to have 32-bit boundary if the
01242                  * packet payload is non-zero. However, gPXE only
01243                  * supports standard 802.11 packets with 24-byte
01244                  * header, so no padding correction should be needed.
01245                  */
01246 
01247                 DBG2("ath5k: rx %d bytes, signal %d\n", rs.rs_datalen,
01248                      rs.rs_rssi);
01249 
01250                 net80211_rx(sc->dev, iob, rs.rs_rssi,
01251                             ath5k_hw_rix_to_bitrate(rs.rs_rate));
01252 
01253                 bf->iob = next_iob;
01254                 bf->iobaddr = next_iob_addr;
01255 next:
01256                 list_del(&bf->list);
01257                 list_add_tail(&bf->list, &sc->rxbuf);
01258         } while (ath5k_rxbuf_setup(sc, bf) == 0);
01259 }
01260 
01261 
01262 
01263 
01264 /*************\
01265 * TX Handling *
01266 \*************/
01267 
01268 static void
01269 ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
01270 {
01271         struct ath5k_tx_status ts;
01272         struct ath5k_buf *bf, *bf0;
01273         struct ath5k_desc *ds;
01274         struct io_buffer *iob;
01275         int ret;
01276 
01277         memset(&ts, 0, sizeof(ts));
01278 
01279         list_for_each_entry_safe(bf, bf0, &txq->q, list) {
01280                 ds = bf->desc;
01281 
01282                 ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts);
01283                 if (ret) {
01284                         if (ret != -EINPROGRESS) {
01285                                 DBG("ath5k: error in processing tx desc: %s\n",
01286                                     strerror(ret));
01287                         } else {
01288                                 /* normal return, reached end of tx completions */
01289                         }
01290                         break;
01291                 }
01292 
01293                 iob = bf->iob;
01294                 bf->iob = NULL;
01295 
01296                 DBG2("ath5k: tx %d bytes complete, %d retries\n",
01297                      iob_len(iob), ts.ts_retry[0]);
01298 
01299                 net80211_tx_complete(sc->dev, iob, ts.ts_retry[0],
01300                                      ts.ts_status ? EIO : 0);
01301 
01302                 list_del(&bf->list);
01303                 list_add_tail(&bf->list, &sc->txbuf);
01304                 sc->txbuf_len++;
01305         }
01306 
01307         if (list_empty(&txq->q))
01308                 txq->link = NULL;
01309 }
01310 
01311 static void
01312 ath5k_handle_tx(struct ath5k_softc *sc)
01313 {
01314         ath5k_tx_processq(sc, &sc->txq);
01315 }
01316 
01317 
01318 /********************\
01319 * Interrupt handling *
01320 \********************/
01321 
01322 static void
01323 ath5k_irq(struct net80211_device *dev, int enable)
01324 {
01325         struct ath5k_softc *sc = dev->priv;
01326         struct ath5k_hw *ah = sc->ah;
01327 
01328         sc->irq_ena = enable;
01329         ah->ah_ier = enable ? AR5K_IER_ENABLE : AR5K_IER_DISABLE;
01330 
01331         ath5k_hw_reg_write(ah, ah->ah_ier, AR5K_IER);
01332         ath5k_hw_set_imr(ah, sc->imask);
01333 }
01334 
01335 static int
01336 ath5k_init(struct ath5k_softc *sc)
01337 {
01338         struct ath5k_hw *ah = sc->ah;
01339         int ret, i;
01340 
01341         /*
01342          * Stop anything previously setup.  This is safe
01343          * no matter this is the first time through or not.
01344          */
01345         ath5k_stop_hw(sc);
01346 
01347         /*
01348          * The basic interface to setting the hardware in a good
01349          * state is ``reset''.  On return the hardware is known to
01350          * be powered up and with interrupts disabled.  This must
01351          * be followed by initialization of the appropriate bits
01352          * and then setup of the interrupt mask.
01353          */
01354         sc->curchan = sc->dev->channels + sc->dev->channel;
01355         sc->curband = sc->curchan->band;
01356         sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
01357                 AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
01358                 AR5K_INT_FATAL | AR5K_INT_GLOBAL;
01359         ret = ath5k_reset(sc, NULL);
01360         if (ret)
01361                 goto done;
01362 
01363         ath5k_rfkill_hw_start(ah);
01364 
01365         /*
01366          * Reset the key cache since some parts do not reset the
01367          * contents on initial power up or resume from suspend.
01368          */
01369         for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
01370                 ath5k_hw_reset_key(ah, i);
01371 
01372         /* Set ack to be sent at low bit-rates */
01373         ath5k_hw_set_ack_bitrate_high(ah, 0);
01374 
01375         ret = 0;
01376 done:
01377         mb();
01378         return ret;
01379 }
01380 
01381 static int
01382 ath5k_stop_hw(struct ath5k_softc *sc)
01383 {
01384         struct ath5k_hw *ah = sc->ah;
01385 
01386         /*
01387          * Shutdown the hardware and driver:
01388          *    stop output from above
01389          *    disable interrupts
01390          *    turn off timers
01391          *    turn off the radio
01392          *    clear transmit machinery
01393          *    clear receive machinery
01394          *    drain and release tx queues
01395          *    reclaim beacon resources
01396          *    power down hardware
01397          *
01398          * Note that some of this work is not possible if the
01399          * hardware is gone (invalid).
01400          */
01401 
01402         if (!(sc->status & ATH_STAT_INVALID)) {
01403                 ath5k_hw_set_imr(ah, 0);
01404         }
01405         ath5k_txq_cleanup(sc);
01406         if (!(sc->status & ATH_STAT_INVALID)) {
01407                 ath5k_rx_stop(sc);
01408                 ath5k_hw_phy_disable(ah);
01409         } else
01410                 sc->rxlink = NULL;
01411 
01412         ath5k_rfkill_hw_stop(sc->ah);
01413 
01414         return 0;
01415 }
01416 
01417 static void
01418 ath5k_poll(struct net80211_device *dev)
01419 {
01420         struct ath5k_softc *sc = dev->priv;
01421         struct ath5k_hw *ah = sc->ah;
01422         enum ath5k_int status;
01423         unsigned int counter = 1000;
01424 
01425         if (currticks() - sc->last_calib_ticks >
01426             ATH5K_CALIB_INTERVAL * ticks_per_sec()) {
01427                 ath5k_calibrate(sc);
01428                 sc->last_calib_ticks = currticks();
01429         }
01430 
01431         if ((sc->status & ATH_STAT_INVALID) ||
01432             (sc->irq_ena && !ath5k_hw_is_intr_pending(ah)))
01433                 return;
01434 
01435         do {
01436                 ath5k_hw_get_isr(ah, &status);          /* NB: clears IRQ too */
01437                 DBGP("ath5k: status %#x/%#x\n", status, sc->imask);
01438                 if (status & AR5K_INT_FATAL) {
01439                         /*
01440                          * Fatal errors are unrecoverable.
01441                          * Typically these are caused by DMA errors.
01442                          */
01443                         DBG("ath5k: fatal error, resetting\n");
01444                         ath5k_reset_wake(sc);
01445                 } else if (status & AR5K_INT_RXORN) {
01446                         DBG("ath5k: rx overrun, resetting\n");
01447                         ath5k_reset_wake(sc);
01448                 } else {
01449                         if (status & AR5K_INT_RXEOL) {
01450                                 /*
01451                                  * NB: the hardware should re-read the link when
01452                                  *     RXE bit is written, but it doesn't work at
01453                                  *     least on older hardware revs.
01454                                  */
01455                                 DBG("ath5k: rx EOL\n");
01456                                 sc->rxlink = NULL;
01457                         }
01458                         if (status & AR5K_INT_TXURN) {
01459                                 /* bump tx trigger level */
01460                                 DBG("ath5k: tx underrun\n");
01461                                 ath5k_hw_update_tx_triglevel(ah, 1);
01462                         }
01463                         if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR))
01464                                 ath5k_handle_rx(sc);
01465                         if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC
01466                                       | AR5K_INT_TXERR | AR5K_INT_TXEOL))
01467                                 ath5k_handle_tx(sc);
01468                 }
01469         } while (ath5k_hw_is_intr_pending(ah) && counter-- > 0);
01470 
01471         if (!counter)
01472                 DBG("ath5k: too many interrupts, giving up for now\n");
01473 }
01474 
01475 /*
01476  * Periodically recalibrate the PHY to account
01477  * for temperature/environment changes.
01478  */
01479 static void
01480 ath5k_calibrate(struct ath5k_softc *sc)
01481 {
01482         struct ath5k_hw *ah = sc->ah;
01483 
01484         if (ath5k_hw_gainf_calibrate(ah) == AR5K_RFGAIN_NEED_CHANGE) {
01485                 /*
01486                  * Rfgain is out of bounds, reset the chip
01487                  * to load new gain values.
01488                  */
01489                 DBG("ath5k: resetting for calibration\n");
01490                 ath5k_reset_wake(sc);
01491         }
01492         if (ath5k_hw_phy_calibrate(ah, sc->curchan))
01493                 DBG("ath5k: calibration of channel %d failed\n",
01494                     sc->curchan->channel_nr);
01495 }
01496 
01497 
01498 /********************\
01499 * Net80211 functions *
01500 \********************/
01501 
01502 static int
01503 ath5k_tx(struct net80211_device *dev, struct io_buffer *iob)
01504 {
01505         struct ath5k_softc *sc = dev->priv;
01506         struct ath5k_buf *bf;
01507         int rc;
01508 
01509         /*
01510          * The hardware expects the header padded to 4 byte boundaries.
01511          * gPXE only ever sends 24-byte headers, so no action necessary.
01512          */
01513 
01514         if (list_empty(&sc->txbuf)) {
01515                 DBG("ath5k: dropping packet because no tx bufs available\n");
01516                 return -ENOBUFS;
01517         }
01518 
01519         bf = list_entry(sc->txbuf.next, struct ath5k_buf, list);
01520         list_del(&bf->list);
01521         sc->txbuf_len--;
01522 
01523         bf->iob = iob;
01524 
01525         if ((rc = ath5k_txbuf_setup(sc, bf)) != 0) {
01526                 bf->iob = NULL;
01527                 list_add_tail(&bf->list, &sc->txbuf);
01528                 sc->txbuf_len++;
01529                 return rc;
01530         }
01531         return 0;
01532 }
01533 
01534 /*
01535  * Reset the hardware.  If chan is not NULL, then also pause rx/tx
01536  * and change to the given channel.
01537  */
01538 static int
01539 ath5k_reset(struct ath5k_softc *sc, struct net80211_channel *chan)
01540 {
01541         struct ath5k_hw *ah = sc->ah;
01542         int ret;
01543 
01544         if (chan) {
01545                 ath5k_hw_set_imr(ah, 0);
01546                 ath5k_txq_cleanup(sc);
01547                 ath5k_rx_stop(sc);
01548 
01549                 sc->curchan = chan;
01550                 sc->curband = chan->band;
01551         }
01552 
01553         ret = ath5k_hw_reset(ah, sc->curchan, 1);
01554         if (ret) {
01555                 DBG("ath5k: can't reset hardware: %s\n", strerror(ret));
01556                 return ret;
01557         }
01558 
01559         ret = ath5k_rx_start(sc);
01560         if (ret) {
01561                 DBG("ath5k: can't start rx logic: %s\n", strerror(ret));
01562                 return ret;
01563         }
01564 
01565         /*
01566          * Change channels and update the h/w rate map if we're switching;
01567          * e.g. 11a to 11b/g.
01568          *
01569          * We may be doing a reset in response to an ioctl that changes the
01570          * channel so update any state that might change as a result.
01571          *
01572          * XXX needed?
01573          */
01574 /*      ath5k_chan_change(sc, c); */
01575 
01576         /* Reenable interrupts if necessary */
01577         ath5k_irq(sc->dev, sc->irq_ena);
01578 
01579         return 0;
01580 }
01581 
01582 static int ath5k_reset_wake(struct ath5k_softc *sc)
01583 {
01584         return ath5k_reset(sc, sc->curchan);
01585 }
01586 
01587 static int ath5k_start(struct net80211_device *dev)
01588 {
01589         struct ath5k_softc *sc = dev->priv;
01590         int ret;
01591 
01592         if ((ret = ath5k_init(sc)) != 0)
01593                 return ret;
01594 
01595         sc->assoc = 0;
01596         ath5k_configure_filter(sc);
01597         ath5k_hw_set_lladdr(sc->ah, dev->netdev->ll_addr);
01598 
01599         return 0;
01600 }
01601 
01602 static void ath5k_stop(struct net80211_device *dev)
01603 {
01604         struct ath5k_softc *sc = dev->priv;
01605         u8 mac[ETH_ALEN] = {};
01606 
01607         ath5k_hw_set_lladdr(sc->ah, mac);
01608 
01609         ath5k_stop_hw(sc);
01610 }
01611 
01612 static int
01613 ath5k_config(struct net80211_device *dev, int changed)
01614 {
01615         struct ath5k_softc *sc = dev->priv;
01616         struct ath5k_hw *ah = sc->ah;
01617         struct net80211_channel *chan = &dev->channels[dev->channel];
01618         int ret;
01619 
01620         if (changed & NET80211_CFG_CHANNEL) {
01621                 sc->power_level = chan->maxpower;
01622                 if ((ret = ath5k_chan_set(sc, chan)) != 0)
01623                         return ret;
01624         }
01625 
01626         if ((changed & NET80211_CFG_RATE) ||
01627             (changed & NET80211_CFG_PHY_PARAMS)) {
01628                 int spmbl = ATH5K_SPMBL_NO;
01629                 u16 rate = dev->rates[dev->rate];
01630                 u16 slowrate = dev->rates[dev->rtscts_rate];
01631                 int i;
01632 
01633                 if (dev->phy_flags & NET80211_PHY_USE_SHORT_PREAMBLE)
01634                         spmbl = ATH5K_SPMBL_YES;
01635 
01636                 for (i = 0; i < ATH5K_NR_RATES; i++) {
01637                         if (ath5k_rates[i].bitrate == rate &&
01638                             (ath5k_rates[i].short_pmbl & spmbl))
01639                                 sc->hw_rate = ath5k_rates[i].hw_code;
01640 
01641                         if (ath5k_rates[i].bitrate == slowrate &&
01642                             (ath5k_rates[i].short_pmbl & spmbl))
01643                                 sc->hw_rtscts_rate = ath5k_rates[i].hw_code;
01644                 }
01645         }
01646 
01647         if (changed & NET80211_CFG_ASSOC) {
01648                 sc->assoc = !!(dev->state & NET80211_ASSOCIATED);
01649                 if (sc->assoc) {
01650                         memcpy(ah->ah_bssid, dev->bssid, ETH_ALEN);
01651                 } else {
01652                         memset(ah->ah_bssid, 0xff, ETH_ALEN);
01653                 }
01654                 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
01655         }
01656 
01657         return 0;
01658 }
01659 
01660 /*
01661  * o always accept unicast, broadcast, and multicast traffic
01662  * o multicast traffic for all BSSIDs will be enabled if mac80211
01663  *   says it should be
01664  * o maintain current state of phy ofdm or phy cck error reception.
01665  *   If the hardware detects any of these type of errors then
01666  *   ath5k_hw_get_rx_filter() will pass to us the respective
01667  *   hardware filters to be able to receive these type of frames.
01668  * o probe request frames are accepted only when operating in
01669  *   hostap, adhoc, or monitor modes
01670  * o enable promiscuous mode according to the interface state
01671  * o accept beacons:
01672  *   - when operating in adhoc mode so the 802.11 layer creates
01673  *     node table entries for peers,
01674  *   - when operating in station mode for collecting rssi data when
01675  *     the station is otherwise quiet, or
01676  *   - when scanning
01677  */
01678 static void ath5k_configure_filter(struct ath5k_softc *sc)
01679 {
01680         struct ath5k_hw *ah = sc->ah;
01681         u32 mfilt[2], rfilt;
01682 
01683         /* Enable all multicast */
01684         mfilt[0] = ~0;
01685         mfilt[1] = ~0;
01686 
01687         /* Enable data frames and beacons */
01688         rfilt = (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST |
01689                  AR5K_RX_FILTER_MCAST | AR5K_RX_FILTER_BEACON);
01690 
01691         /* Set filters */
01692         ath5k_hw_set_rx_filter(ah, rfilt);
01693 
01694         /* Set multicast bits */
01695         ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]);
01696 
01697         /* Set the cached hw filter flags, this will alter actually
01698          * be set in HW */
01699         sc->filter_flags = rfilt;
01700 }

Generated on Tue Apr 6 20:00:55 2010 for gPXE by  doxygen 1.5.7.1