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 if (dprc_major_ver > 6 || (dprc_major_ver == 6 && dprc_minor_ver >= 3)) 580 region_desc->base_address = le64_to_cpu(rsp_params->base_addr); 581 else 582 region_desc->base_address = 0; 583 584 return 0; 585 } 586 EXPORT_SYMBOL_GPL(dprc_get_obj_region); 587 588 /** 589 * dprc_get_api_version - Get Data Path Resource Container API version 590 * @mc_io: Pointer to Mc portal's I/O object 591 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 592 * @major_ver: Major version of Data Path Resource Container API 593 * @minor_ver: Minor version of Data Path Resource Container API 594 * 595 * Return: '0' on Success; Error code otherwise. 596 */ 597 int dprc_get_api_version(struct fsl_mc_io *mc_io, 598 u32 cmd_flags, 599 u16 *major_ver, 600 u16 *minor_ver) 601 { 602 struct fsl_mc_command cmd = { 0 }; 603 int err; 604 605 /* prepare command */ 606 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_API_VERSION, 607 cmd_flags, 0); 608 609 /* send command to mc */ 610 err = mc_send_command(mc_io, &cmd); 611 if (err) 612 return err; 613 614 /* retrieve response parameters */ 615 mc_cmd_read_api_version(&cmd, major_ver, minor_ver); 616 617 return 0; 618 } 619 620 /** 621 * dprc_get_container_id - Get container ID associated with a given portal. 622 * @mc_io: Pointer to Mc portal's I/O object 623 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 624 * @container_id: Requested container id 625 * 626 * Return: '0' on Success; Error code otherwise. 627 */ 628 int dprc_get_container_id(struct fsl_mc_io *mc_io, 629 u32 cmd_flags, 630 int *container_id) 631 { 632 struct fsl_mc_command cmd = { 0 }; 633 int err; 634 635 /* prepare command */ 636 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONT_ID, 637 cmd_flags, 638 0); 639 640 /* send command to mc*/ 641 err = mc_send_command(mc_io, &cmd); 642 if (err) 643 return err; 644 645 /* retrieve response parameters */ 646 *container_id = (int)mc_cmd_read_object_id(&cmd); 647 648 return 0; 649 } 650 651 /** 652 * dprc_get_connection() - Get connected endpoint and link status if connection 653 * exists. 654 * @mc_io: Pointer to MC portal's I/O object 655 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 656 * @token: Token of DPRC object 657 * @endpoint1: Endpoint 1 configuration parameters 658 * @endpoint2: Returned endpoint 2 configuration parameters 659 * @state: Returned link state: 660 * 1 - link is up; 661 * 0 - link is down; 662 * -1 - no connection (endpoint2 information is irrelevant) 663 * 664 * Return: '0' on Success; -ENOTCONN if connection does not exist. 665 */ 666 int dprc_get_connection(struct fsl_mc_io *mc_io, 667 u32 cmd_flags, 668 u16 token, 669 const struct dprc_endpoint *endpoint1, 670 struct dprc_endpoint *endpoint2, 671 int *state) 672 { 673 struct dprc_cmd_get_connection *cmd_params; 674 struct dprc_rsp_get_connection *rsp_params; 675 struct fsl_mc_command cmd = { 0 }; 676 int err, i; 677 678 /* prepare command */ 679 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONNECTION, 680 cmd_flags, 681 token); 682 cmd_params = (struct dprc_cmd_get_connection *)cmd.params; 683 cmd_params->ep1_id = cpu_to_le32(endpoint1->id); 684 cmd_params->ep1_interface_id = cpu_to_le16(endpoint1->if_id); 685 for (i = 0; i < 16; i++) 686 cmd_params->ep1_type[i] = endpoint1->type[i]; 687 688 /* send command to mc */ 689 err = mc_send_command(mc_io, &cmd); 690 if (err) 691 return -ENOTCONN; 692 693 /* retrieve response parameters */ 694 rsp_params = (struct dprc_rsp_get_connection *)cmd.params; 695 endpoint2->id = le32_to_cpu(rsp_params->ep2_id); 696 endpoint2->if_id = le16_to_cpu(rsp_params->ep2_interface_id); 697 *state = le32_to_cpu(rsp_params->state); 698 for (i = 0; i < 16; i++) 699 endpoint2->type[i] = rsp_params->ep2_type[i]; 700 701 return 0; 702 } 703