📄 lan91c111.c
字号:
// check for errors if required
#if defined(ADI_ETHER_DEBUG)
if ((Result = ValidatePDDHandle(PDDHandle)) != ADI_DEV_RESULT_SUCCESS) return (Result);
#endif
dev->Closing = true;
dev->Open = false;
if (dev->Started) {
dev->Started = false;
// wait for the current frames to complete
}
// return
return(Result);
}
/*********************************************************************
*
* Function: pddWrite
*
* Description: Sends packet over the physical channel
*
*********************************************************************/
static u32 adi_pdd_Write( // Writes data or queues an outbound buffer to a device
ADI_DEV_PDD_HANDLE PDDHandle, // PDD handle
ADI_DEV_BUFFER_TYPE BufferType, // buffer type
ADI_DEV_BUFFER *pBuffer // pointer to buffer
)
{
u32 Result; // return value
ADI_ETHER_LAN91C111_DATA *dev = (ADI_ETHER_LAN91C111_DATA *)PDDHandle;
ADI_G(("want write +++.\n"));
// check for errors if required
#if defined(ADI_ETHER_DEBUG)
if ((Result = ValidatePDDHandle(PDDHandle)) != ADI_DEV_RESULT_SUCCESS) return (Result);
if (BufferType != DEV_1D) {
return (ADI_DEV_BUFFER_TYPE_INCOMPATIBLE);
}
if (!dev->Start) {
return ADI_DEV_RESULT_INVALID_SEQUENCE;
}
#endif
if(pBuffer==0x1C) printf("adi_pdd_Write 0x1C\n");
QueueNewXmtFrames((void*)PDDHandle,(ADI_ETHER_BUFFER*)pBuffer);
return(ADI_DEV_RESULT_SUCCESS);
}
/*********************************************************************
*
* Function: pddControl
*
* Description: List of I/O control commands to the driver
*
*********************************************************************/
static u32 adi_pdd_Control( // Sets or senses a device specific parameter
ADI_DEV_PDD_HANDLE PDDHandle, // PDD handle
u32 Command, // command ID
void *pArg // pointer to argument
)
{
u32 Result; // return value
ADI_ETHER_LAN91C111_DATA *dev = (ADI_ETHER_LAN91C111_DATA *)PDDHandle;
ADI_ETHER_MEM_SIZES *msizes;
ADI_ETHER_SUPPLY_MEM *memsup;
int maxbuf,i;
u32 *prefix;
ADI_ETHER_BUFFER_COUNTS *bufcnts;
ADI_ETHER_IVG_MAPPING *ivgs;
// check for errors if required
#if defined(ADI_ETHER_DEBUG)
if ((Result = ValidatePDDHandle(PDDHandle)) != ADI_DEV_RESULT_SUCCESS) return (Result);
if (BufferType != DEV_1D) {
return (ADI_DEV_BUFFER_TYPE_INCOMPATIBLE);
}
#endif
// avoid casts
Result = ADI_DEV_RESULT_SUCCESS;
// CASEOF (Command ID)
switch (Command) {
case ADI_DEV_CMD_SET_DATAFLOW:
// enable or disable accordingly
dev->FlowEnabled = (int)pArg;
break;
case ADI_DEV_CMD_GET_PERIPHERAL_DMA_SUPPORT:
// no we dont want peripheral DMA suppot
(*(int *)pArg) = false;
break;
case ADI_ETHER_CMD_MEM_SIZES:
msizes = (ADI_ETHER_MEM_SIZES *)pArg;
msizes->BaseMemSize = sizeof(ADI_ETHER_STATISTICS_COUNTS);
msizes->MemPerRecv = 0;
msizes->MemPerXmit = 0;
break;
case ADI_ETHER_CMD_SUPPLY_MEM:
memsup = (ADI_ETHER_SUPPLY_MEM *)pArg;
if (memsup->BaseMemLength < sizeof(ADI_ETHER_STATISTICS_COUNTS)) {
Result = ADI_DEV_RESULT_NO_MEMORY;
} else {
dev->Stats = memsup->BaseMem;
memset(dev->Stats,0,sizeof(ADI_ETHER_STATISTICS_COUNTS));
}
break;
case ADI_ETHER_CMD_GET_MAC_ADDR:
GetMacAddr((unsigned char *)pArg);
break;
case ADI_ETHER_CMD_SET_MAC_ADDR:
SetupMacAddr((unsigned char *)pArg);
// store mac in an internel variable
memcpy(dev->phyAddr,(unsigned char*)pArg,6);
break;
case ADI_ETHER_CMD_GET_STATISTICS:
memcpy(pArg,dev->Stats,sizeof(ADI_ETHER_STATISTICS_COUNTS));
break;
case ADI_ETHER_CMD_GET_BUFFER_PREFIX:
prefix = (u32 *)pArg;
*prefix = 0;
break;
case ADI_ETHER_CMD_UNPROCESSED_BUFFER_COUNTS:
bufcnts = (ADI_ETHER_BUFFER_COUNTS *)pArg;
bufcnts->RcvrBufferCnt = dev->m_RxEnqueuedCount;
bufcnts->XmitBufferCnt = dev->m_TxEnqueuedCount;
break;
case ADI_ETHER_CMD_GET_MIN_RECV_BUFSIZE:
prefix = (u32 *)pArg;
*prefix = MAX_RCVE_FRAME;
break;
case ADI_ETHER_CMD_USBLAN_USE_IVG:
ivgs = (ADI_ETHER_IVG_MAPPING *)pArg;
dev->RXIVG = (interrupt_kind)ivgs->RxIVG;
dev->TXIVG = (interrupt_kind)ivgs->TxIVG;
dev->ERRIVG = (interrupt_kind)ivgs->ErrIVG;
break;
case ADI_ETHER_CMD_USBLAN_USE_DMA:
Result = ADI_DEV_RESULT_NOT_SUPPORTED;
break;
case ADI_ETHER_CMD_GEN_CHKSUMS:
Result = ADI_DEV_RESULT_NOT_SUPPORTED;
break;
case ADI_ETHER_CMD_SET_SPEED: // Default Auto Nego mode
i = (int)pArg;
if ((i <= 0) || (i > 2)) {
Result = ADI_DEV_RESULT_NOT_SUPPORTED;
} else {
dev->Port100 = (i == 2);
dev->Auto = false;
}
break;
case ADI_ETHER_CMD_SET_FULL_DUPLEX:
i = (int)(pArg);
dev->FullDuplex = (i!=0);
dev->Auto = false;
break;
case ADI_ETHER_CMD_SET_NEGOTIATE:
i = (int)(pArg);
dev->Auto = (i!=0);
break;
case ADI_DEV_CMD_SET_DATAFLOW_METHOD:
break;
case ADI_ETHER_CMD_SET_LOOPBACK:
i = (int)(pArg);
dev->Loopback = (i!=0);
if (dev->Started) {
// change the phy
u16 cur;
cur = LAN91C111_read_phy_register(PHY_CNTL_REG);
if (dev->Loopback) {
cur |= (1 << 14); // enable TX->RX loopback
} else {
cur &= (~(1 << 14));
}
LAN91C111_write_phy_register(PHY_CNTL_REG,cur);
}
break;
case ADI_ETHER_CMD_GET_PHY_REGS:
{
short *arg = (short *)pArg;
int ic;
for (ic=0;ic<=PHY_MASK_REG;ic++) arg[ic] = LAN91C111_read_phy_register(ic);
}
break;
case ADI_ETHER_CMD_BUFFERS_IN_CACHE:
i = (int)(pArg);
dev->Cache = (i!=0);
break;
case ADI_ETHER_CMD_START:
if (dev->RxStarted) {
StartMac(PDDHandle);
} else {
Result = ADI_DEV_RESULT_INVALID_SEQUENCE;
}
break;
case ADI_DEV_CMD_TABLE:
break;
case ADI_DEV_CMD_END:
break;
default:
smsc_sleep(0);
// we don't understand this command
Result = ADI_DEV_RESULT_NOT_SUPPORTED;
}
// return
return(Result);
}
#pragma section("Merge")
inline short inw(addr) {
short ret;
//asm("p0 = r0;");
//asm("prefetch [p0]");
//asm("prefetch [p0];");
ret = *(short *)addr;
return ret;
}
#pragma section("Merge")
inline void outw(x,addr){
short * pAddr;
pAddr = (short *)addr;
*pAddr = x;
/* asm("prefetch [p1++];");
asm("prefetch [p1++];");
asm("prefetch [p1++];");
asm("prefetch [p1++];");
asm("prefetch [p1++];");
asm("prefetch [p1++];");
asm("prefetch [p1++];");
*/
}
#pragma section("Merge")
inline int readreg(struct net_device *dev, int portno) {
short ret;
outw(portno, dev->base_addr + ADD_PORT);
ret = inw(dev->base_addr + DATA_PORT);
return ret;
}
#pragma section("Merge")
inline void writereg(struct net_device *dev, int portno, int value) {
outw(portno, dev->base_addr + ADD_PORT);
outw(value, dev->base_addr + DATA_PORT);
}
#pragma section("Merge")
inline int readword(struct net_device *dev, int portno) {
return inw(dev->base_addr + portno);
}
#pragma section("Merge")
inline void writeword(struct net_device *dev, int portno, int value) {
outw(value, dev->base_addr + portno);
}
#pragma section("Merge")
void writeblock(struct net_device *dev, char *pData, int Length) {
int i;
for (i = 0 ; i < (Length/2); i++) {
writeword(dev, TX_FRAME_PORT, *(u16 *)pData );
pData += 2;
}
if (Length % 2) {
u16 OddWordValue = *pData;
writeword(dev, TX_FRAME_PORT, OddWordValue);
}
}
#pragma section("Merge")
void readblock(struct net_device *dev, char *pData, int Length) {
u16 InputWord;
int i;
for (i=0; i < (Length/2); i++) {
InputWord = readword(dev, RX_FRAME_PORT);
*(u8*)pData++ = (u8) InputWord & 0xFF;
*(u8*)pData++ = (u8) (InputWord >> 8) & 0xFF;
}
if (Length & 0x1)
*pData = (u8) (readword(dev, RX_FRAME_PORT) & 0xff);
//memcpy( (char *)pData ,(char *)(BASE + (PP_RxFrame<<1 )), Length );//(Length>>1)*2);
/*if(Length&1)
pData[Length-1]=(u8) (readword(dev, RX_FRAME_PORT) & 0xff);
*/
}
#pragma optimize_off
void cs8900a_probe(struct net_device *dev)
{
//read ID
int rev_type,i, chip_type,chip_revision;
rev_type = readreg(dev, PRODUCT_ID_ADD);
chip_type = rev_type&~REVISON_BITS;
chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
printf("Found CS89%c0 rev %c chipset.\n",chip_type == CS8900?'0':'2',chip_revision);
//reset chip
for(i=0;i<1;i++)
writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET);
//wait 30 ms
for(i=0;i<100000000;i++){
i++;
}
//wait until reset done
while( (readreg(dev, PP_SelfST) & INIT_DONE) == 0){
i++;
}
//reset for get mac!
}
#pragma optimize_off
int delay(int d)
{
int i =0;
for(i=0;i<d;i++){
i++;
}
return i;
}
#pragma optimize_off
int net_open(struct net_device *dev)
{
unsigned int jitter=0;
int time_out;
writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL) & ~ENABLE_IRQ);
delay(1000000);
//disable irq
writereg(dev, PP_CS8900_ISAINT, 0);//IRQ 0
delay(1000000);
writereg(dev, PP_BusCTL, MEMORY_ON ); //使能MEMORY模式
/* Set the LineCTL quintuplet */
delay(1000000);
jitter = readreg(dev,PP_LineST);
printf("PP_LineST :%x\n",jitter);
printf(" Set 10Bast-T full duplex ");
writereg(dev, PP_LineCTL, readreg(dev,PP_LineCTL) & ~ AUI_ONLY);
while(!jitter){
int i =0;
for(;i<10;i++);
jitter = readreg(dev,PP_LineST)&LINK_OK;
printf(". ");
}
printf("Ok.\n");
delay(10000000);
printf("PP_LineST :%x\n",readreg(dev,PP_LineST));
//writereg(dev,PP_TestCTL,readreg(dev,PP_TestCTL)|FDX_8900);
writereg(dev,PP_TestCTL,0x4019);
delay(10000000);
printf("PP_TestCTL : %x\n",readreg(dev,PP_TestCTL));
/* Turn on both receive and transmit operations */
writereg(dev, PP_LineCTL,
readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON);//使能TX/RX
/* Receive only error free packets addressed to this card */
delay(10000000);
writereg(dev, PP_RxCTL, DEF_RX_ACCEPT);//DEF_RX_ACCEPT);
delay(10000000);
writereg(dev, PP_RxCFG,RX_OK_ENBL );//| RX_CRC_ERROR_ENBL );
delay(10000000);
writereg(dev, PP_TxCFG,
TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL |
TX_LATE_COL_ENBL | TX_JBR_ENBL |
TX_ANY_COL_ENBL | TX_16_COL_ENBL);
delay(10000000);
writereg(dev, PP_BufCFG,
READY_FOR_TX_ENBL | RX_MISS_COUNT_OVRFLOW_ENBL |
TX_COL_COUNT_OVRFLOW_ENBL | TX_UNDERRUN_ENBL);
delay(10000000);
//writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL) | ENABLE_IRQ);
writereg(dev, PP_BusCTL, 0x8417);
delay(10000000);
printf("PP_BusCTL: %x\n",readreg(dev, PP_BusCTL));
//printf("PP_ISAIOB: %x\n",readreg(dev,PP_ISAIOB));
writereg(dev , PP_CS8900_ISAMemB,0);
printf("PP_CS8900_ISAMemB: %x\n",readreg(dev,PP_CS8900_ISAMemB));
delay(10000000);
// printf("PP_CS8900_ISAMemB: %x\n",readreg(dev,PP_CS8900_ISAMemB));
/* printf("0x%x\n",readreg(dev,PP_LineST));
if(jitter)
{*/
/*}
else
{
printf("Fail.\n");
}
*/
/* move to here */
/*
ret = request_irq(dev->irq, &net_interrupt, SA_INTERRUPT, "cs89x0", dev);
if (ret)
{
printk("%s: request_irq(%d) failed\n", dev->name, dev->irq);
goto bad_out;
}
enable_irq(dev->irq);
*/
}
int net_close(struct net_device *dev)
{
writereg(dev, PP_RxCFG, 0);
writereg(dev, PP_TxCFG, 0);
writereg(dev, PP_BufCFG, 0);
writereg(dev, PP_BusCTL, 0);
/* Update the statistics here. */
return 0;
}
/**************************************************************************
*
* Lan91c111 entry point
*
**************************************************************************/
ADI_DEV_PDD_ENTRY_POINT ADI_ETHER_USBLAN_Entrypoint = {
adi_pdd_Open,
adi_pdd_Close,
adi_pdd_Read,
adi_pdd_Write,
adi_pdd_Control
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -