Skip to contentSkip to conversation

b44: fix eeprom endianess issue

PATCH In review Michael Buesch 2 participants 4 messages Aug 23, 2006

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 b44: fix eeprom endianess issue

Hi Andrew,

Please apply this patch to -mm for testing.
I think in the long term we want to convert b44 to use the new ssb backend driver, which would also fix the issue, but for now I think this small fix is best.

Please note that this test is only compile tested, as I don't have a b44 device.

--

This fixes eeprom read on big-endian architectures.

drivers/net/b44.c +1 -1
Index: linux-2.6/drivers/net/b44.c
===================================================================
@@ -2055,7 +2055,7 @@
 	u16 *ptr = (u16 *) data;
 
 	for (i = 0; i < 128; i += 2)
-		ptr[i / 2] = readw(bp->regs + 4096 + i);
+		ptr[i / 2] = cpu_to_le16(readw(bp->regs + 4096 + i));
 
 	return 0;
 }
Signature · 1 line
Greetings Michael.
#1 lore raw

Oh, I think I should have CCed Jeff ;)
Sorry.

Quoted 31 lines · Michael Buesch

Hi Andrew,

Please apply this patch to -mm for testing.
I think in the long term we want to convert b44 to use the new ssb backend driver, which would also fix the issue, but for now I think this small fix is best.

Please note that this test is only compile tested, as I don't have a b44 device.

--

This fixes eeprom read on big-endian architectures.

Index: linux-2.6/drivers/net/b44.c
===================================================================

drivers/net/b44.c +1 -1
@@ -2055,7 +2055,7 @@
 	u16 *ptr = (u16 *) data;
 
 	for (i = 0; i < 128; i += 2)
-		ptr[i / 2] = readw(bp->regs + 4096 + i);
+		ptr[i / 2] = cpu_to_le16(readw(bp->regs + 4096 + i));
 
 	return 0;
 }
Signature · 1 line
Greetings Michael.
#2 lore raw
Quoted 10 lines · Michael Buesch

drivers/net/b44.c line 2059

Quoted 10 lines

Please note that this test is only compile tested, as I don't have a b44 device.

drivers/net/b44.c +1 -1
@@ -2055,7 +2055,7 @@
 	u16 *ptr = (u16 *) data;
 
 	for (i = 0; i < 128; i += 2)
-		ptr[i / 2] = readw(bp->regs + 4096 + i);
+		ptr[i / 2] = cpu_to_le16(readw(bp->regs + 4096 + i));
 

This looks a bit weird. readw() swaps on big-endian already.

This patch swaps each word -again- on big-endian, even though the only user of the eeprom data is the get-invariants code that reads the MAC address and phy id.

Jeff

#3 lore raw
Quoted 15 lines · Jeff Garzik
Quoted 10 lines · Michael Buesch

drivers/net/b44.c line 2059

Quoted 10 lines

Please note that this test is only compile tested, as I don't have a b44 device.

drivers/net/b44.c +1 -1
@@ -2055,7 +2055,7 @@
 	u16 *ptr = (u16 *) data;
 
 	for (i = 0; i < 128; i += 2)
-		ptr[i / 2] = readw(bp->regs + 4096 + i);
+		ptr[i / 2] = cpu_to_le16(readw(bp->regs + 4096 + i));
 

This looks a bit weird. readw() swaps on big-endian already.

Quoted 3 lines

This patch swaps each word -again- on big-endian, even though the only user of the eeprom data is the get-invariants code that reads the MAC address and phy id.

Yeah. But look at where the data is stored.
The data ends up in a _byte_ array. A byte array is litte endian (little end first). array[0] is low and array[1] is high. Look at the pointer cast above:

u16 *ptr = (u16 *) data;

We store data in _cpu_ order in this byte array. That's wrong.
If we are on a little endian machine, that's ok. But if we are on a big endian machine, this will write bytes swapped.

LE will result in an array:
ABABABABABABAB
BE will result in an array:
BABABABABABABA

But only the first result (LE) is valid, because that's expected later when interpreting the data.

Signature · 1 line
Greetings Michael.