root/usr/src/uts/sun4u/sys/rmc_comm_dp.h
/*
 * 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 2005 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _SYS_RMC_COMM_DP_H
#define _SYS_RMC_COMM_DP_H

#pragma ident   "%Z%%M% %I%     %E% SMI"


#include <sys/rmc_comm_lproto.h>

#ifdef  __cplusplus
extern "C" {
#endif

/*
 * buffer size (used for tx/rx operations)
 */
#define DP_BUFFER_SIZE  2048

/*
 * Number of tx/rx buffers. there are 2 (static) buffers: receive buffer and
 * send buffer. These buffers are basically used by the protocol to packetize
 * a message to be sent OR to collect data received from the serial device.
 * Currently, we just need two for send and receive operations respectively
 * since there is only one request/response session per time (i.e. a new
 * session is not started until the previous one has not finished)
 */
#define DP_BUFFER_COUNT         2

#define DP_TX_BUFFER            0
#define DP_RX_BUFFER            1

/*
 * Tx/Rx buffers.
 */
typedef struct dp_buffer {
        boolean_t in_use;
        uint8_t buf[DP_BUFFER_SIZE];
} dp_buffer_t;

/*
 * Data structure used to collect data from the serial device and to
 * assemble protocol packets
 */

/*
 * The possible states the message receiver can be in:
 */
#define WAITING_FOR_SYNC        0
#define WAITING_FOR_SYNC_ESC    1
#define WAITING_FOR_HDR         2
#define RECEIVING_HDR           3
#define RECEIVING_HDR_ESC       4
#define RECEIVING_BODY          5
#define RECEIVING_BODY_ESC      6
#define N_RX_STATES             7

/*
 * This is the structure passed between the message receiver state routines.
 * It keeps track of all the state of a message that is in the process of
 * being received.
 */
typedef struct dp_packet {
        uint8_t rx_state;       /* Current state of receive engine. */
        uint8_t *inbuf;         /* Input characters to be processed. */
        int16_t inbuflen;       /* Number of input characters. */
        uint8_t *buf;           /* Buffer used to receive current message. */
        int16_t bufpos;         /* Position in buffer. */
        int16_t full_length;    /* Full length of this message. */
} dp_packet_t;


/*
 * message data structure used to send/receive data
 */
typedef struct dp_message {

        uint8_t   msg_type;     /* message type */
        uint8_t  *msg_buf;      /* message buffer */
        uint16_t  msg_bufsiz;   /* size of the buffer */
        int16_t   msg_msglen;   /* message length */

} dp_message_t;

/*
 * structure used by the protocol to send (and, eventually re-send...)
 * messages to the remote side. It keeps the status of the data transfer
 * (message sent, reply received, etc.). It is also used to match
 * request/response
 */

typedef struct dp_req_resp {

        uint8_t         flags;          /* status of the data transfer */

#define MSG_ERROR       0x01
#define MSG_SENT        0x02
#define MSG_ACKED       0x04
#define MSG_REPLY_RXED  0x08
#define MSG_NAKED       0x10
#define MSG_RESET       0x20
#define MSG_SENT_BP     0x40
#define MSG_RXED_BP     0x80

        int             error_status;   /* error code */

        uint8_t         retries_left;   /* number of retries left */

        kcondvar_t      cv_wait_reply[1];       /* cv variable used to signal */
                                                /* threads waiting for a */
                                                /* reply */

        dp_message_t    request;        /* request buffer */

        dp_message_t    response;       /* response buffer */

} dp_req_resp_t;


/*
 * interrupt handler prototype (asynchronous messages notification)
 */
typedef uint_t (*rmc_comm_intrfunc_t)(caddr_t);

/*
 * data structure used to deal with asynchronous notification (requests)
 * from the remote side
 */
typedef struct dp_msg_intr {

        rmc_comm_intrfunc_t     intr_handler;   /* interrupt handler */

        ddi_softintr_t          intr_id;        /* soft intr. id */

        uint8_t                 intr_msg_type;  /* message type */

        caddr_t                 intr_arg;       /* message buffer containing */
                                                /* the expected message type */

        kmutex_t                *intr_lock;     /* for state flag below */
        uint_t                  *intr_state;    /* interrupt handler state */

} dp_msg_intr_t;

/*
 * data protocol structure
 */

typedef struct rmc_comm_dp_state {

        /*
         * data protcol mutex (initialized using <dp_iblk>)
         */
        kmutex_t                dp_mutex[1];
        ddi_iblock_cookie_t     dp_iblk;

        boolean_t       data_link_ok;   /* tells whether the data link has */
                                        /* has been established */

        boolean_t       pending_request;        /* tells if a request is */
                                                /* already being processed */

        uint8_t         last_tx_seqid;  /* sequence ID of last message */
                                        /* transmitted */
        uint8_t         last_rx_seqid;  /* sequence ID of last message */
                                        /* received */
        uint8_t         last_rx_ack;    /* last message acknowledged by */
                                        /* remote side */

        timeout_id_t    timer_link_setup;       /* timer used to set up the */
                                                /* data link at regular */
                                                /* intervals when the link is */
                                                /* down */
        timeout_id_t    timer_delay_ack;        /* timer used to wait a 'bit' */
                                                /* before acknowledging a */
                                                /* received message. In the */
                                                /* meantime a request can be */
                                                /* sent from this side and, */
                                                /* hence, acnowledge that */
                                                /* message */

        kcondvar_t      cv_ok_to_send[1];       /* cv variable used to wait */
                                                /* until it is possible to */
                                                /* send the request (no */
                                                /* pending request */

        dp_packet_t     dp_packet;              /* used to assemble protocol */
                                                /* packet from data received */
                                                /* from the serial device */

        dp_req_resp_t   req_resp;               /* request/response data */
                                                /* structure */

        dp_msg_intr_t   msg_intr;               /* messages for which layered */
                                                /* drivers have registered */
                                                /* for an async notification */
                                                /* (soft.intr.) */

        dp_buffer_t     dp_buffers[DP_BUFFER_COUNT]; /* protocol buffer  */
                                                /* pool used for    */
                                                /* tx/rx operations */

        /* statistical information */

        uint16_t        reset_cnt;
        uint16_t        nak_cnt;
        uint16_t        start_cnt;
        uint16_t        stack_cnt;
        uint16_t        retries_cnt;
        uint16_t        crcerr_cnt;

} rmc_comm_dp_state_t;

#ifdef  __cplusplus
}
#endif

#endif  /* _SYS_RMC_COMM_DP_H */