ProtocolStatusEx: NDIS_STATUS_OPER_STATUS vs NDIS_STATUS_LINK_STATE

Hi

I own miniport/protocol driver. My protocol driver has some clients.

My protocol driver so far indicated link_down to it clients on
ProtocolStatusEx(NDIS_STATUS_OPER_STATUS and ! NET_IF_OPER_STATUS_UP ).

http://msdn.microsoft.com/en-us/library/windows/hardware/ff568746(v=VS.85).aspx

typedef enum _NET_IF_OPER_STATUS {
NET_IF_OPER_STATUS_UP = 1,
NET_IF_OPER_STATUS_DOWN,
NET_IF_OPER_STATUS_TESTING,
NET_IF_OPER_STATUS_UNKNOWN,
NET_IF_OPER_STATUS_DORMANT,
NET_IF_OPER_STATUS_NOT_PRESENT,
NET_IF_OPER_STATUS_LOWER_LAYER_DOWN
} NET_IF_OPER_STATUS, *PNET_IF_OPER_STATUS;

I did not have any issues with above so far.
But in Win 2012 that same code is messing my remote BOOT case.
So I want to move to NDIS_STATUS_LINK_STATE to depend/indicate media_Sense state to my protocol clients.

  1. Why does NDIS send above status to all protocols even when the physical link is good for TX?

  2. When does NDIS send NDIS_STATUS_OPER_STATUS ?
    Can I still assume physical link is good for TX even when I get this with code other than NET_IF_OPER_STATUS_UP .
    My protocol driver doesn’t have 802.1x authentciation states etc

Thx.

NDIS distinguishes between a link state and an oper state, because the difference can be very interesting to end-users. If NDIS has taken down the interface to pause/restart a filter driver, you don’t want to tell the end-user “oh your network cable is unplugged” – because the cable is NOT unplugged. On a Windows 8 AOAC system, you might see the interesting combination of a NIC whose media state is Connected, but whose ifOperStatus is Dormant.

More theoretically, the ifOperStatus stuff actually comes from RFC 2863. The RFC created ifOperStatus to communicate more specialized states, like “this interface is currently connected, but the administrator has declared that applications cannot use it”. (Windows doesn’t really expose AdminStatus in the UI today, although we might find a use for it in some hypothetical future version of the OS).

In general, a protocol driver should not attempt to send data if the ifOperStatus is any value other than NET_IF_OPER_STATUS_UP. (The protocol driver should also pay attention to other states, like NetEventPause and NetEventSetPower[Dx]).

I’d be interested to know how Windows Server 2012 is “messing” your remote boot. I can’t think of any breaking changes in this area.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Tuesday, May 15, 2012 9:27 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] ProtocolStatusEx: NDIS_STATUS_OPER_STATUS vs NDIS_STATUS_LINK_STATE

Hi

I own miniport/protocol driver. My protocol driver has some clients.

My protocol driver so far indicated link_down to it clients on ProtocolStatusEx(NDIS_STATUS_OPER_STATUS and ! NET_IF_OPER_STATUS_UP ).

http://msdn.microsoft.com/en-us/library/windows/hardware/ff568746(v=VS.85).aspx

typedef enum _NET_IF_OPER_STATUS {
NET_IF_OPER_STATUS_UP = 1,
NET_IF_OPER_STATUS_DOWN,
NET_IF_OPER_STATUS_TESTING,
NET_IF_OPER_STATUS_UNKNOWN,
NET_IF_OPER_STATUS_DORMANT,
NET_IF_OPER_STATUS_NOT_PRESENT,
NET_IF_OPER_STATUS_LOWER_LAYER_DOWN
} NET_IF_OPER_STATUS, *PNET_IF_OPER_STATUS;

