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

📄 xscale_linux_2.4.c

📁 基于pxa270的linux下smsc9118的网卡驱动源码
💻 C
📖 第 1 页 / 共 2 页
字号:
				flowControlParameters->BurstPeriod=0x41UL;

				flowControlParameters->IntDeas=0x21UL;

				break;

			default:break;//make lint happy

			}

		}

	} else {

		if(Platform_Is16BitMode(platformData)) {

			switch(platformData->dwIdRev&0xFFFF0000) {

			case 0x01180000UL:

			case 0x01170000UL:

			case 0x01120000UL:

			case 0x118A0000UL:

			case 0x117A0000UL:

				//117/118,16 bit,PIO

				flowControlParameters->MaxThroughput=0xAC3F4UL;

				flowControlParameters->MaxPacketCount=0x1D2UL;

				flowControlParameters->PacketCost=0x5FUL;

				flowControlParameters->BurstPeriod=0x72UL;

				flowControlParameters->IntDeas=0x02UL;

				break;

			case 0x01160000UL:

			case 0x01150000UL:

			case 0x116A0000UL:

			case 0x115A0000UL:

				//115/116,16 bit,PIO

				flowControlParameters->MaxThroughput=0x7295CUL;

				flowControlParameters->MaxPacketCount=0x136UL;

				flowControlParameters->PacketCost=0x00UL;

				flowControlParameters->BurstPeriod=0x6FUL;

				flowControlParameters->IntDeas=0x38UL;

				break;

			default:break;//make lint happy

			}

		} else {

			switch(platformData->dwIdRev&0xFFFF0000) {

			case 0x01180000UL:

			case 0x01170000UL:

			case 0x01120000UL:

			case 0x118A0000UL:

			case 0x117A0000UL:

				//117/118,32 bit,PIO

				flowControlParameters->MaxThroughput=0xCB4BCUL;

				flowControlParameters->MaxPacketCount=0x226;

				flowControlParameters->PacketCost=0x00UL;

				flowControlParameters->BurstPeriod=0x77UL;

				flowControlParameters->IntDeas=0x36UL;

				break;

			case 0x01160000UL:

			case 0x01150000UL:

			case 0x116A0000UL:

			case 0x115A0000UL:

				//115/116,32 bit,PIO

				flowControlParameters->MaxThroughput=0x9E338UL;

				flowControlParameters->MaxPacketCount=0x1ACUL;

				flowControlParameters->PacketCost=0x00UL;

				flowControlParameters->BurstPeriod=0x73UL;

				flowControlParameters->IntDeas=0x31UL;

				break;

			default:break;//make lint happy

			}

		}

	}

}



void PlatformDisplayInfo(void);

void PlatformDisplayInfo(void)

{

}



BOOLEAN PlatformPossibleIRQ(int Irq);

BOOLEAN PlatformPossibleIRQ(int Irq)

{

	Irq=Irq;//make lint happy

	return TRUE;

}



BOOLEAN Platform_RequestIRQ(

	PPLATFORM_DATA platformData,

	DWORD dwIrq,

	irqreturn_t (*pIsr)(int a,void *b,struct pt_regs *c),

	void * dev_id)

{

	SMSC_ASSERT(platformData!=NULL);

	

	if(dwIrq==0xFFFFFFFFUL) {

		dwIrq=LAN_IRQ;

	}



	if(request_irq(dwIrq, pIsr, SA_INTERRUPT, "SMSC_LAN9118_ISR", dev_id)!=0)

	{

		SMSC_WARNING("Unable to use IRQ = %ld",dwIrq);

		return FALSE;

	}



	platformData->dwIrq = dwIrq;

	platformData->dev_id = dev_id;

	return TRUE;

}



DWORD Platform_CurrentIRQ(PPLATFORM_DATA platformData)

{

	SMSC_ASSERT(platformData!=NULL);

	return platformData->dwIrq;

}

void Platform_FreeIRQ(PPLATFORM_DATA platformData)

{

	if(platformData!=NULL) {

		free_irq(platformData->dwIrq,platformData->dev_id);

		platformData->dwIrq=0;

	} else {

		SMSC_ASSERT(FALSE);

	}

}



BOOLEAN Platform_DmaDisable(

	PPLATFORM_DATA platformData, const DWORD dwDmaCh)

{	

	// To avoid Lint error

	DWORD	temp;

	temp = dwDmaCh;

	temp = temp;



	platformData=platformData;//make lint happy



	DCSR(dwDmaCh) &= ~DCSR_RUN;

	while (!(DCSR(dwDmaCh) & DCSR_STOPSTATE)) {};



	return TRUE;

}



BOOLEAN Platform_DmaInitialize(PPLATFORM_DATA platformData, DWORD dwDmaCh)

{

	if(dwDmaCh<256)

		if(!Platform_DmaDisable(platformData, dwDmaCh)) {

			return FALSE;

		}



	return TRUE;

}



void PurgeCache(

	const void * const pStartAddress, 

	const DWORD dwLengthInBytes);

void PurgeCache(

	const void * const pStartAddress, 

	const DWORD dwLengthInBytes)

{

	DWORD dwCurrAddr, dwEndAddr, dwLinesToGo;

	

	dwCurrAddr = (DWORD)pStartAddress & CACHE_ALIGN_MASK;

	dwEndAddr = (((DWORD)pStartAddress) + dwLengthInBytes + (CACHE_LINE_BYTES - 1UL)) & CACHE_ALIGN_MASK;



	dwLinesToGo = (dwEndAddr - dwCurrAddr) / CACHE_LINE_BYTES;

	while (dwLinesToGo)

	{

		CleanCacheLine(dwCurrAddr);

		dwCurrAddr += CACHE_LINE_BYTES;

		dwLinesToGo--;

	}

	DrainWriteBuffers();



	return;	

}



void Platform_CacheInvalidate(PPLATFORM_DATA platformData, const void * const pStartAddress, const DWORD dwLengthInBytes)

{

	platformData=platformData;//make lint happy

	PurgeCache(pStartAddress, dwLengthInBytes);

}



void Platform_CachePurge(PPLATFORM_DATA platformData, const void * const pStartAddress, const DWORD dwLengthInBytes)

{

	platformData=platformData;//make lint happy

	PurgeCache(pStartAddress, dwLengthInBytes);

}



/*

 * SRAM Mapping on Linux:

 *		Physical Address = 0xA000_0000 - 0xA3FF_FFFF (Size = 64MB)

 *		Virtual Address  = 0xC000_0000 - 0xC3FF_FFFF (Size = 64MB)

 *

 * Expansion Card (LAN9118) Mapping on Linux 2.4:

 *		Physical Address = 0x1400_0000 - 0x140F_FFFF (Size = 1MB)

 *      Virtual Address  = 0xF200_0000 - 0xF20F_FFFF (Size = 1MB)



 * Expansion Card (LAN9118) Mapping on Linux 2.6:

 *		Physical Address = 0x1400_0000 - 0x140F_FFFF (Size = 1MB)

 *      Virtual Address  = 0xF500_0000 - 0xF50F_FFFF (Size = 1MB)

 *		

 */

DWORD CpuToPhysicalAddr(const void * const pvCpuAddr);

DWORD CpuToPhysicalAddr(const void * const pvCpuAddr)

{

	const DWORD dwVirtAddr = (DWORD) pvCpuAddr;

	if ((dwVirtAddr >= MST_EXP_BASE) && (dwVirtAddr <= (MST_EXP_BASE+0xFFFFFUL)))

//	if ((dwVirtAddr >= 0xF2000000UL) && (dwVirtAddr <= 0xF20FFFFFUL))

	{

		//Expansion card memory

		return ((dwVirtAddr - MST_EXP_BASE) + MST_EXP_PHYS);

	}

	if ((dwVirtAddr >= 0xC0000000UL) && (dwVirtAddr <= 0xC3FFFFFFUL))

	{

		// Linux SDRAM

		return virt_to_bus(((void *)dwVirtAddr));

	}



	SMSC_WARNING("Wrong virtual address : 0x%08lx", dwVirtAddr);

	return (0xFFFFFFFFUL); //invalid/unrecognized address

}



BOOLEAN Platform_DmaStartXfer(PPLATFORM_DATA platformData, const DMA_XFER * const pDmaXfer)

{



	DWORD dwDmaCmd;

	DWORD dwLanPhysAddr, dwMemPhysAddr;

	DWORD dwAlignMask;



	platformData=platformData;//make lint happy



	//Validate the channel#

	/*

	if (pDmaXfer->dwDmaCh != 0UL) //always use channel 0 on XScale

	{

		printf("DMAStartXfer -- bad dwDmaCh=%ld\n", pDmaXfer->dwDmaCh);

		return FALSE;

	}

	*/



	//Check if the channel is currently running

	if (!(DCSR(pDmaXfer->dwDmaCh) & DCSR_STOPSTATE))

	{

		if (DCSR(pDmaXfer->dwDmaCh) & DCSR_RUN) 

		{

			SMSC_TRACE("DmaStartXfer -- requested channel (%ld) is still running", pDmaXfer->dwDmaCh);

			return FALSE;

		}

		else 

		{

			// DMA is not running yet.

			// Keep going..

			SMSC_WARNING("DmaStartXfer -- requested channel (%ld) is weird status", pDmaXfer->dwDmaCh);

		}

	}



	// calculate the physical transfer addresses

	dwLanPhysAddr = CpuToPhysicalAddr((void *)pDmaXfer->dwLanReg);

	dwMemPhysAddr = CpuToPhysicalAddr((void *)pDmaXfer->pdwBuf);



	dwLanPhysAddr += 0x800;



	// need CL alignment for CL bursts

	dwAlignMask = (CACHE_LINE_BYTES - 1UL);



	if ((dwLanPhysAddr & dwAlignMask) != 0UL)

	{

		SMSC_WARNING("DmaStartXfer -- bad dwLanPhysAddr (0x%08lX) alignment",

			dwLanPhysAddr);

		return FALSE;

	}



	//if ((dwMemPhysAddr & dwAlignMask) != 0UL)

	if ((dwMemPhysAddr & 0x03UL) != 0UL)

	{

		SMSC_WARNING("DmaStartXfer -- bad dwMemPhysAddr (0x%08lX) alignment",

			dwMemPhysAddr);

			return FALSE;

	}



	//validate the transfer size, On XScale Max size is 8k-1

	if (pDmaXfer->dwDwCnt >= 8192UL)

	{

		SMSC_WARNING("DmaStartXfer -- dwDwCnt =%ld is too big (1^20 bytes max on panax)", pDmaXfer->dwDwCnt);

		return FALSE;

	}



	//Note: The DCSR should be cleared, before writing the Target and Source addresses

	DCSR(pDmaXfer->dwDmaCh) = DCSR_NODESC; //get ready for the DMA



	//Set the Source and Target addresses

	dwDmaCmd = 0UL;

	if (pDmaXfer->fMemWr)

	{

		//RX

		DTADR(pDmaXfer->dwDmaCh) = dwMemPhysAddr;

		DSADR(pDmaXfer->dwDmaCh) = dwLanPhysAddr;

		dwDmaCmd |= DCMD_INCTRGADDR; //always increment the memory address

		dwDmaCmd |= DCMD_INCSRCADDR;

	}

	else

	{

		//TX

		DTADR(pDmaXfer->dwDmaCh) = dwLanPhysAddr;

		DSADR(pDmaXfer->dwDmaCh) = dwMemPhysAddr;

		dwDmaCmd |= DCMD_INCSRCADDR; //always increment the memory address

		dwDmaCmd |= DCMD_INCTRGADDR;

	}



	//Set the burst size, if cache line burst set to 32Bytes else set to the smallest

	dwDmaCmd |= DCMD_BURST32;



	dwDmaCmd |= (DCMD_LENGTH & (pDmaXfer->dwDwCnt << 2));

	DCMD(pDmaXfer->dwDmaCh) = dwDmaCmd ;

	DCSR(pDmaXfer->dwDmaCh) |= DCSR_RUN;

	

	return TRUE;

}



DWORD Platform_DmaGetDwCnt( PPLATFORM_DATA platformData, const DWORD dwDmaCh)

{

	platformData=platformData;//make lint happy

	return (((DCMD_LENGTH & DCMD(dwDmaCh)) >> 2));	

}



void Platform_DmaComplete(PPLATFORM_DATA platformData, const DWORD dwDmaCh)

{

	DWORD dwTimeOut=1000000;



	platformData=platformData;//make lint happy



	while((Platform_DmaGetDwCnt(platformData,dwDmaCh))&&(dwTimeOut))

	{

		udelay(1);

		dwTimeOut--;

	}

	if(!Platform_DmaDisable(platformData,dwDmaCh)) {

		SMSC_WARNING("Failed Platform_DmaDisable");

	}

	if(dwTimeOut==0) {

		SMSC_WARNING("Platform_DmaComplete: Timed out");

	}

}



DWORD Platform_RequestDmaChannel(PPLATFORM_DATA platformData)

{

	platformData=platformData;//make lint happy

	return TRANSFER_PIO;

}



void Platform_ReleaseDmaChannel(

	PPLATFORM_DATA platformData,

	DWORD dwDmaChannel)

{

	platformData=platformData;//make lint happy

	dwDmaChannel=dwDmaChannel;//make lint happy

	//since Platform_RequestDmaChannel

	//  never returns a dma channel

	//  then this function should never be called

	SMSC_ASSERT(FALSE);

}



void Platform_WriteFifo(

	DWORD dwLanBase,

	DWORD *pdwBuf,

	DWORD dwDwordCount)

{

	volatile DWORD *pdwReg;

	pdwReg = (volatile DWORD *)(dwLanBase+TX_DATA_FIFO);

	while(dwDwordCount)

	{

		*pdwReg = *pdwBuf++;

		dwDwordCount--;

	}



}

void Platform_ReadFifo(

	DWORD dwLanBase,

	DWORD *pdwBuf,

	DWORD dwDwordCount)

{

	const volatile DWORD * const pdwReg = 

		(const volatile DWORD * const)(dwLanBase+RX_DATA_FIFO);

	

	while (dwDwordCount)

	{

		*pdwBuf++ = *pdwReg;

		dwDwordCount--;

	}

}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -