17c478bd9Sstevel@tonic-gate /**************************************************************************
27c478bd9Sstevel@tonic-gate Etherboot -  BOOTP/TFTP Bootstrap Program
37c478bd9Sstevel@tonic-gate UNDI NIC driver for Etherboot - header file
47c478bd9Sstevel@tonic-gate 
57c478bd9Sstevel@tonic-gate This file Copyright (C) 2003 Michael Brown <mbrown@fensystems.co.uk>
67c478bd9Sstevel@tonic-gate of Fen Systems Ltd. (http://www.fensystems.co.uk/).  All rights
77c478bd9Sstevel@tonic-gate reserved.
87c478bd9Sstevel@tonic-gate 
97c478bd9Sstevel@tonic-gate $Id: undi.h,v 1.5 2003/10/24 10:05:06 mcb30 Exp $
107c478bd9Sstevel@tonic-gate ***************************************************************************/
117c478bd9Sstevel@tonic-gate 
127c478bd9Sstevel@tonic-gate /*
137c478bd9Sstevel@tonic-gate  * This program is free software; you can redistribute it and/or
147c478bd9Sstevel@tonic-gate  * modify it under the terms of the GNU General Public License as
157c478bd9Sstevel@tonic-gate  * published by the Free Software Foundation; either version 2, or (at
167c478bd9Sstevel@tonic-gate  * your option) any later version.
177c478bd9Sstevel@tonic-gate  */
187c478bd9Sstevel@tonic-gate 
197c478bd9Sstevel@tonic-gate /* Include pxe.h from FreeBSD.
207c478bd9Sstevel@tonic-gate  * pxe.h defines PACKED, which etherboot.h has already defined.
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate 
237c478bd9Sstevel@tonic-gate #undef PACKED
247c478bd9Sstevel@tonic-gate #include "pxe.h"
257c478bd9Sstevel@tonic-gate #include "pic8259.h"
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /* __undi_call is the assembler wrapper to the real-mode UNDI calls.
287c478bd9Sstevel@tonic-gate  * Pass it the real-mode segment:offset address of an undi_call_info_t
297c478bd9Sstevel@tonic-gate  * structure.  The parameters are only uint16_t, but GCC will push
307c478bd9Sstevel@tonic-gate  * them on the stack as uint32_t anyway for the sake of alignment.  We
317c478bd9Sstevel@tonic-gate  * specify them here as uint32_t to remove ambiguity.
327c478bd9Sstevel@tonic-gate  */
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate typedef struct undi_call_info {
357c478bd9Sstevel@tonic-gate 	SEGOFF16_t	routine;
367c478bd9Sstevel@tonic-gate 	uint16_t	stack[3];
377c478bd9Sstevel@tonic-gate } undi_call_info_t;
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate typedef uint16_t PXENV_EXIT_t;
407c478bd9Sstevel@tonic-gate #define PXENV_EXIT_SUCCESS 0x0000
417c478bd9Sstevel@tonic-gate #define PXENV_EXIT_FAILURE 0x0001
427c478bd9Sstevel@tonic-gate PXENV_EXIT_t __undi_call ( uint32_t, uint32_t );
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate /* The UNDI loader parameter structure is not defined in pxe.h
457c478bd9Sstevel@tonic-gate  */
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate typedef struct undi_loader {
487c478bd9Sstevel@tonic-gate 	PXENV_STATUS_t	status;
497c478bd9Sstevel@tonic-gate 	uint16_t	ax;
507c478bd9Sstevel@tonic-gate 	uint16_t	bx;
517c478bd9Sstevel@tonic-gate 	uint16_t	dx;
527c478bd9Sstevel@tonic-gate 	uint16_t	di;
537c478bd9Sstevel@tonic-gate 	uint16_t	es;
547c478bd9Sstevel@tonic-gate 	uint16_t	undi_ds;
557c478bd9Sstevel@tonic-gate 	uint16_t	undi_cs;
567c478bd9Sstevel@tonic-gate 	uint16_t	pxe_off;
577c478bd9Sstevel@tonic-gate 	uint16_t	pxenv_off;
587c478bd9Sstevel@tonic-gate } undi_loader_t;
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate /* A union that can function as the parameter block for any UNDI API call.
617c478bd9Sstevel@tonic-gate  */
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate typedef union pxenv_structure {
647c478bd9Sstevel@tonic-gate 	PXENV_STATUS_t			Status; /* Make it easy to read status
657c478bd9Sstevel@tonic-gate 						   for any operation */
667c478bd9Sstevel@tonic-gate 	undi_loader_t			loader;
677c478bd9Sstevel@tonic-gate 	t_PXENV_START_UNDI		start_undi;
687c478bd9Sstevel@tonic-gate 	t_PXENV_UNDI_STARTUP		undi_startup;
697c478bd9Sstevel@tonic-gate 	t_PXENV_UNDI_CLEANUP		undi_cleanup;
707c478bd9Sstevel@tonic-gate 	t_PXENV_UNDI_INITIALIZE		undi_initialize;
717c478bd9Sstevel@tonic-gate 	t_PXENV_UNDI_SHUTDOWN		undi_shutdown;
727c478bd9Sstevel@tonic-gate 	t_PXENV_UNDI_OPEN		undi_open;
737c478bd9Sstevel@tonic-gate 	t_PXENV_UNDI_CLOSE		undi_close;
747c478bd9Sstevel@tonic-gate 	t_PXENV_UNDI_TRANSMIT		undi_transmit;
757c478bd9Sstevel@tonic-gate 	t_PXENV_UNDI_SET_STATION_ADDRESS undi_set_station_address;
767c478bd9Sstevel@tonic-gate 	t_PXENV_UNDI_GET_INFORMATION	undi_get_information;
777c478bd9Sstevel@tonic-gate 	t_PXENV_UNDI_GET_IFACE_INFO	undi_get_iface_info;
787c478bd9Sstevel@tonic-gate 	t_PXENV_UNDI_ISR		undi_isr;
797c478bd9Sstevel@tonic-gate 	t_PXENV_STOP_UNDI		stop_undi;
807c478bd9Sstevel@tonic-gate 	t_PXENV_UNLOAD_STACK		unload_stack;
8199ed6083Sszhou 	t_PXENV_GET_CACHED_INFO		get_cached_info;
8299ed6083Sszhou 	t_PXENV_UDP_OPEN		udp_open;
8399ed6083Sszhou 	t_PXENV_UDP_CLOSE		udp_close;
8499ed6083Sszhou 	t_PXENV_UDP_READ		udp_read;
8599ed6083Sszhou 	t_PXENV_UDP_WRITE		udp_write;
8699ed6083Sszhou 	t_PXENV_TFTP_OPEN		tftp_open;
8799ed6083Sszhou 	t_PXENV_TFTP_CLOSE		tftp_close;
8899ed6083Sszhou 	t_PXENV_TFTP_READ		tftp_read;
8999ed6083Sszhou 	t_PXENV_TFTP_GET_FSIZE		tftp_get_fsize;
907c478bd9Sstevel@tonic-gate } pxenv_structure_t;
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate /* UNDI status codes
937c478bd9Sstevel@tonic-gate  */
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate #define PXENV_STATUS_SUCCESS			0x0000
967c478bd9Sstevel@tonic-gate #define PXENV_STATUS_FAILURE			0x0001
977c478bd9Sstevel@tonic-gate #define PXENV_STATUS_KEEP_UNDI			0x0004
987c478bd9Sstevel@tonic-gate #define PXENV_STATUS_KEEP_ALL			0x0005
997c478bd9Sstevel@tonic-gate #define PXENV_STATUS_UNDI_MEDIATEST_FAILED	0x0061
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate /* BIOS PnP parameter block.  We scan for this so that we can pass it
1027c478bd9Sstevel@tonic-gate  * to the UNDI driver.
1037c478bd9Sstevel@tonic-gate  */
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate #define PNP_BIOS_SIGNATURE ( ('$'<<0) + ('P'<<8) + ('n'<<16) + ('P'<<24) )
1067c478bd9Sstevel@tonic-gate typedef struct pnp_bios {
1077c478bd9Sstevel@tonic-gate 	uint32_t	signature;
1087c478bd9Sstevel@tonic-gate 	uint8_t		version;
1097c478bd9Sstevel@tonic-gate 	uint8_t		length;
1107c478bd9Sstevel@tonic-gate 	uint16_t	control;
1117c478bd9Sstevel@tonic-gate 	uint8_t		checksum;
1127c478bd9Sstevel@tonic-gate 	uint8_t		dontcare[24];
1137c478bd9Sstevel@tonic-gate } PACKED pnp_bios_t;
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate /* Structures within the PXE ROM.
1167c478bd9Sstevel@tonic-gate  */
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate #define ROM_SIGNATURE 0xaa55
1197c478bd9Sstevel@tonic-gate typedef struct rom {
1207c478bd9Sstevel@tonic-gate 	uint16_t	signature;
1217c478bd9Sstevel@tonic-gate 	uint8_t		unused[0x14];
1227c478bd9Sstevel@tonic-gate 	uint16_t	undi_rom_id_off;
1237c478bd9Sstevel@tonic-gate 	uint16_t	pcir_off;
1247c478bd9Sstevel@tonic-gate 	uint16_t	pnp_off;
1257c478bd9Sstevel@tonic-gate } PACKED rom_t;
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate #define PCIR_SIGNATURE ( ('P'<<0) + ('C'<<8) + ('I'<<16) + ('R'<<24) )
1287c478bd9Sstevel@tonic-gate typedef struct pcir_header {
1297c478bd9Sstevel@tonic-gate 	uint32_t	signature;
1307c478bd9Sstevel@tonic-gate 	uint16_t	vendor_id;
1317c478bd9Sstevel@tonic-gate 	uint16_t	device_id;
1327c478bd9Sstevel@tonic-gate } PACKED pcir_header_t;
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate #define PNP_SIGNATURE ( ('$'<<0) + ('P'<<8) + ('n'<<16) + ('P'<<24) )
1357c478bd9Sstevel@tonic-gate typedef struct pnp_header {
1367c478bd9Sstevel@tonic-gate 	uint32_t	signature;
1377c478bd9Sstevel@tonic-gate 	uint8_t		struct_revision;
1387c478bd9Sstevel@tonic-gate 	uint8_t		length;
1397c478bd9Sstevel@tonic-gate 	uint16_t	next;
1407c478bd9Sstevel@tonic-gate 	uint8_t		reserved;
1417c478bd9Sstevel@tonic-gate 	uint8_t		checksum;
1427c478bd9Sstevel@tonic-gate 	uint16_t	id[2];
1437c478bd9Sstevel@tonic-gate 	uint16_t	manuf_str_off;
1447c478bd9Sstevel@tonic-gate 	uint16_t	product_str_off;
1457c478bd9Sstevel@tonic-gate 	uint8_t		base_type;
1467c478bd9Sstevel@tonic-gate 	uint8_t		sub_type;
1477c478bd9Sstevel@tonic-gate 	uint8_t		interface_type;
1487c478bd9Sstevel@tonic-gate 	uint8_t		indicator;
1497c478bd9Sstevel@tonic-gate 	uint16_t	boot_connect_off;
1507c478bd9Sstevel@tonic-gate 	uint16_t	disconnect_off;
1517c478bd9Sstevel@tonic-gate 	uint16_t	initialise_off;
1527c478bd9Sstevel@tonic-gate 	uint16_t	reserved2;
1537c478bd9Sstevel@tonic-gate 	uint16_t	info;
1547c478bd9Sstevel@tonic-gate } PACKED pnp_header_t;
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate #define UNDI_SIGNATURE ( ('U'<<0) + ('N'<<8) + ('D'<<16) + ('I'<<24) )
1577c478bd9Sstevel@tonic-gate typedef struct undi_rom_id {
1587c478bd9Sstevel@tonic-gate 	uint32_t	signature;
1597c478bd9Sstevel@tonic-gate 	uint8_t		struct_length;
1607c478bd9Sstevel@tonic-gate 	uint8_t		struct_cksum;
1617c478bd9Sstevel@tonic-gate 	uint8_t		struct_rev;
1627c478bd9Sstevel@tonic-gate 	uint8_t		undi_rev[3];
1637c478bd9Sstevel@tonic-gate 	uint16_t	undi_loader_off;
1647c478bd9Sstevel@tonic-gate 	uint16_t	stack_size;
1657c478bd9Sstevel@tonic-gate 	uint16_t	data_size;
1667c478bd9Sstevel@tonic-gate 	uint16_t	code_size;
1677c478bd9Sstevel@tonic-gate } PACKED undi_rom_id_t;
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate /* Storage buffers that we need in base memory.  We collect these into
1707c478bd9Sstevel@tonic-gate  * a single structure to make allocation simpler.
1717c478bd9Sstevel@tonic-gate  */
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate typedef struct undi_base_mem_xmit_data {
1747c478bd9Sstevel@tonic-gate 	MAC_ADDR		destaddr;
1757c478bd9Sstevel@tonic-gate 	t_PXENV_UNDI_TBD	tbd;
1767c478bd9Sstevel@tonic-gate } undi_base_mem_xmit_data_t;
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate typedef struct undi_base_mem_data {
1797c478bd9Sstevel@tonic-gate 	undi_call_info_t	undi_call_info;
1807c478bd9Sstevel@tonic-gate 	pxenv_structure_t	pxs;
1817c478bd9Sstevel@tonic-gate 	undi_base_mem_xmit_data_t xmit_data;
1827c478bd9Sstevel@tonic-gate 	char			xmit_buffer[ETH_FRAME_LEN];
1837c478bd9Sstevel@tonic-gate 	char			irq_handler[0]; /* Must be last in structure */
1847c478bd9Sstevel@tonic-gate } undi_base_mem_data_t;
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate /* Macros and data structures used when freeing bits of base memory
1877c478bd9Sstevel@tonic-gate  * used by the UNDI driver.
1887c478bd9Sstevel@tonic-gate  */
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate #define FIRING_SQUAD_TARGET_SIZE 8
1917c478bd9Sstevel@tonic-gate #define FIRING_SQUAD_TARGET_INDEX(x) ( (x) / FIRING_SQUAD_TARGET_SIZE )
1927c478bd9Sstevel@tonic-gate #define FIRING_SQUAD_TARGET_BIT(x) ( (x) % FIRING_SQUAD_TARGET_SIZE )
1937c478bd9Sstevel@tonic-gate typedef struct firing_squad_lineup {
1947c478bd9Sstevel@tonic-gate 	uint8_t targets[ 640 / FIRING_SQUAD_TARGET_SIZE ];
1957c478bd9Sstevel@tonic-gate } firing_squad_lineup_t;
1967c478bd9Sstevel@tonic-gate typedef enum firing_squad_shoot {
1977c478bd9Sstevel@tonic-gate 	DONTSHOOT = 0,
1987c478bd9Sstevel@tonic-gate 	SHOOT = 1
1997c478bd9Sstevel@tonic-gate } firing_squad_shoot_t;
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate /* Driver private data structure.
2027c478bd9Sstevel@tonic-gate  */
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate typedef struct undi {
2057c478bd9Sstevel@tonic-gate 	/* Pointers to various data structures */
2067c478bd9Sstevel@tonic-gate 	pnp_bios_t		*pnp_bios;
2077c478bd9Sstevel@tonic-gate 	rom_t			*rom;
2087c478bd9Sstevel@tonic-gate 	undi_rom_id_t		*undi_rom_id;
2097c478bd9Sstevel@tonic-gate 	pxe_t			*pxe;
2107c478bd9Sstevel@tonic-gate 	undi_call_info_t	*undi_call_info;
2117c478bd9Sstevel@tonic-gate 	pxenv_structure_t	*pxs;
2127c478bd9Sstevel@tonic-gate 	undi_base_mem_xmit_data_t *xmit_data;
2137c478bd9Sstevel@tonic-gate 	/* Pointers and sizes to keep track of allocated base memory */
2147c478bd9Sstevel@tonic-gate 	undi_base_mem_data_t	*base_mem_data;
2157c478bd9Sstevel@tonic-gate 	void			*driver_code;
2167c478bd9Sstevel@tonic-gate 	size_t			driver_code_size;
2177c478bd9Sstevel@tonic-gate 	void			*driver_data;
2187c478bd9Sstevel@tonic-gate 	size_t			driver_data_size;
2197c478bd9Sstevel@tonic-gate 	char			*xmit_buffer;
2207c478bd9Sstevel@tonic-gate 	/* Flags.  We keep our own instead of trusting the UNDI driver
2217c478bd9Sstevel@tonic-gate 	 * to have implemented PXENV_UNDI_GET_STATE correctly.  Plus
2227c478bd9Sstevel@tonic-gate 	 * there's the small issue of PXENV_UNDI_GET_STATE being the
2237c478bd9Sstevel@tonic-gate 	 * same API call as PXENV_STOP_UNDI...
2247c478bd9Sstevel@tonic-gate 	 */
2257c478bd9Sstevel@tonic-gate 	uint8_t prestarted;	/* pxenv_start_undi() has been called */
2267c478bd9Sstevel@tonic-gate 	uint8_t started;	/* pxenv_undi_startup() has been called */
2277c478bd9Sstevel@tonic-gate 	uint8_t	initialized;	/* pxenv_undi_initialize() has been called */
2287c478bd9Sstevel@tonic-gate 	uint8_t opened;		/* pxenv_undi_open() has been called */
2297c478bd9Sstevel@tonic-gate 	/* Parameters that we need to store for future reference
2307c478bd9Sstevel@tonic-gate 	 */
2317c478bd9Sstevel@tonic-gate 	struct pci_device	pci;
2327c478bd9Sstevel@tonic-gate 	irq_t			irq;
2337c478bd9Sstevel@tonic-gate } undi_t;
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate /* Constants
2367c478bd9Sstevel@tonic-gate  */
2377c478bd9Sstevel@tonic-gate 
2387c478bd9Sstevel@tonic-gate #define HUNT_FOR_PIXIES 0
2397c478bd9Sstevel@tonic-gate #define HUNT_FOR_UNDI_ROMS 1
240