PERFORCE change 136174 for review

Sam Leffler sam at FreeBSD.org
Mon Feb 25 16:50:24 UTC 2008


http://perforce.freebsd.org/chv.cgi?CH=136174

Change 136174 by sam at sam_ebb on 2008/02/25 16:50:10

	checkpoint bwi conversion

Affected files ...

.. //depot/projects/vap/sys/conf/files#17 edit
.. //depot/projects/vap/sys/conf/options#11 edit
.. //depot/projects/vap/sys/dev/bwi/bwimac.c#2 edit
.. //depot/projects/vap/sys/dev/bwi/bwirf.c#2 edit
.. //depot/projects/vap/sys/dev/bwi/if_bwi.c#2 edit
.. //depot/projects/vap/sys/dev/bwi/if_bwivar.h#2 edit
.. //depot/projects/vap/sys/modules/bwi/Makefile#2 edit

Differences ...

==== //depot/projects/vap/sys/conf/files#17 (text+ko) ====

@@ -495,6 +495,11 @@
 dev/bktr/bktr_os.c		optional bktr pci
 dev/bktr/bktr_tuner.c		optional bktr pci
 dev/bktr/msp34xx.c		optional bktr pci
+dev/bwi/if_bwi.c		optional bwi
+dev/bwi/if_bwi_pci.c		optional bwi pci
+dev/bwi/bwimac.c		optional bwi
+dev/bwi/bwiphy.c		optional bwi
+dev/bwi/bwirf.c			optional bwi
 dev/buslogic/bt.c		optional bt
 dev/buslogic/bt_eisa.c		optional bt eisa
 dev/buslogic/bt_isa.c		optional bt isa

==== //depot/projects/vap/sys/conf/options#11 (text+ko) ====

@@ -729,6 +729,10 @@
 ATH_DIAGAPI		opt_ath.h
 ATH_TX99_DIAG		opt_ath.h
 
+# options for the Broadcom wireless driver
+BWI_DEBUG		opt_bwi.h
+BWI_DEBUG_VERBOSE	opt_bwi.h
+
 # dcons options 
 DCONS_BUF_SIZE		opt_dcons.h
 DCONS_POLL_HZ		opt_dcons.h

==== //depot/projects/vap/sys/dev/bwi/bwimac.c#2 (text+ko) ====

@@ -38,6 +38,7 @@
 __FBSDID("$FreeBSD$");
 
 #include "opt_inet.h"
+#include "opt_bwi.h"
 
 #include <sys/param.h>
 #include <sys/endian.h>

==== //depot/projects/vap/sys/dev/bwi/bwirf.c#2 (text+ko) ====

@@ -39,6 +39,7 @@
 __FBSDID("$FreeBSD$");
 
 #include "opt_inet.h"
+#include "opt_bwi.h"
 
 #include <sys/param.h>
 #include <sys/endian.h>

==== //depot/projects/vap/sys/dev/bwi/if_bwi.c#2 (text+ko) ====

@@ -38,6 +38,7 @@
 __FBSDID("$FreeBSD$");
 
 #include "opt_inet.h"
+#include "opt_bwi.h"
 
 #include <sys/param.h>
 #include <sys/endian.h>
@@ -93,6 +94,11 @@
 	uint8_t		bssid[IEEE80211_ADDR_LEN];
 } __packed;
 
+static struct ieee80211vap *bwi_vap_create(struct ieee80211com *,
+		   const char [IFNAMSIZ], int, int, int,
+		   const uint8_t [IEEE80211_ADDR_LEN],
+		   const uint8_t [IEEE80211_ADDR_LEN]);
+static void	bwi_vap_delete(struct ieee80211vap *);
 static void	bwi_init(void *);
 static int	bwi_ioctl(struct ifnet *, u_long, caddr_t);
 static void	bwi_start(struct ifnet *);
@@ -103,7 +109,7 @@
 static void	bwi_scan_start(struct ieee80211com *);
 static void	bwi_set_channel(struct ieee80211com *);
 static void	bwi_scan_end(struct ieee80211com *);
-static int	bwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
+static int	bwi_newstate(struct ieee80211vap *, enum ieee80211_state, int);
 static void	bwi_updateslot(struct ifnet *);
 static struct ieee80211_node *bwi_node_alloc(struct ieee80211_node_table *);
 static void	bwi_newassoc(struct ieee80211_node *, int);
@@ -115,11 +121,10 @@
 static int	bwi_calc_rssi(struct bwi_softc *, const struct bwi_rxbuf_hdr *);
 static __inline uint8_t bwi_ofdm_plcp2rate(const uint32_t *);
 static __inline uint8_t bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *);
-static void	bwi_rx_radiotap(struct bwi_softc *, struct mbuf *,
+static void	bwi_rx_radiotap(struct ifnet *, struct mbuf *,
 			struct bwi_rxbuf_hdr *, const void *, int, int);
 
 static void	bwi_restart(void *, int);
-static void	bwi_newstate_begin(struct bwi_softc *, enum ieee80211_state);
 static void	bwi_init_statechg(struct bwi_softc *, int);
 static void	bwi_stop(struct bwi_softc *, int);
 static int	bwi_newbuf(struct bwi_softc *, int, int);
@@ -188,7 +193,6 @@
 static void	bwi_set_addr_filter(struct bwi_softc *, uint16_t,
 				    const uint8_t *);
 static void	bwi_set_bssid(struct bwi_softc *, const uint8_t *);
-static int	bwi_set_chan(struct bwi_softc *, struct ieee80211_channel *);
 
 static void	bwi_get_card_flags(struct bwi_softc *);
 static void	bwi_get_eaddr(struct bwi_softc *, uint16_t, uint8_t *);
@@ -352,7 +356,8 @@
 	struct ifnet *ifp;
 	struct bwi_mac *mac;
 	struct bwi_phy *phy;
-	int i, error, bands;
+	int i, error;
+	uint8_t bands;
 
 	BWI_LOCK_INIT(sc);
 
@@ -365,6 +370,8 @@
 		device_get_nameunit(dev));
 	TASK_INIT(&sc->sc_restart_task, 0, bwi_restart, sc);
 
+	callout_init_mtx(&sc->sc_calib_ch, &sc->sc_mtx, 0);
+
 	/*
 	 * Initialize sysctl variables
 	 */
@@ -372,8 +379,9 @@
 	sc->sc_led_idle = (2350 * hz) / 1000;
 	sc->sc_led_blink = 1;
 	sc->sc_txpwr_calib = 1;
+#ifdef BWI_DEBUG
 	sc->sc_debug = bwi_debug;
-
+#endif
 	bwi_power_on(sc, 1);
 
 	error = bwi_bbp_attach(sc);
@@ -436,7 +444,7 @@
 	if (error)
 		goto fail;
 
-	ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
+	ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
 	if (ifp == NULL) {
 		device_printf(dev, "can not if_alloc()\n");
 		error = ENOSPC;
@@ -446,34 +454,6 @@
 	/* set these up early for if_printf use */
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
 
-	callout_init_mtx(&sc->sc_calib_ch, &sc->sc_mtx, 0);
-	callout_init_mtx(&sc->sc_amrr_ch, &sc->sc_mtx, 0);
-
-	/*
-	 * Add sysctl nodes
-	 */
-	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
-		        SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
-		        "fw_version", CTLFLAG_RD, &sc->sc_fw_version, 0,
-		        "Firmware version");
-	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
-		        SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
-		        "led_idle", CTLFLAG_RW, &sc->sc_led_idle, 0,
-		        "# ticks before LED enters idle state");
-	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
-		       SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
-		       "led_blink", CTLFLAG_RW, &sc->sc_led_blink, 0,
-		       "Allow LED to blink");
-	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
-		       SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
-		       "txpwr_calib", CTLFLAG_RW, &sc->sc_txpwr_calib, 0,
-		       "Enable software TX power calibration");
-#ifdef BWI_DEBUG
-	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
-		        SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
-		        "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
-#endif
-
 	ifp->if_softc = sc;
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_init = bwi_init;
@@ -484,11 +464,6 @@
 	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
 	IFQ_SET_READY(&ifp->if_snd);
 
-	/* Get locale */
-	sc->sc_locale = __SHIFTOUT(bwi_read_sprom(sc, BWI_SPROM_CARD_INFO),
-				   BWI_SPROM_CARD_INFO_LOCALE);
-	DPRINTF(sc, BWI_DBG_ATTACH, "locale: %d\n", sc->sc_locale);
-
 	/*
 	 * Setup ratesets, phytype, channels and get MAC address
 	 */
@@ -520,45 +495,39 @@
 	} else {
 		panic("unknown phymode %d\n", phy->phy_mode);
 	}
+
+	/* Get locale */
+	sc->sc_locale = __SHIFTOUT(bwi_read_sprom(sc, BWI_SPROM_CARD_INFO),
+				   BWI_SPROM_CARD_INFO_LOCALE);
+	DPRINTF(sc, BWI_DBG_ATTACH, "locale: %d\n", sc->sc_locale);
 	/* XXX use locale */
-	ieee80211_init_channels(ic, 0, CTRY_DEFAULT, bands, 0, 1);
+	ieee80211_init_channels(ic, NULL, &bands);
 
 	ic->ic_ifp = ifp;
 	ic->ic_caps = IEEE80211_C_SHSLOT |
 		      IEEE80211_C_SHPREAMBLE |
 		      IEEE80211_C_WPA |
 		      IEEE80211_C_MONITOR;
-	ic->ic_state = IEEE80211_S_INIT;
 	ic->ic_opmode = IEEE80211_M_STA;
-
-	ic->ic_updateslot = bwi_updateslot;
-
 	ieee80211_ifattach(ic);
 
 	ic->ic_headroom = sizeof(struct bwi_txbuf_hdr);
-	ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;
 
 	/* override default methods */
-	sc->sc_newstate = ic->ic_newstate;
-	ic->ic_newstate = bwi_newstate;
+	ic->ic_vap_create = bwi_vap_create;
+	ic->ic_vap_delete = bwi_vap_delete;
+	ic->ic_raw_xmit = bwi_raw_xmit;
+	ic->ic_updateslot = bwi_updateslot;
+	ic->ic_node_alloc = bwi_node_alloc;
 	ic->ic_scan_start = bwi_scan_start;
 	ic->ic_scan_end = bwi_scan_end;
 	ic->ic_set_channel = bwi_set_channel;
-	ic->ic_node_alloc = bwi_node_alloc;
-	ic->ic_newassoc = bwi_newassoc;
-	ic->ic_raw_xmit = bwi_raw_xmit;
-	/* complete initialization */
-	ieee80211_media_init(ic, bwi_media_change, ieee80211_media_status);
-	ieee80211_amrr_init(&sc->sc_amrr, ic,
-	    IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
-	    IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD);
 
 	/*
-	 * Attach radio tap
+	 * Attach bpf.
 	 */
-	bpfattach2(ifp, DLT_IEEE802_11_RADIO,
-		sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th),
-		&sc->sc_drvbpf);
+	bpfattach(ifp, DLT_IEEE802_11_RADIO,
+	    sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th));
 
 	sc->sc_tx_th_len = roundup(sizeof(sc->sc_tx_th), sizeof(uint32_t));
 	sc->sc_tx_th.wt_ihdr.it_len = htole16(sc->sc_tx_th_len);
@@ -568,6 +537,30 @@
 	sc->sc_rx_th.wr_ihdr.it_len = htole16(sc->sc_rx_th_len);
 	sc->sc_rx_th.wr_ihdr.it_present = htole32(BWI_RX_RADIOTAP_PRESENT);
 
+	/*
+	 * Add sysctl nodes
+	 */
+	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+		        SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+		        "fw_version", CTLFLAG_RD, &sc->sc_fw_version, 0,
+		        "Firmware version");
+	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+		        SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+		        "led_idle", CTLFLAG_RW, &sc->sc_led_idle, 0,
+		        "# ticks before LED enters idle state");
+	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+		       SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+		       "led_blink", CTLFLAG_RW, &sc->sc_led_blink, 0,
+		       "Allow LED to blink");
+	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+		       SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+		       "txpwr_calib", CTLFLAG_RW, &sc->sc_txpwr_calib, 0,
+		       "Enable software TX power calibration");
+#ifdef BWI_DEBUG
+	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+		        SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+		        "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
+#endif
 	if (bootverbose)
 		ieee80211_announce(ic);
 
@@ -588,7 +581,6 @@
 	BWI_UNLOCK(sc);
 
 	callout_drain(&sc->sc_calib_ch);
-	callout_drain(&sc->sc_amrr_ch);
 	ieee80211_ifdetach(&sc->sc_ic);
 
 	for (i = 0; i < sc->sc_nmac; ++i)
@@ -602,6 +594,54 @@
 	return (0);
 }
 
+static struct ieee80211vap *
+bwi_vap_create(struct ieee80211com *ic,
+	const char name[IFNAMSIZ], int unit, int opmode, int flags,
+	const uint8_t bssid[IEEE80211_ADDR_LEN],
+	const uint8_t mac[IEEE80211_ADDR_LEN])
+{
+	struct bwi_softc *sc = ic->ic_ifp->if_softc;
+	struct bwi_vap *bvp;
+	struct ieee80211vap *vap;
+
+	if (!TAILQ_EMPTY(&ic->ic_vaps))		/* only one at a time */
+		return NULL;
+	bvp = (struct bwi_vap *) malloc(sizeof(struct bwi_vap),
+	    M_80211_VAP, M_WAITOK | M_ZERO);
+	if (bvp == NULL)
+		return NULL;
+	vap = &bvp->bv_vap;
+	/* enable s/w bmiss handling for sta mode */
+	ieee80211_vap_setup(ic, vap, name, unit, opmode,
+	    flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
+
+	/* override default methods */
+	bvp->bv_newstate = vap->iv_newstate;
+	vap->iv_newstate = bwi_newstate;
+#if 0
+	vap->iv_update_beacon = bwi_beacon_update;
+#endif
+	callout_init_mtx(&bvp->bv_amrr_ch, &sc->sc_mtx, 0);
+	ieee80211_amrr_init(&bvp->bv_amrr, vap,
+	    IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
+	    IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD);
+
+	/* complete setup */
+	ieee80211_vap_attach(vap, bwi_media_change, ieee80211_media_status);
+	ic->ic_opmode = opmode;
+	return vap;
+}
+
+static void
+bwi_vap_delete(struct ieee80211vap *vap)
+{
+	struct bwi_vap *bvp = BWI_VAP(vap);
+
+	callout_drain(&bvp->bv_amrr_ch);
+	ieee80211_vap_detach(vap);
+	free(bvp, M_80211_VAP);
+}
+
 void
 bwi_suspend(struct bwi_softc *sc)
 {
@@ -1207,12 +1247,16 @@
 
 	mac = &sc->sc_mac[0];
 	error = bwi_regwin_switch(sc, &mac->mac_regwin, NULL);
-	if (error)
-		goto back;
-
+	if (error) {
+		if_printf(ifp, "%s: error %d on regwin switch\n",
+		    __func__, error);
+		goto bad;
+	}
 	error = bwi_mac_init(mac);
-	if (error)
-		goto back;
+	if (error) {
+		if_printf(ifp, "%s: error %d on MAC init\n", __func__, error);
+		goto bad;
+	}
 
 	bwi_bbp_power_on(sc, BWI_CLOCK_MODE_DYN);
 	
@@ -1237,7 +1281,7 @@
 			CSR_READ_4(sc, BWI_TXSTATUS1);
 		}
 		if (i == NRETRY)
-			if_printf(ifp, "can't drain TX status\n");
+			if_printf(ifp, "%s: can't drain TX status\n", __func__);
 #undef NRETRY
 	}
 
@@ -1246,36 +1290,24 @@
 
 	/* Start MAC */
 	error = bwi_mac_start(mac);
-	if (error)
-		goto back;
+	if (error) {
+		if_printf(ifp, "%s: error %d starting MAC\n", __func__, error);
+		goto bad;
+	}
 
 	/* Clear stop flag before enabling interrupt */
 	sc->sc_flags &= ~BWI_F_STOP;
 
+	ifp->if_drv_flags |= IFF_DRV_RUNNING;
+
 	/* Enable intrs */
 	bwi_enable_intrs(sc, BWI_INIT_INTRS);
 
-	ifp->if_drv_flags |= IFF_DRV_RUNNING;
-	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
-	if (statechg) {
-		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
-			if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
-				ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
-		} else {
-			ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
-		}
-	} else {
-		/* XXX */
-		if (ic->ic_state != IEEE80211_S_INIT)
-			bwi_set_channel(ic);
-		ieee80211_new_state(ic, ic->ic_state, -1);
-	}
-back:
-	if (error)
-		bwi_stop(sc, 1);
-	else
-		bwi_start_locked(ifp);
+	ieee80211_start_all(ic);		/* start all vap's */
+	BWI_UNLOCK(sc);
+	return;
+bad:
+	bwi_stop(sc, 1);
 	BWI_UNLOCK(sc);
 }
 
@@ -1285,6 +1317,8 @@
 #define	IS_RUNNING(ifp) \
 	((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
 	struct bwi_softc *sc = ifp->if_softc;
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ifreq *ifr = (struct ifreq *)req;
 	int error = 0;
 
 	BWI_LOCK(sc);
@@ -1322,16 +1356,19 @@
 				bwi_stop(sc, 1);
 		}
 		break;
+	case SIOCADDMULTI:
+	case SIOCDELMULTI:
+		/* XXX */
+		break;
+	case SIOCGIFMEDIA:
+	case SIOCSIFMEDIA:
+		error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
+		break;
 	default:
-		error = ieee80211_ioctl(&sc->sc_ic, cmd, req);
+		error = ether_ioctl(ifp, cmd, req);
 		break;
 	}
 
-	if (error == ENETRESET) {
-		if (IS_RUNNING(ifp))
-			bwi_init(sc);
-		error = 0;
-	}
 	BWI_UNLOCK(sc);
 
 	return error;
