/**
 * @file ix1a_shm.h
 *
 * IX1a-SharedMemory - Shared memory layout and access functions.
 *
 * Copyright: 2004 Thomas Wintergerst. All rights reserved.
 *
 * $FreeBSD$
 * $Id: ix1a_shm.h,v 1.1.2.1 2006/02/28 21:35:24 thomas Exp $
 * $Project     CAPI for BSD $
 * $Target      ix1a - CAPI manager driver for IX1 active ISDN controllers $
 * @date        11.07.2004
 * @author      "Thomas Wintergerst" <twinterg@gmx.de>
 * <p>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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.
 *
 * </p>
 */

#ifndef __IX1A_SHM_H
#define __IX1A_SHM_H





/* === Public declarations =============================================== */





/** @name Shared memory layout for the download phase */
/** @{ */

/** Shared memory offset of the boot command byte for Basic and Octo boards. */
#define IX1A_SHM_OFS_BOOT_COMMAND_BYTE_BASIC    0xF800

/** Shared memory offset of the boot status byte for Basic and Octo boards. */
#define IX1A_SHM_OFS_BOOT_STATUS_BYTE_BASIC     0xFC00

/**
 * Shared memory offset of the boot command byte for Primary and Multimodem
 * boards.
 */
#define IX1A_SHM_OFS_BOOT_COMMAND_BYTE_PRIM     0x7C00

/**
 * Shared memory offset of the boot status byte for Primary and Multimodem
 * boards.
 */
#define IX1A_SHM_OFS_BOOT_STATUS_BYTE_PRIM      0x7E00

/**
 * Shared memory offset for the adapter parameter after firmware download.
 *
 * @note For Primary PCI boards the offset for the CAPI shared memory base
 *       address must be added.
 */
#define IX1A_SHM_OFS_ADAPTER_PARAMS             0x0080

/** Magic string to introduce line configuration parameters on startup. */
#define IX1A_SHM_ADAPTER_PARAMS_MAGIC_STRING    "ITK__SM_PARAM"

/** @} */



/** @name Shared memory layout for Basic / Octo / Multimodem during operation */
/** @{ */

/** Shared memory offset for the board state byte. */
#define IX1A_SHM_OFS_CAPI_BOARD_STATE           0x0000

/** Shared memory offset for the board heartbeat (watchdog, word). */
#define IX1A_SHM_OFS_CAPI_BEAT_BOARD            0x0006

/**
 * Shared memory offset for the heartbeat response to the board (watchdog,
 * word).
 */
#define IX1A_SHM_OFS_CAPI_BEAT_PC               0x0008

/** Shared memory offset for XON/XOFF flow control (?, word, unused). */
#define IX1A_SHM_OFS_CAPI_XON_XOFF              0x000E

/** Shared memory offset for the number of data blocks (?, word, unused). */
#define IX1A_SHM_OFS_CAPI_NUM_DATA_BLOCKS       0x0010

/**
 * Shared memory offset for CAPI message raster (maximum message length, word).
 *
 * This value does not include the F/V flag field (word).
 */
#define IX1A_SHM_OFS_CAPI_MAX_MSG_LEN           0x0012

/** Shared memory offset for the maximum number of PLCI/NCCIs (word). */
#define IX1A_SHM_OFS_CAPI_MAX_NUM_PLNC          0x0014

/**
 * Shared memory offset for highest application id that can be registered
 * (word).
 */
#define IX1A_SHM_OFS_CAPI_MAX_APPL_ID           0x0016

/**
 * Shared memory offset for the first address of a CAPI message to send to the
 * board (word).
 */
#define IX1A_SHM_OFS_CAPI_FIRST_WRITE_MSG       0x0018

/**
 * Shared memory offset for the last address of a CAPI message to send to the
 * board (word).
 */
#define IX1A_SHM_OFS_CAPI_LAST_WRITE_MSG        0x001A

/**
 * Shared memory offset for the first address of a CAPI message to receive from
 * the board (word).
 */
#define IX1A_SHM_OFS_CAPI_FIRST_READ_MSG        0x001C

/**
 * Shared memory offset for the last address of a CAPI message to receive from
 * the board (word).
 */
#define IX1A_SHM_OFS_CAPI_LAST_READ_MSG         0x001E

/**
 * Shared memory offset for the manufacturer string (62 bytes, maybe no
 * terminating null byte).
 */
#define IX1A_SHM_OFS_CAPI_MANUFACTURER          0x0020

/** The number of bytes available for the manufacturer string. */
#define IX1A_SHM_SIZE_CAPI_MANUFACTURER         62

/** Shared memory offset for the board type (byte). */
#define IX1A_SHM_OFS_CAPI_BOARD_TYPE            0x005E

/** Shared memory offset for the version specification (64 bytes, ?). */
#define IX1A_SHM_OFS_CAPI_VERSION               0x0060

/** The number of bytes available for the version specification. */
#define IX1A_SHM_SIZE_CAPI_VERSION              64

/**
 * Shared memory offset for the board serial number (10 characters, maybe no
 * terminating null byte).
 */
#define IX1A_SHM_OFS_CAPI_SERIAL_NUMBER         0x00A0

/** The number of bytes available for the serial number string. */
#define IX1A_SHM_SIZE_CAPI_SERIAL_NUMBER        10

/**
 * Shared memory offset for the CAPI profile starting at the number of
 * B-channels (18 bytes, must be filled up with null bytes to full 64 byte
 * CAPI profile buffer size).
 */
#define IX1A_SHM_OFS_CAPI_PROFILE               0x00B8

/** The number of bytes available for the CAPI profile buffer. */
#define IX1A_SHM_SIZE_CAPI_PROFILE              18

/** Shared memory offset for the NCCI flow control table. */
#define IX1A_SHM_OFS_CAPI_NCCI_FC               0x00E0

/** @} */



/** @name Shared memory layout for Primary PCI during operation */
/** @{ */

/**
 * The base offset for the CAPI shared memory, must be added to all offset
 * values.
 */
#define IX1A_SHM_OFS_CAPI_SHM_PRIM              0x00011000

/** Shared memory offset for the board state byte. */
#define IX1A_SHM_OFS_CAPIPRIM_BOARD_STATE       0

/** Shared memory offset for the board heartbeat (watchdog, dword). */
#define IX1A_SHM_OFS_CAPIPRIM_BEAT_BOARD        0x0008

/**
 * Shared memory offset for the heartbeat response to the board (watchdog,
 * dword).
 */
#define IX1A_SHM_OFS_CAPIPRIM_BEAT_PC           0x000C

/** Shared memory offset for the maximum number of PLCI/NCCIs (byte). */
#define IX1A_SHM_OFS_CAPIPRIM_MAX_NUM_PLNC      0x0018

/**
 * Shared memory offset for the highest application id that can be registered
 * (byte).
 */
#define IX1A_SHM_OFS_CAPIPRIM_MAX_APPL_ID       0x0019

/**
 * Shared memory offset for CAPI message raster (maximum message length,
 * dword).
 *
 * This value does not include the F/V flag field.
 */
#define IX1A_SHM_OFS_CAPIPRIM_MAX_MSG_LEN       0x001C

/**
 * Shared memory offset for the first address of a CAPI message to send to the
 * board (dword).
 */
#define IX1A_SHM_OFS_CAPIPRIM_FIRST_WRITE_MSG   0x0020

/**
 * Shared memory offset for the last address of a CAPI message to send to the
 * board (dword).
 */
#define IX1A_SHM_OFS_CAPIPRIM_LAST_WRITE_MSG    0x0024

/**
 * Shared memory offset for the first address of a CAPI message to receive from
 * the board (dword).
 */
#define IX1A_SHM_OFS_CAPIPRIM_FIRST_READ_MSG    0x0028

/**
 * Shared memory offset for the last address of a CAPI message to receive from
 * the board (dword).
 */
#define IX1A_SHM_OFS_CAPIPRIM_LAST_READ_MSG     0x002C

/**
 * Shared memory offset for the address of the NCCI flow control table (dword).
 */
#define IX1A_SHM_OFS_CAPIPRIM_NCCI_FC           0x0030

/**
 * Shared memory offset for the address of the application status table
 * (dword).
 */
#define IX1A_SHM_OFS_CAPIPRIM_APPL_STATE_TABLE  0x0034

/** Shared memory offset for the address of the profile tables (dword). */
#define IX1A_SHM_OFS_CAPIPRIM_PROFILE_TABLE     0x0038

/** Shared memory offset for the manufacturer string (62 bytes). */
#define IX1A_SHM_OFS_CAPIPRIM_MANUFACTURER      0x003C

/** Shared memory offset for the board type (byte). */
#define IX1A_SHM_OFS_CAPIPRIM_BOARD_TYPE        0x007A

/** Shared memory offset for the version specification (64 bytes). */
#define IX1A_SHM_OFS_CAPIPRIM_VERSION           0x007C

/** Shared memory offset for the board serial number (32 bytes). */
#define IX1A_SHM_OFS_CAPIPRIM_SERIAL_NUMBER     0x00BC

/**
 * Shared memory offset for the CAPI profile starting beyond the number of
 * B-channels.
 */
#define IX1A_SHM_OFS_CAPIPRIM_PROFILE           0x0098

/** @} */



/* --- Other definitions --- */

/** Test word to write to low shared memory address for shared memory test. */
#define IX1A_SHM_TEST_WORD_LOW  0x5A12

/** Test word to write to high shared memory address for shared memory test. */
#define IX1A_SHM_TEST_WORD_HIGH 0xA534



/** @name Boot command codes to the board during download operations */
/** @{ */

/** An EEPROM operation shall be started. */
#define IX1A_BOOT_COMMAND_EEPROM_READY          0x01

/** A parameter block is ready to be accepted by the board. */
#define IX1A_BOOT_COMMAND_PARAM_READY           0x03

/** The next firmware block is ready to be accepted by the board. */
#define IX1A_BOOT_COMMAND_BLOCK_2LR_READY       0x05

/** Start the firmware downloaded just before. */
#define IX1A_BOOT_COMMAND_LR_RUN                0x10

/** @} */



/** @name Boot status codes from the board during download operations */
/** @{ */

/** Boot code is working. */
#define IX1A_BOOT_STATUS_BOOT_CODE_OK           0x00

/** EEPROM operation is complete. */
#define IX1A_BOOT_STATUS_EEPROM_DONE            0x02

/** Parameter block accepted. */
#define IX1A_BOOT_STATUS_PARAM_DONE             0x04

/** A block from the board to the host is available. */
#define IX1A_BOOT_STATUS_BLOCK_2PC_READY        0x07

/** A block from the host to the board was accepted. */
#define IX1A_BOOT_STATUS_BLOCK_2LR_DONE         0x08

/** The last block of the firmware doenload was accepted. */
#define IX1A_BOOT_STATUS_TRANSMIT_OK            0x09

/** The boot code has failed to start. */
#define IX1A_BOOT_STATUS_BOOT_CODE_FAILED       0x80

/** EEPROM operation failed. */
#define IX1A_BOOT_STATUS_EEPROM_FAILED          0x81

/** Board failed to accept parameter block. */
#define IX1A_BOOT_STATUS_PARAM_FAILED           0x83

/** A firmware download block could not be accepted. */
#define IX1A_BOOT_STATUS_TRANSMIT_FAILED        0x89

/** The hardware type and the firmware do not match. */
#define IX1A_BOOT_STATUS_WRONG_TARGET_HW        0x8A

/** The board has not enough memory for the firmware. */
#define IX1A_BOOT_STATUS_INSUFFICIENT_MEMORY    0x8B

/** @} */



/** Magic string to introduce adapter parameters before firmware startup. */
#define IX1A_FW_ADAPTER_PARAMS_MAGIC_STRING     "ITK__SM_PARAM"

/** Magic string delivered by the board on successful firmware startup. */
#define IX1A_FW_READY_STRING            "ITK "





/* === Prototypes of interface functions ================================= */





/**
 * Setup shared memory pointers after successful firmware download for all
 * boards but the Primary PCI.
 *
 * @param pSc                   I/O: The softc structure for the board.
 *
 * @retval 0                    Setup was successful, board is ready for CAPI
 *                              message exchange, CAPI profile data set.
 * @retval Else                 Setup failed, board is not ready for CAPI
 *                              message exchange, CAPI profile data is in
 *                              undefined state. The result is an errno value.
 */
extern int ix1ashm_firmware_started
   (Ix1aSc_t *pSc);

/**
 * Setup shared memory pointers after successful firmware download for the
 * Primary PCI.
 *
 * @param pSc                   I/O: The softc structure for the board.
 *
 * @retval 0                    Setup was successful, board is ready for CAPI
 *                              message exchange, CAPI profile data set.
 * @retval Else                 Setup failed, board is not ready for CAPI
 *                              message exchange, CAPI profile data is in
 *                              undefined state. The result is an errno value.
 */
extern int ix1ashm_firmware_started_ppci
   (Ix1aSc_t *pSc);

/**
 * Send a CAPI-Application-Register message to the board.
 *
 * @param pSc                   I/O: The softc structure for the board.
 * @param uMaxLogicalConnections
 *                              I: The maximum number of logical connections
 *                                 the application wishes to handle.
 * @param uMaxBDataBlocks       I: The maximum number of unresponded incoming
 *                                 data blocks to be queued for the
 *                                 application.
 * @param uMaxBDataLen          I: The maximum length of a sent or received
 *                                 data block for a connection.
 * @param puApplID              I/O: On function entrance this parameter
 *                                 contains the CAPI manager assigned unique
 *                                 application id. On successful return the
 *                                 parameter value will be set to the board
 *                                 specific application id.
 *
 * @retval CAPI_OK              The CAPI application registration was
 *                              successful.
 * @retval Else                 CAPI application registration was unsuccessful.
 */
extern unsigned ix1ashm_app_register
   (Ix1aSc_t *pSc,
    unsigned  uMaxLogicalConnections,
    unsigned  uMaxBDataBlocks,
    unsigned  uMaxBDataLen,
    unsigned *puApplID);

/**
 * Send a CAPI-Application-Release message to the board.
 *
 * @param pSc                   I/O: The softc structure for the board.
 * @param uCtlrApplID           I: The board specific application id for the
 *                                 release operation.
 *
 * @retval CAPI_OK              The CAPI release operation was successful.
 * @retval Else                 CAPI application release was unsuccessful.
 */
extern unsigned ix1ashm_app_release
   (Ix1aSc_t *pSc,
    unsigned  uCtlrApplID);

/**
 * Send a general CAPI message to the board.
 *
 * @param pSc                   I/O: The softc structure for the board.
 * @param uCtlrApplID           I: The board specific application ID for the
 *                                 message.
 * @param pmbMsg                I/O: The mbuf with the message to send. On
 *                                 success the mbuf is released before return,
 *                                 on failure the parent is still responsible
 *                                 for the mbuf.
 *
 * @retval CAPI_OK              The message was successfully sent to the
 *                              board, the mbuf is released.
 * @retval Else                 The message could not be sent to the board,
 *                              the mbuf is still allocated.
 */
extern unsigned ix1ashm_put_message
   (Ix1aSc_t    *pSc,
    unsigned     uCtlrApplID,
    struct mbuf *pmbMsg);

