summaryrefslogtreecommitdiffstats
path: root/sys/net80211
diff options
context:
space:
mode:
authoravos <avos@FreeBSD.org>2015-10-27 20:40:57 +0000
committeravos <avos@FreeBSD.org>2015-10-27 20:40:57 +0000
commitad82a0b990f764301d25b8a092aa21a3a9e42b1e (patch)
treeee50096d282dcfd4216425f081964abe4bc62da3 /sys/net80211
parentb918134e7594cf56b89fb9fa063e34b6f9086fae (diff)
downloadFreeBSD-src-ad82a0b990f764301d25b8a092aa21a3a9e42b1e.zip
FreeBSD-src-ad82a0b990f764301d25b8a092aa21a3a9e42b1e.tar.gz
net80211: add ieee80211_restart_all() call.
This call may be used when device cannot continue to operate normally (e.g., throws firmware error, watchdog timer expires) and need to be restarted. Approved by: adrian (mentor) Differential Revision: https://reviews.freebsd.org/D3998
Diffstat (limited to 'sys/net80211')
-rw-r--r--sys/net80211/ieee80211.c2
-rw-r--r--sys/net80211/ieee80211_proto.c24
-rw-r--r--sys/net80211/ieee80211_proto.h1
-rw-r--r--sys/net80211/ieee80211_var.h1
4 files changed, 28 insertions, 0 deletions
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
index 39e03ea..ca27cb1 100644
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -356,6 +356,8 @@ ieee80211_ifdetach(struct ieee80211com *ic)
LIST_REMOVE(ic, ic_next);
mtx_unlock(&ic_list_mtx);
+ taskqueue_drain(taskqueue_thread, &ic->ic_restart_task);
+
/*
* The VAP is responsible for setting and clearing
* the VIMAGE context.
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c
index 52e92ba..408bf93 100644
--- a/sys/net80211/ieee80211_proto.c
+++ b/sys/net80211/ieee80211_proto.c
@@ -108,6 +108,7 @@ static void update_promisc(void *, int);
static void update_channel(void *, int);
static void update_chw(void *, int);
static void update_wme(void *, int);
+static void restart_vaps(void *, int);
static void ieee80211_newstate_cb(void *, int);
static int
@@ -146,6 +147,7 @@ ieee80211_proto_attach(struct ieee80211com *ic)
TASK_INIT(&ic->ic_bmiss_task, 0, beacon_miss, ic);
TASK_INIT(&ic->ic_chw_task, 0, update_chw, ic);
TASK_INIT(&ic->ic_wme_task, 0, update_wme, ic);
+ TASK_INIT(&ic->ic_restart_task, 0, restart_vaps, ic);
ic->ic_wme.wme_hipri_switch_hysteresis =
AGGRESSIVE_MODE_SWITCH_HYSTERESIS;
@@ -1212,6 +1214,15 @@ update_wme(void *arg, int npending)
ic->ic_wme.wme_update(ic);
}
+static void
+restart_vaps(void *arg, int npending)
+{
+ struct ieee80211com *ic = arg;
+
+ ieee80211_suspend_all(ic);
+ ieee80211_resume_all(ic);
+}
+
/*
* Block until the parent is in a known state. This is
* used after any operations that dispatch a task (e.g.
@@ -1486,6 +1497,19 @@ ieee80211_resume_all(struct ieee80211com *ic)
IEEE80211_UNLOCK(ic);
}
+/*
+ * Restart all vap's running on a device.
+ */
+void
+ieee80211_restart_all(struct ieee80211com *ic)
+{
+ /*
+ * NB: do not use ieee80211_runtask here, we will
+ * block & drain net80211 taskqueue.
+ */
+ taskqueue_enqueue(taskqueue_thread, &ic->ic_restart_task);
+}
+
void
ieee80211_beacon_miss(struct ieee80211com *ic)
{
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index 38bd3d6..88633e7 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -307,6 +307,7 @@ void ieee80211_stop(struct ieee80211vap *);
void ieee80211_stop_all(struct ieee80211com *);
void ieee80211_suspend_all(struct ieee80211com *);
void ieee80211_resume_all(struct ieee80211com *);
+void ieee80211_restart_all(struct ieee80211com *);
void ieee80211_dturbo_switch(struct ieee80211vap *, int newflags);
void ieee80211_swbmiss(void *arg);
void ieee80211_beacon_miss(struct ieee80211com *);
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index 5c5b1c9..cd27ead 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -134,6 +134,7 @@ struct ieee80211com {
struct task ic_bmiss_task; /* deferred beacon miss hndlr */
struct task ic_chw_task; /* deferred HT CHW update */
struct task ic_wme_task; /* deferred WME update */
+ struct task ic_restart_task; /* deferred device restart */
counter_u64_t ic_ierrors; /* input errors */
counter_u64_t ic_oerrors; /* output errors */
OpenPOWER on IntegriCloud