hwcom.c
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 1,737 行 · 第 1/4 页
C
1,737 行
/*----------------------------------------------------------------------*/
#pragma NDIS_PAGEABLE_FUNCTION(HW_Setup_BD_List)
STATIC VOID HW_Setup_BD_List(IN BD *pFirstBD,
IN BD *pLastBD,
IN UINT bd_status,
IN PUCHAR pFirstBuffer,
IN UINT bufferSize)
/*++
Description:
Sets up the buffer descriptors for both the receive and
transmit queues. Called only by HW_Internal_Setup_BDs().
Arguments:
pFirstBD - address of first buffer descriptor to be initialized
pLastBD - address of last buffer descriptor to be initialized
bd_status - buffer descriptor status bits
pFirstBuffer - physical address of first data buffer
bufferSize - size of data buffers in bytes
Return Value:
None
--*/
{
BD *current_bd = pFirstBD;
PUCHAR buffer_addr = pFirstBuffer;
DEBUGMSG(ZONE_FUNCTION | ZONE_INIT,
(TEXT("+ETH8XX: HW_Setup_BD_List\r\n")));
while (current_bd <= pLastBD)
{
/* Initialize required buffer descriptor fields. */
current_bd->bd_status = bd_status;
current_bd->bd_length = 0;
current_bd->bd_addr = buffer_addr;
/* Buffer descriptors and data buffers are contiguous. */
current_bd++;
buffer_addr += bufferSize;
}
/* Set the wrap bit to complete circular list. */
pLastBD->bd_status |= ETH_RX_WRAP;
DEBUGMSG(ZONE_FUNCTION | ZONE_INIT,
(TEXT("-ETH8XX: HW_Setup_BD_List\r\n")));
}
/*----------------------------------------------------------------------*/
#pragma NDIS_PAGEABLE_FUNCTION(HW_Setup_Serial_If)
STATIC VOID HW_Setup_Serial_If(IN PETH8XX_ADAPTER Adapter)
/*++
Description:
Setup the serial interface registers in the CPM for Ethernet
mode. Only called from the HW_Setup() function.
Arguments:
Adapter - pointer to the NDIS miniport adapter block
Return Value:
None
--*/
{
DEBUGMSG(ZONE_FUNCTION | ZONE_INIT,
(TEXT("+ETH8XX: HW_Setup_Serial_If\r\n")));
/* Initialize the SICR register -- see section 16.12.5.3 (p. 16-120)
*
* SCC1: No Grant Mechanism, Transmit Clock=CLK1, Receive Clock=CLK2
*/
ADS_IMMR->si_sicr &= ETH_SICR_TX_RX_CLK_MASK;
ADS_IMMR->si_sicr |= ETH_SICR_RX_CLK2
| ETH_SICR_TX_CLK1;
/* Setup for normal Ethernet operation. */
ADS_IMMR->scc_regs[SCC_ETH_PARM].scc_gsmrb = ETH_GSMR_H_NORMAL;
ADS_IMMR->scc_regs[SCC_ETH_PARM].scc_gsmra = ETH_GSMR_L_TX_CLK_INV
| ETH_GSMR_L_TPL_48
| ETH_GSMR_L_TPP_10
| ETH_GSMR_L_MODE_ETH;
ADS_IMMR->scc_regs[SCC_ETH_PARM].scc_dsr = ETH_DATA_SYNC;
ADS_IMMR->scc_regs[SCC_ETH_PARM].scc_psmr = ETH_MODE_CCITT_CRC
| ETH_MODE_NIB_22;
if (Adapter->UseHeartbeat)
{
ADS_IMMR->scc_regs[SCC_ETH_PARM].scc_psmr |= ETH_MODE_HEARTBEAT;
}
DEBUGMSG(ZONE_FUNCTION | ZONE_INIT,
(TEXT("-ETH8XX: HW_Setup_Serial_If\r\n")));
}
/*----------------------------------------------------------------------*/
#pragma NDIS_PAGEABLE_FUNCTION(HW_Setup_Common_Protocol_Area)
STATIC VOID HW_Setup_Common_Protocol_Area(IN PETH8XX_ADAPTER Adapter)
/*++
Description:
Sets up the common parameter RAM in the CPM for Ethernet mode.
Arguments:
Adapter - pointer to the NDIS miniport adapter block
Return Value:
None
--*/
{
USHORT parm_area = SCC_ETH_PARM; /* access SCC parameter RAM. */
DEBUGMSG(ZONE_FUNCTION | ZONE_INIT,
(TEXT("+ETH8XX: HW_Setup_Common_Protocol_Area\r\n")));
/* Setup the buffer descriptor start pointers. Receive area base. */
ADS_IMMR->pram[parm_area].enet_scc.rbase = (USHORT) Adapter->FirstRxBD;
/* Transmit area base. */
ADS_IMMR->pram[parm_area].enet_scc.tbase = (USHORT) Adapter->FirstTxBD;
/* Setup function registers for Motorola (Big-endian) byte ordering. */
ADS_IMMR->pram[parm_area].enet_scc.rfcr = ETH_FCR_BIG_ENDIAN;
ADS_IMMR->pram[parm_area].enet_scc.tfcr = ETH_FCR_BIG_ENDIAN;
/* Setup the max. received buffer length. */
ADS_IMMR->pram[parm_area].enet_scc.mrblr = Adapter->MaxRxBufferSize;
DEBUGMSG(ZONE_FUNCTION | ZONE_INIT,
(TEXT("-ETH8XX: HW_Setup_Common_Protocol_Area\r\n")));
}
/*----------------------------------------------------------------------*/
#pragma NDIS_PAGEABLE_FUNCTION(HW_Setup_Eth_Protocol_Area)
STATIC VOID HW_Setup_Eth_Protocol_Area(IN PETH8XX_ADAPTER Adapter)
/*++
Description:
Sets up the Ethernet-specific parameter RAM in the CPM (as per the
descriptions in the MPC821 User's Guide).
Arguments:
Adapter - pointer to the NDIS miniport adapter block
Return Value:
None
--*/
{
DEBUGMSG(ZONE_FUNCTION | ZONE_INIT,
(TEXT("+ETH8XX: HW_Setup_Eth_Protocol_Area\r\n")));
/* Preset CRC */
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.c_pres = ETH_PRAM_PRESET_CRC;
/* Constant Mask for CRC */
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.c_mask = ETH_PRAM_CONST_CRC_MASK;
/* Error Counter CRC (unused) */
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.crcec = 0;
/* Alignment Error Counter (unused) */
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.alec = 0;
/* Discard Frame Counter (unused) */
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.disfc = 0;
/* Short Frame PAD Characters */
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.pads = ETH_PRAM_PAD_VALUE;
/* Retry Limit Threshold */
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.ret_lim = ETH_PRAM_RETRY_LIMIT;
/* MAX Frame Length Register */
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.mflr = ETH_PRAM_MAX_FRAME_LEN;
/* MIN Frame Length Register */
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.minflr = ETH_PRAM_MIN_FRAME_LEN;
/* MAX DMA1 Length Register */
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.maxd1 = ETH_BUFFER_SIZE;
/* MAX DMA2 Length Register */
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.maxd2 = ETH_BUFFER_SIZE;
/* Clear the Group address filters. */
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.gaddr1 = 0x0;
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.gaddr2 = 0x0;
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.gaddr3 = 0x0;
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.gaddr4 = 0x0;
/* Hardware Ethernet Address. */
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.paddr_h = (Adapter->StationAddr[5] << 8)
+ Adapter->StationAddr[4];
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.paddr_m = (Adapter->StationAddr[3] << 8)
+ Adapter->StationAddr[2];
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.paddr_l = (Adapter->StationAddr[1] << 8)
+ Adapter->StationAddr[0];
/* Persistence (unused) */
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.p_per = 0x0;
/* Clear the Individual address filters. */
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.iaddr1 = 0x0;
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.iaddr2 = 0x0;
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.iaddr3 = 0x0;
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.iaddr4 = 0x0;
/* Clear the temporary address fields. */
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.taddr_h = 0x0;
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.taddr_m = 0x0;
ADS_IMMR->pram[SCC_ETH_PARM].enet_scc.taddr_l = 0x0;
DEBUGMSG(ZONE_FUNCTION | ZONE_INIT,
(TEXT("-ETH8XX: HW_Setup_Eth_Protocol_Area\r\n")));
}
/*----------------------------------------------------------------------*/
STATIC BOOLEAN HW_Handshake_CPM_Init(IN PETH8XX_ADAPTER Adapter)
/*++
Description:
This function executes the CPM "INIT RX AND TX" command. Note
that TENA, GSMRA, and BCSR1 must still be configured before the
Ethernet interface is fully functional. This is done by calling
the HW_Toggle_Eth_If() function.
Arguments:
Adapter - pointer to the NDIS miniport adapter block
Return Value:
None
--*/
{
BOOLEAN rc;
DEBUGMSG(ZONE_FUNCTION | ZONE_INIT,
(TEXT("+ETH8XX: HW_Handshake_CPM_Init\r\n")));
/* Get the CPM to execute the INIT RX AND TX PARAMETERS command.
* Note that Ethernet is on SCC1 for MPC821ADS.
*/
rc = KernelIoControl(OEM_IOCTL_ISSUE_CPM_CMD, (LPVOID)SCC_ETH_CH_NUM,
INIT_RX_TX_PARAMS, (LPVOID) NOTUSED, (DWORD) NOTUSED,
(LPDWORD)NOTUSED);
if (!rc)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("*ETH8XX: KernelIoControl error issuing CPM init cmd\r\n")));
DEBUGMSG(ZONE_ERROR, (TEXT("*ETH8XX: Error Exit\r\n")));
Adapter->Status = DISABLED;
} else {
DEBUGMSG(ZONE_XMIT, (TEXT(" ETH8XX: transmitter enabled\r\n")));
Adapter->Status = ENABLED;
}
DEBUGMSG(ZONE_FUNCTION | ZONE_INIT,
(TEXT("-ETH8XX: HW_Handshake_CPM_Init\r\n")));
return(rc);
}
/*----------------------------------------------------------------------*/
STATIC VOID HW_Clear_Init_Events(IN PETH8XX_ADAPTER Adapter)
/*++
Description:
This function clears the initial events in the CPM.
Arguments:
Adapter - pointer to the NDIS miniport adapter block
Return Value:
None
--*/
{
DEBUGMSG(ZONE_FUNCTION | ZONE_INIT,
(TEXT("+ETH8XX: HW_Clear_Init_Events\r\n")));
/* Don't allow any interrupts. */
ADS_IMMR->scc_regs[SCC_ETH_PARM].scc_sccm = 0x0000;
/* Clear pending events (by writing "1" to each bit). */
ADS_IMMR->scc_regs[SCC_ETH_PARM].scc_scce = 0xFFFF;
DEBUGMSG(ZONE_FUNCTION | ZONE_INIT,
(TEXT("-ETH8XX: HW_Clear_Init_Events\r\n")));
}
/*----------------------------------------------------------------------*/
STATIC VOID HW_Configure_Interrupts(IN PETH8XX_ADAPTER Adapter)
/*++
Description:
This function performs the necessary interrupt setup in the CPM.
Arguments:
Adapter - pointer to the NDIS miniport adapter block
Return Value:
None
--*/
{
DEBUGMSG(ZONE_FUNCTION | ZONE_INIT,
(TEXT("+ETH8XX: HW_Configure_Interrupts\r\n")));
/* Clear any pending events. */
ADS_IMMR->scc_regs[SCC_ETH_PARM].scc_scce = 0xFFFF;
/* Setup subscribed events. */
ADS_IMMR->scc_regs[SCC_ETH_PARM].scc_sccm = ETH_TXB_EVENT
| ETH_BSY_EVENT
| ETH_RXF_EVENT
| ETH_TXE_EVENT
| ETH_GRA_EVENT
;
/* Note that interrupts are also configured in the OAL. */
DEBUGMSG(ZONE_FUNCTION | ZONE_INIT,
(TEXT("-ETH8XX: HW_Configure_Interrupts\r\n")));
}
/*----------------------------------------------------------------------*/
#pragma NDIS_PAGEABLE_FUNCTION(HW_Initialize)
BOOLEAN HW_Initialize(IN PETH8XX_ADAPTER Adapter)
/*++
Description:
Allocate and configure all buffer descriptors and data buffers
needed for Ethernet mode. Do this before configuring hardware
in case there is a problem with required memory allocations.
Arguments:
Adapter - pointer to the adapter block.
Return Value:
TRUE, if all goes well, else FALSE.
--*/
{
DEBUGMSG(ZONE_INIT | ZONE_FUNCTION,
(TEXT("+ETH8XX: HW_Initialize\r\n")));
/************************************************************************/
/* Get a handle to the Internal Memory Map Region in the CPM. */
/************************************************************************/
Adapter->Immr = HW_Get_IMMR();
if (Adapter->Immr == (PDA *)NULL)
{
DEBUGMSG(ZONE_INIT | ZONE_ERROR,
(TEXT("*ETH8XX: HW_Initialize: no access to IMMR\r\n")));
return(FALSE);
}
/************************************************************************/
/* Allocate CPM receive and transmit buffer descriptors. */
/************************************************************************/
if (HW_Allocate_BDs(Adapter) == FALSE)
{
DEBUGMSG(ZONE_INIT | ZONE_ERROR,
(TEXT("*ETH8XX: HW_Initialize: could not allocate BDs.\r\n")));
return(FALSE);
}
/************************************************************************/
/* Allocate the necessary buffers, i.e. Rx. and tx buffers, one of */
/* two path's will be taken depending on where the buffers are being */
/* allocated from (external vs. internal memory). */
/************************************************************************/
if (HW_Allocate_Buffers(Adapter) == FALSE)
{
DEBUGMSG(ZONE_INIT | ZONE_ERROR,
(TEXT("*ETH8XX: HW_Initialize: no buffers\r\n")));
return(FALSE);
}
/************************************************************************/
/* Setup the Rx and Tx Buffer descriptors in the dual-ported RAM. They */
/* will always be in the dual-ported RAM, i.e. they cannot be allocated */
/* from external RAM. */
/************************************************************************/
HW_Internal_Setup_BDs(Adapter);
Adapter->NbrMulticasts = 0;
DEBUGMSG(ZONE_INIT | ZONE_FUNCTION,
(TEXT("-ETH8XX: HW_Initialize\r\n")));
return(TRUE);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?