📄 drv8139.c
字号:
//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 + -