About wil6210#

The wil6210 driver supports 60GHz wireless card by Qualcomm. Hardwareprovides WiFi and wireless PCIE connectivity, as described in the WiGigWBE spec. Driver supports WiFi only. Card is PCIE device, with PCIe ID1ae9:0310

There are old version of the Qualcomm 60GHz card, with PCIe ID1ae9:0301 it is not supported.

wil6210 device,1ae9:0310, has one 2Mb BAR; it supports MSIinterrupt.

Since 60GHz is emerging technology and hardware is completely new,driver provides lots of features for experimenting, and can be used asresearcher workbench.

Network features#

For the WiFi connection, implemented is 802.11ad spec. Supported arechannels 1..3 with corresponded frequencies 58320, 60480, 62640 MHz.

wil6210 use cfg80211 framework, but not mac80211.

Firmware#

We need to get this publicly available…

Firmware has to be downloaded to the card; card will not work without firmware.

What works#

  • managed mode, aka station. Fully functional. Require up-to-date wpa_supplicant.

  • sniffer. May be configured to captures either only CP (control PHY) or all frames

  • AP mode. Up to 8 simultaneous connected stations supported

  • security. supported is GCMP, it is the only allowed cipher accordingly to the spec.

TODO#

  • P2P and FST flows

  • various offloads

Status#

  • Basic support for 802.11ad merged into kernel 3.6

  • The driver merged into kernel 3.8.

  • Patches for basic 11ad support for hostapd/wpa_supplicant merged.

Sniffer#

To configure wil6210 in sniffer mode (assume $WLAN set to network interface name):

# iw $WLAN set type monitor

Sniffer can capture either only control PHY (CP) or all frames. Note however, data sent at high MCS is hard to acquire by the antennas configured for quasi-omni mode.

To configure for control PHY type do, after configuring for monitor mode:

# iw $WLAN set monitor control

Finally, bring interface up:

# ifconfig $WLAN up

AP mode#

To start AP mode, use recent wpa_supplicant (assume relevant patches already merged). Sample config for non-secure mode:

ap_scan=2network={        frequency=60480        ssid="the_ssid_string"        mode=2        key_mgmt=NONE}

Sample config for secure mode. Note GCMP cipher:

ap_scan=2network={        frequency=60480        ssid="secure_ap"        psk="passphrase"        mode=2        key_mgmt=WPA-PSK        proto=RSN        pairwise=GCMP        group=GCMP}

For developer#

Information below is not necessary for operating driver, it is interesting only for those developing/customizing driver, or experimenting with the 60GHz technology.

Module parameters#

Parameter

Type

Default

Comment

use_msi

bool

true

Use MSI or INTx (pin) interrupt

mtu_max

uint

1986

Maximum supported MTU, [68..7912]

rx_ring_order

uint

10

Rx sing size is1<<order, [5..15]

tx_ring_order

uint

10

Tx sing size is1<<order, [5..15]

bcast_ring_order

uint

7

Broadcast Tx sing size is1<<order, [5..15]

max_assoc_sta

uint

8

Max number of stations associated to the AP, [1..8]

agg_wsize

int

0

Window size for Tx Block Ack after connect; 0 - use default; < 0 - don’t auto-establish. Writeable, new value used when new block ack established

rx_ring_overflow_thrsh

ushort

0

RX ring overflow threshold in descriptors.

no_fw_recovery

bool

false

disable automatic FW error recovery

debug_fw

bool

false

do not perform card reset. For FW debug

rx_align_2

bool

false

align Rx buffers on 4*n+2

rtap_include_phy_info

bool

false

Include PHY info in the radiotap header

wil6210 support of interrupt handling modes:

  • MSI - MSI interrupt. This is the default mode.

  • INTx - legacy pin interrupt. Do not use if possible.

Whendebug_fw set to true, driver probe will not fail if firmware do not report “ready” event. This is to aid firmware boot issues debugging.

WMI commands#

Control communication with the card is done through so called WMI commands and events. Target access to the mailbox within memory in BAR0 used. There are 2 similar mailbox structures: one for host->card commands, and one for card->host events.

