Browse Source

[realtek] Support RTL8139 cards within generic Realtek driver

RTL8139C+ cards use essentially the same datapath as RTL8169, which is
zerocopy and 64-bit capable.  Older RTL8139 cards use a single receive
ring buffer rather than a descriptor ring, but still share substantial
amounts of functionality with RTL8169.

Include support for RTL8139 cards within the generic Realtek driver,
since there is no way to differentiate between RTL8139 and RTL8139C+
cards based on the PCI IDs alone.

Many thanks to all the people who worked on the rtl8139 driver over
the years.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
f8bb40b002
3 changed files with 400 additions and 649 deletions
  1. 315
    36
      src/drivers/net/realtek.c
  2. 85
    17
      src/drivers/net/realtek.h
  3. 0
    596
      src/drivers/net/rtl8139.c

+ 315
- 36
src/drivers/net/realtek.c View File

78
 	uint8_t mask = realtek_eeprom_bits[bit_id];
78
 	uint8_t mask = realtek_eeprom_bits[bit_id];
79
 	uint8_t reg;
79
 	uint8_t reg;
80
 
80
 
81
+	DBG_DISABLE ( DBGLVL_IO );
81
 	reg = readb ( rtl->regs + RTL_9346CR );
82
 	reg = readb ( rtl->regs + RTL_9346CR );
83
+	DBG_ENABLE ( DBGLVL_IO );
82
 	return ( reg & mask );
84
 	return ( reg & mask );
83
 }
85
 }
84
 
86
 
96
 	uint8_t mask = realtek_eeprom_bits[bit_id];
98
 	uint8_t mask = realtek_eeprom_bits[bit_id];
97
 	uint8_t reg;
99
 	uint8_t reg;
98
 
100
 
101
+	DBG_DISABLE ( DBGLVL_IO );
99
 	reg = readb ( rtl->regs + RTL_9346CR );
102
 	reg = readb ( rtl->regs + RTL_9346CR );
100
 	reg &= ~mask;
103
 	reg &= ~mask;
101
 	reg |= ( data & mask );
104
 	reg |= ( data & mask );
102
 	writeb ( reg, rtl->regs + RTL_9346CR );
105
 	writeb ( reg, rtl->regs + RTL_9346CR );
106
+	DBG_ENABLE ( DBGLVL_IO );
103
 }
107
 }
104
 
108
 
105
 /** SPI bit-bashing interface */
109
 /** SPI bit-bashing interface */
165
 	unsigned int i;
169
 	unsigned int i;
166
 	uint32_t value;
170
 	uint32_t value;
167
 
171
 
172
+	/* Fail if PHYAR register is not present */
173
+	if ( ! rtl->have_phy_regs )
174
+		return -ENOTSUP;
175
+
168
 	/* Initiate read */
176
 	/* Initiate read */
169
 	writel ( RTL_PHYAR_VALUE ( 0, reg, 0 ), rtl->regs + RTL_PHYAR );
177
 	writel ( RTL_PHYAR_VALUE ( 0, reg, 0 ), rtl->regs + RTL_PHYAR );
170
 
178
 
199
 	struct realtek_nic *rtl = container_of ( mii, struct realtek_nic, mii );
207
 	struct realtek_nic *rtl = container_of ( mii, struct realtek_nic, mii );
200
 	unsigned int i;
208
 	unsigned int i;
201
 
209
 
210
+	/* Fail if PHYAR register is not present */
211
+	if ( ! rtl->have_phy_regs )
212
+		return -ENOTSUP;
213
+
202
 	/* Initiate write */
214
 	/* Initiate write */
203
 	writel ( RTL_PHYAR_VALUE ( RTL_PHYAR_FLAG, reg, data ),
215
 	writel ( RTL_PHYAR_VALUE ( RTL_PHYAR_FLAG, reg, data ),
204
 		 rtl->regs + RTL_PHYAR );
216
 		 rtl->regs + RTL_PHYAR );
253
 			continue;
265
 			continue;
254
 		}
266
 		}
255
 
267
 
256
-		/* Enable PCI Dual Address Cycle (for 64-bit systems) */
257
-		writew ( ( RTL_CPCR_DAC | RTL_CPCR_MULRW ),
258
-			 rtl->regs + RTL_CPCR );
259
-
260
 		return 0;
268
 		return 0;
261
 	}
269
 	}
262
 
270
 
278
  */
286
  */
279
 static void realtek_check_link ( struct net_device *netdev ) {
287
 static void realtek_check_link ( struct net_device *netdev ) {
280
 	struct realtek_nic *rtl = netdev->priv;
288
 	struct realtek_nic *rtl = netdev->priv;
289
+	uint8_t phystatus;
290
+	uint8_t msr;
291
+	int link_up;
292
+
293
+	/* Determine link state */
294
+	if ( rtl->have_phy_regs ) {
295
+		phystatus = readb ( rtl->regs + RTL_PHYSTATUS );
296
+		link_up = ( phystatus & RTL_PHYSTATUS_LINKSTS );
297
+		DBGC ( rtl, "REALTEK %p PHY status is %02x\n", rtl, phystatus );
298
+	} else {
299
+		msr = readb ( rtl->regs + RTL_MSR );
300
+		link_up = ( ! ( msr & RTL_MSR_LINKB ) );
301
+		DBGC ( rtl, "REALTEK %p media status is %02x\n", rtl, msr );
302
+	}
281
 
303
 
282
-	if ( readb ( rtl->regs + RTL_PHYSTATUS ) & RTL_PHYSTATUS_LINKSTS ) {
304
+	/* Report link state */
305
+	if ( link_up ) {
283
 		netdev_link_up ( netdev );
306
 		netdev_link_up ( netdev );
284
 	} else {
307
 	} else {
285
 		netdev_link_down ( netdev );
308
 		netdev_link_down ( netdev );
293
  ******************************************************************************
316
  ******************************************************************************
294
  */
317
  */
295
 
318
 
319
+/**
320
+ * Create receive buffer (legacy mode)
321
+ *
322
+ * @v rtl		Realtek device
323
+ * @ret rc		Return status code
324
+ */
325
+static int realtek_create_buffer ( struct realtek_nic *rtl ) {
326
+	size_t len = ( RTL_RXBUF_LEN + RTL_RXBUF_PAD );
327
+	physaddr_t address;
328
+	int rc;
329
+
330
+	/* Do nothing unless in legacy mode */
331
+	if ( ! rtl->legacy )
332
+		return 0;
333
+
334
+	/* Allocate buffer */
335
+	rtl->rx_buffer = malloc_dma ( len, RTL_RXBUF_ALIGN );
336
+	if ( ! rtl->rx_buffer ) {
337
+		rc = -ENOMEM;
338
+		goto err_alloc;
339
+	}
340
+	address = virt_to_bus ( rtl->rx_buffer );
341
+
342
+	/* Check that card can support address */
343
+	if ( address & ~0xffffffffULL ) {
344
+		DBGC ( rtl, "REALTEK %p cannot support 64-bit RX buffer "
345
+		       "address\n", rtl );
346
+		rc = -ENOTSUP;
347
+		goto err_64bit;
348
+	}
349
+
350
+	/* Program buffer address */
351
+	writel ( address, rtl->regs + RTL_RBSTART );
352
+	DBGC ( rtl, "REALTEK %p receive buffer is at [%08llx,%08llx,%08llx)\n",
353
+	       rtl, ( ( unsigned long long ) address ),
354
+	       ( ( unsigned long long ) address + RTL_RXBUF_LEN ),
355
+	       ( ( unsigned long long ) address + len ) );
356
+
357
+	return 0;
358
+
359
+ err_64bit:
360
+	free_dma ( rtl->rx_buffer, len );
361
+	rtl->rx_buffer = NULL;
362
+ err_alloc:
363
+	return rc;
364
+}
365
+
366
+/**
367
+ * Destroy receive buffer (legacy mode)
368
+ *
369
+ * @v rtl		Realtek device
370
+ */
371
+static void realtek_destroy_buffer ( struct realtek_nic *rtl ) {
372
+	size_t len = ( RTL_RXBUF_LEN + RTL_RXBUF_PAD );
373
+
374
+	/* Do nothing unless in legacy mode */
375
+	if ( ! rtl->legacy )
376
+		return;
377
+
378
+	/* Clear buffer address */
379
+	writel ( 0, rtl->regs + RTL_RBSTART );
380
+
381
+	/* Free buffer */
382
+	free_dma ( rtl->rx_buffer, len );
383
+	rtl->rx_buffer = NULL;
384
+	rtl->rx_offset = 0;
385
+}
386
+
296
 /**
387
 /**
297
  * Create descriptor ring
388
  * Create descriptor ring
298
  *
389
  *
304
 				 struct realtek_ring *ring ) {
395
 				 struct realtek_ring *ring ) {
305
 	physaddr_t address;
396
 	physaddr_t address;
306
 
397
 
398
+	/* Do nothing in legacy mode */
399
+	if ( rtl->legacy )
400
+		return 0;
401
+
307
 	/* Allocate descriptor ring */
402
 	/* Allocate descriptor ring */
308
 	ring->desc = malloc_dma ( ring->len, RTL_RING_ALIGN );
403
 	ring->desc = malloc_dma ( ring->len, RTL_RING_ALIGN );
309
 	if ( ! ring->desc )
404
 	if ( ! ring->desc )
335
 static void realtek_destroy_ring ( struct realtek_nic *rtl,
430
 static void realtek_destroy_ring ( struct realtek_nic *rtl,
336
 				   struct realtek_ring *ring ) {
431
 				   struct realtek_ring *ring ) {
337
 
432
 
433
+	/* Do nothing in legacy mode */
434
+	if ( rtl->legacy )
435
+		return;
436
+
338
 	/* Clear ring address */
437
 	/* Clear ring address */
339
 	writel ( 0, rtl->regs + ring->reg );
438
 	writel ( 0, rtl->regs + ring->reg );
340
 	writel ( 0, rtl->regs + ring->reg + 4 );
439
 	writel ( 0, rtl->regs + ring->reg + 4 );
358
 	physaddr_t address;
457
 	physaddr_t address;
359
 	int is_last;
458
 	int is_last;
360
 
459
 
460
+	/* Do nothing in legacy mode */
461
+	if ( rtl->legacy )
462
+		return;
463
+
361
 	while ( ( rtl->rx.prod - rtl->rx.cons ) < RTL_NUM_RX_DESC ) {
464
 	while ( ( rtl->rx.prod - rtl->rx.cons ) < RTL_NUM_RX_DESC ) {
362
 
465
 
363
 		/* Allocate I/O buffer */
466
 		/* Allocate I/O buffer */
410
 	if ( ( rc = realtek_create_ring ( rtl, &rtl->rx ) ) != 0 )
513
 	if ( ( rc = realtek_create_ring ( rtl, &rtl->rx ) ) != 0 )
411
 		goto err_create_rx;
514
 		goto err_create_rx;
412
 
515
 
413
-	/* Configure MTU */
414
-	writew ( RTL_RX_MAX_LEN, rtl->regs + RTL_RMS );
516
+	/* Create receive buffer */
517
+	if ( ( rc = realtek_create_buffer ( rtl ) ) != 0 )
518
+		goto err_create_buffer;
415
 
519
 
416
 	/* Accept all packets */
520
 	/* Accept all packets */
417
 	writel ( 0xffffffffUL, rtl->regs + RTL_MAR0 );
521
 	writel ( 0xffffffffUL, rtl->regs + RTL_MAR0 );
418
 	writel ( 0xffffffffUL, rtl->regs + RTL_MAR4 );
522
 	writel ( 0xffffffffUL, rtl->regs + RTL_MAR4 );
523
+
524
+	/* Enable transmitter and receiver.  RTL8139 requires that
525
+	 * this happens before writing to RCR.
526
+	 */
527
+	writeb ( ( RTL_CR_TE | RTL_CR_RE ), rtl->regs + RTL_CR );
528
+
529
+	/* Configure receiver */
419
 	rcr = readl ( rtl->regs + RTL_RCR );
530
 	rcr = readl ( rtl->regs + RTL_RCR );
420
-	writel ( ( rcr | RTL_RCR_AB | RTL_RCR_AM | RTL_RCR_APM | RTL_RCR_AAP ),
421
-		 rtl->regs + RTL_RCR );
531
+	rcr &= ~( RTL_RCR_RBLEN_MASK );
532
+	rcr |= ( RTL_RCR_RBLEN_DEFAULT | RTL_RCR_WRAP | RTL_RCR_AB |
533
+		 RTL_RCR_AM | RTL_RCR_APM | RTL_RCR_AAP );
534
+	writel ( rcr, rtl->regs + RTL_RCR );
422
 
535
 
423
 	/* Fill receive ring */
536
 	/* Fill receive ring */
424
 	realtek_refill_rx ( rtl );
537
 	realtek_refill_rx ( rtl );
425
 
538
 
426
-	/* Enable transmitter and receiver */
427
-	writeb ( ( RTL_CR_TE | RTL_CR_RE ), rtl->regs + RTL_CR );
428
-
429
 	/* Update link state */
539
 	/* Update link state */
430
 	realtek_check_link ( netdev );
540
 	realtek_check_link ( netdev );
431
 
541
 
432
 	return 0;
542
 	return 0;
433
 
543
 
544
+	realtek_destroy_buffer ( rtl );
545
+ err_create_buffer:
434
 	realtek_destroy_ring ( rtl, &rtl->rx );
546
 	realtek_destroy_ring ( rtl, &rtl->rx );
435
  err_create_rx:
547
  err_create_rx:
436
 	realtek_destroy_ring ( rtl, &rtl->tx );
548
 	realtek_destroy_ring ( rtl, &rtl->tx );
450
 	/* Disable receiver and transmitter */
562
 	/* Disable receiver and transmitter */
451
 	writeb ( 0, rtl->regs + RTL_CR );
563
 	writeb ( 0, rtl->regs + RTL_CR );
452
 
564
 
565
+	/* Destroy receive buffer */
566
+	realtek_destroy_buffer ( rtl );
567
+
453
 	/* Destroy receive descriptor ring */
568
 	/* Destroy receive descriptor ring */
454
 	realtek_destroy_ring ( rtl, &rtl->rx );
569
 	realtek_destroy_ring ( rtl, &rtl->rx );
455
 
570
 
485
 		return -ENOBUFS;
600
 		return -ENOBUFS;
486
 	}
601
 	}
487
 	tx_idx = ( rtl->tx.prod++ % RTL_NUM_TX_DESC );
602
 	tx_idx = ( rtl->tx.prod++ % RTL_NUM_TX_DESC );
488
-	is_last = ( tx_idx == ( RTL_NUM_TX_DESC - 1 ) );
489
-	tx = &rtl->tx.desc[tx_idx];
490
 
603
 
491
-	/* Populate transmit descriptor */
492
-	address = virt_to_bus ( iobuf->data );
493
-	tx->address = cpu_to_le64 ( address );
494
-	tx->length = cpu_to_le16 ( iob_len ( iobuf ) );
495
-	wmb();
496
-	tx->flags = ( cpu_to_le16 ( RTL_DESC_OWN | RTL_DESC_FS | RTL_DESC_LS ) |
497
-		      ( is_last ? cpu_to_le16 ( RTL_DESC_EOR ) : 0 ) );
498
-	wmb();
604
+	/* Transmit packet */
605
+	if ( rtl->legacy ) {
499
 
606
 
500
-	/* Notify card that there are packets ready to transmit */
501
-	writeb ( RTL_TPPOLL_NPQ, rtl->regs + RTL_TPPOLL );
607
+		/* Pad and align packet */
608
+		iob_pad ( iobuf, ETH_ZLEN );
609
+		address = virt_to_bus ( iobuf->data );
610
+
611
+		/* Check that card can support address */
612
+		if ( address & ~0xffffffffULL ) {
613
+			DBGC ( rtl, "REALTEK %p cannot support 64-bit TX "
614
+			       "buffer address\n", rtl );
615
+			return -ENOTSUP;
616
+		}
617
+
618
+		/* Add to transmit ring */
619
+		writel ( address, rtl->regs + RTL_TSAD ( tx_idx ) );
620
+		writel ( ( RTL_TSD_ERTXTH_DEFAULT | iob_len ( iobuf ) ),
621
+			 rtl->regs + RTL_TSD ( tx_idx ) );
622
+
623
+	} else {
624
+
625
+		/* Populate transmit descriptor */
626
+		address = virt_to_bus ( iobuf->data );
627
+		is_last = ( tx_idx == ( RTL_NUM_TX_DESC - 1 ) );
628
+		tx = &rtl->tx.desc[tx_idx];
629
+		tx->address = cpu_to_le64 ( address );
630
+		tx->length = cpu_to_le16 ( iob_len ( iobuf ) );
631
+		wmb();
632
+		tx->flags = ( cpu_to_le16 ( RTL_DESC_OWN | RTL_DESC_FS |
633
+					    RTL_DESC_LS ) |
634
+			      ( is_last ? cpu_to_le16 ( RTL_DESC_EOR ) : 0 ) );
635
+		wmb();
636
+
637
+		/* Notify card that there are packets ready to transmit */
638
+		writeb ( RTL_TPPOLL_NPQ, rtl->regs + rtl->tppoll );
639
+	}
502
 
640
 
503
 	DBGC2 ( rtl, "REALTEK %p TX %d is [%llx,%llx)\n", rtl, tx_idx,
641
 	DBGC2 ( rtl, "REALTEK %p TX %d is [%llx,%llx)\n", rtl, tx_idx,
504
-		( ( unsigned long long ) address ),
505
-		( ( unsigned long long ) address + iob_len ( iobuf ) ) );
642
+		( ( unsigned long long ) virt_to_bus ( iobuf->data ) ),
643
+		( ( ( unsigned long long ) virt_to_bus ( iobuf->data ) ) +
644
+		  iob_len ( iobuf ) ) );
506
 
645
 
507
 	return 0;
646
 	return 0;
508
 }
647
 }
522
 
661
 
523
 		/* Get next transmit descriptor */
662
 		/* Get next transmit descriptor */
524
 		tx_idx = ( rtl->tx.cons % RTL_NUM_TX_DESC );
663
 		tx_idx = ( rtl->tx.cons % RTL_NUM_TX_DESC );
525
-		tx = &rtl->tx.desc[tx_idx];
526
 
664
 
527
 		/* Stop if descriptor is still in use */
665
 		/* Stop if descriptor is still in use */
528
-		if ( tx->flags & cpu_to_le16 ( RTL_DESC_OWN ) )
529
-			return;
666
+		if ( rtl->legacy ) {
667
+
668
+			/* Check ownership bit in transmit status register */
669
+			if ( ! ( readl ( rtl->regs + RTL_TSD ( tx_idx ) ) &
670
+				 RTL_TSD_OWN ) )
671
+				return;
672
+
673
+		} else {
674
+
675
+			/* Check ownership bit in descriptor */
676
+			tx = &rtl->tx.desc[tx_idx];
677
+			if ( tx->flags & cpu_to_le16 ( RTL_DESC_OWN ) )
678
+				return;
679
+		}
530
 
680
 
531
 		DBGC2 ( rtl, "REALTEK %p TX %d complete\n", rtl, tx_idx );
681
 		DBGC2 ( rtl, "REALTEK %p TX %d complete\n", rtl, tx_idx );
532
 
682
 
536
 	}
686
 	}
537
 }
687
 }
538
 
688
 
689
+/**
690
+ * Poll for received packets (legacy mode)
691
+ *
692
+ * @v netdev		Network device
693
+ */
694
+static void realtek_legacy_poll_rx ( struct net_device *netdev ) {
695
+	struct realtek_nic *rtl = netdev->priv;
696
+	struct realtek_legacy_header *rx;
697
+	struct io_buffer *iobuf;
698
+	size_t len;
699
+
700
+	/* Check for received packets */
701
+	while ( ! ( readb ( rtl->regs + RTL_CR ) & RTL_CR_BUFE ) ) {
702
+
703
+		/* Extract packet from receive buffer */
704
+		rx = ( rtl->rx_buffer + rtl->rx_offset );
705
+		len = le16_to_cpu ( rx->length );
706
+		if ( rx->status & cpu_to_le16 ( RTL_STAT_ROK ) ) {
707
+
708
+			DBGC2 ( rtl, "REALTEK %p RX offset %x+%zx\n",
709
+				rtl, rtl->rx_offset, len );
710
+
711
+			/* Allocate I/O buffer */
712
+			iobuf = alloc_iob ( len );
713
+			if ( ! iobuf ) {
714
+				netdev_rx_err ( netdev, NULL, -ENOMEM );
715
+				/* Leave packet for next poll */
716
+				break;
717
+			}
718
+
719
+			/* Copy data to I/O buffer */
720
+			memcpy ( iob_put ( iobuf, len ), rx->data, len );
721
+			iob_unput ( iobuf, 4 /* strip CRC */ );
722
+
723
+			/* Hand off to network stack */
724
+			netdev_rx ( netdev, iobuf );
725
+
726
+		} else {
727
+
728
+			DBGC ( rtl, "REALTEK %p RX offset %x+%zx error %04x\n",
729
+			       rtl, rtl->rx_offset, len,
730
+			       le16_to_cpu ( rx->status ) );
731
+			netdev_rx_err ( netdev, NULL, -EIO );
732
+		}
733
+
734
+		/* Update buffer offset */
735
+		rtl->rx_offset = ( rtl->rx_offset + sizeof ( *rx ) + len );
736
+		rtl->rx_offset = ( ( rtl->rx_offset + 3 ) & ~3 );
737
+		rtl->rx_offset = ( rtl->rx_offset % RTL_RXBUF_LEN );
738
+		writew ( ( rtl->rx_offset - 16 ), rtl->regs + RTL_CAPR );
739
+	}
740
+}
741
+
539
 /**
742
 /**
540
  * Poll for received packets
743
  * Poll for received packets
541
  *
744
  *
548
 	unsigned int rx_idx;
751
 	unsigned int rx_idx;
549
 	size_t len;
752
 	size_t len;
550
 
753
 
754
+	/* Poll receive buffer if in legacy mode */
755
+	if ( rtl->legacy ) {
756
+		realtek_legacy_poll_rx ( netdev );
757
+		return;
758
+	}
759
+
551
 	/* Check for received packets */
760
 	/* Check for received packets */
552
 	while ( rtl->rx.cons != rtl->rx.prod ) {
761
 	while ( rtl->rx.cons != rtl->rx.prod ) {
553
 
762
 
641
  ******************************************************************************
850
  ******************************************************************************
642
  */
851
  */
643
 
852
 
853
+/**
854
+ * Detect device type
855
+ *
856
+ * @v rtl		Realtek device
857
+ */
858
+static void realtek_detect ( struct realtek_nic *rtl ) {
859
+	uint16_t rms;
860
+	uint16_t check_rms;
861
+	uint16_t cpcr;
862
+	uint16_t check_cpcr;
863
+
864
+	/* The RX Packet Maximum Size register is present only on
865
+	 * 8169.  Try to set to our intended MTU.
866
+	 */
867
+	rms = RTL_RX_MAX_LEN;
868
+	writew ( rms, rtl->regs + RTL_RMS );
869
+	check_rms = readw ( rtl->regs + RTL_RMS );
870
+
871
+	/* The C+ Command register is present only on 8169 and 8139C+.
872
+	 * Try to enable C+ mode and PCI Dual Address Cycle (for
873
+	 * 64-bit systems), if supported.
874
+	 */
875
+	cpcr = ( RTL_CPCR_DAC | RTL_CPCR_MULRW | RTL_CPCR_CPRX |
876
+		 RTL_CPCR_CPTX );
877
+	writew ( cpcr, rtl->regs + RTL_CPCR );
878
+	check_cpcr = readw ( rtl->regs + RTL_CPCR );
879
+
880
+	/* Detect device type */
881
+	if ( check_rms == rms ) {
882
+		DBGC ( rtl, "REALTEK %p appears to be an RTL8169\n", rtl );
883
+		rtl->have_phy_regs = 1;
884
+		rtl->tppoll = RTL_TPPOLL_8169;
885
+	} else {
886
+		if ( check_cpcr == cpcr ) {
887
+			DBGC ( rtl, "REALTEK %p appears to be an RTL8139C+\n",
888
+			       rtl );
889
+			rtl->tppoll = RTL_TPPOLL_8139CP;
890
+		} else {
891
+			DBGC ( rtl, "REALTEK %p appears to be an RTL8139\n",
892
+			       rtl );
893
+			rtl->legacy = 1;
894
+		}
895
+	}
896
+}
897
+
644
 /**
898
 /**
645
  * Probe PCI device
899
  * Probe PCI device
646
  *
900
  *
677
 	if ( ( rc = realtek_reset ( rtl ) ) != 0 )
931
 	if ( ( rc = realtek_reset ( rtl ) ) != 0 )
678
 		goto err_reset;
932
 		goto err_reset;
679
 
933
 
934
+	/* Detect device type */
935
+	realtek_detect ( rtl );
936
+
680
 	/* Initialise EEPROM */
937
 	/* Initialise EEPROM */
681
 	realtek_init_eeprom ( netdev );
938
 	realtek_init_eeprom ( netdev );
682
 
939
 
700
 
957
 
701
 	/* Initialise and reset MII interface */
958
 	/* Initialise and reset MII interface */
702
 	mii_init ( &rtl->mii, &realtek_mii_operations );
959
 	mii_init ( &rtl->mii, &realtek_mii_operations );
703
-	if ( ( rc = mii_reset ( &rtl->mii ) ) != 0 ) {
960
+	if ( rtl->have_phy_regs &&
961
+	     ( ( rc = mii_reset ( &rtl->mii ) ) != 0 ) ) {
704
 		DBGC ( rtl, "REALTEK %p could not reset MII: %s\n",
962
 		DBGC ( rtl, "REALTEK %p could not reset MII: %s\n",
705
 		       rtl, strerror ( rc ) );
963
 		       rtl, strerror ( rc ) );
706
 		goto err_mii_reset;
964
 		goto err_mii_reset;
761
 
1019
 
762
 /** Realtek PCI device IDs */
1020
 /** Realtek PCI device IDs */
763
 static struct pci_device_id realtek_nics[] = {
1021
 static struct pci_device_id realtek_nics[] = {
764
-	PCI_ROM ( 0x10ec, 0x8129, "r8129",	"RTL-8129", 0 ),
765
-	PCI_ROM ( 0x10ec, 0x8136, "r8136",	"RTL8101E/RTL8102E", 0 ),
766
-	PCI_ROM ( 0x10ec, 0x8167, "r8167",	"RTL-8110SC/8169SC", 0 ),
767
-	PCI_ROM ( 0x10ec, 0x8168, "r8168",	"RTL8111/8168B", 0 ),
768
-	PCI_ROM ( 0x10ec, 0x8169, "r8169",	"RTL-8169", 0 ),
1022
+	PCI_ROM ( 0x0001, 0x8168, "clone8169",	"Cloned 8169", 0 ),
1023
+	PCI_ROM ( 0x018a, 0x0106, "fpc0106tx",	"LevelOne FPC-0106TX", 0 ),
1024
+	PCI_ROM ( 0x021b, 0x8139, "hne300",	"Compaq HNE-300", 0 ),
1025
+	PCI_ROM ( 0x02ac, 0x1012, "s1012",	"SpeedStream 1012", 0 ),
1026
+	PCI_ROM ( 0x0357, 0x000a, "ttpmon",	"TTTech TTP-Monitoring", 0 ),
1027
+	PCI_ROM ( 0x10ec, 0x8129, "rtl8129",	"RTL-8129", 0 ),
1028
+	PCI_ROM ( 0x10ec, 0x8136, "rtl8136",	"RTL8101E/RTL8102E", 0 ),
1029
+	PCI_ROM ( 0x10ec, 0x8138, "rtl8138",	"RT8139 (B/C)", 0 ),
1030
+	PCI_ROM ( 0x10ec, 0x8139, "rtl8139",	"RTL-8139/8139C/8139C+", 0 ),
1031
+	PCI_ROM ( 0x10ec, 0x8167, "rtl8167",	"RTL-8110SC/8169SC", 0 ),
1032
+	PCI_ROM ( 0x10ec, 0x8168, "rtl8168",	"RTL8111/8168B", 0 ),
1033
+	PCI_ROM ( 0x10ec, 0x8169, "rtl8169",	"RTL-8169", 0 ),
1034
+	PCI_ROM ( 0x1113, 0x1211, "smc1211",	"SMC2-1211TX", 0 ),
1035
+	PCI_ROM ( 0x1186, 0x1300, "dfe538",	"DFE530TX+/DFE538TX", 0 ),
1036
+	PCI_ROM ( 0x1186, 0x1340, "dfe690",	"DFE-690TXD", 0 ),
769
 	PCI_ROM ( 0x1186, 0x4300, "dge528t",	"DGE-528T", 0 ),
1037
 	PCI_ROM ( 0x1186, 0x4300, "dge528t",	"DGE-528T", 0 ),
1038
+	PCI_ROM ( 0x11db, 0x1234, "sega8139",	"Sega Enterprises 8139", 0 ),
1039
+	PCI_ROM ( 0x1259, 0xa117, "allied8139",	"Allied Telesyn 8139", 0 ),
1040
+	PCI_ROM ( 0x1259, 0xa11e, "allied81xx",	"Allied Telesyn 81xx", 0 ),
770
 	PCI_ROM ( 0x1259, 0xc107, "allied8169",	"Allied Telesyn 8169", 0 ),
1041
 	PCI_ROM ( 0x1259, 0xc107, "allied8169",	"Allied Telesyn 8169", 0 ),
1042
+	PCI_ROM ( 0x126c, 0x1211, "northen8139","Northern Telecom 8139", 0 ),
1043
+	PCI_ROM ( 0x13d1, 0xab06, "fe2000vx",	"Abocom FE2000VX", 0 ),
1044
+	PCI_ROM ( 0x1432, 0x9130, "edi8139",	"Edimax 8139", 0 ),
1045
+	PCI_ROM ( 0x14ea, 0xab06, "fnw3603tx",	"Planex FNW-3603-TX", 0 ),
1046
+	PCI_ROM ( 0x14ea, 0xab07, "fnw3800tx",	"Planex FNW-3800-TX", 0 ),
1047
+	PCI_ROM ( 0x1500, 0x1360, "delta8139",	"Delta Electronics 8139", 0 ),
771
 	PCI_ROM ( 0x16ec, 0x0116, "usr997902",	"USR997902", 0 ),
1048
 	PCI_ROM ( 0x16ec, 0x0116, "usr997902",	"USR997902", 0 ),
772
 	PCI_ROM ( 0x1737, 0x1032, "linksys8169","Linksys 8169", 0 ),
1049
 	PCI_ROM ( 0x1737, 0x1032, "linksys8169","Linksys 8169", 0 ),
773
-	PCI_ROM ( 0x0001, 0x8168, "clone8169",	"Cloned 8169", 0 ),
1050
+	PCI_ROM ( 0x1743, 0x8139, "rolf100",	"Peppercorn ROL/F-100", 0 ),
1051
+	PCI_ROM ( 0x4033, 0x1360, "addron8139",	"Addtron 8139", 0 ),
1052
+	PCI_ROM ( 0xffff, 0x8139, "clonse8139",	"Cloned 8139", 0 ),
774
 };
1053
 };
775
 
1054
 
776
 /** Realtek PCI driver */
1055
 /** Realtek PCI driver */

+ 85
- 17
src/drivers/net/realtek.h View File

49
 /** Descriptor ring alignment */
49
 /** Descriptor ring alignment */
50
 #define RTL_RING_ALIGN 256
50
 #define RTL_RING_ALIGN 256
51
 
51
 
52
+/** A legacy mode receive packet header */
53
+struct realtek_legacy_header {
54
+	/** Status */
55
+	uint16_t status;
56
+	/** Length */
57
+	uint16_t length;
58
+	/** Packet data */
59
+	uint8_t data[0];
60
+} __attribute__ (( packed ));
61
+
62
+/** Legacy mode status bits */
63
+enum realtek_legacy_status {
64
+	/** Received OK */
65
+	RTL_STAT_ROK = 0x0001,
66
+};
67
+
52
 /** ID Register 0 (6 bytes) */
68
 /** ID Register 0 (6 bytes) */
53
 #define RTL_IDR0 0x00
69
 #define RTL_IDR0 0x00
54
 
70
 
58
 /** Multicast Register 4 (dword) */
74
 /** Multicast Register 4 (dword) */
59
 #define RTL_MAR4 0x0c
75
 #define RTL_MAR4 0x0c
60
 
76
 
77
+/** Transmit Status of Descriptor N (dword, 8139 only) */
78
+#define RTL_TSD(n) ( 0x10 + 4 * (n) )
79
+#define RTL_TSD_ERTXTH(x)	( (x) << 16 ) /**< Early TX threshold */
80
+#define RTL_TSD_ERTXTH_DEFAULT RTL_TSD_ERTXTH ( 256 / 32 )
81
+#define RTL_TSD_OWN		0x00002000UL /**< Ownership */
82
+
83
+/** Transmit Start Address of Descriptor N (dword, 8139 only) */
84
+#define RTL_TSAD(n) ( 0x20 + 4 * (n) )
85
+
61
 /** Transmit Normal Priority Descriptors (qword) */
86
 /** Transmit Normal Priority Descriptors (qword) */
62
 #define RTL_TNPDS 0x20
87
 #define RTL_TNPDS 0x20
63
 
88
 
64
-/** Number of transmit descriptors */
89
+/** Number of transmit descriptors
90
+ *
91
+ * This is a hardware limit when using legacy mode.
92
+ */
65
 #define RTL_NUM_TX_DESC 4
93
 #define RTL_NUM_TX_DESC 4
66
 
94
 
95
+/** Receive Buffer Start Address (dword, 8139 only) */
96
+#define RTL_RBSTART 0x30
97
+
98
+/** Receive buffer length */
99
+#define RTL_RXBUF_LEN 8192
100
+
101
+/** Receive buffer padding */
102
+#define RTL_RXBUF_PAD 2038 /* Allow space for WRAP */
103
+
104
+/** Receive buffer alignment */
105
+#define RTL_RXBUF_ALIGN 16
106
+
67
 /** Command Register (byte) */
107
 /** Command Register (byte) */
68
 #define RTL_CR 0x37
108
 #define RTL_CR 0x37
69
 #define RTL_CR_RST		0x10	/**< Reset */
109
 #define RTL_CR_RST		0x10	/**< Reset */
70
 #define RTL_CR_RE		0x08	/**< Receiver Enable */
110
 #define RTL_CR_RE		0x08	/**< Receiver Enable */
71
 #define RTL_CR_TE		0x04	/**< Transmit Enable */
111
 #define RTL_CR_TE		0x04	/**< Transmit Enable */
112
+#define RTL_CR_BUFE		0x01	/**< Receive buffer empty */
72
 
113
 
73
 /** Maximum time to wait for a reset, in milliseconds */
114
 /** Maximum time to wait for a reset, in milliseconds */
74
 #define RTL_RESET_MAX_WAIT_MS 100
115
 #define RTL_RESET_MAX_WAIT_MS 100
75
 
116
 
76
-/** Transmit Priority Polling Register (byte) */
77
-#define RTL_TPPOLL 0x38
117
+/** Current Address of Packet Read (word, 8139 only) */
118
+#define RTL_CAPR 0x38
119
+
120
+/** Transmit Priority Polling Register (byte, 8169 only) */
121
+#define RTL_TPPOLL_8169 0x38
78
 #define RTL_TPPOLL_NPQ		0x40	/**< Normal Priority Queue Polling */
122
 #define RTL_TPPOLL_NPQ		0x40	/**< Normal Priority Queue Polling */
79
 
123
 
80
 /** Interrupt Mask Register (word) */
124
 /** Interrupt Mask Register (word) */
81
 #define RTL_IMR 0x3c
125
 #define RTL_IMR 0x3c
82
-#define RTL_IRQ_PUN_LINKCHG	0x20	/**< Packet underrun / link change */
83
-#define RTL_IRQ_TER		0x08	/**< Transmit error */
84
-#define RTL_IRQ_TOK		0x04	/**< Transmit OK */
85
-#define RTL_IRQ_RER		0x02	/**< Receive error */
86
-#define RTL_IRQ_ROK		0x01	/**< Receive OK */
126
+#define RTL_IRQ_PUN_LINKCHG	0x0020	/**< Packet underrun / link change */
127
+#define RTL_IRQ_TER		0x0008	/**< Transmit error */
128
+#define RTL_IRQ_TOK		0x0004	/**< Transmit OK */
129
+#define RTL_IRQ_RER		0x0002	/**< Receive error */
130
+#define RTL_IRQ_ROK		0x0001	/**< Receive OK */
87
 
131
 
88
 /** Interrupt Status Register (word) */
132
 /** Interrupt Status Register (word) */
89
 #define RTL_ISR 0x3e
133
 #define RTL_ISR 0x3e
90
 
134
 
91
 /** Receive (Rx) Configuration Register (dword) */
135
 /** Receive (Rx) Configuration Register (dword) */
92
 #define RTL_RCR 0x44
136
 #define RTL_RCR 0x44
93
-#define RTL_RCR_9356SEL		0x40	/**< EEPROM is a 93C56 */
94
-#define RTL_RCR_AB		0x08	/**< Accept broadcast packets */
95
-#define RTL_RCR_AM		0x04	/**< Accept multicast packets */
96
-#define RTL_RCR_APM		0x02	/**< Accept physical match packets */
97
-#define RTL_RCR_AAP		0x01	/**< Accept all packets */
137
+#define RTL_RCR_RBLEN(x)	( (x) << 11 ) /**< Receive buffer length */
138
+#define RTL_RCR_RBLEN_MASK	RTL_RCR_RBLEN ( 0x3 )
139
+#define RTL_RCR_RBLEN_DEFAULT	RTL_RCR_RBLEN ( 0 /* 8kB */ )
140
+#define RTL_RCR_WRAP		0x00000080UL /**< Overrun receive buffer */
141
+#define RTL_RCR_9356SEL		0x00000040UL /**< EEPROM is a 93C56 */
142
+#define RTL_RCR_AB		0x00000008UL /**< Accept broadcast packets */
143
+#define RTL_RCR_AM		0x00000004UL /**< Accept multicast packets */
144
+#define RTL_RCR_APM		0x00000002UL /**< Accept physical match */
145
+#define RTL_RCR_AAP		0x00000001UL /**< Accept all packets */
98
 
146
 
99
 /** 93C46 (93C56) Command Register (byte) */
147
 /** 93C46 (93C56) Command Register (byte) */
100
 #define RTL_9346CR 0x50
148
 #define RTL_9346CR 0x50
118
 #define RTL_CONFIG1 0x52
166
 #define RTL_CONFIG1 0x52
119
 #define RTL_CONFIG1_VPD		0x02	/**< Vital Product Data enabled */
167
 #define RTL_CONFIG1_VPD		0x02	/**< Vital Product Data enabled */
120
 
168
 
121
-/** PHY Access Register (dword) */
169
+/** Media Status Register (byte, 8139 only) */
170
+#define RTL_MSR 0x58
171
+#define RTL_MSR_LINKB		0x04	/**< Inverse of link status */
172
+
173
+/** PHY Access Register (dword, 8169 only) */
122
 #define RTL_PHYAR 0x60
174
 #define RTL_PHYAR 0x60
123
 #define RTL_PHYAR_FLAG		0x80000000UL /**< Read/write flag */
175
 #define RTL_PHYAR_FLAG		0x80000000UL /**< Read/write flag */
124
 
176
 
131
 /** Maximum time to wait for PHY access, in microseconds */
183
 /** Maximum time to wait for PHY access, in microseconds */
132
 #define RTL_MII_MAX_WAIT_US 500
184
 #define RTL_MII_MAX_WAIT_US 500
133
 
185
 
134
-/** PHY (GMII, MII, or TBI) Status Register (byte) */
186
+/** PHY (GMII, MII, or TBI) Status Register (byte, 8169 only) */
135
 #define RTL_PHYSTATUS 0x6c
187
 #define RTL_PHYSTATUS 0x6c
136
 #define RTL_PHYSTATUS_LINKSTS	0x02	/**< Link ok */
188
 #define RTL_PHYSTATUS_LINKSTS	0x02	/**< Link ok */
137
 
189
 
190
+/** Transmit Priority Polling Register (byte, 8139C+ only) */
191
+#define RTL_TPPOLL_8139CP 0xd9
192
+
138
 /** RX Packet Maximum Size Register (word) */
193
 /** RX Packet Maximum Size Register (word) */
139
 #define RTL_RMS 0xda
194
 #define RTL_RMS 0xda
140
 
195
 
141
 /** C+ Command Register (word) */
196
 /** C+ Command Register (word) */
142
 #define RTL_CPCR 0xe0
197
 #define RTL_CPCR 0xe0
143
-#define RTL_CPCR_DAC		0x10	/**< PCI Dual Address Cycle Enable */
144
-#define RTL_CPCR_MULRW		0x08	/**< PCI Multiple Read/Write Enable */
198
+#define RTL_CPCR_DAC		0x0010	/**< PCI Dual Address Cycle Enable */
199
+#define RTL_CPCR_MULRW		0x0008	/**< PCI Multiple Read/Write Enable */
200
+#define RTL_CPCR_CPRX		0x0002	/**< C+ receive enable */
201
+#define RTL_CPCR_CPTX		0x0001	/**< C+ transmit enable */
145
 
202
 
146
 /** Receive Descriptor Start Address Register (qword) */
203
 /** Receive Descriptor Start Address Register (qword) */
147
 #define RTL_RDSAR 0xe4
204
 #define RTL_RDSAR 0xe4
194
 	/** MII interface */
251
 	/** MII interface */
195
 	struct mii_interface mii;
252
 	struct mii_interface mii;
196
 
253
 
254
+	/** Legacy datapath mode */
255
+	int legacy;
256
+	/** PHYAR and PHYSTATUS registers are present */
257
+	int have_phy_regs;
258
+	/** TPPoll register offset */
259
+	unsigned int tppoll;
260
+
197
 	/** Transmit descriptor ring */
261
 	/** Transmit descriptor ring */
198
 	struct realtek_ring tx;
262
 	struct realtek_ring tx;
199
 	/** Receive descriptor ring */
263
 	/** Receive descriptor ring */
200
 	struct realtek_ring rx;
264
 	struct realtek_ring rx;
201
 	/** Receive I/O buffers */
265
 	/** Receive I/O buffers */
202
 	struct io_buffer *rx_iobuf[RTL_NUM_RX_DESC];
266
 	struct io_buffer *rx_iobuf[RTL_NUM_RX_DESC];
267
+	/** Receive buffer (legacy mode) */
268
+	void *rx_buffer;
269
+	/** Offset within receive buffer (legacy mode) */
270
+	unsigned int rx_offset;
203
 };
271
 };
204
 
272
 
205
 #endif /* _REALTEK_H */
273
 #endif /* _REALTEK_H */

+ 0
- 596
src/drivers/net/rtl8139.c View File

1
-/* rtl8139.c - etherboot driver for the Realtek 8139 chipset
2
-
3
-  ported from the linux driver written by Donald Becker
4
-  by Rainer Bawidamann (Rainer.Bawidamann@informatik.uni-ulm.de) 1999
5
-
6
-  This software may be used and distributed according to the terms
7
-  of the GNU Public License, incorporated herein by reference.
8
-
9
-  changes to the original driver:
10
-  - removed support for interrupts, switching to polling mode (yuck!)
11
-  - removed support for the 8129 chip (external MII)
12
-
13
-*/
14
-
15
-FILE_LICENCE ( GPL_ANY );
16
-
17
-/*********************************************************************/
18
-/* Revision History                                                  */
19
-/*********************************************************************/
20
-
21
-/*
22
-  27 May 2006	mcb30@users.sourceforge.net (Michael Brown)
23
-     Rewrote to use the new net driver API, the updated PCI API, and
24
-     the generic three-wire serial device support for EEPROM access.
25
-
26
-  28 Dec 2002	ken_yap@users.sourceforge.net (Ken Yap)
27
-     Put in virt_to_bus calls to allow Etherboot relocation.
28
-
29
-  06 Apr 2001	ken_yap@users.sourceforge.net (Ken Yap)
30
-     Following email from Hyun-Joon Cha, added a disable routine, otherwise
31
-     NIC remains live and can crash the kernel later.
32
-
33
-  4 Feb 2000	espenlaub@informatik.uni-ulm.de (Klaus Espenlaub)
34
-     Shuffled things around, removed the leftovers from the 8129 support
35
-     that was in the Linux driver and added a bit more 8139 definitions.
36
-     Moved the 8K receive buffer to a fixed, available address outside the
37
-     0x98000-0x9ffff range.  This is a bit of a hack, but currently the only
38
-     way to make room for the Etherboot features that need substantial amounts
39
-     of code like the ANSI console support.  Currently the buffer is just below
40
-     0x10000, so this even conforms to the tagged boot image specification,
41
-     which reserves the ranges 0x00000-0x10000 and 0x98000-0xA0000.  My
42
-     interpretation of this "reserved" is that Etherboot may do whatever it
43
-     likes, as long as its environment is kept intact (like the BIOS
44
-     variables).  Hopefully fixed rtl_poll() once and for all.  The symptoms
45
-     were that if Etherboot was left at the boot menu for several minutes, the
46
-     first eth_poll failed.  Seems like I am the only person who does this.
47
-     First of all I fixed the debugging code and then set out for a long bug
48
-     hunting session.  It took me about a week full time work - poking around
49
-     various places in the driver, reading Don Becker's and Jeff Garzik's Linux
50
-     driver and even the FreeBSD driver (what a piece of crap!) - and
51
-     eventually spotted the nasty thing: the transmit routine was acknowledging
52
-     each and every interrupt pending, including the RxOverrun and RxFIFIOver
53
-     interrupts.  This confused the RTL8139 thoroughly.  It destroyed the
54
-     Rx ring contents by dumping the 2K FIFO contents right where we wanted to
55
-     get the next packet.  Oh well, what fun.
56
-
57
-  18 Jan 2000   mdc@etherboot.org (Marty Connor)
58
-     Drastically simplified error handling.  Basically, if any error
59
-     in transmission or reception occurs, the card is reset.
60
-     Also, pointed all transmit descriptors to the same buffer to
61
-     save buffer space.  This should decrease driver size and avoid
62
-     corruption because of exceeding 32K during runtime.
63
-
64
-  28 Jul 1999   (Matthias Meixner - meixner@rbg.informatik.tu-darmstadt.de)
65
-     rtl_poll was quite broken: it used the RxOK interrupt flag instead
66
-     of the RxBufferEmpty flag which often resulted in very bad
67
-     transmission performace - below 1kBytes/s.
68
-
69
-*/
70
-
71
-#include <stdint.h>
72
-#include <stdlib.h>
73
-#include <stdio.h>
74
-#include <string.h>
75
-#include <ipxe/io.h>
76
-#include <errno.h>
77
-#include <unistd.h>
78
-#include <byteswap.h>
79
-#include <ipxe/pci.h>
80
-#include <ipxe/if_ether.h>
81
-#include <ipxe/ethernet.h>
82
-#include <ipxe/iobuf.h>
83
-#include <ipxe/netdevice.h>
84
-#include <ipxe/spi_bit.h>
85
-#include <ipxe/threewire.h>
86
-#include <ipxe/nvo.h>
87
-
88
-#define TX_RING_SIZE 4
89
-#define TX_MAX_LEN 8192
90
-
91
-struct rtl8139_tx {
92
-	unsigned int next;
93
-	struct io_buffer *iobuf[TX_RING_SIZE];
94
-};
95
-
96
-struct rtl8139_rx {
97
-	void *ring;
98
-	unsigned int offset;
99
-};
100
-
101
-struct rtl8139_nic {
102
-	unsigned short ioaddr;
103
-	struct rtl8139_tx tx;
104
-	struct rtl8139_rx rx;
105
-	struct spi_bit_basher spibit;
106
-	struct spi_device eeprom;
107
-	struct nvo_block nvo;
108
-};
109
-
110
-/* Tuning Parameters */
111
-#define TX_FIFO_THRESH	256	/* In bytes, rounded down to 32 byte units. */
112
-#define RX_FIFO_THRESH	4	/* Rx buffer level before first PCI xfer.  */
113
-#define RX_DMA_BURST	4	/* Maximum PCI burst, '4' is 256 bytes */
114
-#define TX_DMA_BURST	4	/* Calculate as 16<<val. */
115
-#define TX_IPG		3	/* This is the only valid value */
116
-#define RX_BUF_LEN_IDX	0	/* 0, 1, 2 is allowed - 8,16,32K rx buffer */
117
-#define RX_BUF_LEN ( (8192 << RX_BUF_LEN_IDX) )
118
-#define RX_BUF_PAD 4
119
-
120
-/* Symbolic offsets to registers. */
121
-enum RTL8139_registers {
122
-	MAC0=0,			/* Ethernet hardware address. */
123
-	MAR0=8,			/* Multicast filter. */
124
-	TxStatus0=0x10,		/* Transmit status (four 32bit registers). */
125
-	TxAddr0=0x20,		/* Tx descriptors (also four 32bit). */
126
-	RxBuf=0x30, RxEarlyCnt=0x34, RxEarlyStatus=0x36,
127
-	ChipCmd=0x37, RxBufPtr=0x38, RxBufAddr=0x3A,
128
-	IntrMask=0x3C, IntrStatus=0x3E,
129
-	TxConfig=0x40, RxConfig=0x44,
130
-	Timer=0x48,		/* general-purpose counter. */
131
-	RxMissed=0x4C,		/* 24 bits valid, write clears. */
132
-	Cfg9346=0x50, Config0=0x51, Config1=0x52,
133
-	TimerIntrReg=0x54,	/* intr if gp counter reaches this value */
134
-	MediaStatus=0x58,
135
-	Config3=0x59,
136
-	MultiIntr=0x5C,
137
-	RevisionID=0x5E,	/* revision of the RTL8139 chip */
138
-	TxSummary=0x60,
139
-	MII_BMCR=0x62, MII_BMSR=0x64, NWayAdvert=0x66, NWayLPAR=0x68,
140
-	NWayExpansion=0x6A,
141
-	DisconnectCnt=0x6C, FalseCarrierCnt=0x6E,
142
-	NWayTestReg=0x70,
143
-	RxCnt=0x72,		/* packet received counter */
144
-	CSCR=0x74,		/* chip status and configuration register */
145
-	PhyParm1=0x78,TwisterParm=0x7c,PhyParm2=0x80,	/* undocumented */
146
-	/* from 0x84 onwards are a number of power management/wakeup frame
147
-	 * definitions we will probably never need to know about.  */
148
-};
149
-
150
-enum RxEarlyStatusBits {
151
-	ERGood=0x08, ERBad=0x04, EROVW=0x02, EROK=0x01
152
-};
153
-
154
-enum ChipCmdBits {
155
-	CmdReset=0x10, CmdRxEnb=0x08, CmdTxEnb=0x04, RxBufEmpty=0x01, };
156
-
157
-enum IntrMaskBits {
158
-	SERR=0x8000, TimeOut=0x4000, LenChg=0x2000,
159
-	FOVW=0x40, PUN_LinkChg=0x20, RXOVW=0x10,
160
-	TER=0x08, TOK=0x04, RER=0x02, ROK=0x01
161
-};
162
-
163
-/* Interrupt register bits, using my own meaningful names. */
164
-enum IntrStatusBits {
165
-	PCIErr=0x8000, PCSTimeout=0x4000, CableLenChange= 0x2000,
166
-	RxFIFOOver=0x40, RxUnderrun=0x20, RxOverflow=0x10,
167
-	TxErr=0x08, TxOK=0x04, RxErr=0x02, RxOK=0x01,
168
-};
169
-enum TxStatusBits {
170
-	TxHostOwns=0x2000, TxUnderrun=0x4000, TxStatOK=0x8000,
171
-	TxOutOfWindow=0x20000000, TxAborted=0x40000000,
172
-	TxCarrierLost=0x80000000,
173
-};
174
-enum RxStatusBits {
175
-	RxMulticast=0x8000, RxPhysical=0x4000, RxBroadcast=0x2000,
176
-	RxBadSymbol=0x0020, RxRunt=0x0010, RxTooLong=0x0008, RxCRCErr=0x0004,
177
-	RxBadAlign=0x0002, RxStatusOK=0x0001,
178
-};
179
-
180
-enum MediaStatusBits {
181
-	MSRTxFlowEnable=0x80, MSRRxFlowEnable=0x40, MSRSpeed10=0x08,
182
-	MSRLinkFail=0x04, MSRRxPauseFlag=0x02, MSRTxPauseFlag=0x01,
183
-};
184
-
185
-enum MIIBMCRBits {
186
-	BMCRReset=0x8000, BMCRSpeed100=0x2000, BMCRNWayEnable=0x1000,
187
-	BMCRRestartNWay=0x0200, BMCRDuplex=0x0100,
188
-};
189
-
190
-enum CSCRBits {
191
-	CSCR_LinkOKBit=0x0400, CSCR_LinkChangeBit=0x0800,
192
-	CSCR_LinkStatusBits=0x0f000, CSCR_LinkDownOffCmd=0x003c0,
193
-	CSCR_LinkDownCmd=0x0f3c0,
194
-};
195
-
196
-enum RxConfigBits {
197
-	RxCfgWrap=0x80,
198
-	Eeprom9356=0x40,
199
-	AcceptErr=0x20, AcceptRunt=0x10, AcceptBroadcast=0x08,
200
-	AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01,
201
-};
202
-
203
-enum Config1Bits {
204
-	VPDEnable=0x02,
205
-};
206
-
207
-/*  EEPROM access */
208
-#define EE_M1		0x80	/* Mode select bit 1 */
209
-#define EE_M0		0x40	/* Mode select bit 0 */
210
-#define EE_CS		0x08	/* EEPROM chip select */
211
-#define EE_SK		0x04	/* EEPROM shift clock */
212
-#define EE_DI		0x02	/* Data in */
213
-#define EE_DO		0x01	/* Data out */
214
-
215
-/* Offsets within EEPROM (these are word offsets) */
216
-#define EE_MAC 7
217
-
218
-static const uint8_t rtl_ee_bits[] = {
219
-	[SPI_BIT_SCLK]	= EE_SK,
220
-	[SPI_BIT_MOSI]	= EE_DI,
221
-	[SPI_BIT_MISO]	= EE_DO,
222
-	[SPI_BIT_SS(0)]	= ( EE_CS | EE_M1 ),
223
-};
224
-
225
-static int rtl_spi_read_bit ( struct bit_basher *basher,
226
-			      unsigned int bit_id ) {
227
-	struct rtl8139_nic *rtl = container_of ( basher, struct rtl8139_nic,
228
-						 spibit.basher );
229
-	uint8_t mask = rtl_ee_bits[bit_id];
230
-	uint8_t eereg;
231
-
232
-	eereg = inb ( rtl->ioaddr + Cfg9346 );
233
-	return ( eereg & mask );
234
-}
235
-
236
-static void rtl_spi_write_bit ( struct bit_basher *basher,
237
-				unsigned int bit_id, unsigned long data ) {
238
-	struct rtl8139_nic *rtl = container_of ( basher, struct rtl8139_nic,
239
-						 spibit.basher );
240
-	uint8_t mask = rtl_ee_bits[bit_id];
241
-	uint8_t eereg;
242
-
243
-	eereg = inb ( rtl->ioaddr + Cfg9346 );
244
-	eereg &= ~mask;
245
-	eereg |= ( data & mask );
246
-	outb ( eereg, rtl->ioaddr + Cfg9346 );
247
-}
248
-
249
-static struct bit_basher_operations rtl_basher_ops = {
250
-	.read = rtl_spi_read_bit,
251
-	.write = rtl_spi_write_bit,
252
-};
253
-
254
-/**
255
- * Set up for EEPROM access
256
- *
257
- * @v netdev		Net device
258
- */
259
-static void rtl_init_eeprom ( struct net_device *netdev ) {
260
-	struct rtl8139_nic *rtl = netdev->priv;
261
-	int ee9356;
262
-	int vpd;
263
-
264
-	/* Initialise three-wire bus */
265
-	rtl->spibit.basher.op = &rtl_basher_ops;
266
-	rtl->spibit.bus.mode = SPI_MODE_THREEWIRE;
267
-	init_spi_bit_basher ( &rtl->spibit );
268
-
269
-	/* Detect EEPROM type and initialise three-wire device */
270
-	ee9356 = ( inw ( rtl->ioaddr + RxConfig ) & Eeprom9356 );
271
-	if ( ee9356 ) {
272
-		DBGC ( rtl, "rtl8139 %p EEPROM is an AT93C56\n", rtl );
273
-		init_at93c56 ( &rtl->eeprom, 16 );
274
-	} else {
275
-		DBGC ( rtl, "rtl8139 %p EEPROM is an AT93C46\n", rtl );
276
-		init_at93c46 ( &rtl->eeprom, 16 );
277
-	}
278
-	rtl->eeprom.bus = &rtl->spibit.bus;
279
-
280
-	/* Initialise space for non-volatile options, if available
281
-	 *
282
-	 * We use offset 0x40 (i.e. address 0x20), length 0x40.  This
283
-	 * block is marked as VPD in the rtl8139 datasheets, so we use
284
-	 * it only if we detect that the card is not supporting VPD.
285
-	 */
286
-	vpd = ( inw ( rtl->ioaddr + Config1 ) & VPDEnable );
287
-	if ( vpd ) {
288
-		DBGC ( rtl, "rtl8139 %p EEPROM in use for VPD; cannot use "
289
-		       "for options\n", rtl );
290
-	} else {
291
-		nvo_init ( &rtl->nvo, &rtl->eeprom.nvs, 0x20, 0x40, NULL,
292
-			   &netdev->refcnt );
293
-	}
294
-}
295
-
296
-/**
297
- * Reset NIC
298
- *
299
- * @v netdev		Net device
300
- *
301
- * Issues a hardware reset and waits for the reset to complete.
302
- */
303
-static void rtl_reset ( struct net_device *netdev ) {
304
-	struct rtl8139_nic *rtl = netdev->priv;
305
-
306
-	/* Reset chip */
307
-	outb ( CmdReset, rtl->ioaddr + ChipCmd );
308
-	mdelay ( 10 );
309
-	memset ( &rtl->tx, 0, sizeof ( rtl->tx ) );
310
-	rtl->rx.offset = 0;
311
-}
312
-
313
-/**
314
- * Open NIC
315
- *
316
- * @v netdev		Net device
317
- * @ret rc		Return status code
318
- */
319
-static int rtl_open ( struct net_device *netdev ) {
320
-	struct rtl8139_nic *rtl = netdev->priv;
321
-	int i;
322
-
323
-	/* Program the MAC address */
324
-	for ( i = 0 ; i < ETH_ALEN ; i++ )
325
-		outb ( netdev->ll_addr[i], rtl->ioaddr + MAC0 + i );
326
-
327
-	/* Set up RX ring */
328
-	rtl->rx.ring = malloc ( RX_BUF_LEN + RX_BUF_PAD );
329
-	if ( ! rtl->rx.ring )
330
-		return -ENOMEM;
331
-	outl ( virt_to_bus ( rtl->rx.ring ), rtl->ioaddr + RxBuf );
332
-	DBGC ( rtl, "rtl8139 %p RX ring at %lx\n",
333
-	       rtl, virt_to_bus ( rtl->rx.ring ) );
334
-
335
-	/* Enable TX and RX */
336
-	outb ( ( CmdRxEnb | CmdTxEnb ), rtl->ioaddr + ChipCmd );
337
-	outl ( ( ( RX_FIFO_THRESH << 13 ) | ( RX_BUF_LEN_IDX << 11 ) |
338
-		 ( RX_DMA_BURST << 8 ) | AcceptBroadcast | AcceptMulticast |
339
-		 AcceptMyPhys | AcceptAllPhys ), rtl->ioaddr + RxConfig );
340
-	outl ( 0xffffffffUL, rtl->ioaddr + MAR0 + 0 );
341
-	outl ( 0xffffffffUL, rtl->ioaddr + MAR0 + 4 );
342
-	outl ( ( ( TX_DMA_BURST << 8 ) | ( TX_IPG << 24 ) ),
343
-	       rtl->ioaddr + TxConfig );
344
-
345
-	return 0;
346
-}
347
-
348
-/**
349
- * Close NIC
350
- *
351
- * @v netdev		Net device
352
- */
353
-static void rtl_close ( struct net_device *netdev ) {
354
-	struct rtl8139_nic *rtl = netdev->priv;
355
-
356
-	/* Reset the hardware to disable everything in one go */
357
-	rtl_reset ( netdev );
358
-
359
-	/* Free RX ring */
360
-	free ( rtl->rx.ring );
361
-	rtl->rx.ring = NULL;
362
-}
363
-
364
-/** 
365
- * Transmit packet
366
- *
367
- * @v netdev	Network device
368
- * @v iobuf	I/O buffer
369
- * @ret rc	Return status code
370
- */
371
-static int rtl_transmit ( struct net_device *netdev,
372
-			  struct io_buffer *iobuf ) {
373
-	struct rtl8139_nic *rtl = netdev->priv;
374
-
375
-	/* Check for space in TX ring */
376
-	if ( rtl->tx.iobuf[rtl->tx.next] != NULL ) {
377
-		DBGC ( rtl, "rtl8139 %p TX overflow\n", rtl );
378
-		return -ENOBUFS;
379
-	}
380
-
381
-	/* Check for oversized packets */
382
-	if ( iob_len ( iobuf ) >= TX_MAX_LEN ) {
383
-		DBGC ( rtl, "rtl8139 %p TX too large (%zd bytes)\n",
384
-		       rtl, iob_len ( iobuf ) );
385
-		return -ERANGE;
386
-	}
387
-
388
-	/* Pad and align packet */
389
-	iob_pad ( iobuf, ETH_ZLEN );
390
-
391
-	/* Add to TX ring */
392
-	DBGC2 ( rtl, "rtl8139 %p TX id %d at %lx+%zx\n", rtl, rtl->tx.next,
393
-		virt_to_bus ( iobuf->data ), iob_len ( iobuf ) );
394
-	rtl->tx.iobuf[rtl->tx.next] = iobuf;
395
-	outl ( virt_to_bus ( iobuf->data ),
396
-	       rtl->ioaddr + TxAddr0 + 4 * rtl->tx.next );
397
-	outl ( ( ( ( TX_FIFO_THRESH & 0x7e0 ) << 11 ) | iob_len ( iobuf ) ),
398
-	       rtl->ioaddr + TxStatus0 + 4 * rtl->tx.next );
399
-	rtl->tx.next = ( rtl->tx.next + 1 ) % TX_RING_SIZE;
400
-
401
-	return 0;
402
-}
403
-
404
-/**
405
- * Poll for received packets
406
- *
407
- * @v netdev	Network device
408
- */
409
-static void rtl_poll ( struct net_device *netdev ) {
410
-	struct rtl8139_nic *rtl = netdev->priv;
411
-	unsigned int status;
412
-	unsigned int tsad;
413
-	unsigned int rx_status;
414
-	unsigned int rx_len;
415
-	struct io_buffer *rx_iob;
416
-	int wrapped_len;
417
-	int i;
418
-
419
-	/* Acknowledge interrupts */
420
-	status = inw ( rtl->ioaddr + IntrStatus );
421
-	if ( ! status )
422
-		return;
423
-	outw ( status, rtl->ioaddr + IntrStatus );
424
-
425
-	/* Handle TX completions */
426
-	tsad = inw ( rtl->ioaddr + TxSummary );
427
-	for ( i = 0 ; i < TX_RING_SIZE ; i++ ) {
428
-		if ( ( rtl->tx.iobuf[i] != NULL ) && ( tsad & ( 1 << i ) ) ) {
429
-			DBGC2 ( rtl, "rtl8139 %p TX id %d complete\n",
430
-				rtl, i );
431
-			netdev_tx_complete ( netdev, rtl->tx.iobuf[i] );
432
-			rtl->tx.iobuf[i] = NULL;
433
-		}
434
-	}
435
-
436
-	/* Handle received packets */
437
-	while ( ! ( inb ( rtl->ioaddr + ChipCmd ) & RxBufEmpty ) ) {
438
-		rx_status = * ( ( uint16_t * )
439
-				( rtl->rx.ring + rtl->rx.offset ) );
440
-		rx_len = * ( ( uint16_t * )
441
-			     ( rtl->rx.ring + rtl->rx.offset + 2 ) );
442
-		if ( rx_status & RxOK ) {
443
-			DBGC2 ( rtl, "rtl8139 %p RX packet at offset "
444
-				"%x+%x\n", rtl, rtl->rx.offset, rx_len );
445
-
446
-			rx_iob = alloc_iob ( rx_len );
447
-			if ( ! rx_iob ) {
448
-				netdev_rx_err ( netdev, NULL, -ENOMEM );
449
-				/* Leave packet for next call to poll() */
450
-				break;
451
-			}
452
-
453
-			wrapped_len = ( ( rtl->rx.offset + 4 + rx_len )
454
-					- RX_BUF_LEN );
455
-			if ( wrapped_len < 0 )
456
-				wrapped_len = 0;
457
-
458
-			memcpy ( iob_put ( rx_iob, rx_len - wrapped_len ),
459
-				 rtl->rx.ring + rtl->rx.offset + 4,
460
-				 rx_len - wrapped_len );
461
-			memcpy ( iob_put ( rx_iob, wrapped_len ),
462
-				 rtl->rx.ring, wrapped_len );
463
-			iob_unput ( rx_iob, 4 ); /* Strip CRC */
464
-
465
-			netdev_rx ( netdev, rx_iob );
466
-		} else {
467
-			DBGC ( rtl, "rtl8139 %p RX bad packet (status %#04x "
468
-			       "len %d)\n", rtl, rx_status, rx_len );
469
-			netdev_rx_err ( netdev, NULL, -EINVAL );
470
-		}
471
-		rtl->rx.offset = ( ( ( rtl->rx.offset + 4 + rx_len + 3 ) & ~3 )
472
-				   % RX_BUF_LEN );
473
-		outw ( rtl->rx.offset - 16, rtl->ioaddr + RxBufPtr );
474
-	}
475
-}
476
-
477
-/**
478
- * Enable/disable interrupts
479
- *
480
- * @v netdev	Network device
481
- * @v enable	Interrupts should be enabled
482
- */
483
-static void rtl_irq ( struct net_device *netdev, int enable ) {
484
-	struct rtl8139_nic *rtl = netdev->priv;
485
-
486
-	DBGC ( rtl, "rtl8139 %p interrupts %s\n",
487
-	       rtl, ( enable ? "enabled" : "disabled" ) );
488
-	outw ( ( enable ? ( ROK | RER | TOK | TER ) : 0 ),
489
-	       rtl->ioaddr + IntrMask );
490
-}
491
-
492
-/** RTL8139 net device operations */
493
-static struct net_device_operations rtl_operations = {
494
-	.open		= rtl_open,
495
-	.close		= rtl_close,
496
-	.transmit	= rtl_transmit,
497
-	.poll		= rtl_poll,
498
-	.irq		= rtl_irq,
499
-};
500
-
501
-/**
502
- * Probe PCI device
503
- *
504
- * @v pci	PCI device
505
- * @v id	PCI ID
506
- * @ret rc	Return status code
507
- */
508
-static int rtl_probe ( struct pci_device *pci ) {
509
-	struct net_device *netdev;
510
-	struct rtl8139_nic *rtl;
511
-	int rc;
512
-
513
-	/* Allocate net device */
514
-	netdev = alloc_etherdev ( sizeof ( *rtl ) );
515
-	if ( ! netdev )
516
-		return -ENOMEM;
517
-	netdev_init ( netdev, &rtl_operations );
518
-	rtl = netdev->priv;
519
-	pci_set_drvdata ( pci, netdev );
520
-	netdev->dev = &pci->dev;
521
-	memset ( rtl, 0, sizeof ( *rtl ) );
522
-	rtl->ioaddr = pci->ioaddr;
523
-
524
-	/* Fix up PCI device */
525
-	adjust_pci_device ( pci );
526
-
527
-	/* Reset the NIC, set up EEPROM access and read MAC address */
528
-	rtl_reset ( netdev );
529
-	rtl_init_eeprom ( netdev );
530
-	nvs_read ( &rtl->eeprom.nvs, EE_MAC, netdev->hw_addr, ETH_ALEN );
531
-
532
-	/* Register network device */
533
-	if ( ( rc = register_netdev ( netdev ) ) != 0 )
534
-		goto err_register_netdev;
535
-
536
-	/* Mark as link up; we don't yet handle link state */
537
-	netdev_link_up ( netdev );
538
-
539
-	/* Register non-volatile storage */
540
-	if ( rtl->nvo.nvs ) {
541
-		if ( ( rc = register_nvo ( &rtl->nvo,
542
-					   netdev_settings ( netdev ) ) ) != 0)
543
-			goto err_register_nvo;
544
-	}
545
-
546
-	return 0;
547
-
548
- err_register_nvo:
549
-	unregister_netdev ( netdev );
550
- err_register_netdev:
551
-	rtl_reset ( netdev );
552
-	netdev_nullify ( netdev );
553
-	netdev_put ( netdev );
554
-	return rc;
555
-}
556
-
557
-/**
558
- * Remove PCI device
559
- *
560
- * @v pci	PCI device
561
- */
562
-static void rtl_remove ( struct pci_device *pci ) {
563
-	struct net_device *netdev = pci_get_drvdata ( pci );
564
-	struct rtl8139_nic *rtl = netdev->priv;
565
-
566
-	if ( rtl->nvo.nvs )
567
-		unregister_nvo ( &rtl->nvo );
568
-	unregister_netdev ( netdev );
569
-	rtl_reset ( netdev );
570
-	netdev_nullify ( netdev );
571
-	netdev_put ( netdev );
572
-}
573
-
574
-static struct pci_device_id rtl8139_nics[] = {
575
-PCI_ROM(0x10ec, 0x8129, "rtl8129",       "Realtek 8129", 0),
576
-PCI_ROM(0x10ec, 0x8139, "rtl8139",       "Realtek 8139", 0),
577
-PCI_ROM(0x10ec, 0x8138, "rtl8139b",      "Realtek 8139B", 0),
578
-PCI_ROM(0x1186, 0x1300, "dfe538",        "DFE530TX+/DFE538TX", 0),
579
-PCI_ROM(0x1113, 0x1211, "smc1211-1",     "SMC EZ10/100", 0),
580
-PCI_ROM(0x1112, 0x1211, "smc1211",       "SMC EZ10/100", 0),
581
-PCI_ROM(0x1500, 0x1360, "delta8139",     "Delta Electronics 8139", 0),
582
-PCI_ROM(0x4033, 0x1360, "addtron8139",   "Addtron Technology 8139", 0),
583
-PCI_ROM(0x1186, 0x1340, "dfe690txd",     "D-Link DFE690TXD", 0),
584
-PCI_ROM(0x13d1, 0xab06, "fe2000vx",      "AboCom FE2000VX", 0),
585
-PCI_ROM(0x1259, 0xa117, "allied8139",    "Allied Telesyn 8139", 0),
586
-PCI_ROM(0x14ea, 0xab06, "fnw3603tx",     "Planex FNW-3603-TX", 0),
587
-PCI_ROM(0x14ea, 0xab07, "fnw3800tx",     "Planex FNW-3800-TX", 0),
588
-PCI_ROM(0xffff, 0x8139, "clone-rtl8139", "Cloned 8139", 0),
589
-};
590
-
591
-struct pci_driver rtl8139_driver __pci_driver = {
592
-	.ids = rtl8139_nics,
593
-	.id_count = ( sizeof ( rtl8139_nics ) / sizeof ( rtl8139_nics[0] ) ),
594
-	.probe = rtl_probe,
595
-	.remove = rtl_remove,
596
-};

Loading…
Cancel
Save