Deleted Added
full compact
if_ath.c (152448) if_ath.c (154140)
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 152448 2005-11-15 05:49:02Z sam $");
38__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 154140 2006-01-09 17:13:20Z 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

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

2535 if (sc->sc_rxlink != NULL)
2536 *sc->sc_rxlink = bf->bf_daddr;
2537 sc->sc_rxlink = &ds->ds_link;
2538 return 0;
2539}
2540
2541/*
2542 * Extend 15-bit time stamp from rx descriptor to
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

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

2535 if (sc->sc_rxlink != NULL)
2536 *sc->sc_rxlink = bf->bf_daddr;
2537 sc->sc_rxlink = &ds->ds_link;
2538 return 0;
2539}
2540
2541/*
2542 * Extend 15-bit time stamp from rx descriptor to
2543 * a full 64-bit TSF using the current h/w TSF.
2543 * a full 64-bit TSF using the specified TSF.
2544 */
2545static __inline u_int64_t
2544 */
2545static __inline u_int64_t
2546ath_extend_tsf(struct ath_hal *ah, u_int32_t rstamp)
2546ath_extend_tsf(u_int32_t rstamp, u_int64_t tsf)
2547{
2547{
2548 u_int64_t tsf;
2549
2550 tsf = ath_hal_gettsf64(ah);
2551 if ((tsf & 0x7fff) < rstamp)
2552 tsf -= 0x8000;
2553 return ((tsf &~ 0x7fff) | rstamp);
2554}
2555
2556/*
2557 * Intercept management frames to collect beacon rssi data
2558 * and to do ibss merges.

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

2572 switch (subtype) {
2573 case IEEE80211_FC0_SUBTYPE_BEACON:
2574 /* update rssi statistics for use by the hal */
2575 ATH_RSSI_LPF(ATH_NODE(ni)->an_halstats.ns_avgbrssi, rssi);
2576 /* fall thru... */
2577 case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
2578 if (ic->ic_opmode == IEEE80211_M_IBSS &&
2579 ic->ic_state == IEEE80211_S_RUN) {
2548 if ((tsf & 0x7fff) < rstamp)
2549 tsf -= 0x8000;
2550 return ((tsf &~ 0x7fff) | rstamp);
2551}
2552
2553/*
2554 * Intercept management frames to collect beacon rssi data
2555 * and to do ibss merges.

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

2569 switch (subtype) {
2570 case IEEE80211_FC0_SUBTYPE_BEACON:
2571 /* update rssi statistics for use by the hal */
2572 ATH_RSSI_LPF(ATH_NODE(ni)->an_halstats.ns_avgbrssi, rssi);
2573 /* fall thru... */
2574 case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
2575 if (ic->ic_opmode == IEEE80211_M_IBSS &&
2576 ic->ic_state == IEEE80211_S_RUN) {
2580 u_int64_t tsf = ath_extend_tsf(sc->sc_ah, rstamp);
2577 u_int64_t tsf = ath_extend_tsf(rstamp,
2578 ath_hal_gettsf64(sc->sc_ah));
2581 /*
2582 * Handle ibss merge as needed; check the tsf on the
2583 * frame before attempting the merge. The 802.11 spec
2584 * says the station should change it's bssid to match
2585 * the oldest station with the same ssid, where oldest
2586 * is determined by the tsf. Note that hardware
2587 * reconfiguration happens through callback to
2588 * ath_newstate as the state machine will go from

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

2611 /* XXX block beacon interrupts */
2612 ath_hal_setdefantenna(ah, antenna);
2613 if (sc->sc_defant != antenna)
2614 sc->sc_stats.ast_ant_defswitch++;
2615 sc->sc_defant = antenna;
2616 sc->sc_rxotherant = 0;
2617}
2618
2579 /*
2580 * Handle ibss merge as needed; check the tsf on the
2581 * frame before attempting the merge. The 802.11 spec
2582 * says the station should change it's bssid to match
2583 * the oldest station with the same ssid, where oldest
2584 * is determined by the tsf. Note that hardware
2585 * reconfiguration happens through callback to
2586 * ath_newstate as the state machine will go from

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

2609 /* XXX block beacon interrupts */
2610 ath_hal_setdefantenna(ah, antenna);
2611 if (sc->sc_defant != antenna)
2612 sc->sc_stats.ast_ant_defswitch++;
2613 sc->sc_defant = antenna;
2614 sc->sc_rxotherant = 0;
2615}
2616
2617static int
2618ath_rx_tap(struct ath_softc *sc, struct mbuf *m,
2619 const struct ath_desc *ds, u_int64_t tsf, int16_t nf)
2620{
2621 u_int8_t rix;
2622
2623 KASSERT(sc->sc_drvbpf != NULL, ("no tap"));
2624
2625 /*
2626 * Discard anything shorter than an ack or cts.
2627 */
2628 if (m->m_pkthdr.len < IEEE80211_ACK_LEN) {
2629 DPRINTF(sc, ATH_DEBUG_RECV, "%s: runt packet %d\n",
2630 __func__, m->m_pkthdr.len);
2631 sc->sc_stats.ast_rx_tooshort++;
2632 return 0;
2633 }
2634 sc->sc_rx_th.wr_tsf = htole64(
2635 ath_extend_tsf(ds->ds_rxstat.rs_tstamp, tsf));
2636 rix = ds->ds_rxstat.rs_rate;
2637 sc->sc_rx_th.wr_flags = sc->sc_hwmap[rix].rxflags;
2638 if (ds->ds_rxstat.rs_status & HAL_RXERR_CRC)
2639 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
2640 /* XXX propagate other error flags from descriptor */
2641 sc->sc_rx_th.wr_rate = sc->sc_hwmap[rix].ieeerate;
2642 sc->sc_rx_th.wr_antsignal = ds->ds_rxstat.rs_rssi + nf;
2643 sc->sc_rx_th.wr_antnoise = nf;
2644 sc->sc_rx_th.wr_antenna = ds->ds_rxstat.rs_antenna;
2645
2646 bpf_mtap2(sc->sc_drvbpf, &sc->sc_rx_th, sc->sc_rx_th_len, m);
2647
2648 return 1;
2649}
2650
2619static void
2620ath_rx_proc(void *arg, int npending)
2621{
2622#define PA2DESC(_sc, _pa) \
2623 ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \
2624 ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr)))
2625 struct ath_softc *sc = arg;
2626 struct ath_buf *bf;
2627 struct ieee80211com *ic = &sc->sc_ic;
2628 struct ifnet *ifp = sc->sc_ifp;
2629 struct ath_hal *ah = sc->sc_ah;
2630 struct ath_desc *ds;
2631 struct mbuf *m;
2632 struct ieee80211_node *ni;
2633 struct ath_node *an;
2634 int len, type;
2635 u_int phyerr;
2636 HAL_STATUS status;
2651static void
2652ath_rx_proc(void *arg, int npending)
2653{
2654#define PA2DESC(_sc, _pa) \
2655 ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \
2656 ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr)))
2657 struct ath_softc *sc = arg;
2658 struct ath_buf *bf;
2659 struct ieee80211com *ic = &sc->sc_ic;
2660 struct ifnet *ifp = sc->sc_ifp;
2661 struct ath_hal *ah = sc->sc_ah;
2662 struct ath_desc *ds;
2663 struct mbuf *m;
2664 struct ieee80211_node *ni;
2665 struct ath_node *an;
2666 int len, type;
2667 u_int phyerr;
2668 HAL_STATUS status;
2669 int16_t nf;
2670 u_int64_t tsf;
2637
2638 NET_LOCK_GIANT(); /* XXX */
2639
2640 DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending);
2671
2672 NET_LOCK_GIANT(); /* XXX */
2673
2674 DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending);
2675 nf = ath_hal_getchannoise(ah, &sc->sc_curchan);
2676 tsf = ath_hal_gettsf64(ah);
2641 do {
2642 bf = STAILQ_FIRST(&sc->sc_rxbuf);
2643 if (bf == NULL) { /* NB: shouldn't happen */
2644 if_printf(ifp, "%s: no buffer!\n", __func__);
2645 break;
2646 }
2647 ds = bf->bf_desc;
2648 if (ds->ds_link == bf->bf_daddr) {

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

2730 sc->sc_splitmic ?
2731 ds->ds_rxstat.rs_keyix-32 :
2732 ds->ds_rxstat.rs_keyix
2733 );
2734 }
2735 }
2736 ifp->if_ierrors++;
2737 /*
2677 do {
2678 bf = STAILQ_FIRST(&sc->sc_rxbuf);
2679 if (bf == NULL) { /* NB: shouldn't happen */
2680 if_printf(ifp, "%s: no buffer!\n", __func__);
2681 break;
2682 }
2683 ds = bf->bf_desc;
2684 if (ds->ds_link == bf->bf_daddr) {

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

2766 sc->sc_splitmic ?
2767 ds->ds_rxstat.rs_keyix-32 :
2768 ds->ds_rxstat.rs_keyix
2769 );
2770 }
2771 }
2772 ifp->if_ierrors++;
2773 /*
2738 * Reject error frames, we normally don't want
2739 * to see them in monitor mode (in monitor mode
2740 * allow through packets that have crypto problems).
2774 * When a tap is present pass error frames
2775 * that have been requested. By default we
2776 * pass decrypt+mic errors but others may be
2777 * interesting (e.g. crc).
2741 */
2778 */
2742 if ((ds->ds_rxstat.rs_status &~
2743 (HAL_RXERR_DECRYPT|HAL_RXERR_MIC)) ||
2744 sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR)
2745 goto rx_next;
2779 if (sc->sc_drvbpf != NULL &&
2780 (ds->ds_rxstat.rs_status & sc->sc_monpass)) {
2781 bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap,
2782 BUS_DMASYNC_POSTREAD);
2783 /* NB: bpf needs the mbuf length setup */
2784 len = ds->ds_rxstat.rs_datalen;
2785 m->m_pkthdr.len = m->m_len = len;
2786 (void) ath_rx_tap(sc, m, ds, tsf, nf);
2787 }
2788 /* XXX pass MIC errors up for s/w reclaculation */
2789 goto rx_next;
2746 }
2747rx_accept:
2748 /*
2749 * Sync and unmap the frame. At this point we're
2750 * committed to passing the mbuf somewhere so clear
2751 * bf_m; this means a new sk_buff must be allocated
2752 * when the rx descriptor is setup again to receive
2753 * another frame.

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

2758 bf->bf_m = NULL;
2759
2760 m->m_pkthdr.rcvif = ifp;
2761 len = ds->ds_rxstat.rs_datalen;
2762 m->m_pkthdr.len = m->m_len = len;
2763
2764 sc->sc_stats.ast_ant_rx[ds->ds_rxstat.rs_antenna]++;
2765
2790 }
2791rx_accept:
2792 /*
2793 * Sync and unmap the frame. At this point we're
2794 * committed to passing the mbuf somewhere so clear
2795 * bf_m; this means a new sk_buff must be allocated
2796 * when the rx descriptor is setup again to receive
2797 * another frame.

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

2802 bf->bf_m = NULL;
2803
2804 m->m_pkthdr.rcvif = ifp;
2805 len = ds->ds_rxstat.rs_datalen;
2806 m->m_pkthdr.len = m->m_len = len;
2807
2808 sc->sc_stats.ast_ant_rx[ds->ds_rxstat.rs_antenna]++;
2809
2766 if (sc->sc_drvbpf) {
2767 u_int8_t rix;
2768
2769 /*
2770 * Discard anything shorter than an ack or cts.
2771 */
2772 if (len < IEEE80211_ACK_LEN) {
2773 DPRINTF(sc, ATH_DEBUG_RECV,
2774 "%s: runt packet %d\n",
2775 __func__, len);
2776 sc->sc_stats.ast_rx_tooshort++;
2777 m_freem(m);
2778 goto rx_next;
2779 }
2780 rix = ds->ds_rxstat.rs_rate;
2781 sc->sc_rx_th.wr_flags = sc->sc_hwmap[rix].rxflags;
2782 sc->sc_rx_th.wr_rate = sc->sc_hwmap[rix].ieeerate;
2783 sc->sc_rx_th.wr_antsignal = ds->ds_rxstat.rs_rssi;
2784 sc->sc_rx_th.wr_antenna = ds->ds_rxstat.rs_antenna;
2785 /* XXX TSF */
2786
2787 bpf_mtap2(sc->sc_drvbpf,
2788 &sc->sc_rx_th, sc->sc_rx_th_len, m);
2810 if (sc->sc_drvbpf != NULL && !ath_rx_tap(sc, m, ds, tsf, nf)) {
2811 m_freem(m); /* XXX reclaim */
2812 goto rx_next;
2789 }
2790
2791 /*
2792 * From this point on we assume the frame is at least
2793 * as large as ieee80211_frame_min; verify that.
2794 */
2795 if (len < IEEE80211_MIN_LEN) {
2796 DPRINTF(sc, ATH_DEBUG_RECV, "%s: short packet %d\n",

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

3437
3438 if (IFF_DUMPPKTS(sc, ATH_DEBUG_XMIT))
3439 ieee80211_dump_pkt(mtod(m0, caddr_t), m0->m_len,
3440 sc->sc_hwmap[txrate].ieeerate, -1);
3441
3442 if (ic->ic_rawbpf)
3443 bpf_mtap(ic->ic_rawbpf, m0);
3444 if (sc->sc_drvbpf) {
2813 }
2814
2815 /*
2816 * From this point on we assume the frame is at least
2817 * as large as ieee80211_frame_min; verify that.
2818 */
2819 if (len < IEEE80211_MIN_LEN) {
2820 DPRINTF(sc, ATH_DEBUG_RECV, "%s: short packet %d\n",

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

3461
3462 if (IFF_DUMPPKTS(sc, ATH_DEBUG_XMIT))
3463 ieee80211_dump_pkt(mtod(m0, caddr_t), m0->m_len,
3464 sc->sc_hwmap[txrate].ieeerate, -1);
3465
3466 if (ic->ic_rawbpf)
3467 bpf_mtap(ic->ic_rawbpf, m0);
3468 if (sc->sc_drvbpf) {
3469 u_int64_t tsf = ath_hal_gettsf64(ah);
3470
3471 sc->sc_tx_th.wt_tsf = htole64(tsf);
3445 sc->sc_tx_th.wt_flags = sc->sc_hwmap[txrate].txflags;
3446 if (iswep)
3447 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
3448 sc->sc_tx_th.wt_rate = sc->sc_hwmap[txrate].ieeerate;
3449 sc->sc_tx_th.wt_txpower = ni->ni_txpower;
3450 sc->sc_tx_th.wt_antenna = sc->sc_txantenna;
3451
3452 bpf_mtap2(sc->sc_drvbpf,

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

4019 ath_reset(sc->sc_ifp);
4020 }
4021 if (!ath_hal_calibrate(ah, &sc->sc_curchan)) {
4022 DPRINTF(sc, ATH_DEBUG_ANY,
4023 "%s: calibration of channel %u failed\n",
4024 __func__, sc->sc_curchan.channel);
4025 sc->sc_stats.ast_per_calfail++;
4026 }
3472 sc->sc_tx_th.wt_flags = sc->sc_hwmap[txrate].txflags;
3473 if (iswep)
3474 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
3475 sc->sc_tx_th.wt_rate = sc->sc_hwmap[txrate].ieeerate;
3476 sc->sc_tx_th.wt_txpower = ni->ni_txpower;
3477 sc->sc_tx_th.wt_antenna = sc->sc_txantenna;
3478
3479 bpf_mtap2(sc->sc_drvbpf,

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

4046 ath_reset(sc->sc_ifp);
4047 }
4048 if (!ath_hal_calibrate(ah, &sc->sc_curchan)) {
4049 DPRINTF(sc, ATH_DEBUG_ANY,
4050 "%s: calibration of channel %u failed\n",
4051 __func__, sc->sc_curchan.channel);
4052 sc->sc_stats.ast_per_calfail++;
4053 }
4054 /*
4055 * Calibrate noise floor data again in case of change.
4056 */
4057 ath_hal_process_noisefloor(ah);
4027 callout_reset(&sc->sc_cal_ch, ath_calinterval * hz, ath_calibrate, sc);
4028}
4029
4030static int
4031ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
4032{
4033 struct ifnet *ifp = ic->ic_ifp;
4034 struct ath_softc *sc = ifp->if_softc;

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

4134 ni->ni_ucastkey.wk_keyix == IEEE80211_KEYIX_NONE)
4135 ath_setup_stationkey(ni);
4136 break;
4137 default:
4138 break;
4139 }
4140
4141 /*
4058 callout_reset(&sc->sc_cal_ch, ath_calinterval * hz, ath_calibrate, sc);
4059}
4060
4061static int
4062ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
4063{
4064 struct ifnet *ifp = ic->ic_ifp;
4065 struct ath_softc *sc = ifp->if_softc;

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

4165 ni->ni_ucastkey.wk_keyix == IEEE80211_KEYIX_NONE)
4166 ath_setup_stationkey(ni);
4167 break;
4168 default:
4169 break;
4170 }
4171
4172 /*
4173 * Let the hal process statistics collected during a
4174 * scan so it can provide calibrated noise floor data.
4175 */
4176 ath_hal_process_noisefloor(ah);
4177 /*
4142 * Configure the beacon and sleep timers.
4143 */
4144 ath_beacon_config(sc);
4145 } else {
4146 ath_hal_intrset(ah,
4147 sc->sc_imask &~ (HAL_INT_SWBA | HAL_INT_BMISS));
4148 sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS);
4149 }

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

4856 ath_sysctl_diag, "I", "h/w diagnostic control");
4857 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
4858 "tpscale", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
4859 ath_sysctl_tpscale, "I", "tx power scaling");
4860 if (ath_hal_hastpc(ah))
4861 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
4862 "tpc", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
4863 ath_sysctl_tpc, "I", "enable/disable per-packet TPC");
4178 * Configure the beacon and sleep timers.
4179 */
4180 ath_beacon_config(sc);
4181 } else {
4182 ath_hal_intrset(ah,
4183 sc->sc_imask &~ (HAL_INT_SWBA | HAL_INT_BMISS));
4184 sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS);
4185 }

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

4892 ath_sysctl_diag, "I", "h/w diagnostic control");
4893 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
4894 "tpscale", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
4895 ath_sysctl_tpscale, "I", "tx power scaling");
4896 if (ath_hal_hastpc(ah))
4897 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
4898 "tpc", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
4899 ath_sysctl_tpc, "I", "enable/disable per-packet TPC");
4900 sc->sc_monpass = HAL_RXERR_DECRYPT | HAL_RXERR_MIC;
4901 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
4902 "monpass", CTLFLAG_RW, &sc->sc_monpass, 0,
4903 "mask of error frames to pass when monitoring");
4864}
4865
4866static void
4867ath_bpfattach(struct ath_softc *sc)
4868{
4869 struct ifnet *ifp = sc->sc_ifp;
4870
4871 bpfattach2(ifp, DLT_IEEE802_11_RADIO,

--- 68 unchanged lines hidden ---
4904}
4905
4906static void
4907ath_bpfattach(struct ath_softc *sc)
4908{
4909 struct ifnet *ifp = sc->sc_ifp;
4910
4911 bpfattach2(ifp, DLT_IEEE802_11_RADIO,

--- 68 unchanged lines hidden ---