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

📄 drv8139.c

📁 psos嵌入式操作系统平台下的8139驱动程序,比较难得.
💻 C
📖 第 1 页 / 共 5 页
字号:
       //receive  fifo overflow! printf("[LanInit]: MSR[0x%x].\n", value8) ; 
        microsleep(10000);
        i++;
        if(i > 5)
            break;
    }
    while((value8 & 0x4)); //0000 0100(MSR:Inverse of Link status. 0 = Link OK. 1 = Link Fail.)
    //while((value8 & 0x4) == 0); //0000 0100(MSR:Inverse of Link status. 0 = Link OK. 1 = Link Fail.)
    				

    IoWriteReg8(CR, 0xc);  //Enable Transmit/Receive(RE/TE in Command Register) 
    
    value = IoReadReg32(TCR); 
    value |= 7<<8; //normal, CRC, size of Tx DMA is 2k  
    value &= 0xfff8ffff; 
    IoWriteReg32(TCR, value); //set TCR
    
    // receive Configuration register
    value = IoReadReg32(RCR);
    value &= 0xffff0000;
    //value |= 0x569e;//size of receive buffer is 8k+16, size of Rx DMA is unlimited, wrap, Rx FIFO threshold is 16     
#ifndef RECV_BUF_64K
    value |= 0xd69e;//1101 0110 1001 1110:size of receive buffer is 32k+16, size of Rx DMA is 1024 bytes, wrap, Rx FIFO threshold is 1024 bytes
#else
    value |= 0xde9e;//1101 1110 1001 1110:size of receive buffer is 64k+16
    //#error "RECV_BUF_64K"
#endif
    IoWriteReg32(RCR, value); //set RCR
//    printf("[LanInit]: set RCR = 0x%.8x.\n", value) ;
    /***************************************************************************/
    
    value = IoReadReg16(IMR);
    value |= 0x807f;//enable system error interrupt
		//value |= 0x7f;//disable system error interrupt   
    IoWriteReg16(IMR, value);// 0xe07f //enable IMR
 	//	printf("IoWriteReg16 successfully\n");
     //-----------------------------------------------------------------
     // Init multicast address buffer
     for (i = 0; i < MULTICAST_ADDR_NUM; ++ i)
     {
     	g_multi_addr[i].addr.word1 = 0xffff ;
     	g_multi_addr[i].addr.word2 = 0xffff ;
     	g_multi_addr[i].addr.word3 = 0xffff ;
     	g_multi_addr[i].is_used = 0 ;
     }
     /***************************************************************************/
    //-----------------------------------------------------------------
    printf("[LanInit]: init finish!\n") ;
    //IoWriteReg16(BMCR, 0x0);
}

/****************************************************************************
* function name: SetupLanParams
* design date:2001-5-8, 
* function description: Allocate transmit and receive buffers     
* call: bzero
* called: pNA+
* input parameter: no_of_packet == number of packet
* output parameter: freeMemPtr = pointer to start address of free memory
* return value: no                                           
* change record: no
*****************************************************************************/
UCHAR *SetupLanParams(ULONG no_of_packets, UCHAR *freeMemPtr)
{
    int i;
    
    // Determine number of buffers and descriptors.   
    
    TxNumHdrs = no_of_packets / 2;
    RxNumHdrs = no_of_packets - TxNumHdrs;

    // Allocate transmit headers.                                
    freeMemPtr  = ALIGN((int)freeMemPtr, 64);
    TxHeaders   = (LAN_TX_HDR *)freeMemPtr;
    
    freeMemPtr += (TxNumHdrs * sizeof(LAN_TX_HDR));
    
    // Allocate receive headers.                                
    freeMemPtr  = ALIGN((int)freeMemPtr, 64);
    RxHeaders   = (LAN_RX_BUF *)freeMemPtr;
    
    freeMemPtr += (RxNumHdrs * sizeof(LAN_RX_BUF));
  
    // Allocate transmit descriptors.  
    for(i = 0; i < NUM_TX_DESC; i++)
    {
        TxDesc[i] = ALIGN((int)freeMemPtr, 64);
        bzero((UCHAR *)TxDesc[i], TX_BUF_SIZE);
        
        freeMemPtr += TX_BUF_SIZE;
    }
    
    RxRing = ALIGN((int)freeMemPtr, 64);
    bzero((UCHAR *)RxRing, RX_BUF_SIZE + TX_BUF_SIZE);

    freeMemPtr += RX_BUF_SIZE + TX_BUF_SIZE;
  
    /*  
    printf("[SetupLanParams]: TxNumHdrs[%d], RxNumHdrs[%d].\n", TxNumHdrs, RxNumHdrs) ;
    printf("[SetupLanParams]: TxHeaders [0x%x], RxHeaders [0x%x]\n", TxHeaders, RxHeaders) ; 
    printf("[SetupLanParams]: ") ;
    for(i = 0; i < NUM_TX_DESC; i++)
    {
    	printf(" TxDesc[%d]: 0x%x", i, TxDesc[i]) ;
    }
    printf ("\n") ;
    printf("[SetupLanParams]: RxRing[0x%x].\n", RxRing) ;
    */
 
    return freeMemPtr;
}

