Please note: This project is no longer active. The website is kept online for historic purposes only.
If you´re looking for a Linux driver for your Atheros WLAN device, you should continue here .

HOWTO get Madwifi Register Traces

Note: the branch that is referred to on this page has been removed, since register tracing is now supported "out of the box" in recent Linux kernels. This page is only left for historic purposes.

In order to add support for new hardware to ath5k we need to trace the madwifi HAL register accesses to figure out what is going on.

You can help development of ath5k by submitting trace dumps and (even better) by trying to figure out the missing DevDocs/AtherosRegisters.

This information here is based on:

Building the madwifi modules for tracing

There is a branch of madwifi which is already prepared for tracing. Get it:

svn co

Enter that directory, build the modules and install them as usual.

Building ath_info

In order to classify the register traces we need to know exactly which chipsets are on the card. We get this information with the tool ath_info and it is also used by the script below ( so you should have it somewhere on your systems $PATH.

svn co ath_info
cd ath_info/

You have to tell ath_info the memory address it should operate on. This is the memory address shown by lspci -v. Or just use the following script fragment:

athmem=`lspci -vd 168c: |sed -n 's/.*Memory at \([^ ]*\).*/0x\1/p'`
ath_info $athmem

More about ath_info: UserDocs/AthInfo.

Using the automated trace script

scripts/tools/ automates the task of tracing different useful commands. It also dumps the contents of the eeprom and creates a neat tar.gz file containing all the gathered information. Running it takes a while and gives output like this:

running ath_info -d 0xd0200000...
'modprobe ath_pci autocreate=none' -> sta-mode1-1-modprobe.log
'wlanconfig ath0 create wlandev wifi0 wlanmode sta' -> sta-mode1-2-wlanconfig.log
'iwpriv ath0 mode 1' -> sta-mode1-3-set-mode.log
'ifconfig ath0 up' -> sta-mode1-4-ifup.log
'iwconfig ath0 channel 36' -> sta-mode1-5-chan36.log
'iwconfig ath0 channel 40' -> sta-mode1-6-chan40.log
'iwconfig ath0 channel 44' -> sta-mode1-7-chan44.log
'iwconfig ath0 channel 48' -> sta-mode1-8-chan48.log
'ifconfig ath0 down' -> sta-mode1-9-ifdown.log

When it is finished, you have all log files and dumps in /tmp/mad-trace/ and an archive containing all those files like 5213-mad-trace.tgz, which you can use to submit that information to other developers.

Manual tracing

Of course you can also trace different things manually. Please refer to the README for more details.

1.) load the HAL and enable tracing

modprobe ath_hal
echo 2 > /proc/sys/dev/ath/hal/debug
echo 1 > /proc/sys/dev/ath/hal/alq

2.) load ath_pci and do something with it, e.g.:

modprobe ath_pci
ifconfig ath0 up
iwconfig ath0 channel 1

3.) disable tracing when you're done (you don't want to collect too much information!)

echo 0 > /proc/sys/dev/ath/hal/alq

4.) you can always enable and disable tracing between the steps you're interrested in and the ones you are not by echoing into /proc/sys/dev/ath/hal/alq (but be careful, it's very easy to miss the important parts).

echo 1 > /proc/sys/dev/ath/hal/alq # enable tracing
echo 0 > /proc/sys/dev/ath/hal/alq # disable tracing

5.) you will find the log file in /tmp/ath_hal.log. it's a good idea to filter it thru to get rid of the nasty \0 characters in there.

sed 's/\x00//g' ath_hal.log > ath_hal.txt

That's not strictly necessary if you are going to use the script mentioned in the next section, which will also replace the \0 characters.

Setting up a testbed

The things done in the mad-trace script do not capture everything. To get the full picture what happens, it's necessary to set up a test-bed and actually get a connection to an AP (or ad-hoc node). Associating with the AP should be enough, though, because this means packets have been sent and received. This can be done following this procedure:

a) enable loging/debug
b) modprobe ath_pci
c) save log as <rev>-attach.log
d) disable loging/empty log/reenable loging
e) iwpriv ath0 mode <mode> <- this should result a call to resettxqueue
f) save log as <rev>-iwpriv-mode-<mode>.log
g) disable loging/empty log/reenable loging
h) iwconfig ath0 essid <essid> channel <channel> <- this doesn't result any data on the log
i) ifconfig ath0 up
j) wait to connect
k) disable loging/save log as <rev>-ifup-connected-chan<channel>.log

You can use the script for an automated testbed tracing. just give the mode (a, b, g, aturbo, gturbo) as the first argument. Be sure to setup the AP before you do that. The script assumes

* b mode: essid bbb channel 10
* g mode: essid ggg channel 10
* a mode: essid aaa channel 60
* gturbo mode: essid gturbo channel 6
* aturbo mode: essid aturbo channel 42

After that only get the last reset circle (the one before connection -you shouldn't see another reset after that) from ath_hal_reset to the last call to ath_hal_beacontimers (then only rx_monitor/gettsf etc are called).

Reading the log files

The trace log files contain all register access of the driver, which is a lot of information like this, e.g.:

W:0x04004 = 0x00000000 - ath_hal_reset

It means: in the function 'ath_hal_reset" there was a write of 0x00000000 to the address 0x04004.

Great! So what does that mean?

The script in the scripts/trace directory can help interpreting this output. It downloads a list of known register names from this wiki (DevDocs/AtherosRegisters) and pretty prints the output in serveral different formats.

If you run it on the log containing the above line it will output

./ test.log
W: 0x4004 = 0x00000000 - AR5K_SLEEP_CTL                 .... .... .... .... .... .... .... ....  (ath_hal_reset)

or another example:

W: 0x9938 = 0x1a1c2020 - AR5K_PHY_TXPOWER_RATE2         ...1 1.1. ...1 11.. ..1. .... ..1. ....  (ath_hal_settxpowlimit)

Now we know the name of the define that is used in ath5k to access this register and have the state of all the bits that were written.

If we want to use that info to prepare them as initvals in the ath5k/initval.c you can use a more convenient output format:

./ --out initval test.log
     { AR5K_RF_GAIN(0),                    0x00000000 },     /* ath_hal_reset */
     { AR5K_RF_GAIN(1),                    0x00000040 },     /* ath_hal_reset */

To batch process a series of log files:

./ [-out initval] -b tmp/*.log

Just lookup one single register name:

./ -l 0x4000
0x4000: AR5K_RESET_CTL  Reset control register

To dump all known registers in different formats use

./ -d
0x0000          AR5K_NOQCU_TXDP0                [5210]  Queue 0 - data

./ -d -o wiki
|| 0x0000        || AR5K_NOQCU_TXDP0               || 5210   || Queue 0 - data ||

./ -d -o case
        case 0x0000: return "AR5K_NOQCU_TXDP0"; break;

./ -d -o define
#define AR5K_NOQCU_TXDP0                0x0000  /* [5210] Queue 0 - data */

For now the script assumes a 5212 chip for the register lookups, if you want to use something different specify -c, e.g.: (someone please check if the lookup order in my %chip_lookup is right!)

./ -c 5210 ...

To cross reference registers and the values that are read and written to it you can use the --cross option, e.g.:

./ --cross --batch 5213/raw/sta-mode1-6-chan60.log 5414/raw/sta-mode1-5-chan36.log | less

0x8008 AR5K_BSS_ID0 (First BSSID register (MAC address, lower 32bits))
        0x00000000 [................................]
                W ath_hal_setassocid
                        5213/raw/sta-mode1-6-chan60.log (lines 14, 76, )
                        5414/raw/sta-mode1-5-chan36.log (lines 8, 22, 1474, )
        0xffffffff [11111111111111111111111111111111]
                W ath_hal_setassocid
                        5414/raw/sta-mode1-5-chan36.log (lines 30, 1482, )