Probe UNDI device.
937 {
948 unsigned int retry;
950
951
959 memset ( undinic, 0,
sizeof ( *undinic ) );
961 DBGC ( undinic,
"UNDINIC %p using UNDI %p\n", undinic, undi );
962
963
965 memset ( &start_undi, 0,
sizeof ( start_undi ) );
972 &start_undi,
973 sizeof ( start_undi ) ) ) != 0 )
974 goto err_start_undi;
975 }
977
978
980 memset ( &undi_startup, 0,
sizeof ( undi_startup ) );
982 &undi_startup,
983 sizeof ( undi_startup ) ) ) != 0 )
984 goto err_undi_startup;
985
986
987
988
989
990
991 for ( retry = 0 ; ; ) {
992 memset ( &undi_init, 0,
sizeof ( undi_init ) );
995 &undi_init,
996 sizeof ( undi_init ) ) ) ==0)
997 break;
999 goto err_undi_initialize;
1000 DBGC ( undinic,
"UNDINIC %p retrying "
1001 "PXENV_UNDI_INITIALIZE (retry %d)\n",
1002 undinic, retry );
1003
1005 }
1006 }
1008
1009
1010 memset ( &undi_info, 0,
sizeof ( undi_info ) );
1012 &undi_info, sizeof ( undi_info ) ) ) != 0 )
1013 goto err_undi_get_information;
1016 undinic->
irq = undi_info.IntNumber;
1018 DBGC ( undinic,
"UNDINIC %p ignoring invalid IRQ %d\n",
1019 undinic, undinic->
irq );
1021 }
1022 DBGC ( undinic,
"UNDINIC %p has MAC address %s and IRQ %d\n",
1024 if ( undinic->
irq ) {
1025
1026 assert ( ! irq_enabled ( undinic->
irq ) );
1027 }
1028
1029
1030 memset ( &undi_iface, 0,
sizeof ( undi_iface ) );
1032 &undi_iface, sizeof ( undi_iface ) ) ) != 0 )
1033 goto err_undi_get_iface_info;
1034 DBGC ( undinic,
"UNDINIC %p has type %s, speed %d, flags %08x\n",
1035 undinic, undi_iface.IfaceType, undi_iface.LinkSpeed,
1036 undi_iface.ServiceFlags );
1038 ( undinic->
irq != 0 ) ) {
1040 }
1041 DBGC ( undinic,
"UNDINIC %p using %s mode\n", undinic,
1043 if (
strncmp ( ( (
char * ) undi_iface.IfaceType ),
"Etherboot",
1044 sizeof ( undi_iface.IfaceType ) ) == 0 ) {
1045 DBGC ( undinic,
"UNDINIC %p Etherboot 5.4 workaround enabled\n",
1046 undinic );
1048 }
1050 DBGC ( undinic,
"UNDINIC %p forcing polling mode due to "
1051 "broken interrupts\n", undinic );
1053 }
1054
1055
1057 goto err_register;
1058
1059
1061
1062 DBGC ( undinic,
"UNDINIC %p added\n", undinic );
1063 return 0;
1064
1065 err_register:
1066 err_undi_get_iface_info:
1067 err_undi_get_information:
1068 err_undi_initialize:
1069
1070 memset ( &undi_shutdown, 0,
sizeof ( undi_shutdown ) );
1072 sizeof ( undi_shutdown ) );
1073 memset ( &undi_cleanup, 0,
sizeof ( undi_cleanup ) );
1075 sizeof ( undi_cleanup ) );
1077 err_undi_startup:
1078
1079 memset ( &stop_undi, 0,
sizeof ( stop_undi ) );
1081 sizeof ( stop_undi ) );
1083 err_start_undi:
1088}
#define NULL
NULL pointer (VOID *).
struct arbelprm_rc_send_wqe rc
#define assert(condition)
Assert a condition at run-time.
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
static struct net_device * netdev
#define ENOMEM
Not enough space.
#define PXENV_START_UNDI
PXE API function code for pxenv_start_undi().
#define PXENV_STOP_UNDI
PXE API function code for pxenv_stop_undi().
#define PXENV_UNDI_CLEANUP
PXE API function code for pxenv_undi_cleanup().
#define PXENV_UNDI_GET_IFACE_INFO
PXE API function code for pxenv_undi_get_iface_info().
#define SUPPORTED_IRQ
Interrupt Request supported.
#define PXENV_UNDI_INITIALIZE
PXE API function code for pxenv_undi_initialize().
#define PXENV_UNDI_SHUTDOWN
PXE API function code for pxenv_undi_shutdown().
#define PXENV_UNDI_STARTUP
PXE API function code for pxenv_undi_startup().
#define UNDI_HACK_EB54
Work around Etherboot 5.4 bugs.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
int register_netdev(struct net_device *netdev)
Register network device.
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
int find_pnp_bios(void)
Locate Plug-and-Play BIOS.
int strncmp(const char *first, const char *second, size_t max)
Compare strings.
Parameter block for pxenv_start_undi().
Parameter block for pxenv_stop_undi().
Parameter block for pxenv_undi_cleanup().
Parameter block for pxenv_undi_get_iface_info().
Parameter block for pxenv_undi_initialize().
Parameter block for pxenv_undi_shutdown().
Parameter block for pxenv_undi_startup().
UINT16_t pci_busdevfn
PCI bus:dev.fn, or UNDI_NO_PCI_BUSDEVFN.
UINT16_t isapnp_csn
ISAPnP card select number, or UNDI_NO_ISAPNP_CSN.
UINT16_t isapnp_read_port
ISAPnP read port, or UNDI_NO_ISAPNP_READ_PORT.
SEGOFF16_t entry
Entry point.
int hacks
Bug workarounds.
unsigned int irq
Assigned IRQ number.
int irq_supported
Device supports IRQs.
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
static void undi_set_drvdata(struct undi_device *undi, void *priv)
Set UNDI driver-private data.
#define UNDI_FL_INITIALIZED
UNDI flag: UNDI_STARTUP and UNDI_INITIALIZE have been called.
#define UNDI_FL_STARTED
UNDI flag: START_UNDI has been called.
static int undinet_call(struct undi_nic *undinic, unsigned int function, void *params, size_t params_len)
Issue UNDI API call.
static struct net_device_operations undinet_operations
UNDI network device operations.
#define UNDI_INITIALIZE_RETRY_DELAY_MS
Delay between retries of PXENV_UNDI_INITIALIZE.
#define UNDI_INITIALIZE_RETRY_MAX
Maximum number of times to retry PXENV_UNDI_INITIALIZE.
#define undinet_entry_point
static int undinet_irq_is_broken(struct net_device *netdev)
Check for devices with broken support for generating interrupts.