
/*M*                     
//                    INTEL CORPORATION PROPRIETARY INFORMATION
//      This software is supplied under the terms of a license agreement or
//      nondisclosure agreement with Intel Corporation and may not be copied
//      or disclosed except in accordance with the terms of that agreement.
//            Copyright (c) 1995-2000 Intel Corporation.  All Rights Reserved.
*M*/
/*
 * $Log:   //cospublic004/shareddata/isc/ISC2x/common/src/imb/imb_drv.h.v  $
 * 
 *    Rev 1.8   27 Dec 1999 16:06:50   jpaiasno
 * Refined the logic related to IPMI version detection and
 * creation of DPC named event object
 * 
 *    Rev 1.7   07 Oct 1999 15:28:08   jpaiasno
 * Added  new BMC transfer state machine code
 *  to KCS interface for IPMI 1.0 conformance
 * 
 *    Rev 1.6   27 Jul 1999 10:18:16   jpaiasno
 *  
 * 
 *    Rev 1.5   Jul 22 1999 09:33:42   bmsherma
 * corrected compile warnings
 * 
 *    Rev 1.4   21 Jan 1999 14:20:50   jpaiasno
 * Fixed a logic problem related to checking the IPMI 
 * version
 * 
 *    Rev 1.3   21 Jan 1999 11:44:24   jpaiasno
 *  
 * 
 *    Rev 1.2   21 Jan 1999 11:40:36   jpaiasno
 * Added Support for IPMI 1.0 firmware
 * 
 *    Rev 1.1   08 Dec 1998 10:55:44   jpaiasno
 * Added code to support async.
 * DPC events from the EMP console.
 * 
 *    Rev 1.7   24 Mar 1998 14:19:16   fkhanx
 * Added Copyright Header
*/

#ifndef IMB_DRV__

#define IMB_DRV__

#pragma pack(1)

//
// This structure represents a request directed to the BMC (as opposed to a
// different controller which we have to get to through the BMC.It is meant 
// to be overlayed on a char array of size MAX_BMC_REQUEST_SIZE.
//
typedef struct {
	BYTE    nfLn;
	BYTE    cmd;
	BYTE    data[1];
} BmcRequest;

#define MIN_BMC_REQUEST_SIZE    2
#define MAX_BMC_REQUEST_SIZE    (MIN_BMC_RESPONSE_SIZE + MAX_IMB_PACKET_SIZE)
#define MAX_BUFFER_SIZE                 64


//
// This structure holds a response from the BMC, It is meant to be overlayed on
// a char array of size MAX_BMC_RESPONSE_SIZE
//

typedef struct {
	BYTE    nfLn;
	BYTE    cmd;
	BYTE    cCode;
	BYTE    data[1];
} BmcResponse;

#define MIN_BMC_RESPONSE_SIZE   3
#define MAX_BMC_RESPONSE_SIZE   (MIN_BMC_RESPONSE_SIZE + MAX_IMB_PACKET_SIZE)

//
// Default delays - usable for ImbOsStartReqTimer() and DelayRetryFunc()
//
#define WAIT_1_MS                       1000            // in uSecs
#define WAIT_5_MS                       5000            // in uSecs
#define WAIT_10_MS                      10000           // in uSecs

#define DEFAULT_MESSAGE_TIMEOUT (1000 * WAIT_1_MS)

#define SMS_READY_DELAY                 (20 * WAIT_1_MS)
//
// This value is the number of times the DelayRetryFunc() just returns instead of
// doing a real OS delay. This value has been chosen by histogramming the BMC ready
// times on a Bear and choosing a value that covers the majority of hits
//
#define NO_RETRY_DELAY_COUNT    0x50

//
// IMB packet defines and utility macros
//
#define IMB_HEAD_SIZE                   3       // rsSa, netFnLun, csum

#define NETFN_OF(x)                             (((x)>>2) & 0x3f)       // extract netFn from nfLn
#define LUN_OF(x)                               ((x) & 0x3)                     // extract lun from nfLn
#define SEQ_OF(x)                               (((x)>>2) & 0x3f)       // extract seqNo from seqLn

#define SEQ_LUN(s,l)                    ((((s) & 0x3f) << 2) | ((l) & 0x3))     // construct seqLn from seq and lun
#define NETFN_LUN(n,l)                  ((((n) << 2) | ((l) & 0x3)))            // construct nfLun from netFn and lun

#define RESPONSE_NETFN(nf)              ((nf) | 1)                      // create response netFn from request netFn
#define IS_REQUEST(nf)                  (((nf) & 1) == 0)       // test for request netFn
#define IS_RESPONSE(nf)                 (((nf) & 1) == 1)       // test for response netFn

#define APP_NETFN                               0x06
#define PUBLIC_BUS                              0

//GET DEVICE ID COMMAND
#define GET_DEVICE_ID 0x1

//IPMI 1.0 related definitions (pai 1/15)
#define IPMI_1_VER                      0x1     
#define IPMI_OLD_VER            0x90
#define IPMI_UNKNOWN_VER        0xFF
#define SEND_MESSAGE_CMD        0x34
#define GET_MESSAGE_CMD         0x33            
#define IPMB_CHANNEL_NUMBER   0
#define CHANNEL_NUMBER_OFFSET 0


#define BMC_SA                                  0x20    // BMC slave address
#define BMC_LUN                                 0               // BMC only responds to this LUN
#define SMS_LUN                                 2               // BMC forwards pkts with this LUN to SMS buffer
//
// IMB completion codes
//
#define CCODE_OK                0
#define CCODE_UNKNOWN   0xff    
//
// IMB commands used by the driver
//
#define SET_WATCHDOG_TIMER      0x24

