ath5k.c File Reference

#include <stdlib.h>
#include <gpxe/malloc.h>
#include <gpxe/timer.h>
#include <gpxe/netdevice.h>
#include <gpxe/pci.h>
#include <gpxe/pci_io.h>
#include "base.h"
#include "reg.h"

Go to the source code of this file.

Defines

#define ATH5K_CALIB_INTERVAL   10
#define ATH5K_RETRIES   4
#define ATH5K_DESC_ALIGN   16
#define ATH5K_SPMBL_NO   1
#define ATH5K_SPMBL_YES   2
#define ATH5K_SPMBL_BOTH   3
#define ATH5K_NR_RATES   15

Functions

 FILE_LICENCE (BSD3)
static int ath5k_probe (struct pci_device *pdev, const struct pci_device_id *id)
static void ath5k_remove (struct pci_device *pdev)
static int ath5k_tx (struct net80211_device *dev, struct io_buffer *skb)
static int ath5k_reset (struct ath5k_softc *sc, struct net80211_channel *chan)
static int ath5k_reset_wake (struct ath5k_softc *sc)
static int ath5k_start (struct net80211_device *dev)
static void ath5k_stop (struct net80211_device *dev)
static int ath5k_config (struct net80211_device *dev, int changed)
static void ath5k_poll (struct net80211_device *dev)
static void ath5k_irq (struct net80211_device *dev, int enable)
static int ath5k_attach (struct net80211_device *dev)
static void ath5k_detach (struct net80211_device *dev)
static unsigned int ath5k_copy_channels (struct ath5k_hw *ah, struct net80211_channel *channels, unsigned int mode, unsigned int max)
static int ath5k_setup_bands (struct net80211_device *dev)
static int ath5k_chan_set (struct ath5k_softc *sc, struct net80211_channel *chan)
static void ath5k_setcurmode (struct ath5k_softc *sc, unsigned int mode)
static void ath5k_mode_setup (struct ath5k_softc *sc)
static int ath5k_desc_alloc (struct ath5k_softc *sc)
static void ath5k_desc_free (struct ath5k_softc *sc)
static int ath5k_rxbuf_setup (struct ath5k_softc *sc, struct ath5k_buf *bf)
static int ath5k_txbuf_setup (struct ath5k_softc *sc, struct ath5k_buf *bf)
static void ath5k_txbuf_free (struct ath5k_softc *sc, struct ath5k_buf *bf)
static void ath5k_rxbuf_free (struct ath5k_softc *sc __unused, struct ath5k_buf *bf)
static int ath5k_txq_setup (struct ath5k_softc *sc, int qtype, int subtype)
static void ath5k_txq_drainq (struct ath5k_softc *sc, struct ath5k_txq *txq)
static void ath5k_txq_cleanup (struct ath5k_softc *sc)
static void ath5k_txq_release (struct ath5k_softc *sc)
static int ath5k_rx_start (struct ath5k_softc *sc)
static void ath5k_rx_stop (struct ath5k_softc *sc)
static void ath5k_tx_processq (struct ath5k_softc *sc, struct ath5k_txq *txq)
static int ath5k_init (struct ath5k_softc *sc)
static int ath5k_stop_hw (struct ath5k_softc *sc)
static void ath5k_calibrate (struct ath5k_softc *sc)
static void ath5k_configure_filter (struct ath5k_softc *sc)
static short ath5k_ieee2mhz (short chan)
static int ath5k_hw_rix_to_bitrate (int hw_rix)
int ath5k_bitrate_to_hw_rix (int bitrate)
static struct io_bufferath5k_rx_iob_alloc (struct ath5k_softc *sc, u32 *iob_addr)
static void ath5k_handle_rx (struct ath5k_softc *sc)
static void ath5k_handle_tx (struct ath5k_softc *sc)

Variables

static struct pci_device_id ath5k_nics []
static struct ath5k_srev_name srev_names []
struct {
   u16   bitrate
   u8   short_pmbl
   u8   hw_code
ath5k_rates []
struct pci_driver ath5k_pci_driver __pci_driver
static struct
net80211_device_operations 
ath5k_ops


Define Documentation

#define ATH5K_CALIB_INTERVAL   10

Definition at line 58 of file ath5k.c.

Referenced by ath5k_poll().

#define ATH5K_RETRIES   4

Definition at line 59 of file ath5k.c.

Referenced by ath5k_txbuf_setup().

#define ATH5K_DESC_ALIGN   16

Definition at line 60 of file ath5k.c.

Referenced by ath5k_desc_alloc().

#define ATH5K_SPMBL_NO   1

Definition at line 128 of file ath5k.c.

Referenced by ath5k_config().

#define ATH5K_SPMBL_YES   2

Definition at line 129 of file ath5k.c.

Referenced by ath5k_config().

#define ATH5K_SPMBL_BOTH   3

Definition at line 130 of file ath5k.c.

#define ATH5K_NR_RATES   15

Definition at line 155 of file ath5k.c.

Referenced by ath5k_bitrate_to_hw_rix(), ath5k_config(), and ath5k_hw_rix_to_bitrate().


Function Documentation

FILE_LICENCE ( BSD3   ) 

static int ath5k_probe ( struct pci_device pdev,
const struct pci_device_id id 
) [static]

Definition at line 287 of file ath5k.c.

References adjust_pci_device(), ath5k_softc::ah, ath5k_hw::ah_capabilities, ath5k_hw::ah_mac_srev, ath5k_hw::ah_phy_revision, ath5k_hw::ah_radio_2ghz_revision, ath5k_hw::ah_radio_5ghz_revision, ath5k_hw::ah_single_chip, AR5K_MODE_BIT_11A, AR5K_MODE_BIT_11B, AR5K_VERSION_MAC, AR5K_VERSION_RAD, ath5k_attach(), ath5k_hw_attach(), ath5k_hw_detach(), ATH_STAT_INVALID, ath5k_softc::cachelsz, ath5k_capabilities::cap_mode, net80211_hw_info::channel_change_time, DBG, net_device::dev, ath5k_softc::dev, pci_device_id::driver_data, EIO, ENOMEM, net80211_hw_info::flags, free(), ath5k_softc::hwinfo, ath5k_softc::iobase, ioremap(), iounmap(), pci_device::membase, net80211_alloc(), net80211_free(), net80211_device::netdev, PCI_CACHE_LINE_SIZE, PCI_LATENCY_TIMER, pci_read_config_byte(), pci_set_drvdata(), pci_write_config_byte(), ath5k_softc::pdev, net80211_device::priv, net80211_hw_info::signal_max, net80211_hw_info::signal_type, ath5k_softc::status, u8, and zalloc().

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 }

static void ath5k_remove ( struct pci_device pdev  )  [static]

Definition at line 445 of file ath5k.c.

References ath5k_softc::ah, ath5k_detach(), ath5k_hw_detach(), free(), ath5k_softc::hwinfo, ath5k_softc::iobase, iounmap(), net80211_free(), pci_get_drvdata(), and net80211_device::priv.

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 }

static int ath5k_tx ( struct net80211_device dev,
struct io_buffer skb 
) [static]

Definition at line 1503 of file ath5k.c.

References ath5k_txbuf_setup(), DBG, ENOBUFS, ath5k_buf::iob, ath5k_buf::list, list_add_tail, list_del, list_empty(), list_entry, list_head::next, NULL, net80211_device::priv, ath5k_softc::txbuf, and ath5k_softc::txbuf_len.

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 }

static int ath5k_reset ( struct ath5k_softc sc,
struct net80211_channel chan 
) [static]

Definition at line 1539 of file ath5k.c.

References ath5k_softc::ah, ath5k_hw_reset(), ath5k_hw_set_imr(), ath5k_irq(), ath5k_rx_start(), ath5k_rx_stop(), ath5k_txq_cleanup(), net80211_channel::band, ath5k_softc::curband, ath5k_softc::curchan, DBG, ath5k_softc::dev, ath5k_softc::irq_ena, and strerror().

Referenced by ath5k_chan_set(), ath5k_init(), and ath5k_reset_wake().

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 }

static int ath5k_reset_wake ( struct ath5k_softc sc  )  [static]

Definition at line 1582 of file ath5k.c.

References ath5k_reset(), and ath5k_softc::curchan.

Referenced by ath5k_calibrate(), and ath5k_poll().

01583 {
01584         return ath5k_reset(sc, sc->curchan);
01585 }

static int ath5k_start ( struct net80211_device dev  )  [static]

Definition at line 1587 of file ath5k.c.

References ath5k_softc::ah, ath5k_softc::assoc, ath5k_configure_filter(), ath5k_hw_set_lladdr(), ath5k_init(), net_device::ll_addr, net80211_device::netdev, and net80211_device::priv.

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 }

static void ath5k_stop ( struct net80211_device dev  )  [static]

Definition at line 1602 of file ath5k.c.

References ath5k_softc::ah, ath5k_hw_set_lladdr(), ath5k_stop_hw(), ETH_ALEN, net80211_device::priv, and u8.

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 }

static int ath5k_config ( struct net80211_device dev,
int  changed 
) [static]

Definition at line 1613 of file ath5k.c.

References ath5k_softc::ah, ath5k_hw::ah_bssid, ath5k_softc::assoc, ath5k_chan_set(), ath5k_hw_set_associd(), ATH5K_NR_RATES, ath5k_rates, ATH5K_SPMBL_NO, ATH5K_SPMBL_YES, bitrate, net80211_device::bssid, net80211_device::channel, net80211_device::channels, ETH_ALEN, ath5k_softc::hw_rate, ath5k_softc::hw_rtscts_rate, net80211_channel::maxpower, memcpy, memset(), NET80211_ASSOCIATED, NET80211_CFG_ASSOC, NET80211_CFG_CHANNEL, NET80211_CFG_PHY_PARAMS, NET80211_CFG_RATE, NET80211_PHY_USE_SHORT_PREAMBLE, net80211_device::phy_flags, ath5k_softc::power_level, net80211_device::priv, net80211_device::rate, net80211_device::rates, net80211_device::rtscts_rate, short_pmbl, net80211_device::state, and u16.

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 }

static void ath5k_poll ( struct net80211_device dev  )  [static]

Definition at line 1418 of file ath5k.c.

References ath5k_softc::ah, AR5K_INT_FATAL, AR5K_INT_RXEOL, AR5K_INT_RXERR, AR5K_INT_RXOK, AR5K_INT_RXORN, AR5K_INT_TXDESC, AR5K_INT_TXEOL, AR5K_INT_TXERR, AR5K_INT_TXOK, AR5K_INT_TXURN, ATH5K_CALIB_INTERVAL, ath5k_calibrate(), ath5k_handle_rx(), ath5k_handle_tx(), ath5k_hw_get_isr(), ath5k_hw_is_intr_pending(), ath5k_hw_update_tx_triglevel(), ath5k_reset_wake(), ATH_STAT_INVALID, currticks(), DBG, DBGP, ath5k_softc::imask, ath5k_softc::irq_ena, ath5k_softc::last_calib_ticks, NULL, net80211_device::priv, ath5k_softc::rxlink, ath5k_softc::status, and ticks_per_sec().

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 }

static void ath5k_irq ( struct net80211_device dev,
int  enable 
) [static]

Definition at line 1323 of file ath5k.c.

References ath5k_softc::ah, ath5k_hw::ah_ier, AR5K_IER, AR5K_IER_DISABLE, AR5K_IER_ENABLE, ath5k_hw_reg_write(), ath5k_hw_set_imr(), ath5k_softc::imask, ath5k_softc::irq_ena, and net80211_device::priv.

Referenced by ath5k_reset().

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 }

static int ath5k_attach ( struct net80211_device dev  )  [static]

Definition at line 463 of file ath5k.c.

References ath5k_softc::ah, AR5K_MODE_11A, AR5K_MODE_11B, AR5K_MODE_BIT_11A, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE, ath5k_desc_alloc(), ath5k_desc_free(), ath5k_eeprom_read_mac(), ath5k_hw_set_bssid_mask(), ath5k_setcurmode(), ath5k_setup_bands(), ath5k_txq_release(), ath5k_txq_setup(), ath5k_softc::bssidmask, currticks(), DBG, ath5k_softc::dev, pci_device::device, ETH_ALEN, net80211_hw_info::hwaddr, ath5k_softc::hwinfo, ath5k_softc::last_calib_ticks, memset(), net80211_register(), ath5k_softc::pdev, and net80211_device::priv.

Referenced by ath5k_probe().

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 }

static void ath5k_detach ( struct net80211_device dev  )  [static]

Definition at line 534 of file ath5k.c.

References ath5k_desc_free(), ath5k_txq_release(), net80211_unregister(), and net80211_device::priv.

Referenced by ath5k_remove().

00535 {
00536         struct ath5k_softc *sc = dev->priv;
00537 
00538         net80211_unregister(dev);
00539         ath5k_desc_free(sc);
00540         ath5k_txq_release(sc);
00541 }

static unsigned int ath5k_copy_channels ( struct ath5k_hw ah,
struct net80211_channel channels,
unsigned int  mode,
unsigned int  max 
) [static]

Definition at line 566 of file ath5k.c.

References AR5K_MODE_11A, AR5K_MODE_11A_TURBO, AR5K_MODE_11B, AR5K_MODE_11G, AR5K_MODE_11G_TURBO, ath5k_channel_ok(), ath5k_ieee2mhz(), net80211_channel::band, net80211_channel::center_freq, CHANNEL_2GHZ, CHANNEL_5GHZ, CHANNEL_B, CHANNEL_OFDM, CHANNEL_TURBO, net80211_channel::hw_value, net80211_channel::maxpower, NET80211_BAND_2GHZ, NET80211_BAND_5GHZ, and size.

Referenced by ath5k_setup_bands().

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 }

static int ath5k_setup_bands ( struct net80211_device dev  )  [static]

Definition at line 627 of file ath5k.c.

References ath5k_softc::ah, ath5k_hw::ah_capabilities, AR5K_MODE_11B, AR5K_MODE_11G, AR5K_MODE_BIT_11A, AR5K_MODE_BIT_11B, AR5K_MODE_BIT_11G, ath5k_copy_channels(), ath5k_rates, net80211_hw_info::bands, ath5k_capabilities::cap_mode, net80211_hw_info::channels, ath5k_softc::hwinfo, net80211_hw_info::modes, NET80211_BAND_2GHZ, NET80211_BAND_5GHZ, NET80211_BAND_BIT_2GHZ, NET80211_BAND_BIT_5GHZ, NET80211_MODE_A, NET80211_MODE_B, NET80211_MODE_G, net80211_hw_info::nr_channels, net80211_hw_info::nr_rates, net80211_device::priv, and net80211_hw_info::rates.

Referenced by ath5k_attach().

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 }

static int ath5k_chan_set ( struct ath5k_softc sc,
struct net80211_channel chan 
) [static]

Definition at line 697 of file ath5k.c.

References ath5k_reset(), net80211_channel::center_freq, ath5k_softc::curchan, DBG2, and net80211_channel::hw_value.

Referenced by ath5k_config().

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 }

static void ath5k_setcurmode ( struct ath5k_softc sc,
unsigned int  mode 
) [static]

Definition at line 716 of file ath5k.c.

References AR5K_MODE_11A, ath5k_softc::curband, ath5k_softc::curmode, NET80211_BAND_2GHZ, and NET80211_BAND_5GHZ.

Referenced by ath5k_attach().

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 }

static void ath5k_mode_setup ( struct ath5k_softc sc  )  [static]

Definition at line 728 of file ath5k.c.

References ath5k_softc::ah, ath5k_hw_hasbssidmask, ath5k_hw_set_bssid_mask(), ath5k_hw_set_mcast_filter(), ath5k_hw_set_opmode(), ath5k_hw_set_rx_filter(), ath5k_softc::bssidmask, ath5k_softc::filter_flags, and u32.

Referenced by ath5k_rx_start().

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 }

static int ath5k_desc_alloc ( struct ath5k_softc sc  )  [static]

Definition at line 912 of file ath5k.c.

References ATH5K_DESC_ALIGN, ATH_RXBUF, ATH_TXBUF, ath5k_softc::bufptr, calloc(), DBG, ath5k_softc::desc, ath5k_softc::desc_daddr, ath5k_softc::desc_len, ENOMEM, free_dma(), INIT_LIST_HEAD, list_add_tail, malloc_dma(), memset(), NULL, ath5k_softc::rxbuf, ath5k_softc::txbuf, ath5k_softc::txbuf_len, u32, and virt_to_bus().

Referenced by ath5k_attach().

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 }

static void ath5k_desc_free ( struct ath5k_softc sc  )  [static]

Definition at line 967 of file ath5k.c.

References ath5k_rxbuf_free(), ath5k_txbuf_free(), ath5k_softc::bufptr, ath5k_softc::desc, ath5k_softc::desc_len, free(), free_dma(), ath5k_buf::list, list_for_each_entry, NULL, ath5k_softc::rxbuf, and ath5k_softc::txbuf.

Referenced by ath5k_attach(), and ath5k_detach().

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 }

static int ath5k_rxbuf_setup ( struct ath5k_softc sc,
struct ath5k_buf bf 
) [static]

Definition at line 812 of file ath5k.c.

References ath5k_softc::ah, ath5k_hw::ah_setup_rx_desc, ath5k_rx_iob_alloc(), ath5k_buf::daddr, DBG, ath5k_buf::desc, ath5k_desc::ds_data, ath5k_desc::ds_link, EINVAL, ENOMEM, ath5k_buf::iob, iob_tailroom(), ath5k_buf::iobaddr, NULL, and ath5k_softc::rxlink.

Referenced by ath5k_handle_rx(), and ath5k_rx_start().

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 }

static int ath5k_txbuf_setup ( struct ath5k_softc sc,
struct ath5k_buf bf 
) [static]

Definition at line 857 of file ath5k.c.

References ath5k_softc::ah, ath5k_hw::ah_setup_tx_desc, AR5K_PKT_TYPE_NORMAL, AR5K_TXDESC_CLRDMASK, AR5K_TXDESC_CTSENA, AR5K_TXDESC_INTREQ, AR5K_TXKEYIX_INVALID, ath5k_hw_set_txdp(), ath5k_hw_start_tx_dma(), ATH5K_RETRIES, ath5k_buf::daddr, io_buffer::data, ath5k_buf::desc, ath5k_softc::dev, ath5k_desc::ds_data, ath5k_desc::ds_link, ath5k_softc::hw_rate, ath5k_softc::hw_rtscts_rate, IEEE80211_TYP_FRAME_HEADER_LEN, ath5k_buf::iob, iob_len(), ath5k_buf::iobaddr, ath5k_txq::link, ath5k_buf::list, list_add_tail, mb(), net80211_cts_duration(), NET80211_PHY_USE_PROTECTION, NULL, net80211_device::phy_flags, ath5k_softc::power_level, ath5k_txq::q, ath5k_txq::qnum, ath5k_softc::txq, u16, and virt_to_bus().

Referenced by ath5k_tx().

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 }

static void ath5k_txbuf_free ( struct ath5k_softc sc,
struct ath5k_buf bf 
) [inline, static]

Definition at line 219 of file ath5k.c.

References ath5k_softc::dev, ECANCELED, ath5k_buf::iob, net80211_tx_complete(), and NULL.

Referenced by ath5k_desc_free(), and ath5k_txq_drainq().

00221 {
00222         if (!bf->iob)
00223                 return;
00224 
00225         net80211_tx_complete(sc->dev, bf->iob, 0, ECANCELED);
00226         bf->iob = NULL;
00227 }

static void ath5k_rxbuf_free ( struct ath5k_softc *sc  __unused,
struct ath5k_buf bf 
) [inline, static]

Definition at line 229 of file ath5k.c.

References free_iob(), ath5k_buf::iob, and NULL.

Referenced by ath5k_desc_free().

00231 {
00232         free_iob(bf->iob);
00233         bf->iob = NULL;
00234 }

static int ath5k_txq_setup ( struct ath5k_softc sc,
int  qtype,
int  subtype 
) [static]

Definition at line 992 of file ath5k.c.

