tx.o \
        key.o \
        util.o \
+       event.o \
        $(mac80211-objs-y)
 
--- /dev/null
+/*
+ * Copyright 2007      Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * mac80211 - events
+ */
+
+#include <linux/netdevice.h>
+#include <net/iw_handler.h>
+#include "ieee80211_i.h"
+
+/*
+ * indicate a failed Michael MIC to userspace; the passed packet
+ * (in the variable hdr) must be long enough to extract the TKIP
+ * fields like TSC
+ */
+void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx,
+                                    struct ieee80211_hdr *hdr)
+{
+       union iwreq_data wrqu;
+       char *buf = kmalloc(128, GFP_ATOMIC);
+
+       if (buf) {
+               /* TODO: needed parameters: count, key type, TSC */
+               sprintf(buf, "MLME-MICHAELMICFAILURE.indication("
+                       "keyid=%d %scast addr=" MAC_FMT ")",
+                       keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
+                       MAC_ARG(hdr->addr2));
+               memset(&wrqu, 0, sizeof(wrqu));
+               wrqu.data.length = strlen(buf);
+               wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
+               kfree(buf);
+       }
+
+       /*
+        * TODO: re-add support for sending MIC failure indication
+        * with all info via nl80211
+        */
+}
 
 int ieee80211_is_eapol(const struct sk_buff *skb);
 int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
                             int rate, int erp, int short_preamble);
+void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx,
+                                    struct ieee80211_hdr *hdr);
 
 #endif /* IEEE80211_I_H */
 
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
-#include <net/iw_handler.h>
 #include <net/mac80211.h>
 #include <net/ieee80211_radiotap.h>
 
        }
 
        if ((rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) &&
-           rx->sdata->type == IEEE80211_IF_TYPE_AP) {
-               keyidx = ieee80211_wep_get_keyidx(rx->skb);
+           rx->sdata->type == IEEE80211_IF_TYPE_AP && keyidx) {
                /* AP with Pairwise keys support should never receive Michael
                 * MIC errors for non-zero keyidx because these are reserved
                 * for group keys and only the AP is sending real multicast
                 * frames in BSS. */
-               if (keyidx) {
-                       if (net_ratelimit())
-                               printk(KERN_DEBUG "%s: ignored Michael MIC "
-                                      "error for a frame with non-zero keyidx"
-                                      " (%d) (src " MAC_FMT ")\n", dev->name,
-                                      keyidx, MAC_ARG(hdr->addr2));
-                       goto ignore;
-               }
+               if (net_ratelimit())
+                       printk(KERN_DEBUG "%s: ignored Michael MIC error for "
+                              "a frame with non-zero keyidx (%d)"
+                              " (src " MAC_FMT ")\n", dev->name, keyidx,
+                              MAC_ARG(hdr->addr2));
+               goto ignore;
        }
 
        if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA &&
                goto ignore;
        }
 
-       do {
-               union iwreq_data wrqu;
-               char *buf = kmalloc(128, GFP_ATOMIC);
-               if (!buf)
-                       break;
-
-               /* TODO: needed parameters: count, key type, TSC */
-               sprintf(buf, "MLME-MICHAELMICFAILURE.indication("
-                       "keyid=%d %scast addr=" MAC_FMT ")",
-                       keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
-                       MAC_ARG(hdr->addr2));
-               memset(&wrqu, 0, sizeof(wrqu));
-               wrqu.data.length = strlen(buf);
-               wireless_send_event(rx->dev, IWEVCUSTOM, &wrqu, buf);
-               kfree(buf);
-       } while (0);
-
        /* TODO: consider verifying the MIC error report with software
         * implementation if we get too many spurious reports from the
         * hardware. */
-       if (!rx->local->apdev)
-               goto ignore;
-       ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status,
-                         ieee80211_msg_michael_mic_failure);
-       return;
 
+       mac80211_ev_michael_mic_failure(rx->dev, keyidx, hdr);
  ignore:
        dev_kfree_skb(rx->skb);
        rx->skb = NULL;
 
 #include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/compiler.h>
-#include <net/iw_handler.h>
-
 #include <net/mac80211.h>
-#include "ieee80211_common.h"
+
 #include "ieee80211_i.h"
 #include "michael.h"
 #include "tkip.h"
                printk(KERN_DEBUG "%s: invalid Michael MIC in data frame from "
                       MAC_FMT "\n", rx->dev->name, MAC_ARG(sa));
 
-               do {
-                       struct ieee80211_hdr *hdr;
-                       union iwreq_data wrqu;
-                       char *buf = kmalloc(128, GFP_ATOMIC);
-                       if (!buf)
-                               break;
-
-                       /* TODO: needed parameters: count, key type, TSC */
-                       hdr = (struct ieee80211_hdr *) skb->data;
-                       sprintf(buf, "MLME-MICHAELMICFAILURE.indication("
-                               "keyid=%d %scast addr=" MAC_FMT ")",
-                               rx->key->keyidx,
-                               hdr->addr1[0] & 0x01 ? "broad" : "uni",
-                               MAC_ARG(hdr->addr2));
-                       memset(&wrqu, 0, sizeof(wrqu));
-                       wrqu.data.length = strlen(buf);
-                       wireless_send_event(rx->dev, IWEVCUSTOM, &wrqu, buf);
-                       kfree(buf);
-               } while (0);
-
-               if (!rx->local->apdev)
-                       return TXRX_DROP;
-
-               ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status,
-                                 ieee80211_msg_michael_mic_failure);
-
-               return TXRX_QUEUED;
+               mac80211_ev_michael_mic_failure(rx->dev, rx->key->keyidx,
+                                               (void *) skb->data);
+               return TXRX_DROP;
        }
 
  remove_mic: