iPXE
Defines | Functions | Variables
ath9k_init.c File Reference
#include <ipxe/malloc.h>
#include <ipxe/pci_io.h>
#include <ipxe/pci.h>
#include <ipxe/ethernet.h>
#include "ath9k.h"

Go to the source code of this file.

Defines

#define CHAN2G(_freq, _idx)
#define CHAN5G(_freq, _idx)
#define SHPCHECK(__hw_rate, __flags)   ((__flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
#define RATE(_bitrate, _hw_rate, _flags)
#define DS2PHYS(_dd, _ds)   ((_dd)->dd_desc_paddr + ((char *)(_ds) - (char *)(_dd)->dd_desc))
#define ATH_DESC_4KB_BOUND_CHECK(_daddr)   ((((_daddr) & 0xFFF) > 0xF9F) ? 1 : 0)

Functions

 FILE_LICENCE (BSD2)
static void ath9k_deinit_softc (struct ath_softc *sc)
static void ath9k_iowrite32 (void *hw_priv, u32 val, u32 reg_offset)
static unsigned int ath9k_ioread32 (void *hw_priv, u32 reg_offset)
static unsigned int ath9k_reg_rmw (void *hw_priv, u32 reg_offset, u32 set, u32 clr)
int ath_descdma_setup (struct ath_softc *sc, struct ath_descdma *dd, struct list_head *head, const char *name, int nbuf, int ndesc, int is_tx)
void ath9k_init_crypto (struct ath_softc *sc)
static int ath9k_init_queues (struct ath_softc *sc)
static int ath9k_init_channels_rates (struct ath_softc *sc)
static void ath9k_init_misc (struct ath_softc *sc)
static int ath9k_init_softc (u16 devid, struct ath_softc *sc, u16 subsysid, const struct ath_bus_ops *bus_ops)
static void ath9k_init_band_txpower (struct ath_softc *sc, int band)
static void ath9k_init_txpower_limits (struct ath_softc *sc)
void ath9k_set_hw_capab (struct ath_softc *sc, struct net80211_device *dev __unused)
int ath9k_init_device (u16 devid, struct ath_softc *sc, u16 subsysid, const struct ath_bus_ops *bus_ops)
void ath9k_deinit_device (struct ath_softc *sc)
void ath_descdma_cleanup (struct ath_softc *sc __unused, struct ath_descdma *dd, struct list_head *head)

Variables

int is_ath9k_unloaded
static struct net80211_channel ath9k_2ghz_chantable []
static struct net80211_channel ath9k_5ghz_chantable []
static struct ath9k_legacy_rate ath9k_legacy_rates []

Define Documentation

#define CHAN2G (   _freq,
  _idx 
)
Value:
{ \
        .band = NET80211_BAND_2GHZ, \
        .center_freq = (_freq), \
        .hw_value = (_idx), \
        .maxpower = 20, \
}

Definition at line 32 of file ath9k_init.c.

#define CHAN5G (   _freq,
  _idx 
)
Value:
{ \
        .band = NET80211_BAND_5GHZ, \
        .center_freq = (_freq), \
        .hw_value = (_idx), \
        .maxpower = 20, \
}

Definition at line 39 of file ath9k_init.c.

#define SHPCHECK (   __hw_rate,
  __flags 
)    ((__flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)

Definition at line 103 of file ath9k_init.c.

#define RATE (   _bitrate,
  _hw_rate,
  _flags 
)
Value:
{              \
        .bitrate        = (_bitrate),                   \
        .flags          = (_flags),                     \
        .hw_value       = (_hw_rate),                   \
        .hw_value_short = (SHPCHECK(_hw_rate, _flags))  \
}

Definition at line 106 of file ath9k_init.c.

#define DS2PHYS (   _dd,
  _ds 
)    ((_dd)->dd_desc_paddr + ((char *)(_ds) - (char *)(_dd)->dd_desc))

Referenced by ath_descdma_setup().

#define ATH_DESC_4KB_BOUND_CHECK (   _daddr)    ((((_daddr) & 0xFFF) > 0xF9F) ? 1 : 0)

Referenced by ath_descdma_setup().


Function Documentation

FILE_LICENCE ( BSD2  )
static void ath9k_deinit_softc ( struct ath_softc sc) [static]

Definition at line 561 of file ath9k_init.c.

References ath9k_hw_deinit(), ATH9K_NUM_TX_QUEUES, ath_tx_cleanupq(), ATH_TXQ_SETUP, free, ath_softc::hwinfo, NULL, ath_softc::sc_ah, ath_softc::tx, and ath_tx::txq.

Referenced by ath9k_deinit_device(), and ath9k_init_device().

{
        int i = 0;

        for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
                if (ATH_TXQ_SETUP(sc, i))
                        ath_tx_cleanupq(sc, &sc->tx.txq[i]);

        ath9k_hw_deinit(sc->sc_ah);

        free(sc->hwinfo);
        sc->hwinfo = NULL;
        free(sc->sc_ah);
        sc->sc_ah = NULL;
}
static void ath9k_iowrite32 ( void *  hw_priv,
u32  val,
u32  reg_offset 
) [static]

Definition at line 136 of file ath9k_init.c.

References ah, ath9k_hw_common(), common, ath_softc::mem, ath_common::priv, and writel().

Referenced by ath9k_init_softc().

{
        struct ath_hw *ah = (struct ath_hw *) hw_priv;
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath_softc *sc = (struct ath_softc *) common->priv;

        writel(val, sc->mem + reg_offset);
}
static unsigned int ath9k_ioread32 ( void *  hw_priv,
u32  reg_offset 
) [static]

Definition at line 145 of file ath9k_init.c.

References ah, ath9k_hw_common(), common, ath_softc::mem, ath_common::priv, readl(), and val.

Referenced by ath9k_init_softc().

{
        struct ath_hw *ah = (struct ath_hw *) hw_priv;
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath_softc *sc = (struct ath_softc *) common->priv;
        u32 val;

        val = readl(sc->mem + reg_offset);
        return val;
}
static unsigned int ath9k_reg_rmw ( void *  hw_priv,
u32  reg_offset,
u32  set,
u32  clr 
) [static]

Definition at line 156 of file ath9k_init.c.

References ah, ath9k_hw_common(), common, ath_softc::mem, ath_common::priv, readl(), val, and writel().

Referenced by ath9k_init_softc().

{
        struct ath_hw *ah = (struct ath_hw *) hw_priv;
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath_softc *sc = (struct ath_softc *) common->priv;
        u32 val;

        val = readl(sc->mem + reg_offset);
        val &= ~clr;
        val |= set;
        writel(val, sc->mem + reg_offset);

        return val;
}
int ath_descdma_setup ( struct ath_softc sc,
struct ath_descdma dd,
struct list_head head,
const char *  name,
int  nbuf,
int  ndesc,
int  is_tx 
)

Definition at line 180 of file ath9k_init.c.

References ATH9K_HW_CAP_4KB_SPLITTRANS, ATH_DESC_4KB_BOUND_CHECK, ath_buf::bf_desc, ath_hw::caps, DBG, DBG2, ath_descdma::dd_bufptr, ath_descdma::dd_desc, ath_descdma::dd_desc_len, ath_descdma::dd_desc_paddr, ds, DS2PHYS, ENOMEM, error, free_dma(), ath9k_hw_capabilities::hw_caps, INIT_LIST_HEAD, ito64, list_add_tail, malloc_dma(), memset(), NULL, ath_softc::sc_ah, ath9k_hw_capabilities::tx_desc_len, virt_to_bus(), and zalloc().

Referenced by ath_rx_init(), and ath_tx_init().

{
#define DS2PHYS(_dd, _ds)                                               \
        ((_dd)->dd_desc_paddr + ((char *)(_ds) - (char *)(_dd)->dd_desc))
#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF9F) ? 1 : 0)
        u8 *ds;
        struct ath_buf *bf;
        int i, bsize, error, desc_len;

        DBG2("ath9k: %s DMA: %d buffers %d desc/buf\n",
                name, nbuf, ndesc);

        INIT_LIST_HEAD(head);

        if (is_tx)
                desc_len = sc->sc_ah->caps.tx_desc_len;
        else
                desc_len = sizeof(struct ath_desc);

        /* ath_desc must be a multiple of DWORDs */
        if ((desc_len % 4) != 0) {
                DBG("ath9k: ath_desc not DWORD aligned\n");
                error = -ENOMEM;
                goto fail;
        }

        dd->dd_desc_len = desc_len * nbuf * ndesc;

        /*
         * Need additional DMA memory because we can't use
         * descriptors that cross the 4K page boundary.
         * However, iPXE only utilizes 16 buffers, which
         * will never make up more than half of one page,
         * so we will only ever skip 1 descriptor, if that.
         */
        if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
                u32 ndesc_skipped = 1;
                u32 dma_len;

                dma_len = ndesc_skipped * desc_len;
                dd->dd_desc_len += dma_len;
        }

        /* allocate descriptors */
        dd->dd_desc = malloc_dma(dd->dd_desc_len, 16);
        if (dd->dd_desc == NULL) {
                error = -ENOMEM;
                goto fail;
        }
        dd->dd_desc_paddr = virt_to_bus(dd->dd_desc);
        ds = (u8 *) dd->dd_desc;
        DBG2("ath9k: %s DMA map: %p (%d) -> %llx (%d)\n",
                name, ds, (u32) dd->dd_desc_len,
                ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);

        /* allocate buffers */
        bsize = sizeof(struct ath_buf) * nbuf;
        bf = zalloc(bsize);
        if (bf == NULL) {
                error = -ENOMEM;
                goto fail2;
        }
        dd->dd_bufptr = bf;

        for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
                bf->bf_desc = ds;
                bf->bf_daddr = DS2PHYS(dd, ds);

                if (!(sc->sc_ah->caps.hw_caps &
                      ATH9K_HW_CAP_4KB_SPLITTRANS)) {
                        /*
                         * Skip descriptor addresses which can cause 4KB
                         * boundary crossing (addr + length) with a 32 dword
                         * descriptor fetch.
                         */
                        while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
                                ds += (desc_len * ndesc);
                                bf->bf_desc = ds;
                                bf->bf_daddr = DS2PHYS(dd, ds);
                        }
                }
                list_add_tail(&bf->list, head);
        }
        return 0;
fail2:
        free_dma(dd->dd_desc, dd->dd_desc_len);
fail:
        memset(dd, 0, sizeof(*dd));
        return error;
#undef ATH_DESC_4KB_BOUND_CHECK
#undef DS2PHYS
}
void ath9k_init_crypto ( struct ath_softc sc)

Definition at line 275 of file ath9k_init.c.

References AR_KEYTABLE_SIZE, AR_PCU_MIC_NEW_LOC_ENA, ath9k_hw_common(), ATH_CRYPT_CAP_MIC_COMBINED, ath_hw_keyreset(), common, ath_common::crypt_caps, ath_common::keymax, ath_hw::misc_mode, and ath_softc::sc_ah.

Referenced by ath9k_init_softc().

{
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        unsigned int i = 0;

        /* Get the hardware key cache size. */
        common->keymax = AR_KEYTABLE_SIZE;

        /*
         * Reset the key cache since some parts do not
         * reset the contents on initial power up.
         */
        for (i = 0; i < common->keymax; i++)
                ath_hw_keyreset(common, (u16) i);

        /*
         * Check whether the separate key cache entries
         * are required to handle both tx+rx MIC keys.
         * With split mic keys the number of stations is limited
         * to 27 otherwise 59.
         */
        if (sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
                common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
}
static int ath9k_init_queues ( struct ath_softc sc) [static]

Definition at line 300 of file ath9k_init.c.

References ATH9K_TX_QUEUE_DATA, ath_txq_setup(), ath_txq::mac80211_qnum, ath_softc::tx, ath_tx::txq_map, and WME_NUM_AC.

Referenced by ath9k_init_softc().

{
        int i = 0;

        for (i = 0; i < WME_NUM_AC; i++) {
                sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
                sc->tx.txq_map[i]->mac80211_qnum = i;
        }
        return 0;
}
static int ath9k_init_channels_rates ( struct ath_softc sc) [static]
static void ath9k_init_misc ( struct ath_softc sc) [static]
static int ath9k_init_softc ( u16  devid,
struct ath_softc sc,
u16  subsysid,
const struct ath_bus_ops bus_ops 
) [static]

Definition at line 356 of file ath9k_init.c.

References ah, ath_common::ah, ath_hw::ah_flags, AH_USE_EEPROM, ath9k_hw_common(), ath9k_hw_deinit(), ath9k_hw_init(), ath9k_init_channels_rates(), ath9k_init_crypto(), ath9k_init_misc(), ath9k_init_queues(), ath9k_ioread32(), ath9k_iowrite32(), ATH9K_NUM_TX_QUEUES, ath9k_reg_rmw(), ath9k_tasklet(), ath_read_cachesize(), ath_tx_cleanupq(), ATH_TXQ_SETUP, ath_common::bus_ops, ath_common::cachelsz, common, DBG, ath_common::dev, ath_softc::dev, ath_hw::dev, ath9k_hw_version::devid, ENOMEM, ETH_ALEN, free, ath_hw::hw_version, net80211_hw_info::hwaddr, ath_softc::hwinfo, ath_softc::intr_tq, ath_hw::led_pin, ath_common::macaddr, memcpy(), NULL, ath_common::ops, ath_common::priv, ath_ops::read, ath_hw::reg_ops, ret, ath_ops::rmw, ath_softc::sc_ah, ath9k_hw_version::subsysid, ath_softc::tx, ath_tx::txq, ath_ops::write, and zalloc().

Referenced by ath9k_init_device().

{
        struct ath_hw *ah = NULL;
        struct ath_common *common;
        int ret = 0, i;
        int csz = 0;

        ah = zalloc(sizeof(struct ath_hw));
        if (!ah)
                return -ENOMEM;

        ah->dev = sc->dev;
        ah->hw_version.devid = devid;
        ah->hw_version.subsysid = subsysid;
        ah->reg_ops.read = ath9k_ioread32;
        ah->reg_ops.write = ath9k_iowrite32;
        ah->reg_ops.rmw = ath9k_reg_rmw;
        sc->sc_ah = ah;

        sc->hwinfo = zalloc(sizeof(*sc->hwinfo));
        if (!sc->hwinfo) {
                DBG("ath9k: cannot allocate 802.11 hardware info structure\n");
                return -ENOMEM;
        }

        ah->ah_flags |= AH_USE_EEPROM;
        sc->sc_ah->led_pin = -1;

        common = ath9k_hw_common(ah);
        common->ops = &ah->reg_ops;
        common->bus_ops = bus_ops;
        common->ah = ah;
        common->dev = sc->dev;
        common->priv = sc;

        sc->intr_tq = ath9k_tasklet;

        /*
         * Cache line size is used to size and align various
         * structures used to communicate with the hardware.
         */
        ath_read_cachesize(common, &csz);
        common->cachelsz = csz << 2; /* convert to bytes */

        /* Initializes the hardware for all supported chipsets */
        ret = ath9k_hw_init(ah);
        if (ret)
                goto err_hw;

        memcpy(sc->hwinfo->hwaddr, common->macaddr, ETH_ALEN);

        ret = ath9k_init_queues(sc);
        if (ret)
                goto err_queues;

        ret = ath9k_init_channels_rates(sc);
        if (ret)
                goto err_btcoex;

        ath9k_init_crypto(sc);
        ath9k_init_misc(sc);

        return 0;

err_btcoex:
        for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
                if (ATH_TXQ_SETUP(sc, i))
                        ath_tx_cleanupq(sc, &sc->tx.txq[i]);
err_queues:
        ath9k_hw_deinit(ah);
err_hw:
        free(sc->hwinfo);
        sc->hwinfo = NULL;

        free(ah);
        sc->sc_ah = NULL;

        return ret;
}
static void ath9k_init_band_txpower ( struct ath_softc sc,
int  band 
) [static]
static void ath9k_init_txpower_limits ( struct ath_softc sc) [static]
void ath9k_set_hw_capab ( struct ath_softc sc,
struct net80211_device *dev  __unused 
)
int ath9k_init_device ( u16  devid,
struct ath_softc sc,
u16  subsysid,
const struct ath_bus_ops bus_ops 
)

Definition at line 486 of file ath9k_init.c.

References ath9k_deinit_softc(), ath9k_init_softc(), ath9k_init_txpower_limits(), ath9k_ops, ath9k_set_hw_capab(), ath_hw_pll_work(), ATH_RSSI_DUMMY_MARKER, ath_rx_cleanup(), ath_rx_init(), ATH_RXBUF, ath_tx_cleanup(), ath_tx_init(), ATH_TXBUF, ath_softc::dev, error, ath_softc::hw_pll_work, ath_softc::hwinfo, ath_softc::last_rssi, and net80211_register().

Referenced by ath_pci_probe().

{
        struct net80211_device *dev = sc->dev;
        /*struct ath_common *common;
        struct ath_hw *ah;*/
        int error = 0;
        /*struct ath_regulatory *reg;*/

        /* Bring up device */
        error = ath9k_init_softc(devid, sc, subsysid, bus_ops);
        if (error != 0)
                goto error_init;

        /*ah = sc->sc_ah;
        common = ath9k_hw_common(ah);*/
        ath9k_set_hw_capab(sc, dev);
        /* TODO Cottsay: reg */
        /* Initialize regulatory */
        /*error = ath_regd_init(&common->regulatory, sc->dev->wiphy,
                              ath9k_reg_notifier);
        if (error)
                goto error_regd;

        reg = &common->regulatory;*/

        /* Setup TX DMA */
        error = ath_tx_init(sc, ATH_TXBUF);
        if (error != 0)
                goto error_tx;

        /* Setup RX DMA */
        error = ath_rx_init(sc, ATH_RXBUF);
        if (error != 0)
                goto error_rx;

        ath9k_init_txpower_limits(sc);

        /* Register with mac80211 */
        error = net80211_register(dev, &ath9k_ops, sc->hwinfo);
        if (error)
                goto error_register;

        /* TODO Cottsay: reg */
        /* Handle world regulatory */
        /*if (!ath_is_world_regd(reg)) {
                error = regulatory_hint(hw->wiphy, reg->alpha2);
                if (error)
                        goto error_world;
        }*/

        sc->hw_pll_work = ath_hw_pll_work;
        sc->last_rssi = ATH_RSSI_DUMMY_MARKER;

        /* TODO Cottsay: rfkill */
        /*ath_start_rfkill_poll(sc);*/

        return 0;

//error_world:
//      net80211_unregister(dev);
error_register:
        ath_rx_cleanup(sc);
error_rx:
        ath_tx_cleanup(sc);
error_tx:
        ath9k_deinit_softc(sc);
error_init:
        return error;
}
void ath9k_deinit_device ( struct ath_softc sc)
void ath_descdma_cleanup ( struct ath_softc *sc  __unused,
struct ath_descdma dd,
struct list_head head 
)

Variable Documentation

Definition at line 29 of file ath9k_init.c.

Referenced by ath_pci_remove().

Initial value:
 {
        CHAN2G(2412, 0), 
        CHAN2G(2417, 1), 
        CHAN2G(2422, 2), 
        CHAN2G(2427, 3), 
        CHAN2G(2432, 4), 
        CHAN2G(2437, 5), 
        CHAN2G(2442, 6), 
        CHAN2G(2447, 7), 
        CHAN2G(2452, 8), 
        CHAN2G(2457, 9), 
        CHAN2G(2462, 10), 
        CHAN2G(2467, 11), 
        CHAN2G(2472, 12), 
        CHAN2G(2484, 13), 
}

Definition at line 50 of file ath9k_init.c.

Initial value:
 {
        
        CHAN5G(5180, 14), 
        CHAN5G(5200, 15), 
        CHAN5G(5220, 16), 
        CHAN5G(5240, 17), 
        
        CHAN5G(5260, 18), 
        CHAN5G(5280, 19), 
        CHAN5G(5300, 20), 
        CHAN5G(5320, 21), 
        
        CHAN5G(5500, 22), 
        CHAN5G(5520, 23), 
        CHAN5G(5540, 24), 
        CHAN5G(5560, 25), 
        CHAN5G(5580, 26), 
        CHAN5G(5600, 27), 
        CHAN5G(5620, 28), 
        CHAN5G(5640, 29), 
        CHAN5G(5660, 30), 
        CHAN5G(5680, 31), 
        CHAN5G(5700, 32), 
        
        CHAN5G(5745, 33), 
        CHAN5G(5765, 34), 
        CHAN5G(5785, 35), 
        CHAN5G(5805, 36), 
        CHAN5G(5825, 37), 
}

Definition at line 71 of file ath9k_init.c.

Initial value:
 {
        RATE(10, 0x1b, 0),
        RATE(20, 0x1a, IEEE80211_TX_RC_USE_SHORT_PREAMBLE),
        RATE(55, 0x19, IEEE80211_TX_RC_USE_SHORT_PREAMBLE),
        RATE(110, 0x18, IEEE80211_TX_RC_USE_SHORT_PREAMBLE),
        RATE(60, 0x0b, 0),
        RATE(90, 0x0f, 0),
        RATE(120, 0x0a, 0),
        RATE(180, 0x0e, 0),
        RATE(240, 0x09, 0),
        RATE(360, 0x0d, 0),
        RATE(480, 0x08, 0),
        RATE(540, 0x0c, 0),
}

Definition at line 113 of file ath9k_init.c.