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

📄 driver.c

📁 sis900网卡驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
        *((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 + -