PERFORCE change 135480 for review
Sepherosa Ziehau
sephe at FreeBSD.org
Sat Feb 16 00:00:44 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=135480
Change 135480 by sephe at sephe_zealot:sam_wifi on 2008/02/16 08:00:42
For MAC rev >= 5, if PHY error interrupt comes then reset the device
but leave 802.11 state machine untouched.
Affected files ...
.. //depot/projects/wifi/sys/dev/bwi/bwimac.c#7 edit
.. //depot/projects/wifi/sys/dev/bwi/if_bwi.c#20 edit
.. //depot/projects/wifi/sys/dev/bwi/if_bwivar.h#12 edit
Differences ...
==== //depot/projects/wifi/sys/dev/bwi/bwimac.c#7 (text+ko) ====
@@ -31,7 +31,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $DragonFly: src/sys/dev/netif/bwi/bwimac.c,v 1.11 2008/01/15 09:01:13 sephe Exp $
+ * $DragonFly: src/sys/dev/netif/bwi/bwimac.c,v 1.13 2008/02/15 11:15:38 sephe Exp $
*/
#include <sys/cdefs.h>
@@ -1649,6 +1649,8 @@
mac->mac_flags |= BWI_MAC_F_HAS_TXSTATS;
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "%s\n",
"has TX stats");
+ } else {
+ mac->mac_flags |= BWI_MAC_F_PHYE_RESET;
}
device_printf(sc->sc_dev, "MAC: rev %u\n", rev);
==== //depot/projects/wifi/sys/dev/bwi/if_bwi.c#20 (text+ko) ====
@@ -31,8 +31,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $DragonFly: src/sys/dev/netif/bwi/if_bwi.c,v 1.18 2008/01/15 09:01:13 sephe Exp $
- * 1.8 is not merged
+ * $DragonFly: src/sys/dev/netif/bwi/if_bwi.c,v 1.19 2008/02/15 11:15:38 sephe Exp $
*/
#include <sys/cdefs.h>
@@ -51,6 +50,7 @@
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
+#include <sys/taskqueue.h>
#include <net/if.h>
#include <net/if_dl.h>
@@ -96,6 +96,7 @@
static void bwi_init(void *);
static int bwi_ioctl(struct ifnet *, u_long, caddr_t);
static void bwi_start(struct ifnet *);
+static void bwi_start_locked(struct ifnet *);
static void bwi_watchdog(struct ifnet *);
static void bwi_scan_start(struct ieee80211com *);
static void bwi_set_channel(struct ieee80211com *);
@@ -115,7 +116,10 @@
static void bwi_rx_radiotap(struct bwi_softc *, struct mbuf *,
struct bwi_rxbuf_hdr *, const void *, int, int);
-static void bwi_stop(struct bwi_softc *);
+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);
static int bwi_encap(struct bwi_softc *, int, struct mbuf *,
struct ieee80211_node *);
@@ -348,6 +352,15 @@
BWI_LOCK_INIT(sc);
/*
+ * Initialize taskq and various tasks
+ */
+ sc->sc_tq = taskqueue_create("bwi_taskq", M_NOWAIT | M_ZERO,
+ taskqueue_thread_enqueue, &sc->sc_tq);
+ taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq",
+ device_get_nameunit(dev));
+ TASK_INIT(&sc->sc_restart_task, 0, bwi_restart, sc);
+
+ /*
* Initialize sysctl variables
*/
sc->sc_fw_version = BWI_FW_VERSION3;
@@ -565,7 +578,7 @@
int i;
BWI_LOCK(sc);
- bwi_stop(sc);
+ bwi_stop(sc, 1);
BWI_UNLOCK(sc);
callout_drain(&sc->sc_calib_ch);
@@ -576,6 +589,7 @@
bwi_mac_detach(&sc->sc_mac[i]);
bwi_dma_free(sc);
if_free(ifp);
+ taskqueue_free(sc->sc_tq);
BWI_LOCK_DESTROY(sc);
@@ -586,7 +600,7 @@
bwi_suspend(struct bwi_softc *sc)
{
BWI_LOCK(sc);
- bwi_stop(sc);
+ bwi_stop(sc, 1);
BWI_UNLOCK(sc);
}
@@ -606,7 +620,7 @@
bwi_shutdown(struct bwi_softc *sc)
{
BWI_LOCK(sc);
- bwi_stop(sc);
+ bwi_stop(sc, 1);
BWI_UNLOCK(sc);
return 0;
}
@@ -1166,7 +1180,12 @@
static void
bwi_init(void *xsc)
{
- struct bwi_softc *sc = xsc;
+ bwi_init_statechg(xsc, 1);
+}
+
+static void
+bwi_init_statechg(struct bwi_softc *sc, int statechg)
+{
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = ic->ic_ifp;
struct bwi_mac *mac;
@@ -1174,7 +1193,7 @@
BWI_LOCK(sc);
- bwi_stop(sc);
+ bwi_stop(sc, statechg);
bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST);
@@ -1233,15 +1252,24 @@
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- if (ic->ic_opmode != IEEE80211_M_MONITOR) {
- if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
- ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
+ 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 {
- ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
+ /* 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);
+ bwi_stop(sc, 1);
+ else
+ bwi_start_locked(ifp);
BWI_UNLOCK(sc);
}
@@ -1285,7 +1313,7 @@
bwi_init(sc);
} else {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- bwi_stop(sc);
+ bwi_stop(sc, 1);
}
break;
default:
@@ -1308,6 +1336,16 @@
bwi_start(struct ifnet *ifp)
{
struct bwi_softc *sc = ifp->if_softc;
+
+ BWI_LOCK(sc);
+ bwi_start_locked(ifp);
+ BWI_UNLOCK(sc);
+}
+
+static void
+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;
@@ -1317,12 +1355,9 @@
struct mbuf *m;
int trans, idx;
- BWI_LOCK(sc);
if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) ||
- (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- BWI_UNLOCK(sc);
+ (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
return;
- }
trans = 0;
idx = tbd->tbd_idx;
@@ -1404,7 +1439,6 @@
if (trans)
ifp->if_timer = 5;
- BWI_UNLOCK(sc);
}
static void
@@ -1416,13 +1450,13 @@
if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) {
if_printf(ifp, "watchdog timeout\n");
ifp->if_oerrors++;
- /* TODO */
+ taskqueue_enqueue(sc->sc_tq, &sc->sc_restart_task);
}
BWI_UNLOCK(sc);
}
static void
-bwi_stop(struct bwi_softc *sc)
+bwi_stop(struct bwi_softc *sc, int statechg)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = ic->ic_ifp;
@@ -1432,7 +1466,10 @@
BWI_ASSERT_LOCKED(sc);
sc->sc_flags |= BWI_F_STOP;
- ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
+ 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,
@@ -1473,6 +1510,7 @@
bwi_intr(void *xsc)
{
struct bwi_softc *sc = xsc;
+ struct bwi_mac *mac;
struct ifnet *ifp = sc->sc_ic.ic_ifp;
uint32_t intr_status;
uint32_t txrx_intr_status[BWI_TXRX_NRING];
@@ -1502,6 +1540,10 @@
return;
}
+ 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;
+
txrx_error = 0;
DPRINTF(sc, BWI_DBG_INTR, "%s\n", "TX/RX intr");
for (i = 0; i < BWI_TXRX_NRING; ++i) {
@@ -1537,18 +1579,21 @@
/* Disable all interrupts */
bwi_disable_intrs(sc, BWI_ALL_INTRS);
- if (intr_status & BWI_INTR_PHY_TXERR)
- if_printf(ifp, "intr PHY TX error\n");
+ if (intr_status & BWI_INTR_PHY_TXERR) {
+ if (mac->mac_flags & BWI_MAC_F_PHYE_RESET) {
+ if_printf(ifp, "intr PHY TX error\n");
+ taskqueue_enqueue(sc->sc_tq, &sc->sc_restart_task);
+ BWI_UNLOCK(sc);
+ return;
+ }
+ }
if (txrx_error) {
/* TODO: reset device */
}
- if (intr_status & BWI_INTR_TBTT) {
- KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
- ("current regwin type %d", sc->sc_cur_regwin->rw_type));
- bwi_mac_config_ps((struct bwi_mac *)sc->sc_cur_regwin);
- }
+ if (intr_status & BWI_INTR_TBTT)
+ bwi_mac_config_ps(mac);
if (intr_status & BWI_INTR_EO_ATIM)
if_printf(ifp, "EO_ATIM\n");
@@ -1633,6 +1678,20 @@
{
}
+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)
{
@@ -1644,10 +1703,7 @@
BWI_LOCK(sc);
- callout_stop(&sc->sc_calib_ch);
- callout_stop(&sc->sc_amrr_ch);
-
- bwi_led_newstate(sc, nstate);
+ bwi_newstate_begin(sc, nstate);
if (nstate == IEEE80211_S_INIT)
goto back;
@@ -4041,3 +4097,12 @@
}
return txtime;
}
+
+static void
+bwi_restart(void *xsc, int pending)
+{
+ struct bwi_softc *sc = xsc;
+
+ if_printf(sc->sc_ifp, "%s begin\n", __func__);
+ bwi_init_statechg(xsc, 0);
+}
==== //depot/projects/wifi/sys/dev/bwi/if_bwivar.h#12 (text+ko) ====
@@ -31,7 +31,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $DragonFly: src/sys/dev/netif/bwi/if_bwivar.h,v 1.13 2008/01/15 09:01:13 sephe Exp $
+ * $DragonFly: src/sys/dev/netif/bwi/if_bwivar.h,v 1.14 2008/02/15 11:15:38 sephe Exp $
* 1.9 is not merged
*/
@@ -476,6 +476,7 @@
#define BWI_MAC_F_ENABLED 0x10
#define BWI_MAC_F_LOCKED 0x20 /* for debug */
#define BWI_MAC_F_TPCTL_ERROR 0x40
+#define BWI_MAC_F_PHYE_RESET 0x80
#define BWI_CREATE_MAC(mac, sc, id, rev) \
do { \
@@ -608,6 +609,9 @@
struct bwi_rx_radiotap_hdr sc_rx_th;
int sc_rx_th_len;
+ struct taskqueue *sc_tq;
+ struct task sc_restart_task;
+
int (*sc_newstate)
(struct ieee80211com *,
enum ieee80211_state, int);
More information about the p4-projects
mailing list