Al 05/12/10 15:38, En/na Luca Olivetti ha escrit:

This router has an ar9223, with the calibration data stored in flash. I
copied the data in ath9k_platform_data (btw, I noticed that ar71xx
redefines it adding fields, should I copy the .h to my platform or is
there a better way to avoid incongruencies?).

The first problem is that the device is (incorrectly?) identified as
168c:ff1d instead of 168c:0029. I saw a similar problem here

https://forum.openwrt.org/viewtopic.php?pid=97839#p97839

with a bug report here

https://dev.openwrt.org/ticket/6171

unfortunately I don't think it applies to my platform (ifxmips), so for
the time being I patched compat-wireless to accept ff1d as a valid id.

I think I have to do something similar to what it's done in
ar71xx/files/arch/mips/ar71xx/pci-ath9k-fixup.c, the big problem I have
is I don't know how to adapt it to the ifxmips/danube, since I don't
know what the various calls to ioremap, pci_write_config_dword,
pci_read_config_dword are supposed to do (I'm not into driver
development):

Well, while waiting for an answer, I tried it.
It almost works but I seem to have an endianness issue, while
pci-ath9-fixup.c did


pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
dev->vendor = val & 0xffff;
dev->device = (val >> 16) & 0xffff;


I had to do

pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
dev->device = swab16(val & 0xffff);
dev->vendor = swab16((val >> 16) & 0xffff);


i.e everything was swapped (device<->vendor and the bytes inside each of
them).

Now I swapped the values written to the registers instead, e.g. instead of

/* set pointer to first reg address */
cal_data += 3;
while (*cal_data != 0xffff) {
u32 reg;
reg = *cal_data++;
val = *cal_data++;
val |= (*cal_data++) << 16;

__raw_writel(val, mem + reg);
udelay(100);
}


I do

/* set pointer to first reg address */
cal_data += 3;
while (*cal_data != 0xffff) {
u32 reg;
reg = *cal_data++;
val = swab16(*cal_data++) << 16;
val |= swab16(*cal_data++);

__raw_writel(val, mem + reg);
udelay(100);
}


Since the endianness of the ar71xx and the danube should be the same,
maybe the key is the layout of the data in caldata.

This is what I have, byte by byte:

A5 5A (magic)
00 00 00 03 (bytes skipped by the above routine)
60 00 16 8C 00 29 (it appears vid:pid, at register 0x6000)
60 08 00 01 02 80
60 2C 16 8C 20 91 (another vid:pid?)
50 00 16 8C 00 2A (yet another?)
50 08 00 01 02 80 (same data as at 0x6008)
50 2C 16 8C 20 91 (same data as at 0x602C)
50 64 0C C0 05 04
50 6C 38 11 00 03
40 04 07 3B 00 40
40 74 00 03 00 00
40 00 00 00 01 C2
60 34 00 44 00 00
FF FF 00 00 00 00 (end of data)


what I end up writing with the above loop is

0x6000 -> 8c162900
0x6008 -> 10008002

etc.

and with that I seem to get the correct vid:pid with

pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
dev->vendor = val & 0xffff;
dev->device = (val >> 16) & 0xffff;

I could really use some help here :-/
Wifi is working but performance is atrocious (10% the throughput of a nearby card), so I'm not sure what I did is correct (even if the calibration data checksums ok).

Bye
--
Luca
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to