瀏覽代碼

[smsc95xx] Add driver for SMSC/Microchip LAN95xx USB Ethernet NICs

Tested using QEMU and usbredir to expose the LAN9512 chip present on a
Raspberry Pi.

There is a known issue with the LAN9512: an extra two bytes are
appended to every transmitted packet.  These two bytes comprise:

  {   0x00,   0x08 } if packet length == 0 (mod 8)
  { CRC[0],   0x00 } if packet length == 7 (mod 8)
  { CRC[0], CRC[1] } otherwise

The extra bytes are appended whether the Ethernet CRC is generated
manually or added automatically by the hardware.  The issue occurs
with the Linux kernel driver as well as the iPXE driver.  It appears
to be an undocumented hardware errata.

TCP/IP traffic is not affected, since the IP header length field
causes the extraneous bytes to be discarded by the receiver.  However,
protocols that rely on the length of the Ethernet frame (such as FCoE
or iPXE's "lotest" protocol) will be unusable on this hardware.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 8 年之前
父節點
當前提交
89c767bfd6
共有 3 個檔案被更改,包括 1382 行新增0 行删除
  1. 1127
    0
      src/drivers/net/smsc95xx.c
  2. 254
    0
      src/drivers/net/smsc95xx.h
  3. 1
    0
      src/include/ipxe/errfile.h

+ 1127
- 0
src/drivers/net/smsc95xx.c
文件差異過大導致無法顯示
查看文件


+ 254
- 0
src/drivers/net/smsc95xx.h 查看文件

@@ -0,0 +1,254 @@
1
+#ifndef _SMSC95XX_H
2
+#define _SMSC95XX_H
3
+
4
+/** @file
5
+ *
6
+ * SMSC LAN95xx USB Ethernet driver
7
+ *
8
+ */
9
+
10
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11
+
12
+#include <ipxe/usb.h>
13
+#include <ipxe/usbnet.h>
14
+#include <ipxe/if_ether.h>
15
+#include <ipxe/mii.h>
16
+
17
+/** Register write command */
18
+#define SMSC95XX_REGISTER_WRITE					\
19
+	( USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE |	\
20
+	  USB_REQUEST_TYPE ( 0xa0 ) )
21
+
22
+/** Register read command */
23
+#define SMSC95XX_REGISTER_READ					\
24
+	( USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE |	\
25
+	  USB_REQUEST_TYPE ( 0xa1 ) )
26
+
27
+/** Get statistics command */
28
+#define SMSC95XX_GET_STATISTICS					\
29
+	( USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE |	\
30
+	  USB_REQUEST_TYPE ( 0xa2 ) )
31
+
32
+/** Interrupt status register */
33
+#define SMSC95XX_INT_STS 0x008
34
+#define SMSC95XX_INT_STS_RXDF_INT	0x00000800UL	/**< RX FIFO overflow */
35
+#define SMSC95XX_INT_STS_PHY_INT	0x00008000UL	/**< PHY interrupt */
36
+
37
+/** Transmit configuration register */
38
+#define SMSC95XX_TX_CFG 0x010
39
+#define SMSC95XX_TX_CFG_ON		0x00000004UL	/**< TX enable */
40
+
41
+/** Hardware configuration register */
42
+#define SMSC95XX_HW_CFG 0x014
43
+#define SMSC95XX_HW_CFG_BIR		0x00001000UL	/**< Bulk IN use NAK */
44
+#define SMSC95XX_HW_CFG_LRST		0x00000008UL	/**< Soft lite reset */
45
+
46
+/** EEPROM command register */
47
+#define SMSC95XX_E2P_CMD 0x030
48
+#define SMSC95XX_E2P_CMD_EPC_BSY	0x80000000UL	/**< EPC busy */
49
+#define SMSC95XX_E2P_CMD_EPC_CMD_READ	0x00000000UL	/**< READ command */
50
+#define SMSC95XX_E2P_CMD_EPC_ADDR(addr) ( (addr) << 0 )	/**< EPC address */
51
+
52
+/** EEPROM data register */
53
+#define SMSC95XX_E2P_DATA 0x034
54
+#define SMSC95XX_E2P_DATA_GET(e2p_data) \
55
+	( ( (e2p_data) >> 0 ) & 0xff )			/**< EEPROM data */
56
+
57
+/** MAC address EEPROM address */
58
+#define SMSC95XX_EEPROM_MAC 0x01
59
+
60
+/** Interrupt endpoint control register */
61
+#define SMSC95XX_INT_EP_CTL 0x068
62
+#define SMSC95XX_INT_EP_CTL_RXDF_EN	0x00000800UL	/**< RX FIFO overflow */
63
+#define SMSC95XX_INT_EP_CTL_PHY_EN	0x00008000UL	/**< PHY interrupt */
64
+
65
+/** Bulk IN delay register */
66
+#define SMSC95XX_BULK_IN_DLY 0x06c
67
+#define SMSC95XX_BULK_IN_DLY_SET(ticks)	( (ticks) << 0 ) /**< Delay / 16.7ns */
68
+
69
+/** MAC control register */
70
+#define SMSC95XX_MAC_CR 0x100
71
+#define SMSC95XX_MAC_CR_RXALL		0x80000000UL	/**< Receive all */
72
+#define SMSC95XX_MAC_CR_FDPX		0x00100000UL	/**< Full duplex */
73
+#define SMSC95XX_MAC_CR_MCPAS		0x00080000UL	/**< All multicast */
74
+#define SMSC95XX_MAC_CR_PRMS		0x00040000UL	/**< Promiscuous */
75
+#define SMSC95XX_MAC_CR_PASSBAD		0x00010000UL	/**< Pass bad frames */
76
+#define SMSC95XX_MAC_CR_TXEN		0x00000008UL	/**< TX enabled */
77
+#define SMSC95XX_MAC_CR_RXEN		0x00000004UL	/**< RX enabled */
78
+
79
+/** MAC address high register */
80
+#define SMSC95XX_ADDRH 0x104
81
+
82
+/** MAC address low register */
83
+#define SMSC95XX_ADDRL 0x108
84
+
85
+/** MII access register */
86
+#define SMSC95XX_MII_ACCESS 0x114
87
+#define SMSC95XX_MII_ACCESS_PHY_ADDRESS	0x00000800UL	/**< PHY address */
88
+#define SMSC95XX_MII_ACCESS_MIIRINDA(addr) ( (addr) << 6 ) /**< MII register */
89
+#define SMSC95XX_MII_ACCESS_MIIWNR	0x00000002UL	/**< MII write */
90
+#define SMSC95XX_MII_ACCESS_MIIBZY	0x00000001UL	/**< MII busy */
91
+
92
+/** MII data register */
93
+#define SMSC95XX_MII_DATA 0x118
94
+#define SMSC95XX_MII_DATA_SET(data)	( (data) << 0 )	/**< Set data */
95
+#define SMSC95XX_MII_DATA_GET(mii_data) \
96
+	( ( (mii_data) >> 0 ) & 0xffff )		/**< Get data */
97
+
98
+/** PHY interrupt source MII register */
99
+#define SMSC95XX_MII_PHY_INTR_SOURCE 29
100
+
101
+/** PHY interrupt mask MII register */
102
+#define SMSC95XX_MII_PHY_INTR_MASK 30
103
+
104
+/** PHY interrupt: auto-negotiation complete */
105
+#define SMSC95XX_PHY_INTR_ANEG_DONE	0x0040
106
+
107
+/** PHY interrupt: link down */
108
+#define SMSC95XX_PHY_INTR_LINK_DOWN	0x0010
109
+
110
+/** MAC address */
111
+union smsc95xx_mac {
112
+	/** MAC receive address registers */
113
+	struct {
114
+		/** MAC receive address low register */
115
+		uint32_t l;
116
+		/** MAC receive address high register */
117
+		uint32_t h;
118
+	} __attribute__ (( packed )) addr;
119
+	/** Raw MAC address */
120
+	uint8_t raw[ETH_ALEN];
121
+};
122
+
123
+/** Receive packet header */
124
+struct smsc95xx_rx_header {
125
+	/** Command word */
126
+	uint32_t command;
127
+} __attribute__ (( packed ));
128
+
129
+/** Runt frame */
130
+#define SMSC95XX_RX_RUNT 0x00004000UL
131
+
132
+/** Late collision */
133
+#define SMSC95XX_RX_LATE 0x00000040UL
134
+
135
+/** CRC error */
136
+#define SMSC95XX_RX_CRC 0x00000002UL
137
+
138
+/** Transmit packet header */
139
+struct smsc95xx_tx_header {
140
+	/** Command word */
141
+	uint32_t command;
142
+	/** Frame length */
143
+	uint32_t len;
144
+} __attribute__ (( packed ));
145
+
146
+/** First segment */
147
+#define SMSC95XX_TX_FIRST 0x00002000UL
148
+
149
+/** Last segment */
150
+#define SMSC95XX_TX_LAST 0x00001000UL
151
+
152
+/** Buffer size */
153
+#define SMSC95XX_TX_LEN(len) ( (len) << 0 )
154
+
155
+/** Interrupt packet format */
156
+struct smsc95xx_interrupt {
157
+	/** Current value of INT_STS register */
158
+	uint32_t int_sts;
159
+} __attribute__ (( packed ));
160
+
161
+/** Receive statistics */
162
+struct smsc95xx_rx_statistics {
163
+	/** Good frames */
164
+	uint32_t good;
165
+	/** CRC errors */
166
+	uint32_t crc;
167
+	/** Runt frame errors */
168
+	uint32_t undersize;
169
+	/** Alignment errors */
170
+	uint32_t alignment;
171
+	/** Frame too long errors */
172
+	uint32_t oversize;
173
+	/** Later collision errors */
174
+	uint32_t late;
175
+	/** Bad frames */
176
+	uint32_t bad;
177
+	/** Dropped frames */
178
+	uint32_t dropped;
179
+} __attribute__ (( packed ));
180
+
181
+/** Receive statistics */
182
+#define SMSC95XX_RX_STATISTICS 0
183
+
184
+/** Transmit statistics */
185
+struct smsc95xx_tx_statistics {
186
+	/** Good frames */
187
+	uint32_t good;
188
+	/** Pause frames */
189
+	uint32_t pause;
190
+	/** Single collisions */
191
+	uint32_t single;
192
+	/** Multiple collisions */
193
+	uint32_t multiple;
194
+	/** Excessive collisions */
195
+	uint32_t excessive;
196
+	/** Late collisions */
197
+	uint32_t late;
198
+	/** Buffer underruns */
199
+	uint32_t underrun;
200
+	/** Excessive deferrals */
201
+	uint32_t deferred;
202
+	/** Carrier errors */
203
+	uint32_t carrier;
204
+	/** Bad frames */
205
+	uint32_t bad;
206
+} __attribute__ (( packed ));
207
+
208
+/** Transmit statistics */
209
+#define SMSC95XX_TX_STATISTICS 1
210
+
211
+/** A SMSC95xx network device */
212
+struct smsc95xx_device {
213
+	/** USB device */
214
+	struct usb_device *usb;
215
+	/** USB bus */
216
+	struct usb_bus *bus;
217
+	/** Network device */
218
+	struct net_device *netdev;
219
+	/** USB network device */
220
+	struct usbnet_device usbnet;
221
+	/** MII interface */
222
+	struct mii_interface mii;
223
+	/** Interrupt status */
224
+	uint32_t int_sts;
225
+};
226
+
227
+/** Reset delay (in microseconds) */
228
+#define SMSC95XX_RESET_DELAY_US 2
229
+
230
+/** Maximum time to wait for EEPROM (in milliseconds) */
231
+#define SMSC95XX_EEPROM_MAX_WAIT_MS 100
232
+
233
+/** Maximum time to wait for MII (in milliseconds) */
234
+#define SMSC95XX_MII_MAX_WAIT_MS 100
235
+
236
+/** Interrupt maximum fill level
237
+ *
238
+ * This is a policy decision.
239
+ */
240
+#define SMSC95XX_INTR_MAX_FILL 2
241
+
242
+/** Bulk IN maximum fill level
243
+ *
244
+ * This is a policy decision.
245
+ */
246
+#define SMSC95XX_IN_MAX_FILL 8
247
+
248
+/** Bulk IN buffer size */
249
+#define SMSC95XX_IN_MTU						\
250
+	( sizeof ( struct smsc95xx_rx_header ) +		\
251
+	  ETH_FRAME_LEN + 4 /* possible VLAN header */		\
252
+	  + 4 /* CRC */ )
253
+
254
+#endif /* _SMSC95XX_H */

+ 1
- 0
src/include/ipxe/errfile.h 查看文件

@@ -183,6 +183,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
183 183
 #define ERRFILE_smsc75xx	     ( ERRFILE_DRIVER | 0x00770000 )
184 184
 #define ERRFILE_intelvf		     ( ERRFILE_DRIVER | 0x00780000 )
185 185
 #define ERRFILE_intelxvf	     ( ERRFILE_DRIVER | 0x00790000 )
186
+#define ERRFILE_smsc95xx	     ( ERRFILE_DRIVER | 0x007a0000 )
186 187
 
187 188
 #define ERRFILE_aoe			( ERRFILE_NET | 0x00000000 )
188 189
 #define ERRFILE_arp			( ERRFILE_NET | 0x00010000 )

Loading…
取消
儲存