@@ -1352,70 +1389,35 @@
 bwi_start_locked(struct ifnet *ifp)
 {
 	struct bwi_softc *sc = ifp->if_softc;
-	struct ieee80211com *ic = &sc->sc_ic;
 	struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
 	struct ieee80211_frame *wh;
 	struct ieee80211_node *ni;
-	struct ether_header *eh;
 	struct ieee80211_key *k;
 	struct mbuf *m;
 	int trans, idx;
 
-	if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) ||
-	    (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
 		return;
 
 	trans = 0;
 	idx = tbd->tbd_idx;
 
 	while (tbd->tbd_buf[idx].tb_mbuf == NULL) {
-		IF_DEQUEUE(&ic->ic_mgtq, m);
-		if (m != NULL) {
-			ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
-			m->m_pkthdr.rcvif = NULL;
-		} else {
-			if (ic->ic_state != IEEE80211_S_RUN)
-				break;
+		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);	/* XXX: LOCK */
+		if (m == NULL)
+			break;
 
-			IFQ_DRV_DEQUEUE(&ifp->if_snd, m);	/* XXX: LOCK */
-			if (m == NULL)
-				break;
-
-			if (m->m_len < sizeof(*eh)) {
-				m = m_pullup(m, sizeof(*eh));
-				if (m == NULL) {
-					ifp->if_oerrors++;
-					continue;
-				}
-			}
-			eh = mtod(m, struct ether_header *);
-
-			ni = ieee80211_find_txnode(ic, eh->ether_dhost);
-			if (ni == NULL) {
-				m_freem(m);
-				ifp->if_oerrors++;
-				continue;
-			}
-
-			/* TODO: PS */
-
-			ifp->if_opackets++;
-			BPF_MTAP(ifp, m);
-
-			m = ieee80211_encap(ic, m, ni);
-			if (m == NULL) {
-				ieee80211_free_node(ni);
-				ifp->if_oerrors++;
-				continue;
-			}
+		ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
+		m = ieee80211_encap(ni, m);
+		if (m == NULL) {
+			ieee80211_free_node(ni);
+			ifp->if_oerrors++;
+			continue;
 		}
 
-		if (ic->ic_rawbpf != NULL)
-			bpf_mtap(ic->ic_rawbpf, m);
-
 		wh = mtod(m, struct ieee80211_frame *);
 		if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
-			k = ieee80211_crypto_encap(ic, ni, m);
+			k = ieee80211_crypto_encap(ni, m);
 			if (k == NULL) {
 				ieee80211_free_node(ni);
 				m_freem(m);
@@ -1437,6 +1439,8 @@
 		tbd->tbd_used++;
 		idx = (idx + 1) % BWI_TX_NDESC;
 
+		ifp->if_opackets++;
+
 		if (tbd->tbd_used + BWI_TX_NSPRDESC >= BWI_TX_NDESC) {
 			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 			break;
@@ -1459,8 +1463,7 @@
 	struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
 	int idx, error;
 
-	if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) ||
-	    (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
 		ieee80211_free_node(ni);
 		m_freem(m);
 		return ENETDOWN;
@@ -1522,10 +1525,6 @@
 	BWI_ASSERT_LOCKED(sc);
 
 	sc->sc_flags |= BWI_F_STOP;
-	if (statechg)
-		ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
-	else
-		bwi_newstate_begin(sc, IEEE80211_S_INIT);
 
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 		KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
@@ -1617,8 +1616,9 @@
 			 i, txrx_intr_status[i]);
 
 		if (txrx_intr_status[i] & BWI_TXRX_INTR_ERROR) {
-			if_printf(ifp, "intr fatal TX/RX (%d) error 0x%08x\n",
-				  i, txrx_intr_status[i]);
+			if_printf(ifp,
+			    "%s: intr fatal TX/RX (%d) error 0x%08x\n",
+			    __func__, i, txrx_intr_status[i]);
 			txrx_error = 1;
 		}
 	}
@@ -1637,7 +1637,7 @@
 
 	if (intr_status & BWI_INTR_PHY_TXERR) {
 		if (mac->mac_flags & BWI_MAC_F_PHYE_RESET) {
-			if_printf(ifp, "intr PHY TX error\n");
+			if_printf(ifp, "%s: intr PHY TX error\n", __func__);
 			taskqueue_enqueue(sc->sc_tq, &sc->sc_restart_task);
 			BWI_UNLOCK(sc);
 			return;
@@ -1717,15 +1717,24 @@
 static void
 bwi_set_channel(struct ieee80211com *ic)
 {
-	struct ifnet *ifp = ic->ic_ifp;
-	struct bwi_softc *sc = ifp->if_softc;
-	int error;
+	struct bwi_softc *sc = ic->ic_ifp->if_softc;
+	const struct ieee80211_channel *c = ic->ic_curchan;
+	struct bwi_mac *mac;
 
 	BWI_LOCK(sc);
-	error = bwi_set_chan(sc, ic->ic_curchan);
-	if (error)
-		if_printf(ifp, "can't set channel to %u\n",
-			  ieee80211_chan2ieee(ic, ic->ic_curchan));
+	KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
+	    ("current regwin type %d", sc->sc_cur_regwin->rw_type));
+	mac = (struct bwi_mac *)sc->sc_cur_regwin;
+	bwi_rf_set_chan(mac, ieee80211_chan2ieee(ic, c), 0);
+
+	/*
+	 * Setup radio tap channel freq and flags
+	 */
+	sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
+		htole16(c->ic_freq);
+	sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
+		htole16(c->ic_flags & 0xffff);
+
 	BWI_UNLOCK(sc);
 }
 
@@ -1734,42 +1743,37 @@
 {
 }
 
-static void
-bwi_newstate_begin(struct bwi_softc *sc, enum ieee80211_state nstate)
-{
-	BWI_ASSERT_LOCKED(sc);
-
-	callout_stop(&sc->sc_calib_ch);
-	callout_stop(&sc->sc_amrr_ch);
-
-	bwi_led_newstate(sc, nstate);
-
-	if (nstate == IEEE80211_S_INIT)
-		sc->sc_txpwrcb_type = BWI_TXPWR_INIT;
-}
-
 static int
-bwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
+bwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 {
-	struct ifnet *ifp = ic->ic_ifp;
+	struct bwi_vap *bvp = BWI_VAP(vap);
+	struct ifnet *ifp = vap->iv_ic->ic_ifp;
 	struct bwi_softc *sc = ifp->if_softc;
+	const struct ieee80211_txparam *tp;
 	struct bwi_mac *mac;
 	struct ieee80211_node *ni;
 	int error;
 
 	BWI_LOCK(sc);
 
-	bwi_newstate_begin(sc, nstate);
+	callout_stop(&bvp->bv_amrr_ch);
+	callout_stop(&sc->sc_calib_ch);
 
 	if (nstate == IEEE80211_S_INIT)
+		sc->sc_txpwrcb_type = BWI_TXPWR_INIT;
+
+	bwi_led_newstate(sc, nstate);
+
+	error = bvp->bv_newstate(vap, nstate, arg);
+	if (error != 0)
 		goto back;
 
-	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
+	if (vap->iv_opmode == IEEE80211_M_MONITOR) {
 		/* Nothing to do */
 	} else if (nstate == IEEE80211_S_RUN) {
-		ni = ic->ic_bss;
+		ni = vap->iv_bss;
 
-		bwi_set_bssid(sc, ic->ic_bss->ni_bssid);
+		bwi_set_bssid(sc, vap->iv_bss->ni_bssid);
 
 		KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
 		    ("current regwin type %d", sc->sc_cur_regwin->rw_type));
@@ -1782,27 +1786,22 @@
 #else
 		sc->sc_txpwrcb_type = BWI_TXPWR_CALIB;
 #endif
-
-		if (ic->ic_opmode == IEEE80211_M_STA) {
+		if (vap->iv_opmode == IEEE80211_M_STA) {
 			/* fake a join to init the tx rate */
 			bwi_newassoc(ni, 1);
 		}
 
-		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
-			/* start automatic rate control timer */
-			if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE)
-				callout_reset(&sc->sc_amrr_ch, hz / 2,
-				    bwi_amrr_timeout, sc);
-		}
+		/* start automatic rate control timer */
+		tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
+		if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
+			callout_reset(&bvp->bv_amrr_ch, hz / 2,
+			    bwi_amrr_timeout, vap);
+
+		callout_reset(&sc->sc_calib_ch, hz, bwi_calibrate, sc);
 	} else {
 		bwi_set_bssid(sc, bwi_zero_addr);
 	}
-
 back:
-	error = sc->sc_newstate(ic, nstate, arg);
-
-	if (nstate == IEEE80211_S_RUN)
-		callout_reset(&sc->sc_calib_ch, hz, bwi_calibrate, sc);
 	BWI_UNLOCK(sc);
 
 	return error;
@@ -1821,56 +1820,49 @@
 static void
 bwi_newassoc(struct ieee80211_node *ni, int isnew)
 {
-	struct bwi_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+	struct ieee80211vap *vap = ni->ni_vap;
 	int i;
 
-	ieee80211_amrr_node_init(&sc->sc_amrr, &((struct bwi_node *)ni)->amn);
+	ieee80211_amrr_node_init(&BWI_VAP(vap)->bv_amrr, &BWI_NODE(ni)->amn);
 
 	/* set rate to some reasonable initial value */
 	for (i = ni->ni_rates.rs_nrates - 1;
 	     i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72;
 	     i--);
-		ni->ni_txrate = i;
+	ni->ni_txrate = i;
 }
 
 static void
 bwi_iter_func(void *arg, struct ieee80211_node *ni)
 {
-	struct bwi_softc *sc = arg;
-	struct bwi_node *bn = (struct bwi_node *)ni;
+	struct ieee80211vap *vap = arg;
+	struct bwi_node *bn = BWI_NODE(ni);
 
-	ieee80211_amrr_choose(&sc->sc_amrr, ni, &bn->amn);
+	ieee80211_amrr_choose(&BWI_VAP(vap)->bv_amrr, ni, &bn->amn);
 }
 
 static void
 bwi_amrr_timeout(void *arg)
 {
-	struct bwi_softc *sc = arg;
-	struct ieee80211com *ic = &sc->sc_ic;
+	struct ieee80211vap *vap = arg;
+	struct ieee80211com *ic = vap->iv_ic;
+	struct bwi_softc *sc = ic->ic_ifp->if_softc;
 
 	BWI_ASSERT_LOCKED(sc);
 
-	if (ic->ic_opmode == IEEE80211_M_STA)
-		bwi_iter_func(sc, ic->ic_bss);
+	if (vap->iv_opmode == IEEE80211_M_STA)
+		bwi_iter_func(sc, vap->iv_bss);
 	else
-		ieee80211_iterate_nodes(&ic->ic_sta, bwi_iter_func, sc);
-	callout_reset(&sc->sc_amrr_ch, hz / 2, bwi_amrr_timeout, sc);
+		ieee80211_iterate_nodes(&ic->ic_sta, bwi_iter_func, vap);
+	callout_reset(&BWI_VAP(vap)->bv_amrr_ch, hz / 2, bwi_amrr_timeout, vap);
 }
 
 static int
 bwi_media_change(struct ifnet *ifp)
 {
-#define	IS_RUNNING(ifp) \
-	((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
-	struct bwi_softc *sc = ifp->if_softc;
-
-	BWI_LOCK(sc);
-	if (ieee80211_media_change(ifp) == ENETRESET && IS_RUNNING(ifp))
-		bwi_init(ifp->if_softc);
-	BWI_UNLOCK(sc);
-
-	return 0;
-#undef IS_RUNNING
+	int error = ieee80211_media_change(ifp);
+	/* NB: only the fixed rate can change and that doesn't need a reset */
+	return (error == ENETRESET ? 0 : error);
 }
 
 static int
@@ -2649,42 +2641,6 @@
 }
 
 static int
-bwi_set_chan(struct bwi_softc *sc, struct ieee80211_channel *c)
-{
-	struct ieee80211com *ic = &sc->sc_ic;
-	struct bwi_mac *mac;
-	uint16_t flags;
-	u_int chan;
-
-	BWI_LOCK(sc);
-
-	KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
-	    ("current regwin type %d", sc->sc_cur_regwin->rw_type));
-	mac = (struct bwi_mac *)sc->sc_cur_regwin;
-
-	chan = ieee80211_chan2ieee(ic, c);
-
-	bwi_rf_set_chan(mac, chan, 0);
-
-	/*
-	 * Setup radio tap channel freq and flags
-	 */
-	if (IEEE80211_IS_CHAN_G(c))
-		flags = IEEE80211_CHAN_G;
-	else
-		flags = IEEE80211_CHAN_B;
-
-	sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
-		htole16(c->ic_freq);
-	sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
-		htole16(flags);
-
-	BWI_UNLOCK(sc);
-
-	return 0;
-}
-
-static int
 bwi_rxeof(struct bwi_softc *sc, int end_idx)
 {
 	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
@@ -2723,8 +2679,8 @@
 
 		buflen = le16toh(hdr->rxh_buflen);
 		if (buflen < BWI_FRAME_MIN_LEN(wh_ofs)) {
-			if_printf(ifp, "zero length data, hdr_extra %d\n",
-				  hdr_extra);
+			if_printf(ifp, "%s: zero length data, hdr_extra %d\n",
+				  __func__, hdr_extra);
 			ifp->if_ierrors++;
 			m_freem(m);
 			goto next;
@@ -2743,8 +2699,8 @@
 			rate = bwi_ds_plcp2rate(plcp);
 
 		/* RX radio tap */
-		if (sc->sc_drvbpf != NULL)
-			bwi_rx_radiotap(sc, m, hdr, plcp, rate, rssi);
+		if (bpf_peers_present(ifp->if_bpf))
+			bwi_rx_radiotap(ifp, m, hdr, plcp, rate, rssi);
 
 		m_adj(m, -IEEE80211_CRC_LEN);
 
@@ -2752,10 +2708,13 @@
 
 		wh = mtod(m, struct ieee80211_frame_min *);
 		ni = ieee80211_find_rxnode(ic, wh);
-
-		type = ieee80211_input(ic, m, ni, rssi - BWI_NOISE_FLOOR,
-		    BWI_NOISE_FLOOR, le16toh(hdr->rxh_tsf));
-		ieee80211_free_node(ni);
+		if (ni != NULL) {
+			type = ieee80211_input(ni, m, rssi - BWI_NOISE_FLOOR,
+			    BWI_NOISE_FLOOR, 0);
+			ieee80211_free_node(ni);
+		} else
+			type = ieee80211_input_all(ic, m,
+			    rssi - BWI_NOISE_FLOOR, BWI_NOISE_FLOOR, 0);
 		if (type == IEEE80211_FC0_TYPE_DATA) {
 			rx_data = 1;
 			sc->sc_rx_rate = rate;
@@ -2887,8 +2846,8 @@
 		DELAY(1000);
 	}
 	if (i == NRETRY) {
-		if_printf(ifp, "wait for TX ring(%d) stable timed out\n",
-			  ring_idx);
+		if_printf(ifp, "%s: wait for TX ring(%d) stable timed out\n",
+			  __func__, ring_idx);
 	}
 
 	CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, 0);
@@ -2901,7 +2860,8 @@
 		DELAY(1000);
 	}
 	if (i == NRETRY)
-		if_printf(ifp, "reset TX ring (%d) timed out\n", ring_idx);
+		if_printf(ifp, "%s: reset TX ring (%d) timed out\n",
+		     __func__, ring_idx);
 
 #undef NRETRY
 
@@ -3039,13 +2999,16 @@
 bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
 	  struct ieee80211_node *ni)
 {
+	struct ieee80211vap *vap = ni->ni_vap;
 	struct ieee80211com *ic = &sc->sc_ic;
+	struct ifnet *ifp = ic->ic_ifp;
 	struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING];
 	struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
 	struct bwi_txbuf *tb = &tbd->tbd_buf[idx];
 	struct bwi_mac *mac;
 	struct bwi_txbuf_hdr *hdr;
 	struct ieee80211_frame *wh;
+	const struct ieee80211_txparam *tp;
 	uint8_t rate, rate_fb;
 	uint32_t mac_ctrl;
 	uint16_t phy_ctrl;
@@ -3069,9 +3032,14 @@
 	 * Find TX rate
 	 */
 	bzero(tb->tb_rate_idx, sizeof(tb->tb_rate_idx));
+	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
 	if (IEEE80211_IS_MULTICAST(wh->i_addr1))
-		rate = rate_fb = ic->ic_mcast_rate;
-	else if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) {
+		rate = rate_fb = tp->mcastrate;
+	else if (m->m_flags & M_EAPOL)
+		rate = rate_fb = tp->mgmtrate;
+	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
+		rate = rate_fb = tp->ucastrate;
+	else {
 		rate = ni->ni_rates.rs_rates[ni->ni_txrate] & 
 		    IEEE80211_RATE_VAL;
 		tb->tb_rate_idx[0] = ni->ni_txrate;
@@ -3084,15 +3052,13 @@
 			rate_fb = rate;
 			tb->tb_rate_idx[1] = tb->tb_rate_idx[0];
 		}
-	} else
-		rate = rate_fb = ic->ic_fixed_rate;
-
+	}
 	sc->sc_tx_rate = rate;
 
 	/*
 	 * TX radio tap
 	 */
