From owner-p4-projects@FreeBSD.ORG Tue Jan 27 12:13:55 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 86F0E16A4D0; Tue, 27 Jan 2004 12:13:55 -0800 (PST) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 594AE16A4CE for ; Tue, 27 Jan 2004 12:13:55 -0800 (PST) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1142143D5C for ; Tue, 27 Jan 2004 12:13:01 -0800 (PST) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.10/8.12.10) with ESMTP id i0RKD00B090072 for ; Tue, 27 Jan 2004 12:13:00 -0800 (PST) (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.10/8.12.10/Submit) id i0RKD0Ti090061 for perforce@freebsd.org; Tue, 27 Jan 2004 12:13:00 -0800 (PST) (envelope-from sam@freebsd.org) Date: Tue, 27 Jan 2004 12:13:00 -0800 (PST) Message-Id: <200401272013.i0RKD0Ti090061@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Subject: PERFORCE change 46014 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Jan 2004 20:13:56 -0000 http://perforce.freebsd.org/chv.cgi?CH=46014 Change 46014 by sam@sam_ebb on 2004/01/27 12:12:00 Checkpoint in-progress merge of the netbsd and madwifi work. Affected files ... .. //depot/projects/netperf+sockets/sys/conf/files#7 edit .. //depot/projects/netperf+sockets/sys/dev/ath/if_ath.c#18 edit .. //depot/projects/netperf+sockets/sys/dev/ath/if_ath_pci.c#3 edit .. //depot/projects/netperf+sockets/sys/dev/ath/if_athioctl.h#6 edit .. //depot/projects/netperf+sockets/sys/dev/ath/if_athvar.h#5 edit .. //depot/projects/netperf+sockets/sys/dev/awi/awi.c#6 edit .. //depot/projects/netperf+sockets/sys/dev/awi/awivar.h#3 edit .. //depot/projects/netperf+sockets/sys/dev/wi/if_wi.c#7 edit .. //depot/projects/netperf+sockets/sys/dev/wi/if_wivar.h#3 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211.c#7 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211.h#7 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_compat.c#3 delete .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_compat.h#4 delete .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_crypto.c#4 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_crypto.h#4 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_freebsd.c#1 add .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_freebsd.h#1 add .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_input.c#6 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_ioctl.c#11 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_ioctl.h#4 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_linux.c#1 add .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_linux.h#1 add .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_linux.o#1 add .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_netbsd.c#1 add .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_netbsd.h#1 add .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_node.c#4 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_node.h#4 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_output.c#7 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_proto.c#5 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_proto.h#4 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_radiotap.h#5 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_var.h#7 edit Differences ... ==== //depot/projects/netperf+sockets/sys/conf/files#7 (text+ko) ==== @@ -1267,6 +1267,7 @@ net/zlib.c optional crypto net80211/ieee80211.c optional wlan net80211/ieee80211_crypto.c optional wlan +net80211/ieee80211_freebsd.c optional wlan net80211/ieee80211_input.c optional wlan net80211/ieee80211_ioctl.c optional wlan net80211/ieee80211_node.c optional wlan ==== //depot/projects/netperf+sockets/sys/dev/ath/if_ath.c#18 (text+ko) ==== @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting + * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -105,7 +105,7 @@ static void ath_initkeytable(struct ath_softc *); static void ath_mode_init(struct ath_softc *); static int ath_beacon_alloc(struct ath_softc *, struct ieee80211_node *); -static void ath_beacon_proc(void *, int); +static void ath_beacon_proc(struct ath_softc *); static void ath_beacon_free(struct ath_softc *); static void ath_beacon_config(struct ath_softc *); static int ath_desc_alloc(struct ath_softc *); @@ -121,6 +121,7 @@ static int ath_tx_start(struct ath_softc *, struct ieee80211_node *, struct ath_buf *, struct mbuf *); static void ath_tx_proc(void *, int); +static void ath_chan_change(struct ath_softc *, struct ieee80211_channel *); static int ath_chan_set(struct ath_softc *, struct ieee80211_channel *); static void ath_draintxq(struct ath_softc *); static void ath_stoprecv(struct ath_softc *); @@ -131,9 +132,9 @@ static void ath_newassoc(struct ieee80211com *, struct ieee80211_node *, int); static int ath_getchannels(struct ath_softc *, u_int cc, - HAL_BOOL outdoor, HAL_BOOL xchans); + HAL_BOOL outdoor, HAL_BOOL xchanmode); -static int ath_rate_setup(struct ath_softc *sc, u_int mode); +static int ath_rate_setup(struct ath_softc *, u_int mode); static void ath_setcurmode(struct ath_softc *, enum ieee80211_phymode); static void ath_rate_update(struct ath_softc *, struct ieee80211_node *, int rate); @@ -204,7 +205,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = &ic->ic_if; + struct ifnet *ifp = &sc->sc_if; struct ath_hal *ah; HAL_STATUS status; int error = 0; @@ -290,7 +291,6 @@ TASK_INIT(&sc->sc_txtask, 0, ath_tx_proc, sc); TASK_INIT(&sc->sc_rxtask, 0, ath_rx_proc, sc); - TASK_INIT(&sc->sc_swbatask, 0, ath_beacon_proc, sc); TASK_INIT(&sc->sc_rxorntask, 0, ath_rxorn_proc, sc); TASK_INIT(&sc->sc_fataltask, 0, ath_fatal_proc, sc); TASK_INIT(&sc->sc_bmisstask, 0, ath_bmiss_proc, sc); @@ -308,7 +308,7 @@ ); if (sc->sc_txhalq == (u_int) -1) { if_printf(ifp, "unable to setup a data xmit queue!\n"); - goto bad; + goto bad2; } sc->sc_bhalq = ath_hal_setuptxqueue(ah, HAL_TX_QUEUE_BEACON, @@ -316,7 +316,7 @@ ); if (sc->sc_bhalq == (u_int) -1) { if_printf(ifp, "unable to setup a beacon xmit queue!\n"); - goto bad; + goto bad2; } ifp->if_softc = sc; @@ -327,7 +327,7 @@ ifp->if_init = ath_init; ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; - ic->ic_softc = sc; + ic->ic_ifp = ifp; ic->ic_reset = ath_reset; ic->ic_newassoc = ath_newassoc; /* XXX not right but it's not used anywhere important */ @@ -346,7 +346,7 @@ ath_hal_getmac(ah, ic->ic_myaddr); /* call MI attach routine. */ - ieee80211_ifattach(ifp); + ieee80211_ifattach(ic); /* override default methods */ ic->ic_node_alloc = ath_node_alloc; ic->ic_node_free = ath_node_free; @@ -355,7 +355,7 @@ sc->sc_newstate = ic->ic_newstate; ic->ic_newstate = ath_newstate; /* complete initialization */ - ieee80211_media_init(ifp, ath_media_change, ieee80211_media_status); + ieee80211_media_init(ic, ath_media_change, ieee80211_media_status); bpfattach2(ifp, DLT_IEEE802_11_RADIO, sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th), @@ -375,6 +375,8 @@ if_printf(ifp, "802.11 address: %s\n", ether_sprintf(ic->ic_myaddr)); return 0; +bad2: + ath_desc_free(sc); bad: if (ah) ath_hal_detach(ah); @@ -385,7 +387,8 @@ int ath_detach(struct ath_softc *sc) { - struct ifnet *ifp = &sc->sc_ic.ic_if; + struct ifnet *ifp = &sc->sc_if; + struct ieee80211com *ic = &sc->sc_ic; DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags %x\n", __func__, ifp->if_flags)); @@ -395,7 +398,7 @@ ATH_TXQ_LOCK_DESTROY(sc); ath_desc_free(sc); ath_hal_detach(sc->sc_ah); - ieee80211_ifdetach(ifp); + ieee80211_ifdetach(ic); return 0; } @@ -403,7 +406,7 @@ void ath_suspend(struct ath_softc *sc) { - struct ifnet *ifp = &sc->sc_ic.ic_if; + struct ifnet *ifp = &sc->sc_if; DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags %x\n", __func__, ifp->if_flags)); @@ -413,7 +416,7 @@ void ath_resume(struct ath_softc *sc) { - struct ifnet *ifp = &sc->sc_ic.ic_if; + struct ifnet *ifp = &sc->sc_if; DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags %x\n", __func__, ifp->if_flags)); @@ -427,19 +430,22 @@ void ath_shutdown(struct ath_softc *sc) { - struct ifnet *ifp = &sc->sc_ic.ic_if; + struct ifnet *ifp = &sc->sc_if; DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags %x\n", __func__, ifp->if_flags)); ath_stop(ifp); } +/* + * Interrupt handler. Most of the actual processing is + * deferred to tasklets. + */ void ath_intr(void *arg) { struct ath_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = &ic->ic_if; + struct ifnet *ifp = &sc->sc_if; struct ath_hal *ah = sc->sc_ah; HAL_INT status; @@ -495,8 +501,14 @@ taskqueue_enqueue(taskqueue_swi, &sc->sc_rxtask); if (status & HAL_INT_TX) taskqueue_enqueue(taskqueue_swi, &sc->sc_txtask); - if (status & HAL_INT_SWBA) - taskqueue_enqueue(taskqueue_swi, &sc->sc_swbatask); + if (status & HAL_INT_SWBA) { + /* + * Handle beacon transmission directly; deferring + * this is too slow to meet timing constraints + * under load. + */ + ath_beacon_proc(sc); + } if (status & HAL_INT_BMISS) { sc->sc_stats.ast_bmiss++; taskqueue_enqueue(taskqueue_swi, &sc->sc_bmisstask); @@ -559,8 +571,8 @@ ath_init(void *arg) { struct ath_softc *sc = (struct ath_softc *) arg; + struct ifnet *ifp = &sc->sc_if; struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = &ic->ic_if; struct ieee80211_node *ni; enum ieee80211_phymode mode; struct ath_hal *ah = sc->sc_ah; @@ -577,7 +589,20 @@ */ ath_stop(ifp); +#if 0 /* + * For the MAC address. When this is changed we + * are called after if_setlladdr has already copied + * the new address to the arpcom structure so just + * take it from there. + * + * XXX not right for multiple vap's + */ + IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_ac.ac_enaddr); + ath_hal_setmac(ah, ic->ic_myaddr); +#endif + + /* * The basic interface to setting the hardware in a good * state is ``reset''. On return the hardware is known to * be powered up and with interrupts disabled. This must @@ -637,8 +662,8 @@ static void ath_stop(struct ifnet *ifp) { - struct ieee80211com *ic = (struct ieee80211com *) ifp; struct ath_softc *sc = ifp->if_softc; + struct ieee80211com *ic = &sc->sc_ic; struct ath_hal *ah = sc->sc_ah; DPRINTF(ATH_DEBUG_ANY, ("%s: invalid %u if_flags 0x%x\n", @@ -688,7 +713,7 @@ static int ath_reset(struct ieee80211com *ic) { - struct ifnet *ifp = &ic->ic_if; + struct ifnet *ifp = ic->ic_ifp; struct ath_softc *sc = ifp->if_softc; struct ath_hal *ah = sc->sc_ah; struct ieee80211_channel *c; @@ -716,12 +741,19 @@ * hardware state we do this regardless. */ ath_initkeytable(sc); - ath_hal_intrset(ah, sc->sc_imask); if (ath_startrecv(sc) != 0) /* restart recv */ if_printf(ifp, "%s: unable to start recv logic\n", __func__); - ath_start(ifp); /* restart xmit */ + /* + * We may be doing a reset in response to an ioctl + * that changes the channel so update any state that + * might change as a result. + */ + ath_chan_change(sc, c); if (ic->ic_state == IEEE80211_S_RUN) ath_beacon_config(sc); /* restart beacons */ + ath_hal_intrset(ah, sc->sc_imask); + + ath_start(ifp); /* restart xmit */ return 0; } @@ -785,7 +817,7 @@ /* * Encapsulate the packet in prep for transmission. */ - m = ieee80211_encap(ifp, m, &ni); + m = ieee80211_encap(ic, m, &ni); if (m == NULL) { DPRINTF(ATH_DEBUG_ANY, ("%s: encapsulation failure\n", @@ -849,7 +881,7 @@ if (error == ENETRESET) { if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP)) - ath_init(ifp); /* XXX lose error */ + ath_init(ifp->if_softc); /* XXX lose error */ error = 0; } return error; @@ -888,7 +920,7 @@ else ieee80211_iterate_nodes(ic, ath_rate_ctl, sc); } - ieee80211_watchdog(ifp); + ieee80211_watchdog(ic); } static int @@ -897,6 +929,7 @@ #define UP_RUNNING(_ifp) \ (((_ifp)->if_flags & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING)) struct ath_softc *sc = ifp->if_softc; + struct ieee80211com *ic = &sc->sc_ic; struct ifreq *ifr = (struct ifreq *)data; int error = 0; @@ -921,7 +954,7 @@ * probably a better way to deal with this. */ if (!sc->sc_invalid) - ath_init(ifp); /* XXX lose error */ + ath_init(sc); /* XXX lose error */ } else { /* * Interface marked down; clear the hardware. @@ -959,7 +992,7 @@ break; } default: - error = ieee80211_ioctl(ifp, cmd, data); + error = ieee80211_ioctl(ic, cmd, data); if (error == ENETRESET) { if (UP_RUNNING(ifp)) ath_init(sc); @@ -1011,9 +1044,9 @@ static u_int32_t ath_calcrxfilter(struct ath_softc *sc) { + struct ifnet *ifp = &sc->sc_if; struct ieee80211com *ic = &sc->sc_ic; struct ath_hal *ah = sc->sc_ah; - struct ifnet *ifp = &ic->ic_if; u_int32_t rfilt; rfilt = (ath_hal_getrxfilter(ah) & HAL_RX_FILTER_PHYERR) @@ -1033,9 +1066,8 @@ static void ath_mode_init(struct ath_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; struct ath_hal *ah = sc->sc_ah; - struct ifnet *ifp = &ic->ic_if; + struct ifnet *ifp = &sc->sc_if; u_int32_t rfilt, mfilt[2], val; u_int8_t pos; struct ifmultiaddr *ifma; @@ -1162,14 +1194,13 @@ } static void -ath_beacon_proc(void *arg, int pending) +ath_beacon_proc(struct ath_softc *sc) { - struct ath_softc *sc = arg; struct ieee80211com *ic = &sc->sc_ic; struct ath_buf *bf = sc->sc_bcbuf; struct ath_hal *ah = sc->sc_ah; - DPRINTF(ATH_DEBUG_BEACON_PROC, ("%s: pending %u\n", __func__, pending)); + DPRINTF(ATH_DEBUG_BEACON_PROC, ("%s\n", __func__)); if (ic->ic_opmode == IEEE80211_M_STA || bf == NULL || bf->bf_m == NULL) { DPRINTF(ATH_DEBUG_ANY, ("%s: ic_flags=%x bf=%p bf_m=%p\n", @@ -1432,7 +1463,8 @@ struct ath_node *an = malloc(sizeof(struct ath_node), M_DEVBUF, M_NOWAIT | M_ZERO); if (an) { - struct ath_softc *sc = ic->ic_if.if_softc; + struct ifnet *ifp = ic->ic_ifp; + struct ath_softc *sc = ifp->if_softc; int i; for (i = 0; i < ATH_RHIST_SIZE; i++) @@ -1447,7 +1479,8 @@ static void ath_node_free(struct ieee80211com *ic, struct ieee80211_node *ni) { - struct ath_softc *sc = ic->ic_if.if_softc; + struct ifnet *ifp = ic->ic_ifp; + struct ath_softc *sc = ifp->if_softc; struct ath_buf *bf; TAILQ_FOREACH(bf, &sc->sc_txq, bf_list) { @@ -1578,9 +1611,9 @@ ((struct ath_desc *)((caddr_t)(_sc)->sc_desc + \ ((_pa) - (_sc)->sc_desc_paddr))) struct ath_softc *sc = arg; + struct ifnet *ifp = &sc->sc_if; + struct ieee80211com *ic = &sc->sc_ic; struct ath_buf *bf; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = &ic->ic_if; struct ath_hal *ah = sc->sc_ah; struct ath_desc *ds; struct mbuf *m; @@ -1630,7 +1663,26 @@ if (status == HAL_EINPROGRESS) break; TAILQ_REMOVE(&sc->sc_rxbuf, bf, bf_list); - if (ds->ds_rxstat.rs_status != 0) { + + if (ds->ds_rxstat.rs_more) { + /* + * Frame spans multiple descriptors; this + * cannot happen yet as we don't support + * jumbograms. If not in monitor mode, + * discard the frame. + */ +#ifdef ERROR_FRAMES + /* + * Enable this if you want to see + * error frames in Monitor mode. + */ + if (ic->ic_opmode != IEEE80211_M_MONITOR) { + /* XXX statistic */ + goto rx_next; + } +#endif + /* fall thru for monitor mode handling... */ + } else if (ds->ds_rxstat.rs_status != 0) { if (ds->ds_rxstat.rs_status & HAL_RXERR_CRC) sc->sc_stats.ast_rx_crcerr++; if (ds->ds_rxstat.rs_status & HAL_RXERR_FIFO) @@ -1641,6 +1693,7 @@ sc->sc_stats.ast_rx_phyerr++; phyerr = ds->ds_rxstat.rs_phyerr & 0x1f; sc->sc_stats.ast_rx_phy[phyerr]++; + goto rx_next; } else { /* * NB: don't count PHY errors as input errors; @@ -1651,7 +1704,14 @@ */ ifp->if_ierrors++; } - goto rx_next; + /* + * Reject error frames, we normally don't want + * to see them in monitor mode (in monitor mode + * allow through packets that cannot be decrypted.) + */ + if ((ds->ds_rxstat.rs_status & ~HAL_RXERR_DECRYPT) || + sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR) + goto rx_next; } len = ds->ds_rxstat.rs_datalen; @@ -1670,6 +1730,17 @@ m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = len; + /* + * Strip the CRC before tapping the frame as some + * applications get confused otherwise. If there's + * a good reason to send the CRC to applications + * we'll need to define a radiotap flag for that. + */ + m_adj(m, -IEEE80211_CRC_LEN); + + /* + * Tap and/or dump the received frame. + */ if (sc->sc_drvbpf) { sc->sc_rx_th.wr_rate = sc->sc_hwmap[ds->ds_rxstat.rs_rate]; @@ -1680,8 +1751,13 @@ bpf_mtap2(sc->sc_drvbpf, &sc->sc_rx_th, sizeof(sc->sc_rx_th), m); } + if (IFF_DUMPPKTS(ifp, ATH_DEBUG_RECV)) { + ieee80211_dump_pkt(mtod(m, u_int8_t *), len, + sc->sc_hwmap[ds->ds_rxstat.rs_rate] & + IEEE80211_RATE_VAL, + ds->ds_rxstat.rs_rssi); + } - m_adj(m, -IEEE80211_CRC_LEN); wh = mtod(m, struct ieee80211_frame *); if (wh->i_fc[1] & IEEE80211_FC1_WEP) { /* @@ -1727,7 +1803,7 @@ /* * Send frame up for processing. */ - ieee80211_input(ifp, m, ni, + ieee80211_input(ic, m, ni, ds->ds_rxstat.rs_rssi, ds->ds_rxstat.rs_tstamp); /* @@ -1739,7 +1815,7 @@ ieee80211_unref_node(&ni); else ieee80211_free_node(ic, ni); - rx_next: +rx_next: TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list); } while (ath_rxbuf_init(sc, bf) == 0); @@ -1758,8 +1834,8 @@ struct mbuf *m0) { struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = &sc->sc_if; struct ath_hal *ah = sc->sc_ah; - struct ifnet *ifp = &sc->sc_ic.ic_if; int i, error, iswep, hdrlen, pktlen, try0; u_int8_t rix, cix, txrate, ctsrate; struct ath_desc *ds; @@ -1785,7 +1861,7 @@ m_adj(m0, hdrlen); M_PREPEND(m0, sizeof(hdrbuf), M_DONTWAIT); if (m0 == NULL) { - sc->sc_stats.ast_tx_nombuf++; + sc->sc_stats.ast_tx_nobuf++; return ENOMEM; } ivp = hdrbuf + hdrlen; @@ -1845,7 +1921,7 @@ sc->sc_stats.ast_tx_linear++; MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == NULL) { - sc->sc_stats.ast_tx_nombuf++; + sc->sc_stats.ast_tx_nobuf++; m_freem(m0); return ENOMEM; } @@ -2038,6 +2114,11 @@ &sc->sc_tx_th, sizeof(sc->sc_tx_th), m0); } + if (IFF_DUMPPKTS(ifp, ATH_DEBUG_XMIT)) + ieee80211_dump_pkt(mtod(m0, u_int8_t *), pktlen, + ni->ni_rates.rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL, + -1); + /* * Formulate first tx descriptor with tx controls. */ @@ -2132,10 +2213,10 @@ ath_tx_proc(void *arg, int npending) { struct ath_softc *sc = arg; + struct ifnet *ifp = &sc->sc_if; struct ath_hal *ah = sc->sc_ah; struct ath_buf *bf; struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = &ic->ic_if; struct ath_desc *ds; struct ieee80211_node *ni; struct ath_node *an; @@ -2225,9 +2306,9 @@ static void ath_draintxq(struct ath_softc *sc) { + struct ifnet *ifp = &sc->sc_if; struct ath_hal *ah = sc->sc_ah; struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = &ic->ic_if; struct ieee80211_node *ni; struct ath_buf *bf; @@ -2339,6 +2420,32 @@ return 0; } +/* + * Update internal state after a channel change. + */ +static void +ath_chan_change(struct ath_softc *sc, struct ieee80211_channel *chan) +{ + struct ieee80211com *ic = &sc->sc_ic; + enum ieee80211_phymode mode; + + /* + * Change channels and update the h/w rate map + * if we're switching; e.g. 11a to 11b/g. + */ + mode = ieee80211_chan2mode(ic, chan); + if (mode != sc->sc_curmode) + ath_setcurmode(sc, mode); + + /* + * Update BPF state. + */ + sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = + htole16(chan->ic_freq); + sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = + htole16(chan->ic_flags); +} + /* * Set/change channels. If the channel is really being changed, * it's done by resetting the chip. To accomplish this we must @@ -2358,7 +2465,6 @@ if (chan != ic->ic_ibss_chan) { HAL_STATUS status; HAL_CHANNEL hchan; - enum ieee80211_phymode mode; /* * To switch channels clear any pending DMA operations; @@ -2377,7 +2483,7 @@ hchan.channel = chan->ic_freq; hchan.channelFlags = ath_chan2flags(ic, chan); if (!ath_hal_reset(ah, ic->ic_opmode, &hchan, AH_TRUE, &status)) { - if_printf(&ic->ic_if, "ath_chan_set: unable to reset " + if_printf(&sc->sc_if, "ath_chan_set: unable to reset " "channel %u (%u Mhz)\n", ieee80211_chan2ieee(ic, chan), chan->ic_freq); return EIO; @@ -2386,27 +2492,17 @@ * Re-enable rx framework. */ if (ath_startrecv(sc) != 0) { - if_printf(&ic->ic_if, + if_printf(&sc->sc_if, "ath_chan_set: unable to restart recv logic\n"); return EIO; } /* - * Update BPF state. - */ - sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = - htole16(chan->ic_freq); - sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = - htole16(chan->ic_flags); - - /* * Change channels and update the h/w rate map * if we're switching; e.g. 11a to 11b/g. */ ic->ic_ibss_chan = chan; - mode = ieee80211_chan2mode(ic, chan); - if (mode != sc->sc_curmode) - ath_setcurmode(sc, mode); + ath_chan_change(sc, chan); /* * Re-enable interrupts. @@ -2421,10 +2517,9 @@ { struct ath_softc *sc = arg; struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = &ic->ic_if; if (ic->ic_state == IEEE80211_S_SCAN) - ieee80211_next_scan(ifp); + ieee80211_next_scan(ic); } /* @@ -2473,7 +2568,7 @@ static int ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) { - struct ifnet *ifp = &ic->ic_if; + struct ifnet *ifp = ic->ic_ifp; struct ath_softc *sc = ifp->if_softc; struct ath_hal *ah = sc->sc_ah; struct ieee80211_node *ni; @@ -2592,8 +2687,8 @@ ath_getchannels(struct ath_softc *sc, u_int cc, HAL_BOOL outdoor, HAL_BOOL xchanmode) { + struct ifnet *ifp = &sc->sc_if; struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = &ic->ic_if; struct ath_hal *ah = sc->sc_ah; HAL_CHANNEL *chans; int i, ix, nchan; @@ -2787,25 +2882,45 @@ { #define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL) struct ieee80211com *ic = &sc->sc_ic; + int srate; + KASSERT(ni->ni_rates.rs_nrates > 0, ("no rates")); if (ic->ic_fixed_rate == -1) { - KASSERT(ni->ni_rates.rs_nrates > 0, ("no rates")); - /* start with highest negotiated rate */ - int srate = ni->ni_rates.rs_nrates - 1; + /* + * No fixed rate is requested. For 11b start with + * the highest negotiated rate; otherwise, for 11g + * and 11a, we start "in the middle" at 24Mb or 36Mb. + */ + srate = ni->ni_rates.rs_nrates - 1; if (sc->sc_curmode != IEEE80211_MODE_11B) { /* - * 11a and 11g work better if you start at 24Mb - * or 36Mb and raise the rate. Scan the negotiated - * rate set to find the closest rate. + * Scan the negotiated rate set to find the + * closest rate. */ - /* NB: rate set assumed sorted */ + /* NB: the rate set is assumed sorted */ for (; srate >= 0 && RATE(srate) > 72; srate--) ; KASSERT(srate >= 0, ("bogus rate set")); } - ath_rate_update(sc, ni, srate); - } else - ath_rate_update(sc, ni, ic->ic_fixed_rate); + } else { + /* + * A fixed rate is to be used; ic_fixed_rate is an + * index into the supported rate set. Convert this + * to the index into the negotiated rate set for + * the node. We know the rate is there because the + * rate set is checked when the station associates. + */ + const struct ieee80211_rateset *rs = + &ic->ic_sup_rates[ic->ic_curmode]; + int r = rs->rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; + /* NB: the rate set is assumed sorted */ + srate = ni->ni_rates.rs_nrates - 1; + for (; srate >= 0 && RATE(srate) != r; srate--) + ; + KASSERT(srate >= 0, + ("fixed rate %d not in rate set", ic->ic_fixed_rate)); + } + ath_rate_update(sc, ni, srate); #undef RATE } @@ -2849,7 +2964,7 @@ ath_rate_ctl(void *arg, struct ieee80211_node *ni) { struct ath_softc *sc = arg; - struct ath_node *an = (struct ath_node *) ni; + struct ath_node *an = ATH_NODE(ni); struct ieee80211_rateset *rs = &ni->ni_rates; int mod = 0, nrate, enough; ==== //depot/projects/netperf+sockets/sys/dev/ath/if_ath_pci.c#3 (text+ko) ==== @@ -67,10 +67,6 @@ #include #include -#include -#include -#include -#include #include #ifdef INET ==== //depot/projects/netperf+sockets/sys/dev/ath/if_athioctl.h#6 (text+ko) ==== @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting + * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -55,7 +55,7 @@ u_int32_t ast_tx_qstop; /* output stopped 'cuz no buffer */ u_int32_t ast_tx_encap; /* tx encapsulation failed */ u_int32_t ast_tx_nonode; /* tx failed 'cuz no node */ - u_int32_t ast_tx_nombuf; /* tx failed 'cuz no mbuf */ + u_int32_t ast_tx_nobuf; /* tx failed 'cuz no buf */ u_int32_t ast_tx_nomcl; /* tx failed 'cuz no cluster */ u_int32_t ast_tx_linear; /* tx linearized to cluster */ u_int32_t ast_tx_nodata; /* tx discarded empty frame */ @@ -77,10 +77,10 @@ u_int32_t ast_rx_crcerr; /* rx failed 'cuz of bad CRC */ u_int32_t ast_rx_fifoerr; /* rx failed 'cuz of FIFO overrun */ u_int32_t ast_rx_badcrypt;/* rx failed 'cuz decryption */ - u_int32_t ast_rx_phyerr; /* rx failed 'cuz of PHY err */ + u_int32_t ast_rx_phyerr; /* rx PHY error summary count */ u_int32_t ast_rx_phy[32]; /* rx PHY error per-code counts */ u_int32_t ast_rx_tooshort;/* rx discarded 'cuz frame too short */ - u_int32_t ast_rx_ctl; /* rx discarded 'cuz ctl frame */ + u_int8_t ast_rx_ctl; /* control frames received */ u_int32_t ast_be_nombuf; /* beacon setup failed 'cuz no mbuf */ u_int32_t ast_per_cal; /* periodic calibration calls */ u_int32_t ast_per_calfail;/* periodic calibration failed */ ==== //depot/projects/netperf+sockets/sys/dev/ath/if_athvar.h#5 (text+ko) ==== @@ -103,6 +103,7 @@ }; struct ath_softc { + struct arpcom sc_ac; struct ieee80211com sc_ic; /* IEEE 802.11 common */ int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int); @@ -157,13 +158,13 @@ u_int sc_bhalq; /* HAL q for outgoing beacons */ struct ath_buf *sc_bcbuf; /* beacon buffer */ struct ath_buf *sc_bufptr; /* allocated buffer ptr */ - struct task sc_swbatask; /* swba int processing */ struct task sc_bmisstask; /* bmiss int processing */ struct callout sc_cal_ch; /* callout handle for cals */ struct callout sc_scan_ch; /* callout handle for scan */ struct ath_stats sc_stats; /* interface statistics */ }; +#define sc_if sc_ac.ac_if #define sc_tx_th u_tx_rt.th #define sc_rx_th u_rx_rt.th @@ -211,6 +212,8 @@ #define ath_hal_getcountrycode(_ah) (_ah)->ah_countryCode #define ath_hal_getmac(_ah, _mac) \ ((*(_ah)->ah_getMacAddress)((_ah), (_mac))) +#define ath_hal_setmac(_ah, _mac) \ + ((*(_ah)->ah_setMacAddress)((_ah), (_mac))) #define ath_hal_detach(_ah) \ ((*(_ah)->ah_detach)((_ah))) #define ath_hal_intrset(_ah, _mask) \ ==== //depot/projects/netperf+sockets/sys/dev/awi/awi.c#6 (text+ko) ==== @@ -257,7 +257,7 @@ awi_attach(struct awi_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = &ic->ic_if; + struct ifnet *ifp = &sc->sc_if; int s, i, error, nrate; int mword; enum ieee80211_phymode mode; @@ -324,7 +324,9 @@ #ifdef __NetBSD__ if_attach(ifp); #endif - ieee80211_ifattach(ifp); + ic->ic_ifp = ifp; + + ieee80211_ifattach(ic); sc->sc_newstate = ic->ic_newstate; ic->ic_newstate = awi_newstate; @@ -335,7 +337,7 @@ sc->sc_send_mgmt = ic->ic_send_mgmt; ic->ic_send_mgmt = awi_send_mgmt; - ieee80211_media_init(ifp, awi_media_change, awi_media_status); + ieee80211_media_init(ic, awi_media_change, awi_media_status); /* Melco compatibility mode. */ #define ADD(s, o) ifmedia_add(&ic->ic_media, \ @@ -371,7 +373,8 @@ int awi_detach(struct awi_softc *sc) { - struct ifnet *ifp = &sc->sc_ic.ic_if; + struct ifnet *ifp = &sc->sc_if; + struct ieee80211com *ic = &sc->sc_ic; int s; if (!sc->sc_attached) @@ -386,7 +389,7 @@ (void)tsleep(sc, PWAIT, "awidet", 1); } sc->sc_attached = 0; - ieee80211_ifdetach(ifp); + ieee80211_ifdetach(ic); #ifdef __NetBSD__ if_detach(ifp); shutdownhook_disestablish(sc->sc_sdhook); @@ -401,7 +404,7 @@ awi_activate(struct device *self, enum devact act) { struct awi_softc *sc = (struct awi_softc *)self; - struct ifnet *ifp = &sc->sc_ic.ic_if; + struct ifnet *ifp = &sc->sc_if; int s, error = 0; s = splnet(); @@ -422,7 +425,7 @@ awi_power(int why, void *arg) { struct awi_softc *sc = arg; - struct ifnet *ifp = &sc->sc_ic.ic_if; + struct ifnet *ifp = &sc->sc_if; int s; int ocansleep; @@ -455,7 +458,7 @@ awi_shutdown(void *arg) { struct awi_softc *sc = arg; - struct ifnet *ifp = &sc->sc_ic.ic_if; + struct ifnet *ifp = &sc->sc_if; if (sc->sc_attached) awi_stop(ifp, 1); @@ -526,7 +529,7 @@ if (status & AWI_INT_SCAN_CMPLT) { if (sc->sc_ic.ic_state == IEEE80211_S_SCAN && sc->sc_substate == AWI_ST_NONE) - ieee80211_next_scan(&sc->sc_ic.ic_if); + ieee80211_next_scan(&sc->sc_ic); } } sc->sc_cansleep = ocansleep; @@ -541,7 +544,7 @@ { struct awi_softc *sc = arg; - (void)awi_init(&sc->sc_ic.ic_if); + (void)awi_init(&sc->sc_if); } #endif @@ -801,7 +804,7 @@ if ((ifp->if_flags & IFF_LINK0) || sc->sc_adhoc_ap) m0 = awi_ether_encap(sc, m0); else - m0 = ieee80211_encap(ifp, m0, &ni); + m0 = ieee80211_encap(ic, m0, &ni); if (m0 == NULL) { ifp->if_oerrors++; continue; @@ -826,7 +829,7 @@ bpf_mtap(ic->ic_rawbpf, m0); #endif if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - if ((m0 = ieee80211_wep_crypt(ifp, m0, 1)) == NULL) { + if ((m0 = ieee80211_wep_crypt(ic, m0, 1)) == NULL) { ifp->if_oerrors++; continue; } @@ -834,7 +837,7 @@ #ifdef DIAGNOSTIC if (m0->m_pkthdr.len != len) { printf("%s: length %d should be %d\n", - ic->ic_if.if_xname, m0->m_pkthdr.len, len); + sc->sc_if.if_xname, m0->m_pkthdr.len, len); m_freem(m0); ifp->if_oerrors++; continue; @@ -874,6 +877,7 @@ awi_watchdog(struct ifnet *ifp) { struct awi_softc *sc = ifp->if_softc; + struct ieee80211com *ic = &sc->sc_ic; u_int32_t prevdone; int ocansleep; @@ -899,15 +903,14 @@ if (sc->sc_rx_timer) { if (--sc->sc_rx_timer == 0) { if (sc->sc_ic.ic_state == IEEE80211_S_RUN) { - ieee80211_new_state(&sc->sc_ic, - IEEE80211_S_SCAN, -1); + ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); goto out; } >>> TRUNCATED FOR MAIL (1000 lines) <<<