Browse Source

[smsc75xx] Add driver for SMSC/Microchip LAN75xx USB Ethernet NICs

This driver is functional but any downloads via a TCP-based protocol
tend to perform poorly.  The 1Gbps Ethernet line rate is substantially
higher than the 480Mbps (in practice around 280Mbps) provided by USB2,
and the device has only 32kB of internal buffer memory.  Our 256kB TCP
receive window therefore rapidly overflows the RX FIFO, leading to
multiple dropped packets (usually within the same TCP window) and
hence a low overall throughput.

Reducing the TCP window size so that the RX FIFO does not overflow
greatly increases throughput, but is not a general-purpose solution.

Further investigation is required to determine how other OSes
(e.g. Linux) cope with this scenario.  It is possible that
implementing TCP SACK would provide some benefit.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
69062bbc21
3 changed files with 1366 additions and 0 deletions
  1. 1056
    0
      src/drivers/net/smsc75xx.c
  2. 309
    0
      src/drivers/net/smsc75xx.h
  3. 1
    0
      src/include/ipxe/errfile.h

+ 1056
- 0
src/drivers/net/smsc75xx.c
File diff suppressed because it is too large
View File


+ 309
- 0
src/drivers/net/smsc75xx.h View File

@@ -0,0 +1,309 @@
1
+#ifndef _SMSC75XX_H
2
+#define _SMSC75XX_H
3
+
4
+/** @file
5
+ *
6
+ * SMSC LAN75xx 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 SMSC75XX_REGISTER_WRITE					\
19
+	( USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE |	\
20
+	  USB_REQUEST_TYPE ( 0xa0 ) )
21
+
22
+/** Register read command */
23
+#define SMSC75XX_REGISTER_READ					\
24
+	( USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE |	\
25
+	  USB_REQUEST_TYPE ( 0xa1 ) )
26
+
27
+/** Get statistics command */
28
+#define SMSC75XX_GET_STATISTICS					\
29
+	( USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE |	\
30
+	  USB_REQUEST_TYPE ( 0xa2 ) )
31
+
32
+/** Interrupt status register */
33
+#define SMSC75XX_INT_STS 0x00c
34
+#define SMSC75XX_INT_STS_RDFO_INT	0x00400000UL	/**< RX FIFO overflow */
35
+#define SMSC75XX_INT_STS_PHY_INT	0x00020000UL	/**< PHY interrupt */
36
+
37
+/** Hardware configuration register */
38
+#define SMSC75XX_HW_CFG 0x010
39
+#define SMSC75XX_HW_CFG_BIR		0x00000080UL	/**< Bulk IN use NAK */
40
+#define SMSC75XX_HW_CFG_LRST		0x00000002UL	/**< Soft lite reset */
41
+
42
+/** Interrupt endpoint control register */
43
+#define SMSC75XX_INT_EP_CTL 0x038
44
+#define SMSC75XX_INT_EP_CTL_RDFO_EN	0x00400000UL	/**< RX FIFO overflow */
45
+#define SMSC75XX_INT_EP_CTL_PHY_EN	0x00020000UL	/**< PHY interrupt */
46
+
47
+/** Bulk IN delay register */
48
+#define SMSC75XX_BULK_IN_DLY 0x03c
49
+#define SMSC75XX_BULK_IN_DLY_SET(ticks)	( (ticks) << 0 ) /**< Delay / 16.7ns */
50
+
51
+/** EEPROM command register */
52
+#define SMSC75XX_E2P_CMD 0x040
53
+#define SMSC75XX_E2P_CMD_EPC_BSY	0x80000000UL	/**< EPC busy */
54
+#define SMSC75XX_E2P_CMD_EPC_CMD_READ	0x00000000UL	/**< READ command */
55
+#define SMSC75XX_E2P_CMD_EPC_ADDR(addr) ( (addr) << 0 )	/**< EPC address */
56
+
57
+/** EEPROM data register */
58
+#define SMSC75XX_E2P_DATA 0x044
59
+#define SMSC75XX_E2P_DATA_GET(e2p_data) \
60
+	( ( (e2p_data) >> 0 ) & 0xff )			/**< EEPROM data */
61
+
62
+/** MAC address EEPROM address */
63
+#define SMSC75XX_EEPROM_MAC 0x01
64
+
65
+/** Receive filtering engine control register */
66
+#define SMSC75XX_RFE_CTL 0x060
67
+#define SMSC75XX_RFE_CTL_AB		0x00000400UL	/**< Accept broadcast */
68
+#define SMSC75XX_RFE_CTL_AM		0x00000200UL	/**< Accept multicast */
69
+#define SMSC75XX_RFE_CTL_AU		0x00000100UL	/**< Accept unicast */
70
+
71
+/** FIFO controller RX FIFO control register */
72
+#define SMSC75XX_FCT_RX_CTL 0x090
73
+#define SMSC75XX_FCT_RX_CTL_EN		0x80000000UL	/**< FCT RX enable */
74
+#define SMSC75XX_FCT_RX_CTL_BAD		0x02000000UL	/**< Store bad frames */
75
+
76
+/** FIFO controller TX FIFO control register */
77
+#define SMSC75XX_FCT_TX_CTL 0x094
78
+#define SMSC75XX_FCT_TX_CTL_EN		0x80000000UL	/**< FCT TX enable */
79
+
80
+/** MAC receive register */
81
+#define SMSC75XX_MAC_RX 0x104
82
+#define SMSC75XX_MAC_RX_MAX_SIZE(mtu)	( (mtu) << 16 )	/**< Max frame size */
83
+#define SMSC75XX_MAC_RX_MAX_SIZE_DEFAULT \
84
+	SMSC75XX_MAC_RX_MAX_SIZE ( ETH_FRAME_LEN + 4 /* VLAN */ + 4 /* CRC */ )
85
+#define SMSC75XX_MAC_RX_FCS		0x00000010UL	/**< FCS stripping */
86
+#define SMSC75XX_MAC_RX_EN		0x00000001UL	/**< RX enable */
87
+
88
+/** MAC transmit register */
89
+#define SMSC75XX_MAC_TX 0x108
90
+#define SMSC75XX_MAC_TX_EN		0x00000001UL	/**< TX enable */
91
+
92
+/** MAC receive address high register */
93
+#define SMSC75XX_RX_ADDRH 0x118
94
+
95
+/** MAC receive address low register */
96
+#define SMSC75XX_RX_ADDRL 0x11c
97
+
98
+/** MII access register */
99
+#define SMSC75XX_MII_ACCESS 0x120
100
+#define SMSC75XX_MII_ACCESS_PHY_ADDRESS	0x00000800UL	/**< PHY address */
101
+#define SMSC75XX_MII_ACCESS_MIIRINDA(addr) ( (addr) << 6 ) /**< MII register */
102
+#define SMSC75XX_MII_ACCESS_MIIWNR	0x00000002UL	/**< MII write */
103
+#define SMSC75XX_MII_ACCESS_MIIBZY	0x00000001UL	/**< MII busy */
104
+
105
+/** MII data register */
106
+#define SMSC75XX_MII_DATA 0x124
107
+#define SMSC75XX_MII_DATA_SET(data)	( (data) << 0 )	/**< Set data */
108
+#define SMSC75XX_MII_DATA_GET(mii_data) \
109
+	( ( (mii_data) >> 0 ) & 0xffff )		/**< Get data */
110
+
111
+/** PHY interrupt source MII register */
112
+#define SMSC75XX_MII_PHY_INTR_SOURCE 29
113
+
114
+/** PHY interrupt mask MII register */
115
+#define SMSC75XX_MII_PHY_INTR_MASK 30
116
+
117
+/** PHY interrupt: auto-negotiation complete */
118
+#define SMSC75XX_PHY_INTR_ANEG_DONE	0x0040
119
+
120
+/** PHY interrupt: link down */
121
+#define SMSC75XX_PHY_INTR_LINK_DOWN	0x0010
122
+
123
+/** MAC address perfect filter N high register */
124
+#define SMSC75XX_ADDR_FILTH(n) ( 0x300 + ( 8 * (n) ) )
125
+#define SMSC75XX_ADDR_FILTH_VALID	0x80000000UL	/**< Address valid */
126
+
127
+/** MAC address perfect filter N low register */
128
+#define SMSC75XX_ADDR_FILTL(n) ( 0x304 + ( 8 * (n) ) )
129
+
130
+/** MAC address */
131
+union smsc75xx_mac {
132
+	/** MAC receive address registers */
133
+	struct {
134
+		/** MAC receive address low register */
135
+		uint32_t l;
136
+		/** MAC receive address high register */
137
+		uint32_t h;
138
+	} __attribute__ (( packed )) addr;
139
+	/** Raw MAC address */
140
+	uint8_t raw[ETH_ALEN];
141
+};
142
+
143
+/** Receive packet header */
144
+struct smsc75xx_rx_header {
145
+	/** RX command word */
146
+	uint32_t command;
147
+	/** VLAN tag */
148
+	uint16_t vtag;
149
+	/** Checksum */
150
+	uint16_t csum;
151
+	/** Two-byte padding used to align Ethernet payload */
152
+	uint16_t pad;
153
+} __attribute__ (( packed ));
154
+
155
+/** Receive error detected */
156
+#define SMSC75XX_RX_RED 0x00400000UL
157
+
158
+/** Transmit packet header */
159
+struct smsc75xx_tx_header {
160
+	/** TX command word */
161
+	uint32_t command;
162
+	/** VLAN tag */
163
+	uint16_t tag;
164
+	/** Maximum segment size */
165
+	uint16_t mss;
166
+} __attribute__ (( packed ));
167
+
168
+/** Insert frame checksum and pad */
169
+#define SMSC75XX_TX_FCS 0x00400000UL
170
+
171
+/** Interrupt packet format */
172
+struct smsc75xx_interrupt {
173
+	/** Current value of INT_STS register */
174
+	uint32_t int_sts;
175
+} __attribute__ (( packed ));
176
+
177
+/** Byte count statistics */
178
+struct smsc75xx_byte_statistics {
179
+	/** Unicast byte count */
180
+	uint32_t unicast;
181
+	/** Broadcast byte count */
182
+	uint32_t broadcast;
183
+	/** Multicast byte count */
184
+	uint32_t multicast;
185
+} __attribute__ (( packed ));
186
+
187
+/** Frame count statistics */
188
+struct smsc75xx_frame_statistics {
189
+	/** Unicast frames */
190
+	uint32_t unicast;
191
+	/** Broadcast frames */
192
+	uint32_t broadcast;
193
+	/** Multicast frames */
194
+	uint32_t multicast;
195
+	/** Pause frames */
196
+	uint32_t pause;
197
+	/** Frames by length category */
198
+	uint32_t len[7];
199
+} __attribute__ (( packed ));
200
+
201
+/** Receive error statistics */
202
+struct smsc75xx_rx_error_statistics {
203
+	/** FCS errors */
204
+	uint32_t fcs;
205
+	/** Alignment errors */
206
+	uint32_t alignment;
207
+	/** Fragment errors */
208
+	uint32_t fragment;
209
+	/** Jabber errors */
210
+	uint32_t jabber;
211
+	/** Undersize frame errors */
212
+	uint32_t undersize;
213
+	/** Oversize frame errors */
214
+	uint32_t oversize;
215
+	/** Dropped frame errors */
216
+	uint32_t dropped;
217
+} __attribute__ (( packed ));
218
+
219
+/** Receive statistics */
220
+struct smsc75xx_rx_statistics {
221
+	/** Error statistics */
222
+	struct smsc75xx_rx_error_statistics err;
223
+	/** Byte count statistics */
224
+	struct smsc75xx_byte_statistics byte;
225
+	/** Frame count statistics */
226
+	struct smsc75xx_frame_statistics frame;
227
+} __attribute__ (( packed ));
228
+
229
+/** Transmit error statistics */
230
+struct smsc75xx_tx_error_statistics {
231
+	/** FCS errors */
232
+	uint32_t fcs;
233
+	/** Excess deferral errors */
234
+	uint32_t deferral;
235
+	/** Carrier errors */
236
+	uint32_t carrier;
237
+	/** Bad byte count */
238
+	uint32_t count;
239
+	/** Single collisions */
240
+	uint32_t single;
241
+	/** Multiple collisions */
242
+	uint32_t multiple;
243
+	/** Excession collisions */
244
+	uint32_t excessive;
245
+	/** Late collisions */
246
+	uint32_t late;
247
+} __attribute__ (( packed ));
248
+
249
+/** Transmit statistics */
250
+struct smsc75xx_tx_statistics {
251
+	/** Error statistics */
252
+	struct smsc75xx_tx_error_statistics err;
253
+	/** Byte count statistics */
254
+	struct smsc75xx_byte_statistics byte;
255
+	/** Frame count statistics */
256
+	struct smsc75xx_frame_statistics frame;
257
+} __attribute__ (( packed ));
258
+
259
+/** Statistics */
260
+struct smsc75xx_statistics {
261
+	/** Receive statistics */
262
+	struct smsc75xx_rx_statistics rx;
263
+	/** Transmit statistics */
264
+	struct smsc75xx_tx_statistics tx;
265
+} __attribute__ (( packed ));
266
+
267
+/** A SMSC75xx network device */
268
+struct smsc75xx_device {
269
+	/** USB device */
270
+	struct usb_device *usb;
271
+	/** USB bus */
272
+	struct usb_bus *bus;
273
+	/** Network device */
274
+	struct net_device *netdev;
275
+	/** USB network device */
276
+	struct usbnet_device usbnet;
277
+	/** MII interface */
278
+	struct mii_interface mii;
279
+	/** Interrupt status */
280
+	uint32_t int_sts;
281
+};
282
+
283
+/** Reset delay (in microseconds) */
284
+#define SMSC75XX_RESET_DELAY_US 2
285
+
286
+/** Maximum time to wait for EEPROM (in milliseconds) */
287
+#define SMSC75XX_EEPROM_MAX_WAIT_MS 100
288
+
289
+/** Maximum time to wait for MII (in milliseconds) */
290
+#define SMSC75XX_MII_MAX_WAIT_MS 100
291
+
292
+/** Interrupt maximum fill level
293
+ *
294
+ * This is a policy decision.
295
+ */
296
+#define SMSC75XX_INTR_MAX_FILL 2
297
+
298
+/** Bulk IN maximum fill level
299
+ *
300
+ * This is a policy decision.
301
+ */
302
+#define SMSC75XX_IN_MAX_FILL 8
303
+
304
+/** Bulk IN buffer size */
305
+#define SMSC75XX_IN_MTU						\
306
+	( sizeof ( struct smsc75xx_rx_header ) +		\
307
+	  ETH_FRAME_LEN + 4 /* possible VLAN header */ )
308
+
309
+#endif /* _SMSC75XX_H */

+ 1
- 0
src/include/ipxe/errfile.h View File

@@ -172,6 +172,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
172 172
 #define ERRFILE_ata		     ( ERRFILE_DRIVER | 0x00740000 )
173 173
 #define ERRFILE_srp		     ( ERRFILE_DRIVER | 0x00750000 )
174 174
 #define ERRFILE_qib7322		     ( ERRFILE_DRIVER | 0x00760000 )
175
+#define ERRFILE_smsc75xx	     ( ERRFILE_DRIVER | 0x00770000 )
175 176
 
176 177
 #define ERRFILE_aoe			( ERRFILE_NET | 0x00000000 )
177 178
 #define ERRFILE_arp			( ERRFILE_NET | 0x00010000 )

Loading…
Cancel
Save