372 lines · c
1// SPDX-License-Identifier: GPL-2.02// Copyright 2019 NXP3 4#include <linux/bitfield.h>5#include <linux/module.h>6#include <linux/types.h>7#include <linux/io.h>8#include <linux/fsl/mc.h>9#include "dpdmai.h"10 11#define DEST_TYPE_MASK 0xF12 13struct dpdmai_rsp_get_attributes {14 __le32 id;15 u8 num_of_priorities;16 u8 num_of_queues;17 u8 pad0[2];18 __le16 major;19 __le16 minor;20};21 22struct dpdmai_cmd_queue {23 __le32 dest_id;24 u8 dest_priority;25 union {26 u8 queue;27 u8 pri;28 };29 u8 dest_type;30 u8 queue_idx;31 __le64 user_ctx;32 union {33 __le32 options;34 __le32 fqid;35 };36} __packed;37 38struct dpdmai_rsp_get_tx_queue {39 __le64 pad;40 __le32 fqid;41};42 43struct dpdmai_cmd_open {44 __le32 dpdmai_id;45} __packed;46 47struct dpdmai_cmd_destroy {48 __le32 dpdmai_id;49} __packed;50 51static inline u64 mc_enc(int lsoffset, int width, u64 val)52{53 return (val & MAKE_UMASK64(width)) << lsoffset;54}55 56/**57 * dpdmai_open() - Open a control session for the specified object58 * @mc_io: Pointer to MC portal's I/O object59 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'60 * @dpdmai_id: DPDMAI unique ID61 * @token: Returned token; use in subsequent API calls62 *63 * This function can be used to open a control session for an64 * already created object; an object may have been declared in65 * the DPL or by calling the dpdmai_create() function.66 * This function returns a unique authentication token,67 * associated with the specific object ID and the specific MC68 * portal; this token must be used in all subsequent commands for69 * this specific object.70 *71 * Return: '0' on Success; Error code otherwise.72 */73int dpdmai_open(struct fsl_mc_io *mc_io, u32 cmd_flags,74 int dpdmai_id, u16 *token)75{76 struct dpdmai_cmd_open *cmd_params;77 struct fsl_mc_command cmd = { 0 };78 int err;79 80 /* prepare command */81 cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_OPEN,82 cmd_flags, 0);83 84 cmd_params = (struct dpdmai_cmd_open *)&cmd.params;85 cmd_params->dpdmai_id = cpu_to_le32(dpdmai_id);86 87 /* send command to mc*/88 err = mc_send_command(mc_io, &cmd);89 if (err)90 return err;91 92 /* retrieve response parameters */93 *token = mc_cmd_hdr_read_token(&cmd);94 95 return 0;96}97EXPORT_SYMBOL_GPL(dpdmai_open);98 99/**100 * dpdmai_close() - Close the control session of the object101 * @mc_io: Pointer to MC portal's I/O object102 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'103 * @token: Token of DPDMAI object104 *105 * After this function is called, no further operations are106 * allowed on the object without opening a new control session.107 *108 * Return: '0' on Success; Error code otherwise.109 */110int dpdmai_close(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)111{112 struct fsl_mc_command cmd = { 0 };113 114 /* prepare command */115 cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_CLOSE,116 cmd_flags, token);117 118 /* send command to mc*/119 return mc_send_command(mc_io, &cmd);120}121EXPORT_SYMBOL_GPL(dpdmai_close);122 123/**124 * dpdmai_destroy() - Destroy the DPDMAI object and release all its resources.125 * @mc_io: Pointer to MC portal's I/O object126 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'127 * @dpdmai_id: The object id; it must be a valid id within the container that created this object;128 * @token: Token of DPDMAI object129 *130 * Return: '0' on Success; error code otherwise.131 */132int dpdmai_destroy(struct fsl_mc_io *mc_io, u32 cmd_flags, u32 dpdmai_id, u16 token)133{134 struct dpdmai_cmd_destroy *cmd_params;135 struct fsl_mc_command cmd = { 0 };136 137 /* prepare command */138 cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_DESTROY,139 cmd_flags, token);140 141 cmd_params = (struct dpdmai_cmd_destroy *)&cmd.params;142 cmd_params->dpdmai_id = cpu_to_le32(dpdmai_id);143 144 /* send command to mc*/145 return mc_send_command(mc_io, &cmd);146}147EXPORT_SYMBOL_GPL(dpdmai_destroy);148 149/**150 * dpdmai_enable() - Enable the DPDMAI, allow sending and receiving frames.151 * @mc_io: Pointer to MC portal's I/O object152 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'153 * @token: Token of DPDMAI object154 *155 * Return: '0' on Success; Error code otherwise.156 */157int dpdmai_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)158{159 struct fsl_mc_command cmd = { 0 };160 161 /* prepare command */162 cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_ENABLE,163 cmd_flags, token);164 165 /* send command to mc*/166 return mc_send_command(mc_io, &cmd);167}168EXPORT_SYMBOL_GPL(dpdmai_enable);169 170/**171 * dpdmai_disable() - Disable the DPDMAI, stop sending and receiving frames.172 * @mc_io: Pointer to MC portal's I/O object173 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'174 * @token: Token of DPDMAI object175 *176 * Return: '0' on Success; Error code otherwise.177 */178int dpdmai_disable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)179{180 struct fsl_mc_command cmd = { 0 };181 182 /* prepare command */183 cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_DISABLE,184 cmd_flags, token);185 186 /* send command to mc*/187 return mc_send_command(mc_io, &cmd);188}189EXPORT_SYMBOL_GPL(dpdmai_disable);190 191/**192 * dpdmai_reset() - Reset the DPDMAI, returns the object to initial state.193 * @mc_io: Pointer to MC portal's I/O object194 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'195 * @token: Token of DPDMAI object196 *197 * Return: '0' on Success; Error code otherwise.198 */199int dpdmai_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)200{201 struct fsl_mc_command cmd = { 0 };202 203 /* prepare command */204 cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_RESET,205 cmd_flags, token);206 207 /* send command to mc*/208 return mc_send_command(mc_io, &cmd);209}210EXPORT_SYMBOL_GPL(dpdmai_reset);211 212/**213 * dpdmai_get_attributes() - Retrieve DPDMAI attributes.214 * @mc_io: Pointer to MC portal's I/O object215 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'216 * @token: Token of DPDMAI object217 * @attr: Returned object's attributes218 *219 * Return: '0' on Success; Error code otherwise.220 */221int dpdmai_get_attributes(struct fsl_mc_io *mc_io, u32 cmd_flags,222 u16 token, struct dpdmai_attr *attr)223{224 struct dpdmai_rsp_get_attributes *rsp_params;225 struct fsl_mc_command cmd = { 0 };226 int err;227 228 /* prepare command */229 cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_ATTR,230 cmd_flags, token);231 232 /* send command to mc*/233 err = mc_send_command(mc_io, &cmd);234 if (err)235 return err;236 237 /* retrieve response parameters */238 rsp_params = (struct dpdmai_rsp_get_attributes *)cmd.params;239 attr->id = le32_to_cpu(rsp_params->id);240 attr->version.major = le16_to_cpu(rsp_params->major);241 attr->version.minor = le16_to_cpu(rsp_params->minor);242 attr->num_of_priorities = rsp_params->num_of_priorities;243 attr->num_of_queues = rsp_params->num_of_queues;244 245 return 0;246}247EXPORT_SYMBOL_GPL(dpdmai_get_attributes);248 249/**250 * dpdmai_set_rx_queue() - Set Rx queue configuration251 * @mc_io: Pointer to MC portal's I/O object252 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'253 * @token: Token of DPDMAI object254 * @queue_idx: DMA queue index255 * @priority: Select the queue relative to number of256 * priorities configured at DPDMAI creation257 * @cfg: Rx queue configuration258 *259 * Return: '0' on Success; Error code otherwise.260 */261int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u8 queue_idx,262 u8 priority, const struct dpdmai_rx_queue_cfg *cfg)263{264 struct dpdmai_cmd_queue *cmd_params;265 struct fsl_mc_command cmd = { 0 };266 267 /* prepare command */268 cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_SET_RX_QUEUE,269 cmd_flags, token);270 271 cmd_params = (struct dpdmai_cmd_queue *)cmd.params;272 cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);273 cmd_params->dest_priority = cfg->dest_cfg.priority;274 cmd_params->pri = priority;275 cmd_params->dest_type = cfg->dest_cfg.dest_type;276 cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx);277 cmd_params->options = cpu_to_le32(cfg->options);278 cmd_params->queue_idx = queue_idx;279 280 /* send command to mc*/281 return mc_send_command(mc_io, &cmd);282}283EXPORT_SYMBOL_GPL(dpdmai_set_rx_queue);284 285/**286 * dpdmai_get_rx_queue() - Retrieve Rx queue attributes.287 * @mc_io: Pointer to MC portal's I/O object288 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'289 * @token: Token of DPDMAI object290 * @queue_idx: DMA Queue index291 * @priority: Select the queue relative to number of292 * priorities configured at DPDMAI creation293 * @attr: Returned Rx queue attributes294 *295 * Return: '0' on Success; Error code otherwise.296 */297int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u8 queue_idx,298 u8 priority, struct dpdmai_rx_queue_attr *attr)299{300 struct dpdmai_cmd_queue *cmd_params;301 struct fsl_mc_command cmd = { 0 };302 int err;303 304 /* prepare command */305 cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_RX_QUEUE,306 cmd_flags, token);307 308 cmd_params = (struct dpdmai_cmd_queue *)cmd.params;309 cmd_params->queue = priority;310 cmd_params->queue_idx = queue_idx;311 312 /* send command to mc*/313 err = mc_send_command(mc_io, &cmd);314 if (err)315 return err;316 317 /* retrieve response parameters */318 attr->dest_cfg.dest_id = le32_to_cpu(cmd_params->dest_id);319 attr->dest_cfg.priority = cmd_params->dest_priority;320 attr->dest_cfg.dest_type = FIELD_GET(DEST_TYPE_MASK, cmd_params->dest_type);321 attr->user_ctx = le64_to_cpu(cmd_params->user_ctx);322 attr->fqid = le32_to_cpu(cmd_params->fqid);323 324 return 0;325}326EXPORT_SYMBOL_GPL(dpdmai_get_rx_queue);327 328/**329 * dpdmai_get_tx_queue() - Retrieve Tx queue attributes.330 * @mc_io: Pointer to MC portal's I/O object331 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'332 * @token: Token of DPDMAI object333 * @queue_idx: DMA queue index334 * @priority: Select the queue relative to number of335 * priorities configured at DPDMAI creation336 * @attr: Returned DMA Tx queue attributes337 *338 * Return: '0' on Success; Error code otherwise.339 */340int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io, u32 cmd_flags,341 u16 token, u8 queue_idx, u8 priority, struct dpdmai_tx_queue_attr *attr)342{343 struct dpdmai_rsp_get_tx_queue *rsp_params;344 struct dpdmai_cmd_queue *cmd_params;345 struct fsl_mc_command cmd = { 0 };346 int err;347 348 /* prepare command */349 cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_TX_QUEUE,350 cmd_flags, token);351 352 cmd_params = (struct dpdmai_cmd_queue *)cmd.params;353 cmd_params->queue = priority;354 cmd_params->queue_idx = queue_idx;355 356 /* send command to mc*/357 err = mc_send_command(mc_io, &cmd);358 if (err)359 return err;360 361 /* retrieve response parameters */362 363 rsp_params = (struct dpdmai_rsp_get_tx_queue *)cmd.params;364 attr->fqid = le32_to_cpu(rsp_params->fqid);365 366 return 0;367}368EXPORT_SYMBOL_GPL(dpdmai_get_tx_queue);369 370MODULE_DESCRIPTION("NXP DPAA2 QDMA driver");371MODULE_LICENSE("GPL v2");372