Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
0002 /*
0003  * Copyright 2013-2016 Freescale Semiconductor Inc.
0004  * Copyright 2020 NXP
0005  *
0006  */
0007 #include <linux/kernel.h>
0008 #include <linux/fsl/mc.h>
0009 
0010 #include "fsl-mc-private.h"
0011 
0012 /*
0013  * cache the DPRC version to reduce the number of commands
0014  * towards the mc firmware
0015  */
0016 static u16 dprc_major_ver;
0017 static u16 dprc_minor_ver;
0018 
0019 /**
0020  * dprc_open() - Open DPRC object for use
0021  * @mc_io:  Pointer to MC portal's I/O object
0022  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
0023  * @container_id: Container ID to open
0024  * @token:  Returned token of DPRC object
0025  *
0026  * Return:  '0' on Success; Error code otherwise.
0027  *
0028  * @warning Required before any operation on the object.
0029  */
0030 int dprc_open(struct fsl_mc_io *mc_io,
0031           u32 cmd_flags,
0032           int container_id,
0033           u16 *token)
0034 {
0035     struct fsl_mc_command cmd = { 0 };
0036     struct dprc_cmd_open *cmd_params;
0037     int err;
0038 
0039     /* prepare command */
0040     cmd.header = mc_encode_cmd_header(DPRC_CMDID_OPEN, cmd_flags,
0041                       0);
0042     cmd_params = (struct dprc_cmd_open *)cmd.params;
0043     cmd_params->container_id = cpu_to_le32(container_id);
0044 
0045     /* send command to mc*/
0046     err = mc_send_command(mc_io, &cmd);
0047     if (err)
0048         return err;
0049 
0050     /* retrieve response parameters */
0051     *token = mc_cmd_hdr_read_token(&cmd);
0052 
0053     return 0;
0054 }
0055 EXPORT_SYMBOL_GPL(dprc_open);
0056 
0057 /**
0058  * dprc_close() - Close the control session of the object
0059  * @mc_io:  Pointer to MC portal's I/O object
0060  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
0061  * @token:  Token of DPRC object
0062  *
0063  * After this function is called, no further operations are
0064  * allowed on the object without opening a new control session.
0065  *
0066  * Return:  '0' on Success; Error code otherwise.
0067  */
0068 int dprc_close(struct fsl_mc_io *mc_io,
0069            u32 cmd_flags,
0070            u16 token)
0071 {
0072     struct fsl_mc_command cmd = { 0 };
0073 
0074     /* prepare command */
0075     cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLOSE, cmd_flags,
0076                       token);
0077 
0078     /* send command to mc*/
0079     return mc_send_command(mc_io, &cmd);
0080 }
0081 EXPORT_SYMBOL_GPL(dprc_close);
0082 
0083 /**
0084  * dprc_reset_container - Reset child container.
0085  * @mc_io:  Pointer to MC portal's I/O object
0086  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
0087  * @token:  Token of DPRC object
0088  * @child_container_id: ID of the container to reset
0089  * @options: 32 bit options:
0090  *   - 0 (no bits set) - all the objects inside the container are
0091  *     reset. The child containers are entered recursively and the
0092  *     objects reset. All the objects (including the child containers)
0093  *     are closed.
0094  *   - bit 0 set - all the objects inside the container are reset.
0095  *     However the child containers are not entered recursively.
0096  *     This option is supported for API versions >= 6.5
0097  * In case a software context crashes or becomes non-responsive, the parent
0098  * may wish to reset its resources container before the software context is
0099  * restarted.
0100  *
0101  * This routine informs all objects assigned to the child container that the
0102  * container is being reset, so they may perform any cleanup operations that are
0103  * needed. All objects handles that were owned by the child container shall be
0104  * closed.
0105  *
0106  * Note that such request may be submitted even if the child software context
0107  * has not crashed, but the resulting object cleanup operations will not be
0108  * aware of that.
0109  *
0110  * Return:  '0' on Success; Error code otherwise.
0111  */
0112 int dprc_reset_container(struct fsl_mc_io *mc_io,
0113              u32 cmd_flags,
0114              u16 token,
0115              int child_container_id,
0116              u32 options)
0117 {
0118     struct fsl_mc_command cmd = { 0 };
0119     struct dprc_cmd_reset_container *cmd_params;
0120     u32 cmdid = DPRC_CMDID_RESET_CONT;
0121     int err;
0122 
0123     /*
0124      * If the DPRC object version was not yet cached, cache it now.
0125      * Otherwise use the already cached value.
0126      */
0127     if (!dprc_major_ver && !dprc_minor_ver) {
0128         err = dprc_get_api_version(mc_io, 0,
0129                 &dprc_major_ver,
0130                 &dprc_minor_ver);
0131         if (err)
0132             return err;
0133     }
0134 
0135     /*
0136      * MC API 6.5 introduced a new field in the command used to pass
0137      * some flags.
0138      * Bit 0 indicates that the child containers are not recursively reset.
0139      */
0140     if (dprc_major_ver > 6 || (dprc_major_ver == 6 && dprc_minor_ver >= 5))
0141         cmdid = DPRC_CMDID_RESET_CONT_V2;
0142 
0143     /* prepare command */
0144     cmd.header = mc_encode_cmd_header(cmdid, cmd_flags, token);
0145     cmd_params = (struct dprc_cmd_reset_container *)cmd.params;
0146     cmd_params->child_container_id = cpu_to_le32(child_container_id);
0147     cmd_params->options = cpu_to_le32(options);
0148 
0149     /* send command to mc*/
0150     return mc_send_command(mc_io, &cmd);
0151 }
0152 EXPORT_SYMBOL_GPL(dprc_reset_container);
0153 
0154 /**
0155  * dprc_set_irq() - Set IRQ information for the DPRC to trigger an interrupt.
0156  * @mc_io:  Pointer to MC portal's I/O object
0157  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
0158  * @token:  Token of DPRC object
0159  * @irq_index:  Identifies the interrupt index to configure
0160  * @irq_cfg:    IRQ configuration
0161  *
0162  * Return:  '0' on Success; Error code otherwise.
0163  */
0164 int dprc_set_irq(struct fsl_mc_io *mc_io,
0165          u32 cmd_flags,
0166          u16 token,
0167          u8 irq_index,
0168          struct dprc_irq_cfg *irq_cfg)
0169 {
0170     struct fsl_mc_command cmd = { 0 };
0171     struct dprc_cmd_set_irq *cmd_params;
0172 
0173     /* prepare command */
0174     cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ,
0175                       cmd_flags,
0176                       token);
0177     cmd_params = (struct dprc_cmd_set_irq *)cmd.params;
0178     cmd_params->irq_val = cpu_to_le32(irq_cfg->val);
0179     cmd_params->irq_index = irq_index;
0180     cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr);
0181     cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num);
0182 
0183     /* send command to mc*/
0184     return mc_send_command(mc_io, &cmd);
0185 }
0186 
0187 /**
0188  * dprc_set_irq_enable() - Set overall interrupt state.
0189  * @mc_io:  Pointer to MC portal's I/O object
0190  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
0191  * @token:  Token of DPRC object
0192  * @irq_index:  The interrupt index to configure
0193  * @en:     Interrupt state - enable = 1, disable = 0
0194  *
0195  * Allows GPP software to control when interrupts are generated.
0196  * Each interrupt can have up to 32 causes.  The enable/disable control's the
0197  * overall interrupt state. if the interrupt is disabled no causes will cause
0198  * an interrupt.
0199  *
0200  * Return:  '0' on Success; Error code otherwise.
0201  */
0202 int dprc_set_irq_enable(struct fsl_mc_io *mc_io,
0203             u32 cmd_flags,
0204             u16 token,
0205             u8 irq_index,
0206             u8 en)
0207 {
0208     struct fsl_mc_command cmd = { 0 };
0209     struct dprc_cmd_set_irq_enable *cmd_params;
0210 
0211     /* prepare command */
0212     cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_ENABLE,
0213                       cmd_flags, token);
0214     cmd_params = (struct dprc_cmd_set_irq_enable *)cmd.params;
0215     cmd_params->enable = en & DPRC_ENABLE;
0216     cmd_params->irq_index = irq_index;
0217 
0218     /* send command to mc*/
0219     return mc_send_command(mc_io, &cmd);
0220 }
0221 
0222 /**
0223  * dprc_set_irq_mask() - Set interrupt mask.
0224  * @mc_io:  Pointer to MC portal's I/O object
0225  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
0226  * @token:  Token of DPRC object
0227  * @irq_index:  The interrupt index to configure
0228  * @mask:   event mask to trigger interrupt;
0229  *          each bit:
0230  *              0 = ignore event
0231  *              1 = consider event for asserting irq
0232  *
0233  * Every interrupt can have up to 32 causes and the interrupt model supports
0234  * masking/unmasking each cause independently
0235  *
0236  * Return:  '0' on Success; Error code otherwise.
0237  */
0238 int dprc_set_irq_mask(struct fsl_mc_io *mc_io,
0239               u32 cmd_flags,
0240               u16 token,
0241               u8 irq_index,
0242               u32 mask)
0243 {
0244     struct fsl_mc_command cmd = { 0 };
0245     struct dprc_cmd_set_irq_mask *cmd_params;
0246 
0247     /* prepare command */
0248     cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_MASK,
0249                       cmd_flags, token);
0250     cmd_params = (struct dprc_cmd_set_irq_mask *)cmd.params;
0251     cmd_params->mask = cpu_to_le32(mask);
0252     cmd_params->irq_index = irq_index;
0253 
0254     /* send command to mc*/
0255     return mc_send_command(mc_io, &cmd);
0256 }
0257 
0258 /**
0259  * dprc_get_irq_status() - Get the current status of any pending interrupts.
0260  * @mc_io:  Pointer to MC portal's I/O object
0261  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
0262  * @token:  Token of DPRC object
0263  * @irq_index:  The interrupt index to configure
0264  * @status: Returned interrupts status - one bit per cause:
0265  *          0 = no interrupt pending
0266  *          1 = interrupt pending
0267  *
0268  * Return:  '0' on Success; Error code otherwise.
0269  */
0270 int dprc_get_irq_status(struct fsl_mc_io *mc_io,
0271             u32 cmd_flags,
0272             u16 token,
0273             u8 irq_index,
0274             u32 *status)
0275 {
0276     struct fsl_mc_command cmd = { 0 };
0277     struct dprc_cmd_get_irq_status *cmd_params;
0278     struct dprc_rsp_get_irq_status *rsp_params;
0279     int err;
0280 
0281     /* prepare command */
0282     cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_STATUS,
0283                       cmd_flags, token);
0284     cmd_params = (struct dprc_cmd_get_irq_status *)cmd.params;
0285     cmd_params->status = cpu_to_le32(*status);
0286     cmd_params->irq_index = irq_index;
0287 
0288     /* send command to mc*/
0289     err = mc_send_command(mc_io, &cmd);
0290     if (err)
0291         return err;
0292 
0293     /* retrieve response parameters */
0294     rsp_params = (struct dprc_rsp_get_irq_status *)cmd.params;
0295     *status = le32_to_cpu(rsp_params->status);
0296 
0297     return 0;
0298 }
0299 
0300 /**
0301  * dprc_clear_irq_status() - Clear a pending interrupt's status
0302  * @mc_io:  Pointer to MC portal's I/O object
0303  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
0304  * @token:  Token of DPRC object
0305  * @irq_index:  The interrupt index to configure
0306  * @status: bits to clear (W1C) - one bit per cause:
0307  *                  0 = don't change
0308  *                  1 = clear status bit
0309  *
0310  * Return:  '0' on Success; Error code otherwise.
0311  */
0312 int dprc_clear_irq_status(struct fsl_mc_io *mc_io,
0313               u32 cmd_flags,
0314               u16 token,
0315               u8 irq_index,
0316               u32 status)
0317 {
0318     struct fsl_mc_command cmd = { 0 };
0319     struct dprc_cmd_clear_irq_status *cmd_params;
0320 
0321     /* prepare command */
0322     cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLEAR_IRQ_STATUS,
0323                       cmd_flags, token);
0324     cmd_params = (struct dprc_cmd_clear_irq_status *)cmd.params;
0325     cmd_params->status = cpu_to_le32(status);
0326     cmd_params->irq_index = irq_index;
0327 
0328     /* send command to mc*/
0329     return mc_send_command(mc_io, &cmd);
0330 }
0331 
0332 /**
0333  * dprc_get_attributes() - Obtains container attributes
0334  * @mc_io:  Pointer to MC portal's I/O object
0335  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
0336  * @token:  Token of DPRC object
0337  * @attr:   Returned container attributes
0338  *
0339  * Return:     '0' on Success; Error code otherwise.
0340  */
0341 int dprc_get_attributes(struct fsl_mc_io *mc_io,
0342             u32 cmd_flags,
0343             u16 token,
0344             struct dprc_attributes *attr)
0345 {
0346     struct fsl_mc_command cmd = { 0 };
0347     struct dprc_rsp_get_attributes *rsp_params;
0348     int err;
0349 
0350     /* prepare command */
0351     cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_ATTR,
0352                       cmd_flags,
0353                       token);
0354 
0355     /* send command to mc*/
0356     err = mc_send_command(mc_io, &cmd);
0357     if (err)
0358         return err;
0359 
0360     /* retrieve response parameters */
0361     rsp_params = (struct dprc_rsp_get_attributes *)cmd.params;
0362     attr->container_id = le32_to_cpu(rsp_params->container_id);
0363     attr->icid = le32_to_cpu(rsp_params->icid);
0364     attr->options = le32_to_cpu(rsp_params->options);
0365     attr->portal_id = le32_to_cpu(rsp_params->portal_id);
0366 
0367     return 0;
0368 }
0369 
0370 /**
0371  * dprc_get_obj_count() - Obtains the number of objects in the DPRC
0372  * @mc_io:  Pointer to MC portal's I/O object
0373  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
0374  * @token:  Token of DPRC object
0375  * @obj_count:  Number of objects assigned to the DPRC
0376  *
0377  * Return:  '0' on Success; Error code otherwise.
0378  */
0379 int dprc_get_obj_count(struct fsl_mc_io *mc_io,
0380                u32 cmd_flags,
0381                u16 token,
0382                int *obj_count)
0383 {
0384     struct fsl_mc_command cmd = { 0 };
0385     struct dprc_rsp_get_obj_count *rsp_params;
0386     int err;
0387 
0388     /* prepare command */
0389     cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_COUNT,
0390                       cmd_flags, token);
0391 
0392     /* send command to mc*/
0393     err = mc_send_command(mc_io, &cmd);
0394     if (err)
0395         return err;
0396 
0397     /* retrieve response parameters */
0398     rsp_params = (struct dprc_rsp_get_obj_count *)cmd.params;
0399     *obj_count = le32_to_cpu(rsp_params->obj_count);
0400 
0401     return 0;
0402 }
0403 EXPORT_SYMBOL_GPL(dprc_get_obj_count);
0404 
0405 /**
0406  * dprc_get_obj() - Get general information on an object
0407  * @mc_io:  Pointer to MC portal's I/O object
0408  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
0409  * @token:  Token of DPRC object
0410  * @obj_index:  Index of the object to be queried (< obj_count)
0411  * @obj_desc:   Returns the requested object descriptor
0412  *
0413  * The object descriptors are retrieved one by one by incrementing
0414  * obj_index up to (not including) the value of obj_count returned
0415  * from dprc_get_obj_count(). dprc_get_obj_count() must
0416  * be called prior to dprc_get_obj().
0417  *
0418  * Return:  '0' on Success; Error code otherwise.
0419  */
0420 int dprc_get_obj(struct fsl_mc_io *mc_io,
0421          u32 cmd_flags,
0422          u16 token,
0423          int obj_index,
0424          struct fsl_mc_obj_desc *obj_desc)
0425 {
0426     struct fsl_mc_command cmd = { 0 };
0427     struct dprc_cmd_get_obj *cmd_params;
0428     struct dprc_rsp_get_obj *rsp_params;
0429     int err;
0430 
0431     /* prepare command */
0432     cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ,
0433                       cmd_flags,
0434                       token);
0435     cmd_params = (struct dprc_cmd_get_obj *)cmd.params;
0436     cmd_params->obj_index = cpu_to_le32(obj_index);
0437 
0438     /* send command to mc*/
0439     err = mc_send_command(mc_io, &cmd);
0440     if (err)
0441         return err;
0442 
0443     /* retrieve response parameters */
0444     rsp_params = (struct dprc_rsp_get_obj *)cmd.params;
0445     obj_desc->id = le32_to_cpu(rsp_params->id);
0446     obj_desc->vendor = le16_to_cpu(rsp_params->vendor);
0447     obj_desc->irq_count = rsp_params->irq_count;
0448     obj_desc->region_count = rsp_params->region_count;
0449     obj_desc->state = le32_to_cpu(rsp_params->state);
0450     obj_desc->ver_major = le16_to_cpu(rsp_params->version_major);
0451     obj_desc->ver_minor = le16_to_cpu(rsp_params->version_minor);
0452     obj_desc->flags = le16_to_cpu(rsp_params->flags);
0453     strncpy(obj_desc->type, rsp_params->type, 16);
0454     obj_desc->type[15] = '\0';
0455     strncpy(obj_desc->label, rsp_params->label, 16);
0456     obj_desc->label[15] = '\0';
0457     return 0;
0458 }
0459 EXPORT_SYMBOL_GPL(dprc_get_obj);
0460 
0461 /**
0462  * dprc_set_obj_irq() - Set IRQ information for object to trigger an interrupt.
0463  * @mc_io:  Pointer to MC portal's I/O object
0464  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
0465  * @token:  Token of DPRC object
0466  * @obj_type:   Type of the object to set its IRQ
0467  * @obj_id: ID of the object to set its IRQ
0468  * @irq_index:  The interrupt index to configure
0469  * @irq_cfg:    IRQ configuration
0470  *
0471  * Return:  '0' on Success; Error code otherwise.
0472  */
0473 int dprc_set_obj_irq(struct fsl_mc_io *mc_io,
0474              u32 cmd_flags,
0475              u16 token,
0476              char *obj_type,
0477              int obj_id,
0478              u8 irq_index,
0479              struct dprc_irq_cfg *irq_cfg)
0480 {
0481     struct fsl_mc_command cmd = { 0 };
0482     struct dprc_cmd_set_obj_irq *cmd_params;
0483 
0484     /* prepare command */
0485     cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_OBJ_IRQ,
0486                       cmd_flags,
0487                       token);
0488     cmd_params = (struct dprc_cmd_set_obj_irq *)cmd.params;
0489     cmd_params->irq_val = cpu_to_le32(irq_cfg->val);
0490     cmd_params->irq_index = irq_index;
0491     cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr);
0492     cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num);
0493     cmd_params->obj_id = cpu_to_le32(obj_id);
0494     strncpy(cmd_params->obj_type, obj_type, 16);
0495     cmd_params->obj_type[15] = '\0';
0496 
0497     /* send command to mc*/
0498     return mc_send_command(mc_io, &cmd);
0499 }
0500 EXPORT_SYMBOL_GPL(dprc_set_obj_irq);
0501 
0502 /**
0503  * dprc_get_obj_region() - Get region information for a specified object.
0504  * @mc_io:  Pointer to MC portal's I/O object
0505  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
0506  * @token:  Token of DPRC object
0507  * @obj_type:   Object type as returned in dprc_get_obj()
0508  * @obj_id: Unique object instance as returned in dprc_get_obj()
0509  * @region_index: The specific region to query
0510  * @region_desc:  Returns the requested region descriptor
0511  *
0512  * Return:  '0' on Success; Error code otherwise.
0513  */
0514 int dprc_get_obj_region(struct fsl_mc_io *mc_io,
0515             u32 cmd_flags,
0516             u16 token,
0517             char *obj_type,
0518             int obj_id,
0519             u8 region_index,
0520             struct dprc_region_desc *region_desc)
0521 {
0522     struct fsl_mc_command cmd = { 0 };
0523     struct dprc_cmd_get_obj_region *cmd_params;
0524     struct dprc_rsp_get_obj_region *rsp_params;
0525     int err;
0526 
0527     /*
0528      * If the DPRC object version was not yet cached, cache it now.
0529      * Otherwise use the already cached value.
0530      */
0531     if (!dprc_major_ver && !dprc_minor_ver) {
0532         err = dprc_get_api_version(mc_io, 0,
0533                       &dprc_major_ver,
0534                       &dprc_minor_ver);
0535         if (err)
0536             return err;
0537     }
0538 
0539     if (dprc_major_ver > 6 || (dprc_major_ver == 6 && dprc_minor_ver >= 6)) {
0540         /*
0541          * MC API version 6.6 changed the size of the MC portals and software
0542          * portals to 64K (as implemented by hardware). If older API is in use the
0543          * size reported is less (64 bytes for mc portals and 4K for software
0544          * portals).
0545          */
0546 
0547         cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG_V3,
0548                           cmd_flags, token);
0549 
0550     } else if (dprc_major_ver == 6 && dprc_minor_ver >= 3) {
0551         /*
0552          * MC API version 6.3 introduced a new field to the region
0553          * descriptor: base_address. If the older API is in use then the base
0554          * address is set to zero to indicate it needs to be obtained elsewhere
0555          * (typically the device tree).
0556          */
0557         cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG_V2,
0558                           cmd_flags, token);
0559     } else {
0560         cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG,
0561                           cmd_flags, token);
0562     }
0563 
0564     cmd_params = (struct dprc_cmd_get_obj_region *)cmd.params;
0565     cmd_params->obj_id = cpu_to_le32(obj_id);
0566     cmd_params->region_index = region_index;
0567     strncpy(cmd_params->obj_type, obj_type, 16);
0568     cmd_params->obj_type[15] = '\0';
0569 
0570     /* send command to mc*/
0571     err = mc_send_command(mc_io, &cmd);
0572     if (err)
0573         return err;
0574 
0575     /* retrieve response parameters */
0576     rsp_params = (struct dprc_rsp_get_obj_region *)cmd.params;
0577     region_desc->base_offset = le64_to_cpu(rsp_params->base_offset);
0578     region_desc->size = le32_to_cpu(rsp_params->size);
0579     region_desc->type = rsp_params->type;
0580     region_desc->flags = le32_to_cpu(rsp_params->flags);
0581     if (dprc_major_ver > 6 || (dprc_major_ver == 6 && dprc_minor_ver >= 3))
0582         region_desc->base_address = le64_to_cpu(rsp_params->base_addr);
0583     else
0584         region_desc->base_address = 0;
0585 
0586     return 0;
0587 }
0588 EXPORT_SYMBOL_GPL(dprc_get_obj_region);
0589 
0590 /**
0591  * dprc_get_api_version - Get Data Path Resource Container API version
0592  * @mc_io:  Pointer to Mc portal's I/O object
0593  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
0594  * @major_ver:  Major version of Data Path Resource Container API
0595  * @minor_ver:  Minor version of Data Path Resource Container API
0596  *
0597  * Return:  '0' on Success; Error code otherwise.
0598  */
0599 int dprc_get_api_version(struct fsl_mc_io *mc_io,
0600              u32 cmd_flags,
0601              u16 *major_ver,
0602              u16 *minor_ver)
0603 {
0604     struct fsl_mc_command cmd = { 0 };
0605     int err;
0606 
0607     /* prepare command */
0608     cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_API_VERSION,
0609                       cmd_flags, 0);
0610 
0611     /* send command to mc */
0612     err = mc_send_command(mc_io, &cmd);
0613     if (err)
0614         return err;
0615 
0616     /* retrieve response parameters */
0617     mc_cmd_read_api_version(&cmd, major_ver, minor_ver);
0618 
0619     return 0;
0620 }
0621 
0622 /**
0623  * dprc_get_container_id - Get container ID associated with a given portal.
0624  * @mc_io:      Pointer to Mc portal's I/O object
0625  * @cmd_flags:      Command flags; one or more of 'MC_CMD_FLAG_'
0626  * @container_id:   Requested container id
0627  *
0628  * Return:  '0' on Success; Error code otherwise.
0629  */
0630 int dprc_get_container_id(struct fsl_mc_io *mc_io,
0631               u32 cmd_flags,
0632               int *container_id)
0633 {
0634     struct fsl_mc_command cmd = { 0 };
0635     int err;
0636 
0637     /* prepare command */
0638     cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONT_ID,
0639                       cmd_flags,
0640                       0);
0641 
0642     /* send command to mc*/
0643     err = mc_send_command(mc_io, &cmd);
0644     if (err)
0645         return err;
0646 
0647     /* retrieve response parameters */
0648     *container_id = (int)mc_cmd_read_object_id(&cmd);
0649 
0650     return 0;
0651 }
0652 
0653 /**
0654  * dprc_get_connection() - Get connected endpoint and link status if connection
0655  *          exists.
0656  * @mc_io:  Pointer to MC portal's I/O object
0657  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
0658  * @token:  Token of DPRC object
0659  * @endpoint1:  Endpoint 1 configuration parameters
0660  * @endpoint2:  Returned endpoint 2 configuration parameters
0661  * @state:  Returned link state:
0662  *      1 - link is up;
0663  *      0 - link is down;
0664  *      -1 - no connection (endpoint2 information is irrelevant)
0665  *
0666  * Return:     '0' on Success; -ENOTCONN if connection does not exist.
0667  */
0668 int dprc_get_connection(struct fsl_mc_io *mc_io,
0669             u32 cmd_flags,
0670             u16 token,
0671             const struct dprc_endpoint *endpoint1,
0672             struct dprc_endpoint *endpoint2,
0673             int *state)
0674 {
0675     struct dprc_cmd_get_connection *cmd_params;
0676     struct dprc_rsp_get_connection *rsp_params;
0677     struct fsl_mc_command cmd = { 0 };
0678     int err, i;
0679 
0680     /* prepare command */
0681     cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONNECTION,
0682                       cmd_flags,
0683                       token);
0684     cmd_params = (struct dprc_cmd_get_connection *)cmd.params;
0685     cmd_params->ep1_id = cpu_to_le32(endpoint1->id);
0686     cmd_params->ep1_interface_id = cpu_to_le16(endpoint1->if_id);
0687     for (i = 0; i < 16; i++)
0688         cmd_params->ep1_type[i] = endpoint1->type[i];
0689 
0690     /* send command to mc */
0691     err = mc_send_command(mc_io, &cmd);
0692     if (err)
0693         return -ENOTCONN;
0694 
0695     /* retrieve response parameters */
0696     rsp_params = (struct dprc_rsp_get_connection *)cmd.params;
0697     endpoint2->id = le32_to_cpu(rsp_params->ep2_id);
0698     endpoint2->if_id = le16_to_cpu(rsp_params->ep2_interface_id);
0699     *state = le32_to_cpu(rsp_params->state);
0700     for (i = 0; i < 16; i++)
0701         endpoint2->type[i] = rsp_params->ep2_type[i];
0702 
0703     return 0;
0704 }