summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/net80211/ieee80211_freebsd.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/net80211/ieee80211_freebsd.c')
-rw-r--r--freebsd/sys/net80211/ieee80211_freebsd.c53
1 files changed, 48 insertions, 5 deletions
diff --git a/freebsd/sys/net80211/ieee80211_freebsd.c b/freebsd/sys/net80211/ieee80211_freebsd.c
index 00430f77..f8d5d0f3 100644
--- a/freebsd/sys/net80211/ieee80211_freebsd.c
+++ b/freebsd/sys/net80211/ieee80211_freebsd.c
@@ -70,8 +70,6 @@ SYSCTL_INT(_net_wlan, OID_AUTO, debug, CTLFLAG_RW, &ieee80211_debug,
0, "debugging printfs");
#endif
-static MALLOC_DEFINE(M_80211_COM, "80211com", "802.11 com state");
-
static const char wlanname[] = "wlan";
static struct if_clone *wlan_cloner;
@@ -138,13 +136,12 @@ int
ieee80211_sysctl_msecs_ticks(SYSCTL_HANDLER_ARGS)
{
int msecs = ticks_to_msecs(*(int *)arg1);
- int error, t;
+ int error;
error = sysctl_handle_int(oidp, &msecs, 0, req);
if (error || !req->newptr)
return error;
- t = msecs_to_ticks(msecs);
- *(int *)arg1 = (t < 1) ? 1 : t;
+ *(int *)arg1 = msecs_to_ticks(msecs);
return 0;
}
@@ -309,6 +306,52 @@ ieee80211_sysctl_vdetach(struct ieee80211vap *vap)
}
}
+#define MS(_v, _f) (((_v) & _f##_M) >> _f##_S)
+int
+ieee80211_com_vincref(struct ieee80211vap *vap)
+{
+ uint32_t ostate;
+
+ ostate = atomic_fetchadd_32(&vap->iv_com_state, IEEE80211_COM_REF_ADD);
+
+ if (ostate & IEEE80211_COM_DETACHED) {
+ atomic_subtract_32(&vap->iv_com_state, IEEE80211_COM_REF_ADD);
+ return (ENETDOWN);
+ }
+
+ if (MS(ostate, IEEE80211_COM_REF) == IEEE80211_COM_REF_MAX) {
+ atomic_subtract_32(&vap->iv_com_state, IEEE80211_COM_REF_ADD);
+ return (EOVERFLOW);
+ }
+
+ return (0);
+}
+
+void
+ieee80211_com_vdecref(struct ieee80211vap *vap)
+{
+ uint32_t ostate;
+
+ ostate = atomic_fetchadd_32(&vap->iv_com_state, -IEEE80211_COM_REF_ADD);
+
+ KASSERT(MS(ostate, IEEE80211_COM_REF) != 0,
+ ("com reference counter underflow"));
+
+ (void) ostate;
+}
+
+void
+ieee80211_com_vdetach(struct ieee80211vap *vap)
+{
+ int sleep_time;
+
+ sleep_time = msecs_to_ticks(250);
+ atomic_set_32(&vap->iv_com_state, IEEE80211_COM_DETACHED);
+ while (MS(atomic_load_32(&vap->iv_com_state), IEEE80211_COM_REF) != 0)
+ pause("comref", sleep_time);
+}
+#undef MS
+
int
ieee80211_node_dectestref(struct ieee80211_node *ni)
{