📄 driver.c
字号:
//tx_bufs
NdisMAllocateSharedMemory(
adapter->MiniportAdapterHandle,
TX_BUF_SIZE * NUM_OF_DESC,
FALSE,//not cached
&adapter->tx_bufs, //虚拟地址
&PhysicalAddress //物理地址
);
if(adapter->tx_bufs == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
adapter->tx_bufs_dma = PhysicalAddress;
//align to 32
DbgPrint("tx_bufs=%x, tx_bufs_dma=%x \n",adapter->tx_bufs,NdisGetPhysicalAddressLow(PhysicalAddress));
//rx_bufs
NdisMAllocateSharedMemory(
adapter->MiniportAdapterHandle,
RX_BUF_SIZE * NUM_OF_PACKETS,
FALSE,//not cached
&adapter->rx_bufs, //虚拟地址
&PhysicalAddress //物理地址
);
if(adapter->rx_bufs == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
adapter->rx_bufs_dma = PhysicalAddress;
//align to 32
DbgPrint("rx_bufs=%x, rx_bufs_dma=%x \n",adapter->rx_bufs,NdisGetPhysicalAddressLow(PhysicalAddress));
//分配 Packet pool,Buffer pool to rx
NdisAllocatePacketPool(
&Status,
&adapter->pkt_pool,
NUM_OF_PACKETS,
16
);
if(Status != NDIS_STATUS_SUCCESS)
return STATUS_INSUFFICIENT_RESOURCES;
DbgPrint("pkt_pool = %x \n", adapter->pkt_pool);
NdisAllocateBufferPool(
&Status,
&adapter->buf_pool,
NUM_OF_PACKETS
);
if(Status != NDIS_STATUS_SUCCESS)
return STATUS_INSUFFICIENT_RESOURCES;
DbgPrint("buf_pool = %x \n", adapter->buf_pool);
for(i = 0; i < NUM_OF_PACKETS; i ++){
NdisAllocatePacket(
&Status,
&adapter->pkt_desc[i],
adapter->pkt_pool
);
if(Status != NDIS_STATUS_SUCCESS)
return STATUS_INSUFFICIENT_RESOURCES;
NdisAllocateBuffer(
&Status,
&adapter->buf_desc[i],
adapter->buf_pool,
adapter->rx_bufs + (i * RX_BUF_SIZE),
RX_BUF_SIZE
);
//connection buf_desc->pkt_desc
NdisChainBufferAtBack(
adapter->pkt_desc[i],
adapter->buf_desc[i]
);
}
adapter->read_ptr = 0;
adapter->FreeRxPkt = NUM_OF_PACKETS;
adapter->cur_rx = 0;
adapter->dirty_rx = 0;
adapter->FreeTxDesc = NUM_OF_DESC;
adapter->cur_tx = 0;
adapter->dirty_tx = 0;
return NDIS_STATUS_SUCCESS;
}
//IRQL:DISPATCH_LEVEL
//USED BY RIsrDpc
VOID
TxInt(
PADAPTER adapter
)
/*++
发送中断处理
--*/
{
UINT i = 0;
ULONG Offset;
ULONG tmpTSD;
// DbgPrint("TxInt:adapter->dirty_tx=%x \n", adapter->dirty_tx);
while((i < 4)&&(adapter->FreeTxDesc < 4)){
Offset = (i) << 2;
NdisRawReadPortUlong(adapter->ioaddr + TxStatus0 + Offset, &tmpTSD);
if(tmpTSD & (TxStatOK | TxUnderrun | TxAborted)){
//err
if(tmpTSD & (TxUnderrun | TxAborted)){
adapter->XMIT_ERR ++;
}else{
adapter->XMIT_OK ++;
}
adapter->FreeTxDesc ++;
// adapter->dirty_tx = NextTxDesc(adapter->dirty_tx);
NdisMSendResourcesAvailable(adapter->MiniportAdapterHandle);
i ++;
}
}//while
}
//IRQL:DISPATCH_LEVEL
//USED BY RIsrDpc
VOID
RxInt(
PADAPTER adapter
)
/*++
接收中断处理
--*/
{
UCHAR TmpCMD;
UINT NumOfPkt = 0;
PNDIS_PACKET RevPacket[NUM_OF_PACKETS];
UINT i;
NDIS_STATUS Status;
PUCHAR buf;
PNDIS_BUFFER buf_desc;
UINT buf_len;
do{
//读命令寄存器 ChipCmd
NdisRawReadPortUchar(adapter->ioaddr + ChipCmd, &TmpCMD);
if((TmpCMD & (UCHAR)RxBufEmpty)){
adapter->RCV_NO_BUFFER ++;
break;//缓冲区为空
}
//有接收包
RevPacket[NumOfPkt] = RevOnePacket(adapter);
if(RevPacket[NumOfPkt]) NumOfPkt ++;
else break;
}while(TRUE);
if(NumOfPkt > 0){
// DbgPrint("RxInt:NumOfPkt=%x, RCV_OK=%x \n", NumOfPkt, adapter->RCV_OK);
NdisMIndicateReceivePacket(
adapter->MiniportAdapterHandle,
RevPacket,
NumOfPkt
);
adapter->FreeRxPkt += NumOfPkt;
}//if
}
//IRQL:DISPATCH_LEVEL
//USED RxInt
//#pragma LOCK_CODE
PNDIS_PACKET
RevOnePacket(
PADAPTER adapter
)
{
PUCHAR ReadPtr;
USHORT write_ptr;
PPACKETHEADER head;
NDIS_STATUS Status;
USHORT pkt_size;
USHORT max_byte;
PUCHAR buf;
PNDIS_PACKET pkt_desc;
PNDIS_BUFFER buf_desc;
INT i;
ReadPtr = adapter->rx_ring + adapter->read_ptr;
//chip write ptr
NdisRawReadPortUshort(adapter->ioaddr + RxBufAddr, &write_ptr);
write_ptr = write_ptr % RING_BUF_SIZE;
if(write_ptr > adapter->read_ptr)
max_byte = write_ptr - adapter->read_ptr;
else
max_byte = write_ptr + RING_BUF_SIZE - adapter->read_ptr;
head = (PPACKETHEADER)ReadPtr;
if(PacketOK(head)){
if(adapter->FreeRxPkt <= 0) goto RES_BAD; //没有空 rx_pkt
pkt_size = *((PUSHORT)(ReadPtr + 2)) - 4;
if(head->PAM) {
adapter->RCV_OK ++;
adapter->rev_byte += pkt_size;
}
/* DbgPrint("write_ptr=%x,read_ptr=%x,ReadPtr=%x, max_byte=%x\n", write_ptr,adapter->read_ptr,ReadPtr,max_byte);
if(head->MAR)
DbgPrint("RevOnePacket:multicase pkt. ");
else if(head->PAM){
adapter->RCV_OK ++;
DbgPrint("RevOnePacket:phy dest pkt.");
}else if(head->BAR)
DbgPrint("RevOnePacket:broadcast pkt.");
for(i = 0; i < 12; i ++)
DbgPrint("%02x-", *(ReadPtr + 4 + i));
DbgPrint(", cur_rx=%x", adapter->cur_rx);
DbgPrint("\n");
*/
if(pkt_size + 8 > max_byte){
DbgPrint("pkt_size + 8 > max_byte(%x) \n", max_byte);
return NULL;
}
adapter->FreeRxPkt --; //可用包个数 - 1
pkt_desc = adapter->pkt_desc[adapter->cur_rx];
//内存接收包
NdisMoveMemory(
adapter->rx_bufs + (adapter->cur_rx * RX_BUF_SIZE),
ReadPtr + 4,
pkt_size
);
NdisAdjustBufferLength(
adapter->buf_desc[adapter->cur_rx],
pkt_size
);
adapter->cur_rx = NextRxDesc(adapter->cur_rx);
NDIS_SET_PACKET_STATUS(pkt_desc, NDIS_STATUS_RESOURCES);
}else{//PACKETOK
//err
DbgPrint("RevOnePacket:rev packet error. \n");
RxErrHandle(adapter);
return NULL;
}
//下移读位置
adapter->read_ptr = (adapter->read_ptr + pkt_size + 8 + 3) & (~3); //对齐 32
adapter->read_ptr %= RING_BUF_SIZE;
//更新 RxBufPtr(读寄存器) -> RxReadOffset
NdisRawWritePortUshort(adapter->ioaddr + RxBufPtr, adapter->read_ptr - 16);
return pkt_desc;
RES_BAD:
DbgPrint("resources not enought for rev pkt. \n");
return NULL;
}
VOID
RxErrHandle(
PADAPTER adapter
)
{
UCHAR TmpCM;
ULONG TmpLong;
NdisRawReadPortUlong(adapter->ioaddr + RxMissed, &TmpLong);
adapter->ERR_COUNT += TmpLong;
NdisRawWritePortUlong(adapter->ioaddr + RxMissed, 0);
adapter->RCV_ERR ++;
//更新 RxBufPtr(读寄存器) -> RxReadOffset
NdisRawWritePortUshort(adapter->ioaddr + RxBufPtr, adapter->read_ptr - 16);
}
//IRQL:DISPATCH_LEVEL
//USED RxInt
//#pragma LOCK_CODE
BOOLEAN
PacketOK(
PPACKETHEADER p
)
{
BOOLEAN BadPacket = p->RUNT ||p->LONG ||p->CRC ||p->FAE;
if(BadPacket
||(p->PacketLength > MAX_ETHERNET_FRAME_SIZE)
||(p->PacketLength < MIN_ETHERNET_FRAME_SIZE)){
return FALSE;
}else{
return TRUE;
}
}
#define BMCR_RST 0x8000 //bit15
#define BMCR_SPEED 0x2000 //bit13
#define BMCR_AUTONEG 0x1000 //bit12
#define BMCR_RSTAUTO 0x200 //bit9
#define BMCR_DUPLEX 0x100 //bit8
#define BMSR_AUTOCOMP 0x20 //bit5
VOID
SetMII(
PADAPTER adapter
)
{
USHORT TmpShort;
USHORT media, ad, lp;
//reset
NdisRawWritePortUshort(adapter->ioaddr + BasicModeCtrl, BMCR_RST);
do{
NdisRawReadPortUshort(adapter->ioaddr + BasicModeCtrl, &TmpShort);
}while(TmpShort & BMCR_RST);
DbgPrint("MII reset complete. \n");
NdisRawReadPortUshort(adapter->ioaddr + BasicModeCtrl, &TmpShort);
TmpShort |= BMCR_AUTONEG | BMCR_RSTAUTO;
NdisRawWritePortUshort(adapter->ioaddr + BasicModeCtrl, TmpShort);
//set duplx
do{
NdisRawReadPortUshort(adapter->ioaddr + BasicModeStatus, &TmpShort);
}while(!(TmpShort & BMSR_AUTOCOMP));
DbgPrint("MII AUTONEG complete. \n");
//link ok
NdisRawReadPortUshort(adapter->ioaddr + BasicModeStatus, &TmpShort);
if(! (TmpShort & PHY_BMSR_LINKSTAT)){
DbgPrint("link error.\n");
return;
}
DbgPrint("link ok.\n");
//
NdisRawReadPortUshort(adapter->ioaddr + BasicModeCtrl, &media);
NdisRawReadPortUshort(adapter->ioaddr + NWayAdvert, &ad);
NdisRawReadPortUshort(adapter->ioaddr + NWayLPAR, &lp);
if (ad & PHY_ANAR_100BT4 && lp & PHY_ANAR_100BT4) {
media |= PHY_BMCR_SPEEDSEL;
media &= ~PHY_BMCR_DUPLEX;
DbgPrint("(100baseT4)\n");
} else if (ad & PHY_ANAR_100BTXFULL &&
lp & PHY_ANAR_100BTXFULL) {
media |= PHY_BMCR_SPEEDSEL;
media |= PHY_BMCR_DUPLEX;
DbgPrint("(full-duplex, 100Mbps)\n");
} else if (ad & PHY_ANAR_100BTXHALF &&
lp & PHY_ANAR_100BTXHALF) {
media |= PHY_BMCR_SPEEDSEL;
media &= ~PHY_BMCR_DUPLEX;
DbgPrint("(half-duplex, 100Mbps)\n");
} else if (ad & PHY_ANAR_10BTFULL &&
lp & PHY_ANAR_10BTFULL) {
media &= ~PHY_BMCR_SPEEDSEL;
media |= PHY_BMCR_DUPLEX;
DbgPrint("(full-duplex, 10Mbps)\n");
} else {
media &= ~PHY_BMCR_SPEEDSEL;
media &= ~PHY_BMCR_DUPLEX;
DbgPrint("(half-duplex, 10Mbps)\n");
}
NdisRawWritePortUshort(adapter->ioaddr + BasicModeCtrl, media);
}
BOOLEAN
RCheck(
IN NDIS_HANDLE MiniportAdapterContext
)
{
// PADAPTER adapter = (PADAPTER)MiniportAdapterContext;
// DbgPrint("RCheck. \n");
/* if(adapter->FreeTxDesc == 0){// return TRUE;
adapter->FreeTxDesc = 4;
adapter->cur_tx = 0;
}
*/
return FALSE;
}
#define EIGHT_BIT_MODE 0//定义 93C46 读写模式
USHORT
opEEPROM(
PUCHAR ioaddr,//93c46 port addr
ULONG locate, //寄存器位置
OP_ENUM op, //操作类型
USHORT data
)
{
int i, addrlen;
UCHAR TmpVal;
USHORT retval = 0;
switch(op){
case OP_WRITE:
#if (EIGHT_BIT_MODE) //8BIT MODE
locate = (op << 15) | (locate << 8) | ((UCHAR)data);
addrlen = 18;
#else //16BIT MODE
locate = (op << 22) | (locate << 16) | data;
addrlen = 25;
#endif
break;
case OP_READ:
case OP_ERASE:
#if (EIGHT_BIT_MODE) //8BIT MODE
locate = (op << 7) | locate;
addrlen = 10;
#else //16BIT MODE
locate = (op << 6) | locate;
addrlen = 9;
#endif
break;
default:
return 0;
}
NdisRawWritePortUchar(ioaddr, EE_ENB & ~EE_CS); //进入编程状态
NdisRawWritePortUchar(ioaddr, EE_ENB); //select chip
for(i = addrlen; i >= 0; i --){//串行写入
TmpVal = (locate & (1 << i)) ? EE_DI : 0;
NdisRawWritePortUchar(ioaddr, EE_ENB | TmpVal);
NdisRawWritePortUchar(ioaddr, EE_ENB | TmpVal | EE_CLK); //raise clk
}
NdisRawWritePortUchar(ioaddr, EE_ENB); //low clk
//read result
for(i = 0; i < 16; i ++){
NdisRawWritePortUchar(ioaddr, EE_ENB | EE_CLK); //raise clk
NdisRawReadPortUchar(ioaddr, &TmpVal);
TmpVal &= EE_DO;
retval = (retval << 1) | TmpVal;
NdisRawWritePortUchar(ioaddr, EE_ENB); //low clk
}
NdisRawWritePortUchar(ioaddr, ~EE_CS);
return retval;
}//finish
//IRQL:DISPATCH_LEVEL
NDIS_STATUS
RReset(
OUT PBOOLEAN AddressingReset,
IN NDIS_HANDLE MiniportAdapterContext
)
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PADAPTER adapter = (PADAPTER)MiniportAdapterContext;
DbgPrint("RReset \n");
while(adapter->FreeRxPkt != NUM_OF_PACKETS)
DbgPrint("RReset: FreeRxPkt=%x \n", adapter->FreeRxPkt);
while(adapter->FreeTxDesc != NUM_OF_DESC)
DbgPrint("RReset: FreeTxDesc=%x \n", adapter->FreeTxDesc);
NdisRawWritePortUshort(adapter->ioaddr + IntrMask, 0);
NdisRawWritePortUchar(adapter->ioaddr + ChipCmd, 0);
ResetNIC(adapter);
StartDevice(adapter);
adapter->read_ptr = 0;
adapter->FreeRxPkt = NUM_OF_PACKETS;
adapter->cur_rx = 0;
adapter->dirty_rx = 0;
adapter->FreeTxDesc = NUM_OF_DESC;
adapter->cur_tx = 0;
adapter->dirty_tx = 0;
return Status;
}
VOID
RHalt(
IN NDIS_HANDLE MiniportAdapterContext
)
{
PADAPTER adapter = (PADAPTER)MiniportAdapterContext;
DbgPrint("RHalt \n");
while(adapter->FreeRxPkt != NUM_OF_PACKETS)
DbgPrint("RHalt: FreeRxPkt=%x \n", adapter->FreeRxPkt);
while(adapter->FreeTxDesc != NUM_OF_DESC)
DbgPrint("RHalt: FreeTxDesc=%x \n", adapter->FreeTxDesc);
NdisRawWritePortUshort(adapter->ioaddr + IntrMask, 0);
NdisRawWritePortUchar(adapter->ioaddr + ChipCmd, 0);
FreeRes((PADAPTER)MiniportAdapterContext);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -