⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lan91c111.c

📁 CS8900测试文件(整个工程) 环境:VDSP4.0
💻 C
📖 第 1 页 / 共 4 页
字号:
	// 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 + -