/**
 * Read all available CAPI messages from the shared memory.
 *
 * This function is called within interrupt context to get all pending CAPI
 * messages from a board. The call will only be made in READY state of above.
 *
 * The messages are simply forwarded to the kernel CAPI manager.
 *
 * @param pSc                   I/O: The softc structure for the board to read
 *                                 from.
 *
 * @return Nothing.
 */
extern void ix1ashm_read_capi_messages
   (Ix1aSc_t *pSc);

/**
 * Board type independent function to set the board's current offset pointer
 * within the shared memory.
 *
 * @param pSc                   I/O: The softc structure for the board.
 * @param uAddr                 I: The shared memory offset to set.
 *
 * @retval 0                    The offset pointer was read successfully.
 * @retval Else                 Failure, result is an errno value.
 */
extern int ix1ashm_set_offset
   (Ix1aSc_t *pSc,
    unsigned  uAddr);

/**
 * Board type independent function to read a word from a board's shared memory.
 *
 * @param pSc                   I/O: The softc structure for the board.
 * @param uAddr                 I: The shared memory address to read from.
 * @param puValue               O: On successful return the word read is
 *                                 delivered as an unsigned integer.
 *
 * @retval 0                    The data word was read successfully.
 * @retval Else                 Failure, result is an errno value.
 */
extern int ix1ashm_read_word
   (Ix1aSc_t *pSc,
    unsigned  uAddr,
    unsigned *puValue);

/**
 * Board type independent function to read a block from a board's shared
 * memory.
 *
 * @param pSc                   I/O: The softc structure for the board.
 * @param uAddr                 I: The shared memory address to read from.
 * @param pbData                I: The address for returning the data read.
 * @param nLenData              I: The length in bytes of the data block to
 *                                 read.
 *
 * @retval 0                    The data block was read successfully.
 * @retval Else                 Failure, result is an errno value.
 */
extern int ix1ashm_read_block_16
   (Ix1aSc_t *pSc,
    unsigned  uAddr,
    u_int8_t *pbData,
    size_t    nLenData);

/**
 * Board type independent function to send a word to a board's shared memory.
 *
 * @param pSc                   I/O: The softc structure for the board.
 * @param uAddr                 I: The shared memory address to write to.
 * @param uValue                I: The word to write as an unsigned integer.
 *
 * @retval 0                    The data word was written successfully.
 * @retval Else                 Failure, result is an errno value.
 */
extern int ix1ashm_write_word
   (Ix1aSc_t *pSc,
    unsigned  uAddr,
    unsigned  uValue);

/**
 * Board type independent function to send a block to a board's shared memory.
 *
 * @param pSc                   I/O: The softc structure for the board.
 * @param uAddr                 I: The shared memory address to write to.
 * @param pbData                I: The address of the data block to write.
 * @param nLenData              I: The length in bytes of the data block to
 *                                 write.
 *
 * @retval 0                    The data block was written successfully.
 * @retval Else                 Failure, result is an errno value.
 */
extern int ix1ashm_write_block_16
   (Ix1aSc_t       *pSc,
    unsigned        uAddr,
    const u_int8_t *pbData,
    size_t          nLenData);

/**
 * Board type independent function to compare a block to a board's shared
 * memory content.
 *
 * @param pSc                   I/O: The softc structure for the board.
 * @param uAddr                 I: The shared memory address to write to.
 * @param pbData                I: The address of the data block to write.
 * @param nLenData              I: The length in bytes of the data block to
 *                                 write.
 * @param pfResult              O: The compare result (0 - failure, !0 -
 *                                 success).
 *
 * @retval 0                    The data block was compared successfully,
 *                              compare result is stored into *pfResult.
 * @retval Else                 Failure, result is an errno value.
 */
extern int ix1ashm_compare_block_16
   (Ix1aSc_t       *pSc,
    unsigned        uAddr,
    const u_int8_t *pbData,
    size_t          nLenData,
    int            *pfResult);





#endif /* __IX1A_SHM_H */
