Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F176027710
D60607.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D60607.diff
View Options
diff --git a/sys/dev/iwm/if_iwm.c b/sys/dev/iwm/if_iwm.c
--- a/sys/dev/iwm/if_iwm.c
+++ b/sys/dev/iwm/if_iwm.c
@@ -2149,6 +2149,69 @@
/* XXX TODO: MCS8..15 if >1 antenna and mimo enabled */
}
+static void
+iwm_vap_update_slot(struct ieee80211vap *vap)
+{
+ struct ieee80211com *ic = vap->iv_ic;
+ struct iwm_softc *sc = ic->ic_softc;
+
+ IWM_LOCK_ASSERT_UNLOCKED(sc);
+
+ IWM_LOCK(sc);
+ if ((sc->sc_flags & IWM_FLAG_STOPPED) == 0) {
+ taskqueue_enqueue(sc->sc_tq, &sc->mac_ctxt_task);
+ }
+ IWM_UNLOCK(sc);
+}
+
+static void
+iwm_vap_update_preamble(struct ieee80211vap *vap)
+{
+ struct ieee80211com *ic = vap->iv_ic;
+ struct iwm_softc *sc = ic->ic_softc;
+
+ IWM_LOCK_ASSERT_UNLOCKED(sc);
+
+ IWM_LOCK(sc);
+ if ((sc->sc_flags & IWM_FLAG_STOPPED) == 0) {
+ taskqueue_enqueue(sc->sc_tq, &sc->mac_ctxt_task);
+ }
+ IWM_UNLOCK(sc);
+}
+
+static int
+iwm_vap_update_wme(struct ieee80211vap *vap,
+ const struct wmeParams *wme_params)
+{
+ struct ieee80211com *ic = vap->iv_ic;
+ struct iwm_softc *sc = ic->ic_softc;
+
+ IWM_LOCK_ASSERT_UNLOCKED(sc);
+
+ IWM_LOCK(sc);
+ if ((sc->sc_flags & IWM_FLAG_STOPPED) == 0) {
+ taskqueue_enqueue(sc->sc_tq, &sc->mac_ctxt_task);
+ }
+ IWM_UNLOCK(sc);
+
+ return (0);
+}
+
+static void
+iwm_vap_update_erp_protmode(struct ieee80211vap *vap)
+{
+ struct ieee80211com *ic = vap->iv_ic;
+ struct iwm_softc *sc = ic->ic_softc;
+
+ IWM_LOCK_ASSERT_UNLOCKED(sc);
+
+ IWM_LOCK(sc);
+ if ((sc->sc_flags & IWM_FLAG_STOPPED) == 0) {
+ taskqueue_enqueue(sc->sc_tq, &sc->mac_ctxt_task);
+ }
+ IWM_UNLOCK(sc);
+}
+
static void
iwm_set_hw_address_family_8000(struct iwm_softc *sc, struct iwm_nvm_data *data,
const uint16_t *mac_override, const uint16_t *nvm_hw)
@@ -5209,9 +5272,20 @@
static void
iwm_stop(struct iwm_softc *sc)
{
+ IWM_LOCK_ASSERT_LOCKED(sc);
sc->sc_flags &= ~IWM_FLAG_HW_INITED;
sc->sc_flags |= IWM_FLAG_STOPPED;
+
+ /*
+ * Attempt to cancel; but if we can't, then don't call drain as
+ * that can't be done with the lock held.
+ */
+ if (sc->sc_tq != NULL) {
+ taskqueue_cancel(sc->sc_tq, &sc->mac_ctxt_task, NULL);
+ taskqueue_cancel(sc->sc_tq, &sc->phy_ctxt_task, NULL);
+ }
+
sc->sc_generation++;
iwm_led_blink_stop(sc);
sc->sc_tx_timer = 0;
@@ -5249,6 +5323,8 @@
int startall = 0;
int rfkill = 0;
+ IWM_LOCK_ASSERT_UNLOCKED(sc);
+
IWM_LOCK(sc);
if (ic->ic_nrunning > 0) {
if (!(sc->sc_flags & IWM_FLAG_HW_INITED)) {
@@ -5273,6 +5349,8 @@
struct ieee80211com *ic = &sc->sc_ic;
int rfkill;
+ IWM_LOCK_ASSERT_UNLOCKED(sc);
+
IWM_LOCK(sc);
rfkill = iwm_check_rfkill(sc);
IWM_UNLOCK(sc);
@@ -5289,6 +5367,68 @@
}
}
+/*
+ * Deferred MAC related task updates.
+ *
+ * This is scheduled whenever something in the STA MAC
+ * config has changed. This driver currently only supports
+ * a single STA interface, so that's the assumption made
+ * here.
+ */
+static void
+iwm_mac_ctxt_task(void *arg, int npending __unused)
+{
+ struct iwm_softc *sc = arg;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+ const struct iwm_vap *iv;
+ int error;
+
+ IWM_LOCK_ASSERT_UNLOCKED(sc);
+
+ if (vap == NULL)
+ return;
+
+ iv = IWM_VAP(vap);
+
+ IWM_LOCK(sc);
+
+ /* Don't scheduled work if the driver is stopped */
+ if (sc->sc_flags & IWM_FLAG_STOPPED) {
+ IWM_UNLOCK(sc);
+ return;
+ }
+
+ /*
+ * Only trigger an update if we've already programmed in a
+ * MAC context.
+ */
+ if (iv->is_uploaded) {
+ if ((error = iwm_mac_ctxt_changed(sc, vap)) != 0) {
+ device_printf(sc->sc_dev,
+ "%s: failed to update MAC\n", __func__);
+ }
+ }
+ IWM_UNLOCK(sc);
+}
+
+/*
+ * Deferred PHY related task updates.
+ *
+ * This is scheduled whenever something in the STA PHY
+ * config has changed. This driver currently only supports
+ * a single STA interface, so that's the assumption made
+ * here.
+ */
+static void
+iwm_phy_ctxt_task(void *arg, int npending __unused)
+{
+ struct iwm_softc *sc = arg;
+ /* TODO */
+
+ device_printf(sc->sc_dev, "%s: called\n", __func__);
+}
+
/*
* The interrupt side of things
*/
@@ -6326,6 +6466,14 @@
TASK_INIT(&sc->sc_es_task, 0, iwm_endscan_cb, sc);
TASK_INIT(&sc->sc_rftoggle_task, 0, iwm_rftoggle_task, sc);
+ /*
+ * Note: these would be per-ctx, but right now the driver
+ * only knows about a single VAP. This mirrors what
+ * OpenBSD iwm does to make porting/updating easier.
+ */
+ TASK_INIT(&sc->mac_ctxt_task, 0, iwm_mac_ctxt_task, sc);
+ TASK_INIT(&sc->phy_ctxt_task, 0, iwm_phy_ctxt_task, sc);
+
sc->sc_tq = taskqueue_create("iwm_taskq", M_WAITOK,
taskqueue_thread_enqueue, &sc->sc_tq);
error = taskqueue_start_threads(&sc->sc_tq, 1, 0, "iwm_taskq");
@@ -6711,6 +6859,11 @@
ivp->iv_newstate = vap->iv_newstate;
vap->iv_newstate = iwm_newstate;
+ vap->iv_updateslot = iwm_vap_update_slot;
+ vap->iv_erp_protmode_update = iwm_vap_update_erp_protmode;
+ vap->iv_preamble_update = iwm_vap_update_preamble;
+ vap->iv_wme_update = iwm_vap_update_wme;
+
ivp->id = IWM_DEFAULT_MACID;
ivp->color = IWM_DEFAULT_COLOR;
@@ -6905,15 +7058,29 @@
IWM_LOCK_ASSERT_UNLOCKED(sc);
- if (!sc->sc_attached)
+ IWM_LOCK(sc);
+ if (!sc->sc_attached) {
+ IWM_UNLOCK(sc);
return 0;
+ }
sc->sc_attached = 0;
+ sc->sc_flags |= IWM_FLAG_STOPPED;
+ IWM_UNLOCK(sc);
+
if (do_net80211) {
ieee80211_draintask(&sc->sc_ic, &sc->sc_es_task);
}
iwm_stop_device(sc);
+
+ while (taskqueue_cancel(sc->sc_tq, &sc->mac_ctxt_task, NULL) != 0)
+ taskqueue_drain(sc->sc_tq, &sc->mac_ctxt_task);
+ while (taskqueue_cancel(sc->sc_tq, &sc->phy_ctxt_task, NULL) != 0)
+ taskqueue_drain(sc->sc_tq, &sc->phy_ctxt_task);
+
taskqueue_drain_all(sc->sc_tq);
taskqueue_free(sc->sc_tq);
+ sc->sc_tq = NULL;
+
if (do_net80211) {
IWM_LOCK(sc);
iwm_xmit_queue_drain(sc);
diff --git a/sys/dev/iwm/if_iwmvar.h b/sys/dev/iwm/if_iwmvar.h
--- a/sys/dev/iwm/if_iwmvar.h
+++ b/sys/dev/iwm/if_iwmvar.h
@@ -439,6 +439,12 @@
struct task init_task;
+ /* Task for ERP/HT prot/slot-time/EDCA updates. */
+ struct task mac_ctxt_task;
+
+ /* Task for HT 20/40 MHz channel width updates. */
+ struct task phy_ctxt_task;
+
struct resource *sc_irq;
struct resource *sc_mem;
bus_space_tag_t sc_st;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Oct 16, 10:30 AM (14 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40875145
Default Alt Text
D60607.diff (6 KB)
Attached To
Mode
D60607: iwm: add phy/mac context tasks; clean up task stop; add net80211 MAC methods
Attached
Detach File
Event Timeline
Log In to Comment