#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_buffer * | ath5k_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 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_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().
| 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().
| 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 }
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),
}
struct ath5k_srev_name srev_names[] [static] |
struct { ... } ath5k_rates[] [static] |
Referenced by ath5k_bitrate_to_hw_rix(), ath5k_config(), ath5k_hw_rix_to_bitrate(), and ath5k_setup_bands().
| 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,
}
struct net80211_device_operations ath5k_ops [static] |
Initial value:
{
.open = ath5k_start,
.close = ath5k_stop,
.transmit = ath5k_tx,
.poll = ath5k_poll,
.irq = ath5k_irq,
.config = ath5k_config,
}
1.5.7.1