/**
 * @file avmaic_global.h
 *
 * AvmAic-Global - Common definitions for all AVM active controllers.
 *
 * Copyright: 2000-2003 Thomas Wintergerst. All rights reserved.
 *
 * $FreeBSD$
 * $Id: avmaic_var.h,v 1.1.2.1 2006/02/28 21:35:07 thomas Exp $
 * Project  CAPI for BSD
 * Target   avmaic - CAPI manager driver for AVM active ISDN controllers
 * @date    01.01.2000
 * @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 __AVMAIC_GLOBAL_H
#define __AVMAIC_GLOBAL_H

#include <sys/types.h>          /* size_t */
#include <sys/mbuf.h>
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/condvar.h>
#include <sys/socket.h>         /* struct sockaddr for net/if.h */
#include <net/if.h>             /* struct if_queue */
#include <machine/bus.h>
#include <c4b/kcapimgr/capi_drv.h>

#include <opt_avmaic.h>





/* === public declarations =============================================== */





/* --- several constants --- */

/** The name of the avmaic devices and the device class. */
#define AVMAIC_DEVICE_CLASS_NAME        "avmaic"

/** The maximum number of ports per card (a C4 owns 4 ports). */
#define AVMAIC_MAX_PORTS                4

/** The maximum number of simultaneously registered applications. */
#ifndef AVMAIC_MAX_APPLICATIONS
#define AVMAIC_MAX_APPLICATIONS         30
#endif /* AVMAIC_MAX_APPLICATIONS */

/** The maximum number of B3 connections per physical connection (B-channel). */
#ifndef AVMAIC_MAX_NCCI_PER_CHANNEL
#define AVMAIC_MAX_NCCI_PER_CHANNEL     4
#endif /* AVMAIC_MAX_NCCI_PER_CHANNEL */

/** The size of the communication data buffers. */
#define AVMAIC_MSGBUF_SIZE              (sizeof (CAPIMsg_t) + 2048)

/** The maunfacturer string for all AVM active ISDN controllers. */
#define AVMAIC_MANUFACTURER_NAME        "AVM Berlin GmbH"

/** The version number of this device driver, major part. */
#define AVMAIC_DRIVER_VERSION_MAJOR     2

/** The version number of this device driver, minor part. */
#define AVMAIC_DRIVER_VERSION_MINOR     0

/** The name for the logging level as a tunable kernel parameter. */
#define AVMAIC_TUNABLE_LOGLEVEL \
   "capi." AVMAIC_DEVICE_CLASS_NAME ".loglevel"

/**
 * The name for the maximum number of CAPI applications as a tunable kernel
 * parameter.
 */
#define AVMAIC_TUNABLE_MAX_APPLICATIONS \
   "capi." AVMAIC_DEVICE_CLASS_NAME ".max_applications"

/**
 * The name for the maximum number of B3 connections per B-channel as a tunable
 * kernel parameter.
 */
#define AVMAIC_TUNABLE_MAX_NCCI_PER_CHANNEL \
   "capi." AVMAIC_DEVICE_CLASS_NAME ".max_ncci_per_channel"

/**
 * A debugging flag to turn off the support for the DMA operation of a B1 PCI v4.
 *
 * This is an integer variable. A value of zero retains normal behaviour, a
 * value not equal to zero disables DMA support for the B1 PCI v4.
 */
#define AVMAIC_TUNABLE_NO_B1_PCI_V4_SUPPORT \
   "capi." AVMAIC_DEVICE_CLASS_NAME ".no_b1_pci_v4_support"



/* --- supported types of AVM active ISDN controllers --- */

/**
 * Identifiers for the boards supported.
 *
 * @attention This enumeration is used to index an array of strings in module
 *            avmaic_misc. If this enumeration is modified this names array
 *            must be changed accordingly!
 */
typedef enum
{
   AVMAIC_CARD_TYPE_UNKNOWN,    /* card type not known */
   AVMAIC_CARD_TYPE_B1_ISA,     /* AVM B1 for isa bus */
   AVMAIC_CARD_TYPE_B1_PCI_V3,  /* AVM B1 PCI v3, port i/o */
   AVMAIC_CARD_TYPE_B1_PCI_V4,  /* AVM B1 PCI v4, memory mapped i/o */
   AVMAIC_CARD_TYPE_C1,         /* maybe AVM will create a C1 controller? */
   AVMAIC_CARD_TYPE_C2,         /* AVM C2 (owns 2 ISDN ports) */
   AVMAIC_CARD_TYPE_C4,         /* AVM C4 (owns 4 ISDN ports) */
   AVMAIC_CARD_TYPE_T1_ISA,     /* AVM T1 for isa bus */
   AVMAIC_CARD_TYPE_T1_PCI,     /* AVM T1 for pci bus */
   AVMAIC_CARD_TYPE_B1_PCMCIA,  /* AVM B1 PCMCIA */
   AVMAIC_CARD_TYPE_M1,         /* AVM M1 (?) */
   AVMAIC_CARD_TYPE_M2          /* AVM M2 (?) */
} AvmAicCardType_t;



