Browse Source

Add support for non-volatile stored options in the RTL8139 EEPROM.

tags/v0.9.3
Michael Brown 17 years ago
parent
commit
29db66fb51
1 changed files with 38 additions and 1 deletions
  1. 38
    1
      src/drivers/net/rtl8139.c

+ 38
- 1
src/drivers/net/rtl8139.c View File

@@ -79,6 +79,7 @@
79 79
 #include <gpxe/netdevice.h>
80 80
 #include <gpxe/spi_bit.h>
81 81
 #include <gpxe/threewire.h>
82
+#include <gpxe/nvo.h>
82 83
 
83 84
 #define TX_RING_SIZE 4
84 85
 
@@ -98,6 +99,7 @@ struct rtl8139_nic {
98 99
 	struct rtl8139_rx rx;
99 100
 	struct spi_bit_basher spibit;
100 101
 	struct spi_device eeprom;
102
+	struct nvo_block nvo;
101 103
 };
102 104
 
103 105
 /* Tuning Parameters */
@@ -193,6 +195,10 @@ enum RxConfigBits {
193 195
 	AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01,
194 196
 };
195 197
 
198
+enum Config1Bits {
199
+	VPDEnable=0x02,
200
+};
201
+
196 202
 /*  EEPROM access */
197 203
 #define EE_M1		0x80	/* Mode select bit 1 */
198 204
 #define EE_M0		0x40	/* Mode select bit 0 */
@@ -240,6 +246,17 @@ static struct bit_basher_operations rtl_basher_ops = {
240 246
 	.write = rtl_spi_write_bit,
241 247
 };
242 248
 
249
+/** Portion of EEPROM available for non-volatile stored options
250
+ *
251
+ * We use offset 0x40 (i.e. address 0x20), length 0x40.  This block is
252
+ * marked as VPD in the rtl8139 datasheets, so we use it only if we
253
+ * detect that the card is not supporting VPD.
254
+ */
255
+static struct nvo_fragment rtl_nvo_fragments[] = {
256
+	{ 0x20, 0x40 },
257
+	{ 0, 0 }
258
+};
259
+
243 260
 /**
244 261
  * Set up for EEPROM access
245 262
  *
@@ -247,6 +264,7 @@ static struct bit_basher_operations rtl_basher_ops = {
247 264
  */
248 265
  void rtl_init_eeprom ( struct rtl8139_nic *rtl ) {
249 266
 	int ee9356;
267
+	int vpd;
250 268
 
251 269
 	/* Initialise three-wire bus */
252 270
 	rtl->spibit.basher.op = &rtl_basher_ops;
@@ -263,6 +281,15 @@ static struct bit_basher_operations rtl_basher_ops = {
263 281
 		init_at93c46 ( &rtl->eeprom, 16 );
264 282
 	}
265 283
 	rtl->eeprom.bus = &rtl->spibit.bus;
284
+
285
+	/* Initialise space for non-volatile options, if available */
286
+	vpd = ( inw ( rtl->ioaddr + Config1 ) & VPDEnable );
287
+	if ( vpd ) {
288
+		DBG ( "EEPROM in use for VPD; cannot use for options\n" );
289
+	} else {
290
+		rtl->nvo.nvs = &rtl->eeprom.nvs;
291
+		rtl->nvo.fragments = rtl_nvo_fragments;
292
+	}
266 293
 }
267 294
 
268 295
 /**
@@ -492,6 +519,7 @@ static int rtl_probe ( struct pci_device *pci,
492 519
 		       const struct pci_device_id *id __unused ) {
493 520
 	struct net_device *netdev;
494 521
 	struct rtl8139_nic *rtl = NULL;
522
+	int registered_netdev = 0;
495 523
 	int rc;
496 524
 
497 525
 	/* Fix up PCI device */
@@ -522,7 +550,13 @@ static int rtl_probe ( struct pci_device *pci,
522 550
 	/* Register network device */
523 551
 	if ( ( rc = register_netdev ( netdev ) ) != 0 )
524 552
 		goto err;
553
+	registered_netdev = 1;
525 554
 
555
+	/* Register non-volatile storage */
556
+	if ( rtl->nvo.nvs ) {
557
+		if ( ( rc = nvo_register ( &rtl->nvo ) ) != 0 )
558
+			goto err;
559
+	}
526 560
 
527 561
 #warning "Hack alert"
528 562
 	rtl_open ( netdev );
@@ -534,6 +568,8 @@ static int rtl_probe ( struct pci_device *pci,
534 568
 	/* Disable NIC */
535 569
 	if ( rtl )
536 570
 		rtl_reset ( rtl );
571
+	if ( registered_netdev )
572
+		unregister_netdev ( netdev );
537 573
 	/* Free net device */
538 574
 	free_netdev ( netdev );
539 575
 	return rc;
@@ -552,7 +588,8 @@ static void rtl_remove ( struct pci_device *pci ) {
552 588
 #warning "Hack alert"	
553 589
 	rtl_close ( netdev );
554 590
 
555
-
591
+	if ( rtl->nvo.nvs )
592
+		nvo_unregister ( &rtl->nvo );
556 593
 	unregister_netdev ( netdev );
557 594
 	rtl_reset ( rtl );
558 595
 	free_netdev ( netdev );

Loading…
Cancel
Save