/***************************************************************************
Routine Description:


    The R6040Send request instructs a driver to transmit a packet through
    the adapter onto the medium.

Arguments:

    MiniportAdapterContext - Context registered with the wrapper, really
        a pointer to the adapter.

    Packet - A pointer to a descriptor for the packet that is to be
    transmitted.

    SendFlags - Optional send flags

Notes:

    This miniport driver will always accept a send.  This is because
    the R6040 has limited send resources and the driver needs packets
    to copy to the adapter immediately after a transmit completes in
    order to keep the adapter as busy as possible.

    This is not required for other adapters, as they have enough
    resources to keep the transmitter busy until the wrapper submits
    the next packet.
*****************************************************************************/
NDIS_STATUS R6040Send(
    IN NDIS_HANDLE MiniportAdapterContext,
    IN PNDIS_PACKET Packet,
    IN UINT Flags)
{
    PR6040_ADAPTER Adapter = (PR6040_ADAPTER)(MiniportAdapterContext);

    NdisAcquireSpinLock(&Adapter->SendLock);

    //RETAILMSG(R6040DBG, (TEXT("<")));

    // Put the packet on the send queue.
    if (Adapter->FirstPacket == NULL)
    {
        Adapter->FirstPacket = Packet;
    }
    else
    {
        RESERVED(Adapter->LastPacket)->Next = Packet;
    }

    RESERVED(Packet)->Next = NULL;
    Adapter->LastPacket = Packet;

    // Process the next send
    R6040DoNextSend(Adapter);

    //RETAILMSG(R6040DBG, (TEXT(">\r\n")));

    NdisReleaseSpinLock(&Adapter->SendLock);

    return(NDIS_STATUS_PENDING);
}
Example #2
0
/*******************************************************************************
**
** Function        userial_set_port
**
** Description     Configure UART port name
**
** Returns         0 : Success
**                 Otherwise : Fail
**
*******************************************************************************/
int userial_set_port(char *p_conf_name, char *p_conf_value, int param)
{
    RESERVED(p_conf_name);
    RESERVED(param);
    strlcpy(vnd_userial.port_name, p_conf_value, VND_PORT_NAME_MAXLEN);

    return 0;
}
Example #3
0
NTSTATUS PacketRead( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
	POPEN_INSTANCE      open;
	PNDIS_PACKET        pPacket;
	NDIS_STATUS         status;
	NTSTATUS            ntStatus;
	PIO_STACK_LOCATION  irpSp;

	// DebugPrint(("Read\n"));

	open = DeviceObject->DeviceExtension;

	IoIncrement(open);

	if(!open->Bound) {
		ntStatus = STATUS_DEVICE_NOT_READY;
		goto ERROR;
	}

	irpSp = IoGetCurrentIrpStackLocation(Irp);

	if (irpSp->Parameters.Read.Length < ETHERNET_HEADER_LENGTH) {
		ntStatus = STATUS_BUFFER_TOO_SMALL;
		goto ERROR;
	}

	NdisAllocatePacket( &status, &pPacket, open->PacketPool );
	if (status != NDIS_STATUS_SUCCESS) {
		// DebugPrint(("Packet: Read- No free packets\n"));
		ntStatus = STATUS_INSUFFICIENT_RESOURCES;
		goto ERROR;
	}

	RESERVED(pPacket)->Irp=Irp;
	RESERVED(pPacket)->pMdl=NULL;
	IoMarkIrpPending(Irp);

	IoSetCancelRoutine(Irp, PacketCancelRoutine);

	ExInterlockedInsertTailList(
			&open->RcvList,
			&RESERVED(pPacket)->ListElement,
			&open->RcvQSpinLock);

	return STATUS_PENDING;

ERROR:
	Irp->IoStatus.Status = ntStatus;
	IoCompleteRequest (Irp, IO_NO_INCREMENT);
	IoDecrement(open);
	return ntStatus;
}
Example #4
0
PNDIS_PACKET
PacketCopy(
	IN	PNDIS_PACKET	Packet,
	OUT	PLONG			CloneCount
	)
{
	if (CloneCount)
		*CloneCount = InterlockedIncrement( &(RESERVED(Packet)->Cloned) );
	else
		InterlockedIncrement( &(RESERVED(Packet)->Cloned) );

	return Packet;
}
Example #5
0
DWORD PacketRead(POPEN_INSTANCE     Open,
                 DWORD              dwDDB,
                 DWORD              hDevice,
                 PDIOCPARAMETERS    pDiocParms)
{
  // read a packet

  NDIS_STATUS     Status;
  PNDIS_PACKET    pPacket;
  
  //  Check that the buffer can hold a max length Ethernet packet
  if (pDiocParms->cbOutBuffer < ETHERNET_PACKET_LENGTH) {
    *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0; // Need bigger buffer       
    return NDIS_STATUS_SUCCESS;
  }
  
  PacketAllocatePacketBuffer(&Status, Open, &pPacket, pDiocParms, IOCTL_EPACKET_READ);
  
  if (Status == NDIS_STATUS_SUCCESS) {
    //  Put this packet in a list of pending reads.
    //  The receive indication handler will attempt to remove packets
    //  from this list for use in transfer data calls
    NdisAcquireSpinLock(&Open->RcvQSpinLock); // fixed 6.11.97
    InsertTailList(&Open->RcvList, &RESERVED(pPacket)->ListElement);
    NdisReleaseSpinLock(&Open->RcvQSpinLock);
  }

  return -1;  // This will make DeviceIOControl return ERROR_IO_PENDING
}
Example #6
0
VOID
ProtocolSendComplete(
    IN NDIS_HANDLE   ProtocolBindingContext,
    IN PNDIS_PACKET  pPacket,
    IN NDIS_STATUS   Status
    )
{
	OPEN_INSTANCE *pOpen = (OPEN_INSTANCE *)ProtocolBindingContext;
	PIRP pIrp = RESERVED(pPacket)->pIrp;
	PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation(pIrp);

	// 释放封包
	NdisFreePacket(pPacket);
	// 完成IRP请求
	if(Status == NDIS_STATUS_SUCCESS)
	{
		pIrp->IoStatus.Information = pIrpSp->Parameters.Write.Length;
		pIrp->IoStatus.Status = STATUS_SUCCESS;

		DbgPrint(" ProtoDrv: Send data success \n");
	}
	else
	{
		pIrp->IoStatus.Information = 0;
		pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
	}
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	IoDecrement(pOpen);
}
Example #7
0
NTSTATUS PacketCancelReadIrps( IN PDEVICE_OBJECT DeviceObject )
{
	POPEN_INSTANCE      open = DeviceObject->DeviceExtension;
	PLIST_ENTRY         thisEntry;
	PIRP                pendingIrp;
	PNDIS_PACKET        myPacket = NULL;
	PPACKET_RESERVED    reserved;
	PMDL                mdl;

	// DebugPrint(("PacketCancelReadIrps\n"));

	// Walk through the RcvList and cancel all read IRPs.

	while( thisEntry = ExInterlockedRemoveHeadList( &open->RcvList, &open->RcvQSpinLock )) {
		reserved=CONTAINING_RECORD(thisEntry,PACKET_RESERVED,ListElement);
		myPacket=CONTAINING_RECORD(reserved,NDIS_PACKET,ProtocolReserved);

		ASSERT(myPacket);

		pendingIrp = RESERVED(myPacket)->Irp;

		NdisFreePacket(myPacket);

		// DebugPrint(("Cancelled : 0%0x\n", pendingIrp));

		IoSetCancelRoutine(pendingIrp, NULL);

		pendingIrp->IoStatus.Information = 0;
		pendingIrp->IoStatus.Status = STATUS_CANCELLED;
		IoCompleteRequest(pendingIrp, IO_NO_INCREMENT);
		IoDecrement(open);
	}

	return STATUS_SUCCESS;
}
Example #8
0
__inline
LpxCopyEthLpxHeadersToLpxReserved(
	PNDIS_PACKET Packet,
	PVOID		EthHeader,
	USHORT		EthType,
	PVOID		LpxHeader,
	UINT		LpxHeaderSize
){
	RtlCopyMemory( &RESERVED(Packet)->EthernetHeader,
					EthHeader,
					ETHERNET_HEADER_LENGTH );
	// Override ether type in case of LLC SNAP
	RESERVED(Packet)->EthernetHeader.Type = EthType;

	RtlCopyMemory( &RESERVED(Packet)->LpxHeader, LpxHeader, LpxHeaderSize );
	RESERVED(Packet)->HeaderCopied = TRUE;
}
Example #9
0
PNDIS_PACKET
PacketClone(
    IN	PNDIS_PACKET Packet
)
{
    InterlockedIncrement(&(RESERVED(Packet)->Cloned));
    InterlockedIncrement(&NumberOfCloned);

    return Packet;
}
Example #10
0
NDIS_STATUS NDIS_API PacketReceiveIndicate(IN NDIS_HANDLE ProtocolBindingContext,
                                           IN NDIS_HANDLE MacReceiveContext,
                                           IN PVOID       HeaderBuffer,
                                           IN UINT        HeaderBufferSize,
                                           IN PVOID       LookaheadBuffer,
                                           IN UINT        LookaheadBufferSize,
                                           IN UINT        PacketSize)
{
  // upcall on packet arrival

  POPEN_INSTANCE      Open;
  PLIST_ENTRY         PacketListEntry;
  PNDIS_PACKET        pPacket;
  NDIS_STATUS         Status;
  UINT                BytesTransfered = 0;
  PPACKET_RESERVED    pReserved;


  if (HeaderBufferSize != ETHERNET_HEADER_LENGTH)
    return NDIS_STATUS_NOT_ACCEPTED;
  
  Open = (POPEN_INSTANCE) ProtocolBindingContext;
  
  //  See if there are any pending reads that we can satisfy
  NdisAcquireSpinLock(&Open->RcvQSpinLock); // fixed 5.11.97
  
  if (IsListEmpty(&Open->RcvList)) { 
    NdisReleaseSpinLock(&Open->RcvQSpinLock);
    return NDIS_STATUS_NOT_ACCEPTED;
  }

  PacketListEntry = RemoveHeadList(&Open->RcvList);
  NdisReleaseSpinLock(&Open->RcvQSpinLock);
  
  pReserved = CONTAINING_RECORD(PacketListEntry, PACKET_RESERVED, ListElement);
  pPacket = CONTAINING_RECORD(pReserved, NDIS_PACKET, ProtocolReserved);
  
  // Copy the MAC header
  NdisMoveMemory(RESERVED(pPacket)->lpBuffer, HeaderBuffer, HeaderBufferSize);

  //  Call the Mac to transfer the data portion of the packet
  NdisTransferData(&Status, Open->AdapterHandle, MacReceiveContext, 0, PacketSize, pPacket, &BytesTransfered);
  if (Status == NDIS_STATUS_PENDING)
    return NDIS_STATUS_PENDING;

  if (Status == NDIS_STATUS_SUCCESS) {
    PacketTransferDataComplete(Open, pPacket, Status, BytesTransfered);
    return NDIS_STATUS_SUCCESS;
  }

  PacketTransferDataComplete(Open, pPacket, Status, 0);
  return NDIS_STATUS_SUCCESS;
}
Example #11
0
NTSTATUS DispatchWrite(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
	NTSTATUS status;

	// 取得描述适配器的OPEN_INSTANCE结构的指针
	OPEN_INSTANCE *pOpen = (OPEN_INSTANCE *)pDevObj->DeviceExtension;
	// 增加IO引用计数
	IoIncrement(pOpen);
	do
	{
		if(!pOpen->bBound)
		{
			status = STATUS_DEVICE_NOT_READY;
			break;
		}

		// 从封包池中申请一个封包
		PNDIS_PACKET pPacket;
		NdisAllocatePacket((NDIS_STATUS*)&status, &pPacket, pOpen->hPacketPool);
		if(status != NDIS_STATUS_SUCCESS)	// 封包被申请完了!
		{
			status = STATUS_INSUFFICIENT_RESOURCES;
			break;
		}

		RESERVED(pPacket)->pIrp = pIrp; // 保存IRP指针,在完成例程中还要使用

		// 附加写缓冲区到封包
		NdisChainBufferAtFront(pPacket, pIrp->MdlAddress);

		// 注意,既然我们已经标识此IRP未决,我们必须返回STATUS_PENDING,即便是
		// 我们恰巧同步完成了这个IRP
		IoMarkIrpPending(pIrp);

		// 发送封包到下层NIC设备
		NdisSend((NDIS_STATUS*)&status, pOpen->hAdapter, pPacket);
		if(status != NDIS_STATUS_PENDING)
		{
			ProtocolSendComplete(pOpen, pPacket, status);
		}
		return STATUS_PENDING;		
	}while(FALSE);

	if(status != STATUS_SUCCESS)
	{
		IoDecrement(pOpen);
		pIrp->IoStatus.Information = 0;
		pIrp->IoStatus.Status = status;
		IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	}
	return status;
}
Example #12
0
PNDIS_PACKET
PacketCopy(
    IN	PNDIS_PACKET Packet,
    OUT	PLONG	Cloned
)
{
    ASSERT(Cloned) ;

    *Cloned = InterlockedIncrement(&(RESERVED(Packet)->Cloned));
    InterlockedIncrement(&NumberOfCloned);

    return Packet;
}
Example #13
0
VOID
PacketTransferDataComplete (
	IN NDIS_HANDLE   ProtocolBindingContext,
	IN PNDIS_PACKET  pPacket,
	IN NDIS_STATUS   Status,
	IN UINT          BytesTransfered
)
{
	PIO_STACK_LOCATION   irpSp;
	POPEN_INSTANCE       open;
	PIRP                 irp;
	PMDL                 pMdl;

	// DebugPrint(("Packet: TransferDataComplete\n"));

	open = (POPEN_INSTANCE)ProtocolBindingContext;
	irp = RESERVED(pPacket)->Irp;
	irpSp = IoGetCurrentIrpStackLocation(irp);
	pMdl = RESERVED(pPacket)->pMdl;


	if(pMdl) IoFreeMdl(pMdl);

	NdisFreePacket(pPacket);

	if(Status == NDIS_STATUS_SUCCESS) {
		irp->IoStatus.Status = STATUS_SUCCESS;
		irp->IoStatus.Information = BytesTransfered+ETHERNET_HEADER_LENGTH;
	} else {
		irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
		irp->IoStatus.Information = 0;
	}

	// DebugPrint(("BytesTransfered:%d\n", irp->IoStatus.Information));

	IoCompleteRequest(irp, IO_NO_INCREMENT);
	IoDecrement(open);
}
Example #14
0
static void reserved_c ()
{
	RESERVED(__inline__);
	RESERVED(__inline);
	RESERVED(inline);
	RESERVED(do);
	RESERVED(struct);
	RESERVED(case);
	RESERVED(for);
	RESERVED(short);
	RESERVED(union);
	RESERVED(sizeof);
	RESERVED(register);
	RESERVED(break);
	RESERVED(auto);
	RESERVED(continue);
	RESERVED(const);
	RESERVED(default);
	RESERVED(enum);
	RESERVED(else);
	RESERVED(extern);
	RESERVED(goto);
	RESERVED(if);
	RESERVED(long);
	RESERVED(return);
	RESERVED(signed);
	RESERVED(static);
	RESERVED(switch);
	RESERVED(typedef);
	RESERVED(unsigned);
	RESERVED(volatile);
	RESERVED(while);
	RESERVED(__asm__);
#ifdef GNU_VIOLATIONS
	RESERVED(__typeof__);
	RESERVED(__label__);
	RESERVED(_Complex);
#endif

	RESERVED(void);
	RESERVED(int);
	RESERVED(char);
	RESERVED(float);
	RESERVED(double);
}
Example #15
0
INT
PacketReceivePacket(
	IN    NDIS_HANDLE         ProtocolBindingContext,
	IN    PNDIS_PACKET        Packet
)
{
	UINT                bytesTransfered = 0;
	POPEN_INSTANCE      open;
	PIRP                irp;
	PNDIS_PACKET        myPacket;
	PLIST_ENTRY         packetListEntry;
	ULONG               bufferLength;
	PPACKET_RESERVED    reserved;
	PIO_STACK_LOCATION  irpSp;
	PMDL                mdl;
	PVOID               startAddress;
	NTSTATUS           status;

	// DebugPrint(("PacketReceivePacket\n"));

	open = (POPEN_INSTANCE)ProtocolBindingContext;

	packetListEntry = ExInterlockedRemoveHeadList(
											&open->RcvList,
											&open->RcvQSpinLock
											);

	if (packetListEntry == NULL) {
		// DebugPrint(("No pending read, dropping packets\n"));
		return 0;
	}

	reserved = CONTAINING_RECORD(packetListEntry,PACKET_RESERVED,ListElement);
	myPacket = CONTAINING_RECORD(reserved,NDIS_PACKET,ProtocolReserved);

	irp = RESERVED(myPacket)->Irp;
	irpSp = IoGetCurrentIrpStackLocation(irp);

	// We don't have to worry about the situation where the IRP is cancelled
	// after we remove it from the queue and before we reset the cancel
	// routine because the cancel routine has been coded to cancel an IRP
	// only if it's in the queue.

	IoSetCancelRoutine(irp, NULL);

	// Following block of code locks the destination packet
	// MDLs in a safe manner. This is a temporary workaround
	// for NdisCopyFromPacketToPacket that currently doesn't use
	// safe functions to lock pages of MDL. This is required to
	// prevent system from bugchecking under low memory resources.
	//
	{
		PVOID           virtualAddress;
		PNDIS_BUFFER    firstBuffer, nextBuffer;
		ULONG           totalLength;

		NdisQueryPacket(Packet, NULL, NULL, &firstBuffer, &totalLength);
		while( firstBuffer ) {
			NdisQueryBufferSafe( firstBuffer, &virtualAddress, &totalLength, NormalPagePriority );
			if(!virtualAddress) {
				status = STATUS_INSUFFICIENT_RESOURCES;
				goto CleanExit;
			}
			NdisGetNextBuffer(firstBuffer,  &nextBuffer);
			firstBuffer = nextBuffer;
		}
	}

	NdisChainBufferAtFront( myPacket, irp->MdlAddress );
	bufferLength=irpSp->Parameters.Read.Length;
	NdisCopyFromPacketToPacket( myPacket, 0, bufferLength, Packet, 0,  &bytesTransfered );

CleanExit:
	NdisFreePacket(myPacket);
	irp->IoStatus.Status = status;
	irp->IoStatus.Information = bytesTransfered;
	IoCompleteRequest(irp, IO_NO_INCREMENT);
	// DebugPrint(("BytesTransfered:%d\n", bytesTransfered));
	IoDecrement(open);
	return 0;
}
Example #16
0
/**
 * Called when a pagefault occurs, is in charge of fixing the fault and swapping
 * if necessary.
 */
