]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blobdiff - net/wireless/nl80211.c
cfg80211: use wdev in mgmt-tx/ROC APIs
[mirror_ubuntu-jammy-kernel.git] / net / wireless / nl80211.c
index 5800c49d6942b8b6cf4434a9674af70313fb7977..0dc3356eea4030b54146d3f72776ef12fc907df6 100644 (file)
@@ -1728,6 +1728,11 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
        return result;
 }
 
+static inline u64 wdev_id(struct wireless_dev *wdev)
+{
+       return (u64)wdev->identifier |
+              ((u64)wiphy_to_dev(wdev->wiphy)->wiphy_idx << 32);
+}
 
 static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
                              struct cfg80211_registered_device *rdev,
@@ -1735,8 +1740,6 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 {
        struct net_device *dev = wdev->netdev;
        void *hdr;
-       u64 wdev_id = (u64)wdev->identifier |
-                     ((u64)rdev->wiphy_idx << 32);
 
        hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_INTERFACE);
        if (!hdr)
@@ -1750,7 +1753,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 
        if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
            nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) ||
-           nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id) ||
+           nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) ||
            nla_put_u32(msg, NL80211_ATTR_GENERATION,
                        rdev->devlist_generation ^
                        (cfg80211_rdev_list_generation << 2)))
@@ -5752,7 +5755,7 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
                                     struct genl_info *info)
 {
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
-       struct net_device *dev = info->user_ptr[1];
+       struct wireless_dev *wdev = info->user_ptr[1];
        struct ieee80211_channel *chan;
        struct sk_buff *msg;
        void *hdr;
@@ -5800,7 +5803,7 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
                goto free_msg;
        }
 
-       err = rdev->ops->remain_on_channel(&rdev->wiphy, dev, chan,
+       err = rdev->ops->remain_on_channel(&rdev->wiphy, wdev, chan,
                                           channel_type, duration, &cookie);
 
        if (err)
@@ -5824,7 +5827,7 @@ static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
                                            struct genl_info *info)
 {
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
-       struct net_device *dev = info->user_ptr[1];
+       struct wireless_dev *wdev = info->user_ptr[1];
        u64 cookie;
 
        if (!info->attrs[NL80211_ATTR_COOKIE])
@@ -5835,7 +5838,7 @@ static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
 
        cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
 
-       return rdev->ops->cancel_remain_on_channel(&rdev->wiphy, dev, cookie);
+       return rdev->ops->cancel_remain_on_channel(&rdev->wiphy, wdev, cookie);
 }
 
 static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
@@ -5984,7 +5987,7 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
 static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
 {
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
-       struct net_device *dev = info->user_ptr[1];
+       struct wireless_dev *wdev = info->user_ptr[1];
        u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION;
 
        if (!info->attrs[NL80211_ATTR_FRAME_MATCH])
@@ -5993,21 +5996,24 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
        if (info->attrs[NL80211_ATTR_FRAME_TYPE])
                frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]);
 
-       if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
-           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
-           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
-           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
-           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
-           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
-           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
+       switch (wdev->iftype) {
+       case NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_ADHOC:
+       case NL80211_IFTYPE_P2P_CLIENT:
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_AP_VLAN:
+       case NL80211_IFTYPE_MESH_POINT:
+       case NL80211_IFTYPE_P2P_GO:
+               break;
+       default:
                return -EOPNOTSUPP;
+       }
 
        /* not much point in registering if we can't reply */
        if (!rdev->ops->mgmt_tx)
                return -EOPNOTSUPP;
 
-       return cfg80211_mlme_register_mgmt(dev->ieee80211_ptr, info->snd_pid,
-                       frame_type,
+       return cfg80211_mlme_register_mgmt(wdev, info->snd_pid, frame_type,
                        nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
                        nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]));
 }
@@ -6015,7 +6021,7 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
 static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
 {
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
-       struct net_device *dev = info->user_ptr[1];
+       struct wireless_dev *wdev = info->user_ptr[1];
        struct ieee80211_channel *chan;
        enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
        bool channel_type_valid = false;
@@ -6036,14 +6042,18 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
        if (!rdev->ops->mgmt_tx)
                return -EOPNOTSUPP;
 
-       if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
-           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
-           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
-           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
-           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
-           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
-           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
+       switch (wdev->iftype) {
+       case NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_ADHOC:
+       case NL80211_IFTYPE_P2P_CLIENT:
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_AP_VLAN:
+       case NL80211_IFTYPE_MESH_POINT:
+       case NL80211_IFTYPE_P2P_GO:
+               break;
+       default:
                return -EOPNOTSUPP;
+       }
 
        if (info->attrs[NL80211_ATTR_DURATION]) {
                if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
@@ -6092,7 +6102,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
                }
        }
 
-       err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, offchan, channel_type,
+       err = cfg80211_mlme_mgmt_tx(rdev, wdev, chan, offchan, channel_type,
                                    channel_type_valid, wait,
                                    nla_data(info->attrs[NL80211_ATTR_FRAME]),
                                    nla_len(info->attrs[NL80211_ATTR_FRAME]),
@@ -6120,7 +6130,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
 static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info)
 {
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
-       struct net_device *dev = info->user_ptr[1];
+       struct wireless_dev *wdev = info->user_ptr[1];
        u64 cookie;
 
        if (!info->attrs[NL80211_ATTR_COOKIE])
@@ -6129,17 +6139,21 @@ static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *in
        if (!rdev->ops->mgmt_tx_cancel_wait)
                return -EOPNOTSUPP;
 
-       if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
-           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
-           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
-           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
-           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
-           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
+       switch (wdev->iftype) {
+       case NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_ADHOC:
+       case NL80211_IFTYPE_P2P_CLIENT:
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_AP_VLAN:
+       case NL80211_IFTYPE_P2P_GO:
+               break;
+       default:
                return -EOPNOTSUPP;
+       }
 
        cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
 
-       return rdev->ops->mgmt_tx_cancel_wait(&rdev->wiphy, dev, cookie);
+       return rdev->ops->mgmt_tx_cancel_wait(&rdev->wiphy, wdev, cookie);
 }
 
 static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
@@ -7172,7 +7186,7 @@ static struct genl_ops nl80211_ops[] = {
                .doit = nl80211_remain_on_channel,
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
-               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+               .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
@@ -7180,7 +7194,7 @@ static struct genl_ops nl80211_ops[] = {
                .doit = nl80211_cancel_remain_on_channel,
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
-               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+               .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
@@ -7196,7 +7210,7 @@ static struct genl_ops nl80211_ops[] = {
                .doit = nl80211_register_mgmt,
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
-               .internal_flags = NL80211_FLAG_NEED_NETDEV |
+               .internal_flags = NL80211_FLAG_NEED_WDEV |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
@@ -7204,7 +7218,7 @@ static struct genl_ops nl80211_ops[] = {
                .doit = nl80211_tx_mgmt,
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
-               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+               .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
@@ -7212,7 +7226,7 @@ static struct genl_ops nl80211_ops[] = {
                .doit = nl80211_tx_mgmt_cancel_wait,
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
-               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+               .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
@@ -8040,7 +8054,7 @@ nla_put_failure:
 
 static void nl80211_send_remain_on_chan_event(
        int cmd, struct cfg80211_registered_device *rdev,
-       struct net_device *netdev, u64 cookie,
+       struct wireless_dev *wdev, u64 cookie,
        struct ieee80211_channel *chan,
        enum nl80211_channel_type channel_type,
        unsigned int duration, gfp_t gfp)
@@ -8059,7 +8073,9 @@ static void nl80211_send_remain_on_chan_event(
        }
 
        if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
-           nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+           (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
+                                        wdev->netdev->ifindex)) ||
+           nla_put_u32(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) ||
            nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
            nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, channel_type) ||
            nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
@@ -8081,23 +8097,24 @@ static void nl80211_send_remain_on_chan_event(
 }
 
 void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev,
-                                   struct net_device *netdev, u64 cookie,
+                                   struct wireless_dev *wdev, u64 cookie,
                                    struct ieee80211_channel *chan,
                                    enum nl80211_channel_type channel_type,
                                    unsigned int duration, gfp_t gfp)
 {
        nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
-                                         rdev, netdev, cookie, chan,
+                                         rdev, wdev, cookie, chan,
                                          channel_type, duration, gfp);
 }
 
 void nl80211_send_remain_on_channel_cancel(
-       struct cfg80211_registered_device *rdev, struct net_device *netdev,
+       struct cfg80211_registered_device *rdev,
+       struct wireless_dev *wdev,
        u64 cookie, struct ieee80211_channel *chan,
        enum nl80211_channel_type channel_type, gfp_t gfp)
 {
        nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
-                                         rdev, netdev, cookie, chan,
+                                         rdev, wdev, cookie, chan,
                                          channel_type, 0, gfp);
 }
 
@@ -8211,10 +8228,11 @@ bool nl80211_unexpected_4addr_frame(struct net_device *dev,
 }
 
 int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
-                     struct net_device *netdev, u32 nlpid,
+                     struct wireless_dev *wdev, u32 nlpid,
                      int freq, int sig_dbm,
                      const u8 *buf, size_t len, gfp_t gfp)
 {
+       struct net_device *netdev = wdev->netdev;
        struct sk_buff *msg;
        void *hdr;
 
@@ -8229,7 +8247,8 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
        }
 
        if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
-           nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+           (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
+                                       netdev->ifindex)) ||
            nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
            (sig_dbm &&
             nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
@@ -8247,10 +8266,11 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
 }
 
 void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev,
-                                struct net_device *netdev, u64 cookie,
+                                struct wireless_dev *wdev, u64 cookie,
                                 const u8 *buf, size_t len, bool ack,
                                 gfp_t gfp)
 {
+       struct net_device *netdev = wdev->netdev;
        struct sk_buff *msg;
        void *hdr;
 
@@ -8265,7 +8285,8 @@ void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev,
        }
 
        if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
-           nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+           (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
+                                  netdev->ifindex)) ||
            nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
            nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie) ||
            (ack && nla_put_flag(msg, NL80211_ATTR_ACK)))