/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_FLOW_H
#define	_FLOW_H

#pragma ident	"@(#)flow.h	1.31	08/08/05 SMI"

/*
 * Main structure describing a flow of packets, for classification use
 */

#ifdef	__cplusplus
extern "C" {
#endif

#include <sys/types.h>
#include <netinet/in.h>		/* for IPPROTO_* constants */
#include <sys/ethernet.h>

#define	MAXFLOWNAME		32

/* need to use MAXMACADDRLEN from dld.h instead of this one */
#define	MAXMACADDR		20

/* Bit-mask for the selectors carried in the flow descriptor */
typedef	uint64_t		flow_mask_t;

#define	FLOW_LINK_DST		0x00000001	/* Destination MAC addr */
#define	FLOW_LINK_SRC		0x00000002	/* Source MAC address */
#define	FLOW_LINK_VID		0x00000004	/* VLAN ID */
#define	FLOW_LINK_SAP		0x00000008	/* SAP value */

#define	FLOW_IP_VERSION		0x00000010	/* V4 or V6 */
#define	FLOW_IP_PROTOCOL	0x00000020	/* Protocol type */
#define	FLOW_IP_LOCAL		0x00000040	/* Local address */
#define	FLOW_IP_REMOTE		0x00000080	/* Remote address */
#define	FLOW_IP_DSFIELD		0x00000100	/* DSfield value */

#define	FLOW_ULP_PORT_LOCAL	0x00001000	/* ULP local port */
#define	FLOW_ULP_PORT_REMOTE	0x00002000	/* ULP remote port */

#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
#pragma pack(4)
#endif

typedef struct flow_desc_s {
	flow_mask_t			fd_mask;
	uint32_t			fd_mac_len;
	uint8_t				fd_dst_mac[MAXMACADDR];
	uint8_t				fd_src_mac[MAXMACADDR];
	uint16_t			fd_vid;
	uint32_t			fd_sap;
	uint8_t				fd_ipversion;
	uint8_t				fd_protocol;
	in6_addr_t			fd_local_addr;
	in6_addr_t			fd_local_netmask;
	in6_addr_t			fd_remote_addr;
	in6_addr_t			fd_remote_netmask;
	in_port_t			fd_local_port;
	in_port_t			fd_remote_port;
	uint8_t				fd_dsfield;
	uint8_t				fd_dsfield_mask;
} flow_desc_t;

/* Bit-mask for the network resource control types types */
typedef	uint32_t			mac_service_type_t;

#define	MAC_BANDWIDTH_LIMIT		0x00000001
#define	MAC_FLOW_PRIORITY		0x00000002
#define	MAC_THROTTLE			(MAC_BANDWIDTH_LIMIT)

/* Special value denoting no bandwidth control */
#define	MAC_BANDWIDTH_RESET_LIMIT	-1ULL

/*
 * Until sub-megabit limit is implemented,
 * reject values lower than 1 MTU per tick or 1.2Mbps
 */
#define	MAC_BANDWIDTH_MIN_LIMIT		1200000

/* Define additional resource controls */

#define	MAC_RESOURCE_CTL		0x00000001
#define	MAC_BIND_CPU			0x00000002

/* 3 levels - low, medium, high */
#define	FLOW_PRIORITY_LEVELS		3

/* Flow priority values */
typedef enum {
	FLOW_LOW_PRIORITY,
	FLOW_MEDIUM_PRIORITY,
	FLOW_HIGH_PRIORITY,
	FLOW_RESET_PRIORITY
} flow_priority_t;

/* The default priority for links */
#define	FLOW_DEFAULT_LINK_PRIORITY	FLOW_HIGH_PRIORITY

/* The default priority for flows */
#define	FLOW_DEFAULT_FLOW_PRIORITY	FLOW_MEDIUM_PRIORITY

typedef	struct net_resource_ctl_s {
	mac_service_type_t	nr_mask;
	uint64_t		nr_bw_limit;	/* bandwidth limit in bps */
	flow_priority_t		nr_flow_priority; /* relative flow priority */
} net_resource_ctl_t;

/*
 * In CPULIST mode, cpu bindings is user specified. In COUNT mode, user
 * only specifies a fanout count.
 */
typedef enum {
	FANOUT_COUNT = 1,
	FANOUT_CPULIST
} fanout_mode_t;

#define	NBIND_CPU	128
/*
 * nbc_intr_cpu less than 0 implies platform limitation in retargetting
 * the interrupt assignment.
 */
typedef struct net_bind_cpus_s {
	uint32_t		nbc_ncpus;	/* num of cpus */
	uint32_t		nbc_cpus[NBIND_CPU];
	uint32_t		nbc_pollid;	/* poll thr cpubinding */
	uint32_t		nbc_workerid;	/* worker thr cpubinding */
	int32_t			nbc_intr_cpu;	/* interrupt cpu */
	uint32_t		nbc_cpu_ind;	/* round robin assignment */
	boolean_t		nbc_user_spec;	/* property user specified */
	fanout_mode_t		nbc_fanout_mode;
} net_bind_cpu_t;

typedef struct flow_stats_s {
	uint64_t	fs_rbytes;
	uint64_t	fs_ipackets;
	uint64_t	fs_ierrors;
	uint64_t	fs_obytes;
	uint64_t	fs_opackets;
	uint64_t	fs_oerrors;
} flow_stats_t;

typedef enum {
	FLOW_STAT_RBYTES,
	FLOW_STAT_IPACKETS,
	FLOW_STAT_IERRORS,
	FLOW_STAT_OBYTES,
	FLOW_STAT_OPACKETS,
	FLOW_STAT_OERRORS
} flow_stat_t;

#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
#pragma pack()
#endif

#ifdef	__cplusplus
}
#endif

#endif	/* _FLOW_H */