void cPageFault(isrVal_t registers)
{
	addr_t page = getCR2();
	addr_t page_addr = page & ~(0xFFF);

#ifdef PAGEDBG
	printf("PG!\n");
	printf("Fault addr: %X\nPage index: %X\n", page, page_addr);
	printf("Fault type: %X\n", registers.errCode);
	printf("EIP: %X\nESP: %X\nESP: %X\n",
			       registers.eip, registers.procesp, registers.esp);
	printf("eax: %X\tebx: %X\necx: %X\tedx: %X\n",
		    registers.eax, registers.ebx, registers.ecx, registers.edx);
#endif

	if (registers.cs != 0x8 && registers.cs != 0x18)
		panic("Incorrect frame!");
	if (USER(registers.errCode))
		panic("Userspace isn't implemented yet!");
	if (RESERVED(registers.errCode))
		panic("A reserved bit has been set!\n");
	if (PRESENT(registers.errCode))
		panic("Illegal operation!");

	addr_t pd = getPageDir();

	/**
	* The data bit only works if a specific bit is set. See intel docs volume 3
	* for more information.
	*/

	if (DATA(registers.errCode))
	{
#ifdef PAGEDBG
		printf("Trying to access unimplemented data!\n");
#endif
		if (WRITE(registers.errCode))
		{
#ifdef PAGEDBG
		printf("Faulted a write attempt!\n");
		printf("Adding page!\n");
#endif
		if (USER(registers.errCode))
		{
			//Add a user page!
		}
		else
		{
#ifdef PAGEDBG
			printf("Adding a kernel page!\n");
#endif
			if (idx_kernel_space == MAP_NOMAP)
				panic("Kernel page map not correctly initialised!");

			int ret = page_alloc_page
				(idx_kernel_space, page_addr, (void*)pd, FALSE);
			if (ret != -E_SUCCESS)
			{
				printf("ERRCODE: %X\n", -ret);
				panic("Couldn't alloc page!");
			}
#ifdef PAGEDBG
			printf("Phys of %X = %X\n", page, page_phys_addr(page, (void*)pd));
#endif
			}
		}
		else
		{
#ifdef PAGEDBG
			printf("Faulted a read attempt!\n");
#endif
			// Assume the page may be read!
			if (idx_kernel_space == MAP_NOMAP)
			    panic("Kernel page map not correctly initialised!");
			int ret = page_alloc_page(idx_kernel_space, page_addr,
							      (void*)pd, FALSE);
			if (ret != -E_SUCCESS)
			{
				printf("ERRCODE: %X\n", -ret);
				panic("Couldn't alloc page!");
			}
#ifdef PAGEDBG
			printf("Phys of %X = %X\n", page, page_phys_addr(page, (void*)pd));
#endif
		}
	}
	else
	{
#ifdef PAGEDBG
	panic("Trying to run unimplemented code!\n");
#endif
	}
#ifdef UNDEFINED
	printf("Page faults currently under construction!\n");
#endif
}
Example #17
0
NTSTATUS
PacketAllocate(
    IN	PSERVICE_POINT		ServicePoint,
    IN	ULONG				PacketLength,
    IN	PDEVICE_CONTEXT		DeviceContext,
    IN	UCHAR				Type,
    IN	PUCHAR				CopyData,
    IN	ULONG				CopyDataLength,
    IN	PIO_STACK_LOCATION	IrpSp,
    OUT	PNDIS_PACKET		*Packet
)
{
    NTSTATUS		status;
    PUCHAR			packetData;
    PNDIS_BUFFER	pNdisBuffer;
    PNDIS_BUFFER	pNdisBufferData;
    PNDIS_PACKET	packet;
    USHORT			port;

    DebugPrint(3, ("PacketAllocate, PacketLength = %d, Numberofpackets = %d\n", PacketLength, NumberOfPackets));

    //	if(ServicePoint && ServicePoint->SmpState == SMP_SYN_RECV)
    //		return STATUS_INSUFFICIENT_RESOURCES;

    if(DeviceContext == NULL) {
        DebugPrint(1, ("[LPX]PacketAllocate: DeviceContext is NULL!!!\n"));
        return STATUS_INVALID_PARAMETER;
    }

    if(DeviceContext->LpxPacketPool == NULL) {
        DebugPrint(1, ("[LPX]PacketAllocate: DeviceContext->LpxPacketPool is NULL!!!\n"));
        return STATUS_INVALID_PARAMETER;
    }

    NdisAllocatePacket(&status,	&packet, DeviceContext->LpxPacketPool);

    if(status != NDIS_STATUS_SUCCESS) {
        DebugPrint(1, ("[LPX]PacketAllocate: NdisAllocatePacket Failed!!!\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    status = NdisAllocateMemory(
                 &packetData,
                 PacketLength
             );
    if(status != NDIS_STATUS_SUCCESS) {
        DebugPrint(1, ("[LpxSmp]PacketAllocate: Can't Allocate Memory packet.\n"));

        NdisFreePacket(packet);
        *Packet = NULL;

        return status;
    }

    NdisAllocateBuffer(
        &status,
        &pNdisBuffer,
        DeviceContext->LpxBufferPool,
        packetData,
        PacketLength
    );
    if(!NT_SUCCESS(status)) {
        NdisFreePacket(packet);
        *Packet = NULL;
        NdisFreeMemory(packetData);
        DebugPrint(1, ("[LPX]PacketAllocate: Can't Allocate Buffer!!!\n"));

        return status;
    }

    switch(Type) {

    case SEND_TYPE:

        if(ServicePoint && &ServicePoint->SmpContext) {
            RtlCopyMemory(&packetData[0],
                          ServicePoint->DestinationAddress.Node,
                          ETHERNET_ADDRESS_LENGTH
                         );
            RtlCopyMemory(&packetData[ETHERNET_ADDRESS_LENGTH],
                          ServicePoint->SourceAddress.Node,
                          ETHERNET_ADDRESS_LENGTH
                         );
            port = HTONS(ETH_P_LPX);
            RtlCopyMemory(&packetData[ETHERNET_ADDRESS_LENGTH*2],
                          &port, //&ServicePoint->DestinationAddress.Port,
                          2
                         );
        }

        if(CopyDataLength) {

            NdisAllocateBuffer(
                &status,
                &pNdisBufferData,
                DeviceContext->LpxBufferPool,
                CopyData,
                CopyDataLength
            );
            if(!NT_SUCCESS(status)) {
                NdisFreePacket(packet);
                *Packet = NULL;
                NdisFreeMemory(packetData);
                DebugPrint(1, ("[LPX]PacketAllocate: Can't Allocate Buffer For CopyData!!!\n"));

                return status;
            }

            NdisChainBufferAtFront(packet, pNdisBufferData);
        }
        break;

    case RECEIVE_TYPE:

        NdisMoveMappedMemory(
            packetData,
            CopyData,
            CopyDataLength
        );

        break;
    }

    //	RESERVED(packet)->ServicePoint = ServicePoint;
    RESERVED(packet)->Cloned = 0;
    RESERVED(packet)->IrpSp = IrpSp;
    RESERVED(packet)->Type = Type;
    RESERVED(packet)->LpxSmpHeader = NULL;

    if(IrpSp == NULL) {
        DebugPrint(2, ("[LPX] PacketAllocate: No IrpSp\n")) ;
    }

    NdisChainBufferAtFront(packet, pNdisBuffer);

    InterlockedIncrement(&NumberOfPackets);

    *Packet = packet;
    return STATUS_SUCCESS;
}
Example #18
0
VOID
PacketFree(
    IN PNDIS_PACKET	Packet
)
{
    PLPX_RESERVED	reserved = RESERVED(Packet);
    PUCHAR			packetData;
    PNDIS_BUFFER	pNdisBuffer;
    UINT			uiLength;
    LONG			clone ;

    DebugPrint(3, ("PacketFree reserved->type = %d\n", reserved->Type));

    switch(reserved->Type) {

    case SEND_TYPE:

        clone = InterlockedDecrement(&reserved->Cloned);
        if(clone >= 0) {
            return;
        }

        pNdisBuffer = NULL;
        NdisUnchainBufferAtFront(Packet, &pNdisBuffer);
        if(pNdisBuffer) {

            NdisQueryBufferSafe(
                pNdisBuffer,
                &packetData,
                &uiLength,
                HighPagePriority
            );

            NdisFreeMemory(packetData);
            NdisFreeBuffer(pNdisBuffer);
        }
        pNdisBuffer = NULL;
        NdisUnchainBufferAtFront(Packet, &pNdisBuffer);
        while(pNdisBuffer) {
            NdisFreeBuffer(pNdisBuffer);
            pNdisBuffer = NULL;
            NdisUnchainBufferAtFront(Packet, &pNdisBuffer);
        }
        if(reserved->IrpSp != NULL) {
            LpxDereferenceSendIrp(reserved->IrpSp);
        } else {
            DebugPrint(2, ("[LPX] PacketFree: No IrpSp\n")) ;
        }
        break;

    case RECEIVE_TYPE:

        if(reserved->LpxSmpHeader)
            //ExFreePool(reserved->LpxSmpHeader);
            NdisFreeMemory(reserved->LpxSmpHeader);

        pNdisBuffer = NULL;
        NdisUnchainBufferAtFront(Packet, &pNdisBuffer);
        if(pNdisBuffer) {
            NdisQueryBufferSafe(
                pNdisBuffer,
                &packetData,
                &uiLength,
                HighPagePriority
            );

            NdisFreeMemory(packetData);
            NdisFreeBuffer(pNdisBuffer);
        }
        reserved->PacketDataOffset = 0;

        break;

    }

    NdisFreePacket(Packet);

    InterlockedDecrement(&NumberOfPackets);

    DebugPrint(2, ("Packet REALLY Freed Numberofpackets = %d\n", NumberOfPackets));
}
Example #19
0
INT
LpxProtocolReceivePacket(
	IN NDIS_HANDLE	ProtocolBindingContext,
	IN PNDIS_PACKET	Packet
){
	PDEVICE_CONTEXT	deviceContext;
	PNDIS_BUFFER	ndisFirstBuffer;
	PVOID			firstBuffer;
	UINT		    firstBufferSize;
	UINT			totalBufferSize;
	USHORT		    protocol;
	PNDIS_PACKET	packet = NULL;
	NDIS_STATUS		status;
	INT				pktReferenceCount = 0;
	UINT		    addiLlcHeaderSize = 0;
	PLPX_HEADER		lpxHeader;
	USHORT			lpxHeaderSize;
	UINT			lpxPayload;
	UINT			rawDataOffset;


	DebugPrint( 4, ("ProtocolReceivePacket: Entered\n") );
	
	deviceContext = (PDEVICE_CONTEXT)ProtocolBindingContext;

	//
	//	Check to see if the device context is initialized.
	//
	ASSERT( deviceContext->NdisBindingHandle );

	if (!FlagOn(deviceContext->LpxFlags, LPX_DEVICE_CONTEXT_START) ||
		FlagOn(deviceContext->LpxFlags, LPX_DEVICE_CONTEXT_STOP)) {

			DebugPrint( 4,("Device is not initialized. Drop packet\n") );

			return 0;
	}

	//
	//	validation
	//
	NdisGetFirstBufferFromPacket(
				Packet,
				&ndisFirstBuffer,
				&firstBuffer,
				&firstBufferSize,
				&totalBufferSize);

	if (firstBufferSize < ETHERNET_HEADER_LENGTH) {

		DebugPrint( 1, ("ProtocolReceivePacket: FirstBufferSize = %x\n", firstBufferSize) );
		return 0;
	}

	protocol = ((PETHERNET_HEADER)firstBuffer)->Type;

	//
	//	Discard 802.2 LLC SNAP field.
	//
	// if Ether Type less than 0x0600 ( 1536 )
	//

	if (NTOHS(protocol) < 0x0600  && 
	    NTOHS(protocol) != 0x0060 && // LOOP: Ethernet Loopback
		NTOHS(protocol) != 0x0200 && // PUP : Xerox PUP packet
		NTOHS(protocol) != 0x0201) { // PUPAP: Xerox PUP address trans packet 

		protocol = *(PUSHORT)((PUCHAR)firstBuffer + ETHERNET_HEADER_LENGTH + LENGTH_8022LLCSNAP - 2);
		if(firstBufferSize >= LENGTH_8022LLCSNAP)
			firstBufferSize -= LENGTH_8022LLCSNAP;
		else {
			DebugPrint( 1, ("ProtocolReceivePacket: Too small first buffer\n") );
			return 0;
		}

		if(totalBufferSize >= LENGTH_8022LLCSNAP)
			totalBufferSize -= LENGTH_8022LLCSNAP;
		else {
			DebugPrint( 1, ("ProtocolReceivePacket: Too small total buffer\n") );
			return 0;
		}
		addiLlcHeaderSize = LENGTH_8022LLCSNAP;
	}

	if (protocol != HTONS(ETH_P_LPX)) {
	
		DebugPrint( 4, ("ProtocolReceivePacket: Type = %x\n", protocol) );
		return 0;
	}
	if(totalBufferSize < ETHERNET_HEADER_LENGTH + addiLlcHeaderSize + sizeof(LPX_HEADER)) {
		DebugPrint( 1, ("ProtocolReceivePacket: too small packet(1).\n"));
		return 0;
	}

	//
	// Extract LPX header information
	//
	//

	lpxHeader = (PLPX_HEADER)((PBYTE)firstBuffer + ETHERNET_HEADER_LENGTH + addiLlcHeaderSize);
	lpxHeaderSize = sizeof(LPX_HEADER);
	lpxPayload = NTOHS(lpxHeader->PacketSize & ~LPX_TYPE_MASK) - lpxHeaderSize;

#if __LPX_OPTION_ADDRESSS__

	if (FlagOn(lpxHeader->Option, LPX_OPTION_SOURCE_ADDRESS)) {
		lpxHeaderSize += ETHERNET_ADDRESS_LENGTH;
	}

	if (FlagOn(lpxHeader->Option, LPX_OPTION_DESTINATION_ADDRESS)) {
		lpxHeaderSize += ETHERNET_ADDRESS_LENGTH;
	}

#endif

	if(totalBufferSize < ETHERNET_HEADER_LENGTH + addiLlcHeaderSize + lpxHeaderSize + lpxPayload) {
		DebugPrint( 1, ("ProtocolReceivePacket: too small packet(2).\n"));
		return 0;
	}

	//
	// DROP PACKET for DEBUGGING!!!!
	//

#if 1 //DBG // Enabled for testing

	if (PacketRxDropRate) {

		PacketRxCountForDrop++;
				
		if ((PacketRxCountForDrop % 1000) <= PacketRxDropRate) {
			PLPX_HEADER        lpxHeader = (PLPX_HEADER)((PUCHAR)firstBuffer + addiLlcHeaderSize);
#if 0
			if ((PacketRxCountForDrop % (PacketRxDropRate*20)) == 0) 
				DebugPrint( 1, ("[Drop(%x,%x,%x))]\n", 
								 NTOHS(lpxHeader->Lsctl), NTOHS(lpxHeader->Sequence), NTOHS(lpxHeader->AckSequence)) );
#endif			
			DebugPrint( 1, ("D\n") );

			return 0;
		}
	}

#endif

	ASSERT( addiLlcHeaderSize == 0 );

	DebugPrint( 4, ("ProtocolReceivePacket: TotalBuffSz = %d, FirstBuffSz = %d, LPX_HEADER size = %d\n",
					 totalBufferSize, firstBufferSize, sizeof(LPX_HEADER)) );
	//
	//  If the miniport is out of resources, we can't queue
	//  this packet - make a copy if this is so.
	//
	if (NDIS_GET_PACKET_STATUS(Packet) == NDIS_STATUS_RESOURCES) {

		UINT			bytesCopied;

		DebugPrint( 1, ("ProtocolReceivePacket: Miniport reported low packet resources.\n"));

		status = RcvPacketAlloc( deviceContext,
								 lpxPayload,
								 &packet );

		if (status == STATUS_SUCCESS) {
			ASSERT( packet->Private.NdisPacketFlags & fPACKET_ALLOCATED_BY_NDIS );
			//
			// Copy lpx payload. payload contains only data.
			//
			NdisCopyFromPacketToPacket(
						packet, 0,
						lpxPayload,
						Packet, ETHERNET_HEADER_LENGTH + addiLlcHeaderSize + lpxHeaderSize,
						&bytesCopied);
			ASSERT(lpxPayload == bytesCopied);
		}

		rawDataOffset = 0;
		pktReferenceCount = 0;
	} else {
		PLPX_RESERVED	externalReserved;
		//
		// No need to allocate new NDIS packet and copy data to the new NDIS packet.
		// But, NDIS miniport allocates only 4 * sizeof(PVOID) for protocol reserved context.
		// We should allocate our own.
		//
		packet = Packet;

		status = NdisAllocateMemoryWithTag(&externalReserved, sizeof(LPX_RESERVED), LPX_MEM_TAG_EXTERNAL_RESERVED);
		if(status == NDIS_STATUS_SUCCESS) {

			RtlZeroMemory(externalReserved, sizeof(LPX_RESERVED));

			// By setting the external reserved field, RESERVED() uses external reserved context automatically.
			((PLPX_RESERVED)packet->ProtocolReserved)->ExternalReserved = externalReserved;

			// Initialize LPX reserved context instead of RcvPacketAlloc().
			RESERVED(packet)->Cloned = 0;
			RESERVED(packet)->Type = LPX_PACKET_TYPE_RECEIVE;
			RESERVED(packet)->RecvFlags |= LPX_RESERVED_RECVFLAG_ALLOC_MINIPORT;

			// set data offset
			// Because NDIS miniport allocated the packet, the NDIS packet contains whole raw packet data.
			rawDataOffset = ETHERNET_HEADER_LENGTH + addiLlcHeaderSize + lpxHeaderSize;
			lpxPayload += rawDataOffset;

			// return one reference count indicating LPX will call NdisReturnPackets() once.
			pktReferenceCount = 1;

		}
	}

	if (status != NDIS_STATUS_SUCCESS) {

		return 0;
	}

	//
	// Init LPX reserved context
	//

	LpxCopyEthLpxHeadersToLpxReserved(packet, firstBuffer, protocol, lpxHeader, lpxHeaderSize);
	RESERVED(Packet)->Packet = packet;
	RESERVED(Packet)->RecvTime = CurrentTime();
	RESERVED(Packet)->PacketRawDataLength = lpxPayload;
	RESERVED(Packet)->PacketRawDataOffset = rawDataOffset;

	//
	// Queue to the device context.
	//

	ExInterlockedInsertTailList( &deviceContext->PacketInProgressList,
								 &(RESERVED(Packet)->ListEntry),
								 &deviceContext->PacketInProgressQSpinLock );


	return pktReferenceCount;
}
Example #20
0
VOID
LpxTransferDataComplete(
	IN NDIS_HANDLE   ProtocolBindingContext,
	IN PNDIS_PACKET  Packet,
	IN NDIS_STATUS   Status,
	IN UINT          BytesTransfered
	)
{
	PDEVICE_CONTEXT	pDeviceContext;
	PLPX_HEADER	lpxHeader;
	PNDIS_BUFFER	firstBuffer;	
	PUCHAR			packetData;
	UINT			packetDataLength;
	USHORT			lpxHeaderSize;


	UNREFERENCED_PARAMETER( BytesTransfered );

	pDeviceContext = (PDEVICE_CONTEXT)ProtocolBindingContext;

	if (Status != NDIS_STATUS_SUCCESS) {

		ASSERT( FALSE );
		DebugPrint( 1,  ("[LPX] LpxTransferDataComplete error %x\n", Status) );
		PacketFree( pDeviceContext, Packet );
		return;
	}

	if (RESERVED(Packet)->HeaderCopied == FALSE) {
	
		NdisQueryPacket( Packet, NULL, NULL, &firstBuffer, NULL );
		NdisQueryBufferSafe( firstBuffer, &packetData, &packetDataLength, HighPagePriority );

		lpxHeader = (PLPX_HEADER)(packetData + RESERVED(Packet)->PacketRawDataOffset);

		lpxHeaderSize = sizeof(LPX_HEADER);

#if __LPX_OPTION_ADDRESSS__

		if (FlagOn(lpxHeader->Option, LPX_OPTION_SOURCE_ADDRESS)) {

			lpxHeaderSize += ETHERNET_ADDRESS_LENGTH;
		}

		if (FlagOn(lpxHeader->Option, LPX_OPTION_DESTINATION_ADDRESS)) {

			lpxHeaderSize += ETHERNET_ADDRESS_LENGTH;
		}

#endif

		RtlCopyMemory( &RESERVED(Packet)->LpxHeader, lpxHeader, lpxHeaderSize );
		RESERVED(Packet)->HeaderCopied = TRUE;

		RESERVED(Packet)->PacketRawDataLength = RESERVED(Packet)->PacketRawDataOffset + NTOHS(lpxHeader->PacketSize & ~LPX_TYPE_MASK);
		RESERVED(Packet)->PacketRawDataOffset += lpxHeaderSize;
	}
	
	lpxHeaderSize = sizeof(LPX_HEADER);

#if __LPX_OPTION_ADDRESSS__

	if (FlagOn(RESERVED(Packet)->LpxHeader.Option, LPX_OPTION_SOURCE_ADDRESS)) {

		if (!FlagOn(RESERVED(Packet)->LpxHeader.Option, LPX_OPTION_DESTINATION_ADDRESS)) {
		
			RtlCopyMemory( RESERVED(Packet)->OptionSourceAddress,
						   RESERVED(Packet)->OptionDestinationAddress,
						   ETHERNET_ADDRESS_LENGTH );	
		}

		lpxHeaderSize += ETHERNET_ADDRESS_LENGTH;

		ASSERT( RtlEqualMemory(RESERVED(Packet)->EthernetHeader.SourceAddress,
							   RESERVED(Packet)->OptionSourceAddress,
							   ETHERNET_ADDRESS_LENGTH) );
	}

	if (FlagOn(RESERVED(Packet)->LpxHeader.Option, LPX_OPTION_DESTINATION_ADDRESS)) {

		lpxHeaderSize += ETHERNET_ADDRESS_LENGTH;

		ASSERT( RtlEqualMemory(RESERVED(Packet)->EthernetHeader.DestinationAddress,
							   RESERVED(Packet)->OptionDestinationAddress,
							   ETHERNET_ADDRESS_LENGTH) );
	}

#endif

	if (NTOHS(RESERVED(Packet)->LpxHeader.PacketSize & ~LPX_TYPE_MASK) - lpxHeaderSize != 
		RESERVED(Packet)->PacketRawDataLength - RESERVED(Packet)->PacketRawDataOffset) {

		ASSERT( FALSE );
		PacketFree( pDeviceContext, Packet );
		return;
	}		

	ExInterlockedInsertTailList( &pDeviceContext->PacketInProgressList,
								 &(RESERVED(Packet)->ListEntry),
								 &pDeviceContext->PacketInProgressQSpinLock );
	return;
}
Example #21
0
NDIS_STATUS
LpxReceiveIndication (
	IN NDIS_HANDLE	ProtocolBindingContext,
	IN NDIS_HANDLE	MacReceiveContext,
	IN PVOID		HeaderBuffer,
	IN UINT		    HeaderBufferSize,
	IN PVOID		LookAheadBuffer,
	IN UINT		    LookAheadBufferSize,
	IN UINT		    PacketSize
	)
/*++

Routine Description:

	This routine receives control from the physical provider as an
	indication that a frame has been received on the physical link.
	This routine is time critical, so we only allocate a
	buffer and copy the packet into it. We also perform minimal
	validation on this packet. It gets queued to the device context
	to allow for processing later.

Arguments:

	BindingContext - The Adapter Binding specified at initialization time.

	ReceiveContext - A magic cookie for the MAC.

	HeaderBuffer - pointer to a buffer containing the packet header.

	HeaderBufferSize - the size of the header.

	LookaheadBuffer - pointer to a buffer containing the negotiated minimum
		amount of buffer I get to look at (not including header).

	LookaheadBufferSize - the size of the above. May be less than asked
		for, if that's all there is.

	PacketSize - Overall size of the packet (not including header).

Return Value:

	NDIS_STATUS - status of operation, one of:

			     NDIS_STATUS_SUCCESS if packet accepted,
			     NDIS_STATUS_NOT_RECOGNIZED if not recognized by protocol,
			     NDIS_any_other_thing if I understand, but can't handle.

--*/
{
	PDEVICE_CONTEXT	deviceContext;
	USHORT		    protocol;
	PNDIS_PACKET	packet;
	NDIS_STATUS		status;
	UINT		    bytesTransfered = 0;
	UINT		    startOffset = 0;


	DebugPrint( 4, ("LpxReceiveIndication, Entered\n") );
	
	deviceContext = (PDEVICE_CONTEXT)ProtocolBindingContext;

	//
	//	validation
	//

	if (HeaderBufferSize != ETHERNET_HEADER_LENGTH) {

		DebugPrint( 4, ("HeaderBufferSize = %x\n", HeaderBufferSize) );
		return NDIS_STATUS_NOT_RECOGNIZED;
	}
	
	RtlCopyMemory( (PUCHAR)&protocol, &((PUCHAR)HeaderBuffer)[12], sizeof(USHORT) );

	//
	//	Discard 802.2 LLC SNAP field.
	//
	// if Ether Type less than 0x0600 ( 1536 )
	//

	if (NTOHS(protocol) < 0x0600  && 
	    protocol != HTONS(0x0060) && // LOOP: Ethernet Loopback
		protocol != HTONS(0x0200) && // PUP : Xerox PUP packet
		protocol != HTONS(0x0201)) { // PUPAP: Xerox PUP address trans packet 

#if __LPX__
		NdisCopyLookaheadData( (PUCHAR)&protocol,
								&((PUCHAR)LookAheadBuffer)[LENGTH_8022LLCSNAP - 2],
								sizeof(USHORT),
								deviceContext->MacOptions );
#endif
		PacketSize -= LENGTH_8022LLCSNAP;
		LookAheadBufferSize -= LENGTH_8022LLCSNAP;
		startOffset = LENGTH_8022LLCSNAP;
	}

	if (protocol != HTONS(ETH_P_LPX)) {
	
		DebugPrint( 4, ("Type = %x\n", protocol) );
		return NDIS_STATUS_NOT_RECOGNIZED;
	}


	//
	//	Check to see if the device context is initialized.
	//

	//ACQUIRE_DPC_SPIN_LOCK( &deviceContext->SpinLock );

	if (!FlagOn(deviceContext->LpxFlags, LPX_DEVICE_CONTEXT_START) || FlagOn(deviceContext->LpxFlags, LPX_DEVICE_CONTEXT_STOP)) {
	
		//RELEASE_DPC_SPIN_LOCK( &deviceContext->SpinLock );
		DebugPrint( 4,("Device is not initialized. Drop packet\n") );

		return NDIS_STATUS_NOT_RECOGNIZED;
	}

	ASSERT( deviceContext->NdisBindingHandle );

	//RELEASE_DPC_SPIN_LOCK( &deviceContext->SpinLock );

	//
	// DROP PACKET for DEBUGGING!!!!
	//

#if 1 //DBG // Enabled for testing

	if (PacketRxDropRate) {

		PacketRxCountForDrop++;
				
		if ((PacketRxCountForDrop % 1000) <= PacketRxDropRate) {
			PLPX_HEADER        lpxHeader = (PLPX_HEADER)LookAheadBuffer;
#if 0
			if ((PacketRxCountForDrop % (PacketRxDropRate*20)) == 0) 
				DebugPrint( 1, ("[Drop(%x,%x,%x))]\n", 
								 NTOHS(lpxHeader->Lsctl), NTOHS(lpxHeader->Sequence), NTOHS(lpxHeader->AckSequence)) );
#endif			
			DebugPrint( 1, ("D") );

			return NDIS_STATUS_NOT_RECOGNIZED;
		}
	}

#endif

	ASSERT( startOffset == 0 );

	DebugPrint( 4, ("LpxReceiveIndication, PacketSize = %d, LookAheadBufferSize = %d, LPX_HEADER size = %d\n",
					 PacketSize, LookAheadBufferSize, sizeof(LPX_HEADER)) );

	if (LookAheadBufferSize >= sizeof(LPX_HEADER)) {

		PNDIS_BUFFER	firstBuffer;    
		PUCHAR		    packetData;
		PLPX_HEADER		lpxHeader;
		USHORT			lpxHeaderSize;

		
		lpxHeader = (PLPX_HEADER)((PBYTE)LookAheadBuffer + startOffset);
		
		lpxHeaderSize = sizeof(LPX_HEADER);

#if __LPX_OPTION_ADDRESSS__

		if (FlagOn(lpxHeader->Option, LPX_OPTION_SOURCE_ADDRESS)) {

			lpxHeaderSize += ETHERNET_ADDRESS_LENGTH;
		}

		if (FlagOn(lpxHeader->Option, LPX_OPTION_DESTINATION_ADDRESS)) {

			lpxHeaderSize += ETHERNET_ADDRESS_LENGTH;
		}

#endif

		if (NTOHS(lpxHeader->PacketSize & ~LPX_TYPE_MASK) == lpxHeaderSize) {

			status = RcvPacketAlloc( deviceContext,
									 0,
									 &packet );

			if (status == STATUS_SUCCESS) {

				NdisCopyLookaheadData( &RESERVED(packet)->EthernetHeader,
										HeaderBuffer,
										ETHERNET_HEADER_LENGTH,
										deviceContext->MacOptions );

				RESERVED(packet)->EthernetHeader.Type = protocol;
				RESERVED(packet)->RecvTime = CurrentTime();
			
				RtlCopyMemory( &RESERVED(packet)->LpxHeader, lpxHeader, lpxHeaderSize );
				RESERVED(packet)->HeaderCopied = TRUE;

				RESERVED(packet)->PacketRawDataLength = 0;
				RESERVED(packet)->PacketRawDataOffset = 0;

				LpxTransferDataComplete( deviceContext,
					                     packet,
					                     NDIS_STATUS_SUCCESS,
					                     LookAheadBufferSize );

				return NDIS_STATUS_SUCCESS;
			}

		} else if (LookAheadBufferSize >= NTOHS(lpxHeader->PacketSize & ~LPX_TYPE_MASK)) {
				
			status = RcvPacketAlloc( deviceContext,
									 NTOHS(lpxHeader->PacketSize & ~LPX_TYPE_MASK) - lpxHeaderSize,
									 &packet );

			if (status == STATUS_SUCCESS) {
			
				NdisCopyLookaheadData( &RESERVED(packet)->EthernetHeader,
										HeaderBuffer,
										ETHERNET_HEADER_LENGTH,
										deviceContext->MacOptions );

				RESERVED(packet)->EthernetHeader.Type = protocol;
				RESERVED(packet)->RecvTime = CurrentTime();

				RtlCopyMemory( &RESERVED(packet)->LpxHeader, lpxHeader, lpxHeaderSize );
				RESERVED(packet)->HeaderCopied = TRUE;

				RESERVED(packet)->PacketRawDataLength = NTOHS(lpxHeader->PacketSize & ~LPX_TYPE_MASK) - lpxHeaderSize;
				RESERVED(packet)->PacketRawDataOffset = 0;

				NdisQueryPacket( packet, NULL, NULL, &firstBuffer, NULL );
				packetData = MmGetMdlVirtualAddress( firstBuffer );

				NdisCopyLookaheadData( packetData,
									   (PBYTE)LookAheadBuffer + startOffset + lpxHeaderSize,
									   RESERVED(packet)->PacketRawDataLength,
									   deviceContext->MacOptions );

				LpxTransferDataComplete( deviceContext,
					                     packet,
					                     NDIS_STATUS_SUCCESS,
					                     LookAheadBufferSize );

				return NDIS_STATUS_SUCCESS;
			}

		} else {

			status = RcvPacketAlloc( deviceContext,
									 startOffset + NTOHS(lpxHeader->PacketSize & ~LPX_TYPE_MASK),
									 &packet );
			
			if (status == STATUS_SUCCESS) {
			
				NdisCopyLookaheadData( &RESERVED(packet)->EthernetHeader,
										HeaderBuffer,
										ETHERNET_HEADER_LENGTH,
										deviceContext->MacOptions );

				RESERVED(packet)->EthernetHeader.Type = protocol;
				RESERVED(packet)->RecvTime = CurrentTime();

				RtlCopyMemory( &RESERVED(packet)->LpxHeader, lpxHeader, lpxHeaderSize );
				RESERVED(packet)->HeaderCopied = TRUE;

				RESERVED(packet)->PacketRawDataLength = startOffset + NTOHS(lpxHeader->PacketSize & ~LPX_TYPE_MASK);
				RESERVED(packet)->PacketRawDataOffset = startOffset + lpxHeaderSize;
			}
		}

	} else {

		PLPX_HEADER		lpxHeader;
		PNDIS_BUFFER	firstBuffer;	
		PUCHAR			packetData;
		UINT			packetDataLength;

		ASSERT( FALSE );

		status = RcvPacketAlloc( deviceContext, PacketSize, &packet );
		
		if (status == STATUS_SUCCESS) {
		
			RtlCopyMemory( &RESERVED(packet)->EthernetHeader,
						   HeaderBuffer,
						   ETHERNET_HEADER_LENGTH );

			RESERVED(packet)->EthernetHeader.Type = protocol;
			RESERVED(packet)->RecvTime = CurrentTime();

			RESERVED(packet)->PacketRawDataLength = PacketSize;
			RESERVED(packet)->PacketRawDataOffset = startOffset;

			NdisQueryPacket( packet, NULL, NULL, &firstBuffer, NULL );
			NdisQueryBufferSafe( firstBuffer, &packetData, &packetDataLength, HighPagePriority );

			lpxHeader = (PLPX_HEADER)(packetData + RESERVED(packet)->PacketRawDataOffset);
			RtlZeroMemory( lpxHeader, sizeof(LPX_HEADER) );

			RESERVED(packet)->HeaderCopied = FALSE;
		}
	}

	if (status != NDIS_STATUS_SUCCESS) {
	
		return NDIS_STATUS_NOT_RECOGNIZED;
	}

	ASSERT( packet->Private.NdisPacketFlags & fPACKET_ALLOCATED_BY_NDIS );
			
	if (deviceContext->NdisBindingHandle) {

		//ASSERT( FALSE );

		NdisTransferData( &status,
						  deviceContext->NdisBindingHandle,
						  MacReceiveContext,
						  0, //RESERVED(packet)->PacketRawDataOffset,
						  RESERVED(packet)->PacketRawDataLength,
						  packet,
						  &bytesTransfered );

			
		if (status == NDIS_STATUS_PENDING) {

			LPX_ASSERT( FALSE );
		    status = NDIS_STATUS_SUCCESS;
		
		} else if (status == NDIS_STATUS_SUCCESS) {
		
			LpxTransferDataComplete( deviceContext,
									 packet,
									 status,
									 bytesTransfered );

		} else {
	
			LPX_ASSERT( FALSE );
			DebugPrint( 1, ("NdisTransferData() failed. STATUS=%08lx\n", status) );
		}

	} else {
			
		status = NDIS_STATUS_NOT_RECOGNIZED;
		DebugPrint( 1, ("Invalid device status. STATUS=%08lx\n", status) );
	}

	return status;
}
Example #22
0
VOID PacketAllocatePacketBuffer(PNDIS_STATUS    pStatus,
                                POPEN_INSTANCE  pOpen,
                                PNDIS_PACKET    *ppPacket,
                                PDIOCPARAMETERS pDiocParms,
                                DWORD           FunctionCode )
{
  // allocate a buffer for reading/writing

  PNDIS_BUFFER pNdisBuffer;
  PNDIS_PACKET pPacket;
  

  //  Try to get a packet from our list of free ones
  NdisAllocatePacket(pStatus, ppPacket, pOpen->PacketPool);
  
  if (*pStatus != NDIS_STATUS_SUCCESS) {
    *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
    return;
  }
  
  pPacket = *ppPacket;
  
  // Buffers used asynchronously must be page locked
  switch (FunctionCode) {
    case IOCTL_EPACKET_READ:
      RESERVED(pPacket)->lpBuffer = (PVOID)PacketPageLock(pDiocParms->lpvOutBuffer, pDiocParms->cbOutBuffer);
      RESERVED(pPacket)->cbBuffer = pDiocParms->cbOutBuffer;
      break;
    
    case IOCTL_EPACKET_WRITE:
      RESERVED(pPacket)->lpBuffer = (PVOID)PacketPageLock(pDiocParms->lpvInBuffer, pDiocParms->cbInBuffer);
      RESERVED(pPacket)->cbBuffer = pDiocParms->cbInBuffer;
      break;
    
    default:
      // recycle the packet
      NdisReinitializePacket(pPacket);
    
      // Put the packet on the free queue
      NdisFreePacket(pPacket);
    
      *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
      *pStatus = NDIS_STATUS_NOT_ACCEPTED;
      return;
  }
  
  RESERVED(pPacket)->lpcbBytesReturned = (PVOID)PacketPageLock(pDiocParms->lpcbBytesReturned, sizeof(DWORD));
  RESERVED(pPacket)->lpoOverlapped     = (PVOID)PacketPageLock(pDiocParms->lpoOverlapped, sizeof(OVERLAPPED));
  RESERVED(pPacket)->hDevice           = pDiocParms->hDevice;
  RESERVED(pPacket)->tagProcess        = pDiocParms->tagProcess;
  
  switch (FunctionCode) {
    case IOCTL_EPACKET_READ:
      NdisAllocateBuffer(pStatus,
                         &pNdisBuffer,
                         pOpen->BufferPool,
                         (PVOID)(RESERVED(pPacket)->lpBuffer + ETHERNET_HEADER_LENGTH),
                         pDiocParms->cbOutBuffer);
      break;
    
    case IOCTL_EPACKET_WRITE:
      NdisAllocateBuffer(pStatus,
                         &pNdisBuffer,
                         pOpen->BufferPool,
                         (PVOID)RESERVED(pPacket)->lpBuffer,
                         pDiocParms->cbInBuffer);
      break;
  }
  
  if (*pStatus == NDIS_STATUS_SUCCESS)
    NdisChainBufferAtFront(pPacket, pNdisBuffer); // Attach buffer to Packet
  else {
    NdisReinitializePacket(pPacket);  // recycle the packet
    NdisFreePacket(pPacket);          // Put the packet on the free queue
    *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
  }
}
Example #23
0
VOID
PacketFree2 (
	IN PNDIS_PACKET		Packet
	)
{
	PLPX_RESERVED	reserved = RESERVED(Packet);
	PUCHAR			packetData;
	PNDIS_BUFFER	pNdisBuffer;
	UINT			uiLength;
	LONG			clone;
	LONG			BufferSeq;
	BOOLEAN			allocMiniport = FALSE;
	PLPX_RESERVED	externalReserved;


	DebugPrint( 3, ("PacketFree reserved->type = %d\n", reserved->Type) );
	ASSERT( Packet->Private.NdisPacketFlags & fPACKET_ALLOCATED_BY_NDIS );

	
	switch (reserved->Type) {

	case LPX_PACKET_TYPE_SEND:

		clone = InterlockedDecrement( &reserved->Cloned );
		
		if(clone >= 0) {
		
			return;
		}
	
		pNdisBuffer = NULL;
		BufferSeq = 0;
		NdisUnchainBufferAtFront( Packet, &pNdisBuffer );

		while (pNdisBuffer) {

			//
			//	Assuming the first data buffer comes from user application
			//			the others are created in LPX for padding, etc.
			//	Free the memory of the others.
			//
			
			if (BufferSeq == 0) {

#if DBG
				NdisQueryBufferSafe( pNdisBuffer, &packetData, &uiLength, HighPagePriority );
				ASSERT( packetData == (PCHAR)&RESERVED(Packet)->EthernetHeader );
#endif

			} else if (BufferSeq == 1) {

				// UserBuffer

			} else if (BufferSeq == 2) {

				// Padding
					
				NdisQueryBufferSafe( pNdisBuffer, &packetData, &uiLength, HighPagePriority );
				LpxFreeMemoryWithLpxTag( packetData );
			
			} else {

				ASSERT( FALSE );
			}

			NdisFreeBuffer( pNdisBuffer );

			pNdisBuffer = NULL;
			NdisUnchainBufferAtFront( Packet, &pNdisBuffer );
			BufferSeq ++;
		}
		
		if (reserved->IrpSp != NULL) {
			
			PIRP _Irp = IRP_SEND_IRP( reserved->IrpSp );

			ASSERT( reserved->NdisStatus == NDIS_STATUS_SUCCESS || reserved->NdisStatus == NDIS_STATUS_NOT_ACCEPTED || !NT_SUCCESS(reserved->NdisStatus) );

			if (!NT_SUCCESS(reserved->NdisStatus)) {

				_Irp->IoStatus.Status = reserved->NdisStatus;
			}

			//INC_IRP_RETRANSMITS( _Irp, reserved->Retransmits );

			LpxDereferenceSendIrp( "Destroy packet", reserved->IrpSp, RREF_PACKET );
		
		} else {
		
			DebugPrint( 3, ("[LPX] PacketFree: No IrpSp\n") ) ;
		}

		break;

	case LPX_PACKET_TYPE_RECEIVE:

		//
		// If the packet allocated by NIC miniport, break here.
		//
		if(RESERVED(Packet)->RecvFlags & LPX_RESERVED_RECVFLAG_ALLOC_MINIPORT) {
			allocMiniport = TRUE;
			break;
		}

		pNdisBuffer = NULL;	

		NdisUnchainBufferAtFront( Packet, &pNdisBuffer );

#if __LPX_STATISTICS__
		{
			LARGE_INTEGER systemTime;

			KeQuerySystemTime( &systemTime );

			RESERVED(Packet)->DeviceContext->NumberOfRecvPackets ++;
			RESERVED(Packet)->DeviceContext->FreeTimeOfRecvPackets.QuadPart += systemTime.QuadPart - RESERVED(Packet)->RecvTime2.QuadPart;
			RESERVED(Packet)->DeviceContext->BytesOfRecvPackets.QuadPart += sizeof(LPX_HEADER) + RESERVED(Packet)->PacketRawDataLength;

			if (RESERVED(Packet)->PacketRawDataLength) {

				RESERVED(Packet)->DeviceContext->NumberOfLargeRecvPackets ++;
				RESERVED(Packet)->DeviceContext->FreeTimeOfLargeRecvPackets.QuadPart += systemTime.QuadPart - RESERVED(Packet)->RecvTime2.QuadPart;
				RESERVED(Packet)->DeviceContext->BytesOfLargeRecvPackets.QuadPart += sizeof(LPX_HEADER) + RESERVED(Packet)->PacketRawDataLength;
			
			} else {

				RESERVED(Packet)->DeviceContext->NumberOfSmallRecvPackets ++;
				RESERVED(Packet)->DeviceContext->FreeTimeOfSmallRecvPackets.QuadPart += systemTime.QuadPart - RESERVED(Packet)->RecvTime2.QuadPart;
				RESERVED(Packet)->DeviceContext->BytesOfSmallRecvPackets.QuadPart += sizeof(LPX_HEADER);
			}
		}
#endif

		if (pNdisBuffer) {

			NdisQueryBufferSafe( pNdisBuffer, &packetData, &uiLength, HighPagePriority );
			
			LpxFreeMemoryWithLpxTag( packetData );
			NdisFreeBuffer( pNdisBuffer );
		}

		break;
	default:
		ASSERT(FALSE);
		return;
	}

	//
	// Free external protocol reserved context.
	//

	externalReserved = ((PLPX_RESERVED)(Packet->ProtocolReserved))->ExternalReserved;
	if(externalReserved) {
		NdisFreeMemory(externalReserved, sizeof(LPX_RESERVED), 0);
	}

	ASSERT( Packet->Private.NdisPacketFlags & fPACKET_ALLOCATED_BY_NDIS );
	if(allocMiniport) {
		//
		// Return the packet allocated by NIC miniport
		//
		NdisReturnPackets(&Packet, 1);
	} else {

		NdisFreePacket( Packet );

		InterlockedDecrement( &NumberOfAllockPackets );
		DebugPrint( 3, ("Packet REALLY Freed NumberOfAllockPackets = %d\n", NumberOfAllockPackets) );

	}

}
/***************************************************************************
Routine Description:

    This routine examines if the packet at the head of the packet
    list can be copied to the adapter, and does so.

Arguments:

    Adapter - Pointer to the adapter block.

Return Value:

    None
*****************************************************************************/
void R6040DoNextSend(PR6040_ADAPTER Adapter)
{
    // The packet to process.
    PNDIS_PACKET Packet;

    // The current destination transmit buffer.
    // XMIT_BUF TmpBuf1;

    // Length of the packet
    ULONG Len;

    //RETAILMSG(R6040DBG, (TEXT("+")));

    // Check if we have enough resources and a packet to process
    while ((Adapter->FirstPacket != NULL) /*&&!Adapter->Tx_free_cnt*/)
    {
        // If we're shutting down, just get out of here (card may not be present)
        if (Adapter->ShuttingDown)
        {
            RETAILMSG(R6040DBG, (TEXT("R6040DoNextSend(): Shutdown detected\r\n")));
            break;
        }

        //If Queue full
        if (Adapter->Tx_free_cnt <= 0)
        {
            RETAILMSG(R6040DBG, (TEXT("R6040DoNextSend(): Queue full\r\n")));
            break;
        }

        // Get the length of the packet.
        NdisQueryPacket(
            Adapter->FirstPacket,
            NULL,
            NULL,
            NULL,
            &Len
            );

        //RETAILMSG(R6040DBG, (TEXT("R6040DoNextSend(): packet length = %d\r\n"), Len));

        // Remove the packet from the queue.
        Packet = Adapter->FirstPacket;
        Adapter->FirstPacket = RESERVED(Packet)->Next;

        if (Packet == Adapter->LastPacket)
        {
            Adapter->LastPacket = NULL;
        }

        // Copy down the packet.
        if (CardCopyDownPacket(Adapter, Packet,
                                &Adapter->PacketLens[Adapter->Tx_desc_add]) == FALSE)
        {
            RETAILMSG(R6040DBG, (TEXT("R6040DoNextSend(): Copy Down packet error\r\n")));

            NdisReleaseSpinLock(&Adapter->SendLock);

            NdisMSendComplete(
                Adapter->MiniportAdapterHandle,
                Packet,
                NDIS_STATUS_FAILURE
                );

            NdisAcquireSpinLock(&Adapter->SendLock);
            continue;
        }


        // Ack the send immediately.  If for some reason it
        // should fail, the protocol should be able to handle
        // the retransmit.
        NdisReleaseSpinLock(&Adapter->SendLock);

        //RETAILMSG(R6040DBG, (TEXT("R6040DoNextSend(): NdisMSendComplete \r\n")));

        NdisMSendComplete(
                Adapter->MiniportAdapterHandle,
                Packet,
                NDIS_STATUS_SUCCESS
                );

        NdisAcquireSpinLock(&Adapter->SendLock);
    }
    //RETAILMSG(R6040DBG, (TEXT("-")));
}
Example #25
0
VOID
PacketCancelRoutine (
	IN PDEVICE_OBJECT   DeviceObject,
	IN PIRP             Irp
)

{
	POPEN_INSTANCE      open = DeviceObject->DeviceExtension;
	KIRQL               oldIrql;
	PIRP                irpToComplete = NULL;
	PLIST_ENTRY         thisEntry, listHead;
	PIRP                pendingIrp;
	PNDIS_PACKET        myPacket = NULL;
	PPACKET_RESERVED    reserved;
	PMDL                mdl;

	// Don't assume that the IRP being cancelled is in the queue.
	// Only complete the IRP if it IS in the queue.
	//
	// Must acquire the local spinlock before releasing
	// the global cancel spinlock
	//
	// DebugPrint(("PacketCancelRoutine\n"));

	oldIrql = Irp->CancelIrql;

	// One should not intermix KeAcquireSpinLock(AtDpcLevel)
	// and ExInterlocked...List() functions on the same spinlock if the
	// routines that use the lock run at IRQL > DISPATCH_LEVEL.
	// After acquiring the lock using Ke function, if we got interrupted
	// and entered into an ISR and tried to manipulate the list using
	// ExInterlocked...List function with the same lock, we deadlock.
	// In this sample we can safely do that because none of our routines
	// will be called at IRQL > DISPATCH_LEVEL.

	KeAcquireSpinLockAtDpcLevel(&open->RcvQSpinLock);
	IoReleaseCancelSpinLock( KeGetCurrentIrql() );

	listHead = &open->RcvList;
	for( thisEntry = listHead->Flink; thisEntry != listHead; thisEntry = thisEntry->Flink ) {
		reserved=CONTAINING_RECORD(thisEntry,PACKET_RESERVED,ListElement);
		myPacket=CONTAINING_RECORD(reserved,NDIS_PACKET,ProtocolReserved);
		pendingIrp = RESERVED(myPacket)->Irp;
		if (pendingIrp == Irp) {
			RemoveEntryList(thisEntry);
			irpToComplete = pendingIrp;
			break;
		}
	}

	KeReleaseSpinLock(&open->RcvQSpinLock, oldIrql);

	if(irpToComplete) {
		// DebugPrint(("Cancelling IRP\n"));
		// ASSERT(myPacket);

		NdisFreePacket(myPacket);

		irpToComplete->IoStatus.Status = STATUS_CANCELLED;
		irpToComplete->IoStatus.Information = 0;
		IoCompleteRequest(irpToComplete, IO_NO_INCREMENT);
		IoDecrement(open);
	}
}
Example #26
0
NTSTATUS
SendPacketAlloc (
	IN  PDEVICE_CONTEXT		DeviceContext,
	IN  PTP_ADDRESS			Address,
	IN  UCHAR				DestinationAddressNode[],
	IN	PUCHAR				UserData,
	IN	ULONG				UserDataLength,
	IN	PIO_STACK_LOCATION	IrpSp,
	IN  UCHAR				Option,
	OUT	PNDIS_PACKET		*Packet
	)
{
	NTSTATUS		status;
	PUCHAR			packetHeader = NULL;
	PNDIS_BUFFER	packetHeaderBuffer = NULL;
	ULONG			packetHeaderLength;

	PNDIS_BUFFER	userDataBuffer = NULL;
	PUCHAR			paddingData = NULL;
	PNDIS_BUFFER	paddingDataBuffer = NULL;
	PNDIS_PACKET	packet = NULL;
	USHORT			etherType;


	packetHeaderLength = ETHERNET_HEADER_LENGTH + sizeof(LPX_HEADER);

#if __LPX_OPTION_ADDRESSS__

	if (FlagOn(Option, LPX_OPTION_SOURCE_ADDRESS)) {

		packetHeaderLength += ETHERNET_ADDRESS_LENGTH;
	}
	if (FlagOn(Option, LPX_OPTION_DESTINATION_ADDRESS)) {

		packetHeaderLength += ETHERNET_ADDRESS_LENGTH;
	}

#endif

	ASSERT( packetHeaderLength + UserDataLength <= ETHERNET_HEADER_LENGTH + DeviceContext->MaxUserData );
	
	DebugPrint( 3, ("SendPacketAlloc, packetHeaderLength = %d, NumberOfAllockPackets = %d\n", packetHeaderLength, NumberOfAllockPackets) );
	
	ASSERT( DeviceContext );
	ASSERT( DeviceContext->LpxPacketPool != NULL );

	do {
	
		NdisAllocatePacket( &status, &packet, DeviceContext->LpxPacketPool );

		if (status != NDIS_STATUS_SUCCESS) {
 	
			ASSERT( FALSE );
			LPX_ASSERT( status == NDIS_STATUS_RESOURCES );

			return status;
		}

		RtlZeroMemory( RESERVED(packet), sizeof(LPX_RESERVED) );

		ASSERT( packet->Private.NdisPacketFlags & fPACKET_ALLOCATED_BY_NDIS );

		packetHeader = (PCHAR)&RESERVED(packet)->EthernetHeader;

		NdisAllocateBuffer( &status,
							&packetHeaderBuffer,
							DeviceContext->LpxBufferPool,
							packetHeader,
							packetHeaderLength );

		if (!NT_SUCCESS(status)) {

			ASSERT( status == NDIS_STATUS_FAILURE ); 
			ASSERT( FALSE );
			break;
		}

		if (UserData && UserDataLength) {
			
			NdisAllocateBuffer( &status,
								&userDataBuffer,
								DeviceContext->LpxBufferPool,
								UserData,
								UserDataLength );

			if(!NT_SUCCESS(status)) {

				ASSERT( status == NDIS_STATUS_FAILURE ); 
				ASSERT( FALSE );
				break;
			}
		}

//////////////////////////////////////////////////////////////////////////
//
//	Add padding to fix Under-60byte bug of NDAS chip 2.0.
//

		if (packetHeaderLength == ETHERNET_HEADER_LENGTH + sizeof(LPX_HEADER)) {

			UINT		    totalPacketLength;

			totalPacketLength = packetHeaderLength + UserDataLength;

			if (totalPacketLength >= ETHERNET_HEADER_LENGTH + sizeof(LPX_HEADER) + 4 && totalPacketLength <= 56) {

			    LONG			paddingLen = 60 - totalPacketLength;
			
				DebugPrint( 4, ("[LpxSmp]TransmitDataPacket: Adding padding to support NDAS chip 2.0\n") );

				status = LpxAllocateMemoryWithLpxTag( &paddingData, paddingLen );

				if (status != NDIS_STATUS_SUCCESS) {

					ASSERT( status == NDIS_STATUS_FAILURE ); 
					ASSERT( FALSE );
			
					break;
				}

				NdisAllocateBuffer( &status,
									&paddingDataBuffer,
									DeviceContext->LpxBufferPool,
									paddingData,
									paddingLen );

				if (status != NDIS_STATUS_SUCCESS) {

					ASSERT( status == NDIS_STATUS_FAILURE ); 
					ASSERT( FALSE );
			
					break;
				}

				RtlZeroMemory( paddingData, paddingLen );

				RtlCopyMemory( paddingData + paddingLen - 4, UserData + UserDataLength - 4, 4 );
			}
		}

//
//	End of padding routine.
//
//////////////////////////////////////////////////////////////////////////

	} while(0);

	if (status == STATUS_SUCCESS) {
	
		RtlCopyMemory( &packetHeader[0],
					   DestinationAddressNode,
					   ETHERNET_ADDRESS_LENGTH );

		RtlCopyMemory( &packetHeader[ETHERNET_ADDRESS_LENGTH],
					   Address->NetworkName->Node,
					   ETHERNET_ADDRESS_LENGTH );

		etherType = HTONS( ETH_P_LPX );

		RtlCopyMemory( &packetHeader[ETHERNET_ADDRESS_LENGTH*2],
					   &etherType,
					   2 );

#if __LPX_OPTION_ADDRESSS__

		if (FlagOn(Option, LPX_OPTION_DESTINATION_ADDRESS)) {

			RtlCopyMemory( RESERVED(packet)->OptionDestinationAddress,
						   DestinationAddressNode,
						   ETHERNET_ADDRESS_LENGTH );	
		}

		if (FlagOn(Option, LPX_OPTION_SOURCE_ADDRESS)) {

			if (FlagOn(Option, LPX_OPTION_DESTINATION_ADDRESS)) {
		
				RtlCopyMemory( RESERVED(packet)->OptionSourceAddress,
							   Address->NetworkName->Node,
							   ETHERNET_ADDRESS_LENGTH );	
			
			} else {
			
				RtlCopyMemory( RESERVED(packet)->OptionDestinationAddress,
							   Address->NetworkName->Node,
							   ETHERNET_ADDRESS_LENGTH );	
			}
		}

#endif

		RESERVED(packet)->LpxHeader.PacketSize = HTONS( (USHORT)(packetHeaderLength - ETHERNET_HEADER_LENGTH + UserDataLength) );
		RESERVED(packet)->LpxHeader.Option = Option;

		RESERVED(packet)->Cloned = 0;
		RESERVED(packet)->IrpSp  = IrpSp;
		RESERVED(packet)->Type   = LPX_PACKET_TYPE_SEND;
		RESERVED(packet)->Packet = packet;
		
		if (IrpSp == NULL) {

			DebugPrint( 3, ("[LPX] PacketAllocate: No IrpSp\n") ) ;
		}
	
		if (paddingDataBuffer)
			NdisChainBufferAtFront( packet, paddingDataBuffer );
		
		if (userDataBuffer)
			NdisChainBufferAtFront( packet, userDataBuffer );
		
		NdisChainBufferAtFront( packet, packetHeaderBuffer );

		InterlockedIncrement( &NumberOfAllockPackets );
	
		*Packet = packet;
	
	} else {

		if (paddingDataBuffer)
			NdisFreeBuffer( paddingDataBuffer );

		if( paddingData)
			LpxFreeMemoryWithLpxTag( paddingData );

		if (userDataBuffer)
			NdisFreeBuffer( userDataBuffer );

		if (packetHeaderBuffer)
			NdisFreeBuffer( packetHeaderBuffer );
		
		if (packet)
			NdisFreePacket( packet );

		*Packet = NULL;
		
		DebugPrint( 1, ("[LPX]PacketAllocate: Can't Allocate Buffer For CopyData!!!\n") );
	}

	return status;
}
Example #27
0
NDIS_STATUS
PacketReceiveIndicate (
    IN NDIS_HANDLE ProtocolBindingContext,
    IN NDIS_HANDLE MacReceiveContext,
    IN PVOID       HeaderBuffer,
    IN UINT        HeaderBufferSize,
    IN PVOID       LookAheadBuffer,
    IN UINT        LookaheadBufferSize,
    IN UINT        PacketSize
)
{
	POPEN_INSTANCE      open;
	PIO_STACK_LOCATION  irpSp;
	PIRP                irp;
	PLIST_ENTRY         packetListEntry;
	PNDIS_PACKET        pPacket;
	ULONG               sizeToTransfer;
	NDIS_STATUS         status;
	UINT                bytesTransfered = 0;
	ULONG               bufferLength;
	PPACKET_RESERVED    reserved;
	PMDL                pMdl;

	// DebugPrint(("ReceiveIndicate\n"));

	open= (POPEN_INSTANCE)ProtocolBindingContext;

	if (HeaderBufferSize > ETHERNET_HEADER_LENGTH) {
			return NDIS_STATUS_SUCCESS;
	}

	//  See if there are any pending read that we can satisfy
	packetListEntry = ExInterlockedRemoveHeadList( &open->RcvList, &open->RcvQSpinLock );

	if (packetListEntry == NULL) {
		// DebugPrint(("No pending read, dropping packets\n"));
		return NDIS_STATUS_NOT_ACCEPTED;
	}

	reserved = CONTAINING_RECORD(packetListEntry,PACKET_RESERVED,ListElement);
	pPacket = CONTAINING_RECORD(reserved,NDIS_PACKET,ProtocolReserved);

	irp = RESERVED(pPacket)->Irp;
	irpSp = IoGetCurrentIrpStackLocation(irp);

	// We don't have to worry about the situation where the IRP is cancelled
	// after we remove it from the queue and before we reset the cancel
	// routine because the cancel routine has been coded to cancel an IRP
	// only if it's in the queue.

	IoSetCancelRoutine(irp, NULL);

	bufferLength = irpSp->Parameters.Read.Length-ETHERNET_HEADER_LENGTH;

		sizeToTransfer = (PacketSize < bufferLength) ? PacketSize : bufferLength;

	NdisMoveMappedMemory(
			MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority),
			HeaderBuffer,
			HeaderBufferSize
			);

	pMdl=IoAllocateMdl(
						MmGetMdlVirtualAddress(irp->MdlAddress),
						MmGetMdlByteCount(irp->MdlAddress),
						FALSE,
						FALSE,
						NULL
						);

	if (pMdl == NULL) {
		// DebugPrint(("Packet: Read-Failed to allocate Mdl\n"));
		status = NDIS_STATUS_RESOURCES;
		goto ERROR;
	}

	IoBuildPartialMdl(
			irp->MdlAddress,
			pMdl,
			((PUCHAR)MmGetMdlVirtualAddress(irp->MdlAddress))+ETHERNET_HEADER_LENGTH,
			0
			);

	pMdl->Next = NULL;

	RESERVED(pPacket)->pMdl=pMdl;

	NdisChainBufferAtFront(pPacket,pMdl);

	NdisTransferData(
			&status,
			open->AdapterHandle,
			MacReceiveContext,
			0,
			sizeToTransfer,
			pPacket,
			&bytesTransfered
	);

	if (status == NDIS_STATUS_PENDING) {
		return NDIS_STATUS_SUCCESS;
	}

ERROR:
	PacketTransferDataComplete( open, pPacket, status, bytesTransfered );
	return NDIS_STATUS_SUCCESS;
}
Example #28
0
NTSTATUS
RcvPacketAlloc (
	IN  PDEVICE_CONTEXT		DeviceContext,
	IN	ULONG				PacketDataLength,
	OUT	PNDIS_PACKET		*Packet
	)
{
	NTSTATUS		status;
	PUCHAR			packetData = NULL;
	PNDIS_BUFFER	packetDataBuffer = NULL;
	PNDIS_PACKET	packet = NULL;


	DebugPrint( 3, ("RcvPacketAlloc, PacketLength = %d, NumberOfAllockPackets = %d\n", PacketDataLength, NumberOfAllockPackets) );
	
	ASSERT( DeviceContext );
	ASSERT( DeviceContext->LpxPacketPool != NULL );

	ASSERT( PacketDataLength <= DeviceContext->MaxUserData );

	do {
	
		NdisAllocatePacket( &status, &packet, DeviceContext->LpxPacketPool );

		if (status != NDIS_STATUS_SUCCESS) {
 	
			ASSERT( status == NDIS_STATUS_RESOURCES );
			ASSERT( FALSE );

			return status;
		}

		RtlZeroMemory( RESERVED(packet), sizeof(LPX_RESERVED) );

		ASSERT( packet->Private.NdisPacketFlags & fPACKET_ALLOCATED_BY_NDIS );

		if (PacketDataLength) {
		
			status = LpxAllocateMemoryWithLpxTag( &packetData,
												  PacketDataLength );

			if (status != NDIS_STATUS_SUCCESS) {

				ASSERT( status == NDIS_STATUS_FAILURE ); 
				ASSERT( FALSE );
			
				break;
			}

			NdisAllocateBuffer( &status,
								&packetDataBuffer,
								DeviceContext->LpxBufferPool,
								packetData,
								PacketDataLength );

			if (!NT_SUCCESS(status)) {

				ASSERT( status == NDIS_STATUS_FAILURE ); 
				ASSERT( FALSE );
				break;
			}

			NdisChainBufferAtFront( packet, packetDataBuffer );
		}
	
	} while(0);

	if (status == STATUS_SUCCESS) {
	
		RESERVED(packet)->Cloned = 0;
		RESERVED(packet)->Type = LPX_PACKET_TYPE_RECEIVE;
		RESERVED(packet)->Packet = packet;
	
		InterlockedIncrement( &NumberOfAllockPackets );
	
		*Packet = packet;
	
#if __LPX_STATISTICS__
		
		KeQuerySystemTime( &RESERVED(packet)->RecvTime2 );
		RESERVED(packet)->DeviceContext = DeviceContext;

#endif

	} else {

		if (packetDataBuffer)
			NdisFreeBuffer( packetDataBuffer );
		
		if (packetData)
			LpxFreeMemoryWithLpxTag( packetData );

		if (packet)
			NdisFreePacket( packet );

		*Packet = NULL;
		
		DebugPrint( 1, ("[LPX]RcvPacketAlloc: Can't Allocate Buffer For CopyData!!!\n") );
	}

	return status;
}