update the network support to etherboot-4.5.8.

This commit is contained in:
okuji 2000-04-22 01:17:09 +00:00
parent 26fef18cb8
commit 5ff25f9b8f
51 changed files with 5395 additions and 3479 deletions

143
ChangeLog
View file

@ -1,3 +1,146 @@
2000-04-22 OKUJI Yoshinori <okuji@gnu.org>
Update the network support to Etherboot 4.5.8.
* configure.in (--enable-3c590): New option.
(--enable-3c595): Likewise.
(--enable-depca): Likewise.
(--enable-lance): Likewise.
(--enable-ns8390): Likewise.
(--enable-ntulip): Likewise.
(--enable-lancepci): Removed.
(--enable-nepci): Likewise.
(--enable-otulip): Likewise.
(--enable-smc9000): The duplicated one is named to ...
(--enable-smc9000-scan): ... this. This was a typo, perhaps.
* netboot/Makefile.am (libdrivers_a_SOURCES): Removed
byteorder.h, if.h, netboot_config.h and netdevice.h, and added
cards.h.
(EXTRA_libdrivers_a_SOURCES): Removed ntulip.c and tulip.h, and
added 3c595.c, 3c595.h, depca.c, otulip.c and otulip.h.
(libdrivers_a_CFLAGS): Define FSYS_TFTP as 1 instead of empty.
(EXTRA_DIST): Removed ntulip.txt, and added cs89x0.txt and
tulip.txt.
(3c595_drivers): New variable.
(depca_drivers): Likewise.
(lance_drivers): Removed lancepci.o and added lance.o.
(ns8390_drivers): Removed nepci.o and added ns8390.o.
(ntulip_drivers): Deleted.
(otulip_drivers): New variable.
($(3c595_drivers)): New target.
($(depca_drivers)): Likewise.
($(ntulip_drivers)): Deleted.
($(otulip_drivers)): New target.
(3c590_o_CFLAGS): New variable.
(3c595_o_CFLAGS): Likewise.
(depca_o_CFLAGS): Likewise.
(lancepci_o_CFLAGS): Deleted.
(lance_o_CFLAGS): New variable.
(nepci_o_CFLAGS): Deleted.
(ns8390_o_CFLAGS): New variable.
(ntulip_o_CFLAGS): Deleted.
(otulip_o_CFLAGS): New variable.
* netboot/3c90x.c: Updated to Etherboot-4.5.8.
* netboot/3c90x.txt: Likewise.
* netboot/cs89x0.c: Likewise.
* netboot/cs89x0.h: Likewise.
* netboot/eepro100.c: Likewise.
* netboot/epic100.c: Likewise.
* netboot/epic100.h: Likewise.
* netboot/i82586.c: Likewise.
* netboot/lance.c: Likewise.
* netboot/linux-asm-io.h: Likewise.
* netboot/linux-asm-string.h: Likewise.
* netboot/nic.h: Likewise.
* netboot/ns8390.c: Likewise.
* netboot/ns8390.h: Likewise.
* netboot/pci.c: Likewise.
* netboot/pci.h: Likewise.
* netboot/rtl8139.c: Likewise.
* netboot/sk_g16.c: Likewise.
* netboot/sk_g16.h: Likewise.
* netboot/smc9000.c: Likewise.
* netboot/smc9000.h: Likewise.
* netboot/tiara.c: Likewise.
* netboot/tulip.c: Likewise.
* netboot/via-rhine.c: Likewise.
* netboot/config.c: Updated to Etherboot-4.5.8 and modified (see
below).
[GRUB] (print_config): Undefined.
(eth_probe) [GRUB]: If PROBED is true, do nothing. Otherwise,
clear NETWORK_READY and ARPTABLE, set ROM to ROM_INFO_LOCATION,
and set PROBED to 1 if succeeds.
* netboot/etherboot.h: Likewise,
(GRUB): New macro.
[GRUB]: Include <shared.h>.
[GRUB] (NO_DHCP_SUPPORT): Undefined.
[GRUB] (RELOC): Defined as zero.
[GRUB] (INTERNAL_BOOTP_DATA): Defined as one.
[GRUB] (USE_INTERNAL_BUFFER): Likewise.
[GRUB] (BACKOFF_LIMIT): Defined as 7.
[GRUB] (CTRL_C): New macro.
[GRUB] (print_network_configuration): Declared.
[GRUB] (ip_abort): Likewise.
[GRUB] (network_ready): Likewise.
* netboot/fsys_tftp.c: Don't include <netboot_config.h>.
(isocket): Renamed to ...
(iport): ... this.
(osocket): Renamed to ...
(oport): ... this.
(bcounter): New variable.
(buf_fill): When checking the block order, see BCOUNTER as well
as BLOCK.
Don't process a packet, if BLOCK minus PREVBLOCK is not 1,
instead of if BLOCK is less than or equal to PREVBLOCK.
Increment BCOUNTER after reseting RETRY.
(send_rrq): Clear BCOUNTER.
Call await_reply with AWAIT_QDRAIN.
* netboot/main.c: Don't include <netboot_config.h>.
(dhcpdiscover): Made const.
(dhcprequest): Likewise. Updated the contents.
(broadcast): Made const.
(udp_transmit): Copied.
(tftp): Likewise.
(bootp): Likewise.
(rarp): Likewise.
(await_reply): Likewise.
(decode_rfc1533): Likewise.
(rfc951_sleep): Likewise.
(cleanup_net): Likewise.
* netboot/misc.c (sleep): Copied.
(twiddle): Likewise.
(getdec): Likewise.
* netboot/osdep.h: Copied and modified (see below).
[GRUB] (ETHERBOOT32): Used the same definition as Linux and
FreeBSD.
[GRUB] (ntohl): Likewise.
[GRUB] (htonl): Likewise.
[GRUB] (ntohs): Likewise.
[GRUB] (htons): Likewise.
[GRUB] (swap32): Likewise.
[GRUB] (swap16): Likewise.
[GRUB]: Include "linux-asm-io.h".
* netboot/byteorder.h: Removed.
* netboot/if.h: Likewise.
* netboot/netboot_config.h: Likewise.
* netboot/netdevice.h: Likewise.
* netboot/ntulip.c: Likewise.
* netboot/ntulip.txt: Likewise.
* netboot/tulip.h: Likewise.
* netboot/3c595.c: New file. Copied from Etherboot-4.5.8.
* netboot/3c595.h: Likewise.
* netboot/cards.h: Likewise.
* netboot/cs89x0.txt: Likewise.
* netboot/depca.c: Likewise.
* netboot/otulip.c: Likewise.
* netboot/otulip.h: Likewise.
* netboot/tulip.txt: Likewise.
2000-02-29 Jochen Hoenicke <jochen@gnu.org>
* stage2/common.c (err_list): Added message for ERR_UNALIGNED.

2
NEWS
View file

@ -21,6 +21,8 @@ New in 0.5.95 - XXXX-XX-XX:
"grub-install" has the same effect as to the command "install".
* The configure script doesn't accept the option
`--disable-lba-support-bitmap-check' any longer. Use the option above.
* The network support is updated to Etherboot-4.5.8. So now we have
3Com59x and DEPCA drivers.
New in 0.5.94 - 2000-03-06:
* Stage 1 supports both the LBA mode and the CHS mode.

244
configure vendored
View file

@ -42,10 +42,16 @@ ac_help="$ac_help
--enable-3c509 enable 3Com509 driver"
ac_help="$ac_help
--enable-3c529 enable 3Com529 driver"
ac_help="$ac_help
--enable-3c590 enable 3Com590 driver"
ac_help="$ac_help
--enable-3c595 enable 3Com595 driver"
ac_help="$ac_help
--enable-3c90x enable 3Com90x driver"
ac_help="$ac_help
--enable-cs89x0 enable CS89x0 driver"
ac_help="$ac_help
--enable-depca enable DEPCA and EtherWORKS driver"
ac_help="$ac_help
--enable-eepro100 enable Etherexpress Pro/100 driver"
ac_help="$ac_help
@ -57,7 +63,7 @@ ac_help="$ac_help
ac_help="$ac_help
--enable-ni5210 enable Racal-Interlan NI5210 driver"
ac_help="$ac_help
--enable-lancepci enable Lance PCI PCNet/32 driver"
--enable-lance enable Lance PCI PCNet/32 driver"
ac_help="$ac_help
--enable-ne2100 enable Novell NE2100 driver"
ac_help="$ac_help
@ -67,11 +73,11 @@ ac_help="$ac_help
ac_help="$ac_help
--enable-ne enable NE1000/2000 ISA driver"
ac_help="$ac_help
--enable-nepci enable NE2000 PCI driver"
--enable-ns8390 enable NE2000 PCI driver"
ac_help="$ac_help
--enable-wd enable WD8003/8013, SMC8216/8416 driver"
ac_help="$ac_help
--enable-ntulip enable Tulip driver"
--enable-otulip enable old Tulip driver"
ac_help="$ac_help
--enable-rtl8139 enable Realtek 8139 driver"
ac_help="$ac_help
@ -81,7 +87,7 @@ ac_help="$ac_help
ac_help="$ac_help
--enable-tiara enable Tiara driver"
ac_help="$ac_help
--enable-tulip enable old Tulip driver"
--enable-tulip enable Tulip driver"
ac_help="$ac_help
--enable-via-rhine enable Rhine-I/II driver"
ac_help="$ac_help
@ -644,7 +650,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
echo "configure:648: checking for a BSD compatible install" >&5
echo "configure:654: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@ -697,7 +703,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
echo "configure:701: checking whether build environment is sane" >&5
echo "configure:707: checking whether build environment is sane" >&5
# Just in case
sleep 1
echo timestamp > conftestfile
@ -769,7 +775,7 @@ do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:773: checking for $ac_word" >&5
echo "configure:779: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -799,7 +805,7 @@ test -n "$AWK" && break
done
echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
echo "configure:803: checking whether ${MAKE-make} sets \${MAKE}" >&5
echo "configure:809: checking whether ${MAKE-make} sets \${MAKE}" >&5
set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@ -934,7 +940,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
fi
echo $ac_n "checking host system type""... $ac_c" 1>&6
echo "configure:938: checking host system type" >&5
echo "configure:944: checking host system type" >&5
host_alias=$host
case "$host_alias" in
@ -968,7 +974,7 @@ esac
#
echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
echo "configure:972: checking whether to enable maintainer-specific portions of Makefiles" >&5
echo "configure:978: checking whether to enable maintainer-specific portions of Makefiles" >&5
# Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
if test "${enable_maintainer_mode+set}" = set; then
enableval="$enable_maintainer_mode"
@ -994,7 +1000,7 @@ if test "x$enable_maintainer_mode" = xyes; then
# Extract the first word of "perl", so it can be a program name with args.
set dummy perl; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:998: checking for $ac_word" >&5
echo "configure:1004: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1041,7 +1047,7 @@ fi
#
echo $ac_n "checking build system type""... $ac_c" 1>&6
echo "configure:1045: checking build system type" >&5
echo "configure:1051: checking build system type" >&5
build_alias=$build
case "$build_alias" in
@ -1067,7 +1073,7 @@ fi
# Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
set dummy ${ac_tool_prefix}gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1071: checking for $ac_word" >&5
echo "configure:1077: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1099,7 +1105,7 @@ fi
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1103: checking for $ac_word" >&5
echo "configure:1109: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1129,7 +1135,7 @@ if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1133: checking for $ac_word" >&5
echo "configure:1139: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1180,7 +1186,7 @@ fi
# Extract the first word of "cl", so it can be a program name with args.
set dummy cl; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1184: checking for $ac_word" >&5
echo "configure:1190: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1212,7 +1218,7 @@ fi
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
echo "configure:1216: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
echo "configure:1222: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@ -1223,12 +1229,12 @@ cross_compiling=$ac_cv_prog_cc_cross
cat > conftest.$ac_ext << EOF
#line 1227 "configure"
#line 1233 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
if { (eval echo configure:1232: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:1238: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then
@ -1254,12 +1260,12 @@ if test $ac_cv_prog_cc_works = no; then
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
echo "configure:1258: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "configure:1264: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
echo "configure:1263: checking whether we are using GNU C" >&5
echo "configure:1269: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1268,7 +1274,7 @@ else
yes;
#endif
EOF
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1272: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1278: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes
else
ac_cv_prog_gcc=no
@ -1287,7 +1293,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
echo "configure:1291: checking whether ${CC-cc} accepts -g" >&5
echo "configure:1297: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1320,7 +1326,7 @@ fi
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
echo "configure:1324: checking how to run the C preprocessor" >&5
echo "configure:1330: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
@ -1335,13 +1341,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
#line 1339 "configure"
#line 1345 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1345: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:1351: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@ -1352,13 +1358,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
#line 1356 "configure"
#line 1362 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1362: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:1368: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@ -1369,13 +1375,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF
#line 1373 "configure"
#line 1379 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1379: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:1385: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@ -1408,7 +1414,7 @@ echo "$ac_t""$CPP" 1>&6
depcc="$CC"
depcpp="$CPP"
echo $ac_n "checking dependency style of $depcc""... $ac_c" 1>&6
echo "configure:1412: checking dependency style of $depcc" >&5
echo "configure:1418: checking dependency style of $depcc" >&5
if eval "test \"`echo '$''{'am_cv_CC_dependencies_compiler_type'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1464,7 +1470,7 @@ if test "x$with_binutils" != x; then
# Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1468: checking for $ac_word" >&5
echo "configure:1474: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1501,7 +1507,7 @@ else
# Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1505: checking for $ac_word" >&5
echo "configure:1511: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1541,7 +1547,7 @@ if test "x$ac_cv_prog_gcc" = xyes; then
STAGE1_CFLAGS="-O2"
GRUB_CFLAGS="-O2"
echo $ac_n "checking whether optimization for size works""... $ac_c" 1>&6
echo "configure:1545: checking whether optimization for size works" >&5
echo "configure:1551: checking whether optimization for size works" >&5
if eval "test \"`echo '$''{'size_flag'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1549,14 +1555,14 @@ else
saved_CFLAGS=$CFLAGS
CFLAGS="-Os -g"
cat > conftest.$ac_ext <<EOF
#line 1553 "configure"
#line 1559 "configure"
#include "confdefs.h"
int main() {
; return 0; }
EOF
if { (eval echo configure:1560: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if { (eval echo configure:1566: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
size_flag=yes
else
@ -1590,7 +1596,7 @@ if test "x$with_binutils" != x; then
# Extract the first word of "objcopy", so it can be a program name with args.
set dummy objcopy; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1594: checking for $ac_word" >&5
echo "configure:1600: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_OBJCOPY'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1626,7 +1632,7 @@ else
# Extract the first word of "${ac_tool_prefix}objcopy", so it can be a program name with args.
set dummy ${ac_tool_prefix}objcopy; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1630: checking for $ac_word" >&5
echo "configure:1636: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_OBJCOPY'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1660,7 +1666,7 @@ fi
# Defined in acinclude.m4.
echo $ac_n "checking if C symbols get an underscore after compilation""... $ac_c" 1>&6
echo "configure:1664: checking if C symbols get an underscore after compilation" >&5
echo "configure:1670: checking if C symbols get an underscore after compilation" >&5
if eval "test \"`echo '$''{'grub_cv_asm_uscore'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1673,7 +1679,7 @@ func (int *list)
}
EOF
if { ac_try='${CC-cc} ${CFLAGS} -S conftest.c'; { (eval echo configure:1677: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.s; then
if { ac_try='${CC-cc} ${CFLAGS} -S conftest.c'; { (eval echo configure:1683: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.s; then
true
else
{ echo "configure: error: ${CC-cc} failed to produce assembly code" 1>&2; exit 1; }
@ -1699,7 +1705,7 @@ fi
echo "$ac_t""$grub_cv_asm_uscore" 1>&6
echo $ac_n "checking whether ${OBJCOPY} works for absolute addresses""... $ac_c" 1>&6
echo "configure:1703: checking whether ${OBJCOPY} works for absolute addresses" >&5
echo "configure:1709: checking whether ${OBJCOPY} works for absolute addresses" >&5
if eval "test \"`echo '$''{'grub_cv_prog_objcopy_absolute'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1711,21 +1717,21 @@ cmain (void)
}
EOF
if { (eval echo configure:1715: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.o; then :
if { (eval echo configure:1721: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.o; then :
else
{ echo "configure: error: ${CC-cc} cannot compile C source code" 1>&2; exit 1; }
fi
grub_cv_prog_objcopy_absolute=yes
for link_addr in 2000 8000 7C00; do
if { ac_try='${CC-cc} ${CFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec'; { (eval echo configure:1721: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then :
if { ac_try='${CC-cc} ${CFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec'; { (eval echo configure:1727: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then :
else
{ echo "configure: error: ${CC-cc} cannot link at address $link_addr" 1>&2; exit 1; }
fi
if { ac_try='${OBJCOPY-objcopy} -O binary conftest.exec conftest'; { (eval echo configure:1725: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then :
if { ac_try='${OBJCOPY-objcopy} -O binary conftest.exec conftest'; { (eval echo configure:1731: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then :
else
{ echo "configure: error: ${OBJCOPY-objcopy} cannot create binary files" 1>&2; exit 1; }
fi
if test ! -f conftest.old || { ac_try='cmp -s conftest.old conftest'; { (eval echo configure:1729: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
if test ! -f conftest.old || { ac_try='cmp -s conftest.old conftest'; { (eval echo configure:1735: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
mv -f conftest conftest.old
else
grub_cv_prog_objcopy_absolute=no
@ -1742,7 +1748,7 @@ fi
echo $ac_n "checking whether addr32 must be in the same line as the instruction""... $ac_c" 1>&6
echo "configure:1746: checking whether addr32 must be in the same line as the instruction" >&5
echo "configure:1752: checking whether addr32 must be in the same line as the instruction" >&5
if eval "test \"`echo '$''{'grub_cv_asm_prefix_requirement'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1751,7 +1757,7 @@ else
l1: addr32 movb %al, l1
EOF
if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s'; { (eval echo configure:1755: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.o; then
if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s'; { (eval echo configure:1761: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.o; then
grub_cv_asm_prefix_requirement=yes
else
grub_cv_asm_prefix_requirement=no
@ -1783,7 +1789,7 @@ echo "$ac_t""$grub_cv_asm_prefix_requirement" 1>&6
echo $ac_n "checking for .code16 addr32 assembler support""... $ac_c" 1>&6
echo "configure:1787: checking for .code16 addr32 assembler support" >&5
echo "configure:1793: checking for .code16 addr32 assembler support" >&5
if eval "test \"`echo '$''{'grub_cv_asm_addr32'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1798,7 +1804,7 @@ else
sed -e s/@ADDR32@/addr32\;/ < conftest.s.in > conftest.s
fi
if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s'; { (eval echo configure:1802: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.o; then
if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s'; { (eval echo configure:1808: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.o; then
grub_cv_asm_addr32=yes
else
grub_cv_asm_addr32=no
@ -1815,19 +1821,19 @@ fi
echo $ac_n "checking if start is defined by the compiler""... $ac_c" 1>&6
echo "configure:1819: checking if start is defined by the compiler" >&5
echo "configure:1825: checking if start is defined by the compiler" >&5
if eval "test \"`echo '$''{'grub_cv_check_start_symbol'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1824 "configure"
#line 1830 "configure"
#include "confdefs.h"
int main() {
asm ("incl start")
; return 0; }
EOF
if { (eval echo configure:1831: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:1837: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
grub_cv_check_start_symbol=yes
else
@ -1851,19 +1857,19 @@ echo "$ac_t""$grub_cv_check_start_symbol" 1>&6
echo $ac_n "checking if _start is defined by the compiler""... $ac_c" 1>&6
echo "configure:1855: checking if _start is defined by the compiler" >&5
echo "configure:1861: checking if _start is defined by the compiler" >&5
if eval "test \"`echo '$''{'grub_cv_check_uscore_start_symbol'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1860 "configure"
#line 1866 "configure"
#include "confdefs.h"
int main() {
asm ("incl _start")
; return 0; }
EOF
if { (eval echo configure:1867: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:1873: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
grub_cv_check_uscore_start_symbol=yes
else
@ -1892,19 +1898,19 @@ fi
echo $ac_n "checking if __bss_start is defined by the compiler""... $ac_c" 1>&6
echo "configure:1896: checking if __bss_start is defined by the compiler" >&5
echo "configure:1902: checking if __bss_start is defined by the compiler" >&5
if eval "test \"`echo '$''{'grub_cv_check_uscore_uscore_bss_start_symbol'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1901 "configure"
#line 1907 "configure"
#include "confdefs.h"
int main() {
asm ("incl __bss_start")
; return 0; }
EOF
if { (eval echo configure:1908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:1914: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
grub_cv_check_uscore_uscore_bss_start_symbol=yes
else
@ -1928,19 +1934,19 @@ echo "$ac_t""$grub_cv_check_uscore_uscore_bss_start_symbol" 1>&6
echo $ac_n "checking if _edata is defined by the compiler""... $ac_c" 1>&6
echo "configure:1932: checking if _edata is defined by the compiler" >&5
echo "configure:1938: checking if _edata is defined by the compiler" >&5
if eval "test \"`echo '$''{'grub_cv_check_uscore_edata_symbol'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1937 "configure"
#line 1943 "configure"
#include "confdefs.h"
int main() {
asm ("incl _edata")
; return 0; }
EOF
if { (eval echo configure:1944: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:1950: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
grub_cv_check_uscore_edata_symbol=yes
else
@ -1964,19 +1970,19 @@ echo "$ac_t""$grub_cv_check_uscore_edata_symbol" 1>&6
echo $ac_n "checking if edata is defined by the compiler""... $ac_c" 1>&6
echo "configure:1968: checking if edata is defined by the compiler" >&5
echo "configure:1974: checking if edata is defined by the compiler" >&5
if eval "test \"`echo '$''{'grub_cv_check_edata_symbol'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1973 "configure"
#line 1979 "configure"
#include "confdefs.h"
int main() {
asm ("incl edata")
; return 0; }
EOF
if { (eval echo configure:1980: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:1986: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
grub_cv_check_edata_symbol=yes
else
@ -2006,19 +2012,19 @@ fi
echo $ac_n "checking if end is defined by the compiler""... $ac_c" 1>&6
echo "configure:2010: checking if end is defined by the compiler" >&5
echo "configure:2016: checking if end is defined by the compiler" >&5
if eval "test \"`echo '$''{'grub_cv_check_end_symbol'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2015 "configure"
#line 2021 "configure"
#include "confdefs.h"
int main() {
asm ("incl end")
; return 0; }
EOF
if { (eval echo configure:2022: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:2028: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
grub_cv_check_end_symbol=yes
else
@ -2042,19 +2048,19 @@ echo "$ac_t""$grub_cv_check_end_symbol" 1>&6
echo $ac_n "checking if _end is defined by the compiler""... $ac_c" 1>&6
echo "configure:2046: checking if _end is defined by the compiler" >&5
echo "configure:2052: checking if _end is defined by the compiler" >&5
if eval "test \"`echo '$''{'grub_cv_check_uscore_end_symbol'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2051 "configure"
#line 2057 "configure"
#include "confdefs.h"
int main() {
asm ("incl _end")
; return 0; }
EOF
if { (eval echo configure:2058: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:2064: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
grub_cv_check_uscore_end_symbol=yes
else
@ -2092,7 +2098,7 @@ fi
# Get the filename or the whole disk and open it.
# Known to work on NetBSD.
echo $ac_n "checking for opendisk in -lutil""... $ac_c" 1>&6
echo "configure:2096: checking for opendisk in -lutil" >&5
echo "configure:2102: checking for opendisk in -lutil" >&5
ac_lib_var=`echo util'_'opendisk | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@ -2100,7 +2106,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lutil $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2104 "configure"
#line 2110 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@ -2111,7 +2117,7 @@ int main() {
opendisk()
; return 0; }
EOF
if { (eval echo configure:2115: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:2121: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -2139,7 +2145,7 @@ fi
# Unless the user specify --without-curses, check for curses.
if test "x$with_curses" != "xno"; then
echo $ac_n "checking for wgetch in -lncurses""... $ac_c" 1>&6
echo "configure:2143: checking for wgetch in -lncurses" >&5
echo "configure:2149: checking for wgetch in -lncurses" >&5
ac_lib_var=`echo ncurses'_'wgetch | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@ -2147,7 +2153,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lncurses $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2151 "configure"
#line 2157 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@ -2158,7 +2164,7 @@ int main() {
wgetch()
; return 0; }
EOF
if { (eval echo configure:2162: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:2168: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -2181,7 +2187,7 @@ EOF
else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for wgetch in -lcurses""... $ac_c" 1>&6
echo "configure:2185: checking for wgetch in -lcurses" >&5
echo "configure:2191: checking for wgetch in -lcurses" >&5
ac_lib_var=`echo curses'_'wgetch | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@ -2189,7 +2195,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lcurses $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2193 "configure"
#line 2199 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@ -2200,7 +2206,7 @@ int main() {
wgetch()
; return 0; }
EOF
if { (eval echo configure:2204: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:2210: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -2235,17 +2241,17 @@ for ac_hdr in string.h strings.h ncurses/curses.h ncurses.h curses.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:2239: checking for $ac_hdr" >&5
echo "configure:2245: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2244 "configure"
#line 2250 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:2249: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:2255: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@ -2385,6 +2391,27 @@ if test "x$enable_3c529" = xyes; then
NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c529.o"
fi
# Check whether --enable-3c590 or --disable-3c590 was given.
if test "${enable_3c590+set}" = set; then
enableval="$enable_3c590"
:
fi
if test "x$enable_3c590" = xyes; then
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C590=1"
NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c590.o"
fi
# Check whether --enable-3c595 or --disable-3c595 was given.
if test "${enable_3c595+set}" = set; then
enableval="$enable_3c595"
:
fi
if test "x$enable_3c595" = xyes; then
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C595=1"
NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c595.o"
fi
# Check whether --enable-3c90x or --disable-3c90x was given.
if test "${enable_3c90x+set}" = set; then
@ -2408,6 +2435,17 @@ if test "x$enable_cs89x0" = xyes; then
NETBOOT_DRIVERS="$NETBOOT_DRIVERS cs89x0.o"
fi
# Check whether --enable-depca or --disable-depca was given.
if test "${enable_depca+set}" = set; then
enableval="$enable_depca"
:
fi
if test "x$enable_depca" = xyes; then
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_DEPCA=1"
NETBOOT_DRIVERS="$NETBOOT_DRIVERS depca.o"
fi
# Check whether --enable-eepro100 or --disable-eepro100 was given.
if test "${enable_eepro100+set}" = set; then
enableval="$enable_eepro100"
@ -2463,15 +2501,15 @@ if test "x$enable_ni5210" = xyes; then
NETBOOT_DRIVERS="$NETBOOT_DRIVERS ni5210.o"
fi
# Check whether --enable-lancepci or --disable-lancepci was given.
if test "${enable_lancepci+set}" = set; then
enableval="$enable_lancepci"
# Check whether --enable-lance or --disable-lance was given.
if test "${enable_lance+set}" = set; then
enableval="$enable_lance"
:
fi
if test "x$enable_lancepci" = xyes; then
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_LANCEPCI=1"
NETBOOT_DRIVERS="$NETBOOT_DRIVERS lancepci.o"
if test "x$enable_lance" = xyes; then
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_LANCE=1"
NETBOOT_DRIVERS="$NETBOOT_DRIVERS lance.o"
fi
# Check whether --enable-ne2100 or --disable-ne2100 was given.
@ -2518,15 +2556,15 @@ if test "x$enable_ne" = xyes; then
NETBOOT_DRIVERS="$NETBOOT_DRIVERS ne.o"
fi
# Check whether --enable-nepci or --disable-nepci was given.
if test "${enable_nepci+set}" = set; then
enableval="$enable_nepci"
# Check whether --enable-ns8390 or --disable-ns8390 was given.
if test "${enable_ns8390+set}" = set; then
enableval="$enable_ns8390"
:
fi
if test "x$enable_nepci" = xyes; then
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NEPCI=1"
NETBOOT_DRIVERS="$NETBOOT_DRIVERS nepci.o"
if test "x$enable_ns8390" = xyes; then
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NS8390=1"
NETBOOT_DRIVERS="$NETBOOT_DRIVERS ns8390.o"
fi
# Check whether --enable-wd or --disable-wd was given.
@ -2540,15 +2578,15 @@ if test "x$enable_wd" = xyes; then
NETBOOT_DRIVERS="$NETBOOT_DRIVERS wd.o"
fi
# Check whether --enable-ntulip or --disable-ntulip was given.
if test "${enable_ntulip+set}" = set; then
enableval="$enable_ntulip"
# Check whether --enable-otulip or --disable-otulip was given.
if test "${enable_otulip+set}" = set; then
enableval="$enable_otulip"
:
fi
if test "x$enable_ntulip" = xyes; then
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NTULIP=1"
NETBOOT_DRIVERS="$NETBOOT_DRIVERS ntulip.o"
if test "x$enable_otulip" = xyes; then
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_OTULIP=1"
NETBOOT_DRIVERS="$NETBOOT_DRIVERS otulip.o"
fi
# Check whether --enable-rtl8139 or --disable-rtl8139 was given.
@ -2670,9 +2708,9 @@ if test "x$enable_compex_rl2000_fix" = xyes; then
NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCOMPEX_RL2000_FIX=1"
fi
# Check whether --enable-smc9000 or --disable-smc9000 was given.
if test "${enable_smc9000+set}" = set; then
enableval="$enable_smc9000"
# Check whether --enable-smc9000-scan or --disable-smc9000-scan was given.
if test "${enable_smc9000_scan+set}" = set; then
enableval="$enable_smc9000_scan"
NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DSMC9000_SCAN=$enable_smc9000_scan"
fi

View file

@ -1,5 +1,5 @@
dnl Configure script for GRUB.
dnl Copyright 1999 Free Software Foundation, Inc.
dnl Copyright 1999,2000 Free Software Foundation, Inc.
dnl Permission to use, copy, modify and distribute this software and its
dnl documentation is hereby granted, provided that both the copyright
@ -244,12 +244,19 @@ if test "x$enable_3c529" = xyes; then
NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c529.o"
fi
dnl AC_ARG_ENABLE(3c59x,
dnl [ --enable-3c59x enable 3Com59x driver])
dnl if test "x$enable_3c59x" = xyes; then
dnl NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C59x=1"
dnl NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c59x.o"
dnl fi
AC_ARG_ENABLE(3c590,
[ --enable-3c590 enable 3Com590 driver])
if test "x$enable_3c590" = xyes; then
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C590=1"
NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c590.o"
fi
AC_ARG_ENABLE(3c595,
[ --enable-3c595 enable 3Com595 driver])
if test "x$enable_3c595" = xyes; then
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C595=1"
NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c595.o"
fi
AC_ARG_ENABLE(3c90x,
[ --enable-3c90x enable 3Com90x driver])
@ -265,6 +272,13 @@ if test "x$enable_cs89x0" = xyes; then
NETBOOT_DRIVERS="$NETBOOT_DRIVERS cs89x0.o"
fi
AC_ARG_ENABLE(depca,
[ --enable-depca enable DEPCA and EtherWORKS driver])
if test "x$enable_depca" = xyes; then
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_DEPCA=1"
NETBOOT_DRIVERS="$NETBOOT_DRIVERS depca.o"
fi
AC_ARG_ENABLE(eepro100,
[ --enable-eepro100 enable Etherexpress Pro/100 driver])
if test "x$enable_eepro100" = xyes; then
@ -300,11 +314,11 @@ if test "x$enable_ni5210" = xyes; then
NETBOOT_DRIVERS="$NETBOOT_DRIVERS ni5210.o"
fi
AC_ARG_ENABLE(lancepci,
[ --enable-lancepci enable Lance PCI PCNet/32 driver])
if test "x$enable_lancepci" = xyes; then
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_LANCEPCI=1"
NETBOOT_DRIVERS="$NETBOOT_DRIVERS lancepci.o"
AC_ARG_ENABLE(lance,
[ --enable-lance enable Lance PCI PCNet/32 driver])
if test "x$enable_lance" = xyes; then
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_LANCE=1"
NETBOOT_DRIVERS="$NETBOOT_DRIVERS lance.o"
fi
AC_ARG_ENABLE(ne2100,
@ -335,11 +349,11 @@ if test "x$enable_ne" = xyes; then
NETBOOT_DRIVERS="$NETBOOT_DRIVERS ne.o"
fi
AC_ARG_ENABLE(nepci,
[ --enable-nepci enable NE2000 PCI driver])
if test "x$enable_nepci" = xyes; then
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NEPCI=1"
NETBOOT_DRIVERS="$NETBOOT_DRIVERS nepci.o"
AC_ARG_ENABLE(ns8390,
[ --enable-ns8390 enable NE2000 PCI driver])
if test "x$enable_ns8390" = xyes; then
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NS8390=1"
NETBOOT_DRIVERS="$NETBOOT_DRIVERS ns8390.o"
fi
AC_ARG_ENABLE(wd,
@ -349,11 +363,11 @@ if test "x$enable_wd" = xyes; then
NETBOOT_DRIVERS="$NETBOOT_DRIVERS wd.o"
fi
AC_ARG_ENABLE(ntulip,
[ --enable-ntulip enable Tulip driver])
if test "x$enable_ntulip" = xyes; then
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NTULIP=1"
NETBOOT_DRIVERS="$NETBOOT_DRIVERS ntulip.o"
AC_ARG_ENABLE(otulip,
[ --enable-otulip enable old Tulip driver])
if test "x$enable_otulip" = xyes; then
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_OTULIP=1"
NETBOOT_DRIVERS="$NETBOOT_DRIVERS otulip.o"
fi
AC_ARG_ENABLE(rtl8139,
@ -385,7 +399,7 @@ if test "x$enable_tiara" = xyes; then
fi
AC_ARG_ENABLE(tulip,
[ --enable-tulip enable old Tulip driver])
[ --enable-tulip enable Tulip driver])
if test "x$enable_tulip" = xyes; then
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_TULIP=1"
NETBOOT_DRIVERS="$NETBOOT_DRIVERS tulip.o"
@ -430,7 +444,7 @@ if test "x$enable_compex_rl2000_fix" = xyes; then
NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCOMPEX_RL2000_FIX=1"
fi
AC_ARG_ENABLE(smc9000,
AC_ARG_ENABLE(smc9000-scan,
[ --enable-smc9000-scan=LIST
probe for SMC9000 I/O addresses using LIST],
[NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DSMC9000_SCAN=$enable_smc9000_scan"])

535
netboot/3c595.c Normal file
View file

@ -0,0 +1,535 @@
/*
* 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"
static unsigned char eth_vendor, eth_flags, eth_laar;
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);
static void safetwiddle()
{
static int count=0;
static int count2=0;
static char tiddles[]="-\\|/";
putchar(tiddles[(count2++)&0xfff?count&3:(count++)&3]);
putchar('\b');
}
/* a surrogate */
static void DELAY(int val)
{
int c;
for(c=0; c<val; c+=20) {
twiddle();
}
}
static void SAFEDELAY(int val)
{
int c;
for (c=0; c<val; c+=20) {
safetwiddle();
}
}
/**************************************************************************
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);
DELAY(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 < ETHER_ADDR_SIZE; 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 unsigned int len;
int pad;
int status;
#ifdef EDEBUG
printf("{l=%d,t=%x}",s+ETHER_HDR_SIZE,t);
#endif
/* swap bytes of type */
t= htons(t);
len=s+ETHER_HDR_SIZE; /* 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_MAX_PACKET) {
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, ETHER_ADDR_SIZE/2);
outsw(BASE + VX_W1_TX_PIO_WR_1, nic->node_addr, ETHER_ADDR_SIZE/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 */
/* timeout after sending */
DELAY(1000);
}
/**************************************************************************
ETH_POLL - Wait for a frame
***************************************************************************/
static int t595_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 + VX_STATUS);
#ifdef EDEBUG
if(cst & 0x1FFF)
printf("-%x-",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("*%x*",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("*%x*",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;
}
DELAY(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*ETHER_ADDR_SIZE)
printf(",t=0x%x,b]",type);
else
printf(",t=0x%x]",type);
#endif
return 1;
}
/*************************************************************************
3Com 509 - specific routines
**************************************************************************/
static int
eeprom_rdy()
{
int i;
for (i = 0; is_eeprom_busy(BASE) && i < MAX_EEPROMBUSY; i++)
DELAY(1000);
if (i >= MAX_EEPROMBUSY) {
/* printf("3c509: 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);
DELAY(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);
DELAY(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);
DELAY(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("%x:", 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: ");
for(i=0; i<5; i++) {
printf("%b:",nic->node_addr[i]);
}
printf("%b\n",nic->node_addr[i]);
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
netboot/3c595.h Normal file
View file

@ -0,0 +1,435 @@
/*
* 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:
*/

View file

@ -37,11 +37,7 @@
#include "etherboot.h"
#include "nic.h"
#include "pci.h"
#if 0
#ifndef __FreeBSD__
#include <linux/pci.h>
#endif
#endif
#include "cards.h"
#define TIME_OUT 60000
#define XCVR_MAGIC (0x5A00)
@ -477,8 +473,8 @@ a3c90x_reset(struct nic *nic)
*** p - the pointer to the packet data itself.
***/
static void
a3c90x_transmit(struct nic *nic, char *d, unsigned int t,
unsigned int s, char *p)
a3c90x_transmit(struct nic *nic, const char *d, unsigned int t,
unsigned int s, const char *p)
{
struct eth_hdr
@ -539,7 +535,7 @@ a3c90x_transmit(struct nic *nic, char *d, unsigned int t,
if (timeout==0)
{
printf("3C90X: Transmission Timeout\n");
printf("3C90X: Tx Timeout\n");
continue;
}
@ -556,12 +552,12 @@ a3c90x_transmit(struct nic *nic, char *d, unsigned int t,
/** check error codes **/
if (status & 0x02)
{
printf("3C90X: Transmitter Reclaim Error (%x)\n", status);
printf("3C90X: Tx Reclaim Error (%x)\n", status);
a3c90x_reset(NULL);
}
else if (status & 0x04)
{
printf("3C90X: Transmitter Status Overflow (%x)\n", status);
printf("3C90X: Tx Status Overflow (%x)\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 **/
@ -569,18 +565,18 @@ a3c90x_transmit(struct nic *nic, char *d, unsigned int t,
}
else if (status & 0x08)
{
printf("3C90X: Transmitter Max Collisions (%x)\n", status);
printf("3C90X: Tx Max Collisions (%x)\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: Transmitter Underrun (%x)\n", status);
printf("3C90X: Tx Underrun (%x)\n", status);
a3c90x_reset(NULL);
}
else if (status & 0x20)
{
printf("3C90X: Transmitter Jabber (%x)\n", status);
printf("3C90X: Tx Jabber (%x)\n", status);
a3c90x_reset(NULL);
}
else if ((status & 0x80) != 0x80)
@ -638,7 +634,7 @@ a3c90x_poll(struct nic *nic)
{
errcode = INF_3C90X.ReceiveUPD.UpPktStatus;
if (errcode & (1<<16))
printf("3C90X: Receiver Overrun (%x)\n",errcode>>16);
printf("3C90X: Rx Overrun (%x)\n",errcode>>16);
else if (errcode & (1<<17))
printf("3C90X: Runt Frame (%x)\n",errcode>>16);
else if (errcode & (1<<18))
@ -676,9 +672,9 @@ a3c90x_disable(struct nic *nic)
*** card. We just have to init it here.
***/
struct nic*
a3c90x_probe(struct nic *nic, unsigned short *probeaddrs)
a3c90x_probe(struct nic *nic, unsigned short *probeaddrs, struct pci_device *pci)
{
int i, j, to, v, c;
int i, c;
unsigned short eeprom[0x21];
unsigned int cfg;
unsigned int mopt;
@ -718,9 +714,11 @@ a3c90x_probe(struct nic *nic, unsigned short *probeaddrs)
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)
@ -853,7 +851,7 @@ a3c90x_probe(struct nic *nic, unsigned short *probeaddrs)
#ifdef CFG_3C90X_XCVR
if (CFG_3C90X_XCVR != 255)
linktype = CFG_3C90X_XCVR;
#endif // CFG_3C90X_XCVR
#endif /* CFG_3C90X_XCVR */
/** I don't know what MII MAC only mode is!!! **/
if (linktype == 0x0009)

View file

@ -10,13 +10,18 @@
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 is not yet available.
the 3c90xB revision cards. 3C90xC family support has been tested to some
degree but not extensively.
Here's the licensing information:
@ -27,10 +32,10 @@ I OVERVIEW
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.
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
@ -55,22 +60,22 @@ II FLASH PROMS
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.
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.
Better yet, for those using Linux it might be even better if the programming
could be done while Linux is running, either via a modification to the 3c59x
driver or via some other program/driver. That way, a system administrator
on a private network could update all the NC flash images from a centrally
managed location.
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!
III GENERAL USE
@ -79,23 +84,22 @@ III GENERAL USE
1. Run the 3c90xcfg program on the driver diskette to enable the
boot PROM and set it to 64k or 128k, as appropriate.
2. Edit Config (in the src-32 directory) and define the
90X_SIGNATURE for your particular adapter (model numbers and
corresponding values are listed in the file)
3. Build the 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, etc.)
4. Run the floppy image on the PC to be network booted, to get
it configured, and to verify that it will boot properly.
5. Build the 3c90x.rom or 3c90x.lzrom PROM image and program
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 verify that
it will boot properly.
4. Build the 3c90x.rom or 3c90x.lzrom PROM image and program
it into the flash memory chip.
6. Put the PROM in the ethernet card, boot and enable 'boot from
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. A picky BIOS that may work better with NO_PNP_PCI_HEADER
defined to boot the prom image.
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.
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
@ -105,36 +109,37 @@ III GENERAL USE
Some things that are on the 'To-Do' list, perhaps for me, but perhaps
for any other volunteers out there:
1. Write a DOS- or Linux- based flash programmer for the 3c905b
card, so PROM users don't have to buy a $200 programmer....
2. Extend the driver to fully implement the auto-select
1. Extend the driver to fully implement the auto-select
algorithm if the card has multiple media ports.
3. Fix any bugs in the code <grin>....
4. Extend the driver to support the 3c905c revision cards
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.
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).
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:
@ -143,7 +148,9 @@ III GENERAL USE
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.
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
@ -152,11 +159,14 @@ III GENERAL USE
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.
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_3C905B_XCVR=x, where 'x' is one of the following
image with -DCFG_3C90X_XCVR=x, where 'x' is one of the following
values:
0 10Base-T
@ -193,7 +203,7 @@ III GENERAL USE
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.
I haven't tested anything else. The 3com documentation specifically
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
@ -214,10 +224,10 @@ IV FOR DEVELOPERS....
a3c90x_probe is the main entry point for this driver. It is referred
to in an array in 'config.c'.
B. Other Exported Functions
B. Other Important Functions
The functions a3c90x_transmit, a3c90x_poll, a3c90x_reset, and
a3c90x_disable are exported functions that EtherBoot finds out about
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

View file

@ -10,36 +10,37 @@ endif
noinst_LIBRARIES = $(LIBDRIVERS)
libdrivers_a_SOURCES = byteorder.h config.c etherboot.h \
fsys_tftp.c if.h linux-asm-io.h linux-asm-string.h \
main.c misc.c netboot_config.h netdevice.h nic.h osdep.h \
pci.c pci.h
EXTRA_libdrivers_a_SOURCES = 3c509.c 3c509.h 3c90x.c cs89x0.c \
cs89x0.h eepro100.c epic100.c epic100.h i82586.c lance.c \
ns8390.c ns8390.h ntulip.c rtl8139.c sk_g16.c sk_g16.h \
smc9000.c smc9000.h tiara.c tulip.c tulip.h via-rhine.c
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
EXTRA_libdrivers_a_SOURCES = 3c509.c 3c509.h 3c595.c 3c595.h 3c90x.c \
cs89x0.c cs89x0.h depca.c eepro100.c epic100.c epic100.h \
i82586.c lance.c ns8390.c ns8390.h otulip.c otulip.h rtl8139.c \
sk_g16.c sk_g16.h smc9000.c smc9000.h tiara.c tulip.c \
via-rhine.c
libdrivers_a_CFLAGS = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
-DFSYS_TFTP $(NET_CFLAGS) $(NET_EXTRAFLAGS)
-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 ntulip.txt
EXTRA_DIST = README.netboot 3c90x.txt cs89x0.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
#3c59x_drivers = 3c59x.o
3c595_drivers = 3c590.o 3c595.o
3c90x_drivers = 3c90x.o
cs89x0_drivers = cs89x0.o
depca_drivers = depca.o
eepro100_drivers = eepro100.o
epic100_drivers = epic100.o
i82586_drivers = 3c507.o exos205.o ni5210.o
lance_drivers = lancepci.o ne2100.o ni6510.o
ns8390_drivers = 3c503.o ne.o nepci.o wd.o
ntulip_drivers = ntulip.o
lance_drivers = lance.o ne2100.o ni6510.o
ns8390_drivers = 3c503.o ne.o ns8390.o wd.o
otulip_drivers = otulip.o
rtl8139_drivers = rtl8139.o
sk_g16_drivers = sk_g16.o
smc9000_drivers = smc9000.o
@ -63,10 +64,10 @@ $(3c509_drivers): %.o: 3c509.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
#$(3c59x_drivers): 3c59x.c 3c509.h
#$(3c59x_drivers): %.o: 3c59x.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
@ -78,6 +79,11 @@ $(cs89x0_drivers): %.o: cs89x0.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 $<
$(eepro100_drivers): eepro100.c
$(eepro100_drivers): %.o: eepro100.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
@ -93,8 +99,8 @@ $(lance_drivers): %.o: lance.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(ntulip_drivers): ntulip.c
$(ntulip_drivers): %.o: ntulip.c
$(tulip_drivers): tulip.c
$(tulip_drivers): %.o: tulip.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
@ -118,8 +124,8 @@ $(tiara_drivers): %.o: tiara.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(tulip_drivers): tulip.c tulip.h
$(tulip_drivers): %.o: tulip.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 $<
@ -132,22 +138,24 @@ $(via_rhine_drivers): %.o: via-rhine.c
# Per-object flags.
3c509_o_CFLAGS = -DINCLUDE_3C509=1
3c529_o_CFLAGS = -DINCLUDE_3C529=1
#3c59x_o_CFLAGS = -DINCLUDE_3C59X=1
3c590_o_CFLAGS = -DINCLUDE_3C590=1
3c595_o_CFLAGS = -DINCLUDE_3C595=1
3c90x_o_CFLAGS = -DINCLUDE_3C90X=1
cs89x0_o_CFLAGS = -DINCLUDE_CS89X0=1
depca_o_CFLAGS = -DINCLUDE_DEPCA=1
eepro100_o_CFLAGS = -DINCLUDE_EEPRO100=1
epic100_o_CFLAGS = -DINCLUDE_EPIC100=1
3c507_o_CFLAGS = -DINCLUDE_3C507=1
exos205_o_CFLAGS = -DINCLUDE_EXOS205=1
ni5210_o_CFLAGS = -DINCLUDE_NI5210=1
lancepci_o_CFLAGS = -DINCLUDE_LANCEPCI=1
lance_o_CFLAGS = -DINCLUDE_LANCE=1
ne2100_o_CFLAGS = -DINCLUDE_NE2100=1
ni6510_o_CFLAGS = -DINCLUDE_NI6510=1
3c503_o_CFLAGS = -DINCLUDE_3C503=1
ne_o_CFLAGS = -DINCLUDE_NE=1
nepci_o_CFLAGS = -DINCLUDE_NEPCI=1
ns8390_o_CFLAGS = -DINCLUDE_NS8390=1
wd_o_CFLAGS = -DINCLUDE_WD=1
ntulip_o_CFLAGS = -DINCLUDE_NTULIP=1
otulip_o_CFLAGS = -DINCLUDE_OTULIP=1
rtl8139_o_CFLAGS = -DINCLUDE_RTL8139=1
sk_g16_o_CFLAGS = -DINCLUDE_SK_G16=1
smc9000_o_CFLAGS = -DINCLUDE_SMC9000=1

View file

@ -95,39 +95,40 @@ INCLUDES = -I$(top_srcdir)/stage2 -I$(top_srcdir)/stage1
noinst_LIBRARIES = $(LIBDRIVERS)
libdrivers_a_SOURCES = byteorder.h config.c etherboot.h \
fsys_tftp.c if.h linux-asm-io.h linux-asm-string.h \
main.c misc.c netboot_config.h netdevice.h nic.h osdep.h \
pci.c pci.h
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
EXTRA_libdrivers_a_SOURCES = 3c509.c 3c509.h 3c90x.c cs89x0.c \
cs89x0.h eepro100.c epic100.c epic100.h i82586.c lance.c \
ns8390.c ns8390.h ntulip.c rtl8139.c sk_g16.c sk_g16.h \
smc9000.c smc9000.h tiara.c tulip.c tulip.h via-rhine.c
EXTRA_libdrivers_a_SOURCES = 3c509.c 3c509.h 3c595.c 3c595.h 3c90x.c \
cs89x0.c cs89x0.h depca.c eepro100.c epic100.c epic100.h \
i82586.c lance.c ns8390.c ns8390.h otulip.c otulip.h rtl8139.c \
sk_g16.c sk_g16.h smc9000.c smc9000.h tiara.c tulip.c \
via-rhine.c
libdrivers_a_CFLAGS = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
-DFSYS_TFTP $(NET_CFLAGS) $(NET_EXTRAFLAGS)
-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 ntulip.txt
EXTRA_DIST = README.netboot 3c90x.txt cs89x0.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
#3c59x_drivers = 3c59x.o
3c595_drivers = 3c590.o 3c595.o
3c90x_drivers = 3c90x.o
cs89x0_drivers = cs89x0.o
depca_drivers = depca.o
eepro100_drivers = eepro100.o
epic100_drivers = epic100.o
i82586_drivers = 3c507.o exos205.o ni5210.o
lance_drivers = lancepci.o ne2100.o ni6510.o
ns8390_drivers = 3c503.o ne.o nepci.o wd.o
ntulip_drivers = ntulip.o
lance_drivers = lance.o ne2100.o ni6510.o
ns8390_drivers = 3c503.o ne.o ns8390.o wd.o
otulip_drivers = otulip.o
rtl8139_drivers = rtl8139.o
sk_g16_drivers = sk_g16.o
smc9000_drivers = smc9000.o
@ -138,22 +139,24 @@ via_rhine_drivers = via_rhine.o
# Per-object flags.
3c509_o_CFLAGS = -DINCLUDE_3C509=1
3c529_o_CFLAGS = -DINCLUDE_3C529=1
#3c59x_o_CFLAGS = -DINCLUDE_3C59X=1
3c590_o_CFLAGS = -DINCLUDE_3C590=1
3c595_o_CFLAGS = -DINCLUDE_3C595=1
3c90x_o_CFLAGS = -DINCLUDE_3C90X=1
cs89x0_o_CFLAGS = -DINCLUDE_CS89X0=1
depca_o_CFLAGS = -DINCLUDE_DEPCA=1
eepro100_o_CFLAGS = -DINCLUDE_EEPRO100=1
epic100_o_CFLAGS = -DINCLUDE_EPIC100=1
3c507_o_CFLAGS = -DINCLUDE_3C507=1
exos205_o_CFLAGS = -DINCLUDE_EXOS205=1
ni5210_o_CFLAGS = -DINCLUDE_NI5210=1
lancepci_o_CFLAGS = -DINCLUDE_LANCEPCI=1
lance_o_CFLAGS = -DINCLUDE_LANCE=1
ne2100_o_CFLAGS = -DINCLUDE_NE2100=1
ni6510_o_CFLAGS = -DINCLUDE_NI6510=1
3c503_o_CFLAGS = -DINCLUDE_3C503=1
ne_o_CFLAGS = -DINCLUDE_NE=1
nepci_o_CFLAGS = -DINCLUDE_NEPCI=1
ns8390_o_CFLAGS = -DINCLUDE_NS8390=1
wd_o_CFLAGS = -DINCLUDE_WD=1
ntulip_o_CFLAGS = -DINCLUDE_NTULIP=1
otulip_o_CFLAGS = -DINCLUDE_OTULIP=1
rtl8139_o_CFLAGS = -DINCLUDE_RTL8139=1
sk_g16_o_CFLAGS = -DINCLUDE_SK_G16=1
smc9000_o_CFLAGS = -DINCLUDE_SMC9000=1
@ -184,12 +187,13 @@ LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(libdrivers_a_SOURCES) $(EXTRA_libdrivers_a_SOURCES)
depcomp = $(SHELL) $(top_srcdir)/depcomp
DEP_FILES = @AMDEP@ $(DEPDIR)/libdrivers_a-3c509.Po \
$(DEPDIR)/libdrivers_a-3c90x.Po $(DEPDIR)/libdrivers_a-config.Po \
$(DEPDIR)/libdrivers_a-cs89x0.Po $(DEPDIR)/libdrivers_a-eepro100.Po \
$(DEPDIR)/libdrivers_a-3c595.Po $(DEPDIR)/libdrivers_a-3c90x.Po \
$(DEPDIR)/libdrivers_a-config.Po $(DEPDIR)/libdrivers_a-cs89x0.Po \
$(DEPDIR)/libdrivers_a-depca.Po $(DEPDIR)/libdrivers_a-eepro100.Po \
$(DEPDIR)/libdrivers_a-epic100.Po $(DEPDIR)/libdrivers_a-fsys_tftp.Po \
$(DEPDIR)/libdrivers_a-i82586.Po $(DEPDIR)/libdrivers_a-lance.Po \
$(DEPDIR)/libdrivers_a-main.Po $(DEPDIR)/libdrivers_a-misc.Po \
$(DEPDIR)/libdrivers_a-ns8390.Po $(DEPDIR)/libdrivers_a-ntulip.Po \
$(DEPDIR)/libdrivers_a-ns8390.Po $(DEPDIR)/libdrivers_a-otulip.Po \
$(DEPDIR)/libdrivers_a-pci.Po $(DEPDIR)/libdrivers_a-rtl8139.Po \
$(DEPDIR)/libdrivers_a-sk_g16.Po $(DEPDIR)/libdrivers_a-smc9000.Po \
$(DEPDIR)/libdrivers_a-tiara.Po $(DEPDIR)/libdrivers_a-tulip.Po \
@ -238,14 +242,16 @@ libdrivers_a-main.o: main.c
libdrivers_a-misc.o: misc.c
libdrivers_a-pci.o: pci.c
libdrivers_a-3c509.o: 3c509.c
libdrivers_a-3c595.o: 3c595.c
libdrivers_a-3c90x.o: 3c90x.c
libdrivers_a-cs89x0.o: cs89x0.c
libdrivers_a-depca.o: depca.c
libdrivers_a-eepro100.o: eepro100.c
libdrivers_a-epic100.o: epic100.c
libdrivers_a-i82586.o: i82586.c
libdrivers_a-lance.o: lance.c
libdrivers_a-ns8390.o: ns8390.c
libdrivers_a-ntulip.o: ntulip.c
libdrivers_a-otulip.o: otulip.c
libdrivers_a-rtl8139.o: rtl8139.c
libdrivers_a-sk_g16.o: sk_g16.c
libdrivers_a-smc9000.o: smc9000.c
@ -292,9 +298,11 @@ distclean-tags:
maintainer-clean-tags:
@AMDEP@include $(DEPDIR)/libdrivers_a-3c509.Po
@AMDEP@include $(DEPDIR)/libdrivers_a-3c595.Po
@AMDEP@include $(DEPDIR)/libdrivers_a-3c90x.Po
@AMDEP@include $(DEPDIR)/libdrivers_a-config.Po
@AMDEP@include $(DEPDIR)/libdrivers_a-cs89x0.Po
@AMDEP@include $(DEPDIR)/libdrivers_a-depca.Po
@AMDEP@include $(DEPDIR)/libdrivers_a-eepro100.Po
@AMDEP@include $(DEPDIR)/libdrivers_a-epic100.Po
@AMDEP@include $(DEPDIR)/libdrivers_a-fsys_tftp.Po
@ -303,7 +311,7 @@ maintainer-clean-tags:
@AMDEP@include $(DEPDIR)/libdrivers_a-main.Po
@AMDEP@include $(DEPDIR)/libdrivers_a-misc.Po
@AMDEP@include $(DEPDIR)/libdrivers_a-ns8390.Po
@AMDEP@include $(DEPDIR)/libdrivers_a-ntulip.Po
@AMDEP@include $(DEPDIR)/libdrivers_a-otulip.Po
@AMDEP@include $(DEPDIR)/libdrivers_a-pci.Po
@AMDEP@include $(DEPDIR)/libdrivers_a-rtl8139.Po
@AMDEP@include $(DEPDIR)/libdrivers_a-sk_g16.Po
@ -380,6 +388,14 @@ libdrivers_a-3c509.o: 3c509.c
@AMDEP@CCDEPMODE = @CCDEPMODE@
libdrivers_a-3c595.o: 3c595.c
@AMDEP@ source='3c595.c' object='libdrivers_a-3c595.o' libtool=no @AMDEPBACKSLASH@
@AMDEP@ depfile='$(DEPDIR)/libdrivers_a-3c595.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-3c595.TPo' @AMDEPBACKSLASH@
@AMDEP@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-3c595.o `test -f 3c595.c || echo '$(srcdir)/'`3c595.c
@AMDEP@CCDEPMODE = @CCDEPMODE@
libdrivers_a-3c90x.o: 3c90x.c
@AMDEP@ source='3c90x.c' object='libdrivers_a-3c90x.o' libtool=no @AMDEPBACKSLASH@
@AMDEP@ depfile='$(DEPDIR)/libdrivers_a-3c90x.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-3c90x.TPo' @AMDEPBACKSLASH@
@ -396,6 +412,14 @@ libdrivers_a-cs89x0.o: cs89x0.c
@AMDEP@CCDEPMODE = @CCDEPMODE@
libdrivers_a-depca.o: depca.c
@AMDEP@ source='depca.c' object='libdrivers_a-depca.o' libtool=no @AMDEPBACKSLASH@
@AMDEP@ depfile='$(DEPDIR)/libdrivers_a-depca.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-depca.TPo' @AMDEPBACKSLASH@
@AMDEP@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-depca.o `test -f depca.c || echo '$(srcdir)/'`depca.c
@AMDEP@CCDEPMODE = @CCDEPMODE@
libdrivers_a-eepro100.o: eepro100.c
@AMDEP@ source='eepro100.c' object='libdrivers_a-eepro100.o' libtool=no @AMDEPBACKSLASH@
@AMDEP@ depfile='$(DEPDIR)/libdrivers_a-eepro100.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-eepro100.TPo' @AMDEPBACKSLASH@
@ -436,11 +460,11 @@ libdrivers_a-ns8390.o: ns8390.c
@AMDEP@CCDEPMODE = @CCDEPMODE@
libdrivers_a-ntulip.o: ntulip.c
@AMDEP@ source='ntulip.c' object='libdrivers_a-ntulip.o' libtool=no @AMDEPBACKSLASH@
@AMDEP@ depfile='$(DEPDIR)/libdrivers_a-ntulip.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-ntulip.TPo' @AMDEPBACKSLASH@
libdrivers_a-otulip.o: otulip.c
@AMDEP@ source='otulip.c' object='libdrivers_a-otulip.o' libtool=no @AMDEPBACKSLASH@
@AMDEP@ depfile='$(DEPDIR)/libdrivers_a-otulip.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-otulip.TPo' @AMDEPBACKSLASH@
@AMDEP@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-ntulip.o `test -f ntulip.c || echo '$(srcdir)/'`ntulip.c
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-otulip.o `test -f otulip.c || echo '$(srcdir)/'`otulip.c
@AMDEP@CCDEPMODE = @CCDEPMODE@
@ -594,10 +618,10 @@ $(3c509_drivers): %.o: 3c509.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
#$(3c59x_drivers): 3c59x.c 3c509.h
#$(3c59x_drivers): %.o: 3c59x.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
@ -609,6 +633,11 @@ $(cs89x0_drivers): %.o: cs89x0.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 $<
$(eepro100_drivers): eepro100.c
$(eepro100_drivers): %.o: eepro100.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
@ -624,8 +653,8 @@ $(lance_drivers): %.o: lance.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(ntulip_drivers): ntulip.c
$(ntulip_drivers): %.o: ntulip.c
$(tulip_drivers): tulip.c
$(tulip_drivers): %.o: tulip.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
@ -649,8 +678,8 @@ $(tiara_drivers): %.o: tiara.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(tulip_drivers): tulip.c tulip.h
$(tulip_drivers): %.o: tulip.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 $<

View file

@ -43,6 +43,12 @@ drivers at the same time.
3Com529 == MCA 3c509
--enable-3c529
3Com590
--enable-3c590
3Com595
--enable-3c595
3Com90x
--enable-3c90x
@ -54,6 +60,9 @@ Crystal Semiconductor CS89x0
a more aggressive probing algorithm. This might be neccessary after
a soft-reset of the NIC.
Digital DE100 and DE200
--enable-depca
Intel Etherexpress Pro/100
--enable-eepro100
@ -64,12 +73,15 @@ EXOS205
--enable-exos205
Lance PCI PCNet/32
--enable-lancepci
--enable-lance
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 Macronix 987x5
--enable-ntulip
Tulip-Fast
Tulip+
Tulip 21142
--enable-tulip
NE1000/2000 and clones (ISA)
--enable-ne
@ -85,7 +97,7 @@ Winbond 86C940
Compex RL2000
KTI ET32P2
NetVin 5000SC
--enable-nepci
--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
@ -98,6 +110,7 @@ Racal-Interlan NI6510
--enable-ni6510
Realtek 8139
SMC 1211
--enable-rtl8139
Schneider and Koch G16
@ -112,7 +125,7 @@ Tiara, Fujitsu Lancard
--enable-tiara
Old base driver for Tulip clones
--enable-tulip
--enable-otulip
Rhine-I, e.g. D-Link DFE-530TX
Rhine-II

View file

@ -1,77 +0,0 @@
#ifndef _I386_BYTEORDER_H
#define _I386_BYTEORDER_H
/*
* This file contains parts of Linux's /usr/include/asm/byteorder.h
*/
#undef ntohl
#undef ntohs
#undef htonl
#undef htons
extern unsigned long int ntohl(unsigned long int);
extern unsigned short int ntohs(unsigned short int);
extern unsigned long int htonl(unsigned long int);
extern unsigned short int htons(unsigned short int);
extern __inline__ unsigned long int __ntohl(unsigned long int);
extern __inline__ unsigned short int __ntohs(unsigned short int);
extern __inline__ unsigned long int __constant_ntohl(unsigned long int);
extern __inline__ unsigned short int __constant_ntohs(unsigned short int);
extern __inline__ unsigned long int
__ntohl(unsigned long int x)
{
__asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
"rorl $16,%0\n\t" /* swap words */
"xchgb %b0,%h0" /* swap higher bytes */
:"=q" (x)
: "0" (x));
return x;
}
#define __constant_ntohl(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)))
extern __inline__ unsigned short int
__ntohs(unsigned short int x)
{
__asm__("xchgb %b0,%h0" /* swap bytes */
: "=q" (x)
: "0" (x));
return x;
}
#define __constant_ntohs(x) \
((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
(((unsigned short int)(x) & 0xff00) >> 8))) \
#define __htonl(x) __ntohl(x)
#define __htons(x) __ntohs(x)
#define __constant_htonl(x) __constant_ntohl(x)
#define __constant_htons(x) __constant_ntohs(x)
#ifdef __OPTIMIZE__
# define ntohl(x) \
(__builtin_constant_p((long)(x)) ? \
__constant_ntohl((x)) : \
__ntohl((x)))
# define ntohs(x) \
(__builtin_constant_p((short)(x)) ? \
__constant_ntohs((x)) : \
__ntohs((x)))
# define htonl(x) \
(__builtin_constant_p((long)(x)) ? \
__constant_htonl((x)) : \
__htonl((x)))
# define htons(x) \
(__builtin_constant_p((short)(x)) ? \
__constant_htons((x)) : \
__htons((x)))
#endif
#endif

143
netboot/cards.h Normal file
View file

@ -0,0 +1,143 @@
#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_3C90X
extern struct nic *a3c90x_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_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_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
#endif /* CARDS_H */

View file

@ -17,27 +17,28 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Based on "src/config.c" in etherboot-4.4.2. Some parts are stolen
from "include/linux/pci.h" in linux-2.2.14. */
/* Based on "src/config.c" in etherboot-4.5.8. */
/*
* 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 "netboot_config.h"
struct pci_device; /* for the probe prototype */
#undef INCLUDE_PCI
#if defined(INCLUDE_NEPCI) || defined(INCLUDE_EEPRO100) || defined(INCLUDE_LANCEPCI) || defined(INCLUDE_EPIC100) || defined(INCLUDE_TULIP) || defined(INCLUDE_NTULIP) || defined(INCLUDE_3C90X) || defined(INCLUDE_RTL8139) || defined(INCLUDE_VIA_RHINE) || defined(INCLUDE_3C59X)
#if defined(INCLUDE_NS8390) || defined(INCLUDE_EEPRO100) || defined(INCLUDE_LANCE) || defined(INCLUDE_EPIC100) || defined(INCLUDE_TULIP) || defined(INCLUDE_OTULIP) || defined(INCLUDE_3C90X) || defined(INCLUDE_RTL8139) || defined(INCLUDE_VIA_RHINE)
/* || others later */
#if defined(ETHERBOOT32) /* only for 32 bit machines */
#define INCLUDE_PCI
/*#include <linux/pci.h>*/
#include "pci.h"
static unsigned short pci_ioaddrs[16];
static struct pci_device pci_nic_list[] = {
#ifdef INCLUDE_NEPCI
#ifdef INCLUDE_NS8390
{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8029,
"Realtek 8029", 0, 0, 0},
{ PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940,
@ -85,7 +86,7 @@ static struct pci_device pci_nic_list[] = {
{ PCI_VENDOR_ID_SMC, PCI_DEVICE_ID_SMC_EPIC100,
"SMC EtherPowerII", 0, 0, 0},
#endif
#ifdef INCLUDE_LANCEPCI
#ifdef INCLUDE_LANCE
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE,
"AMD Lance/PCI", 0, 0, 0},
#endif
@ -95,7 +96,7 @@ static struct pci_device pci_nic_list[] = {
{ PCI_VENDOR_ID_SMC_1211, PCI_DEVICE_ID_SMC_1211,
"SMC EZ10/100", 0, 0, 0},
#endif
#ifdef INCLUDE_TULIP
#ifdef INCLUDE_OTULIP
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP,
"Digital Tulip", 0, 0, 0},
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
@ -105,7 +106,7 @@ static struct pci_device pci_nic_list[] = {
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
"Digital Tulip 21142", 0, 0, 0},
#endif
#ifdef INCLUDE_NTULIP
#ifdef INCLUDE_TULIP
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP,
"Digital Tulip", 0, 0, 0},
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
@ -127,157 +128,27 @@ static struct pci_device pci_nic_list[] = {
{ PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_86C100A,
"VIA 86C100A", 0, 0, 0},
#endif
#ifdef INCLUDE_3C59X
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C590,
"3c590 Vortex 10Mbps", 0, 0, 0},
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595TX,
"3c595 Vortex 100baseTX", 0, 0, 0},
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595T4,
"3c595 Vortex 100baseT4", 0, 0, 0},
{ PCI_VENDOR_ID_3COM, PCI_DEVIVE_ID_3COM_3C595MII,
"3c595 Vortex 100base-MII", 0, 0, 0},
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900TPO,
"3c900 Boomerang 10baseT", 0, 0, 0},
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900COMBO,
"3c900 Boomerang 10Mbps/Combo", 0, 0, 0},
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905TX,
"3c905 Boomerang 100baseTx", 0, 0, 0},
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905T4,
"3c905 Boomerang 100baseT4", 0, 0, 0},
#endif
/* other PCI NICs go here */
{0,}
{0, 0, NULL, 0, 0, 0}
};
#endif /* ETHERBOOT32 */
#endif /* INCLUDE_*PCI */
#include "cards.h"
struct dispatch_table
{
char *nic_name;
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 */
};
#ifdef INCLUDE_WD
extern struct nic *wd_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_3C503
extern struct nic *t503_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_VIA_RHINE
extern struct nic *rhine_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_NE
extern struct nic *ne_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_NEPCI
extern struct nic *nepci_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_3C509
extern struct nic *t509_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_3C529
extern struct nic *t529_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_3C90X
extern struct nic *a3c90x_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_EEPRO100
extern struct nic *eepro100_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_EPIC100
extern struct nic *epic100_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_TULIP
extern struct nic *tulip_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_NTULIP
extern struct nic *ntulip_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_CS89x0
extern struct nic *cs89x0_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_LANCEPCI
extern struct nic *lancepci_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_NE2100
extern struct nic *ne2100_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_NI6510
extern struct nic *ni6510_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_SK_G16
extern struct nic *SK_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_3C507
extern struct nic *t507_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_NI5210
extern struct nic *ni5210_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_EXOS205
extern struct nic *exos205_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_SMC9000
extern struct nic *smc9000_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_TIARA
extern struct nic *tiara_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_RTL8139
extern struct nic *rtl8139_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
#ifdef INCLUDE_3C59X
extern struct nic *VX_probe(struct nic *, unsigned short *,
struct pci_device *);
#endif
/*
* NIC probing is in order of appearance in this table.
* If for some reason you want to change the order,
@ -312,13 +183,13 @@ static struct dispatch_table NIC[] =
#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_NTULIP
{ "NTulip", ntulip_probe, pci_ioaddrs },
#endif
#ifdef INCLUDE_CS89x0
#ifdef INCLUDE_CS89X0
{ "CS89x0", cs89x0_probe, 0 },
#endif
#ifdef INCLUDE_NE2100
@ -345,17 +216,17 @@ static struct dispatch_table NIC[] =
#ifdef INCLUDE_TIARA
{ "TIARA", tiara_probe, 0 },
#endif
#ifdef INCLUDE_NEPCI
#ifdef INCLUDE_DEPCA
{ "DEPCA", depca_probe, 0 },
#endif
#ifdef INCLUDE_NS8390
{ "NE2000/PCI", nepci_probe, pci_ioaddrs },
#endif
#ifdef INCLUDE_LANCEPCI
#ifdef INCLUDE_LANCE
{ "LANCE/PCI", lancepci_probe, pci_ioaddrs },
#endif
#ifdef INCLUDE_VIA_RHINE
{ "VIA 86C100", rhine_probe, pci_ioaddrs },
#endif
#ifdef INCLUDE_3C59X
{ "VorTex/PCI", VX_probe, pci_ioaddrs },
#endif
/* this entry must always be last to mark the end of list */
{ 0, 0, 0 }
@ -368,16 +239,16 @@ static int eth_dummy(struct nic *nic)
return (0);
}
char packet[ETH_MAX_PACKET];
static char packet[ETH_MAX_PACKET];
struct nic nic =
{
#ifdef ETHERBOOT32
(void (*)(struct nic *))eth_dummy, /* reset */
eth_dummy, /* poll */
(void (*)(struct nic *, char *,
(void (*)(struct nic *, const char *,
unsigned int, unsigned int,
char *))eth_dummy, /* transmit */
const char *))eth_dummy, /* transmit */
(void (*)(struct nic *))eth_dummy, /* disable */
#endif
/* bcc has problems with complicated casts */
@ -398,7 +269,7 @@ struct nic nic =
0 /* priv_data */
};
#if 0
#ifndef GRUB
void print_config(void)
{
struct dispatch_table *t;
@ -414,7 +285,7 @@ void print_config(void)
printf("[%s]", t->nic_name);
putchar('\n');
}
#endif
#endif /* ! GRUB */
void eth_reset(void)
{
@ -425,8 +296,11 @@ int eth_probe(void)
{
struct pci_device *p;
struct dispatch_table *t;
#ifdef GRUB
static int probed = 0;
#endif /* GRUB */
#ifdef GRUB
/* If already probed, don't try to probe it any longer. */
if (probed)
return 1;
@ -436,11 +310,15 @@ int eth_probe(void)
/* Clear the ARP table. */
grub_memset ((char *) arptable, 0,
MAX_ARP * sizeof (struct arptable_t));
#endif /* GRUB */
p = 0;
#ifdef INCLUDE_PCI
# ifdef GRUB
/* In GRUB, the ROM info is initialized here. */
rom = *((struct rom_info *) ROM_INFO_LOCATION);
# endif /* GRUB */
eth_pci_init(pci_nic_list);
pci_ioaddrs[0] = 0;
@ -458,9 +336,14 @@ int eth_probe(void)
for (t = NIC; t->nic_name != 0; ++t)
{
printf("[%s]", t->nic_name);
if ((*t->eth_probe)(&nic, t->probe_ioaddrs, p))
{
#ifdef INCLUDE_PCI
if ((*t->eth_probe)(&nic, t->probe_ioaddrs, p)) {
#else
if ((*t->eth_probe)(&nic, t->probe_ioaddrs)) {
#endif /* INCLUDE_PCI */
#ifdef GRUB
probed = 1;
#endif /* GRUB */
return (1);
}
}
@ -472,7 +355,7 @@ int eth_poll(void)
return ((*nic.poll)(&nic));
}
void eth_transmit(char *d, unsigned int t, unsigned int s, char *p)
void eth_transmit(const char *d, unsigned int t, unsigned int s, const void *p)
{
(*nic.transmit)(&nic, d, t, s, p);
twiddle();

View file

@ -65,6 +65,7 @@
#include "etherboot.h"
#include "nic.h"
#include "cards.h"
#include "cs89x0.h"
static unsigned short eth_nic_base;
@ -80,16 +81,13 @@ static unsigned char eth_vendor;
CS89x0 - specific routines
**************************************************************************/
static int inline readreg(portno)
int portno;
static inline int readreg(int portno)
{
outw(portno, eth_nic_base + ADD_PORT);
return inw(eth_nic_base + DATA_PORT);
}
static void inline writereg(portno,value)
int portno;
int value;
static inline void writereg(int portno, int value)
{
outw(portno, eth_nic_base + ADD_PORT);
outw(value, eth_nic_base + DATA_PORT);
@ -100,27 +98,24 @@ static void inline writereg(portno,value)
EEPROM access
**************************************************************************/
static int wait_eeprom_ready()
static int wait_eeprom_ready(void)
{
long tmo = currticks() + 4*TICKS_PER_SEC;
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 >= 0)
if (currticks() >= tmo)
return -1; }
return 0;
}
static int get_eeprom_data(off,len,buffer)
int off;
int len;
unsigned short *buffer;
static int get_eeprom_data(int off, int len, unsigned short *buffer)
{
int i;
#if defined(EDEBUG)
#ifdef EDEBUG
printf("\ncs: EEPROM data from %x for %x:",off,len);
#endif
for (i = 0; i < len; i++) {
@ -132,23 +127,20 @@ static int get_eeprom_data(off,len,buffer)
if (wait_eeprom_ready() < 0)
return -1;
buffer[i] = readreg(PP_EEData);
#if defined(EDEBUG)
#ifdef EDEBUG
if (!(i%10))
printf("\ncs: ");
printf("%x ", buffer[i]);
#endif
}
#if defined(EDEBUG)
#ifdef EDEBUG
putchar('\n');
#endif
return(0);
}
static int get_eeprom_chksum(off, len, buffer)
int off;
int len;
unsigned short *buffer;
static int get_eeprom_chksum(int off, int len, unsigned short *buffer)
{
int i, cksum;
@ -165,7 +157,7 @@ static int get_eeprom_chksum(off, len, buffer)
Activate all of the available media and probe for network
**************************************************************************/
static void clrline()
static void clrline(void)
{
int i;
@ -175,11 +167,10 @@ static void clrline()
return;
}
static void control_dc_dc(on_not_off)
int on_not_off;
static void control_dc_dc(int on_not_off)
{
unsigned int selfcontrol;
long tmo = currticks() + TICKS_PER_SEC;
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 */
@ -190,14 +181,14 @@ static void control_dc_dc(on_not_off)
writereg(PP_SelfCTL, selfcontrol);
/* Wait for the DC/DC converter to power up - 1000ms */
while (currticks() - tmo < 0);
while (currticks() < tmo);
return;
}
static int detect_tp()
static int detect_tp(void)
{
long tmo;
unsigned long tmo;
/* Turn on the chip auto detection of 10BT/ AUI */
@ -214,7 +205,7 @@ static int detect_tp()
/* Delay for the hardware to work out if the TP cable is
present - 150ms */
for (tmo = currticks() + 4; currticks() - tmo < 0; );
for (tmo = currticks() + 4; currticks() < tmo; );
if ((readreg(PP_LineST) & LINK_OK) == 0)
return 0;
@ -248,7 +239,7 @@ static int send_test_pkt(struct nic *nic)
0, 46, /*A 46 in network order */
0, 0, /*DSAP=0 & SSAP=0 fields */
0xf3,0 /*Control (Test Req+P bit set)*/ };
long tmo;
unsigned long tmo;
writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_TX_ON);
@ -261,7 +252,7 @@ static int send_test_pkt(struct nic *nic)
/* 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 >= 0)
if (currticks() >= tmo)
return(0);
/* Write the contents of the packet */
@ -270,7 +261,7 @@ static int send_test_pkt(struct nic *nic)
printf(" sending test packet ");
/* wait a couple of timer ticks for packet to be received */
for (tmo = currticks() + 2; currticks() - tmo < 0; );
for (tmo = currticks() + 2; currticks() < tmo; );
if ((readreg(PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) {
printf("succeeded");
@ -311,10 +302,10 @@ static int detect_bnc(struct nic *nic)
ETH_RESET - Reset adapter
***************************************************************************/
void cs89x0_reset(struct nic *nic)
static void cs89x0_reset(struct nic *nic)
{
int i;
long reset_tmo;
unsigned long reset_tmo;
if(eth_vendor!=VENDOR_CS89x0)
return;
@ -322,8 +313,7 @@ void cs89x0_reset(struct nic *nic)
writereg(PP_SelfCTL, readreg(PP_SelfCTL) | POWER_ON_RESET);
/* wait for two ticks; that is 2*55ms */
for (reset_tmo = currticks() + 2;
reset_tmo > currticks(); );
for (reset_tmo = currticks() + 2; currticks() < reset_tmo; );
if (eth_cs_type != CS8900) {
/* Hardware problem requires PNP registers to be reconfigured
@ -341,7 +331,7 @@ void cs89x0_reset(struct nic *nic)
/* Wait until the chip is reset */
for (reset_tmo = currticks() + 2;
(readreg(PP_SelfST) & INIT_DONE) == 0 &&
currticks() - reset_tmo < 0; );
currticks() < reset_tmo; );
/* disable interrupts and memory accesses */
writereg(PP_BusCTL, 0);
@ -376,12 +366,12 @@ ETH_TRANSMIT - Transmit a frame
static void cs89x0_transmit(
struct nic *nic,
char *d, /* Destination */
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
char *p) /* Packet */
const char *p) /* Packet */
{
long tmo;
unsigned long tmo;
int sr;
if(eth_vendor!=VENDOR_CS89x0)
@ -401,7 +391,7 @@ retry:
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 < 0; );
for (tmo = currticks() + 5*TICKS_PER_SEC; currticks() < tmo; );
cs89x0_reset(nic);
goto retry; }
@ -416,8 +406,8 @@ retry:
/* wait for transfer to succeed */
for (tmo = currticks()+5*TICKS_PER_SEC;
(s = readreg(PP_TxEvent)&~0x1F) == 0 && currticks() - tmo < 0;
twiddle());
(s = readreg(PP_TxEvent)&~0x1F) == 0 && currticks() < tmo;)
/* nothing */ ;
if ((s & TX_SEND_OK_BITS) != TX_OK) {
printf("\ntransmission error 0x%x\n", s);
}

26
netboot/cs89x0.txt Normal file
View file

@ -0,0 +1,26 @@
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.

698
netboot/depca.c Normal file
View file

@ -0,0 +1,698 @@
/* 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 */
/*
** EISA configuration Register (CNFG) bit definitions
*/
#define TIMEO 0x0100 /* 0:2.5 mins, 1: 30 secs */
#define REMOTE 0x0080 /* Remote Boot Enable -> 1 */
#define IRQ11 0x0040 /* Enable -> 1 */
#define IRQ10 0x0020 /* Enable -> 1 */
#define IRQ9 0x0010 /* Enable -> 1 */
#define IRQ5 0x0008 /* Enable -> 1 */
#define BUFF 0x0004 /* 0: 64kB or 128kB, 1: 32kB */
#define PADR16 0x0002 /* RAM on 64kB boundary */
#define PADR17 0x0001 /* RAM on 128kB boundary */
/*
** Miscellaneous
*/
#define HASH_TABLE_LEN 64 /* Bits */
#define HASH_BITS 0x003f /* 6 LS bits */
#define MASK_INTERRUPTS 1
#define UNMASK_INTERRUPTS 0
#define EISA_EN 0x0001 /* Enable EISA bus buffers */
#define EISA_ID iobase+0x0080 /* ID long word for EISA card */
#define EISA_CTRL iobase+0x0084 /* Control word for EISA card */
/*
** Recognised commands for the driver
*/
#define DEPCA_GET_HWADDR 0x01 /* Get the hardware address */
#define DEPCA_SET_HWADDR 0x02 /* Get the hardware address */
#define DEPCA_SET_PROM 0x03 /* Set Promiscuous Mode */
#define DEPCA_CLR_PROM 0x04 /* Clear Promiscuous Mode */
#define DEPCA_SAY_BOO 0x05 /* Say "Boo!" to the kernel log file */
#define DEPCA_GET_MCA 0x06 /* Get a multicast address */
#define DEPCA_SET_MCA 0x07 /* Set a multicast address */
#define DEPCA_CLR_MCA 0x08 /* Clear a multicast address */
#define DEPCA_MCA_EN 0x09 /* Enable a multicast address group */
#define DEPCA_GET_STATS 0x0a /* Get the driver statistics */
#define DEPCA_CLR_STATS 0x0b /* Zero out the driver statistics */
#define DEPCA_GET_REG 0x0c /* Get the Register contents */
#define DEPCA_SET_REG 0x0d /* Set the Register contents */
#define DEPCA_DUMP 0x0f /* Dump the DEPCA Status */
#ifdef DEPCA_DEBUG
static int depca_debug = DEPCA_DEBUG;
#else
static int depca_debug = 1;
#endif
#define DEPCA_NDA 0xffe0 /* No Device Address */
/*
** Ethernet PROM defines
*/
#define PROBE_LENGTH 32
#define ETH_PROM_SIG 0xAA5500FFUL
/*
** 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 8 /* Number of RX descriptors */
#define NUM_TX_DESC 8 /* 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 */
#define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */
#define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */
/*
** EISA bus defines
*/
#define DEPCA_EISA_IO_PORTS 0x0c00 /* I/O port base address, slot 0 */
#define MAX_EISA_SLOTS 16
#define EISA_SLOT_INC 0x1000
/*
** ISA Bus defines
*/
#define DEPCA_RAM_BASE_ADDRESSES {0xc0000,0xd0000,0xe0000,0x00000}
#define DEPCA_IO_PORTS {0x300, 0x200, 0}
#define DEPCA_TOTAL_SIZE 0x10
static short mem_chkd = 0;
/*
** Adapter ID for the MCA EtherWORKS DE210/212 adapter
*/
#define DE212_ID 0x6def
/*
** Name <-> Adapter mapping
*/
#define DEPCA_SIGNATURE {"DEPCA",\
"DE100","DE101",\
"DE200","DE201","DE202",\
"DE210","DE212",\
"DE422",\
""}
static enum {
DEPCA, de100, de101, de200, de201, de202, de210, de212, de422, unknown
} adapter;
/*
** Miscellaneous info...
*/
#define DEPCA_STRLEN 16
#define MAX_NUM_DEPCAS 2
/*
** 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 ((u_long)4 - 1) /* 1 longword align */
#define ALIGN8 ((u_long)8 - 1) /* 2 longword (quadword) align */
#define ALIGN ALIGN8 /* Keep the LANCE happy... */
typedef long s32;
typedef unsigned long u32;
typedef unsigned long u_long;
typedef short s16;
typedef unsigned short u16;
typedef unsigned char u8;
typedef char s8;
/*
** 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[ETHER_ADDR_SIZE]; /* 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 */
};
#define DEPCA_PKT_STAT_SZ 16
#define DEPCA_PKT_BIN_SZ 128 /* Should be >=100 unless you
increase DEPCA_PKT_STAT_SZ */
struct depca_private {
char devname[DEPCA_STRLEN]; /* Device Product String */
char adapter_name[DEPCA_STRLEN];/* /proc/ioports string */
char adapter; /* Adapter type */
char mca_slot; /* MCA slot, if MCA else -1 */ struct depca_rx_desc *rx_ring; /* Pointer to start of RX descriptor ring */
struct depca_tx_desc *tx_ring; /* Pointer to start of TX descriptor ring */
struct depca_init init_block;/* Shadow Initialization block */
char *rx_memcpy[NUM_RX_DESC]; /* CPU virt address of sh'd memory buffs */
char *tx_memcpy[NUM_TX_DESC]; /* CPU virt address of sh'd memory buffs */
u_long bus_offset; /* (E)ISA bus address offset vs LANCE */
u_long sh_mem; /* Physical start addr of shared mem area */
u_long dma_buffs; /* LANCE Rx and Tx buffers start address. */
int rx_new, tx_new; /* The next free ring entry */
int rx_old, tx_old; /* The ring entries to be free()ed. */
struct { /* Private stats counters */
u32 bins[DEPCA_PKT_STAT_SZ];
u32 unicast;
u32 multicast;
u32 broadcast;
u32 excessive_collisions;
u32 tx_underruns;
u32 excessive_underruns;
} pktStats;
int txRingMask; /* TX ring mask */
int rxRingMask; /* RX ring mask */
s32 rx_rlen; /* log2(rxRingMask+1) for the descriptors */
s32 tx_rlen; /* log2(txRingMask+1) for the descriptors */
};
/*
** The transmit ring full condition is described by the tx_old and tx_new
** pointers by:
** tx_old = tx_new Empty ring
** tx_old = tx_new+1 Full ring
** tx_old+txRingMask = tx_new Full ring (wrapped condition)
*/
#define TX_BUFFS_AVAIL ((lp->tx_old<=lp->tx_new)?\
lp->tx_old+lp->txRingMask-lp->tx_new:\
lp->tx_old -lp->tx_new-1)
static char name[DEPCA_STRLEN];
static int num_depcas = 0, num_eth = 0;
static int mem=0; /* For loadable module assignment
use insmod mem=0x????? .... */
static char *adapter_name = '\0'; /* If no PROM when loadable module
use insmod adapter_name=DE??? ...
*/
static unsigned short ioaddr = 0;
/*
** Miscellaneous defines...
*/
#define STOP_DEPCA \
outw(CSR0, DEPCA_ADDR);\
outw(STOP, DEPCA_DATA)
/**************************************************************************
RESET - Reset adapter
***************************************************************************/
static void depca_reset(struct nic *nic)
{
#if 0
int i, j, offset, netRAM, mem_len, status = 0;
s16 nicsr;
Address mem_start = 0, mem_base[] = DEPCA_RAM_BASE_ADDRESSES;
/* put the card in its initial state */
STOP_DEPCA;
nicsr = inb(DEPCA_NICSR);
nicsr = ((nicsr & ~SHE & ~RBE & ~IEN( | IM);
outb(nicsr, DEPCA_NICSR);
if (inw(DEPCA_DATA) == STOP) {
do {
strcpu(name, (adapter_name ? adapter_name : ""));
mem_start = (mem ? mem & 0xf0000 : mem_base[mem_chkd++]);
DepcaSignature(name, mem_start);
} while (!mem && mem_base[mem_chkd] && (adapter == unknown));
if ((adapter != unknown) && mem_start) {
;
}
#endif
}
/**************************************************************************
POLL - Wait for a frame
***************************************************************************/
static int depca_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 */
return 0;
}
/**************************************************************************
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 */
{
/* send the packet to destination */
}
/**************************************************************************
DISABLE - Turn off ethernet interface
***************************************************************************/
static void depca_disable(struct nic *nic)
{
}
/* Return 1 if device present at ioaddr */
static int DevicePresent(void)
{
union {
struct {
u32 a;
u32 b;
} llsig;
char Sig[sizeof(u32) << 1];
} dev;
short siglength = 0;
s8 data;
s16 nicsr;
int i, j;
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);
}
dev.llsig.a = ETH_PROM_SIG;
dev.llsig.b = ETH_PROM_SIG;
siglength = sizeof(u32) << 1;
for (i = 0, j = 0; j < siglength && i < PROBE_LENGTH+siglength-1; ++i) {
data = inb(DEPCA_PROM);
if (dev.Sig[j] == data) { /* track signature */
++j;
} else {
if (data == dev.Sig[0]) { /* rare case... */
j = 1;
} else {
j = 0;
}
}
}
return (j == siglength);
}
/**************************************************************************
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[] = { 0x200, 0x300, 0 };
int i;
printf("DEPCA driver not fully functional, only probe working...\n");
if (probe_addrs == 0 || probe_addrs[0] == 0)
probe_addrs = base; /* Use defaults */
for (i = 0; (ioaddr = base[i]) != 0; ++i) {
if (DevicePresent()) {
break;
}
}
if (ioaddr != 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;
}
return 0;
}

View file

@ -36,8 +36,7 @@
* Jul 25 1997 V1.00 REW Tested by AW to work in a PROM
* Cleanup for publication
*
* This is the etherboot-3.1 compatible intel etherexpress Pro/100B
* driver.
* 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
@ -53,8 +52,9 @@
*
* Probing:
*
* Using a subset of "bios32" and "pci" functions of the linux kernel,
* the pci 82557 chip is detected.
* 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:
@ -89,11 +89,7 @@
* 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.
*
* If you run into trouble, the method used to give "pci.c" dynamic
* allocation should be used to allocate the larger variables (like
* the packet buffers)
* */
*/
/* The etherboot authors seem to dislike the argument ordering in
@ -104,6 +100,7 @@
#include "etherboot.h"
#include "nic.h"
#include "pci.h"
#include "cards.h"
#undef virt_to_bus
#define virt_to_bus(x) ((unsigned long)x)
@ -128,7 +125,7 @@ enum speedo_offsets {
};
static int read_eeprom(int ioaddr, int location);
static int read_eeprom(int location);
static void udelay (int val);
void hd (void *where, int n);
@ -210,7 +207,7 @@ static inline void wait_for_cmd_done(int cmd_ioaddr)
/* Elements of the dump_statistics block. This block must be lword aligned. */
struct speedo_stats {
static struct speedo_stats {
u32 tx_good_frames;
u32 tx_coll16_errs;
u32 tx_late_colls;
@ -232,7 +229,7 @@ struct speedo_stats {
/* A speedo3 TX buffer descriptor with two buffers... */
struct TxFD {
static struct TxFD {
volatile s16 status;
s16 command;
u32 link; /* void * */
@ -246,8 +243,6 @@ struct TxFD {
} txfd;
/* The Speedo3 Rx buffer descriptors. */
struct RxFD { /* Receive frame descriptor. */
volatile s16 status;
s16 command;
@ -256,7 +251,15 @@ struct RxFD { /* Receive frame descriptor. */
u16 count;
u16 size;
char packet[1518];
} rxfd;
};
#ifndef USE_INTERNAL_BUFFER
#define rxfd ((struct RxFD *)(0x10000 - sizeof(struct RxFD)))
#define ACCESS(x) x->
#else
static struct RxFD rxfd;
#define ACCESS(x) x.
#endif
@ -270,7 +273,7 @@ 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 */
struct ConfCmd {
static struct ConfCmd {
s16 status;
s16 command;
u32 link;
@ -288,19 +291,8 @@ struct ConfCmd {
#define TIME_OUT 1000000
/* The "pci" code needs to allocate a few structures. It wants to
* increment the "kernel memory ends here" pointer to allocate memory.
* I guess that a machine with PCI has more than 2Mb of memory, so
* that is where those things are put. Those structures don't survive
* the "jump to kernel start".
* */
#define MEM_START 0x200000 /* Memory starts at 2Mb for now.... */
#define MEM_END 0
static unsigned short eeprom [0x40];
static void calibrate_delay (void);
/***********************************************************************/
/* Locally used functions */
@ -314,7 +306,7 @@ static void calibrate_delay (void);
*/
static int mdio_write(int ioaddr, int phy_id, int location, int value)
static int mdio_write(int phy_id, int location, int value)
{
int val, boguscnt = 64*4; /* <64 usec. to complete, typ 27 ticks */
@ -337,7 +329,7 @@ static int mdio_write(int ioaddr, int phy_id, int location, int value)
* This probably reads a register in the "physical media interface chip".
* -- REW
*/
static int mdio_read(int ioaddr, int phy_id, int location)
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);
@ -355,11 +347,10 @@ static int mdio_read(int ioaddr, int phy_id, int location)
/* Support function: read_eeprom
* reads a value from the eeprom at a specified location.
* Arguments: ioaddr: address of the 82557 chip
* location: address of the location to read from the eeprom.
* Arguments: location: address of the location to read from the eeprom.
* returns: value read from eeprom at location.
*/
static int read_eeprom(int ioaddr, int location)
static int read_eeprom(int location)
{
int i;
unsigned short retval = 0;
@ -395,7 +386,7 @@ static int read_eeprom(int ioaddr, int location)
}
static void inline whereami (char *str)
static inline void whereami (const char *str)
{
#if 0
printf ("%s\n", str);
@ -425,7 +416,7 @@ static void eepro100_reset(struct nic *nic)
/* function: eepro100_transmit / eth_transmit
/* function: eepro100_transmit
* This transmits a packet.
*
* Arguments: char d[6]: destination ethernet address.
@ -435,7 +426,7 @@ static void eepro100_reset(struct nic *nic)
* returns: void.
*/
static void eepro100_transmit(struct nic *nic, char *d, unsigned int t, unsigned int s, char *p)
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[6];
@ -512,22 +503,22 @@ static int eepro100_poll(struct nic *nic)
int to;
to = TIME_OUT;
while (!rxfd.status && --to)
while (!ACCESS(rxfd)status && --to)
/* Wait */;
/* Ok. We got a packet. Now restart the reciever.... */
rxfd.status = 0;
rxfd.command = 0xc000;
outl(virt_to_bus(&rxfd), ioaddr + SCBPointer);
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);
if (to) {
#ifdef DEBUG
printf ("Got a packet: Len = %d.\n", rxfd.count & 0x3fff);
printf ("Got a packet: Len = %d.\n", ACCESS(rxfd)count & 0x3fff);
#endif
nic->packetlen = rxfd.count & 0x3fff;
memcpy (nic->packet, rxfd.packet, sizeof (rxfd.packet));
nic->packetlen = ACCESS(rxfd)count & 0x3fff;
memcpy (nic->packet, ACCESS(rxfd)packet, nic->packetlen);
#ifdef DEBUG
hd (nic->packet, 0x30);
#endif
@ -550,7 +541,6 @@ static void eepro100_disable(struct nic *nic)
struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs, struct pci_device *p)
{
int pci_index;
u16 sum = 0;
int i, j, to;
unsigned short value;
@ -569,7 +559,7 @@ struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs, struct p
/* Ok. Got one. Read the eeprom. */
for (j = 0, i = 0; i < 0x40; i++) {
value = read_eeprom(ioaddr, i);
value = read_eeprom(i);
eeprom[i] = value;
sum += value;
}
@ -628,23 +618,23 @@ struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs, struct p
whereami ("set rx base addr.");
rxfd.status = 0x0001;
rxfd.command = 0x0000;
rxfd.link = virt_to_bus(&rxfd);
rxfd.rx_buf_addr = (int) &nic->packet;
rxfd.count = 0;
rxfd.size = 1528;
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(&rxfd), ioaddr + SCBPointer);
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.... */
rxfd.status = 0;
rxfd.command = 0xc000;
outl(virt_to_bus(&rxfd), ioaddr + SCBPointer);
ACCESS(rxfd)status = 0;
ACCESS(rxfd)command = 0xc000;
outl(virt_to_bus(&(ACCESS(rxfd)status)), ioaddr + SCBPointer);
outw(INT_MASK | RX_START, ioaddr + SCBCmd);
@ -662,10 +652,10 @@ struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs, struct p
txfd.link = virt_to_bus (&confcmd);
{
char *p = (char *)&txfd.tx_desc_addr;
char *t = (char *)&txfd.tx_desc_addr;
for (i=0;i<6;i++)
p[i] = nic->node_addr[i];
t[i] = nic->node_addr[i];
}
#ifdef DEBUG
@ -680,16 +670,16 @@ struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs, struct p
printf ("eeprom[6] = %x \n", eeprom[6]);
if ( ((eeprom[6]>>8) & 0x3f) == DP83840
|| ((eeprom[6]>>8) & 0x3f) == DP83840A) {
int mdi_reg23 = mdio_read(ioaddr, eeprom[6] & 0x1f, 23) | 0x0422;
int mdi_reg23 = mdio_read(eeprom[6] & 0x1f, 23) | 0x0422;
if (congenb)
mdi_reg23 |= 0x0100;
printf(" DP83840 specific setup, setting register 23 to %x.\n",
mdi_reg23);
mdio_write(ioaddr, eeprom[6] & 0x1f, 23, mdi_reg23);
mdio_write(eeprom[6] & 0x1f, 23, mdi_reg23);
}
whereami ("Done DP8340 special setup.");
if (options != 0) {
mdio_write(ioaddr, eeprom[6] & 0x1f, 0,
mdio_write(eeprom[6] & 0x1f, 0,
((options & 0x20) ? 0x2000 : 0) | /* 100mbps? */
((options & 0x10) ? 0x0100 : 0)); /* Full duplex? */
whereami ("set mdio_register.");
@ -725,8 +715,7 @@ struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs, struct p
return nic;
}
static int loops_per_sec;
static int loops_per_usec;
static int loops_per_usec = 300; /* totally bogus value */
static void udelay (int val)
{
@ -737,76 +726,6 @@ static void udelay (int val)
}
}
#if 1
/* I don't have the possibility to test the below code. Murphey tells me
* it won't work.
*/
static void calibrate_delay (void)
{
loops_per_usec = 500;
}
#else
#define __delay udelay
#define jiffies currticks()
#define HZ 18
#define LPS_PREC 8
/* Copied from /usr/src/linux/init/main.c */
/* with just a few modifications. */
void calibrate_delay (void)
{
int ticks;
int loopbit;
int lps_precision = LPS_PREC;
loops_per_sec = (1<<12);
loops_per_usec = 1;
printk("Calibrating delay loop.. ");
while (loops_per_sec <<= 1) {
/* wait for "start of" clock tick */
ticks = jiffies;
while (ticks == jiffies)
/* nothing */;
/* Go .. */
ticks = jiffies;
__delay(loops_per_sec);
ticks = jiffies - ticks;
if (ticks)
break;
}
/* Do a binary approximation to get loops_per_second set to equal one clock
(up to lps_precision bits) */
loops_per_sec >>= 1;
loopbit = loops_per_sec;
while ( lps_precision-- && (loopbit >>= 1) ) {
loops_per_sec |= loopbit;
ticks = jiffies;
while (ticks == jiffies);
ticks = jiffies;
__delay(loops_per_sec);
if (jiffies != ticks) /* longer than 1 tick */
loops_per_sec &= ~loopbit;
}
/* finally, adjust loops per second in terms of seconds instead of clocks */
loops_per_sec *= HZ;
/* Round the value and print it */
printk("ok - %d.%d BogoMIPS\n",
(loops_per_sec+25000)/500000,
((loops_per_sec+25000)/50000) % 10);
loops_per_usec = loops_per_sec / 1000000;
}
#endif
/*********************************************************************/
#ifdef DEBUG

View file

@ -1,10 +1,10 @@
/* epic100.c: A SMC 83c170 EPIC/100 fast ethernet driver for EtherBoot 4.0 */
/* epic100.c: A SMC 83c170 EPIC/100 fast ethernet driver for Etherboot */
#define LINUX_OUT_MACROS
#include "etherboot.h"
#include "nic.h"
/*#include <linux/pci.h>*/
#include "cards.h"
#include "epic100.h"
#undef virt_to_bus
@ -23,7 +23,7 @@
#define DEBUG_EEPROM
*/
static int epic_debug = 0; /* debug level */
#define EPIC_DEBUG 0 /* debug level */
/* The EPIC100 Rx and Tx buffer descriptors. */
struct epic_rx_desc {
@ -50,12 +50,12 @@ struct epic_tx_desc {
#define delay(nanosec) do { int _i = 3; while (--_i > 0) \
{ __SLOW_DOWN_IO; }} while (0)
static void epic100_open();
static void epic100_init_ring();
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, char *destaddr,
unsigned int type, unsigned int len, char *data);
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);
@ -80,11 +80,16 @@ static unsigned int cur_rx, cur_tx; /* The next free ring entry */
#ifdef DEBUG_EEPROM
static unsigned short eeprom[64];
#endif
signed char phys[4]; /* MII device addresses. */
struct epic_rx_desc rx_ring[RX_RING_SIZE];
struct epic_tx_desc tx_ring[TX_RING_SIZE];
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];
#ifndef USE_INTERNAL_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 */
@ -102,9 +107,9 @@ epic100_probe(struct nic *nic, unsigned short *probeaddrs)
{
unsigned short sum = 0;
unsigned short value;
int i, j;
int i;
unsigned short* ap;
int phy, phy_idx;
unsigned int phy, phy_idx;
if (probeaddrs == 0 || probeaddrs[0] == 0)
return 0;
@ -162,12 +167,12 @@ epic100_probe(struct nic *nic, unsigned short *probeaddrs)
sum += value;
}
if (epic_debug > 1) {
#if (EPIC_DEBUG > 1)
printf("EEPROM contents\n");
for (i = 0; i < 64; i++) {
printf(" %02x%s", eeprom[i], i % 16 == 15 ? "\n" : "");
}
}
#endif
#endif
/* This could also be read from the EEPROM. */
@ -186,15 +191,15 @@ epic100_probe(struct nic *nic, unsigned short *probeaddrs)
if (mii_status != 0xffff && mii_status != 0x0000) {
phys[phy_idx++] = phy;
if (epic_debug > 1) {
#if (EPIC_DEBUG > 1)
printf("MII transceiver found at address %d.\n", phy);
}
#endif
}
}
if (phy_idx == 0) {
if (epic_debug > 1) {
#if (EPIC_DEBUG > 1)
printf("***WARNING***: No MII transceiver found!\n");
}
#endif
/* Use the known PHY address of the EPII. */
phys[0] = 3;
}
@ -212,7 +217,6 @@ epic100_probe(struct nic *nic, unsigned short *probeaddrs)
static void
epic100_open()
{
int i;
int mii_reg5;
int full_duplex = 0;
unsigned long tmp;
@ -240,8 +244,8 @@ epic100_open()
outl(virt_to_bus(&rx_ring), prcdar);
outl(virt_to_bus(&tx_ring), ptcdar);
/* Start the chip's Rx process: Don't receive broadcast */
outl(0, rxcon);
/* Start the chip's Rx process: receive unicast and broadcast */
outl(0x04, rxcon);
outl(CR_START_RX | CR_QUEUE_RX, command);
putchar('\n');
@ -282,7 +286,7 @@ epic100_init_ring()
tx_ring[i-1].next = virt_to_bus(&tx_ring[0]);
}
/* function: epic100_transmit / eth_transmit
/* function: epic100_transmit
* This transmits a packet.
*
* Arguments: char d[6]: destination ethernet address.
@ -292,8 +296,8 @@ epic100_init_ring()
* returns: void.
*/
static void
epic100_transmit(struct nic *nic, char *destaddr, unsigned int type,
unsigned int len, char *data)
epic100_transmit(struct nic *nic, const char *destaddr, unsigned int type,
unsigned int len, const char *data)
{
unsigned short nstype;
unsigned short status;
@ -397,8 +401,9 @@ epic100_poll(struct nic *nic)
/* We own the next entry, it's a new packet. Send it up. */
if (epic_debug > 4)
#if (EPIC_DEBUG > 4)
printf("epic_poll: entry %d status %8x\n", entry, status);
#endif
if (status & 0x2000) {
printf("epic_poll: Giant packet\n");

View file

@ -6,13 +6,31 @@ Author: Martin Renters
**************************************************************************/
/* Enable GRUB-specific stuff. */
#define GRUB 1
#ifdef GRUB
/* Include GRUB-specific macros and prototypes here. */
#include <shared.h>
# 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
# 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
/* Force to use the internal buffer. */
# define INTERNAL_BOOTP_DATA 1
/* Likewise. */
# define USE_INTERNAL_BUFFER 1
/* FIXME: Should be an option. */
# define BACKOFF_LIMIT 7
#endif /* GRUB */
#include "osdep.h"
@ -29,16 +47,47 @@ Author: Martin Renters
#define TAGGED_IMAGE /* choose at least one */
#endif
#if 0
# define ESC 0x1B
#else
#ifdef GRUB
# define CTRL_C 3
#endif
#else /* ! GRUB */
# define ESC 0x1B
#endif /* ! GRUB */
#ifndef DEFAULT_BOOTFILE
#define DEFAULT_BOOTFILE "/tftpboot/kernel"
#endif
/* Clean up console settings... mainly CONSOLE_CRT and CONSOLE_SERIAL are used
* in the sources (except start.S and serial.S which cannot include
* etherboot.h). At least one of the CONSOLE_xxx has to be set, and
* CONSOLE_DUAL sets both CONSOLE_CRT and CONSOLE_SERIAL. If none is set,
* CONSOLE_CRT is assumed. */
#ifdef CONSOLE_DUAL
#undef CONSOLE_CRT
#define CONSOLE_CRT
#undef CONSOLE_SERIAL
#define CONSOLE_SERIAL
#endif
#if defined(CONSOLE_CRT) && defined(CONSOLE_SERIAL)
#undef CONSOLE_DUAL
#define CONSOLE_DUAL
#endif
#if !defined(CONSOLE_CRT) && !defined(CONSOLE_SERIAL)
#define CONSOLE_CRT
#endif
#ifndef DOWNLOAD_PROTO_NFS
#undef DOWNLOAD_PROTO_TFTP
#define DOWNLOAD_PROTO_TFTP /* default booting protocol */
#endif
#ifdef DOWNLOAD_PROTO_TFTP
#define download(fname,loader) tftp((fname),(loader))
#endif
#ifdef DOWNLOAD_PROTO_NFS
#define download(fname,loader) nfs((fname),(loader))
#endif
#ifndef MAX_TFTP_RETRIES
#define MAX_TFTP_RETRIES 20
#endif
@ -48,11 +97,17 @@ Author: Martin Renters
#endif
#ifndef MAX_BOOTP_EXTLEN
#if defined(INTERNAL_BOOTP_DATA) || (RELOC >= 0x94200)
#if (RELOC < 0x94000)
/* Force internal buffer (if external buffer would overlap with our code...) */
#undef INTERNAL_BOOTP_DATA
#define INTERNAL_BOOTP_DATA
#endif
/* sizeof(struct bootp_t) == 0x240 */
#if defined(INTERNAL_BOOTP_DATA) || (RELOC >= 0x94240)
#define MAX_BOOTP_EXTLEN 1024
#else
#define MAX_BOOTP_EXTLEN (1024-sizeof(struct bootp_t))
#endif /* INTERNAL_BOOTP_DATA || RELOC > 0x94200 */
#endif
#endif
#ifndef MAX_ARP_RETRIES
@ -113,7 +168,8 @@ Author: Martin Renters
#define BOOTP_SERVER 67
#define BOOTP_CLIENT 68
#define TFTP 69
#define TFTP_PORT 69
#define SUNRPC_PORT 111
#define IP_UDP 17
/* Same after going through htonl */
@ -195,7 +251,9 @@ Author: Martin Renters
#define RFC1533_VENDOR_MAGIC 128
#define RFC1533_VENDOR_ADDPARM 129
#define RFC1533_VENDOR_HOWTO 132 /* used by FreeBSD */
#ifdef IMAGE_FREEBSD
#define RFC1533_VENDOR_HOWTO 132
#endif
#define RFC1533_VENDOR_MNUOPTS 160
#define RFC1533_VENDOR_SELECTION 176
#define RFC1533_VENDOR_MOTD 184
@ -229,6 +287,8 @@ Author: Martin Renters
#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;
@ -329,6 +389,60 @@ struct tftp_t {
#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
#define ROM_INFO_LOCATION 0x7dfa
/* at end of floppy boot block */
@ -338,30 +452,45 @@ struct rom_info {
};
/***************************************************************************
extern int rarp P((void));
External prototypes
***************************************************************************/
/* main.c */
extern void print_network_configuration (void);
#ifdef GRUB
extern void print_network_configuration P((void));
#endif /* GRUB */
#if 0
#ifndef GRUB
extern void print_bytes P((unsigned char *bytes, int len));
extern void load P((void));
extern int load_linux P((int root_mount_port,int swap_mount_port,
int root_nfs_port,char *kernel_handle));
extern int tftpkernel P((unsigned char *, int, int, int));
extern int downloadkernel P((unsigned char *, int, int, int));
extern int tftp P((char *name, int (*)(unsigned char *, int, int, int)));
#endif
extern void rpc_init(void);
extern int nfs P((const char *name, int (*)(unsigned char *, int, int, int)));
extern void nfs_umountall P((int));
#endif /* ! GRUB */
extern int bootp P((void));
extern int rarp P((void));
extern int udp_transmit P((unsigned long destip, unsigned int srcsock,
unsigned int destsock, int len, char *buf));
extern int await_reply P((int type, int ival, char *ptr, int timeout));
unsigned int destsock, int len, const void *buf));
extern int await_reply P((int type, int ival, void *ptr, int timeout));
extern int decode_rfc1533 P((unsigned char *, int, int, int));
extern unsigned short ipchksum P((unsigned short *, int len));
extern void rfc951_sleep P((int));
extern void cleanup_net P((void));
extern void cleanup P((void));
#if 0
/* 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);
#ifndef GRUB
/* bootmenu.c */
extern int execute P((char *string));
extern void bootmenu P((int));
@ -374,24 +503,25 @@ extern void selectImage P((char **));
#if defined(AOUT_IMAGE) || defined(ELF_IMAGE)
extern int howto;
#endif
extern int os_tftp P((unsigned int block,unsigned char *data,int len));
#endif
extern int os_download P((unsigned int, unsigned char *,unsigned int));
#endif /* ! GRUB */
/* misc.c */
extern void twiddle P((void));
extern void sleep P((int secs));
#if 0
#ifndef GRUB
extern int strcasecmp P((char *a, char *b));
extern char *substr P((char *a, char *b));
#endif
#endif /* ! GRUB */
extern int getdec P((char **));
#if 0
extern void printf(); /* old style to avoid varargs */
extern char *sprintf();
extern int inet_ntoa P((char *p, in_addr *i));
extern void gateA20 P((void));
#ifndef GRUB
extern void printf P((const char *, ...));
extern char *sprintf P((char *, const char *, ...));
extern int inet_aton P((char *p, in_addr *i));
extern void gateA20_set P((void));
extern void gateA20_unset P((void));
extern void putchar P((int));
extern int getchar ();
extern int getchar P((void));
extern int iskey P((void));
/* start*.S */
@ -399,24 +529,27 @@ extern int getc P((void));
extern void putc P((int));
extern int ischar P((void));
extern int getshift P((void));
extern unsigned short memsize P((void));
extern unsigned int memsize P((void));
extern unsigned short basememsize P((void));
extern void disk_init P((void));
extern unsigned int disk_read P((int drv,int c,int h,int s,char *buf));
extern void xstart P((unsigned long, unsigned long, char *));
extern long currticks P((void));
extern unsigned long currticks P((void));
extern int setjmp P((void *jmpbuf));
extern void longjmp P((void *jmpbuf, int where));
extern void exit P((int status));
extern void slowdownio P((void));
/* serial.S */
extern int serial_getc P((void));
extern void serial_putc P((int));
extern int serial_ischar P((void));
extern void serial_init P((void));
extern int serial_init P((void));
/* ansiesc.c */
extern void ansi_reset P((void));
extern void enable_cursor P((int));
extern void handleansi P((unsigned char));
/* md5.c */
extern void md5_put P((unsigned int ch));
@ -424,53 +557,58 @@ extern void md5_done P((unsigned char *buf));
/* floppy.c */
extern int bootdisk P((int dev,int part));
#endif
#endif /* ! GRUB */
/***************************************************************************
External variables
***************************************************************************/
/* main.c */
#ifdef GRUB
extern int ip_abort;
extern int network_ready;
#if 0
extern char *kernel;
extern char kernel_buf[];
#endif
#endif /* GRUB */
#ifndef GRUB
extern const char *kernel;
extern char kernel_buf[128];
#endif /* ! GRUB */
extern struct rom_info rom;
#if 0
#ifndef GRUB
extern int hostnamelen;
extern unsigned long netmask;
extern int jmp_bootmenu[10];
extern char kernel_buf[128];
#endif
#endif /* ! GRUB */
extern struct arptable_t arptable[MAX_ARP];
#if 0
extern char *imagelist[RFC1533_VENDOR_NUMOFIMG];
#ifndef GRUB
#ifdef IMAGE_MENU
extern char *motd[RFC1533_VENDOR_NUMOFMOTD];
extern int menutmo,menudefault;
extern struct bootpd_t bootp_data;
extern unsigned char *defparams;
extern int defparams_max;
#endif
#ifdef ETHERBOOT32
#define INTERNAL_BOOTP_DATA 1
#ifdef INTERNAL_BOOTP_DATA
#define BOOTP_DATA_ADDR (&bootp_data)
#else
#endif /* ! GRUB */
#if defined(ETHERBOOT32) && !defined(INTERNAL_BOOTP_DATA)
#define BOOTP_DATA_ADDR ((struct bootpd_t *)0x93C00)
#endif /* INTERNAL_BOOTP_DATA */
#endif
#ifdef ETHERBOOT16
#else
extern struct bootpd_t bootp_data;
#define BOOTP_DATA_ADDR (&bootp_data)
#endif
extern unsigned char *end_of_rfc1533;
#ifdef IMAGE_FREEBSD
extern int freebsd_howto;
#endif
/* config.c */
extern struct nic nic;
/* bootmenu.c */
/* osloader.c */
#if 0
#ifndef GRUB
/* created by linker */
extern char _edata[], _end[];
#endif
extern char _start[], _edata[], _end[];
#endif /* ! GRUB */
/*
* Local variables:

View file

@ -17,7 +17,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Based on "src/main.c" in etherboot-4.4.2. */
/* Based on "src/main.c" in etherboot-4.5.8. */
/**************************************************************************
ETHERBOOT - BOOTP/TFTP Bootstrap Program
@ -32,12 +32,12 @@ Author: Martin Renters
#include <etherboot.h>
#include <nic.h>
#include <netboot_config.h>
static int retry;
static unsigned short isocket = 2000;
static unsigned short osocket;
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;
@ -58,9 +58,10 @@ buf_fill (int abort)
struct tftp_t *tr;
#ifdef CONGESTED
if (! await_reply (AWAIT_TFTP, isocket, NULL, block ? TFTP_REXMT : 0))
if (! await_reply (AWAIT_TFTP, iport, NULL,
block ? TFTP_REXMT : TIMEOUT))
#else
if (! await_reply (AWAIT_TFTP, isocket, NULL, 0))
if (! await_reply (AWAIT_TFTP, iport, NULL, TIMEOUT))
#endif
{
if (ip_abort)
@ -74,7 +75,7 @@ buf_fill (int abort)
#endif
rfc951_sleep (retry);
if (! udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
++isocket, TFTP, len, (char *) &tp))
++iport, TFTP_PORT, len, &tp))
return 0;
continue;
@ -88,8 +89,8 @@ buf_fill (int abort)
grub_printf ("<REXMT>\n");
# endif
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
isocket, osocket,
TFTP_MIN_PACKET, (char *) &tp);
iport, oport,
TFTP_MIN_PACKET, &tp);
continue;
}
#endif
@ -158,8 +159,8 @@ buf_fill (int abort)
"RFC1782 error")
+ TFTP_MIN_PACKET + 1);
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
isocket, ntohs (tr->udp.src),
len, (char *) &tp);
iport, ntohs (tr->udp.src),
len, &tp);
return 0;
}
@ -195,20 +196,20 @@ buf_fill (int abort)
/* Neither TFTP_OACK nor TFTP_DATA. */
break;
/* Block order. */
if (block && (block != prevblock + 1))
if ((block || bcounter) && (block != prevblock + 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);
osocket = ntohs (tr->udp.src);
oport = ntohs (tr->udp.src);
#ifdef TFTP_DEBUG
grub_printf ("ACK\n");
#endif
/* Ack. */
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, isocket,
osocket, TFTP_MIN_PACKET, (char *) &tp);
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, iport,
oport, TFTP_MIN_PACKET, &tp);
if (abort)
{
@ -217,7 +218,7 @@ buf_fill (int abort)
}
/* Retransmission or OACK. */
if (block <= prevblock)
if ((unsigned short) (block - prevblock) != 1)
/* Don't process. */
continue;
@ -225,6 +226,10 @@ buf_fill (int abort)
/* 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;
@ -246,18 +251,27 @@ send_rrq (void)
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");
#endif
/* Send the packet. */
return udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, ++isocket, TFTP,
len, (char *) &tp);
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

View file

@ -11,10 +11,9 @@ Ken Yap, January 1998
* 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"
/* Sources of information:
@ -336,7 +335,7 @@ RESET - Reset adapter
static void i82586_reset(struct nic *nic)
{
long time;
unsigned long time;
#ifdef ETHERBOOT32
unsigned short *shmem = (short *)mem_start;
#endif
@ -410,8 +409,8 @@ static void i82586_reset(struct nic *nic)
}
/**************************************************************************
POLL - Wait for a frame
***************************************************************************/
POLL - Wait for a frame
***************************************************************************/
static int i82586_poll(struct nic *nic)
{
int status;
@ -476,14 +475,14 @@ static int i82586_poll(struct nic *nic)
}
/**************************************************************************
TRANSMIT - Transmit a frame
***************************************************************************/
TRANSMIT - Transmit a frame
***************************************************************************/
static void i82586_transmit(
struct nic *nic,
char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
char *p) /* Packet */
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;
@ -564,8 +563,8 @@ char *p) /* Packet */
}
/**************************************************************************
DISABLE - Turn off ethernet interface
***************************************************************************/
DISABLE - Turn off ethernet interface
***************************************************************************/
static void i82586_disable(struct nic *nic)
{
#ifdef ETHERBOOT32

View file

@ -1,18 +0,0 @@
/* Standard interface flags. */
#define IFF_UP 0x1 /* interface is up */
#define IFF_BROADCAST 0x2 /* broadcast address valid */
#define IFF_DEBUG 0x4 /* turn on debugging */
#define IFF_LOOPBACK 0x8 /* is a loopback net */
#define IFF_POINTOPOINT 0x10 /* interface is has p-p link */
#define IFF_NOTRAILERS 0x20 /* avoid use of trailers */
#define IFF_RUNNING 0x40 /* resources allocated */
#define IFF_NOARP 0x80 /* no ARP protocol */
#define IFF_PROMISC 0x100 /* receive all packets */
/* Not supported */
#define IFF_ALLMULTI 0x200 /* receive all multicast packets*/
#define IFF_MASTER 0x400 /* master of a load balancer */
#define IFF_SLAVE 0x800 /* slave of a load balancer */
#define IFF_MULTICAST 0x1000 /* Supports multicast */

View file

@ -16,9 +16,13 @@ Ken Yap, July 1997
#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_LANCEPCI)
#if defined(INCLUDE_NE2100) || defined(INCLUDE_LANCE)
#define LANCE_ETH_ADDR 0x0
#define LANCE_DATA 0x10
#define LANCE_ADDR 0x12
@ -75,9 +79,7 @@ struct lance_interface
#define LANCE_MUST_PAD 0x00000001
#define LANCE_ENABLE_AUTOSELECT 0x00000002
#define LANCE_MUST_REINIT_RING 0x00000004
#define LANCE_MUST_UNRESET 0x00000008
#define LANCE_HAS_MISSED_FRAME 0x00000010
/* A mapping from the chip ID number to the part number and features.
These are from the datasheets -- in real life the '970 version
@ -85,31 +87,25 @@ struct lance_interface
static struct lance_chip_type
{
int id_number;
char *name;
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 + LANCE_MUST_REINIT_RING +
LANCE_HAS_MISSED_FRAME},
LANCE_ENABLE_AUTOSELECT},
{0x2260, "PCnet/ISA+ 79C961", /* 79C961 PCnet/ISA+, Plug-n-Play. */
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
LANCE_HAS_MISSED_FRAME},
LANCE_ENABLE_AUTOSELECT},
{0x2420, "PCnet/PCI 79C970", /* 79C970 or 79C974 PCnet-SCSI, PCI. */
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
LANCE_HAS_MISSED_FRAME},
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 + LANCE_MUST_REINIT_RING +
LANCE_HAS_MISSED_FRAME},
LANCE_ENABLE_AUTOSELECT},
{0x2621, "PCnet/PCI-II 79C970A", /* 79C970A PCInetPCI II. */
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
LANCE_HAS_MISSED_FRAME},
LANCE_ENABLE_AUTOSELECT},
{0x0, "PCnet (unknown)",
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
LANCE_HAS_MISSED_FRAME},
LANCE_ENABLE_AUTOSELECT},
};
/* Define a macro for converting program addresses to real addresses */
@ -125,9 +121,16 @@ static int chip_version;
static unsigned short ioaddr;
static int dma;
static struct lance_interface *lp;
/* additional 8 bytes for 8-byte alignment space */
static char lance[sizeof(struct lance_interface)+8];
/* additional 8 bytes for 8-byte alignment space */
#ifndef USE_INTERNAL_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 */
@ -183,6 +186,7 @@ static void set_dma_mode(unsigned int dmanr, char mode)
else
outb_p(mode | (dmanr&3), DMA2_MODE_REG);
}
#endif /* !INCLUDE_LANCE */
/**************************************************************************
RESET - Reset adapter
@ -202,7 +206,8 @@ static void lance_reset(struct nic *nic)
/* This is 79C960 specific; Turn on auto-select of media
(AUI, BNC). */
outw(0x2, ioaddr+LANCE_ADDR);
outw(0x2, ioaddr+LANCE_BUS_IF);
/* Don't touch 10base2 power bit. */
outw(inw(ioaddr+LANCE_BUS_IF) | 0x2, ioaddr+LANCE_BUS_IF);
}
/* Re-initialise the LANCE, and start it when done. */
/* Set station address */
@ -269,10 +274,10 @@ TRANSMIT - Transmit a frame
***************************************************************************/
static void lance_transmit(
struct nic *nic,
char *d, /* Destination */
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
char *p) /* Packet */
const char *p) /* Packet */
{
unsigned long time;
@ -312,18 +317,26 @@ static void lance_transmit(
static void lance_disable(struct nic *nic)
{
#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, lance_version, i;
int reset_val, lance_version;
unsigned int i;
Address l;
short dma_channels;
static char dmas[] = { 5, 6, 7, 3 };
static const char dmas[] = { 5, 6, 7, 3 };
reset_val = inw(ioaddr+LANCE_RESET);
#ifdef INCLUDE_NE2100
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);
@ -363,6 +376,7 @@ static int lance_probe1(struct nic *nic)
outw(0x915, ioaddr+LANCE_DATA);
outw(0x0, ioaddr+LANCE_ADDR);
(void)inw(ioaddr+LANCE_ADDR);
#ifndef INCLUDE_LANCE
/* now probe for DMA channel */
dma_channels = ((inb(DMA1_STAT_REG) >> 4) & 0xf) |
(inb(DMA2_STAT_REG) & 0xf0);
@ -392,6 +406,9 @@ static int lance_probe1(struct nic *nic)
dma = 0;
printf("\n%s base 0x%x, DMA %d, addr ",
chip_table[lance_version].name, ioaddr, dma);
#else
printf(" %s base 0x%x, addr ", chip_table[lance_version].name, ioaddr);
#endif
/* Get station address */
for (i = 0; i < ETHER_ADDR_SIZE; ++i)
{
@ -400,6 +417,13 @@ static int lance_probe1(struct nic *nic)
printf(":");
}
putchar('\n');
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);
}
@ -407,8 +431,8 @@ static int lance_probe1(struct nic *nic)
PROBE - Look for an adapter, this routine's visible to the outside
***************************************************************************/
#ifdef INCLUDE_LANCEPCI
struct nic *lancepci_probe(struct nic *nic, unsigned short *probe_addrs)
#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)
@ -426,17 +450,29 @@ struct nic *ni6510_probe(struct nic *nic, unsigned short *probe_addrs)
for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
{
char offset15, offset14 = inb(ioaddr + 14);
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))
#endif
if (lance_probe1(nic) >= 0)
break;
#endif
#ifdef INCLUDE_LANCE
pcibios_read_config_word(0, pci->devfn, PCI_COMMAND, &pci_cmd);
if (!(pci_cmd & PCI_COMMAND_MASTER)) {
pci_cmd |= PCI_COMMAND_MASTER;
pcibios_write_config_word(0, pci->devfn, PCI_COMMAND, pci_cmd);
}
if (lance_probe1(nic, pci) >= 0)
break;
#endif
}
/* if board found */
if (ioaddr != 0)

View file

@ -37,30 +37,6 @@
#define SLOW_DOWN_IO __SLOW_DOWN_IO
#endif
/*
* Change virtual addresses to physical addresses and vv.
* These are trivial on the 1:1 Linux/i386 mapping (but if we ever
* make the kernel segment mapped at 0, we need to do translation
* on the i386 as well)
*/
extern inline unsigned long virt_to_phys(volatile void * address);
extern inline unsigned long virt_to_phys(volatile void * address)
{
return (unsigned long) address;
}
extern inline void * phys_to_virt(unsigned long address);
extern inline void * phys_to_virt(unsigned long address)
{
return (void *) address;
}
/*
* IO bus memory addresses are also 1:1 with the physical address
*/
#define virt_to_bus virt_to_phys
#define bus_to_virt phys_to_virt
/*
* readX/writeX() are used to access memory mapped devices. On some
* architectures the memory mapped IO stuff needs to be accessed
@ -90,7 +66,7 @@ extern inline void * phys_to_virt(unsigned long address)
*/
#define __OUT1(s,x) \
extern inline void __out##s(unsigned x value, unsigned short port); \
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) \
@ -102,42 +78,34 @@ __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) \
extern inline RETURN_TYPE __in##s(unsigned short port); \
extern inline RETURN_TYPE __in##s(unsigned short port) { RETURN_TYPE _v;
#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,i...) \
__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); return _v; } \
__IN1(s##c) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); return _v; } \
__IN1(s##_p) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); SLOW_DOWN_IO; return _v; } \
__IN1(s##c_p) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); SLOW_DOWN_IO; return _v; }
#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 inline void ins##s(unsigned short port, void * addr, unsigned long count); \
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 inline void outs##s(unsigned short port, const void * addr, unsigned long count); \
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)); }
#define RETURN_TYPE unsigned char
/* __IN(b,"b","0" (0)) */
__IN(b,"")
#undef RETURN_TYPE
#define RETURN_TYPE unsigned short
/* __IN(w,"w","0" (0)) */
__IN(w,"")
#undef RETURN_TYPE
#define RETURN_TYPE unsigned int
__IN(l,"")
#undef RETURN_TYPE
__IN(b,"", char)
__IN(w,"",short)
__IN(l,"", long)
__OUT(b,"b",char)
__OUT(w,"w",short)

View file

@ -1,6 +1,6 @@
/*
* Taken from Linux /usr/include/asm/string.h
* All except memcpy, memset and memcmp removed.
* All except memcpy, memmove, memset and memcmp removed.
*/
#ifndef _I386_STRING_H_
@ -19,9 +19,15 @@
* consider these trivial functions to be PD.
*/
#ifndef __FreeBSD__
typedef int size_t;
#endif
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)
{
@ -242,7 +248,7 @@ __asm__ __volatile__("cld\n\t" \
#define __HAVE_ARCH_MEMSET
#define memset(s, c, count) \
(__builtin_constant_p(c) ? \
__memset((s),(c),(count)) : \
__constant_c_x_memset((s),(c),(count)) : \
__memset((s),(c),(count)))
#endif

View file

@ -17,7 +17,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Based on "src/main.c" in etherboot-4.4.2. */
/* Based on "src/main.c" in etherboot-4.5.8. */
/**************************************************************************
ETHERBOOT - BOOTP/TFTP Bootstrap Program
@ -25,6 +25,16 @@ ETHERBOOT - BOOTP/TFTP Bootstrap Program
Author: Martin Renters
Date: Dec/93
Literature dealing with the network protocols:
ARP - RFC826
RARP - RFC903
UDP - RFC768
BOOTP - RFC951, RFC2132 (vendor extensions)
DHCP - RFC2131, RFC2132 (options)
TFTP - RFC1350, RFC2347 (options), RFC2348 (blocksize), RFC2349 (tsize)
RPC - RFC1831, RFC1832 (XDR), RFC1833 (rpcbind/portmapper)
NFS - RFC1094, RFC1813 (v3, useful for clarifications, not implemented)
**************************************************************************/
/* #define MDEBUG */
@ -32,8 +42,6 @@ Author: Martin Renters
#include <etherboot.h>
#include <nic.h>
#include <netboot_config.h>
struct arptable_t arptable[MAX_ARP];
/* Set if the user pushes Control-C. */
@ -67,7 +75,7 @@ static char rfc1533_cookie[5] = {RFC1533_COOKIE, RFC1533_END};
static char rfc1533_cookie[] = {RFC1533_COOKIE};
static char rfc1533_end[] = {RFC1533_END};
static char dhcpdiscover[] =
static const char dhcpdiscover[] =
{
RFC2132_MSG_TYPE, 1, DHCPDISCOVER,
RFC2132_MAX_SIZE, 2, 2, 64,
@ -75,7 +83,7 @@ static char dhcpdiscover[] =
RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH
};
static char dhcprequest[] =
static const char dhcprequest[] =
{
RFC2132_MSG_TYPE, 1, DHCPREQUEST,
RFC2132_SRV_ID, 4, 0, 0, 0, 0,
@ -83,13 +91,21 @@ static char dhcprequest[] =
RFC2132_MAX_SIZE, 2, 2, 64,
/* request parameters */
RFC2132_PARAM_LIST,
#ifdef IMAGE_FREEBSD
/* 4 standard + 4 vendortags + 8 motd + 16 menu items */
4 + 4 + 8 + 16,
#else
/* 4 standard + 3 vendortags + 8 motd + 16 menu items */
4 + 3 + 8 + 16,
#endif
/* Standard parameters */
RFC1533_NETMASK, RFC1533_GATEWAY,
RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH,
/* Etherboot vendortags */
RFC1533_VENDOR_MAGIC, RFC1533_VENDOR_HOWTO,
RFC1533_VENDOR_MAGIC,
#ifdef IMAGE_FREEBSD
RFC1533_VENDOR_HOWTO,
#endif
RFC1533_VENDOR_MNUOPTS, RFC1533_VENDOR_SELECTION,
/* 8 MOTD entries */
RFC1533_VENDOR_MOTD,
@ -121,7 +137,7 @@ static char dhcprequest[] =
#endif /* ! NO_DHCP_SUPPORT */
static char broadcast[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
static const char broadcast[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
void
print_network_configuration (void)
@ -170,8 +186,8 @@ default_netmask (void)
UDP_TRANSMIT - Send a UDP datagram
**************************************************************************/
int
udp_transmit (unsigned long destip, unsigned srcsock, unsigned destsock,
int len, char *buf)
udp_transmit (unsigned long destip, unsigned int srcsock,
unsigned int destsock, int len, const void *buf)
{
struct iphdr *ip;
struct udphdr *udp;
@ -180,7 +196,7 @@ udp_transmit (unsigned long destip, unsigned srcsock, unsigned destsock,
int retry;
ip = (struct iphdr *) buf;
udp = (struct udphdr *) (buf + sizeof (struct iphdr));
udp = (struct udphdr *) ((unsigned long) buf + sizeof (struct iphdr));
ip->verhdrlen = 0x45;
ip->service = 0;
ip->len = htons (len);
@ -237,9 +253,20 @@ udp_transmit (unsigned long destip, unsigned srcsock, unsigned destsock,
grub_memset (arpreq.thwaddr, 0, ETHER_ADDR_SIZE);
grub_memmove (arpreq.tipaddr, (char *) &destip, sizeof (in_addr));
for (retry = 0; retry < MAX_ARP_RETRIES; rfc951_sleep (++retry))
for (retry = 1; retry <= MAX_ARP_RETRIES; retry++)
{
eth_transmit (broadcast, ARP, sizeof (arpreq), (char *) &arpreq);
eth_transmit (broadcast, ARP, sizeof (arpreq), &arpreq);
if (await_reply (AWAIT_ARP, arpentry, arpreq.tipaddr, TIMEOUT))
goto xmit;
if (ip_abort)
return 0;
rfc951_sleep (retry);
/* We have slept for a while - the packet may
* have arrived by now. If not, we have at
* least some room in the Rx buffer for the
* next reply. */
if (await_reply (AWAIT_ARP, arpentry, arpreq.tipaddr, 0))
goto xmit;
@ -264,28 +291,38 @@ static int
tftp (char *name, int (*fnc) (unsigned char *, int, int, int))
{
int retry = 0;
static unsigned short isocket = 2000;
unsigned short osocket;
static unsigned short iport = 2000;
unsigned short oport;
unsigned short len, block = 0, prevblock = 0;
int bcounter = 0;
struct tftp_t *tr;
struct tftp_t tp;
int rc;
int packetsize = TFTP_DEFAULTSIZE_PACKET;
/* 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);
tp.opcode = htons (TFTP_RRQ);
len = (grub_sprintf ((char *)tp.u.rrq, "%s%coctet%cblksize%c%d",
name, 0, 0, 0, TFTP_MAX_PACKET)
+ TFTP_MIN_PACKET + 1);
if (! udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, ++isocket, TFTP,
len, (char *) &tp))
if (! udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, ++iport,
TFTP_PORT, len, &tp))
return 0;
for (;;)
{
#ifdef CONGESTED
if (! await_reply (AWAIT_TFTP, isocket, NULL, (block ? TFTP_REXMT : 0)))
if (! await_reply (AWAIT_TFTP, iport, NULL,
(block ? TFTP_REXMT : TIMEOUT)))
#else
if (! await_reply (AWAIT_TFTP, isocket, NULL, 0))
if (! await_reply (AWAIT_TFTP, iport, NULL, TIMEOUT))
#endif
{
if (! block && retry++ < MAX_TFTP_RETRIES)
@ -293,7 +330,7 @@ tftp (char *name, int (*fnc) (unsigned char *, int, int, int))
/* Maybe initial request was lost. */
rfc951_sleep (retry);
if (! udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
++isocket, TFTP, len, (char *) &tp))
++iport, TFTP_PORT, len, &tp))
return 0;
continue;
@ -307,8 +344,8 @@ tftp (char *name, int (*fnc) (unsigned char *, int, int, int))
grub_printf ("<REXMT>\n");
#endif
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
isocket, osocket,
TFTP_MIN_PACKET, (char *)&tp);
iport, oport,
TFTP_MIN_PACKET, &tp);
continue;
}
#endif
@ -362,8 +399,8 @@ tftp (char *name, int (*fnc) (unsigned char *, int, int, int))
"RFC1782 error")
+ TFTP_MIN_PACKET + 1);
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
isocket, ntohs (tr->udp.src),
len, (char *) &tp);
iport, ntohs (tr->udp.src),
len, &tp);
return 0;
}
}
@ -388,27 +425,28 @@ tftp (char *name, int (*fnc) (unsigned char *, int, int, int))
/* Neither TFTP_OACK nor TFTP_DATA. */
break;
if (block && (block != prevblock+1))
/* Block order. */
if ((block || bcounter) && (block != prevblock + 1))
/* Block order should be continuous */
tp.u.ack.block = htons (block = prevblock);
/* Should be continuous. */
tp.opcode = htons (TFTP_ACK);
osocket = ntohs (tr->udp.src);
oport = ntohs (tr->udp.src);
/* Ack. */
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, isocket,
osocket, TFTP_MIN_PACKET, (char *) &tp);
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, iport,
oport, TFTP_MIN_PACKET, &tp);
/* Retransmission or OACK. */
if (block <= prevblock)
/* Don't process. */
if ((unsigned short) (block - prevblock) != 1)
/* Retransmission or OACK, don't process via callback
* and don't change the value of prevblock. */
continue;
prevblock = block;
/* Is it the right place to zero the timer? */
retry = 0;
if ((rc = fnc (tr->u.data.download, block, len, len < packetsize)) >= 0)
if ((rc = fnc (tr->u.data.download,
++bcounter, len, len < packetsize)) >= 0)
return rc;
/* End of data. */
@ -453,9 +491,9 @@ rarp (void)
for (retry = 0; retry < MAX_ARP_RETRIES; rfc951_sleep (++retry))
{
eth_transmit (broadcast, RARP, sizeof (rarpreq), (char *) &rarpreq);
eth_transmit (broadcast, RARP, sizeof (rarpreq), &rarpreq);
if (await_reply (AWAIT_RARP, 0, rarpreq.shwaddr, 0))
if (await_reply (AWAIT_RARP, 0, rarpreq.shwaddr, TIMEOUT))
break;
if (ip_abort)
@ -516,23 +554,17 @@ bootp (void)
for (retry = 0; retry < MAX_BOOTP_RETRIES;)
{
/*
* Discard all received packets - we have no requests
* outstanding. It happened too often that the reply sent
* by the BOOTP server caused a RX buffer overrun (which for
* most cards - especially the cheap ones with a small
* receive buffer - is handled by discarding the whole
* receive buffer contents). An even cruder way to solve
* the problem would be to discard all packets while in
* rfc951_sleep(), but this may have affected future changes
* to the etherboot implementation.
*/
while (eth_poll ())
/* Nothing */
;
/* 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);
udp_transmit (IP_BROADCAST, 0, BOOTP_SERVER,
sizeof (struct bootp_t), (char *) &bp);
sizeof (struct bootp_t), &bp);
#ifdef T509HACK
if (flag)
{
@ -542,13 +574,13 @@ bootp (void)
#endif /* T509HACK */
#ifdef NO_DHCP_SUPPORT
if (await_reply (AWAIT_BOOTP, 0, NULL, 0))
if (await_reply (AWAIT_BOOTP, 0, NULL, TIMEOUT))
{
network_ready = 1;
return 1;
}
#else /* ! NO_DHCP_SUPPORT */
if (await_reply (AWAIT_BOOTP, 0, NULL, 0))
if (await_reply (AWAIT_BOOTP, 0, NULL, TIMEOUT))
{
if (dhcp_reply == DHCPOFFER)
{
@ -566,9 +598,9 @@ bootp (void)
for (retry1 = 0; retry1 < MAX_BOOTP_RETRIES;)
{
udp_transmit (IP_BROADCAST, 0, BOOTP_SERVER,
sizeof (struct bootp_t), (char *) &bp);
sizeof (struct bootp_t), &bp);
dhcp_reply = 0;
if (await_reply (AWAIT_BOOTP, 0, NULL, 0))
if (await_reply (AWAIT_BOOTP, 0, NULL, TIMEOUT))
if (dhcp_reply == DHCPACK)
{
network_ready = 1;
@ -607,35 +639,26 @@ bootp (void)
AWAIT_REPLY - Wait until we get a response for our request
**************************************************************************/
int
await_reply (int type, int ival, char *ptr, int timeout)
await_reply (int type, int ival, void *ptr, int timeout)
{
unsigned long time;
struct iphdr *ip;
struct udphdr *udp;
struct arprequest *arpreply;
struct bootp_t *bootpreply;
struct rpc_t *rpc;
unsigned short ptype;
int protohdrlen = (ETHER_HDR_SIZE + sizeof (struct iphdr)
unsigned int protohdrlen = (ETHER_HDR_SIZE + sizeof (struct iphdr)
+ sizeof (struct udphdr));
/* Clear the abort flag. */
ip_abort = 0;
#ifdef CONGESTED
time = currticks () + (timeout ? timeout : TIMEOUT);
#else
time = currticks () + TIMEOUT;
#endif
while (time > currticks ())
/* The timeout check is done below. The timeout is only checked if
* there is no packet in the Rx queue. This assumes that eth_poll()
* needs a negligible amount of time. */
for (;;)
{
/* If Control-C is pushed, return immediately. */
if (checkkey () != -1 && ASCII_CHAR (getkey ()) == CTRL_C)
{
ip_abort = 1;
return 0;
}
if (eth_poll ())
{
/* We have something! */
@ -686,7 +709,7 @@ await_reply (int type, int ival, char *ptr, int timeout)
ETHER_ADDR_SIZE);
eth_transmit (arpreply->thwaddr, ARP,
sizeof (struct arprequest),
(char *) arpreply);
arpreply);
#ifdef MDEBUG
grub_memmove (&tmp, arpreply->tipaddr, sizeof (in_addr));
grub_printf ("Sent ARP reply to: %x\n", tmp);
@ -696,6 +719,11 @@ await_reply (int type, int ival, char *ptr, int timeout)
continue;
}
if (type == AWAIT_QDRAIN)
{
continue;
}
/* Check for RARP - No IP hdr. */
if (type == AWAIT_RARP
&& nic.packetlen >= ETHER_HDR_SIZE + sizeof (struct arprequest)
@ -761,13 +789,13 @@ await_reply (int type, int ival, char *ptr, int timeout)
grub_memset (arptable[ARP_GATEWAY].node, 0, ETHER_ADDR_SIZE);
/* GRUB doesn't autoload any kernel image. */
#if 0
#ifndef GRUB
if (bootpreply->bp_file[0])
{
grub_memmove (kernel_buf, bootpreply->bp_file, 128);
kernel = kernel_buf;
}
#endif
#endif /* ! GRUB */
grub_memmove ((char *) BOOTP_DATA_ADDR, (char *) bootpreply,
sizeof (struct bootpd_t));
@ -785,9 +813,24 @@ await_reply (int type, int ival, char *ptr, int timeout)
/* TFTP ? */
if (type == AWAIT_TFTP && ntohs (udp->dest) == ival)
return 1;
}
else
{
/* Check for abort key only if the Rx queue is empty -
* as long as we have something to process, don't
* assume that something failed. It is unlikely that
* we have no processing time left between packets. */
if (checkkey () != -1 && ASCII_CHAR (getkey ()) == CTRL_C)
{
ip_abort = 1;
return 0;
}
/* RPC */
rpc = (struct rpc_t *) &nic.packet[ETHER_HDR_SIZE];
/* Do the timeout after at least a full queue walk. */
if ((timeout == 0) || (currticks() > time))
{
break;
}
}
}
@ -802,7 +845,7 @@ decode_rfc1533 (unsigned char *p, int block, int len, int eof)
{
static unsigned char *extdata = NULL, *extend = NULL;
unsigned char *extpath = NULL;
unsigned char *end;
unsigned char *endp;
if (block == 0)
{
@ -823,7 +866,7 @@ decode_rfc1533 (unsigned char *p, int block, int len, int eof)
return 0;
p += 4;
end = p + len;
endp = p + len;
}
else
{
@ -852,12 +895,12 @@ decode_rfc1533 (unsigned char *p, int block, int len, int eof)
}
p = extdata;
end = extend;
endp = extend;
}
if (eof)
{
while (p < end)
while (p < endp)
{
unsigned char c = *p;
@ -868,7 +911,7 @@ decode_rfc1533 (unsigned char *p, int block, int len, int eof)
}
else if (c == RFC1533_END)
{
end_of_rfc1533 = end = p;
end_of_rfc1533 = endp = p;
continue;
}
else if (c == RFC1533_NETMASK)
@ -898,22 +941,18 @@ decode_rfc1533 (unsigned char *p, int block, int len, int eof)
#endif /* ! NO_DHCP_SUPPORT */
/* GRUB needs not to use any vendor-specific extension. */
#if 0
#ifndef GRUB
else if (c == RFC1533_VENDOR_MAGIC
# if !defined(AOUT_IMAGE) && !defined(ELF_IMAGE) /* since FreeBSD uses tag 128 for swap definition */
&& TAG_LEN (p) >= 6 &&
!memcmp (p + 2, vendorext_magic, 4) &&
# ifndef IMAGE_FREEBSD /* since FreeBSD uses tag 128 for swap definition */
&& TAG_LEN(p) >= 6 &&
!memcmp(p+2,vendorext_magic,4) &&
p[6] == RFC1533_VENDOR_MAJOR
# endif
)
vendorext_isvalid++;
# if defined(AOUT_IMAGE) || defined(ELF_IMAGE)
else if (c == RFC1533_VENDOR_HOWTO)
{
howto = ((p[2] * 256 + p[3]) * 256 + p[4]) * 256 + p[5];
/*
printf("Howto %X %d,%x %x %x %x\n",howto,TAGLEN(p),p[2],p[3],p[4],p[5]);
*/
# ifdef IMAGE_FREEBSD
else if (c == RFC1533_VENDOR_HOWTO) {
freebsd_howto = ((p[2]*256+p[3])*256+p[4])*256+p[5];
}
# endif
# ifdef IMAGE_MENU
@ -936,17 +975,19 @@ decode_rfc1533 (unsigned char *p, int block, int len, int eof)
# endif
else
{
/* printf("Unknown RFC1533-tag ");
# if 0
printf("Unknown RFC1533-tag ");
for(q=p;q<p+2+TAG_LEN(p);q++)
printf("%x ",*q);
putchar('\n'); */
putchar('\n');
# endif
}
#endif /* 0 */
#endif /* ! GRUB */
p += TAG_LEN (p) + 2;
}
extdata = extend = end;
extdata = extend = endp;
/* Perhaps we can eliminate this because we doesn't require so
much information, but I leave this alone. */
@ -988,7 +1029,13 @@ void
rfc951_sleep (int exp)
{
static long seed = 0;
long q, tmo;
long q;
unsigned long tmo;
#ifdef BACKOFF_LIMIT
if (exp > BACKOFF_LIMIT)
exp = BACKOFF_LIMIT;
#endif
if (! seed)
/* Initialize linear congruential generator. */
@ -1013,3 +1060,32 @@ rfc951_sleep (int exp)
if (checkkey () != -1 && ASCII_CHAR (getkey ()) == CTRL_C)
break;
}
/**************************************************************************
CLEANUP_NET - shut down networking
**************************************************************************/
void
cleanup_net (void)
{
if (network_ready)
{
#ifdef DOWNLOAD_PROTO_NFS
nfs_umountall (ARP_SERVER);
#endif
eth_disable ();
network_ready = 0;
}
}
#ifndef GRUB
/**************************************************************************
CLEANUP - shut down etherboot so that the OS may be called right away
**************************************************************************/
void
cleanup (void)
{
#if defined(ANSIESC) && defined(CONSOLE_CRT)
ansi_reset ();
#endif
}
#endif /* ! GRUB */

View file

@ -17,7 +17,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Based on "src/misc.c" in etherboot-4.4.2. */
/* Based on "src/misc.c" in etherboot-4.5.8. */
/**************************************************************************
MISC Support Routines
@ -30,7 +30,7 @@ SLEEP
**************************************************************************/
void sleep(int secs)
{
long tmo;
unsigned long tmo;
for (tmo = currticks()+secs*TICKS_PER_SEC; currticks() < tmo; )
/* Nothing */;
@ -45,15 +45,14 @@ void twiddle()
static int count=0;
static char tiddles[]="-\\|/";
unsigned long ticks;
if ((ticks = currticks()) < lastticks)
if ((ticks = currticks()) == lastticks)
return;
lastticks = ticks+1;
lastticks = ticks;
putchar(tiddles[(count++)&3]);
putchar('\b');
}
#if 0
#ifdef ETHERBOOT32
#ifndef GRUB
/**************************************************************************
STRCASECMP (not entirely correct, but this will do for our purposes)
**************************************************************************/
@ -63,7 +62,6 @@ int strcasecmp(a,b)
while (*a && *b && (*a & ~0x20) == (*b & ~0x20)) {a++; b++; }
return((*a & ~0x20) - (*b & ~0x20));
}
#endif /* ETHERBOOT32 */
/**************************************************************************
PRINTF and friends
@ -78,9 +76,7 @@ PRINTF and friends
%I - Internet address in x.x.x.x notation
**************************************************************************/
static char hex[]="0123456789ABCDEF";
char *do_printf(buf, fmt, dp)
char *buf, *fmt;
int *dp;
static char *do_printf(char *buf, const char *fmt, const int *dp)
{
register char *p;
char tmp[16];
@ -89,9 +85,9 @@ char *do_printf(buf, fmt, dp)
fmt++;
if (*fmt == 'X') {
long *lp = (long *)dp;
const long *lp = (const long *)dp;
register long h = *lp++;
dp = (int *)lp;
dp = (const int *)lp;
*(buf++) = hex[(h>>28)& 0x0F];
*(buf++) = hex[(h>>24)& 0x0F];
*(buf++) = hex[(h>>20)& 0x0F];
@ -131,9 +127,9 @@ char *do_printf(buf, fmt, dp)
long l;
unsigned char c[4];
} u;
long *lp = (long *)dp;
const long *lp = (const long *)dp;
u.l = *lp++;
dp = (int *)lp;
dp = (const int *)lp;
buf = sprintf(buf,"%d.%d.%d.%d",
u.c[0], u.c[1], u.c[2], u.c[3]);
}
@ -150,30 +146,25 @@ char *do_printf(buf, fmt, dp)
return(buf);
}
char *sprintf(buf, fmt, data)
char *fmt, *buf;
int data;
char *sprintf(char *buf, const char *fmt, ...)
{
return(do_printf(buf,fmt, &data));
return do_printf(buf, fmt, ((const int *)&fmt)+1);
}
void printf(fmt,data)
char *fmt;
int data;
void printf(const char *fmt, ...)
{
char buf[120],*p;
p = buf;
do_printf(buf,fmt,&data);
do_printf(buf, fmt, ((const int *)&fmt)+1);
while (*p) putchar(*p++);
}
#ifdef IMAGE_MENU
/**************************************************************************
INET_NTOA - Convert an ascii x.x.x.x to binary form
INET_ATON - Convert an ascii x.x.x.x to binary form
**************************************************************************/
int inet_ntoa(p, i)
char *p;
in_addr *i;
int inet_aton(char *p, in_addr *i)
{
unsigned long ip = 0;
int val;
@ -195,10 +186,9 @@ int inet_ntoa(p, i)
}
#endif /* IMAGE_MENU */
#endif /* 0 */
#endif /* ! GRUB */
int getdec(ptr)
char **ptr;
int getdec(char **ptr)
{
char *p = *ptr;
int ret=0;
@ -211,7 +201,7 @@ int getdec(ptr)
return(ret);
}
#if 0
#ifndef GRUB
#define K_RDWR 0x60 /* keyboard data & cmds (read/write) */
#define K_STATUS 0x64 /* keyboard status */
#define K_CMD 0x64 /* keybd ctlr command (write-only) */
@ -221,15 +211,17 @@ int getdec(ptr)
#define KC_CMD_WIN 0xd0 /* read output port */
#define KC_CMD_WOUT 0xd1 /* write output port */
#define KB_A20 0xdf /* enable A20,
#define KB_SET_A20 0xdf /* enable A20,
enable output buffer full interrupt
enable data line
disable clock line */
#define KB_UNSET_A20 0xdd /* enable A20,
enable output buffer full interrupt
enable data line
disable clock line */
#ifndef IBM_L40
static void empty_8042(void)
{
extern void slowdownio();
unsigned long time;
char st;
@ -245,99 +237,105 @@ static void empty_8042(void)
/*
* Gate A20 for high memory
*/
void gateA20()
void gateA20_set(void)
{
#ifdef IBM_L40
outb(0x2, 0x92);
#else IBM_L40
#else /* IBM_L40 */
empty_8042();
outb(KC_CMD_WOUT, K_CMD);
empty_8042();
outb(KB_A20, K_RDWR);
outb(KB_SET_A20, K_RDWR);
empty_8042();
#endif IBM_L40
#endif /* IBM_L40 */
}
#ifdef TAGGED_IMAGE
/*
* Unset Gate A20 for high memory - some operating systems (mainly old 16 bit
* ones) don't expect it to be set by the boot loader.
*/
void gateA20_unset(void)
{
#ifdef IBM_L40
outb(0x0, 0x92);
#else /* IBM_L40 */
empty_8042();
outb(KC_CMD_WOUT, K_CMD);
empty_8042();
outb(KB_UNSET_A20, K_RDWR);
empty_8042();
#endif /* IBM_L40 */
}
#endif
#ifdef ETHERBOOT32
/* Serial console is only implemented in ETHERBOOT32 for now */
void
putchar(int c)
{
#ifdef ANSIESC
handleansi(c);
return;
#endif
#ifndef ANSIESC
if (c == '\n')
putchar('\r');
#ifdef SERIAL_CONSOLE
#if SERIAL_CONSOLE == DUAL
putc(c);
#endif /* SERIAL_CONSOLE == DUAL */
serial_putc(c);
#endif
#ifdef CONSOLE_CRT
#ifdef ANSIESC
handleansi(c);
#else
putc(c);
#endif /* SERIAL_CONSOLE */
#endif
#endif
#ifdef CONSOLE_SERIAL
#ifdef ANSIESC
if (c == '\n')
serial_putc('\r');
#endif
serial_putc(c);
#endif
}
/**************************************************************************
GETCHAR - Read the next character from the console WITHOUT ECHO
**************************************************************************/
int
getchar(int in_buf)
getchar(void)
{
int c=256;
int c = 256;
loop:
#ifdef SERIAL_CONSOLE
#if SERIAL_CONSOLE == DUAL
do {
#ifdef CONSOLE_CRT
if (ischar())
c = getc();
#endif
#ifdef CONSOLE_SERIAL
if (serial_ischar())
c = serial_getc();
#else
if (ischar())
c = getc();
#endif
if (c==256){
goto loop;
}
} while (c==256);
if (c == '\r')
c = '\n';
if (c == '\b') {
if (in_buf != 0) {
putchar('\b');
putchar(' ');
} else {
goto loop;
}
}
putchar(c);
return(c);
return c;
}
int
iskey(void)
{
int isc;
/*
* Checking the keyboard has the side effect of enabling clock
* interrupts so that bios_tick works. Check the keyboard to
* get this side effect even if we only want the serial status.
*/
#ifdef SERIAL_CONSOLE
#if SERIAL_CONSOLE == DUAL
#ifdef CONSOLE_CRT
if (ischar())
return 1;
#endif
#ifdef CONSOLE_SERIAL
if (serial_ischar())
return 1;
#else
if (ischar())
return 1;
#endif
return 0;
}
#endif /* ETHERBOOT32 */
#endif
#endif /* ! GRUB */
/*
* Local variables:
* c-basic-offset: 8
* End:
*/

View file

@ -1,15 +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.
*/
extern struct nic nic;
extern void print_config(void);
extern void eth_reset(void);
extern int eth_probe(void);
extern int eth_poll(void);
extern void eth_transmit(char *d, unsigned int t, unsigned int s, char *p);
extern void eth_disable(void);

View file

@ -1,195 +0,0 @@
/*
* INET An implementation of the TCP/IP protocol suite for the LINUX
* operating system. INET is implemented using the BSD Socket
* interface as the means of communication with the user level.
*
* Definitions for the Interfaces handler.
*
* Version: @(#)dev.h 1.0.10 08/12/93
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Corey Minyard <wf-rch!minyard@relay.EU.net>
* Donald J. Becker, <becker@super.org>
* Alan Cox, <A.Cox@swansea.ac.uk>
* Bjorn Ekwall. <bj0rn@blox.se>
*
* 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.
*
* Moved to /usr/include/linux for NET3
*/
/* for future expansion when we will have different priorities. */
#define DEV_NUMBUFFS 3
#define MAX_ADDR_LEN 7
#ifndef CONFIG_AX25
#ifndef CONFIG_TR
#ifndef CONFIG_NET_IPIP
#define MAX_HEADER 32 /* We really need about 18 worst case .. so 32 is aligned */
#else
#define MAX_HEADER 80 /* We need to allow for having tunnel headers */
#endif /* IPIP */
#else
#define MAX_HEADER 48 /* Token Ring header needs 40 bytes ... 48 is aligned */
#endif /* TR */
#else
#define MAX_HEADER 96 /* AX.25 + NetROM */
#endif /* AX25 */
#define IS_MYADDR 1 /* address is (one of) our own */
#define IS_LOOPBACK 2 /* address is for LOOPBACK */
#define IS_BROADCAST 3 /* address is a valid broadcast */
#define IS_INVBCAST 4 /* Wrong netmask bcast not for us (unused)*/
#define IS_MULTICAST 5 /* Multicast IP address */
/*
* The DEVICE structure.
* Actually, this whole structure is a big mistake. It mixes I/O
* data with strictly "high-level" data, and it has to know about
* almost every data structure used in the INET module.
*/
struct device
{
/*
* This is the first field of the "visible" part of this structure
* (i.e. as seen by users in the "Space.c" file). It is the name
* the interface.
*/
char *name;
/* I/O specific fields - FIXME: Merge these and struct ifmap into one */
unsigned long rmem_end; /* shmem "recv" end */
unsigned long rmem_start; /* shmem "recv" start */
unsigned long mem_end; /* shared mem end */
unsigned long mem_start; /* shared mem start */
unsigned long base_addr; /* device I/O address */
unsigned char irq; /* device IRQ number */
/* Low-level status flags. */
volatile unsigned char start, /* start an operation */
interrupt; /* interrupt arrived */
unsigned long tbusy; /* transmitter busy must be long for bitops */
struct device *next;
/* The device initialization function. Called only once. */
int (*init)(struct device *dev);
/* Some hardware also needs these fields, but they are not part of the
usual set specified in Space.c. */
unsigned char if_port; /* Selectable AUI, TP,..*/
unsigned char dma; /* DMA channel */
/* struct enet_statistics* (*get_stats)(struct device *dev); */
/*
* This marks the end of the "visible" part of the structure. All
* fields hereafter are internal to the system, and may change at
* will (read: may be cleaned up at will).
*/
/* These may be needed for future network-power-down code. */
unsigned long trans_start; /* Time (in jiffies) of last Tx */
unsigned long last_rx; /* Time of last Rx */
unsigned short flags; /* interface flags (a la BSD) */
unsigned short family; /* address family ID (AF_INET) */
unsigned short metric; /* routing metric (not used) */
unsigned short mtu; /* interface MTU value */
unsigned short type; /* interface hardware type */
unsigned short hard_header_len; /* hardware hdr length */
void *priv; /* pointer to private data */
/* Interface address info. */
unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
unsigned char pad; /* make dev_addr aligned to 8 bytes */
unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address */
unsigned char addr_len; /* hardware address length */
unsigned long pa_addr; /* protocol address */
unsigned long pa_brdaddr; /* protocol broadcast addr */
unsigned long pa_dstaddr; /* protocol P-P other side addr */
unsigned long pa_mask; /* protocol netmask */
unsigned short pa_alen; /* protocol address length */
#if 0
struct dev_mc_list *mc_list; /* Multicast mac addresses */
#endif
int mc_count; /* Number of installed mcasts */
#if 0
struct ip_mc_list *ip_mc_list; /* IP multicast filter chain */
#endif
unsigned int tx_queue_len; /* Max frames per queue allowed */
/* For load balancing driver pair support */
unsigned long pkt_queue; /* Packets queued */
#if 0
struct device *slave; /* Slave device */
struct net_alias_info *alias_info; /* main dev alias info */
struct net_alias *my_alias; /* alias devs */
/* Pointer to the interface buffers. */
struct sk_buff_head buffs[DEV_NUMBUFFS];
#endif
int (*change_mtu)(struct device *dev, int new_mtu);
};
#if 0
struct packet_type {
unsigned short type; /* This is really htons(ether_type). */
struct device * dev;
int (*func) (struct sk_buff *, struct device *,
struct packet_type *);
void *data;
struct packet_type *next;
};
/* Used by dev_rint */
#define IN_SKBUFF 1
extern int dev_lockct;
/*
* These two don't currently need to be interrupt-safe
* but they may do soon. Do it properly anyway.
*/
extern __inline__ void dev_lock_list(void)
{
unsigned long flags;
save_flags(flags);
cli();
dev_lockct++;
restore_flags(flags);
}
extern __inline__ void dev_unlock_list(void)
{
unsigned long flags;
save_flags(flags);
cli();
dev_lockct--;
restore_flags(flags);
}
/*
* This almost never occurs, isn't in performance critical paths
* and we can thus be relaxed about it
*/
extern __inline__ void dev_lock_wait(void)
{
while(dev_lockct)
schedule();
}
#endif /* _LINUX_DEV_H */

View file

@ -1,10 +1,13 @@
/*
/*
* 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.
@ -14,12 +17,14 @@ struct nic
{
void (*reset)P((struct nic *));
int (*poll)P((struct nic *));
void (*transmit)P((struct nic *, char *d,
unsigned int t, unsigned int s, char *p));
void (*transmit)P((struct nic *, const char *d,
unsigned int t, unsigned int s, const char *p));
void (*disable)P((struct nic *));
char aui;
char *node_addr;
unsigned char *node_addr;
char *packet;
int packetlen;
unsigned int packetlen;
void *priv_data; /* driver can hang private data here */
};
#endif /* NIC_H */

View file

@ -1,4 +1,3 @@
/**************************************************************************
ETHERBOOT - BOOTP/TFTP Bootstrap Program
@ -25,6 +24,10 @@ RX overrun by Klaus Espenlaub (espenlaub@informatik.uni-ulm.de) on 3/10/99
#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;
@ -34,7 +37,7 @@ static unsigned char eth_drain_receiver;
#ifdef INCLUDE_WD
static struct wd_board {
char *name;
const char *name;
char id;
char flags;
char memsize;
@ -54,7 +57,7 @@ static struct wd_board {
{"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}
{NULL, 0, 0, 0}
};
#endif
@ -64,48 +67,45 @@ static unsigned char t503_output; /* AUI or internal xcvr (Thinnet) */
#if defined(INCLUDE_WD)
#define eth_probe wd_probe
#if defined(INCLUDE_3C503) || defined(INCLUDE_NE) || defined(INCLUDE_NEPCI)
Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE[PCI]
#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_NEPCI) || defined(INCLUDE_WD)
Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE[PCI]
#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_NEPCI) || defined(INCLUDE_3C503) || defined(INCLUDE_WD)
Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE[PCI]
#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_NEPCI)
#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[PCI]
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_NEPCI)
#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390)
#define ASIC_PIO NE_DATA
#endif
#endif
#if defined(INCLUDE_NE) || defined(INCLUDE_NEPCI) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM))
#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(src, dst, cnt)
unsigned int src;
unsigned char *dst;
unsigned int cnt;
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 |
@ -148,10 +148,7 @@ static void eth_pio_read(src, dst, cnt)
/**************************************************************************
ETH_PIO_WRITE - Write a frame via Programmed I/O
**************************************************************************/
static void eth_pio_write(src, dst, cnt)
unsigned char *src;
unsigned int dst;
unsigned int cnt;
static void eth_pio_write(const unsigned char *src, unsigned int dst, unsigned int cnt)
{
#ifdef COMPEX_RL2000_FIX
unsigned int x;
@ -216,9 +213,9 @@ static void eth_pio_read(unsigned int src, unsigned char *dst, unsigned int cnt)
#endif
/**************************************************************************
ETH_RESET - Reset adapter
NS8390_RESET - Reset adapter
**************************************************************************/
static void eth_reset(struct nic *nic)
static void ns8390_reset(struct nic *nic)
{
int i;
@ -284,7 +281,7 @@ static void eth_reset(struct nic *nic)
#endif
}
static int eth_poll(struct nic *nic);
static int ns8390_poll(struct nic *nic);
#ifndef INCLUDE_3C503
/**************************************************************************
@ -327,7 +324,7 @@ static void eth_rx_overrun(struct nic *nic)
/* clear the RX ring, acknowledge overrun interrupt */
eth_drain_receiver = 1;
while (eth_poll(nic))
while (ns8390_poll(nic))
/* Nothing */;
eth_drain_receiver = 0;
outb(D8390_ISR_OVW, eth_nic_base+D8390_P0_ISR);
@ -338,14 +335,14 @@ static void eth_rx_overrun(struct nic *nic)
#endif /* INCLUDE_3C503 */
/**************************************************************************
ETH_TRANSMIT - Transmit a frame
NS8390_TRANSMIT - Transmit a frame
**************************************************************************/
static void eth_transmit(
static void ns8390_transmit(
struct nic *nic,
char *d, /* Destination */
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
char *p) /* Packet */
const char *p) /* Packet */
{
int c; /* used in ETHERBOOT16 */
@ -421,7 +418,7 @@ static void eth_transmit(
#if defined(INCLUDE_3C503)
if (eth_flags & FLAG_PIO) {
#endif
#if defined(INCLUDE_NE) || defined(INCLUDE_NEPCI) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM))
#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM))
/* Programmed I/O */
unsigned short type;
type = (t >> 8) | (t << 8);
@ -460,9 +457,9 @@ static void eth_transmit(
}
/**************************************************************************
ETH_POLL - Wait for a frame
NS8390_POLL - Wait for a frame
**************************************************************************/
static int eth_poll(struct nic *nic)
static int ns8390_poll(struct nic *nic)
{
int ret = 0;
unsigned char rstat, curr, next;
@ -564,16 +561,21 @@ static int eth_poll(struct nic *nic)
}
/**************************************************************************
ETH_DISABLE - Turn off adapter
NS8390_DISABLE - Turn off adapter
**************************************************************************/
static void eth_disable(struct nic *nic)
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;
@ -780,7 +782,7 @@ struct nic *eth_probe(struct nic *nic, unsigned short *probe_addrs)
eth_vendor = VENDOR_3COM;
/* Need this to make eth_poll() happy. */
/* Need this to make ns8390_poll() happy. */
eth_rmem = eth_bmem - 0x2000;
@ -845,14 +847,14 @@ struct nic *eth_probe(struct nic *nic, unsigned short *probe_addrs)
}
#endif
#if defined(INCLUDE_NE) || defined(INCLUDE_NEPCI)
#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[] = "NE1000/2000 memory";
static char test[] = "NE*000 memory";
static unsigned short base[] = {
#ifdef NE_SCAN
NE_SCAN,
@ -877,6 +879,10 @@ struct nic *eth_probe(struct nic *nic, unsigned short *probe_addrs)
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 INCLUDE_NS8390
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)))
@ -914,11 +920,11 @@ struct nic *eth_probe(struct nic *nic, unsigned short *probe_addrs)
return(0);
if (eth_vendor != VENDOR_3COM)
eth_rmem = eth_bmem;
eth_reset(nic);
nic->reset = eth_reset;
nic->poll = eth_poll;
nic->transmit = eth_transmit;
nic->disable = eth_disable;
ns8390_reset(nic);
nic->reset = ns8390_reset;
nic->poll = ns8390_poll;
nic->transmit = ns8390_transmit;
nic->disable = ns8390_disable;
return(nic);
}

View file

@ -1,601 +0,0 @@
/*
Tulip and clone Etherboot Driver
By Marty Connor (mdc@thinguin.org)
This software may be used and distributed according to the terms
of the GNU Public License, incorporated herein by reference.
Based on Ken Yap's Tulip Etherboot Driver and Donald Becker's
Linux Tulip Driver. Supports N-Way speed auto-configuration on
MX98715, MX98715A and MX98725. Support inexpensive PCI 10/100 cards
based on the Macronix MX987x5 chip, such as the SOHOware Fast
model SFA110A, and the LinkSYS model LNE100TX. The NetGear
model FA310X, based on the LC82C168 chip is also supported.
Documentation and source code used:
Source for Etherboot driver at
http://www.slug.org.au/etherboot/
MX98715A Data Sheet and MX98715A Application Note
on http://www.macronix.com/ (PDF format files)
Source for Linux tulip driver at
http://cesdis.gsfc.nasa.gov/linux/drivers/tulip.html
Adapted by Ken Yap from
FreeBSD netboot DEC 21143 driver
Author: David Sharp
date: Nov/98
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
*/
/*********************************************************************/
/* Revision History */
/*********************************************************************/
/*
11 Jan 2000 mdc 0.75b4
Added support for NetGear FA310TX card based on the LC82C168
chip. This should also support Lite-On LC82C168 boards.
Added simple MII support. Re-arranged code to better modularize
initializations.
04 Dec 1999 mdc 0.75b3
Added preliminary support for LNE100TX PCI cards. Should work for
PNIC2 cards. No MII support, but single interface (RJ45) tulip
cards seem to not care.
03 Dec 1999 mdc 0.75b2
Renamed from mx987x5 to ntulip, merged in original tulip init code
from tulip.c to support other tulip compatible cards.
02 Dec 1999 mdc 0.75b1
Released Beta MX987x5 Driver for code review and testing to netboot
and thinguin mailing lists.
*/
#include "etherboot.h"
#include "nic.h"
#include "pci.h"
/*********************************************************************/
/* Declarations */
/*********************************************************************/
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 tulip device */
enum ntulip_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
};
#define DEC_21142_CSR6_TTM 0x00400000 /* Transmit Threshold Mode */
#define DEC_21142_CSR6_HBD 0x00080000 /* Heartbeat Disable */
#define DEC_21142_CSR6_PS 0x00040000 /* Port Select */
/* EEPROM Address width definitions */
#define EEPROM_ADDRLEN 6
#define EEPROM_SIZE 128 /* 2 << EEPROM_ADDRLEN */
/* 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)
/* 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)
/* Calibration constant for udelay loop. Very approximate */
#define UADJUST 870
/* transmit and receive descriptor format */
struct txrxdesc {
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 1600
/* Note: transmit and receive buffers must be longword aligned and
longword divisable */
/* transmit descriptor and buffer */
static struct txrxdesc txd;
static unsigned char txb[BUFLEN];
/* receive descriptor(s) and buffer(s) */
#define NRXD 4
static struct txrxdesc rxd[NRXD];
static int rxd_tail = 0;
static unsigned char rxb[NRXD][BUFLEN];
/* PCI Bus parameters */
static unsigned short vendor, dev_id;
static unsigned long ioaddr;
static unsigned long devfn;
/* buffer for ethernet header */
static unsigned char ehdr[ETHER_HDR_SIZE];
/* MIIs found */
static int mii_cnt;
/* Temporary CSR6 storage */
static int csr6;
/*********************************************************************/
/* Utility Routines */
/*********************************************************************/
#undef NTULIP_DEBUG
#undef NTULIP_DEBUG_WHERE
static void inline whereami (char *str)
{
#ifdef NTULIP_DEBUG_WHERE
printf("%s\n", str);
// sleep(2);
#endif
}
/*********************************************************************/
/* Delay Code */
/*********************************************************************/
/* Assumes 33MHz PCI bus. This is not very accurate and should be used
only with gross over estimations of required delay times unless
UADJUST is tuned to your specific processor and I/O subsystem. */
static void udelay(unsigned long usec)
{
unsigned long i;
for (i=((usec*UADJUST)/33)+1; i>0; i--)
(void) inl(ioaddr + CSR0);
}
/*********************************************************************/
/* Media Descriptor Code */
/*********************************************************************/
static int lc82c168_mdio_read(int phy_id, int location)
{
int i = 1000;
int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
int retval = 0;
whereami("mdio_read\n");
outl(0x60020000 | (phy_id<<23) | (location<<18), ioaddr + 0xA0);
inl(ioaddr + 0xA0);
inl(ioaddr + 0xA0);
while (--i > 0)
if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
return retval & 0xffff;
if (i == 0) printf("mdio read timeout!\n");
return 0xffff;
}
static void lc82c168_mdio_write(int phy_id, int location, int value)
{
int i = 1000;
int cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
whereami("mdio_write\n");
outl(cmd, ioaddr + 0xA0);
do
if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
break;
while (--i > 0);
if (i == 0) printf("mdio write timeout!\n");
return;
}
static void lc82c168_do_mii()
{
int phy, phy_idx;
whereami("do_mii\n");
mii_cnt = 0;
for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < 4; phy++) {
int mii_status = lc82c168_mdio_read(phy, 1);
if ((mii_status & 0x8301) == 0x8001 ||
((mii_status & 0x8000) == 0 && (mii_status & 0x7800) != 0)) {
int mii_reg0 = lc82c168_mdio_read(phy, 0);
int mii_advert = lc82c168_mdio_read(phy, 4);
int mii_reg4 = ((mii_status >> 6) & 0x01E1) | 1;
phy_idx++;
printf("%s: MII trcvr #%d "
"config %x status %x advertising %x reg4 %x.\n",
"LC82C168", phy, mii_reg0, mii_status, mii_advert, mii_reg4);
lc82c168_mdio_write(phy, 0, mii_reg0 | 0x1000);
if (mii_advert != mii_reg4)
lc82c168_mdio_write(phy, 4, mii_reg4);
}
}
mii_cnt = phy_idx;
#ifdef NTULIP_DEBUG
printf("mii_cnt = %d\n", mii_cnt);
#endif
}
/*********************************************************************/
/* 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;
}
/*********************************************************************/
/* ntulip_init_ring - setup the tx and rx descriptors */
/*********************************************************************/
static void ntulip_init_ring(struct nic *nic)
{
int i;
/* setup the transmit descriptor */
memset(&txd, 0, sizeof(struct txrxdesc));
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 device */
/* 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++) {
memset(&rxd[i], 0, sizeof(struct txrxdesc));
rxd[i].buf1addr = &rxb[i][0];
rxd[i].buf2addr = 0; /* not used */
rxd[i].buf1sz = BUFLEN;
rxd[i].buf2sz = 0; /* not used */
rxd[i].control = 0x0;
rxd[i].status = 0x80000000; /* give ownership it to device */
}
/* Set Receive end of ring on last descriptor */
rxd[NRXD - 1].control = 0x008;
rxd_tail = 0;
}
/*********************************************************************/
/* eth_reset - Reset adapter */
/*********************************************************************/
static void ntulip_reset(struct nic *nic)
{
whereami("ntulip_reset\n");
if (vendor == PCI_VENDOR_ID_MACRONIX && dev_id == PCI_DEVICE_ID_MX987x5) {
/* set up 10-BASE-T Control Port */
outl(0xFFFFFFFF, ioaddr + CSR14);
/* set up 10-BASE-T Status Port */
outl(0x00001000, ioaddr + CSR12);
/* Set Operation Control Register (CSR6) for MX987x5
to allow N-Way Active Speed selection, and
start the chip's Tx to process setup frame.
While it is possible to force speed selection,
this is probably more useful most of the time.
*/
outl(0x01A80200, ioaddr + CSR6);
} else if (vendor == PCI_VENDOR_ID_LINKSYS && dev_id == PCI_DEVICE_ID_LC82C115) {
/* This is MX987x5 init code. It seems to work for the LNE100TX
but should be replaced when we figure out the right way
to do this initialization
*/
outl(0xFFFFFFFF, ioaddr + CSR14);
outl(0x00001000, ioaddr + CSR12);
outl(0x01A80200, ioaddr + CSR6);
} else if (vendor == PCI_VENDOR_ID_LINKSYS && dev_id == PCI_DEVICE_ID_DEC_TULIP) {
lc82c168_do_mii();
} else {
/* Set to 10Mbps half-duplex */
outl(0x00000000, ioaddr + CSR13);
outl(0x7F3F0000, ioaddr + CSR14);
outl(0x08000008, ioaddr + CSR15);
outl(0x00000000, ioaddr + CSR13);
outl(0x00000001, ioaddr + CSR13);
outl(0x02404000, ioaddr + CSR6);
outl(0x08AF0008, ioaddr + CSR15);
outl(0x00050008, ioaddr + CSR15);
}
/* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
outl(0x00000001, ioaddr + CSR0);
udelay(50000);
udelay(50000);
/* turn off reset and set cache align=16lword, burst=unlimit */
outl(0x01A08000, ioaddr + CSR0);
/* set up transmit and receive descriptors */
ntulip_init_ring(nic);
/* Point to receive descriptor */
outl((unsigned long)&rxd[0], ioaddr + CSR3);
outl((unsigned long)&txd , ioaddr + CSR4);
csr6 = 0x02404000;
/* Chip specific init code */
if (vendor == PCI_VENDOR_ID_MACRONIX && dev_id == PCI_DEVICE_ID_MX987x5) {
csr6 = 0x01880200;
/* Set CSR16 and CSR20 to values that allow device modification */
outl(0x0B3C0000 | inl(ioaddr + CSR16), ioaddr + CSR16);
outl(0x00011000 | inl(ioaddr + CSR20), ioaddr + CSR20);
} else if (vendor == PCI_VENDOR_ID_LINKSYS && dev_id == PCI_DEVICE_ID_LC82C115) {
/* This is MX987x5 init code. It seems to work for the LNE100TX
but should be replaced when we figure out the right way
to do this initialization.
*/
csr6 = 0x01880200;
outl(0x0B3C0000 | inl(ioaddr + CSR16), ioaddr + CSR16);
outl(0x00011000 | inl(ioaddr + CSR20), ioaddr + CSR20);
} else if (vendor == PCI_VENDOR_ID_LINKSYS && dev_id == PCI_DEVICE_ID_DEC_TULIP) {
csr6 = 0x814C0000;
outl(0x00000001, ioaddr + CSR15);
} else if (vendor == PCI_VENDOR_ID_DEC && dev_id == PCI_DEVICE_ID_DEC_21142) {
/* check SROM for evidence of an MII interface */
/* get Controller_0 Info Leaf Offset from SROM - assume already in ee_data */
int offset = ee_data [27] + (ee_data [28] << 8);
/* check offset range and if we have an extended type 3 Info Block */
if ((offset >= 30) && (offset < 120) && (ee_data [offset + 3] > 128) &&
(ee_data [offset + 4] == 3)) {
/* must have an MII interface - disable heartbeat, select port etc. */
csr6 |= (DEC_21142_CSR6_HBD | DEC_21142_CSR6_PS);
csr6 &= ~(DEC_21142_CSR6_TTM);
}
}
/* Start the chip's Tx to process setup frame. */
outl(csr6, ioaddr + CSR6);
outl(csr6 | 0x00002000, ioaddr + CSR6);
outl(csr6 | 0x00002002, ioaddr + CSR6);
}
/*********************************************************************/
/* eth_transmit - Transmit a frame */
/*********************************************************************/
static void ntulip_transmit(struct nic *nic, char *d, unsigned int t,
unsigned int s, char *p)
{
unsigned int len;
int pad;
int status;
unsigned char c;
whereami("ntulip_transmit\n");
/* Stop Tx */
outl(inl(ioaddr + CSR6) & ~0x00002000, ioaddr + CSR6);
/* setup ethernet header */
memcpy(ehdr, d, ETHER_ADDR_SIZE);
memcpy(&ehdr[ETHER_ADDR_SIZE], nic->node_addr, ETHER_ADDR_SIZE);
ehdr[ETHER_ADDR_SIZE*2] = (t >> 8) & 0xff;
ehdr[ETHER_ADDR_SIZE*2+1] = t & 0xff;
/* setup the transmit descriptor */
memset(&txd, 0, sizeof(struct txrxdesc));
txd.buf1addr = &ehdr[0]; /* ethernet header */
txd.buf1sz = ETHER_HDR_SIZE;
txd.buf2addr = p; /* packet to transmit */
txd.buf2sz = s;
txd.control = 0x00000188; /* LS+FS+TER */
txd.status = 0x80000000; /* give it the device */
/* Point to transmit descriptor */
outl((unsigned long)&txd, ioaddr + CSR4);
/* Start Tx */
outl(inl(ioaddr + CSR6) | 0x00002000, ioaddr + CSR6);
udelay(300);
}
/*********************************************************************/
/* eth_poll - Wait for a frame */
/*********************************************************************/
static int ntulip_poll(struct nic *nic)
{
int x;
whereami("ntulip_poll\n");
if (rxd[rxd_tail].status & 0x80000000)
return 0;
whereami("ntulip_poll got one\n");
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][0], 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 ntulip_disable(struct nic *nic)
{
whereami("ntulip_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 *ntulip_probe(struct nic *nic, unsigned short *io_addrs,
struct pci_device *pci)
{
int i;
whereami("ntulip_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(0, 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 */
/* Hardware Address retrieval method for LC82C168 */
if (vendor == PCI_VENDOR_ID_LINKSYS && dev_id == PCI_DEVICE_ID_DEC_TULIP) {
for (i = 0; i < 3; i++) {
int value, boguscnt = 100000;
outl(0x600 | i, ioaddr + 0x98);
do
value = inl(ioaddr + CSR9);
while (value < 0 && --boguscnt > 0);
nic->node_addr[i*2] = (u8)((value >> 8) & 0xff);
nic->node_addr[i*2 + 1] = (u8)( value & 0xff);
}
} else {
/* 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<6; i++)
nic->node_addr[i] = ee_data[20+i];
}
printf("NTulip %b:%b:%b:%b:%b:%b at ioaddr 0x%x\n",
nic->node_addr[0],nic->node_addr[1],nic->node_addr[2],nic->node_addr[3],
nic->node_addr[4],nic->node_addr[5],ioaddr);
/* initialize device */
ntulip_reset(nic);
nic->reset = ntulip_reset;
nic->poll = ntulip_poll;
nic->transmit = ntulip_transmit;
nic->disable = ntulip_disable;
return nic;
}

View file

@ -8,30 +8,39 @@
* your option) any later version.
*/
#if 1
# define ETHERBOOT32
# include <byteorder.h>
# if 0
# include <linux-asm-string.h>
# endif
# include <linux-asm-io.h>
#else
#ifdef __linux__
#if defined(__linux__) || defined(__FreeBSD__) || defined(GRUB)
#define ETHERBOOT32
#include <asm/byteorder.h>
#include "linux-asm-string.h"
#include "linux-asm-io.h"
#define _edata edata /* ELF does not prepend a _ */
#define _end end
#endif
#define ntohl(x) swap32(x)
#define htonl(x) swap32(x)
#define ntohs(x) swap16(x)
#define htons(x) swap16(x)
#ifdef __FreeBSD__
#define ETHERBOOT32
#include <sys/types.h>
#include "linux-asm-string.h"
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;
}
#ifndef GRUB
# include "linux-asm-string.h"
#endif /* ! GRUB */
#include "linux-asm-io.h"
#ifndef GRUB
#define _edata edata /* ELF does not prepend a _ */
#define _end end
#endif /* ! GRUB */
#endif
#ifdef __BCC__
@ -48,7 +57,6 @@ typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
#endif
#endif
#if !defined(ETHERBOOT16) && !defined(ETHERBOOT32)
Error, neither ETHERBOOT16 nor ETHERBOOT32 defined

376
netboot/otulip.c Normal file
View file

@ -0,0 +1,376 @@
/*
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;
#ifndef USE_INTERNAL_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[ETHER_HDR_SIZE]; /* 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, ETHER_ADDR_SIZE);
memcpy(&ehdr[ETHER_ADDR_SIZE], nic->node_addr, ETHER_ADDR_SIZE);
ehdr[ETHER_ADDR_SIZE*2] = (t >> 8) & 0xff;
ehdr[ETHER_ADDR_SIZE*2+1] = t & 0xff;
/* setup the transmit descriptor */
memset(&txd, 0, sizeof(struct txdesc));
txd.buf1addr = &ehdr[0]; /* ethernet header */
txd.buf1sz = ETHER_HDR_SIZE;
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(0,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 < 6; i++)
nic->node_addr[i] = srom[20+i];
printf("Tulip %b:%b:%b:%b:%b:%b at ioaddr 0x%x\n",
srom[20],srom[21],srom[22],srom[23],srom[24],srom[25],
ioaddr);
tulip_reset(nic);
nic->reset = tulip_reset;
nic->poll = tulip_poll;
nic->transmit = tulip_transmit;
nic->disable = tulip_disable;
return nic;
}

76
netboot/otulip.h Normal file
View file

@ -0,0 +1,76 @@
/* 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 */
};

View file

@ -9,9 +9,6 @@
** /usr/src/linux/arch/i386/bios32.c
** /usr/src/linux/include/linux/bios32.h
** /usr/src/linux/drivers/net/ne.c
**
** Limitations: only finds devices on bus 0 (I figure that anybody with
** a multi-pcibus machine will have something better than an ne2000)
*/
/*
@ -391,10 +388,10 @@ static void scan_bus(struct pci_device *pcidev)
if (class == 0x06 && subclass == 0x04)
buses++;
#if DEBUG
#if DEBUG
printf("bus %x, function %x, vendor %x, device %x\n",
bus, devfn, vendor, device);
#endif
#endif
for (i = 0; pcidev[i].vendor != 0; i++) {
if (vendor != pcidev[i].vendor
|| device != pcidev[i].dev_id)
@ -415,7 +412,7 @@ static void scan_bus(struct pci_device *pcidev)
printf("Found %s at 0x%x, ROM address 0x%X\n",
pcidev[i].name, ioaddr, romaddr);
/* Take the first one or the one that matches in boot ROM address */
if (pci_ioaddr == 0 || romaddr == ((long) rom.rom_segment >> 4)) {
if (pci_ioaddr == 0 || romaddr == ((unsigned long) rom.rom_segment << 4)) {
pcidev[i].membase = membase;
pcidev[i].ioaddr = ioaddr;
pcidev[i].devfn = devfn;

View file

@ -1,3 +1,6 @@
#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
@ -134,7 +137,7 @@ __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
struct pci_device {
unsigned short vendor, dev_id;
char *name;
const char *name;
unsigned int membase;
unsigned short ioaddr;
unsigned short devfn;
@ -148,3 +151,5 @@ extern int pcibios_read_config_word(unsigned char bus, unsigned char device_fn,
extern int pcibios_write_config_word (unsigned char bus, unsigned char device_fn, unsigned char where, unsigned short value);
extern int pcibios_write_config_dword(unsigned char bus,
unsigned char device_fn, unsigned char where, unsigned int value);
#endif /* PCI_H */

View file

@ -56,12 +56,10 @@
*/
/* to get some global routines like printf */
#include "etherboot.h"
/* to get the interface to the body of the program */
#include "nic.h"
/* we have a PIC card */
#include "pci.h"
#include "cards.h"
#define RTL_TIMEOUT (1*TICKS_PER_SEC)
@ -153,7 +151,7 @@ enum rx_mode_bits {
};
static int ioaddr;
unsigned int cur_rx,cur_tx;
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)));
@ -163,18 +161,18 @@ static unsigned char tx_buffer[TX_BUF_SIZE] __attribute__((aligned(4)));
/* But we still give the user the choice of using an internal buffer
just in case - Ken */
#ifdef USE_INTERNAL_BUFFER
static unsigned char rx_ring[RX_BUF_LEN+16] __attribute__ ((aligned(4)));
static unsigned char rx_ring[RX_BUF_LEN+16] __attribute__((aligned(4)));
#else
static unsigned char *rx_ring = (unsigned char *)(0x10000 - (RX_BUF_LEN + 16));
#define rx_ring ((unsigned char *)(0x10000 - (RX_BUF_LEN + 16)))
#endif
struct nic *rtl8139_probe(struct nic *nic, unsigned short *probeaddrs,
struct pci_device *pci);
static int read_eeprom(long ioaddr, int location);
static int read_eeprom(int location);
static void rtl_reset(struct nic *nic);
static void rtl_transmit(struct nic *nic, char *destaddr,
unsigned int type, unsigned int len, char *data);
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*);
@ -191,13 +189,13 @@ struct nic *rtl8139_probe(struct nic *nic, unsigned short *probeaddrs,
printf(" - ");
if (probeaddrs == 0 || probeaddrs[0] == 0) {
printf("\nERROR: no probeaddrs given, using pci_device\n");
for (p = pci; p; p++) {
for (p = pci; p->vendor; p++) {
if ( ( (p->vendor == PCI_VENDOR_ID_REALTEK)
&& (p->dev_id == PCI_DEVICE_ID_REALTEK_8139) )
|| ( (p->vendor == PCI_VENDOR_ID_SMC_1211)
&& (p->dev_id == PCI_DEVICE_ID_SMC_1211) ) ) {
probeaddrs[0] = p->ioaddr;
printf("rtl8139: probing %x (membase would be %x)\n",
printf("rtl8139: probing %x (membase %x)\n",
p->ioaddr, p->membase);
}
}
@ -210,10 +208,10 @@ struct nic *rtl8139_probe(struct nic *nic, unsigned short *probeaddrs,
/* Bring the chip out of low-power mode. */
outb(0x00, ioaddr + Config1);
if (read_eeprom(ioaddr, 0) != 0xffff) {
if (read_eeprom(0) != 0xffff) {
unsigned short *ap = (unsigned short*)nic->node_addr;
for (i = 0; i < 3; i++)
*ap++ = read_eeprom(ioaddr, i + 7);
*ap++ = read_eeprom(i + 7);
} else {
unsigned char *ap = (unsigned char*)nic->node_addr;
for (i = 0; i < ETHER_ADDR_SIZE; i++)
@ -264,7 +262,7 @@ struct nic *rtl8139_probe(struct nic *nic, unsigned short *probeaddrs,
#define EE_READ_CMD (6 << 6)
#define EE_ERASE_CMD (7 << 6)
static int read_eeprom(long ioaddr, int location)
static int read_eeprom(int location)
{
int i;
unsigned int retval = 0;
@ -347,10 +345,10 @@ static void rtl_reset(struct nic* nic)
outw(0, ioaddr + IntrMask);
}
static void rtl_transmit(struct nic *nic, char *destaddr,
unsigned int type, unsigned int len, char *data)
static void rtl_transmit(struct nic *nic, const char *destaddr,
unsigned int type, unsigned int len, const char *data)
{
unsigned int i, status, to, nstype;
unsigned int status, to, nstype;
unsigned long txstatus;
memcpy(tx_buffer, destaddr, ETHER_ADDR_SIZE);

View file

@ -468,10 +468,10 @@ static void SK_reset(struct nic *nic);
static int SK_poll(struct nic *nic);
static void SK_transmit(
struct nic *nic,
char *d, /* Destination */
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
char *p); /* Packet */
const char *p); /* Packet */
static void SK_disable(struct nic *nic);
struct nic *SK_probe(struct nic *nic, unsigned short *probe_addrs);
@ -481,19 +481,19 @@ struct nic *SK_probe(struct nic *nic, unsigned short *probe_addrs);
*/
static int SK_lance_init(struct nic *nic, unsigned short mode);
void SK_reset_board(void);
void SK_set_RAP(int reg_number);
int SK_read_reg(int reg_number);
int SK_rread_reg(void);
void SK_write_reg(int reg_number, int value);
static void SK_reset_board(void);
static void SK_set_RAP(int reg_number);
static int SK_read_reg(int reg_number);
static int SK_rread_reg(void);
static void SK_write_reg(int reg_number, int value);
/*
* Debugging functions
* -------------------
*/
void SK_print_pos(struct nic *nic, char *text);
void SK_print_ram(struct nic *nic);
static void SK_print_pos(struct nic *nic, char *text);
static void SK_print_ram(struct nic *nic);
/**************************************************************************
@ -617,10 +617,10 @@ TRANSMIT - Transmit a frame
***************************************************************************/
static void SK_transmit(
struct nic *nic,
char *d, /* Destination */
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
char *pack) /* Packet */
const char *pack) /* Packet */
{
/* send the packet to destination */
struct priv *p; /* SK_G16 private structure */
@ -1046,7 +1046,7 @@ static int SK_lance_init(struct nic *nic, unsigned short mode)
* ! CSR1-3 can only be accessed when in CSR0 the STOP bit is set !
*/
void SK_reset_board(void)
static void SK_reset_board(void)
{
int i;
@ -1058,7 +1058,7 @@ void SK_reset_board(void)
} /* End of SK_reset_board() */
void SK_set_RAP(int reg_number)
static void SK_set_RAP(int reg_number)
{
SK_IOREG = reg_number;
SK_PORT = SK_RESET | SK_RAP | SK_WREG;
@ -1068,7 +1068,7 @@ void SK_set_RAP(int reg_number)
;
} /* End of SK_set_RAP() */
int SK_read_reg(int reg_number)
static int SK_read_reg(int reg_number)
{
SK_set_RAP(reg_number);
@ -1081,7 +1081,7 @@ int SK_read_reg(int reg_number)
} /* End of SK_read_reg() */
int SK_rread_reg(void)
static int SK_rread_reg(void)
{
SK_PORT = SK_RESET | SK_RDATA | SK_RREG;
@ -1093,7 +1093,7 @@ int SK_rread_reg(void)
} /* End of SK_rread_reg() */
void SK_write_reg(int reg_number, int value)
static void SK_write_reg(int reg_number, int value)
{
SK_set_RAP(reg_number);
@ -1111,7 +1111,7 @@ void SK_write_reg(int reg_number, int value)
*/
#ifdef SK_DEBUG
void SK_print_pos(struct nic *nic, char *text)
static void SK_print_pos(struct nic *nic, char *text)
{
unsigned char pos0 = inb(SK_POS0),
@ -1127,7 +1127,7 @@ void SK_print_pos(struct nic *nic, char *text)
} /* End of SK_print_pos() */
void SK_print_ram(struct nic *nic)
static void SK_print_ram(struct nic *nic)
{
int i;

View file

@ -16,8 +16,8 @@
* network device driver which uses this chip
*
* $Log$
* Revision 1.1 2000-02-07 06:30:07 okuji
* add missing files.
* Revision 1.2 2000-04-22 01:17:09 okuji
* update the network support to etherboot-4.5.8.
*
-*/

View file

@ -29,6 +29,7 @@
#include "etherboot.h"
#include "nic.h"
#include "cards.h"
#include "smc9000.h"
# define _outb outb
@ -178,14 +179,14 @@ static void smc9000_reset(struct nic *nic)
***************************************************************************/
static void smc9000_transmit(
struct nic *nic,
char *d, /* Destination */
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
char *p) /* Packet */
const char *p) /* Packet */
{
word length; /* real, length incl. header */
word numPages;
long time_out;
unsigned long time_out;
byte packet_no;
word status;
int i;
@ -211,7 +212,7 @@ static void smc9000_transmit(
status = 0;
/* wait for the memory allocation to finnish */
for (time_out = currticks() + 5*TICKS_PER_SEC; (currticks() - time_out) < 0; ) {
for (time_out = currticks() + 5*TICKS_PER_SEC; currticks() < time_out; ) {
status = inb(smc9000_base + INTERRUPT);
if ( status & IM_ALLOC_INT ) {
/* acknowledge the interrupt */
@ -312,7 +313,7 @@ static void smc9000_transmit(
return;
}
}while(currticks() - time_out < 0);
}while(currticks() < time_out);
printf("SMC9000: Waring TX timed out, resetting board\n");
smc_reset(smc9000_base);
@ -324,8 +325,6 @@ static void smc9000_transmit(
***************************************************************************/
static int smc9000_poll(struct nic *nic)
{
word status;
if(!smc9000_base)
return 0;
@ -390,7 +389,6 @@ struct nic *smc9000_probe(struct nic *nic, unsigned short *probe_addrs)
int media;
const char * version_string;
const char * if_string;
int irqval;
int i;
/*

View file

@ -21,6 +21,7 @@ Fujitsu MB86960 spec sheet (different chip but same family)
#include "etherboot.h"
/* to get the interface to the body of the program */
#include "nic.h"
#include "cards.h"
/*
EtherStar I/O Register offsets
@ -159,10 +160,10 @@ TRANSMIT - Transmit a frame
***************************************************************************/
static void tiara_transmit(
struct nic *nic,
char *d, /* Destination */
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
char *p) /* Packet */
const char *p) /* Packet */
{
unsigned int len;
unsigned long time;
@ -203,7 +204,7 @@ 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, b;
int i;
for (i = 0; i < ETHER_ADDR_SIZE; ++i)
nic->node_addr[i] = inb(ioaddr + PROM_ID + i);

View file

@ -1,380 +1,699 @@
/*
Etherboot DEC Tulip driver
adapted by Ken Yap from
Tulip and clone Etherboot Driver
By Marty Connor (mdc@thinguin.org)
This software may be used and distributed according to the terms
of the GNU Public License, incorporated herein by reference.
Based on Ken Yap's Tulip Etherboot Driver and Donald Becker's
Linux Tulip Driver. Supports N-Way speed auto-configuration on
MX98715, MX98715A and MX98725. Support inexpensive PCI 10/100 cards
based on the Macronix MX987x5 chip, such as the SOHOware Fast
model SFA110A, and the LinkSYS model LNE100TX. The NetGear
model FA310X, based on the LC82C168 chip is supported.
The TRENDnet TE100-PCIA NIC which uses a genuine Intel 21143-PD
chipset is supported.
Documentation and source code used:
Source for Etherboot driver at
http://etherboot.sourceforge.net/
MX98715A Data Sheet and MX98715A Application Note
on http://www.macronix.com/ (PDF format files)
Source for Linux tulip driver at
http://cesdis.gsfc.nasa.gov/linux/drivers/tulip.html
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:
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
*/
/*********************************************************************/
/* Revision History */
/*********************************************************************/
/*
29 Feb 2000 mdc 0.75b7
Increased reset delay to 3 seconds because Macronix cards seem to
need more reset time before card comes back to a usable state.
26 Feb 2000 mdc 0.75b6
Added a 1 second delay after initializing the transmitter because
some cards seem to need the time or they drop the first packet
transmitted.
23 Feb 2000 mdc 0.75b5
removed udelay code and used currticks() for more reliable delay
code in reset pause and sanity timeouts. Added function prototypes
and TX debugging code.
21 Feb 2000 mdc patch to Etherboot 4.4.3
Incorporated patches from Bob Edwards and Paul Mackerras of
Linuxcare's OZLabs to deal with inefficiencies in tulip_transmit
and udelay. We now wait for packet transmission to complete
(or sanity timeout).
04 Feb 2000 Robert.Edwards@anu.edu.au patch to Etherboot 4.4.2
patch to tulip.c that implements the automatic selection of the MII
interface on cards using the Intel/DEC 21143 reference design, in
particular, the TRENDnet TE100-PCIA NIC which uses a genuine Intel
21143-PD chipset.
11 Jan 2000 mdc 0.75b4
Added support for NetGear FA310TX card based on the LC82C168
chip. This should also support Lite-On LC82C168 boards.
Added simple MII support. Re-arranged code to better modularize
initializations.
04 Dec 1999 mdc 0.75b3
Added preliminary support for LNE100TX PCI cards. Should work for
PNIC2 cards. No MII support, but single interface (RJ45) tulip
cards seem to not care.
03 Dec 1999 mdc 0.75b2
Renamed from mx987x5 to tulip, merged in original tulip init code
from tulip.c to support other tulip compatible cards.
02 Dec 1999 mdc 0.75b1
Released Beta MX987x5 Driver for code review and testing to netboot
and thinguin mailing lists.
*/
/*********************************************************************/
/* Declarations */
/*********************************************************************/
#include "etherboot.h"
#include "nic.h"
#include "pci.h"
#include "tulip.h"
#include "cards.h"
static unsigned short vendor, dev_id;
static unsigned short ioaddr;
static unsigned int *membase;
static unsigned long devfn;
static unsigned char srom[1024];
#undef TULIP_DEBUG
#undef TULIP_DEBUG_WHERE
#define BUFLEN 1600 /* must be longword divisable */
/* buffers must be longword aligned */
#define TX_TIME_OUT 2*TICKS_PER_SEC
/* transmit descriptor and buffer */
static struct txrxdesc txd;
static unsigned char txb[BUFLEN];
/* receive descriptor(s) and buffer(s) */
#define NRXD 4
static struct txrxdesc rxd[NRXD];
static int rxd_tail = 0;
static unsigned char rxb[NRXD][BUFLEN];
static unsigned char ehdr[ETHER_HDR_SIZE]; /* buffer for ethernet header */
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 tulip device */
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 };
CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78, CSR16=0x80, CSR20=0xA0
};
#define DEC_21142_CSR6_TTM 0x00400000 /* Transmit Threshold Mode */
#define DEC_21142_CSR6_HBD 0x00080000 /* Heartbeat Disable */
#define DEC_21142_CSR6_PS 0x00040000 /* Port Select */
/***************************************************************************/
/* 21143 specific stuff */
/***************************************************************************/
/* EEPROM Address width definitions */
#define EEPROM_ADDRLEN 6
#define EEPROM_SIZE 128 /* 2 << EEPROM_ADDRLEN */
/* 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 */
/* Data Read from the EEPROM */
static unsigned char ee_data[EEPROM_SIZE];
#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 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)
/* 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 */
static struct txdesc txd __attribute__ ((aligned(4)));
#ifndef USE_INTERNAL_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)));
#ifndef USE_INTERNAL_BUFFER
#define rxb ((char *)0x10000 - NRXD * BUFLEN - BUFLEN)
#else
static unsigned char rxb[NRXD * BUFLEN] __attribute__ ((aligned(4)));
#endif
static int rxd_tail;
/* buffer for ethernet header */
static unsigned char ehdr[ETHER_HDR_SIZE];
/*********************************************************************/
/* Function Prototypes */
/*********************************************************************/
static void whereami(const char *str);
static int lc82c168_mdio_read(int phy_id, int location);
static void lc82c168_mdio_write(int phy_id, int location, int value);
static void lc82c168_do_mii();
static int read_eeprom(unsigned long ioaddr, int location, int addr_len);
struct nic *tulip_probe(struct nic *nic, unsigned short *io_addrs,
struct pci_device *pci);
static void tulip_init_ring(struct nic *nic);
static void tulip_reset(struct nic *nic);
static void tulip_transmit(struct nic *nic, const char *d, unsigned int t,
unsigned int s, const char *p);
static int tulip_poll(struct nic *nic);
static void tulip_disable(struct nic *nic);
static void whereami (const char *str);
#ifdef TULIP_DEBUG
static void tulip_more(void);
#endif /* TULIP_DEBUG */
static void tulip_wait(unsigned int nticks);
/*********************************************************************/
/* Utility Routines */
/*********************************************************************/
static inline void whereami (const char *str)
{
#ifdef TULIP_DEBUG_WHERE
printf("%s\n", str);
/* sleep(2); */
#endif
}
/* 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()
#ifdef TULIP_DEBUG
static void tulip_more()
{
int idx;
for (idx = (300 / 33) + 1; idx > 0; idx--)
(void) TULIP_CSR_READ(csr_busmode);
printf("\n\n-- more --");
while (!iskey())
/* wait */;
getchar();
printf("\n\n");
}
#endif /* TULIP_DEBUG */
static void tulip_wait(unsigned int nticks)
{
unsigned int to = currticks() + nticks;
while (currticks() < to)
/* wait */ ;
}
#define EMIT do { TULIP_CSR_WRITE(csr_srom_mii, csr); delay_300ns(); } while (0)
static void srom_idle()
/*********************************************************************/
/* Media Descriptor Code */
/*********************************************************************/
static int lc82c168_mdio_read(int phy_id, int location)
{
unsigned bit, csr;
int i = 1000;
int retval = 0;
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;
whereami("mdio_read\n");
outl(0x60020000 | (phy_id<<23) | (location<<18), ioaddr + 0xA0);
inl(ioaddr + 0xA0);
inl(ioaddr + 0xA0);
while (--i > 0)
if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
return retval & 0xFFFF;
if (i == 0) printf("mdio read timeout!\n");
return 0xFFFF;
}
static void srom_read()
static void lc82c168_mdio_write(int phy_id, int location, int value)
{
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;
int i = 1000;
int cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
srom_idle();
whereami("mdio_write\n");
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();
outl(cmd, ioaddr + 0xA0);
do
if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
break;
while (--i > 0);
if (i == 0) printf("mdio write timeout!\n");
return;
}
/**************************************************************************
ETH_RESET - Reset adapter
***************************************************************************/
static void tulip_reset(struct nic *nic)
static void lc82c168_do_mii(void)
{
int x,cnt=2;
unsigned long csr6,csr15;
int phy, phy_idx;
outl(0x00000001, ioaddr + CSR0);
udelay(1000);
/* turn off reset and set cache align=16lword, burst=unlimit */
outl(0x01A08000, ioaddr + CSR0);
whereami("do_mii\n");
/* for some reason the media selection does not take
the first time se it is repeated. */
for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < 4; phy++) {
while(cnt--) {
/* stop TX,RX processes */
if (cnt == 1)
outl(0x32404000, ioaddr + CSR6);
else
outl(0x32000040, ioaddr + CSR6);
int mii_status = lc82c168_mdio_read(phy, 1);
/* 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 */
if ((mii_status & 0x8301) == 0x8001 ||
((mii_status & 0x8000) == 0 && (mii_status & 0x7800) != 0)) {
/* start set to 10Mbps half-duplex */
int mii_reg0 = lc82c168_mdio_read(phy, 0);
int mii_advert = lc82c168_mdio_read(phy, 4);
int mii_reg4 = ((mii_status >> 6) & 0x01E1) | 1;
/* 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);
phy_idx++;
printf("%s: MII trcvr #%d "
"config %x status %x advertising %x reg4 %x.\n",
"LC82C168", phy, mii_reg0, mii_status, mii_advert, mii_reg4);
/* initalize GP */
outl(0x8af0008, ioaddr + CSR15);
outl(0x50008, ioaddr + CSR15);
lc82c168_mdio_write(phy, 0, mii_reg0 | 0x1000);
if (mii_advert != mii_reg4)
lc82c168_mdio_write(phy, 4, mii_reg4);
}
}
#ifdef TULIP_DEBUG
printf("mii_cnt = %d\n", phy_idx);
#endif
/* 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);
/*********************************************************************/
/* 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();
}
outl(0x0, ioaddr + CSR7); /* disable interrupts */
/* Terminate the EEPROM access. */
outl(EE_ENB & ~EE_CS, ee_addr);
return retval;
}
/*********************************************************************/
/* tulip_init_ring - setup the tx and rx descriptors */
/*********************************************************************/
static void tulip_init_ring(struct nic *nic)
{
int i;
/* construct setup packet which is used by the 21143 to
program its CAM to recognize interesting MAC addresses */
memset(&txd, 0, sizeof(struct txrxdesc));
/* setup the transmit descriptor */
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 */
txd.control = 0x028; /* setup packet + TER */
txd.status = 0x80000000; /* give ownership to device */
/* 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;
/* 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];
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 txrxdesc));
rxd[x].buf1addr = &rxb[x][0];
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 */
for (i=0; i<NRXD; i++) {
rxd[i].buf1addr = &rxb[i * BUFLEN];
rxd[i].buf2addr = 0; /* not used */
rxd[i].buf1sz = BUFLEN;
rxd[i].buf2sz = 0; /* not used */
rxd[i].control = 0x0;
rxd[i].status = 0x80000000; /* give ownership to device */
}
rxd[NRXD - 1].control = 0x008; /* Set Receive end of ring on la
st descriptor */
/* Set Receive end of ring on last descriptor */
rxd[NRXD - 1].control = 0x008;
rxd_tail = 0;
}
/*********************************************************************/
/* eth_reset - Reset adapter */
/*********************************************************************/
static void tulip_reset(struct nic *nic)
{
unsigned long to, csr6;
whereami("tulip_reset\n");
/* Stop Tx and RX */
outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
if (vendor == PCI_VENDOR_ID_MACRONIX && dev_id == PCI_DEVICE_ID_MX987x5) {
/* set up 10-BASE-T Control Port */
outl(0xFFFFFFFF, ioaddr + CSR14);
/* set up 10-BASE-T Status Port */
outl(0x00001000, ioaddr + CSR12);
/* Set Operation Control Register (CSR6) for MX987x5
to allow N-Way Active Speed selection, and
start the chip's Tx to process setup frame.
While it is possible to force speed selection,
this is probably more useful most of the time.
*/
outl(0x01A80200, ioaddr + CSR6);
} else if (vendor == PCI_VENDOR_ID_LINKSYS && dev_id == PCI_DEVICE_ID_LC82C115) {
/* This is MX987x5 init code. It seems to work for the LNE100TX
but should be replaced when we figure out the right way
to do this initialization
*/
outl(0xFFFFFFFF, ioaddr + CSR14);
outl(0x00001000, ioaddr + CSR12);
outl(0x01A80200, ioaddr + CSR6);
} else if (vendor == PCI_VENDOR_ID_LINKSYS && dev_id == PCI_DEVICE_ID_DEC_TULIP) {
lc82c168_do_mii();
} else if (vendor == PCI_VENDOR_ID_DEC && dev_id == PCI_DEVICE_ID_DEC_21142) {
/* nothing */
} else {
/* If we don't know what to do with the card, set to 10Mbps half-duplex */
outl(0x00000000, ioaddr + CSR13);
outl(0x7F3F0000, ioaddr + CSR14);
outl(0x08000008, ioaddr + CSR15);
outl(0x00000000, ioaddr + CSR13);
outl(0x00000001, ioaddr + CSR13);
outl(0x02404000, ioaddr + CSR6);
outl(0x08AF0008, ioaddr + CSR15);
outl(0x00050008, ioaddr + CSR15);
}
/* tell DC211XX where to find rx descriptor list */
outl((unsigned long)&rxd[0], ioaddr + CSR3);
/* start the receiver */
outl(0x2406002, ioaddr + CSR6);
/* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
outl(0x00000001, ioaddr + CSR0);
tulip_wait(3*TICKS_PER_SEC);
/* turn off reset and set cache align=16lword, burst=unlimit */
outl(0x01A08000, ioaddr + CSR0);
/* set up transmit and receive descriptors */
tulip_init_ring(nic);
/* Point to receive descriptor */
outl((unsigned long)&rxd[0], ioaddr + CSR3);
outl((unsigned long)&txd , ioaddr + CSR4);
csr6 = 0x02404000;
/* Chip specific init code */
if (vendor == PCI_VENDOR_ID_MACRONIX && dev_id == PCI_DEVICE_ID_MX987x5) {
csr6 = 0x01880200;
/* Set CSR16 and CSR20 to values that allow device modification */
outl(0x0B3C0000 | inl(ioaddr + CSR16), ioaddr + CSR16);
outl(0x00011000 | inl(ioaddr + CSR20), ioaddr + CSR20);
} else if (vendor == PCI_VENDOR_ID_LINKSYS && dev_id == PCI_DEVICE_ID_LC82C115) {
/* This is MX987x5 init code. It seems to work for the LNE100TX
but should be replaced when we figure out the right way
to do this initialization.
*/
csr6 = 0x01880200;
outl(0x0B3C0000 | inl(ioaddr + CSR16), ioaddr + CSR16);
outl(0x00011000 | inl(ioaddr + CSR20), ioaddr + CSR20);
} else if (vendor == PCI_VENDOR_ID_LINKSYS && dev_id == PCI_DEVICE_ID_DEC_TULIP) {
csr6 = 0x814C0000;
outl(0x00000001, ioaddr + CSR15);
} else if (vendor == PCI_VENDOR_ID_DEC && dev_id == PCI_DEVICE_ID_DEC_21142) {
/* check SROM for evidence of an MII interface */
/* get Controller_0 Info Leaf Offset from SROM - assume already in ee_data */
int offset = ee_data [27] + (ee_data [28] << 8);
/* check offset range and if we have an extended type 3 Info Block */
if ((offset >= 30) && (offset < 120) && (ee_data [offset + 3] > 128) &&
(ee_data [offset + 4] == 3)) {
/* must have an MII interface - disable heartbeat, select port etc. */
csr6 |= (DEC_21142_CSR6_HBD | DEC_21142_CSR6_PS);
csr6 &= ~(DEC_21142_CSR6_TTM);
}
}
/* set the chip's operating mode */
outl(csr6, ioaddr + CSR6);
/* Start Tx */
outl(inl(ioaddr + CSR6) | 0x00002000, ioaddr + CSR6);
/* immediate transmit demand */
outl(0, ioaddr + CSR1);
to = currticks() + TX_TIME_OUT;
while ((txd.status & 0x80000000) && (currticks() < to))
/* wait */ ;
if (currticks() >= to) {
printf ("TX Setup Timeout!\n");
}
#ifdef TULIP_DEBUG
printf("txd.status = %X\n", txd.status);
printf("ticks = %d\n", currticks() - (to - TX_TIME_OUT));
tulip_more();
#endif
/* enable RX */
outl(inl(ioaddr + CSR6) | 0x00000002, ioaddr + CSR6);
/* immediate poll demand */
outl(0, ioaddr + CSR2);
}
/**************************************************************************
ETH_TRANSMIT - Transmit a frame
***************************************************************************/
static const char padmap[] = {
0, 3, 2, 1};
static void tulip_transmit(struct nic *nic, char *d, unsigned int t, unsigned int s, char *p)
/*********************************************************************/
/* eth_transmit - Transmit a frame */
/*********************************************************************/
static void tulip_transmit(struct nic *nic, const char *d, unsigned int t,
unsigned int s, const char *p)
{
unsigned int len;
int pad;
int status;
unsigned char c;
unsigned long time;
unsigned long to;
whereami("tulip_transmit\n");
/* Stop Tx */
outl(inl(ioaddr + CSR6) & ~0x00002000, ioaddr + CSR6);
/* setup ethernet header */
memcpy(ehdr, d, ETHER_ADDR_SIZE);
memcpy(&ehdr[ETHER_ADDR_SIZE], nic->node_addr, ETHER_ADDR_SIZE);
ehdr[ETHER_ADDR_SIZE*2] = (t >> 8) & 0xff;
ehdr[ETHER_ADDR_SIZE*2+1] = t & 0xff;
ehdr[ETHER_ADDR_SIZE*2] = (t >> 8) & 0xFF;
ehdr[ETHER_ADDR_SIZE*2+1] = t & 0xFF;
/* setup the transmit descriptor */
memset(&txd, 0, sizeof(struct txrxdesc));
txd.buf1addr = &ehdr[0]; /* ethernet header */
txd.buf1sz = ETHER_HDR_SIZE;
txd.buf2addr = p; /* packet to transmit */
txd.buf2sz = s;
txd.control = 0x00000188; /* LS+FS+TER */
txd.status = 0x80000000; /* give ownership to device */
txd.control = 0x188; /* LS+FS+TER */
txd.status = 0x80000000; /* give it to 21143 */
outl(inl(ioaddr + CSR6) & ~0x00004000, ioaddr + CSR6);
/* Point to transmit descriptor */
outl((unsigned long)&txd, ioaddr + CSR4);
outl(inl(ioaddr + CSR6) | 0x00004000, ioaddr + CSR6);
/* Wait for transmit to complete before returning. not well tested.
/* Start Tx */
outl(inl(ioaddr + CSR6) | 0x00002000, ioaddr + CSR6);
time = currticks();
while(txd.status & 0x80000000) {
if (currticks() - time > 20) {
printf("transmit timeout.\n");
break;
/* immediate transmit demand */
outl(0, ioaddr + CSR1);
to = currticks() + TX_TIME_OUT;
while ((txd.status & 0x80000000) && (currticks() < to))
/* wait */ ;
if (currticks() >= to) {
printf ("TX Timeout!\n");
}
}
*/
}
/**************************************************************************
ETH_POLL - Wait for a frame
***************************************************************************/
/*********************************************************************/
/* eth_poll - Wait for a frame */
/*********************************************************************/
static int tulip_poll(struct nic *nic)
{
/* common variables */
unsigned short type = 0;
int x;
whereami("tulip_poll\n");
if (rxd[rxd_tail].status & 0x80000000) return 0;
if (rxd[rxd_tail].status & 0x80000000)
return 0;
whereami("tulip_poll got one\n");
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 is quite fast */
memcpy(nic->packet, &rxb[rxd_tail][0], nic->packetlen);
memcpy(nic->packet, rxb + rxd_tail * BUFLEN, nic->packetlen);
/* return the descriptor and buffer to recieve ring */
/* 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 tulip_disable(struct nic *nic)
{
/* nothing for the moment */
}
whereami("tulip_disable\n");
/**************************************************************************
ETH_PROBE - Look for an adapter
***************************************************************************/
struct nic *tulip_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci)
/* The other Etherboot drivers don't seem to do anything here,
so for now, we will not either */
#if 0
/* 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);
#endif
}
/*********************************************************************/
/* eth_probe - Look for an adapter */
/*********************************************************************/
struct nic *tulip_probe(struct nic *nic, unsigned short *io_addrs,
struct pci_device *pci)
{
int i;
unsigned int i;
whereami("tulip_probe\n");
if (io_addrs == 0 || *io_addrs == 0)
return (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(0,pci->devfn,0x40,0x00000000);
pcibios_write_config_dword(0, pci->devfn, 0x40, 0x00000000);
/* Stop the chip's Tx and Rx processes. */
/* outl(inl(ioaddr + CSR6) & ~0x2002, ioaddr + CSR6); */
outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
/* Clear the missed-packet counter. */
/* (volatile int)inl(ioaddr + CSR8); */
(volatile unsigned long)inl(ioaddr + CSR8);
srom_read();
/* Get MAC Address */
for (i=0; i < 6; i++)
nic->node_addr[i] = srom[20+i];
/* Hardware Address retrieval method for LC82C168 */
if (vendor == PCI_VENDOR_ID_LINKSYS && dev_id == PCI_DEVICE_ID_DEC_TULIP) {
for (i = 0; i < 3; i++) {
int value, boguscnt = 100000;
outl(0x600 | i, ioaddr + 0x98);
do
value = inl(ioaddr + CSR9);
while (value < 0 && --boguscnt > 0);
nic->node_addr[i*2] = (u8)((value >> 8) & 0xFF);
nic->node_addr[i*2 + 1] = (u8)( value & 0xFF);
}
} else {
/* 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<6; i++)
nic->node_addr[i] = ee_data[20+i];
}
printf("Tulip %b:%b:%b:%b:%b:%b at ioaddr 0x%x\n",
srom[20],srom[21],srom[22],srom[23],srom[24],srom[25],
ioaddr);
nic->node_addr[0],nic->node_addr[1],nic->node_addr[2],nic->node_addr[3],
nic->node_addr[4],nic->node_addr[5],ioaddr);
/* initialize device */
tulip_reset(nic);
nic->reset = tulip_reset;
nic->poll = tulip_poll;
nic->transmit = tulip_transmit;
nic->disable = tulip_disable;
return nic;
}

View file

@ -1,67 +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 txrxdesc {
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 */
};

View file

@ -1,6 +1,13 @@
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
@ -8,9 +15,6 @@ MX98715 based cards. That file is available at:
http://cesdis.gsfc.nasa.gov/linux/drivers/test/tulip.c
See the comments at the beginning of ntulip.c for more information
on the code.
NOTES
I've tested this driver with a SOHOware Fast 10/100 Model SDA110A,
@ -46,3 +50,4 @@ Regards,
Marty Connor
mdc@thinguin.org
http://www.thinguin.org/

View file

@ -16,8 +16,6 @@
This driver is designed for the VIA VT86C100A Rhine-II PCI Fast Ethernet
controller.
TODO: Some block comments are C++ style. Can get away with it
with gcc, but not nice.
*/
static const char *version = "rhine.c v1.0.0 2000-01-07\n";
@ -48,6 +46,7 @@ static const char *version = "rhine.c v1.0.0 2000-01-07\n";
#include "etherboot.h"
#include "nic.h"
#include "pci.h"
#include "cards.h"
/* define all ioaddr */
@ -106,254 +105,254 @@ static const char *version = "rhine.c v1.0.0 2000-01-07\n";
#define wTallyCntCRC ioaddr + 0x7d
/*--------------------- Exioaddr Definitions -------------------------*/
//
// Bits in the RCR register
//
/*
* Bits in the RCR register
*/
#define RCR_RRFT2 0x80 //
#define RCR_RRFT1 0x40 //
#define RCR_RRFT0 0x20 //
#define RCR_PROM 0x10 //
#define RCR_AB 0x08 //
#define RCR_AM 0x04 //
#define RCR_AR 0x02 //
#define RCR_SEP 0x01 //
#define RCR_RRFT2 0x80
#define RCR_RRFT1 0x40
#define RCR_RRFT0 0x20
#define RCR_PROM 0x10
#define RCR_AB 0x08
#define RCR_AM 0x04
#define RCR_AR 0x02
#define RCR_SEP 0x01
//
// Bits in the TCR register
//
/*
* Bits in the TCR register
*/
#define TCR_RTSF 0x80 //
#define TCR_RTFT1 0x40 //
#define TCR_RTFT0 0x20 //
#define TCR_OFSET 0x08 //
#define TCR_LB1 0x04 // loopback[1]
#define TCR_LB0 0x02 // loopback[0]
#define TCR_RTSF 0x80
#define TCR_RTFT1 0x40
#define TCR_RTFT0 0x20
#define TCR_OFSET 0x08
#define TCR_LB1 0x04 /* loopback[1] */
#define TCR_LB0 0x02 /* loopback[0] */
//
// Bits in the CR0 register
//
/*
* Bits in the CR0 register
*/
#define CR0_RDMD 0x40 // rx descriptor polling demand
#define CR0_TDMD 0x20 // tx descriptor polling demand
#define CR0_TXON 0x10 //
#define CR0_RXON 0x08 //
#define CR0_STOP 0x04 // stop NIC, default = 1
#define CR0_STRT 0x02 // start NIC
#define CR0_INIT 0x01 // start init process
#define CR0_RDMD 0x40 /* rx descriptor polling demand */
#define CR0_TDMD 0x20 /* tx descriptor polling demand */
#define CR0_TXON 0x10
#define CR0_RXON 0x08
#define CR0_STOP 0x04 /* stop NIC, default = 1 */
#define CR0_STRT 0x02 /* start NIC */
#define CR0_INIT 0x01 /* start init process */
//
// Bits in the CR1 register
//
/*
* Bits in the CR1 register
*/
#define CR1_SFRST 0x80 // software reset
#define CR1_RDMD1 0x40 // RDMD1
#define CR1_TDMD1 0x20 // TDMD1
#define CR1_KEYPAG 0x10 // turn on par/key
#define CR1_DPOLL 0x08 // disable rx/tx auto polling
#define CR1_FDX 0x04 // full duplex mode
#define CR1_ETEN 0x02 // early tx mode
#define CR1_EREN 0x01 // early rx mode
#define CR1_SFRST 0x80 /* software reset */
#define CR1_RDMD1 0x40 /* RDMD1 */
#define CR1_TDMD1 0x20 /* TDMD1 */
#define CR1_KEYPAG 0x10 /* turn on par/key */
#define CR1_DPOLL 0x08 /* disable rx/tx auto polling */
#define CR1_FDX 0x04 /* full duplex mode */
#define CR1_ETEN 0x02 /* early tx mode */
#define CR1_EREN 0x01 /* early rx mode */
//
// Bits in the CR register
//
/*
* Bits in the CR register
*/
#define CR_RDMD 0x0040 // rx descriptor polling demand
#define CR_TDMD 0x0020 // tx descriptor polling demand
#define CR_TXON 0x0010 //
#define CR_RXON 0x0008 //
#define CR_STOP 0x0004 // stop NIC, default = 1
#define CR_STRT 0x0002 // start NIC
#define CR_INIT 0x0001 // start init process
#define CR_SFRST 0x8000 // software reset
#define CR_RDMD1 0x4000 // RDMD1
#define CR_TDMD1 0x2000 // TDMD1
#define CR_KEYPAG 0x1000 // turn on par/key
#define CR_DPOLL 0x0800 // disable rx/tx auto polling
#define CR_FDX 0x0400 // full duplex mode
#define CR_ETEN 0x0200 // early tx mode
#define CR_EREN 0x0100 // early rx mode
#define CR_RDMD 0x0040 /* rx descriptor polling demand */
#define CR_TDMD 0x0020 /* tx descriptor polling demand */
#define CR_TXON 0x0010
#define CR_RXON 0x0008
#define CR_STOP 0x0004 /* stop NIC, default = 1 */
#define CR_STRT 0x0002 /* start NIC */
#define CR_INIT 0x0001 /* start init process */
#define CR_SFRST 0x8000 /* software reset */
#define CR_RDMD1 0x4000 /* RDMD1 */
#define CR_TDMD1 0x2000 /* TDMD1 */
#define CR_KEYPAG 0x1000 /* turn on par/key */
#define CR_DPOLL 0x0800 /* disable rx/tx auto polling */
#define CR_FDX 0x0400 /* full duplex mode */
#define CR_ETEN 0x0200 /* early tx mode */
#define CR_EREN 0x0100 /* early rx mode */
//
// Bits in the IMR0 register
//
/*
* Bits in the IMR0 register
*/
#define IMR0_CNTM 0x80 //
#define IMR0_BEM 0x40 //
#define IMR0_RUM 0x20 //
#define IMR0_TUM 0x10 //
#define IMR0_TXEM 0x08 //
#define IMR0_RXEM 0x04 //
#define IMR0_PTXM 0x02 //
#define IMR0_PRXM 0x01 //
#define IMR0_CNTM 0x80
#define IMR0_BEM 0x40
#define IMR0_RUM 0x20
#define IMR0_TUM 0x10
#define IMR0_TXEM 0x08
#define IMR0_RXEM 0x04
#define IMR0_PTXM 0x02
#define IMR0_PRXM 0x01
// define imrshadow
/* define imrshadow */
#define IMRShadow 0x5AFF
//
// Bits in the IMR1 register
//
/*
* Bits in the IMR1 register
*/
#define IMR1_INITM 0x80 //
#define IMR1_SRCM 0x40 //
#define IMR1_NBFM 0x10 //
#define IMR1_PRAIM 0x08 //
#define IMR1_RES0M 0x04 //
#define IMR1_ETM 0x02 //
#define IMR1_ERM 0x01 //
#define IMR1_INITM 0x80
#define IMR1_SRCM 0x40
#define IMR1_NBFM 0x10
#define IMR1_PRAIM 0x08
#define IMR1_RES0M 0x04
#define IMR1_ETM 0x02
#define IMR1_ERM 0x01
//
// Bits in the ISR register
//
/*
* Bits in the ISR register
*/
#define ISR_INITI 0x8000 //
#define ISR_SRCI 0x4000 //
#define ISR_ABTI 0x2000 //
#define ISR_NORBF 0x1000 //
#define ISR_PKTRA 0x0800 //
#define ISR_RES0 0x0400 //
#define ISR_ETI 0x0200 //
#define ISR_ERI 0x0100 //
#define ISR_CNT 0x0080 //
#define ISR_BE 0x0040 //
#define ISR_RU 0x0020 //
#define ISR_TU 0x0010 //
#define ISR_TXE 0x0008 //
#define ISR_RXE 0x0004 //
#define ISR_PTX 0x0002 //
#define ISR_PRX 0x0001 //
#define ISR_INITI 0x8000
#define ISR_SRCI 0x4000
#define ISR_ABTI 0x2000
#define ISR_NORBF 0x1000
#define ISR_PKTRA 0x0800
#define ISR_RES0 0x0400
#define ISR_ETI 0x0200
#define ISR_ERI 0x0100
#define ISR_CNT 0x0080
#define ISR_BE 0x0040
#define ISR_RU 0x0020
#define ISR_TU 0x0010
#define ISR_TXE 0x0008
#define ISR_RXE 0x0004
#define ISR_PTX 0x0002
#define ISR_PRX 0x0001
//
// Bits in the ISR0 register
//
/*
* Bits in the ISR0 register
*/
#define ISR0_CNT 0x80 //
#define ISR0_BE 0x40 //
#define ISR0_RU 0x20 //
#define ISR0_TU 0x10 //
#define ISR0_TXE 0x08 //
#define ISR0_RXE 0x04 //
#define ISR0_PTX 0x02 //
#define ISR0_PRX 0x01 //
#define ISR0_CNT 0x80
#define ISR0_BE 0x40
#define ISR0_RU 0x20
#define ISR0_TU 0x10
#define ISR0_TXE 0x08
#define ISR0_RXE 0x04
#define ISR0_PTX 0x02
#define ISR0_PRX 0x01
//
// Bits in the ISR1 register
//
/*
* Bits in the ISR1 register
*/
#define ISR1_INITI 0x80 //
#define ISR1_SRCI 0x40 //
#define ISR1_NORBF 0x10 //
#define ISR1_PKTRA 0x08 //
#define ISR1_ETI 0x02 //
#define ISR1_ERI 0x01 //
#define ISR1_INITI 0x80
#define ISR1_SRCI 0x40
#define ISR1_NORBF 0x10
#define ISR1_PKTRA 0x08
#define ISR1_ETI 0x02
#define ISR1_ERI 0x01
// ISR ABNORMAL CONDITION
/* ISR ABNORMAL CONDITION */
#define ISR_ABNORMAL ISR_BE+ISR_RU+ISR_TU+ISR_CNT+ISR_NORBF+ISR_PKTRA
//
// Bits in the MIISR register
//
/*
* Bits in the MIISR register
*/
#define MIISR_MIIERR 0x08 //
#define MIISR_MRERR 0x04 //
#define MIISR_LNKFL 0x02 //
#define MIISR_SPEED 0x01 //
#define MIISR_MIIERR 0x08
#define MIISR_MRERR 0x04
#define MIISR_LNKFL 0x02
#define MIISR_SPEED 0x01
//
// Bits in the MIICR register
//
/*
* Bits in the MIICR register
*/
#define MIICR_MAUTO 0x80 //
#define MIICR_RCMD 0x40 //
#define MIICR_WCMD 0x20 //
#define MIICR_MDPM 0x10 //
#define MIICR_MOUT 0x08 //
#define MIICR_MDO 0x04 //
#define MIICR_MDI 0x02 //
#define MIICR_MDC 0x01 //
#define MIICR_MAUTO 0x80
#define MIICR_RCMD 0x40
#define MIICR_WCMD 0x20
#define MIICR_MDPM 0x10
#define MIICR_MOUT 0x08
#define MIICR_MDO 0x04
#define MIICR_MDI 0x02
#define MIICR_MDC 0x01
//
// Bits in the EECSR register
//
/*
* Bits in the EECSR register
*/
#define EECSR_EEPR 0x80 // eeprom programed status, 73h means programed
#define EECSR_EMBP 0x40 // eeprom embeded programming
#define EECSR_AUTOLD 0x20 // eeprom content reload
#define EECSR_DPM 0x10 // eeprom direct programming
#define EECSR_CS 0x08 // eeprom CS pin
#define EECSR_SK 0x04 // eeprom SK pin
#define EECSR_DI 0x02 // eeprom DI pin
#define EECSR_DO 0x01 // eeprom DO pin
#define EECSR_EEPR 0x80 /* eeprom programed status, 73h means programed */
#define EECSR_EMBP 0x40 /* eeprom embeded programming */
#define EECSR_AUTOLD 0x20 /* eeprom content reload */
#define EECSR_DPM 0x10 /* eeprom direct programming */
#define EECSR_CS 0x08 /* eeprom CS pin */
#define EECSR_SK 0x04 /* eeprom SK pin */
#define EECSR_DI 0x02 /* eeprom DI pin */
#define EECSR_DO 0x01 /* eeprom DO pin */
//
// Bits in the BCR0 register
//
/*
* Bits in the BCR0 register
*/
#define BCR0_CRFT2 0x20 //
#define BCR0_CRFT1 0x10 //
#define BCR0_CRFT0 0x08 //
#define BCR0_DMAL2 0x04 //
#define BCR0_DMAL1 0x02 //
#define BCR0_DMAL0 0x01 //
#define BCR0_CRFT2 0x20
#define BCR0_CRFT1 0x10
#define BCR0_CRFT0 0x08
#define BCR0_DMAL2 0x04
#define BCR0_DMAL1 0x02
#define BCR0_DMAL0 0x01
//
// Bits in the BCR1 register
//
/*
* Bits in the BCR1 register
*/
#define BCR1_CTSF 0x20 //
#define BCR1_CTFT1 0x10 //
#define BCR1_CTFT0 0x08 //
#define BCR1_POT2 0x04 //
#define BCR1_POT1 0x02 //
#define BCR1_POT0 0x01 //
#define BCR1_CTSF 0x20
#define BCR1_CTFT1 0x10
#define BCR1_CTFT0 0x08
#define BCR1_POT2 0x04
#define BCR1_POT1 0x02
#define BCR1_POT0 0x01
//
// Bits in the CFGA register
//
/*
* Bits in the CFGA register
*/
#define CFGA_EELOAD 0x80 // enable eeprom embeded and direct programming
#define CFGA_JUMPER 0x40 //
#define CFGA_MTGPIO 0x08 //
#define CFGA_T10EN 0x02 //
#define CFGA_AUTO 0x01 //
#define CFGA_EELOAD 0x80 /* enable eeprom embeded and direct programming */
#define CFGA_JUMPER 0x40
#define CFGA_MTGPIO 0x08
#define CFGA_T10EN 0x02
#define CFGA_AUTO 0x01
//
// Bits in the CFGB register
//
/*
* Bits in the CFGB register
*/
#define CFGB_PD 0x80 //
#define CFGB_POLEN 0x02 //
#define CFGB_LNKEN 0x01 //
#define CFGB_PD 0x80
#define CFGB_POLEN 0x02
#define CFGB_LNKEN 0x01
//
// Bits in the CFGC register
//
/*
* Bits in the CFGC register
*/
#define CFGC_M10TIO 0x80 //
#define CFGC_M10POL 0x40 //
#define CFGC_PHY1 0x20 //
#define CFGC_PHY0 0x10 //
#define CFGC_BTSEL 0x08 //
#define CFGC_BPS2 0x04 // bootrom select[2]
#define CFGC_BPS1 0x02 // bootrom select[1]
#define CFGC_BPS0 0x01 // bootrom select[0]
#define CFGC_M10TIO 0x80
#define CFGC_M10POL 0x40
#define CFGC_PHY1 0x20
#define CFGC_PHY0 0x10
#define CFGC_BTSEL 0x08
#define CFGC_BPS2 0x04 /* bootrom select[2] */
#define CFGC_BPS1 0x02 /* bootrom select[1] */
#define CFGC_BPS0 0x01 /* bootrom select[0] */
//
// Bits in the CFGD register
//
/*
* Bits in the CFGD register
*/
#define CFGD_GPIOEN 0x80 //
#define CFGD_DIAG 0x40 //
#define CFGD_MAGIC 0x10 //
#define CFGD_CFDX 0x04 //
#define CFGD_CEREN 0x02 //
#define CFGD_CETEN 0x01 //
#define CFGD_GPIOEN 0x80
#define CFGD_DIAG 0x40
#define CFGD_MAGIC 0x10
#define CFGD_CFDX 0x04
#define CFGD_CEREN 0x02
#define CFGD_CETEN 0x01
// Bits in RSR
/* Bits in RSR */
#define RSR_RERR 0x00000001
#define RSR_CRC 0x00000002
#define RSR_FAE 0x00000004
@ -371,7 +370,7 @@ static const char *version = "rhine.c v1.0.0 2000-01-07\n";
#define RSR_RXOK 0x00008000
#define RSR_ABNORMAL RSR_RERR+RSR_LONG+RSR_RUNT
//Bits in TSR
/* Bits in TSR */
#define TSR_NCR0 0x00000001
#define TSR_NCR1 0x00000002
#define TSR_NCR2 0x00000004
@ -389,26 +388,26 @@ static const char *version = "rhine.c v1.0.0 2000-01-07\n";
#define TSR_ABNORMAL TSR_TERR+TSR_OWC+TSR_ABT+TSR_JAB+TSR_CRS
#define TSR_OWN_BIT 0x80000000
#define CB_DELAY_LOOP_WAIT (10) // 10ms
// enabled mask value of irq
#define CB_DELAY_LOOP_WAIT 10 /* 10ms */
/* enabled mask value of irq */
#define W_IMR_MASK_VALUE 0x1BFF // initial value of IMR
#define W_IMR_MASK_VALUE 0x1BFF /* initial value of IMR */
// Ethernet address filter type
#define PKT_TYPE_DIRECTED 0x0001 // obselete, directed address is always accepted
/* Ethernet address filter type */
#define PKT_TYPE_DIRECTED 0x0001 /* obsolete, directed address is always accepted */
#define PKT_TYPE_MULTICAST 0x0002
#define PKT_TYPE_ALL_MULTICAST 0x0004
#define PKT_TYPE_BROADCAST 0x0008
#define PKT_TYPE_PROMISCUOUS 0x0020
//#define PKT_TYPE_LONG 0x2000
#define PKT_TYPE_LONG 0x2000
#define PKT_TYPE_RUNT 0x4000
#define PKT_TYPE_ERROR 0x8000 // accept error packets, e.g. CRC error
#define PKT_TYPE_ERROR 0x8000 /* accept error packets, e.g. CRC error */
// Loopback mode
/* Loopback mode */
#define NIC_LB_NONE 0x00 //
#define NIC_LB_INTERNAL 0x01 //
#define NIC_LB_PHY 0x02 // MII or Internal-10BaseT loopback
#define NIC_LB_NONE 0x00
#define NIC_LB_INTERNAL 0x01
#define NIC_LB_PHY 0x02 /* MII or Internal-10BaseT loopback */
#define TX_RING_SIZE 2
#define RX_RING_SIZE 2
@ -659,14 +658,16 @@ static int QueryAuto (int);
static int ReadMII (int byMIIIndex, int);
static void WriteMII (char, char, char, int);
static void MIIDelay (void);
static void post_reset_delay (void);
static unsigned int read_tick_counter (void);
static void rhine_init_ring (struct nic *dev);
static void rhine_disable (struct nic *nic);
static void rhine_reset (struct nic *nic);
static int rhine_poll (struct nic *nic);
static void rhine_transmit (struct nic *nic, char *d, unsigned int t,
unsigned int s, char *p);
static void rhine_transmit (struct nic *nic, const char *d, unsigned int t,
unsigned int s, const char *p);
/* Linux support functions */
#define virt_to_bus(x) ((unsigned long)x)
#define bus_to_virt(x) ((void *)x)
/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
static void
@ -687,12 +688,12 @@ rhine_init_ring (struct nic *nic)
tp->rx_ring[i].buf_addr_1 = virt_to_bus (tp->rx_buffs[i]);
tp->rx_ring[i].buf_addr_2 = virt_to_bus (&tp->rx_ring[i + 1]);
// printf("[%d]buf1=%x,buf2=%x",i,tp->rx_ring[i].buf_addr_1,tp->rx_ring[i].buf_addr_2);
/* printf("[%d]buf1=%x,buf2=%x",i,tp->rx_ring[i].buf_addr_1,tp->rx_ring[i].buf_addr_2); */
}
/* Mark the last entry as wrapping the ring. */
// tp->rx_ring[i-1].rx_ctrl.bits.rx_buf_size =1518;
/* tp->rx_ring[i-1].rx_ctrl.bits.rx_buf_size =1518; */
tp->rx_ring[i - 1].buf_addr_2 = virt_to_bus (&tp->rx_ring[0]);
//printf("[%d]buf1=%x,buf2=%x",i-1,tp->rx_ring[i-1].buf_addr_1,tp->rx_ring[i-1].buf_addr_2);
/*printf("[%d]buf1=%x,buf2=%x",i-1,tp->rx_ring[i-1].buf_addr_1,tp->rx_ring[i-1].buf_addr_2); */
/* The Tx buffer descriptor is filled in as needed, but we
do need to clear the ownership bit. */
@ -704,11 +705,11 @@ rhine_init_ring (struct nic *nic)
tp->tx_ring[i].tx_ctrl.lw = 0x00e08000;
tp->tx_ring[i].buf_addr_1 = virt_to_bus (tp->tx_buffs[i]);
tp->tx_ring[i].buf_addr_2 = virt_to_bus (&tp->tx_ring[i + 1]);
// printf("[%d]buf1=%x,buf2=%x",i,tp->tx_ring[i].buf_addr_1,tp->tx_ring[i].buf_addr_2);
/* printf("[%d]buf1=%x,buf2=%x",i,tp->tx_ring[i].buf_addr_1,tp->tx_ring[i].buf_addr_2); */
}
tp->tx_ring[i - 1].buf_addr_2 = virt_to_bus (&tp->tx_ring[0]);
// printf("[%d]buf1=%x,buf2=%x",i,tp->tx_ring[i-1].buf_addr_1,tp->tx_ring[i-1].buf_addr_2);
/* printf("[%d]buf1=%x,buf2=%x",i,tp->tx_ring[i-1].buf_addr_1,tp->tx_ring[i-1].buf_addr_2); */
}
int
@ -862,44 +863,6 @@ MIIDelay (void)
}
}
static unsigned int
read_tick_counter (void)
{
unsigned int current_time = 0;
/* Program 8254 to latch T0's count */
outb (0x43, 0x6);
/* Read the counter */
current_time = inb (0x40);
current_time = current_time | (inb (0x40) << 8);
return current_time;
}
static void
post_reset_delay (void)
{
unsigned int initial_time, current_time;
/* need to wait 10 mini seconds */
initial_time = read_tick_counter ();
/* 8254 time tick gives 419 nsec per count. We have to delay a delta
count of 10,000,000ns/419ns = 23866. We will round it up to 23866
*/
while (1)
{
current_time = read_tick_counter ();
if ((initial_time - current_time) >= 23866)
{ /* 10 mini second */
return;
}
}
}
struct nic *
rhine_probe (struct nic *nic, unsigned short *probeaddrs,
struct pci_device *pci)
@ -947,7 +910,8 @@ rhine_probe1 (struct nic *nic, int ioaddr, int chip_id, int options)
{
struct rhine_private *tp;
static int did_version = 0; /* Already printed version info. */
int i, x;
int i;
unsigned int timeout;
int FDXFlag;
int byMIIvalue, LineSpeed, MIICRbak;
@ -967,8 +931,10 @@ rhine_probe1 (struct nic *nic, int ioaddr, int chip_id, int options)
printf ("Analyzing Media type,this will take several seconds........");
for (i = 0; i < 5; i++)
{
for (x = 0; x < 100; x++)
post_reset_delay ();
/* need to wait 1 millisecond - we will round it up to 50-100ms */
timeout = currticks() + 2;
for (timeout = currticks() + 2; currticks() < timeout;)
/* nothing */;
if (ReadMII (1, ioaddr) & 0x0020)
break;
}
@ -1005,8 +971,7 @@ rhine_probe1 (struct nic *nic, int ioaddr, int chip_id, int options)
outb (0x41, byMIIAD);
MIIDelay ();
// while((inb(byMIIAD)&0x20)==0)
// ;
/* while((inb(byMIIAD)&0x20)==0) ; */
outb (MIICRbak | 0x80, byMIICR);
nic->priv_data = &rhine;
@ -1048,14 +1013,21 @@ rhine_reset (struct nic *nic)
int rx_bufs_tmp, rx_bufs_tmp1;
int tx_bufs_tmp, tx_bufs_tmp1;
#ifndef USE_INTERNAL_BUFFER
#define buf1 (0x10000 - (RX_RING_SIZE * PKT_BUF_SZ + 32))
#define buf2 (buf1 - (RX_RING_SIZE * PKT_BUF_SZ + 32))
#define desc1 (buf2 - (TX_RING_SIZE * sizeof (struct rhine_tx_desc) + 32))
#define desc2 (desc1 - (TX_RING_SIZE * sizeof (struct rhine_tx_desc) + 32))
#else
static char buf1[RX_RING_SIZE * PKT_BUF_SZ + 32];
static char buf2[RX_RING_SIZE * PKT_BUF_SZ + 32];
static char desc1[TX_RING_SIZE * sizeof (struct rhine_tx_desc) + 32];
static char desc2[TX_RING_SIZE * sizeof (struct rhine_tx_desc) + 32];
#endif
// printf ("rhine_reset\n");
/* printf ("rhine_reset\n"); */
/* Soft reset the chip. */
//outb(CmdReset, ioaddr + ChipCmd);
/*outb(CmdReset, ioaddr + ChipCmd); */
tx_bufs_tmp = (int) buf1;
tx_ring_tmp = (int) desc1;
@ -1065,40 +1037,40 @@ rhine_reset (struct nic *nic)
/* tune RD TD 32 byte alignment */
rx_ring_tmp1 = (int) virt_to_bus ((char *) rx_ring_tmp);
j = (rx_ring_tmp1 + 32) & (~0x1f);
// printf ("txring[%d]", j);
/* printf ("txring[%d]", j); */
tp->rx_ring = (struct rhine_rx_desc *) bus_to_virt (j);
tx_ring_tmp1 = (int) virt_to_bus ((char *) tx_ring_tmp);
j = (tx_ring_tmp1 + 32) & (~0x1f);
tp->tx_ring = (struct rhine_tx_desc *) bus_to_virt (j);
// printf ("rxring[%x]", j);
/* printf ("rxring[%x]", j); */
tx_bufs_tmp1 = (int) virt_to_bus ((char *) tx_bufs_tmp);
j = (int) (tx_bufs_tmp1 + 32) & (~0x1f);
tx_bufs_tmp = (int) bus_to_virt (j);
// printf ("txb[%x]", j);
/* printf ("txb[%x]", j); */
rx_bufs_tmp1 = (int) virt_to_bus ((char *) rx_bufs_tmp);
j = (int) (rx_bufs_tmp1 + 32) & (~0x1f);
rx_bufs_tmp = (int) bus_to_virt (j);
// printf ("rxb[%x][%x]", rx_bufs_tmp1, j);
/* printf ("rxb[%x][%x]", rx_bufs_tmp1, j); */
for (i = 0; i < RX_RING_SIZE; i++)
{
tp->rx_buffs[i] = (char *) rx_bufs_tmp;
// printf("r[%x]",tp->rx_buffs[i]);
/* printf("r[%x]",tp->rx_buffs[i]); */
rx_bufs_tmp += 1536;
}
for (i = 0; i < TX_RING_SIZE; i++)
{
tp->tx_buffs[i] = (char *) tx_bufs_tmp;
// printf("t[%x]",tp->tx_buffs[i]);
/* printf("t[%x]",tp->tx_buffs[i]); */
tx_bufs_tmp += 1536;
}
// printf ("init ring");
/* printf ("init ring"); */
rhine_init_ring (nic);
/*write TD RD Descriptor to MAC */
outl (virt_to_bus (tp->rx_ring), dwCurrentRxDescAddr);
@ -1123,9 +1095,9 @@ rhine_reset (struct nic *nic)
outw (CR_FDX, byCR0);
}
/*KICK NIC to WORK */
/* KICK NIC to WORK */
CRbak = inw (byCR0);
CRbak = CRbak & 0xFFFB; /*not CR_STOP */
CRbak = CRbak & 0xFFFB; /* not CR_STOP */
outw ((CRbak | CR_STRT | CR_TXON | CR_RXON | CR_DPOLL), byCR0);
/*set IMR to work */
@ -1136,7 +1108,6 @@ static int
rhine_poll (struct nic *nic)
{
struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
int ioaddr = tp->ioaddr;
int rxstatus, good = 0;;
if (tp->rx_ring[tp->cur_rx].rx_status.bits.own_bit == 0)
@ -1157,7 +1128,7 @@ rhine_poll (struct nic *nic)
{
nic->packetlen = tp->rx_ring[tp->cur_rx].rx_status.bits.frame_length;
memcpy (nic->packet, tp->rx_buffs[tp->cur_rx], nic->packetlen);
// printf ("Packet RXed\n");
/* printf ("Packet RXed\n"); */
}
tp->rx_ring[tp->cur_rx].rx_status.bits.own_bit = 1;
tp->cur_rx++;
@ -1168,14 +1139,14 @@ rhine_poll (struct nic *nic)
static void
rhine_transmit (struct nic *nic,
char *d, unsigned int t, unsigned int s, char *p)
const char *d, unsigned int t, unsigned int s, const char *p)
{
struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
int ioaddr = tp->ioaddr;
int entry;
unsigned char CR1bak;
//printf ("rhine_transmit\n");
/*printf ("rhine_transmit\n"); */
/* setup ethernet header */
@ -1199,21 +1170,21 @@ rhine_transmit (struct nic *nic,
CR1bak = inb (byCR1);
CR1bak = CR1bak | CR1_TDMD1;
//printf("tdsw=[%x]",tp->tx_ring[entry].tx_status.lw);
//printf("tdcw=[%x]",tp->tx_ring[entry].tx_ctrl.lw);
//printf("tdbuf1=[%x]",tp->tx_ring[entry].buf_addr_1);
//printf("tdbuf2=[%x]",tp->tx_ring[entry].buf_addr_2);
//printf("td1=[%x]",inl(dwCurrentTDSE0));
//printf("td2=[%x]",inl(dwCurrentTDSE1));
//printf("td3=[%x]",inl(dwCurrentTDSE2));
//printf("td4=[%x]",inl(dwCurrentTDSE3));
/*printf("tdsw=[%x]",tp->tx_ring[entry].tx_status.lw); */
/*printf("tdcw=[%x]",tp->tx_ring[entry].tx_ctrl.lw); */
/*printf("tdbuf1=[%x]",tp->tx_ring[entry].buf_addr_1); */
/*printf("tdbuf2=[%x]",tp->tx_ring[entry].buf_addr_2); */
/*printf("td1=[%x]",inl(dwCurrentTDSE0)); */
/*printf("td2=[%x]",inl(dwCurrentTDSE1)); */
/*printf("td3=[%x]",inl(dwCurrentTDSE2)); */
/*printf("td4=[%x]",inl(dwCurrentTDSE3)); */
outb (CR1bak, byCR1);
tp->cur_tx++;
//outw(IMRShadow,byIMR0);
//dev_kfree_skb(tp->tx_skbuff[entry], FREE_WRITE);
//tp->tx_skbuff[entry] = 0;
/*outw(IMRShadow,byIMR0); */
/*dev_kfree_skb(tp->tx_skbuff[entry], FREE_WRITE); */
/*tp->tx_skbuff[entry] = 0; */
}
// EOF via-rhine.c
/* EOF via-rhine.c */