📄 driver.c
字号:
case OID_802_3_XMIT_DEFERRED:// 0x01020201
*((PULONG)inbuf) = (ULONG)0;
break;
case OID_802_3_XMIT_MAX_COLLISIONS:// 0x01020202
*((PULONG)inbuf) = (ULONG)0;
break;
case OID_802_3_RCV_OVERRUN:// 0x01020203
*((PULONG)inbuf) = (ULONG)0;
break;
case OID_802_3_XMIT_UNDERRUN:// 0x01020204
*((PULONG)inbuf) = (ULONG)0;
break;
case OID_802_3_XMIT_HEARTBEAT_FAILURE:// 0x01020205
*((PULONG)inbuf) = (ULONG)0;
break;
case OID_802_3_XMIT_TIMES_CRS_LOST:// 0x01020206
*((PULONG)inbuf) = (ULONG)0;
break;
case OID_802_3_XMIT_LATE_COLLISIONS:// 0x01020207
*((PULONG)inbuf) = (ULONG)0;
break;
//
// Required statistics
//
case OID_GEN_XMIT_OK:// 0x00020101
*((PULONG)inbuf) = adapter->XMIT_OK;
break;
case OID_GEN_RCV_OK:// 0x00020102
*((PULONG)inbuf) = adapter->RCV_OK;
break;
case OID_GEN_XMIT_ERROR:// 0x00020103
*((PULONG)inbuf) = adapter->XMIT_ERR;
break;
case OID_GEN_RCV_ERROR:// 0x00020104
*((PULONG)inbuf) = adapter->RCV_ERR;
break;
case OID_GEN_RCV_NO_BUFFER:// 0x00020105
*((PULONG)inbuf) = adapter->RCV_NO_BUFFER;
break;
default:
break;
}
return (Status);
}
//IRQL:DISPATCH_LEVEL
VOID
RReturnPkt(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet
)
{
PADAPTER adapter = (PADAPTER)MiniportAdapterContext;
//GetBackPkt(adapter, Packet);
}
//IRQL:DISPATCH_LEVEL
//#pragma LOCK_CODE
VOID
RSendPkts(
IN NDIS_HANDLE MiniportAdapterContext,
IN PPNDIS_PACKET PacketArray,
IN UINT NumberofPackets
)
/*++
Sending Packets on a Busmaster DMA NIC
--*/
{
PADAPTER adapter = (PADAPTER)MiniportAdapterContext;
UINT i;
// DbgPrint("RSendPkts:NumberofPackets=%x \n", NumberofPackets);
for(i = 0; i < NumberofPackets; i ++){
SendPkt(
adapter,
PacketArray[i]
);
}//for
}
//IRQL:DISPATCH_LEVEL
//USED BY RSendPkts
//#pragma LOCK_CODE
BOOLEAN
SendPkt(
IN PADAPTER adapter,
IN PNDIS_PACKET Packet
)
/*++
发送一个包
--*/
{
static UINT pkt_len;
PUCHAR vaddr;
ULONG paddr;
if(adapter->FreeTxDesc > 0){//有空闲的描述寄存器
adapter->FreeTxDesc --;
vaddr = adapter->tx_bufs + (adapter->cur_tx * TX_BUF_SIZE);
paddr = NdisGetPhysicalAddressLow(adapter->tx_bufs_dma) + (adapter->cur_tx * TX_BUF_SIZE);
//1.COPY 包内容
pkt_len = CopyPktToBuf(
Packet,
vaddr
);
adapter->xmit_byte += pkt_len;
//dma oparater
NDIS_SET_PACKET_STATUS(Packet, NDIS_STATUS_SUCCESS);
IssueCMD(adapter, adapter->cur_tx, paddr, pkt_len);
adapter->cur_tx = NextTxDesc(adapter->cur_tx);
return TRUE;
}//has free tsd
DbgPrint("SendPkt failure. no free txdesc. pkt_len=%x,cur_tx=%x \n", pkt_len, adapter->cur_tx);
//由 NDIS 排队包
NDIS_SET_PACKET_STATUS(Packet, NDIS_STATUS_RESOURCES);
return FALSE;
}
//IRQL:DISPATCH_LEVEL
//USED BY SendPkt
VOID
IssueCMD(
PADAPTER adapter,
UINT cur_tx,
ULONG paddr,
UINT len
)
{
ULONG offset = cur_tx << 2;
ULONG tmpTSD;
UCHAR tmpCMD;
NdisRawReadPortUchar(adapter->ioaddr + ChipCmd, &tmpCMD);
ASSERT(tmpCMD & CmdTxEnb);
if(len < MIN_ETHERNET_FRAME_SIZE)
len = MIN_ETHERNET_FRAME_SIZE;
NdisRawWritePortUlong(
adapter->ioaddr + TxAddr0 + offset,
paddr
);
NdisRawWritePortUlong(
adapter->ioaddr + TxStatus0 + offset,
len | (2 << 16)//64
);
}
//IRQL:DISPATCH_LEVEL
//USED BY SendPkt
//#pragma LOCK_CODE
ULONG
CopyPktToBuf(
PNDIS_PACKET packet,
PUCHAR buff
)
{
PUCHAR WritePtr = buff;
UINT BufferCount;
PNDIS_BUFFER srcBuff, NextBuff;
UINT PacketLength, BufferLength;
UINT i;
PUCHAR Address;
NdisQueryPacket(
packet,
NULL,
&BufferCount,
&srcBuff,
&PacketLength
);
ASSERT(PacketLength <= TX_BUF_SIZE); //每个发送包长
for(i = 0; i < BufferCount; i ++){
NdisQueryBuffer(
srcBuff,
&Address,
&BufferLength
);
NdisMoveMemory(
WritePtr,
Address,
BufferLength
);
WritePtr += BufferLength;
NdisGetNextBuffer(
srcBuff,
&NextBuff
);
srcBuff = NextBuff;
}//for
return PacketLength;
}
typedef struct tagISR_STATUS{
USHORT ROK:1;
USHORT RER:1;
USHORT TOK:1;
USHORT TER:1;
USHORT RXOVW:1;
USHORT LINKCHG:1;
USHORT RXFIFOOVW:1;
USHORT REV:6;
USHORT LENCHG:1;
USHORT TIMEOUT:1;
USHORT SERR:1;
}ISR_STATUS, *PISR_STATUS;
//IRQL:DIRQL
//USED BY NDIS
//#pragma LOCK_CODE
VOID
RIsr(
OUT PBOOLEAN InterruptRecognized,
OUT PBOOLEAN QueueMiniportHandleInterrupt,
IN NDIS_HANDLE MiniportAdapterContext
)
{
PADAPTER adapter = (PADAPTER)MiniportAdapterContext;
USHORT curISR, Tmp;
UCHAR cmd;
//read isr status
NdisRawReadPortUshort(adapter->ioaddr + IntrStatus, &curISR);
NdisRawWritePortUshort(adapter->ioaddr + IntrStatus, curISR);
DbgPrint("RIsr:IntrStatus=%x,FreeTxDesc=%x \n", curISR, adapter->FreeTxDesc);
if(curISR & R39_INTERRUPT_MASK){
NdisRawWritePortUshort(adapter->ioaddr + IntrMask, 0);
adapter->curISR = curISR & R39_INTERRUPT_MASK;
//is our interrupt
*InterruptRecognized = TRUE;
*QueueMiniportHandleInterrupt = TRUE;
}else{
//is not our interrupt
*InterruptRecognized = FALSE;
*QueueMiniportHandleInterrupt = FALSE;
}
}
//IRQL:DISPATCH_LEVEL
//USED BY NDIS
//#pragma LOCK_CODE
VOID
RIsrDpc(
IN NDIS_HANDLE MiniportAdapterContext
)
{
PADAPTER adapter = (PADAPTER)MiniportAdapterContext;
UCHAR TmpTCR;
ULONG Tmplong;
USHORT cur_rx;
USHORT link_changed;
USHORT write_ptr;
if(adapter->curISR & RxUnderrun){
DbgPrint("RIsrDpc:RxUnderrun(link chg) \n");
}
//TX
if((adapter->curISR & TxOK)||(adapter->curISR & TxErr)){
TxInt(adapter);
}
//RX
if(adapter->curISR & RxOK){
RxInt(adapter);
}
if( adapter->curISR & (RxErr|RxOverflow|RxFIFOOver)){
//chip write ptr
NdisRawReadPortUshort(adapter->ioaddr + RxBufAddr, &write_ptr);
DbgPrint("RIsrDpc:RxErr|RxOverflow|RxFIFOOver, write_ptr=%x,read_ptr=%x \n", write_ptr, adapter->read_ptr);
//更新 RxBufPtr(读寄存器) -> RxReadOffset
adapter->read_ptr = write_ptr % RING_BUF_SIZE;
NdisRawWritePortUshort(adapter->ioaddr + RxBufPtr, adapter->read_ptr - 16);
NdisRawWritePortUshort(adapter->ioaddr + IntrStatus, RxOK);
}
//enable interrupt
NdisRawWritePortUshort(adapter->ioaddr + IntrMask, R39_INTERRUPT_MASK);
}
//IRQL:PASSIVE_LEVEL
//USED BY RInit
//#pragma PAGE_CODE
VOID
FreeRes(
PADAPTER adapter
)
{
int i;
//free i/o
if(adapter->ioaddr != 0){
NdisMDeregisterIoPortRange(
adapter->MiniportAdapterHandle,
adapter->BaseIO,
0x100,
(PVOID)&adapter->ioaddr
);
}
//free dma
if(adapter){
NdisMFreeMapRegisters(adapter->MiniportAdapterHandle);
}
//free interrupt
if(adapter->IRQVector > 0){
NdisMDeregisterInterrupt(adapter->MiniportAdapterHandle);
}
//free tx_bufs
if(adapter->tx_bufs != NULL)
NdisMFreeSharedMemory(
adapter->MiniportAdapterHandle,
TX_BUF_SIZE * NUM_OF_DESC,
FALSE,//not cached
adapter->tx_bufs,
adapter->tx_bufs_dma
);
//free tx_bufs
if(adapter->rx_bufs != NULL)
NdisMFreeSharedMemory(
adapter->MiniportAdapterHandle,
RX_BUF_SIZE * NUM_OF_PACKETS,
FALSE,//not cached
adapter->rx_bufs,
adapter->rx_bufs_dma
);
//free rx_ring
if(adapter->rx_ring != NULL)
NdisMFreeSharedMemory(
adapter->MiniportAdapterHandle,
RING_BUF_SIZE + RING_BUF_PAD,
FALSE,//not cached
adapter->rx_ring,
adapter->rx_ring_dma
);
if(adapter->buf_pool != NULL)
NdisFreeBufferPool(adapter->buf_pool);
if(adapter->pkt_pool != NULL)
NdisFreeBufferPool(adapter->pkt_pool);
//free adapter mem
NdisFreeMemory(
(PVOID)adapter,
sizeof(ADAPTER),
0
);
}
VOID
OpenPOWNER(
PADAPTER adapter
)
{
UCHAR TmpUCHAR;
NdisRawReadPortUchar(adapter->ioaddr + Config1, &TmpUCHAR);
if(LWAKE & TmpUCHAR){
DbgPrint("oh, no powner. \n");
TmpUCHAR &= ~LWAKE;
TmpUCHAR |= Cfg1_PM_Enable;
//unlock
NdisRawWritePortUchar(adapter->ioaddr + Cfg9346, Cfg9346_Unlock);
NdisRawWritePortUchar(adapter->ioaddr + Config1, TmpUCHAR);
NdisRawReadPortUchar(adapter->ioaddr + Config4, &TmpUCHAR);
TmpUCHAR &= ~LWPTN;
NdisRawWritePortUchar(adapter->ioaddr + Config4, TmpUCHAR);
//lock
NdisRawWritePortUchar(adapter->ioaddr + Cfg9346, Cfg9346_Lock);
}
}
VOID
ResetNIC(
PADAPTER adapter
)
{
UCHAR TmpCM;
//reset device
NdisRawWritePortUchar(adapter->ioaddr + ChipCmd, CmdReset|1);
//test rest success ?
do{
NdisRawReadPortUchar(adapter->ioaddr + ChipCmd, &TmpCM);
}while(TmpCM & CmdReset);
DbgPrint("Reset operate complete. ChipCmd=%x \n", TmpCM);
//enable io,mem
NdisRawReadPortUchar(adapter->ioaddr + Config1, &TmpCM);
ASSERT(TmpCM & Cfg1_PIO);
ASSERT(TmpCM & Cfg1_MMIO);
}
//IRQL:PASSIVE_LEVEL
//USED BY RInit
//#pragma PAGE_CODE
NDIS_STATUS
StartDevice(
PADAPTER adapter
)
{
UCHAR TmpCM;
ULONG Tmplong;
UINT i;
USHORT TmpShort;
// SetMII(adapter);
//enable dma Tx/Rx
NdisRawWritePortUchar(adapter->ioaddr + ChipCmd, CmdRxEnb | CmdTxEnb);
//config rx
NdisRawWritePortUlong(adapter->ioaddr + RxConfig, rtl8139_rx_config);
//config tx
NdisRawWritePortUlong(adapter->ioaddr + TxConfig, RL_TXCFG_CONFIG);
/* init Rx ring buffer DMA address */
NdisRawWritePortUlong(adapter->ioaddr + RxBuf, NdisGetPhysicalAddressLow(adapter->rx_ring_dma));
//clear 0
NdisRawWritePortUlong(adapter->ioaddr + RxMissed, 0);
//all mult
adapter->PacketFilter = NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_MULTICAST;
NdisRawWritePortUlong(adapter->ioaddr + MAR0, 0x80004000);
NdisRawWritePortUlong(adapter->ioaddr + MAR0 + 4, 0);
((PULONG)adapter->mc_filter)[0] = 0x80004000;
((PULONG)adapter->mc_filter)[1] = 0;
//enable dma Tx/Rx
NdisRawWritePortUchar(adapter->ioaddr + ChipCmd, CmdRxEnb | CmdTxEnb);
//enable int
NdisRawWritePortUshort(adapter->ioaddr + IntrMask, R39_INTERRUPT_MASK);
return NDIS_STATUS_SUCCESS;
}
//IRQL:PASSIVE_LEVEL
//USED BY RInit
//#pragma PAGE_CODE
NDIS_STATUS
AllocRes(
PADAPTER adapter
)
{
PUCHAR Addr;
UINT bufsize;
NDIS_STATUS Status;
UINT i;
PVOID VirtualAddress;
NDIS_PHYSICAL_ADDRESS PhysicalAddress;
ULONG phy;
//rx_ring
NdisMAllocateSharedMemory(
adapter->MiniportAdapterHandle,
RING_BUF_SIZE + RING_BUF_PAD,
FALSE,//not cached
&adapter->rx_ring, //虚拟地址
&PhysicalAddress //物理地址
);
if(adapter->rx_ring == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
adapter->rx_ring_dma = PhysicalAddress;
//align to 32?
DbgPrint("rx_ring=%x, rx_ring_dma=%x \n",adapter->rx_ring,NdisGetPhysicalAddressLow(PhysicalAddress));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -