13fdfc330SAdrian Chadd /*- 23fdfc330SAdrian Chadd * Copyright (c) 2012 Adrian Chadd <adrian@FreeBSD.org> 33fdfc330SAdrian Chadd * All rights reserved. 43fdfc330SAdrian Chadd * 53fdfc330SAdrian Chadd * Redistribution and use in source and binary forms, with or without 63fdfc330SAdrian Chadd * modification, are permitted provided that the following conditions 73fdfc330SAdrian Chadd * are met: 83fdfc330SAdrian Chadd * 1. Redistributions of source code must retain the above copyright 93fdfc330SAdrian Chadd * notice, this list of conditions and the following disclaimer, 103fdfc330SAdrian Chadd * without modification. 113fdfc330SAdrian Chadd * 2. Redistributions in binary form must reproduce at minimum a disclaimer 123fdfc330SAdrian Chadd * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 133fdfc330SAdrian Chadd * redistribution must be conditioned upon including a substantially 143fdfc330SAdrian Chadd * similar Disclaimer requirement for further binary redistribution. 153fdfc330SAdrian Chadd * 163fdfc330SAdrian Chadd * NO WARRANTY 173fdfc330SAdrian Chadd * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 183fdfc330SAdrian Chadd * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 193fdfc330SAdrian Chadd * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 203fdfc330SAdrian Chadd * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 213fdfc330SAdrian Chadd * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 223fdfc330SAdrian Chadd * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 233fdfc330SAdrian Chadd * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 243fdfc330SAdrian Chadd * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 253fdfc330SAdrian Chadd * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 263fdfc330SAdrian Chadd * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 273fdfc330SAdrian Chadd * THE POSSIBILITY OF SUCH DAMAGES. 283fdfc330SAdrian Chadd */ 293fdfc330SAdrian Chadd 303fdfc330SAdrian Chadd #include <sys/cdefs.h> 313fdfc330SAdrian Chadd __FBSDID("$FreeBSD$"); 323fdfc330SAdrian Chadd 333fdfc330SAdrian Chadd /* 343fdfc330SAdrian Chadd * Driver for the Atheros Wireless LAN controller. 353fdfc330SAdrian Chadd * 363fdfc330SAdrian Chadd * This software is derived from work of Atsushi Onoe; his contribution 373fdfc330SAdrian Chadd * is greatly appreciated. 383fdfc330SAdrian Chadd */ 393fdfc330SAdrian Chadd 403fdfc330SAdrian Chadd #include "opt_inet.h" 413fdfc330SAdrian Chadd #include "opt_ath.h" 423fdfc330SAdrian Chadd /* 433fdfc330SAdrian Chadd * This is needed for register operations which are performed 443fdfc330SAdrian Chadd * by the driver - eg, calls to ath_hal_gettsf32(). 453fdfc330SAdrian Chadd * 463fdfc330SAdrian Chadd * It's also required for any AH_DEBUG checks in here, eg the 473fdfc330SAdrian Chadd * module dependencies. 483fdfc330SAdrian Chadd */ 493fdfc330SAdrian Chadd #include "opt_ah.h" 503fdfc330SAdrian Chadd #include "opt_wlan.h" 513fdfc330SAdrian Chadd 523fdfc330SAdrian Chadd #include <sys/param.h> 533fdfc330SAdrian Chadd #include <sys/systm.h> 543fdfc330SAdrian Chadd #include <sys/sysctl.h> 553fdfc330SAdrian Chadd #include <sys/mbuf.h> 563fdfc330SAdrian Chadd #include <sys/malloc.h> 573fdfc330SAdrian Chadd #include <sys/lock.h> 583fdfc330SAdrian Chadd #include <sys/mutex.h> 593fdfc330SAdrian Chadd #include <sys/kernel.h> 603fdfc330SAdrian Chadd #include <sys/socket.h> 613fdfc330SAdrian Chadd #include <sys/sockio.h> 623fdfc330SAdrian Chadd #include <sys/errno.h> 633fdfc330SAdrian Chadd #include <sys/callout.h> 643fdfc330SAdrian Chadd #include <sys/bus.h> 653fdfc330SAdrian Chadd #include <sys/endian.h> 663fdfc330SAdrian Chadd #include <sys/kthread.h> 673fdfc330SAdrian Chadd #include <sys/taskqueue.h> 683fdfc330SAdrian Chadd #include <sys/priv.h> 693fdfc330SAdrian Chadd #include <sys/module.h> 703fdfc330SAdrian Chadd #include <sys/ktr.h> 713fdfc330SAdrian Chadd #include <sys/smp.h> /* for mp_ncpus */ 723fdfc330SAdrian Chadd 733fdfc330SAdrian Chadd #include <machine/bus.h> 743fdfc330SAdrian Chadd 753fdfc330SAdrian Chadd #include <net/if.h> 763fdfc330SAdrian Chadd #include <net/if_dl.h> 773fdfc330SAdrian Chadd #include <net/if_media.h> 783fdfc330SAdrian Chadd #include <net/if_types.h> 793fdfc330SAdrian Chadd #include <net/if_arp.h> 803fdfc330SAdrian Chadd #include <net/ethernet.h> 813fdfc330SAdrian Chadd #include <net/if_llc.h> 823fdfc330SAdrian Chadd 833fdfc330SAdrian Chadd #include <net80211/ieee80211_var.h> 843fdfc330SAdrian Chadd #include <net80211/ieee80211_regdomain.h> 853fdfc330SAdrian Chadd #ifdef IEEE80211_SUPPORT_SUPERG 863fdfc330SAdrian Chadd #include <net80211/ieee80211_superg.h> 873fdfc330SAdrian Chadd #endif 883fdfc330SAdrian Chadd #ifdef IEEE80211_SUPPORT_TDMA 893fdfc330SAdrian Chadd #include <net80211/ieee80211_tdma.h> 903fdfc330SAdrian Chadd #endif 913fdfc330SAdrian Chadd 923fdfc330SAdrian Chadd #include <net/bpf.h> 933fdfc330SAdrian Chadd 943fdfc330SAdrian Chadd #ifdef INET 953fdfc330SAdrian Chadd #include <netinet/in.h> 963fdfc330SAdrian Chadd #include <netinet/if_ether.h> 973fdfc330SAdrian Chadd #endif 983fdfc330SAdrian Chadd 993fdfc330SAdrian Chadd #include <dev/ath/if_athvar.h> 1003fdfc330SAdrian Chadd #include <dev/ath/ath_hal/ah_devid.h> /* XXX for softled */ 1013fdfc330SAdrian Chadd #include <dev/ath/ath_hal/ah_diagcodes.h> 1023fdfc330SAdrian Chadd 1033fdfc330SAdrian Chadd #include <dev/ath/if_ath_debug.h> 1043fdfc330SAdrian Chadd #include <dev/ath/if_ath_misc.h> 1053fdfc330SAdrian Chadd #include <dev/ath/if_ath_tsf.h> 1063fdfc330SAdrian Chadd #include <dev/ath/if_ath_tx.h> 1073fdfc330SAdrian Chadd #include <dev/ath/if_ath_sysctl.h> 1083fdfc330SAdrian Chadd #include <dev/ath/if_ath_led.h> 1093fdfc330SAdrian Chadd #include <dev/ath/if_ath_keycache.h> 1103fdfc330SAdrian Chadd #include <dev/ath/if_ath_rx.h> 1113fdfc330SAdrian Chadd #include <dev/ath/if_ath_beacon.h> 1123fdfc330SAdrian Chadd #include <dev/ath/if_athdfs.h> 1133fdfc330SAdrian Chadd 1143fdfc330SAdrian Chadd #ifdef ATH_TX99_DIAG 1153fdfc330SAdrian Chadd #include <dev/ath/ath_tx99/ath_tx99.h> 1163fdfc330SAdrian Chadd #endif 1173fdfc330SAdrian Chadd 1183fdfc330SAdrian Chadd #include <dev/ath/if_ath_tx_edma.h> 1193fdfc330SAdrian Chadd 1203fdfc330SAdrian Chadd /* 1213fdfc330SAdrian Chadd * some general macros 1223fdfc330SAdrian Chadd */ 1233fdfc330SAdrian Chadd #define INCR(_l, _sz) (_l) ++; (_l) &= ((_sz) - 1) 1243fdfc330SAdrian Chadd #define DECR(_l, _sz) (_l) --; (_l) &= ((_sz) - 1) 1253fdfc330SAdrian Chadd 126*ba3fd9d8SAdrian Chadd /* 127*ba3fd9d8SAdrian Chadd * XXX doesn't belong here, and should be tunable 128*ba3fd9d8SAdrian Chadd */ 129*ba3fd9d8SAdrian Chadd #define ATH_TXSTATUS_RING_SIZE 512 130*ba3fd9d8SAdrian Chadd 1313fdfc330SAdrian Chadd MALLOC_DECLARE(M_ATHDEV); 1323fdfc330SAdrian Chadd 1333fdfc330SAdrian Chadd static int 1343fdfc330SAdrian Chadd ath_edma_dma_txsetup(struct ath_softc *sc) 1353fdfc330SAdrian Chadd { 136*ba3fd9d8SAdrian Chadd int error; 1373fdfc330SAdrian Chadd 138*ba3fd9d8SAdrian Chadd error = ath_descdma_alloc_desc(sc, &sc->sc_txsdma, 139*ba3fd9d8SAdrian Chadd NULL, "txcomp", sc->sc_tx_statuslen, ATH_TXSTATUS_RING_SIZE); 140*ba3fd9d8SAdrian Chadd if (error != 0) 141*ba3fd9d8SAdrian Chadd return (error); 142*ba3fd9d8SAdrian Chadd 143*ba3fd9d8SAdrian Chadd ath_hal_setuptxstatusring(sc->sc_ah, 144*ba3fd9d8SAdrian Chadd (void *) sc->sc_txsdma.dd_desc, 145*ba3fd9d8SAdrian Chadd sc->sc_txsdma.dd_desc_paddr, 146*ba3fd9d8SAdrian Chadd ATH_TXSTATUS_RING_SIZE); 147*ba3fd9d8SAdrian Chadd 148*ba3fd9d8SAdrian Chadd 1493fdfc330SAdrian Chadd return (0); 1503fdfc330SAdrian Chadd } 1513fdfc330SAdrian Chadd 1523fdfc330SAdrian Chadd static int 1533fdfc330SAdrian Chadd ath_edma_dma_txteardown(struct ath_softc *sc) 1543fdfc330SAdrian Chadd { 1553fdfc330SAdrian Chadd 156*ba3fd9d8SAdrian Chadd ath_descdma_cleanup(sc, &sc->sc_txsdma, NULL); 1573fdfc330SAdrian Chadd return (0); 1583fdfc330SAdrian Chadd } 1593fdfc330SAdrian Chadd 1603fdfc330SAdrian Chadd void 1613fdfc330SAdrian Chadd ath_xmit_setup_edma(struct ath_softc *sc) 1623fdfc330SAdrian Chadd { 1633fdfc330SAdrian Chadd 1643fdfc330SAdrian Chadd /* Fetch EDMA field and buffer sizes */ 1653fdfc330SAdrian Chadd (void) ath_hal_gettxdesclen(sc->sc_ah, &sc->sc_tx_desclen); 1663fdfc330SAdrian Chadd (void) ath_hal_gettxstatuslen(sc->sc_ah, &sc->sc_tx_statuslen); 1673fdfc330SAdrian Chadd (void) ath_hal_getntxmaps(sc->sc_ah, &sc->sc_tx_nmaps); 1683fdfc330SAdrian Chadd 1693fdfc330SAdrian Chadd device_printf(sc->sc_dev, "TX descriptor length: %d\n", 1703fdfc330SAdrian Chadd sc->sc_tx_desclen); 1713fdfc330SAdrian Chadd device_printf(sc->sc_dev, "TX status length: %d\n", 1723fdfc330SAdrian Chadd sc->sc_tx_statuslen); 1733fdfc330SAdrian Chadd device_printf(sc->sc_dev, "TX buffers per descriptor: %d\n", 1743fdfc330SAdrian Chadd sc->sc_tx_nmaps); 1753fdfc330SAdrian Chadd 1763fdfc330SAdrian Chadd sc->sc_tx.xmit_setup = ath_edma_dma_txsetup; 1773fdfc330SAdrian Chadd sc->sc_tx.xmit_teardown = ath_edma_dma_txteardown; 1783fdfc330SAdrian Chadd } 179