/****************************************************************************
* function name: InitTxDescRxRing
* design date:2001-5-8, 
* function description: Initialize 8139 receive buffer and transmit descriptors.      
* call: no
* called: SetupLanParams, InitBuffers
* input parameter: ptr = pointer to the address to zero
*                  length = length of memory to be zeroed
* output parameter: no
* return value: no                                           
* change record: no
*****************************************************************************/
void InitTxDescRxRing()
{
    int i;
    
    for(i = 0; i < NUM_TX_DESC; i++)
    {
        IoWriteReg32(TSAD0 + i * 4, (ULONG)TxDesc[i]);
    }
    
    IoWriteReg32(RBSTART, (ULONG)RxRing);
    
    CurDescId = 0;
    RxOffset = 0; 
}

/****************************************************************************
* function name: InitBuffers
* design date:2001-5-8, 
* function description: Initialize receive buffer and transmit descriprot       
* call: bzero
* called: ni_init
* input parameter: no
* output parameter: no
* return value: no                                           
* change record: no
*****************************************************************************/
static void InitBuffers(void)
{
    int i;
     
      
    //Zero out the transmit headers                            
    bzero((UCHAR *)TxHeaders, sizeof(LAN_TX_HDR) * TxNumHdrs);
    //Link transmit headers in a free list                        
    TxHdrFreeHead = &TxHeaders[0];
    for (i = 0; i < (TxNumHdrs - 1); ++i)
        TxHeaders[i].next = &TxHeaders[i + 1];
    TxHeaders[TxNumHdrs - 1].next = NULL;
    //Initialize the list of queued transmit headers to empty.   
    TxHdrOutHead = TxHdrOutTail = NULL;
    
    //Zero out the receive headers                            
    bzero((UCHAR *)RxHeaders, sizeof(LAN_RX_BUF) * RxNumHdrs);
    //Link receive headers in a free list                        
    RxPktFreeHead = &RxHeaders[0];
    for (i = 0; i < (RxNumHdrs - 1); ++i)
        RxHeaders[i].next = &RxHeaders[i + 1];
    RxHeaders[RxNumHdrs - 1].next = NULL;
    //Initialize the list of queued transmit headers to empty.   
    RxPktList = NULL;
    FreeRxPktCount = RxNumHdrs;
    
    InitTxDescRxRing();
}

/****************************************************************************
* function name: LanChipReset
* design date:2001-5-8, 
* function description: Reset the LAN chip       
* call: IoWriteReg8
* called: LanInit
* input parameter: no
* output parameter: no
* return value: no                                           
* change record: no
*****************************************************************************/
//Reset: Setting to 1 forces the RTL8139D(L) to a software reset state

//which disables the transmitter and receiver, reinitializes the FIFOs,

//resets the system buffer pointer to the initial value
//(after reset: Tx buffer is at TSAD0, Rx buffer is empty). 
//The values of IDR0-5 and MAR0-7 and PCI configuration space will have no changes.
static void LanChipReset(void)
{
    IoWriteReg8(CR, 0x10);     //Software Reset
           
    //Must wait for minimum of 50 PCI clock cycles.                     
    microsleep(10);
}

