bus: fsl-mc: add the fsl_mc_get_endpoint function

Using the newly added fsl_mc_get_endpoint function a fsl-mc driver can
find its associated endpoint (another object at the other link of a MC
firmware link).

The API will be used in the following patch in order to discover the
connected DPMAC object of a DPNI.

Also, the fsl_mc_device_lookup function is made available to the entire
fsl-mc bus driver and not just for the dprc driver.

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Ioana Ciornei 2019-10-31 01:18:29 +02:00 committed by David S. Miller
parent 6fff8c0107
commit 1ac210d128
5 changed files with 132 additions and 4 deletions

View File

@ -104,10 +104,8 @@ static int __fsl_mc_device_match(struct device *dev, void *data)
return fsl_mc_device_match(mc_dev, obj_desc); return fsl_mc_device_match(mc_dev, obj_desc);
} }
static struct fsl_mc_device *fsl_mc_device_lookup(struct fsl_mc_obj_desc struct fsl_mc_device *fsl_mc_device_lookup(struct fsl_mc_obj_desc *obj_desc,
*obj_desc, struct fsl_mc_device *mc_bus_dev)
struct fsl_mc_device
*mc_bus_dev)
{ {
struct device *dev; struct device *dev;

View File

@ -554,3 +554,56 @@ int dprc_get_container_id(struct fsl_mc_io *mc_io,
return 0; return 0;
} }
/**
* dprc_get_connection() - Get connected endpoint and link status if connection
* exists.
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPRC object
* @endpoint1: Endpoint 1 configuration parameters
* @endpoint2: Returned endpoint 2 configuration parameters
* @state: Returned link state:
* 1 - link is up;
* 0 - link is down;
* -1 - no connection (endpoint2 information is irrelevant)
*
* Return: '0' on Success; -ENOTCONN if connection does not exist.
*/
int dprc_get_connection(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
const struct dprc_endpoint *endpoint1,
struct dprc_endpoint *endpoint2,
int *state)
{
struct dprc_cmd_get_connection *cmd_params;
struct dprc_rsp_get_connection *rsp_params;
struct fsl_mc_command cmd = { 0 };
int err, i;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONNECTION,
cmd_flags,
token);
cmd_params = (struct dprc_cmd_get_connection *)cmd.params;
cmd_params->ep1_id = cpu_to_le32(endpoint1->id);
cmd_params->ep1_interface_id = cpu_to_le16(endpoint1->if_id);
for (i = 0; i < 16; i++)
cmd_params->ep1_type[i] = endpoint1->type[i];
/* send command to mc */
err = mc_send_command(mc_io, &cmd);
if (err)
return -ENOTCONN;
/* retrieve response parameters */
rsp_params = (struct dprc_rsp_get_connection *)cmd.params;
endpoint2->id = le32_to_cpu(rsp_params->ep2_id);
endpoint2->if_id = le16_to_cpu(rsp_params->ep2_interface_id);
*state = le32_to_cpu(rsp_params->state);
for (i = 0; i < 16; i++)
endpoint2->type[i] = rsp_params->ep2_type[i];
return 0;
}

View File

@ -712,6 +712,39 @@ void fsl_mc_device_remove(struct fsl_mc_device *mc_dev)
} }
EXPORT_SYMBOL_GPL(fsl_mc_device_remove); EXPORT_SYMBOL_GPL(fsl_mc_device_remove);
struct fsl_mc_device *fsl_mc_get_endpoint(struct fsl_mc_device *mc_dev)
{
struct fsl_mc_device *mc_bus_dev, *endpoint;
struct fsl_mc_obj_desc endpoint_desc = { 0 };
struct dprc_endpoint endpoint1 = { 0 };
struct dprc_endpoint endpoint2 = { 0 };
int state, err;
mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent);
strcpy(endpoint1.type, mc_dev->obj_desc.type);
endpoint1.id = mc_dev->obj_desc.id;
err = dprc_get_connection(mc_bus_dev->mc_io, 0,
mc_bus_dev->mc_handle,
&endpoint1, &endpoint2,
&state);
if (err == -ENOTCONN || state == -1)
return ERR_PTR(-ENOTCONN);
if (err < 0) {
dev_err(&mc_bus_dev->dev, "dprc_get_connection() = %d\n", err);
return ERR_PTR(err);
}
strcpy(endpoint_desc.type, endpoint2.type);
endpoint_desc.id = endpoint2.id;
endpoint = fsl_mc_device_lookup(&endpoint_desc, mc_bus_dev);
return endpoint;
}
EXPORT_SYMBOL_GPL(fsl_mc_get_endpoint);
static int parse_mc_ranges(struct device *dev, static int parse_mc_ranges(struct device *dev,
int *paddr_cells, int *paddr_cells,
int *mc_addr_cells, int *mc_addr_cells,

View File

@ -105,6 +105,8 @@ int dpmcp_reset(struct fsl_mc_io *mc_io,
#define DPRC_CMDID_GET_OBJ_REG_V2 DPRC_CMD_V2(0x15E) #define DPRC_CMDID_GET_OBJ_REG_V2 DPRC_CMD_V2(0x15E)
#define DPRC_CMDID_SET_OBJ_IRQ DPRC_CMD(0x15F) #define DPRC_CMDID_SET_OBJ_IRQ DPRC_CMD(0x15F)
#define DPRC_CMDID_GET_CONNECTION DPRC_CMD(0x16C)
struct dprc_cmd_open { struct dprc_cmd_open {
__le32 container_id; __le32 container_id;
}; };
@ -228,6 +230,22 @@ struct dprc_cmd_set_obj_irq {
u8 obj_type[16]; u8 obj_type[16];
}; };
struct dprc_cmd_get_connection {
__le32 ep1_id;
__le16 ep1_interface_id;
u8 pad[2];
u8 ep1_type[16];
};
struct dprc_rsp_get_connection {
__le64 pad[3];
__le32 ep2_id;
__le16 ep2_interface_id;
__le16 pad1;
u8 ep2_type[16];
__le32 state;
};
/* /*
* DPRC API for managing and querying DPAA resources * DPRC API for managing and querying DPAA resources
*/ */
@ -392,6 +410,27 @@ int dprc_get_container_id(struct fsl_mc_io *mc_io,
u32 cmd_flags, u32 cmd_flags,
int *container_id); int *container_id);
/**
* struct dprc_endpoint - Endpoint description for link connect/disconnect
* operations
* @type: Endpoint object type: NULL terminated string
* @id: Endpoint object ID
* @if_id: Interface ID; should be set for endpoints with multiple
* interfaces ("dpsw", "dpdmux"); for others, always set to 0
*/
struct dprc_endpoint {
char type[16];
int id;
u16 if_id;
};
int dprc_get_connection(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
const struct dprc_endpoint *endpoint1,
struct dprc_endpoint *endpoint2,
int *state);
/* /*
* Data Path Buffer Pool (DPBP) API * Data Path Buffer Pool (DPBP) API
*/ */
@ -574,4 +613,7 @@ void fsl_destroy_mc_io(struct fsl_mc_io *mc_io);
bool fsl_mc_is_root_dprc(struct device *dev); bool fsl_mc_is_root_dprc(struct device *dev);
struct fsl_mc_device *fsl_mc_device_lookup(struct fsl_mc_obj_desc *obj_desc,
struct fsl_mc_device *mc_bus_dev);
#endif /* _FSL_MC_PRIVATE_H_ */ #endif /* _FSL_MC_PRIVATE_H_ */

View File

@ -403,6 +403,8 @@ int __must_check fsl_mc_allocate_irqs(struct fsl_mc_device *mc_dev);
void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev); void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev);
struct fsl_mc_device *fsl_mc_get_endpoint(struct fsl_mc_device *mc_dev);
extern struct bus_type fsl_mc_bus_type; extern struct bus_type fsl_mc_bus_type;
extern struct device_type fsl_mc_bus_dprc_type; extern struct device_type fsl_mc_bus_dprc_type;