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

📄 drv8139.c

📁 psos嵌入式操作系统平台下的8139驱动程序,比较难得.
💻 C
📖 第 1 页 / 共 5 页
字号:
    ArpPacket[31] = LanIPaddr & 0xff;

    for(i = 0; i < 6; i++)
        ArpPacket[i+32] = Broadcast[i];
        
    ArpPacket[38] = (DefGateWay >> 24) & 0xff;
    ArpPacket[39] = (DefGateWay >> 16) & 0xff;
    ArpPacket[40] = (DefGateWay >> 8) & 0xff;
    ArpPacket[41] = DefGateWay & 0xff;

    for(i = 42; i < 63; i++)
        ArpPacket[i] = 0;
}


/****************************************************************************
* function name: SendArpPacket
* design date:2001-8-17, 
* function description: send arp request packet to default gateway
* call: no
* called: NiLan, ni_poll
* input parameter: no
* output parameter: no
* return value: no
* change record: no
*****************************************************************************/
void SendArpPacket(unsigned long addr)
{
    UInt32 status;
    ArpPacket[38] = (addr >> 24) & 0xff;
    ArpPacket[39] = (addr >> 16) & 0xff;
    ArpPacket[40] = (addr >> 8) & 0xff;
    ArpPacket[41] = addr & 0xff;
    
    memcpy((void*)(TxDesc[CurDescId]), (void*)ArpPacket, 64);
    
    _cache_copyback((void*)(int)(TxDesc[CurDescId]), TX_BUF_SIZE);

    status &= 0xffffc000; //The driver must set OWN bit to 0 after set descriptor size
    status |= 0x003f0000|64; //Set Descriptor Size, tx FIFO is 2k

    IoWriteReg32(TSD0 + CurDescId * 4, status);
    
    CurDescId++;
    CurDescId = CurDescId % NUM_TX_DESC;
    
    //_dp("send arp packet\n");
}


/****************************************************************************
* function name: map_mcast
* design date:2001-5-10, 
* function description: map protocol multicast address to hardware multicast      
*                       address 
* call: no
* called: ni_ioctl
* input parameter: mmap = location of the mapping structure 
* output parameter: no
* return value: 0 if hardware address has been filled in.
*               EINVALID if not a known protocol.
* change record: no
*****************************************************************************/
//多播组地址到以太网地址的转换,这种地址分配将使以太网多播地址中的23bit与IP多播组号对应起来,
//通过将多播组号中的低位23bit映射到以太网地址中的低位23bit实现
//(注:每发一个多播包都会调用这个函数进行一次地址转换)
static ULONG map_mcast(struct ni_map_mcast *mmap)
{
    register char *prtladdr, *hdwraddr;
    
    //printf("[map_mcast]: enter map_mcast.\n") ;
 
    if (mmap->type == 0x800)
    {
        prtladdr = mmap->prtladdr;
        hdwraddr = mmap->hdwraddr;
 
        hdwraddr[0] = 0x01;
        hdwraddr[1] = 0x00;
        hdwraddr[2] = 0x5E;
        hdwraddr[3] = prtladdr[1] & 0x7F; //0111 1111 (7+8+8 = 23)
        hdwraddr[4] = prtladdr[2]; // 8
        hdwraddr[5] = prtladdr[3]; // 8
    }
    else
        return(EINVALID);
 
    return(0);
}

/****************************************************************************
* function name: lan_add_mcast
* design date:2001-5-10, 
* function description: Add a multicast address to the table in sorted order 
* call: no
* called: ni_ioctl
* input parameter: addr = pointer to the address to add
* output parameter: no
* return value: 0                                           
* change record: no
*****************************************************************************/
static long lan_add_mcast(UCHAR *addr)
{
    int i = 0 ;
    int i_ret = 0 ;
 /*   unsigned char sz_text[64]= {0} ;
    printf("[lan_add_mcast]: enter lan_add_mcast (0x)") ;    
    for (i = 0; i < 14; i ++)
    {
    	printf("%.2x", addr[i]) ;
    }
    printf("\n") ;
 */  
    LAN_HWA * pDestHWA = (LAN_HWA *)addr ;
    for (i = 0; i < MULTICAST_ADDR_NUM; ++ i)
    {
        if (1 == g_multi_addr[i].is_used &&
        g_multi_addr[i].addr.byte[0] == addr[0] &&
        g_multi_addr[i].addr.byte[1] == addr[1] &&
        g_multi_addr[i].addr.byte[2] == addr[2] && 
        g_multi_addr[i].addr.byte[3] == addr[3] &&
        g_multi_addr[i].addr.byte[4] == addr[4] &&
        g_multi_addr[i].addr.byte[5] == addr[5])
        {
        	DP(("[lan_add_mcast]: the multiaddress[(0x)%.2x%.2x%.2x%.2x%.2x%.2x] had exist!\n", 
        	    addr[0],addr[1],addr[2],addr[3],addr[4],addr[5])) ;
       	    return 0 ;
        }
    }
    
    for (i = 0; i < MULTICAST_ADDR_NUM; ++ i)
    {
    	if (0 == g_multi_addr[i].is_used)
    	{
    		g_multi_addr[i].addr.byte[0] = addr[0] ;
        	g_multi_addr[i].addr.byte[1] = addr[1] ;
        	g_multi_addr[i].addr.byte[2] = addr[2] ;
        	g_multi_addr[i].addr.byte[3] = addr[3] ;
        	g_multi_addr[i].addr.byte[4] = addr[4] ;
        	g_multi_addr[i].addr.byte[5] = addr[5] ;
        	g_multi_addr[i].is_used = 1 ;
        	DP(("[lan_add_mcast]: add new multiaddress[(0x)%.2x%.2x%.2x%.2x%.2x%.2x]\n", 
        	    addr[0],addr[1],addr[2],addr[3],addr[4],addr[5])) ;
        	return 0 ;
    	}
    }
    
    return -1 ;
}