/* --- possible states for an AVM active ISDN controller --- */

/**
 * The possible states for a board .
 *
 * @note The order is important. "Ready" must be the lowest state number
 *       defining a working controller. States below it are regarded as
 *       "controller not working".
 */
typedef enum
{
   AVMAIC_STATE_DOWN = 0,       /**< Controller is down, i.e. not functional. */
   AVMAIC_STATE_INITIALIZING,   /**< Controller is beeing initialized. */
   AVMAIC_STATE_READY,          /** Controller is ready to perform requests. */
   AVMAIC_STATE_BUSY            /** Controller is currently executing a req. */
} AvmAicState_t;



/* --- D-channel protocols supported by AVM active ISDN controllers --- */

/* Note: Definitions from AVM */

typedef enum
{
   AVMAIC_DCHN_PROT_NONE = 0,
   AVMAIC_DCHN_PROT_DSS1,
   AVMAIC_DCHN_PROT_D64S,
   AVMAIC_DCHN_PROT_D64S2,
   AVMAIC_DCHN_PROT_D64SD,
   AVMAIC_DCHN_PROT_DS01,
   AVMAIC_DCHN_PROT_DS02,
   AVMAIC_DCHN_PROT_CT1,
   AVMAIC_DCHN_PROT_VN3,
   AVMAIC_DCHN_PROT_AUSTEL,
   AVMAIC_DCHN_PROT_5ESS,       /* need SPID, SPID2, DN, DN2 */
   AVMAIC_DCHN_PROT_NI1,        /* need SPID, SPID2, DN, DN2 */
   AVMAIC_DCHN_PROT_DSS1MOBIL,
   AVMAIC_DCHN_PROT_1TR6MOBIL,
   AVMAIC_DCHN_PROT_GSM,
   AVMAIC_DCHN_PROT_1TR6,
   AVMAIC_DCHN_PROT_T1
} AvmAicDChnProtocol_t;



/* --- Possible line types --- */

typedef enum
{
   AVMAIC_LINE_TYPE_MP,         /* multipoint line, for terminal devices */
   AVMAIC_LINE_TYPE_P2P         /* point-to-point line, dial-in line */
} AvmAicLineType_t;



/* --- function prototypes for board type specific parts of CAPI calls --- */

struct _avmaic_portdata;
struct _avmaic_sc;

/** Function prototype to perform a CAPI register at a controller. */
typedef unsigned (*AvmAicRegisterFct_t)
   (struct _avmaic_sc       *pSc,
    struct _avmaic_portdata *pPortData,
    unsigned                 uMaxLogicalConnections,
    unsigned                 uMaxBDataBlocks,
    unsigned                 uMaxBDataLen,
    unsigned                 uApplID);

/** Function prototype to perform a CAPI release at a controller. */
typedef unsigned (*AvmAicReleaseFct_t)
   (struct _avmaic_sc       *pSc,
    struct _avmaic_portdata *pPortData,
    unsigned                 uApplID);

/** Function prototype to perform a CAPI put-message at a controller. */
typedef unsigned (*AvmAicPutMessageFct_t)
   (struct _avmaic_sc       *pSc,
    struct _avmaic_portdata *pPortData,
    unsigned                 uApplID,
    struct mbuf             *pmbMsg);

/** Function prototype to perform a controller reset. */
typedef unsigned (*AvmAicResetCtlrFct_t)
   (struct _avmaic_sc   *pSc,
    size_t               nNumDataBlocks,
    CAPICtlrDataBlock_t *pDataBlocks);



/* --- data stored for installed boards --- */

/** Configuration settings for a controller. */
typedef struct
{
   char                 szCardName [32];
   AvmAicDChnProtocol_t dchnProt;
   AvmAicLineType_t     lineType;
   int                  iTei;
} AvmAicCtlrConfig_t;

/** Hardware resource data for the board. */
typedef struct
{
   int                 iIoBase;         /* i/o port number */
   int                 iRidIo;
   struct resource    *pResIo;
   bus_space_tag_t     ioTag;
   bus_space_handle_t  ioHandle;

   int                 iMemBase;        /* i/o memory base address */
   int                 iRidMem;
   struct resource    *pResMem;
   bus_space_tag_t     memTag;
   bus_space_handle_t  memHandle;

   int                 iIrq;            /* assigned irq */
   int                 iRidIrq;
   struct resource    *pResIrq;
   void               *hIrqCookie;      /* needed to setup/teardown the irq */
} AvmAicResourceInfo_t;

/** Data needed to perform DMA operations. */
typedef struct
{
   int            fDmaOk;       /**< Flag for initialised DMA data. */
   bus_dma_tag_t  dmat;         /**< DMA tag. */
   bus_dmamap_t   map;          /**< DMA map. */
   u_int8_t      *pVirtAddr;    /**<
                                 * Virtual address pointer for accessing
                                 * memory.
                                 */
   u_int32_t      ulPhysAddr;   /**<
                                 * Physical address pointer (32bit) for
                                 * addressing the memory by the board.
                                 */
} AvmAicDmaData_t;

/** Data stored for one port of a card (cards may contain more than one port). */
typedef struct _avmaic_portdata
{
   struct _avmaic_sc *pSc;      /**<
                                 * Address of the surrounding softc structure.
                                 */
   unsigned           uPortIdx; /**<
                                 * Index of this port into the port data array
                                 * of the softc structure.
                                 */
   AvmAicState_t      state;    /**<
                                 * Current state of the port (AVMAIC_STATE_*);
                                 * is toggled by the interrupt routine between
                                 * READY and BUSY, when controller sends
                                 * AVMAIC_RECEIVE_START and AVMAIC_RECEIVE_STOP
                                 * respectively.
                                 */
   char               szCtlrPortName [CAPI_CTLR_NAME_LEN];
                                /**<
                                 * Port name for CAPI registration, should
                                 * contain card type, unit number and port
                                 * number, e.g. "AVMC4-1/3".
                                 */
   unsigned           uUniqueCapiCtlrNum;
                                /**<
                                 * CAPI controller number assigned by the CAPI
                                 * manager; if 0 the controller is not
                                 * registered at the CAPI manager.
                                 */
   unsigned           uDrvCapiCtlrNum;
                                /**<
                                 * CAPI controller number used to communicate
                                 * with the controller itself (if not equal to
                                 * uUniqueCapiCtlrNum controller mapping is
                                 * necessary).
                                 */
   size_t             nBChns;   /**< Number of available B-channels. */

   /* data for registering the ISDN port as a controller at the CAPI manager */
   CAPICtlrRegisterParams_t regParams;
   
   /* fields with information about the controller hardware and download
    * software, only valid after download operation
    */
   u_int8_t           acVersionBuf [512];
                                        /* buffer to store the version data */
   size_t             nLenVersion;      /* no. bytes used in acVersionBuf */
   char               szDriverVersion [16];
                                        /* version string for the download
                                         * software
                                         */
   char               szSerialNo [16];  /* serial number of the controller */
   char               szCardType [16];
   char               szHardwareID [16];
   char               acCapability [64];
   size_t             nLenCapability;
   char               szDChnProt [32];
   u_int8_t           abCapiProfile [64];
} AvmAicPortData_t;

