aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTadeusz Struk <tadeusz.struk@intel.com>2015-08-24 14:56:02 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2015-08-25 09:13:19 -0400
commitdf9e21e100a65618b56971ec8da4975eb60e919d (patch)
tree771018555bfed1c11ec798e4df077001a26356e9
parent0f74fbf77d457c692e108c91475bb7a46aa6d60c (diff)
crypto: qat - enable legacy VFs
We need to support legacy VFs as well as VFs running on different OSes. To do so the compatibility check need needs to be relaxed. This patch moves the logic responsible for VF to PF version and compatibility checking from adfsriov.c to adf_pf2vf_msg.c, where it belongs, and changes the logic enable legacy VFs. Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/qat/qat_common/adf_common_drv.h1
-rw-r--r--drivers/crypto/qat/qat_common/adf_pf2vf_msg.c102
-rw-r--r--drivers/crypto/qat/qat_common/adf_pf2vf_msg.h2
-rw-r--r--drivers/crypto/qat/qat_common/adf_sriov.c119
4 files changed, 118 insertions, 106 deletions
diff --git a/drivers/crypto/qat/qat_common/adf_common_drv.h b/drivers/crypto/qat/qat_common/adf_common_drv.h
index 0f5f5e8c5003..7836dffc3d47 100644
--- a/drivers/crypto/qat/qat_common/adf_common_drv.h
+++ b/drivers/crypto/qat/qat_common/adf_common_drv.h
@@ -111,6 +111,7 @@ void adf_disable_pf2vf_interrupts(struct adf_accel_dev *accel_dev);
111int adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr); 111int adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr);
112void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev); 112void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev);
113int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev); 113int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev);
114void adf_vf2pf_req_hndl(struct adf_accel_vf_info *vf_info);
114void adf_devmgr_update_class_index(struct adf_hw_device_data *hw_data); 115void adf_devmgr_update_class_index(struct adf_hw_device_data *hw_data);
115void adf_clean_vf_map(bool); 116void adf_clean_vf_map(bool);
116 117
diff --git a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c
index c5790cd0b91b..5fdbad809343 100644
--- a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c
+++ b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c
@@ -256,6 +256,108 @@ int adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr)
256} 256}
257EXPORT_SYMBOL_GPL(adf_iov_putmsg); 257EXPORT_SYMBOL_GPL(adf_iov_putmsg);
258 258
259void adf_vf2pf_req_hndl(struct adf_accel_vf_info *vf_info)
260{
261 struct adf_accel_dev *accel_dev = vf_info->accel_dev;
262 struct adf_hw_device_data *hw_data = accel_dev->hw_device;
263 int bar_id = hw_data->get_misc_bar_id(hw_data);
264 struct adf_bar *pmisc = &GET_BARS(accel_dev)[bar_id];
265 void __iomem *pmisc_addr = pmisc->virt_addr;
266 u32 msg, resp = 0, vf_nr = vf_info->vf_nr;
267
268 /* Read message from the VF */
269 msg = ADF_CSR_RD(pmisc_addr, hw_data->get_pf2vf_offset(vf_nr));
270
271 /* To ACK, clear the VF2PFINT bit */
272 msg &= ~ADF_VF2PF_INT;
273 ADF_CSR_WR(pmisc_addr, hw_data->get_pf2vf_offset(vf_nr), msg);
274
275 if (!(msg & ADF_VF2PF_MSGORIGIN_SYSTEM))
276 /* Ignore legacy non-system (non-kernel) VF2PF messages */
277 goto err;
278
279 switch ((msg & ADF_VF2PF_MSGTYPE_MASK) >> ADF_VF2PF_MSGTYPE_SHIFT) {
280 case ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ:
281 {
282 u8 vf_compat_ver = msg >> ADF_VF2PF_COMPAT_VER_REQ_SHIFT;
283
284 resp = (ADF_PF2VF_MSGORIGIN_SYSTEM |
285 (ADF_PF2VF_MSGTYPE_VERSION_RESP <<
286 ADF_PF2VF_MSGTYPE_SHIFT) |
287 (ADF_PFVF_COMPATIBILITY_VERSION <<
288 ADF_PF2VF_VERSION_RESP_VERS_SHIFT));
289
290 dev_dbg(&GET_DEV(accel_dev),
291 "Compatibility Version Request from VF%d vers=%u\n",
292 vf_nr + 1, vf_compat_ver);
293
294 if (vf_compat_ver < hw_data->min_iov_compat_ver) {
295 dev_err(&GET_DEV(accel_dev),
296 "VF (vers %d) incompatible with PF (vers %d)\n",
297 vf_compat_ver, ADF_PFVF_COMPATIBILITY_VERSION);
298 resp |= ADF_PF2VF_VF_INCOMPATIBLE <<
299 ADF_PF2VF_VERSION_RESP_RESULT_SHIFT;
300 } else if (vf_compat_ver > ADF_PFVF_COMPATIBILITY_VERSION) {
301 dev_err(&GET_DEV(accel_dev),
302 "VF (vers %d) compat with PF (vers %d) unkn.\n",
303 vf_compat_ver, ADF_PFVF_COMPATIBILITY_VERSION);
304 resp |= ADF_PF2VF_VF_COMPAT_UNKNOWN <<
305 ADF_PF2VF_VERSION_RESP_RESULT_SHIFT;
306 } else {
307 dev_dbg(&GET_DEV(accel_dev),
308 "VF (vers %d) compatible with PF (vers %d)\n",
309 vf_compat_ver, ADF_PFVF_COMPATIBILITY_VERSION);
310 resp |= ADF_PF2VF_VF_COMPATIBLE <<
311 ADF_PF2VF_VERSION_RESP_RESULT_SHIFT;
312 }
313 }
314 break;
315 case ADF_VF2PF_MSGTYPE_VERSION_REQ:
316 dev_dbg(&GET_DEV(accel_dev),
317 "Legacy VersionRequest received from VF%d 0x%x\n",
318 vf_nr + 1, msg);
319 resp = (ADF_PF2VF_MSGORIGIN_SYSTEM |
320 (ADF_PF2VF_MSGTYPE_VERSION_RESP <<
321 ADF_PF2VF_MSGTYPE_SHIFT) |
322 (ADF_PFVF_COMPATIBILITY_VERSION <<
323 ADF_PF2VF_VERSION_RESP_VERS_SHIFT));
324 resp |= ADF_PF2VF_VF_COMPATIBLE <<
325 ADF_PF2VF_VERSION_RESP_RESULT_SHIFT;
326 /* Set legacy major and minor version num */
327 resp |= 1 << ADF_PF2VF_MAJORVERSION_SHIFT |
328 1 << ADF_PF2VF_MINORVERSION_SHIFT;
329 break;
330 case ADF_VF2PF_MSGTYPE_INIT:
331 {
332 dev_dbg(&GET_DEV(accel_dev),
333 "Init message received from VF%d 0x%x\n",
334 vf_nr + 1, msg);
335 vf_info->init = true;
336 }
337 break;
338 case ADF_VF2PF_MSGTYPE_SHUTDOWN:
339 {
340 dev_dbg(&GET_DEV(accel_dev),
341 "Shutdown message received from VF%d 0x%x\n",
342 vf_nr + 1, msg);
343 vf_info->init = false;
344 }
345 break;
346 default:
347 goto err;
348 }
349
350 if (resp && adf_iov_putmsg(accel_dev, resp, vf_nr))
351 dev_err(&GET_DEV(accel_dev), "Failed to send response to VF\n");
352
353 /* re-enable interrupt on PF from this VF */
354 adf_enable_vf2pf_interrupts(accel_dev, (1 << vf_nr));
355 return;
356err:
357 dev_dbg(&GET_DEV(accel_dev), "Unknown message from VF%d (0x%x);\n",
358 vf_nr + 1, msg);
359}
360
259void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev) 361void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev)
260{ 362{
261 struct adf_accel_vf_info *vf; 363 struct adf_accel_vf_info *vf;
diff --git a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.h b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.h
index 3ceaa3829414..5acd531a11ff 100644
--- a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.h
+++ b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.h
@@ -113,6 +113,8 @@
113#define ADF_PF2VF_VERSION_RESP_VERS_SHIFT 6 113#define ADF_PF2VF_VERSION_RESP_VERS_SHIFT 6
114#define ADF_PF2VF_VERSION_RESP_RESULT_MASK 0x0000C000 114#define ADF_PF2VF_VERSION_RESP_RESULT_MASK 0x0000C000
115#define ADF_PF2VF_VERSION_RESP_RESULT_SHIFT 14 115#define ADF_PF2VF_VERSION_RESP_RESULT_SHIFT 14
116#define ADF_PF2VF_MINORVERSION_SHIFT 6
117#define ADF_PF2VF_MAJORVERSION_SHIFT 10
116#define ADF_PF2VF_VF_COMPATIBLE 1 118#define ADF_PF2VF_VF_COMPATIBLE 1
117#define ADF_PF2VF_VF_INCOMPATIBLE 2 119#define ADF_PF2VF_VF_INCOMPATIBLE 2
118#define ADF_PF2VF_VF_COMPAT_UNKNOWN 3 120#define ADF_PF2VF_VF_COMPAT_UNKNOWN 3
diff --git a/drivers/crypto/qat/qat_common/adf_sriov.c b/drivers/crypto/qat/qat_common/adf_sriov.c
index 069b9ea55cfa..2f77a4a8cecb 100644
--- a/drivers/crypto/qat/qat_common/adf_sriov.c
+++ b/drivers/crypto/qat/qat_common/adf_sriov.c
@@ -79,125 +79,32 @@ static struct workqueue_struct *pf2vf_resp_wq;
79 ADF_CSR_WR(pmisc_bar_addr, ME2FUNCTION_MAP_B_OFFSET + \ 79 ADF_CSR_WR(pmisc_bar_addr, ME2FUNCTION_MAP_B_OFFSET + \
80 ME2FUNCTION_MAP_REG_SIZE * index, value) 80 ME2FUNCTION_MAP_REG_SIZE * index, value)
81 81
82struct adf_pf2vf_resp_data { 82struct adf_pf2vf_resp {
83 struct work_struct pf2vf_resp_work; 83 struct work_struct pf2vf_resp_work;
84 struct adf_accel_dev *accel_dev; 84 struct adf_accel_vf_info *vf_info;
85 u32 resp;
86 u8 vf_nr;
87}; 85};
88 86
89static void adf_iov_send_resp(struct work_struct *work) 87static void adf_iov_send_resp(struct work_struct *work)
90{ 88{
91 struct adf_pf2vf_resp_data *pf2vf_resp_data = 89 struct adf_pf2vf_resp *pf2vf_resp =
92 container_of(work, struct adf_pf2vf_resp_data, pf2vf_resp_work); 90 container_of(work, struct adf_pf2vf_resp, pf2vf_resp_work);
93
94 if (adf_iov_putmsg(pf2vf_resp_data->accel_dev, pf2vf_resp_data->resp,
95 pf2vf_resp_data->vf_nr)) {
96 dev_err(&GET_DEV(pf2vf_resp_data->accel_dev),
97 "Failed to send response\n");
98 }
99 91
100 kfree(pf2vf_resp_data); 92 adf_vf2pf_req_hndl(pf2vf_resp->vf_info);
93 kfree(pf2vf_resp);
101} 94}
102 95
103static void adf_vf2pf_bh_handler(void *data) 96static void adf_vf2pf_bh_handler(void *data)
104{ 97{
105 struct adf_accel_vf_info *vf_info = (struct adf_accel_vf_info *)data; 98 struct adf_accel_vf_info *vf_info = (struct adf_accel_vf_info *)data;
106 struct adf_accel_dev *accel_dev = vf_info->accel_dev; 99 struct adf_pf2vf_resp *pf2vf_resp;
107 struct adf_hw_device_data *hw_data = accel_dev->hw_device;
108 struct adf_bar *pmisc =
109 &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)];
110 void __iomem *pmisc_addr = pmisc->virt_addr;
111 u32 msg;
112
113 /* Read message from the VF */
114 msg = ADF_CSR_RD(pmisc_addr, hw_data->get_pf2vf_offset(vf_info->vf_nr));
115
116 if (!(msg & ADF_VF2PF_MSGORIGIN_SYSTEM))
117 /* Ignore legacy non-system (non-kernel) VF2PF messages */
118 goto err;
119
120 switch ((msg & ADF_VF2PF_MSGTYPE_MASK) >> ADF_VF2PF_MSGTYPE_SHIFT) {
121 case ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ:
122 {
123 u8 vf_compat_ver = msg >> ADF_VF2PF_COMPAT_VER_REQ_SHIFT;
124 struct adf_pf2vf_resp_data *pf2vf_resp_data;
125 u32 resp = (ADF_PF2VF_MSGORIGIN_SYSTEM |
126 (ADF_PF2VF_MSGTYPE_VERSION_RESP <<
127 ADF_PF2VF_MSGTYPE_SHIFT) |
128 (ADF_PFVF_COMPATIBILITY_VERSION <<
129 ADF_PF2VF_VERSION_RESP_VERS_SHIFT));
130
131 dev_dbg(&GET_DEV(accel_dev),
132 "Compatibility Version Request from VF%d vers=%u\n",
133 vf_info->vf_nr + 1, vf_compat_ver);
134
135 if (vf_compat_ver < hw_data->min_iov_compat_ver) {
136 dev_err(&GET_DEV(accel_dev),
137 "VF (vers %d) incompatible with PF (vers %d)\n",
138 vf_compat_ver, ADF_PFVF_COMPATIBILITY_VERSION);
139 resp |= ADF_PF2VF_VF_INCOMPATIBLE <<
140 ADF_PF2VF_VERSION_RESP_RESULT_SHIFT;
141 } else if (vf_compat_ver > ADF_PFVF_COMPATIBILITY_VERSION) {
142 dev_err(&GET_DEV(accel_dev),
143 "VF (vers %d) compat with PF (vers %d) unkn.\n",
144 vf_compat_ver, ADF_PFVF_COMPATIBILITY_VERSION);
145 resp |= ADF_PF2VF_VF_COMPAT_UNKNOWN <<
146 ADF_PF2VF_VERSION_RESP_RESULT_SHIFT;
147 } else {
148 dev_dbg(&GET_DEV(accel_dev),
149 "VF (vers %d) compatible with PF (vers %d)\n",
150 vf_compat_ver, ADF_PFVF_COMPATIBILITY_VERSION);
151 resp |= ADF_PF2VF_VF_COMPATIBLE <<
152 ADF_PF2VF_VERSION_RESP_RESULT_SHIFT;
153 }
154
155 pf2vf_resp_data = kzalloc(sizeof(*pf2vf_resp_data), GFP_ATOMIC);
156 if (!pf2vf_resp_data)
157 return;
158
159 pf2vf_resp_data->accel_dev = accel_dev;
160 pf2vf_resp_data->vf_nr = vf_info->vf_nr;
161 pf2vf_resp_data->resp = resp;
162 INIT_WORK(&pf2vf_resp_data->pf2vf_resp_work, adf_iov_send_resp);
163 queue_work(pf2vf_resp_wq, &pf2vf_resp_data->pf2vf_resp_work);
164 }
165 break;
166 case ADF_VF2PF_MSGTYPE_INIT:
167 {
168 dev_dbg(&GET_DEV(accel_dev),
169 "Init message received from VF%d 0x%x\n",
170 vf_info->vf_nr + 1, msg);
171 vf_info->init = true;
172 }
173 break;
174 case ADF_VF2PF_MSGTYPE_SHUTDOWN:
175 {
176 dev_dbg(&GET_DEV(accel_dev),
177 "Shutdown message received from VF%d 0x%x\n",
178 vf_info->vf_nr + 1, msg);
179 vf_info->init = false;
180 }
181 break;
182 case ADF_VF2PF_MSGTYPE_VERSION_REQ:
183 dev_err(&GET_DEV(accel_dev),
184 "Incompatible VersionRequest received from VF%d 0x%x\n",
185 vf_info->vf_nr + 1, msg);
186 break;
187 default:
188 goto err;
189 }
190 100
191 /* To ACK, clear the VF2PFINT bit */ 101 pf2vf_resp = kzalloc(sizeof(*pf2vf_resp), GFP_ATOMIC);
192 msg &= ~ADF_VF2PF_INT; 102 if (!pf2vf_resp)
193 ADF_CSR_WR(pmisc_addr, hw_data->get_pf2vf_offset(vf_info->vf_nr), msg); 103 return;
194 104
195 /* re-enable interrupt on PF from this VF */ 105 pf2vf_resp->vf_info = vf_info;
196 adf_enable_vf2pf_interrupts(accel_dev, (1 << vf_info->vf_nr)); 106 INIT_WORK(&pf2vf_resp->pf2vf_resp_work, adf_iov_send_resp);
197 return; 107 queue_work(pf2vf_resp_wq, &pf2vf_resp->pf2vf_resp_work);
198err:
199 dev_err(&GET_DEV(accel_dev), "Unknown message from VF%d (0x%x);\n",
200 vf_info->vf_nr + 1, msg);
201} 108}
202 109
203static int adf_enable_sriov(struct adf_accel_dev *accel_dev) 110static int adf_enable_sriov(struct adf_accel_dev *accel_dev)