📄 kitleth.c
字号:
*pSize += sizeof(UINT32);
memcpy(pData, g_kitlEthState.deviceMAC, 3*sizeof(UINT16));
pData += 3*sizeof(UINT16);
*pSize += 3*sizeof(UINT16);
memcpy(pData, &port, sizeof(UINT16));
pData += sizeof(UINT16);
*pSize += sizeof(UINT16);
// We are done
rc = TRUE;
cleanUp:
OALMSGS(OAL_KITL&&OAL_FUNC, (L"-KitlEthGetDevCfg(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
//
// Function: KitlEthSend
//
// This function is called by KITL to send packet over transport layer
//
static BOOL KitlEthSend(UCHAR *pData, USHORT length)
{
UCHAR *pSendData;
ULONG sendLength;
USHORT code;
int nRetries = 0;
OALMSGS(OAL_KITL&&OAL_VERBOSE, (
L"+KitlEthSend(0x%08x, %d)\r\n", pData, length
));
// Update multicast addresses
if (g_kitlEthState.updateMCast) {
if (g_kitlEthState.pDriver->pfnMulticastList)
g_kitlEthState.pDriver->pfnMulticastList(
g_kitlEthState.deviceMCast, g_kitlEthState.deviceMCastSize
);
g_kitlEthState.updateMCast = FALSE;
}
// Update filter
if (g_kitlEthState.updateFilter) {
// Update filter
g_kitlEthState.pDriver->pfnCurrentPacketFilter(
g_kitlEthState.deviceFilter
);
// Tell VBRIDGE that there is new filter
VBridgeUCurrentPacketFilter(&g_kitlEthState.deviceFilter);
g_kitlEthState.updateFilter = FALSE;
}
do {
code = g_kitlEthState.pDriver->pfnSendFrame(pData, length);
if (code == 0) {
if (g_kitlEthState.flags & OAL_KITL_FLAGS_VMINI) {
// Consume all the client packets.
while (VBridgeKGetOneTxBuffer(&pSendData, &sendLength)) {
g_kitlEthState.pDriver->pfnSendFrame(pSendData, (USHORT)sendLength);
VBridgeKGetOneTxBufferComplete(pSendData);
}
}
break;
}
KITLOutputDebugString ("!Driver Send failure, retry %u\n",nRetries);
} while (nRetries ++ < 4);
OALMSGS(OAL_KITL&&OAL_VERBOSE, (L"-KitlEthSend(rc = %d)\r\n", code == 0));
return code == 0;
}
//------------------------------------------------------------------------------
//
// Function: KitlEthRecv
//
// This function is called by KITL to receive packet from transport layer
//
static BOOL KitlEthRecv(UCHAR *pData, USHORT *pLength)
{
USHORT code;
UCHAR *pSendData;
ULONG sendLength;
OALMSGS(OAL_KITL&&OAL_VERBOSE, (
L"+KitlEthRecv(0x%08x, 0x%08x->%d)\r\n", pData, pLength, *pLength
));
// Update multicast addresses
if (g_kitlEthState.updateMCast) {
if (g_kitlEthState.pDriver->pfnMulticastList)
g_kitlEthState.pDriver->pfnMulticastList(
g_kitlEthState.deviceMCast, g_kitlEthState.deviceMCastSize
);
g_kitlEthState.updateMCast = FALSE;
}
// Update filter
if (g_kitlEthState.updateFilter) {
// Update filter
g_kitlEthState.pDriver->pfnCurrentPacketFilter(
g_kitlEthState.deviceFilter
);
// Tell VBRIDGE that there is new filter
VBridgeUCurrentPacketFilter(&g_kitlEthState.deviceFilter);
g_kitlEthState.updateFilter = FALSE;
}
// When VMINI is active send all queued VMINI packets
if ((g_kitlEthState.flags & OAL_KITL_FLAGS_VMINI) != 0) {
// First send all VMINI packets
while (VBridgeKGetOneTxBuffer(&pSendData, &sendLength)) {
g_kitlEthState.pDriver->pfnSendFrame(pSendData, (USHORT)sendLength);
VBridgeKGetOneTxBufferComplete(pSendData);
}
}
// Now get packet
code = g_kitlEthState.pDriver->pfnGetFrame(pData, pLength);
OALMSGS(OAL_KITL&&OAL_VERBOSE, (L"-KitlEthRecv(rc = %d)\r\n", code > 0));
return code > 0;
}
//------------------------------------------------------------------------------
//
// Function: KitlEthEnableInt
//
// This function is called by KITL to enable and disable the KITL transport
// interrupt if the transport is interrupt-based
//
//
static VOID KitlEthEnableInt(BOOL enable)
{
OALMSGS(OAL_KITL&&OAL_FUNC, (L"+KitlEthEnableInt(%d)\r\n", enable));
if (enable) {
g_kitlEthState.pDriver->pfnEnableInts();
} else {
g_kitlEthState.pDriver->pfnDisableInts();
}
OALMSGS(OAL_KITL&&OAL_FUNC, (L"-KitlEthEnableInt\r\n"));
}
//------------------------------------------------------------------------------
//
// Function: OALIoCtlVBridge
//
// This function implement OEMIoControl calls for VMINI related IOCTL codes.
//
BOOL OALIoCtlVBridge(
UINT32 code, VOID *pInBuffer, UINT32 inSize, VOID *pOutBuffer,
UINT32 outSize, UINT32 *pOutSize
) {
BOOL rc = TRUE;
OALMSGS(OAL_KITL&&OAL_VERBOSE, (L"+OALIcCtlVBridge(0x%08x,...)\r\n", code));
switch (code) {
case IOCTL_VBRIDGE_GET_TX_PACKET:
rc = VBridgeUGetOneTxPacket((UINT8**)pOutBuffer, inSize);
break;
case IOCTL_VBRIDGE_GET_TX_PACKET_COMPLETE:
VBridgeUGetOneTxPacketComplete((UINT8*)pInBuffer, inSize);
break;
case IOCTL_VBRIDGE_GET_RX_PACKET:
rc = VBridgeUGetOneRxPacket((UINT8**)pOutBuffer, pOutSize);
break;
case IOCTL_VBRIDGE_GET_RX_PACKET_COMPLETE:
VBridgeUGetOneRxPacketComplete((UINT8*)pInBuffer);
break;
case IOCTL_VBRIDGE_GET_ETHERNET_MAC:
VBridgeUGetEDBGMac((UINT8*)pOutBuffer);
break;
case IOCTL_VBRIDGE_CURRENT_PACKET_FILTER:
g_kitlEthState.deviceFilter = *(UINT32*)pInBuffer;
g_kitlEthState.updateFilter = TRUE;
break;
case IOCTL_VBRIDGE_802_3_MULTICAST_LIST:
if (inSize * 6 <= sizeof(g_kitlEthState.deviceMCast)) {
memcpy(g_kitlEthState.deviceMCast, pInBuffer, inSize * 6);
g_kitlEthState.deviceMCastSize = inSize;
g_kitlEthState.updateMCast = TRUE;
} else {
rc = FALSE;
}
break;
case IOCTL_VBRIDGE_WILD_CARD:
rc = VBridgeUWildCard(
pInBuffer, inSize, pOutBuffer, outSize, pOutSize
);
break;
case IOCTL_VBRIDGE_SHARED_ETHERNET:
break;
default:
rc = FALSE;
}
OALMSGS(OAL_KITL&&OAL_VERBOSE, (L"-OALIcCtlVBridge(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
//
// Function: OALKitlEthInit
//
// This function is called by OAL to initialize KITL Ethernet/IP4 protocol
// driver. It first initialize KITL device, fill KITLTRANSPORT structure
// na if OAL_KITL_FLAGS_DHCP flag is set it gets or renews IP4 address
// from DHCP server.
//
BOOL OALKitlEthInit(
LPSTR deviceId, OAL_KITL_DEVICE *pDevice, OAL_KITL_ARGS *pArgs,
KITLTRANSPORT *pKitl
) {
BOOL rc = FALSE;
OAL_KITL_ETH_DRIVER *pDriver;
UINT32 irq, sysIntr, count;
OALMSGS(OAL_KITL&&OAL_FUNC, (
L"+OALKitlEthInit('%S', '%s', 0x%08x, 0x%08x)\r\n",
deviceId, pDevice->name, pArgs, pKitl
));
// Cast driver config parameter
pDriver = (OAL_KITL_ETH_DRIVER*)pDevice->pDriver;
if (pDriver == NULL) {
OALMSGS(OAL_ERROR, (L"ERROR: KITL device driver is NULL\r\n"));
goto cleanUp;
}
// Call InitDmaBuffer if there is any
if (pDriver->pfnInitDmaBuffer != NULL) {
if (!pDriver->pfnInitDmaBuffer(
(DWORD)g_oalKitlBuffer, sizeof(g_oalKitlBuffer)
)) {
OALMSGS(OAL_ERROR, (
L"ERROR: KITL call to pfnInitDmaBuffer failed\r\n"
));
goto cleanUp;
}
}
// Call pfnInit
if (!pDriver->pfnInit(
(UCHAR*)pArgs->devLoc.PhysicalLoc, pArgs->devLoc.LogicalLoc, pArgs->mac
)) {
OALMSGS(OAL_ERROR, (L"ERROR: KITL call to pfnInit failed\r\n"));
goto cleanUp;
}
// Extend name if flag is set
if ((pArgs->flags & OAL_KITL_FLAGS_EXTNAME) != 0) {
OALKitlCreateName(deviceId, pArgs->mac, deviceId);
}
// Now we know final name, print it
OALMSGS(TRUE, (L"KITL: *** Device Name %hs ***\r\n", deviceId));
// Map and enable interrupt
if ((pArgs->flags & OAL_KITL_FLAGS_POLL) != 0) {
sysIntr = KITL_SYSINTR_NOINTR;
} else {
// Get IRQ, when interface is undefined use Pin as IRQ
if (pArgs->devLoc.IfcType == InterfaceTypeUndefined) {
irq = pArgs->devLoc.Pin;
} else {
count = 1;
if (!OALIntrRequestIrqs(&pArgs->devLoc, &count, &irq)) {
OALMSGS(OAL_WARN, (
L"WARN: KITL can't obtain IRQ for KITL device\r\n"
));
irq = OAL_INTR_IRQ_UNDEFINED;
}
}
// Get SYSINTR for IRQ
if (irq != OAL_INTR_IRQ_UNDEFINED) {
sysIntr = OALIntrRequestSysIntr(1, &irq, OAL_INTR_TRANSLATE);
if (sysIntr != SYSINTR_UNDEFINED) {
OEMInterruptEnable(sysIntr, NULL, 0);
} else {
OALMSGS(OAL_WARN, (
L"WARN: KITL can't obtain SYSINTR for IRQ %d\r\n", irq
));
sysIntr = KITL_SYSINTR_NOINTR;
}
} else {
sysIntr = KITL_SYSINTR_NOINTR;
}
}
OALMSGS(OAL_WARN && (sysIntr == KITL_SYSINTR_NOINTR), (
L"WARN: KITL will run in polling mode\r\n"
));
//-----------------------------------------------------------------------
// Initalize KITL transport structure
//-----------------------------------------------------------------------
memcpy(pKitl->szName, deviceId, sizeof(pKitl->szName));
pKitl->Interrupt = (UCHAR)sysIntr;
pKitl->WindowSize = OAL_KITL_WINDOW_SIZE;
pKitl->FrmHdrSize = KitlEthGetFrameHdrSize();
pKitl->dwPhysBuffer = 0;
pKitl->dwPhysBufLen = 0;
pKitl->pfnEncode = KitlEthEncode;
pKitl->pfnDecode = KitlEthDecode;
pKitl->pfnSend = KitlEthSend;
pKitl->pfnRecv = KitlEthRecv;
pKitl->pfnEnableInt = KitlEthEnableInt;
pKitl->pfnGetDevCfg = KitlEthGetDevCfg;
pKitl->pfnSetHostCfg = KitlEthSetHostCfg;
//-----------------------------------------------------------------------
// Initalize KITL IP4 state structure
//-----------------------------------------------------------------------
g_kitlEthState.pDriver = pDriver;
g_kitlEthState.flags = pArgs->flags;
g_kitlEthState.deviceMAC[0] = (UINT8)pArgs->mac[0];
g_kitlEthState.deviceMAC[1] = (UINT8)(pArgs->mac[0] >> 8);
g_kitlEthState.deviceMAC[2] = (UINT8)pArgs->mac[1];
g_kitlEthState.deviceMAC[3] = (UINT8)(pArgs->mac[1] >> 8);
g_kitlEthState.deviceMAC[4] = (UINT8)pArgs->mac[2];
g_kitlEthState.deviceMAC[5] = (UINT8)(pArgs->mac[2] >> 8);
g_kitlEthState.deviceIP = pArgs->ipAddress;
g_kitlEthState.kitlServerMAC[0] = 0xFF;
g_kitlEthState.kitlServerMAC[1] = 0xFF;
g_kitlEthState.kitlServerMAC[2] = 0xFF;
g_kitlEthState.kitlServerMAC[3] = 0xFF;
g_kitlEthState.kitlServerMAC[4] = 0xFF;
g_kitlEthState.kitlServerMAC[5] = 0xFF;
g_kitlEthState.kitlServerIP = 0xFFFFFFFF;
g_kitlEthState.kitlServerPort = htons(KITL_SERVER_PORT);
g_kitlEthState.dhcpXId = pArgs->mac[2] | 0x17016414;
g_kitlEthState.dhcpState = DHCP_BOUND;
// Get or renew DHCP address
if ((pArgs->flags & OAL_KITL_FLAGS_DHCP) != 0) {
// KITL isn't running let use direct functions for send/receive
g_kitlEthState.pfnSend = pKitl->pfnSend;
g_kitlEthState.pfnRecv = pKitl->pfnRecv;
// Get or renew address from DHCP server
GetAddressDHCP(pArgs->ipAddress);
}
// When KITL is running we should call sync function for send
g_kitlEthState.pfnSend = KitlSendRawData;
// There should not be direct receive
g_kitlEthState.pfnRecv = NULL;
// Activate VMINI bridge...
if ((pArgs->flags & OAL_KITL_FLAGS_VMINI) != 0) {
VBridgeInit();
VBridgeKSetLocalMacAddress((char*)pArgs->mac);
}
// Result depends on fact if we get IP address
rc = (g_kitlEthState.deviceIP != 0);
cleanUp:
OALMSGS(OAL_KITL&&OAL_FUNC, (L"-OALKitlEthInit(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -