[rt2x00-users] Success story: running RT2800 802.11n PCI [1814:0601] as AP in VM with vfio

Andreas Hartmann andihartmann at 01019freenet.de
Fri Jul 27 18:48:51 AEST 2012


Hello,

I managed to run this PCI (not PCIe(!)) device

06:07.0 Network controller [0280]: Ralink corp. RT2800 802.11n PCI [1814:0601]
        Subsystem: Linksys Device [1737:0067]
        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=slow >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Latency: 32 (500ns min, 1000ns max), Cache Line Size: 64 bytes
        Interrupt: pin A routed to IRQ 21
        Region 0: Memory at fd8e0000 (32-bit, non-prefetchable) [size=64K]
        Capabilities: [40] Power Management version 3
                Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
                Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
        Kernel driver in use: vfio-pci

in a VM, which is used as AP (802.11n) on an AMD 900 series chipset.


The device as seen by the VM:

00:06.0 Network controller [0280]: Ralink corp. RT2800 802.11n PCI [1814:0601]
        Subsystem: Linksys Device [1737:0067]
        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=slow >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Latency: 32 (500ns min, 1000ns max), Cache Line Size: 64 bytes
        Interrupt: pin A routed to IRQ 11
        Region 0: Memory at febe0000 (32-bit, non-prefetchable) [size=64K]
        Capabilities: [40] Power Management version 3
                Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
                Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
        Kernel driver in use: rt2800pci


The hardware being used besides the network interface is a
Gigabyte GA-990XA-UD3, BIOS F11 05/17/2012 mainboard, which handles
PCI devices behind a ATI SB700/SB800/SB900 PCI to PCI bridge and which
supports IOMMU.

The softwarestack being used is (host):

- openSUSE 11.4 with kernel-desktop-3.4.6-1.1 with vfio-patch from Alex
  Williamson (https://github.com/awilliam/linux-vfio) and qemu from
  Alex Williamson (https://github.com/awilliam/qemu-vfio) and with
  additional PCI quirks https://patchwork.kernel.org/patch/1186581/

- libvirt-0.9.10-200.1.x86_64 with the following VM:

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
  <name>Ap</name>
  <uuid>11111111-1111-1111-1111-111111111111</uuid>
  <memory>262144</memory>
  <cpu mode='host-passthrough'/>
  <vcpu>1</vcpu>
  <os>
    <type arch='x86_64'>hvm</type>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <pae/>
  </features>
  <clock offset='utc'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <devices>
    <emulator>/usr/local/bin/qemu-system-x86_64</emulator>

    <disk type='file' device='disk'>
      <source file='/vm/ap-12.1.hd'/>
      <target dev='vda' bus='virtio'/>
      <driver name='qemu' type='qcow2' cache='none'/>
    </disk>

    <interface type='ethernet'>
      <mac address='00:00:00:00:00:00'/>
      <script path='no'/>
      <target dev='tap12'/>
      <model type='virtio'/>
    </interface>

    <input type='mouse' bus='ps2'/>
    <graphics type='vnc' port='5934' autoport='no'/>
    <video>
      <model type='cirrus' vram='9216' heads='1'/>
    </video>
  </devices>

  <qemu:commandline>
    <qemu:arg value='-device'/>
    <qemu:arg value='vfio-pci,host=06:07.0'/>
  </qemu:commandline>
</domain>


The VM is started like this:

------------------------------------------------------------------------
#!/bin/sh

function bind() {
modprobe vfio-pci

# WLAN-Device
echo "1814 0601" > /sys/bus/pci/drivers/vfio-pci/new_id
echo 0000:06:07.0 > /sys/bus/pci/devices/0000:06:07.0/driver/unbind
echo 0000:06:07.0 > /sys/bus/pci/drivers/vfio-pci/bind

sleep 1

chgrp virtuser /dev/vfio/13
chmod 660 /dev/vfio/13

chgrp virtuser /dev/vfio/vfio
chmod 660 /dev/vfio/vfio
}

if [ -S /ssd/browser/vm/.libvirt/qemu/lib/Ap.monitor ]; then
    echo "Ap laueft schon!"
    exit 1
fi

bind

ulimit -l 524288
su virtuser -c "virsh start Ap"
-------------------------------------------------------------------------



The softwarestack being used is (VM):

- OpenSUSE 12.1 (kernel-desktop-3.1.10-1.16) 64bit
- hostapd: hostap-e1bd4e1 (from Jun 6 2012) - without monitor device.
- compat-wireless-3.5-rc5-1.tar.bz2 with these additional patches:

prohibit sending more than one beacon:
--- a/drivers/net/wireless/rt2x00/rt2800lib.c     2011-11-14 23:18:11.000000000 +0100
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c     2011-11-25 16:27:15.000000000 +0100
@@ -1195,7 +1197,7 @@
                if (!is_zero_ether_addr((const u8 *)conf->bssid)) {
                        reg = le32_to_cpu(conf->bssid[1]);
                        rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 3);
-                       rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 7);
+                       rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 0);
                        conf->bssid[1] = cpu_to_le32(reg);
                }

---

Enable 802.11w for rt2x00pci by using sw-encryption.

--- a/drivers/net/wireless/rt2x00/rt2800pci.c  2012-04-26 22:10:30.000000000 +0200
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c  2012-05-10 19:06:51.813040835 +0200
@@ -52,7 +52,7 @@
  */
 static bool modparam_nohwcrypt = false;
 module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
-MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption. Enable MFP (802.11w)");

 static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
 {
@@ -1020,6 +1020,11 @@
        __set_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags);
        if (!modparam_nohwcrypt)
                __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags);
+       else {
+               INFO(rt2x00dev, "802.11w support (MFP) enabled.\n");
+               rt2x00dev->hw->flags |=
+                   IEEE80211_HW_MFP_CAPABLE;
+       }
        __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
        __set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags);

---


The device behaves in the VM the same way as on bare metal. Throughput
with scp is at ~ 10-12 MB/s using a ath9k (ar9285) supplicant through
ferroconcrete ceiling.
The configured WLAN is: 802.11n / 40MHz / EAP-tls / 802.11w


This is a fine improvement for AMD chipset 900 series users using 
legacy PCI devices because it offers the ability to run
an AP separated of the host. This gives you the easy to operate ability
to run a longterm stable and fast AP.



Thanks to all of the contributors which offered this fine improvement!



Kind regards,
Andreas



More information about the users mailing list