How to develop a miniport-intermediate-driver: for a NIC with multiple interfaces?

Hi:

I am developing a Miniport driver for a NIC.
The NIC has 1 - 4 channels depending on HW model. My goal is to create 1 - 4 network interfaces. Each interface has its own MAC and IP address.

I believe I should make a miniport-intermediate-driver:

The single drive will handle HW interface(PCIe memory I/O) and expose logical adapters.

Now, I call NdisMRegisterMiniportDriver() in DriverEntry(). InitializeHandlerEx() gets called and I call NdisMSetMiniportAttributes(). Then 1 network interface is created.

I have many questions. But I would ask the first 2:

  1. I don't want to expose the interface for the physical device. I just want to expose the logical interfaces when I detect the channels on my HW.
    How do I prevent the physical device interface being exposed?
  2. How to get the HW interface?
    My driver used to be a generic PCIe device driver. I called WdfDriverCreate() in DriverEntry() and gets the PCIe I/O address in EvtDevicePrepareHardware(). From there, I can access to the HW.
    However, EvtDevicePrepareHardware() was not called if I call NdisMRegisterMiniportDriver().

Many thanks for the answers. And feel free the correct any of my saying if they were wrong.

Kevin

Bonjour Kevin,

I just completed a driver for a PCI card with 2 ethernet port on it. I developped using NetAdapterCx because I expected it support more than 1 network adapter for the same PCIe device. But, after reaching the NetAdapterCx team, I learned it does not.

So, on Windows, each Ethernet port must be associated to a single device driver instance.

Often, the PCI device present the 2 (or more) Ethernet port as separate "PCIe function". This way, Windows load a device driver instance for each of them.

In my case, the FPGA was not able to present more than 1 PCIe function. So I created 2 drivers. The first one is loaded for the PCIe device. It manage all PCIe stuff and also act as a BUS driver and enumerate 2 "software" devices.
The second driver is the NDIS driver (based on NetAdapterCx). It use a private interface to communicate with the first driver and access PCIe stuff.

The PCIe part is called DrvDMA
0066_en.pdf

Have fun!
Martin Dubois

Hi Martin:

My FPGA is similar as yours.
I studied NetAdapterCx in 2020 but didn't use it as it was for mobile adapter only and didn't support old version of Windows.

Now, it should be good for all NICs.

What prevents it from supporting more than 1 network adapter for a single PCIe device? Can you call NetAdapterCreate() multiple times at EvtDriverDeviceAdd()?

Thanks
Kevin

Hi Martin:

I just checked out your project DrvDMA. This part:

        for (unsigned int i = 0; i < ADAPTER_QTY; i++)
        {
            lResult = Adapter_Create(lDevice, lThis->mAdapters + i);
            if (STATUS_SUCCESS != lResult)
            {
                DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, __FUNCTION__ " - Adapter_Create( ,  ) failed - 0x%08x\n", lResult);
                break;
            }
        }

If ADAPTER_QTY > 1, can you expose multiple network interface?

Thanks
Kevin

Bonjour Kevin,

What you just checked is a sample of a NID's driver using DrvDMA. Unfortunately, this sample is not up to date with what I learned when I created a real driver based on this sample.

I plan to update this sample when I get some free time.

I created a Wiki page to describe what I learned about NetAdapterCx and be able to share it with other driver developer as you.

Many Interfaces per Device | KMS Wiki

If you have other question, do not hesitate to reach me here or by e-mail.
Martin

Hi Martin:

Your Wiki is very helpful.
I also looked at Microsoft's MUX sample (Windows-driver-samples/network/ndis/mux at develop · microsoft/Windows-driver-samples · GitHub). But it is very complicated so I prefer to follow your way.

I have a couple questions:

  1. What class does the PCIe device driver belong to? I mean the class in inf file.
  2. In my PCIe device driver, I can detect 2 channels. How do I notify the NDIS driver to create 2 interfaces (calling NetAdapterCreate) ?

Thanks
Kevin

Bonjour Kevin,

Thanks for sharing the link to the MUX sample. I was not knowing about it. The approach is very similar to mine.

Now, let answer your question.

  1. The class I use is a user defined class. I call it "DrvDMA" and I just created a new GUID for it.
  2. In my case, because I wan the PCIe driver to be as generic as possible, I configure the number of "software function" into the registry base. The DrvDMA driver read registry at start and then know how many NIC driver to indicates. Note that the PCIe driver do not know if the the other driver is a NIC driver or a Toaster driver. It only know (from the registry) the device count and vendor and device id for each ones.

Have fun,
Regards

I need to correct my last post now I get a real look to the MUX sample. The MUX sample is very interesting, but It is clearly not similar to my approach. In fact, I don't believe it aims to address the same issue.