[PATCH 4/9] bus: fsl-mc: dpio: add frame descriptor and scatter/gather APIs

Ruxandra Ioana Radulescu ruxandra.radulescu at nxp.com
Fri Nov 4 13:22:26 UTC 2016


> -----Original Message-----
> From: Stuart Yoder [mailto:stuart.yoder at nxp.com]
> Sent: Friday, October 21, 2016 9:02 AM
> To: gregkh at linuxfoundation.org
> Cc: German Rivera <german.rivera at nxp.com>; devel at driverdev.osuosl.org;
> linux-kernel at vger.kernel.org; agraf at suse.de; arnd at arndb.de; Leo Li
> <leoyang.li at nxp.com>; Roy Pledge <roy.pledge at nxp.com>; Stuart Yoder
> <stuart.yoder at nxp.com>
> Subject: [PATCH 4/9] bus: fsl-mc: dpio: add frame descriptor and
> scatter/gather APIs
> 
> From: Roy Pledge <Roy.Pledge at nxp.com>
> 
> Add global definitions for DPAA2 frame descriptors and scatter
> gather entries.
> 
> Signed-off-by: Roy Pledge <Roy.Pledge at nxp.com>
> Signed-off-by: Stuart Yoder <stuart.yoder at nxp.com>
> ---
>  include/linux/fsl/dpaa2-fd.h | 415
> +++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 415 insertions(+)
>  create mode 100644 include/linux/fsl/dpaa2-fd.h
> 
> diff --git a/include/linux/fsl/dpaa2-fd.h b/include/linux/fsl/dpaa2-fd.h
> new file mode 100644
> index 0000000..b3fa9ff
> --- /dev/null
> +++ b/include/linux/fsl/dpaa2-fd.h
> @@ -0,0 +1,415 @@
> +/*
> + * Copyright 2014-2016 Freescale Semiconductor Inc.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in the
> + *       documentation and/or other materials provided with the distribution.
> + *     * Neither the name of Freescale Semiconductor nor the
> + *       names of its contributors may be used to endorse or promote
> products
> + *       derived from this software without specific prior written permission.
> + *
> + * ALTERNATIVELY, this software may be distributed under the terms of the
> + * GNU General Public License ("GPL") as published by the Free Software
> + * Foundation, either version 2 of that License or (at your option) any
> + * later version.
> + *
> + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND
> ANY
> + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE IMPLIED
> + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE ARE
> + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR
> ANY
> + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> CONSEQUENTIAL DAMAGES
> + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
> GOODS OR SERVICES;
> + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> HOWEVER CAUSED AND
> + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
> OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
> THE USE OF THIS
> + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +#ifndef __FSL_DPAA2_FD_H
> +#define __FSL_DPAA2_FD_H
> +
> +#include <linux/kernel.h>
> +
> +/**
> + * DOC: DPAA2 FD - Frame Descriptor APIs for DPAA2
> + *
> + * Frame Descriptors (FDs) are used to describe frame data in the DPAA2.
> + * Frames can be enqueued and dequeued to Frame Queues (FQs) which
> are consumed
> + * by the various DPAA accelerators (WRIOP, SEC, PME, DCE)
> + *
> + * There are three types of frames: single, scatter gather, and frame lists.
> + *
> + * The set of APIs in this file must be used to create, manipulate and
> + * query Frame Descriptors.
> + */
> +
> +/**
> + * struct dpaa2_fd - Struct describing FDs
> + * @words:         for easier/faster copying the whole FD structure
> + * @addr:          address in the FD
> + * @len:           length in the FD
> + * @bpid:          buffer pool ID
> + * @format_offset: format and offset fields
> + * @frc:           frame context
> + * @ctrl:          control bits...including dd, sc, va, err, etc
> + * @flc:           flow context address
> + *
> + * This structure represents the basic Frame Descriptor used in the system.
> + */
> +struct dpaa2_fd {
> +	union {
> +		u32 words[8];
> +		struct dpaa2_fd_simple {
> +			__le64 addr;
> +			__le32 len;
> +			__le16 bpid;
> +			__le16 format_offset;
> +			__le32 frc;
> +			__le32 ctrl;
> +			__le64 flc;
> +		} simple;
> +	};
> +};
> +
> +#define FD_OFFSET_MASK 0x0FFF
> +#define FD_FORMAT_MASK 0x3
> +#define FD_FORMAT_SHIFT 12
> +#define SG_SHORT_LEN_FLAG_MASK 0x1
> +#define SG_SHORT_LEN_FLAG_SHIFT 14
> +#define SG_SHORT_LEN_MASK 0x1FFFF
> +#define SG_OFFSET_MASK 0x0FFF
> +#define SG_FORMAT_MASK 0x3
> +#define SG_FORMAT_SHIFT 12
> +#define SG_BPID_MASK 0x3FFF
> +#define SG_FINAL_FLAG_MASK 0x1
> +#define SG_FINAL_FLAG_SHIFT 15
> +
> +enum dpaa2_fd_format {
> +	dpaa2_fd_single = 0,
> +	dpaa2_fd_list,
> +	dpaa2_fd_sg
> +};
> +
> +/**
> + * dpaa2_fd_get_addr() - get the addr field of frame descriptor
> + * @fd: the given frame descriptor
> + *
> + * Return the address in the frame descriptor.
> + */
> +static inline dma_addr_t dpaa2_fd_get_addr(const struct dpaa2_fd *fd)
> +{
> +
> +	return (dma_addr_t)fd->simple.addr;
> +}
> +
> +/**
> + * dpaa2_fd_set_addr() - Set the addr field of frame descriptor
> + * @fd: the given frame descriptor
> + * @addr: the address needs to be set in frame descriptor
> + */
> +static inline void dpaa2_fd_set_addr(struct dpaa2_fd *fd, dma_addr_t
> addr)
> +{
> +	fd->simple.addr = addr;
> +}
> +
> +/**
> + * dpaa2_fd_get_frc() - Get the frame context in the frame descriptor
> + * @fd: the given frame descriptor
> + *
> + * Return the frame context field in the frame descriptor.
> + */
> +static inline u32 dpaa2_fd_get_frc(const struct dpaa2_fd *fd)
> +{
> +	return fd->simple.frc;
> +}
> +
> +/**
> + * dpaa2_fd_set_frc() - Set the frame context in the frame descriptor
> + * @fd: the given frame descriptor
> + * @frc: the frame context needs to be set in frame descriptor
> + */
> +static inline void dpaa2_fd_set_frc(struct dpaa2_fd *fd, u32 frc)
> +{
> +	fd->simple.frc = frc;
> +}
> +
> +/**
> + * dpaa2_fd_get_flc() - Get the flow context in the frame descriptor
> + * @fd: the given frame descriptor
> + *
> + * Return the flow context in the frame descriptor.
> + */
> +static inline dma_addr_t dpaa2_fd_get_flc(const struct dpaa2_fd *fd)
> +{
> +	return (dma_addr_t)fd->simple.flc;
> +}
> +
> +/**
> + * dpaa2_fd_set_flc() - Set the flow context field of frame descriptor
> + * @fd: the given frame descriptor
> + * @flc_addr: the flow context needs to be set in frame descriptor
> + */
> +static inline void dpaa2_fd_set_flc(struct dpaa2_fd *fd,  dma_addr_t
> flc_addr)
> +{
> +	fd->simple.flc = flc_addr;
> +}
> +
> +/**
> + * dpaa2_fd_get_len() - Get the length in the frame descriptor
> + * @fd: the given frame descriptor
> + *
> + * Return the length field in the frame descriptor.
> + */
> +static inline u32 dpaa2_fd_get_len(const struct dpaa2_fd *fd)
> +{
> +	return fd->simple.len;
> +}
> +
> +/**
> + * dpaa2_fd_set_len() - Set the length field of frame descriptor
> + * @fd: the given frame descriptor
> + * @len: the length needs to be set in frame descriptor
> + */
> +static inline void dpaa2_fd_set_len(struct dpaa2_fd *fd, u32 len)
> +{
> +	fd->simple.len = len;
> +}
> +
> +/**
> + * dpaa2_fd_get_offset() - Get the offset field in the frame descriptor
> + * @fd: the given frame descriptor
> + *
> + * Return the offset.
> + */
> +static inline uint16_t dpaa2_fd_get_offset(const struct dpaa2_fd *fd)
> +{
> +	return fd->simple.format_offset & FD_OFFSET_MASK;
> +}
> +
> +/**
> + * dpaa2_fd_set_offset() - Set the offset field of frame descriptor
> + * @fd: the given frame descriptor
> + * @offset: the offset needs to be set in frame descriptor
> + */
> +static inline void dpaa2_fd_set_offset(struct dpaa2_fd *fd, uint16_t offset)
> +{
> +	fd->simple.format_offset &= ~(FD_OFFSET_MASK);
> +	fd->simple.format_offset |= offset;
> +}
> +
> +/**
> + * dpaa2_fd_get_format() - Get the format field in the frame descriptor
> + * @fd: the given frame descriptor
> + *
> + * Return the format.
> + */
> +static inline enum dpaa2_fd_format dpaa2_fd_get_format(
> +						const struct dpaa2_fd *fd)
> +{
> +	return (enum dpaa2_fd_format)((fd->simple.format_offset
> +				      >> FD_FORMAT_SHIFT) &
> FD_FORMAT_MASK);
> +}
> +
> +/**
> + * dpaa2_fd_set_format() - Set the format field of frame descriptor
> + * @fd: the given frame descriptor
> + * @format: the format needs to be set in frame descriptor
> + */
> +static inline void dpaa2_fd_set_format(struct dpaa2_fd *fd,
> +				       enum dpaa2_fd_format format)
> +{
> +	fd->simple.format_offset &= ~(FD_FORMAT_MASK <<
> FD_FORMAT_SHIFT);
> +	fd->simple.format_offset |= format << FD_FORMAT_SHIFT;
> +}
> +
> +/**
> + * dpaa2_fd_get_bpid() - Get the bpid field in the frame descriptor
> + * @fd: the given frame descriptor
> + *
> + * Return the buffer pool id.
> + */
> +static inline uint16_t dpaa2_fd_get_bpid(const struct dpaa2_fd *fd)
> +{
> +	return fd->simple.bpid;
> +}
> +
> +/**
> + * dpaa2_fd_set_bpid() - Set the bpid field of frame descriptor
> + * @fd: the given frame descriptor
> + * @bpid: buffer pool id to be set
> + */
> +static inline void dpaa2_fd_set_bpid(struct dpaa2_fd *fd, uint16_t bpid)
> +{
> +	fd->simple.bpid = bpid;
> +}
 
The setter/getter functions for fd.ctrl are missing.

> +
> +/**
> + * struct dpaa2_sg_entry - the scatter-gathering structure
> + * @addr: address of the sg entry
> + * @len: length in this sg entry
> + * @bpid: buffer pool id
> + * @format_offset: offset in the MS 16 bits, BPID in the LS 16 bits

Description of the format_offset field is incorrect, it shouldn't
contain the reference to BPID.

> + */
> +struct dpaa2_sg_entry {
> +	__le64 addr;
> +	__le32 len;
> +	__le16 bpid;
> +	__le16 format_offset;
> +};
> +
> +enum dpaa2_sg_format {
> +	dpaa2_sg_single = 0,
> +	dpaa2_sg_frame_data,
> +	dpaa2_sg_sgt_ext
> +};
> +
> +/* Accessors for SG entry fields */
> +
> +/**
> + * dpaa2_sg_get_addr() - Get the address from SG entry
> + * @sg: the given scatter-gathering object
> + *
> + * Return the address.
> + */
> +static inline dma_addr_t dpaa2_sg_get_addr(const struct dpaa2_sg_entry
> *sg)
> +{
> +	return le64_to_cpu((dma_addr_t)sg->addr);
> +}
> +
> +/**
> + * dpaa2_sg_set_addr() - Set the address in SG entry
> + * @sg: the given scatter-gathering object
> + * @addr: the address to be set
> + */
> +static inline void dpaa2_sg_set_addr(struct dpaa2_sg_entry *sg,
> dma_addr_t addr)
> +{
> +	sg->addr = cpu_to_le64(addr);
> +}
> +
> +static inline bool dpaa2_sg_short_len(const struct dpaa2_sg_entry *sg)
> +{
> +	return (le16_to_cpu(sg->format_offset) >>
> SG_SHORT_LEN_FLAG_SHIFT)
> +		& SG_SHORT_LEN_FLAG_MASK;
> +}
> +
> +/**
> + * dpaa2_sg_get_len() - Get the length in SG entry
> + * @sg: the given scatter-gathering object
> + *
> + * Return the length.
> + */
> +static inline u32 dpaa2_sg_get_len(const struct dpaa2_sg_entry *sg)
> +{
> +	if (dpaa2_sg_short_len(sg))
> +		return le32_to_cpu(sg->len) & SG_SHORT_LEN_MASK;
> +
> +	return le32_to_cpu(sg->len);
> +}

We should do this in dpaa2_fd_get_len() as well. Hardware is capable of
generating FDs with SL bit set for single frame format too, although in
practice I've never actually seen it.

Thanks,
Ioana



More information about the devel mailing list