Browse Source

[velocity] Rewrite VIA Velocity driver

Signed-off-by: Adrian Jamróz <adrian.jamroz@gmail.com>
Modified-by: Thomas Miletich <thomas.miletich@gmail.com>
Signed-off-by: Thomas Miletich <thomas.miletich@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Adrian Jamróz 11 years ago
parent
commit
4fabc0012a

+ 807
- 0
src/drivers/net/velocity.c View File

@@ -0,0 +1,807 @@
1
+/*
2
+ * Copyright (C) 2012 Adrian Jamróz <adrian.jamroz@gmail.com>
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or (at your option) any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17
+ * 02110-1301, USA.
18
+ */
19
+
20
+FILE_LICENCE ( GPL2_OR_LATER );
21
+
22
+#include <stdint.h>
23
+#include <string.h>
24
+#include <unistd.h>
25
+#include <errno.h>
26
+#include <byteswap.h>
27
+#include <ipxe/netdevice.h>
28
+#include <ipxe/ethernet.h>
29
+#include <ipxe/if_ether.h>
30
+#include <ipxe/iobuf.h>
31
+#include <ipxe/malloc.h>
32
+#include <ipxe/pci.h>
33
+#include <ipxe/mii.h>
34
+#include "velocity.h"
35
+
36
+#define	velocity_setbit(_reg, _mask)	writeb ( readb ( _reg ) | _mask, _reg )
37
+#define virt_to_le32bus(x)		( cpu_to_le32 ( virt_to_bus ( x ) ) )
38
+
39
+/** @file
40
+ *
41
+ * VIA Velocity network driver
42
+ *
43
+ */
44
+
45
+/******************************************************************************
46
+ *
47
+ * MII interface
48
+ *
49
+ ******************************************************************************
50
+ */
51
+
52
+/**
53
+ * Stop MII auto-polling
54
+ *
55
+ * @v vlc	Velocity device
56
+ * @ret	rc	Return status code
57
+ */
58
+static int velocity_autopoll_stop ( struct velocity_nic *vlc ) {
59
+	int timeout = VELOCITY_TIMEOUT_US;
60
+
61
+	/* Disable MII auto polling */
62
+	writeb ( 0, vlc->regs + VELOCITY_MIICR );
63
+
64
+	/* Wait for disabling to take effect */
65
+	while ( timeout-- ) {
66
+		udelay ( 1 );
67
+		if ( readb ( vlc->regs + VELOCITY_MIISR ) &
68
+		             VELOCITY_MIISR_IDLE )
69
+			return 0;
70
+	}
71
+
72
+	DBGC ( vlc, "MII autopoll stop timeout\n" );
73
+	return -ETIMEDOUT;
74
+}
75
+
76
+/**
77
+ * Start MII auto-polling
78
+ *
79
+ * @v vlc	Velocity device
80
+ * @ret rc	Return status code
81
+ */
82
+static int velocity_autopoll_start ( struct velocity_nic *vlc ) {
83
+	int timeout = VELOCITY_TIMEOUT_US;
84
+
85
+	/* Enable MII auto polling */
86
+	writeb ( VELOCITY_MIICR_MAUTO, vlc->regs + VELOCITY_MIICR );
87
+
88
+	/* Wait for enabling to take effect */
89
+	while ( timeout-- ) {
90
+		udelay ( 1 );
91
+		if ( ( readb ( vlc->regs + VELOCITY_MIISR ) &
92
+		       VELOCITY_MIISR_IDLE ) == 0 )
93
+			return 0;
94
+	}
95
+
96
+	DBGC ( vlc, "MII autopoll start timeout\n" );
97
+	return -ETIMEDOUT;
98
+}
99
+
100
+/**
101
+ * Read from MII register
102
+ *
103
+ * @v mii		MII interface
104
+ * @v reg		Register address
105
+ * @ret value		Data read, or negative error
106
+ */
107
+static int velocity_mii_read ( struct mii_interface *mii, unsigned int reg ) {
108
+	struct velocity_nic *vlc =
109
+		container_of ( mii, struct velocity_nic, mii );
110
+	int timeout = VELOCITY_TIMEOUT_US;
111
+	int result;
112
+
113
+	DBGC2 ( vlc, "VELOCITY %p MII read reg %d\n", vlc, reg );
114
+
115
+	/* Disable autopolling before we can access MII */
116
+	velocity_autopoll_stop ( vlc );
117
+
118
+	/* Send read command and address */
119
+	writeb ( reg, vlc->regs + VELOCITY_MIIADDR );
120
+	velocity_setbit ( vlc->regs + VELOCITY_MIICR, VELOCITY_MIICR_RCMD );
121
+
122
+	/* Wait for read to complete */
123
+	while ( timeout-- ) {
124
+		udelay ( 1 );
125
+		if ( ( readb ( vlc->regs + VELOCITY_MIICR ) &
126
+		       VELOCITY_MIICR_RCMD ) == 0 ) {
127
+			result = readw ( vlc->regs + VELOCITY_MIIDATA );
128
+			velocity_autopoll_start ( vlc );
129
+			return result;
130
+		}
131
+	}
132
+
133
+	/* Restart autopolling */
134
+	velocity_autopoll_start ( vlc );
135
+
136
+	DBGC ( vlc, "MII read timeout\n" );
137
+	return -ETIMEDOUT;
138
+}
139
+
140
+/**
141
+ * Write to MII register
142
+ *
143
+ * @v mii		MII interface
144
+ * @v reg		Register address
145
+ * @v data		Data to write
146
+ * @ret rc		Return status code
147
+ */
148
+static int velocity_mii_write ( struct mii_interface *mii, unsigned int reg,
149
+				unsigned int data) {
150
+	struct velocity_nic *vlc =
151
+		container_of ( mii, struct velocity_nic, mii );
152
+	int timeout = VELOCITY_TIMEOUT_US;
153
+
154
+	DBGC2 ( vlc, "VELOCITY %p MII write reg %d data 0x%04x\n",
155
+			vlc, reg, data );
156
+
157
+	/* Disable autopolling before we can access MII */
158
+	velocity_autopoll_stop ( vlc );
159
+
160
+	/* Send write command, data and destination register */
161
+	writeb ( reg, vlc->regs + VELOCITY_MIIADDR );
162
+	writew ( data, vlc->regs + VELOCITY_MIIDATA );
163
+	velocity_setbit ( vlc->regs + VELOCITY_MIICR, VELOCITY_MIICR_WCMD );
164
+
165
+	/* Wait for write to complete */
166
+	while ( timeout-- ) {
167
+		udelay ( 1 );
168
+		if ( ( readb ( vlc->regs + VELOCITY_MIICR ) &
169
+		       VELOCITY_MIICR_WCMD ) == 0 ) {
170
+			velocity_autopoll_start ( vlc );
171
+			return 0;
172
+		}
173
+	}
174
+
175
+	/* Restart autopolling */
176
+	velocity_autopoll_start ( vlc );
177
+
178
+	DBGC ( vlc, "MII write timeout\n" );
179
+	return -ETIMEDOUT;
180
+}
181
+
182
+/** Velocity MII operations */
183
+static struct mii_operations velocity_mii_operations = {
184
+	.read = velocity_mii_read,
185
+	.write = velocity_mii_write,
186
+};
187
+
188
+/**
189
+ * Set Link speed 
190
+ *
191
+ * @v vlc	Velocity device
192
+ */
193
+static void velocity_set_link ( struct velocity_nic *vlc ) {
194
+	int tmp;
195
+
196
+	/* Advertise 1000MBit */
197
+	tmp = velocity_mii_read ( &vlc->mii, MII_CTRL1000 );
198
+	tmp |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
199
+	velocity_mii_write ( &vlc->mii, MII_CTRL1000, tmp );
200
+
201
+	/* Enable GBit operation in MII Control Register */
202
+	tmp = velocity_mii_read ( &vlc->mii, MII_BMCR );
203
+	tmp |= BMCR_SPEED1000;
204
+	velocity_mii_write ( &vlc->mii, MII_BMCR, tmp );
205
+}
206
+
207
+/******************************************************************************
208
+ *
209
+ * Device reset
210
+ *
211
+ ******************************************************************************
212
+ */
213
+
214
+/**
215
+ * Reload eeprom contents
216
+ *
217
+ * @v vlc		Velocity device
218
+ */
219
+static int velocity_reload_eeprom ( struct velocity_nic *vlc ) {
220
+	int timeout = VELOCITY_TIMEOUT_US;
221
+
222
+	/* Initiate reload */
223
+	velocity_setbit ( vlc->regs + VELOCITY_EECSR, VELOCITY_EECSR_RELOAD );
224
+
225
+	/* Wait for reload to complete */
226
+	while ( timeout-- ) {
227
+		udelay ( 1 );
228
+		if ( ( readb ( vlc->regs + VELOCITY_EECSR ) &
229
+		       VELOCITY_EECSR_RELOAD ) == 0 )
230
+			return 0;
231
+	}
232
+
233
+	DBGC ( vlc, "VELOCITY %p EEPROM reload timeout\n", vlc );
234
+	return -ETIMEDOUT;
235
+}
236
+
237
+/**
238
+ * Reset hardware
239
+ *
240
+ * @v vlc		Velocity device
241
+ * @ret rc		Return status code
242
+ */
243
+static int velocity_reset ( struct velocity_nic *vlc ) {
244
+	int timeout = VELOCITY_TIMEOUT_US;
245
+	uint8_t tmp;
246
+
247
+	DBGC ( vlc, "VELOCITY %p reset\n", vlc );
248
+
249
+	/* clear sticky Power state bits */
250
+	tmp = readb ( vlc->regs + VELOCITY_STICKY );
251
+	tmp &= ~( VELOCITY_STICKY_DS0 | VELOCITY_STICKY_DS1 );
252
+	writeb ( tmp, vlc->regs + VELOCITY_STICKY );
253
+
254
+	/* clear PACPI, which might have been enabled by the EEPROM reload */
255
+	tmp = readb ( vlc->regs + VELOCITY_CFGA );
256
+	tmp &= ~VELOCITY_CFGA_PACPI;
257
+	writeb ( tmp, vlc->regs + VELOCITY_CFGA );
258
+
259
+	velocity_setbit ( vlc->regs + VELOCITY_CRS1, VELOCITY_CR1_SFRST );
260
+
261
+	/* Wait for reset to complete */
262
+	while ( timeout-- ) {
263
+		udelay ( 1 );
264
+		if ( ( readb ( vlc->regs + VELOCITY_CRS1 ) &
265
+		       VELOCITY_CR1_SFRST ) == 0 )
266
+			return 0;
267
+	}
268
+
269
+	return -EINVAL;
270
+}
271
+
272
+/******************************************************************************
273
+ *
274
+ * Link state
275
+ *
276
+ ******************************************************************************
277
+ */
278
+
279
+/**
280
+ * Check link state
281
+ *
282
+ * @v netdev		Network device
283
+ */
284
+static void velocity_check_link ( struct net_device *netdev ) {
285
+	struct velocity_nic *vlc = netdev->priv;
286
+
287
+	if ( readb ( vlc->regs + VELOCITY_PHYSTS0 ) & VELOCITY_PHYSTS0_LINK ) {
288
+		netdev_link_up ( netdev );
289
+		DBGC ( vlc, "VELOCITY %p link up\n", vlc );
290
+	} else {
291
+		netdev_link_down ( netdev );
292
+		DBGC ( vlc, "VELOCITY %p link down\n", vlc );
293
+	}
294
+
295
+	/* The card disables auto-poll after a link change */
296
+	velocity_autopoll_start ( vlc );
297
+}
298
+
299
+/******************************************************************************
300
+ *
301
+ * Network device interface
302
+ *
303
+ ******************************************************************************
304
+ */
305
+
306
+/**
307
+ * Allocate descriptor rings
308
+ *
309
+ * @v vlc	Velocity device
310
+ * @ret rc	Return status code
311
+ */
312
+static int velocity_alloc_rings ( struct velocity_nic *vlc ) {
313
+	int rc = 0;
314
+
315
+	/* Allocate RX descriptor ring */
316
+	vlc->rx_prod = 0;
317
+	vlc->rx_cons = 0;
318
+	vlc->rx_commit = 0;
319
+	vlc->rx_ring = malloc_dma ( VELOCITY_RXDESC_SIZE, VELOCITY_RING_ALIGN );
320
+	if ( ! vlc->rx_ring )
321
+		return -ENOMEM;
322
+
323
+	memset ( vlc->rx_ring, 0, VELOCITY_RXDESC_SIZE );
324
+
325
+	DBGC2 ( vlc, "VELOCITY %p RX ring start address: %p(phys: %#08lx)\n",
326
+	       vlc, vlc->rx_ring, virt_to_bus ( vlc->rx_ring ) );
327
+
328
+	/* Allocate TX descriptor ring */
329
+	vlc->tx_prod = 0;
330
+	vlc->tx_cons = 0;
331
+	vlc->tx_ring = malloc_dma ( VELOCITY_TXDESC_SIZE, VELOCITY_RING_ALIGN );
332
+	if ( ! vlc->tx_ring ) {
333
+		rc = -ENOMEM;
334
+		goto err_tx_alloc;
335
+	}
336
+
337
+	memset ( vlc->tx_ring, 0, VELOCITY_TXDESC_SIZE );
338
+
339
+	/* Send RX ring to the card */
340
+	writel ( virt_to_bus ( vlc->rx_ring ),
341
+	         vlc->regs + VELOCITY_RXDESC_ADDR_LO );
342
+	writew ( VELOCITY_RXDESC_NUM - 1, vlc->regs + VELOCITY_RXDESCNUM );
343
+
344
+	/* Send TX ring to the card */
345
+	writel ( virt_to_bus ( vlc->tx_ring ),
346
+	         vlc->regs + VELOCITY_TXDESC_ADDR_LO0 );
347
+	writew ( VELOCITY_TXDESC_NUM - 1, vlc->regs + VELOCITY_TXDESCNUM );
348
+
349
+	DBGC2 ( vlc, "VELOCITY %p TX ring start address: %p(phys: %#08lx)\n",
350
+	       vlc, vlc->tx_ring, virt_to_bus ( vlc->tx_ring ) );
351
+
352
+	return 0;
353
+
354
+err_tx_alloc:
355
+	free_dma ( vlc->rx_ring, VELOCITY_RXDESC_SIZE );
356
+	return rc;
357
+}
358
+
359
+/**
360
+ * Refill receive descriptor ring
361
+ *
362
+ * @v vlc	Velocity device
363
+ */
364
+static void velocity_refill_rx ( struct velocity_nic *vlc ) {
365
+	struct velocity_rx_descriptor *desc;
366
+	struct io_buffer *iobuf;
367
+	int rx_idx, i = 0;
368
+
369
+	/* Check for new packets */
370
+	while ( ( vlc->rx_prod - vlc->rx_cons ) < VELOCITY_RXDESC_NUM ) {
371
+		iobuf = alloc_iob ( VELOCITY_RX_MAX_LEN );
372
+
373
+		/* Memory pressure: try again next poll */
374
+		if ( ! iobuf )
375
+			break;
376
+
377
+		rx_idx = ( vlc->rx_prod++ % VELOCITY_RXDESC_NUM );
378
+		desc = &vlc->rx_ring[rx_idx];
379
+
380
+		/* Set descrptor fields */
381
+		desc->des1 = 0;
382
+		desc->addr = virt_to_le32bus ( iobuf-> data );
383
+		desc->des2 = cpu_to_le32 (
384
+		    VELOCITY_DES2_SIZE ( VELOCITY_RX_MAX_LEN - 1 ) |
385
+		    VELOCITY_DES2_IC );
386
+
387
+		vlc->rx_buffs[rx_idx] = iobuf;
388
+		i++;
389
+
390
+		/* Return RX descriptors in blocks of 4 (hw requirement) */
391
+		if ( rx_idx % 4 == 3 ) {
392
+			int j;
393
+			for (j = 0; j < 4; j++) {
394
+				desc = &vlc->rx_ring[rx_idx - j];
395
+				desc->des0 = cpu_to_le32 ( VELOCITY_DES0_OWN );
396
+			}
397
+			vlc->rx_commit += 4;
398
+		}
399
+	}
400
+
401
+	wmb();
402
+
403
+	if ( vlc->rx_commit ) {
404
+		writew ( vlc->rx_commit,
405
+		         vlc->regs + VELOCITY_RXDESC_RESIDUECNT );
406
+		vlc->rx_commit = 0;
407
+	}
408
+
409
+	if ( i > 0 )
410
+		DBGC2 ( vlc, "VELOCITY %p refilled %d RX descriptors\n",
411
+		        vlc, i );
412
+}
413
+
414
+/**
415
+ * Open network device
416
+ *
417
+ * @v netdev		Network device
418
+ * @ret rc		Return status code
419
+ */
420
+static int velocity_open ( struct net_device *netdev ) {
421
+	struct velocity_nic *vlc = netdev->priv;
422
+	int rc;
423
+
424
+	DBGC ( vlc, "VELOCITY %p open\n", vlc );
425
+	DBGC ( vlc, "VELOCITY %p regs at: %p\n", vlc, vlc->regs );
426
+
427
+	/* Allocate descriptor rings */
428
+	if ( ( rc = velocity_alloc_rings ( vlc ) ) != 0 )
429
+		return rc;
430
+
431
+	velocity_refill_rx ( vlc );
432
+
433
+	/* Enable TX/RX queue */
434
+	writew ( VELOCITY_TXQCSRS_RUN0, vlc->regs + VELOCITY_TXQCSRS );
435
+	writew ( VELOCITY_RXQCSR_RUN | VELOCITY_RXQCSR_WAK,
436
+	         vlc->regs + VELOCITY_RXQCSRS );
437
+
438
+	/* Enable interrupts */
439
+	writeb ( 0xff, vlc->regs + VELOCITY_IMR0 );
440
+	writeb ( 0xff, vlc->regs + VELOCITY_IMR1 );
441
+
442
+	/* Start MAC */
443
+	writeb ( VELOCITY_CR0_STOP, vlc->regs + VELOCITY_CRC0 );
444
+	writeb ( VELOCITY_CR1_DPOLL, vlc->regs + VELOCITY_CRC0 );
445
+	writeb ( VELOCITY_CR0_START | VELOCITY_CR0_TXON | VELOCITY_CR0_RXON,
446
+	         vlc->regs + VELOCITY_CRS0 );
447
+
448
+	/* Receive all packets */
449
+	writeb ( 0xff, vlc->regs + VELOCITY_RCR );
450
+
451
+	/* Set initial link state */
452
+	velocity_check_link ( netdev );
453
+
454
+	velocity_autopoll_start ( vlc );
455
+
456
+	DBGC2 ( vlc, "VELOCITY %p CR3 %02x\n",
457
+	        vlc, readb ( vlc->regs + 0x0B ) );
458
+
459
+	return 0;
460
+}
461
+
462
+/**
463
+ * Close network device
464
+ *
465
+ * @v netdev		Network device
466
+ */
467
+static void velocity_close ( struct net_device *netdev ) {
468
+	struct velocity_nic *vlc = netdev->priv;
469
+	int i;
470
+
471
+	/* Stop NIC */
472
+	writeb ( VELOCITY_CR0_TXON | VELOCITY_CR0_RXON,
473
+	         vlc->regs + VELOCITY_CRC0 );
474
+	writeb ( VELOCITY_CR0_STOP, vlc->regs + VELOCITY_CRS0 );
475
+
476
+	/* Clear RX ring information */
477
+	writel ( 0, vlc->regs + VELOCITY_RXDESC_ADDR_LO );
478
+	writew ( 0, vlc->regs + VELOCITY_RXDESCNUM );
479
+
480
+	/* Destroy RX ring */
481
+	free_dma ( vlc->rx_ring, VELOCITY_RXDESC_SIZE );
482
+	vlc->rx_ring = NULL;
483
+	vlc->rx_prod = 0;
484
+	vlc->rx_cons = 0;
485
+
486
+	/* Discard receive buffers */
487
+	for ( i = 0 ; i < VELOCITY_RXDESC_NUM ; i++ ) {
488
+		if ( vlc->rx_buffs[i] )
489
+			free_iob ( vlc->rx_buffs[i] );
490
+		vlc->rx_buffs[i] = NULL;
491
+	}
492
+
493
+	/* Clear TX ring information */
494
+	writel ( 0, vlc->regs + VELOCITY_TXDESC_ADDR_LO0 );
495
+	writew ( 0, vlc->regs + VELOCITY_TXDESCNUM );
496
+
497
+	/* Destroy TX ring */
498
+	free_dma ( vlc->tx_ring, VELOCITY_TXDESC_SIZE );
499
+	vlc->tx_ring = NULL;
500
+	vlc->tx_prod = 0;
501
+	vlc->tx_cons = 0;
502
+}
503
+
504
+/**
505
+ * Transmit packet
506
+ *
507
+ * @v netdev		Network device
508
+ * @v iobuf		I/O buffer
509
+ * @ret rc		Return status code
510
+ */
511
+static int velocity_transmit ( struct net_device *netdev,
512
+			       struct io_buffer *iobuf ) {
513
+	struct velocity_nic *vlc = netdev->priv;
514
+	struct velocity_tx_descriptor *desc;
515
+	unsigned int tx_idx;
516
+
517
+	/* Pad packet to minimum length */
518
+	iob_pad ( iobuf, ETH_ZLEN );
519
+
520
+	tx_idx = ( vlc->tx_prod++ % VELOCITY_TXDESC_NUM );
521
+	desc = &vlc->tx_ring[tx_idx];
522
+
523
+	/* Set packet size and transfer ownership to NIC */
524
+	desc->des0 = cpu_to_le32 ( VELOCITY_DES0_OWN |
525
+	                           VELOCITY_DES2_SIZE ( iob_len ( iobuf ) ) );
526
+	/* Data in first desc fragment, only desc for packet, generate INT */
527
+	desc->des1 = cpu_to_le32 ( VELOCITY_DES1_FRAG ( 1 ) |
528
+	                           VELOCITY_DES1_TCPLS |
529
+				   VELOCITY_DES1_INTR );
530
+
531
+	desc->frags[0].addr = virt_to_le32bus ( iobuf->data );
532
+	desc->frags[0].des2 = cpu_to_le32 (
533
+	                      VELOCITY_DES2_SIZE ( iob_len ( iobuf ) ) );
534
+
535
+	wmb();
536
+
537
+	/* Initiate TX */
538
+	velocity_setbit ( vlc->regs + VELOCITY_TXQCSRS, VELOCITY_TXQCSRS_WAK0 );
539
+
540
+	DBGC2 ( vlc, "VELOCITY %p tx_prod=%d desc=%p iobuf=%p len=%zd\n",
541
+	        vlc, tx_idx, desc, iobuf->data, iob_len ( iobuf ) );
542
+
543
+	return 0;
544
+}
545
+
546
+/**
547
+ * Poll for received packets.
548
+ *
549
+ * @v vlc	Velocity device
550
+ */
551
+static void velocity_poll_rx ( struct velocity_nic *vlc ) {
552
+	struct velocity_rx_descriptor *desc;
553
+	struct io_buffer *iobuf;
554
+	int rx_idx;
555
+	size_t len;
556
+	uint32_t des0;
557
+
558
+	/* Check for packets */
559
+	while ( vlc->rx_cons != vlc->rx_prod ) {
560
+		rx_idx = ( vlc->rx_cons % VELOCITY_RXDESC_NUM );
561
+		desc = &vlc->rx_ring[rx_idx];
562
+
563
+		des0 = cpu_to_le32 ( desc->des0 );
564
+
565
+		/* Return if descriptor still in use */
566
+		if ( des0 & VELOCITY_DES0_OWN )
567
+			return;
568
+
569
+		iobuf = vlc->rx_buffs[rx_idx];
570
+
571
+		/* Get length, strip CRC */
572
+		len = VELOCITY_DES0_RMBC ( des0 ) - 4;
573
+		iob_put ( iobuf, len );
574
+
575
+		DBGC2 ( vlc, "VELOCITY %p got packet on idx=%d (prod=%d), len %zd\n",
576
+		    vlc, rx_idx, vlc->rx_prod % VELOCITY_RXDESC_NUM, len );
577
+
578
+		if ( des0 & VELOCITY_DES0_RX_ERR ) {
579
+			/* Report receive error */
580
+			netdev_rx_err ( vlc->netdev, iobuf, -EINVAL );
581
+			DBGC ( vlc, "VELOCITY %p receive error, status: %02x\n",
582
+			       vlc, des0 );
583
+		} else if ( des0 & VELOCITY_DES0_RXOK ) {
584
+			/* Report receive success */
585
+			netdev_rx( vlc->netdev, iobuf );
586
+		} else {
587
+			/* Card indicated neither success nor failure
588
+			 * Technically this shouldn't happen, but we saw it
589
+			 * in debugging once. */
590
+			DBGC ( vlc, "VELOCITY %p RX neither ERR nor OK: %04x\n",
591
+			       vlc, des0 );
592
+			DBGC ( vlc, "packet len: %zd\n", len );
593
+			DBGC_HD ( vlc, iobuf->data, 64 );
594
+
595
+			/* we don't know what it is, treat is as an error */
596
+			netdev_rx_err ( vlc->netdev, iobuf, -EINVAL );
597
+		}
598
+
599
+		vlc->rx_cons++;
600
+	}
601
+}
602
+
603
+/**
604
+ * Poll for completed packets.
605
+ *
606
+ * @v vlc	Velocity device
607
+ */
608
+static void velocity_poll_tx ( struct velocity_nic *vlc ) {
609
+	struct velocity_tx_descriptor *desc;
610
+	int tx_idx;
611
+
612
+	/* Check for packets */
613
+	while ( vlc->tx_cons != vlc->tx_prod ) {
614
+		tx_idx = ( vlc->tx_cons % VELOCITY_TXDESC_NUM );
615
+		desc = &vlc->tx_ring[tx_idx];
616
+
617
+		/* Return if descriptor still in use */
618
+		if ( le32_to_cpu ( desc->des0 ) & VELOCITY_DES0_OWN )
619
+			return;
620
+
621
+		/* Report errors */
622
+		if ( le32_to_cpu ( desc->des0 ) & VELOCITY_DES0_TERR ) {
623
+			netdev_tx_complete_next_err ( vlc->netdev, -EINVAL );
624
+			return;
625
+		}
626
+
627
+		netdev_tx_complete_next ( vlc->netdev );
628
+
629
+		DBGC2 ( vlc, "VELOCITY %p poll_tx cons=%d prod=%d tsr=%04x\n",
630
+		        vlc, tx_idx, vlc->tx_prod % VELOCITY_TXDESC_NUM,
631
+			( desc->des0 & 0xffff ) );
632
+		vlc->tx_cons++;
633
+	}
634
+}
635
+
636
+/**
637
+ * Poll for completed and received packets
638
+ *
639
+ * @v netdev		Network device
640
+ */
641
+static void velocity_poll ( struct net_device *netdev ) {
642
+	struct velocity_nic *vlc = netdev->priv;
643
+	uint8_t isr1;
644
+
645
+	isr1 = readb ( vlc->regs + VELOCITY_ISR1 );
646
+
647
+	/* ACK interrupts */
648
+	writew ( 0xFFFF, vlc->regs + VELOCITY_ISR0 );
649
+
650
+	/* Check for competed packets */
651
+	velocity_poll_rx ( vlc );
652
+	velocity_poll_tx ( vlc );
653
+
654
+	if ( isr1 & VELOCITY_ISR1_SRCI ) {
655
+		/* Update linkstate */
656
+		DBGC2 ( vlc, "VELOCITY %p link status interrupt\n", vlc );
657
+		velocity_check_link ( netdev );
658
+	}
659
+
660
+	velocity_refill_rx ( vlc );
661
+
662
+	/* deal with potential RX stall caused by RX ring underrun */
663
+	writew ( VELOCITY_RXQCSR_RUN | VELOCITY_RXQCSR_WAK,
664
+	         vlc->regs + VELOCITY_RXQCSRS );
665
+}
666
+
667
+/**
668
+ * Enable or disable interrupts
669
+ *
670
+ * @v netdev		Network device
671
+ * @v enable		Interrupts should be enabled
672
+ */
673
+static void velocity_irq ( struct net_device *netdev, int enable ) {
674
+	struct velocity_nic *vlc = netdev->priv;
675
+
676
+	DBGC ( vlc, "VELOCITY %p interrupts %s\n", vlc,
677
+	    enable ? "enable" : "disable" );
678
+
679
+	if (enable) {
680
+		/* Enable interrupts */
681
+		writeb ( VELOCITY_CR3_GINTMSK1, vlc->regs + VELOCITY_CRS3 );
682
+	} else {
683
+		/* Disable interrupts */
684
+		writeb ( VELOCITY_CR3_GINTMSK1, vlc->regs + VELOCITY_CRC3 );
685
+	}
686
+}
687
+
688
+/** Velocity network device operations */
689
+static struct net_device_operations velocity_operations = {
690
+	.open		= velocity_open,
691
+	.close		= velocity_close,
692
+	.transmit	= velocity_transmit,
693
+	.poll		= velocity_poll,
694
+	.irq		= velocity_irq,
695
+};
696
+
697
+/******************************************************************************
698
+ *
699
+ * PCI interface
700
+ *
701
+ ******************************************************************************
702
+ */
703
+
704
+/**
705
+ * Probe PCI device
706
+ *
707
+ * @v pci		PCI device
708
+ * @ret rc		Return status code
709
+ */
710
+static int velocity_probe ( struct pci_device *pci ) {
711
+	struct net_device *netdev;
712
+	struct velocity_nic *vlc;
713
+	int rc;
714
+
715
+	/* Allocate and initialise net device */
716
+	netdev = alloc_etherdev ( sizeof ( *vlc ) );
717
+	if ( ! netdev ) {
718
+		rc = -ENOMEM;
719
+		goto err_alloc;
720
+	}
721
+	netdev_init ( netdev, &velocity_operations );
722
+	vlc = netdev->priv;
723
+	pci_set_drvdata ( pci, netdev );
724
+	netdev->dev = &pci->dev;
725
+
726
+	/* Fix up PCI device */
727
+	adjust_pci_device ( pci );
728
+
729
+	/* Map registers */
730
+	vlc->regs = ioremap ( pci->membase, VELOCITY_BAR_SIZE );
731
+	vlc->netdev = netdev;
732
+
733
+	/* Reset the NIC */
734
+	if ( ( rc = velocity_reset ( vlc ) ) != 0 )
735
+		goto err_reset;
736
+
737
+	/* Reload EEPROM */
738
+	if ( ( rc = velocity_reload_eeprom ( vlc ) ) != 0 )
739
+		goto err_reset;
740
+
741
+	/* Get MAC address */
742
+	netdev->hw_addr[0] = readb ( vlc->regs + VELOCITY_MAC0 );
743
+	netdev->hw_addr[1] = readb ( vlc->regs + VELOCITY_MAC1 );
744
+	netdev->hw_addr[2] = readb ( vlc->regs + VELOCITY_MAC2 );
745
+	netdev->hw_addr[3] = readb ( vlc->regs + VELOCITY_MAC3 );
746
+	netdev->hw_addr[4] = readb ( vlc->regs + VELOCITY_MAC4 );
747
+	netdev->hw_addr[5] = readb ( vlc->regs + VELOCITY_MAC5 );
748
+
749
+	/* Initialise and reset MII interface */
750
+	mii_init ( &vlc->mii, &velocity_mii_operations );
751
+	if ( ( rc = mii_reset ( &vlc->mii ) ) != 0 ) {
752
+		DBGC ( vlc, "VELOCITY %p could not reset MII: %s\n",
753
+		       vlc, strerror ( rc ) );
754
+		goto err_mii_reset;
755
+	}
756
+
757
+	/* Enable proper link advertising */
758
+	velocity_set_link ( vlc );
759
+
760
+	/* Register network device */
761
+	if ( ( rc = register_netdev ( netdev ) ) != 0 )
762
+		goto err_register_netdev;
763
+
764
+	return 0;
765
+
766
+ err_register_netdev:
767
+ err_mii_reset:
768
+	velocity_reset ( vlc );
769
+ err_reset:
770
+	netdev_nullify ( netdev );
771
+	netdev_put ( netdev );
772
+ err_alloc:
773
+	return rc;
774
+}
775
+
776
+/**
777
+ * Remove PCI device
778
+ *
779
+ * @v pci		PCI device
780
+ */
781
+static void velocity_remove ( struct pci_device *pci ) {
782
+	struct net_device *netdev = pci_get_drvdata ( pci );
783
+	struct velocity_nic *vlc = netdev->priv;
784
+
785
+	/* Unregister network device */
786
+	unregister_netdev ( netdev );
787
+
788
+	/* Reset card */
789
+	velocity_reset ( vlc );
790
+
791
+	/* Free network device */
792
+	netdev_nullify ( netdev );
793
+	netdev_put ( netdev );
794
+}
795
+
796
+/** Velocity PCI device IDs */
797
+static struct pci_device_id velocity_nics[] = {
798
+	PCI_ROM ( 0x1106, 0x3119, "vt6122",	"VIA Velocity", 0 ),
799
+};
800
+
801
+/** Velocity PCI driver */
802
+struct pci_driver velocity_driver __pci_driver = {
803
+	.ids = velocity_nics,
804
+	.id_count = ( sizeof ( velocity_nics ) / sizeof ( velocity_nics[0] ) ),
805
+	.probe = velocity_probe,
806
+	.remove = velocity_remove,
807
+};

