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 (4712B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * This file is part of wlcore
      4 *
      5 * Copyright (C) 2014 Texas Instruments. All rights reserved.
      6 */
      7
      8#include <linux/pm_runtime.h>
      9
     10#include <net/mac80211.h>
     11#include <net/netlink.h>
     12
     13#include "wlcore.h"
     14#include "debug.h"
     15#include "hw_ops.h"
     16#include "vendor_cmd.h"
     17
     18static const
     19struct nla_policy wlcore_vendor_attr_policy[NUM_WLCORE_VENDOR_ATTR] = {
     20	[WLCORE_VENDOR_ATTR_FREQ]		= { .type = NLA_U32 },
     21	[WLCORE_VENDOR_ATTR_GROUP_ID]		= { .type = NLA_U32 },
     22	[WLCORE_VENDOR_ATTR_GROUP_KEY]		= { .type = NLA_BINARY,
     23						    .len = WLAN_MAX_KEY_LEN },
     24};
     25
     26static int
     27wlcore_vendor_cmd_smart_config_start(struct wiphy *wiphy,
     28				     struct wireless_dev *wdev,
     29				     const void *data, int data_len)
     30{
     31	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
     32	struct wl1271 *wl = hw->priv;
     33	struct nlattr *tb[NUM_WLCORE_VENDOR_ATTR];
     34	int ret;
     35
     36	wl1271_debug(DEBUG_CMD, "vendor cmd smart config start");
     37
     38	if (!data)
     39		return -EINVAL;
     40
     41	ret = nla_parse_deprecated(tb, MAX_WLCORE_VENDOR_ATTR, data, data_len,
     42				   wlcore_vendor_attr_policy, NULL);
     43	if (ret)
     44		return ret;
     45
     46	if (!tb[WLCORE_VENDOR_ATTR_GROUP_ID])
     47		return -EINVAL;
     48
     49	mutex_lock(&wl->mutex);
     50
     51	if (unlikely(wl->state != WLCORE_STATE_ON)) {
     52		ret = -EINVAL;
     53		goto out;
     54	}
     55
     56	ret = pm_runtime_resume_and_get(wl->dev);
     57	if (ret < 0)
     58		goto out;
     59
     60	ret = wlcore_smart_config_start(wl,
     61			nla_get_u32(tb[WLCORE_VENDOR_ATTR_GROUP_ID]));
     62
     63	pm_runtime_mark_last_busy(wl->dev);
     64	pm_runtime_put_autosuspend(wl->dev);
     65out:
     66	mutex_unlock(&wl->mutex);
     67
     68	return ret;
     69}
     70
     71static int
     72wlcore_vendor_cmd_smart_config_stop(struct wiphy *wiphy,
     73				    struct wireless_dev *wdev,
     74				    const void *data, int data_len)
     75{
     76	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
     77	struct wl1271 *wl = hw->priv;
     78	int ret;
     79
     80	wl1271_debug(DEBUG_CMD, "testmode cmd smart config stop");
     81
     82	mutex_lock(&wl->mutex);
     83
     84	if (unlikely(wl->state != WLCORE_STATE_ON)) {
     85		ret = -EINVAL;
     86		goto out;
     87	}
     88
     89	ret = pm_runtime_resume_and_get(wl->dev);
     90	if (ret < 0)
     91		goto out;
     92
     93	ret = wlcore_smart_config_stop(wl);
     94
     95	pm_runtime_mark_last_busy(wl->dev);
     96	pm_runtime_put_autosuspend(wl->dev);
     97out:
     98	mutex_unlock(&wl->mutex);
     99
    100	return ret;
    101}
    102
    103static int
    104wlcore_vendor_cmd_smart_config_set_group_key(struct wiphy *wiphy,
    105					     struct wireless_dev *wdev,
    106					     const void *data, int data_len)
    107{
    108	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
    109	struct wl1271 *wl = hw->priv;
    110	struct nlattr *tb[NUM_WLCORE_VENDOR_ATTR];
    111	int ret;
    112
    113	wl1271_debug(DEBUG_CMD, "testmode cmd smart config set group key");
    114
    115	if (!data)
    116		return -EINVAL;
    117
    118	ret = nla_parse_deprecated(tb, MAX_WLCORE_VENDOR_ATTR, data, data_len,
    119				   wlcore_vendor_attr_policy, NULL);
    120	if (ret)
    121		return ret;
    122
    123	if (!tb[WLCORE_VENDOR_ATTR_GROUP_ID] ||
    124	    !tb[WLCORE_VENDOR_ATTR_GROUP_KEY])
    125		return -EINVAL;
    126
    127	mutex_lock(&wl->mutex);
    128
    129	if (unlikely(wl->state != WLCORE_STATE_ON)) {
    130		ret = -EINVAL;
    131		goto out;
    132	}
    133
    134	ret = pm_runtime_resume_and_get(wl->dev);
    135	if (ret < 0)
    136		goto out;
    137
    138	ret = wlcore_smart_config_set_group_key(wl,
    139			nla_get_u32(tb[WLCORE_VENDOR_ATTR_GROUP_ID]),
    140			nla_len(tb[WLCORE_VENDOR_ATTR_GROUP_KEY]),
    141			nla_data(tb[WLCORE_VENDOR_ATTR_GROUP_KEY]));
    142
    143	pm_runtime_mark_last_busy(wl->dev);
    144	pm_runtime_put_autosuspend(wl->dev);
    145out:
    146	mutex_unlock(&wl->mutex);
    147
    148	return ret;
    149}
    150
    151static const struct wiphy_vendor_command wlcore_vendor_commands[] = {
    152	{
    153		.info = {
    154			.vendor_id = TI_OUI,
    155			.subcmd = WLCORE_VENDOR_CMD_SMART_CONFIG_START,
    156		},
    157		.flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
    158			 WIPHY_VENDOR_CMD_NEED_RUNNING,
    159		.doit = wlcore_vendor_cmd_smart_config_start,
    160		.policy = wlcore_vendor_attr_policy,
    161	},
    162	{
    163		.info = {
    164			.vendor_id = TI_OUI,
    165			.subcmd = WLCORE_VENDOR_CMD_SMART_CONFIG_STOP,
    166		},
    167		.flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
    168			 WIPHY_VENDOR_CMD_NEED_RUNNING,
    169		.doit = wlcore_vendor_cmd_smart_config_stop,
    170		.policy = wlcore_vendor_attr_policy,
    171	},
    172	{
    173		.info = {
    174			.vendor_id = TI_OUI,
    175			.subcmd = WLCORE_VENDOR_CMD_SMART_CONFIG_SET_GROUP_KEY,
    176		},
    177		.flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
    178			 WIPHY_VENDOR_CMD_NEED_RUNNING,
    179		.doit = wlcore_vendor_cmd_smart_config_set_group_key,
    180		.policy = wlcore_vendor_attr_policy,
    181	},
    182};
    183
    184static const struct nl80211_vendor_cmd_info wlcore_vendor_events[] = {
    185	{
    186		.vendor_id = TI_OUI,
    187		.subcmd = WLCORE_VENDOR_EVENT_SC_SYNC,
    188	},
    189	{
    190		.vendor_id = TI_OUI,
    191		.subcmd = WLCORE_VENDOR_EVENT_SC_DECODE,
    192	},
    193};
    194
    195void wlcore_set_vendor_commands(struct wiphy *wiphy)
    196{
    197	wiphy->vendor_commands = wlcore_vendor_commands;
    198	wiphy->n_vendor_commands = ARRAY_SIZE(wlcore_vendor_commands);
    199	wiphy->vendor_events = wlcore_vendor_events;
    200	wiphy->n_vendor_events = ARRAY_SIZE(wlcore_vendor_events);
    201}