1 /*******************************************************************************
3 * Copyright (c) 2015-2016 Intel Corporation. All rights reserved.
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenFabrics.org BSD license below:
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 *******************************************************************************/
35 #include "i40iw_osdep.h"
36 #include "i40iw_register.h"
37 #include "i40iw_status.h"
38 #include "i40iw_hmc.h"
40 #include "i40iw_type.h"
42 #include "i40iw_virtchnl.h"
45 * vchnl_vf_send_get_ver_req - Request Channel version
46 * @dev: IWARP device pointer
47 * @vchnl_req: Virtual channel message request pointer
49 static enum i40iw_status_code
vchnl_vf_send_get_ver_req(struct i40iw_sc_dev
*dev
,
50 struct i40iw_virtchnl_req
*vchnl_req
)
52 enum i40iw_status_code ret_code
= I40IW_ERR_NOT_READY
;
53 struct i40iw_virtchnl_op_buf
*vchnl_msg
= vchnl_req
->vchnl_msg
;
58 memset(vchnl_msg
, 0, sizeof(*vchnl_msg
));
59 vchnl_msg
->iw_chnl_op_ctx
= (uintptr_t)vchnl_req
;
60 vchnl_msg
->iw_chnl_buf_len
= sizeof(*vchnl_msg
);
61 vchnl_msg
->iw_op_code
= I40IW_VCHNL_OP_GET_VER
;
62 vchnl_msg
->iw_op_ver
= I40IW_VCHNL_OP_GET_VER_V0
;
63 ret_code
= dev
->vchnl_if
.vchnl_send(dev
, 0, (u8
*)vchnl_msg
, vchnl_msg
->iw_chnl_buf_len
);
65 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
66 "%s: virt channel send failed 0x%x\n", __func__
, ret_code
);
71 * vchnl_vf_send_get_hmc_fcn_req - Request HMC Function from VF
72 * @dev: IWARP device pointer
73 * @vchnl_req: Virtual channel message request pointer
75 static enum i40iw_status_code
vchnl_vf_send_get_hmc_fcn_req(struct i40iw_sc_dev
*dev
,
76 struct i40iw_virtchnl_req
*vchnl_req
)
78 enum i40iw_status_code ret_code
= I40IW_ERR_NOT_READY
;
79 struct i40iw_virtchnl_op_buf
*vchnl_msg
= vchnl_req
->vchnl_msg
;
84 memset(vchnl_msg
, 0, sizeof(*vchnl_msg
));
85 vchnl_msg
->iw_chnl_op_ctx
= (uintptr_t)vchnl_req
;
86 vchnl_msg
->iw_chnl_buf_len
= sizeof(*vchnl_msg
);
87 vchnl_msg
->iw_op_code
= I40IW_VCHNL_OP_GET_HMC_FCN
;
88 vchnl_msg
->iw_op_ver
= I40IW_VCHNL_OP_GET_HMC_FCN_V0
;
89 ret_code
= dev
->vchnl_if
.vchnl_send(dev
, 0, (u8
*)vchnl_msg
, vchnl_msg
->iw_chnl_buf_len
);
91 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
92 "%s: virt channel send failed 0x%x\n", __func__
, ret_code
);
97 * vchnl_vf_send_get_pe_stats_req - Request PE stats from VF
98 * @dev: IWARP device pointer
99 * @vchnl_req: Virtual channel message request pointer
101 static enum i40iw_status_code
vchnl_vf_send_get_pe_stats_req(struct i40iw_sc_dev
*dev
,
102 struct i40iw_virtchnl_req
*vchnl_req
)
104 enum i40iw_status_code ret_code
= I40IW_ERR_NOT_READY
;
105 struct i40iw_virtchnl_op_buf
*vchnl_msg
= vchnl_req
->vchnl_msg
;
110 memset(vchnl_msg
, 0, sizeof(*vchnl_msg
));
111 vchnl_msg
->iw_chnl_op_ctx
= (uintptr_t)vchnl_req
;
112 vchnl_msg
->iw_chnl_buf_len
= sizeof(*vchnl_msg
) + sizeof(struct i40iw_dev_hw_stats
) - 1;
113 vchnl_msg
->iw_op_code
= I40IW_VCHNL_OP_GET_STATS
;
114 vchnl_msg
->iw_op_ver
= I40IW_VCHNL_OP_GET_STATS_V0
;
115 ret_code
= dev
->vchnl_if
.vchnl_send(dev
, 0, (u8
*)vchnl_msg
, vchnl_msg
->iw_chnl_buf_len
);
117 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
118 "%s: virt channel send failed 0x%x\n", __func__
, ret_code
);
123 * vchnl_vf_send_add_hmc_objs_req - Add HMC objects
124 * @dev: IWARP device pointer
125 * @vchnl_req: Virtual channel message request pointer
127 static enum i40iw_status_code
vchnl_vf_send_add_hmc_objs_req(struct i40iw_sc_dev
*dev
,
128 struct i40iw_virtchnl_req
*vchnl_req
,
129 enum i40iw_hmc_rsrc_type rsrc_type
,
133 enum i40iw_status_code ret_code
= I40IW_ERR_NOT_READY
;
134 struct i40iw_virtchnl_op_buf
*vchnl_msg
= vchnl_req
->vchnl_msg
;
135 struct i40iw_virtchnl_hmc_obj_range
*add_hmc_obj
;
140 add_hmc_obj
= (struct i40iw_virtchnl_hmc_obj_range
*)vchnl_msg
->iw_chnl_buf
;
141 memset(vchnl_msg
, 0, sizeof(*vchnl_msg
));
142 memset(add_hmc_obj
, 0, sizeof(*add_hmc_obj
));
143 vchnl_msg
->iw_chnl_op_ctx
= (uintptr_t)vchnl_req
;
144 vchnl_msg
->iw_chnl_buf_len
= sizeof(*vchnl_msg
) + sizeof(struct i40iw_virtchnl_hmc_obj_range
) - 1;
145 vchnl_msg
->iw_op_code
= I40IW_VCHNL_OP_ADD_HMC_OBJ_RANGE
;
146 vchnl_msg
->iw_op_ver
= I40IW_VCHNL_OP_ADD_HMC_OBJ_RANGE_V0
;
147 add_hmc_obj
->obj_type
= (u16
)rsrc_type
;
148 add_hmc_obj
->start_index
= start_index
;
149 add_hmc_obj
->obj_count
= rsrc_count
;
150 ret_code
= dev
->vchnl_if
.vchnl_send(dev
, 0, (u8
*)vchnl_msg
, vchnl_msg
->iw_chnl_buf_len
);
152 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
153 "%s: virt channel send failed 0x%x\n", __func__
, ret_code
);
158 * vchnl_vf_send_del_hmc_objs_req - del HMC objects
159 * @dev: IWARP device pointer
160 * @vchnl_req: Virtual channel message request pointer
161 * @ rsrc_type - resource type to delete
162 * @ start_index - starting index for resource
163 * @ rsrc_count - number of resource type to delete
165 static enum i40iw_status_code
vchnl_vf_send_del_hmc_objs_req(struct i40iw_sc_dev
*dev
,
166 struct i40iw_virtchnl_req
*vchnl_req
,
167 enum i40iw_hmc_rsrc_type rsrc_type
,
171 enum i40iw_status_code ret_code
= I40IW_ERR_NOT_READY
;
172 struct i40iw_virtchnl_op_buf
*vchnl_msg
= vchnl_req
->vchnl_msg
;
173 struct i40iw_virtchnl_hmc_obj_range
*add_hmc_obj
;
178 add_hmc_obj
= (struct i40iw_virtchnl_hmc_obj_range
*)vchnl_msg
->iw_chnl_buf
;
179 memset(vchnl_msg
, 0, sizeof(*vchnl_msg
));
180 memset(add_hmc_obj
, 0, sizeof(*add_hmc_obj
));
181 vchnl_msg
->iw_chnl_op_ctx
= (uintptr_t)vchnl_req
;
182 vchnl_msg
->iw_chnl_buf_len
= sizeof(*vchnl_msg
) + sizeof(struct i40iw_virtchnl_hmc_obj_range
) - 1;
183 vchnl_msg
->iw_op_code
= I40IW_VCHNL_OP_DEL_HMC_OBJ_RANGE
;
184 vchnl_msg
->iw_op_ver
= I40IW_VCHNL_OP_DEL_HMC_OBJ_RANGE_V0
;
185 add_hmc_obj
->obj_type
= (u16
)rsrc_type
;
186 add_hmc_obj
->start_index
= start_index
;
187 add_hmc_obj
->obj_count
= rsrc_count
;
188 ret_code
= dev
->vchnl_if
.vchnl_send(dev
, 0, (u8
*)vchnl_msg
, vchnl_msg
->iw_chnl_buf_len
);
190 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
191 "%s: virt channel send failed 0x%x\n", __func__
, ret_code
);
196 * vchnl_pf_send_get_ver_resp - Send channel version to VF
197 * @dev: IWARP device pointer
198 * @vf_id: Virtual function ID associated with the message
199 * @vchnl_msg: Virtual channel message buffer pointer
201 static void vchnl_pf_send_get_ver_resp(struct i40iw_sc_dev
*dev
,
203 struct i40iw_virtchnl_op_buf
*vchnl_msg
)
205 enum i40iw_status_code ret_code
;
206 u8 resp_buffer
[sizeof(struct i40iw_virtchnl_resp_buf
) + sizeof(u32
) - 1];
207 struct i40iw_virtchnl_resp_buf
*vchnl_msg_resp
= (struct i40iw_virtchnl_resp_buf
*)resp_buffer
;
209 memset(resp_buffer
, 0, sizeof(*resp_buffer
));
210 vchnl_msg_resp
->iw_chnl_op_ctx
= vchnl_msg
->iw_chnl_op_ctx
;
211 vchnl_msg_resp
->iw_chnl_buf_len
= sizeof(resp_buffer
);
212 vchnl_msg_resp
->iw_op_ret_code
= I40IW_SUCCESS
;
213 *((u32
*)vchnl_msg_resp
->iw_chnl_buf
) = I40IW_VCHNL_CHNL_VER_V0
;
214 ret_code
= dev
->vchnl_if
.vchnl_send(dev
, vf_id
, resp_buffer
, sizeof(resp_buffer
));
216 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
217 "%s: virt channel send failed 0x%x\n", __func__
, ret_code
);
221 * vchnl_pf_send_get_hmc_fcn_resp - Send HMC Function to VF
222 * @dev: IWARP device pointer
223 * @vf_id: Virtual function ID associated with the message
224 * @vchnl_msg: Virtual channel message buffer pointer
226 static void vchnl_pf_send_get_hmc_fcn_resp(struct i40iw_sc_dev
*dev
,
228 struct i40iw_virtchnl_op_buf
*vchnl_msg
,
231 enum i40iw_status_code ret_code
;
232 u8 resp_buffer
[sizeof(struct i40iw_virtchnl_resp_buf
) + sizeof(u16
) - 1];
233 struct i40iw_virtchnl_resp_buf
*vchnl_msg_resp
= (struct i40iw_virtchnl_resp_buf
*)resp_buffer
;
235 memset(resp_buffer
, 0, sizeof(*resp_buffer
));
236 vchnl_msg_resp
->iw_chnl_op_ctx
= vchnl_msg
->iw_chnl_op_ctx
;
237 vchnl_msg_resp
->iw_chnl_buf_len
= sizeof(resp_buffer
);
238 vchnl_msg_resp
->iw_op_ret_code
= I40IW_SUCCESS
;
239 *((u16
*)vchnl_msg_resp
->iw_chnl_buf
) = hmc_fcn
;
240 ret_code
= dev
->vchnl_if
.vchnl_send(dev
, vf_id
, resp_buffer
, sizeof(resp_buffer
));
242 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
243 "%s: virt channel send failed 0x%x\n", __func__
, ret_code
);
247 * vchnl_pf_send_get_pe_stats_resp - Send PE Stats to VF
248 * @dev: IWARP device pointer
249 * @vf_id: Virtual function ID associated with the message
250 * @vchnl_msg: Virtual channel message buffer pointer
251 * @hw_stats: HW Stats struct
254 static void vchnl_pf_send_get_pe_stats_resp(struct i40iw_sc_dev
*dev
,
256 struct i40iw_virtchnl_op_buf
*vchnl_msg
,
257 struct i40iw_dev_hw_stats hw_stats
)
259 enum i40iw_status_code ret_code
;
260 u8 resp_buffer
[sizeof(struct i40iw_virtchnl_resp_buf
) + sizeof(struct i40iw_dev_hw_stats
) - 1];
261 struct i40iw_virtchnl_resp_buf
*vchnl_msg_resp
= (struct i40iw_virtchnl_resp_buf
*)resp_buffer
;
263 memset(resp_buffer
, 0, sizeof(*resp_buffer
));
264 vchnl_msg_resp
->iw_chnl_op_ctx
= vchnl_msg
->iw_chnl_op_ctx
;
265 vchnl_msg_resp
->iw_chnl_buf_len
= sizeof(resp_buffer
);
266 vchnl_msg_resp
->iw_op_ret_code
= I40IW_SUCCESS
;
267 *((struct i40iw_dev_hw_stats
*)vchnl_msg_resp
->iw_chnl_buf
) = hw_stats
;
268 ret_code
= dev
->vchnl_if
.vchnl_send(dev
, vf_id
, resp_buffer
, sizeof(resp_buffer
));
270 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
271 "%s: virt channel send failed 0x%x\n", __func__
, ret_code
);
275 * vchnl_pf_send_error_resp - Send an error response to VF
276 * @dev: IWARP device pointer
277 * @vf_id: Virtual function ID associated with the message
278 * @vchnl_msg: Virtual channel message buffer pointer
280 static void vchnl_pf_send_error_resp(struct i40iw_sc_dev
*dev
, u32 vf_id
,
281 struct i40iw_virtchnl_op_buf
*vchnl_msg
,
284 enum i40iw_status_code ret_code
;
285 u8 resp_buffer
[sizeof(struct i40iw_virtchnl_resp_buf
)];
286 struct i40iw_virtchnl_resp_buf
*vchnl_msg_resp
= (struct i40iw_virtchnl_resp_buf
*)resp_buffer
;
288 memset(resp_buffer
, 0, sizeof(resp_buffer
));
289 vchnl_msg_resp
->iw_chnl_op_ctx
= vchnl_msg
->iw_chnl_op_ctx
;
290 vchnl_msg_resp
->iw_chnl_buf_len
= sizeof(resp_buffer
);
291 vchnl_msg_resp
->iw_op_ret_code
= (u16
)op_ret_code
;
292 ret_code
= dev
->vchnl_if
.vchnl_send(dev
, vf_id
, resp_buffer
, sizeof(resp_buffer
));
294 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
295 "%s: virt channel send failed 0x%x\n", __func__
, ret_code
);
299 * pf_cqp_get_hmc_fcn_callback - Callback for Get HMC Fcn
300 * @cqp_req_param: CQP Request param value
301 * @not_used: unused CQP callback parameter
303 static void pf_cqp_get_hmc_fcn_callback(struct i40iw_sc_dev
*dev
, void *callback_param
,
304 struct i40iw_ccq_cqe_info
*cqe_info
)
306 struct i40iw_vfdev
*vf_dev
= callback_param
;
307 struct i40iw_virt_mem vf_dev_mem
;
309 if (cqe_info
->error
) {
310 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
311 "CQP Completion Error on Get HMC Function. Maj = 0x%04x, Minor = 0x%04x\n",
312 cqe_info
->maj_err_code
, cqe_info
->min_err_code
);
313 dev
->vf_dev
[vf_dev
->iw_vf_idx
] = NULL
;
314 vchnl_pf_send_error_resp(dev
, vf_dev
->vf_id
, &vf_dev
->vf_msg_buffer
.vchnl_msg
,
315 (u16
)I40IW_ERR_CQP_COMPL_ERROR
);
316 vf_dev_mem
.va
= vf_dev
;
317 vf_dev_mem
.size
= sizeof(*vf_dev
);
318 i40iw_free_virt_mem(dev
->hw
, &vf_dev_mem
);
320 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
321 "CQP Completion Operation Return information = 0x%08x\n",
322 cqe_info
->op_ret_val
);
323 vf_dev
->pmf_index
= (u16
)cqe_info
->op_ret_val
;
325 vchnl_pf_send_get_hmc_fcn_resp(dev
,
327 &vf_dev
->vf_msg_buffer
.vchnl_msg
,
333 * pf_add_hmc_obj - Callback for Add HMC Object
334 * @vf_dev: pointer to the VF Device
336 static void pf_add_hmc_obj_callback(void *work_vf_dev
)
338 struct i40iw_vfdev
*vf_dev
= (struct i40iw_vfdev
*)work_vf_dev
;
339 struct i40iw_hmc_info
*hmc_info
= &vf_dev
->hmc_info
;
340 struct i40iw_virtchnl_op_buf
*vchnl_msg
= &vf_dev
->vf_msg_buffer
.vchnl_msg
;
341 struct i40iw_hmc_create_obj_info info
;
342 struct i40iw_virtchnl_hmc_obj_range
*add_hmc_obj
;
343 enum i40iw_status_code ret_code
;
345 if (!vf_dev
->pf_hmc_initialized
) {
346 ret_code
= i40iw_pf_init_vfhmc(vf_dev
->pf_dev
, (u8
)vf_dev
->pmf_index
, NULL
);
349 vf_dev
->pf_hmc_initialized
= true;
352 add_hmc_obj
= (struct i40iw_virtchnl_hmc_obj_range
*)vchnl_msg
->iw_chnl_buf
;
354 memset(&info
, 0, sizeof(info
));
355 info
.hmc_info
= hmc_info
;
357 info
.rsrc_type
= (u32
)add_hmc_obj
->obj_type
;
358 info
.entry_type
= (info
.rsrc_type
== I40IW_HMC_IW_PBLE
) ? I40IW_SD_TYPE_PAGED
: I40IW_SD_TYPE_DIRECT
;
359 info
.start_idx
= add_hmc_obj
->start_index
;
360 info
.count
= add_hmc_obj
->obj_count
;
361 i40iw_debug(vf_dev
->pf_dev
, I40IW_DEBUG_VIRT
,
362 "I40IW_VCHNL_OP_ADD_HMC_OBJ_RANGE. Add %u type %u objects\n",
363 info
.count
, info
.rsrc_type
);
364 ret_code
= i40iw_sc_create_hmc_obj(vf_dev
->pf_dev
, &info
);
366 vf_dev
->hmc_info
.hmc_obj
[add_hmc_obj
->obj_type
].cnt
= add_hmc_obj
->obj_count
;
369 vchnl_pf_send_error_resp(vf_dev
->pf_dev
, vf_dev
->vf_id
, vchnl_msg
, (u16
)ret_code
);
373 * pf_del_hmc_obj_callback - Callback for delete HMC Object
374 * @work_vf_dev: pointer to the VF Device
376 static void pf_del_hmc_obj_callback(void *work_vf_dev
)
378 struct i40iw_vfdev
*vf_dev
= (struct i40iw_vfdev
*)work_vf_dev
;
379 struct i40iw_hmc_info
*hmc_info
= &vf_dev
->hmc_info
;
380 struct i40iw_virtchnl_op_buf
*vchnl_msg
= &vf_dev
->vf_msg_buffer
.vchnl_msg
;
381 struct i40iw_hmc_del_obj_info info
;
382 struct i40iw_virtchnl_hmc_obj_range
*del_hmc_obj
;
383 enum i40iw_status_code ret_code
= I40IW_SUCCESS
;
385 if (!vf_dev
->pf_hmc_initialized
)
388 del_hmc_obj
= (struct i40iw_virtchnl_hmc_obj_range
*)vchnl_msg
->iw_chnl_buf
;
390 memset(&info
, 0, sizeof(info
));
391 info
.hmc_info
= hmc_info
;
393 info
.rsrc_type
= (u32
)del_hmc_obj
->obj_type
;
394 info
.start_idx
= del_hmc_obj
->start_index
;
395 info
.count
= del_hmc_obj
->obj_count
;
396 i40iw_debug(vf_dev
->pf_dev
, I40IW_DEBUG_VIRT
,
397 "I40IW_VCHNL_OP_DEL_HMC_OBJ_RANGE. Delete %u type %u objects\n",
398 info
.count
, info
.rsrc_type
);
399 ret_code
= i40iw_sc_del_hmc_obj(vf_dev
->pf_dev
, &info
, false);
402 vchnl_pf_send_error_resp(vf_dev
->pf_dev
, vf_dev
->vf_id
, vchnl_msg
, (u16
)ret_code
);
406 * i40iw_vchnl_recv_pf - Receive PF virtual channel messages
407 * @dev: IWARP device pointer
408 * @vf_id: Virtual function ID associated with the message
409 * @msg: Virtual channel message buffer pointer
410 * @len: Length of the virtual channels message
412 enum i40iw_status_code
i40iw_vchnl_recv_pf(struct i40iw_sc_dev
*dev
,
417 struct i40iw_virtchnl_op_buf
*vchnl_msg
= (struct i40iw_virtchnl_op_buf
*)msg
;
418 struct i40iw_vfdev
*vf_dev
= NULL
;
419 struct i40iw_hmc_fcn_info hmc_fcn_info
;
421 u16 first_avail_iw_vf
= I40IW_MAX_PE_ENABLED_VF_COUNT
;
422 struct i40iw_virt_mem vf_dev_mem
;
423 struct i40iw_virtchnl_work_info work_info
;
424 struct i40iw_dev_pestat
*devstat
;
425 enum i40iw_status_code ret_code
;
428 if (!dev
|| !msg
|| !len
)
429 return I40IW_ERR_PARAM
;
432 return I40IW_ERR_NOT_READY
;
433 if (vchnl_msg
->iw_op_code
== I40IW_VCHNL_OP_GET_VER
) {
434 if (vchnl_msg
->iw_op_ver
!= I40IW_VCHNL_OP_GET_VER_V0
)
435 vchnl_pf_send_get_ver_resp(dev
, vf_id
, vchnl_msg
);
437 vchnl_pf_send_get_ver_resp(dev
, vf_id
, vchnl_msg
);
438 return I40IW_SUCCESS
;
440 for (iw_vf_idx
= 0; iw_vf_idx
< I40IW_MAX_PE_ENABLED_VF_COUNT
;
442 if (!dev
->vf_dev
[iw_vf_idx
]) {
443 if (first_avail_iw_vf
==
444 I40IW_MAX_PE_ENABLED_VF_COUNT
)
445 first_avail_iw_vf
= iw_vf_idx
;
448 if (dev
->vf_dev
[iw_vf_idx
]->vf_id
== vf_id
) {
449 vf_dev
= dev
->vf_dev
[iw_vf_idx
];
454 if (!vf_dev
->msg_count
) {
457 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
458 "VF%u already has a channel message in progress.\n",
460 return I40IW_SUCCESS
;
463 switch (vchnl_msg
->iw_op_code
) {
464 case I40IW_VCHNL_OP_GET_HMC_FCN
:
466 (first_avail_iw_vf
!= I40IW_MAX_PE_ENABLED_VF_COUNT
)) {
467 ret_code
= i40iw_allocate_virt_mem(dev
->hw
, &vf_dev_mem
, sizeof(struct i40iw_vfdev
) +
468 (sizeof(struct i40iw_hmc_obj_info
) * I40IW_HMC_IW_MAX
));
470 vf_dev
= vf_dev_mem
.va
;
471 vf_dev
->stats_initialized
= false;
472 vf_dev
->pf_dev
= dev
;
473 vf_dev
->msg_count
= 1;
474 vf_dev
->vf_id
= vf_id
;
475 vf_dev
->iw_vf_idx
= first_avail_iw_vf
;
476 vf_dev
->pf_hmc_initialized
= false;
477 vf_dev
->hmc_info
.hmc_obj
= (struct i40iw_hmc_obj_info
*)(&vf_dev
[1]);
478 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
479 "vf_dev %p, hmc_info %p, hmc_obj %p\n",
480 vf_dev
, &vf_dev
->hmc_info
, vf_dev
->hmc_info
.hmc_obj
);
481 dev
->vf_dev
[first_avail_iw_vf
] = vf_dev
;
482 iw_vf_idx
= first_avail_iw_vf
;
484 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
485 "VF%u Unable to allocate a VF device structure.\n",
487 vchnl_pf_send_error_resp(dev
, vf_id
, vchnl_msg
, (u16
)I40IW_ERR_NO_MEMORY
);
488 return I40IW_SUCCESS
;
490 memcpy(&vf_dev
->vf_msg_buffer
.vchnl_msg
, vchnl_msg
, len
);
491 hmc_fcn_info
.callback_fcn
= pf_cqp_get_hmc_fcn_callback
;
492 hmc_fcn_info
.vf_id
= vf_id
;
493 hmc_fcn_info
.iw_vf_idx
= vf_dev
->iw_vf_idx
;
494 hmc_fcn_info
.cqp_callback_param
= vf_dev
;
495 hmc_fcn_info
.free_fcn
= false;
496 ret_code
= i40iw_cqp_manage_hmc_fcn_cmd(dev
, &hmc_fcn_info
);
498 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
499 "VF%u error CQP HMC Function operation.\n",
501 ret_code
= i40iw_device_init_pestat(&vf_dev
->dev_pestat
);
503 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
504 "VF%u - i40iw_device_init_pestat failed\n",
506 vf_dev
->dev_pestat
.ops
.iw_hw_stat_init(&vf_dev
->dev_pestat
,
507 (u8
)vf_dev
->pmf_index
,
509 vf_dev
->stats_initialized
= true;
513 vchnl_pf_send_get_hmc_fcn_resp(dev
, vf_id
, vchnl_msg
, vf_dev
->pmf_index
);
515 vchnl_pf_send_error_resp(dev
, vf_id
, vchnl_msg
,
516 (u16
)I40IW_ERR_NO_MEMORY
);
520 case I40IW_VCHNL_OP_ADD_HMC_OBJ_RANGE
:
522 return I40IW_ERR_BAD_PTR
;
523 work_info
.worker_vf_dev
= vf_dev
;
524 work_info
.callback_fcn
= pf_add_hmc_obj_callback
;
525 memcpy(&vf_dev
->vf_msg_buffer
.vchnl_msg
, vchnl_msg
, len
);
526 i40iw_cqp_spawn_worker(dev
, &work_info
, vf_dev
->iw_vf_idx
);
528 case I40IW_VCHNL_OP_DEL_HMC_OBJ_RANGE
:
530 return I40IW_ERR_BAD_PTR
;
531 work_info
.worker_vf_dev
= vf_dev
;
532 work_info
.callback_fcn
= pf_del_hmc_obj_callback
;
533 memcpy(&vf_dev
->vf_msg_buffer
.vchnl_msg
, vchnl_msg
, len
);
534 i40iw_cqp_spawn_worker(dev
, &work_info
, vf_dev
->iw_vf_idx
);
536 case I40IW_VCHNL_OP_GET_STATS
:
538 return I40IW_ERR_BAD_PTR
;
539 devstat
= &vf_dev
->dev_pestat
;
540 spin_lock_irqsave(&dev
->dev_pestat
.stats_lock
, flags
);
541 devstat
->ops
.iw_hw_stat_read_all(devstat
, &devstat
->hw_stats
);
542 spin_unlock_irqrestore(&dev
->dev_pestat
.stats_lock
, flags
);
544 vchnl_pf_send_get_pe_stats_resp(dev
, vf_id
, vchnl_msg
, devstat
->hw_stats
);
547 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
548 "40iw_vchnl_recv_pf: Invalid OpCode 0x%x\n",
549 vchnl_msg
->iw_op_code
);
550 vchnl_pf_send_error_resp(dev
, vf_id
,
551 vchnl_msg
, (u16
)I40IW_ERR_NOT_IMPLEMENTED
);
553 return I40IW_SUCCESS
;
557 * i40iw_vchnl_recv_vf - Receive VF virtual channel messages
558 * @dev: IWARP device pointer
559 * @vf_id: Virtual function ID associated with the message
560 * @msg: Virtual channel message buffer pointer
561 * @len: Length of the virtual channels message
563 enum i40iw_status_code
i40iw_vchnl_recv_vf(struct i40iw_sc_dev
*dev
,
568 struct i40iw_virtchnl_resp_buf
*vchnl_msg_resp
= (struct i40iw_virtchnl_resp_buf
*)msg
;
569 struct i40iw_virtchnl_req
*vchnl_req
;
571 vchnl_req
= (struct i40iw_virtchnl_req
*)(uintptr_t)vchnl_msg_resp
->iw_chnl_op_ctx
;
572 vchnl_req
->ret_code
= (enum i40iw_status_code
)vchnl_msg_resp
->iw_op_ret_code
;
573 if (len
== (sizeof(*vchnl_msg_resp
) + vchnl_req
->parm_len
- 1)) {
574 if (vchnl_req
->parm_len
&& vchnl_req
->parm
)
575 memcpy(vchnl_req
->parm
, vchnl_msg_resp
->iw_chnl_buf
, vchnl_req
->parm_len
);
576 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
577 "%s: Got response, data size %u\n", __func__
,
578 vchnl_req
->parm_len
);
580 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
581 "%s: error length on response, Got %u, expected %u\n", __func__
,
582 len
, (u32
)(sizeof(*vchnl_msg_resp
) + vchnl_req
->parm_len
- 1));
585 return I40IW_SUCCESS
;
589 * i40iw_vchnl_vf_get_ver - Request Channel version
590 * @dev: IWARP device pointer
591 * @vchnl_ver: Virtual channel message version pointer
593 enum i40iw_status_code
i40iw_vchnl_vf_get_ver(struct i40iw_sc_dev
*dev
,
596 struct i40iw_virtchnl_req vchnl_req
;
597 enum i40iw_status_code ret_code
;
599 memset(&vchnl_req
, 0, sizeof(vchnl_req
));
601 vchnl_req
.parm
= vchnl_ver
;
602 vchnl_req
.parm_len
= sizeof(*vchnl_ver
);
603 vchnl_req
.vchnl_msg
= &dev
->vchnl_vf_msg_buf
.vchnl_msg
;
604 ret_code
= vchnl_vf_send_get_ver_req(dev
, &vchnl_req
);
606 ret_code
= i40iw_vf_wait_vchnl_resp(dev
);
608 ret_code
= vchnl_req
.ret_code
;
610 dev
->vchnl_up
= false;
612 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
613 "%s Send message failed 0x%0x\n", __func__
, ret_code
);
619 * i40iw_vchnl_vf_get_hmc_fcn - Request HMC Function
620 * @dev: IWARP device pointer
621 * @hmc_fcn: HMC function index pointer
623 enum i40iw_status_code
i40iw_vchnl_vf_get_hmc_fcn(struct i40iw_sc_dev
*dev
,
626 struct i40iw_virtchnl_req vchnl_req
;
627 enum i40iw_status_code ret_code
;
629 memset(&vchnl_req
, 0, sizeof(vchnl_req
));
631 vchnl_req
.parm
= hmc_fcn
;
632 vchnl_req
.parm_len
= sizeof(*hmc_fcn
);
633 vchnl_req
.vchnl_msg
= &dev
->vchnl_vf_msg_buf
.vchnl_msg
;
634 ret_code
= vchnl_vf_send_get_hmc_fcn_req(dev
, &vchnl_req
);
636 ret_code
= i40iw_vf_wait_vchnl_resp(dev
);
638 ret_code
= vchnl_req
.ret_code
;
640 dev
->vchnl_up
= false;
642 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
643 "%s Send message failed 0x%0x\n", __func__
, ret_code
);
649 * i40iw_vchnl_vf_add_hmc_objs - Add HMC Object
650 * @dev: IWARP device pointer
651 * @rsrc_type: HMC Resource type
652 * @start_index: Starting index of the objects to be added
653 * @rsrc_count: Number of resources to be added
655 enum i40iw_status_code
i40iw_vchnl_vf_add_hmc_objs(struct i40iw_sc_dev
*dev
,
656 enum i40iw_hmc_rsrc_type rsrc_type
,
660 struct i40iw_virtchnl_req vchnl_req
;
661 enum i40iw_status_code ret_code
;
663 memset(&vchnl_req
, 0, sizeof(vchnl_req
));
665 vchnl_req
.vchnl_msg
= &dev
->vchnl_vf_msg_buf
.vchnl_msg
;
666 ret_code
= vchnl_vf_send_add_hmc_objs_req(dev
,
672 ret_code
= i40iw_vf_wait_vchnl_resp(dev
);
674 ret_code
= vchnl_req
.ret_code
;
676 dev
->vchnl_up
= false;
678 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
679 "%s Send message failed 0x%0x\n", __func__
, ret_code
);
685 * i40iw_vchnl_vf_del_hmc_obj - del HMC obj
686 * @dev: IWARP device pointer
687 * @rsrc_type: HMC Resource type
688 * @start_index: Starting index of the object to delete
689 * @rsrc_count: Number of resources to be delete
691 enum i40iw_status_code
i40iw_vchnl_vf_del_hmc_obj(struct i40iw_sc_dev
*dev
,
692 enum i40iw_hmc_rsrc_type rsrc_type
,
696 struct i40iw_virtchnl_req vchnl_req
;
697 enum i40iw_status_code ret_code
;
699 memset(&vchnl_req
, 0, sizeof(vchnl_req
));
701 vchnl_req
.vchnl_msg
= &dev
->vchnl_vf_msg_buf
.vchnl_msg
;
702 ret_code
= vchnl_vf_send_del_hmc_objs_req(dev
,
708 ret_code
= i40iw_vf_wait_vchnl_resp(dev
);
710 ret_code
= vchnl_req
.ret_code
;
712 dev
->vchnl_up
= false;
714 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
715 "%s Send message failed 0x%0x\n", __func__
, ret_code
);
721 * i40iw_vchnl_vf_get_pe_stats - Get PE stats
722 * @dev: IWARP device pointer
723 * @hw_stats: HW stats struct
725 enum i40iw_status_code
i40iw_vchnl_vf_get_pe_stats(struct i40iw_sc_dev
*dev
,
726 struct i40iw_dev_hw_stats
*hw_stats
)
728 struct i40iw_virtchnl_req vchnl_req
;
729 enum i40iw_status_code ret_code
;
731 memset(&vchnl_req
, 0, sizeof(vchnl_req
));
733 vchnl_req
.parm
= hw_stats
;
734 vchnl_req
.parm_len
= sizeof(*hw_stats
);
735 vchnl_req
.vchnl_msg
= &dev
->vchnl_vf_msg_buf
.vchnl_msg
;
736 ret_code
= vchnl_vf_send_get_pe_stats_req(dev
, &vchnl_req
);
738 ret_code
= i40iw_vf_wait_vchnl_resp(dev
);
740 ret_code
= vchnl_req
.ret_code
;
742 dev
->vchnl_up
= false;
744 i40iw_debug(dev
, I40IW_DEBUG_VIRT
,
745 "%s Send message failed 0x%0x\n", __func__
, ret_code
);