References ath5k_softc::ah, AR5K_TXQ_FLAG_TXDESCINT_ENABLE, AR5K_TXQ_FLAG_TXEOLINT_ENABLE, AR5K_TXQ_USEDEFAULT, ath5k_hw_setup_tx_queue(), DBG, EIO, INIT_LIST_HEAD, ath5k_txq::link, NULL, ath5k_txq::q, ath5k_txq::qnum, ath5k_txq::setup, ath5k_txq_info::tqi_flags, ath5k_txq_info::tqi_subtype, and ath5k_softc::txq.

Referenced by ath5k_attach().

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 }

static void ath5k_txq_drainq ( struct ath5k_softc sc,
struct ath5k_txq txq 
) [static]

Definition at line 1035 of file ath5k.c.

References ath5k_txbuf_free(), ath5k_txq::link, ath5k_buf::list, list_add_tail, list_del, list_for_each_entry_safe, NULL, ath5k_txq::q, ath5k_softc::txbuf, and ath5k_softc::txbuf_len.

Referenced by ath5k_txq_cleanup().

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 }

static void ath5k_txq_cleanup ( struct ath5k_softc sc  )  [static]

Definition at line 1053 of file ath5k.c.

References ath5k_softc::ah, ath5k_hw_get_txdp(), ath5k_hw_stop_tx_dma(), ath5k_txq_drainq(), ATH_STAT_INVALID, DBG, ath5k_txq::link, ath5k_txq::qnum, ath5k_txq::setup, ath5k_softc::status, and ath5k_softc::txq.

Referenced by ath5k_reset(), and ath5k_stop_hw().

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 }

static void ath5k_txq_release ( struct ath5k_softc sc  )  [static]

Definition at line 1073 of file ath5k.c.

References ath5k_softc::ah, ath5k_hw_release_tx_queue(), ath5k_txq::setup, and ath5k_softc::txq.

Referenced by ath5k_attach(), and ath5k_detach().

01074 {
01075         if (sc->txq.setup) {
01076                 ath5k_hw_release_tx_queue(sc->ah);
01077                 sc->txq.setup = 0;
01078         }
01079 }

static int ath5k_rx_start ( struct ath5k_softc sc  )  [static]

Definition at line 1092 of file ath5k.c.

References ath5k_softc::ah, ath5k_hw_set_rxdp(), ath5k_hw_start_rx_dma(), ath5k_hw_start_rx_pcu(), ath5k_mode_setup(), ath5k_rxbuf_setup(), ath5k_softc::cachelsz, ath5k_buf::daddr, IEEE80211_MAX_LEN, ath5k_buf::list, list_entry, list_for_each_entry, list_head::next, NULL, ath5k_softc::rxbuf, ath5k_softc::rxbufsize, and ath5k_softc::rxlink.

Referenced by ath5k_reset().

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 }

static void ath5k_rx_stop ( struct ath5k_softc sc  )  [static]

Definition at line 1124 of file ath5k.c.

References ath5k_softc::ah, ath5k_hw_set_rx_filter(), ath5k_hw_stop_rx_dma(), ath5k_hw_stop_rx_pcu(), NULL, and ath5k_softc::rxlink.

Referenced by ath5k_reset(), and ath5k_stop_hw().

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 }

static void ath5k_tx_processq ( struct ath5k_softc sc,
struct ath5k_txq txq 
) [static]

Definition at line 1269 of file ath5k.c.

References ath5k_softc::ah, ath5k_hw::ah_proc_tx_desc, DBG, DBG2, ath5k_buf::desc, ath5k_softc::dev, EINPROGRESS, EIO, ath5k_buf::iob, iob_len(), ath5k_txq::link, ath5k_buf::list, io_buffer::list, list_add_tail, list_del, list_empty(), list_for_each_entry_safe, memset(), net80211_tx_complete(), NULL, ath5k_txq::q, strerror(), ath5k_tx_status::ts_retry, ath5k_tx_status::ts_status, ath5k_softc::txbuf, and ath5k_softc::txbuf_len.

Referenced by ath5k_handle_tx().

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 }

static int ath5k_init ( struct ath5k_softc sc  )  [static]

Definition at line 1336 of file ath5k.c.

References ath5k_softc::ah, AR5K_INT_FATAL, AR5K_INT_GLOBAL, AR5K_INT_RXEOL, AR5K_INT_RXERR, AR5K_INT_RXOK, AR5K_INT_RXORN, AR5K_INT_TXDESC, AR5K_INT_TXEOL, AR5K_KEYTABLE_SIZE, ath5k_hw_reset_key(), ath5k_hw_set_ack_bitrate_high(), ath5k_reset(), ath5k_rfkill_hw_start(), ath5k_stop_hw(), net80211_channel::band, net80211_device::channel, net80211_device::channels, ath5k_softc::curband, ath5k_softc::curchan, ath5k_softc::dev, ath5k_softc::imask, mb(), and NULL.

Referenced by ath5k_start().

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 }

static int ath5k_stop_hw ( struct ath5k_softc sc  )  [static]

Definition at line 1382 of file ath5k.c.

References ath5k_softc::ah, ath5k_hw_phy_disable(), ath5k_hw_set_imr(), ath5k_rfkill_hw_stop(), ath5k_rx_stop(), ath5k_txq_cleanup(), ATH_STAT_INVALID, NULL, ath5k_softc::rxlink, and ath5k_softc::status.

Referenced by ath5k_init(), and ath5k_stop().

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 }

static void ath5k_calibrate ( struct ath5k_softc sc  )  [static]

Definition at line 1480 of file ath5k.c.

References ath5k_softc::ah, AR5K_RFGAIN_NEED_CHANGE, ath5k_hw_gainf_calibrate(), ath5k_hw_phy_calibrate(), ath5k_reset_wake(), net80211_channel::channel_nr, ath5k_softc::curchan, and DBG.

Referenced by ath5k_poll().

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 }

static void ath5k_configure_filter ( struct ath5k_softc sc  )  [static]

Definition at line 1678 of file ath5k.c.

References ath5k_softc::ah, AR5K_RX_FILTER_BCAST, AR5K_RX_FILTER_BEACON, AR5K_RX_FILTER_MCAST, AR5K_RX_FILTER_UCAST, ath5k_hw_set_mcast_filter(), ath5k_hw_set_rx_filter(), ath5k_softc::filter_flags, and u32.

Referenced by ath5k_start().

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 }

static short ath5k_ieee2mhz ( short  chan  )  [inline, static]

Definition at line 554 of file ath5k.c.

Referenced by ath5k_copy_channels().

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 }

static int ath5k_hw_rix_to_bitrate ( int  hw_rix  )  [inline, static]

Definition at line 747 of file ath5k.c.

References ATH5K_NR_RATES, ath5k_rates, DBG, and hw_code.

Referenced by ath5k_handle_rx().

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 }

int ath5k_bitrate_to_hw_rix ( int  bitrate  ) 

Definition at line 760 of file ath5k.c.

References ATH5K_NR_RATES, ATH5K_RATE_CODE_1M, ath5k_rates, and DBG.

Referenced by ath5k_hw_write_rate_duration().

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 }

static struct io_buffer* ath5k_rx_iob_alloc ( struct ath5k_softc sc,
u32 iob_addr 
) [static, read]

Definition at line 778 of file ath5k.c.

References alloc_iob(), ath5k_softc::cachelsz, io_buffer::data, DBG, iob_reserve, NULL, off, ath5k_softc::rxbufsize, and virt_to_bus().

Referenced by ath5k_handle_rx(), and ath5k_rxbuf_setup().

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 }

static void ath5k_handle_rx ( struct ath5k_softc sc  )  [static]

Definition at line 1136 of file ath5k.c.

References ath5k_softc::ah, ath5k_hw::ah_proc_rx_desc, AR5K_RXERR_CRC, AR5K_RXERR_DECRYPT, AR5K_RXERR_PHY, AR5K_RXKEYIX_INVALID, assert, ath5k_hw_rix_to_bitrate(), ath5k_rx_iob_alloc(), ath5k_rxbuf_setup(), DBG, DBG2, ath5k_buf::desc, ath5k_softc::dev, EINPROGRESS, EIO, ath5k_buf::flags, ath5k_buf::iob, iob_put, ath5k_buf::iobaddr, ath5k_buf::list, list_add_tail, list_del, list_empty(), list_entry, memset(), net80211_rx(), net80211_rx_err(), list_head::next, NULL, list_head::prev, ath5k_rx_status::rs_datalen, ath5k_rx_status::rs_keyix, ath5k_rx_status::rs_more, ath5k_rx_status::rs_rate, ath5k_rx_status::rs_rssi, ath5k_rx_status::rs_status, ath5k_softc::rxbuf, strerror(), and u32.

