if_ath.c (155491) | if_ath.c (155492) |
---|---|
1/*- 2 * Copyright (c) 2002-2005 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 --- 21 unchanged lines hidden (view full) --- 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 32 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 34 * THE POSSIBILITY OF SUCH DAMAGES. 35 */ 36 37#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2002-2005 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 --- 21 unchanged lines hidden (view full) --- 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 32 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 34 * THE POSSIBILITY OF SUCH DAMAGES. 35 */ 36 37#include <sys/cdefs.h> |
38__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 155491 2006-02-09 21:48:51Z sam $"); | 38__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 155492 2006-02-09 22:03:26Z sam $"); |
39 40/* 41 * Driver for the Atheros Wireless LAN controller. 42 * 43 * This software is derived from work of Atsushi Onoe; his contribution 44 * is greatly appreciated. 45 */ 46 --- 780 unchanged lines hidden (view full) --- 827{ 828 struct ath_softc *sc = arg; 829 struct ieee80211com *ic = &sc->sc_ic; 830 831 DPRINTF(sc, ATH_DEBUG_ANY, "%s: pending %u\n", __func__, pending); 832 KASSERT(ic->ic_opmode == IEEE80211_M_STA, 833 ("unexpect operating mode %u", ic->ic_opmode)); 834 if (ic->ic_state == IEEE80211_S_RUN) { | 39 40/* 41 * Driver for the Atheros Wireless LAN controller. 42 * 43 * This software is derived from work of Atsushi Onoe; his contribution 44 * is greatly appreciated. 45 */ 46 --- 780 unchanged lines hidden (view full) --- 827{ 828 struct ath_softc *sc = arg; 829 struct ieee80211com *ic = &sc->sc_ic; 830 831 DPRINTF(sc, ATH_DEBUG_ANY, "%s: pending %u\n", __func__, pending); 832 KASSERT(ic->ic_opmode == IEEE80211_M_STA, 833 ("unexpect operating mode %u", ic->ic_opmode)); 834 if (ic->ic_state == IEEE80211_S_RUN) { |
835 u_int64_t lastrx = sc->sc_lastrx; 836 u_int64_t tsf = ath_hal_gettsf64(sc->sc_ah); 837 u_int bmisstimeout = 838 ic->ic_bmissthreshold * ic->ic_bss->ni_intval * 1024; 839 840 DPRINTF(sc, ATH_DEBUG_BEACON, 841 "%s: tsf %llu lastrx %lld (%llu) bmiss %u\n", 842 __func__, (unsigned long long) tsf, 843 (unsigned long long)(tsf - lastrx), 844 (unsigned long long) lastrx, bmisstimeout); |
|
835 /* | 845 /* |
836 * Rather than go directly to scan state, try to 837 * reassociate first. If that fails then the state 838 * machine will drop us into scanning after timing 839 * out waiting for a probe response. | 846 * Workaround phantom bmiss interrupts by sanity-checking 847 * the time of our last rx'd frame. If it is within the 848 * beacon miss interval then ignore the interrupt. If it's 849 * truly a bmiss we'll get another interrupt soon and that'll 850 * be dispatched up for processing. |
840 */ | 851 */ |
841 NET_LOCK_GIANT(); 842 ieee80211_new_state(ic, IEEE80211_S_ASSOC, -1); 843 NET_UNLOCK_GIANT(); | 852 if (tsf - lastrx > bmisstimeout) { 853 NET_LOCK_GIANT(); 854 ieee80211_beacon_miss(ic); 855 NET_UNLOCK_GIANT(); 856 } else 857 sc->sc_stats.ast_bmiss_phantom++; |
844 } 845} 846 847static u_int 848ath_chan2flags(struct ieee80211com *ic, struct ieee80211_channel *chan) 849{ 850#define N(a) (sizeof(a) / sizeof(a[0])) 851 static const u_int modeflags[] = { --- 1851 unchanged lines hidden (view full) --- 2703 struct ath_buf *bf; 2704 struct ieee80211com *ic = &sc->sc_ic; 2705 struct ifnet *ifp = sc->sc_ifp; 2706 struct ath_hal *ah = sc->sc_ah; 2707 struct ath_desc *ds; 2708 struct mbuf *m; 2709 struct ieee80211_node *ni; 2710 struct ath_node *an; | 858 } 859} 860 861static u_int 862ath_chan2flags(struct ieee80211com *ic, struct ieee80211_channel *chan) 863{ 864#define N(a) (sizeof(a) / sizeof(a[0])) 865 static const u_int modeflags[] = { --- 1851 unchanged lines hidden (view full) --- 2717 struct ath_buf *bf; 2718 struct ieee80211com *ic = &sc->sc_ic; 2719 struct ifnet *ifp = sc->sc_ifp; 2720 struct ath_hal *ah = sc->sc_ah; 2721 struct ath_desc *ds; 2722 struct mbuf *m; 2723 struct ieee80211_node *ni; 2724 struct ath_node *an; |
2711 int len, type; | 2725 int len, type, ngood; |
2712 u_int phyerr; 2713 HAL_STATUS status; 2714 int16_t nf; 2715 u_int64_t tsf; 2716 2717 NET_LOCK_GIANT(); /* XXX */ 2718 2719 DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending); | 2726 u_int phyerr; 2727 HAL_STATUS status; 2728 int16_t nf; 2729 u_int64_t tsf; 2730 2731 NET_LOCK_GIANT(); /* XXX */ 2732 2733 DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending); |
2734 ngood = 0; |
|
2720 nf = ath_hal_getchannoise(ah, &sc->sc_curchan); 2721 tsf = ath_hal_gettsf64(ah); 2722 do { 2723 bf = STAILQ_FIRST(&sc->sc_rxbuf); 2724 if (bf == NULL) { /* NB: shouldn't happen */ 2725 if_printf(ifp, "%s: no buffer!\n", __func__); 2726 break; 2727 } --- 191 unchanged lines hidden (view full) --- 2919 * periodic beacon frames to trigger the poll event. 2920 */ 2921 if (type == IEEE80211_FC0_TYPE_DATA) { 2922 sc->sc_rxrate = ds->ds_rxstat.rs_rate; 2923 ath_led_event(sc, ATH_LED_RX); 2924 } else if (ticks - sc->sc_ledevent >= sc->sc_ledidle) 2925 ath_led_event(sc, ATH_LED_POLL); 2926 } | 2735 nf = ath_hal_getchannoise(ah, &sc->sc_curchan); 2736 tsf = ath_hal_gettsf64(ah); 2737 do { 2738 bf = STAILQ_FIRST(&sc->sc_rxbuf); 2739 if (bf == NULL) { /* NB: shouldn't happen */ 2740 if_printf(ifp, "%s: no buffer!\n", __func__); 2741 break; 2742 } --- 191 unchanged lines hidden (view full) --- 2934 * periodic beacon frames to trigger the poll event. 2935 */ 2936 if (type == IEEE80211_FC0_TYPE_DATA) { 2937 sc->sc_rxrate = ds->ds_rxstat.rs_rate; 2938 ath_led_event(sc, ATH_LED_RX); 2939 } else if (ticks - sc->sc_ledevent >= sc->sc_ledidle) 2940 ath_led_event(sc, ATH_LED_POLL); 2941 } |
2942 /* 2943 * Arrange to update the last rx timestamp only for 2944 * frames from our ap when operating in station mode. 2945 * This assumes the rx key is always setup when associated. 2946 */ 2947 if (ic->ic_opmode == IEEE80211_M_STA && 2948 ds->ds_rxstat.rs_keyix != HAL_RXKEYIX_INVALID) 2949 ngood++; |
|
2927rx_next: 2928 STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list); 2929 } while (ath_rxbuf_init(sc, bf) == 0); 2930 2931 /* rx signal state monitoring */ 2932 ath_hal_rxmonitor(ah, &sc->sc_halstats); | 2950rx_next: 2951 STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list); 2952 } while (ath_rxbuf_init(sc, bf) == 0); 2953 2954 /* rx signal state monitoring */ 2955 ath_hal_rxmonitor(ah, &sc->sc_halstats); |
2956 if (ngood) 2957 sc->sc_lastrx = tsf; |
|
2933 2934 NET_UNLOCK_GIANT(); /* XXX */ 2935#undef PA2DESC 2936} 2937 2938/* 2939 * Setup a h/w transmit queue. 2940 */ --- 720 unchanged lines hidden (view full) --- 3661 ATH_TXQ_UNLOCK(txq); 3662 3663 return 0; 3664} 3665 3666/* 3667 * Process completed xmit descriptors from the specified queue. 3668 */ | 2958 2959 NET_UNLOCK_GIANT(); /* XXX */ 2960#undef PA2DESC 2961} 2962 2963/* 2964 * Setup a h/w transmit queue. 2965 */ --- 720 unchanged lines hidden (view full) --- 3686 ATH_TXQ_UNLOCK(txq); 3687 3688 return 0; 3689} 3690 3691/* 3692 * Process completed xmit descriptors from the specified queue. 3693 */ |
3669static void | 3694static int |
3670ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) 3671{ 3672 struct ath_hal *ah = sc->sc_ah; 3673 struct ieee80211com *ic = &sc->sc_ic; 3674 struct ath_buf *bf; 3675 struct ath_desc *ds, *ds0; 3676 struct ieee80211_node *ni; 3677 struct ath_node *an; | 3695ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) 3696{ 3697 struct ath_hal *ah = sc->sc_ah; 3698 struct ieee80211com *ic = &sc->sc_ic; 3699 struct ath_buf *bf; 3700 struct ath_desc *ds, *ds0; 3701 struct ieee80211_node *ni; 3702 struct ath_node *an; |
3678 int sr, lr, pri; | 3703 int sr, lr, pri, nacked; |
3679 HAL_STATUS status; 3680 3681 DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s: tx queue %u head %p link %p\n", 3682 __func__, txq->axq_qnum, 3683 (caddr_t)(uintptr_t) ath_hal_gettxbuf(sc->sc_ah, txq->axq_qnum), 3684 txq->axq_link); | 3704 HAL_STATUS status; 3705 3706 DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s: tx queue %u head %p link %p\n", 3707 __func__, txq->axq_qnum, 3708 (caddr_t)(uintptr_t) ath_hal_gettxbuf(sc->sc_ah, txq->axq_qnum), 3709 txq->axq_link); |
3710 nacked = 0; |
|
3685 for (;;) { 3686 ATH_TXQ_LOCK(txq); 3687 txq->axq_intrcnt = 0; /* reset periodic desc intr count */ 3688 bf = STAILQ_FIRST(&txq->axq_q); 3689 if (bf == NULL) { 3690 txq->axq_link = NULL; 3691 ATH_TXQ_UNLOCK(txq); 3692 break; --- 40 unchanged lines hidden (view full) --- 3733 sr = ds->ds_txstat.ts_shortretry; 3734 lr = ds->ds_txstat.ts_longretry; 3735 sc->sc_stats.ast_tx_shortretry += sr; 3736 sc->sc_stats.ast_tx_longretry += lr; 3737 /* 3738 * Hand the descriptor to the rate control algorithm. 3739 */ 3740 if ((ds->ds_txstat.ts_status & HAL_TXERR_FILT) == 0 && | 3711 for (;;) { 3712 ATH_TXQ_LOCK(txq); 3713 txq->axq_intrcnt = 0; /* reset periodic desc intr count */ 3714 bf = STAILQ_FIRST(&txq->axq_q); 3715 if (bf == NULL) { 3716 txq->axq_link = NULL; 3717 ATH_TXQ_UNLOCK(txq); 3718 break; --- 40 unchanged lines hidden (view full) --- 3759 sr = ds->ds_txstat.ts_shortretry; 3760 lr = ds->ds_txstat.ts_longretry; 3761 sc->sc_stats.ast_tx_shortretry += sr; 3762 sc->sc_stats.ast_tx_longretry += lr; 3763 /* 3764 * Hand the descriptor to the rate control algorithm. 3765 */ 3766 if ((ds->ds_txstat.ts_status & HAL_TXERR_FILT) == 0 && |
3741 (bf->bf_flags & HAL_TXDESC_NOACK) == 0) | 3767 (bf->bf_flags & HAL_TXDESC_NOACK) == 0) { 3768 /* 3769 * If frame was ack'd update the last rx time 3770 * used to workaround phantom bmiss interrupts. 3771 */ 3772 if (ds->ds_txstat.ts_status == 0) 3773 nacked++; |
3742 ath_rate_tx_complete(sc, an, ds, ds0); | 3774 ath_rate_tx_complete(sc, an, ds, ds0); |
3775 } |
|
3743 /* 3744 * Reclaim reference to node. 3745 * 3746 * NB: the node may be reclaimed here if, for example 3747 * this is a DEAUTH message that was sent and the 3748 * node was timed out due to inactivity. 3749 */ 3750 ieee80211_free_node(ni); --- 4 unchanged lines hidden (view full) --- 3755 m_freem(bf->bf_m); 3756 bf->bf_m = NULL; 3757 bf->bf_node = NULL; 3758 3759 ATH_TXBUF_LOCK(sc); 3760 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list); 3761 ATH_TXBUF_UNLOCK(sc); 3762 } | 3776 /* 3777 * Reclaim reference to node. 3778 * 3779 * NB: the node may be reclaimed here if, for example 3780 * this is a DEAUTH message that was sent and the 3781 * node was timed out due to inactivity. 3782 */ 3783 ieee80211_free_node(ni); --- 4 unchanged lines hidden (view full) --- 3788 m_freem(bf->bf_m); 3789 bf->bf_m = NULL; 3790 bf->bf_node = NULL; 3791 3792 ATH_TXBUF_LOCK(sc); 3793 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list); 3794 ATH_TXBUF_UNLOCK(sc); 3795 } |
3796 return nacked; |
|
3763} 3764 | 3797} 3798 |
3799static __inline int 3800txqactive(struct ath_hal *ah, int qnum) 3801{ 3802 /* XXX not yet */ 3803 return 1; 3804} 3805 |
|
3765/* 3766 * Deferred processing of transmit interrupt; special-cased 3767 * for a single hardware transmit queue (e.g. 5210 and 5211). 3768 */ 3769static void 3770ath_tx_proc_q0(void *arg, int npending) 3771{ 3772 struct ath_softc *sc = arg; 3773 struct ifnet *ifp = sc->sc_ifp; 3774 | 3806/* 3807 * Deferred processing of transmit interrupt; special-cased 3808 * for a single hardware transmit queue (e.g. 5210 and 5211). 3809 */ 3810static void 3811ath_tx_proc_q0(void *arg, int npending) 3812{ 3813 struct ath_softc *sc = arg; 3814 struct ifnet *ifp = sc->sc_ifp; 3815 |
3775 ath_tx_processq(sc, &sc->sc_txq[0]); | 3816 if (txqactive(sc->sc_ah, 0) && ath_tx_processq(sc, &sc->sc_txq[0])) 3817 sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah); 3818 if (txqactive(sc->sc_ah, sc->sc_cabq->axq_qnum)) 3819 ath_tx_processq(sc, sc->sc_cabq); |
3776 ath_tx_processq(sc, sc->sc_cabq); 3777 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 3778 sc->sc_tx_timer = 0; 3779 3780 if (sc->sc_softled) 3781 ath_led_event(sc, ATH_LED_TX); 3782 3783 ath_start(ifp); 3784} 3785 3786/* 3787 * Deferred processing of transmit interrupt; special-cased 3788 * for four hardware queues, 0-3 (e.g. 5212 w/ WME support). 3789 */ 3790static void 3791ath_tx_proc_q0123(void *arg, int npending) 3792{ 3793 struct ath_softc *sc = arg; 3794 struct ifnet *ifp = sc->sc_ifp; | 3820 ath_tx_processq(sc, sc->sc_cabq); 3821 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 3822 sc->sc_tx_timer = 0; 3823 3824 if (sc->sc_softled) 3825 ath_led_event(sc, ATH_LED_TX); 3826 3827 ath_start(ifp); 3828} 3829 3830/* 3831 * Deferred processing of transmit interrupt; special-cased 3832 * for four hardware queues, 0-3 (e.g. 5212 w/ WME support). 3833 */ 3834static void 3835ath_tx_proc_q0123(void *arg, int npending) 3836{ 3837 struct ath_softc *sc = arg; 3838 struct ifnet *ifp = sc->sc_ifp; |
3839 int nacked; |
|
3795 3796 /* 3797 * Process each active queue. 3798 */ | 3840 3841 /* 3842 * Process each active queue. 3843 */ |
3799 ath_tx_processq(sc, &sc->sc_txq[0]); 3800 ath_tx_processq(sc, &sc->sc_txq[1]); 3801 ath_tx_processq(sc, &sc->sc_txq[2]); 3802 ath_tx_processq(sc, &sc->sc_txq[3]); 3803 ath_tx_processq(sc, sc->sc_cabq); | 3844 nacked = 0; 3845 if (txqactive(sc->sc_ah, 0)) 3846 nacked += ath_tx_processq(sc, &sc->sc_txq[0]); 3847 if (txqactive(sc->sc_ah, 1)) 3848 nacked += ath_tx_processq(sc, &sc->sc_txq[1]); 3849 if (txqactive(sc->sc_ah, 2)) 3850 nacked += ath_tx_processq(sc, &sc->sc_txq[2]); 3851 if (txqactive(sc->sc_ah, 3)) 3852 nacked += ath_tx_processq(sc, &sc->sc_txq[3]); 3853 if (txqactive(sc->sc_ah, sc->sc_cabq->axq_qnum)) 3854 ath_tx_processq(sc, sc->sc_cabq); 3855 if (nacked) 3856 sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah); |
3804 3805 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 3806 sc->sc_tx_timer = 0; 3807 3808 if (sc->sc_softled) 3809 ath_led_event(sc, ATH_LED_TX); 3810 3811 ath_start(ifp); 3812} 3813 3814/* 3815 * Deferred processing of transmit interrupt. 3816 */ 3817static void 3818ath_tx_proc(void *arg, int npending) 3819{ 3820 struct ath_softc *sc = arg; 3821 struct ifnet *ifp = sc->sc_ifp; | 3857 3858 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 3859 sc->sc_tx_timer = 0; 3860 3861 if (sc->sc_softled) 3862 ath_led_event(sc, ATH_LED_TX); 3863 3864 ath_start(ifp); 3865} 3866 3867/* 3868 * Deferred processing of transmit interrupt. 3869 */ 3870static void 3871ath_tx_proc(void *arg, int npending) 3872{ 3873 struct ath_softc *sc = arg; 3874 struct ifnet *ifp = sc->sc_ifp; |
3822 int i; | 3875 int i, nacked; |
3823 3824 /* 3825 * Process each active queue. 3826 */ | 3876 3877 /* 3878 * Process each active queue. 3879 */ |
3827 /* XXX faster to read ISR_S0_S and ISR_S1_S to determine q's? */ | 3880 nacked = 0; |
3828 for (i = 0; i < HAL_NUM_TX_QUEUES; i++) | 3881 for (i = 0; i < HAL_NUM_TX_QUEUES; i++) |
3829 if (ATH_TXQ_SETUP(sc, i)) 3830 ath_tx_processq(sc, &sc->sc_txq[i]); | 3882 if (ATH_TXQ_SETUP(sc, i) && txqactive(sc->sc_ah, i)) 3883 nacked += ath_tx_processq(sc, &sc->sc_txq[i]); 3884 if (nacked) 3885 sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah); |
3831 3832 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 3833 sc->sc_tx_timer = 0; 3834 3835 if (sc->sc_softled) 3836 ath_led_event(sc, ATH_LED_TX); 3837 3838 ath_start(ifp); --- 1269 unchanged lines hidden --- | 3886 3887 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 3888 sc->sc_tx_timer = 0; 3889 3890 if (sc->sc_softled) 3891 ath_led_event(sc, ATH_LED_TX); 3892 3893 ath_start(ifp); --- 1269 unchanged lines hidden --- |