{
        struct ieee80211_local *local = wiphy_priv(wiphy);
        enum ieee80211_if_types itype;
+       struct net_device *dev;
+       struct ieee80211_sub_if_data *sdata;
+       int err;
 
        if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED))
                return -ENODEV;
        if (itype == IEEE80211_IF_TYPE_INVALID)
                return -EINVAL;
 
-       return ieee80211_if_add(local->mdev, name, NULL, itype);
+       err = ieee80211_if_add(local->mdev, name, &dev, itype);
+       if (err || itype != IEEE80211_IF_TYPE_MNTR || !flags)
+               return err;
+
+       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       sdata->u.mntr_flags = *flags;
+       return 0;
 }
 
 static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex)
        ieee80211_if_reinit(dev);
        ieee80211_if_set_type(dev, itype);
 
+       if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR || !flags)
+               return 0;
+
+       sdata->u.mntr_flags = *flags;
        return 0;
 }
 
 
                new_flags |= FIF_ALLMULTI;
 
        if (local->monitors)
-               new_flags |= FIF_CONTROL |
-                            FIF_OTHER_BSS |
-                            FIF_BCN_PRBRESP_PROMISC;
+               new_flags |= FIF_BCN_PRBRESP_PROMISC;
+
+       if (local->fif_fcsfail)
+               new_flags |= FIF_FCSFAIL;
+
+       if (local->fif_plcpfail)
+               new_flags |= FIF_PLCPFAIL;
+
+       if (local->fif_control)
+               new_flags |= FIF_CONTROL;
+
+       if (local->fif_other_bss)
+               new_flags |= FIF_OTHER_BSS;
 
        changed_flags = local->filter_flags ^ new_flags;
 
        case IEEE80211_IF_TYPE_MNTR:
                /* must be before the call to ieee80211_configure_filter */
                local->monitors++;
-               if (local->monitors == 1) {
-                       netif_tx_lock_bh(local->mdev);
-                       ieee80211_configure_filter(local);
-                       netif_tx_unlock_bh(local->mdev);
-
+               if (local->monitors == 1)
                        local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP;
-               }
+
+               if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
+                       local->fif_fcsfail++;
+               if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
+                       local->fif_plcpfail++;
+               if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL)
+                       local->fif_control++;
+               if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
+                       local->fif_other_bss++;
+
+               netif_tx_lock_bh(local->mdev);
+               ieee80211_configure_filter(local);
+               netif_tx_unlock_bh(local->mdev);
                break;
        case IEEE80211_IF_TYPE_STA:
        case IEEE80211_IF_TYPE_IBSS:
                break;
        case IEEE80211_IF_TYPE_MNTR:
                local->monitors--;
-               if (local->monitors == 0) {
-                       netif_tx_lock_bh(local->mdev);
-                       ieee80211_configure_filter(local);
-                       netif_tx_unlock_bh(local->mdev);
-
+               if (local->monitors == 0)
                        local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP;
-               }
+
+               if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
+                       local->fif_fcsfail--;
+               if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
+                       local->fif_plcpfail--;
+               if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL)
+                       local->fif_control--;
+               if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
+                       local->fif_other_bss--;
+
+               netif_tx_lock_bh(local->mdev);
+               ieee80211_configure_filter(local);
+               netif_tx_unlock_bh(local->mdev);
                break;
        case IEEE80211_IF_TYPE_STA:
        case IEEE80211_IF_TYPE_IBSS:
 
                struct ieee80211_if_wds wds;
                struct ieee80211_if_vlan vlan;
                struct ieee80211_if_sta sta;
+               u32 mntr_flags;
        } u;
        int channel_use;
        int channel_use_raw;
        struct net_device *mdev; /* wmaster# - "master" 802.11 device */
        int open_count;
        int monitors;
+       /* number of interfaces with corresponding FIF_ flags */
+       int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss;
        unsigned int filter_flags; /* FIF_* */
        struct iw_statistics wstats;
        u8 wstats_flags;