+ 356
- 0
src/drivers/net/velocity.h View File

@@ -0,0 +1,356 @@
1
+#ifndef _VELOCITY_H
2
+#define _VELOCITY_H
3
+
4
+/** @file
5
+ *
6
+ * VIA Velocity network driver
7
+ *
8
+ */
9
+
10
+FILE_LICENCE ( GPL2_OR_LATER );
11
+
12
+/** Skeleton BAR size */
13
+#define	VELOCITY_BAR_SIZE 	256
14
+
15
+/** Default timeout */
16
+#define	VELOCITY_TIMEOUT_US	10 * 1000
17
+
18
+struct velocity_frag {
19
+	uint32_t	addr;
20
+	uint32_t	des2;
21
+} __attribute__ ((packed));
22
+
23
+/** Velocity descriptor format */
24
+struct velocity_tx_descriptor {
25
+	uint32_t	des0;
26
+	uint32_t	des1;
27
+	/* We only use the first fragment, the HW requires us to have 7 */
28
+	struct velocity_frag frags[7];
29
+} __attribute__ ((packed));
30
+
31
+struct velocity_rx_descriptor {
32
+	uint32_t	des0;
33
+	uint32_t	des1;
34
+	uint32_t	addr;
35
+	uint32_t	des2;
36
+} __attribute__ ((packed));
37
+
38
+#define	VELOCITY_DES0_RMBC(_n)	(((_n) >> 16) & 0x1fff)
39
+#define	VELOCITY_DES0_OWN	(1 << 31)
40
+#define	VELOCITY_DES0_TERR	(1 << 15)
41
+#define	VELOCITY_DES0_RXOK	(1 << 15)
42
+#define	VELOCITY_DES0_FDX	(1 << 14)
43
+#define	VELOCITY_DES0_GMII	(1 << 13)
44
+#define	VELOCITY_DES0_LNKFL	(1 << 12)
45
+#define	VELOCITY_DES0_SHDN	(1 << 10)
46
+#define	VELOCITY_DES0_CRS	(1 << 9)
47
+#define	VELOCITY_DES0_CDH	(1 << 8)
48
+#define	VELOCITY_DES0_ABT	(1 << 7)
49
+#define	VELOCITY_DES0_OWT	(1 << 6)
50
+#define	VELOCITY_DES0_OWC	(1 << 5)
51
+#define	VELOCITY_DES0_COLS	(1 << 4)
52
+
53
+#define VELOCITY_DES0_RXSHDN	(1 << 30)
54
+#define VELOCITY_DES0_RXER	(1 << 5)
55
+#define VELOCITY_DES0_RLE	(1 << 4)
56
+#define VELOCITY_DES0_CE	(1 << 3)
57
+#define VELOCITY_DES0_FAE	(1 << 2)
58
+#define VELOCITY_DES0_CRC	(1 << 1)
59
+#define VELOCITY_DES0_RX_ERR	( VELOCITY_DES0_RXER | \
60
+                                  VELOCITY_DES0_RLE | \
61
+                                  VELOCITY_DES0_CE | \
62
+                                  VELOCITY_DES0_FAE | \
63
+                                  VELOCITY_DES0_CRC )
64
+
65
+/** TX descriptor fragment number */
66
+#define	VELOCITY_DES1_FRAG(_n)	(((_n + 1) & 0xf) << 28)
67
+#define	VELOCITY_DES1_TCPLS	((1 << 24) | (1 << 25))
68
+#define	VELOCITY_DES1_INTR	(1 << 23)
69
+#define	VELOCITY_DES1_PIC	(1 << 22)
70
+#define	VELOCITY_DES1_VETAG	(1 << 21)
71
+#define	VELOCITY_DES1_IPCK	(1 << 20)
72
+#define	VELOCITY_DES1_UDPCK	(1 << 19)
73
+#define VELOCITY_DES1_TCPCK	(1 << 18)
74
+#define	VELOCITY_DES1_JMBO	(1 << 17)
75
+#define	VELOCITY_DES1_CRC	(1 << 16)
76
+
77
+#define	VELOCITY_DES2_IC	(1 << 31)
78
+#define	VELOCITY_DES2_SIZE(_n)	(((_n) & 0x1fff) << 16)
79
+
80
+/** Number of receive descriptors
81
+ *
82
+ * Must be a multiple of 4 (hardware requirement).
83
+ */
84
+#define	VELOCITY_RXDESC_NUM	8
85
+#define	VELOCITY_RXDESC_SIZE	\
86
+    ( VELOCITY_RXDESC_NUM * sizeof ( struct velocity_rx_descriptor ) )
87
+
88
+/** Number of transmit descriptors */
89
+#define	VELOCITY_TXDESC_NUM	8
90
+#define	VELOCITY_TXDESC_SIZE	\
91
+    ( VELOCITY_TXDESC_NUM * sizeof ( struct velocity_tx_descriptor ) )
92
+
93
+/** Descriptor alignment */
94
+#define	VELOCITY_RING_ALIGN	64
95
+
96
+/** Receive buffer length */
97
+#define VELOCITY_RX_MAX_LEN 1536
98
+
99
+/** MAC address registers */
100
+#define VELOCITY_MAC0		0x00
101
+#define VELOCITY_MAC1		0x01
102
+#define	VELOCITY_MAC2		0x02
103
+#define VELOCITY_MAC3		0x03
104
+#define	VELOCITY_MAC4		0x04
105
+#define	VELOCITY_MAC5		0x05
106
+
107
+/** Receive control register */
108
+#define VELOCITY_RCR		0x06
109
+#define	RHINE_RCR_SYMERR_ACCEPT	(1 << 7)	/*< Accept symbol error */
110
+#define	RHINE_RCR_FILTER_ACCEPT	(1 << 6)	/*< Accept based on filter */
111
+#define	RHINE_RCR_LONG_ACCEPT	(1 << 5)	/*< Accept long packets */
112
+#define	RHINE_RCR_PROMISC	(1 << 4)	/*< Promiscuous mode */
113
+#define	RHINE_RCR_BCAST_ACCEPT	(1 << 3)	/*< Accept broadcast */
114
+#define	RHINE_RCR_MCAST_ACCEPT	(1 << 2)	/*< Accept multicast */
115
+#define	RHINE_RCR_RUNT_ACCEPT	(1 << 1)	/*< Accept runt frames */
116
+#define	RHINE_RCR_ERR_ACCEPT	(1 << 0)	/*< Accept erroneous frames */
117
+
118
+/** Transmit control register */
119
+#define VELOCITY_TCR			0x07
120
+#define	VELOCITY_TCR_LB0	(1 << 0)	/*< Loopback control */
121
+#define	VELOCITY_TCR_LB1	(1 << 1)	/*< Loopback control */
122
+#define	VELOCITY_TCR_COLTMC0	(1 << 2)	/*< Collision retry control */
123
+#define	VELOCITY_TCR_COLTMC1	(1 << 3)	/*< Collision retry control */
124
+
125
+/** Command register 0 (set) */
126
+#define VELOCITY_CRS0			0x08
127
+#define	VELOCITY_CR0_TXON	(1 << 3)	/*< Transmit enable */
128
+#define	VELOCITY_CR0_RXON	(1 << 2)	/*< Receive enable */
129
+#define	VELOCITY_CR0_STOP	(1 << 1)	/*< Stop NIC */
130
+#define	VELOCITY_CR0_START	(1 << 0)	/*< Start NIC */
131
+
132
+/** Command register 1 (set) */
133
+#define VELOCITY_CRS1			0x09
134
+#define	VELOCITY_CR1_SFRST	(1 << 7)	/*< Software reset */
135
+#define	VELOCITY_CR1_TM1EN	(1 << 6)	/*< Perioding software counting */
136
+#define	VELOCITY_CR1_TM0EN	(1 << 5)	/*< Single-shot software counting */
137
+#define	VELOCITY_CR1_DPOLL	(1 << 3)	/*< Disable auto polling */
138
+#define	VELOCITY_CR1_DISAU	(1 << 0)	/*< Unicast reception disable */
139
+
140
+/** Command register 2 (set) */
141
+#define VELOCITY_CRS2			0x0A
142
+#define	VELOCITY_CR2_XONEN	(1 << 7)	/*< XON/XOFF mode enable */
143
+#define	VELOCITY_CR2_FDXTFCEN	(1 << 6)	/*< FDX flow control TX */
144
+#define	VELOCITY_CR2_FDXRFCEN	(1 << 5)
145
+#define	VELOCITY_CR2_HDXFCEN	(1 << 4)
146
+
147
+/** Command register 3 (set) */
148
+#define VELOCITY_CRS3			0x0B
149
+#define	VELOCITY_CR3_FOSRST		(1 << 6)
150
+#define	VELOCITY_CR3_FPHYRST		(1 << 5)
151
+#define	VELOCITY_CR3_DIAG		(1 << 4)
152
+#define	VELOCITY_CR3_INTPCTL		(1 << 2)
153
+#define	VELOCITY_CR3_GINTMSK1		(1 << 1)
154
+#define	VELOCITY_CR3_SWPEND		(1 << 0)
155
+
156
+/** Command register 0 (clear) */
157
+#define VELOCITY_CRC0			0x0C
158
+
159
+/** Command register 1 (clear) */
160
+#define VELOCITY_CRC1			0x0D
161
+
162
+/** Command register 2 (clear */
163
+#define VELOCITY_CRC2			0x0E
164
+
165
+/** Command register 3 (clear */
166
+#define VELOCITY_CRC3			0x0F
167
+#define VELOCITY_CAM0			0x10
168
+#define VELOCITY_CAM1			0x11
169
+#define VELOCITY_CAM2			0x12
170
+#define VELOCITY_CAM3			0x13
171
+#define VELOCITY_CAM4			0x14
172
+#define VELOCITY_CAM5			0x15
173
+#define VELOCITY_CAM6			0x16
174
+#define VELOCITY_CAM7			0x17
175
+#define VELOCITY_TXDESC_HI		0x18    /* Hi part of 64bit txdesc base addr */
176
+#define VELOCITY_DATABUF_HI		0x1D    /* Hi part of 64bit data buffer addr */
177
+#define VELOCITY_INTCTL0		0x20    /* interrupt control register */
178
+#define VELOCITY_RXSUPPTHR		0x20
179
+#define VELOCITY_TXSUPPTHR		0x20
180
+#define VELOCITY_INTHOLDOFF		0x20
181
+#define VELOCITY_INTCTL1		0x21    /* interrupt control register */
182
+#define VELOCITY_TXHOSTERR		0x22    /* TX host error status */
183
+#define VELOCITY_RXHOSTERR		0x23    /* RX host error status */
184
+
185
+/** Interrupt status register 0 */
186
+#define VELOCITY_ISR0			0x24
187
+#define	VELOCITY_ISR0_PTX3		(1 << 7)
188
+#define	VELOCITY_ISR0_PTX2		(1 << 6)
189
+#define VELOCITY_ISR0_PTX1		(1 << 5)
190
+#define VELOCITY_ISR0_PTX0		(1 << 4)
191
+#define VELOCITY_ISR0_PTXI		(1 << 3)
192
+#define VELOCITY_ISR0_PRXI		(1 << 2)
193
+#define VELOCITY_ISR0_PPTXI		(1 << 1)
194
+#define VELOCITY_ISR0_PPRXI		(1 << 0)
195
+
196
+/** Interrupt status register 1 */
197
+#define VELOCITY_ISR1			0x25
198
+#define VELOCITY_ISR1_SRCI		(1 << 7)
199
+#define VELOCITY_ISR1_LSTPEI		(1 << 6)
200
+#define VELOCITY_ISR1_LSTEI		(1 << 5)
201
+#define VELOCITY_ISR1_OVFL		(1 << 4)
202
+#define VELOCITY_ISR1_FLONI		(1 << 3)
203
+#define VELOCITY_ISR1_RACEI		(1 << 2)
204
+
205
+/** Interrupt status register 2 */
206
+#define VELOCITY_ISR2			0x26
207
+#define VELOCITY_ISR2_HFLD		(1 << 7)
208
+#define VELOCITY_ISR2_UDPI		(1 << 6)
209
+#define VELOCITY_ISR2_MIBFI		(1 << 5)
210
+#define VELOCITY_ISR2_SHDNII		(1 << 4)
211
+#define VELOCITY_ISR2_PHYI		(1 << 3)
212
+#define VELOCITY_ISR2_PWEI		(1 << 2)
213
+#define VELOCITY_ISR2_TMR1I		(1 << 1)
214
+#define VELOCITY_ISR2_TMR0I		(1 << 0)
215
+
216
+/** Interrupt status register 3 */
217
+#define VELOCITY_ISR3			0x27
218
+
219
+/** Interrupt mask register 0 */
220
+#define VELOCITY_IMR0			0x28
221
+
222
+/** Interrupt mask register 1 */
223
+#define VELOCITY_IMR1			0x29
224
+
225
+/** Interrupt mask register 2 */
226
+#define VELOCITY_IMR2			0x2a
227
+
228
+/** Interrupt mask register 3 */
229
+#define VELOCITY_IMR3			0x2b
230
+
231
+#define VELOCITY_TXSTS_PORT		0x2C    /* Transmit status port (???) */
232
+#define VELOCITY_TXQCSRS		0x30    /* TX queue ctl/status set */
233
+
234
+#define	VELOCITY_TXQCSRS_DEAD3		(1 << 15)
235
+#define	VELOCITY_TXQCSRS_WAK3		(1 << 14)
236
+#define	VELOCITY_TXQCSRS_ACT3		(1 << 13)
237
+#define	VELOCITY_TXQCSRS_RUN3		(1 << 12)
238
+#define	VELOCITY_TXQCSRS_DEAD2		(1 << 11)
239
+#define	VELOCITY_TXQCSRS_WAK2		(1 << 10)
240
+#define	VELOCITY_TXQCSRS_ACT2		(1 << 9)
241
+#define	VELOCITY_TXQCSRS_RUN2		(1 << 8)
242
+#define VELOCITY_TXQCSRS_DEAD1		(1 << 7)
243
+#define	VELOCITY_TXQCSRS_WAK1		(1 << 6)
244
+#define	VELOCITY_TXQCSRS_ACT1		(1 << 5)
245
+#define VELOCITY_TXQCSRS_RUN1		(1 << 4)
246
+#define	VELOCITY_TXQCSRS_DEAD0		(1 << 3)
247
+#define	VELOCITY_TXQCSRS_WAK0		(1 << 2)
248
+#define	VELOCITY_TXQCSRS_ACT0		(1 << 1)
249
+#define	VELOCITY_TXQCSRS_RUN0		(1 << 0)
250
+
251
+#define VELOCITY_RXQCSRS		0x32    /* RX queue ctl/status set */
252
+#define VELOCITY_RXQCSRC		0x36
253
+
254
+#define	VELOCITY_RXQCSR_DEAD		(1 << 3)
255
+#define	VELOCITY_RXQCSR_WAK		(1 << 2)
256
+#define	VELOCITY_RXQCSR_ACT		(1 << 1)
257
+#define	VELOCITY_RXQCSR_RUN		(1 << 0)
258
+
259
+#define VELOCITY_TXQCSRC		0x34    /* TX queue ctl/status clear */
260
+#define VELOCITY_RXQCSRC		0x36    /* RX queue ctl/status clear */
261
+#define VELOCITY_RXDESC_ADDR_LO		0x38    /* RX desc base addr (lo 32 bits) */
262
+#define VELOCITY_RXDESC_CONSIDX		0x3C    /* Current RX descriptor index */
263
+#define VELOCITY_TXQTIMER		0x3E    /* TX queue timer pend register */
264
+#define VELOCITY_RXQTIMER		0x3F    /* RX queue timer pend register */
265
+#define VELOCITY_TXDESC_ADDR_LO0	0x40    /* TX desc0 base addr (lo 32 bits) */
266
+#define VELOCITY_TXDESC_ADDR_LO1	0x44    /* TX desc1 base addr (lo 32 bits) */
267
+#define VELOCITY_TXDESC_ADDR_LO2	0x48    /* TX desc2 base addr (lo 32 bits) */
268
+#define VELOCITY_TXDESC_ADDR_LO3	0x4C    /* TX desc3 base addr (lo 32 bits) */
269
+#define VELOCITY_RXDESCNUM		0x50    /* Size of RX desc ring */
270
+#define VELOCITY_TXDESCNUM		0x52    /* Size of TX desc ring */
271
+#define VELOCITY_TXDESC_CONSIDX0	0x54    /* Current TX descriptor index */
272
+#define VELOCITY_TXDESC_CONSIDX1	0x56    /* Current TX descriptor index */
273
+#define VELOCITY_TXDESC_CONSIDX2	0x58    /* Current TX descriptor index */
274
+#define VELOCITY_TXDESC_CONSIDX3	0x5A    /* Current TX descriptor index */
275
+#define VELOCITY_TX_PAUSE_TIMER		0x5C    /* TX pause frame timer */
276
+#define VELOCITY_RXDESC_RESIDUECNT	0x5E    /* RX descriptor residue count */
277
+#define VELOCITY_FIFOTEST0		0x60    /* FIFO test register */
278
+#define VELOCITY_FIFOTEST1		0x64    /* FIFO test register */
279
+#define VELOCITY_CAMADDR		0x68    /* CAM address register */
280
+#define VELOCITY_CAMCTL			0x69    /* CAM control register */
281
+#define VELOCITY_MIICFG			0x6C    /* MII port config register */
282
+#define VELOCITY_MIISR			0x6D    /* MII port status register */
283
+#define	VELOCITY_MIISR_IDLE		(1 << 7)
284
+#define VELOCITY_PHYSTS0		0x6E    /* PHY status register */
285
+#define	VELOCITY_PHYSTS0_LINK		(1 << 6)
286
+#define VELOCITY_PHYSTS1		0x6F    /* PHY status register */
287
+#define VELOCITY_MIICR			0x70    /* MII command register */
288
+#define VELOCITY_MIICR_MAUTO		(1 << 7)
289
+#define VELOCITY_MIICR_RCMD		(1 << 6)
290
+#define VELOCITY_MIICR_WCMD		(1 << 5)
291
+#define VELOCITY_MIICR_MDPM		(1 << 4)
292
+#define VELOCITY_MIICR_MOUT		(1 << 3)
293
+#define VELOCITY_MIICR_MDO		(1 << 2)
294
+#define VELOCITY_MIICR_MDI		(1 << 1)
295
+#define VELOCITY_MIICR_MDC		(1 << 0)
296
+
297
+#define VELOCITY_MIIADDR		0x71    /* MII address register */
298
+#define VELOCITY_MIIDATA		0x72    /* MII data register */
299
+#define VELOCITY_SSTIMER		0x74    /* single-shot timer */
300
+#define VELOCITY_PTIMER			0x76    /* periodic timer */
301
+#define VELOCITY_DMACFG0		0x7C    /* DMA config 0 */
302
+#define VELOCITY_DMACFG1		0x7D    /* DMA config 1 */
303
+#define VELOCITY_RXCFG			0x7E    /* MAC RX config */
304
+#define VELOCITY_TXCFG			0x7F    /* MAC TX config */
305
+#define VELOCITY_SWEEDATA		0x85    /* EEPROM software loaded data */
306
+
307
+/** Chip Configuration Register A */
308
+#define VELOCITY_CFGA			0x78
309
+#define VELOCITY_CFGA_PACPI		(1 << 0)
310
+
311
+/** Power Management Sticky Register */
312
+#define VELOCITY_STICKY			0x83
313
+#define VELOCITY_STICKY_DS0		(1 << 0)
314
+#define VELOCITY_STICKY_DS1		(1 << 1)
315
+
316
+#define VELOCITY_EEWRDAT		0x8C    /* EEPROM embedded write */
317
+#define VELOCITY_EECSUM			0x92    /* EEPROM checksum */
318
+#define VELOCITY_EECSR			0x93    /* EEPROM control/status */
319
+#define	VELOCITY_EECSR_RELOAD		(1 << 5)
320
+#define VELOCITY_EERDDAT		0x94    /* EEPROM embedded read */
321
+#define VELOCITY_EEADDR			0x96    /* EEPROM address */
322
+#define VELOCITY_EECMD			0x97    /* EEPROM embedded command */
323
+
324
+/** A Velocity network card */
325
+struct velocity_nic {
326
+	/** Registers */
327
+	void *regs;
328
+	/** MII interface */
329
+	struct mii_interface mii;
330
+	/** Netdev */
331
+	struct net_device *netdev;
332
+
333
+	/** Receive descriptor ring */
334
+	struct velocity_rx_descriptor *rx_ring;
335
+	/** Receive I/O buffers */
336
+	struct io_buffer *rx_buffs[VELOCITY_RXDESC_NUM];
337
+	/** Receive producer index */
338
+	unsigned int rx_prod;
339
+	/** Receive consumer index */
340
+	unsigned int rx_cons;
341
+	/** Receive commit number
342
+	  *
343
+	  * Used to fullfill the hardware requirement of returning receive buffers
344
+	  * to the hardware only in blocks of 4.
345
+	  */
346
+	unsigned int rx_commit;
347
+
348
+	/** Transmit descriptor ring */
349
+	struct velocity_tx_descriptor *tx_ring;
350
+	/** Transmit producer index */
351
+	unsigned int tx_prod;
352
+	/** Transmit consumer index */
353
+	unsigned int tx_cons;
354
+};
355
+
356
+#endif /* _VELOCITY_H */

+ 0
- 1927
src/drivers/net/via-velocity.c
File diff suppressed because it is too large
View File


+ 0
- 1932
src/drivers/net/via-velocity.h
File diff suppressed because it is too large
View File


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

@@ -114,7 +114,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
114 114
 #define ERRFILE_tlan		     ( ERRFILE_DRIVER | 0x00420000 )
115 115
 #define ERRFILE_tulip		     ( ERRFILE_DRIVER | 0x00430000 )
116 116
 #define ERRFILE_rhine		     ( ERRFILE_DRIVER | 0x00440000 )
117
-#define ERRFILE_via_velocity	     ( ERRFILE_DRIVER | 0x00450000 )
117
+#define ERRFILE_velocity	     ( ERRFILE_DRIVER | 0x00450000 )
118 118
 #define ERRFILE_w89c840		     ( ERRFILE_DRIVER | 0x00460000 )
119 119
 #define ERRFILE_ipoib		     ( ERRFILE_DRIVER | 0x00470000 )
120 120
 #define ERRFILE_e1000_main	     ( ERRFILE_DRIVER | 0x00480000 )

Loading…
Cancel
Save