PCIe pass through for Wifi Dev
For the last little while I have been working on porting a WiFi driver. I initially planned to use one of my testbed machines, but the card I had wasn't supported by the original driver and locked up the system.
While waiting for another card I spun up development on the Morefine M6 which had failed complete at its proposed role as a desktop mirrored storage array.
The Morefine M6 has an Intel N200 SoC and supported Intel wifi.
I always set out to try PCIe pass through and the FreeBSD wiki page provided most of what I needed .
On the host you need to exclude the PCIe devices you wish to give to a guest.
You need to find the PCIe address for the device to exclude,
pciconf -lv
is
good for this:
# pciconf -lv
...
none2@pci0:0:20:2: class=0x050000 rev=0x00 hdr=0x00 vendor=0x8086 device=0x54ef subvendor=0x8086 subdevice=0x7270
vendor = 'Intel Corporation'
device = 'Alder Lake-N PCH Shared SRAM'
class = memory
subclass = RAM
ppt0@pci0:0:20:3: class=0x028000 rev=0x00 hdr=0x00 vendor=0x8086 device=0x54f0 subvendor=0x8086 subdevice=0x0070
vendor = 'Intel Corporation'
device = 'CNVi: Wi-Fi'
class = network
ig4iic0@pci0:0:21:0: class=0x0c8000 rev=0x00 hdr=0x00 vendor=0x8086 device=0x54e8 subvendor=0x8086 subdevice=0x7270
vendor = 'Intel Corporation'
class = serial bus
ig4iic1@pci0:0:21:1: class=0x0c8000 rev=0x00 hdr=0x00 vendor=0x8086 device=0x54e9 subvendor=0x8086 subdevice=0x7270
vendor = 'Intel Corporation'
class = serial bus
...
I have passed PCIe device 0:20:3 to my guests, in the
pciconf
list you will
see the driver assigned to the device followed by the bus and the address. So
the ig4 i2c driver has devices
ig4iic0@pci0:0:21:0
and
ig4iic1@pci0:0:21:1
and the 'Wi-Fi' device has been taken by ppt0.
This is configured by adding the PCIe address to
/boot/loader.conf
:
pptdevs="0/20/3" # intel wifi
We need to give our PCIe device to our VM, I am simple person and do all my
bhyve through
vmrun.sh
and wrapper shell scripts. For FreeBSD the script is
this:
#!/bin/sh
diskimage="not set"
vmname="not set"
pcidev="0/20/3"
diskimage="/home/tj/vms/fbsd-iwx.raw"
vmname=$(basename $diskimage .raw)
if [ $# -ge 1 ]
then
for x in $@
do
interfaces="$interfaces -t $x"
done
else
echo 'usage: launchfreebsd.sh tapDev [tapDev tapDev ...]'
exit
fi
echo starting vm $vmname from image $diskimage with interfaces ${interfaces}
sh /usr/share/examples/bhyve/vmrun.sh \
-c $(nproc) \
-m 8G \
-p ${pcidev} \
${interfaces} \
-d $diskimage \
$vmname
And for OpenBSD:
#!/bin/sh
diskimage="not set"
vmname="not set"
pcidev="0/20/3"
diskimage="/home/tj/vms/obsd.raw"
vmname=$(basename $diskimage .raw)
#setup="true"
if [ $# -ge 1 ]
then
for x in $@
do
interfaces="$interfaces -t $x"
done
else
echo 'usage: $0 tapDev [tapDev tapDev ...]'
exit
fi
echo starting vm $vmname from image $diskimage with interfaces ${interfaces}
if [ -z $setup ]
then
bhyve -A -D -H -P -S -u -w -c 4 -m 8G \
-s 0,amd_hostbridge \
-s 3,virtio-blk,${diskimage} \
-s 5,passthru,${pcidev} \
-s 10,virtio-net,tap0 \
-s 20,virtio-rnd \
-s 31,lpc -l com1,stdio \
-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \
$vmname
else
vmname=openbsd-installer
echo "Trying to run installer, remember to configure serial"
echo " set tty com0"
bhyve -A -D -H -P -S -u -w -c 4 -m 8G \
-s 0,amd_hostbridge \
-s 3,virtio-blk,${diskimage} \
-s 4,ahci-hd,/home/tj/miniroot76.img \
-s 5,passthru,${pcidev} \
-s 10,virtio-net,tap0 \
-s 20,virtio-rnd \
-s 31,lpc -l com1,stdio \
-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \
$vmname
fi
bhyvectl --destroy --vm=$vmname
In the FreeBSD VM I want to override the default driver so I can test my port
this is done by adding a block line to
/etc/rc.conf
:
devmatch_blocklist="if_iwlwifi"
My work on FreeBSD is supported by the FreeBSD Foundation , you can contribute to improving FreeBSD with code, documentation or financially by donating to the FreeBSD Foundation .