summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/net80211/ieee80211_input.c101
1 files changed, 69 insertions, 32 deletions
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index bdb667601c3..62e220d5418 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_input.c,v 1.119 2011/04/05 11:48:28 blambert Exp $ */
+/* $OpenBSD: ieee80211_input.c,v 1.120 2012/07/13 11:25:04 stsp Exp $ */
/*-
* Copyright (c) 2001 Atsushi Onoe
@@ -42,6 +42,7 @@
#include <sys/errno.h>
#include <sys/proc.h>
#include <sys/sysctl.h>
+#include <sys/workq.h>
#include <net/if.h>
#include <net/if_dl.h>
@@ -131,6 +132,9 @@ void ieee80211_recv_bar(struct ieee80211com *, struct mbuf *,
void ieee80211_bar_tid(struct ieee80211com *, struct ieee80211_node *,
u_int8_t, u_int16_t);
#endif
+void ieee80211_input_print(struct ieee80211com *, struct ifnet *,
+ struct ieee80211_frame *, struct ieee80211_rxinfo *);
+void ieee80211_input_print_task(void *, void *);
/*
* Retrieve the length in bytes of an 802.11 header.
@@ -152,6 +156,68 @@ ieee80211_get_hdrlen(const struct ieee80211_frame *wh)
return size;
}
+/*
+ * Work queue task that prints a received frame. Avoids printf() from
+ * interrupt context at IPL_NET making slow machines unusable when many
+ * frames are received and the interface is put in debug mode.
+ */
+void
+ieee80211_input_print_task(void *arg1, void *arg2)
+{
+ char *msg = arg1;
+
+ printf("%s", msg);
+ free(msg, M_DEVBUF);
+
+}
+
+void
+ieee80211_input_print(struct ieee80211com *ic, struct ifnet *ifp,
+ struct ieee80211_frame *wh, struct ieee80211_rxinfo *rxi)
+{
+ int doprint, error;
+ char *msg;
+ u_int8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+
+ /* avoid printing too many frames */
+ doprint = 0;
+ switch (subtype) {
+ case IEEE80211_FC0_SUBTYPE_BEACON:
+ if (ic->ic_state == IEEE80211_S_SCAN)
+ doprint = 1;
+ break;
+#ifndef IEEE80211_STA_ONLY
+ case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
+ if (ic->ic_opmode == IEEE80211_M_IBSS)
+ doprint = 1;
+ break;
+#endif
+ default:
+ doprint = 1;
+ break;
+ }
+#ifdef IEEE80211_DEBUG
+ doprint += ieee80211_debug;
+#endif
+ if (!doprint)
+ return;
+
+ msg = malloc(1024, M_DEVBUF, M_NOWAIT);
+ if (msg == NULL)
+ return;
+
+ snprintf(msg, 1024, "%s: received %s from %s rssi %d mode %s\n",
+ ifp->if_xname,
+ ieee80211_mgt_subtype_name[subtype >> IEEE80211_FC0_SUBTYPE_SHIFT],
+ ether_sprintf(wh->i_addr2), rxi->rxi_rssi,
+ ieee80211_phymode_name[ieee80211_chan2mode(
+ ic, ic->ic_bss->ni_chan)]);
+
+ error = workq_add_task(NULL, 0, ieee80211_input_print_task, msg, NULL);
+ if (error)
+ free(msg, M_DEVBUF);
+}
+
/*
* Process a received frame. The node associated with the sender
* should be supplied. If nothing was found in the node table then
@@ -467,37 +533,8 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
goto out;
}
- if (ifp->if_flags & IFF_DEBUG) {
- /* avoid to print too many frames */
- int doprint = 0;
-
- switch (subtype) {
- case IEEE80211_FC0_SUBTYPE_BEACON:
- if (ic->ic_state == IEEE80211_S_SCAN)
- doprint = 1;
- break;
-#ifndef IEEE80211_STA_ONLY
- case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
- if (ic->ic_opmode == IEEE80211_M_IBSS)
- doprint = 1;
- break;
-#endif
- default:
- doprint = 1;
- break;
- }
-#ifdef IEEE80211_DEBUG
- doprint += ieee80211_debug;
-#endif
- if (doprint)
- printf("%s: received %s from %s rssi %d mode %s\n",
- ifp->if_xname,
- ieee80211_mgt_subtype_name[subtype
- >> IEEE80211_FC0_SUBTYPE_SHIFT],
- ether_sprintf(wh->i_addr2), rxi->rxi_rssi,
- ieee80211_phymode_name[ieee80211_chan2mode(ic,
- ic->ic_bss->ni_chan)]);
- }
+ if (ifp->if_flags & IFF_DEBUG)
+ ieee80211_input_print(ic, ifp, wh, rxi);
#if NBPFILTER > 0
if (ic->ic_rawbpf)
bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_IN);