Cancelación de datos de red con anillos netos

Los controladores de cliente netAdapterCx cancelan los datos de red cuando el marco invoca su función de devolución de llamada EvtPacketQueueCancel para una cola de paquetes. Esta devolución de llamada es donde los controladores de cliente realizan cualquier procesamiento necesario antes de que el marco elimine las colas de paquetes.

Cancelación de una cola de transmisión

En la función de devolución de llamada EvtPacketQueueCancel para una cola de transmisión, tiene la oportunidad de completar los paquetes de transmisión pendientes. A diferencia de una cola de recepción, no es necesario hacerlo. Si deja paquetes pendientes, NetAdapterCx llama a evtPacketQueueAdvance para la cola de transmisión, donde los procesa como parte de su operación normal.

Si el hardware admite la cancelación de las transmisións en curso, también debe avanzar el iterador de paquetes posteriores del anillo neto más allá de todos los paquetes cancelados. Esto podría tener un aspecto similar al del ejemplo siguiente:

void
MyEvtTxQueueCancel(
    NETPACKETQUEUE TxQueue
)
{
    // Get the transmit queue's context to retrieve the net ring collection
    PMY_TX_QUEUE_CONTEXT txQueueContext = MyGetTxQueueContext(TxQueue);
    NET_RING_COLLECTION const * ringCollection = txQueueContext->RingCollection;
    NET_RING * packetRing = ringCollection->Rings[NET_RING_TYPE_PACKET];
    UINT32 currentPacketIndex = packetRing->BeginIndex;
    UINT32 packetEndIndex = packetRing->EndIndex;

    while (currentPacketIndex != packetEndIndex)
    {
        // Mark this packet as canceled with the scratch field, then move past it
        NET_PACKET * packet = NetRingGetPacketAtIndex(packetRing, currentPacketIndex);
        packet->Scratch = 1;
        currentPacketIndex = NetRingIncrementIndex(packetRing, currentPacketIndex);
    }
    
    packetRing->BeginIndex = packetRing->EndIndex;
}

Si el hardware no admite la cancelación, esta devolución de llamada puede devolverse sin tomar medidas.

Cancelación de una cola de recepción

En la función de devolución de llamada EvtPacketQueueCancel para una cola de recepción, debe completar los paquetes de recepción pendientes. Si no devuelve todos los paquetes, el sistema operativo no elimina la cola y NetAdapterCx deja de llamar a las devoluciones de llamada de la cola.

Para devolver paquetes, primero debe intentar indicar cualquier recepción que se haya indicado mientras se deshabilitaba la ruta de acceso de recepción y, a continuación, establecer todos los paquetes que se omitirán y devolver todos los fragmentos al sistema operativo. Esto podría ser similar al ejemplo de código siguiente.

Nota:

En este ejemplo se dejan los detalles para indicar que recibe. Para obtener un ejemplo de código de recepción de datos, consulte Recepción de datos de red con anillos netos.

void
MyEvtRxQueueCancel(
    NETPACKETQUEUE RxQueue
)
{
    // Get the receive queue's context to retrieve the net ring collection
    PMY_RX_QUEUE_CONTEXT rxQueueContext = MyGetRxQueueContext(RxQueue);
    NET_RING_COLLECTION const * ringCollection = rxQueueContext->RingCollection;
    NET_RING * packetRing = ringCollection->Rings[NET_RING_TYPE_PACKET];
    NET_RING * fragmentRing = ringCollection->Rings[NET_RING_TYPE_FRAGMENT];
    UINT32 currentPacketIndex = packetRing->BeginIndex;
    UINT32 packetEndIndex = packetRing->EndIndex;

    // Set hardware register for cancellation
    ...
    //

    // Indicate receives
    ...
    //

    // Get all packets and mark them for ignoring
    currentPacketIndex = packetRing->BeginIndex;
    while(currentPacketIndex != packetEndIndex)
    {
        NET_PACKET * packet = NetRingGetPacketAtIndex(packetRing, currentPacketIndex);
        packet->Ignore = 1;
        currentPacketIndex = NetRingIncrementIndex(packetRing, currentPacketIndex);
    }
    
    packetRing->BeginIndex = packetRing->EndIndex;

    // Return all fragments to the OS
    fragmentRing->BeginIndex = fragmentRing->EndIndex;
}