diff mbox

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

Message ID 20120727104851.5f5b6745@dualc.maya.org (mailing list archive)
State New, archived
Headers show

Commit Message

Andreas Hartmann July 27, 2012, 8:48 a.m. UTC
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:
---


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
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Helmut Schaa Aug. 31, 2012, 7:24 a.m. UTC | #1
Hi Andreas,

On Fri, Jul 27, 2012 at 10:48 AM, Andreas Hartmann
<andihartmann@01019freenet.de> wrote:
> Hello,
>
> I managed to run this PCI (not PCIe(!)) device

This is pretty cool!

> 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:

Yup, I still haven't figured out how to fix this properly but I still got
the problem on my TODO list.

> --- 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.

I think we could apply this to wireless-testing since you already did
some testing, right?

> --- 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
>
> _______________________________________________
> users mailing list
> users@rt2x00.serialmonkey.com
> http://rt2x00.serialmonkey.com/mailman/listinfo/users_rt2x00.serialmonkey.com
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

--- 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);