mac80211: add vif debugfs driver callbacks
authorAlexander Bondar <alexander.bondar@intel.com>
Sat, 22 Dec 2012 08:43:33 +0000 (10:43 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 11 Feb 2013 17:44:58 +0000 (18:44 +0100)
Add debugfs driver callbacks so drivers can add
debugfs entries for interfaces. Note that they
_must_ remove the entries again as add/remove in
the driver doesn't correspond to add/remove in
debugfs; the former is up/down while the latter
is netdev create/destroy.

Signed-off-by: Alexander Bondar <alexander.bondar@intel.com>
Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/mac80211.h
net/mac80211/driver-ops.h
net/mac80211/iface.c

index 7da11211825d32625b637a419acc8fe933d97196..46e08ba92b970d289bfc5e85d817bcdd37961d3e 100644 (file)
@@ -2167,6 +2167,18 @@ enum ieee80211_rate_control_changed {
  *     MAC address of the device going away.
  *     Hence, this callback must be implemented. It can sleep.
  *
+ * @add_interface_debugfs: Drivers can use this callback to add debugfs files
+ *     when a vif is added to mac80211. This callback and
+ *     @remove_interface_debugfs should be within a CONFIG_MAC80211_DEBUGFS
+ *     conditional. @remove_interface_debugfs must be provided for cleanup.
+ *     This callback can sleep.
+ *
+ * @remove_interface_debugfs: Remove the debugfs files which were added using
+ *     @add_interface_debugfs. This callback must remove all debugfs entries
+ *     that were added because mac80211 only removes interface debugfs when the
+ *     interface is destroyed, not when it is removed from the driver.
+ *     This callback can sleep.
+ *
  * @config: Handler for configuration requests. IEEE 802.11 code calls this
  *     function to change hardware configuration, e.g., channel.
  *     This function should never fail but returns a negative error code
@@ -2580,6 +2592,12 @@ struct ieee80211_ops {
                                   struct ieee80211_vif *vif,
                                   struct ieee80211_sta *sta,
                                   struct dentry *dir);
+       void (*add_interface_debugfs)(struct ieee80211_hw *hw,
+                                     struct ieee80211_vif *vif,
+                                     struct dentry *dir);
+       void (*remove_interface_debugfs)(struct ieee80211_hw *hw,
+                                        struct ieee80211_vif *vif,
+                                        struct dentry *dir);
 #endif
        void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                        enum sta_notify_cmd, struct ieee80211_sta *sta);
index 434b3c4f31b568a1fc3220764412743da0bcc130..2b08b9982d0650096d92369500c5deb6b5352147 100644 (file)
@@ -528,6 +528,43 @@ static inline void drv_sta_remove_debugfs(struct ieee80211_local *local,
                local->ops->sta_remove_debugfs(&local->hw, &sdata->vif,
                                               sta, dir);
 }
+
+static inline
+void drv_add_interface_debugfs(struct ieee80211_local *local,
+                              struct ieee80211_sub_if_data *sdata)
+{
+       might_sleep();
+
+       check_sdata_in_driver(sdata);
+
+       if (!local->ops->add_interface_debugfs)
+               return;
+
+       local->ops->add_interface_debugfs(&local->hw, &sdata->vif,
+                                         sdata->debugfs.dir);
+}
+
+static inline
+void drv_remove_interface_debugfs(struct ieee80211_local *local,
+                                 struct ieee80211_sub_if_data *sdata)
+{
+       might_sleep();
+
+       check_sdata_in_driver(sdata);
+
+       if (!local->ops->remove_interface_debugfs)
+               return;
+
+       local->ops->remove_interface_debugfs(&local->hw, &sdata->vif,
+                                            sdata->debugfs.dir);
+}
+#else
+static inline
+void drv_add_interface_debugfs(struct ieee80211_local *local,
+                              struct ieee80211_sub_if_data *sdata) {}
+static inline
+void drv_remove_interface_debugfs(struct ieee80211_local *local,
+                                 struct ieee80211_sub_if_data *sdata) {}
 #endif
 
 static inline __must_check
index 0a36dc6346bb707d5fdf708e1ccc0ea4af9305f2..deb78e864af6a48ad4aadd27b47099a6ca9a3b7a 100644 (file)
@@ -621,6 +621,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
                                goto err_del_interface;
                }
 
+               drv_add_interface_debugfs(local, sdata);
+
                if (sdata->vif.type == NL80211_IFTYPE_AP) {
                        local->fif_pspoll++;
                        local->fif_probe_req++;
@@ -882,6 +884,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
                 */
                ieee80211_free_keys(sdata);
 
+               drv_remove_interface_debugfs(local, sdata);
+
                if (going_down)
                        drv_remove_interface(local, sdata);
        }