// SPDX-License-Identifier: GPL-2.01// Copyright 2019 NXP23#include <linux/bitfield.h>4#include <linux/module.h>5#include <linux/types.h>6#include <linux/io.h>7#include <linux/fsl/mc.h>8#include "dpdmai.h"910#define DEST_TYPE_MASK 0xF1112struct dpdmai_rsp_get_attributes {13__le32 id;14u8 num_of_priorities;15u8 num_of_queues;16u8 pad0[2];17__le16 major;18__le16 minor;19};2021struct dpdmai_cmd_queue {22__le32 dest_id;23u8 dest_priority;24union {25u8 queue;26u8 pri;27};28u8 dest_type;29u8 queue_idx;30__le64 user_ctx;31union {32__le32 options;33__le32 fqid;34};35} __packed;3637struct dpdmai_rsp_get_tx_queue {38__le64 pad;39__le32 fqid;40};4142struct dpdmai_cmd_open {43__le32 dpdmai_id;44} __packed;4546struct dpdmai_cmd_destroy {47__le32 dpdmai_id;48} __packed;4950/**51* dpdmai_open() - Open a control session for the specified object52* @mc_io: Pointer to MC portal's I/O object53* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'54* @dpdmai_id: DPDMAI unique ID55* @token: Returned token; use in subsequent API calls56*57* This function can be used to open a control session for an58* already created object; an object may have been declared in59* the DPL or by calling the dpdmai_create() function.60* This function returns a unique authentication token,61* associated with the specific object ID and the specific MC62* portal; this token must be used in all subsequent commands for63* this specific object.64*65* Return: '0' on Success; Error code otherwise.66*/67int dpdmai_open(struct fsl_mc_io *mc_io, u32 cmd_flags,68int dpdmai_id, u16 *token)69{70struct dpdmai_cmd_open *cmd_params;71struct fsl_mc_command cmd = { 0 };72int err;7374/* prepare command */75cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_OPEN,76cmd_flags, 0);7778cmd_params = (struct dpdmai_cmd_open *)&cmd.params;79cmd_params->dpdmai_id = cpu_to_le32(dpdmai_id);8081/* send command to mc*/82err = mc_send_command(mc_io, &cmd);83if (err)84return err;8586/* retrieve response parameters */87*token = mc_cmd_hdr_read_token(&cmd);8889return 0;90}91EXPORT_SYMBOL_GPL(dpdmai_open);9293/**94* dpdmai_close() - Close the control session of the object95* @mc_io: Pointer to MC portal's I/O object96* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'97* @token: Token of DPDMAI object98*99* After this function is called, no further operations are100* allowed on the object without opening a new control session.101*102* Return: '0' on Success; Error code otherwise.103*/104int dpdmai_close(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)105{106struct fsl_mc_command cmd = { 0 };107108/* prepare command */109cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_CLOSE,110cmd_flags, token);111112/* send command to mc*/113return mc_send_command(mc_io, &cmd);114}115EXPORT_SYMBOL_GPL(dpdmai_close);116117/**118* dpdmai_destroy() - Destroy the DPDMAI object and release all its resources.119* @mc_io: Pointer to MC portal's I/O object120* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'121* @dpdmai_id: The object id; it must be a valid id within the container that created this object;122* @token: Token of DPDMAI object123*124* Return: '0' on Success; error code otherwise.125*/126int dpdmai_destroy(struct fsl_mc_io *mc_io, u32 cmd_flags, u32 dpdmai_id, u16 token)127{128struct dpdmai_cmd_destroy *cmd_params;129struct fsl_mc_command cmd = { 0 };130131/* prepare command */132cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_DESTROY,133cmd_flags, token);134135cmd_params = (struct dpdmai_cmd_destroy *)&cmd.params;136cmd_params->dpdmai_id = cpu_to_le32(dpdmai_id);137138/* send command to mc*/139return mc_send_command(mc_io, &cmd);140}141EXPORT_SYMBOL_GPL(dpdmai_destroy);142143/**144* dpdmai_enable() - Enable the DPDMAI, allow sending and receiving frames.145* @mc_io: Pointer to MC portal's I/O object146* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'147* @token: Token of DPDMAI object148*149* Return: '0' on Success; Error code otherwise.150*/151int dpdmai_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)152{153struct fsl_mc_command cmd = { 0 };154155/* prepare command */156cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_ENABLE,157cmd_flags, token);158159/* send command to mc*/160return mc_send_command(mc_io, &cmd);161}162EXPORT_SYMBOL_GPL(dpdmai_enable);163164/**165* dpdmai_disable() - Disable the DPDMAI, stop sending and receiving frames.166* @mc_io: Pointer to MC portal's I/O object167* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'168* @token: Token of DPDMAI object169*170* Return: '0' on Success; Error code otherwise.171*/172int dpdmai_disable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)173{174struct fsl_mc_command cmd = { 0 };175176/* prepare command */177cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_DISABLE,178cmd_flags, token);179180/* send command to mc*/181return mc_send_command(mc_io, &cmd);182}183EXPORT_SYMBOL_GPL(dpdmai_disable);184185/**186* dpdmai_reset() - Reset the DPDMAI, returns the object to initial state.187* @mc_io: Pointer to MC portal's I/O object188* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'189* @token: Token of DPDMAI object190*191* Return: '0' on Success; Error code otherwise.192*/193int dpdmai_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)194{195struct fsl_mc_command cmd = { 0 };196197/* prepare command */198cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_RESET,199cmd_flags, token);200201/* send command to mc*/202return mc_send_command(mc_io, &cmd);203}204EXPORT_SYMBOL_GPL(dpdmai_reset);205206/**207* dpdmai_get_attributes() - Retrieve DPDMAI attributes.208* @mc_io: Pointer to MC portal's I/O object209* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'210* @token: Token of DPDMAI object211* @attr: Returned object's attributes212*213* Return: '0' on Success; Error code otherwise.214*/215int dpdmai_get_attributes(struct fsl_mc_io *mc_io, u32 cmd_flags,216u16 token, struct dpdmai_attr *attr)217{218struct dpdmai_rsp_get_attributes *rsp_params;219struct fsl_mc_command cmd = { 0 };220int err;221222/* prepare command */223cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_ATTR,224cmd_flags, token);225226/* send command to mc*/227err = mc_send_command(mc_io, &cmd);228if (err)229return err;230231/* retrieve response parameters */232rsp_params = (struct dpdmai_rsp_get_attributes *)cmd.params;233attr->id = le32_to_cpu(rsp_params->id);234attr->version.major = le16_to_cpu(rsp_params->major);235attr->version.minor = le16_to_cpu(rsp_params->minor);236attr->num_of_priorities = rsp_params->num_of_priorities;237attr->num_of_queues = rsp_params->num_of_queues;238239return 0;240}241EXPORT_SYMBOL_GPL(dpdmai_get_attributes);242243/**244* dpdmai_set_rx_queue() - Set Rx queue configuration245* @mc_io: Pointer to MC portal's I/O object246* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'247* @token: Token of DPDMAI object248* @queue_idx: DMA queue index249* @priority: Select the queue relative to number of250* priorities configured at DPDMAI creation251* @cfg: Rx queue configuration252*253* Return: '0' on Success; Error code otherwise.254*/255int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u8 queue_idx,256u8 priority, const struct dpdmai_rx_queue_cfg *cfg)257{258struct dpdmai_cmd_queue *cmd_params;259struct fsl_mc_command cmd = { 0 };260261/* prepare command */262cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_SET_RX_QUEUE,263cmd_flags, token);264265cmd_params = (struct dpdmai_cmd_queue *)cmd.params;266cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);267cmd_params->dest_priority = cfg->dest_cfg.priority;268cmd_params->pri = priority;269cmd_params->dest_type = cfg->dest_cfg.dest_type;270cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx);271cmd_params->options = cpu_to_le32(cfg->options);272cmd_params->queue_idx = queue_idx;273274/* send command to mc*/275return mc_send_command(mc_io, &cmd);276}277EXPORT_SYMBOL_GPL(dpdmai_set_rx_queue);278279/**280* dpdmai_get_rx_queue() - Retrieve Rx queue attributes.281* @mc_io: Pointer to MC portal's I/O object282* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'283* @token: Token of DPDMAI object284* @queue_idx: DMA Queue index285* @priority: Select the queue relative to number of286* priorities configured at DPDMAI creation287* @attr: Returned Rx queue attributes288*289* Return: '0' on Success; Error code otherwise.290*/291int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u8 queue_idx,292u8 priority, struct dpdmai_rx_queue_attr *attr)293{294struct dpdmai_cmd_queue *cmd_params;295struct fsl_mc_command cmd = { 0 };296int err;297298/* prepare command */299cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_RX_QUEUE,300cmd_flags, token);301302cmd_params = (struct dpdmai_cmd_queue *)cmd.params;303cmd_params->queue = priority;304cmd_params->queue_idx = queue_idx;305306/* send command to mc*/307err = mc_send_command(mc_io, &cmd);308if (err)309return err;310311/* retrieve response parameters */312attr->dest_cfg.dest_id = le32_to_cpu(cmd_params->dest_id);313attr->dest_cfg.priority = cmd_params->dest_priority;314attr->dest_cfg.dest_type = FIELD_GET(DEST_TYPE_MASK, cmd_params->dest_type);315attr->user_ctx = le64_to_cpu(cmd_params->user_ctx);316attr->fqid = le32_to_cpu(cmd_params->fqid);317318return 0;319}320EXPORT_SYMBOL_GPL(dpdmai_get_rx_queue);321322/**323* dpdmai_get_tx_queue() - Retrieve Tx queue attributes.324* @mc_io: Pointer to MC portal's I/O object325* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'326* @token: Token of DPDMAI object327* @queue_idx: DMA queue index328* @priority: Select the queue relative to number of329* priorities configured at DPDMAI creation330* @attr: Returned DMA Tx queue attributes331*332* Return: '0' on Success; Error code otherwise.333*/334int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io, u32 cmd_flags,335u16 token, u8 queue_idx, u8 priority, struct dpdmai_tx_queue_attr *attr)336{337struct dpdmai_rsp_get_tx_queue *rsp_params;338struct dpdmai_cmd_queue *cmd_params;339struct fsl_mc_command cmd = { 0 };340int err;341342/* prepare command */343cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_TX_QUEUE,344cmd_flags, token);345346cmd_params = (struct dpdmai_cmd_queue *)cmd.params;347cmd_params->queue = priority;348cmd_params->queue_idx = queue_idx;349350/* send command to mc*/351err = mc_send_command(mc_io, &cmd);352if (err)353return err;354355/* retrieve response parameters */356357rsp_params = (struct dpdmai_rsp_get_tx_queue *)cmd.params;358attr->fqid = le32_to_cpu(rsp_params->fqid);359360return 0;361}362EXPORT_SYMBOL_GPL(dpdmai_get_tx_queue);363364MODULE_DESCRIPTION("NXP DPAA2 QDMA driver");365MODULE_LICENSE("GPL v2");366367368