mac80211: don't call bss_info_changed on p2p-device/monitor
authorJohannes Berg <johannes.berg@intel.com>
Wed, 13 Feb 2013 12:50:51 +0000 (13:50 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 15 Feb 2013 08:41:11 +0000 (09:41 +0100)
Since the idle decision rework, mac80211 started calling
bss_info_changed() for the driver's monitor interface,
which causes a crash for iwlwifi, but drivers generally
don't expect this to happen. Therefore, avoid it.

While at it, also prevent calling it in such cases and
only print a warning. For the P2P Device interface the
idle will no longer be called (no channel context), so
also prevent that and warn on it.

Reported-by: Chaitanya <chaitanya.mgit@gmail.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/chan.c
net/mac80211/driver-ops.h

index 2e6faeda22ad3447ef613686a90d930e67dcdf1e..d91ccfcaa6d1c2c8eebabdcd13c1babfa6a6ce68 100644 (file)
@@ -137,7 +137,10 @@ static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
 
        ieee80211_recalc_txpower(sdata);
        sdata->vif.bss_conf.idle = false;
-       ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE);
+
+       if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
+           sdata->vif.type != NL80211_IFTYPE_MONITOR)
+               ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE);
 
        return 0;
 }
@@ -186,7 +189,10 @@ static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
        rcu_assign_pointer(sdata->vif.chanctx_conf, NULL);
 
        sdata->vif.bss_conf.idle = true;
-       ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE);
+
+       if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
+           sdata->vif.type != NL80211_IFTYPE_MONITOR)
+               ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE);
 
        drv_unassign_vif_chanctx(local, sdata, ctx);
 
index 2b08b9982d0650096d92369500c5deb6b5352147..ee56d0779d8bdea4b5374ce5d0749cbbe1a88937 100644 (file)
@@ -207,13 +207,16 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
 {
        might_sleep();
 
-       WARN_ON_ONCE(changed & (BSS_CHANGED_BEACON |
-                               BSS_CHANGED_BEACON_ENABLED) &&
-                    sdata->vif.type != NL80211_IFTYPE_AP &&
-                    sdata->vif.type != NL80211_IFTYPE_ADHOC &&
-                    sdata->vif.type != NL80211_IFTYPE_MESH_POINT);
-       WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE &&
-                    changed & ~BSS_CHANGED_IDLE);
+       if (WARN_ON_ONCE(changed & (BSS_CHANGED_BEACON |
+                                   BSS_CHANGED_BEACON_ENABLED) &&
+                        sdata->vif.type != NL80211_IFTYPE_AP &&
+                        sdata->vif.type != NL80211_IFTYPE_ADHOC &&
+                        sdata->vif.type != NL80211_IFTYPE_MESH_POINT))
+               return;
+
+       if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE ||
+                        sdata->vif.type == NL80211_IFTYPE_MONITOR))
+               return;
 
        check_sdata_in_driver(sdata);