mirror of
https://git.savannah.gnu.org/git/grub.git
synced 2026-10-25 16:49:23 +00:00
Remove all files not related to Multiboot.
This commit is contained in:
1 parent
89e617e847
commit
29bfa2494c
179 files changed
-99150
No files matched your search
@@ -1,7 +0,0 @@
|
||||
See the Bug Tracking System for GNU GRUB on Savannah. The URL is:
|
||||
|
||||
http://savannah.gnu.org/bugs/?group_id=68 (without SSL)
|
||||
|
||||
or
|
||||
|
||||
https://savannah.gnu.org/bugs/?group_id=68 (with SSL)
|
||||
-60
@@ -1,60 +0,0 @@
|
||||
-*- text -*-
|
||||
|
||||
This is a list of random notes for GRUB maintainers. If you are not a
|
||||
maintainer, you need to ask maintainers to do these instead of doing
|
||||
these yourself.
|
||||
|
||||
How to update the online manual: (FIXME: this is obsoelete)
|
||||
1. Copy docs/*.texi (excluding "multiboot.texi") to fencepost.gnu.org.
|
||||
2. Make a symbolic link from ~mohit/gnudoc/gnudoc_template to the
|
||||
directory under which *.texi were copied, if the link isn't present.
|
||||
3. Run ``~mohit/gnudoc/gendocs.sh grub "GNU GRUB Manual"''.
|
||||
4. Copy the contents of the directory ``manual'' to
|
||||
gnudist.gnu.org:~ftp/gnu/Manuals/grub-VERSION (VERSION is, for
|
||||
example, 1.0).
|
||||
5. Run ``ln -sf grub-VERSION grub'' in gnudist.gnu.org:~ftp/gnu/Manuals.
|
||||
6. Run ``cd grub; ln -s grub.html index.html''.
|
||||
7. Verify the new online manual with a WWW browser.
|
||||
8. Update manual.html by hand.
|
||||
|
||||
How to release a version:
|
||||
1. Check out the source tree from the CVS from scratch.
|
||||
2. Check if ``make distcheck'' succeeds.
|
||||
3. Run ``util/grub-image''.
|
||||
4. Check the resulted images, for example, using bochs.
|
||||
5. Copy grub-VERSION.tar.gz, grub-VERSION-i386-pc.tar.gz and
|
||||
grub-VERSION-i386-pc.ext2fs to fencepost.gnu.org:~ftp/gnu/grub.
|
||||
6. Move older files in that directory above to the directory ``old'',
|
||||
if you think they are eyesores.
|
||||
7. Post an announcement to bug-grub@gnu.org. It would be a good idea to
|
||||
send a carbon copy to bug-hurd@gnu.org and
|
||||
debian-hurd@lists.debian.org. If the announcement is for a stable
|
||||
version, you can inform info-gnu@gnu.org as well.
|
||||
8. Optionally, post an announcement to Freshmeat.net.
|
||||
|
||||
Legal issues:
|
||||
1. If a patch is not significant (in size), you don't have to care about
|
||||
the copyright.
|
||||
2. If a patch is significant, you shouldn't apply the patch to the CVS.
|
||||
Before doing that, you must ask the contributor to assign or disclaim
|
||||
the copyright. Send ``/gd/gnuorg/request-assign.changes'' or
|
||||
``/gd/gnuorg/request-assign.future'' to the contributor, and wait
|
||||
until the FSF finishes the legal work.
|
||||
3. You can check if a contributor has already assigned his/her copyright
|
||||
to the FSF by looking at ``/gd/gnuorg/copyright.list''.
|
||||
|
||||
What you should have in your mind:
|
||||
1. Don't add features unnecessarily! You may think it is a Good Thing to
|
||||
have more features, but you must be prepared for more burdens.
|
||||
DO THAT ONLY IF YOU BELIEVE THAT THE FEATURE IS ESSENTIAL.
|
||||
2. Don't break backward-compatibility! Don't apply any patch which could
|
||||
break existing features. Otherwise you would receive a lot of
|
||||
complaints. DO THAT ONLY IF YOU BELIEVE THAT THE INCOMPATIBILITY IS
|
||||
INEVITABLE.
|
||||
3. Write good code. Be not satisfied with ad hoc workarounds or quick
|
||||
hacks. NEVER WRITE BAD CODE.
|
||||
|
||||
Resources:
|
||||
* http://www.gnu.org/prep/maintain_toc.html
|
||||
* http://www.gnu.org/prep/standards_toc.html
|
||||
* http://www.gnu.org/server/fsf-html-style-sheet.html
|
||||
-605
@@ -1,605 +0,0 @@
|
||||
# Makefile.in generated by automake 1.9.4 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
top_builddir = .
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
INSTALL = @INSTALL@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
|
||||
$(srcdir)/Makefile.in $(srcdir)/config.h.in \
|
||||
$(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
|
||||
THANKS TODO compile config.guess config.sub depcomp install-sh \
|
||||
missing mkinstalldirs
|
||||
subdir = .
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
|
||||
configure.lineno configure.status.lineno
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
SOURCES =
|
||||
DIST_SOURCES =
|
||||
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
|
||||
html-recursive info-recursive install-data-recursive \
|
||||
install-exec-recursive install-info-recursive \
|
||||
install-recursive installcheck-recursive installdirs-recursive \
|
||||
pdf-recursive ps-recursive uninstall-info-recursive \
|
||||
uninstall-recursive
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DIST_SUBDIRS = $(SUBDIRS)
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
distdir = $(PACKAGE)-$(VERSION)
|
||||
top_distdir = $(distdir)
|
||||
am__remove_distdir = \
|
||||
{ test ! -d $(distdir) \
|
||||
|| { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
|
||||
&& rm -fr $(distdir); }; }
|
||||
DIST_ARCHIVES = $(distdir).tar.gz
|
||||
GZIP_ENV = --best
|
||||
distuninstallcheck_listfiles = find . -type f -print
|
||||
distcleancheck_listfiles = find . -type f -print
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMDEP_FALSE = @AMDEP_FALSE@
|
||||
AMDEP_TRUE = @AMDEP_TRUE@
|
||||
AMTAR = @AMTAR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
BUILD_EXAMPLE_KERNEL_FALSE = @BUILD_EXAMPLE_KERNEL_FALSE@
|
||||
BUILD_EXAMPLE_KERNEL_TRUE = @BUILD_EXAMPLE_KERNEL_TRUE@
|
||||
CC = @CC@
|
||||
CCAS = @CCAS@
|
||||
CCASFLAGS = @CCASFLAGS@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DISKLESS_SUPPORT_FALSE = @DISKLESS_SUPPORT_FALSE@
|
||||
DISKLESS_SUPPORT_TRUE = @DISKLESS_SUPPORT_TRUE@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FSYS_CFLAGS = @FSYS_CFLAGS@
|
||||
GRUB_CFLAGS = @GRUB_CFLAGS@
|
||||
GRUB_LIBS = @GRUB_LIBS@
|
||||
HERCULES_SUPPORT_FALSE = @HERCULES_SUPPORT_FALSE@
|
||||
HERCULES_SUPPORT_TRUE = @HERCULES_SUPPORT_TRUE@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAINT = @MAINT@
|
||||
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
|
||||
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
|
||||
NETBOOT_SUPPORT_FALSE = @NETBOOT_SUPPORT_FALSE@
|
||||
NETBOOT_SUPPORT_TRUE = @NETBOOT_SUPPORT_TRUE@
|
||||
NET_CFLAGS = @NET_CFLAGS@
|
||||
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||
OBJCOPY = @OBJCOPY@
|
||||
OBJEXT = @OBJEXT@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PERL = @PERL@
|
||||
RANLIB = @RANLIB@
|
||||
SERIAL_SPEED_SIMULATION_FALSE = @SERIAL_SPEED_SIMULATION_FALSE@
|
||||
SERIAL_SPEED_SIMULATION_TRUE = @SERIAL_SPEED_SIMULATION_TRUE@
|
||||
SERIAL_SUPPORT_FALSE = @SERIAL_SUPPORT_FALSE@
|
||||
SERIAL_SUPPORT_TRUE = @SERIAL_SUPPORT_TRUE@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STAGE1_CFLAGS = @STAGE1_CFLAGS@
|
||||
STAGE2_CFLAGS = @STAGE2_CFLAGS@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_OBJCOPY = @ac_ct_OBJCOPY@
|
||||
ac_ct_RANLIB = @ac_ct_RANLIB@
|
||||
ac_ct_STRIP = @ac_ct_STRIP@
|
||||
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
|
||||
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
datadir = @datadir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
|
||||
# Do not change this order if you don't know what you are doing.
|
||||
AUTOMAKE_OPTIONS = 1.7 gnu
|
||||
SUBDIRS = netboot stage2 stage1 lib grub util docs
|
||||
EXTRA_DIST = BUGS MAINTENANCE
|
||||
all: config.h
|
||||
$(MAKE) $(AM_MAKEFLAGS) all-recursive
|
||||
|
||||
.SUFFIXES:
|
||||
am--refresh:
|
||||
@:
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \
|
||||
cd $(srcdir) && $(AUTOMAKE) --gnu \
|
||||
&& exit 0; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
echo ' $(SHELL) ./config.status'; \
|
||||
$(SHELL) ./config.status;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
$(SHELL) ./config.status --recheck
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
cd $(srcdir) && $(AUTOCONF)
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
|
||||
|
||||
config.h: stamp-h1
|
||||
@if test ! -f $@; then \
|
||||
rm -f stamp-h1; \
|
||||
$(MAKE) stamp-h1; \
|
||||
else :; fi
|
||||
|
||||
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
|
||||
@rm -f stamp-h1
|
||||
cd $(top_builddir) && $(SHELL) ./config.status config.h
|
||||
$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
cd $(top_srcdir) && $(AUTOHEADER)
|
||||
rm -f stamp-h1
|
||||
touch $@
|
||||
|
||||
distclean-hdr:
|
||||
-rm -f config.h stamp-h1
|
||||
uninstall-info-am:
|
||||
|
||||
# This directory's subdirectories are mostly independent; you can cd
|
||||
# into them and run `make' without going through this Makefile.
|
||||
# To change the values of `make' variables: instead of editing Makefiles,
|
||||
# (1) if the variable is set in `config.status', edit `config.status'
|
||||
# (which will cause the Makefiles to be regenerated when you run `make');
|
||||
# (2) otherwise, pass the desired values on the `make' command line.
|
||||
$(RECURSIVE_TARGETS):
|
||||
@set fnord $$MAKEFLAGS; amf=$$2; \
|
||||
dot_seen=no; \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
echo "Making $$target in $$subdir"; \
|
||||
if test "$$subdir" = "."; then \
|
||||
dot_seen=yes; \
|
||||
local_target="$$target-am"; \
|
||||
else \
|
||||
local_target="$$target"; \
|
||||
fi; \
|
||||
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
||||
done; \
|
||||
if test "$$dot_seen" = "no"; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
|
||||
fi; test -z "$$fail"
|
||||
|
||||
mostlyclean-recursive clean-recursive distclean-recursive \
|
||||
maintainer-clean-recursive:
|
||||
@set fnord $$MAKEFLAGS; amf=$$2; \
|
||||
dot_seen=no; \
|
||||
case "$@" in \
|
||||
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
|
||||
*) list='$(SUBDIRS)' ;; \
|
||||
esac; \
|
||||
rev=''; for subdir in $$list; do \
|
||||
if test "$$subdir" = "."; then :; else \
|
||||
rev="$$subdir $$rev"; \
|
||||
fi; \
|
||||
done; \
|
||||
rev="$$rev ."; \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
for subdir in $$rev; do \
|
||||
echo "Making $$target in $$subdir"; \
|
||||
if test "$$subdir" = "."; then \
|
||||
local_target="$$target-am"; \
|
||||
else \
|
||||
local_target="$$target"; \
|
||||
fi; \
|
||||
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
||||
done && test -z "$$fail"
|
||||
tags-recursive:
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
|
||||
done
|
||||
ctags-recursive:
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
|
||||
done
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
|
||||
include_option=--etags-include; \
|
||||
empty_fix=.; \
|
||||
else \
|
||||
include_option=--include; \
|
||||
empty_fix=; \
|
||||
fi; \
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
test ! -f $$subdir/TAGS || \
|
||||
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
|
||||
fi; \
|
||||
done; \
|
||||
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$tags $$unique; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$tags $$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& cd $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) $$here
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
$(am__remove_distdir)
|
||||
mkdir $(distdir)
|
||||
$(mkdir_p) $(distdir)/util
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
|
||||
list='$(DISTFILES)'; for file in $$list; do \
|
||||
case $$file in \
|
||||
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
|
||||
esac; \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
dir="/$$dir"; \
|
||||
$(mkdir_p) "$(distdir)$$dir"; \
|
||||
else \
|
||||
dir=''; \
|
||||
fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||
fi; \
|
||||
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
test -d "$(distdir)/$$subdir" \
|
||||
|| $(mkdir_p) "$(distdir)/$$subdir" \
|
||||
|| exit 1; \
|
||||
distdir=`$(am__cd) $(distdir) && pwd`; \
|
||||
top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
|
||||
(cd $$subdir && \
|
||||
$(MAKE) $(AM_MAKEFLAGS) \
|
||||
top_distdir="$$top_distdir" \
|
||||
distdir="$$distdir/$$subdir" \
|
||||
distdir) \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
|
||||
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
|
||||
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
|
||||
! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
|
||||
|| chmod -R a+r $(distdir)
|
||||
dist-gzip: distdir
|
||||
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist-bzip2: distdir
|
||||
tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist-tarZ: distdir
|
||||
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist-shar: distdir
|
||||
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist-zip: distdir
|
||||
-rm -f $(distdir).zip
|
||||
zip -rq $(distdir).zip $(distdir)
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist dist-all: distdir
|
||||
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
|
||||
$(am__remove_distdir)
|
||||
|
||||
# This target untars the dist file and tries a VPATH configuration. Then
|
||||
# it guarantees that the distribution is self-contained by making another
|
||||
# tarfile.
|
||||
distcheck: dist
|
||||
case '$(DIST_ARCHIVES)' in \
|
||||
*.tar.gz*) \
|
||||
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
|
||||
*.tar.bz2*) \
|
||||
bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
|
||||
*.tar.Z*) \
|
||||
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
|
||||
*.shar.gz*) \
|
||||
GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
|
||||
*.zip*) \
|
||||
unzip $(distdir).zip ;;\
|
||||
esac
|
||||
chmod -R a-w $(distdir); chmod a+w $(distdir)
|
||||
mkdir $(distdir)/_build
|
||||
mkdir $(distdir)/_inst
|
||||
chmod a-w $(distdir)
|
||||
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
|
||||
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
|
||||
&& cd $(distdir)/_build \
|
||||
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
|
||||
$(DISTCHECK_CONFIGURE_FLAGS) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) check \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) install \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
|
||||
distuninstallcheck \
|
||||
&& chmod -R a-w "$$dc_install_base" \
|
||||
&& ({ \
|
||||
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
|
||||
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
|
||||
} || { rm -rf "$$dc_destdir"; exit 1; }) \
|
||||
&& rm -rf "$$dc_destdir" \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) dist \
|
||||
&& rm -rf $(DIST_ARCHIVES) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck
|
||||
$(am__remove_distdir)
|
||||
@(echo "$(distdir) archives ready for distribution: "; \
|
||||
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
|
||||
sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
|
||||
distuninstallcheck:
|
||||
@cd $(distuninstallcheck_dir) \
|
||||
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|
||||
|| { echo "ERROR: files left after uninstall:" ; \
|
||||
if test -n "$(DESTDIR)"; then \
|
||||
echo " (check DESTDIR support)"; \
|
||||
fi ; \
|
||||
$(distuninstallcheck_listfiles) ; \
|
||||
exit 1; } >&2
|
||||
distcleancheck: distclean
|
||||
@if test '$(srcdir)' = . ; then \
|
||||
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
|
||||
exit 1 ; \
|
||||
fi
|
||||
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|
||||
|| { echo "ERROR: files left in build directory after distclean:" ; \
|
||||
$(distcleancheck_listfiles) ; \
|
||||
exit 1; } >&2
|
||||
check-am: all-am
|
||||
check: check-recursive
|
||||
all-am: Makefile config.h
|
||||
installdirs: installdirs-recursive
|
||||
installdirs-am:
|
||||
install: install-recursive
|
||||
install-exec: install-exec-recursive
|
||||
install-data: install-data-recursive
|
||||
uninstall: uninstall-recursive
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-recursive
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-recursive
|
||||
|
||||
clean-am: clean-generic mostlyclean-am
|
||||
|
||||
distclean: distclean-recursive
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-generic distclean-hdr distclean-tags
|
||||
|
||||
dvi: dvi-recursive
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-recursive
|
||||
|
||||
info: info-recursive
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-info: install-info-recursive
|
||||
|
||||
install-man:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-recursive
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -rf $(top_srcdir)/autom4te.cache
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-recursive
|
||||
|
||||
mostlyclean-am: mostlyclean-generic
|
||||
|
||||
pdf: pdf-recursive
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-recursive
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-info-am
|
||||
|
||||
uninstall-info: uninstall-info-recursive
|
||||
|
||||
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \
|
||||
check-am clean clean-generic clean-recursive ctags \
|
||||
ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-shar \
|
||||
dist-tarZ dist-zip distcheck distclean distclean-generic \
|
||||
distclean-hdr distclean-recursive distclean-tags \
|
||||
distcleancheck distdir distuninstallcheck dvi dvi-am html \
|
||||
html-am info info-am install install-am install-data \
|
||||
install-data-am install-exec install-exec-am install-info \
|
||||
install-info-am install-man install-strip installcheck \
|
||||
installcheck-am installdirs installdirs-am maintainer-clean \
|
||||
maintainer-clean-generic maintainer-clean-recursive \
|
||||
mostlyclean mostlyclean-generic mostlyclean-recursive pdf \
|
||||
pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
|
||||
uninstall-info-am
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
@@ -1,102 +0,0 @@
|
||||
-*- Mode: Outline -*-
|
||||
|
||||
Before working on anything in this file, it's very important that you
|
||||
make contact with the core GRUB developers. Things herein might be
|
||||
slightly out of date or otherwise not easy to understand at first
|
||||
glance. So write to <bug-grub@gnu.org> first.
|
||||
|
||||
Priorities:
|
||||
Reported bugs generally have top priority.
|
||||
Non-reported and non-encountered bugs (things we know don't work,
|
||||
but don't really impede things) have lower priority.
|
||||
Things in this file are ranked with one to three !; the more, the
|
||||
higher priority.
|
||||
|
||||
|
||||
Things that should be done before 1.0:
|
||||
|
||||
* Finish the Multiboot Speicification 0.7. !!!
|
||||
|
||||
* Add more --disable-FOO options to configure, so that you can create a
|
||||
minimum GRUB image. This is useful for boot floppies because of the size
|
||||
restriction. !
|
||||
|
||||
* Implement a new version of track_int13, using Virtual 8086 Mode. !!!
|
||||
|
||||
* Add missing features of graphics support. !!
|
||||
|
||||
Things that should _not_ be done before 1.0:
|
||||
|
||||
* Add configuration inclusion support by adding a command "include". !
|
||||
|
||||
* Add automatic configuration support.
|
||||
|
||||
* Add bunzip2 support.
|
||||
|
||||
* Define the module system.
|
||||
|
||||
* Add BSD syntax support, using results of ioprobe to map drives. !
|
||||
(0x1f0-0x1f7 = primary IDE, 0x170-0x176 = secondary,
|
||||
0x1e8-0x1ef = tertiary, 0x168-0x16f = quaternary).
|
||||
|
||||
* Add a real scripting language, possibly retaining backward
|
||||
compatibility so that old config files can be used.
|
||||
|
||||
* Add internationalization support, emulating gettext as much as is
|
||||
feasible.
|
||||
|
||||
* Support other architectures than i386-pc.
|
||||
|
||||
* Add real memory management.
|
||||
|
||||
|
||||
Things that may be done anytime:
|
||||
|
||||
* Port the script ``grub-install'' to OpenBSD. At least you will have to
|
||||
modify the function `convert' so that it can translate a native device
|
||||
name into the corresponding GRUB drive representation. !
|
||||
|
||||
* Add a command to run a GRUB script file. !!
|
||||
|
||||
* Add commands to manipulate the menu from the command-line interface. !
|
||||
|
||||
* Make symbolic links work for BSD FFS.
|
||||
|
||||
* Add indirect block support to the BSD FFS filesystem code, so files
|
||||
larger than 16MB can be read.
|
||||
|
||||
* Fix-up FreeBSD, NetBSD (and OpenBSD ?) command-line boot
|
||||
parameters.
|
||||
|
||||
* Support embedding a Stage 1.5 in the "bootloader" area of a FFS
|
||||
partition. (We already have the code, but need an approval by an
|
||||
expert before turning on the support. Any volunteers?)
|
||||
|
||||
* Support embedding a Stage 1.5 in the EXT2_BOOT_LOADER_INO of an ext2fs
|
||||
partition, so that it won't be accidentally erased or modified by
|
||||
the kernel.
|
||||
|
||||
* Add ISA PnP support.
|
||||
|
||||
* Add more filesystems support (NTFS, etc.)
|
||||
|
||||
* Add more remote console support (parallel and net).
|
||||
|
||||
* Add (real) RAID support.
|
||||
|
||||
? Add a partition naming syntax that means ``the first partition of
|
||||
this type''. We need this for clean Hurd install floppies.
|
||||
Nope. Improving the `find' command would solve this problem.
|
||||
|
||||
* Add CDROM-chainloading support. It would be enough to support only
|
||||
BIOSes which have bootable-CDROM support (so you may use the "Bootable
|
||||
CDROM" BIOS calls). It is not trivial to support BIOSes without the
|
||||
capability to boot CDROM.
|
||||
|
||||
? Divide pxegrub into two parts, so the initial image doesn't exceed
|
||||
the 32KB limit. I'm not sure if this is really necessary, because the
|
||||
PXE standard just says that it is _recommended_ to improve the
|
||||
modularity of a boot image. Obviously, this reason doesn't apply to
|
||||
GRUB, as pxegrub is merely a secondary boot loader. So whether this
|
||||
task should be done depends on if existing PXE ROMs support >32KB
|
||||
images or not, after all.
|
||||
-366
@@ -1,366 +0,0 @@
|
||||
dnl grub_ASM_USCORE checks if C symbols get an underscore after
|
||||
dnl compiling to assembler.
|
||||
dnl Written by Pavel Roskin. Based on grub_ASM_EXT_C written by
|
||||
dnl Erich Boleyn and modified by OKUJI Yoshinori
|
||||
AC_DEFUN([grub_ASM_USCORE],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING([if C symbols get an underscore after compilation])
|
||||
AC_CACHE_VAL(grub_cv_asm_uscore,
|
||||
[cat > conftest.c <<\EOF
|
||||
int
|
||||
func (int *list)
|
||||
{
|
||||
*list = 0;
|
||||
return *list;
|
||||
}
|
||||
EOF
|
||||
|
||||
if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -S conftest.c]) && test -s conftest.s; then
|
||||
true
|
||||
else
|
||||
AC_MSG_ERROR([${CC-cc} failed to produce assembly code])
|
||||
fi
|
||||
|
||||
if grep _func conftest.s >/dev/null 2>&1; then
|
||||
grub_cv_asm_uscore=yes
|
||||
else
|
||||
grub_cv_asm_uscore=no
|
||||
fi
|
||||
|
||||
rm -f conftest*])
|
||||
|
||||
if test "x$grub_cv_asm_uscore" = xyes; then
|
||||
AC_DEFINE_UNQUOTED([HAVE_ASM_USCORE], $grub_cv_asm_uscore,
|
||||
[Define if C symbols get an underscore after compilation])
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([$grub_cv_asm_uscore])
|
||||
])
|
||||
|
||||
|
||||
dnl Some versions of `objcopy -O binary' vary their output depending
|
||||
dnl on the link address.
|
||||
AC_DEFUN([grub_PROG_OBJCOPY_ABSOLUTE],
|
||||
[AC_MSG_CHECKING([whether ${OBJCOPY} works for absolute addresses])
|
||||
AC_CACHE_VAL(grub_cv_prog_objcopy_absolute,
|
||||
[cat > conftest.c <<\EOF
|
||||
void
|
||||
cmain (void)
|
||||
{
|
||||
*((int *) 0x1000) = 2;
|
||||
}
|
||||
EOF
|
||||
|
||||
if AC_TRY_EVAL(ac_compile) && test -s conftest.o; then :
|
||||
else
|
||||
AC_MSG_ERROR([${CC-cc} cannot compile C source code])
|
||||
fi
|
||||
grub_cv_prog_objcopy_absolute=yes
|
||||
for link_addr in 2000 8000 7C00; do
|
||||
if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} ${LDFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then :
|
||||
else
|
||||
AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr])
|
||||
fi
|
||||
if AC_TRY_COMMAND([${OBJCOPY-objcopy} -O binary conftest.exec conftest]); then :
|
||||
else
|
||||
AC_MSG_ERROR([${OBJCOPY-objcopy} cannot create binary files])
|
||||
fi
|
||||
if test ! -f conftest.old || AC_TRY_COMMAND([cmp -s conftest.old conftest]); then
|
||||
mv -f conftest conftest.old
|
||||
else
|
||||
grub_cv_prog_objcopy_absolute=no
|
||||
break
|
||||
fi
|
||||
done
|
||||
rm -f conftest*])
|
||||
AC_MSG_RESULT([$grub_cv_prog_objcopy_absolute])])
|
||||
|
||||
dnl Mass confusion!
|
||||
dnl Older versions of GAS interpret `.code16' to mean ``generate 32-bit
|
||||
dnl instructions, but implicitly insert addr32 and data32 bytes so
|
||||
dnl that the code works in real mode''.
|
||||
dnl
|
||||
dnl Newer versions of GAS interpret `.code16' to mean ``generate 16-bit
|
||||
dnl instructions,'' which seems right. This requires the programmer
|
||||
dnl to explicitly insert addr32 and data32 instructions when they want
|
||||
dnl them.
|
||||
dnl
|
||||
dnl We only support the newer versions, because the old versions cause
|
||||
dnl major pain, by requiring manual assembly to get 16-bit instructions into
|
||||
dnl stage1/stage1.S.
|
||||
AC_DEFUN([grub_ASM_ADDR32],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_REQUIRE([grub_ASM_PREFIX_REQUIREMENT])
|
||||
AC_MSG_CHECKING([for .code16 addr32 assembler support])
|
||||
AC_CACHE_VAL(grub_cv_asm_addr32,
|
||||
[cat > conftest.s.in <<\EOF
|
||||
.code16
|
||||
l1: @ADDR32@ movb %al, l1
|
||||
EOF
|
||||
|
||||
if test "x$grub_cv_asm_prefix_requirement" = xyes; then
|
||||
sed -e s/@ADDR32@/addr32/ < conftest.s.in > conftest.s
|
||||
else
|
||||
sed -e s/@ADDR32@/addr32\;/ < conftest.s.in > conftest.s
|
||||
fi
|
||||
|
||||
if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then
|
||||
grub_cv_asm_addr32=yes
|
||||
else
|
||||
grub_cv_asm_addr32=no
|
||||
fi
|
||||
|
||||
rm -f conftest*])
|
||||
|
||||
AC_MSG_RESULT([$grub_cv_asm_addr32])])
|
||||
|
||||
dnl
|
||||
dnl Later versions of GAS requires that addr32 and data32 prefixes
|
||||
dnl appear in the same lines as the instructions they modify, while
|
||||
dnl earlier versions requires that they appear in separate lines.
|
||||
AC_DEFUN([grub_ASM_PREFIX_REQUIREMENT],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING(dnl
|
||||
[whether addr32 must be in the same line as the instruction])
|
||||
AC_CACHE_VAL(grub_cv_asm_prefix_requirement,
|
||||
[cat > conftest.s <<\EOF
|
||||
.code16
|
||||
l1: addr32 movb %al, l1
|
||||
EOF
|
||||
|
||||
if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then
|
||||
grub_cv_asm_prefix_requirement=yes
|
||||
else
|
||||
grub_cv_asm_prefix_requirement=no
|
||||
fi
|
||||
|
||||
rm -f conftest*])
|
||||
|
||||
if test "x$grub_cv_asm_prefix_requirement" = xyes; then
|
||||
grub_tmp_addr32="addr32"
|
||||
grub_tmp_data32="data32"
|
||||
else
|
||||
grub_tmp_addr32="addr32;"
|
||||
grub_tmp_data32="data32;"
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED([ADDR32], $grub_tmp_addr32,
|
||||
[Define it to \"addr32\" or \"addr32;\" to make GAS happy])
|
||||
AC_DEFINE_UNQUOTED([DATA32], $grub_tmp_data32,
|
||||
[Define it to \"data32\" or \"data32;\" to make GAS happy])
|
||||
|
||||
AC_MSG_RESULT([$grub_cv_asm_prefix_requirement])])
|
||||
|
||||
dnl
|
||||
dnl Older versions of GAS require that absolute indirect calls/jumps are
|
||||
dnl not prefixed with `*', while later versions warn if not prefixed.
|
||||
AC_DEFUN([grub_ASM_ABSOLUTE_WITHOUT_ASTERISK],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING(dnl
|
||||
[whether an absolute indirect call/jump must not be prefixed with an asterisk])
|
||||
AC_CACHE_VAL(grub_cv_asm_absolute_without_asterisk,
|
||||
[cat > conftest.s <<\EOF
|
||||
lcall *(offset)
|
||||
offset:
|
||||
.long 0
|
||||
.word 0
|
||||
EOF
|
||||
|
||||
if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then
|
||||
grub_cv_asm_absolute_without_asterisk=no
|
||||
else
|
||||
grub_cv_asm_absolute_without_asterisk=yes
|
||||
fi
|
||||
|
||||
rm -f conftest*])
|
||||
|
||||
if test "x$grub_cv_asm_absolute_without_asterisk" = xyes; then
|
||||
AC_DEFINE(ABSOLUTE_WITHOUT_ASTERISK, 1, [Define if an absolute indirect call/jump must NOT be prefixed with `*'])
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([$grub_cv_asm_absolute_without_asterisk])])
|
||||
|
||||
dnl
|
||||
dnl grub_CHECK_START_SYMBOL checks if start is automatically defined by
|
||||
dnl the compiler.
|
||||
dnl Written by OKUJI Yoshinori
|
||||
AC_DEFUN([grub_CHECK_START_SYMBOL],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING([if start is defined by the compiler])
|
||||
AC_CACHE_VAL(grub_cv_check_start_symbol,
|
||||
[AC_TRY_LINK([], [asm ("incl start")],
|
||||
grub_cv_check_start_symbol=yes,
|
||||
grub_cv_check_start_symbol=no)])
|
||||
|
||||
if test "x$grub_cv_check_start_symbol" = xyes; then
|
||||
AC_DEFINE(HAVE_START_SYMBOL, 1, [Define if start is defined])
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([$grub_cv_check_start_symbol])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl grub_CHECK_USCORE_START_SYMBOL checks if _start is automatically
|
||||
dnl defined by the compiler.
|
||||
dnl Written by OKUJI Yoshinori
|
||||
AC_DEFUN([grub_CHECK_USCORE_START_SYMBOL],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING([if _start is defined by the compiler])
|
||||
AC_CACHE_VAL(grub_cv_check_uscore_start_symbol,
|
||||
[AC_TRY_LINK([], [asm ("incl _start")],
|
||||
grub_cv_check_uscore_start_symbol=yes,
|
||||
grub_cv_check_uscore_start_symbol=no)])
|
||||
|
||||
if test "x$grub_cv_check_uscore_start_symbol" = xyes; then
|
||||
AC_DEFINE(HAVE_USCORE_START_SYMBOL, 1, [Define if _start is defined])
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([$grub_cv_check_uscore_start_symbol])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl grub_CHECK_USCORE_USCORE_BSS_START_SYMBOL checks if __bss_start is
|
||||
dnl automatically defined by the compiler.
|
||||
dnl Written by Michael Hohmoth.
|
||||
AC_DEFUN([grub_CHECK_USCORE_USCORE_BSS_START_SYMBOL],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING([if __bss_start is defined by the compiler])
|
||||
AC_CACHE_VAL(grub_cv_check_uscore_uscore_bss_start_symbol,
|
||||
[AC_TRY_LINK([], [asm ("incl __bss_start")],
|
||||
grub_cv_check_uscore_uscore_bss_start_symbol=yes,
|
||||
grub_cv_check_uscore_uscore_bss_start_symbol=no)])
|
||||
|
||||
if test "x$grub_cv_check_uscore_uscore_bss_start_symbol" = xyes; then
|
||||
AC_DEFINE(HAVE_USCORE_USCORE_BSS_START_SYMBOL, 1, [Define if __bss_start is defined])
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([$grub_cv_check_uscore_uscore_bss_start_symbol])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl grub_CHECK_EDATA_SYMBOL checks if edata is automatically defined by the
|
||||
dnl compiler.
|
||||
dnl Written by Michael Hohmuth.
|
||||
AC_DEFUN([grub_CHECK_EDATA_SYMBOL],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING([if edata is defined by the compiler])
|
||||
AC_CACHE_VAL(grub_cv_check_edata_symbol,
|
||||
[AC_TRY_LINK([], [asm ("incl edata")],
|
||||
grub_cv_check_edata_symbol=yes,
|
||||
grub_cv_check_edata_symbol=no)])
|
||||
|
||||
if test "x$grub_cv_check_edata_symbol" = xyes; then
|
||||
AC_DEFINE(HAVE_EDATA_SYMBOL, 1, [Define if edata is defined])
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([$grub_cv_check_edata_symbol])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl grub_CHECK_USCORE_EDATA_SYMBOL checks if _edata is automatically
|
||||
dnl defined by the compiler.
|
||||
dnl Written by Michael Hohmuth.
|
||||
AC_DEFUN([grub_CHECK_USCORE_EDATA_SYMBOL],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING([if _edata is defined by the compiler])
|
||||
AC_CACHE_VAL(grub_cv_check_uscore_edata_symbol,
|
||||
[AC_TRY_LINK([], [asm ("incl _edata")],
|
||||
grub_cv_check_uscore_edata_symbol=yes,
|
||||
grub_cv_check_uscore_edata_symbol=no)])
|
||||
|
||||
if test "x$grub_cv_check_uscore_edata_symbol" = xyes; then
|
||||
AC_DEFINE(HAVE_USCORE_EDATA_SYMBOL, 1, [Define if _edata is defined])
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([$grub_cv_check_uscore_edata_symbol])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl grub_CHECK_END_SYMBOL checks if end is automatically defined by the
|
||||
dnl compiler.
|
||||
dnl Written by OKUJI Yoshinori
|
||||
AC_DEFUN([grub_CHECK_END_SYMBOL],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING([if end is defined by the compiler])
|
||||
AC_CACHE_VAL(grub_cv_check_end_symbol,
|
||||
[AC_TRY_LINK([], [asm ("incl end")],
|
||||
grub_cv_check_end_symbol=yes,
|
||||
grub_cv_check_end_symbol=no)])
|
||||
|
||||
if test "x$grub_cv_check_end_symbol" = xyes; then
|
||||
AC_DEFINE(HAVE_END_SYMBOL, 1, [Define if end is defined])
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([$grub_cv_check_end_symbol])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl grub_CHECK_USCORE_END_SYMBOL checks if _end is automatically defined
|
||||
dnl by the compiler.
|
||||
dnl Written by OKUJI Yoshinori
|
||||
AC_DEFUN([grub_CHECK_USCORE_END_SYMBOL],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING([if _end is defined by the compiler])
|
||||
AC_CACHE_VAL(grub_cv_check_uscore_end_symbol,
|
||||
[AC_TRY_LINK([], [asm ("incl _end")],
|
||||
grub_cv_check_uscore_end_symbol=yes,
|
||||
grub_cv_check_uscore_end_symbol=no)])
|
||||
|
||||
if test "x$grub_cv_check_uscore_end_symbol" = xyes; then
|
||||
AC_DEFINE(HAVE_USCORE_END_SYMBOL, 1, [Define if end is defined])
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([$grub_cv_check_uscore_end_symbol])
|
||||
])
|
||||
|
||||
dnl grub_DEFINE_FILE(MACRO_NAME, FILE_NAME, DESCRIPTION)
|
||||
dnl grub_DEFINE_FILE defines a macro as the contents of a file safely.
|
||||
dnl Replace some escape sequences, because autoconf doesn't handle them
|
||||
dnl gracefully.
|
||||
dnl Written by OKUJI Yoshinori.
|
||||
AC_DEFUN([grub_DEFINE_FILE],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
# Because early versions of GNU sed 3.x are too buggy, use a C program
|
||||
# instead of shell commands. *sigh*
|
||||
cat >conftest.c <<\EOF
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int c;
|
||||
|
||||
while ((c = getchar ()) != EOF)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
fputs ("\\n", stdout);
|
||||
break;
|
||||
case '\r':
|
||||
fputs ("\\r", stdout);
|
||||
break;
|
||||
case '\\':
|
||||
fputs ("\\\\", stdout);
|
||||
break;
|
||||
case '"':
|
||||
fputs ("\\\"", stdout);
|
||||
break;
|
||||
default:
|
||||
putchar (c);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
|
||||
if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} conftest.c -o conftest]) && test -s conftest; then
|
||||
grub_tmp_value=`./conftest < "[$2]"`
|
||||
else
|
||||
AC_MSG_ERROR([${CC-cc} failed to produce an executable file])
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED([$1], "$grub_tmp_value", [$3])
|
||||
rm -f conftest*
|
||||
])
|
||||
Vendored
-1061
File diff suppressed because it is too large.
Load diff
@@ -1,142 +0,0 @@
|
||||
#! /bin/sh
|
||||
# Wrapper for compilers which do not understand `-c -o'.
|
||||
|
||||
scriptversion=2004-10-12.08
|
||||
|
||||
# Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
# 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, or (at your option)
|
||||
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Wrapper for compilers which do not understand `-c -o'.
|
||||
Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
|
||||
arguments, and rename the output as expected.
|
||||
|
||||
If you are trying to build a whole package this is not the
|
||||
right script to run: please start by reading the file `INSTALL'.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit 0
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "compile $scriptversion"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
ofile=
|
||||
cfile=
|
||||
eat=
|
||||
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as `compile cc -o foo foo.c'.
|
||||
# So we strip `-o arg' only if arg is an object.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.obj)
|
||||
ofile=$2
|
||||
;;
|
||||
*)
|
||||
set x "$@" -o "$2"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*.c)
|
||||
cfile=$1
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if test -z "$ofile" || test -z "$cfile"; then
|
||||
# If no `-o' option was seen then we might have been invoked from a
|
||||
# pattern rule where we don't need one. That is ok -- this is a
|
||||
# normal compilation that the losing compiler can handle. If no
|
||||
# `.c' file was seen then we are probably linking. That is also
|
||||
# ok.
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
# Name of file we expect compiler to create.
|
||||
cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
|
||||
|
||||
# Create the lock directory.
|
||||
# Note: use `[/.-]' here to ensure that we don't use the same name
|
||||
# that we are using for the .o file. Also, base the name on the expected
|
||||
# object file name, since that is what matters with a parallel build.
|
||||
lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d
|
||||
while true; do
|
||||
if mkdir "$lockdir" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
# FIXME: race condition here if user kills between mkdir and trap.
|
||||
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
||||
|
||||
# Run the compile.
|
||||
"$@"
|
||||
ret=$?
|
||||
|
||||
if test -f "$cofile"; then
|
||||
mv "$cofile" "$ofile"
|
||||
elif test -f "${cofile}bj"; then
|
||||
mv "${cofile}bj" "$ofile"
|
||||
fi
|
||||
|
||||
rmdir "$lockdir"
|
||||
exit $ret
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
||||
Vendored
-1453
File diff suppressed because it is too large.
Load diff
-106
@@ -1,106 +0,0 @@
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define if an absolute indirect call/jump must NOT be prefixed with `*' */
|
||||
#undef ABSOLUTE_WITHOUT_ASTERISK
|
||||
|
||||
/* Define it to \"addr32\" or \"addr32;\" to make GAS happy */
|
||||
#undef ADDR32
|
||||
|
||||
/* Define if you don't want to pass the mem= option to Linux */
|
||||
#undef AUTO_LINUX_MEM_OPT
|
||||
|
||||
/* Define it to \"data32\" or \"data32;\" to make GAS happy */
|
||||
#undef DATA32
|
||||
|
||||
/* Define if C symbols get an underscore after compilation */
|
||||
#undef HAVE_ASM_USCORE
|
||||
|
||||
/* Define to 1 if you have the <curses.h> header file. */
|
||||
#undef HAVE_CURSES_H
|
||||
|
||||
/* Define if edata is defined */
|
||||
#undef HAVE_EDATA_SYMBOL
|
||||
|
||||
/* Define if end is defined */
|
||||
#undef HAVE_END_SYMBOL
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define if you have a curses library */
|
||||
#undef HAVE_LIBCURSES
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the <ncurses/curses.h> header file. */
|
||||
#undef HAVE_NCURSES_CURSES_H
|
||||
|
||||
/* Define to 1 if you have the <ncurses.h> header file. */
|
||||
#undef HAVE_NCURSES_H
|
||||
|
||||
/* Define if opendisk() in -lutil can be used */
|
||||
#undef HAVE_OPENDISK
|
||||
|
||||
/* Define if start is defined */
|
||||
#undef HAVE_START_SYMBOL
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define if _edata is defined */
|
||||
#undef HAVE_USCORE_EDATA_SYMBOL
|
||||
|
||||
/* Define if end is defined */
|
||||
#undef HAVE_USCORE_END_SYMBOL
|
||||
|
||||
/* Define if _start is defined */
|
||||
#undef HAVE_USCORE_START_SYMBOL
|
||||
|
||||
/* Define if __bss_start is defined */
|
||||
#undef HAVE_USCORE_USCORE_BSS_START_SYMBOL
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define if there is user specified preset menu string */
|
||||
#undef PRESET_MENU_STRING
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
Vendored
-1566
File diff suppressed because it is too large.
Load diff
@@ -1,522 +0,0 @@
|
||||
#! /bin/sh
|
||||
# depcomp - compile a program generating dependencies as side-effects
|
||||
|
||||
scriptversion=2004-05-31.23
|
||||
|
||||
# Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
# 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, or (at your option)
|
||||
# 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., 59 Temple Place - Suite 330, Boston, MA
|
||||
# 02111-1307, USA.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Run PROGRAMS ARGS to compile a file, generating dependencies
|
||||
as side-effects.
|
||||
|
||||
Environment variables:
|
||||
depmode Dependency tracking mode.
|
||||
source Source file read by `PROGRAMS ARGS'.
|
||||
object Object file output by `PROGRAMS ARGS'.
|
||||
DEPDIR directory where to store dependencies.
|
||||
depfile Dependency file to output.
|
||||
tmpdepfile Temporary file to use when outputing dependencies.
|
||||
libtool Whether libtool is used (yes/no).
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit 0
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "depcomp $scriptversion"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
|
||||
depfile=${depfile-`echo "$object" |
|
||||
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
|
||||
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||
|
||||
rm -f "$tmpdepfile"
|
||||
|
||||
# Some modes work just like other modes, but use different flags. We
|
||||
# parameterize here, but still list the modes in the big case below,
|
||||
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
||||
# here, because this file can only contain one case statement.
|
||||
if test "$depmode" = hp; then
|
||||
# HP compiler uses -M and no extra arg.
|
||||
gccflag=-M
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
if test "$depmode" = dashXmstdout; then
|
||||
# This is just like dashmstdout with a different argument.
|
||||
dashmflag=-xM
|
||||
depmode=dashmstdout
|
||||
fi
|
||||
|
||||
case "$depmode" in
|
||||
gcc3)
|
||||
## gcc 3 implements dependency tracking that does exactly what
|
||||
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
mv "$tmpdepfile" "$depfile"
|
||||
;;
|
||||
|
||||
gcc)
|
||||
## There are various ways to get dependency output from gcc. Here's
|
||||
## why we pick this rather obscure method:
|
||||
## - Don't want to use -MD because we'd like the dependencies to end
|
||||
## up in a subdir. Having to rename by hand is ugly.
|
||||
## (We might end up doing this anyway to support other compilers.)
|
||||
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
||||
## -MM, not -M (despite what the docs say).
|
||||
## - Using -M directly means running the compiler twice (even worse
|
||||
## than renaming).
|
||||
if test -z "$gccflag"; then
|
||||
gccflag=-MD,
|
||||
fi
|
||||
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
||||
## The second -e expression handles DOS-style file names with drive letters.
|
||||
sed -e 's/^[^:]*: / /' \
|
||||
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||
## This next piece of magic avoids the `deleted header file' problem.
|
||||
## The problem is that when a header file which appears in a .P file
|
||||
## is deleted, the dependency causes make to die (because there is
|
||||
## typically no way to rebuild the header). We avoid this by adding
|
||||
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||
## this for us directly.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" |
|
||||
## Some versions of gcc put a space before the `:'. On the theory
|
||||
## that the space means something, we add a space to the output as
|
||||
## well.
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
sgi)
|
||||
if test "$libtool" = yes; then
|
||||
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
||||
else
|
||||
"$@" -MDupdate "$tmpdepfile"
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
|
||||
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
||||
echo "$object : \\" > "$depfile"
|
||||
|
||||
# Clip off the initial element (the dependent). Don't try to be
|
||||
# clever and replace this with sed code, as IRIX sed won't handle
|
||||
# lines with more than a fixed number of characters (4096 in
|
||||
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||
# the IRIX cc adds comments like `#:fec' to the end of the
|
||||
# dependency line.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
|
||||
tr '
|
||||
' ' ' >> $depfile
|
||||
echo >> $depfile
|
||||
|
||||
# The second pass generates a dummy entry for each header file.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||
>> $depfile
|
||||
else
|
||||
# The sourcefile does not contain any dependencies, so just
|
||||
# store a dummy comment line, to avoid errors with the Makefile
|
||||
# "include basename.Plo" scheme.
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
aix)
|
||||
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||
# in a .u file. In older versions, this file always lives in the
|
||||
# current directory. Also, the AIX compiler puts `$object:' at the
|
||||
# start of each line; $object doesn't have directory information.
|
||||
# Version 6 uses the directory in both cases.
|
||||
stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
|
||||
tmpdepfile="$stripped.u"
|
||||
if test "$libtool" = yes; then
|
||||
"$@" -Wc,-M
|
||||
else
|
||||
"$@" -M
|
||||
fi
|
||||
stat=$?
|
||||
|
||||
if test -f "$tmpdepfile"; then :
|
||||
else
|
||||
stripped=`echo "$stripped" | sed 's,^.*/,,'`
|
||||
tmpdepfile="$stripped.u"
|
||||
fi
|
||||
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
if test -f "$tmpdepfile"; then
|
||||
outname="$stripped.o"
|
||||
# Each line is of the form `foo.o: dependent.h'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
|
||||
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
# The sourcefile does not contain any dependencies, so just
|
||||
# store a dummy comment line, to avoid errors with the Makefile
|
||||
# "include basename.Plo" scheme.
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
icc)
|
||||
# Intel's C compiler understands `-MD -MF file'. However on
|
||||
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
|
||||
# ICC 7.0 will fill foo.d with something like
|
||||
# foo.o: sub/foo.c
|
||||
# foo.o: sub/foo.h
|
||||
# which is wrong. We want:
|
||||
# sub/foo.o: sub/foo.c
|
||||
# sub/foo.o: sub/foo.h
|
||||
# sub/foo.c:
|
||||
# sub/foo.h:
|
||||
# ICC 7.1 will output
|
||||
# foo.o: sub/foo.c sub/foo.h
|
||||
# and will wrap long lines using \ :
|
||||
# foo.o: sub/foo.c ... \
|
||||
# sub/foo.h ... \
|
||||
# ...
|
||||
|
||||
"$@" -MD -MF "$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each line is of the form `foo.o: dependent.h',
|
||||
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
|
||||
sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
tru64)
|
||||
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
|
||||
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||
# dependencies in `foo.d' instead, so we check for that too.
|
||||
# Subdirectories are respected.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
|
||||
if test "$libtool" = yes; then
|
||||
# Dependencies are output in .lo.d with libtool 1.4.
|
||||
# With libtool 1.5 they are output both in $dir.libs/$base.o.d
|
||||
# and in $dir.libs/$base.o.d and $dir$base.o.d. We process the
|
||||
# latter, because the former will be cleaned when $dir.libs is
|
||||
# erased.
|
||||
tmpdepfile1="$dir.libs/$base.lo.d"
|
||||
tmpdepfile2="$dir$base.o.d"
|
||||
tmpdepfile3="$dir.libs/$base.d"
|
||||
"$@" -Wc,-MD
|
||||
else
|
||||
tmpdepfile1="$dir$base.o.d"
|
||||
tmpdepfile2="$dir$base.d"
|
||||
tmpdepfile3="$dir$base.d"
|
||||
"$@" -MD
|
||||
fi
|
||||
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
if test -f "$tmpdepfile1"; then
|
||||
tmpdepfile="$tmpdepfile1"
|
||||
elif test -f "$tmpdepfile2"; then
|
||||
tmpdepfile="$tmpdepfile2"
|
||||
else
|
||||
tmpdepfile="$tmpdepfile3"
|
||||
fi
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||
# That's a tab and a space in the [].
|
||||
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
#nosideeffect)
|
||||
# This comment above is used by automake to tell side-effect
|
||||
# dependency tracking mechanisms from slower ones.
|
||||
|
||||
dashmstdout)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout, regardless of -o.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test $1 != '--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove `-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
test -z "$dashmflag" && dashmflag=-M
|
||||
# Require at least two characters before searching for `:'
|
||||
# in the target name. This is to cope with DOS-style filenames:
|
||||
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
|
||||
"$@" $dashmflag |
|
||||
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" | \
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
dashXmstdout)
|
||||
# This case only exists to satisfy depend.m4. It is never actually
|
||||
# run, as this mode is specially recognized in the preamble.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
makedepend)
|
||||
"$@" || exit $?
|
||||
# Remove any Libtool call
|
||||
if test "$libtool" = yes; then
|
||||
while test $1 != '--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
# X makedepend
|
||||
shift
|
||||
cleared=no
|
||||
for arg in "$@"; do
|
||||
case $cleared in
|
||||
no)
|
||||
set ""; shift
|
||||
cleared=yes ;;
|
||||
esac
|
||||
case "$arg" in
|
||||
-D*|-I*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
# Strip any option that makedepend may not understand. Remove
|
||||
# the object too, otherwise makedepend will parse it as a source file.
|
||||
-*|$object)
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
esac
|
||||
done
|
||||
obj_suffix="`echo $object | sed 's/^.*\././'`"
|
||||
touch "$tmpdepfile"
|
||||
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
sed '1,2d' "$tmpdepfile" | tr ' ' '
|
||||
' | \
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||
;;
|
||||
|
||||
cpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test $1 != '--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove `-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
"$@" -E |
|
||||
sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
|
||||
sed '$ s: \\$::' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
cat < "$tmpdepfile" >> "$depfile"
|
||||
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvisualcpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout, regardless of -o,
|
||||
# because we must use -o when running libtool.
|
||||
"$@" || exit $?
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case "$arg" in
|
||||
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||
set fnord "$@"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
"$@" -E |
|
||||
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
|
||||
echo " " >> "$depfile"
|
||||
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
none)
|
||||
exec "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown depmode $depmode" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
||||
@@ -1,770 +0,0 @@
|
||||
# Makefile.in generated by automake 1.9.4 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
|
||||
SOURCES = $(kernel_SOURCES)
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
top_builddir = ..
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
INSTALL = @INSTALL@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
EXTRA_PROGRAMS = kernel$(EXEEXT)
|
||||
@BUILD_EXAMPLE_KERNEL_TRUE@noinst_PROGRAMS = kernel$(EXEEXT)
|
||||
subdir = docs
|
||||
DIST_COMMON = $(grub_TEXINFOS) $(multiboot_TEXINFOS) \
|
||||
$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
|
||||
$(srcdir)/stamp-vti $(srcdir)/version.texi mdate-sh \
|
||||
texinfo.tex
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
PROGRAMS = $(noinst_PROGRAMS)
|
||||
am__kernel_SOURCES_DIST = boot.S kernel.c multiboot.h
|
||||
am__objects_1 = boot.$(OBJEXT) kernel-kernel.$(OBJEXT)
|
||||
@BUILD_EXAMPLE_KERNEL_TRUE@am_kernel_OBJECTS = $(am__objects_1)
|
||||
kernel_OBJECTS = $(am_kernel_OBJECTS)
|
||||
kernel_LDADD = $(LDADD)
|
||||
SCRIPTS = $(noinst_SCRIPTS)
|
||||
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
CCASCOMPILE = $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS)
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
SOURCES = $(kernel_SOURCES)
|
||||
DIST_SOURCES = $(am__kernel_SOURCES_DIST)
|
||||
INFO_DEPS = $(srcdir)/grub.info $(srcdir)/multiboot.info
|
||||
am__TEXINFO_TEX_DIR = $(srcdir)
|
||||
DVIS = grub.dvi multiboot.dvi
|
||||
PDFS = grub.pdf multiboot.pdf
|
||||
PSS = grub.ps multiboot.ps
|
||||
HTMLS = grub.html multiboot.html
|
||||
TEXINFOS = grub.texi multiboot.texi
|
||||
TEXI2DVI = texi2dvi
|
||||
TEXI2PDF = $(TEXI2DVI) --pdf --batch
|
||||
MAKEINFOHTML = $(MAKEINFO) --html
|
||||
AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
|
||||
DVIPS = dvips
|
||||
am__installdirs = "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)" \
|
||||
"$(DESTDIR)$(man8dir)"
|
||||
man1dir = $(mandir)/man1
|
||||
man8dir = $(mandir)/man8
|
||||
NROFF = nroff
|
||||
MANS = $(man_MANS)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMDEP_FALSE = @AMDEP_FALSE@
|
||||
AMDEP_TRUE = @AMDEP_TRUE@
|
||||
AMTAR = @AMTAR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
BUILD_EXAMPLE_KERNEL_FALSE = @BUILD_EXAMPLE_KERNEL_FALSE@
|
||||
BUILD_EXAMPLE_KERNEL_TRUE = @BUILD_EXAMPLE_KERNEL_TRUE@
|
||||
CC = @CC@
|
||||
CCAS = @CCAS@
|
||||
CCASFLAGS = @CCASFLAGS@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DISKLESS_SUPPORT_FALSE = @DISKLESS_SUPPORT_FALSE@
|
||||
DISKLESS_SUPPORT_TRUE = @DISKLESS_SUPPORT_TRUE@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FSYS_CFLAGS = @FSYS_CFLAGS@
|
||||
GRUB_CFLAGS = @GRUB_CFLAGS@
|
||||
GRUB_LIBS = @GRUB_LIBS@
|
||||
HERCULES_SUPPORT_FALSE = @HERCULES_SUPPORT_FALSE@
|
||||
HERCULES_SUPPORT_TRUE = @HERCULES_SUPPORT_TRUE@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAINT = @MAINT@
|
||||
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
|
||||
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
|
||||
NETBOOT_SUPPORT_FALSE = @NETBOOT_SUPPORT_FALSE@
|
||||
NETBOOT_SUPPORT_TRUE = @NETBOOT_SUPPORT_TRUE@
|
||||
NET_CFLAGS = @NET_CFLAGS@
|
||||
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||
OBJCOPY = @OBJCOPY@
|
||||
OBJEXT = @OBJEXT@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PERL = @PERL@
|
||||
RANLIB = @RANLIB@
|
||||
SERIAL_SPEED_SIMULATION_FALSE = @SERIAL_SPEED_SIMULATION_FALSE@
|
||||
SERIAL_SPEED_SIMULATION_TRUE = @SERIAL_SPEED_SIMULATION_TRUE@
|
||||
SERIAL_SUPPORT_FALSE = @SERIAL_SUPPORT_FALSE@
|
||||
SERIAL_SUPPORT_TRUE = @SERIAL_SUPPORT_TRUE@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STAGE1_CFLAGS = @STAGE1_CFLAGS@
|
||||
STAGE2_CFLAGS = @STAGE2_CFLAGS@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_OBJCOPY = @ac_ct_OBJCOPY@
|
||||
ac_ct_RANLIB = @ac_ct_RANLIB@
|
||||
ac_ct_STRIP = @ac_ct_STRIP@
|
||||
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
|
||||
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
datadir = @datadir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
info_TEXINFOS = grub.texi multiboot.texi
|
||||
grub_TEXINFOS = internals.texi fdl.texi
|
||||
EXAMPLES = boot.S kernel.c multiboot.h
|
||||
multiboot_TEXINFOS = boot.S.texi kernel.c.texi multiboot.h.texi
|
||||
man_MANS = grub.8 mbchk.1 grub-install.8 grub-md5-crypt.8 grub-terminfo.8
|
||||
HELP2MAN = help2man
|
||||
SRC2TEXI = src2texi
|
||||
noinst_SCRIPTS = $(HELP2MAN) $(SRC2TEXI)
|
||||
@BUILD_EXAMPLE_KERNEL_TRUE@kernel_SOURCES = $(EXAMPLES)
|
||||
@BUILD_EXAMPLE_KERNEL_TRUE@kernel_CFLAGS = -fno-builtin -nostdinc -O -g -Wall \
|
||||
@BUILD_EXAMPLE_KERNEL_TRUE@ -imacros $(top_builddir)/config.h
|
||||
|
||||
@BUILD_EXAMPLE_KERNEL_TRUE@kernel_LDFLAGS = -nostdlib -Wl,-N -Wl,-Ttext -Wl,100000
|
||||
EXTRA_DIST = menu.lst $(man_MANS) $(noinst_SCRIPTS) \
|
||||
$(EXAMPLES) $(multiboot_TEXINFOS)
|
||||
|
||||
CLEANFILES = $(noinst_PROGRAMS)
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .S .c .dvi .html .info .o .obj .pdf .ps .texi
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
|
||||
&& exit 0; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu docs/Makefile'; \
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu docs/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
clean-noinstPROGRAMS:
|
||||
-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
|
||||
kernel$(EXEEXT): $(kernel_OBJECTS) $(kernel_DEPENDENCIES)
|
||||
@rm -f kernel$(EXEEXT)
|
||||
$(LINK) $(kernel_LDFLAGS) $(kernel_OBJECTS) $(kernel_LDADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel-kernel.Po@am__quote@
|
||||
|
||||
.S.o:
|
||||
$(CCASCOMPILE) -c $<
|
||||
|
||||
.S.obj:
|
||||
$(CCASCOMPILE) -c `$(CYGPATH_W) '$<'`
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
|
||||
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
|
||||
|
||||
.c.obj:
|
||||
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
|
||||
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
|
||||
|
||||
kernel-kernel.o: kernel.c
|
||||
@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kernel_CFLAGS) $(CFLAGS) -MT kernel-kernel.o -MD -MP -MF "$(DEPDIR)/kernel-kernel.Tpo" -c -o kernel-kernel.o `test -f 'kernel.c' || echo '$(srcdir)/'`kernel.c; \
|
||||
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/kernel-kernel.Tpo" "$(DEPDIR)/kernel-kernel.Po"; else rm -f "$(DEPDIR)/kernel-kernel.Tpo"; exit 1; fi
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='kernel.c' object='kernel-kernel.o' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kernel_CFLAGS) $(CFLAGS) -c -o kernel-kernel.o `test -f 'kernel.c' || echo '$(srcdir)/'`kernel.c
|
||||
|
||||
kernel-kernel.obj: kernel.c
|
||||
@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kernel_CFLAGS) $(CFLAGS) -MT kernel-kernel.obj -MD -MP -MF "$(DEPDIR)/kernel-kernel.Tpo" -c -o kernel-kernel.obj `if test -f 'kernel.c'; then $(CYGPATH_W) 'kernel.c'; else $(CYGPATH_W) '$(srcdir)/kernel.c'; fi`; \
|
||||
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/kernel-kernel.Tpo" "$(DEPDIR)/kernel-kernel.Po"; else rm -f "$(DEPDIR)/kernel-kernel.Tpo"; exit 1; fi
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='kernel.c' object='kernel-kernel.obj' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kernel_CFLAGS) $(CFLAGS) -c -o kernel-kernel.obj `if test -f 'kernel.c'; then $(CYGPATH_W) 'kernel.c'; else $(CYGPATH_W) '$(srcdir)/kernel.c'; fi`
|
||||
|
||||
.texi.info:
|
||||
restore=: && backupdir="$(am__leading_dot)am$$$$" && \
|
||||
am__cwd=`pwd` && cd $(srcdir) && \
|
||||
rm -rf $$backupdir && mkdir $$backupdir && \
|
||||
for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \
|
||||
if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \
|
||||
done; \
|
||||
cd "$$am__cwd"; \
|
||||
if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
|
||||
-o $@ $<; \
|
||||
then \
|
||||
rc=0; \
|
||||
cd $(srcdir); \
|
||||
else \
|
||||
rc=$$?; \
|
||||
cd $(srcdir) && \
|
||||
$$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \
|
||||
fi; \
|
||||
rm -rf $$backupdir; exit $$rc
|
||||
|
||||
.texi.dvi:
|
||||
TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
|
||||
MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
|
||||
$(TEXI2DVI) $<
|
||||
|
||||
.texi.pdf:
|
||||
TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
|
||||
MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
|
||||
$(TEXI2PDF) $<
|
||||
|
||||
.texi.html:
|
||||
rm -rf $(@:.html=.htp)
|
||||
if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
|
||||
-o $(@:.html=.htp) $<; \
|
||||
then \
|
||||
rm -rf $@; \
|
||||
if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
|
||||
mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \
|
||||
else \
|
||||
if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
|
||||
rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \
|
||||
exit 1; \
|
||||
fi
|
||||
$(srcdir)/grub.info: grub.texi $(srcdir)/version.texi $(grub_TEXINFOS)
|
||||
grub.dvi: grub.texi $(srcdir)/version.texi $(grub_TEXINFOS)
|
||||
grub.pdf: grub.texi $(srcdir)/version.texi $(grub_TEXINFOS)
|
||||
grub.html: grub.texi $(srcdir)/version.texi $(grub_TEXINFOS)
|
||||
$(srcdir)/version.texi: @MAINTAINER_MODE_TRUE@ $(srcdir)/stamp-vti
|
||||
$(srcdir)/stamp-vti: grub.texi $(top_srcdir)/configure
|
||||
@(dir=.; test -f ./grub.texi || dir=$(srcdir); \
|
||||
set `$(SHELL) $(srcdir)/mdate-sh $$dir/grub.texi`; \
|
||||
echo "@set UPDATED $$1 $$2 $$3"; \
|
||||
echo "@set UPDATED-MONTH $$2 $$3"; \
|
||||
echo "@set EDITION $(VERSION)"; \
|
||||
echo "@set VERSION $(VERSION)") > vti.tmp
|
||||
@cmp -s vti.tmp $(srcdir)/version.texi \
|
||||
|| (echo "Updating $(srcdir)/version.texi"; \
|
||||
cp vti.tmp $(srcdir)/version.texi)
|
||||
-@rm -f vti.tmp
|
||||
@cp $(srcdir)/version.texi $@
|
||||
|
||||
mostlyclean-vti:
|
||||
-rm -f vti.tmp
|
||||
|
||||
maintainer-clean-vti:
|
||||
@MAINTAINER_MODE_TRUE@ -rm -f $(srcdir)/stamp-vti $(srcdir)/version.texi
|
||||
$(srcdir)/multiboot.info: multiboot.texi $(multiboot_TEXINFOS)
|
||||
multiboot.dvi: multiboot.texi $(multiboot_TEXINFOS)
|
||||
multiboot.pdf: multiboot.texi $(multiboot_TEXINFOS)
|
||||
multiboot.html: multiboot.texi $(multiboot_TEXINFOS)
|
||||
.dvi.ps:
|
||||
$(DVIPS) -o $@ $<
|
||||
|
||||
uninstall-info-am:
|
||||
$(PRE_UNINSTALL)
|
||||
@if (install-info --version && \
|
||||
install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
|
||||
list='$(INFO_DEPS)'; \
|
||||
for file in $$list; do \
|
||||
relfile=`echo "$$file" | sed 's|^.*/||'`; \
|
||||
echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \
|
||||
install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \
|
||||
done; \
|
||||
else :; fi
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(INFO_DEPS)'; \
|
||||
for file in $$list; do \
|
||||
relfile=`echo "$$file" | sed 's|^.*/||'`; \
|
||||
relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \
|
||||
(if cd "$(DESTDIR)$(infodir)"; then \
|
||||
echo " rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9])"; \
|
||||
rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \
|
||||
else :; fi); \
|
||||
done
|
||||
|
||||
dist-info: $(INFO_DEPS)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
|
||||
list='$(INFO_DEPS)'; \
|
||||
for base in $$list; do \
|
||||
case $$base in \
|
||||
$(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
esac; \
|
||||
if test -f $$base; then d=.; else d=$(srcdir); fi; \
|
||||
for file in $$d/$$base*; do \
|
||||
relfile=`expr "$$file" : "$$d/\(.*\)"`; \
|
||||
test -f $(distdir)/$$relfile || \
|
||||
cp -p $$file $(distdir)/$$relfile; \
|
||||
done; \
|
||||
done
|
||||
|
||||
mostlyclean-aminfo:
|
||||
-rm -rf grub.aux grub.cp grub.cps grub.fn grub.ky grub.log grub.pg grub.tmp \
|
||||
grub.toc grub.tp grub.vr grub.dvi grub.pdf grub.ps grub.html \
|
||||
multiboot.aux multiboot.cp multiboot.cps multiboot.fn \
|
||||
multiboot.ky multiboot.log multiboot.pg multiboot.tmp \
|
||||
multiboot.toc multiboot.tp multiboot.vr multiboot.dvi \
|
||||
multiboot.pdf multiboot.ps multiboot.html
|
||||
|
||||
maintainer-clean-aminfo:
|
||||
@list='$(INFO_DEPS)'; for i in $$list; do \
|
||||
i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \
|
||||
echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \
|
||||
rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \
|
||||
done
|
||||
install-man1: $(man1_MANS) $(man_MANS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(man1dir)" || $(mkdir_p) "$(DESTDIR)$(man1dir)"
|
||||
@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
|
||||
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
|
||||
for i in $$l2; do \
|
||||
case "$$i" in \
|
||||
*.1*) list="$$list $$i" ;; \
|
||||
esac; \
|
||||
done; \
|
||||
for i in $$list; do \
|
||||
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
|
||||
else file=$$i; fi; \
|
||||
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
|
||||
case "$$ext" in \
|
||||
1*) ;; \
|
||||
*) ext='1' ;; \
|
||||
esac; \
|
||||
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
|
||||
inst=`echo $$inst | sed -e 's/^.*\///'`; \
|
||||
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
|
||||
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
|
||||
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst"; \
|
||||
done
|
||||
uninstall-man1:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
|
||||
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
|
||||
for i in $$l2; do \
|
||||
case "$$i" in \
|
||||
*.1*) list="$$list $$i" ;; \
|
||||
esac; \
|
||||
done; \
|
||||
for i in $$list; do \
|
||||
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
|
||||
case "$$ext" in \
|
||||
1*) ;; \
|
||||
*) ext='1' ;; \
|
||||
esac; \
|
||||
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
|
||||
inst=`echo $$inst | sed -e 's/^.*\///'`; \
|
||||
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
|
||||
echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \
|
||||
rm -f "$(DESTDIR)$(man1dir)/$$inst"; \
|
||||
done
|
||||
install-man8: $(man8_MANS) $(man_MANS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(man8dir)" || $(mkdir_p) "$(DESTDIR)$(man8dir)"
|
||||
@list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
|
||||
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
|
||||
for i in $$l2; do \
|
||||
case "$$i" in \
|
||||
*.8*) list="$$list $$i" ;; \
|
||||
esac; \
|
||||
done; \
|
||||
for i in $$list; do \
|
||||
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
|
||||
else file=$$i; fi; \
|
||||
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
|
||||
case "$$ext" in \
|
||||
8*) ;; \
|
||||
*) ext='8' ;; \
|
||||
esac; \
|
||||
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
|
||||
inst=`echo $$inst | sed -e 's/^.*\///'`; \
|
||||
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
|
||||
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
|
||||
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst"; \
|
||||
done
|
||||
uninstall-man8:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
|
||||
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
|
||||
for i in $$l2; do \
|
||||
case "$$i" in \
|
||||
*.8*) list="$$list $$i" ;; \
|
||||
esac; \
|
||||
done; \
|
||||
for i in $$list; do \
|
||||
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
|
||||
case "$$ext" in \
|
||||
8*) ;; \
|
||||
*) ext='8' ;; \
|
||||
esac; \
|
||||
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
|
||||
inst=`echo $$inst | sed -e 's/^.*\///'`; \
|
||||
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
|
||||
echo " rm -f '$(DESTDIR)$(man8dir)/$$inst'"; \
|
||||
rm -f "$(DESTDIR)$(man8dir)/$$inst"; \
|
||||
done
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$tags $$unique; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$tags $$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& cd $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) $$here
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
|
||||
list='$(DISTFILES)'; for file in $$list; do \
|
||||
case $$file in \
|
||||
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
|
||||
esac; \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
dir="/$$dir"; \
|
||||
$(mkdir_p) "$(distdir)$$dir"; \
|
||||
else \
|
||||
dir=''; \
|
||||
fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||
fi; \
|
||||
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
$(MAKE) $(AM_MAKEFLAGS) \
|
||||
top_distdir="$(top_distdir)" distdir="$(distdir)" \
|
||||
dist-info
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(INFO_DEPS) $(PROGRAMS) $(SCRIPTS) $(MANS)
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man8dir)"; do \
|
||||
test -z "$$dir" || $(mkdir_p) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-noinstPROGRAMS mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am: $(DVIS)
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am: $(HTMLS)
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am: $(INFO_DEPS)
|
||||
|
||||
install-data-am: install-info-am install-man
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am: $(INFO_DEPS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(infodir)" || $(mkdir_p) "$(DESTDIR)$(infodir)"
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
|
||||
list='$(INFO_DEPS)'; \
|
||||
for file in $$list; do \
|
||||
case $$file in \
|
||||
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
esac; \
|
||||
if test -f $$file; then d=.; else d=$(srcdir); fi; \
|
||||
file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \
|
||||
for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \
|
||||
$$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \
|
||||
if test -f $$ifile; then \
|
||||
relfile=`echo "$$ifile" | sed 's|^.*/||'`; \
|
||||
echo " $(INSTALL_DATA) '$$ifile' '$(DESTDIR)$(infodir)/$$relfile'"; \
|
||||
$(INSTALL_DATA) "$$ifile" "$(DESTDIR)$(infodir)/$$relfile"; \
|
||||
else : ; fi; \
|
||||
done; \
|
||||
done
|
||||
@$(POST_INSTALL)
|
||||
@if (install-info --version && \
|
||||
install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
|
||||
list='$(INFO_DEPS)'; \
|
||||
for file in $$list; do \
|
||||
relfile=`echo "$$file" | sed 's|^.*/||'`; \
|
||||
echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\
|
||||
install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\
|
||||
done; \
|
||||
else : ; fi
|
||||
install-man: install-man1 install-man8
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-aminfo \
|
||||
maintainer-clean-generic maintainer-clean-vti
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-aminfo mostlyclean-compile \
|
||||
mostlyclean-generic mostlyclean-vti
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am: $(PDFS)
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am: $(PSS)
|
||||
|
||||
uninstall-am: uninstall-info-am uninstall-man
|
||||
|
||||
uninstall-man: uninstall-man1 uninstall-man8
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
|
||||
clean-noinstPROGRAMS ctags dist-info distclean \
|
||||
distclean-compile distclean-generic distclean-tags distdir dvi \
|
||||
dvi-am html html-am info info-am install install-am \
|
||||
install-data install-data-am install-exec install-exec-am \
|
||||
install-info install-info-am install-man install-man1 \
|
||||
install-man8 install-strip installcheck installcheck-am \
|
||||
installdirs maintainer-clean maintainer-clean-aminfo \
|
||||
maintainer-clean-generic maintainer-clean-vti mostlyclean \
|
||||
mostlyclean-aminfo mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-vti pdf pdf-am ps ps-am tags uninstall \
|
||||
uninstall-am uninstall-info-am uninstall-man uninstall-man1 \
|
||||
uninstall-man8
|
||||
|
||||
|
||||
@BUILD_EXAMPLE_KERNEL_TRUE@boot.o: multiboot.h
|
||||
|
||||
# Cancel the rule %.texi -> %. This rule may confuse make to determine
|
||||
# the dependecies.
|
||||
.texi:
|
||||
|
||||
%.c.texi: %.c $(srcdir)/$(SRC2TEXI)
|
||||
$(SHELL) $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
|
||||
|
||||
%.h.texi: %.h $(srcdir)/$(SRC2TEXI)
|
||||
$(SHELL) $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
|
||||
|
||||
%.S.texi: %.S $(srcdir)/$(SRC2TEXI)
|
||||
$(SHELL) $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
|
||||
|
||||
@MAINTAINER_MODE_TRUE@$(srcdir)/grub.8: ../grub/grub $(srcdir)/$(HELP2MAN)
|
||||
@MAINTAINER_MODE_TRUE@ $(PERL) $(srcdir)/$(HELP2MAN) --name="the grub shell" \
|
||||
@MAINTAINER_MODE_TRUE@ --section=8 --output=$@ $<
|
||||
|
||||
@MAINTAINER_MODE_TRUE@$(srcdir)/grub-install.8: ../util/grub-install $(srcdir)/$(HELP2MAN)
|
||||
@MAINTAINER_MODE_TRUE@ chmod 755 $<
|
||||
@MAINTAINER_MODE_TRUE@ $(PERL) $(srcdir)/$(HELP2MAN) --name="install GRUB on your drive" \
|
||||
@MAINTAINER_MODE_TRUE@ --section=8 --output=$@ $<
|
||||
|
||||
@MAINTAINER_MODE_TRUE@$(srcdir)/mbchk.1: ../util/mbchk $(srcdir)/$(HELP2MAN)
|
||||
@MAINTAINER_MODE_TRUE@ $(PERL) $(srcdir)/$(HELP2MAN) \
|
||||
@MAINTAINER_MODE_TRUE@ --name="check the format of a Multiboot kernel" \
|
||||
@MAINTAINER_MODE_TRUE@ --section=1 --output=$@ $<
|
||||
|
||||
@MAINTAINER_MODE_TRUE@$(srcdir)/grub-md5-crypt.8: ../util/grub-md5-crypt $(srcdir)/$(HELP2MAN)
|
||||
@MAINTAINER_MODE_TRUE@ chmod 755 $<
|
||||
@MAINTAINER_MODE_TRUE@ $(PERL) $(srcdir)/$(HELP2MAN) \
|
||||
@MAINTAINER_MODE_TRUE@ --name="Encrypt a password in MD5 format" \
|
||||
@MAINTAINER_MODE_TRUE@ --section=8 --output=$@ $<
|
||||
|
||||
@MAINTAINER_MODE_TRUE@$(srcdir)/grub-terminfo.8: ../util/grub-terminfo $(srcdir)/$(HELP2MAN)
|
||||
@MAINTAINER_MODE_TRUE@ chmod 755 $<
|
||||
@MAINTAINER_MODE_TRUE@ $(PERL) $(srcdir)/$(HELP2MAN) \
|
||||
@MAINTAINER_MODE_TRUE@ --name="Generate a terminfo command from a terminfo name" \
|
||||
@MAINTAINER_MODE_TRUE@ --section=8 --output=$@ $<
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
@@ -1,79 +0,0 @@
|
||||
/* @r{boot.S - bootstrap the kernel} */
|
||||
/* @r{Copyright (C) 1999, 2001 Free Software Foundation, Inc.
|
||||
|
||||
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
|
||||
(at your option) 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.} */
|
||||
|
||||
#define ASM 1
|
||||
#include <multiboot.h>
|
||||
|
||||
.text
|
||||
|
||||
.globl start, _start
|
||||
start:
|
||||
_start:
|
||||
jmp multiboot_entry
|
||||
|
||||
/* @r{Align 32 bits boundary.} */
|
||||
.align 4
|
||||
|
||||
/* @r{Multiboot header.} */
|
||||
multiboot_header:
|
||||
/* @r{magic} */
|
||||
.long MULTIBOOT_HEADER_MAGIC
|
||||
/* @r{flags} */
|
||||
.long MULTIBOOT_HEADER_FLAGS
|
||||
/* @r{checksum} */
|
||||
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
|
||||
#ifndef __ELF__
|
||||
/* @r{header_addr} */
|
||||
.long multiboot_header
|
||||
/* @r{load_addr} */
|
||||
.long _start
|
||||
/* @r{load_end_addr} */
|
||||
.long _edata
|
||||
/* @r{bss_end_addr} */
|
||||
.long _end
|
||||
/* @r{entry_addr} */
|
||||
.long multiboot_entry
|
||||
#endif /* @r{! __ELF__} */
|
||||
|
||||
multiboot_entry:
|
||||
/* @r{Initialize the stack pointer.} */
|
||||
movl $(stack + STACK_SIZE), %esp
|
||||
|
||||
/* @r{Reset EFLAGS.} */
|
||||
pushl $0
|
||||
popf
|
||||
|
||||
/* @r{Push the pointer to the Multiboot information structure.} */
|
||||
pushl %ebx
|
||||
/* @r{Push the magic value.} */
|
||||
pushl %eax
|
||||
|
||||
/* @r{Now enter the C main function...} */
|
||||
call EXT_C(cmain)
|
||||
|
||||
/* @r{Halt.} */
|
||||
pushl $halt_message
|
||||
call EXT_C(printf)
|
||||
|
||||
loop: hlt
|
||||
jmp loop
|
||||
|
||||
halt_message:
|
||||
.asciz "Halted."
|
||||
|
||||
/* @r{Our stack area.} */
|
||||
.comm stack, STACK_SIZE
|
||||
@@ -1,52 +0,0 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.23.
|
||||
.TH GRUB-INSTALL "8" "June 2006" "grub-install (GNU GRUB 0.97)" FSF
|
||||
.SH NAME
|
||||
grub-install \- install GRUB on your drive
|
||||
.SH SYNOPSIS
|
||||
.B grub-install
|
||||
[\fIOPTION\fR] \fIinstall_device\fR
|
||||
.SH DESCRIPTION
|
||||
Install GRUB on your drive.
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
print this message and exit
|
||||
.TP
|
||||
\fB\-v\fR, \fB\-\-version\fR
|
||||
print the version information and exit
|
||||
.TP
|
||||
\fB\-\-root\-directory\fR=\fIDIR\fR
|
||||
install GRUB images under the directory DIR
|
||||
instead of the root directory
|
||||
.TP
|
||||
\fB\-\-grub\-shell\fR=\fIFILE\fR
|
||||
use FILE as the grub shell
|
||||
.TP
|
||||
\fB\-\-no\-floppy\fR
|
||||
do not probe any floppy drive
|
||||
.TP
|
||||
\fB\-\-force\-lba\fR
|
||||
force GRUB to use LBA mode even for a buggy
|
||||
BIOS
|
||||
.TP
|
||||
\fB\-\-recheck\fR
|
||||
probe a device map even if it already exists
|
||||
.PP
|
||||
INSTALL_DEVICE can be a GRUB device name or a system device filename.
|
||||
.PP
|
||||
grub-install copies GRUB images into the DIR/boot directory specfied by
|
||||
\fB\-\-root\-directory\fR, and uses the grub shell to install grub into the boot
|
||||
sector.
|
||||
.SH "REPORTING BUGS"
|
||||
Report bugs to <bug-grub@gnu.org>.
|
||||
.SH "SEE ALSO"
|
||||
The full documentation for
|
||||
.B grub-install
|
||||
is maintained as a Texinfo manual. If the
|
||||
.B info
|
||||
and
|
||||
.B grub-install
|
||||
programs are properly installed at your site, the command
|
||||
.IP
|
||||
.B info grub-install
|
||||
.PP
|
||||
should give you access to the complete manual.
|
||||
@@ -1,32 +0,0 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.23.
|
||||
.TH GRUB-MD5-CRYPT "8" "June 2006" "grub-md5-crypt (GNU GRUB )" FSF
|
||||
.SH NAME
|
||||
grub-md5-crypt \- Encrypt a password in MD5 format
|
||||
.SH SYNOPSIS
|
||||
.B grub-md5-crypt
|
||||
[\fIOPTION\fR]
|
||||
.SH DESCRIPTION
|
||||
Encrypt a password in MD5 format.
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
print this message and exit
|
||||
.TP
|
||||
\fB\-v\fR, \fB\-\-version\fR
|
||||
print the version information and exit
|
||||
.TP
|
||||
\fB\-\-grub\-shell\fR=\fIFILE\fR
|
||||
use FILE as the grub shell
|
||||
.SH "REPORTING BUGS"
|
||||
Report bugs to <bug-grub@gnu.org>.
|
||||
.SH "SEE ALSO"
|
||||
The full documentation for
|
||||
.B grub-md5-crypt
|
||||
is maintained as a Texinfo manual. If the
|
||||
.B info
|
||||
and
|
||||
.B grub-md5-crypt
|
||||
programs are properly installed at your site, the command
|
||||
.IP
|
||||
.B info grub-md5-crypt
|
||||
.PP
|
||||
should give you access to the complete manual.
|
||||
@@ -1,29 +0,0 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.23.
|
||||
.TH GRUB-TERMINFO "8" "June 2006" "grub-terminfo (GNU GRUB 0.97)" FSF
|
||||
.SH NAME
|
||||
grub-terminfo \- Generate a terminfo command from a terminfo name
|
||||
.SH SYNOPSIS
|
||||
.B grub-terminfo
|
||||
\fITERMNAME\fR
|
||||
.SH DESCRIPTION
|
||||
Generate a terminfo command from a terminfo name.
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
print this message and exit
|
||||
.TP
|
||||
\fB\-v\fR, \fB\-\-version\fR
|
||||
print the version information and exit
|
||||
.SH "REPORTING BUGS"
|
||||
Report bugs to <bug-grub@gnu.org>.
|
||||
.SH "SEE ALSO"
|
||||
The full documentation for
|
||||
.B grub-terminfo
|
||||
is maintained as a Texinfo manual. If the
|
||||
.B info
|
||||
and
|
||||
.B grub-terminfo
|
||||
programs are properly installed at your site, the command
|
||||
.IP
|
||||
.B info grub-terminfo
|
||||
.PP
|
||||
should give you access to the complete manual.
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.23.
|
||||
.TH GRUB "8" "June 2006" "grub (GNU GRUB 0.97)" FSF
|
||||
.SH NAME
|
||||
grub \- the grub shell
|
||||
.SH SYNOPSIS
|
||||
.B grub
|
||||
[\fIOPTION\fR]...
|
||||
.SH DESCRIPTION
|
||||
Enter the GRand Unified Bootloader command shell.
|
||||
.TP
|
||||
\fB\-\-batch\fR
|
||||
turn on batch mode for non-interactive use
|
||||
.TP
|
||||
\fB\-\-boot\-drive\fR=\fIDRIVE\fR
|
||||
specify stage2 boot_drive [default=0x0]
|
||||
.TP
|
||||
\fB\-\-config\-file\fR=\fIFILE\fR
|
||||
specify stage2 config_file [default=/boot/grub/menu.lst]
|
||||
.TP
|
||||
\fB\-\-device\-map\fR=\fIFILE\fR
|
||||
use the device map file FILE
|
||||
.TP
|
||||
\fB\-\-help\fR
|
||||
display this message and exit
|
||||
.TP
|
||||
\fB\-\-hold\fR
|
||||
wait until a debugger will attach
|
||||
.TP
|
||||
\fB\-\-install\-partition\fR=\fIPAR\fR
|
||||
specify stage2 install_partition [default=0x20000]
|
||||
.TP
|
||||
\fB\-\-no\-config\-file\fR
|
||||
do not use the config file
|
||||
.TP
|
||||
\fB\-\-no\-curses\fR
|
||||
do not use curses
|
||||
.TP
|
||||
\fB\-\-no\-floppy\fR
|
||||
do not probe any floppy drive
|
||||
.TP
|
||||
\fB\-\-no\-pager\fR
|
||||
do not use internal pager
|
||||
.TP
|
||||
\fB\-\-preset\-menu\fR
|
||||
use the preset menu
|
||||
.TP
|
||||
\fB\-\-probe\-second\-floppy\fR
|
||||
probe the second floppy drive
|
||||
.TP
|
||||
\fB\-\-read\-only\fR
|
||||
do not write anything to devices
|
||||
.TP
|
||||
\fB\-\-verbose\fR
|
||||
print verbose messages
|
||||
.TP
|
||||
\fB\-\-version\fR
|
||||
print version information and exit
|
||||
.SH "REPORTING BUGS"
|
||||
Report bugs to <bug-grub@gnu.org>.
|
||||
.SH "SEE ALSO"
|
||||
The full documentation for
|
||||
.B grub
|
||||
is maintained as a Texinfo manual. If the
|
||||
.B info
|
||||
and
|
||||
.B grub
|
||||
programs are properly installed at your site, the command
|
||||
.IP
|
||||
.B info grub
|
||||
.PP
|
||||
should give you access to the complete manual.
|
||||
-3979
File diff suppressed because it is too large.
Load diff
@@ -1,427 +0,0 @@
|
||||
@node Internals
|
||||
@appendix Hacking GRUB
|
||||
|
||||
This chapter documents the user-invisible aspect of GRUB.
|
||||
|
||||
As a general rule of software development, it is impossible to keep the
|
||||
descriptions of the internals up-to-date, and it is quite hard to
|
||||
document everything. So refer to the source code, whenever you are not
|
||||
satisfied with this documentation. Please assume that this gives just
|
||||
hints to you.
|
||||
|
||||
@menu
|
||||
* Memory map:: The memory map of various components
|
||||
* Embedded data:: Embedded variables in GRUB
|
||||
* Filesystem interface:: The generic interface for filesystems
|
||||
* Command interface:: The generic interface for built-ins
|
||||
* Bootstrap tricks:: The bootstrap mechanism used in GRUB
|
||||
* I/O ports detection:: How to probe I/O ports used by INT 13H
|
||||
* Memory detection:: How to detect all installed RAM
|
||||
* Low-level disk I/O:: INT 13H disk I/O interrupts
|
||||
* MBR:: The structure of Master Boot Record
|
||||
* Partition table:: The format of partition tables
|
||||
* Submitting patches:: Where and how you should send patches
|
||||
@end menu
|
||||
|
||||
|
||||
@node Memory map
|
||||
@section The memory map of various components
|
||||
|
||||
GRUB consists of two distinct components, called @dfn{stages}, which are
|
||||
loaded at different times in the boot process. Because they run
|
||||
mutual-exclusively, sometimes a memory area overlaps with another
|
||||
memory area. And, even in one stage, a single memory area can be used
|
||||
for various purposes, because their usages are mutually exclusive.
|
||||
|
||||
Here is the memory map of the various components:
|
||||
|
||||
@table @asis
|
||||
@item 0 to 4K-1
|
||||
BIOS and real mode interrupts
|
||||
|
||||
@item 0x07BE to 0x07FF
|
||||
Partition table passed to another boot loader
|
||||
|
||||
@item down from 8K-1
|
||||
Real mode stack
|
||||
|
||||
@item 0x2000 to ?
|
||||
The optional Stage 1.5 is loaded here
|
||||
|
||||
@item 0x2000 to 0x7FFF
|
||||
Command-line buffer for Multiboot kernels and modules
|
||||
|
||||
@item 0x7C00 to 0x7DFF
|
||||
Stage 1 is loaded here by BIOS or another boot loader
|
||||
|
||||
@item 0x7F00 to 0x7F42
|
||||
LBA drive parameters
|
||||
|
||||
@item 0x8000 to ?
|
||||
Stage2 is loaded here
|
||||
|
||||
@item The end of Stage 2 to 416K-1
|
||||
Heap, in particular used for the menu
|
||||
|
||||
@item down from 416K-1
|
||||
Protected mode stack
|
||||
|
||||
@item 416K to 448K-1
|
||||
Filesystem buffer
|
||||
|
||||
@item 448K to 479.5K-1
|
||||
Raw device buffer
|
||||
|
||||
@item 479.5K to 480K-1
|
||||
512-byte scratch area
|
||||
|
||||
@item 480K to 512K-1
|
||||
Buffers for various functions, such as password, command-line, cut and
|
||||
paste, and completion.
|
||||
|
||||
@item The last 1K of lower memory
|
||||
Disk swapping code and data
|
||||
@end table
|
||||
|
||||
See the file @file{stage2/shared.h}, for more information.
|
||||
|
||||
|
||||
@node Embedded data
|
||||
@section Embedded variables in GRUB
|
||||
|
||||
Stage 1 and Stage 2 have embedded variables whose locations are
|
||||
well-defined, so that the installation can patch the binary file
|
||||
directly without recompilation of the stages.
|
||||
|
||||
In Stage 1, these are defined:
|
||||
|
||||
@table @code
|
||||
@item 0x3E
|
||||
The version number (not GRUB's, but the installation mechanism's).
|
||||
|
||||
@item 0x40
|
||||
The boot drive. If it is 0xFF, use a drive passed by BIOS.
|
||||
|
||||
@item 0x41
|
||||
The flag for if forcing LBA.
|
||||
|
||||
@item 0x42
|
||||
The starting address of Stage 2.
|
||||
|
||||
@item 0x44
|
||||
The first sector of Stage 2.
|
||||
|
||||
@item 0x48
|
||||
The starting segment of Stage 2.
|
||||
|
||||
@item 0x1FE
|
||||
The signature (@code{0xAA55}).
|
||||
@end table
|
||||
|
||||
See the file @file{stage1/stage1.S}, for more information.
|
||||
|
||||
In the first sector of Stage 1.5 and Stage 2, the blocklists are
|
||||
recorded between @code{firstlist} and @code{lastlist}. The address of
|
||||
@code{lastlist} is determined when assembling the file
|
||||
@file{stage2/start.S}.
|
||||
|
||||
The trick here is that it is actually read backward, and the first
|
||||
8-byte blocklist is not read here, but after the pointer is decremented
|
||||
8 bytes, then after reading it, it decrements again, reads, and so on,
|
||||
until it is finished. The terminating condition is when the number of
|
||||
sectors to be read in the next blocklist is zero.
|
||||
|
||||
The format of a blocklist can be seen from the example in the code just
|
||||
before the @code{firstlist} label. Note that it is always from the
|
||||
beginning of the disk, but @emph{not} relative to the partition
|
||||
boundaries.
|
||||
|
||||
In the second sector of Stage 1.5 and Stage 2, these are defined:
|
||||
|
||||
@table @asis
|
||||
@item @code{0x6}
|
||||
The version number (likewise, the installation mechanism's).
|
||||
|
||||
@item @code{0x8}
|
||||
The installed partition.
|
||||
|
||||
@item @code{0xC}
|
||||
The saved entry number.
|
||||
|
||||
@item @code{0x10}
|
||||
The identifier.
|
||||
|
||||
@item @code{0x11}
|
||||
The flag for if forcing LBA.
|
||||
|
||||
@item @code{0x12}
|
||||
The version string (GRUB's).
|
||||
|
||||
@item @code{0x12} + @dfn{the length of the version string}
|
||||
The name of a configuration file.
|
||||
@end table
|
||||
|
||||
See the file @file{stage2/asm.S}, for more information.
|
||||
|
||||
|
||||
@node Filesystem interface
|
||||
@section The generic interface for filesystems
|
||||
|
||||
For any particular partition, it is presumed that only one of the
|
||||
@dfn{normal} filesystems such as FAT, FFS, or ext2fs can be used, so
|
||||
there is a switch table managed by the functions in
|
||||
@file{disk_io.c}. The notation is that you can only @dfn{mount} one at a
|
||||
time.
|
||||
|
||||
The blocklist filesystem has a special place in the system. In addition
|
||||
to the @dfn{normal} filesystem (or even without one mounted), you can
|
||||
access disk blocks directly (in the indicated partition) via the block
|
||||
list notation. Using the blocklist filesystem doesn't effect any other
|
||||
filesystem mounts.
|
||||
|
||||
The variables which can be read by the filesystem backend are:
|
||||
|
||||
@vtable @code
|
||||
@item current_drive
|
||||
The current BIOS drive number (numbered from 0, if a floppy, and
|
||||
numbered from 0x80, if a hard disk).
|
||||
|
||||
@item current_partition
|
||||
The current partition number.
|
||||
|
||||
@item current_slice
|
||||
The current partition type.
|
||||
|
||||
@item saved_drive
|
||||
The @dfn{drive} part of the root device.
|
||||
|
||||
@item saved_partition
|
||||
The @dfn{partition} part of the root device.
|
||||
|
||||
@item part_start
|
||||
The current partition starting address, in sectors.
|
||||
|
||||
@item part_length
|
||||
The current partition length, in sectors.
|
||||
|
||||
@item print_possibilities
|
||||
True when the @code{dir} function should print the possible completions
|
||||
of a file, and false when it should try to actually open a file of that
|
||||
name.
|
||||
|
||||
@item FSYS_BUF
|
||||
Filesystem buffer which is 32K in size, to use in any way which the
|
||||
filesystem backend desires.
|
||||
@end vtable
|
||||
|
||||
The variables which need to be written by a filesystem backend are:
|
||||
|
||||
@vtable @code
|
||||
@item filepos
|
||||
The current position in the file, in sectors.
|
||||
|
||||
@strong{Caution:} the value of @var{filepos} can be changed out from
|
||||
under the filesystem code in the current implementation. Don't depend on
|
||||
it being the same for later calls into the backend code!
|
||||
|
||||
@item filemax
|
||||
The length of the file.
|
||||
|
||||
@item disk_read_func
|
||||
The value of @var{disk_read_hook} @emph{only} during reading of data
|
||||
for the file, not any other fs data, inodes, FAT tables, whatever, then
|
||||
set to @code{NULL} at all other times (it will be @code{NULL} by
|
||||
default). If this isn't done correctly, then the @command{testload} and
|
||||
@command{install} commands won't work correctly.
|
||||
@end vtable
|
||||
|
||||
The functions expected to be used by the filesystem backend are:
|
||||
|
||||
@ftable @code
|
||||
@item devread
|
||||
Only read sectors from within a partition. Sector 0 is the first sector
|
||||
in the partition.
|
||||
|
||||
@item grub_read
|
||||
If the backend uses the blocklist code, then @code{grub_read} can be
|
||||
used, after setting @var{block_file} to 1.
|
||||
|
||||
@item print_a_completion
|
||||
If @var{print_possibilities} is true, call @code{print_a_completion} for
|
||||
each possible file name. Otherwise, the file name completion won't work.
|
||||
@end ftable
|
||||
|
||||
The functions expected to be defined by the filesystem backend are
|
||||
described at least moderately in the file @file{filesys.h}. Their usage
|
||||
is fairly evident from their use in the functions in @file{disk_io.c},
|
||||
look for the use of the @var{fsys_table} array.
|
||||
|
||||
@strong{Caution:} The semantics are such that then @samp{mount}ing the
|
||||
filesystem, presume the filesystem buffer @code{FSYS_BUF} is corrupted,
|
||||
and (re-)load all important contents. When opening and reading a file,
|
||||
presume that the data from the @samp{mount} is available, and doesn't
|
||||
get corrupted by the open/read (i.e. multiple opens and/or reads will be
|
||||
done with only one mount if in the same filesystem).
|
||||
|
||||
|
||||
@node Command interface
|
||||
@section The generic interface for built-ins
|
||||
|
||||
GRUB built-in commands are defined in a uniform interface, whether
|
||||
they are menu-specific or can be used anywhere. The definition of a
|
||||
built-in command consists of two parts: the code itself and the table of
|
||||
the information.
|
||||
|
||||
The code must be a function which takes two arguments, a command-line
|
||||
string and flags, and returns an @samp{int} value. The @dfn{flags}
|
||||
argument specifies how the function is called, using a bit mask. The
|
||||
return value must be zero if successful, otherwise non-zero. So it is
|
||||
normally enough to return @var{errnum}.
|
||||
|
||||
The table of the information is represented by the structure
|
||||
@code{struct builtin}, which contains the name of the command, a pointer
|
||||
to the function, flags, a short description of the command and a long
|
||||
description of the command. Since the descriptions are used only for
|
||||
help messages interactively, you don't have to define them, if the
|
||||
command may not be called interactively (such as @command{title}).
|
||||
|
||||
The table is finally registered in the table @var{builtin_table}, so
|
||||
that @code{run_script} and @code{enter_cmdline} can find the
|
||||
command. See the files @file{cmdline.c} and @file{builtins.c}, for more
|
||||
details.
|
||||
|
||||
|
||||
@node Bootstrap tricks
|
||||
@section The bootstrap mechanism used in GRUB
|
||||
|
||||
The disk space can be used in a boot loader is very restricted because
|
||||
a MBR (@pxref{MBR}) is only 512 bytes but it also contains a partition
|
||||
table (@pxref{Partition table}) and a BPB. So the question is how to
|
||||
make a boot loader code enough small to be fit in a MBR.
|
||||
|
||||
However, GRUB is a very large program, so we break GRUB into 2 (or 3)
|
||||
distinct components, @dfn{Stage 1} and @dfn{Stage 2} (and optionally
|
||||
@dfn{Stage 1.5}). @xref{Memory map}, for more information.
|
||||
|
||||
We embed Stage 1 in a MBR or in the boot sector of a partition, and
|
||||
place Stage 2 in a filesystem. The optional Stage 1.5 can be installed
|
||||
in a filesystem, in the @dfn{boot loader} area in a FFS or a ReiserFS,
|
||||
and in the sectors right after a MBR, because Stage 1.5 is enough small
|
||||
and the sectors right after a MBR is normally an unused region. The size
|
||||
of this region is the number of sectors per head minus 1.
|
||||
|
||||
Thus, all Stage1 must do is just load Stage2 or Stage1.5. But even if
|
||||
Stage 1 needs not to support the user interface or the filesystem
|
||||
interface, it is impossible to make Stage 1 less than 400 bytes, because
|
||||
GRUB should support both the CHS mode and the LBA mode (@pxref{Low-level
|
||||
disk I/O}).
|
||||
|
||||
The solution used by GRUB is that Stage 1 loads only the first sector of
|
||||
Stage 2 (or Stage 1.5) and Stage 2 itself loads the rest. The flow of
|
||||
Stage 1 is:
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
Initialize the system briefly.
|
||||
|
||||
@item
|
||||
Detect the geometry and the accessing mode of the @dfn{loading drive}.
|
||||
|
||||
@item
|
||||
Load the first sector of Stage 2.
|
||||
|
||||
@item
|
||||
Jump to the starting address of the Stage 2.
|
||||
@end enumerate
|
||||
|
||||
The flow of Stage 2 (and Stage 1.5) is:
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
Load the rest of itself to the real starting address, that is, the
|
||||
starting address plus 512 bytes. The blocklists are stored in the last
|
||||
part of the first sector.
|
||||
|
||||
@item
|
||||
Long jump to the real starting address.
|
||||
@end enumerate
|
||||
|
||||
Note that Stage 2 (or Stage 1.5) does not probe the geometry
|
||||
or the accessing mode of the @dfn{loading drive}, since Stage 1 has
|
||||
already probed them.
|
||||
|
||||
|
||||
@node I/O ports detection
|
||||
@section How to probe I/O ports used by INT 13H
|
||||
|
||||
FIXME: I will write this chapter after implementing the new technique.
|
||||
|
||||
|
||||
|
||||
@node Memory detection
|
||||
@section How to detect all installed RAM
|
||||
|
||||
FIXME: I doubt if Erich didn't write this chapter only himself wholly,
|
||||
so I will rewrite this chapter.
|
||||
|
||||
|
||||
@node Low-level disk I/O
|
||||
@section INT 13H disk I/O interrupts
|
||||
|
||||
FIXME: I'm not sure where some part of the original chapter is derived,
|
||||
so I will rewrite this chapter.
|
||||
|
||||
|
||||
@node MBR
|
||||
@section The structure of Master Boot Record
|
||||
|
||||
FIXME: Likewise.
|
||||
|
||||
|
||||
@node Partition table
|
||||
@section The format of partition tables
|
||||
|
||||
FIXME: Probably the original chapter is derived from "How It Works", so
|
||||
I will rewrite this chapter.
|
||||
|
||||
|
||||
@node Submitting patches
|
||||
@section Where and how you should send patches
|
||||
|
||||
When you write patches for GRUB, please send them to the mailing list
|
||||
@email{bug-grub@@gnu.org}. Here is the list of items of which you
|
||||
should take care:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Please make your patch as small as possible. Generally, it is not a good
|
||||
thing to make one big patch which changes many things. Instead,
|
||||
segregate features and produce many patches.
|
||||
|
||||
@item
|
||||
Use as late code as possible, for the original code. The CVS repository
|
||||
always has the current version (@pxref{Obtaining and Building GRUB}).
|
||||
|
||||
@item
|
||||
Write ChangeLog entries. @xref{Change Logs, , Change Logs, standards,
|
||||
GNU Coding Standards}, if you don't know how to write ChangeLog.
|
||||
|
||||
@item
|
||||
Make patches in unified diff format. @samp{diff -urN} is appropriate in
|
||||
most cases.
|
||||
|
||||
@item
|
||||
Don't make patches reversely. Reverse patches are difficult to read and
|
||||
use.
|
||||
|
||||
@item
|
||||
Be careful enough of the license term and the copyright. Because GRUB
|
||||
is under GNU General Public License, you may not steal code from
|
||||
software whose license is incompatible against GPL. And, if you copy
|
||||
code written by others, you must not ignore their copyrights. Feel free
|
||||
to ask GRUB maintainers, whenever you are not sure what you should do.
|
||||
|
||||
@item
|
||||
If your patch is too large to send in e-mail, put it at somewhere we can
|
||||
see. Usually, you shouldn't send e-mail over 20K.
|
||||
@end itemize
|
||||
@@ -1,27 +0,0 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.23.
|
||||
.TH MBCHK "1" "June 2006" "mbchk (GNU GRUB 0.97)" FSF
|
||||
.SH NAME
|
||||
mbchk \- check the format of a Multiboot kernel
|
||||
.SH SYNOPSIS
|
||||
.B mbchk
|
||||
[\fIOPTION\fR]... [\fIFILE\fR]...
|
||||
.SH DESCRIPTION
|
||||
Check if the format of FILE complies with the Multiboot Specification.
|
||||
.PP
|
||||
\fB\-q\fR, \fB\-\-quiet\fR suppress all normal output
|
||||
\fB\-h\fR, \fB\-\-help\fR display this help and exit
|
||||
\fB\-v\fR, \fB\-\-version\fR output version information and exit.
|
||||
.SH "REPORTING BUGS"
|
||||
Report bugs to <bug-grub@gnu.org>.
|
||||
.SH "SEE ALSO"
|
||||
The full documentation for
|
||||
.B mbchk
|
||||
is maintained as a Texinfo manual. If the
|
||||
.B info
|
||||
and
|
||||
.B mbchk
|
||||
programs are properly installed at your site, the command
|
||||
.IP
|
||||
.B info mbchk
|
||||
.PP
|
||||
should give you access to the complete manual.
|
||||
-170
@@ -1,170 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Get modification time of a file or directory and pretty-print it.
|
||||
|
||||
scriptversion=2004-12-08.12
|
||||
|
||||
# Copyright (C) 1995, 1996, 1997, 2003, 2004 Free Software Foundation, Inc.
|
||||
# written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
|
||||
#
|
||||
# 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, or (at your option)
|
||||
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No file. Try \`$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: mdate-sh [--help] [--version] FILE
|
||||
|
||||
Pretty-print the modification time of FILE.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit 0
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "mdate-sh $scriptversion"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# Prevent date giving response in another language.
|
||||
LANG=C
|
||||
export LANG
|
||||
LC_ALL=C
|
||||
export LC_ALL
|
||||
LC_TIME=C
|
||||
export LC_TIME
|
||||
|
||||
save_arg1="$1"
|
||||
|
||||
# Find out how to get the extended ls output of a file or directory.
|
||||
if ls -L /dev/null 1>/dev/null 2>&1; then
|
||||
ls_command='ls -L -l -d'
|
||||
else
|
||||
ls_command='ls -l -d'
|
||||
fi
|
||||
|
||||
# A `ls -l' line looks as follows on OS/2.
|
||||
# drwxrwx--- 0 Aug 11 2001 foo
|
||||
# This differs from Unix, which adds ownership information.
|
||||
# drwxrwx--- 2 root root 4096 Aug 11 2001 foo
|
||||
#
|
||||
# To find the date, we split the line on spaces and iterate on words
|
||||
# until we find a month. This cannot work with files whose owner is a
|
||||
# user named `Jan', or `Feb', etc. However, it's unlikely that `/'
|
||||
# will be owned by a user whose name is a month. So we first look at
|
||||
# the extended ls output of the root directory to decide how many
|
||||
# words should be skipped to get the date.
|
||||
|
||||
# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below.
|
||||
set x`ls -l -d /`
|
||||
|
||||
# Find which argument is the month.
|
||||
month=
|
||||
command=
|
||||
until test $month
|
||||
do
|
||||
shift
|
||||
# Add another shift to the command.
|
||||
command="$command shift;"
|
||||
case $1 in
|
||||
Jan) month=January; nummonth=1;;
|
||||
Feb) month=February; nummonth=2;;
|
||||
Mar) month=March; nummonth=3;;
|
||||
Apr) month=April; nummonth=4;;
|
||||
May) month=May; nummonth=5;;
|
||||
Jun) month=June; nummonth=6;;
|
||||
Jul) month=July; nummonth=7;;
|
||||
Aug) month=August; nummonth=8;;
|
||||
Sep) month=September; nummonth=9;;
|
||||
Oct) month=October; nummonth=10;;
|
||||
Nov) month=November; nummonth=11;;
|
||||
Dec) month=December; nummonth=12;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Get the extended ls output of the file or directory.
|
||||
set x`eval "$ls_command \"\$save_arg1\""`
|
||||
|
||||
# Remove all preceding arguments
|
||||
eval $command
|
||||
|
||||
# Get the month. Next argument is day, followed by the year or time.
|
||||
case $1 in
|
||||
Jan) month=January; nummonth=1;;
|
||||
Feb) month=February; nummonth=2;;
|
||||
Mar) month=March; nummonth=3;;
|
||||
Apr) month=April; nummonth=4;;
|
||||
May) month=May; nummonth=5;;
|
||||
Jun) month=June; nummonth=6;;
|
||||
Jul) month=July; nummonth=7;;
|
||||
Aug) month=August; nummonth=8;;
|
||||
Sep) month=September; nummonth=9;;
|
||||
Oct) month=October; nummonth=10;;
|
||||
Nov) month=November; nummonth=11;;
|
||||
Dec) month=December; nummonth=12;;
|
||||
esac
|
||||
|
||||
day=$2
|
||||
|
||||
# Here we have to deal with the problem that the ls output gives either
|
||||
# the time of day or the year.
|
||||
case $3 in
|
||||
*:*) set `date`; eval year=\$$#
|
||||
case $2 in
|
||||
Jan) nummonthtod=1;;
|
||||
Feb) nummonthtod=2;;
|
||||
Mar) nummonthtod=3;;
|
||||
Apr) nummonthtod=4;;
|
||||
May) nummonthtod=5;;
|
||||
Jun) nummonthtod=6;;
|
||||
Jul) nummonthtod=7;;
|
||||
Aug) nummonthtod=8;;
|
||||
Sep) nummonthtod=9;;
|
||||
Oct) nummonthtod=10;;
|
||||
Nov) nummonthtod=11;;
|
||||
Dec) nummonthtod=12;;
|
||||
esac
|
||||
# For the first six month of the year the time notation can also
|
||||
# be used for files modified in the last year.
|
||||
if (expr $nummonth \> $nummonthtod) > /dev/null;
|
||||
then
|
||||
year=`expr $year - 1`
|
||||
fi;;
|
||||
*) year=$3;;
|
||||
esac
|
||||
|
||||
# The result.
|
||||
echo $day $month $year
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
||||
@@ -1,82 +0,0 @@
|
||||
#
|
||||
# Sample boot menu configuration file
|
||||
#
|
||||
|
||||
# Boot automatically after 30 secs.
|
||||
timeout 30
|
||||
|
||||
# By default, boot the first entry.
|
||||
default 0
|
||||
|
||||
# Fallback to the second entry.
|
||||
fallback 1
|
||||
|
||||
# For booting GNU/Hurd
|
||||
title GNU/Hurd
|
||||
root (hd0,0)
|
||||
kernel /boot/gnumach.gz root=hd0s1
|
||||
module /boot/serverboot.gz
|
||||
|
||||
# For booting GNU/Linux
|
||||
title GNU/Linux
|
||||
root (hd1,0)
|
||||
kernel /vmlinuz root=/dev/hdb1
|
||||
#initrd /initrd.img
|
||||
|
||||
# For booting GNU/kFreeBSD
|
||||
title GNU/kFreeBSD
|
||||
root (hd0,2,a)
|
||||
kernel /boot/loader.gz
|
||||
|
||||
# For booting GNU/kNetBSD
|
||||
title GNU/kNetBSD
|
||||
root (hd0,2,a)
|
||||
kernel --type=netbsd /boot/knetbsd.gz
|
||||
|
||||
# For booting Mach (getting kernel from floppy)
|
||||
title Utah Mach4 multiboot
|
||||
root (hd0,2)
|
||||
pause Insert the diskette now!!
|
||||
kernel (fd0)/boot/kernel root=hd0s3
|
||||
module (fd0)/boot/bootstrap
|
||||
|
||||
# For booting FreeBSD
|
||||
title FreeBSD
|
||||
root (hd0,2,a)
|
||||
kernel /boot/loader
|
||||
|
||||
# For booting NetBSD
|
||||
title NetBSD
|
||||
root (hd0,2,a)
|
||||
kernel --type=netbsd /netbsd
|
||||
|
||||
# For booting OpenBSD
|
||||
title OpenBSD
|
||||
root (hd0,2,a)
|
||||
kernel --type=netbsd /bsd
|
||||
|
||||
# For booting OS/2
|
||||
title OS/2
|
||||
root (hd0,1)
|
||||
makeactive
|
||||
# chainload OS/2 bootloader from the first sector
|
||||
chainloader +1
|
||||
# This is similar to "chainload", but loads a specific file
|
||||
#chainloader /boot/chain.os2
|
||||
|
||||
# For booting Windows NT or Windows95
|
||||
title Windows NT / Windows 95 boot menu
|
||||
rootnoverify (hd0,0)
|
||||
makeactive
|
||||
chainloader +1
|
||||
# For loading DOS if Windows NT is installed
|
||||
# chainload /bootsect.dos
|
||||
|
||||
# For installing GRUB into the hard disk
|
||||
title Install GRUB into the hard disk
|
||||
root (hd0,0)
|
||||
setup (hd0)
|
||||
|
||||
# Change the colors.
|
||||
title Change the colors
|
||||
color light-green/brown blink-red/blue
|
||||
@@ -1,4 +0,0 @@
|
||||
@set UPDATED 8 May 2005
|
||||
@set UPDATED-MONTH May 2005
|
||||
@set EDITION 0.97
|
||||
@set VERSION 0.97
|
||||
-7086
File diff suppressed because it is too large.
Load diff
@@ -1,3 +0,0 @@
|
||||
.deps
|
||||
Makefile
|
||||
grub
|
||||
@@ -1,19 +0,0 @@
|
||||
sbin_PROGRAMS = grub
|
||||
|
||||
if SERIAL_SPEED_SIMULATION
|
||||
SERIAL_FLAGS = -DSUPPORT_SERIAL=1 -DSIMULATE_SLOWNESS_OF_SERIAL=1
|
||||
else
|
||||
SERIAL_FLAGS = -DSUPPORT_SERIAL=1
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
|
||||
-DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
|
||||
-DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \
|
||||
-DUSE_MD5_PASSWORDS=1 -DSUPPORT_HERCULES=1 \
|
||||
$(SERIAL_FLAGS) -I$(top_srcdir)/stage2 \
|
||||
-I$(top_srcdir)/stage1 -I$(top_srcdir)/lib
|
||||
|
||||
AM_CFLAGS = $(GRUB_CFLAGS)
|
||||
|
||||
grub_SOURCES = main.c asmstub.c
|
||||
grub_LDADD = ../stage2/libgrub.a ../lib/libcommon.a $(GRUB_LIBS)
|
||||
@@ -1,445 +0,0 @@
|
||||
# Makefile.in generated by automake 1.9.4 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
SOURCES = $(grub_SOURCES)
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
top_builddir = ..
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
INSTALL = @INSTALL@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
sbin_PROGRAMS = grub$(EXEEXT)
|
||||
subdir = grub
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
am__installdirs = "$(DESTDIR)$(sbindir)"
|
||||
sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
|
||||
PROGRAMS = $(sbin_PROGRAMS)
|
||||
am_grub_OBJECTS = main.$(OBJEXT) asmstub.$(OBJEXT)
|
||||
grub_OBJECTS = $(am_grub_OBJECTS)
|
||||
am__DEPENDENCIES_1 =
|
||||
grub_DEPENDENCIES = ../stage2/libgrub.a ../lib/libcommon.a \
|
||||
$(am__DEPENDENCIES_1)
|
||||
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
SOURCES = $(grub_SOURCES)
|
||||
DIST_SOURCES = $(grub_SOURCES)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMDEP_FALSE = @AMDEP_FALSE@
|
||||
AMDEP_TRUE = @AMDEP_TRUE@
|
||||
AMTAR = @AMTAR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
BUILD_EXAMPLE_KERNEL_FALSE = @BUILD_EXAMPLE_KERNEL_FALSE@
|
||||
BUILD_EXAMPLE_KERNEL_TRUE = @BUILD_EXAMPLE_KERNEL_TRUE@
|
||||
CC = @CC@
|
||||
CCAS = @CCAS@
|
||||
CCASFLAGS = @CCASFLAGS@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DISKLESS_SUPPORT_FALSE = @DISKLESS_SUPPORT_FALSE@
|
||||
DISKLESS_SUPPORT_TRUE = @DISKLESS_SUPPORT_TRUE@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FSYS_CFLAGS = @FSYS_CFLAGS@
|
||||
GRUB_CFLAGS = @GRUB_CFLAGS@
|
||||
GRUB_LIBS = @GRUB_LIBS@
|
||||
HERCULES_SUPPORT_FALSE = @HERCULES_SUPPORT_FALSE@
|
||||
HERCULES_SUPPORT_TRUE = @HERCULES_SUPPORT_TRUE@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAINT = @MAINT@
|
||||
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
|
||||
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
|
||||
NETBOOT_SUPPORT_FALSE = @NETBOOT_SUPPORT_FALSE@
|
||||
NETBOOT_SUPPORT_TRUE = @NETBOOT_SUPPORT_TRUE@
|
||||
NET_CFLAGS = @NET_CFLAGS@
|
||||
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||
OBJCOPY = @OBJCOPY@
|
||||
OBJEXT = @OBJEXT@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PERL = @PERL@
|
||||
RANLIB = @RANLIB@
|
||||
SERIAL_SPEED_SIMULATION_FALSE = @SERIAL_SPEED_SIMULATION_FALSE@
|
||||
SERIAL_SPEED_SIMULATION_TRUE = @SERIAL_SPEED_SIMULATION_TRUE@
|
||||
SERIAL_SUPPORT_FALSE = @SERIAL_SUPPORT_FALSE@
|
||||
SERIAL_SUPPORT_TRUE = @SERIAL_SUPPORT_TRUE@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STAGE1_CFLAGS = @STAGE1_CFLAGS@
|
||||
STAGE2_CFLAGS = @STAGE2_CFLAGS@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_OBJCOPY = @ac_ct_OBJCOPY@
|
||||
ac_ct_RANLIB = @ac_ct_RANLIB@
|
||||
ac_ct_STRIP = @ac_ct_STRIP@
|
||||
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
|
||||
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
datadir = @datadir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
@SERIAL_SPEED_SIMULATION_FALSE@SERIAL_FLAGS = -DSUPPORT_SERIAL=1
|
||||
@SERIAL_SPEED_SIMULATION_TRUE@SERIAL_FLAGS = -DSUPPORT_SERIAL=1 -DSIMULATE_SLOWNESS_OF_SERIAL=1
|
||||
AM_CPPFLAGS = -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
|
||||
-DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
|
||||
-DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \
|
||||
-DUSE_MD5_PASSWORDS=1 -DSUPPORT_HERCULES=1 \
|
||||
$(SERIAL_FLAGS) -I$(top_srcdir)/stage2 \
|
||||
-I$(top_srcdir)/stage1 -I$(top_srcdir)/lib
|
||||
|
||||
AM_CFLAGS = $(GRUB_CFLAGS)
|
||||
grub_SOURCES = main.c asmstub.c
|
||||
grub_LDADD = ../stage2/libgrub.a ../lib/libcommon.a $(GRUB_LIBS)
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .o .obj
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
|
||||
&& exit 0; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu grub/Makefile'; \
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu grub/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
install-sbinPROGRAMS: $(sbin_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(sbindir)" || $(mkdir_p) "$(DESTDIR)$(sbindir)"
|
||||
@list='$(sbin_PROGRAMS)'; for p in $$list; do \
|
||||
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
|
||||
if test -f $$p \
|
||||
; then \
|
||||
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
|
||||
echo " $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
|
||||
$(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
|
||||
else :; fi; \
|
||||
done
|
||||
|
||||
uninstall-sbinPROGRAMS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(sbin_PROGRAMS)'; for p in $$list; do \
|
||||
f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
|
||||
echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \
|
||||
rm -f "$(DESTDIR)$(sbindir)/$$f"; \
|
||||
done
|
||||
|
||||
clean-sbinPROGRAMS:
|
||||
-test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS)
|
||||
grub$(EXEEXT): $(grub_OBJECTS) $(grub_DEPENDENCIES)
|
||||
@rm -f grub$(EXEEXT)
|
||||
$(LINK) $(grub_LDFLAGS) $(grub_OBJECTS) $(grub_LDADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asmstub.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
|
||||
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
|
||||
|
||||
.c.obj:
|
||||
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
|
||||
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
|
||||
uninstall-info-am:
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$tags $$unique; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$tags $$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& cd $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) $$here
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
|
||||
list='$(DISTFILES)'; for file in $$list; do \
|
||||
case $$file in \
|
||||
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
|
||||
esac; \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
dir="/$$dir"; \
|
||||
$(mkdir_p) "$(distdir)$$dir"; \
|
||||
else \
|
||||
dir=''; \
|
||||
fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||
fi; \
|
||||
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(PROGRAMS)
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(sbindir)"; do \
|
||||
test -z "$$dir" || $(mkdir_p) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
|
||||
install-exec-am: install-sbinPROGRAMS
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-man:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-info-am uninstall-sbinPROGRAMS
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
|
||||
clean-sbinPROGRAMS ctags distclean distclean-compile \
|
||||
distclean-generic distclean-tags distdir dvi dvi-am html \
|
||||
html-am info info-am install install-am install-data \
|
||||
install-data-am install-exec install-exec-am install-info \
|
||||
install-info-am install-man install-sbinPROGRAMS install-strip \
|
||||
installcheck installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
|
||||
uninstall-am uninstall-info-am uninstall-sbinPROGRAMS
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
-1311
File diff suppressed because it is too large.
Load diff
-272
@@ -1,272 +0,0 @@
|
||||
/* main.c - experimental GRUB stage2 that runs under Unix */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 1999,2000,2001,2002 Free Software Foundation, Inc.
|
||||
*
|
||||
* 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
|
||||
* (at your option) 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.
|
||||
*/
|
||||
|
||||
/* Simulator entry point. */
|
||||
int grub_stage2 (void);
|
||||
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#define WITHOUT_LIBC_STUBS 1
|
||||
#include <shared.h>
|
||||
#include <term.h>
|
||||
#include <device.h>
|
||||
|
||||
char *program_name = 0;
|
||||
int use_config_file = 1;
|
||||
int use_preset_menu = 0;
|
||||
#ifdef HAVE_LIBCURSES
|
||||
int use_curses = 1;
|
||||
#else
|
||||
int use_curses = 0;
|
||||
#endif
|
||||
int verbose = 0;
|
||||
int read_only = 0;
|
||||
int floppy_disks = 1;
|
||||
char *device_map_file = 0;
|
||||
static int default_boot_drive;
|
||||
static int default_install_partition;
|
||||
static char *default_config_file;
|
||||
|
||||
#define OPT_HELP -2
|
||||
#define OPT_VERSION -3
|
||||
#define OPT_HOLD -4
|
||||
#define OPT_CONFIG_FILE -5
|
||||
#define OPT_INSTALL_PARTITION -6
|
||||
#define OPT_BOOT_DRIVE -7
|
||||
#define OPT_NO_CONFIG_FILE -8
|
||||
#define OPT_NO_CURSES -9
|
||||
#define OPT_BATCH -10
|
||||
#define OPT_VERBOSE -11
|
||||
#define OPT_READ_ONLY -12
|
||||
#define OPT_PROBE_SECOND_FLOPPY -13
|
||||
#define OPT_NO_FLOPPY -14
|
||||
#define OPT_DEVICE_MAP -15
|
||||
#define OPT_PRESET_MENU -16
|
||||
#define OPT_NO_PAGER -17
|
||||
#define OPTSTRING ""
|
||||
|
||||
static struct option longopts[] =
|
||||
{
|
||||
{"batch", no_argument, 0, OPT_BATCH},
|
||||
{"boot-drive", required_argument, 0, OPT_BOOT_DRIVE},
|
||||
{"config-file", required_argument, 0, OPT_CONFIG_FILE},
|
||||
{"device-map", required_argument, 0, OPT_DEVICE_MAP},
|
||||
{"help", no_argument, 0, OPT_HELP},
|
||||
{"hold", optional_argument, 0, OPT_HOLD},
|
||||
{"install-partition", required_argument, 0, OPT_INSTALL_PARTITION},
|
||||
{"no-config-file", no_argument, 0, OPT_NO_CONFIG_FILE},
|
||||
{"no-curses", no_argument, 0, OPT_NO_CURSES},
|
||||
{"no-floppy", no_argument, 0, OPT_NO_FLOPPY},
|
||||
{"no-pager", no_argument, 0, OPT_NO_PAGER},
|
||||
{"preset-menu", no_argument, 0, OPT_PRESET_MENU},
|
||||
{"probe-second-floppy", no_argument, 0, OPT_PROBE_SECOND_FLOPPY},
|
||||
{"read-only", no_argument, 0, OPT_READ_ONLY},
|
||||
{"verbose", no_argument, 0, OPT_VERBOSE},
|
||||
{"version", no_argument, 0, OPT_VERSION},
|
||||
{0},
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
usage (int status)
|
||||
{
|
||||
if (status)
|
||||
fprintf (stderr, "Try ``grub --help'' for more information.\n");
|
||||
else
|
||||
printf ("\
|
||||
Usage: grub [OPTION]...\n\
|
||||
\n\
|
||||
Enter the GRand Unified Bootloader command shell.\n\
|
||||
\n\
|
||||
--batch turn on batch mode for non-interactive use\n\
|
||||
--boot-drive=DRIVE specify stage2 boot_drive [default=0x%x]\n\
|
||||
--config-file=FILE specify stage2 config_file [default=%s]\n\
|
||||
--device-map=FILE use the device map file FILE\n\
|
||||
--help display this message and exit\n\
|
||||
--hold wait until a debugger will attach\n\
|
||||
--install-partition=PAR specify stage2 install_partition [default=0x%x]\n\
|
||||
--no-config-file do not use the config file\n\
|
||||
--no-curses do not use curses\n\
|
||||
--no-floppy do not probe any floppy drive\n\
|
||||
--no-pager do not use internal pager\n\
|
||||
--preset-menu use the preset menu\n\
|
||||
--probe-second-floppy probe the second floppy drive\n\
|
||||
--read-only do not write anything to devices\n\
|
||||
--verbose print verbose messages\n\
|
||||
--version print version information and exit\n\
|
||||
\n\
|
||||
Report bugs to <bug-grub@gnu.org>.\n\
|
||||
",
|
||||
default_boot_drive, default_config_file,
|
||||
default_install_partition);
|
||||
|
||||
exit (status);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
int hold = 0;
|
||||
|
||||
/* First of all, call sync so that all in-core data is scheduled to be
|
||||
actually written to disks. This is very important because GRUB does
|
||||
not use ordinary stdio interface but raw devices. */
|
||||
sync ();
|
||||
|
||||
program_name = argv[0];
|
||||
default_boot_drive = boot_drive;
|
||||
default_install_partition = install_partition;
|
||||
if (config_file)
|
||||
default_config_file = config_file;
|
||||
else
|
||||
default_config_file = "NONE";
|
||||
|
||||
/* Parse command-line options. */
|
||||
do
|
||||
{
|
||||
c = getopt_long (argc, argv, OPTSTRING, longopts, 0);
|
||||
switch (c)
|
||||
{
|
||||
case EOF:
|
||||
/* Fall through the bottom of the loop. */
|
||||
break;
|
||||
|
||||
case OPT_HELP:
|
||||
usage (0);
|
||||
break;
|
||||
|
||||
case OPT_VERSION:
|
||||
printf ("grub (GNU GRUB " VERSION ")\n");
|
||||
exit (0);
|
||||
break;
|
||||
|
||||
case OPT_HOLD:
|
||||
if (! optarg)
|
||||
hold = -1;
|
||||
else
|
||||
hold = atoi (optarg);
|
||||
break;
|
||||
|
||||
case OPT_CONFIG_FILE:
|
||||
strncpy (config_file, optarg, 127); /* FIXME: arbitrary */
|
||||
config_file[127] = '\0';
|
||||
break;
|
||||
|
||||
case OPT_INSTALL_PARTITION:
|
||||
install_partition = strtoul (optarg, 0, 0);
|
||||
if (install_partition == ULONG_MAX)
|
||||
{
|
||||
perror ("strtoul");
|
||||
exit (1);
|
||||
}
|
||||
break;
|
||||
|
||||
case OPT_BOOT_DRIVE:
|
||||
boot_drive = strtoul (optarg, 0, 0);
|
||||
if (boot_drive == ULONG_MAX)
|
||||
{
|
||||
perror ("strtoul");
|
||||
exit (1);
|
||||
}
|
||||
if (boot_drive >= NUM_DISKS)
|
||||
{
|
||||
fprintf (stderr, "boot_drive should be from 0 to %d\n",
|
||||
NUM_DISKS - 1);
|
||||
exit (1);
|
||||
}
|
||||
break;
|
||||
|
||||
case OPT_NO_CONFIG_FILE:
|
||||
use_config_file = 0;
|
||||
break;
|
||||
|
||||
case OPT_NO_CURSES:
|
||||
use_curses = 0;
|
||||
break;
|
||||
|
||||
case OPT_NO_PAGER:
|
||||
use_pager = 0;
|
||||
break;
|
||||
|
||||
case OPT_BATCH:
|
||||
/* This is the same as "--no-config-file --no-curses --no-pager". */
|
||||
use_config_file = 0;
|
||||
use_curses = 0;
|
||||
use_pager = 0;
|
||||
break;
|
||||
|
||||
case OPT_READ_ONLY:
|
||||
read_only = 1;
|
||||
break;
|
||||
|
||||
case OPT_VERBOSE:
|
||||
verbose = 1;
|
||||
break;
|
||||
|
||||
case OPT_NO_FLOPPY:
|
||||
floppy_disks = 0;
|
||||
break;
|
||||
|
||||
case OPT_PROBE_SECOND_FLOPPY:
|
||||
floppy_disks = 2;
|
||||
break;
|
||||
|
||||
case OPT_DEVICE_MAP:
|
||||
device_map_file = strdup (optarg);
|
||||
break;
|
||||
|
||||
case OPT_PRESET_MENU:
|
||||
use_preset_menu = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage (1);
|
||||
}
|
||||
}
|
||||
while (c != EOF);
|
||||
|
||||
/* Wait until the HOLD variable is cleared by an attached debugger. */
|
||||
if (hold && verbose)
|
||||
printf ("Run \"gdb %s %d\", and set HOLD to zero.\n",
|
||||
program_name, (int) getpid ());
|
||||
while (hold)
|
||||
{
|
||||
if (hold > 0)
|
||||
hold--;
|
||||
|
||||
sleep (1);
|
||||
}
|
||||
|
||||
/* If we don't have curses (!HAVE_LIBCURSES or --no-curses or
|
||||
--batch) put terminal to dumb for better handling of line i/o */
|
||||
if (! use_curses)
|
||||
current_term->flags = TERM_NO_EDIT | TERM_DUMB;
|
||||
|
||||
/* Transfer control to the stage2 simulator. */
|
||||
exit (grub_stage2 ());
|
||||
}
|
||||
-323
@@ -1,323 +0,0 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2004-12-17.09
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch. It can only install one file at a time, a restriction
|
||||
# shared with many OS's install programs.
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit="${DOITPROG-}"
|
||||
|
||||
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||
|
||||
mvprog="${MVPROG-mv}"
|
||||
cpprog="${CPPROG-cp}"
|
||||
chmodprog="${CHMODPROG-chmod}"
|
||||
chownprog="${CHOWNPROG-chown}"
|
||||
chgrpprog="${CHGRPPROG-chgrp}"
|
||||
stripprog="${STRIPPROG-strip}"
|
||||
rmprog="${RMPROG-rm}"
|
||||
mkdirprog="${MKDIRPROG-mkdir}"
|
||||
|
||||
chmodcmd="$chmodprog 0755"
|
||||
chowncmd=
|
||||
chgrpcmd=
|
||||
stripcmd=
|
||||
rmcmd="$rmprog -f"
|
||||
mvcmd="$mvprog"
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dstarg=
|
||||
no_target_directory=
|
||||
|
||||
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
Options:
|
||||
-c (ignored)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-s $stripprog installed files.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
|
||||
"
|
||||
|
||||
while test -n "$1"; do
|
||||
case $1 in
|
||||
-c) shift
|
||||
continue;;
|
||||
|
||||
-d) dir_arg=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
--help) echo "$usage"; exit 0;;
|
||||
|
||||
-m) chmodcmd="$chmodprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-s) stripcmd=$stripprog
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-t) dstarg=$2
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-T) no_target_directory=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit 0;;
|
||||
|
||||
*) # When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
test -n "$dir_arg$dstarg" && break
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dstarg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dstarg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dstarg=$arg
|
||||
done
|
||||
break;;
|
||||
esac
|
||||
done
|
||||
|
||||
if test -z "$1"; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call `install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names starting with `-'.
|
||||
case $src in
|
||||
-*) src=./$src ;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
src=
|
||||
|
||||
if test -d "$dst"; then
|
||||
mkdircmd=:
|
||||
chmodcmd=
|
||||
else
|
||||
mkdircmd=$mkdirprog
|
||||
fi
|
||||
else
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dstarg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dst=$dstarg
|
||||
# Protect names starting with `-'.
|
||||
case $dst in
|
||||
-*) dst=./$dst ;;
|
||||
esac
|
||||
|
||||
# If destination is a directory, append the input filename; won't work
|
||||
# if double slashes aren't ignored.
|
||||
if test -d "$dst"; then
|
||||
if test -n "$no_target_directory"; then
|
||||
echo "$0: $dstarg: Is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
dst=$dst/`basename "$src"`
|
||||
fi
|
||||
fi
|
||||
|
||||
# This sed command emulates the dirname command.
|
||||
dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
|
||||
|
||||
# Make sure that the destination directory exists.
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if test ! -d "$dstdir"; then
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-$defaultIFS}"
|
||||
|
||||
oIFS=$IFS
|
||||
# Some sh's can't handle IFS=/ for some reason.
|
||||
IFS='%'
|
||||
set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||
shift
|
||||
IFS=$oIFS
|
||||
|
||||
pathcomp=
|
||||
|
||||
while test $# -ne 0 ; do
|
||||
pathcomp=$pathcomp$1
|
||||
shift
|
||||
if test ! -d "$pathcomp"; then
|
||||
$mkdirprog "$pathcomp"
|
||||
# mkdir can fail with a `File exist' error in case several
|
||||
# install-sh are creating the directory concurrently. This
|
||||
# is OK.
|
||||
test -d "$pathcomp" || exit
|
||||
fi
|
||||
pathcomp=$pathcomp/
|
||||
done
|
||||
fi
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
$doit $mkdircmd "$dst" \
|
||||
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
|
||||
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
|
||||
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
|
||||
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
|
||||
|
||||
else
|
||||
dstfile=`basename "$dst"`
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=$dstdir/_inst.$$_
|
||||
rmtmp=$dstdir/_rm.$$_
|
||||
|
||||
# Trap to clean up those temp files at exit.
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
trap '(exit $?); exit' 1 2 13 15
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
$doit $cpprog "$src" "$dsttmp" &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
|
||||
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
|
||||
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
|
||||
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
|
||||
|| {
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
if test -f "$dstdir/$dstfile"; then
|
||||
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|
||||
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|
||||
|| {
|
||||
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
else
|
||||
:
|
||||
fi
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
|
||||
}
|
||||
}
|
||||
fi || { (exit 1); exit 1; }
|
||||
done
|
||||
|
||||
# The final little trick to "correctly" pass the exit status to the exit trap.
|
||||
{
|
||||
(exit 0); exit 0
|
||||
}
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
||||
@@ -1,2 +0,0 @@
|
||||
.deps
|
||||
Makefile
|
||||
@@ -1,6 +0,0 @@
|
||||
noinst_LIBRARIES = libcommon.a
|
||||
|
||||
AM_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/stage2 \
|
||||
-I$(top_srcdir)/stage1
|
||||
|
||||
libcommon_a_SOURCES = getopt.c getopt1.c getopt.h device.c device.h
|
||||
-416
@@ -1,416 +0,0 @@
|
||||
# Makefile.in generated by automake 1.9.4 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
SOURCES = $(libcommon_a_SOURCES)
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
top_builddir = ..
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
INSTALL = @INSTALL@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
subdir = lib
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
LIBRARIES = $(noinst_LIBRARIES)
|
||||
AR = ar
|
||||
ARFLAGS = cru
|
||||
libcommon_a_AR = $(AR) $(ARFLAGS)
|
||||
libcommon_a_LIBADD =
|
||||
am_libcommon_a_OBJECTS = getopt.$(OBJEXT) getopt1.$(OBJEXT) \
|
||||
device.$(OBJEXT)
|
||||
libcommon_a_OBJECTS = $(am_libcommon_a_OBJECTS)
|
||||
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
SOURCES = $(libcommon_a_SOURCES)
|
||||
DIST_SOURCES = $(libcommon_a_SOURCES)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMDEP_FALSE = @AMDEP_FALSE@
|
||||
AMDEP_TRUE = @AMDEP_TRUE@
|
||||
AMTAR = @AMTAR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
BUILD_EXAMPLE_KERNEL_FALSE = @BUILD_EXAMPLE_KERNEL_FALSE@
|
||||
BUILD_EXAMPLE_KERNEL_TRUE = @BUILD_EXAMPLE_KERNEL_TRUE@
|
||||
CC = @CC@
|
||||
CCAS = @CCAS@
|
||||
CCASFLAGS = @CCASFLAGS@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DISKLESS_SUPPORT_FALSE = @DISKLESS_SUPPORT_FALSE@
|
||||
DISKLESS_SUPPORT_TRUE = @DISKLESS_SUPPORT_TRUE@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FSYS_CFLAGS = @FSYS_CFLAGS@
|
||||
GRUB_CFLAGS = @GRUB_CFLAGS@
|
||||
GRUB_LIBS = @GRUB_LIBS@
|
||||
HERCULES_SUPPORT_FALSE = @HERCULES_SUPPORT_FALSE@
|
||||
HERCULES_SUPPORT_TRUE = @HERCULES_SUPPORT_TRUE@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAINT = @MAINT@
|
||||
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
|
||||
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
|
||||
NETBOOT_SUPPORT_FALSE = @NETBOOT_SUPPORT_FALSE@
|
||||
NETBOOT_SUPPORT_TRUE = @NETBOOT_SUPPORT_TRUE@
|
||||
NET_CFLAGS = @NET_CFLAGS@
|
||||
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||
OBJCOPY = @OBJCOPY@
|
||||
OBJEXT = @OBJEXT@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PERL = @PERL@
|
||||
RANLIB = @RANLIB@
|
||||
SERIAL_SPEED_SIMULATION_FALSE = @SERIAL_SPEED_SIMULATION_FALSE@
|
||||
SERIAL_SPEED_SIMULATION_TRUE = @SERIAL_SPEED_SIMULATION_TRUE@
|
||||
SERIAL_SUPPORT_FALSE = @SERIAL_SUPPORT_FALSE@
|
||||
SERIAL_SUPPORT_TRUE = @SERIAL_SUPPORT_TRUE@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STAGE1_CFLAGS = @STAGE1_CFLAGS@
|
||||
STAGE2_CFLAGS = @STAGE2_CFLAGS@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_OBJCOPY = @ac_ct_OBJCOPY@
|
||||
ac_ct_RANLIB = @ac_ct_RANLIB@
|
||||
ac_ct_STRIP = @ac_ct_STRIP@
|
||||
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
|
||||
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
datadir = @datadir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
noinst_LIBRARIES = libcommon.a
|
||||
AM_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/stage2 \
|
||||
-I$(top_srcdir)/stage1
|
||||
|
||||
libcommon_a_SOURCES = getopt.c getopt1.c getopt.h device.c device.h
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .o .obj
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
|
||||
&& exit 0; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu lib/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
clean-noinstLIBRARIES:
|
||||
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
|
||||
libcommon.a: $(libcommon_a_OBJECTS) $(libcommon_a_DEPENDENCIES)
|
||||
-rm -f libcommon.a
|
||||
$(libcommon_a_AR) libcommon.a $(libcommon_a_OBJECTS) $(libcommon_a_LIBADD)
|
||||
$(RANLIB) libcommon.a
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/device.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
|
||||
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
|
||||
|
||||
.c.obj:
|
||||
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
|
||||
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
|
||||
uninstall-info-am:
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$tags $$unique; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$tags $$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& cd $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) $$here
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
|
||||
list='$(DISTFILES)'; for file in $$list; do \
|
||||
case $$file in \
|
||||
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
|
||||
esac; \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
dir="/$$dir"; \
|
||||
$(mkdir_p) "$(distdir)$$dir"; \
|
||||
else \
|
||||
dir=''; \
|
||||
fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||
fi; \
|
||||
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(LIBRARIES)
|
||||
installdirs:
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-man:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-info-am
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
|
||||
clean-noinstLIBRARIES ctags distclean distclean-compile \
|
||||
distclean-generic distclean-tags distdir dvi dvi-am html \
|
||||
html-am info info-am install install-am install-data \
|
||||
install-data-am install-exec install-exec-am install-info \
|
||||
install-info-am install-man install-strip installcheck \
|
||||
installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
|
||||
uninstall-am uninstall-info-am
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
-950
@@ -1,950 +0,0 @@
|
||||
/* device.c - Some helper functions for OS devices and BIOS drives */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* 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
|
||||
* (at your option) 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.
|
||||
*/
|
||||
|
||||
/* Try to use glibc's transparant LFS support. */
|
||||
#define _LARGEFILE_SOURCE 1
|
||||
/* lseek becomes synonymous with lseek64. */
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __linux__
|
||||
# if !defined(__GLIBC__) || \
|
||||
((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))
|
||||
/* Maybe libc doesn't have large file support. */
|
||||
# include <linux/unistd.h> /* _llseek */
|
||||
# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */
|
||||
# include <sys/ioctl.h> /* ioctl */
|
||||
# ifndef HDIO_GETGEO
|
||||
# define HDIO_GETGEO 0x0301 /* get device geometry */
|
||||
/* If HDIO_GETGEO is not defined, it is unlikely that hd_geometry is
|
||||
defined. */
|
||||
struct hd_geometry
|
||||
{
|
||||
unsigned char heads;
|
||||
unsigned char sectors;
|
||||
unsigned short cylinders;
|
||||
unsigned long start;
|
||||
};
|
||||
# endif /* ! HDIO_GETGEO */
|
||||
# ifndef FLOPPY_MAJOR
|
||||
# define FLOPPY_MAJOR 2 /* the major number for floppy */
|
||||
# endif /* ! FLOPPY_MAJOR */
|
||||
# ifndef MAJOR
|
||||
# define MAJOR(dev) \
|
||||
({ \
|
||||
unsigned long long __dev = (dev); \
|
||||
(unsigned) ((__dev >> 8) & 0xfff) \
|
||||
| ((unsigned int) (__dev >> 32) & ~0xfff); \
|
||||
})
|
||||
# endif /* ! MAJOR */
|
||||
# ifndef CDROM_GET_CAPABILITY
|
||||
# define CDROM_GET_CAPABILITY 0x5331 /* get capabilities */
|
||||
# endif /* ! CDROM_GET_CAPABILITY */
|
||||
# ifndef BLKGETSIZE64
|
||||
# define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size */
|
||||
# endif /* ! BLKGETSIZE64 */
|
||||
#endif /* __linux__ */
|
||||
|
||||
/* Use __FreeBSD_kernel__ instead of __FreeBSD__ for compatibility with
|
||||
kFreeBSD-based non-FreeBSD systems (e.g. GNU/kFreeBSD) */
|
||||
#if defined(__FreeBSD__) && ! defined(__FreeBSD_kernel__)
|
||||
# define __FreeBSD_kernel__
|
||||
#endif
|
||||
#ifdef __FreeBSD_kernel__
|
||||
/* Obtain version of kFreeBSD headers */
|
||||
# include <osreldate.h>
|
||||
# ifndef __FreeBSD_kernel_version
|
||||
# define __FreeBSD_kernel_version __FreeBSD_version
|
||||
# endif
|
||||
|
||||
/* Runtime detection of kernel */
|
||||
# include <sys/utsname.h>
|
||||
int
|
||||
get_kfreebsd_version ()
|
||||
{
|
||||
struct utsname uts;
|
||||
int major; int minor, v[2];
|
||||
|
||||
uname (&uts);
|
||||
sscanf (uts.release, "%d.%d", &major, &minor);
|
||||
|
||||
if (major >= 9)
|
||||
major = 9;
|
||||
if (major >= 5)
|
||||
{
|
||||
v[0] = minor/10; v[1] = minor%10;
|
||||
}
|
||||
else
|
||||
{
|
||||
v[0] = minor%10; v[1] = minor/10;
|
||||
}
|
||||
return major*100000+v[0]*10000+v[1]*1000;
|
||||
}
|
||||
#endif /* __FreeBSD_kernel__ */
|
||||
|
||||
#if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
# include <sys/ioctl.h> /* ioctl */
|
||||
# include <sys/disklabel.h>
|
||||
# include <sys/cdio.h> /* CDIOCCLRDEBUG */
|
||||
# if defined(__FreeBSD_kernel__)
|
||||
# include <sys/param.h>
|
||||
# if __FreeBSD_kernel_version >= 500040
|
||||
# include <sys/disk.h>
|
||||
# endif
|
||||
# endif /* __FreeBSD_kernel__ */
|
||||
#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */
|
||||
|
||||
#ifdef HAVE_OPENDISK
|
||||
# include <util.h>
|
||||
#endif /* HAVE_OPENDISK */
|
||||
|
||||
#define WITHOUT_LIBC_STUBS 1
|
||||
#include <shared.h>
|
||||
#include <device.h>
|
||||
|
||||
/* Get the geometry of a drive DRIVE. */
|
||||
void
|
||||
get_drive_geometry (struct geometry *geom, char **map, int drive)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if (geom->flags == -1)
|
||||
{
|
||||
fd = open (map[drive], O_RDONLY);
|
||||
assert (fd >= 0);
|
||||
}
|
||||
else
|
||||
fd = geom->flags;
|
||||
|
||||
/* XXX This is the default size. */
|
||||
geom->sector_size = SECTOR_SIZE;
|
||||
|
||||
#if defined(__linux__)
|
||||
/* Linux */
|
||||
{
|
||||
struct hd_geometry hdg;
|
||||
unsigned long long nr;
|
||||
|
||||
if (ioctl (fd, HDIO_GETGEO, &hdg))
|
||||
goto fail;
|
||||
|
||||
if (ioctl (fd, BLKGETSIZE64, &nr))
|
||||
goto fail;
|
||||
|
||||
/* Got the geometry, so save it. */
|
||||
geom->cylinders = hdg.cylinders;
|
||||
geom->heads = hdg.heads;
|
||||
geom->sectors = hdg.sectors;
|
||||
geom->total_sectors = nr / 512;
|
||||
|
||||
goto success;
|
||||
}
|
||||
|
||||
#elif defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
# if defined(__FreeBSD_kernel__) && __FreeBSD_kernel_version >= 500040
|
||||
/* kFreeBSD version 5 or later */
|
||||
if (get_kfreebsd_version () >= 500040)
|
||||
{
|
||||
unsigned int sector_size;
|
||||
off_t media_size;
|
||||
unsigned int tmp;
|
||||
|
||||
if(ioctl (fd, DIOCGSECTORSIZE, §or_size) != 0)
|
||||
sector_size = 512;
|
||||
|
||||
if (ioctl (fd, DIOCGMEDIASIZE, &media_size) != 0)
|
||||
goto fail;
|
||||
|
||||
geom->total_sectors = media_size / sector_size;
|
||||
|
||||
if (ioctl (fd, DIOCGFWSECTORS, &tmp) == 0)
|
||||
geom->sectors = tmp;
|
||||
else
|
||||
geom->sectors = 63;
|
||||
if (ioctl (fd, DIOCGFWHEADS, &tmp) == 0)
|
||||
geom->heads = tmp;
|
||||
else if (geom->total_sectors <= 63 * 1 * 1024)
|
||||
geom->heads = 1;
|
||||
else if (geom->total_sectors <= 63 * 16 * 1024)
|
||||
geom->heads = 16;
|
||||
else
|
||||
geom->heads = 255;
|
||||
|
||||
geom->cylinders = (geom->total_sectors
|
||||
/ geom->heads
|
||||
/ geom->sectors);
|
||||
|
||||
goto success;
|
||||
}
|
||||
else
|
||||
#endif /* defined(__FreeBSD_kernel__) && __FreeBSD_kernel_version >= 500040 */
|
||||
|
||||
/* kFreeBSD < 5, NetBSD or OpenBSD */
|
||||
{
|
||||
struct disklabel hdg;
|
||||
if (ioctl (fd, DIOCGDINFO, &hdg))
|
||||
goto fail;
|
||||
|
||||
geom->cylinders = hdg.d_ncylinders;
|
||||
geom->heads = hdg.d_ntracks;
|
||||
geom->sectors = hdg.d_nsectors;
|
||||
geom->total_sectors = hdg.d_secperunit;
|
||||
|
||||
goto success;
|
||||
}
|
||||
|
||||
#else
|
||||
/* Notably, defined(__GNU__) */
|
||||
# warning "Automatic detection of geometries will be performed only \
|
||||
partially. This is not fatal."
|
||||
#endif
|
||||
|
||||
fail:
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
/* FIXME: It would be nice to somehow compute fake C/H/S settings,
|
||||
given a proper st_blocks size. */
|
||||
if (drive & 0x80)
|
||||
{
|
||||
geom->cylinders = DEFAULT_HD_CYLINDERS;
|
||||
geom->heads = DEFAULT_HD_HEADS;
|
||||
geom->sectors = DEFAULT_HD_SECTORS;
|
||||
}
|
||||
else
|
||||
{
|
||||
geom->cylinders = DEFAULT_FD_CYLINDERS;
|
||||
geom->heads = DEFAULT_FD_HEADS;
|
||||
geom->sectors = DEFAULT_FD_SECTORS;
|
||||
}
|
||||
|
||||
/* Set the total sectors properly, if we can. */
|
||||
if (! fstat (fd, &st) && st.st_size)
|
||||
geom->total_sectors = st.st_size >> SECTOR_BITS;
|
||||
else
|
||||
geom->total_sectors = geom->cylinders * geom->heads * geom->sectors;
|
||||
}
|
||||
|
||||
success:
|
||||
if (geom->flags == -1)
|
||||
close (fd);
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
/* Check if we have devfs support. */
|
||||
static int
|
||||
have_devfs (void)
|
||||
{
|
||||
static int dev_devfsd_exists = -1;
|
||||
|
||||
if (dev_devfsd_exists < 0)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
dev_devfsd_exists = stat ("/dev/.devfsd", &st) == 0;
|
||||
}
|
||||
|
||||
return dev_devfsd_exists;
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
|
||||
/* These three functions are quite different among OSes. */
|
||||
static void
|
||||
get_floppy_disk_name (char *name, int unit)
|
||||
{
|
||||
#if defined(__linux__)
|
||||
/* GNU/Linux */
|
||||
if (have_devfs ())
|
||||
sprintf (name, "/dev/floppy/%d", unit);
|
||||
else
|
||||
sprintf (name, "/dev/fd%d", unit);
|
||||
#elif defined(__GNU__)
|
||||
/* GNU/Hurd */
|
||||
sprintf (name, "/dev/fd%d", unit);
|
||||
#elif defined(__FreeBSD_kernel__)
|
||||
/* kFreeBSD */
|
||||
if (get_kfreebsd_version () >= 400000)
|
||||
sprintf (name, "/dev/fd%d", unit);
|
||||
else
|
||||
sprintf (name, "/dev/rfd%d", unit);
|
||||
#elif defined(__NetBSD__)
|
||||
/* NetBSD */
|
||||
/* opendisk() doesn't work for floppies. */
|
||||
sprintf (name, "/dev/rfd%da", unit);
|
||||
#elif defined(__OpenBSD__)
|
||||
/* OpenBSD */
|
||||
sprintf (name, "/dev/rfd%dc", unit);
|
||||
#elif defined(__QNXNTO__)
|
||||
/* QNX RTP */
|
||||
sprintf (name, "/dev/fd%d", unit);
|
||||
#else
|
||||
# warning "BIOS floppy drives cannot be guessed in your operating system."
|
||||
/* Set NAME to a bogus string. */
|
||||
*name = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
get_ide_disk_name (char *name, int unit)
|
||||
{
|
||||
#if defined(__linux__)
|
||||
/* GNU/Linux */
|
||||
sprintf (name, "/dev/hd%c", unit + 'a');
|
||||
#elif defined(__GNU__)
|
||||
/* GNU/Hurd */
|
||||
sprintf (name, "/dev/hd%d", unit);
|
||||
#elif defined(__FreeBSD_kernel__)
|
||||
/* kFreeBSD */
|
||||
if (get_kfreebsd_version () >= 400000)
|
||||
sprintf (name, "/dev/ad%d", unit);
|
||||
else
|
||||
sprintf (name, "/dev/rwd%d", unit);
|
||||
#elif defined(__NetBSD__) && defined(HAVE_OPENDISK)
|
||||
/* NetBSD */
|
||||
char shortname[16];
|
||||
int fd;
|
||||
|
||||
sprintf (shortname, "wd%d", unit);
|
||||
fd = opendisk (shortname, O_RDONLY, name,
|
||||
16, /* length of NAME */
|
||||
0 /* char device */
|
||||
);
|
||||
close (fd);
|
||||
#elif defined(__OpenBSD__)
|
||||
/* OpenBSD */
|
||||
sprintf (name, "/dev/rwd%dc", unit);
|
||||
#elif defined(__QNXNTO__)
|
||||
/* QNX RTP */
|
||||
/* Actually, QNX RTP doesn't distinguish IDE from SCSI, so this could
|
||||
contain SCSI disks. */
|
||||
sprintf (name, "/dev/hd%d", unit);
|
||||
#else
|
||||
# warning "BIOS IDE drives cannot be guessed in your operating system."
|
||||
/* Set NAME to a bogus string. */
|
||||
*name = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
get_scsi_disk_name (char *name, int unit)
|
||||
{
|
||||
#if defined(__linux__)
|
||||
/* GNU/Linux */
|
||||
sprintf (name, "/dev/sd%c", unit + 'a');
|
||||
#elif defined(__GNU__)
|
||||
/* GNU/Hurd */
|
||||
sprintf (name, "/dev/sd%d", unit);
|
||||
#elif defined(__FreeBSD_kernel__)
|
||||
/* kFreeBSD */
|
||||
if (get_kfreebsd_version () >= 400000)
|
||||
sprintf (name, "/dev/da%d", unit);
|
||||
else
|
||||
sprintf (name, "/dev/rda%d", unit);
|
||||
#elif defined(__NetBSD__) && defined(HAVE_OPENDISK)
|
||||
/* NetBSD */
|
||||
char shortname[16];
|
||||
int fd;
|
||||
|
||||
sprintf (shortname, "sd%d", unit);
|
||||
fd = opendisk (shortname, O_RDONLY, name,
|
||||
16, /* length of NAME */
|
||||
0 /* char device */
|
||||
);
|
||||
close (fd);
|
||||
#elif defined(__OpenBSD__)
|
||||
/* OpenBSD */
|
||||
sprintf (name, "/dev/rsd%dc", unit);
|
||||
#elif defined(__QNXNTO__)
|
||||
/* QNX RTP */
|
||||
/* QNX RTP doesn't distinguish SCSI from IDE, so it is better to
|
||||
disable the detection of SCSI disks here. */
|
||||
*name = 0;
|
||||
#else
|
||||
# warning "BIOS SCSI drives cannot be guessed in your operating system."
|
||||
/* Set NAME to a bogus string. */
|
||||
*name = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
static void
|
||||
get_dac960_disk_name (char *name, int controller, int drive)
|
||||
{
|
||||
sprintf (name, "/dev/rd/c%dd%d", controller, drive);
|
||||
}
|
||||
|
||||
static void
|
||||
get_ataraid_disk_name (char *name, int unit)
|
||||
{
|
||||
sprintf (name, "/dev/ataraid/d%c", unit + '0');
|
||||
}
|
||||
|
||||
static void
|
||||
get_i2o_disk_name (char *name, char unit)
|
||||
{
|
||||
sprintf (name, "/dev/i2o/hd%c", unit);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check if DEVICE can be read. If an error occurs, return zero,
|
||||
otherwise return non-zero. */
|
||||
int
|
||||
check_device (const char *device)
|
||||
{
|
||||
char buf[512];
|
||||
FILE *fp;
|
||||
|
||||
/* If DEVICE is empty, just return 1. */
|
||||
if (*device == 0)
|
||||
return 1;
|
||||
|
||||
fp = fopen (device, "r");
|
||||
if (! fp)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
#ifdef ENOMEDIUM
|
||||
case ENOMEDIUM:
|
||||
# if 0
|
||||
/* At the moment, this finds only CDROMs, which can't be
|
||||
read anyway, so leave it out. Code should be
|
||||
reactivated if `removable disks' and CDROMs are
|
||||
supported. */
|
||||
/* Accept it, it may be inserted. */
|
||||
return 1;
|
||||
# endif
|
||||
break;
|
||||
#endif /* ENOMEDIUM */
|
||||
default:
|
||||
/* Break case and leave. */
|
||||
break;
|
||||
}
|
||||
/* Error opening the device. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Make sure CD-ROMs don't get assigned a BIOS disk number
|
||||
before SCSI disks! */
|
||||
#ifdef __linux__
|
||||
# ifdef CDROM_GET_CAPABILITY
|
||||
if (ioctl (fileno (fp), CDROM_GET_CAPABILITY, 0) >= 0)
|
||||
return 0;
|
||||
# else /* ! CDROM_GET_CAPABILITY */
|
||||
/* Check if DEVICE is a CD-ROM drive by the HDIO_GETGEO ioctl. */
|
||||
{
|
||||
struct hd_geometry hdg;
|
||||
struct stat st;
|
||||
|
||||
if (fstat (fileno (fp), &st))
|
||||
return 0;
|
||||
|
||||
/* If it is a block device and isn't a floppy, check if HDIO_GETGEO
|
||||
succeeds. */
|
||||
if (S_ISBLK (st.st_mode)
|
||||
&& MAJOR (st.st_rdev) != FLOPPY_MAJOR
|
||||
&& ioctl (fileno (fp), HDIO_GETGEO, &hdg))
|
||||
return 0;
|
||||
}
|
||||
# endif /* ! CDROM_GET_CAPABILITY */
|
||||
#endif /* __linux__ */
|
||||
|
||||
#if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
# ifdef CDIOCCLRDEBUG
|
||||
if (ioctl (fileno (fp), CDIOCCLRDEBUG, 0) >= 0)
|
||||
return 0;
|
||||
# endif /* CDIOCCLRDEBUG */
|
||||
#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */
|
||||
|
||||
/* Attempt to read the first sector. */
|
||||
if (fread (buf, 1, 512, fp) != 512)
|
||||
{
|
||||
fclose (fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fclose (fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Read mapping information from FP, and write it to MAP. */
|
||||
static int
|
||||
read_device_map (FILE *fp, char **map, const char *map_file)
|
||||
{
|
||||
auto void show_error (int no, const char *msg);
|
||||
auto void show_warning (int no, const char *msg, ...);
|
||||
|
||||
auto void show_error (int no, const char *msg)
|
||||
{
|
||||
fprintf (stderr, "%s:%d: error: %s\n", map_file, no, msg);
|
||||
}
|
||||
|
||||
auto void show_warning (int no, const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, msg);
|
||||
fprintf (stderr, "%s:%d: warning: ", map_file, no);
|
||||
vfprintf (stderr, msg, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
/* If there is the device map file, use the data in it instead of
|
||||
probing devices. */
|
||||
char buf[1024]; /* XXX */
|
||||
int line_number = 0;
|
||||
|
||||
while (fgets (buf, sizeof (buf), fp))
|
||||
{
|
||||
char *ptr, *eptr;
|
||||
int drive;
|
||||
int is_floppy = 0;
|
||||
|
||||
/* Increase the number of lines. */
|
||||
line_number++;
|
||||
|
||||
/* If the first character is '#', skip it. */
|
||||
if (buf[0] == '#')
|
||||
continue;
|
||||
|
||||
ptr = buf;
|
||||
/* Skip leading spaces. */
|
||||
while (*ptr && isspace (*ptr))
|
||||
ptr++;
|
||||
|
||||
/* Skip empty lines. */
|
||||
if (! *ptr)
|
||||
continue;
|
||||
|
||||
if (*ptr != '(')
|
||||
{
|
||||
show_error (line_number, "No open parenthesis found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ptr++;
|
||||
if ((*ptr != 'f' && *ptr != 'h') || *(ptr + 1) != 'd')
|
||||
{
|
||||
show_error (line_number, "Bad drive name");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*ptr == 'f')
|
||||
is_floppy = 1;
|
||||
|
||||
ptr += 2;
|
||||
drive = strtoul (ptr, &ptr, 10);
|
||||
if (drive < 0)
|
||||
{
|
||||
show_error (line_number, "Bad device number");
|
||||
return 0;
|
||||
}
|
||||
else if (drive > 127)
|
||||
{
|
||||
show_warning (line_number,
|
||||
"Ignoring %cd%d due to a BIOS limitation",
|
||||
is_floppy ? 'f' : 'h', drive);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! is_floppy)
|
||||
drive += 0x80;
|
||||
|
||||
if (*ptr != ')')
|
||||
{
|
||||
show_error (line_number, "No close parenthesis found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ptr++;
|
||||
/* Skip spaces. */
|
||||
while (*ptr && isspace (*ptr))
|
||||
ptr++;
|
||||
|
||||
if (! *ptr)
|
||||
{
|
||||
show_error (line_number, "No filename found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Terminate the filename. */
|
||||
eptr = ptr;
|
||||
while (*eptr && ! isspace (*eptr))
|
||||
eptr++;
|
||||
*eptr = 0;
|
||||
|
||||
/* Multiple entries for a given drive is not allowed. */
|
||||
if (map[drive])
|
||||
{
|
||||
show_error (line_number, "Duplicated entry found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
map[drive] = strdup (ptr);
|
||||
assert (map[drive]);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Initialize the device map MAP. *MAP will be allocated from the heap
|
||||
space. If MAP_FILE is not NULL, then read mappings from the file
|
||||
MAP_FILE if it exists, otherwise, write guessed mappings to the file.
|
||||
FLOPPY_DISKS is the number of floppy disk drives which will be probed.
|
||||
If it is zero, don't probe any floppy at all. If it is one, probe one
|
||||
floppy. If it is two, probe two floppies. And so on. */
|
||||
int
|
||||
init_device_map (char ***map, const char *map_file, int floppy_disks)
|
||||
{
|
||||
int i;
|
||||
int num_hd = 0;
|
||||
FILE *fp = 0;
|
||||
|
||||
assert (map);
|
||||
assert (*map == 0);
|
||||
*map = malloc (NUM_DISKS * sizeof (char *));
|
||||
assert (*map);
|
||||
|
||||
/* Probe devices for creating the device map. */
|
||||
|
||||
/* Initialize DEVICE_MAP. */
|
||||
for (i = 0; i < NUM_DISKS; i++)
|
||||
(*map)[i] = 0;
|
||||
|
||||
if (map_file)
|
||||
{
|
||||
/* Open the device map file. */
|
||||
fp = fopen (map_file, "r");
|
||||
if (fp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = read_device_map (fp, *map, map_file);
|
||||
fclose (fp);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print something so that the user does not think GRUB has been
|
||||
crashed. */
|
||||
fprintf (stderr,
|
||||
"Probing devices to guess BIOS drives. "
|
||||
"This may take a long time.\n");
|
||||
|
||||
if (map_file)
|
||||
/* Try to open the device map file to write the probed data. */
|
||||
fp = fopen (map_file, "w");
|
||||
|
||||
/* Floppies. */
|
||||
for (i = 0; i < floppy_disks; i++)
|
||||
{
|
||||
char name[16];
|
||||
|
||||
get_floppy_disk_name (name, i);
|
||||
/* In floppies, write the map, whether check_device succeeds
|
||||
or not, because the user just does not insert floppies. */
|
||||
if (fp)
|
||||
fprintf (fp, "(fd%d)\t%s\n", i, name);
|
||||
|
||||
if (check_device (name))
|
||||
{
|
||||
(*map)[i] = strdup (name);
|
||||
assert ((*map)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
if (have_devfs ())
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
char discn[32];
|
||||
char name[PATH_MAX];
|
||||
struct stat st;
|
||||
|
||||
/* Linux creates symlinks "/dev/discs/discN" for convenience.
|
||||
The way to number disks is the same as GRUB's. */
|
||||
sprintf (discn, "/dev/discs/disc%d", num_hd);
|
||||
if (stat (discn, &st) < 0)
|
||||
break;
|
||||
|
||||
if (realpath (discn, name))
|
||||
{
|
||||
strcat (name, "/disc");
|
||||
(*map)[num_hd + 0x80] = strdup (name);
|
||||
assert ((*map)[num_hd + 0x80]);
|
||||
|
||||
/* If the device map file is opened, write the map. */
|
||||
if (fp)
|
||||
fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
|
||||
}
|
||||
|
||||
num_hd++;
|
||||
}
|
||||
|
||||
/* OK, close the device map file if opened. */
|
||||
if (fp)
|
||||
fclose (fp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
|
||||
/* IDE disks. */
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
char name[16];
|
||||
|
||||
get_ide_disk_name (name, i);
|
||||
if (check_device (name))
|
||||
{
|
||||
(*map)[num_hd + 0x80] = strdup (name);
|
||||
assert ((*map)[num_hd + 0x80]);
|
||||
|
||||
/* If the device map file is opened, write the map. */
|
||||
if (fp)
|
||||
fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
|
||||
|
||||
num_hd++;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
/* ATARAID disks. */
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
char name[20];
|
||||
|
||||
get_ataraid_disk_name (name, i);
|
||||
if (check_device (name))
|
||||
{
|
||||
(*map)[num_hd + 0x80] = strdup (name);
|
||||
assert ((*map)[num_hd + 0x80]);
|
||||
|
||||
/* If the device map file is opened, write the map. */
|
||||
if (fp)
|
||||
fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
|
||||
|
||||
num_hd++;
|
||||
}
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
|
||||
/* The rest is SCSI disks. */
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
char name[16];
|
||||
|
||||
get_scsi_disk_name (name, i);
|
||||
if (check_device (name))
|
||||
{
|
||||
(*map)[num_hd + 0x80] = strdup (name);
|
||||
assert ((*map)[num_hd + 0x80]);
|
||||
|
||||
/* If the device map file is opened, write the map. */
|
||||
if (fp)
|
||||
fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
|
||||
|
||||
num_hd++;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
/* This is for DAC960 - we have
|
||||
/dev/rd/c<controller>d<logical drive>p<partition>.
|
||||
|
||||
DAC960 driver currently supports up to 8 controllers, 32 logical
|
||||
drives, and 7 partitions. */
|
||||
{
|
||||
int controller, drive;
|
||||
|
||||
for (controller = 0; controller < 8; controller++)
|
||||
{
|
||||
for (drive = 0; drive < 15; drive++)
|
||||
{
|
||||
char name[24];
|
||||
|
||||
get_dac960_disk_name (name, controller, drive);
|
||||
if (check_device (name))
|
||||
{
|
||||
(*map)[num_hd + 0x80] = strdup (name);
|
||||
assert ((*map)[num_hd + 0x80]);
|
||||
|
||||
/* If the device map file is opened, write the map. */
|
||||
if (fp)
|
||||
fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
|
||||
|
||||
num_hd++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This is for I2O - we have /dev/i2o/hd<logical drive><partition> */
|
||||
{
|
||||
int unit;
|
||||
|
||||
for (unit = 'a'; unit < 'f'; unit++)
|
||||
{
|
||||
char name[24];
|
||||
|
||||
get_i2o_disk_name (name, unit);
|
||||
if (check_device (name))
|
||||
{
|
||||
(*map)[num_hd + 0x80] = strdup (name);
|
||||
assert ((*map)[num_hd + 0x80]);
|
||||
|
||||
/* If the device map file is opened, write the map. */
|
||||
if (fp)
|
||||
fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
|
||||
|
||||
num_hd++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
|
||||
/* OK, close the device map file if opened. */
|
||||
if (fp)
|
||||
fclose (fp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Restore the memory consumed for MAP. */
|
||||
void
|
||||
restore_device_map (char **map)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_DISKS; i++)
|
||||
if (map[i])
|
||||
free (map[i]);
|
||||
|
||||
free (map);
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
/* Linux-only functions, because Linux has a bug that the disk cache for
|
||||
a whole disk is not consistent with the one for a partition of the
|
||||
disk. */
|
||||
int
|
||||
is_disk_device (char **map, int drive)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
assert (map[drive] != 0);
|
||||
assert (stat (map[drive], &st) == 0);
|
||||
/* For now, disk devices under Linux are all block devices. */
|
||||
return S_ISBLK (st.st_mode);
|
||||
}
|
||||
|
||||
int
|
||||
write_to_partition (char **map, int drive, int partition,
|
||||
int sector, int size, const char *buf)
|
||||
{
|
||||
char dev[PATH_MAX]; /* XXX */
|
||||
int fd;
|
||||
|
||||
if ((partition & 0x00FF00) != 0x00FF00)
|
||||
{
|
||||
/* If the partition is a BSD partition, it is difficult to
|
||||
obtain the representation in Linux. So don't support that. */
|
||||
errnum = ERR_DEV_VALUES;
|
||||
return 1;
|
||||
}
|
||||
|
||||
assert (map[drive] != 0);
|
||||
|
||||
strcpy (dev, map[drive]);
|
||||
if (have_devfs ())
|
||||
{
|
||||
if (strcmp (dev + strlen(dev) - 5, "/disc") == 0)
|
||||
strcpy (dev + strlen(dev) - 5, "/part");
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((strncmp (dev, "/dev/ataraid/", 13) == 0) ||
|
||||
(strncmp (dev, "/dev/rd/", 8) == 0))
|
||||
strcpy (dev + strlen(dev), "p");
|
||||
}
|
||||
sprintf (dev + strlen(dev), "%d", ((partition >> 16) & 0xFF) + 1);
|
||||
|
||||
/* Open the partition. */
|
||||
fd = open (dev, O_RDWR);
|
||||
if (fd < 0)
|
||||
{
|
||||
errnum = ERR_NO_PART;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(__linux__) && (!defined(__GLIBC__) || \
|
||||
((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
|
||||
/* Maybe libc doesn't have large file support. */
|
||||
{
|
||||
loff_t offset, result;
|
||||
static int _llseek (uint filedes, ulong hi, ulong lo,
|
||||
loff_t *res, uint wh);
|
||||
_syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo,
|
||||
loff_t *, res, uint, wh);
|
||||
|
||||
offset = (loff_t) sector * (loff_t) SECTOR_SIZE;
|
||||
if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET))
|
||||
{
|
||||
errnum = ERR_DEV_VALUES;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
off_t offset = (off_t) sector * (off_t) SECTOR_SIZE;
|
||||
|
||||
if (lseek (fd, offset, SEEK_SET) != offset)
|
||||
{
|
||||
errnum = ERR_DEV_VALUES;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (write (fd, buf, size * SECTOR_SIZE) != (size * SECTOR_SIZE))
|
||||
{
|
||||
close (fd);
|
||||
errnum = ERR_WRITE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sync (); /* Paranoia. */
|
||||
close (fd);
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
@@ -1,48 +0,0 @@
|
||||
/* device.h - Define macros and declare prototypes for device.c */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 1999,2000,2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* 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
|
||||
* (at your option) 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.
|
||||
*/
|
||||
|
||||
#ifndef DEVICE_MAP_HEADER
|
||||
#define DEVICE_MAP_HEADER 1
|
||||
|
||||
/* The maximum number of BIOS disks. */
|
||||
#define NUM_DISKS 256
|
||||
|
||||
/* Simulated disk sizes. */
|
||||
#define DEFAULT_FD_CYLINDERS 80
|
||||
#define DEFAULT_FD_HEADS 2
|
||||
#define DEFAULT_FD_SECTORS 18
|
||||
#define DEFAULT_HD_CYLINDERS 620
|
||||
#define DEFAULT_HD_HEADS 128
|
||||
#define DEFAULT_HD_SECTORS 63
|
||||
|
||||
/* Function prototypes. */
|
||||
extern void get_drive_geometry (struct geometry *geom, char **map, int drive);
|
||||
extern int check_device (const char *device);
|
||||
extern int init_device_map (char ***map, const char *map_file,
|
||||
int no_floppies);
|
||||
extern void restore_device_map (char **map);
|
||||
|
||||
#ifdef __linux__
|
||||
extern int is_disk_device (char **map, int drive);
|
||||
extern int write_to_partition (char **map, int drive, int partition,
|
||||
int offset, int size, const char *buf);
|
||||
#endif /* __linux__ */
|
||||
|
||||
#endif /* DEVICE_MAP_HEADER */
|
||||
-1053
File diff suppressed because it is too large.
Load diff
-133
@@ -1,133 +0,0 @@
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
|
||||
|
||||
NOTE: The canonical source of this file is maintained with the GNU C Library.
|
||||
Bugs can be reported to bug-glibc@gnu.org.
|
||||
|
||||
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, or (at your option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
USA. */
|
||||
|
||||
#ifndef _GETOPT_H
|
||||
#define _GETOPT_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
extern char *optarg;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns -1, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
extern int optind;
|
||||
|
||||
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||
for unrecognized options. */
|
||||
|
||||
extern int opterr;
|
||||
|
||||
/* Set to an option character which was unrecognized. */
|
||||
|
||||
extern int optopt;
|
||||
|
||||
/* Describe the long-named options requested by the application.
|
||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||
of `struct option' terminated by an element containing a name which is
|
||||
zero.
|
||||
|
||||
The field `has_arg' is:
|
||||
no_argument (or 0) if the option does not take an argument,
|
||||
required_argument (or 1) if the option requires an argument,
|
||||
optional_argument (or 2) if the option takes an optional argument.
|
||||
|
||||
If the field `flag' is not NULL, it points to a variable that is set
|
||||
to the value given in the field `val' when the option is found, but
|
||||
left unchanged if the option is not found.
|
||||
|
||||
To have a long-named option do something other than set an `int' to
|
||||
a compiled-in constant, such as set a value from `optarg', set the
|
||||
option's `flag' field to zero and its `val' field to a nonzero
|
||||
value (the equivalent single-letter option character, if there is
|
||||
one). For long options that have a zero `flag' field, `getopt'
|
||||
returns the contents of the `val' field. */
|
||||
|
||||
struct option
|
||||
{
|
||||
#if defined (__STDC__) && __STDC__
|
||||
const char *name;
|
||||
#else
|
||||
char *name;
|
||||
#endif
|
||||
/* has_arg can't be an enum because some compilers complain about
|
||||
type mismatches in all the code that assumes it is an int. */
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
|
||||
#if defined (__STDC__) && __STDC__
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* Many other libraries have conflicting prototypes for getopt, with
|
||||
differences in the consts, in stdlib.h. To avoid compilation
|
||||
errors, only prototype getopt for the GNU C library. */
|
||||
extern int getopt (int argc, char *const *argv, const char *shortopts);
|
||||
#else /* not __GNU_LIBRARY__ */
|
||||
extern int getopt ();
|
||||
#endif /* __GNU_LIBRARY__ */
|
||||
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
extern int getopt_long_only (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
|
||||
/* Internal only. Users should not call this directly. */
|
||||
extern int _getopt_internal (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind,
|
||||
int long_only);
|
||||
#else /* not __STDC__ */
|
||||
extern int getopt ();
|
||||
extern int getopt_long ();
|
||||
extern int getopt_long_only ();
|
||||
|
||||
extern int _getopt_internal ();
|
||||
#endif /* __STDC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* getopt.h */
|
||||
-190
@@ -1,190 +0,0 @@
|
||||
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
||||
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
NOTE: The canonical source of this file is maintained with the GNU C Library.
|
||||
Bugs can be reported to bug-glibc@gnu.org.
|
||||
|
||||
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, or (at your option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
#if !defined __STDC__ || !__STDC__
|
||||
/* This is a separate conditional since some stdc systems
|
||||
reject `defined (const)'. */
|
||||
#ifndef const
|
||||
#define const
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#define GETOPT_INTERFACE_VERSION 2
|
||||
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
|
||||
#include <gnu-versions.h>
|
||||
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
|
||||
#define ELIDE_CODE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ELIDE_CODE
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
int
|
||||
getopt_long (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
}
|
||||
|
||||
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
|
||||
If an option that starts with '-' (not '--') doesn't match a long option,
|
||||
but does match a short option, it is parsed as a short option
|
||||
instead. */
|
||||
|
||||
int
|
||||
getopt_long_only (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||
}
|
||||
|
||||
|
||||
#endif /* Not ELIDE_CODE. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
int option_index = 0;
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"add", 1, 0, 0},
|
||||
{"append", 0, 0, 0},
|
||||
{"delete", 1, 0, 0},
|
||||
{"verbose", 0, 0, 0},
|
||||
{"create", 0, 0, 0},
|
||||
{"file", 1, 0, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long (argc, argv, "abc:d:0123456789",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
printf ("option %s", long_options[option_index].name);
|
||||
if (optarg)
|
||||
printf (" with arg %s", optarg);
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
printf ("option d with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
||||
@@ -1,353 +0,0 @@
|
||||
#! /bin/sh
|
||||
# Common stub for a few missing GNU programs while installing.
|
||||
|
||||
scriptversion=2004-09-07.08
|
||||
|
||||
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004
|
||||
# Free Software Foundation, Inc.
|
||||
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||
|
||||
# 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, or (at your option)
|
||||
# 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., 59 Temple Place - Suite 330, Boston, MA
|
||||
# 02111-1307, USA.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
if test $# -eq 0; then
|
||||
echo 1>&2 "Try \`$0 --help' for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
run=:
|
||||
|
||||
# In the cases where this matters, `missing' is being run in the
|
||||
# srcdir already.
|
||||
if test -f configure.ac; then
|
||||
configure_ac=configure.ac
|
||||
else
|
||||
configure_ac=configure.in
|
||||
fi
|
||||
|
||||
msg="missing on your system"
|
||||
|
||||
case "$1" in
|
||||
--run)
|
||||
# Try to run requested program, and just exit if it succeeds.
|
||||
run=
|
||||
shift
|
||||
"$@" && exit 0
|
||||
# Exit code 63 means version mismatch. This often happens
|
||||
# when the user try to use an ancient version of a tool on
|
||||
# a file that requires a minimum version. In this case we
|
||||
# we should proceed has if the program had been absent, or
|
||||
# if --run hadn't been passed.
|
||||
if test $? = 63; then
|
||||
run=:
|
||||
msg="probably too old"
|
||||
fi
|
||||
;;
|
||||
|
||||
-h|--h|--he|--hel|--help)
|
||||
echo "\
|
||||
$0 [OPTION]... PROGRAM [ARGUMENT]...
|
||||
|
||||
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
|
||||
error status if there is no known handling for PROGRAM.
|
||||
|
||||
Options:
|
||||
-h, --help display this help and exit
|
||||
-v, --version output version information and exit
|
||||
--run try to run the given command, and emulate it if it fails
|
||||
|
||||
Supported PROGRAM values:
|
||||
aclocal touch file \`aclocal.m4'
|
||||
autoconf touch file \`configure'
|
||||
autoheader touch file \`config.h.in'
|
||||
automake touch all \`Makefile.in' files
|
||||
bison create \`y.tab.[ch]', if possible, from existing .[ch]
|
||||
flex create \`lex.yy.c', if possible, from existing .c
|
||||
help2man touch the output file
|
||||
lex create \`lex.yy.c', if possible, from existing .c
|
||||
makeinfo touch the output file
|
||||
tar try tar, gnutar, gtar, then tar without non-portable flags
|
||||
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
|
||||
|
||||
Send bug reports to <bug-automake@gnu.org>."
|
||||
exit 0
|
||||
;;
|
||||
|
||||
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
||||
echo "missing $scriptversion (GNU Automake)"
|
||||
exit 0
|
||||
;;
|
||||
|
||||
-*)
|
||||
echo 1>&2 "$0: Unknown \`$1' option"
|
||||
echo 1>&2 "Try \`$0 --help' for more information"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
# Now exit if we have it, but it failed. Also exit now if we
|
||||
# don't have it and --version was passed (most likely to detect
|
||||
# the program).
|
||||
case "$1" in
|
||||
lex|yacc)
|
||||
# Not GNU programs, they don't have --version.
|
||||
;;
|
||||
|
||||
tar)
|
||||
if test -n "$run"; then
|
||||
echo 1>&2 "ERROR: \`tar' requires --run"
|
||||
exit 1
|
||||
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||
# We have it, but it failed.
|
||||
exit 1
|
||||
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
|
||||
# Could not run --version or --help. This is probably someone
|
||||
# running `$TOOL --version' or `$TOOL --help' to check whether
|
||||
# $TOOL exists and not knowing $TOOL uses missing.
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# If it does not exist, or fails to run (possibly an outdated version),
|
||||
# try to emulate it.
|
||||
case "$1" in
|
||||
aclocal*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
|
||||
to install the \`Automake' and \`Perl' packages. Grab them from
|
||||
any GNU archive site."
|
||||
touch aclocal.m4
|
||||
;;
|
||||
|
||||
autoconf)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified \`${configure_ac}'. You might want to install the
|
||||
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
|
||||
archive site."
|
||||
touch configure
|
||||
;;
|
||||
|
||||
autoheader)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified \`acconfig.h' or \`${configure_ac}'. You might want
|
||||
to install the \`Autoconf' and \`GNU m4' packages. Grab them
|
||||
from any GNU archive site."
|
||||
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
|
||||
test -z "$files" && files="config.h"
|
||||
touch_files=
|
||||
for f in $files; do
|
||||
case "$f" in
|
||||
*:*) touch_files="$touch_files "`echo "$f" |
|
||||
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
|
||||
*) touch_files="$touch_files $f.in";;
|
||||
esac
|
||||
done
|
||||
touch $touch_files
|
||||
;;
|
||||
|
||||
automake*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
|
||||
You might want to install the \`Automake' and \`Perl' packages.
|
||||
Grab them from any GNU archive site."
|
||||
find . -type f -name Makefile.am -print |
|
||||
sed 's/\.am$/.in/' |
|
||||
while read f; do touch "$f"; done
|
||||
;;
|
||||
|
||||
autom4te)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is needed, but is $msg.
|
||||
You might have modified some files without having the
|
||||
proper tools for further handling them.
|
||||
You can get \`$1' as part of \`Autoconf' from any GNU
|
||||
archive site."
|
||||
|
||||
file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
|
||||
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
|
||||
if test -f "$file"; then
|
||||
touch $file
|
||||
else
|
||||
test -z "$file" || exec >$file
|
||||
echo "#! /bin/sh"
|
||||
echo "# Created by GNU Automake missing as a replacement of"
|
||||
echo "# $ $@"
|
||||
echo "exit 0"
|
||||
chmod +x $file
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
bison|yacc)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' $msg. You should only need it if
|
||||
you modified a \`.y' file. You may need the \`Bison' package
|
||||
in order for those modifications to take effect. You can get
|
||||
\`Bison' from any GNU archive site."
|
||||
rm -f y.tab.c y.tab.h
|
||||
if [ $# -ne 1 ]; then
|
||||
eval LASTARG="\${$#}"
|
||||
case "$LASTARG" in
|
||||
*.y)
|
||||
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
|
||||
if [ -f "$SRCFILE" ]; then
|
||||
cp "$SRCFILE" y.tab.c
|
||||
fi
|
||||
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
|
||||
if [ -f "$SRCFILE" ]; then
|
||||
cp "$SRCFILE" y.tab.h
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
if [ ! -f y.tab.h ]; then
|
||||
echo >y.tab.h
|
||||
fi
|
||||
if [ ! -f y.tab.c ]; then
|
||||
echo 'main() { return 0; }' >y.tab.c
|
||||
fi
|
||||
;;
|
||||
|
||||
lex|flex)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified a \`.l' file. You may need the \`Flex' package
|
||||
in order for those modifications to take effect. You can get
|
||||
\`Flex' from any GNU archive site."
|
||||
rm -f lex.yy.c
|
||||
if [ $# -ne 1 ]; then
|
||||
eval LASTARG="\${$#}"
|
||||
case "$LASTARG" in
|
||||
*.l)
|
||||
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
|
||||
if [ -f "$SRCFILE" ]; then
|
||||
cp "$SRCFILE" lex.yy.c
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
if [ ! -f lex.yy.c ]; then
|
||||
echo 'main() { return 0; }' >lex.yy.c
|
||||
fi
|
||||
;;
|
||||
|
||||
help2man)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified a dependency of a manual page. You may need the
|
||||
\`Help2man' package in order for those modifications to take
|
||||
effect. You can get \`Help2man' from any GNU archive site."
|
||||
|
||||
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
|
||||
if test -z "$file"; then
|
||||
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
|
||||
fi
|
||||
if [ -f "$file" ]; then
|
||||
touch $file
|
||||
else
|
||||
test -z "$file" || exec >$file
|
||||
echo ".ab help2man is required to generate this page"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
makeinfo)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified a \`.texi' or \`.texinfo' file, or any other file
|
||||
indirectly affecting the aspect of the manual. The spurious
|
||||
call might also be the consequence of using a buggy \`make' (AIX,
|
||||
DU, IRIX). You might want to install the \`Texinfo' package or
|
||||
the \`GNU make' package. Grab either from any GNU archive site."
|
||||
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
|
||||
if test -z "$file"; then
|
||||
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
|
||||
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
|
||||
fi
|
||||
touch $file
|
||||
;;
|
||||
|
||||
tar)
|
||||
shift
|
||||
|
||||
# We have already tried tar in the generic part.
|
||||
# Look for gnutar/gtar before invocation to avoid ugly error
|
||||
# messages.
|
||||
if (gnutar --version > /dev/null 2>&1); then
|
||||
gnutar "$@" && exit 0
|
||||
fi
|
||||
if (gtar --version > /dev/null 2>&1); then
|
||||
gtar "$@" && exit 0
|
||||
fi
|
||||
firstarg="$1"
|
||||
if shift; then
|
||||
case "$firstarg" in
|
||||
*o*)
|
||||
firstarg=`echo "$firstarg" | sed s/o//`
|
||||
tar "$firstarg" "$@" && exit 0
|
||||
;;
|
||||
esac
|
||||
case "$firstarg" in
|
||||
*h*)
|
||||
firstarg=`echo "$firstarg" | sed s/h//`
|
||||
tar "$firstarg" "$@" && exit 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
echo 1>&2 "\
|
||||
WARNING: I can't seem to be able to run \`tar' with the given arguments.
|
||||
You may want to install GNU tar or Free paxutils, or check the
|
||||
command line arguments."
|
||||
exit 1
|
||||
;;
|
||||
|
||||
*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is needed, and is $msg.
|
||||
You might have modified some files without having the
|
||||
proper tools for further handling them. Check the \`README' file,
|
||||
it often tells you about the needed prerequisites for installing
|
||||
this package. You may also peek at any GNU archive site, in case
|
||||
some other package would contain this missing \`$1' program."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
||||
-150
@@ -1,150 +0,0 @@
|
||||
#! /bin/sh
|
||||
# mkinstalldirs --- make directory hierarchy
|
||||
|
||||
scriptversion=2004-02-15.20
|
||||
|
||||
# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1993-05-16
|
||||
# Public domain.
|
||||
#
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
errstatus=0
|
||||
dirmode=""
|
||||
|
||||
usage="\
|
||||
Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
|
||||
|
||||
Create each directory DIR (with mode MODE, if specified), including all
|
||||
leading file name components.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>."
|
||||
|
||||
# process command line arguments
|
||||
while test $# -gt 0 ; do
|
||||
case $1 in
|
||||
-h | --help | --h*) # -h for help
|
||||
echo "$usage"
|
||||
exit 0
|
||||
;;
|
||||
-m) # -m PERM arg
|
||||
shift
|
||||
test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
|
||||
dirmode=$1
|
||||
shift
|
||||
;;
|
||||
--version)
|
||||
echo "$0 $scriptversion"
|
||||
exit 0
|
||||
;;
|
||||
--) # stop option processing
|
||||
shift
|
||||
break
|
||||
;;
|
||||
-*) # unknown option
|
||||
echo "$usage" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
*) # first non-opt arg
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
for file
|
||||
do
|
||||
if test -d "$file"; then
|
||||
shift
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
case $# in
|
||||
0) exit 0 ;;
|
||||
esac
|
||||
|
||||
# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
|
||||
# mkdir -p a/c at the same time, both will detect that a is missing,
|
||||
# one will create a, then the other will try to create a and die with
|
||||
# a "File exists" error. This is a problem when calling mkinstalldirs
|
||||
# from a parallel make. We use --version in the probe to restrict
|
||||
# ourselves to GNU mkdir, which is thread-safe.
|
||||
case $dirmode in
|
||||
'')
|
||||
if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
|
||||
echo "mkdir -p -- $*"
|
||||
exec mkdir -p -- "$@"
|
||||
else
|
||||
# On NextStep and OpenStep, the `mkdir' command does not
|
||||
# recognize any option. It will interpret all options as
|
||||
# directories to create, and then abort because `.' already
|
||||
# exists.
|
||||
test -d ./-p && rmdir ./-p
|
||||
test -d ./--version && rmdir ./--version
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
|
||||
test ! -d ./--version; then
|
||||
echo "mkdir -m $dirmode -p -- $*"
|
||||
exec mkdir -m "$dirmode" -p -- "$@"
|
||||
else
|
||||
# Clean up after NextStep and OpenStep mkdir.
|
||||
for d in ./-m ./-p ./--version "./$dirmode";
|
||||
do
|
||||
test -d $d && rmdir $d
|
||||
done
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
for file
|
||||
do
|
||||
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
|
||||
shift
|
||||
|
||||
pathcomp=
|
||||
for d
|
||||
do
|
||||
pathcomp="$pathcomp$d"
|
||||
case $pathcomp in
|
||||
-*) pathcomp=./$pathcomp ;;
|
||||
esac
|
||||
|
||||
if test ! -d "$pathcomp"; then
|
||||
echo "mkdir $pathcomp"
|
||||
|
||||
mkdir "$pathcomp" || lasterr=$?
|
||||
|
||||
if test ! -d "$pathcomp"; then
|
||||
errstatus=$lasterr
|
||||
else
|
||||
if test ! -z "$dirmode"; then
|
||||
echo "chmod $dirmode $pathcomp"
|
||||
lasterr=""
|
||||
chmod "$dirmode" "$pathcomp" || lasterr=$?
|
||||
|
||||
if test ! -z "$lasterr"; then
|
||||
errstatus=$lasterr
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
pathcomp="$pathcomp/"
|
||||
done
|
||||
done
|
||||
|
||||
exit $errstatus
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
||||
@@ -1,2 +0,0 @@
|
||||
.deps
|
||||
Makefile
|
||||
-620
@@ -1,620 +0,0 @@
|
||||
/**************************************************************************
|
||||
ETHERBOOT - BOOTP/TFTP Bootstrap Program
|
||||
|
||||
Author: Martin Renters.
|
||||
Date: Mar 22 1995
|
||||
|
||||
This code is based heavily on David Greenman's if_ed.c driver and
|
||||
Andres Vega Garcia's if_ep.c driver.
|
||||
|
||||
Copyright (C) 1993-1994, David Greenman, Martin Renters.
|
||||
Copyright (C) 1993-1995, Andres Vega Garcia.
|
||||
Copyright (C) 1995, Serge Babkin.
|
||||
This software may be used, modified, copied, distributed, and sold, in
|
||||
both source and binary form provided that the above copyright and these
|
||||
terms are retained. Under no circumstances are the authors responsible for
|
||||
the proper functioning of this software, nor do the authors assume any
|
||||
responsibility for damages incurred with its use.
|
||||
|
||||
3c509 support added by Serge Babkin (babkin@hq.icb.chel.su)
|
||||
|
||||
$Id$
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
/* #define EDEBUG */
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "cards.h"
|
||||
#include "timer.h"
|
||||
#include "3c509.h"
|
||||
|
||||
#define udelay(n) waiton_timer2(((n)*TICKS_PER_MS)/1000)
|
||||
|
||||
static unsigned short eth_nic_base;
|
||||
static enum { none, bnc, utp } connector = none; /* for 3C509 */
|
||||
|
||||
#ifdef INCLUDE_3C529
|
||||
/*
|
||||
* This table and several other pieces of the MCA support
|
||||
* code were shamelessly borrowed from the Linux kernel source.
|
||||
*
|
||||
* MCA support added by Adam Fritzler (mid@auk.cx)
|
||||
*
|
||||
*/
|
||||
struct el3_mca_adapters_struct {
|
||||
const char *name;
|
||||
int id;
|
||||
};
|
||||
static struct el3_mca_adapters_struct el3_mca_adapters[] = {
|
||||
{ "3Com 3c529 EtherLink III (10base2)", 0x627c },
|
||||
{ "3Com 3c529 EtherLink III (10baseT)", 0x627d },
|
||||
{ "3Com 3c529 EtherLink III (test mode)", 0x62db },
|
||||
{ "3Com 3c529 EtherLink III (TP or coax)", 0x62f6 },
|
||||
{ "3Com 3c529 EtherLink III (TP)", 0x62f7 },
|
||||
{ NULL, 0 },
|
||||
};
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
ETH_RESET - Reset adapter
|
||||
***************************************************************************/
|
||||
static void t509_reset(struct nic *nic)
|
||||
{
|
||||
int i;
|
||||
|
||||
/***********************************************************
|
||||
Reset 3Com 509 card
|
||||
*************************************************************/
|
||||
|
||||
/* stop card */
|
||||
outw(RX_DISABLE, BASE + EP_COMMAND);
|
||||
outw(RX_DISCARD_TOP_PACK, BASE + EP_COMMAND);
|
||||
while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)
|
||||
;
|
||||
outw(TX_DISABLE, BASE + EP_COMMAND);
|
||||
outw(STOP_TRANSCEIVER, BASE + EP_COMMAND);
|
||||
udelay(1000);
|
||||
outw(RX_RESET, BASE + EP_COMMAND);
|
||||
outw(TX_RESET, BASE + EP_COMMAND);
|
||||
outw(C_INTR_LATCH, BASE + EP_COMMAND);
|
||||
outw(SET_RD_0_MASK, BASE + EP_COMMAND);
|
||||
outw(SET_INTR_MASK, BASE + EP_COMMAND);
|
||||
outw(SET_RX_FILTER, BASE + EP_COMMAND);
|
||||
|
||||
/*
|
||||
* initialize card
|
||||
*/
|
||||
while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)
|
||||
;
|
||||
|
||||
GO_WINDOW(0);
|
||||
|
||||
/* Disable the card */
|
||||
outw(0, BASE + EP_W0_CONFIG_CTRL);
|
||||
|
||||
/* Configure IRQ to none */
|
||||
outw(SET_IRQ(0), BASE + EP_W0_RESOURCE_CFG);
|
||||
|
||||
/* Enable the card */
|
||||
outw(ENABLE_DRQ_IRQ, BASE + EP_W0_CONFIG_CTRL);
|
||||
|
||||
GO_WINDOW(2);
|
||||
|
||||
/* Reload the ether_addr. */
|
||||
for (i = 0; i < ETH_ALEN; i++)
|
||||
outb(nic->node_addr[i], BASE + EP_W2_ADDR_0 + i);
|
||||
|
||||
outw(RX_RESET, BASE + EP_COMMAND);
|
||||
outw(TX_RESET, BASE + EP_COMMAND);
|
||||
|
||||
/* Window 1 is operating window */
|
||||
GO_WINDOW(1);
|
||||
for (i = 0; i < 31; i++)
|
||||
inb(BASE + EP_W1_TX_STATUS);
|
||||
|
||||
/* get rid of stray intr's */
|
||||
outw(ACK_INTR | 0xff, BASE + EP_COMMAND);
|
||||
|
||||
outw(SET_RD_0_MASK | S_5_INTS, BASE + EP_COMMAND);
|
||||
|
||||
outw(SET_INTR_MASK, BASE + EP_COMMAND);
|
||||
|
||||
outw(SET_RX_FILTER | FIL_INDIVIDUAL | FIL_BRDCST, BASE + EP_COMMAND);
|
||||
|
||||
/* configure BNC */
|
||||
if (connector == bnc) {
|
||||
outw(START_TRANSCEIVER, BASE + EP_COMMAND);
|
||||
udelay(1000);
|
||||
}
|
||||
/* configure UTP */
|
||||
else if (connector == utp) {
|
||||
GO_WINDOW(4);
|
||||
outw(ENABLE_UTP, BASE + EP_W4_MEDIA_TYPE);
|
||||
sleep(2); /* Give time for media to negotiate */
|
||||
GO_WINDOW(1);
|
||||
}
|
||||
|
||||
/* start transceiver and receiver */
|
||||
outw(RX_ENABLE, BASE + EP_COMMAND);
|
||||
outw(TX_ENABLE, BASE + EP_COMMAND);
|
||||
|
||||
/* set early threshold for minimal packet length */
|
||||
outw(SET_RX_EARLY_THRESH | ETH_ZLEN, BASE + EP_COMMAND);
|
||||
outw(SET_TX_START_THRESH | 16, BASE + EP_COMMAND);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
ETH_TRANSMIT - Transmit a frame
|
||||
***************************************************************************/
|
||||
static char padmap[] = {
|
||||
0, 3, 2, 1};
|
||||
|
||||
static void t509_transmit(
|
||||
struct nic *nic,
|
||||
const char *d, /* Destination */
|
||||
unsigned int t, /* Type */
|
||||
unsigned int s, /* size */
|
||||
const char *p) /* Packet */
|
||||
{
|
||||
register unsigned int len;
|
||||
int pad;
|
||||
int status;
|
||||
|
||||
#ifdef EDEBUG
|
||||
printf("{l=%d,t=%hX}",s+ETH_HLEN,t);
|
||||
#endif
|
||||
|
||||
/* swap bytes of type */
|
||||
t= htons(t);
|
||||
|
||||
len=s+ETH_HLEN; /* actual length of packet */
|
||||
pad = padmap[len & 3];
|
||||
|
||||
/*
|
||||
* The 3c509 automatically pads short packets to minimum ethernet length,
|
||||
* but we drop packets that are too large. Perhaps we should truncate
|
||||
* them instead?
|
||||
*/
|
||||
if (len + pad > ETH_FRAME_LEN) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* drop acknowledgements */
|
||||
while ((status=inb(BASE + EP_W1_TX_STATUS)) & TXS_COMPLETE ) {
|
||||
if (status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) {
|
||||
outw(TX_RESET, BASE + EP_COMMAND);
|
||||
outw(TX_ENABLE, BASE + EP_COMMAND);
|
||||
}
|
||||
outb(0x0, BASE + EP_W1_TX_STATUS);
|
||||
}
|
||||
|
||||
while (inw(BASE + EP_W1_FREE_TX) < (unsigned short)len + pad + 4)
|
||||
; /* no room in FIFO */
|
||||
|
||||
outw(len, BASE + EP_W1_TX_PIO_WR_1);
|
||||
outw(0x0, BASE + EP_W1_TX_PIO_WR_1); /* Second dword meaningless */
|
||||
|
||||
/* write packet */
|
||||
outsw(BASE + EP_W1_TX_PIO_WR_1, d, ETH_ALEN/2);
|
||||
outsw(BASE + EP_W1_TX_PIO_WR_1, nic->node_addr, ETH_ALEN/2);
|
||||
outw(t, BASE + EP_W1_TX_PIO_WR_1);
|
||||
outsw(BASE + EP_W1_TX_PIO_WR_1, p, s / 2);
|
||||
if (s & 1)
|
||||
outb(*(p+s - 1), BASE + EP_W1_TX_PIO_WR_1);
|
||||
|
||||
while (pad--)
|
||||
outb(0, BASE + EP_W1_TX_PIO_WR_1); /* Padding */
|
||||
|
||||
/* wait for Tx complete */
|
||||
while((inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS) != 0)
|
||||
;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
ETH_POLL - Wait for a frame
|
||||
***************************************************************************/
|
||||
static int t509_poll(struct nic *nic)
|
||||
{
|
||||
/* common variables */
|
||||
unsigned short type = 0; /* used by EDEBUG */
|
||||
/* variables for 3C509 */
|
||||
short status, cst;
|
||||
register short rx_fifo;
|
||||
|
||||
cst=inw(BASE + EP_STATUS);
|
||||
|
||||
#ifdef EDEBUG
|
||||
if(cst & 0x1FFF)
|
||||
printf("-%hX-",cst);
|
||||
#endif
|
||||
|
||||
if( (cst & S_RX_COMPLETE)==0 ) {
|
||||
/* acknowledge everything */
|
||||
outw(ACK_INTR| (cst & S_5_INTS), BASE + EP_COMMAND);
|
||||
outw(C_INTR_LATCH, BASE + EP_COMMAND);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = inw(BASE + EP_W1_RX_STATUS);
|
||||
#ifdef EDEBUG
|
||||
printf("*%hX*",status);
|
||||
#endif
|
||||
|
||||
if (status & ERR_RX) {
|
||||
outw(RX_DISCARD_TOP_PACK, BASE + EP_COMMAND);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rx_fifo = status & RX_BYTES_MASK;
|
||||
if (rx_fifo==0)
|
||||
return 0;
|
||||
|
||||
/* read packet */
|
||||
#ifdef EDEBUG
|
||||
printf("[l=%d",rx_fifo);
|
||||
#endif
|
||||
insw(BASE + EP_W1_RX_PIO_RD_1, nic->packet, rx_fifo / 2);
|
||||
if(rx_fifo & 1)
|
||||
nic->packet[rx_fifo-1]=inb(BASE + EP_W1_RX_PIO_RD_1);
|
||||
nic->packetlen=rx_fifo;
|
||||
|
||||
while(1) {
|
||||
status = inw(BASE + EP_W1_RX_STATUS);
|
||||
#ifdef EDEBUG
|
||||
printf("*%hX*",status);
|
||||
#endif
|
||||
rx_fifo = status & RX_BYTES_MASK;
|
||||
if(rx_fifo>0) {
|
||||
insw(BASE + EP_W1_RX_PIO_RD_1, nic->packet+nic->packetlen, rx_fifo / 2);
|
||||
if(rx_fifo & 1)
|
||||
nic->packet[nic->packetlen+rx_fifo-1]=inb(BASE + EP_W1_RX_PIO_RD_1);
|
||||
nic->packetlen+=rx_fifo;
|
||||
#ifdef EDEBUG
|
||||
printf("+%d",rx_fifo);
|
||||
#endif
|
||||
}
|
||||
if(( status & RX_INCOMPLETE )==0) {
|
||||
#ifdef EDEBUG
|
||||
printf("=%d",nic->packetlen);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
udelay(1000); /* if incomplete wait 1 ms */
|
||||
}
|
||||
/* acknowledge reception of packet */
|
||||
outw(RX_DISCARD_TOP_PACK, BASE + EP_COMMAND);
|
||||
while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)
|
||||
;
|
||||
#ifdef EDEBUG
|
||||
type = (nic->packet[12]<<8) | nic->packet[13];
|
||||
if(nic->packet[0]+nic->packet[1]+nic->packet[2]+nic->packet[3]+nic->packet[4]+
|
||||
nic->packet[5] == 0xFF*ETH_ALEN)
|
||||
printf(",t=%hX,b]",type);
|
||||
else
|
||||
printf(",t=%hX]",type);
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
3Com 509 - specific routines
|
||||
**************************************************************************/
|
||||
|
||||
static int
|
||||
eeprom_rdy(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; is_eeprom_busy(IS_BASE) && i < MAX_EEPROMBUSY; i++);
|
||||
if (i >= MAX_EEPROMBUSY) {
|
||||
/* printf("3c509: eeprom failed to come ready.\n"); */
|
||||
printf("3c509: eeprom busy.\n"); /* memory in EPROM is tight */
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_e: gets a 16 bits word from the EEPROM. we must have set the window
|
||||
* before
|
||||
*/
|
||||
static int
|
||||
get_e(int offset)
|
||||
{
|
||||
if (!eeprom_rdy())
|
||||
return (0xffff);
|
||||
outw(EEPROM_CMD_RD | offset, IS_BASE + EP_W0_EEPROM_COMMAND);
|
||||
if (!eeprom_rdy())
|
||||
return (0xffff);
|
||||
return (inw(IS_BASE + EP_W0_EEPROM_DATA));
|
||||
}
|
||||
|
||||
static int
|
||||
send_ID_sequence(int port)
|
||||
{
|
||||
int cx, al;
|
||||
|
||||
for (al = 0xff, cx = 0; cx < 255; cx++) {
|
||||
outb(al, port);
|
||||
al <<= 1;
|
||||
if (al & 0x100)
|
||||
al ^= 0xcf;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We get eeprom data from the id_port given an offset into the eeprom.
|
||||
* Basically; after the ID_sequence is sent to all of the cards; they enter
|
||||
* the ID_CMD state where they will accept command requests. 0x80-0xbf loads
|
||||
* the eeprom data. We then read the port 16 times and with every read; the
|
||||
* cards check for contention (ie: if one card writes a 0 bit and another
|
||||
* writes a 1 bit then the host sees a 0. At the end of the cycle; each card
|
||||
* compares the data on the bus; if there is a difference then that card goes
|
||||
* into ID_WAIT state again). In the meantime; one bit of data is returned in
|
||||
* the AX register which is conveniently returned to us by inb(). Hence; we
|
||||
* read 16 times getting one bit of data with each read.
|
||||
*/
|
||||
static int
|
||||
get_eeprom_data(int id_port, int offset)
|
||||
{
|
||||
int i, data = 0;
|
||||
outb(0x80 + offset, id_port);
|
||||
/* Do we really need this wait? Won't be noticeable anyway */
|
||||
udelay(10000);
|
||||
for (i = 0; i < 16; i++)
|
||||
data = (data << 1) | (inw(id_port) & 1);
|
||||
return (data);
|
||||
}
|
||||
|
||||
static void t509_disable(struct nic *nic)
|
||||
{
|
||||
outb(0xc0, EP_ID_PORT);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
ETH_PROBE - Look for an adapter
|
||||
***************************************************************************/
|
||||
#ifdef INCLUDE_3C529
|
||||
struct nic *t529_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||
#else
|
||||
struct nic *t509_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||
#endif
|
||||
{
|
||||
/* common variables */
|
||||
int i;
|
||||
int failcount;
|
||||
|
||||
#ifdef INCLUDE_3C529
|
||||
struct el3_mca_adapters_struct *mcafound = NULL;
|
||||
int mca_pos4 = 0, mca_pos5 = 0, mca_irq = 0;
|
||||
#endif
|
||||
|
||||
t509_disable(nic); /* in case board was active */
|
||||
/* note that nic is not used */
|
||||
for (failcount = 0; failcount < 4000; failcount++) {
|
||||
int data, j, io_base, id_port;
|
||||
unsigned short k;
|
||||
int ep_current_tag;
|
||||
short *p;
|
||||
#ifdef INCLUDE_3C529
|
||||
int curboard;
|
||||
#endif
|
||||
|
||||
id_port = EP_ID_PORT;
|
||||
ep_current_tag = EP_LAST_TAG + 1;
|
||||
|
||||
/*********************************************************
|
||||
Search for 3Com 509 card
|
||||
***********************************************************/
|
||||
#ifdef INCLUDE_3C529
|
||||
/*
|
||||
* XXX: We should really check to make sure we have an MCA
|
||||
* bus controller before going ahead with this...
|
||||
*
|
||||
* For now, we avoid any hassle by making it a compile
|
||||
* time option.
|
||||
*
|
||||
*/
|
||||
printf("\nWarning: Assuming presence of MCA bus\n");
|
||||
|
||||
/* Make sure motherboard setup is off */
|
||||
outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);
|
||||
|
||||
/* Cycle through slots */
|
||||
for(curboard=0; curboard<MCA_MAX_SLOT_NR; curboard++) {
|
||||
int boardid;
|
||||
int curcard;
|
||||
|
||||
outb_p(0x8|(curboard&0xf), MCA_ADAPTER_SETUP_REG);
|
||||
|
||||
boardid = inb_p(MCA_POS_REG(0));
|
||||
boardid += inb_p(MCA_POS_REG(1)) << 8;
|
||||
|
||||
curcard = 0;
|
||||
while (el3_mca_adapters[curcard].name) {
|
||||
if (el3_mca_adapters[curcard].id == boardid) {
|
||||
mcafound = &el3_mca_adapters[curcard];
|
||||
|
||||
mca_pos4 = inb_p(MCA_POS_REG(4));
|
||||
mca_pos5 = inb_p(MCA_POS_REG(5));
|
||||
|
||||
goto donewithdetect;
|
||||
}
|
||||
else
|
||||
curcard++;
|
||||
}
|
||||
|
||||
}
|
||||
donewithdetect:
|
||||
/* Kill all setup modes */
|
||||
outb_p(0, MCA_ADAPTER_SETUP_REG);
|
||||
|
||||
if (mcafound) {
|
||||
eth_nic_base = ((short)((mca_pos4&0xfc)|0x02)) << 8;
|
||||
mca_irq = mca_pos5 & 0x0f;
|
||||
ep_current_tag--;
|
||||
}
|
||||
else
|
||||
printf("MCA Card not found\n");
|
||||
#endif
|
||||
/* Look for the EISA boards, leave them activated */
|
||||
/* search for the first card, ignore all others */
|
||||
for(j = 1; j < 16; j++) {
|
||||
io_base = (j * EP_EISA_START) | EP_EISA_W0;
|
||||
if (inw(io_base + EP_W0_MFG_ID) != MFG_ID)
|
||||
continue;
|
||||
|
||||
/* we must have found 0x1f if the board is EISA configurated */
|
||||
if ((inw(io_base + EP_W0_ADDRESS_CFG) & 0x1f) != 0x1f)
|
||||
continue;
|
||||
|
||||
/* Reset and Enable the card */
|
||||
outb(W0_P4_CMD_RESET_ADAPTER, io_base + EP_W0_CONFIG_CTRL);
|
||||
udelay(1000); /* Must wait 800 µs, be conservative */
|
||||
outb(W0_P4_CMD_ENABLE_ADAPTER, io_base + EP_W0_CONFIG_CTRL);
|
||||
|
||||
/*
|
||||
* Once activated, all the registers are mapped in the range
|
||||
* x000 - x00F, where x is the slot number.
|
||||
*/
|
||||
eth_nic_base = j * EP_EISA_START;
|
||||
break;
|
||||
}
|
||||
ep_current_tag--;
|
||||
|
||||
/* Look for the ISA boards. Init and leave them actived */
|
||||
/* search for the first card, ignore all others */
|
||||
outb(0xc0, id_port); /* Global reset */
|
||||
udelay(1000); /* wait 1 ms */
|
||||
for (i = 0; i < EP_MAX_BOARDS; i++) {
|
||||
outb(0, id_port);
|
||||
outb(0, id_port);
|
||||
send_ID_sequence(id_port);
|
||||
|
||||
data = get_eeprom_data(id_port, EEPROM_MFG_ID);
|
||||
if (data != MFG_ID)
|
||||
break;
|
||||
|
||||
/* resolve contention using the Ethernet address */
|
||||
for (j = 0; j < 3; j++)
|
||||
data = get_eeprom_data(id_port, j);
|
||||
|
||||
eth_nic_base =
|
||||
(get_eeprom_data(id_port, EEPROM_ADDR_CFG) & 0x1f) * 0x10 + 0x200;
|
||||
outb(ep_current_tag, id_port); /* tags board */
|
||||
outb(ACTIVATE_ADAPTER_TO_CONFIG, id_port);
|
||||
ep_current_tag--;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= EP_MAX_BOARDS)
|
||||
goto no3c509;
|
||||
|
||||
/*
|
||||
* The iobase was found and MFG_ID was 0x6d50. PROD_ID should be
|
||||
* 0x9[0-f]50
|
||||
*/
|
||||
GO_WINDOW(0);
|
||||
k = get_e(EEPROM_PROD_ID);
|
||||
#ifdef INCLUDE_3C529
|
||||
/*
|
||||
* On MCA, the PROD_ID matches the MCA card ID (POS0+POS1)
|
||||
*/
|
||||
if (mcafound) {
|
||||
if (mcafound->id != k) {
|
||||
printf("MCA: PROD_ID in EEPROM does not match MCA card ID! (%hX != %hX)\n", k, mcafound->id);
|
||||
goto no3c509;
|
||||
}
|
||||
} else { /* for ISA/EISA */
|
||||
if ((k & 0xf0ff) != (PROD_ID & 0xf0ff))
|
||||
goto no3c509;
|
||||
}
|
||||
#else
|
||||
if ((k & 0xf0ff) != (PROD_ID & 0xf0ff))
|
||||
goto no3c509;
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_3C529
|
||||
if (mcafound) {
|
||||
printf("%s board found on MCA at %#hx IRQ %d -",
|
||||
mcafound->name, eth_nic_base, mca_irq);
|
||||
} else {
|
||||
#endif
|
||||
if(eth_nic_base >= EP_EISA_START)
|
||||
printf("3C5x9 board on EISA at %#hx - ",eth_nic_base);
|
||||
else
|
||||
printf("3C5x9 board on ISA at %#hx - ",eth_nic_base);
|
||||
#ifdef INCLUDE_3C529
|
||||
}
|
||||
#endif
|
||||
|
||||
/* test for presence of connectors */
|
||||
i = inw(IS_BASE + EP_W0_CONFIG_CTRL);
|
||||
j = (inw(IS_BASE + EP_W0_ADDRESS_CFG) >> 14) & 0x3;
|
||||
|
||||
switch(j) {
|
||||
case 0:
|
||||
if (i & IS_UTP) {
|
||||
printf("10baseT\n");
|
||||
connector = utp;
|
||||
}
|
||||
else {
|
||||
printf("10baseT not present\n");
|
||||
goto no3c509;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (i & IS_AUI)
|
||||
printf("10base5\n");
|
||||
else {
|
||||
printf("10base5 not present\n");
|
||||
goto no3c509;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (i & IS_BNC) {
|
||||
printf("10base2\n");
|
||||
connector = bnc;
|
||||
}
|
||||
else {
|
||||
printf("10base2 not present\n");
|
||||
goto no3c509;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("unknown connector\n");
|
||||
goto no3c509;
|
||||
}
|
||||
/*
|
||||
* Read the station address from the eeprom
|
||||
*/
|
||||
p = (unsigned short *) nic->node_addr;
|
||||
for (i = 0; i < ETH_ALEN / 2; i++) {
|
||||
GO_WINDOW(0);
|
||||
p[i] = htons(get_e(i));
|
||||
GO_WINDOW(2);
|
||||
outw(ntohs(p[i]), BASE + EP_W2_ADDR_0 + (i * 2));
|
||||
}
|
||||
printf("Ethernet address: %!\n", nic->node_addr);
|
||||
t509_reset(nic);
|
||||
nic->reset = t509_reset;
|
||||
nic->poll = t509_poll;
|
||||
nic->transmit = t509_transmit;
|
||||
nic->disable = t509_disable;
|
||||
return nic;
|
||||
no3c509:
|
||||
printf("(probe fail)");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
||||
-397
@@ -1,397 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1993 Herb Peyerl (hpeyerl@novatel.ca) All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2. The name
|
||||
* of the author may not be used to endorse or promote products derived from
|
||||
* this software withough specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* if_epreg.h,v 1.4 1994/11/13 10:12:37 gibbs Exp Modified by:
|
||||
*
|
||||
October 2, 1994
|
||||
|
||||
Modified by: Andres Vega Garcia
|
||||
|
||||
INRIA - Sophia Antipolis, France
|
||||
e-mail: avega@sophia.inria.fr
|
||||
finger: avega@pax.inria.fr
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* Ethernet software status per interface.
|
||||
*/
|
||||
/*
|
||||
* Some global constants
|
||||
*/
|
||||
|
||||
#define TX_INIT_RATE 16
|
||||
#define TX_INIT_MAX_RATE 64
|
||||
#define RX_INIT_LATENCY 64
|
||||
#define RX_INIT_EARLY_THRESH 64
|
||||
#define MIN_RX_EARLY_THRESHF 16 /* not less than ether_header */
|
||||
#define MIN_RX_EARLY_THRESHL 4
|
||||
|
||||
#define EEPROMSIZE 0x40
|
||||
#define MAX_EEPROMBUSY 1000
|
||||
#define EP_LAST_TAG 0xd7
|
||||
#define EP_MAX_BOARDS 16
|
||||
#define EP_ID_PORT 0x100
|
||||
|
||||
/*
|
||||
* some macros to acces long named fields
|
||||
*/
|
||||
#define IS_BASE (eth_nic_base)
|
||||
#define BASE (eth_nic_base)
|
||||
|
||||
/*
|
||||
* Commands to read/write EEPROM trough EEPROM command register (Window 0,
|
||||
* Offset 0xa)
|
||||
*/
|
||||
#define EEPROM_CMD_RD 0x0080 /* Read: Address required (5 bits) */
|
||||
#define EEPROM_CMD_WR 0x0040 /* Write: Address required (5 bits) */
|
||||
#define EEPROM_CMD_ERASE 0x00c0 /* Erase: Address required (5 bits) */
|
||||
#define EEPROM_CMD_EWEN 0x0030 /* Erase/Write Enable: No data required */
|
||||
|
||||
#define EEPROM_BUSY (1<<15)
|
||||
#define EEPROM_TST_MODE (1<<14)
|
||||
|
||||
/*
|
||||
* Some short functions, worth to let them be a macro
|
||||
*/
|
||||
#define is_eeprom_busy(b) (inw((b)+EP_W0_EEPROM_COMMAND)&EEPROM_BUSY)
|
||||
#define GO_WINDOW(x) outw(WINDOW_SELECT|(x), BASE+EP_COMMAND)
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* These define the EEPROM data structure. They are used in the probe
|
||||
* function to verify the existance of the adapter after having sent
|
||||
* the ID_Sequence.
|
||||
*
|
||||
* There are others but only the ones we use are defined here.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#define EEPROM_NODE_ADDR_0 0x0 /* Word */
|
||||
#define EEPROM_NODE_ADDR_1 0x1 /* Word */
|
||||
#define EEPROM_NODE_ADDR_2 0x2 /* Word */
|
||||
#define EEPROM_PROD_ID 0x3 /* 0x9[0-f]50 */
|
||||
#define EEPROM_MFG_ID 0x7 /* 0x6d50 */
|
||||
#define EEPROM_ADDR_CFG 0x8 /* Base addr */
|
||||
#define EEPROM_RESOURCE_CFG 0x9 /* IRQ. Bits 12-15 */
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* These are the registers for the 3Com 3c509 and their bit patterns when
|
||||
* applicable. They have been taken out the the "EtherLink III Parallel
|
||||
* Tasking EISA and ISA Technical Reference" "Beta Draft 10/30/92" manual
|
||||
* from 3com.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#define EP_COMMAND 0x0e /* Write. BASE+0x0e is always a
|
||||
* command reg. */
|
||||
#define EP_STATUS 0x0e /* Read. BASE+0x0e is always status
|
||||
* reg. */
|
||||
#define EP_WINDOW 0x0f /* Read. BASE+0x0f is always window
|
||||
* reg. */
|
||||
/*
|
||||
* Window 0 registers. Setup.
|
||||
*/
|
||||
/* Write */
|
||||
#define EP_W0_EEPROM_DATA 0x0c
|
||||
#define EP_W0_EEPROM_COMMAND 0x0a
|
||||
#define EP_W0_RESOURCE_CFG 0x08
|
||||
#define EP_W0_ADDRESS_CFG 0x06
|
||||
#define EP_W0_CONFIG_CTRL 0x04
|
||||
/* Read */
|
||||
#define EP_W0_PRODUCT_ID 0x02
|
||||
#define EP_W0_MFG_ID 0x00
|
||||
|
||||
/*
|
||||
* Window 1 registers. Operating Set.
|
||||
*/
|
||||
/* Write */
|
||||
#define EP_W1_TX_PIO_WR_2 0x02
|
||||
#define EP_W1_TX_PIO_WR_1 0x00
|
||||
/* Read */
|
||||
#define EP_W1_FREE_TX 0x0c
|
||||
#define EP_W1_TX_STATUS 0x0b /* byte */
|
||||
#define EP_W1_TIMER 0x0a /* byte */
|
||||
#define EP_W1_RX_STATUS 0x08
|
||||
#define EP_W1_RX_PIO_RD_2 0x02
|
||||
#define EP_W1_RX_PIO_RD_1 0x00
|
||||
|
||||
/*
|
||||
* Window 2 registers. Station Address Setup/Read
|
||||
*/
|
||||
/* Read/Write */
|
||||
#define EP_W2_ADDR_5 0x05
|
||||
#define EP_W2_ADDR_4 0x04
|
||||
#define EP_W2_ADDR_3 0x03
|
||||
#define EP_W2_ADDR_2 0x02
|
||||
#define EP_W2_ADDR_1 0x01
|
||||
#define EP_W2_ADDR_0 0x00
|
||||
|
||||
/*
|
||||
* Window 3 registers. FIFO Management.
|
||||
*/
|
||||
/* Read */
|
||||
#define EP_W3_FREE_TX 0x0c
|
||||
#define EP_W3_FREE_RX 0x0a
|
||||
|
||||
/*
|
||||
* Window 4 registers. Diagnostics.
|
||||
*/
|
||||
/* Read/Write */
|
||||
#define EP_W4_MEDIA_TYPE 0x0a
|
||||
#define EP_W4_CTRLR_STATUS 0x08
|
||||
#define EP_W4_NET_DIAG 0x06
|
||||
#define EP_W4_FIFO_DIAG 0x04
|
||||
#define EP_W4_HOST_DIAG 0x02
|
||||
#define EP_W4_TX_DIAG 0x00
|
||||
|
||||
/*
|
||||
* Window 5 Registers. Results and Internal status.
|
||||
*/
|
||||
/* Read */
|
||||
#define EP_W5_READ_0_MASK 0x0c
|
||||
#define EP_W5_INTR_MASK 0x0a
|
||||
#define EP_W5_RX_FILTER 0x08
|
||||
#define EP_W5_RX_EARLY_THRESH 0x06
|
||||
#define EP_W5_TX_AVAIL_THRESH 0x02
|
||||
#define EP_W5_TX_START_THRESH 0x00
|
||||
|
||||
/*
|
||||
* Window 6 registers. Statistics.
|
||||
*/
|
||||
/* Read/Write */
|
||||
#define TX_TOTAL_OK 0x0c
|
||||
#define RX_TOTAL_OK 0x0a
|
||||
#define TX_DEFERRALS 0x08
|
||||
#define RX_FRAMES_OK 0x07
|
||||
#define TX_FRAMES_OK 0x06
|
||||
#define RX_OVERRUNS 0x05
|
||||
#define TX_COLLISIONS 0x04
|
||||
#define TX_AFTER_1_COLLISION 0x03
|
||||
#define TX_AFTER_X_COLLISIONS 0x02
|
||||
#define TX_NO_SQE 0x01
|
||||
#define TX_CD_LOST 0x00
|
||||
|
||||
/****************************************
|
||||
*
|
||||
* Register definitions.
|
||||
*
|
||||
****************************************/
|
||||
|
||||
/*
|
||||
* Command register. All windows.
|
||||
*
|
||||
* 16 bit register.
|
||||
* 15-11: 5-bit code for command to be executed.
|
||||
* 10-0: 11-bit arg if any. For commands with no args;
|
||||
* this can be set to anything.
|
||||
*/
|
||||
#define GLOBAL_RESET (unsigned short) 0x0000 /* Wait at least 1ms
|
||||
* after issuing */
|
||||
#define WINDOW_SELECT (unsigned short) (0x1<<11)
|
||||
#define START_TRANSCEIVER (unsigned short) (0x2<<11) /* Read ADDR_CFG reg to
|
||||
* determine whether
|
||||
* this is needed. If
|
||||
* so; wait 800 uSec
|
||||
* before using trans-
|
||||
* ceiver. */
|
||||
#define RX_DISABLE (unsigned short) (0x3<<11) /* state disabled on
|
||||
* power-up */
|
||||
#define RX_ENABLE (unsigned short) (0x4<<11)
|
||||
#define RX_RESET (unsigned short) (0x5<<11)
|
||||
#define RX_DISCARD_TOP_PACK (unsigned short) (0x8<<11)
|
||||
#define TX_ENABLE (unsigned short) (0x9<<11)
|
||||
#define TX_DISABLE (unsigned short) (0xa<<11)
|
||||
#define TX_RESET (unsigned short) (0xb<<11)
|
||||
#define REQ_INTR (unsigned short) (0xc<<11)
|
||||
#define SET_INTR_MASK (unsigned short) (0xe<<11)
|
||||
#define SET_RD_0_MASK (unsigned short) (0xf<<11)
|
||||
#define SET_RX_FILTER (unsigned short) (0x10<<11)
|
||||
#define FIL_INDIVIDUAL (unsigned short) (0x1)
|
||||
#define FIL_GROUP (unsigned short) (0x2)
|
||||
#define FIL_BRDCST (unsigned short) (0x4)
|
||||
#define FIL_ALL (unsigned short) (0x8)
|
||||
#define SET_RX_EARLY_THRESH (unsigned short) (0x11<<11)
|
||||
#define SET_TX_AVAIL_THRESH (unsigned short) (0x12<<11)
|
||||
#define SET_TX_START_THRESH (unsigned short) (0x13<<11)
|
||||
#define STATS_ENABLE (unsigned short) (0x15<<11)
|
||||
#define STATS_DISABLE (unsigned short) (0x16<<11)
|
||||
#define STOP_TRANSCEIVER (unsigned short) (0x17<<11)
|
||||
/*
|
||||
* The following C_* acknowledge the various interrupts. Some of them don't
|
||||
* do anything. See the manual.
|
||||
*/
|
||||
#define ACK_INTR (unsigned short) (0x6800)
|
||||
#define C_INTR_LATCH (unsigned short) (ACK_INTR|0x1)
|
||||
#define C_CARD_FAILURE (unsigned short) (ACK_INTR|0x2)
|
||||
#define C_TX_COMPLETE (unsigned short) (ACK_INTR|0x4)
|
||||
#define C_TX_AVAIL (unsigned short) (ACK_INTR|0x8)
|
||||
#define C_RX_COMPLETE (unsigned short) (ACK_INTR|0x10)
|
||||
#define C_RX_EARLY (unsigned short) (ACK_INTR|0x20)
|
||||
#define C_INT_RQD (unsigned short) (ACK_INTR|0x40)
|
||||
#define C_UPD_STATS (unsigned short) (ACK_INTR|0x80)
|
||||
|
||||
/*
|
||||
* Status register. All windows.
|
||||
*
|
||||
* 15-13: Window number(0-7).
|
||||
* 12: Command_in_progress.
|
||||
* 11: reserved.
|
||||
* 10: reserved.
|
||||
* 9: reserved.
|
||||
* 8: reserved.
|
||||
* 7: Update Statistics.
|
||||
* 6: Interrupt Requested.
|
||||
* 5: RX Early.
|
||||
* 4: RX Complete.
|
||||
* 3: TX Available.
|
||||
* 2: TX Complete.
|
||||
* 1: Adapter Failure.
|
||||
* 0: Interrupt Latch.
|
||||
*/
|
||||
#define S_INTR_LATCH (unsigned short) (0x1)
|
||||
#define S_CARD_FAILURE (unsigned short) (0x2)
|
||||
#define S_TX_COMPLETE (unsigned short) (0x4)
|
||||
#define S_TX_AVAIL (unsigned short) (0x8)
|
||||
#define S_RX_COMPLETE (unsigned short) (0x10)
|
||||
#define S_RX_EARLY (unsigned short) (0x20)
|
||||
#define S_INT_RQD (unsigned short) (0x40)
|
||||
#define S_UPD_STATS (unsigned short) (0x80)
|
||||
#define S_5_INTS (S_CARD_FAILURE|S_TX_COMPLETE|\
|
||||
S_TX_AVAIL|S_RX_COMPLETE|S_RX_EARLY)
|
||||
#define S_COMMAND_IN_PROGRESS (unsigned short) (0x1000)
|
||||
|
||||
/*
|
||||
* FIFO Registers.
|
||||
* RX Status. Window 1/Port 08
|
||||
*
|
||||
* 15: Incomplete or FIFO empty.
|
||||
* 14: 1: Error in RX Packet 0: Incomplete or no error.
|
||||
* 13-11: Type of error.
|
||||
* 1000 = Overrun.
|
||||
* 1011 = Run Packet Error.
|
||||
* 1100 = Alignment Error.
|
||||
* 1101 = CRC Error.
|
||||
* 1001 = Oversize Packet Error (>1514 bytes)
|
||||
* 0010 = Dribble Bits.
|
||||
* (all other error codes, no errors.)
|
||||
*
|
||||
* 10-0: RX Bytes (0-1514)
|
||||
*/
|
||||
#define ERR_RX_INCOMPLETE (unsigned short) (0x1<<15)
|
||||
#define ERR_RX (unsigned short) (0x1<<14)
|
||||
#define ERR_RX_OVERRUN (unsigned short) (0x8<<11)
|
||||
#define ERR_RX_RUN_PKT (unsigned short) (0xb<<11)
|
||||
#define ERR_RX_ALIGN (unsigned short) (0xc<<11)
|
||||
#define ERR_RX_CRC (unsigned short) (0xd<<11)
|
||||
#define ERR_RX_OVERSIZE (unsigned short) (0x9<<11)
|
||||
#define ERR_RX_DRIBBLE (unsigned short) (0x2<<11)
|
||||
|
||||
/*
|
||||
* FIFO Registers.
|
||||
* TX Status. Window 1/Port 0B
|
||||
*
|
||||
* Reports the transmit status of a completed transmission. Writing this
|
||||
* register pops the transmit completion stack.
|
||||
*
|
||||
* Window 1/Port 0x0b.
|
||||
*
|
||||
* 7: Complete
|
||||
* 6: Interrupt on successful transmission requested.
|
||||
* 5: Jabber Error (TP Only, TX Reset required. )
|
||||
* 4: Underrun (TX Reset required. )
|
||||
* 3: Maximum Collisions.
|
||||
* 2: TX Status Overflow.
|
||||
* 1-0: Undefined.
|
||||
*
|
||||
*/
|
||||
#define TXS_COMPLETE 0x80
|
||||
#define TXS_SUCCES_INTR_REQ 0x40
|
||||
#define TXS_JABBER 0x20
|
||||
#define TXS_UNDERRUN 0x10
|
||||
#define TXS_MAX_COLLISION 0x8
|
||||
#define TXS_STATUS_OVERFLOW 0x4
|
||||
|
||||
/*
|
||||
* Configuration control register.
|
||||
* Window 0/Port 04
|
||||
*/
|
||||
/* Read */
|
||||
#define IS_AUI (1<<13)
|
||||
#define IS_BNC (1<<12)
|
||||
#define IS_UTP (1<<9)
|
||||
/* Write */
|
||||
#define ENABLE_DRQ_IRQ 0x0001
|
||||
#define W0_P4_CMD_RESET_ADAPTER 0x4
|
||||
#define W0_P4_CMD_ENABLE_ADAPTER 0x1
|
||||
/*
|
||||
* Media type and status.
|
||||
* Window 4/Port 0A
|
||||
*/
|
||||
#define ENABLE_UTP 0xc0
|
||||
#define DISABLE_UTP 0x0
|
||||
|
||||
/*
|
||||
* Resource control register
|
||||
*/
|
||||
|
||||
#define SET_IRQ(i) ( ((i)<<12) | 0xF00) /* set IRQ i */
|
||||
|
||||
/*
|
||||
* Receive status register
|
||||
*/
|
||||
|
||||
#define RX_BYTES_MASK (unsigned short) (0x07ff)
|
||||
#define RX_ERROR 0x4000
|
||||
#define RX_INCOMPLETE 0x8000
|
||||
|
||||
|
||||
/*
|
||||
* Misc defines for various things.
|
||||
*/
|
||||
#define ACTIVATE_ADAPTER_TO_CONFIG 0xff /* to the id_port */
|
||||
#define MFG_ID 0x6d50 /* in EEPROM and W0 ADDR_CONFIG */
|
||||
#define PROD_ID 0x9150
|
||||
|
||||
#define AUI 0x1
|
||||
#define BNC 0x2
|
||||
#define UTP 0x4
|
||||
|
||||
#define RX_BYTES_MASK (unsigned short) (0x07ff)
|
||||
|
||||
/* EISA support */
|
||||
#define EP_EISA_START 0x1000
|
||||
#define EP_EISA_W0 0x0c80
|
||||
|
||||
#ifdef INCLUDE_3C529
|
||||
/* MCA support */
|
||||
#define MCA_MOTHERBOARD_SETUP_REG 0x94
|
||||
#define MCA_ADAPTER_SETUP_REG 0x96
|
||||
#define MCA_MAX_SLOT_NR 8
|
||||
#define MCA_POS_REG(n) (0x100+(n))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
||||
-503
@@ -1,503 +0,0 @@
|
||||
/*
|
||||
* 3c595.c -- 3COM 3C595 Fast Etherlink III PCI driver for etherboot
|
||||
*
|
||||
* Copyright (C) 2000 Shusuke Nisiyama <shu@athena.qe.eng.hokudai.ac.jp>
|
||||
* All rights reserved.
|
||||
* Mar. 14, 2000
|
||||
*
|
||||
* This software may be used, modified, copied, distributed, and sold, in
|
||||
* both source and binary form provided that the above copyright and these
|
||||
* terms are retained. Under no circumstances are the authors responsible for
|
||||
* the proper functioning of this software, nor do the authors assume any
|
||||
* responsibility for damages incurred with its use.
|
||||
*
|
||||
* This code is based on Martin Renters' etherboot-4.4.3 3c509.c and
|
||||
* Herb Peyerl's FreeBSD 3.4-RELEASE if_vx.c driver.
|
||||
*
|
||||
* Copyright (C) 1993-1994, David Greenman, Martin Renters.
|
||||
* Copyright (C) 1993-1995, Andres Vega Garcia.
|
||||
* Copyright (C) 1995, Serge Babkin.
|
||||
*
|
||||
* Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca>
|
||||
*
|
||||
*/
|
||||
|
||||
/* #define EDEBUG */
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "pci.h"
|
||||
#include "3c595.h"
|
||||
#include "timer.h"
|
||||
|
||||
static unsigned short eth_nic_base, eth_asic_base;
|
||||
static unsigned short vx_connector, vx_connectors;
|
||||
|
||||
static struct connector_entry {
|
||||
int bit;
|
||||
char *name;
|
||||
} conn_tab[VX_CONNECTORS] = {
|
||||
#define CONNECTOR_UTP 0
|
||||
{ 0x08, "utp"},
|
||||
#define CONNECTOR_AUI 1
|
||||
{ 0x20, "aui"},
|
||||
/* dummy */
|
||||
{ 0, "???"},
|
||||
#define CONNECTOR_BNC 3
|
||||
{ 0x10, "bnc"},
|
||||
#define CONNECTOR_TX 4
|
||||
{ 0x02, "tx"},
|
||||
#define CONNECTOR_FX 5
|
||||
{ 0x04, "fx"},
|
||||
#define CONNECTOR_MII 6
|
||||
{ 0x40, "mii"},
|
||||
{ 0, "???"}
|
||||
};
|
||||
|
||||
static void vxgetlink(void);
|
||||
static void vxsetlink(void);
|
||||
|
||||
#define udelay(n) waiton_timer2(((n)*TICKS_PER_MS)/1000)
|
||||
|
||||
/**************************************************************************
|
||||
ETH_RESET - Reset adapter
|
||||
***************************************************************************/
|
||||
static void t595_reset(struct nic *nic)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
/***********************************************************
|
||||
Reset 3Com 595 card
|
||||
*************************************************************/
|
||||
|
||||
/* stop card */
|
||||
outw(RX_DISABLE, BASE + VX_COMMAND);
|
||||
outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
|
||||
VX_BUSY_WAIT;
|
||||
outw(TX_DISABLE, BASE + VX_COMMAND);
|
||||
outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
|
||||
udelay(8000);
|
||||
outw(RX_RESET, BASE + VX_COMMAND);
|
||||
VX_BUSY_WAIT;
|
||||
outw(TX_RESET, BASE + VX_COMMAND);
|
||||
VX_BUSY_WAIT;
|
||||
outw(C_INTR_LATCH, BASE + VX_COMMAND);
|
||||
outw(SET_RD_0_MASK, BASE + VX_COMMAND);
|
||||
outw(SET_INTR_MASK, BASE + VX_COMMAND);
|
||||
outw(SET_RX_FILTER, BASE + VX_COMMAND);
|
||||
|
||||
/*
|
||||
* initialize card
|
||||
*/
|
||||
VX_BUSY_WAIT;
|
||||
|
||||
GO_WINDOW(0);
|
||||
|
||||
/* Disable the card */
|
||||
/* outw(0, BASE + VX_W0_CONFIG_CTRL); */
|
||||
|
||||
/* Configure IRQ to none */
|
||||
/* outw(SET_IRQ(0), BASE + VX_W0_RESOURCE_CFG); */
|
||||
|
||||
/* Enable the card */
|
||||
/* outw(ENABLE_DRQ_IRQ, BASE + VX_W0_CONFIG_CTRL); */
|
||||
|
||||
GO_WINDOW(2);
|
||||
|
||||
/* Reload the ether_addr. */
|
||||
for (i = 0; i < ETH_ALEN; i++)
|
||||
outb(nic->node_addr[i], BASE + VX_W2_ADDR_0 + i);
|
||||
|
||||
outw(RX_RESET, BASE + VX_COMMAND);
|
||||
VX_BUSY_WAIT;
|
||||
outw(TX_RESET, BASE + VX_COMMAND);
|
||||
VX_BUSY_WAIT;
|
||||
|
||||
/* Window 1 is operating window */
|
||||
GO_WINDOW(1);
|
||||
for (i = 0; i < 31; i++)
|
||||
inb(BASE + VX_W1_TX_STATUS);
|
||||
|
||||
outw(SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
|
||||
S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
|
||||
outw(SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
|
||||
S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
|
||||
|
||||
/*
|
||||
* Attempt to get rid of any stray interrupts that occured during
|
||||
* configuration. On the i386 this isn't possible because one may
|
||||
* already be queued. However, a single stray interrupt is
|
||||
* unimportant.
|
||||
*/
|
||||
|
||||
outw(ACK_INTR | 0xff, BASE + VX_COMMAND);
|
||||
|
||||
outw(SET_RX_FILTER | FIL_INDIVIDUAL |
|
||||
FIL_BRDCST, BASE + VX_COMMAND);
|
||||
|
||||
vxsetlink();
|
||||
/*{
|
||||
int i,j;
|
||||
i = CONNECTOR_TX;
|
||||
GO_WINDOW(3);
|
||||
j = inl(BASE + VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK;
|
||||
outl(BASE + VX_W3_INTERNAL_CFG, j | (i <<INTERNAL_CONNECTOR_BITS));
|
||||
GO_WINDOW(4);
|
||||
outw(LINKBEAT_ENABLE, BASE + VX_W4_MEDIA_TYPE);
|
||||
GO_WINDOW(1);
|
||||
}*/
|
||||
|
||||
/* start tranciever and receiver */
|
||||
outw(RX_ENABLE, BASE + VX_COMMAND);
|
||||
outw(TX_ENABLE, BASE + VX_COMMAND);
|
||||
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
ETH_TRANSMIT - Transmit a frame
|
||||
***************************************************************************/
|
||||
static char padmap[] = {
|
||||
0, 3, 2, 1};
|
||||
|
||||
static void t595_transmit(
|
||||
struct nic *nic,
|
||||
const char *d, /* Destination */
|
||||
unsigned int t, /* Type */
|
||||
unsigned int s, /* size */
|
||||
const char *p) /* Packet */
|
||||
{
|
||||
register int len;
|
||||
int pad;
|
||||
int status;
|
||||
|
||||
#ifdef EDEBUG
|
||||
printf("{l=%d,t=%hX}",s+ETH_HLEN,t);
|
||||
#endif
|
||||
|
||||
/* swap bytes of type */
|
||||
t= htons(t);
|
||||
|
||||
len=s+ETH_HLEN; /* actual length of packet */
|
||||
pad = padmap[len & 3];
|
||||
|
||||
/*
|
||||
* The 3c595 automatically pads short packets to minimum ethernet length,
|
||||
* but we drop packets that are too large. Perhaps we should truncate
|
||||
* them instead?
|
||||
*/
|
||||
if (len + pad > ETH_FRAME_LEN) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* drop acknowledgements */
|
||||
while(( status=inb(BASE + VX_W1_TX_STATUS) )& TXS_COMPLETE ) {
|
||||
if(status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) {
|
||||
outw(TX_RESET, BASE + VX_COMMAND);
|
||||
outw(TX_ENABLE, BASE + VX_COMMAND);
|
||||
}
|
||||
|
||||
outb(0x0, BASE + VX_W1_TX_STATUS);
|
||||
}
|
||||
|
||||
while (inw(BASE + VX_W1_FREE_TX) < len + pad + 4) {
|
||||
/* no room in FIFO */
|
||||
}
|
||||
|
||||
outw(len, BASE + VX_W1_TX_PIO_WR_1);
|
||||
outw(0x0, BASE + VX_W1_TX_PIO_WR_1); /* Second dword meaningless */
|
||||
|
||||
/* write packet */
|
||||
outsw(BASE + VX_W1_TX_PIO_WR_1, d, ETH_ALEN/2);
|
||||
outsw(BASE + VX_W1_TX_PIO_WR_1, nic->node_addr, ETH_ALEN/2);
|
||||
outw(t, BASE + VX_W1_TX_PIO_WR_1);
|
||||
outsw(BASE + VX_W1_TX_PIO_WR_1, p, s / 2);
|
||||
if (s & 1)
|
||||
outb(*(p+s - 1), BASE + VX_W1_TX_PIO_WR_1);
|
||||
|
||||
while (pad--)
|
||||
outb(0, BASE + VX_W1_TX_PIO_WR_1); /* Padding */
|
||||
|
||||
/* wait for Tx complete */
|
||||
while((inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS) != 0)
|
||||
;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
ETH_POLL - Wait for a frame
|
||||
***************************************************************************/
|
||||
static int t595_poll(struct nic *nic)
|
||||
{
|
||||
/* common variables */
|
||||
unsigned short type = 0; /* used by EDEBUG */
|
||||
/* variables for 3C595 */
|
||||
short status, cst;
|
||||
register short rx_fifo;
|
||||
|
||||
cst=inw(BASE + VX_STATUS);
|
||||
|
||||
#ifdef EDEBUG
|
||||
if(cst & 0x1FFF)
|
||||
printf("-%hX-",cst);
|
||||
#endif
|
||||
|
||||
if( (cst & S_RX_COMPLETE)==0 ) {
|
||||
/* acknowledge everything */
|
||||
outw(ACK_INTR | cst, BASE + VX_COMMAND);
|
||||
outw(C_INTR_LATCH, BASE + VX_COMMAND);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = inw(BASE + VX_W1_RX_STATUS);
|
||||
#ifdef EDEBUG
|
||||
printf("*%hX*",status);
|
||||
#endif
|
||||
|
||||
if (status & ERR_RX) {
|
||||
outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rx_fifo = status & RX_BYTES_MASK;
|
||||
if (rx_fifo==0)
|
||||
return 0;
|
||||
|
||||
/* read packet */
|
||||
#ifdef EDEBUG
|
||||
printf("[l=%d",rx_fifo);
|
||||
#endif
|
||||
insw(BASE + VX_W1_RX_PIO_RD_1, nic->packet, rx_fifo / 2);
|
||||
if(rx_fifo & 1)
|
||||
nic->packet[rx_fifo-1]=inb(BASE + VX_W1_RX_PIO_RD_1);
|
||||
nic->packetlen=rx_fifo;
|
||||
|
||||
while(1) {
|
||||
status = inw(BASE + VX_W1_RX_STATUS);
|
||||
#ifdef EDEBUG
|
||||
printf("*%hX*",status);
|
||||
#endif
|
||||
rx_fifo = status & RX_BYTES_MASK;
|
||||
|
||||
if(rx_fifo>0) {
|
||||
insw(BASE + VX_W1_RX_PIO_RD_1, nic->packet+nic->packetlen, rx_fifo / 2);
|
||||
if(rx_fifo & 1)
|
||||
nic->packet[nic->packetlen+rx_fifo-1]=inb(BASE + VX_W1_RX_PIO_RD_1);
|
||||
nic->packetlen+=rx_fifo;
|
||||
#ifdef EDEBUG
|
||||
printf("+%d",rx_fifo);
|
||||
#endif
|
||||
}
|
||||
if(( status & RX_INCOMPLETE )==0) {
|
||||
#ifdef EDEBUG
|
||||
printf("=%d",nic->packetlen);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
udelay(1000);
|
||||
}
|
||||
|
||||
/* acknowledge reception of packet */
|
||||
outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
|
||||
while (inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS);
|
||||
#ifdef EDEBUG
|
||||
type = (nic->packet[12]<<8) | nic->packet[13];
|
||||
if(nic->packet[0]+nic->packet[1]+nic->packet[2]+nic->packet[3]+nic->packet[4]+
|
||||
nic->packet[5] == 0xFF*ETH_ALEN)
|
||||
printf(",t=%hX,b]",type);
|
||||
else
|
||||
printf(",t=%hX]",type);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
3Com 595 - specific routines
|
||||
**************************************************************************/
|
||||
|
||||
static int
|
||||
eeprom_rdy()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; is_eeprom_busy(BASE) && i < MAX_EEPROMBUSY; i++)
|
||||
udelay(1000);
|
||||
if (i >= MAX_EEPROMBUSY) {
|
||||
/* printf("3c595: eeprom failed to come ready.\n"); */
|
||||
printf("3c595: eeprom is busy.\n"); /* memory in EPROM is tight */
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_e: gets a 16 bits word from the EEPROM. we must have set the window
|
||||
* before
|
||||
*/
|
||||
static int
|
||||
get_e(offset)
|
||||
int offset;
|
||||
{
|
||||
if (!eeprom_rdy())
|
||||
return (0xffff);
|
||||
outw(EEPROM_CMD_RD | offset, BASE + VX_W0_EEPROM_COMMAND);
|
||||
if (!eeprom_rdy())
|
||||
return (0xffff);
|
||||
return (inw(BASE + VX_W0_EEPROM_DATA));
|
||||
}
|
||||
|
||||
static void
|
||||
vxgetlink(void)
|
||||
{
|
||||
int n, k;
|
||||
|
||||
GO_WINDOW(3);
|
||||
vx_connectors = inw(BASE + VX_W3_RESET_OPT) & 0x7f;
|
||||
for (n = 0, k = 0; k < VX_CONNECTORS; k++) {
|
||||
if (vx_connectors & conn_tab[k].bit) {
|
||||
if (n > 0) {
|
||||
printf("/");
|
||||
}
|
||||
printf(conn_tab[k].name);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
if (vx_connectors == 0) {
|
||||
printf("no connectors!");
|
||||
return;
|
||||
}
|
||||
GO_WINDOW(3);
|
||||
vx_connector = (inl(BASE + VX_W3_INTERNAL_CFG)
|
||||
& INTERNAL_CONNECTOR_MASK)
|
||||
>> INTERNAL_CONNECTOR_BITS;
|
||||
if (vx_connector & 0x10) {
|
||||
vx_connector &= 0x0f;
|
||||
printf("[*%s*]", conn_tab[vx_connector].name);
|
||||
printf(": disable 'auto select' with DOS util!");
|
||||
} else {
|
||||
printf("[*%s*]", conn_tab[vx_connector].name);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vxsetlink(void)
|
||||
{
|
||||
int i, j, k;
|
||||
char *reason, *warning;
|
||||
static short prev_flags;
|
||||
static char prev_conn = -1;
|
||||
|
||||
if (prev_conn == -1) {
|
||||
prev_conn = vx_connector;
|
||||
}
|
||||
|
||||
i = vx_connector; /* default in EEPROM */
|
||||
reason = "default";
|
||||
warning = 0;
|
||||
|
||||
if ((vx_connectors & conn_tab[vx_connector].bit) == 0) {
|
||||
warning = "strange connector type in EEPROM.";
|
||||
reason = "forced";
|
||||
i = CONNECTOR_UTP;
|
||||
}
|
||||
|
||||
if (warning != 0) {
|
||||
printf("warning: %s\n", warning);
|
||||
}
|
||||
printf("selected %s. (%s)\n", conn_tab[i].name, reason);
|
||||
|
||||
/* Set the selected connector. */
|
||||
GO_WINDOW(3);
|
||||
j = inl(BASE + VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK;
|
||||
outl(j | (i <<INTERNAL_CONNECTOR_BITS), BASE + VX_W3_INTERNAL_CFG);
|
||||
|
||||
/* First, disable all. */
|
||||
outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
|
||||
udelay(8000);
|
||||
GO_WINDOW(4);
|
||||
outw(0, BASE + VX_W4_MEDIA_TYPE);
|
||||
|
||||
/* Second, enable the selected one. */
|
||||
switch(i) {
|
||||
case CONNECTOR_UTP:
|
||||
GO_WINDOW(4);
|
||||
outw(ENABLE_UTP, BASE + VX_W4_MEDIA_TYPE);
|
||||
break;
|
||||
case CONNECTOR_BNC:
|
||||
outw(START_TRANSCEIVER,BASE + VX_COMMAND);
|
||||
udelay(8000);
|
||||
break;
|
||||
case CONNECTOR_TX:
|
||||
case CONNECTOR_FX:
|
||||
GO_WINDOW(4);
|
||||
outw(LINKBEAT_ENABLE, BASE + VX_W4_MEDIA_TYPE);
|
||||
break;
|
||||
default: /* AUI and MII fall here */
|
||||
break;
|
||||
}
|
||||
GO_WINDOW(1);
|
||||
}
|
||||
|
||||
static void t595_disable(struct nic *nic)
|
||||
{
|
||||
outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
|
||||
udelay(8000);
|
||||
GO_WINDOW(4);
|
||||
outw(0, BASE + VX_W4_MEDIA_TYPE);
|
||||
GO_WINDOW(1);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
ETH_PROBE - Look for an adapter
|
||||
***************************************************************************/
|
||||
struct nic *t595_probe(struct nic *nic, unsigned short *probeaddrs, struct pci_device *pci)
|
||||
{
|
||||
int i;
|
||||
unsigned short *p;
|
||||
|
||||
if (probeaddrs == 0 || probeaddrs[0] == 0)
|
||||
return 0;
|
||||
/* eth_nic_base = probeaddrs[0] & ~3; */
|
||||
eth_nic_base = pci->ioaddr;
|
||||
|
||||
GO_WINDOW(0);
|
||||
outw(GLOBAL_RESET, BASE + VX_COMMAND);
|
||||
VX_BUSY_WAIT;
|
||||
|
||||
vxgetlink();
|
||||
|
||||
/*
|
||||
printf("\nEEPROM:");
|
||||
for (i = 0; i < (EEPROMSIZE/2); i++) {
|
||||
printf("%hX:", get_e(i));
|
||||
}
|
||||
printf("\n");
|
||||
*/
|
||||
/*
|
||||
* Read the station address from the eeprom
|
||||
*/
|
||||
p = (unsigned short *) nic->node_addr;
|
||||
for (i = 0; i < 3; i++) {
|
||||
GO_WINDOW(0);
|
||||
p[i] = htons(get_e(EEPROM_OEM_ADDR_0 + i));
|
||||
GO_WINDOW(2);
|
||||
outw(ntohs(p[i]), BASE + VX_W2_ADDR_0 + (i * 2));
|
||||
}
|
||||
|
||||
printf("Ethernet address: %!\n", nic->node_addr);
|
||||
|
||||
t595_reset(nic);
|
||||
nic->reset = t595_reset;
|
||||
nic->poll = t595_poll;
|
||||
nic->transmit = t595_transmit;
|
||||
nic->disable = t595_disable;
|
||||
return nic;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
||||
|
||||
-435
@@ -1,435 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1993 Herb Peyerl (hpeyerl@novatel.ca) All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2. The name
|
||||
* of the author may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
October 2, 1994
|
||||
|
||||
Modified by: Andres Vega Garcia
|
||||
|
||||
INRIA - Sophia Antipolis, France
|
||||
e-mail: avega@sophia.inria.fr
|
||||
finger: avega@pax.inria.fr
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* Created from if_epreg.h by Fred Gray (fgray@rice.edu) to support the
|
||||
* 3c590 family.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by Shusuke Nisiyama <shu@athena.qe.eng.hokudai.ac.jp>
|
||||
* for etherboot
|
||||
* Mar. 14, 2000
|
||||
*/
|
||||
|
||||
/*
|
||||
* Ethernet software status per interface.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Some global constants
|
||||
*/
|
||||
|
||||
#define TX_INIT_RATE 16
|
||||
#define TX_INIT_MAX_RATE 64
|
||||
#define RX_INIT_LATENCY 64
|
||||
#define RX_INIT_EARLY_THRESH 64
|
||||
#define MIN_RX_EARLY_THRESHF 16 /* not less than ether_header */
|
||||
#define MIN_RX_EARLY_THRESHL 4
|
||||
|
||||
#define EEPROMSIZE 0x40
|
||||
#define MAX_EEPROMBUSY 1000
|
||||
#define VX_LAST_TAG 0xd7
|
||||
#define VX_MAX_BOARDS 16
|
||||
#define VX_ID_PORT 0x100
|
||||
|
||||
/*
|
||||
* some macros to acces long named fields
|
||||
*/
|
||||
#define BASE (eth_nic_base)
|
||||
|
||||
/*
|
||||
* Commands to read/write EEPROM trough EEPROM command register (Window 0,
|
||||
* Offset 0xa)
|
||||
*/
|
||||
#define EEPROM_CMD_RD 0x0080 /* Read: Address required (5 bits) */
|
||||
#define EEPROM_CMD_WR 0x0040 /* Write: Address required (5 bits) */
|
||||
#define EEPROM_CMD_ERASE 0x00c0 /* Erase: Address required (5 bits) */
|
||||
#define EEPROM_CMD_EWEN 0x0030 /* Erase/Write Enable: No data required */
|
||||
|
||||
#define EEPROM_BUSY (1<<15)
|
||||
|
||||
/*
|
||||
* Some short functions, worth to let them be a macro
|
||||
*/
|
||||
|
||||
/**************************************************************************
|
||||
* *
|
||||
* These define the EEPROM data structure. They are used in the probe
|
||||
* function to verify the existence of the adapter after having sent
|
||||
* the ID_Sequence.
|
||||
*
|
||||
* There are others but only the ones we use are defined here.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#define EEPROM_NODE_ADDR_0 0x0 /* Word */
|
||||
#define EEPROM_NODE_ADDR_1 0x1 /* Word */
|
||||
#define EEPROM_NODE_ADDR_2 0x2 /* Word */
|
||||
#define EEPROM_PROD_ID 0x3 /* 0x9[0-f]50 */
|
||||
#define EEPROM_MFG_ID 0x7 /* 0x6d50 */
|
||||
#define EEPROM_ADDR_CFG 0x8 /* Base addr */
|
||||
#define EEPROM_RESOURCE_CFG 0x9 /* IRQ. Bits 12-15 */
|
||||
#define EEPROM_OEM_ADDR_0 0xa /* Word */
|
||||
#define EEPROM_OEM_ADDR_1 0xb /* Word */
|
||||
#define EEPROM_OEM_ADDR_2 0xc /* Word */
|
||||
#define EEPROM_SOFT_INFO_2 0xf /* Software information 2 */
|
||||
|
||||
#define NO_RX_OVN_ANOMALY (1<<5)
|
||||
|
||||
/**************************************************************************
|
||||
* *
|
||||
* These are the registers for the 3Com 3c509 and their bit patterns when *
|
||||
* applicable. They have been taken out the the "EtherLink III Parallel *
|
||||
* Tasking EISA and ISA Technical Reference" "Beta Draft 10/30/92" manual *
|
||||
* from 3com. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#define VX_COMMAND 0x0e /* Write. BASE+0x0e is always a
|
||||
* command reg. */
|
||||
#define VX_STATUS 0x0e /* Read. BASE+0x0e is always status
|
||||
* reg. */
|
||||
#define VX_WINDOW 0x0f /* Read. BASE+0x0f is always window
|
||||
* reg. */
|
||||
/*
|
||||
* Window 0 registers. Setup.
|
||||
*/
|
||||
/* Write */
|
||||
#define VX_W0_EEPROM_DATA 0x0c
|
||||
#define VX_W0_EEPROM_COMMAND 0x0a
|
||||
#define VX_W0_RESOURCE_CFG 0x08
|
||||
#define VX_W0_ADDRESS_CFG 0x06
|
||||
#define VX_W0_CONFIG_CTRL 0x04
|
||||
/* Read */
|
||||
#define VX_W0_PRODUCT_ID 0x02
|
||||
#define VX_W0_MFG_ID 0x00
|
||||
|
||||
|
||||
/*
|
||||
* Window 1 registers. Operating Set.
|
||||
*/
|
||||
/* Write */
|
||||
#define VX_W1_TX_PIO_WR_2 0x02
|
||||
#define VX_W1_TX_PIO_WR_1 0x00
|
||||
/* Read */
|
||||
#define VX_W1_FREE_TX 0x0c
|
||||
#define VX_W1_TX_STATUS 0x0b /* byte */
|
||||
#define VX_W1_TIMER 0x0a /* byte */
|
||||
#define VX_W1_RX_STATUS 0x08
|
||||
#define VX_W1_RX_PIO_RD_2 0x02
|
||||
#define VX_W1_RX_PIO_RD_1 0x00
|
||||
|
||||
/*
|
||||
* Window 2 registers. Station Address Setup/Read
|
||||
*/
|
||||
/* Read/Write */
|
||||
#define VX_W2_ADDR_5 0x05
|
||||
#define VX_W2_ADDR_4 0x04
|
||||
#define VX_W2_ADDR_3 0x03
|
||||
#define VX_W2_ADDR_2 0x02
|
||||
#define VX_W2_ADDR_1 0x01
|
||||
#define VX_W2_ADDR_0 0x00
|
||||
|
||||
/*
|
||||
* Window 3 registers. FIFO Management.
|
||||
*/
|
||||
/* Read */
|
||||
#define VX_W3_INTERNAL_CFG 0x00
|
||||
#define VX_W3_RESET_OPT 0x08
|
||||
#define VX_W3_FREE_TX 0x0c
|
||||
#define VX_W3_FREE_RX 0x0a
|
||||
|
||||
/*
|
||||
* Window 4 registers. Diagnostics.
|
||||
*/
|
||||
/* Read/Write */
|
||||
#define VX_W4_MEDIA_TYPE 0x0a
|
||||
#define VX_W4_CTRLR_STATUS 0x08
|
||||
#define VX_W4_NET_DIAG 0x06
|
||||
#define VX_W4_FIFO_DIAG 0x04
|
||||
#define VX_W4_HOST_DIAG 0x02
|
||||
#define VX_W4_TX_DIAG 0x00
|
||||
|
||||
/*
|
||||
* Window 5 Registers. Results and Internal status.
|
||||
*/
|
||||
/* Read */
|
||||
#define VX_W5_READ_0_MASK 0x0c
|
||||
#define VX_W5_INTR_MASK 0x0a
|
||||
#define VX_W5_RX_FILTER 0x08
|
||||
#define VX_W5_RX_EARLY_THRESH 0x06
|
||||
#define VX_W5_TX_AVAIL_THRESH 0x02
|
||||
#define VX_W5_TX_START_THRESH 0x00
|
||||
|
||||
/*
|
||||
* Window 6 registers. Statistics.
|
||||
*/
|
||||
/* Read/Write */
|
||||
#define TX_TOTAL_OK 0x0c
|
||||
#define RX_TOTAL_OK 0x0a
|
||||
#define TX_DEFERRALS 0x08
|
||||
#define RX_FRAMES_OK 0x07
|
||||
#define TX_FRAMES_OK 0x06
|
||||
#define RX_OVERRUNS 0x05
|
||||
#define TX_COLLISIONS 0x04
|
||||
#define TX_AFTER_1_COLLISION 0x03
|
||||
#define TX_AFTER_X_COLLISIONS 0x02
|
||||
#define TX_NO_SQE 0x01
|
||||
#define TX_CD_LOST 0x00
|
||||
|
||||
/****************************************
|
||||
*
|
||||
* Register definitions.
|
||||
*
|
||||
****************************************/
|
||||
|
||||
/*
|
||||
* Command register. All windows.
|
||||
*
|
||||
* 16 bit register.
|
||||
* 15-11: 5-bit code for command to be executed.
|
||||
* 10-0: 11-bit arg if any. For commands with no args;
|
||||
* this can be set to anything.
|
||||
*/
|
||||
#define GLOBAL_RESET (unsigned short) 0x0000 /* Wait at least 1ms
|
||||
* after issuing */
|
||||
#define WINDOW_SELECT (unsigned short) (0x1<<11)
|
||||
#define START_TRANSCEIVER (unsigned short) (0x2<<11) /* Read ADDR_CFG reg to
|
||||
* determine whether
|
||||
* this is needed. If
|
||||
* so; wait 800 uSec
|
||||
* before using trans-
|
||||
* ceiver. */
|
||||
#define RX_DISABLE (unsigned short) (0x3<<11) /* state disabled on
|
||||
* power-up */
|
||||
#define RX_ENABLE (unsigned short) (0x4<<11)
|
||||
#define RX_RESET (unsigned short) (0x5<<11)
|
||||
#define RX_DISCARD_TOP_PACK (unsigned short) (0x8<<11)
|
||||
#define TX_ENABLE (unsigned short) (0x9<<11)
|
||||
#define TX_DISABLE (unsigned short) (0xa<<11)
|
||||
#define TX_RESET (unsigned short) (0xb<<11)
|
||||
#define REQ_INTR (unsigned short) (0xc<<11)
|
||||
/*
|
||||
* The following C_* acknowledge the various interrupts. Some of them don't
|
||||
* do anything. See the manual.
|
||||
*/
|
||||
#define ACK_INTR (unsigned short) (0x6800)
|
||||
# define C_INTR_LATCH (unsigned short) (ACK_INTR|0x1)
|
||||
# define C_CARD_FAILURE (unsigned short) (ACK_INTR|0x2)
|
||||
# define C_TX_COMPLETE (unsigned short) (ACK_INTR|0x4)
|
||||
# define C_TX_AVAIL (unsigned short) (ACK_INTR|0x8)
|
||||
# define C_RX_COMPLETE (unsigned short) (ACK_INTR|0x10)
|
||||
# define C_RX_EARLY (unsigned short) (ACK_INTR|0x20)
|
||||
# define C_INT_RQD (unsigned short) (ACK_INTR|0x40)
|
||||
# define C_UPD_STATS (unsigned short) (ACK_INTR|0x80)
|
||||
#define SET_INTR_MASK (unsigned short) (0xe<<11)
|
||||
#define SET_RD_0_MASK (unsigned short) (0xf<<11)
|
||||
#define SET_RX_FILTER (unsigned short) (0x10<<11)
|
||||
# define FIL_INDIVIDUAL (unsigned short) (0x1)
|
||||
# define FIL_MULTICAST (unsigned short) (0x02)
|
||||
# define FIL_BRDCST (unsigned short) (0x04)
|
||||
# define FIL_PROMISC (unsigned short) (0x08)
|
||||
#define SET_RX_EARLY_THRESH (unsigned short) (0x11<<11)
|
||||
#define SET_TX_AVAIL_THRESH (unsigned short) (0x12<<11)
|
||||
#define SET_TX_START_THRESH (unsigned short) (0x13<<11)
|
||||
#define STATS_ENABLE (unsigned short) (0x15<<11)
|
||||
#define STATS_DISABLE (unsigned short) (0x16<<11)
|
||||
#define STOP_TRANSCEIVER (unsigned short) (0x17<<11)
|
||||
|
||||
/*
|
||||
* Status register. All windows.
|
||||
*
|
||||
* 15-13: Window number(0-7).
|
||||
* 12: Command_in_progress.
|
||||
* 11: reserved.
|
||||
* 10: reserved.
|
||||
* 9: reserved.
|
||||
* 8: reserved.
|
||||
* 7: Update Statistics.
|
||||
* 6: Interrupt Requested.
|
||||
* 5: RX Early.
|
||||
* 4: RX Complete.
|
||||
* 3: TX Available.
|
||||
* 2: TX Complete.
|
||||
* 1: Adapter Failure.
|
||||
* 0: Interrupt Latch.
|
||||
*/
|
||||
#define S_INTR_LATCH (unsigned short) (0x1)
|
||||
#define S_CARD_FAILURE (unsigned short) (0x2)
|
||||
#define S_TX_COMPLETE (unsigned short) (0x4)
|
||||
#define S_TX_AVAIL (unsigned short) (0x8)
|
||||
#define S_RX_COMPLETE (unsigned short) (0x10)
|
||||
#define S_RX_EARLY (unsigned short) (0x20)
|
||||
#define S_INT_RQD (unsigned short) (0x40)
|
||||
#define S_UPD_STATS (unsigned short) (0x80)
|
||||
#define S_COMMAND_IN_PROGRESS (unsigned short) (0x1000)
|
||||
|
||||
#define VX_BUSY_WAIT while (inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS)
|
||||
|
||||
/* Address Config. Register.
|
||||
* Window 0/Port 06
|
||||
*/
|
||||
|
||||
#define ACF_CONNECTOR_BITS 14
|
||||
#define ACF_CONNECTOR_UTP 0
|
||||
#define ACF_CONNECTOR_AUI 1
|
||||
#define ACF_CONNECTOR_BNC 3
|
||||
|
||||
#define INTERNAL_CONNECTOR_BITS 20
|
||||
#define INTERNAL_CONNECTOR_MASK 0x01700000
|
||||
|
||||
/*
|
||||
* FIFO Registers. RX Status.
|
||||
*
|
||||
* 15: Incomplete or FIFO empty.
|
||||
* 14: 1: Error in RX Packet 0: Incomplete or no error.
|
||||
* 13-11: Type of error.
|
||||
* 1000 = Overrun.
|
||||
* 1011 = Run Packet Error.
|
||||
* 1100 = Alignment Error.
|
||||
* 1101 = CRC Error.
|
||||
* 1001 = Oversize Packet Error (>1514 bytes)
|
||||
* 0010 = Dribble Bits.
|
||||
* (all other error codes, no errors.)
|
||||
*
|
||||
* 10-0: RX Bytes (0-1514)
|
||||
*/
|
||||
#define ERR_INCOMPLETE (unsigned short) (0x8000)
|
||||
#define ERR_RX (unsigned short) (0x4000)
|
||||
#define ERR_MASK (unsigned short) (0x7800)
|
||||
#define ERR_OVERRUN (unsigned short) (0x4000)
|
||||
#define ERR_RUNT (unsigned short) (0x5800)
|
||||
#define ERR_ALIGNMENT (unsigned short) (0x6000)
|
||||
#define ERR_CRC (unsigned short) (0x6800)
|
||||
#define ERR_OVERSIZE (unsigned short) (0x4800)
|
||||
#define ERR_DRIBBLE (unsigned short) (0x1000)
|
||||
|
||||
/*
|
||||
* TX Status.
|
||||
*
|
||||
* Reports the transmit status of a completed transmission. Writing this
|
||||
* register pops the transmit completion stack.
|
||||
*
|
||||
* Window 1/Port 0x0b.
|
||||
*
|
||||
* 7: Complete
|
||||
* 6: Interrupt on successful transmission requested.
|
||||
* 5: Jabber Error (TP Only, TX Reset required. )
|
||||
* 4: Underrun (TX Reset required. )
|
||||
* 3: Maximum Collisions.
|
||||
* 2: TX Status Overflow.
|
||||
* 1-0: Undefined.
|
||||
*
|
||||
*/
|
||||
#define TXS_COMPLETE 0x80
|
||||
#define TXS_INTR_REQ 0x40
|
||||
#define TXS_JABBER 0x20
|
||||
#define TXS_UNDERRUN 0x10
|
||||
#define TXS_MAX_COLLISION 0x8
|
||||
#define TXS_STATUS_OVERFLOW 0x4
|
||||
|
||||
#define RS_AUI (1<<5)
|
||||
#define RS_BNC (1<<4)
|
||||
#define RS_UTP (1<<3)
|
||||
#define RS_T4 (1<<0)
|
||||
#define RS_TX (1<<1)
|
||||
#define RS_FX (1<<2)
|
||||
#define RS_MII (1<<6)
|
||||
|
||||
|
||||
/*
|
||||
* FIFO Status (Window 4)
|
||||
*
|
||||
* Supports FIFO diagnostics
|
||||
*
|
||||
* Window 4/Port 0x04.1
|
||||
*
|
||||
* 15: 1=RX receiving (RO). Set when a packet is being received
|
||||
* into the RX FIFO.
|
||||
* 14: Reserved
|
||||
* 13: 1=RX underrun (RO). Generates Adapter Failure interrupt.
|
||||
* Requires RX Reset or Global Reset command to recover.
|
||||
* It is generated when you read past the end of a packet -
|
||||
* reading past what has been received so far will give bad
|
||||
* data.
|
||||
* 12: 1=RX status overrun (RO). Set when there are already 8
|
||||
* packets in the RX FIFO. While this bit is set, no additional
|
||||
* packets are received. Requires no action on the part of
|
||||
* the host. The condition is cleared once a packet has been
|
||||
* read out of the RX FIFO.
|
||||
* 11: 1=RX overrun (RO). Set when the RX FIFO is full (there
|
||||
* may not be an overrun packet yet). While this bit is set,
|
||||
* no additional packets will be received (some additional
|
||||
* bytes can still be pending between the wire and the RX
|
||||
* FIFO). Requires no action on the part of the host. The
|
||||
* condition is cleared once a few bytes have been read out
|
||||
* from the RX FIFO.
|
||||
* 10: 1=TX overrun (RO). Generates adapter failure interrupt.
|
||||
* Requires TX Reset or Global Reset command to recover.
|
||||
* Disables Transmitter.
|
||||
* 9-8: Unassigned.
|
||||
* 7-0: Built in self test bits for the RX and TX FIFO's.
|
||||
*/
|
||||
#define FIFOS_RX_RECEIVING (unsigned short) 0x8000
|
||||
#define FIFOS_RX_UNDERRUN (unsigned short) 0x2000
|
||||
#define FIFOS_RX_STATUS_OVERRUN (unsigned short) 0x1000
|
||||
#define FIFOS_RX_OVERRUN (unsigned short) 0x0800
|
||||
#define FIFOS_TX_OVERRUN (unsigned short) 0x0400
|
||||
|
||||
/*
|
||||
* Misc defines for various things.
|
||||
*/
|
||||
#define TAG_ADAPTER 0xd0
|
||||
#define ACTIVATE_ADAPTER_TO_CONFIG 0xff
|
||||
#define ENABLE_DRQ_IRQ 0x0001
|
||||
#define MFG_ID 0x506d /* `TCM' */
|
||||
#define PROD_ID 0x5090
|
||||
#define GO_WINDOW(x) outw(WINDOW_SELECT|(x),BASE+VX_COMMAND)
|
||||
#define JABBER_GUARD_ENABLE 0x40
|
||||
#define LINKBEAT_ENABLE 0x80
|
||||
#define ENABLE_UTP (JABBER_GUARD_ENABLE | LINKBEAT_ENABLE)
|
||||
#define DISABLE_UTP 0x0
|
||||
#define RX_BYTES_MASK (unsigned short) (0x07ff)
|
||||
#define RX_ERROR 0x4000
|
||||
#define RX_INCOMPLETE 0x8000
|
||||
#define TX_INDICATE 1<<15
|
||||
#define is_eeprom_busy(b) (inw((b)+VX_W0_EEPROM_COMMAND)&EEPROM_BUSY)
|
||||
|
||||
#define VX_IOSIZE 0x20
|
||||
|
||||
#define VX_CONNECTORS 8
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
||||
-929
@@ -1,929 +0,0 @@
|
||||
/*
|
||||
* 3c90x.c -- This file implements the 3c90x driver for etherboot. Written
|
||||
* by Greg Beeley, Greg.Beeley@LightSys.org. Modified by Steve Smith,
|
||||
* Steve.Smith@Juno.Com
|
||||
*
|
||||
* This program Copyright (C) 1999 LightSys Technology Services, Inc.
|
||||
* Portions Copyright (C) 1999 Steve Smith
|
||||
*
|
||||
* This program may be re-distributed in source or binary form, modified,
|
||||
* sold, or copied for any purpose, provided that the above copyright message
|
||||
* and this text are included with all source copies or derivative works, and
|
||||
* provided that the above copyright message and this text are included in the
|
||||
* documentation of any binary-only distributions. This program is distributed
|
||||
* WITHOUT ANY WARRANTY, without even the warranty of FITNESS FOR A PARTICULAR
|
||||
* PURPOSE or MERCHANTABILITY. Please read the associated documentation
|
||||
* "3c90x.txt" before compiling and using this driver.
|
||||
*
|
||||
* --------
|
||||
*
|
||||
* Program written with the assistance of the 3com documentation for
|
||||
* the 3c905B-TX card, as well as with some assistance from the 3c59x
|
||||
* driver Donald Becker wrote for the Linux kernel, and with some assistance
|
||||
* from the remainder of the Etherboot distribution.
|
||||
*
|
||||
* REVISION HISTORY:
|
||||
*
|
||||
* v0.10 1-26-1998 GRB Initial implementation.
|
||||
* v0.90 1-27-1998 GRB System works.
|
||||
* v1.00pre1 2-11-1998 GRB Got prom boot issue fixed.
|
||||
* v2.0 9-24-1999 SCS Modified for 3c905 (from 3c905b code)
|
||||
* Re-wrote poll and transmit for
|
||||
* better error recovery and heavy
|
||||
* network traffic operation
|
||||
*
|
||||
*/
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "pci.h"
|
||||
#include "cards.h"
|
||||
#include "timer.h"
|
||||
|
||||
#define XCVR_MAGIC (0x5A00)
|
||||
/** any single transmission fails after 16 collisions or other errors
|
||||
** this is the number of times to retry the transmission -- this should
|
||||
** be plenty
|
||||
**/
|
||||
#define XMIT_RETRIES 250
|
||||
|
||||
#undef virt_to_bus
|
||||
#define virt_to_bus(x) ((unsigned long)x)
|
||||
|
||||
/*** Register definitions for the 3c905 ***/
|
||||
enum Registers
|
||||
{
|
||||
regPowerMgmtCtrl_w = 0x7c, /** 905B Revision Only **/
|
||||
regUpMaxBurst_w = 0x7a, /** 905B Revision Only **/
|
||||
regDnMaxBurst_w = 0x78, /** 905B Revision Only **/
|
||||
regDebugControl_w = 0x74, /** 905B Revision Only **/
|
||||
regDebugData_l = 0x70, /** 905B Revision Only **/
|
||||
regRealTimeCnt_l = 0x40, /** Universal **/
|
||||
regUpBurstThresh_b = 0x3e, /** 905B Revision Only **/
|
||||
regUpPoll_b = 0x3d, /** 905B Revision Only **/
|
||||
regUpPriorityThresh_b = 0x3c, /** 905B Revision Only **/
|
||||
regUpListPtr_l = 0x38, /** Universal **/
|
||||
regCountdown_w = 0x36, /** Universal **/
|
||||
regFreeTimer_w = 0x34, /** Universal **/
|
||||
regUpPktStatus_l = 0x30, /** Universal with Exception, pg 130 **/
|
||||
regTxFreeThresh_b = 0x2f, /** 90X Revision Only **/
|
||||
regDnPoll_b = 0x2d, /** 905B Revision Only **/
|
||||
regDnPriorityThresh_b = 0x2c, /** 905B Revision Only **/
|
||||
regDnBurstThresh_b = 0x2a, /** 905B Revision Only **/
|
||||
regDnListPtr_l = 0x24, /** Universal with Exception, pg 107 **/
|
||||
regDmaCtrl_l = 0x20, /** Universal with Exception, pg 106 **/
|
||||
/** **/
|
||||
regIntStatusAuto_w = 0x1e, /** 905B Revision Only **/
|
||||
regTxStatus_b = 0x1b, /** Universal with Exception, pg 113 **/
|
||||
regTimer_b = 0x1a, /** Universal **/
|
||||
regTxPktId_b = 0x18, /** 905B Revision Only **/
|
||||
regCommandIntStatus_w = 0x0e, /** Universal (Command Variations) **/
|
||||
};
|
||||
|
||||
/** following are windowed registers **/
|
||||
enum Registers7
|
||||
{
|
||||
regPowerMgmtEvent_7_w = 0x0c, /** 905B Revision Only **/
|
||||
regVlanEtherType_7_w = 0x04, /** 905B Revision Only **/
|
||||
regVlanMask_7_w = 0x00, /** 905B Revision Only **/
|
||||
};
|
||||
|
||||
enum Registers6
|
||||
{
|
||||
regBytesXmittedOk_6_w = 0x0c, /** Universal **/
|
||||
regBytesRcvdOk_6_w = 0x0a, /** Universal **/
|
||||
regUpperFramesOk_6_b = 0x09, /** Universal **/
|
||||
regFramesDeferred_6_b = 0x08, /** Universal **/
|
||||
regFramesRecdOk_6_b = 0x07, /** Universal with Exceptions, pg 142 **/
|
||||
regFramesXmittedOk_6_b = 0x06, /** Universal **/
|
||||
regRxOverruns_6_b = 0x05, /** Universal **/
|
||||
regLateCollisions_6_b = 0x04, /** Universal **/
|
||||
regSingleCollisions_6_b = 0x03, /** Universal **/
|
||||
regMultipleCollisions_6_b = 0x02, /** Universal **/
|
||||
regSqeErrors_6_b = 0x01, /** Universal **/
|
||||
regCarrierLost_6_b = 0x00, /** Universal **/
|
||||
};
|
||||
|
||||
enum Registers5
|
||||
{
|
||||
regIndicationEnable_5_w = 0x0c, /** Universal **/
|
||||
regInterruptEnable_5_w = 0x0a, /** Universal **/
|
||||
regTxReclaimThresh_5_b = 0x09, /** 905B Revision Only **/
|
||||
regRxFilter_5_b = 0x08, /** Universal **/
|
||||
regRxEarlyThresh_5_w = 0x06, /** Universal **/
|
||||
regTxStartThresh_5_w = 0x00, /** Universal **/
|
||||
};
|
||||
|
||||
enum Registers4
|
||||
{
|
||||
regUpperBytesOk_4_b = 0x0d, /** Universal **/
|
||||
regBadSSD_4_b = 0x0c, /** Universal **/
|
||||
regMediaStatus_4_w = 0x0a, /** Universal with Exceptions, pg 201 **/
|
||||
regPhysicalMgmt_4_w = 0x08, /** Universal **/
|
||||
regNetworkDiagnostic_4_w = 0x06, /** Universal with Exceptions, pg 203 **/
|
||||
regFifoDiagnostic_4_w = 0x04, /** Universal with Exceptions, pg 196 **/
|
||||
regVcoDiagnostic_4_w = 0x02, /** Undocumented? **/
|
||||
};
|
||||
|
||||
enum Registers3
|
||||
{
|
||||
regTxFree_3_w = 0x0c, /** Universal **/
|
||||
regRxFree_3_w = 0x0a, /** Universal with Exceptions, pg 125 **/
|
||||
regResetMediaOptions_3_w = 0x08, /** Media Options on B Revision, **/
|
||||
/** Reset Options on Non-B Revision **/
|
||||
regMacControl_3_w = 0x06, /** Universal with Exceptions, pg 199 **/
|
||||
regMaxPktSize_3_w = 0x04, /** 905B Revision Only **/
|
||||
regInternalConfig_3_l = 0x00, /** Universal, different bit **/
|
||||
/** definitions, pg 59 **/
|
||||
};
|
||||
|
||||
enum Registers2
|
||||
{
|
||||
regResetOptions_2_w = 0x0c, /** 905B Revision Only **/
|
||||
regStationMask_2_3w = 0x06, /** Universal with Exceptions, pg 127 **/
|
||||
regStationAddress_2_3w = 0x00, /** Universal with Exceptions, pg 127 **/
|
||||
};
|
||||
|
||||
enum Registers1
|
||||
{
|
||||
regRxStatus_1_w = 0x0a, /** 90X Revision Only, Pg 126 **/
|
||||
};
|
||||
|
||||
enum Registers0
|
||||
{
|
||||
regEepromData_0_w = 0x0c, /** Universal **/
|
||||
regEepromCommand_0_w = 0x0a, /** Universal **/
|
||||
regBiosRomData_0_b = 0x08, /** 905B Revision Only **/
|
||||
regBiosRomAddr_0_l = 0x04, /** 905B Revision Only **/
|
||||
};
|
||||
|
||||
|
||||
/*** The names for the eight register windows ***/
|
||||
enum Windows
|
||||
{
|
||||
winPowerVlan7 = 0x07,
|
||||
winStatistics6 = 0x06,
|
||||
winTxRxControl5 = 0x05,
|
||||
winDiagnostics4 = 0x04,
|
||||
winTxRxOptions3 = 0x03,
|
||||
winAddressing2 = 0x02,
|
||||
winUnused1 = 0x01,
|
||||
winEepromBios0 = 0x00,
|
||||
};
|
||||
|
||||
|
||||
/*** Command definitions for the 3c90X ***/
|
||||
enum Commands
|
||||
{
|
||||
cmdGlobalReset = 0x00, /** Universal with Exceptions, pg 151 **/
|
||||
cmdSelectRegisterWindow = 0x01, /** Universal **/
|
||||
cmdEnableDcConverter = 0x02, /** **/
|
||||
cmdRxDisable = 0x03, /** **/
|
||||
cmdRxEnable = 0x04, /** Universal **/
|
||||
cmdRxReset = 0x05, /** Universal **/
|
||||
cmdStallCtl = 0x06, /** Universal **/
|
||||
cmdTxEnable = 0x09, /** Universal **/
|
||||
cmdTxDisable = 0x0A, /** **/
|
||||
cmdTxReset = 0x0B, /** Universal **/
|
||||
cmdRequestInterrupt = 0x0C, /** **/
|
||||
cmdAcknowledgeInterrupt = 0x0D, /** Universal **/
|
||||
cmdSetInterruptEnable = 0x0E, /** Universal **/
|
||||
cmdSetIndicationEnable = 0x0F, /** Universal **/
|
||||
cmdSetRxFilter = 0x10, /** Universal **/
|
||||
cmdSetRxEarlyThresh = 0x11, /** **/
|
||||
cmdSetTxStartThresh = 0x13, /** **/
|
||||
cmdStatisticsEnable = 0x15, /** **/
|
||||
cmdStatisticsDisable = 0x16, /** **/
|
||||
cmdDisableDcConverter = 0x17, /** **/
|
||||
cmdSetTxReclaimThresh = 0x18, /** **/
|
||||
cmdSetHashFilterBit = 0x19, /** **/
|
||||
};
|
||||
|
||||
|
||||
/*** Values for int status register bitmask **/
|
||||
#define INT_INTERRUPTLATCH (1<<0)
|
||||
#define INT_HOSTERROR (1<<1)
|
||||
#define INT_TXCOMPLETE (1<<2)
|
||||
#define INT_RXCOMPLETE (1<<4)
|
||||
#define INT_RXEARLY (1<<5)
|
||||
#define INT_INTREQUESTED (1<<6)
|
||||
#define INT_UPDATESTATS (1<<7)
|
||||
#define INT_LINKEVENT (1<<8)
|
||||
#define INT_DNCOMPLETE (1<<9)
|
||||
#define INT_UPCOMPLETE (1<<10)
|
||||
#define INT_CMDINPROGRESS (1<<12)
|
||||
#define INT_WINDOWNUMBER (7<<13)
|
||||
|
||||
|
||||
/*** TX descriptor ***/
|
||||
typedef struct
|
||||
{
|
||||
unsigned int DnNextPtr;
|
||||
unsigned int FrameStartHeader;
|
||||
unsigned int HdrAddr;
|
||||
unsigned int HdrLength;
|
||||
unsigned int DataAddr;
|
||||
unsigned int DataLength;
|
||||
}
|
||||
TXD;
|
||||
|
||||
/*** RX descriptor ***/
|
||||
typedef struct
|
||||
{
|
||||
unsigned int UpNextPtr;
|
||||
unsigned int UpPktStatus;
|
||||
unsigned int DataAddr;
|
||||
unsigned int DataLength;
|
||||
}
|
||||
RXD;
|
||||
|
||||
/*** Global variables ***/
|
||||
static struct
|
||||
{
|
||||
unsigned char isBrev;
|
||||
unsigned char CurrentWindow;
|
||||
unsigned int IOAddr;
|
||||
unsigned char HWAddr[ETH_ALEN];
|
||||
TXD TransmitDPD;
|
||||
RXD ReceiveUPD;
|
||||
}
|
||||
INF_3C90X;
|
||||
|
||||
|
||||
/*** a3c90x_internal_IssueCommand: sends a command to the 3c90x card
|
||||
***/
|
||||
static int
|
||||
a3c90x_internal_IssueCommand(int ioaddr, int cmd, int param)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
/** Build the cmd. **/
|
||||
val = cmd;
|
||||
val <<= 11;
|
||||
val |= param;
|
||||
|
||||
/** Send the cmd to the cmd register **/
|
||||
outw(val, ioaddr + regCommandIntStatus_w);
|
||||
|
||||
/** Wait for the cmd to complete, if necessary **/
|
||||
while (inw(ioaddr + regCommandIntStatus_w) & INT_CMDINPROGRESS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*** a3c90x_internal_SetWindow: selects a register window set.
|
||||
***/
|
||||
static int
|
||||
a3c90x_internal_SetWindow(int ioaddr, int window)
|
||||
{
|
||||
|
||||
/** Window already as set? **/
|
||||
if (INF_3C90X.CurrentWindow == window) return 0;
|
||||
|
||||
/** Issue the window command. **/
|
||||
a3c90x_internal_IssueCommand(ioaddr, cmdSelectRegisterWindow, window);
|
||||
INF_3C90X.CurrentWindow = window;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*** a3c90x_internal_ReadEeprom - read data from the serial eeprom.
|
||||
***/
|
||||
static unsigned short
|
||||
a3c90x_internal_ReadEeprom(int ioaddr, int address)
|
||||
{
|
||||
unsigned short val;
|
||||
|
||||
/** Select correct window **/
|
||||
a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winEepromBios0);
|
||||
|
||||
/** Make sure the eeprom isn't busy **/
|
||||
while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
|
||||
|
||||
/** Read the value. **/
|
||||
outw(address + ((0x02)<<6), ioaddr + regEepromCommand_0_w);
|
||||
while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
|
||||
val = inw(ioaddr + regEepromData_0_w);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
/*** a3c90x_internal_WriteEepromWord - write a physical word of
|
||||
*** data to the onboard serial eeprom (not the BIOS prom, but the
|
||||
*** nvram in the card that stores, among other things, the MAC
|
||||
*** address).
|
||||
***/
|
||||
static int
|
||||
a3c90x_internal_WriteEepromWord(int ioaddr, int address, unsigned short value)
|
||||
{
|
||||
/** Select register window **/
|
||||
a3c90x_internal_SetWindow(ioaddr, winEepromBios0);
|
||||
|
||||
/** Verify Eeprom not busy **/
|
||||
while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
|
||||
|
||||
/** Issue WriteEnable, and wait for completion. **/
|
||||
outw(0x30, ioaddr + regEepromCommand_0_w);
|
||||
while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
|
||||
|
||||
/** Issue EraseRegister, and wait for completion. **/
|
||||
outw(address + ((0x03)<<6), ioaddr + regEepromCommand_0_w);
|
||||
while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
|
||||
|
||||
/** Send the new data to the eeprom, and wait for completion. **/
|
||||
outw(value, ioaddr + regEepromData_0_w);
|
||||
outw(0x30, ioaddr + regEepromCommand_0_w);
|
||||
while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
|
||||
|
||||
/** Burn the new data into the eeprom, and wait for completion. **/
|
||||
outw(address + ((0x01)<<6), ioaddr + regEepromCommand_0_w);
|
||||
while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*** a3c90x_internal_WriteEeprom - write data to the serial eeprom,
|
||||
*** and re-compute the eeprom checksum.
|
||||
***/
|
||||
static int
|
||||
a3c90x_internal_WriteEeprom(int ioaddr, int address, unsigned short value)
|
||||
{
|
||||
int cksum = 0,v;
|
||||
int i;
|
||||
int maxAddress, cksumAddress;
|
||||
|
||||
if (INF_3C90X.isBrev)
|
||||
{
|
||||
maxAddress=0x1f;
|
||||
cksumAddress=0x20;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxAddress=0x16;
|
||||
cksumAddress=0x17;
|
||||
}
|
||||
|
||||
/** Write the value. **/
|
||||
if (a3c90x_internal_WriteEepromWord(ioaddr, address, value) == -1)
|
||||
return -1;
|
||||
|
||||
/** Recompute the checksum. **/
|
||||
for(i=0;i<=maxAddress;i++)
|
||||
{
|
||||
v = a3c90x_internal_ReadEeprom(ioaddr, i);
|
||||
cksum ^= (v & 0xFF);
|
||||
cksum ^= ((v>>8) & 0xFF);
|
||||
}
|
||||
/** Write the checksum to the location in the eeprom **/
|
||||
if (a3c90x_internal_WriteEepromWord(ioaddr, cksumAddress, cksum) == -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*** a3c90x_reset: exported function that resets the card to its default
|
||||
*** state. This is so the Linux driver can re-set the card up the way
|
||||
*** it wants to. If CFG_3C90X_PRESERVE_XCVR is defined, then the reset will
|
||||
*** not alter the selected transceiver that we used to download the boot
|
||||
*** image.
|
||||
***/
|
||||
static void
|
||||
a3c90x_reset(struct nic *nic)
|
||||
{
|
||||
int cfg;
|
||||
|
||||
#ifdef CFG_3C90X_PRESERVE_XCVR
|
||||
/** Read the current InternalConfig value. **/
|
||||
a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winTxRxOptions3);
|
||||
cfg = inl(INF_3C90X.IOAddr + regInternalConfig_3_l);
|
||||
#endif
|
||||
|
||||
/** Send the reset command to the card **/
|
||||
printf("Issuing RESET:\n");
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdGlobalReset, 0);
|
||||
|
||||
/** wait for reset command to complete **/
|
||||
while (inw(INF_3C90X.IOAddr + regCommandIntStatus_w) & INT_CMDINPROGRESS);
|
||||
|
||||
/** global reset command resets station mask, non-B revision cards
|
||||
** require explicit reset of values
|
||||
**/
|
||||
a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winAddressing2);
|
||||
outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+0);
|
||||
outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+2);
|
||||
outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+4);
|
||||
|
||||
#ifdef CFG_3C90X_PRESERVE_XCVR
|
||||
/** Re-set the original InternalConfig value from before reset **/
|
||||
a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winTxRxOptions3);
|
||||
outl(cfg, INF_3C90X.IOAddr + regInternalConfig_3_l);
|
||||
|
||||
/** enable DC converter for 10-Base-T **/
|
||||
if ((cfg&0x0300) == 0x0300)
|
||||
{
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdEnableDcConverter, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Issue transmit reset, wait for command completion **/
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdTxReset, 0);
|
||||
while (inw(INF_3C90X.IOAddr + regCommandIntStatus_w) & INT_CMDINPROGRESS)
|
||||
;
|
||||
if (! INF_3C90X.isBrev)
|
||||
outb(0x01, INF_3C90X.IOAddr + regTxFreeThresh_b);
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdTxEnable, 0);
|
||||
|
||||
/**
|
||||
** reset of the receiver on B-revision cards re-negotiates the link
|
||||
** takes several seconds (a computer eternity)
|
||||
**/
|
||||
if (INF_3C90X.isBrev)
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdRxReset, 0x04);
|
||||
else
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdRxReset, 0x00);
|
||||
while (inw(INF_3C90X.IOAddr + regCommandIntStatus_w) & INT_CMDINPROGRESS);
|
||||
;
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdRxEnable, 0);
|
||||
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr,
|
||||
cmdSetInterruptEnable, 0);
|
||||
/** enable rxComplete and txComplete **/
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr,
|
||||
cmdSetIndicationEnable, 0x0014);
|
||||
/** acknowledge any pending status flags **/
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr,
|
||||
cmdAcknowledgeInterrupt, 0x661);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*** a3c90x_transmit: exported function that transmits a packet. Does not
|
||||
*** return any particular status. Parameters are:
|
||||
*** d[6] - destination address, ethernet;
|
||||
*** t - protocol type (ARP, IP, etc);
|
||||
*** s - size of the non-header part of the packet that needs transmitted;
|
||||
*** p - the pointer to the packet data itself.
|
||||
***/
|
||||
static void
|
||||
a3c90x_transmit(struct nic *nic, const char *d, unsigned int t,
|
||||
unsigned int s, const char *p)
|
||||
{
|
||||
|
||||
struct eth_hdr
|
||||
{
|
||||
unsigned char dst_addr[ETH_ALEN];
|
||||
unsigned char src_addr[ETH_ALEN];
|
||||
unsigned short type;
|
||||
} hdr;
|
||||
|
||||
unsigned char status;
|
||||
unsigned i, retries;
|
||||
|
||||
for (retries=0; retries < XMIT_RETRIES ; retries++)
|
||||
{
|
||||
/** Stall the download engine **/
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdStallCtl, 2);
|
||||
|
||||
/** Make sure the card is not waiting on us **/
|
||||
inw(INF_3C90X.IOAddr + regCommandIntStatus_w);
|
||||
inw(INF_3C90X.IOAddr + regCommandIntStatus_w);
|
||||
|
||||
while (inw(INF_3C90X.IOAddr+regCommandIntStatus_w) &
|
||||
INT_CMDINPROGRESS)
|
||||
;
|
||||
|
||||
/** Set the ethernet packet type **/
|
||||
hdr.type = htons(t);
|
||||
|
||||
/** Copy the destination address **/
|
||||
memcpy(hdr.dst_addr, d, ETH_ALEN);
|
||||
|
||||
/** Copy our MAC address **/
|
||||
memcpy(hdr.src_addr, INF_3C90X.HWAddr, ETH_ALEN);
|
||||
|
||||
/** Setup the DPD (download descriptor) **/
|
||||
INF_3C90X.TransmitDPD.DnNextPtr = 0;
|
||||
/** set notification for transmission completion (bit 15) **/
|
||||
INF_3C90X.TransmitDPD.FrameStartHeader = (s + sizeof(hdr)) | 0x8000;
|
||||
INF_3C90X.TransmitDPD.HdrAddr = virt_to_bus(&hdr);
|
||||
INF_3C90X.TransmitDPD.HdrLength = sizeof(hdr);
|
||||
INF_3C90X.TransmitDPD.DataAddr = virt_to_bus(p);
|
||||
INF_3C90X.TransmitDPD.DataLength = s + (1<<31);
|
||||
|
||||
/** Send the packet **/
|
||||
outl(virt_to_bus(&(INF_3C90X.TransmitDPD)),
|
||||
INF_3C90X.IOAddr + regDnListPtr_l);
|
||||
|
||||
/** End Stall and Wait for upload to complete. **/
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdStallCtl, 3);
|
||||
while(inl(INF_3C90X.IOAddr + regDnListPtr_l) != 0)
|
||||
;
|
||||
|
||||
/** Wait for NIC Transmit to Complete **/
|
||||
load_timer2(10*TICKS_PER_MS); /* Give it 10 ms */
|
||||
while (!(inw(INF_3C90X.IOAddr + regCommandIntStatus_w)&0x0004) &&
|
||||
timer2_running())
|
||||
;
|
||||
|
||||
if (!(inw(INF_3C90X.IOAddr + regCommandIntStatus_w)&0x0004))
|
||||
{
|
||||
printf("3C90X: Tx Timeout\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
status = inb(INF_3C90X.IOAddr + regTxStatus_b);
|
||||
|
||||
/** acknowledge transmit interrupt by writing status **/
|
||||
outb(0x00, INF_3C90X.IOAddr + regTxStatus_b);
|
||||
|
||||
/** successful completion (sans "interrupt Requested" bit) **/
|
||||
if ((status & 0xbf) == 0x80)
|
||||
return;
|
||||
|
||||
printf("3C90X: Status (%hhX)\n", status);
|
||||
/** check error codes **/
|
||||
if (status & 0x02)
|
||||
{
|
||||
printf("3C90X: Tx Reclaim Error (%hhX)\n", status);
|
||||
a3c90x_reset(NULL);
|
||||
}
|
||||
else if (status & 0x04)
|
||||
{
|
||||
printf("3C90X: Tx Status Overflow (%hhX)\n", status);
|
||||
for (i=0; i<32; i++)
|
||||
outb(0x00, INF_3C90X.IOAddr + regTxStatus_b);
|
||||
/** must re-enable after max collisions before re-issuing tx **/
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdTxEnable, 0);
|
||||
}
|
||||
else if (status & 0x08)
|
||||
{
|
||||
printf("3C90X: Tx Max Collisions (%hhX)\n", status);
|
||||
/** must re-enable after max collisions before re-issuing tx **/
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdTxEnable, 0);
|
||||
}
|
||||
else if (status & 0x10)
|
||||
{
|
||||
printf("3C90X: Tx Underrun (%hhX)\n", status);
|
||||
a3c90x_reset(NULL);
|
||||
}
|
||||
else if (status & 0x20)
|
||||
{
|
||||
printf("3C90X: Tx Jabber (%hhX)\n", status);
|
||||
a3c90x_reset(NULL);
|
||||
}
|
||||
else if ((status & 0x80) != 0x80)
|
||||
{
|
||||
printf("3C90X: Internal Error - Incomplete Transmission (%hhX)\n",
|
||||
status);
|
||||
a3c90x_reset(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/** failed after RETRY attempts **/
|
||||
printf("Failed to send after %d retries\n", retries);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*** a3c90x_poll: exported routine that waits for a certain length of time
|
||||
*** for a packet, and if it sees none, returns 0. This routine should
|
||||
*** copy the packet to nic->packet if it gets a packet and set the size
|
||||
*** in nic->packetlen. Return 1 if a packet was found.
|
||||
***/
|
||||
static int
|
||||
a3c90x_poll(struct nic *nic)
|
||||
{
|
||||
int i, errcode;
|
||||
|
||||
if (!(inw(INF_3C90X.IOAddr + regCommandIntStatus_w)&0x0010))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** we don't need to acknowledge rxComplete -- the upload engine
|
||||
** does it for us.
|
||||
**/
|
||||
|
||||
/** Build the up-load descriptor **/
|
||||
INF_3C90X.ReceiveUPD.UpNextPtr = 0;
|
||||
INF_3C90X.ReceiveUPD.UpPktStatus = 0;
|
||||
INF_3C90X.ReceiveUPD.DataAddr = virt_to_bus(nic->packet);
|
||||
INF_3C90X.ReceiveUPD.DataLength = 1536 + (1<<31);
|
||||
|
||||
/** Submit the upload descriptor to the NIC **/
|
||||
outl(virt_to_bus(&(INF_3C90X.ReceiveUPD)),
|
||||
INF_3C90X.IOAddr + regUpListPtr_l);
|
||||
|
||||
/** Wait for upload completion (upComplete(15) or upError (14)) **/
|
||||
for(i=0;i<40000;i++);
|
||||
while((INF_3C90X.ReceiveUPD.UpPktStatus & ((1<<14) | (1<<15))) == 0)
|
||||
for(i=0;i<40000;i++);
|
||||
|
||||
/** Check for Error (else we have good packet) **/
|
||||
if (INF_3C90X.ReceiveUPD.UpPktStatus & (1<<14))
|
||||
{
|
||||
errcode = INF_3C90X.ReceiveUPD.UpPktStatus;
|
||||
if (errcode & (1<<16))
|
||||
printf("3C90X: Rx Overrun (%hX)\n",errcode>>16);
|
||||
else if (errcode & (1<<17))
|
||||
printf("3C90X: Runt Frame (%hX)\n",errcode>>16);
|
||||
else if (errcode & (1<<18))
|
||||
printf("3C90X: Alignment Error (%hX)\n",errcode>>16);
|
||||
else if (errcode & (1<<19))
|
||||
printf("3C90X: CRC Error (%hX)\n",errcode>>16);
|
||||
else if (errcode & (1<<20))
|
||||
printf("3C90X: Oversized Frame (%hX)\n",errcode>>16);
|
||||
else
|
||||
printf("3C90X: Packet error (%hX)\n",errcode>>16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Ok, got packet. Set length in nic->packetlen. **/
|
||||
nic->packetlen = (INF_3C90X.ReceiveUPD.UpPktStatus & 0x1FFF);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*** a3c90x_disable: exported routine to disable the card. What's this for?
|
||||
*** the eepro100.c driver didn't have one, so I just left this one empty too.
|
||||
*** Ideas anyone?
|
||||
*** Must turn off receiver at least so stray packets will not corrupt memory
|
||||
*** [Ken]
|
||||
***/
|
||||
static void
|
||||
a3c90x_disable(struct nic *nic)
|
||||
{
|
||||
/* Disable the receiver and transmitter. */
|
||||
outw(cmdRxDisable, INF_3C90X.IOAddr + regCommandIntStatus_w);
|
||||
outw(cmdTxDisable, INF_3C90X.IOAddr + regCommandIntStatus_w);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*** a3c90x_probe: exported routine to probe for the 3c905 card and perform
|
||||
*** initialization. If this routine is called, the pci functions did find the
|
||||
*** card. We just have to init it here.
|
||||
***/
|
||||
struct nic*
|
||||
a3c90x_probe(struct nic *nic, unsigned short *probeaddrs, struct pci_device *pci)
|
||||
{
|
||||
int i, c;
|
||||
unsigned short eeprom[0x21];
|
||||
unsigned int cfg;
|
||||
unsigned int mopt;
|
||||
unsigned short linktype;
|
||||
|
||||
if (probeaddrs == 0 || probeaddrs[0] == 0)
|
||||
return 0;
|
||||
|
||||
adjust_pci_device(pci);
|
||||
|
||||
INF_3C90X.IOAddr = probeaddrs[0] & ~3;
|
||||
INF_3C90X.CurrentWindow = 255;
|
||||
switch (a3c90x_internal_ReadEeprom(INF_3C90X.IOAddr, 0x03))
|
||||
{
|
||||
case 0x9000: /** 10 Base TPO **/
|
||||
case 0x9001: /** 10/100 T4 **/
|
||||
case 0x9050: /** 10/100 TPO **/
|
||||
case 0x9051: /** 10 Base Combo **/
|
||||
INF_3C90X.isBrev = 0;
|
||||
break;
|
||||
|
||||
case 0x9004: /** 10 Base TPO **/
|
||||
case 0x9005: /** 10 Base Combo **/
|
||||
case 0x9006: /** 10 Base TPO and Base2 **/
|
||||
case 0x900A: /** 10 Base FL **/
|
||||
case 0x9055: /** 10/100 TPO **/
|
||||
case 0x9056: /** 10/100 T4 **/
|
||||
case 0x905A: /** 10 Base FX **/
|
||||
default:
|
||||
INF_3C90X.isBrev = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/** Load the EEPROM contents **/
|
||||
if (INF_3C90X.isBrev)
|
||||
{
|
||||
for(i=0;i<=0x20;i++)
|
||||
{
|
||||
eeprom[i] = a3c90x_internal_ReadEeprom(INF_3C90X.IOAddr, i);
|
||||
}
|
||||
|
||||
#ifdef CFG_3C90X_BOOTROM_FIX
|
||||
/** Set xcvrSelect in InternalConfig in eeprom. **/
|
||||
/* only necessary for 3c905b revision cards with boot PROM bug!!! */
|
||||
a3c90x_internal_WriteEeprom(INF_3C90X.IOAddr, 0x13, 0x0160);
|
||||
#endif
|
||||
|
||||
#ifdef CFG_3C90X_XCVR
|
||||
if (CFG_3C90X_XCVR == 255)
|
||||
{
|
||||
/** Clear the LanWorks register **/
|
||||
a3c90x_internal_WriteEeprom(INF_3C90X.IOAddr, 0x16, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/** Set the selected permanent-xcvrSelect in the
|
||||
** LanWorks register
|
||||
**/
|
||||
a3c90x_internal_WriteEeprom(INF_3C90X.IOAddr, 0x16,
|
||||
XCVR_MAGIC + ((CFG_3C90X_XCVR) & 0x000F));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=0;i<=0x17;i++)
|
||||
{
|
||||
eeprom[i] = a3c90x_internal_ReadEeprom(INF_3C90X.IOAddr, i);
|
||||
}
|
||||
}
|
||||
|
||||
/** Print identification message **/
|
||||
printf("\n\n3C90X Driver 2.00 "
|
||||
"Copyright 1999 LightSys Technology Services, Inc.\n"
|
||||
"Portions Copyright 1999 Steve Smith\n");
|
||||
printf("Provided with ABSOLUTELY NO WARRANTY.\n");
|
||||
printf("-------------------------------------------------------"
|
||||
"------------------------\n");
|
||||
|
||||
/** Retrieve the Hardware address and print it on the screen. **/
|
||||
INF_3C90X.HWAddr[0] = eeprom[0]>>8;
|
||||
INF_3C90X.HWAddr[1] = eeprom[0]&0xFF;
|
||||
INF_3C90X.HWAddr[2] = eeprom[1]>>8;
|
||||
INF_3C90X.HWAddr[3] = eeprom[1]&0xFF;
|
||||
INF_3C90X.HWAddr[4] = eeprom[2]>>8;
|
||||
INF_3C90X.HWAddr[5] = eeprom[2]&0xFF;
|
||||
printf("MAC Address = %!\n", INF_3C90X.HWAddr);
|
||||
|
||||
/** Program the MAC address into the station address registers **/
|
||||
a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winAddressing2);
|
||||
outw(htons(eeprom[0]), INF_3C90X.IOAddr + regStationAddress_2_3w);
|
||||
outw(htons(eeprom[1]), INF_3C90X.IOAddr + regStationAddress_2_3w+2);
|
||||
outw(htons(eeprom[2]), INF_3C90X.IOAddr + regStationAddress_2_3w+4);
|
||||
outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+0);
|
||||
outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+2);
|
||||
outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+4);
|
||||
|
||||
/** Fill in our entry in the etherboot arp table **/
|
||||
for(i=0;i<ETH_ALEN;i++)
|
||||
nic->node_addr[i] = (eeprom[i/2] >> (8*((i&1)^1))) & 0xff;
|
||||
|
||||
/** Read the media options register, print a message and set default
|
||||
** xcvr.
|
||||
**
|
||||
** Uses Media Option command on B revision, Reset Option on non-B
|
||||
** revision cards -- same register address
|
||||
**/
|
||||
a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winTxRxOptions3);
|
||||
mopt = inw(INF_3C90X.IOAddr + regResetMediaOptions_3_w);
|
||||
|
||||
/** mask out VCO bit that is defined as 10baseFL bit on B-rev cards **/
|
||||
if (! INF_3C90X.isBrev)
|
||||
{
|
||||
mopt &= 0x7F;
|
||||
}
|
||||
|
||||
printf("Connectors present: ");
|
||||
c = 0;
|
||||
linktype = 0x0008;
|
||||
if (mopt & 0x01)
|
||||
{
|
||||
printf("%s100Base-T4",(c++)?", ":"");
|
||||
linktype = 0x0006;
|
||||
}
|
||||
if (mopt & 0x04)
|
||||
{
|
||||
printf("%s100Base-FX",(c++)?", ":"");
|
||||
linktype = 0x0005;
|
||||
}
|
||||
if (mopt & 0x10)
|
||||
{
|
||||
printf("%s10Base-2",(c++)?", ":"");
|
||||
linktype = 0x0003;
|
||||
}
|
||||
if (mopt & 0x20)
|
||||
{
|
||||
printf("%sAUI",(c++)?", ":"");
|
||||
linktype = 0x0001;
|
||||
}
|
||||
if (mopt & 0x40)
|
||||
{
|
||||
printf("%sMII",(c++)?", ":"");
|
||||
linktype = 0x0006;
|
||||
}
|
||||
if ((mopt & 0xA) == 0xA)
|
||||
{
|
||||
printf("%s10Base-T / 100Base-TX",(c++)?", ":"");
|
||||
linktype = 0x0008;
|
||||
}
|
||||
else if ((mopt & 0xA) == 0x2)
|
||||
{
|
||||
printf("%s100Base-TX",(c++)?", ":"");
|
||||
linktype = 0x0008;
|
||||
}
|
||||
else if ((mopt & 0xA) == 0x8)
|
||||
{
|
||||
printf("%s10Base-T",(c++)?", ":"");
|
||||
linktype = 0x0008;
|
||||
}
|
||||
printf(".\n");
|
||||
|
||||
/** Determine transceiver type to use, depending on value stored in
|
||||
** eeprom 0x16
|
||||
**/
|
||||
if (INF_3C90X.isBrev)
|
||||
{
|
||||
if ((eeprom[0x16] & 0xFF00) == XCVR_MAGIC)
|
||||
{
|
||||
/** User-defined **/
|
||||
linktype = eeprom[0x16] & 0x000F;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef CFG_3C90X_XCVR
|
||||
if (CFG_3C90X_XCVR != 255)
|
||||
linktype = CFG_3C90X_XCVR;
|
||||
#endif /* CFG_3C90X_XCVR */
|
||||
|
||||
/** I don't know what MII MAC only mode is!!! **/
|
||||
if (linktype == 0x0009)
|
||||
{
|
||||
if (INF_3C90X.isBrev)
|
||||
printf("WARNING: MII External MAC Mode only supported on B-revision "
|
||||
"cards!!!!\nFalling Back to MII Mode\n");
|
||||
linktype = 0x0006;
|
||||
}
|
||||
}
|
||||
|
||||
/** enable DC converter for 10-Base-T **/
|
||||
if (linktype == 0x0003)
|
||||
{
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdEnableDcConverter, 0);
|
||||
}
|
||||
|
||||
/** Set the link to the type we just determined. **/
|
||||
a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winTxRxOptions3);
|
||||
cfg = inl(INF_3C90X.IOAddr + regInternalConfig_3_l);
|
||||
cfg &= ~(0xF<<20);
|
||||
cfg |= (linktype<<20);
|
||||
outl(cfg, INF_3C90X.IOAddr + regInternalConfig_3_l);
|
||||
|
||||
/** Now that we set the xcvr type, reset the Tx and Rx, re-enable. **/
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdTxReset, 0x00);
|
||||
while (inw(INF_3C90X.IOAddr + regCommandIntStatus_w) & INT_CMDINPROGRESS)
|
||||
;
|
||||
|
||||
if (!INF_3C90X.isBrev)
|
||||
outb(0x01, INF_3C90X.IOAddr + regTxFreeThresh_b);
|
||||
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdTxEnable, 0);
|
||||
|
||||
/**
|
||||
** reset of the receiver on B-revision cards re-negotiates the link
|
||||
** takes several seconds (a computer eternity)
|
||||
**/
|
||||
if (INF_3C90X.isBrev)
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdRxReset, 0x04);
|
||||
else
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdRxReset, 0x00);
|
||||
while (inw(INF_3C90X.IOAddr + regCommandIntStatus_w) & INT_CMDINPROGRESS)
|
||||
;
|
||||
|
||||
/** Set the RX filter = receive only individual pkts & bcast. **/
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdSetRxFilter, 0x01 + 0x04);
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdRxEnable, 0);
|
||||
|
||||
|
||||
/**
|
||||
** set Indication and Interrupt flags , acknowledge any IRQ's
|
||||
**/
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdSetInterruptEnable, 0);
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr,
|
||||
cmdSetIndicationEnable, 0x0014);
|
||||
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr,
|
||||
cmdAcknowledgeInterrupt, 0x661);
|
||||
|
||||
/** Set our exported functions **/
|
||||
nic->reset = a3c90x_reset;
|
||||
nic->poll = a3c90x_poll;
|
||||
nic->transmit = a3c90x_transmit;
|
||||
nic->disable = a3c90x_disable;
|
||||
|
||||
return nic;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,307 +0,0 @@
|
||||
|
||||
Instructions for use of the 3C90X driver for EtherBoot
|
||||
|
||||
Original 3C905B support by:
|
||||
Greg Beeley (Greg.Beeley@LightSys.org),
|
||||
LightSys Technology Services, Inc.
|
||||
February 11, 1999
|
||||
|
||||
Updates for 3C90X family by:
|
||||
Steve Smith (steve.smith@juno.com)
|
||||
October 1, 1999
|
||||
|
||||
Minor documentation updates by
|
||||
Greg Beeley (Greg.Beeley@LightSys.org)
|
||||
March 29, 2000
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
I OVERVIEW
|
||||
|
||||
The 3c90X series ethernet cards are a group of high-performance busmaster
|
||||
DMA cards from 3Com. This particular driver supports both the 3c90x and
|
||||
the 3c90xB revision cards. 3C90xC family support has been tested to some
|
||||
degree but not extensively.
|
||||
|
||||
Here's the licensing information:
|
||||
|
||||
This program Copyright (C) 1999 LightSys Technology Services, Inc.
|
||||
Portions Copyright (C) 1999 Steve Smith.
|
||||
|
||||
This program may be re-distributed in source or binary form, modified,
|
||||
sold, or copied for any purpose, provided that the above copyright message
|
||||
and this text are included with all source copies or derivative works, and
|
||||
provided that the above copyright message and this text are included in the
|
||||
documentation of any binary-only distributions. This program is
|
||||
distributed WITHOUT ANY WARRANTY, without even the warranty of FITNESS FOR
|
||||
A PARTICULAR PURPOSE or MERCHANTABILITY. Please read the associated
|
||||
documentation "3c90x.txt" before compiling and using this driver.
|
||||
|
||||
|
||||
II FLASH PROMS
|
||||
|
||||
The 3c90xB cards, according to the 3Com documentation, only accept the
|
||||
following flash memory chips:
|
||||
|
||||
Atmel AT29C512 (64 kilobyte)
|
||||
Atmel AT29C010 (128 kilobyte)
|
||||
|
||||
The 3c90x cards, according to the 3Com documentation, accept the
|
||||
following flash memory chips capacities:
|
||||
|
||||
64 kb (8 kB)
|
||||
128 kb (16 kB)
|
||||
256 kb (32 kB) and
|
||||
512 kb (64 kB)
|
||||
|
||||
Atmel AT29C512 (64 kilobyte) chips are specifically listed for both
|
||||
adapters, but flashing on the 3c905b cards would only be supported
|
||||
through the Atmel parts. Any device, of the supported size, should
|
||||
be supported when programmed by a dedicated PROM programmer (e.g.
|
||||
not the card).
|
||||
|
||||
To use this driver in such a PROM, visit Atmel's web site and download
|
||||
their .PDF file containing a list of their distributors. Contact the
|
||||
distributors for pricing information. The prices are quite reasonable
|
||||
(about $3 US each for the 64 kB part), and are comparable to what one would
|
||||
expect for similarly sized standard EPROMs. And, the flash chips are much
|
||||
easier to work with, as they don't need to be UV-erased to be reprogrammed.
|
||||
The 3C905B card actually provides a method to program the flash memory
|
||||
while it is resident on board the card itself; if someone would like to
|
||||
write a small DOS program to do the programming, I can provide the
|
||||
information about the registers and so forth.
|
||||
|
||||
A utility program, 3c90xutil, is provided with Etherboot in the 'contrib'
|
||||
directory that allows for the on-board flashing of the ROM while Linux
|
||||
is running. The program has been successfully used under Linux, but I
|
||||
have heard problem reports of its use under FreeBSD. Anyone willing to
|
||||
make it work under FreeBSD is more than welcome to do so!
|
||||
|
||||
You also have the option of using EPROM chips - the 3C905B-TX-NM has been
|
||||
successfully tested with 27C256 (32kB) and 27C512 (64kB) chips with a
|
||||
specified access time of 100ns and faster.
|
||||
|
||||
|
||||
III GENERAL USE
|
||||
|
||||
Normally, the basic procedure for using this driver is as follows:
|
||||
|
||||
1. Run the 3c90xcfg program on the driver diskette to enable the
|
||||
boot PROM and set it to 64k or 128k, as appropriate.
|
||||
2. Build the appropriate 3c90x.fd0 or 3c90x.fd0 floppy image with
|
||||
possibly the value CFG_3C90X_XCVR defined to the transceiver type that
|
||||
you want to use (i.e., 10/100 rj45, AUI, coax, MII).
|
||||
3. Run the floppy image on the PC to be network booted, to get
|
||||
it configured, and to verify that it will boot properly.
|
||||
4. Build the 3c90x.rom or 3c90x.lzrom PROM image and program
|
||||
it into the flash or EPROM memory chip.
|
||||
5. Put the PROM in the ethernet card, boot and enable 'boot from
|
||||
network first' in the system BIOS, save and reboot.
|
||||
|
||||
Here are some issues to be aware of:
|
||||
|
||||
1. If you experience crashes or different behaviour when using the
|
||||
boot PROM, add the setting CFG_3C90X_BOOTROM_FIX and go through the
|
||||
steps 2-5 above. This works around a bug in some 3c905B cards (see
|
||||
below), but has some side-effects which may not be desirable.
|
||||
Please note that you have to boot off a floppy (not PROM!) once for
|
||||
this fix to take effect.
|
||||
2. The possible need to manually set the CFG_3C90X_XCVR value to
|
||||
configure the transceiver type. Values are listed below.
|
||||
3. The possible need to define CFG_3C90X_PRESERVE_XCVR for use in
|
||||
operating systems that don't intelligently determine the
|
||||
transceiver type.
|
||||
|
||||
Some things that are on the 'To-Do' list, perhaps for me, but perhaps
|
||||
for any other volunteers out there:
|
||||
|
||||
1. Extend the driver to fully implement the auto-select
|
||||
algorithm if the card has multiple media ports.
|
||||
2. Fix any bugs in the code <grin>....
|
||||
3. Extend the driver to support the 3c905c revision cards
|
||||
"officially". Right now, the support has been primarily empirical
|
||||
and not based on 3c905C documentation.
|
||||
|
||||
Now for the details....
|
||||
|
||||
This driver has been tested on roughly 300 systems. The main two
|
||||
configuration issues to contend with are:
|
||||
|
||||
1. Ensure that PCI Busmastering is enabled for the adapter (configured
|
||||
in the CMOS setup)
|
||||
2. Some systems don't work properly with the adapter when plug and
|
||||
play OS is enabled; I always set it to "No" or "Disabled" -- this makes
|
||||
it easier and really doesn't adversely affect anything.
|
||||
|
||||
Roughly 95% of the systems worked when configured properly. A few
|
||||
have issues with booting locally once the boot PROM has been installed
|
||||
(this number has been less than 2%). Other configuration issues that
|
||||
to check:
|
||||
|
||||
1. Newer BIOS's actually work correctly with the network boot order.
|
||||
Set the network adapter first. Most older BIOS's automatically go to
|
||||
the network boot PROM first.
|
||||
2. For systems where the adapter was already installed and is just
|
||||
having the PROM installed, try setting the "reset configuration data"
|
||||
to yes in the CMOS setup if the BIOS isn't seen at first. If your BIOS
|
||||
doesn't have this option, remove the card, start the system, shut down,
|
||||
install the card and restart (or switch to a different PCI slot).
|
||||
3. Make sure the CMOS security settings aren't preventing a boot.
|
||||
|
||||
The 3c905B cards have a significant 'bug' that relates to the flash prom:
|
||||
unless the card is set internally to the MII transceiver, it will only
|
||||
read the first 8k of the PROM image. Don't ask why -- it seems really
|
||||
obscure, but it has to do with the way they mux'd the address lines
|
||||
from the PCI bus to the ROM. Unfortunately, most of us are not using
|
||||
MII transceivers, and even the .lzrom image ends up being just a little
|
||||
bit larger than 8k. Note that the workaround for this is disabled by
|
||||
default, because the Windows NT 4.0 driver does not like it (no packets
|
||||
are transmitted).
|
||||
|
||||
So, the solution that I've used is to internally set the card's nvram
|
||||
configuration to use MII when it boots. The 3c905b driver does this
|
||||
automatically. This way, the 16k prom image can be loaded into memory,
|
||||
and then the 3c905b driver can set the temporary configuration of the
|
||||
card to an appropriate value, either configurable by the user or chosen
|
||||
by the driver.
|
||||
|
||||
To enable the 3c905B bugfix, which is necessary for these cards when
|
||||
booting from the Flash ROM, define -DCFG_3C90X_BOOTROM_FIX when building,
|
||||
create a floppy image and boot it once.
|
||||
Thereafter, the card should accept the larger prom image.
|
||||
|
||||
The driver should choose an appropriate transceiver on the card. However,
|
||||
if it doesn't on your card or if you need to, for instance, set your
|
||||
card to 10mbps when connected to an unmanaged 10/100 hub, you can specify
|
||||
which transceiver you want to use. To do this, build the 3c905b.fd0
|
||||
image with -DCFG_3C90X_XCVR=x, where 'x' is one of the following
|
||||
values:
|
||||
|
||||
0 10Base-T
|
||||
1 10mbps AUI
|
||||
3 10Base-2 (thinnet/coax)
|
||||
4 100Base-TX
|
||||
5 100Base-FX
|
||||
6 MII
|
||||
8 Auto-negotiation 10Base-T / 100Base-TX (usually the default)
|
||||
9 MII External MAC Mode
|
||||
255 Allow driver to choose an 'appropriate' media port.
|
||||
|
||||
Then proceed from step 2 in the above 'general use' instructions. The
|
||||
.rom image can be built with CFG_3C90X_XCVR set to a value, but you
|
||||
normally don't want to do this, since it is easier to change the
|
||||
transceiver type by rebuilding a new floppy, changing the BIOS to floppy
|
||||
boot, booting, and then changing the BIOS back to network boot. If
|
||||
CFG_3C90X_XCVR is not set in a particular build, it just uses the
|
||||
current configuration (either its 'best guess' or whatever the stored
|
||||
CFG_3C90X_XCVR value was from the last time it was set).
|
||||
|
||||
[[ Note for the more technically inclined: The CFG_3C90X_XCVR value is
|
||||
programmed into a register in the card's NVRAM that was reserved for
|
||||
LanWorks PROM images to use. When the driver boots, the card comes
|
||||
up in MII mode, and the driver checks the LanWorks register to find
|
||||
out if the user specified a transceiver type. If it finds that
|
||||
information, it uses that, otherwise it picks a transceiver that the
|
||||
card has based on the 3c905b's MediaOptions register. This driver isn't
|
||||
quite smart enough to always determine which media port is actually
|
||||
_connected_; maybe someone else would like to take on that task (it
|
||||
actually involves sending a self-directed packet and seeing if it
|
||||
comes back. IF it does, that port is connected). ]]
|
||||
|
||||
Another issue to keep in mind is that it is possible that some OS'es
|
||||
might not be happy with the way I've handled the PROM-image hack with
|
||||
setting MII mode on bootup. Linux 2.0.35 does not have this problem.
|
||||
Behavior of other systems may vary. The 3com documentation specifically
|
||||
says that, at least with the card that I have, the device driver in the
|
||||
OS should auto-select the media port, so other drivers should work fine
|
||||
with this 'hack'. However, if yours doesn't seem to, you can try defining
|
||||
CFG_3C90X_PRESERVE_XCVR when building to cause Etherboot to keep the
|
||||
working setting (that allowed the bootp/tftp process) across the eth_reset
|
||||
operation.
|
||||
|
||||
|
||||
IV FOR DEVELOPERS....
|
||||
|
||||
If you would like to fix/extend/etc. this driver, feel free to do so; just
|
||||
be sure you can test the modified version on the 3c905B-TX cards that the
|
||||
driver was originally designed for. This section of this document gives
|
||||
some information that might be relevant to a programmer.
|
||||
|
||||
A. Main Entry Point
|
||||
|
||||
a3c90x_probe is the main entry point for this driver. It is referred
|
||||
to in an array in 'config.c'.
|
||||
|
||||
B. Other Important Functions
|
||||
|
||||
The functions a3c90x_transmit, a3c90x_poll, a3c90x_reset, and
|
||||
a3c90x_disable are static functions that EtherBoot finds out about
|
||||
as a result of a3c90x_probe setting entries in the nic structure
|
||||
for them. The EtherBoot framework does not use interrupts. It is
|
||||
polled. All transmit and receive operations are initiated by the
|
||||
etherboot framework, not by an interrupt or by the driver.
|
||||
|
||||
C. Internal Functions
|
||||
|
||||
The following functions are internal to the driver:
|
||||
|
||||
a3c90x_internal_IssueCommand - sends a command to the 3c905b card.
|
||||
a3c90x_internal_SetWindow - shifts between one of eight register
|
||||
windows onboard the 3c90x. The bottom 16 bytes of the card's
|
||||
I/O space are multiplexed among 128 bytes, only 16 of which are
|
||||
visible at any one time. This SetWindow function selects one of
|
||||
the eight sets.
|
||||
a3c90x_internal_ReadEeprom - reads a word (16 bits) from the
|
||||
card's onboard nvram. This is NOT the BIOS boot rom. This is
|
||||
where the card stores such things as its hardware address.
|
||||
a3c90x_internal_WriteEeprom - writes a word (16 bits) to the
|
||||
card's nvram, and recomputes the eeprom checksum.
|
||||
a3c90x_internal_WriteEepromWord - writes a word (16 bits) to the
|
||||
card's nvram. Used by the above routine.
|
||||
a3c90x_internal_WriteEepromWord - writes a word (16 bits) to the
|
||||
card's nvram. Used by the above routine.
|
||||
|
||||
D. Globals
|
||||
|
||||
All global variables are inside a global structure named INF_3C90X.
|
||||
So, wherever you see that structure referenced, you know the variable
|
||||
is a global. Just keeps things a little neater.
|
||||
|
||||
E. Enumerations
|
||||
|
||||
There are quite a few enumerated type definitions for registers and
|
||||
so forth, many for registers that I didn't even touch in the driver.
|
||||
Register types start with 'reg', window numbers (for SetWindow)
|
||||
start with 'win', and commands (for IssueCommand) start with 'cmd'.
|
||||
Register offsets also include an indication in the name as to the
|
||||
size of the register (_b = byte, _w = word, _l = long), and which
|
||||
window the register is in, if it is windowed (0-7).
|
||||
|
||||
F. Why the 'a3c90x' name?
|
||||
|
||||
I had to come up with a letter at the beginning of all of the
|
||||
identifiers, since 3com so conveniently had their name start with a
|
||||
number. Another driver used 't' (for 'three'?); I chose 'a' for
|
||||
no reason at all.
|
||||
|
||||
Addendum by Jorge L. deLyra <delyra@latt.if.usp.br>, 22Nov2000 re
|
||||
working around the 3C905 hardware bug mentioned above:
|
||||
|
||||
Use this floppy to fix any 3COM model 3C905B PCI 10/100 Ethernet cards
|
||||
that fail to load and run the boot program the first time around. If
|
||||
they have a "Lucent" rather than a "Broadcom" chipset these cards have
|
||||
a configuration bug that causes a hang when trying to load the boot
|
||||
program from the PROM, if you try to use them right out of the box.
|
||||
|
||||
The boot program in this floppy is the file named 3c905b-tpo100.rom
|
||||
from Etherboot version 4.6.10, compiled with the bugfix parameter
|
||||
|
||||
CFG_3C90X_BOOTROM_FIX
|
||||
|
||||
You have to take the chip off the card and boot the system once using
|
||||
this floppy. Once loaded from the floppy, the boot program will access
|
||||
the card and change some setting in it, correcting the problem. After
|
||||
that you may use either this boot program or the normal one, compiled
|
||||
without this bugfix parameter, to boot the machine from the PROM chip.
|
||||
|
||||
[Any recent Etherboot version should do, not just 4.6.10 - Ed.]
|
||||
@@ -1,219 +0,0 @@
|
||||
# For <shared.h> and <stage1.h>.
|
||||
INCLUDES = -I$(top_srcdir)/stage2 -I$(top_srcdir)/stage1
|
||||
|
||||
# Don't build the netboot support by default.
|
||||
if NETBOOT_SUPPORT
|
||||
LIBDRIVERS = libdrivers.a
|
||||
else
|
||||
LIBDRIVERS =
|
||||
endif
|
||||
|
||||
noinst_LIBRARIES = $(LIBDRIVERS)
|
||||
|
||||
libdrivers_a_SOURCES = cards.h config.c etherboot.h \
|
||||
fsys_tftp.c linux-asm-io.h linux-asm-string.h \
|
||||
main.c misc.c nic.h osdep.h pci.c pci.h timer.c timer.h
|
||||
EXTRA_libdrivers_a_SOURCES = 3c509.c 3c509.h 3c595.c 3c595.h 3c90x.c \
|
||||
cs89x0.c cs89x0.h davicom.c depca.c eepro.c eepro100.c \
|
||||
epic100.c epic100.h fa311.c i82586.c lance.c natsemi.c \
|
||||
ni5010.c ns8390.c ns8390.h otulip.c otulip.h rtl8139.c \
|
||||
sis900.c sis900.h sk_g16.c sk_g16.h smc9000.c smc9000.h \
|
||||
tiara.c tlan.c tulip.c via-rhine.c w89c840.c
|
||||
libdrivers_a_CFLAGS = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
-DFSYS_TFTP=1 $(NET_CFLAGS) $(NET_EXTRAFLAGS)
|
||||
# Filled by configure.
|
||||
libdrivers_a_LIBADD = @NETBOOT_DRIVERS@
|
||||
libdrivers_a_DEPENDENCIES = $(libdrivers_a_LIBADD)
|
||||
|
||||
EXTRA_DIST = README.netboot 3c90x.txt cs89x0.txt sis900.txt tulip.txt
|
||||
|
||||
# These below are several special rules for the device drivers.
|
||||
# We cannot use a simple rule for them...
|
||||
|
||||
# What objects are derived from a driver?
|
||||
3c509_drivers = 3c509.o 3c529.o
|
||||
3c595_drivers = 3c595.o
|
||||
3c90x_drivers = 3c90x.o
|
||||
cs89x0_drivers = cs89x0.o
|
||||
davicom_drivers = davicom.o
|
||||
depca_drivers = depca.o
|
||||
eepro_drivers = eepro.o
|
||||
eepro100_drivers = eepro100.o
|
||||
epic100_drivers = epic100.o
|
||||
#fa311_drivers = fa311.o
|
||||
i82586_drivers = 3c507.o exos205.o ni5210.o
|
||||
lance_drivers = lance.o ne2100.o ni6510.o
|
||||
natsemi_drivers = natsemi.o
|
||||
ni5010_drivers = ni5010.o
|
||||
ns8390_drivers = 3c503.o ne.o ns8390.o wd.o
|
||||
otulip_drivers = otulip.o
|
||||
rtl8139_drivers = rtl8139.o
|
||||
sis900_drivers = sis900.o
|
||||
sk_g16_drivers = sk_g16.o
|
||||
smc9000_drivers = smc9000.o
|
||||
tiara_drivers = tiara.o
|
||||
#tlan_drivers = tlan.o
|
||||
tulip_drivers = tulip.o
|
||||
via_rhine_drivers = via_rhine.o
|
||||
w89c840_drivers = w89c840.o
|
||||
|
||||
# Is it really necessary to specify dependecies explicitly?
|
||||
$(3c509_drivers): 3c509.c 3c509.h
|
||||
$(3c509_drivers): %.o: 3c509.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(3c595_drivers): 3c595.c 3c595.h
|
||||
$(3c595_drivers): %.o: 3c595.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(3c90x_drivers): 3c90x.c
|
||||
$(3c90x_drivers): %.o: 3c90x.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(cs89x0_drivers): cs89x0.c cs89x0.h
|
||||
$(cs89x0_drivers): %.o: cs89x0.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(davicom_drivers): davicom.c
|
||||
$(davicom_drivers): %.o: davicom.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(depca_drivers): depca.c
|
||||
$(depca_drivers): %.o: depca.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(eepro_drivers): eepro.c
|
||||
$(eepro_drivers): %.o: eepro.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(eepro100_drivers): eepro100.c
|
||||
$(eepro100_drivers): %.o: eepro100.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(epic100_drivers): epic100.c epic100.h
|
||||
$(epic100_drivers): %.o: epic100.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
#$(fa311_drivers): fa311.c
|
||||
#$(fa311_drivers): %.o: fa311.c
|
||||
# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(i82586_drivers): i82586.c
|
||||
$(i82586_drivers): %.o: i82586.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(lance_drivers): lance.c
|
||||
$(lance_drivers): %.o: lance.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(natsemi_drivers): natsemi.c
|
||||
$(natsemi_drivers): %.o: natsemi.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(ni5010_drivers): ni5010.c
|
||||
$(ni5010_drivers): %.o: ni5010.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(ns8390_drivers): ns8390.c ns8390.h
|
||||
$(ns8390_drivers): %.o: ns8390.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(otulip_drivers): otulip.c otulip.h
|
||||
$(otulip_drivers): %.o: otulip.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(rtl8139_drivers): rtl8139.c
|
||||
$(rtl8139_drivers): %.o: rtl8139.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(sis900_drivers): sis900.c
|
||||
$(sis900_drivers): %.o: sis900.c sis900.h
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(sk_g16_drivers): sk_g16.c sk_g16.h
|
||||
$(sk_g16_drivers): %.o: sk_g16.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(smc9000_drivers): smc9000.c smc9000.h
|
||||
$(smc9000_drivers): %.o: smc9000.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(tiara_drivers): tiara.c
|
||||
$(tiara_drivers): %.o: tiara.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
#$(tlan_drivers): tlan.c
|
||||
#$(tlan_drivers): %.o: tlan.c
|
||||
# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(tulip_drivers): tulip.c
|
||||
$(tulip_drivers): %.o: tulip.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(via_rhine_drivers): via-rhine.c
|
||||
$(via_rhine_drivers): %.o: via-rhine.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(w89c840_drivers): w89c840.c
|
||||
$(w89c840_drivers): %.o: w89c840.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
# Per-object flags.
|
||||
3c509_o_CFLAGS = -DINCLUDE_3C509=1
|
||||
3c529_o_CFLAGS = -DINCLUDE_3C529=1
|
||||
3c595_o_CFLAGS = -DINCLUDE_3C595=1
|
||||
3c90x_o_CFLAGS = -DINCLUDE_3C90X=1
|
||||
cs89x0_o_CFLAGS = -DINCLUDE_CS89X0=1
|
||||
davicom_o_CFLAGS = -DINCLUDE_DAVICOM=1
|
||||
depca_o_CFLAGS = -DINCLUDE_DEPCA=1
|
||||
eepro_o_CFLAGS = -DINCLUDE_EEPRO=1
|
||||
eepro100_o_CFLAGS = -DINCLUDE_EEPRO100=1
|
||||
epic100_o_CFLAGS = -DINCLUDE_EPIC100=1
|
||||
#fa311_o_CFLAGS = -DINCLUDE_FA311=1
|
||||
3c507_o_CFLAGS = -DINCLUDE_3C507=1
|
||||
exos205_o_CFLAGS = -DINCLUDE_EXOS205=1
|
||||
ni5210_o_CFLAGS = -DINCLUDE_NI5210=1
|
||||
lance_o_CFLAGS = -DINCLUDE_LANCE=1
|
||||
ne2100_o_CFLAGS = -DINCLUDE_NE2100=1
|
||||
ni6510_o_CFLAGS = -DINCLUDE_NI6510=1
|
||||
natsemi_o_CFLAGS = -DINCLUDE_NATSEMI=1
|
||||
ni5010_o_CFLAGS = -DINCLUDE_NI5010=1
|
||||
3c503_o_CFLAGS = -DINCLUDE_3C503=1
|
||||
ne_o_CFLAGS = -DINCLUDE_NE=1
|
||||
ns8390_o_CFLAGS = -DINCLUDE_NS8390=1
|
||||
wd_o_CFLAGS = -DINCLUDE_WD=1
|
||||
otulip_o_CFLAGS = -DINCLUDE_OTULIP=1
|
||||
rtl8139_o_CFLAGS = -DINCLUDE_RTL8139=1
|
||||
sis900_o_CFLAGS = -DINCLUDE_SIS900=1
|
||||
sk_g16_o_CFLAGS = -DINCLUDE_SK_G16=1
|
||||
smc9000_o_CFLAGS = -DINCLUDE_SMC9000=1
|
||||
tiara_o_CFLAGS = -DINCLUDE_TIARA=1
|
||||
#tlan_o_CFLAGS = -DINCLUDE_TLAN=1
|
||||
tulip_o_CFLAGS = -DINCLUDE_TULIP=1
|
||||
via_rhine_o_CFLAGS = -DINCLUDE_VIA_RHINE=1
|
||||
w89c840_o_CFLAGS = -DINCLUDE_W89C840=1
|
||||
-1091
File diff suppressed because it is too large.
Load diff
@@ -1,168 +0,0 @@
|
||||
You can use the netboot support to download OS images from a network.
|
||||
Nearly all the device drivers are coming from the network-based boot
|
||||
loader, Etherboot. Please visit its web page. They have rich
|
||||
documentations so you will be able to get useful information from there.
|
||||
The URL is <http://etherboot.sourceforge.net/>.
|
||||
|
||||
These below are common options for configure. Perhaps you may not need
|
||||
to specify them.
|
||||
|
||||
--disable-packet-retransmission
|
||||
Turns off packet retransmission. Use it on an empty network, where
|
||||
no packet collision can happen.
|
||||
|
||||
--enable-pci-direct
|
||||
Define this for PCI BIOSes that do not implement BIOS32 or not
|
||||
correctly.
|
||||
|
||||
--enable-diskless
|
||||
Enable the diskless support. If specified, you will get two optional
|
||||
images, called "nbgrub" and "pxegrub". The former is the ``Net Boot
|
||||
Image Proposal'' format, which is used by Etherboot and Netboot, while
|
||||
the latter is the ``Preboot Execution Environment" format, which is
|
||||
used by a PXE ROM. You may buy a PXE ROM from some companies.
|
||||
|
||||
Here is the information about the device drivers. They are all disabled
|
||||
by default, so you must specify configure options to enable drivers you
|
||||
want to use. Some drivers have extra per-driver options, so the extra
|
||||
options are also described below.
|
||||
|
||||
Caution: You should enable them as you need. Don't enable any
|
||||
unnecessary driver, because GRUB might crash if you include too many
|
||||
drivers at the same time.
|
||||
|
||||
3Com509, ISA/EISA
|
||||
--enable-3c509
|
||||
|
||||
3Com529 == MCA 3c509
|
||||
--enable-3c529
|
||||
|
||||
3Com59x and 3Com900
|
||||
--enable-3c595
|
||||
|
||||
3Com90x
|
||||
--enable-3c90x
|
||||
|
||||
Crystal Semiconductor CS89x0
|
||||
--enable-cs89x0
|
||||
--enable-cs-scan=LIST
|
||||
Probe for CS89x0 base address using LIST of comma separated hex
|
||||
addresses; increasing the address by one (0x300 -> 0x301) will force
|
||||
a more aggressive probing algorithm. This might be neccessary after
|
||||
a soft-reset of the NIC.
|
||||
|
||||
Davicom DM9102 and 9009
|
||||
--enable-davicom
|
||||
|
||||
Digital DE100 and DE200
|
||||
--enable-depca
|
||||
|
||||
Intel Etherexpress Pro/10 (ISA card)
|
||||
--enable-eepro
|
||||
|
||||
Intel Etherexpress Pro/100
|
||||
--enable-eepro100
|
||||
|
||||
SMC 83c170 EPIC/100
|
||||
--enable-epic100
|
||||
|
||||
3Com507
|
||||
--enable-3c507
|
||||
|
||||
EXOS205
|
||||
--enable-exos205
|
||||
|
||||
Racal-Interlan NI5210
|
||||
--enable-ni5210
|
||||
|
||||
Lance PCI PCNet/32
|
||||
AMD HomePNA
|
||||
--enable-lance
|
||||
|
||||
Novell NE2100 and NE1500
|
||||
--enable-ne2100
|
||||
|
||||
Racal-Interlan NI6510
|
||||
--enable-ni6510
|
||||
|
||||
National Semiconductor DP8381x (Netgear FA311 and FA312)
|
||||
--enable-natsemi
|
||||
|
||||
Racal-Interlan NI5010
|
||||
--enable-ni5010
|
||||
|
||||
3Com503, aka Etherlink II, also /16 model
|
||||
--enable-3c503
|
||||
--enable-3c503-shmem
|
||||
Use 3c503 shared memory mode.
|
||||
--enable-3c503-aui
|
||||
Use AUI by default on 3c503 cards.
|
||||
|
||||
NE1000/2000 and clones (ISA)
|
||||
--enable-ne
|
||||
--enable-ne-scan=LIST (0x280,0x300,0x320,0x340)
|
||||
Probe for NE base address using LIST of comma separated hex
|
||||
addresses.
|
||||
|
||||
NE2000 PCI clone (RTL8029)
|
||||
Winbond 86C940
|
||||
Compex RL2000
|
||||
KTI ET32P2
|
||||
NetVin 5000SC
|
||||
Holtek 80232
|
||||
--enable-ns8390
|
||||
--enable-compex-rl2000-fix
|
||||
If you have a Compex RL2000 PCI 32-bit (11F6:1401), and the probe
|
||||
hangs in "Probing...[NE*000/PCI]", try enabling this fix... it
|
||||
worked for me :).
|
||||
|
||||
WD8003/8013, SMC8216/8416
|
||||
--enable-wd
|
||||
--enable-wd-default-mem=MEM (0xCC000)
|
||||
Default memory location for WD/SMC cards.
|
||||
|
||||
Old base driver for Tulip clones
|
||||
--enable-otulip
|
||||
|
||||
Realtek 8139
|
||||
SMC 1211
|
||||
D-Link DFE530TX+ and DFE538TX
|
||||
--enable-rtl8139
|
||||
|
||||
SIS 900 and SIS 7016
|
||||
--enable-sis900
|
||||
|
||||
Schneider and Koch G16
|
||||
--enable-sk-g16
|
||||
|
||||
SMC9000
|
||||
--enable-smc9000
|
||||
--enable-smc9000-scan=LIST
|
||||
List of I/O addresses to probe.
|
||||
|
||||
Tiara, Fujitsu Lancard
|
||||
--enable-tiara
|
||||
|
||||
Linksys LNE100TX and other NICs using this Tulip clone chip
|
||||
Netgear FA310TX and other NICs using this Tulip clone chip
|
||||
Tulip clones based on the ADMtek Centaur-P
|
||||
Tulip clones based on the Macronix 987x5
|
||||
Tulip-Fast
|
||||
Tulip+
|
||||
Tulip 21142
|
||||
ASIX AX88140
|
||||
Intel Tulip
|
||||
Compex RL100-TX
|
||||
--enable-tulip
|
||||
|
||||
Rhine-I, e.g. D-Link DFE-530TX
|
||||
Rhine-II
|
||||
--enable-via-rhine
|
||||
|
||||
Winbond W89c840
|
||||
Compex RL100-ATX
|
||||
--enable-w89c840
|
||||
|
||||
|
||||
The description about how to use the support can be found in the GRUB
|
||||
manual. Run "info grub" in the shell prompt.
|
||||
-183
@@ -1,183 +0,0 @@
|
||||
#ifndef CARDS_H
|
||||
#define CARDS_H
|
||||
|
||||
/*
|
||||
* 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, or (at
|
||||
* your option) any later version.
|
||||
*/
|
||||
|
||||
#include "nic.h"
|
||||
|
||||
/* OK, this is how the PCI support hack works: if pci.h is included before
|
||||
* this file is included, assume that the driver supports PCI. This means that
|
||||
* this file is usually included last. */
|
||||
|
||||
#ifdef PCI_H
|
||||
#define PCI_ARG(x) ,x
|
||||
#else
|
||||
#define PCI_ARG(x)
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_WD
|
||||
extern struct nic *wd_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_3C503
|
||||
extern struct nic *t503_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_VIA_RHINE
|
||||
extern struct nic *rhine_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_NE
|
||||
extern struct nic *ne_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_NS8390
|
||||
extern struct nic *nepci_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_3C509
|
||||
extern struct nic *t509_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_3C529
|
||||
extern struct nic *t529_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_3C595
|
||||
extern struct nic *t595_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_3C90X
|
||||
extern struct nic *a3c90x_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_EEPRO
|
||||
extern struct nic *eepro_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_EEPRO100
|
||||
extern struct nic *eepro100_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_EPIC100
|
||||
extern struct nic *epic100_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_OTULIP
|
||||
extern struct nic *otulip_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_TULIP
|
||||
extern struct nic *tulip_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_DAVICOM
|
||||
extern struct nic *davicom_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_CS89X0
|
||||
extern struct nic *cs89x0_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_LANCE
|
||||
extern struct nic *lancepci_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_NE2100
|
||||
extern struct nic *ne2100_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_NI6510
|
||||
extern struct nic *ni6510_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_SK_G16
|
||||
extern struct nic *SK_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_3C507
|
||||
extern struct nic *t507_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_NI5010
|
||||
extern struct nic *ni5010_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_NI5210
|
||||
extern struct nic *ni5210_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_EXOS205
|
||||
extern struct nic *exos205_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_SMC9000
|
||||
extern struct nic *smc9000_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_TIARA
|
||||
extern struct nic *tiara_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_DEPCA
|
||||
extern struct nic *depca_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_RTL8139
|
||||
extern struct nic *rtl8139_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_W89C840
|
||||
extern struct nic *w89c840_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_SIS900
|
||||
extern struct nic *sis900_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_NATSEMI
|
||||
extern struct nic *natsemi_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_TLAN
|
||||
extern struct nic *tlan_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
#endif /* CARDS_H */
|
||||
@@ -1,598 +0,0 @@
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2001,2002 Free Software Foundation, Inc.
|
||||
*
|
||||
* 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
|
||||
* (at your option) 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.
|
||||
*/
|
||||
|
||||
/* Based on "src/config.c" in etherboot-5.0.5. */
|
||||
|
||||
/*
|
||||
* 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, or (at
|
||||
* your option) any later version.
|
||||
*/
|
||||
|
||||
#define GRUB 1
|
||||
#include <etherboot.h>
|
||||
#include <nic.h>
|
||||
|
||||
#undef INCLUDE_PCI
|
||||
#if defined(INCLUDE_NS8390) || defined(INCLUDE_EEPRO100) || defined(INCLUDE_LANCE) || defined(INCLUDE_EPIC100) || defined(INCLUDE_TULIP) || defined(INCLUDE_OTULIP) || defined(INCLUDE_3C90X) || defined(INCLUDE_3C595) || defined(INCLUDE_RTL8139) || defined(INCLUDE_VIA_RHINE) || defined(INCLUDE_W89C840) || defined(INCLUDE_DAVICOM) || defined(INCLUDE_SIS900) || defined(INCLUDE_NATSEMI) || defined(INCLUDE_TLAN)
|
||||
/* || others later */
|
||||
# define INCLUDE_PCI
|
||||
# include <pci.h>
|
||||
static unsigned short pci_ioaddrs[16];
|
||||
|
||||
static struct pci_device pci_nic_list[] =
|
||||
{
|
||||
#ifdef INCLUDE_NS8390
|
||||
{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8029,
|
||||
"Realtek 8029", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940,
|
||||
"Winbond NE2000-PCI", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_RL2000,
|
||||
"Compex ReadyLink 2000", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_KTI, PCI_DEVICE_ID_KTI_ET32P2,
|
||||
"KTI ET32P2", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_NETVIN, PCI_DEVICE_ID_NETVIN_NV5000SC,
|
||||
"NetVin NV5000SC", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_HT80232,
|
||||
"Holtek HT80232", 0, 0, 0, 0},
|
||||
#endif
|
||||
#ifdef INCLUDE_3C90X
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900TPO,
|
||||
"3Com900-TPO", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900COMBO,
|
||||
"3Com900-Combo", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905TX,
|
||||
"3Com905-TX", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905T4,
|
||||
"3Com905-T4", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x9004,
|
||||
"3Com900B-TPO", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x9005,
|
||||
"3Com900B-Combo", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x9006,
|
||||
"3Com900B-2/T", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x900A,
|
||||
"3Com900B-FL", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905B_TX,
|
||||
"3Com905B-TX", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x9056,
|
||||
"3Com905B-T4", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x905A,
|
||||
"3Com905B-FL", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905C_TXM,
|
||||
"3Com905C-TXM", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x9800,
|
||||
"3Com980-Cyclone", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x9805,
|
||||
"3Com9805", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x7646,
|
||||
"3CSOHO100-TX", 0, 0, 0, 0},
|
||||
#endif
|
||||
#ifdef INCLUDE_3C595
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C590,
|
||||
"3Com590", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595,
|
||||
"3Com595", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595_1,
|
||||
"3Com595", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595_2,
|
||||
"3Com595", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900TPO,
|
||||
"3Com900-TPO", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900COMBO,
|
||||
"3Com900-Combo", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x9004,
|
||||
"3Com900B-TPO", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x9005,
|
||||
"3Com900B-Combo", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x9006,
|
||||
"3Com900B-2/T", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x900A,
|
||||
"3Com900B-FL", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x9800,
|
||||
"3Com980-Cyclone", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x9805,
|
||||
"3Com9805", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x7646,
|
||||
"3CSOHO100-TX", 0, 0, 0, 0},
|
||||
#endif
|
||||
#ifdef INCLUDE_EEPRO100
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557,
|
||||
"Intel EtherExpressPro100", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER,
|
||||
"Intel EtherExpressPro100 82559ER", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1029,
|
||||
"Intel EtherExpressPro100 ID1029", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1030,
|
||||
"Intel Corporation 82559 InBusiness 10/100", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82562,
|
||||
"Intel EtherExpressPro100 82562EM", 0, 0, 0, 0},
|
||||
#endif
|
||||
#ifdef INCLUDE_EPIC100
|
||||
{ PCI_VENDOR_ID_SMC, PCI_DEVICE_ID_SMC_EPIC100,
|
||||
"SMC EtherPowerII", 0, 0, 0, 0},
|
||||
#endif
|
||||
#ifdef INCLUDE_LANCE
|
||||
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE,
|
||||
"AMD Lance/PCI", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_AMD_HOMEPNA, PCI_DEVICE_ID_AMD_HOMEPNA,
|
||||
"AMD Lance/HomePNA", 0, 0, 0, 0},
|
||||
#endif
|
||||
#ifdef INCLUDE_RTL8139
|
||||
{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139,
|
||||
"Realtek 8139", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DFE530TXP,
|
||||
"DFE530TX+/DFE538TX", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_SMC_1211, PCI_DEVICE_ID_SMC_1211,
|
||||
"SMC EZ10/100", 0, 0, 0, 0},
|
||||
#endif
|
||||
#ifdef INCLUDE_OTULIP
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP,
|
||||
"Digital Tulip", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
|
||||
"Digital Tulip Fast", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_PLUS,
|
||||
"Digital Tulip+", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
|
||||
"Digital Tulip 21142", 0, 0, 0, 0},
|
||||
#endif
|
||||
#ifdef INCLUDE_TULIP
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP,
|
||||
"Digital Tulip", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
|
||||
"Digital Tulip Fast", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_PLUS,
|
||||
"Digital Tulip+", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
|
||||
"Digital Tulip 21142", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_MACRONIX, PCI_DEVICE_ID_MX987x5,
|
||||
"Macronix MX987x5", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LC82C115,
|
||||
"LinkSys LNE100TX", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_DEC_TULIP,
|
||||
"Netgear FA310TX", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9102,
|
||||
"Davicom 9102", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9009,
|
||||
"Davicom 9009", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_ADMTEK, PCI_DEVICE_ID_ADMTEK_0985,
|
||||
"ADMtek Centaur-P", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_ADMTEK, 0x0981,
|
||||
"ADMtek AN981 Comet", 0, 0, 0, 0},
|
||||
{ 0x125B, 0x1400,
|
||||
"ASIX AX88140", 0, 0, 0, 0 },
|
||||
{ 0x11F6, 0x9881,
|
||||
"Compex RL100-TX", 0, 0, 0, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_DAVICOM
|
||||
{ PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9102,
|
||||
"Davicom 9102", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9009,
|
||||
"Davicom 9009", 0, 0, 0, 0},
|
||||
#endif
|
||||
#ifdef INCLUDE_VIA_RHINE
|
||||
{ PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_VT6102,
|
||||
"VIA 6102", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_RHINE_I,
|
||||
"VIA 3043", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_86C100A,
|
||||
"VIA 86C100A", 0, 0, 0, 0},
|
||||
#endif
|
||||
#ifdef INCLUDE_W89C840
|
||||
{ PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C840,
|
||||
"Winbond W89C840F", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_RL100ATX,
|
||||
"Compex RL100ATX", 0, 0, 0, 0},
|
||||
#endif
|
||||
#ifdef INCLUDE_SIS900
|
||||
{ PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS900,
|
||||
"SIS900", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS7016,
|
||||
"SIS7016", 0, 0, 0, 0},
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_NATSEMI
|
||||
{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_DP83815,
|
||||
"DP83815", 0, 0, 0, 0},
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_TLAN
|
||||
{ PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2326,
|
||||
"OC2326", 0, 0, 0, 0},
|
||||
#endif
|
||||
|
||||
/* other PCI NICs go here */
|
||||
{0, 0, NULL, 0, 0, 0, 0}
|
||||
};
|
||||
#endif /* INCLUDE_*PCI */
|
||||
|
||||
#include <cards.h>
|
||||
|
||||
#ifdef INCLUDE_PCI
|
||||
struct pci_dispatch_table
|
||||
{
|
||||
unsigned short vendor;
|
||||
unsigned short dev_id;
|
||||
struct nic *(*eth_probe) (struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
};
|
||||
|
||||
static struct pci_dispatch_table PCI_NIC[] =
|
||||
{
|
||||
# ifdef INCLUDE_NS8390
|
||||
{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8029, nepci_probe },
|
||||
{ PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940, nepci_probe },
|
||||
{ PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_RL2000, nepci_probe },
|
||||
{ PCI_VENDOR_ID_KTI, PCI_DEVICE_ID_KTI_ET32P2, nepci_probe },
|
||||
{ PCI_VENDOR_ID_NETVIN, PCI_DEVICE_ID_NETVIN_NV5000SC, nepci_probe },
|
||||
{ PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_HT80232, nepci_probe },
|
||||
# endif /* INCLUDE_NS8390 */
|
||||
# ifdef INCLUDE_3C90X
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900TPO, a3c90x_probe },
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900COMBO, a3c90x_probe },
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905TX, a3c90x_probe },
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905T4, a3c90x_probe },
|
||||
{ PCI_VENDOR_ID_3COM, 0x9004, a3c90x_probe },
|
||||
{ PCI_VENDOR_ID_3COM, 0x9005, a3c90x_probe },
|
||||
{ PCI_VENDOR_ID_3COM, 0x9006, a3c90x_probe },
|
||||
{ PCI_VENDOR_ID_3COM, 0x900A, a3c90x_probe },
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905B_TX, a3c90x_probe },
|
||||
{ PCI_VENDOR_ID_3COM, 0x9056, a3c90x_probe },
|
||||
{ PCI_VENDOR_ID_3COM, 0x905A, a3c90x_probe },
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905C_TXM, a3c90x_probe },
|
||||
{ PCI_VENDOR_ID_3COM, 0x9800, a3c90x_probe },
|
||||
{ PCI_VENDOR_ID_3COM, 0x9805, a3c90x_probe },
|
||||
{ PCI_VENDOR_ID_3COM, 0x7646, a3c90x_probe },
|
||||
# endif /* INCLUDE_3C90X */
|
||||
# ifdef INCLUDE_3C595
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C590, t595_probe },
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595, t595_probe },
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595_1, t595_probe },
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595_2, t595_probe },
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900TPO, t595_probe },
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900COMBO, t595_probe },
|
||||
{ PCI_VENDOR_ID_3COM, 0x9004, t595_probe },
|
||||
{ PCI_VENDOR_ID_3COM, 0x9005, t595_probe },
|
||||
{ PCI_VENDOR_ID_3COM, 0x9006, t595_probe },
|
||||
{ PCI_VENDOR_ID_3COM, 0x900A, t595_probe },
|
||||
{ PCI_VENDOR_ID_3COM, 0x9800, t595_probe },
|
||||
{ PCI_VENDOR_ID_3COM, 0x9805, t595_probe },
|
||||
{ PCI_VENDOR_ID_3COM, 0x7646, t595_probe },
|
||||
# endif /* INCLUDE_3C595 */
|
||||
# ifdef INCLUDE_EEPRO100
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557, eepro100_probe },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER, eepro100_probe },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1029, eepro100_probe },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1030, eepro100_probe },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82562, eepro100_probe },
|
||||
# endif /* INCLUDE_EEPRO100 */
|
||||
# ifdef INCLUDE_EPIC100
|
||||
{ PCI_VENDOR_ID_SMC, PCI_DEVICE_ID_SMC_EPIC100, epic100_probe },
|
||||
# endif /* INCLUDE_EPIC100 */
|
||||
# ifdef INCLUDE_LANCE
|
||||
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, lancepci_probe },
|
||||
{ PCI_VENDOR_ID_AMD_HOMEPNA, PCI_DEVICE_ID_AMD_HOMEPNA, lancepci_probe },
|
||||
# endif /* INCLUDE_LANCE */
|
||||
# ifdef INCLUDE_RTL8139
|
||||
{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139, rtl8139_probe },
|
||||
{ PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DFE530TXP, rtl8139_probe },
|
||||
{ PCI_VENDOR_ID_SMC_1211, PCI_DEVICE_ID_SMC_1211, rtl8139_probe },
|
||||
# endif /* INCLUDE_RTL8139 */
|
||||
# ifdef INCLUDE_OTULIP
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP, otulip_probe },
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST, otulip_probe },
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_PLUS, otulip_probe },
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, otulip_probe },
|
||||
# endif /* INCLUDE_OTULIP */
|
||||
# ifdef INCLUDE_TULIP
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP, tulip_probe },
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST, tulip_probe },
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_PLUS, tulip_probe },
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, tulip_probe },
|
||||
{ PCI_VENDOR_ID_MACRONIX, PCI_DEVICE_ID_MX987x5, tulip_probe },
|
||||
{ PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LC82C115, tulip_probe },
|
||||
{ PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_DEC_TULIP, tulip_probe },
|
||||
{ PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9102, tulip_probe },
|
||||
{ PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9009, tulip_probe },
|
||||
{ PCI_VENDOR_ID_ADMTEK, PCI_DEVICE_ID_ADMTEK_0985, tulip_probe },
|
||||
{ PCI_VENDOR_ID_ADMTEK, 0x0981, tulip_probe },
|
||||
{ 0x125B, 0x1400, tulip_probe },
|
||||
{ 0x11F6, 0x9881, tulip_probe },
|
||||
# endif /* INCLUDE_TULIP */
|
||||
# ifdef INCLUDE_DAVICOM
|
||||
{ PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9102, davicom_probe },
|
||||
{ PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9009, davicom_probe },
|
||||
# endif /* INCLUDE_DAVICOM */
|
||||
# ifdef INCLUDE_VIA_RHINE
|
||||
{ PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_VT6102, rhine_probe },
|
||||
{ PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_RHINE_I, rhine_probe },
|
||||
{ PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_86C100A, rhine_probe },
|
||||
# endif /* INCLUDE_VIA_RHINE */
|
||||
# ifdef INCLUDE_W89C840
|
||||
{ PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C840, w89c840_probe },
|
||||
{ PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_RL100ATX, w89c840_probe },
|
||||
# endif /* INCLUDE_W89C840 */
|
||||
# ifdef INCLUDE_SIS900
|
||||
{ PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS900, sis900_probe },
|
||||
{ PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS7016, sis900_probe },
|
||||
# endif /* INCLUDE_SIS900 */
|
||||
# ifdef INCLUDE_NATSEMI
|
||||
{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_DP83815, natsemi_probe },
|
||||
# endif /* INCLUDE_NATSEMI */
|
||||
# ifdef INCLUDE_TLAN
|
||||
{ PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2326, tlan_probe },
|
||||
# endif /* INCLUDE_TLAN */
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
#endif /* GRUB && INCLUDE_PCI */
|
||||
|
||||
struct dispatch_table
|
||||
{
|
||||
const char *nic_name;
|
||||
#ifdef INCLUDE_PCI
|
||||
struct nic *(*eth_probe) (struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#else
|
||||
struct nic *(*eth_probe) (struct nic *, unsigned short *);
|
||||
#endif /* INCLUDE_PCI */
|
||||
unsigned short *probe_ioaddrs; /* for probe overrides */
|
||||
};
|
||||
|
||||
/*
|
||||
* NIC probing is in order of appearance in this table.
|
||||
* If for some reason you want to change the order,
|
||||
* just rearrange the entries (bracketed by the #ifdef/#endif)
|
||||
*/
|
||||
static struct dispatch_table NIC[] =
|
||||
{
|
||||
#ifdef INCLUDE_RTL8139
|
||||
{ "RTL8139", rtl8139_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_SIS900
|
||||
{ "SIS900", sis900_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_NATSEMI
|
||||
{ "NATSEMI", natsemi_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_WD
|
||||
{ "WD", wd_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_3C503
|
||||
{ "3C503", t503_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_NE
|
||||
{ "NE*000", ne_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_3C509
|
||||
{ "3C5x9", t509_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_3C529
|
||||
{ "3C5x9", t529_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_3C595
|
||||
{ "3C595", t595_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_3C90X
|
||||
{ "3C90X", a3c90x_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_EEPRO
|
||||
{ "EEPRO", eepro_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_EEPRO100
|
||||
{ "EEPRO100", eepro100_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_EPIC100
|
||||
{ "EPIC100", epic100_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_OTULIP
|
||||
{ "OTulip", otulip_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_TULIP
|
||||
{ "Tulip", tulip_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_DAVICOM
|
||||
{ "DAVICOM", davicom_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_CS89X0
|
||||
{ "CS89x0", cs89x0_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_NE2100
|
||||
{ "NE2100", ne2100_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_NI6510
|
||||
{ "NI6510", ni6510_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_SK_G16
|
||||
{ "SK_G16", SK_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_3C507
|
||||
{ "3C507", t507_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_NI5010
|
||||
{ "NI5010", ni5010_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_NI5210
|
||||
{ "NI5210", ni5210_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_EXOS205
|
||||
{ "EXOS205", exos205_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_SMC9000
|
||||
{ "SMC9000", smc9000_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_TIARA
|
||||
{ "TIARA", tiara_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_DEPCA
|
||||
{ "DEPCA", depca_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_NS8390
|
||||
{ "NE2000/PCI", nepci_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_LANCE
|
||||
{ "LANCE/PCI", lancepci_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_VIA_RHINE
|
||||
{ "VIA 86C100", rhine_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_W89C840
|
||||
{ "W89C840F", w89c840_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_TLAN
|
||||
{ "Olicom 2326", tlan_probe, pci_ioaddrs },
|
||||
#endif
|
||||
/* this entry must always be last to mark the end of list */
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
#define NIC_TABLE_SIZE (sizeof (NIC) / sizeof (NIC[0]))
|
||||
|
||||
static int
|
||||
eth_dummy (struct nic *dummy)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char packet[ETH_FRAME_LEN];
|
||||
|
||||
struct nic nic =
|
||||
{
|
||||
(void (*) (struct nic *)) eth_dummy, /* reset */
|
||||
eth_dummy, /* poll */
|
||||
(void (*) (struct nic *, const char *,
|
||||
unsigned int, unsigned int,
|
||||
const char *)) eth_dummy, /* transmit */
|
||||
(void (*) (struct nic *)) eth_dummy, /* disable */
|
||||
#ifdef T503_AUI
|
||||
1, /* aui */
|
||||
#else
|
||||
0, /* no aui */
|
||||
#endif
|
||||
&rom, /* rom_info */
|
||||
arptable[ARP_CLIENT].node, /* node_addr */
|
||||
packet, /* packet */
|
||||
0, /* packetlen */
|
||||
0, /* priv_data */
|
||||
};
|
||||
|
||||
void
|
||||
eth_reset (void)
|
||||
{
|
||||
(*nic.reset) (&nic);
|
||||
}
|
||||
|
||||
int
|
||||
eth_probe (void)
|
||||
{
|
||||
struct pci_device *p;
|
||||
const struct dispatch_table *t;
|
||||
static int probed = 0;
|
||||
|
||||
/* If already probed, don't try to probe it any longer. */
|
||||
if (probed)
|
||||
return 1;
|
||||
|
||||
/* Clear the ready flag. */
|
||||
network_ready = 0;
|
||||
/* Clear the ARP table. */
|
||||
grub_memset ((char *) arptable, 0,
|
||||
MAX_ARP * sizeof (struct arptable_t));
|
||||
|
||||
p = 0;
|
||||
|
||||
#ifdef INCLUDE_PCI
|
||||
/* In GRUB, the ROM info is initialized here. */
|
||||
rom = *((struct rom_info *) ROM_INFO_LOCATION);
|
||||
|
||||
eth_pci_init(pci_nic_list);
|
||||
pci_ioaddrs[0] = 0;
|
||||
pci_ioaddrs[1] = 0;
|
||||
/* at this point we have a list of possible PCI candidates
|
||||
we just pick the first one with a non-zero ioaddr */
|
||||
for (p = pci_nic_list; p->vendor != 0; ++p)
|
||||
{
|
||||
if (p->ioaddr != 0)
|
||||
{
|
||||
pci_ioaddrs[0] = p->ioaddr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
etherboot_printf("Probing...");
|
||||
|
||||
#ifdef INCLUDE_PCI
|
||||
if (p->vendor)
|
||||
{
|
||||
struct pci_dispatch_table *pt;
|
||||
|
||||
for (pt = PCI_NIC; pt->eth_probe != 0; pt++)
|
||||
if (p->vendor == pt->vendor && p->dev_id == pt->dev_id)
|
||||
{
|
||||
etherboot_printf ("[%s]", p->name);
|
||||
if ((pt->eth_probe) (&nic, pci_ioaddrs, p))
|
||||
{
|
||||
probed = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* INCLUDE_PCI */
|
||||
|
||||
for (t = NIC; t->nic_name != 0; ++t)
|
||||
{
|
||||
etherboot_printf("[%s]", t->nic_name);
|
||||
#ifdef INCLUDE_PCI
|
||||
if ((*t->eth_probe) (&nic, t->probe_ioaddrs, p))
|
||||
{
|
||||
probed = 1;
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
if ((*t->eth_probe) (&nic, t->probe_ioaddrs))
|
||||
{
|
||||
probed = 1;
|
||||
return 1;
|
||||
}
|
||||
#endif /* INCLUDE_PCI */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
eth_poll (void)
|
||||
{
|
||||
return ((*nic.poll) (&nic));
|
||||
}
|
||||
|
||||
void
|
||||
eth_transmit (const char *d, unsigned int t, unsigned int s, const void *p)
|
||||
{
|
||||
(*nic.transmit) (&nic, d, t, s, p);
|
||||
if (t == IP)
|
||||
twiddle ();
|
||||
}
|
||||
|
||||
void
|
||||
eth_disable (void)
|
||||
{
|
||||
(*nic.disable) (&nic);
|
||||
}
|
||||
@@ -1,677 +0,0 @@
|
||||
/**
|
||||
Per an email message from Russ Nelson <nelson@crynwr.com> on
|
||||
18 March 2008 this file is now licensed under GPL Version 2.
|
||||
|
||||
From: Russ Nelson <nelson@crynwr.com>
|
||||
Date: Tue, 18 Mar 2008 12:42:00 -0400
|
||||
Subject: Re: [Etherboot-developers] cs89x0 driver in etherboot
|
||||
-- quote from email
|
||||
As copyright holder, if I say it doesn't conflict with the GPL,
|
||||
then it doesn't conflict with the GPL.
|
||||
|
||||
However, there's no point in causing people's brains to overheat,
|
||||
so yes, I grant permission for the code to be relicensed under the
|
||||
GPLv2. Please make sure that this change in licensing makes its
|
||||
way upstream. -russ
|
||||
-- quote from email
|
||||
**/
|
||||
|
||||
/* cs89x0.c: A Crystal Semiconductor CS89[02]0 driver for etherboot. */
|
||||
/*
|
||||
Permission is granted to distribute the enclosed cs89x0.[ch] driver
|
||||
only in conjunction with the Etherboot package. The code is
|
||||
ordinarily distributed under the GPL.
|
||||
|
||||
Russ Nelson, January 2000
|
||||
|
||||
ChangeLog:
|
||||
|
||||
Thu Dec 6 22:40:00 1996 Markus Gutschke <gutschk@math.uni-muenster.de>
|
||||
|
||||
* disabled all "advanced" features; this should make the code more reliable
|
||||
|
||||
* reorganized the reset function
|
||||
|
||||
* always reset the address port, so that autoprobing will continue working
|
||||
|
||||
* some cosmetic changes
|
||||
|
||||
* 2.5
|
||||
|
||||
Thu Dec 5 21:00:00 1996 Markus Gutschke <gutschk@math.uni-muenster.de>
|
||||
|
||||
* tested the code against a CS8900 card
|
||||
|
||||
* lots of minor bug fixes and adjustments
|
||||
|
||||
* this is the first release, that actually works! it still requires some
|
||||
changes in order to be more tolerant to different environments
|
||||
|
||||
* 4
|
||||
|
||||
Fri Nov 22 23:00:00 1996 Markus Gutschke <gutschk@math.uni-muenster.de>
|
||||
|
||||
* read the manuals for the CS89x0 chipsets and took note of all the
|
||||
changes that will be neccessary in order to adapt Russel Nelson's code
|
||||
to the requirements of a BOOT-Prom
|
||||
|
||||
* 6
|
||||
|
||||
Thu Nov 19 22:00:00 1996 Markus Gutschke <gutschk@math.uni-muenster.de>
|
||||
|
||||
* Synched with Russel Nelson's current code (v1.00)
|
||||
|
||||
* 2
|
||||
|
||||
Thu Nov 12 18:00:00 1996 Markus Gutschke <gutschk@math.uni-muenster.de>
|
||||
|
||||
* Cleaned up some of the code and tried to optimize the code size.
|
||||
|
||||
* 1.5
|
||||
|
||||
Sun Nov 10 16:30:00 1996 Markus Gutschke <gutschk@math.uni-muenster.de>
|
||||
|
||||
* First experimental release. This code compiles fine, but I
|
||||
have no way of testing whether it actually works.
|
||||
|
||||
* I did not (yet) bother to make the code 16bit aware, so for
|
||||
the time being, it will only work for Etherboot/32.
|
||||
|
||||
* 12
|
||||
|
||||
*/
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "cards.h"
|
||||
#include "cs89x0.h"
|
||||
|
||||
static unsigned short eth_nic_base;
|
||||
static unsigned long eth_mem_start;
|
||||
static unsigned short eth_irq;
|
||||
static unsigned short eth_cs_type; /* one of: CS8900, CS8920, CS8920M */
|
||||
static unsigned short eth_auto_neg_cnf;
|
||||
static unsigned short eth_adapter_cnf;
|
||||
static unsigned short eth_linectl;
|
||||
|
||||
/*************************************************************************
|
||||
CS89x0 - specific routines
|
||||
**************************************************************************/
|
||||
|
||||
static inline int readreg(int portno)
|
||||
{
|
||||
outw(portno, eth_nic_base + ADD_PORT);
|
||||
return inw(eth_nic_base + DATA_PORT);
|
||||
}
|
||||
|
||||
static inline void writereg(int portno, int value)
|
||||
{
|
||||
outw(portno, eth_nic_base + ADD_PORT);
|
||||
outw(value, eth_nic_base + DATA_PORT);
|
||||
return;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
EEPROM access
|
||||
**************************************************************************/
|
||||
|
||||
static int wait_eeprom_ready(void)
|
||||
{
|
||||
unsigned long tmo = currticks() + 4*TICKS_PER_SEC;
|
||||
|
||||
/* check to see if the EEPROM is ready, a timeout is used -
|
||||
just in case EEPROM is ready when SI_BUSY in the
|
||||
PP_SelfST is clear */
|
||||
while(readreg(PP_SelfST) & SI_BUSY) {
|
||||
if (currticks() >= tmo)
|
||||
return -1; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_eeprom_data(int off, int len, unsigned short *buffer)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef EDEBUG
|
||||
printf("\ncs: EEPROM data from %hX for %hX:",off,len);
|
||||
#endif
|
||||
for (i = 0; i < len; i++) {
|
||||
if (wait_eeprom_ready() < 0)
|
||||
return -1;
|
||||
/* Now send the EEPROM read command and EEPROM location
|
||||
to read */
|
||||
writereg(PP_EECMD, (off + i) | EEPROM_READ_CMD);
|
||||
if (wait_eeprom_ready() < 0)
|
||||
return -1;
|
||||
buffer[i] = readreg(PP_EEData);
|
||||
#ifdef EDEBUG
|
||||
if (!(i%10))
|
||||
printf("\ncs: ");
|
||||
printf("%hX ", buffer[i]);
|
||||
#endif
|
||||
}
|
||||
#ifdef EDEBUG
|
||||
putchar('\n');
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int get_eeprom_chksum(int off, int len, unsigned short *buffer)
|
||||
{
|
||||
int i, cksum;
|
||||
|
||||
cksum = 0;
|
||||
for (i = 0; i < len; i++)
|
||||
cksum += buffer[i];
|
||||
cksum &= 0xffff;
|
||||
if (cksum == 0)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Activate all of the available media and probe for network
|
||||
**************************************************************************/
|
||||
|
||||
static void clrline(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
putchar('\r');
|
||||
for (i = 79; i--; ) putchar(' ');
|
||||
printf("\rcs: ");
|
||||
return;
|
||||
}
|
||||
|
||||
static void control_dc_dc(int on_not_off)
|
||||
{
|
||||
unsigned int selfcontrol;
|
||||
unsigned long tmo = currticks() + TICKS_PER_SEC;
|
||||
|
||||
/* control the DC to DC convertor in the SelfControl register. */
|
||||
selfcontrol = HCB1_ENBL; /* Enable the HCB1 bit as an output */
|
||||
if (((eth_adapter_cnf & A_CNF_DC_DC_POLARITY) != 0) ^ on_not_off)
|
||||
selfcontrol |= HCB1;
|
||||
else
|
||||
selfcontrol &= ~HCB1;
|
||||
writereg(PP_SelfCTL, selfcontrol);
|
||||
|
||||
/* Wait for the DC/DC converter to power up - 1000ms */
|
||||
while (currticks() < tmo);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int detect_tp(void)
|
||||
{
|
||||
unsigned long tmo;
|
||||
|
||||
/* Turn on the chip auto detection of 10BT/ AUI */
|
||||
|
||||
clrline(); printf("attempting %s:","TP");
|
||||
|
||||
/* If connected to another full duplex capable 10-Base-T card
|
||||
the link pulses seem to be lost when the auto detect bit in
|
||||
the LineCTL is set. To overcome this the auto detect bit
|
||||
will be cleared whilst testing the 10-Base-T interface.
|
||||
This would not be necessary for the sparrow chip but is
|
||||
simpler to do it anyway. */
|
||||
writereg(PP_LineCTL, eth_linectl &~ AUI_ONLY);
|
||||
control_dc_dc(0);
|
||||
|
||||
/* Delay for the hardware to work out if the TP cable is
|
||||
present - 150ms */
|
||||
for (tmo = currticks() + 4; currticks() < tmo; );
|
||||
|
||||
if ((readreg(PP_LineST) & LINK_OK) == 0)
|
||||
return 0;
|
||||
|
||||
if (eth_cs_type != CS8900) {
|
||||
|
||||
writereg(PP_AutoNegCTL, eth_auto_neg_cnf & AUTO_NEG_MASK);
|
||||
|
||||
if ((eth_auto_neg_cnf & AUTO_NEG_BITS) == AUTO_NEG_ENABLE) {
|
||||
printf(" negotiating duplex... ");
|
||||
while (readreg(PP_AutoNegST) & AUTO_NEG_BUSY) {
|
||||
if (currticks() - tmo > 40*TICKS_PER_SEC) {
|
||||
printf("time out ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (readreg(PP_AutoNegST) & FDX_ACTIVE)
|
||||
printf("using full duplex");
|
||||
else
|
||||
printf("using half duplex");
|
||||
}
|
||||
|
||||
return A_CNF_MEDIA_10B_T;
|
||||
}
|
||||
|
||||
/* send a test packet - return true if carrier bits are ok */
|
||||
static int send_test_pkt(struct nic *nic)
|
||||
{
|
||||
static unsigned char testpacket[] = { 0,0,0,0,0,0, 0,0,0,0,0,0,
|
||||
0, 46, /*A 46 in network order */
|
||||
0, 0, /*DSAP=0 & SSAP=0 fields */
|
||||
0xf3,0 /*Control (Test Req+P bit set)*/ };
|
||||
unsigned long tmo;
|
||||
|
||||
writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_TX_ON);
|
||||
|
||||
memcpy(testpacket, nic->node_addr, ETH_ALEN);
|
||||
memcpy(testpacket+ETH_ALEN, nic->node_addr, ETH_ALEN);
|
||||
|
||||
outw(TX_AFTER_ALL, eth_nic_base + TX_CMD_PORT);
|
||||
outw(ETH_ZLEN, eth_nic_base + TX_LEN_PORT);
|
||||
|
||||
/* Test to see if the chip has allocated memory for the packet */
|
||||
for (tmo = currticks() + 2;
|
||||
(readreg(PP_BusST) & READY_FOR_TX_NOW) == 0; )
|
||||
if (currticks() >= tmo)
|
||||
return(0);
|
||||
|
||||
/* Write the contents of the packet */
|
||||
outsw(eth_nic_base + TX_FRAME_PORT, testpacket,
|
||||
(ETH_ZLEN+1)>>1);
|
||||
|
||||
printf(" sending test packet ");
|
||||
/* wait a couple of timer ticks for packet to be received */
|
||||
for (tmo = currticks() + 2; currticks() < tmo; );
|
||||
|
||||
if ((readreg(PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) {
|
||||
printf("succeeded");
|
||||
return 1;
|
||||
}
|
||||
printf("failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int detect_aui(struct nic *nic)
|
||||
{
|
||||
clrline(); printf("attempting %s:","AUI");
|
||||
control_dc_dc(0);
|
||||
|
||||
writereg(PP_LineCTL, (eth_linectl & ~AUTO_AUI_10BASET) | AUI_ONLY);
|
||||
|
||||
if (send_test_pkt(nic)) {
|
||||
return A_CNF_MEDIA_AUI; }
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int detect_bnc(struct nic *nic)
|
||||
{
|
||||
clrline(); printf("attempting %s:","BNC");
|
||||
control_dc_dc(1);
|
||||
|
||||
writereg(PP_LineCTL, (eth_linectl & ~AUTO_AUI_10BASET) | AUI_ONLY);
|
||||
|
||||
if (send_test_pkt(nic)) {
|
||||
return A_CNF_MEDIA_10B_2; }
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
ETH_RESET - Reset adapter
|
||||
***************************************************************************/
|
||||
|
||||
static void cs89x0_reset(struct nic *nic)
|
||||
{
|
||||
int i;
|
||||
unsigned long reset_tmo;
|
||||
|
||||
writereg(PP_SelfCTL, readreg(PP_SelfCTL) | POWER_ON_RESET);
|
||||
|
||||
/* wait for two ticks; that is 2*55ms */
|
||||
for (reset_tmo = currticks() + 2; currticks() < reset_tmo; );
|
||||
|
||||
if (eth_cs_type != CS8900) {
|
||||
/* Hardware problem requires PNP registers to be reconfigured
|
||||
after a reset */
|
||||
if (eth_irq != 0xFFFF) {
|
||||
outw(PP_CS8920_ISAINT, eth_nic_base + ADD_PORT);
|
||||
outb(eth_irq, eth_nic_base + DATA_PORT);
|
||||
outb(0, eth_nic_base + DATA_PORT + 1); }
|
||||
|
||||
if (eth_mem_start) {
|
||||
outw(PP_CS8920_ISAMemB, eth_nic_base + ADD_PORT);
|
||||
outb((eth_mem_start >> 8) & 0xff, eth_nic_base + DATA_PORT);
|
||||
outb((eth_mem_start >> 24) & 0xff, eth_nic_base + DATA_PORT + 1); } }
|
||||
|
||||
/* Wait until the chip is reset */
|
||||
for (reset_tmo = currticks() + 2;
|
||||
(readreg(PP_SelfST) & INIT_DONE) == 0 &&
|
||||
currticks() < reset_tmo; );
|
||||
|
||||
/* disable interrupts and memory accesses */
|
||||
writereg(PP_BusCTL, 0);
|
||||
|
||||
/* set the ethernet address */
|
||||
for (i=0; i < ETH_ALEN/2; i++)
|
||||
writereg(PP_IA+i*2,
|
||||
nic->node_addr[i*2] |
|
||||
(nic->node_addr[i*2+1] << 8));
|
||||
|
||||
/* receive only error free packets addressed to this card */
|
||||
writereg(PP_RxCTL, DEF_RX_ACCEPT);
|
||||
|
||||
/* do not generate any interrupts on receive operations */
|
||||
writereg(PP_RxCFG, 0);
|
||||
|
||||
/* do not generate any interrupts on transmit operations */
|
||||
writereg(PP_TxCFG, 0);
|
||||
|
||||
/* do not generate any interrupts on buffer operations */
|
||||
writereg(PP_BufCFG, 0);
|
||||
|
||||
/* reset address port, so that autoprobing will keep working */
|
||||
outw(PP_ChipID, eth_nic_base + ADD_PORT);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
ETH_TRANSMIT - Transmit a frame
|
||||
***************************************************************************/
|
||||
|
||||
static void cs89x0_transmit(
|
||||
struct nic *nic,
|
||||
const char *d, /* Destination */
|
||||
unsigned int t, /* Type */
|
||||
unsigned int s, /* size */
|
||||
const char *p) /* Packet */
|
||||
{
|
||||
unsigned long tmo;
|
||||
int sr;
|
||||
|
||||
/* does this size have to be rounded??? please,
|
||||
somebody have a look in the specs */
|
||||
if ((sr = ((s + ETH_HLEN + 1)&~1)) < ETH_ZLEN)
|
||||
sr = ETH_ZLEN;
|
||||
|
||||
retry:
|
||||
/* initiate a transmit sequence */
|
||||
outw(TX_AFTER_ALL, eth_nic_base + TX_CMD_PORT);
|
||||
outw(sr, eth_nic_base + TX_LEN_PORT);
|
||||
|
||||
/* Test to see if the chip has allocated memory for the packet */
|
||||
if ((readreg(PP_BusST) & READY_FOR_TX_NOW) == 0) {
|
||||
/* Oops... this should not happen! */
|
||||
printf("cs: unable to send packet; retrying...\n");
|
||||
for (tmo = currticks() + 5*TICKS_PER_SEC; currticks() < tmo; );
|
||||
cs89x0_reset(nic);
|
||||
goto retry; }
|
||||
|
||||
/* Write the contents of the packet */
|
||||
outsw(eth_nic_base + TX_FRAME_PORT, d, ETH_ALEN/2);
|
||||
outsw(eth_nic_base + TX_FRAME_PORT, nic->node_addr,
|
||||
ETH_ALEN/2);
|
||||
outw(((t >> 8)&0xFF)|(t << 8), eth_nic_base + TX_FRAME_PORT);
|
||||
outsw(eth_nic_base + TX_FRAME_PORT, p, (s+1)/2);
|
||||
for (sr = sr/2 - (s+1)/2 - ETH_ALEN - 1; sr-- > 0;
|
||||
outw(0, eth_nic_base + TX_FRAME_PORT));
|
||||
|
||||
/* wait for transfer to succeed */
|
||||
for (tmo = currticks()+5*TICKS_PER_SEC;
|
||||
(s = readreg(PP_TxEvent)&~0x1F) == 0 && currticks() < tmo;)
|
||||
/* nothing */ ;
|
||||
if ((s & TX_SEND_OK_BITS) != TX_OK) {
|
||||
printf("\ntransmission error %#hX\n", s);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
ETH_POLL - Wait for a frame
|
||||
***************************************************************************/
|
||||
|
||||
static int cs89x0_poll(struct nic *nic)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = readreg(PP_RxEvent);
|
||||
|
||||
if ((status & RX_OK) == 0)
|
||||
return(0);
|
||||
|
||||
status = inw(eth_nic_base + RX_FRAME_PORT);
|
||||
nic->packetlen = inw(eth_nic_base + RX_FRAME_PORT);
|
||||
insw(eth_nic_base + RX_FRAME_PORT, nic->packet, nic->packetlen >> 1);
|
||||
if (nic->packetlen & 1)
|
||||
nic->packet[nic->packetlen-1] = inw(eth_nic_base + RX_FRAME_PORT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void cs89x0_disable(struct nic *nic)
|
||||
{
|
||||
cs89x0_reset(nic);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
ETH_PROBE - Look for an adapter
|
||||
***************************************************************************/
|
||||
|
||||
struct nic *cs89x0_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||
{
|
||||
static const unsigned int netcard_portlist[] = {
|
||||
#ifdef CS_SCAN
|
||||
CS_SCAN,
|
||||
#else /* use "conservative" default values for autoprobing */
|
||||
0x300,0x320,0x340,0x200,0x220,0x240,
|
||||
0x260,0x280,0x2a0,0x2c0,0x2e0,
|
||||
/* if that did not work, then be more aggressive */
|
||||
0x301,0x321,0x341,0x201,0x221,0x241,
|
||||
0x261,0x281,0x2a1,0x2c1,0x2e1,
|
||||
#endif
|
||||
0};
|
||||
|
||||
int i, result = -1;
|
||||
unsigned rev_type = 0, ioaddr, ioidx, isa_cnf, cs_revision;
|
||||
unsigned short eeprom_buff[CHKSUM_LEN];
|
||||
|
||||
|
||||
for (ioidx = 0; (ioaddr=netcard_portlist[ioidx++]) != 0; ) {
|
||||
/* if they give us an odd I/O address, then do ONE write to
|
||||
the address port, to get it back to address zero, where we
|
||||
expect to find the EISA signature word. */
|
||||
if (ioaddr & 1) {
|
||||
ioaddr &= ~1;
|
||||
if ((inw(ioaddr + ADD_PORT) & ADD_MASK) != ADD_SIG)
|
||||
continue;
|
||||
outw(PP_ChipID, ioaddr + ADD_PORT);
|
||||
}
|
||||
|
||||
if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG)
|
||||
continue;
|
||||
eth_nic_base = ioaddr;
|
||||
|
||||
/* get the chip type */
|
||||
rev_type = readreg(PRODUCT_ID_ADD);
|
||||
eth_cs_type = rev_type &~ REVISON_BITS;
|
||||
cs_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
|
||||
|
||||
printf("\ncs: cs89%c0%s rev %c, base %#hX",
|
||||
eth_cs_type==CS8900?'0':'2',
|
||||
eth_cs_type==CS8920M?"M":"",
|
||||
cs_revision,
|
||||
eth_nic_base);
|
||||
|
||||
/* First check to see if an EEPROM is attached*/
|
||||
if ((readreg(PP_SelfST) & EEPROM_PRESENT) == 0) {
|
||||
printf("\ncs: no EEPROM...\n");
|
||||
outw(PP_ChipID, eth_nic_base + ADD_PORT);
|
||||
continue; }
|
||||
else if (get_eeprom_data(START_EEPROM_DATA,CHKSUM_LEN,
|
||||
eeprom_buff) < 0) {
|
||||
printf("\ncs: EEPROM read failed...\n");
|
||||
outw(PP_ChipID, eth_nic_base + ADD_PORT);
|
||||
continue; }
|
||||
else if (get_eeprom_chksum(START_EEPROM_DATA,CHKSUM_LEN,
|
||||
eeprom_buff) < 0) {
|
||||
printf("\ncs: EEPROM checksum bad...\n");
|
||||
outw(PP_ChipID, eth_nic_base + ADD_PORT);
|
||||
continue; }
|
||||
|
||||
/* get transmission control word but keep the
|
||||
autonegotiation bits */
|
||||
eth_auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET/2];
|
||||
/* Store adapter configuration */
|
||||
eth_adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET/2];
|
||||
/* Store ISA configuration */
|
||||
isa_cnf = eeprom_buff[ISA_CNF_OFFSET/2];
|
||||
|
||||
/* store the initial memory base address */
|
||||
eth_mem_start = eeprom_buff[PACKET_PAGE_OFFSET/2] << 8;
|
||||
|
||||
printf("%s%s%s, addr ",
|
||||
(eth_adapter_cnf & A_CNF_10B_T)?", RJ-45":"",
|
||||
(eth_adapter_cnf & A_CNF_AUI)?", AUI":"",
|
||||
(eth_adapter_cnf & A_CNF_10B_2)?", BNC":"");
|
||||
|
||||
/* If this is a CS8900 then no pnp soft */
|
||||
if (eth_cs_type != CS8900 &&
|
||||
/* Check if the ISA IRQ has been set */
|
||||
(i = readreg(PP_CS8920_ISAINT) & 0xff,
|
||||
(i != 0 && i < CS8920_NO_INTS)))
|
||||
eth_irq = i;
|
||||
else {
|
||||
i = isa_cnf & INT_NO_MASK;
|
||||
if (eth_cs_type == CS8900) {
|
||||
/* the table that follows is dependent
|
||||
upon how you wired up your cs8900
|
||||
in your system. The table is the
|
||||
same as the cs8900 engineering demo
|
||||
board. irq_map also depends on the
|
||||
contents of the table. Also see
|
||||
write_irq, which is the reverse
|
||||
mapping of the table below. */
|
||||
if (i < 4) i = "\012\013\014\005"[i];
|
||||
else printf("\ncs: BUG: isa_config is %d\n", i); }
|
||||
eth_irq = i; }
|
||||
|
||||
/* Retrieve and print the ethernet address. */
|
||||
for (i=0; i<ETH_ALEN; i++) {
|
||||
nic->node_addr[i] = ((unsigned char *)eeprom_buff)[i];
|
||||
}
|
||||
printf("%!\n", nic->node_addr);
|
||||
|
||||
/* Set the LineCTL quintuplet based on adapter
|
||||
configuration read from EEPROM */
|
||||
if ((eth_adapter_cnf & A_CNF_EXTND_10B_2) &&
|
||||
(eth_adapter_cnf & A_CNF_LOW_RX_SQUELCH))
|
||||
eth_linectl = LOW_RX_SQUELCH;
|
||||
else
|
||||
eth_linectl = 0;
|
||||
|
||||
/* check to make sure that they have the "right"
|
||||
hardware available */
|
||||
switch(eth_adapter_cnf & A_CNF_MEDIA_TYPE) {
|
||||
case A_CNF_MEDIA_10B_T: result = eth_adapter_cnf & A_CNF_10B_T;
|
||||
break;
|
||||
case A_CNF_MEDIA_AUI: result = eth_adapter_cnf & A_CNF_AUI;
|
||||
break;
|
||||
case A_CNF_MEDIA_10B_2: result = eth_adapter_cnf & A_CNF_10B_2;
|
||||
break;
|
||||
default: result = eth_adapter_cnf & (A_CNF_10B_T | A_CNF_AUI |
|
||||
A_CNF_10B_2);
|
||||
}
|
||||
if (!result) {
|
||||
printf("cs: EEPROM is configured for unavailable media\n");
|
||||
error:
|
||||
writereg(PP_LineCTL, readreg(PP_LineCTL) &
|
||||
~(SERIAL_TX_ON | SERIAL_RX_ON));
|
||||
outw(PP_ChipID, eth_nic_base + ADD_PORT);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Initialize the card for probing of the attached media */
|
||||
cs89x0_reset(nic);
|
||||
|
||||
/* set the hardware to the configured choice */
|
||||
switch(eth_adapter_cnf & A_CNF_MEDIA_TYPE) {
|
||||
case A_CNF_MEDIA_10B_T:
|
||||
result = detect_tp();
|
||||
if (!result) {
|
||||
clrline();
|
||||
printf("10Base-T (RJ-45%s",
|
||||
") has no cable\n"); }
|
||||
/* check "ignore missing media" bit */
|
||||
if (eth_auto_neg_cnf & IMM_BIT)
|
||||
/* Yes! I don't care if I see a link pulse */
|
||||
result = A_CNF_MEDIA_10B_T;
|
||||
break;
|
||||
case A_CNF_MEDIA_AUI:
|
||||
result = detect_aui(nic);
|
||||
if (!result) {
|
||||
clrline();
|
||||
printf("10Base-5 (AUI%s",
|
||||
") has no cable\n"); }
|
||||
/* check "ignore missing media" bit */
|
||||
if (eth_auto_neg_cnf & IMM_BIT)
|
||||
/* Yes! I don't care if I see a carrrier */
|
||||
result = A_CNF_MEDIA_AUI;
|
||||
break;
|
||||
case A_CNF_MEDIA_10B_2:
|
||||
result = detect_bnc(nic);
|
||||
if (!result) {
|
||||
clrline();
|
||||
printf("10Base-2 (BNC%s",
|
||||
") has no cable\n"); }
|
||||
/* check "ignore missing media" bit */
|
||||
if (eth_auto_neg_cnf & IMM_BIT)
|
||||
/* Yes! I don't care if I can xmit a packet */
|
||||
result = A_CNF_MEDIA_10B_2;
|
||||
break;
|
||||
case A_CNF_MEDIA_AUTO:
|
||||
writereg(PP_LineCTL, eth_linectl | AUTO_AUI_10BASET);
|
||||
if (eth_adapter_cnf & A_CNF_10B_T)
|
||||
if ((result = detect_tp()) != 0)
|
||||
break;
|
||||
if (eth_adapter_cnf & A_CNF_AUI)
|
||||
if ((result = detect_aui(nic)) != 0)
|
||||
break;
|
||||
if (eth_adapter_cnf & A_CNF_10B_2)
|
||||
if ((result = detect_bnc(nic)) != 0)
|
||||
break;
|
||||
clrline(); printf("no media detected\n");
|
||||
goto error;
|
||||
}
|
||||
clrline();
|
||||
switch(result) {
|
||||
case 0: printf("no network cable attached to configured media\n");
|
||||
goto error;
|
||||
case A_CNF_MEDIA_10B_T: printf("using 10Base-T (RJ-45)\n");
|
||||
break;
|
||||
case A_CNF_MEDIA_AUI: printf("using 10Base-5 (AUI)\n");
|
||||
break;
|
||||
case A_CNF_MEDIA_10B_2: printf("using 10Base-2 (BNC)\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Turn on both receive and transmit operations */
|
||||
writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_RX_ON |
|
||||
SERIAL_TX_ON);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (ioaddr == 0)
|
||||
return (0);
|
||||
nic->reset = cs89x0_reset;
|
||||
nic->poll = cs89x0_poll;
|
||||
nic->transmit = cs89x0_transmit;
|
||||
nic->disable = cs89x0_disable;
|
||||
return (nic);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
||||
|
||||
@@ -1,479 +0,0 @@
|
||||
/**
|
||||
Per an email message from Russ Nelson <nelson@crynwr.com> on
|
||||
18 March 2008 this file is now licensed under GPL Version 2.
|
||||
|
||||
From: Russ Nelson <nelson@crynwr.com>
|
||||
Date: Tue, 18 Mar 2008 12:42:00 -0400
|
||||
Subject: Re: [Etherboot-developers] cs89x0 driver in etherboot
|
||||
-- quote from email
|
||||
As copyright holder, if I say it doesn't conflict with the GPL,
|
||||
then it doesn't conflict with the GPL.
|
||||
|
||||
However, there's no point in causing people's brains to overheat,
|
||||
so yes, I grant permission for the code to be relicensed under the
|
||||
GPLv2. Please make sure that this change in licensing makes its
|
||||
way upstream. -russ
|
||||
-- quote from email
|
||||
**/
|
||||
|
||||
/* Copyright, 1988-1992, Russell Nelson, Crynwr Software
|
||||
|
||||
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, version 1.
|
||||
|
||||
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. */
|
||||
|
||||
#define PP_ChipID 0x0000 /* offset 0h -> Corp -ID */
|
||||
/* offset 2h -> Model/Product Number */
|
||||
/* offset 3h -> Chip Revision Number */
|
||||
|
||||
#define PP_ISAIOB 0x0020 /* IO base address */
|
||||
#define PP_CS8900_ISAINT 0x0022 /* ISA interrupt select */
|
||||
#define PP_CS8920_ISAINT 0x0370 /* ISA interrupt select */
|
||||
#define PP_CS8900_ISADMA 0x0024 /* ISA Rec DMA channel */
|
||||
#define PP_CS8920_ISADMA 0x0374 /* ISA Rec DMA channel */
|
||||
#define PP_ISASOF 0x0026 /* ISA DMA offset */
|
||||
#define PP_DmaFrameCnt 0x0028 /* ISA DMA Frame count */
|
||||
#define PP_DmaByteCnt 0x002A /* ISA DMA Byte count */
|
||||
#define PP_CS8900_ISAMemB 0x002C /* Memory base */
|
||||
#define PP_CS8920_ISAMemB 0x0348 /* */
|
||||
|
||||
#define PP_ISABootBase 0x0030 /* Boot Prom base */
|
||||
#define PP_ISABootMask 0x0034 /* Boot Prom Mask */
|
||||
|
||||
/* EEPROM data and command registers */
|
||||
#define PP_EECMD 0x0040 /* NVR Interface Command register */
|
||||
#define PP_EEData 0x0042 /* NVR Interface Data Register */
|
||||
#define PP_DebugReg 0x0044 /* Debug Register */
|
||||
|
||||
#define PP_RxCFG 0x0102 /* Rx Bus config */
|
||||
#define PP_RxCTL 0x0104 /* Receive Control Register */
|
||||
#define PP_TxCFG 0x0106 /* Transmit Config Register */
|
||||
#define PP_TxCMD 0x0108 /* Transmit Command Register */
|
||||
#define PP_BufCFG 0x010A /* Bus configuration Register */
|
||||
#define PP_LineCTL 0x0112 /* Line Config Register */
|
||||
#define PP_SelfCTL 0x0114 /* Self Command Register */
|
||||
#define PP_BusCTL 0x0116 /* ISA bus control Register */
|
||||
#define PP_TestCTL 0x0118 /* Test Register */
|
||||
#define PP_AutoNegCTL 0x011C /* Auto Negotiation Ctrl */
|
||||
|
||||
#define PP_ISQ 0x0120 /* Interrupt Status */
|
||||
#define PP_RxEvent 0x0124 /* Rx Event Register */
|
||||
#define PP_TxEvent 0x0128 /* Tx Event Register */
|
||||
#define PP_BufEvent 0x012C /* Bus Event Register */
|
||||
#define PP_RxMiss 0x0130 /* Receive Miss Count */
|
||||
#define PP_TxCol 0x0132 /* Transmit Collision Count */
|
||||
#define PP_LineST 0x0134 /* Line State Register */
|
||||
#define PP_SelfST 0x0136 /* Self State register */
|
||||
#define PP_BusST 0x0138 /* Bus Status */
|
||||
#define PP_TDR 0x013C /* Time Domain Reflectometry */
|
||||
#define PP_AutoNegST 0x013E /* Auto Neg Status */
|
||||
#define PP_TxCommand 0x0144 /* Tx Command */
|
||||
#define PP_TxLength 0x0146 /* Tx Length */
|
||||
#define PP_LAF 0x0150 /* Hash Table */
|
||||
#define PP_IA 0x0158 /* Physical Address Register */
|
||||
|
||||
#define PP_RxStatus 0x0400 /* Receive start of frame */
|
||||
#define PP_RxLength 0x0402 /* Receive Length of frame */
|
||||
#define PP_RxFrame 0x0404 /* Receive frame pointer */
|
||||
#define PP_TxFrame 0x0A00 /* Transmit frame pointer */
|
||||
|
||||
/* Primary I/O Base Address. If no I/O base is supplied by the user, then this */
|
||||
/* can be used as the default I/O base to access the PacketPage Area. */
|
||||
#define DEFAULTIOBASE 0x0300
|
||||
#define FIRST_IO 0x020C /* First I/O port to check */
|
||||
#define LAST_IO 0x037C /* Last I/O port to check (+10h) */
|
||||
#define ADD_MASK 0x3000 /* Mask it use of the ADD_PORT register */
|
||||
#define ADD_SIG 0x3000 /* Expected ID signature */
|
||||
|
||||
#define CHIP_EISA_ID_SIG 0x630E /* Product ID Code for Crystal Chip (CS8900 spec 4.3) */
|
||||
|
||||
#ifdef IBMEIPKT
|
||||
#define EISA_ID_SIG 0x4D24 /* IBM */
|
||||
#define PART_NO_SIG 0x1010 /* IBM */
|
||||
#define MONGOOSE_BIT 0x0000 /* IBM */
|
||||
#else
|
||||
#define EISA_ID_SIG 0x630E /* PnP Vendor ID (same as chip id for Crystal board) */
|
||||
#define PART_NO_SIG 0x4000 /* ID code CS8920 board (PnP Vendor Product code) */
|
||||
#define MONGOOSE_BIT 0x2000 /* PART_NO_SIG + MONGOOSE_BUT => ID of mongoose */
|
||||
#endif
|
||||
|
||||
#define PRODUCT_ID_ADD 0x0002 /* Address of product ID */
|
||||
|
||||
/* Mask to find out the types of registers */
|
||||
#define REG_TYPE_MASK 0x001F
|
||||
|
||||
/* Eeprom Commands */
|
||||
#define ERSE_WR_ENBL 0x00F0
|
||||
#define ERSE_WR_DISABLE 0x0000
|
||||
|
||||
/* Defines Control/Config register quintuplet numbers */
|
||||
#define RX_BUF_CFG 0x0003
|
||||
#define RX_CONTROL 0x0005
|
||||
#define TX_CFG 0x0007
|
||||
#define TX_COMMAND 0x0009
|
||||
#define BUF_CFG 0x000B
|
||||
#define LINE_CONTROL 0x0013
|
||||
#define SELF_CONTROL 0x0015
|
||||
#define BUS_CONTROL 0x0017
|
||||
#define TEST_CONTROL 0x0019
|
||||
|
||||
/* Defines Status/Count registers quintuplet numbers */
|
||||
#define RX_EVENT 0x0004
|
||||
#define TX_EVENT 0x0008
|
||||
#define BUF_EVENT 0x000C
|
||||
#define RX_MISS_COUNT 0x0010
|
||||
#define TX_COL_COUNT 0x0012
|
||||
#define LINE_STATUS 0x0014
|
||||
#define SELF_STATUS 0x0016
|
||||
#define BUS_STATUS 0x0018
|
||||
#define TDR 0x001C
|
||||
|
||||
/* PP_RxCFG - Receive Configuration and Interrupt Mask bit definition - Read/write */
|
||||
#define SKIP_1 0x0040
|
||||
#define RX_STREAM_ENBL 0x0080
|
||||
#define RX_OK_ENBL 0x0100
|
||||
#define RX_DMA_ONLY 0x0200
|
||||
#define AUTO_RX_DMA 0x0400
|
||||
#define BUFFER_CRC 0x0800
|
||||
#define RX_CRC_ERROR_ENBL 0x1000
|
||||
#define RX_RUNT_ENBL 0x2000
|
||||
#define RX_EXTRA_DATA_ENBL 0x4000
|
||||
|
||||
/* PP_RxCTL - Receive Control bit definition - Read/write */
|
||||
#define RX_IA_HASH_ACCEPT 0x0040
|
||||
#define RX_PROM_ACCEPT 0x0080
|
||||
#define RX_OK_ACCEPT 0x0100
|
||||
#define RX_MULTCAST_ACCEPT 0x0200
|
||||
#define RX_IA_ACCEPT 0x0400
|
||||
#define RX_BROADCAST_ACCEPT 0x0800
|
||||
#define RX_BAD_CRC_ACCEPT 0x1000
|
||||
#define RX_RUNT_ACCEPT 0x2000
|
||||
#define RX_EXTRA_DATA_ACCEPT 0x4000
|
||||
#define RX_ALL_ACCEPT (RX_PROM_ACCEPT|RX_BAD_CRC_ACCEPT|RX_RUNT_ACCEPT|RX_EXTRA_DATA_ACCEPT)
|
||||
/* Default receive mode - individually addressed, broadcast, and error free */
|
||||
#define DEF_RX_ACCEPT (RX_IA_ACCEPT | RX_BROADCAST_ACCEPT | RX_OK_ACCEPT)
|
||||
|
||||
/* PP_TxCFG - Transmit Configuration Interrupt Mask bit definition - Read/write */
|
||||
#define TX_LOST_CRS_ENBL 0x0040
|
||||
#define TX_SQE_ERROR_ENBL 0x0080
|
||||
#define TX_OK_ENBL 0x0100
|
||||
#define TX_LATE_COL_ENBL 0x0200
|
||||
#define TX_JBR_ENBL 0x0400
|
||||
#define TX_ANY_COL_ENBL 0x0800
|
||||
#define TX_16_COL_ENBL 0x8000
|
||||
|
||||
/* PP_TxCMD - Transmit Command bit definition - Read-only */
|
||||
#define TX_START_4_BYTES 0x0000
|
||||
#define TX_START_64_BYTES 0x0040
|
||||
#define TX_START_128_BYTES 0x0080
|
||||
#define TX_START_ALL_BYTES 0x00C0
|
||||
#define TX_FORCE 0x0100
|
||||
#define TX_ONE_COL 0x0200
|
||||
#define TX_TWO_PART_DEFF_DISABLE 0x0400
|
||||
#define TX_NO_CRC 0x1000
|
||||
#define TX_RUNT 0x2000
|
||||
|
||||
/* PP_BufCFG - Buffer Configuration Interrupt Mask bit definition - Read/write */
|
||||
#define GENERATE_SW_INTERRUPT 0x0040
|
||||
#define RX_DMA_ENBL 0x0080
|
||||
#define READY_FOR_TX_ENBL 0x0100
|
||||
#define TX_UNDERRUN_ENBL 0x0200
|
||||
#define RX_MISS_ENBL 0x0400
|
||||
#define RX_128_BYTE_ENBL 0x0800
|
||||
#define TX_COL_COUNT_OVRFLOW_ENBL 0x1000
|
||||
#define RX_MISS_COUNT_OVRFLOW_ENBL 0x2000
|
||||
#define RX_DEST_MATCH_ENBL 0x8000
|
||||
|
||||
/* PP_LineCTL - Line Control bit definition - Read/write */
|
||||
#define SERIAL_RX_ON 0x0040
|
||||
#define SERIAL_TX_ON 0x0080
|
||||
#define AUI_ONLY 0x0100
|
||||
#define AUTO_AUI_10BASET 0x0200
|
||||
#define MODIFIED_BACKOFF 0x0800
|
||||
#define NO_AUTO_POLARITY 0x1000
|
||||
#define TWO_PART_DEFDIS 0x2000
|
||||
#define LOW_RX_SQUELCH 0x4000
|
||||
|
||||
/* PP_SelfCTL - Software Self Control bit definition - Read/write */
|
||||
#define POWER_ON_RESET 0x0040
|
||||
#define SW_STOP 0x0100
|
||||
#define SLEEP_ON 0x0200
|
||||
#define AUTO_WAKEUP 0x0400
|
||||
#define HCB0_ENBL 0x1000
|
||||
#define HCB1_ENBL 0x2000
|
||||
#define HCB0 0x4000
|
||||
#define HCB1 0x8000
|
||||
|
||||
/* PP_BusCTL - ISA Bus Control bit definition - Read/write */
|
||||
#define RESET_RX_DMA 0x0040
|
||||
#define MEMORY_ON 0x0400
|
||||
#define DMA_BURST_MODE 0x0800
|
||||
#define IO_CHANNEL_READY_ON 0x1000
|
||||
#define RX_DMA_SIZE_64K 0x2000
|
||||
#define ENABLE_IRQ 0x8000
|
||||
|
||||
/* PP_TestCTL - Test Control bit definition - Read/write */
|
||||
#define LINK_OFF 0x0080
|
||||
#define ENDEC_LOOPBACK 0x0200
|
||||
#define AUI_LOOPBACK 0x0400
|
||||
#define BACKOFF_OFF 0x0800
|
||||
#define FAST_TEST 0x8000
|
||||
|
||||
/* PP_RxEvent - Receive Event Bit definition - Read-only */
|
||||
#define RX_IA_HASHED 0x0040
|
||||
#define RX_DRIBBLE 0x0080
|
||||
#define RX_OK 0x0100
|
||||
#define RX_HASHED 0x0200
|
||||
#define RX_IA 0x0400
|
||||
#define RX_BROADCAST 0x0800
|
||||
#define RX_CRC_ERROR 0x1000
|
||||
#define RX_RUNT 0x2000
|
||||
#define RX_EXTRA_DATA 0x4000
|
||||
|
||||
#define HASH_INDEX_MASK 0x0FC00
|
||||
|
||||
/* PP_TxEvent - Transmit Event Bit definition - Read-only */
|
||||
#define TX_LOST_CRS 0x0040
|
||||
#define TX_SQE_ERROR 0x0080
|
||||
#define TX_OK 0x0100
|
||||
#define TX_LATE_COL 0x0200
|
||||
#define TX_JBR 0x0400
|
||||
#define TX_16_COL 0x8000
|
||||
#define TX_SEND_OK_BITS (TX_OK|TX_LOST_CRS)
|
||||
#define TX_COL_COUNT_MASK 0x7800
|
||||
|
||||
/* PP_BufEvent - Buffer Event Bit definition - Read-only */
|
||||
#define SW_INTERRUPT 0x0040
|
||||
#define RX_DMA 0x0080
|
||||
#define READY_FOR_TX 0x0100
|
||||
#define TX_UNDERRUN 0x0200
|
||||
#define RX_MISS 0x0400
|
||||
#define RX_128_BYTE 0x0800
|
||||
#define TX_COL_OVRFLW 0x1000
|
||||
#define RX_MISS_OVRFLW 0x2000
|
||||
#define RX_DEST_MATCH 0x8000
|
||||
|
||||
/* PP_LineST - Ethernet Line Status bit definition - Read-only */
|
||||
#define LINK_OK 0x0080
|
||||
#define AUI_ON 0x0100
|
||||
#define TENBASET_ON 0x0200
|
||||
#define POLARITY_OK 0x1000
|
||||
#define CRS_OK 0x4000
|
||||
|
||||
/* PP_SelfST - Chip Software Status bit definition */
|
||||
#define ACTIVE_33V 0x0040
|
||||
#define INIT_DONE 0x0080
|
||||
#define SI_BUSY 0x0100
|
||||
#define EEPROM_PRESENT 0x0200
|
||||
#define EEPROM_OK 0x0400
|
||||
#define EL_PRESENT 0x0800
|
||||
#define EE_SIZE_64 0x1000
|
||||
|
||||
/* PP_BusST - ISA Bus Status bit definition */
|
||||
#define TX_BID_ERROR 0x0080
|
||||
#define READY_FOR_TX_NOW 0x0100
|
||||
|
||||
/* PP_AutoNegCTL - Auto Negotiation Control bit definition */
|
||||
#define RE_NEG_NOW 0x0040
|
||||
#define ALLOW_FDX 0x0080
|
||||
#define AUTO_NEG_ENABLE 0x0100
|
||||
#define NLP_ENABLE 0x0200
|
||||
#define FORCE_FDX 0x8000
|
||||
#define AUTO_NEG_BITS (FORCE_FDX|NLP_ENABLE|AUTO_NEG_ENABLE)
|
||||
#define AUTO_NEG_MASK (FORCE_FDX|NLP_ENABLE|AUTO_NEG_ENABLE|ALLOW_FDX|RE_NEG_NOW)
|
||||
|
||||
/* PP_AutoNegST - Auto Negotiation Status bit definition */
|
||||
#define AUTO_NEG_BUSY 0x0080
|
||||
#define FLP_LINK 0x0100
|
||||
#define FLP_LINK_GOOD 0x0800
|
||||
#define LINK_FAULT 0x1000
|
||||
#define HDX_ACTIVE 0x4000
|
||||
#define FDX_ACTIVE 0x8000
|
||||
|
||||
/* The following block defines the ISQ event types */
|
||||
#define ISQ_RECEIVER_EVENT 0x04
|
||||
#define ISQ_TRANSMITTER_EVENT 0x08
|
||||
#define ISQ_BUFFER_EVENT 0x0c
|
||||
#define ISQ_RX_MISS_EVENT 0x10
|
||||
#define ISQ_TX_COL_EVENT 0x12
|
||||
|
||||
#define ISQ_EVENT_MASK 0x003F /* ISQ mask to find out type of event */
|
||||
#define ISQ_HIST 16 /* small history buffer */
|
||||
#define AUTOINCREMENT 0x8000 /* Bit mask to set bit-15 for autoincrement */
|
||||
|
||||
#define TXRXBUFSIZE 0x0600
|
||||
#define RXDMABUFSIZE 0x8000
|
||||
#define RXDMASIZE 0x4000
|
||||
#define TXRX_LENGTH_MASK 0x07FF
|
||||
|
||||
/* rx options bits */
|
||||
#define RCV_WITH_RXON 1 /* Set SerRx ON */
|
||||
#define RCV_COUNTS 2 /* Use Framecnt1 */
|
||||
#define RCV_PONG 4 /* Pong respondent */
|
||||
#define RCV_DONG 8 /* Dong operation */
|
||||
#define RCV_POLLING 0x10 /* Poll RxEvent */
|
||||
#define RCV_ISQ 0x20 /* Use ISQ, int */
|
||||
#define RCV_AUTO_DMA 0x100 /* Set AutoRxDMAE */
|
||||
#define RCV_DMA 0x200 /* Set RxDMA only */
|
||||
#define RCV_DMA_ALL 0x400 /* Copy all DMA'ed */
|
||||
#define RCV_FIXED_DATA 0x800 /* Every frame same */
|
||||
#define RCV_IO 0x1000 /* Use ISA IO only */
|
||||
#define RCV_MEMORY 0x2000 /* Use ISA Memory */
|
||||
|
||||
#define RAM_SIZE 0x1000 /* The card has 4k bytes or RAM */
|
||||
#define PKT_START PP_TxFrame /* Start of packet RAM */
|
||||
|
||||
#define RX_FRAME_PORT 0x0000
|
||||
#define TX_FRAME_PORT RX_FRAME_PORT
|
||||
#define TX_CMD_PORT 0x0004
|
||||
#define TX_NOW 0x0000 /* Tx packet after 5 bytes copied */
|
||||
#define TX_AFTER_381 0x0020 /* Tx packet after 381 bytes copied */
|
||||
#define TX_AFTER_ALL 0x0060 /* Tx packet after all bytes copied */
|
||||
#define TX_LEN_PORT 0x0006
|
||||
#define ISQ_PORT 0x0008
|
||||
#define ADD_PORT 0x000A
|
||||
#define DATA_PORT 0x000C
|
||||
|
||||
#define EEPROM_WRITE_EN 0x00F0
|
||||
#define EEPROM_WRITE_DIS 0x0000
|
||||
#define EEPROM_WRITE_CMD 0x0100
|
||||
#define EEPROM_READ_CMD 0x0200
|
||||
|
||||
/* Receive Header */
|
||||
/* Description of header of each packet in receive area of memory */
|
||||
#define RBUF_EVENT_LOW 0 /* Low byte of RxEvent - status of received frame */
|
||||
#define RBUF_EVENT_HIGH 1 /* High byte of RxEvent - status of received frame */
|
||||
#define RBUF_LEN_LOW 2 /* Length of received data - low byte */
|
||||
#define RBUF_LEN_HI 3 /* Length of received data - high byte */
|
||||
#define RBUF_HEAD_LEN 4 /* Length of this header */
|
||||
|
||||
#define CHIP_READ 0x1 /* Used to mark state of the repins code (chip or dma) */
|
||||
#define DMA_READ 0x2 /* Used to mark state of the repins code (chip or dma) */
|
||||
|
||||
/* for bios scan */
|
||||
/* */
|
||||
#ifdef CSDEBUG
|
||||
/* use these values for debugging bios scan */
|
||||
#define BIOS_START_SEG 0x00000
|
||||
#define BIOS_OFFSET_INC 0x0010
|
||||
#else
|
||||
#define BIOS_START_SEG 0x0c000
|
||||
#define BIOS_OFFSET_INC 0x0200
|
||||
#endif
|
||||
|
||||
#define BIOS_LAST_OFFSET 0x0fc00
|
||||
|
||||
/* Byte offsets into the EEPROM configuration buffer */
|
||||
#define ISA_CNF_OFFSET 0x6
|
||||
#define TX_CTL_OFFSET (ISA_CNF_OFFSET + 8) /* 8900 eeprom */
|
||||
#define AUTO_NEG_CNF_OFFSET (ISA_CNF_OFFSET + 8) /* 8920 eeprom */
|
||||
|
||||
/* the assumption here is that the bits in the eeprom are generally */
|
||||
/* in the same position as those in the autonegctl register. */
|
||||
/* Of course the IMM bit is not in that register so it must be */
|
||||
/* masked out */
|
||||
#define EE_FORCE_FDX 0x8000
|
||||
#define EE_NLP_ENABLE 0x0200
|
||||
#define EE_AUTO_NEG_ENABLE 0x0100
|
||||
#define EE_ALLOW_FDX 0x0080
|
||||
#define EE_AUTO_NEG_CNF_MASK (EE_FORCE_FDX|EE_NLP_ENABLE|EE_AUTO_NEG_ENABLE|EE_ALLOW_FDX)
|
||||
|
||||
#define IMM_BIT 0x0040 /* ignore missing media */
|
||||
|
||||
#define ADAPTER_CNF_OFFSET (AUTO_NEG_CNF_OFFSET + 2)
|
||||
#define A_CNF_10B_T 0x0001
|
||||
#define A_CNF_AUI 0x0002
|
||||
#define A_CNF_10B_2 0x0004
|
||||
#define A_CNF_MEDIA_TYPE 0x0060
|
||||
#define A_CNF_MEDIA_AUTO 0x0000
|
||||
#define A_CNF_MEDIA_10B_T 0x0020
|
||||
#define A_CNF_MEDIA_AUI 0x0040
|
||||
#define A_CNF_MEDIA_10B_2 0x0060
|
||||
#define A_CNF_DC_DC_POLARITY 0x0080
|
||||
#define A_CNF_NO_AUTO_POLARITY 0x2000
|
||||
#define A_CNF_LOW_RX_SQUELCH 0x4000
|
||||
#define A_CNF_EXTND_10B_2 0x8000
|
||||
|
||||
#define PACKET_PAGE_OFFSET 0x8
|
||||
|
||||
/* Bit definitions for the ISA configuration word from the EEPROM */
|
||||
#define INT_NO_MASK 0x000F
|
||||
#define DMA_NO_MASK 0x0070
|
||||
#define ISA_DMA_SIZE 0x0200
|
||||
#define ISA_AUTO_RxDMA 0x0400
|
||||
#define ISA_RxDMA 0x0800
|
||||
#define DMA_BURST 0x1000
|
||||
#define STREAM_TRANSFER 0x2000
|
||||
#define ANY_ISA_DMA (ISA_AUTO_RxDMA | ISA_RxDMA)
|
||||
|
||||
/* DMA controller registers */
|
||||
#define DMA_BASE 0x00 /* DMA controller base */
|
||||
#define DMA_BASE_2 0x0C0 /* DMA controller base */
|
||||
|
||||
#define DMA_STAT 0x0D0 /* DMA controller status register */
|
||||
#define DMA_MASK 0x0D4 /* DMA controller mask register */
|
||||
#define DMA_MODE 0x0D6 /* DMA controller mode register */
|
||||
#define DMA_RESETFF 0x0D8 /* DMA controller first/last flip flop */
|
||||
|
||||
/* DMA data */
|
||||
#define DMA_DISABLE 0x04 /* Disable channel n */
|
||||
#define DMA_ENABLE 0x00 /* Enable channel n */
|
||||
/* Demand transfers, incr. address, auto init, writes, ch. n */
|
||||
#define DMA_RX_MODE 0x14
|
||||
/* Demand transfers, incr. address, auto init, reads, ch. n */
|
||||
#define DMA_TX_MODE 0x18
|
||||
|
||||
#define DMA_SIZE (16*1024) /* Size of dma buffer - 16k */
|
||||
|
||||
#define CS8900 0x0000
|
||||
#define CS8920 0x4000
|
||||
#define CS8920M 0x6000
|
||||
#define REVISON_BITS 0x1F00
|
||||
#define EEVER_NUMBER 0x12
|
||||
#define CHKSUM_LEN 0x14
|
||||
#define CHKSUM_VAL 0x0000
|
||||
#define START_EEPROM_DATA 0x001c /* Offset into eeprom for start of data */
|
||||
#define IRQ_MAP_EEPROM_DATA 0x0046 /* Offset into eeprom for the IRQ map */
|
||||
#define IRQ_MAP_LEN 0x0004 /* No of bytes to read for the IRQ map */
|
||||
#define PNP_IRQ_FRMT 0x0022 /* PNP small item IRQ format */
|
||||
#define CS8900_IRQ_MAP 0x1c20 /* This IRQ map is fixed */
|
||||
|
||||
#define CS8920_NO_INTS 0x0F /* Max CS8920 interrupt select # */
|
||||
|
||||
#define PNP_ADD_PORT 0x0279
|
||||
#define PNP_WRITE_PORT 0x0A79
|
||||
|
||||
#define GET_PNP_ISA_STRUCT 0x40
|
||||
#define PNP_ISA_STRUCT_LEN 0x06
|
||||
#define PNP_CSN_CNT_OFF 0x01
|
||||
#define PNP_RD_PORT_OFF 0x02
|
||||
#define PNP_FUNCTION_OK 0x00
|
||||
#define PNP_WAKE 0x03
|
||||
#define PNP_RSRC_DATA 0x04
|
||||
#define PNP_RSRC_READY 0x01
|
||||
#define PNP_STATUS 0x05
|
||||
#define PNP_ACTIVATE 0x30
|
||||
#define PNP_CNF_IO_H 0x60
|
||||
#define PNP_CNF_IO_L 0x61
|
||||
#define PNP_CNF_INT 0x70
|
||||
#define PNP_CNF_DMA 0x74
|
||||
#define PNP_CNF_MEM 0x48
|
||||
|
||||
#define BIT0 1
|
||||
#define BIT15 0x8000
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
Permission is granted to distribute the enclosed cs89x0.[ch] driver
|
||||
only in conjunction with the Etherboot package. The code is
|
||||
ordinarily distributed under the GPL.
|
||||
|
||||
Russ Nelson, January 2000
|
||||
|
||||
CREDITS
|
||||
|
||||
I want to thank
|
||||
|
||||
Mike Cruse <mcruse@cti-ltd.com>
|
||||
for providing an evaluation NIC and for sponsoring the
|
||||
development of this driver.
|
||||
|
||||
Randall Sears <sears@crystal.cirrus.com>
|
||||
Deva Bodas <bodas@crystal.cirrus.com>
|
||||
Andreas Kraemer <akraemer@crystal.cirrus.com>
|
||||
Wolfgang Krause <100303.2673@compuserve.com>
|
||||
for excellent technical support and for providing the required
|
||||
programming information. I appreciate Crystal Semiconductor's
|
||||
commitment towards free software.
|
||||
|
||||
Russell Nelson <nelson@crynwr.com>
|
||||
for writing the Linux device driver for the CS89x0
|
||||
chipset. Russel's code is very well designed and simplified my
|
||||
job a lot.
|
||||
@@ -1,692 +0,0 @@
|
||||
/*
|
||||
DAVICOM DM9009/DM9102/DM9102A Etherboot Driver V1.00
|
||||
|
||||
This driver was ported from Marty Conner's Tulip Etherboot driver.
|
||||
Thanks Marty Connor (mdc@thinguin.org)
|
||||
You can get Tulip driver source file from this URL:
|
||||
|
||||
"http://etherboot.sourceforge..net/#Distribution"
|
||||
|
||||
This davicom etherboot driver supports DM9009/DM9102/DM9102A/
|
||||
DM9102A+DM9801/DM9102A+DM9802 NICs.
|
||||
|
||||
This software may be used and distributed according to the terms
|
||||
of the GNU Public License, incorporated herein by reference.
|
||||
|
||||
*/
|
||||
|
||||
/*********************************************************************/
|
||||
/* Revision History */
|
||||
/*********************************************************************/
|
||||
|
||||
/*
|
||||
19 OCT 2000 Sten 1.00
|
||||
Different half and full duplex mode
|
||||
Do the different programming for DM9801/DM9802
|
||||
|
||||
12 OCT 2000 Sten 0.90
|
||||
This driver was ported from tulip driver and it
|
||||
has the following difference.
|
||||
Changed symbol tulip/TULIP to davicom/DAVICOM
|
||||
Deleted some code that did not use in this driver.
|
||||
Used chain-strcture to replace ring structure
|
||||
for both TX/RX descriptor.
|
||||
Allocated two tx descriptor.
|
||||
According current media mode to set operating
|
||||
register(CR6)
|
||||
*/
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
/* Declarations */
|
||||
/*********************************************************************/
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "pci.h"
|
||||
#include "cards.h"
|
||||
|
||||
#undef DAVICOM_DEBUG
|
||||
#undef DAVICOM_DEBUG_WHERE
|
||||
|
||||
#define TX_TIME_OUT 2*TICKS_PER_SEC
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef signed char s8;
|
||||
typedef unsigned short u16;
|
||||
typedef signed short s16;
|
||||
typedef unsigned int u32;
|
||||
typedef signed int s32;
|
||||
|
||||
/* Register offsets for davicom device */
|
||||
enum davicom_offsets {
|
||||
CSR0=0, CSR1=0x08, CSR2=0x10, CSR3=0x18, CSR4=0x20, CSR5=0x28,
|
||||
CSR6=0x30, CSR7=0x38, CSR8=0x40, CSR9=0x48, CSR10=0x50, CSR11=0x58,
|
||||
CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78, CSR16=0x80, CSR20=0xA0
|
||||
};
|
||||
|
||||
/* EEPROM Address width definitions */
|
||||
#define EEPROM_ADDRLEN 6
|
||||
#define EEPROM_SIZE 32 /* 1 << EEPROM_ADDRLEN */
|
||||
/* Used to be 128, but we only need to read enough to get the MAC
|
||||
address at bytes 20..25 */
|
||||
|
||||
/* Data Read from the EEPROM */
|
||||
static unsigned char ee_data[EEPROM_SIZE];
|
||||
|
||||
/* The EEPROM commands include the alway-set leading bit. */
|
||||
#define EE_WRITE_CMD (5 << addr_len)
|
||||
#define EE_READ_CMD (6 << addr_len)
|
||||
#define EE_ERASE_CMD (7 << addr_len)
|
||||
|
||||
/* EEPROM_Ctrl bits. */
|
||||
#define EE_SHIFT_CLK 0x02 /* EEPROM shift clock. */
|
||||
#define EE_CS 0x01 /* EEPROM chip select. */
|
||||
#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */
|
||||
#define EE_WRITE_0 0x01
|
||||
#define EE_WRITE_1 0x05
|
||||
#define EE_DATA_READ 0x08 /* EEPROM chip data out. */
|
||||
#define EE_ENB (0x4800 | EE_CS)
|
||||
|
||||
/* Sten 10/11 for phyxcer */
|
||||
#define PHY_DATA_0 0x0
|
||||
#define PHY_DATA_1 0x20000
|
||||
#define MDCLKH 0x10000
|
||||
|
||||
/* Delay between EEPROM clock transitions. Even at 33Mhz current PCI
|
||||
implementations don't overrun the EEPROM clock. We add a bus
|
||||
turn-around to insure that this remains true. */
|
||||
#define eeprom_delay() inl(ee_addr)
|
||||
|
||||
/* helpful macro if on a big_endian machine for changing byte order.
|
||||
not strictly needed on Intel */
|
||||
#define le16_to_cpu(val) (val)
|
||||
|
||||
/* transmit and receive descriptor format */
|
||||
struct txdesc {
|
||||
volatile unsigned long status; /* owner, status */
|
||||
unsigned long buf1sz:11, /* size of buffer 1 */
|
||||
buf2sz:11, /* size of buffer 2 */
|
||||
control:10; /* control bits */
|
||||
const unsigned char *buf1addr; /* buffer 1 address */
|
||||
const unsigned char *buf2addr; /* buffer 2 address */
|
||||
};
|
||||
|
||||
struct rxdesc {
|
||||
volatile unsigned long status; /* owner, status */
|
||||
unsigned long buf1sz:11, /* size of buffer 1 */
|
||||
buf2sz:11, /* size of buffer 2 */
|
||||
control:10; /* control bits */
|
||||
unsigned char *buf1addr; /* buffer 1 address */
|
||||
unsigned char *buf2addr; /* buffer 2 address */
|
||||
};
|
||||
|
||||
/* Size of transmit and receive buffers */
|
||||
#define BUFLEN 1536
|
||||
|
||||
/*********************************************************************/
|
||||
/* Global Storage */
|
||||
/*********************************************************************/
|
||||
|
||||
/* PCI Bus parameters */
|
||||
static unsigned short vendor, dev_id;
|
||||
static unsigned long ioaddr;
|
||||
|
||||
/* Note: transmit and receive buffers must be longword aligned and
|
||||
longword divisable */
|
||||
|
||||
/* transmit descriptor and buffer */
|
||||
#define NTXD 2
|
||||
static struct txdesc txd[NTXD] __attribute__ ((aligned(4)));
|
||||
#ifdef USE_LOWMEM_BUFFER
|
||||
#define txb ((char *)0x10000 - BUFLEN)
|
||||
#else
|
||||
static unsigned char txb[BUFLEN] __attribute__ ((aligned(4)));
|
||||
#endif
|
||||
|
||||
/* receive descriptor(s) and buffer(s) */
|
||||
#define NRXD 4
|
||||
static struct rxdesc rxd[NRXD] __attribute__ ((aligned(4)));
|
||||
#ifdef USE_LOWMEM_BUFFER
|
||||
#define rxb ((char *)0x10000 - NRXD * BUFLEN - BUFLEN)
|
||||
#else
|
||||
static unsigned char rxb[NRXD * BUFLEN] __attribute__ ((aligned(4)));
|
||||
#endif
|
||||
static int rxd_tail;
|
||||
static int TxPtr;
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
/* Function Prototypes */
|
||||
/*********************************************************************/
|
||||
static void whereami(const char *str);
|
||||
static int read_eeprom(unsigned long ioaddr, int location, int addr_len);
|
||||
struct nic *davicom_probe(struct nic *nic, unsigned short *io_addrs,
|
||||
struct pci_device *pci);
|
||||
static void davicom_init_chain(struct nic *nic); /* Sten 10/9 */
|
||||
static void davicom_reset(struct nic *nic);
|
||||
static void davicom_transmit(struct nic *nic, const char *d, unsigned int t,
|
||||
unsigned int s, const char *p);
|
||||
static int davicom_poll(struct nic *nic);
|
||||
static void davicom_disable(struct nic *nic);
|
||||
static void whereami (const char *str);
|
||||
#ifdef DAVICOM_DEBUG
|
||||
static void davicom_more(void);
|
||||
#endif /* DAVICOM_DEBUG */
|
||||
static void davicom_wait(unsigned int nticks);
|
||||
static int phy_read(int);
|
||||
static void phy_write(int, u16);
|
||||
static void phy_write_1bit(u32, u32);
|
||||
static int phy_read_1bit(u32);
|
||||
static void davicom_media_chk(struct nic *);
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
/* Utility Routines */
|
||||
/*********************************************************************/
|
||||
|
||||
static inline void whereami (const char *str)
|
||||
{
|
||||
#ifdef DAVICOM_DEBUG_WHERE
|
||||
printf("%s\n", str);
|
||||
/* sleep(2); */
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DAVICOM_DEBUG
|
||||
static void davicom_more()
|
||||
{
|
||||
printf("\n\n-- more --");
|
||||
while (!iskey())
|
||||
/* wait */;
|
||||
getchar();
|
||||
printf("\n\n");
|
||||
}
|
||||
#endif /* DAVICOM_DEBUG */
|
||||
|
||||
static void davicom_wait(unsigned int nticks)
|
||||
{
|
||||
unsigned int to = currticks() + nticks;
|
||||
while (currticks() < to)
|
||||
/* wait */ ;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
/* For DAVICOM phyxcer register by MII interface */
|
||||
/*********************************************************************/
|
||||
/*
|
||||
Read a word data from phy register
|
||||
*/
|
||||
static int phy_read(int location)
|
||||
{
|
||||
int i, phy_addr=1;
|
||||
u16 phy_data;
|
||||
u32 io_dcr9;
|
||||
|
||||
whereami("phy_read\n");
|
||||
|
||||
io_dcr9 = ioaddr + CSR9;
|
||||
|
||||
/* Send 33 synchronization clock to Phy controller */
|
||||
for (i=0; i<34; i++)
|
||||
phy_write_1bit(io_dcr9, PHY_DATA_1);
|
||||
|
||||
/* Send start command(01) to Phy */
|
||||
phy_write_1bit(io_dcr9, PHY_DATA_0);
|
||||
phy_write_1bit(io_dcr9, PHY_DATA_1);
|
||||
|
||||
/* Send read command(10) to Phy */
|
||||
phy_write_1bit(io_dcr9, PHY_DATA_1);
|
||||
phy_write_1bit(io_dcr9, PHY_DATA_0);
|
||||
|
||||
/* Send Phy addres */
|
||||
for (i=0x10; i>0; i=i>>1)
|
||||
phy_write_1bit(io_dcr9, phy_addr&i ? PHY_DATA_1: PHY_DATA_0);
|
||||
|
||||
/* Send register addres */
|
||||
for (i=0x10; i>0; i=i>>1)
|
||||
phy_write_1bit(io_dcr9, location&i ? PHY_DATA_1: PHY_DATA_0);
|
||||
|
||||
/* Skip transition state */
|
||||
phy_read_1bit(io_dcr9);
|
||||
|
||||
/* read 16bit data */
|
||||
for (phy_data=0, i=0; i<16; i++) {
|
||||
phy_data<<=1;
|
||||
phy_data|=phy_read_1bit(io_dcr9);
|
||||
}
|
||||
|
||||
return phy_data;
|
||||
}
|
||||
|
||||
/*
|
||||
Write a word to Phy register
|
||||
*/
|
||||
static void phy_write(int location, u16 phy_data)
|
||||
{
|
||||
u16 i, phy_addr=1;
|
||||
u32 io_dcr9;
|
||||
|
||||
whereami("phy_write\n");
|
||||
|
||||
io_dcr9 = ioaddr + CSR9;
|
||||
|
||||
/* Send 33 synchronization clock to Phy controller */
|
||||
for (i=0; i<34; i++)
|
||||
phy_write_1bit(io_dcr9, PHY_DATA_1);
|
||||
|
||||
/* Send start command(01) to Phy */
|
||||
phy_write_1bit(io_dcr9, PHY_DATA_0);
|
||||
phy_write_1bit(io_dcr9, PHY_DATA_1);
|
||||
|
||||
/* Send write command(01) to Phy */
|
||||
phy_write_1bit(io_dcr9, PHY_DATA_0);
|
||||
phy_write_1bit(io_dcr9, PHY_DATA_1);
|
||||
|
||||
/* Send Phy addres */
|
||||
for (i=0x10; i>0; i=i>>1)
|
||||
phy_write_1bit(io_dcr9, phy_addr&i ? PHY_DATA_1: PHY_DATA_0);
|
||||
|
||||
/* Send register addres */
|
||||
for (i=0x10; i>0; i=i>>1)
|
||||
phy_write_1bit(io_dcr9, location&i ? PHY_DATA_1: PHY_DATA_0);
|
||||
|
||||
/* written trasnition */
|
||||
phy_write_1bit(io_dcr9, PHY_DATA_1);
|
||||
phy_write_1bit(io_dcr9, PHY_DATA_0);
|
||||
|
||||
/* Write a word data to PHY controller */
|
||||
for (i=0x8000; i>0; i>>=1)
|
||||
phy_write_1bit(io_dcr9, phy_data&i ? PHY_DATA_1: PHY_DATA_0);
|
||||
}
|
||||
|
||||
/*
|
||||
Write one bit data to Phy Controller
|
||||
*/
|
||||
static void phy_write_1bit(u32 ee_addr, u32 phy_data)
|
||||
{
|
||||
whereami("phy_write_1bit\n");
|
||||
outl(phy_data, ee_addr); /* MII Clock Low */
|
||||
eeprom_delay();
|
||||
outl(phy_data|MDCLKH, ee_addr); /* MII Clock High */
|
||||
eeprom_delay();
|
||||
outl(phy_data, ee_addr); /* MII Clock Low */
|
||||
eeprom_delay();
|
||||
}
|
||||
|
||||
/*
|
||||
Read one bit phy data from PHY controller
|
||||
*/
|
||||
static int phy_read_1bit(u32 ee_addr)
|
||||
{
|
||||
int phy_data;
|
||||
|
||||
whereami("phy_read_1bit\n");
|
||||
|
||||
outl(0x50000, ee_addr);
|
||||
eeprom_delay();
|
||||
|
||||
phy_data=(inl(ee_addr)>>19) & 0x1;
|
||||
|
||||
outl(0x40000, ee_addr);
|
||||
eeprom_delay();
|
||||
|
||||
return phy_data;
|
||||
}
|
||||
|
||||
/*
|
||||
DM9801/DM9802 present check and program
|
||||
*/
|
||||
static void HPNA_process(void)
|
||||
{
|
||||
|
||||
if ( (phy_read(3) & 0xfff0) == 0xb900 ) {
|
||||
if ( phy_read(31) == 0x4404 ) {
|
||||
/* DM9801 present */
|
||||
if (phy_read(3) == 0xb901)
|
||||
phy_write(16, 0x5); /* DM9801 E4 */
|
||||
else
|
||||
phy_write(16, 0x1005); /* DM9801 E3 and others */
|
||||
phy_write(25, ((phy_read(24) + 3) & 0xff) | 0xf000);
|
||||
} else {
|
||||
/* DM9802 present */
|
||||
phy_write(16, 0x5);
|
||||
phy_write(25, (phy_read(25) & 0xff00) + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Sense media mode and set CR6
|
||||
*/
|
||||
static void davicom_media_chk(struct nic * nic)
|
||||
{
|
||||
unsigned long to, csr6;
|
||||
|
||||
csr6 = 0x00200000; /* SF */
|
||||
outl(csr6, ioaddr + CSR6);
|
||||
|
||||
if (vendor == PCI_VENDOR_ID_DAVICOM && dev_id == PCI_DEVICE_ID_DM9009) {
|
||||
/* Set to 10BaseT mode for DM9009 */
|
||||
phy_write(0, 0);
|
||||
} else {
|
||||
/* For DM9102/DM9102A */
|
||||
to = currticks() + 2 * TICKS_PER_SEC;
|
||||
while ( ((phy_read(1) & 0x24)!=0x24) && (currticks() < to))
|
||||
/* wait */ ;
|
||||
|
||||
if ( (phy_read(1) & 0x24) == 0x24 ) {
|
||||
if (phy_read(17) & 0xa000)
|
||||
csr6 |= 0x00000200; /* Full Duplex mode */
|
||||
} else
|
||||
csr6 |= 0x00040000; /* Select DM9801/DM9802 when Ethernet link failed */
|
||||
}
|
||||
|
||||
/* set the chip's operating mode */
|
||||
outl(csr6, ioaddr + CSR6);
|
||||
|
||||
/* DM9801/DM9802 present check & program */
|
||||
if (csr6 & 0x40000)
|
||||
HPNA_process();
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
/* EEPROM Reading Code */
|
||||
/*********************************************************************/
|
||||
/* EEPROM routines adapted from the Linux Tulip Code */
|
||||
/* Reading a serial EEPROM is a "bit" grungy, but we work our way
|
||||
through:->.
|
||||
*/
|
||||
static int read_eeprom(unsigned long ioaddr, int location, int addr_len)
|
||||
{
|
||||
int i;
|
||||
unsigned short retval = 0;
|
||||
long ee_addr = ioaddr + CSR9;
|
||||
int read_cmd = location | EE_READ_CMD;
|
||||
|
||||
whereami("read_eeprom\n");
|
||||
|
||||
outl(EE_ENB & ~EE_CS, ee_addr);
|
||||
outl(EE_ENB, ee_addr);
|
||||
|
||||
/* Shift the read command bits out. */
|
||||
for (i = 4 + addr_len; i >= 0; i--) {
|
||||
short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
|
||||
outl(EE_ENB | dataval, ee_addr);
|
||||
eeprom_delay();
|
||||
outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
|
||||
eeprom_delay();
|
||||
}
|
||||
outl(EE_ENB, ee_addr);
|
||||
|
||||
for (i = 16; i > 0; i--) {
|
||||
outl(EE_ENB | EE_SHIFT_CLK, ee_addr);
|
||||
eeprom_delay();
|
||||
retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
|
||||
outl(EE_ENB, ee_addr);
|
||||
eeprom_delay();
|
||||
}
|
||||
|
||||
/* Terminate the EEPROM access. */
|
||||
outl(EE_ENB & ~EE_CS, ee_addr);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
/* davicom_init_chain - setup the tx and rx descriptors */
|
||||
/* Sten 10/9 */
|
||||
/*********************************************************************/
|
||||
static void davicom_init_chain(struct nic *nic)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* setup the transmit descriptor */
|
||||
/* Sten: Set 2 TX descriptor but use one TX buffer because
|
||||
it transmit a packet and wait complete every time. */
|
||||
for (i=0; i<NTXD; i++) {
|
||||
txd[i].buf1addr = &txb[0]; /* Used same TX buffer */
|
||||
txd[i].buf2addr = (unsigned char *)&txd[i+1]; /* Point to Next TX desc */
|
||||
txd[i].buf1sz = 0;
|
||||
txd[i].buf2sz = 0;
|
||||
txd[i].control = 0x184; /* Begin/End/Chain */
|
||||
txd[i].status = 0x00000000; /* give ownership to Host */
|
||||
}
|
||||
|
||||
/* construct perfect filter frame with mac address as first match
|
||||
and broadcast address for all others */
|
||||
for (i=0; i<192; i++) txb[i] = 0xFF;
|
||||
txb[0] = nic->node_addr[0];
|
||||
txb[1] = nic->node_addr[1];
|
||||
txb[4] = nic->node_addr[2];
|
||||
txb[5] = nic->node_addr[3];
|
||||
txb[8] = nic->node_addr[4];
|
||||
txb[9] = nic->node_addr[5];
|
||||
|
||||
/* setup receive descriptor */
|
||||
for (i=0; i<NRXD; i++) {
|
||||
rxd[i].buf1addr = &rxb[i * BUFLEN];
|
||||
rxd[i].buf2addr = (unsigned char *)&rxd[i+1]; /* Point to Next RX desc */
|
||||
rxd[i].buf1sz = BUFLEN;
|
||||
rxd[i].buf2sz = 0; /* not used */
|
||||
rxd[i].control = 0x4; /* Chain Structure */
|
||||
rxd[i].status = 0x80000000; /* give ownership to device */
|
||||
}
|
||||
|
||||
/* Chain the last descriptor to first */
|
||||
txd[NTXD - 1].buf2addr = (unsigned char *)&txd[0];
|
||||
rxd[NRXD - 1].buf2addr = (unsigned char *)&rxd[0];
|
||||
TxPtr = 0;
|
||||
rxd_tail = 0;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
/* davicom_reset - Reset adapter */
|
||||
/*********************************************************************/
|
||||
static void davicom_reset(struct nic *nic)
|
||||
{
|
||||
unsigned long to;
|
||||
u32 addr_low, addr_high;
|
||||
|
||||
whereami("davicom_reset\n");
|
||||
|
||||
/* Stop Tx and RX */
|
||||
outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
|
||||
|
||||
/* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
|
||||
outl(0x00000001, ioaddr + CSR0);
|
||||
|
||||
davicom_wait(TICKS_PER_SEC);
|
||||
|
||||
/* TX/RX descriptor burst */
|
||||
outl(0x0C00000, ioaddr + CSR0); /* Sten 10/9 */
|
||||
|
||||
/* set up transmit and receive descriptors */
|
||||
davicom_init_chain(nic); /* Sten 10/9 */
|
||||
|
||||
/* Point to receive descriptor */
|
||||
outl((unsigned long)&rxd[0], ioaddr + CSR3);
|
||||
outl((unsigned long)&txd[0], ioaddr + CSR4); /* Sten 10/9 */
|
||||
|
||||
/* According phyxcer media mode to set CR6,
|
||||
DM9102/A phyxcer can auto-detect media mode */
|
||||
davicom_media_chk(nic);
|
||||
|
||||
/* Prepare Setup Frame Sten 10/9 */
|
||||
txd[TxPtr].buf1sz = 192;
|
||||
txd[TxPtr].control = 0x024; /* SF/CE */
|
||||
txd[TxPtr].status = 0x80000000; /* Give ownership to device */
|
||||
|
||||
/* Start Tx */
|
||||
outl(inl(ioaddr + CSR6) | 0x00002000, ioaddr + CSR6);
|
||||
/* immediate transmit demand */
|
||||
outl(0, ioaddr + CSR1);
|
||||
|
||||
to = currticks() + TX_TIME_OUT;
|
||||
while ((txd[TxPtr].status & 0x80000000) && (currticks() < to)) /* Sten 10/9 */
|
||||
/* wait */ ;
|
||||
|
||||
if (currticks() >= to) {
|
||||
printf ("TX Setup Timeout!\n");
|
||||
}
|
||||
/* Point to next TX descriptor */
|
||||
TxPtr = (++TxPtr >= NTXD) ? 0:TxPtr; /* Sten 10/9 */
|
||||
|
||||
#ifdef DAVICOM_DEBUG
|
||||
printf("txd.status = %X\n", txd.status);
|
||||
printf("ticks = %d\n", currticks() - (to - TX_TIME_OUT));
|
||||
davicom_more();
|
||||
#endif
|
||||
|
||||
/* enable RX */
|
||||
outl(inl(ioaddr + CSR6) | 0x00000002, ioaddr + CSR6);
|
||||
/* immediate poll demand */
|
||||
outl(0, ioaddr + CSR2);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
/* eth_transmit - Transmit a frame */
|
||||
/*********************************************************************/
|
||||
static void davicom_transmit(struct nic *nic, const char *d, unsigned int t,
|
||||
unsigned int s, const char *p)
|
||||
{
|
||||
unsigned long to;
|
||||
|
||||
whereami("davicom_transmit\n");
|
||||
|
||||
/* Stop Tx */
|
||||
/* outl(inl(ioaddr + CSR6) & ~0x00002000, ioaddr + CSR6); */
|
||||
|
||||
/* setup ethernet header */
|
||||
memcpy(&txb[0], d, ETH_ALEN); /* DA 6byte */
|
||||
memcpy(&txb[ETH_ALEN], nic->node_addr, ETH_ALEN); /* SA 6byte*/
|
||||
txb[ETH_ALEN*2] = (t >> 8) & 0xFF; /* Frame type: 2byte */
|
||||
txb[ETH_ALEN*2+1] = t & 0xFF;
|
||||
memcpy(&txb[ETH_HLEN], p, s); /* Frame data */
|
||||
|
||||
/* setup the transmit descriptor */
|
||||
txd[TxPtr].buf1sz = ETH_HLEN+s;
|
||||
txd[TxPtr].control = 0x00000184; /* LS+FS+CE */
|
||||
txd[TxPtr].status = 0x80000000; /* give ownership to device */
|
||||
|
||||
/* immediate transmit demand */
|
||||
outl(0, ioaddr + CSR1);
|
||||
|
||||
to = currticks() + TX_TIME_OUT;
|
||||
while ((txd[TxPtr].status & 0x80000000) && (currticks() < to))
|
||||
/* wait */ ;
|
||||
|
||||
if (currticks() >= to) {
|
||||
printf ("TX Timeout!\n");
|
||||
}
|
||||
|
||||
/* Point to next TX descriptor */
|
||||
TxPtr = (++TxPtr >= NTXD) ? 0:TxPtr; /* Sten 10/9 */
|
||||
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
/* eth_poll - Wait for a frame */
|
||||
/*********************************************************************/
|
||||
static int davicom_poll(struct nic *nic)
|
||||
{
|
||||
whereami("davicom_poll\n");
|
||||
|
||||
if (rxd[rxd_tail].status & 0x80000000)
|
||||
return 0;
|
||||
|
||||
whereami("davicom_poll got one\n");
|
||||
|
||||
nic->packetlen = (rxd[rxd_tail].status & 0x3FFF0000) >> 16;
|
||||
|
||||
if( rxd[rxd_tail].status & 0x00008000){
|
||||
rxd[rxd_tail].status = 0x80000000;
|
||||
rxd_tail++;
|
||||
if (rxd_tail == NRXD) rxd_tail = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* copy packet to working buffer */
|
||||
/* XXX - this copy could be avoided with a little more work
|
||||
but for now we are content with it because the optimised
|
||||
memcpy is quite fast */
|
||||
|
||||
memcpy(nic->packet, rxb + rxd_tail * BUFLEN, nic->packetlen);
|
||||
|
||||
/* return the descriptor and buffer to receive ring */
|
||||
rxd[rxd_tail].status = 0x80000000;
|
||||
rxd_tail++;
|
||||
if (rxd_tail == NRXD) rxd_tail = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
/* eth_disable - Disable the interface */
|
||||
/*********************************************************************/
|
||||
static void davicom_disable(struct nic *nic)
|
||||
{
|
||||
whereami("davicom_disable\n");
|
||||
|
||||
/* disable interrupts */
|
||||
outl(0x00000000, ioaddr + CSR7);
|
||||
|
||||
/* Stop the chip's Tx and Rx processes. */
|
||||
outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
|
||||
|
||||
/* Clear the missed-packet counter. */
|
||||
(volatile unsigned long)inl(ioaddr + CSR8);
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
/* eth_probe - Look for an adapter */
|
||||
/*********************************************************************/
|
||||
struct nic *davicom_probe(struct nic *nic, unsigned short *io_addrs,
|
||||
struct pci_device *pci)
|
||||
{
|
||||
unsigned int i;
|
||||
u32 l1, l2;
|
||||
|
||||
whereami("davicom_probe\n");
|
||||
|
||||
if (io_addrs == 0 || *io_addrs == 0)
|
||||
return 0;
|
||||
|
||||
vendor = pci->vendor;
|
||||
dev_id = pci->dev_id;
|
||||
ioaddr = *io_addrs;
|
||||
|
||||
/* wakeup chip */
|
||||
pcibios_write_config_dword(pci->bus, pci->devfn, 0x40, 0x00000000);
|
||||
|
||||
/* Stop the chip's Tx and Rx processes. */
|
||||
outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
|
||||
|
||||
/* Clear the missed-packet counter. */
|
||||
(volatile unsigned long)inl(ioaddr + CSR8);
|
||||
|
||||
/* Get MAC Address */
|
||||
/* read EEPROM data */
|
||||
for (i = 0; i < sizeof(ee_data)/2; i++)
|
||||
((unsigned short *)ee_data)[i] =
|
||||
le16_to_cpu(read_eeprom(ioaddr, i, EEPROM_ADDRLEN));
|
||||
|
||||
/* extract MAC address from EEPROM buffer */
|
||||
for (i=0; i<ETH_ALEN; i++)
|
||||
nic->node_addr[i] = ee_data[20+i];
|
||||
|
||||
printf("Davicom %! at ioaddr %#hX\n", nic->node_addr, ioaddr);
|
||||
|
||||
/* initialize device */
|
||||
davicom_reset(nic);
|
||||
|
||||
nic->reset = davicom_reset;
|
||||
nic->poll = davicom_poll;
|
||||
nic->transmit = davicom_transmit;
|
||||
nic->disable = davicom_disable;
|
||||
|
||||
return nic;
|
||||
}
|
||||
-752
@@ -1,752 +0,0 @@
|
||||
/* Etherboot: depca.h merged, comments from Linux driver retained */
|
||||
/* depca.c: A DIGITAL DEPCA & EtherWORKS ethernet driver for linux.
|
||||
|
||||
Written 1994, 1995 by David C. Davies.
|
||||
|
||||
|
||||
Copyright 1994 David C. Davies
|
||||
and
|
||||
United States Government
|
||||
(as represented by the Director, National Security Agency).
|
||||
|
||||
Copyright 1995 Digital Equipment Corporation.
|
||||
|
||||
|
||||
This software may be used and distributed according to the terms of
|
||||
the GNU Public License, incorporated herein by reference.
|
||||
|
||||
This driver is written for the Digital Equipment Corporation series
|
||||
of DEPCA and EtherWORKS ethernet cards:
|
||||
|
||||
DEPCA (the original)
|
||||
DE100
|
||||
DE101
|
||||
DE200 Turbo
|
||||
DE201 Turbo
|
||||
DE202 Turbo (TP BNC)
|
||||
DE210
|
||||
DE422 (EISA)
|
||||
|
||||
The driver has been tested on DE100, DE200 and DE202 cards in a
|
||||
relatively busy network. The DE422 has been tested a little.
|
||||
|
||||
This driver will NOT work for the DE203, DE204 and DE205 series of
|
||||
cards, since they have a new custom ASIC in place of the AMD LANCE
|
||||
chip. See the 'ewrk3.c' driver in the Linux source tree for running
|
||||
those cards.
|
||||
|
||||
I have benchmarked the driver with a DE100 at 595kB/s to (542kB/s from)
|
||||
a DECstation 5000/200.
|
||||
|
||||
The author may be reached at davies@maniac.ultranet.com
|
||||
|
||||
=========================================================================
|
||||
|
||||
The driver was originally based on the 'lance.c' driver from Donald
|
||||
Becker which is included with the standard driver distribution for
|
||||
linux. V0.4 is a complete re-write with only the kernel interface
|
||||
remaining from the original code.
|
||||
|
||||
1) Lance.c code in /linux/drivers/net/
|
||||
2) "Ethernet/IEEE 802.3 Family. 1992 World Network Data Book/Handbook",
|
||||
AMD, 1992 [(800) 222-9323].
|
||||
3) "Am79C90 CMOS Local Area Network Controller for Ethernet (C-LANCE)",
|
||||
AMD, Pub. #17881, May 1993.
|
||||
4) "Am79C960 PCnet-ISA(tm), Single-Chip Ethernet Controller for ISA",
|
||||
AMD, Pub. #16907, May 1992
|
||||
5) "DEC EtherWORKS LC Ethernet Controller Owners Manual",
|
||||
Digital Equipment corporation, 1990, Pub. #EK-DE100-OM.003
|
||||
6) "DEC EtherWORKS Turbo Ethernet Controller Owners Manual",
|
||||
Digital Equipment corporation, 1990, Pub. #EK-DE200-OM.003
|
||||
7) "DEPCA Hardware Reference Manual", Pub. #EK-DEPCA-PR
|
||||
Digital Equipment Corporation, 1989
|
||||
8) "DEC EtherWORKS Turbo_(TP BNC) Ethernet Controller Owners Manual",
|
||||
Digital Equipment corporation, 1991, Pub. #EK-DE202-OM.001
|
||||
|
||||
|
||||
Peter Bauer's depca.c (V0.5) was referred to when debugging V0.1 of this
|
||||
driver.
|
||||
|
||||
The original DEPCA card requires that the ethernet ROM address counter
|
||||
be enabled to count and has an 8 bit NICSR. The ROM counter enabling is
|
||||
only done when a 0x08 is read as the first address octet (to minimise
|
||||
the chances of writing over some other hardware's I/O register). The
|
||||
NICSR accesses have been changed to byte accesses for all the cards
|
||||
supported by this driver, since there is only one useful bit in the MSB
|
||||
(remote boot timeout) and it is not used. Also, there is a maximum of
|
||||
only 48kB network RAM for this card. My thanks to Torbjorn Lindh for
|
||||
help debugging all this (and holding my feet to the fire until I got it
|
||||
right).
|
||||
|
||||
The DE200 series boards have on-board 64kB RAM for use as a shared
|
||||
memory network buffer. Only the DE100 cards make use of a 2kB buffer
|
||||
mode which has not been implemented in this driver (only the 32kB and
|
||||
64kB modes are supported [16kB/48kB for the original DEPCA]).
|
||||
|
||||
At the most only 2 DEPCA cards can be supported on the ISA bus because
|
||||
there is only provision for two I/O base addresses on each card (0x300
|
||||
and 0x200). The I/O address is detected by searching for a byte sequence
|
||||
in the Ethernet station address PROM at the expected I/O address for the
|
||||
Ethernet PROM. The shared memory base address is 'autoprobed' by
|
||||
looking for the self test PROM and detecting the card name. When a
|
||||
second DEPCA is detected, information is placed in the base_addr
|
||||
variable of the next device structure (which is created if necessary),
|
||||
thus enabling ethif_probe initialization for the device. More than 2
|
||||
EISA cards can be supported, but care will be needed assigning the
|
||||
shared memory to ensure that each slot has the correct IRQ, I/O address
|
||||
and shared memory address assigned.
|
||||
|
||||
************************************************************************
|
||||
|
||||
NOTE: If you are using two ISA DEPCAs, it is important that you assign
|
||||
the base memory addresses correctly. The driver autoprobes I/O 0x300
|
||||
then 0x200. The base memory address for the first device must be less
|
||||
than that of the second so that the auto probe will correctly assign the
|
||||
I/O and memory addresses on the same card. I can't think of a way to do
|
||||
this unambiguously at the moment, since there is nothing on the cards to
|
||||
tie I/O and memory information together.
|
||||
|
||||
I am unable to test 2 cards together for now, so this code is
|
||||
unchecked. All reports, good or bad, are welcome.
|
||||
|
||||
************************************************************************
|
||||
|
||||
The board IRQ setting must be at an unused IRQ which is auto-probed
|
||||
using Donald Becker's autoprobe routines. DEPCA and DE100 board IRQs are
|
||||
{2,3,4,5,7}, whereas the DE200 is at {5,9,10,11,15}. Note that IRQ2 is
|
||||
really IRQ9 in machines with 16 IRQ lines.
|
||||
|
||||
No 16MB memory limitation should exist with this driver as DMA is not
|
||||
used and the common memory area is in low memory on the network card (my
|
||||
current system has 20MB and I've not had problems yet).
|
||||
|
||||
The ability to load this driver as a loadable module has been added. To
|
||||
utilise this ability, you have to do <8 things:
|
||||
|
||||
0) have a copy of the loadable modules code installed on your system.
|
||||
1) copy depca.c from the /linux/drivers/net directory to your favourite
|
||||
temporary directory.
|
||||
2) if you wish, edit the source code near line 1530 to reflect the I/O
|
||||
address and IRQ you're using (see also 5).
|
||||
3) compile depca.c, but include -DMODULE in the command line to ensure
|
||||
that the correct bits are compiled (see end of source code).
|
||||
4) if you are wanting to add a new card, goto 5. Otherwise, recompile a
|
||||
kernel with the depca configuration turned off and reboot.
|
||||
5) insmod depca.o [irq=7] [io=0x200] [mem=0xd0000] [adapter_name=DE100]
|
||||
[Alan Cox: Changed the code to allow command line irq/io assignments]
|
||||
[Dave Davies: Changed the code to allow command line mem/name
|
||||
assignments]
|
||||
6) run the net startup bits for your eth?? interface manually
|
||||
(usually /etc/rc.inet[12] at boot time).
|
||||
7) enjoy!
|
||||
|
||||
Note that autoprobing is not allowed in loadable modules - the system is
|
||||
already up and running and you're messing with interrupts.
|
||||
|
||||
To unload a module, turn off the associated interface
|
||||
'ifconfig eth?? down' then 'rmmod depca'.
|
||||
|
||||
To assign a base memory address for the shared memory when running as a
|
||||
loadable module, see 5 above. To include the adapter name (if you have
|
||||
no PROM but know the card name) also see 5 above. Note that this last
|
||||
option will not work with kernel built-in depca's.
|
||||
|
||||
The shared memory assignment for a loadable module makes sense to avoid
|
||||
the 'memory autoprobe' picking the wrong shared memory (for the case of
|
||||
2 depca's in a PC).
|
||||
|
||||
************************************************************************
|
||||
Support for MCA EtherWORKS cards added 11-3-98.
|
||||
Verified to work with up to 2 DE212 cards in a system (although not
|
||||
fully stress-tested).
|
||||
|
||||
Currently known bugs/limitations:
|
||||
|
||||
Note: with the MCA stuff as a module, it trusts the MCA configuration,
|
||||
not the command line for IRQ and memory address. You can
|
||||
specify them if you want, but it will throw your values out.
|
||||
You still have to pass the IO address it was configured as
|
||||
though.
|
||||
|
||||
************************************************************************
|
||||
TO DO:
|
||||
------
|
||||
|
||||
|
||||
Revision History
|
||||
----------------
|
||||
|
||||
Version Date Description
|
||||
|
||||
0.1 25-jan-94 Initial writing.
|
||||
0.2 27-jan-94 Added LANCE TX hardware buffer chaining.
|
||||
0.3 1-feb-94 Added multiple DEPCA support.
|
||||
0.31 4-feb-94 Added DE202 recognition.
|
||||
0.32 19-feb-94 Tidy up. Improve multi-DEPCA support.
|
||||
0.33 25-feb-94 Fix DEPCA ethernet ROM counter enable.
|
||||
Add jabber packet fix from murf@perftech.com
|
||||
and becker@super.org
|
||||
0.34 7-mar-94 Fix DEPCA max network memory RAM & NICSR access.
|
||||
0.35 8-mar-94 Added DE201 recognition. Tidied up.
|
||||
0.351 30-apr-94 Added EISA support. Added DE422 recognition.
|
||||
0.36 16-may-94 DE422 fix released.
|
||||
0.37 22-jul-94 Added MODULE support
|
||||
0.38 15-aug-94 Added DBR ROM switch in depca_close().
|
||||
Multi DEPCA bug fix.
|
||||
0.38axp 15-sep-94 Special version for Alpha AXP Linux V1.0.
|
||||
0.381 12-dec-94 Added DE101 recognition, fix multicast bug.
|
||||
0.382 9-feb-95 Fix recognition bug reported by <bkm@star.rl.ac.uk>.
|
||||
0.383 22-feb-95 Fix for conflict with VESA SCSI reported by
|
||||
<stromain@alf.dec.com>
|
||||
0.384 17-mar-95 Fix a ring full bug reported by <bkm@star.rl.ac.uk>
|
||||
0.385 3-apr-95 Fix a recognition bug reported by
|
||||
<ryan.niemi@lastfrontier.com>
|
||||
0.386 21-apr-95 Fix the last fix...sorry, must be galloping senility
|
||||
0.40 25-May-95 Rewrite for portability & updated.
|
||||
ALPHA support from <jestabro@amt.tay1.dec.com>
|
||||
0.41 26-Jun-95 Added verify_area() calls in depca_ioctl() from
|
||||
suggestion by <heiko@colossus.escape.de>
|
||||
0.42 27-Dec-95 Add 'mem' shared memory assignment for loadable
|
||||
modules.
|
||||
Add 'adapter_name' for loadable modules when no PROM.
|
||||
Both above from a suggestion by
|
||||
<pchen@woodruffs121.residence.gatech.edu>.
|
||||
Add new multicasting code.
|
||||
0.421 22-Apr-96 Fix alloc_device() bug <jari@markkus2.fimr.fi>
|
||||
0.422 29-Apr-96 Fix depca_hw_init() bug <jari@markkus2.fimr.fi>
|
||||
0.423 7-Jun-96 Fix module load bug <kmg@barco.be>
|
||||
0.43 16-Aug-96 Update alloc_device() to conform to de4x5.c
|
||||
0.44 1-Sep-97 Fix *_probe() to test check_region() first - bug
|
||||
reported by <mmogilvi@elbert.uccs.edu>
|
||||
0.45 3-Nov-98 Added support for MCA EtherWORKS (DE210/DE212) cards
|
||||
by <tymm@computer.org>
|
||||
0.451 5-Nov-98 Fixed mca stuff cuz I'm a dummy. <tymm@computer.org>
|
||||
0.5 14-Nov-98 Re-spin for 2.1.x kernels.
|
||||
0.51 27-Jun-99 Correct received packet length for CRC from
|
||||
report by <worm@dkik.dk>
|
||||
|
||||
=========================================================================
|
||||
*/
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "cards.h"
|
||||
|
||||
/*
|
||||
** I/O addresses. Note that the 2k buffer option is not supported in
|
||||
** this driver.
|
||||
*/
|
||||
#define DEPCA_NICSR ioaddr+0x00 /* Network interface CSR */
|
||||
#define DEPCA_RBI ioaddr+0x02 /* RAM buffer index (2k buffer mode) */
|
||||
#define DEPCA_DATA ioaddr+0x04 /* LANCE registers' data port */
|
||||
#define DEPCA_ADDR ioaddr+0x06 /* LANCE registers' address port */
|
||||
#define DEPCA_HBASE ioaddr+0x08 /* EISA high memory base address reg. */
|
||||
#define DEPCA_PROM ioaddr+0x0c /* Ethernet address ROM data port */
|
||||
#define DEPCA_CNFG ioaddr+0x0c /* EISA Configuration port */
|
||||
#define DEPCA_RBSA ioaddr+0x0e /* RAM buffer starting address (2k buff.) */
|
||||
|
||||
/*
|
||||
** These are LANCE registers addressable through DEPCA_ADDR
|
||||
*/
|
||||
#define CSR0 0
|
||||
#define CSR1 1
|
||||
#define CSR2 2
|
||||
#define CSR3 3
|
||||
|
||||
/*
|
||||
** NETWORK INTERFACE CSR (NI_CSR) bit definitions
|
||||
*/
|
||||
|
||||
#define TO 0x0100 /* Time Out for remote boot */
|
||||
#define SHE 0x0080 /* SHadow memory Enable */
|
||||
#define BS 0x0040 /* Bank Select */
|
||||
#define BUF 0x0020 /* BUFfer size (1->32k, 0->64k) */
|
||||
#define RBE 0x0010 /* Remote Boot Enable (1->net boot) */
|
||||
#define AAC 0x0008 /* Address ROM Address Counter (1->enable) */
|
||||
#define _128KB 0x0008 /* 128kB Network RAM (1->enable) */
|
||||
#define IM 0x0004 /* Interrupt Mask (1->mask) */
|
||||
#define IEN 0x0002 /* Interrupt tristate ENable (1->enable) */
|
||||
#define LED 0x0001 /* LED control */
|
||||
|
||||
/*
|
||||
** Control and Status Register 0 (CSR0) bit definitions
|
||||
*/
|
||||
|
||||
#define ERR 0x8000 /* Error summary */
|
||||
#define BABL 0x4000 /* Babble transmitter timeout error */
|
||||
#define CERR 0x2000 /* Collision Error */
|
||||
#define MISS 0x1000 /* Missed packet */
|
||||
#define MERR 0x0800 /* Memory Error */
|
||||
#define RINT 0x0400 /* Receiver Interrupt */
|
||||
#define TINT 0x0200 /* Transmit Interrupt */
|
||||
#define IDON 0x0100 /* Initialization Done */
|
||||
#define INTR 0x0080 /* Interrupt Flag */
|
||||
#define INEA 0x0040 /* Interrupt Enable */
|
||||
#define RXON 0x0020 /* Receiver on */
|
||||
#define TXON 0x0010 /* Transmitter on */
|
||||
#define TDMD 0x0008 /* Transmit Demand */
|
||||
#define STOP 0x0004 /* Stop */
|
||||
#define STRT 0x0002 /* Start */
|
||||
#define INIT 0x0001 /* Initialize */
|
||||
#define INTM 0xff00 /* Interrupt Mask */
|
||||
#define INTE 0xfff0 /* Interrupt Enable */
|
||||
|
||||
/*
|
||||
** CONTROL AND STATUS REGISTER 3 (CSR3)
|
||||
*/
|
||||
|
||||
#define BSWP 0x0004 /* Byte SWaP */
|
||||
#define ACON 0x0002 /* ALE control */
|
||||
#define BCON 0x0001 /* Byte CONtrol */
|
||||
|
||||
/*
|
||||
** Initialization Block Mode Register
|
||||
*/
|
||||
|
||||
#define PROM 0x8000 /* Promiscuous Mode */
|
||||
#define EMBA 0x0080 /* Enable Modified Back-off Algorithm */
|
||||
#define INTL 0x0040 /* Internal Loopback */
|
||||
#define DRTY 0x0020 /* Disable Retry */
|
||||
#define COLL 0x0010 /* Force Collision */
|
||||
#define DTCR 0x0008 /* Disable Transmit CRC */
|
||||
#define LOOP 0x0004 /* Loopback */
|
||||
#define DTX 0x0002 /* Disable the Transmitter */
|
||||
#define DRX 0x0001 /* Disable the Receiver */
|
||||
|
||||
/*
|
||||
** Receive Message Descriptor 1 (RMD1) bit definitions.
|
||||
*/
|
||||
|
||||
#define R_OWN 0x80000000 /* Owner bit 0 = host, 1 = lance */
|
||||
#define R_ERR 0x4000 /* Error Summary */
|
||||
#define R_FRAM 0x2000 /* Framing Error */
|
||||
#define R_OFLO 0x1000 /* Overflow Error */
|
||||
#define R_CRC 0x0800 /* CRC Error */
|
||||
#define R_BUFF 0x0400 /* Buffer Error */
|
||||
#define R_STP 0x0200 /* Start of Packet */
|
||||
#define R_ENP 0x0100 /* End of Packet */
|
||||
|
||||
/*
|
||||
** Transmit Message Descriptor 1 (TMD1) bit definitions.
|
||||
*/
|
||||
|
||||
#define T_OWN 0x80000000 /* Owner bit 0 = host, 1 = lance */
|
||||
#define T_ERR 0x4000 /* Error Summary */
|
||||
#define T_ADD_FCS 0x2000 /* More the 1 retry needed to Xmit */
|
||||
#define T_MORE 0x1000 /* >1 retry to transmit packet */
|
||||
#define T_ONE 0x0800 /* 1 try needed to transmit the packet */
|
||||
#define T_DEF 0x0400 /* Deferred */
|
||||
#define T_STP 0x02000000 /* Start of Packet */
|
||||
#define T_ENP 0x01000000 /* End of Packet */
|
||||
#define T_FLAGS 0xff000000 /* TX Flags Field */
|
||||
|
||||
/*
|
||||
** Transmit Message Descriptor 3 (TMD3) bit definitions.
|
||||
*/
|
||||
|
||||
#define TMD3_BUFF 0x8000 /* BUFFer error */
|
||||
#define TMD3_UFLO 0x4000 /* UnderFLOw error */
|
||||
#define TMD3_RES 0x2000 /* REServed */
|
||||
#define TMD3_LCOL 0x1000 /* Late COLlision */
|
||||
#define TMD3_LCAR 0x0800 /* Loss of CARrier */
|
||||
#define TMD3_RTRY 0x0400 /* ReTRY error */
|
||||
|
||||
/*
|
||||
** Ethernet PROM defines
|
||||
*/
|
||||
#define PROBE_LENGTH 32
|
||||
|
||||
/*
|
||||
** Set the number of Tx and Rx buffers. Ensure that the memory requested
|
||||
** here is <= to the amount of shared memory set up by the board switches.
|
||||
** The number of descriptors MUST BE A POWER OF 2.
|
||||
**
|
||||
** total_memory = NUM_RX_DESC*(8+RX_BUFF_SZ) + NUM_TX_DESC*(8+TX_BUFF_SZ)
|
||||
*/
|
||||
#define NUM_RX_DESC 2 /* Number of RX descriptors */
|
||||
#define NUM_TX_DESC 2 /* Number of TX descriptors */
|
||||
#define RX_BUFF_SZ 1536 /* Buffer size for each Rx buffer */
|
||||
#define TX_BUFF_SZ 1536 /* Buffer size for each Tx buffer */
|
||||
|
||||
/*
|
||||
** ISA Bus defines
|
||||
*/
|
||||
#define DEPCA_IO_PORTS {0x300, 0x200, 0}
|
||||
|
||||
#ifndef DEPCA_MODEL
|
||||
#define DEPCA_MODEL DEPCA
|
||||
#endif
|
||||
|
||||
static enum {
|
||||
DEPCA, DE100, DE101, DE200, DE201, DE202, DE210, DE212, DE422, unknown
|
||||
} adapter = DEPCA_MODEL;
|
||||
|
||||
/*
|
||||
** Name <-> Adapter mapping
|
||||
*/
|
||||
|
||||
static char *adapter_name[] = {
|
||||
"DEPCA",
|
||||
"DE100","DE101",
|
||||
"DE200","DE201","DE202",
|
||||
"DE210","DE212",
|
||||
"DE422",
|
||||
""
|
||||
};
|
||||
|
||||
#ifndef DEPCA_RAM_BASE
|
||||
#define DEPCA_RAM_BASE 0xd0000
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Memory Alignment. Each descriptor is 4 longwords long. To force a
|
||||
** particular alignment on the TX descriptor, adjust DESC_SKIP_LEN and
|
||||
** DESC_ALIGN. ALIGN aligns the start address of the private memory area
|
||||
** and hence the RX descriptor ring's first entry.
|
||||
*/
|
||||
#define ALIGN4 ((u32)4 - 1) /* 1 longword align */
|
||||
#define ALIGN8 ((u32)8 - 1) /* 2 longword (quadword) align */
|
||||
#define ALIGN ALIGN8 /* Keep the LANCE happy... */
|
||||
|
||||
typedef long s32;
|
||||
typedef unsigned long u32;
|
||||
typedef short s16;
|
||||
typedef unsigned short u16;
|
||||
typedef char s8;
|
||||
typedef unsigned char u8;
|
||||
|
||||
/*
|
||||
** The DEPCA Rx and Tx ring descriptors.
|
||||
*/
|
||||
struct depca_rx_desc {
|
||||
volatile s32 base;
|
||||
s16 buf_length; /* This length is negative 2's complement! */
|
||||
s16 msg_length; /* This length is "normal". */
|
||||
};
|
||||
|
||||
struct depca_tx_desc {
|
||||
volatile s32 base;
|
||||
s16 length; /* This length is negative 2's complement! */
|
||||
s16 misc; /* Errors and TDR info */
|
||||
};
|
||||
|
||||
#define LA_MASK 0x0000ffff /* LANCE address mask for mapping network RAM
|
||||
to LANCE memory address space */
|
||||
|
||||
/*
|
||||
** The Lance initialization block, described in databook, in common memory.
|
||||
*/
|
||||
struct depca_init {
|
||||
u16 mode; /* Mode register */
|
||||
u8 phys_addr[ETH_ALEN]; /* Physical ethernet address */
|
||||
u8 mcast_table[8]; /* Multicast Hash Table. */
|
||||
u32 rx_ring; /* Rx ring base pointer & ring length */
|
||||
u32 tx_ring; /* Tx ring base pointer & ring length */
|
||||
};
|
||||
|
||||
struct depca_private {
|
||||
struct depca_rx_desc *rx_ring;
|
||||
struct depca_tx_desc *tx_ring;
|
||||
struct depca_init init_block; /* Shadow init block */
|
||||
char *rx_memcpy[NUM_RX_DESC];
|
||||
char *tx_memcpy[NUM_TX_DESC];
|
||||
u32 bus_offset; /* ISA bus address offset */
|
||||
u32 sh_mem; /* address of shared mem */
|
||||
u32 dma_buffs; /* Rx & Tx buffer start */
|
||||
int rx_cur, tx_cur; /* Next free ring entry */
|
||||
int txRingMask, rxRingMask;
|
||||
s32 rx_rlen, tx_rlen;
|
||||
/* log2([rt]xRingMask+1) for the descriptors */
|
||||
};
|
||||
|
||||
static Address mem_start = DEPCA_RAM_BASE;
|
||||
static Address mem_len, offset;
|
||||
static unsigned short ioaddr = 0;
|
||||
static struct depca_private lp;
|
||||
|
||||
/*
|
||||
** Miscellaneous defines...
|
||||
*/
|
||||
#define STOP_DEPCA \
|
||||
outw(CSR0, DEPCA_ADDR);\
|
||||
outw(STOP, DEPCA_DATA)
|
||||
|
||||
/* Initialize the lance Rx and Tx descriptor rings. */
|
||||
static void depca_init_ring(struct nic *nic)
|
||||
{
|
||||
int i;
|
||||
u32 p;
|
||||
|
||||
lp.rx_cur = lp.tx_cur = 0;
|
||||
/* Initialize the base addresses and length of each buffer in the ring */
|
||||
for (i = 0; i <= lp.rxRingMask; i++) {
|
||||
writel((p = lp.dma_buffs + i * RX_BUFF_SZ) | R_OWN, &lp.rx_ring[i].base);
|
||||
writew(-RX_BUFF_SZ, &lp.rx_ring[i].buf_length);
|
||||
lp.rx_memcpy[i] = (char *) (p + lp.bus_offset);
|
||||
}
|
||||
for (i = 0; i <= lp.txRingMask; i++) {
|
||||
writel((p = lp.dma_buffs + (i + lp.txRingMask + 1) * TX_BUFF_SZ) & 0x00ffffff, &lp.tx_ring[i].base);
|
||||
lp.tx_memcpy[i] = (char *) (p + lp.bus_offset);
|
||||
}
|
||||
|
||||
/* Set up the initialization block */
|
||||
lp.init_block.rx_ring = ((u32) ((u32) lp.rx_ring) & LA_MASK) | lp.rx_rlen;
|
||||
lp.init_block.tx_ring = ((u32) ((u32) lp.tx_ring) & LA_MASK) | lp.tx_rlen;
|
||||
for (i = 0; i < ETH_ALEN; i++)
|
||||
lp.init_block.phys_addr[i] = nic->node_addr[i];
|
||||
lp.init_block.mode = 0x0000; /* Enable the Tx and Rx */
|
||||
memset(lp.init_block.mcast_table, 0, sizeof(lp.init_block.mcast_table));
|
||||
}
|
||||
|
||||
static void LoadCSRs(void)
|
||||
{
|
||||
outw(CSR1, DEPCA_ADDR); /* initialisation block address LSW */
|
||||
outw((u16) (lp.sh_mem & LA_MASK), DEPCA_DATA);
|
||||
outw(CSR2, DEPCA_ADDR); /* initialisation block address MSW */
|
||||
outw((u16) ((lp.sh_mem & LA_MASK) >> 16), DEPCA_DATA);
|
||||
outw(CSR3, DEPCA_ADDR); /* ALE control */
|
||||
outw(ACON, DEPCA_DATA);
|
||||
outw(CSR0, DEPCA_ADDR); /* Point back to CSR0 */
|
||||
}
|
||||
|
||||
static int InitRestartDepca(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Copy the shadow init_block to shared memory */
|
||||
memcpy_toio((char *)lp.sh_mem, &lp.init_block, sizeof(struct depca_init));
|
||||
outw(CSR0, DEPCA_ADDR); /* point back to CSR0 */
|
||||
outw(INIT, DEPCA_DATA); /* initialise DEPCA */
|
||||
|
||||
for (i = 0; i < 100 && !(inw(DEPCA_DATA) & IDON); i++)
|
||||
;
|
||||
if (i < 100) {
|
||||
/* clear IDON by writing a 1, and start LANCE */
|
||||
outw(IDON | STRT, DEPCA_DATA);
|
||||
} else {
|
||||
printf("DEPCA not initialised\n");
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
RESET - Reset adapter
|
||||
***************************************************************************/
|
||||
static void depca_reset(struct nic *nic)
|
||||
{
|
||||
s16 nicsr;
|
||||
int i, j;
|
||||
|
||||
STOP_DEPCA;
|
||||
nicsr = inb(DEPCA_NICSR);
|
||||
nicsr = ((nicsr & ~SHE & ~RBE & ~IEN) | IM);
|
||||
outb(nicsr, DEPCA_NICSR);
|
||||
if (inw(DEPCA_DATA) != STOP)
|
||||
{
|
||||
printf("depca: Cannot stop NIC\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialisation block */
|
||||
lp.sh_mem = mem_start;
|
||||
mem_start += sizeof(struct depca_init);
|
||||
/* Tx & Rx descriptors (aligned to a quadword boundary) */
|
||||
mem_start = (mem_start + ALIGN) & ~ALIGN;
|
||||
lp.rx_ring = (struct depca_rx_desc *) mem_start;
|
||||
mem_start += (sizeof(struct depca_rx_desc) * NUM_RX_DESC);
|
||||
lp.tx_ring = (struct depca_tx_desc *) mem_start;
|
||||
mem_start += (sizeof(struct depca_tx_desc) * NUM_TX_DESC);
|
||||
|
||||
lp.bus_offset = mem_start & 0x00ff0000;
|
||||
/* LANCE re-mapped start address */
|
||||
lp.dma_buffs = mem_start & LA_MASK;
|
||||
|
||||
/* Finish initialising the ring information. */
|
||||
lp.rxRingMask = NUM_RX_DESC - 1;
|
||||
lp.txRingMask = NUM_TX_DESC - 1;
|
||||
|
||||
/* Calculate Tx/Rx RLEN size for the descriptors. */
|
||||
for (i = 0, j = lp.rxRingMask; j > 0; i++) {
|
||||
j >>= 1;
|
||||
}
|
||||
lp.rx_rlen = (s32) (i << 29);
|
||||
for (i = 0, j = lp.txRingMask; j > 0; i++) {
|
||||
j >>= 1;
|
||||
}
|
||||
lp.tx_rlen = (s32) (i << 29);
|
||||
|
||||
/* Load the initialisation block */
|
||||
depca_init_ring(nic);
|
||||
LoadCSRs();
|
||||
InitRestartDepca();
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
POLL - Wait for a frame
|
||||
***************************************************************************/
|
||||
static int depca_poll(struct nic *nic)
|
||||
{
|
||||
int entry;
|
||||
u32 status;
|
||||
|
||||
entry = lp.rx_cur;
|
||||
if ((status = readl(&lp.rx_ring[entry].base) & R_OWN))
|
||||
return (0);
|
||||
memcpy(nic->packet, lp.rx_memcpy[entry], nic->packetlen = lp.rx_ring[entry].msg_length);
|
||||
lp.rx_ring[entry].base |= R_OWN;
|
||||
lp.rx_cur = (++lp.rx_cur) & lp.rxRingMask;
|
||||
return (1);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
TRANSMIT - Transmit a frame
|
||||
***************************************************************************/
|
||||
static void depca_transmit(
|
||||
struct nic *nic,
|
||||
const char *d, /* Destination */
|
||||
unsigned int t, /* Type */
|
||||
unsigned int s, /* size */
|
||||
const char *p) /* Packet */
|
||||
{
|
||||
int entry, len;
|
||||
char *mem;
|
||||
|
||||
/* send the packet to destination */
|
||||
/*
|
||||
** Caution: the right order is important here... dont
|
||||
** setup the ownership rights until all the other
|
||||
** information is in place
|
||||
*/
|
||||
mem = lp.tx_memcpy[entry = lp.tx_cur];
|
||||
memcpy_toio(mem, d, ETH_ALEN);
|
||||
memcpy_toio(mem + ETH_ALEN, nic->node_addr, ETH_ALEN);
|
||||
mem[ETH_ALEN * 2] = t >> 8;
|
||||
mem[ETH_ALEN * 2 + 1] = t;
|
||||
memcpy_toio(mem + ETH_HLEN, p, s);
|
||||
s += ETH_HLEN;
|
||||
len = (s < ETH_ZLEN ? ETH_ZLEN : s);
|
||||
/* clean out flags */
|
||||
writel(readl(&lp.tx_ring[entry].base) & ~T_FLAGS, &lp.tx_ring[entry].base);
|
||||
/* clears other error flags */
|
||||
writew(0x0000, &lp.tx_ring[entry].misc);
|
||||
/* packet length in buffer */
|
||||
writew(-len, &lp.tx_ring[entry].length);
|
||||
/* start and end of packet, ownership */
|
||||
writel(readl(&lp.tx_ring[entry].base) | (T_STP|T_ENP|T_OWN), &lp.tx_ring[entry].base);
|
||||
/* update current pointers */
|
||||
lp.tx_cur = (++lp.tx_cur) & lp.txRingMask;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
DISABLE - Turn off ethernet interface
|
||||
***************************************************************************/
|
||||
static void depca_disable(struct nic *nic)
|
||||
{
|
||||
STOP_DEPCA;
|
||||
}
|
||||
|
||||
/*
|
||||
** Look for a special sequence in the Ethernet station address PROM that
|
||||
** is common across all DEPCA products. Note that the original DEPCA needs
|
||||
** its ROM address counter to be initialized and enabled. Only enable
|
||||
** if the first address octet is a 0x08 - this minimises the chances of
|
||||
** messing around with some other hardware, but it assumes that this DEPCA
|
||||
** card initialized itself correctly.
|
||||
**
|
||||
** Search the Ethernet address ROM for the signature. Since the ROM address
|
||||
** counter can start at an arbitrary point, the search must include the entire
|
||||
** probe sequence length plus the (length_of_the_signature - 1).
|
||||
** Stop the search IMMEDIATELY after the signature is found so that the
|
||||
** PROM address counter is correctly positioned at the start of the
|
||||
** ethernet address for later read out.
|
||||
*/
|
||||
static int depca_probe1(struct nic *nic)
|
||||
{
|
||||
u8 data, nicsr;
|
||||
/* This is only correct for little endian machines, but then
|
||||
Etherboot doesn't work on anything but a PC */
|
||||
u8 sig[] = { 0xFF, 0x00, 0x55, 0xAA, 0xFF, 0x00, 0x55, 0xAA };
|
||||
int i, j;
|
||||
long sum, chksum;
|
||||
|
||||
data = inb(DEPCA_PROM); /* clear counter on DEPCA */
|
||||
data = inb(DEPCA_PROM); /* read data */
|
||||
if (data == 0x8) {
|
||||
nicsr = inb(DEPCA_NICSR);
|
||||
nicsr |= AAC;
|
||||
outb(nicsr, DEPCA_NICSR);
|
||||
}
|
||||
for (i = 0, j = 0; j < (int)sizeof(sig) && i < PROBE_LENGTH+((int)sizeof(sig))-1; ++i) {
|
||||
data = inb(DEPCA_PROM);
|
||||
if (data == sig[j]) /* track signature */
|
||||
++j;
|
||||
else
|
||||
j = (data == sig[0]) ? 1 : 0;
|
||||
}
|
||||
if (j != sizeof(sig))
|
||||
return (0);
|
||||
/* put the card in its initial state */
|
||||
STOP_DEPCA;
|
||||
nicsr = ((inb(DEPCA_NICSR) & ~SHE & ~RBE & ~IEN) | IM);
|
||||
outb(nicsr, DEPCA_NICSR);
|
||||
if (inw(DEPCA_DATA) != STOP)
|
||||
return (0);
|
||||
memcpy((char *)mem_start, sig, sizeof(sig));
|
||||
if (memcmp((char *)mem_start, sig, sizeof(sig)) != 0)
|
||||
return (0);
|
||||
for (i = 0, j = 0, sum = 0; j < 3; j++) {
|
||||
sum <<= 1;
|
||||
if (sum > 0xFFFF)
|
||||
sum -= 0xFFFF;
|
||||
sum += (u8)(nic->node_addr[i++] = inb(DEPCA_PROM));
|
||||
sum += (u16)((nic->node_addr[i++] = inb(DEPCA_PROM)) << 8);
|
||||
if (sum > 0xFFFF)
|
||||
sum -= 0xFFFF;
|
||||
}
|
||||
if (sum == 0xFFFF)
|
||||
sum = 0;
|
||||
chksum = (u8)inb(DEPCA_PROM);
|
||||
chksum |= (u16)(inb(DEPCA_PROM) << 8);
|
||||
mem_len = (adapter == DEPCA) ? (48 << 10) : (64 << 10);
|
||||
offset = 0;
|
||||
if (nicsr & BUF) {
|
||||
offset = 0x8000;
|
||||
nicsr &= ~BS;
|
||||
mem_len -= (32 << 10);
|
||||
}
|
||||
if (adapter != DEPCA) /* enable shadow RAM */
|
||||
outb(nicsr |= SHE, DEPCA_NICSR);
|
||||
printf("%s base %#hX, memory [%#hX-%#hX], addr %!",
|
||||
adapter_name[adapter], ioaddr, mem_start, mem_start + mem_len,
|
||||
nic->node_addr);
|
||||
if (sum != chksum)
|
||||
printf(" (bad checksum)");
|
||||
putchar('\n');
|
||||
return (1);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
PROBE - Look for an adapter, this routine's visible to the outside
|
||||
***************************************************************************/
|
||||
struct nic *depca_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||
{
|
||||
static unsigned short base[] = DEPCA_IO_PORTS;
|
||||
int i;
|
||||
|
||||
if (probe_addrs == 0 || probe_addrs[0] == 0)
|
||||
probe_addrs = base; /* Use defaults */
|
||||
for (i = 0; (ioaddr = base[i]) != 0; ++i) {
|
||||
if (depca_probe1(nic))
|
||||
break;
|
||||
}
|
||||
if (ioaddr == 0)
|
||||
return (0);
|
||||
depca_reset(nic);
|
||||
/* point to NIC specific routines */
|
||||
nic->reset = depca_reset;
|
||||
nic->poll = depca_poll;
|
||||
nic->transmit = depca_transmit;
|
||||
nic->disable = depca_disable;
|
||||
return (nic);
|
||||
}
|
||||
-586
@@ -1,586 +0,0 @@
|
||||
/**************************************************************************
|
||||
Etherboot - BOOTP/TFTP Bootstrap Program
|
||||
Intel EEPRO/10 NIC driver for Etherboot
|
||||
Adapted from Linux eepro.c from kernel 2.2.17
|
||||
|
||||
This board accepts a 32 pin EEPROM (29C256), however a test with a
|
||||
27C010 shows that this EPROM also works in the socket, but it's not clear
|
||||
how repeatably. The two top address pins appear to be held low, thus
|
||||
the bottom 32kB of the 27C010 is visible in the CPU's address space.
|
||||
To be sure you could put 4 copies of the code in the 27C010, then
|
||||
it doesn't matter whether the extra lines are held low or high, just
|
||||
hopefully not floating as CMOS chips don't like floating inputs.
|
||||
|
||||
Be careful with seating the EPROM as the socket on my board actually
|
||||
has 34 pins, the top row of 2 are not used.
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* 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, or (at
|
||||
* your option) any later version.
|
||||
*/
|
||||
|
||||
/* to get some global routines like printf */
|
||||
#include "etherboot.h"
|
||||
/* to get the interface to the body of the program */
|
||||
#include "nic.h"
|
||||
/* to get our own prototype */
|
||||
#include "cards.h"
|
||||
/* we use timer2 for microsecond waits */
|
||||
#include "timer.h"
|
||||
|
||||
#undef DEBUG /* only after include files */
|
||||
|
||||
/* Different 82595 chips */
|
||||
#define LAN595 0
|
||||
#define LAN595TX 1
|
||||
#define LAN595FX 2
|
||||
#define LAN595FX_10ISA 3
|
||||
|
||||
#define SLOW_DOWN inb(0x80);
|
||||
|
||||
/* The station (ethernet) address prefix, used for IDing the board. */
|
||||
#define SA_ADDR0 0x00 /* Etherexpress Pro/10 */
|
||||
#define SA_ADDR1 0xaa
|
||||
#define SA_ADDR2 0x00
|
||||
|
||||
#define GetBit(x,y) ((x & (1<<y))>>y)
|
||||
|
||||
/* EEPROM Word 0: */
|
||||
#define ee_PnP 0 /* Plug 'n Play enable bit */
|
||||
#define ee_Word1 1 /* Word 1? */
|
||||
#define ee_BusWidth 2 /* 8/16 bit */
|
||||
#define ee_FlashAddr 3 /* Flash Address */
|
||||
#define ee_FlashMask 0x7 /* Mask */
|
||||
#define ee_AutoIO 6 /* */
|
||||
#define ee_reserved0 7 /* =0! */
|
||||
#define ee_Flash 8 /* Flash there? */
|
||||
#define ee_AutoNeg 9 /* Auto Negotiation enabled? */
|
||||
#define ee_IO0 10 /* IO Address LSB */
|
||||
#define ee_IO0Mask 0x /*...*/
|
||||
#define ee_IO1 15 /* IO MSB */
|
||||
|
||||
/* EEPROM Word 1: */
|
||||
#define ee_IntSel 0 /* Interrupt */
|
||||
#define ee_IntMask 0x7
|
||||
#define ee_LI 3 /* Link Integrity 0= enabled */
|
||||
#define ee_PC 4 /* Polarity Correction 0= enabled */
|
||||
#define ee_TPE_AUI 5 /* PortSelection 1=TPE */
|
||||
#define ee_Jabber 6 /* Jabber prevention 0= enabled */
|
||||
#define ee_AutoPort 7 /* Auto Port Selection 1= Disabled */
|
||||
#define ee_SMOUT 8 /* SMout Pin Control 0= Input */
|
||||
#define ee_PROM 9 /* Flash EPROM / PROM 0=Flash */
|
||||
#define ee_reserved1 10 /* .. 12 =0! */
|
||||
#define ee_AltReady 13 /* Alternate Ready, 0=normal */
|
||||
#define ee_reserved2 14 /* =0! */
|
||||
#define ee_Duplex 15
|
||||
|
||||
/* Word2,3,4: */
|
||||
#define ee_IA5 0 /*bit start for individual Addr Byte 5 */
|
||||
#define ee_IA4 8 /*bit start for individual Addr Byte 5 */
|
||||
#define ee_IA3 0 /*bit start for individual Addr Byte 5 */
|
||||
#define ee_IA2 8 /*bit start for individual Addr Byte 5 */
|
||||
#define ee_IA1 0 /*bit start for individual Addr Byte 5 */
|
||||
#define ee_IA0 8 /*bit start for individual Addr Byte 5 */
|
||||
|
||||
/* Word 5: */
|
||||
#define ee_BNC_TPE 0 /* 0=TPE */
|
||||
#define ee_BootType 1 /* 00=None, 01=IPX, 10=ODI, 11=NDIS */
|
||||
#define ee_BootTypeMask 0x3
|
||||
#define ee_NumConn 3 /* Number of Connections 0= One or Two */
|
||||
#define ee_FlashSock 4 /* Presence of Flash Socket 0= Present */
|
||||
#define ee_PortTPE 5
|
||||
#define ee_PortBNC 6
|
||||
#define ee_PortAUI 7
|
||||
#define ee_PowerMgt 10 /* 0= disabled */
|
||||
#define ee_CP 13 /* Concurrent Processing */
|
||||
#define ee_CPMask 0x7
|
||||
|
||||
/* Word 6: */
|
||||
#define ee_Stepping 0 /* Stepping info */
|
||||
#define ee_StepMask 0x0F
|
||||
#define ee_BoardID 4 /* Manucaturer Board ID, reserved */
|
||||
#define ee_BoardMask 0x0FFF
|
||||
|
||||
/* Word 7: */
|
||||
#define ee_INT_TO_IRQ 0 /* int to IRQ Mapping = 0x1EB8 for Pro/10+ */
|
||||
#define ee_FX_INT2IRQ 0x1EB8 /* the _only_ mapping allowed for FX chips */
|
||||
|
||||
/*..*/
|
||||
#define ee_SIZE 0x40 /* total EEprom Size */
|
||||
#define ee_Checksum 0xBABA /* initial and final value for adding checksum */
|
||||
|
||||
|
||||
/* Card identification via EEprom: */
|
||||
#define ee_addr_vendor 0x10 /* Word offset for EISA Vendor ID */
|
||||
#define ee_addr_id 0x11 /* Word offset for Card ID */
|
||||
#define ee_addr_SN 0x12 /* Serial Number */
|
||||
#define ee_addr_CRC_8 0x14 /* CRC over last thee Bytes */
|
||||
|
||||
|
||||
#define ee_vendor_intel0 0x25 /* Vendor ID Intel */
|
||||
#define ee_vendor_intel1 0xD4
|
||||
#define ee_id_eepro10p0 0x10 /* ID for eepro/10+ */
|
||||
#define ee_id_eepro10p1 0x31
|
||||
|
||||
/* now this section could be used by both boards: the oldies and the ee10:
|
||||
* ee10 uses tx buffer before of rx buffer and the oldies the inverse.
|
||||
* (aris)
|
||||
*/
|
||||
#define RAM_SIZE 0x8000
|
||||
|
||||
#define RCV_HEADER 8
|
||||
#define RCV_DEFAULT_RAM 0x6000
|
||||
#define RCV_RAM rcv_ram
|
||||
|
||||
static unsigned rcv_ram = RCV_DEFAULT_RAM;
|
||||
|
||||
#define XMT_HEADER 8
|
||||
#define XMT_RAM (RAM_SIZE - RCV_RAM)
|
||||
|
||||
#define XMT_START ((rcv_start + RCV_RAM) % RAM_SIZE)
|
||||
|
||||
#define RCV_LOWER_LIMIT (rcv_start >> 8)
|
||||
#define RCV_UPPER_LIMIT (((rcv_start + RCV_RAM) - 2) >> 8)
|
||||
#define XMT_LOWER_LIMIT (XMT_START >> 8)
|
||||
#define XMT_UPPER_LIMIT (((XMT_START + XMT_RAM) - 2) >> 8)
|
||||
|
||||
#define RCV_START_PRO 0x00
|
||||
#define RCV_START_10 XMT_RAM
|
||||
/* by default the old driver */
|
||||
static unsigned rcv_start = RCV_START_PRO;
|
||||
|
||||
#define RCV_DONE 0x0008
|
||||
#define RX_OK 0x2000
|
||||
#define RX_ERROR 0x0d81
|
||||
|
||||
#define TX_DONE_BIT 0x0080
|
||||
#define CHAIN_BIT 0x8000
|
||||
#define XMT_STATUS 0x02
|
||||
#define XMT_CHAIN 0x04
|
||||
#define XMT_COUNT 0x06
|
||||
|
||||
#define BANK0_SELECT 0x00
|
||||
#define BANK1_SELECT 0x40
|
||||
#define BANK2_SELECT 0x80
|
||||
|
||||
/* Bank 0 registers */
|
||||
#define COMMAND_REG 0x00 /* Register 0 */
|
||||
#define MC_SETUP 0x03
|
||||
#define XMT_CMD 0x04
|
||||
#define DIAGNOSE_CMD 0x07
|
||||
#define RCV_ENABLE_CMD 0x08
|
||||
#define RCV_DISABLE_CMD 0x0a
|
||||
#define STOP_RCV_CMD 0x0b
|
||||
#define RESET_CMD 0x0e
|
||||
#define POWER_DOWN_CMD 0x18
|
||||
#define RESUME_XMT_CMD 0x1c
|
||||
#define SEL_RESET_CMD 0x1e
|
||||
#define STATUS_REG 0x01 /* Register 1 */
|
||||
#define RX_INT 0x02
|
||||
#define TX_INT 0x04
|
||||
#define EXEC_STATUS 0x30
|
||||
#define ID_REG 0x02 /* Register 2 */
|
||||
#define R_ROBIN_BITS 0xc0 /* round robin counter */
|
||||
#define ID_REG_MASK 0x2c
|
||||
#define ID_REG_SIG 0x24
|
||||
#define AUTO_ENABLE 0x10
|
||||
#define INT_MASK_REG 0x03 /* Register 3 */
|
||||
#define RX_STOP_MASK 0x01
|
||||
#define RX_MASK 0x02
|
||||
#define TX_MASK 0x04
|
||||
#define EXEC_MASK 0x08
|
||||
#define ALL_MASK 0x0f
|
||||
#define IO_32_BIT 0x10
|
||||
#define RCV_BAR 0x04 /* The following are word (16-bit) registers */
|
||||
#define RCV_STOP 0x06
|
||||
|
||||
#define XMT_BAR_PRO 0x0a
|
||||
#define XMT_BAR_10 0x0b
|
||||
static unsigned xmt_bar = XMT_BAR_PRO;
|
||||
|
||||
#define HOST_ADDRESS_REG 0x0c
|
||||
#define IO_PORT 0x0e
|
||||
#define IO_PORT_32_BIT 0x0c
|
||||
|
||||
/* Bank 1 registers */
|
||||
#define REG1 0x01
|
||||
#define WORD_WIDTH 0x02
|
||||
#define INT_ENABLE 0x80
|
||||
#define INT_NO_REG 0x02
|
||||
#define RCV_LOWER_LIMIT_REG 0x08
|
||||
#define RCV_UPPER_LIMIT_REG 0x09
|
||||
|
||||
#define XMT_LOWER_LIMIT_REG_PRO 0x0a
|
||||
#define XMT_UPPER_LIMIT_REG_PRO 0x0b
|
||||
#define XMT_LOWER_LIMIT_REG_10 0x0b
|
||||
#define XMT_UPPER_LIMIT_REG_10 0x0a
|
||||
static unsigned xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_PRO;
|
||||
static unsigned xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_PRO;
|
||||
|
||||
/* Bank 2 registers */
|
||||
#define XMT_Chain_Int 0x20 /* Interrupt at the end of the transmit chain */
|
||||
#define XMT_Chain_ErrStop 0x40 /* Interrupt at the end of the chain even if there are errors */
|
||||
#define RCV_Discard_BadFrame 0x80 /* Throw bad frames away, and continue to receive others */
|
||||
#define REG2 0x02
|
||||
#define PRMSC_Mode 0x01
|
||||
#define Multi_IA 0x20
|
||||
#define REG3 0x03
|
||||
#define TPE_BIT 0x04
|
||||
#define BNC_BIT 0x20
|
||||
#define REG13 0x0d
|
||||
#define FDX 0x00
|
||||
#define A_N_ENABLE 0x02
|
||||
|
||||
#define I_ADD_REG0 0x04
|
||||
#define I_ADD_REG1 0x05
|
||||
#define I_ADD_REG2 0x06
|
||||
#define I_ADD_REG3 0x07
|
||||
#define I_ADD_REG4 0x08
|
||||
#define I_ADD_REG5 0x09
|
||||
|
||||
#define EEPROM_REG_PRO 0x0a
|
||||
#define EEPROM_REG_10 0x0b
|
||||
static unsigned eeprom_reg = EEPROM_REG_PRO;
|
||||
|
||||
#define EESK 0x01
|
||||
#define EECS 0x02
|
||||
#define EEDI 0x04
|
||||
#define EEDO 0x08
|
||||
|
||||
/* The horrible routine to read a word from the serial EEPROM. */
|
||||
/* IMPORTANT - the 82595 will be set to Bank 0 after the eeprom is read */
|
||||
|
||||
/* The delay between EEPROM clock transitions. */
|
||||
#define eeprom_delay() { udelay(40); }
|
||||
#define EE_READ_CMD (6 << 6)
|
||||
|
||||
/* do a full reset */
|
||||
#define eepro_full_reset(ioaddr) outb(RESET_CMD, ioaddr); udelay(40);
|
||||
|
||||
/* do a nice reset */
|
||||
#define eepro_sel_reset(ioaddr) { \
|
||||
outb(SEL_RESET_CMD, ioaddr); \
|
||||
SLOW_DOWN; \
|
||||
SLOW_DOWN; \
|
||||
}
|
||||
|
||||
/* clear all interrupts */
|
||||
#define eepro_clear_int(ioaddr) outb(ALL_MASK, ioaddr + STATUS_REG)
|
||||
|
||||
/* enable rx */
|
||||
#define eepro_en_rx(ioaddr) outb(RCV_ENABLE_CMD, ioaddr)
|
||||
|
||||
/* disable rx */
|
||||
#define eepro_dis_rx(ioaddr) outb(RCV_DISABLE_CMD, ioaddr)
|
||||
|
||||
/* switch bank */
|
||||
#define eepro_sw2bank0(ioaddr) outb(BANK0_SELECT, ioaddr)
|
||||
#define eepro_sw2bank1(ioaddr) outb(BANK1_SELECT, ioaddr)
|
||||
#define eepro_sw2bank2(ioaddr) outb(BANK2_SELECT, ioaddr)
|
||||
|
||||
static unsigned int rx_start, tx_start;
|
||||
static int tx_last;
|
||||
static unsigned tx_end;
|
||||
static int eepro = 0;
|
||||
static unsigned short ioaddr = 0;
|
||||
static unsigned int mem_start, mem_end = RCV_DEFAULT_RAM / 1024;
|
||||
|
||||
#define udelay(n) waiton_timer2(((n)*TICKS_PER_MS)/1000)
|
||||
|
||||
/**************************************************************************
|
||||
RESET - Reset adapter
|
||||
***************************************************************************/
|
||||
static void eepro_reset(struct nic *nic)
|
||||
{
|
||||
int temp_reg, i;
|
||||
|
||||
/* put the card in its initial state */
|
||||
eepro_sw2bank2(ioaddr); /* be careful, bank2 now */
|
||||
temp_reg = inb(ioaddr + eeprom_reg);
|
||||
#ifdef DEBUG
|
||||
printf("Stepping %d\n", temp_reg >> 5);
|
||||
#endif
|
||||
if (temp_reg & 0x10) /* check the TurnOff Enable bit */
|
||||
outb(temp_reg & 0xEF, ioaddr + eeprom_reg);
|
||||
for (i = 0; i < ETH_ALEN; i++) /* fill the MAC address */
|
||||
outb(nic->node_addr[i], ioaddr + I_ADD_REG0 + i);
|
||||
temp_reg = inb(ioaddr + REG1);
|
||||
/* setup Transmit Chaining and discard bad RCV frames */
|
||||
outb(temp_reg | XMT_Chain_Int | XMT_Chain_ErrStop
|
||||
| RCV_Discard_BadFrame, ioaddr + REG1);
|
||||
temp_reg = inb(ioaddr + REG2); /* match broadcast */
|
||||
outb(temp_reg | 0x14, ioaddr + REG2);
|
||||
temp_reg = inb(ioaddr + REG3);
|
||||
outb(temp_reg & 0x3F, ioaddr + REG3); /* clear test mode */
|
||||
/* set the receiving mode */
|
||||
eepro_sw2bank1(ioaddr); /* be careful, bank1 now */
|
||||
/* initialise the RCV and XMT upper and lower limits */
|
||||
outb(RCV_LOWER_LIMIT, ioaddr + RCV_LOWER_LIMIT_REG);
|
||||
outb(RCV_UPPER_LIMIT, ioaddr + RCV_UPPER_LIMIT_REG);
|
||||
outb(XMT_LOWER_LIMIT, ioaddr + xmt_lower_limit_reg);
|
||||
outb(XMT_UPPER_LIMIT, ioaddr + xmt_upper_limit_reg);
|
||||
eepro_sw2bank0(ioaddr); /* Switch back to bank 0 */
|
||||
eepro_clear_int(ioaddr);
|
||||
/* Initialise RCV */
|
||||
outw(rx_start = (RCV_LOWER_LIMIT << 8), ioaddr + RCV_BAR);
|
||||
outw(((RCV_UPPER_LIMIT << 8) | 0xFE), ioaddr + RCV_STOP);
|
||||
/* Intialise XMT */
|
||||
outw((XMT_LOWER_LIMIT << 8), ioaddr + xmt_bar);
|
||||
eepro_sel_reset(ioaddr);
|
||||
tx_start = tx_end = (XMT_LOWER_LIMIT << 8);
|
||||
tx_last = 0;
|
||||
eepro_en_rx(ioaddr);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
POLL - Wait for a frame
|
||||
***************************************************************************/
|
||||
static int eepro_poll(struct nic *nic)
|
||||
{
|
||||
int i;
|
||||
unsigned int rcv_car = rx_start;
|
||||
unsigned int rcv_event, rcv_status, rcv_next_frame, rcv_size;
|
||||
|
||||
/* return true if there's an ethernet packet ready to read */
|
||||
/* nic->packet should contain data on return */
|
||||
/* nic->packetlen should contain length of data */
|
||||
#if 0
|
||||
if ((inb(ioaddr + STATUS_REG) & 0x40) == 0)
|
||||
return (0);
|
||||
outb(0x40, ioaddr + STATUS_REG);
|
||||
#endif
|
||||
outw(rcv_car, ioaddr + HOST_ADDRESS_REG);
|
||||
rcv_event = inw(ioaddr + IO_PORT);
|
||||
if (rcv_event != RCV_DONE)
|
||||
return (0);
|
||||
rcv_status = inw(ioaddr + IO_PORT);
|
||||
rcv_next_frame = inw(ioaddr + IO_PORT);
|
||||
rcv_size = inw(ioaddr + IO_PORT);
|
||||
#if 0
|
||||
printf("%hX %hX %d %hhX\n", rcv_status, rcv_next_frame, rcv_size,
|
||||
inb(ioaddr + STATUS_REG));
|
||||
#endif
|
||||
if ((rcv_status & (RX_OK|RX_ERROR)) != RX_OK) {
|
||||
printf("Receive error %hX\n", rcv_status);
|
||||
return (0);
|
||||
}
|
||||
rcv_size &= 0x3FFF;
|
||||
insw(ioaddr + IO_PORT, nic->packet, ((rcv_size + 3) >> 1));
|
||||
#if 0
|
||||
for (i = 0; i < 48; i++) {
|
||||
printf("%hhX", nic->packet[i]);
|
||||
putchar(i % 16 == 15 ? '\n' : ' ');
|
||||
}
|
||||
#endif
|
||||
nic->packetlen = rcv_size;
|
||||
rcv_car = rx_start + RCV_HEADER + rcv_size;
|
||||
rx_start = rcv_next_frame;
|
||||
if (rcv_car == 0)
|
||||
rcv_car = ((RCV_UPPER_LIMIT << 8) | 0xff);
|
||||
outw(rcv_car - 1, ioaddr + RCV_STOP);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
TRANSMIT - Transmit a frame
|
||||
***************************************************************************/
|
||||
static void eepro_transmit(
|
||||
struct nic *nic,
|
||||
const char *d, /* Destination */
|
||||
unsigned int t, /* Type */
|
||||
unsigned int s, /* size */
|
||||
const char *p) /* Packet */
|
||||
{
|
||||
unsigned int status, tx_available, last, end, length;
|
||||
unsigned short type;
|
||||
int boguscount = 20;
|
||||
|
||||
length = s + ETH_HLEN;
|
||||
if (tx_end > tx_start)
|
||||
tx_available = XMT_RAM - (tx_end - tx_start);
|
||||
else if (tx_end < tx_start)
|
||||
tx_available = tx_start - tx_end;
|
||||
else
|
||||
tx_available = XMT_RAM;
|
||||
last = tx_end;
|
||||
end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
|
||||
if (end >= (XMT_UPPER_LIMIT << 8)) {
|
||||
last = (XMT_LOWER_LIMIT << 8);
|
||||
end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
|
||||
}
|
||||
outw(last, ioaddr + HOST_ADDRESS_REG);
|
||||
outw(XMT_CMD, ioaddr + IO_PORT);
|
||||
outw(0, ioaddr + IO_PORT);
|
||||
outw(end, ioaddr + IO_PORT);
|
||||
outw(length, ioaddr + IO_PORT);
|
||||
outsw(ioaddr + IO_PORT, d, ETH_ALEN / 2);
|
||||
outsw(ioaddr + IO_PORT, nic->node_addr, ETH_ALEN / 2);
|
||||
type = htons(t);
|
||||
outsw(ioaddr + IO_PORT, &type, sizeof(type) / 2);
|
||||
outsw(ioaddr + IO_PORT, p, (s + 3) >> 1);
|
||||
/* A dummy read to flush the DRAM write pipeline */
|
||||
status = inw(ioaddr + IO_PORT);
|
||||
outw(last, ioaddr + xmt_bar);
|
||||
outb(XMT_CMD, ioaddr);
|
||||
tx_start = last;
|
||||
tx_last = last;
|
||||
tx_end = end;
|
||||
#if 0
|
||||
printf("%d %d\n", tx_start, tx_end);
|
||||
#endif
|
||||
while (boguscount > 0) {
|
||||
if (((status = inw(ioaddr + IO_PORT)) & TX_DONE_BIT) == 0) {
|
||||
udelay(40);
|
||||
boguscount--;
|
||||
continue;
|
||||
}
|
||||
#if DEBUG
|
||||
if ((status & 0x2000) == 0)
|
||||
printf("Transmit status %hX\n", status);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
DISABLE - Turn off ethernet interface
|
||||
***************************************************************************/
|
||||
static void eepro_disable(struct nic *nic)
|
||||
{
|
||||
eepro_sw2bank0(ioaddr); /* Switch to bank 0 */
|
||||
/* Flush the Tx and disable Rx */
|
||||
outb(STOP_RCV_CMD, ioaddr);
|
||||
tx_start = tx_end = (XMT_LOWER_LIMIT << 8);
|
||||
tx_last = 0;
|
||||
/* Reset the 82595 */
|
||||
eepro_full_reset(ioaddr);
|
||||
}
|
||||
|
||||
static int read_eeprom(int location)
|
||||
{
|
||||
int i;
|
||||
unsigned short retval = 0;
|
||||
int ee_addr = ioaddr + eeprom_reg;
|
||||
int read_cmd = location | EE_READ_CMD;
|
||||
int ctrl_val = EECS;
|
||||
|
||||
if (eepro == LAN595FX_10ISA) {
|
||||
eepro_sw2bank1(ioaddr);
|
||||
outb(0x00, ioaddr + STATUS_REG);
|
||||
}
|
||||
eepro_sw2bank2(ioaddr);
|
||||
outb(ctrl_val, ee_addr);
|
||||
/* shift the read command bits out */
|
||||
for (i = 8; i >= 0; i--) {
|
||||
short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI : ctrl_val;
|
||||
outb(outval, ee_addr);
|
||||
outb(outval | EESK, ee_addr); /* EEPROM clock tick */
|
||||
eeprom_delay();
|
||||
outb(outval, ee_addr); /* finish EEPROM clock tick */
|
||||
eeprom_delay();
|
||||
}
|
||||
outb(ctrl_val, ee_addr);
|
||||
for (i = 16; i > 0; i--) {
|
||||
outb(ctrl_val | EESK, ee_addr);
|
||||
eeprom_delay();
|
||||
retval = (retval << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0);
|
||||
outb(ctrl_val, ee_addr);
|
||||
eeprom_delay();
|
||||
}
|
||||
/* terminate the EEPROM access */
|
||||
ctrl_val &= ~EECS;
|
||||
outb(ctrl_val | EESK, ee_addr);
|
||||
eeprom_delay();
|
||||
outb(ctrl_val, ee_addr);
|
||||
eeprom_delay();
|
||||
eepro_sw2bank0(ioaddr);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
static int eepro_probe1(struct nic *nic)
|
||||
{
|
||||
int i, id, counter, l_eepro = 0;
|
||||
union {
|
||||
unsigned char caddr[ETH_ALEN];
|
||||
unsigned short saddr[ETH_ALEN/2];
|
||||
} station_addr;
|
||||
char *name;
|
||||
|
||||
id = inb(ioaddr + ID_REG);
|
||||
if ((id & ID_REG_MASK) != ID_REG_SIG)
|
||||
return (0);
|
||||
counter = id & R_ROBIN_BITS;
|
||||
if (((id = inb(ioaddr + ID_REG)) & R_ROBIN_BITS) != (counter + 0x40))
|
||||
return (0);
|
||||
/* yes the 82595 has been found */
|
||||
station_addr.saddr[2] = read_eeprom(2);
|
||||
if (station_addr.saddr[2] == 0x0000 || station_addr.saddr[2] == 0xFFFF) {
|
||||
l_eepro = 3;
|
||||
eepro = LAN595FX_10ISA;
|
||||
eeprom_reg= EEPROM_REG_10;
|
||||
rcv_start = RCV_START_10;
|
||||
xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_10;
|
||||
xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_10;
|
||||
station_addr.saddr[2] = read_eeprom(2);
|
||||
}
|
||||
station_addr.saddr[1] = read_eeprom(3);
|
||||
station_addr.saddr[0] = read_eeprom(4);
|
||||
if (l_eepro)
|
||||
name = "Intel EtherExpress 10 ISA";
|
||||
else if (read_eeprom(7) == ee_FX_INT2IRQ) {
|
||||
name = "Intel EtherExpress Pro/10+ ISA";
|
||||
l_eepro = 2;
|
||||
} else if (station_addr.saddr[0] == SA_ADDR1) {
|
||||
name = "Intel EtherExpress Pro/10 ISA";
|
||||
l_eepro = 1;
|
||||
} else {
|
||||
l_eepro = 0;
|
||||
name = "Intel 82595-based LAN card";
|
||||
}
|
||||
station_addr.saddr[0] = swap16(station_addr.saddr[0]);
|
||||
station_addr.saddr[1] = swap16(station_addr.saddr[1]);
|
||||
station_addr.saddr[2] = swap16(station_addr.saddr[2]);
|
||||
for (i = 0; i < ETH_ALEN; i++) {
|
||||
nic->node_addr[i] = station_addr.caddr[i];
|
||||
}
|
||||
printf("\n%s ioaddr %#hX, addr %!", name, ioaddr, nic->node_addr);
|
||||
mem_start = RCV_LOWER_LIMIT << 8;
|
||||
if ((mem_end & 0x3F) < 3 || (mem_end & 0x3F) > 29)
|
||||
mem_end = RCV_UPPER_LIMIT << 8;
|
||||
else {
|
||||
mem_end = mem_end * 1024 + (RCV_LOWER_LIMIT << 8);
|
||||
rcv_ram = mem_end - (RCV_LOWER_LIMIT << 8);
|
||||
}
|
||||
printf(", Rx mem %dK, if %s\n", (mem_end - mem_start) >> 10,
|
||||
GetBit(read_eeprom(5), ee_BNC_TPE) ? "BNC" : "TP");
|
||||
return (1);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
PROBE - Look for an adapter, this routine's visible to the outside
|
||||
***************************************************************************/
|
||||
struct nic *eepro_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||
{
|
||||
unsigned short *p;
|
||||
/* same probe list as the Linux driver */
|
||||
static unsigned short ioaddrs[] = {
|
||||
0x300, 0x210, 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360, 0};
|
||||
|
||||
if (probe_addrs == 0 || probe_addrs[0] == 0)
|
||||
probe_addrs = ioaddrs;
|
||||
for (p = probe_addrs; (ioaddr = *p) != 0; p++) {
|
||||
if (eepro_probe1(nic))
|
||||
break;
|
||||
}
|
||||
if (*p == 0)
|
||||
return (0);
|
||||
eepro_reset(nic);
|
||||
/* point to NIC specific routines */
|
||||
nic->reset = eepro_reset;
|
||||
nic->poll = eepro_poll;
|
||||
nic->transmit = eepro_transmit;
|
||||
nic->disable = eepro_disable;
|
||||
return (nic);
|
||||
}
|
||||
@@ -1,654 +0,0 @@
|
||||
/*
|
||||
* eepro100.c -- This file implements the eepro100 driver for etherboot.
|
||||
*
|
||||
*
|
||||
* Copyright (C) AW Computer Systems.
|
||||
* written by R.E.Wolff -- R.E.Wolff@BitWizard.nl
|
||||
*
|
||||
*
|
||||
* AW Computer Systems is contributing to the free software community
|
||||
* by paying for this driver and then putting the result under GPL.
|
||||
*
|
||||
* If you need a Linux device driver, please contact BitWizard for a
|
||||
* quote.
|
||||
*
|
||||
*
|
||||
* 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, or (at
|
||||
* your option) 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.
|
||||
*
|
||||
*
|
||||
* date version by what
|
||||
* Written: May 29 1997 V0.10 REW Initial revision.
|
||||
* changes: May 31 1997 V0.90 REW Works!
|
||||
* Jun 1 1997 V0.91 REW Cleanup
|
||||
* Jun 2 1997 V0.92 REW Add some code documentation
|
||||
* Jul 25 1997 V1.00 REW Tested by AW to work in a PROM
|
||||
* Cleanup for publication
|
||||
*
|
||||
* This is the etherboot intel etherexpress Pro/100B driver.
|
||||
*
|
||||
* It was written from scratch, with Donald Beckers eepro100.c kernel
|
||||
* driver as a guideline. Mostly the 82557 related definitions and the
|
||||
* lower level routines have been cut-and-pasted into this source.
|
||||
*
|
||||
* The driver was finished before Intel got the NDA out of the closet.
|
||||
* I still don't have the docs.
|
||||
* */
|
||||
|
||||
/* Philosophy of this driver.
|
||||
*
|
||||
* Probing:
|
||||
*
|
||||
* Using the pci.c functions of the Etherboot code, the 82557 chip is detected.
|
||||
* It is verified that the BIOS initialized everything properly and if
|
||||
* something is missing it is done now.
|
||||
*
|
||||
*
|
||||
* Initialization:
|
||||
*
|
||||
*
|
||||
* The chip is then initialized to "know" its ethernet address, and to
|
||||
* start recieving packets. The Linux driver has a whole transmit and
|
||||
* recieve ring of buffers. This is neat if you need high performance:
|
||||
* you can write the buffers asynchronously to the chip reading the
|
||||
* buffers and transmitting them over the network. Performance is NOT
|
||||
* an issue here. We can boot a 400k kernel in about two
|
||||
* seconds. (Theory: 0.4 seconds). Booting a system is going to take
|
||||
* about half a minute anyway, so getting 10 times closer to the
|
||||
* theoretical limit is going to make a difference of a few percent.
|
||||
*
|
||||
*
|
||||
* Transmitting and recieving.
|
||||
*
|
||||
* We have only one transmit descriptor. It has two buffer descriptors:
|
||||
* one for the header, and the other for the data.
|
||||
* We have only one receive buffer. The chip is told to recieve packets,
|
||||
* and suspend itself once it got one. The recieve (poll) routine simply
|
||||
* looks at the recieve buffer to see if there is already a packet there.
|
||||
* if there is, the buffer is copied, and the reciever is restarted.
|
||||
*
|
||||
* Caveats:
|
||||
*
|
||||
* The etherboot framework moves the code to the 32k segment from
|
||||
* 0x98000 to 0xa0000. There is just a little room between the end of
|
||||
* this driver and the 0xa0000 address. If you compile in too many
|
||||
* features, this will overflow.
|
||||
* The number under "hex" in the output of size that scrolls by while
|
||||
* compiling should be less than 8000. Maybe even the stack is up there,
|
||||
* so that you need even more headroom.
|
||||
*/
|
||||
|
||||
/* The etherboot authors seem to dislike the argument ordering in
|
||||
* outb macros that Linux uses. I disklike the confusion that this
|
||||
* has caused even more.... This file uses the Linux argument ordering. */
|
||||
/* Sorry not us. It's inherted code from FreeBSD. [The authors] */
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "pci.h"
|
||||
#include "cards.h"
|
||||
#include "timer.h"
|
||||
|
||||
#undef virt_to_bus
|
||||
#define virt_to_bus(x) ((unsigned long)x)
|
||||
|
||||
static int ioaddr;
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef signed char s8;
|
||||
typedef unsigned short u16;
|
||||
typedef signed short s16;
|
||||
typedef unsigned int u32;
|
||||
typedef signed int s32;
|
||||
|
||||
enum speedo_offsets {
|
||||
SCBStatus = 0, SCBCmd = 2, /* Rx/Command Unit command and status. */
|
||||
SCBPointer = 4, /* General purpose pointer. */
|
||||
SCBPort = 8, /* Misc. commands and operands. */
|
||||
SCBflash = 12, SCBeeprom = 14, /* EEPROM and flash memory control. */
|
||||
SCBCtrlMDI = 16, /* MDI interface control. */
|
||||
SCBEarlyRx = 20, /* Early receive byte count. */
|
||||
};
|
||||
|
||||
static int do_eeprom_cmd(int cmd, int cmd_len);
|
||||
void hd(void *where, int n);
|
||||
|
||||
/***********************************************************************/
|
||||
/* I82557 related defines */
|
||||
/***********************************************************************/
|
||||
|
||||
/* Serial EEPROM section.
|
||||
A "bit" grungy, but we work our way through bit-by-bit :->. */
|
||||
/* EEPROM_Ctrl bits. */
|
||||
#define EE_SHIFT_CLK 0x01 /* EEPROM shift clock. */
|
||||
#define EE_CS 0x02 /* EEPROM chip select. */
|
||||
#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */
|
||||
#define EE_DATA_READ 0x08 /* EEPROM chip data out. */
|
||||
#define EE_WRITE_0 0x4802
|
||||
#define EE_WRITE_1 0x4806
|
||||
#define EE_ENB (0x4800 | EE_CS)
|
||||
|
||||
#define udelay(n) waiton_timer2(((n)*TICKS_PER_MS)/1000)
|
||||
|
||||
/* The EEPROM commands include the alway-set leading bit. */
|
||||
#define EE_READ_CMD 6
|
||||
|
||||
/* The SCB accepts the following controls for the Tx and Rx units: */
|
||||
#define CU_START 0x0010
|
||||
#define CU_RESUME 0x0020
|
||||
#define CU_STATSADDR 0x0040
|
||||
#define CU_SHOWSTATS 0x0050 /* Dump statistics counters. */
|
||||
#define CU_CMD_BASE 0x0060 /* Base address to add to add CU commands. */
|
||||
#define CU_DUMPSTATS 0x0070 /* Dump then reset stats counters. */
|
||||
|
||||
#define RX_START 0x0001
|
||||
#define RX_RESUME 0x0002
|
||||
#define RX_ABORT 0x0004
|
||||
#define RX_ADDR_LOAD 0x0006
|
||||
#define RX_RESUMENR 0x0007
|
||||
#define INT_MASK 0x0100
|
||||
#define DRVR_INT 0x0200 /* Driver generated interrupt. */
|
||||
|
||||
enum phy_chips { NonSuchPhy=0, I82553AB, I82553C, I82503, DP83840, S80C240,
|
||||
S80C24, PhyUndefined, DP83840A=10, };
|
||||
|
||||
/* Commands that can be put in a command list entry. */
|
||||
enum commands {
|
||||
CmdNOp = 0,
|
||||
CmdIASetup = 1,
|
||||
CmdConfigure = 2,
|
||||
CmdMulticastList = 3,
|
||||
CmdTx = 4,
|
||||
CmdTDR = 5,
|
||||
CmdDump = 6,
|
||||
CmdDiagnose = 7,
|
||||
|
||||
/* And some extra flags: */
|
||||
CmdSuspend = 0x4000, /* Suspend after completion. */
|
||||
CmdIntr = 0x2000, /* Interrupt after completion. */
|
||||
CmdTxFlex = 0x0008, /* Use "Flexible mode" for CmdTx command. */
|
||||
};
|
||||
|
||||
/* How to wait for the command unit to accept a command.
|
||||
Typically this takes 0 ticks. */
|
||||
static inline void wait_for_cmd_done(int cmd_ioaddr)
|
||||
{
|
||||
short wait = 100;
|
||||
do ;
|
||||
while(inb(cmd_ioaddr) && --wait >= 0);
|
||||
}
|
||||
|
||||
/* Elements of the dump_statistics block. This block must be lword aligned. */
|
||||
static struct speedo_stats {
|
||||
u32 tx_good_frames;
|
||||
u32 tx_coll16_errs;
|
||||
u32 tx_late_colls;
|
||||
u32 tx_underruns;
|
||||
u32 tx_lost_carrier;
|
||||
u32 tx_deferred;
|
||||
u32 tx_one_colls;
|
||||
u32 tx_multi_colls;
|
||||
u32 tx_total_colls;
|
||||
u32 rx_good_frames;
|
||||
u32 rx_crc_errs;
|
||||
u32 rx_align_errs;
|
||||
u32 rx_resource_errs;
|
||||
u32 rx_overrun_errs;
|
||||
u32 rx_colls_errs;
|
||||
u32 rx_runt_errs;
|
||||
u32 done_marker;
|
||||
} lstats;
|
||||
|
||||
/* A speedo3 TX buffer descriptor with two buffers... */
|
||||
static struct TxFD {
|
||||
volatile s16 status;
|
||||
s16 command;
|
||||
u32 link; /* void * */
|
||||
u32 tx_desc_addr; /* (almost) Always points to the tx_buf_addr element. */
|
||||
s32 count; /* # of TBD (=2), Tx start thresh., etc. */
|
||||
/* This constitutes two "TBD" entries: hdr and data */
|
||||
u32 tx_buf_addr0; /* void *, header of frame to be transmitted. */
|
||||
s32 tx_buf_size0; /* Length of Tx hdr. */
|
||||
u32 tx_buf_addr1; /* void *, data to be transmitted. */
|
||||
s32 tx_buf_size1; /* Length of Tx data. */
|
||||
} txfd;
|
||||
|
||||
struct RxFD { /* Receive frame descriptor. */
|
||||
volatile s16 status;
|
||||
s16 command;
|
||||
u32 link; /* struct RxFD * */
|
||||
u32 rx_buf_addr; /* void * */
|
||||
u16 count;
|
||||
u16 size;
|
||||
char packet[1518];
|
||||
};
|
||||
|
||||
#ifdef USE_LOWMEM_BUFFER
|
||||
#define rxfd ((struct RxFD *)(0x10000 - sizeof(struct RxFD)))
|
||||
#define ACCESS(x) x->
|
||||
#else
|
||||
static struct RxFD rxfd;
|
||||
#define ACCESS(x) x.
|
||||
#endif
|
||||
|
||||
static int congenb = 0; /* Enable congestion control in the DP83840. */
|
||||
static int txfifo = 8; /* Tx FIFO threshold in 4 byte units, 0-15 */
|
||||
static int rxfifo = 8; /* Rx FIFO threshold, default 32 bytes. */
|
||||
static int txdmacount = 0; /* Tx DMA burst length, 0-127, default 0. */
|
||||
static int rxdmacount = 0; /* Rx DMA length, 0 means no preemption. */
|
||||
|
||||
/* I don't understand a byte in this structure. It was copied from the
|
||||
* Linux kernel initialization for the eepro100. -- REW */
|
||||
static struct ConfCmd {
|
||||
s16 status;
|
||||
s16 command;
|
||||
u32 link;
|
||||
unsigned char data[22];
|
||||
} confcmd = {
|
||||
0, CmdConfigure,
|
||||
(u32) & txfd,
|
||||
{22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1, /* 1=Use MII 0=Use AUI */
|
||||
0, 0x2E, 0, 0x60, 0,
|
||||
0xf2, 0x48, 0, 0x40, 0xf2, 0x80, /* 0x40=Force full-duplex */
|
||||
0x3f, 0x05, }
|
||||
};
|
||||
|
||||
/***********************************************************************/
|
||||
/* Locally used functions */
|
||||
/***********************************************************************/
|
||||
|
||||
/* Support function: mdio_write
|
||||
*
|
||||
* This probably writes to the "physical media interface chip".
|
||||
* -- REW
|
||||
*/
|
||||
|
||||
static int mdio_write(int phy_id, int location, int value)
|
||||
{
|
||||
int val, boguscnt = 64*4; /* <64 usec. to complete, typ 27 ticks */
|
||||
|
||||
outl(0x04000000 | (location<<16) | (phy_id<<21) | value,
|
||||
ioaddr + SCBCtrlMDI);
|
||||
do {
|
||||
udelay(16);
|
||||
|
||||
val = inl(ioaddr + SCBCtrlMDI);
|
||||
if (--boguscnt < 0) {
|
||||
printf(" mdio_write() timed out with val = %X.\n", val);
|
||||
}
|
||||
} while (! (val & 0x10000000));
|
||||
return val & 0xffff;
|
||||
}
|
||||
|
||||
/* Support function: mdio_read
|
||||
*
|
||||
* This probably reads a register in the "physical media interface chip".
|
||||
* -- REW
|
||||
*/
|
||||
static int mdio_read(int phy_id, int location)
|
||||
{
|
||||
int val, boguscnt = 64*4; /* <64 usec. to complete, typ 27 ticks */
|
||||
outl(0x08000000 | (location<<16) | (phy_id<<21), ioaddr + SCBCtrlMDI);
|
||||
do {
|
||||
udelay(16);
|
||||
|
||||
val = inl(ioaddr + SCBCtrlMDI);
|
||||
if (--boguscnt < 0) {
|
||||
printf( " mdio_read() timed out with val = %X.\n", val);
|
||||
}
|
||||
} while (! (val & 0x10000000));
|
||||
return val & 0xffff;
|
||||
}
|
||||
|
||||
/* The fixes for the code were kindly provided by Dragan Stancevic
|
||||
<visitor@valinux.com> to strictly follow Intel specifications of EEPROM
|
||||
access timing.
|
||||
The publicly available sheet 64486302 (sec. 3.1) specifies 1us access
|
||||
interval for serial EEPROM. However, it looks like that there is an
|
||||
additional requirement dictating larger udelay's in the code below.
|
||||
2000/05/24 SAW */
|
||||
static int do_eeprom_cmd(int cmd, int cmd_len)
|
||||
{
|
||||
unsigned retval = 0;
|
||||
long ee_addr = ioaddr + SCBeeprom;
|
||||
|
||||
outw(EE_ENB, ee_addr); udelay(2);
|
||||
outw(EE_ENB | EE_SHIFT_CLK, ee_addr); udelay(2);
|
||||
|
||||
/* Shift the command bits out. */
|
||||
do {
|
||||
short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0;
|
||||
outw(dataval, ee_addr); udelay(2);
|
||||
outw(dataval | EE_SHIFT_CLK, ee_addr); udelay(2);
|
||||
retval = (retval << 1) | ((inw(ee_addr) & EE_DATA_READ) ? 1 : 0);
|
||||
} while (--cmd_len >= 0);
|
||||
outw(EE_ENB, ee_addr); udelay(2);
|
||||
|
||||
/* Terminate the EEPROM access. */
|
||||
outw(EE_ENB & ~EE_CS, ee_addr);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static inline void whereami (const char *str)
|
||||
{
|
||||
#if 0
|
||||
printf ("%s\n", str);
|
||||
sleep (2);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* function: eepro100_reset
|
||||
* resets the card. This is used to allow Etherboot to probe the card again
|
||||
* from a "virginal" state....
|
||||
* Arguments: none
|
||||
*
|
||||
* returns: void.
|
||||
*/
|
||||
|
||||
static void eepro100_reset(struct nic *nic)
|
||||
{
|
||||
outl(0, ioaddr + SCBPort);
|
||||
}
|
||||
|
||||
/* function: eepro100_transmit
|
||||
* This transmits a packet.
|
||||
*
|
||||
* Arguments: char d[6]: destination ethernet address.
|
||||
* unsigned short t: ethernet protocol type.
|
||||
* unsigned short s: size of the data-part of the packet.
|
||||
* char *p: the data for the packet.
|
||||
* returns: void.
|
||||
*/
|
||||
|
||||
static void eepro100_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
|
||||
{
|
||||
struct eth_hdr {
|
||||
unsigned char dst_addr[ETH_ALEN];
|
||||
unsigned char src_addr[ETH_ALEN];
|
||||
unsigned short type;
|
||||
} hdr;
|
||||
unsigned short status;
|
||||
int to;
|
||||
int s1, s2;
|
||||
|
||||
status = inw(ioaddr + SCBStatus);
|
||||
/* Acknowledge all of the current interrupt sources ASAP. */
|
||||
outw(status & 0xfc00, ioaddr + SCBStatus);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("transmitting type %hX packet (%d bytes). status = %hX, cmd=%hX\n",
|
||||
t, s, status, inw (ioaddr + SCBCmd));
|
||||
#endif
|
||||
|
||||
memcpy (&hdr.dst_addr, d, ETH_ALEN);
|
||||
memcpy (&hdr.src_addr, nic->node_addr, ETH_ALEN);
|
||||
|
||||
hdr.type = htons (t);
|
||||
|
||||
txfd.status = 0;
|
||||
txfd.command = CmdSuspend | CmdTx | CmdTxFlex;
|
||||
txfd.link = virt_to_bus (&txfd);
|
||||
txfd.count = 0x02208000;
|
||||
txfd.tx_desc_addr = (u32)&txfd.tx_buf_addr0;
|
||||
|
||||
txfd.tx_buf_addr0 = virt_to_bus (&hdr);
|
||||
txfd.tx_buf_size0 = sizeof (hdr);
|
||||
|
||||
txfd.tx_buf_addr1 = virt_to_bus (p);
|
||||
txfd.tx_buf_size1 = s;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("txfd: \n");
|
||||
hd (&txfd, sizeof (txfd));
|
||||
#endif
|
||||
|
||||
outl(virt_to_bus(&txfd), ioaddr + SCBPointer);
|
||||
outw(INT_MASK | CU_START, ioaddr + SCBCmd);
|
||||
wait_for_cmd_done(ioaddr + SCBCmd);
|
||||
|
||||
s1 = inw (ioaddr + SCBStatus);
|
||||
load_timer2(10*TICKS_PER_MS); /* timeout 10 ms for transmit */
|
||||
while (!txfd.status && timer2_running())
|
||||
/* Wait */;
|
||||
s2 = inw (ioaddr + SCBStatus);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("s1 = %hX, s2 = %hX.\n", s1, s2);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* function: eepro100_poll / eth_poll
|
||||
* This recieves a packet from the network.
|
||||
*
|
||||
* Arguments: none
|
||||
*
|
||||
* returns: 1 if a packet was recieved.
|
||||
* 0 if no pacet was recieved.
|
||||
* side effects:
|
||||
* returns the packet in the array nic->packet.
|
||||
* returns the length of the packet in nic->packetlen.
|
||||
*/
|
||||
|
||||
static int eepro100_poll(struct nic *nic)
|
||||
{
|
||||
if (!ACCESS(rxfd)status)
|
||||
return 0;
|
||||
|
||||
/* Ok. We got a packet. Now restart the reciever.... */
|
||||
ACCESS(rxfd)status = 0;
|
||||
ACCESS(rxfd)command = 0xc000;
|
||||
outl(virt_to_bus(&(ACCESS(rxfd)status)), ioaddr + SCBPointer);
|
||||
outw(INT_MASK | RX_START, ioaddr + SCBCmd);
|
||||
wait_for_cmd_done(ioaddr + SCBCmd);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("Got a packet: Len = %d.\n", ACCESS(rxfd)count & 0x3fff);
|
||||
#endif
|
||||
nic->packetlen = ACCESS(rxfd)count & 0x3fff;
|
||||
memcpy (nic->packet, ACCESS(rxfd)packet, nic->packetlen);
|
||||
#ifdef DEBUG
|
||||
hd (nic->packet, 0x30);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void eepro100_disable(struct nic *nic)
|
||||
{
|
||||
/* See if this PartialReset solves the problem with interfering with
|
||||
kernel operation after Etherboot hands over. - Ken 20001102 */
|
||||
outl(2, ioaddr + SCBPort);
|
||||
}
|
||||
|
||||
/* exported function: eepro100_probe / eth_probe
|
||||
* initializes a card
|
||||
*
|
||||
* side effects:
|
||||
* leaves the ioaddress of the 82557 chip in the variable ioaddr.
|
||||
* leaves the 82557 initialized, and ready to recieve packets.
|
||||
*/
|
||||
|
||||
struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs, struct pci_device *p)
|
||||
{
|
||||
unsigned short sum = 0;
|
||||
int i;
|
||||
int read_cmd, ee_size;
|
||||
unsigned short value;
|
||||
int options;
|
||||
int promisc;
|
||||
|
||||
/* we cache only the first few words of the EEPROM data
|
||||
be careful not to access beyond this array */
|
||||
unsigned short eeprom[16];
|
||||
|
||||
if (probeaddrs == 0 || probeaddrs[0] == 0)
|
||||
return 0;
|
||||
ioaddr = probeaddrs[0] & ~3; /* Mask the bit that says "this is an io addr" */
|
||||
|
||||
adjust_pci_device(p);
|
||||
|
||||
if ((do_eeprom_cmd(EE_READ_CMD << 24, 27) & 0xffe0000)
|
||||
== 0xffe0000) {
|
||||
ee_size = 0x100;
|
||||
read_cmd = EE_READ_CMD << 24;
|
||||
} else {
|
||||
ee_size = 0x40;
|
||||
read_cmd = EE_READ_CMD << 22;
|
||||
}
|
||||
|
||||
for (i = 0, sum = 0; i < ee_size; i++) {
|
||||
unsigned short value = do_eeprom_cmd(read_cmd | (i << 16), 27);
|
||||
if (i < (int)(sizeof(eeprom)/sizeof(eeprom[0])))
|
||||
eeprom[i] = value;
|
||||
sum += value;
|
||||
}
|
||||
|
||||
for (i=0;i<ETH_ALEN;i++) {
|
||||
nic->node_addr[i] = (eeprom[i/2] >> (8*(i&1))) & 0xff;
|
||||
}
|
||||
printf ("Ethernet addr: %!\n", nic->node_addr);
|
||||
|
||||
if (sum != 0xBABA)
|
||||
printf("eepro100: Invalid EEPROM checksum %#hX, "
|
||||
"check settings before activating this device!\n", sum);
|
||||
outl(0, ioaddr + SCBPort);
|
||||
udelay (10000);
|
||||
|
||||
whereami ("Got eeprom.");
|
||||
|
||||
outl(virt_to_bus(&lstats), ioaddr + SCBPointer);
|
||||
outw(INT_MASK | CU_STATSADDR, ioaddr + SCBCmd);
|
||||
wait_for_cmd_done(ioaddr + SCBCmd);
|
||||
|
||||
whereami ("set stats addr.");
|
||||
/* INIT RX stuff. */
|
||||
|
||||
/* Base = 0 */
|
||||
outl(0, ioaddr + SCBPointer);
|
||||
outw(INT_MASK | RX_ADDR_LOAD, ioaddr + SCBCmd);
|
||||
wait_for_cmd_done(ioaddr + SCBCmd);
|
||||
|
||||
whereami ("set rx base addr.");
|
||||
|
||||
ACCESS(rxfd)status = 0x0001;
|
||||
ACCESS(rxfd)command = 0x0000;
|
||||
ACCESS(rxfd)link = virt_to_bus(&(ACCESS(rxfd)status));
|
||||
ACCESS(rxfd)rx_buf_addr = (int) &nic->packet;
|
||||
ACCESS(rxfd)count = 0;
|
||||
ACCESS(rxfd)size = 1528;
|
||||
|
||||
outl(virt_to_bus(&(ACCESS(rxfd)status)), ioaddr + SCBPointer);
|
||||
outw(INT_MASK | RX_START, ioaddr + SCBCmd);
|
||||
wait_for_cmd_done(ioaddr + SCBCmd);
|
||||
|
||||
whereami ("started RX process.");
|
||||
|
||||
/* Start the reciever.... */
|
||||
ACCESS(rxfd)status = 0;
|
||||
ACCESS(rxfd)command = 0xc000;
|
||||
outl(virt_to_bus(&(ACCESS(rxfd)status)), ioaddr + SCBPointer);
|
||||
outw(INT_MASK | RX_START, ioaddr + SCBCmd);
|
||||
|
||||
/* INIT TX stuff. */
|
||||
|
||||
/* Base = 0 */
|
||||
outl(0, ioaddr + SCBPointer);
|
||||
outw(INT_MASK | CU_CMD_BASE, ioaddr + SCBCmd);
|
||||
wait_for_cmd_done(ioaddr + SCBCmd);
|
||||
|
||||
whereami ("set TX base addr.");
|
||||
|
||||
txfd.command = (CmdIASetup);
|
||||
txfd.status = 0x0000;
|
||||
txfd.link = virt_to_bus (&confcmd);
|
||||
|
||||
{
|
||||
char *t = (char *)&txfd.tx_desc_addr;
|
||||
|
||||
for (i=0;i<ETH_ALEN;i++)
|
||||
t[i] = nic->node_addr[i];
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("Setup_eaddr:\n");
|
||||
hd (&txfd, 0x20);
|
||||
#endif
|
||||
/* options = 0x40; */ /* 10mbps half duplex... */
|
||||
options = 0x00; /* Autosense */
|
||||
|
||||
promisc = 0;
|
||||
|
||||
if ( ((eeprom[6]>>8) & 0x3f) == DP83840
|
||||
|| ((eeprom[6]>>8) & 0x3f) == DP83840A) {
|
||||
int mdi_reg23 = mdio_read(eeprom[6] & 0x1f, 23) | 0x0422;
|
||||
if (congenb)
|
||||
mdi_reg23 |= 0x0100;
|
||||
printf(" DP83840 specific setup, setting register 23 to %hX.\n",
|
||||
mdi_reg23);
|
||||
mdio_write(eeprom[6] & 0x1f, 23, mdi_reg23);
|
||||
}
|
||||
whereami ("Done DP8340 special setup.");
|
||||
if (options != 0) {
|
||||
mdio_write(eeprom[6] & 0x1f, 0,
|
||||
((options & 0x20) ? 0x2000 : 0) | /* 100mbps? */
|
||||
((options & 0x10) ? 0x0100 : 0)); /* Full duplex? */
|
||||
whereami ("set mdio_register.");
|
||||
}
|
||||
|
||||
confcmd.command = CmdSuspend | CmdConfigure;
|
||||
confcmd.status = 0x0000;
|
||||
confcmd.link = virt_to_bus (&txfd);
|
||||
confcmd.data[1] = (txfifo << 4) | rxfifo;
|
||||
confcmd.data[4] = rxdmacount;
|
||||
confcmd.data[5] = txdmacount + 0x80;
|
||||
confcmd.data[15] = promisc ? 0x49: 0x48;
|
||||
confcmd.data[19] = (options & 0x10) ? 0xC0 : 0x80;
|
||||
confcmd.data[21] = promisc ? 0x0D: 0x05;
|
||||
|
||||
outl(virt_to_bus(&txfd), ioaddr + SCBPointer);
|
||||
outw(INT_MASK | CU_START, ioaddr + SCBCmd);
|
||||
wait_for_cmd_done(ioaddr + SCBCmd);
|
||||
|
||||
whereami ("started TX thingy (config, iasetup).");
|
||||
|
||||
load_timer2(10*TICKS_PER_MS);
|
||||
while (!txfd.status && timer2_running())
|
||||
/* Wait */;
|
||||
|
||||
nic->reset = eepro100_reset;
|
||||
nic->poll = eepro100_poll;
|
||||
nic->transmit = eepro100_transmit;
|
||||
nic->disable = eepro100_disable;
|
||||
return nic;
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
/* Hexdump a number of bytes from memory... */
|
||||
void hd (void *where, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
while (n > 0) {
|
||||
printf ("%X ", where);
|
||||
for (i=0;i < ( (n>16)?16:n);i++)
|
||||
printf (" %hhX", ((char *)where)[i]);
|
||||
printf ("\n");
|
||||
n -= 16;
|
||||
where += 16;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,481 +0,0 @@
|
||||
/* epic100.c: A SMC 83c170 EPIC/100 fast ethernet driver for Etherboot */
|
||||
|
||||
#define LINUX_OUT_MACROS
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "cards.h"
|
||||
#include "timer.h"
|
||||
#include "epic100.h"
|
||||
|
||||
#undef virt_to_bus
|
||||
#define virt_to_bus(x) ((unsigned long)x)
|
||||
|
||||
#define TX_RING_SIZE 2 /* use at least 2 buffers for TX */
|
||||
#define RX_RING_SIZE 2
|
||||
|
||||
#define PKT_BUF_SZ 1536 /* Size of each temporary Tx/Rx buffer.*/
|
||||
|
||||
/*
|
||||
#define DEBUG_RX
|
||||
#define DEBUG_TX
|
||||
#define DEBUG_EEPROM
|
||||
*/
|
||||
|
||||
#define EPIC_DEBUG 0 /* debug level */
|
||||
|
||||
/* The EPIC100 Rx and Tx buffer descriptors. */
|
||||
struct epic_rx_desc {
|
||||
unsigned short status;
|
||||
unsigned short rxlength;
|
||||
unsigned long bufaddr;
|
||||
unsigned short buflength;
|
||||
unsigned short control;
|
||||
unsigned long next;
|
||||
};
|
||||
|
||||
/* description of the tx descriptors control bits commonly used */
|
||||
#define TD_STDFLAGS TD_LASTDESC
|
||||
|
||||
struct epic_tx_desc {
|
||||
unsigned short status;
|
||||
unsigned short txlength;
|
||||
unsigned long bufaddr;
|
||||
unsigned short buflength;
|
||||
unsigned short control;
|
||||
unsigned long next;
|
||||
};
|
||||
|
||||
#define delay(nanosec) do { int _i = 3; while (--_i > 0) \
|
||||
{ __SLOW_DOWN_IO; }} while (0)
|
||||
|
||||
static void epic100_open(void);
|
||||
static void epic100_init_ring(void);
|
||||
static void epic100_disable(struct nic *nic);
|
||||
static int epic100_poll(struct nic *nic);
|
||||
static void epic100_transmit(struct nic *nic, const char *destaddr,
|
||||
unsigned int type, unsigned int len, const char *data);
|
||||
static int read_eeprom(int location);
|
||||
static int mii_read(int phy_id, int location);
|
||||
|
||||
static int ioaddr;
|
||||
|
||||
static int command;
|
||||
static int intstat;
|
||||
static int intmask;
|
||||
static int genctl ;
|
||||
static int eectl ;
|
||||
static int test ;
|
||||
static int mmctl ;
|
||||
static int mmdata ;
|
||||
static int lan0 ;
|
||||
static int rxcon ;
|
||||
static int txcon ;
|
||||
static int prcdar ;
|
||||
static int ptcdar ;
|
||||
static int eththr ;
|
||||
|
||||
static unsigned int cur_rx, cur_tx; /* The next free ring entry */
|
||||
#ifdef DEBUG_EEPROM
|
||||
static unsigned short eeprom[64];
|
||||
#endif
|
||||
static signed char phys[4]; /* MII device addresses. */
|
||||
static struct epic_rx_desc rx_ring[RX_RING_SIZE];
|
||||
static struct epic_tx_desc tx_ring[TX_RING_SIZE];
|
||||
#ifdef USE_LOWMEM_BUFFER
|
||||
#define rx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE)
|
||||
#define tx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE - PKT_BUF_SZ * TX_RING_SIZE)
|
||||
#else
|
||||
static char rx_packet[PKT_BUF_SZ * RX_RING_SIZE];
|
||||
static char tx_packet[PKT_BUF_SZ * TX_RING_SIZE];
|
||||
#endif
|
||||
|
||||
/***********************************************************************/
|
||||
/* Externally visible functions */
|
||||
/***********************************************************************/
|
||||
|
||||
static void
|
||||
epic100_reset(struct nic *nic)
|
||||
{
|
||||
/* Soft reset the chip. */
|
||||
outl(GC_SOFT_RESET, genctl);
|
||||
}
|
||||
|
||||
struct nic*
|
||||
epic100_probe(struct nic *nic, unsigned short *probeaddrs)
|
||||
{
|
||||
unsigned short sum = 0;
|
||||
unsigned short value;
|
||||
int i;
|
||||
unsigned short* ap;
|
||||
unsigned int phy, phy_idx;
|
||||
|
||||
if (probeaddrs == 0 || probeaddrs[0] == 0)
|
||||
return 0;
|
||||
|
||||
/* Ideally we would detect all network cards in slot order. That would
|
||||
be best done a central PCI probe dispatch, which wouldn't work
|
||||
well with the current structure. So instead we detect just the
|
||||
Epic cards in slot order. */
|
||||
|
||||
ioaddr = probeaddrs[0] & ~3; /* Mask the bit that says "this is an io addr" */
|
||||
|
||||
/* compute all used static epic100 registers address */
|
||||
command = ioaddr + COMMAND; /* Control Register */
|
||||
intstat = ioaddr + INTSTAT; /* Interrupt Status */
|
||||
intmask = ioaddr + INTMASK; /* Interrupt Mask */
|
||||
genctl = ioaddr + GENCTL; /* General Control */
|
||||
eectl = ioaddr + EECTL; /* EEPROM Control */
|
||||
test = ioaddr + TEST; /* Test register (clocks) */
|
||||
mmctl = ioaddr + MMCTL; /* MII Management Interface Control */
|
||||
mmdata = ioaddr + MMDATA; /* MII Management Interface Data */
|
||||
lan0 = ioaddr + LAN0; /* MAC address. (0x40-0x48) */
|
||||
rxcon = ioaddr + RXCON; /* Receive Control */
|
||||
txcon = ioaddr + TXCON; /* Transmit Control */
|
||||
prcdar = ioaddr + PRCDAR; /* PCI Receive Current Descr Address */
|
||||
ptcdar = ioaddr + PTCDAR; /* PCI Transmit Current Descr Address */
|
||||
eththr = ioaddr + ETHTHR; /* Early Transmit Threshold */
|
||||
|
||||
/* Reset the chip & bring it out of low-power mode. */
|
||||
outl(GC_SOFT_RESET, genctl);
|
||||
|
||||
/* Disable ALL interrupts by setting the interrupt mask. */
|
||||
outl(INTR_DISABLE, intmask);
|
||||
|
||||
/*
|
||||
* set the internal clocks:
|
||||
* Application Note 7.15 says:
|
||||
* In order to set the CLOCK TEST bit in the TEST register,
|
||||
* perform the following:
|
||||
*
|
||||
* Write 0x0008 to the test register at least sixteen
|
||||
* consecutive times.
|
||||
*
|
||||
* The CLOCK TEST bit is Write-Only. Writing it several times
|
||||
* consecutively insures a successful write to the bit...
|
||||
*/
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
outl(0x00000008, test);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_EEPROM
|
||||
for (i = 0; i < 64; i++) {
|
||||
value = read_eeprom(i);
|
||||
eeprom[i] = value;
|
||||
sum += value;
|
||||
}
|
||||
|
||||
#if (EPIC_DEBUG > 1)
|
||||
printf("EEPROM contents\n");
|
||||
for (i = 0; i < 64; i++) {
|
||||
printf(" %hhX%s", eeprom[i], i % 16 == 15 ? "\n" : "");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This could also be read from the EEPROM. */
|
||||
ap = (unsigned short*)nic->node_addr;
|
||||
for (i = 0; i < 3; i++)
|
||||
*ap++ = inw(lan0 + i*4);
|
||||
|
||||
printf(" I/O %#hX %! ", ioaddr, nic->node_addr);
|
||||
|
||||
/* Find the connected MII xcvrs. */
|
||||
for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(phys); phy++) {
|
||||
int mii_status = mii_read(phy, 0);
|
||||
|
||||
if (mii_status != 0xffff && mii_status != 0x0000) {
|
||||
phys[phy_idx++] = phy;
|
||||
#if (EPIC_DEBUG > 1)
|
||||
printf("MII transceiver found at address %d.\n", phy);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (phy_idx == 0) {
|
||||
#if (EPIC_DEBUG > 1)
|
||||
printf("***WARNING***: No MII transceiver found!\n");
|
||||
#endif
|
||||
/* Use the known PHY address of the EPII. */
|
||||
phys[0] = 3;
|
||||
}
|
||||
|
||||
epic100_open();
|
||||
|
||||
nic->reset = epic100_reset;
|
||||
nic->poll = epic100_poll;
|
||||
nic->transmit = epic100_transmit;
|
||||
nic->disable = epic100_disable;
|
||||
|
||||
return nic;
|
||||
}
|
||||
|
||||
static void
|
||||
epic100_open(void)
|
||||
{
|
||||
int mii_reg5;
|
||||
int full_duplex = 0;
|
||||
unsigned long tmp;
|
||||
|
||||
epic100_init_ring();
|
||||
|
||||
/* Pull the chip out of low-power mode, and set for PCI read multiple. */
|
||||
outl(GC_RX_FIFO_THR_64 | GC_MRC_READ_MULT | GC_ONE_COPY, genctl);
|
||||
|
||||
outl(TX_FIFO_THRESH, eththr);
|
||||
|
||||
tmp = TC_EARLY_TX_ENABLE | TX_SLOT_TIME;
|
||||
|
||||
mii_reg5 = mii_read(phys[0], 5);
|
||||
if (mii_reg5 != 0xffff && (mii_reg5 & 0x0100)) {
|
||||
full_duplex = 1;
|
||||
printf(" full-duplex mode");
|
||||
tmp |= TC_LM_FULL_DPX;
|
||||
} else
|
||||
tmp |= TC_LM_NORMAL;
|
||||
|
||||
outl(tmp, txcon);
|
||||
|
||||
/* Give adress of RX and TX ring to the chip */
|
||||
outl(virt_to_bus(&rx_ring), prcdar);
|
||||
outl(virt_to_bus(&tx_ring), ptcdar);
|
||||
|
||||
/* Start the chip's Rx process: receive unicast and broadcast */
|
||||
outl(0x04, rxcon);
|
||||
outl(CR_START_RX | CR_QUEUE_RX, command);
|
||||
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
/* Initialize the Rx and Tx rings. */
|
||||
static void
|
||||
epic100_init_ring(void)
|
||||
{
|
||||
int i;
|
||||
char* p;
|
||||
|
||||
cur_rx = cur_tx = 0;
|
||||
|
||||
p = &rx_packet[0];
|
||||
for (i = 0; i < RX_RING_SIZE; i++) {
|
||||
rx_ring[i].status = RRING_OWN; /* Owned by Epic chip */
|
||||
rx_ring[i].buflength = PKT_BUF_SZ;
|
||||
rx_ring[i].bufaddr = virt_to_bus(p + (PKT_BUF_SZ * i));
|
||||
rx_ring[i].control = 0;
|
||||
rx_ring[i].next = virt_to_bus(&(rx_ring[i + 1]) );
|
||||
}
|
||||
/* Mark the last entry as wrapping the ring. */
|
||||
rx_ring[i-1].next = virt_to_bus(&rx_ring[0]);
|
||||
|
||||
/*
|
||||
*The Tx buffer descriptor is filled in as needed,
|
||||
* but we do need to clear the ownership bit.
|
||||
*/
|
||||
p = &tx_packet[0];
|
||||
|
||||
for (i = 0; i < TX_RING_SIZE; i++) {
|
||||
tx_ring[i].status = 0; /* Owned by CPU */
|
||||
tx_ring[i].bufaddr = virt_to_bus(p + (PKT_BUF_SZ * i));
|
||||
tx_ring[i].control = TD_STDFLAGS;
|
||||
tx_ring[i].next = virt_to_bus(&(tx_ring[i + 1]) );
|
||||
}
|
||||
tx_ring[i-1].next = virt_to_bus(&tx_ring[0]);
|
||||
}
|
||||
|
||||
/* function: epic100_transmit
|
||||
* This transmits a packet.
|
||||
*
|
||||
* Arguments: char d[6]: destination ethernet address.
|
||||
* unsigned short t: ethernet protocol type.
|
||||
* unsigned short s: size of the data-part of the packet.
|
||||
* char *p: the data for the packet.
|
||||
* returns: void.
|
||||
*/
|
||||
static void
|
||||
epic100_transmit(struct nic *nic, const char *destaddr, unsigned int type,
|
||||
unsigned int len, const char *data)
|
||||
{
|
||||
unsigned short nstype;
|
||||
char* txp;
|
||||
int entry;
|
||||
|
||||
/* Calculate the next Tx descriptor entry. */
|
||||
entry = cur_tx % TX_RING_SIZE;
|
||||
|
||||
if ((tx_ring[entry].status & TRING_OWN) == TRING_OWN) {
|
||||
printf("eth_transmit: Unable to transmit. status=%hX. Resetting...\n",
|
||||
tx_ring[entry].status);
|
||||
|
||||
epic100_open();
|
||||
return;
|
||||
}
|
||||
|
||||
txp = (char*)tx_ring[entry].bufaddr;
|
||||
|
||||
memcpy(txp, destaddr, ETH_ALEN);
|
||||
memcpy(txp + ETH_ALEN, nic->node_addr, ETH_ALEN);
|
||||
nstype = htons(type);
|
||||
memcpy(txp + 12, (char*)&nstype, 2);
|
||||
memcpy(txp + ETH_HLEN, data, len);
|
||||
|
||||
len += ETH_HLEN;
|
||||
|
||||
/*
|
||||
* Caution: the write order is important here,
|
||||
* set the base address with the "ownership"
|
||||
* bits last.
|
||||
*/
|
||||
tx_ring[entry].txlength = (len >= 60 ? len : 60);
|
||||
tx_ring[entry].buflength = len;
|
||||
tx_ring[entry].status = TRING_OWN; /* Pass ownership to the chip. */
|
||||
|
||||
cur_tx++;
|
||||
|
||||
/* Trigger an immediate transmit demand. */
|
||||
outl(CR_QUEUE_TX, command);
|
||||
|
||||
load_timer2(10*TICKS_PER_MS); /* timeout 10 ms for transmit */
|
||||
while ((tx_ring[entry].status & TRING_OWN) && timer2_running())
|
||||
/* Wait */;
|
||||
|
||||
if ((tx_ring[entry].status & TRING_OWN) != 0)
|
||||
printf("Oops, transmitter timeout, status=%hX\n",
|
||||
tx_ring[entry].status);
|
||||
}
|
||||
|
||||
/* function: epic100_poll / eth_poll
|
||||
* This receives a packet from the network.
|
||||
*
|
||||
* Arguments: none
|
||||
*
|
||||
* returns: 1 if a packet was received.
|
||||
* 0 if no pacet was received.
|
||||
* side effects:
|
||||
* returns the packet in the array nic->packet.
|
||||
* returns the length of the packet in nic->packetlen.
|
||||
*/
|
||||
|
||||
static int
|
||||
epic100_poll(struct nic *nic)
|
||||
{
|
||||
int entry;
|
||||
int status;
|
||||
int retcode;
|
||||
|
||||
entry = cur_rx % RX_RING_SIZE;
|
||||
|
||||
if ((status = rx_ring[entry].status & RRING_OWN) == RRING_OWN)
|
||||
return (0);
|
||||
|
||||
/* We own the next entry, it's a new packet. Send it up. */
|
||||
|
||||
#if (EPIC_DEBUG > 4)
|
||||
printf("epic_poll: entry %d status %hX\n", entry, status);
|
||||
#endif
|
||||
|
||||
cur_rx++;
|
||||
if (status & 0x2000) {
|
||||
printf("epic_poll: Giant packet\n");
|
||||
retcode = 0;
|
||||
} else if (status & 0x0006) {
|
||||
/* Rx Frame errors are counted in hardware. */
|
||||
printf("epic_poll: Frame received with errors\n");
|
||||
retcode = 0;
|
||||
} else {
|
||||
/* Omit the four octet CRC from the length. */
|
||||
nic->packetlen = rx_ring[entry].rxlength - 4;
|
||||
memcpy(nic->packet, (char*)rx_ring[entry].bufaddr, nic->packetlen);
|
||||
retcode = 1;
|
||||
}
|
||||
|
||||
/* Clear all error sources. */
|
||||
outl(status & INTR_CLEARERRS, intstat);
|
||||
|
||||
/* Give the descriptor back to the chip */
|
||||
rx_ring[entry].status = RRING_OWN;
|
||||
|
||||
/* Restart Receiver */
|
||||
outl(CR_START_RX | CR_QUEUE_RX, command);
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
epic100_disable(struct nic *nic)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_EEPROM
|
||||
/* Serial EEPROM section. */
|
||||
|
||||
/* EEPROM_Ctrl bits. */
|
||||
#define EE_SHIFT_CLK 0x04 /* EEPROM shift clock. */
|
||||
#define EE_CS 0x02 /* EEPROM chip select. */
|
||||
#define EE_DATA_WRITE 0x08 /* EEPROM chip data in. */
|
||||
#define EE_WRITE_0 0x01
|
||||
#define EE_WRITE_1 0x09
|
||||
#define EE_DATA_READ 0x10 /* EEPROM chip data out. */
|
||||
#define EE_ENB (0x0001 | EE_CS)
|
||||
|
||||
/* The EEPROM commands include the alway-set leading bit. */
|
||||
#define EE_WRITE_CMD (5 << 6)
|
||||
#define EE_READ_CMD (6 << 6)
|
||||
#define EE_ERASE_CMD (7 << 6)
|
||||
|
||||
#define eeprom_delay(n) delay(n)
|
||||
|
||||
static int
|
||||
read_eeprom(int location)
|
||||
{
|
||||
int i;
|
||||
int retval = 0;
|
||||
int read_cmd = location | EE_READ_CMD;
|
||||
|
||||
outl(EE_ENB & ~EE_CS, eectl);
|
||||
outl(EE_ENB, eectl);
|
||||
|
||||
/* Shift the read command bits out. */
|
||||
for (i = 10; i >= 0; i--) {
|
||||
short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
|
||||
outl(EE_ENB | dataval, eectl);
|
||||
eeprom_delay(100);
|
||||
outl(EE_ENB | dataval | EE_SHIFT_CLK, eectl);
|
||||
eeprom_delay(150);
|
||||
outl(EE_ENB | dataval, eectl); /* Finish EEPROM a clock tick. */
|
||||
eeprom_delay(250);
|
||||
}
|
||||
outl(EE_ENB, eectl);
|
||||
|
||||
for (i = 16; i > 0; i--) {
|
||||
outl(EE_ENB | EE_SHIFT_CLK, eectl);
|
||||
eeprom_delay(100);
|
||||
retval = (retval << 1) | ((inl(eectl) & EE_DATA_READ) ? 1 : 0);
|
||||
outl(EE_ENB, eectl);
|
||||
eeprom_delay(100);
|
||||
}
|
||||
|
||||
/* Terminate the EEPROM access. */
|
||||
outl(EE_ENB & ~EE_CS, eectl);
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define MII_READOP 1
|
||||
#define MII_WRITEOP 2
|
||||
|
||||
static int
|
||||
mii_read(int phy_id, int location)
|
||||
{
|
||||
int i;
|
||||
|
||||
outl((phy_id << 9) | (location << 4) | MII_READOP, mmctl);
|
||||
/* Typical operation takes < 50 ticks. */
|
||||
|
||||
for (i = 4000; i > 0; i--)
|
||||
if ((inl(mmctl) & MII_READOP) == 0)
|
||||
break;
|
||||
return inw(mmdata);
|
||||
}
|
||||
@@ -1,188 +0,0 @@
|
||||
#ifndef _EPIC100_H_
|
||||
# define _EPIC100_H_
|
||||
|
||||
#ifndef PCI_VENDOR_SMC
|
||||
# define PCI_VENDOR_SMC 0x10B8
|
||||
#endif
|
||||
|
||||
#ifndef PCI_DEVICE_SMC_EPIC100
|
||||
# define PCI_DEVICE_SMC_EPIC100 0x0005
|
||||
#endif
|
||||
|
||||
#define PCI_DEVICE_ID_NONE 0xFFFF
|
||||
|
||||
/* Offsets to registers (using SMC names). */
|
||||
enum epic100_registers {
|
||||
COMMAND= 0, /* Control Register */
|
||||
INTSTAT= 4, /* Interrupt Status */
|
||||
INTMASK= 8, /* Interrupt Mask */
|
||||
GENCTL = 0x0C, /* General Control */
|
||||
NVCTL = 0x10, /* Non Volatile Control */
|
||||
EECTL = 0x14, /* EEPROM Control */
|
||||
TEST = 0x1C, /* Test register: marked as reserved (see in source code) */
|
||||
CRCCNT = 0x20, /* CRC Error Counter */
|
||||
ALICNT = 0x24, /* Frame Alignment Error Counter */
|
||||
MPCNT = 0x28, /* Missed Packet Counter */
|
||||
MMCTL = 0x30, /* MII Management Interface Control */
|
||||
MMDATA = 0x34, /* MII Management Interface Data */
|
||||
MIICFG = 0x38, /* MII Configuration */
|
||||
IPG = 0x3C, /* InterPacket Gap */
|
||||
LAN0 = 0x40, /* MAC address. (0x40-0x48) */
|
||||
IDCHK = 0x4C, /* BoardID/ Checksum */
|
||||
MC0 = 0x50, /* Multicast filter table. (0x50-0x5c) */
|
||||
RXCON = 0x60, /* Receive Control */
|
||||
TXCON = 0x70, /* Transmit Control */
|
||||
TXSTAT = 0x74, /* Transmit Status */
|
||||
PRCDAR = 0x84, /* PCI Receive Current Descriptor Address */
|
||||
PRSTAT = 0xA4, /* PCI Receive DMA Status */
|
||||
PRCPTHR= 0xB0, /* PCI Receive Copy Threshold */
|
||||
PTCDAR = 0xC4, /* PCI Transmit Current Descriptor Address */
|
||||
ETHTHR = 0xDC /* Early Transmit Threshold */
|
||||
};
|
||||
|
||||
/* Command register (CR_) bits */
|
||||
#define CR_STOP_RX (0x00000001)
|
||||
#define CR_START_RX (0x00000002)
|
||||
#define CR_QUEUE_TX (0x00000004)
|
||||
#define CR_QUEUE_RX (0x00000008)
|
||||
#define CR_NEXTFRAME (0x00000010)
|
||||
#define CR_STOP_TX_DMA (0x00000020)
|
||||
#define CR_STOP_RX_DMA (0x00000040)
|
||||
#define CR_TX_UGO (0x00000080)
|
||||
|
||||
/* Interrupt register bits. NI means No Interrupt generated */
|
||||
|
||||
#define INTR_RX_THR_STA (0x00400000) /* rx copy threshold status NI */
|
||||
#define INTR_RX_BUFF_EMPTY (0x00200000) /* rx buffers empty. NI */
|
||||
#define INTR_TX_IN_PROG (0x00100000) /* tx copy in progess. NI */
|
||||
#define INTR_RX_IN_PROG (0x00080000) /* rx copy in progress. NI */
|
||||
#define INTR_TXIDLE (0x00040000) /* tx idle. NI */
|
||||
#define INTR_RXIDLE (0x00020000) /* rx idle. NI */
|
||||
#define INTR_INTR_ACTIVE (0x00010000) /* Interrupt active. NI */
|
||||
#define INTR_RX_STATUS_OK (0x00008000) /* rx status valid. NI */
|
||||
#define INTR_PCI_TGT_ABT (0x00004000) /* PCI Target abort */
|
||||
#define INTR_PCI_MASTER_ABT (0x00002000) /* PCI Master abort */
|
||||
#define INTR_PCI_PARITY_ERR (0x00001000) /* PCI adress parity error */
|
||||
#define INTR_PCI_DATA_ERR (0x00000800) /* PCI data parity error */
|
||||
#define INTR_RX_THR_CROSSED (0x00000400) /* rx copy threshold crossed */
|
||||
#define INTR_CNTFULL (0x00000200) /* Counter overflow */
|
||||
#define INTR_TXUNDERRUN (0x00000100) /* tx underrun. */
|
||||
#define INTR_TXEMPTY (0x00000080) /* tx queue empty */
|
||||
#define INTR_TX_CH_COMPLETE (0x00000040) /* tx chain complete */
|
||||
#define INTR_TXDONE (0x00000020) /* tx complete (w or w/o err) */
|
||||
#define INTR_RXERROR (0x00000010) /* rx error (CRC) */
|
||||
#define INTR_RXOVERFLOW (0x00000008) /* rx buffer overflow */
|
||||
#define INTR_RX_QUEUE_EMPTY (0x00000004) /* rx queue empty. */
|
||||
#define INTR_RXHEADER (0x00000002) /* header copy complete */
|
||||
#define INTR_RXDONE (0x00000001) /* Receive copy complete */
|
||||
|
||||
#define INTR_CLEARINTR (0x00007FFF)
|
||||
#define INTR_VALIDBITS (0x007FFFFF)
|
||||
#define INTR_DISABLE (0x00000000)
|
||||
#define INTR_CLEARERRS (0x00007F18)
|
||||
#define INTR_ABNINTR (INTR_CNTFULL | INTR_TXUNDERRUN | INTR_RXOVERFLOW)
|
||||
|
||||
/* General Control (GC_) bits */
|
||||
|
||||
#define GC_SOFT_RESET (0x00000001)
|
||||
#define GC_INTR_ENABLE (0x00000002)
|
||||
#define GC_SOFT_INTR (0x00000004)
|
||||
#define GC_POWER_DOWN (0x00000008)
|
||||
#define GC_ONE_COPY (0x00000010)
|
||||
#define GC_BIG_ENDIAN (0x00000020)
|
||||
#define GC_RX_PREEMPT_TX (0x00000040)
|
||||
#define GC_TX_PREEMPT_RX (0x00000080)
|
||||
|
||||
/*
|
||||
* Receive FIFO Threshold values
|
||||
* Control the level at which the PCI burst state machine
|
||||
* begins to empty the receive FIFO. Possible values: 0-3
|
||||
*
|
||||
* 0 => 32, 1 => 64, 2 => 96 3 => 128 bytes.
|
||||
*/
|
||||
#define GC_RX_FIFO_THR_32 (0x00000000)
|
||||
#define GC_RX_FIFO_THR_64 (0x00000100)
|
||||
#define GC_RX_FIFO_THR_96 (0x00000200)
|
||||
#define GC_RX_FIFO_THR_128 (0x00000300)
|
||||
|
||||
/* Memory Read Control (MRC_) values */
|
||||
#define GC_MRC_MEM_READ (0x00000000)
|
||||
#define GC_MRC_READ_MULT (0x00000400)
|
||||
#define GC_MRC_READ_LINE (0x00000800)
|
||||
|
||||
#define GC_SOFTBIT0 (0x00001000)
|
||||
#define GC_SOFTBIT1 (0x00002000)
|
||||
#define GC_RESET_PHY (0x00004000)
|
||||
|
||||
/* Definitions of the Receive Control (RC_) register bits */
|
||||
|
||||
#define RC_SAVE_ERRORED_PKT (0x00000001)
|
||||
#define RC_SAVE_RUNT_FRAMES (0x00000002)
|
||||
#define RC_RCV_BROADCAST (0x00000004)
|
||||
#define RC_RCV_MULTICAST (0x00000008)
|
||||
#define RC_RCV_INVERSE_PKT (0x00000010)
|
||||
#define RC_PROMISCUOUS_MODE (0x00000020)
|
||||
#define RC_MONITOR_MODE (0x00000040)
|
||||
#define RC_EARLY_RCV_ENABLE (0x00000080)
|
||||
|
||||
/* description of the rx descriptors control bits */
|
||||
#define RD_FRAGLIST (0x0001) /* Desc points to a fragment list */
|
||||
#define RD_LLFORM (0x0002) /* Frag list format */
|
||||
#define RD_HDR_CPY (0x0004) /* Desc used for header copy */
|
||||
|
||||
/* Definition of the Transmit CONTROL (TC) register bits */
|
||||
|
||||
#define TC_EARLY_TX_ENABLE (0x00000001)
|
||||
|
||||
/* Loopback Mode (LM_) Select valuesbits */
|
||||
#define TC_LM_NORMAL (0x00000000)
|
||||
#define TC_LM_INTERNAL (0x00000002)
|
||||
#define TC_LM_EXTERNAL (0x00000004)
|
||||
#define TC_LM_FULL_DPX (0x00000006)
|
||||
|
||||
#define TX_SLOT_TIME (0x00000078)
|
||||
|
||||
/* Bytes transferred to chip before transmission starts. */
|
||||
#define TX_FIFO_THRESH 128 /* Rounded down to 4 byte units. */
|
||||
|
||||
/* description of rx descriptors status bits */
|
||||
#define RRING_PKT_INTACT (0x0001)
|
||||
#define RRING_ALIGN_ERR (0x0002)
|
||||
#define RRING_CRC_ERR (0x0004)
|
||||
#define RRING_MISSED_PKT (0x0008)
|
||||
#define RRING_MULTICAST (0x0010)
|
||||
#define RRING_BROADCAST (0x0020)
|
||||
#define RRING_RECEIVER_DISABLE (0x0040)
|
||||
#define RRING_STATUS_VALID (0x1000)
|
||||
#define RRING_FRAGLIST_ERR (0x2000)
|
||||
#define RRING_HDR_COPIED (0x4000)
|
||||
#define RRING_OWN (0x8000)
|
||||
|
||||
/* error summary */
|
||||
#define RRING_ERROR (RRING_ALIGN_ERR|RRING_CRC_ERR)
|
||||
|
||||
/* description of tx descriptors status bits */
|
||||
#define TRING_PKT_INTACT (0x0001) /* pkt transmitted. */
|
||||
#define TRING_PKT_NONDEFER (0x0002) /* pkt xmitted w/o deferring */
|
||||
#define TRING_COLL (0x0004) /* pkt xmitted w collisions */
|
||||
#define TRING_CARR (0x0008) /* carrier sense lost */
|
||||
#define TRING_UNDERRUN (0x0010) /* DMA underrun */
|
||||
#define TRING_HB_COLL (0x0020) /* Collision detect Heartbeat */
|
||||
#define TRING_WIN_COLL (0x0040) /* out of window collision */
|
||||
#define TRING_DEFERRED (0x0080) /* Deferring */
|
||||
#define TRING_COLL_COUNT (0x0F00) /* collision counter (mask) */
|
||||
#define TRING_COLL_EXCESS (0x1000) /* tx aborted: excessive colls */
|
||||
#define TRING_OWN (0x8000) /* desc ownership bit */
|
||||
|
||||
/* error summary */
|
||||
#define TRING_ABORT (TRING_COLL_EXCESS|TRING_WIN_COLL|TRING_UNDERRUN)
|
||||
#define TRING_ERROR (TRING_DEFERRED|TRING_WIN_COLL|TRING_UNDERRUN|TRING_CARR/*|TRING_COLL*/ )
|
||||
|
||||
/* description of the tx descriptors control bits */
|
||||
#define TD_FRAGLIST (0x0001) /* Desc points to a fragment list */
|
||||
#define TD_LLFORM (0x0002) /* Frag list format */
|
||||
#define TD_IAF (0x0004) /* Generate Interrupt after tx */
|
||||
#define TD_NOCRC (0x0008) /* No CRC generated */
|
||||
#define TD_LASTDESC (0x0010) /* Last desc for this frame */
|
||||
|
||||
#endif /* _EPIC100_H_ */
|
||||
@@ -1,544 +0,0 @@
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
|
||||
*
|
||||
* 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
|
||||
* (at your option) 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.
|
||||
*/
|
||||
|
||||
/* RULE: You must define the macro ``GRUB'' when including this header
|
||||
file in GRUB code. */
|
||||
|
||||
/* Based on "src/etherboot.h" in etherboot-5.0.5. */
|
||||
|
||||
/**************************************************************************
|
||||
ETHERBOOT - BOOTP/TFTP Bootstrap Program
|
||||
|
||||
Author: Martin Renters
|
||||
Date: Dec/93
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/* Include GRUB-specific macros and prototypes here. */
|
||||
#include <shared.h>
|
||||
|
||||
/* FIXME: For now, enable the DHCP support. Perhaps I should segregate
|
||||
the DHCP support from the BOOTP support, and permit both to
|
||||
co-exist. */
|
||||
#undef NO_DHCP_SUPPORT
|
||||
|
||||
/* In GRUB, the relocated address in Etherboot doesn't have any sense.
|
||||
Just define it as a bogus value. */
|
||||
#define RELOC 0
|
||||
|
||||
/* FIXME: Should be an option. */
|
||||
#define BACKOFF_LIMIT 7
|
||||
|
||||
#include <osdep.h>
|
||||
|
||||
#define CTRL_C 3
|
||||
|
||||
#ifndef MAX_TFTP_RETRIES
|
||||
# define MAX_TFTP_RETRIES 20
|
||||
#endif
|
||||
|
||||
#ifndef MAX_BOOTP_RETRIES
|
||||
# define MAX_BOOTP_RETRIES 20
|
||||
#endif
|
||||
|
||||
#define MAX_BOOTP_EXTLEN (ETH_FRAME_LEN - ETH_HLEN - \
|
||||
sizeof (struct bootp_t))
|
||||
|
||||
#ifndef MAX_ARP_RETRIES
|
||||
# define MAX_ARP_RETRIES 20
|
||||
#endif
|
||||
|
||||
#ifndef MAX_RPC_RETRIES
|
||||
# define MAX_RPC_RETRIES 20
|
||||
#endif
|
||||
|
||||
#define TICKS_PER_SEC 18
|
||||
|
||||
/* Inter-packet retry in ticks */
|
||||
#define TIMEOUT (10 * TICKS_PER_SEC)
|
||||
|
||||
/* These settings have sense only if compiled with -DCONGESTED */
|
||||
/* total retransmission timeout in ticks */
|
||||
#define TFTP_TIMEOUT (30 * TICKS_PER_SEC)
|
||||
/* packet retransmission timeout in ticks */
|
||||
#define TFTP_REXMT (3 * TICKS_PER_SEC)
|
||||
|
||||
#ifndef NULL
|
||||
# define NULL ((void *) 0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
I'm moving towards the defined names in linux/if_ether.h for clarity.
|
||||
The confusion between 60/64 and 1514/1518 arose because the NS8390
|
||||
counts the 4 byte frame checksum in the incoming packet, but not
|
||||
in the outgoing packet. 60/1514 are the correct numbers for most
|
||||
if not all of the other NIC controllers. I will be retiring the
|
||||
64/1518 defines in the lead-up to 5.0.
|
||||
*/
|
||||
|
||||
#define ETH_ALEN 6 /* Size of Ethernet address */
|
||||
#define ETH_HLEN 14 /* Size of ethernet header */
|
||||
#define ETH_ZLEN 60 /* Minimum packet */
|
||||
/*#define ETH_MIN_PACKET 64*/
|
||||
#define ETH_FRAME_LEN 1514 /* Maximum packet */
|
||||
/*#define ETH_MAX_PACKET 1518*/
|
||||
/* Because some DHCP/BOOTP servers don't treat the maximum length the same
|
||||
as Etherboot, subtract the size of an IP header and that of an UDP
|
||||
header. */
|
||||
#define ETH_MAX_MTU (ETH_FRAME_LEN - ETH_HLEN \
|
||||
- sizeof (struct iphdr) \
|
||||
- sizeof (struct udphdr))
|
||||
|
||||
#define ARP_CLIENT 0
|
||||
#define ARP_SERVER 1
|
||||
#define ARP_GATEWAY 2
|
||||
#define ARP_ROOTSERVER 3
|
||||
#define ARP_SWAPSERVER 4
|
||||
#define MAX_ARP ARP_SWAPSERVER+1
|
||||
|
||||
#define RARP_REQUEST 3
|
||||
#define RARP_REPLY 4
|
||||
|
||||
#define IP 0x0800
|
||||
#define ARP 0x0806
|
||||
#define RARP 0x8035
|
||||
|
||||
#define BOOTP_SERVER 67
|
||||
#define BOOTP_CLIENT 68
|
||||
#define TFTP_PORT 69
|
||||
#define SUNRPC_PORT 111
|
||||
|
||||
#define IP_UDP 17
|
||||
/* Same after going through htonl */
|
||||
#define IP_BROADCAST 0xFFFFFFFF
|
||||
|
||||
#define ARP_REQUEST 1
|
||||
#define ARP_REPLY 2
|
||||
|
||||
#define BOOTP_REQUEST 1
|
||||
#define BOOTP_REPLY 2
|
||||
|
||||
#define TAG_LEN(p) (*((p) + 1))
|
||||
#define RFC1533_COOKIE 99, 130, 83, 99
|
||||
#define RFC1533_PAD 0
|
||||
#define RFC1533_NETMASK 1
|
||||
#define RFC1533_TIMEOFFSET 2
|
||||
#define RFC1533_GATEWAY 3
|
||||
#define RFC1533_TIMESERVER 4
|
||||
#define RFC1533_IEN116NS 5
|
||||
#define RFC1533_DNS 6
|
||||
#define RFC1533_LOGSERVER 7
|
||||
#define RFC1533_COOKIESERVER 8
|
||||
#define RFC1533_LPRSERVER 9
|
||||
#define RFC1533_IMPRESSSERVER 10
|
||||
#define RFC1533_RESOURCESERVER 11
|
||||
#define RFC1533_HOSTNAME 12
|
||||
#define RFC1533_BOOTFILESIZE 13
|
||||
#define RFC1533_MERITDUMPFILE 14
|
||||
#define RFC1533_DOMAINNAME 15
|
||||
#define RFC1533_SWAPSERVER 16
|
||||
#define RFC1533_ROOTPATH 17
|
||||
#define RFC1533_EXTENSIONPATH 18
|
||||
#define RFC1533_IPFORWARDING 19
|
||||
#define RFC1533_IPSOURCEROUTING 20
|
||||
#define RFC1533_IPPOLICYFILTER 21
|
||||
#define RFC1533_IPMAXREASSEMBLY 22
|
||||
#define RFC1533_IPTTL 23
|
||||
#define RFC1533_IPMTU 24
|
||||
#define RFC1533_IPMTUPLATEAU 25
|
||||
#define RFC1533_INTMTU 26
|
||||
#define RFC1533_INTLOCALSUBNETS 27
|
||||
#define RFC1533_INTBROADCAST 28
|
||||
#define RFC1533_INTICMPDISCOVER 29
|
||||
#define RFC1533_INTICMPRESPOND 30
|
||||
#define RFC1533_INTROUTEDISCOVER 31
|
||||
#define RFC1533_INTROUTESOLICIT 32
|
||||
#define RFC1533_INTSTATICROUTES 33
|
||||
#define RFC1533_LLTRAILERENCAP 34
|
||||
#define RFC1533_LLARPCACHETMO 35
|
||||
#define RFC1533_LLETHERNETENCAP 36
|
||||
#define RFC1533_TCPTTL 37
|
||||
#define RFC1533_TCPKEEPALIVETMO 38
|
||||
#define RFC1533_TCPKEEPALIVEGB 39
|
||||
#define RFC1533_NISDOMAIN 40
|
||||
#define RFC1533_NISSERVER 41
|
||||
#define RFC1533_NTPSERVER 42
|
||||
#define RFC1533_VENDOR 43
|
||||
#define RFC1533_NBNS 44
|
||||
#define RFC1533_NBDD 45
|
||||
#define RFC1533_NBNT 46
|
||||
#define RFC1533_NBSCOPE 47
|
||||
#define RFC1533_XFS 48
|
||||
#define RFC1533_XDM 49
|
||||
#ifndef NO_DHCP_SUPPORT
|
||||
#define RFC2132_REQ_ADDR 50
|
||||
#define RFC2132_MSG_TYPE 53
|
||||
#define RFC2132_SRV_ID 54
|
||||
#define RFC2132_PARAM_LIST 55
|
||||
#define RFC2132_MAX_SIZE 57
|
||||
#define RFC2132_VENDOR_CLASS_ID 60
|
||||
|
||||
#define DHCPDISCOVER 1
|
||||
#define DHCPOFFER 2
|
||||
#define DHCPREQUEST 3
|
||||
#define DHCPACK 5
|
||||
#endif /* NO_DHCP_SUPPORT */
|
||||
|
||||
#define RFC1533_VENDOR_MAJOR 0
|
||||
#define RFC1533_VENDOR_MINOR 0
|
||||
|
||||
#define RFC1533_VENDOR_MAGIC 128
|
||||
#define RFC1533_VENDOR_ADDPARM 129
|
||||
#define RFC1533_VENDOR_MNUOPTS 160
|
||||
#define RFC1533_VENDOR_SELECTION 176
|
||||
#define RFC1533_VENDOR_MOTD 184
|
||||
#define RFC1533_VENDOR_NUMOFMOTD 8
|
||||
#define RFC1533_VENDOR_IMG 192
|
||||
#define RFC1533_VENDOR_NUMOFIMG 16
|
||||
|
||||
#define RFC1533_VENDOR_CONFIGFILE 150
|
||||
|
||||
#define RFC1533_END 255
|
||||
|
||||
#define BOOTP_VENDOR_LEN 64
|
||||
#ifndef NO_DHCP_SUPPORT
|
||||
#define DHCP_OPT_LEN 312
|
||||
#endif /* NO_DHCP_SUPPORT */
|
||||
|
||||
#define TFTP_DEFAULTSIZE_PACKET 512
|
||||
#define TFTP_MAX_PACKET 1432 /* 512 */
|
||||
|
||||
#define TFTP_RRQ 1
|
||||
#define TFTP_WRQ 2
|
||||
#define TFTP_DATA 3
|
||||
#define TFTP_ACK 4
|
||||
#define TFTP_ERROR 5
|
||||
#define TFTP_OACK 6
|
||||
|
||||
#define TFTP_CODE_EOF 1
|
||||
#define TFTP_CODE_MORE 2
|
||||
#define TFTP_CODE_ERROR 3
|
||||
#define TFTP_CODE_BOOT 4
|
||||
#define TFTP_CODE_CFG 5
|
||||
|
||||
#define AWAIT_ARP 0
|
||||
#define AWAIT_BOOTP 1
|
||||
#define AWAIT_TFTP 2
|
||||
#define AWAIT_RARP 3
|
||||
#define AWAIT_RPC 4
|
||||
#define AWAIT_QDRAIN 5 /* drain queue, process ARP requests */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned long s_addr;
|
||||
}
|
||||
in_addr;
|
||||
|
||||
struct arptable_t
|
||||
{
|
||||
in_addr ipaddr;
|
||||
unsigned char node[6];
|
||||
};
|
||||
|
||||
/*
|
||||
* A pity sipaddr and tipaddr are not longword aligned or we could use
|
||||
* in_addr. No, I don't want to use #pragma packed.
|
||||
*/
|
||||
struct arprequest
|
||||
{
|
||||
unsigned short hwtype;
|
||||
unsigned short protocol;
|
||||
char hwlen;
|
||||
char protolen;
|
||||
unsigned short opcode;
|
||||
char shwaddr[6];
|
||||
char sipaddr[4];
|
||||
char thwaddr[6];
|
||||
char tipaddr[4];
|
||||
};
|
||||
|
||||
struct iphdr
|
||||
{
|
||||
char verhdrlen;
|
||||
char service;
|
||||
unsigned short len;
|
||||
unsigned short ident;
|
||||
unsigned short frags;
|
||||
char ttl;
|
||||
char protocol;
|
||||
unsigned short chksum;
|
||||
in_addr src;
|
||||
in_addr dest;
|
||||
};
|
||||
|
||||
struct udphdr
|
||||
{
|
||||
unsigned short src;
|
||||
unsigned short dest;
|
||||
unsigned short len;
|
||||
unsigned short chksum;
|
||||
};
|
||||
|
||||
/* Format of a bootp packet. */
|
||||
struct bootp_t
|
||||
{
|
||||
char bp_op;
|
||||
char bp_htype;
|
||||
char bp_hlen;
|
||||
char bp_hops;
|
||||
unsigned long bp_xid;
|
||||
unsigned short bp_secs;
|
||||
unsigned short unused;
|
||||
in_addr bp_ciaddr;
|
||||
in_addr bp_yiaddr;
|
||||
in_addr bp_siaddr;
|
||||
in_addr bp_giaddr;
|
||||
char bp_hwaddr[16];
|
||||
char bp_sname[64];
|
||||
char bp_file[128];
|
||||
#ifdef NO_DHCP_SUPPORT
|
||||
char bp_vend[BOOTP_VENDOR_LEN];
|
||||
#else
|
||||
char bp_vend[DHCP_OPT_LEN];
|
||||
#endif /* NO_DHCP_SUPPORT */
|
||||
};
|
||||
|
||||
/* Format of a bootp IP packet. */
|
||||
struct bootpip_t
|
||||
{
|
||||
struct iphdr ip;
|
||||
struct udphdr udp;
|
||||
struct bootp_t bp;
|
||||
};
|
||||
|
||||
/* Format of bootp packet with extensions. */
|
||||
struct bootpd_t
|
||||
{
|
||||
struct bootp_t bootp_reply;
|
||||
unsigned char bootp_extension[MAX_BOOTP_EXTLEN];
|
||||
};
|
||||
|
||||
struct tftp_t
|
||||
{
|
||||
struct iphdr ip;
|
||||
struct udphdr udp;
|
||||
unsigned short opcode;
|
||||
union
|
||||
{
|
||||
char rrq[TFTP_DEFAULTSIZE_PACKET];
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned short block;
|
||||
char download[TFTP_MAX_PACKET];
|
||||
}
|
||||
data;
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned short block;
|
||||
}
|
||||
ack;
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned short errcode;
|
||||
char errmsg[TFTP_DEFAULTSIZE_PACKET];
|
||||
}
|
||||
err;
|
||||
|
||||
struct
|
||||
{
|
||||
char data[TFTP_DEFAULTSIZE_PACKET+2];
|
||||
}
|
||||
oack;
|
||||
}
|
||||
u;
|
||||
};
|
||||
|
||||
/* Define a smaller tftp packet solely for making requests to conserve stack
|
||||
512 bytes should be enough. */
|
||||
struct tftpreq_t
|
||||
{
|
||||
struct iphdr ip;
|
||||
struct udphdr udp;
|
||||
unsigned short opcode;
|
||||
union
|
||||
{
|
||||
char rrq[512];
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned short block;
|
||||
}
|
||||
ack;
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned short errcode;
|
||||
char errmsg[512-2];
|
||||
}
|
||||
err;
|
||||
}
|
||||
u;
|
||||
};
|
||||
|
||||
#define TFTP_MIN_PACKET (sizeof(struct iphdr) + sizeof(struct udphdr) + 4)
|
||||
|
||||
struct rpc_t
|
||||
{
|
||||
struct iphdr ip;
|
||||
struct udphdr udp;
|
||||
union
|
||||
{
|
||||
char data[300]; /* longest RPC call must fit!!!! */
|
||||
|
||||
struct
|
||||
{
|
||||
long id;
|
||||
long type;
|
||||
long rpcvers;
|
||||
long prog;
|
||||
long vers;
|
||||
long proc;
|
||||
long data[1];
|
||||
}
|
||||
call;
|
||||
|
||||
struct
|
||||
{
|
||||
long id;
|
||||
long type;
|
||||
long rstatus;
|
||||
long verifier;
|
||||
long v2;
|
||||
long astatus;
|
||||
long data[1];
|
||||
}
|
||||
reply;
|
||||
}
|
||||
u;
|
||||
};
|
||||
|
||||
#define PROG_PORTMAP 100000
|
||||
#define PROG_NFS 100003
|
||||
#define PROG_MOUNT 100005
|
||||
|
||||
#define MSG_CALL 0
|
||||
#define MSG_REPLY 1
|
||||
|
||||
#define PORTMAP_GETPORT 3
|
||||
|
||||
#define MOUNT_ADDENTRY 1
|
||||
#define MOUNT_UMOUNTALL 4
|
||||
|
||||
#define NFS_LOOKUP 4
|
||||
#define NFS_READ 6
|
||||
|
||||
#define NFS_FHSIZE 32
|
||||
|
||||
#define NFSERR_PERM 1
|
||||
#define NFSERR_NOENT 2
|
||||
#define NFSERR_ACCES 13
|
||||
|
||||
/* Block size used for NFS read accesses. A RPC reply packet (including all
|
||||
* headers) must fit within a single Ethernet frame to avoid fragmentation.
|
||||
* Chosen to be a power of two, as most NFS servers are optimized for this. */
|
||||
#define NFS_READ_SIZE 1024
|
||||
|
||||
#define FLOPPY_BOOT_LOCATION 0x7c00
|
||||
/* Must match offsets in loader.S */
|
||||
#define ROM_SEGMENT 0x1fa
|
||||
#define ROM_LENGTH 0x1fc
|
||||
|
||||
#define ROM_INFO_LOCATION (FLOPPY_BOOT_LOCATION + ROM_SEGMENT)
|
||||
/* at end of floppy boot block */
|
||||
|
||||
struct rom_info
|
||||
{
|
||||
unsigned short rom_segment;
|
||||
unsigned short rom_length;
|
||||
};
|
||||
|
||||
static inline int
|
||||
rom_address_ok (struct rom_info *rom, int assigned_rom_segment)
|
||||
{
|
||||
return (assigned_rom_segment < 0xC000
|
||||
|| assigned_rom_segment == rom->rom_segment);
|
||||
}
|
||||
|
||||
/* Define a type for passing info to a loaded program. */
|
||||
struct ebinfo
|
||||
{
|
||||
unsigned char major, minor; /* Version */
|
||||
unsigned short flags; /* Bit flags */
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
External prototypes
|
||||
***************************************************************************/
|
||||
/* main.c */
|
||||
extern void print_network_configuration (void);
|
||||
extern int ifconfig (char *ip, char *sm, char *gw, char *svr);
|
||||
extern int udp_transmit (unsigned long destip, unsigned int srcsock,
|
||||
unsigned int destsock, int len, const void *buf);
|
||||
extern int await_reply (int type, int ival, void *ptr, int timeout);
|
||||
extern int decode_rfc1533 (unsigned char *, int, int, int);
|
||||
extern long rfc2131_sleep_interval (int base, int exp);
|
||||
extern void cleanup (void);
|
||||
extern int rarp (void);
|
||||
extern int bootp (void);
|
||||
extern void cleanup_net (void);
|
||||
|
||||
/* config.c */
|
||||
extern void print_config (void);
|
||||
extern void eth_reset (void);
|
||||
extern int eth_probe (void);
|
||||
extern int eth_poll (void);
|
||||
extern void eth_transmit (const char *d, unsigned int t,
|
||||
unsigned int s, const void *p);
|
||||
extern void eth_disable (void);
|
||||
|
||||
/* misc.c */
|
||||
extern void twiddle (void);
|
||||
extern void sleep (int secs);
|
||||
extern int getdec (char **s);
|
||||
extern void etherboot_printf (const char *, ...);
|
||||
extern int etherboot_sprintf (char *, const char *, ...);
|
||||
extern int inet_aton (char *p, in_addr *i);
|
||||
|
||||
/***************************************************************************
|
||||
External variables
|
||||
***************************************************************************/
|
||||
/* main.c */
|
||||
extern int ip_abort;
|
||||
extern int network_ready;
|
||||
extern struct rom_info rom;
|
||||
extern struct arptable_t arptable[MAX_ARP];
|
||||
|
||||
/* config.c */
|
||||
extern struct nic nic;
|
||||
|
||||
/* Local hack - define some macros to use etherboot source files "as is". */
|
||||
#ifndef GRUB
|
||||
# undef printf
|
||||
# define printf etherboot_printf
|
||||
# undef sprintf
|
||||
# define sprintf etherboot_sprintf
|
||||
#endif /* GRUB */
|
||||
-421
@@ -1,421 +0,0 @@
|
||||
/*
|
||||
Driver for the National Semiconductor DP83810 Ethernet controller.
|
||||
|
||||
Portions Copyright (C) 2001 Inprimis Technologies, Inc.
|
||||
http://www.inprimis.com/
|
||||
|
||||
This driver is based (heavily) on the Linux driver for this chip
|
||||
which is copyright 1999-2001 by Donald Becker.
|
||||
|
||||
This software has no warranties expressed or implied for any
|
||||
purpose.
|
||||
|
||||
This software may be used and distributed according to the terms of
|
||||
the GNU General Public License (GPL), incorporated herein by reference.
|
||||
Drivers based on or derived from this code fall under the GPL and must
|
||||
retain the authorship, copyright and license notice. This file is not
|
||||
a complete program and may only be used when the entire operating
|
||||
system is licensed under the GPL. License for under other terms may be
|
||||
available. Contact the original author for details.
|
||||
|
||||
The original author may be reached as becker@scyld.com, or at
|
||||
Scyld Computing Corporation
|
||||
410 Severn Ave., Suite 210
|
||||
Annapolis MD 21403
|
||||
*/
|
||||
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef signed char s8;
|
||||
typedef unsigned short u16;
|
||||
typedef signed short s16;
|
||||
typedef unsigned int u32;
|
||||
typedef signed int s32;
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "pci.h"
|
||||
|
||||
#undef virt_to_bus
|
||||
#define virt_to_bus(x) ((unsigned long)x)
|
||||
#define cpu_to_le32(val) (val)
|
||||
#define le32_to_cpu(val) (val)
|
||||
#define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr))
|
||||
#define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
|
||||
|
||||
#define TX_RING_SIZE 1
|
||||
#define RX_RING_SIZE 4
|
||||
#define TIME_OUT 1000000
|
||||
#define PKT_BUF_SZ 1536
|
||||
|
||||
/* Offsets to the device registers. */
|
||||
enum register_offsets {
|
||||
ChipCmd=0x00, ChipConfig=0x04, EECtrl=0x08, PCIBusCfg=0x0C,
|
||||
IntrStatus=0x10, IntrMask=0x14, IntrEnable=0x18,
|
||||
TxRingPtr=0x20, TxConfig=0x24,
|
||||
RxRingPtr=0x30, RxConfig=0x34,
|
||||
WOLCmd=0x40, PauseCmd=0x44, RxFilterAddr=0x48, RxFilterData=0x4C,
|
||||
BootRomAddr=0x50, BootRomData=0x54, StatsCtrl=0x5C, StatsData=0x60,
|
||||
RxPktErrs=0x60, RxMissed=0x68, RxCRCErrs=0x64,
|
||||
};
|
||||
|
||||
/* Bit in ChipCmd. */
|
||||
enum ChipCmdBits {
|
||||
ChipReset=0x100, RxReset=0x20, TxReset=0x10, RxOff=0x08, RxOn=0x04,
|
||||
TxOff=0x02, TxOn=0x01,
|
||||
};
|
||||
|
||||
/* Bits in the interrupt status/mask registers. */
|
||||
enum intr_status_bits {
|
||||
IntrRxDone=0x0001, IntrRxIntr=0x0002, IntrRxErr=0x0004, IntrRxEarly=0x0008,
|
||||
IntrRxIdle=0x0010, IntrRxOverrun=0x0020,
|
||||
IntrTxDone=0x0040, IntrTxIntr=0x0080, IntrTxErr=0x0100,
|
||||
IntrTxIdle=0x0200, IntrTxUnderrun=0x0400,
|
||||
StatsMax=0x0800, LinkChange=0x4000, WOLPkt=0x2000,
|
||||
RxResetDone=0x1000000, TxResetDone=0x2000000,
|
||||
IntrPCIErr=0x00f00000, IntrNormalSummary=0x0251, IntrAbnormalSummary=0xED20,
|
||||
};
|
||||
|
||||
/* Bits in the RxMode register. */
|
||||
enum rx_mode_bits {
|
||||
AcceptErr=0x20, AcceptRunt=0x10, AcceptBroadcast=0xC0000000,
|
||||
AcceptMulticast=0x00200000, AcceptAllMulticast=0x20000000,
|
||||
AcceptAllPhys=0x10000000, AcceptMyPhys=0x08000000,
|
||||
};
|
||||
|
||||
/* Bits in network_desc.status */
|
||||
enum desc_status_bits {
|
||||
DescOwn=0x80000000, DescMore=0x40000000, DescIntr=0x20000000,
|
||||
DescNoCRC=0x10000000,
|
||||
DescPktOK=0x08000000, RxTooLong=0x00400000,
|
||||
};
|
||||
|
||||
/* The Rx and Tx buffer descriptors. */
|
||||
struct netdev_desc {
|
||||
u32 next_desc;
|
||||
s32 cmd_status;
|
||||
u32 addr;
|
||||
};
|
||||
|
||||
static struct FA311_DEV {
|
||||
unsigned int ioaddr;
|
||||
unsigned short vendor;
|
||||
unsigned short device;
|
||||
unsigned int cur_rx;
|
||||
unsigned int cur_tx;
|
||||
unsigned int rx_buf_sz;
|
||||
volatile struct netdev_desc *rx_head_desc;
|
||||
volatile struct netdev_desc rx_ring[RX_RING_SIZE] __attribute__ ((aligned (4)));
|
||||
volatile struct netdev_desc tx_ring[TX_RING_SIZE] __attribute__ ((aligned (4)));
|
||||
} fa311_dev;
|
||||
|
||||
static int eeprom_read(long ioaddr, int location);
|
||||
static void init_ring(struct FA311_DEV *dev);
|
||||
static void fa311_reset(struct nic *nic);
|
||||
static int fa311_poll(struct nic *nic);
|
||||
static void fa311_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p);
|
||||
static void fa311_disable(struct nic *nic);
|
||||
|
||||
static char rx_packet[PKT_BUF_SZ * RX_RING_SIZE] __attribute__ ((aligned (4)));
|
||||
static char tx_packet[PKT_BUF_SZ * TX_RING_SIZE] __attribute__ ((aligned (4)));
|
||||
|
||||
struct nic * fa311_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci)
|
||||
{
|
||||
int prev_eedata;
|
||||
int i;
|
||||
int duplex;
|
||||
int tx_config;
|
||||
int rx_config;
|
||||
unsigned char macaddr[6];
|
||||
unsigned char mactest;
|
||||
unsigned char pci_bus = 0;
|
||||
struct FA311_DEV* dev = &fa311_dev;
|
||||
|
||||
if (io_addrs == 0 || *io_addrs == 0)
|
||||
return (0);
|
||||
memset(dev, 0, sizeof(*dev));
|
||||
dev->vendor = pci->vendor;
|
||||
dev->device = pci->dev_id;
|
||||
dev->ioaddr = pci->membase;
|
||||
|
||||
/* Work around the dropped serial bit. */
|
||||
prev_eedata = eeprom_read(dev->ioaddr, 6);
|
||||
for (i = 0; i < 3; i++) {
|
||||
int eedata = eeprom_read(dev->ioaddr, i + 7);
|
||||
macaddr[i*2] = (eedata << 1) + (prev_eedata >> 15);
|
||||
macaddr[i*2+1] = eedata >> 7;
|
||||
prev_eedata = eedata;
|
||||
}
|
||||
mactest = 0;
|
||||
for (i = 0; i < 6; i++)
|
||||
mactest |= macaddr[i];
|
||||
if (mactest == 0)
|
||||
return (0);
|
||||
for (i = 0; i < 6; i++)
|
||||
nic->node_addr[i] = macaddr[i];
|
||||
printf("%! ", nic->node_addr);
|
||||
|
||||
adjust_pci_device(pci);
|
||||
|
||||
fa311_reset(nic);
|
||||
|
||||
nic->reset = fa311_reset;
|
||||
nic->disable = fa311_disable;
|
||||
nic->poll = fa311_poll;
|
||||
nic->transmit = fa311_transmit;
|
||||
|
||||
init_ring(dev);
|
||||
|
||||
writel(virt_to_bus(dev->rx_ring), dev->ioaddr + RxRingPtr);
|
||||
writel(virt_to_bus(dev->tx_ring), dev->ioaddr + TxRingPtr);
|
||||
|
||||
for (i = 0; i < 6; i += 2)
|
||||
{
|
||||
writel(i, dev->ioaddr + RxFilterAddr);
|
||||
writew(macaddr[i] + (macaddr[i+1] << 8),
|
||||
dev->ioaddr + RxFilterData);
|
||||
}
|
||||
|
||||
/* Initialize other registers. */
|
||||
/* Configure for standard, in-spec Ethernet. */
|
||||
if (readl(dev->ioaddr + ChipConfig) & 0x20000000)
|
||||
{ /* Full duplex */
|
||||
tx_config = 0xD0801002;
|
||||
rx_config = 0x10000020;
|
||||
}
|
||||
else
|
||||
{
|
||||
tx_config = 0x10801002;
|
||||
rx_config = 0x0020;
|
||||
}
|
||||
writel(tx_config, dev->ioaddr + TxConfig);
|
||||
writel(rx_config, dev->ioaddr + RxConfig);
|
||||
|
||||
duplex = readl(dev->ioaddr + ChipConfig) & 0x20000000 ? 1 : 0;
|
||||
if (duplex) {
|
||||
rx_config |= 0x10000000;
|
||||
tx_config |= 0xC0000000;
|
||||
} else {
|
||||
rx_config &= ~0x10000000;
|
||||
tx_config &= ~0xC0000000;
|
||||
}
|
||||
writew(tx_config, dev->ioaddr + TxConfig);
|
||||
writew(rx_config, dev->ioaddr + RxConfig);
|
||||
|
||||
writel(AcceptBroadcast | AcceptAllMulticast | AcceptMyPhys,
|
||||
dev->ioaddr + RxFilterAddr);
|
||||
|
||||
writel(RxOn | TxOn, dev->ioaddr + ChipCmd);
|
||||
writel(4, dev->ioaddr + StatsCtrl); /* Clear Stats */
|
||||
return nic;
|
||||
|
||||
}
|
||||
|
||||
static void fa311_reset(struct nic *nic)
|
||||
{
|
||||
u32 chip_config;
|
||||
struct FA311_DEV* dev = &fa311_dev;
|
||||
|
||||
/* Reset the chip to erase previous misconfiguration. */
|
||||
outl(ChipReset, dev->ioaddr + ChipCmd);
|
||||
|
||||
if ((readl(dev->ioaddr + ChipConfig) & 0xe000) != 0xe000)
|
||||
{
|
||||
chip_config = readl(dev->ioaddr + ChipConfig);
|
||||
}
|
||||
}
|
||||
|
||||
static int fa311_poll(struct nic *nic)
|
||||
{
|
||||
s32 desc_status;
|
||||
int to;
|
||||
int entry;
|
||||
int retcode;
|
||||
struct FA311_DEV* dev = &fa311_dev;
|
||||
|
||||
retcode = 0;
|
||||
entry = dev->cur_rx;
|
||||
to = TIME_OUT;
|
||||
while (to != 0)
|
||||
{
|
||||
desc_status = dev->rx_ring[entry].cmd_status;
|
||||
if ((desc_status & DescOwn) != 0)
|
||||
break;
|
||||
else
|
||||
--to;
|
||||
}
|
||||
if (to != 0)
|
||||
{
|
||||
readl(dev->ioaddr + IntrStatus); /* clear interrrupt bits */
|
||||
/* driver owns the next entry it's a new packet. Send it up. */
|
||||
if ((desc_status & (DescMore|DescPktOK|RxTooLong)) == DescPktOK)
|
||||
{
|
||||
nic->packetlen = (desc_status & 0x0fff) - 4; /* Omit CRC size. */
|
||||
memcpy(nic->packet, (char*)(dev->rx_ring[entry].addr), nic->packetlen);
|
||||
retcode = 1;
|
||||
}
|
||||
/* Give the descriptor back to the chip */
|
||||
dev->rx_ring[entry].cmd_status = cpu_to_le32(dev->rx_buf_sz);
|
||||
dev->cur_rx++;
|
||||
if (dev->cur_rx >= RX_RING_SIZE)
|
||||
dev->cur_rx = 0;
|
||||
dev->rx_head_desc = &dev->rx_ring[dev->cur_rx];
|
||||
}
|
||||
/* Restart Rx engine if stopped. */
|
||||
writel(RxOn, dev->ioaddr + ChipCmd);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
static void fa311_transmit(struct nic *nic, const char *destaddr, unsigned int type, unsigned int len, const char *data)
|
||||
{
|
||||
unsigned short nstype;
|
||||
s32 desc_status;
|
||||
int to;
|
||||
int entry;
|
||||
char* txp;
|
||||
unsigned char* s;
|
||||
struct FA311_DEV* dev = &fa311_dev;
|
||||
|
||||
/* Calculate the next Tx descriptor entry. */
|
||||
entry = dev->cur_tx;
|
||||
txp = (char*)(dev->tx_ring[entry].addr);
|
||||
|
||||
memcpy(txp, destaddr, ETH_ALEN);
|
||||
memcpy(txp + ETH_ALEN, nic->node_addr, ETH_ALEN);
|
||||
nstype = htons(type);
|
||||
memcpy(txp + 12, (char*)&nstype, 2);
|
||||
memcpy(txp + ETH_HLEN, data, len);
|
||||
len += ETH_HLEN;
|
||||
/* pad frame */
|
||||
if (len < ETH_ZLEN)
|
||||
{
|
||||
s = (unsigned char*)(txp+len);
|
||||
while (s < (unsigned char*)(txp+ETH_ZLEN))
|
||||
*s++ = 0;
|
||||
len = ETH_ZLEN;
|
||||
}
|
||||
dev->tx_ring[entry].cmd_status = cpu_to_le32(DescOwn | len);
|
||||
dev->cur_tx++;
|
||||
if (dev->cur_tx >= TX_RING_SIZE)
|
||||
dev->cur_tx = 0;
|
||||
|
||||
/* Wake the potentially-idle transmit channel. */
|
||||
writel(TxOn, dev->ioaddr + ChipCmd);
|
||||
|
||||
/* wait for tranmission to complete */
|
||||
to = TIME_OUT;
|
||||
while (to != 0)
|
||||
{
|
||||
desc_status = dev->tx_ring[entry].cmd_status;
|
||||
if ((desc_status & DescOwn) == 0)
|
||||
break;
|
||||
else
|
||||
--to;
|
||||
}
|
||||
|
||||
readl(dev->ioaddr + IntrStatus); /* clear interrrupt bits */
|
||||
return;
|
||||
}
|
||||
|
||||
static void fa311_disable(struct nic *nic)
|
||||
{
|
||||
struct FA311_DEV* dev = &fa311_dev;
|
||||
|
||||
/* Stop the chip's Tx and Rx processes. */
|
||||
writel(RxOff | TxOff, dev->ioaddr + ChipCmd);
|
||||
}
|
||||
|
||||
|
||||
/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
|
||||
The EEPROM code is for the common 93c06/46 EEPROMs with 6 bit addresses. */
|
||||
|
||||
/* Delay between EEPROM clock transitions.
|
||||
No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
|
||||
a delay. Note that pre-2.0.34 kernels had a cache-alignment bug that
|
||||
made udelay() unreliable.
|
||||
The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
|
||||
depricated.
|
||||
*/
|
||||
#define eeprom_delay(ee_addr) inl(ee_addr)
|
||||
|
||||
enum EEPROM_Ctrl_Bits {
|
||||
EE_ShiftClk=0x04, EE_DataIn=0x01, EE_ChipSelect=0x08, EE_DataOut=0x02,
|
||||
};
|
||||
#define EE_Write0 (EE_ChipSelect)
|
||||
#define EE_Write1 (EE_ChipSelect | EE_DataIn)
|
||||
|
||||
/* The EEPROM commands include the alway-set leading bit. */
|
||||
enum EEPROM_Cmds {
|
||||
EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
|
||||
};
|
||||
|
||||
|
||||
static int eeprom_read(long addr, int location)
|
||||
{
|
||||
int i;
|
||||
int retval = 0;
|
||||
int ee_addr = addr + EECtrl;
|
||||
int read_cmd = location | EE_ReadCmd;
|
||||
writel(EE_Write0, ee_addr);
|
||||
|
||||
/* Shift the read command bits out. */
|
||||
for (i = 10; i >= 0; i--) {
|
||||
short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
|
||||
writel(dataval, ee_addr);
|
||||
eeprom_delay(ee_addr);
|
||||
writel(dataval | EE_ShiftClk, ee_addr);
|
||||
eeprom_delay(ee_addr);
|
||||
}
|
||||
writel(EE_ChipSelect, ee_addr);
|
||||
eeprom_delay(ee_addr);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
writel(EE_ChipSelect | EE_ShiftClk, ee_addr);
|
||||
eeprom_delay(ee_addr);
|
||||
retval |= (readl(ee_addr) & EE_DataOut) ? 1 << i : 0;
|
||||
writel(EE_ChipSelect, ee_addr);
|
||||
eeprom_delay(ee_addr);
|
||||
}
|
||||
|
||||
/* Terminate the EEPROM access. */
|
||||
writel(EE_Write0, ee_addr);
|
||||
writel(0, ee_addr);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
|
||||
static void init_ring(struct FA311_DEV *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
dev->cur_rx = 0;
|
||||
dev->cur_tx = 0;
|
||||
|
||||
dev->rx_buf_sz = PKT_BUF_SZ;
|
||||
dev->rx_head_desc = &dev->rx_ring[0];
|
||||
|
||||
/* Initialize all Rx descriptors. */
|
||||
for (i = 0; i < RX_RING_SIZE; i++) {
|
||||
dev->rx_ring[i].next_desc = virt_to_le32desc(&dev->rx_ring[i+1]);
|
||||
dev->rx_ring[i].cmd_status = DescOwn;
|
||||
}
|
||||
/* Mark the last entry as wrapping the ring. */
|
||||
dev->rx_ring[i-1].next_desc = virt_to_le32desc(&dev->rx_ring[0]);
|
||||
|
||||
/* Fill in the Rx buffers. Handle allocation failure gracefully. */
|
||||
for (i = 0; i < RX_RING_SIZE; i++) {
|
||||
dev->rx_ring[i].addr = (u32)(&rx_packet[PKT_BUF_SZ * i]);
|
||||
dev->rx_ring[i].cmd_status = cpu_to_le32(dev->rx_buf_sz);
|
||||
}
|
||||
|
||||
for (i = 0; i < TX_RING_SIZE; i++) {
|
||||
dev->tx_ring[i].next_desc = virt_to_le32desc(&dev->tx_ring[i+1]);
|
||||
dev->tx_ring[i].cmd_status = 0;
|
||||
}
|
||||
dev->tx_ring[i-1].next_desc = virt_to_le32desc(&dev->tx_ring[0]);
|
||||
|
||||
for (i = 0; i < TX_RING_SIZE; i++)
|
||||
dev->tx_ring[i].addr = (u32)(&tx_packet[PKT_BUF_SZ * i]);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,497 +0,0 @@
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2000,2001,2002,2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* 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
|
||||
* (at your option) 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.
|
||||
*/
|
||||
|
||||
/* Based on "src/main.c" in etherboot-4.5.8. */
|
||||
/**************************************************************************
|
||||
ETHERBOOT - BOOTP/TFTP Bootstrap Program
|
||||
|
||||
Author: Martin Renters
|
||||
Date: Dec/93
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/* #define TFTP_DEBUG 1 */
|
||||
|
||||
#include <filesys.h>
|
||||
|
||||
#define GRUB 1
|
||||
#include <etherboot.h>
|
||||
#include <nic.h>
|
||||
|
||||
static int retry;
|
||||
static unsigned short iport = 2000;
|
||||
static unsigned short oport;
|
||||
static unsigned short block, prevblock;
|
||||
static int bcounter;
|
||||
static struct tftp_t tp, saved_tp;
|
||||
static int packetsize;
|
||||
static int buf_eof, buf_read;
|
||||
static int saved_filepos;
|
||||
static unsigned short len, saved_len;
|
||||
static char *buf;
|
||||
|
||||
/* Fill the buffer by receiving the data via the TFTP protocol. */
|
||||
static int
|
||||
buf_fill (int abort)
|
||||
{
|
||||
#ifdef TFTP_DEBUG
|
||||
grub_printf ("buf_fill (%d)\n", abort);
|
||||
#endif
|
||||
|
||||
while (! buf_eof && (buf_read + packetsize <= FSYS_BUFLEN))
|
||||
{
|
||||
struct tftp_t *tr;
|
||||
long timeout;
|
||||
|
||||
#ifdef CONGESTED
|
||||
timeout = rfc2131_sleep_interval (block ? TFTP_REXMT : TIMEOUT, retry);
|
||||
#else
|
||||
timeout = rfc2131_sleep_interval (TIMEOUT, retry);
|
||||
#endif
|
||||
|
||||
if (! await_reply (AWAIT_TFTP, iport, NULL, timeout))
|
||||
{
|
||||
if (ip_abort)
|
||||
return 0;
|
||||
|
||||
if (! block && retry++ < MAX_TFTP_RETRIES)
|
||||
{
|
||||
/* Maybe initial request was lost. */
|
||||
#ifdef TFTP_DEBUG
|
||||
grub_printf ("Maybe initial request was lost.\n");
|
||||
#endif
|
||||
if (! udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
|
||||
++iport, TFTP_PORT, len, &tp))
|
||||
return 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef CONGESTED
|
||||
if (block && ((retry += TFTP_REXMT) < TFTP_TIMEOUT))
|
||||
{
|
||||
/* We resend our last ack. */
|
||||
# ifdef TFTP_DEBUG
|
||||
grub_printf ("<REXMT>\n");
|
||||
# endif
|
||||
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
|
||||
iport, oport,
|
||||
TFTP_MIN_PACKET, &tp);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
/* Timeout. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
tr = (struct tftp_t *) &nic.packet[ETH_HLEN];
|
||||
if (tr->opcode == ntohs (TFTP_ERROR))
|
||||
{
|
||||
grub_printf ("TFTP error %d (%s)\n",
|
||||
ntohs (tr->u.err.errcode),
|
||||
tr->u.err.errmsg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tr->opcode == ntohs (TFTP_OACK))
|
||||
{
|
||||
char *p = tr->u.oack.data, *e;
|
||||
|
||||
#ifdef TFTP_DEBUG
|
||||
grub_printf ("OACK ");
|
||||
#endif
|
||||
/* Shouldn't happen. */
|
||||
if (prevblock)
|
||||
{
|
||||
/* Ignore it. */
|
||||
grub_printf ("%s:%d: warning: PREVBLOCK != 0 (0x%x)\n",
|
||||
__FILE__, __LINE__, prevblock);
|
||||
continue;
|
||||
}
|
||||
|
||||
len = ntohs (tr->udp.len) - sizeof (struct udphdr) - 2;
|
||||
if (len > TFTP_MAX_PACKET)
|
||||
goto noak;
|
||||
|
||||
e = p + len;
|
||||
while (*p != '\000' && p < e)
|
||||
{
|
||||
if (! grub_strcmp ("blksize", p))
|
||||
{
|
||||
p += 8;
|
||||
if ((packetsize = getdec (&p)) < TFTP_DEFAULTSIZE_PACKET)
|
||||
goto noak;
|
||||
#ifdef TFTP_DEBUG
|
||||
grub_printf ("blksize = %d\n", packetsize);
|
||||
#endif
|
||||
}
|
||||
else if (! grub_strcmp ("tsize", p))
|
||||
{
|
||||
p += 6;
|
||||
if ((filemax = getdec (&p)) < 0)
|
||||
{
|
||||
filemax = -1;
|
||||
goto noak;
|
||||
}
|
||||
#ifdef TFTP_DEBUG
|
||||
grub_printf ("tsize = %d\n", filemax);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
noak:
|
||||
#ifdef TFTP_DEBUG
|
||||
grub_printf ("NOAK\n");
|
||||
#endif
|
||||
tp.opcode = htons (TFTP_ERROR);
|
||||
tp.u.err.errcode = 8;
|
||||
len = (grub_sprintf ((char *) tp.u.err.errmsg,
|
||||
"RFC1782 error")
|
||||
+ sizeof (tp.ip) + sizeof (tp.udp)
|
||||
+ sizeof (tp.opcode) + sizeof (tp.u.err.errcode)
|
||||
+ 1);
|
||||
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
|
||||
iport, ntohs (tr->udp.src),
|
||||
len, &tp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (p < e && *p)
|
||||
p++;
|
||||
|
||||
if (p < e)
|
||||
p++;
|
||||
}
|
||||
|
||||
if (p > e)
|
||||
goto noak;
|
||||
|
||||
/* This ensures that the packet does not get processed as
|
||||
data! */
|
||||
block = tp.u.ack.block = 0;
|
||||
}
|
||||
else if (tr->opcode == ntohs (TFTP_DATA))
|
||||
{
|
||||
#ifdef TFTP_DEBUG
|
||||
grub_printf ("DATA ");
|
||||
#endif
|
||||
len = ntohs (tr->udp.len) - sizeof (struct udphdr) - 4;
|
||||
|
||||
/* Shouldn't happen. */
|
||||
if (len > packetsize)
|
||||
{
|
||||
/* Ignore it. */
|
||||
grub_printf ("%s:%d: warning: LEN > PACKETSIZE (0x%x > 0x%x)\n",
|
||||
__FILE__, __LINE__, len, packetsize);
|
||||
continue;
|
||||
}
|
||||
|
||||
block = ntohs (tp.u.ack.block = tr->u.data.block);
|
||||
}
|
||||
else
|
||||
/* Neither TFTP_OACK nor TFTP_DATA. */
|
||||
break;
|
||||
|
||||
if ((block || bcounter) && (block != prevblock + (unsigned short) 1))
|
||||
/* Block order should be continuous */
|
||||
tp.u.ack.block = htons (block = prevblock);
|
||||
|
||||
/* Should be continuous. */
|
||||
tp.opcode = abort ? htons (TFTP_ERROR) : htons (TFTP_ACK);
|
||||
oport = ntohs (tr->udp.src);
|
||||
|
||||
#ifdef TFTP_DEBUG
|
||||
grub_printf ("ACK\n");
|
||||
#endif
|
||||
/* Ack. */
|
||||
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, iport,
|
||||
oport, TFTP_MIN_PACKET, &tp);
|
||||
|
||||
if (abort)
|
||||
{
|
||||
buf_eof = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Retransmission or OACK. */
|
||||
if ((unsigned short) (block - prevblock) != 1)
|
||||
/* Don't process. */
|
||||
continue;
|
||||
|
||||
prevblock = block;
|
||||
/* Is it the right place to zero the timer? */
|
||||
retry = 0;
|
||||
|
||||
/* In GRUB, this variable doesn't play any important role at all,
|
||||
but use it for consistency with Etherboot. */
|
||||
bcounter++;
|
||||
|
||||
/* Copy the downloaded data to the buffer. */
|
||||
grub_memmove (buf + buf_read, tr->u.data.download, len);
|
||||
buf_read += len;
|
||||
|
||||
/* End of data. */
|
||||
if (len < packetsize)
|
||||
buf_eof = 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Send the RRQ whose length is LEN. */
|
||||
static int
|
||||
send_rrq (void)
|
||||
{
|
||||
/* Initialize some variables. */
|
||||
retry = 0;
|
||||
block = 0;
|
||||
prevblock = 0;
|
||||
packetsize = TFTP_DEFAULTSIZE_PACKET;
|
||||
bcounter = 0;
|
||||
|
||||
buf = (char *) FSYS_BUF;
|
||||
buf_eof = 0;
|
||||
buf_read = 0;
|
||||
saved_filepos = 0;
|
||||
|
||||
/* Clear out the Rx queue first. It contains nothing of interest,
|
||||
* except possibly ARP requests from the DHCP/TFTP server. We use
|
||||
* polling throughout Etherboot, so some time may have passed since we
|
||||
* last polled the receive queue, which may now be filled with
|
||||
* broadcast packets. This will cause the reply to the packets we are
|
||||
* about to send to be lost immediately. Not very clever. */
|
||||
await_reply (AWAIT_QDRAIN, 0, NULL, 0);
|
||||
|
||||
#ifdef TFTP_DEBUG
|
||||
grub_printf ("send_rrq ()\n");
|
||||
{
|
||||
int i;
|
||||
char *p;
|
||||
|
||||
for (i = 0, p = (char *) &tp; i < len; i++)
|
||||
if (p[i] >= ' ' && p[i] <= '~')
|
||||
grub_putchar (p[i]);
|
||||
else
|
||||
grub_printf ("\\%x", (unsigned) p[i]);
|
||||
|
||||
grub_putchar ('\n');
|
||||
}
|
||||
#endif
|
||||
/* Send the packet. */
|
||||
return udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, ++iport,
|
||||
TFTP_PORT, len, &tp);
|
||||
}
|
||||
|
||||
/* Mount the network drive. If the drive is ready, return one, otherwise
|
||||
return zero. */
|
||||
int
|
||||
tftp_mount (void)
|
||||
{
|
||||
/* Check if the current drive is the network drive. */
|
||||
if (current_drive != NETWORK_DRIVE)
|
||||
return 0;
|
||||
|
||||
/* If the drive is not initialized yet, abort. */
|
||||
if (! network_ready)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Read up to SIZE bytes, returned in ADDR. */
|
||||
int
|
||||
tftp_read (char *addr, int size)
|
||||
{
|
||||
/* How many bytes is read? */
|
||||
int ret = 0;
|
||||
|
||||
#ifdef TFTP_DEBUG
|
||||
grub_printf ("tftp_read (0x%x, %d)\n", (int) addr, size);
|
||||
#endif
|
||||
|
||||
if (filepos < saved_filepos)
|
||||
{
|
||||
/* Uggh.. FILEPOS has been moved backwards. So reopen the file. */
|
||||
buf_read = 0;
|
||||
buf_fill (1);
|
||||
grub_memmove ((char *) &tp, (char *) &saved_tp, saved_len);
|
||||
len = saved_len;
|
||||
#ifdef TFTP_DEBUG
|
||||
{
|
||||
int i;
|
||||
grub_printf ("opcode = 0x%x, rrq = ", (unsigned long) tp.opcode);
|
||||
for (i = 0; i < TFTP_DEFAULTSIZE_PACKET; i++)
|
||||
{
|
||||
if (tp.u.rrq[i] >= ' ' && tp.u.rrq[i] <= '~')
|
||||
grub_putchar (tp.u.rrq[i]);
|
||||
else
|
||||
grub_putchar ('*');
|
||||
}
|
||||
grub_putchar ('\n');
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! send_rrq ())
|
||||
{
|
||||
errnum = ERR_WRITE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
while (size > 0)
|
||||
{
|
||||
int amt = buf_read + saved_filepos - filepos;
|
||||
|
||||
/* If the length that can be copied from the buffer is over the
|
||||
requested size, cut it down. */
|
||||
if (amt > size)
|
||||
amt = size;
|
||||
|
||||
if (amt > 0)
|
||||
{
|
||||
/* Copy the buffer to the supplied memory space. */
|
||||
grub_memmove (addr, buf + filepos - saved_filepos, amt);
|
||||
size -= amt;
|
||||
addr += amt;
|
||||
filepos += amt;
|
||||
ret += amt;
|
||||
|
||||
/* If the size of the empty space becomes small, move the unused
|
||||
data forwards. */
|
||||
if (filepos - saved_filepos > FSYS_BUFLEN / 2)
|
||||
{
|
||||
grub_memmove (buf, buf + FSYS_BUFLEN / 2, FSYS_BUFLEN / 2);
|
||||
buf_read -= FSYS_BUFLEN / 2;
|
||||
saved_filepos += FSYS_BUFLEN / 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Skip the whole buffer. */
|
||||
saved_filepos += buf_read;
|
||||
buf_read = 0;
|
||||
}
|
||||
|
||||
/* Read the data. */
|
||||
if (size > 0 && ! buf_fill (0))
|
||||
{
|
||||
errnum = ERR_READ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sanity check. */
|
||||
if (size > 0 && buf_read == 0)
|
||||
{
|
||||
errnum = ERR_READ;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Check if the file DIRNAME really exists. Get the size and save it in
|
||||
FILEMAX. */
|
||||
int
|
||||
tftp_dir (char *dirname)
|
||||
{
|
||||
int ch;
|
||||
|
||||
#ifdef TFTP_DEBUG
|
||||
grub_printf ("tftp_dir (%s)\n", dirname);
|
||||
#endif
|
||||
|
||||
/* In TFTP, there is no way to know what files exist. */
|
||||
if (print_possibilities)
|
||||
return 1;
|
||||
|
||||
/* Don't know the size yet. */
|
||||
filemax = -1;
|
||||
|
||||
reopen:
|
||||
/* Construct the TFTP request packet. */
|
||||
tp.opcode = htons (TFTP_RRQ);
|
||||
/* Terminate the filename. */
|
||||
ch = nul_terminate (dirname);
|
||||
/* Make the request string (octet, blksize and tsize). */
|
||||
len = (grub_sprintf ((char *) tp.u.rrq,
|
||||
"%s%coctet%cblksize%c%d%ctsize%c0",
|
||||
dirname, 0, 0, 0, TFTP_MAX_PACKET, 0, 0)
|
||||
+ sizeof (tp.ip) + sizeof (tp.udp) + sizeof (tp.opcode) + 1);
|
||||
/* Restore the original DIRNAME. */
|
||||
dirname[grub_strlen (dirname)] = ch;
|
||||
/* Save the TFTP packet so that we can reopen the file later. */
|
||||
grub_memmove ((char *) &saved_tp, (char *) &tp, len);
|
||||
saved_len = len;
|
||||
if (! send_rrq ())
|
||||
{
|
||||
errnum = ERR_WRITE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read the data. */
|
||||
if (! buf_fill (0))
|
||||
{
|
||||
errnum = ERR_FILE_NOT_FOUND;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (filemax == -1)
|
||||
{
|
||||
/* The server doesn't support the "tsize" option, so we must read
|
||||
the file twice... */
|
||||
|
||||
/* Zero the size of the file. */
|
||||
filemax = 0;
|
||||
do
|
||||
{
|
||||
/* Add the length of the downloaded data. */
|
||||
filemax += buf_read;
|
||||
/* Reset the offset. Just discard the contents of the buffer. */
|
||||
buf_read = 0;
|
||||
/* Read the data. */
|
||||
if (! buf_fill (0))
|
||||
{
|
||||
errnum = ERR_READ;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
while (! buf_eof);
|
||||
|
||||
/* Maybe a few amounts of data remains. */
|
||||
filemax += buf_read;
|
||||
|
||||
/* Retry the open instruction. */
|
||||
goto reopen;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Close the file. */
|
||||
void
|
||||
tftp_close (void)
|
||||
{
|
||||
#ifdef TFTP_DEBUG
|
||||
grub_printf ("tftp_close ()\n");
|
||||
#endif
|
||||
|
||||
buf_read = 0;
|
||||
buf_fill (1);
|
||||
}
|
||||
@@ -1,825 +0,0 @@
|
||||
/**************************************************************************
|
||||
Etherboot - BOOTP/TFTP Bootstrap Program
|
||||
i82586 NIC driver for Etherboot
|
||||
Ken Yap, January 1998
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* 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, or (at
|
||||
* your option) any later version.
|
||||
*/
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "cards.h"
|
||||
#include "timer.h"
|
||||
|
||||
#define udelay(n) waiton_timer2(((n)*TICKS_PER_MS)/1000)
|
||||
|
||||
/* Sources of information:
|
||||
|
||||
Donald Becker's excellent 3c507 driver in Linux
|
||||
Intel 82596 data sheet (yes, 82596; it has a 586 compatibility mode)
|
||||
*/
|
||||
|
||||
/* Code below mostly stolen wholesale from 3c507.c driver in Linux */
|
||||
|
||||
/*
|
||||
Details of the i82586.
|
||||
|
||||
You'll really need the databook to understand the details of this part,
|
||||
but the outline is that the i82586 has two separate processing units.
|
||||
Both are started from a list of three configuration tables, of which only
|
||||
the last, the System Control Block (SCB), is used after reset-time. The SCB
|
||||
has the following fields:
|
||||
Status word
|
||||
Command word
|
||||
Tx/Command block addr.
|
||||
Rx block addr.
|
||||
The command word accepts the following controls for the Tx and Rx units:
|
||||
*/
|
||||
|
||||
#define CUC_START 0x0100
|
||||
#define CUC_RESUME 0x0200
|
||||
#define CUC_SUSPEND 0x0300
|
||||
#define RX_START 0x0010
|
||||
#define RX_RESUME 0x0020
|
||||
#define RX_SUSPEND 0x0030
|
||||
|
||||
/* The Rx unit uses a list of frame descriptors and a list of data buffer
|
||||
descriptors. We use full-sized (1518 byte) data buffers, so there is
|
||||
a one-to-one pairing of frame descriptors to buffer descriptors.
|
||||
|
||||
The Tx ("command") unit executes a list of commands that look like:
|
||||
Status word Written by the 82586 when the command is done.
|
||||
Command word Command in lower 3 bits, post-command action in upper 3
|
||||
Link word The address of the next command.
|
||||
Parameters (as needed).
|
||||
|
||||
Some definitions related to the Command Word are:
|
||||
*/
|
||||
#define CMD_EOL 0x8000 /* The last command of the list, stop. */
|
||||
#define CMD_SUSP 0x4000 /* Suspend after doing cmd. */
|
||||
#define CMD_INTR 0x2000 /* Interrupt after doing cmd. */
|
||||
|
||||
enum commands {
|
||||
CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
|
||||
CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7};
|
||||
|
||||
/*
|
||||
Details of the EtherLink16 Implementation
|
||||
|
||||
The 3c507 and NI5210 are generic shared-memory i82586 implementations.
|
||||
3c507: The host can map 16K, 32K, 48K, or 64K of the 64K memory into
|
||||
0x0[CD][08]0000, or all 64K into 0xF[02468]0000.
|
||||
NI5210: The host can map 8k or 16k at 0x[CDE][048C]000 but we
|
||||
assume 8k because to have 16k you cannot put a ROM on the NIC.
|
||||
*/
|
||||
|
||||
/* Offsets from the base I/O address. */
|
||||
|
||||
#ifdef INCLUDE_3C507
|
||||
|
||||
#define SA_DATA 0 /* Station address data, or 3Com signature. */
|
||||
#define MISC_CTRL 6 /* Switch the SA_DATA banks, and bus config bits. */
|
||||
#define RESET_IRQ 10 /* Reset the latched IRQ line. */
|
||||
#define I82586_ATTN 11 /* Frob the 82586 Channel Attention line. */
|
||||
#define ROM_CONFIG 13
|
||||
#define MEM_CONFIG 14
|
||||
#define IRQ_CONFIG 15
|
||||
#define EL16_IO_EXTENT 16
|
||||
|
||||
/* The ID port is used at boot-time to locate the ethercard. */
|
||||
#define ID_PORT 0x100
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_NI5210
|
||||
|
||||
#define NI52_RESET 0 /* writing to this address, resets the i82586 */
|
||||
#define I82586_ATTN 1 /* channel attention, kick the 586 */
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_EXOS205
|
||||
|
||||
#define EXOS205_RESET 0 /* writing to this address, resets the i82586 */
|
||||
#define I82586_ATTN 1 /* channel attention, kick the 586 */
|
||||
|
||||
#endif
|
||||
|
||||
/* Offsets to registers in the mailbox (SCB). */
|
||||
#define iSCB_STATUS 0x8
|
||||
#define iSCB_CMD 0xA
|
||||
#define iSCB_CBL 0xC /* Command BLock offset. */
|
||||
#define iSCB_RFA 0xE /* Rx Frame Area offset. */
|
||||
|
||||
/* Since the 3c507 maps the shared memory window so that the last byte is
|
||||
at 82586 address FFFF, the first byte is at 82586 address 0, 16K, 32K, or
|
||||
48K corresponding to window sizes of 64K, 48K, 32K and 16K respectively.
|
||||
We can account for this be setting the 'SBC Base' entry in the ISCP table
|
||||
below for all the 16 bit offset addresses, and also adding the 'SCB Base'
|
||||
value to all 24 bit physical addresses (in the SCP table and the TX and RX
|
||||
Buffer Descriptors).
|
||||
-Mark
|
||||
*/
|
||||
|
||||
/*
|
||||
What follows in 'init_words[]' is the "program" that is downloaded to the
|
||||
82586 memory. It's mostly tables and command blocks, and starts at the
|
||||
reset address 0xfffff6. This is designed to be similar to the EtherExpress,
|
||||
thus the unusual location of the SCB at 0x0008.
|
||||
|
||||
Even with the additional "don't care" values, doing it this way takes less
|
||||
program space than initializing the individual tables, and I feel it's much
|
||||
cleaner.
|
||||
|
||||
The databook is particularly useless for the first two structures, I had
|
||||
to use the Crynwr driver as an example.
|
||||
|
||||
The memory setup is as follows:
|
||||
*/
|
||||
|
||||
#define CONFIG_CMD 0x18
|
||||
#define SET_SA_CMD 0x24
|
||||
#define SA_OFFSET 0x2A
|
||||
#define IDLELOOP 0x30
|
||||
#define TDR_CMD 0x38
|
||||
#define TDR_TIME 0x3C
|
||||
#define DUMP_CMD 0x40
|
||||
#define DIAG_CMD 0x48
|
||||
#define SET_MC_CMD 0x4E
|
||||
#define DUMP_DATA 0x56 /* A 170 byte buffer for dump and Set-MC into. */
|
||||
|
||||
#define TX_BUF_START 0x0100
|
||||
#define TX_BUF_SIZE (1518+14+20+16) /* packet+header+TBD */
|
||||
|
||||
#define RX_BUF_START 0x1000
|
||||
#define RX_BUF_SIZE (1518+14+18) /* packet+header+RBD */
|
||||
#define RX_BUF_END (mem_end - mem_start - 20)
|
||||
|
||||
/*
|
||||
That's it: only 86 bytes to set up the beast, including every extra
|
||||
command available. The 170 byte buffer at DUMP_DATA is shared between the
|
||||
Dump command (called only by the diagnostic program) and the SetMulticastList
|
||||
command.
|
||||
|
||||
To complete the memory setup you only have to write the station address at
|
||||
SA_OFFSET and create the Tx & Rx buffer lists.
|
||||
|
||||
The Tx command chain and buffer list is setup as follows:
|
||||
A Tx command table, with the data buffer pointing to...
|
||||
A Tx data buffer descriptor. The packet is in a single buffer, rather than
|
||||
chaining together several smaller buffers.
|
||||
A NoOp command, which initially points to itself,
|
||||
And the packet data.
|
||||
|
||||
A transmit is done by filling in the Tx command table and data buffer,
|
||||
re-writing the NoOp command, and finally changing the offset of the last
|
||||
command to point to the current Tx command. When the Tx command is finished,
|
||||
it jumps to the NoOp, when it loops until the next Tx command changes the
|
||||
"link offset" in the NoOp. This way the 82586 never has to go through the
|
||||
slow restart sequence.
|
||||
|
||||
The Rx buffer list is set up in the obvious ring structure. We have enough
|
||||
memory (and low enough interrupt latency) that we can avoid the complicated
|
||||
Rx buffer linked lists by alway associating a full-size Rx data buffer with
|
||||
each Rx data frame.
|
||||
|
||||
I currently use one transmit buffer starting at TX_BUF_START (0x0100), and
|
||||
use the rest of memory, from RX_BUF_START to RX_BUF_END, for Rx buffers.
|
||||
|
||||
*/
|
||||
|
||||
static unsigned short init_words[] = {
|
||||
/* System Configuration Pointer (SCP). */
|
||||
#if defined(INCLUDE_3C507)
|
||||
0x0000, /* Set bus size to 16 bits. */
|
||||
#else
|
||||
0x0001, /* Set bus size to 8 bits */
|
||||
#endif
|
||||
0,0, /* pad words. */
|
||||
0x0000,0x0000, /* ISCP phys addr, set in init_82586_mem(). */
|
||||
|
||||
/* Intermediate System Configuration Pointer (ISCP). */
|
||||
0x0001, /* Status word that's cleared when init is done. */
|
||||
0x0008,0,0, /* SCB offset, (skip, skip) */
|
||||
|
||||
/* System Control Block (SCB). */
|
||||
0,0xf000|RX_START|CUC_START, /* SCB status and cmd. */
|
||||
CONFIG_CMD, /* Command list pointer, points to Configure. */
|
||||
RX_BUF_START, /* Rx block list. */
|
||||
0,0,0,0, /* Error count: CRC, align, buffer, overrun. */
|
||||
|
||||
/* 0x0018: Configure command. Change to put MAC data with packet. */
|
||||
0, CmdConfigure, /* Status, command. */
|
||||
SET_SA_CMD, /* Next command is Set Station Addr. */
|
||||
0x0804, /* "4" bytes of config data, 8 byte FIFO. */
|
||||
0x2e40, /* Magic values, including MAC data location. */
|
||||
0, /* Unused pad word. */
|
||||
|
||||
/* 0x0024: Setup station address command. */
|
||||
0, CmdSASetup,
|
||||
SET_MC_CMD, /* Next command. */
|
||||
0xaa00,0xb000,0x0bad, /* Station address (to be filled in) */
|
||||
|
||||
/* 0x0030: NOP, looping back to itself. Point to first Tx buffer to Tx. */
|
||||
0, CmdNOp, IDLELOOP, 0 /* pad */,
|
||||
|
||||
/* 0x0038: A unused Time-Domain Reflectometer command. */
|
||||
0, CmdTDR, IDLELOOP, 0,
|
||||
|
||||
/* 0x0040: An unused Dump State command. */
|
||||
0, CmdDump, IDLELOOP, DUMP_DATA,
|
||||
|
||||
/* 0x0048: An unused Diagnose command. */
|
||||
0, CmdDiagnose, IDLELOOP,
|
||||
|
||||
/* 0x004E: An empty set-multicast-list command. */
|
||||
0, CmdMulticastList, IDLELOOP, 0,
|
||||
};
|
||||
|
||||
/* NIC specific static variables go here */
|
||||
|
||||
static unsigned short ioaddr, irq, scb_base;
|
||||
static Address mem_start, mem_end;
|
||||
static unsigned short rx_head, rx_tail;
|
||||
|
||||
#define read_mem(m,s) fmemcpy((char *)s, m, sizeof(s))
|
||||
|
||||
static void setup_rx_buffers(struct nic *nic)
|
||||
{
|
||||
Address write_ptr;
|
||||
unsigned short cur_rx_buf;
|
||||
static unsigned short rx_cmd[16] = {
|
||||
0x0000, /* Rx status */
|
||||
0x0000, /* Rx command, only and last */
|
||||
RX_BUF_START, /* Link (will be adjusted) */
|
||||
RX_BUF_START + 22, /* Buffer offset (will be adjusted) */
|
||||
0x0000, 0x0000, 0x0000, /* Pad for dest addr */
|
||||
0x0000, 0x0000, 0x0000, /* Pad for source addr */
|
||||
0x0000, /* Pad for protocol */
|
||||
0x0000, /* Buffer: Actual count */
|
||||
-1, /* Buffer: Next (none) */
|
||||
RX_BUF_START + 0x20, /* Buffer: Address low (+ scb_base) (will be adjusted) */
|
||||
0x0000, /* Buffer: Address high */
|
||||
0x8000 | (RX_BUF_SIZE - 0x20)
|
||||
};
|
||||
|
||||
cur_rx_buf = rx_head = RX_BUF_START;
|
||||
do { /* While there is room for one more buffer */
|
||||
write_ptr = mem_start + cur_rx_buf;
|
||||
/* adjust some contents */
|
||||
rx_cmd[1] = 0x0000;
|
||||
rx_cmd[2] = cur_rx_buf + RX_BUF_SIZE;
|
||||
rx_cmd[3] = cur_rx_buf + 22;
|
||||
rx_cmd[13] = cur_rx_buf + 0x20 + scb_base;
|
||||
memcpy((char *)write_ptr, (char *)rx_cmd, sizeof(rx_cmd));
|
||||
rx_tail = cur_rx_buf;
|
||||
cur_rx_buf += RX_BUF_SIZE;
|
||||
} while (cur_rx_buf <= RX_BUF_END - RX_BUF_SIZE);
|
||||
/* Terminate the list by setting the EOL bit and wrap ther pointer
|
||||
to make the list a ring. */
|
||||
write_ptr = mem_start + rx_tail;
|
||||
rx_cmd[1] = 0xC000;
|
||||
rx_cmd[2] = rx_head;
|
||||
memcpy((char *)write_ptr, (char *)rx_cmd, sizeof(unsigned short) * 3);
|
||||
}
|
||||
|
||||
static void ack_status(void)
|
||||
{
|
||||
unsigned short cmd, status;
|
||||
unsigned short *shmem = (short *)mem_start;
|
||||
|
||||
cmd = (status = shmem[iSCB_STATUS>>1]) & 0xf000;
|
||||
if (status & 0x100) /* CU suspended? */
|
||||
cmd |= CUC_RESUME;
|
||||
if ((status & 0x200) == 0) /* CU not active? */
|
||||
cmd |= CUC_START;
|
||||
if (status & 0x010) /* RU suspended? */
|
||||
cmd |= RX_RESUME;
|
||||
else if ((status & 0x040) == 0) /* RU not active? */
|
||||
cmd |= RX_START;
|
||||
if (cmd == 0) /* Nothing to do */
|
||||
return;
|
||||
shmem[iSCB_CMD>>1] = cmd;
|
||||
#if defined(DEBUG)
|
||||
printf("Status %hX Command %hX\n", status, cmd);
|
||||
#endif
|
||||
outb(0, ioaddr + I82586_ATTN);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
RESET - Reset adapter
|
||||
***************************************************************************/
|
||||
|
||||
static void i82586_reset(struct nic *nic)
|
||||
{
|
||||
unsigned long time;
|
||||
unsigned short *shmem = (short *)mem_start;
|
||||
|
||||
/* put the card in its initial state */
|
||||
|
||||
#ifdef INCLUDE_3C507
|
||||
/* Enable loopback to protect the wire while starting up,
|
||||
and hold the 586 in reset during the memory initialisation. */
|
||||
outb(0x20, ioaddr + MISC_CTRL);
|
||||
#endif
|
||||
|
||||
/* Fix the ISCP address and base. */
|
||||
init_words[3] = scb_base;
|
||||
init_words[7] = scb_base;
|
||||
|
||||
/* Write the words at 0xfff6. */
|
||||
/* Write the words at 0x0000. */
|
||||
/* Fill in the station address. */
|
||||
memcpy((char *)(mem_end - 10), (char *)init_words, 10);
|
||||
memcpy((char *)mem_start, (char *)&init_words[5], sizeof(init_words) - 10);
|
||||
memcpy((char *)mem_start + SA_OFFSET, nic->node_addr, ETH_ALEN);
|
||||
setup_rx_buffers(nic);
|
||||
|
||||
#ifdef INCLUDE_3C507
|
||||
/* Start the 586 by releasing the reset line, but leave loopback. */
|
||||
outb(0xA0, ioaddr + MISC_CTRL);
|
||||
#endif
|
||||
|
||||
/* This was time consuming to track down; you need to give two channel
|
||||
attention signals to reliably start up the i82586. */
|
||||
outb(0, ioaddr + I82586_ATTN);
|
||||
time = currticks() + TICKS_PER_SEC; /* allow 1 second to init */
|
||||
while (
|
||||
shmem[iSCB_STATUS>>1] == 0)
|
||||
{
|
||||
if (currticks() > time)
|
||||
{
|
||||
printf("i82586 initialisation timed out with status %hX, cmd %hX\n",
|
||||
shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Issue channel-attn -- the 82586 won't start. */
|
||||
outb(0, ioaddr + I82586_ATTN);
|
||||
|
||||
#ifdef INCLUDE_3C507
|
||||
/* Disable loopback. */
|
||||
outb(0x80, ioaddr + MISC_CTRL);
|
||||
#endif
|
||||
#if defined(DEBUG)
|
||||
printf("i82586 status %hX, cmd %hX\n",
|
||||
shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
POLL - Wait for a frame
|
||||
***************************************************************************/
|
||||
static int i82586_poll(struct nic *nic)
|
||||
{
|
||||
int status;
|
||||
unsigned short rfd_cmd, next_rx_frame, data_buffer_addr,
|
||||
frame_status, pkt_len;
|
||||
unsigned short *shmem = (short *)mem_start + rx_head;
|
||||
|
||||
/* return true if there's an ethernet packet ready to read */
|
||||
if (
|
||||
((frame_status = shmem[0]) & 0x8000) == 0)
|
||||
return (0); /* nope */
|
||||
rfd_cmd = shmem[1];
|
||||
next_rx_frame = shmem[2];
|
||||
data_buffer_addr = shmem[3];
|
||||
pkt_len = shmem[11];
|
||||
status = 0;
|
||||
if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
|
||||
|| (pkt_len & 0xC000) != 0xC000)
|
||||
printf("\nRx frame corrupt, discarded");
|
||||
else if ((frame_status & 0x2000) == 0)
|
||||
printf("\nRx frame had error");
|
||||
else
|
||||
{
|
||||
/* We have a frame, copy it to our buffer */
|
||||
pkt_len &= 0x3FFF;
|
||||
memcpy(nic->packet, (char *)mem_start + rx_head + 0x20, pkt_len);
|
||||
/* Only packets not from ourself */
|
||||
if (memcmp(nic->packet + ETH_ALEN, nic->node_addr, ETH_ALEN) != 0)
|
||||
{
|
||||
nic->packetlen = pkt_len;
|
||||
status = 1;
|
||||
}
|
||||
}
|
||||
/* Clear the status word and set EOL on Rx frame */
|
||||
shmem[0] = 0;
|
||||
shmem[1] = 0xC000;
|
||||
*(short *)(mem_start + rx_tail + 2) = 0;
|
||||
rx_tail = rx_head;
|
||||
rx_head = next_rx_frame;
|
||||
ack_status();
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
TRANSMIT - Transmit a frame
|
||||
***************************************************************************/
|
||||
static void i82586_transmit(
|
||||
struct nic *nic,
|
||||
const char *d, /* Destination */
|
||||
unsigned int t, /* Type */
|
||||
unsigned int s, /* size */
|
||||
const char *p) /* Packet */
|
||||
{
|
||||
Address bptr;
|
||||
unsigned short type, z;
|
||||
static unsigned short tx_cmd[11] = {
|
||||
0x0, /* Tx status */
|
||||
CmdTx, /* Tx command */
|
||||
TX_BUF_START+16, /* Next command is a NoOp */
|
||||
TX_BUF_START+8, /* Data Buffer offset */
|
||||
0x8000, /* | with size */
|
||||
0xffff, /* No next data buffer */
|
||||
TX_BUF_START+22, /* + scb_base */
|
||||
0x0, /* Buffer address high bits (always zero) */
|
||||
0x0, /* Nop status */
|
||||
CmdNOp, /* Nop command */
|
||||
TX_BUF_START+16 /* Next is myself */
|
||||
};
|
||||
unsigned short *shmem = (short *)mem_start + TX_BUF_START;
|
||||
|
||||
/* send the packet to destination */
|
||||
/* adjust some contents */
|
||||
type = htons(t);
|
||||
if (s < ETH_ZLEN)
|
||||
s = ETH_ZLEN;
|
||||
tx_cmd[4] = (s + ETH_HLEN) | 0x8000;
|
||||
tx_cmd[6] = TX_BUF_START + 22 + scb_base;
|
||||
bptr = mem_start + TX_BUF_START;
|
||||
memcpy((char *)bptr, (char *)tx_cmd, sizeof(tx_cmd));
|
||||
bptr += sizeof(tx_cmd);
|
||||
memcpy((char *)bptr, d, ETH_ALEN);
|
||||
bptr += ETH_ALEN;
|
||||
memcpy((char *)bptr, nic->node_addr, ETH_ALEN);
|
||||
bptr += ETH_ALEN;
|
||||
memcpy((char *)bptr, (char *)&type, sizeof(type));
|
||||
bptr += sizeof(type);
|
||||
memcpy((char *)bptr, p, s);
|
||||
/* Change the offset in the IDLELOOP */
|
||||
*(unsigned short *)(mem_start + IDLELOOP + 4) = TX_BUF_START;
|
||||
/* Wait for transmit completion */
|
||||
while (
|
||||
(shmem[0] & 0x2000) == 0)
|
||||
;
|
||||
/* Change the offset in the IDLELOOP back and
|
||||
change the final loop to point here */
|
||||
*(unsigned short *)(mem_start + IDLELOOP + 4) = IDLELOOP;
|
||||
*(unsigned short *)(mem_start + TX_BUF_START + 20) = IDLELOOP;
|
||||
ack_status();
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
DISABLE - Turn off ethernet interface
|
||||
***************************************************************************/
|
||||
static void i82586_disable(struct nic *nic)
|
||||
{
|
||||
unsigned short *shmem = (short *)mem_start;
|
||||
|
||||
#if 0
|
||||
/* Flush the Tx and disable Rx. */
|
||||
shmem[iSCB_CMD>>1] = RX_SUSPEND | CUC_SUSPEND;
|
||||
outb(0, ioaddr + I82586_ATTN);
|
||||
#ifdef INCLUDE_NI5210
|
||||
outb(0, ioaddr + NI52_RESET);
|
||||
#endif
|
||||
#endif /* 0 */
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_3C507
|
||||
|
||||
static int t507_probe1(struct nic *nic, unsigned short ioaddr)
|
||||
{
|
||||
int i;
|
||||
Address size;
|
||||
char mem_config;
|
||||
char if_port;
|
||||
|
||||
if (inb(ioaddr) != '*' || inb(ioaddr+1) != '3'
|
||||
|| inb(ioaddr+2) != 'C' || inb(ioaddr+3) != 'O')
|
||||
return (0);
|
||||
irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
|
||||
mem_config = inb(ioaddr + MEM_CONFIG);
|
||||
if (mem_config & 0x20)
|
||||
{
|
||||
size = 65536L;
|
||||
mem_start = 0xf00000L + (mem_config & 0x08 ? 0x080000L
|
||||
: (((Address)mem_config & 0x3) << 17));
|
||||
}
|
||||
else
|
||||
{
|
||||
size = ((((Address)mem_config & 0x3) + 1) << 14);
|
||||
mem_start = 0x0c0000L + (((Address)mem_config & 0x18) << 12);
|
||||
}
|
||||
mem_end = mem_start + size;
|
||||
scb_base = 65536L - size;
|
||||
if_port = inb(ioaddr + ROM_CONFIG) & 0x80;
|
||||
/* Get station address */
|
||||
outb(0x01, ioaddr + MISC_CTRL);
|
||||
for (i = 0; i < ETH_ALEN; ++i)
|
||||
{
|
||||
nic->node_addr[i] = inb(ioaddr+i);
|
||||
}
|
||||
printf("\n3c507 ioaddr %#hX, IRQ %d, mem [%#X-%#X], %sternal xcvr, addr %!\n",
|
||||
ioaddr, irq, mem_start, mem_end, if_port ? "in" : "ex", nic->node_addr);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
PROBE - Look for an adapter, this routine's visible to the outside
|
||||
***************************************************************************/
|
||||
|
||||
struct nic *t507_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||
{
|
||||
static unsigned char init_ID_done = 0;
|
||||
unsigned short lrs_state = 0xff;
|
||||
static unsigned short io_addrs[] = { 0x300, 0x320, 0x340, 0x280, 0 };
|
||||
unsigned short *p;
|
||||
int i;
|
||||
|
||||
if (init_ID_done == 0)
|
||||
{
|
||||
/* Send the ID sequence to the ID_PORT to enable the board */
|
||||
outb(0x00, ID_PORT);
|
||||
for (i = 0; i < 255; ++i)
|
||||
{
|
||||
outb(lrs_state, ID_PORT);
|
||||
lrs_state <<= 1;
|
||||
if (lrs_state & 0x100)
|
||||
lrs_state ^= 0xe7;
|
||||
}
|
||||
outb(0x00, ID_PORT);
|
||||
init_ID_done = 1;
|
||||
}
|
||||
/* if probe_addrs is 0, then routine can use a hardwired default */
|
||||
if (probe_addrs == 0)
|
||||
probe_addrs = io_addrs;
|
||||
for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
|
||||
if (t507_probe1(nic, ioaddr))
|
||||
break;
|
||||
if (ioaddr != 0)
|
||||
{
|
||||
/* point to NIC specific routines */
|
||||
i82586_reset(nic);
|
||||
nic->reset = i82586_reset;
|
||||
nic->poll = i82586_poll;
|
||||
nic->transmit = i82586_transmit;
|
||||
nic->disable = i82586_disable;
|
||||
return nic;
|
||||
}
|
||||
/* else */
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_NI5210
|
||||
|
||||
static int ni5210_probe2(void)
|
||||
{
|
||||
unsigned short i;
|
||||
unsigned short shmem[10];
|
||||
|
||||
/* Fix the ISCP address and base. */
|
||||
init_words[3] = scb_base;
|
||||
init_words[7] = scb_base;
|
||||
|
||||
/* Write the words at 0xfff6. */
|
||||
/* Write the words at 0x0000. */
|
||||
memcpy((char *)(mem_end - 10), (char *)init_words, 10);
|
||||
memcpy((char *)mem_start, (char *)&init_words[5], sizeof(init_words) - 10);
|
||||
if (*(unsigned short *)mem_start != 1)
|
||||
return (0);
|
||||
outb(0, ioaddr + NI52_RESET);
|
||||
outb(0, ioaddr + I82586_ATTN);
|
||||
udelay(32);
|
||||
i = 50;
|
||||
while (
|
||||
shmem[iSCB_STATUS>>1] == 0)
|
||||
{
|
||||
if (--i == 0)
|
||||
{
|
||||
printf("i82586 initialisation timed out with status %hX, cmd %hX\n",
|
||||
shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Issue channel-attn -- the 82586 won't start. */
|
||||
outb(0, ioaddr + I82586_ATTN);
|
||||
if (*(unsigned short *)mem_start != 0)
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int ni5210_probe1(struct nic *nic)
|
||||
{
|
||||
int i;
|
||||
static Address mem_addrs[] = {
|
||||
0xc0000, 0xc4000, 0xc8000, 0xcc000,
|
||||
0xd0000, 0xd4000, 0xd8000, 0xdc000,
|
||||
0xe0000, 0xe4000, 0xe8000, 0xec000,
|
||||
0 };
|
||||
Address *p;
|
||||
|
||||
if (inb(ioaddr + 6) != 0x0 || inb(ioaddr + 7) != 0x55)
|
||||
return (0);
|
||||
scb_base = -8192; /* assume 8k memory */
|
||||
for (p = mem_addrs; (mem_start = *p) != 0; ++p)
|
||||
if (mem_end = mem_start + 8192, ni5210_probe2())
|
||||
break;
|
||||
if (mem_start == 0)
|
||||
return (0);
|
||||
/* Get station address */
|
||||
for (i = 0; i < ETH_ALEN; ++i)
|
||||
{
|
||||
nic->node_addr[i] = inb(ioaddr+i);
|
||||
}
|
||||
printf("\nNI5210 ioaddr %#hX, mem [%#X-%#X], addr %!\n",
|
||||
ioaddr, mem_start, mem_end, nic->node_addr);
|
||||
return (1);
|
||||
}
|
||||
|
||||
struct nic *ni5210_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||
{
|
||||
/* missing entries are addresses usually already used */
|
||||
static unsigned short io_addrs[] = {
|
||||
0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230, 0x238,
|
||||
0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, /*Par*/
|
||||
0x280, 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8,
|
||||
0x2C0, 0x2C8, 0x2D0, 0x2D8, 0x2E0, 0x2E8, 0x2F0, /*Ser*/
|
||||
0x300, 0x308, 0x310, 0x318, 0x320, 0x328, 0x330, 0x338,
|
||||
0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370, /*Par*/
|
||||
0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, /*Vid,Par*/
|
||||
0x3C0, 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, /*Ser*/
|
||||
0x0
|
||||
};
|
||||
unsigned short *p;
|
||||
int i;
|
||||
|
||||
/* if probe_addrs is 0, then routine can use a hardwired default */
|
||||
if (probe_addrs == 0)
|
||||
probe_addrs = io_addrs;
|
||||
for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
|
||||
if (ni5210_probe1(nic))
|
||||
break;
|
||||
if (ioaddr != 0)
|
||||
{
|
||||
/* point to NIC specific routines */
|
||||
i82586_reset(nic);
|
||||
nic->reset = i82586_reset;
|
||||
nic->poll = i82586_poll;
|
||||
nic->transmit = i82586_transmit;
|
||||
nic->disable = i82586_disable;
|
||||
return nic;
|
||||
}
|
||||
/* else */
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_EXOS205
|
||||
|
||||
/*
|
||||
* Code to download to I186 in EXOS205
|
||||
*/
|
||||
|
||||
static unsigned char exos_i186_init[] =
|
||||
{
|
||||
0x08,0x00,0x14,0x00,0x00,0x00,0xaa,0xfa,0x33,0xc0,0xba,0xfe,0xff,0xef,0xb8,0xf8,
|
||||
0xff,0xe7,0xa0,0xb8,0x7c,0x00,0xe7,0xa4,0xb8,0xbc,0x80,0xe7,0xa8,0x8c,0xc8,0x8e,
|
||||
0xd8,0xbb,0x2f,0x0e,0xc6,0x07,0xa5,0x33,0xc9,0xeb,0x00,0xeb,0x00,0xeb,0x00,0xe2,
|
||||
0xf8,0xbe,0x2c,0x0e,0xba,0x02,0x05,0x33,0xdb,0xb9,0x03,0x00,0xec,0x24,0x0f,0x8a,
|
||||
0xe0,0x02,0xd8,0x42,0x42,0xec,0x02,0xd8,0xd0,0xe0,0xd0,0xe0,0xd0,0xe0,0xd0,0xe0,
|
||||
0x0a,0xc4,0x88,0x04,0x42,0x42,0x46,0xe2,0xe3,0x8a,0xe3,0xd0,0xec,0xd0,0xec,0xd0,
|
||||
0xec,0xd0,0xec,0x80,0xe3,0x0f,0x02,0xe3,0x80,0xf4,0x05,0xec,0x3a,0xe0,0x74,0x05,
|
||||
0xc6,0x04,0x5a,0xeb,0xfe,0xc6,0x04,0x55,0x33,0xc0,0x8e,0xd8,0xbe,0x38,0x00,0xc7,
|
||||
0x04,0xce,0x0e,0x46,0x46,0xc7,0x04,0x00,0xff,0xfb,0xba,0x3c,0x00,0xb8,0x03,0x00,
|
||||
0xef,0x33,0xdb,0x33,0xc9,0xbd,0x04,0x0f,0x90,0x90,0x90,0x90,0xe2,0xfa,0x43,0x2e,
|
||||
0x89,0x5e,0x00,0xeb,0xf3,0x52,0xba,0x00,0x06,0xef,0x50,0x53,0x55,0xbd,0xf8,0x0e,
|
||||
0x2e,0x8b,0x5e,0x00,0x43,0x2e,0x89,0x5e,0x00,0xba,0x22,0x00,0xb8,0x00,0x80,0xef,
|
||||
0x5d,0x5b,0x58,0x5a,0xcf,0x49,0x4e,0x54,0x52,0x20,0x63,0x6e,0x74,0x2d,0x3e,0x00,
|
||||
0x00,0x4c,0x4f,0x4f,0x50,0x20,0x63,0x6e,0x74,0x2d,0x3e,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xea,0x30,0x0e,0x00,0xff,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,00
|
||||
};
|
||||
|
||||
/* These offsets are from the end of the i186 download code */
|
||||
|
||||
#define OFFSET_SEMA 0x1D1
|
||||
#define OFFSET_ADDR 0x1D7
|
||||
|
||||
static int exos205_probe2(void)
|
||||
{
|
||||
unsigned short i;
|
||||
unsigned short shmem[10];
|
||||
|
||||
/* Fix the ISCP address and base. */
|
||||
init_words[3] = scb_base;
|
||||
init_words[7] = scb_base;
|
||||
|
||||
/* Write the words at 0xfff6. */
|
||||
/* Write the words at 0x0000. */
|
||||
memcpy((char *)(mem_end - 10), (char *)init_words, 10);
|
||||
memcpy((char *)mem_start, (char *)&init_words[5], sizeof(init_words) - 10);
|
||||
if (*(unsigned short *)mem_start != 1)
|
||||
return (0);
|
||||
outb(0, ioaddr + EXOS205_RESET);
|
||||
outb(0, ioaddr + I82586_ATTN);
|
||||
i = 50;
|
||||
while (
|
||||
shmem[iSCB_STATUS>>1] == 0)
|
||||
{
|
||||
if (--i == 0)
|
||||
{
|
||||
printf("i82586 initialisation timed out with status %hX, cmd %hX\n",
|
||||
shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Issue channel-attn -- the 82586 won't start. */
|
||||
outb(0, ioaddr + I82586_ATTN);
|
||||
if (*(unsigned short *)mem_start != 0)
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int exos205_probe1(struct nic *nic)
|
||||
{
|
||||
int i;
|
||||
/* If you know the other addresses please let me know */
|
||||
static Address mem_addrs[] = {
|
||||
0xcc000, 0 };
|
||||
Address *p;
|
||||
|
||||
scb_base = -16384; /* assume 8k memory */
|
||||
for (p = mem_addrs; (mem_start = *p) != 0; ++p)
|
||||
if (mem_end = mem_start + 16384, exos205_probe2())
|
||||
break;
|
||||
if (mem_start == 0)
|
||||
return (0);
|
||||
/* Get station address */
|
||||
for (i = 0; i < ETH_ALEN; ++i)
|
||||
{
|
||||
nic->node_addr[i] = inb(ioaddr+i);
|
||||
}
|
||||
printf("\nEXOS205 ioaddr %#hX, mem [%#X-%#X], addr %!\n",
|
||||
ioaddr, mem_start, mem_end, nic->node_addr);
|
||||
return (1);
|
||||
}
|
||||
|
||||
struct nic *exos205_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||
{
|
||||
/* If you know the other addresses, please let me know */
|
||||
static unsigned short io_addrs[] = {
|
||||
0x310, 0x0
|
||||
};
|
||||
unsigned short *p;
|
||||
int i;
|
||||
|
||||
/* if probe_addrs is 0, then routine can use a hardwired default */
|
||||
if (probe_addrs == 0)
|
||||
probe_addrs = io_addrs;
|
||||
for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
|
||||
if (exos205_probe1(nic))
|
||||
break;
|
||||
if (ioaddr != 0)
|
||||
{
|
||||
/* point to NIC specific routines */
|
||||
i82586_reset(nic);
|
||||
nic->reset = i82586_reset;
|
||||
nic->poll = i82586_poll;
|
||||
nic->transmit = i82586_transmit;
|
||||
nic->disable = i82586_disable;
|
||||
return nic;
|
||||
}
|
||||
/* else */
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
-564
@@ -1,564 +0,0 @@
|
||||
/**************************************************************************
|
||||
Etherboot - BOOTP/TFTP Bootstrap Program
|
||||
LANCE NIC driver for Etherboot
|
||||
Large portions borrowed from the Linux LANCE driver by Donald Becker
|
||||
Ken Yap, July 1997
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* 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, or (at
|
||||
* your option) any later version.
|
||||
*/
|
||||
|
||||
/* to get some global routines like printf */
|
||||
#include "etherboot.h"
|
||||
/* to get the interface to the body of the program */
|
||||
#include "nic.h"
|
||||
#ifdef INCLUDE_LANCE
|
||||
#include "pci.h"
|
||||
#endif
|
||||
#include "cards.h"
|
||||
|
||||
/* Offsets from base I/O address */
|
||||
#if defined(INCLUDE_NE2100) || defined(INCLUDE_LANCE)
|
||||
#define LANCE_ETH_ADDR 0x0
|
||||
#define LANCE_DATA 0x10
|
||||
#define LANCE_ADDR 0x12
|
||||
#define LANCE_RESET 0x14
|
||||
#define LANCE_BUS_IF 0x16
|
||||
#define LANCE_TOTAL_SIZE 0x18
|
||||
#endif
|
||||
#ifdef INCLUDE_NI6510
|
||||
#define LANCE_ETH_ADDR 0x8
|
||||
#define LANCE_DATA 0x0
|
||||
#define LANCE_ADDR 0x2
|
||||
#define LANCE_RESET 0x4
|
||||
#define LANCE_BUS_IF 0x6
|
||||
#define LANCE_TOTAL_SIZE 0x10
|
||||
#endif
|
||||
|
||||
/* lance_poll() now can use multiple Rx buffers to prevent packet loss. Set
|
||||
* Set LANCE_LOG_RX_BUFFERS to 0..7 for 1, 2, 4, 8, 16, 32, 64 or 128 Rx
|
||||
* buffers. Usually 4 (=16 Rx buffers) is a good value. (Andreas Neuhaus)
|
||||
* Decreased to 2 (=4 Rx buffers) (Ken Yap, 20010305) */
|
||||
|
||||
#define LANCE_LOG_RX_BUFFERS 2 /* Use 2^2=4 Rx buffers */
|
||||
|
||||
#define RX_RING_SIZE (1 << (LANCE_LOG_RX_BUFFERS))
|
||||
#define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
|
||||
#define RX_RING_LEN_BITS ((LANCE_LOG_RX_BUFFERS) << 29)
|
||||
|
||||
struct lance_init_block
|
||||
{
|
||||
unsigned short mode;
|
||||
unsigned char phys_addr[ETH_ALEN];
|
||||
unsigned long filter[2];
|
||||
Address rx_ring;
|
||||
Address tx_ring;
|
||||
};
|
||||
|
||||
struct lance_rx_head
|
||||
{
|
||||
union {
|
||||
Address base;
|
||||
unsigned char addr[4];
|
||||
} u;
|
||||
short buf_length; /* 2s complement */
|
||||
short msg_length;
|
||||
};
|
||||
|
||||
struct lance_tx_head
|
||||
{
|
||||
union {
|
||||
Address base;
|
||||
unsigned char addr[4];
|
||||
} u;
|
||||
short buf_length; /* 2s complement */
|
||||
short misc;
|
||||
};
|
||||
|
||||
struct lance_interface
|
||||
{
|
||||
struct lance_init_block init_block;
|
||||
struct lance_rx_head rx_ring[RX_RING_SIZE];
|
||||
struct lance_tx_head tx_ring;
|
||||
unsigned char rbuf[RX_RING_SIZE][ETH_FRAME_LEN+4];
|
||||
unsigned char tbuf[ETH_FRAME_LEN];
|
||||
/*
|
||||
* Do not alter the order of the struct members above;
|
||||
* the hardware depends on the correct alignment.
|
||||
*/
|
||||
int rx_idx;
|
||||
};
|
||||
|
||||
#define LANCE_MUST_PAD 0x00000001
|
||||
#define LANCE_ENABLE_AUTOSELECT 0x00000002
|
||||
#define LANCE_SELECT_PHONELINE 0x00000004
|
||||
#define LANCE_MUST_UNRESET 0x00000008
|
||||
|
||||
/* A mapping from the chip ID number to the part number and features.
|
||||
These are from the datasheets -- in real life the '970 version
|
||||
reportedly has the same ID as the '965. */
|
||||
static const struct lance_chip_type
|
||||
{
|
||||
int id_number;
|
||||
const char *name;
|
||||
int flags;
|
||||
} chip_table[] = {
|
||||
{0x0000, "LANCE 7990", /* Ancient lance chip. */
|
||||
LANCE_MUST_PAD + LANCE_MUST_UNRESET},
|
||||
{0x0003, "PCnet/ISA 79C960", /* 79C960 PCnet/ISA. */
|
||||
LANCE_ENABLE_AUTOSELECT},
|
||||
{0x2260, "PCnet/ISA+ 79C961", /* 79C961 PCnet/ISA+, Plug-n-Play. */
|
||||
LANCE_ENABLE_AUTOSELECT},
|
||||
{0x2420, "PCnet/PCI 79C970", /* 79C970 or 79C974 PCnet-SCSI, PCI. */
|
||||
LANCE_ENABLE_AUTOSELECT},
|
||||
/* Bug: the PCnet/PCI actually uses the PCnet/VLB ID number, so just call
|
||||
it the PCnet32. */
|
||||
{0x2430, "PCnet32", /* 79C965 PCnet for VL bus. */
|
||||
LANCE_ENABLE_AUTOSELECT},
|
||||
{0x2621, "PCnet/PCI-II 79C970A", /* 79C970A PCInetPCI II. */
|
||||
LANCE_ENABLE_AUTOSELECT},
|
||||
{0x2625, "PCnet-FAST III 79C973", /* 79C973 PCInet-FAST III. */
|
||||
LANCE_ENABLE_AUTOSELECT},
|
||||
{0x2626, "PCnet/HomePNA 79C978",
|
||||
LANCE_ENABLE_AUTOSELECT|LANCE_SELECT_PHONELINE},
|
||||
{0x0, "PCnet (unknown)",
|
||||
LANCE_ENABLE_AUTOSELECT},
|
||||
};
|
||||
|
||||
/* Define a macro for converting program addresses to real addresses */
|
||||
#undef virt_to_bus
|
||||
#define virt_to_bus(x) ((unsigned long)x)
|
||||
|
||||
static int chip_version;
|
||||
static int lance_version;
|
||||
static unsigned short ioaddr;
|
||||
#ifndef INCLUDE_LANCE
|
||||
static int dma;
|
||||
#endif
|
||||
static struct lance_interface *lp;
|
||||
|
||||
/* additional 8 bytes for 8-byte alignment space */
|
||||
#ifdef USE_LOWMEM_BUFFER
|
||||
#define lance ((char *)0x10000 - (sizeof(struct lance_interface)+8))
|
||||
#else
|
||||
static char lance[sizeof(struct lance_interface)+8];
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_LANCE
|
||||
/* DMA defines and helper routines */
|
||||
|
||||
/* DMA controller registers */
|
||||
#define DMA1_CMD_REG 0x08 /* command register (w) */
|
||||
#define DMA1_STAT_REG 0x08 /* status register (r) */
|
||||
#define DMA1_REQ_REG 0x09 /* request register (w) */
|
||||
#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */
|
||||
#define DMA1_MODE_REG 0x0B /* mode register (w) */
|
||||
#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */
|
||||
#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */
|
||||
#define DMA1_RESET_REG 0x0D /* Master Clear (w) */
|
||||
#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */
|
||||
#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */
|
||||
|
||||
#define DMA2_CMD_REG 0xD0 /* command register (w) */
|
||||
#define DMA2_STAT_REG 0xD0 /* status register (r) */
|
||||
#define DMA2_REQ_REG 0xD2 /* request register (w) */
|
||||
#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */
|
||||
#define DMA2_MODE_REG 0xD6 /* mode register (w) */
|
||||
#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */
|
||||
#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */
|
||||
#define DMA2_RESET_REG 0xDA /* Master Clear (w) */
|
||||
#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */
|
||||
#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */
|
||||
|
||||
|
||||
#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */
|
||||
#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */
|
||||
#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */
|
||||
|
||||
/* enable/disable a specific DMA channel */
|
||||
static void enable_dma(unsigned int dmanr)
|
||||
{
|
||||
if (dmanr <= 3)
|
||||
outb_p(dmanr, DMA1_MASK_REG);
|
||||
else
|
||||
outb_p(dmanr & 3, DMA2_MASK_REG);
|
||||
}
|
||||
|
||||
static void disable_dma(unsigned int dmanr)
|
||||
{
|
||||
if (dmanr <= 3)
|
||||
outb_p(dmanr | 4, DMA1_MASK_REG);
|
||||
else
|
||||
outb_p((dmanr & 3) | 4, DMA2_MASK_REG);
|
||||
}
|
||||
|
||||
/* set mode (above) for a specific DMA channel */
|
||||
static void set_dma_mode(unsigned int dmanr, char mode)
|
||||
{
|
||||
if (dmanr <= 3)
|
||||
outb_p(mode | dmanr, DMA1_MODE_REG);
|
||||
else
|
||||
outb_p(mode | (dmanr&3), DMA2_MODE_REG);
|
||||
}
|
||||
#endif /* !INCLUDE_LANCE */
|
||||
|
||||
/**************************************************************************
|
||||
RESET - Reset adapter
|
||||
***************************************************************************/
|
||||
static void lance_reset(struct nic *nic)
|
||||
{
|
||||
int i;
|
||||
Address l;
|
||||
|
||||
/* Reset the LANCE */
|
||||
(void)inw(ioaddr+LANCE_RESET);
|
||||
/* Un-Reset the LANCE, needed only for the NE2100 */
|
||||
if (chip_table[lance_version].flags & LANCE_MUST_UNRESET)
|
||||
outw(0, ioaddr+LANCE_RESET);
|
||||
if (chip_table[lance_version].flags & LANCE_ENABLE_AUTOSELECT)
|
||||
{
|
||||
/* This is 79C960 specific; Turn on auto-select of media
|
||||
(AUI, BNC). */
|
||||
outw(0x2, ioaddr+LANCE_ADDR);
|
||||
/* Don't touch 10base2 power bit. */
|
||||
outw(inw(ioaddr+LANCE_BUS_IF) | 0x2, ioaddr+LANCE_BUS_IF);
|
||||
}
|
||||
/* HomePNA cards need to explicitly pick the phoneline interface.
|
||||
* Some of these cards have ethernet interfaces as well, this
|
||||
* code might require some modification for those.
|
||||
*/
|
||||
if (chip_table[lance_version].flags & LANCE_SELECT_PHONELINE) {
|
||||
short media, check ;
|
||||
/* this is specific to HomePNA cards... */
|
||||
outw(49, ioaddr+0x12) ;
|
||||
media = inw(ioaddr+0x16) ;
|
||||
#ifdef DEBUG
|
||||
printf("media was %d\n", media) ;
|
||||
#endif
|
||||
media &= ~3 ;
|
||||
media |= 1 ;
|
||||
#ifdef DEBUG
|
||||
printf("media changed to %d\n", media) ;
|
||||
#endif
|
||||
media &= ~3 ;
|
||||
media |= 1 ;
|
||||
outw(49, ioaddr+0x12) ;
|
||||
outw(media, ioaddr+0x16) ;
|
||||
outw(49, ioaddr+0x12) ;
|
||||
check = inw(ioaddr+0x16) ;
|
||||
#ifdef DEBUG
|
||||
printf("check %s, media was set properly\n",
|
||||
check == media ? "passed" : "FAILED" ) ;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Re-initialise the LANCE, and start it when done. */
|
||||
/* Set station address */
|
||||
for (i = 0; i < ETH_ALEN; ++i)
|
||||
lp->init_block.phys_addr[i] = nic->node_addr[i];
|
||||
/* Preset the receive ring headers */
|
||||
for (i=0; i<RX_RING_SIZE; i++) {
|
||||
lp->rx_ring[i].buf_length = -ETH_FRAME_LEN-4;
|
||||
/* OWN */
|
||||
lp->rx_ring[i].u.base = virt_to_bus(lp->rbuf[i]) & 0xffffff;
|
||||
/* we set the top byte as the very last thing */
|
||||
lp->rx_ring[i].u.addr[3] = 0x80;
|
||||
}
|
||||
lp->rx_idx = 0;
|
||||
lp->init_block.mode = 0x0; /* enable Rx and Tx */
|
||||
l = (Address)virt_to_bus(&lp->init_block);
|
||||
outw(0x1, ioaddr+LANCE_ADDR);
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
outw((short)l, ioaddr+LANCE_DATA);
|
||||
outw(0x2, ioaddr+LANCE_ADDR);
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
outw((short)(l >> 16), ioaddr+LANCE_DATA);
|
||||
outw(0x4, ioaddr+LANCE_ADDR);
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
outw(0x915, ioaddr+LANCE_DATA);
|
||||
outw(0x0, ioaddr+LANCE_ADDR);
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
outw(0x4, ioaddr+LANCE_DATA); /* stop */
|
||||
outw(0x1, ioaddr+LANCE_DATA); /* init */
|
||||
for (i = 10000; i > 0; --i)
|
||||
if (inw(ioaddr+LANCE_DATA) & 0x100)
|
||||
break;
|
||||
#ifdef DEBUG
|
||||
if (i <= 0)
|
||||
printf("Init timed out\n");
|
||||
#endif
|
||||
/* Apparently clearing the InitDone bit here triggers a bug
|
||||
in the '974. (Mark Stockton) */
|
||||
outw(0x2, ioaddr+LANCE_DATA); /* start */
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
POLL - Wait for a frame
|
||||
***************************************************************************/
|
||||
static int lance_poll(struct nic *nic)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = lp->rx_ring[lp->rx_idx].u.base >> 24;
|
||||
if (status & 0x80)
|
||||
return (0);
|
||||
#ifdef DEBUG
|
||||
printf("LANCE packet received rx_ring.u.base %X mcnt %hX csr0 %hX\n",
|
||||
lp->rx_ring[lp->rx_idx].u.base, lp->rx_ring[lp->rx_idx].msg_length,
|
||||
inw(ioaddr+LANCE_DATA));
|
||||
#endif
|
||||
if (status == 0x3)
|
||||
memcpy(nic->packet, lp->rbuf[lp->rx_idx], nic->packetlen = lp->rx_ring[lp->rx_idx].msg_length);
|
||||
/* Andrew Boyd of QNX reports that some revs of the 79C765
|
||||
clear the buffer length */
|
||||
lp->rx_ring[lp->rx_idx].buf_length = -ETH_FRAME_LEN-4;
|
||||
lp->rx_ring[lp->rx_idx].u.addr[3] |= 0x80; /* prime for next receive */
|
||||
|
||||
/* I'm not sure if the following is still ok with multiple Rx buffers, but it works */
|
||||
outw(0x0, ioaddr+LANCE_ADDR);
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
outw(0x500, ioaddr+LANCE_DATA); /* clear receive + InitDone */
|
||||
|
||||
/* Switch to the next Rx ring buffer */
|
||||
lp->rx_idx = (lp->rx_idx + 1) & RX_RING_MOD_MASK;
|
||||
|
||||
return (status == 0x3);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
TRANSMIT - Transmit a frame
|
||||
***************************************************************************/
|
||||
static void lance_transmit(
|
||||
struct nic *nic,
|
||||
const char *d, /* Destination */
|
||||
unsigned int t, /* Type */
|
||||
unsigned int s, /* size */
|
||||
const char *p) /* Packet */
|
||||
{
|
||||
unsigned long time;
|
||||
|
||||
/* copy the packet to ring buffer */
|
||||
memcpy(lp->tbuf, d, ETH_ALEN); /* dst */
|
||||
memcpy(&lp->tbuf[ETH_ALEN], nic->node_addr, ETH_ALEN); /* src */
|
||||
lp->tbuf[ETH_ALEN+ETH_ALEN] = t >> 8; /* type */
|
||||
lp->tbuf[ETH_ALEN+ETH_ALEN+1] = t; /* type */
|
||||
memcpy(&lp->tbuf[ETH_HLEN], p, s);
|
||||
s += ETH_HLEN;
|
||||
if (chip_table[chip_version].flags & LANCE_MUST_PAD)
|
||||
while (s < ETH_ZLEN) /* pad to min length */
|
||||
lp->tbuf[s++] = 0;
|
||||
lp->tx_ring.buf_length = -s;
|
||||
lp->tx_ring.misc = 0x0;
|
||||
/* OWN, STP, ENP */
|
||||
lp->tx_ring.u.base = virt_to_bus(lp->tbuf) & 0xffffff;
|
||||
/* we set the top byte as the very last thing */
|
||||
lp->tx_ring.u.addr[3] = 0x83;
|
||||
/* Trigger an immediate send poll */
|
||||
outw(0x0, ioaddr+LANCE_ADDR);
|
||||
(void)inw(ioaddr+LANCE_ADDR); /* as in the datasheets... */
|
||||
/* Klaus Espenlaub: the value below was 0x48, but that enabled the
|
||||
* interrupt line, causing a hang if for some reasone the interrupt
|
||||
* controller had the LANCE interrupt enabled. I have no idea why
|
||||
* nobody ran into this before... */
|
||||
outw(0x08, ioaddr+LANCE_DATA);
|
||||
/* wait for transmit complete */
|
||||
time = currticks() + TICKS_PER_SEC; /* wait one second */
|
||||
while (currticks() < time && (lp->tx_ring.u.base & 0x80000000) != 0)
|
||||
;
|
||||
if ((lp->tx_ring.u.base & 0x80000000) != 0)
|
||||
printf("LANCE timed out on transmit\n");
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
outw(0x200, ioaddr+LANCE_DATA); /* clear transmit + InitDone */
|
||||
#ifdef DEBUG
|
||||
printf("tx_ring.u.base %X tx_ring.buf_length %hX tx_ring.misc %hX csr0 %hX\n",
|
||||
lp->tx_ring.u.base, lp->tx_ring.buf_length, lp->tx_ring.misc,
|
||||
inw(ioaddr+LANCE_DATA));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void lance_disable(struct nic *nic)
|
||||
{
|
||||
(void)inw(ioaddr+LANCE_RESET);
|
||||
if (chip_table[lance_version].flags & LANCE_MUST_UNRESET)
|
||||
outw(0, ioaddr+LANCE_RESET);
|
||||
|
||||
outw(0, ioaddr+LANCE_ADDR);
|
||||
outw(0x0004, ioaddr+LANCE_DATA); /* stop the LANCE */
|
||||
|
||||
#ifndef INCLUDE_LANCE
|
||||
disable_dma(dma);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_LANCE
|
||||
static int lance_probe1(struct nic *nic, struct pci_device *pci)
|
||||
#else
|
||||
static int lance_probe1(struct nic *nic)
|
||||
#endif
|
||||
{
|
||||
int reset_val ;
|
||||
unsigned int i;
|
||||
Address l;
|
||||
short dma_channels;
|
||||
#ifndef INCLUDE_LANCE
|
||||
static const char dmas[] = { 5, 6, 7, 3 };
|
||||
#endif
|
||||
|
||||
reset_val = inw(ioaddr+LANCE_RESET);
|
||||
outw(reset_val, ioaddr+LANCE_RESET);
|
||||
#if 1 /* Klaus Espenlaub -- was #ifdef INCLUDE_NE2100*/
|
||||
outw(0x0, ioaddr+LANCE_ADDR); /* Switch to window 0 */
|
||||
if (inw(ioaddr+LANCE_DATA) != 0x4)
|
||||
return (-1);
|
||||
#endif
|
||||
outw(88, ioaddr+LANCE_ADDR); /* Get the version of the chip */
|
||||
if (inw(ioaddr+LANCE_ADDR) != 88)
|
||||
lance_version = 0;
|
||||
else
|
||||
{
|
||||
chip_version = inw(ioaddr+LANCE_DATA);
|
||||
outw(89, ioaddr+LANCE_ADDR);
|
||||
chip_version |= inw(ioaddr+LANCE_DATA) << 16;
|
||||
if ((chip_version & 0xfff) != 0x3)
|
||||
return (-1);
|
||||
chip_version = (chip_version >> 12) & 0xffff;
|
||||
for (lance_version = 1; chip_table[lance_version].id_number != 0; ++lance_version)
|
||||
if (chip_table[lance_version].id_number == chip_version)
|
||||
break;
|
||||
}
|
||||
/* make sure data structure is 8-byte aligned */
|
||||
l = ((Address)lance + 7) & ~7;
|
||||
lp = (struct lance_interface *)l;
|
||||
lp->init_block.mode = 0x3; /* disable Rx and Tx */
|
||||
lp->init_block.filter[0] = lp->init_block.filter[1] = 0x0;
|
||||
/* using multiple Rx buffer and a single Tx buffer */
|
||||
lp->init_block.rx_ring = (virt_to_bus(&lp->rx_ring) & 0xffffff) | RX_RING_LEN_BITS;
|
||||
lp->init_block.tx_ring = virt_to_bus(&lp->tx_ring) & 0xffffff;
|
||||
l = virt_to_bus(&lp->init_block);
|
||||
outw(0x1, ioaddr+LANCE_ADDR);
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
outw((unsigned short)l, ioaddr+LANCE_DATA);
|
||||
outw(0x2, ioaddr+LANCE_ADDR);
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
outw((unsigned short)(l >> 16), ioaddr+LANCE_DATA);
|
||||
outw(0x4, ioaddr+LANCE_ADDR);
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
outw(0x915, ioaddr+LANCE_DATA);
|
||||
outw(0x0, ioaddr+LANCE_ADDR);
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
/* Get station address */
|
||||
for (i = 0; i < ETH_ALEN; ++i) {
|
||||
nic->node_addr[i] = inb(ioaddr+LANCE_ETH_ADDR+i);
|
||||
}
|
||||
#ifndef INCLUDE_LANCE
|
||||
/* now probe for DMA channel */
|
||||
dma_channels = ((inb(DMA1_STAT_REG) >> 4) & 0xf) |
|
||||
(inb(DMA2_STAT_REG) & 0xf0);
|
||||
/* need to fix when PCI provides DMA info */
|
||||
for (i = 0; i < (sizeof(dmas)/sizeof(dmas[0])); ++i)
|
||||
{
|
||||
int j;
|
||||
|
||||
dma = dmas[i];
|
||||
/* Don't enable a permanently busy DMA channel,
|
||||
or the machine will hang */
|
||||
if (dma_channels & (1 << dma))
|
||||
continue;
|
||||
outw(0x7f04, ioaddr+LANCE_DATA); /* clear memory error bits */
|
||||
set_dma_mode(dma, DMA_MODE_CASCADE);
|
||||
enable_dma(dma);
|
||||
outw(0x1, ioaddr+LANCE_DATA); /* init */
|
||||
for (j = 100; j > 0; --j)
|
||||
if (inw(ioaddr+LANCE_DATA) & 0x900)
|
||||
break;
|
||||
if (inw(ioaddr+LANCE_DATA) & 0x100)
|
||||
break;
|
||||
else
|
||||
disable_dma(dma);
|
||||
}
|
||||
if (i >= (sizeof(dmas)/sizeof(dmas[0])))
|
||||
dma = 0;
|
||||
printf("\n%s base %#X, DMA %d, addr %!\n",
|
||||
chip_table[lance_version].name, ioaddr, dma, nic->node_addr);
|
||||
#else
|
||||
printf(" %s base %#hX, addr %!\n", chip_table[lance_version].name, ioaddr, nic->node_addr);
|
||||
#endif
|
||||
if (chip_table[chip_version].flags & LANCE_ENABLE_AUTOSELECT) {
|
||||
/* Turn on auto-select of media (10baseT or BNC) so that the
|
||||
* user watch the LEDs. */
|
||||
outw(0x0002, ioaddr+LANCE_ADDR);
|
||||
/* Don't touch 10base2 power bit. */
|
||||
outw(inw(ioaddr+LANCE_BUS_IF) | 0x0002, ioaddr+LANCE_BUS_IF);
|
||||
}
|
||||
return (lance_version);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
PROBE - Look for an adapter, this routine's visible to the outside
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef INCLUDE_LANCE
|
||||
struct nic *lancepci_probe(struct nic *nic, unsigned short *probe_addrs, struct pci_device *pci)
|
||||
#endif
|
||||
#ifdef INCLUDE_NE2100
|
||||
struct nic *ne2100_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||
#endif
|
||||
#ifdef INCLUDE_NI6510
|
||||
struct nic *ni6510_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||
#endif
|
||||
{
|
||||
unsigned short *p;
|
||||
#ifndef INCLUDE_LANCE
|
||||
static unsigned short io_addrs[] = { 0x300, 0x320, 0x340, 0x360, 0 };
|
||||
#endif
|
||||
|
||||
/* if probe_addrs is 0, then routine can use a hardwired default */
|
||||
if (probe_addrs == 0) {
|
||||
#ifdef INCLUDE_LANCE
|
||||
return 0;
|
||||
#else
|
||||
probe_addrs = io_addrs;
|
||||
#endif
|
||||
}
|
||||
for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
|
||||
{
|
||||
char offset15, offset14 = inb(ioaddr + 14);
|
||||
unsigned short pci_cmd;
|
||||
|
||||
#ifdef INCLUDE_NE2100
|
||||
if ((offset14 == 0x52 || offset14 == 0x57) &&
|
||||
((offset15 = inb(ioaddr + 15)) == 0x57 || offset15 == 0x44))
|
||||
if (lance_probe1(nic) >= 0)
|
||||
break;
|
||||
#endif
|
||||
#ifdef INCLUDE_NI6510
|
||||
if ((offset14 == 0x00 || offset14 == 0x52) &&
|
||||
((offset15 = inb(ioaddr + 15)) == 0x55 || offset15 == 0x44))
|
||||
if (lance_probe1(nic) >= 0)
|
||||
break;
|
||||
#endif
|
||||
#ifdef INCLUDE_LANCE
|
||||
adjust_pci_device(pci);
|
||||
if (lance_probe1(nic, pci) >= 0)
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
/* if board found */
|
||||
if (ioaddr != 0)
|
||||
{
|
||||
/* point to NIC specific routines */
|
||||
lance_reset(nic);
|
||||
nic->reset = lance_reset;
|
||||
nic->poll = lance_poll;
|
||||
nic->transmit = lance_transmit;
|
||||
nic->disable = lance_disable;
|
||||
return nic;
|
||||
}
|
||||
|
||||
/* no board found */
|
||||
return 0;
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
#ifndef _ASM_IO_H
|
||||
#define _ASM_IO_H
|
||||
|
||||
/*
|
||||
* This file contains the definitions for the x86 IO instructions
|
||||
* inb/inw/inl/outb/outw/outl and the "string versions" of the same
|
||||
* (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
|
||||
* versions of the single-IO instructions (inb_p/inw_p/..).
|
||||
*
|
||||
* This file is not meant to be obfuscating: it's just complicated
|
||||
* to (a) handle it all in a way that makes gcc able to optimize it
|
||||
* as well as possible and (b) trying to avoid writing the same thing
|
||||
* over and over again with slight variations and possibly making a
|
||||
* mistake somewhere.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Thanks to James van Artsdalen for a better timing-fix than
|
||||
* the two short jumps: using outb's to a nonexistent port seems
|
||||
* to guarantee better timings even on fast machines.
|
||||
*
|
||||
* On the other hand, I'd like to be sure of a non-existent port:
|
||||
* I feel a bit unsafe about using 0x80 (should be safe, though)
|
||||
*
|
||||
* Linus
|
||||
*/
|
||||
|
||||
#ifdef SLOW_IO_BY_JUMPING
|
||||
#define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
|
||||
#else
|
||||
#define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
|
||||
#endif
|
||||
|
||||
#ifdef REALLY_SLOW_IO
|
||||
#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
|
||||
#else
|
||||
#define SLOW_DOWN_IO __SLOW_DOWN_IO
|
||||
#endif
|
||||
|
||||
/*
|
||||
* readX/writeX() are used to access memory mapped devices. On some
|
||||
* architectures the memory mapped IO stuff needs to be accessed
|
||||
* differently. On the x86 architecture, we just read/write the
|
||||
* memory location directly.
|
||||
*/
|
||||
#define readb(addr) (*(volatile unsigned char *) (addr))
|
||||
#define readw(addr) (*(volatile unsigned short *) (addr))
|
||||
#define readl(addr) (*(volatile unsigned int *) (addr))
|
||||
|
||||
#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
|
||||
#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
|
||||
#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
|
||||
|
||||
#define memset_io(a,b,c) memset((void *)(a),(b),(c))
|
||||
#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
|
||||
#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
|
||||
|
||||
/*
|
||||
* Again, i386 does not require mem IO specific function.
|
||||
*/
|
||||
|
||||
#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(void *)(b),(c),(d))
|
||||
|
||||
/*
|
||||
* Talk about misusing macros..
|
||||
*/
|
||||
|
||||
#define __OUT1(s,x) \
|
||||
extern void __out##s(unsigned x value, unsigned short port); \
|
||||
extern inline void __out##s(unsigned x value, unsigned short port) {
|
||||
|
||||
#define __OUT2(s,s1,s2) \
|
||||
__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
|
||||
|
||||
#define __OUT(s,s1,x) \
|
||||
__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); } \
|
||||
__OUT1(s##c,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); } \
|
||||
__OUT1(s##_p,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); SLOW_DOWN_IO; } \
|
||||
__OUT1(s##c_p,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); SLOW_DOWN_IO; }
|
||||
|
||||
#define __IN1(s,x) \
|
||||
extern unsigned x __in##s(unsigned short port); \
|
||||
extern inline unsigned x __in##s(unsigned short port) { unsigned x _v;
|
||||
|
||||
#define __IN2(s,s1,s2) \
|
||||
__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
|
||||
|
||||
#define __IN(s,s1,x,i...) \
|
||||
__IN1(s,x) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); return _v; } \
|
||||
__IN1(s##c,x) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); return _v; } \
|
||||
__IN1(s##_p,x) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); SLOW_DOWN_IO; return _v; } \
|
||||
__IN1(s##c_p,x) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); SLOW_DOWN_IO; return _v; }
|
||||
|
||||
#define __INS(s) \
|
||||
extern void ins##s(unsigned short port, void * addr, unsigned long count); \
|
||||
extern inline void ins##s(unsigned short port, void * addr, unsigned long count) \
|
||||
{ __asm__ __volatile__ ("cld ; rep ; ins" #s \
|
||||
: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
|
||||
|
||||
#define __OUTS(s) \
|
||||
extern void outs##s(unsigned short port, const void * addr, unsigned long count); \
|
||||
extern inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
|
||||
{ __asm__ __volatile__ ("cld ; rep ; outs" #s \
|
||||
: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
|
||||
|
||||
__IN(b,"", char)
|
||||
__IN(w,"",short)
|
||||
__IN(l,"", long)
|
||||
|
||||
__OUT(b,"b",char)
|
||||
__OUT(w,"w",short)
|
||||
__OUT(l,,int)
|
||||
|
||||
__INS(b)
|
||||
__INS(w)
|
||||
__INS(l)
|
||||
|
||||
__OUTS(b)
|
||||
__OUTS(w)
|
||||
__OUTS(l)
|
||||
|
||||
/*
|
||||
* Note that due to the way __builtin_constant_p() works, you
|
||||
* - can't use it inside a inline function (it will never be true)
|
||||
* - you don't have to worry about side effects within the __builtin..
|
||||
*/
|
||||
#define outb(val,port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__outbc((val),(port)) : \
|
||||
__outb((val),(port)))
|
||||
|
||||
#define inb(port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__inbc(port) : \
|
||||
__inb(port))
|
||||
|
||||
#define outb_p(val,port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__outbc_p((val),(port)) : \
|
||||
__outb_p((val),(port)))
|
||||
|
||||
#define inb_p(port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__inbc_p(port) : \
|
||||
__inb_p(port))
|
||||
|
||||
#define outw(val,port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__outwc((val),(port)) : \
|
||||
__outw((val),(port)))
|
||||
|
||||
#define inw(port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__inwc(port) : \
|
||||
__inw(port))
|
||||
|
||||
#define outw_p(val,port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__outwc_p((val),(port)) : \
|
||||
__outw_p((val),(port)))
|
||||
|
||||
#define inw_p(port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__inwc_p(port) : \
|
||||
__inw_p(port))
|
||||
|
||||
#define outl(val,port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__outlc((val),(port)) : \
|
||||
__outl((val),(port)))
|
||||
|
||||
#define inl(port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__inlc(port) : \
|
||||
__inl(port))
|
||||
|
||||
#define outl_p(val,port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__outlc_p((val),(port)) : \
|
||||
__outl_p((val),(port)))
|
||||
|
||||
#define inl_p(port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__inlc_p(port) : \
|
||||
__inl_p(port))
|
||||
|
||||
#endif
|
||||
@@ -1,291 +0,0 @@
|
||||
/*
|
||||
* Taken from Linux /usr/include/asm/string.h
|
||||
* All except memcpy, memmove, memset and memcmp removed.
|
||||
*/
|
||||
|
||||
#ifndef _I386_STRING_H_
|
||||
#define _I386_STRING_H_
|
||||
|
||||
/*
|
||||
* This string-include defines all string functions as inline
|
||||
* functions. Use gcc. It also assumes ds=es=data space, this should be
|
||||
* normal. Most of the string-functions are rather heavily hand-optimized,
|
||||
* see especially strtok,strstr,str[c]spn. They should work, but are not
|
||||
* very easy to understand. Everything is done entirely within the register
|
||||
* set, making the functions fast and clean. String instructions have been
|
||||
* used through-out, making for "slightly" unclear code :-)
|
||||
*
|
||||
* NO Copyright (C) 1991, 1992 Linus Torvalds,
|
||||
* consider these trivial functions to be PD.
|
||||
*/
|
||||
|
||||
typedef int size_t;
|
||||
|
||||
extern void *__memcpy(void * to, const void * from, size_t n);
|
||||
extern void *__constant_memcpy(void * to, const void * from, size_t n);
|
||||
extern void *memmove(void * dest,const void * src, size_t n);
|
||||
extern void *__memset_generic(void * s, char c,size_t count);
|
||||
extern void *__constant_c_memset(void * s, unsigned long c, size_t count);
|
||||
extern void *__constant_c_and_count_memset(void * s, unsigned long pattern, size_t count);
|
||||
|
||||
|
||||
extern inline void * __memcpy(void * to, const void * from, size_t n)
|
||||
{
|
||||
int d0, d1, d2;
|
||||
__asm__ __volatile__(
|
||||
"cld\n\t"
|
||||
"rep ; movsl\n\t"
|
||||
"testb $2,%b4\n\t"
|
||||
"je 1f\n\t"
|
||||
"movsw\n"
|
||||
"1:\ttestb $1,%b4\n\t"
|
||||
"je 2f\n\t"
|
||||
"movsb\n"
|
||||
"2:"
|
||||
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
|
||||
:"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
|
||||
: "memory");
|
||||
return (to);
|
||||
}
|
||||
|
||||
/*
|
||||
* This looks horribly ugly, but the compiler can optimize it totally,
|
||||
* as the count is constant.
|
||||
*/
|
||||
extern inline void * __constant_memcpy(void * to, const void * from, size_t n)
|
||||
{
|
||||
switch (n) {
|
||||
case 0:
|
||||
return to;
|
||||
case 1:
|
||||
*(unsigned char *)to = *(const unsigned char *)from;
|
||||
return to;
|
||||
case 2:
|
||||
*(unsigned short *)to = *(const unsigned short *)from;
|
||||
return to;
|
||||
case 3:
|
||||
*(unsigned short *)to = *(const unsigned short *)from;
|
||||
*(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
|
||||
return to;
|
||||
case 4:
|
||||
*(unsigned long *)to = *(const unsigned long *)from;
|
||||
return to;
|
||||
case 6: /* for Ethernet addresses */
|
||||
*(unsigned long *)to = *(const unsigned long *)from;
|
||||
*(2+(unsigned short *)to) = *(2+(const unsigned short *)from);
|
||||
return to;
|
||||
case 8:
|
||||
*(unsigned long *)to = *(const unsigned long *)from;
|
||||
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
|
||||
return to;
|
||||
case 12:
|
||||
*(unsigned long *)to = *(const unsigned long *)from;
|
||||
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
|
||||
*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
|
||||
return to;
|
||||
case 16:
|
||||
*(unsigned long *)to = *(const unsigned long *)from;
|
||||
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
|
||||
*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
|
||||
*(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
|
||||
return to;
|
||||
case 20:
|
||||
*(unsigned long *)to = *(const unsigned long *)from;
|
||||
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
|
||||
*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
|
||||
*(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
|
||||
*(4+(unsigned long *)to) = *(4+(const unsigned long *)from);
|
||||
return to;
|
||||
}
|
||||
#define COMMON(x) \
|
||||
__asm__ __volatile__( \
|
||||
"cld\n\t" \
|
||||
"rep ; movsl" \
|
||||
x \
|
||||
: "=&c" (d0), "=&D" (d1), "=&S" (d2) \
|
||||
: "0" (n/4),"1" ((long) to),"2" ((long) from) \
|
||||
: "memory");
|
||||
{
|
||||
int d0, d1, d2;
|
||||
switch (n % 4) {
|
||||
case 0: COMMON(""); return to;
|
||||
case 1: COMMON("\n\tmovsb"); return to;
|
||||
case 2: COMMON("\n\tmovsw"); return to;
|
||||
default: COMMON("\n\tmovsw\n\tmovsb"); return to;
|
||||
}
|
||||
}
|
||||
|
||||
#undef COMMON
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_MEMCPY
|
||||
#define memcpy(t, f, n) \
|
||||
(__builtin_constant_p(n) ? \
|
||||
__constant_memcpy((t),(f),(n)) : \
|
||||
__memcpy((t),(f),(n)))
|
||||
|
||||
#define __HAVE_ARCH_MEMMOVE
|
||||
extern inline void * memmove(void * dest,const void * src, size_t n)
|
||||
{
|
||||
int d0, d1, d2;
|
||||
if (dest<src)
|
||||
__asm__ __volatile__(
|
||||
"cld\n\t"
|
||||
"rep\n\t"
|
||||
"movsb"
|
||||
: "=&c" (d0), "=&S" (d1), "=&D" (d2)
|
||||
:"0" (n),"1" (src),"2" (dest)
|
||||
: "memory");
|
||||
else
|
||||
__asm__ __volatile__(
|
||||
"std\n\t"
|
||||
"rep\n\t"
|
||||
"movsb\n\t"
|
||||
"cld"
|
||||
: "=&c" (d0), "=&S" (d1), "=&D" (d2)
|
||||
:"0" (n),
|
||||
"1" (n-1+(const char *)src),
|
||||
"2" (n-1+(char *)dest)
|
||||
:"memory");
|
||||
return dest;
|
||||
}
|
||||
|
||||
#define memcmp __builtin_memcmp
|
||||
|
||||
extern inline void * __memset_generic(void * s, char c,size_t count)
|
||||
{
|
||||
int d0, d1;
|
||||
__asm__ __volatile__(
|
||||
"cld\n\t"
|
||||
"rep\n\t"
|
||||
"stosb"
|
||||
: "=&c" (d0), "=&D" (d1)
|
||||
:"a" (c),"1" (s),"0" (count)
|
||||
:"memory");
|
||||
return s;
|
||||
}
|
||||
|
||||
/* we might want to write optimized versions of these later */
|
||||
#define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
|
||||
|
||||
/*
|
||||
* memset(x,0,y) is a reasonably common thing to do, so we want to fill
|
||||
* things 32 bits at a time even when we don't know the size of the
|
||||
* area at compile-time..
|
||||
*/
|
||||
extern inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
|
||||
{
|
||||
int d0, d1;
|
||||
__asm__ __volatile__(
|
||||
"cld\n\t"
|
||||
"rep ; stosl\n\t"
|
||||
"testb $2,%b3\n\t"
|
||||
"je 1f\n\t"
|
||||
"stosw\n"
|
||||
"1:\ttestb $1,%b3\n\t"
|
||||
"je 2f\n\t"
|
||||
"stosb\n"
|
||||
"2:"
|
||||
: "=&c" (d0), "=&D" (d1)
|
||||
:"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
|
||||
:"memory");
|
||||
return (s);
|
||||
}
|
||||
|
||||
/*
|
||||
* This looks horribly ugly, but the compiler can optimize it totally,
|
||||
* as we by now know that both pattern and count is constant..
|
||||
*/
|
||||
extern inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
|
||||
{
|
||||
switch (count) {
|
||||
case 0:
|
||||
return s;
|
||||
case 1:
|
||||
*(unsigned char *)s = pattern;
|
||||
return s;
|
||||
case 2:
|
||||
*(unsigned short *)s = pattern;
|
||||
return s;
|
||||
case 3:
|
||||
*(unsigned short *)s = pattern;
|
||||
*(2+(unsigned char *)s) = pattern;
|
||||
return s;
|
||||
case 4:
|
||||
*(unsigned long *)s = pattern;
|
||||
return s;
|
||||
}
|
||||
#define COMMON(x) \
|
||||
__asm__ __volatile__("cld\n\t" \
|
||||
"rep ; stosl" \
|
||||
x \
|
||||
: "=&c" (d0), "=&D" (d1) \
|
||||
: "a" (pattern),"0" (count/4),"1" ((long) s) \
|
||||
: "memory")
|
||||
{
|
||||
int d0, d1;
|
||||
switch (count % 4) {
|
||||
case 0: COMMON(""); return s;
|
||||
case 1: COMMON("\n\tstosb"); return s;
|
||||
case 2: COMMON("\n\tstosw"); return s;
|
||||
default: COMMON("\n\tstosw\n\tstosb"); return s;
|
||||
}
|
||||
}
|
||||
|
||||
#undef COMMON
|
||||
}
|
||||
|
||||
#define __constant_c_x_memset(s, c, count) \
|
||||
(__builtin_constant_p(count) ? \
|
||||
__constant_c_and_count_memset((s),(c),(count)) : \
|
||||
__constant_c_memset((s),(c),(count)))
|
||||
|
||||
#define __memset(s, c, count) \
|
||||
(__builtin_constant_p(count) ? \
|
||||
__constant_count_memset((s),(c),(count)) : \
|
||||
__memset_generic((s),(c),(count)))
|
||||
|
||||
#define __HAVE_ARCH_MEMSET
|
||||
#define memset(s, c, count) \
|
||||
(__builtin_constant_p(c) ? \
|
||||
__constant_c_x_memset((s),(c),(count)) : \
|
||||
__memset((s),(c),(count)))
|
||||
|
||||
#define __HAVE_ARCH_STRNCMP
|
||||
static inline int strncmp(const char * cs,const char * ct,size_t count)
|
||||
{
|
||||
register int __res;
|
||||
int d0, d1, d2;
|
||||
__asm__ __volatile__(
|
||||
"1:\tdecl %3\n\t"
|
||||
"js 2f\n\t"
|
||||
"lodsb\n\t"
|
||||
"scasb\n\t"
|
||||
"jne 3f\n\t"
|
||||
"testb %%al,%%al\n\t"
|
||||
"jne 1b\n"
|
||||
"2:\txorl %%eax,%%eax\n\t"
|
||||
"jmp 4f\n"
|
||||
"3:\tsbbl %%eax,%%eax\n\t"
|
||||
"orb $1,%%al\n"
|
||||
"4:"
|
||||
:"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
|
||||
:"1" (cs),"2" (ct),"3" (count));
|
||||
return __res;
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_STRLEN
|
||||
static inline size_t strlen(const char * s)
|
||||
{
|
||||
int d0;
|
||||
register int __res;
|
||||
__asm__ __volatile__(
|
||||
"repne\n\t"
|
||||
"scasb\n\t"
|
||||
"notl %0\n\t"
|
||||
"decl %0"
|
||||
:"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff));
|
||||
return __res;
|
||||
}
|
||||
|
||||
#endif
|
||||
-1171
File diff suppressed because it is too large.
Load diff
-266
@@ -1,266 +0,0 @@
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
|
||||
*
|
||||
* 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
|
||||
* (at your option) 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.
|
||||
*/
|
||||
|
||||
/* Based on "src/misc.c" in etherboot-5.0.5. */
|
||||
|
||||
#define GRUB 1
|
||||
#include <etherboot.h>
|
||||
|
||||
void
|
||||
sleep (int secs)
|
||||
{
|
||||
unsigned long tmo = currticks () + secs;
|
||||
|
||||
while (currticks () < tmo)
|
||||
;
|
||||
}
|
||||
|
||||
void
|
||||
twiddle (void)
|
||||
{
|
||||
static unsigned long lastticks = 0;
|
||||
static int count = 0;
|
||||
static const char tiddles[]="-\\|/";
|
||||
unsigned long ticks;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
if ((ticks = currticks ()) == lastticks)
|
||||
return;
|
||||
|
||||
lastticks = ticks;
|
||||
grub_putchar (tiddles[(count++) & 3]);
|
||||
grub_putchar ('\b');
|
||||
}
|
||||
}
|
||||
|
||||
/* Because Etherboot uses its own formats for the printf family,
|
||||
define separate definitions from GRUB. */
|
||||
/**************************************************************************
|
||||
PRINTF and friends
|
||||
|
||||
Formats:
|
||||
%[#]x - 4 bytes long (8 hex digits, lower case)
|
||||
%[#]X - 4 bytes long (8 hex digits, upper case)
|
||||
%[#]hx - 2 bytes int (4 hex digits, lower case)
|
||||
%[#]hX - 2 bytes int (4 hex digits, upper case)
|
||||
%[#]hhx - 1 byte int (2 hex digits, lower case)
|
||||
%[#]hhX - 1 byte int (2 hex digits, upper case)
|
||||
- optional # prefixes 0x or 0X
|
||||
%d - decimal int
|
||||
%c - char
|
||||
%s - string
|
||||
%@ - Internet address in ddd.ddd.ddd.ddd notation
|
||||
%! - Ethernet address in xx:xx:xx:xx:xx:xx notation
|
||||
Note: width specification not supported
|
||||
**************************************************************************/
|
||||
static int
|
||||
etherboot_vsprintf (char *buf, const char *fmt, const int *dp)
|
||||
{
|
||||
char *p, *s;
|
||||
|
||||
s = buf;
|
||||
for ( ; *fmt != '\0'; ++fmt)
|
||||
{
|
||||
if (*fmt != '%')
|
||||
{
|
||||
buf ? *s++ = *fmt : grub_putchar (*fmt);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*++fmt == 's')
|
||||
{
|
||||
for (p = (char *) *dp++; *p != '\0'; p++)
|
||||
buf ? *s++ = *p : grub_putchar (*p);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Length of item is bounded */
|
||||
char tmp[20], *q = tmp;
|
||||
int alt = 0;
|
||||
int shift = 28;
|
||||
|
||||
if (*fmt == '#')
|
||||
{
|
||||
alt = 1;
|
||||
fmt++;
|
||||
}
|
||||
|
||||
if (*fmt == 'h')
|
||||
{
|
||||
shift = 12;
|
||||
fmt++;
|
||||
}
|
||||
|
||||
if (*fmt == 'h')
|
||||
{
|
||||
shift = 4;
|
||||
fmt++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Before each format q points to tmp buffer
|
||||
* After each format q points past end of item
|
||||
*/
|
||||
if ((*fmt | 0x20) == 'x')
|
||||
{
|
||||
/* With x86 gcc, sizeof(long) == sizeof(int) */
|
||||
const long *lp = (const long *) dp;
|
||||
long h = *lp++;
|
||||
int ncase = (*fmt & 0x20);
|
||||
|
||||
dp = (const int *) lp;
|
||||
if (alt)
|
||||
{
|
||||
*q++ = '0';
|
||||
*q++ = 'X' | ncase;
|
||||
}
|
||||
for (; shift >= 0; shift -= 4)
|
||||
*q++ = "0123456789ABCDEF"[(h >> shift) & 0xF] | ncase;
|
||||
}
|
||||
else if (*fmt == 'd')
|
||||
{
|
||||
int i = *dp++;
|
||||
char *r;
|
||||
|
||||
if (i < 0)
|
||||
{
|
||||
*q++ = '-';
|
||||
i = -i;
|
||||
}
|
||||
|
||||
p = q; /* save beginning of digits */
|
||||
do
|
||||
{
|
||||
*q++ = '0' + (i % 10);
|
||||
i /= 10;
|
||||
}
|
||||
while (i);
|
||||
|
||||
/* reverse digits, stop in middle */
|
||||
r = q; /* don't alter q */
|
||||
while (--r > p)
|
||||
{
|
||||
i = *r;
|
||||
*r = *p;
|
||||
*p++ = i;
|
||||
}
|
||||
}
|
||||
else if (*fmt == '@')
|
||||
{
|
||||
unsigned char *r;
|
||||
union
|
||||
{
|
||||
long l;
|
||||
unsigned char c[4];
|
||||
}
|
||||
u;
|
||||
const long *lp = (const long *) dp;
|
||||
|
||||
u.l = *lp++;
|
||||
dp = (const int *) lp;
|
||||
|
||||
for (r = &u.c[0]; r < &u.c[4]; ++r)
|
||||
q += etherboot_sprintf (q, "%d.", *r);
|
||||
|
||||
--q;
|
||||
}
|
||||
else if (*fmt == '!')
|
||||
{
|
||||
char *r;
|
||||
p = (char *) *dp++;
|
||||
|
||||
for (r = p + ETH_ALEN; p < r; ++p)
|
||||
q += etherboot_sprintf (q, "%hhX:", *p);
|
||||
|
||||
--q;
|
||||
}
|
||||
else if (*fmt == 'c')
|
||||
*q++ = *dp++;
|
||||
else
|
||||
*q++ = *fmt;
|
||||
|
||||
/* now output the saved string */
|
||||
for (p = tmp; p < q; ++p)
|
||||
buf ? *s++ = *p : grub_putchar (*p);
|
||||
}
|
||||
}
|
||||
|
||||
if (buf)
|
||||
*s = '\0';
|
||||
|
||||
return (s - buf);
|
||||
}
|
||||
|
||||
int
|
||||
etherboot_sprintf (char *buf, const char *fmt, ...)
|
||||
{
|
||||
return etherboot_vsprintf (buf, fmt, ((const int *) &fmt) + 1);
|
||||
}
|
||||
|
||||
void
|
||||
etherboot_printf (const char *fmt, ...)
|
||||
{
|
||||
(void) etherboot_vsprintf (0, fmt, ((const int *) &fmt) + 1);
|
||||
}
|
||||
|
||||
int
|
||||
inet_aton (char *p, in_addr *addr)
|
||||
{
|
||||
unsigned long ip = 0;
|
||||
int val;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
val = getdec (&p);
|
||||
|
||||
if (val < 0 || val > 255)
|
||||
return 0;
|
||||
|
||||
if (i != 3 && *p++ != '.')
|
||||
return 0;
|
||||
|
||||
ip = (ip << 8) | val;
|
||||
}
|
||||
|
||||
addr->s_addr = htonl (ip);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
getdec (char **ptr)
|
||||
{
|
||||
char *p = *ptr;
|
||||
int ret = 0;
|
||||
|
||||
if (*p < '0' || *p > '9')
|
||||
return -1;
|
||||
|
||||
while (*p >= '0' && *p <= '9')
|
||||
{
|
||||
ret = ret * 10 + (*p - '0');
|
||||
p++;
|
||||
}
|
||||
|
||||
*ptr = p;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1,739 +0,0 @@
|
||||
/* -*- Mode:C; c-basic-offset:4; -*- */
|
||||
|
||||
/*
|
||||
natsemi.c: An Etherboot driver for the NatSemi DP8381x series.
|
||||
|
||||
Copyright (C) 2001 Entity Cyber, Inc.
|
||||
|
||||
This development of this Etherboot driver was funded by
|
||||
|
||||
Sicom Systems: http://www.sicompos.com/
|
||||
|
||||
Author: Marty Connor (mdc@thinguin.org)
|
||||
Adapted from a Linux driver which was written by Donald Becker
|
||||
|
||||
This software may be used and distributed according to the terms
|
||||
of the GNU Public License (GPL), incorporated herein by reference.
|
||||
|
||||
Original Copyright Notice:
|
||||
|
||||
Written/copyright 1999-2001 by Donald Becker.
|
||||
|
||||
This software may be used and distributed according to the terms of
|
||||
the GNU General Public License (GPL), incorporated herein by reference.
|
||||
Drivers based on or derived from this code fall under the GPL and must
|
||||
retain the authorship, copyright and license notice. This file is not
|
||||
a complete program and may only be used when the entire operating
|
||||
system is licensed under the GPL. License for under other terms may be
|
||||
available. Contact the original author for details.
|
||||
|
||||
The original author may be reached as becker@scyld.com, or at
|
||||
Scyld Computing Corporation
|
||||
410 Severn Ave., Suite 210
|
||||
Annapolis MD 21403
|
||||
|
||||
Support information and updates available at
|
||||
http://www.scyld.com/network/netsemi.html
|
||||
|
||||
References:
|
||||
|
||||
http://www.scyld.com/expert/100mbps.html
|
||||
http://www.scyld.com/expert/NWay.html
|
||||
Datasheet is available from:
|
||||
http://www.national.com/pf/DP/DP83815.html
|
||||
|
||||
*/
|
||||
|
||||
/* Revision History */
|
||||
|
||||
/*
|
||||
29 May 2001 mdc 1.0
|
||||
Initial Release. Tested with Netgear FA311 and FA312 boards
|
||||
*/
|
||||
/* Includes */
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "pci.h"
|
||||
#include "cards.h"
|
||||
|
||||
/* defines */
|
||||
|
||||
#define OWN 0x80000000
|
||||
#define DSIZE 0x00000FFF
|
||||
#define CRC_SIZE 4
|
||||
|
||||
/* Time in ticks before concluding the transmitter is hung. */
|
||||
#define TX_TIMEOUT (4*TICKS_PER_SEC)
|
||||
|
||||
#define TX_BUF_SIZE 1536
|
||||
#define RX_BUF_SIZE 1536
|
||||
|
||||
#define NUM_RX_DESC 4 /* Number of Rx descriptor registers. */
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef signed char s8;
|
||||
typedef unsigned short u16;
|
||||
typedef signed short s16;
|
||||
typedef unsigned int u32;
|
||||
typedef signed int s32;
|
||||
|
||||
/* helpful macroes if on a big_endian machine for changing byte order.
|
||||
not strictly needed on Intel */
|
||||
#define le16_to_cpu(val) (val)
|
||||
#define cpu_to_le32(val) (val)
|
||||
#define get_unaligned(ptr) (*(ptr))
|
||||
#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
|
||||
#define get_u16(ptr) (*(u16 *)(ptr))
|
||||
#define virt_to_bus(x) ((unsigned long)x)
|
||||
#define virt_to_le32desc(addr) virt_to_bus(addr)
|
||||
|
||||
enum pcistuff {
|
||||
PCI_USES_IO = 0x01,
|
||||
PCI_USES_MEM = 0x02,
|
||||
PCI_USES_MASTER = 0x04,
|
||||
PCI_ADDR0 = 0x08,
|
||||
PCI_ADDR1 = 0x10,
|
||||
};
|
||||
|
||||
/* MMIO operations required */
|
||||
#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1)
|
||||
|
||||
/* Offsets to the device registers.
|
||||
Unlike software-only systems, device drivers interact with complex hardware.
|
||||
It's not useful to define symbolic names for every register bit in the
|
||||
device.
|
||||
*/
|
||||
enum register_offsets {
|
||||
ChipCmd = 0x00,
|
||||
ChipConfig = 0x04,
|
||||
EECtrl = 0x08,
|
||||
PCIBusCfg = 0x0C,
|
||||
IntrStatus = 0x10,
|
||||
IntrMask = 0x14,
|
||||
IntrEnable = 0x18,
|
||||
TxRingPtr = 0x20,
|
||||
TxConfig = 0x24,
|
||||
RxRingPtr = 0x30,
|
||||
RxConfig = 0x34,
|
||||
ClkRun = 0x3C,
|
||||
WOLCmd = 0x40,
|
||||
PauseCmd = 0x44,
|
||||
RxFilterAddr = 0x48,
|
||||
RxFilterData = 0x4C,
|
||||
BootRomAddr = 0x50,
|
||||
BootRomData = 0x54,
|
||||
SiliconRev = 0x58,
|
||||
StatsCtrl = 0x5C,
|
||||
StatsData = 0x60,
|
||||
RxPktErrs = 0x60,
|
||||
RxMissed = 0x68,
|
||||
RxCRCErrs = 0x64,
|
||||
PCIPM = 0x44,
|
||||
PhyStatus = 0xC0,
|
||||
MIntrCtrl = 0xC4,
|
||||
MIntrStatus = 0xC8,
|
||||
|
||||
/* These are from the spec, around page 78... on a separate table. */
|
||||
PGSEL = 0xCC,
|
||||
PMDCSR = 0xE4,
|
||||
TSTDAT = 0xFC,
|
||||
DSPCFG = 0xF4,
|
||||
SDCFG = 0x8C
|
||||
};
|
||||
|
||||
/* Bit in ChipCmd. */
|
||||
enum ChipCmdBits {
|
||||
ChipReset = 0x100,
|
||||
RxReset = 0x20,
|
||||
TxReset = 0x10,
|
||||
RxOff = 0x08,
|
||||
RxOn = 0x04,
|
||||
TxOff = 0x02,
|
||||
TxOn = 0x01
|
||||
};
|
||||
|
||||
/* Bits in the RxMode register. */
|
||||
enum rx_mode_bits {
|
||||
AcceptErr = 0x20,
|
||||
AcceptRunt = 0x10,
|
||||
AcceptBroadcast = 0xC0000000,
|
||||
AcceptMulticast = 0x00200000,
|
||||
AcceptAllMulticast = 0x20000000,
|
||||
AcceptAllPhys = 0x10000000,
|
||||
AcceptMyPhys = 0x08000000
|
||||
};
|
||||
|
||||
typedef struct _BufferDesc {
|
||||
u32 link;
|
||||
volatile u32 cmdsts;
|
||||
u32 bufptr;
|
||||
u32 software_use;
|
||||
} BufferDesc;
|
||||
|
||||
/* Bits in network_desc.status */
|
||||
enum desc_status_bits {
|
||||
DescOwn = 0x80000000,
|
||||
DescMore = 0x40000000,
|
||||
DescIntr = 0x20000000,
|
||||
DescNoCRC = 0x10000000,
|
||||
DescPktOK = 0x08000000,
|
||||
RxTooLong = 0x00400000
|
||||
};
|
||||
|
||||
/* Globals */
|
||||
|
||||
static int natsemi_debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */
|
||||
|
||||
const char *nic_name;
|
||||
|
||||
static u32 SavedClkRun;
|
||||
|
||||
|
||||
static unsigned short vendor, dev_id;
|
||||
static unsigned long ioaddr;
|
||||
|
||||
static unsigned int cur_rx;
|
||||
|
||||
static unsigned int advertising;
|
||||
|
||||
static unsigned int rx_config;
|
||||
static unsigned int tx_config;
|
||||
|
||||
/* Note: transmit and receive buffers and descriptors must be
|
||||
longword aligned
|
||||
*/
|
||||
|
||||
static BufferDesc txd __attribute__ ((aligned(4)));
|
||||
static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(4)));
|
||||
|
||||
#ifdef USE_LOWMEM_BUFFER
|
||||
#define txb ((char *)0x10000 - TX_BUF_SIZE)
|
||||
#define rxb ((char *)0x10000 - NUM_RX_DESC*RX_BUF_SIZE - TX_BUF_SIZE)
|
||||
#else
|
||||
static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(4)));
|
||||
static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE] __attribute__ ((aligned(4)));
|
||||
#endif
|
||||
|
||||
/* Function Prototypes */
|
||||
|
||||
struct nic *natsemi_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci);
|
||||
static int eeprom_read(long addr, int location);
|
||||
static int mdio_read(int phy_id, int location);
|
||||
static void natsemi_init(struct nic *nic);
|
||||
static void natsemi_reset(struct nic *nic);
|
||||
static void natsemi_init_rxfilter(struct nic *nic);
|
||||
static void natsemi_init_txd(struct nic *nic);
|
||||
static void natsemi_init_rxd(struct nic *nic);
|
||||
static void natsemi_set_rx_mode(struct nic *nic);
|
||||
static void natsemi_check_duplex(struct nic *nic);
|
||||
static void natsemi_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p);
|
||||
static int natsemi_poll(struct nic *nic);
|
||||
static void natsemi_disable(struct nic *nic);
|
||||
|
||||
/*
|
||||
* Function: natsemi_probe
|
||||
*
|
||||
* Description: Retrieves the MAC address of the card, and sets up some
|
||||
* globals required by other routines, and initializes the NIC, making it
|
||||
* ready to send and receive packets.
|
||||
*
|
||||
* Side effects:
|
||||
* leaves the ioaddress of the natsemi chip in the variable ioaddr.
|
||||
* leaves the natsemi initialized, and ready to recieve packets.
|
||||
*
|
||||
* Returns: struct nic *: pointer to NIC data structure
|
||||
*/
|
||||
|
||||
struct nic *
|
||||
natsemi_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci)
|
||||
{
|
||||
int i;
|
||||
int prev_eedata;
|
||||
u32 tmp;
|
||||
|
||||
if (io_addrs == 0 || *io_addrs == 0)
|
||||
return NULL;
|
||||
|
||||
/* initialize some commonly used globals */
|
||||
|
||||
ioaddr = *io_addrs & ~3;
|
||||
vendor = pci->vendor;
|
||||
dev_id = pci->dev_id;
|
||||
nic_name = pci->name;
|
||||
|
||||
adjust_pci_device(pci);
|
||||
|
||||
/* natsemi has a non-standard PM control register
|
||||
* in PCI config space. Some boards apparently need
|
||||
* to be brought to D0 in this manner.
|
||||
*/
|
||||
pcibios_read_config_dword(pci->bus, pci->devfn, PCIPM, &tmp);
|
||||
if (tmp & (0x03|0x100)) {
|
||||
/* D0 state, disable PME assertion */
|
||||
u32 newtmp = tmp & ~(0x03|0x100);
|
||||
pcibios_write_config_dword(pci->bus, pci->devfn, PCIPM, newtmp);
|
||||
}
|
||||
|
||||
/* get MAC address */
|
||||
|
||||
prev_eedata = eeprom_read(ioaddr, 6);
|
||||
for (i = 0; i < 3; i++) {
|
||||
int eedata = eeprom_read(ioaddr, i + 7);
|
||||
nic->node_addr[i*2] = (eedata << 1) + (prev_eedata >> 15);
|
||||
nic->node_addr[i*2+1] = eedata >> 7;
|
||||
prev_eedata = eedata;
|
||||
}
|
||||
|
||||
printf("\nnatsemi_probe: MAC addr %! at ioaddr %#hX\n",
|
||||
nic->node_addr, ioaddr);
|
||||
printf("natsemi_probe: Vendor:%#hX Device:%#hX\n", vendor, dev_id);
|
||||
|
||||
/* Reset the chip to erase any previous misconfiguration. */
|
||||
outl(ChipReset, ioaddr + ChipCmd);
|
||||
|
||||
advertising = mdio_read(1, 4);
|
||||
{
|
||||
u32 chip_config = inl(ioaddr + ChipConfig);
|
||||
printf("%s: Transceiver default autoneg. %s "
|
||||
"10%s %s duplex.\n",
|
||||
nic_name,
|
||||
chip_config & 0x2000 ? "enabled, advertise" : "disabled, force",
|
||||
chip_config & 0x4000 ? "0" : "",
|
||||
chip_config & 0x8000 ? "full" : "half");
|
||||
}
|
||||
printf("%s: Transceiver status %hX advertising %hX\n",
|
||||
nic_name, (int)inl(ioaddr + 0x84), advertising);
|
||||
|
||||
/* Disable PME:
|
||||
* The PME bit is initialized from the EEPROM contents.
|
||||
* PCI cards probably have PME disabled, but motherboard
|
||||
* implementations may have PME set to enable WakeOnLan.
|
||||
* With PME set the chip will scan incoming packets but
|
||||
* nothing will be written to memory. */
|
||||
SavedClkRun = inl(ioaddr + ClkRun);
|
||||
outl(SavedClkRun & ~0x100, ioaddr + ClkRun);
|
||||
|
||||
/* initialize device */
|
||||
natsemi_init(nic);
|
||||
|
||||
nic->reset = natsemi_init;
|
||||
nic->poll = natsemi_poll;
|
||||
nic->transmit = natsemi_transmit;
|
||||
nic->disable = natsemi_disable;
|
||||
|
||||
return nic;
|
||||
}
|
||||
|
||||
/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
|
||||
The EEPROM code is for the common 93c06/46 EEPROMs with 6 bit addresses.
|
||||
*/
|
||||
|
||||
/* Delay between EEPROM clock transitions.
|
||||
No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
|
||||
a delay. */
|
||||
#define eeprom_delay(ee_addr) inl(ee_addr)
|
||||
|
||||
enum EEPROM_Ctrl_Bits {
|
||||
EE_ShiftClk = 0x04,
|
||||
EE_DataIn = 0x01,
|
||||
EE_ChipSelect = 0x08,
|
||||
EE_DataOut = 0x02
|
||||
};
|
||||
|
||||
#define EE_Write0 (EE_ChipSelect)
|
||||
#define EE_Write1 (EE_ChipSelect | EE_DataIn)
|
||||
|
||||
/* The EEPROM commands include the alway-set leading bit. */
|
||||
enum EEPROM_Cmds {
|
||||
EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
|
||||
};
|
||||
|
||||
static int eeprom_read(long addr, int location)
|
||||
{
|
||||
int i;
|
||||
int retval = 0;
|
||||
int ee_addr = addr + EECtrl;
|
||||
int read_cmd = location | EE_ReadCmd;
|
||||
outl(EE_Write0, ee_addr);
|
||||
|
||||
/* Shift the read command bits out. */
|
||||
for (i = 10; i >= 0; i--) {
|
||||
short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
|
||||
outl(dataval, ee_addr);
|
||||
eeprom_delay(ee_addr);
|
||||
outl(dataval | EE_ShiftClk, ee_addr);
|
||||
eeprom_delay(ee_addr);
|
||||
}
|
||||
outl(EE_ChipSelect, ee_addr);
|
||||
eeprom_delay(ee_addr);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
outl(EE_ChipSelect | EE_ShiftClk, ee_addr);
|
||||
eeprom_delay(ee_addr);
|
||||
retval |= (inl(ee_addr) & EE_DataOut) ? 1 << i : 0;
|
||||
outl(EE_ChipSelect, ee_addr);
|
||||
eeprom_delay(ee_addr);
|
||||
}
|
||||
|
||||
/* Terminate the EEPROM access. */
|
||||
outl(EE_Write0, ee_addr);
|
||||
outl(0, ee_addr);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* MII transceiver control section.
|
||||
The 83815 series has an internal transceiver, and we present the
|
||||
management registers as if they were MII connected. */
|
||||
|
||||
static int mdio_read(int phy_id, int location)
|
||||
{
|
||||
if (phy_id == 1 && location < 32)
|
||||
return inl(ioaddr + 0x80 + (location<<2)) & 0xffff;
|
||||
else
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
/* Function: natsemi_init
|
||||
*
|
||||
* Description: resets the ethernet controller chip and configures
|
||||
* registers and data structures required for sending and receiving packets.
|
||||
*
|
||||
* Arguments: struct nic *nic: NIC data structure
|
||||
*
|
||||
* returns: void.
|
||||
*/
|
||||
|
||||
static void
|
||||
natsemi_init(struct nic *nic)
|
||||
{
|
||||
natsemi_reset(nic);
|
||||
|
||||
/* Disable PME:
|
||||
* The PME bit is initialized from the EEPROM contents.
|
||||
* PCI cards probably have PME disabled, but motherboard
|
||||
* implementations may have PME set to enable WakeOnLan.
|
||||
* With PME set the chip will scan incoming packets but
|
||||
* nothing will be written to memory. */
|
||||
outl(SavedClkRun & ~0x100, ioaddr + ClkRun);
|
||||
|
||||
natsemi_init_rxfilter(nic);
|
||||
|
||||
natsemi_init_txd(nic);
|
||||
natsemi_init_rxd(nic);
|
||||
|
||||
/* Initialize other registers. */
|
||||
/* Configure the PCI bus bursts and FIFO thresholds. */
|
||||
/* Configure for standard, in-spec Ethernet. */
|
||||
if (inl(ioaddr + ChipConfig) & 0x20000000) { /* Full duplex */
|
||||
tx_config = 0xD0801002;
|
||||
rx_config = 0x10000020;
|
||||
} else {
|
||||
tx_config = 0x10801002;
|
||||
rx_config = 0x0020;
|
||||
}
|
||||
outl(tx_config, ioaddr + TxConfig);
|
||||
outl(rx_config, ioaddr + RxConfig);
|
||||
|
||||
natsemi_check_duplex(nic);
|
||||
natsemi_set_rx_mode(nic);
|
||||
|
||||
outl(RxOn, ioaddr + ChipCmd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: natsemi_reset
|
||||
*
|
||||
* Description: soft resets the controller chip
|
||||
*
|
||||
* Arguments: struct nic *nic: NIC data structure
|
||||
*
|
||||
* Returns: void.
|
||||
*/
|
||||
static void
|
||||
natsemi_reset(struct nic *nic)
|
||||
{
|
||||
outl(ChipReset, ioaddr + ChipCmd);
|
||||
|
||||
/* On page 78 of the spec, they recommend some settings for "optimum
|
||||
performance" to be done in sequence. These settings optimize some
|
||||
of the 100Mbit autodetection circuitry. Also, we only want to do
|
||||
this for rev C of the chip.
|
||||
*/
|
||||
if (inl(ioaddr + SiliconRev) == 0x302) {
|
||||
outw(0x0001, ioaddr + PGSEL);
|
||||
outw(0x189C, ioaddr + PMDCSR);
|
||||
outw(0x0000, ioaddr + TSTDAT);
|
||||
outw(0x5040, ioaddr + DSPCFG);
|
||||
outw(0x008C, ioaddr + SDCFG);
|
||||
}
|
||||
/* Disable interrupts using the mask. */
|
||||
outl(0, ioaddr + IntrMask);
|
||||
outl(0, ioaddr + IntrEnable);
|
||||
}
|
||||
|
||||
/* Function: natsemi_init_rxfilter
|
||||
*
|
||||
* Description: sets receive filter address to our MAC address
|
||||
*
|
||||
* Arguments: struct nic *nic: NIC data structure
|
||||
*
|
||||
* returns: void.
|
||||
*/
|
||||
|
||||
static void
|
||||
natsemi_init_rxfilter(struct nic *nic)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ETH_ALEN; i += 2) {
|
||||
outl(i, ioaddr + RxFilterAddr);
|
||||
outw(nic->node_addr[i] + (nic->node_addr[i+1] << 8), ioaddr + RxFilterData);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: natsemi_init_txd
|
||||
*
|
||||
* Description: initializes the Tx descriptor
|
||||
*
|
||||
* Arguments: struct nic *nic: NIC data structure
|
||||
*
|
||||
* returns: void.
|
||||
*/
|
||||
|
||||
static void
|
||||
natsemi_init_txd(struct nic *nic)
|
||||
{
|
||||
txd.link = (u32) 0;
|
||||
txd.cmdsts = (u32) 0;
|
||||
txd.bufptr = (u32) &txb[0];
|
||||
|
||||
/* load Transmit Descriptor Register */
|
||||
outl((u32) &txd, ioaddr + TxRingPtr);
|
||||
if (natsemi_debug > 1)
|
||||
printf("natsemi_init_txd: TX descriptor register loaded with: %X\n",
|
||||
inl(ioaddr + TxRingPtr));
|
||||
}
|
||||
|
||||
/* Function: natsemi_init_rxd
|
||||
*
|
||||
* Description: initializes the Rx descriptor ring
|
||||
*
|
||||
* Arguments: struct nic *nic: NIC data structure
|
||||
*
|
||||
* Returns: void.
|
||||
*/
|
||||
|
||||
static void
|
||||
natsemi_init_rxd(struct nic *nic)
|
||||
{
|
||||
int i;
|
||||
|
||||
cur_rx = 0;
|
||||
|
||||
/* init RX descriptor */
|
||||
for (i = 0; i < NUM_RX_DESC; i++) {
|
||||
rxd[i].link = (i+1 < NUM_RX_DESC) ? (u32) &rxd[i+1] : (u32) &rxd[0];
|
||||
rxd[i].cmdsts = (u32) RX_BUF_SIZE;
|
||||
rxd[i].bufptr = (u32) &rxb[i*RX_BUF_SIZE];
|
||||
if (natsemi_debug > 1)
|
||||
printf("natsemi_init_rxd: rxd[%d]=%X link=%X cmdsts=%X bufptr=%X\n",
|
||||
i, &rxd[i], rxd[i].link, rxd[i].cmdsts, rxd[i].bufptr);
|
||||
}
|
||||
|
||||
/* load Receive Descriptor Register */
|
||||
outl((u32) &rxd[0], ioaddr + RxRingPtr);
|
||||
|
||||
if (natsemi_debug > 1)
|
||||
printf("natsemi_init_rxd: RX descriptor register loaded with: %X\n",
|
||||
inl(ioaddr + RxRingPtr));
|
||||
}
|
||||
|
||||
/* Function: natsemi_set_rx_mode
|
||||
*
|
||||
* Description:
|
||||
* sets the receive mode to accept all broadcast packets and packets
|
||||
* with our MAC address, and reject all multicast packets.
|
||||
*
|
||||
* Arguments: struct nic *nic: NIC data structure
|
||||
*
|
||||
* Returns: void.
|
||||
*/
|
||||
|
||||
static void natsemi_set_rx_mode(struct nic *nic)
|
||||
{
|
||||
u32 rx_mode = AcceptBroadcast | AcceptMyPhys;
|
||||
|
||||
outl(rx_mode, ioaddr + RxFilterAddr);
|
||||
}
|
||||
|
||||
static void natsemi_check_duplex(struct nic *nic)
|
||||
{
|
||||
int duplex = inl(ioaddr + ChipConfig) & 0x20000000 ? 1 : 0;
|
||||
|
||||
if (natsemi_debug)
|
||||
printf("%s: Setting %s-duplex based on negotiated link"
|
||||
" capability.\n", nic_name,
|
||||
duplex ? "full" : "half");
|
||||
if (duplex) {
|
||||
rx_config |= 0x10000000;
|
||||
tx_config |= 0xC0000000;
|
||||
} else {
|
||||
rx_config &= ~0x10000000;
|
||||
tx_config &= ~0xC0000000;
|
||||
}
|
||||
outl(tx_config, ioaddr + TxConfig);
|
||||
outl(rx_config, ioaddr + RxConfig);
|
||||
}
|
||||
|
||||
/* Function: natsemi_transmit
|
||||
*
|
||||
* Description: transmits a packet and waits for completion or timeout.
|
||||
*
|
||||
* Arguments: char d[6]: destination ethernet address.
|
||||
* unsigned short t: ethernet protocol type.
|
||||
* unsigned short s: size of the data-part of the packet.
|
||||
* char *p: the data for the packet.
|
||||
*
|
||||
* Returns: void.
|
||||
*/
|
||||
|
||||
static void
|
||||
natsemi_transmit(struct nic *nic,
|
||||
const char *d, /* Destination */
|
||||
unsigned int t, /* Type */
|
||||
unsigned int s, /* size */
|
||||
const char *p) /* Packet */
|
||||
{
|
||||
u32 status, to, nstype;
|
||||
volatile u32 tx_status;
|
||||
|
||||
/* Stop the transmitter */
|
||||
outl(TxOff, ioaddr + ChipCmd);
|
||||
|
||||
/* load Transmit Descriptor Register */
|
||||
outl((u32) &txd, ioaddr + TxRingPtr);
|
||||
if (natsemi_debug > 1)
|
||||
printf("natsemi_transmit: TX descriptor register loaded with: %X\n",
|
||||
inl(ioaddr + TxRingPtr));
|
||||
|
||||
memcpy(txb, d, ETH_ALEN);
|
||||
memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN);
|
||||
nstype = htons(t);
|
||||
memcpy(txb + 2 * ETH_ALEN, (char*)&nstype, 2);
|
||||
memcpy(txb + ETH_HLEN, p, s);
|
||||
|
||||
s += ETH_HLEN;
|
||||
s &= DSIZE;
|
||||
|
||||
if (natsemi_debug > 1)
|
||||
printf("natsemi_transmit: sending %d bytes ethtype %hX\n", (int) s, t);
|
||||
|
||||
/* pad to minimum packet size */
|
||||
while (s < ETH_ZLEN)
|
||||
txb[s++] = '\0';
|
||||
|
||||
/* set the transmit buffer descriptor and enable Transmit State Machine */
|
||||
txd.bufptr = (u32) &txb[0];
|
||||
txd.cmdsts = (u32) OWN | s;
|
||||
|
||||
/* restart the transmitter */
|
||||
outl(TxOn, ioaddr + ChipCmd);
|
||||
|
||||
if (natsemi_debug > 1)
|
||||
printf("natsemi_transmit: Queued Tx packet size %d.\n", (int) s);
|
||||
|
||||
to = currticks() + TX_TIMEOUT;
|
||||
|
||||
while (((tx_status=txd.cmdsts) & OWN) && (currticks() < to))
|
||||
/* wait */ ;
|
||||
|
||||
if (currticks() >= to) {
|
||||
printf("natsemi_transmit: TX Timeout! Tx status %X.\n", tx_status);
|
||||
}
|
||||
|
||||
if (!(tx_status & 0x08000000)) {
|
||||
printf("natsemi_transmit: Transmit error, Tx status %X.\n", tx_status);
|
||||
}
|
||||
}
|
||||
|
||||
/* Function: natsemi_poll
|
||||
*
|
||||
* Description: checks for a received packet and returns it if found.
|
||||
*
|
||||
* Arguments: struct nic *nic: NIC data structure
|
||||
*
|
||||
* Returns: 1 if packet was received.
|
||||
* 0 if no packet was received.
|
||||
*
|
||||
* Side effects:
|
||||
* Returns (copies) the packet to the array nic->packet.
|
||||
* Returns the length of the packet in nic->packetlen.
|
||||
*/
|
||||
|
||||
static int
|
||||
natsemi_poll(struct nic *nic)
|
||||
{
|
||||
u32 rx_status = rxd[cur_rx].cmdsts;
|
||||
int retstat = 0;
|
||||
|
||||
if (natsemi_debug > 2)
|
||||
printf("natsemi_poll: cur_rx:%d, status:%X\n", cur_rx, rx_status);
|
||||
|
||||
if (!(rx_status & OWN))
|
||||
return retstat;
|
||||
|
||||
if (natsemi_debug > 1)
|
||||
printf("natsemi_poll: got a packet: cur_rx:%d, status:%X\n",
|
||||
cur_rx, rx_status);
|
||||
|
||||
nic->packetlen = (rx_status & DSIZE) - CRC_SIZE;
|
||||
|
||||
if ((rx_status & (DescMore|DescPktOK|RxTooLong)) != DescPktOK) {
|
||||
/* corrupted packet received */
|
||||
printf("natsemi_poll: Corrupted packet received, buffer status = %X\n",
|
||||
rx_status);
|
||||
retstat = 0;
|
||||
} else {
|
||||
/* give packet to higher level routine */
|
||||
memcpy(nic->packet, (rxb + cur_rx*RX_BUF_SIZE), nic->packetlen);
|
||||
retstat = 1;
|
||||
}
|
||||
|
||||
/* return the descriptor and buffer to receive ring */
|
||||
rxd[cur_rx].cmdsts = RX_BUF_SIZE;
|
||||
rxd[cur_rx].bufptr = (u32) &rxb[cur_rx*RX_BUF_SIZE];
|
||||
|
||||
if (++cur_rx == NUM_RX_DESC)
|
||||
cur_rx = 0;
|
||||
|
||||
/* re-enable the potentially idle receive state machine */
|
||||
outl(RxOn, ioaddr + ChipCmd);
|
||||
|
||||
return retstat;
|
||||
}
|
||||
|
||||
/* Function: natsemi_disable
|
||||
*
|
||||
* Description: Turns off interrupts and stops Tx and Rx engines
|
||||
*
|
||||
* Arguments: struct nic *nic: NIC data structure
|
||||
*
|
||||
* Returns: void.
|
||||
*/
|
||||
|
||||
static void
|
||||
natsemi_disable(struct nic *nic)
|
||||
{
|
||||
/* Disable interrupts using the mask. */
|
||||
outl(0, ioaddr + IntrMask);
|
||||
outl(0, ioaddr + IntrEnable);
|
||||
|
||||
/* Stop the chip's Tx and Rx processes. */
|
||||
outl(RxOff | TxOff, ioaddr + ChipCmd);
|
||||
|
||||
/* Restore PME enable bit */
|
||||
outl(SavedClkRun, ioaddr + ClkRun);
|
||||
}
|
||||
@@ -1,371 +0,0 @@
|
||||
/**************************************************************************
|
||||
Etherboot - BOOTP/TFTP Bootstrap Program
|
||||
Driver for NI5010.
|
||||
Code freely taken from Jan-Pascal van Best and Andreas Mohr's
|
||||
Linux NI5010 driver.
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* 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, or (at
|
||||
* your option) any later version.
|
||||
*/
|
||||
|
||||
/* to get some global routines like printf */
|
||||
#include "etherboot.h"
|
||||
/* to get the interface to the body of the program */
|
||||
#include "nic.h"
|
||||
/* to get our own prototype */
|
||||
#include "cards.h"
|
||||
|
||||
/* ni5010.h file included verbatim */
|
||||
/*
|
||||
* Racal-Interlan ni5010 Ethernet definitions
|
||||
*
|
||||
* This is an extension to the Linux operating system, and is covered by the
|
||||
* same Gnu Public License that covers that work.
|
||||
*
|
||||
* copyrights (c) 1996 by Jan-Pascal van Best (jvbest@wi.leidenuniv.nl)
|
||||
*
|
||||
* I have done a look in the following sources:
|
||||
* crynwr-packet-driver by Russ Nelson
|
||||
*/
|
||||
|
||||
#define NI5010_BUFSIZE 2048 /* number of bytes in a buffer */
|
||||
|
||||
#define NI5010_MAGICVAL0 0x00 /* magic-values for ni5010 card */
|
||||
#define NI5010_MAGICVAL1 0x55
|
||||
#define NI5010_MAGICVAL2 0xAA
|
||||
|
||||
#define SA_ADDR0 0x02
|
||||
#define SA_ADDR1 0x07
|
||||
#define SA_ADDR2 0x01
|
||||
|
||||
/* The number of low I/O ports used by the ni5010 ethercard. */
|
||||
#define NI5010_IO_EXTENT 32
|
||||
|
||||
#define PRINTK(x) if (NI5010_DEBUG) printk x
|
||||
#define PRINTK2(x) if (NI5010_DEBUG>=2) printk x
|
||||
#define PRINTK3(x) if (NI5010_DEBUG>=3) printk x
|
||||
|
||||
/* The various IE command registers */
|
||||
#define EDLC_XSTAT (ioaddr + 0x00) /* EDLC transmit csr */
|
||||
#define EDLC_XCLR (ioaddr + 0x00) /* EDLC transmit "Clear IRQ" */
|
||||
#define EDLC_XMASK (ioaddr + 0x01) /* EDLC transmit "IRQ Masks" */
|
||||
#define EDLC_RSTAT (ioaddr + 0x02) /* EDLC receive csr */
|
||||
#define EDLC_RCLR (ioaddr + 0x02) /* EDLC receive "Clear IRQ" */
|
||||
#define EDLC_RMASK (ioaddr + 0x03) /* EDLC receive "IRQ Masks" */
|
||||
#define EDLC_XMODE (ioaddr + 0x04) /* EDLC transmit Mode */
|
||||
#define EDLC_RMODE (ioaddr + 0x05) /* EDLC receive Mode */
|
||||
#define EDLC_RESET (ioaddr + 0x06) /* EDLC RESET register */
|
||||
#define EDLC_TDR1 (ioaddr + 0x07) /* "Time Domain Reflectometry" reg1 */
|
||||
#define EDLC_ADDR (ioaddr + 0x08) /* EDLC station address, 6 bytes */
|
||||
/* 0x0E doesn't exist for r/w */
|
||||
#define EDLC_TDR2 (ioaddr + 0x0f) /* "Time Domain Reflectometry" reg2 */
|
||||
#define IE_GP (ioaddr + 0x10) /* GP pointer (word register) */
|
||||
/* 0x11 is 2nd byte of GP Pointer */
|
||||
#define IE_RCNT (ioaddr + 0x10) /* Count of bytes in rcv'd packet */
|
||||
/* 0x11 is 2nd byte of "Byte Count" */
|
||||
#define IE_MMODE (ioaddr + 0x12) /* Memory Mode register */
|
||||
#define IE_DMA_RST (ioaddr + 0x13) /* IE DMA Reset. write only */
|
||||
#define IE_ISTAT (ioaddr + 0x13) /* IE Interrupt Status. read only */
|
||||
#define IE_RBUF (ioaddr + 0x14) /* IE Receive Buffer port */
|
||||
#define IE_XBUF (ioaddr + 0x15) /* IE Transmit Buffer port */
|
||||
#define IE_SAPROM (ioaddr + 0x16) /* window on station addr prom */
|
||||
#define IE_RESET (ioaddr + 0x17) /* any write causes Board Reset */
|
||||
|
||||
/* bits in EDLC_XSTAT, interrupt clear on write, status when read */
|
||||
#define XS_TPOK 0x80 /* transmit packet successful */
|
||||
#define XS_CS 0x40 /* carrier sense */
|
||||
#define XS_RCVD 0x20 /* transmitted packet received */
|
||||
#define XS_SHORT 0x10 /* transmission media is shorted */
|
||||
#define XS_UFLW 0x08 /* underflow. iff failed board */
|
||||
#define XS_COLL 0x04 /* collision occurred */
|
||||
#define XS_16COLL 0x02 /* 16th collision occurred */
|
||||
#define XS_PERR 0x01 /* parity error */
|
||||
|
||||
#define XS_CLR_UFLW 0x08 /* clear underflow */
|
||||
#define XS_CLR_COLL 0x04 /* clear collision */
|
||||
#define XS_CLR_16COLL 0x02 /* clear 16th collision */
|
||||
#define XS_CLR_PERR 0x01 /* clear parity error */
|
||||
|
||||
/* bits in EDLC_XMASK, mask/enable transmit interrupts. register is r/w */
|
||||
#define XM_TPOK 0x80 /* =1 to enable Xmt Pkt OK interrupts */
|
||||
#define XM_RCVD 0x20 /* =1 to enable Xmt Pkt Rcvd ints */
|
||||
#define XM_UFLW 0x08 /* =1 to enable Xmt Underflow ints */
|
||||
#define XM_COLL 0x04 /* =1 to enable Xmt Collision ints */
|
||||
#define XM_COLL16 0x02 /* =1 to enable Xmt 16th Coll ints */
|
||||
#define XM_PERR 0x01 /* =1 to enable Xmt Parity Error ints */
|
||||
/* note: always clear this bit */
|
||||
#define XM_ALL (XM_TPOK | XM_RCVD | XM_UFLW | XM_COLL | XM_COLL16)
|
||||
|
||||
/* bits in EDLC_RSTAT, interrupt clear on write, status when read */
|
||||
#define RS_PKT_OK 0x80 /* received good packet */
|
||||
#define RS_RST_PKT 0x10 /* RESET packet received */
|
||||
#define RS_RUNT 0x08 /* Runt Pkt rcvd. Len < 64 Bytes */
|
||||
#define RS_ALIGN 0x04 /* Alignment error. not 8 bit aligned */
|
||||
#define RS_CRC_ERR 0x02 /* Bad CRC on rcvd pkt */
|
||||
#define RS_OFLW 0x01 /* overflow for rcv FIFO */
|
||||
#define RS_VALID_BITS ( RS_PKT_OK | RS_RST_PKT | RS_RUNT | RS_ALIGN | RS_CRC_ERR | RS_OFLW )
|
||||
/* all valid RSTAT bits */
|
||||
|
||||
#define RS_CLR_PKT_OK 0x80 /* clear rcvd packet interrupt */
|
||||
#define RS_CLR_RST_PKT 0x10 /* clear RESET packet received */
|
||||
#define RS_CLR_RUNT 0x08 /* clear Runt Pckt received */
|
||||
#define RS_CLR_ALIGN 0x04 /* clear Alignment error */
|
||||
#define RS_CLR_CRC_ERR 0x02 /* clear CRC error */
|
||||
#define RS_CLR_OFLW 0x01 /* clear rcv FIFO Overflow */
|
||||
|
||||
/* bits in EDLC_RMASK, mask/enable receive interrupts. register is r/w */
|
||||
#define RM_PKT_OK 0x80 /* =1 to enable rcvd good packet ints */
|
||||
#define RM_RST_PKT 0x10 /* =1 to enable RESET packet ints */
|
||||
#define RM_RUNT 0x08 /* =1 to enable Runt Pkt rcvd ints */
|
||||
#define RM_ALIGN 0x04 /* =1 to enable Alignment error ints */
|
||||
#define RM_CRC_ERR 0x02 /* =1 to enable Bad CRC error ints */
|
||||
#define RM_OFLW 0x01 /* =1 to enable overflow error ints */
|
||||
|
||||
/* bits in EDLC_RMODE, set Receive Packet mode. register is r/w */
|
||||
#define RMD_TEST 0x80 /* =1 for Chip testing. normally 0 */
|
||||
#define RMD_ADD_SIZ 0x10 /* =1 5-byte addr match. normally 0 */
|
||||
#define RMD_EN_RUNT 0x08 /* =1 enable runt rcv. normally 0 */
|
||||
#define RMD_EN_RST 0x04 /* =1 to rcv RESET pkt. normally 0 */
|
||||
|
||||
#define RMD_PROMISC 0x03 /* receive *all* packets. unusual */
|
||||
#define RMD_MULTICAST 0x02 /* receive multicasts too. unusual */
|
||||
#define RMD_BROADCAST 0x01 /* receive broadcasts & normal. usual */
|
||||
#define RMD_NO_PACKETS 0x00 /* don't receive any packets. unusual */
|
||||
|
||||
/* bits in EDLC_XMODE, set Transmit Packet mode. register is r/w */
|
||||
#define XMD_COLL_CNT 0xf0 /* coll's since success. read-only */
|
||||
#define XMD_IG_PAR 0x08 /* =1 to ignore parity. ALWAYS set */
|
||||
#define XMD_T_MODE 0x04 /* =1 to power xcvr. ALWAYS set this */
|
||||
#define XMD_LBC 0x02 /* =1 for loopback. normally set */
|
||||
#define XMD_DIS_C 0x01 /* =1 disables contention. normally 0 */
|
||||
|
||||
/* bits in EDLC_RESET, write only */
|
||||
#define RS_RESET 0x80 /* =1 to hold EDLC in reset state */
|
||||
|
||||
/* bits in IE_MMODE, write only */
|
||||
#define MM_EN_DMA 0x80 /* =1 begin DMA xfer, Cplt clrs it */
|
||||
#define MM_EN_RCV 0x40 /* =1 allows Pkt rcv. clr'd by rcv */
|
||||
#define MM_EN_XMT 0x20 /* =1 begin Xmt pkt. Cplt clrs it */
|
||||
#define MM_BUS_PAGE 0x18 /* =00 ALWAYS. Used when MUX=1 */
|
||||
#define MM_NET_PAGE 0x06 /* =00 ALWAYS. Used when MUX=0 */
|
||||
#define MM_MUX 0x01 /* =1 means Rcv Buff on system bus */
|
||||
/* =0 means Xmt Buff on system bus */
|
||||
|
||||
/* bits in IE_ISTAT, read only */
|
||||
#define IS_TDIAG 0x80 /* =1 if Diagnostic problem */
|
||||
#define IS_EN_RCV 0x20 /* =1 until frame is rcv'd cplt */
|
||||
#define IS_EN_XMT 0x10 /* =1 until frame is xmt'd cplt */
|
||||
#define IS_EN_DMA 0x08 /* =1 until DMA is cplt or aborted */
|
||||
#define IS_DMA_INT 0x04 /* =0 iff DMA done interrupt. */
|
||||
#define IS_R_INT 0x02 /* =0 iff unmasked Rcv interrupt */
|
||||
#define IS_X_INT 0x01 /* =0 iff unmasked Xmt interrupt */
|
||||
|
||||
/* NIC specific static variables go here */
|
||||
|
||||
static unsigned short ioaddr = 0;
|
||||
static unsigned int bufsize_rcv = 0;
|
||||
|
||||
#if 0
|
||||
static void show_registers(void)
|
||||
{
|
||||
printf("XSTAT %hhX ", inb(EDLC_XSTAT));
|
||||
printf("XMASK %hhX ", inb(EDLC_XMASK));
|
||||
printf("RSTAT %hhX ", inb(EDLC_RSTAT));
|
||||
printf("RMASK %hhX ", inb(EDLC_RMASK));
|
||||
printf("RMODE %hhX ", inb(EDLC_RMODE));
|
||||
printf("XMODE %hhX ", inb(EDLC_XMODE));
|
||||
printf("ISTAT %hhX\n", inb(IE_ISTAT));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void reset_receiver(void)
|
||||
{
|
||||
outw(0, IE_GP); /* Receive packet at start of buffer */
|
||||
outb(RS_VALID_BITS, EDLC_RCLR); /* Clear all pending Rcv interrupts */
|
||||
outb(MM_EN_RCV, IE_MMODE); /* Enable rcv */
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
RESET - Reset adapter
|
||||
***************************************************************************/
|
||||
static void ni5010_reset(struct nic *nic)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Reset the hardware here. Don't forget to set the station address. */
|
||||
outb(RS_RESET, EDLC_RESET); /* Hold up EDLC_RESET while configing board */
|
||||
outb(0, IE_RESET); /* Hardware reset of ni5010 board */
|
||||
outb(0, EDLC_XMASK); /* Disable all Xmt interrupts */
|
||||
outb(0, EDLC_RMASK); /* Disable all Rcv interrupt */
|
||||
outb(0xFF, EDLC_XCLR); /* Clear all pending Xmt interrupts */
|
||||
outb(0xFF, EDLC_RCLR); /* Clear all pending Rcv interrupts */
|
||||
outb(XMD_LBC, EDLC_XMODE); /* Only loopback xmits */
|
||||
/* Set the station address */
|
||||
for(i = 0; i < ETH_ALEN; i++)
|
||||
outb(nic->node_addr[i], EDLC_ADDR + i);
|
||||
outb(XMD_IG_PAR | XMD_T_MODE | XMD_LBC, EDLC_XMODE);
|
||||
/* Normal packet xmit mode */
|
||||
outb(RMD_BROADCAST, EDLC_RMODE);
|
||||
/* Receive broadcast and normal packets */
|
||||
reset_receiver();
|
||||
outb(0x00, EDLC_RESET); /* Un-reset the ni5010 */
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
POLL - Wait for a frame
|
||||
***************************************************************************/
|
||||
static int ni5010_poll(struct nic *nic)
|
||||
{
|
||||
int rcv_stat;
|
||||
|
||||
if (((rcv_stat = inb(EDLC_RSTAT)) & RS_VALID_BITS) != RS_PKT_OK) {
|
||||
outb(rcv_stat, EDLC_RSTAT); /* Clear the status */
|
||||
return (0);
|
||||
}
|
||||
outb(rcv_stat, EDLC_RCLR); /* Clear the status */
|
||||
nic->packetlen = inw(IE_RCNT);
|
||||
/* Read packet into buffer */
|
||||
outb(MM_MUX, IE_MMODE); /* Rcv buffer to system bus */
|
||||
outw(0, IE_GP); /* Seek to beginning of packet */
|
||||
insb(IE_RBUF, nic->packet, nic->packetlen);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
TRANSMIT - Transmit a frame
|
||||
***************************************************************************/
|
||||
static void ni5010_transmit(struct nic *nic,
|
||||
const char *d, /* Destination */
|
||||
unsigned int t, /* Type */
|
||||
unsigned int s, /* size */
|
||||
const char *p) /* Packet */
|
||||
{
|
||||
unsigned int len;
|
||||
int buf_offs, xmt_stat;
|
||||
unsigned long time;
|
||||
|
||||
len = s + ETH_HLEN;
|
||||
if (len < ETH_ZLEN)
|
||||
len = ETH_ZLEN;
|
||||
buf_offs = NI5010_BUFSIZE - len;
|
||||
outb(0, EDLC_RMASK); /* Mask all receive interrupts */
|
||||
outb(0, IE_MMODE); /* Put Xmit buffer on system bus */
|
||||
outb(0xFF, EDLC_RCLR); /* Clear out pending rcv interrupts */
|
||||
outw(buf_offs, IE_GP); /* Point GP at start of packet */
|
||||
outsb(IE_XBUF, d, ETH_ALEN); /* Put dst in buffer */
|
||||
outsb(IE_XBUF, nic->node_addr, ETH_ALEN);/* Put src in buffer */
|
||||
outb(t >> 8, IE_XBUF);
|
||||
outb(t, IE_XBUF);
|
||||
outsb(IE_XBUF, p, s); /* Put data in buffer */
|
||||
while (s++ < ETH_ZLEN - ETH_HLEN) /* Pad to min size */
|
||||
outb(0, IE_XBUF);
|
||||
outw(buf_offs, IE_GP); /* Rewrite where packet starts */
|
||||
/* should work without that outb() (Crynwr used it) */
|
||||
/*outb(MM_MUX, IE_MMODE);*/
|
||||
/* Xmt buffer to EDLC bus */
|
||||
outb(MM_EN_XMT | MM_MUX, IE_MMODE); /* Begin transmission */
|
||||
/* wait for transmit complete */
|
||||
while (((xmt_stat = inb(IE_ISTAT)) & IS_EN_XMT) != 0)
|
||||
;
|
||||
reset_receiver(); /* Immediately switch to receive */
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
DISABLE - Turn off ethernet interface
|
||||
***************************************************************************/
|
||||
static void ni5010_disable(struct nic *nic)
|
||||
{
|
||||
outb(0, IE_MMODE);
|
||||
outb(RS_RESET, EDLC_RESET);
|
||||
}
|
||||
|
||||
static inline int rd_port(void)
|
||||
{
|
||||
inb(IE_RBUF);
|
||||
return inb(IE_SAPROM);
|
||||
}
|
||||
|
||||
static int ni5010_probe1(struct nic *nic)
|
||||
{
|
||||
int i, boguscount = 40, data;
|
||||
|
||||
/* The tests are from the Linux NI5010 driver
|
||||
I don't understand it all, but if it works for them... */
|
||||
if (inb(ioaddr) == 0xFF)
|
||||
return (0);
|
||||
while ((rd_port() & rd_port() & rd_port()
|
||||
& rd_port() & rd_port() & rd_port()) != 0xFF)
|
||||
{
|
||||
if (boguscount-- <= 0)
|
||||
return (0);
|
||||
}
|
||||
for (i = 0; i < 32; i++)
|
||||
if ((data = rd_port()) != 0xFF)
|
||||
break;
|
||||
if (data == 0xFF)
|
||||
return (0);
|
||||
if (data == SA_ADDR0 && rd_port() == SA_ADDR1 && rd_port() == SA_ADDR2) {
|
||||
for (i = 0; i < 4; i++)
|
||||
rd_port();
|
||||
if (rd_port() != NI5010_MAGICVAL1 || rd_port() != NI5010_MAGICVAL2)
|
||||
return (0);
|
||||
} else
|
||||
return (0);
|
||||
for (i = 0; i < ETH_ALEN; i++) {
|
||||
outw(i, IE_GP);
|
||||
nic->node_addr[i] = inb(IE_SAPROM);
|
||||
}
|
||||
printf("\nNI5010 ioaddr %#hX, addr %!\n", ioaddr, nic->node_addr);
|
||||
/* get the size of the onboard receive buffer
|
||||
* higher addresses than bufsize are wrapped into real buffer
|
||||
* i.e. data for offs. 0x801 is written to 0x1 with a 2K onboard buffer
|
||||
*/
|
||||
if (bufsize_rcv == 0) {
|
||||
outb(1, IE_MMODE); /* Put Rcv buffer on system bus */
|
||||
outw(0, IE_GP); /* Point GP at start of packet */
|
||||
outb(0, IE_RBUF); /* set buffer byte 0 to 0 */
|
||||
for (i = 1; i < 0xFF; i++) {
|
||||
outw(i << 8, IE_GP); /* Point GP at packet size to be tested */
|
||||
outb(i, IE_RBUF);
|
||||
outw(0x0, IE_GP); /* Point GP at start of packet */
|
||||
data = inb(IE_RBUF);
|
||||
if (data == i) break;
|
||||
}
|
||||
bufsize_rcv = i << 8;
|
||||
outw(0, IE_GP); /* Point GP at start of packet */
|
||||
outb(0, IE_RBUF); /* set buffer byte 0 to 0 again */
|
||||
}
|
||||
printf("Bufsize rcv/xmt=%d/%d\n", bufsize_rcv, NI5010_BUFSIZE);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
PROBE - Look for an adapter, this routine's visible to the outside
|
||||
***************************************************************************/
|
||||
struct nic *ni5010_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||
{
|
||||
static unsigned short io_addrs[] = {
|
||||
0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0 };
|
||||
unsigned short *p;
|
||||
|
||||
/* if probe_addrs is 0, then use list above */
|
||||
if (probe_addrs == 0 || *probe_addrs == 0)
|
||||
probe_addrs = io_addrs;
|
||||
for (p = probe_addrs; (ioaddr = *p) != 0; p++) {
|
||||
if (ni5010_probe1(nic))
|
||||
break;
|
||||
}
|
||||
if (ioaddr == 0)
|
||||
return (0);
|
||||
ni5010_reset(nic);
|
||||
/* point to NIC specific routines */
|
||||
nic->reset = ni5010_reset;
|
||||
nic->poll = ni5010_poll;
|
||||
nic->transmit = ni5010_transmit;
|
||||
nic->disable = ni5010_disable;
|
||||
return (nic);
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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, or (at
|
||||
* your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef NIC_H
|
||||
#define NIC_H
|
||||
|
||||
/*
|
||||
* Structure returned from eth_probe and passed to other driver
|
||||
* functions.
|
||||
*/
|
||||
|
||||
struct nic
|
||||
{
|
||||
void (*reset)P((struct nic *));
|
||||
int (*poll)P((struct nic *));
|
||||
void (*transmit)P((struct nic *, const char *d,
|
||||
unsigned int t, unsigned int s, const char *p));
|
||||
void (*disable)P((struct nic *));
|
||||
int flags; /* driver specific flags */
|
||||
struct rom_info *rom_info; /* -> rom_info from main */
|
||||
unsigned char *node_addr;
|
||||
char *packet;
|
||||
unsigned int packetlen;
|
||||
void *priv_data; /* driver can hang private data here */
|
||||
};
|
||||
|
||||
#endif /* NIC_H */
|
||||
@@ -1,835 +0,0 @@
|
||||
/**************************************************************************
|
||||
ETHERBOOT - BOOTP/TFTP Bootstrap Program
|
||||
|
||||
Author: Martin Renters
|
||||
Date: May/94
|
||||
|
||||
This code is based heavily on David Greenman's if_ed.c driver
|
||||
|
||||
Copyright (C) 1993-1994, David Greenman, Martin Renters.
|
||||
This software may be used, modified, copied, distributed, and sold, in
|
||||
both source and binary form provided that the above copyright and these
|
||||
terms are retained. Under no circumstances are the authors responsible for
|
||||
the proper functioning of this software, nor do the authors assume any
|
||||
responsibility for damages incurred with its use.
|
||||
|
||||
3c503 support added by Bill Paul (wpaul@ctr.columbia.edu) on 11/15/94
|
||||
SMC8416 support added by Bill Paul (wpaul@ctr.columbia.edu) on 12/25/94
|
||||
3c503 PIO support added by Jim Hague (jim.hague@acm.org) on 2/17/98
|
||||
RX overrun by Klaus Espenlaub (espenlaub@informatik.uni-ulm.de) on 3/10/99
|
||||
parts taken from the Linux 8390 driver (by Donald Becker and Paul Gortmaker)
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "ns8390.h"
|
||||
#ifdef INCLUDE_NS8390
|
||||
#include "pci.h"
|
||||
#endif
|
||||
#include "cards.h"
|
||||
|
||||
static unsigned char eth_vendor, eth_flags, eth_laar;
|
||||
static unsigned short eth_nic_base, eth_asic_base;
|
||||
static unsigned char eth_memsize, eth_rx_start, eth_tx_start;
|
||||
static Address eth_bmem, eth_rmem;
|
||||
static unsigned char eth_drain_receiver;
|
||||
|
||||
#ifdef INCLUDE_WD
|
||||
static struct wd_board {
|
||||
const char *name;
|
||||
char id;
|
||||
char flags;
|
||||
char memsize;
|
||||
} wd_boards[] = {
|
||||
{"WD8003S", TYPE_WD8003S, 0, MEM_8192},
|
||||
{"WD8003E", TYPE_WD8003E, 0, MEM_8192},
|
||||
{"WD8013EBT", TYPE_WD8013EBT, FLAG_16BIT, MEM_16384},
|
||||
{"WD8003W", TYPE_WD8003W, 0, MEM_8192},
|
||||
{"WD8003EB", TYPE_WD8003EB, 0, MEM_8192},
|
||||
{"WD8013W", TYPE_WD8013W, FLAG_16BIT, MEM_16384},
|
||||
{"WD8003EP/WD8013EP",
|
||||
TYPE_WD8013EP, 0, MEM_8192},
|
||||
{"WD8013WC", TYPE_WD8013WC, FLAG_16BIT, MEM_16384},
|
||||
{"WD8013EPC", TYPE_WD8013EPC, FLAG_16BIT, MEM_16384},
|
||||
{"SMC8216T", TYPE_SMC8216T, FLAG_16BIT | FLAG_790, MEM_16384},
|
||||
{"SMC8216C", TYPE_SMC8216C, FLAG_16BIT | FLAG_790, MEM_16384},
|
||||
{"SMC8416T", TYPE_SMC8416T, FLAG_16BIT | FLAG_790, MEM_8192},
|
||||
{"SMC8416C/BT", TYPE_SMC8416C, FLAG_16BIT | FLAG_790, MEM_8192},
|
||||
{"SMC8013EBP", TYPE_SMC8013EBP,FLAG_16BIT, MEM_16384},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_3C503
|
||||
static unsigned char t503_output; /* AUI or internal xcvr (Thinnet) */
|
||||
#endif
|
||||
|
||||
#if defined(INCLUDE_WD)
|
||||
#define eth_probe wd_probe
|
||||
#if defined(INCLUDE_3C503) || defined(INCLUDE_NE) || defined(INCLUDE_NS8390)
|
||||
Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(INCLUDE_3C503)
|
||||
#define eth_probe t503_probe
|
||||
#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || defined(INCLUDE_WD)
|
||||
Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(INCLUDE_NE)
|
||||
#define eth_probe ne_probe
|
||||
#if defined(INCLUDE_NS8390) || defined(INCLUDE_3C503) || defined(INCLUDE_WD)
|
||||
Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(INCLUDE_NS8390)
|
||||
#define eth_probe nepci_probe
|
||||
#if defined(INCLUDE_NE) || defined(INCLUDE_3C503) || defined(INCLUDE_WD)
|
||||
Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(INCLUDE_3C503)
|
||||
#define ASIC_PIO _3COM_RFMSB
|
||||
#else
|
||||
#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390)
|
||||
#define ASIC_PIO NE_DATA
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM))
|
||||
/**************************************************************************
|
||||
ETH_PIO_READ - Read a frame via Programmed I/O
|
||||
**************************************************************************/
|
||||
static void eth_pio_read(unsigned int src, unsigned char *dst, unsigned int cnt)
|
||||
{
|
||||
if (eth_flags & FLAG_16BIT) { ++cnt; cnt &= ~1; }
|
||||
outb(D8390_COMMAND_RD2 |
|
||||
D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
|
||||
outb(cnt, eth_nic_base + D8390_P0_RBCR0);
|
||||
outb(cnt>>8, eth_nic_base + D8390_P0_RBCR1);
|
||||
outb(src, eth_nic_base + D8390_P0_RSAR0);
|
||||
outb(src>>8, eth_nic_base + D8390_P0_RSAR1);
|
||||
outb(D8390_COMMAND_RD0 |
|
||||
D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
|
||||
|
||||
#ifdef INCLUDE_3C503
|
||||
outb(src & 0xff, eth_asic_base + _3COM_DALSB);
|
||||
outb(src >> 8, eth_asic_base + _3COM_DAMSB);
|
||||
outb(t503_output | _3COM_CR_START, eth_asic_base + _3COM_CR);
|
||||
#endif
|
||||
|
||||
if (eth_flags & FLAG_16BIT)
|
||||
cnt >>= 1;
|
||||
|
||||
while(cnt--) {
|
||||
#ifdef INCLUDE_3C503
|
||||
while((inb(eth_asic_base + _3COM_STREG) & _3COM_STREG_DPRDY) == 0)
|
||||
;
|
||||
#endif
|
||||
|
||||
if (eth_flags & FLAG_16BIT) {
|
||||
*((unsigned short *)dst) = inw(eth_asic_base + ASIC_PIO);
|
||||
dst += 2;
|
||||
}
|
||||
else
|
||||
*(dst++) = inb(eth_asic_base + ASIC_PIO);
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_3C503
|
||||
outb(t503_output, eth_asic_base + _3COM_CR);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
ETH_PIO_WRITE - Write a frame via Programmed I/O
|
||||
**************************************************************************/
|
||||
static void eth_pio_write(const unsigned char *src, unsigned int dst, unsigned int cnt)
|
||||
{
|
||||
#ifdef COMPEX_RL2000_FIX
|
||||
unsigned int x;
|
||||
#endif /* COMPEX_RL2000_FIX */
|
||||
if (eth_flags & FLAG_16BIT) { ++cnt; cnt &= ~1; }
|
||||
outb(D8390_COMMAND_RD2 |
|
||||
D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
|
||||
outb(D8390_ISR_RDC, eth_nic_base + D8390_P0_ISR);
|
||||
outb(cnt, eth_nic_base + D8390_P0_RBCR0);
|
||||
outb(cnt>>8, eth_nic_base + D8390_P0_RBCR1);
|
||||
outb(dst, eth_nic_base + D8390_P0_RSAR0);
|
||||
outb(dst>>8, eth_nic_base + D8390_P0_RSAR1);
|
||||
outb(D8390_COMMAND_RD1 |
|
||||
D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
|
||||
|
||||
#ifdef INCLUDE_3C503
|
||||
outb(dst & 0xff, eth_asic_base + _3COM_DALSB);
|
||||
outb(dst >> 8, eth_asic_base + _3COM_DAMSB);
|
||||
|
||||
outb(t503_output | _3COM_CR_DDIR | _3COM_CR_START, eth_asic_base + _3COM_CR);
|
||||
#endif
|
||||
|
||||
if (eth_flags & FLAG_16BIT)
|
||||
cnt >>= 1;
|
||||
|
||||
while(cnt--)
|
||||
{
|
||||
#ifdef INCLUDE_3C503
|
||||
while((inb(eth_asic_base + _3COM_STREG) & _3COM_STREG_DPRDY) == 0)
|
||||
;
|
||||
#endif
|
||||
|
||||
if (eth_flags & FLAG_16BIT) {
|
||||
outw(*((unsigned short *)src), eth_asic_base + ASIC_PIO);
|
||||
src += 2;
|
||||
}
|
||||
else
|
||||
outb(*(src++), eth_asic_base + ASIC_PIO);
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_3C503
|
||||
outb(t503_output, eth_asic_base + _3COM_CR);
|
||||
#else
|
||||
#ifdef COMPEX_RL2000_FIX
|
||||
for (x = 0;
|
||||
x < COMPEX_RL2000_TRIES &&
|
||||
(inb(eth_nic_base + D8390_P0_ISR) & D8390_ISR_RDC)
|
||||
!= D8390_ISR_RDC;
|
||||
++x);
|
||||
if (x >= COMPEX_RL2000_TRIES)
|
||||
printf("Warning: Compex RL2000 aborted wait!\n");
|
||||
#endif /* COMPEX_RL2000_FIX */
|
||||
while((inb(eth_nic_base + D8390_P0_ISR) & D8390_ISR_RDC)
|
||||
!= D8390_ISR_RDC);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
/**************************************************************************
|
||||
ETH_PIO_READ - Dummy routine when NE2000 not compiled in
|
||||
**************************************************************************/
|
||||
static void eth_pio_read(unsigned int src, unsigned char *dst, unsigned int cnt) {}
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
NS8390_RESET - Reset adapter
|
||||
**************************************************************************/
|
||||
static void ns8390_reset(struct nic *nic)
|
||||
{
|
||||
int i;
|
||||
|
||||
eth_drain_receiver = 0;
|
||||
#ifdef INCLUDE_WD
|
||||
if (eth_flags & FLAG_790)
|
||||
outb(D8390_COMMAND_PS0 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
|
||||
else
|
||||
#endif
|
||||
outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 |
|
||||
D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
|
||||
if (eth_flags & FLAG_16BIT)
|
||||
outb(0x49, eth_nic_base+D8390_P0_DCR);
|
||||
else
|
||||
outb(0x48, eth_nic_base+D8390_P0_DCR);
|
||||
outb(0, eth_nic_base+D8390_P0_RBCR0);
|
||||
outb(0, eth_nic_base+D8390_P0_RBCR1);
|
||||
outb(0x20, eth_nic_base+D8390_P0_RCR); /* monitor mode */
|
||||
outb(2, eth_nic_base+D8390_P0_TCR);
|
||||
outb(eth_tx_start, eth_nic_base+D8390_P0_TPSR);
|
||||
outb(eth_rx_start, eth_nic_base+D8390_P0_PSTART);
|
||||
#ifdef INCLUDE_WD
|
||||
if (eth_flags & FLAG_790) outb(0, eth_nic_base + 0x09);
|
||||
#endif
|
||||
outb(eth_memsize, eth_nic_base+D8390_P0_PSTOP);
|
||||
outb(eth_memsize - 1, eth_nic_base+D8390_P0_BOUND);
|
||||
outb(0xFF, eth_nic_base+D8390_P0_ISR);
|
||||
outb(0, eth_nic_base+D8390_P0_IMR);
|
||||
#ifdef INCLUDE_WD
|
||||
if (eth_flags & FLAG_790)
|
||||
outb(D8390_COMMAND_PS1 |
|
||||
D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
|
||||
else
|
||||
#endif
|
||||
outb(D8390_COMMAND_PS1 |
|
||||
D8390_COMMAND_RD2 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
|
||||
for (i=0; i<ETH_ALEN; i++)
|
||||
outb(nic->node_addr[i], eth_nic_base+D8390_P1_PAR0+i);
|
||||
for (i=0; i<ETH_ALEN; i++)
|
||||
outb(0xFF, eth_nic_base+D8390_P1_MAR0+i);
|
||||
outb(eth_rx_start, eth_nic_base+D8390_P1_CURR);
|
||||
#ifdef INCLUDE_WD
|
||||
if (eth_flags & FLAG_790)
|
||||
outb(D8390_COMMAND_PS0 |
|
||||
D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
|
||||
else
|
||||
#endif
|
||||
outb(D8390_COMMAND_PS0 |
|
||||
D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
|
||||
outb(0xFF, eth_nic_base+D8390_P0_ISR);
|
||||
outb(0, eth_nic_base+D8390_P0_TCR);
|
||||
outb(4, eth_nic_base+D8390_P0_RCR); /* allow broadcast frames */
|
||||
|
||||
#ifdef INCLUDE_3C503
|
||||
/*
|
||||
* No way to tell whether or not we're supposed to use
|
||||
* the 3Com's transceiver unless the user tells us.
|
||||
* 'flags' should have some compile time default value
|
||||
* which can be changed from the command menu.
|
||||
*/
|
||||
t503_output = (nic->flags) ? 0 : _3COM_CR_XSEL;
|
||||
outb(t503_output, eth_asic_base + _3COM_CR);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int ns8390_poll(struct nic *nic);
|
||||
|
||||
#ifndef INCLUDE_3C503
|
||||
/**************************************************************************
|
||||
ETH_RX_OVERRUN - Bring adapter back to work after an RX overrun
|
||||
**************************************************************************/
|
||||
static void eth_rx_overrun(struct nic *nic)
|
||||
{
|
||||
int start_time;
|
||||
|
||||
#ifdef INCLUDE_WD
|
||||
if (eth_flags & FLAG_790)
|
||||
outb(D8390_COMMAND_PS0 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
|
||||
else
|
||||
#endif
|
||||
outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 |
|
||||
D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
|
||||
|
||||
/* wait for at least 1.6ms - we wait one timer tick */
|
||||
start_time = currticks();
|
||||
while (currticks() - start_time <= 1)
|
||||
/* Nothing */;
|
||||
|
||||
outb(0, eth_nic_base+D8390_P0_RBCR0); /* reset byte counter */
|
||||
outb(0, eth_nic_base+D8390_P0_RBCR1);
|
||||
|
||||
/*
|
||||
* Linux driver checks for interrupted TX here. This is not necessary,
|
||||
* because the transmit routine waits until the frame is sent.
|
||||
*/
|
||||
|
||||
/* enter loopback mode and restart NIC */
|
||||
outb(2, eth_nic_base+D8390_P0_TCR);
|
||||
#ifdef INCLUDE_WD
|
||||
if (eth_flags & FLAG_790)
|
||||
outb(D8390_COMMAND_PS0 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
|
||||
else
|
||||
#endif
|
||||
outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 |
|
||||
D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
|
||||
|
||||
/* clear the RX ring, acknowledge overrun interrupt */
|
||||
eth_drain_receiver = 1;
|
||||
while (ns8390_poll(nic))
|
||||
/* Nothing */;
|
||||
eth_drain_receiver = 0;
|
||||
outb(D8390_ISR_OVW, eth_nic_base+D8390_P0_ISR);
|
||||
|
||||
/* leave loopback mode - no packets to be resent (see Linux driver) */
|
||||
outb(0, eth_nic_base+D8390_P0_TCR);
|
||||
}
|
||||
#endif /* INCLUDE_3C503 */
|
||||
|
||||
/**************************************************************************
|
||||
NS8390_TRANSMIT - Transmit a frame
|
||||
**************************************************************************/
|
||||
static void ns8390_transmit(
|
||||
struct nic *nic,
|
||||
const char *d, /* Destination */
|
||||
unsigned int t, /* Type */
|
||||
unsigned int s, /* size */
|
||||
const char *p) /* Packet */
|
||||
{
|
||||
#ifdef INCLUDE_3C503
|
||||
if (!(eth_flags & FLAG_PIO)) {
|
||||
memcpy((char *)eth_bmem, d, ETH_ALEN); /* dst */
|
||||
memcpy((char *)eth_bmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
|
||||
*((char *)eth_bmem+12) = t>>8; /* type */
|
||||
*((char *)eth_bmem+13) = t;
|
||||
memcpy((char *)eth_bmem+ETH_HLEN, p, s);
|
||||
s += ETH_HLEN;
|
||||
while (s < ETH_ZLEN) *((char *)eth_bmem+(s++)) = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_WD
|
||||
/* Memory interface */
|
||||
if (eth_flags & FLAG_16BIT) {
|
||||
outb(eth_laar | WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
|
||||
inb(0x84);
|
||||
}
|
||||
if (eth_flags & FLAG_790) {
|
||||
outb(WD_MSR_MENB, eth_asic_base + WD_MSR);
|
||||
inb(0x84);
|
||||
}
|
||||
inb(0x84);
|
||||
memcpy((char *)eth_bmem, d, ETH_ALEN); /* dst */
|
||||
memcpy((char *)eth_bmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
|
||||
*((char *)eth_bmem+12) = t>>8; /* type */
|
||||
*((char *)eth_bmem+13) = t;
|
||||
memcpy((char *)eth_bmem+ETH_HLEN, p, s);
|
||||
s += ETH_HLEN;
|
||||
while (s < ETH_ZLEN) *((char *)eth_bmem+(s++)) = 0;
|
||||
if (eth_flags & FLAG_790) {
|
||||
outb(0, eth_asic_base + WD_MSR);
|
||||
inb(0x84);
|
||||
}
|
||||
if (eth_flags & FLAG_16BIT) {
|
||||
outb(eth_laar & ~WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
|
||||
inb(0x84);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(INCLUDE_3C503)
|
||||
if (eth_flags & FLAG_PIO) {
|
||||
#endif
|
||||
#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM))
|
||||
/* Programmed I/O */
|
||||
unsigned short type;
|
||||
type = (t >> 8) | (t << 8);
|
||||
eth_pio_write(d, eth_tx_start<<8, ETH_ALEN);
|
||||
eth_pio_write(nic->node_addr, (eth_tx_start<<8)+ETH_ALEN, ETH_ALEN);
|
||||
/* bcc generates worse code without (const+const) below */
|
||||
eth_pio_write((unsigned char *)&type, (eth_tx_start<<8)+(ETH_ALEN+ETH_ALEN), 2);
|
||||
eth_pio_write(p, (eth_tx_start<<8)+ETH_HLEN, s);
|
||||
s += ETH_HLEN;
|
||||
if (s < ETH_ZLEN) s = ETH_ZLEN;
|
||||
#endif
|
||||
#if defined(INCLUDE_3C503)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_WD
|
||||
if (eth_flags & FLAG_790)
|
||||
outb(D8390_COMMAND_PS0 |
|
||||
D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
|
||||
else
|
||||
#endif
|
||||
outb(D8390_COMMAND_PS0 |
|
||||
D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
|
||||
outb(eth_tx_start, eth_nic_base+D8390_P0_TPSR);
|
||||
outb(s, eth_nic_base+D8390_P0_TBCR0);
|
||||
outb(s>>8, eth_nic_base+D8390_P0_TBCR1);
|
||||
#ifdef INCLUDE_WD
|
||||
if (eth_flags & FLAG_790)
|
||||
outb(D8390_COMMAND_PS0 |
|
||||
D8390_COMMAND_TXP | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
|
||||
else
|
||||
#endif
|
||||
outb(D8390_COMMAND_PS0 |
|
||||
D8390_COMMAND_TXP | D8390_COMMAND_RD2 |
|
||||
D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
NS8390_POLL - Wait for a frame
|
||||
**************************************************************************/
|
||||
static int ns8390_poll(struct nic *nic)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char rstat, curr, next;
|
||||
unsigned short len, frag;
|
||||
unsigned short pktoff;
|
||||
unsigned char *p;
|
||||
struct ringbuffer pkthdr;
|
||||
|
||||
#ifndef INCLUDE_3C503
|
||||
/* avoid infinite recursion: see eth_rx_overrun() */
|
||||
if (!eth_drain_receiver && (inb(eth_nic_base+D8390_P0_ISR) & D8390_ISR_OVW)) {
|
||||
eth_rx_overrun(nic);
|
||||
return(0);
|
||||
}
|
||||
#endif /* INCLUDE_3C503 */
|
||||
rstat = inb(eth_nic_base+D8390_P0_RSR);
|
||||
if (!(rstat & D8390_RSTAT_PRX)) return(0);
|
||||
next = inb(eth_nic_base+D8390_P0_BOUND)+1;
|
||||
if (next >= eth_memsize) next = eth_rx_start;
|
||||
outb(D8390_COMMAND_PS1, eth_nic_base+D8390_P0_COMMAND);
|
||||
curr = inb(eth_nic_base+D8390_P1_CURR);
|
||||
outb(D8390_COMMAND_PS0, eth_nic_base+D8390_P0_COMMAND);
|
||||
if (curr >= eth_memsize) curr=eth_rx_start;
|
||||
if (curr == next) return(0);
|
||||
#ifdef INCLUDE_WD
|
||||
if (eth_flags & FLAG_16BIT) {
|
||||
outb(eth_laar | WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
|
||||
inb(0x84);
|
||||
}
|
||||
if (eth_flags & FLAG_790) {
|
||||
outb(WD_MSR_MENB, eth_asic_base + WD_MSR);
|
||||
inb(0x84);
|
||||
}
|
||||
inb(0x84);
|
||||
#endif
|
||||
pktoff = next << 8;
|
||||
if (eth_flags & FLAG_PIO)
|
||||
eth_pio_read(pktoff, (char *)&pkthdr, 4);
|
||||
else
|
||||
memcpy(&pkthdr, (char *)eth_rmem + pktoff, 4);
|
||||
pktoff += sizeof(pkthdr);
|
||||
/* incoming length includes FCS so must sub 4 */
|
||||
len = pkthdr.len - 4;
|
||||
if ((pkthdr.status & D8390_RSTAT_PRX) == 0 || len < ETH_ZLEN
|
||||
|| len > ETH_FRAME_LEN) {
|
||||
printf("Bogus packet, ignoring\n");
|
||||
return (0);
|
||||
}
|
||||
else {
|
||||
p = nic->packet;
|
||||
nic->packetlen = len; /* available to caller */
|
||||
frag = (eth_memsize << 8) - pktoff;
|
||||
if (len > frag) { /* We have a wrap-around */
|
||||
/* read first part */
|
||||
if (eth_flags & FLAG_PIO)
|
||||
eth_pio_read(pktoff, p, frag);
|
||||
else
|
||||
memcpy(p, (char *)eth_rmem + pktoff, frag);
|
||||
pktoff = eth_rx_start << 8;
|
||||
p += frag;
|
||||
len -= frag;
|
||||
}
|
||||
/* read second part */
|
||||
if (eth_flags & FLAG_PIO)
|
||||
eth_pio_read(pktoff, p, len);
|
||||
else
|
||||
memcpy(p, (char *)eth_rmem + pktoff, len);
|
||||
ret = 1;
|
||||
}
|
||||
#ifdef INCLUDE_WD
|
||||
if (eth_flags & FLAG_790) {
|
||||
outb(0, eth_asic_base + WD_MSR);
|
||||
inb(0x84);
|
||||
}
|
||||
if (eth_flags & FLAG_16BIT) {
|
||||
outb(eth_laar & ~WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
|
||||
inb(0x84);
|
||||
}
|
||||
inb(0x84);
|
||||
#endif
|
||||
next = pkthdr.next; /* frame number of next packet */
|
||||
if (next == eth_rx_start)
|
||||
next = eth_memsize;
|
||||
outb(next-1, eth_nic_base+D8390_P0_BOUND);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
NS8390_DISABLE - Turn off adapter
|
||||
**************************************************************************/
|
||||
static void ns8390_disable(struct nic *nic)
|
||||
{
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
ETH_PROBE - Look for an adapter
|
||||
**************************************************************************/
|
||||
#ifdef INCLUDE_NS8390
|
||||
struct nic *eth_probe(struct nic *nic, unsigned short *probe_addrs,
|
||||
struct pci_device *pci)
|
||||
#else
|
||||
struct nic *eth_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
struct wd_board *brd;
|
||||
unsigned short chksum;
|
||||
unsigned char c;
|
||||
eth_vendor = VENDOR_NONE;
|
||||
eth_drain_receiver = 0;
|
||||
|
||||
#ifdef INCLUDE_WD
|
||||
/******************************************************************
|
||||
Search for WD/SMC cards
|
||||
******************************************************************/
|
||||
for (eth_asic_base = WD_LOW_BASE; eth_asic_base <= WD_HIGH_BASE;
|
||||
eth_asic_base += 0x20) {
|
||||
chksum = 0;
|
||||
for (i=8; i<16; i++)
|
||||
chksum += inb(eth_asic_base+i);
|
||||
/* Extra checks to avoid soundcard */
|
||||
if ((chksum & 0xFF) == 0xFF &&
|
||||
inb(eth_asic_base+8) != 0xFF &&
|
||||
inb(eth_asic_base+9) != 0xFF)
|
||||
break;
|
||||
}
|
||||
if (eth_asic_base > WD_HIGH_BASE)
|
||||
return (0);
|
||||
/* We've found a board */
|
||||
eth_vendor = VENDOR_WD;
|
||||
eth_nic_base = eth_asic_base + WD_NIC_ADDR;
|
||||
c = inb(eth_asic_base+WD_BID); /* Get board id */
|
||||
for (brd = wd_boards; brd->name; brd++)
|
||||
if (brd->id == c) break;
|
||||
if (!brd->name) {
|
||||
printf("Unknown WD/SMC NIC type %hhX\n", c);
|
||||
return (0); /* Unknown type */
|
||||
}
|
||||
eth_flags = brd->flags;
|
||||
eth_memsize = brd->memsize;
|
||||
eth_tx_start = 0;
|
||||
eth_rx_start = D8390_TXBUF_SIZE;
|
||||
if ((c == TYPE_WD8013EP) &&
|
||||
(inb(eth_asic_base + WD_ICR) & WD_ICR_16BIT)) {
|
||||
eth_flags = FLAG_16BIT;
|
||||
eth_memsize = MEM_16384;
|
||||
}
|
||||
if ((c & WD_SOFTCONFIG) && (!(eth_flags & FLAG_790))) {
|
||||
eth_bmem = (0x80000 |
|
||||
((inb(eth_asic_base + WD_MSR) & 0x3F) << 13));
|
||||
} else
|
||||
eth_bmem = WD_DEFAULT_MEM;
|
||||
if (brd->id == TYPE_SMC8216T || brd->id == TYPE_SMC8216C) {
|
||||
*((unsigned int *)(eth_bmem + 8192)) = (unsigned int)0;
|
||||
if (*((unsigned int *)(eth_bmem + 8192))) {
|
||||
brd += 2;
|
||||
eth_memsize = brd->memsize;
|
||||
}
|
||||
}
|
||||
outb(0x80, eth_asic_base + WD_MSR); /* Reset */
|
||||
for (i=0; i<ETH_ALEN; i++) {
|
||||
nic->node_addr[i] = inb(i+eth_asic_base+WD_LAR);
|
||||
}
|
||||
printf("\n%s base %#hx, memory %#hx, addr %!\n",
|
||||
brd->name, eth_asic_base, eth_bmem, nic->node_addr);
|
||||
if (eth_flags & FLAG_790) {
|
||||
outb(WD_MSR_MENB, eth_asic_base+WD_MSR);
|
||||
outb((inb(eth_asic_base+0x04) |
|
||||
0x80), eth_asic_base+0x04);
|
||||
outb((((unsigned)eth_bmem >> 13) & 0x0F) |
|
||||
(((unsigned)eth_bmem >> 11) & 0x40) |
|
||||
(inb(eth_asic_base+0x0B) & 0xB0), eth_asic_base+0x0B);
|
||||
outb((inb(eth_asic_base+0x04) &
|
||||
~0x80), eth_asic_base+0x04);
|
||||
} else {
|
||||
outb((((unsigned)eth_bmem >> 13) & 0x3F) | 0x40, eth_asic_base+WD_MSR);
|
||||
}
|
||||
if (eth_flags & FLAG_16BIT) {
|
||||
if (eth_flags & FLAG_790) {
|
||||
eth_laar = inb(eth_asic_base + WD_LAAR);
|
||||
outb(WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
|
||||
} else {
|
||||
outb((eth_laar =
|
||||
WD_LAAR_L16EN | 1), eth_asic_base + WD_LAAR);
|
||||
/*
|
||||
The previous line used to be
|
||||
WD_LAAR_M16EN | WD_LAAR_L16EN | 1));
|
||||
jluke@deakin.edu.au reported that removing WD_LAAR_M16EN made
|
||||
it work for WD8013s. This seems to work for my 8013 boards. I
|
||||
don't know what is really happening. I wish I had data sheets
|
||||
or more time to decode the Linux driver. - Ken
|
||||
*/
|
||||
}
|
||||
inb(0x84);
|
||||
}
|
||||
#endif
|
||||
#ifdef INCLUDE_3C503
|
||||
/******************************************************************
|
||||
Search for 3Com 3c503 if no WD/SMC cards
|
||||
******************************************************************/
|
||||
if (eth_vendor == VENDOR_NONE) {
|
||||
int idx;
|
||||
int iobase_reg, membase_reg;
|
||||
static unsigned short base[] = {
|
||||
0x300, 0x310, 0x330, 0x350,
|
||||
0x250, 0x280, 0x2A0, 0x2E0, 0 };
|
||||
|
||||
/* Loop through possible addresses checking each one */
|
||||
|
||||
for (idx = 0; (eth_nic_base = base[idx]) != 0; ++idx) {
|
||||
|
||||
eth_asic_base = eth_nic_base + _3COM_ASIC_OFFSET;
|
||||
/*
|
||||
* Note that we use the same settings for both 8 and 16 bit cards:
|
||||
* both have an 8K bank of memory at page 1 while only the 16 bit
|
||||
* cards have a bank at page 0.
|
||||
*/
|
||||
eth_memsize = MEM_16384;
|
||||
eth_tx_start = 32;
|
||||
eth_rx_start = 32 + D8390_TXBUF_SIZE;
|
||||
|
||||
/* Check our base address. iobase and membase should */
|
||||
/* both have a maximum of 1 bit set or be 0. */
|
||||
|
||||
iobase_reg = inb(eth_asic_base + _3COM_BCFR);
|
||||
membase_reg = inb(eth_asic_base + _3COM_PCFR);
|
||||
|
||||
if ((iobase_reg & (iobase_reg - 1)) ||
|
||||
(membase_reg & (membase_reg - 1)))
|
||||
continue; /* nope */
|
||||
|
||||
/* Now get the shared memory address */
|
||||
|
||||
eth_flags = 0;
|
||||
|
||||
switch (membase_reg) {
|
||||
case _3COM_PCFR_DC000:
|
||||
eth_bmem = 0xdc000;
|
||||
break;
|
||||
case _3COM_PCFR_D8000:
|
||||
eth_bmem = 0xd8000;
|
||||
break;
|
||||
case _3COM_PCFR_CC000:
|
||||
eth_bmem = 0xcc000;
|
||||
break;
|
||||
case _3COM_PCFR_C8000:
|
||||
eth_bmem = 0xc8000;
|
||||
break;
|
||||
case _3COM_PCFR_PIO:
|
||||
eth_flags |= FLAG_PIO;
|
||||
eth_bmem = 0;
|
||||
break;
|
||||
default:
|
||||
continue; /* nope */
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (base[idx] == 0) /* not found */
|
||||
return (0);
|
||||
#ifndef T503_SHMEM
|
||||
eth_flags |= FLAG_PIO; /* force PIO mode */
|
||||
eth_bmem = 0;
|
||||
#endif
|
||||
eth_vendor = VENDOR_3COM;
|
||||
|
||||
|
||||
/* Need this to make ns8390_poll() happy. */
|
||||
|
||||
eth_rmem = eth_bmem - 0x2000;
|
||||
|
||||
/* Reset NIC and ASIC */
|
||||
|
||||
outb(_3COM_CR_RST | _3COM_CR_XSEL, eth_asic_base + _3COM_CR );
|
||||
outb(_3COM_CR_XSEL, eth_asic_base + _3COM_CR );
|
||||
|
||||
/* Get our ethernet address */
|
||||
|
||||
outb(_3COM_CR_EALO | _3COM_CR_XSEL, eth_asic_base + _3COM_CR);
|
||||
printf("\n3Com 3c503 base %#hx, ", eth_nic_base);
|
||||
if (eth_flags & FLAG_PIO)
|
||||
printf("PIO mode");
|
||||
else
|
||||
printf("memory %#hx", eth_bmem);
|
||||
for (i=0; i<ETH_ALEN; i++) {
|
||||
nic->node_addr[i] = inb(eth_nic_base+i);
|
||||
}
|
||||
printf(", %s, addr %!\n", nic->flags ? "AUI" : "internal xcvr",
|
||||
nic->node_addr);
|
||||
outb(_3COM_CR_XSEL, eth_asic_base + _3COM_CR);
|
||||
/*
|
||||
* Initialize GA configuration register. Set bank and enable shared
|
||||
* mem. We always use bank 1. Disable interrupts.
|
||||
*/
|
||||
outb(_3COM_GACFR_RSEL |
|
||||
_3COM_GACFR_MBS0 | _3COM_GACFR_TCM | _3COM_GACFR_NIM, eth_asic_base + _3COM_GACFR);
|
||||
|
||||
outb(0xff, eth_asic_base + _3COM_VPTR2);
|
||||
outb(0xff, eth_asic_base + _3COM_VPTR1);
|
||||
outb(0x00, eth_asic_base + _3COM_VPTR0);
|
||||
/*
|
||||
* Clear memory and verify that it worked (we use only 8K)
|
||||
*/
|
||||
|
||||
if (!(eth_flags & FLAG_PIO)) {
|
||||
memset((char *)eth_bmem, 0, 0x2000);
|
||||
for(i = 0; i < 0x2000; ++i)
|
||||
if (*(((char *)eth_bmem)+i)) {
|
||||
printf ("Failed to clear 3c503 shared mem.\n");
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Initialize GA page/start/stop registers.
|
||||
*/
|
||||
outb(eth_tx_start, eth_asic_base + _3COM_PSTR);
|
||||
outb(eth_memsize, eth_asic_base + _3COM_PSPR);
|
||||
}
|
||||
#endif
|
||||
#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390)
|
||||
/******************************************************************
|
||||
Search for NE1000/2000 if no WD/SMC or 3com cards
|
||||
******************************************************************/
|
||||
if (eth_vendor == VENDOR_NONE) {
|
||||
char romdata[16], testbuf[32];
|
||||
int idx;
|
||||
static char test[] = "NE*000 memory";
|
||||
static unsigned short base[] = {
|
||||
#ifdef NE_SCAN
|
||||
NE_SCAN,
|
||||
#endif
|
||||
0 };
|
||||
/* if no addresses supplied, fall back on defaults */
|
||||
if (probe_addrs == 0 || probe_addrs[0] == 0)
|
||||
probe_addrs = base;
|
||||
eth_bmem = 0; /* No shared memory */
|
||||
for (idx = 0; (eth_nic_base = probe_addrs[idx]) != 0; ++idx) {
|
||||
eth_flags = FLAG_PIO;
|
||||
eth_asic_base = eth_nic_base + NE_ASIC_OFFSET;
|
||||
eth_memsize = MEM_16384;
|
||||
eth_tx_start = 32;
|
||||
eth_rx_start = 32 + D8390_TXBUF_SIZE;
|
||||
c = inb(eth_asic_base + NE_RESET);
|
||||
outb(c, eth_asic_base + NE_RESET);
|
||||
inb(0x84);
|
||||
outb(D8390_COMMAND_STP |
|
||||
D8390_COMMAND_RD2, eth_nic_base + D8390_P0_COMMAND);
|
||||
outb(D8390_RCR_MON, eth_nic_base + D8390_P0_RCR);
|
||||
outb(D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR);
|
||||
outb(MEM_8192, eth_nic_base + D8390_P0_PSTART);
|
||||
outb(MEM_16384, eth_nic_base + D8390_P0_PSTOP);
|
||||
#ifdef NS8390_FORCE_16BIT
|
||||
eth_flags |= FLAG_16BIT; /* force 16-bit mode */
|
||||
#endif
|
||||
|
||||
eth_pio_write(test, 8192, sizeof(test));
|
||||
eth_pio_read(8192, testbuf, sizeof(test));
|
||||
if (!memcmp(test, testbuf, sizeof(test)))
|
||||
break;
|
||||
eth_flags |= FLAG_16BIT;
|
||||
eth_memsize = MEM_32768;
|
||||
eth_tx_start = 64;
|
||||
eth_rx_start = 64 + D8390_TXBUF_SIZE;
|
||||
outb(D8390_DCR_WTS |
|
||||
D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR);
|
||||
outb(MEM_16384, eth_nic_base + D8390_P0_PSTART);
|
||||
outb(MEM_32768, eth_nic_base + D8390_P0_PSTOP);
|
||||
eth_pio_write(test, 16384, sizeof(test));
|
||||
eth_pio_read(16384, testbuf, sizeof(test));
|
||||
if (!memcmp(testbuf, test, sizeof(test)))
|
||||
break;
|
||||
}
|
||||
if (eth_nic_base == 0)
|
||||
return (0);
|
||||
if (eth_nic_base > ISA_MAX_ADDR) /* PCI probably */
|
||||
eth_flags |= FLAG_16BIT;
|
||||
eth_vendor = VENDOR_NOVELL;
|
||||
eth_pio_read(0, romdata, sizeof(romdata));
|
||||
for (i=0; i<ETH_ALEN; i++) {
|
||||
nic->node_addr[i] = romdata[i + ((eth_flags & FLAG_16BIT) ? i : 0)];
|
||||
}
|
||||
printf("\nNE%c000 base %#hx, addr %!\n",
|
||||
(eth_flags & FLAG_16BIT) ? '2' : '1', eth_nic_base,
|
||||
nic->node_addr);
|
||||
}
|
||||
#endif
|
||||
if (eth_vendor == VENDOR_NONE)
|
||||
return(0);
|
||||
if (eth_vendor != VENDOR_3COM)
|
||||
eth_rmem = eth_bmem;
|
||||
ns8390_reset(nic);
|
||||
nic->reset = ns8390_reset;
|
||||
nic->poll = ns8390_poll;
|
||||
nic->transmit = ns8390_transmit;
|
||||
nic->disable = ns8390_disable;
|
||||
return(nic);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
||||
|
||||
@@ -1,238 +0,0 @@
|
||||
/**************************************************************************
|
||||
ETHERBOOT - BOOTP/TFTP Bootstrap Program
|
||||
|
||||
Author: Martin Renters
|
||||
Date: Jun/94
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
#define VENDOR_NONE 0
|
||||
#define VENDOR_WD 1
|
||||
#define VENDOR_NOVELL 2
|
||||
#define VENDOR_3COM 3
|
||||
|
||||
#define FLAG_PIO 0x01
|
||||
#define FLAG_16BIT 0x02
|
||||
#define FLAG_790 0x04
|
||||
|
||||
#define MEM_8192 32
|
||||
#define MEM_16384 64
|
||||
#define MEM_32768 128
|
||||
|
||||
#define ISA_MAX_ADDR 0x400
|
||||
|
||||
/**************************************************************************
|
||||
Western Digital/SMC Board Definitions
|
||||
**************************************************************************/
|
||||
#define WD_LOW_BASE 0x200
|
||||
#define WD_HIGH_BASE 0x3e0
|
||||
#ifndef WD_DEFAULT_MEM
|
||||
#define WD_DEFAULT_MEM 0xD0000
|
||||
#endif
|
||||
#define WD_NIC_ADDR 0x10
|
||||
|
||||
/**************************************************************************
|
||||
Western Digital/SMC ASIC Addresses
|
||||
**************************************************************************/
|
||||
#define WD_MSR 0x00
|
||||
#define WD_ICR 0x01
|
||||
#define WD_IAR 0x02
|
||||
#define WD_BIO 0x03
|
||||
#define WD_IRR 0x04
|
||||
#define WD_LAAR 0x05
|
||||
#define WD_IJR 0x06
|
||||
#define WD_GP2 0x07
|
||||
#define WD_LAR 0x08
|
||||
#define WD_BID 0x0E
|
||||
|
||||
#define WD_ICR_16BIT 0x01
|
||||
|
||||
#define WD_MSR_MENB 0x40
|
||||
|
||||
#define WD_LAAR_L16EN 0x40
|
||||
#define WD_LAAR_M16EN 0x80
|
||||
|
||||
#define WD_SOFTCONFIG 0x20
|
||||
|
||||
/**************************************************************************
|
||||
Western Digital/SMC Board Types
|
||||
**************************************************************************/
|
||||
#define TYPE_WD8003S 0x02
|
||||
#define TYPE_WD8003E 0x03
|
||||
#define TYPE_WD8013EBT 0x05
|
||||
#define TYPE_WD8003W 0x24
|
||||
#define TYPE_WD8003EB 0x25
|
||||
#define TYPE_WD8013W 0x26
|
||||
#define TYPE_WD8013EP 0x27
|
||||
#define TYPE_WD8013WC 0x28
|
||||
#define TYPE_WD8013EPC 0x29
|
||||
#define TYPE_SMC8216T 0x2a
|
||||
#define TYPE_SMC8216C 0x2b
|
||||
#define TYPE_SMC8416T 0x00 /* Bogus entries: the 8416 generates the */
|
||||
#define TYPE_SMC8416C 0x00 /* the same codes as the 8216. */
|
||||
#define TYPE_SMC8013EBP 0x2c
|
||||
|
||||
/**************************************************************************
|
||||
3com 3c503 definitions
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef _3COM_BASE
|
||||
#define _3COM_BASE 0x300
|
||||
#endif
|
||||
|
||||
#define _3COM_TX_PAGE_OFFSET_8BIT 0x20
|
||||
#define _3COM_TX_PAGE_OFFSET_16BIT 0x0
|
||||
#define _3COM_RX_PAGE_OFFSET_16BIT 0x20
|
||||
|
||||
#define _3COM_ASIC_OFFSET 0x400
|
||||
#define _3COM_NIC_OFFSET 0x0
|
||||
|
||||
#define _3COM_PSTR 0
|
||||
#define _3COM_PSPR 1
|
||||
|
||||
#define _3COM_BCFR 3
|
||||
#define _3COM_BCFR_2E0 0x01
|
||||
#define _3COM_BCFR_2A0 0x02
|
||||
#define _3COM_BCFR_280 0x04
|
||||
#define _3COM_BCFR_250 0x08
|
||||
#define _3COM_BCFR_350 0x10
|
||||
#define _3COM_BCFR_330 0x20
|
||||
#define _3COM_BCFR_310 0x40
|
||||
#define _3COM_BCFR_300 0x80
|
||||
#define _3COM_PCFR 4
|
||||
#define _3COM_PCFR_PIO 0
|
||||
#define _3COM_PCFR_C8000 0x10
|
||||
#define _3COM_PCFR_CC000 0x20
|
||||
#define _3COM_PCFR_D8000 0x40
|
||||
#define _3COM_PCFR_DC000 0x80
|
||||
#define _3COM_CR 6
|
||||
#define _3COM_CR_RST 0x01 /* Reset GA and NIC */
|
||||
#define _3COM_CR_XSEL 0x02 /* Transceiver select. BNC=1(def) AUI=0 */
|
||||
#define _3COM_CR_EALO 0x04 /* window EA PROM 0-15 to I/O base */
|
||||
#define _3COM_CR_EAHI 0x08 /* window EA PROM 16-31 to I/O base */
|
||||
#define _3COM_CR_SHARE 0x10 /* select interrupt sharing option */
|
||||
#define _3COM_CR_DBSEL 0x20 /* Double buffer select */
|
||||
#define _3COM_CR_DDIR 0x40 /* DMA direction select */
|
||||
#define _3COM_CR_START 0x80 /* Start DMA controller */
|
||||
#define _3COM_GACFR 5
|
||||
#define _3COM_GACFR_MBS0 0x01
|
||||
#define _3COM_GACFR_MBS1 0x02
|
||||
#define _3COM_GACFR_MBS2 0x04
|
||||
#define _3COM_GACFR_RSEL 0x08 /* enable shared memory */
|
||||
#define _3COM_GACFR_TEST 0x10 /* for GA testing */
|
||||
#define _3COM_GACFR_OWS 0x20 /* select 0WS access to GA */
|
||||
#define _3COM_GACFR_TCM 0x40 /* Mask DMA interrupts */
|
||||
#define _3COM_GACFR_NIM 0x80 /* Mask NIC interrupts */
|
||||
#define _3COM_STREG 7
|
||||
#define _3COM_STREG_REV 0x07 /* GA revision */
|
||||
#define _3COM_STREG_DIP 0x08 /* DMA in progress */
|
||||
#define _3COM_STREG_DTC 0x10 /* DMA terminal count */
|
||||
#define _3COM_STREG_OFLW 0x20 /* Overflow */
|
||||
#define _3COM_STREG_UFLW 0x40 /* Underflow */
|
||||
#define _3COM_STREG_DPRDY 0x80 /* Data port ready */
|
||||
#define _3COM_IDCFR 8
|
||||
#define _3COM_IDCFR_DRQ0 0x01 /* DMA request 1 select */
|
||||
#define _3COM_IDCFR_DRQ1 0x02 /* DMA request 2 select */
|
||||
#define _3COM_IDCFR_DRQ2 0x04 /* DMA request 3 select */
|
||||
#define _3COM_IDCFR_UNUSED 0x08 /* not used */
|
||||
#define _3COM_IDCFR_IRQ2 0x10 /* Interrupt request 2 select */
|
||||
#define _3COM_IDCFR_IRQ3 0x20 /* Interrupt request 3 select */
|
||||
#define _3COM_IDCFR_IRQ4 0x40 /* Interrupt request 4 select */
|
||||
#define _3COM_IDCFR_IRQ5 0x80 /* Interrupt request 5 select */
|
||||
#define _3COM_IRQ2 2
|
||||
#define _3COM_IRQ3 3
|
||||
#define _3COM_IRQ4 4
|
||||
#define _3COM_IRQ5 5
|
||||
#define _3COM_DAMSB 9
|
||||
#define _3COM_DALSB 0x0a
|
||||
#define _3COM_VPTR2 0x0b
|
||||
#define _3COM_VPTR1 0x0c
|
||||
#define _3COM_VPTR0 0x0d
|
||||
#define _3COM_RFMSB 0x0e
|
||||
#define _3COM_RFLSB 0x0f
|
||||
|
||||
/**************************************************************************
|
||||
NE1000/2000 definitions
|
||||
**************************************************************************/
|
||||
#define NE_ASIC_OFFSET 0x10
|
||||
#define NE_RESET 0x0F /* Used to reset card */
|
||||
#define NE_DATA 0x00 /* Used to read/write NIC mem */
|
||||
|
||||
#define COMPEX_RL2000_TRIES 200
|
||||
|
||||
/**************************************************************************
|
||||
8390 Register Definitions
|
||||
**************************************************************************/
|
||||
#define D8390_P0_COMMAND 0x00
|
||||
#define D8390_P0_PSTART 0x01
|
||||
#define D8390_P0_PSTOP 0x02
|
||||
#define D8390_P0_BOUND 0x03
|
||||
#define D8390_P0_TSR 0x04
|
||||
#define D8390_P0_TPSR 0x04
|
||||
#define D8390_P0_TBCR0 0x05
|
||||
#define D8390_P0_TBCR1 0x06
|
||||
#define D8390_P0_ISR 0x07
|
||||
#define D8390_P0_RSAR0 0x08
|
||||
#define D8390_P0_RSAR1 0x09
|
||||
#define D8390_P0_RBCR0 0x0A
|
||||
#define D8390_P0_RBCR1 0x0B
|
||||
#define D8390_P0_RSR 0x0C
|
||||
#define D8390_P0_RCR 0x0C
|
||||
#define D8390_P0_TCR 0x0D
|
||||
#define D8390_P0_DCR 0x0E
|
||||
#define D8390_P0_IMR 0x0F
|
||||
#define D8390_P1_COMMAND 0x00
|
||||
#define D8390_P1_PAR0 0x01
|
||||
#define D8390_P1_PAR1 0x02
|
||||
#define D8390_P1_PAR2 0x03
|
||||
#define D8390_P1_PAR3 0x04
|
||||
#define D8390_P1_PAR4 0x05
|
||||
#define D8390_P1_PAR5 0x06
|
||||
#define D8390_P1_CURR 0x07
|
||||
#define D8390_P1_MAR0 0x08
|
||||
|
||||
#define D8390_COMMAND_PS0 0x0 /* Page 0 select */
|
||||
#define D8390_COMMAND_PS1 0x40 /* Page 1 select */
|
||||
#define D8390_COMMAND_PS2 0x80 /* Page 2 select */
|
||||
#define D8390_COMMAND_RD2 0x20 /* Remote DMA control */
|
||||
#define D8390_COMMAND_RD1 0x10
|
||||
#define D8390_COMMAND_RD0 0x08
|
||||
#define D8390_COMMAND_TXP 0x04 /* transmit packet */
|
||||
#define D8390_COMMAND_STA 0x02 /* start */
|
||||
#define D8390_COMMAND_STP 0x01 /* stop */
|
||||
|
||||
#define D8390_RCR_MON 0x20 /* monitor mode */
|
||||
|
||||
#define D8390_DCR_FT1 0x40
|
||||
#define D8390_DCR_LS 0x08 /* Loopback select */
|
||||
#define D8390_DCR_WTS 0x01 /* Word transfer select */
|
||||
|
||||
#define D8390_ISR_PRX 0x01 /* successful recv */
|
||||
#define D8390_ISR_PTX 0x02 /* successful xmit */
|
||||
#define D8390_ISR_RXE 0x04 /* receive error */
|
||||
#define D8390_ISR_TXE 0x08 /* transmit error */
|
||||
#define D8390_ISR_OVW 0x10 /* Overflow */
|
||||
#define D8390_ISR_CNT 0x20 /* Counter overflow */
|
||||
#define D8390_ISR_RDC 0x40 /* Remote DMA complete */
|
||||
#define D8390_ISR_RST 0x80 /* reset */
|
||||
|
||||
#define D8390_RSTAT_PRX 0x01 /* successful recv */
|
||||
#define D8390_RSTAT_CRC 0x02 /* CRC error */
|
||||
#define D8390_RSTAT_FAE 0x04 /* Frame alignment error */
|
||||
#define D8390_RSTAT_OVER 0x08 /* FIFO overrun */
|
||||
|
||||
#define D8390_TXBUF_SIZE 6
|
||||
#define D8390_RXBUF_END 32
|
||||
#define D8390_PAGE_SIZE 256
|
||||
|
||||
struct ringbuffer {
|
||||
unsigned char status;
|
||||
unsigned char next;
|
||||
unsigned short len;
|
||||
};
|
||||
/*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
#ifndef __OSDEP_H__
|
||||
#define __OSDEP_H__
|
||||
|
||||
/*
|
||||
* 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, or (at
|
||||
* your option) any later version.
|
||||
*/
|
||||
|
||||
#define __LITTLE_ENDIAN /* x86 */
|
||||
|
||||
/* Taken from /usr/include/linux/hfs_sysdep.h */
|
||||
#if defined(__BIG_ENDIAN)
|
||||
# if !defined(__constant_htonl)
|
||||
# define __constant_htonl(x) (x)
|
||||
# endif
|
||||
# if !defined(__constant_htons)
|
||||
# define __constant_htons(x) (x)
|
||||
# endif
|
||||
#elif defined(__LITTLE_ENDIAN)
|
||||
# if !defined(__constant_htonl)
|
||||
# define __constant_htonl(x) \
|
||||
((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \
|
||||
(((unsigned long int)(x) & 0x0000ff00U) << 8) | \
|
||||
(((unsigned long int)(x) & 0x00ff0000U) >> 8) | \
|
||||
(((unsigned long int)(x) & 0xff000000U) >> 24)))
|
||||
# endif
|
||||
# if !defined(__constant_htons)
|
||||
# define __constant_htons(x) \
|
||||
((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
|
||||
(((unsigned short int)(x) & 0xff00) >> 8)))
|
||||
# endif
|
||||
#else
|
||||
# error "Don't know if bytes are big- or little-endian!"
|
||||
#endif
|
||||
|
||||
#define ntohl(x) \
|
||||
(__builtin_constant_p(x) ? \
|
||||
__constant_htonl((x)) : \
|
||||
__swap32(x))
|
||||
#define htonl(x) \
|
||||
(__builtin_constant_p(x) ? \
|
||||
__constant_htonl((x)) : \
|
||||
__swap32(x))
|
||||
#define ntohs(x) \
|
||||
(__builtin_constant_p(x) ? \
|
||||
__constant_htons((x)) : \
|
||||
__swap16(x))
|
||||
#define htons(x) \
|
||||
(__builtin_constant_p(x) ? \
|
||||
__constant_htons((x)) : \
|
||||
__swap16(x))
|
||||
|
||||
static inline unsigned long int __swap32(unsigned long int x)
|
||||
{
|
||||
__asm__("xchgb %b0,%h0\n\t"
|
||||
"rorl $16,%0\n\t"
|
||||
"xchgb %b0,%h0"
|
||||
: "=q" (x)
|
||||
: "0" (x));
|
||||
return x;
|
||||
}
|
||||
|
||||
static inline unsigned short int __swap16(unsigned short int x)
|
||||
{
|
||||
__asm__("xchgb %b0,%h0"
|
||||
: "=q" (x)
|
||||
: "0" (x));
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Make routines available to all */
|
||||
#define swap32(x) __swap32(x)
|
||||
#define swap16(x) __swap16(x)
|
||||
|
||||
#include "linux-asm-io.h"
|
||||
|
||||
typedef unsigned long Address;
|
||||
|
||||
/* ANSI prototyping macro */
|
||||
#ifdef __STDC__
|
||||
#define P(x) x
|
||||
#else
|
||||
#define P(x) ()
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
||||
@@ -1,374 +0,0 @@
|
||||
/*
|
||||
Etherboot DEC Tulip driver
|
||||
adapted by Ken Yap from
|
||||
|
||||
FreeBSD netboot DEC 21143 driver
|
||||
|
||||
Author: David Sharp
|
||||
date: Nov/98
|
||||
|
||||
Known to work on DEC DE500 using 21143-PC chipset.
|
||||
Even on cards with the same chipset there can be
|
||||
incompatablity problems with the way media selection
|
||||
and status LED settings are done. See comments below.
|
||||
|
||||
Some code fragments were taken from verious places,
|
||||
Ken Yap's etherboot, FreeBSD's if_de.c, and various
|
||||
Linux related files. DEC's manuals for the 21143 and
|
||||
SROM format were very helpful. The Linux de driver
|
||||
development page has a number of links to useful
|
||||
related information. Have a look at:
|
||||
ftp://cesdis.gsfc.nasa.gov/pub/linux/drivers/tulip-devel.html
|
||||
|
||||
*/
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "pci.h"
|
||||
#include "cards.h"
|
||||
#include "otulip.h"
|
||||
|
||||
static unsigned short vendor, dev_id;
|
||||
static unsigned short ioaddr;
|
||||
static unsigned int *membase;
|
||||
static unsigned char srom[1024];
|
||||
|
||||
#define BUFLEN 1536 /* must be longword divisable */
|
||||
/* buffers must be longword aligned */
|
||||
|
||||
/* transmit descriptor and buffer */
|
||||
static struct txdesc txd;
|
||||
|
||||
/* receive descriptor(s) and buffer(s) */
|
||||
#define NRXD 4
|
||||
static struct rxdesc rxd[NRXD];
|
||||
static int rxd_tail = 0;
|
||||
#ifdef USE_LOWMEM_BUFFER
|
||||
#define rxb ((char *)0x10000 - NRXD * BUFLEN)
|
||||
#define txb ((char *)0x10000 - NRXD * BUFLEN - BUFLEN)
|
||||
#else
|
||||
static unsigned char rxb[NRXD * BUFLEN];
|
||||
static unsigned char txb[BUFLEN];
|
||||
#endif
|
||||
|
||||
static unsigned char ehdr[ETH_HLEN]; /* buffer for ethernet header */
|
||||
|
||||
enum tulip_offsets {
|
||||
CSR0=0, CSR1=0x08, CSR2=0x10, CSR3=0x18, CSR4=0x20, CSR5=0x28,
|
||||
CSR6=0x30, CSR7=0x38, CSR8=0x40, CSR9=0x48, CSR10=0x50, CSR11=0x58,
|
||||
CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78 };
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* 21143 specific stuff */
|
||||
/***************************************************************************/
|
||||
|
||||
/* XXX assume 33MHz PCI bus, this is not very accurate and should be
|
||||
used only with gross over estimations of required delay times unless
|
||||
you tune UADJUST to your specific processor and I/O subsystem */
|
||||
|
||||
#define UADJUST 870
|
||||
static void udelay(unsigned long usec) {
|
||||
unsigned long i;
|
||||
for (i=((usec*UADJUST)/33)+1; i>0; i--) (void) TULIP_CSR_READ(csr_0);
|
||||
}
|
||||
|
||||
/* The following srom related code was taken from FreeBSD's if_de.c */
|
||||
/* with minor alterations to make it work here. the Linux code is */
|
||||
/* better but this was easier to use */
|
||||
|
||||
static void delay_300ns(void)
|
||||
{
|
||||
int idx;
|
||||
for (idx = (300 / 33) + 1; idx > 0; idx--)
|
||||
(void) TULIP_CSR_READ(csr_busmode);
|
||||
}
|
||||
|
||||
#define EMIT do { TULIP_CSR_WRITE(csr_srom_mii, csr); delay_300ns(); } while (0)
|
||||
|
||||
static void srom_idle(void)
|
||||
{
|
||||
unsigned bit, csr;
|
||||
|
||||
csr = SROMSEL ; EMIT;
|
||||
csr = SROMSEL | SROMRD; EMIT;
|
||||
csr ^= SROMCS; EMIT;
|
||||
csr ^= SROMCLKON; EMIT;
|
||||
/*
|
||||
* Write 25 cycles of 0 which will force the SROM to be idle.
|
||||
*/
|
||||
for (bit = 3 + SROM_BITWIDTH + 16; bit > 0; bit--) {
|
||||
csr ^= SROMCLKOFF; EMIT; /* clock low; data not valid */
|
||||
csr ^= SROMCLKON; EMIT; /* clock high; data valid */
|
||||
}
|
||||
csr ^= SROMCLKOFF; EMIT;
|
||||
csr ^= SROMCS; EMIT;
|
||||
csr = 0; EMIT;
|
||||
}
|
||||
|
||||
static void srom_read(void)
|
||||
{
|
||||
unsigned idx;
|
||||
const unsigned bitwidth = SROM_BITWIDTH;
|
||||
const unsigned cmdmask = (SROMCMD_RD << bitwidth);
|
||||
const unsigned msb = 1 << (bitwidth + 3 - 1);
|
||||
unsigned lastidx = (1 << bitwidth) - 1;
|
||||
|
||||
srom_idle();
|
||||
|
||||
for (idx = 0; idx <= lastidx; idx++) {
|
||||
unsigned lastbit, data, bits, bit, csr;
|
||||
csr = SROMSEL ; EMIT;
|
||||
csr = SROMSEL | SROMRD; EMIT;
|
||||
csr ^= SROMCSON; EMIT;
|
||||
csr ^= SROMCLKON; EMIT;
|
||||
|
||||
lastbit = 0;
|
||||
for (bits = idx|cmdmask, bit = bitwidth + 3; bit > 0; bit--, bits <<= 1)
|
||||
{
|
||||
const unsigned thisbit = bits & msb;
|
||||
csr ^= SROMCLKOFF; EMIT; /* clock low; data not valid */
|
||||
if (thisbit != lastbit) {
|
||||
csr ^= SROMDOUT; EMIT; /* clock low; invert data */
|
||||
} else {
|
||||
EMIT;
|
||||
}
|
||||
csr ^= SROMCLKON; EMIT; /* clock high; data valid */
|
||||
lastbit = thisbit;
|
||||
}
|
||||
csr ^= SROMCLKOFF; EMIT;
|
||||
|
||||
for (data = 0, bits = 0; bits < 16; bits++) {
|
||||
data <<= 1;
|
||||
csr ^= SROMCLKON; EMIT; /* clock high; data valid */
|
||||
data |= TULIP_CSR_READ(csr_srom_mii) & SROMDIN ? 1 : 0;
|
||||
csr ^= SROMCLKOFF; EMIT; /* clock low; data not valid */
|
||||
}
|
||||
srom[idx*2] = data & 0xFF;
|
||||
srom[idx*2+1] = data >> 8;
|
||||
csr = SROMSEL | SROMRD; EMIT;
|
||||
csr = 0; EMIT;
|
||||
}
|
||||
srom_idle();
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
ETH_RESET - Reset adapter
|
||||
***************************************************************************/
|
||||
static void tulip_reset(struct nic *nic)
|
||||
{
|
||||
int x,cnt=2;
|
||||
|
||||
outl(0x00000001, ioaddr + CSR0);
|
||||
udelay(1000);
|
||||
/* turn off reset and set cache align=16lword, burst=unlimit */
|
||||
outl(0x01A08000, ioaddr + CSR0);
|
||||
|
||||
/* for some reason the media selection does not take
|
||||
the first time se it is repeated. */
|
||||
|
||||
while(cnt--) {
|
||||
/* stop TX,RX processes */
|
||||
if (cnt == 1)
|
||||
outl(0x32404000, ioaddr + CSR6);
|
||||
else
|
||||
outl(0x32000040, ioaddr + CSR6);
|
||||
|
||||
/* XXX - media selection is vendor specific and hard coded right
|
||||
here. This should be fixed to use the hints in the SROM and
|
||||
allow media selection by the user at runtime. MII support
|
||||
should also be added. Support for chips other than the
|
||||
21143 should be added here as well */
|
||||
|
||||
/* start set to 10Mbps half-duplex */
|
||||
|
||||
/* setup SIA */
|
||||
outl(0x0, ioaddr + CSR13); /* reset SIA */
|
||||
outl(0x7f3f, ioaddr + CSR14);
|
||||
outl(0x8000008, ioaddr + CSR15);
|
||||
outl(0x0, ioaddr + CSR13);
|
||||
outl(0x1, ioaddr + CSR13);
|
||||
outl(0x2404000, ioaddr + CSR6);
|
||||
|
||||
/* initalize GP */
|
||||
outl(0x8af0008, ioaddr + CSR15);
|
||||
outl(0x50008, ioaddr + CSR15);
|
||||
|
||||
/* end set to 10Mbps half-duplex */
|
||||
|
||||
if (vendor == PCI_VENDOR_ID_MACRONIX && dev_id == PCI_DEVICE_ID_MX987x5) {
|
||||
/* do stuff for MX98715 */
|
||||
outl(0x01a80000, ioaddr + CSR6);
|
||||
outl(0xFFFFFFFF, ioaddr + CSR14);
|
||||
outl(0x00001000, ioaddr + CSR12);
|
||||
}
|
||||
|
||||
outl(0x0, ioaddr + CSR7); /* disable interrupts */
|
||||
|
||||
/* construct setup packet which is used by the 21143 to
|
||||
program its CAM to recognize interesting MAC addresses */
|
||||
|
||||
memset(&txd, 0, sizeof(struct txdesc));
|
||||
txd.buf1addr = &txb[0];
|
||||
txd.buf2addr = &txb[0]; /* just in case */
|
||||
txd.buf1sz = 192; /* setup packet must be 192 bytes */
|
||||
txd.buf2sz = 0;
|
||||
txd.control = 0x020; /* setup packet */
|
||||
txd.status = 0x80000000; /* give ownership to 21143 */
|
||||
|
||||
/* construct perfect filter frame */
|
||||
/* with mac address as first match */
|
||||
/* and broadcast address for all others */
|
||||
|
||||
for(x=0;x<192;x++) txb[x] = 0xff;
|
||||
txb[0] = nic->node_addr[0];
|
||||
txb[1] = nic->node_addr[1];
|
||||
txb[4] = nic->node_addr[2];
|
||||
txb[5] = nic->node_addr[3];
|
||||
txb[8] = nic->node_addr[4];
|
||||
txb[9] = nic->node_addr[5];
|
||||
outl((unsigned long)&txd, ioaddr + CSR4); /* set xmit buf */
|
||||
outl(0x2406000, ioaddr + CSR6); /* start transmiter */
|
||||
|
||||
udelay(50000); /* wait for the setup packet to be processed */
|
||||
|
||||
}
|
||||
|
||||
/* setup receive descriptor */
|
||||
{
|
||||
int x;
|
||||
for(x=0;x<NRXD;x++) {
|
||||
memset(&rxd[x], 0, sizeof(struct rxdesc));
|
||||
rxd[x].buf1addr = &rxb[x * BUFLEN];
|
||||
rxd[x].buf2addr = 0; /* not used */
|
||||
rxd[x].buf1sz = BUFLEN;
|
||||
rxd[x].buf2sz = 0; /* not used */
|
||||
rxd[x].control = 0x0;
|
||||
rxd[x].status = 0x80000000; /* give ownership it to 21143 */
|
||||
}
|
||||
rxd[NRXD - 1].control = 0x008; /* Set Receive end of ring on la
|
||||
st descriptor */
|
||||
rxd_tail = 0;
|
||||
}
|
||||
|
||||
/* tell DC211XX where to find rx descriptor list */
|
||||
outl((unsigned long)&rxd[0], ioaddr + CSR3);
|
||||
/* start the receiver */
|
||||
outl(0x2406002, ioaddr + CSR6);
|
||||
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
ETH_TRANSMIT - Transmit a frame
|
||||
***************************************************************************/
|
||||
static const char padmap[] = {
|
||||
0, 3, 2, 1};
|
||||
|
||||
static void tulip_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
|
||||
{
|
||||
unsigned long time;
|
||||
|
||||
/* setup ethernet header */
|
||||
|
||||
memcpy(ehdr, d, ETH_ALEN);
|
||||
memcpy(&ehdr[ETH_ALEN], nic->node_addr, ETH_ALEN);
|
||||
ehdr[ETH_ALEN*2] = (t >> 8) & 0xff;
|
||||
ehdr[ETH_ALEN*2+1] = t & 0xff;
|
||||
|
||||
/* setup the transmit descriptor */
|
||||
|
||||
memset(&txd, 0, sizeof(struct txdesc));
|
||||
|
||||
txd.buf1addr = &ehdr[0]; /* ethernet header */
|
||||
txd.buf1sz = ETH_HLEN;
|
||||
|
||||
txd.buf2addr = p; /* packet to transmit */
|
||||
txd.buf2sz = s;
|
||||
|
||||
txd.control = 0x188; /* LS+FS+TER */
|
||||
|
||||
txd.status = 0x80000000; /* give it to 21143 */
|
||||
|
||||
outl(inl(ioaddr + CSR6) & ~0x00004000, ioaddr + CSR6);
|
||||
outl((unsigned long)&txd, ioaddr + CSR4);
|
||||
outl(inl(ioaddr + CSR6) | 0x00004000, ioaddr + CSR6);
|
||||
|
||||
/* Wait for transmit to complete before returning. not well tested.
|
||||
|
||||
time = currticks();
|
||||
while(txd.status & 0x80000000) {
|
||||
if (currticks() - time > 20) {
|
||||
printf("transmit timeout.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
ETH_POLL - Wait for a frame
|
||||
***************************************************************************/
|
||||
static int tulip_poll(struct nic *nic)
|
||||
{
|
||||
if (rxd[rxd_tail].status & 0x80000000) return 0;
|
||||
|
||||
nic->packetlen = (rxd[rxd_tail].status & 0x3FFF0000) >> 16;
|
||||
|
||||
/* copy packet to working buffer */
|
||||
/* XXX - this copy could be avoided with a little more work
|
||||
but for now we are content with it because the optimised
|
||||
memcpy(, , ) is quite fast */
|
||||
|
||||
memcpy(nic->packet, rxb + rxd_tail * BUFLEN, nic->packetlen);
|
||||
|
||||
/* return the descriptor and buffer to recieve ring */
|
||||
rxd[rxd_tail].status = 0x80000000;
|
||||
rxd_tail++;
|
||||
if (rxd_tail == NRXD) rxd_tail = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void tulip_disable(struct nic *nic)
|
||||
{
|
||||
/* nothing for the moment */
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
ETH_PROBE - Look for an adapter
|
||||
***************************************************************************/
|
||||
struct nic *otulip_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (io_addrs == 0 || *io_addrs == 0)
|
||||
return (0);
|
||||
vendor = pci->vendor;
|
||||
dev_id = pci->dev_id;
|
||||
ioaddr = *io_addrs;
|
||||
membase = (unsigned int *)pci->membase;
|
||||
|
||||
/* wakeup chip */
|
||||
pcibios_write_config_dword(pci->bus,pci->devfn,0x40,0x00000000);
|
||||
|
||||
/* Stop the chip's Tx and Rx processes. */
|
||||
/* outl(inl(ioaddr + CSR6) & ~0x2002, ioaddr + CSR6); */
|
||||
/* Clear the missed-packet counter. */
|
||||
/* (volatile int)inl(ioaddr + CSR8); */
|
||||
|
||||
srom_read();
|
||||
|
||||
for (i=0; i < ETH_ALEN; i++)
|
||||
nic->node_addr[i] = srom[20+i];
|
||||
|
||||
printf("Tulip %! at ioaddr %#hX\n", nic->node_addr, ioaddr);
|
||||
|
||||
tulip_reset(nic);
|
||||
|
||||
nic->reset = tulip_reset;
|
||||
nic->poll = tulip_poll;
|
||||
nic->transmit = tulip_transmit;
|
||||
nic->disable = tulip_disable;
|
||||
return nic;
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/* mostly stolen from FreeBSD if_de.c, if_devar.h */
|
||||
|
||||
#define TULIP_CSR_READ(csr) (membase[csr*2])
|
||||
#define CSR_READ(csr) (membase[csr*2])
|
||||
#define TULIP_CSR_WRITE(csr, val) (membase[csr*2] = val)
|
||||
#define CSR_WRITE(csr, val) (membase[csr*2] = val)
|
||||
|
||||
#define csr_0 0
|
||||
#define csr_1 1
|
||||
#define csr_2 2
|
||||
#define csr_3 3
|
||||
#define csr_4 4
|
||||
#define csr_5 5
|
||||
#define csr_6 6
|
||||
#define csr_7 7
|
||||
#define csr_8 8
|
||||
#define csr_9 9
|
||||
#define csr_10 10
|
||||
#define csr_11 11
|
||||
#define csr_12 12
|
||||
#define csr_13 13
|
||||
#define csr_14 14
|
||||
#define csr_15 15
|
||||
|
||||
#define csr_busmode csr_0
|
||||
#define csr_txpoll csr_1
|
||||
#define csr_rxpoll csr_2
|
||||
#define csr_rxlist csr_3
|
||||
#define csr_txlist csr_4
|
||||
#define csr_status csr_5
|
||||
#define csr_command csr_6
|
||||
#define csr_intr csr_7
|
||||
#define csr_missed_frames csr_8
|
||||
#define csr_enetrom csr_9 /* 21040 */
|
||||
#define csr_reserved csr_10 /* 21040 */
|
||||
#define csr_full_duplex csr_11 /* 21040 */
|
||||
#define csr_bootrom csr_10 /* 21041/21140A/?? */
|
||||
#define csr_gp csr_12 /* 21140* */
|
||||
#define csr_watchdog csr_15 /* 21140* */
|
||||
#define csr_gp_timer csr_11 /* 21041/21140* */
|
||||
#define csr_srom_mii csr_9 /* 21041/21140* */
|
||||
#define csr_sia_status csr_12 /* 2104x */
|
||||
#define csr_sia_connectivity csr_13 /* 2104x */
|
||||
#define csr_sia_tx_rx csr_14 /* 2104x */
|
||||
#define csr_sia_general csr_15 /* 2104x */
|
||||
|
||||
#define SROMSEL 0x0800
|
||||
#define SROMCS 0x0001
|
||||
#define SROMCLKON 0x0002
|
||||
#define SROMCLKOFF 0x0002
|
||||
#define SROMRD 0x4000
|
||||
#define SROMWR 0x2000
|
||||
#define SROM_BITWIDTH 6
|
||||
#define SROMCMD_RD 6
|
||||
#define SROMCSON 0x0001
|
||||
#define SROMDOUT 0x0004
|
||||
#define SROMDIN 0x0008
|
||||
|
||||
|
||||
struct txdesc {
|
||||
unsigned long status; /* owner, status */
|
||||
unsigned long buf1sz:11, /* size of buffer 1 */
|
||||
buf2sz:11, /* size of buffer 2 */
|
||||
control:10; /* control bits */
|
||||
const unsigned char *buf1addr; /* buffer 1 address */
|
||||
const unsigned char *buf2addr; /* buffer 2 address */
|
||||
};
|
||||
|
||||
struct rxdesc {
|
||||
unsigned long status; /* owner, status */
|
||||
unsigned long buf1sz:11, /* size of buffer 1 */
|
||||
buf2sz:11, /* size of buffer 2 */
|
||||
control:10; /* control bits */
|
||||
unsigned char *buf1addr; /* buffer 1 address */
|
||||
unsigned char *buf2addr; /* buffer 2 address */
|
||||
};
|
||||
-501
@@ -1,501 +0,0 @@
|
||||
/*
|
||||
** Support for NE2000 PCI clones added David Monro June 1997
|
||||
** Generalised to other NICs by Ken Yap July 1997
|
||||
**
|
||||
** Most of this is taken from:
|
||||
**
|
||||
** /usr/src/linux/drivers/pci/pci.c
|
||||
** /usr/src/linux/include/linux/pci.h
|
||||
** /usr/src/linux/arch/i386/bios32.c
|
||||
** /usr/src/linux/include/linux/bios32.h
|
||||
** /usr/src/linux/drivers/net/ne.c
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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, or (at
|
||||
* your option) any later version.
|
||||
*/
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "pci.h"
|
||||
|
||||
/*#define DEBUG 1*/
|
||||
#define DEBUG 0
|
||||
|
||||
#ifdef CONFIG_PCI_DIRECT
|
||||
#define PCIBIOS_SUCCESSFUL 0x00
|
||||
|
||||
/*
|
||||
* Functions for accessing PCI configuration space with type 1 accesses
|
||||
*/
|
||||
|
||||
#define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3))
|
||||
|
||||
int pcibios_read_config_byte(unsigned int bus, unsigned int device_fn,
|
||||
unsigned int where, unsigned char *value)
|
||||
{
|
||||
outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
|
||||
*value = inb(0xCFC + (where&3));
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
int pcibios_read_config_word (unsigned int bus,
|
||||
unsigned int device_fn, unsigned int where, unsigned short *value)
|
||||
{
|
||||
outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
|
||||
*value = inw(0xCFC + (where&2));
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
int pcibios_read_config_dword (unsigned int bus, unsigned int device_fn,
|
||||
unsigned int where, unsigned int *value)
|
||||
{
|
||||
outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
|
||||
*value = inl(0xCFC);
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
int pcibios_write_config_byte (unsigned int bus, unsigned int device_fn,
|
||||
unsigned int where, unsigned char value)
|
||||
{
|
||||
outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
|
||||
outb(value, 0xCFC + (where&3));
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
int pcibios_write_config_word (unsigned int bus, unsigned int device_fn,
|
||||
unsigned int where, unsigned short value)
|
||||
{
|
||||
outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
|
||||
outw(value, 0xCFC + (where&2));
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
int pcibios_write_config_dword (unsigned int bus, unsigned int device_fn, unsigned int where, unsigned int value)
|
||||
{
|
||||
outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
|
||||
outl(value, 0xCFC);
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
#undef CONFIG_CMD
|
||||
|
||||
#else /* CONFIG_PCI_DIRECT not defined */
|
||||
|
||||
static struct {
|
||||
unsigned long address;
|
||||
unsigned short segment;
|
||||
} bios32_indirect = { 0, KERN_CODE_SEG };
|
||||
|
||||
static long pcibios_entry;
|
||||
static struct {
|
||||
unsigned long address;
|
||||
unsigned short segment;
|
||||
} pci_indirect = { 0, KERN_CODE_SEG };
|
||||
|
||||
static unsigned long bios32_service(unsigned long service)
|
||||
{
|
||||
unsigned char return_code; /* %al */
|
||||
unsigned long address; /* %ebx */
|
||||
unsigned long length; /* %ecx */
|
||||
unsigned long entry; /* %edx */
|
||||
unsigned long flags;
|
||||
|
||||
save_flags(flags);
|
||||
__asm__(
|
||||
#ifdef ABSOLUTE_WITHOUT_ASTERISK
|
||||
"lcall (%%edi)"
|
||||
#else
|
||||
"lcall *(%%edi)"
|
||||
#endif
|
||||
: "=a" (return_code),
|
||||
"=b" (address),
|
||||
"=c" (length),
|
||||
"=d" (entry)
|
||||
: "0" (service),
|
||||
"1" (0),
|
||||
"D" (&bios32_indirect));
|
||||
restore_flags(flags);
|
||||
|
||||
switch (return_code) {
|
||||
case 0:
|
||||
return address + entry;
|
||||
case 0x80: /* Not present */
|
||||
printf("bios32_service(%d) : not present\n", service);
|
||||
return 0;
|
||||
default: /* Shouldn't happen */
|
||||
printf("bios32_service(%d) : returned %#X, mail drew@colorado.edu\n",
|
||||
service, return_code);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int pcibios_read_config_byte(unsigned int bus,
|
||||
unsigned int device_fn, unsigned int where, unsigned char *value)
|
||||
{
|
||||
unsigned long ret;
|
||||
unsigned long bx = (bus << 8) | device_fn;
|
||||
unsigned long flags;
|
||||
|
||||
save_flags(flags);
|
||||
__asm__(
|
||||
#ifdef ABSOLUTE_WITHOUT_ASTERISK
|
||||
"lcall (%%esi)\n\t"
|
||||
#else
|
||||
"lcall *(%%esi)\n\t"
|
||||
#endif
|
||||
"jc 1f\n\t"
|
||||
"xor %%ah, %%ah\n"
|
||||
"1:"
|
||||
: "=c" (*value),
|
||||
"=a" (ret)
|
||||
: "1" (PCIBIOS_READ_CONFIG_BYTE),
|
||||
"b" (bx),
|
||||
"D" ((long) where),
|
||||
"S" (&pci_indirect));
|
||||
restore_flags(flags);
|
||||
return (int) (ret & 0xff00) >> 8;
|
||||
}
|
||||
|
||||
int pcibios_read_config_word(unsigned int bus,
|
||||
unsigned int device_fn, unsigned int where, unsigned short *value)
|
||||
{
|
||||
unsigned long ret;
|
||||
unsigned long bx = (bus << 8) | device_fn;
|
||||
unsigned long flags;
|
||||
|
||||
save_flags(flags);
|
||||
__asm__(
|
||||
#ifdef ABSOLUTE_WITHOUT_ASTERISK
|
||||
"lcall (%%esi)\n\t"
|
||||
#else
|
||||
"lcall *(%%esi)\n\t"
|
||||
#endif
|
||||
"jc 1f\n\t"
|
||||
"xor %%ah, %%ah\n"
|
||||
"1:"
|
||||
: "=c" (*value),
|
||||
"=a" (ret)
|
||||
: "1" (PCIBIOS_READ_CONFIG_WORD),
|
||||
"b" (bx),
|
||||
"D" ((long) where),
|
||||
"S" (&pci_indirect));
|
||||
restore_flags(flags);
|
||||
return (int) (ret & 0xff00) >> 8;
|
||||
}
|
||||
|
||||
int pcibios_read_config_dword(unsigned int bus,
|
||||
unsigned int device_fn, unsigned int where, unsigned int *value)
|
||||
{
|
||||
unsigned long ret;
|
||||
unsigned long bx = (bus << 8) | device_fn;
|
||||
unsigned long flags;
|
||||
|
||||
save_flags(flags);
|
||||
__asm__(
|
||||
#ifdef ABSOLUTE_WITHOUT_ASTERISK
|
||||
"lcall (%%esi)\n\t"
|
||||
#else
|
||||
"lcall *(%%esi)\n\t"
|
||||
#endif
|
||||
"jc 1f\n\t"
|
||||
"xor %%ah, %%ah\n"
|
||||
"1:"
|
||||
: "=c" (*value),
|
||||
"=a" (ret)
|
||||
: "1" (PCIBIOS_READ_CONFIG_DWORD),
|
||||
"b" (bx),
|
||||
"D" ((long) where),
|
||||
"S" (&pci_indirect));
|
||||
restore_flags(flags);
|
||||
return (int) (ret & 0xff00) >> 8;
|
||||
}
|
||||
|
||||
int pcibios_write_config_byte (unsigned int bus,
|
||||
unsigned int device_fn, unsigned int where, unsigned char value)
|
||||
{
|
||||
unsigned long ret;
|
||||
unsigned long bx = (bus << 8) | device_fn;
|
||||
unsigned long flags;
|
||||
|
||||
save_flags(flags); cli();
|
||||
__asm__(
|
||||
#ifdef ABSOLUTE_WITHOUT_ASTERISK
|
||||
"lcall (%%esi)\n\t"
|
||||
#else
|
||||
"lcall *(%%esi)\n\t"
|
||||
#endif
|
||||
"jc 1f\n\t"
|
||||
"xor %%ah, %%ah\n"
|
||||
"1:"
|
||||
: "=a" (ret)
|
||||
: "0" (PCIBIOS_WRITE_CONFIG_BYTE),
|
||||
"c" (value),
|
||||
"b" (bx),
|
||||
"D" ((long) where),
|
||||
"S" (&pci_indirect));
|
||||
restore_flags(flags);
|
||||
return (int) (ret & 0xff00) >> 8;
|
||||
}
|
||||
|
||||
int pcibios_write_config_word (unsigned int bus,
|
||||
unsigned int device_fn, unsigned int where, unsigned short value)
|
||||
{
|
||||
unsigned long ret;
|
||||
unsigned long bx = (bus << 8) | device_fn;
|
||||
unsigned long flags;
|
||||
|
||||
save_flags(flags); cli();
|
||||
__asm__(
|
||||
#ifdef ABSOLUTE_WITHOUT_ASTERISK
|
||||
"lcall (%%esi)\n\t"
|
||||
#else
|
||||
"lcall *(%%esi)\n\t"
|
||||
#endif
|
||||
"jc 1f\n\t"
|
||||
"xor %%ah, %%ah\n"
|
||||
"1:"
|
||||
: "=a" (ret)
|
||||
: "0" (PCIBIOS_WRITE_CONFIG_WORD),
|
||||
"c" (value),
|
||||
"b" (bx),
|
||||
"D" ((long) where),
|
||||
"S" (&pci_indirect));
|
||||
restore_flags(flags);
|
||||
return (int) (ret & 0xff00) >> 8;
|
||||
}
|
||||
|
||||
int pcibios_write_config_dword (unsigned int bus,
|
||||
unsigned int device_fn, unsigned int where, unsigned int value)
|
||||
{
|
||||
unsigned long ret;
|
||||
unsigned long bx = (bus << 8) | device_fn;
|
||||
unsigned long flags;
|
||||
|
||||
save_flags(flags); cli();
|
||||
__asm__(
|
||||
#ifdef ABSOLUTE_WITHOUT_ASTERISK
|
||||
"lcall (%%esi)\n\t"
|
||||
#else
|
||||
"lcall *(%%esi)\n\t"
|
||||
#endif
|
||||
"jc 1f\n\t"
|
||||
"xor %%ah, %%ah\n"
|
||||
"1:"
|
||||
: "=a" (ret)
|
||||
: "0" (PCIBIOS_WRITE_CONFIG_DWORD),
|
||||
"c" (value),
|
||||
"b" (bx),
|
||||
"D" ((long) where),
|
||||
"S" (&pci_indirect));
|
||||
restore_flags(flags);
|
||||
return (int) (ret & 0xff00) >> 8;
|
||||
}
|
||||
|
||||
static void check_pcibios(void)
|
||||
{
|
||||
unsigned long signature;
|
||||
unsigned char present_status;
|
||||
unsigned char major_revision;
|
||||
unsigned char minor_revision;
|
||||
unsigned long flags;
|
||||
int pack;
|
||||
|
||||
if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
|
||||
pci_indirect.address = pcibios_entry;
|
||||
|
||||
save_flags(flags);
|
||||
__asm__(
|
||||
#ifdef ABSOLUTE_WITHOUT_ASTERISK
|
||||
"lcall (%%edi)\n\t"
|
||||
#else
|
||||
"lcall *(%%edi)\n\t"
|
||||
#endif
|
||||
"jc 1f\n\t"
|
||||
"xor %%ah, %%ah\n"
|
||||
"1:\tshl $8, %%eax\n\t"
|
||||
"movw %%bx, %%ax"
|
||||
: "=d" (signature),
|
||||
"=a" (pack)
|
||||
: "1" (PCIBIOS_PCI_BIOS_PRESENT),
|
||||
"D" (&pci_indirect)
|
||||
: "bx", "cx");
|
||||
restore_flags(flags);
|
||||
|
||||
present_status = (pack >> 16) & 0xff;
|
||||
major_revision = (pack >> 8) & 0xff;
|
||||
minor_revision = pack & 0xff;
|
||||
if (present_status || (signature != PCI_SIGNATURE)) {
|
||||
printf("ERROR: BIOS32 says PCI BIOS, but no PCI "
|
||||
"BIOS????\n");
|
||||
pcibios_entry = 0;
|
||||
}
|
||||
#if DEBUG
|
||||
if (pcibios_entry) {
|
||||
printf ("pcibios_init : PCI BIOS revision %hhX.%hhX"
|
||||
" entry at %#X\n", major_revision,
|
||||
minor_revision, pcibios_entry);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void pcibios_init(void)
|
||||
{
|
||||
union bios32 *check;
|
||||
unsigned char sum;
|
||||
int i, length;
|
||||
unsigned long bios32_entry = 0;
|
||||
|
||||
/*
|
||||
* Follow the standard procedure for locating the BIOS32 Service
|
||||
* directory by scanning the permissible address range from
|
||||
* 0xe0000 through 0xfffff for a valid BIOS32 structure.
|
||||
*
|
||||
*/
|
||||
|
||||
for (check = (union bios32 *) 0xe0000; check <= (union bios32 *) 0xffff0; ++check) {
|
||||
if (check->fields.signature != BIOS32_SIGNATURE)
|
||||
continue;
|
||||
length = check->fields.length * 16;
|
||||
if (!length)
|
||||
continue;
|
||||
sum = 0;
|
||||
for (i = 0; i < length ; ++i)
|
||||
sum += check->chars[i];
|
||||
if (sum != 0)
|
||||
continue;
|
||||
if (check->fields.revision != 0) {
|
||||
printf("pcibios_init : unsupported revision %d at %#X, mail drew@colorado.edu\n",
|
||||
check->fields.revision, check);
|
||||
continue;
|
||||
}
|
||||
#if DEBUG
|
||||
printf("pcibios_init : BIOS32 Service Directory "
|
||||
"structure at %#X\n", check);
|
||||
#endif
|
||||
if (!bios32_entry) {
|
||||
if (check->fields.entry >= 0x100000) {
|
||||
printf("pcibios_init: entry in high "
|
||||
"memory, giving up\n");
|
||||
return;
|
||||
} else {
|
||||
bios32_entry = check->fields.entry;
|
||||
#if DEBUG
|
||||
printf("pcibios_init : BIOS32 Service Directory"
|
||||
" entry at %#X\n", bios32_entry);
|
||||
#endif
|
||||
bios32_indirect.address = bios32_entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bios32_entry)
|
||||
check_pcibios();
|
||||
}
|
||||
#endif /* CONFIG_PCI_DIRECT not defined*/
|
||||
|
||||
static void scan_bus(struct pci_device *pcidev)
|
||||
{
|
||||
unsigned int devfn, l, bus, buses;
|
||||
unsigned char hdr_type = 0;
|
||||
unsigned short vendor, device;
|
||||
unsigned int membase, ioaddr, romaddr;
|
||||
int i, reg;
|
||||
unsigned int pci_ioaddr = 0;
|
||||
|
||||
/* Scan all PCI buses, until we find our card.
|
||||
* We could be smart only scan the required busses but that
|
||||
* is error prone, and tricky.
|
||||
* By scanning all possible pci busses in order we should find
|
||||
* our card eventually.
|
||||
*/
|
||||
buses=256;
|
||||
for (bus = 0; bus < buses; ++bus) {
|
||||
for (devfn = 0; devfn < 0xff; ++devfn) {
|
||||
if (PCI_FUNC (devfn) == 0)
|
||||
pcibios_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type);
|
||||
else if (!(hdr_type & 0x80)) /* not a multi-function device */
|
||||
continue;
|
||||
pcibios_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l);
|
||||
/* some broken boards return 0 if a slot is empty: */
|
||||
if (l == 0xffffffff || l == 0x00000000) {
|
||||
hdr_type = 0;
|
||||
continue;
|
||||
}
|
||||
vendor = l & 0xffff;
|
||||
device = (l >> 16) & 0xffff;
|
||||
|
||||
#if DEBUG
|
||||
printf("bus %hhX, function %hhX, vendor %hX, device %hX\n",
|
||||
bus, devfn, vendor, device);
|
||||
#endif
|
||||
for (i = 0; pcidev[i].vendor != 0; i++) {
|
||||
if (vendor != pcidev[i].vendor
|
||||
|| device != pcidev[i].dev_id)
|
||||
continue;
|
||||
pcidev[i].devfn = devfn;
|
||||
pcidev[i].bus = bus;
|
||||
for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) {
|
||||
pcibios_read_config_dword(bus, devfn, reg, &ioaddr);
|
||||
|
||||
if ((ioaddr & PCI_BASE_ADDRESS_IO_MASK) == 0 || (ioaddr & PCI_BASE_ADDRESS_SPACE_IO) == 0)
|
||||
continue;
|
||||
/* Strip the I/O address out of the returned value */
|
||||
ioaddr &= PCI_BASE_ADDRESS_IO_MASK;
|
||||
/* Get the memory base address */
|
||||
pcibios_read_config_dword(bus, devfn,
|
||||
PCI_BASE_ADDRESS_1, &membase);
|
||||
/* Get the ROM base address */
|
||||
pcibios_read_config_dword(bus, devfn, PCI_ROM_ADDRESS, &romaddr);
|
||||
romaddr >>= 10;
|
||||
printf("Found %s at %#hx, ROM address %#hx\n",
|
||||
pcidev[i].name, ioaddr, romaddr);
|
||||
/* Take the first one or the one that matches in boot ROM address */
|
||||
if (pci_ioaddr == 0 || romaddr == ((unsigned long) rom.rom_segment << 4)) {
|
||||
pcidev[i].membase = membase;
|
||||
pcidev[i].ioaddr = ioaddr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void eth_pci_init(struct pci_device *pcidev)
|
||||
{
|
||||
#ifndef CONFIG_PCI_DIRECT
|
||||
pcibios_init();
|
||||
if (!pcibios_entry) {
|
||||
printf("pci_init: no BIOS32 detected\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
scan_bus(pcidev);
|
||||
/* return values are in pcidev structures */
|
||||
}
|
||||
|
||||
/*
|
||||
* Set device to be a busmaster in case BIOS neglected to do so.
|
||||
* Also adjust PCI latency timer to a reasonable value, 32.
|
||||
*/
|
||||
void adjust_pci_device(struct pci_device *p)
|
||||
{
|
||||
unsigned short new_command, pci_command;
|
||||
unsigned char pci_latency;
|
||||
|
||||
pcibios_read_config_word(p->bus, p->devfn, PCI_COMMAND, &pci_command);
|
||||
new_command = pci_command | PCI_COMMAND_MASTER|PCI_COMMAND_IO;
|
||||
if (pci_command != new_command) {
|
||||
printf("The PCI BIOS has not enabled this device!\nUpdating PCI command %hX->%hX. pci_bus %hhX pci_device_fn %hhX\n",
|
||||
pci_command, new_command, p->bus, p->devfn);
|
||||
pcibios_write_config_word(p->bus, p->devfn, PCI_COMMAND, new_command);
|
||||
}
|
||||
pcibios_read_config_byte(p->bus, p->devfn, PCI_LATENCY_TIMER, &pci_latency);
|
||||
if (pci_latency < 32) {
|
||||
printf("PCI latency timer (CFLT) is unreasonably low at %d. Setting to 32 clocks.\n", pci_latency);
|
||||
pcibios_write_config_byte(p->bus, p->devfn, PCI_LATENCY_TIMER, 32);
|
||||
}
|
||||
}
|
||||
-192
@@ -1,192 +0,0 @@
|
||||
#ifndef PCI_H
|
||||
#define PCI_H
|
||||
|
||||
/*
|
||||
** Support for NE2000 PCI clones added David Monro June 1997
|
||||
** Generalised for other PCI NICs by Ken Yap July 1997
|
||||
**
|
||||
** Most of this is taken from:
|
||||
**
|
||||
** /usr/src/linux/drivers/pci/pci.c
|
||||
** /usr/src/linux/include/linux/pci.h
|
||||
** /usr/src/linux/arch/i386/bios32.c
|
||||
** /usr/src/linux/include/linux/bios32.h
|
||||
** /usr/src/linux/drivers/net/ne.c
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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, or (at
|
||||
* your option) any later version.
|
||||
*/
|
||||
|
||||
#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
|
||||
#define PCI_COMMAND_MEM 0x2 /* Enable response in mem space */
|
||||
#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
|
||||
#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
|
||||
|
||||
#define PCIBIOS_PCI_FUNCTION_ID 0xb1XX
|
||||
#define PCIBIOS_PCI_BIOS_PRESENT 0xb101
|
||||
#define PCIBIOS_FIND_PCI_DEVICE 0xb102
|
||||
#define PCIBIOS_FIND_PCI_CLASS_CODE 0xb103
|
||||
#define PCIBIOS_GENERATE_SPECIAL_CYCLE 0xb106
|
||||
#define PCIBIOS_READ_CONFIG_BYTE 0xb108
|
||||
#define PCIBIOS_READ_CONFIG_WORD 0xb109
|
||||
#define PCIBIOS_READ_CONFIG_DWORD 0xb10a
|
||||
#define PCIBIOS_WRITE_CONFIG_BYTE 0xb10b
|
||||
#define PCIBIOS_WRITE_CONFIG_WORD 0xb10c
|
||||
#define PCIBIOS_WRITE_CONFIG_DWORD 0xb10d
|
||||
|
||||
#define PCI_VENDOR_ID 0x00 /* 16 bits */
|
||||
#define PCI_DEVICE_ID 0x02 /* 16 bits */
|
||||
#define PCI_COMMAND 0x04 /* 16 bits */
|
||||
|
||||
#define PCI_REVISION 0x08 /* 8 bits */
|
||||
#define PCI_CLASS_CODE 0x0b /* 8 bits */
|
||||
#define PCI_SUBCLASS_CODE 0x0a /* 8 bits */
|
||||
#define PCI_HEADER_TYPE 0x0e /* 8 bits */
|
||||
|
||||
#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
|
||||
#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits */
|
||||
#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits */
|
||||
#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */
|
||||
#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
|
||||
#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
|
||||
|
||||
#ifndef PCI_BASE_ADDRESS_IO_MASK
|
||||
#define PCI_BASE_ADDRESS_IO_MASK (~0x03)
|
||||
#endif
|
||||
#define PCI_BASE_ADDRESS_SPACE_IO 0x01
|
||||
#define PCI_ROM_ADDRESS 0x30 /* 32 bits */
|
||||
#define PCI_ROM_ADDRESS_ENABLE 0x01 /* Write 1 to enable ROM,
|
||||
bits 31..11 are address,
|
||||
10..2 are reserved */
|
||||
|
||||
#define PCI_FUNC(devfn) ((devfn) & 0x07)
|
||||
|
||||
#define BIOS32_SIGNATURE (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
|
||||
|
||||
/* PCI signature: "PCI " */
|
||||
#define PCI_SIGNATURE (('P' << 0) + ('C' << 8) + ('I' << 16) + (' ' << 24))
|
||||
|
||||
/* PCI service signature: "$PCI" */
|
||||
#define PCI_SERVICE (('$' << 0) + ('P' << 8) + ('C' << 16) + ('I' << 24))
|
||||
|
||||
union bios32 {
|
||||
struct {
|
||||
unsigned long signature; /* _32_ */
|
||||
unsigned long entry; /* 32 bit physical address */
|
||||
unsigned char revision; /* Revision level, 0 */
|
||||
unsigned char length; /* Length in paragraphs should be 01 */
|
||||
unsigned char checksum; /* All bytes must add up to zero */
|
||||
unsigned char reserved[5]; /* Must be zero */
|
||||
} fields;
|
||||
char chars[16];
|
||||
};
|
||||
|
||||
#define KERN_CODE_SEG 0x8 /* This _MUST_ match start.S */
|
||||
|
||||
/* Stuff for asm */
|
||||
#define save_flags(x) \
|
||||
__asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */ :"memory")
|
||||
|
||||
#define cli() __asm__ __volatile__ ("cli": : :"memory")
|
||||
|
||||
#define restore_flags(x) \
|
||||
__asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
|
||||
|
||||
#define PCI_VENDOR_ID_ADMTEK 0x1317
|
||||
#define PCI_DEVICE_ID_ADMTEK_0985 0x0985
|
||||
#define PCI_VENDOR_ID_REALTEK 0x10ec
|
||||
#define PCI_DEVICE_ID_REALTEK_8029 0x8029
|
||||
#define PCI_DEVICE_ID_REALTEK_8139 0x8139
|
||||
#define PCI_VENDOR_ID_WINBOND2 0x1050
|
||||
#define PCI_DEVICE_ID_WINBOND2_89C940 0x0940
|
||||
#define PCI_DEVICE_ID_WINBOND2_89C840 0x0840
|
||||
#define PCI_VENDOR_ID_COMPEX 0x11f6
|
||||
#define PCI_DEVICE_ID_COMPEX_RL2000 0x1401
|
||||
#define PCI_DEVICE_ID_COMPEX_RL100ATX 0x2011
|
||||
#define PCI_VENDOR_ID_KTI 0x8e2e
|
||||
#define PCI_DEVICE_ID_KTI_ET32P2 0x3000
|
||||
#define PCI_VENDOR_ID_NETVIN 0x4a14
|
||||
#define PCI_DEVICE_ID_NETVIN_NV5000SC 0x5000
|
||||
#define PCI_VENDOR_ID_HOLTEK 0x12c3
|
||||
#define PCI_DEVICE_ID_HOLTEK_HT80232 0x0058
|
||||
#define PCI_VENDOR_ID_3COM 0x10b7
|
||||
#define PCI_DEVICE_ID_3COM_3C590 0x5900
|
||||
#define PCI_DEVICE_ID_3COM_3C595 0x5950
|
||||
#define PCI_DEVICE_ID_3COM_3C595_1 0x5951
|
||||
#define PCI_DEVICE_ID_3COM_3C595_2 0x5952
|
||||
#define PCI_DEVICE_ID_3COM_3C900TPO 0x9000
|
||||
#define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001
|
||||
#define PCI_DEVICE_ID_3COM_3C905TX 0x9050
|
||||
#define PCI_DEVICE_ID_3COM_3C905T4 0x9051
|
||||
#define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055
|
||||
#define PCI_DEVICE_ID_3COM_3C905C_TXM 0x9200
|
||||
#define PCI_VENDOR_ID_INTEL 0x8086
|
||||
#define PCI_DEVICE_ID_INTEL_82557 0x1229
|
||||
#define PCI_DEVICE_ID_INTEL_82559ER 0x1209
|
||||
#define PCI_DEVICE_ID_INTEL_ID1029 0x1029
|
||||
#define PCI_DEVICE_ID_INTEL_ID1030 0x1030
|
||||
#define PCI_DEVICE_ID_INTEL_82562 0x2449
|
||||
#define PCI_VENDOR_ID_AMD 0x1022
|
||||
#define PCI_DEVICE_ID_AMD_LANCE 0x2000
|
||||
#define PCI_VENDOR_ID_AMD_HOMEPNA 0x1022
|
||||
#define PCI_DEVICE_ID_AMD_HOMEPNA 0x2001
|
||||
#define PCI_VENDOR_ID_SMC_1211 0x1113
|
||||
#define PCI_DEVICE_ID_SMC_1211 0x1211
|
||||
#define PCI_VENDOR_ID_DEC 0x1011
|
||||
#define PCI_DEVICE_ID_DEC_TULIP 0x0002
|
||||
#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009
|
||||
#define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014
|
||||
#define PCI_DEVICE_ID_DEC_21142 0x0019
|
||||
#define PCI_VENDOR_ID_SMC 0x10B8
|
||||
#ifndef PCI_DEVICE_ID_SMC_EPIC100
|
||||
# define PCI_DEVICE_ID_SMC_EPIC100 0x0005
|
||||
#endif
|
||||
#define PCI_VENDOR_ID_MACRONIX 0x10d9
|
||||
#define PCI_DEVICE_ID_MX987x5 0x0531
|
||||
#define PCI_VENDOR_ID_LINKSYS 0x11AD
|
||||
#define PCI_DEVICE_ID_LC82C115 0xC115
|
||||
#define PCI_VENDOR_ID_VIATEC 0x1106
|
||||
#define PCI_DEVICE_ID_VIA_RHINE_I 0x3043
|
||||
#define PCI_DEVICE_ID_VIA_VT6102 0x3065
|
||||
#define PCI_DEVICE_ID_VIA_86C100A 0x6100
|
||||
#define PCI_VENDOR_ID_DAVICOM 0x1282
|
||||
#define PCI_DEVICE_ID_DM9009 0x9009
|
||||
#define PCI_DEVICE_ID_DM9102 0x9102
|
||||
#define PCI_VENDOR_ID_SIS 0x1039
|
||||
#define PCI_DEVICE_ID_SIS900 0x0900
|
||||
#define PCI_DEVICE_ID_SIS7016 0x7016
|
||||
#define PCI_VENDOR_ID_DLINK 0x1186
|
||||
#define PCI_DEVICE_ID_DFE530TXP 0x1300
|
||||
#define PCI_VENDOR_ID_NS 0x100B
|
||||
#define PCI_DEVICE_ID_DP83815 0x0020
|
||||
#define PCI_VENDOR_ID_OLICOM 0x108d
|
||||
#define PCI_DEVICE_ID_OLICOM_OC3136 0x0001
|
||||
#define PCI_DEVICE_ID_OLICOM_OC2315 0x0011
|
||||
#define PCI_DEVICE_ID_OLICOM_OC2325 0x0012
|
||||
#define PCI_DEVICE_ID_OLICOM_OC2183 0x0013
|
||||
#define PCI_DEVICE_ID_OLICOM_OC2326 0x0014
|
||||
#define PCI_DEVICE_ID_OLICOM_OC6151 0x0021
|
||||
|
||||
struct pci_device {
|
||||
unsigned short vendor, dev_id;
|
||||
const char *name;
|
||||
unsigned int membase;
|
||||
unsigned short ioaddr;
|
||||
unsigned char devfn;
|
||||
unsigned char bus;
|
||||
};
|
||||
|
||||
extern void eth_pci_init(struct pci_device *);
|
||||
|
||||
extern int pcibios_read_config_byte(unsigned int bus, unsigned int device_fn, unsigned int where, unsigned char *value);
|
||||
extern int pcibios_write_config_byte (unsigned int bus, unsigned int device_fn, unsigned int where, unsigned char value);
|
||||
extern int pcibios_read_config_word(unsigned int bus, unsigned int device_fn, unsigned int where, unsigned short *value);
|
||||
extern int pcibios_write_config_word (unsigned int bus, unsigned int device_fn, unsigned int where, unsigned short value);
|
||||
extern int pcibios_read_config_dword(unsigned int bus, unsigned int device_fn, unsigned int where, unsigned int *value);
|
||||
extern int pcibios_write_config_dword(unsigned int bus, unsigned int device_fn, unsigned int where, unsigned int value);
|
||||
void adjust_pci_device(struct pci_device *p);
|
||||
#endif /* PCI_H */
|
||||
@@ -1,458 +0,0 @@
|
||||
/* rtl8139.c - etherboot driver for the Realtek 8139 chipset
|
||||
|
||||
ported from the linux driver written by Donald Becker
|
||||
by Rainer Bawidamann (Rainer.Bawidamann@informatik.uni-ulm.de) 1999
|
||||
|
||||
This software may be used and distributed according to the terms
|
||||
of the GNU Public License, incorporated herein by reference.
|
||||
|
||||
changes to the original driver:
|
||||
- removed support for interrupts, switching to polling mode (yuck!)
|
||||
- removed support for the 8129 chip (external MII)
|
||||
|
||||
*/
|
||||
|
||||
/*********************************************************************/
|
||||
/* Revision History */
|
||||
/*********************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
06 Apr 2001 ken_yap@users.sourceforge.net (Ken Yap)
|
||||
Following email from Hyun-Joon Cha, added a disable routine, otherwise
|
||||
NIC remains live and can crash the kernel later.
|
||||
|
||||
4 Feb 2000 espenlaub@informatik.uni-ulm.de (Klaus Espenlaub)
|
||||
Shuffled things around, removed the leftovers from the 8129 support
|
||||
that was in the Linux driver and added a bit more 8139 definitions.
|
||||
Moved the 8K receive buffer to a fixed, available address outside the
|
||||
0x98000-0x9ffff range. This is a bit of a hack, but currently the only
|
||||
way to make room for the Etherboot features that need substantial amounts
|
||||
of code like the ANSI console support. Currently the buffer is just below
|
||||
0x10000, so this even conforms to the tagged boot image specification,
|
||||
which reserves the ranges 0x00000-0x10000 and 0x98000-0xA0000. My
|
||||
interpretation of this "reserved" is that Etherboot may do whatever it
|
||||
likes, as long as its environment is kept intact (like the BIOS
|
||||
variables). Hopefully fixed rtl_poll() once and for all. The symptoms
|
||||
were that if Etherboot was left at the boot menu for several minutes, the
|
||||
first eth_poll failed. Seems like I am the only person who does this.
|
||||
First of all I fixed the debugging code and then set out for a long bug
|
||||
hunting session. It took me about a week full time work - poking around
|
||||
various places in the driver, reading Don Becker's and Jeff Garzik's Linux
|
||||
driver and even the FreeBSD driver (what a piece of crap!) - and
|
||||
eventually spotted the nasty thing: the transmit routine was acknowledging
|
||||
each and every interrupt pending, including the RxOverrun and RxFIFIOver
|
||||
interrupts. This confused the RTL8139 thoroughly. It destroyed the
|
||||
Rx ring contents by dumping the 2K FIFO contents right where we wanted to
|
||||
get the next packet. Oh well, what fun.
|
||||
|
||||
18 Jan 2000 mdc@thinguin.org (Marty Connor)
|
||||
Drastically simplified error handling. Basically, if any error
|
||||
in transmission or reception occurs, the card is reset.
|
||||
Also, pointed all transmit descriptors to the same buffer to
|
||||
save buffer space. This should decrease driver size and avoid
|
||||
corruption because of exceeding 32K during runtime.
|
||||
|
||||
28 Jul 1999 (Matthias Meixner - meixner@rbg.informatik.tu-darmstadt.de)
|
||||
rtl_poll was quite broken: it used the RxOK interrupt flag instead
|
||||
of the RxBufferEmpty flag which often resulted in very bad
|
||||
transmission performace - below 1kBytes/s.
|
||||
|
||||
*/
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "pci.h"
|
||||
#include "cards.h"
|
||||
#include "timer.h"
|
||||
|
||||
#define RTL_TIMEOUT (1*TICKS_PER_SEC)
|
||||
|
||||
/* PCI Tuning Parameters
|
||||
Threshold is bytes transferred to chip before transmission starts. */
|
||||
#define TX_FIFO_THRESH 256 /* In bytes, rounded down to 32 byte units. */
|
||||
#define RX_FIFO_THRESH 4 /* Rx buffer level before first PCI xfer. */
|
||||
#define RX_DMA_BURST 4 /* Maximum PCI burst, '4' is 256 bytes */
|
||||
#define TX_DMA_BURST 4 /* Calculate as 16<<val. */
|
||||
#define NUM_TX_DESC 4 /* Number of Tx descriptor registers. */
|
||||
#define TX_BUF_SIZE ETH_FRAME_LEN /* FCS is added by the chip */
|
||||
#define RX_BUF_LEN_IDX 0 /* 0, 1, 2 is allowed - 8,16,32K rx buffer */
|
||||
#define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX)
|
||||
|
||||
#undef DEBUG_TX
|
||||
#undef DEBUG_RX
|
||||
|
||||
/* Symbolic offsets to registers. */
|
||||
enum RTL8139_registers {
|
||||
MAC0=0, /* Ethernet hardware address. */
|
||||
MAR0=8, /* Multicast filter. */
|
||||
TxStatus0=0x10, /* Transmit status (four 32bit registers). */
|
||||
TxAddr0=0x20, /* Tx descriptors (also four 32bit). */
|
||||
RxBuf=0x30, RxEarlyCnt=0x34, RxEarlyStatus=0x36,
|
||||
ChipCmd=0x37, RxBufPtr=0x38, RxBufAddr=0x3A,
|
||||
IntrMask=0x3C, IntrStatus=0x3E,
|
||||
TxConfig=0x40, RxConfig=0x44,
|
||||
Timer=0x48, /* general-purpose counter. */
|
||||
RxMissed=0x4C, /* 24 bits valid, write clears. */
|
||||
Cfg9346=0x50, Config0=0x51, Config1=0x52,
|
||||
TimerIntrReg=0x54, /* intr if gp counter reaches this value */
|
||||
MediaStatus=0x58,
|
||||
Config3=0x59,
|
||||
MultiIntr=0x5C,
|
||||
RevisionID=0x5E, /* revision of the RTL8139 chip */
|
||||
TxSummary=0x60,
|
||||
MII_BMCR=0x62, MII_BMSR=0x64, NWayAdvert=0x66, NWayLPAR=0x68,
|
||||
NWayExpansion=0x6A,
|
||||
DisconnectCnt=0x6C, FalseCarrierCnt=0x6E,
|
||||
NWayTestReg=0x70,
|
||||
RxCnt=0x72, /* packet received counter */
|
||||
CSCR=0x74, /* chip status and configuration register */
|
||||
PhyParm1=0x78,TwisterParm=0x7c,PhyParm2=0x80, /* undocumented */
|
||||
/* from 0x84 onwards are a number of power management/wakeup frame
|
||||
* definitions we will probably never need to know about. */
|
||||
};
|
||||
|
||||
enum ChipCmdBits {
|
||||
CmdReset=0x10, CmdRxEnb=0x08, CmdTxEnb=0x04, RxBufEmpty=0x01, };
|
||||
|
||||
/* Interrupt register bits, using my own meaningful names. */
|
||||
enum IntrStatusBits {
|
||||
PCIErr=0x8000, PCSTimeout=0x4000, CableLenChange= 0x2000,
|
||||
RxFIFOOver=0x40, RxUnderrun=0x20, RxOverflow=0x10,
|
||||
TxErr=0x08, TxOK=0x04, RxErr=0x02, RxOK=0x01,
|
||||
};
|
||||
enum TxStatusBits {
|
||||
TxHostOwns=0x2000, TxUnderrun=0x4000, TxStatOK=0x8000,
|
||||
TxOutOfWindow=0x20000000, TxAborted=0x40000000,
|
||||
TxCarrierLost=0x80000000,
|
||||
};
|
||||
enum RxStatusBits {
|
||||
RxMulticast=0x8000, RxPhysical=0x4000, RxBroadcast=0x2000,
|
||||
RxBadSymbol=0x0020, RxRunt=0x0010, RxTooLong=0x0008, RxCRCErr=0x0004,
|
||||
RxBadAlign=0x0002, RxStatusOK=0x0001,
|
||||
};
|
||||
|
||||
enum MediaStatusBits {
|
||||
MSRTxFlowEnable=0x80, MSRRxFlowEnable=0x40, MSRSpeed10=0x08,
|
||||
MSRLinkFail=0x04, MSRRxPauseFlag=0x02, MSRTxPauseFlag=0x01,
|
||||
};
|
||||
|
||||
enum MIIBMCRBits {
|
||||
BMCRReset=0x8000, BMCRSpeed100=0x2000, BMCRNWayEnable=0x1000,
|
||||
BMCRRestartNWay=0x0200, BMCRDuplex=0x0100,
|
||||
};
|
||||
|
||||
enum CSCRBits {
|
||||
CSCR_LinkOKBit=0x0400, CSCR_LinkChangeBit=0x0800,
|
||||
CSCR_LinkStatusBits=0x0f000, CSCR_LinkDownOffCmd=0x003c0,
|
||||
CSCR_LinkDownCmd=0x0f3c0,
|
||||
};
|
||||
|
||||
/* Bits in RxConfig. */
|
||||
enum rx_mode_bits {
|
||||
RxCfgWrap=0x80,
|
||||
AcceptErr=0x20, AcceptRunt=0x10, AcceptBroadcast=0x08,
|
||||
AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01,
|
||||
};
|
||||
|
||||
static int ioaddr;
|
||||
static unsigned int cur_rx,cur_tx;
|
||||
|
||||
/* The RTL8139 can only transmit from a contiguous, aligned memory block. */
|
||||
static unsigned char tx_buffer[TX_BUF_SIZE] __attribute__((aligned(4)));
|
||||
|
||||
/* I know that this is a MEGA HACK, but the tagged boot image specification
|
||||
* states that we can do whatever we want below 0x10000 - so we do! */
|
||||
/* But we still give the user the choice of using an internal buffer
|
||||
just in case - Ken */
|
||||
#ifdef USE_LOWMEM_BUFFER
|
||||
#define rx_ring ((unsigned char *)(0x10000 - (RX_BUF_LEN + 16)))
|
||||
#else
|
||||
static unsigned char rx_ring[RX_BUF_LEN+16] __attribute__((aligned(4)));
|
||||
#endif
|
||||
|
||||
struct nic *rtl8139_probe(struct nic *nic, unsigned short *probeaddrs,
|
||||
struct pci_device *pci);
|
||||
static int read_eeprom(int location);
|
||||
static void rtl_reset(struct nic *nic);
|
||||
static void rtl_transmit(struct nic *nic, const char *destaddr,
|
||||
unsigned int type, unsigned int len, const char *data);
|
||||
static int rtl_poll(struct nic *nic);
|
||||
static void rtl_disable(struct nic*);
|
||||
|
||||
|
||||
struct nic *rtl8139_probe(struct nic *nic, unsigned short *probeaddrs,
|
||||
struct pci_device *pci)
|
||||
{
|
||||
int i;
|
||||
int speed10, fullduplex;
|
||||
|
||||
/* There are enough "RTL8139" strings on the console already, so
|
||||
* be brief and concentrate on the interesting pieces of info... */
|
||||
printf(" - ");
|
||||
|
||||
/* Mask the bit that says "this is an io addr" */
|
||||
ioaddr = probeaddrs[0] & ~3;
|
||||
|
||||
adjust_pci_device(pci);
|
||||
|
||||
/* Bring the chip out of low-power mode. */
|
||||
outb(0x00, ioaddr + Config1);
|
||||
|
||||
if (read_eeprom(0) != 0xffff) {
|
||||
unsigned short *ap = (unsigned short*)nic->node_addr;
|
||||
for (i = 0; i < 3; i++)
|
||||
*ap++ = read_eeprom(i + 7);
|
||||
} else {
|
||||
unsigned char *ap = (unsigned char*)nic->node_addr;
|
||||
for (i = 0; i < ETH_ALEN; i++)
|
||||
*ap++ = inb(ioaddr + MAC0 + i);
|
||||
}
|
||||
|
||||
speed10 = inb(ioaddr + MediaStatus) & MSRSpeed10;
|
||||
fullduplex = inw(ioaddr + MII_BMCR) & BMCRDuplex;
|
||||
printf("ioaddr %#hX, addr %! %sMbps %s-duplex\n", ioaddr,
|
||||
nic->node_addr, speed10 ? "10" : "100",
|
||||
fullduplex ? "full" : "half");
|
||||
|
||||
rtl_reset(nic);
|
||||
|
||||
nic->reset = rtl_reset;
|
||||
nic->poll = rtl_poll;
|
||||
nic->transmit = rtl_transmit;
|
||||
nic->disable = rtl_disable;
|
||||
|
||||
return nic;
|
||||
}
|
||||
|
||||
/* Serial EEPROM section. */
|
||||
|
||||
/* EEPROM_Ctrl bits. */
|
||||
#define EE_SHIFT_CLK 0x04 /* EEPROM shift clock. */
|
||||
#define EE_CS 0x08 /* EEPROM chip select. */
|
||||
#define EE_DATA_WRITE 0x02 /* EEPROM chip data in. */
|
||||
#define EE_WRITE_0 0x00
|
||||
#define EE_WRITE_1 0x02
|
||||
#define EE_DATA_READ 0x01 /* EEPROM chip data out. */
|
||||
#define EE_ENB (0x80 | EE_CS)
|
||||
|
||||
/*
|
||||
Delay between EEPROM clock transitions.
|
||||
No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
|
||||
*/
|
||||
|
||||
#define eeprom_delay() inl(ee_addr)
|
||||
|
||||
/* The EEPROM commands include the alway-set leading bit. */
|
||||
#define EE_WRITE_CMD (5 << 6)
|
||||
#define EE_READ_CMD (6 << 6)
|
||||
#define EE_ERASE_CMD (7 << 6)
|
||||
|
||||
static int read_eeprom(int location)
|
||||
{
|
||||
int i;
|
||||
unsigned int retval = 0;
|
||||
long ee_addr = ioaddr + Cfg9346;
|
||||
int read_cmd = location | EE_READ_CMD;
|
||||
|
||||
outb(EE_ENB & ~EE_CS, ee_addr);
|
||||
outb(EE_ENB, ee_addr);
|
||||
|
||||
/* Shift the read command bits out. */
|
||||
for (i = 10; i >= 0; i--) {
|
||||
int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
|
||||
outb(EE_ENB | dataval, ee_addr);
|
||||
eeprom_delay();
|
||||
outb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
|
||||
eeprom_delay();
|
||||
}
|
||||
outb(EE_ENB, ee_addr);
|
||||
eeprom_delay();
|
||||
|
||||
for (i = 16; i > 0; i--) {
|
||||
outb(EE_ENB | EE_SHIFT_CLK, ee_addr);
|
||||
eeprom_delay();
|
||||
retval = (retval << 1) | ((inb(ee_addr) & EE_DATA_READ) ? 1 : 0);
|
||||
outb(EE_ENB, ee_addr);
|
||||
eeprom_delay();
|
||||
}
|
||||
|
||||
/* Terminate the EEPROM access. */
|
||||
outb(~EE_CS, ee_addr);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void rtl_reset(struct nic* nic)
|
||||
{
|
||||
int i;
|
||||
|
||||
outb(CmdReset, ioaddr + ChipCmd);
|
||||
|
||||
cur_rx = 0;
|
||||
cur_tx = 0;
|
||||
|
||||
/* Give the chip 10ms to finish the reset. */
|
||||
load_timer2(10*TICKS_PER_MS);
|
||||
while ((inb(ioaddr + ChipCmd) & CmdReset) != 0 && timer2_running())
|
||||
/* wait */;
|
||||
|
||||
for (i = 0; i < ETH_ALEN; i++)
|
||||
outb(nic->node_addr[i], ioaddr + MAC0 + i);
|
||||
|
||||
/* Must enable Tx/Rx before setting transfer thresholds! */
|
||||
outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
|
||||
outl((RX_FIFO_THRESH<<13) | (RX_BUF_LEN_IDX<<11) | (RX_DMA_BURST<<8),
|
||||
ioaddr + RxConfig); /* accept no frames yet! */
|
||||
outl((TX_DMA_BURST<<8)|0x03000000, ioaddr + TxConfig);
|
||||
|
||||
/* The Linux driver changes Config1 here to use a different LED pattern
|
||||
* for half duplex or full/autodetect duplex (for full/autodetect, the
|
||||
* outputs are TX/RX, Link10/100, FULL, while for half duplex it uses
|
||||
* TX/RX, Link100, Link10). This is messy, because it doesn't match
|
||||
* the inscription on the mounting bracket. It should not be changed
|
||||
* from the configuration EEPROM default, because the card manufacturer
|
||||
* should have set that to match the card. */
|
||||
|
||||
#ifdef DEBUG_RX
|
||||
printf("rx ring address is %X\n",(unsigned long)rx_ring);
|
||||
#endif
|
||||
outl((unsigned long)rx_ring, ioaddr + RxBuf);
|
||||
|
||||
/* Start the chip's Tx and Rx process. */
|
||||
outl(0, ioaddr + RxMissed);
|
||||
/* set_rx_mode */
|
||||
outb(AcceptBroadcast|AcceptMyPhys, ioaddr + RxConfig);
|
||||
/* If we add multicast support, the MAR0 register would have to be
|
||||
* initialized to 0xffffffffffffffff (two 32 bit accesses). Etherboot
|
||||
* only needs broadcast (for ARP/RARP/BOOTP/DHCP) and unicast. */
|
||||
outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
|
||||
|
||||
/* Disable all known interrupts by setting the interrupt mask. */
|
||||
outw(0, ioaddr + IntrMask);
|
||||
}
|
||||
|
||||
static void rtl_transmit(struct nic *nic, const char *destaddr,
|
||||
unsigned int type, unsigned int len, const char *data)
|
||||
{
|
||||
unsigned int status, to, nstype;
|
||||
unsigned long txstatus;
|
||||
|
||||
memcpy(tx_buffer, destaddr, ETH_ALEN);
|
||||
memcpy(tx_buffer + ETH_ALEN, nic->node_addr, ETH_ALEN);
|
||||
nstype = htons(type);
|
||||
memcpy(tx_buffer + 2 * ETH_ALEN, (char*)&nstype, 2);
|
||||
memcpy(tx_buffer + ETH_HLEN, data, len);
|
||||
|
||||
len += ETH_HLEN;
|
||||
#ifdef DEBUG_TX
|
||||
printf("sending %d bytes ethtype %hX\n", len, type);
|
||||
#endif
|
||||
|
||||
/* Note: RTL8139 doesn't auto-pad, send minimum payload (another 4
|
||||
* bytes are sent automatically for the FCS, totalling to 64 bytes). */
|
||||
while (len < ETH_ZLEN) {
|
||||
tx_buffer[len++] = '\0';
|
||||
}
|
||||
|
||||
outl((unsigned long)tx_buffer, ioaddr + TxAddr0 + cur_tx*4);
|
||||
outl(((TX_FIFO_THRESH<<11) & 0x003f0000) | len,
|
||||
ioaddr + TxStatus0 + cur_tx*4);
|
||||
|
||||
to = currticks() + RTL_TIMEOUT;
|
||||
|
||||
do {
|
||||
status = inw(ioaddr + IntrStatus);
|
||||
/* Only acknlowledge interrupt sources we can properly handle
|
||||
* here - the RxOverflow/RxFIFOOver MUST be handled in the
|
||||
* rtl_poll() function. */
|
||||
outw(status & (TxOK | TxErr | PCIErr), ioaddr + IntrStatus);
|
||||
if ((status & (TxOK | TxErr | PCIErr)) != 0) break;
|
||||
} while (currticks() < to);
|
||||
|
||||
txstatus = inl(ioaddr+ TxStatus0 + cur_tx*4);
|
||||
|
||||
if (status & TxOK) {
|
||||
cur_tx = (cur_tx + 1) % NUM_TX_DESC;
|
||||
#ifdef DEBUG_TX
|
||||
printf("tx done (%d ticks), status %hX txstatus %X\n",
|
||||
to-currticks(), status, txstatus);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef DEBUG_TX
|
||||
printf("tx timeout/error (%d ticks), status %hX txstatus %X\n",
|
||||
currticks()-to, status, txstatus);
|
||||
#endif
|
||||
rtl_reset(nic);
|
||||
}
|
||||
}
|
||||
|
||||
static int rtl_poll(struct nic *nic)
|
||||
{
|
||||
unsigned int status;
|
||||
unsigned int ring_offs;
|
||||
unsigned int rx_size, rx_status;
|
||||
|
||||
if (inb(ioaddr + ChipCmd) & RxBufEmpty) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = inw(ioaddr + IntrStatus);
|
||||
/* See below for the rest of the interrupt acknowledges. */
|
||||
outw(status & ~(RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus);
|
||||
|
||||
#ifdef DEBUG_RX
|
||||
printf("rtl_poll: int %hX ", status);
|
||||
#endif
|
||||
|
||||
ring_offs = cur_rx % RX_BUF_LEN;
|
||||
rx_status = *(unsigned int*)(rx_ring + ring_offs);
|
||||
rx_size = rx_status >> 16;
|
||||
rx_status &= 0xffff;
|
||||
|
||||
if ((rx_status & (RxBadSymbol|RxRunt|RxTooLong|RxCRCErr|RxBadAlign)) ||
|
||||
(rx_size < ETH_ZLEN) || (rx_size > ETH_FRAME_LEN + 4)) {
|
||||
printf("rx error %hX\n", rx_status);
|
||||
rtl_reset(nic); /* this clears all interrupts still pending */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Received a good packet */
|
||||
nic->packetlen = rx_size - 4; /* no one cares about the FCS */
|
||||
if (ring_offs+4+rx_size-4 > RX_BUF_LEN) {
|
||||
int semi_count = RX_BUF_LEN - ring_offs - 4;
|
||||
|
||||
memcpy(nic->packet, rx_ring + ring_offs + 4, semi_count);
|
||||
memcpy(nic->packet+semi_count, rx_ring, rx_size-4-semi_count);
|
||||
#ifdef DEBUG_RX
|
||||
printf("rx packet %d+%d bytes", semi_count,rx_size-4-semi_count);
|
||||
#endif
|
||||
} else {
|
||||
memcpy(nic->packet, rx_ring + ring_offs + 4, nic->packetlen);
|
||||
#ifdef DEBUG_RX
|
||||
printf("rx packet %d bytes", rx_size-4);
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG_RX
|
||||
printf(" at %X type %hhX%hhX rxstatus %hX\n",
|
||||
(unsigned long)(rx_ring+ring_offs+4),
|
||||
nic->packet[12], nic->packet[13], rx_status);
|
||||
#endif
|
||||
cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
|
||||
outw(cur_rx - 16, ioaddr + RxBufPtr);
|
||||
/* See RTL8139 Programming Guide V0.1 for the official handling of
|
||||
* Rx overflow situations. The document itself contains basically no
|
||||
* usable information, except for a few exception handling rules. */
|
||||
outw(status & (RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void rtl_disable(struct nic *nic)
|
||||
{
|
||||
/* reset the chip */
|
||||
outb(CmdReset, ioaddr + ChipCmd);
|
||||
|
||||
/* 10 ms timeout */
|
||||
load_timer2(10*TICKS_PER_MS);
|
||||
while ((inb(ioaddr + ChipCmd) & CmdReset) != 0 && timer2_running())
|
||||
/* wait */;
|
||||
}
|
||||
-1034
File diff suppressed because it is too large.
Load diff
@@ -1,363 +0,0 @@
|
||||
/* -*- Mode:C; c-basic-offset:4; -*- */
|
||||
|
||||
/* Definitions for SiS ethernet controllers including 7014/7016 and 900
|
||||
* References:
|
||||
* SiS 7016 Fast Ethernet PCI Bus 10/100 Mbps LAN Controller with OnNow Support,
|
||||
* preliminary Rev. 1.0 Jan. 14, 1998
|
||||
* SiS 900 Fast Ethernet PCI Bus 10/100 Mbps LAN Single Chip with OnNow Support,
|
||||
* preliminary Rev. 1.0 Nov. 10, 1998
|
||||
* SiS 7014 Single Chip 100BASE-TX/10BASE-T Physical Layer Solution,
|
||||
* preliminary Rev. 1.0 Jan. 18, 1998
|
||||
* http://www.sis.com.tw/support/databook.htm
|
||||
*/
|
||||
|
||||
/* MAC operationl registers of SiS 7016 and SiS 900 ethernet controller */
|
||||
/* The I/O extent, SiS 900 needs 256 bytes of io address */
|
||||
#define SIS900_TOTAL_SIZE 0x100
|
||||
|
||||
/* Symbolic offsets to registers. */
|
||||
enum sis900_registers {
|
||||
cr=0x0, /* Command Register */
|
||||
cfg=0x4, /* Configuration Register */
|
||||
mear=0x8, /* EEPROM Access Register */
|
||||
ptscr=0xc, /* PCI Test Control Register */
|
||||
isr=0x10, /* Interrupt Status Register */
|
||||
imr=0x14, /* Interrupt Mask Register */
|
||||
ier=0x18, /* Interrupt Enable Register */
|
||||
epar=0x18, /* Enhanced PHY Access Register */
|
||||
txdp=0x20, /* Transmit Descriptor Pointer Register */
|
||||
txcfg=0x24, /* Transmit Configuration Register */
|
||||
rxdp=0x30, /* Receive Descriptor Pointer Register */
|
||||
rxcfg=0x34, /* Receive Configuration Register */
|
||||
flctrl=0x38, /* Flow Control Register */
|
||||
rxlen=0x3c, /* Receive Packet Length Register */
|
||||
rfcr=0x48, /* Receive Filter Control Register */
|
||||
rfdr=0x4C, /* Receive Filter Data Register */
|
||||
pmctrl=0xB0, /* Power Management Control Register */
|
||||
pmer=0xB4 /* Power Management Wake-up Event Register */
|
||||
};
|
||||
|
||||
/* Symbolic names for bits in various registers */
|
||||
enum sis900_command_register_bits {
|
||||
RESET = 0x00000100,
|
||||
SWI = 0x00000080,
|
||||
RxRESET = 0x00000020,
|
||||
TxRESET = 0x00000010,
|
||||
RxDIS = 0x00000008,
|
||||
RxENA = 0x00000004,
|
||||
TxDIS = 0x00000002,
|
||||
TxENA = 0x00000001
|
||||
};
|
||||
|
||||
enum sis900_configuration_register_bits {
|
||||
DESCRFMT = 0x00000100, /* 7016 specific */
|
||||
REQALG = 0x00000080,
|
||||
SB = 0x00000040,
|
||||
POW = 0x00000020,
|
||||
EXD = 0x00000010,
|
||||
PESEL = 0x00000008,
|
||||
LPM = 0x00000004,
|
||||
BEM = 0x00000001
|
||||
};
|
||||
|
||||
enum sis900_eeprom_access_reigster_bits {
|
||||
MDC = 0x00000040,
|
||||
MDDIR = 0x00000020,
|
||||
MDIO = 0x00000010, /* 7016 specific */
|
||||
EECS = 0x00000008,
|
||||
EECLK = 0x00000004,
|
||||
EEDO = 0x00000002,
|
||||
EEDI = 0x00000001
|
||||
};
|
||||
|
||||
enum sis900_interrupt_register_bits {
|
||||
WKEVT = 0x10000000,
|
||||
TxPAUSEEND = 0x08000000,
|
||||
TxPAUSE = 0x04000000,
|
||||
TxRCMP = 0x02000000,
|
||||
RxRCMP = 0x01000000,
|
||||
DPERR = 0x00800000,
|
||||
SSERR = 0x00400000,
|
||||
RMABT = 0x00200000,
|
||||
RTABT = 0x00100000,
|
||||
RxSOVR = 0x00010000,
|
||||
HIBERR = 0x00008000,
|
||||
SWINT = 0x00001000,
|
||||
MIBINT = 0x00000800,
|
||||
TxURN = 0x00000400,
|
||||
TxIDLE = 0x00000200,
|
||||
TxERR = 0x00000100,
|
||||
TxDESC = 0x00000080,
|
||||
TxOK = 0x00000040,
|
||||
RxORN = 0x00000020,
|
||||
RxIDLE = 0x00000010,
|
||||
RxEARLY = 0x00000008,
|
||||
RxERR = 0x00000004,
|
||||
RxDESC = 0x00000002,
|
||||
RxOK = 0x00000001
|
||||
};
|
||||
|
||||
enum sis900_interrupt_enable_reigster_bits {
|
||||
IE = 0x00000001
|
||||
};
|
||||
|
||||
/* maximum dma burst fro transmission and receive*/
|
||||
#define MAX_DMA_RANGE 7 /* actually 0 means MAXIMUM !! */
|
||||
#define TxMXDMA_shift 20
|
||||
#define RxMXDMA_shift 20
|
||||
#define TX_DMA_BURST 0
|
||||
#define RX_DMA_BURST 0
|
||||
|
||||
/* transmit FIFO threshholds */
|
||||
#define TX_FILL_THRESH 16 /* 1/4 FIFO size */
|
||||
#define TxFILLT_shift 8
|
||||
#define TxDRNT_shift 0
|
||||
#define TxDRNT_100 48 /* 3/4 FIFO size */
|
||||
#define TxDRNT_10 16 /* 1/2 FIFO size */
|
||||
|
||||
enum sis900_transmit_config_register_bits {
|
||||
TxCSI = 0x80000000,
|
||||
TxHBI = 0x40000000,
|
||||
TxMLB = 0x20000000,
|
||||
TxATP = 0x10000000,
|
||||
TxIFG = 0x0C000000,
|
||||
TxFILLT = 0x00003F00,
|
||||
TxDRNT = 0x0000003F
|
||||
};
|
||||
|
||||
/* recevie FIFO thresholds */
|
||||
#define RxDRNT_shift 1
|
||||
#define RxDRNT_100 16 /* 1/2 FIFO size */
|
||||
#define RxDRNT_10 24 /* 3/4 FIFO size */
|
||||
|
||||
enum sis900_reveive_config_register_bits {
|
||||
RxAEP = 0x80000000,
|
||||
RxARP = 0x40000000,
|
||||
RxATX = 0x10000000,
|
||||
RxAJAB = 0x08000000,
|
||||
RxDRNT = 0x0000007F
|
||||
};
|
||||
|
||||
#define RFAA_shift 28
|
||||
#define RFADDR_shift 16
|
||||
|
||||
enum sis900_receive_filter_control_register_bits {
|
||||
RFEN = 0x80000000,
|
||||
RFAAB = 0x40000000,
|
||||
RFAAM = 0x20000000,
|
||||
RFAAP = 0x10000000,
|
||||
RFPromiscuous = (RFAAB|RFAAM|RFAAP)
|
||||
};
|
||||
|
||||
enum sis900_reveive_filter_data_mask {
|
||||
RFDAT = 0x0000FFFF
|
||||
};
|
||||
|
||||
/* EEPROM Addresses */
|
||||
enum sis900_eeprom_address {
|
||||
EEPROMSignature = 0x00,
|
||||
EEPROMVendorID = 0x02,
|
||||
EEPROMDeviceID = 0x03,
|
||||
EEPROMMACAddr = 0x08,
|
||||
EEPROMChecksum = 0x0b
|
||||
};
|
||||
|
||||
/* The EEPROM commands include the alway-set leading bit. Refer to NM93Cxx datasheet */
|
||||
enum sis900_eeprom_command {
|
||||
EEread = 0x0180,
|
||||
EEwrite = 0x0140,
|
||||
EEerase = 0x01C0,
|
||||
EEwriteEnable = 0x0130,
|
||||
EEwriteDisable = 0x0100,
|
||||
EEeraseAll = 0x0120,
|
||||
EEwriteAll = 0x0110,
|
||||
EEaddrMask = 0x013F,
|
||||
};
|
||||
|
||||
/* Manamgement Data I/O (mdio) frame */
|
||||
#define MIIread 0x6000
|
||||
#define MIIwrite 0x5002
|
||||
#define MIIpmdShift 7
|
||||
#define MIIregShift 2
|
||||
#define MIIcmdLen 16
|
||||
#define MIIcmdShift 16
|
||||
|
||||
/* Buffer Descriptor Status*/
|
||||
enum sis900_buffer_status {
|
||||
OWN = 0x80000000,
|
||||
MORE = 0x40000000,
|
||||
INTR = 0x20000000,
|
||||
SUPCRC = 0x10000000,
|
||||
INCCRC = 0x10000000,
|
||||
OK = 0x08000000,
|
||||
DSIZE = 0x00000FFF
|
||||
};
|
||||
|
||||
/* Status for TX Buffers */
|
||||
enum sis900_tx_buffer_status {
|
||||
ABORT = 0x04000000,
|
||||
UNDERRUN = 0x02000000,
|
||||
NOCARRIER = 0x01000000,
|
||||
DEFERD = 0x00800000,
|
||||
EXCDEFER = 0x00400000,
|
||||
OWCOLL = 0x00200000,
|
||||
EXCCOLL = 0x00100000,
|
||||
COLCNT = 0x000F0000
|
||||
};
|
||||
|
||||
enum sis900_rx_bufer_status {
|
||||
OVERRUN = 0x02000000,
|
||||
DEST = 0x00800000,
|
||||
BCAST = 0x01800000,
|
||||
MCAST = 0x01000000,
|
||||
UNIMATCH = 0x00800000,
|
||||
TOOLONG = 0x00400000,
|
||||
RUNT = 0x00200000,
|
||||
RXISERR = 0x00100000,
|
||||
CRCERR = 0x00080000,
|
||||
FAERR = 0x00040000,
|
||||
LOOPBK = 0x00020000,
|
||||
RXCOL = 0x00010000
|
||||
};
|
||||
|
||||
/* MII register offsets */
|
||||
enum mii_registers {
|
||||
MII_CONTROL = 0x0000,
|
||||
MII_STATUS = 0x0001,
|
||||
MII_PHY_ID0 = 0x0002,
|
||||
MII_PHY_ID1 = 0x0003,
|
||||
MII_ANADV = 0x0004,
|
||||
MII_ANLPAR = 0x0005,
|
||||
MII_ANEXT = 0x0006
|
||||
};
|
||||
|
||||
/* mii registers specific to SiS 900 */
|
||||
enum sis_mii_registers {
|
||||
MII_CONFIG1 = 0x0010,
|
||||
MII_CONFIG2 = 0x0011,
|
||||
MII_STSOUT = 0x0012,
|
||||
MII_MASK = 0x0013
|
||||
};
|
||||
|
||||
/* mii registers specific to AMD 79C901 */
|
||||
enum amd_mii_registers {
|
||||
MII_STATUS_SUMMARY = 0x0018
|
||||
};
|
||||
|
||||
/* mii registers specific to ICS 1893 */
|
||||
enum ics_mii_registers {
|
||||
MII_EXTCTRL = 0x0010, MII_QPDSTS = 0x0011, MII_10BTOP = 0x0012,
|
||||
MII_EXTCTRL2 = 0x0013
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* MII Control register bit definitions. */
|
||||
enum mii_control_register_bits {
|
||||
MII_CNTL_FDX = 0x0100,
|
||||
MII_CNTL_RST_AUTO = 0x0200,
|
||||
MII_CNTL_ISOLATE = 0x0400,
|
||||
MII_CNTL_PWRDWN = 0x0800,
|
||||
MII_CNTL_AUTO = 0x1000,
|
||||
MII_CNTL_SPEED = 0x2000,
|
||||
MII_CNTL_LPBK = 0x4000,
|
||||
MII_CNTL_RESET = 0x8000
|
||||
};
|
||||
|
||||
/* MII Status register bit */
|
||||
enum mii_status_register_bits {
|
||||
MII_STAT_EXT = 0x0001,
|
||||
MII_STAT_JAB = 0x0002,
|
||||
MII_STAT_LINK = 0x0004,
|
||||
MII_STAT_CAN_AUTO = 0x0008,
|
||||
MII_STAT_FAULT = 0x0010,
|
||||
MII_STAT_AUTO_DONE = 0x0020,
|
||||
MII_STAT_CAN_T = 0x0800,
|
||||
MII_STAT_CAN_T_FDX = 0x1000,
|
||||
MII_STAT_CAN_TX = 0x2000,
|
||||
MII_STAT_CAN_TX_FDX = 0x4000,
|
||||
MII_STAT_CAN_T4 = 0x8000
|
||||
};
|
||||
|
||||
#define MII_ID1_OUI_LO 0xFC00 /* low bits of OUI mask */
|
||||
#define MII_ID1_MODEL 0x03F0 /* model number */
|
||||
#define MII_ID1_REV 0x000F /* model number */
|
||||
|
||||
/* MII NWAY Register Bits ...
|
||||
valid for the ANAR (Auto-Negotiation Advertisement) and
|
||||
ANLPAR (Auto-Negotiation Link Partner) registers */
|
||||
enum mii_nway_register_bits {
|
||||
MII_NWAY_NODE_SEL = 0x001f,
|
||||
MII_NWAY_CSMA_CD = 0x0001,
|
||||
MII_NWAY_T = 0x0020,
|
||||
MII_NWAY_T_FDX = 0x0040,
|
||||
MII_NWAY_TX = 0x0080,
|
||||
MII_NWAY_TX_FDX = 0x0100,
|
||||
MII_NWAY_T4 = 0x0200,
|
||||
MII_NWAY_PAUSE = 0x0400,
|
||||
MII_NWAY_RF = 0x2000,
|
||||
MII_NWAY_ACK = 0x4000,
|
||||
MII_NWAY_NP = 0x8000
|
||||
};
|
||||
|
||||
enum mii_stsout_register_bits {
|
||||
MII_STSOUT_LINK_FAIL = 0x4000,
|
||||
MII_STSOUT_SPD = 0x0080,
|
||||
MII_STSOUT_DPLX = 0x0040
|
||||
};
|
||||
|
||||
enum mii_stsics_register_bits {
|
||||
MII_STSICS_SPD = 0x8000, MII_STSICS_DPLX = 0x4000,
|
||||
MII_STSICS_LINKSTS = 0x0001
|
||||
};
|
||||
|
||||
enum mii_stssum_register_bits {
|
||||
MII_STSSUM_LINK = 0x0008,
|
||||
MII_STSSUM_DPLX = 0x0004,
|
||||
MII_STSSUM_AUTO = 0x0002,
|
||||
MII_STSSUM_SPD = 0x0001
|
||||
};
|
||||
|
||||
enum sis900_revision_id {
|
||||
SIS630A_900_REV = 0x80, SIS630E_900_REV = 0x81,
|
||||
SIS630S_900_REV = 0x82, SIS630EA1_900_REV = 0x83
|
||||
};
|
||||
|
||||
enum sis630_revision_id {
|
||||
SIS630A0 = 0x00, SIS630A1 = 0x01,
|
||||
SIS630B0 = 0x10, SIS630B1 = 0x11
|
||||
};
|
||||
|
||||
#define FDX_CAPABLE_DUPLEX_UNKNOWN 0
|
||||
#define FDX_CAPABLE_HALF_SELECTED 1
|
||||
#define FDX_CAPABLE_FULL_SELECTED 2
|
||||
|
||||
#define HW_SPEED_UNCONFIG 0
|
||||
#define HW_SPEED_HOME 1
|
||||
#define HW_SPEED_10_MBPS 10
|
||||
#define HW_SPEED_100_MBPS 100
|
||||
#define HW_SPEED_DEFAULT (HW_SPEED_100_MBPS)
|
||||
|
||||
#define CRC_SIZE 4
|
||||
#define MAC_HEADER_SIZE 14
|
||||
|
||||
#define TX_BUF_SIZE 1536
|
||||
#define RX_BUF_SIZE 1536
|
||||
|
||||
#define NUM_RX_DESC 4 /* Number of Rx descriptor registers. */
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef signed char s8;
|
||||
typedef unsigned short u16;
|
||||
typedef signed short s16;
|
||||
typedef unsigned int u32;
|
||||
typedef signed int s32;
|
||||
|
||||
/* Time in ticks before concluding the transmitter is hung. */
|
||||
#define TX_TIMEOUT (4*TICKS_PER_SEC)
|
||||
|
||||
typedef struct _BufferDesc {
|
||||
u32 link;
|
||||
volatile u32 cmdsts;
|
||||
u32 bufptr;
|
||||
} BufferDesc;
|
||||
@@ -1,91 +0,0 @@
|
||||
How I added the SIS900 card to Etherboot
|
||||
|
||||
Author: Marty Connor (mdc@thinguin.org)
|
||||
|
||||
Date: 25 Febrary 2001
|
||||
|
||||
Description:
|
||||
|
||||
This file is intended to help people who want to write an Etherboot
|
||||
driver or port another driver to Etherboot. It is a starting point.
|
||||
Perhaps someday I may write a more detailed description of writing an
|
||||
Etherboot driver. This text should help get people started, and
|
||||
studying sis900.[ch] should help show the basic structure and
|
||||
techniques involved in writing and Etherboot driver.
|
||||
|
||||
***********************************************************************
|
||||
|
||||
0. Back up all the files I need to modify:
|
||||
|
||||
cd etherboot-4.7.20/src
|
||||
cp Makefile Makefile.orig
|
||||
cp config.c config.c.orig
|
||||
cp pci.h pci.h.orig
|
||||
cp NIC NIC.orig
|
||||
cp cards.h cards.h.orig
|
||||
|
||||
1. Edit src/Makefile to add SIS900FLAGS to defines
|
||||
|
||||
SIS900FLAGS= -DINCLUDE_SIS900
|
||||
|
||||
2. edit src/pci.h to add PCI signatures for card
|
||||
|
||||
#define PCI_VENDOR_ID_SIS 0x1039
|
||||
#define PCI_DEVICE_ID_SIS900 0x0900
|
||||
#define PCI_DEVICE_ID_SIS7016 0x7016
|
||||
|
||||
3. Edit src/config.c to add the card to the card probe list
|
||||
|
||||
#if defined(INCLUDE_NS8390) || defined(INCLUDE_EEPRO100) ||
|
||||
defined(INCLUDE_LANCE) || defined(INCLUDE_EPIC100) ||
|
||||
defined(INCLUDE_TULIP) || defined(INCLUDE_OTULIP) ||
|
||||
defined(INCLUDE_3C90X) || defined(INCLUDE_3C595) ||
|
||||
defined(INCLUDE_RTL8139) || defined(INCLUDE_VIA_RHINE) ||
|
||||
defined(INCLUDE_SIS900) || defined(INCLUDE_W89C840)
|
||||
|
||||
... and ...
|
||||
|
||||
#ifdef INCLUDE_SIS900
|
||||
{ PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS900,
|
||||
"SIS900", 0, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS7016,
|
||||
"SIS7016", 0, 0, 0, 0},
|
||||
#endif
|
||||
|
||||
... and ...
|
||||
|
||||
#ifdef INCLUDE_SIS900
|
||||
{ "SIS900", sis900_probe, pci_ioaddrs },
|
||||
#endif
|
||||
|
||||
4. Edit NIC to add sis900 and sis7016 to NIC list
|
||||
|
||||
# SIS 900 and SIS 7016
|
||||
sis900 sis900 0x1039,0x0900
|
||||
sis7016 sis900 0x1039,0x7016
|
||||
|
||||
5. Edit cards.h to add sis900 probe routine declaration
|
||||
|
||||
#ifdef INCLUDE_SIS900
|
||||
extern struct nic *sis900_probe(struct nic *, unsigned short *
|
||||
PCI_ARG(struct pci_device *));
|
||||
#endif
|
||||
|
||||
***********************************************************************
|
||||
|
||||
At this point, you can begin creating your driver source file. See
|
||||
the "Writing and Etherboot Driver" section of the Etherboot
|
||||
documentation for some hints. See the skel.c file for a starting
|
||||
point. If there is a Linux driver for the card, you may be able to
|
||||
use that. Copy and learn from existing Etherboot drivers (this is GPL
|
||||
/ Open Source software!).
|
||||
|
||||
Join the etherboot-developers and etherboot-users mailing lists
|
||||
(information is on etherboot.sourceforge.net) for information and
|
||||
assistance. We invite more developers to help improve Etherboot.
|
||||
|
||||
Visit the http://etherboot.sourceforge.net, http://thinguin.org,
|
||||
http://rom-o-matic.net, and http://ltsp.org sites for information and
|
||||
assistance.
|
||||
|
||||
Enjoy.
|
||||
-1160
File diff suppressed because it is too large.
Load diff
@@ -1,168 +0,0 @@
|
||||
/*-
|
||||
*
|
||||
* This software may be used and distributed according to the terms
|
||||
* of the GNU Public License, incorporated herein by reference.
|
||||
*
|
||||
* Module : sk_g16.h
|
||||
* Version : $Revision$
|
||||
*
|
||||
* Author : M.Hipp (mhipp@student.uni-tuebingen.de)
|
||||
* changes by : Patrick J.D. Weichmann
|
||||
*
|
||||
* Date Created : 94/05/25
|
||||
*
|
||||
* Description : In here are all necessary definitions of
|
||||
* the am7990 (LANCE) chip used for writing a
|
||||
* network device driver which uses this chip
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.3 2000-07-29 19:22:54 okuji
|
||||
* update the network support to etherboot-4.6.4.
|
||||
*
|
||||
-*/
|
||||
|
||||
#ifndef SK_G16_H
|
||||
|
||||
#define SK_G16_H
|
||||
|
||||
|
||||
/*
|
||||
* Control and Status Register 0 (CSR0) bit definitions
|
||||
*
|
||||
* (R=Readable) (W=Writeable) (S=Set on write) (C-Clear on write)
|
||||
*
|
||||
*/
|
||||
|
||||
#define CSR0_ERR 0x8000 /* Error summary (R) */
|
||||
#define CSR0_BABL 0x4000 /* Babble transmitter timeout error (RC) */
|
||||
#define CSR0_CERR 0x2000 /* Collision Error (RC) */
|
||||
#define CSR0_MISS 0x1000 /* Missed packet (RC) */
|
||||
#define CSR0_MERR 0x0800 /* Memory Error (RC) */
|
||||
#define CSR0_RINT 0x0400 /* Receiver Interrupt (RC) */
|
||||
#define CSR0_TINT 0x0200 /* Transmit Interrupt (RC) */
|
||||
#define CSR0_IDON 0x0100 /* Initialization Done (RC) */
|
||||
#define CSR0_INTR 0x0080 /* Interrupt Flag (R) */
|
||||
#define CSR0_INEA 0x0040 /* Interrupt Enable (RW) */
|
||||
#define CSR0_RXON 0x0020 /* Receiver on (R) */
|
||||
#define CSR0_TXON 0x0010 /* Transmitter on (R) */
|
||||
#define CSR0_TDMD 0x0008 /* Transmit Demand (RS) */
|
||||
#define CSR0_STOP 0x0004 /* Stop (RS) */
|
||||
#define CSR0_STRT 0x0002 /* Start (RS) */
|
||||
#define CSR0_INIT 0x0001 /* Initialize (RS) */
|
||||
|
||||
#define CSR0_CLRALL 0x7f00 /* mask for all clearable bits */
|
||||
|
||||
/*
|
||||
* Control and Status Register 3 (CSR3) bit definitions
|
||||
*
|
||||
*/
|
||||
|
||||
#define CSR3_BSWAP 0x0004 /* Byte Swap (RW) */
|
||||
#define CSR3_ACON 0x0002 /* ALE Control (RW) */
|
||||
#define CSR3_BCON 0x0001 /* Byte Control (RW) */
|
||||
|
||||
/*
|
||||
* Initialization Block Mode operation Bit Definitions.
|
||||
*/
|
||||
|
||||
#define MODE_PROM 0x8000 /* Promiscuous Mode */
|
||||
#define MODE_INTL 0x0040 /* Internal Loopback */
|
||||
#define MODE_DRTY 0x0020 /* Disable Retry */
|
||||
#define MODE_COLL 0x0010 /* Force Collision */
|
||||
#define MODE_DTCR 0x0008 /* Disable Transmit CRC) */
|
||||
#define MODE_LOOP 0x0004 /* Loopback */
|
||||
#define MODE_DTX 0x0002 /* Disable the Transmitter */
|
||||
#define MODE_DRX 0x0001 /* Disable the Receiver */
|
||||
|
||||
#define MODE_NORMAL 0x0000 /* Normal operation mode */
|
||||
|
||||
/*
|
||||
* Receive message descriptor status bit definitions.
|
||||
*/
|
||||
|
||||
#define RX_OWN 0x80 /* Owner bit 0 = host, 1 = lance */
|
||||
#define RX_ERR 0x40 /* Error Summary */
|
||||
#define RX_FRAM 0x20 /* Framing Error */
|
||||
#define RX_OFLO 0x10 /* Overflow Error */
|
||||
#define RX_CRC 0x08 /* CRC Error */
|
||||
#define RX_BUFF 0x04 /* Buffer Error */
|
||||
#define RX_STP 0x02 /* Start of Packet */
|
||||
#define RX_ENP 0x01 /* End of Packet */
|
||||
|
||||
|
||||
/*
|
||||
* Transmit message descriptor status bit definitions.
|
||||
*/
|
||||
|
||||
#define TX_OWN 0x80 /* Owner bit 0 = host, 1 = lance */
|
||||
#define TX_ERR 0x40 /* Error Summary */
|
||||
#define TX_MORE 0x10 /* More the 1 retry needed to Xmit */
|
||||
#define TX_ONE 0x08 /* One retry needed to Xmit */
|
||||
#define TX_DEF 0x04 /* Deferred */
|
||||
#define TX_STP 0x02 /* Start of Packet */
|
||||
#define TX_ENP 0x01 /* End of Packet */
|
||||
|
||||
/*
|
||||
* Transmit status (2) (valid if TX_ERR == 1)
|
||||
*/
|
||||
|
||||
#define TX_BUFF 0x8000 /* Buffering error (no ENP) */
|
||||
#define TX_UFLO 0x4000 /* Underflow (late memory) */
|
||||
#define TX_LCOL 0x1000 /* Late collision */
|
||||
#define TX_LCAR 0x0400 /* Loss of Carrier */
|
||||
#define TX_RTRY 0x0200 /* Failed after 16 retransmissions */
|
||||
#define TX_TDR 0x003f /* Time-domain-reflectometer-value */
|
||||
|
||||
|
||||
/*
|
||||
* Structures used for Communication with the LANCE
|
||||
*/
|
||||
|
||||
/* LANCE Initialize Block */
|
||||
|
||||
struct init_block
|
||||
{
|
||||
unsigned short mode; /* Mode Register */
|
||||
unsigned char paddr[6]; /* Physical Address (MAC) */
|
||||
unsigned char laddr[8]; /* Logical Filter Address (not used) */
|
||||
unsigned int rdrp; /* Receive Descriptor Ring pointer */
|
||||
unsigned int tdrp; /* Transmit Descriptor Ring pointer */
|
||||
};
|
||||
|
||||
|
||||
/* Receive Message Descriptor Entry */
|
||||
|
||||
struct rmd
|
||||
{
|
||||
union rmd_u
|
||||
{
|
||||
unsigned long buffer; /* Address of buffer */
|
||||
struct rmd_s
|
||||
{
|
||||
unsigned char unused[3];
|
||||
unsigned volatile char status; /* Status Bits */
|
||||
} s;
|
||||
} u;
|
||||
volatile short blen; /* Buffer Length (two's complement) */
|
||||
unsigned short mlen; /* Message Byte Count */
|
||||
};
|
||||
|
||||
|
||||
/* Transmit Message Descriptor Entry */
|
||||
|
||||
struct tmd
|
||||
{
|
||||
union tmd_u
|
||||
{
|
||||
unsigned long buffer; /* Address of buffer */
|
||||
struct tmd_s
|
||||
{
|
||||
unsigned char unused[3];
|
||||
unsigned volatile char status; /* Status Bits */
|
||||
} s;
|
||||
} u;
|
||||
unsigned short blen; /* Buffer Length (two's complement) */
|
||||
unsigned volatile short status2; /* Error Status Bits */
|
||||
};
|
||||
|
||||
#endif /* End of SK_G16_H */
|
||||
@@ -1,522 +0,0 @@
|
||||
/*------------------------------------------------------------------------
|
||||
* smc9000.c
|
||||
* This is a Etherboot driver for SMC's 9000 series of Ethernet cards.
|
||||
*
|
||||
* Copyright (C) 1998 Daniel Engström <daniel.engstrom@riksnett.no>
|
||||
* Based on the Linux SMC9000 driver, smc9194.c by Eric Stahlman
|
||||
* Copyright (C) 1996 by Erik Stahlman <eric@vt.edu>
|
||||
*
|
||||
* This software may be used and distributed according to the terms
|
||||
* of the GNU Public License, incorporated herein by reference.
|
||||
*
|
||||
* "Features" of the SMC chip:
|
||||
* 4608 byte packet memory. ( for the 91C92/4. Others have more )
|
||||
* EEPROM for configuration
|
||||
* AUI/TP selection
|
||||
*
|
||||
* Authors
|
||||
* Erik Stahlman <erik@vt.edu>
|
||||
* Daniel Engström <daniel.engstrom@riksnett.no>
|
||||
*
|
||||
* History
|
||||
* 98-09-25 Daniel Engström Etherboot driver crated from Eric's
|
||||
* Linux driver.
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
#define LINUX_OUT_MACROS 1
|
||||
#define SMC9000_VERBOSE 1
|
||||
#define SMC9000_DEBUG 0
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "cards.h"
|
||||
#include "smc9000.h"
|
||||
|
||||
# define _outb outb
|
||||
# define _outw outw
|
||||
|
||||
static const char smc9000_version[] = "Version 0.99 98-09-30";
|
||||
static unsigned int smc9000_base=0;
|
||||
static const char *interfaces[ 2 ] = { "TP", "AUI" };
|
||||
static const char *chip_ids[ 15 ] = {
|
||||
NULL, NULL, NULL,
|
||||
/* 3 */ "SMC91C90/91C92",
|
||||
/* 4 */ "SMC91C94",
|
||||
/* 5 */ "SMC91C95",
|
||||
NULL,
|
||||
/* 7 */ "SMC91C100",
|
||||
/* 8 */ "SMC91C100FD",
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL, NULL
|
||||
};
|
||||
static const char smc91c96_id[] = "SMC91C96";
|
||||
|
||||
/*
|
||||
* Function: smc_reset( int ioaddr )
|
||||
* Purpose:
|
||||
* This sets the SMC91xx chip to its normal state, hopefully from whatever
|
||||
* mess that any other DOS driver has put it in.
|
||||
*
|
||||
* Maybe I should reset more registers to defaults in here? SOFTRESET should
|
||||
* do that for me.
|
||||
*
|
||||
* Method:
|
||||
* 1. send a SOFT RESET
|
||||
* 2. wait for it to finish
|
||||
* 3. reset the memory management unit
|
||||
* 4. clear all interrupts
|
||||
*
|
||||
*/
|
||||
static void smc_reset(int ioaddr)
|
||||
{
|
||||
/* This resets the registers mostly to defaults, but doesn't
|
||||
* affect EEPROM. That seems unnecessary */
|
||||
SMC_SELECT_BANK(ioaddr, 0);
|
||||
_outw( RCR_SOFTRESET, ioaddr + RCR );
|
||||
|
||||
/* this should pause enough for the chip to be happy */
|
||||
SMC_DELAY(ioaddr);
|
||||
|
||||
/* Set the transmit and receive configuration registers to
|
||||
* default values */
|
||||
_outw(RCR_CLEAR, ioaddr + RCR);
|
||||
_outw(TCR_CLEAR, ioaddr + TCR);
|
||||
|
||||
/* Reset the MMU */
|
||||
SMC_SELECT_BANK(ioaddr, 2);
|
||||
_outw( MC_RESET, ioaddr + MMU_CMD );
|
||||
|
||||
/* Note: It doesn't seem that waiting for the MMU busy is needed here,
|
||||
* but this is a place where future chipsets _COULD_ break. Be wary
|
||||
* of issuing another MMU command right after this */
|
||||
_outb(0, ioaddr + INT_MASK);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
* Function: smc_probe( int ioaddr )
|
||||
*
|
||||
* Purpose:
|
||||
* Tests to see if a given ioaddr points to an SMC9xxx chip.
|
||||
* Returns a 0 on success
|
||||
*
|
||||
* Algorithm:
|
||||
* (1) see if the high byte of BANK_SELECT is 0x33
|
||||
* (2) compare the ioaddr with the base register's address
|
||||
* (3) see if I recognize the chip ID in the appropriate register
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
static int smc_probe( int ioaddr )
|
||||
{
|
||||
word bank;
|
||||
word revision_register;
|
||||
word base_address_register;
|
||||
|
||||
/* First, see if the high byte is 0x33 */
|
||||
bank = inw(ioaddr + BANK_SELECT);
|
||||
if ((bank & 0xFF00) != 0x3300) {
|
||||
return -1;
|
||||
}
|
||||
/* The above MIGHT indicate a device, but I need to write to further
|
||||
* test this. */
|
||||
_outw(0x0, ioaddr + BANK_SELECT);
|
||||
bank = inw(ioaddr + BANK_SELECT);
|
||||
if ((bank & 0xFF00) != 0x3300) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* well, we've already written once, so hopefully another time won't
|
||||
* hurt. This time, I need to switch the bank register to bank 1,
|
||||
* so I can access the base address register */
|
||||
SMC_SELECT_BANK(ioaddr, 1);
|
||||
base_address_register = inw(ioaddr + BASE);
|
||||
|
||||
if (ioaddr != (base_address_register >> 3 & 0x3E0)) {
|
||||
#ifdef SMC9000_VERBOSE
|
||||
printf("SMC9000: IOADDR %hX doesn't match configuration (%hX)."
|
||||
"Probably not a SMC chip\n",
|
||||
ioaddr, base_address_register >> 3 & 0x3E0);
|
||||
#endif
|
||||
/* well, the base address register didn't match. Must not have
|
||||
* been a SMC chip after all. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* check if the revision register is something that I recognize.
|
||||
* These might need to be added to later, as future revisions
|
||||
* could be added. */
|
||||
SMC_SELECT_BANK(ioaddr, 3);
|
||||
revision_register = inw(ioaddr + REVISION);
|
||||
if (!chip_ids[(revision_register >> 4) & 0xF]) {
|
||||
/* I don't recognize this chip, so... */
|
||||
#ifdef SMC9000_VERBOSE
|
||||
printf("SMC9000: IO %hX: Unrecognized revision register:"
|
||||
" %hX, Contact author.\n", ioaddr, revision_register);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* at this point I'll assume that the chip is an SMC9xxx.
|
||||
* It might be prudent to check a listing of MAC addresses
|
||||
* against the hardware address, or do some other tests. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* ETH_RESET - Reset adapter
|
||||
***************************************************************************/
|
||||
|
||||
static void smc9000_reset(struct nic *nic)
|
||||
{
|
||||
smc_reset(smc9000_base);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* ETH_TRANSMIT - Transmit a frame
|
||||
***************************************************************************/
|
||||
static void smc9000_transmit(
|
||||
struct nic *nic,
|
||||
const char *d, /* Destination */
|
||||
unsigned int t, /* Type */
|
||||
unsigned int s, /* size */
|
||||
const char *p) /* Packet */
|
||||
{
|
||||
word length; /* real, length incl. header */
|
||||
word numPages;
|
||||
unsigned long time_out;
|
||||
byte packet_no;
|
||||
word status;
|
||||
int i;
|
||||
|
||||
/* We dont pad here since we can have the hardware doing it for us */
|
||||
length = (s + ETH_HLEN + 1)&~1;
|
||||
|
||||
/* convert to MMU pages */
|
||||
numPages = length / 256;
|
||||
|
||||
if (numPages > 7 ) {
|
||||
#ifdef SMC9000_VERBOSE
|
||||
printf("SMC9000: Far too big packet error. \n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/* dont try more than, say 30 times */
|
||||
for (i=0;i<30;i++) {
|
||||
/* now, try to allocate the memory */
|
||||
SMC_SELECT_BANK(smc9000_base, 2);
|
||||
_outw(MC_ALLOC | numPages, smc9000_base + MMU_CMD);
|
||||
|
||||
status = 0;
|
||||
/* wait for the memory allocation to finnish */
|
||||
for (time_out = currticks() + 5*TICKS_PER_SEC; currticks() < time_out; ) {
|
||||
status = inb(smc9000_base + INTERRUPT);
|
||||
if ( status & IM_ALLOC_INT ) {
|
||||
/* acknowledge the interrupt */
|
||||
_outb(IM_ALLOC_INT, smc9000_base + INTERRUPT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((status & IM_ALLOC_INT) != 0 ) {
|
||||
/* We've got the memory */
|
||||
break;
|
||||
} else {
|
||||
printf("SMC9000: Memory allocation timed out, resetting MMU.\n");
|
||||
_outw(MC_RESET, smc9000_base + MMU_CMD);
|
||||
}
|
||||
}
|
||||
|
||||
/* If I get here, I _know_ there is a packet slot waiting for me */
|
||||
packet_no = inb(smc9000_base + PNR_ARR + 1);
|
||||
if (packet_no & 0x80) {
|
||||
/* or isn't there? BAD CHIP! */
|
||||
printf("SMC9000: Memory allocation failed. \n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* we have a packet address, so tell the card to use it */
|
||||
_outb(packet_no, smc9000_base + PNR_ARR);
|
||||
|
||||
/* point to the beginning of the packet */
|
||||
_outw(PTR_AUTOINC, smc9000_base + POINTER);
|
||||
|
||||
#if SMC9000_DEBUG > 2
|
||||
printf("Trying to xmit packet of length %hX\n", length );
|
||||
#endif
|
||||
|
||||
/* send the packet length ( +6 for status, length and ctl byte )
|
||||
* and the status word ( set to zeros ) */
|
||||
_outw(0, smc9000_base + DATA_1 );
|
||||
|
||||
/* send the packet length ( +6 for status words, length, and ctl) */
|
||||
_outb((length+6) & 0xFF, smc9000_base + DATA_1);
|
||||
_outb((length+6) >> 8 , smc9000_base + DATA_1);
|
||||
|
||||
/* Write the contents of the packet */
|
||||
|
||||
/* The ethernet header first... */
|
||||
outsw(smc9000_base + DATA_1, d, ETH_ALEN >> 1);
|
||||
outsw(smc9000_base + DATA_1, nic->node_addr, ETH_ALEN >> 1);
|
||||
_outw(htons(t), smc9000_base + DATA_1);
|
||||
|
||||
/* ... the data ... */
|
||||
outsw(smc9000_base + DATA_1 , p, s >> 1);
|
||||
|
||||
/* ... and the last byte, if there is one. */
|
||||
if ((s & 1) == 0) {
|
||||
_outw(0, smc9000_base + DATA_1);
|
||||
} else {
|
||||
_outb(p[s-1], smc9000_base + DATA_1);
|
||||
_outb(0x20, smc9000_base + DATA_1);
|
||||
}
|
||||
|
||||
/* and let the chipset deal with it */
|
||||
_outw(MC_ENQUEUE , smc9000_base + MMU_CMD);
|
||||
|
||||
status = 0; time_out = currticks() + 5*TICKS_PER_SEC;
|
||||
do {
|
||||
status = inb(smc9000_base + INTERRUPT);
|
||||
|
||||
if ((status & IM_TX_INT ) != 0) {
|
||||
word tx_status;
|
||||
|
||||
/* ack interrupt */
|
||||
_outb(IM_TX_INT, smc9000_base + INTERRUPT);
|
||||
|
||||
packet_no = inw(smc9000_base + FIFO_PORTS);
|
||||
packet_no &= 0x7F;
|
||||
|
||||
/* select this as the packet to read from */
|
||||
_outb( packet_no, smc9000_base + PNR_ARR );
|
||||
|
||||
/* read the first word from this packet */
|
||||
_outw( PTR_AUTOINC | PTR_READ, smc9000_base + POINTER );
|
||||
|
||||
tx_status = inw( smc9000_base + DATA_1 );
|
||||
|
||||
if (0 == (tx_status & TS_SUCCESS)) {
|
||||
#ifdef SMC9000_VERBOSE
|
||||
printf("SMC9000: TX FAIL STATUS: %hX \n", tx_status);
|
||||
#endif
|
||||
/* re-enable transmit */
|
||||
SMC_SELECT_BANK(smc9000_base, 0);
|
||||
_outw(inw(smc9000_base + TCR ) | TCR_ENABLE, smc9000_base + TCR );
|
||||
}
|
||||
|
||||
/* kill the packet */
|
||||
SMC_SELECT_BANK(smc9000_base, 2);
|
||||
_outw(MC_FREEPKT, smc9000_base + MMU_CMD);
|
||||
|
||||
return;
|
||||
}
|
||||
}while(currticks() < time_out);
|
||||
|
||||
printf("SMC9000: Waring TX timed out, resetting board\n");
|
||||
smc_reset(smc9000_base);
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* ETH_POLL - Wait for a frame
|
||||
***************************************************************************/
|
||||
static int smc9000_poll(struct nic *nic)
|
||||
{
|
||||
if(!smc9000_base)
|
||||
return 0;
|
||||
|
||||
SMC_SELECT_BANK(smc9000_base, 2);
|
||||
if (inw(smc9000_base + FIFO_PORTS) & FP_RXEMPTY)
|
||||
return 0;
|
||||
|
||||
/* start reading from the start of the packet */
|
||||
_outw(PTR_READ | PTR_RCV | PTR_AUTOINC, smc9000_base + POINTER);
|
||||
|
||||
/* First read the status and check that we're ok */
|
||||
if (!(inw(smc9000_base + DATA_1) & RS_ERRORS)) {
|
||||
/* Next: read the packet length and mask off the top bits */
|
||||
nic->packetlen = (inw(smc9000_base + DATA_1) & 0x07ff);
|
||||
|
||||
/* the packet length includes the 3 extra words */
|
||||
nic->packetlen -= 6;
|
||||
#if SMC9000_DEBUG > 2
|
||||
printf(" Reading %d words (and %d byte(s))\n",
|
||||
(nic->packetlen >> 1), nic->packetlen & 1);
|
||||
#endif
|
||||
/* read the packet (and the last "extra" word) */
|
||||
insw(smc9000_base + DATA_1, nic->packet, (nic->packetlen+2) >> 1);
|
||||
/* is there an odd last byte ? */
|
||||
if (nic->packet[nic->packetlen+1] & 0x20)
|
||||
nic->packetlen++;
|
||||
|
||||
/* error or good, tell the card to get rid of this packet */
|
||||
_outw(MC_RELEASE, smc9000_base + MMU_CMD);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("SMC9000: RX error\n");
|
||||
/* error or good, tell the card to get rid of this packet */
|
||||
_outw(MC_RELEASE, smc9000_base + MMU_CMD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void smc9000_disable(struct nic *nic)
|
||||
{
|
||||
if(!smc9000_base)
|
||||
return;
|
||||
|
||||
/* no more interrupts for me */
|
||||
SMC_SELECT_BANK(smc9000_base, 2);
|
||||
_outb( 0, smc9000_base + INT_MASK);
|
||||
|
||||
/* and tell the card to stay away from that nasty outside world */
|
||||
SMC_SELECT_BANK(smc9000_base, 0);
|
||||
_outb( RCR_CLEAR, smc9000_base + RCR );
|
||||
_outb( TCR_CLEAR, smc9000_base + TCR );
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* ETH_PROBE - Look for an adapter
|
||||
***************************************************************************/
|
||||
|
||||
struct nic *smc9000_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||
{
|
||||
unsigned short revision;
|
||||
int memory;
|
||||
int media;
|
||||
const char * version_string;
|
||||
const char * if_string;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* the SMC9000 can be at any of the following port addresses. To change,
|
||||
* for a slightly different card, you can add it to the array. Keep in
|
||||
* mind that the array must end in zero.
|
||||
*/
|
||||
static unsigned short portlist[] = {
|
||||
#ifdef SMC9000_SCAN
|
||||
SMC9000_SCAN,
|
||||
#else
|
||||
0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0,
|
||||
0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0,
|
||||
#endif
|
||||
0 };
|
||||
|
||||
printf("\nSMC9000 %s\n", smc9000_version);
|
||||
#ifdef SMC9000_VERBOSE
|
||||
printf("Copyright (C) 1998 Daniel Engstr\x94m\n");
|
||||
printf("Copyright (C) 1996 Eric Stahlman\n");
|
||||
#endif
|
||||
/* if no addresses supplied, fall back on defaults */
|
||||
if (probe_addrs == 0 || probe_addrs[0] == 0)
|
||||
probe_addrs = portlist;
|
||||
|
||||
/* check every ethernet address */
|
||||
for (i = 0; probe_addrs[i]; i++) {
|
||||
/* check this specific address */
|
||||
if (smc_probe(probe_addrs[i]) == 0)
|
||||
smc9000_base = probe_addrs[i];
|
||||
}
|
||||
|
||||
/* couldn't find anything */
|
||||
if(0 == smc9000_base)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Get the MAC address ( bank 1, regs 4 - 9 )
|
||||
*/
|
||||
SMC_SELECT_BANK(smc9000_base, 1);
|
||||
for ( i = 0; i < 6; i += 2 ) {
|
||||
word address;
|
||||
|
||||
address = inw(smc9000_base + ADDR0 + i);
|
||||
nic->node_addr[i+1] = address >> 8;
|
||||
nic->node_addr[i] = address & 0xFF;
|
||||
}
|
||||
|
||||
|
||||
/* get the memory information */
|
||||
SMC_SELECT_BANK(smc9000_base, 0);
|
||||
memory = ( inw(smc9000_base + MCR) >> 9 ) & 0x7; /* multiplier */
|
||||
memory *= 256 * (inw(smc9000_base + MIR) & 0xFF);
|
||||
|
||||
/*
|
||||
* Now, I want to find out more about the chip. This is sort of
|
||||
* redundant, but it's cleaner to have it in both, rather than having
|
||||
* one VERY long probe procedure.
|
||||
*/
|
||||
SMC_SELECT_BANK(smc9000_base, 3);
|
||||
revision = inw(smc9000_base + REVISION);
|
||||
version_string = chip_ids[(revision >> 4) & 0xF];
|
||||
|
||||
if (((revision & 0xF0) >> 4 == CHIP_9196) &&
|
||||
((revision & 0x0F) >= REV_9196)) {
|
||||
/* This is a 91c96. 'c96 has the same chip id as 'c94 (4) but
|
||||
* a revision starting at 6 */
|
||||
version_string = smc91c96_id;
|
||||
}
|
||||
|
||||
if ( !version_string ) {
|
||||
/* I shouldn't get here because this call was done before.... */
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* is it using AUI or 10BaseT ? */
|
||||
SMC_SELECT_BANK(smc9000_base, 1);
|
||||
if (inw(smc9000_base + CONFIG) & CFG_AUI_SELECT)
|
||||
media = 2;
|
||||
else
|
||||
media = 1;
|
||||
|
||||
if_string = interfaces[media - 1];
|
||||
|
||||
/* now, reset the chip, and put it into a known state */
|
||||
smc_reset(smc9000_base);
|
||||
|
||||
printf("%s rev:%d I/O port:%hX Interface:%s RAM:%d bytes \n",
|
||||
version_string, revision & 0xF,
|
||||
smc9000_base, if_string, memory );
|
||||
/*
|
||||
* Print the Ethernet address
|
||||
*/
|
||||
printf("Ethernet MAC address: %!\n", nic->node_addr);
|
||||
|
||||
SMC_SELECT_BANK(smc9000_base, 0);
|
||||
|
||||
/* see the header file for options in TCR/RCR NORMAL*/
|
||||
_outw(TCR_NORMAL, smc9000_base + TCR);
|
||||
_outw(RCR_NORMAL, smc9000_base + RCR);
|
||||
|
||||
/* Select which interface to use */
|
||||
SMC_SELECT_BANK(smc9000_base, 1);
|
||||
if ( media == 1 ) {
|
||||
_outw( inw( smc9000_base + CONFIG ) & ~CFG_AUI_SELECT,
|
||||
smc9000_base + CONFIG );
|
||||
}
|
||||
else if ( media == 2 ) {
|
||||
_outw( inw( smc9000_base + CONFIG ) | CFG_AUI_SELECT,
|
||||
smc9000_base + CONFIG );
|
||||
}
|
||||
|
||||
nic->reset = smc9000_reset;
|
||||
nic->poll = smc9000_poll;
|
||||
nic->transmit = smc9000_transmit;
|
||||
nic->disable = smc9000_disable;
|
||||
|
||||
|
||||
return nic;
|
||||
|
||||
out:
|
||||
#ifdef SMC9000_VERBOSE
|
||||
printf("No SMC9000 adapters found\n");
|
||||
#endif
|
||||
smc9000_base = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,205 +0,0 @@
|
||||
/*------------------------------------------------------------------------
|
||||
* smc9000.h
|
||||
*
|
||||
* Copyright (C) 1998 by Daniel Engström
|
||||
* Copyright (C) 1996 by Erik Stahlman
|
||||
*
|
||||
* This software may be used and distributed according to the terms
|
||||
* of the GNU Public License, incorporated herein by reference.
|
||||
*
|
||||
* This file contains register information and access macros for
|
||||
* the SMC91xxx chipset.
|
||||
*
|
||||
* Information contained in this file was obtained from the SMC91C94
|
||||
* manual from SMC. To get a copy, if you really want one, you can find
|
||||
* information under www.smsc.com in the components division.
|
||||
* ( this thanks to advice from Donald Becker ).
|
||||
*
|
||||
* Authors
|
||||
* Daniel Engström <daniel.engstrom@riksnett.no>
|
||||
* Erik Stahlman <erik@vt.edu>
|
||||
*
|
||||
* History
|
||||
* 96-01-06 Erik Stahlman moved definitions here from main .c
|
||||
* file
|
||||
* 96-01-19 Erik Stahlman polished this up some, and added
|
||||
* better error handling
|
||||
* 98-09-25 Daniel Engström adjusted for Etherboot
|
||||
* 98-09-27 Daniel Engström moved some static strings back to the
|
||||
* main .c file
|
||||
* --------------------------------------------------------------------------*/
|
||||
#ifndef _SMC9000_H_
|
||||
# define _SMC9000_H_
|
||||
|
||||
/* I want some simple types */
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned long int dword;
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
*
|
||||
* A description of the SMC registers is probably in order here,
|
||||
* although for details, the SMC datasheet is invaluable.
|
||||
*
|
||||
* Basically, the chip has 4 banks of registers ( 0 to 3 ), which
|
||||
* are accessed by writing a number into the BANK_SELECT register
|
||||
* ( I also use a SMC_SELECT_BANK macro for this ).
|
||||
*
|
||||
* The banks are configured so that for most purposes, bank 2 is all
|
||||
* that is needed for simple run time tasks.
|
||||
* ----------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Bank Select Register:
|
||||
*
|
||||
* yyyy yyyy 0000 00xx
|
||||
* xx = bank number
|
||||
* yyyy yyyy = 0x33, for identification purposes.
|
||||
*/
|
||||
#define BANK_SELECT 14
|
||||
|
||||
/* BANK 0 */
|
||||
|
||||
#define TCR 0 /* transmit control register */
|
||||
#define TCR_ENABLE 0x0001 /* if this is 1, we can transmit */
|
||||
#define TCR_FDUPLX 0x0800 /* receive packets sent out */
|
||||
#define TCR_STP_SQET 0x1000 /* stop transmitting if Signal quality error */
|
||||
#define TCR_MON_CNS 0x0400 /* monitors the carrier status */
|
||||
#define TCR_PAD_ENABLE 0x0080 /* pads short packets to 64 bytes */
|
||||
|
||||
#define TCR_CLEAR 0 /* do NOTHING */
|
||||
/* the normal settings for the TCR register : */
|
||||
#define TCR_NORMAL (TCR_ENABLE | TCR_PAD_ENABLE)
|
||||
|
||||
|
||||
#define EPH_STATUS 2
|
||||
#define ES_LINK_OK 0x4000 /* is the link integrity ok ? */
|
||||
|
||||
#define RCR 4
|
||||
#define RCR_SOFTRESET 0x8000 /* resets the chip */
|
||||
#define RCR_STRIP_CRC 0x200 /* strips CRC */
|
||||
#define RCR_ENABLE 0x100 /* IFF this is set, we can receive packets */
|
||||
#define RCR_ALMUL 0x4 /* receive all multicast packets */
|
||||
#define RCR_PROMISC 0x2 /* enable promiscuous mode */
|
||||
|
||||
/* the normal settings for the RCR register : */
|
||||
#define RCR_NORMAL (RCR_STRIP_CRC | RCR_ENABLE)
|
||||
#define RCR_CLEAR 0x0 /* set it to a base state */
|
||||
|
||||
#define COUNTER 6
|
||||
#define MIR 8
|
||||
#define MCR 10
|
||||
/* 12 is reserved */
|
||||
|
||||
/* BANK 1 */
|
||||
#define CONFIG 0
|
||||
#define CFG_AUI_SELECT 0x100
|
||||
#define BASE 2
|
||||
#define ADDR0 4
|
||||
#define ADDR1 6
|
||||
#define ADDR2 8
|
||||
#define GENERAL 10
|
||||
#define CONTROL 12
|
||||
#define CTL_POWERDOWN 0x2000
|
||||
#define CTL_LE_ENABLE 0x80
|
||||
#define CTL_CR_ENABLE 0x40
|
||||
#define CTL_TE_ENABLE 0x0020
|
||||
#define CTL_AUTO_RELEASE 0x0800
|
||||
#define CTL_EPROM_ACCESS 0x0003 /* high if Eprom is being read */
|
||||
|
||||
/* BANK 2 */
|
||||
#define MMU_CMD 0
|
||||
#define MC_BUSY 1 /* only readable bit in the register */
|
||||
#define MC_NOP 0
|
||||
#define MC_ALLOC 0x20 /* or with number of 256 byte packets */
|
||||
#define MC_RESET 0x40
|
||||
#define MC_REMOVE 0x60 /* remove the current rx packet */
|
||||
#define MC_RELEASE 0x80 /* remove and release the current rx packet */
|
||||
#define MC_FREEPKT 0xA0 /* Release packet in PNR register */
|
||||
#define MC_ENQUEUE 0xC0 /* Enqueue the packet for transmit */
|
||||
|
||||
#define PNR_ARR 2
|
||||
#define FIFO_PORTS 4
|
||||
|
||||
#define FP_RXEMPTY 0x8000
|
||||
#define FP_TXEMPTY 0x80
|
||||
|
||||
#define POINTER 6
|
||||
#define PTR_READ 0x2000
|
||||
#define PTR_RCV 0x8000
|
||||
#define PTR_AUTOINC 0x4000
|
||||
#define PTR_AUTO_INC 0x0040
|
||||
|
||||
#define DATA_1 8
|
||||
#define DATA_2 10
|
||||
#define INTERRUPT 12
|
||||
|
||||
#define INT_MASK 13
|
||||
#define IM_RCV_INT 0x1
|
||||
#define IM_TX_INT 0x2
|
||||
#define IM_TX_EMPTY_INT 0x4
|
||||
#define IM_ALLOC_INT 0x8
|
||||
#define IM_RX_OVRN_INT 0x10
|
||||
#define IM_EPH_INT 0x20
|
||||
#define IM_ERCV_INT 0x40 /* not on SMC9192 */
|
||||
|
||||
/* BANK 3 */
|
||||
#define MULTICAST1 0
|
||||
#define MULTICAST2 2
|
||||
#define MULTICAST3 4
|
||||
#define MULTICAST4 6
|
||||
#define MGMT 8
|
||||
#define REVISION 10 /* ( hi: chip id low: rev # ) */
|
||||
|
||||
|
||||
/* this is NOT on SMC9192 */
|
||||
#define ERCV 12
|
||||
|
||||
/* Note that 9194 and 9196 have the smame chip id,
|
||||
* the 9196 will have revisions starting at 6 */
|
||||
#define CHIP_9190 3
|
||||
#define CHIP_9194 4
|
||||
#define CHIP_9195 5
|
||||
#define CHIP_9196 4
|
||||
#define CHIP_91100 7
|
||||
#define CHIP_91100FD 8
|
||||
|
||||
#define REV_9196 6
|
||||
|
||||
/*
|
||||
* Transmit status bits
|
||||
*/
|
||||
#define TS_SUCCESS 0x0001
|
||||
#define TS_LOSTCAR 0x0400
|
||||
#define TS_LATCOL 0x0200
|
||||
#define TS_16COL 0x0010
|
||||
|
||||
/*
|
||||
* Receive status bits
|
||||
*/
|
||||
#define RS_ALGNERR 0x8000
|
||||
#define RS_BADCRC 0x2000
|
||||
#define RS_ODDFRAME 0x1000
|
||||
#define RS_TOOLONG 0x0800
|
||||
#define RS_TOOSHORT 0x0400
|
||||
#define RS_MULTICAST 0x0001
|
||||
#define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT)
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* I define some macros to make it easier to do somewhat common
|
||||
* or slightly complicated, repeated tasks.
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
/* select a register bank, 0 to 3 */
|
||||
|
||||
#define SMC_SELECT_BANK(x, y) { _outw( y, x + BANK_SELECT ); }
|
||||
|
||||
/* define a small delay for the reset */
|
||||
#define SMC_DELAY(x) { inw( x + RCR );\
|
||||
inw( x + RCR );\
|
||||
inw( x + RCR ); }
|
||||
|
||||
|
||||
#endif /* _SMC_9000_H_ */
|
||||
|
||||
-255
@@ -1,255 +0,0 @@
|
||||
/**************************************************************************
|
||||
Etherboot - BOOTP/TFTP Bootstrap Program
|
||||
|
||||
TIARA (Fujitsu Etherstar) NIC driver for Etherboot
|
||||
Copyright (c) Ken Yap 1998
|
||||
|
||||
Information gleaned from:
|
||||
|
||||
TIARA.ASM Packet driver by Brian Fisher, Queens U, Kingston, Ontario
|
||||
Fujitsu MB86960 spec sheet (different chip but same family)
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* 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, or (at
|
||||
* your option) any later version.
|
||||
*/
|
||||
|
||||
/* to get some global routines like printf */
|
||||
#include "etherboot.h"
|
||||
/* to get the interface to the body of the program */
|
||||
#include "nic.h"
|
||||
#include "cards.h"
|
||||
|
||||
/*
|
||||
EtherStar I/O Register offsets
|
||||
*/
|
||||
|
||||
/* Offsets of registers */
|
||||
#define DLCR_XMIT_STAT 0x00
|
||||
#define DLCR_XMIT_MASK 0x01
|
||||
#define DLCR_RECV_STAT 0x02
|
||||
#define DLCR_RECV_MASK 0x03
|
||||
#define DLCR_XMIT_MODE 0x04
|
||||
#define DLCR_RECV_MODE 0x05
|
||||
#define DLCR_ENABLE 0x06
|
||||
#define DLCR_TDR_LOW 0x07
|
||||
#define DLCR_NODE_ID 0x08
|
||||
#define DLCR_TDR_HIGH 0x0F
|
||||
#define BMPR_MEM_PORT 0x10
|
||||
#define BMPR_PKT_LEN 0x12
|
||||
#define BMPR_DMA_ENABLE 0x14
|
||||
#define PROM_ID 0x18
|
||||
|
||||
#define TMST 0x80
|
||||
#define TMT_OK 0x80
|
||||
#define TMT_16COLL 0x02
|
||||
#define BUF_EMPTY 0x40
|
||||
|
||||
#define CARD_DISABLE 0x80 /* written to DLCR_ENABLE to disable card */
|
||||
#define CARD_ENABLE 0 /* written to DLCR_ENABLE to enable card */
|
||||
|
||||
#define CLEAR_STATUS 0x0F /* used to clear status info */
|
||||
/*
|
||||
00001111B
|
||||
!!!!!!!!--------
|
||||
!!!!!!!+--------CLEAR BUS WRITE ERROR
|
||||
!!!!!!+---------CLEAR 16 COLLISION
|
||||
!!!!!+----------CLEAR COLLISION
|
||||
!!!!+-----------CLEAR UNDERFLOW
|
||||
!!!+------------NC
|
||||
!!+-------------NC
|
||||
!+--------------NC
|
||||
+---------------NC
|
||||
*/
|
||||
|
||||
#define NO_TX_IRQS 0 /* written to clear transmit IRQs */
|
||||
|
||||
#define CLR_RCV_STATUS 0xCF /* clears receive status */
|
||||
|
||||
#define EN_RCV_IRQS 0x80 /* enable receive interrupts */
|
||||
/*
|
||||
10000000B
|
||||
!!!!!!!!--------
|
||||
!!!!!!!+--------ENABLE OVERFLOW
|
||||
!!!!!!+---------ENABLE CRC
|
||||
!!!!!+----------ENABLE ALIGN
|
||||
!!!!+-----------ENABLE SHORT PKT
|
||||
!!!+------------DISABLE REMOTE RESET
|
||||
!!+-------------RESERVED
|
||||
!+--------------RESERVED
|
||||
+---------------ENABLE PKT READY
|
||||
*/
|
||||
|
||||
#define XMIT_MODE 0x02
|
||||
/*
|
||||
00000010B
|
||||
!!!!!!!!---------ENABLE CARRIER DETECT
|
||||
!!!!!!!+---------DISABLE LOOPBACK
|
||||
*/
|
||||
|
||||
#define RECV_MODE 0x02
|
||||
/*
|
||||
00000010B
|
||||
!!!!!!!!---------ACCEPT ALL PACKETS
|
||||
!!!!!!!+---------ACCEPT PHYSICAL, MULTICAST, AND
|
||||
!!!!!!+----------BROADCAST PACKETS
|
||||
!!!!!+-----------DISABLE REMOTE RESET
|
||||
!!!!+------------DISABLE SHORT PACKETS
|
||||
!!!+-------------USE 6 BYTE ADDRESS
|
||||
!!+--------------NC
|
||||
!+---------------NC
|
||||
+----------------DISABLE CRC TEST MODE
|
||||
*/
|
||||
|
||||
/* NIC specific static variables go here */
|
||||
|
||||
static unsigned short ioaddr;
|
||||
|
||||
/**************************************************************************
|
||||
RESET - Reset adapter
|
||||
***************************************************************************/
|
||||
static void tiara_reset(struct nic *nic)
|
||||
{
|
||||
int i;
|
||||
|
||||
outb(CARD_DISABLE, ioaddr + DLCR_ENABLE);
|
||||
outb(CLEAR_STATUS, ioaddr + DLCR_XMIT_STAT);
|
||||
outb(NO_TX_IRQS, ioaddr + DLCR_XMIT_MASK);
|
||||
outb(CLR_RCV_STATUS, ioaddr + DLCR_RECV_STAT);
|
||||
outb(XMIT_MODE, ioaddr + DLCR_XMIT_MODE);
|
||||
outb(RECV_MODE, ioaddr + DLCR_RECV_MODE);
|
||||
/* Vacuum recv buffer */
|
||||
while ((inb(ioaddr + DLCR_RECV_MODE) & BUF_EMPTY) == 0)
|
||||
inb(ioaddr + BMPR_MEM_PORT);
|
||||
/* Set node address */
|
||||
for (i = 0; i < ETH_ALEN; ++i)
|
||||
outb(nic->node_addr[i], ioaddr + DLCR_NODE_ID + i);
|
||||
outb(CLR_RCV_STATUS, ioaddr + DLCR_RECV_STAT);
|
||||
outb(CARD_ENABLE, ioaddr + DLCR_ENABLE);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
POLL - Wait for a frame
|
||||
***************************************************************************/
|
||||
static int tiara_poll(struct nic *nic)
|
||||
{
|
||||
unsigned int len;
|
||||
|
||||
if (inb(ioaddr + DLCR_RECV_MODE) & BUF_EMPTY)
|
||||
return (0);
|
||||
/* Ack packet */
|
||||
outw(CLR_RCV_STATUS, ioaddr + DLCR_RECV_STAT);
|
||||
len = inw(ioaddr + BMPR_MEM_PORT); /* throw away status */
|
||||
len = inw(ioaddr + BMPR_MEM_PORT);
|
||||
/* Drop overlength packets */
|
||||
if (len > ETH_FRAME_LEN)
|
||||
return (0); /* should we drain the buffer? */
|
||||
insw(ioaddr + BMPR_MEM_PORT, nic->packet, len / 2);
|
||||
/* If it's our own, drop it */
|
||||
if (memcmp(nic->packet + ETH_ALEN, nic->node_addr, ETH_ALEN) == 0)
|
||||
return (0);
|
||||
nic->packetlen = len;
|
||||
return (1);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
TRANSMIT - Transmit a frame
|
||||
***************************************************************************/
|
||||
static void tiara_transmit(
|
||||
struct nic *nic,
|
||||
const char *d, /* Destination */
|
||||
unsigned int t, /* Type */
|
||||
unsigned int s, /* size */
|
||||
const char *p) /* Packet */
|
||||
{
|
||||
unsigned int len;
|
||||
unsigned long time;
|
||||
|
||||
len = s + ETH_HLEN;
|
||||
if (len < ETH_ZLEN)
|
||||
len = ETH_ZLEN;
|
||||
t = htons(t);
|
||||
outsw(ioaddr + BMPR_MEM_PORT, d, ETH_ALEN / 2);
|
||||
outsw(ioaddr + BMPR_MEM_PORT, nic->node_addr, ETH_ALEN / 2);
|
||||
outw(t, ioaddr + BMPR_MEM_PORT);
|
||||
outsw(ioaddr + BMPR_MEM_PORT, p, s / 2);
|
||||
if (s & 1) /* last byte */
|
||||
outb(p[s-1], ioaddr + BMPR_MEM_PORT);
|
||||
while (s++ < ETH_ZLEN - ETH_HLEN) /* pad */
|
||||
outb(0, ioaddr + BMPR_MEM_PORT);
|
||||
outw(len | (TMST << 8), ioaddr + BMPR_PKT_LEN);
|
||||
/* wait for transmit complete */
|
||||
time = currticks() + TICKS_PER_SEC; /* wait one second */
|
||||
while (currticks() < time && (inb(ioaddr) & (TMT_OK|TMT_16COLL)) == 0)
|
||||
;
|
||||
if ((inb(ioaddr) & (TMT_OK|TMT_16COLL)) == 0)
|
||||
printf("Tiara timed out on transmit\n");
|
||||
/* Do we need to ack the transmit? */
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
DISABLE - Turn off ethernet interface
|
||||
***************************************************************************/
|
||||
static void tiara_disable(struct nic *nic)
|
||||
{
|
||||
/* Apparently only a power down can do this properly */
|
||||
outb(CARD_DISABLE, ioaddr + DLCR_ENABLE);
|
||||
}
|
||||
|
||||
static int tiara_probe1(struct nic *nic)
|
||||
{
|
||||
/* Hope all the Tiara cards have this vendor prefix */
|
||||
static char vendor_prefix[] = { 0x08, 0x00, 0x1A };
|
||||
static char all_ones[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ETH_ALEN; ++i)
|
||||
nic->node_addr[i] = inb(ioaddr + PROM_ID + i);
|
||||
if (memcmp(nic->node_addr, vendor_prefix, sizeof(vendor_prefix)) != 0)
|
||||
return (0);
|
||||
if (memcmp(nic->node_addr, all_ones, sizeof(all_ones)) == 0)
|
||||
return (0);
|
||||
printf("\nTiara ioaddr %#hX, addr %!\n", ioaddr, nic->node_addr);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
PROBE - Look for an adapter, this routine's visible to the outside
|
||||
***************************************************************************/
|
||||
struct nic *tiara_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||
{
|
||||
/* missing entries are addresses usually already used */
|
||||
static unsigned short io_addrs[] = {
|
||||
0x100, 0x120, 0x140, 0x160,
|
||||
0x180, 0x1A0, 0x1C0, 0x1E0,
|
||||
0x200, 0x220, 0x240, /*Par*/
|
||||
0x280, 0x2A0, 0x2C0, /*Ser*/
|
||||
0x300, 0x320, 0x340, /*Par*/
|
||||
0x380, /*Vid,Par*/ 0x3C0, /*Ser*/
|
||||
0x0
|
||||
};
|
||||
unsigned short *p;
|
||||
|
||||
/* if probe_addrs is 0, then routine can use a hardwired default */
|
||||
if (probe_addrs == 0)
|
||||
probe_addrs = io_addrs;
|
||||
for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
|
||||
if (tiara_probe1(nic))
|
||||
break;
|
||||
/* if board found */
|
||||
if (ioaddr != 0)
|
||||
{
|
||||
tiara_reset(nic);
|
||||
/* point to NIC specific routines */
|
||||
nic->reset = tiara_reset;
|
||||
nic->poll = tiara_poll;
|
||||
nic->transmit = tiara_transmit;
|
||||
nic->disable = tiara_disable;
|
||||
return nic;
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
-127
@@ -1,127 +0,0 @@
|
||||
/* A couple of routines to implement a low-overhead timer for drivers */
|
||||
|
||||
/*
|
||||
* 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, or (at
|
||||
* your option) any later version.
|
||||
*/
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "timer.h"
|
||||
|
||||
void load_timer2(unsigned int ticks)
|
||||
{
|
||||
/* Set up the timer gate, turn off the speaker */
|
||||
outb((inb(PPC_PORTB) & ~PPCB_SPKR) | PPCB_T2GATE, PPC_PORTB);
|
||||
outb(TIMER2_SEL|WORD_ACCESS|MODE0|BINARY_COUNT, TIMER_MODE_PORT);
|
||||
outb(ticks & 0xFF, TIMER2_PORT);
|
||||
outb(ticks >> 8, TIMER2_PORT);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_TSC_CURRTICKS)
|
||||
#define rdtsc(low,high) \
|
||||
__asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
|
||||
|
||||
#define rdtscll(val) \
|
||||
__asm__ __volatile__ ("rdtsc" : "=A" (val))
|
||||
|
||||
|
||||
#define HZ TICKS_PER_SEC
|
||||
#define CLOCK_TICK_RATE 1193180U /* Underlying HZ */
|
||||
/* LATCH is used in the interval timer and ftape setup. */
|
||||
#define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */
|
||||
|
||||
|
||||
/* ------ Calibrate the TSC -------
|
||||
* Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
|
||||
* Too much 64-bit arithmetic here to do this cleanly in C, and for
|
||||
* accuracy's sake we want to keep the overhead on the CTC speaker (channel 2)
|
||||
* output busy loop as low as possible. We avoid reading the CTC registers
|
||||
* directly because of the awkward 8-bit access mechanism of the 82C54
|
||||
* device.
|
||||
*/
|
||||
|
||||
#define CALIBRATE_LATCH (5 * LATCH)
|
||||
|
||||
static unsigned long long calibrate_tsc(void)
|
||||
{
|
||||
/* Set the Gate high, disable speaker */
|
||||
outb((inb(0x61) & ~0x02) | 0x01, 0x61);
|
||||
|
||||
/*
|
||||
* Now let's take care of CTC channel 2
|
||||
*
|
||||
* Set the Gate high, program CTC channel 2 for mode 0,
|
||||
* (interrupt on terminal count mode), binary count,
|
||||
* load 5 * LATCH count, (LSB and MSB) to begin countdown.
|
||||
*/
|
||||
outb(0xb0, 0x43); /* binary, mode 0, LSB/MSB, Ch 2 */
|
||||
outb(CALIBRATE_LATCH & 0xff, 0x42); /* LSB of count */
|
||||
outb(CALIBRATE_LATCH >> 8, 0x42); /* MSB of count */
|
||||
|
||||
{
|
||||
unsigned long startlow, starthigh;
|
||||
unsigned long endlow, endhigh;
|
||||
unsigned long count;
|
||||
|
||||
rdtsc(startlow,starthigh);
|
||||
count = 0;
|
||||
do {
|
||||
count++;
|
||||
} while ((inb(0x61) & 0x20) == 0);
|
||||
rdtsc(endlow,endhigh);
|
||||
|
||||
/* Error: ECTCNEVERSET */
|
||||
if (count <= 1)
|
||||
goto bad_ctc;
|
||||
|
||||
/* 64-bit subtract - gcc just messes up with long longs */
|
||||
__asm__("subl %2,%0\n\t"
|
||||
"sbbl %3,%1"
|
||||
:"=a" (endlow), "=d" (endhigh)
|
||||
:"g" (startlow), "g" (starthigh),
|
||||
"0" (endlow), "1" (endhigh));
|
||||
|
||||
/* Error: ECPUTOOFAST */
|
||||
if (endhigh)
|
||||
goto bad_ctc;
|
||||
|
||||
endlow /= 5;
|
||||
return endlow;
|
||||
}
|
||||
|
||||
/*
|
||||
* The CTC wasn't reliable: we got a hit on the very first read,
|
||||
* or the CPU was so fast/slow that the quotient wouldn't fit in
|
||||
* 32 bits..
|
||||
*/
|
||||
bad_ctc:
|
||||
printf("bad_ctc\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned long currticks(void)
|
||||
{
|
||||
static unsigned long clocks_per_tick;
|
||||
unsigned long clocks_high, clocks_low;
|
||||
unsigned long currticks;
|
||||
if (!clocks_per_tick) {
|
||||
clocks_per_tick = calibrate_tsc();
|
||||
printf("clocks_per_tick = %d\n", clocks_per_tick);
|
||||
}
|
||||
|
||||
/* Read the Time Stamp Counter */
|
||||
rdtsc(clocks_low, clocks_high);
|
||||
|
||||
/* currticks = clocks / clocks_per_tick; */
|
||||
__asm__("divl %1"
|
||||
:"=a" (currticks)
|
||||
:"r" (clocks_per_tick), "0" (clocks_low), "d" (clocks_high));
|
||||
|
||||
|
||||
return currticks;
|
||||
}
|
||||
|
||||
#endif /* RTC_CURRTICKS */
|
||||
@@ -1,64 +0,0 @@
|
||||
/* Defines for routines to implement a low-overhead timer for drivers */
|
||||
|
||||
/*
|
||||
* 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, or (at
|
||||
* your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
/* Ports for the 8254 timer chip */
|
||||
#define TIMER2_PORT 0x42
|
||||
#define TIMER_MODE_PORT 0x43
|
||||
|
||||
/* Meaning of the mode bits */
|
||||
#define TIMER0_SEL 0x00
|
||||
#define TIMER1_SEL 0x40
|
||||
#define TIMER2_SEL 0x80
|
||||
#define READBACK_SEL 0xC0
|
||||
|
||||
#define LATCH_COUNT 0x00
|
||||
#define LOBYTE_ACCESS 0x10
|
||||
#define HIBYTE_ACCESS 0x20
|
||||
#define WORD_ACCESS 0x30
|
||||
|
||||
#define MODE0 0x00
|
||||
#define MODE1 0x02
|
||||
#define MODE2 0x04
|
||||
#define MODE3 0x06
|
||||
#define MODE4 0x08
|
||||
#define MODE5 0x0A
|
||||
|
||||
#define BINARY_COUNT 0x00
|
||||
#define BCD_COUNT 0x01
|
||||
|
||||
/* Timers tick over at this rate */
|
||||
#define TICKS_PER_MS 1193
|
||||
|
||||
/* Parallel Peripheral Controller Port B */
|
||||
#define PPC_PORTB 0x61
|
||||
|
||||
/* Meaning of the port bits */
|
||||
#define PPCB_T2OUT 0x20 /* Bit 5 */
|
||||
#define PPCB_SPKR 0x02 /* Bit 1 */
|
||||
#define PPCB_T2GATE 0x01 /* Bit 0 */
|
||||
|
||||
/* Ticks must be between 0 and 65535 (0 == 65536)
|
||||
because it is a 16 bit counter */
|
||||
extern void load_timer2(unsigned int ticks);
|
||||
extern inline int timer2_running(void)
|
||||
{
|
||||
return ((inb(PPC_PORTB) & PPCB_T2OUT) == 0);
|
||||
}
|
||||
|
||||
extern inline void waiton_timer2(unsigned int ticks)
|
||||
{
|
||||
load_timer2(ticks);
|
||||
while ((inb(PPC_PORTB) & PPCB_T2OUT) == 0)
|
||||
;
|
||||
}
|
||||
|
||||
#endif /* TIMER_H */
|
||||
-3746
File diff suppressed because it is too large.
Load diff
-1989
File diff suppressed because it is too large.
Load diff
@@ -1,53 +0,0 @@
|
||||
This software may be used and distributed according to the terms of
|
||||
the GNU Public License, incorporated herein by reference.
|
||||
|
||||
This is a tulip and clone driver for Etherboot. See the revision
|
||||
history in the tulip.c file for information on changes. This version
|
||||
of the driver incorporates changes from Bob Edwards and Paul Mackerras
|
||||
who cantributed changes to support the TRENDnet TE100-PCIA NIC which
|
||||
uses a genuine Intel 21143-PD chipset. There are also various code
|
||||
cleanups to make time-based activities more reliable.
|
||||
|
||||
Of course you have to have all the usual Etherboot environment
|
||||
(bootp/dhcp/NFS) set up, and you need a Linux kernel with v0.91g
|
||||
(7.16.99) or later of the tulip.c driver compiled in to support some
|
||||
MX98715 based cards. That file is available at:
|
||||
|
||||
http://cesdis.gsfc.nasa.gov/linux/drivers/test/tulip.c
|
||||
|
||||
NOTES
|
||||
|
||||
I've tested this driver with a SOHOware Fast 10/100 Model SDA110A,
|
||||
a Linksys LNE100TX v2.0, and a Netgear FA310TX card, and it worked at
|
||||
both 10 and 100 mbits. Other cards based on the tulip family may work as
|
||||
well.
|
||||
|
||||
These cards are about 20$US, are supported by Linux and now Etherboot,
|
||||
and being PCI, they auto-configure IRQ and IOADDR and auto-negotiate
|
||||
10/100 half/full duplex. It seems like a pretty good value compared to
|
||||
some of the pricier cards, and can lower the cost of building/adapting
|
||||
thin client workstations substantially while giving a considerable
|
||||
performance increase.
|
||||
|
||||
On some PCI tulip clone chipsets (MX987x5, LC82C115, LC82C168) this driver
|
||||
lets the card choose the fastest speed it can negotiate with the peer
|
||||
device. On other cards, it chooses 10mbit half-duplex.
|
||||
|
||||
I burned an AM27C256 (32KByte) EPROM with mx987x5.lzrom and it worked.
|
||||
According to the data sheet the MX98715A supports up to 64K (27C512)
|
||||
EPROMs,
|
||||
|
||||
I've liberally commented the code and header files in the hope that it
|
||||
will help the next person who hacks the code or needs to support some
|
||||
tulip clone card, or wishes to add functionality.
|
||||
|
||||
Anyway, please test this if you can on your tulip based card, and let
|
||||
me (mdc@thinguin.org) and the netboot list (netboot@baghira.han.de)
|
||||
know how things go. I also would appreciate code review by people who
|
||||
program. I'm a strong believer in "another set of eyes".
|
||||
|
||||
Regards,
|
||||
|
||||
Marty Connor
|
||||
mdc@thinguin.org
|
||||
http://www.thinguin.org/
|
||||
-1180
File diff suppressed because it is too large.
Load diff
@@ -1,934 +0,0 @@
|
||||
/*
|
||||
* Etherboot - BOOTP/TFTP Bootstrap Program
|
||||
*
|
||||
* w89c840.c -- This file implements the winbond-840 driver for etherboot.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Adapted by Igor V. Kovalenko
|
||||
* -- <garrison@mail.ru>
|
||||
* OR
|
||||
* -- <iko@crec.mipt.ru>
|
||||
* Initial adaptaion stage, including testing, completed 23 August 2000.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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, or (at
|
||||
* your option) 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* date version by what
|
||||
* Written: Aug 20 2000 V0.10 iko Initial revision.
|
||||
* changes: Aug 22 2000 V0.90 iko Works!
|
||||
* Aug 23 2000 V0.91 iko Cleanup, posted to etherboot
|
||||
* maintainer.
|
||||
* Aug 26 2000 V0.92 iko Fixed Rx ring handling.
|
||||
* First Linux Kernel (TM)
|
||||
* successfully loaded using
|
||||
* this driver.
|
||||
* Jan 07 2001 V0.93 iko Transmitter timeouts are handled
|
||||
* using timer2 routines. Proposed
|
||||
* by Ken Yap to eliminate CPU speed
|
||||
* dependency.
|
||||
*
|
||||
* This is the etherboot driver for cards based on Winbond W89c840F chip.
|
||||
*
|
||||
* It was written from skeleton source, with Donald Becker's winbond-840.c
|
||||
* kernel driver as a guideline. Mostly the w89c840 related definitions
|
||||
* and the lower level routines have been cut-and-pasted into this source.
|
||||
*
|
||||
* Frankly speaking, about 90% of the code was obtained using cut'n'paste
|
||||
* sequence :) while the remainder appeared while brainstorming
|
||||
* Linux Kernel 2.4.0-testX source code. Thanks, Donald and Linus!
|
||||
*
|
||||
* There was a demand for using this card in a rather large
|
||||
* remote boot environment at MSKP OVTI Lab of
|
||||
* Moscow Institute for Physics and Technology (MIPT) -- http://www.mipt.ru/
|
||||
* so you may count that for motivation.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* If you want to see debugging output then define W89C840_DEBUG
|
||||
*/
|
||||
|
||||
/*
|
||||
#define W89C840_DEBUG
|
||||
*/
|
||||
|
||||
/*
|
||||
* Keep using IO_OPS for Etherboot driver!
|
||||
*/
|
||||
#define USE_IO_OPS
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "pci.h"
|
||||
#include "cards.h"
|
||||
#include "timer.h"
|
||||
|
||||
static const char *w89c840_version = "diver Version 0.92 - August 27, 2000";
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef signed char s8;
|
||||
typedef unsigned short u16;
|
||||
typedef signed short s16;
|
||||
typedef unsigned int u32;
|
||||
typedef signed int s32;
|
||||
|
||||
/* Linux support functions */
|
||||
#define virt_to_bus(x) ((unsigned long)x)
|
||||
#define bus_to_virt(x) ((void *)x)
|
||||
|
||||
#define virt_to_le32desc(addr) virt_to_bus(addr)
|
||||
#define le32desc_to_virt(addr) bus_to_virt(addr)
|
||||
|
||||
/*
|
||||
#define cpu_to_le32(val) (val)
|
||||
#define le32_to_cpu(val) (val)
|
||||
*/
|
||||
|
||||
/* Operational parameters that are set at compile time. */
|
||||
|
||||
/* Keep the ring sizes a power of two for compile efficiency.
|
||||
The compiler will convert <unsigned>'%'<2^N> into a bit mask.
|
||||
Making the Tx ring too large decreases the effectiveness of channel
|
||||
bonding and packet priority.
|
||||
There are no ill effects from too-large receive rings. */
|
||||
#define TX_RING_SIZE 2
|
||||
|
||||
#define RX_RING_SIZE 2
|
||||
|
||||
/* The presumed FIFO size for working around the Tx-FIFO-overflow bug.
|
||||
To avoid overflowing we don't queue again until we have room for a
|
||||
full-size packet.
|
||||
*/
|
||||
#define TX_FIFO_SIZE (2048)
|
||||
#define TX_BUG_FIFO_LIMIT (TX_FIFO_SIZE-1514-16)
|
||||
|
||||
/* Operational parameters that usually are not changed. */
|
||||
/* Time in jiffies before concluding the transmitter is hung. */
|
||||
#define TX_TIMEOUT (10*TICKS_PER_MS)
|
||||
|
||||
#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
|
||||
|
||||
/*
|
||||
* Used to be this much CPU loops on Celeron@400 (?),
|
||||
* now using real timer and TX_TIMEOUT!
|
||||
* #define TX_LOOP_COUNT 10000000
|
||||
*/
|
||||
|
||||
#if !defined(__OPTIMIZE__)
|
||||
#warning You must compile this file with the correct options!
|
||||
#warning See the last lines of the source file.
|
||||
#error You must compile this driver with "-O".
|
||||
#endif
|
||||
|
||||
enum chip_capability_flags {CanHaveMII=1, HasBrokenTx=2};
|
||||
|
||||
#ifdef USE_IO_OPS
|
||||
#define W840_FLAGS (PCI_USES_IO | PCI_ADDR0 | PCI_USES_MASTER)
|
||||
#else
|
||||
#define W840_FLAGS (PCI_USES_MEM | PCI_ADDR1 | PCI_USES_MASTER)
|
||||
#endif
|
||||
|
||||
static u32 driver_flags = CanHaveMII | HasBrokenTx;
|
||||
|
||||
/* This driver was written to use PCI memory space, however some x86 systems
|
||||
work only with I/O space accesses. Pass -DUSE_IO_OPS to use PCI I/O space
|
||||
accesses instead of memory space. */
|
||||
|
||||
#ifdef USE_IO_OPS
|
||||
#undef readb
|
||||
#undef readw
|
||||
#undef readl
|
||||
#undef writeb
|
||||
#undef writew
|
||||
#undef writel
|
||||
#define readb inb
|
||||
#define readw inw
|
||||
#define readl inl
|
||||
#define writeb outb
|
||||
#define writew outw
|
||||
#define writel outl
|
||||
#endif
|
||||
|
||||
/* Offsets to the Command and Status Registers, "CSRs".
|
||||
While similar to the Tulip, these registers are longword aligned.
|
||||
Note: It's not useful to define symbolic names for every register bit in
|
||||
the device. The name can only partially document the semantics and make
|
||||
the driver longer and more difficult to read.
|
||||
*/
|
||||
enum w840_offsets {
|
||||
PCIBusCfg=0x00, TxStartDemand=0x04, RxStartDemand=0x08,
|
||||
RxRingPtr=0x0C, TxRingPtr=0x10,
|
||||
IntrStatus=0x14, NetworkConfig=0x18, IntrEnable=0x1C,
|
||||
RxMissed=0x20, EECtrl=0x24, MIICtrl=0x24, BootRom=0x28, GPTimer=0x2C,
|
||||
CurRxDescAddr=0x30, CurRxBufAddr=0x34, /* Debug use */
|
||||
MulticastFilter0=0x38, MulticastFilter1=0x3C, StationAddr=0x40,
|
||||
CurTxDescAddr=0x4C, CurTxBufAddr=0x50,
|
||||
};
|
||||
|
||||
/* Bits in the interrupt status/enable registers. */
|
||||
/* The bits in the Intr Status/Enable registers, mostly interrupt sources. */
|
||||
enum intr_status_bits {
|
||||
NormalIntr=0x10000, AbnormalIntr=0x8000,
|
||||
IntrPCIErr=0x2000, TimerInt=0x800,
|
||||
IntrRxDied=0x100, RxNoBuf=0x80, IntrRxDone=0x40,
|
||||
TxFIFOUnderflow=0x20, RxErrIntr=0x10,
|
||||
TxIdle=0x04, IntrTxStopped=0x02, IntrTxDone=0x01,
|
||||
};
|
||||
|
||||
/* Bits in the NetworkConfig register. */
|
||||
enum rx_mode_bits {
|
||||
AcceptErr=0x80, AcceptRunt=0x40,
|
||||
AcceptBroadcast=0x20, AcceptMulticast=0x10,
|
||||
AcceptAllPhys=0x08, AcceptMyPhys=0x02,
|
||||
};
|
||||
|
||||
enum mii_reg_bits {
|
||||
MDIO_ShiftClk=0x10000, MDIO_DataIn=0x80000, MDIO_DataOut=0x20000,
|
||||
MDIO_EnbOutput=0x40000, MDIO_EnbIn = 0x00000,
|
||||
};
|
||||
|
||||
/* The Tulip Rx and Tx buffer descriptors. */
|
||||
struct w840_rx_desc {
|
||||
s32 status;
|
||||
s32 length;
|
||||
u32 buffer1;
|
||||
u32 next_desc;
|
||||
};
|
||||
|
||||
struct w840_tx_desc {
|
||||
s32 status;
|
||||
s32 length;
|
||||
u32 buffer1, buffer2; /* We use only buffer 1. */
|
||||
};
|
||||
|
||||
/* Bits in network_desc.status */
|
||||
enum desc_status_bits {
|
||||
DescOwn=0x80000000, DescEndRing=0x02000000, DescUseLink=0x01000000,
|
||||
DescWholePkt=0x60000000, DescStartPkt=0x20000000, DescEndPkt=0x40000000,
|
||||
DescIntr=0x80000000,
|
||||
};
|
||||
#define PRIV_ALIGN 15 /* Required alignment mask */
|
||||
#define PRIV_ALIGN_BYTES 32
|
||||
|
||||
static struct winbond_private
|
||||
{
|
||||
/* Descriptor rings first for alignment. */
|
||||
struct w840_rx_desc rx_ring[RX_RING_SIZE];
|
||||
struct w840_tx_desc tx_ring[TX_RING_SIZE];
|
||||
struct net_device *next_module; /* Link for devices of this type. */
|
||||
void *priv_addr; /* Unaligned address for kfree */
|
||||
const char *product_name;
|
||||
/* Frequently used values: keep some adjacent for cache effect. */
|
||||
int chip_id, drv_flags;
|
||||
struct pci_dev *pci_dev;
|
||||
int csr6;
|
||||
struct w840_rx_desc *rx_head_desc;
|
||||
unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */
|
||||
unsigned int rx_buf_sz; /* Based on MTU+slack. */
|
||||
unsigned int cur_tx, dirty_tx;
|
||||
int tx_q_bytes;
|
||||
unsigned int tx_full:1; /* The Tx queue is full. */
|
||||
/* These values are keep track of the transceiver/media in use. */
|
||||
unsigned int full_duplex:1; /* Full-duplex operation requested. */
|
||||
unsigned int duplex_lock:1;
|
||||
unsigned int medialock:1; /* Do not sense media. */
|
||||
unsigned int default_port:4; /* Last dev->if_port value. */
|
||||
/* MII transceiver section. */
|
||||
int mii_cnt; /* MII device addresses. */
|
||||
u16 advertising; /* NWay media advertisement */
|
||||
unsigned char phys[2]; /* MII device addresses. */
|
||||
} w840private __attribute__ ((aligned (PRIV_ALIGN_BYTES)));
|
||||
|
||||
/* NIC specific static variables go here */
|
||||
|
||||
static int ioaddr;
|
||||
static unsigned short eeprom [0x40];
|
||||
|
||||
#ifdef USE_LOWMEM_BUFFER
|
||||
#define rx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE)
|
||||
#define tx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE - PKT_BUF_SZ * TX_RING_SIZE)
|
||||
#else
|
||||
static char rx_packet[PKT_BUF_SZ * RX_RING_SIZE];
|
||||
static char tx_packet[PKT_BUF_SZ * TX_RING_SIZE];
|
||||
#endif
|
||||
|
||||
static int eeprom_read(long ioaddr, int location);
|
||||
static int mdio_read(int base_address, int phy_id, int location);
|
||||
static void mdio_write(int base_address, int phy_id, int location, int value);
|
||||
|
||||
static void check_duplex(void);
|
||||
static void set_rx_mode(void);
|
||||
static void init_ring(void);
|
||||
|
||||
/*
|
||||
static void wait_long_time(void)
|
||||
{
|
||||
printf("Paused - please read output above this line\n");
|
||||
sleep(3);
|
||||
}
|
||||
*/
|
||||
|
||||
#if defined W89C840_DEBUG
|
||||
static void decode_interrupt(u32 intr_status)
|
||||
{
|
||||
printf("Interrupt status: ");
|
||||
|
||||
#define TRACE_INTR(_intr_) \
|
||||
if (intr_status & (_intr_)) { printf (" " #_intr_); }
|
||||
|
||||
TRACE_INTR(NormalIntr);
|
||||
TRACE_INTR(AbnormalIntr);
|
||||
TRACE_INTR(IntrPCIErr);
|
||||
TRACE_INTR(TimerInt);
|
||||
TRACE_INTR(IntrRxDied);
|
||||
TRACE_INTR(RxNoBuf);
|
||||
TRACE_INTR(IntrRxDone);
|
||||
TRACE_INTR(TxFIFOUnderflow);
|
||||
TRACE_INTR(RxErrIntr);
|
||||
TRACE_INTR(TxIdle);
|
||||
TRACE_INTR(IntrTxStopped);
|
||||
TRACE_INTR(IntrTxDone);
|
||||
|
||||
printf("\n");
|
||||
/*sleep(1);*/
|
||||
}
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
w89c840_reset - Reset adapter
|
||||
***************************************************************************/
|
||||
static void w89c840_reset(struct nic *nic)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Reset the chip to erase previous misconfiguration.
|
||||
No hold time required! */
|
||||
writel(0x00000001, ioaddr + PCIBusCfg);
|
||||
|
||||
init_ring();
|
||||
|
||||
writel(virt_to_bus(w840private.rx_ring), ioaddr + RxRingPtr);
|
||||
writel(virt_to_bus(w840private.tx_ring), ioaddr + TxRingPtr);
|
||||
|
||||
for (i = 0; i < ETH_ALEN; i++)
|
||||
writeb(nic->node_addr[i], ioaddr + StationAddr + i);
|
||||
|
||||
/* Initialize other registers. */
|
||||
/* Configure the PCI bus bursts and FIFO thresholds.
|
||||
486: Set 8 longword cache alignment, 8 longword burst.
|
||||
586: Set 16 longword cache alignment, no burst limit.
|
||||
Cache alignment bits 15:14 Burst length 13:8
|
||||
0000 <not allowed> 0000 align to cache 0800 8 longwords
|
||||
4000 8 longwords 0100 1 longword 1000 16 longwords
|
||||
8000 16 longwords 0200 2 longwords 2000 32 longwords
|
||||
C000 32 longwords 0400 4 longwords
|
||||
Wait the specified 50 PCI cycles after a reset by initializing
|
||||
Tx and Rx queues and the address filter list. */
|
||||
|
||||
writel(0xE010, ioaddr + PCIBusCfg);
|
||||
|
||||
writel(0, ioaddr + RxStartDemand);
|
||||
w840private.csr6 = 0x20022002;
|
||||
check_duplex();
|
||||
set_rx_mode();
|
||||
|
||||
/* Clear and Enable interrupts by setting the interrupt mask. */
|
||||
writel(0x1A0F5, ioaddr + IntrStatus);
|
||||
writel(0x1A0F5, ioaddr + IntrEnable);
|
||||
|
||||
#if defined(W89C840_DEBUG)
|
||||
printf("winbond-840 : Done reset.\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void handle_intr(u32 intr_stat)
|
||||
{
|
||||
if ((intr_stat & (NormalIntr|AbnormalIntr)) == 0) {
|
||||
/* we are polling, do not return now */
|
||||
/*return 0;*/
|
||||
} else {
|
||||
/* Acknowledge all of the current interrupt sources ASAP. */
|
||||
writel(intr_stat & 0x001ffff, ioaddr + IntrStatus);
|
||||
}
|
||||
|
||||
if (intr_stat & AbnormalIntr) {
|
||||
/* There was an abnormal interrupt */
|
||||
printf("\n-=- Abnormal interrupt.\n");
|
||||
|
||||
#if defined (W89C840_DEBUG)
|
||||
decode_interrupt(intr_stat);
|
||||
#endif
|
||||
|
||||
if (intr_stat & RxNoBuf) {
|
||||
/* There was an interrupt */
|
||||
printf("-=- <=> No receive buffers available.\n");
|
||||
writel(0, ioaddr + RxStartDemand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
w89c840_poll - Wait for a frame
|
||||
***************************************************************************/
|
||||
static int w89c840_poll(struct nic *nic)
|
||||
{
|
||||
/* return true if there's an ethernet packet ready to read */
|
||||
/* nic->packet should contain data on return */
|
||||
/* nic->packetlen should contain length of data */
|
||||
int packet_received = 0;
|
||||
|
||||
u32 intr_status = readl(ioaddr + IntrStatus);
|
||||
/* handle_intr(intr_status); */ /* -- handled later */
|
||||
|
||||
do {
|
||||
/* Code from netdev_rx(dev) */
|
||||
|
||||
int entry = w840private.cur_rx % RX_RING_SIZE;
|
||||
|
||||
struct w840_rx_desc *desc = w840private.rx_head_desc;
|
||||
s32 status = desc->status;
|
||||
|
||||
if (status & DescOwn) {
|
||||
/* DescOwn bit is still set, we should wait for RX to complete */
|
||||
packet_received = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((status & 0x38008300) != 0x0300) {
|
||||
if ((status & 0x38000300) != 0x0300) {
|
||||
/* Ingore earlier buffers. */
|
||||
if ((status & 0xffff) != 0x7fff) {
|
||||
printf("winbond-840 : Oversized Ethernet frame spanned "
|
||||
"multiple buffers, entry %d status %X !\n",
|
||||
w840private.cur_rx, status);
|
||||
}
|
||||
} else if (status & 0x8000) {
|
||||
/* There was a fatal error. */
|
||||
#if defined(W89C840_DEBUG)
|
||||
printf("winbond-840 : Receive error, Rx status %X :", status);
|
||||
if (status & 0x0890) {
|
||||
printf(" RXLEN_ERROR");
|
||||
}
|
||||
if (status & 0x004C) {
|
||||
printf(", FRAME_ERROR");
|
||||
}
|
||||
if (status & 0x0002) {
|
||||
printf(", CRC_ERROR");
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
/* Simpy do a reset now... */
|
||||
w89c840_reset(nic);
|
||||
|
||||
packet_received = 0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Omit the four octet CRC from the length. */
|
||||
int pkt_len = ((status >> 16) & 0x7ff) - 4;
|
||||
|
||||
#if defined(W89C840_DEBUG)
|
||||
printf(" netdev_rx() normal Rx pkt ring %d length %d status %X\n", entry, pkt_len, status);
|
||||
#endif
|
||||
|
||||
nic->packetlen = pkt_len;
|
||||
|
||||
/* Check if the packet is long enough to accept without copying
|
||||
to a minimally-sized skbuff. */
|
||||
|
||||
memcpy(nic->packet, le32desc_to_virt(w840private.rx_ring[entry].buffer1), pkt_len);
|
||||
packet_received = 1;
|
||||
|
||||
/* Release buffer to NIC */
|
||||
w840private.rx_ring[entry].status = DescOwn;
|
||||
|
||||
#if defined(W89C840_DEBUG)
|
||||
/* You will want this info for the initial debug. */
|
||||
printf(" Rx data %hhX:%hhX:%hhX:%hhX:%hhX:"
|
||||
"%hhX %hhX:%hhX:%hhX:%hhX:%hhX:%hhX %hhX%hhX "
|
||||
"%hhX.%hhX.%hhX.%hhX.\n",
|
||||
nic->packet[0], nic->packet[1], nic->packet[2], nic->packet[3],
|
||||
nic->packet[4], nic->packet[5], nic->packet[6], nic->packet[7],
|
||||
nic->packet[8], nic->packet[9], nic->packet[10],
|
||||
nic->packet[11], nic->packet[12], nic->packet[13],
|
||||
nic->packet[14], nic->packet[15], nic->packet[16],
|
||||
nic->packet[17]);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
entry = (++w840private.cur_rx) % RX_RING_SIZE;
|
||||
w840private.rx_head_desc = &w840private.rx_ring[entry];
|
||||
} while (0);
|
||||
|
||||
if (intr_status & (AbnormalIntr | TxFIFOUnderflow | IntrPCIErr |TimerInt | IntrTxStopped)) {
|
||||
handle_intr(intr_status);
|
||||
}
|
||||
|
||||
return packet_received;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
w89c840_transmit - Transmit a frame
|
||||
***************************************************************************/
|
||||
|
||||
static void w89c840_transmit(
|
||||
struct nic *nic,
|
||||
const char *d, /* Destination */
|
||||
unsigned int t, /* Type */
|
||||
unsigned int s, /* size */
|
||||
const char *p) /* Packet */
|
||||
{
|
||||
/* send the packet to destination */
|
||||
unsigned entry;
|
||||
int transmit_status;
|
||||
|
||||
/* Caution: the write order is important here, set the field
|
||||
with the "ownership" bits last. */
|
||||
|
||||
/* Fill in our transmit buffer */
|
||||
entry = w840private.cur_tx % TX_RING_SIZE;
|
||||
|
||||
memcpy (tx_packet, d, ETH_ALEN); /* dst */
|
||||
memcpy (tx_packet + ETH_ALEN, nic->node_addr, ETH_ALEN);/* src */
|
||||
|
||||
*((char *) tx_packet + 12) = t >> 8; /* type */
|
||||
*((char *) tx_packet + 13) = t;
|
||||
|
||||
memcpy (tx_packet + ETH_HLEN, p, s);
|
||||
s += ETH_HLEN;
|
||||
|
||||
while (s < ETH_ZLEN)
|
||||
*((char *) tx_packet + ETH_HLEN + (s++)) = 0;
|
||||
|
||||
w840private.tx_ring[entry].buffer1 = virt_to_le32desc(tx_packet);
|
||||
|
||||
w840private.tx_ring[entry].length = (DescWholePkt | s);
|
||||
if (entry >= TX_RING_SIZE-1) /* Wrap ring */
|
||||
w840private.tx_ring[entry].length |= (DescIntr | DescEndRing);
|
||||
w840private.tx_ring[entry].status = (DescOwn);
|
||||
w840private.cur_tx++;
|
||||
|
||||
w840private.tx_q_bytes += s;
|
||||
writel(0, ioaddr + TxStartDemand);
|
||||
|
||||
/* Work around horrible bug in the chip by marking the queue as full
|
||||
when we do not have FIFO room for a maximum sized packet. */
|
||||
|
||||
if ((w840private.drv_flags & HasBrokenTx) && w840private.tx_q_bytes > TX_BUG_FIFO_LIMIT) {
|
||||
/* Actually this is left to help finding error tails later in debugging...
|
||||
* See Linux kernel driver in winbond-840.c for details.
|
||||
*/
|
||||
w840private.tx_full = 1;
|
||||
}
|
||||
|
||||
#if defined(W89C840_DEBUG)
|
||||
printf("winbond-840 : Transmit frame # %d size %d queued in slot %d.\n", w840private.cur_tx, s, entry);
|
||||
#endif
|
||||
|
||||
/* Now wait for TX to complete. */
|
||||
transmit_status = w840private.tx_ring[entry].status;
|
||||
|
||||
load_timer2(TX_TIMEOUT);
|
||||
|
||||
{
|
||||
u32 intr_stat = 0;
|
||||
|
||||
while (1) {
|
||||
|
||||
intr_stat = readl(ioaddr + IntrStatus);
|
||||
#if defined(W89C840_DEBUG)
|
||||
decode_interrupt(intr_stat);
|
||||
#endif
|
||||
|
||||
if (intr_stat & (NormalIntr | IntrTxDone)) {
|
||||
|
||||
while ( (transmit_status & DescOwn) && timer2_running()) {
|
||||
|
||||
transmit_status = w840private.tx_ring[entry].status;
|
||||
}
|
||||
|
||||
writel(intr_stat & 0x0001ffff, ioaddr + IntrStatus);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((transmit_status & DescOwn) == 0) {
|
||||
|
||||
#if defined(W89C840_DEBUG)
|
||||
printf("winbond-840 : transmission complete after %d wait loop iterations, status %X\n",
|
||||
TX_LOOP_COUNT - transmit_loop_counter, w840private.tx_ring[entry].status);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Transmit timed out... */
|
||||
|
||||
printf("winbond-840 : transmission TIMEOUT : status %X\n", w840private.tx_ring[entry].status);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
w89c840_disable - Turn off ethernet interface
|
||||
***************************************************************************/
|
||||
static void w89c840_disable(struct nic *nic)
|
||||
{
|
||||
/* Don't know what to do to disable the board. Is this needed at all? */
|
||||
/* Yes, a live NIC can corrupt the loaded memory later [Ken] */
|
||||
/* Stop the chip's Tx and Rx processes. */
|
||||
writel(w840private.csr6 &= ~0x20FA, ioaddr + NetworkConfig);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
w89c840_probe - Look for an adapter, this routine's visible to the outside
|
||||
***************************************************************************/
|
||||
struct nic *w89c840_probe(struct nic *nic, unsigned short *probe_addrs, struct pci_device *p)
|
||||
{
|
||||
u16 sum = 0;
|
||||
int i, j, to;
|
||||
unsigned short value;
|
||||
int options;
|
||||
int promisc;
|
||||
|
||||
if (probe_addrs == 0 || probe_addrs[0] == 0)
|
||||
return 0;
|
||||
|
||||
ioaddr = probe_addrs[0]; /* Mask the bit that says "this is an io addr" */
|
||||
|
||||
#if defined(W89C840_DEBUG)
|
||||
printf("winbond-840: PCI bus %hhX device function %hhX: I/O address: %hX\n", p->bus, p->devfn, ioaddr);
|
||||
#endif
|
||||
|
||||
ioaddr = ioaddr & ~3; /* Mask the bit that says "this is an io addr" */
|
||||
|
||||
/* if probe_addrs is 0, then routine can use a hardwired default */
|
||||
|
||||
/* From Matt Hortman <mbhortman@acpthinclient.com> */
|
||||
if (p->vendor == PCI_VENDOR_ID_WINBOND2
|
||||
&& p->dev_id == PCI_DEVICE_ID_WINBOND2_89C840) {
|
||||
|
||||
/* detected "Winbond W89c840 Fast Ethernet PCI NIC" */
|
||||
|
||||
} else if ( p->vendor == PCI_VENDOR_ID_COMPEX
|
||||
&& p->dev_id == PCI_DEVICE_ID_COMPEX_RL100ATX) {
|
||||
|
||||
/* detected "Compex RL100ATX Fast Ethernet PCI NIC" */
|
||||
|
||||
} else {
|
||||
/* Gee, guess what? They missed again. */
|
||||
printf("device ID : %X - is not a Compex RL100ATX NIC.\n", p->dev_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf(" %s\n", w89c840_version);
|
||||
|
||||
adjust_pci_device(p);
|
||||
|
||||
/* Ok. Got one. Read the eeprom. */
|
||||
for (j = 0, i = 0; i < 0x40; i++) {
|
||||
value = eeprom_read(ioaddr, i);
|
||||
eeprom[i] = value;
|
||||
sum += value;
|
||||
}
|
||||
|
||||
for (i=0;i<ETH_ALEN;i++) {
|
||||
nic->node_addr[i] = (eeprom[i/2] >> (8*(i&1))) & 0xff;
|
||||
}
|
||||
printf ("Ethernet addr: %!\n", nic->node_addr);
|
||||
|
||||
#if defined(W89C840_DEBUG)
|
||||
printf("winbond-840: EEPROM checksum %hX, got eeprom", sum);
|
||||
#endif
|
||||
|
||||
/* Reset the chip to erase previous misconfiguration.
|
||||
No hold time required! */
|
||||
writel(0x00000001, ioaddr + PCIBusCfg);
|
||||
|
||||
if (driver_flags & CanHaveMII) {
|
||||
int phy, phy_idx = 0;
|
||||
for (phy = 1; phy < 32 && phy_idx < 4; phy++) {
|
||||
int mii_status = mdio_read(ioaddr, phy, 1);
|
||||
if (mii_status != 0xffff && mii_status != 0x0000) {
|
||||
w840private.phys[phy_idx++] = phy;
|
||||
w840private.advertising = mdio_read(ioaddr, phy, 4);
|
||||
|
||||
#if defined(W89C840_DEBUG)
|
||||
printf("winbond-840 : MII PHY found at address %d, status "
|
||||
"%X advertising %hX.\n", phy, mii_status, w840private.advertising);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
w840private.mii_cnt = phy_idx;
|
||||
|
||||
if (phy_idx == 0) {
|
||||
printf("winbond-840 : MII PHY not found -- this device may not operate correctly.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* point to NIC specific routines */
|
||||
nic->reset = w89c840_reset;
|
||||
nic->poll = w89c840_poll;
|
||||
nic->transmit = w89c840_transmit;
|
||||
nic->disable = w89c840_disable;
|
||||
|
||||
w89c840_reset(nic);
|
||||
|
||||
return nic;
|
||||
}
|
||||
|
||||
/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. These are
|
||||
often serial bit streams generated by the host processor.
|
||||
The example below is for the common 93c46 EEPROM, 64 16 bit words. */
|
||||
|
||||
/* Delay between EEPROM clock transitions.
|
||||
No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
|
||||
a delay. Note that pre-2.0.34 kernels had a cache-alignment bug that
|
||||
made udelay() unreliable.
|
||||
The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
|
||||
depricated.
|
||||
*/
|
||||
#define eeprom_delay(ee_addr) readl(ee_addr)
|
||||
|
||||
enum EEPROM_Ctrl_Bits {
|
||||
EE_ShiftClk=0x02, EE_Write0=0x801, EE_Write1=0x805,
|
||||
EE_ChipSelect=0x801, EE_DataIn=0x08,
|
||||
};
|
||||
|
||||
/* The EEPROM commands include the alway-set leading bit. */
|
||||
enum EEPROM_Cmds {
|
||||
EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
|
||||
};
|
||||
|
||||
static int eeprom_read(long addr, int location)
|
||||
{
|
||||
int i;
|
||||
int retval = 0;
|
||||
int ee_addr = addr + EECtrl;
|
||||
int read_cmd = location | EE_ReadCmd;
|
||||
writel(EE_ChipSelect, ee_addr);
|
||||
|
||||
/* Shift the read command bits out. */
|
||||
for (i = 10; i >= 0; i--) {
|
||||
short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
|
||||
writel(dataval, ee_addr);
|
||||
eeprom_delay(ee_addr);
|
||||
writel(dataval | EE_ShiftClk, ee_addr);
|
||||
eeprom_delay(ee_addr);
|
||||
}
|
||||
writel(EE_ChipSelect, ee_addr);
|
||||
|
||||
for (i = 16; i > 0; i--) {
|
||||
writel(EE_ChipSelect | EE_ShiftClk, ee_addr);
|
||||
eeprom_delay(ee_addr);
|
||||
retval = (retval << 1) | ((readl(ee_addr) & EE_DataIn) ? 1 : 0);
|
||||
writel(EE_ChipSelect, ee_addr);
|
||||
eeprom_delay(ee_addr);
|
||||
}
|
||||
|
||||
/* Terminate the EEPROM access. */
|
||||
writel(0, ee_addr);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* MII transceiver control section.
|
||||
Read and write the MII registers using software-generated serial
|
||||
MDIO protocol. See the MII specifications or DP83840A data sheet
|
||||
for details.
|
||||
|
||||
The maximum data clock rate is 2.5 Mhz. The minimum timing is usually
|
||||
met by back-to-back 33Mhz PCI cycles. */
|
||||
#define mdio_delay(mdio_addr) readl(mdio_addr)
|
||||
|
||||
/* Set iff a MII transceiver on any interface requires mdio preamble.
|
||||
This only set with older tranceivers, so the extra
|
||||
code size of a per-interface flag is not worthwhile. */
|
||||
static char mii_preamble_required = 1;
|
||||
|
||||
#define MDIO_WRITE0 (MDIO_EnbOutput)
|
||||
#define MDIO_WRITE1 (MDIO_DataOut | MDIO_EnbOutput)
|
||||
|
||||
/* Generate the preamble required for initial synchronization and
|
||||
a few older transceivers. */
|
||||
static void mdio_sync(long mdio_addr)
|
||||
{
|
||||
int bits = 32;
|
||||
|
||||
/* Establish sync by sending at least 32 logic ones. */
|
||||
while (--bits >= 0) {
|
||||
writel(MDIO_WRITE1, mdio_addr);
|
||||
mdio_delay(mdio_addr);
|
||||
writel(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr);
|
||||
mdio_delay(mdio_addr);
|
||||
}
|
||||
}
|
||||
|
||||
static int mdio_read(int base_address, int phy_id, int location)
|
||||
{
|
||||
long mdio_addr = base_address + MIICtrl;
|
||||
int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
|
||||
int i, retval = 0;
|
||||
|
||||
if (mii_preamble_required)
|
||||
mdio_sync(mdio_addr);
|
||||
|
||||
/* Shift the read command bits out. */
|
||||
for (i = 15; i >= 0; i--) {
|
||||
int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
|
||||
|
||||
writel(dataval, mdio_addr);
|
||||
mdio_delay(mdio_addr);
|
||||
writel(dataval | MDIO_ShiftClk, mdio_addr);
|
||||
mdio_delay(mdio_addr);
|
||||
}
|
||||
/* Read the two transition, 16 data, and wire-idle bits. */
|
||||
for (i = 20; i > 0; i--) {
|
||||
writel(MDIO_EnbIn, mdio_addr);
|
||||
mdio_delay(mdio_addr);
|
||||
retval = (retval << 1) | ((readl(mdio_addr) & MDIO_DataIn) ? 1 : 0);
|
||||
writel(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
|
||||
mdio_delay(mdio_addr);
|
||||
}
|
||||
return (retval>>1) & 0xffff;
|
||||
}
|
||||
|
||||
static void mdio_write(int base_address, int phy_id, int location, int value)
|
||||
{
|
||||
long mdio_addr = base_address + MIICtrl;
|
||||
int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
|
||||
int i;
|
||||
|
||||
if (location == 4 && phy_id == w840private.phys[0])
|
||||
w840private.advertising = value;
|
||||
|
||||
if (mii_preamble_required)
|
||||
mdio_sync(mdio_addr);
|
||||
|
||||
/* Shift the command bits out. */
|
||||
for (i = 31; i >= 0; i--) {
|
||||
int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
|
||||
|
||||
writel(dataval, mdio_addr);
|
||||
mdio_delay(mdio_addr);
|
||||
writel(dataval | MDIO_ShiftClk, mdio_addr);
|
||||
mdio_delay(mdio_addr);
|
||||
}
|
||||
/* Clear out extra bits. */
|
||||
for (i = 2; i > 0; i--) {
|
||||
writel(MDIO_EnbIn, mdio_addr);
|
||||
mdio_delay(mdio_addr);
|
||||
writel(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
|
||||
mdio_delay(mdio_addr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void check_duplex(void)
|
||||
{
|
||||
int mii_reg5 = mdio_read(ioaddr, w840private.phys[0], 5);
|
||||
int negotiated = mii_reg5 & w840private.advertising;
|
||||
int duplex;
|
||||
|
||||
if (w840private.duplex_lock || mii_reg5 == 0xffff)
|
||||
return;
|
||||
|
||||
duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
|
||||
if (w840private.full_duplex != duplex) {
|
||||
w840private.full_duplex = duplex;
|
||||
|
||||
#if defined(W89C840_DEBUG)
|
||||
printf("winbond-840 : Setting %s-duplex based on MII # %d negotiated capability %X\n",
|
||||
duplex ? "full" : "half", w840private.phys[0], negotiated);
|
||||
#endif
|
||||
|
||||
w840private.csr6 &= ~0x200;
|
||||
w840private.csr6 |= duplex ? 0x200 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_rx_mode(void)
|
||||
{
|
||||
u32 mc_filter[2]; /* Multicast hash filter */
|
||||
u32 rx_mode;
|
||||
|
||||
/* Accept all multicasts from now on. */
|
||||
memset(mc_filter, 0xff, sizeof(mc_filter));
|
||||
|
||||
/*
|
||||
* Actually, should work OK with multicast enabled. -- iko
|
||||
*/
|
||||
/*
|
||||
* rx_mode = AcceptBroadcast | AcceptMyPhys | AcceptMulticast;
|
||||
*/
|
||||
rx_mode = AcceptBroadcast | AcceptMyPhys;
|
||||
|
||||
writel(mc_filter[0], ioaddr + MulticastFilter0);
|
||||
writel(mc_filter[1], ioaddr + MulticastFilter1);
|
||||
w840private.csr6 &= ~0x00F8;
|
||||
w840private.csr6 |= rx_mode;
|
||||
writel(w840private.csr6, ioaddr + NetworkConfig);
|
||||
|
||||
#if defined(W89C840_DEBUG)
|
||||
printf("winbond-840 : Done setting RX mode.\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
|
||||
static void init_ring(void)
|
||||
{
|
||||
int i;
|
||||
char * p;
|
||||
|
||||
w840private.tx_full = 0;
|
||||
w840private.tx_q_bytes = w840private.cur_rx = w840private.cur_tx = 0;
|
||||
w840private.dirty_rx = w840private.dirty_tx = 0;
|
||||
|
||||
w840private.rx_buf_sz = PKT_BUF_SZ;
|
||||
w840private.rx_head_desc = &w840private.rx_ring[0];
|
||||
|
||||
/* Initial all Rx descriptors. Fill in the Rx buffers. */
|
||||
|
||||
p = &rx_packet[0];
|
||||
|
||||
for (i = 0; i < RX_RING_SIZE; i++) {
|
||||
w840private.rx_ring[i].length = w840private.rx_buf_sz;
|
||||
w840private.rx_ring[i].status = 0;
|
||||
w840private.rx_ring[i].next_desc = virt_to_le32desc(&w840private.rx_ring[i+1]);
|
||||
|
||||
w840private.rx_ring[i].buffer1 = virt_to_le32desc(p + (PKT_BUF_SZ * i));
|
||||
w840private.rx_ring[i].status = DescOwn | DescIntr;
|
||||
}
|
||||
|
||||
/* Mark the last entry as wrapping the ring. */
|
||||
w840private.rx_ring[i-1].length |= DescEndRing;
|
||||
w840private.rx_ring[i-1].next_desc = virt_to_le32desc(&w840private.rx_ring[0]);
|
||||
|
||||
w840private.dirty_rx = (unsigned int)(i - RX_RING_SIZE);
|
||||
|
||||
for (i = 0; i < TX_RING_SIZE; i++) {
|
||||
w840private.tx_ring[i].status = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
.deps
|
||||
Makefile
|
||||
stage1
|
||||
stage1.exec
|
||||
@@ -1,15 +0,0 @@
|
||||
pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
|
||||
nodist_pkglib_DATA = stage1
|
||||
|
||||
CLEANFILES = $(nodist_pkglib_DATA)
|
||||
|
||||
# We can't use builtins or standard includes.
|
||||
AM_CCASFLAGS = $(STAGE1_CFLAGS) -fno-builtin -nostdinc
|
||||
stage1_exec_LDFLAGS = -nostdlib -Wl,-N,-Ttext,7C00
|
||||
|
||||
noinst_PROGRAMS = stage1.exec
|
||||
stage1_exec_SOURCES = stage1.S stage1.h
|
||||
|
||||
SUFFIXES = .exec
|
||||
.exec:
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
@@ -1,434 +0,0 @@
|
||||
# Makefile.in generated by automake 1.9.4 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
|
||||
SOURCES = $(stage1_exec_SOURCES)
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
top_builddir = ..
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
INSTALL = @INSTALL@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
noinst_PROGRAMS = stage1.exec$(EXEEXT)
|
||||
subdir = stage1
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
PROGRAMS = $(noinst_PROGRAMS)
|
||||
am_stage1_exec_OBJECTS = stage1.$(OBJEXT)
|
||||
stage1_exec_OBJECTS = $(am_stage1_exec_OBJECTS)
|
||||
stage1_exec_LDADD = $(LDADD)
|
||||
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
|
||||
CCASCOMPILE = $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS)
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
SOURCES = $(stage1_exec_SOURCES)
|
||||
DIST_SOURCES = $(stage1_exec_SOURCES)
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
|
||||
am__installdirs = "$(DESTDIR)$(pkglibdir)"
|
||||
nodist_pkglibDATA_INSTALL = $(INSTALL_DATA)
|
||||
DATA = $(nodist_pkglib_DATA)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMDEP_FALSE = @AMDEP_FALSE@
|
||||
AMDEP_TRUE = @AMDEP_TRUE@
|
||||
AMTAR = @AMTAR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
BUILD_EXAMPLE_KERNEL_FALSE = @BUILD_EXAMPLE_KERNEL_FALSE@
|
||||
BUILD_EXAMPLE_KERNEL_TRUE = @BUILD_EXAMPLE_KERNEL_TRUE@
|
||||
CC = @CC@
|
||||
CCAS = @CCAS@
|
||||
CCASFLAGS = @CCASFLAGS@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DISKLESS_SUPPORT_FALSE = @DISKLESS_SUPPORT_FALSE@
|
||||
DISKLESS_SUPPORT_TRUE = @DISKLESS_SUPPORT_TRUE@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FSYS_CFLAGS = @FSYS_CFLAGS@
|
||||
GRUB_CFLAGS = @GRUB_CFLAGS@
|
||||
GRUB_LIBS = @GRUB_LIBS@
|
||||
HERCULES_SUPPORT_FALSE = @HERCULES_SUPPORT_FALSE@
|
||||
HERCULES_SUPPORT_TRUE = @HERCULES_SUPPORT_TRUE@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAINT = @MAINT@
|
||||
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
|
||||
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
|
||||
NETBOOT_SUPPORT_FALSE = @NETBOOT_SUPPORT_FALSE@
|
||||
NETBOOT_SUPPORT_TRUE = @NETBOOT_SUPPORT_TRUE@
|
||||
NET_CFLAGS = @NET_CFLAGS@
|
||||
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||
OBJCOPY = @OBJCOPY@
|
||||
OBJEXT = @OBJEXT@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PERL = @PERL@
|
||||
RANLIB = @RANLIB@
|
||||
SERIAL_SPEED_SIMULATION_FALSE = @SERIAL_SPEED_SIMULATION_FALSE@
|
||||
SERIAL_SPEED_SIMULATION_TRUE = @SERIAL_SPEED_SIMULATION_TRUE@
|
||||
SERIAL_SUPPORT_FALSE = @SERIAL_SUPPORT_FALSE@
|
||||
SERIAL_SUPPORT_TRUE = @SERIAL_SUPPORT_TRUE@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STAGE1_CFLAGS = @STAGE1_CFLAGS@
|
||||
STAGE2_CFLAGS = @STAGE2_CFLAGS@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_OBJCOPY = @ac_ct_OBJCOPY@
|
||||
ac_ct_RANLIB = @ac_ct_RANLIB@
|
||||
ac_ct_STRIP = @ac_ct_STRIP@
|
||||
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
|
||||
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
datadir = @datadir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
nodist_pkglib_DATA = stage1
|
||||
CLEANFILES = $(nodist_pkglib_DATA)
|
||||
|
||||
# We can't use builtins or standard includes.
|
||||
AM_CCASFLAGS = $(STAGE1_CFLAGS) -fno-builtin -nostdinc
|
||||
stage1_exec_LDFLAGS = -nostdlib -Wl,-N,-Ttext,7C00
|
||||
stage1_exec_SOURCES = stage1.S stage1.h
|
||||
SUFFIXES = .exec
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .exec .S .o .obj
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
|
||||
&& exit 0; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu stage1/Makefile'; \
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu stage1/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
clean-noinstPROGRAMS:
|
||||
-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
|
||||
stage1.exec$(EXEEXT): $(stage1_exec_OBJECTS) $(stage1_exec_DEPENDENCIES)
|
||||
@rm -f stage1.exec$(EXEEXT)
|
||||
$(LINK) $(stage1_exec_LDFLAGS) $(stage1_exec_OBJECTS) $(stage1_exec_LDADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
.S.o:
|
||||
$(CCASCOMPILE) -c $<
|
||||
|
||||
.S.obj:
|
||||
$(CCASCOMPILE) -c `$(CYGPATH_W) '$<'`
|
||||
uninstall-info-am:
|
||||
install-nodist_pkglibDATA: $(nodist_pkglib_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(pkglibdir)" || $(mkdir_p) "$(DESTDIR)$(pkglibdir)"
|
||||
@list='$(nodist_pkglib_DATA)'; for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
f=$(am__strip_dir) \
|
||||
echo " $(nodist_pkglibDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkglibdir)/$$f'"; \
|
||||
$(nodist_pkglibDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkglibdir)/$$f"; \
|
||||
done
|
||||
|
||||
uninstall-nodist_pkglibDATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(nodist_pkglib_DATA)'; for p in $$list; do \
|
||||
f=$(am__strip_dir) \
|
||||
echo " rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \
|
||||
rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \
|
||||
done
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$tags $$unique; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$tags $$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& cd $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) $$here
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
|
||||
list='$(DISTFILES)'; for file in $$list; do \
|
||||
case $$file in \
|
||||
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
|
||||
esac; \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
dir="/$$dir"; \
|
||||
$(mkdir_p) "$(distdir)$$dir"; \
|
||||
else \
|
||||
dir=''; \
|
||||
fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||
fi; \
|
||||
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(PROGRAMS) $(DATA)
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(pkglibdir)"; do \
|
||||
test -z "$$dir" || $(mkdir_p) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-noinstPROGRAMS mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
|
||||
install-exec-am: install-nodist_pkglibDATA
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-man:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-info-am uninstall-nodist_pkglibDATA
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
|
||||
clean-noinstPROGRAMS ctags distclean distclean-compile \
|
||||
distclean-generic distclean-tags distdir dvi dvi-am html \
|
||||
html-am info info-am install install-am install-data \
|
||||
install-data-am install-exec install-exec-am install-info \
|
||||
install-info-am install-man install-nodist_pkglibDATA \
|
||||
install-strip installcheck installcheck-am installdirs \
|
||||
maintainer-clean maintainer-clean-generic mostlyclean \
|
||||
mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
|
||||
tags uninstall uninstall-am uninstall-info-am \
|
||||
uninstall-nodist_pkglibDATA
|
||||
|
||||
.exec:
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
Loaded 100 of 179 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user