|
@@ -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 );
|