typedef struct  {

	BYTE    timerUse;
#define                         WD_DONT_LOG                     0x80
#define                         WD_BIOS_FRB2            0x01
#define                         WD_BIOS_POST            0x02
#define                         WD_OS_LOAD                      0x03
#define                         WD_SMS                          0x04

	BYTE    timerActions;
#define                         WD_PRE_ACT_NONE         0x00
#define                         WD_PRE_ACT_SMI          0x10
#define                         WD_PRE_ACT_SCI          0x20

#define                         WD_ACT_NONE                     0x00
#define                         WD_ACT_RESET            0x01
#define                         WD_ACT_PWR_DOWN         0x02
#define                         WD_ACT_PWR_CYCLE        0x03

	BYTE    preTimeOut;
	BYTE    timerUseClear;
	BYTE    countLow;
	BYTE    countHigh;
} WatchdogCmd;

#define RESET_WATCHDOG_TIMER    0x22

typedef struct  {
	BYTE    busType;
	BYTE    devSa;
	BYTE    readCount;
	BYTE    data[1];
} WriteReadI2cCmd;

#define MIN_WRI2C_CMD_LEN       3       

#define WRITE_READ_I2C          0x52

typedef struct {
	BYTE    busType;
	BYTE    data[1];
} WriteI2cCmd;

#define MIN_WI2C_CMD_LEN        1

#define WRITE_I2C                       0x50

#define READ_SMS_BUFFER         0x37    // no request data for this command

#pragma pack()

///////////////////////////////////////////////////////////////////////////////
// prototypes for functions provided by the OS/interface independent module
//

IMB_STATUS
SendImbRequest (
		ImbRequestBuffer *      req,
		ImbResponseBuffer *     resp,
		DWORD *                         respLength,
		void *                          context
	);

IMB_STATUS
GetSmsBuffer (
		BmcResponse *resp,
		DWORD *         bmcLength,
		void *          context
	);

void
ImbShutdownSystem (
		DWORD shutdownCode,     // codes defined in imb_if.h
		DWORD delayTime,        // units of 100ms
		void *context
	);
//
// Async message functions
//

void
ImbAsyncInit (
		ImbAsyncQueueInfo *     asyncQ
	);

IMB_STATUS
ImbAsyncGetMessage (
		ImbAsyncRequest *       req,            // his request
		ImbAsyncResponse *      buf,            // data buffer
		DWORD *                         length,         // IN - size of buf and OUT - size of message
		ImbAsyncQueueInfo *     asyncQ
	);

void
ImbAsyncQueueMessage (
		BmcResponse *   msg,            // contains SMS buffer message
		DWORD                   length,         // message length
		void *                  context         // OS dependent handle
	);

//
// Check to see if there are any SMS messages to processes
//
void
ImbAsyncMessageProcess (
		void *                          context         // OS dependent handle
	);

///////////////////////////////////////////////////////////////////////////////
// prototypes for functions provided by the OS specific modules
//

//
// DelayRetryFunc - if retryCount is greater than an OS specific value, wait 'delay' uSecs
//
VOID
DelayRetryFunc (
		DWORD retryCount,       // number of times we've been called while waiting
		DWORD delay,            // time to delay (in uSecs)
		void *context           // OS dependent handle
	);

#define FORCE_DELAY             0xffffffff      // if retryCount has this value, force a delay
//
// ImbReqTimedOut - test to see if the current IMB request has timed out
//
void
ImbOsStartReq (
		DWORD   timeOut,        // in uSec units
		void *  context         // OS dependent handle
	);

void
ImbOsEndReq (
		void *  context         // OS dependent handle
	);

BOOL
ImbReqTimedOut (
		void *context           // OS dependent handle
	);

BYTE
GetNextImbSeq (
		void *context           // OS dependent handle
	);

struct ImbIfStruct *
ImbIf(
		void *context           // OS dependent handle
	);
//
// Return a pointer to the queue structure
//
ImbAsyncQueueInfo *
ImbAsyncQueue (
		void * context
	);
//
// Initialize the OS dependent parts of the Async Queue
//
void
ImbAsyncOsInit (
		ImbAsyncQueueInfo *info
	);

//
// Wait for an async request to be satisfied or timed out
//
void
ImbAsyncOsReqWait (
		ImbAsyncQueueInfo *     info,
		DWORD                           timeOut
	);
//
// Wakeup all those waiting for incoming requests
//
void
ImbAsyncOsReqWakeup (
		ImbAsyncQueueInfo *info
	);

void ImbAsyncOsNewWakeup(
		void *context
	);
//
// Lock the async queue
//
BOOL
ImbAsyncOsLock (
		ImbAsyncQueueInfo *info
	);
//
// Unlock the async queue
//
BOOL
ImbAsyncOsUnLock (
		ImbAsyncQueueInfo *info
	);


int isIpmiOldVersion(void* context);

///////////////////////////////////////////////////////////////////////////////
// prototypes for functions provided by the interface specific modules (smic, kcs)
//

//
// define the function to send and get a response for a BMC request
//
typedef IMB_STATUS (* BmcRequestProc ) (
		BmcRequest *    request,
		DWORD                   reqLength,
		BmcResponse *   response,
		DWORD *                 respLength,
		void *                  context,
		DWORD           ipmiOldFlag
	);

//
// define the function that returns whether the SMS buffer has something in it
//
typedef BOOL    (* SmsBufAvailProc ) ( void );

//
// define the function that returns whether the platform has an interface of this type
//
typedef BOOL    (* ImbIfProbeProc ) ( void );

typedef struct ImbIfStruct {
	BmcRequestProc          sendBmcRequest;
	SmsBufAvailProc         smsBufferAvail;
	ImbIfProbeProc          ifProbe;
} ImbInterface;


#endif // IMB_DRV__
