cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dprc.c (21038B)


      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 */
     16static u16 dprc_major_ver;
     17static 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 */
     30int dprc_open(struct fsl_mc_io *mc_io,
     31	      u32 cmd_flags,
     32	      int container_id,
     33	      u16 *token)
     34{
     35	struct fsl_mc_command cmd = { 0 };
     36	struct dprc_cmd_open *cmd_params;
     37	int err;
     38
     39	/* prepare command */
     40	cmd.header = mc_encode_cmd_header(DPRC_CMDID_OPEN, cmd_flags,
     41					  0);
     42	cmd_params = (struct dprc_cmd_open *)cmd.params;
     43	cmd_params->container_id = cpu_to_le32(container_id);
     44
     45	/* send command to mc*/
     46	err = mc_send_command(mc_io, &cmd);
     47	if (err)
     48		return err;
     49
     50	/* retrieve response parameters */
     51	*token = mc_cmd_hdr_read_token(&cmd);
     52
     53	return 0;
     54}
     55EXPORT_SYMBOL_GPL(dprc_open);
     56
     57/**
     58 * dprc_close() - Close the control session of the 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 */
     68int dprc_close(struct fsl_mc_io *mc_io,
     69	       u32 cmd_flags,
     70	       u16 token)
     71{
     72	struct fsl_mc_command cmd = { 0 };
     73
     74	/* prepare command */
     75	cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLOSE, cmd_flags,
     76					  token);
     77
     78	/* send command to mc*/
     79	return mc_send_command(mc_io, &cmd);
     80}
     81EXPORT_SYMBOL_GPL(dprc_close);
     82
     83/**
     84 * dprc_reset_container - Reset child container.
     85 * @mc_io:	Pointer to MC portal's I/O 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 */
    112int dprc_reset_container(struct fsl_mc_io *mc_io,
    113			 u32 cmd_flags,
    114			 u16 token,
    115			 int child_container_id,
    116			 u32 options)
    117{
    118	struct fsl_mc_command cmd = { 0 };
    119	struct dprc_cmd_reset_container *cmd_params;
    120	u32 cmdid = DPRC_CMDID_RESET_CONT;
    121	int err;
    122
    123	/*
    124	 * If the DPRC object version was not yet cached, cache it now.
    125	 * Otherwise use the already cached value.
    126	 */
    127	if (!dprc_major_ver && !dprc_minor_ver) {
    128		err = dprc_get_api_version(mc_io, 0,
    129				&dprc_major_ver,
    130				&dprc_minor_ver);
    131		if (err)
    132			return err;
    133	}
    134
    135	/*
    136	 * MC API 6.5 introduced a new field in the command used to 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}
    152EXPORT_SYMBOL_GPL(dprc_reset_container);
    153
    154/**
    155 * dprc_set_irq() - Set IRQ information for the DPRC to trigger an interrupt.
    156 * @mc_io:	Pointer to MC portal's I/O 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 */
    164int dprc_set_irq(struct fsl_mc_io *mc_io,
    165		 u32 cmd_flags,
    166		 u16 token,
    167		 u8 irq_index,
    168		 struct dprc_irq_cfg *irq_cfg)
    169{
    170	struct fsl_mc_command cmd = { 0 };
    171	struct dprc_cmd_set_irq *cmd_params;
    172
    173	/* prepare command */
    174	cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ,
    175					  cmd_flags,
    176					  token);
    177	cmd_params = (struct dprc_cmd_set_irq *)cmd.params;
    178	cmd_params->irq_val = cpu_to_le32(irq_cfg->val);
    179	cmd_params->irq_index = irq_index;
    180	cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr);
    181	cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num);
    182
    183	/* send command to mc*/
    184	return mc_send_command(mc_io, &cmd);
    185}
    186
    187/**
    188 * dprc_set_irq_enable() - Set overall interrupt state.
    189 * @mc_io:	Pointer to MC portal's I/O 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 */
    202int dprc_set_irq_enable(struct fsl_mc_io *mc_io,
    203			u32 cmd_flags,
    204			u16 token,
    205			u8 irq_index,
    206			u8 en)
    207{
    208	struct fsl_mc_command cmd = { 0 };
    209	struct dprc_cmd_set_irq_enable *cmd_params;
    210
    211	/* prepare command */
    212	cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_ENABLE,
    213					  cmd_flags, token);
    214	cmd_params = (struct dprc_cmd_set_irq_enable *)cmd.params;
    215	cmd_params->enable = en & DPRC_ENABLE;
    216	cmd_params->irq_index = irq_index;
    217
    218	/* send command to mc*/
    219	return mc_send_command(mc_io, &cmd);
    220}
    221
    222/**
    223 * dprc_set_irq_mask() - Set interrupt mask.
    224 * @mc_io:	Pointer to MC portal's I/O 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 */
    238int dprc_set_irq_mask(struct fsl_mc_io *mc_io,
    239		      u32 cmd_flags,
    240		      u16 token,
    241		      u8 irq_index,
    242		      u32 mask)
    243{
    244	struct fsl_mc_command cmd = { 0 };
    245	struct dprc_cmd_set_irq_mask *cmd_params;
    246
    247	/* prepare command */
    248	cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_MASK,
    249					  cmd_flags, token);
    250	cmd_params = (struct dprc_cmd_set_irq_mask *)cmd.params;
    251	cmd_params->mask = cpu_to_le32(mask);
    252	cmd_params->irq_index = irq_index;
    253
    254	/* send command to mc*/
    255	return mc_send_command(mc_io, &cmd);
    256}
    257
    258/**
    259 * dprc_get_irq_status() - Get the current status of any pending interrupts.
    260 * @mc_io:	Pointer to MC portal's I/O 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 */
    270int dprc_get_irq_status(struct fsl_mc_io *mc_io,
    271			u32 cmd_flags,
    272			u16 token,
    273			u8 irq_index,
    274			u32 *status)
    275{
    276	struct fsl_mc_command cmd = { 0 };
    277	struct dprc_cmd_get_irq_status *cmd_params;
    278	struct dprc_rsp_get_irq_status *rsp_params;
    279	int err;
    280
    281	/* prepare command */
    282	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_STATUS,
    283					  cmd_flags, token);
    284	cmd_params = (struct dprc_cmd_get_irq_status *)cmd.params;
    285	cmd_params->status = cpu_to_le32(*status);
    286	cmd_params->irq_index = irq_index;
    287
    288	/* send command to mc*/
    289	err = mc_send_command(mc_io, &cmd);
    290	if (err)
    291		return err;
    292
    293	/* retrieve response parameters */
    294	rsp_params = (struct dprc_rsp_get_irq_status *)cmd.params;
    295	*status = le32_to_cpu(rsp_params->status);
    296
    297	return 0;
    298}
    299
    300/**
    301 * dprc_clear_irq_status() - Clear a pending interrupt's 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 */
    312int dprc_clear_irq_status(struct fsl_mc_io *mc_io,
    313			  u32 cmd_flags,
    314			  u16 token,
    315			  u8 irq_index,
    316			  u32 status)
    317{
    318	struct fsl_mc_command cmd = { 0 };
    319	struct dprc_cmd_clear_irq_status *cmd_params;
    320
    321	/* prepare command */
    322	cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLEAR_IRQ_STATUS,
    323					  cmd_flags, token);
    324	cmd_params = (struct dprc_cmd_clear_irq_status *)cmd.params;
    325	cmd_params->status = cpu_to_le32(status);
    326	cmd_params->irq_index = irq_index;
    327
    328	/* send command to mc*/
    329	return mc_send_command(mc_io, &cmd);
    330}
    331
    332/**
    333 * dprc_get_attributes() - Obtains container 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 */
    341int dprc_get_attributes(struct fsl_mc_io *mc_io,
    342			u32 cmd_flags,
    343			u16 token,
    344			struct dprc_attributes *attr)
    345{
    346	struct fsl_mc_command cmd = { 0 };
    347	struct dprc_rsp_get_attributes *rsp_params;
    348	int err;
    349
    350	/* prepare command */
    351	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_ATTR,
    352					  cmd_flags,
    353					  token);
    354
    355	/* send command to mc*/
    356	err = mc_send_command(mc_io, &cmd);
    357	if (err)
    358		return err;
    359
    360	/* retrieve response parameters */
    361	rsp_params = (struct dprc_rsp_get_attributes *)cmd.params;
    362	attr->container_id = le32_to_cpu(rsp_params->container_id);
    363	attr->icid = le32_to_cpu(rsp_params->icid);
    364	attr->options = le32_to_cpu(rsp_params->options);
    365	attr->portal_id = le32_to_cpu(rsp_params->portal_id);
    366
    367	return 0;
    368}
    369
    370/**
    371 * dprc_get_obj_count() - Obtains the number of objects in the 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 */
    379int dprc_get_obj_count(struct fsl_mc_io *mc_io,
    380		       u32 cmd_flags,
    381		       u16 token,
    382		       int *obj_count)
    383{
    384	struct fsl_mc_command cmd = { 0 };
    385	struct dprc_rsp_get_obj_count *rsp_params;
    386	int err;
    387
    388	/* prepare command */
    389	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_COUNT,
    390					  cmd_flags, token);
    391
    392	/* send command to mc*/
    393	err = mc_send_command(mc_io, &cmd);
    394	if (err)
    395		return err;
    396
    397	/* retrieve response parameters */
    398	rsp_params = (struct dprc_rsp_get_obj_count *)cmd.params;
    399	*obj_count = le32_to_cpu(rsp_params->obj_count);
    400
    401	return 0;
    402}
    403EXPORT_SYMBOL_GPL(dprc_get_obj_count);
    404
    405/**
    406 * dprc_get_obj() - Get general information on an 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 */
    420int dprc_get_obj(struct fsl_mc_io *mc_io,
    421		 u32 cmd_flags,
    422		 u16 token,
    423		 int obj_index,
    424		 struct fsl_mc_obj_desc *obj_desc)
    425{
    426	struct fsl_mc_command cmd = { 0 };
    427	struct dprc_cmd_get_obj *cmd_params;
    428	struct dprc_rsp_get_obj *rsp_params;
    429	int err;
    430
    431	/* prepare command */
    432	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ,
    433					  cmd_flags,
    434					  token);
    435	cmd_params = (struct dprc_cmd_get_obj *)cmd.params;
    436	cmd_params->obj_index = cpu_to_le32(obj_index);
    437
    438	/* send command to mc*/
    439	err = mc_send_command(mc_io, &cmd);
    440	if (err)
    441		return err;
    442
    443	/* retrieve response parameters */
    444	rsp_params = (struct dprc_rsp_get_obj *)cmd.params;
    445	obj_desc->id = le32_to_cpu(rsp_params->id);
    446	obj_desc->vendor = le16_to_cpu(rsp_params->vendor);
    447	obj_desc->irq_count = rsp_params->irq_count;
    448	obj_desc->region_count = rsp_params->region_count;
    449	obj_desc->state = le32_to_cpu(rsp_params->state);
    450	obj_desc->ver_major = le16_to_cpu(rsp_params->version_major);
    451	obj_desc->ver_minor = le16_to_cpu(rsp_params->version_minor);
    452	obj_desc->flags = le16_to_cpu(rsp_params->flags);
    453	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}
    459EXPORT_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 */
    473int 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}
    500EXPORT_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 */
    514int 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}
    588EXPORT_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 */
    599int 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 */
    630int 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 */
    668int 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}