lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20160611225407.GG10685@sisyphus.home.austad.us>
Date:	Sun, 12 Jun 2016 00:54:07 +0200
From:	Henrik Austad <henrik@...tad.us>
To:	linux-kernel@...r.kernel.org
Cc:	linux-media@...r.kernel.org, alsa-devel@...r.kernel.org,
	linux-netdev@...r.kernel.org, henrk@...tad.us,
	Henrik Austad <haustad@...co.com>,
	"David S. Miller" <davem@...emloft.net>
Subject: Re: [very-RFC 4/8] Add TSN header for the driver

Clearing up netdev-typo
-H

On Sun, Jun 12, 2016 at 12:22:17AM +0200, Henrik Austad wrote:
> From: Henrik Austad <haustad@...co.com>
> 
> This defines the general TSN headers for network packets, the
> shim-interface and the central 'tsn_list' structure.
> 
> Cc: "David S. Miller" <davem@...emloft.net>
> Signed-off-by: Henrik Austad <haustad@...co.com>
> ---
>  include/linux/tsn.h | 806 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 806 insertions(+)
>  create mode 100644 include/linux/tsn.h
> 
> diff --git a/include/linux/tsn.h b/include/linux/tsn.h
> new file mode 100644
> index 0000000..0e1f732b
> --- /dev/null
> +++ b/include/linux/tsn.h
> @@ -0,0 +1,806 @@
> +/*   TSN - Time Sensitive Networking
> + *
> + *   Copyright (C) 2016- Henrik Austad <haustad@...co.com>
> + *
> + *   This program is free software; you can redistribute it and/or modify
> + *   it under the terms of the GNU General Public License as published by
> + *   the Free Software Foundation; either version 2 of the License, or
> + *   (at your option) any later version.
> + *
> + *   This program is distributed in the hope that it will be useful,
> + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *   GNU General Public License for more details.
> + */
> +#ifndef _TSN_H
> +#define _TSN_H
> +#include <linux/list.h>
> +#include <linux/configfs.h>
> +#include <linux/hrtimer.h>
> +
> +/* The naming here can be a bit confusing as we call it TSN but naming
> + * suggests 'AVB'. Reason: IEE 1722 was written before the working group
> + * was renamed to Time Sensitive Networking.
> + *
> + * To be precise. TSN describes the protocol for shipping data, AVB is a
> + * medialayer which you can build on top of TSN.
> + *
> + * For this reason the frames are given avb-names whereas the functions
> + * use tsn_-naming.
> + */
> +
> +/* 7 bit value 0x00 - 0x7F */
> +enum avtp_subtype {
> +	AVTP_61883_IIDC = 0,
> +	AVTP_MMA = 0x1,
> +	AVTP_MAAP = 0x7e,
> +	AVTP_EXPERIMENTAL = 0x7f,
> +};
> +
> +/*		NOTE NOTE NOTE !!
> + * The headers below use bitfields extensively and verifications
> + * are needed when using little-endian vs big-endian systems.
> + */
> +
> +/* Common part of avtph header
> + *
> + * AVB Transport Protocol Common Header
> + *
> + * Defined in 1722-2011 Sec. 5.2
> + */
> +struct avtp_ch {
> +#if defined(__LITTLE_ENDIAN_BITFIELD)
> +	/* use avtp_subtype enum.
> +	 */
> +	u8 subtype:7;
> +
> +	/* Controlframe: 1
> +	 * Dataframe   : 0
> +	 */
> +	u8 cd:1;
> +
> +	/* Type specific data, part 1 */
> +	u8 tsd_1:4;
> +
> +	/* In current version of AVB, only 0 is valid, all other values
> +	 * are reserved for future versions.
> +	 */
> +	u8 version:3;
> +
> +	/* Valid StreamID in frame
> +	 *
> +	 * ControlData not related to a specific stream should clear
> +	 * this (and have stream_id = 0), _all_ other values should set
> +	 * this to 1.
> +	 */
> +	u8 sv:1;
> +#elif defined(__BIG_ENDIAN_BITFIELD)
> +	u8 cd:1;
> +	u8 subtype:7;
> +	u8 sv:1;
> +	u8 version:3;
> +	u8 tsd_1:4;
> +#else
> +#error "Unknown Endianness, cannot determine bitfield ordering"
> +#endif
> +	/* Type specific data (adjacent to tsd_1, but split due to bitfield) */
> +	u16 tsd_2;
> +	u64 stream_id;
> +
> +	/*
> +	 * payload by subtype
> +	 */
> +	u8 pbs[0];
> +} __packed;
> +
> +/* AVTPDU Common Control header format
> + * IEEE 1722#5.3
> + */
> +struct avtpc_header {
> +#if defined(__LITTLE_ENDIAN_BITFIELD)
> +	u8 subtype:7;
> +	u8 cd:1;
> +	u8 control_data:4;
> +	u8 version:3;
> +	u8 sv:1;
> +	u16 control_data_length:11;
> +	u16 status:5;
> +#elif defined(__BIG_ENDIAN_BITFIELD)
> +	u8 cd:1;
> +	u8 subtype:7;
> +	u8 sv:1;
> +	u8 version:3;
> +	u8 control_data:4;
> +	u16 status:5;
> +	u16 control_data_length:11;
> +#else
> +#error "Unknown Endianness, cannot determine bitfield ordering"
> +#endif
> +	u64 stream_id;
> +} __packed;
> +
> +/* AVTP common stream data AVTPDU header format
> + * IEEE 1722#5.4
> + */
> +struct avtpdu_header {
> +#if defined(__LITTLE_ENDIAN_BITFIELD)
> +	u8 subtype:7;
> +	u8 cd:1;
> +
> +	/* avtp_timestamp valid */
> +	u8 tv: 1;
> +
> +	/* gateway_info valid */
> +	u8 gv:1;
> +
> +	/* reserved */
> +	u8 r:1;
> +
> +	/*
> +	 * Media clock Restart toggle
> +	 */
> +	u8 mr:1;
> +
> +	u8 version:3;
> +
> +	/* StreamID valid */
> +	u8 sv:1;
> +	u8 seqnr;
> +
> +	/* Timestamp uncertain */
> +	u8 tu:1;
> +	u8 r2:7;
> +#elif defined(__BIG_ENDIAN_BITFIELD)
> +	u8 cd:1;
> +	u8 subtype:7;
> +
> +	u8 sv:1;
> +	u8 version:3;
> +	u8 mr:1;
> +	u8 r:1;
> +	u8 gv:1;
> +	u8 tv: 1;
> +
> +	u8 seqnr;
> +	u8 r2:7;
> +	u8 tu:1;
> +#else
> +#error "Unknown Endianness, cannot determine bitfield ordering"
> +#endif
> +
> +	u64 stream_id;
> +
> +	u32 avtp_timestamp;
> +	u32 gateway_info;
> +
> +	/* Stream Data Length */
> +	u16 sd_len;
> +
> +	/* Protocol specific header, derived from avtp_subtype */
> +	u16 psh;
> +
> +	/* Stream Payload Data 0 to n octets
> +	 * n so that total size < MTU
> +	 */
> +	u8 data[0];
> +} __packed;
> +
> +
> +/**
> + * struct tsn_list - The top level container of TSN
> + *
> + * This is what tsn_configfs refers to as 'tier-0'
> + *
> + * @head List of TSN cards
> + * @lock lock protecting global entries
> + * @tsn_subsys Ref to ConfigFS subsystem
> + *
> + * @running: hrtimer is running driving data out
> + * @tsn_timer: hrtimer container
> + * @num_avail Number of available TSN NICs exposed through ConfigFS
> + */
> +struct tsn_list {
> +	struct list_head head;
> +	struct mutex lock;
> +	struct configfs_subsystem tsn_subsys;
> +
> +	/*
> +	 * TSN-timer is running. Not to be confused with the per-link
> +	 * disabled flag which indicates if a remote client, like aplay,
> +	 * is pushing data to it.
> +	 */
> +	atomic_t running;
> +	struct hrtimer tsn_timer;
> +	unsigned int period_ns;
> +
> +
> +	size_t num_avail;
> +};
> +
> +/**
> + * struct tsn_nic
> + *
> + * Individual TSN-capable NICs, or 'tier-1' struct
> + *
> + * @list linked list of all TSN NICs
> + * @group configfs group
> + * @dev corresponding net_device
> + * @dma_size : size of the DMA buffer
> + * @dma_handle: housekeeping DMA-stuff
> + * @dma_mem : pointer to memory region we're using for DMAing to the NIC
> + * @name Name of NIC (same as name in dev), TO BE REMOVED
> + * @txq Size of Tx-queue. TO BE REMOVED
> + * @rx_registered flag indicating if a handler is registered for the nic
> + * @capable: if the NIC is capable for proper TSN traffic or if it must
> + *	     be emulated in software.
> + *
> + */
> +struct tsn_nic {
> +	struct list_head list;
> +	struct config_group group;
> +	struct net_device *dev;
> +	struct tsn_list *tsn_list;
> +
> +	size_t dma_size;
> +	dma_addr_t dma_handle;
> +	void *dma_mem;
> +
> +	char *name;
> +	int txq;
> +	u8 rx_registered:1;
> +	u8 capable:1;
> +	u8 reserved:6;
> +};
> +
> +struct tsn_shim_ops;
> +/**
> + * tsn_link - Structure describing a single TSN link
> + *
> + */
> +struct tsn_link {
> +	/*
> +	 * Lock for protecting the buffer
> +	 */
> +	spinlock_t lock;
> +
> +	struct config_group group;
> +	struct tsn_nic *nic;
> +	struct hlist_node node;
> +
> +	/* The link itself is active, and the tsn_core will treat it as
> +	 * an active participant and feed data from it to the
> +	 * network. This places some restrictions on which attributes
> +	 * can be changed.
> +	 *
> +	 * 1: active
> +	 * 0: inactive
> +	 */
> +	atomic_t active;
> +
> +	u64 timer_period_ns;
> +
> +	/* Pointer to media-specific data.
> +	 * e.g. struct avb_chip
> +	 */
> +	void *media_chip;
> +
> +	u64 stream_id;
> +
> +	/*
> +	 * The max required size for a _single_ TSN frame.
> +	 *
> +	 * To be used instead of channels and sample_freq.
> +	 */
> +	u16 max_payload_size;
> +	u16 shim_header_size;
> +
> +	/*
> +	 * Size of buffer (in bytes) to use when handling data to/from
> +	 * NIC.
> +	 *
> +	 * Smaller size will result in client being called more often
> +	 * but also provides lower latencies.
> +	 */
> +	size_t buffer_size;
> +	size_t used_buffer_size;
> +
> +	/*
> +	 * Used when frames are constructed and shipped to the network
> +	 * layer. If this is true, 0-frames will be sent insted of data
> +	 * from the buffer.
> +	 */
> +	atomic_t buffer_active;
> +
> +	/*
> +	 * ringbuffer for incoming or outging traffic
> +	 * +-----------------------------------+
> +	 * |                  ##########       |
> +	 * +-----------------------------------+
> +	 * ^                  ^         ^      ^
> +	 * buffer           tail      head    end
> +	 *
> +	 * Buffer: start of memory area
> +	 * tail: first byte of data in buffer
> +	 * head: first unused slot in which to store new data
> +	 *
> +	 * head,tail is used to represent the position of 'live data' in
> +	 * the buffer.
> +	 */
> +	void *buffer;
> +	void *head;
> +	void *tail;
> +	void *end;
> +
> +	/* Number of bytes to run refill/drain callbacks */
> +	size_t low_water_mark;
> +	size_t high_water_mark;
> +
> +
> +	/*
> +	 * callback ops.
> +	 */
> +	struct tsn_shim_ops *ops;
> +
> +	/*
> +	 * EndStation Type
> +	 *
> +	 * Either Talker or Listener
> +	 *
> +	 * 1: We are *Talker*, i.e. producing data to send
> +	 * 0: We are *Listener*, i.e. we receive data from another ES.
> +	 *
> +	 * This is for a single link, so even though an end-station can
> +	 * be both Talker *and* Listener, a link can only be one.
> +	 */
> +	u8 estype_talker;
> +
> +	/*
> +	 * Link will use buffer managed by the shim. For this to work,
> +	 * the shim must:
> +	 *
> +	 * - call tsn_use_external_buffer(link, size);
> +	 * - provide tsn_shim_buffer_swap(link) in tsn_shim_ops
> +	 */
> +	u8 external_buffer;
> +
> +	u8 last_seqnr;
> +
> +	/*
> +	 * Class can be either A or B
> +	 *
> +	 * ClassA: every 125us
> +	 * ClassB: every 250us
> +	 *
> +	 * This will also affect how large each frame will be.
> +	 */
> +	u8 class_a:1;
> +
> +	/*
> +	 * Any AVTP data stream must set the 802.1Q vlan id and priority
> +	 * Code point. This should be obtained from MSRP, default values
> +	 * are:
> +	 *
> +	 * pvid: SR_PVID 2
> +	 * pcp: Class A: 3
> +	 *	Class B: 2
> +	 *
> +	 * See IEEE 802.1Q-2011, Sec 35.2.2.9.3 and table 6-6 in 6.6.2
> +	 * for details
> +	 */
> +	u8 pcp_a:3;
> +	u8 pcp_b:3;
> +	u16 vlan_id:12;
> +
> +	u8 remote_mac[6];
> +};
> +
> +/**
> + * tsn_link_on - make link active
> + *
> + * This cause most of the attributes to be treated read-only since we
> + * will have to re-negotiate with the network if most of these
> + * parameters change.
> + *
> + * Note: this means that the link will be handled by the rx-handler or
> + * the timer callback, but until the link_buffer is set active (via
> + * tsn_lb_on()), actual data is not moved.
> + *
> + * @link: link being set to active
> + */
> +static inline void tsn_link_on(struct tsn_link *link)
> +{
> +	if (link)
> +		atomic_set(&link->active, 1);
> +}
> +
> +/**
> + * tsn_link_off - make link inactive
> + *
> + * The link will now be ignored by timer callback or the
> + * rx-handler. Attributes can be mostly freely changed (we assume that
> + * userspace sets values that are negotiated properly).
> + *
> + * @link: link to deactivate
> + */
> +static inline void tsn_link_off(struct tsn_link *link)
> +{
> +	if (link)
> +		atomic_set(&link->active, 0);
> +}
> +
> +/**
> + * tsn_link_is_on - query link to see if it is active
> + *
> + * Mostly used by tsn_configfs to respect the "read-only" once link is
> + * configured and made active.
> + *
> + * @link active link
> + * @returns 1 if active/on, 0 otherwise
> + */
> +static inline int tsn_link_is_on(struct tsn_link *link)
> +{
> +	if (link)
> +		return atomic_read(&link->active);
> +	return 0;
> +}
> +
> +/**
> + * tsn_set_buffer_size - adjust buffersize to match a shim
> + *
> + * This will not allocate (or deallcoate) memory, just adjust how much
> + * of the buffer allocated in tsn_prepare_link is being used. tsn_
> + * expects tsn_clear_buffer_size() to be invoked when stream is closed.
> + */
> +int tsn_set_buffer_size(struct tsn_link *link, size_t bsize);
> +int tsn_clear_buffer_size(struct tsn_link *link);
> +
> +/**
> + * tsn_buffer_write write data into the buffer from shim
> + *
> + * This is called from the shim-driver when more data is available and
> + * data needs to be pushed out to the network.
> + *
> + * NOTE: This is used when TSN handles the databuffer. This will not be
> + *	 needed for "shim-hosted" buffers.
> + *
> + * _If_ this function is called when the link is inactive, it will
> + * _enable_ the link (i.e. link will mark the buffer as 'active'). Do
> + * not copy data into the buffer unless you are ready to start sending
> + * frames!
> + *
> + * @link active link
> + * @src	the buffer to copy data from
> + * @bytes bytes to copy
> + * @return bytes copied from link->buffer or negative error
> + */
> +int tsn_buffer_write(struct tsn_link *link, void *src, size_t bytes);
> +
> +
> +/**
> + * tsn_buffer_read - read data from link->buffer and give to shim
> + *
> + * When we act as a listener, this is what the shim (should|will) call
> + * to grab data. It typically grabs much more data than the _net
> + * equivalent. It also do not trigger a refill-event the same way
> + * buffer_read_net does.
> + *
> + * @param link current link that holds the buffer
> + * @param buffer the buffer to copy into, must be at least of size bytes
> + * @param bytes number of bytes.
> + *
> + * Note that this routine does NOT CARE about channels, samplesize etc,
> + * it is a _pure_ copy that handles ringbuffer wraps etc.
> + *
> + * This function have side-effects as it will update internal tsn_link
> + * values.
> + *
> + * @return Bytes copied into link->buffer, negative value upon error.
> + */
> +int tsn_buffer_read(struct tsn_link *link, void *buffer, size_t bytes);
> +
> +/**
> + * tsn_lb_enable - TSN Link Buffer Enable
> + *
> + * Mark the link as "buffer-enabled" which will let the core start
> + * shifting data in/out of the buffer instead of ignoring incoming
> + * frames or sending "nullframes".
> + *
> + * This is for the network-end of the tsn-buffer, i.e.
> + * - when enabled frames *from* the network will be inserted into the buffer,
> + * - or frames going *out* will include data from the buffer instead of sending
> + *   null-frames.
> + *
> + * When disabled, data will be zero'd, e.g Tx will send NULL-frames and
> + * Rx will silently drop the frames.
> + *
> + * @link: active link
> + */
> +static inline void tsn_lb_enable(struct tsn_link *link)
> +{
> +	if (link)
> +		atomic_set(&link->buffer_active, 1);
> +}
> +
> +/**
> + * tsn_lb_disable - stop using the buffer for the net-side of TSN
> + *
> + * When we close a stream, we do not necessarily tear down the link, and
> + * we need to handle the data in some way.
> + */
> +static inline void tsn_lb_disable(struct tsn_link *link)
> +{
> +	if (link)
> +		atomic_set(&link->buffer_active, 0);
> +}
> +
> +/**
> + * tsn_lb() - query if we have disabled pushing of data to/from link-buffer
> + *
> + * @param struct tsn_link *link - active link
> + * @returns 1 if link is enabled
> + */
> +static inline int tsn_lb(struct tsn_link *link)
> +{
> +	if (link)
> +		return atomic_read(&link->buffer_active);
> +
> +	/* if link is NULL; buffer not active */
> +	return 0;
> +}
> +
> +
> +/**
> + * Shim ops - what tsn_core use when calling back into the shim. All ops
> + * must be reentrant.
> + */
> +#define SHIM_NAME_SIZE 32
> +struct tsn_shim_ops {
> +
> +	/* internal linked list used by tsn_core to keep track of all
> +	 * shims.
> +	 */
> +	struct list_head head;
> +
> +	/**
> +	 * name - a unique name identifying this shim
> +	 *
> +	 * This is what userspace use to indicate to core what SHIM a
> +	 * particular link will use. If the name is already present,
> +	 * core will reject this name.
> +	 */
> +	char shim_name[SHIM_NAME_SIZE];
> +
> +	/**
> +	 * probe - callback when a new link of this type is instantiated.
> +	 *
> +	 * When a new link is brought online, this is called once the
> +	 * essential parts of tsn_core has finiesh. Once probe_cb has
> +	 * finisehd, the shim _must_ be ready to accept data to/from
> +	 * tsn_core. On the other hand, due to the final steps of setup,
> +	 * it cannot expect to be called into action immediately after
> +	 * probe has finished.
> +	 *
> +	 * In other words, shim must be ready, but core doesn't have to
> +	 *
> +	 * @param : a particular link to pass along to the probe-function.
> +	 */
> +	int (*probe)(struct tsn_link *link);
> +
> +	/**
> +	 * buffer_swap - set a new buffer for the link. [OPTIONAL]
> +	 *
> +	 * Used when external buffering is enabled.
> +	 *
> +	 * When called, a new buffer must be returned WITHOUT blocking
> +	 * as this will be called from interrupt context.
> +	 *
> +	 * The buffer returned from the shim must be at least the size
> +	 * of used_buffer_size.
> +	 *
> +	 * @param current link
> +	 * @param old_buffer the buffer that are no longer needed
> +	 * @param used number of bytes in buffer that has been filled with data.
> +	 * @return new buffer to use
> +	 */
> +	void * (*buffer_swap)(struct tsn_link *link, void *old_buffer,
> +			      size_t used);
> +
> +	/**
> +	 * buffer_refill - signal shim that more data is required
> +	 * @link Active link
> +	 *
> +	 * This function should not do anything that can preempt the
> +	 * task (kmalloc, sleeping lock) or invoke actions that can take
> +	 * a long time to complete.
> +	 *
> +	 * This will be called from tsn_buffer_read_net() when available
> +	 * data in the buffer drops below low_water_mark. It will be
> +	 * called with the link-lock *held*
> +	 */
> +	size_t (*buffer_refill)(struct tsn_link *link);
> +
> +	/**
> +	 * buffer_drain - shim need to copy data from buffer
> +	 *
> +	 * This will be called from tsn_buffer_write_net() when data in
> +	 * the buffer exceeds high_water_mark.
> +	 *
> +	 * The expected behavior is for the shim to then fill data into
> +	 * the buffer via tsn_buffer_write()
> +	 */
> +	size_t (*buffer_drain)(struct tsn_link *link);
> +
> +	/**
> +	 * media_close - shut down media controller properly
> +	 *
> +	 * when the link is closed/removed for some reason
> +	 * external to the media controller (ALSA soundcard, v4l2 driver
> +	 * etc), we call this to clean up.
> +	 *
> +	 * Normal operation is stopped before media_close is called, but
> +	 * all references should be valid. TSN core expects media_close
> +	 * to handle any local cleanup, once returned, any references in
> +	 * stale tsn_links cannot be trusted.
> +	 *
> +	 * @link: current link where data is stored
> +	 * @returns: 0 upon success, negative on error.
> +	 */
> +	int (*media_close)(struct tsn_link *link);
> +
> +	/**
> +	 * hdr_size - ask shim how large the header is
> +	 *
> +	 * Needed when reserving space in skb for transmitting data.
> +	 *
> +	 * @link: current link where data is stored
> +	 * @return: size of header for this shim
> +	 */
> +	size_t (*hdr_size)(struct tsn_link *link);
> +
> +	/**
> +	 * copy_size - ask client how much from the buffer to include in
> +	 *	       the next frame.
> +	 *
> +	 *	       This is for *outgoing* frames, incoming frames
> +	 *	       have 'sd_len' set in the header.
> +	 *
> +	 *	       Note: copy_size should not return a size larger
> +	 *		     than link->max_payload_size
> +	 */
> +	size_t (*copy_size)(struct tsn_link *link);
> +
> +	/**
> +	 * validate_header - let the shim validate subtype-header
> +	 *
> +	 * Both psh and data may (or may not) contain headers that need
> +	 * validating. This is the responsibility of the shim to
> +	 * validate, and ops->valdiate_header() will be called before
> +	 * any data is copied from the incoming frame and into the
> +	 * buffer.
> +	 *
> +	 * Important: tsn_core expects validate_header to _not_ alter
> +	 * the contents of the frame, and ideally, validate_header could
> +	 * be called multiple times and give the same result.
> +	 *
> +	 * @param: active link owning the new data
> +	 * @param: start of data-unit header
> +	 *
> +	 * This function will be called from interrupt-context and MUST
> +	 * NOT take any locks.
> +	 */
> +	int (*validate_header)(struct tsn_link *link,
> +			       struct avtpdu_header *header);
> +
> +	/**
> +	 * assemble_header - add shim-specific headers
> +	 *
> +	 * This adds the headers required by the current shim after the
> +	 * generic 1722-header.
> +	 *
> +	 * @param: active link
> +	 * @param: start of data-unit header
> +	 * @param: size of data to send in this frame
> +	 * @return void
> +	 */
> +	void (*assemble_header)(struct tsn_link *link,
> +				struct avtpdu_header *header, size_t bytes);
> +
> +	/**
> +	 * get_payload_data - get a pointer to where the data is stored
> +	 *
> +	 * core will use the pointer (or drop it if NULL is returned)
> +	 * and copy header->sd_len bytes of *consecutive* data from the
> +	 * target memory and into the buffer memory.
> +	 *
> +	 * This is called with relevant locks held, from interrupt context.
> +	 *
> +	 * @param link active link
> +	 * @param header header of frame, which contains data
> +	 * @returns pointer to memory to copy from
> +	 */
> +	void * (*get_payload_data)(struct tsn_link *link,
> +				   struct avtpdu_header *header);
> +};
> +/**
> + * tsn_shim_register_ops - register shim-callbacks for a given shim
> + *
> + * @param shim_ops - callbacks. The ops-struct should be kept intact for
> + *		     as long as the driver is running.
> + *
> + *
> + */
> +int tsn_shim_register_ops(struct tsn_shim_ops *shim_ops);
> +
> +/**
> + * tsn_shim_deregister_ops - remove callback for module
> + *
> + * Completely remove shim_ops. This will close any links currently using
> + * this shim. Note: the links will be closed, but _not_ removed.
> + *
> + * @param shim_ops ops associated with this shim
> + */
> +void tsn_shim_deregister_ops(struct tsn_shim_ops *shim_ops);
> +
> +/**
> + * tsn_shim_get_active : return the name of the currently loaded shim
> + *
> + * @param current link
> + * @return name of shim (matches an entry from exported triggers)
> + */
> +char *tsn_shim_get_active(struct tsn_link *link);
> +
> +/**
> + * tsn_shim_find_by_name find shim_ops by name
> + *
> + * @param name of shim
> + * @return shim or NULL if not found/error.
> + */
> +struct tsn_shim_ops *tsn_shim_find_by_name(const char *name);
> +
> +/**
> + * tsn_shim_export_probe_triggers - export a list of registered shims
> + *
> + * @param page to write content into
> + * @returns length of data written to page
> + */
> +ssize_t tsn_shim_export_probe_triggers(char *page);
> +
> +/**
> + * tsn_get_framesize - get the size of the next TSN frame to send
> + *
> + * This will call into the shim to get the next chunk of data to
> + * read. Some sanitychecking is performed, i.e.
> + *
> + * 0 <= size <= max_payload_size
> + *
> + * @param struct tsn_link *link active link
> + * @returns size of frame in bytes or negative on error.
> + */
> +static inline size_t tsn_shim_get_framesize(struct tsn_link *link)
> +{
> +	size_t ret;
> +
> +	ret = link->ops->copy_size(link);
> +	if (ret <= link->max_payload_size)
> +		return ret;
> +	return link->max_payload_size;
> +}
> +
> +/**
> + * tsn_get_hdr_size - get the size of the shim-specific header size
> + *
> + * The shim will add it's own header to the frame.
> + */
> +static inline size_t tsn_shim_get_hdr_size(struct tsn_link *link)
> +{
> +	size_t ret;
> +
> +	if (!link || !link->ops->hdr_size)
> +		return -EINVAL;
> +	ret = link->ops->hdr_size(link);
> +	if (ret > link->max_payload_size)
> +		return -EINVAL;
> +	return ret;
> +}
> +
> +#endif	/* _TSN_H */
> -- 
> 2.7.4
> 

-- 
Henrik Austad

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