mac80211: Use monitor configuration flags
authorMichael Wu <flamingice@sourmilk.net>
Thu, 31 Jan 2008 18:48:23 +0000 (19:48 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 29 Feb 2008 20:37:02 +0000 (15:37 -0500)
Take advantage of the monitor configuration flags now provided by cfg80211.

Signed-off-by: Michael Wu <flamingice@sourmilk.net>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/mac80211/cfg.c
net/mac80211/ieee80211.c
net/mac80211/ieee80211_i.h
net/mac80211/ieee80211_iface.c

index 706418d477c23bcaa7790e9c0bc7c2a42542e3a9..a083cc78855edc39b51eb011bf1cd6c430a1c4f2 100644 (file)
@@ -38,6 +38,9 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
 {
        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;
@@ -46,7 +49,13 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
        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)
@@ -99,6 +108,10 @@ static int ieee80211_change_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;
 }
 
index cb09931af86a2f7bd90a9cf93f1483d550f4b517..83694fb497342ef4d8b79e465bafc82fa8619ff1 100644 (file)
@@ -67,9 +67,19 @@ static void ieee80211_configure_filter(struct ieee80211_local *local)
                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;
 
@@ -231,13 +241,21 @@ static int ieee80211_open(struct net_device *dev)
        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:
@@ -353,13 +371,21 @@ static int ieee80211_stop(struct net_device *dev)
                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:
index 31fc64c5652c95268287eb0b7e991fc9b54d984c..21d54b27ccc10da34ac3f63d675ac87ba27bcd4a 100644 (file)
@@ -345,6 +345,7 @@ struct ieee80211_sub_if_data {
                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;
@@ -425,6 +426,8 @@ struct ieee80211_local {
        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;
index 27cee580f9f14b441cd7f3f4baf135723577576d..f66f1ddc3fda0d11200548350cd286b48593ff42 100644 (file)
@@ -160,6 +160,8 @@ void ieee80211_if_set_type(struct net_device *dev, int type)
        case IEEE80211_IF_TYPE_MNTR:
                dev->type = ARPHRD_IEEE80211_RADIOTAP;
                dev->hard_start_xmit = ieee80211_monitor_start_xmit;
+               sdata->u.mntr_flags = MONITOR_FLAG_CONTROL |
+                                     MONITOR_FLAG_OTHER_BSS;
                break;
        default:
                printk(KERN_WARNING "%s: %s: Unknown interface type 0x%x",