1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 Intel Corporation */
3 /* $FreeBSD$ */
4 #include <linux/device.h>
5 #include "adf_accel_devices.h"
6 #include "adf_common_drv.h"
7 #include "adf_pf2vf_msg.h"
8 #include "adf_cfg.h"
9
10 #define ADF_VF2PF_CAPABILITIES_V1_VERSION 1
11 #define ADF_VF2PF_CAPABILITIES_V1_LENGTH 4
12 #define ADF_VF2PF_CAPABILITIES_V2_VERSION 2
13 #define ADF_VF2PF_CAPABILITIES_CAP_OFFSET 4
14 #define ADF_VF2PF_CAPABILITIES_V2_LENGTH 8
15 #define ADF_VF2PF_CAPABILITIES_V3_VERSION 3
16 #define ADF_VF2PF_CAPABILITIES_FREQ_OFFSET 8
17 #define ADF_VF2PF_CAPABILITIES_V3_LENGTH 12
18
19 static int
20 adf_pf_capabilities_msg_provider(struct adf_accel_dev *accel_dev,
21 u8 **buffer,
22 u8 *length,
23 u8 *block_version,
24 u8 compatibility,
25 u8 byte_num)
26 {
27 static u8 data[ADF_VF2PF_CAPABILITIES_V3_LENGTH] = { 0 };
28 struct adf_hw_device_data *hw_data = accel_dev->hw_device;
29 u32 ext_dc_caps = hw_data->extended_dc_capabilities;
30 u32 capabilities = hw_data->accel_capabilities_mask;
31 u32 frequency = hw_data->clock_frequency;
32 u16 byte = 0;
33 u16 index = 0;
34
35 for (byte = 0; byte < sizeof(ext_dc_caps); byte++) {
36 data[byte] = (ext_dc_caps >> (byte * ADF_PFVF_DATA_SHIFT)) &
37 ADF_PFVF_DATA_MASK;
38 }
39
40 for (byte = 0, index = ADF_VF2PF_CAPABILITIES_CAP_OFFSET;
41 byte < sizeof(capabilities);
42 byte++, index++) {
43 data[index] = (capabilities >> (byte * ADF_PFVF_DATA_SHIFT)) &
44 ADF_PFVF_DATA_MASK;
45 }
46
47 if (frequency) {
48 for (byte = 0, index = ADF_VF2PF_CAPABILITIES_FREQ_OFFSET;
49 byte < sizeof(frequency);
50 byte++, index++) {
51 data[index] =
52 (frequency >> (byte * ADF_PFVF_DATA_SHIFT)) &
53 ADF_PFVF_DATA_MASK;
54 }
55 *length = ADF_VF2PF_CAPABILITIES_V3_LENGTH;
56 *block_version = ADF_VF2PF_CAPABILITIES_V3_VERSION;
57 } else {
58 *length = ADF_VF2PF_CAPABILITIES_V2_LENGTH;
59 *block_version = ADF_VF2PF_CAPABILITIES_V2_VERSION;
60 }
61
62 *buffer = data;
63 return 0;
64 }
65
66 int
67 adf_pf_vf_capabilities_init(struct adf_accel_dev *accel_dev)
68 {
69 u8 data[ADF_VF2PF_CAPABILITIES_V3_LENGTH] = { 0 };
70 u8 len = ADF_VF2PF_CAPABILITIES_V3_LENGTH;
71 u8 version = ADF_VF2PF_CAPABILITIES_V2_VERSION;
72 u32 ex_dc_cap = 0;
73 u32 capabilities = 0;
74 u32 frequency = 0;
75 u16 byte = 0;
76 u16 index = 0;
77
78 if (!accel_dev->is_vf) {
79 /* on the pf */
80 if (!adf_iov_is_block_provider_registered(
81 ADF_VF2PF_BLOCK_MSG_CAP_SUMMARY))
82 adf_iov_block_provider_register(
83 ADF_VF2PF_BLOCK_MSG_CAP_SUMMARY,
84 adf_pf_capabilities_msg_provider);
85 } else if (accel_dev->u1.vf.pf_version >=
86 ADF_PFVF_COMPATIBILITY_CAPABILITIES) {
87 /* on the vf */
88 if (adf_iov_block_get(accel_dev,
89 ADF_VF2PF_BLOCK_MSG_CAP_SUMMARY,
90 &version,
91 data,
92 &len)) {
93 device_printf(GET_DEV(accel_dev),
94 "QAT: Failed adf_iov_block_get\n");
95 return EFAULT;
96 }
97
98 if (len < ADF_VF2PF_CAPABILITIES_V1_LENGTH) {
99 device_printf(
100 GET_DEV(accel_dev),
101 "Capabilities message truncated to %d bytes\n",
102 len);
103 return EFAULT;
104 }
105
106 for (byte = 0; byte < sizeof(ex_dc_cap); byte++) {
107 ex_dc_cap |= data[byte] << (byte * ADF_PFVF_DATA_SHIFT);
108 }
109 accel_dev->hw_device->extended_dc_capabilities = ex_dc_cap;
110
111 /* Get capabilities if provided by PF */
112 if (len >= ADF_VF2PF_CAPABILITIES_V2_LENGTH) {
113 for (byte = 0,
114 index = ADF_VF2PF_CAPABILITIES_CAP_OFFSET;
115 byte < sizeof(capabilities);
116 byte++, index++) {
117 capabilities |= data[index]
118 << (byte * ADF_PFVF_DATA_SHIFT);
119 }
120 accel_dev->hw_device->accel_capabilities_mask =
121 capabilities;
122 } else {
123 device_printf(GET_DEV(accel_dev),
124 "PF did not communicate capabilities\n");
125 }
126
127 /* Get frequency if provided by the PF */
128 if (len >= ADF_VF2PF_CAPABILITIES_V3_LENGTH) {
129 for (byte = 0,
130 index = ADF_VF2PF_CAPABILITIES_FREQ_OFFSET;
131 byte < sizeof(frequency);
132 byte++, index++) {
133 frequency |= data[index]
134 << (byte * ADF_PFVF_DATA_SHIFT);
135 }
136 accel_dev->hw_device->clock_frequency = frequency;
137 } else {
138 device_printf(GET_DEV(accel_dev),
139 "PF did not communicate frequency\n");
140 }
141
142 } else {
143 /* The PF is too old to support the extended capabilities */
144 accel_dev->hw_device->extended_dc_capabilities = 0;
145 }
146 return 0;
147 }
Cache object: e5c38ee4ecbe6a930b33f82652c59b3a
|