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 * @attributes 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 strncpy(obj_desc->type, rsp_params->type, 16); 454 obj_desc->type[15] = '\0'; 455 strncpy(obj_desc->label, rsp_params->label, 16); 456 obj_desc->label[15] = '\0'; 457 return 0; 458 } 459 EXPORT_SYMBOL_GPL(dprc_get_obj); 460 461 /** 462 * dprc_set_obj_irq() - Set IRQ information for object to trigger an interrupt. 463 * @mc_io: Pointer to MC portal's I/O object 464 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 465 * @token: Token of DPRC object 466 * @obj_type: Type of the object to set its IRQ 467 * @obj_id: ID of the object to set its IRQ 468 * @irq_index: The interrupt index to configure 469 * @irq_cfg: IRQ configuration 470 * 471 * Return: '0' on Success; Error code otherwise. 472 */ 473 int dprc_set_obj_irq(struct fsl_mc_io *mc_io, 474 u32 cmd_flags, 475 u16 token, 476 char *obj_type, 477 int obj_id, 478 u8 irq_index, 479 struct dprc_irq_cfg *irq_cfg) 480 { 481 struct fsl_mc_command cmd = { 0 }; 482 struct dprc_cmd_set_obj_irq *cmd_params; 483 484 /* prepare command */ 485 cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_OBJ_IRQ, 486 cmd_flags, 487 token); 488 cmd_params = (struct dprc_cmd_set_obj_irq *)cmd.params; 489 cmd_params->irq_val = cpu_to_le32(irq_cfg->val); 490 cmd_params->irq_index = irq_index; 491 cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr); 492 cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num); 493 cmd_params->obj_id = cpu_to_le32(obj_id); 494 strncpy(cmd_params->obj_type, obj_type, 16); 495 cmd_params->obj_type[15] = '\0'; 496 497 /* send command to mc*/ 498 return mc_send_command(mc_io, &cmd); 499 } 500 EXPORT_SYMBOL_GPL(dprc_set_obj_irq); 501 502 /** 503 * dprc_get_obj_region() - Get region information for a specified object. 504 * @mc_io: Pointer to MC portal's I/O object 505 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 506 * @token: Token of DPRC object 507 * @obj_type; Object type as returned in dprc_get_obj() 508 * @obj_id: Unique object instance as returned in dprc_get_obj() 509 * @region_index: The specific region to query 510 * @region_desc: Returns the requested region descriptor 511 * 512 * Return: '0' on Success; Error code otherwise. 513 */ 514 int dprc_get_obj_region(struct fsl_mc_io *mc_io, 515 u32 cmd_flags, 516 u16 token, 517 char *obj_type, 518 int obj_id, 519 u8 region_index, 520 struct dprc_region_desc *region_desc) 521 { 522 struct fsl_mc_command cmd = { 0 }; 523 struct dprc_cmd_get_obj_region *cmd_params; 524 struct dprc_rsp_get_obj_region *rsp_params; 525 int err; 526 527 /* 528 * If the DPRC object version was not yet cached, cache it now. 529 * Otherwise use the already cached value. 530 */ 531 if (!dprc_major_ver && !dprc_minor_ver) { 532 err = dprc_get_api_version(mc_io, 0, 533 &dprc_major_ver, 534 &dprc_minor_ver); 535 if (err) 536 return err; 537 } 538 539 if (dprc_major_ver > 6 || (dprc_major_ver == 6 && dprc_minor_ver >= 6)) { 540 /* 541 * MC API version 6.6 changed the size of the MC portals and software 542 * portals to 64K (as implemented by hardware). If older API is in use the 543 * size reported is less (64 bytes for mc portals and 4K for software 544 * portals). 545 */ 546 547 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG_V3, 548 cmd_flags, token); 549 550 } else if (dprc_major_ver == 6 && dprc_minor_ver >= 3) { 551 /* 552 * MC API version 6.3 introduced a new field to the region 553 * descriptor: base_address. If the older API is in use then the base 554 * address is set to zero to indicate it needs to be obtained elsewhere 555 * (typically the device tree). 556 */ 557 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG_V2, 558 cmd_flags, token); 559 } else { 560 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG, 561 cmd_flags, token); 562 } 563 564 cmd_params = (struct dprc_cmd_get_obj_region *)cmd.params; 565 cmd_params->obj_id = cpu_to_le32(obj_id); 566 cmd_params->region_index = region_index; 567 strncpy(cmd_params->obj_type, obj_type, 16); 568 cmd_params->obj_type[15] = '\0'; 569 570 /* send command to mc*/ 571 err = mc_send_command(mc_io, &cmd); 572 if (err) 573 return err; 574 575 /* retrieve response parameters */ 576 rsp_params = (struct dprc_rsp_get_obj_region *)cmd.params; 577 region_desc->base_offset = le64_to_cpu(rsp_params->base_offset); 578 region_desc->size = le32_to_cpu(rsp_params->size); 579 region_desc->type = rsp_params->type; 580 region_desc->flags = le32_to_cpu(rsp_params->flags); 581 if (dprc_major_ver > 6 || (dprc_major_ver == 6 && dprc_minor_ver >= 3)) 582 region_desc->base_address = le64_to_cpu(rsp_params->base_addr); 583 else 584 region_desc->base_address = 0; 585 586 return 0; 587 } 588 EXPORT_SYMBOL_GPL(dprc_get_obj_region); 589 590 /** 591 * dprc_get_api_version - Get Data Path Resource Container API version 592 * @mc_io: Pointer to Mc portal's I/O object 593 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 594 * @major_ver: Major version of Data Path Resource Container API 595 * @minor_ver: Minor version of Data Path Resource Container API 596 * 597 * Return: '0' on Success; Error code otherwise. 598 */ 599 int dprc_get_api_version(struct fsl_mc_io *mc_io, 600 u32 cmd_flags, 601 u16 *major_ver, 602 u16 *minor_ver) 603 { 604 struct fsl_mc_command cmd = { 0 }; 605 int err; 606 607 /* prepare command */ 608 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_API_VERSION, 609 cmd_flags, 0); 610 611 /* send command to mc */ 612 err = mc_send_command(mc_io, &cmd); 613 if (err) 614 return err; 615 616 /* retrieve response parameters */ 617 mc_cmd_read_api_version(&cmd, major_ver, minor_ver); 618 619 return 0; 620 } 621 622 /** 623 * dprc_get_container_id - Get container ID associated with a given portal. 624 * @mc_io: Pointer to Mc portal's I/O object 625 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 626 * @container_id: Requested container id 627 * 628 * Return: '0' on Success; Error code otherwise. 629 */ 630 int dprc_get_container_id(struct fsl_mc_io *mc_io, 631 u32 cmd_flags, 632 int *container_id) 633 { 634 struct fsl_mc_command cmd = { 0 }; 635 int err; 636 637 /* prepare command */ 638 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONT_ID, 639 cmd_flags, 640 0); 641 642 /* send command to mc*/ 643 err = mc_send_command(mc_io, &cmd); 644 if (err) 645 return err; 646 647 /* retrieve response parameters */ 648 *container_id = (int)mc_cmd_read_object_id(&cmd); 649 650 return 0; 651 } 652 653 /** 654 * dprc_get_connection() - Get connected endpoint and link status if connection 655 * exists. 656 * @mc_io: Pointer to MC portal's I/O object 657 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 658 * @token: Token of DPRC object 659 * @endpoint1: Endpoint 1 configuration parameters 660 * @endpoint2: Returned endpoint 2 configuration parameters 661 * @state: Returned link state: 662 * 1 - link is up; 663 * 0 - link is down; 664 * -1 - no connection (endpoint2 information is irrelevant) 665 * 666 * Return: '0' on Success; -ENOTCONN if connection does not exist. 667 */ 668 int dprc_get_connection(struct fsl_mc_io *mc_io, 669 u32 cmd_flags, 670 u16 token, 671 const struct dprc_endpoint *endpoint1, 672 struct dprc_endpoint *endpoint2, 673 int *state) 674 { 675 struct dprc_cmd_get_connection *cmd_params; 676 struct dprc_rsp_get_connection *rsp_params; 677 struct fsl_mc_command cmd = { 0 }; 678 int err, i; 679 680 /* prepare command */ 681 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONNECTION, 682 cmd_flags, 683 token); 684 cmd_params = (struct dprc_cmd_get_connection *)cmd.params; 685 cmd_params->ep1_id = cpu_to_le32(endpoint1->id); 686 cmd_params->ep1_interface_id = cpu_to_le16(endpoint1->if_id); 687 for (i = 0; i < 16; i++) 688 cmd_params->ep1_type[i] = endpoint1->type[i]; 689 690 /* send command to mc */ 691 err = mc_send_command(mc_io, &cmd); 692 if (err) 693 return -ENOTCONN; 694 695 /* retrieve response parameters */ 696 rsp_params = (struct dprc_rsp_get_connection *)cmd.params; 697 endpoint2->id = le32_to_cpu(rsp_params->ep2_id); 698 endpoint2->if_id = le16_to_cpu(rsp_params->ep2_interface_id); 699 *state = le32_to_cpu(rsp_params->state); 700 for (i = 0; i < 16; i++) 701 endpoint2->type[i] = rsp_params->ep2_type[i]; 702 703 return 0; 704 } 705