18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright 2013-2016 Freescale Semiconductor Inc.
48c2ecf20Sopenharmony_ci * Copyright 2016 NXP
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci#include <linux/kernel.h>
88c2ecf20Sopenharmony_ci#include <linux/fsl/mc.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include "dpio.h"
118c2ecf20Sopenharmony_ci#include "dpio-cmd.h"
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci/*
148c2ecf20Sopenharmony_ci * Data Path I/O Portal API
158c2ecf20Sopenharmony_ci * Contains initialization APIs and runtime control APIs for DPIO
168c2ecf20Sopenharmony_ci */
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci/**
198c2ecf20Sopenharmony_ci * dpio_open() - Open a control session for the specified object
208c2ecf20Sopenharmony_ci * @mc_io:	Pointer to MC portal's I/O object
218c2ecf20Sopenharmony_ci * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
228c2ecf20Sopenharmony_ci * @dpio_id:	DPIO unique ID
238c2ecf20Sopenharmony_ci * @token:	Returned token; use in subsequent API calls
248c2ecf20Sopenharmony_ci *
258c2ecf20Sopenharmony_ci * This function can be used to open a control session for an
268c2ecf20Sopenharmony_ci * already created object; an object may have been declared in
278c2ecf20Sopenharmony_ci * the DPL or by calling the dpio_create() function.
288c2ecf20Sopenharmony_ci * This function returns a unique authentication token,
298c2ecf20Sopenharmony_ci * associated with the specific object ID and the specific MC
308c2ecf20Sopenharmony_ci * portal; this token must be used in all subsequent commands for
318c2ecf20Sopenharmony_ci * this specific object.
328c2ecf20Sopenharmony_ci *
338c2ecf20Sopenharmony_ci * Return:	'0' on Success; Error code otherwise.
348c2ecf20Sopenharmony_ci */
358c2ecf20Sopenharmony_ciint dpio_open(struct fsl_mc_io *mc_io,
368c2ecf20Sopenharmony_ci	      u32 cmd_flags,
378c2ecf20Sopenharmony_ci	      int dpio_id,
388c2ecf20Sopenharmony_ci	      u16 *token)
398c2ecf20Sopenharmony_ci{
408c2ecf20Sopenharmony_ci	struct fsl_mc_command cmd = { 0 };
418c2ecf20Sopenharmony_ci	struct dpio_cmd_open *dpio_cmd;
428c2ecf20Sopenharmony_ci	int err;
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	/* prepare command */
458c2ecf20Sopenharmony_ci	cmd.header = mc_encode_cmd_header(DPIO_CMDID_OPEN,
468c2ecf20Sopenharmony_ci					  cmd_flags,
478c2ecf20Sopenharmony_ci					  0);
488c2ecf20Sopenharmony_ci	dpio_cmd = (struct dpio_cmd_open *)cmd.params;
498c2ecf20Sopenharmony_ci	dpio_cmd->dpio_id = cpu_to_le32(dpio_id);
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	err = mc_send_command(mc_io, &cmd);
528c2ecf20Sopenharmony_ci	if (err)
538c2ecf20Sopenharmony_ci		return err;
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	/* retrieve response parameters */
568c2ecf20Sopenharmony_ci	*token = mc_cmd_hdr_read_token(&cmd);
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci	return 0;
598c2ecf20Sopenharmony_ci}
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci/**
628c2ecf20Sopenharmony_ci * dpio_close() - Close the control session of the object
638c2ecf20Sopenharmony_ci * @mc_io:	Pointer to MC portal's I/O object
648c2ecf20Sopenharmony_ci * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
658c2ecf20Sopenharmony_ci * @token:	Token of DPIO object
668c2ecf20Sopenharmony_ci *
678c2ecf20Sopenharmony_ci * Return:	'0' on Success; Error code otherwise.
688c2ecf20Sopenharmony_ci */
698c2ecf20Sopenharmony_ciint dpio_close(struct fsl_mc_io *mc_io,
708c2ecf20Sopenharmony_ci	       u32 cmd_flags,
718c2ecf20Sopenharmony_ci	       u16 token)
728c2ecf20Sopenharmony_ci{
738c2ecf20Sopenharmony_ci	struct fsl_mc_command cmd = { 0 };
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci	/* prepare command */
768c2ecf20Sopenharmony_ci	cmd.header = mc_encode_cmd_header(DPIO_CMDID_CLOSE,
778c2ecf20Sopenharmony_ci					  cmd_flags,
788c2ecf20Sopenharmony_ci					  token);
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci	return mc_send_command(mc_io, &cmd);
818c2ecf20Sopenharmony_ci}
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci/**
848c2ecf20Sopenharmony_ci * dpio_enable() - Enable the DPIO, allow I/O portal operations.
858c2ecf20Sopenharmony_ci * @mc_io:	Pointer to MC portal's I/O object
868c2ecf20Sopenharmony_ci * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
878c2ecf20Sopenharmony_ci * @token:	Token of DPIO object
888c2ecf20Sopenharmony_ci *
898c2ecf20Sopenharmony_ci * Return:	'0' on Success; Error code otherwise
908c2ecf20Sopenharmony_ci */
918c2ecf20Sopenharmony_ciint dpio_enable(struct fsl_mc_io *mc_io,
928c2ecf20Sopenharmony_ci		u32 cmd_flags,
938c2ecf20Sopenharmony_ci		u16 token)
948c2ecf20Sopenharmony_ci{
958c2ecf20Sopenharmony_ci	struct fsl_mc_command cmd = { 0 };
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci	/* prepare command */
988c2ecf20Sopenharmony_ci	cmd.header = mc_encode_cmd_header(DPIO_CMDID_ENABLE,
998c2ecf20Sopenharmony_ci					  cmd_flags,
1008c2ecf20Sopenharmony_ci					  token);
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci	return mc_send_command(mc_io, &cmd);
1038c2ecf20Sopenharmony_ci}
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci/**
1068c2ecf20Sopenharmony_ci * dpio_disable() - Disable the DPIO, stop any I/O portal operation.
1078c2ecf20Sopenharmony_ci * @mc_io:	Pointer to MC portal's I/O object
1088c2ecf20Sopenharmony_ci * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1098c2ecf20Sopenharmony_ci * @token:	Token of DPIO object
1108c2ecf20Sopenharmony_ci *
1118c2ecf20Sopenharmony_ci * Return:	'0' on Success; Error code otherwise
1128c2ecf20Sopenharmony_ci */
1138c2ecf20Sopenharmony_ciint dpio_disable(struct fsl_mc_io *mc_io,
1148c2ecf20Sopenharmony_ci		 u32 cmd_flags,
1158c2ecf20Sopenharmony_ci		 u16 token)
1168c2ecf20Sopenharmony_ci{
1178c2ecf20Sopenharmony_ci	struct fsl_mc_command cmd = { 0 };
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	/* prepare command */
1208c2ecf20Sopenharmony_ci	cmd.header = mc_encode_cmd_header(DPIO_CMDID_DISABLE,
1218c2ecf20Sopenharmony_ci					  cmd_flags,
1228c2ecf20Sopenharmony_ci					  token);
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci	return mc_send_command(mc_io, &cmd);
1258c2ecf20Sopenharmony_ci}
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci/**
1288c2ecf20Sopenharmony_ci * dpio_get_attributes() - Retrieve DPIO attributes
1298c2ecf20Sopenharmony_ci * @mc_io:	Pointer to MC portal's I/O object
1308c2ecf20Sopenharmony_ci * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1318c2ecf20Sopenharmony_ci * @token:	Token of DPIO object
1328c2ecf20Sopenharmony_ci * @attr:	Returned object's attributes
1338c2ecf20Sopenharmony_ci *
1348c2ecf20Sopenharmony_ci * Return:	'0' on Success; Error code otherwise
1358c2ecf20Sopenharmony_ci */
1368c2ecf20Sopenharmony_ciint dpio_get_attributes(struct fsl_mc_io *mc_io,
1378c2ecf20Sopenharmony_ci			u32 cmd_flags,
1388c2ecf20Sopenharmony_ci			u16 token,
1398c2ecf20Sopenharmony_ci			struct dpio_attr *attr)
1408c2ecf20Sopenharmony_ci{
1418c2ecf20Sopenharmony_ci	struct fsl_mc_command cmd = { 0 };
1428c2ecf20Sopenharmony_ci	struct dpio_rsp_get_attr *dpio_rsp;
1438c2ecf20Sopenharmony_ci	int err;
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci	/* prepare command */
1468c2ecf20Sopenharmony_ci	cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_ATTR,
1478c2ecf20Sopenharmony_ci					  cmd_flags,
1488c2ecf20Sopenharmony_ci					  token);
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci	err = mc_send_command(mc_io, &cmd);
1518c2ecf20Sopenharmony_ci	if (err)
1528c2ecf20Sopenharmony_ci		return err;
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci	/* retrieve response parameters */
1558c2ecf20Sopenharmony_ci	dpio_rsp = (struct dpio_rsp_get_attr *)cmd.params;
1568c2ecf20Sopenharmony_ci	attr->id = le32_to_cpu(dpio_rsp->id);
1578c2ecf20Sopenharmony_ci	attr->qbman_portal_id = le16_to_cpu(dpio_rsp->qbman_portal_id);
1588c2ecf20Sopenharmony_ci	attr->num_priorities = dpio_rsp->num_priorities;
1598c2ecf20Sopenharmony_ci	attr->channel_mode = dpio_rsp->channel_mode & DPIO_CHANNEL_MODE_MASK;
1608c2ecf20Sopenharmony_ci	attr->qbman_portal_ce_offset =
1618c2ecf20Sopenharmony_ci		le64_to_cpu(dpio_rsp->qbman_portal_ce_addr);
1628c2ecf20Sopenharmony_ci	attr->qbman_portal_ci_offset =
1638c2ecf20Sopenharmony_ci		le64_to_cpu(dpio_rsp->qbman_portal_ci_addr);
1648c2ecf20Sopenharmony_ci	attr->qbman_version = le32_to_cpu(dpio_rsp->qbman_version);
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci	return 0;
1678c2ecf20Sopenharmony_ci}
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ciint dpio_set_stashing_destination(struct fsl_mc_io *mc_io,
1708c2ecf20Sopenharmony_ci				  u32 cmd_flags,
1718c2ecf20Sopenharmony_ci				  u16 token,
1728c2ecf20Sopenharmony_ci				  u8 sdest)
1738c2ecf20Sopenharmony_ci{
1748c2ecf20Sopenharmony_ci	struct fsl_mc_command cmd = { 0 };
1758c2ecf20Sopenharmony_ci	struct dpio_stashing_dest *dpio_cmd;
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ci	cmd.header = mc_encode_cmd_header(DPIO_CMDID_SET_STASHING_DEST,
1788c2ecf20Sopenharmony_ci					  cmd_flags, token);
1798c2ecf20Sopenharmony_ci	dpio_cmd = (struct dpio_stashing_dest *)cmd.params;
1808c2ecf20Sopenharmony_ci	dpio_cmd->sdest = sdest;
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci	return mc_send_command(mc_io, &cmd);
1838c2ecf20Sopenharmony_ci}
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci/**
1868c2ecf20Sopenharmony_ci * dpio_get_api_version - Get Data Path I/O API version
1878c2ecf20Sopenharmony_ci * @mc_io:	Pointer to MC portal's DPIO object
1888c2ecf20Sopenharmony_ci * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1898c2ecf20Sopenharmony_ci * @major_ver:	Major version of DPIO API
1908c2ecf20Sopenharmony_ci * @minor_ver:	Minor version of DPIO API
1918c2ecf20Sopenharmony_ci *
1928c2ecf20Sopenharmony_ci * Return:	'0' on Success; Error code otherwise
1938c2ecf20Sopenharmony_ci */
1948c2ecf20Sopenharmony_ciint dpio_get_api_version(struct fsl_mc_io *mc_io,
1958c2ecf20Sopenharmony_ci			 u32 cmd_flags,
1968c2ecf20Sopenharmony_ci			 u16 *major_ver,
1978c2ecf20Sopenharmony_ci			 u16 *minor_ver)
1988c2ecf20Sopenharmony_ci{
1998c2ecf20Sopenharmony_ci	struct fsl_mc_command cmd = { 0 };
2008c2ecf20Sopenharmony_ci	int err;
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci	/* prepare command */
2038c2ecf20Sopenharmony_ci	cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_API_VERSION,
2048c2ecf20Sopenharmony_ci					  cmd_flags, 0);
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci	err = mc_send_command(mc_io, &cmd);
2078c2ecf20Sopenharmony_ci	if (err)
2088c2ecf20Sopenharmony_ci		return err;
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci	/* retrieve response parameters */
2118c2ecf20Sopenharmony_ci	mc_cmd_read_api_version(&cmd, major_ver, minor_ver);
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci	return 0;
2148c2ecf20Sopenharmony_ci}
2158c2ecf20Sopenharmony_ci
2168c2ecf20Sopenharmony_ci/**
2178c2ecf20Sopenharmony_ci * dpio_reset() - Reset the DPIO, returns the object to initial state.
2188c2ecf20Sopenharmony_ci * @mc_io:	Pointer to MC portal's I/O object
2198c2ecf20Sopenharmony_ci * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
2208c2ecf20Sopenharmony_ci * @token:	Token of DPIO object
2218c2ecf20Sopenharmony_ci *
2228c2ecf20Sopenharmony_ci * Return:	'0' on Success; Error code otherwise.
2238c2ecf20Sopenharmony_ci */
2248c2ecf20Sopenharmony_ciint dpio_reset(struct fsl_mc_io *mc_io,
2258c2ecf20Sopenharmony_ci	       u32 cmd_flags,
2268c2ecf20Sopenharmony_ci	       u16 token)
2278c2ecf20Sopenharmony_ci{
2288c2ecf20Sopenharmony_ci	struct fsl_mc_command cmd = { 0 };
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_ci	/* prepare command */
2318c2ecf20Sopenharmony_ci	cmd.header = mc_encode_cmd_header(DPIO_CMDID_RESET,
2328c2ecf20Sopenharmony_ci					  cmd_flags,
2338c2ecf20Sopenharmony_ci					  token);
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_ci	/* send command to mc*/
2368c2ecf20Sopenharmony_ci	return mc_send_command(mc_io, &cmd);
2378c2ecf20Sopenharmony_ci}
238