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

📄 drv8139.c

📁 psos嵌入式操作系统平台下的8139驱动程序,比较难得.
💻 C
📖 第 1 页 / 共 5 页
字号:
    }
    else
        TxHdrFreeHead = tx_hdr->next;
    intRaise(V_LAN);
    
    //Write destination and source address to the header.            
    for (i = 0; i < 6; ++i)
    {
        tx_hdr->daddr.byte[i] = hwa_p[i];
     	tx_hdr->saddr.byte[i] = SelfAddr[i];
  	}
    
    //Write type to header, after switching to network order.         
    tx_hdr->type = htons(type);
  
    //Save address of message block triplet in transmit header, along   
    //with total number of descriptors needed to transmit frame.       
    tx_hdr->msg_ptr   = msgBlk;        
    tx_hdr->NoRetFlag = 0;
    tx_hdr->len  = len;
  
    //Put this transmit header at the end of the queued message list.  
    tx_hdr->next = NULL;
    intClear(V_LAN);
    if (TxHdrOutHead == NULL)
        TxHdrOutHead = TxHdrOutTail = tx_hdr;
    else
    {
        TxHdrOutTail->next = tx_hdr;
        TxHdrOutTail = tx_hdr;
    }
  
    //intRESTORE_IEN(ien);
    intRaise(V_LAN);
  
    //Try to keep the transmit buffer descriptors full.                
    TxFillDesc();
    
    
    return 0;
}

/****************************************************************************
* function name: ni_isr
* design date:?2001-5-8, 
* function description: Interrupt service routine 
* call: ni_poll
* called: tmIntInit
* input parameter: no                  
* output parameter: no
* return value: 0                                            
* change record: no
*****************************************************************************/
static void ni_isr(void)
{
#pragma TCS_handler
    //DP8139("go in ni_isr\n");
    //pSOS interrupt service routine entry routine.                    
    ienter();
    AppModel_run_on_sstack((Pointer)ni_poll, Null);
    //pSOS interrupt service routine exit routine.     
    ireturn();
}

/****************************************************************************
* function name: ni_poll
* design date:?2001-5-8, 
* function description:  Check for and process interrupt events 
* call: TxFillDesc,ni_init,SendArpPacket,SendNetCheckMsg,RxBufRcv,IoWriteReg16
* called: ni_isr
* input parameter: no                  
* output parameter: no
* return value: 0                                            
* change record: no
*****************************************************************************/
static void ni_poll(void)
{
    USHORT isrValue; 
    int i;

    //While there is an interrupt pending, service it.                

   // for (;;)
   {
        //Read interrupt status register and break if none set.  
        isrValue = IoReadReg16(ISR);
  
        //Clear ISR so that new events continue to generate interrupts.
        IoWriteReg16(ISR, isrValue);

        if(!(isrValue & (ISR_NIS|ISR_AIS)))
       {
           //_dp("isrValue = %d, break out of ni_poll\n", isrValue);
           DP(("[ni_poll]isrValue = 0x%x, break out of ni_poll\n", isrValue)) ;
      //      break;
        }
		
//	printf("[ni_poll]isrValue = 0x%x.\n", isrValue) ;
        if(isrValue & 0x807a) //ISR_AIS)
        {
            enet_ais++;
	      
	        if(isrValue & ISR_SERR)    //System error
            {
                int command = LAN_DS_MA | LAN_DS_RTA | LAN_DS_SERR;   //new
          
          	DP(("------[ni_poll] System error!\n")) ;
                command &= PciRdCfg16(CF_STATUS);
                PciWrCfg16(CF_STATUS, command);
                enet_serr++;
                if(enet_serr % 100 == 0)
                    _dp("ni_poll: System error, enet_serr = %d, enet_rok = %d\n", enet_serr, enet_rok);
            }


            //If transmit errors, detach buffers.                        
            if(isrValue & ISR_TER)
            {
            	DP(("------[ni_poll] transmit errors!\n")) ;
                enet_ter++;
                TxFillDesc();
                if(enet_ter % 10 == 0)
                    _dp("ni_poll: transmit error, enet_ter = %d, enet_tok = %d\n", enet_ter, enet_tok);
            }
            
            //if link change
            if(isrValue & ISR_LNKCHG)
            {                
            	DP(("------[ni_poll] link change!\n")) ;
                ni_init();
                SendArpPacket(DefGateWay);
				SendArpPacket(LanIPaddr);
				//SendArpPacket();
           }

            // Check if receive error.                      
            if(isrValue & ISR_RER)
            {
            	DP(("------[ni_poll] receive error!\n")) ;
                enet_rer++;
                ni_init();
                if(enet_rer % 10 == 0)
                    _dp("ni_poll: receive error, enet_rer = %d, enet_rok = %d\n", enet_rer, enet_rok);
            }
            
            if(isrValue & (ISR_FOVW| ISR_RXOVW))
            {
                if(isrValue & ISR_FOVW)
                {
                	DP(("------[ni_poll] receive  fifo overflow!\n")) ;
                    enet_fovw++;
                    
                    if(enet_fovw % 10 == 0)
                        _dp("ni_poll: rx overflow, enet_fovw = %d, enet_rok = %d\n", enet_fovw, enet_rok);
                }
                    
                if(isrValue & ISR_RXOVW)
                {
                	DP(("------[ni_poll] receive buffer overflow!\n")) ;
                    enet_rxovw++;
                    RxOffset = IoReadReg16(CBR) % (RX_BUF_SIZE - 16);
                    RxOffset = (RxOffset + 3) & ~3;                    
                    IoWriteReg16(CAPR, RxOffset - 16);
                    
                    if(enet_rxovw % 10 == 0)
                        _dp("ni_poll: rx overflow, enet_rxovw = %d, enet_rok = %d\n", enet_rxovw, enet_rok);
		}
		IoWriteReg16(ISR, 1);
            }                 
        }
     
        //Check for Normal Interrupt Summary.                           
        if(isrValue & 0x5)//ISR_NIS)
        {
            enet_nis++;

            //If normal receive interrupt occurred, receive packets.       
            if(isrValue & 0x1)//ISR_ROK)
            {
                enet_rok++; 
                if(bFirst == 1)
                { 
                    bFirst = 0;
                    bLanCheck = 1;
                    //SendNetCheckMsg();
                }
                RxBufRcv();
                //_dp("ni_poll: receive OK\n");
           }

            //If normal transmit interrupt occurred, recover headers.      
            if(isrValue & 0x4)//ISR_TOK)
            {
                enet_tok++;
                TxFillDesc();
                //_dp("ni_poll: transmit OK\n");
            }
        }
        //zzm [2006-2-22]
		}
}

/****************************************************************************
* function name: ni_pna_init
* design date:?2001-5-8, 
* function description:  Called from ni_ioctl() to tell driver that pNA has    
*                        re/initialized.This driver needs to be sure that any 
*                        mblks still being used by the transmitter are NOT 
*                        returned to the mblk pool. This is because pna has just            
*                        re/initialize the mblk pool and if the driver did a    
*                        freemsg on those mblks still in the command queue     
*                        the result would be those mblks would show up twice   
*                        in the free list!
* call: no
* called: ni_ioctl
* input parameter: no                  
* output parameter: no
* return value: 0                                            
* change record: no
*****************************************************************************/
static void ni_pna_init(void)
{
    LAN_TX_HDR    *tx_hdr;
    Bool ien;
  
    intClear(V_LAN);

    //If there are any frames waiting to be put into the transmit      
    //descriptor ring flag them so they will not be returned.    
         
    tx_hdr = TxHdrOutHead;

    while (tx_hdr != NULL)
    {
        tx_hdr->NoRetFlag = 1;
        tx_hdr = tx_hdr->next;
    }

    intRaise(V_LAN);
}


/****************************************************************************
* function name: NiLan
* design date:?2001-5-8, 
* function description:  Main function interface between pNA+ and the NI 
* call: LanPciInit,enable_tm_sdram_access_ie,ni_init,MakeArpPacket,
*       SendArpPacket,ni_send,ni_ioctl
* called: pNA+
* input parameter: function = function code of the function to execute         
*                  p        = pointer to parameter block set up by pNA+                     
* output parameter: no
* return value: Varies with function -- see function headers                                               
* change record: no
*****************************************************************************/            
long NiLan(ULONG function, union nientry *p)
{
    long rc = 0;
    
    switch(function)
    {
    case NI_INIT:
        LanPciInit();
        enable_tm_sdram_access_ie();

        //Save global interface number and function pointers.            
        Announce = p->niinit.ap_addr;
        IfNum = p->niinit.if_num;
        NiFuncs = *(p->niinit.funcs);
        rc = ni_init();
        MakeArpPacket();
        SendArpPacket(DefGateWay);
        SendArpPacket(LanIPaddr);
        DP8139("sendarppacket1\n");
        /*
        SendArpPacket();
        DP8139("sendarppacket2\n");
        SendArpPacket();
        DP8139("sendarppacket3\n");
        SendArpPacket();
        DP8139("sendarppacket4\n");
        */
        break;
    case NI_GETPKB:
    case NI_RETPKB:
        rc = -1;
        break;
    case NI_SEND:
        ++OutUcastPkts;
        OutOctets += p->nisend.count + 18;
        rc = ni_send(p->nisend.hwa_ptr, p->nisend.buff_addr, 
                    (USHORT)p->nisend.count, (USHORT)p->nisend.type);
        break;
    case NI_POLL:
        ni_poll();
        break;
    case NI_BROADCAST:
        ++outnucastpkts;
        OutOctets += p->nibrdcast.count + 18;
        ni_send("\xFF\xFF\xFF\xFF\xFF\xFF", p->nibrdcast.buff_addr, 
               (USHORT)p->nibrdcast.count, (USHORT)p->nibrdcast.type);        
        break;
    case NI_IOCTL:
        rc = ni_ioctl(p->niioctl.cmd, p->niioctl.arg);
        break;
    default:
        rc = EINVALID;
        break;
    }

    return (rc);

}
BOOL get_netstatus()
 {
 	
 	unsigned char n;
 	 
 	n = IoReadReg8(MSR);
 	n &= 4;
 	if(n)
 		return FALSE;
 	return TRUE;
 	//IoReadReg16(DIS);
 	//return IoReadReg8(MSR);
}

/****************************************************************************
* function name: ni_ioctl
* design date:?2001-5-8, 
* function description: IOCTL call of the NiLan,The descriptions in quotes 
*                       below come from rfc1213   
* call: ni_pna_init
* called: NiLan 
* input parameter: cmd = MIB-II or SNMP command                      
* output parameter: mib_ifreq structure return through *arg   
* return value: 0, EINVALID (cmd invalid), or -1.                                               
* change record: no
*****************************************************************************/
static ULONG ni_ioctl(long cmd, long *arg)
{
    struct mib_ifreq *ifrp = (struct mib_ifreq *) arg;
    //Determine the requested command and perform the request.     
    //printf("[ni_ioctl]: default cmd[0x%x].\n", cmd) ; 
    switch((ULONG)cmd)
    {
        //pNA+ re/initialize                                          
        case SIOCPSOSINIT:
            ni_pna_init();
            break;         
        
        //Inform NI of IP address change :: No action required       
        case SIOCSIFADDR:
            break ;
            

⌨️ 快捷键说明

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