xref: /freebsd/sys/dev/ath/if_ath_tx_edma.c (revision ba3fd9d86a83b5daf54849d28c09b066b066b488)
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