cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

vendor-cmd.c (4311B)


      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}