📄 kitleth.c
字号:
}
//------------------------------------------------------------------------------
//
// 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;
KITL_RETAILMSG(ZONE_SEND, (
"+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;
}
KITL_RETAILMSG(ZONE_ERROR, ("!Driver Send failure, retry %u\n",nRetries));
} while (nRetries ++ < 8);
KITL_RETAILMSG(ZONE_SEND, (
"-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;
KITL_RETAILMSG(ZONE_RECV, (
"+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);
KITL_RETAILMSG(ZONE_RECV, ("-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)
{
KITL_RETAILMSG(ZONE_KITL_OAL, ("+KitlEthEnableInt(%d)\r\n", enable));
if (enable) {
g_kitlEthState.pDriver->pfnEnableInts();
} else {
g_kitlEthState.pDriver->pfnDisableInts();
}
KITL_RETAILMSG(ZONE_KITL_OAL, ("-KitlEthEnableInt\r\n"));
}
//------------------------------------------------------------------------------
//
// Function: OALIoCtlVBridge
//
// This function implements OEMKitlIoctl calls, e.g. VMINI related IOCTL codes.
//
BOOL OALIoCtlVBridge(
UINT32 code, VOID *pInBuffer, UINT32 inSize, VOID *pOutBuffer,
UINT32 outSize, UINT32 *pOutSize
) {
BOOL rc = TRUE;
KITL_RETAILMSG(ZONE_SEND|ZONE_RECV, ("+OALIoCtlVBridge(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:
NKSetLastError (ERROR_NOT_SUPPORTED);
rc = FALSE;
}
KITL_RETAILMSG(ZONE_SEND|ZONE_RECV, ("-OALIoCtlVBridge(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
// and 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;
KITL_RETAILMSG(ZONE_KITL_OAL, (
"+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) {
KITL_RETAILMSG(ZONE_ERROR, ("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)
)) {
KITL_RETAILMSG(ZONE_ERROR, (
"ERROR: KITL call to pfnInitDmaBuffer failed\r\n"
));
goto cleanUp;
}
}
// Call pfnInit
if (!pDriver->pfnInit(
(UCHAR*)pArgs->devLoc.PhysicalLoc, pArgs->devLoc.LogicalLoc, pArgs->mac
)) {
KITL_RETAILMSG(ZONE_ERROR, ("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
KITL_RETAILMSG(ZONE_INIT, ("KITL: *** Device Name %s ***\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 {
if (!OEMIoControl(
IOCTL_HAL_REQUEST_IRQ, &pArgs->devLoc, sizeof(pArgs->devLoc),
&irq, sizeof(irq), NULL
)) {
KITL_RETAILMSG(ZONE_WARNING, (
"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) {
UINT32 aIrqs[3];
aIrqs[0] = -1;
aIrqs[1] = (pArgs->devLoc.IfcType == InterfaceTypeUndefined)
? OAL_INTR_TRANSLATE
: OAL_INTR_FORCE_STATIC;
aIrqs[2] = irq;
if (
OEMIoControl(
IOCTL_HAL_REQUEST_SYSINTR, aIrqs, sizeof(aIrqs), &sysIntr,
sizeof(sysIntr), NULL
) && sysIntr != SYSINTR_UNDEFINED
) {
KITL_RETAILMSG(ZONE_INIT, ("KITL: using sysintr 0x%x\r\n", sysIntr));
} else {
KITL_RETAILMSG(ZONE_WARNING, (
"WARN: KITL can't obtain SYSINTR for IRQ %d\r\n", irq
));
sysIntr = KITL_SYSINTR_NOINTR;
}
} else {
sysIntr = KITL_SYSINTR_NOINTR;
}
}
if (sysIntr == KITL_SYSINTR_NOINTR) {
KITL_RETAILMSG(ZONE_WARNING, (
"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;
#ifdef KITL_ETHER
// Activate VMINI bridge...
if ((pArgs->flags & OAL_KITL_FLAGS_VMINI) != 0) {
VBridgeInit();
VBridgeKSetLocalMacAddress((char*)pArgs->mac);
}
#endif
// Result depends on fact if we get IP address
rc = (g_kitlEthState.deviceIP != 0);
cleanUp:
KITL_RETAILMSG(ZONE_KITL_OAL, ("-OALKitlEthInit(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -