if_ath.c (238055) | if_ath.c (238284) |
---|---|
1/*- 2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 14 unchanged lines hidden (view full) --- 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 */ 29 30#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 14 unchanged lines hidden (view full) --- 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 */ 29 30#include <sys/cdefs.h> |
31__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 238055 2012-07-03 06:59:12Z adrian $"); | 31__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 238284 2012-07-09 08:37:59Z adrian $"); |
32 33/* 34 * Driver for the Atheros Wireless LAN controller. 35 * 36 * This software is derived from work of Atsushi Onoe; his contribution 37 * is greatly appreciated. 38 */ 39 --- 112 unchanged lines hidden (view full) --- 152static void ath_bmiss_proc(void *, int); 153static void ath_key_update_begin(struct ieee80211vap *); 154static void ath_key_update_end(struct ieee80211vap *); 155static void ath_update_mcast(struct ifnet *); 156static void ath_update_promisc(struct ifnet *); 157static void ath_updateslot(struct ifnet *); 158static void ath_bstuck_proc(void *, int); 159static void ath_reset_proc(void *, int); | 32 33/* 34 * Driver for the Atheros Wireless LAN controller. 35 * 36 * This software is derived from work of Atsushi Onoe; his contribution 37 * is greatly appreciated. 38 */ 39 --- 112 unchanged lines hidden (view full) --- 152static void ath_bmiss_proc(void *, int); 153static void ath_key_update_begin(struct ieee80211vap *); 154static void ath_key_update_end(struct ieee80211vap *); 155static void ath_update_mcast(struct ifnet *); 156static void ath_update_promisc(struct ifnet *); 157static void ath_updateslot(struct ifnet *); 158static void ath_bstuck_proc(void *, int); 159static void ath_reset_proc(void *, int); |
160static void ath_descdma_cleanup(struct ath_softc *sc, 161 struct ath_descdma *, ath_bufhead *); | |
162static int ath_desc_alloc(struct ath_softc *); 163static void ath_desc_free(struct ath_softc *); 164static struct ieee80211_node *ath_node_alloc(struct ieee80211vap *, 165 const uint8_t [IEEE80211_ADDR_LEN]); 166static void ath_node_cleanup(struct ieee80211_node *); 167static void ath_node_free(struct ieee80211_node *); 168static void ath_node_getsignal(const struct ieee80211_node *, 169 int8_t *, int8_t *); --- 64 unchanged lines hidden (view full) --- 234 0, "short chip calibration interval (msecs)"); 235static int ath_resetcalinterval = 20*60; /* reset cal state 20 mins */ 236SYSCTL_INT(_hw_ath, OID_AUTO, resetcal, CTLFLAG_RW, &ath_resetcalinterval, 237 0, "reset chip calibration results (secs)"); 238static int ath_anicalinterval = 100; /* ANI calibration - 100 msec */ 239SYSCTL_INT(_hw_ath, OID_AUTO, anical, CTLFLAG_RW, &ath_anicalinterval, 240 0, "ANI calibration (msecs)"); 241 | 160static int ath_desc_alloc(struct ath_softc *); 161static void ath_desc_free(struct ath_softc *); 162static struct ieee80211_node *ath_node_alloc(struct ieee80211vap *, 163 const uint8_t [IEEE80211_ADDR_LEN]); 164static void ath_node_cleanup(struct ieee80211_node *); 165static void ath_node_free(struct ieee80211_node *); 166static void ath_node_getsignal(const struct ieee80211_node *, 167 int8_t *, int8_t *); --- 64 unchanged lines hidden (view full) --- 232 0, "short chip calibration interval (msecs)"); 233static int ath_resetcalinterval = 20*60; /* reset cal state 20 mins */ 234SYSCTL_INT(_hw_ath, OID_AUTO, resetcal, CTLFLAG_RW, &ath_resetcalinterval, 235 0, "reset chip calibration results (secs)"); 236static int ath_anicalinterval = 100; /* ANI calibration - 100 msec */ 237SYSCTL_INT(_hw_ath, OID_AUTO, anical, CTLFLAG_RW, &ath_anicalinterval, 238 0, "ANI calibration (msecs)"); 239 |
242static int ath_rxbuf = ATH_RXBUF; /* # rx buffers to allocate */ | 240int ath_rxbuf = ATH_RXBUF; /* # rx buffers to allocate */ |
243SYSCTL_INT(_hw_ath, OID_AUTO, rxbuf, CTLFLAG_RW, &ath_rxbuf, 244 0, "rx buffers allocated"); 245TUNABLE_INT("hw.ath.rxbuf", &ath_rxbuf); | 241SYSCTL_INT(_hw_ath, OID_AUTO, rxbuf, CTLFLAG_RW, &ath_rxbuf, 242 0, "rx buffers allocated"); 243TUNABLE_INT("hw.ath.rxbuf", &ath_rxbuf); |
246static int ath_txbuf = ATH_TXBUF; /* # tx buffers to allocate */ | 244int ath_txbuf = ATH_TXBUF; /* # tx buffers to allocate */ |
247SYSCTL_INT(_hw_ath, OID_AUTO, txbuf, CTLFLAG_RW, &ath_txbuf, 248 0, "tx buffers allocated"); 249TUNABLE_INT("hw.ath.txbuf", &ath_txbuf); | 245SYSCTL_INT(_hw_ath, OID_AUTO, txbuf, CTLFLAG_RW, &ath_txbuf, 246 0, "tx buffers allocated"); 247TUNABLE_INT("hw.ath.txbuf", &ath_txbuf); |
250static int ath_txbuf_mgmt = ATH_MGMT_TXBUF; /* # mgmt tx buffers to allocate */ | 248int ath_txbuf_mgmt = ATH_MGMT_TXBUF; /* # mgmt tx buffers to allocate */ |
251SYSCTL_INT(_hw_ath, OID_AUTO, txbuf_mgmt, CTLFLAG_RW, &ath_txbuf_mgmt, 252 0, "tx (mgmt) buffers allocated"); 253TUNABLE_INT("hw.ath.txbuf_mgmt", &ath_txbuf_mgmt); 254 255int ath_bstuck_threshold = 4; /* max missed beacons */ 256SYSCTL_INT(_hw_ath, OID_AUTO, bstuck, CTLFLAG_RW, &ath_bstuck_threshold, 257 0, "max missed beacon xmits before chip reset"); 258 --- 44 unchanged lines hidden (view full) --- 303#endif 304 305 /* 306 * Setup the DMA/EDMA functions based on the current 307 * hardware support. 308 * 309 * This is required before the descriptors are allocated. 310 */ | 249SYSCTL_INT(_hw_ath, OID_AUTO, txbuf_mgmt, CTLFLAG_RW, &ath_txbuf_mgmt, 250 0, "tx (mgmt) buffers allocated"); 251TUNABLE_INT("hw.ath.txbuf_mgmt", &ath_txbuf_mgmt); 252 253int ath_bstuck_threshold = 4; /* max missed beacons */ 254SYSCTL_INT(_hw_ath, OID_AUTO, bstuck, CTLFLAG_RW, &ath_bstuck_threshold, 255 0, "max missed beacon xmits before chip reset"); 256 --- 44 unchanged lines hidden (view full) --- 301#endif 302 303 /* 304 * Setup the DMA/EDMA functions based on the current 305 * hardware support. 306 * 307 * This is required before the descriptors are allocated. 308 */ |
311 if (ath_hal_hasedma(sc->sc_ah)) | 309 if (ath_hal_hasedma(sc->sc_ah)) { 310 sc->sc_isedma = 1; |
312 ath_recv_setup_edma(sc); | 311 ath_recv_setup_edma(sc); |
313 else | 312 } else |
314 ath_recv_setup_legacy(sc); 315 316 /* 317 * Check if the MAC has multi-rate retry support. 318 * We do this by trying to setup a fake extended 319 * descriptor. MAC's that don't have support will 320 * return false w/o doing anything. MAC's that do 321 * support it will return true w/o doing anything. --- 51 unchanged lines hidden (view full) --- 373 /* 374 * Allocate tx+rx descriptors and populate the lists. 375 */ 376 error = ath_desc_alloc(sc); 377 if (error != 0) { 378 if_printf(ifp, "failed to allocate descriptors: %d\n", error); 379 goto bad; 380 } | 313 ath_recv_setup_legacy(sc); 314 315 /* 316 * Check if the MAC has multi-rate retry support. 317 * We do this by trying to setup a fake extended 318 * descriptor. MAC's that don't have support will 319 * return false w/o doing anything. MAC's that do 320 * support it will return true w/o doing anything. --- 51 unchanged lines hidden (view full) --- 372 /* 373 * Allocate tx+rx descriptors and populate the lists. 374 */ 375 error = ath_desc_alloc(sc); 376 if (error != 0) { 377 if_printf(ifp, "failed to allocate descriptors: %d\n", error); 378 goto bad; 379 } |
380 381 error = ath_rxdma_setup(sc); 382 if (error != 0) { 383 if_printf(ifp, "failed to allocate RX descriptors: %d\n", 384 error); 385 goto bad; 386 } 387 |
|
381 callout_init_mtx(&sc->sc_cal_ch, &sc->sc_mtx, 0); 382 callout_init_mtx(&sc->sc_wd_ch, &sc->sc_mtx, 0); 383 384 ATH_TXBUF_LOCK_INIT(sc); 385 386 sc->sc_tq = taskqueue_create("ath_taskq", M_NOWAIT, 387 taskqueue_thread_enqueue, &sc->sc_tq); 388 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, --- 460 unchanged lines hidden (view full) --- 849 850 if (bootverbose) 851 ieee80211_announce(ic); 852 ath_announce(sc); 853 return 0; 854bad2: 855 ath_tx_cleanup(sc); 856 ath_desc_free(sc); | 388 callout_init_mtx(&sc->sc_cal_ch, &sc->sc_mtx, 0); 389 callout_init_mtx(&sc->sc_wd_ch, &sc->sc_mtx, 0); 390 391 ATH_TXBUF_LOCK_INIT(sc); 392 393 sc->sc_tq = taskqueue_create("ath_taskq", M_NOWAIT, 394 taskqueue_thread_enqueue, &sc->sc_tq); 395 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, --- 460 unchanged lines hidden (view full) --- 856 857 if (bootverbose) 858 ieee80211_announce(ic); 859 ath_announce(sc); 860 return 0; 861bad2: 862 ath_tx_cleanup(sc); 863 ath_desc_free(sc); |
864 ath_rxdma_teardown(sc); |
|
857bad: 858 if (ah) 859 ath_hal_detach(ah); 860 if (ifp != NULL) 861 if_free(ifp); 862 sc->sc_invalid = 1; 863 return error; 864} --- 26 unchanged lines hidden (view full) --- 891#ifdef ATH_TX99_DIAG 892 if (sc->sc_tx99 != NULL) 893 sc->sc_tx99->detach(sc->sc_tx99); 894#endif 895 ath_rate_detach(sc->sc_rc); 896 897 ath_dfs_detach(sc); 898 ath_desc_free(sc); | 865bad: 866 if (ah) 867 ath_hal_detach(ah); 868 if (ifp != NULL) 869 if_free(ifp); 870 sc->sc_invalid = 1; 871 return error; 872} --- 26 unchanged lines hidden (view full) --- 899#ifdef ATH_TX99_DIAG 900 if (sc->sc_tx99 != NULL) 901 sc->sc_tx99->detach(sc->sc_tx99); 902#endif 903 ath_rate_detach(sc->sc_rc); 904 905 ath_dfs_detach(sc); 906 ath_desc_free(sc); |
907 ath_rxdma_teardown(sc); |
|
899 ath_tx_cleanup(sc); 900 ath_hal_detach(sc->sc_ah); /* NB: sets chip in full sleep */ 901 if_free(ifp); 902 903 return 0; 904} 905 906/* --- 1682 unchanged lines hidden (view full) --- 2589 2590 /* configure rx filter */ 2591 rfilt = ath_calcrxfilter(sc); 2592 ath_hal_setrxfilter(ah, rfilt); 2593 2594 /* configure operational mode */ 2595 ath_hal_setopmode(ah); 2596 | 908 ath_tx_cleanup(sc); 909 ath_hal_detach(sc->sc_ah); /* NB: sets chip in full sleep */ 910 if_free(ifp); 911 912 return 0; 913} 914 915/* --- 1682 unchanged lines hidden (view full) --- 2598 2599 /* configure rx filter */ 2600 rfilt = ath_calcrxfilter(sc); 2601 ath_hal_setrxfilter(ah, rfilt); 2602 2603 /* configure operational mode */ 2604 ath_hal_setopmode(ah); 2605 |
2606 DPRINTF(sc, ATH_DEBUG_STATE | ATH_DEBUG_MODE, 2607 "%s: ah=%p, ifp=%p, if_addr=%p\n", 2608 __func__, 2609 ah, 2610 ifp, 2611 (ifp == NULL) ? NULL : ifp->if_addr); 2612 |
|
2597 /* handle any link-level address change */ 2598 ath_hal_setmac(ah, IF_LLADDR(ifp)); 2599 2600 /* calculate and install multicast filter */ 2601 ath_update_mcast(ifp); 2602} 2603 2604/* --- 114 unchanged lines hidden (view full) --- 2719static void 2720ath_load_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error) 2721{ 2722 bus_addr_t *paddr = (bus_addr_t*) arg; 2723 KASSERT(error == 0, ("error %u on bus_dma callback", error)); 2724 *paddr = segs->ds_addr; 2725} 2726 | 2613 /* handle any link-level address change */ 2614 ath_hal_setmac(ah, IF_LLADDR(ifp)); 2615 2616 /* calculate and install multicast filter */ 2617 ath_update_mcast(ifp); 2618} 2619 2620/* --- 114 unchanged lines hidden (view full) --- 2735static void 2736ath_load_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error) 2737{ 2738 bus_addr_t *paddr = (bus_addr_t*) arg; 2739 KASSERT(error == 0, ("error %u on bus_dma callback", error)); 2740 *paddr = segs->ds_addr; 2741} 2742 |
2727static int | 2743int |
2728ath_descdma_setup(struct ath_softc *sc, 2729 struct ath_descdma *dd, ath_bufhead *head, 2730 const char *name, int nbuf, int ndesc) 2731{ 2732#define DS2PHYS(_dd, _ds) \ 2733 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) 2734#define ATH_DESC_4KB_BOUND_CHECK(_daddr, _len) \ 2735 ((((u_int32_t)(_daddr) & 0xFFF) > (0x1000 - (_len))) ? 1 : 0) --- 122 unchanged lines hidden (view full) --- 2858fail0: 2859 bus_dma_tag_destroy(dd->dd_dmat); 2860 memset(dd, 0, sizeof(*dd)); 2861 return error; 2862#undef DS2PHYS 2863#undef ATH_DESC_4KB_BOUND_CHECK 2864} 2865 | 2744ath_descdma_setup(struct ath_softc *sc, 2745 struct ath_descdma *dd, ath_bufhead *head, 2746 const char *name, int nbuf, int ndesc) 2747{ 2748#define DS2PHYS(_dd, _ds) \ 2749 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) 2750#define ATH_DESC_4KB_BOUND_CHECK(_daddr, _len) \ 2751 ((((u_int32_t)(_daddr) & 0xFFF) > (0x1000 - (_len))) ? 1 : 0) --- 122 unchanged lines hidden (view full) --- 2874fail0: 2875 bus_dma_tag_destroy(dd->dd_dmat); 2876 memset(dd, 0, sizeof(*dd)); 2877 return error; 2878#undef DS2PHYS 2879#undef ATH_DESC_4KB_BOUND_CHECK 2880} 2881 |
2866static void | 2882void |
2867ath_descdma_cleanup(struct ath_softc *sc, 2868 struct ath_descdma *dd, ath_bufhead *head) 2869{ 2870 struct ath_buf *bf; 2871 struct ieee80211_node *ni; 2872 2873 bus_dmamap_unload(dd->dd_dmat, dd->dd_dmamap); 2874 bus_dmamem_free(dd->dd_dmat, dd->dd_desc, dd->dd_dmamap); --- 24 unchanged lines hidden (view full) --- 2899 memset(dd, 0, sizeof(*dd)); 2900} 2901 2902static int 2903ath_desc_alloc(struct ath_softc *sc) 2904{ 2905 int error; 2906 | 2883ath_descdma_cleanup(struct ath_softc *sc, 2884 struct ath_descdma *dd, ath_bufhead *head) 2885{ 2886 struct ath_buf *bf; 2887 struct ieee80211_node *ni; 2888 2889 bus_dmamap_unload(dd->dd_dmat, dd->dd_dmamap); 2890 bus_dmamem_free(dd->dd_dmat, dd->dd_desc, dd->dd_dmamap); --- 24 unchanged lines hidden (view full) --- 2915 memset(dd, 0, sizeof(*dd)); 2916} 2917 2918static int 2919ath_desc_alloc(struct ath_softc *sc) 2920{ 2921 int error; 2922 |
2907 error = ath_descdma_setup(sc, &sc->sc_rxdma, &sc->sc_rxbuf, 2908 "rx", ath_rxbuf, 1); 2909 if (error != 0) 2910 return error; 2911 | |
2912 error = ath_descdma_setup(sc, &sc->sc_txdma, &sc->sc_txbuf, 2913 "tx", ath_txbuf, ATH_TXDESC); 2914 if (error != 0) { | 2923 error = ath_descdma_setup(sc, &sc->sc_txdma, &sc->sc_txbuf, 2924 "tx", ath_txbuf, ATH_TXDESC); 2925 if (error != 0) { |
2915 ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf); | |
2916 return error; 2917 } 2918 sc->sc_txbuf_cnt = ath_txbuf; 2919 2920 error = ath_descdma_setup(sc, &sc->sc_txdma_mgmt, &sc->sc_txbuf_mgmt, 2921 "tx_mgmt", ath_txbuf_mgmt, ATH_TXDESC); 2922 if (error != 0) { | 2926 return error; 2927 } 2928 sc->sc_txbuf_cnt = ath_txbuf; 2929 2930 error = ath_descdma_setup(sc, &sc->sc_txdma_mgmt, &sc->sc_txbuf_mgmt, 2931 "tx_mgmt", ath_txbuf_mgmt, ATH_TXDESC); 2932 if (error != 0) { |
2923 ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf); | |
2924 ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf); 2925 return error; 2926 } 2927 2928 /* 2929 * XXX mark txbuf_mgmt frames with ATH_BUF_MGMT, so the 2930 * flag doesn't have to be set in ath_getbuf_locked(). 2931 */ 2932 2933 error = ath_descdma_setup(sc, &sc->sc_bdma, &sc->sc_bbuf, 2934 "beacon", ATH_BCBUF, 1); 2935 if (error != 0) { | 2933 ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf); 2934 return error; 2935 } 2936 2937 /* 2938 * XXX mark txbuf_mgmt frames with ATH_BUF_MGMT, so the 2939 * flag doesn't have to be set in ath_getbuf_locked(). 2940 */ 2941 2942 error = ath_descdma_setup(sc, &sc->sc_bdma, &sc->sc_bbuf, 2943 "beacon", ATH_BCBUF, 1); 2944 if (error != 0) { |
2936 ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf); | |
2937 ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf); 2938 ath_descdma_cleanup(sc, &sc->sc_txdma_mgmt, 2939 &sc->sc_txbuf_mgmt); 2940 return error; 2941 } 2942 return 0; 2943} 2944 2945static void 2946ath_desc_free(struct ath_softc *sc) 2947{ 2948 2949 if (sc->sc_bdma.dd_desc_len != 0) 2950 ath_descdma_cleanup(sc, &sc->sc_bdma, &sc->sc_bbuf); 2951 if (sc->sc_txdma.dd_desc_len != 0) 2952 ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf); | 2945 ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf); 2946 ath_descdma_cleanup(sc, &sc->sc_txdma_mgmt, 2947 &sc->sc_txbuf_mgmt); 2948 return error; 2949 } 2950 return 0; 2951} 2952 2953static void 2954ath_desc_free(struct ath_softc *sc) 2955{ 2956 2957 if (sc->sc_bdma.dd_desc_len != 0) 2958 ath_descdma_cleanup(sc, &sc->sc_bdma, &sc->sc_bbuf); 2959 if (sc->sc_txdma.dd_desc_len != 0) 2960 ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf); |
2953 if (sc->sc_rxdma.dd_desc_len != 0) 2954 ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf); | |
2955 if (sc->sc_txdma_mgmt.dd_desc_len != 0) 2956 ath_descdma_cleanup(sc, &sc->sc_txdma_mgmt, 2957 &sc->sc_txbuf_mgmt); 2958} 2959 2960static struct ieee80211_node * 2961ath_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) 2962{ --- 2108 unchanged lines hidden --- | 2961 if (sc->sc_txdma_mgmt.dd_desc_len != 0) 2962 ath_descdma_cleanup(sc, &sc->sc_txdma_mgmt, 2963 &sc->sc_txbuf_mgmt); 2964} 2965 2966static struct ieee80211_node * 2967ath_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) 2968{ --- 2108 unchanged lines hidden --- |