📄 driver.c
字号:
*((PULONG)inbuf) = (ULONG)0;
break;
case OID_802_3_XMIT_MORE_COLLISIONS:// 0x01020103
*((PULONG)inbuf) = (ULONG)0;
break;
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;
}
DbgPrint("go out rquery. \n");
return (Status);
}
//IRQL:DISPATCH_LEVEL
NDIS_STATUS
RReset(
OUT PBOOLEAN AddressingReset,
IN NDIS_HANDLE Context
)
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PADAPTER adapter = (PADAPTER)Context;
// ResetNIC(adapter);
// Status = StartDevice(adapter);
*AddressingReset = FALSE;
return Status;
}
//IRQL:DISPATCH_LEVEL
VOID
RReturnPkt(
IN NDIS_HANDLE Context,
IN PNDIS_PACKET Packet
)
{
PADAPTER adapter = (PADAPTER)Context;
adapter->free_rx ++;
DbgPrint("RReturnPkt. \n");;
}
//IRQL:DISPATCH_LEVEL
//#pragma LOCK_CODE
VOID
RSendPkts(
IN NDIS_HANDLE Context,
IN PPNDIS_PACKET PacketArray,
IN UINT NumberofPackets
)
/*++
Sending Packets on a Busmaster DMA NIC
--*/
{
PADAPTER adapter = (PADAPTER)Context;
UINT i;
DbgPrint("go in RSendPkts. \n");
for(i = 0; i < NumberofPackets; i ++){
SendPkt(
adapter,
PacketArray[i]
);
}//for
DbgPrint("go out RSendPkts. \n");
}
//IRQL:DISPATCH_LEVEL
//USED BY RSendPkts
//#pragma LOCK_CODE
VOID
SendPkt(
IN PADAPTER adapter,
IN PNDIS_PACKET Packet
)
/*++
发送一个包
--*/
{
UINT MapReg, cur_tx;
UINT NeedOfMap;
UINT NumOfBuf;
PNDIS_BUFFER first, next;
UINT pkt_len;
NDIS_PHYSICAL_ADDRESS_UNIT phy[MAX_MAP_REG];
UINT i, j, numOfphy = 0;
PUCHAR buf_addr;
UINT buf_len;
PUCHAR tx_buf_ptr;
if(! adapter->free_tx){
//由 NDIS 排队包
NDIS_SET_PACKET_STATUS(Packet, NDIS_STATUS_RESOURCES);
return;
}
NdisQueryPacket(
Packet,
&NeedOfMap,
&NumOfBuf,
&first,
&pkt_len
);
DbgPrint("NeedOfMap=%x, NumOfBuf=%x, pkt_len=%x \n", NeedOfMap, NumOfBuf, pkt_len);
cur_tx = adapter->dirty_tx = adapter->cur_tx;
if((NeedOfMap > MAX_MAP_REG) || (NumOfBuf > MAX_MAP_REG) || (pkt_len <= 0xff)){
DbgPrint("map-reg(%x)>%x or pkt_len(%x)<=0xff \n", NeedOfMap, MAX_MAP_REG, pkt_len);//copy buff
if(adapter->free_tx_bufs == 0){
DbgPrint("tx_bufs not enought. \n");
//由 NDIS 排队包
NDIS_SET_PACKET_STATUS(Packet, NDIS_STATUS_RESOURCES);
return;
}
//
tx_buf_ptr = adapter->tx_bufs + adapter->cur_tx_bufs * TX_BUF_SIZE;
do{
NdisQueryBuffer(
first,
&buf_addr,
&buf_len
);
NdisMoveMemory(
tx_buf_ptr,
buf_addr,
buf_len
);
tx_buf_ptr += buf_len;
NdisGetNextBuffer(
first,
&next
);
first = next;
}while(next != NULL);
adapter->tx_ring[cur_tx].bufptr = NdisGetPhysicalAddressLow(adapter->tx_buf_dma) + adapter->cur_tx_bufs * TX_BUF_SIZE;
adapter->tx_ring[cur_tx].cmdsts = OWN | pkt_len;
adapter->tx_complete[cur_tx].pkt = NULL; //FLAG
adapter->free_tx_bufs --;
adapter->cur_tx_bufs = NextTxDesc(adapter->cur_tx_bufs);
cur_tx = NextTxDesc(cur_tx);
NDIS_SET_PACKET_STATUS(Packet, NDIS_STATUS_SUCCESS);
}else{
if(adapter->free_tx < NeedOfMap){
DbgPrint("tx_ring not enought. \n");
//由 NDIS 排队包
NDIS_SET_PACKET_STATUS(Packet, NDIS_STATUS_RESOURCES);
return;
}
MapReg = 0;
// cur_tx = adapter->dirty_tx = adapter->cur_tx;
do{//每次循环就审请一个 tx_ring
NdisMStartBufferPhysicalMapping(
adapter->MiniportAdapterHandle,
first,
MapReg,
TRUE,
&phy[numOfphy],
&j
);
for(i = 0; i < j; i ++){
adapter->tx_ring[cur_tx].bufptr = NdisGetPhysicalAddressLow(phy[numOfphy].PhysicalAddress);
adapter->tx_ring[cur_tx].cmdsts = OWN | phy[numOfphy].Length | MORE;
adapter->tx_complete[cur_tx].buff = first;
adapter->tx_complete[cur_tx].MapReg = MapReg;
adapter->tx_complete[cur_tx].pkt = Packet; //有冗余
cur_tx = NextTxDesc(cur_tx);
adapter->free_tx --;
MapReg ++;
numOfphy ++;
}
NdisGetNextBuffer(
first,
&next
);
first = next;
}while(next != NULL);
//清除最后一个 tx_ring[].cmdsts 的 MORE
adapter->tx_ring[cur_tx - 1].cmdsts &= ~MORE;
NDIS_SET_PACKET_STATUS(Packet, NDIS_STATUS_PENDING);
}//if
adapter->cur_tx = cur_tx;
//start dma
NdisRawWritePortUlong(adapter->ioaddr + cr, TxENA);
}
//IRQL:DIRQL
//USED BY NDIS
//#pragma LOCK_CODE
VOID
RIsr(
OUT PBOOLEAN InterruptRecognized,
OUT PBOOLEAN QueueMiniportHandleInterrupt,
IN NDIS_HANDLE Context
)
{
PADAPTER adapter = (PADAPTER)Context;
u32 status;
NdisRawReadPortUlong(adapter->ioaddr + isr, &status);
if (status & (HIBERR|TxURN|TxERR|TxIDLE|RxORN|RxERR|RxOK)){
NdisRawWritePortUlong(adapter->ioaddr + ier, 0);
adapter->curISR = status;
DbgPrint("RIsr:adapter->curISR=%x \n", adapter->curISR);
//is our interrupt
*InterruptRecognized = TRUE;
*QueueMiniportHandleInterrupt = TRUE;
}else{
/* nothing intresting happened */
*InterruptRecognized = FALSE;
*QueueMiniportHandleInterrupt = FALSE;
}
return;
}
//IRQL:DISPATCH_LEVEL
//USED BY NDIS
//#pragma LOCK_CODE
VOID
RIsrDpc(
IN NDIS_HANDLE Context
)
{
PADAPTER adapter = (PADAPTER)Context;
/* why dow't we break after Tx/Rx case ?? keyword: full-duplex */
if (adapter->curISR & (RxORN | RxERR|RxOK))
/* Rx interrupt */
RxInt(adapter);
if (adapter->curISR & (RxORN | RxERR))
/* load Receive Descriptor Register */
NdisRawWritePortUlong(adapter->ioaddr + cr, RxENA);
if (adapter->curISR & (TxURN | TxERR | TxIDLE))
/* Tx interrupt */
TxInt(adapter);
/* something strange happened !!! */
if (adapter->curISR & HIBERR) {
DbgPrint("Abnormal interrupt,adapter->curISR %#8.8x.\n", adapter->curISR);
}
NdisRawWritePortUlong(adapter->ioaddr + ier, IE);
}
//IRQL:PASSIVE_LEVEL
//USED BY RInit
//#pragma PAGE_CODE
VOID
FreeRes(
PADAPTER adapter
)
{
int i;
NdisFreeSpinLock(&adapter->lock);
//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
NdisMDeregisterInterrupt(adapter->MiniportAdapterHandle);
//free tx_ring
if(adapter->tx_ring != NULL)
NdisMFreeSharedMemory(
adapter->MiniportAdapterHandle,
NUM_TX_DESC * sizeof(RING_STRU),
FALSE,//not cached
adapter->tx_ring,
adapter->tx_ring_dma
);
//free rx_buf
if(adapter->rx_bufs != NULL)
NdisMFreeSharedMemory(
adapter->MiniportAdapterHandle,
RX_BUF_SIZE * NUM_RX_DESC,
FALSE,//not cached
adapter->rx_bufs,
adapter->rx_buf_dma
);
//free rx_ring
if(adapter->rx_ring != NULL)
NdisMFreeSharedMemory(
adapter->MiniportAdapterHandle,
NUM_RX_DESC * sizeof(RING_STRU),
FALSE,//not cached
adapter->rx_ring,
adapter->rx_ring_dma
);
//free tx_buf
if(adapter->tx_bufs != NULL)
NdisMFreeSharedMemory(
adapter->MiniportAdapterHandle,
TX_BUF_SIZE * NUM_TX_DESC,
FALSE,//not cached
adapter->tx_bufs,
adapter->tx_buf_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
ResetNIC(
PADAPTER adapter
)
{
int i = 0;
ULONG status = TxRCMP | RxRCMP;
ULONG TmpISR;
NdisRawWritePortUlong(adapter->ioaddr + ier, 0);
NdisRawWritePortUlong(adapter->ioaddr + imr, 0);
NdisRawWritePortUlong(adapter->ioaddr + rfcr, 0);
NdisRawWritePortUlong(adapter->ioaddr + cr, RxRESET | TxRESET | RESET);
/* Check that the chip has finished the reset. */
do{
NdisRawReadPortUlong(adapter->ioaddr + isr, &TmpISR);
status ^= TmpISR & status;
}while (status && (i++ < 1000));
NdisRawWritePortUlong(adapter->ioaddr + cfg, PESEL);
DbgPrint("Reset operate complete. \n");
}
//IRQL:PASSIVE_LEVEL
//USED BY RInit
//#pragma PAGE_CODE
NDIS_STATUS
StartDevice(
PADAPTER adapter
)
{
UCHAR TmpCM;
ULONG Tmplong;
UINT i;
u32 status;
init_rxfilter(adapter);
set_rx_mode(adapter);
check_mode(adapter);
/* Enable all known interrupts by setting the interrupt mask. */
NdisRawWritePortUlong(adapter->ioaddr + imr, RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE);
NdisRawWritePortUlong(adapter->ioaddr + ier, IE);
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 = NDIS_STATUS_SUCCESS;
UINT i;
PVOID VirtualAddress;
NDIS_PHYSICAL_ADDRESS PhysicalAddress;
ULONG phy,phy1;
NdisAllocateSpinLock(&adapter->lock);
//tx_buf
NdisMAllocateSharedMemory(
adapter->MiniportAdapterHandle,
TX_BUF_SIZE * NUM_TX_DESC,
FALSE,//not cached
&adapter->tx_bufs, //虚拟地址
&PhysicalAddress //物理地址
);
if(adapter->tx_bufs == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
adapter->tx_buf_dma = PhysicalAddress;
adapter->cur_tx_bufs = 0;
adapter->free_tx_bufs = NUM_TX_DESC;
//tx_ring
NdisMAllocateSharedMemory(
adapter->MiniportAdapterHandle,
NUM_TX_DESC * sizeof(RING_STRU),
FALSE,//not cached
(PVOID)&adapter->tx_ring, //虚拟地址
&PhysicalAddress //物理地址
);
if(adapter->tx_ring == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
adapter->tx_ring_dma = PhysicalAddress;
phy = NdisGetPhysicalAddressLow(PhysicalAddress);
//align to 32?
DbgPrint("tx_ring=%x, tx_ring_dma=%x \n", adapter->tx_ring, phy);
for(i = 0; i < NUM_TX_DESC; i ++){
adapter->tx_ring[i].link = phy + (i+1) * sizeof(RING_STRU);
adapter->tx_ring[i].cmdsts = 0;
adapter->tx_ring[i].bufptr = 0;
}
adapter->tx_ring[i-1].link = phy;
/* load Transmit Descriptor Register */
NdisRawWritePortUlong(adapter->ioaddr + txdp, phy);
//rx_buf
NdisMAllocateSharedMemory(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -