1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2 /* 3 * Copyright 2013-2016 Freescale Semiconductor Inc. 4 * Copyright 2020 NXP 5 * 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 commands 14 * towards the mc firmware 15 */ 16 static u16 dprc_major_ver; 17 static u16 dprc_minor_ver; 18 19 /** 20 * dprc_open() - Open DPRC object for use 21 * @mc_io: Pointer to MC portal's I/O object 22 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 23 * @container_id: Container ID to open 24 * @token: Returned token of DPRC object 25 * 26 * Return: '0' on Success; Error code otherwise. 27 * 28 * @warning Required before any operation on the object. 29 */ 30 int 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 } 55 EXPORT_SYMBOL_GPL(dprc_open); 56 57 /** 58 * dprc_close() - Close the control session of the object 59 * @mc_io: Pointer to MC portal's I/O object 60 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 61 * @token: Token of DPRC object 62 * 63 * After this function is called, no further operations are 64 * allowed on the object without opening a new control session. 65 * 66 * Return: '0' on Success; Error code otherwise. 67 */ 68 int 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 } 81 EXPORT_SYMBOL_GPL(dprc_close); 82 83 /** 84 * dprc_reset_container - Reset child container. 85 * @mc_io: Pointer to MC portal's I/O object 86 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 87 * @token: Token of DPRC object 88 * @child_container_id: ID of the container to reset 89 * @options: 32 bit options: 90 * - 0 (no bits set) - all the objects inside the container are 91 * reset. The child containers are entered recursively and the 92 * 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.5 97 * In case a software context crashes or becomes non-responsive, the parent 98 * may wish to reset its resources container before the software context is 99 * restarted. 100 * 101 * This routine informs all objects assigned to the child container that the 102 * container is being reset, so they may perform any cleanup operations that are 103 * needed. All objects handles that were owned by the child container shall be 104 * closed. 105 * 106 * Note that such request may be submitted even if the child software context 107 * has not crashed, but the resulting object cleanup operations will not be 108 * aware of that. 109 * 110 * Return: '0' on Success; Error code otherwise. 111 */ 112 int 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 pass 137 * 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 } 152 EXPORT_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 object 157 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 158 * @token: Token of DPRC object 159 * @irq_index: Identifies the interrupt index to configure 160 * @irq_cfg: IRQ configuration 161 * 162 * Return: '0' on Success; Error code otherwise. 163 */ 164 int 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 object 190 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 191 * @token: Token of DPRC object 192 * @irq_index: The interrupt index to configure 193 * @en: Interrupt state - enable = 1, disable = 0 194 * 195 * Allows GPP software to control when interrupts are generated. 196 * Each interrupt can have up to 32 causes. The enable/disable control's the 197 * overall interrupt state. if the interrupt is disabled no causes will cause 198 * an interrupt. 199 * 200 * Return: '0' on Success; Error code otherwise. 201 */ 202 int 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 object 225 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 226 * @token: Token of DPRC object 227 * @irq_index: The interrupt index to configure 228 * @mask: event mask to trigger interrupt; 229 * each bit: 230 * 0 = ignore event 231 * 1 = consider event for asserting irq 232 * 233 * Every interrupt can have up to 32 causes and the interrupt model supports 234 * masking/unmasking each cause independently 235 * 236 * Return: '0' on Success; Error code otherwise. 237 */ 238 int 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 object 261 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 262 * @token: Token of DPRC object 263 * @irq_index: The interrupt index to configure 264 * @status: Returned interrupts status - one bit per cause: 265 * 0 = no interrupt pending 266 * 1 = interrupt pending 267 * 268 * Return: '0' on Success; Error code otherwise. 269 */ 270 int 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 status 302 * @mc_io: Pointer to MC portal's I/O object 303 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 304 * @token: Token of DPRC object 305 * @irq_index: The interrupt index to configure 306 * @status: bits to clear (W1C) - one bit per cause: 307 * 0 = don't change 308 * 1 = clear status bit 309 * 310 * Return: '0' on Success; Error code otherwise. 311 */ 312 int 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 attributes 334 * @mc_io: Pointer to MC portal's I/O object 335 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 336 * @token: Token of DPRC object 337 * @attr: Returned container attributes 338 * 339 * Return: '0' on Success; Error code otherwise. 340 */ 341 int 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 DPRC 372 * @mc_io: Pointer to MC portal's I/O object 373 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 374 * @token: Token of DPRC object 375 * @obj_count: Number of objects assigned to the DPRC 376 * 377 * Return: '0' on Success; Error code otherwise. 378 */ 379 int 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 } 403 EXPORT_SYMBOL_GPL(dprc_get_obj_count); 404 405 /** 406 * dprc_get_obj() - Get general information on an object 407 * @mc_io: Pointer to MC portal's I/O object 408 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 409 * @token: Token of DPRC object 410 * @obj_index: Index of the object to be queried (< obj_count) 411 * @obj_desc: Returns the requested object descriptor 412 * 413 * The object descriptors are retrieved one by one by incrementing 414 * obj_index up to (not including) the value of obj_count returned 415 * from dprc_get_obj_count(). dprc_get_obj_count() must 416 * be called prior to dprc_get_obj(). 417 * 418 * Return: '0' on Success; Error code otherwise. 419 */ 420 int 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 } 457 EXPORT_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 object 462 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 463 * @token: Token of DPRC object 464 * @obj_type: Type of the object to set its IRQ 465 * @obj_id: ID of the object to set its IRQ 466 * @irq_index: The interrupt index to configure 467 * @irq_cfg: IRQ configuration 468 * 469 * Return: '0' on Success; Error code otherwise. 470 */ 471 int 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 } 497 EXPORT_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 object 502 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 503 * @token: Token of DPRC object 504 * @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 query 507 * @region_desc: Returns the requested region descriptor 508 * 509 * Return: '0' on Success; Error code otherwise. 510 */ 511 int 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 software 539 * portals to 64K (as implemented by hardware). If older API is in use the 540 * size reported is less (64 bytes for mc portals and 4K for software 541 * 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 region 550 * descriptor: base_address. If the older API is in use then the base 551 * address is set to zero to indicate it needs to be obtained elsewhere 552 * (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 else 580 region_desc->base_address = 0; 581 582 return 0; 583 } 584 EXPORT_SYMBOL_GPL(dprc_get_obj_region); 585 586 /** 587 * dprc_get_api_version - Get Data Path Resource Container API version 588 * @mc_io: Pointer to Mc portal's I/O object 589 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 590 * @major_ver: Major version of Data Path Resource Container API 591 * @minor_ver: Minor version of Data Path Resource Container API 592 * 593 * Return: '0' on Success; Error code otherwise. 594 */ 595 int 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 object 621 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 622 * @container_id: Requested container id 623 * 624 * Return: '0' on Success; Error code otherwise. 625 */ 626 int 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 connection 651 * exists. 652 * @mc_io: Pointer to MC portal's I/O object 653 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 654 * @token: Token of DPRC object 655 * @endpoint1: Endpoint 1 configuration parameters 656 * @endpoint2: Returned endpoint 2 configuration parameters 657 * @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 */ 664 int 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