brintos

brintos / linux-shallow public Read only

0
0
Text · 4.2 KiB · 080a158 Raw
154 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2021 Intel Corporation4 */5#include "mvm.h"6#include <linux/nl80211-vnd-intel.h>7#include <net/netlink.h>8 9static const struct nla_policy10iwl_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_IDX110};111 112static const struct nl80211_vendor_cmd_info113iwl_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}154