📄 csend.c
字号:
#ifdef CS_DEBUG_ENABLE
pCS->TxQueueDepth = 0;
pCS->MaxTxQueueDepth = 0;
#endif
/* Initialize local queues */
pCS->pTxBuffFreeList = &TxBuffFreeList;
pCS->pRxBuffProcessList = &RxBuffProcessList;
pCS->pTxQueue = &TxQueue;
csInitQueue( pCS->pTxBuffFreeList );
csInitQueue( pCS->pRxBuffProcessList );
csInitQueue( pCS->pTxQueue );
/* Allocate the receive frame buffers */
if ( csInitRxBuff(pCS) == ERROR )
{
#ifdef CS_DEBUG_ENABLE
logMsg("csEndLoad: CS_END_DEVICE %d Can not allocate receive buffers\n",
pCS->unit,0,0,0,0,0 );
#endif
return NULL;
}
/* Verify that it is the correct chip */
if ( csVerifyChip(pCS) == ERROR )
{
#ifdef CS_DEBUG_ENABLE
logMsg("csEndLoad: CS_END_DEVICE %d, csVerifyChip failed\n",
pCS->unit,0,0,0,0,0 );
#endif
return NULL;
}
/* Get any CS8900 parameters not specifed in network interface table */
if ( sysEnetGetConfig(pCS) == ERROR )
{
#ifdef CS_DEBUG_ENABLE
logMsg("csEndLoad: CS_END_DEVICE %d, sysEnetGetConfig failed\n",
pCS->unit,0,0,0,0,0 );
#endif
return NULL;
}
/* Get Ethernet addr in BSP-specific manner*/
if ( sysEnetAddrGet(pCS,pCS->enetAddr) == ERROR )
{
#ifdef CS_DEBUG_ENABLE
logMsg("csEndLoad: CS_END_DEVICE %d, sysEnetAddrGet failed\n",
pCS->unit,0,0,0,0,0 );
#endif
return NULL;
}
/* initialize the END and MIB2 parts of the structure
* The M2 element must come from m2Lib.h
* This template is set up for a DIX type ethernet device.
*/
status1 = END_OBJ_INIT (&pCS->end, (DEV_OBJ *)pCS, (char *)CS_NAME,
pCS->unit, &endFuncTable,
"MUX-based Cirrus Logic CS8900 Ethernet Driver.");
status2 = END_MIB_INIT (&pCS->end, M2_ifType_ethernet_csmacd,
&pCS->enetAddr[0], 6,
ETHERMTU, END_SPEED);
if ((status1 == ERROR) || (status2 == ERROR))
{
#ifdef CS_DEBUG_ENABLE
logMsg("csEndLoad: CS_END_DEVICE %d, END_OBJ_INIT or END_MIB_INIT failed\n",
pCS->unit,0,0,0,0,0 );
#endif
return( NULL );
}
/* Reset the chip */
if ( csResetChip(pCS) == ERROR )
{
#ifdef CS_DEBUG_ENABLE
logMsg("csEndLoad: CS_END_DEVICE %d, Can not reset chip\n",
pCS->unit,0,0,0,0,0 );
#endif
return NULL;
}
/* set the flags to indicate readiness */
END_OBJ_READY (&pCS->end, IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST );
/* Set promiscuous mode if user asked for. */
if ( pCS->ConfigFlags & CFGFLG_PROMISC_MODE )
{
END_FLAGS_SET(&pCS->end, IFF_PROMISC);
}
#ifdef CS_DEBUG_ENABLE
logMsg("csEndLoad: CS_END_DEVICE %d, csEndLoad has finished successfully!\n",
pCS->unit,0,0,0,0,0 );
#endif
return (&pCS->end);
}
/*******************************************************************************
*
* csParse - parse the init string
*
* Parse the input string. Fill in values in the driver control structure.
*
* The initialization string format is:
* "Unit:IOAdr:IntLevel:MemAddr:MediaType:ConfigFlags"
*
* .bS
*
* unit Device unit number, a small integer, Decimal.
*
* IOAdr IO address, Hexadecimal.
*
* intLevel Interrupt level, Hexadecimal.
*
* memAddr Memory Address, Hexadecimal.
*
* mediaType Media Type, Decimal.
*
* cofigFlag Configuration flags. See definition of flags in csEnd.h, Hexadecimal.
*
*
*
* .bE
*
* RETURNS: NULL for invalid arguments or Pointer to CS_END_DEVICE for the device.
*/
CS_END_DEVICE *csParse (
char *initString /* information string */
)
{
char* tok;
char* pHolder = NULL;
int unit;
unsigned long tmp_long;
unsigned short tmp_short;
CS_END_DEVICE *pCS;
/* Parse the initString */
/* Unit number. */
tok = strtok_r (initString, ":", &pHolder);
if (tok == NULL)
return NULL;
unit = atoi(tok);
if ( unit >= CS_MAX_NUM_UNITS )
{
#ifdef CS_DEBUG_ENABLE
logMsg("csEndLoad: Invalid unit number (%d)\n", unit,0,0,0,0,0 );
#endif
return NULL;
}
pCS = &cs_end[unit];
pCS->unit =unit;
/* Save the passed-in parameters */
tok = strtok_r (NULL, ":", &pHolder);
if (tok == NULL)
{
return NULL;
}
tmp_long = strtoul (tok, NULL, 16);
pCS->IOAddr= tmp_long;
tok = strtok_r (NULL, ":", &pHolder);
if (tok == NULL) return NULL;
tmp_short = (USHORT )strtoul(tok, NULL, 16);
pCS->IntLevel= tmp_short;
/* The intVector value is used for intConnect() to
* connect ISR() to the interrupt vector number.
* In intConnect(), we pass INUM_TO_IVEC((ULONG)pCS->IntVector) as the 1st parameter.
* If the processor type is Intel x86, It is automatically calculated by
* "pCS->IntVector = sysVectorIRQ0 + pCS->IntLevel;" for x86.
* For non-x86 processors, just let IntVector = IntLevel.
*/
#if CPU_FAMILY == I80X86
pCS->IntVector = sysVectorIRQ0 + pCS->IntLevel;
#else
pCS->IntVector = pCS->IntLevel;
#endif
tok = strtok_r (NULL, ":", &pHolder);
if (tok == NULL) return NULL;
tmp_long = strtoul (tok, NULL, 16);
pCS->pPacketPage= (unsigned short *)tmp_long;
tok = strtok_r (NULL, ":", &pHolder);
if (tok == NULL) return NULL;
tmp_short = (USHORT )atoi(tok);
pCS->MediaType = tmp_short;
tok = strtok_r (NULL, ":", &pHolder);
if (tok == NULL) return NULL;
tmp_long = (USHORT)strtoul (tok, NULL, 16);
pCS->ConfigFlags = tmp_long;
#ifdef CS_DEBUG_ENABLE
logMsg("csParser(): IOAddr=0X%X, IntLevel=0X%X, IntVect=0X%X,
MemBase=0X%X, MediaType=%d, ConfigFlag=0X%X\n",
pCS->IOAddr,pCS->IntLevel,pCS->IntVector,(unsigned int)pCS->pPacketPage,
pCS->MediaType, pCS->ConfigFlags );
#endif
return pCS;
}
/*******************************************************************************
*
* csInitRxBuff -
*
* This routine initializes the network interface driver's collection of
* receive buffers. The receive buffers are allocated from system memory
* and linked together in a linked list of free receive buffers.
*
* RETURNS: OK or ERROR.
*/
LOCAL STATUS csInitRxBuff( CS_END_DEVICE *pCS )
{
M_CL_CONFIG endMclBlkConfig= /* network mbuf configuration table */
/* no. mBlks no. clBlks memArea memSize
--------- ---------- ------- ------- */
{ 0, 0, NULL, 0 };
CL_DESC endClDescTbl []= { /* network cluster pool configuration table */
/* clusterSize num memArea memSize
------------ ---------------- ------- ------- */
{END_BUFSIZE, CS_NUM_RX_BUFFERS, NULL, 0}
};
int endClDescTblNumEnt;
/* Allocate Memory for Clusters used by RX buffers */
if ((pCS->end.pNetPool = malloc(sizeof(NET_POOL))) == NULL)
return (ERROR);
endMclBlkConfig.mBlkNum = 2*CS_NUM_RX_BUFFERS;
endMclBlkConfig.clBlkNum = CS_NUM_RX_BUFFERS;
/* Calculate the total memory for all the M-Blks and CL-Blks. */
endMclBlkConfig.memSize = (endMclBlkConfig.mBlkNum * (MSIZE + sizeof (long))) +
(endMclBlkConfig.clBlkNum * (CL_BLK_SZ + sizeof(long)));
if ((endMclBlkConfig.memArea = (char *) memalign (sizeof(long),
endMclBlkConfig.memSize)) == NULL)
{
#ifdef CS_DEBUG_ENABLE
logMsg("csInitRxBuff: Unit=%d Memory unavailable. memalign() Failed!\n",
pCS->unit, 0, 0, 0, 0, 0);
#endif
return (ERROR);
}
/* Calculate the memory size of all the clusters. */
endClDescTbl[0].memSize = (endClDescTbl[0].clNum * (END_BUFSIZE + 8))
+ sizeof(int);
/* Allocate the memory for the clusters from cache safe memory. */
endClDescTbl[0].memArea =(char *) cacheDmaMalloc(endClDescTbl[0].memSize);
if ((int)endClDescTbl[0].memArea == NULL)
{
#ifdef CS_DEBUG_ENABLE
logMsg("csInitRxBuff: Unit=%d System memory unavailable\n",
pCS->unit, 0, 0, 0, 0, 0);
#endif
return (ERROR);
}
endClDescTblNumEnt = (NELEMENTS(endClDescTbl));
/* Initialize the memory pool. */
if (netPoolInit(pCS->end.pNetPool, &endMclBlkConfig,
&endClDescTbl[0], endClDescTblNumEnt, NULL) == ERROR)
{
#ifdef CS_DEBUG_ENABLE
logMsg("csInitRxBuff: Unit=%d Could not init buffering\n",
pCS->unit, 0, 0, 0, 0, 0);
#endif
return (ERROR);
}
/* Store the cluster pool id as others need it later. */
pCS->pClPoolId = netClPoolIdGet(pCS->end.pNetPool, (int)END_BUFSIZE, (BOOL)FALSE);
if (pCS->pClPoolId == NULL)
{
#ifdef CS_DEBUG_ENABLE
logMsg("csInitRxBuff: Unit=%d Could not memory cluster ID\n",
pCS->unit, 0, 0, 0, 0, 0);
#endif
return (ERROR);
}
return OK;
}
/*******************************************************************************
*
* csVerifyChip -
*
* This routine verifies that the Ethernet chip is present and correct.
*
*/
LOCAL STATUS csVerifyChip( CS_END_DEVICE *pCS )
{
USHORT wrVal, rdVal;
USHORT errorCount = 0;
USHORT x=0xFFFF;
/* Verify that we can read from the chip */
x = csReadPacketPage( pCS, PKTPG_EISA_NUM );
if ( x == 0xFFFF )
{
#ifdef CS_DEBUG_ENABLE
logMsg("csVerifyChip: CS_END_DEVICE %d, can't read from chip (I/O address correct?)\n",
pCS->unit, 0,0,0,0,0 );
#endif
return ERROR;
}
/* Verify that the chip is a Crystal Semiconductor chip */
if ( x != EISA_NUM_CRYSTAL )
{
#ifdef CS_DEBUG_ENABLE
logMsg("csVerifyChip: CS_END_DEVICE %d, Chip is not a Crystal Semiconductor chip\n",
pCS->unit, 0,0,0,0,0 );
#endif
return ERROR;
}
/* Verify that the chip is a CS8900 */
x = csReadPacketPage(pCS,PKTPG_PRODUCT_ID);
x &= PROD_ID_MASK;
if ( x != PROD_ID_CS8900)
{
#ifdef CS_DEBUG_ENABLE
logMsg("csVerifyChip: CS_END_DEVICE %d, Chip is not a CS8900p\n",
pCS->unit, 0,0,0,0,0 );
#endif
return ERROR;
}
/* walk a one in the memory of the enet controller */
for( wrVal = 0x0001; wrVal != 0; wrVal <<= 1 )
{
for( x=0x150; x<= 0x15d; x+=2 )
{
/* write out value - don't swap bytes */
csWritePacketPage( pCS, x, wrVal );
/* read back value - don't swap bytes */
rdVal = csReadPacketPage( pCS, x );
if( wrVal != rdVal )
{
if( errorCount <=10 )
{
#ifdef CS_DEBUG_ENABLE
logMsg("csVerifyChip: ERROR reg %04X, wrVal %04X, rdVal %04X\n",
x, (unsigned int) BYTE_SWAP(wrVal),
(unsigned int) BYTE_SWAP(rdVal),0,0,0 );
#endif
}
errorCount++;
}
}
} /* end walking one test */
/* write incrementing value test */
for( x=0x150, wrVal=0x0101; x<= 0x15d; x+=2, wrVal+=0x0101 )
{
/* write out value - don't worry about swapping bytes */
csWritePacketPage( pCS, x, wrVal );
}
/* read incrementing value test */
for( x=0x150, wrVal=0x0101; x<= 0x15d; x+=2, wrVal+=0x0101 )
{
/* read back value - don't worry about swapping bytes */
rdVal = csReadPacketPage( pCS, x );
if( wrVal != rdVal )
{
#ifdef CS_DEBUG_ENABLE
logMsg("\ncsVerifyChip: ERROR reg %04X, wrVal %04X, rdVal %04X\n",
x, (unsigned int) BYTE_SWAP(wrVal),
(unsigned int) BYTE_SWAP(rdVal),0,0,0 );
#endif
errorCount++;
}
} /* end walking one test */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -