Deleted Added
full compact
if_ath.c (185745) if_ath.c (186904)
1/*-
1/*-
2 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
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
9 * notice, this list of conditions and the following disclaimer,
10 * without modification.

--- 12 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>
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
9 * notice, this list of conditions and the following disclaimer,
10 * without modification.

--- 12 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 185745 2008-12-07 19:29:11Z sam $");
31__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 186904 2009-01-08 17:12:47Z sam $");
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

--- 23 unchanged lines hidden (view full) ---

63#include <net/if_dl.h>
64#include <net/if_media.h>
65#include <net/if_types.h>
66#include <net/if_arp.h>
67#include <net/ethernet.h>
68#include <net/if_llc.h>
69
70#include <net80211/ieee80211_var.h>
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

--- 23 unchanged lines hidden (view full) ---

63#include <net/if_dl.h>
64#include <net/if_media.h>
65#include <net/if_types.h>
66#include <net/if_arp.h>
67#include <net/ethernet.h>
68#include <net/if_llc.h>
69
70#include <net80211/ieee80211_var.h>
71#ifdef ATH_SUPPORT_TDMA
72#include <net80211/ieee80211_tdma.h>
73#endif
71
72#include <net/bpf.h>
73
74#ifdef INET
75#include <netinet/in.h>
76#include <netinet/if_ether.h>
77#endif
78

--- 132 unchanged lines hidden (view full) ---

211static void ath_setcurmode(struct ath_softc *, enum ieee80211_phymode);
212
213static void ath_sysctlattach(struct ath_softc *);
214static int ath_raw_xmit(struct ieee80211_node *,
215 struct mbuf *, const struct ieee80211_bpf_params *);
216static void ath_bpfattach(struct ath_softc *);
217static void ath_announce(struct ath_softc *);
218
74
75#include <net/bpf.h>
76
77#ifdef INET
78#include <netinet/in.h>
79#include <netinet/if_ether.h>
80#endif
81

--- 132 unchanged lines hidden (view full) ---

214static void ath_setcurmode(struct ath_softc *, enum ieee80211_phymode);
215
216static void ath_sysctlattach(struct ath_softc *);
217static int ath_raw_xmit(struct ieee80211_node *,
218 struct mbuf *, const struct ieee80211_bpf_params *);
219static void ath_bpfattach(struct ath_softc *);
220static void ath_announce(struct ath_softc *);
221
222#ifdef ATH_SUPPORT_TDMA
223static void ath_tdma_settimers(struct ath_softc *sc, u_int32_t nexttbtt,
224 u_int32_t bintval);
225static void ath_tdma_bintvalsetup(struct ath_softc *sc,
226 const struct ieee80211_tdma_state *tdma);
227static void ath_tdma_config(struct ath_softc *sc, struct ieee80211vap *vap);
228static void ath_tdma_update(struct ieee80211_node *ni,
229 const struct ieee80211_tdma_param *tdma);
230static void ath_tdma_beacon_send(struct ath_softc *sc,
231 struct ieee80211vap *vap);
232
233static __inline void
234ath_hal_setcca(struct ath_hal *ah, int ena)
235{
236 /*
237 * NB: fill me in; this is not provided by default because disabling
238 * CCA in most locales violates regulatory.
239 */
240}
241
242static __inline int
243ath_hal_getcca(struct ath_hal *ah)
244{
245 u_int32_t diag;
246 if (ath_hal_getcapability(ah, HAL_CAP_DIAG, 0, &diag) != HAL_OK)
247 return 1;
248 return ((diag & 0x500000) == 0);
249}
250
251#define TDMA_EP_MULTIPLIER (1<<10) /* pow2 to optimize out * and / */
252#define TDMA_LPF_LEN 6
253#define TDMA_DUMMY_MARKER 0x127
254#define TDMA_EP_MUL(x, mul) ((x) * (mul))
255#define TDMA_IN(x) (TDMA_EP_MUL((x), TDMA_EP_MULTIPLIER))
256#define TDMA_LPF(x, y, len) \
257 ((x != TDMA_DUMMY_MARKER) ? (((x) * ((len)-1) + (y)) / (len)) : (y))
258#define TDMA_SAMPLE(x, y) do { \
259 x = TDMA_LPF((x), TDMA_IN(y), TDMA_LPF_LEN); \
260} while (0)
261#define TDMA_EP_RND(x,mul) \
262 ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
263#define TDMA_AVG(x) TDMA_EP_RND(x, TDMA_EP_MULTIPLIER)
264#endif /* ATH_SUPPORT_TDMA */
265
219SYSCTL_DECL(_hw_ath);
220
221/* XXX validate sysctl values */
222static int ath_longcalinterval = 30; /* long cals every 30 secs */
223SYSCTL_INT(_hw_ath, OID_AUTO, longcal, CTLFLAG_RW, &ath_longcalinterval,
224 0, "long chip calibration interval (secs)");
225static int ath_shortcalinterval = 100; /* short cals every 100 ms */
226SYSCTL_INT(_hw_ath, OID_AUTO, shortcal, CTLFLAG_RW, &ath_shortcalinterval,

--- 28 unchanged lines hidden (view full) ---

255 ATH_DEBUG_BEACON_PROC = 0x00008000, /* beacon ISR proc */
256 ATH_DEBUG_CALIBRATE = 0x00010000, /* periodic calibration */
257 ATH_DEBUG_KEYCACHE = 0x00020000, /* key cache management */
258 ATH_DEBUG_STATE = 0x00040000, /* 802.11 state transitions */
259 ATH_DEBUG_NODE = 0x00080000, /* node management */
260 ATH_DEBUG_LED = 0x00100000, /* led management */
261 ATH_DEBUG_FF = 0x00200000, /* fast frames */
262 ATH_DEBUG_DFS = 0x00400000, /* DFS processing */
266SYSCTL_DECL(_hw_ath);
267
268/* XXX validate sysctl values */
269static int ath_longcalinterval = 30; /* long cals every 30 secs */
270SYSCTL_INT(_hw_ath, OID_AUTO, longcal, CTLFLAG_RW, &ath_longcalinterval,
271 0, "long chip calibration interval (secs)");
272static int ath_shortcalinterval = 100; /* short cals every 100 ms */
273SYSCTL_INT(_hw_ath, OID_AUTO, shortcal, CTLFLAG_RW, &ath_shortcalinterval,

--- 28 unchanged lines hidden (view full) ---

302 ATH_DEBUG_BEACON_PROC = 0x00008000, /* beacon ISR proc */
303 ATH_DEBUG_CALIBRATE = 0x00010000, /* periodic calibration */
304 ATH_DEBUG_KEYCACHE = 0x00020000, /* key cache management */
305 ATH_DEBUG_STATE = 0x00040000, /* 802.11 state transitions */
306 ATH_DEBUG_NODE = 0x00080000, /* node management */
307 ATH_DEBUG_LED = 0x00100000, /* led management */
308 ATH_DEBUG_FF = 0x00200000, /* fast frames */
309 ATH_DEBUG_DFS = 0x00400000, /* DFS processing */
310 ATH_DEBUG_TDMA = 0x00800000, /* TDMA processing */
311 ATH_DEBUG_TDMA_TIMER = 0x01000000, /* TDMA timer processing */
263 ATH_DEBUG_REGDOMAIN = 0x02000000, /* regulatory processing */
264 ATH_DEBUG_FATAL = 0x80000000, /* fatal errors */
265 ATH_DEBUG_ANY = 0xffffffff
266};
267static int ath_debug = 0;
268SYSCTL_INT(_hw_ath, OID_AUTO, debug, CTLFLAG_RW, &ath_debug,
269 0, "control debugging printfs");
270TUNABLE_INT("hw.ath.debug", &ath_debug);

--- 339 unchanged lines hidden (view full) ---

610 ic->ic_caps |= IEEE80211_C_BURST;
611 sc->sc_hasbmask = ath_hal_hasbssidmask(ah);
612 sc->sc_hastsfadd = ath_hal_hastsfadjust(ah);
613 if (ath_hal_hasfastframes(ah))
614 ic->ic_caps |= IEEE80211_C_FF;
615 wmodes = ath_hal_getwirelessmodes(ah, ic->ic_regdomain.country);
616 if (wmodes & (HAL_MODE_108G|HAL_MODE_TURBO))
617 ic->ic_caps |= IEEE80211_C_TURBOP;
312 ATH_DEBUG_REGDOMAIN = 0x02000000, /* regulatory processing */
313 ATH_DEBUG_FATAL = 0x80000000, /* fatal errors */
314 ATH_DEBUG_ANY = 0xffffffff
315};
316static int ath_debug = 0;
317SYSCTL_INT(_hw_ath, OID_AUTO, debug, CTLFLAG_RW, &ath_debug,
318 0, "control debugging printfs");
319TUNABLE_INT("hw.ath.debug", &ath_debug);

--- 339 unchanged lines hidden (view full) ---

659 ic->ic_caps |= IEEE80211_C_BURST;
660 sc->sc_hasbmask = ath_hal_hasbssidmask(ah);
661 sc->sc_hastsfadd = ath_hal_hastsfadjust(ah);
662 if (ath_hal_hasfastframes(ah))
663 ic->ic_caps |= IEEE80211_C_FF;
664 wmodes = ath_hal_getwirelessmodes(ah, ic->ic_regdomain.country);
665 if (wmodes & (HAL_MODE_108G|HAL_MODE_TURBO))
666 ic->ic_caps |= IEEE80211_C_TURBOP;
618
667#ifdef ATH_SUPPORT_TDMA
668 if (ath_hal_macversion(ah) > 0x78) {
669 ic->ic_caps |= IEEE80211_C_TDMA; /* capable of TDMA */
670 ic->ic_tdma_update = ath_tdma_update;
671 }
672#endif
619 /*
620 * Indicate we need the 802.11 header padded to a
621 * 32-bit boundary for 4-address and QoS frames.
622 */
623 ic->ic_flags |= IEEE80211_F_DATAPAD;
624
625 /*
626 * Query the hal about antenna support.

--- 192 unchanged lines hidden (view full) ---

819 }
820 if (sc->sc_nvaps) {
821 /*
822 * When there are multiple vaps we must fall
823 * back to s/w beacon miss handling.
824 */
825 flags |= IEEE80211_CLONE_NOBEACONS;
826 }
673 /*
674 * Indicate we need the 802.11 header padded to a
675 * 32-bit boundary for 4-address and QoS frames.
676 */
677 ic->ic_flags |= IEEE80211_F_DATAPAD;
678
679 /*
680 * Query the hal about antenna support.

--- 192 unchanged lines hidden (view full) ---

873 }
874 if (sc->sc_nvaps) {
875 /*
876 * When there are multiple vaps we must fall
877 * back to s/w beacon miss handling.
878 */
879 flags |= IEEE80211_CLONE_NOBEACONS;
880 }
827 if (flags & IEEE80211_CLONE_NOBEACONS) {
828 sc->sc_swbmiss = 1;
881 if (flags & IEEE80211_CLONE_NOBEACONS)
829 ic_opmode = IEEE80211_M_HOSTAP;
882 ic_opmode = IEEE80211_M_HOSTAP;
830 } else
883 else
831 ic_opmode = opmode;
832 break;
833 case IEEE80211_M_IBSS:
834 if (sc->sc_nvaps != 0) { /* XXX only 1 for now */
835 device_printf(sc->sc_dev,
836 "only 1 ibss vap supported\n");
837 goto bad;
838 }
839 ic_opmode = opmode;
840 needbeacon = 1;
841 break;
842 case IEEE80211_M_AHDEMO:
884 ic_opmode = opmode;
885 break;
886 case IEEE80211_M_IBSS:
887 if (sc->sc_nvaps != 0) { /* XXX only 1 for now */
888 device_printf(sc->sc_dev,
889 "only 1 ibss vap supported\n");
890 goto bad;
891 }
892 ic_opmode = opmode;
893 needbeacon = 1;
894 break;
895 case IEEE80211_M_AHDEMO:
896#ifdef ATH_SUPPORT_TDMA
897 if (flags & IEEE80211_CLONE_TDMA) {
898 needbeacon = 1;
899 flags |= IEEE80211_CLONE_NOBEACONS;
900 }
843 /* fall thru... */
901 /* fall thru... */
902#endif
844 case IEEE80211_M_MONITOR:
845 if (sc->sc_nvaps != 0 && ic->ic_opmode != opmode) {
846 /* XXX not right for monitor mode */
847 ic_opmode = ic->ic_opmode;
848 } else
849 ic_opmode = opmode;
850 break;
851 case IEEE80211_M_HOSTAP:

--- 102 unchanged lines hidden (view full) ---

954 switch (ic_opmode) {
955 case IEEE80211_M_IBSS:
956 sc->sc_opmode = HAL_M_IBSS;
957 break;
958 case IEEE80211_M_STA:
959 sc->sc_opmode = HAL_M_STA;
960 break;
961 case IEEE80211_M_AHDEMO:
903 case IEEE80211_M_MONITOR:
904 if (sc->sc_nvaps != 0 && ic->ic_opmode != opmode) {
905 /* XXX not right for monitor mode */
906 ic_opmode = ic->ic_opmode;
907 } else
908 ic_opmode = opmode;
909 break;
910 case IEEE80211_M_HOSTAP:

--- 102 unchanged lines hidden (view full) ---

1013 switch (ic_opmode) {
1014 case IEEE80211_M_IBSS:
1015 sc->sc_opmode = HAL_M_IBSS;
1016 break;
1017 case IEEE80211_M_STA:
1018 sc->sc_opmode = HAL_M_STA;
1019 break;
1020 case IEEE80211_M_AHDEMO:
1021#ifdef ATH_SUPPORT_TDMA
1022 if (vap->iv_caps & IEEE80211_C_TDMA) {
1023 sc->sc_tdma = 1;
1024 /* NB: disable tsf adjust */
1025 sc->sc_stagbeacons = 0;
1026 }
1027 /*
1028 * NB: adhoc demo mode is a pseudo mode; to the hal it's
1029 * just ap mode.
1030 */
1031 /* fall thru... */
1032#endif
962 case IEEE80211_M_HOSTAP:
963 sc->sc_opmode = HAL_M_HOSTAP;
964 break;
965 case IEEE80211_M_MONITOR:
966 sc->sc_opmode = HAL_M_MONITOR;
967 break;
968 default:
969 /* XXX should not happen */
970 break;
971 }
972 if (sc->sc_hastsfadd) {
973 /*
974 * Configure whether or not TSF adjust should be done.
975 */
976 ath_hal_settsfadjust(sc->sc_ah, sc->sc_stagbeacons);
977 }
1033 case IEEE80211_M_HOSTAP:
1034 sc->sc_opmode = HAL_M_HOSTAP;
1035 break;
1036 case IEEE80211_M_MONITOR:
1037 sc->sc_opmode = HAL_M_MONITOR;
1038 break;
1039 default:
1040 /* XXX should not happen */
1041 break;
1042 }
1043 if (sc->sc_hastsfadd) {
1044 /*
1045 * Configure whether or not TSF adjust should be done.
1046 */
1047 ath_hal_settsfadjust(sc->sc_ah, sc->sc_stagbeacons);
1048 }
1049 if (flags & IEEE80211_CLONE_NOBEACONS) {
1050 /*
1051 * Enable s/w beacon miss handling.
1052 */
1053 sc->sc_swbmiss = 1;
1054 }
978 ATH_UNLOCK(sc);
979
980 /* complete setup */
981 ieee80211_vap_attach(vap, ath_media_change, ieee80211_media_status);
982 return vap;
983bad2:
984 reclaim_address(sc, mac);
985 ath_hal_setbssidmask(sc->sc_ah, sc->sc_hwbssidmask);

--- 56 unchanged lines hidden (view full) ---

1042 if (sc->sc_nstavaps == 0 && sc->sc_swbmiss)
1043 sc->sc_swbmiss = 0;
1044 } else if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
1045 reclaim_address(sc, vap->iv_myaddr);
1046 ath_hal_setbssidmask(ah, sc->sc_hwbssidmask);
1047 }
1048 if (vap->iv_opmode != IEEE80211_M_WDS)
1049 sc->sc_nvaps--;
1055 ATH_UNLOCK(sc);
1056
1057 /* complete setup */
1058 ieee80211_vap_attach(vap, ath_media_change, ieee80211_media_status);
1059 return vap;
1060bad2:
1061 reclaim_address(sc, mac);
1062 ath_hal_setbssidmask(sc->sc_ah, sc->sc_hwbssidmask);

--- 56 unchanged lines hidden (view full) ---

1119 if (sc->sc_nstavaps == 0 && sc->sc_swbmiss)
1120 sc->sc_swbmiss = 0;
1121 } else if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
1122 reclaim_address(sc, vap->iv_myaddr);
1123 ath_hal_setbssidmask(ah, sc->sc_hwbssidmask);
1124 }
1125 if (vap->iv_opmode != IEEE80211_M_WDS)
1126 sc->sc_nvaps--;
1127#ifdef ATH_SUPPORT_TDMA
1128 /* TDMA operation ceases when the last vap is destroyed */
1129 if (sc->sc_tdma && sc->sc_nvaps == 0) {
1130 sc->sc_tdma = 0;
1131 sc->sc_swbmiss = 0;
1132 }
1133#endif
1050 ATH_UNLOCK(sc);
1051 free(avp, M_80211_VAP);
1052
1053 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1054 /*
1055 * Restart rx+tx machines if still running (RUNNING will
1056 * be reset if we just destroyed the last vap).
1057 */

--- 135 unchanged lines hidden (view full) ---

1193 } else {
1194 if (status & HAL_INT_SWBA) {
1195 /*
1196 * Software beacon alert--time to send a beacon.
1197 * Handle beacon transmission directly; deferring
1198 * this is too slow to meet timing constraints
1199 * under load.
1200 */
1134 ATH_UNLOCK(sc);
1135 free(avp, M_80211_VAP);
1136
1137 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1138 /*
1139 * Restart rx+tx machines if still running (RUNNING will
1140 * be reset if we just destroyed the last vap).
1141 */

--- 135 unchanged lines hidden (view full) ---

1277 } else {
1278 if (status & HAL_INT_SWBA) {
1279 /*
1280 * Software beacon alert--time to send a beacon.
1281 * Handle beacon transmission directly; deferring
1282 * this is too slow to meet timing constraints
1283 * under load.
1284 */
1201 ath_beacon_proc(sc, 0);
1285#ifdef ATH_SUPPORT_TDMA
1286 if (sc->sc_tdma) {
1287 if (sc->sc_tdmaswba == 0) {
1288 struct ieee80211com *ic = ifp->if_l2com;
1289 struct ieee80211vap *vap =
1290 TAILQ_FIRST(&ic->ic_vaps);
1291 ath_tdma_beacon_send(sc, vap);
1292 sc->sc_tdmaswba =
1293 vap->iv_tdma->tdma_bintval;
1294 } else
1295 sc->sc_tdmaswba--;
1296 } else
1297#endif
1298 ath_beacon_proc(sc, 0);
1202 }
1203 if (status & HAL_INT_RXEOL) {
1204 /*
1205 * NB: the hardware should re-read the link when
1206 * RXE bit is written, but it doesn't work at
1207 * least on older hardware revs.
1208 */
1209 sc->sc_stats.ast_rxeol++;

--- 366 unchanged lines hidden (view full) ---

1576 if (ath_startrecv(sc) != 0) /* restart recv */
1577 if_printf(ifp, "%s: unable to start recv logic\n", __func__);
1578 /*
1579 * We may be doing a reset in response to an ioctl
1580 * that changes the channel so update any state that
1581 * might change as a result.
1582 */
1583 ath_chan_change(sc, ic->ic_curchan);
1299 }
1300 if (status & HAL_INT_RXEOL) {
1301 /*
1302 * NB: the hardware should re-read the link when
1303 * RXE bit is written, but it doesn't work at
1304 * least on older hardware revs.
1305 */
1306 sc->sc_stats.ast_rxeol++;

--- 366 unchanged lines hidden (view full) ---

1673 if (ath_startrecv(sc) != 0) /* restart recv */
1674 if_printf(ifp, "%s: unable to start recv logic\n", __func__);
1675 /*
1676 * We may be doing a reset in response to an ioctl
1677 * that changes the channel so update any state that
1678 * might change as a result.
1679 */
1680 ath_chan_change(sc, ic->ic_curchan);
1584 if (sc->sc_beacons)
1585 ath_beacon_config(sc, NULL); /* restart beacons */
1681 if (sc->sc_beacons) {
1682#ifdef ATH_SUPPORT_TDMA
1683 if (sc->sc_tdma)
1684 ath_tdma_config(sc, NULL);
1685 else
1686#endif
1687 ath_beacon_config(sc, NULL); /* restart beacons */
1688 }
1586 ath_hal_intrset(ah, sc->sc_imask);
1587
1588 ath_start(ifp); /* restart xmit */
1589 return 0;
1590}
1591
1592static int
1593ath_reset_vap(struct ieee80211vap *vap, u_long cmd)

--- 89 unchanged lines hidden (view full) ---

1683 ieee80211_free_node(ni);
1684 bf->bf_node = NULL;
1685 if (bf->bf_m != NULL) {
1686 m_freem(bf->bf_m);
1687 bf->bf_m = NULL;
1688 }
1689
1690 ATH_TXBUF_LOCK(sc);
1689 ath_hal_intrset(ah, sc->sc_imask);
1690
1691 ath_start(ifp); /* restart xmit */
1692 return 0;
1693}
1694
1695static int
1696ath_reset_vap(struct ieee80211vap *vap, u_long cmd)

--- 89 unchanged lines hidden (view full) ---

1786 ieee80211_free_node(ni);
1787 bf->bf_node = NULL;
1788 if (bf->bf_m != NULL) {
1789 m_freem(bf->bf_m);
1790 bf->bf_m = NULL;
1791 }
1792
1793 ATH_TXBUF_LOCK(sc);
1691 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
1794 STAILQ_INSERT_HEAD(&sc->sc_txbuf, bf, bf_list);
1692 ATH_TXBUF_UNLOCK(sc);
1693 }
1694}
1695
1696static __inline u_int32_t
1697ath_ff_approx_txtime(struct ath_softc *sc, struct ath_node *an, struct mbuf *m)
1698{
1699 struct ieee80211com *ic = sc->sc_ifp->if_l2com;

--- 124 unchanged lines hidden (view full) ---

1824 */
1825 bfstaged->bf_node = NULL;
1826 ieee80211_free_node(ni);
1827
1828 /*
1829 * Return bfstaged to the free list.
1830 */
1831 ATH_TXBUF_LOCK(sc);
1795 ATH_TXBUF_UNLOCK(sc);
1796 }
1797}
1798
1799static __inline u_int32_t
1800ath_ff_approx_txtime(struct ath_softc *sc, struct ath_node *an, struct mbuf *m)
1801{
1802 struct ieee80211com *ic = sc->sc_ifp->if_l2com;

--- 124 unchanged lines hidden (view full) ---

1927 */
1928 bfstaged->bf_node = NULL;
1929 ieee80211_free_node(ni);
1930
1931 /*
1932 * Return bfstaged to the free list.
1933 */
1934 ATH_TXBUF_LOCK(sc);
1832 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bfstaged, bf_list);
1935 STAILQ_INSERT_HEAD(&sc->sc_txbuf, bfstaged, bf_list);
1833 ATH_TXBUF_UNLOCK(sc);
1834
1835 return m; /* ready to go */
1836 } else {
1837 /*
1838 * No frame available, queue this frame to wait
1839 * for a partner. Note that we hold the buffer
1840 * and a reference to the node; we need the

--- 56 unchanged lines hidden (view full) ---

1897 ieee80211_free_node(ni);
1898 bfstaged->bf_node = NULL;
1899 if (bfstaged->bf_m != NULL) {
1900 m_freem(bfstaged->bf_m);
1901 bfstaged->bf_m = NULL;
1902 }
1903
1904 ATH_TXBUF_LOCK(sc);
1936 ATH_TXBUF_UNLOCK(sc);
1937
1938 return m; /* ready to go */
1939 } else {
1940 /*
1941 * No frame available, queue this frame to wait
1942 * for a partner. Note that we hold the buffer
1943 * and a reference to the node; we need the

--- 56 unchanged lines hidden (view full) ---

2000 ieee80211_free_node(ni);
2001 bfstaged->bf_node = NULL;
2002 if (bfstaged->bf_m != NULL) {
2003 m_freem(bfstaged->bf_m);
2004 bfstaged->bf_m = NULL;
2005 }
2006
2007 ATH_TXBUF_LOCK(sc);
1905 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bfstaged, bf_list);
2008 STAILQ_INSERT_HEAD(&sc->sc_txbuf, bfstaged, bf_list);
1906 ATH_TXBUF_UNLOCK(sc);
1907 } else {
1908#if 0
1909 ifp->if_opackets++;
1910#endif
1911 }
1912 } else {
1913 if (an->an_ff_buf[pri] != NULL) {

--- 6 unchanged lines hidden (view full) ---

1920 ether_sprintf(an->an_node.ni_macaddr));
1921 /* XXX stat */
1922 }
1923 ATH_TXQ_UNLOCK(txq);
1924 }
1925 return m;
1926}
1927
2009 ATH_TXBUF_UNLOCK(sc);
2010 } else {
2011#if 0
2012 ifp->if_opackets++;
2013#endif
2014 }
2015 } else {
2016 if (an->an_ff_buf[pri] != NULL) {

--- 6 unchanged lines hidden (view full) ---

2023 ether_sprintf(an->an_node.ni_macaddr));
2024 /* XXX stat */
2025 }
2026 ATH_TXQ_UNLOCK(txq);
2027 }
2028 return m;
2029}
2030
2031static struct ath_buf *
2032_ath_getbuf_locked(struct ath_softc *sc)
2033{
2034 struct ath_buf *bf;
2035
2036 ATH_TXBUF_LOCK_ASSERT(sc);
2037
2038 bf = STAILQ_FIRST(&sc->sc_txbuf);
2039 if (bf != NULL && (bf->bf_flags & ATH_BUF_BUSY) == 0)
2040 STAILQ_REMOVE_HEAD(&sc->sc_txbuf, bf_list);
2041 else
2042 bf = NULL;
2043 if (bf == NULL) {
2044 DPRINTF(sc, ATH_DEBUG_XMIT, "%s: %s\n", __func__,
2045 STAILQ_FIRST(&sc->sc_txbuf) == NULL ?
2046 "out of xmit buffers" : "xmit buffer busy");
2047 sc->sc_stats.ast_tx_nobuf++;
2048 }
2049 return bf;
2050}
2051
2052static struct ath_buf *
2053ath_getbuf(struct ath_softc *sc)
2054{
2055 struct ath_buf *bf;
2056
2057 ATH_TXBUF_LOCK(sc);
2058 bf = _ath_getbuf_locked(sc);
2059 if (bf == NULL) {
2060 struct ifnet *ifp = sc->sc_ifp;
2061
2062 DPRINTF(sc, ATH_DEBUG_XMIT, "%s: stop queue\n", __func__);
2063 sc->sc_stats.ast_tx_qstop++;
2064 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
2065 }
2066 ATH_TXBUF_UNLOCK(sc);
2067 return bf;
2068}
2069
1928/*
1929 * Cleanup driver resources when we run out of buffers
1930 * while processing fragments; return the tx buffers
1931 * allocated and drop node references.
1932 */
1933static void
1934ath_txfrag_cleanup(struct ath_softc *sc,
1935 ath_bufhead *frags, struct ieee80211_node *ni)
1936{
1937 struct ath_buf *bf, *next;
1938
1939 ATH_TXBUF_LOCK_ASSERT(sc);
1940
1941 STAILQ_FOREACH_SAFE(bf, frags, bf_list, next) {
1942 /* NB: bf assumed clean */
1943 STAILQ_REMOVE_HEAD(frags, bf_list);
2070/*
2071 * Cleanup driver resources when we run out of buffers
2072 * while processing fragments; return the tx buffers
2073 * allocated and drop node references.
2074 */
2075static void
2076ath_txfrag_cleanup(struct ath_softc *sc,
2077 ath_bufhead *frags, struct ieee80211_node *ni)
2078{
2079 struct ath_buf *bf, *next;
2080
2081 ATH_TXBUF_LOCK_ASSERT(sc);
2082
2083 STAILQ_FOREACH_SAFE(bf, frags, bf_list, next) {
2084 /* NB: bf assumed clean */
2085 STAILQ_REMOVE_HEAD(frags, bf_list);
1944 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
2086 STAILQ_INSERT_HEAD(&sc->sc_txbuf, bf, bf_list);
1945 ieee80211_node_decref(ni);
1946 }
1947}
1948
1949/*
1950 * Setup xmit of a fragmented frame. Allocate a buffer
1951 * for each frag and bump the node reference count to
1952 * reflect the held reference to be setup by ath_tx_start.
1953 */
1954static int
1955ath_txfrag_setup(struct ath_softc *sc, ath_bufhead *frags,
1956 struct mbuf *m0, struct ieee80211_node *ni)
1957{
1958 struct mbuf *m;
1959 struct ath_buf *bf;
1960
1961 ATH_TXBUF_LOCK(sc);
1962 for (m = m0->m_nextpkt; m != NULL; m = m->m_nextpkt) {
2087 ieee80211_node_decref(ni);
2088 }
2089}
2090
2091/*
2092 * Setup xmit of a fragmented frame. Allocate a buffer
2093 * for each frag and bump the node reference count to
2094 * reflect the held reference to be setup by ath_tx_start.
2095 */
2096static int
2097ath_txfrag_setup(struct ath_softc *sc, ath_bufhead *frags,
2098 struct mbuf *m0, struct ieee80211_node *ni)
2099{
2100 struct mbuf *m;
2101 struct ath_buf *bf;
2102
2103 ATH_TXBUF_LOCK(sc);
2104 for (m = m0->m_nextpkt; m != NULL; m = m->m_nextpkt) {
1963 bf = STAILQ_FIRST(&sc->sc_txbuf);
2105 bf = _ath_getbuf_locked(sc);
1964 if (bf == NULL) { /* out of buffers, cleanup */
1965 ath_txfrag_cleanup(sc, frags, ni);
1966 break;
1967 }
2106 if (bf == NULL) { /* out of buffers, cleanup */
2107 ath_txfrag_cleanup(sc, frags, ni);
2108 break;
2109 }
1968 STAILQ_REMOVE_HEAD(&sc->sc_txbuf, bf_list);
1969 ieee80211_node_incref(ni);
1970 STAILQ_INSERT_TAIL(frags, bf, bf_list);
1971 }
1972 ATH_TXBUF_UNLOCK(sc);
1973
1974 return !STAILQ_EMPTY(frags);
1975}
1976

--- 10 unchanged lines hidden (view full) ---

1987 int pri;
1988
1989 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid)
1990 return;
1991 for (;;) {
1992 /*
1993 * Grab a TX buffer and associated resources.
1994 */
2110 ieee80211_node_incref(ni);
2111 STAILQ_INSERT_TAIL(frags, bf, bf_list);
2112 }
2113 ATH_TXBUF_UNLOCK(sc);
2114
2115 return !STAILQ_EMPTY(frags);
2116}
2117

--- 10 unchanged lines hidden (view full) ---

2128 int pri;
2129
2130 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid)
2131 return;
2132 for (;;) {
2133 /*
2134 * Grab a TX buffer and associated resources.
2135 */
1995 ATH_TXBUF_LOCK(sc);
1996 bf = STAILQ_FIRST(&sc->sc_txbuf);
1997 if (bf != NULL)
1998 STAILQ_REMOVE_HEAD(&sc->sc_txbuf, bf_list);
1999 ATH_TXBUF_UNLOCK(sc);
2000 if (bf == NULL) {
2001 DPRINTF(sc, ATH_DEBUG_XMIT, "%s: out of xmit buffers\n",
2002 __func__);
2003 sc->sc_stats.ast_tx_qstop++;
2004 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
2136 bf = ath_getbuf(sc);
2137 if (bf == NULL)
2005 break;
2138 break;
2006 }
2007
2008 IFQ_DEQUEUE(&ifp->if_snd, m);
2009 if (m == NULL) {
2010 ATH_TXBUF_LOCK(sc);
2139
2140 IFQ_DEQUEUE(&ifp->if_snd, m);
2141 if (m == NULL) {
2142 ATH_TXBUF_LOCK(sc);
2011 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
2143 STAILQ_INSERT_HEAD(&sc->sc_txbuf, bf, bf_list);
2012 ATH_TXBUF_UNLOCK(sc);
2013 break;
2014 }
2015 STAILQ_INIT(&frags);
2016 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
2017 pri = M_WME_GETAC(m);
2018 txq = sc->sc_ac2q[pri];
2019 if (IEEE80211_ATH_CAP(ni->ni_vap, ni, IEEE80211_NODE_FF)) {

--- 57 unchanged lines hidden (view full) ---

2077 next = m->m_nextpkt;
2078 if (ath_tx_start(sc, ni, bf, m)) {
2079 bad:
2080 ifp->if_oerrors++;
2081 reclaim:
2082 bf->bf_m = NULL;
2083 bf->bf_node = NULL;
2084 ATH_TXBUF_LOCK(sc);
2144 ATH_TXBUF_UNLOCK(sc);
2145 break;
2146 }
2147 STAILQ_INIT(&frags);
2148 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
2149 pri = M_WME_GETAC(m);
2150 txq = sc->sc_ac2q[pri];
2151 if (IEEE80211_ATH_CAP(ni->ni_vap, ni, IEEE80211_NODE_FF)) {

--- 57 unchanged lines hidden (view full) ---

2209 next = m->m_nextpkt;
2210 if (ath_tx_start(sc, ni, bf, m)) {
2211 bad:
2212 ifp->if_oerrors++;
2213 reclaim:
2214 bf->bf_m = NULL;
2215 bf->bf_node = NULL;
2216 ATH_TXBUF_LOCK(sc);
2085 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
2217 STAILQ_INSERT_HEAD(&sc->sc_txbuf, bf, bf_list);
2086 ath_txfrag_cleanup(sc, &frags, ni);
2087 ATH_TXBUF_UNLOCK(sc);
2088 if (ni != NULL)
2089 ieee80211_free_node(ni);
2090 continue;
2091 }
2092 if (next != NULL) {
2093 /*

--- 2116 unchanged lines hidden (view full) ---

4210 ni = ieee80211_find_rxnode_withkey(ic,
4211 mtod(m, const struct ieee80211_frame_min *),
4212 rs->rs_keyix == HAL_RXKEYIX_INVALID ?
4213 IEEE80211_KEYIX_NONE : rs->rs_keyix);
4214 if (ni != NULL) {
4215 /*
4216 * Sending station is known, dispatch directly.
4217 */
2218 ath_txfrag_cleanup(sc, &frags, ni);
2219 ATH_TXBUF_UNLOCK(sc);
2220 if (ni != NULL)
2221 ieee80211_free_node(ni);
2222 continue;
2223 }
2224 if (next != NULL) {
2225 /*

--- 2116 unchanged lines hidden (view full) ---

4342 ni = ieee80211_find_rxnode_withkey(ic,
4343 mtod(m, const struct ieee80211_frame_min *),
4344 rs->rs_keyix == HAL_RXKEYIX_INVALID ?
4345 IEEE80211_KEYIX_NONE : rs->rs_keyix);
4346 if (ni != NULL) {
4347 /*
4348 * Sending station is known, dispatch directly.
4349 */
4350#ifdef ATH_SUPPORT_TDMA
4351 sc->sc_tdmars = rs;
4352#endif
4218 type = ieee80211_input(ni, m,
4219 rs->rs_rssi, nf, rs->rs_tstamp);
4220 ieee80211_free_node(ni);
4221 /*
4222 * Arrange to update the last rx timestamp only for
4223 * frames from our ap when operating in station mode.
4224 * This assumes the rx key is always setup when
4225 * associated.

--- 156 unchanged lines hidden (view full) ---

4382 struct ifnet *ifp = sc->sc_ifp;
4383 struct ieee80211com *ic = ifp->if_l2com;
4384 struct ath_txq *txq = sc->sc_ac2q[ac];
4385 struct wmeParams *wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
4386 struct ath_hal *ah = sc->sc_ah;
4387 HAL_TXQ_INFO qi;
4388
4389 ath_hal_gettxqueueprops(ah, txq->axq_qnum, &qi);
4353 type = ieee80211_input(ni, m,
4354 rs->rs_rssi, nf, rs->rs_tstamp);
4355 ieee80211_free_node(ni);
4356 /*
4357 * Arrange to update the last rx timestamp only for
4358 * frames from our ap when operating in station mode.
4359 * This assumes the rx key is always setup when
4360 * associated.

--- 156 unchanged lines hidden (view full) ---

4517 struct ifnet *ifp = sc->sc_ifp;
4518 struct ieee80211com *ic = ifp->if_l2com;
4519 struct ath_txq *txq = sc->sc_ac2q[ac];
4520 struct wmeParams *wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
4521 struct ath_hal *ah = sc->sc_ah;
4522 HAL_TXQ_INFO qi;
4523
4524 ath_hal_gettxqueueprops(ah, txq->axq_qnum, &qi);
4390 qi.tqi_aifs = wmep->wmep_aifsn;
4391 qi.tqi_cwmin = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin);
4392 qi.tqi_cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax);
4393 qi.tqi_burstTime = ATH_TXOP_TO_US(wmep->wmep_txopLimit);
4525#ifdef ATH_SUPPORT_TDMA
4526 if (sc->sc_tdma) {
4527 /*
4528 * AIFS is zero so there's no pre-transmit wait. The
4529 * burst time defines the slot duration and is configured
4530 * via sysctl. The QCU is setup to not do post-xmit
4531 * back off, lockout all lower-priority QCU's, and fire
4532 * off the DMA beacon alert timer which is setup based
4533 * on the slot configuration.
4534 */
4535 qi.tqi_qflags = HAL_TXQ_TXOKINT_ENABLE
4536 | HAL_TXQ_TXERRINT_ENABLE
4537 | HAL_TXQ_TXURNINT_ENABLE
4538 | HAL_TXQ_TXEOLINT_ENABLE
4539 | HAL_TXQ_DBA_GATED
4540 | HAL_TXQ_BACKOFF_DISABLE
4541 | HAL_TXQ_ARB_LOCKOUT_GLOBAL
4542 ;
4543 qi.tqi_aifs = 0;
4544 /* XXX +dbaprep? */
4545 qi.tqi_readyTime = sc->sc_tdmaslotlen;
4546 qi.tqi_burstTime = qi.tqi_readyTime;
4547 } else {
4548#endif
4549 qi.tqi_qflags = HAL_TXQ_TXOKINT_ENABLE
4550 | HAL_TXQ_TXERRINT_ENABLE
4551 | HAL_TXQ_TXDESCINT_ENABLE
4552 | HAL_TXQ_TXURNINT_ENABLE
4553 ;
4554 qi.tqi_aifs = wmep->wmep_aifsn;
4555 qi.tqi_cwmin = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin);
4556 qi.tqi_cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax);
4557 qi.tqi_readyTime = 0;
4558 qi.tqi_burstTime = ATH_TXOP_TO_US(wmep->wmep_txopLimit);
4559#ifdef ATH_SUPPORT_TDMA
4560 }
4561#endif
4394
4562
4563 DPRINTF(sc, ATH_DEBUG_RESET,
4564 "%s: Q%u qflags 0x%x aifs %u cwmin %u cwmax %u burstTime %u\n",
4565 __func__, txq->axq_qnum, qi.tqi_qflags,
4566 qi.tqi_aifs, qi.tqi_cwmin, qi.tqi_cwmax, qi.tqi_burstTime);
4567
4395 if (!ath_hal_settxqueueprops(ah, txq->axq_qnum, &qi)) {
4396 if_printf(ifp, "unable to update hardware queue "
4397 "parameters for %s traffic!\n",
4398 ieee80211_wme_acnames[ac]);
4399 return 0;
4400 } else {
4401 ath_hal_resettxqueue(ah, txq->axq_qnum); /* push to h/w */
4402 return 1;

--- 162 unchanged lines hidden (view full) ---

4565 * Insert the frame on the outbound list and pass it on
4566 * to the hardware. Multicast frames buffered for power
4567 * save stations and transmit from the CAB queue are stored
4568 * on a s/w only queue and loaded on to the CAB queue in
4569 * the SWBA handler since frames only go out on DTIM and
4570 * to avoid possible races.
4571 */
4572 ATH_TXQ_LOCK(txq);
4568 if (!ath_hal_settxqueueprops(ah, txq->axq_qnum, &qi)) {
4569 if_printf(ifp, "unable to update hardware queue "
4570 "parameters for %s traffic!\n",
4571 ieee80211_wme_acnames[ac]);
4572 return 0;
4573 } else {
4574 ath_hal_resettxqueue(ah, txq->axq_qnum); /* push to h/w */
4575 return 1;

--- 162 unchanged lines hidden (view full) ---

4738 * Insert the frame on the outbound list and pass it on
4739 * to the hardware. Multicast frames buffered for power
4740 * save stations and transmit from the CAB queue are stored
4741 * on a s/w only queue and loaded on to the CAB queue in
4742 * the SWBA handler since frames only go out on DTIM and
4743 * to avoid possible races.
4744 */
4745 ATH_TXQ_LOCK(txq);
4746 KASSERT((bf->bf_flags & ATH_BUF_BUSY) == 0,
4747 ("busy status 0x%x", bf->bf_flags));
4573 if (txq->axq_qnum != ATH_TXQ_SWQ) {
4748 if (txq->axq_qnum != ATH_TXQ_SWQ) {
4749#ifdef ATH_SUPPORT_TDMA
4750 int qbusy;
4751
4574 ATH_TXQ_INSERT_TAIL(txq, bf, bf_list);
4752 ATH_TXQ_INSERT_TAIL(txq, bf, bf_list);
4753 qbusy = ath_hal_txqenabled(ah, txq->axq_qnum);
4575 if (txq->axq_link == NULL) {
4754 if (txq->axq_link == NULL) {
4755 /*
4756 * Be careful writing the address to TXDP. If
4757 * the tx q is enabled then this write will be
4758 * ignored. Normally this is not an issue but
4759 * when tdma is in use and the q is beacon gated
4760 * this race can occur. If the q is busy then
4761 * defer the work to later--either when another
4762 * packet comes along or when we prepare a beacon
4763 * frame at SWBA.
4764 */
4765 if (!qbusy) {
4766 ath_hal_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
4767 txq->axq_flags &= ~ATH_TXQ_PUTPENDING;
4768 DPRINTF(sc, ATH_DEBUG_XMIT,
4769 "%s: TXDP[%u] = %p (%p) depth %d\n",
4770 __func__, txq->axq_qnum,
4771 (caddr_t)bf->bf_daddr, bf->bf_desc,
4772 txq->axq_depth);
4773 } else {
4774 txq->axq_flags |= ATH_TXQ_PUTPENDING;
4775 DPRINTF(sc, ATH_DEBUG_TDMA | ATH_DEBUG_XMIT,
4776 "%s: Q%u busy, defer enable\n", __func__,
4777 txq->axq_qnum);
4778 }
4779 } else {
4780 *txq->axq_link = bf->bf_daddr;
4781 DPRINTF(sc, ATH_DEBUG_XMIT,
4782 "%s: link[%u](%p)=%p (%p) depth %d\n", __func__,
4783 txq->axq_qnum, txq->axq_link,
4784 (caddr_t)bf->bf_daddr, bf->bf_desc, txq->axq_depth);
4785 if ((txq->axq_flags & ATH_TXQ_PUTPENDING) && !qbusy) {
4786 /*
4787 * The q was busy when we previously tried
4788 * to write the address of the first buffer
4789 * in the chain. Since it's not busy now
4790 * handle this chore. We are certain the
4791 * buffer at the front is the right one since
4792 * axq_link is NULL only when the buffer list
4793 * is/was empty.
4794 */
4795 ath_hal_puttxbuf(ah, txq->axq_qnum,
4796 STAILQ_FIRST(&txq->axq_q)->bf_daddr);
4797 txq->axq_flags &= ~ATH_TXQ_PUTPENDING;
4798 DPRINTF(sc, ATH_DEBUG_TDMA | ATH_DEBUG_XMIT,
4799 "%s: Q%u restarted\n", __func__,
4800 txq->axq_qnum);
4801 }
4802 }
4803#else
4804 ATH_TXQ_INSERT_TAIL(txq, bf, bf_list);
4805 if (txq->axq_link == NULL) {
4576 ath_hal_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
4577 DPRINTF(sc, ATH_DEBUG_XMIT,
4806 ath_hal_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
4807 DPRINTF(sc, ATH_DEBUG_XMIT,
4578 "%s: TXDP[%u] = %p (%p) depth %d\n", __func__,
4579 txq->axq_qnum, (caddr_t)bf->bf_daddr, bf->bf_desc,
4808 "%s: TXDP[%u] = %p (%p) depth %d\n",
4809 __func__, txq->axq_qnum,
4810 (caddr_t)bf->bf_daddr, bf->bf_desc,
4580 txq->axq_depth);
4581 } else {
4582 *txq->axq_link = bf->bf_daddr;
4583 DPRINTF(sc, ATH_DEBUG_XMIT,
4584 "%s: link[%u](%p)=%p (%p) depth %d\n", __func__,
4585 txq->axq_qnum, txq->axq_link,
4586 (caddr_t)bf->bf_daddr, bf->bf_desc, txq->axq_depth);
4587 }
4811 txq->axq_depth);
4812 } else {
4813 *txq->axq_link = bf->bf_daddr;
4814 DPRINTF(sc, ATH_DEBUG_XMIT,
4815 "%s: link[%u](%p)=%p (%p) depth %d\n", __func__,
4816 txq->axq_qnum, txq->axq_link,
4817 (caddr_t)bf->bf_daddr, bf->bf_desc, txq->axq_depth);
4818 }
4819#endif /* ATH_SUPPORT_TDMA */
4588 txq->axq_link = &bf->bf_desc[bf->bf_nseg - 1].ds_link;
4589 ath_hal_txstart(ah, txq->axq_qnum);
4590 } else {
4591 if (txq->axq_link != NULL) {
4592 struct ath_buf *last = ATH_TXQ_LAST(txq);
4593 struct ieee80211_frame *wh;
4594
4595 /* mark previous frame */

--- 218 unchanged lines hidden (view full) ---

4814 } else if (pktlen > vap->iv_rtsthreshold &&
4815 (ni->ni_ath_flags & IEEE80211_NODE_FF) == 0) {
4816 flags |= HAL_TXDESC_RTSENA; /* RTS based on frame length */
4817 cix = rt->info[rix].controlRate;
4818 sc->sc_stats.ast_tx_rts++;
4819 }
4820 if (flags & HAL_TXDESC_NOACK) /* NB: avoid double counting */
4821 sc->sc_stats.ast_tx_noack++;
4820 txq->axq_link = &bf->bf_desc[bf->bf_nseg - 1].ds_link;
4821 ath_hal_txstart(ah, txq->axq_qnum);
4822 } else {
4823 if (txq->axq_link != NULL) {
4824 struct ath_buf *last = ATH_TXQ_LAST(txq);
4825 struct ieee80211_frame *wh;
4826
4827 /* mark previous frame */

--- 218 unchanged lines hidden (view full) ---

5046 } else if (pktlen > vap->iv_rtsthreshold &&
5047 (ni->ni_ath_flags & IEEE80211_NODE_FF) == 0) {
5048 flags |= HAL_TXDESC_RTSENA; /* RTS based on frame length */
5049 cix = rt->info[rix].controlRate;
5050 sc->sc_stats.ast_tx_rts++;
5051 }
5052 if (flags & HAL_TXDESC_NOACK) /* NB: avoid double counting */
5053 sc->sc_stats.ast_tx_noack++;
5054#ifdef ATH_SUPPORT_TDMA
5055 if (sc->sc_tdma && (flags & HAL_TXDESC_NOACK) == 0) {
5056 DPRINTF(sc, ATH_DEBUG_XMIT, "%s: ACK required w/ TDMA\n",
5057 __func__);
5058 /* XXX statistic */
5059 ath_freetx(m0);
5060 return EIO;
5061 }
5062#endif
4822
4823 /*
4824 * If 802.11g protection is enabled, determine whether
4825 * to use RTS/CTS or just CTS. Note that this is only
4826 * done for OFDM unicast frames.
4827 */
4828 if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
4829 rt->info[rix].phy == IEEE80211_T_OFDM &&

--- 182 unchanged lines hidden (view full) ---

5012 * Process completed xmit descriptors from the specified queue.
5013 */
5014static int
5015ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
5016{
5017 struct ath_hal *ah = sc->sc_ah;
5018 struct ifnet *ifp = sc->sc_ifp;
5019 struct ieee80211com *ic = ifp->if_l2com;
5063
5064 /*
5065 * If 802.11g protection is enabled, determine whether
5066 * to use RTS/CTS or just CTS. Note that this is only
5067 * done for OFDM unicast frames.
5068 */
5069 if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
5070 rt->info[rix].phy == IEEE80211_T_OFDM &&

--- 182 unchanged lines hidden (view full) ---

5253 * Process completed xmit descriptors from the specified queue.
5254 */
5255static int
5256ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
5257{
5258 struct ath_hal *ah = sc->sc_ah;
5259 struct ifnet *ifp = sc->sc_ifp;
5260 struct ieee80211com *ic = ifp->if_l2com;
5020 struct ath_buf *bf;
5261 struct ath_buf *bf, *last;
5021 struct ath_desc *ds, *ds0;
5022 struct ath_tx_status *ts;
5023 struct ieee80211_node *ni;
5024 struct ath_node *an;
5025 int sr, lr, pri, nacked;
5026 HAL_STATUS status;
5027
5028 DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s: tx queue %u head %p link %p\n",

--- 18 unchanged lines hidden (view full) ---

5047 ath_printtxbuf(sc, bf, txq->axq_qnum, 0,
5048 status == HAL_OK);
5049#endif
5050 if (status == HAL_EINPROGRESS) {
5051 ATH_TXQ_UNLOCK(txq);
5052 break;
5053 }
5054 ATH_TXQ_REMOVE_HEAD(txq, bf_list);
5262 struct ath_desc *ds, *ds0;
5263 struct ath_tx_status *ts;
5264 struct ieee80211_node *ni;
5265 struct ath_node *an;
5266 int sr, lr, pri, nacked;
5267 HAL_STATUS status;
5268
5269 DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s: tx queue %u head %p link %p\n",

--- 18 unchanged lines hidden (view full) ---

5288 ath_printtxbuf(sc, bf, txq->axq_qnum, 0,
5289 status == HAL_OK);
5290#endif
5291 if (status == HAL_EINPROGRESS) {
5292 ATH_TXQ_UNLOCK(txq);
5293 break;
5294 }
5295 ATH_TXQ_REMOVE_HEAD(txq, bf_list);
5296#ifdef ATH_SUPPORT_TDMA
5297 if (txq->axq_depth > 0) {
5298 /*
5299 * More frames follow. Mark the buffer busy
5300 * so it's not re-used while the hardware may
5301 * still re-read the link field in the descriptor.
5302 */
5303 bf->bf_flags |= ATH_BUF_BUSY;
5304 } else
5305#else
5055 if (txq->axq_depth == 0)
5306 if (txq->axq_depth == 0)
5307#endif
5056 txq->axq_link = NULL;
5057 ATH_TXQ_UNLOCK(txq);
5058
5059 ni = bf->bf_node;
5060 if (ni != NULL) {
5061 an = ATH_NODE(ni);
5062 if (ts->ts_status == 0) {
5063 u_int8_t txant = ts->ts_antenna;

--- 59 unchanged lines hidden (view full) ---

5123 BUS_DMASYNC_POSTWRITE);
5124 bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
5125
5126 m_freem(bf->bf_m);
5127 bf->bf_m = NULL;
5128 bf->bf_node = NULL;
5129
5130 ATH_TXBUF_LOCK(sc);
5308 txq->axq_link = NULL;
5309 ATH_TXQ_UNLOCK(txq);
5310
5311 ni = bf->bf_node;
5312 if (ni != NULL) {
5313 an = ATH_NODE(ni);
5314 if (ts->ts_status == 0) {
5315 u_int8_t txant = ts->ts_antenna;

--- 59 unchanged lines hidden (view full) ---

5375 BUS_DMASYNC_POSTWRITE);
5376 bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
5377
5378 m_freem(bf->bf_m);
5379 bf->bf_m = NULL;
5380 bf->bf_node = NULL;
5381
5382 ATH_TXBUF_LOCK(sc);
5383 last = STAILQ_LAST(&sc->sc_txbuf, ath_buf, bf_list);
5384 if (last != NULL)
5385 last->bf_flags &= ~ATH_BUF_BUSY;
5131 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
5132 ATH_TXBUF_UNLOCK(sc);
5133 }
5134 /*
5135 * Flush fast-frame staging queue when traffic slows.
5136 */
5137 if (txq->axq_depth <= 1)
5138 ath_ff_stageq_flush(sc, txq, ath_ff_always);

--- 106 unchanged lines hidden (view full) ---

5245 struct ieee80211_node *ni;
5246 struct ath_buf *bf;
5247 u_int ix;
5248
5249 /*
5250 * NB: this assumes output has been stopped and
5251 * we do not need to block ath_tx_proc
5252 */
5386 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
5387 ATH_TXBUF_UNLOCK(sc);
5388 }
5389 /*
5390 * Flush fast-frame staging queue when traffic slows.
5391 */
5392 if (txq->axq_depth <= 1)
5393 ath_ff_stageq_flush(sc, txq, ath_ff_always);

--- 106 unchanged lines hidden (view full) ---

5500 struct ieee80211_node *ni;
5501 struct ath_buf *bf;
5502 u_int ix;
5503
5504 /*
5505 * NB: this assumes output has been stopped and
5506 * we do not need to block ath_tx_proc
5507 */
5508 ATH_TXBUF_LOCK(sc);
5509 bf = STAILQ_LAST(&sc->sc_txbuf, ath_buf, bf_list);
5510 if (bf != NULL)
5511 bf->bf_flags &= ~ATH_BUF_BUSY;
5512 ATH_TXBUF_UNLOCK(sc);
5253 for (ix = 0;; ix++) {
5254 ATH_TXQ_LOCK(txq);
5255 bf = STAILQ_FIRST(&txq->axq_q);
5256 if (bf == NULL) {
5257 txq->axq_link = NULL;
5258 ATH_TXQ_UNLOCK(txq);
5259 break;
5260 }

--- 18 unchanged lines hidden (view full) ---

5279 * Do any callback and reclaim the node reference.
5280 */
5281 if (bf->bf_m->m_flags & M_TXCB)
5282 ieee80211_process_callback(ni, bf->bf_m, -1);
5283 ieee80211_free_node(ni);
5284 }
5285 m_freem(bf->bf_m);
5286 bf->bf_m = NULL;
5513 for (ix = 0;; ix++) {
5514 ATH_TXQ_LOCK(txq);
5515 bf = STAILQ_FIRST(&txq->axq_q);
5516 if (bf == NULL) {
5517 txq->axq_link = NULL;
5518 ATH_TXQ_UNLOCK(txq);
5519 break;
5520 }

--- 18 unchanged lines hidden (view full) ---

5539 * Do any callback and reclaim the node reference.
5540 */
5541 if (bf->bf_m->m_flags & M_TXCB)
5542 ieee80211_process_callback(ni, bf->bf_m, -1);
5543 ieee80211_free_node(ni);
5544 }
5545 m_freem(bf->bf_m);
5546 bf->bf_m = NULL;
5547 bf->bf_flags &= ~ATH_BUF_BUSY;
5287
5288 ATH_TXBUF_LOCK(sc);
5289 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
5290 ATH_TXBUF_UNLOCK(sc);
5291 }
5292}
5293
5294static void

--- 460 unchanged lines hidden (view full) ---

5755
5756 DPRINTF(sc, ATH_DEBUG_STATE,
5757 "%s(RUN): iv_flags 0x%08x bintvl %d bssid %s "
5758 "capinfo 0x%04x chan %d\n", __func__,
5759 vap->iv_flags, ni->ni_intval, ether_sprintf(ni->ni_bssid),
5760 ni->ni_capinfo, ieee80211_chan2ieee(ic, ic->ic_curchan));
5761
5762 switch (vap->iv_opmode) {
5548
5549 ATH_TXBUF_LOCK(sc);
5550 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
5551 ATH_TXBUF_UNLOCK(sc);
5552 }
5553}
5554
5555static void

--- 460 unchanged lines hidden (view full) ---

6016
6017 DPRINTF(sc, ATH_DEBUG_STATE,
6018 "%s(RUN): iv_flags 0x%08x bintvl %d bssid %s "
6019 "capinfo 0x%04x chan %d\n", __func__,
6020 vap->iv_flags, ni->ni_intval, ether_sprintf(ni->ni_bssid),
6021 ni->ni_capinfo, ieee80211_chan2ieee(ic, ic->ic_curchan));
6022
6023 switch (vap->iv_opmode) {
6024#ifdef ATH_SUPPORT_TDMA
6025 case IEEE80211_M_AHDEMO:
6026 if ((vap->iv_caps & IEEE80211_C_TDMA) == 0)
6027 break;
6028 /* fall thru... */
6029#endif
5763 case IEEE80211_M_HOSTAP:
5764 case IEEE80211_M_IBSS:
5765 /*
5766 * Allocate and setup the beacon frame.
5767 *
5768 * Stop any previous beacon DMA. This may be
5769 * necessary, for example, when an ibss merge
5770 * causes reconfiguration; there will be a state

--- 12 unchanged lines hidden (view full) ---

5783 * starting an ibss/bss so there's no need to delay;
5784 * if this is the first vap moving to RUN state, then
5785 * beacon state needs to be [re]configured.
5786 */
5787 if (vap->iv_opmode == IEEE80211_M_IBSS &&
5788 ni->ni_tstamp.tsf != 0) {
5789 sc->sc_syncbeacon = 1;
5790 } else if (!sc->sc_beacons) {
6030 case IEEE80211_M_HOSTAP:
6031 case IEEE80211_M_IBSS:
6032 /*
6033 * Allocate and setup the beacon frame.
6034 *
6035 * Stop any previous beacon DMA. This may be
6036 * necessary, for example, when an ibss merge
6037 * causes reconfiguration; there will be a state

--- 12 unchanged lines hidden (view full) ---

6050 * starting an ibss/bss so there's no need to delay;
6051 * if this is the first vap moving to RUN state, then
6052 * beacon state needs to be [re]configured.
6053 */
6054 if (vap->iv_opmode == IEEE80211_M_IBSS &&
6055 ni->ni_tstamp.tsf != 0) {
6056 sc->sc_syncbeacon = 1;
6057 } else if (!sc->sc_beacons) {
5791 ath_beacon_config(sc, vap);
6058#ifdef ATH_SUPPORT_TDMA
6059 if (vap->iv_caps & IEEE80211_C_TDMA)
6060 ath_tdma_config(sc, vap);
6061 else
6062#endif
6063 ath_beacon_config(sc, vap);
5792 sc->sc_beacons = 1;
5793 }
5794 break;
5795 case IEEE80211_M_STA:
5796 /*
5797 * Defer beacon timer configuration to the next
5798 * beacon frame so we have a current TSF to use
5799 * (any TSF collected when scanning is likely old).

--- 46 unchanged lines hidden (view full) ---

5846 */
5847 if (!ath_isanyrunningvaps(vap)) {
5848 sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS);
5849 /* disable interrupts */
5850 ath_hal_intrset(ah, sc->sc_imask &~ HAL_INT_GLOBAL);
5851 taskqueue_block(sc->sc_tq);
5852 sc->sc_beacons = 0;
5853 }
6064 sc->sc_beacons = 1;
6065 }
6066 break;
6067 case IEEE80211_M_STA:
6068 /*
6069 * Defer beacon timer configuration to the next
6070 * beacon frame so we have a current TSF to use
6071 * (any TSF collected when scanning is likely old).

--- 46 unchanged lines hidden (view full) ---

6118 */
6119 if (!ath_isanyrunningvaps(vap)) {
6120 sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS);
6121 /* disable interrupts */
6122 ath_hal_intrset(ah, sc->sc_imask &~ HAL_INT_GLOBAL);
6123 taskqueue_block(sc->sc_tq);
6124 sc->sc_beacons = 0;
6125 }
6126#ifdef ATH_SUPPORT_TDMA
6127 ath_hal_setcca(ah, AH_TRUE);
6128#endif
5854 }
5855bad:
5856 return error;
5857}
5858
5859/*
5860 * Allocate a key cache slot to the station so we can
5861 * setup a mapping from key index to node. The key cache

--- 633 unchanged lines hidden (view full) ---

6495 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
6496 break;
6497 case SIOCGATHSTATS:
6498 /* NB: embed these numbers to get a consistent view */
6499 sc->sc_stats.ast_tx_packets = ifp->if_opackets;
6500 sc->sc_stats.ast_rx_packets = ifp->if_ipackets;
6501 sc->sc_stats.ast_tx_rssi = ATH_RSSI(sc->sc_halstats.ns_avgtxrssi);
6502 sc->sc_stats.ast_rx_rssi = ATH_RSSI(sc->sc_halstats.ns_avgrssi);
6129 }
6130bad:
6131 return error;
6132}
6133
6134/*
6135 * Allocate a key cache slot to the station so we can
6136 * setup a mapping from key index to node. The key cache

--- 633 unchanged lines hidden (view full) ---

6770 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
6771 break;
6772 case SIOCGATHSTATS:
6773 /* NB: embed these numbers to get a consistent view */
6774 sc->sc_stats.ast_tx_packets = ifp->if_opackets;
6775 sc->sc_stats.ast_rx_packets = ifp->if_ipackets;
6776 sc->sc_stats.ast_tx_rssi = ATH_RSSI(sc->sc_halstats.ns_avgtxrssi);
6777 sc->sc_stats.ast_rx_rssi = ATH_RSSI(sc->sc_halstats.ns_avgrssi);
6778#ifdef ATH_SUPPORT_TDMA
6779 sc->sc_stats.ast_tdma_tsfadjp = TDMA_AVG(sc->sc_avgtsfdeltap);
6780 sc->sc_stats.ast_tdma_tsfadjm = TDMA_AVG(sc->sc_avgtsfdeltam);
6781#endif
6503 rt = sc->sc_currates;
6504 /* XXX HT rates */
6505 sc->sc_stats.ast_tx_rate =
6506 rt->info[sc->sc_txrix].dot11Rate &~ IEEE80211_RATE_BASIC;
6507 return copyout(&sc->sc_stats,
6508 ifr->ifr_data, sizeof (sc->sc_stats));
6509#ifdef ATH_DIAGAPI
6510 case SIOCGATHDIAG:

--- 360 unchanged lines hidden (view full) ---

6871 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
6872 "intmit", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
6873 ath_sysctl_intmit, "I", "interference mitigation");
6874 }
6875 sc->sc_monpass = HAL_RXERR_DECRYPT | HAL_RXERR_MIC;
6876 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
6877 "monpass", CTLFLAG_RW, &sc->sc_monpass, 0,
6878 "mask of error frames to pass when monitoring");
6782 rt = sc->sc_currates;
6783 /* XXX HT rates */
6784 sc->sc_stats.ast_tx_rate =
6785 rt->info[sc->sc_txrix].dot11Rate &~ IEEE80211_RATE_BASIC;
6786 return copyout(&sc->sc_stats,
6787 ifr->ifr_data, sizeof (sc->sc_stats));
6788#ifdef ATH_DIAGAPI
6789 case SIOCGATHDIAG:

--- 360 unchanged lines hidden (view full) ---

7150 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
7151 "intmit", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
7152 ath_sysctl_intmit, "I", "interference mitigation");
7153 }
7154 sc->sc_monpass = HAL_RXERR_DECRYPT | HAL_RXERR_MIC;
7155 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
7156 "monpass", CTLFLAG_RW, &sc->sc_monpass, 0,
7157 "mask of error frames to pass when monitoring");
7158#ifdef ATH_SUPPORT_TDMA
7159 if (ath_hal_macversion(ah) > 0x78) {
7160 sc->sc_tdmadbaprep = 2;
7161 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
7162 "dbaprep", CTLFLAG_RW, &sc->sc_tdmadbaprep, 0,
7163 "TDMA DBA preparation time");
7164 sc->sc_tdmaswbaprep = 10;
7165 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
7166 "swbaprep", CTLFLAG_RW, &sc->sc_tdmaswbaprep, 0,
7167 "TDMA SWBA preparation time");
7168 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
7169 "guardtime", CTLFLAG_RW, &sc->sc_tdmaguard, 0,
7170 "TDMA slot guard time");
7171 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
7172 "superframe", CTLFLAG_RD, &sc->sc_tdmabintval, 0,
7173 "TDMA calculated super frame");
7174 }
7175#endif
6879}
6880
6881static void
6882ath_bpfattach(struct ath_softc *sc)
6883{
6884 struct ifnet *ifp = sc->sc_ifp;
6885
6886 bpfattach(ifp, DLT_IEEE802_11_RADIO,

--- 231 unchanged lines hidden (view full) ---

7118 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) {
7119 ieee80211_free_node(ni);
7120 m_freem(m);
7121 return ENETDOWN;
7122 }
7123 /*
7124 * Grab a TX buffer and associated resources.
7125 */
7176}
7177
7178static void
7179ath_bpfattach(struct ath_softc *sc)
7180{
7181 struct ifnet *ifp = sc->sc_ifp;
7182
7183 bpfattach(ifp, DLT_IEEE802_11_RADIO,

--- 231 unchanged lines hidden (view full) ---

7415 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) {
7416 ieee80211_free_node(ni);
7417 m_freem(m);
7418 return ENETDOWN;
7419 }
7420 /*
7421 * Grab a TX buffer and associated resources.
7422 */
7126 ATH_TXBUF_LOCK(sc);
7127 bf = STAILQ_FIRST(&sc->sc_txbuf);
7128 if (bf != NULL)
7129 STAILQ_REMOVE_HEAD(&sc->sc_txbuf, bf_list);
7130 ATH_TXBUF_UNLOCK(sc);
7423 bf = ath_getbuf(sc);
7131 if (bf == NULL) {
7424 if (bf == NULL) {
7132 DPRINTF(sc, ATH_DEBUG_XMIT, "%s: out of xmit buffers\n",
7133 __func__);
7134 sc->sc_stats.ast_tx_qstop++;
7135 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
7136 ieee80211_free_node(ni);
7137 m_freem(m);
7138 return ENOBUFS;
7139 }
7140
7141 ifp->if_opackets++;
7142 sc->sc_stats.ast_tx_raw++;
7143

--- 13 unchanged lines hidden (view full) ---

7157 goto bad;
7158 }
7159 ifp->if_timer = 5;
7160
7161 return 0;
7162bad:
7163 ifp->if_oerrors++;
7164 ATH_TXBUF_LOCK(sc);
7425 ieee80211_free_node(ni);
7426 m_freem(m);
7427 return ENOBUFS;
7428 }
7429
7430 ifp->if_opackets++;
7431 sc->sc_stats.ast_tx_raw++;
7432

--- 13 unchanged lines hidden (view full) ---

7446 goto bad;
7447 }
7448 ifp->if_timer = 5;
7449
7450 return 0;
7451bad:
7452 ifp->if_oerrors++;
7453 ATH_TXBUF_LOCK(sc);
7165 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
7454 STAILQ_INSERT_HEAD(&sc->sc_txbuf, bf, bf_list);
7166 ATH_TXBUF_UNLOCK(sc);
7167 ieee80211_free_node(ni);
7168 return EIO; /* XXX */
7169}
7170
7171/*
7172 * Announce various information on device/driver attach.
7173 */

--- 41 unchanged lines hidden (view full) ---

7215 if_printf(ifp, "Use hw queue %u for beacons\n", sc->sc_bhalq);
7216 }
7217 if (ath_rxbuf != ATH_RXBUF)
7218 if_printf(ifp, "using %u rx buffers\n", ath_rxbuf);
7219 if (ath_txbuf != ATH_TXBUF)
7220 if_printf(ifp, "using %u tx buffers\n", ath_txbuf);
7221#undef HAL_MODE_DUALBAND
7222}
7455 ATH_TXBUF_UNLOCK(sc);
7456 ieee80211_free_node(ni);
7457 return EIO; /* XXX */
7458}
7459
7460/*
7461 * Announce various information on device/driver attach.
7462 */

--- 41 unchanged lines hidden (view full) ---

7504 if_printf(ifp, "Use hw queue %u for beacons\n", sc->sc_bhalq);
7505 }
7506 if (ath_rxbuf != ATH_RXBUF)
7507 if_printf(ifp, "using %u rx buffers\n", ath_rxbuf);
7508 if (ath_txbuf != ATH_TXBUF)
7509 if_printf(ifp, "using %u tx buffers\n", ath_txbuf);
7510#undef HAL_MODE_DUALBAND
7511}
7512
7513#ifdef ATH_SUPPORT_TDMA
7514static __inline uint32_t
7515ath_hal_getnexttbtt(struct ath_hal *ah)
7516{
7517#define AR_TIMER0 0x8028
7518 return OS_REG_READ(ah, AR_TIMER0);
7519}
7520
7521static __inline void
7522ath_hal_adjusttsf(struct ath_hal *ah, int32_t tsfdelta)
7523{
7524 /* XXX handle wrap/overflow */
7525 OS_REG_WRITE(ah, AR_TSF_L32, OS_REG_READ(ah, AR_TSF_L32) + tsfdelta);
7526}
7527
7528static void
7529ath_tdma_settimers(struct ath_softc *sc, u_int32_t nexttbtt, u_int32_t bintval)
7530{
7531 struct ath_hal *ah = sc->sc_ah;
7532 HAL_BEACON_TIMERS bt;
7533
7534 bt.bt_intval = bintval | HAL_BEACON_ENA;
7535 bt.bt_nexttbtt = nexttbtt;
7536 bt.bt_nextdba = (nexttbtt<<3) - sc->sc_tdmadbaprep;
7537 bt.bt_nextswba = (nexttbtt<<3) - sc->sc_tdmaswbaprep;
7538 bt.bt_nextatim = nexttbtt+1;
7539 ath_hal_beaconsettimers(ah, &bt);
7540}
7541
7542/*
7543 * Calculate the beacon interval. This is periodic in the
7544 * superframe for the bss. We assume each station is configured
7545 * identically wrt transmit rate so the guard time we calculate
7546 * above will be the same on all stations. Note we need to
7547 * factor in the xmit time because the hardware will schedule
7548 * a frame for transmit if the start of the frame is within
7549 * the burst time. When we get hardware that properly kills
7550 * frames in the PCU we can reduce/eliminate the guard time.
7551 *
7552 * Roundup to 1024 is so we have 1 TU buffer in the guard time
7553 * to deal with the granularity of the nexttbtt timer. 11n MAC's
7554 * with 1us timer granularity should allow us to reduce/eliminate
7555 * this.
7556 */
7557static void
7558ath_tdma_bintvalsetup(struct ath_softc *sc,
7559 const struct ieee80211_tdma_state *tdma)
7560{
7561 /* copy from vap state (XXX check all vaps have same value?) */
7562 sc->sc_tdmaslotlen = tdma->tdma_slotlen;
7563 sc->sc_tdmabintcnt = tdma->tdma_bintval;
7564
7565 sc->sc_tdmabintval = roundup((sc->sc_tdmaslotlen+sc->sc_tdmaguard) *
7566 tdma->tdma_slotcnt, 1024);
7567 sc->sc_tdmabintval >>= 10; /* TSF -> TU */
7568 if (sc->sc_tdmabintval & 1)
7569 sc->sc_tdmabintval++;
7570
7571 if (tdma->tdma_slot == 0) {
7572 /*
7573 * Only slot 0 beacons; other slots respond.
7574 */
7575 sc->sc_imask |= HAL_INT_SWBA;
7576 sc->sc_tdmaswba = 0; /* beacon immediately */
7577 } else {
7578 /* XXX all vaps must be slot 0 or slot !0 */
7579 sc->sc_imask &= ~HAL_INT_SWBA;
7580 }
7581}
7582
7583/*
7584 * Max 802.11 overhead. This assumes no 4-address frames and
7585 * the encapsulation done by ieee80211_encap (llc). We also
7586 * include potential crypto overhead.
7587 */
7588#define IEEE80211_MAXOVERHEAD \
7589 (sizeof(struct ieee80211_qosframe) \
7590 + sizeof(struct llc) \
7591 + IEEE80211_ADDR_LEN \
7592 + IEEE80211_WEP_IVLEN \
7593 + IEEE80211_WEP_KIDLEN \
7594 + IEEE80211_WEP_CRCLEN \
7595 + IEEE80211_WEP_MICLEN \
7596 + IEEE80211_CRC_LEN)
7597
7598/*
7599 * Setup initially for tdma operation. Start the beacon
7600 * timers and enable SWBA if we are slot 0. Otherwise
7601 * we wait for slot 0 to arrive so we can sync up before
7602 * starting to transmit.
7603 */
7604static void
7605ath_tdma_config(struct ath_softc *sc, struct ieee80211vap *vap)
7606{
7607 struct ath_hal *ah = sc->sc_ah;
7608 struct ifnet *ifp = sc->sc_ifp;
7609 struct ieee80211com *ic = ifp->if_l2com;
7610 const struct ieee80211_txparam *tp;
7611 const struct ieee80211_tdma_state *tdma = NULL;
7612 int rix;
7613
7614 if (vap == NULL) {
7615 vap = TAILQ_FIRST(&ic->ic_vaps); /* XXX */
7616 if (vap == NULL) {
7617 if_printf(ifp, "%s: no vaps?\n", __func__);
7618 return;
7619 }
7620 }
7621 tp = vap->iv_bss->ni_txparms;
7622 /*
7623 * Calculate the guard time for each slot. This is the
7624 * time to send a maximal-size frame according to the
7625 * fixed/lowest transmit rate. Note that the interface
7626 * mtu does not include the 802.11 overhead so we must
7627 * tack that on (ath_hal_computetxtime includes the
7628 * preamble and plcp in it's calculation).
7629 */
7630 tdma = vap->iv_tdma;
7631 if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
7632 rix = ath_tx_findrix(sc->sc_currates, tp->ucastrate);
7633 else
7634 rix = ath_tx_findrix(sc->sc_currates, tp->mcastrate);
7635 /* XXX short preamble assumed */
7636 sc->sc_tdmaguard = ath_hal_computetxtime(ah, sc->sc_currates,
7637 ifp->if_mtu + IEEE80211_MAXOVERHEAD, rix, AH_TRUE);
7638
7639 ath_hal_intrset(ah, 0);
7640
7641 ath_beaconq_config(sc); /* setup h/w beacon q */
7642 ath_hal_setcca(ah, AH_FALSE); /* disable CCA */
7643 ath_tdma_bintvalsetup(sc, tdma); /* calculate beacon interval */
7644 ath_tdma_settimers(sc, sc->sc_tdmabintval,
7645 sc->sc_tdmabintval | HAL_BEACON_RESET_TSF);
7646 sc->sc_syncbeacon = 0;
7647
7648 sc->sc_avgtsfdeltap = TDMA_DUMMY_MARKER;
7649 sc->sc_avgtsfdeltam = TDMA_DUMMY_MARKER;
7650
7651 ath_hal_intrset(ah, sc->sc_imask);
7652
7653 DPRINTF(sc, ATH_DEBUG_TDMA, "%s: slot %u len %uus cnt %u "
7654 "bsched %u guard %uus bintval %u TU dba prep %u\n", __func__,
7655 tdma->tdma_slot, tdma->tdma_slotlen, tdma->tdma_slotcnt,
7656 tdma->tdma_bintval, sc->sc_tdmaguard, sc->sc_tdmabintval,
7657 sc->sc_tdmadbaprep);
7658}
7659
7660/*
7661 * Update tdma operation. Called from the 802.11 layer
7662 * when a beacon is received from the TDMA station operating
7663 * in the slot immediately preceding us in the bss. Use
7664 * the rx timestamp for the beacon frame to update our
7665 * beacon timers so we follow their schedule. Note that
7666 * by using the rx timestamp we implicitly include the
7667 * propagation delay in our schedule.
7668 */
7669static void
7670ath_tdma_update(struct ieee80211_node *ni,
7671 const struct ieee80211_tdma_param *tdma)
7672{
7673#define TSF_TO_TU(_h,_l) \
7674 ((((u_int32_t)(_h)) << 22) | (((u_int32_t)(_l)) >> 10))
7675#define TU_TO_TSF(_tu) (((u_int64_t)(_tu)) << 10)
7676 struct ieee80211vap *vap = ni->ni_vap;
7677 struct ieee80211com *ic = ni->ni_ic;
7678 struct ath_softc *sc = ic->ic_ifp->if_softc;
7679 struct ath_hal *ah = sc->sc_ah;
7680 const HAL_RATE_TABLE *rt = sc->sc_currates;
7681 u_int64_t tsf, rstamp, nextslot;
7682 u_int32_t txtime, nextslottu, timer0;
7683 int32_t tudelta, tsfdelta;
7684 const struct ath_rx_status *rs;
7685 int rix;
7686
7687 sc->sc_stats.ast_tdma_update++;
7688
7689 /*
7690 * Check for and adopt configuration changes.
7691 */
7692 if (isset(ATH_VAP(vap)->av_boff.bo_flags, IEEE80211_BEACON_TDMA)) {
7693 const struct ieee80211_tdma_state *ts = vap->iv_tdma;
7694
7695 ath_tdma_bintvalsetup(sc, ts);
7696
7697 DPRINTF(sc, ATH_DEBUG_TDMA,
7698 "%s: adopt slot %u slotcnt %u slotlen %u us "
7699 "bintval %u TU\n", __func__,
7700 ts->tdma_slot, ts->tdma_slotcnt, ts->tdma_slotlen,
7701 sc->sc_tdmabintval);
7702
7703 ath_beaconq_config(sc);
7704 /* XXX right? */
7705 ath_hal_intrset(ah, sc->sc_imask);
7706 /* NB: beacon timers programmed below */
7707 }
7708
7709 /* extend rx timestamp to 64 bits */
7710 tsf = ath_hal_gettsf64(ah);
7711 rstamp = ath_extend_tsf(ni->ni_rstamp, tsf);
7712 /*
7713 * The rx timestamp is set by the hardware on completing
7714 * reception (at the point where the rx descriptor is DMA'd
7715 * to the host). To find the start of our next slot we
7716 * must adjust this time by the time required to send
7717 * the packet just received.
7718 */
7719 rs = sc->sc_tdmars;
7720 rix = rt->rateCodeToIndex[rs->rs_rate];
7721 txtime = ath_hal_computetxtime(ah, rt, rs->rs_datalen, rix,
7722 rt->info[rix].shortPreamble);
7723 /* NB: << 9 is to cvt to TU and /2 */
7724 nextslot = (rstamp - txtime) + (sc->sc_tdmabintval << 9);
7725 nextslottu = TSF_TO_TU(nextslot>>32, nextslot) & HAL_BEACON_PERIOD;
7726
7727 /*
7728 * TIMER0 is the h/w's idea of NextTBTT (in TU's). Convert
7729 * to usecs and calculate the difference between what the
7730 * other station thinks and what we have programmed. This
7731 * lets us figure how to adjust our timers to match. The
7732 * adjustments are done by pulling the TSF forward and possibly
7733 * rewriting the beacon timers.
7734 */
7735 timer0 = ath_hal_getnexttbtt(ah);
7736 tsfdelta = (int32_t)((nextslot % TU_TO_TSF(HAL_BEACON_PERIOD+1)) - TU_TO_TSF(timer0));
7737
7738 DPRINTF(sc, ATH_DEBUG_TDMA_TIMER,
7739 "tsfdelta %d avg +%d/-%d\n", tsfdelta,
7740 TDMA_AVG(sc->sc_avgtsfdeltap), TDMA_AVG(sc->sc_avgtsfdeltam));
7741
7742 if (tsfdelta < 0) {
7743 TDMA_SAMPLE(sc->sc_avgtsfdeltap, 0);
7744 TDMA_SAMPLE(sc->sc_avgtsfdeltam, -tsfdelta);
7745 tsfdelta = -tsfdelta % 1024;
7746 nextslottu++;
7747 } else if (tsfdelta > 0) {
7748 TDMA_SAMPLE(sc->sc_avgtsfdeltap, tsfdelta);
7749 TDMA_SAMPLE(sc->sc_avgtsfdeltam, 0);
7750 tsfdelta = 1024 - (tsfdelta % 1024);
7751 nextslottu++;
7752 } else {
7753 TDMA_SAMPLE(sc->sc_avgtsfdeltap, 0);
7754 TDMA_SAMPLE(sc->sc_avgtsfdeltam, 0);
7755 }
7756 tudelta = nextslottu - timer0;
7757
7758 /*
7759 * Copy sender's timetstamp into tdma ie so they can
7760 * calculate roundtrip time. We submit a beacon frame
7761 * below after any timer adjustment. The frame goes out
7762 * at the next TBTT so the sender can calculate the
7763 * roundtrip by inspecting the tdma ie in our beacon frame.
7764 *
7765 * NB: This tstamp is subtlely preserved when
7766 * IEEE80211_BEACON_TDMA is marked (e.g. when the
7767 * slot position changes) because ieee80211_add_tdma
7768 * skips over the data.
7769 */
7770 memcpy(ATH_VAP(vap)->av_boff.bo_tdma +
7771 __offsetof(struct ieee80211_tdma_param, tdma_tstamp),
7772 &ni->ni_tstamp.data, 8);
7773#if 0
7774 DPRINTF(sc, ATH_DEBUG_TDMA_TIMER,
7775 "tsf %llu nextslot %llu (%d, %d) nextslottu %u timer0 %u (%d)\n",
7776 (unsigned long long) tsf, (unsigned long long) nextslot,
7777 (int)(nextslot - tsf), tsfdelta,
7778 nextslottu, timer0, tudelta);
7779#endif
7780 /*
7781 * Adjust the beacon timers only when pulling them forward
7782 * or when going back by less than the beacon interval.
7783 * Negative jumps larger than the beacon interval seem to
7784 * cause the timers to stop and generally cause instability.
7785 * This basically filters out jumps due to missed beacons.
7786 */
7787 if (tudelta != 0 && (tudelta > 0 || -tudelta < sc->sc_tdmabintval)) {
7788 ath_tdma_settimers(sc, nextslottu, sc->sc_tdmabintval);
7789 sc->sc_stats.ast_tdma_timers++;
7790 }
7791 if (tsfdelta > 0) {
7792 ath_hal_adjusttsf(ah, tsfdelta);
7793 sc->sc_stats.ast_tdma_tsf++;
7794 }
7795 ath_tdma_beacon_send(sc, vap); /* prepare response */
7796#undef TU_TO_TSF
7797#undef TSF_TO_TU
7798}
7799
7800/*
7801 * Transmit a beacon frame at SWBA. Dynamic updates
7802 * to the frame contents are done as needed.
7803 */
7804static void
7805ath_tdma_beacon_send(struct ath_softc *sc, struct ieee80211vap *vap)
7806{
7807 struct ath_hal *ah = sc->sc_ah;
7808 struct ath_buf *bf;
7809 int otherant;
7810
7811 /*
7812 * Check if the previous beacon has gone out. If
7813 * not don't try to post another, skip this period
7814 * and wait for the next. Missed beacons indicate
7815 * a problem and should not occur. If we miss too
7816 * many consecutive beacons reset the device.
7817 */
7818 if (ath_hal_numtxpending(ah, sc->sc_bhalq) != 0) {
7819 sc->sc_bmisscount++;
7820 DPRINTF(sc, ATH_DEBUG_BEACON,
7821 "%s: missed %u consecutive beacons\n",
7822 __func__, sc->sc_bmisscount);
7823 if (sc->sc_bmisscount > 3) /* NB: 3 is a guess */
7824 taskqueue_enqueue(sc->sc_tq, &sc->sc_bstucktask);
7825 return;
7826 }
7827 if (sc->sc_bmisscount != 0) {
7828 DPRINTF(sc, ATH_DEBUG_BEACON,
7829 "%s: resume beacon xmit after %u misses\n",
7830 __func__, sc->sc_bmisscount);
7831 sc->sc_bmisscount = 0;
7832 }
7833
7834 /*
7835 * Check recent per-antenna transmit statistics and flip
7836 * the default antenna if noticeably more frames went out
7837 * on the non-default antenna.
7838 * XXX assumes 2 anntenae
7839 */
7840 if (!sc->sc_diversity) {
7841 otherant = sc->sc_defant & 1 ? 2 : 1;
7842 if (sc->sc_ant_tx[otherant] > sc->sc_ant_tx[sc->sc_defant] + 2)
7843 ath_setdefantenna(sc, otherant);
7844 sc->sc_ant_tx[1] = sc->sc_ant_tx[2] = 0;
7845 }
7846
7847 bf = ath_beacon_generate(sc, vap);
7848 if (bf != NULL) {
7849 /*
7850 * Stop any current dma and put the new frame on the queue.
7851 * This should never fail since we check above that no frames
7852 * are still pending on the queue.
7853 */
7854 if (!ath_hal_stoptxdma(ah, sc->sc_bhalq)) {
7855 DPRINTF(sc, ATH_DEBUG_ANY,
7856 "%s: beacon queue %u did not stop?\n",
7857 __func__, sc->sc_bhalq);
7858 /* NB: the HAL still stops DMA, so proceed */
7859 }
7860 ath_hal_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr);
7861 ath_hal_txstart(ah, sc->sc_bhalq);
7862
7863 sc->sc_stats.ast_be_xmit++; /* XXX per-vap? */
7864
7865 /*
7866 * Record local TSF for our last send for use
7867 * in arbitrating slot collisions.
7868 */
7869 vap->iv_bss->ni_tstamp.tsf = ath_hal_gettsf64(ah);
7870 }
7871}
7872#endif /* ATH_SUPPORT_TDMA */