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

📄 lan91c111.c

📁 lwip tcp/ip 协议栈 adsp BF533 DSP 移植 用 visual dsp++ 编译
💻 C
📖 第 1 页 / 共 4 页
字号:

               /* Change the Enqueued head */
               dev->m_TxEnqueuedHead = (ADI_ETHER_BUFFER*)tmp_q_ele->pNext;
               dev->m_TxEnqueuedCount--;
               if (dev->m_TxEnqueuedCount == 0)
               {
                  dev->m_TxEnqueuedTail = NULL;
                  cont = 0;
               }

               /* Add the packet to dequeued list*/
               if (dev->m_TxDequeuedCount)
                  dev->m_TxDequeuedTail->pNext = (ADI_ETHER_BUFFER*)tmp_q_ele;
               else
                  dev->m_TxDequeuedHead = tmp_q_ele;

               //No matter what this is also the tail.
               dev->m_TxDequeuedTail = tmp_q_ele;
               //And tail->next should point to NULL
               tmp_q_ele->pNext = NULL;
               dev->m_TxDequeuedCount++; 
            
            }
         }
      }
     if (dev->DCBHandle != NULL) {
	 	result = adi_dcb_Post(dev->DCBHandle,ik_ivg13,dev->DMCallback,dev->DeviceHandle,ADI_ETHER_EVENT_FRAME_XMIT,dev->m_TxDequeuedHead->CallbackParameter);
     } else {
     	(dev->DMCallback)(dev->DeviceHandle,ADI_ETHER_EVENT_FRAME_XMIT,dev->m_TxDequeuedHead->CallbackParameter);
     	result = ADI_DCB_RESULT_SUCCESS;
     }
     //if (result == ADI_DCB_RESULT_SUCCESS) {
		//## what happens if a packet is trasnmitted while in the callback
        dev->m_TxDequeuedHead = NULL;
  		dev->m_TxDequeuedTail = NULL;
		dev->m_TxDequeuedCount = 0;
     //}
      EXIT_CRTICIAL_REGION();

      return mr;
}

/******************************************************************************
 * Get MAC address in the SMSC  
 *****************************************************************************/
static void GetMacAddr(unsigned char *mac_addr)
{
	volatile unsigned short addr;
	volatile unsigned short page;
	page = _inpw(BSR_REG);

	_outpw(BSR_REG, 1);
	addr = _inpw(ADDR0_REG); // get MAC addr
	mac_addr[0] = addr & 0xFF;
	mac_addr[1] = addr >> 8;

	addr = _inpw(ADDR1_REG); // get MAC addr
	mac_addr[2] = addr & 0xFF;
	mac_addr[3] = addr >> 8;

	addr = _inpw(ADDR2_REG); // get MAC addr
	mac_addr[4] = addr & 0xFF;
	mac_addr[5] = addr >> 8;
	_outpw(BSR_REG, page);
	return;
}
/******************************************************************************
 * Set MAC address in the SMSC  
 *****************************************************************************/
static void SetupMacAddr(unsigned char *mac_addr)
{
   unsigned short page;
   short wtmp;

   // save old page
   page = _inpw(BSR_REG);

   // select bank 1
   _outpw(BSR_REG, 1); 
   
   // Set EEPROM Store
   _outpw(CTL_REG,CTL_EEPROM_SELECT | CTL_STORE);
       
    wtmp = (((mac_addr[1])<<8)|(mac_addr[0]));
    _outpw(ADDR0_REG, wtmp);
    wtmp = (((mac_addr[3])<<8)|(mac_addr[2]));
    _outpw(ADDR1_REG, wtmp);
    wtmp = (((mac_addr[5])<<8)|(mac_addr[4]));
    _outpw(ADDR2_REG, wtmp); 

        
   // restore bank
   _outpw(BSR_REG, page);
    
   return;
}

/******************************************************************************
 *
 * Configures the PF/IMASK/IAR settings associated with the driver.
 *
 *****************************************************************************/
static int  SetDevicePFConfig(ADI_ETHER_LAN91C111_DATA *dev)
{
	unsigned int iar2_mask;
	
	 *pEBIU_AMGCTL   = 0xF;
	
	 // Init EBIU
	if ((*pEBIU_SDSTAT & 0x8))
	{
	 *pEBIU_SDRRC = 0x397;
	 *pEBIU_SDBCTL = 0x13;
	 *pEBIU_SDGCTL = 0x8011998D;
	     
	}
	
	// Default PF configuration is PF9
	//
	if(dev->pf == 0)
		dev->pf = PF9;

	csync();
	ssync();	
	
	// Clear off any pending interrupts
	*pFIO_DIR     = 0x0;
	*pFIO_POLAR   = 0x0;
	*pFIO_MASKB_C = dev->pf;
	ssync();
	*pFIO_MASKB_S = dev->pf;
	*pFIO_INEN	  = dev->pf;
               
	 return 1;
}

/*********************************************************************
*
*	Function:		pddOpen
*
*	Description:	Opens the Network Driver and does initialization. 
*
*********************************************************************/

static u32 adi_pdd_Open(				// Open a device
	ADI_DEV_MANAGER_HANDLE	ManagerHandle,	// device manager handle
	u32 					DeviceNumber,	// device number
	ADI_DEV_DEVICE_HANDLE 	DeviceHandle,	// device handle
	ADI_DEV_PDD_HANDLE 		*pPDDHandle,	// pointer to PDD handle location 
	ADI_DEV_DIRECTION 		Direction,		// data direction
	void			*pCriticalRegionArg,		// critical region imask storage location
	ADI_DMA_MANAGER_HANDLE	DMAHandle,		// handle to the DMA manager
	ADI_DCB_HANDLE			DCBHandle,		// callback handle
	ADI_DCB_CALLBACK_FN		DMCallback		// device manager callback function
)
{
	u32 			Result;		// return value
	void 			*CriticalResult;
	ADI_ETHER_LAN91C111_DATA *dev= &EtherDev;	


	// check for errors if required
#ifdef ADI_ETHER_ERROR_CHECKING_ENABLED
	if (DeviceNumber > 0) {		// check the device number
		return (ADI_DEV_RESULT_BAD_DEVICE_NUMBER);
	}
#endif

	// insure the device the client wants is available
	Result = ADI_DEV_RESULT_DEVICE_IN_USE;
	//CriticalResult = adi_int_EnterCriticalRegion(pCriticalRegionArg);

	// Open the device
	if(!dev->Open)
	{
		// initialize the device settings
		memset(dev,0,sizeof(ADI_ETHER_LAN91C111_DATA));

		dev->CriticalData = pCriticalRegionArg;
		dev->DeviceHandle = DeviceHandle;
		dev->DCBHandle = DCBHandle;
		dev->DMCallback = DMCallback;
		dev->Direction = Direction;
		dev->Started = false;

		// default ivg levels
		dev->RXIVG  = ik_ivg8;
		dev->TXIVG  = ik_ivg8;
		dev->ERRIVG = ik_ivg8;

		//set PF configuration
		SetDevicePFConfig(dev);

		dev->Open = true;
		Result = ADI_DEV_RESULT_SUCCESS;
	}

	// exit critical region
	//
	//adi_int_ExitCriticalRegion(CriticalResult);

	if (Result != ADI_DEV_RESULT_SUCCESS) return (Result);

	*pPDDHandle = (ADI_DEV_PDD_HANDLE *)&EtherDev;
	return(ADI_DEV_RESULT_SUCCESS);
}


/*********************************************************************
*
*	Function:		pddRead
*
*	Description:	Gives list of read buffers to the driver
*
*********************************************************************/
static u32 adi_pdd_Read(		// Reads data or queues an inbound 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;

	// 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

	QueueNewRcvFrames((void*)PDDHandle,(ADI_ETHER_BUFFER*)pBuffer);
	return(ADI_DEV_RESULT_SUCCESS);
}


/*********************************************************************
*
*	Function:		pddClose
*
*	Description:	Closes the driver and releases any memory
*
*********************************************************************/

static u32 adi_pdd_Close(		// Closes a device	
	ADI_DEV_PDD_HANDLE PDDHandle	// PDD handle
)
{
	ADI_ETHER_LAN91C111_DATA *dev = (ADI_ETHER_LAN91C111_DATA *)PDDHandle;	
	u32 		Result = ADI_DEV_RESULT_SUCCESS;				// return value
	bool active=true;
	
	// 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;	
	
	// 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
	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);
}

/**************************************************************************
 *
 * 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 + -