Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F143610097
D9797.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D9797.diff
View Options
Index: head/sys/dev/iwn/if_iwn.c
===================================================================
--- head/sys/dev/iwn/if_iwn.c
+++ head/sys/dev/iwn/if_iwn.c
@@ -217,7 +217,7 @@
static void iwn_cmd_done(struct iwn_softc *, struct iwn_rx_desc *);
static void iwn_notif_intr(struct iwn_softc *);
static void iwn_wakeup_intr(struct iwn_softc *);
-static void iwn_rftoggle_intr(struct iwn_softc *);
+static void iwn_rftoggle_task(void *, int);
static void iwn_fatal_intr(struct iwn_softc *);
static void iwn_intr(void *);
static void iwn4965_update_sched(struct iwn_softc *, int, int, uint8_t,
@@ -334,11 +334,9 @@
static int iwn_hw_prepare(struct iwn_softc *);
static int iwn_hw_init(struct iwn_softc *);
static void iwn_hw_stop(struct iwn_softc *);
-static void iwn_radio_on(void *, int);
-static void iwn_radio_off(void *, int);
static void iwn_panicked(void *, int);
-static void iwn_init_locked(struct iwn_softc *);
-static void iwn_init(struct iwn_softc *);
+static int iwn_init_locked(struct iwn_softc *);
+static int iwn_init(struct iwn_softc *);
static void iwn_stop_locked(struct iwn_softc *);
static void iwn_stop(struct iwn_softc *);
static void iwn_scan_start(struct ieee80211com *);
@@ -679,8 +677,7 @@
callout_init_mtx(&sc->calib_to, &sc->sc_mtx, 0);
callout_init_mtx(&sc->scan_timeout, &sc->sc_mtx, 0);
callout_init_mtx(&sc->watchdog_to, &sc->sc_mtx, 0);
- TASK_INIT(&sc->sc_radioon_task, 0, iwn_radio_on, sc);
- TASK_INIT(&sc->sc_radiooff_task, 0, iwn_radio_off, sc);
+ TASK_INIT(&sc->sc_rftoggle_task, 0, iwn_rftoggle_task, sc);
TASK_INIT(&sc->sc_panic_task, 0, iwn_panicked, sc);
TASK_INIT(&sc->sc_xmit_task, 0, iwn_xmit_task, sc);
@@ -1401,8 +1398,6 @@
iwn_xmit_queue_drain(sc);
IWN_UNLOCK(sc);
- ieee80211_draintask(&sc->sc_ic, &sc->sc_radioon_task);
- ieee80211_draintask(&sc->sc_ic, &sc->sc_radiooff_task);
iwn_stop(sc);
taskqueue_drain_all(sc->sc_tq);
@@ -4013,19 +4008,28 @@
}
static void
-iwn_rftoggle_intr(struct iwn_softc *sc)
+iwn_rftoggle_task(void *arg, int npending)
{
+ struct iwn_softc *sc = arg;
struct ieee80211com *ic = &sc->sc_ic;
- uint32_t tmp = IWN_READ(sc, IWN_GP_CNTRL);
+ uint32_t tmp;
- IWN_LOCK_ASSERT(sc);
+ IWN_LOCK(sc);
+ tmp = IWN_READ(sc, IWN_GP_CNTRL);
+ IWN_UNLOCK(sc);
device_printf(sc->sc_dev, "RF switch: radio %s\n",
(tmp & IWN_GP_CNTRL_RFKILL) ? "enabled" : "disabled");
- if (tmp & IWN_GP_CNTRL_RFKILL)
- ieee80211_runtask(ic, &sc->sc_radioon_task);
- else
- ieee80211_runtask(ic, &sc->sc_radiooff_task);
+ if (!(tmp & IWN_GP_CNTRL_RFKILL)) {
+ ieee80211_suspend_all(ic);
+
+ /* Enable interrupts to get RF toggle notification. */
+ IWN_LOCK(sc);
+ IWN_WRITE(sc, IWN_INT, 0xffffffff);
+ IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
+ IWN_UNLOCK(sc);
+ } else
+ ieee80211_resume_all(ic);
}
/*
@@ -4139,7 +4143,7 @@
IWN_WRITE(sc, IWN_FH_INT, r2);
if (r1 & IWN_INT_RF_TOGGLED) {
- iwn_rftoggle_intr(sc);
+ taskqueue_enqueue(sc->sc_tq, &sc->sc_rftoggle_task);
goto done;
}
if (r1 & IWN_INT_CT_REACHED) {
@@ -5084,25 +5088,28 @@
iwn_parent(struct ieee80211com *ic)
{
struct iwn_softc *sc = ic->ic_softc;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- int startall = 0, stop = 0;
-
- IWN_LOCK(sc);
+ struct ieee80211vap *vap;
+ int error;
+
if (ic->ic_nrunning > 0) {
- if (!(sc->sc_flags & IWN_FLAG_RUNNING)) {
- iwn_init_locked(sc);
- if (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL)
- startall = 1;
- else
- stop = 1;
+ error = iwn_init(sc);
+
+ switch (error) {
+ case 0:
+ ieee80211_start_all(ic);
+ break;
+ case EAGAIN:
+ /* radio is disabled via RFkill switch */
+ taskqueue_enqueue(sc->sc_tq, &sc->sc_rftoggle_task);
+ break;
+ default:
+ vap = TAILQ_FIRST(&ic->ic_vaps);
+ if (vap != NULL)
+ ieee80211_stop(vap);
+ break;
}
- } else if (sc->sc_flags & IWN_FLAG_RUNNING)
- iwn_stop_locked(sc);
- IWN_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- else if (vap != NULL && stop)
- ieee80211_stop(vap);
+ } else
+ iwn_stop(sc);
}
/*
@@ -8681,41 +8688,6 @@
}
static void
-iwn_radio_on(void *arg0, int pending)
-{
- struct iwn_softc *sc = arg0;
- struct ieee80211com *ic = &sc->sc_ic;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
-
- DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__);
-
- if (vap != NULL) {
- iwn_init(sc);
- ieee80211_init(vap);
- }
-}
-
-static void
-iwn_radio_off(void *arg0, int pending)
-{
- struct iwn_softc *sc = arg0;
- struct ieee80211com *ic = &sc->sc_ic;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
-
- DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__);
-
- iwn_stop(sc);
- if (vap != NULL)
- ieee80211_stop(vap);
-
- /* Enable interrupts to get RF toggle notification. */
- IWN_LOCK(sc);
- IWN_WRITE(sc, IWN_INT, 0xffffffff);
- IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
- IWN_UNLOCK(sc);
-}
-
-static void
iwn_panicked(void *arg0, int pending)
{
struct iwn_softc *sc = arg0;
@@ -8746,7 +8718,11 @@
IWN_LOCK(sc);
iwn_stop_locked(sc);
- iwn_init_locked(sc);
+ if ((error = iwn_init_locked(sc)) != 0) {
+ device_printf(sc->sc_dev,
+ "%s: could not init hardware\n", __func__);
+ goto unlock;
+ }
if (vap->iv_state >= IEEE80211_S_AUTH &&
(error = iwn_auth(sc, vap)) != 0) {
device_printf(sc->sc_dev,
@@ -8758,11 +8734,12 @@
"%s: could not move to run state\n", __func__);
}
+unlock:
IWN_UNLOCK(sc);
#endif
}
-static void
+static int
iwn_init_locked(struct iwn_softc *sc)
{
int error;
@@ -8771,6 +8748,9 @@
IWN_LOCK_ASSERT(sc);
+ if (sc->sc_flags & IWN_FLAG_RUNNING)
+ goto end;
+
sc->sc_flags |= IWN_FLAG_RUNNING;
if ((error = iwn_hw_prepare(sc)) != 0) {
@@ -8785,12 +8765,8 @@
/* Check that the radio is not disabled by hardware switch. */
if (!(IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL)) {
- device_printf(sc->sc_dev,
- "radio is disabled by hardware switch\n");
- /* Enable interrupts to get RF toggle notifications. */
- IWN_WRITE(sc, IWN_INT, 0xffffffff);
- IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
- return;
+ error = EAGAIN;
+ goto fail;
}
/* Read firmware images from the filesystem. */
@@ -8821,26 +8797,29 @@
callout_reset(&sc->watchdog_to, hz, iwn_watchdog, sc);
+end:
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__);
- return;
+ return (0);
fail:
- sc->sc_flags &= ~IWN_FLAG_RUNNING;
iwn_stop_locked(sc);
+
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end in error\n",__func__);
+
+ return (error);
}
-static void
+static int
iwn_init(struct iwn_softc *sc)
{
+ int error;
IWN_LOCK(sc);
- iwn_init_locked(sc);
+ error = iwn_init_locked(sc);
IWN_UNLOCK(sc);
- if (sc->sc_flags & IWN_FLAG_RUNNING)
- ieee80211_start_all(&sc->sc_ic);
+ return (error);
}
static void
@@ -8849,6 +8828,9 @@
IWN_LOCK_ASSERT(sc);
+ if (!(sc->sc_flags & IWN_FLAG_RUNNING))
+ return;
+
sc->sc_is_scanning = 0;
sc->sc_tx_timer = 0;
callout_stop(&sc->watchdog_to);
Index: head/sys/dev/iwn/if_iwnvar.h
===================================================================
--- head/sys/dev/iwn/if_iwnvar.h
+++ head/sys/dev/iwn/if_iwnvar.h
@@ -305,8 +305,7 @@
int sc_cap_off; /* PCIe Capabilities. */
/* Tasks used by the driver */
- struct task sc_radioon_task;
- struct task sc_radiooff_task;
+ struct task sc_rftoggle_task;
struct task sc_panic_task;
struct task sc_xmit_task;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Feb 1, 1:35 AM (15 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28241418
Default Alt Text
D9797.diff (7 KB)
Attached To
Mode
D9797: iwn: some initialization / RF switch state change fixes
Attached
Detach File
Event Timeline
Log In to Comment