HOWTO get Madwifi Register Traces
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:
- http://kernel.org/pub/linux/kernel/people/mcgrof/madwifi-regdumps/README
- ticket #1380
- http://nouveau.freedesktop.org/wiki/MmioTrace
Building the madwifi modules for tracing
There is a branch of madwifi which is already prepared for tracing. Get it:
svn co http://svn.madwifi.org/madwifi/branches/madwifi-trace
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 (mad-trace.sh) so you should have it somewhere on your systems $PATH.
svn co http://svn.madwifi.org/ath_info/trunk ath_info cd ath_info/ make
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/mad-trace.sh 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:
./mad-trace.sh 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 ath0 '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 ath-reg-decode.pl 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 mad-trace.sh 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 ath-reg-decode.pl 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
./ath-reg-decode.pl 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:
./ath-reg-decode.pl --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:
./ath-reg-decode.pl [-out initval] -b tmp/*.log
Just lookup one single register name:
./ath-reg-decode.pl -l 0x4000 0x4000: AR5K_RESET_CTL Reset control register
To dump all known registers in different formats use
./ath-reg-decode.pl -d
0x0000 AR5K_NOQCU_TXDP0 [5210] Queue 0 - data
...
./ath-reg-decode.pl -d -o wiki
|| 0x0000 || AR5K_NOQCU_TXDP0 || 5210 || Queue 0 - data ||
...
./ath-reg-decode.pl -d -o case
case 0x0000: return "AR5K_NOQCU_TXDP0"; break;
...
./ath-reg-decode.pl -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!)
./ath-reg-decode.pl -c 5210 ...
To cross reference registers and the values that are read and written to it you can use the --cross option, e.g.:
./ath-reg-decode.pl --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, )
