summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2020-04-02 12:34:28 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2020-04-02 12:34:28 +0000
commit18df0738bfe427dad789626303a916ae1022f8a3 (patch)
treea5a44986289ebfc6db70dd4de2a2807917160a3e /sys/dev/pci
parente03c6e4e196bdd36834f3c8938a2584348eac052 (diff)
iwm's LQ_CMD can work asynchronously from interrupt context.
There is no need to schedule a task to send this command and wait for a response. Linux iwlwifi also sends this command async. tested by myself and benno
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/if_iwm.c38
-rw-r--r--sys/dev/pci/if_iwmvar.h3
2 files changed, 9 insertions, 32 deletions
diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c
index 2b3c60404a2..776f62012f8 100644
--- a/sys/dev/pci/if_iwm.c
+++ b/sys/dev/pci/if_iwm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwm.c,v 1.303 2020/04/02 12:25:21 stsp Exp $ */
+/* $OpenBSD: if_iwm.c,v 1.304 2020/04/02 12:34:27 stsp Exp $ */
/*
* Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -453,8 +453,7 @@ int iwm_run(struct iwm_softc *);
int iwm_run_stop(struct iwm_softc *);
struct ieee80211_node *iwm_node_alloc(struct ieee80211com *);
void iwm_calib_timeout(void *);
-void iwm_setrates_task(void *);
-void iwm_setrates(struct iwm_node *);
+void iwm_setrates(struct iwm_node *, int);
int iwm_media_change(struct ifnet *);
void iwm_newstate_task(void *);
int iwm_newstate(struct ieee80211com *, enum ieee80211_state, int);
@@ -4206,7 +4205,7 @@ iwm_rx_tx_cmd_single(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
best_mcs = ieee80211_mira_get_best_mcs(&in->in_mn);
if (best_mcs != in->chosen_txmcs) {
in->chosen_txmcs = best_mcs;
- iwm_add_task(sc, systq, &sc->setrates_task);
+ iwm_setrates(in, 1);
}
/* Fall back to CCK rates if MCS 0 is failing. */
@@ -6753,7 +6752,7 @@ iwm_run(struct iwm_softc *sc)
in->in_ni.ni_txmcs = 0;
in->chosen_txrate = 0;
in->chosen_txmcs = 0;
- iwm_setrates(in);
+ iwm_setrates(in, 0);
timeout_add_msec(&sc->sc_calib_to, 500);
iwm_led_enable(sc);
@@ -6834,7 +6833,7 @@ iwm_calib_timeout(void *arg)
*/
if (ni->ni_txrate != in->chosen_txrate) {
in->chosen_txrate = ni->ni_txrate;
- iwm_add_task(sc, systq, &sc->setrates_task);
+ iwm_setrates(in, 1);
}
if (in->ht_force_cck) {
struct ieee80211_rateset *rs = &ni->ni_rates;
@@ -6851,27 +6850,7 @@ iwm_calib_timeout(void *arg)
}
void
-iwm_setrates_task(void *arg)
-{
- struct iwm_softc *sc = arg;
- struct ieee80211com *ic = &sc->sc_ic;
- struct iwm_node *in = (struct iwm_node *)ic->ic_bss;
- int s = splnet();
-
- if (sc->sc_flags & IWM_FLAG_SHUTDOWN) {
- refcnt_rele_wake(&sc->task_refs);
- splx(s);
- return;
- }
-
- /* Update rates table based on new TX rate determined by AMRR. */
- iwm_setrates(in);
- refcnt_rele_wake(&sc->task_refs);
- splx(s);
-}
-
-void
-iwm_setrates(struct iwm_node *in)
+iwm_setrates(struct iwm_node *in, int async)
{
struct ieee80211_node *ni = &in->in_ni;
struct ieee80211com *ic = ni->ni_ic;
@@ -6884,6 +6863,8 @@ iwm_setrates(struct iwm_node *in)
.len = { sizeof(lqcmd), },
};
+ cmd.flags = async ? IWM_CMD_ASYNC : 0;
+
memset(&lqcmd, 0, sizeof(lqcmd));
lqcmd.sta_id = IWM_STATION_ID;
@@ -7128,7 +7109,6 @@ iwm_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
ieee80211_mira_cancel_timeouts(&in->in_mn);
iwm_del_task(sc, systq, &sc->ba_task);
iwm_del_task(sc, systq, &sc->htprot_task);
- iwm_del_task(sc, systq, &sc->setrates_task);
}
sc->ns_nstate = nstate;
@@ -7902,7 +7882,6 @@ iwm_stop(struct ifnet *ifp)
/* Cancel scheduled tasks and let any stale tasks finish up. */
task_del(systq, &sc->init_task);
iwm_del_task(sc, sc->sc_nswq, &sc->newstate_task);
- iwm_del_task(sc, systq, &sc->setrates_task);
iwm_del_task(sc, systq, &sc->ba_task);
iwm_del_task(sc, systq, &sc->htprot_task);
KASSERT(sc->task_refs.refs >= 1);
@@ -9330,7 +9309,6 @@ iwm_attach(struct device *parent, struct device *self, void *aux)
timeout_set(&sc->sc_led_blink_to, iwm_led_blink_timeout, sc);
task_set(&sc->init_task, iwm_init_task, sc);
task_set(&sc->newstate_task, iwm_newstate_task, sc);
- task_set(&sc->setrates_task, iwm_setrates_task, sc);
task_set(&sc->ba_task, iwm_ba_task, sc);
task_set(&sc->htprot_task, iwm_htprot_task, sc);
diff --git a/sys/dev/pci/if_iwmvar.h b/sys/dev/pci/if_iwmvar.h
index 1192da0f222..a0a95ec43c3 100644
--- a/sys/dev/pci/if_iwmvar.h
+++ b/sys/dev/pci/if_iwmvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwmvar.h,v 1.52 2020/04/02 12:25:21 stsp Exp $ */
+/* $OpenBSD: if_iwmvar.h,v 1.53 2020/04/02 12:34:27 stsp Exp $ */
/*
* Copyright (c) 2014 genua mbh <info@genua.de>
@@ -374,7 +374,6 @@ struct iwm_softc {
struct task init_task; /* NB: not reference-counted */
struct refcnt task_refs;
struct task newstate_task;
- struct task setrates_task;
enum ieee80211_state ns_nstate;
int ns_arg;