I did not have any issues with above so far.
But in Win 2012 that same code is messing my remote BOOT case.
So I want to move to NDIS_STATUS_LINK_STATE to depend/indicate media_Sense state to my protocol clients.

  1. Why does NDIS send above status to all protocols even when the physical link is good for TX?

  2. When does NDIS send NDIS_STATUS_OPER_STATUS ?
    Can I still assume physical link is good for TX even when I get this with code other than NET_IF_OPER_STATUS_UP .
    My protocol driver doesn’t have 802.1x authentciation states etc

Thx.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Jeff, Thx for the reply.

Below is the NET PnP/status sequence. This same sequence was working on 2k8 R2.
***On R2 I need to check though if I was getting DORMANT_PAUSED.***
On 2012 Server all below are conspiring (including S1 below) to kick me out of the switch, i.e. windows thinks it doesn’t have access to BOOT disk anymore and BSOD (I am thinking windows tolerance for BOOT disk access might have also reduced)
[Processor#]

[1] Status: OperationalStatus: NET_IF_OPER_STATUS_DORMANT, Flags: NET_IF_OPER_STATUS_DORMANT_PAUSED (0x4)
[1] Status: LINK_EVENT_FLAGS - ***DOWN***
?
[1] PnP: [8] *NetEventPause*
[1] PnP: Reason - NDIS_PAUSE_BIND_PROTOCOL
?
01> [0] MiniportPause: Miniport paused
01> [0] MiniportRestart: Miniport restarted
[1] PnP: [9] *NetEventRestart*
?
[1] Status: OperationalStatus: NET_IF_OPER_STATUS_UP, Flags: * Unknwn net_if_oper_flags !!! * (0x0)
[1] Status: LINK_EVENT_FLAGS - *UP*

>>
In general, a protocol driver should not attempt to send data if the
ifOperStatus is any value other than NET_IF_OPER_STATUS_UP.
<<
O.k. I will revert back to what it was before then. I also found some optimizations I can do on pause/restart (but then the same was working on R2?).
I follow all the Pause/Restart rules.
On Pause I do below
a) Don’t send
b) return all RX NBLs’

[Q1] I was looking for if I can do OIDs when PAused, I thought I had that info in WDK soemwhere, but now not able to find it.
I can do OIDs while paused, right?

[S1] Another thing added to the mix is my protocol is operational only once I send an OID to program something in HW.
Below is what I am observing. Will debug more…
As soon as I am in NDis/Restart state, I get something from switch and now need to send down that OID.

I am on Proc1 and send the OID down. The OID is called at Dispatcl_LEvel. Hence it returns PENDING. But I do not get ProtocolOIDRequestComplete() at all.
On this, I fire a timer and do the OID again, still no ProtocolOIDRequestComplete().
This goes not for almost >15 secs.

Once I give up this timer. I now see all above pending OIDS being completed on Proc2 continuously.
But that is too late, I need OID to be completed for my wire protocol to proceed to next state.
[Q2]Any hints on why/how to debug above OID scenario.

I did notice as long as the PRoc1.Timer is fired/active, the OIDS did not even reach the miniport.
But once PRoc1 gave up, suddenly all the OIDs invocation instances rushed into miniport and completed. Anyways debugging more on this OID case.

[S2] Not sure this matters, miniport is 6.3, protocol is 6.2. So I guess all the NDIS stack downgraded to 6.2.

Thx.

> I can do OIDs while paused, right?

Yes. “Pause” only refers to datapath state.

But I do not get ProtocolOIDRequestComplete() at all. On this, I fire a timer and do the OID again

That’s probably not useful. NDIS serializes OIDs at the miniport; if the first OID is stuck, you won’t get a better response by queuing another OID behind the first.

Any hints on why/how to debug above OID scenario.

Well you mentioned that you own the miniport driver too. I’d start there – does your miniport see the OID? What’s the output of the !ndiskd.oid debugger command? Are there any filters between your miniport and protocol?

I did notice as long as the PRoc1.Timer is fired/active, the OIDS did not even reach the miniport. But once PRoc1 gave up, suddenly all the OIDs invocation instances rushed into miniport and completed.

That sounds suspicious. Timer DPCs should run quickly; your timer should not be waiting in it. In particular, a protocol *must*not* wait at DISPATCH_LEVEL for a pended OID request to complete. The contract for miniports is that the miniport gets an OID at PASSIVE_LEVEL. If there’s only one CPU, then you’d have a priority inversion if a DISPATCH_LEVEL protocol waited for a PASSIVE_LEVEL miniport.

Not sure this matters, miniport is 6.3, protocol is 6.2. So I guess all the NDIS stack downgraded to 6.2.

For general OID handling, there’s no significant difference between 6.20 and 6.30. NDIS doesn’t do any downgrading, except for specific system-defined OIDs.

As for the log with NET_IF_OPER_STATUS_DORMANT, that looks fairly typical for a protocol bind operation.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Wednesday, May 16, 2012 7:48 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] ProtocolStatusEx: NDIS_STATUS_OPER_STATUS vs NDIS_STATUS_LINK_STATE

Jeff, Thx for the reply.

Below is the NET PnP/status sequence. This same sequence was working on 2k8 R2.
***On R2 I need to check though if I was getting DORMANT_PAUSED.***
On 2012 Server all below are conspiring (including S1 below) to kick me out of the switch, i.e. windows thinks it doesn’t have access to BOOT disk anymore and BSOD (I am thinking windows tolerance for BOOT disk access might have also reduced)
[Processor#]

[1] Status: OperationalStatus: NET_IF_OPER_STATUS_DORMANT, Flags: NET_IF_OPER_STATUS_DORMANT_PAUSED (0x4)
[1] Status: LINK_EVENT_FLAGS - ***DOWN***
?
[1] PnP: [8] *NetEventPause*
[1] PnP: Reason - NDIS_PAUSE_BIND_PROTOCOL
?
01> [0] MiniportPause: Miniport paused
01> [0] MiniportRestart: Miniport restarted
[1] PnP: [9] *NetEventRestart*
?
[1] Status: OperationalStatus: NET_IF_OPER_STATUS_UP, Flags: * Unknwn net_if_oper_flags !!! * (0x0)
[1] Status: LINK_EVENT_FLAGS - *UP*

>>
In general, a protocol driver should not attempt to send data if the
ifOperStatus is any value other than NET_IF_OPER_STATUS_UP.
<<
O.k. I will revert back to what it was before then. I also found some optimizations I can do on pause/restart (but then the same was working on R2?).
I follow all the Pause/Restart rules.
On Pause I do below
a) Don’t send
b) return all RX NBLs’

[Q1] I was looking for if I can do OIDs when PAused, I thought I had that info in WDK soemwhere, but now not able to find it.
I can do OIDs while paused, right?

[S1] Another thing added to the mix is my protocol is operational only once I send an OID to program something in HW.
Below is what I am observing. Will debug more…
As soon as I am in NDis/Restart state, I get something from switch and now need to send down that OID.

I am on Proc1 and send the OID down. The OID is called at Dispatcl_LEvel. Hence it returns PENDING. But I do not get ProtocolOIDRequestComplete() at all.
On this, I fire a timer and do the OID again, still no ProtocolOIDRequestComplete().
This goes not for almost >15 secs.

Once I give up this timer. I now see all above pending OIDS being completed on Proc2 continuously.
But that is too late, I need OID to be completed for my wire protocol to proceed to next state.
[Q2]Any hints on why/how to debug above OID scenario.

I did notice as long as the PRoc1.Timer is fired/active, the OIDS did not even reach the miniport.
But once PRoc1 gave up, suddenly all the OIDs invocation instances rushed into miniport and completed. Anyways debugging more on this OID case.

[S2] Not sure this matters, miniport is 6.3, protocol is 6.2. So I guess all the NDIS stack downgraded to 6.2.

Thx.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

My protocol driver has a client which is a driver and it was constantly rescheduleing DPC, when it should not have. Fixing that (along with not treating DORMANT_PAUSE as PHYSICAL_LINK_DOWN) took care of the issues.

Thx.