]> Git Repo - J-linux.git/blob - drivers/net/wireless/intel/iwlwifi/mvm/vendor-cmd.c
Merge tag 'kbuild-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy...
[J-linux.git] / drivers / net / wireless / intel / iwlwifi / mvm / vendor-cmd.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2021 Intel Corporation
4  */
5 #include "mvm.h"
6 #include <linux/nl80211-vnd-intel.h>
7 #include <net/netlink.h>
8
9 static const struct nla_policy
10 iwl_mvm_vendor_attr_policy[NUM_IWL_MVM_VENDOR_ATTR] = {
11         [IWL_MVM_VENDOR_ATTR_ROAMING_FORBIDDEN] = { .type = NLA_U8 },
12         [IWL_MVM_VENDOR_ATTR_AUTH_MODE] = { .type = NLA_U32 },
13         [IWL_MVM_VENDOR_ATTR_CHANNEL_NUM] = { .type = NLA_U8 },
14         [IWL_MVM_VENDOR_ATTR_SSID] = { .type = NLA_BINARY,
15                                        .len = IEEE80211_MAX_SSID_LEN },
16         [IWL_MVM_VENDOR_ATTR_BAND] = { .type = NLA_U8 },
17         [IWL_MVM_VENDOR_ATTR_COLLOC_CHANNEL] = { .type = NLA_U8 },
18         [IWL_MVM_VENDOR_ATTR_COLLOC_ADDR] = { .type = NLA_BINARY, .len = ETH_ALEN },
19 };
20
21 static int iwl_mvm_vendor_get_csme_conn_info(struct wiphy *wiphy,
22                                              struct wireless_dev *wdev,
23                                              const void *data, int data_len)
24 {
25         struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
26         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
27         struct iwl_mvm_csme_conn_info *csme_conn_info;
28         struct sk_buff *skb;
29         int err = 0;
30
31         mutex_lock(&mvm->mutex);
32         csme_conn_info = iwl_mvm_get_csme_conn_info(mvm);
33
34         if (!csme_conn_info) {
35                 err = -EINVAL;
36                 goto out_unlock;
37         }
38
39         skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, 200);
40         if (!skb) {
41                 err = -ENOMEM;
42                 goto out_unlock;
43         }
44
45         if (nla_put_u32(skb, IWL_MVM_VENDOR_ATTR_AUTH_MODE,
46                         csme_conn_info->conn_info.auth_mode) ||
47             nla_put(skb, IWL_MVM_VENDOR_ATTR_SSID,
48                     csme_conn_info->conn_info.ssid_len,
49                     csme_conn_info->conn_info.ssid) ||
50             nla_put_u32(skb, IWL_MVM_VENDOR_ATTR_STA_CIPHER,
51                         csme_conn_info->conn_info.pairwise_cipher) ||
52             nla_put_u8(skb, IWL_MVM_VENDOR_ATTR_CHANNEL_NUM,
53                        csme_conn_info->conn_info.channel) ||
54             nla_put(skb, IWL_MVM_VENDOR_ATTR_ADDR, ETH_ALEN,
55                     csme_conn_info->conn_info.bssid)) {
56                 kfree_skb(skb);
57                 err = -ENOBUFS;
58         }
59
60 out_unlock:
61         mutex_unlock(&mvm->mutex);
62         if (err)
63                 return err;
64
65         return cfg80211_vendor_cmd_reply(skb);
66 }
67
68 static int iwl_mvm_vendor_host_get_ownership(struct wiphy *wiphy,
69                                              struct wireless_dev *wdev,
70                                              const void *data, int data_len)
71 {
72         struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
73         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
74         int ret;
75
76         mutex_lock(&mvm->mutex);
77         ret = iwl_mvm_mei_get_ownership(mvm);
78         mutex_unlock(&mvm->mutex);
79
80         return ret;
81 }
82
83 static const struct wiphy_vendor_command iwl_mvm_vendor_commands[] = {
84         {
85                 .info = {
86                         .vendor_id = INTEL_OUI,
87                         .subcmd = IWL_MVM_VENDOR_CMD_GET_CSME_CONN_INFO,
88                 },
89                 .doit = iwl_mvm_vendor_get_csme_conn_info,
90                 .flags = WIPHY_VENDOR_CMD_NEED_WDEV,
91                 .policy = iwl_mvm_vendor_attr_policy,
92                 .maxattr = MAX_IWL_MVM_VENDOR_ATTR,
93         },
94         {
95                 .info = {
96                         .vendor_id = INTEL_OUI,
97                         .subcmd = IWL_MVM_VENDOR_CMD_HOST_GET_OWNERSHIP,
98                 },
99                 .doit = iwl_mvm_vendor_host_get_ownership,
100                 .flags = WIPHY_VENDOR_CMD_NEED_WDEV,
101                 .policy = iwl_mvm_vendor_attr_policy,
102                 .maxattr = MAX_IWL_MVM_VENDOR_ATTR,
103         },
104 };
105
106 enum iwl_mvm_vendor_events_idx {
107         /* 0x0 - 0x3 are deprecated */
108         IWL_MVM_VENDOR_EVENT_IDX_ROAMING_FORBIDDEN = 4,
109         NUM_IWL_MVM_VENDOR_EVENT_IDX
110 };
111
112 static const struct nl80211_vendor_cmd_info
113 iwl_mvm_vendor_events[NUM_IWL_MVM_VENDOR_EVENT_IDX] = {
114         [IWL_MVM_VENDOR_EVENT_IDX_ROAMING_FORBIDDEN] = {
115                 .vendor_id = INTEL_OUI,
116                 .subcmd = IWL_MVM_VENDOR_CMD_ROAMING_FORBIDDEN_EVENT,
117         },
118 };
119
120 void iwl_mvm_vendor_cmds_register(struct iwl_mvm *mvm)
121 {
122         mvm->hw->wiphy->vendor_commands = iwl_mvm_vendor_commands;
123         mvm->hw->wiphy->n_vendor_commands = ARRAY_SIZE(iwl_mvm_vendor_commands);
124         mvm->hw->wiphy->vendor_events = iwl_mvm_vendor_events;
125         mvm->hw->wiphy->n_vendor_events = ARRAY_SIZE(iwl_mvm_vendor_events);
126 }
127
128 void iwl_mvm_send_roaming_forbidden_event(struct iwl_mvm *mvm,
129                                           struct ieee80211_vif *vif,
130                                           bool forbidden)
131 {
132         struct sk_buff *msg =
133                 cfg80211_vendor_event_alloc(mvm->hw->wiphy,
134                                             ieee80211_vif_to_wdev(vif),
135                                             200, IWL_MVM_VENDOR_EVENT_IDX_ROAMING_FORBIDDEN,
136                                             GFP_ATOMIC);
137         if (!msg)
138                 return;
139
140         if (WARN_ON(!vif))
141                 return;
142
143         if (nla_put(msg, IWL_MVM_VENDOR_ATTR_VIF_ADDR,
144                     ETH_ALEN, vif->addr) ||
145             nla_put_u8(msg, IWL_MVM_VENDOR_ATTR_ROAMING_FORBIDDEN, forbidden))
146                 goto nla_put_failure;
147
148         cfg80211_vendor_event(msg, GFP_ATOMIC);
149         return;
150
151  nla_put_failure:
152         kfree_skb(msg);
153 }
This page took 0.033955 seconds and 4 git commands to generate.