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