701 lines · c
1// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)2/*3 * Copyright 2013-2016 Freescale Semiconductor Inc.4 * Copyright 2020 NXP5 *6 */7#include <linux/kernel.h>8#include <linux/fsl/mc.h>9 10#include "fsl-mc-private.h"11 12/*13 * cache the DPRC version to reduce the number of commands14 * towards the mc firmware15 */16static u16 dprc_major_ver;17static u16 dprc_minor_ver;18 19/**20 * dprc_open() - Open DPRC object for use21 * @mc_io: Pointer to MC portal's I/O object22 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'23 * @container_id: Container ID to open24 * @token: Returned token of DPRC object25 *26 * Return: '0' on Success; Error code otherwise.27 *28 * @warning Required before any operation on the object.29 */30int dprc_open(struct fsl_mc_io *mc_io,31 u32 cmd_flags,32 int container_id,33 u16 *token)34{35 struct fsl_mc_command cmd = { 0 };36 struct dprc_cmd_open *cmd_params;37 int err;38 39 /* prepare command */40 cmd.header = mc_encode_cmd_header(DPRC_CMDID_OPEN, cmd_flags,41 0);42 cmd_params = (struct dprc_cmd_open *)cmd.params;43 cmd_params->container_id = cpu_to_le32(container_id);44 45 /* send command to mc*/46 err = mc_send_command(mc_io, &cmd);47 if (err)48 return err;49 50 /* retrieve response parameters */51 *token = mc_cmd_hdr_read_token(&cmd);52 53 return 0;54}55EXPORT_SYMBOL_GPL(dprc_open);56 57/**58 * dprc_close() - Close the control session of the object59 * @mc_io: Pointer to MC portal's I/O object60 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'61 * @token: Token of DPRC object62 *63 * After this function is called, no further operations are64 * allowed on the object without opening a new control session.65 *66 * Return: '0' on Success; Error code otherwise.67 */68int dprc_close(struct fsl_mc_io *mc_io,69 u32 cmd_flags,70 u16 token)71{72 struct fsl_mc_command cmd = { 0 };73 74 /* prepare command */75 cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLOSE, cmd_flags,76 token);77 78 /* send command to mc*/79 return mc_send_command(mc_io, &cmd);80}81EXPORT_SYMBOL_GPL(dprc_close);82 83/**84 * dprc_reset_container - Reset child container.85 * @mc_io: Pointer to MC portal's I/O object86 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'87 * @token: Token of DPRC object88 * @child_container_id: ID of the container to reset89 * @options: 32 bit options:90 * - 0 (no bits set) - all the objects inside the container are91 * reset. The child containers are entered recursively and the92 * objects reset. All the objects (including the child containers)93 * are closed.94 * - bit 0 set - all the objects inside the container are reset.95 * However the child containers are not entered recursively.96 * This option is supported for API versions >= 6.597 * In case a software context crashes or becomes non-responsive, the parent98 * may wish to reset its resources container before the software context is99 * restarted.100 *101 * This routine informs all objects assigned to the child container that the102 * container is being reset, so they may perform any cleanup operations that are103 * needed. All objects handles that were owned by the child container shall be104 * closed.105 *106 * Note that such request may be submitted even if the child software context107 * has not crashed, but the resulting object cleanup operations will not be108 * aware of that.109 *110 * Return: '0' on Success; Error code otherwise.111 */112int dprc_reset_container(struct fsl_mc_io *mc_io,113 u32 cmd_flags,114 u16 token,115 int child_container_id,116 u32 options)117{118 struct fsl_mc_command cmd = { 0 };119 struct dprc_cmd_reset_container *cmd_params;120 u32 cmdid = DPRC_CMDID_RESET_CONT;121 int err;122 123 /*124 * If the DPRC object version was not yet cached, cache it now.125 * Otherwise use the already cached value.126 */127 if (!dprc_major_ver && !dprc_minor_ver) {128 err = dprc_get_api_version(mc_io, 0,129 &dprc_major_ver,130 &dprc_minor_ver);131 if (err)132 return err;133 }134 135 /*136 * MC API 6.5 introduced a new field in the command used to pass137 * some flags.138 * Bit 0 indicates that the child containers are not recursively reset.139 */140 if (dprc_major_ver > 6 || (dprc_major_ver == 6 && dprc_minor_ver >= 5))141 cmdid = DPRC_CMDID_RESET_CONT_V2;142 143 /* prepare command */144 cmd.header = mc_encode_cmd_header(cmdid, cmd_flags, token);145 cmd_params = (struct dprc_cmd_reset_container *)cmd.params;146 cmd_params->child_container_id = cpu_to_le32(child_container_id);147 cmd_params->options = cpu_to_le32(options);148 149 /* send command to mc*/150 return mc_send_command(mc_io, &cmd);151}152EXPORT_SYMBOL_GPL(dprc_reset_container);153 154/**155 * dprc_set_irq() - Set IRQ information for the DPRC to trigger an interrupt.156 * @mc_io: Pointer to MC portal's I/O object157 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'158 * @token: Token of DPRC object159 * @irq_index: Identifies the interrupt index to configure160 * @irq_cfg: IRQ configuration161 *162 * Return: '0' on Success; Error code otherwise.163 */164int dprc_set_irq(struct fsl_mc_io *mc_io,165 u32 cmd_flags,166 u16 token,167 u8 irq_index,168 struct dprc_irq_cfg *irq_cfg)169{170 struct fsl_mc_command cmd = { 0 };171 struct dprc_cmd_set_irq *cmd_params;172 173 /* prepare command */174 cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ,175 cmd_flags,176 token);177 cmd_params = (struct dprc_cmd_set_irq *)cmd.params;178 cmd_params->irq_val = cpu_to_le32(irq_cfg->val);179 cmd_params->irq_index = irq_index;180 cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr);181 cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num);182 183 /* send command to mc*/184 return mc_send_command(mc_io, &cmd);185}186 187/**188 * dprc_set_irq_enable() - Set overall interrupt state.189 * @mc_io: Pointer to MC portal's I/O object190 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'191 * @token: Token of DPRC object192 * @irq_index: The interrupt index to configure193 * @en: Interrupt state - enable = 1, disable = 0194 *195 * Allows GPP software to control when interrupts are generated.196 * Each interrupt can have up to 32 causes. The enable/disable control's the197 * overall interrupt state. if the interrupt is disabled no causes will cause198 * an interrupt.199 *200 * Return: '0' on Success; Error code otherwise.201 */202int dprc_set_irq_enable(struct fsl_mc_io *mc_io,203 u32 cmd_flags,204 u16 token,205 u8 irq_index,206 u8 en)207{208 struct fsl_mc_command cmd = { 0 };209 struct dprc_cmd_set_irq_enable *cmd_params;210 211 /* prepare command */212 cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_ENABLE,213 cmd_flags, token);214 cmd_params = (struct dprc_cmd_set_irq_enable *)cmd.params;215 cmd_params->enable = en & DPRC_ENABLE;216 cmd_params->irq_index = irq_index;217 218 /* send command to mc*/219 return mc_send_command(mc_io, &cmd);220}221 222/**223 * dprc_set_irq_mask() - Set interrupt mask.224 * @mc_io: Pointer to MC portal's I/O object225 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'226 * @token: Token of DPRC object227 * @irq_index: The interrupt index to configure228 * @mask: event mask to trigger interrupt;229 * each bit:230 * 0 = ignore event231 * 1 = consider event for asserting irq232 *233 * Every interrupt can have up to 32 causes and the interrupt model supports234 * masking/unmasking each cause independently235 *236 * Return: '0' on Success; Error code otherwise.237 */238int dprc_set_irq_mask(struct fsl_mc_io *mc_io,239 u32 cmd_flags,240 u16 token,241 u8 irq_index,242 u32 mask)243{244 struct fsl_mc_command cmd = { 0 };245 struct dprc_cmd_set_irq_mask *cmd_params;246 247 /* prepare command */248 cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_MASK,249 cmd_flags, token);250 cmd_params = (struct dprc_cmd_set_irq_mask *)cmd.params;251 cmd_params->mask = cpu_to_le32(mask);252 cmd_params->irq_index = irq_index;253 254 /* send command to mc*/255 return mc_send_command(mc_io, &cmd);256}257 258/**259 * dprc_get_irq_status() - Get the current status of any pending interrupts.260 * @mc_io: Pointer to MC portal's I/O object261 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'262 * @token: Token of DPRC object263 * @irq_index: The interrupt index to configure264 * @status: Returned interrupts status - one bit per cause:265 * 0 = no interrupt pending266 * 1 = interrupt pending267 *268 * Return: '0' on Success; Error code otherwise.269 */270int dprc_get_irq_status(struct fsl_mc_io *mc_io,271 u32 cmd_flags,272 u16 token,273 u8 irq_index,274 u32 *status)275{276 struct fsl_mc_command cmd = { 0 };277 struct dprc_cmd_get_irq_status *cmd_params;278 struct dprc_rsp_get_irq_status *rsp_params;279 int err;280 281 /* prepare command */282 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_STATUS,283 cmd_flags, token);284 cmd_params = (struct dprc_cmd_get_irq_status *)cmd.params;285 cmd_params->status = cpu_to_le32(*status);286 cmd_params->irq_index = irq_index;287 288 /* send command to mc*/289 err = mc_send_command(mc_io, &cmd);290 if (err)291 return err;292 293 /* retrieve response parameters */294 rsp_params = (struct dprc_rsp_get_irq_status *)cmd.params;295 *status = le32_to_cpu(rsp_params->status);296 297 return 0;298}299 300/**301 * dprc_clear_irq_status() - Clear a pending interrupt's status302 * @mc_io: Pointer to MC portal's I/O object303 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'304 * @token: Token of DPRC object305 * @irq_index: The interrupt index to configure306 * @status: bits to clear (W1C) - one bit per cause:307 * 0 = don't change308 * 1 = clear status bit309 *310 * Return: '0' on Success; Error code otherwise.311 */312int dprc_clear_irq_status(struct fsl_mc_io *mc_io,313 u32 cmd_flags,314 u16 token,315 u8 irq_index,316 u32 status)317{318 struct fsl_mc_command cmd = { 0 };319 struct dprc_cmd_clear_irq_status *cmd_params;320 321 /* prepare command */322 cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLEAR_IRQ_STATUS,323 cmd_flags, token);324 cmd_params = (struct dprc_cmd_clear_irq_status *)cmd.params;325 cmd_params->status = cpu_to_le32(status);326 cmd_params->irq_index = irq_index;327 328 /* send command to mc*/329 return mc_send_command(mc_io, &cmd);330}331 332/**333 * dprc_get_attributes() - Obtains container attributes334 * @mc_io: Pointer to MC portal's I/O object335 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'336 * @token: Token of DPRC object337 * @attr: Returned container attributes338 *339 * Return: '0' on Success; Error code otherwise.340 */341int dprc_get_attributes(struct fsl_mc_io *mc_io,342 u32 cmd_flags,343 u16 token,344 struct dprc_attributes *attr)345{346 struct fsl_mc_command cmd = { 0 };347 struct dprc_rsp_get_attributes *rsp_params;348 int err;349 350 /* prepare command */351 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_ATTR,352 cmd_flags,353 token);354 355 /* send command to mc*/356 err = mc_send_command(mc_io, &cmd);357 if (err)358 return err;359 360 /* retrieve response parameters */361 rsp_params = (struct dprc_rsp_get_attributes *)cmd.params;362 attr->container_id = le32_to_cpu(rsp_params->container_id);363 attr->icid = le32_to_cpu(rsp_params->icid);364 attr->options = le32_to_cpu(rsp_params->options);365 attr->portal_id = le32_to_cpu(rsp_params->portal_id);366 367 return 0;368}369 370/**371 * dprc_get_obj_count() - Obtains the number of objects in the DPRC372 * @mc_io: Pointer to MC portal's I/O object373 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'374 * @token: Token of DPRC object375 * @obj_count: Number of objects assigned to the DPRC376 *377 * Return: '0' on Success; Error code otherwise.378 */379int dprc_get_obj_count(struct fsl_mc_io *mc_io,380 u32 cmd_flags,381 u16 token,382 int *obj_count)383{384 struct fsl_mc_command cmd = { 0 };385 struct dprc_rsp_get_obj_count *rsp_params;386 int err;387 388 /* prepare command */389 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_COUNT,390 cmd_flags, token);391 392 /* send command to mc*/393 err = mc_send_command(mc_io, &cmd);394 if (err)395 return err;396 397 /* retrieve response parameters */398 rsp_params = (struct dprc_rsp_get_obj_count *)cmd.params;399 *obj_count = le32_to_cpu(rsp_params->obj_count);400 401 return 0;402}403EXPORT_SYMBOL_GPL(dprc_get_obj_count);404 405/**406 * dprc_get_obj() - Get general information on an object407 * @mc_io: Pointer to MC portal's I/O object408 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'409 * @token: Token of DPRC object410 * @obj_index: Index of the object to be queried (< obj_count)411 * @obj_desc: Returns the requested object descriptor412 *413 * The object descriptors are retrieved one by one by incrementing414 * obj_index up to (not including) the value of obj_count returned415 * from dprc_get_obj_count(). dprc_get_obj_count() must416 * be called prior to dprc_get_obj().417 *418 * Return: '0' on Success; Error code otherwise.419 */420int dprc_get_obj(struct fsl_mc_io *mc_io,421 u32 cmd_flags,422 u16 token,423 int obj_index,424 struct fsl_mc_obj_desc *obj_desc)425{426 struct fsl_mc_command cmd = { 0 };427 struct dprc_cmd_get_obj *cmd_params;428 struct dprc_rsp_get_obj *rsp_params;429 int err;430 431 /* prepare command */432 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ,433 cmd_flags,434 token);435 cmd_params = (struct dprc_cmd_get_obj *)cmd.params;436 cmd_params->obj_index = cpu_to_le32(obj_index);437 438 /* send command to mc*/439 err = mc_send_command(mc_io, &cmd);440 if (err)441 return err;442 443 /* retrieve response parameters */444 rsp_params = (struct dprc_rsp_get_obj *)cmd.params;445 obj_desc->id = le32_to_cpu(rsp_params->id);446 obj_desc->vendor = le16_to_cpu(rsp_params->vendor);447 obj_desc->irq_count = rsp_params->irq_count;448 obj_desc->region_count = rsp_params->region_count;449 obj_desc->state = le32_to_cpu(rsp_params->state);450 obj_desc->ver_major = le16_to_cpu(rsp_params->version_major);451 obj_desc->ver_minor = le16_to_cpu(rsp_params->version_minor);452 obj_desc->flags = le16_to_cpu(rsp_params->flags);453 strscpy_pad(obj_desc->type, rsp_params->type, 16);454 strscpy_pad(obj_desc->label, rsp_params->label, 16);455 return 0;456}457EXPORT_SYMBOL_GPL(dprc_get_obj);458 459/**460 * dprc_set_obj_irq() - Set IRQ information for object to trigger an interrupt.461 * @mc_io: Pointer to MC portal's I/O object462 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'463 * @token: Token of DPRC object464 * @obj_type: Type of the object to set its IRQ465 * @obj_id: ID of the object to set its IRQ466 * @irq_index: The interrupt index to configure467 * @irq_cfg: IRQ configuration468 *469 * Return: '0' on Success; Error code otherwise.470 */471int dprc_set_obj_irq(struct fsl_mc_io *mc_io,472 u32 cmd_flags,473 u16 token,474 char *obj_type,475 int obj_id,476 u8 irq_index,477 struct dprc_irq_cfg *irq_cfg)478{479 struct fsl_mc_command cmd = { 0 };480 struct dprc_cmd_set_obj_irq *cmd_params;481 482 /* prepare command */483 cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_OBJ_IRQ,484 cmd_flags,485 token);486 cmd_params = (struct dprc_cmd_set_obj_irq *)cmd.params;487 cmd_params->irq_val = cpu_to_le32(irq_cfg->val);488 cmd_params->irq_index = irq_index;489 cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr);490 cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num);491 cmd_params->obj_id = cpu_to_le32(obj_id);492 strscpy_pad(cmd_params->obj_type, obj_type, 16);493 494 /* send command to mc*/495 return mc_send_command(mc_io, &cmd);496}497EXPORT_SYMBOL_GPL(dprc_set_obj_irq);498 499/**500 * dprc_get_obj_region() - Get region information for a specified object.501 * @mc_io: Pointer to MC portal's I/O object502 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'503 * @token: Token of DPRC object504 * @obj_type: Object type as returned in dprc_get_obj()505 * @obj_id: Unique object instance as returned in dprc_get_obj()506 * @region_index: The specific region to query507 * @region_desc: Returns the requested region descriptor508 *509 * Return: '0' on Success; Error code otherwise.510 */511int dprc_get_obj_region(struct fsl_mc_io *mc_io,512 u32 cmd_flags,513 u16 token,514 char *obj_type,515 int obj_id,516 u8 region_index,517 struct dprc_region_desc *region_desc)518{519 struct fsl_mc_command cmd = { 0 };520 struct dprc_cmd_get_obj_region *cmd_params;521 struct dprc_rsp_get_obj_region *rsp_params;522 int err;523 524 /*525 * If the DPRC object version was not yet cached, cache it now.526 * Otherwise use the already cached value.527 */528 if (!dprc_major_ver && !dprc_minor_ver) {529 err = dprc_get_api_version(mc_io, 0,530 &dprc_major_ver,531 &dprc_minor_ver);532 if (err)533 return err;534 }535 536 if (dprc_major_ver > 6 || (dprc_major_ver == 6 && dprc_minor_ver >= 6)) {537 /*538 * MC API version 6.6 changed the size of the MC portals and software539 * portals to 64K (as implemented by hardware). If older API is in use the540 * size reported is less (64 bytes for mc portals and 4K for software541 * portals).542 */543 544 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG_V3,545 cmd_flags, token);546 547 } else if (dprc_major_ver == 6 && dprc_minor_ver >= 3) {548 /*549 * MC API version 6.3 introduced a new field to the region550 * descriptor: base_address. If the older API is in use then the base551 * address is set to zero to indicate it needs to be obtained elsewhere552 * (typically the device tree).553 */554 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG_V2,555 cmd_flags, token);556 } else {557 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG,558 cmd_flags, token);559 }560 561 cmd_params = (struct dprc_cmd_get_obj_region *)cmd.params;562 cmd_params->obj_id = cpu_to_le32(obj_id);563 cmd_params->region_index = region_index;564 strscpy_pad(cmd_params->obj_type, obj_type, 16);565 566 /* send command to mc*/567 err = mc_send_command(mc_io, &cmd);568 if (err)569 return err;570 571 /* retrieve response parameters */572 rsp_params = (struct dprc_rsp_get_obj_region *)cmd.params;573 region_desc->base_offset = le64_to_cpu(rsp_params->base_offset);574 region_desc->size = le32_to_cpu(rsp_params->size);575 region_desc->type = rsp_params->type;576 region_desc->flags = le32_to_cpu(rsp_params->flags);577 if (dprc_major_ver > 6 || (dprc_major_ver == 6 && dprc_minor_ver >= 3))578 region_desc->base_address = le64_to_cpu(rsp_params->base_addr);579 else580 region_desc->base_address = 0;581 582 return 0;583}584EXPORT_SYMBOL_GPL(dprc_get_obj_region);585 586/**587 * dprc_get_api_version - Get Data Path Resource Container API version588 * @mc_io: Pointer to Mc portal's I/O object589 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'590 * @major_ver: Major version of Data Path Resource Container API591 * @minor_ver: Minor version of Data Path Resource Container API592 *593 * Return: '0' on Success; Error code otherwise.594 */595int dprc_get_api_version(struct fsl_mc_io *mc_io,596 u32 cmd_flags,597 u16 *major_ver,598 u16 *minor_ver)599{600 struct fsl_mc_command cmd = { 0 };601 int err;602 603 /* prepare command */604 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_API_VERSION,605 cmd_flags, 0);606 607 /* send command to mc */608 err = mc_send_command(mc_io, &cmd);609 if (err)610 return err;611 612 /* retrieve response parameters */613 mc_cmd_read_api_version(&cmd, major_ver, minor_ver);614 615 return 0;616}617 618/**619 * dprc_get_container_id - Get container ID associated with a given portal.620 * @mc_io: Pointer to Mc portal's I/O object621 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'622 * @container_id: Requested container id623 *624 * Return: '0' on Success; Error code otherwise.625 */626int dprc_get_container_id(struct fsl_mc_io *mc_io,627 u32 cmd_flags,628 int *container_id)629{630 struct fsl_mc_command cmd = { 0 };631 int err;632 633 /* prepare command */634 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONT_ID,635 cmd_flags,636 0);637 638 /* send command to mc*/639 err = mc_send_command(mc_io, &cmd);640 if (err)641 return err;642 643 /* retrieve response parameters */644 *container_id = (int)mc_cmd_read_object_id(&cmd);645 646 return 0;647}648 649/**650 * dprc_get_connection() - Get connected endpoint and link status if connection651 * exists.652 * @mc_io: Pointer to MC portal's I/O object653 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'654 * @token: Token of DPRC object655 * @endpoint1: Endpoint 1 configuration parameters656 * @endpoint2: Returned endpoint 2 configuration parameters657 * @state: Returned link state:658 * 1 - link is up;659 * 0 - link is down;660 * -1 - no connection (endpoint2 information is irrelevant)661 *662 * Return: '0' on Success; -ENOTCONN if connection does not exist.663 */664int dprc_get_connection(struct fsl_mc_io *mc_io,665 u32 cmd_flags,666 u16 token,667 const struct dprc_endpoint *endpoint1,668 struct dprc_endpoint *endpoint2,669 int *state)670{671 struct dprc_cmd_get_connection *cmd_params;672 struct dprc_rsp_get_connection *rsp_params;673 struct fsl_mc_command cmd = { 0 };674 int err, i;675 676 /* prepare command */677 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONNECTION,678 cmd_flags,679 token);680 cmd_params = (struct dprc_cmd_get_connection *)cmd.params;681 cmd_params->ep1_id = cpu_to_le32(endpoint1->id);682 cmd_params->ep1_interface_id = cpu_to_le16(endpoint1->if_id);683 for (i = 0; i < 16; i++)684 cmd_params->ep1_type[i] = endpoint1->type[i];685 686 /* send command to mc */687 err = mc_send_command(mc_io, &cmd);688 if (err)689 return -ENOTCONN;690 691 /* retrieve response parameters */692 rsp_params = (struct dprc_rsp_get_connection *)cmd.params;693 endpoint2->id = le32_to_cpu(rsp_params->ep2_id);694 endpoint2->if_id = le16_to_cpu(rsp_params->ep2_interface_id);695 *state = le32_to_cpu(rsp_params->state);696 for (i = 0; i < 16; i++)697 endpoint2->type[i] = rsp_params->ep2_type[i];698 699 return 0;700}701