-	if (bpf_peers_present(sc->sc_drvbpf)) {
+	if (bpf_peers_present(ifp->if_bpf)) {
 		sc->sc_tx_th.wt_flags = 0;
 		if (wh->i_fc[1] & IEEE80211_FC1_WEP)
 			sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
@@ -3103,7 +3069,7 @@
 		}
 		sc->sc_tx_th.wt_rate = rate;
 
-		bpf_mtap2(sc->sc_drvbpf, &sc->sc_tx_th, sc->sc_tx_th_len, m);
+		bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m);
 	}
 
 	/*
@@ -3111,7 +3077,7 @@
 	 */
 	M_PREPEND(m, sizeof(*hdr), M_DONTWAIT);
 	if (m == NULL) {
-		if_printf(ic->ic_ifp, "prepend TX header failed\n");
+		if_printf(ifp, "%s: prepend TX header failed\n", __func__);
 		return ENOBUFS;
 	}
 	hdr = mtod(m, struct bwi_txbuf_hdr *);
@@ -3163,7 +3129,8 @@
 	error = bus_dmamap_load_mbuf(sc->sc_buf_dtag, tb->tb_dmap, m,
 				     bwi_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
 	if (error && error != EFBIG) {
-		if_printf(ic->ic_ifp, "can't load TX buffer (1) %d\n", error);
+		if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
+		    __func__, error);
 		goto back;
 	}
 
@@ -3172,7 +3139,8 @@
 
 		m_new = m_defrag(m, M_DONTWAIT);
 		if (m_new == NULL) {
-			if_printf(ic->ic_ifp, "can't defrag TX buffer\n");
+			if_printf(ifp, "%s: can't defrag TX buffer\n",
+			    __func__);
 			error = ENOBUFS;
 			goto back;
 		} else {
@@ -3183,8 +3151,8 @@

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list