/***************************************************************** ***************************************************************** *** ** *** (C)Copyright 2005-2006, American Megatrends Inc. ** *** ** *** All Rights Reserved. ** *** ** *** 6145-F, Northbelt Parkway, Norcross, ** *** ** *** Georgia - 30071, USA. Phone-(770)-246-8600. ** *** ** ***************************************************************** **************************************************************** * * SOLConfig.c * SOL configuration * * Author: Govind kothandapani ****************************************************************/ #define ENABLE_DEBUG_MACROS 0 #include "Types.h" #include "Debug.h" #include "MsgHndlr.h" #include "Support.h" #include "IPMIDefs.h" #include "SharedMem.h" #include "PMConfig.h" #include "IPMI_SOLConfig.h" #include "NVRAccess.h" #include "PDKDefs.h" #include "PDKAccess.h" #include"Ethaddr.h" #include "IPMIConf.h" /*** Local Definitions ***/ #define SOL_SET_IN_PROGRESS 0 #define SOL_ENABLE_PARAM 1 #define SOL_AUTHENTICATION_PARAM 2 #define SOL_ACCUM_THRESHOLD_PARAM 3 #define SOL_RETRY_PARAM 4 #define SOL_NVOL_BIT_RATE_PARAM 5 #define SOL_VOL_BIT_RATE_PARAM 6 #define SOL_PAYLD_CHANNEL_PARAM 7 #define SOL_PAYLD_PORT_NUM_PARAM 8 #define SET_IN_PROGRESS 0x01 #define SET_COMPLETE 0x00 #define PARAM_REVISION 0x11 #define GET_PARAM_REV_ONLY_MASK 0x80 #define BAUD_RATE_9600 6 #define BAUD_RATE_19200 7 #define BAUD_RATE_38400 8 #define BAUD_RATE_57600 9 #define BAUD_RATE_115200 10 /* Reserved Bits table */ #define MAX_SOL_PARAMS_DATA 9 #define RESERVED_VALUE_70 0x70 #define RESERVED_VALUE_F0 0xF0 typedef struct { INT8U Params; INT8U ReservedBits [MAX_SOL_PARAMS_DATA]; INT8U DataLen; } SOLCfgRsvdBits_T; static SOLCfgRsvdBits_T m_RsvdBitsCheck [] = { /* Param Reserved Bits Data Size */ { 0, { 0xFC }, 0x1 }, { 1, { 0xFE }, 0x1 }, { 2, { 0x30 }, 0x1 }, { 4, { 0xF8 }, 0x1 }, { 5, { 0xF0 }, 0x1 } }; /*** Module Variables ***/ /** * @brief SOL Configuration Parameter Lengths **/ static const INT8U SOLConfigParamLengths [] = { 1,1,1,2,2,1,1,1,2 }; /** * IsBaudRateValid **/ static int IsBaudRateValid (INT8U BaudRate); // Function to check if valid privileges static int IsValidPrivilege(INT8U authtype); #if SOL_ACTIVATING_COMMAND != UNIMPLEMENTED /*--------------------------------------- * SOLActivating *---------------------------------------*/ int SOLActivating (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst) { /** * Send SOL activating Message to Remote Application connected to * Connected to Serial port **/ *pRes = CC_NORMAL; return sizeof (*pRes); } #endif /* SOL_ACTIVATING_COMMAND */ #if GET_SOL_CONFIGURATION != UNIMPLEMENTED /*--------------------------------------- * GetSOLConfig *---------------------------------------*/ int GetSOLConfig (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst) { _NEAR_ GetSOLConfigReq_T* GetReq = (_NEAR_ GetSOLConfigReq_T*) pReq; _NEAR_ GetSOLConfigRes_T* GetRes = (_NEAR_ GetSOLConfigRes_T*) pRes; _NEAR_ GetSOLConfigOEMRes_T* GetOEMRes = (_NEAR_ GetSOLConfigOEMRes_T*) pRes; _FAR_ BMCSharedMem_T* pSharedMem = BMC_GET_SHARED_MEM (BMCInst); BMCInfo_t *pBMCInfo = &g_BMCInfo[BMCInst]; INT8U Size,*curchannel; INT8U ChannelNum, EthIndex; INT8U oem_len; unsigned long oem_addr; ChannelNum = GetReq->ChannelNum & 0x0F; if(GetReq->ChannelNum & RESERVED_VALUE_70) { /* Alarm !!! Somebody is trying to set Reseved Bits */ *pRes = CC_INV_DATA_FIELD; return sizeof (*pRes); } if (ChannelNum > 0x0F) { *pRes =CC_INV_DATA_FIELD; return sizeof(*pRes); } if (0x0E == ChannelNum) { OS_THREAD_TLS_GET(g_tls.CurChannel,curchannel); EthIndex = GetEthIndex (*curchannel & 0xF, BMCInst); } else { EthIndex = GetEthIndex (ChannelNum, BMCInst); } if (0xFF == EthIndex) { *pRes = CC_INV_DATA_FIELD; return sizeof (*pRes); } if((GetReq->SetSel != 0x00) ||(GetReq->BlkSEl != 0x00)) { *pRes =CC_INV_DATA_FIELD; return sizeof(*pRes); } GetRes->CompletionCode = CC_NORMAL; GetRes->ParamRev = PARAM_REVISION; /* Check if only parameter revision is required */ if (0 != (GetReq->ChannelNum & GET_PARAM_REV_ONLY_MASK)) { if((MAX_SOL_CONF_PARAM >= GetReq->ParamSel)) { return sizeof(GetSOLConfigRes_T); } else if(( NULL != g_PDKHandle[PDK_GETSOLOEMPARAM]) && ((MIN_SOL_OEM_CONF_PARAM <= GetReq->ParamSel) && (MAX_SOL_OEM_CONF_PARAM >= GetReq->ParamSel))) { oem_len = ((int(*)(INT8U, unsigned long*,int))(g_PDKHandle[PDK_GETSOLOEMPARAM]))(GetReq->ParamSel, &oem_addr ,BMCInst); if( oem_len == 0) { GetRes->CompletionCode = CC_PARAM_NOT_SUPPORTED; return sizeof(INT8U); } else return sizeof(GetSOLConfigRes_T); } else { *pRes = CC_PARAM_NOT_SUPPORTED; return sizeof (*pRes); } } Size = sizeof (GetSOLConfigRes_T); /* Load individual configurations */ switch (GetReq->ParamSel) { case SOL_SET_IN_PROGRESS: LOCK_BMC_SHARED_MEM(BMCInst); (*(_NEAR_ INT8U*)(GetRes + 1)) = BMC_GET_SHARED_MEM(BMCInst)->m_SOL_SetInProgress; UNLOCK_BMC_SHARED_MEM(BMCInst); Size = Size + sizeof (INT8U); break; case SOL_ENABLE_PARAM: (*(_NEAR_ INT8U*)(GetRes + 1)) = pBMCInfo->SOLCfg[EthIndex].SOLEnable; Size = Size + sizeof (INT8U); break; case SOL_AUTHENTICATION_PARAM: (*(_NEAR_ INT8U*)(GetRes + 1)) = pBMCInfo->SOLCfg[EthIndex].SOLAuth; Size = Size + sizeof (INT8U); break; case SOL_ACCUM_THRESHOLD_PARAM: _fmemcpy((INT8U *)(GetRes+1),(INT8U *)&pBMCInfo->SOLCfg[EthIndex].CharAccThresh,sizeof(INT16U)); Size = Size + sizeof (INT16U); break; case SOL_RETRY_PARAM: (*((_NEAR_ INT8U*)(GetRes + 1))) = pBMCInfo->SOLCfg[EthIndex].SOLRetryCount; (*((_NEAR_ INT8U*)(GetRes + 1) + 1)) = pBMCInfo->SOLCfg[EthIndex].SOLRetryInterval; Size = Size + sizeof (INT16U); break; case SOL_NVOL_BIT_RATE_PARAM: (*(_NEAR_ INT8U*)(GetRes + 1)) = pBMCInfo->SOLCfg[EthIndex].NVBitRate; Size = Size + sizeof (INT8U); break; case SOL_VOL_BIT_RATE_PARAM: (*(_NEAR_ INT8U*)(GetRes + 1)) = pSharedMem->SOLBitRate[EthIndex]; Size = Size + sizeof (INT8U); break; case SOL_PAYLD_CHANNEL_PARAM: (*(_NEAR_ INT8U*)(GetRes + 1)) = pBMCInfo->SOLCfg[EthIndex].PayldChannel; Size = Size + sizeof (INT8U); break; case SOL_PAYLD_PORT_NUM_PARAM: _fmemcpy((INT8U *)(GetRes+1),(INT8U *)&pBMCInfo->SOLCfg[EthIndex].PayldPortNum,sizeof(INT16U)); Size = Size + sizeof (INT16U); break; default: if(g_PDKHandle[PDK_GETSOLOEMPARAM] != NULL && (GetReq->ParamSel >= 192 && GetReq->ParamSel <= 255)) { oem_len = ((int(*)(INT8U, unsigned long*,int))(g_PDKHandle[PDK_GETSOLOEMPARAM]))(GetReq->ParamSel, &oem_addr ,BMCInst); if( oem_len == 0) { GetRes->CompletionCode = CC_PARAM_NOT_SUPPORTED; return sizeof(INT8U); } else { //Acquire the OEM parameters if( oem_len < MSG_PAYLOAD_SIZE - sizeof(GetSOLConfigOEMRes_T)) { memcpy((char*)GetOEMRes + sizeof(GetSOLConfigOEMRes_T) ,\ (unsigned int*)oem_addr , oem_len); } else { GetRes->CompletionCode = CC_PARAM_NOT_SUPPORTED; return sizeof(INT8U); } return sizeof(GetSystemInfoParamOEMRes_T) + oem_len; } } else { GetRes->CompletionCode = CC_PARAM_NOT_SUPPORTED; Size = sizeof (INT8U); } } return Size; } #endif /* GET_SOL_CONFIGURATION */ #if SET_SOL_CONFIGURATION != UNIMPLEMENTED /*--------------------------------------- * SetSOLConfig *---------------------------------------*/ int SetSOLConfig (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst) { _NEAR_ SetSOLConfigReq_T* SetReq = (_NEAR_ SetSOLConfigReq_T*) pReq; _NEAR_ SetSOLConfigOEMReq_T* pSetOEMReq = (_NEAR_ SetSOLConfigOEMReq_T*) pReq; _FAR_ BMCSharedMem_T* pSharedMem = BMC_GET_SHARED_MEM (BMCInst); BMCInfo_t *pBMCInfo = &g_BMCInfo[BMCInst]; int i=0, j=0; INT8U ChannelNum, EthIndex,*curchannel; unsigned long oem_addr; int size; INT8U m_SOL_SetInProgress; /**< Contains setting SOL configuration status */ ChannelNum = SetReq->ChannelNum & 0x0F; if (ChannelNum > 0x0F) { *pRes =CC_INV_DATA_FIELD; return sizeof(*pRes); } if (0x0E == ChannelNum) { OS_THREAD_TLS_GET(g_tls.CurChannel,curchannel); EthIndex = GetEthIndex (*curchannel & 0xF, BMCInst); } else { EthIndex = GetEthIndex (ChannelNum, BMCInst); } if (0xFF == EthIndex) { *pRes = CC_INV_DATA_FIELD; return sizeof (*pRes); } if (SetReq->ParamSel >= sizeof (SOLConfigParamLengths)) { *pRes = CC_PARAM_NOT_SUPPORTED; return sizeof (*pRes); } /* Validate Req Lengths */ if (ReqLen != (sizeof (SetSOLConfigReq_T) + SOLConfigParamLengths [SetReq->ParamSel])) { *pRes = CC_REQ_INV_LEN; return sizeof (*pRes); } if(SetReq->ChannelNum & RESERVED_VALUE_F0) { /* Alarm !!! Somebody is trying to set Reseved Bits */ *pRes = CC_INV_DATA_FIELD; return sizeof (*pRes); } /* Check for Reserved Bits */ for (i = 0; i < sizeof (m_RsvdBitsCheck)/ sizeof (m_RsvdBitsCheck[0]); i++) { /* Check if this Parameter Selector needs Reserved bit checking !! */ if (m_RsvdBitsCheck[i].Params == SetReq->ParamSel ) { for (j = 0; j < m_RsvdBitsCheck[i].DataLen; j++) { if ( 0 != (pReq[2+j] & m_RsvdBitsCheck[i].ReservedBits[j])) { /* Alarm !!! Somebody is trying to set Reseved Bits */ *pRes = CC_INV_DATA_FIELD; return sizeof (*pRes); } } } } *pRes = CC_NORMAL; switch (SetReq->ParamSel) { case SOL_SET_IN_PROGRESS: LOCK_BMC_SHARED_MEM(BMCInst); m_SOL_SetInProgress = BMC_GET_SHARED_MEM(BMCInst)->m_SOL_SetInProgress; UNLOCK_BMC_SHARED_MEM(BMCInst); /* Commit Write is optional and supported * only if rollback is supported */ if ((SET_COMPLETE != (*(_NEAR_ INT8U*)(SetReq + 1))) && (SET_IN_PROGRESS != (*(_NEAR_ INT8U*)(SetReq + 1)))) { *pRes = CC_PARAM_NOT_SUPPORTED; return sizeof (*pRes); } else if ((SET_IN_PROGRESS == m_SOL_SetInProgress) && (SET_IN_PROGRESS == (*(_NEAR_ INT8U*)(SetReq + 1)))) { /*Set In Progress already Set */ *pRes = CC_SET_IN_PROGRESS; return sizeof (*pRes); } LOCK_BMC_SHARED_MEM(BMCInst); BMC_GET_SHARED_MEM(BMCInst)->m_SOL_SetInProgress = (*(_NEAR_ INT8U*)(SetReq + 1)); UNLOCK_BMC_SHARED_MEM(BMCInst); break; case SOL_ENABLE_PARAM: pBMCInfo->SOLCfg[EthIndex].SOLEnable = (*(_NEAR_ INT8U*)(SetReq + 1)); break; case SOL_AUTHENTICATION_PARAM: /* #34323: Check if user is setting reserved bits. This cannot be handled at main logic of reserve bit checking. */ if (0 != IsValidPrivilege((0x3F & (*(_NEAR_ INT8U*)(SetReq + 1))))) { *pRes = CC_INV_DATA_FIELD; return sizeof (*pRes); } pBMCInfo->SOLCfg[EthIndex].SOLAuth = (*(_NEAR_ INT8U*)(SetReq + 1)); break; case SOL_ACCUM_THRESHOLD_PARAM: if(((*(_NEAR_ INT8U*)(SetReq + 1)) == 0) || ((*((_NEAR_ INT8U*)(SetReq +1)+1)) == 0)) { *pRes = CC_INV_DATA_FIELD; return sizeof (*pRes); } pBMCInfo->SOLCfg[EthIndex].CharAccThresh = (*(_NEAR_ INT16U*)(SetReq + 1)); break; case SOL_RETRY_PARAM: pBMCInfo->SOLCfg[EthIndex].SOLRetryCount = (*((_NEAR_ INT8U*)(SetReq +1) ) ); pBMCInfo->SOLCfg[EthIndex].SOLRetryInterval = (*((_NEAR_ INT8U*)(SetReq +1)+1)); break; case SOL_NVOL_BIT_RATE_PARAM: if ( 0 != IsBaudRateValid (*(_NEAR_ INT8U*)(SetReq + 1))) { /*Invalid baud rate setting */ *pRes = CC_INV_DATA_FIELD; return sizeof (*pRes); } if((*(_NEAR_ INT8U*)(SetReq+1)) == 0) *(_NEAR_ INT8U*)(SetReq+1) = BAUD_RATE_9600; pBMCInfo->SOLCfg[EthIndex].NVBitRate = *(_NEAR_ INT8U*)(SetReq + 1); break; case SOL_VOL_BIT_RATE_PARAM: if ( 0 != IsBaudRateValid (*(_NEAR_ INT8U*)(SetReq + 1))) { /*Invalid baud rate setting */ *pRes = CC_INV_DATA_FIELD; return sizeof (*pRes); } if((*(_NEAR_ INT8U*)(SetReq+1)) == 0) *(_NEAR_ INT8U*)(SetReq+1) = BAUD_RATE_9600; pSharedMem->SOLBitRate[EthIndex] = *(_NEAR_ INT8U*)(SetReq + 1); break; case SOL_PAYLD_CHANNEL_PARAM: *pRes = CC_ATTEMPT_TO_SET_RO_PARAM; return sizeof (*pRes); break; case SOL_PAYLD_PORT_NUM_PARAM: *pRes = CC_ATTEMPT_TO_SET_RO_PARAM; return sizeof (*pRes); break; default: if(g_PDKHandle[PDK_SETSOLOEMPARAM] != NULL && (SetReq->ParamSel >= 192 && SetReq->ParamSel <= 255)) { oem_addr = (unsigned long)((char*)pSetOEMReq + sizeof(SetSOLConfigOEMReq_T)); size = ((int(*)(INT8U, unsigned long*,int))(g_PDKHandle[PDK_SETSOLOEMPARAM]))(SetReq->ParamSel, &oem_addr ,BMCInst); if(size <= 0) { *pRes = CC_PARAM_NOT_SUPPORTED; return sizeof(*pRes); } else { *pRes = CC_PARAM_NOT_SUPPORTED; return sizeof(*pRes); } } } FlushIPMI((INT8U*)&pBMCInfo->SOLCfg[0],(INT8U*)&pBMCInfo->SOLCfg[EthIndex],pBMCInfo->IPMIConfLoc.SOLCfgAddr, sizeof(SOLConfig_T),BMCInst); return sizeof (*pRes); } #endif /* SET_SOL_CONFIGURATION */ /** * IsBaudRateValid **/ int IsBaudRateValid (INT8U BaudRate) { /* Check against supported Baud Rates */ if ((BaudRate == 0) || (BaudRate == BAUD_RATE_9600) || (BaudRate == BAUD_RATE_19200) || (BaudRate == BAUD_RATE_38400) || (BaudRate == BAUD_RATE_57600) || (BaudRate == BAUD_RATE_115200)) { //Baud rate is valid return 0; } //Baud rate is invvalid return -1; } /* Check if user entered Auth type is valid */ int IsValidPrivilege(INT8U priv_lvl) { if ((priv_lvl == 02) || (priv_lvl == 03) || (priv_lvl == 04) || (priv_lvl == 05)) return 0; else return -1; //// Invalid privilege } #if 0 /** * InitSOLPort **/ int InitSOLPort (INT8U BaudRate) { int status; int fd; struct termios tty_struct; if ((fd = open(SOL_IFC_PORT,O_RDONLY)) < 0) { IPMI_WARNING ("Can't open serial port..%s\n",strerror(errno)); return -1; } status = tcgetattr(fd,&tty_struct); /* get termios structure */ switch (BaudRate) { case BAUD_RATE_9600: cfsetospeed(&tty_struct, B9600); cfsetispeed(&tty_struct, B9600); break; case BAUD_RATE_19200: cfsetospeed(&tty_struct, B19200); cfsetispeed(&tty_struct, B19200); break; case BAUD_RATE_38400: cfsetospeed(&tty_struct, B38400); cfsetispeed(&tty_struct, B38400); break; case BAUD_RATE_57600: cfsetospeed(&tty_struct, B57600); cfsetispeed(&tty_struct, B57600); break; case BAUD_RATE_115200: cfsetospeed(&tty_struct, B115200); cfsetispeed(&tty_struct, B115200); break; default: IPMI_ERROR ("SOLConfig.c : Invalid baud rate = %x\n", BaudRate); } tty_struct.c_cflag |= CS8; /* Set 8bits/charecter */ tty_struct.c_cflag &= ~CSTOPB; /* set framing to 1 stop bits */ tty_struct.c_cflag &= ~(PARENB); /* set parity to NONE */ tty_struct.c_iflag &= ~(INPCK); /* Set Hardware flow control */ tty_struct.c_cflag |= CRTSCTS; tty_struct.c_lflag &= ~(ICANON|ECHO|ECHOE|ISIG); /* Raw input mode */ tty_struct.c_oflag &= ~(OCRNL | ONOCR | ONLRET); tty_struct.c_iflag &= ~(IXON | IXOFF); /* no sw flow ctrl */ tty_struct.c_iflag &= ~INLCR; tty_struct.c_iflag &= ~ICRNL; tty_struct.c_iflag &= ~IGNCR; PDK_InitSOLPort (&tty_struct); /* OEM specific SOL initialization */ /* set the new attributes in the tty driver */ status = tcsetattr(fd, TCSANOW, &tty_struct); close (fd); return 0; } #endif /* #if 0 */