Referenced by ath5k_poll().

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 }

static void ath5k_handle_tx ( struct ath5k_softc sc  )  [static]

Definition at line 1312 of file ath5k.c.

References ath5k_tx_processq(), and ath5k_softc::txq.

Referenced by ath5k_poll().

01313 {
01314         ath5k_tx_processq(sc, &sc->txq);
01315 }


Variable Documentation

struct pci_device_id ath5k_nics[] [static]

Initial value:

 {
        PCI_ROM(0x168c, 0x0207, "ath5210e", "Atheros 5210 early", AR5K_AR5210),
        PCI_ROM(0x168c, 0x0007, "ath5210", "Atheros 5210", AR5K_AR5210),
        PCI_ROM(0x168c, 0x0011, "ath5311", "Atheros 5311 (AHB)", AR5K_AR5211),
        PCI_ROM(0x168c, 0x0012, "ath5211", "Atheros 5211", AR5K_AR5211),
        PCI_ROM(0x168c, 0x0013, "ath5212", "Atheros 5212", AR5K_AR5212),
        PCI_ROM(0xa727, 0x0013, "ath5212c","3com Ath 5212", AR5K_AR5212),
        PCI_ROM(0x10b7, 0x0013, "rdag675", "3com 3CRDAG675", AR5K_AR5212),
        PCI_ROM(0x168c, 0x1014, "ath5212m", "Ath 5212 miniPCI", AR5K_AR5212),
        PCI_ROM(0x168c, 0x0014, "ath5212x14", "Atheros 5212 x14", AR5K_AR5212),
        PCI_ROM(0x168c, 0x0015, "ath5212x15", "Atheros 5212 x15", AR5K_AR5212),
        PCI_ROM(0x168c, 0x0016, "ath5212x16", "Atheros 5212 x16", AR5K_AR5212),
        PCI_ROM(0x168c, 0x0017, "ath5212x17", "Atheros 5212 x17", AR5K_AR5212),
        PCI_ROM(0x168c, 0x0018, "ath5212x18", "Atheros 5212 x18", AR5K_AR5212),
        PCI_ROM(0x168c, 0x0019, "ath5212x19", "Atheros 5212 x19", AR5K_AR5212),
        PCI_ROM(0x168c, 0x001a, "ath2413", "Atheros 2413 Griffin", AR5K_AR5212),
        PCI_ROM(0x168c, 0x001b, "ath5413", "Atheros 5413 Eagle", AR5K_AR5212),
        PCI_ROM(0x168c, 0x001c, "ath5212e", "Atheros 5212 PCI-E", AR5K_AR5212),
        PCI_ROM(0x168c, 0x001d, "ath2417", "Atheros 2417 Nala", AR5K_AR5212),
}

Definition at line 67 of file ath5k.c.

struct ath5k_srev_name srev_names[] [static]

Definition at line 89 of file ath5k.c.

Definition at line 133 of file ath5k.c.

Referenced by ath5k_config().

Definition at line 134 of file ath5k.c.

Referenced by ath5k_config().

Definition at line 135 of file ath5k.c.

Referenced by ath5k_hw_rix_to_bitrate().

struct { ... } ath5k_rates[] [static]

struct pci_driver ath5k_pci_driver __pci_driver

Initial value:

 {
        .ids            = ath5k_nics,
        .id_count       = sizeof(ath5k_nics) / sizeof(ath5k_nics[0]),
        .probe          = ath5k_probe,
        .remove         = ath5k_remove,
}

Definition at line 164 of file ath5k.c.

Initial value:

 {
        .open           = ath5k_start,
        .close          = ath5k_stop,
        .transmit       = ath5k_tx,
        .poll           = ath5k_poll,
        .irq            = ath5k_irq,
        .config         = ath5k_config,
}

Definition at line 185 of file ath5k.c.


Generated on Tue Apr 6 20:01:18 2010 for gPXE by  doxygen 1.5.7.1