u8 *pos;
        bool reassoc;
        struct cfg80211_bss *bss;
+       struct ieee80211_event event = {
+               .type = MLME_EVENT,
+               .u.mlme.data = ASSOC_EVENT,
+       };
 
        sdata_assert_lock(sdata);
 
                sdata_info(sdata, "%pM denied association (code=%d)\n",
                           mgmt->sa, status_code);
                ieee80211_destroy_assoc_data(sdata, false);
+               event.u.mlme.status = MLME_DENIED;
+               event.u.mlme.reason = status_code;
+               drv_event_callback(sdata->local, sdata, &event);
        } else {
                if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) {
                        /* oops -- internal error -- send timeout for now */
                        cfg80211_assoc_timeout(sdata->dev, bss);
                        return;
                }
+               event.u.mlme.status = MLME_SUCCESS;
+               drv_event_callback(sdata->local, sdata, &event);
                sdata_info(sdata, "associated\n");
 
                /*
                if ((ifmgd->assoc_data->need_beacon && !ifmgd->have_beacon) ||
                    ieee80211_do_assoc(sdata)) {
                        struct cfg80211_bss *bss = ifmgd->assoc_data->bss;
+                       struct ieee80211_event event = {
+                               .type = MLME_EVENT,
+                               .u.mlme.data = ASSOC_EVENT,
+                               .u.mlme.status = MLME_TIMEOUT,
+                       };
 
                        ieee80211_destroy_assoc_data(sdata, false);
                        cfg80211_assoc_timeout(sdata->dev, bss);
+                       drv_event_callback(sdata->local, sdata, &event);
                }
        } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started)
                run_again(sdata, ifmgd->assoc_data->timeout);