/****************************************************************************
* function name: tmIntInit
* design date:2001-5-8, 
* function description: install interrupt handler, open network interrupt       
* call: no
* called: ni_init
* input parameter: no
* output parameter: no
* return value: no                                           
* change record: no
*****************************************************************************/
static long tmIntInit(void)
{    
    tmLibdevErr_t tm_err;
    intInstanceSetup_t iisetup;

    iisetup.enabled = True; //Install the interrupt service routine. 
    iisetup.handler = ni_isr;
    iisetup.priority = intPRIO_6;//intPRIO_6;  //priority
    iisetup.level_triggered = True;//False; 
    
    tm_err = intOpen(V_LAN);       
    if(tm_err != TMLIBDEV_OK) 
        return False;
   
    tm_err = intInstanceSetup(V_LAN, &iisetup);
    if(tm_err != TMLIBDEV_OK) 
    {
        intClose(V_LAN);
        return False;
    }
    
    return True;
}

/****************************************************************************
* function name: ni_init
* design date:2001-5-8, 
* function description: Initialize the network interface.      
* call: tmIntInit,LanInit,InitBuffers
* called: ni_init
* input parameter: no
* output parameter: no
* return value: Pointer to hardware address of NI or -1 if failure                                            
* change record: no
*****************************************************************************/
static long ni_init(void)
{
    int i;
    Bool ien;
	//add by zhengkun
    ArpReqFlag = 0;
    intClear(V_LAN);
    
    if(!tmIntInit())
    {
    	DP8139("Int init fail!\n");
        return -1;
    }
        
    // Get the Ethernet Address.  This is set in bpdialog.c.             
    // This is an interim solution till I get the roms working.          
    
    //Initialize MIB variables.
    InErrors = outerrors = 0;             
    InOctets = OutOctets = 0;
    InUcastPkts = OutUcastPkts = 0;
    innucastpkts = outnucastpkts = 0;
    ifadminstatus = 1;                   //up 
    InUnknownProtos = 0;
    lc_err = 0;
    InitBuffers();  //Initialize the receive buffers and transmit headers.
    LanInit();        //Initialize Lan chip in Ethernet mode in stopped mode.        
    for(i = 0; i < 6; ++i)
        OurAddress.byte[i] = SelfAddr[i]; 
              
    //InitBuffers();  //Initialize the receive buffers and transmit headers.  

//    intRESTORE_IEN(ien);
    intRaise(V_LAN);
    
    //No errors if we got here, so return pointer to Ethernet address.  
    //for(i = 0; i < 6; ++i)
     //   DP8139("OurAddress.byte[%d] = %x\n", i, OurAddress.byte[i]);
    
    return (long)&OurAddress;         //the NI Ethernet physical address
}

/****************************************************************************
* function name: ni_send
* design date:?2001-5-8, 
* function description: Send a packet to another node.      
* call: TxFillDesc
* called: NiLan
* input parameter: hwa_ptr = pointer to the destination hardware address        
*                  pkb_ptr = pointer to packet (msg block triplet)              
*                  len    = number of bytes in packet buffer                   
*                  type    = flag indicating either IP, ARP, or RARP            
* output parameter: no
* return value: 0                                            
* change record: no
*****************************************************************************/
#pragma pack(1)
struct taga
{
	char a ;
	int b ;
}af ;
#pragma pack()

static long ni_send(char *hwa_p, char *pkb_p, USHORT len, USHORT type)
{
    LAN_TX_HDR *tx_hdr;
    mblk_t     *msgBlk;
    int        i;
    Bool ien;
      
    //Try to keep the transmit descriptors full.                     
    TxFillDesc();
  
    if(hwa_p[0] & 1) 
        outnucastpkts++;
    else
        OutUcastPkts++;
   
    //Compute the # of descriptors required to send this frame.        
    msgBlk = (mblk_t *)pkb_p;
    
    if(len == 0)
    {
        NiFuncs.freemsg(msgBlk);
        return 0;
    }
    len += 14;
    
    /*---------------------------------------------------------------------*/
    /* Update record of total bytes sent.                                  */
    /*---------------------------------------------------------------------*/
    OutOctets += len;
    
    //Obtain transmit header from free list.  If none available, we     
    //can't send the packet.  Just return the triplet.                 
    intClear(V_LAN);
    tx_hdr = TxHdrFreeHead;
    if(tx_hdr == (LAN_TX_HDR *)NULL)
    {
        intRaise(V_LAN);
    	outerrors++;
        NiFuncs.freemsg(msgBlk);
        return 0;

⌨️ 快捷键说明

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