linux/drivers/net/wireless
Johannes Berg af6b8ee388 iwlwifi: fix EEPROM/OTP reading endian annotations and a bug
The construct "le16_to_cpu((__force __le16)(r >> 16))" has
always bothered me when looking through the iwlwifi code,
it shouldn't be necessary to __force anything, and before
this code, "r" was obtained with an ioread32, which swaps
each of the two u16 values in it properly when swapping the
entire u32 value. I've had arguments about this code with
people before, but always conceded they were right because
removing it only made things not work at all on big endian
platforms.

However, analysing a failure of the OTP reading code, I now
finally figured out what is going on, and why my intuition
about that code being wrong was right all along.

It turns out that the 'priv->eeprom' u8 array really wants
to have the data in it in little endian. So the force code
above and all really converts *to* little endian, not from
it. Cf., for instance, the function iwl_eeprom_query16() --
it reads two u8 values and combines them into a u16, in a
little-endian way. And considering it more, it makes sense
to have the eeprom array as on the device, after all not
all values really are 16-bit values, the MAC address for
instance is not.

Now, what this really means is that all the annotations are
completely wrong. The eeprom reading code should fill the
priv->eeprom array as a __le16 array, with __le16 values.

This also means that iwl_read_otp_word() should really have
a __le16 pointer as the data argument, since it should be
filling that in a format suitable for priv->eeprom.

Propagating these changes throughout, iwl_find_otp_image()
is found to be, now obviously visible, defective -- it uses
the data returned by iwl_read_otp_word() directly as if it
was CPU endianness. Fixing that, which is this hunk of the
patch:

-               next_link_addr = link_value * sizeof(u16);
+               next_link_addr = le16_to_cpu(link_value) * sizeof(u16);

is the only real change of this patch. Everything else is
just fixing the sparse annotations.

Also, the bug only shows up on big endian platforms with a
1000 series card. 5000 and previous series do not use OTP,
and 6000 series has shadow RAM support which means we don't
ever use the defective code on any cards but 1000.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Cc: stable@kernel.org
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
2009-12-21 11:32:05 -05:00
..
ath ath9k: Last fix for TX software padding. 2009-12-21 11:32:00 -05:00
b43 b43: Remove reset after fatal DMA error 2009-12-10 16:09:51 -05:00
b43legacy b43legacy: avoid PPC fault during resume 2009-12-04 13:28:50 -05:00
hostap Merge branch 'master' of /home/davem/src/GIT/linux-2.6/ 2009-12-05 15:22:26 -08:00
ipw2x00 ipw2100: fix rebooting hang with driver loaded 2009-12-04 14:16:25 -05:00
iwlwifi iwlwifi: fix EEPROM/OTP reading endian annotations and a bug 2009-12-21 11:32:05 -05:00
iwmc3200wifi iwmc3200wifi: Enable wimax core through module parameter 2009-12-04 14:16:29 -05:00
libertas Merge branch 'master' of /home/davem/src/GIT/linux-2.6/ 2009-12-05 15:22:26 -08:00
libertas_tf libertas_tf_usb: declare MODULE_FIRMWARE 2009-11-11 15:23:53 -05:00
orinoco orinoco: remove spare KERN_DEBUG 2009-12-07 16:55:00 -05:00
p54 cfg80211: convert bools into flags 2009-11-19 11:08:50 -05:00
prism54 drivers/net: request_irq - Remove unnecessary leading & from second arg 2009-11-18 23:29:17 -08:00
rt2x00 rt2x00: Disable powersaving for rt61pci and rt2800pci. 2009-12-21 11:32:04 -05:00
rtl818x rtl8187: add radio led and fix warnings on suspend 2009-12-10 16:09:51 -05:00
wl12xx wl1251: don't build null data template in wl1251_op_config() 2009-12-07 16:50:13 -05:00
zd1211rw zd1211rw: declare MODULE_FIRMWARE 2009-11-11 15:23:55 -05:00
adm8211.c drivers/net/adm8211.c: remove exceptional & on function name 2009-11-18 10:48:52 -08:00
adm8211.h mac80211: fix ADM8211_SYNCTL_RFtype define 2009-10-07 16:33:51 -04:00
airo_cs.c pcmcia: rework the irq_req_t typedef 2009-11-28 18:03:14 +01:00
airo.c airo: Fix integer overflow warning 2009-12-04 13:30:40 -05:00
airo.h
at76c50x-usb.c at76c50x-usb: Supply additional parameters to at76_start_monitor scan request 2009-11-11 17:09:17 -05:00
at76c50x-usb.h
atmel_cs.c pcmcia: rework the irq_req_t typedef 2009-11-28 18:03:14 +01:00
atmel_pci.c
atmel.c atmel: declare MODULE_FIRMWARE 2009-11-11 15:23:49 -05:00
atmel.h
Kconfig wireless: airo_cs needs WEXT_SPY 2009-10-30 16:50:38 -04:00
mac80211_hwsim.c cfg80211: convert bools into flags 2009-11-19 11:08:50 -05:00
Makefile netwave: move driver to staging 2009-10-30 16:50:34 -04:00
mwl8k.c mwl8k: don't complain about oversized beacons in FINALIZE_JOIN 2009-12-07 16:51:23 -05:00
ray_cs.c Merge branch 'master' of /home/davem/src/GIT/linux-2.6/ 2009-12-05 15:22:26 -08:00
ray_cs.h
rayctl.h
rndis_wlan.c rndis_wlan: disable stall workaround 2009-11-23 17:05:40 -05:00
wl3501_cs.c Merge branch 'master' of /home/davem/src/GIT/linux-2.6/ 2009-12-05 15:22:26 -08:00
wl3501.h
zd1201.c zd1201: declare MODULE_FIRMWARE 2009-11-11 15:23:54 -05:00
zd1201.h