Lines Matching +full:rpc +full:- +full:if

1 // SPDX-License-Identifier: GPL-2.0
43 struct pdsfc_dev *pdsfc = container_of(uctx->fwctl, struct pdsfc_dev, fwctl); in pdsfc_open_uctx()
46 pdsfc_uctx->uctx_caps = pdsfc->caps; in pdsfc_open_uctx()
61 if (!info) in pdsfc_info()
62 return ERR_PTR(-ENOMEM); in pdsfc_info()
64 info->uctx_caps = pdsfc_uctx->uctx_caps; in pdsfc_info()
71 struct device *dev = &pdsfc->fwctl.dev; in pdsfc_identify()
78 ident = dma_alloc_coherent(dev->parent, sizeof(*ident), &ident_pa, GFP_KERNEL); in pdsfc_identify()
79 if (!ident) { in pdsfc_identify()
81 return -ENOMEM; in pdsfc_identify()
93 err = pds_client_adminq_cmd(pdsfc->padev, &cmd, sizeof(cmd), &comp, 0); in pdsfc_identify()
94 if (err) in pdsfc_identify()
98 pdsfc->ident = *ident; in pdsfc_identify()
100 dma_free_coherent(dev->parent, sizeof(*ident), ident, ident_pa); in pdsfc_identify()
107 struct device *dev = &pdsfc->fwctl.dev; in pdsfc_free_endpoints()
111 if (!pdsfc->endpoints) in pdsfc_free_endpoints()
114 num_endpoints = le32_to_cpu(pdsfc->endpoints->num_entries); in pdsfc_free_endpoints()
115 for (i = 0; pdsfc->endpoint_info && i < num_endpoints; i++) in pdsfc_free_endpoints()
116 mutex_destroy(&pdsfc->endpoint_info[i].lock); in pdsfc_free_endpoints()
117 vfree(pdsfc->endpoint_info); in pdsfc_free_endpoints()
118 pdsfc->endpoint_info = NULL; in pdsfc_free_endpoints()
119 dma_free_coherent(dev->parent, PAGE_SIZE, in pdsfc_free_endpoints()
120 pdsfc->endpoints, pdsfc->endpoints_pa); in pdsfc_free_endpoints()
121 pdsfc->endpoints = NULL; in pdsfc_free_endpoints()
122 pdsfc->endpoints_pa = DMA_MAPPING_ERROR; in pdsfc_free_endpoints()
127 struct device *dev = &pdsfc->fwctl.dev; in pdsfc_free_operations()
131 num_endpoints = le32_to_cpu(pdsfc->endpoints->num_entries); in pdsfc_free_operations()
133 struct pdsfc_rpc_endpoint_info *ei = &pdsfc->endpoint_info[i]; in pdsfc_free_operations()
135 if (ei->operations) { in pdsfc_free_operations()
136 dma_free_coherent(dev->parent, PAGE_SIZE, in pdsfc_free_operations()
137 ei->operations, ei->operations_pa); in pdsfc_free_operations()
138 ei->operations = NULL; in pdsfc_free_operations()
139 ei->operations_pa = DMA_MAPPING_ERROR; in pdsfc_free_operations()
147 struct device *dev = &pdsfc->fwctl.dev; in pdsfc_get_endpoints()
154 data = dma_alloc_coherent(dev->parent, PAGE_SIZE, &data_pa, GFP_KERNEL); in pdsfc_get_endpoints()
155 if (!data) { in pdsfc_get_endpoints()
157 return ERR_PTR(-ENOMEM); in pdsfc_get_endpoints()
170 err = pds_client_adminq_cmd(pdsfc->padev, &cmd, sizeof(cmd), &comp, 0); in pdsfc_get_endpoints()
171 if (err) { in pdsfc_get_endpoints()
174 dma_free_coherent(dev->parent, PAGE_SIZE, data, data_pa); in pdsfc_get_endpoints()
189 pdsfc->endpoints = pdsfc_get_endpoints(pdsfc, &pdsfc->endpoints_pa); in pdsfc_init_endpoints()
190 if (IS_ERR(pdsfc->endpoints)) in pdsfc_init_endpoints()
191 return PTR_ERR(pdsfc->endpoints); in pdsfc_init_endpoints()
193 num_endpoints = le32_to_cpu(pdsfc->endpoints->num_entries); in pdsfc_init_endpoints()
194 pdsfc->endpoint_info = vcalloc(num_endpoints, in pdsfc_init_endpoints()
195 sizeof(*pdsfc->endpoint_info)); in pdsfc_init_endpoints()
196 if (!pdsfc->endpoint_info) { in pdsfc_init_endpoints()
198 return -ENOMEM; in pdsfc_init_endpoints()
201 ep_entry = (struct pds_fwctl_query_data_endpoint *)pdsfc->endpoints->entries; in pdsfc_init_endpoints()
203 mutex_init(&pdsfc->endpoint_info[i].lock); in pdsfc_init_endpoints()
204 pdsfc->endpoint_info[i].endpoint = le32_to_cpu(ep_entry[i].id); in pdsfc_init_endpoints()
214 struct device *dev = &pdsfc->fwctl.dev; in pdsfc_get_operations()
224 data = dma_alloc_coherent(dev->parent, PAGE_SIZE, &data_pa, GFP_KERNEL); in pdsfc_get_operations()
225 if (!data) { in pdsfc_get_operations()
227 return ERR_PTR(-ENOMEM); in pdsfc_get_operations()
241 err = pds_client_adminq_cmd(pdsfc->padev, &cmd, sizeof(cmd), &comp, 0); in pdsfc_get_operations()
242 if (err) { in pdsfc_get_operations()
245 dma_free_coherent(dev->parent, PAGE_SIZE, data, data_pa); in pdsfc_get_operations()
251 entries = (struct pds_fwctl_query_data_operation *)data->entries; in pdsfc_get_operations()
252 num_entries = le32_to_cpu(data->num_entries); in pdsfc_get_operations()
281 struct fwctl_rpc_pds *rpc, in pdsfc_validate_rpc() argument
286 struct device *dev = &pdsfc->fwctl.dev; in pdsfc_validate_rpc()
290 /* validate rpc in_len & out_len based in pdsfc_validate_rpc()
293 if (rpc->in.len > le32_to_cpu(pdsfc->ident.max_req_sz)) { in pdsfc_validate_rpc()
295 rpc->in.len, le32_to_cpu(pdsfc->ident.max_req_sz)); in pdsfc_validate_rpc()
296 return -EINVAL; in pdsfc_validate_rpc()
299 if (rpc->out.len > le32_to_cpu(pdsfc->ident.max_resp_sz)) { in pdsfc_validate_rpc()
301 rpc->out.len, le32_to_cpu(pdsfc->ident.max_resp_sz)); in pdsfc_validate_rpc()
302 return -EINVAL; in pdsfc_validate_rpc()
305 num_entries = le32_to_cpu(pdsfc->endpoints->num_entries); in pdsfc_validate_rpc()
307 if (pdsfc->endpoint_info[i].endpoint == rpc->in.ep) { in pdsfc_validate_rpc()
308 ep_info = &pdsfc->endpoint_info[i]; in pdsfc_validate_rpc()
312 if (!ep_info) { in pdsfc_validate_rpc()
313 dev_dbg(dev, "Invalid endpoint %d\n", rpc->in.ep); in pdsfc_validate_rpc()
314 return -EINVAL; in pdsfc_validate_rpc()
318 mutex_lock(&ep_info->lock); in pdsfc_validate_rpc()
319 if (!ep_info->operations) { in pdsfc_validate_rpc()
323 &ep_info->operations_pa, in pdsfc_validate_rpc()
324 rpc->in.ep); in pdsfc_validate_rpc()
325 if (IS_ERR(operations)) { in pdsfc_validate_rpc()
326 mutex_unlock(&ep_info->lock); in pdsfc_validate_rpc()
327 return -ENOMEM; in pdsfc_validate_rpc()
329 ep_info->operations = operations; in pdsfc_validate_rpc()
331 mutex_unlock(&ep_info->lock); in pdsfc_validate_rpc()
334 op_entry = (struct pds_fwctl_query_data_operation *)ep_info->operations->entries; in pdsfc_validate_rpc()
335 num_entries = le32_to_cpu(ep_info->operations->num_entries); in pdsfc_validate_rpc()
337 if (PDS_FWCTL_RPC_OPCODE_CMP(rpc->in.op, le32_to_cpu(op_entry[i].id))) { in pdsfc_validate_rpc()
338 if (scope < op_entry[i].scope) in pdsfc_validate_rpc()
339 return -EPERM; in pdsfc_validate_rpc()
344 dev_dbg(dev, "Invalid operation %d for endpoint %d\n", rpc->in.op, rpc->in.ep); in pdsfc_validate_rpc()
346 return -EINVAL; in pdsfc_validate_rpc()
352 struct pdsfc_dev *pdsfc = container_of(uctx->fwctl, struct pdsfc_dev, fwctl); in pdsfc_fw_rpc()
353 struct device *dev = &uctx->fwctl->dev; in pdsfc_fw_rpc()
357 struct fwctl_rpc_pds *rpc = in; in pdsfc_fw_rpc() local
364 err = pdsfc_validate_rpc(pdsfc, rpc, scope); in pdsfc_fw_rpc()
365 if (err) in pdsfc_fw_rpc()
368 if (rpc->in.len > 0) { in pdsfc_fw_rpc()
369 in_payload = kzalloc(rpc->in.len, GFP_KERNEL); in pdsfc_fw_rpc()
370 if (!in_payload) { in pdsfc_fw_rpc()
372 err = -ENOMEM; in pdsfc_fw_rpc()
376 if (copy_from_user(in_payload, u64_to_user_ptr(rpc->in.payload), in pdsfc_fw_rpc()
377 rpc->in.len)) { in pdsfc_fw_rpc()
379 err = -EFAULT; in pdsfc_fw_rpc()
383 in_payload_dma_addr = dma_map_single(dev->parent, in_payload, in pdsfc_fw_rpc()
384 rpc->in.len, DMA_TO_DEVICE); in pdsfc_fw_rpc()
385 err = dma_mapping_error(dev->parent, in_payload_dma_addr); in pdsfc_fw_rpc()
386 if (err) { in pdsfc_fw_rpc()
392 if (rpc->out.len > 0) { in pdsfc_fw_rpc()
393 out_payload = kzalloc(rpc->out.len, GFP_KERNEL); in pdsfc_fw_rpc()
394 if (!out_payload) { in pdsfc_fw_rpc()
396 err = -ENOMEM; in pdsfc_fw_rpc()
400 out_payload_dma_addr = dma_map_single(dev->parent, out_payload, in pdsfc_fw_rpc()
401 rpc->out.len, DMA_FROM_DEVICE); in pdsfc_fw_rpc()
402 err = dma_mapping_error(dev->parent, out_payload_dma_addr); in pdsfc_fw_rpc()
403 if (err) { in pdsfc_fw_rpc()
413 .ep = cpu_to_le32(rpc->in.ep), in pdsfc_fw_rpc()
414 .op = cpu_to_le32(rpc->in.op), in pdsfc_fw_rpc()
416 .req_sz = cpu_to_le32(rpc->in.len), in pdsfc_fw_rpc()
418 .resp_sz = cpu_to_le32(rpc->out.len), in pdsfc_fw_rpc()
422 err = pds_client_adminq_cmd(pdsfc->padev, &cmd, sizeof(cmd), &comp, 0); in pdsfc_fw_rpc()
423 if (err) { in pdsfc_fw_rpc()
425 __func__, rpc->in.ep, rpc->in.op, in pdsfc_fw_rpc()
432 dynamic_hex_dump("out ", DUMP_PREFIX_OFFSET, 16, 1, out_payload, rpc->out.len, true); in pdsfc_fw_rpc()
434 if (copy_to_user(u64_to_user_ptr(rpc->out.payload), out_payload, rpc->out.len)) { in pdsfc_fw_rpc()
436 out = ERR_PTR(-EFAULT); in pdsfc_fw_rpc()
440 rpc->out.retval = le32_to_cpu(comp.fwctl_rpc.err); in pdsfc_fw_rpc()
445 if (out_payload_dma_addr) in pdsfc_fw_rpc()
446 dma_unmap_single(dev->parent, out_payload_dma_addr, in pdsfc_fw_rpc()
447 rpc->out.len, DMA_FROM_DEVICE); in pdsfc_fw_rpc()
451 if (in_payload_dma_addr) in pdsfc_fw_rpc()
452 dma_unmap_single(dev->parent, in_payload_dma_addr, in pdsfc_fw_rpc()
453 rpc->in.len, DMA_TO_DEVICE); in pdsfc_fw_rpc()
457 if (err) in pdsfc_fw_rpc()
477 struct device *dev = &adev->dev; in pdsfc_probe()
481 pdsfc = fwctl_alloc_device(&padev->vf_pdev->dev, &pdsfc_ops, in pdsfc_probe()
483 if (!pdsfc) in pdsfc_probe()
484 return dev_err_probe(dev, -ENOMEM, "Failed to allocate fwctl device struct\n"); in pdsfc_probe()
485 pdsfc->padev = padev; in pdsfc_probe()
488 if (err) { in pdsfc_probe()
489 fwctl_put(&pdsfc->fwctl); in pdsfc_probe()
494 if (err) { in pdsfc_probe()
495 fwctl_put(&pdsfc->fwctl); in pdsfc_probe()
499 pdsfc->caps = PDS_FWCTL_QUERY_CAP | PDS_FWCTL_SEND_CAP; in pdsfc_probe()
501 err = fwctl_register(&pdsfc->fwctl); in pdsfc_probe()
502 if (err) { in pdsfc_probe()
504 fwctl_put(&pdsfc->fwctl); in pdsfc_probe()
517 fwctl_unregister(&pdsfc->fwctl); in pdsfc_remove()
521 fwctl_put(&pdsfc->fwctl); in pdsfc_remove()