Tx/Rx#

DMA using ‘vring’ structures. Vring allocated in consistent memory; hold descriptors that points to the data buffers. Card to write status back to the descriptor.

There is one Rx vring. Tx vrings - multiple, per DA*TID, AP also has broadcast Tx vring.

Firmware error recovery#

Should firmware crash, or in case of scan timeout, driver try to recover from error by resetting card. This works forstation only. In theAP mode, driver will not perform recovery. It will, however, report error to the user space. There are 2 modes of firmware recovery, depending on the driver parameterno_fw_recovery:

  • Automatic

  • whenno_fw_recovery not set (default), driver starts recovery attempt immediately. If firmware keeps crashing, driver will stop after 5 attempts performed within short time.

  • Manual

  • whenno_fw_recovery set (Y or1), driver will report firmware error to the user space and wait for command to continue. To query error state and continue with recovery, userecovery file on the driver’s debugfs: read it

cat /sys/kernel/debug/ieee80211/phy/wil6210/recovery

to query status, it will reads: <code> mode = [auto|manual] state = [idle|pending|running]</code> Ifstate ispending, it is time to collect all crash information as desired, and continue with recovery by writingrun intorecovery:

  • echo-n"run">/sys/kernel/debug/ieee80211/phy/wil6210/recovery

Debug facilities#

Dynamic debug#

Almost all messages printed to the dmesg, are “dynamic debug” ones. See Documentation/dynamic-debug-howto.txt for details. Module “wil6210” uses format prefixes to identify message groups:

* "DBG[ IRQ]" for interrupt related messages. Prints every IRQ.* "DBG[TXRX]" for Tx/Rx path. Prints every Tx/Rx package.* "DBG[ WMI]" for WMI commands subsystem* "DBG[ FW ]" for FW download* "DBG[MISC]" for various un-categorized cases Groups IRQ and TXRX are heavy traffic; enable only when required. Group WMI is relatively low traffic, it prints only WMI messages. It is good idea to enable all but IRQ and TXRX when debugging.* "DBG[ IOC]" for IOCTL

Debugfs#

All debugfs files placed under standard location for the cfg80211 devices, $DEBUGFS/ieee80211/$PHY/ where $PHY is phy name like ‘phy1’.

All wil6210 specific files placed under directory ‘wil6210’. Facilities provided:

  • register access. All ICR (Interrupt Control Registers) groups represented as directories, with entries per register, allowing read/write. ITR (Interrupt Threshold Registers) represented as well.

  • raw memory access. All memory sections represented as ‘blob’ files, providing read only access to the memory on card. Sections include:

+---------------------------------+---------------+| blob_xxx    | BAR0    | Size    | Comment       || file name   | offset  |         |               |+-------------+---------+---------+---------------+| rgf         |     0x0 |  0xa000 | Register file || AGC_tbl     |  0xa000 |  0x1000 | AGC table     || rgf_ext     |  0xb000 |  0x1000 | Ext. rgf      || mac_rgf_ext |  0xc000 |   0x200 | Mac Ext. rgf  || fw_code     | 0x40000 | 0x40000 | FW code       || fw_data     | 0x80000 |  0x8000 | FW data       || fw_peri     | 0x88000 | 0x18000 | FW peripheral || uc_code     | 0xa0000 | 0x10000 | Ucode code    || uc_data     | 0xb0000 |  0x4000 | Ucode data    |+-------------+---------+---------+---------------+

Raw memory access used by firmware/ucode trace extractor. See below. Also, raw memory dump may be obtained for later analysis.

  • DWORD memory read, as FW see it. Files ‘mem_addr’ and ‘mem_val’ provide access to the memory, using FW addresses (FW memory mapping is somewhat different from what host see in BAR0). Write address to the ‘mem_addr’, then read ‘mem_val’. It will reads like “[0x%08x] = 0x%08x\n”, addr, value

  • mailbox for WMI commands events. File ‘mbox’ reads like:

ring tx = {  base = 0x008802e8  size = 0x0028 bytes -> 5 entries  tail = 0x00880300  head = 0x00880300  entry size = 1288  [ 0] E    0x00842490 -> 1fc9 001e 0000 00      : 00 00 07 00 00 00 00 00 ff ff 03 00 00 00 00 00      : 00 00 00 20 04 07 01 88 ff 02 00 00 01 00  [ 1] E    0x00841f88 -> 1fca 001e 0000 00      : 00 00 07 00 00 00 00 00 ff ff 03 00 00 00 00 00      : 00 00 00 20 04 07 01 88 ff 02 00 00 01 00  [ 2] E    0x00841a80 -> 1fcb 001e 0000 00      : 00 00 07 00 00 00 00 00 ff ff 03 00 00 00 00 00      : 00 00 00 20 04 07 01 88 ff 02 00 00 01 00  [ 3] E th 0x00841578 -> 1fc7 001e 0000 00      : 00 00 07 00 00 00 00 00 ff ff 03 00 00 00 00 00      : 00 00 00 20 04 07 01 88 ff 02 00 00 01 00  [ 4] E    0x00841070 -> 1fc8 001e 0000 00      : 00 00 07 00 00 00 00 00 ff ff 03 00 00 00 00 00      : 00 00 00 20 04 07 01 88 ff 02 00 00 01 00}ring rx = {  base = 0x00880318  size = 0x0040 bytes -> 8 entries  tail = 0x00880320  head = 0x00880320  entry size = 256  [ 0] E    0x00842f98 -> 24f8 000c 0000 00      : 00 00 0a 10 00 00 00 00 00 00 00 00  [ 1] E th 0x00000000 -> 2020 0f80 0000 c0  [ 2] E    0x00000000 -> 2020 0f80 0000 c0  [ 3] E    0x00000000 -> 2020 0f80 0000 c0  [ 4] E    0x00000000 -> 2020 0f80 0000 c0  [ 5] E    0x00000000 -> 2020 0f80 0000 c0  [ 6] E    0x00000000 -> 2020 0f80 0000 c0  [ 7] E    0x00000000 -> 2020 0f80 0000 c0}

There are 2 separate rings, one for Tx, or host->card commands; and 2-nd for Rx, or card->host events.

Printed for each ring (all addresses in FW memory mapping):

  • base address of ring in card’s memory

  • ring size in bytes and entries

  • tail and head pointers

  • max. entry size. It is fake for Rx - FW may allocate entry of arbitrary size

  • mailbox entries, format for entry:

<code> /– ‘E’ for empty entry, ‘F’ for full

| /+-- 't' for tail, 'h' for head| ||

index | || address /-mbox header—\ [seq,len,type,flags]

  v  v vv   v           v               v[ 3] E th 0x00841578 -> 1fc7 001e 0000 00    : 00 00 07 00 00 00 00 00 ff ff 03 00 00 00 00 00    : 00 00 00 20 04 07 01 88 ff 02 00 00 01 00      \--buffer content (if valid)------------------/</code>  *                         *               * Tx/Rx DMA Vrings. File 'vrings' reads as:
VRING rx = {  pa     = 0x00000000bb075000  va     = 0xffff8800bb075000  size   = 128  swtail = 127  swhead = 0  hwtail = [0x008813c8] -> 0x0000007fHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHS}

There is one block for Rx DMA vring and one for every Tx DMA vring.

Information printed:

  • addresses, physical (pa) and virtual (va)

  • size, entries

  • software head and tail pointers

  • hardware tail, format: [fw addr] -> value

  • One letter per vring entry, ‘H’ for hardware owned and ‘S’ for software owned ones.

Contributions to wil6210#

You can seestatistics and graphs of contributions to wil6210 here.Contact the wil6210 maintainer if you’d like to help with keeping thisdocument up to date.

Subscribe to this page!#

You should subscribe to this page so you can get e-mail updates onchanges and news for ath9k automatically. You’ll get an e-mail as soonas this page gets updated.