/****************************************************************************
* function name: lan_del_mcast
* design date:2001-5-10, 
* function description: Delete a mulicast address from the table 
* call: no
* called: ni_ioctl
* input parameter: addr = pointer to the address to remove
* output parameter: no
* return value: 0                                           
* change record: no
*****************************************************************************/
static long lan_del_mcast(UCHAR *addr)
{
    int i = 0 ;
	
	//-------------------------------------------------------------------------------
	LAN_HWA * pDestHWA = (LAN_HWA *)addr ;
//	printf("[lan_del_mcast]: enter lan_del_mcast.\n") ;
	
    for (i = 0; i < MULTICAST_ADDR_NUM; ++ i)
    {
        if (1 == g_multi_addr[i].is_used &&
        g_multi_addr[i].addr.byte[0] == addr[0] &&
        g_multi_addr[i].addr.byte[1] == addr[1] &&
        g_multi_addr[i].addr.byte[2] == addr[2] && 
        g_multi_addr[i].addr.byte[3] == addr[3] &&
        g_multi_addr[i].addr.byte[4] == addr[4] &&
        g_multi_addr[i].addr.byte[5] == addr[5])
        {
        	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 ;
        	DP(("[lan_del_mcast]: del multiaddress[(0x)%.2x%.2x%.2x%.2x%.2x%.2x]\n", 
        	    addr[0],addr[1],addr[2],addr[3],addr[4],addr[5])) ;
        	break ;
        }
    }
	//-------------------------------------------------------------------------------
	
    IoWriteReg32(MAR0, 0xffffffff);
    IoWriteReg32(MAR4, 0xffffffff);

    intRaise(V_LAN);

    return 0;
}

/****************************************************************************
* function name: bzero
* design date:2001-5-8, 
* function description: Zero memory at specified address  
* 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
*****************************************************************************/
static void bzero(UCHAR *ptr, int length)
{
    while(length--)
        *ptr++ = 0;
}

/****************************************************************************
* function name: LanPciInit
* design date:2001-5-8, 
* function description: Initialize the LAN PCI Configuration Registers, 
*                       All Multibyte registers follow little endian byte 
*                       ordering. 
* call: PciWrCfg8, PciWrCfg16, PciWrCfg32
* called: NiLan
* input parameter: no
* output parameter: no
* return value: no                                           
* change record: no
*****************************************************************************/
static void LanPciInit(void) // LAN PCI Configuration Registers
{ 
    PciWrCfg16(CF_CMD,  0);//PCI Command Register - clear
    
    //PCI Status Register - clear                    
    PciWrCfg16(CF_STATUS, LAN_DS_PER|LAN_DS_SERR|LAN_DS_MA|LAN_DS_RTA|LAN_DS_DPAR);
 
    // PCI IO Map Base register - Set IO Space Base Address             
    PciWrCfg32(CBIO, LAN_PCI_IO_BASE);
    
    //PCI Latency Timer Register - initialize                          
    PciWrCfg8(CF_LATENCY, 0xff);
     
    //PCI Command Register - Set         //IO Space Enable,Bus Master Enable                                   
    PciWrCfg16(CF_CMD, 0x45);     
}

/****************************************************************************
* function name: LanInit
* design date:2001-5-8, 
* function description: Initialize 8139 Control and Status Registers      
* call: LanChipReset,IoWriteReg8,IoWriteReg16,IoWriteReg32,IoReadReg8,
*       IoReadReg16,IoReadReg32
* called: ni_init
* input parameter: no
* output parameter: no
* return value: no                                           
* change record: no
*****************************************************************************/
void LanInit()
{
    UCHAR    i, value8;
    USHORT   value16;
    ULONG    value;
	        
    //DP8139("enter LanInit()\n"); 
    
    value = IoReadReg32(IDR0);
    
		//printf("1.mac long:0x%x\n",value);
   //read Mac address 
    SelfAddr[0]=(unsigned char)value;
    SelfAddr[1]=(unsigned char )(value>>8);
    SelfAddr[2]=(unsigned char )(value>>16);
    SelfAddr[3]=(unsigned char )(value>>24);
		
    value =  IoReadReg32(IDR4);        
    SelfAddr[4]=(unsigned char )value;
    SelfAddr[5]=(unsigned char )(value>>8);
		//printf("2.mac long:0x%x\n",value);
    i = 0;
    do
    {
        LanChipReset();  //Perform software reset of the chip
    
    	//-----------------------------------------------------------------------
    	// Config register write enable: Before writing to CONFIG0,
	// 1, 3, 4 registers, and bit13, 12, 8 of BMCR(offset
	// 62h-63h), the RTL8139D(L) must be placed in this mode.
	// This will prevent RTL8139D(L)'s configurations from
	// accidental change.
        IoWriteReg8(CR9346, 0xc0); //enable config
        //-----------------------------------------------------------------------
     
        value = SelfAddr[0] | SelfAddr[1] << 8 | SelfAddr[2] << 16 | SelfAddr[3] << 24;
        IoWriteReg32(IDR0, value);
        
        value = SelfAddr[4] | SelfAddr[5] << 8;
        IoWriteReg32(IDR4, value);
        
        //-----------------------------------------------------------------------
        // Multicast Register(Driver is responsible for initializing these registers.)
        IoWriteReg32(MAR0, 0xffffffff);
        IoWriteReg32(MAR4, 0xffffffff);
        //-----------------------------------------------------------------------
    
    	//-----------------------------------------------------------------------
    	// Basic Mode Control Register: 0x1000(0001 0000 0000 0000)
    	// This bit enables/disables the NWay auto-negotiation function.
	// Set to 1 to enable auto-negotiation, bit13 will be ignored.
	// Set to 0 disables auto-negotiation, bit13 and bit8 will determine the
	// link speed and the data transfer mode, respectively.
	// This bit‘s initial value comes from 93C46.
        value16 = IoReadReg16(BMCR);
        //printf("[LanInit]: read BMCR[0x%x]", value16) ;
        value16 |= 0x1100; // 0001 0001 0000 0000 : duplex mode
        //value16 |= 0x3100;   // 0011 0001 0000 0000 : Spd_Set: 1 = 100Mbps; 0 = 10Mbps.  
        value16 &= 0xfeff;   // 1111 1110 1111 1111 : normal operation
        //printf(", write BMCR[0x%x].\n", value16) ;//0x1000
        IoWriteReg16(BMCR, value16);
        //-----------------------------------------------------------------------
    
        // Media Status Register
        value8 = IoReadReg8(MSR);
        value8 |= 0xc0; // 1100 0000
        IoWriteReg8(MSR, value8); // 0xdc(1101 1100)  
        //printf("[LanInit]: MSR[0x%x].\n", value8) ; 

	// Configuration Register 1
        value8 = IoReadReg8(CONFIG1);
        value8 &= 0x3f; // 0011 1111
        value8 |= 0x40; // 0100 0000
        IoWriteReg8(CONFIG1, value8);  // 0x4d (0100 1101)
        //printf("[LanInit]: CONFIG1[0x%x].\n", value8) ; 
                

	//-----------------------------------------------------------------------        
        // Configuration Register 4 
        // operator:| 0x80(1000 0000) means: RxFIFOAutoClr: Set to 1, the RTL8139D(L) 
        // will clear the Rx FIFO overflow automatically.
        value8 = IoReadReg8(CONFIG4);
        value8 |= 0x80; // 1000 0000
        IoWriteReg8(CONFIG4, value8); // 0x88 (1000 1000)
        //printf("[LanInit]: CONFIG4[0x%x].\n", value8) ;       
   	//-----------------------------------------------------------------------
   	
   	// This register contains the advertised abilities of this device as they 
   	// will be transmitted to its link partner during Auto-negotiation.
        value16 = IoReadReg16(ANAR);
        value16 |= 0x5e1; //0000 0101 1110 0001
        IoWriteReg16(ANAR, value16); // 0x5e1
        //printf("[LanInit]: ANAR[0x%x].\n", value16) ; 
    
        IoWriteReg8(CR9346, 0x0); //disable config   
    
        value8 = IoReadReg8(MSR); // 0x1c (0001 1100)

⌨️ 快捷键说明

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