#include "debugfs_netdev.h"
 #include "driver-ops.h"
 
-static ssize_t ieee80211_if_read(
-       void *data,
+static ssize_t ieee80211_if_read_sdata(
+       struct ieee80211_sub_if_data *sdata,
        char __user *userbuf,
        size_t count, loff_t *ppos,
-       ssize_t (*format)(const void *, char *, int))
+       ssize_t (*format)(const struct ieee80211_sub_if_data *sdata, char *, int))
 {
        char buf[200];
        ssize_t ret = -EINVAL;
 
-       read_lock(&dev_base_lock);
-       ret = (*format)(data, buf, sizeof(buf));
-       read_unlock(&dev_base_lock);
+       wiphy_lock(sdata->local->hw.wiphy);
+       ret = (*format)(sdata, buf, sizeof(buf));
+       wiphy_unlock(sdata->local->hw.wiphy);
 
        if (ret >= 0)
                ret = simple_read_from_buffer(userbuf, count, ppos, buf, ret);
        return ret;
 }
 
-static ssize_t ieee80211_if_write(
-       void *data,
+static ssize_t ieee80211_if_write_sdata(
+       struct ieee80211_sub_if_data *sdata,
        const char __user *userbuf,
        size_t count, loff_t *ppos,
-       ssize_t (*write)(void *, const char *, int))
+       ssize_t (*write)(struct ieee80211_sub_if_data *sdata, const char *, int))
 {
        char buf[64];
        ssize_t ret;
                return -EFAULT;
        buf[count] = '\0';
 
-       rtnl_lock();
-       ret = (*write)(data, buf, count);
-       rtnl_unlock();
+       wiphy_lock(sdata->local->hw.wiphy);
+       ret = (*write)(sdata, buf, count);
+       wiphy_unlock(sdata->local->hw.wiphy);
+
+       return ret;
+}
+
+static ssize_t ieee80211_if_read_link(
+       struct ieee80211_link_data *link,
+       char __user *userbuf,
+       size_t count, loff_t *ppos,
+       ssize_t (*format)(const struct ieee80211_link_data *link, char *, int))
+{
+       char buf[200];
+       ssize_t ret = -EINVAL;
+
+       wiphy_lock(link->sdata->local->hw.wiphy);
+       ret = (*format)(link, buf, sizeof(buf));
+       wiphy_unlock(link->sdata->local->hw.wiphy);
+
+       if (ret >= 0)
+               ret = simple_read_from_buffer(userbuf, count, ppos, buf, ret);
+
+       return ret;
+}
+
+static ssize_t ieee80211_if_write_link(
+       struct ieee80211_link_data *link,
+       const char __user *userbuf,
+       size_t count, loff_t *ppos,
+       ssize_t (*write)(struct ieee80211_link_data *link, const char *, int))
+{
+       char buf[64];
+       ssize_t ret;
+
+       if (count >= sizeof(buf))
+               return -E2BIG;
+
+       if (copy_from_user(buf, userbuf, count))
+               return -EFAULT;
+       buf[count] = '\0';
+
+       wiphy_lock(link->sdata->local->hw.wiphy);
+       ret = (*write)(link, buf, count);
+       wiphy_unlock(link->sdata->local->hw.wiphy);
 
        return ret;
 }
        .llseek = generic_file_llseek,                                  \
 }
 
-#define _IEEE80211_IF_FILE_R_FN(name, type)                            \
+#define _IEEE80211_IF_FILE_R_FN(name)                                  \
 static ssize_t ieee80211_if_read_##name(struct file *file,             \
                                        char __user *userbuf,           \
                                        size_t count, loff_t *ppos)     \
 {                                                                      \
-       ssize_t (*fn)(const void *, char *, int) = (void *)             \
-               ((ssize_t (*)(const type, char *, int))                 \
-                ieee80211_if_fmt_##name);                              \
-       return ieee80211_if_read(file->private_data,                    \
-                                userbuf, count, ppos, fn);             \
+       return ieee80211_if_read_sdata(file->private_data,              \
+                                      userbuf, count, ppos,            \
+                                      ieee80211_if_fmt_##name);        \
 }
 
-#define _IEEE80211_IF_FILE_W_FN(name, type)                            \
+#define _IEEE80211_IF_FILE_W_FN(name)                                  \
 static ssize_t ieee80211_if_write_##name(struct file *file,            \
                                         const char __user *userbuf,    \
                                         size_t count, loff_t *ppos)    \
 {                                                                      \
-       ssize_t (*fn)(void *, const char *, int) = (void *)             \
-               ((ssize_t (*)(type, const char *, int))                 \
-                ieee80211_if_parse_##name);                            \
-       return ieee80211_if_write(file->private_data, userbuf, count,   \
-                                 ppos, fn);                            \
+       return ieee80211_if_write_sdata(file->private_data, userbuf,    \
+                                       count, ppos,                    \
+                                       ieee80211_if_parse_##name);     \
 }
 
 #define IEEE80211_IF_FILE_R(name)                                      \
-       _IEEE80211_IF_FILE_R_FN(name, struct ieee80211_sub_if_data *)   \
+       _IEEE80211_IF_FILE_R_FN(name)                                   \
        _IEEE80211_IF_FILE_OPS(name, ieee80211_if_read_##name, NULL)
 
 #define IEEE80211_IF_FILE_W(name)                                      \
-       _IEEE80211_IF_FILE_W_FN(name, struct ieee80211_sub_if_data *)   \
+       _IEEE80211_IF_FILE_W_FN(name)                                   \
        _IEEE80211_IF_FILE_OPS(name, NULL, ieee80211_if_write_##name)
 
 #define IEEE80211_IF_FILE_RW(name)                                     \
-       _IEEE80211_IF_FILE_R_FN(name, struct ieee80211_sub_if_data *)   \
-       _IEEE80211_IF_FILE_W_FN(name, struct ieee80211_sub_if_data *)   \
+       _IEEE80211_IF_FILE_R_FN(name)                                   \
+       _IEEE80211_IF_FILE_W_FN(name)                                   \
        _IEEE80211_IF_FILE_OPS(name, ieee80211_if_read_##name,          \
                               ieee80211_if_write_##name)
 
        IEEE80211_IF_FMT_##format(name, struct ieee80211_sub_if_data, field) \
        IEEE80211_IF_FILE_R(name)
 
-/* Same but with a link_ prefix in the ops variable name and different type */
+#define _IEEE80211_IF_LINK_R_FN(name)                                  \
+static ssize_t ieee80211_if_read_##name(struct file *file,             \
+                                       char __user *userbuf,           \
+                                       size_t count, loff_t *ppos)     \
+{                                                                      \
+       return ieee80211_if_read_link(file->private_data,               \
+                                     userbuf, count, ppos,             \
+                                     ieee80211_if_fmt_##name); \
+}
+
+#define _IEEE80211_IF_LINK_W_FN(name)                                  \
+static ssize_t ieee80211_if_write_##name(struct file *file,            \
+                                        const char __user *userbuf,    \
+                                        size_t count, loff_t *ppos)    \
+{                                                                      \
+       return ieee80211_if_write_link(file->private_data, userbuf,     \
+                                      count, ppos,                     \
+                                      ieee80211_if_parse_##name);      \
+}
+
 #define IEEE80211_IF_LINK_FILE_R(name)                                 \
-       _IEEE80211_IF_FILE_R_FN(name, struct ieee80211_link_data *)     \
+       _IEEE80211_IF_LINK_R_FN(name)                                   \
        _IEEE80211_IF_FILE_OPS(link_##name, ieee80211_if_read_##name, NULL)
 
 #define IEEE80211_IF_LINK_FILE_W(name)                                 \
-       _IEEE80211_IF_FILE_W_FN(name)                                   \
+       _IEEE80211_IF_LINK_W_FN(name)                                   \
        _IEEE80211_IF_FILE_OPS(link_##name, NULL, ieee80211_if_write_##name)
 
 #define IEEE80211_IF_LINK_FILE_RW(name)                                        \
-       _IEEE80211_IF_FILE_R_FN(name, struct ieee80211_link_data *)     \
-       _IEEE80211_IF_FILE_W_FN(name, struct ieee80211_link_data *)     \
+       _IEEE80211_IF_LINK_R_FN(name)                                   \
+       _IEEE80211_IF_LINK_W_FN(name)                                   \
        _IEEE80211_IF_FILE_OPS(link_##name, ieee80211_if_read_##name,   \
                               ieee80211_if_write_##name)