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

📄 drv8139.c

📁 psos嵌入式操作系统平台下的8139驱动程序,比较难得.
💻 C
📖 第 1 页 / 共 5 页
字号:
        //Inform Pt-to-Pt NI of destination addr :: Not applicable 
        case SIOCSIFDSTADDR:
            break;    
                     
        //Set NI Flags                                               
        case SIOCSIFFLAGS:
        {
            int s = socket(AF_INET, SOCK_DGRAM, UDP);
            struct ifreq ifr_ifru;

            if (s == -1)
                return errno;
	
	       ifr_ifru.ifr_ifno = IfNum;
            ioctlsocket(s, SIOCGIFFLAGS, (char *)&ifr_ifru);

            if (ifr_ifru.ifr_flags & IFF_UP)      //Turn the chip on
            {
            }
            else                                  //Turn the chip off
            {
            }

            closesocket(s);
            break;
        }
            
        case SIOCGIFDESCR:  //Get NI descriptor  

        // "A textual string containing information about the interface.
        // This string should include the name of the manufacturer, the 
        // product name and the version of the hardware interface." 
		   
        if (LanType == REALTEK_8139_ID)
            ifrp->ie_descr = "REALTEK 8139 Ethernet Controller - PCI";
        else
            ifrp->ie_descr = "REALTEK other Ethernet Controller - PCI";
            DP8139("SIOCGIFDESCR\n");
        break;

                                                           
        case SIOCGIFTYPE: //Get NI type
      
            // "The type of interface, distinguished according to the       
            // physical/link protocol(s) immediately `below' the network    
            // layer in the protocol stack." "ETHERNET"                     
            ifrp->ie_type = 6;
            break;
    
                                                             
        case SIOCGIFMTUNIT://Get NI MTU
            // "The size of the largest datagram which can be sent/received 
            // on the interface, specified in octets. For interfaces that   
            // are used for transmitting network datagrams, this is the size
            // of the largest network datagram that can be sent on the      
            // interface."                                                 
            {
                int s = socket(AF_INET, SOCK_DGRAM, UDP);
                struct ifreq ifr_ifru;

                if (s == -1)
                    return errno;

                ifr_ifru.ifr_ifno = IfNum;
                ioctlsocket(s, SIOCGIFMTU, (char *) &ifr_ifru);
                ifrp->ie_mtu = ifr_ifru.ifr_mtu;
                closesocket(s);
                break;
            }
                                                           
        case SIOCGIFSPEED://Get NI speed 
            // "An estimate of the interface's current bandwidth in bits per
            //  second. For interfaces which do not vary in bandwidth or for
            //  those where no accurate estimation can be made, this object
            //  should contain the nominal bandwidth."                     
            ifrp->ie_speed = lan_spd;    // Current operational speed. //lan_spd???
            break;
                                               
        case SIOCGIFPHYSADDRESS://Get NI physical address 
            // "The interface's address at the protocol layer immediately  
            // `below' the network layer in the protocol stack. For        
            // interfaces which do not have such an address (e.g., a serial 
            // line), this object should contain an octet string of zero   
            // length."                                                    
            {
                ULONG i;

                ifrp->ie_physaddress.sa_family = 0;
                for (i = 0; i < 6; i++)
                    ifrp->ie_physaddress.sa_data[i] = OurAddress.byte[i];
                break;
            }
            // "The desired state of the interface. The testing(3) state    
            // indicates that no operational packets can be passed."        
            // Get NI administrative status     
        case SIOCGIFADMINSTATUS:
            ifrp->ie_adminstatus = ifadminstatus;  
            break;
                                           
        case SIOCSIFADMINSTATUS://Set NI administrative status 
        {
            int s = socket(AF_INET, SOCK_DGRAM, UDP);
            struct ifreq ifr_ifru;

            if (s == -1)
               return errno;

            ifr_ifru.ifr_ifno = IfNum;
            ioctlsocket(s, SIOCGIFFLAGS, (char *) &ifr_ifru);

            if (ifr_ifru.ifr_flags & IFF_UP)
            {
                ifr_ifru.ifr_flags |= IFF_UP;
                ifadminstatus = 1;       //up 
            }
            else
            {
                ifr_ifru.ifr_flags &= ~IFF_UP;
                ifadminstatus = 2;       //down
            }

            ioctlsocket(s, SIOCSIFFLAGS, (char *) &ifr_ifru);
            closesocket(s);
            break;
        }
                                            
        case SIOCGIFOPERSTATUS://Get NI operational status  
            // "The current operational state of the interface. The         
            // testing(3) state indicates that no operational packets can   
            // be passed."           
            ifrp->ie_operstatus = 1;    //up
            break;
                             
        case SIOCGIFLASTCHANGE:// Get sysUpTime at last status change     
            // "The value of sysUpTime at the time the interface entered   
            // its current operational state. If the current state was     
            // entered prior to the last re-initialization of the local   
            // network management subsystem, then this object contains a   
            // zero value."                                               
            // This statistic cannot be calculated without being able to  
            // get the value of sysUpTime.  Since that is maintained by    
            // the SNMP agent, not the NI, there is no way to calculated   
            // it here.  As shipped, the NI outputs 0 in response to the   
            // SIOCGIFLASTCHANGE command.  Those using ISI software to    
            // implement SNMP agents should make the value of sysUpTime    
            // available globally and add code in this module to calculate 
            // ifLastChange.       
            DP8139("SIOCGIFLASTCHANGE\n");    
            ifrp->ie_lastchange = 0;
            break;
                                      
        case SIOCGIFINOCTETS://Get number of octets received   
            // "The total number of octets received on the interface,    
            // including framing characters."                             
            ifrp->ie_inoctets = InOctets;
            break;
                                  
        case SIOCGIFINUCASTPKTS://Get number of unicast packets rcvd   
            //"The number of subnetwork-unicast packets delivered to a   
            //higher-layer protocol."  
            ifrp->ie_inucastpkts = InUcastPkts;
            break;
                                  
        case SIOCGIFINNUCASTPKTS://Get number of multicast packets rcvd 
            // "The number of non-unicast (i.e., subnetwork-broadcast or   
            // subnetwork-multicast) packets delivered to a higher-layer   
            // protocol."  
            ifrp->ie_innucastpkts = innucastpkts;
            break;
                                        
        case SIOCGIFINDISCARDS://Get number of packets discarded 
            // "The number of inbound packets which were chosen to be     
            // discarded even though no errors had been detected to prevent
            // their being deliverable to a higher-layer protocol. One     
            // possible reason for discarding such a packet could be to    
            // free up buffer space."        
                                     
            //MissedFrames += (ioLongRead(CSR8) & LAN_CSR8_CNTR);//old
            ifrp->ie_indiscards = MissedFrames;
            break;
                                 
        case SIOCGIFINERRORS:// Get number of packets rcvd with errors 
            // "The number of inbound packets that contained errors      
            // preventing them from being deliverable to a higher-layer   
            // protocol."    
            ifrp->ie_inerrors = InErrors;
            break;
                     
        case SIOCGIFINUNKNOWNPROTOS:// Get number of packets rcvd with unknown protocol  
            // "The number of packets received via the interface which were
            // discarded because of an unknown or unsupported protocol."
            ifrp->ie_inunknownprotos = InUnknownProtos;  
            break;
                                     
        case SIOCGIFOUTOCTETS://Get number of octets transmitted  
            // "The total number of octets transmitted out of the         
            // interface, including framing characters."   
            ifrp->ie_outoctets = OutOctets;
            break;
             
        case SIOCGIFOUTUCASTPKTS://Get number of unicast packets tmtd  
            // "The total number of packets that higher-level protocols   
            // requested be transmitted to a subnetwork-unicast address,  
            // including those that were discarded or not sent." 
            ifrp->ie_outucastpkts = OutUcastPkts;
            break;
            // Get number of multicast packets tmtd                           
        case SIOCGIFOUTNUCASTPKTS:
            // "The total number of packets that higher-level protocols    
            // requested be transmitted to a non-unicast (i.e., a          
            // subnetwork-broadcast or subnetwork-multicast) address,      
            // including those that were discarded or not sent."    
            ifrp->ie_outnucastpkts = outnucastpkts;
                break;
        case SIOCGIFOUTDISCARDS:
            // "The number of outbound packets which were chosen to be     
            // discarded even though no errors had been detected to prevent
            // their being transmitted. One possible reason for discarding 
            // such a packet could be to free up buffer space."    
            ifrp->ie_outdiscards = 0;       //no drops are don     
            break;
        case SIOCGIFOUTERRORS:
            // "The number of outbound packets that could not be          
            // transmitted because of errors."           
            ifrp->ie_outerrors = outerrors;
            break;
        case SIOCGIFOUTQLEN:
            //"The length of the output packet queue (in packets)."      
            break;
            // Get NI specific object                                     
        case SIOCGIFSPECIFIC:
            // "A reference to MIB definitions specific to the particular  
            // media being used to realize the interface. For example, if 
            // the interface is realized by an ethernet, then the value of 
            // this object refers to a document defining objects specific  
            // to ethernet. If this information is not present, its value  
            // should be set to the OBJECT IDENTIFIER { 0 0 }, which is a  
            // syntatically valid object identifier, and any conformant   
            // implementation of ASN.1 and BER must be able to generate and
            // recognize this value."      
                ifrp->ie_specific = "0.0";
               break; 
       	 // 对于以太网,当地址中最高字节的最低位设置为1时表示该地址是一个多播地址,
       	 // 用十六进制可表示为01:00:00:00:00:00(以太网广播地址ff:ff:ff:ff:ff:ff可
       	 // 看作是以太网多播地址的特例)。
	case SIOCADDMCAST:
	{
            struct mib_ifreq *mib_ifrp = (struct mib_ifreq *)arg;

            register UCHAR *addr =
                (UCHAR *)&mib_ifrp->ie_physaddress.sa_data[0];
 
            if ((addr[0] & 0x01) != 1) // 检查是否为多播地址 
                return(EINVALID);
 
            return(lan_add_mcast(addr));
        }
        case SIOCDELMCAST:
        {   
            struct mib_ifreq *mib_ifrp = (struct mib_ifreq *)arg;

            register UCHAR *addr =
                (UCHAR *)&mib_ifrp->ie_physaddress.sa_data[0];
 
            if ((addr[0] & 0x01) != 1) // 检查是否为多播地址 
                return(EINVALID);
 
            return(lan_del_mcast(addr));
        }
        case SIOCMAPMCAST:
            return(map_mcast((struct ni_map_mcast *)arg));
        
        
        default:
            //printf("[ni_ioctl]: default cmd[0x%x].\n", cmd) ;
            return EINVALID;
    }

    return 0;
}

/****************************************************************************
* function name: RxBufDetach
* design date:?2001-5-8, 
* function description: Return a receive buffer to the free list.
*                       This is the "Free Routine" called by pNA+ after it has       
*                       unlinked the buffer from the message block structure to      
*                       return it to the driver's buffer poll.   
* call: none
* called: pNA+ 
* input parameter: buf_ptr: Pointer to the buffer being returned                    
* output parameter: none
* return value: none                                               
* change record: none
*****************************************************************************/
static void RxBufDetach(LAN_RX_BUF *buf_ptr)
{
    Bool ien;
    
    intClear(V_LAN);

    // Link returned buffer to the buffer previously at the top of the  
    // free queue and point "free_head" to the newly returned buffer.    
    buf_ptr->next = RxPktFreeHead;
    RxPktFreeHead = buf_ptr;
    FreeRxPktCount++;
    
    intRaise(V_LAN);
}

//IP地址冲突时,响应Arp请求
//add by zhengkun
void SendArqP(UCHAR *RxPtr)
{
	char data[42];
    int i;
    UInt32 status;
    for(i = 0; i < 6; i++)
    {
        data[i] = RxPtr[6+i];
        data[i+6] = SelfAddr[i];
    }
    
    data[12] = 0x08;
    data[13] = 0x06;
    
    data[14] = 0x00;
    data[15] = 0x01;
    
    data[16] = 0x08;
    data[17] = 0x00;
    
    data[18] = 0x06;
    data[19] = 0x04;
    
    data[20] = 0x00;
    data[21] = 0x02;//1:请求操作 2:应当操作 
    
    for(i = 0; i < 6; i++)
        data[i+22] = SelfAddr[i];
    data[28] = (LanIPaddr >> 24) & 0xff;
    data[29] = (LanIPaddr >> 16) & 0xff;
    data[30] = (LanIPaddr >> 8) & 0xff;
    data[31] = LanIPaddr & 0xff;

    //目标Mac地址,目标IP    
    for(i = 0; i < 10; i++)
        data[i+32] = RxPtr[22+i];
        
    //发送
    memcpy((void*)(TxDesc[CurDescId]), (void*)data, 42);
    
    _cache_copyback((void*)(int)(TxDesc[

⌨️ 快捷键说明

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