---- /dev/null 2009-03-26 21:01:06.000000000 +0100
-+++ ./ath/ath_wprobe.c 2009-03-26 20:58:07.000000000 +0100
-@@ -0,0 +1,364 @@
+--- /dev/null
++++ b/ath/ath_wprobe.c
+@@ -0,0 +1,433 @@
+#include <net80211/ieee80211_node.h>
+#include <linux/wprobe.h>
+
+ WP_GLOBAL_PHY_BUSY,
+ WP_GLOBAL_PHY_RX,
+ WP_GLOBAL_PHY_TX,
++ WP_GLOBAL_FRAMES,
++ WP_GLOBAL_PROBEREQ,
+};
+
+static struct wprobe_item ath_wprobe_globals[] = {
+ .type = WPROBE_VAL_U8,
+ .flags = WPROBE_F_KEEPSTAT
+ },
++ [WP_GLOBAL_FRAMES] = {
++ .name = "frames",
++ .type = WPROBE_VAL_U32,
++ },
++ [WP_GLOBAL_PROBEREQ] = {
++ .name = "probereq",
++ .type = WPROBE_VAL_U32,
++ },
+};
+
+static struct wprobe_item ath_wprobe_link[] = {
+ WPROBE_SET(WP_GLOBAL_PHY_BUSY, U8, busy);
+ WPROBE_SET(WP_GLOBAL_PHY_RX, U8, rx);
+ WPROBE_SET(WP_GLOBAL_PHY_TX, U8, tx);
++ WPROBE_SET(WP_GLOBAL_FRAMES, U32, avp->av_rxframes);
++ WPROBE_SET(WP_GLOBAL_PROBEREQ, U32, avp->av_rxprobereq);
++
+phy_skip:
+ WPROBE_SET(WP_GLOBAL_NOISE, S16, noise);
+ WPROBE_FILL_END();
+ if ((rate < 0) || (rate >= rt->rateCount))
+ return -1;
+
-+ return rt->info[rate].rateKbps / 10;
++ return rt->info[rate].rateKbps;
+}
+
+static void
++ath_wprobe_report_rx(struct ieee80211vap *vap, struct ath_rx_status *rs, struct sk_buff *skb)
++{
++ const struct ieee80211_frame *wh = (struct ieee80211_frame *)skb->data;
++ struct wprobe_wlan_hdr hdr;
++ struct ath_vap *avp;
++ int hdrsize;
++
++ if (wprobe_disabled())
++ return;
++
++ avp = ATH_VAP(vap);
++ avp->av_rxframes++;
++ if (wh->i_fc[0] == (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_REQ))
++ avp->av_rxprobereq++;
++
++ memset(&hdr, 0, sizeof(hdr));
++ hdr.len = skb->len;
++ hdr.snr = rs->rs_rssi;
++ hdr.type = WPROBE_PKT_RX;
++ if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
++ hdrsize = sizeof(struct ieee80211_ctlframe_addr2);
++ else
++ hdrsize = ieee80211_hdrsize(skb->data);
++ wprobe_add_frame(&avp->av_wpif, &hdr, skb->data, hdrsize + 0x42);
++}
++
++
++static void
+ath_node_sample_rx(struct ieee80211_node *ni, struct ath_rx_status *rs)
+{
+ struct ath_node *an = ATH_NODE(ni);
+}
+
+static void
-+ath_node_sample_tx(struct ieee80211_node *ni, struct ath_tx_status *ts, int len)
++ath_wprobe_report_tx(struct ieee80211vap *vap, struct ath_tx_status *ts, struct sk_buff *skb)
++{
++ const struct ieee80211_frame *wh = (struct ieee80211_frame *)skb->data;
++ struct wprobe_wlan_hdr hdr;
++ struct ath_vap *avp;
++ int hdrsize;
++
++ if (wprobe_disabled())
++ return;
++
++ avp = ATH_VAP(vap);
++
++ memset(&hdr, 0, sizeof(hdr));
++ hdr.len = skb->len;
++ hdr.snr = ts->ts_rssi;
++ hdr.type = WPROBE_PKT_TX;
++ if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
++ hdrsize = sizeof(struct ieee80211_ctlframe_addr2);
++ else
++ hdrsize = ieee80211_hdrsize(skb->data);
++ wprobe_add_frame(&avp->av_wpif, &hdr, skb->data, hdrsize + 0x42);
++}
++
++
++
++static void
++ath_node_sample_tx(struct ieee80211_node *ni, struct ath_tx_status *ts, struct sk_buff *skb)
+{
+ struct ath_node *an = ATH_NODE(ni);
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct wprobe_value *v = l->val;
+ unsigned long flags;
+ int rate, rexmit_counter;
++ int len = skb->len;
+
+ if (wprobe_disabled() || !an->an_wplink_active || !l->val)
+ return;
+
++ ath_wprobe_report_tx(vap, ts, skb);
+ rate = ath_lookup_rateval(ni, ts->ts_rate);
+
+ spin_lock_irqsave(&l->iface->lock, flags);
+
+ wprobe_remove_iface(dev);
+}
---- a/ath/if_ath.c 2009-03-26 19:54:36.000000000 +0100
-+++ /var/folders/DB/DBZUyxsHGRKP0B3nCU1mmU+++TI/-Tmp-/cocci-output-73937-18abc0-if_ath.c 2009-03-26 21:08:34.000000000 +0100
+--- a/ath/if_ath.c
++++ b/ath/if_ath.c
@@ -400,6 +400,7 @@ static int countrycode = -1;
static int maxvaps = -1;
static int outdoor = -1;
static int beacon_cal = 1;
static const struct ath_hw_detect generic_hw_info = {
-@@ -1525,6 +1526,7 @@ ath_vap_create(struct ieee80211com *ic,
+@@ -1525,6 +1526,7 @@ ath_vap_create(struct ieee80211com *ic,
ath_hal_intrset(ah, sc->sc_imask);
}
return vap;
}
-@@ -1605,6 +1607,7 @@ ath_vap_delete(struct ieee80211vap *vap)
+@@ -1606,6 +1608,7 @@ ath_vap_delete(struct ieee80211vap *vap)
decrease = 0;
ieee80211_vap_detach(vap);
/* NB: memory is reclaimed through dev->destructor callback */
if (decrease)
sc->sc_nvaps--;
-@@ -5931,6 +5934,7 @@ ath_node_cleanup(struct ieee80211_node *
+@@ -5940,6 +5943,7 @@ ath_node_cleanup(struct ieee80211_node *
/* Clean up node-specific rate things - this currently appears to
* always be a no-op */
sc->sc_rc->ops->node_cleanup(sc, ATH_NODE(ni));
ATH_NODE_UAPSD_LOCK_IRQ(an);
#ifdef IEEE80211_DEBUG_REFCNT
-@@ -7001,6 +7005,7 @@ drop_micfail:
+@@ -7010,6 +7014,8 @@ drop_micfail:
goto lookup_slowpath;
}
ATH_RSSI_LPF(ATH_NODE(ni)->an_avgrssi, rs->rs_rssi);
+ ath_node_sample_rx(ni, rs);
++ ath_wprobe_report_rx(ni->ni_vap, rs, skb);
type = ieee80211_input(ni->ni_vap, ni, skb, rs->rs_rssi, bf->bf_tsf);
ieee80211_unref_node(&ni);
} else {
-@@ -7020,6 +7025,7 @@ lookup_slowpath:
+@@ -7024,15 +7030,21 @@ lookup_slowpath:
+ else
+ vap = ieee80211_find_rxvap(ic, wh->i_addr1);
+
+- if (vap)
++ if (vap) {
++ ath_wprobe_report_rx(vap, rs, skb);
+ ni = ieee80211_find_rxnode(ic, vap, wh);
+- else
++ } else {
++ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
++ ath_wprobe_report_rx(vap, rs, skb);
++ }
+ ni = NULL;
++ }
+
+ if (ni != NULL) {
ieee80211_keyix_t keyix;
ATH_RSSI_LPF(ATH_NODE(ni)->an_avgrssi, rs->rs_rssi);
type = ieee80211_input(vap, ni, skb, rs->rs_rssi, bf->bf_tsf);
/*
* If the station has a key cache slot assigned
-@@ -8599,6 +8605,7 @@ ath_tx_processq(struct ath_softc *sc, st
+@@ -8612,6 +8624,7 @@ ath_tx_processq(struct ath_softc *sc, st
sc->sc_stats.ast_tx_rssi = ts->ts_rssi;
ATH_RSSI_LPF(an->an_halstats.ns_avgtxrssi,
ts->ts_rssi);
-+ ath_node_sample_tx(&an->an_node, ts, bf->bf_skb->len);
++ ath_node_sample_tx(&an->an_node, ts, bf->bf_skb);
if (bf->bf_skb->priority == WME_AC_VO ||
bf->bf_skb->priority == WME_AC_VI)
ni->ni_ic->ic_wme.wme_hipri_traffic++;
-@@ -10090,6 +10097,7 @@ ath_newassoc(struct ieee80211_node *ni,
+@@ -10111,6 +10124,7 @@ ath_newassoc(struct ieee80211_node *ni,
struct ath_softc *sc = ic->ic_dev->priv;
sc->sc_rc->ops->newassoc(sc, ATH_NODE(ni), isnew);
/* are we supporting compression? */
if (!(vap->iv_ath_cap & ni->ni_ath_flags & IEEE80211_NODE_COMP))
---- a/ath/if_athvar.h 2009-03-26 19:54:35.000000000 +0100
-+++ /var/folders/DB/DBZUyxsHGRKP0B3nCU1mmU+++TI/-Tmp-/cocci-output-73937-80429d-if_athvar.h 2009-03-26 21:08:42.000000000 +0100
+--- a/ath/if_athvar.h
++++ b/ath/if_athvar.h
@@ -46,6 +46,7 @@
#include "ah_desc.h"
#include "ah_os.h"
u_int16_t an_decomp_index; /* decompression mask index */
u_int32_t an_avgrssi; /* average rssi over all rx frames */
u_int8_t an_prevdatarix; /* rate ix of last data frame */
-@@ -521,6 +525,7 @@ struct ath_vap {
+@@ -521,6 +525,9 @@ struct ath_vap {
#else
unsigned int av_beacon_alloc;
#endif
+ struct wprobe_iface av_wpif;
++ u32 av_rxframes;
++ u32 av_rxprobereq;
};
#define ATH_VAP(_v) ((struct ath_vap *)(_v))