/*
* 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
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Inter-Domain Network
*/
#ifndef _SYS_IDN_H
#define _SYS_IDN_H
#ifndef _ASM
#ifdef _KERNEL
#include <sys/dditypes.h>
#include <sys/machsystm.h>
#include <sys/ethernet.h>
#include <sys/idn_sigb.h>
#endif /* _KERNEL */
#ifdef __cplusplus
extern "C" {
#endif
typedef const char * const procname_t;
#ifdef _KERNEL
/*
* IDN_PROP_SMRSIZE - User specified size in MBytes.
* IDN_PROP_SMRADDR - OBP's internal physical address of the region.
*
* OBP properties of "memory" node that define the SMR space.
*/
/*
* IDN_AWOLMSG_INTERVAL (driver.conf)
*
* Number of seconds between AWOL messages on a per-domain basis.
* The purpose is to throttle the frequency at which these
* messages appear.
*
* IDN_MSGWAIT_NEGO (driver.conf)
* IDN_MSGWAIT_CFG
* IDN_MSGWAIT_CON
* IDN_MSGWAIT_FIN
* IDN_MSGWAIT_CMD
* IDN_MSGWAIT_DATA
*
* Number of seconds to wait for response to respective
* message type.
*
* IDN_RETRYFREQ_NEGO (driver.conf)
* IDN_RETRYFREQ_CON
* IDN_RETRYFREQ_FIN
*
* Number of seconds to wait between retries of the respective
* message type.
*
* IDN_SMR_ALIGN (not tunable)
*
* The hardware registers that describe the SMR are based on a 64K
* aligned physical address.
*
* IDN_SMR_SIZE (OBP [only])
*
* Total size of the SMR (Shared Memory Region) in bytes.
*
* IDN_NWR_SIZE (driver.conf)
*
* Total size of the NWR (NetWork Region) portion of the SMR which
* is actually used to support network activity. The NWR is managed
* as simply a pool of I/O buffers which are distributed by the
* Master domain to the Slaves for the purpose of communicating
* between each other. If not set then the entire SMR is used
* as the NWR.
* Req: IDN_NWR_SIZE <= IDN_SMR_SIZE
*
* IDN_SMR_BUFSIZE (driver.conf)
*
* Size of individual SMR buffers. The SMR is divided into chunks
* of IDN_SMR_BUFSIZE bytes. The IDN_MTU is based on this size
* and thus the IDN_SMR_BUFSIZE should be chosen based on performance.
*
* IDN_DATA_SIZE (NOT tunable)
*
* Portion of IDN_SMR_BUFSIZE that can contain raw non-IDN dependent
* data. We subtract IDN_ALIGNSIZE bytes to allow for fast bcopy
* alignment.
* Req: IDN_DATA_SIZE <=
* (IDN_SMR_BUFSIZE - sizeof (smr_pkthdr_t) - IDN_ALIGNSIZE)
*
* IDN_MTU (indirectly tunable via IDN_SMR_BUFSIZE)
*
* This size represents the portion of an SMR I/O buffers that can
* contain (ethernet headerless) data.
* Req: IDN_MTU <= IDN_DATA_SIZE - sizeof (ether_header)
*
* IDN_WINDOW_MAX (driver.conf)
*
* Maximum number of outstanding packets that are allowed per
* domain. If this value is exceeded for a particular domain
* has acknowledged enough of the previous transmission to bring
* down its outstanding I/O count (idn_domain.dio) below this
* value. In addition, if this value is exceeded then a Timer
* is scheduled to check for any response from the remote domain.
*
* IDN_WINDOW_INCR (driver.conf)
*
* the greater the number of possible outstanding data packets
* that can be outstanding to a given domain. Since this natural
* occurence can result in the outstanding-I/O count to a given
* domain to increase we run the risk of dropping into the
* IDN_WINDOW_MAX region even though the receiving domain
* may be fine with handling the load. In order to compensate
* for this increased activity and to not incur unjustified
* slips into the IDN_WINDOW_MAX region, the IDN_WINDOW_MAX
* that is activated for a given domain.
*
* IDN_WINDOW_EMAX (not tunable)
*
* The effective value of IDN_WINDOW_MAX once it has
* been adjusted by IDN_WINDOW_INCR.
*
* IDN_RECLAIM_MIN (driver.conf)
*
* Minimum number of outstanding packets that our allowed
* before subsequent sends will attempt to reclaim some number
* of outstanding data packets.
*
* IDN_RECLAIM_MAX (driver.conf)
* This value represents the maximum number of outstanding
* packets we will try to reclaim during a send once we've
* passed the IDN_RECLAIM_MIN boundary.
*
* IDN_MODUNLOADABLE (ndd)
*
* By default the IDN driver is unloadable. Setting this
* variable will allow the IDN driver to be unloaded provided
* it's not in use.
*
*
*
* IDN_MBOX_PER_NET (driver.conf)
*
* This value effectively represents the amount of outstanding
* activity that can reside at a domain. Increasing this value
* allows more packets to be in transit to a domain, however
* at some point there are diminishing returns since the receiver
* can only consume packets so fast.
*
* IDN_MAX_NETS (driver.conf)
*
* Maximum number of network interfaces (channels) that IDN
* is currently configured to allow. The absolute max is
* IDN_MAXMAX_NETS. We don't automatically default IDN_MAX_NETS
* to IDN_MAXMAX_NETS because it would mean wasted space in
* the mailbox region having to reserve mailboxes that will
* very likely go unused. The smaller this value the fewer
* the number of mailboxes in the SMR and thus the greater the
* number of possible I/O buffers available.
* Req: IDN_MAX_NETS <= IDN_MAXMAX_NETS
*
* IDN_CHECKSUM (driver.conf)
*
* If enabled, IDN validates the smr_pkthdr_t of incoming packets
* via a checksum, and calculates the checksum for outgoing packets.
* Only the first 3 fields of smr_pkthdr_t are checksummed and
* must be set to their expected values prior to calculating the
* checksum. Turned OFF by default when compiled DEBUG.
*
* IDN_SMR_MAXSIZE (not tunable)
*
* The absolute maximum size of the SMR region that we'll allow.
* Note that the virtual address space comes out kernelmap.
*/
- sizeof (smr_pkthdr_t) \
#define IDN_TUNEVAR_VALUE(v) (v)
/*
* History structure to support problem analysis.
*/
if (idn_history) { \
}
struct idn_h_entry {
};
struct idn_history {
int h_index;
};
#endif /* _KERNEL */
/*
* IDN_SIGBPIL - Interrupt level at which IDN driver
* wakes up idn_sigbhandler_thread
*/
/*
* Definition of sigbintr.sb_busy values which
* represents state of idn_sigbhandler.
*/
/*
* Some Xfire based macros that assume 4 cpus per board.
*/
{ \
register int c, b; \
(bset) = 0; \
for (b = 0; b < MAX_BOARDS; b++) \
for (c = 0; c < MAX_CPU_PER_BRD; c++) \
if (CPU_IN_SET((cset), \
(b * MAX_CPU_PER_BRD) + c)) \
(bset) |= 1 << b; \
}
/*
* Macros to manipulate boardset and domainset masks.
*/
/*
* PFN_TO_SMADDR macro converts a PFN to a IDN_SMR_ALIGN'ed
*/
#if (IDN_SMR_SHIFT <= MMU_PAGESHIFT)
#else
#endif
/*
* Translate a physical address to a unique domain identifier.
* IMPORTANT - Assumes each board's memory is configured on a 8GB
* boundary. PA(8G) = PFN(1M).
*/
/*
* The following are bit values of idn_debug, currently
* only useful if compiled with DEBUG.
*/
#ifdef DEBUG
#else
#endif /* DEBUG */
#ifdef _KERNEL
/*
* IDN drivers fields.
*
* IDNMINPSZ Minimum packet size the IDN supports.
*
* IDNMAXPSZ Maximum packet size that IDN supports from upper
* layers. Is equal to IDN_MTU + ether_header. Note
* that the IDN driver could support larger packets
* however the infrastructure to support fragmentation
* does not (and should not) exist with respect to
* ethernet packet types.
*/
#ifdef DEBUG
#else
#endif /* DEBUG */
#endif /* _KERNEL */
/*
* IDN Global States.
*/
typedef enum {
} idn_gstate_t;
#ifdef _KERNEL
/*
* Spaced defined in:
* sigblkp[cpu0.cpu_id]->sigb_idn.reserved1.
*/
#define IDNSB_GSTATE_NEW 0
/*
* This structure gets overlay onto:
* sigblkp[cpu0.cpu_id]->sigb_idn.reserved1.
*
* This structure must be exactly IDNSB_SIZE bytes.
*/
typedef struct idnsb {
struct {
{ \
(uchar_t)0xff; \
else \
} \
}
/*
* The following definitions and macros pertain to the
* id_hwstate and id_hwchkpt[] fields.
*
* id_hwstate (m = mark: 1=open, 2=close)
* 0 1 2 3 4 5 6 7
* ---------------------------------
* | m | m | m | m | XX unused XXX |
* ---------------------------------
* | | | |
* | | | +- CACHE
* | | +- CHAN
* | +- LINK
* +- SMR
*
* Note that nibble 4 is used in DEBUG for noting cache
* flush progress through idnxf_flushall_ecache(). This
* will override id_hwchkpt[] since it only has room for
* 4 items, however the BBSRAM space is there and
* unofficially available :-o
*
* id_hwchkpt[0] = SMR boardset
* id_hwchkpt[1] = LINK boardset
* id_hwchkpt[2] = CHAN boardset
* id_hwchkpt[3] = CACHE boardset.
*/
#define IDNSB_CHKPT_SMR 0
{ \
}
{ \
} \
}
{ \
} \
}
{ \
} \
}
#ifdef DEBUG
#else
#endif /* DEBUG */
#ifdef DEBUG
{ \
/*LINTED*/ \
ASSERT(IDN_GLOCK_IS_EXCL()); \
PR_STATE("GSTATE:%ld: (l=%d) %s(%d) -> %s(%d)\n", \
} \
}
#else
{ \
} \
}
#endif /* DEBUG */
/*
* caller. The following definitions are to support the return of
* just provide a very small cache of waiting list entries. If the
* cache becomes exhausted then additional ones are kmem_alloc'd.
*/
typedef struct dop_waitlist {
short dw_op;
/*
* Types of synchronization zones which a connection
* could be in.
*/
typedef enum {
/*
* Type of sync-registration that is being requested.
*/
typedef enum {
((s) != IDNSYNC_DISCONNECT)) ? \
-1 : (int)(s) - 1)
((s) == IDNSYNC_DISCONNECT) ? \
/*
* Generic states when in a state transition region.
* These ultimately map to domain states via
* a idn_xphase_t definition. General model:
*
* PEND
* /\
* / \
* | |
* V V
* SENT--->RCVD
* \ /
* \ /
* VV
* FINAL
*
* Start these types with PEND = 0 so that they're
* compatible with idnxs_state_table[] and idn_xphase_t
* phases that use the value as an index.
*/
typedef enum {
} idn_xstate_t;
/*
* Locking protocol:
*
* Each routine is called with SYNC_LOCK and
* the respective domain's DLOCK(EXCL) held.
* The routines must return with these locks
* still held.
*/
struct idn_msgtype;
typedef struct {
int t_state;
} idn_trans_t;
/*
* The callback routines (xt_final & xt_exit) are called with
* DLOCK and SYNC_LOCK held and they are required to return
* with these locks still held.
*/
typedef struct {
} idn_xphase_t;
/*
* Synchronization entry representing the synchronization
* state with respect to a given domain for a given zone.
*/
typedef struct idn_syncop {
int s_domid;
int s_msg;
void *s_transarg;
#ifdef DEBUG
#endif /* DEBUG */
} idn_syncop_t;
#ifdef DEBUG
#define IDN_SYNC_QUERY_INIT(d) \
#else /* DEBUG */
#define IDN_SYNC_QUERY_INIT(d)
#endif /* DEBUG */
typedef struct {
int sc_cnt;
#endif /* _KERNEL */
/*
* Vote Ticket used during negotiations and elections.
*
* 31 0
* -----------------------------------------
* |m...|....|pppp|....|Cbbb|bccc|cccB|BBB1|
* -----------------------------------------
* . [30:24] = unused
* p [23:20] = priority
* . [19:16] = unused
* C [15] = connected (has master)
* b [14:11] = nmembrds-1
* c [10:5] = ncpus-1
* B [4:1] = board_id
* 1 [0] = one
*/
typedef union {
struct {
} v;
} idn_vote_t;
#define IDNVOTE_MINPRI 0
/*
* Initially:
* vote.v.priority = IDNVOTE_DEFPRI
* vote.v.one = 1
*/
/*
* During elections we only use the "elect" attributes of the
* election ticket, i.e. those physical attributes pertaining
* to the individual domain (priority, nboards, ncpus, board).
*/
/*
* Values used in idn_select_master().
*/
typedef enum {
/*
* the original requester (user). Necessary since link establishment
* occurs asynchronously.
*/
typedef enum {
} idn_opflag_t;
/*
* IDN Protocol Messages.
* These are IDN version (IDN_VERSION) dependent.
*
* ----- 7, --- 6,5.................0
* | ack | nack | IDN message type |
* ----------------------------------
*/
/*
* Must be no more than 6-bits. See DMV private data.
*/
typedef struct idn_msgtype {
/*
* IDN private data section of DMV layout (48 bits).
*
* 47......40,39.....34,33.....28,27..24,23......16,15..............0
* | version | msgtype | acktype | did | cpuid | cookie |
* ------------------------------------------------------------------
*
* version Local domain's version of IDN software.
* msgtype Type of IDN message, e.g. nego, syn, etc.
* acktype If msgtype is a ACK or NACK, then acktype is the
* did Local domain's ID (netid) - system-wide unique.
* cpuid Local domain's CPU->cpu_id that sending message.
* cookie Cookie assigned by remote domain for authentication.
* For NEGO & NEGO+ACK messages, it's the cookie that
* the sender expects the receiver to use in subsequent
* messages. The upper-eight bits represent a timer
* cookie to associate timers with expected messages.
*/
#endif /* !_ASM */
#ifdef _KERNEL
#define _IDNPD_CPUID_SHIFT 0
#ifndef _ASM
_IDNPD_COOKIE_SHIFT) | \
_IDNPD_VER_SHIFT) | \
_IDNPD_MTYPE_SHIFT) | \
_IDNPD_ATYPE_SHIFT) | \
_IDNPD_DOMID_SHIFT) | \
/*
* IDNP_NEGO
*
* 127........96,95........64,63........32,31.........0
* | vote | domainset |
* ----------------------------------------------------
* domainset Mask of cpuids of domains to which
* sender is connected. Position in domainset
* designates respective domainid.
* E.g. domainset[6] = 20 -> domainid 6 is
* accessible via cpuid 20.
* The slot for the receiving domain
* contains the masterid of the sending
* domain. If the sending domain does
* not have a master then the entry will
* contain IDNNEG_NO_MASTER.
*
* These macros insert a domainid-cpuid pair into the
* domainset to be subsequently passed in a NEGO message,
* also retrieve the cpuid from the domainset for a
* given domainid.
*
* Usage:
* Sending:
* mask = IDNNEG_DSET_MYMASK();
* IDNNEG_DSET_INIT(dset, mask)
* for (all domains except self)
* IDNNEG_DSET_SET(dset, domain, cpuid, mask);
*
* Receiving:
* IDNNEG_DSET_GET_MASK(dset, recv_domid, recv_mask);
* for (all domains except recv_domid)
* IDNNEG_DSET_GET(dset, domid, cpuid, recv_mask);
*/
sizeof (idnneg_dset_t)))
{ \
}
{ \
/*LINTED*/ \
}
{ \
else \
(cpuid) = -1; \
}
(domid)+MAX_DOMAINS)
/*
* IDNP_CFG sub-types.
*
* Format of first 32 bit word in XDC:
* stX = sub-type.
* staX = sub-type arg.
* X = position in idn_cfgsubtype_t.param.p[] array.
* num = number of parameters in this XDC (0-3)
*
* 31...28,27...24,23...20,19...16,15...12,11....8,7.....3,2....0
* | st0 . sta0 | st1 . sta1 | st2 . sta2 | phase | num |
* --------------------------------------------------------------
*
* Note that since the first 32-bit word in a (IDNP_CFG) XDC is used
* for a sub-type, subsequent three 32-bits words are used for data that
* pertains to respective sub-type, i.e. first sub-type corresponds
* to first of the 3x32-bit words (pos=0), second sub-type corresponds
* to second of the 3x32-bit words (pos=1), etc. Obviously, a max of
* only three sub-types can be sent per xdc.
*/
typedef union {
struct {
uchar_t p[3];
} param;
struct {
} info;
/*
* IDN_MASTER_NCFGITEMS
* Minimum number of config items expected from master.
*
* IDN_SLAVE_NCFGITEMS
* Number of config items expected from slave.
*/
/*
* IDNP_CMD sub-types.
*/
typedef enum {
} idn_cmd_t;
((int)(c) <= (int)IDNCMD_NODENAME))
/*
* IDNP_NACK
*/
typedef enum {
} idn_nack_t;
/*
* IDNP_CON sub-types.
*/
typedef enum {
} idn_con_t;
/*
* IDNP_FIN sub-types.
*/
typedef enum {
} idn_fin_t;
#define VALID_FIN(f) (((int)(f) > 0) && \
((int)(f) < (int)IDNFIN_QUERY))
((f) == IDNFIN_FORCE_HARD))
/*
* FIN ARG types - reasons a FIN was sent.
*/
typedef enum {
} idn_finarg_t;
#define SET_FIN_TYPE(x, t) \
#define SET_FIN_ARG(x, a) \
/*
* FIN SYNC types.
*/
typedef short idn_finsync_t;
/*
* IDNP_FIN options.
*/
typedef enum {
} idn_finopt_t;
((f) == IDNFIN_OPT_RELINK))
IDN_NIL_DCPU : ((x) & 0xfff))
((uint_t)(c) & 0xffff))
#ifdef DEBUG
{ \
int _id; \
PR_STATE("FSTATE:%ld:%d: (l=%d, b/p=%d/%d) " \
"%s(%d) -> %s(%d)\n", \
__LINE__, \
} \
}
#else
{ \
}
#endif /* DEBUG */
#endif /* !_ASM */
#endif /* _KERNEL */
#ifndef _ASM
/*
* IDN Per-Domain States.
*/
typedef enum {
} idn_dstate_t;
#endif /* !_ASM */
#ifdef _KERNEL
#ifndef _ASM
/*
* ---------------------------------------------------------------------
*/
typedef struct idn_timer {
*t_back;
short t_domid;
short t_onq;
#ifdef DEBUG
#endif /* DEBUG */
} idn_timer_t;
((void) idn_timer_stopall(tp))
{ \
}
#ifdef DEBUG
#else /* DEBUG */
#endif /* DEBUG */
{ \
idn_timer_t *_tp; \
char _str[15]; \
PR_TIMER("msgtimer:%d: START: type = %s (0x%x)\n", \
_tp = IDN_TIMER_ALLOC(); \
IDN_TIMER_POST(_tp); \
if (_ckp) { \
} else { \
} \
}
{ \
char _str[15]; \
PR_TIMER("msgtimer:%d: STOP: type = %s (0x%x), " \
"cookie = 0x%x\n", \
}
/*
* IDN_SLABALLOC_WAITTIME
* Max wait time in ticks that local domains waits for
* master to respond to a slab allocation request. Has
* to be at least as long as wait time for a response to
* the command.
*/
/*
* Domain state transition macros.
*/
#ifdef DEBUG
{ \
int id; \
PR_STATE("DSTATE:%ld:%d: (l=%d, b/p=%d/%d) " \
"%s(%d) -> %s(%d)\n", \
__LINE__, \
}
#else
{ \
}
#endif /* DEBUG */
{ \
IDN_DSTATE_TRANSITION((dp), \
} \
}
/*
* ---------------------------------------------------------------------
* IDN Per-Domain Data
*
* The comment to the right of the respective field represents
* what lock protects that field. If there is no comment then
* no lock is required to access the field.
* ---------------------------------------------------------------------
*/
typedef struct idn_domain {
/*
* Assigned domid for domain. Never
* changes once idn_domain[] is
* initialized. We are guaranteed that
* all domains in IDN will have a
* uniqueue domid in the range (0-15).
*/
int domid;
/*
* Gotten from uname -n for local
* domain. Remote domains pass
* theirs during Config phase.
*/
/*
* IDN-wide unique identifier for the
* given domain. This value will be
* the same as the domid.
*/
/*
* Used during FIN sequenece to
* determine what type of shutdown
* (unlink) we're executing with
* respect to the given domain.
*/
/*
* A non-zero value for dfin_sync
* indicates that unlink of respective
* domain does not need to be performed
* synchronously among all the IDN
* member domains.
*/
/*
* Cookie used to determine the
* proper context in which we're
* receiving messages from the given
* domain. Assigned cookies are exchanged
* during initial NEGO messages.
*/
/*
* Primary target cpu for sending
* messages. Can change to help
* distribute interrupts on receiving
* side.
*/
/*
* Used to store dcpu from a previous
* life. Only used when requesting
* a RELINK with a domain we were just
* previously linked with. Thus, it
* does represent a valid cpu in the
* remote domain.
*/
/*
* Used to store from which cpu the
* last message was received.
*/
int dcpu_last;
/*
* Transition phase area. This field
* points to the proper phase structure
* depending on what stage the given
* domain is in.
*/
/*
* Actual synchronization object for
* the given domain.
*/
/*
* Slab information for given domain.
* If the local domain is a master,
* then this field in each domain is used
* to store which slabs have been assigned
* to given domain. If the local domain
* is a slave, then this information is
* NULL for all remote idn_domain[]
* entries, but for local domain holds
* those slabs assigned to local domain.
*/
/*
* Set of cpus belonging to domain.
*/
/*
* Index into dcpumap to determine
* which cpu to target next for
* interrupt. Intended to allow fair
* distribution of interrupts on
* remote domain.
*/
/*
* Quick look-up map of cpus belonging
* to domain. Used to select next target.
*/
/*
* Non-zero indicates outstanding
* I/O's to given domain.
*/
/*
* Set when we fail to allocate a buffer
* for a domain. Dictates whether to
* reclaim max buffers or not.
*/
/*
* Set when remote domain does not
* seem to be picking up messages sent
* to it. Non-zero indicates we have
* an outstanding "ping" to domain.
*/
/*
* The following field is primarily
* used during CFG exchange to keep
* track of certain per-domain information.
*/
union { /* all - drwlock */
struct {
} _s;
int _dtmp;
} _u;
/*
* Each domain entry maintains a
* timer queue holding timers for
* messages outstanding to that domain.
*/
struct idn_timerq {
} dtimerq;
/*
* dawol is used to keep
* track of AWOL details for
* given domain when it is
* non-responsive.
*/
struct {
} dawol;
struct hwconfig {
} dhw;
/*
* Mailbox information used to
*/
struct {
} dmbox;
} idn_domain_t;
#define DSLAB_STATE_UNKNOWN 0
#define DSLAB_LOCK_EXCL(d) \
#define DSLAB_LOCK_SHARED(d) \
#define DSLAB_LOCK_TRYUPGRADE(d) \
/*
* ---------------------------------------------------------------------
* Macro to pick another target for the given domain. This hopefully
* improves performance by better distributing the SSI responsibilities
* at the target domain.
* ---------------------------------------------------------------------
*/
{ \
register int p; \
if (CPU_IN_SET((set), p)) \
break; \
if (p >= NCPU) \
for (p = 0; p <= (index); p++) \
if (CPU_IN_SET((set), p)) \
break; \
if (!CPU_IN_SET((set), p)) { \
"IDN: cpu %d not in cpuset 0x%x.%0x\n", \
} \
(index) = p; \
}
/*
* ---------------------------------------------------------------------
* ---------------------------------------------------------------------
*/
(uint32_t)(n))
/*
* DMV vector interrupt support.
*
* A fixed-size circular buffer is maintained as a queue of
* incoming interrupts. The low-level idn_dmv_handler() waits
* for an entry to become FREE and will atomically mark it INUSE.
* Once he has filled in the appropriate fields it will be marked
* as READY. The high-level idn_handler() will be invoked and will
* process all messages in the queue that are READY. Each message
* is marked PROCESS, a protojob job created and filled in, and
* then the interrupt message is marked FREE for use in the next
* interrupt. The iv_state field is used to hold the relevant
* state and is updated atomically.
*/
#endif /* !_ASM */
#ifndef _ASM
/*
* The size of this structure must be a power of 2
* so that we can do a simple shift to calculate
* our offset into based on cpuid.
*/
typedef struct idn_dmv_cpu {
sizeof (uint32_t) - \
sizeof (lock_t) - \
sizeof (int32_t)];
typedef struct idn_dmv_data {
/*
* Requirements of the following data structure:
* - MUST be double-word (8 bytes) aligned.
* - _iv_head field MUST start on double-word boundary.
* - iv_xargs0 MUST start on double-word boundary
* with iv_xargs1 immediately following.
* - iv_xargs2 MUST start on double-word boundary
* with iv_xargs3 immediately following.
*/
typedef struct idn_dmv_msg {
extern uint_t idn_dmv_inum;
extern uint_t idn_soft_inum;
/*
* An IDN-network address has the following format:
*
* 31......16,15........0
* | channel | dnetid |
* ----------------------
* channel - network interface.
* netid - idn_domain[].dnetid
*/
typedef union {
struct {
} net;
#define CHANSET(c) \
#define CHAN_IN_SET(m, c) \
#define CHANSET_ADD(m, c) \
#define CHANSET_DEL(m, c) \
#define CHANSET_ZERO(m) ((m) = 0)
typedef enum {
} idn_chanop_t;
/*
* Retry support.
*/
(0xffff & (uint_t)(x)))
typedef struct idn_retry_job {
void *rj_arg;
short rj_onq;
#define IDNRETRY_ALLOCJOB() \
#define IDNRETRY_FREEJOB(j) \
typedef enum {
} idn_retry_t;
/*
* ---------------------------------------------------------------------
*/
typedef struct {
int m_domid;
int m_cpuid;
typedef struct idn_protojob {
int j_cache;
typedef struct idn_protoqueue {
int q_die;
int q_id;
/*
* ---------------------------------------------------------------------
* Data Server definitions.
*
* idn_datasvr_t - Describes data server thread.
* . ds_id - Per-domain identifier for data server.
* . ds_domid - Domain which data server is handling.
* data server.
* . ds_mboxp - Pointer to data server's (local)
* mailbox to be serviced.
* . ds_waittime - cv_timedwait sleep time before
* checking respective mailbox.
* . ds_threadp - Pointer to data server thread.
* . ds_cv - Condvar for sleeping.
* . ds_morguep - Semaphore for terminating thread.
*
* idn_mboxhdr_t - Resides in SMR space (MUST be cache_linesize).
* . mh_svr_active - Non-zero indicates data server is
* actively reading mailbox for messages.
* . mh_svr_ready - Non-zero indicates data server has
* allocated and is ready to accept data.
* . mh_cookie - Identifier primarily for debug purposes.
*
* idn_mboxmsg_t - Entry in the SMR space circular queue use to
* represent a data packet.
* . mm_owner - Non-zero indicates entry is available
* to be processed by receiver's data server.
* . mm_flag - Indicates whether entry needs to be
* reclaimed by the sender. Also holds error
* indications (e.g. bad offset).
* . mm_offset - SMR offset of respective data packet.
*
* idn_mboxtbl_t - Encapsulation of a per-domain mailbox (SMR space).
* . mt_header - Header information for synchronization.
* . mt_queue - Circular queue of idn_mboxmsg_t entries.
*
* . mm_mutex - Protects mm_* entries, enqueuing, and
* dequeuing of messages. Also protects
* updates to the route table pointed to
* by mm_routetbl.
* . mm_count - send: Current number of messages
* enqueued.
* - recv: Cumulative number of messages
* processed.
* . mm_max_count - send: Maximum number of messages
* enqueued per iteration.
* recv: Maximum number of messages
* dequeued per iteration.
* . mm_smr_mboxp - Pointer to SMR (vaddr) space where
* respective mailbox resides.
* ---------------------------------------------------------------------
*/
((IDN_MBOXHDR_COOKIE_TOP << 16) \
((IDN_GET_MBOXHDR_COOKIE(mhp) == \
IDN_MAKE_MBOXHDR_COOKIE(0, 0, (ch))) && \
/*
* The number of entries in a mailbox queue must be chosen so
* that (IDN_MMBOX_NUMENTRIES * sizeof (idn_mboxmsg_t)) is a multiple
* of a cacheline size (64).
*/
/*
* We step through the mailboxes in effectively cacheline size
* incremenents so that the source and receiving cpus are not competing
* for the same cacheline when transmitting/receiving messages into/from
* the mailboxes. The hard requirement is that the step value be even
* since the mailbox size will be chosen odd. This allows us to wraparound
* the mailbox uniquely touching each entry until we've exhausted them
* all at which point we'll end up where we initially started and repeat
* again.
*/
#define IDN_MMBOXINDEX_INC(i) \
{ \
if (((i) += IDN_MMBOXINDEX_STEP) >= IDN_MMBOX_NUMENTRIES) \
(i) -= IDN_MMBOX_NUMENTRIES; \
}
#define IDN_MMBOXINDEX_DIFF(i, j) \
(((i) >= (j)) ? (((i) - (j)) / IDN_MMBOXINDEX_STEP) \
: ((((i) + IDN_MMBOX_NUMENTRIES) - (j)) / IDN_MMBOXINDEX_STEP))
/*
* Require IDN_MBOXAREA_SIZE <= IDN_SLAB_SIZE so we don't waste
* slab space.
*
* Each domain maintains a MAX_DOMAIN(16) entry mbox_table. Each
* entry represents a receive mailbox for a possible domain to which
* the given domain may have a connection. The send mailbox for each
* respective domain is given to the local domain at the time of
* connection establishment.
*/
/*
* ---------------------------------------------------------------------
*/
#define IDN_MBOXTBL_SIZE \
+ sizeof (idn_mboxhdr_t)), IDN_ALIGNSIZE))
/*
* ---------------------------------------------------------------------
* Each domain has idn_max_nets worth of possible mailbox tables
* for each domain to which it might possibly be connected.
* ---------------------------------------------------------------------
*/
#define IDN_MBOXAREA_SIZE \
#define IDN_MBOXAREA_OFFSET(d) \
/*
* ---------------------------------------------------------------------
* Return the base of the mailbox area (set of tables) assigned
* to the given domain id.
* ---------------------------------------------------------------------
*/
#define IDN_MBOXAREA_BASE(m, d) \
/*
* ---------------------------------------------------------------------
* Return the pointer to the respective receive mailbox (table set)
* for the given domain id relative to the given base mailbox table.
* ---------------------------------------------------------------------
*/
#define IDN_MBOXTBL_PTR(t, d) \
* IDN_MAX_NETS)))
/*
* ---------------------------------------------------------------------
* Return the pointer to the actual target mailbox based on the
* given channel in the given mailbox table.
* ---------------------------------------------------------------------
*/
#define IDN_MBOXTBL_PTR_CHAN(t, c) \
#define IDN_MBOXTBL_PTR_INC(t) \
#define IDN_MBOXCHAN_INC(i) \
{ \
if (++(i) == IDN_MAX_NETS) \
(i) = 0; \
}
/*
* ---------------------------------------------------------------------
* Return the absolute location within the entire mailbox area
* of the mboxtbl for the given primary and secondary domain and
* channel. Only relevant when done by the master.
* ---------------------------------------------------------------------
*/
(sd)), \
(ch)))
typedef struct idn_mboxmsg {
#define IDN_CKSUM_MBOX(h) \
(IDN_CHECKSUM ? \
typedef struct idn_mboxhdr {
(4*sizeof (uint_t)) -
typedef struct idn_mboxtbl {
{ \
register int _d; \
if ((int)(((csp)->ch_recv_scanset_pending >> \
break; \
else \
} \
(csp)->ch_recv_domcount++; \
} \
} \
}
{ \
register int _d; \
if ((int)(((csp)->ch_recv_scanset_pending >> \
break; \
else \
} \
(csp)->ch_recv_domcount--; \
if ((csp)->ch_recv_domcount) { \
(csp)->ch_recv_scanset_pending |= \
_domset; \
_domset <<= \
} \
} \
} \
}
/*
* A channel table is an array of pointers to mailboxes
* for the respective domains for the given channel.
* Used a cache for the frequently used items. Respective
* fields in mainmbox are updated just prior to sleeping.
*/
/*
* Reading c_state requires either c_mutex or ch_mutex.
* Writing c_state requires both c_mutex and ch_mutex in the order:
* ch_mutex
* c_mutex
*/
typedef struct idn_chaninfo {
/*
* When updating both recv and send c_state's for the locks
* must be grabbed in the following order:
* ch_mutex
* ch_recv.c_mutex
* ch_send.c_mutex
* This order is necessary to prevent deadlocks.
* In general ch_state is intended to represent c_state of
* ch_state and c_state values may be slightly different,
* but eventually should end up identical.
*/
typedef struct idn_chansvr {
sizeof (idn_chaninfo_t)) / sizeof (int)];
short ch_recv_domcount;
int ch_recv_waittime;
int ch_recv_changed;
int ch_bound_cpuid;
typedef struct idn_mainmbox {
short mm_channel;
short mm_domid;
short mm_type;
int mm_count;
int mm_dropped;
/*
* mm_flags
*/
/*
* mm_type
*/
/*
* Period between sending wakeup xdc's to remote domain.
*/
/*
* ms_flag bit values.
*/
/*
*/
/*
* GLOBAL
*/
/*
* SEND
*/
/*
* RECV
*/
{ \
}
{ \
}
typedef enum {
#define IDN_CHANNEL_SUSPEND(c, w) \
(idn_chan_action((c), IDNCHAN_ACTION_SUSPEND, (w)))
#define IDN_CHANNEL_RESUME(c) \
(idn_chan_action((c), IDNCHAN_ACTION_RESUME, 0))
#define IDN_CHANNEL_STOP(c, w) \
(idn_chan_action((c), IDNCHAN_ACTION_STOP, (w)))
#define IDN_CHANNEL_RESTART(c) \
(idn_chan_action((c), IDNCHAN_ACTION_RESTART, 0))
#define IDN_CHANNEL_DETACH(c, w) \
(idn_chan_action((c), IDNCHAN_ACTION_DETACH, (w)))
#define IDN_CHANNEL_ATTACH(c) \
(idn_chan_action((c), IDNCHAN_ACTION_ATTACH, 0))
/*
* ds_waittime range values.
* When a packet arrives the waittime starts at MIN and gradually
* shifts up to MAX until another packet arrives. If still no
* packet arrives then we go to a hard sleep
*/
/*
* ---------------------------------------------------------------------
* IDN Global Data
*
* The comment to the right of the respective field represents
* what lock protects that field. If there is no comment then
* no lock is required to access the field.
* ---------------------------------------------------------------------
*/
/*
* Global state of IDN w.r.t.
* the local domain.
*/
/*
* Version of the IDN driver.
* Is passed in DMV header so that
* other domains can validate they
* support protocol used by local
* domain.
*/
int version;
/*
* Set to 1 if SMR region properly
* allocated and available.
*/
int enabled;
/*
* Local domains "domain id".
*/
int localid;
/*
* Domain id of the Master domain.
* Set to IDN_NIL_DOMID if none
* currently exists.
*/
/*
* Primarily used during Reconfiguration
* to track the expected new Master.
* Once the current IDN is dismantled
* the local domain will attempt to
* connect to this new domain.
*/
/*
* Number of protocol servers configured.
*/
int nservers;
struct {
/*
* dmv_inum
* Interrupt number assigned by
* DMV subsystem to IDN's DMV
* handler.
* soft_inum
* Soft interrupt number assigned
* by OS (add_softintr) for Soft
* interrupt dispatched by DMV
* handler.
*/
} intr;
/*
* first_swlink
* Used as synchronization to
* know whether channels need
* to be activated or not.
* first_hwlink
* Used as mechanism to determine
* whether local domain needs
* to publicize its SMR, assuming
* it is the Master.
* first_hwmaster
* Domainid of the domain that
* was the master at the time
* the hardware was programmed.
* We need to keep this so that
* we deprogram with respect to
* the correct domain that the
* hardware was originally
* programmed to.
*/
short first_hwmasterid;
/*
* The xmit* fields are used to set-up a background
* thread to monitor when a channel is ready to be
* enabled again. This is necessary since IDN
* can't rely on hardware to interrupt it when
* things are ready to go. We need this ability
* to wakeup our STREAMS queues.
* Criteria for reenabling queues.
* gstate == IDNGS_ONLINE
* channel = !check-in
* buffers are available
*
* xmit_chanset_wanted
* Indicates which channels wish to have
* their queues reenabled when ready.
* xmit_tid
* Timeout-id of monitor.
*/
struct {
/*
* ready
* Indicates SMR region allocated
* and available from OBP.
* vaddr
* Virtual address assigned to SMR.
* locpfn
* Page Frame Number associated
* with local domain's SMR.
* rempfn
* Page Frame Number associated
* with remote (Master) domain's SMR.
* rempfnlim
* PFN past end of remote domain's
* SMR.
* Physical address and size of
* SMR that were assigned by OBP.
*/
int ready;
} smr;
/*
* idnsb_mutex
* Protects access to IDN's
* sigblock area.
* idnsb_eventp
* IDN's private area in sigblock
* used for signaling events
* regarding IDN state to SSP.
* idnsb
* Area within IDN's private
* sigblock area used for tracking
* certain IDN state which might
* be useful during arbstop
* conditions (if caused by IDN!).
*/
struct sigbintr {
/*
* sb_mutex
* Protects sigbintr elements
* to synchronize execution of
* sigblock (IDN) mailbox handling.
* sb_cpuid
* Cpu whose sigblock mailbox
* originally received IDN request
* from SSP. Necessary to know
* where to put response.
* sb_busy
* Flag indicating state of
* sigblock handler thread.
* Synchronize activity between
* SSP and current IDN requests that
* are in progress.
* sb_cv
* Condition variable for sigblock
* handler thread to wait on.
* sb_inum
* Soft interrupt number assigned
* by OS to handle soft interrupt
* request make by low-level (IDN)
* sigblock handler to dispatch actual
* processing of sigblock (mailbox)
* request.
*/
} sigbintr;
/*
* struprwlock, strup, sip, siplock
* Standard network streams
* handling structures to manage
* instances of IDN driver.
*/
/*
* Area where IDN maintains its kstats.
*/
/*
* Number of domains that local domain
* has "open".
*/
/*
* Number of domains that local domain
* has registered as non-responsive.
*/
/*
* Number of network channels (interfaces)
* which are currently active.
*/
/*
* Bitmask representing channels
* that are currently active.
*/
/*
* that have been created. Not necessarily
* all active.
*/
/*
* Pointer to sigblock handler thread
* which ultimately processes SSP
* IDN requests.
*/
/*
* Pointer to area used by Master
* to hold mailbox structures.
* Actual memory is in SMR.
*/
struct {
/*
* IDN_SYNC_LOCK - Provides serialization
* mechanism when performing synchronous
* operations across domains.
*/
/*
* Actual synchronization zones for
* CONNECT/DISCONNECT phases.
*/
struct {
/*
* ds_trans_on
* Set of domains which are trying
* ds_ready_on
* Set of domains which local knows
* are ready for linking, but has
* ds_connected
* Set of domains that local has
* confirmed as being ready.
* ds_trans_off
* Set of domains which are trying
* to unlink from local.
* ds_ready_off
* Set of domains which local knows
* are ready for unlink, but has
* ds_relink
* Set of domains we're expecting
* to relink with subsequent to
* a RECONFIG (new master selection).
* ds_hwlinked
* Set of domains for which local
* has programmed its hardware.
* ds_flush
* Set of domains requiring that
* local flush its ecache prior
* to unlinking.
* ds_awol
* Set of domains believed to be
* AWOL - haven't responded to
* any queries.
* ds_hitlist
* Set of domains which local domain
* is unlinking from and wishes to ignore
* any extraneous indirect link requests
* from other domains, e.g. during a
* Reconfig.
*/
} domset;
/*
* Bitmask identifying all cpus in
* the local IDN.
*/
/*
* Bitmask identifying all boards in
* the local IDN.
*/
struct dopers {
/*
* Waiting area for IDN requests,
* i.e. link & unlinks. IDN requests
* are performed asynchronously so
* we need a place to wait until the
* operation has completed.
*
* dop_domset
* Identifies which domains the
* current waiter is interested in.
* dop_waitcount
* Number of waiters in the room.
* dop_waitlist
* Actual waiting area.
* dop_freelist
* Freelist (small cache) of
* structs for waiting area.
*/
/* dop_mutex */
} *dopers;
struct {
/*
* Protocol Server:
*
* p_server
* Linked list of queues
* describing protocol
* servers in use.
* p_jobpool
* Kmem cache of structs
* used to enqueue protocol
* jobs for protocol servers.
* p_morgue
* Synchronization (check-in)
* area used when terminating
* protocol servers (threads).
*/
} protocol;
struct idn_retry_queue {
/*
* rq_jobs
* Queue of Retry jobs
* that are outstanding.
* rq_count
* Number of jobs on retry
* queue.
* rq_cache
* Kmem cache for structs
* used to describe retry
* jobs.
*/
} retryqueue;
struct slabpool {
/*
* Slabpool:
*
* ntotslabs
* Total number of slabs
* in SMR (free & in-use).
* npools
* Number of pools available
* in list. One smr_slabtbl
* exists for each pool.
*/
int ntotslabs;
int npools;
struct smr_slabtbl {
/*
* sarray
* Array of slab structs
* representing slabs in SMR.
* nfree
* Number of slabs actually
* available in sarray.
* nslabs
* Number of slabs represented
* in sarray (free & in-use).
*/
int nfree;
int nslabs;
} *pool;
/*
* Holds array of smr_slab_t structs kmem_alloc'd
* for slabpool.
*/
} *slabpool;
struct slabwaiter {
/*
* Waiting area for threads
* requesting slab allocations.
* Used by Slaves for all requests,
* but used by Master only for
* redundant requests, i.e. multiple
* requests on behalf of the same
* domain. One slabwaiter area
* exist for each possible domain.
*
* w_nwaiters
* Number of threads waiting
* in waiting area.
* w_done
* Flag to indicate that
* allocation request has
* completed.
* w_serrno
* Non-zero indicates an
* errno value to represent
* error that occurred during
* attempt to allocate slab.
* w_closed
* Indicates that waiting area is
* closed and won't allow any new
* waiters. This occurs during
* the small window where we're
* trying to suspend a channel.
* w_cv
* Condvar for waiting on.
* w_sp
* Holds slab structure of
* successfully allocated slab.
*/
} *slabwaiter;
/*
* Kmem cache used for allocating
* timer structures for outstanding
* IDN requests.
*/
/*
* Effectively constant used in
* translating buffer frames in
* mailbox message frames to
* offsets within SMR.
*/
int bframe_shift;
} idn_global_t;
{ \
if (_mid == IDN_NIL_DOMID) \
else \
} \
}
{ \
}
/*
* Macro to reset some globals necessary in preparing
* for initialization of HW for IDN.
*/
#define IDN_PREP_HWINIT() \
{ \
ASSERT(IDN_GLOCK_IS_EXCL()); \
}
/*
* Return values of idn_send_data.
*/
/*
* ---------------------------------------------------------------------
* ss_rwlock must be acquired _before_ any idn_domain locks are
* acquired if both structs need to be accessed.
* idn.struprwlock is acquired when traversing IDN's strup list
* and when adding or deleting entries.
*
* ss_nextp Linked list of streams.
* ss_rq Respective read queue.
* ss_sip Attached device.
* ss_state Current DL state.
* ss_sap Bound SAP.
* ss_flags Misc. flags.
* ss_mccount # enabled multicast addrs.
* ss_mctab Table of multicast addrs.
* ss_minor Minor device number.
* ss_rwlock Protects ss_linkup fields and DLPI state machine.
* ss_linkup Boolean flag indicating whether particular (domain) link
* is up.
* ---------------------------------------------------------------------
*/
};
/*
* idnstr.ss_flags - Per-stream flags
*/
/*
* Maximum number of multicast address per stream.
*/
/*
* Full DLSAP address length (in struct dladdr format).
*/
struct idndladdr {
};
/*
* Respective interpretation of bytes in 6 byte ethernet address.
*/
#define IDNETHER_ZERO 0
/*
* IDN driver supports multliple instances, however they
* still all refer to the same "physical" device. Multiple
* instances are supported primarily to allow increased
* STREAMs bandwidth since each instance has it's own IP queue.
* This structure is primarily defined to be consistent with
* other network drivers and also to hold the kernel stats.
*/
struct idn_kstat {
/*
* MIB II kstat variables
*/
/*
* PSARC 1997/198 : 64 bit kstats
*/
/*
* PSARC 1997/247 : RFC 1643 dot3Stats...
*/
};
/*
* Per logical interface private data structure.
*/
struct idn {
};
struct idn_gkstat {
};
extern struct idn_gkstat sg_kstat;
#ifdef IDN_NO_KSTAT
#define IDN_KSTAT_INC(s, i)
#define IDN_KSTAT_ADD(s, i, n)
#define IDN_GKSTAT_INC(i)
#else /* IDN_NO_KSTAT */
#endif /* IDN_NO_KSTAT */
/*
* idn.si_flags
*/
struct idn_kstat_named {
/*
* MIB II kstat variables
*/
/*
* PSARC 1997/198 : 64bit kstats
*/
/*
* PSARC 1997/247 : RFC 1643 dot3Stats...
*/
};
/*
* Stats for global events of interest (non-counters).
*/
struct idn_gkstat_named {
};
/*
* ---------------------------------------------------------------------
*/
#ifdef DEBUG
#else /* DEBUG */
#endif /* DEBUG */
/*
* ---------------------------------------------------------------------
*/
#define CLR_XARGS(x) \
((x)[0] = (x)[1] = (x)[2] = (x)[3] = 0)
#define GET_XARGS_NEGO_DSET(x, d) \
((d)[0] = (x)[1], (d)[1] = (x)[2], (d)[2] = (x)[3])
#define SET_XARGS_NEGO_DSET(x, d) \
((x)[1] = (uint_t)(d)[0], \
#define GET_XARGS_CFG_PHASE(x) ((int)(x)[0])
/*
* ---------------------------------------------------------------------
*/
/*
* Device instance to SIP (IDN instance pointer).
*/
#ifdef DEBUG
#define IDN_INST2SIP(i) \
idn_i2s_table[i])
#else /* DEBUG */
#endif /* DEBUG */
#define IDN_SET_INST2SIP(i, s) \
{ \
idn_i2s_table[i] = (s); \
}
((int)(n)) : IDN_NIL_DOMID)
#ifdef DEBUG
#else
/*
* The following values can be returned from IDNDL_ETHER2DOMAIN:
* IDN_NIL_DOMID
* Ether address is broadcast (0xff) or domain doesn't exist.
* domid Domain id with drwlock(reader) held.
*/
#endif /* DEBUG */
#ifdef DEBUG
#else /* DEBUG */
KM_SLEEP))
#endif /* DEBUG */
extern int idn_debug;
extern idn_global_t idn;
extern idn_domain_t idn_domain[];
extern struct idn *idn_i2s_table[];
extern int idn_history;
extern struct idn_history idnhlog;
extern int idn_smr_size;
extern int idn_nwr_size;
extern int idn_protocol_nservers;
extern int idn_awolmsg_interval;
extern int idn_smr_bufsize;
extern int idn_slab_bufcount;
extern int idn_slab_prealloc;
extern int idn_slab_mintotal;
extern int idn_window_max;
extern int idn_window_incr;
extern int idn_reclaim_min;
extern int idn_reclaim_max;
extern int idn_mbox_per_net;
extern int idn_max_nets;
extern int idn_netsvr_spin_count;
extern int idn_netsvr_wait_min;
extern int idn_netsvr_wait_max;
extern int idn_netsvr_wait_shift;
extern int idn_checksum;
extern int idn_msgwait_nego;
extern int idn_msgwait_cfg;
extern int idn_msgwait_con;
extern int idn_msgwait_fin;
extern int idn_msgwait_cmd;
extern int idn_msgwait_data;
extern int idn_retryfreq_nego;
extern int idn_retryfreq_con;
extern int idn_retryfreq_fin;
extern int idn_window_emax; /* calculated */
extern int idn_slab_maxperdomain; /* calculated */
/*
* ---------------------------------------------------------------------
* ---------------------------------------------------------------------
*/
extern void idn_close_domain(int domid);
extern idn_timer_t *idn_timer_alloc();
int disconnect);
extern void idn_dopcache_init();
extern void idn_dopcache_deinit();
idnsb_error_t *sep);
idnsb_error_t *sep);
extern void idn_deinit_op(void *cookie);
int wait_timeout);
#ifdef DEBUG
#endif /* DEBUG */
/*
* ---------------------------------------------------------------------
* ---------------------------------------------------------------------
*/
extern void idn_assign_cookie(int domid);
idnsb_error_t *sep);
idnsb_error_t *sep);
extern void idn_clear_awol(int domid);
extern int idn_protocol_init(int nservers);
extern void idn_protocol_deinit();
extern void idn_timer_expired(void *arg);
extern int idn_open_channel(int channel);
extern int idn_chanservers_init();
extern void idn_chanservers_deinit();
extern void idn_xmit_monitor_kickoff(int chan_wanted);
/*
* ---------------------------------------------------------------------
* ---------------------------------------------------------------------
*/
extern void idnxf_flushall_ecache();
/*
* ---------------------------------------------------------------------
* io/idn_dlpi.c
* ---------------------------------------------------------------------
*/
extern void idndl_dodetach(struct idnstr *);
struct ether_addr *eap);
extern void idndl_dlpi_init();
struct ether_addr *);
struct ether_addr *);
extern void idndl_wenable(struct idn *);
/*
* ---------------------------------------------------------------------
* ---------------------------------------------------------------------
*/
/*
* ---------------------------------------------------------------------
*/
extern void idn_smrsize_init();
extern void idn_init_autolink();
extern void idn_deinit_autolink();
extern void idn_dmv_handler(void *arg);
extern int idnxf_send_mondo(int upaid);
extern clock_t idn_msg_waittime[];
extern clock_t idn_msg_retrytime[];
#endif /* !_ASM */
#endif /* _KERNEL */
#ifndef _ASM
/*
* ---------------------------------------------------------------------
*/
/*
* ---------------------------------------------------------------------
*/
/*
* IOCTL Interface
*
* Commands must stay in the range (1 - 4096) since only 12 bits
* are allotted.
*/
((op) == DL_IOC_HDR_INFO))
VALID_NDOP(op) || \
typedef union idnop {
struct {
} link;
struct {
} unlink;
struct {
} ping;
struct {
} rwmem;
} idnop_t;
#ifdef _KERNEL
/*
* ndd support for IDN tunables.
*/
typedef struct idnparam {
char *sp_name;
} idnparam_t;
extern idnparam_t idn_param_arr[];
#ifdef IDN_PERF
#define _LP 0
#endif /* IDN_PERF */
/*
* =====================================================================
*/
/*
* Some junk to pretty print board lists and cpu lists in
* digit cpus separated by a command and single space. (Board list
* is similar, but only 16 entries possible.
*/
/*
* These are declared in idn.c.
*/
extern const char *idnds_str[];
extern const char *idnxs_str[];
extern const char *idngs_str[];
extern const char *idncmd_str[];
extern const char *idncon_str[];
extern const char *idnfin_str[];
extern const char *idnfinarg_str[];
extern const char *idnfinopt_str[];
extern const char *idnreg_str[];
extern const char *idnnack_str[];
extern const char *idnop_str[];
extern const char *idnsync_str[];
extern const char *chanop_str[];
extern const char *chanaction_str[];
extern const char *inum_str[];
extern const int inum_bump;
extern const int inum_max;
extern const int acknack_shift;
extern const char *timer_str[];
extern const char *res_str[];
#endif /* _KERNEL */
#endif /* !_ASM */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_IDN_H */