/*
 **************************************************************************
 *
 * Network driver interface for netboot bootrom
 *
 * Module:  gethwinfo.S86
 * Purpose: Support routines to determine type of NIC hardware
 * Entries: sethwinfo
 *
 **************************************************************************
 *
 * Copyright (C) 1998-2007 Gero Kuhlmann <gero@gkminix.han.de>
 *
 *  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: gethwinfo.S86,v 1.7 2007/01/06 18:30:48 gkminix Exp $
 *
 */


/*
 **************************************************************************
 *
 * Load assembler macros and other include files.
 *
 */
#include <common.i86>
#include <romconfig.i86>
#include <pxe/undi.i86>
#include <pxe/loader.i86>
#include <system/bios.i86>
#include <system/pci.i86>

.file __FILE__
.line __LINE__



/*
 **************************************************************************
 *
 * Start BSS segment.
 *
 */
	.bss

	.global	devinfo

	.lcomm	devinfo,getnic_size	# structure holding NIC hardware info




/*
 **************************************************************************
 *
 * Start data segment.
 *
 */
	_rodata

btypes:	.byte	UNDI_NIC_PNP		# array used to convert PXE bus types
	.byte	UNDI_NIC_PNP		# into UNDI bus types
	.byte	UNDI_NIC_PNP
	.byte	UNDI_NIC_PCI
	.byte	UNDI_NIC_PNP
	.byte	UNDI_NIC_CB




/*
 **************************************************************************
 *
 * Start code segment.
 *
 */
	.text

	.global	sethwinfo

	.extern	bustyp
	.extern	drvid



/*
 **************************************************************************
 *
 * Setup hardware info
 * Input:  FS:BX  -  Pointer to UNDI loader structure
 * Output: Carry flag set if error
 * Registers changed: EAX
 *
 */
sethwinfo:

	push	si
	push	di
	push	ebx
	push	ecx
	push	edx

/*
 * First convert the bus type value into an UNDI compliant value. Also save
 * the driver ID or PCI vendor/device ID. Both values have the same size and
 * are at the same offset.
 */

	mov	eax,dword ptr cs:[drvid]
	mov	o_ugnt_pnp_eisa_devid[devinfo],eax
	movzx	si,byte ptr cs:[bustyp]
	mov	al,btypes[si]
	mov	o_ugnt_nictype[devinfo],al
	cmp	al,UNDI_NIC_PCI
	jne	5f

/*
 * Get information for PCI network card using PCI BIOS. The network loader
 * always gets us a PCI PFA number, which we can use to determine the vendor
 * and device IDs.
 */

	mov	bx,fs:o_ul_ax[bx]
	cmp	bx,0xFFFF		# check that we really have a PFA
	je	8f
	mov	o_ugnt_pci_busdevfunc[devinfo],bx

	mov	di,PCI_REG_VENDOR_ID
	mov	ax,PCI_FUNC_READ_WORD
	int	INT_PCI			# get vendor ID
	jc	8f
	cmp	cx,o_ugnt_pci_vendid[devinfo]
	jne	8f			# check vendor ID

	mov	di,PCI_REG_DEVICE_ID
	mov	ax,PCI_FUNC_READ_WORD
	int	INT_PCI			# get device ID
	jc	8f
	cmp	cx,o_ugnt_pci_devid[devinfo]
	jne	8f			# check device ID

	mov	di,PCI_REG_REVISION
	mov	ax,PCI_FUNC_READ_BYTE
	int	INT_PCI			# get hardware revision number
	jc	2f
	mov	o_ugnt_pci_revision[devinfo],cl

2:	mov	di,PCI_REG_SUBSYS_VEND
	mov	ax,PCI_FUNC_READ_WORD
	int	INT_PCI			# get sub-vendor ID
	jc	3f
	mov	o_ugnt_pci_subvendid[devinfo],cx

3:	mov	di,PCI_REG_SUBSYS_ID
	mov	ax,PCI_FUNC_READ_WORD
	int	INT_PCI			# get sub-device ID
	jc	6f
	mov	o_ugnt_pci_subdevid[devinfo],cx
	jmp	6f

/*
 * For PnP/EISA cards we just save the card select number and the EISA
 * device ID. The class values are the same for both PnP and PCI, and
 * are also at the same offsets.
 */

5:	mov	ax,fs:o_ul_bx[bx]
	mov	word ptr o_ugnt_pnp_cardselnum[devinfo],ax
6:	mov	byte ptr o_ugnt_pnp_baseclass[devinfo],PCI_BASE_NETWORK
	clc
	jmp	9f

8:	stc				# return with error
9:	pop	edx
	pop	ecx
	pop	ebx
	pop	di
	pop	si
	ret



/*
 **************************************************************************
 *
 */
	.end

