Browse Source

[realtek] Force EEPROM CS low before disabling EEPROM access mode

Some RTL8169 cards seem to drive the EEPROM CS line high (i.e. active)
when 9346CR.EEM is set to "normal operating mode", with the result
that the CS line is never deasserted.  The symptom of this is that the
first read from the EEPROM will work, while all subsequent reads will
return garbage data.

Reported-by: Thomas Miletich <thomas.miletich@gmail.com>
Debugged-by: Thomas Miletich <thomas.miletich@gmail.com>
Tested-by: Thomas Miletich <thomas.miletich@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
70618161ad
2 changed files with 32 additions and 3 deletions
  1. 29
    1
      src/drivers/net/realtek.c
  2. 3
    2
      src/drivers/net/realtek.h

+ 29
- 1
src/drivers/net/realtek.c View File

60
 	[SPI_BIT_SCLK]	= RTL_9346CR_EESK,
60
 	[SPI_BIT_SCLK]	= RTL_9346CR_EESK,
61
 	[SPI_BIT_MOSI]	= RTL_9346CR_EEDI,
61
 	[SPI_BIT_MOSI]	= RTL_9346CR_EEDI,
62
 	[SPI_BIT_MISO]	= RTL_9346CR_EEDO,
62
 	[SPI_BIT_MISO]	= RTL_9346CR_EEDO,
63
-	[SPI_BIT_SS(0)]	= ( RTL_9346CR_EECS | RTL_9346CR_EEM1 ),
63
+	[SPI_BIT_SS(0)]	= RTL_9346CR_EECS,
64
 };
64
 };
65
 
65
 
66
+/**
67
+ * Open bit-bashing interface
68
+ *
69
+ * @v basher		Bit-bashing interface
70
+ */
71
+static void realtek_spi_open_bit ( struct bit_basher *basher ) {
72
+	struct realtek_nic *rtl = container_of ( basher, struct realtek_nic,
73
+						 spibit.basher );
74
+
75
+	/* Enable EEPROM access */
76
+	writeb ( RTL_9346CR_EEM_EEPROM, rtl->regs + RTL_9346CR );
77
+}
78
+
79
+/**
80
+ * Close bit-bashing interface
81
+ *
82
+ * @v basher		Bit-bashing interface
83
+ */
84
+static void realtek_spi_close_bit ( struct bit_basher *basher ) {
85
+	struct realtek_nic *rtl = container_of ( basher, struct realtek_nic,
86
+						 spibit.basher );
87
+
88
+	/* Disable EEPROM access */
89
+	writeb ( RTL_9346CR_EEM_NORMAL, rtl->regs + RTL_9346CR );
90
+}
91
+
66
 /**
92
 /**
67
  * Read input bit
93
  * Read input bit
68
  *
94
  *
108
 
134
 
109
 /** SPI bit-bashing interface */
135
 /** SPI bit-bashing interface */
110
 static struct bit_basher_operations realtek_basher_ops = {
136
 static struct bit_basher_operations realtek_basher_ops = {
137
+	.open = realtek_spi_open_bit,
138
+	.close = realtek_spi_close_bit,
111
 	.read = realtek_spi_read_bit,
139
 	.read = realtek_spi_read_bit,
112
 	.write = realtek_spi_write_bit,
140
 	.write = realtek_spi_write_bit,
113
 };
141
 };

+ 3
- 2
src/drivers/net/realtek.h View File

158
 
158
 
159
 /** 93C46 (93C56) Command Register (byte) */
159
 /** 93C46 (93C56) Command Register (byte) */
160
 #define RTL_9346CR 0x50
160
 #define RTL_9346CR 0x50
161
-#define RTL_9346CR_EEM1		0x80	/**< Mode select bit 1 */
162
-#define RTL_9346CR_EEM0		0x40	/**< Mode select bit 0 */
161
+#define RTL_9346CR_EEM(x)	( (x) << 6 ) /**< Mode select */
162
+#define RTL_9346CR_EEM_EEPROM	RTL_9346CR_EEM ( 0x2 ) /**< EEPROM mode */
163
+#define RTL_9346CR_EEM_NORMAL	RTL_9346CR_EEM ( 0x0 ) /**< Normal mode */
163
 #define RTL_9346CR_EECS		0x08	/**< Chip select */
164
 #define RTL_9346CR_EECS		0x08	/**< Chip select */
164
 #define RTL_9346CR_EESK		0x04	/**< Clock */
165
 #define RTL_9346CR_EESK		0x04	/**< Clock */
165
 #define RTL_9346CR_EEDI		0x02	/**< Data in */
166
 #define RTL_9346CR_EEDI		0x02	/**< Data in */

Loading…
Cancel
Save