/* ************************************************************************** * * Boot-ROM-Code to load an operating system across a TCP/IP network. * * Module: pxe/undi.h * Purpose: Definitions for the Universal Network Driver Interface * Entries: None * ************************************************************************** * * Copyright (C) 1998-2003 Gero Kuhlmann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: undi.h,v 1.4 2003/01/25 23:29:40 gkminix Exp $ */ #ifndef _PXE_UNDI_H #define _PXE_UNDI_H /* ************************************************************************** * * This file contains the Universal Network Driver Interface definitions * as per Intels PXE specification version 1.0. * ************************************************************************** * * UNDI opcodes: */ #define UNDI_START_UNDI 0x0000 #define UNDI_STARTUP 0x0001 #define UNDI_CLEANUP 0x0002 #define UNDI_INITIALIZE 0x0003 #define UNDI_RESET_NIC 0x0004 #define UNDI_SHUTDOWN 0x0005 #define UNDI_OPEN 0x0006 #define UNDI_CLOSE 0x0007 #define UNDI_TRANSMIT 0x0008 #define UNDI_SET_MCAST_ADDR 0x0009 #define UNDI_SET_STATION_ADDR 0x000A #define UNDI_SET_PACKET_FILTER 0x000B #define UNDI_GET_INFORMATION 0x000C #define UNDI_GET_STATISTICS 0x000D #define UNDI_CLEAR_STATISTICS 0x000E #define UNDI_INITIATE_DIAGS 0x000F #define UNDI_FORCE_INTERRUPT 0x0010 #define UNDI_GET_MCAST_ADDR 0x0011 #define UNDI_GET_NIC_TYPE 0x0012 #define UNDI_GET_IFACE_INFO 0x0013 #define UNDI_ISR 0x0014 #define UNDI_STOP_UNDI 0x0015 #define UNDI_GET_STATE 0x0016 #define UNDI_MINNUM 0x0000 #define UNDI_MAXNUM 0x0016 /* Misc. definitions */ #define UNDI_ADDR_LEN 16 #define UNDI_MAXNUM_MCADDR 8 /* Protocol identifiers */ #define UNDI_PROT_UNKNOWN 0 #define UNDI_PROT_IP 1 #define UNDI_PROT_ARP 2 #define UNDI_PROT_RARP 3 #define UNDI_PROT_OTHERS 4 /* Packet type identifier */ #define UNDI_PKT_DIRECTED 0 #define UNDI_PKT_BROADCAST 1 #define UNDI_PKT_MULTICAST 2 /* ************************************************************************** * * Definition of multicast address structure: */ #ifndef _USE_ASSEMBLER typedef struct s_undi_mcast_addr { unsigned int count; /* In: number of multicast addrs */ unsigned char addrs[UNDI_MAXNUM_MCADDR][UNDI_ADDR_LEN]; /* In: */ /* list of multicast addresses */ } t_undi_mcast_addr; #else o_uma_count equ $0000 ! number of multicast addresses o_uma_addrs equ $0002 ! list of multicast addresses mcast_addr_size equ 130 ! size of multicast address structure #endif /* _USE_ASSEMBLER */ /* ************************************************************************** * * Definition of structure for UNDI_START_UNDI function: */ #ifndef _USE_ASSEMBLER typedef struct s_start_undi { unsigned int status; /* Out: function status */ unsigned int AX; /* In: AX register from BIOS */ unsigned int BX; /* In: BX register from BIOS */ unsigned int DX; /* In: DX register from BIOS */ unsigned int DI; /* In: DI register from BIOS */ unsigned int ES; /* In: ES register from BIOS */ } t_start_undi; #else o_su_status equ $0000 ! Out: status o_su_reg_ax equ $0002 ! In: AX register from BIOS o_su_reg_bx equ $0004 ! In: BX register from BIOS o_su_reg_dx equ $0006 ! In: DX register from BIOS o_su_reg_di equ $0008 ! In: DI register from BIOS o_su_reg_es equ $000A ! In: ES register from BIOS start_undi_size equ $000C ! size of function structure #endif /* _USE_ASSEMBLER */ /* ************************************************************************** * * Definition of structure for UNDI_STARTUP function: */ #ifndef _USE_ASSEMBLER typedef struct s_undi_startup { unsigned int status; /* Out: function status */ } t_undi_startup; #else o_us_status equ $0000 ! Out: status startup_size equ $0002 ! size of function structure #endif /* _USE_ASSEMBLER */ /* ************************************************************************** * * Definition of structure for UNDI_CLEANUP function: */ #ifndef _USE_ASSEMBLER typedef struct s_undi_cleanup { unsigned int status; /* Out: function status */ } t_undi_cleanup; #else o_uc_status equ $0000 ! Out: status cleanup_size equ $0002 ! size of function structure #endif /* _USE_ASSEMBLER */ /* ************************************************************************** * * Definition of structure for UNDI_INITIALIZE function: * * protocolini: * This is an input parameter and is a 32-bit physical address of a memory * copy of the driver module in the protocol.ini file obtained from the * Protocol Manager driver (refer to NDIS 2.0 specification). For further * information see the PXE specification document. */ #ifndef _USE_ASSEMBLER typedef struct s_undi_initialize { unsigned int status; /* Out: function status */ unsigned long protocolini; /* In: see above */ unsigned char resvd[8]; } t_undi_initialize; #else o_ui_status equ $0000 ! Out: status o_ui_protocolini equ $0002 ! In: see above initialize_size equ $000E ! size of function structure #endif /* _USE_ASSEMBLER */ /* ************************************************************************** * * Definition of structure for UNDI_RESET function: */ #ifndef _USE_ASSEMBLER typedef struct s_undi_reset { unsigned int status; /* Out: function status */ t_undi_mcast_addr mcastbuf; /* In: multicast address list */ } t_undi_reset; #else o_ur_status equ $0000 ! Out: status o_ur_mcastbuf equ $0002 ! In: multicast address list reset_size equ ($0002 + mcast_addr_size) #endif /* _USE_ASSEMBLER */ /* ************************************************************************** * * Definition of structure for UNDI_SHUTDOWN function: */ #ifndef _USE_ASSEMBLER typedef struct s_undi_shutdown { unsigned int status; /* Out: function status */ } t_undi_shutdown; #else o_ud_status equ $0000 ! Out: status shutdown_size equ $0002 ! size of function structure #endif /* _USE_ASSEMBLER */ /* ************************************************************************** * * Definition of structure for UNDI_OPEN function: */ #ifndef _USE_ASSEMBLER typedef struct s_undi_open { unsigned int status; /* Out: function status */ unsigned int openflag; /* In: adapter specific */ unsigned int pktfilter; /* In: packet filter for receiving */ t_undi_mcast_addr mcastbuf; /* In: multicast address list */ } t_undi_open; #else o_uo_status equ $0000 ! Out: status o_uo_openflag equ $0002 ! In: adapter specific flags o_uo_pktfilter equ $0004 ! In: packet filter for receiving o_uo_mcastbuf equ $0006 ! In: multicast address list open_size equ ($0006 + mcast_addr_size) #endif /* _USE_ASSEMBLER */ /* Packet filter values for receiving */ #define UNDI_FLTR_DIRECTED 0x0001 /* directed/multicast */ #define UNDI_FLTR_BROADCAST 0x0002 /* broadcast */ #define UNDI_FLTR_PROMISC 0x0004 /* any packet on LAN */ #define UNDI_FLTR_SRC_ROUTE 0x0008 /* source routing packet */ /* ************************************************************************** * * Definition of structure for UNDI_CLOSE function: */ #ifndef _USE_ASSEMBLER typedef struct s_undi_close { unsigned int status; /* Out: function status */ } t_undi_close; #else o_ux_status equ $0000 ! Out: status close_size equ $0002 ! size of function structure #endif /* _USE_ASSEMBLER */ /* ************************************************************************** * * Definition of structure for UNDI_TRANSMIT function: */ #define UNDI_MAX_DATA_BLKS 8 #ifndef _USE_ASSEMBLER typedef struct s_undi_tbd { unsigned int xmtlength; /* In: data buffer length in bytes */ unsigned int xmt_off; /* In: far ptr to transmit buffer */ unsigned int xmt_seg; unsigned int blocks; /* In: number of data blocks */ struct { unsigned char tdptrtype; /* In: type of data block address */ unsigned char tdresvd; /* reserved */ unsigned int tdlength; /* In: data block length in bytes */ unsigned long tdaddr; /* In: ptr to data block */ } datablock[UNDI_MAX_DATA_BLKS]; } t_undi_tbd; #else o_tbd_xmtlength equ $0000 ! In: data buffer length in bytes o_tbd_xmt_off equ $0002 ! In: far ptr to transmit buffer o_tbd_xmt_seg equ $0004 o_tbd_blocks equ $0006 ! In: number of data blocks o_tbd_datablock equ $0008 ! In: data block structure array o_tbd_tdptrtype equ $0000 ! In: type of data block address o_tbd_tdlength equ $0002 ! In: data block length in bytes o_tbd_tdaddr equ $0004 ! In: pointer to data block datablk_size equ $0008 tbd_size equ ($0008 + (datablk_size * UNDI_MAX_DATA_BLKS)) #endif /* _USE_ASSEMBLER */ #ifndef _USE_ASSEMBLER typedef struct s_undi_transmit { unsigned int status; /* Out: function status */ unsigned char protocol; /* In: protocol of upper layer */ unsigned char xmtflag; /* In: type of destination address */ unsigned int dest_addr_off; /* In: far ptr to destination address */ unsigned int dest_addr_seg; unsigned int tbd_off; /* In: far ptr to transmit data block */ unsigned int tbd_seg; unsigned long reserved; } t_undi_transmit; #else o_ut_status equ $0000 ! Out: status o_ut_protocol equ $0002 ! In: protocol of upper layer o_ut_xmtflag equ $0003 ! In: type of destination address o_ut_dest_off equ $0004 ! In: far ptr to destination address o_ut_dest_seg equ $0006 o_ut_tbd_off equ $0008 ! In: far ptr to transmit data block o_ut_tbd_seg equ $000A transmit_size equ $0010 ! size of function structure #endif /* _USE_ASSEMBLER */ /* Destination address flags */ #define UNDI_XMT_DESTADDR 0 #define UNDI_XMT_BROADCAST 1 /* ************************************************************************** * * Definition of structure for UNDI_SET_MCAST_ADDR function: */ #ifndef _USE_ASSEMBLER typedef struct s_undi_set_mcast_addr { unsigned int status; /* Out: function status */ t_undi_mcast_addr mcastbuf; /* In: multicast address list */ } t_undi_set_mcast_addr; #else o_usma_status equ $0000 ! Out: status o_usma_mcastbuf equ $0002 ! In: multicast address list setmcast_size equ ($0002 + mcast_addr_size) #endif /* _USE_ASSEMBLER */ /* ************************************************************************** * * Definition of structure for UNDI_SET_STATION_ADDR function: */ #ifndef _USE_ASSEMBLER typedef struct s_undi_set_station_addr { unsigned int status; /* Out: function status */ unsigned char addr[UNDI_ADDR_LEN]; } t_undi_set_station_addr; #else o_ussa_status equ $0000 ! Out: status o_ussa_addr equ $0002 ! In: station hardware address setstation_size equ ($0002 + UNDI_ADDR_LEN) #endif /* _USE_ASSEMBLER */ /* ************************************************************************** * * Definition of structure for UNDI_SET_PACKET_FILTER function: */ #ifndef _USE_ASSEMBLER typedef struct s_undi_set_packet_filter { unsigned int status; /* Out: function status */ unsigned char filter; /* In: receive filter value */ } t_undi_set_packet_filter; #else o_uspf_status equ $0000 ! Out: status o_uspf_filter equ $0002 ! In: receive filter value setfilter_size equ $0004 ! size of function structure #endif /* _USE_ASSEMBLER */ /* ************************************************************************** * * Definition of structure for UNDI_GET_INFORMATION function: */ #ifndef _USE_ASSEMBLER typedef struct s_undi_get_information { unsigned int status; /* Out: function status */ unsigned int baseio; /* Out: adapters base I/O address */ unsigned int intnumber; /* Out: IRQ number */ unsigned int MTU; /* Out: MTU */ unsigned int hwtype; /* Out: type of hardware protocol */ unsigned int hwaddrlen; /* Out: length of hardware address */ unsigned char currentaddr[UNDI_ADDR_LEN]; /* Out: current addr */ unsigned char permaddr[UNDI_ADDR_LEN]; /* Out: perm addr */ unsigned int romaddr; /* Out: ROM address */ unsigned int rxbufcnt; /* Out: receive queue length */ unsigned int txbufcnt; /* Out: transmit queue length */ } t_undi_get_information; #else o_ugi_status equ $0000 ! Out: status o_ugi_baseio equ $0002 ! Out: adapters base I/O address o_ugi_intnumber equ $0004 ! Out: IRQ number o_ugi_mtu equ $0006 ! Out: MTU o_ugi_hwtype equ $0008 ! Out: type of hardware protocol o_ugi_hwaddrlen equ $000A ! Out: length of hardware address o_ugi_currentaddr equ $000C ! Out: current hardware address o_ugi_permaddr equ $0014 ! Out: permanent hardware address o_ugi_romaddr equ $001C ! Out: ROM address o_ugi_rxbufcnt equ $001E ! Out: receive queue length o_ugi_txbufcnt equ $0020 ! Out: transmit queue length getinfo_size equ $0022 ! size of function structure #endif /* _USE_ASSEMBLER */ /* Type of hardware protocol */ #define UNDI_TYPE_ETHER 1 #define UNDI_TYPE_EXP_ETHER 2 #define UNDI_TYPE_AX25 3 #define UNDI_TYPE_IEEE 6 #define UNDI_TYPE_ARCNET 7 #define UNDI_TYPE_APPLETALK 8 /* ************************************************************************** * * Definition of structure for UNDI_GET_STATISTICS function: */ #ifndef _USE_ASSEMBLER typedef struct s_undi_get_statistics { unsigned int status; /* Out: function status */ unsigned long xmtgood; /* Out: no. successful transmissions */ unsigned long rcvgood; /* Out: no. of good frames received */ unsigned long rcvcrcerr; /* Out: no. of frames with CRC errors */ unsigned long rcvreserr; /* Out: no. of frames discarded */ } t_undi_get_statistics; #else o_ugs_status equ $0000 ! Out: status o_ugs_xmtgood equ $0002 ! Out: no. successful transmissions o_ugs_rcvgood equ $0006 ! Out: no. good frames received o_ugs_rcvcrcerr equ $000A ! Out: no. of frames with CRC errors o_ugs_rcvreserr equ $000E ! Out: no. of frames discarded getstat_size equ $0012 ! size of function structure #endif /* _USE_ASSEMBLER */ /* ************************************************************************** * * Definition of structure for UNDI_CLEAR_STATISTICS function: */ #ifndef _USE_ASSEMBLER typedef struct s_undi_clear_statistics { unsigned int status; /* Out: function status */ } t_undi_clear_statistics; #else o_ucs_status equ $0000 ! Out: status clearstat_size equ $0002 ! size of function structure #endif /* _USE_ASSEMBLER */ /* ************************************************************************** * * Definition of structure for UNDI_INITIATE_DIAGS function: */ #ifndef _USE_ASSEMBLER typedef struct s_undi_initiate_diags { unsigned int status; /* Out: function status */ } t_undi_initiate_diags; #else o_uid_status equ $0000 ! Out: status initdiag_size equ $0002 ! size of function structure #endif /* _USE_ASSEMBLER */ /* ************************************************************************** * * Definition of structure for UNDI_FORCE_INTERRUPT function: */ #ifndef _USE_ASSEMBLER typedef struct s_undi_force_interrupt { unsigned int status; /* Out: function status */ } t_undi_force_interrupt; #else o_ufi_status equ $0000 ! Out: status forceint_size equ $0002 ! size of function structure #endif /* _USE_ASSEMBLER */ /* ************************************************************************** * * Definition of structure for UNDI_GET_MCAST_ADDR function: */ #ifndef _USE_ASSEMBLER typedef struct s_undi_get_mcast_addr { unsigned int status; /* Out: function status */ unsigned long inetaddr; /* In: IP multicast address */ unsigned char hwaddr[UNDI_ADDR_LEN]; /* Out: corresponding HW addr */ } t_undi_get_mcast_addr; #else o_ugma_status equ $0000 ! Out: status o_ugma_inetaddr equ $0002 ! In: IP multicast address o_ugma_hwaddr equ $0006 ! Out: corresponding hardware address getmcast_size equ $000E ! size of function structure #endif /* _USE_ASSEMBLER */ /* ************************************************************************** * * Definition of structure for UNDI_GET_NIC_TYPE function: */ #ifndef _USE_ASSEMBLER typedef struct s_undi_get_nic_type { unsigned int status; /* Out: function status */ unsigned char nictype; /* Out: type of NIC */ union { struct { unsigned int vendorid; unsigned int devid; unsigned char baseclass; unsigned char subclass; unsigned char progint; unsigned char revision; unsigned int busdevfunc; unsigned int subvendorid; unsigned int subdevid; } pci; struct { unsigned long eisa_devid; unsigned char baseclass; unsigned char subclass; unsigned char progint; unsigned int cardselnum; } pnp; } info; } t_undi_get_nic_type; #else o_ugnt_status equ $0000 ! Out: status o_ugnt_nictype equ $0002 ! Out: NIC type o_ugnt_pci_vendid equ $0003 o_ugnt_pci_devid equ $0005 o_ugnt_pci_baseclass equ $0007 o_ugnt_pci_subclass equ $0008 o_ugnt_pci_progint equ $0009 o_ugnt_pci_revision equ $000A o_ugnt_pci_busdevfunc equ $000B o_ugnt_pci_subvendid equ $000D o_ugnt_pci_subdevid equ $000F o_ugnt_pnp_eisa_devid equ $0003 o_ugnt_pnp_baseclass equ $0007 o_ugnt_pnp_subclass equ $0008 o_ugnt_pnp_progint equ $0009 o_ugnt_pnp_cardselnum equ $000A getnic_size equ $0011 ! size of function structure #endif /* _USE_ASSEMBLER */ /* NIC types */ #define UNDI_NIC_PCI 2 /* PCI NIC */ #define UNDI_NIC_PNP 3 /* PnP NIC */ #define UNDI_NIC_CB 4 /* CardBus NIC */ /* ************************************************************************** * * Definition of structure for UNDI_GET_IFACE_INFO function: */ #ifndef _USE_ASSEMBLER typedef struct s_undi_get_iface_info { unsigned int status; /* Out: function status */ unsigned char ifacetype[16]; /* Out: name of MAC in ASCIZ format */ unsigned long linkspeed; /* Out: link speed as per NDIS2 */ unsigned long serviceflags; /* Out: flags as defined in NDIS2 */ unsigned long resvd[4]; } t_undi_get_iface_info; #else o_ugii_status equ $0000 ! Out: status o_ugii_ifacetype equ $0002 ! Out: name of MAC in ASCIZ format o_ugii_linkspeed equ $0012 ! Out: link speed as per NDIS2 o_ugii_serviceflags equ $0016 ! Out: flags as defined in NDIS2 o_ugii_ifacelen equ (o_ugii_linkspeed - o_ugii_ifacetype) getiface_size equ $002A ! size of function structure #endif /* _USE_ASSEMBLER */ /* ************************************************************************** * * Definition of structure for UNDI_ISR function: * * Interupt service routine operation: * * In this design the UNDI does not hook the interrupt for the network * interface. Instead, the application or teh protocol driver hooks the * interrupt and calls UNDI with the UNDI_ISR API call for different * levels of interrupt processing. * * When the network interface hardware generates an interrupt the protocol * drivers interrupt service routine gets control and takes care of the * interrupt processing at the PIC level. The ISR then calls the UNDI using * the UNDI_ISR API with the value UNDI_ISR_IN_START for the FuncFlag * parameter. At this time UNDI must disable the interrupts at the network * interface level and read any status values required to further process * the interrupt. UNDI must return as quickly as possible with one of the * two values, UNDI_ISR_OUT_OURS or UNDI_ISR_OUT_NOT_OURS, for the * parameter FuncFlag depending on whether the interrupt was generated * by this particular network interface or not. * * If the value returned in FuncFlag is UNDI_ISR_OUT_OURS, the protocol * driver must call UNDI using the same API call with FuncFlag equal to * UNDI_ISR_IN_PROCESS. At this time UNDI must find the cause of this * interrupt and return the status in the FuncFlag. It first checks if * there is a frame received and if so it returns the first buffer pointer * of that frame in the parameter block. * * The protocol driver calls UNDI repeatedly with the FuncFlag equal to * UNDI_ISR_IN_GET_NEXT to get all the buffers in a frame and also all the * received frames in the queue. On this call, UNDI must remember the * previous buffer given to the protocol and remove it from the receive * queue and recycle. In case of a multi buffered frame if the previous * buffer is not the last buffer in the frame it must return the next buffer * in the frame in the parameter block. Otherwise it must return the first * buffer in the next frame. * * If there is no received frame pending to be processed, UNDI processes * the transmit completes and if there is no other interrupt status to be * processed, UNDI re-enables the interrupt at the network interface * level and returns UNID_ISR_OUT_DONE in the FuncFlag. */ #ifndef _USE_ASSEMBLER typedef struct s_undi_isr { unsigned int status; /* Out: function status */ unsigned int funcflag; /* In/Out: function flag */ unsigned int buflength; /* Out: length of data in buffer */ unsigned int framelength; /* Out: length of data in frame */ unsigned int headerlength; /* Out: length of MAC header */ unsigned long frame; /* Out: far ptr to frame buffer */ unsigned char prottype; /* Out: protocol identifier */ unsigned char pkttype; /* Out: type of received frame */ } t_undi_isr; #else o_uisr_status equ $0000 ! Out: status o_uisr_funcflag equ $0002 ! In/Out: function flag o_uisr_buflength equ $0004 ! Out: length of data in buffer o_uisr_framelength equ $0006 ! Out: length of data in frame o_uisr_headerlength equ $0008 ! Out: length of MAC header o_uisr_frame equ $000A ! Out: far ptr to frame buffer o_uisr_prottype equ $000E ! Out: protocol identifier o_uisr_pkttype equ $000F ! Out: type of received frame isr_size equ $0010 ! size of function structure #endif /* _USE_ASSEMBLER */ /* FuncFlag values */ #define UNDI_ISR_IN_START 1 #define UNDI_ISR_IN_PROCESS 2 #define UNDI_ISR_IN_GET_NEXT 3 #define UNDI_ISR_OUT_OURS 0 #define UNDI_ISR_OUT_NOT_OURS 1 #define UNDI_ISR_OUT_DONE 0 #define UNDI_ISR_OUT_TRANSMIT 2 #define UNDI_ISR_OUT_RECEIVE 3 #define UNDI_ISR_OUT_BUSY 4 /* ************************************************************************** * * Definition of structure for UNDI_STOP_UNDI function: */ #ifndef _USE_ASSEMBLER typedef struct s_stop_undi { unsigned int status; /* Out: function status */ } t_stop_undi; #else o_xu_status equ $0000 ! Out: status stop_undi_size equ $0002 ! size of function structure #endif /* _USE_ASSEMBLER */ /* ************************************************************************** * * Definition of structure for UNDI_GET_STATE function: */ #ifndef _USE_ASSEMBLER typedef struct s_get_state { unsigned int status; /* Out: function status */ unsigned char state; /* Out: UNDI state */ } t_get_state; #else o_gs_status equ $0000 ! Out: status o_gs_state equ $0002 ! Out: UNDI state get_state_size equ $0004 ! size of function structure #endif /* _USE_ASSEMBLER */ /* State values */ #define UNDI_STATE_STARTED 1 #define UNDI_STATE_INITIALIZED 2 #define UNDI_STATE_OPENED 3 #endif /* _PXE_UNDI_H */