Linux Audio

Check our new training course

Loading...
v6.8
  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
  9static const struct nla_policy
 10iwl_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
 21static 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
 60out_unlock:
 61	mutex_unlock(&mvm->mutex);
 62	if (err)
 63		return err;
 64
 65	return cfg80211_vendor_cmd_reply(skb);
 66}
 67
 68static 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
 83static 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
106enum 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
112static const struct nl80211_vendor_cmd_info
113iwl_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
120void 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
128void 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}
v6.2
  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
  9static const struct nla_policy
 10iwl_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
 21static 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
 60out_unlock:
 61	mutex_unlock(&mvm->mutex);
 62	if (err)
 63		return err;
 64
 65	return cfg80211_vendor_cmd_reply(skb);
 66}
 67
 68static 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
 83static 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
106enum 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
112static const struct nl80211_vendor_cmd_info
113iwl_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
120void 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
128void 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}