/** The device specific softc structure. */
typedef struct _avmaic_sc
{
   int                   iUnit; /**< Unit number for device. */
   AvmAicResourceInfo_t  resInfo;
                                /**<
                                 * Summary of i/o, memory and irq resources for
                                 * the board.
                                 */
   AvmAicCardType_t      cardType;
                                /**< Card type, AVMAIC_CARD_TYPE_*. */
   char                  szCardName [CAPI_CTLR_NAME_LEN];
                                /**<
                                 * Card name for log output, should contain
                                 * card type and unit number, e.g. "AVMB1-1".
                                 */
   char                  szDriverName [CAPI_CTLR_DRIVER_NAME_LEN];
                                /**< Driver name, "avmaic". */
   unsigned int          uT1IsaBoardNo;
                                /**<
                                 * The T1 ISA needs to know which board of a
                                 * maximum of 4 it is (0-3). This value is not
                                 * related to the CAPI or driver controller
                                 * number.
                                 */
   int                   iClass;/**<
                                 * Class from the card, currently only traced
                                 * and used for nothing.
                                 */
   int                   iRevision;
                                /**<
                                 * Revision from the card, currently only
                                 * traced and used for nothing.
                                 */
   AvmAicState_t         state; /**<
                                 * Current state of the controller,
                                 * AVMAIC_STATE_*.
                                 */
   size_t                nPorts;/**<
                                 * Number of (CAPI-)controllers, normally 1,
                                 * but a C4 owns 4.
                                 */
   size_t                nPortsInitialized;
                                /**<
                                 * The number of ports currently initialized;
                                 * this value will grow from 0 to nPorts when
                                 * downloading the controller.
                                 */
   AvmAicPortData_t      aPortData [AVMAIC_MAX_PORTS];
   	                          /**<
                                 * Array of data for the controllers, number of
                                 * used records is in nPorts.
                                 */
   AvmAicDmaData_t       dmaRecv;
                                /**<
                                 * Data to setup DMA input operations for
                                 * boards that use DMA (B1 PCI v4, C2, C4). For
                                 * other boards this data remains uninitialised
                                 * and fDmaOk is 0.
                                 */
   unsigned char        *paucRecvMsgBuf;
                                /**<
                                 * Buffer to receive (CAPI) messages from the
                                 * controller. If the board uses DMA, this
                                 * address is the virtual address pointer from
                                 * the DMA data structure. For other boards
                                 * the memory is allocated by malloc(). So if
                                 * this pointer is non-NULL and dmaRecv.fDmaOk
                                 * is 0, the memory must be release through
                                 * free() when detaching the device.
                                 */
   u_int32_t             ulRecvMsgBufLength;
                                /**<
                                 * The current length of data read into the
                                 * receive buffer (aucRecvMsgBuf).
                                 */
   AvmAicDmaData_t       dmaSend;
                                /**<
                                 * Data to setup DMA output operations for
                                 * boards that use DMA (B1 PCI v4, C2, C4). For
                                 * other boards this data remains uninitialised
                                 * and fDmaOk is 0.
                                 */
   u_int32_t             ulSendMsgBufLength;
                                /**<
                                 * The current length of the data written into
                                 * the send buffer (aucSendMsgBuf) (only used
                                 * for dma and arm based boards).
                                 */
   u_int32_t             ulDmaIcsr;
                                /**<
                                 * For dma based boards this is the current
                                 * content of the INTCSR register of the AMCC.
                                 */
   struct ifqueue        sendQueue;
                                /**<
                                 * For dma or arm based boards this is the
                                 * queue for messages to send to the
                                 * controller. The intrinsic mutex will not be
                                 * used, because there is already a mutex for
                                 * the board data.
                                 */

   /* function addresses for board type specific parts of CAPI calls */
   AvmAicRegisterFct_t   pfnAppRegister;
   AvmAicReleaseFct_t    pfnAppRelease;
   AvmAicPutMessageFct_t pfnPutMessage;
   AvmAicResetCtlrFct_t  pfnResetCtlr;

   /* fields for communication between user processes and the interrupt routine
    */
   int                   fIntrActive;
                                /**<
                                 * Flag for a currently active interrupt
                                 * routine.
                                 */
   int                   fOpInProgress;
                                /**<
                                 * Flag for a running send operation, possibly
                                 * with someone waiting for a result.
                                 */
   int                   fWaitingForRc;
                                /**<
                                 * - 1
                                 *    There is someone waiting for cvNotify (or
                                 *    for wakeup on the address of the softc
                                 *    structure).
                                 * - 0
                                 *    No one waiting.
                                 */
   unsigned              uRc;   /**<
                                 * Result of requests to the controller.
                                 */
   struct mtx            mtxAccess;
                                /**< Mutex to access board data. */
   struct cv             cvNotify;
                                /**<
                                 * Condition variable to wait for results in
                                 * uRc. To wait on it or for it to be signaled
                                 * the access mutex must be held.
                                 */
} AvmAicSc_t;



/**
 * Mapping from CAPI controller number to the port data.
 *
 * @note CAPI defines a maximum of 127 controller numbers from 1 to 127.
 */
extern AvmAicPortData_t *e_apMapCapiCtlrToPortData [128];



/* --- the logging functionality --- */

/** The logging levels supported. */
#define LOG_ALWAYS      0
#define LOG_ERROR       1
#define LOG_INFO        2
#define LOG_TRACE       3
#define LOG_DEBUG       4
#define LOG_DATAMSG     5
#define LOG_IRQ         6

/**
 * Characters to mark log messages with their severity.
 *
 * @note The array-string is indexed by the log level.
 */
#define LOG_CHARS       "AEMTDDI"

/** The current logging level. */
extern int e_iAvmAicLogLevel;
 
/** The macro for log output with driver unit number. */
#define DBG( level, iUnit, fmt, args... )                        \
   if ((level) <= e_iAvmAicLogLevel)                             \
   {                                                             \
      printf ("avmaic%d: %c %s: " fmt "\n",                      \
              iUnit, LOG_CHARS [level], __FUNCTION__ , ## args); \
   }

/** The macro for log output with no unit number available. */
#define DBG0( level, fmt, args... )                       \
   if ((level) <= e_iAvmAicLogLevel)                      \
   {                                                      \
      printf ("avmaic: %c %s: " fmt "\n",                 \
              LOG_CHARS [level], __FUNCTION__ , ## args); \
   }



/* --- some parameters tunable by kernel environment variables --- */

extern int e_iAvmAicMaxApplications;
extern int e_iAvmAicMaxNcciPerChannel;





/* === prototypes of interface functions ================================= */





/* === definition of inline functions ==================================== */





#endif /* __AVMAIC_GLOBAL_H */
