mirror of https://github.com/ipxe/ipxe.git
Add support for non-volatile stored options in the RTL8139 EEPROM.
parent
2863d1a1de
commit
29db66fb51
|
@ -79,6 +79,7 @@
|
||||||
#include <gpxe/netdevice.h>
|
#include <gpxe/netdevice.h>
|
||||||
#include <gpxe/spi_bit.h>
|
#include <gpxe/spi_bit.h>
|
||||||
#include <gpxe/threewire.h>
|
#include <gpxe/threewire.h>
|
||||||
|
#include <gpxe/nvo.h>
|
||||||
|
|
||||||
#define TX_RING_SIZE 4
|
#define TX_RING_SIZE 4
|
||||||
|
|
||||||
|
@ -98,6 +99,7 @@ struct rtl8139_nic {
|
||||||
struct rtl8139_rx rx;
|
struct rtl8139_rx rx;
|
||||||
struct spi_bit_basher spibit;
|
struct spi_bit_basher spibit;
|
||||||
struct spi_device eeprom;
|
struct spi_device eeprom;
|
||||||
|
struct nvo_block nvo;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Tuning Parameters */
|
/* Tuning Parameters */
|
||||||
|
@ -193,6 +195,10 @@ enum RxConfigBits {
|
||||||
AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01,
|
AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum Config1Bits {
|
||||||
|
VPDEnable=0x02,
|
||||||
|
};
|
||||||
|
|
||||||
/* EEPROM access */
|
/* EEPROM access */
|
||||||
#define EE_M1 0x80 /* Mode select bit 1 */
|
#define EE_M1 0x80 /* Mode select bit 1 */
|
||||||
#define EE_M0 0x40 /* Mode select bit 0 */
|
#define EE_M0 0x40 /* Mode select bit 0 */
|
||||||
|
@ -240,6 +246,17 @@ static struct bit_basher_operations rtl_basher_ops = {
|
||||||
.write = rtl_spi_write_bit,
|
.write = rtl_spi_write_bit,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Portion of EEPROM available for non-volatile stored options
|
||||||
|
*
|
||||||
|
* We use offset 0x40 (i.e. address 0x20), length 0x40. This block is
|
||||||
|
* marked as VPD in the rtl8139 datasheets, so we use it only if we
|
||||||
|
* detect that the card is not supporting VPD.
|
||||||
|
*/
|
||||||
|
static struct nvo_fragment rtl_nvo_fragments[] = {
|
||||||
|
{ 0x20, 0x40 },
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up for EEPROM access
|
* Set up for EEPROM access
|
||||||
*
|
*
|
||||||
|
@ -247,6 +264,7 @@ static struct bit_basher_operations rtl_basher_ops = {
|
||||||
*/
|
*/
|
||||||
void rtl_init_eeprom ( struct rtl8139_nic *rtl ) {
|
void rtl_init_eeprom ( struct rtl8139_nic *rtl ) {
|
||||||
int ee9356;
|
int ee9356;
|
||||||
|
int vpd;
|
||||||
|
|
||||||
/* Initialise three-wire bus */
|
/* Initialise three-wire bus */
|
||||||
rtl->spibit.basher.op = &rtl_basher_ops;
|
rtl->spibit.basher.op = &rtl_basher_ops;
|
||||||
|
@ -263,6 +281,15 @@ static struct bit_basher_operations rtl_basher_ops = {
|
||||||
init_at93c46 ( &rtl->eeprom, 16 );
|
init_at93c46 ( &rtl->eeprom, 16 );
|
||||||
}
|
}
|
||||||
rtl->eeprom.bus = &rtl->spibit.bus;
|
rtl->eeprom.bus = &rtl->spibit.bus;
|
||||||
|
|
||||||
|
/* Initialise space for non-volatile options, if available */
|
||||||
|
vpd = ( inw ( rtl->ioaddr + Config1 ) & VPDEnable );
|
||||||
|
if ( vpd ) {
|
||||||
|
DBG ( "EEPROM in use for VPD; cannot use for options\n" );
|
||||||
|
} else {
|
||||||
|
rtl->nvo.nvs = &rtl->eeprom.nvs;
|
||||||
|
rtl->nvo.fragments = rtl_nvo_fragments;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -492,6 +519,7 @@ static int rtl_probe ( struct pci_device *pci,
|
||||||
const struct pci_device_id *id __unused ) {
|
const struct pci_device_id *id __unused ) {
|
||||||
struct net_device *netdev;
|
struct net_device *netdev;
|
||||||
struct rtl8139_nic *rtl = NULL;
|
struct rtl8139_nic *rtl = NULL;
|
||||||
|
int registered_netdev = 0;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Fix up PCI device */
|
/* Fix up PCI device */
|
||||||
|
@ -522,7 +550,13 @@ static int rtl_probe ( struct pci_device *pci,
|
||||||
/* Register network device */
|
/* Register network device */
|
||||||
if ( ( rc = register_netdev ( netdev ) ) != 0 )
|
if ( ( rc = register_netdev ( netdev ) ) != 0 )
|
||||||
goto err;
|
goto err;
|
||||||
|
registered_netdev = 1;
|
||||||
|
|
||||||
|
/* Register non-volatile storage */
|
||||||
|
if ( rtl->nvo.nvs ) {
|
||||||
|
if ( ( rc = nvo_register ( &rtl->nvo ) ) != 0 )
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
#warning "Hack alert"
|
#warning "Hack alert"
|
||||||
rtl_open ( netdev );
|
rtl_open ( netdev );
|
||||||
|
@ -534,6 +568,8 @@ static int rtl_probe ( struct pci_device *pci,
|
||||||
/* Disable NIC */
|
/* Disable NIC */
|
||||||
if ( rtl )
|
if ( rtl )
|
||||||
rtl_reset ( rtl );
|
rtl_reset ( rtl );
|
||||||
|
if ( registered_netdev )
|
||||||
|
unregister_netdev ( netdev );
|
||||||
/* Free net device */
|
/* Free net device */
|
||||||
free_netdev ( netdev );
|
free_netdev ( netdev );
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -552,7 +588,8 @@ static void rtl_remove ( struct pci_device *pci ) {
|
||||||
#warning "Hack alert"
|
#warning "Hack alert"
|
||||||
rtl_close ( netdev );
|
rtl_close ( netdev );
|
||||||
|
|
||||||
|
if ( rtl->nvo.nvs )
|
||||||
|
nvo_unregister ( &rtl->nvo );
|
||||||
unregister_netdev ( netdev );
|
unregister_netdev ( netdev );
|
||||||
rtl_reset ( rtl );
|
rtl_reset ( rtl );
|
||||||
free_netdev ( netdev );
|
free_netdev ( netdev );
|
||||||
|
|
Loading…
Reference in New Issue