Probe UNDI device.
931 {
942 unsigned int retry;
944
945
953 memset ( undinic, 0,
sizeof ( *undinic ) );
955 DBGC ( undinic,
"UNDINIC %p using UNDI %p\n", undinic, undi );
956
957
959 memset ( &start_undi, 0,
sizeof ( start_undi ) );
966 &start_undi,
967 sizeof ( start_undi ) ) ) != 0 )
968 goto err_start_undi;
969 }
971
972
974 memset ( &undi_startup, 0,
sizeof ( undi_startup ) );
976 &undi_startup,
977 sizeof ( undi_startup ) ) ) != 0 )
978 goto err_undi_startup;
979
980
981
982
983
984
985 for ( retry = 0 ; ; ) {
986 memset ( &undi_init, 0,
sizeof ( undi_init ) );
989 &undi_init,
990 sizeof ( undi_init ) ) ) ==0)
991 break;
993 goto err_undi_initialize;
994 DBGC ( undinic,
"UNDINIC %p retrying "
995 "PXENV_UNDI_INITIALIZE (retry %d)\n",
996 undinic, retry );
997
999 }
1000 }
1002
1003
1004 memset ( &undi_info, 0,
sizeof ( undi_info ) );
1006 &undi_info, sizeof ( undi_info ) ) ) != 0 )
1007 goto err_undi_get_information;
1010 undinic->
irq = undi_info.IntNumber;
1012 DBGC ( undinic,
"UNDINIC %p ignoring invalid IRQ %d\n",
1013 undinic, undinic->
irq );
1015 }
1016 DBGC ( undinic,
"UNDINIC %p has MAC address %s and IRQ %d\n",
1018 if ( undinic->
irq ) {
1019
1020 assert ( ! irq_enabled ( undinic->
irq ) );
1021 }
1022
1023
1024 memset ( &undi_iface, 0,
sizeof ( undi_iface ) );
1026 &undi_iface, sizeof ( undi_iface ) ) ) != 0 )
1027 goto err_undi_get_iface_info;
1028 DBGC ( undinic,
"UNDINIC %p has type %s, speed %d, flags %08x\n",
1029 undinic, undi_iface.IfaceType, undi_iface.LinkSpeed,
1030 undi_iface.ServiceFlags );
1032 ( undinic->
irq != 0 ) ) {
1034 }
1035 DBGC ( undinic,
"UNDINIC %p using %s mode\n", undinic,
1037 if (
strncmp ( ( (
char * ) undi_iface.IfaceType ),
"Etherboot",
1038 sizeof ( undi_iface.IfaceType ) ) == 0 ) {
1039 DBGC ( undinic,
"UNDINIC %p Etherboot 5.4 workaround enabled\n",
1040 undinic );
1042 }
1044 DBGC ( undinic,
"UNDINIC %p forcing polling mode due to "
1045 "broken interrupts\n", undinic );
1047 }
1048
1049
1051 goto err_register;
1052
1053
1055
1056 DBGC ( undinic,
"UNDINIC %p added\n", undinic );
1057 return 0;
1058
1059 err_register:
1060 err_undi_get_iface_info:
1061 err_undi_get_information:
1062 err_undi_initialize:
1063
1064 memset ( &undi_shutdown, 0,
sizeof ( undi_shutdown ) );
1066 sizeof ( undi_shutdown ) );
1067 memset ( &undi_cleanup, 0,
sizeof ( undi_cleanup ) );
1069 sizeof ( undi_cleanup ) );
1071 err_undi_startup:
1072
1073 memset ( &stop_undi, 0,
sizeof ( stop_undi ) );
1075 sizeof ( stop_undi ) );
1077 err_start_undi:
1082}
#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.