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

adf_pfvf_vf_msg.c (4796B)


      1// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
      2/* Copyright(c) 2015 - 2021 Intel Corporation */
      3#include <linux/bitfield.h>
      4#include "adf_accel_devices.h"
      5#include "adf_common_drv.h"
      6#include "adf_pfvf_msg.h"
      7#include "adf_pfvf_vf_msg.h"
      8#include "adf_pfvf_vf_proto.h"
      9
     10/**
     11 * adf_vf2pf_notify_init() - send init msg to PF
     12 * @accel_dev:  Pointer to acceleration VF device.
     13 *
     14 * Function sends an init message from the VF to a PF
     15 *
     16 * Return: 0 on success, error code otherwise.
     17 */
     18int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev)
     19{
     20	struct pfvf_message msg = { .type = ADF_VF2PF_MSGTYPE_INIT };
     21
     22	if (adf_send_vf2pf_msg(accel_dev, msg)) {
     23		dev_err(&GET_DEV(accel_dev),
     24			"Failed to send Init event to PF\n");
     25		return -EFAULT;
     26	}
     27	set_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status);
     28	return 0;
     29}
     30EXPORT_SYMBOL_GPL(adf_vf2pf_notify_init);
     31
     32/**
     33 * adf_vf2pf_notify_shutdown() - send shutdown msg to PF
     34 * @accel_dev:  Pointer to acceleration VF device.
     35 *
     36 * Function sends a shutdown message from the VF to a PF
     37 *
     38 * Return: void
     39 */
     40void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev)
     41{
     42	struct pfvf_message msg = { .type = ADF_VF2PF_MSGTYPE_SHUTDOWN };
     43
     44	if (test_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status))
     45		if (adf_send_vf2pf_msg(accel_dev, msg))
     46			dev_err(&GET_DEV(accel_dev),
     47				"Failed to send Shutdown event to PF\n");
     48}
     49EXPORT_SYMBOL_GPL(adf_vf2pf_notify_shutdown);
     50
     51int adf_vf2pf_request_version(struct adf_accel_dev *accel_dev)
     52{
     53	u8 pf_version;
     54	int compat;
     55	int ret;
     56	struct pfvf_message resp;
     57	struct pfvf_message msg = {
     58		.type = ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ,
     59		.data = ADF_PFVF_COMPAT_THIS_VERSION,
     60	};
     61
     62	BUILD_BUG_ON(ADF_PFVF_COMPAT_THIS_VERSION > 255);
     63
     64	ret = adf_send_vf2pf_req(accel_dev, msg, &resp);
     65	if (ret) {
     66		dev_err(&GET_DEV(accel_dev),
     67			"Failed to send Compatibility Version Request.\n");
     68		return ret;
     69	}
     70
     71	pf_version = FIELD_GET(ADF_PF2VF_VERSION_RESP_VERS_MASK, resp.data);
     72	compat = FIELD_GET(ADF_PF2VF_VERSION_RESP_RESULT_MASK, resp.data);
     73
     74	/* Response from PF received, check compatibility */
     75	switch (compat) {
     76	case ADF_PF2VF_VF_COMPATIBLE:
     77		break;
     78	case ADF_PF2VF_VF_COMPAT_UNKNOWN:
     79		/* VF is newer than PF - compatible for now */
     80		break;
     81	case ADF_PF2VF_VF_INCOMPATIBLE:
     82		dev_err(&GET_DEV(accel_dev),
     83			"PF (vers %d) and VF (vers %d) are not compatible\n",
     84			pf_version, ADF_PFVF_COMPAT_THIS_VERSION);
     85		return -EINVAL;
     86	default:
     87		dev_err(&GET_DEV(accel_dev),
     88			"Invalid response from PF; assume not compatible\n");
     89		return -EINVAL;
     90	}
     91
     92	accel_dev->vf.pf_compat_ver = pf_version;
     93	return 0;
     94}
     95
     96int adf_vf2pf_get_capabilities(struct adf_accel_dev *accel_dev)
     97{
     98	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
     99	struct capabilities_v3 cap_msg = { 0 };
    100	unsigned int len = sizeof(cap_msg);
    101
    102	if (accel_dev->vf.pf_compat_ver < ADF_PFVF_COMPAT_CAPABILITIES)
    103		/* The PF is too old to support the extended capabilities */
    104		return 0;
    105
    106	if (adf_send_vf2pf_blkmsg_req(accel_dev, ADF_VF2PF_BLKMSG_REQ_CAP_SUMMARY,
    107				      (u8 *)&cap_msg, &len)) {
    108		dev_err(&GET_DEV(accel_dev),
    109			"QAT: Failed to get block message response\n");
    110		return -EFAULT;
    111	}
    112
    113	switch (cap_msg.hdr.version) {
    114	default:
    115		/* Newer version received, handle only the know parts */
    116		fallthrough;
    117	case ADF_PFVF_CAPABILITIES_V3_VERSION:
    118		if (likely(len >= sizeof(struct capabilities_v3)))
    119			hw_data->clock_frequency = cap_msg.frequency;
    120		else
    121			dev_info(&GET_DEV(accel_dev), "Could not get frequency");
    122		fallthrough;
    123	case ADF_PFVF_CAPABILITIES_V2_VERSION:
    124		if (likely(len >= sizeof(struct capabilities_v2)))
    125			hw_data->accel_capabilities_mask = cap_msg.capabilities;
    126		else
    127			dev_info(&GET_DEV(accel_dev), "Could not get capabilities");
    128		fallthrough;
    129	case ADF_PFVF_CAPABILITIES_V1_VERSION:
    130		if (likely(len >= sizeof(struct capabilities_v1))) {
    131			hw_data->extended_dc_capabilities = cap_msg.ext_dc_caps;
    132		} else {
    133			dev_err(&GET_DEV(accel_dev),
    134				"Capabilities message truncated to %d bytes\n", len);
    135			return -EFAULT;
    136		}
    137	}
    138
    139	return 0;
    140}
    141
    142int adf_vf2pf_get_ring_to_svc(struct adf_accel_dev *accel_dev)
    143{
    144	struct ring_to_svc_map_v1 rts_map_msg = { 0 };
    145	unsigned int len = sizeof(rts_map_msg);
    146
    147	if (accel_dev->vf.pf_compat_ver < ADF_PFVF_COMPAT_RING_TO_SVC_MAP)
    148		/* Use already set default mappings */
    149		return 0;
    150
    151	if (adf_send_vf2pf_blkmsg_req(accel_dev, ADF_VF2PF_BLKMSG_REQ_RING_SVC_MAP,
    152				      (u8 *)&rts_map_msg, &len)) {
    153		dev_err(&GET_DEV(accel_dev),
    154			"QAT: Failed to get block message response\n");
    155		return -EFAULT;
    156	}
    157
    158	if (unlikely(len < sizeof(struct ring_to_svc_map_v1))) {
    159		dev_err(&GET_DEV(accel_dev),
    160			"RING_TO_SVC message truncated to %d bytes\n", len);
    161		return -EFAULT;
    162	}
    163
    164	/* Only v1 at present */
    165	accel_dev->hw_device->ring_to_svc_map = rts_map_msg.map;
    166	return 0;
    167}